@akira-tl/forgerelay 0.8.4 → 0.8.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/README.md +10 -10
  3. package/dist/activity/audit-store.js +44 -6
  4. package/dist/activity/mcp-query-tools.js +53 -36
  5. package/dist/activity/query-service.js +41 -11
  6. package/dist/cli.js +16 -17
  7. package/dist/composite-activity.js +124 -33
  8. package/dist/config.js +8 -13
  9. package/dist/lsp/test-support/server-fixture.js +7 -7
  10. package/dist/process-sessions.js +2 -2
  11. package/dist/remote-auth.js +11 -1
  12. package/dist/remote-mcp-connection-pool.js +90 -0
  13. package/dist/remote-transport.js +28 -14
  14. package/dist/remote-workspace-relay.js +203 -45
  15. package/dist/server.js +134 -64
  16. package/dist/skills.js +1 -1
  17. package/dist/subagents/profiles.js +1 -2
  18. package/dist/subagents/providers/adapters/pi.js +2 -2
  19. package/dist/subagents/providers/availability.js +2 -2
  20. package/dist/subagents/providers/path.js +4 -4
  21. package/dist/ui/.vite/manifest.json +32 -32
  22. package/dist/ui/activity-panel-app.html +3 -3
  23. package/dist/ui/assets/{activity-panel-app-E1ju2dqI.js → activity-panel-app-CUAN6zyW.js} +1 -1
  24. package/dist/ui/assets/{heavy-payload-CeW-n9w5.js → heavy-payload-CgzrutLm.js} +1 -1
  25. package/dist/ui/assets/{review-payload-B9CO298v.js → review-payload-BrLbezbq.js} +1 -1
  26. package/dist/ui/assets/{scrollbar-C2twAENW.js → scrollbar-CbhpdW05.js} +1 -1
  27. package/dist/ui/assets/workspace-app-Bhj96tsR.js +1 -0
  28. package/dist/ui/assets/{workspace-app-CwbJnb_w.js → workspace-app-CxwJuZyS.js} +1 -1
  29. package/dist/ui/assets/{workspace-app-BztEvZIC.js → workspace-app-D6UR0AFl.js} +3 -3
  30. package/dist/ui/assets/workspace-app-ldjBmCJR.css +1 -0
  31. package/dist/ui/assets/workspace-lifecycle-app-Cqfhx9pV.js +1 -0
  32. package/dist/ui/workspace-app.html +4 -4
  33. package/dist/ui/workspace-lifecycle-app.html +4 -4
  34. package/dist/user-config.js +3 -19
  35. package/dist/workspace-presentation.js +69 -0
  36. package/docs/agent-profile-schema.md +4 -9
  37. package/docs/artifact-exchange.md +2 -1
  38. package/docs/chatgpt-coding-workflow.md +9 -9
  39. package/docs/configuration.md +20 -29
  40. package/docs/gotchas.md +10 -7
  41. package/docs/roadmap.md +6 -3
  42. package/docs/security.md +3 -2
  43. package/docs/setup.md +8 -5
  44. package/docs/versioning.md +1 -1
  45. package/package.json +6 -2
  46. package/scripts/debug/accept.mjs +7 -1
  47. package/scripts/debug/relay-accept.mjs +889 -0
  48. package/scripts/debug/runtime.mjs +0 -4
  49. package/scripts/debug/runtime.test.mjs +0 -2
  50. package/scripts/debug/traffic/run.sh +5 -0
  51. package/scripts/debug/traffic/traffic-audit.mjs +907 -0
  52. package/scripts/release/push-ready.mjs +124 -0
  53. package/scripts/release/push-ready.test.mjs +108 -0
  54. package/scripts/release/release-gate.test.mjs +1 -0
  55. package/scripts/release-proof.mjs +16 -1
  56. package/scripts/wiki/sync.mjs +246 -0
  57. package/dist/ui/assets/workspace-app-YnUST8IP.css +0 -1
  58. package/dist/ui/assets/workspace-app-rKuhdae8.js +0 -1
  59. package/dist/ui/assets/workspace-lifecycle-app-CEfMdudP.js +0 -1
