@skaile/workspaces 0.9.1 → 0.10.1

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 (102) hide show
  1. package/CHANGELOG.md +38 -0
  2. package/README.md +2 -2
  3. package/dist/asset-manager/index.js +2 -2
  4. package/dist/asset-manager/scaffold.js +1 -1
  5. package/dist/base-assets/connectors/deploy.js +1 -1
  6. package/dist/base-assets/connectors/devserver.js +1 -1
  7. package/dist/base-assets/connectors/flow/adapter.js +1 -1
  8. package/dist/base-assets/connectors/flow/run-flow.js +2 -2
  9. package/dist/base-assets/connectors/flow.js +1 -1
  10. package/dist/base-assets/connectors/git.js +1 -1
  11. package/dist/base-assets/connectors/gmail.js +1 -1
  12. package/dist/base-assets/connectors/local.js +1 -1
  13. package/dist/base-assets/connectors/mattermost.js +1 -1
  14. package/dist/base-assets/connectors/memory.js +1 -1
  15. package/dist/base-assets/connectors/minio.js +1 -1
  16. package/dist/base-assets/connectors/postgres.js +1 -1
  17. package/dist/base-assets/connectors/redis.js +1 -1
  18. package/dist/base-assets/connectors/s3.js +1 -1
  19. package/dist/base-assets/connectors/sharepoint.js +1 -1
  20. package/dist/base-assets/connectors/sqlite.js +1 -1
  21. package/dist/base-assets/connectors/static-server.js +1 -1
  22. package/dist/base-assets/connectors/tunnel.js +1 -1
  23. package/dist/base-assets/connectors/webdav.js +1 -1
  24. package/dist/base-assets/connectors/xstate-store.js +1 -1
  25. package/dist/base-assets/connectors/xstate.js +1 -1
  26. package/dist/base-assets/connectors/yjs.js +1 -1
  27. package/dist/bridge/drivers/claude-sdk.js +53 -3
  28. package/dist/bridge/drivers/claude-sdk.js.map +1 -1
  29. package/dist/bridge/drivers/codex.js +1 -1
  30. package/dist/bridge/drivers/echo.js +1 -1
  31. package/dist/bridge/drivers/omp.js +1 -1
  32. package/dist/bridge/index.js +2 -2
  33. package/dist/bridge/src/drivers/claude-sdk.d.ts +23 -0
  34. package/dist/bridge/src/drivers/claude-sdk.d.ts.map +1 -1
  35. package/dist/{chunk-5IC6CJL4.js → chunk-BTKNSMLK.js} +2 -2
  36. package/dist/{chunk-5IC6CJL4.js.map → chunk-BTKNSMLK.js.map} +1 -1
  37. package/dist/{chunk-TODD4VNR.js → chunk-D3VO6WNC.js} +85 -3
  38. package/dist/chunk-D3VO6WNC.js.map +1 -0
  39. package/dist/{chunk-I3S4BAAR.js → chunk-FEBLE7QX.js} +2 -2
  40. package/dist/{chunk-I3S4BAAR.js.map → chunk-FEBLE7QX.js.map} +1 -1
  41. package/dist/{chunk-DTL7S57T.js → chunk-IFRUVHOQ.js} +3 -3
  42. package/dist/{chunk-DTL7S57T.js.map → chunk-IFRUVHOQ.js.map} +1 -1
  43. package/dist/{chunk-XIVOEUAF.js → chunk-OQIBHB4F.js} +2 -2
  44. package/dist/{chunk-XIVOEUAF.js.map → chunk-OQIBHB4F.js.map} +1 -1
  45. package/dist/{chunk-K3TMZI6D.js → chunk-OSJH4SPO.js} +3 -3
  46. package/dist/{chunk-K3TMZI6D.js.map → chunk-OSJH4SPO.js.map} +1 -1
  47. package/dist/{chunk-QZ6PY73K.js → chunk-OVM36NYF.js} +18 -23
  48. package/dist/chunk-OVM36NYF.js.map +1 -0
  49. package/dist/{chunk-AE6GCXGL.js → chunk-S7RACIZI.js} +2 -2
  50. package/dist/{chunk-AE6GCXGL.js.map → chunk-S7RACIZI.js.map} +1 -1
  51. package/dist/{chunk-O5AE4QDX.js → chunk-TDSRLMDB.js} +4 -4
  52. package/dist/chunk-TDSRLMDB.js.map +1 -0
  53. package/dist/{chunk-EPGHAOEU.js → chunk-UHSC75L7.js} +19 -3
  54. package/dist/chunk-UHSC75L7.js.map +1 -0
  55. package/dist/chunk-W3UDISS2.js +31 -0
  56. package/dist/chunk-W3UDISS2.js.map +1 -0
  57. package/dist/cli/index.js +11 -10
  58. package/dist/cli/index.js.map +1 -1
  59. package/dist/connectors/index.js +1 -1
  60. package/dist/connectors/src/connector-manager.d.ts +7 -0
  61. package/dist/connectors/src/connector-manager.d.ts.map +1 -1
  62. package/dist/runner/index.js +7 -6
  63. package/dist/runner/prompt-assembly.js +4 -0
  64. package/dist/runner/prompt-assembly.js.map +1 -0
  65. package/dist/runner/src/capability-registry.d.ts.map +1 -1
  66. package/dist/runner/src/capability-roundtrip.d.ts +18 -0
  67. package/dist/runner/src/capability-roundtrip.d.ts.map +1 -1
  68. package/dist/runner/src/define-capability.d.ts +7 -0
  69. package/dist/runner/src/define-capability.d.ts.map +1 -1
  70. package/dist/runner/src/prompt-assembly.d.ts +39 -0
  71. package/dist/runner/src/prompt-assembly.d.ts.map +1 -1
  72. package/dist/runner/src/serve.d.ts.map +1 -1
  73. package/dist/sdk/asset-manager.js +2 -2
  74. package/dist/sdk/bridge.js +2 -2
  75. package/dist/sdk/index.js +7 -6
  76. package/dist/sdk/index.js.map +1 -1
  77. package/dist/sdk/runner.js +7 -6
  78. package/dist/sdk/session.js +2 -2
  79. package/dist/sdk/types.js +1 -1
  80. package/dist/session/index.js +2 -2
  81. package/dist/session/src/dispatcher.d.ts +57 -0
  82. package/dist/session/src/dispatcher.d.ts.map +1 -1
  83. package/dist/{setup-PHFPBDBI.js → setup-QIEPIYH2.js} +4 -4
  84. package/dist/{setup-PHFPBDBI.js.map → setup-QIEPIYH2.js.map} +1 -1
  85. package/dist/tui/index.js +7 -6
  86. package/dist/tui/index.js.map +1 -1
  87. package/dist/types/index.js +1 -1
  88. package/dist/types/src/capabilities.d.ts +13 -0
  89. package/dist/types/src/capabilities.d.ts.map +1 -1
  90. package/dist/types/src/events.d.ts +29 -1
  91. package/dist/types/src/events.d.ts.map +1 -1
  92. package/dist/types/src/index.d.ts +1 -1
  93. package/dist/types/src/index.d.ts.map +1 -1
  94. package/dist/types/src/version.d.ts +19 -1
  95. package/dist/types/src/version.d.ts.map +1 -1
  96. package/dist/workspace-plugin/adapters/mcp.js +2 -2
  97. package/dist/workspace-plugin/index.js +1 -1
  98. package/package.json +7 -1
  99. package/dist/chunk-EPGHAOEU.js.map +0 -1
  100. package/dist/chunk-O5AE4QDX.js.map +0 -1
  101. package/dist/chunk-QZ6PY73K.js.map +0 -1
  102. package/dist/chunk-TODD4VNR.js.map +0 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,43 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.10.1
