Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
6df16af
feat(native): add Studio desktop app with a local Rust runtime
tlgimenes Jul 27, 2026
79396c9
fix(native): relax sandbox cookies for the loopback preview
tlgimenes Jul 27, 2026
fcf06bd
feat(native): serve the app over local HTTPS on a real domain
tlgimenes Jul 27, 2026
77aa808
fix(native): keep the selftest origin on plain localhost
tlgimenes Jul 27, 2026
4ce9690
fix(native): keep localhost in the capability allowlist for boot smoke
tlgimenes Jul 28, 2026
92f2b6a
fix(native): match the preview CSP to the origin actually served
tlgimenes Jul 28, 2026
d2857c6
fix(native): derive a thread's branch from the sandbox manager
tlgimenes Jul 28, 2026
0c3b103
fix(native): cut worktrees from origin, not the frozen local head
tlgimenes Jul 28, 2026
6c976b1
fix(chat): hide the runtime toggle on desktop
tlgimenes Jul 28, 2026
09f3440
fix(native): lock the desktop dependencies this branch adds
tlgimenes Jul 28, 2026
6b6e338
fix(native): give each sandbox its own branch name
tlgimenes Jul 28, 2026
a5ad9ea
fix(native): record the sandbox branch where git can read it back
tlgimenes Jul 28, 2026
5891a79
refactor(native): name the worktree directory for what it holds
tlgimenes Jul 28, 2026
9a6f43d
feat(native): make the worktree handle the repository and branch
tlgimenes Jul 28, 2026
d993651
fix(native): keep the 404 wording and satisfy clippy
tlgimenes Jul 28, 2026
0af6c74
feat(native): the worktree handle is the repository and branch
tlgimenes Jul 28, 2026
bf559b3
fix(deps): pin zod so the workspace packages share one copy
tlgimenes Jul 28, 2026
177593a
fix(deps): resolve one zod across the whole workspace
tlgimenes Jul 28, 2026
186a577
fix(harness): label the Claude Code thinking tier Opus 5 1M
tlgimenes Jul 28, 2026
e87d1d4
fix(native): name the sandbox branch after the branch, not the directory
tlgimenes Jul 28, 2026
aae4116
fix(native): let two agents share one repo+branch sandbox
tlgimenes Jul 28, 2026
b06401c
[chore]: narrow the e2e sandbox-handle exports knip flagged
tlgimenes Jul 28, 2026
33634be
fix(native): walk nested handles when publishing local sandboxes
tlgimenes Jul 28, 2026
fd5598a
fix(native): drop the host from handles and give previews a real DNS …
tlgimenes Jul 28, 2026
87942a9
fix(native): rebuild blocks.gen.json on read, like the daemon does
tlgimenes Jul 28, 2026
904dad5
fix(native): key the mirror store on owner/repo, like the worktrees
tlgimenes Jul 28, 2026
c1eb217
feat(native): one studio.db for threads and the sandbox registry
tlgimenes Jul 28, 2026
8aa0257
fix(native): forward org-data requests cookie-led, bearer as fallback
tlgimenes Jul 28, 2026
eb0b1a4
fix(native): answer git suggest-commit and judge-review locally
tlgimenes Jul 28, 2026
4874f5b
feat(native): local-only sandbox surface, served from the registry
tlgimenes Jul 28, 2026
be4ddf5
perf(native): stop paying a write transaction on every thread read
tlgimenes Jul 28, 2026
f3c855c
fix(native): boot off the main thread, fail visibly, constrain the CA
tlgimenes Jul 28, 2026
d567c4f
feat(native): never on main — branchless sandboxes land on staging
tlgimenes Jul 29, 2026
1dc38e7
fix(native): six review blockers — wrong-sandbox ops, lost work, wedg…
tlgimenes Jul 29, 2026
512f153
fix(native): stop the repeated and self-contradicting [org-fs] lines
tlgimenes Jul 29, 2026
ca91c1c
fix(native): fence the preview listener and scope the mount credential
tlgimenes Jul 29, 2026
ccb435e
fix(native): restore Host from the HTTP/2 :authority pseudo-header
tlgimenes Jul 29, 2026
b6196fe
fix(native): allocate each sandbox its own dev-server port
tlgimenes Jul 29, 2026
895181f
feat(native): name a thread from its first message
tlgimenes Jul 29, 2026
c43a4ab
feat(native): generate thread titles with the harness's own fast model
tlgimenes Jul 29, 2026
a0f1638
fix(native): stop the preview hanging on "Starting your preview"
tlgimenes Jul 29, 2026
5ff2e2c
fix(native): keep the watch stream reconnectable across listener rest…
tlgimenes Jul 29, 2026
528a24c
fix(native): a thread with a queued turn never reports done
tlgimenes Jul 29, 2026
b63497a
test(web): assert the browser bundle carries no Tauri desktop code
tlgimenes Jul 29, 2026
b4ba9cc
fix(native): let the claude CLI trust the listener so threads get MCP…
tlgimenes Jul 29, 2026
ccf8640
fix(sandbox): teardown EBUSY on Windows must not fail a passed test
tlgimenes Jul 29, 2026
4f45af4
fix(native): force AUTH_UNIX on org mounts so volumes stay writable
tlgimenes Jul 29, 2026
f081bf3
Revert "fix(native): force AUTH_UNIX on org mounts so volumes stay wr…
tlgimenes Jul 29, 2026
3337657
fix(web): a failed thread-list load must not freeze sidebar status fo…
tlgimenes Jul 29, 2026
3eeb7d2
fix(native): one dev-port policy for every spawn path and the proxy
tlgimenes Jul 29, 2026
93ca0c2
fix(native): org mounts die with the app and ghosts are reclaimed, no…
tlgimenes Jul 29, 2026
f253c1d
refactor(native): consolidate duplicated process machinery into share…
tlgimenes Jul 29, 2026
409daf8
refactor(native): consolidate private-file plumbing and the read-only…
tlgimenes Jul 29, 2026
d26bdc6
refactor(native): consolidate duplicated HTTP plumbing into shared homes
tlgimenes Jul 29, 2026
d367c61
refactor(native): consolidate shared constants, clocks, and path deri…
tlgimenes Jul 29, 2026
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
  •  
  •  
  •  
