@aiwg/cli 2026.10.1 → 2026.10.4

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 (361) hide show
  1. package/README.md +2 -2
  2. package/agentic/code/providers/capability-matrix.yaml +270 -0
  3. package/agentic/code/providers/model-capabilities.v1.json +3183 -24
  4. package/bin/aiwg.mjs +135 -47
  5. package/dist/src/a2a/codecs.js +9 -0
  6. package/dist/src/agents/grounding/knowledge-base.js +54 -6
  7. package/dist/src/artifacts/browser-export.js +6 -0
  8. package/dist/src/artifacts/checksum-manifest.js +1 -0
  9. package/dist/src/artifacts/citation-parser.js +173 -92
  10. package/dist/src/artifacts/citation-table-schema.js +59 -0
  11. package/dist/src/artifacts/cli.js +57 -18
  12. package/dist/src/artifacts/corpus-tools/snapshot.js +1 -1
  13. package/dist/src/artifacts/corpus-tools/vision-extract.js +107 -15
  14. package/dist/src/artifacts/corpus-views/ref-parser.js +3 -1
  15. package/dist/src/artifacts/corpus-views/renderers.js +3 -3
  16. package/dist/src/artifacts/discovery-eval.js +6 -4
  17. package/dist/src/artifacts/fortemi-core-query-adapter.js +36 -3
  18. package/dist/src/artifacts/fortemi-core-sync.js +166 -40
  19. package/dist/src/artifacts/framework-capabilities.js +171 -0
  20. package/dist/src/artifacts/framework-index-paths.js +73 -0
  21. package/dist/src/artifacts/framework-source-digest.js +75 -0
  22. package/dist/src/artifacts/index-builder.js +285 -131
  23. package/dist/src/artifacts/index-files.js +132 -18
  24. package/dist/src/artifacts/index-preparation.js +65 -0
  25. package/dist/src/artifacts/index-refresh.js +576 -0
  26. package/dist/src/artifacts/index-worker.mjs +9 -0
  27. package/dist/src/artifacts/prebuilt-build-lock.js +47 -4
  28. package/dist/src/artifacts/prebuilt-deployment.js +46 -0
  29. package/dist/src/artifacts/prebuilt-relations.js +80 -0
  30. package/dist/src/artifacts/query-engine.js +410 -88
  31. package/dist/src/artifacts/relations-builder.js +168 -0
  32. package/dist/src/artifacts/relations.js +148 -0
  33. package/dist/src/artifacts/repair.js +9 -4
  34. package/dist/src/artifacts/stats.js +5 -2
  35. package/dist/src/artifacts/types.js +30 -10
  36. package/dist/src/artifacts/watcher.js +1 -1
  37. package/dist/src/auth/credential-store.js +2 -1
  38. package/dist/src/catalog/cli.d.mts +5 -0
  39. package/dist/src/channel/manager.d.mts +20 -0
  40. package/dist/src/channel/manager.mjs +78 -12
  41. package/dist/src/cli/child-process-result.js +40 -0
  42. package/dist/src/cli/command-log.js +2 -3
  43. package/dist/src/cli/env.js +38 -16
  44. package/dist/src/cli/flag-parsing.js +236 -0
  45. package/dist/src/cli/handlers/artifacts.js +3 -0
  46. package/dist/src/cli/handlers/auth.js +3 -0
  47. package/dist/src/cli/handlers/decision.js +218 -5
  48. package/dist/src/cli/handlers/diagnose.js +13 -5
  49. package/dist/src/cli/handlers/effect.js +4 -2
  50. package/dist/src/cli/handlers/evidence.js +3 -0
  51. package/dist/src/cli/handlers/feedback.js +14 -5
  52. package/dist/src/cli/handlers/help.js +1 -0
  53. package/dist/src/cli/handlers/index.js +3 -1
  54. package/dist/src/cli/handlers/init.js +248 -30
  55. package/dist/src/cli/handlers/lint.js +5 -0
  56. package/dist/src/cli/handlers/mc.js +23 -0
  57. package/dist/src/cli/handlers/models.js +169 -10
  58. package/dist/src/cli/handlers/ralph-launcher.js +2 -0
  59. package/dist/src/cli/handlers/ralph.js +3 -0
  60. package/dist/src/cli/handlers/refresh.js +28 -0
  61. package/dist/src/cli/handlers/regenerate.js +14 -0
  62. package/dist/src/cli/handlers/resource-versions.js +3 -0
  63. package/dist/src/cli/handlers/rules.js +195 -0
  64. package/dist/src/cli/handlers/run.js +4 -0
  65. package/dist/src/cli/handlers/runtime-info.js +25 -11
  66. package/dist/src/cli/handlers/script-runner.js +19 -8
  67. package/dist/src/cli/handlers/session.js +406 -62
  68. package/dist/src/cli/handlers/sessions.js +243 -76
  69. package/dist/src/cli/handlers/setup-manifest.js +474 -79
  70. package/dist/src/cli/handlers/setup.js +180 -39
  71. package/dist/src/cli/handlers/steward.js +11 -0
  72. package/dist/src/cli/handlers/subcommands.js +60 -3
  73. package/dist/src/cli/handlers/team.js +18 -8
  74. package/dist/src/cli/handlers/uhp.js +3 -0
  75. package/dist/src/cli/handlers/use.js +307 -55
  76. package/dist/src/cli/handlers/utilities.js +125 -26
  77. package/dist/src/cli/handlers/version.js +8 -0
  78. package/dist/src/cli/prompt-utils.js +72 -0
  79. package/dist/src/cli/provider-resolution.js +11 -0
  80. package/dist/src/cli/router.js +15 -1
  81. package/dist/src/cli/services/deployment-verification.js +19 -9
  82. package/dist/src/cli/services/provider-prepare-coordinator.js +24 -0
  83. package/dist/src/cli/skill-usage.js +2 -3
  84. package/dist/src/config/aiwg-config.js +349 -35
  85. package/dist/src/config/cli.js +256 -23
  86. package/dist/src/config/decision-config.js +106 -0
  87. package/dist/src/config/dispatch-thresholds-runtime.d.mts +8 -0
  88. package/dist/src/config/dispatch-thresholds-runtime.mjs +38 -0
  89. package/dist/src/config/gitignore.js +50 -0
  90. package/dist/src/config/index-graph-overrides.js +36 -0
  91. package/dist/src/config/project-artifacts-health.d.mts +37 -0
  92. package/dist/src/config/project-artifacts-health.mjs +14 -3
  93. package/dist/src/config/project-artifacts-runtime.d.mts +16 -0
  94. package/dist/src/config/user-config-dir.d.mts +9 -0
  95. package/dist/src/config/user-config.js +38 -11
  96. package/dist/src/config/user-registry.js +23 -15
  97. package/dist/src/config/user-state.js +7 -0
  98. package/dist/src/decision/adapters/jev.js +75 -27
  99. package/dist/src/decision/ask.js +203 -43
  100. package/dist/src/decision/context-live-qualification.js +2 -2
  101. package/dist/src/decision/driver.js +14 -7
  102. package/dist/src/decision/ensemble/aggregate.js +23 -10
  103. package/dist/src/decision/ensemble-study/multifact-study.js +6 -2
  104. package/dist/src/decision/entry.js +25 -6
  105. package/dist/src/decision/graph-live-qualification.js +1 -1
  106. package/dist/src/decision/graph-run.js +9 -0
  107. package/dist/src/decision/heldout/collector.js +15 -14
  108. package/dist/src/decision/heldout/contract.js +30 -7
  109. package/dist/src/decision/index.js +1 -0
  110. package/dist/src/decision/interop.js +60 -8
  111. package/dist/src/decision/jev-credentials.js +15 -1
  112. package/dist/src/decision/ledger.js +942 -0
  113. package/dist/src/decision/offload-activation.js +137 -0
  114. package/dist/src/decision/offload.js +550 -0
  115. package/dist/src/decision/qualification/load.js +4 -6
  116. package/dist/src/decision/savings.js +28 -0
  117. package/dist/src/decision/validate.js +6 -3
  118. package/dist/src/effects/dispatch-verifier.js +252 -0
  119. package/dist/src/effects/index.js +1 -0
  120. package/dist/src/effects/types.js +5 -1
  121. package/dist/src/effects/verifiers/git.js +2 -1
  122. package/dist/src/effects/verifiers/tracker.js +26 -14
  123. package/dist/src/extensions/commands/definitions.js +19 -0
  124. package/dist/src/extensions/project-local-remove.js +36 -1
  125. package/dist/src/features/installer.js +2 -2
  126. package/dist/src/flow/graph-metadata.js +5 -0
  127. package/dist/src/gates/providers/loader.js +64 -18
  128. package/dist/src/installation/manager-command.d.mts +18 -0
  129. package/dist/src/installation/manager-command.mjs +15 -3
  130. package/dist/src/installation/manager.d.mts +49 -0
  131. package/dist/src/installation/manager.mjs +95 -5
  132. package/dist/src/issues/cli.js +4 -4
  133. package/dist/src/issues/local.js +24 -5
  134. package/dist/src/jobs/runner.js +1 -1
  135. package/dist/src/lint/cli.js +27 -1
  136. package/dist/src/lint/loader.js +2 -1
  137. package/dist/src/lint/reporters.js +25 -1
  138. package/dist/src/lint/rule-activation.js +43 -0
  139. package/dist/src/lint/runner.js +137 -62
  140. package/dist/src/mcp/adapters/codex-runtime.js +366 -56
  141. package/dist/src/mcp/claude-install.d.mts +4 -0
  142. package/dist/src/mcp/claude-install.mjs +41 -0
  143. package/dist/src/mcp/cli.d.mts +1 -0
  144. package/dist/src/mcp/cli.mjs +620 -85
  145. package/dist/src/mcp/config-file.d.mts +28 -0
  146. package/dist/src/mcp/config-file.mjs +279 -0
  147. package/dist/src/mcp/config-layers.d.mts +36 -0
  148. package/dist/src/mcp/config-layers.mjs +348 -0
  149. package/dist/src/mcp/credentials.d.mts +51 -0
  150. package/dist/src/mcp/credentials.mjs +484 -0
  151. package/dist/src/mcp/grok-build-config.d.mts +6 -0
  152. package/dist/src/mcp/grok-build-config.mjs +17 -27
  153. package/dist/src/mcp/helpers.mjs +109 -4
  154. package/dist/src/mcp/muse-native-config.d.mts +13 -0
  155. package/dist/src/mcp/muse-native-config.mjs +1 -0
  156. package/dist/src/mcp/omp-config.d.mts +4 -0
  157. package/dist/src/mcp/omp-config.mjs +50 -29
  158. package/dist/src/mcp/profiles.js +97 -23
  159. package/dist/src/mcp/profiles.mjs +99 -27
  160. package/dist/src/mcp/registry.js +248 -131
  161. package/dist/src/mcp/registry.mjs +169 -100
  162. package/dist/src/mcp/server-config.d.mts +3 -0
  163. package/dist/src/mcp/server-config.mjs +89 -0
  164. package/dist/src/mcp/server.mjs +127 -82
  165. package/dist/src/mcp/test-simple.mjs +2 -1
  166. package/dist/src/mcp/toml-editor.d.mts +4 -0
  167. package/dist/src/mcp/toml-string.d.mts +1 -0
  168. package/dist/src/mcp/toml-string.mjs +9 -0
  169. package/dist/src/mcp/toml-strip-mcp.d.mts +1 -0
  170. package/dist/src/mcp/toml-strip-mcp.mjs +135 -0
  171. package/dist/src/mcp/tool-filters.d.mts +46 -0
  172. package/dist/src/mcp/tool-filters.mjs +357 -0
  173. package/dist/src/mcp/tools/agentic-sandbox.mjs +3 -1
  174. package/dist/src/mcp/tools/decision.mjs +22 -3
  175. package/dist/src/mcp/tools/discovery.mjs +62 -55
  176. package/dist/src/mcp/tools/orchestration.mjs +50 -2
  177. package/dist/src/mcp/tools/subsystems.mjs +39 -8
  178. package/dist/src/mcp/tools/worker-invoke.mjs +2856 -0
  179. package/dist/src/mcp/tools/worker-shell-control.mjs +289 -0
  180. package/dist/src/mcp/tools/worker-stdin-runtime.mjs +79 -0
  181. package/dist/src/memory/project-registry.js +2 -2
  182. package/dist/src/mission-protocol/codecs.js +647 -1
  183. package/dist/src/mission-protocol/types.js +110 -0
  184. package/dist/src/mission-protocol/worker-status.js +2 -0
  185. package/dist/src/models/config-loader.js +76 -14
  186. package/dist/src/models/grok-build-models.js +93 -41
  187. package/dist/src/models/model-capabilities.v1.json +3183 -24
  188. package/dist/src/models/model-discovery.js +931 -67
  189. package/dist/src/models/provider-policy.js +719 -11
  190. package/dist/src/models/qualification-digest.d.mts +2 -0
  191. package/dist/src/models/qualification-digest.mjs +17 -0
  192. package/dist/src/models/resolver.js +261 -0
  193. package/dist/src/models/worker-direct-readiness.js +550 -0
  194. package/dist/src/models/worker-dispatch-offer.js +169 -0
  195. package/dist/src/models/worker-health-readiness.js +144 -0
  196. package/dist/src/models/worker-installation.d.mts +39 -0
  197. package/dist/src/models/worker-installation.mjs +986 -0
  198. package/dist/src/models/wrapper-route.js +18 -0
  199. package/dist/src/ops/registry.js +9 -14
  200. package/dist/src/plugins/standalone-packager.js +4 -3
  201. package/dist/src/process/bounded-child-process.d.mts +84 -0
  202. package/dist/src/process/bounded-child-process.mjs +430 -0
  203. package/dist/src/process/cli-command.d.mts +16 -0
  204. package/dist/src/process/cli-command.mjs +75 -0
  205. package/dist/src/process/signal-child.d.mts +6 -0
  206. package/dist/src/process/signal-child.mjs +7 -0
  207. package/dist/src/providers/capability-matrix.js +8 -0
  208. package/dist/src/providers/capability-matrix.yaml +270 -0
  209. package/dist/src/providers/deployed-skill-roots.js +20 -0
  210. package/dist/src/providers/grok-build-acp.js +3 -2
  211. package/dist/src/providers/grok-build-headless.js +53 -23
  212. package/dist/src/providers/grok-build-inspect.js +1 -0
  213. package/dist/src/providers/omp-agent.d.mts +8 -0
  214. package/dist/src/providers/omp-diagnostics.d.mts +1 -0
  215. package/dist/src/providers/omp-paths.d.mts +13 -0
  216. package/dist/src/providers/provider-definitions.js +9 -1
  217. package/dist/src/providers/provider-definitions.mjs +9 -2
  218. package/dist/src/providers/skill-ownership.d.mts +9 -0
  219. package/dist/src/providers/skill-ownership.mjs +88 -0
  220. package/dist/src/rules/activation.d.mts +21 -0
  221. package/dist/src/rules/activation.mjs +62 -0
  222. package/dist/src/rules/inline-budget.d.mts +26 -0
  223. package/dist/src/rules/inline-budget.mjs +66 -0
  224. package/dist/src/rules/inventory.js +129 -0
  225. package/dist/src/rules/pin-state.js +73 -0
  226. package/dist/src/rules/pins.d.mts +14 -0
  227. package/dist/src/rules/pins.mjs +112 -0
  228. package/dist/src/rules/rule-frontmatter.schema.json +197 -0
  229. package/dist/src/serve/executor-registry.js +16 -24
  230. package/dist/src/serve/fleet-mission-conductor.js +9 -0
  231. package/dist/src/serve/mission-conductor.js +47 -12
  232. package/dist/src/serve/shared-host-scheduler.js +2 -0
  233. package/dist/src/serve/worker-invocation.js +558 -0
  234. package/dist/src/serve/worker-stdin-frame.d.mts +10 -0
  235. package/dist/src/serve/worker-stdin-frame.mjs +107 -0
  236. package/dist/src/sessions/adapter-registry.js +49 -0
  237. package/dist/src/sessions/adapters/claude.js +39 -54
  238. package/dist/src/sessions/adapters/codex.js +82 -67
  239. package/dist/src/sessions/adapters/copilot.js +4 -4
  240. package/dist/src/sessions/adapters/cursor.js +40 -57
  241. package/dist/src/sessions/adapters/deepseek-harness.js +15 -12
  242. package/dist/src/sessions/adapters/factory.js +31 -27
  243. package/dist/src/sessions/adapters/generic.js +43 -9
  244. package/dist/src/sessions/adapters/grok-build.js +11 -11
  245. package/dist/src/sessions/adapters/grokbot-locator.js +111 -0
  246. package/dist/src/sessions/adapters/grokbot.js +434 -24
  247. package/dist/src/sessions/adapters/hermes.js +27 -29
  248. package/dist/src/sessions/adapters/muse-workspace-scan.js +128 -0
  249. package/dist/src/sessions/adapters/muse.js +200 -104
  250. package/dist/src/sessions/adapters/omp.js +28 -14
  251. package/dist/src/sessions/adapters/openclaw.js +89 -79
  252. package/dist/src/sessions/adapters/opencode.js +27 -24
  253. package/dist/src/sessions/adapters/openhuman.js +18 -60
  254. package/dist/src/sessions/adapters/pi.js +30 -14
  255. package/dist/src/sessions/adapters/warp.js +3 -3
  256. package/dist/src/sessions/adapters/windsurf.js +19 -48
  257. package/dist/src/sessions/batch-contracts.js +25 -5
  258. package/dist/src/sessions/batch-import.js +72 -51
  259. package/dist/src/sessions/candidates.js +47 -11
  260. package/dist/src/sessions/contracts.js +75 -2
  261. package/dist/src/sessions/coverage-preflight.js +134 -0
  262. package/dist/src/sessions/discovery.js +3 -0
  263. package/dist/src/sessions/export-plan.js +4 -3
  264. package/dist/src/sessions/grok-build-cli.js +67 -5
  265. package/dist/src/sessions/import-exclusions.js +72 -0
  266. package/dist/src/sessions/import-lease.js +34 -18
  267. package/dist/src/sessions/import-limits.js +37 -0
  268. package/dist/src/sessions/importer.js +84 -46
  269. package/dist/src/sessions/index.js +2 -0
  270. package/dist/src/sessions/lifecycle.js +45 -0
  271. package/dist/src/sessions/policy.js +133 -25
  272. package/dist/src/sessions/readers.js +106 -53
  273. package/dist/src/sessions/refresh.js +106 -0
  274. package/dist/src/sessions/repository.js +199 -63
  275. package/dist/src/sessions/workspace-discovery.js +315 -88
  276. package/dist/src/sessions/workspace-matching.js +107 -0
  277. package/dist/src/skills/adapters/clawhub.js +10 -8
  278. package/dist/src/skills/adapters/openclaw.js +10 -7
  279. package/dist/src/skills/importer.js +1 -0
  280. package/dist/src/smiths/context-pipeline/aiwg-md.js +11 -0
  281. package/dist/src/smiths/context-pipeline/claude-hook.js +3 -26
  282. package/dist/src/smiths/context-pipeline/finalization.js +6 -5
  283. package/dist/src/smiths/context-pipeline/generator.js +21 -4
  284. package/dist/src/smiths/context-pipeline/parallelism-section.js +195 -14
  285. package/dist/src/smiths/context-pipeline/workspace-context.js +116 -9
  286. package/dist/src/smiths/hook-bridge/codex-translator.js +6 -5
  287. package/dist/src/smiths/mcpsmith/example.js +1 -1
  288. package/dist/src/smiths/mcpsmith/generator.js +1 -1
  289. package/dist/src/smiths/toolsmith/runtime-discovery.d.mts +10 -0
  290. package/dist/src/smiths/toolsmith/runtime-discovery.mjs +85 -31
  291. package/dist/src/storage/backends/fs.js +18 -76
  292. package/dist/src/storage/backends/logseq.js +68 -7
  293. package/dist/src/storage/backends/obsidian.js +1 -0
  294. package/dist/src/storage/fortemi-qualification-receipt.js +2 -2
  295. package/dist/src/testing/generators/test-code-generator.js +57 -30
  296. package/dist/src/tracker/forge-http.js +2 -1
  297. package/dist/src/uhp/client.js +11 -1
  298. package/dist/src/uhp/mission.js +5 -0
  299. package/dist/src/update/checker.d.mts +2 -0
  300. package/dist/src/update/checker.mjs +5 -5
  301. package/dist/src/update/notifier.mjs +54 -2
  302. package/dist/src/update/service.d.mts +22 -0
  303. package/dist/src/utils/contained-filesystem.d.mts +37 -0
  304. package/dist/src/utils/contained-filesystem.mjs +683 -0
  305. package/dist/src/utils/temporary-directory.js +36 -0
  306. package/dist/src/writing/example-generator.js +1 -1
  307. package/dist/src/writing/fidelity.js +18 -1
  308. package/package.json +32 -2
  309. package/schemas/mission-v1.schema.json +2429 -0
  310. package/schemas/models/model-catalog.v1.schema.json +301 -0
  311. package/schemas/models/model-config-compatibility.v1.schema.json +281 -0
  312. package/schemas/models/model-policy.v1.schema.json +14 -0
  313. package/schemas/models/provider-model-capabilities.v1.schema.json +1072 -0
  314. package/tools/_resolve-impl.mjs +39 -2
  315. package/tools/agents/deploy-agents.mjs +64 -23
  316. package/tools/agents/providers/base.mjs +153 -166
  317. package/tools/agents/providers/claude.mjs +8 -24
  318. package/tools/agents/providers/codex.mjs +18 -11
  319. package/tools/agents/providers/cursor.mjs +19 -18
  320. package/tools/agents/providers/grok-build.mjs +3 -1
  321. package/tools/agents/providers/grokbot.mjs +11 -12
  322. package/tools/agents/providers/hermes.mjs +62 -49
  323. package/tools/agents/providers/omp.mjs +5 -2
  324. package/tools/agents/providers/openclaw-translator.mjs +19 -5
  325. package/tools/agents/providers/openclaw.mjs +9 -4
  326. package/tools/agents/providers/pi.mjs +5 -0
  327. package/tools/agents/providers/provider-prepare-channel.mjs +5 -0
  328. package/tools/agents/providers/provider-prepare-coordinator.mjs +247 -0
  329. package/tools/agents/providers/provider-prepare-worker.mjs +84 -0
  330. package/tools/agents/providers/rule-delivery.mjs +1270 -0
  331. package/tools/agents/providers/warp.mjs +20 -26
  332. package/tools/cli/decision-offload-report.mjs +40 -0
  333. package/tools/cli/workspace-status.mjs +862 -0
  334. package/tools/plugin/package-plugins.mjs +186 -8
  335. package/tools/plugin/plugin-links.mjs +114 -0
  336. package/tools/providers/antigravity-transport.mjs +3 -1
  337. package/tools/providers/deepseek-harness-transport.mjs +360 -0
  338. package/tools/providers/omp-transport.mjs +194 -0
  339. package/tools/ralph-external/lib/claude-adapter.mjs +389 -0
  340. package/tools/ralph-external/lib/codex-adapter.mjs +432 -0
  341. package/tools/ralph-external/lib/consecutive-failure-circuit-breaker.mjs +1748 -0
  342. package/tools/ralph-external/lib/deepseek-harness-adapter.mjs +397 -0
  343. package/tools/ralph-external/lib/factory-adapter.mjs +503 -0
  344. package/tools/ralph-external/lib/launcher-recovery-evidence.mjs +55 -0
  345. package/tools/ralph-external/lib/muse-adapter.mjs +364 -0
  346. package/tools/ralph-external/lib/omp-adapter.mjs +315 -0
  347. package/tools/ralph-external/lib/opencode-adapter.mjs +575 -0
  348. package/tools/ralph-external/lib/openhuman-adapter.mjs +75 -0
  349. package/tools/ralph-external/lib/pi-adapter.mjs +329 -0
  350. package/tools/ralph-external/lib/provider-adapter.mjs +748 -0
  351. package/tools/ralph-external/lib/recovery-probe.mjs +72 -0
  352. package/tools/ralph-external/lib/session-environment.mjs +28 -0
  353. package/tools/ralph-external/lib/systemd-client.mjs +49 -0
  354. package/tools/ralph-external/lib/worker-health.mjs +439 -0
  355. package/tools/ralph-external/lib/worker-isolation.mjs +717 -0
  356. package/tools/ralph-external/lib/worker-overflow.mjs +50 -0
  357. package/tools/ralph-external/process-monitor.mjs +1017 -0
  358. package/tools/ralph-external/session-launcher.mjs +5057 -0
  359. package/tools/scripts/resource-preflight.mjs +541 -0
  360. package/tools/skills/deploy-skills-codex.mjs +2 -1
  361. package/vscode-extension/schemas/aiwg.config.v1.json +2916 -0