4
+
5
+ ### Patch Changes
6
+
7
+ - addb191: `ConnectorManager.buildWrappedMediator` now falls back to the legacy
8
+ `mount:<id>` pre-mint namespace when no `connector:<id>` entry is found,
9
+ emitting a single `warn` log on each fallback hit
10
+ (`"connector credential resolved via mount-namespace fallback"`).
11
+
12
+ Defence-in-depth companion to the platform-side pre-mint namespace
13
+ alignment (2026-05-19 incident): when the platform writer files git
14
+ credentials under the pre-unified key, the runner still resolves the
15
+ token and the warn log surfaces the drift so operators can detect a
16
+ platform regression. The primary `connector:` lookup path is unchanged
17
+ and incurs no extra work.
18
+
19
+ ## 0.10.0
20
+
21
+ ### Minor Changes
22
+
23
+ - eb14ab2: Add runtime support for agent-to-agent (session-to-session) communication:
24
+ - New `a2a_message` event kind in the agent event union.
25
+ - `SessionDispatcher.onceNextFinished` — a one-shot hook that resolves on the
26
+ session's next finished assistant turn, used to capture a peer's answer to a
27
+ synchronous `ask`.
28
+ - `SessionDispatcher.deliverPrompt` — delivers a turn-triggering prompt without
29
+ persisting it to the message store (A2A message persistence is owned by the
30
+ caller).
31
+ - Per-capability `callTimeoutMs` on the capability definition + wire format, so
32
+ a long-running capability call (e.g. a 5-minute `ask_session`) can exceed the
33
+ default capability-call timeout.
34
+ - `buildLinkedPeersPromptSection` — renders a `<LINKED_PEERS>` system-prompt
35
+ block from a session's linked peers, exported via the new
36
+ `@skaile/workspaces/runner/prompt-assembly` subpath.
37
+ - `PROTOCOL_VERSION` bumped to `3.3.0` for the additive A2A wire surface
38
+ (`a2a_message` event + capability `callTimeoutMs`); also backfills the
39
+ `3.2.0` changelog entry for the previously-undocumented resume cascade.
40
+
3
41
  ## 0.9.1