441 changes: 441 additions & 0 deletions .github/workflows/native.yml

Large diffs are not rendered by default.

8 changes: 7 additions & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -179,12 +179,18 @@ jobs:
test -f apps/api/dist/server/migrate.js
test -f apps/api/dist/server/cli.js

# `build:web` rather than `build` so VITE_TAURI_APP=0 is stated, not
# inherited from the variable happening to be unset — the desktop-free
# assertion below is only meaningful against a known browser build.
- name: Build web app
run: bun run --cwd=apps/web build
run: bun run --cwd=apps/web build:web

- name: Verify web output
run: test -f apps/web/dist/index.html

- name: Assert no Tauri desktop code in the browser bundle
run: bun run check:web-bundle

# Playwright component tests for the sections-editor field widgets
# (apps/web/ct). Self-contained — real chromium, no server/DB — so it lives
# here rather than e2e.yml, gated to web changes only.
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ packages/e2e/playwright-report/
# so we can un-ignore specific subdirs below — git won't traverse into an
# ignored directory.
/docs/*
# Committed engineering plans (desktop migration etc.)
!/docs/plans/
# Superpowers workspace artifacts (brainstorming + writing-plans output)
# are kept local to the working tree, not committed.

Expand Down
16 changes: 16 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,24 @@ bun run --cwd=apps/api dev:server

# Run documentation site locally
bun run docs:dev

# Native desktop app (Tauri) dev loop — HMR via Vite on port 4420
bun run --cwd=apps/native dev
```

**One-time macOS setup for `apps/native` devs**: run
`bun run --cwd=apps/native dev:signing:setup` once. It creates or reuses the
local self-signed `decocms-dev` code-signing identity; no Apple Developer
account is required. It also builds, signs, and installs one fixed
`decocms-keychain-helper` under the user's Application Support directory.
Debug app rebuilds talk to that unchanged helper over JSON stdin/stdout, so
Keychain sees one stable executable; tokens never use argv, logs, or a
filesystem fallback. The native dev runner still signs the app itself and
fails closed if signing drifts, but the fixed helper—not the app's self-signed
designated requirement—is what makes debug Keychain access stable. Debug
sessions stay in the Keychain-only `com.decocms.studio.dev` namespace; release
sessions stay in `com.decocms.studio`.

### Testing & Quality
```bash
# Run all tests (Bun test runner)
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ Every tool call gets input/output validation, access control, audit logging, and
| --- | --- |
| [`apps/api`](./apps/api/README.md) | Hono API, authentication, tools, storage, migrations, and the `deco` CLI |
| [`apps/docs`](./apps/docs/README.md) | Astro documentation site |
| [`apps/native`](./apps/native/README.md) | Tauri desktop app and local Rust runtime |
| [`apps/web`](./apps/web/README.md) | Vite and React 19 administration interface |

### Packages
Expand Down
2 changes: 1 addition & 1 deletion apps/api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@
"typescript": "^7.0.2",
"typescript5": "npm:typescript@^5.9.3",
"vite": "^7.2.1",
"zod": "^4.0.0"
"zod": "4.3.6"
},
"homepage": "https://github.com/decocms/studio",
"keywords": [
Expand Down
4 changes: 2 additions & 2 deletions apps/api/src/api/routes/desktop-session-bridge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* Desktop system-browser session bridge.
*
* `POST /api/auth/desktop/session-from-oauth` — the one Studio-side change
* `apps/desktop/docs/real-ui-auth-recon.md` concluded was unavoidable to fix
* the native authentication contract concluded was unavoidable to fix
* the Google/GitHub/SAML system-browser desktop login path: an MCP OAuth
* access token (the `oauthAccessToken` row both desktop login paths
* ultimately hold) satisfies org-scoped `/api/:org/*` routes but is REJECTED
Expand All @@ -20,7 +20,7 @@
* `Set-Cookie` header — this caller is a native app process, not a browser
* that would capture one) so it can forward that value itself, byte for
* byte, as `Cookie: better-auth.session_token=<value>` — see
* `apps/desktop/crates/upstream/src/login.rs`'s
* `apps/native/crates/upstream/src/login.rs`'s
* `mint_session_from_access_token`, the Rust-side caller.
*
* ## Auth guard
Expand Down
11 changes: 11 additions & 0 deletions apps/native/.cargo/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# macOS dev-build signing hook. Cargo routes each locally-executed binary
# through the runner, but the script signs only `decocms-desktop`; test binaries
# pass through unchanged. The app uses the local self-signed `decocms-dev`
# identity with an explicit certificate-hash + bundle-identifier requirement so
# Keychain ACLs remain stable across rebuilds. Signing fails closed instead of
# launching an ad-hoc binary.
[target.aarch64-apple-darwin]
runner = "scripts/dev-runner.sh"

[target.x86_64-apple-darwin]
runner = "scripts/dev-runner.sh"
4 changes: 4 additions & 0 deletions apps/native/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/target/
**/target/
/.dev-signing-identity
/src-tauri/binaries/
Loading
Loading