@@ -0,0 +1,69 @@
1
+ import { createHash } from "node:crypto";
2
+ const PRESENTATION_FIELDS = [
3
+ "workspaceId",
4
+ "kind",
5
+ "name",
6
+ "members",
7
+ "root",
8
+ "path",
9
+ "mode",
10
+ "sourceRoot",
11
+ "workspaceReused",
12
+ "includeBootstrapContext",
13
+ "worktree",
14
+ "summary",
15
+ ];
16
+ export function compactWorkspacePresentation(card) {
17
+ const presentation = {};
18
+ for (const field of PRESENTATION_FIELDS) {
19
+ const value = card[field];
20
+ if (value !== undefined)
21
+ presentation[field] = value;
22
+ }
23
+ assignProjectedArray(presentation, "agentsFiles", card.agentsFiles, (entry) => pickFields(entry, ["path"]));
24
+ assignProjectedArray(presentation, "availableAgentsFiles", card.availableAgentsFiles, (entry) => pickFields(entry, ["path"]));
25
+ assignProjectedArray(presentation, "skills", card.skills, (entry) => pickFields(entry, ["name"]));
26
+ assignProjectedArray(presentation, "agentProviders", card.agentProviders, (entry) => pickFields(entry, ["name", "available", "reason"]));
27
+ assignProjectedArray(presentation, "agents", card.agents, (entry) => pickFields(entry, [
28
+ "name",
29
+ "provider",
30
+ "model",
31
+ "providerAvailable",
32
+ ]));
33
+ presentation.presentationRevision = presentationRevision(card, presentation);
34
+ return presentation;
35
+ }
36
+ function assignProjectedArray(target, field, value, project) {
37
+ if (!Array.isArray(value))
38
+ return;
39
+ const projected = value.flatMap((entry) => {
40
+ if (!entry || typeof entry !== "object" || Array.isArray(entry))
41
+ return [];
42
+ const item = project(entry);
43
+ return Object.keys(item).length > 0 ? [item] : [];
44
+ });
45
+ target[field] = projected;
46
+ }
47
+ function pickFields(value, fields) {
48
+ const projected = {};
49
+ for (const field of fields) {
50
+ const entry = value[field];
51
+ if (typeof entry === "string" ||
52
+ typeof entry === "boolean" ||
53
+ typeof entry === "number") {
54
+ projected[field] = entry;
55
+ }
56
+ }
57
+ return projected;
58
+ }
59
+ function presentationRevision(card, presentation) {
60
+ if (typeof card.presentationRevision === "string" && card.presentationRevision.length > 0) {
61
+ return card.presentationRevision;
62
+ }
63
+ if (typeof card.contextFingerprint === "string" && card.contextFingerprint.length > 0) {
64
+ return card.contextFingerprint;
65
+ }
66
+ return createHash("sha256")
67
+ .update(JSON.stringify(presentation))
68
+ .digest("hex");
69
+ }
@@ -13,15 +13,10 @@ New locations:
13
13
  .forgerelay/agents/*.md
14
14
  ```
15
15
 
16
- Migration compatibility:
17
-
18
- ```text
19
- ~/.devspace/agents/*.md
20
- .devspace/agents/*.md
21
- ```
22
-
23
- When an existing legacy config directory is reused, its global `agents` folder
24
- remains active automatically.
16
+ Rename-era DevSpace profile discovery has ended. `~/.devspace/agents/*.md` and
17
+ `.devspace/agents/*.md` are not scanned automatically. Move older profiles into
18
+ a canonical ForgeRelay location, or temporarily point `FORGERELAY_CONFIG_DIR`
19
+ at the old global config directory while migrating.
25
20
 
26
21
  ## Example
27
22
 
@@ -9,7 +9,8 @@ Enable the capability with:
9
9
  FORGERELAY_ARTIFACTS=1 forgerelay serve
10
10
  ```
11
11
 
12
- The legacy `DEVSPACE_ARTIFACTS` variable remains a fallback during migration.
12
+ Use the canonical `FORGERELAY_ARTIFACTS` variable; the old
13
+ `DEVSPACE_ARTIFACTS` name is no longer read.
13
14
 
14
15
  ## Workflow
15
16
 
@@ -244,14 +244,15 @@ files in the skill directory.
244
244
 
245
245
  ## Local subagent profiles
246
246
 
247
- With `FORGERELAY_SUBAGENTS=1`, profiles are discovered from the active global
248
- config directory plus:
247
+ With `FORGERELAY_SUBAGENTS=1`, profiles are discovered from the active ForgeRelay
248
+ global config directory plus:
249
249
 
250
250
  ```text
251
251
  .forgerelay/agents/*.md
252
- .devspace/agents/*.md # migration compatibility
253
252
  ```
254
253
 
254
+ Rename-era `.devspace/agents` discovery has ended.
255
+
255
256
  The workspace result exposes only compact profile metadata so the host can
256
257
  choose a provider/profile without loading full provider launch details. Read the
257
258
  ForgeRelay-owned `subagents` capability guide when delegation is actually needed;
@@ -349,9 +350,8 @@ and keeps widget usage focused on workspace/change review.
349
350
 
350
351
  ## Legacy configuration
351
352
 
352
- `FORGERELAY_*` is the canonical environment-variable prefix. Equivalent
353
- `DEVSPACE_*` variables remain accepted as fallbacks during migration.
354
-
355
- Likewise, an existing `~/.devspace` configuration/state setup is reused when the
356
- new ForgeRelay location does not yet exist. See
357
- [Configuration Reference](configuration.md) for the compatibility rules.
353
+ `FORGERELAY_*` is the canonical environment-variable prefix. Rename-era
354
+ `DEVSPACE_*` fallbacks and automatic `~/.devspace` reuse have ended. Migrate
355
+ older installations explicitly; persisted internal identifiers that would
356
+ otherwise orphan state remain compatible. See
357
+ [Configuration Reference](configuration.md) for the current rules.
@@ -18,10 +18,10 @@ Override the directory with:
18
18
  FORGERELAY_CONFIG_DIR=/path/to/config npx @akira-tl/forgerelay serve
19
19
  ```
20
20
 
21
- For migration compatibility, `DEVSPACE_CONFIG_DIR` is accepted when
22
- `FORGERELAY_CONFIG_DIR` is unset. Without either variable, ForgeRelay uses
23
- `~/.forgerelay` unless that directory is absent and an existing `~/.devspace`
24
- directory is present; in that case the legacy directory is reused.
21
+ The rename-era automatic fallback has ended. `DEVSPACE_CONFIG_DIR` is ignored,
22
+ and the default directory is always `~/.forgerelay`. If an older installation
23
+ still has data in a DevSpace-named directory, migrate it explicitly or point
24
+ `FORGERELAY_CONFIG_DIR` at that directory during the migration.
25
25
 
26
26
  ## Commands
27
27
 
@@ -33,20 +33,11 @@ npx @akira-tl/forgerelay config get
33
33
  npx @akira-tl/forgerelay config set publicBaseUrl https://forge.example.com/forgerelay/main,https://forge-alt.example.com/relay
34
34
  ```
35
35
 
36
- ## Environment variable compatibility
36
+ ## Environment variables
37
37
 
38
- The public prefix is `FORGERELAY_*`.
39
-
40
- During the rename transition, the equivalent `DEVSPACE_*` variable remains a
41
- fallback when the ForgeRelay variable is unset. For example:
42
-
43
- ```text
44
- FORGERELAY_ALLOWED_ROOTS
45
- ↓ if unset
46
- DEVSPACE_ALLOWED_ROOTS
47
- ```
48
-
49
- When both are present, `FORGERELAY_*` wins.
38
+ The public prefix is `FORGERELAY_*`. Rename-era `DEVSPACE_*` environment
39
+ variables are no longer read. Migrate automation, service files, shell profiles,
40
+ and CI configuration to the canonical ForgeRelay names.
50
41
 
51
42
  ## Core variables
52
43
 
@@ -88,10 +79,10 @@ A single persisted string remains fully supported, so existing configs require n
88
79
  migration. For environment configuration, use a comma-separated list in
89
80
  `FORGERELAY_PUBLIC_BASE_URL`.
90
81
 
91
- If an existing legacy state/worktree directory is present and the new default is
92
- not, ForgeRelay reuses the legacy location rather than orphaning stored state.
93
- Persisted `stateDir` and `worktreeRoot` values in `config.json` also continue to
94
- win over defaults.
82
+ ForgeRelay no longer auto-detects DevSpace-named state or worktree directories.
83
+ Persisted `stateDir` and `worktreeRoot` values in `config.json` continue to win
84
+ over defaults, so an explicit configuration may temporarily point at an older
85
+ location while data is migrated.
95
86
 
96
87
  ## Native artifact download
97
88
 
@@ -145,8 +136,7 @@ MCP clients discover metadata from:
145
136
  | `codex` | Experimental Codex-shaped compatibility adapter using `open_workspace`, `close_workspace`, `read`, `rename`, `delete`, `apply_patch`, `exec_command`, `write_stdin`, and `capability`. It does not define the ForgeRelay canonical interface. |
146
137
 
147
138
  `FORGERELAY_MINIMAL_TOOLS` remains a compatibility-style boolean alias when the
148
- explicit tool mode is unset. The corresponding legacy `DEVSPACE_*` names are
149
- also accepted.
139
+ explicit tool mode is unset. DevSpace-prefixed equivalents are no longer read.
150
140
 
151
141
  `minimal` and `full` now resolve to the same regular 9-tool `tools/list`; `full`
152
142
  is retained only as a configuration-compatibility value. `codex` selects a
@@ -347,8 +337,7 @@ remains durable.
347
337
  | --- | --- | --- |
348
338
  | `FORGERELAY_TASK_REMINDER_INTERVAL` | `30` | Successful semantic work calls between Task update reminders; `0` disables reminders. |
349
339
 
350
- The same value may be persisted as `taskReminderInterval` in `config.json`. The
351
- legacy-compatible `DEVSPACE_TASK_REMINDER_INTERVAL` environment name is also accepted.
340
+ The same value may be persisted as `taskReminderInterval` in `config.json`.
352
341
 
353
342
  Use `open_workspace(action="list")` only when the Agent needs lightweight inventory
354
343
  to discover known Workspaces, continue earlier work, or organize Workspace state. The
@@ -609,10 +598,12 @@ Standard Agent Skills are discovered from:
609
598
 
610
599
  When subagents are enabled, profiles are discovered from:
611
600
 
612
- - `~/.forgerelay/agents/*.md` for new installations;
613
- - project `.forgerelay/agents/*.md`;
614
- - active legacy config directory `~/.devspace/agents/*.md` when reused;
615
- - project `.devspace/agents/*.md` for migration compatibility.
601
+ - the active ForgeRelay config directory's `agents/*.md`;
602
+ - project `.forgerelay/agents/*.md`.
603
+
604
+ DevSpace-named profile directories are no longer discovered automatically. Move
605
+ those profiles or explicitly select their parent with `FORGERELAY_CONFIG_DIR`
606
+ during migration.
616
607
 
617
608
  The ForgeRelay-owned `subagents` capability guide teaches the current CLI
618
609
  workflow on demand:
package/docs/gotchas.md CHANGED
@@ -28,11 +28,10 @@ npm rebuild better-sqlite3
28
28
  npx @akira-tl/forgerelay doctor
29
29
  ```
30
30
 
31
- ## Existing DevSpace config is still being used
31
+ ## Existing DevSpace config stopped being used
32
32
 
33
- This is intentional migration behavior. If `~/.forgerelay` does not exist but
34
- `~/.devspace` does, ForgeRelay reuses the legacy config directory so existing
35
- OAuth/state configuration is not silently abandoned.
33
+ The automatic rename-era fallback has ended. ForgeRelay now defaults to
34
+ `~/.forgerelay` and ignores `DEVSPACE_*` environment variables.
36
35
 
37
36
  Check the resolved directory:
38
37
 
@@ -40,7 +39,8 @@ Check the resolved directory:
40
39
  forgerelay doctor
41
40
  ```
42
41
 
43
- To force a new location, set:
42
+ If an older installation still needs data from a DevSpace-named directory,
43
+ point the canonical setting at it explicitly while migrating:
44
44
 
45
45
  ```bash
46
46
  FORGERELAY_CONFIG_DIR="$HOME/.forgerelay" forgerelay init
@@ -135,7 +135,9 @@ New installs normally use:
135
135
  ~/.forgerelay/auth.json
136
136
  ```
137
137
 
138
- A migrated install may still use `~/.devspace/auth.json`.
138
+ ForgeRelay no longer discovers `~/.devspace/auth.json` automatically. Move the
139
+ credential file to the active ForgeRelay config directory or explicitly set
140
+ `FORGERELAY_CONFIG_DIR` while migrating.
139
141
 
140
142
  Regenerate setup intentionally with:
141
143
 
@@ -227,7 +229,8 @@ New profile locations include:
227
229
  .forgerelay/agents/*.md
228
230
  ```
229
231
 
230
- Legacy `.devspace/agents` paths remain supported.
232
+ Legacy `.devspace/agents` paths are no longer scanned automatically. Move
233
+ profiles into one of the canonical locations before upgrading.
231
234
 
232
235
  `forgerelay agents ls` lists sessions, not profile definitions. The compact
233
236
  profile catalog is returned through `open_workspace`.
package/docs/roadmap.md CHANGED
@@ -365,6 +365,9 @@ New public names use ForgeRelay:
365
365
  - `.forgerelay`
366
366
  - `forgerelay/*` managed branches
367
367
 
368
- Legacy `DEVSPACE_*`, `~/.devspace`, `.devspace`, old managed branch names, and
369
- selected persisted internal identifiers remain readable during migration where
370
- removing compatibility would orphan real user state.
368
+ Rename-era public compatibility adapters have a bounded migration window rather
369
+ than permanent support. `DEVSPACE_*`, automatic `~/.devspace` reuse, legacy
370
+ `.devspace/agents` discovery, and old package-path special cases are retired once
371
+ they are outside that window. Persisted internal identifiers remain compatible
372
+ when removing them would orphan real user state; those are storage/protocol
373
+ migration concerns, not public product aliases.
package/docs/security.md CHANGED
@@ -60,8 +60,9 @@ FORGERELAY_OAUTH_OWNER_TOKEN="$(openssl rand -base64 32)"
60
60
 
61
61
  The token must be at least 16 characters.
62
62
 
63
- Existing `~/.devspace` configuration and `DEVSPACE_*` variables remain readable
64
- for migration compatibility when the new ForgeRelay equivalents are absent.
63
+ Rename-era `DEVSPACE_*` environment-variable and automatic `~/.devspace`
64
+ configuration fallbacks have ended. Use canonical `FORGERELAY_*` settings and
65
+ explicit paths when migrating older installations.
65
66
 
66
67
  ## Public URL and tunnels
67
68
 
package/docs/setup.md CHANGED
@@ -121,11 +121,14 @@ Keep `auth.json` private.
121
121
 
122
122
  ### Existing DevSpace configuration
123
123
 
124
- During migration, if `~/.forgerelay` does not exist but `~/.devspace` does,
125
- ForgeRelay reuses the legacy directory automatically. `FORGERELAY_CONFIG_DIR`
126
- takes precedence over the legacy `DEVSPACE_CONFIG_DIR` environment variable.
127
-
128
- You do not need to move a working legacy config before starting ForgeRelay.
124
+ Automatic DevSpace directory fallback has ended. ForgeRelay defaults to
125
+ `~/.forgerelay` and ignores `DEVSPACE_CONFIG_DIR`.
126
+
127
+ Before upgrading an older installation, move or copy the needed configuration
128
+ and credentials into the ForgeRelay directory, or temporarily point
129
+ `FORGERELAY_CONFIG_DIR` at the old directory. If state or managed worktrees live
130
+ under older paths, preserve them with explicit `stateDir` / `worktreeRoot`
131
+ configuration until migration is complete.
129
132
 
130
133
  ## Check the setup
131
134
 
@@ -167,7 +167,7 @@ npm publishing token.
167
167
  3. Run the appropriate `release:patch`, `release:minor`, or `release:major`
168
168
  command.
169
169
  4. Review the generated version and changelog diff, then commit the release-ready code and metadata.
170
- 5. Push the release-ready `main` commit without changing it afterward.
170
+ 5. Run `npm run release:verify` on the committed release HEAD, then run `npm run release:push-ready`. This is the only normal release-ready branch push entrypoint: it requires a proof for the current HEAD, atomically advances `origin/main` plus the current `release/*` branch when applicable, rejects a local `main` with real unique patches, and synchronizes the local `main` ref after the remote push succeeds.
171
171
  6. Create the exact version tag, for example:
172
172
 
173
173
  ```bash
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@akira-tl/forgerelay",
3
- "version": "0.8.4",
3
+ "version": "0.8.6",
4
4
  "description": "Local development control plane for MCP coding agents.",
5
5
  "type": "module",
6
6
  "homepage": "https://github.com/Akira-TL/forgerelay#readme",
@@ -40,14 +40,18 @@
40
40
  "dev": "node scripts/debug/serve.mjs",
41
41
  "debug:serve": "node scripts/debug/serve.mjs",
42
42
  "debug:accept": "node scripts/debug/accept.mjs",
43
+ "debug:accept:relay": "node scripts/debug/relay-accept.mjs",
43
44
  "lsp:interop": "node scripts/lsp-interop.mjs",
45
+ "wiki:check": "node scripts/wiki/sync.mjs check",
46
+ "wiki:publish": "node scripts/wiki/sync.mjs publish",
44
47
  "ci:verify": "node scripts/ci/verify.mjs",
45
48
  "release:parity": "node scripts/release-parity.mjs",
46
49
  "release:pack": "node scripts/release/pack.mjs",
47
50
  "release:publish": "node scripts/release/publish.mjs",
51
+ "release:push-ready": "node scripts/release/push-ready.mjs",
48
52
  "postinstall": "node scripts/fix-node-pty-permissions.mjs",
49
53
  "start": "node dist/cli.js serve",
50
- "test": "node --test scripts/debug/runtime.test.mjs scripts/release-proof.test.mjs scripts/release/release-gate.test.mjs scripts/release/release-version.test.mjs && tsx src/oauth/router.test.ts && tsx src/remote-auth-cli.test.ts && tsx src/remote-ssh-auth-cli.test.ts && tsx src/remote-workspace-relay.test.ts && tsx src/remote-workspace-relay-process.test.ts && tsx src/config.test.ts && tsx src/lsp/language-server-config.test.ts && tsx src/lsp/normalization/hover.test.ts && tsx src/lsp/references.server.test.ts && tsx src/lsp/operations/document-symbols.server.test.ts && tsx src/lsp/operations/workspace-symbols.server.test.ts && tsx src/lsp/operations/diagnostics-push.server.test.ts && tsx src/lsp/operations/diagnostics-pull.server.test.ts && tsx src/lsp/operations/request-hardening.server.test.ts && tsx src/lsp/operations/recovery.server.test.ts && tsx src/lsp/operations/lifecycle.server.test.ts && tsx src/lsp/runtime/semantic-requests.test.ts && tsx src/logger.test.ts && tsx src/proxy-trust.test.ts && tsx src/mcp-app-template.test.ts && tsx src/hooks.test.ts && tsx src/capability-registry.test.ts && tsx src/mcp/server-instructions.test.ts && tsx src/request-meta.test.ts && tsx src/incoming-artifacts.test.ts && tsx src/artifact-download.test.ts && tsx src/ui/card-types.test.ts && tsx src/ui/workspace-lifecycle-app.test.ts && tsx src/ui/activity/model.test.ts && tsx src/ui/patch-display.test.ts && tsx src/ui/tool-display.test.ts && tsx src/apply-patch.test.ts && tsx src/process-platform.test.ts && tsx src/process-sessions.test.ts && tsx src/mcp-sessions.test.ts && tsx src/server-shutdown.test.ts && tsx src/subagents/providers/adapters/codex.test.ts && tsx src/subagents/providers/registry.test.ts && tsx src/subagents/providers/availability.test.ts && tsx src/subagents/profiles.test.ts && tsx src/subagents/cli-target.test.ts && tsx src/subagents/sessions/store.test.ts && tsx src/subagents/sessions/manager.test.ts && tsx src/subagents/sessions/mcp/capability.server.test.ts && tsx src/subagents/sessions/mcp/continuation.server.test.ts && tsx src/subagents/sessions/mcp/lifecycle.server.test.ts && tsx src/subagents/sessions/mcp/reconciliation.server.test.ts && tsx src/subagents/sessions/mcp/routing.server.test.ts && tsx src/roots.test.ts && tsx src/file-mutations.test.ts && tsx src/operations/edit-preflight.test.ts && tsx src/skills.test.ts && tsx src/db/migrations.test.ts && tsx src/workspace-store.test.ts && tsx src/workspace-tasks.test.ts && tsx src/workspace-task-reminders.test.ts && tsx src/activity/audit-store.test.ts && tsx src/activity/bash-output-store.test.ts && tsx src/activity/lifecycle.test.ts && tsx src/activity/query-service.test.ts && tsx src/operations/core-operation-executor.test.ts && tsx src/operations/bulk-mutation.test.ts && tsx src/operations/batch/scheduler.test.ts && tsx src/operations/batch/executor-policy.test.ts && tsx src/workspaces.test.ts && tsx src/workspace-conversation.test.ts && tsx src/review-checkpoints.test.ts && tsx src/lsp/code-intelligence.server.test.ts && npm run build:app && tsx src/server.test.ts && tsx src/oauth-store.test.ts && tsx src/cli.test.ts",
54
+ "test": "node --test scripts/debug/runtime.test.mjs scripts/release-proof.test.mjs scripts/release/release-gate.test.mjs scripts/release/push-ready.test.mjs scripts/release/release-version.test.mjs && tsx src/oauth/router.test.ts && tsx src/remote-auth-cli.test.ts && tsx src/remote-ssh-auth-cli.test.ts && tsx src/remote-workspace-relay.test.ts && tsx src/remote-workspace-relay-process.test.ts && tsx src/config.test.ts && tsx src/lsp/language-server-config.test.ts && tsx src/lsp/normalization/hover.test.ts && tsx src/lsp/references.server.test.ts && tsx src/lsp/operations/document-symbols.server.test.ts && tsx src/lsp/operations/workspace-symbols.server.test.ts && tsx src/lsp/operations/diagnostics-push.server.test.ts && tsx src/lsp/operations/diagnostics-pull.server.test.ts && tsx src/lsp/operations/request-hardening.server.test.ts && tsx src/lsp/operations/recovery.server.test.ts && tsx src/lsp/operations/lifecycle.server.test.ts && tsx src/lsp/runtime/semantic-requests.test.ts && tsx src/logger.test.ts && tsx src/proxy-trust.test.ts && tsx src/mcp-app-template.test.ts && tsx src/hooks.test.ts && tsx src/capability-registry.test.ts && tsx src/mcp/server-instructions.test.ts && tsx src/request-meta.test.ts && tsx src/incoming-artifacts.test.ts && tsx src/artifact-download.test.ts && tsx src/ui/card-types.test.ts && tsx src/ui/workspace-lifecycle-app.test.ts && tsx src/ui/activity/model.test.ts && tsx src/ui/patch-display.test.ts && tsx src/ui/tool-display.test.ts && tsx src/apply-patch.test.ts && tsx src/process-platform.test.ts && tsx src/process-sessions.test.ts && tsx src/mcp-sessions.test.ts && tsx src/server-shutdown.test.ts && tsx src/subagents/providers/adapters/codex.test.ts && tsx src/subagents/providers/registry.test.ts && tsx src/subagents/providers/availability.test.ts && tsx src/subagents/profiles.test.ts && tsx src/subagents/cli-target.test.ts && tsx src/subagents/sessions/store.test.ts && tsx src/subagents/sessions/manager.test.ts && tsx src/subagents/sessions/mcp/capability.server.test.ts && tsx src/subagents/sessions/mcp/continuation.server.test.ts && tsx src/subagents/sessions/mcp/lifecycle.server.test.ts && tsx src/subagents/sessions/mcp/reconciliation.server.test.ts && tsx src/subagents/sessions/mcp/routing.server.test.ts && tsx src/roots.test.ts && tsx src/file-mutations.test.ts && tsx src/operations/edit-preflight.test.ts && tsx src/skills.test.ts && tsx src/db/migrations.test.ts && tsx src/workspace-store.test.ts && tsx src/workspace-tasks.test.ts && tsx src/workspace-task-reminders.test.ts && tsx src/activity/audit-store.test.ts && tsx src/activity/bash-output-store.test.ts && tsx src/activity/lifecycle.test.ts && tsx src/activity/query-service.test.ts && tsx src/operations/core-operation-executor.test.ts && tsx src/operations/bulk-mutation.test.ts && tsx src/operations/batch/scheduler.test.ts && tsx src/operations/batch/executor-policy.test.ts && tsx src/workspaces.test.ts && tsx src/workspace-conversation.test.ts && tsx src/review-checkpoints.test.ts && tsx src/lsp/code-intelligence.server.test.ts && npm run build:app && tsx src/server.test.ts && tsx src/oauth-store.test.ts && tsx src/cli.test.ts",
51
55
  "typecheck": "tsc -p tsconfig.json --noEmit",
52
56
  "release:check": "node scripts/release-version.mjs check",
53
57
  "release:tag-check": "node scripts/release-version.mjs tag",
@@ -155,6 +155,7 @@ try {
155
155
  "open_workspace",
156
156
  "activity_panel",
157
157
  "activity_snapshot",
158
+ "activity_index",
158
159
  "activity_detail",
159
160
  "activity_output",
160
161
  "capability",
@@ -694,8 +695,13 @@ try {
694
695
  });
695
696
  assert.equal(inspectorSnapshot.isError, undefined);
696
697
  assert.ok(inspectorSnapshot.structuredContent.revision > 0);
698
+ assert.equal(inspectorSnapshot.structuredContent.activities, undefined);
699
+ const inspectorIndex = callTool(oauth.accessToken, sessionId, 93, "activity_index", {
700
+ turnId: inspectorTurnId,
701
+ });
702
+ assert.equal(inspectorIndex.isError, undefined);
697
703
  assert.deepEqual(
698
- inspectorSnapshot.structuredContent.activities.map(({ tool, workspaceId: activityWorkspaceId, target }) => ({
704
+ inspectorIndex.structuredContent.activities.map(({ tool, workspaceId: activityWorkspaceId, target }) => ({
699
705
  tool,
700
706
  workspaceId: activityWorkspaceId,
701
707
  target,