4
42
 
5
43
  ### Patch Changes
package/README.md CHANGED
@@ -76,7 +76,7 @@ bun run cli run mvp # run a flow
76
76
 
77
77
  ## Architecture Docs
78
78
 
79
- - [Client-Server Architecture](docs/client-server-architecture.md) — design for the agent client, transport, and shared state protocol (new packages: `client`, `transport`)
80
- - [Session Dispatcher Architecture](session/docs/architecture.md) — design for session message dispatching, persistence, and fan-out (new package: `session`)
79
+ - [Client-Server Architecture](../../docs/client-server-architecture.md) — design for the agent client, transport, and shared state protocol (new packages: `client`, `transport`)
80
+ - [Session Dispatcher Architecture](../../docs/session/architecture.md) — design for session message dispatching, persistence, and fan-out (new package: `session`)
81
81
 
82
82
  See each package's `CLAUDE.md` for architecture details and developer conventions.
@@ -1,8 +1,8 @@
1
- export { AssetManager } from '../chunk-I3S4BAAR.js';
1
+ export { AssetManager } from '../chunk-FEBLE7QX.js';
2
2
  export { createScaffold, deployAll, removeAsset } from '../chunk-M2NLRGIX.js';
3
3
  export { appendHistory, clearHistory, getRecentHistory, loadHistory } from '../chunk-KTBKW2FI.js';
4
4
  import '../chunk-UQ6LFBPZ.js';
5
- export { listTemplates, scaffoldWorkspace, setTemplatesDir } from '../chunk-XIVOEUAF.js';
5
+ export { listTemplates, scaffoldWorkspace, setTemplatesDir } from '../chunk-OQIBHB4F.js';
6
6
  import '../chunk-DIKFRNCS.js';
7
7
  import '../chunk-4RUVG5GX.js';
8
8
  import '../chunk-JKNWJ64A.js';
