Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
4 changes: 2 additions & 2 deletions .github/ISSUE_TEMPLATE/bug.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ body:
id: version
attributes:
label: Version
description: Settings → About, or the GitHub Release tag (for example 0.16.1).
placeholder: 0.16.1
description: Settings → About, or the GitHub Release tag (for example 0.17.0).
placeholder: 0.17.0
validations:
required: true
- type: dropdown
Expand Down
1 change: 1 addition & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ private advisory: https://github.com/Modsofthenation/Locus/security/advisories/n
Local (CI also runs these, then builds `@locus/desktop`, `locus/agent:0.1`, and the Android debug APK):

- [ ] `npm test`
- [ ] `npm run test:visual` (or N/A if the desktop UI did not change)
- [ ] `npm run typecheck`
- [ ] `npm run lint`
- [ ] `npm run format:check`
Expand Down
17 changes: 16 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ jobs:
ELECTRON_SKIP_BINARY_DOWNLOAD: "1"
- run: sudo apt-get update && sudo apt-get install -y ripgrep
- run: npm test
- name: Install Playwright Chromium
run: npx playwright install --with-deps chromium
working-directory: apps/desktop
- run: npm run test:visual
- run: npm run typecheck
- run: npm run lint
- run: npm run format:check
Expand All @@ -28,6 +32,15 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0
with:
node-version: "22.22"
- name: Prefetch code-server
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
mkdir -p images/agent/vendor
node scripts/prefetch-github-release-asset.mjs --owner coder --repo code-server --tag v4.96.4 --file code-server-4.96.4-linux-amd64.tar.gz --out images/agent/vendor/code-server.tar.gz
- run: docker build -t locus/agent:0.1 images/agent

