Skip to content

Commit 7b8d9ae

Browse files
authored
Huge Cleanup (#355)
* ship: prepare launch cleanup lane * Address launch cleanup review feedback * Align constrained model submit tests * Guard mission sync step-key matching * Address runtime review follow-ups * Restore dynamic RPC action lists * Allow TCP runtime daemons without build hashes * Validate runtime roles for source CLI attach * Select uncovered failed mission steps
1 parent d5e8456 commit 7b8d9ae

113 files changed

Lines changed: 6124 additions & 5724 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ __pycache__/
2323

2424
# Build outputs
2525
/apps/ade-cli/dist/
26+
/apps/ade-cli/dist-static/
2627
/apps/ade-code/dist/
2728
/apps/desktop/release/
2829
/apps/desktop/dist/

AGENTS.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,15 @@
2323

2424
- Desktop checks:
2525
- `npm --prefix apps/desktop run typecheck`
26-
- `npm --prefix apps/desktop run test`
26+
- `npm run test:desktop:sharded`
2727
- `npm --prefix apps/desktop run build`
2828
- `npm --prefix apps/desktop run lint`
2929
- ADE CLI checks:
3030
- `npm --prefix apps/ade-cli run typecheck`
3131
- `npm --prefix apps/ade-cli run test`
3232
- `npm --prefix apps/ade-cli run build`
3333
- Run the smallest relevant subset first when iterating, then finish with the broader checks that cover the touched surfaces.
34-
- If even running the full desktop test suit, u ahve to shard like ci
34+
- Run full desktop tests with the root `npm run test:desktop:sharded` command; use single-file or single-shard Vitest commands for iteration.
3535

3636
## Terminology
3737

@@ -81,7 +81,7 @@ Desktop release:
8181
- **Node.js 22.x** is required (`node:sqlite` is used as the primary database engine).
8282
- Each app under `apps/` has its own independent `node_modules` and `package-lock.json` (no npm workspaces).
8383
- Validation commands are documented in the "Validation" section above.
84-
- The desktop test suite (265 test files) is large; CI shards it. For local iteration, run targeted tests (e.g. `npm --prefix apps/desktop run test:unit`) or a single file rather than the full suite.
84+
- The desktop test suite is large; CI shards it. For local iteration, run a single file or one CI-style shard rather than the full suite.
8585

8686
### Inspecting the local Electron desktop app with Codex Computer Use on macOS
8787

@@ -111,7 +111,7 @@ Desktop release:
111111
- The `ADE_PROJECT_ROOT=/workspace` env var tells the main process to auto-open a project at startup. However, there is a timing race: the renderer's initial `getProject()` call may return null before the async project switch completes, causing the welcome screen to appear even though the backend loaded the project. A workaround is to open the project manually via the "Open a project" button in the top bar.
112112
- Computer-use features (screenshot, video capture, GUI automation) are macOS-only (`screencapture`, `osascript`). On Linux these gracefully degrade — the app returns `blocked_by_capability`.
113113
- `electron-builder` config only defines a `mac` target. Distributable Linux builds (deb/AppImage) are not configured, but dev mode works fine.
114-
- The `test:unit` script (`npm --prefix apps/desktop run test:unit`) uses `--project unit` which the pinned vitest 0.34.6 doesn't support. Use `npx vitest run <specific-test-file>` in `apps/desktop` for targeted tests, or `npm --prefix apps/desktop run test` for the full suite.
114+
- The pinned Vitest 0.34.6 does not support `--project`. Use `npx vitest run <specific-test-file>` in `apps/desktop` for targeted tests, `npx vitest run --shard=<n>/8` for a CI-style shard, or `npm run test:desktop:sharded` from the repo root for the full desktop unit workspace.
115115
- In the Cursor Cloud VM the active X display is `:1`, not `:99`. When launching Electron set `DISPLAY=:1`.
116116
- To launch the desktop dev app quickly when the CLI is already built: `npm run dev:desktop -- --skip-runtime-build`.
117117
- To launch the TUI against an already-running dev runtime: `npm run dev:code -- --skip-runtime-build --attach --project-root <path> --workspace-root <path>`.

README.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ Daily desktop dev:
154154
npm run dev
155155
```
156156

157-
That aliases to `npm run dev:desktop`: it rebuilds `apps/ade-cli`, launches the Electron desktop app, and points it at the dev runtime socket `/tmp/ade-runtime-dev.sock`. If no dev runtime is listening, desktop is allowed to create it. This is the normal desktop-dev flow.
157+
That aliases to `npm run dev:desktop`: it rebuilds `apps/ade-cli`, refreshes the shared dev runtime at `/tmp/ade-runtime-dev.sock` when needed, launches the Electron desktop app, and points desktop at that runtime. This is the normal desktop-dev flow.
158158

159159
When these commands are run from an ADE lane worktree under `.ade/worktrees/`,
160160
they still run code from that lane checkout, but they open the primary checkout's
@@ -165,7 +165,7 @@ and uses the lane path as the workspace root for `dev:code`.
165165
Dev command matrix:
166166

167167
```bash
168-
npm run dev:desktop # desktop only; dev socket; desktop may auto-create runtime
168+
npm run dev:desktop # refresh shared dev runtime, then launch desktop
169169
npm run dev:desktop:attach # desktop only; fail if dev runtime is not already running
170170
npm run dev:desktop:clean # desktop only; clear Vite cache before launch
171171
npm run dev:code:web # `ade code` in the browser (PTY + inspector WebSocket)
@@ -192,11 +192,11 @@ ADE_DEV_RUNTIME_SOCKET_PATH=/tmp/my-ade-dev.sock npm run dev:runtime
192192
ADE_DESKTOP_BRIDGE_SOCKET_PATH=/tmp/my-bridge.sock npm run dev:desktop
193193
```
194194

195-
To test auto-runtime creation, use the `:auto`/default commands after stopping the dev runtime:
195+
To test auto-runtime creation, use the default dev commands after stopping the dev runtime:
196196

197197
```bash
198198
npm run dev:stop
199-
npm run dev:desktop # tests desktop creating the dev runtime
199+
npm run dev:desktop # tests the desktop wrapper creating the dev runtime
200200
npm run dev:stop
201201
npm run dev:code # tests TUI wrapper creating the dev runtime
202202
```
@@ -211,7 +211,7 @@ npm run package:beta # origin/main -> ADE Beta.app, ade-beta, ~/.ade-bet
211211
These are unsigned local macOS app builds under `apps/desktop/release-alpha` and `apps/desktop/release-beta`. Beta fetches `origin/main`, fast-forwards the local `main` checkout when possible, and builds that checkout as `ADE Beta`. It does not create a packaging worktree. These builds do not replace the production `ADE.app`, production `ade`, or `~/.ade` runtime/state. Alpha and Beta also use separate Electron profile directories (`ade-desktop-alpha` / `ade-desktop-beta`) so their browser storage and window state do not collide with dev or stable.
212212
Local channel packages include the host runtime binary for this Mac. Release builds still require the full cross-platform runtime artifact set used by remote runtime bootstrap.
213213

214-
Validate with `npm --prefix apps/desktop run typecheck` and `run test`. The desktop test suite is large run the smallest relevant subset first.
214+
Validate with `npm --prefix apps/desktop run typecheck` and `npm run test:desktop:sharded` for the full desktop suite. The desktop test suite is large, so run the smallest relevant subset first.
215215

216216
## Links
217217

apps/ade-cli/src/adeRpcServer.test.ts

Lines changed: 59 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1441,6 +1441,31 @@ describe("adeRpcServer", () => {
14411441
}
14421442
});
14431443

1444+
it("allows trusted runtimes to serve lower-privilege requested roles", async () => {
1445+
await withEnv({ ADE_DEFAULT_ROLE: "cto" }, async () => {
1446+
const { runtime } = createRuntime();
1447+
const handler = createAdeRpcRequestHandler({ runtime, serverVersion: "test" });
1448+
1449+
await handler({
1450+
jsonrpc: "2.0",
1451+
id: 1,
1452+
method: "ade/initialize",
1453+
params: {
1454+
identity: {
1455+
callerId: "agent-client",
1456+
role: "agent",
1457+
},
1458+
},
1459+
});
1460+
const result = (await handler({ jsonrpc: "2.0", id: 3, method: "ade/actions/list" })) as any;
1461+
1462+
const names = (result.actions ?? []).map((tool: any) => tool.name);
1463+
expect(names).toContain("delegate_to_subagent");
1464+
expect(names).not.toContain("get_cto_state");
1465+
expect(names).not.toContain("getLinearSyncDashboard");
1466+
});
1467+
});
1468+
14441469
it("lists the full tool surface including coordinator orchestration tools for orchestrator callers", async () => {
14451470
const { runtime } = createRuntime();
14461471
const handler = createAdeRpcRequestHandler({ runtime, serverVersion: "test" });
@@ -1592,6 +1617,32 @@ describe("adeRpcServer", () => {
15921617
);
15931618
});
15941619

1620+
it("reflects backend availability changes in the action list", async () => {
1621+
const fixture = createRuntime();
1622+
const handler = createAdeRpcRequestHandler({ runtime: fixture.runtime, serverVersion: "test" });
1623+
1624+
await initialize(handler, {
1625+
callerId: "worker-1",
1626+
role: "agent",
1627+
missionId: "mission-1",
1628+
runId: "run-1",
1629+
stepId: "step-1",
1630+
attemptId: "attempt-1",
1631+
});
1632+
const before = (await handler({ jsonrpc: "2.0", id: 3, method: "ade/actions/list" })) as any;
1633+
const beforeNames = (before.actions ?? []).map((tool: any) => tool.name);
1634+
expect(beforeNames).toContain("screenshot_environment");
1635+
1636+
fixture.runtime.computerUseArtifactBrokerService.getBackendStatus.mockReturnValue({
1637+
backends: [{ id: "external-proof", available: true }],
1638+
});
1639+
1640+
const after = (await handler({ jsonrpc: "2.0", id: 4, method: "ade/actions/list" })) as any;
1641+
const afterNames = (after.actions ?? []).map((tool: any) => tool.name);
1642+
expect(afterNames).not.toContain("screenshot_environment");
1643+
expect(fixture.runtime.computerUseArtifactBrokerService.getBackendStatus).toHaveBeenCalledTimes(2);
1644+
});
1645+
15951646
it("routes macOS VM computer-use tools and ingests screenshots as proof artifacts", async () => {
15961647
const fixture = createRuntime();
15971648
const handler = createAdeRpcRequestHandler({ runtime: fixture.runtime, serverVersion: "test" });
@@ -1608,7 +1659,7 @@ describe("adeRpcServer", () => {
16081659
});
16091660
expect(fixture.runtime.computerUseArtifactBrokerService.ingest).toHaveBeenCalledWith(
16101661
expect.objectContaining({
1611-
backend: { name: "macos-vm", toolName: "macos_vm_screenshot" },
1662+
backend: { name: "macos-vm", style: "local_fallback", toolName: "macos_vm_screenshot" },
16121663
owners: expect.arrayContaining([
16131664
expect.objectContaining({ kind: "lane", id: "lane-1" }),
16141665
expect.objectContaining({ kind: "chat_session", id: "chat-session-1" }),
@@ -1631,7 +1682,7 @@ describe("adeRpcServer", () => {
16311682
});
16321683
expect(fixture.runtime.computerUseArtifactBrokerService.ingest).toHaveBeenCalledWith(
16331684
expect.objectContaining({
1634-
backend: { name: "macos-vm", toolName: "macos_vm_select" },
1685+
backend: { name: "macos-vm", style: "local_fallback", toolName: "macos_vm_select" },
16351686
}),
16361687
);
16371688

@@ -1671,7 +1722,7 @@ describe("adeRpcServer", () => {
16711722
});
16721723
expect(fixture.runtime.computerUseArtifactBrokerService.ingest).toHaveBeenCalledWith(
16731724
expect.objectContaining({
1674-
backend: { name: "macos-vm", toolName: "screenshot_environment" },
1725+
backend: { name: "macos-vm", style: "local_fallback", toolName: "screenshot_environment" },
16751726
}),
16761727
);
16771728

@@ -1967,6 +2018,10 @@ describe("adeRpcServer", () => {
19672018

19682019
expect(runtime.computerUseArtifactBrokerService.ingest).toHaveBeenCalledWith(
19692020
expect.objectContaining({
2021+
backend: expect.objectContaining({
2022+
name: "agent-browser",
2023+
style: "external_cli",
2024+
}),
19702025
owners: expect.arrayContaining([
19712026
expect.objectContaining({
19722027
kind: "chat_session",
@@ -2360,7 +2415,7 @@ describe("adeRpcServer", () => {
23602415
params: { identity: { callerId: "coord-1", role: "orchestrator" } }
23612416
}) as any;
23622417

2363-
expect(response.capabilities?.actions).toBeTruthy();
2418+
expect(response.capabilities?.actions).toEqual({ listChanged: true });
23642419
expect(response.capabilities?.resources).toBeUndefined();
23652420
} finally {
23662421
if (previousRole == null) delete process.env.ADE_DEFAULT_ROLE;

0 commit comments

Comments
 (0)