@@ -1,4 +1,4 @@
1
- export { applyBaseLayer, applyConnectorsLayer, applyContainerLayer, applyDriverTargetLayer, applyHooksLayer, applySkillsLayer, applyTemplateLayer, listTemplates, loadTemplate, resolveTemplatePath, scaffoldWorkspace, setTemplatesDir } from '../chunk-XIVOEUAF.js';
1
+ export { applyBaseLayer, applyConnectorsLayer, applyContainerLayer, applyDriverTargetLayer, applyHooksLayer, applySkillsLayer, applyTemplateLayer, listTemplates, loadTemplate, resolveTemplatePath, scaffoldWorkspace, setTemplatesDir } from '../chunk-OQIBHB4F.js';
2
2
  export { applyAgentsLayer } from '../chunk-DIKFRNCS.js';
3
3
  import '../chunk-4RUVG5GX.js';
4
4
  import '../chunk-JKNWJ64A.js';
@@ -1,4 +1,4 @@
1
- export { DeployConnector, createConnector20 as createConnector } from '../../chunk-EPGHAOEU.js';
1
+ export { DeployConnector, createConnector20 as createConnector } from '../../chunk-UHSC75L7.js';
2
2
  import '../../chunk-W75ASXH4.js';
3
3
  import '../../chunk-EBMFCF4P.js';
4
4
  import '../../chunk-GCRKAFH7.js';
@@ -1,4 +1,4 @@
1
- export { DevServerConnector, createConnector17 as createConnector } from '../../chunk-EPGHAOEU.js';
1
+ export { DevServerConnector, createConnector17 as createConnector } from '../../chunk-UHSC75L7.js';
2
2
  import '../../chunk-W75ASXH4.js';
3
3
  import '../../chunk-EBMFCF4P.js';
4
4
  import '../../chunk-GCRKAFH7.js';
@@ -1,4 +1,4 @@
1
- export { FlowAdapter, createConnector } from '../../../chunk-EPGHAOEU.js';
1
+ export { FlowAdapter, createConnector } from '../../../chunk-UHSC75L7.js';
2
2
  import '../../../chunk-W75ASXH4.js';
3
3
  import '../../../chunk-EBMFCF4P.js';
4
4
  import '../../../chunk-GCRKAFH7.js';
@@ -1,7 +1,7 @@
1
- export { resumeFlow, runFlow } from '../../../chunk-DTL7S57T.js';
1
+ export { resumeFlow, runFlow } from '../../../chunk-IFRUVHOQ.js';
2
2
  import '../../../chunk-GCJXPUHG.js';
3
3
  import '../../../chunk-IPUYL6TD.js';
4
- import '../../../chunk-EPGHAOEU.js';
4
+ import '../../../chunk-UHSC75L7.js';
5
5
  import '../../../chunk-W75ASXH4.js';
6
6
  import '../../../chunk-EBMFCF4P.js';
7
7
  import '../../../chunk-GCRKAFH7.js';
@@ -1,4 +1,4 @@
1
- export { FlowAdapter, createConnector } from '../../chunk-EPGHAOEU.js';
1
+ export { FlowAdapter, createConnector } from '../../chunk-UHSC75L7.js';
2
2
  import '../../chunk-W75ASXH4.js';
3
3
  import '../../chunk-EBMFCF4P.js';
4
4
  import '../../chunk-GCRKAFH7.js';
@@ -1,4 +1,4 @@
1
- export { GitConnector, createConnector2 as createConnector } from '../../chunk-EPGHAOEU.js';
1
+ export { GitConnector, createConnector2 as createConnector } from '../../chunk-UHSC75L7.js';
2
2
  import '../../chunk-W75ASXH4.js';
3
3
  import '../../chunk-EBMFCF4P.js';
4
4
  import '../../chunk-GCRKAFH7.js';
