Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
0be08b9
Add global and project chat background images
hardbeat920 Sep 8, 2026
ac46198
Fix session selection cleanup when closing menu
hardbeat920 Sep 8, 2026
3a65e69
Hide empty-session arcade behind chat backgrounds
hardbeat920 Sep 8, 2026
7f006e5
Play the Sounds switch cue when it turns on (#111)
kartava Sep 8, 2026
3f375b3
Add a shortcut to archive the focused conversation (#89)
kualta Sep 8, 2026
acf79d1
Add prompt outline to session transcript (#90)
kartava Sep 8, 2026
898572f
Add note image attachments and theme-aware window glass
hardbeat920 Sep 8, 2026
a8c7424
Replace prompt outline button+list with vertical hover bar
hardbeat920 Sep 8, 2026
073f53e
Add fade blur effect to scrolled transcript
hardbeat920 Sep 8, 2026
7069e52
Refine popover backdrop tint for light and dark themes
hardbeat920 Sep 8, 2026
8063bad
Style the composer for light theme
hardbeat920 Sep 8, 2026
2f63c63
Ignore IME composition in composer key handlers
hardbeat920 Sep 8, 2026
537ca05
Release 0.1.38
hardbeat920 Sep 8, 2026
a739b50
Remove transcript top fade effect
hardbeat920 Sep 8, 2026
f693c2a
Show prompt outline at narrower widths
hardbeat920 Sep 8, 2026
5ede624
Enable Windows in-app updates
hardbeat920 Sep 8, 2026
1593e08
Release 0.1.39
hardbeat920 Sep 8, 2026
d4cd7df
Fix release artifact discovery
hardbeat920 Sep 8, 2026
9a6e84d
Bind code block dark theme to the app preference (#117)
kartava Sep 8, 2026
464e95e
Share chat background across split panes
hardbeat920 Sep 8, 2026
722d102
Support staged and unstaged working-tree diffs
hardbeat920 Sep 8, 2026
68cda8a
Add tree view and open-all button to changes panel
hardbeat920 Sep 8, 2026
f8e900f
Treat search include globs as pathspecs, not git grep flags (#125)
Karajelly Sep 8, 2026
3e650cc
Add regression coverage for search pathspec options
hardbeat920 Sep 8, 2026
a57dd0a
Release 0.1.40
hardbeat920 Sep 8, 2026
d618fa5
feat: hide the sidebar update control unless an update is available
felipeorlando Sep 8, 2026
84ff7b6
Prevent duplicate sidebar update installs from concurrent clicks
cursoragent Sep 9, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
127 changes: 101 additions & 26 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,10 @@ jobs:
(process.env.R2_PUBLIC_BASE_URL
? `${process.env.R2_PUBLIC_BASE_URL.replace(/\/$/, "")}/latest.json`
: "");
if (!pubkey || !endpoint) {
console.error("TAURI_UPDATER_PUBKEY and an updater endpoint are required");
process.exit(1);
}
writeFileSync(
process.env.RUNNER_TEMP + "/tauri.release.conf.json",
JSON.stringify(
Expand Down Expand Up @@ -107,6 +111,18 @@ jobs:
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}
run: npx tauri build --bundles app,dmg --config "$RUNNER_TEMP/tauri.release.conf.json"

- name: Download Linux packages
uses: actions/download-artifact@v4
with:
name: linux-packages
path: target/release/bundle/linux

- name: Download Windows packages
uses: actions/download-artifact@v4
with:
name: windows-packages
path: target/release/bundle/nsis

- name: Upload to R2
env:
AWS_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }}
Expand All @@ -122,14 +138,30 @@ jobs:
TAR=$(find "$BUNDLE/macos" -maxdepth 1 -type f -name '*.app.tar.gz' -print -quit)
SIG="${TAR}.sig"
DMG=$(find "$BUNDLE/dmg" -maxdepth 1 -type f -name '*.dmg' -print -quit)
shopt -s nullglob
WINDOWS_INSTALLERS=("$BUNDLE"/nsis/*.exe)
WINDOWS_SIGNATURES=("$BUNDLE"/nsis/*.exe.sig)
if (( ${#WINDOWS_INSTALLERS[@]} != 1 || ${#WINDOWS_SIGNATURES[@]} != 1 )); then
echo "Expected exactly one Windows installer and updater signature" >&2
exit 1
fi
WINDOWS_INSTALLER="${WINDOWS_INSTALLERS[0]}"
WINDOWS_SIGNATURE="${WINDOWS_SIGNATURES[0]}"
BASE="${R2_PUBLIC_BASE_URL%/}"
ENDPOINT="https://${R2_ACCOUNT_ID}.r2.cloudflarestorage.com"
RELEASE_PREFIX="releases/${VERSION}"
TAR_KEY="${RELEASE_PREFIX}/MonoCode.app.tar.gz"
SIG_KEY="${TAR_KEY}.sig"
DMG_KEY="${RELEASE_PREFIX}/MonoCode_${VERSION}_aarch64.dmg"
WINDOWS_INSTALLER_KEY="${RELEASE_PREFIX}/MonoCode_${VERSION}_x64-setup.exe"
WINDOWS_SIGNATURE_KEY="${WINDOWS_INSTALLER_KEY}.sig"

VERSION="$VERSION" SIG="$SIG" TAR_URL="$BASE/$TAR_KEY" node <<'NODE'
VERSION="$VERSION" \
SIG="$SIG" \
TAR_URL="$BASE/$TAR_KEY" \
WINDOWS_SIGNATURE="$WINDOWS_SIGNATURE" \
WINDOWS_INSTALLER_URL="$BASE/$WINDOWS_INSTALLER_KEY" \
node <<'NODE'
const fs = require("fs");
fs.writeFileSync(
"latest.json",
Expand All @@ -143,6 +175,12 @@ jobs:
signature: fs.readFileSync(process.env.SIG, "utf8").trim(),
url: process.env.TAR_URL,
},
"windows-x86_64": {
signature: fs
.readFileSync(process.env.WINDOWS_SIGNATURE, "utf8")
.trim(),
url: process.env.WINDOWS_INSTALLER_URL,
},
},
},
null,
Expand All @@ -157,45 +195,37 @@ jobs:
aws s3 cp "$DMG" "s3://${R2_BUCKET_NAME}/${DMG_KEY}" --cache-control "$IMMUTABLE_CACHE" --endpoint-url "$ENDPOINT"
aws s3 cp "$TAR" "s3://${R2_BUCKET_NAME}/${TAR_KEY}" --cache-control "$IMMUTABLE_CACHE" --endpoint-url "$ENDPOINT"
aws s3 cp "$SIG" "s3://${R2_BUCKET_NAME}/${SIG_KEY}" --cache-control "$IMMUTABLE_CACHE" --endpoint-url "$ENDPOINT"
aws s3 cp "$WINDOWS_INSTALLER" "s3://${R2_BUCKET_NAME}/${WINDOWS_INSTALLER_KEY}" --cache-control "$IMMUTABLE_CACHE" --endpoint-url "$ENDPOINT"
aws s3 cp "$WINDOWS_SIGNATURE" "s3://${R2_BUCKET_NAME}/${WINDOWS_SIGNATURE_KEY}" --cache-control "$IMMUTABLE_CACHE" --endpoint-url "$ENDPOINT"
# Keep the website's stable DMG link, but never let the CDN retain an
# older release under this mutable name.
aws s3 cp "$DMG" "s3://${R2_BUCKET_NAME}/MonoCode.dmg" --cache-control "$NO_CACHE" --endpoint-url "$ENDPOINT"
aws s3 cp latest.json "s3://${R2_BUCKET_NAME}/latest.json" --content-type "application/json" --cache-control "$NO_CACHE" --endpoint-url "$ENDPOINT"

- name: Download Linux packages
uses: actions/download-artifact@v4
with:
name: linux-packages
path: target/release/bundle/linux

- name: Download Windows packages
uses: actions/download-artifact@v4
with:
name: windows-packages
path: target/release/bundle/nsis

- name: GitHub Release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set -euo pipefail
VERSION="${GITHUB_REF_NAME#v}"
BUNDLE="target/release/bundle"
TAR=$(find "$BUNDLE/macos" -maxdepth 1 -type f -name '*.app.tar.gz' -print -quit)
TAR="$BUNDLE/macos/MonoCode.app.tar.gz"
SIG="${TAR}.sig"
DMG=$(find "$BUNDLE/dmg" -maxdepth 1 -type f -name '*.dmg' -print -quit)
shopt -s nullglob
DEB=("$BUNDLE"/linux/*.deb)
APPIMAGE=("$BUNDLE"/linux/*.AppImage)
NSIS=("$BUNDLE"/nsis/*.exe)
if (( ${#DEB[@]} != 1 || ${#APPIMAGE[@]} != 1 || ${#NSIS[@]} != 1 )); then
echo "Expected exactly one .deb, one AppImage, and one NSIS installer" >&2
exit 1
fi
DMG="$BUNDLE/dmg/MonoCode_${VERSION}_aarch64.dmg"
DEB="$BUNDLE/linux/MonoCode_${VERSION}_amd64.deb"
APPIMAGE="$BUNDLE/linux/MonoCode_${VERSION}_amd64.AppImage"
NSIS="$BUNDLE/nsis/MonoCode_${VERSION}_x64-setup.exe"
NSIS_SIG="${NSIS}.sig"
for artifact in "$DMG" "$TAR" "$SIG" "$DEB" "$APPIMAGE" "$NSIS" "$NSIS_SIG"; do
if [[ ! -f "$artifact" ]]; then
echo "Missing release artifact: $artifact" >&2
exit 1
fi
done
gh release create "$GITHUB_REF_NAME" \
--title "MonoCode $VERSION" \
--notes "See CHANGELOG.md for details." \
"$DMG" "$TAR" "$SIG" "${DEB[0]}" "${APPIMAGE[0]}" "${NSIS[0]}"
"$DMG" "$TAR" "$SIG" "$DEB" "$APPIMAGE" "$NSIS" "$NSIS_SIG"

linux:
name: Linux packages
Expand Down Expand Up @@ -253,12 +283,57 @@ jobs:

- run: npm ci

- name: Write updater release config
env:
TAURI_UPDATER_PUBKEY: ${{ secrets.TAURI_UPDATER_PUBKEY }}
TAURI_UPDATER_ENDPOINT: ${{ secrets.TAURI_UPDATER_ENDPOINT }}
R2_PUBLIC_BASE_URL: ${{ secrets.R2_PUBLIC_BASE_URL }}
run: |
$endpoint = $env:TAURI_UPDATER_ENDPOINT
if ([string]::IsNullOrWhiteSpace($endpoint)) {
if ([string]::IsNullOrWhiteSpace($env:R2_PUBLIC_BASE_URL)) {
throw "TAURI_UPDATER_ENDPOINT or R2_PUBLIC_BASE_URL is required"
}
$endpoint = "$($env:R2_PUBLIC_BASE_URL.TrimEnd('/'))/latest.json"
}
if ([string]::IsNullOrWhiteSpace($env:TAURI_UPDATER_PUBKEY)) {
throw "TAURI_UPDATER_PUBKEY is required"
}
$config = @{
bundle = @{
createUpdaterArtifacts = $true
}
plugins = @{
updater = @{
pubkey = $env:TAURI_UPDATER_PUBKEY
endpoints = @($endpoint)
}
}
}
$config | ConvertTo-Json -Depth 5 | Set-Content -Encoding utf8 "$env:RUNNER_TEMP\tauri.release.conf.json"

- name: Build Windows packages
run: npm run build:windows
env:
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}
run: |
$env:RUSTUP_TOOLCHAIN = "stable-x86_64-pc-windows-msvc"
npx tauri build --bundles nsis --config "$env:RUNNER_TEMP\tauri.release.conf.json"

- name: Stage Windows packages
run: |
$installers = @(Get-ChildItem "target/release/bundle/nsis" -Filter "*.exe")
$signatures = @(Get-ChildItem "target/release/bundle/nsis" -Filter "*.exe.sig")
if ($installers.Count -ne 1 -or $signatures.Count -ne 1) {
throw "Expected exactly one NSIS installer and one updater signature"
}
New-Item -ItemType Directory -Force "release-artifacts" | Out-Null
$artifacts = @($installers[0].FullName, $signatures[0].FullName)
Copy-Item -Path $artifacts -Destination "release-artifacts/"

- name: Upload Windows packages
uses: actions/upload-artifact@v4
with:
name: windows-packages
path: target/release/bundle/nsis/*.exe
path: release-artifacts/
if-no-files-found: error
49 changes: 49 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,55 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [0.1.40] - 2026-09-08

### Added

- Working-tree reviews now separate staged changes against `HEAD` from unstaged changes against the index, including partially staged files.
- The Changes panel can organize files into a collapsible directory tree, remembers the selected list or tree view, and can open every change in one review.

### Fixed

- Code block syntax highlighting follows MonoCode's appearance preference instead of the system color scheme. In #117 by @kartava.
- Split conversation panes share one continuous chat background instead of repeating the image in every pane.
- Project search safely treats include filters beginning with `-` as path patterns instead of Git options. In #125 by @Karajelly.
- Release publishing validates and uploads the expected versioned artifacts for every supported platform.

## [0.1.39] - 2026-09-08

### Added

- Windows releases now check for, download, and install signed updates through the same in-app update flow as macOS.

### Changed

- The prompt outline remains visible on slightly narrower windows.
- Removed the scrolled transcript's top-edge fade and blur effect.

## [0.1.38] - 2026-09-08

### Added

- The sidebar project picker is now searchable and keyboard navigable, shows each project's parent path, and includes actions for opening a new project or starting a new tab.
- Right-click a title-bar tab to close that tab, the other tabs, or every tab to its left or right. Bulk closing still protects unsaved files and running terminals.
- Shift-click conversations in the sidebar to select several at once, then pin, unpin, archive, unarchive, move into or out of folders, or delete them together.
- Settings → Appearance → Chat background adds an on-device image behind empty sessions or every conversation, with adjustable visibility. Each project can override the global image from its project-rail menu.
- Long transcripts have a vertical prompt outline for jumping between turns. Hover or keyboard-focus a marker to preview its prompt and reply. In #90 by @kartava.
- Drag image files into a note to copy them into MonoCode's local note storage and insert them into the note at the cursor.
- Archive the focused conversation with Shift+Command/Ctrl+A. The shortcut stays out of editors, terminals, diffs, and open overlays. In #89 by @kualta.

### Changed

- Scrolled transcripts fade and blur smoothly beneath the title bar, and popover backdrops now use theme-aware tints.
- Light mode uses an opaque native window for legibility, preserves the dark-mode glass settings, and gives the composer theme-specific shadows and send-button states.

### Fixed

- Enabling Sounds now plays the switch cue immediately. In #111 by @kartava.
- Sidebar multi-selection clears reliably when its menu closes or the pointer moves outside the selected conversation cards.
- Chat background changes appear across open session panes immediately, and the empty-session arcade stays hidden when a background is visible.
- Composer keyboard handlers ignore active IME composition, preventing Enter, Escape, and picker actions from firing while composing text.

## [0.1.37] - 2026-09-07

### Fixed
Expand Down
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ members = ["src-tauri"]
exclude = ["vendor/portable-pty"]

[workspace.package]
version = "0.1.37"
version = "0.1.40"
edition = "2021"
license = "MIT"

Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "monocode-desktop",
"private": true,
"version": "0.1.37",
"version": "0.1.40",
"type": "module",
"scripts": {
"dev": "vite",
Expand Down
Loading