android:
Expand All @@ -46,5 +59,7 @@ jobs:
with:
packages: platform-tools
- uses: gradle/actions/setup-gradle@ed408507eac070d1f99cc633dbcf757c94c7933a # v4.4.3
with:
gradle-version: "8.9"
- name: Assemble debug APK
run: ./gradlew assembleDebug --no-daemon --stacktrace
run: gradle assembleDebug --no-daemon --stacktrace
32 changes: 30 additions & 2 deletions .github/workflows/dist-linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ jobs:
# v0.4.1 is a Windows-only hotfix; skip Linux packaging for that tag.
if: github.ref != 'refs/tags/v0.4.1'
runs-on: ubuntu-latest
timeout-minutes: 45
timeout-minutes: 60
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
Expand All @@ -34,8 +34,36 @@ jobs:
with:
node-version: 22
cache: npm
# github.com/releases/download 504s from Actions. Prefetch Electron (zip +
# SHASUMS256.txt) and 7zip / AppImage / icons through the GitHub API.
- uses: actions/cache/restore@caa296126883cff596d87d8935842f9db880ef25 # v5.1.0
id: electron-cache
with:
path: |
~/.cache/electron
~/.cache/electron-builder
key: electron-${{ runner.os }}-${{ hashFiles('package-lock.json') }}-${{ github.run_id }}
restore-keys: |
electron-${{ runner.os }}-${{ hashFiles('package-lock.json') }}-
electron-${{ runner.os }}-
- run: npm ci
- run: npm run dist --workspace=@locus/desktop
- name: Prefetch Electron and electron-builder binaries
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: node scripts/prefetch-github-release-asset.mjs
- name: Package
env:
RETRY_ATTEMPTS: "3"
RETRY_DELAY_MS: "30000"
run: node scripts/retry-cmd.mjs npm run dist --workspace=@locus/desktop
- uses: actions/cache/save@caa296126883cff596d87d8935842f9db880ef25 # v5.1.0
if: always()
continue-on-error: true
with:
path: |
~/.cache/electron
~/.cache/electron-builder
key: ${{ steps.electron-cache.outputs.cache-primary-key }}
- name: Checksums
run: node scripts/release-checksums.mjs apps/desktop/dist-electron SHA256SUMS-linux
- uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
Expand Down
30 changes: 28 additions & 2 deletions .github/workflows/dist-macos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ jobs:
# v0.4.1 is a Windows-only hotfix; skip macOS packaging for that tag.
if: github.ref != 'refs/tags/v0.4.1'
runs-on: macos-latest
timeout-minutes: 45
timeout-minutes: 60
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
Expand All @@ -34,11 +34,29 @@ jobs:
with:
node-version: 22
cache: npm
# github.com/releases/download 504s from Actions. Prefetch Electron (zip +
# SHASUMS256.txt) and 7zip / icons through the GitHub API.
- uses: actions/cache/restore@caa296126883cff596d87d8935842f9db880ef25 # v5.1.0
id: electron-cache
with:
path: |
~/Library/Caches/electron
~/Library/Caches/electron-builder
key: electron-${{ runner.os }}-${{ hashFiles('package-lock.json') }}-${{ github.run_id }}
restore-keys: |
electron-${{ runner.os }}-${{ hashFiles('package-lock.json') }}-
electron-${{ runner.os }}-
- run: npm ci
- name: Prefetch Electron and electron-builder binaries
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: node scripts/prefetch-github-release-asset.mjs
- name: Package
env:
CSC_LINK_RAW: ${{ secrets.CSC_LINK }}
CSC_KEY_PASSWORD_RAW: ${{ secrets.CSC_KEY_PASSWORD }}
RETRY_ATTEMPTS: "3"
RETRY_DELAY_MS: "30000"
run: |
# GitHub interpolates missing secrets as "", and electron-builder
# treats empty CSC_LINK as a certificate path (the desktop dir).
Expand All @@ -49,7 +67,15 @@ jobs:
else
export CSC_IDENTITY_AUTO_DISCOVERY=false
fi
npm run dist --workspace=@locus/desktop
node scripts/retry-cmd.mjs npm run dist --workspace=@locus/desktop
- uses: actions/cache/save@caa296126883cff596d87d8935842f9db880ef25 # v5.1.0
if: always()
continue-on-error: true
with:
path: |
~/Library/Caches/electron
~/Library/Caches/electron-builder
key: ${{ steps.electron-cache.outputs.cache-primary-key }}
- name: Checksums
run: node scripts/release-checksums.mjs apps/desktop/dist-electron SHA256SUMS-macos
- uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
Expand Down
34 changes: 32 additions & 2 deletions .github/workflows/dist-windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ concurrency:
jobs:
package:
runs-on: windows-latest
timeout-minutes: 45
timeout-minutes: 60
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
Expand All @@ -32,8 +32,38 @@ jobs:
with:
node-version: 22
cache: npm
# github.com/releases/download 504s from Actions. Prefetch Electron (zip +
# SHASUMS256.txt) and 7zip / NSIS / icons through the GitHub API so
# @electron/get does not re-fetch checksums after the zip (that 504 is
# what failed Windows after Linux/macOS already succeeded).
- uses: actions/cache/restore@caa296126883cff596d87d8935842f9db880ef25 # v5.1.0
id: electron-cache
with:
path: |
~/AppData/Local/electron/Cache
~/AppData/Local/electron-builder/Cache
key: electron-${{ runner.os }}-${{ hashFiles('package-lock.json') }}-${{ github.run_id }}
restore-keys: |
electron-${{ runner.os }}-${{ hashFiles('package-lock.json') }}-
electron-${{ runner.os }}-
- run: npm ci
- run: npm run dist --workspace=@locus/desktop
- name: Prefetch Electron and electron-builder binaries
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: node scripts/prefetch-github-release-asset.mjs
- name: Package
env:
RETRY_ATTEMPTS: "3"
RETRY_DELAY_MS: "30000"
run: node scripts/retry-cmd.mjs npm run dist --workspace=@locus/desktop
- uses: actions/cache/save@caa296126883cff596d87d8935842f9db880ef25 # v5.1.0
if: always()
continue-on-error: true
with:
path: |
~/AppData/Local/electron/Cache
~/AppData/Local/electron-builder/Cache
key: ${{ steps.electron-cache.outputs.cache-primary-key }}
- name: Checksums
run: node scripts/release-checksums.mjs apps/desktop/dist-electron SHA256SUMS-windows
- uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
Expand Down
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
node_modules/
images/agent/vendor/*.tar.gz
dist/
build/
.turbo/
Expand All @@ -17,6 +18,9 @@ apps/server/dist/
packages/*/dist/
.idea/
.vscode/
playwright-report/
blob-report/
test-results/
*.qcow2
*.iso
*.img
Expand Down
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,18 @@

## Unreleased

## 0.17.0 — 2026-11-08