@@ -1,4 +1,4 @@
1
- export { GmailConnector, createConnector15 as createConnector } from '../../chunk-EPGHAOEU.js';
1
+ export { GmailConnector, createConnector15 as createConnector } from '../../chunk-UHSC75L7.js';
2
2
  import '../../chunk-W75ASXH4.js';
3
3
  import '../../chunk-EBMFCF4P.js';
4
4
  import '../../chunk-GCRKAFH7.js';
@@ -1,4 +1,4 @@
1
- export { LocalConnector, createConnector3 as createConnector } from '../../chunk-EPGHAOEU.js';
1
+ export { LocalConnector, createConnector3 as createConnector } from '../../chunk-UHSC75L7.js';
2
2
  import '../../chunk-W75ASXH4.js';
3
3
  import '../../chunk-EBMFCF4P.js';
4
4
  import '../../chunk-GCRKAFH7.js';
@@ -1,4 +1,4 @@
1
- export { MattermostConnector, createConnector16 as createConnector } from '../../chunk-EPGHAOEU.js';
1
+ export { MattermostConnector, createConnector16 as createConnector } from '../../chunk-UHSC75L7.js';
2
2
  import '../../chunk-W75ASXH4.js';
3
3
  import '../../chunk-EBMFCF4P.js';
4
4
  import '../../chunk-GCRKAFH7.js';
@@ -1,4 +1,4 @@
1
- export { MemoryConnector, createConnector7 as createConnector } from '../../chunk-EPGHAOEU.js';
1
+ export { MemoryConnector, createConnector7 as createConnector } from '../../chunk-UHSC75L7.js';
2
2
  import '../../chunk-W75ASXH4.js';
3
3
  import '../../chunk-EBMFCF4P.js';
4
4
  import '../../chunk-GCRKAFH7.js';
@@ -1,4 +1,4 @@
1
- export { MinIOConnector, createConnector11 as createConnector } from '../../chunk-EPGHAOEU.js';
1
+ export { MinIOConnector, createConnector11 as createConnector } from '../../chunk-UHSC75L7.js';
2
2
  import '../../chunk-W75ASXH4.js';
3
3
  import '../../chunk-EBMFCF4P.js';
4
4
  import '../../chunk-GCRKAFH7.js';
@@ -1,4 +1,4 @@
1
- export { PostgresConnector, createConnector8 as createConnector } from '../../chunk-EPGHAOEU.js';
1
+ export { PostgresConnector, createConnector8 as createConnector } from '../../chunk-UHSC75L7.js';
2
2
  import '../../chunk-W75ASXH4.js';
3
3
  import '../../chunk-EBMFCF4P.js';
4
4
  import '../../chunk-GCRKAFH7.js';
@@ -1,4 +1,4 @@
1
- export { RedisConnector, createConnector9 as createConnector } from '../../chunk-EPGHAOEU.js';
1
+ export { RedisConnector, createConnector9 as createConnector } from '../../chunk-UHSC75L7.js';
2
2
  import '../../chunk-W75ASXH4.js';
3
3
  import '../../chunk-EBMFCF4P.js';
4
4
  import '../../chunk-GCRKAFH7.js';
@@ -1,4 +1,4 @@
1
- export { S3Connector, createConnector4 as createConnector } from '../../chunk-EPGHAOEU.js';
1
+ export { S3Connector, createConnector4 as createConnector } from '../../chunk-UHSC75L7.js';
2
2
  import '../../chunk-W75ASXH4.js';
3
3
  import '../../chunk-EBMFCF4P.js';
4
4
  import '../../chunk-GCRKAFH7.js';
@@ -1,4 +1,4 @@
1
- export { SharePointConnector, createConnector6 as createConnector } from '../../chunk-EPGHAOEU.js';
1
+ export { SharePointConnector, createConnector6 as createConnector } from '../../chunk-UHSC75L7.js';
2
2
  import '../../chunk-W75ASXH4.js';
3
3
  import '../../chunk-EBMFCF4P.js';
4
4
  import '../../chunk-GCRKAFH7.js';
