fix(web): return every service a host row injects, and run the browser lane
The browser e2e lane had been failing wholesale since this stack moved the agent plane into presets, and nothing caught it: 34 of 48 files. Two of the causes are product defects, not test breakage. `bashEnv` goes back to the host plane. `apps/cli/src/web.ts` injects it to publish `DSH_WEB_URL`/`DSH_WEB_MODE`, so the earlier note that "nothing outside the agent plane injects bashEnv" was simply wrong — behind a preset's `shell` realm those variables reached no shell at all, and a `dsh web` agent could not find the address of its own interface. This is the same criterion that returned `subagents`: a host row that injects a service resolves before any session exists and has no agent to key by, so the service is host-plane. `tool-bash` consumes the host registry from inside the preset, which works because an agent context chains to the host; only the reverse is invisible. `tool-subagent-report` goes back with it. It is not a tool this agent calls: it registers a continuable SETUP on the host `subagents` singleton, and that list is not scope-aware. One copy per mounted preset meant every child was handed `report` once per live session, so the second registration threw and a cold subagent resume failed with `subagent-not-resumable` — a diagnostic three layers removed from the cause. The lane's own composition facts follow. Skill roots resolve inside a preset now, a subtree include patches cannot reach, so the scaffold pins the roots' documented environment fallback for its whole lifetime rather than for the boot — presets mount per session. Without it the developer's real `~/.dsh/skills` enters replay requests and goldens while CI sees none. The `apps/cli` composition test pins `storage-json` for the same reason: unpinned it wrote, and then read back, the developer's own `~/.dsh/storages/`. Three tests now address through an agent what they used to read off the root context, because that is where the thing lives: the tool catalog, the skill registry, and the token meter. The seeded-history projection baseline asserts the opposite of what it did — a detached session yields a preset-plane projection only from a durable checkpoint written while it was live, and this seed was written straight to persistence and never ran. Goldens re-recorded for the hero's preset chip and the settings nav entry.
This commit is contained in:
@@ -206,8 +206,6 @@
|
||||
# absent from a surface overlay would silently reappear the day someone reorders
|
||||
# the composition.
|
||||
|
||||
- id: bash-env
|
||||
disabled: true
|
||||
|
||||
- id: tool-bash
|
||||
disabled: true
|
||||
@@ -282,9 +280,6 @@
|
||||
- id: tool-subagent-fork
|
||||
disabled: true
|
||||
|
||||
- id: tool-subagent-report
|
||||
disabled: true
|
||||
|
||||
- id: workflow-workerthread
|
||||
disabled: true
|
||||
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write packages/client/README.md
|
||||
README.md: a0888b0d02d3d6ed234489d686ae9ad996e11674
|
||||
README.zh.md: a6e4e42c12c97802897c6d58efdcc7468d45db8c
|
||||
README.md: c2400ce36dc0df5494cdf69ec9fe34c71c2b65b9
|
||||
README.zh.md: b88c28df776c1a74f9b652282756b614229e0ff5
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write packages/client/connection/README.md
|
||||
README.md: 526df44ce2a167e6f06bedea6d57e4d703848e89
|
||||
README.zh.md: 02bba4aeed7155ebacae2ad66b4325d069f37301
|
||||
README.md: 0392d51a929e2b92d9cd4b4728549250437631f1
|
||||
README.zh.md: e82b25bf30717abbcd9ec460b5790277d3f9ce13
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write packages/client/ui-agent-preset/README.md
|
||||
README.md: 3df8e43892ea619155918b28a171d30b6f9d1a3d
|
||||
README.zh.md: 4725517c6f2ebf5b172bd01023cdef0de6f542ac
|
||||
README.md: 6261984835a70b6b669545acc8f9bfafc93ab64d
|
||||
README.zh.md: fb860812b1646f6b1912e4aedf56b00696957352
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write packages/client/ui-question/README.md
|
||||
README.md: 00763e03234468e80dce56d99e6abb719a0d97e3
|
||||
README.zh.md: b0dd70264e885c73d7be76add800326e9740ef44
|
||||
README.md: d31ceb62c46cb7a720b52d9e2a6c92e98d1c7e42
|
||||
README.zh.md: 9f9ad01c3f1f661f60fe11ec072f487cb18c170a
|
||||
|
||||
@@ -98,15 +98,15 @@ export const SERVICE_API: readonly ServiceApiEntry[] = [
|
||||
},
|
||||
{
|
||||
signature: 'async read(id: string): Promise<string>',
|
||||
jsDoc: '/**\n * Read one profile\'s composition text.\n * @param id - the profile id.\n * @returns the composition exactly as stored.\n * @throws when no configured root supplies that id.\n */',
|
||||
jsDoc: '/**\n * Read one preset\'s composition text.\n * @param id - the preset id.\n * @returns the composition exactly as stored.\n * @throws when no configured root supplies that id.\n */',
|
||||
},
|
||||
{
|
||||
signature: 'async write(id: string, content: string, metadata: PresetMetadata = {}): Promise<void>',
|
||||
jsDoc: '/**\n * Create or replace a locally authored profile.\n *\n * The text is shape-checked before it lands, so a save cannot leave a file no\n * session could load; it is NOT mounted, so a composition that parses but\n * names a missing plugin still fails at the next session that selects it.\n * @param id - the profile id, which becomes its directory name.\n * @param content - the composition text.\n * @param metadata - display name and description; clearing both removes the file.\n * @throws when the id is unusable, the text is not an entry list, or the\n * deployment configures no writable root.\n */',
|
||||
jsDoc: '/**\n * Create or replace a locally authored preset.\n *\n * The text is shape-checked before it lands, so a save cannot leave a file no\n * session could load; it is NOT mounted, so a composition that parses but\n * names a missing plugin still fails at the next session that selects it.\n * @param id - the preset id, which becomes its directory name.\n * @param content - the composition text.\n * @param metadata - display name and description; clearing both removes the file.\n * @throws when the id is unusable, the text is not an entry list, or the\n * deployment configures no writable root.\n */',
|
||||
},
|
||||
{
|
||||
signature: 'async remove(id: string): Promise<void>',
|
||||
jsDoc: '/**\n * Delete a locally authored profile.\n * @param id - the profile id.\n * @throws when the profile is unknown or ships with the deployment.\n */',
|
||||
jsDoc: '/**\n * Delete a locally authored preset.\n * @param id - the preset id.\n * @throws when the preset is unknown or ships with the deployment.\n */',
|
||||
},
|
||||
{
|
||||
signature: 'serviceFor<K extends string & keyof Context>(agent: { ctx: Context }, name: K): Context[K] | undefined',
|
||||
@@ -2227,6 +2227,10 @@ export const TYPE_API: readonly TypeApiEntry[] = [
|
||||
name: 'PrepareSessionOptions',
|
||||
declaration: 'export type PrepareSessionOptions = (CreateSessionOptions & {\n readonly seedSource?: undefined;\n}) | RestoredSessionOptions;',
|
||||
},
|
||||
{
|
||||
name: 'PresetMetadata',
|
||||
declaration: 'export interface PresetMetadata {\n readonly name?: string;\n readonly description?: string;\n readonly order?: number;\n}',
|
||||
},
|
||||
{
|
||||
name: 'PresetOption',
|
||||
declaration: 'export interface PresetOption {\n value: string;\n name: string;\n description?: string;\n}',
|
||||
@@ -2235,10 +2239,6 @@ export const TYPE_API: readonly TypeApiEntry[] = [
|
||||
name: 'PresetSpec',
|
||||
declaration: 'export interface PresetSpec {\n sandbox: SandboxMode;\n approval: ApprovalPolicy;\n name?: string;\n description?: string;\n}',
|
||||
},
|
||||
{
|
||||
name: 'PresetMetadata',
|
||||
declaration: 'export interface PresetMetadata {\n readonly name?: string;\n readonly description?: string;\n readonly order?: number;\n}',
|
||||
},
|
||||
{
|
||||
name: 'PresetTrust',
|
||||
declaration: 'export type PresetTrust = \'system\' | \'user\';',
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write packages/host/apiproxy/README.md
|
||||
README.md: abada8172e0ddc74850e1b3a0ec6b19aee5b8011
|
||||
README.zh.md: 833ebf603da94ecd46dec5f8ea8c22b71d164859
|
||||
README.md: 2715a3115307017a06ac13f35efd50c239036923
|
||||
README.zh.md: 597c1fe2df6ce97385e16c6120e62fdfe0ab090d
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write packages/preset/README.md
|
||||
README.md: 997e64c75e36d6a70438a92c223dea93eab5eb32
|
||||
README.zh.md: 946b98a7b1366facec37360c9f39ca36cc908872
|
||||
README.md: ca874398f06728af60999d11f03b67fb2f4b62e0
|
||||
README.zh.md: 2187bc78ed2ad2dffcc989c587992e3aeda3c5ea
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write packages/preset/agent-presets/README.md
|
||||
README.md: b6f00366ef319637d19cccb513d41dbff1eaa5e1
|
||||
README.zh.md: f09fd89c2c9bfb08fafbdb47b80ebaf26ae42b47
|
||||
README.md: c61a84730a273052eeab31dc24696a7340621d4f
|
||||
README.zh.md: 1caacec4f93990865e82c4498e64578eb149a3d6
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write packages/session-persistence/session-persistence-jsonl/README.md
|
||||
README.md: 7cd3b36f40e00e37c161ebb30eaae95f86337203
|
||||
README.zh.md: a7395c94eb8adcddf30b3b8452c5426d57ae3a4e
|
||||
README.md: 79bc4cebe6f303a5aa8b73a60dfee55dcb9a90a7
|
||||
README.zh.md: 9bd4d34f2983c60d5df2d5bab85913618d2e6d66
|
||||
|
||||
Reference in New Issue
Block a user