Quieter desktop shell, more guest runtimes, extra forges, and more reliable installer builds. Settings → About is **0.17.0**.

**Runtimes.** Dev Container files can define install, start, ports, and image when a Locus environment file is absent. Docker, Podman, and nerdctl are all valid container engines. Linux guests on Apple silicon use arm64 QEMU; Windows guests stay x86_64. Host coding CLIs can run over SSH inside a Linux VM. LAN workers can run QEMU guests (live display stays on the worker).

**Forges and subscriptions.** Gitea, Forgejo, and Azure DevOps can be added as forges. Subscribe also understands Linear, Jira, Sentry, Grafana alerts, incident.io, and pull URLs from those extra forges.

**Desktop.** Shared themed dialogs, empty states, shortcuts, undo toasts, and command-palette search. Failed actions surface in the notice stack with Retry. Confirm and prompt no longer use the browser’s native dialogs. The computer column stays collapsed until the agent opens a canvas.

**Packaging.** Linux, macOS, and Windows installer jobs prefetch Electron and packaging tools through the GitHub Releases API and retry failed fetches.

## 0.16.1 — 2026-11-08

First public release.
2 changes: 1 addition & 1 deletion CONTEXT.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ The `/workspace` tree the operator Files pane and the agent file tools share. Ho

## Forge

GitHub, GitLab, or Bitbucket as the remote for clone, push, pull requests, and issues. Locus stays the local catalog. `ForgeClient` selects one forge adapter per account.
GitHub, GitLab, Bitbucket, Gitea, Forgejo, or Azure DevOps as the remote for clone, push, pull requests, and issues. Locus stays the local catalog. `ForgeClient` selects one forge adapter per account. Gitea/Forgejo/Azure DevOps are PAT-only and are not auto-added as empty Settings cards.

## Design

Expand Down
15 changes: 12 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,16 @@ npm run lint
npm run format:check
```

CI on `main` and pull requests runs those plus `npm run build --workspace=@locus/desktop`, a Docker image build, and `cd apps/android && ./gradlew assembleDebug`. When Docker is available, tests include a real container write/patch/commit eval. Installers are **Package Linux / macOS / Windows**; they also publish to a GitHub Release when you push a `v*` tag. **Actions → Package from main → Run workflow** builds all three platforms from current `main` and uploads artifacts without publishing a release. Only the Linux job sets `generate_release_notes: true` so the three parallel packagers do not concatenate the changelog.
Visual regression (Chromium, Linux baselines in `apps/desktop/e2e`):

```bash
npx playwright install chromium
npm run test:visual
```

After an intentional UI change, recapture screenshots with `npm run test:visual:update`. CI Linux is the source of truth. Harness-backed README shots (New agent, New automation) copy with `npm run capture:readme`. Playwright also runs axe on confirm, prompt, feedback, empty-hero, shortcuts, and chat, plus phone-sized shots of confirm / prompt / toast / feedback / shortcuts. Visual runs with `prefers-reduced-motion: reduce`.

CI on `main` and pull requests runs those plus `npm run test:visual`, `npm run build --workspace=@locus/desktop`, a Docker image build, and `cd apps/android && ./gradlew assembleDebug`. When Docker is available, tests include a real container write/patch/commit eval. Installers are **Package Linux / macOS / Windows**; they also publish to a GitHub Release when you push a `v*` tag. **Actions → Package from main → Run workflow** builds all three platforms from current `main` and uploads artifacts without publishing a release. Only the Linux job sets `generate_release_notes: true` so the three parallel packagers do not concatenate the changelog.

Please run those four checks before you open a PR. Target `main`.

Expand All @@ -39,8 +48,8 @@ First agent without Docker: Settings → Providers (Ollama needs no key) then Ne
After merge to `main`:

```bash
git tag v0.16.1
git push origin v0.16.1
git tag v0.17.0
git push origin v0.17.0
```

GitHub Releases are the distribution channel (`v*` tags). Pushing a `v*` tag publishes Linux, macOS, and Windows installers, then **Prune GitHub Releases** deletes older published releases so only the last three remain (git tags are kept). See [docs/public-release.md](docs/public-release.md) for listing settings this tree cannot change (visibility, vulnerability reporting, unsigned macOS/Windows). Keep the repository description as the README tagline and topics `ai-agents`, `qemu`, `docker`, `computer-use`, `electron`, `local-first`.
Expand Down
Loading
Loading