@@ -1,4 +1,4 @@
1
- export { SQLiteConnector, createConnector10 as createConnector } from '../../chunk-EPGHAOEU.js';
1
+ export { SQLiteConnector, createConnector10 as createConnector } from '../../chunk-UHSC75L7.js';
2
2
  import '../../chunk-W75ASXH4.js';
3
3
  import '../../chunk-EBMFCF4P.js';
4
4
  import '../../chunk-GCRKAFH7.js';
@@ -1,4 +1,4 @@
1
- export { StaticServerConnector, createConnector18 as createConnector } from '../../chunk-EPGHAOEU.js';
1
+ export { StaticServerConnector, createConnector18 as createConnector } from '../../chunk-UHSC75L7.js';
2
2
  import '../../chunk-W75ASXH4.js';
3
3
  import '../../chunk-EBMFCF4P.js';
4
4
  import '../../chunk-GCRKAFH7.js';
@@ -1,4 +1,4 @@
1
- export { TunnelConnector, createConnector19 as createConnector } from '../../chunk-EPGHAOEU.js';
1
+ export { TunnelConnector, createConnector19 as createConnector } from '../../chunk-UHSC75L7.js';
2
2
  import '../../chunk-W75ASXH4.js';
3
3
  import '../../chunk-EBMFCF4P.js';
4
4
  import '../../chunk-GCRKAFH7.js';
@@ -1,4 +1,4 @@
1
- export { WebDAVConnector, createConnector5 as createConnector } from '../../chunk-EPGHAOEU.js';
1
+ export { WebDAVConnector, createConnector5 as createConnector } from '../../chunk-UHSC75L7.js';
2
2
  import '../../chunk-W75ASXH4.js';
3
3
  import '../../chunk-EBMFCF4P.js';
4
4
  import '../../chunk-GCRKAFH7.js';
@@ -1,4 +1,4 @@
1
- export { XStateStoreConnector, createConnector13 as createConnector } from '../../chunk-EPGHAOEU.js';
1
+ export { XStateStoreConnector, createConnector13 as createConnector } from '../../chunk-UHSC75L7.js';
2
2
  import '../../chunk-W75ASXH4.js';
3
3
  import '../../chunk-EBMFCF4P.js';
4
4
  import '../../chunk-GCRKAFH7.js';
@@ -1,4 +1,4 @@
1
- export { XStateConnector, createConnector12 as createConnector } from '../../chunk-EPGHAOEU.js';
1
+ export { XStateConnector, createConnector12 as createConnector } from '../../chunk-UHSC75L7.js';
2
2
  import '../../chunk-W75ASXH4.js';
3
3
  import '../../chunk-EBMFCF4P.js';
4
4
  import '../../chunk-GCRKAFH7.js';
@@ -1,4 +1,4 @@
1
- export { YjsConnector, createConnector14 as createConnector } from '../../chunk-EPGHAOEU.js';
1
+ export { YjsConnector, createConnector14 as createConnector } from '../../chunk-UHSC75L7.js';
2
2
  import '../../chunk-W75ASXH4.js';
3
3
  import '../../chunk-EBMFCF4P.js';
4
4
  import '../../chunk-GCRKAFH7.js';
@@ -1,7 +1,7 @@
1
1
  import { classifyClaudeSdkError, AuthError } from '../../chunk-EWP5HZBV.js';
2
2
  import { fetchProviderModels } from '../../chunk-KOVLSBXK.js';
3
3
  import { dispatchCapability } from '../../chunk-RRVQAE5D.js';
4
- import { registerDriver, DRIVER_CATALOG, AgentDriver, getBridgeLogger } from '../../chunk-AE6GCXGL.js';
4
+ import { registerDriver, DRIVER_CATALOG, AgentDriver, getBridgeLogger } from '../../chunk-S7RACIZI.js';
5
5
  import '../../chunk-24UIWON4.js';
6
6
  import '../../chunk-NSBPE2FW.js';