@@ -1,8 +1,8 @@
1
1
  import { opendir } from 'node:fs/promises';
2
2
  import { basename, dirname, extname, resolve, } from 'node:path';
3
3
  import { z } from 'zod';
4
- import { SessionContractError, assertSupportedSchemaMajor, } from '../contracts.js';
5
- import { readBoundedJsonLines, readBoundedText, streamBoundedJsonLines, } from '../readers.js';
4
+ import { schemaRejectionDetail, schemaIssueDetail, SessionContractError, assertSupportedSchemaMajor, } from '../contracts.js';
5
+ import { readBoundedText, streamBoundedJsonLines, } from '../readers.js';
6
6
  export const CURSOR_ADAPTER_VERSION = '1.0.0';
7
7
  export const CURSOR_SOURCE_SCHEMA_VERSION = '1.0.0';
8
8
  const CliEventSchema = z.object({
@@ -82,7 +82,7 @@ export class CursorSessionAdapter {
82
82
  for (const root of [...scope.allowedRoots].sort()) {
83
83
  for await (const locator of discoverJsonl(resolve(root), this.discoveryLimits.maxDepth)) {
84
84
  if (++emitted > this.discoveryLimits.maxFiles) {
85
- throw new SessionContractError('RESOURCE_LIMIT_EXCEEDED', 'Cursor source discovery exceeded the authorized file limit');
85
+ throw new SessionContractError('RESOURCE_LIMIT_EXCEEDED', 'Cursor source discovery exceeded the authorized file limit', { limit: 'maxFiles', configured: this.discoveryLimits.maxFiles, observed: emitted });
86
86
  }
87
87
  yield {
88
88
  provider: 'cursor',
@@ -93,6 +93,16 @@ export class CursorSessionAdapter {
93
93
  }
94
94
  }
95
95
  async inspect(source) {
96
+ if (source.locatorClass === 'cursor-cli-stream-json'
97
+ || source.locatorClass === 'cursor-cloud-events-jsonl'
98
+ || source.locatorClass === 'cursor-agent-transcript-jsonl') {
99
+ const records = this.stream(source);
100
+ let result = await records.next();
101
+ while (!result.done)
102
+ result = await records.next();
103
+ if (result.value)
104
+ return result.value;
105
+ }
96
106
  const parsed = await this.readSource(source);
97
107
  return {
98
108
  sourceSchemaVersion: parsed.schemaVersion,
@@ -102,7 +112,8 @@ export class CursorSessionAdapter {
102
112
  }
103
113
  async *stream(source, cursor) {
104
114
  if (source.locatorClass === 'cursor-cli-stream-json'
105
- || source.locatorClass === 'cursor-cloud-events-jsonl') {
115
+ || source.locatorClass === 'cursor-cloud-events-jsonl'
116
+ || source.locatorClass === 'cursor-agent-transcript-jsonl') {
106
117
  const input = await streamBoundedJsonLines({
107
118
  selectedPath: source.locator,
108
119
  allowedRoots: source.authorizedScope.allowedRoots,
@@ -114,13 +125,14 @@ export class CursorSessionAdapter {
114
125
  let agentId;
115
126
  let runId;
116
127
  let sawRecord = false;
128
+ let complete = false;
117
129
  for await (const line of input) {
118
130
  sawRecord = true;
119
131
  const raw = asObject(line.value);
120
132
  const currentSchema = typeof raw.schemaVersion === 'string'
121
133
  ? raw.schemaVersion : CURSOR_SOURCE_SCHEMA_VERSION;
122
134
  if (schemaVersion && schemaVersion !== currentSchema) {
123
- throw new SessionContractError('SCHEMA_DRIFT', 'Cursor source declares mixed schema versions');
135
+ throw new SessionContractError('SCHEMA_DRIFT', 'Cursor source declares mixed schema versions', schemaIssueDetail('schemaVersion'));
124
136
  }
125
137
  schemaVersion = currentSchema;
126
138
  assertSupportedSchemaMajor(schemaVersion);
@@ -128,7 +140,7 @@ export class CursorSessionAdapter {
128
140
  if (source.locatorClass === 'cursor-cli-stream-json') {
129
141
  const parsed = CliEventSchema.safeParse(line.value);
130
142
  if (!parsed.success) {
131
- throw new SessionContractError('MALFORMED_SOURCE', 'Cursor CLI event is malformed');
143
+ throw new SessionContractError('MALFORMED_SOURCE', 'Cursor CLI event is malformed', schemaRejectionDetail(parsed.error));
132
144
  }
133
145
  const event = parsed.data;
134
146
  if (cliSessionId && cliSessionId !== event.session_id) {
@@ -137,10 +149,10 @@ export class CursorSessionAdapter {
137
149
  cliSessionId = event.session_id;
138
150
  record = normalizeCli([line]).records[0];
139
151
  }
140
- else {
152
+ else if (source.locatorClass === 'cursor-cloud-events-jsonl') {
141
153
  const parsed = CloudEventSchema.safeParse(line.value);
142
154
  if (!parsed.success) {
143
- throw new SessionContractError('MALFORMED_SOURCE', 'Cursor Cloud Agent event is malformed');
155
+ throw new SessionContractError('MALFORMED_SOURCE', 'Cursor Cloud Agent event is malformed', schemaRejectionDetail(parsed.error));
144
156
  }
145
157
  const event = parsed.data;
146
158
  const nextAgentId = event.agent?.id ?? agentId;
@@ -153,27 +165,38 @@ export class CursorSessionAdapter {
153
165
  }
154
166
  agentId = nextAgentId;
155
167
  runId = nextRunId;
156
- record = normalizeCloud([{
168
+ const normalized = normalizeCloud([{
157
169
  ...line,
158
170
  value: {
159
171
  ...event,
160
172
  agent: event.agent ?? (agentId ? { id: agentId } : undefined),
161
173
  run: event.run ?? (runId ? { id: runId } : undefined),
162
174
  },
163
- }]).records[0];
175
+ }]);
176
+ complete ||= normalized.complete;
177
+ record = normalized.records[0];
178
+ }
179
+ else {
180
+ record = normalizeAgentTranscript([line], source.locator).records[0];
164
181
  }
182
+ complete ||= record.extensions?.lifecycle === 'complete';
165
183
  if (outputIndex++ >= start)
166
184
  yield record;
167
185
  }
168
186
  if (!sawRecord && !input.incompleteTail) {
169
- throw new SessionContractError('MALFORMED_SOURCE', 'Cursor structured source is empty');
187
+ throw new SessionContractError('MALFORMED_SOURCE', 'Cursor structured source is empty', schemaIssueDetail('<root>'));
170
188
  }
171
- return;
189
+ return {
190
+ sourceSchemaVersion: schemaVersion ?? CURSOR_SOURCE_SCHEMA_VERSION,
191
+ consistency: complete && !input.incompleteTail ? 'complete' : 'provisional',
192
+ operationalState: 'available',
193
+ };
172
194
  }
173
195
  const parsed = await this.readSource(source);
174
196
  const start = parseCursor(cursor?.value);
175
197
  for (const record of parsed.records.slice(start))
176
198
  yield record;
199
+ return undefined;
177
200
  }
178
201
  async readSource(source) {
179
202
  const authorization = {
@@ -191,36 +214,6 @@ export class CursorSessionAdapter {
191
214
  records: normalizeMarkdown(input.value, source.locator),
192
215
  };
193
216
  }
194
- const input = await readBoundedJsonLines(authorization, { consistency: 'provisional', limits: this.limits });
195
- if (input.records.length === 0 && !input.incompleteTail) {
196
- throw new SessionContractError('MALFORMED_SOURCE', 'Cursor structured source is empty');
197
- }
198
- const schemaVersion = declaredVersion(input.records);
199
- assertSupportedSchemaMajor(schemaVersion);
200
- if (source.locatorClass === 'cursor-cli-stream-json') {
201
- const normalized = normalizeCli(input.records);
202
- return {
203
- schemaVersion,
204
- consistency: normalized.complete && !input.incompleteTail ? 'complete' : 'provisional',
205
- records: normalized.records,
206
- };
207
- }
208
- if (source.locatorClass === 'cursor-cloud-events-jsonl') {
209
- const normalized = normalizeCloud(input.records);
210
- return {
211
- schemaVersion,
212
- consistency: normalized.complete && !input.incompleteTail ? 'complete' : 'provisional',
213
- records: normalized.records,
214
- };
215
- }
216
- if (source.locatorClass === 'cursor-agent-transcript-jsonl') {
217
- const normalized = normalizeAgentTranscript(input.records, source.locator);
218
- return {
219
- schemaVersion,
220
- consistency: normalized.complete && !input.incompleteTail ? 'complete' : 'provisional',
221
- records: normalized.records,
222
- };
223
- }
224
217
  throw new SessionContractError('UNSUPPORTED_OPERATION', 'unsupported Cursor source class');
225
218
  }
226
219
  }
@@ -257,7 +250,7 @@ function normalizeCli(input) {
257
250
  for (const line of input) {
258
251
  const parsed = CliEventSchema.safeParse(line.value);
259
252
  if (!parsed.success) {
260
- throw new SessionContractError('MALFORMED_SOURCE', 'Cursor CLI event is malformed');
253
+ throw new SessionContractError('MALFORMED_SOURCE', 'Cursor CLI event is malformed', schemaRejectionDetail(parsed.error));
261
254
  }
262
255
  const event = parsed.data;
263
256
  if (sessionId && sessionId !== event.session_id) {
@@ -307,7 +300,7 @@ function normalizeCloud(input) {
307
300
  for (const line of input) {
308
301
  const parsed = CloudEventSchema.safeParse(line.value);
309
302
  if (!parsed.success) {
310
- throw new SessionContractError('MALFORMED_SOURCE', 'Cursor Cloud Agent event is malformed');
303
+ throw new SessionContractError('MALFORMED_SOURCE', 'Cursor Cloud Agent event is malformed', schemaRejectionDetail(parsed.error));
311
304
  }
312
305
  const event = parsed.data;
313
306
  const nextAgentId = event.agent?.id ?? agentId;
@@ -371,7 +364,7 @@ function normalizeAgentTranscript(input, locator) {
371
364
  for (const line of input) {
372
365
  const parsed = AgentTranscriptEventSchema.safeParse(line.value);
373
366
  if (!parsed.success) {
374
- throw new SessionContractError('MALFORMED_SOURCE', 'Cursor agent transcript event is malformed');
367
+ throw new SessionContractError('MALFORMED_SOURCE', 'Cursor agent transcript event is malformed', schemaRejectionDetail(parsed.error));
375
368
  }
376
369
  const event = parsed.data;
377
370
  const terminal = event.type === 'turn_ended' && event.status === 'success';
@@ -411,7 +404,7 @@ function normalizeMarkdown(value, locator) {
411
404
  const heading = /^#{1,3}\s+(User|Assistant|Cursor)\s*$/gim;
412
405
  const matches = [...value.matchAll(heading)];
413
406
  if (matches.length === 0) {
414
- throw new SessionContractError('MALFORMED_SOURCE', 'Cursor Markdown export has no role headings');
407
+ throw new SessionContractError('MALFORMED_SOURCE', 'Cursor Markdown export has no role headings', schemaIssueDetail('headings'));
415
408
  }
416
409
  const nativeSessionId = basename(locator, extname(locator));
417
410
  return matches.map((match, index) => {
@@ -462,16 +455,6 @@ function messageText(value) {
462
455
  return '';
463
456
  }).filter(Boolean).join('\n');
464
457
  }
465
- function declaredVersion(records) {
466
- const versions = new Set(records.map((line) => {
467
- const value = asObject(line.value);
468
- return typeof value.schemaVersion === 'string' ? value.schemaVersion : CURSOR_SOURCE_SCHEMA_VERSION;
469
- }));
470
- if (versions.size !== 1) {
471
- throw new SessionContractError('SCHEMA_DRIFT', 'Cursor source declares mixed schema versions');
472
- }
473
- return [...versions][0];
474
- }
475
458
  function declaredEventVersion(event) {
476
459
  return event.schemaVersion ?? CURSOR_SOURCE_SCHEMA_VERSION;
477
460
  }
@@ -511,7 +494,7 @@ function parseCursor(value) {
511
494
  if (!value)
512
495
  return 0;
513
496
  if (!/^\d+$/.test(value)) {
514
- throw new SessionContractError('SCHEMA_DRIFT', 'invalid Cursor record cursor');
497
+ throw new SessionContractError('SCHEMA_DRIFT', 'invalid Cursor record cursor', schemaIssueDetail('cursor'));
515
498
  }
516
499
  return Number(value);
517
500
  }
@@ -1,8 +1,8 @@
1
1
  import { opendir } from 'node:fs/promises';
2
2
  import { resolve } from 'node:path';
3
3
  import { z } from 'zod';
4
- import { SessionContractError, } from '../contracts.js';
5
- import { readBoundedJsonLines, streamBoundedJsonLines } from '../readers.js';
4
+ import { schemaRejectionDetail, schemaIssueDetail, SessionContractError, } from '../contracts.js';
5
+ import { streamBoundedJsonLines } from '../readers.js';
6
6
  export const DEEPSEEK_HARNESS_ADAPTER_VERSION = '1.0.0';
7
7
  export const DEEPSEEK_HARNESS_SOURCE_SCHEMA_VERSION = '2.0.0';
8
8
  const Header = z.object({
@@ -39,7 +39,7 @@ export class DeepSeekHarnessSessionAdapter {
39
39
  for (const root of [...scope.allowedRoots].sort()) {
40
40
  for await (const locator of jsonlFiles(resolve(root))) {
41
41
  if (++count > this.maxFiles)
42
- throw new SessionContractError('RESOURCE_LIMIT_EXCEEDED', 'DeepSeek Harness discovery file limit exceeded');
42
+ throw new SessionContractError('RESOURCE_LIMIT_EXCEEDED', 'DeepSeek Harness discovery file limit exceeded', { limit: 'maxFiles', configured: this.maxFiles, observed: count });
43
43
  yield { provider: this.provider, locator, locatorClass: 'deepseek-harness-session-v2-jsonl' };
44
44
  }
45
45
  }
@@ -47,12 +47,15 @@ export class DeepSeekHarnessSessionAdapter {
47
47
  async inspect(source) {
48
48
  let input;
49
49
  try {
50
- input = await readBoundedJsonLines({ selectedPath: source.locator, allowedRoots: source.authorizedScope.allowedRoots }, { consistency: 'provisional', limits: this.limits });
50
+ input = await streamBoundedJsonLines({ selectedPath: source.locator, allowedRoots: source.authorizedScope.allowedRoots }, { consistency: 'provisional', limits: this.limits });
51
51
  }
52
52
  catch (error) {
53
53
  throw normalizeAuthorizationError(error);
54
54
  }
55
- const header = parseHeader(input.records[0]?.value);
55
+ let header;
56
+ for await (const line of input)
57
+ header ??= parseHeader(line.value);
58
+ header ??= parseHeader(undefined);
56
59
  if (input.incompleteTail)
57
60
  throw new SessionContractError('TRUNCATED_SOURCE', 'DeepSeek Harness session has a truncated JSONL tail');
58
61
  return { sourceSchemaVersion: `${header.version}.0.0`, consistency: 'complete', operationalState: 'available' };
@@ -67,24 +70,24 @@ export class DeepSeekHarnessSessionAdapter {
67
70
  }
68
71
  const start = cursor?.value.replace(/^byte:/, '') ?? '0';
69
72
  if (!/^\d+$/.test(start))
70
- throw new SessionContractError('SCHEMA_DRIFT', 'invalid DeepSeek Harness cursor');
73
+ throw new SessionContractError('SCHEMA_DRIFT', 'invalid DeepSeek Harness cursor', schemaIssueDetail('cursor'));
71
74
  let header;
72
75
  let expectedSeq = 0;
73
76
  let end = 0;
74
77
  for await (const line of input) {
75
78
  end = line.byteOffset + line.byteLength;
76
79
  if (Number(start) > line.byteOffset && Number(start) < end)
77
- throw new SessionContractError('SCHEMA_DRIFT', 'DeepSeek Harness cursor is not a record boundary');
80
+ throw new SessionContractError('SCHEMA_DRIFT', 'DeepSeek Harness cursor is not a record boundary', schemaIssueDetail('cursor'));
78
81
  if (!header) {
79
82
  header = parseHeader(line.value);
80
83
  continue;
81
84
  }
82
85
  const parsed = Event.safeParse(line.value);
83
86
  if (!parsed.success)
84
- throw new SessionContractError('MALFORMED_SOURCE', 'DeepSeek Harness session event is malformed');
87
+ throw new SessionContractError('MALFORMED_SOURCE', 'DeepSeek Harness session event is malformed', schemaRejectionDetail(parsed.error));
85
88
  const event = parsed.data;
86
89
  if (event.seq !== expectedSeq)
87
- throw new SessionContractError(event.seq < expectedSeq ? 'DUPLICATE_NATIVE_ID' : 'SCHEMA_DRIFT', `DeepSeek Harness sequence expected ${expectedSeq}, received ${event.seq}`);
90
+ throw new SessionContractError(event.seq < expectedSeq ? 'DUPLICATE_NATIVE_ID' : 'SCHEMA_DRIFT', `DeepSeek Harness sequence expected ${expectedSeq}, received ${event.seq}`, schemaIssueDetail('seq'));
88
91
  expectedSeq++;
89
92
  if (end <= Number(start))
90
93
  continue;
@@ -121,9 +124,9 @@ export class DeepSeekHarnessSessionAdapter {
121
124
  };
122
125
  }
123
126
  if (!header)
124
- throw new SessionContractError('MALFORMED_SOURCE', 'DeepSeek Harness session header is missing');
127
+ throw new SessionContractError('MALFORMED_SOURCE', 'DeepSeek Harness session header is missing', schemaIssueDetail('header'));
125
128
  if (Number(start) > end)
126
- throw new SessionContractError('SCHEMA_DRIFT', 'DeepSeek Harness cursor exceeds source size');
129
+ throw new SessionContractError('SCHEMA_DRIFT', 'DeepSeek Harness cursor exceeds source size', schemaIssueDetail('cursor'));
127
130
  if (input.incompleteTail)
128
131
  throw new SessionContractError('TRUNCATED_SOURCE', 'DeepSeek Harness session has a truncated JSONL tail');
129
132
  }
@@ -131,7 +134,7 @@ export class DeepSeekHarnessSessionAdapter {
131
134
  function parseHeader(value) {
132
135
  const parsed = Header.safeParse(value);
133
136
  if (!parsed.success)
134
- throw new SessionContractError('MALFORMED_SOURCE', 'DeepSeek Harness session header is malformed');
137
+ throw new SessionContractError('MALFORMED_SOURCE', 'DeepSeek Harness session header is malformed', schemaRejectionDetail(parsed.error));
135
138
  if (parsed.data.version !== 2)
136
139
  throw new SessionContractError('UNKNOWN_SCHEMA_MAJOR', `unsupported DeepSeek Harness session version: ${parsed.data.version}`);
137
140
  return parsed.data;
@@ -1,8 +1,8 @@
1
1
  import { opendir } from 'node:fs/promises';
2
2
  import { basename, extname, resolve } from 'node:path';
3
3
  import { z } from 'zod';
4
- import { SessionContractError, assertSupportedSchemaMajor, } from '../contracts.js';
5
- import { readBoundedJsonLines, streamBoundedJsonLines, } from '../readers.js';
4
+ import { schemaRejectionDetail, schemaIssueDetail, SessionContractError, assertSupportedSchemaMajor, } from '../contracts.js';
5
+ import { streamBoundedJsonLines, } from '../readers.js';
6
6
  export const FACTORY_ADAPTER_VERSION = '1.0.0';
7
7
  export const FACTORY_SOURCE_SCHEMA_VERSION = '1.0.0';
8
8
  const FactoryRecordSchema = z.object({
@@ -51,13 +51,21 @@ export class FactorySessionAdapter {
51
51
  for (const root of [...scope.allowedRoots].sort()) {
52
52
  for await (const locator of discoverJsonl(resolve(root), this.discoveryLimits.maxDepth)) {
53
53
  if (++emitted > this.discoveryLimits.maxFiles) {
54
- throw new SessionContractError('RESOURCE_LIMIT_EXCEEDED', 'Factory source discovery exceeded the authorized file limit');
54
+ throw new SessionContractError('RESOURCE_LIMIT_EXCEEDED', 'Factory source discovery exceeded the authorized file limit', { limit: 'maxFiles', configured: this.discoveryLimits.maxFiles, observed: emitted });
55
55
  }
56
56
  yield { provider: 'factory', locator, locatorClass: 'factory-droid-jsonl' };
57
57
  }
58
58
  }
59
59
  }
60
60
  async inspect(source) {
61
+ if (source.locatorClass === 'factory-droid-jsonl') {
62
+ const records = this.stream(source);
63
+ let result = await records.next();
64
+ while (!result.done)
65
+ result = await records.next();
66
+ if (result.value)
67
+ return result.value;
68
+ }
61
69
  const parsed = await this.readSource(source);
62
70
  return {
63
71
  sourceSchemaVersion: parsed.schemaVersion,
@@ -76,6 +84,7 @@ export class FactorySessionAdapter {
76
84
  let establishedId;
77
85
  let schemaVersion = null;
78
86
  let sawRecord = false;
87
+ let complete = false;
79
88
  for await (const line of input) {
80
89
  sawRecord = true;
81
90
  const parsed = FactoryRecordSchema.safeParse(line.value);
@@ -85,7 +94,7 @@ export class FactorySessionAdapter {
85
94
  const value = parsed.data;
86
95
  const currentSchema = value.schemaVersion ?? FACTORY_SOURCE_SCHEMA_VERSION;
87
96
  if (schemaVersion && schemaVersion !== currentSchema) {
88
- throw new SessionContractError('SCHEMA_DRIFT', 'mixed Factory source schemas');
97
+ throw new SessionContractError('SCHEMA_DRIFT', 'mixed Factory source schemas', schemaIssueDetail('schemaVersion'));
89
98
  }
90
99
  schemaVersion = currentSchema;
91
100
  assertSupportedSchemaMajor(schemaVersion);
@@ -95,44 +104,39 @@ export class FactorySessionAdapter {
95
104
  throw new SessionContractError('DUPLICATE_NATIVE_ID', 'Factory source changes session identity');
96
105
  }
97
106
  establishedId = currentId;
98
- for (const record of normalize([line], source, establishedId).records) {
107
+ const normalized = normalize([line], source, establishedId);
108
+ complete ||= normalized.complete;
109
+ for (const record of normalized.records) {
99
110
  if (outputIndex++ >= start)
100
111
  yield record;
101
112
  }
102
113
  }
103
114
  if (!sawRecord && !input.incompleteTail) {
104
- throw new SessionContractError('MALFORMED_SOURCE', 'Factory session source is empty');
115
+ throw new SessionContractError('MALFORMED_SOURCE', 'Factory session source is empty', schemaIssueDetail('<root>'));
105
116
  }
106
- return;
117
+ return {
118
+ sourceSchemaVersion: schemaVersion ?? FACTORY_SOURCE_SCHEMA_VERSION,
119
+ consistency: complete && !input.incompleteTail ? 'complete' : 'provisional',
120
+ operationalState: 'available',
121
+ };
107
122
  }
108
123
  const parsed = await this.readSource(source);
109
124
  const start = parseCursor(cursor?.value);
110
125
  for (const record of parsed.records.slice(start))
111
126
  yield record;
127
+ return undefined;
112
128
  }
113
129
  async readSource(source) {
114
- let input;
115
- let incompleteTail = false;
116
- if (source.locatorClass === 'factory-droid-jsonl') {
117
- const result = await readBoundedJsonLines({
118
- selectedPath: source.locator,
119
- allowedRoots: source.authorizedScope.allowedRoots,
120
- }, { consistency: 'provisional', limits: this.limits });
121
- input = result.records;
122
- incompleteTail = result.incompleteTail;
123
- }
124
- else {
125
- input = await this.remoteRecords(source);
126
- }
127
- if (input.length === 0 && !incompleteTail) {
128
- throw new SessionContractError('MALFORMED_SOURCE', 'Factory session source is empty');
130
+ const input = await this.remoteRecords(source);
131
+ if (input.length === 0) {
132
+ throw new SessionContractError('MALFORMED_SOURCE', 'Factory session source is empty', schemaIssueDetail('<root>'));
129
133
  }
130
134
  const schemaVersion = declaredVersion(input);
131
135
  assertSupportedSchemaMajor(schemaVersion);
132
136
  const normalized = normalize(input, source);
133
137
  return {
134
138
  schemaVersion,
135
- consistency: normalized.complete && !incompleteTail ? 'complete' : 'provisional',
139
+ consistency: normalized.complete ? 'complete' : 'provisional',
136
140
  records: normalized.records,
137
141
  };
138
142
  }
@@ -155,7 +159,7 @@ export class FactorySessionAdapter {
155
159
  }
156
160
  const values = await transport.snapshot(source);
157
161
  if (values.length > (this.limits?.maxRecords ?? 1_000_000)) {
158
- throw new SessionContractError('RESOURCE_LIMIT_EXCEEDED', 'Factory remote record limit exceeded');
162
+ throw new SessionContractError('RESOURCE_LIMIT_EXCEEDED', 'Factory remote record limit exceeded', { limit: 'maxRecords', configured: this.limits?.maxRecords ?? 1_000_000, observed: values.length });
159
163
  }
160
164
  return values.map((value, sequence) => ({
161
165
  value, sequence, byteOffset: sequence, byteLength: Buffer.byteLength(JSON.stringify(value)),
@@ -330,7 +334,7 @@ function factoryMalformedRecord(source, record, error) {
330
334
  ? issue.path.map(String).join('.')
331
335
  : 'record';
332
336
  return new SessionContractError('MALFORMED_SOURCE', `Factory source ${basename(source.locator)} record ${record.sequence + 1} `
333
- + `type ${type} failed requirement ${requirement} (${issue?.code ?? 'invalid_type'})`);
337
+ + `type ${type} failed requirement ${requirement} (${issue?.code ?? 'invalid_type'})`, schemaRejectionDetail(error));
334
338
  }
335
339
  function declaredVersion(records) {
336
340
  const versions = new Set(records.flatMap((record) => {
@@ -338,7 +342,7 @@ function declaredVersion(records) {
338
342
  return typeof value.schemaVersion === 'string' ? [value.schemaVersion] : [];
339
343
  }));
340
344
  if (versions.size > 1)
341
- throw new SessionContractError('SCHEMA_DRIFT', 'mixed Factory schema versions');
345
+ throw new SessionContractError('SCHEMA_DRIFT', 'mixed Factory schema versions', schemaIssueDetail('schemaVersion'));
342
346
  return [...versions][0] ?? FACTORY_SOURCE_SCHEMA_VERSION;
343
347
  }
344
348
  function timestamp(value) {
@@ -375,7 +379,7 @@ function parseCursor(value) {
375
379
  if (!value)
376
380
  return 0;
377
381
  if (!/^\d+$/.test(value))
378
- throw new SessionContractError('SCHEMA_DRIFT', 'invalid Factory cursor');
382
+ throw new SessionContractError('SCHEMA_DRIFT', 'invalid Factory cursor', schemaIssueDetail('cursor'));
379
383
  return Number(value);
380
384
  }
381
385
  const RECORD_KEYS = new Set([
@@ -1,5 +1,5 @@
1
1
  import { z } from 'zod';
2
- import { SessionContractError, assertSupportedSchemaMajor, } from '../contracts.js';
2
+ import { schemaRejectionDetail, schemaIssueDetail, SessionContractError, assertSupportedSchemaMajor, } from '../contracts.js';
3
3
  import { streamBoundedJsonLines } from '../readers.js';
4
4
  export const GENERIC_INTERCHANGE_KIND = 'aiwg.session-interchange';
5
5
  export const GENERIC_ADAPTER_VERSION = '1.0.0';
@@ -80,7 +80,7 @@ export class GenericSessionInterchangeAdapter {
80
80
  sessionSequences.add(sequenceKey);
81
81
  }
82
82
  if (!header)
83
- throw new SessionContractError('MALFORMED_SOURCE', 'generic interchange is empty');
83
+ throw new SessionContractError('MALFORMED_SOURCE', 'generic interchange is empty', schemaIssueDetail('<root>'));
84
84
  if (input.incompleteTail) {
85
85
  throw new SessionContractError('TRUNCATED_SOURCE', 'generic interchange contains a truncated record');
86
86
  }
@@ -88,6 +88,7 @@ export class GenericSessionInterchangeAdapter {
88
88
  sourceSchemaVersion: header.schemaVersion,
89
89
  consistency: header.consistency,
90
90
  operationalState: 'available',
91
+ declaredWorkspaceId: header.workspace.id,
91
92
  };
92
93
  }
93
94
  async *stream(source, cursor) {
@@ -99,7 +100,7 @@ export class GenericSessionInterchangeAdapter {
99
100
  const first = await iterator.next();
100
101
  await iterator.return?.();
101
102
  if (first.done)
102
- throw new SessionContractError('MALFORMED_SOURCE', 'generic interchange is empty');
103
+ throw new SessionContractError('MALFORMED_SOURCE', 'generic interchange is empty', schemaIssueDetail('<root>'));
103
104
  header = this.validateHeader(first.value.value, source);
104
105
  }
105
106
  const input = await this.openStream(source, byteCursor ?? undefined);
@@ -159,7 +160,7 @@ export class GenericSessionInterchangeAdapter {
159
160
  };
160
161
  }
161
162
  if (!header) {
162
- throw new SessionContractError('MALFORMED_SOURCE', 'generic interchange is empty');
163
+ throw new SessionContractError('MALFORMED_SOURCE', 'generic interchange is empty', schemaIssueDetail('<root>'));
163
164
  }
164
165
  if (input.incompleteTail) {
165
166
  throw new SessionContractError('TRUNCATED_SOURCE', 'generic interchange contains a truncated record');
@@ -179,7 +180,10 @@ export class GenericSessionInterchangeAdapter {
179
180
  const header = parseHeader(value);
180
181
  assertSupportedSchemaMajor(header.schemaVersion);
181
182
  if (header.sourceId !== source.sourceId) {
182
- throw new SessionContractError('SCHEMA_DRIFT', 'selected source identity does not match interchange header');
183
+ // SCHEMA_DRIFT: the selected identity no longer describes this file's
184
+ // declared source, so importing it would attach events to the wrong source.
185
+ throw new SessionContractError('SCHEMA_DRIFT', `selected source identity does not match interchange header: --source-id ${quoteValue(source.sourceId)} `
186
+ + `but header sourceId is ${quoteValue(header.sourceId)}; pass --source-id ${quoteValue(header.sourceId)}`, schemaIssueDetail('sourceId'));
183
187
  }
184
188
  return header;
185
189
  }
@@ -189,7 +193,7 @@ function parseByteCursor(value) {
189
193
  return null;
190
194
  const position = value.slice(5);
191
195
  if (!/^\d+$/.test(position)) {
192
- throw new SessionContractError('SCHEMA_DRIFT', 'invalid generic byte cursor');
196
+ throw new SessionContractError('SCHEMA_DRIFT', 'invalid generic byte cursor', schemaIssueDetail('cursor'));
193
197
  }
194
198
  return Number(position);
195
199
  }
@@ -200,7 +204,10 @@ function parseHeader(value) {
200
204
  if (hasAmbiguousTimestamp(result.error)) {
201
205
  throw new SessionContractError('AMBIGUOUS_TIMESTAMP', 'generic interchange header has an ambiguous timestamp');
202
206
  }
203
- throw new SessionContractError('MALFORMED_SOURCE', 'input is not a declared AIWG generic session interchange');
207
+ if (!isDeclaredInterchange(value)) {
208
+ throw new SessionContractError('MALFORMED_SOURCE', 'input is not a declared AIWG generic session interchange', schemaRejectionDetail(result.error));
209
+ }
210
+ throw new SessionContractError('MALFORMED_SOURCE', `generic interchange header ${describeIssue(result.error, true)}`, schemaRejectionDetail(result.error));
204
211
  }
205
212
  function parseEvent(value) {
206
213
  const result = GenericInterchangeEventSchema.safeParse(value);
@@ -209,7 +216,34 @@ function parseEvent(value) {
209
216
  if (hasAmbiguousTimestamp(result.error)) {
210
217
  throw new SessionContractError('AMBIGUOUS_TIMESTAMP', 'generic interchange event has an ambiguous timestamp');
211
218
  }
212
- throw new SessionContractError('MALFORMED_SOURCE', 'generic interchange event is malformed');
219
+ // Event values can carry transcript content, so name the field and the
220
+ // expected shape without echoing the received value.
221
+ throw new SessionContractError('MALFORMED_SOURCE', `generic interchange event is malformed: ${describeIssue(result.error, false)}`, schemaRejectionDetail(result.error));
222
+ }
223
+ function isDeclaredInterchange(value) {
224
+ return typeof value === 'object' && value !== null
225
+ && value.type === GENERIC_INTERCHANGE_KIND;
226
+ }
227
+ function quoteValue(value) {
228
+ const text = typeof value === 'string' ? value : JSON.stringify(value) ?? String(value);
229
+ return JSON.stringify(text.length > 64 ? `${text.slice(0, 64)}…` : text);
230
+ }
231
+ function describeIssue(error, echoReceived) {
232
+ const issue = error.issues[0];
233
+ const field = issue.path.length > 0 ? `field "${issue.path.join('.')}"` : 'record';
234
+ if (issue.code === z.ZodIssueCode.invalid_enum_value) {
235
+ const received = echoReceived ? ` (got ${quoteValue(issue.received)})` : '';
236
+ return `${field} must be one of ${issue.options.join('|')}${received}`;
237
+ }
238
+ if (issue.code === z.ZodIssueCode.invalid_type) {
239
+ return issue.received === 'undefined'
240
+ ? `${field} is required (${issue.expected})`
241
+ : `${field} must be ${issue.expected} (got ${issue.received})`;
242
+ }
243
+ if (issue.code === z.ZodIssueCode.invalid_literal) {
244
+ return `${field} must be ${quoteValue(issue.expected)}`;
245
+ }
246
+ return `${field} is invalid: ${issue.message}`;
213
247
  }
214
248
  function hasAmbiguousTimestamp(error) {
215
249
  return error.issues.some((issue) => issue.code === z.ZodIssueCode.custom
@@ -219,7 +253,7 @@ function parseEventCursor(value) {
219
253
  if (value === undefined || value === '')
220
254
  return 0;
221
255
  if (!/^\d+$/.test(value))
222
- throw new SessionContractError('SCHEMA_DRIFT', 'generic event cursor is invalid');
256
+ throw new SessionContractError('SCHEMA_DRIFT', 'generic event cursor is invalid', schemaIssueDetail('cursor'));
223
257
  return Number(value);
224
258
  }
225
259
  //# sourceMappingURL=generic.js.map