7
7
  import { spawnSync } from 'child_process';
@@ -367,9 +367,8 @@ var ClaudeSdkDriver = class extends AgentDriver {
367
367
  const isPoisonedHistory = _retryCount === 0 && /invalid_request_error/i.test(errMsg) && /media[_ ]?type|could not process image|image exceeds|cache_control/i.test(errMsg);
368
368
  const poisonSessionId = this.config.resumeSessionId || this.sessionId;
369
369
  if (isPoisonedHistory && poisonSessionId) {
370
- const configDir = this.config.env?.CLAUDE_CONFIG_DIR || process.env.CLAUDE_CONFIG_DIR || join(homedir(), ".claude");
371
370
  const scrub = scrubPoisonedTranscript({
372
- configDir,
371
+ configDir: this.resolveClaudeConfigDir(),
373
372
  sessionId: poisonSessionId,
374
373
  log: this.log
375
374
  });
@@ -450,8 +449,59 @@ var ClaudeSdkDriver = class extends AgentDriver {
450
449
  }
451
450
  }
452
451
  }
452
+ /**
453
+ * Resolve the Claude Code config directory — the parent of `projects/` — from
454
+ * the driver config, the process environment, or the `~/.claude` default.
455
+ */
456
+ resolveClaudeConfigDir() {
457
+ return this.config.env?.CLAUDE_CONFIG_DIR || process.env.CLAUDE_CONFIG_DIR || join(homedir(), ".claude");
458
+ }
459
+ /**
460
+ * Preventively repair the on-disk SDK transcript before a resume.
461
+ *
462
+ * The reactive {@link scrubPoisonedTranscript} pass in `prompt()` only fires
463
+ * *after* a turn has already failed with a `400 invalid_request_error`,
464
+ * costing a wasted round-trip and surfacing a scary (if non-fatal) error to
465
+ * the user. A transcript poisoned in a prior driver lifetime — most commonly
466
+ * an image block whose `media_type` does not match its bytes, produced by the
467
+ * Claude Code `Read` tool on a PDF with embedded JPEGs (anthropics/claude-code
468
+ * #55338) — would otherwise 400 on the very first resumed turn.
469
+ *
470
+ * Running the same magic-byte scrub *before* handing the transcript to the
471
+ * SDK means a known poison class never reaches the API, so recovery is
472
+ * invisible. This is regex-free (unlike the reactive gate) and idempotent: a
473
+ * clean transcript is left byte-for-byte untouched. The reactive path remains
474
+ * the safety net for poison introduced mid-turn within the current lifetime.
475
+ */
476
+ preventivelyScrubTranscript() {
477
+ const sessionId = this.config.resumeSessionId || this.sessionId;
478
+ if (!sessionId) {
479
+ return;
480
+ }
481
+ try {
482
+ const scrub = scrubPoisonedTranscript({
483
+ configDir: this.resolveClaudeConfigDir(),
484
+ sessionId,
485
+ log: this.log
486
+ });
487
+ if (scrub.changed) {
488
+ this.log.warn("preventively scrubbed poisoned Claude Code transcript before resume", {
489
+ sessionId,
490
+ corrected: scrub.corrected,
491
+ stubbed: scrub.stubbed,
492
+ cacheStripped: scrub.cacheStripped
493
+ });
494
+ }
495
+ } catch (err) {
496
+ this.log.warn("preventive transcript scrub failed; continuing", {
497
+ sessionId,
498
+ error: err instanceof Error ? err.message : String(err)
499
+ });
500
+ }
501
+ }
453
502
  async startQuery(message) {
454
503
  this.abortController = new AbortController();
504
+ this.preventivelyScrubTranscript();
455
505
  const apiKey = this.config.apiKeys?.anthropic || this.config.env?.ANTHROPIC_API_KEY || process.env.ANTHROPIC_API_KEY;
456
506
  this.usingOauthCredential = !apiKey;
457
507
  const claudePath = this.findClaudeBinary();