@sayknow-cli/coding-agent 0.4.6 → 0.5.0

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 (428) hide show
  1. package/CHANGELOG.md +112 -0
  2. package/dist/types/capability/index.d.ts +10 -20
  3. package/dist/types/capability/types.d.ts +3 -0
  4. package/dist/types/cli/args.d.ts +0 -2
  5. package/dist/types/cli/read-cli.d.ts +1 -0
  6. package/dist/types/cli.d.ts +9 -1
  7. package/dist/types/commands/daemon.d.ts +2 -2
  8. package/dist/types/commands/deep-interview.d.ts +9 -0
  9. package/dist/types/commands/harness.d.ts +22 -0
  10. package/dist/types/commands/read.d.ts +6 -0
  11. package/dist/types/commands/sdk.d.ts +20 -2
  12. package/dist/types/config/keybindings.d.ts +34 -4
  13. package/dist/types/config/model-profile-contract.d.ts +40 -0
  14. package/dist/types/config/model-profiles.d.ts +2 -3
  15. package/dist/types/config/model-registry.d.ts +5 -0
  16. package/dist/types/config/provider-auth-health.d.ts +14 -0
  17. package/dist/types/config/provider-ranking.d.ts +59 -0
  18. package/dist/types/config/settings-schema.d.ts +156 -10
  19. package/dist/types/config/settings.d.ts +3 -0
  20. package/dist/types/edit/modes/patch.d.ts +13 -0
  21. package/dist/types/edit/path-mutation-lock.d.ts +15 -0
  22. package/dist/types/eval/py/executor.d.ts +1 -1
  23. package/dist/types/eval/py/runner-artifact.d.ts +8 -0
  24. package/dist/types/eval/py/tool-bridge.d.ts +1 -2
  25. package/dist/types/extensibility/extensions/types.d.ts +43 -2
  26. package/dist/types/extensibility/shared-events.d.ts +6 -0
  27. package/dist/types/internal-urls/local-root-gc.d.ts +2 -0
  28. package/dist/types/main.d.ts +33 -2
  29. package/dist/types/memories/index.d.ts +2 -0
  30. package/dist/types/modes/acp/acp-agent.d.ts +22 -9
  31. package/dist/types/modes/components/assistant-message.d.ts +3 -1
  32. package/dist/types/modes/components/btw-panel.d.ts +1 -0
  33. package/dist/types/modes/components/irc-sidebar.d.ts +41 -0
  34. package/dist/types/modes/components/queue-pane.d.ts +8 -0
  35. package/dist/types/modes/components/queued-message-selector.d.ts +6 -0
  36. package/dist/types/modes/components/read-tool-group.d.ts +4 -4
  37. package/dist/types/modes/components/runtime-mcp-add-wizard.d.ts +2 -1
  38. package/dist/types/modes/components/session-observer-overlay.d.ts +4 -0
  39. package/dist/types/modes/components/settings-selector.d.ts +2 -0
  40. package/dist/types/modes/components/tool-execution.d.ts +8 -0
  41. package/dist/types/modes/components/tool-status-header.d.ts +4 -2
  42. package/dist/types/modes/components/welcome.d.ts +5 -0
  43. package/dist/types/modes/controllers/btw-controller.d.ts +5 -0
  44. package/dist/types/modes/controllers/command-controller.d.ts +2 -0
  45. package/dist/types/modes/controllers/event-controller.d.ts +3 -0
  46. package/dist/types/modes/interactive-mode.d.ts +13 -2
  47. package/dist/types/modes/irc-observation-ledger.d.ts +17 -1
  48. package/dist/types/modes/prompt-action-autocomplete.d.ts +6 -1
  49. package/dist/types/modes/prompt-suggestion-controller.d.ts +35 -0
  50. package/dist/types/modes/shared/agent-wire/workflow-gate-broker.d.ts +2 -2
  51. package/dist/types/modes/types.d.ts +6 -0
  52. package/dist/types/modes/utils/hotkeys-markdown.d.ts +2 -1
  53. package/dist/types/modes/utils/ui-helpers.d.ts +16 -0
  54. package/dist/types/runtime/memory-domain.d.ts +9 -0
  55. package/dist/types/runtime/memory-guard-contract.d.ts +71 -0
  56. package/dist/types/runtime/memory-guard.d.ts +39 -0
  57. package/dist/types/runtime/memory-limit.d.ts +11 -0
  58. package/dist/types/runtime-mcp/content-limits.d.ts +7 -0
  59. package/dist/types/runtime-mcp/discoverable-tool-metadata.d.ts +1 -1
  60. package/dist/types/runtime-mcp/manager.d.ts +9 -1
  61. package/dist/types/runtime-mcp/oauth-flow.d.ts +0 -5
  62. package/dist/types/runtime-mcp/plugin-network-boundary.d.ts +14 -0
  63. package/dist/types/runtime-mcp/redaction.d.ts +2 -0
  64. package/dist/types/runtime-mcp/smithery-auth.d.ts +5 -0
  65. package/dist/types/sdk/acp/final-text.d.ts +19 -0
  66. package/dist/types/sdk/acp/mcp.d.ts +23 -0
  67. package/dist/types/sdk/broker/broker.d.ts +2 -0
  68. package/dist/types/sdk/broker/lifecycle.d.ts +13 -0
  69. package/dist/types/sdk/bus/chat-daemon-control.d.ts +9 -1
  70. package/dist/types/sdk/bus/config-commands.d.ts +2 -2
  71. package/dist/types/sdk/bus/config.d.ts +2 -0
  72. package/dist/types/sdk/bus/control-drain-lease.d.ts +52 -0
  73. package/dist/types/sdk/bus/conversation-store.d.ts +1 -0
  74. package/dist/types/sdk/bus/daemon-paths.d.ts +1 -0
  75. package/dist/types/sdk/bus/index.d.ts +52 -4
  76. package/dist/types/sdk/bus/kind-aware-reconciliation.d.ts +37 -0
  77. package/dist/types/sdk/bus/lifecycle-commands.d.ts +5 -4
  78. package/dist/types/sdk/bus/notification-orchestration.d.ts +1 -0
  79. package/dist/types/sdk/bus/notification-service.d.ts +34 -0
  80. package/dist/types/sdk/bus/operator-runtime.d.ts +1 -0
  81. package/dist/types/sdk/bus/prompt-reconciliation.d.ts +106 -0
  82. package/dist/types/sdk/bus/rate-limit-pool.d.ts +2 -0
  83. package/dist/types/sdk/bus/reconciliation-store.d.ts +65 -0
  84. package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +33 -9
  85. package/dist/types/sdk/bus/telegram-daemon-control.d.ts +5 -1
  86. package/dist/types/sdk/bus/telegram-daemon.d.ts +286 -12
  87. package/dist/types/sdk/bus/telegram-reference.d.ts +2 -0
  88. package/dist/types/sdk/bus/topic-registry.d.ts +88 -2
  89. package/dist/types/sdk/client/discovery.d.ts +2 -0
  90. package/dist/types/sdk/client/liveness.d.ts +7 -0
  91. package/dist/types/sdk/host/control/operations.d.ts +3 -2
  92. package/dist/types/sdk/host/host.d.ts +3 -1
  93. package/dist/types/sdk/host/query/handlers.d.ts +14 -0
  94. package/dist/types/sdk/index.d.ts +2 -0
  95. package/dist/types/sdk/lifecycle-session.d.ts +10 -1
  96. package/dist/types/sdk/prompt-status.d.ts +88 -0
  97. package/dist/types/sdk/session-directory.d.ts +1 -1
  98. package/dist/types/sdk/session.d.ts +7 -0
  99. package/dist/types/sdk/startup-capability.d.ts +9 -0
  100. package/dist/types/sdk/transport/auth-preface.d.ts +9 -0
  101. package/dist/types/sdk/transport/index.d.ts +12 -0
  102. package/dist/types/sdk/transport/relay.d.ts +43 -0
  103. package/dist/types/sdk/transport/serve-cli.d.ts +4 -0
  104. package/dist/types/sdk/transport/socket.d.ts +7 -0
  105. package/dist/types/sdk/transport/stdio.d.ts +3 -0
  106. package/dist/types/session/agent-session.d.ts +83 -24
  107. package/dist/types/session/btw-contract.d.ts +16 -0
  108. package/dist/types/session/fallback-chain-controller.d.ts +18 -2
  109. package/dist/types/session/internal/managed-session-scope.d.ts +70 -10
  110. package/dist/types/session/internal/managed-session-storage.d.ts +34 -12
  111. package/dist/types/session/internal/native-publish-outcome.d.ts +48 -0
  112. package/dist/types/session/memory-guard-checkpoint-participant.d.ts +69 -0
  113. package/dist/types/session/session-manager.d.ts +89 -18
  114. package/dist/types/session/session-storage.d.ts +31 -0
  115. package/dist/types/session/streaming-output.d.ts +60 -5
  116. package/dist/types/setup/credential-import.d.ts +5 -1
  117. package/dist/types/setup/provider-onboarding.d.ts +2 -0
  118. package/dist/types/skc-runtime/deep-interview-runtime.d.ts +1 -1
  119. package/dist/types/skc-runtime/deep-interview-stage.d.ts +37 -0
  120. package/dist/types/skc-runtime/gc-runtime.d.ts +1 -1
  121. package/dist/types/skc-runtime/linux-proc.d.ts +22 -14
  122. package/dist/types/skc-runtime/memory-guard-owner-claims.d.ts +47 -0
  123. package/dist/types/skc-runtime/ralplan-runtime.d.ts +112 -1
  124. package/dist/types/skc-runtime/repository-binding.d.ts +63 -0
  125. package/dist/types/skc-runtime/state-runtime.d.ts +3 -1
  126. package/dist/types/skc-runtime/state-writer.d.ts +5 -1
  127. package/dist/types/skc-runtime/team-launch.d.ts +1 -1
  128. package/dist/types/skc-runtime/team-runtime.d.ts +9 -2
  129. package/dist/types/skc-runtime/team-store.d.ts +12 -0
  130. package/dist/types/skc-runtime/team-worker-memory-guard.d.ts +92 -0
  131. package/dist/types/skc-runtime/tmux-owner-isolation.d.ts +7 -0
  132. package/dist/types/skc-runtime/ultragoal-guard.d.ts +6 -5
  133. package/dist/types/skc-runtime/ultragoal-receipt-freshness.d.ts +28 -0
  134. package/dist/types/skc-runtime/ultragoal-runtime.d.ts +43 -5
  135. package/dist/types/skill-state/workflow-hud.d.ts +3 -0
  136. package/dist/types/ssh/utils.d.ts +1 -0
  137. package/dist/types/task/discovery.d.ts +3 -1
  138. package/dist/types/task/executor.d.ts +6 -0
  139. package/dist/types/task/index.d.ts +3 -1
  140. package/dist/types/task/provider-retry-status.d.ts +13 -0
  141. package/dist/types/task/receipt.d.ts +2 -0
  142. package/dist/types/task/types.d.ts +133 -0
  143. package/dist/types/task/ultragoal-redteam-activation.d.ts +33 -0
  144. package/dist/types/tools/browser/launch.d.ts +7 -0
  145. package/dist/types/tools/fetch.d.ts +22 -9
  146. package/dist/types/tools/image-gen.d.ts +63 -1
  147. package/dist/types/tools/index.d.ts +7 -1
  148. package/dist/types/tools/output-meta.d.ts +21 -1
  149. package/dist/types/tools/read-internals.d.ts +12 -0
  150. package/dist/types/tools/read.d.ts +45 -1
  151. package/dist/types/tools/resource-gc.d.ts +23 -0
  152. package/dist/types/tools/skill-discovery.d.ts +7 -0
  153. package/dist/types/tools/sqlite-reader.d.ts +7 -0
  154. package/dist/types/tools/tool-result.d.ts +7 -1
  155. package/dist/types/utils/prompt-suggestion.d.ts +33 -0
  156. package/dist/types/utils/shell-snapshot.d.ts +12 -0
  157. package/dist/types/web/insane/bridge.d.ts +1 -0
  158. package/dist/types/web/insane/url-guard.d.ts +17 -0
  159. package/package.json +8 -12
  160. package/scripts/benchmark-sticky-viewport-pr1.ts +239 -0
  161. package/scripts/capture-platform-shortcut-labels-showcase.ts +342 -0
  162. package/scripts/capture-sticky-viewport-showcase.ts +292 -0
  163. package/scripts/compile-args.ts +0 -1
  164. package/scripts/dogfood-repository-binding.ts +209 -0
  165. package/scripts/generate-docs-index.ts +4 -1
  166. package/scripts/generate-sdk-operation-inventory.ts +9 -0
  167. package/scripts/run-test-manifest.ts +6 -4
  168. package/scripts/verify-skc-sdk-canonicalization.ts +122 -18
  169. package/scripts/verify-sticky-viewport-showcase.ts +611 -0
  170. package/src/capability/index.ts +58 -42
  171. package/src/capability/types.ts +3 -0
  172. package/src/cli/args.ts +16 -100
  173. package/src/cli/fast-help.ts +1 -1
  174. package/src/cli/mcp-cli.ts +4 -21
  175. package/src/cli/notify-cli.ts +6 -38
  176. package/src/cli/read-cli.ts +2 -1
  177. package/src/cli/setup-cli.ts +10 -4
  178. package/src/cli.ts +133 -11
  179. package/src/commands/daemon.ts +22 -5
  180. package/src/commands/deep-interview.ts +26 -1
  181. package/src/commands/harness.ts +35 -12
  182. package/src/commands/read.ts +11 -2
  183. package/src/commands/sdk.ts +134 -17
  184. package/src/commands/team.ts +1 -1
  185. package/src/commit/agentic/index.ts +3 -3
  186. package/src/commit/map-reduce/index.ts +2 -2
  187. package/src/config/keybindings.ts +158 -25
  188. package/src/config/model-profile-contract.ts +174 -0
  189. package/src/config/model-profiles.ts +51 -10
  190. package/src/config/model-registry.ts +24 -4
  191. package/src/config/model-resolver.ts +2 -2
  192. package/src/config/provider-auth-health.ts +42 -0
  193. package/src/config/provider-ranking.ts +119 -0
  194. package/src/config/settings-schema.ts +157 -10
  195. package/src/config/settings.ts +254 -108
  196. package/src/coordinator-mcp/model-preset.ts +21 -74
  197. package/src/defaults/skc/skills/deep-interview/SKILL.md +147 -24
  198. package/src/defaults/skc/skills/ralplan/SKILL.md +91 -34
  199. package/src/defaults/skc/skills/team/SKILL.md +1 -1
  200. package/src/defaults/skc/skills/ultragoal/SKILL.md +68 -17
  201. package/src/discovery/ssh.ts +12 -1
  202. package/src/edit/index.ts +3 -6
  203. package/src/edit/modes/patch.ts +38 -1
  204. package/src/edit/modes/replace.ts +42 -0
  205. package/src/edit/path-mutation-lock.ts +112 -0
  206. package/src/eval/js/tool-bridge.ts +1 -1
  207. package/src/eval/py/executor.ts +37 -13
  208. package/src/eval/py/kernel.ts +1 -21
  209. package/src/eval/py/prelude.py +2 -2
  210. package/src/eval/py/runner-artifact.ts +84 -0
  211. package/src/eval/py/tool-bridge.ts +34 -18
  212. package/src/extensibility/extensions/runner.ts +4 -0
  213. package/src/extensibility/extensions/types.ts +42 -4
  214. package/src/extensibility/plugins/marketplace/fetcher.ts +191 -7
  215. package/src/extensibility/shared-events.ts +5 -0
  216. package/src/extensibility/skc-plugins/runtime-adapters.ts +2 -1
  217. package/src/hooks/native-skill-hook.ts +17 -4
  218. package/src/internal-urls/docs-index.generated.ts +17 -16
  219. package/src/internal-urls/local-protocol.ts +87 -25
  220. package/src/internal-urls/local-root-gc.ts +127 -0
  221. package/src/internal-urls/mcp-protocol.ts +73 -11
  222. package/src/main.ts +120 -42
  223. package/src/memories/index.ts +10 -0
  224. package/src/modes/DESIGN.md +52 -0
  225. package/src/modes/acp/acp-agent.ts +647 -83
  226. package/src/modes/acp/acp-event-mapper.ts +106 -12
  227. package/src/modes/acp/acp-mode.ts +39 -3
  228. package/src/modes/action-registry.ts +1 -1
  229. package/src/modes/components/assistant-message.ts +123 -22
  230. package/src/modes/components/btw-panel.ts +82 -16
  231. package/src/modes/components/irc-sidebar.ts +176 -62
  232. package/src/modes/components/model-selector.ts +61 -4
  233. package/src/modes/components/notifications-settings-editor.ts +1 -1
  234. package/src/modes/components/oauth-selector.ts +42 -12
  235. package/src/modes/components/plan-preview-overlay.ts +1 -1
  236. package/src/modes/components/queue-pane.ts +55 -9
  237. package/src/modes/components/queued-message-selector.ts +53 -10
  238. package/src/modes/components/read-tool-group.ts +82 -14
  239. package/src/modes/components/runtime-mcp-add-wizard.ts +5 -0
  240. package/src/modes/components/sayknow-pet-widget.ts +27 -8
  241. package/src/modes/components/session-observer-overlay.ts +187 -32
  242. package/src/modes/components/settings-selector.ts +60 -18
  243. package/src/modes/components/tool-execution.ts +138 -27
  244. package/src/modes/components/tool-status-header.ts +26 -8
  245. package/src/modes/components/welcome.ts +50 -23
  246. package/src/modes/controllers/btw-controller.ts +119 -36
  247. package/src/modes/controllers/command-controller.ts +101 -54
  248. package/src/modes/controllers/event-controller.ts +119 -27
  249. package/src/modes/controllers/extension-ui-controller.ts +23 -12
  250. package/src/modes/controllers/input-controller.ts +100 -8
  251. package/src/modes/controllers/runtime-mcp-command-controller.ts +29 -6
  252. package/src/modes/controllers/selector-controller.ts +4 -1
  253. package/src/modes/interactive-mode.ts +201 -60
  254. package/src/modes/irc-observation-ledger.ts +71 -15
  255. package/src/modes/prompt-action-autocomplete.ts +32 -13
  256. package/src/modes/prompt-suggestion-controller.ts +96 -0
  257. package/src/modes/runtime-init.ts +20 -2
  258. package/src/modes/shared/agent-wire/command-dispatch.ts +3 -3
  259. package/src/modes/shared/agent-wire/workflow-gate-broker.ts +2 -2
  260. package/src/modes/types.ts +6 -0
  261. package/src/modes/utils/hotkeys-markdown.ts +64 -36
  262. package/src/modes/utils/ui-helpers.ts +99 -4
  263. package/src/prompts/agent-fragments/restricted-bash.md +1 -1
  264. package/src/prompts/agents/architect.md +17 -3
  265. package/src/prompts/agents/critic.md +17 -2
  266. package/src/prompts/agents/executor.md +1 -1
  267. package/src/prompts/agents/planner.md +8 -1
  268. package/src/prompts/system/btw-user.md +3 -8
  269. package/src/prompts/system/prompt-suggestion-system.md +32 -0
  270. package/src/prompts/system/system-prompt.md +6 -3
  271. package/src/prompts/tools/cron.md +3 -1
  272. package/src/prompts/tools/read.md +4 -2
  273. package/src/prompts/tools/skill-discovery.md +1 -0
  274. package/src/runtime/memory-domain.ts +66 -0
  275. package/src/runtime/memory-guard-contract.ts +73 -0
  276. package/src/runtime/memory-guard.ts +292 -0
  277. package/src/runtime/memory-limit.ts +50 -0
  278. package/src/runtime-mcp/client.ts +41 -55
  279. package/src/runtime-mcp/content-limits.ts +71 -0
  280. package/src/runtime-mcp/discoverable-tool-metadata.ts +1 -1
  281. package/src/runtime-mcp/json-rpc.ts +28 -11
  282. package/src/runtime-mcp/manager.ts +77 -59
  283. package/src/runtime-mcp/oauth-flow.ts +0 -72
  284. package/src/runtime-mcp/plugin-network-boundary.ts +101 -0
  285. package/src/runtime-mcp/redaction.ts +30 -0
  286. package/src/runtime-mcp/smithery-auth.ts +17 -2
  287. package/src/runtime-mcp/smithery-connect.ts +11 -1
  288. package/src/runtime-mcp/transports/http.ts +63 -22
  289. package/src/sdk/acp/adapter.ts +8 -1
  290. package/src/sdk/acp/final-text.ts +40 -0
  291. package/src/sdk/acp/mcp.ts +26 -0
  292. package/src/sdk/broker/broker.ts +34 -20
  293. package/src/sdk/broker/identity.ts +22 -12
  294. package/src/sdk/broker/lifecycle.ts +293 -43
  295. package/src/sdk/broker/session-index.ts +11 -1
  296. package/src/sdk/bus/chat-daemon-cli.ts +2 -2
  297. package/src/sdk/bus/chat-daemon-control.ts +22 -5
  298. package/src/sdk/bus/config-commands.ts +2 -2
  299. package/src/sdk/bus/config.ts +10 -2
  300. package/src/sdk/bus/control-drain-lease.ts +104 -0
  301. package/src/sdk/bus/conversation-store.ts +40 -6
  302. package/src/sdk/bus/daemon-paths.ts +2 -0
  303. package/src/sdk/bus/index.ts +793 -121
  304. package/src/sdk/bus/kind-aware-reconciliation.ts +242 -0
  305. package/src/sdk/bus/lifecycle-commands.ts +63 -10
  306. package/src/sdk/bus/lifecycle-control-runtime.ts +11 -2
  307. package/src/sdk/bus/lifecycle-orchestrator.ts +32 -1
  308. package/src/sdk/bus/notification-orchestration.ts +12 -0
  309. package/src/sdk/bus/notification-service.ts +87 -25
  310. package/src/sdk/bus/operator-runtime.ts +31 -5
  311. package/src/sdk/bus/prompt-reconciliation.ts +240 -0
  312. package/src/sdk/bus/rate-limit-pool.ts +8 -0
  313. package/src/sdk/bus/recent-activity.ts +90 -26
  314. package/src/sdk/bus/reconciliation-store.ts +224 -0
  315. package/src/sdk/bus/telegram-cli.ts +6 -13
  316. package/src/sdk/bus/telegram-daemon-cli.ts +8 -3
  317. package/src/sdk/bus/telegram-daemon-contract.ts +34 -9
  318. package/src/sdk/bus/telegram-daemon-control.ts +161 -40
  319. package/src/sdk/bus/telegram-daemon.ts +3649 -593
  320. package/src/sdk/bus/telegram-reference.ts +20 -2
  321. package/src/sdk/bus/topic-registry.ts +451 -12
  322. package/src/sdk/cli/session-cli.ts +15 -2
  323. package/src/sdk/client/discovery.ts +19 -3
  324. package/src/sdk/client/liveness.ts +49 -0
  325. package/src/sdk/host/control/dispatch.ts +8 -2
  326. package/src/sdk/host/control/operations.ts +3 -2
  327. package/src/sdk/host/host.ts +27 -9
  328. package/src/sdk/host/query/handlers.ts +125 -5
  329. package/src/sdk/index.ts +12 -0
  330. package/src/sdk/lifecycle-session.ts +19 -3
  331. package/src/sdk/mcp/server.ts +46 -18
  332. package/src/sdk/prompt-status.ts +97 -0
  333. package/src/sdk/protocol/operation-inventory.generated.json +145 -0
  334. package/src/sdk/protocol/operation-registry.ts +24 -4
  335. package/src/sdk/session-directory.ts +5 -1
  336. package/src/sdk/session.ts +69 -8
  337. package/src/sdk/startup-capability.ts +15 -1
  338. package/src/sdk/transport/auth-preface.ts +82 -0
  339. package/src/sdk/transport/index.ts +18 -0
  340. package/src/sdk/transport/relay.ts +252 -0
  341. package/src/sdk/transport/serve-cli.ts +105 -0
  342. package/src/sdk/transport/socket.ts +197 -0
  343. package/src/sdk/transport/stdio.ts +17 -0
  344. package/src/session/agent-session.ts +1112 -314
  345. package/src/session/blob-store.ts +25 -7
  346. package/src/session/btw-contract.ts +59 -0
  347. package/src/session/fallback-chain-controller.ts +47 -8
  348. package/src/session/internal/managed-session-scope.ts +1426 -259
  349. package/src/session/internal/managed-session-storage.ts +414 -238
  350. package/src/session/internal/native-publish-outcome.ts +271 -0
  351. package/src/session/memory-guard-checkpoint-participant.ts +131 -0
  352. package/src/session/session-manager.ts +2079 -469
  353. package/src/session/session-storage.ts +151 -11
  354. package/src/session/streaming-output.ts +262 -43
  355. package/src/setup/credential-import.ts +28 -3
  356. package/src/setup/provider-onboarding.ts +49 -5
  357. package/src/setup/provider-presets.json +2 -1
  358. package/src/skc-runtime/deep-interview-runtime.ts +303 -36
  359. package/src/skc-runtime/deep-interview-stage.ts +1016 -0
  360. package/src/skc-runtime/deep-interview-state.ts +8 -5
  361. package/src/skc-runtime/gc-render.ts +1 -0
  362. package/src/skc-runtime/gc-runtime.ts +11 -1
  363. package/src/skc-runtime/linux-proc.ts +70 -36
  364. package/src/skc-runtime/managed-owner-supervisor.ts +83 -4
  365. package/src/skc-runtime/memory-guard-owner-claims.ts +389 -0
  366. package/src/skc-runtime/ralplan-runtime.ts +1057 -75
  367. package/src/skc-runtime/repository-binding.ts +267 -0
  368. package/src/skc-runtime/session-state-sidecar.ts +25 -9
  369. package/src/skc-runtime/state-runtime.ts +50 -12
  370. package/src/skc-runtime/state-writer.ts +68 -56
  371. package/src/skc-runtime/team-launch.ts +34 -5
  372. package/src/skc-runtime/team-runtime.ts +41 -1
  373. package/src/skc-runtime/team-store.ts +32 -0
  374. package/src/skc-runtime/team-worker-memory-guard.ts +363 -0
  375. package/src/skc-runtime/team-workers.ts +1 -0
  376. package/src/skc-runtime/tmux-common.ts +13 -2
  377. package/src/skc-runtime/tmux-owner-isolation.ts +20 -1
  378. package/src/skc-runtime/tmux-sessions.ts +45 -6
  379. package/src/skc-runtime/ultragoal-guard.ts +93 -15
  380. package/src/skc-runtime/ultragoal-receipt-freshness.ts +123 -0
  381. package/src/skc-runtime/ultragoal-runtime.ts +469 -38
  382. package/src/skc-runtime/workflow-manifest.generated.json +195 -5
  383. package/src/skc-runtime/workflow-manifest.ts +67 -3
  384. package/src/skill-state/workflow-hud.ts +25 -2
  385. package/src/skill-state/workflow-mutation-guard.ts +104 -12
  386. package/src/slash-commands/builtin-registry.ts +1 -1
  387. package/src/ssh/utils.ts +14 -0
  388. package/src/task/discovery.ts +8 -2
  389. package/src/task/executor.ts +165 -47
  390. package/src/task/index.ts +123 -15
  391. package/src/task/provider-retry-status.ts +88 -0
  392. package/src/task/receipt.ts +3 -0
  393. package/src/task/render.ts +45 -26
  394. package/src/task/skc-command.ts +2 -2
  395. package/src/task/types.ts +55 -10
  396. package/src/task/ultragoal-redteam-activation.ts +75 -0
  397. package/src/tools/ask.ts +1 -1
  398. package/src/tools/ast-edit.ts +2 -2
  399. package/src/tools/bash-allowed-prefixes.ts +45 -1
  400. package/src/tools/bash-pty-selection.ts +2 -2
  401. package/src/tools/browser/launch.ts +41 -6
  402. package/src/tools/browser/screenshot-format.ts +6 -1
  403. package/src/tools/cron.ts +1 -1
  404. package/src/tools/fetch.ts +127 -154
  405. package/src/tools/image-gen.ts +476 -23
  406. package/src/tools/index.ts +7 -1
  407. package/src/tools/output-meta.ts +176 -9
  408. package/src/tools/path-utils.ts +5 -1
  409. package/src/tools/read-internals.ts +44 -0
  410. package/src/tools/read.ts +1544 -310
  411. package/src/tools/resource-gc.ts +665 -125
  412. package/src/tools/skill-discovery.ts +39 -3
  413. package/src/tools/sqlite-reader.ts +63 -5
  414. package/src/tools/subagent-render.ts +74 -16
  415. package/src/tools/subagent.ts +2 -0
  416. package/src/tools/tool-result.ts +14 -1
  417. package/src/utils/edit-mode.ts +2 -2
  418. package/src/utils/pasted-image-path.ts +15 -6
  419. package/src/utils/prompt-suggestion.ts +265 -0
  420. package/src/utils/shell-snapshot.ts +173 -63
  421. package/src/utils/sixel.ts +3 -3
  422. package/src/web/insane/bridge.ts +5 -1
  423. package/src/web/insane/url-guard.ts +140 -27
  424. package/src/web/scrapers/docs-rs.ts +30 -5
  425. package/src/web/scrapers/types.ts +19 -49
  426. package/src/web/scrapers/utils.ts +12 -26
  427. package/src/web/search/providers/codex.ts +1 -1
  428. package/src/workflow/workflow-intent-diff.ts +4 -1
@@ -1,16 +1,30 @@
1
1
  import { createHash, randomBytes } from "node:crypto";
2
2
  import * as fs from "node:fs/promises";
3
- import * as os from "node:os";
4
3
  import * as path from "node:path";
4
+ import { getConfigRootDir } from "@sayknow-cli/utils";
5
+ import { YAML } from "bun";
5
6
  import { syncSkillActiveState } from "../skill-state/active-state";
6
7
  import { deriveDeepInterviewHud } from "../skill-state/workflow-hud";
7
8
  import { WORKFLOW_STATE_VERSION } from "../skill-state/workflow-state-contract";
8
- import { normalizeDeepInterviewEnvelope } from "./deep-interview-state";
9
+ import { isDeepInterviewStageVerb, runDeepInterviewStageCommand } from "./deep-interview-stage";
10
+ import {
11
+ assertDeepInterviewInputWithinLimit,
12
+ assertDeepInterviewIntentReview,
13
+ type DeepInterviewIntentCategory,
14
+ type DeepInterviewIntentItem,
15
+ type DeepInterviewIntentManifest,
16
+ type DeepInterviewIntentReview,
17
+ MAX_DEEP_INTERVIEW_STRUCTURED_RESPONSE_LENGTH,
18
+ MAX_INITIAL_CONTEXT_LENGTH,
19
+ normalizeDeepInterviewEnvelope,
20
+ reviewDeepInterviewIntent,
21
+ } from "./deep-interview-state";
9
22
  import { runNativeRalplanCommand } from "./ralplan-runtime";
10
23
  import { modeStatePath, sessionSpecsDir } from "./session-layout";
11
24
  import { resolveSkcSessionForWrite, writeSessionActivityMarker } from "./session-resolution";
12
25
  import { runNativeStateCommand } from "./state-runtime";
13
26
  import { appendJsonl, readExistingStateForMutation, writeArtifact, writeWorkflowEnvelopeAtomic } from "./state-writer";
27
+ import { assertSafePathComponent, CommandError, flagValue, hasFlag } from "./workflow-cli-common";
14
28
 
15
29
  export * from "./deep-interview-recorder";
16
30
 
@@ -19,7 +33,7 @@ export * from "./deep-interview-recorder";
19
33
  *
20
34
  * The CLI itself does not run the Socratic interview; that lives inside the `/skill:deep-interview`
21
35
  * skill executed by the agent. This handler validates the documented argument-hint surface
22
- * (`[--quick|--standard|--deep] <idea>`), seeds `.skc/state/deep-interview-state.json`, and
36
+ * (`[--trace] [--quick|--standard|--deep] <idea>`), seeds `.skc/state/deep-interview-state.json`, and
23
37
  * updates the shared HUD rail via `syncSkillActiveState` so the active interview is visible to
24
38
  * the TUI.
25
39
  */
@@ -30,8 +44,6 @@ export interface DeepInterviewCommandResult {
30
44
  stderr?: string;
31
45
  }
32
46
 
33
- const PATH_COMPONENT_RE = /^[A-Za-z0-9_-][A-Za-z0-9._-]{0,63}$/;
34
-
35
47
  const DEFAULT_AMBIGUITY_THRESHOLD = 0.05;
36
48
 
37
49
  const RESOLUTION_THRESHOLDS = {
@@ -40,14 +52,73 @@ const RESOLUTION_THRESHOLDS = {
40
52
  deep: 0.35,
41
53
  } as const;
42
54
 
55
+ const TRACE_MAX_RELEVANT_PATHS = 12;
56
+ const TRACE_MAX_PACKAGE_HINTS = 8;
57
+ const TRACE_MAX_DIRECTORY_VISITS = 1200;
58
+ const TRACE_MAX_ENTRY_VISITS = 5000;
59
+ const TRACE_MAX_PENDING_DIRECTORIES = 1200;
60
+ const TRACE_SKIP_DIRS = new Set([
61
+ ".git",
62
+ ".skc",
63
+ "node_modules",
64
+ "dist",
65
+ "build",
66
+ "coverage",
67
+ ".next",
68
+ ".turbo",
69
+ ".cache",
70
+ "vendor",
71
+ "target",
72
+ ".venv",
73
+ "venv",
74
+ "__pycache__",
75
+ ".pytest_cache",
76
+ "tmp",
77
+ "temp",
78
+ "logs",
79
+ "out",
80
+ ]);
81
+ const TRACE_SOURCE_EXTENSIONS = new Set([
82
+ ".ts",
83
+ ".tsx",
84
+ ".js",
85
+ ".jsx",
86
+ ".mts",
87
+ ".cts",
88
+ ".py",
89
+ ".rs",
90
+ ".go",
91
+ ".java",
92
+ ".kt",
93
+ ".swift",
94
+ ".md",
95
+ ".json",
96
+ ".yml",
97
+ ".yaml",
98
+ ]);
99
+
100
+ interface DeepInterviewTraceSummary {
101
+ enabled: true;
102
+ generated_at: string;
103
+ bounded: true;
104
+ limits: {
105
+ max_relevant_paths: number;
106
+ max_package_hints: number;
107
+ max_directory_visits: number;
108
+ max_entry_visits: number;
109
+ max_pending_directories: number;
110
+ };
111
+ idea_terms: string[];
112
+ project_hints: string[];
113
+ relevant_paths: Array<{ path: string; reason: string }>;
114
+ findings: string[];
115
+ }
116
+
43
117
  type DeepInterviewResolution = keyof typeof RESOLUTION_THRESHOLDS;
44
118
 
45
- class DeepInterviewCommandError extends Error {
46
- constructor(
47
- public readonly exitStatus: number,
48
- message: string,
49
- ) {
50
- super(message);
119
+ class DeepInterviewCommandError extends CommandError {
120
+ constructor(exitStatus: number, message: string) {
121
+ super(exitStatus, message);
51
122
  this.name = "DeepInterviewCommandError";
52
123
  }
53
124
  }
@@ -62,22 +133,6 @@ const VALUE_FLAGS = new Set([
62
133
  "--handoff",
63
134
  ]);
64
135
 
65
- function flagValue(args: readonly string[], flag: string): string | undefined {
66
- const index = args.indexOf(flag);
67
- if (index < 0) return undefined;
68
- return args[index + 1];
69
- }
70
-
71
- function hasFlag(args: readonly string[], flag: string): boolean {
72
- return args.includes(flag);
73
- }
74
-
75
- function assertSafePathComponent(value: string, label: string): void {
76
- if (!PATH_COMPONENT_RE.test(value) || value.includes("..")) {
77
- throw new DeepInterviewCommandError(2, `invalid path component for --${label}: ${value}`);
78
- }
79
- }
80
-
81
136
  function defaultSpecSlug(now: Date = new Date()): string {
82
137
  const yyyy = now.getUTCFullYear().toString().padStart(4, "0");
83
138
  const mm = (now.getUTCMonth() + 1).toString().padStart(2, "0");
@@ -100,13 +155,141 @@ async function resolveSpecContent(rawSpec: string, cwd: string): Promise<string>
100
155
  if (stat.isFile()) return await fs.readFile(candidate, "utf-8");
101
156
  } catch (error) {
102
157
  const err = error as NodeJS.ErrnoException;
103
- if (err.code !== "ENOENT" && err.code !== "ENOTDIR") {
158
+ if (err.code !== "ENOENT" && err.code !== "ENOTDIR" && err.code !== "ENAMETOOLONG") {
104
159
  throw new DeepInterviewCommandError(2, `failed to read --spec ${candidate}: ${err.message}`);
105
160
  }
106
161
  }
107
162
  return rawSpec;
108
163
  }
109
164
 
165
+ function traceTerms(idea: string): string[] {
166
+ const terms = new Set<string>();
167
+ for (const match of idea.toLowerCase().matchAll(/[a-z0-9][a-z0-9_-]{2,}/g)) {
168
+ const value = match[0];
169
+ if (["the", "and", "for", "with", "that", "this", "from", "into", "should", "would"].includes(value)) continue;
170
+ terms.add(value);
171
+ if (terms.size >= 12) break;
172
+ }
173
+ return [...terms];
174
+ }
175
+
176
+ function relativePathReason(relativePath: string, terms: readonly string[]): string | undefined {
177
+ const normalized = relativePath.toLowerCase();
178
+ const matched = terms.find(term => normalized.includes(term));
179
+ if (matched) return `path matches idea term "${matched}"`;
180
+ if (/deep[-_]?interview/i.test(relativePath)) return "path matches deep-interview workflow surface";
181
+ if (/skill|workflow|runtime|state/i.test(relativePath)) return "path matches workflow/runtime surface";
182
+ return undefined;
183
+ }
184
+
185
+ async function readPackageHints(cwd: string): Promise<string[]> {
186
+ const packagePath = path.join(cwd, "package.json");
187
+ let parsed: unknown;
188
+ try {
189
+ parsed = JSON.parse(await fs.readFile(packagePath, "utf-8"));
190
+ } catch {
191
+ return [];
192
+ }
193
+ const manifest = parsed as {
194
+ name?: unknown;
195
+ workspaces?: unknown;
196
+ scripts?: Record<string, unknown>;
197
+ dependencies?: Record<string, unknown>;
198
+ devDependencies?: Record<string, unknown>;
199
+ };
200
+ const hints: string[] = [];
201
+ if (typeof manifest.name === "string") hints.push(`package: ${manifest.name}`);
202
+ if (manifest.workspaces) hints.push("workspace: package.json declares workspaces");
203
+ const scripts = Object.keys(manifest.scripts ?? {}).slice(0, TRACE_MAX_PACKAGE_HINTS);
204
+ if (scripts.length > 0) hints.push(`scripts: ${scripts.join(", ")}`);
205
+ const deps = [...Object.keys(manifest.dependencies ?? {}), ...Object.keys(manifest.devDependencies ?? {})]
206
+ .filter(name => /typescript|bun|react|vite|zod|winston|commander|oclif/i.test(name))
207
+ .slice(0, TRACE_MAX_PACKAGE_HINTS);
208
+ if (deps.length > 0) hints.push(`notable dependencies: ${deps.join(", ")}`);
209
+ return hints.slice(0, TRACE_MAX_PACKAGE_HINTS);
210
+ }
211
+
212
+ async function collectRelevantTracePaths(
213
+ cwd: string,
214
+ terms: readonly string[],
215
+ ): Promise<Array<{ path: string; reason: string }>> {
216
+ const results: Array<{ path: string; reason: string; score: number }> = [];
217
+ const pending: Array<{ absolutePath: string; depth: number }> = [{ absolutePath: cwd, depth: 0 }];
218
+ let visitedDirectories = 0;
219
+ let visitedEntries = 0;
220
+ while (
221
+ pending.length > 0 &&
222
+ visitedDirectories < TRACE_MAX_DIRECTORY_VISITS &&
223
+ visitedEntries < TRACE_MAX_ENTRY_VISITS
224
+ ) {
225
+ const current = pending.shift();
226
+ if (!current) break;
227
+ visitedDirectories += 1;
228
+ try {
229
+ const directory = await fs.opendir(current.absolutePath);
230
+ for await (const entry of directory) {
231
+ visitedEntries += 1;
232
+ if (visitedEntries > TRACE_MAX_ENTRY_VISITS) break;
233
+ if (TRACE_SKIP_DIRS.has(entry.name)) continue;
234
+ const absolutePath = path.join(current.absolutePath, entry.name);
235
+ const relativePath = path.relative(cwd, absolutePath).split(path.sep).join("/");
236
+ if (entry.isDirectory()) {
237
+ if (current.depth < 6 && pending.length < TRACE_MAX_PENDING_DIRECTORIES) {
238
+ pending.push({ absolutePath, depth: current.depth + 1 });
239
+ }
240
+ continue;
241
+ }
242
+ if (!entry.isFile() || !TRACE_SOURCE_EXTENSIONS.has(path.extname(entry.name))) continue;
243
+ const reason = relativePathReason(relativePath, terms);
244
+ if (!reason) continue;
245
+ const termScore = terms.reduce(
246
+ (score, term) => score + (relativePath.toLowerCase().includes(term) ? 2 : 0),
247
+ 0,
248
+ );
249
+ const surfaceScore = /deep[-_]?interview|skill|workflow|runtime|state/i.test(relativePath) ? 1 : 0;
250
+ results.push({ path: relativePath, reason, score: termScore + surfaceScore });
251
+ }
252
+ } catch {}
253
+ }
254
+ return results
255
+ .sort((a, b) => b.score - a.score || a.path.localeCompare(b.path))
256
+ .slice(0, TRACE_MAX_RELEVANT_PATHS)
257
+ .map(({ path: relativePath, reason }) => ({ path: relativePath, reason }));
258
+ }
259
+
260
+ async function buildDeepInterviewTraceSummary(cwd: string, idea: string): Promise<DeepInterviewTraceSummary> {
261
+ const terms = traceTerms(idea);
262
+ const [projectHints, relevantPaths] = await Promise.all([
263
+ readPackageHints(cwd),
264
+ collectRelevantTracePaths(cwd, terms),
265
+ ]);
266
+ const findings = [
267
+ projectHints.length > 0
268
+ ? "Project manifest was summarized into bounded package/script/dependency hints."
269
+ : "No readable package.json manifest was found at the project root.",
270
+ relevantPaths.length > 0
271
+ ? `Relevant path scan captured ${relevantPaths.length} bounded path hint(s) before interview questions.`
272
+ : "Relevant path scan found no matching source/documentation paths before interview questions.",
273
+ "Trace summary intentionally stores path-level evidence only; raw files and logs are excluded.",
274
+ ];
275
+ return {
276
+ enabled: true,
277
+ generated_at: new Date().toISOString(),
278
+ bounded: true,
279
+ limits: {
280
+ max_relevant_paths: TRACE_MAX_RELEVANT_PATHS,
281
+ max_package_hints: TRACE_MAX_PACKAGE_HINTS,
282
+ max_directory_visits: TRACE_MAX_DIRECTORY_VISITS,
283
+ max_entry_visits: TRACE_MAX_ENTRY_VISITS,
284
+ max_pending_directories: TRACE_MAX_PENDING_DIRECTORIES,
285
+ },
286
+ idea_terms: terms,
287
+ project_hints: projectHints,
288
+ relevant_paths: relevantPaths,
289
+ findings,
290
+ };
291
+ }
292
+
110
293
  interface ResolvedDeepInterviewArgs {
111
294
  resolution: DeepInterviewResolution;
112
295
  threshold: number;
@@ -114,6 +297,7 @@ interface ResolvedDeepInterviewArgs {
114
297
  sessionId: string;
115
298
  idea: string;
116
299
  language?: DeepInterviewLanguagePreference;
300
+ trace?: DeepInterviewTraceSummary;
117
301
  json: boolean;
118
302
  }
119
303
 
@@ -190,16 +374,14 @@ async function readSettingsAmbiguityThreshold(
190
374
  function modernSettingsPath(): string {
191
375
  const configDir = process.env.SKC_CODING_AGENT_DIR?.trim() || process.env.PI_CODING_AGENT_DIR?.trim();
192
376
  if (configDir) return path.join(configDir, "config.yml");
193
- const configRoot = process.env.SKC_CONFIG_DIR?.trim() || process.env.PI_CONFIG_DIR?.trim();
194
- if (configRoot) return path.join(configRoot, "agent", "config.yml");
195
- return path.join(os.homedir(), ".skc", "agent", "config.yml");
377
+ return path.join(getConfigRootDir(), "agent", "config.yml");
196
378
  }
197
379
 
198
380
  async function readModernSettingsAmbiguityThreshold(): Promise<{ threshold: number; source: string } | undefined> {
199
381
  const modernConfigPath = modernSettingsPath();
200
382
  let parsed: unknown;
201
383
  try {
202
- parsed = (await import("bun")).YAML.parse(await fs.readFile(modernConfigPath, "utf-8"));
384
+ parsed = YAML.parse(await fs.readFile(modernConfigPath, "utf-8"));
203
385
  } catch {
204
386
  return undefined;
205
387
  }
@@ -218,8 +400,7 @@ async function resolveConfiguredAmbiguityThreshold(
218
400
  const projectSettings = path.join(cwd, ".skc", "settings.json");
219
401
  const projectValue = await readSettingsAmbiguityThreshold(projectSettings);
220
402
  if (projectValue) return projectValue;
221
- const configDir = process.env.SKC_CONFIG_DIR?.trim() || path.join(os.homedir(), ".skc");
222
- const userSettings = path.join(configDir, "settings.json");
403
+ const userSettings = path.join(getConfigRootDir(), "settings.json");
223
404
  return await readSettingsAmbiguityThreshold(userSettings);
224
405
  }
225
406
 
@@ -371,6 +552,7 @@ async function resolveDeepInterviewArgs(args: readonly string[], cwd: string): P
371
552
  skipNext = true;
372
553
  continue;
373
554
  }
555
+ if (arg === "--trace") continue;
374
556
  if (arg === "--quick" || arg === "--standard" || arg === "--deep" || arg === "--json") continue;
375
557
  if (arg.startsWith("-")) {
376
558
  throw new DeepInterviewCommandError(2, `unknown flag for skc deep-interview: ${arg}`);
@@ -378,7 +560,9 @@ async function resolveDeepInterviewArgs(args: readonly string[], cwd: string): P
378
560
  ideaParts.push(arg);
379
561
  }
380
562
  const idea = ideaParts.join(" ").trim();
563
+ assertDeepInterviewInputWithinLimit(idea, MAX_INITIAL_CONTEXT_LENGTH, "initial_idea");
381
564
  const effectiveResolution: DeepInterviewResolution = resolution ?? "standard";
565
+ const trace = hasFlag(args, "--trace") && idea ? await buildDeepInterviewTraceSummary(cwd, idea) : undefined;
382
566
  return {
383
567
  resolution: effectiveResolution,
384
568
  threshold,
@@ -386,14 +570,75 @@ async function resolveDeepInterviewArgs(args: readonly string[], cwd: string): P
386
570
  sessionId,
387
571
  idea,
388
572
  language: resolveDeepInterviewLanguagePreference(idea),
573
+ trace,
389
574
  json: hasFlag(args, "--json"),
390
575
  };
391
576
  }
392
577
 
578
+ function intentIdsInSpec(content: string): string[] {
579
+ const ids = content.match(/(?:artifact|surface|integration|constraint):[a-z0-9][a-z0-9._/-]{0,127}/g) ?? [];
580
+ return [...new Set(ids)].sort();
581
+ }
582
+
583
+ function resolveLockedIntentReview(existing: unknown, content: string): DeepInterviewIntentReview | undefined {
584
+ const envelope = normalizeDeepInterviewEnvelope(existing);
585
+ const state = envelope.state;
586
+ if (!state) return undefined;
587
+ if (state.intent_contract === undefined) {
588
+ if (state.intent_contract_required === true)
589
+ throw new DeepInterviewCommandError(
590
+ 2,
591
+ "deep-interview locked intent blocks spec persistence: missing Round 0 intent contract",
592
+ );
593
+ return undefined;
594
+ }
595
+ const locked = state.intent_contract as DeepInterviewIntentManifest;
596
+ const observedIds = intentIdsInSpec(content);
597
+ const rounds = Array.isArray(state.rounds)
598
+ ? state.rounds
599
+ .filter(
600
+ (round): round is Record<string, unknown> =>
601
+ Boolean(round) && typeof round === "object" && !Array.isArray(round),
602
+ )
603
+ .map(round => ({ round: round.round, answer_hash: round.answer_hash }))
604
+ : [];
605
+ try {
606
+ if (state.intent_review === undefined) {
607
+ if (locked.items.some(item => !observedIds.includes(item.id))) throw new Error("missing intent review");
608
+ const lockedById = new Map(locked.items.map(item => [item.id, item]));
609
+ const observedItems: DeepInterviewIntentItem[] = observedIds.map(id => {
610
+ const existingItem = lockedById.get(id);
611
+ if (existingItem) return existingItem;
612
+ return {
613
+ id,
614
+ category: id.slice(0, id.indexOf(":")) as DeepInterviewIntentCategory,
615
+ statement: id,
616
+ };
617
+ });
618
+ return reviewDeepInterviewIntent(locked, observedItems, {
619
+ status: "not_required",
620
+ supporting_substitutions: [],
621
+ });
622
+ }
623
+ assertDeepInterviewIntentReview(state.intent_review, locked, observedIds, rounds);
624
+ return state.intent_review as DeepInterviewIntentReview;
625
+ } catch (error) {
626
+ throw new DeepInterviewCommandError(
627
+ 2,
628
+ `deep-interview locked intent blocks spec persistence: ${error instanceof Error ? error.message : String(error)}`,
629
+ );
630
+ }
631
+ }
632
+
393
633
  export async function persistDeepInterviewSpec(
394
634
  cwd: string,
395
635
  resolved: ResolvedDeepInterviewSpecWriteArgs,
396
636
  ): Promise<PersistedDeepInterviewSpec> {
637
+ assertDeepInterviewInputWithinLimit(
638
+ resolved.spec,
639
+ MAX_DEEP_INTERVIEW_STRUCTURED_RESPONSE_LENGTH,
640
+ "structured deep-interview response",
641
+ );
397
642
  const statePath = deepInterviewStatePath(cwd, resolved.sessionId);
398
643
  const existingRead = await readExistingStateForMutation(statePath);
399
644
  if (existingRead.kind === "corrupt" && !resolved.force) {
@@ -404,8 +649,9 @@ export async function persistDeepInterviewSpec(
404
649
  }
405
650
  const existing = existingRead.kind === "valid" ? existingRead.value : {};
406
651
 
407
- const specPath = path.join(sessionSpecsDir(cwd, resolved.sessionId), `deep-interview-${resolved.slug}.md`);
408
652
  const content = resolved.spec.endsWith("\n") ? resolved.spec : `${resolved.spec}\n`;
653
+ const intentReview = resolveLockedIntentReview(existing, content);
654
+ const specPath = path.join(sessionSpecsDir(cwd, resolved.sessionId), `deep-interview-${resolved.slug}.md`);
409
655
  await writeArtifact(specPath, content, {
410
656
  cwd,
411
657
  audit: {
@@ -447,6 +693,10 @@ export async function persistDeepInterviewSpec(
447
693
  spec_persisted_at: createdAt,
448
694
  updated_at: createdAt,
449
695
  }) as Record<string, unknown>;
696
+ if (intentReview) {
697
+ const state = payload.state as Record<string, unknown>;
698
+ state.intent_review = intentReview;
699
+ }
450
700
  if (resolved.sessionId) payload.session_id = resolved.sessionId;
451
701
  await writeWorkflowEnvelopeAtomic(statePath, payload, {
452
702
  cwd,
@@ -488,6 +738,7 @@ export async function persistDeepInterviewSpec(
488
738
 
489
739
  async function seedDeepInterviewState(cwd: string, resolved: ResolvedDeepInterviewArgs): Promise<string> {
490
740
  const statePath = deepInterviewStatePath(cwd, resolved.sessionId);
741
+ assertDeepInterviewInputWithinLimit(resolved.idea, MAX_INITIAL_CONTEXT_LENGTH, "initial_idea");
491
742
  const now = new Date().toISOString();
492
743
  const payload: Record<string, unknown> = {
493
744
  active: true,
@@ -499,6 +750,7 @@ async function seedDeepInterviewState(cwd: string, resolved: ResolvedDeepIntervi
499
750
  threshold_source: resolved.thresholdSource,
500
751
  state: {
501
752
  initial_idea: resolved.idea,
753
+ intent_contract_required: true,
502
754
  rounds: [],
503
755
  established_facts: [],
504
756
  current_ambiguity: 1.0,
@@ -507,6 +759,17 @@ async function seedDeepInterviewState(cwd: string, resolved: ResolvedDeepIntervi
507
759
  },
508
760
  updated_at: now,
509
761
  };
762
+ if (resolved.trace) {
763
+ payload.trace = resolved.trace;
764
+ (payload.state as Record<string, unknown>).trace = resolved.trace;
765
+ (payload.state as Record<string, unknown>).trace_summary = resolved.trace;
766
+ (payload.state as Record<string, unknown>).codebase_context = {
767
+ source: "trace",
768
+ summary: resolved.trace.findings,
769
+ relevant_paths: resolved.trace.relevant_paths,
770
+ project_hints: resolved.trace.project_hints,
771
+ };
772
+ }
510
773
  if (resolved.language) {
511
774
  payload.language = resolved.language;
512
775
  (payload.state as Record<string, unknown>).language = resolved.language;
@@ -629,6 +892,8 @@ export async function runNativeDeepInterviewCommand(
629
892
  cwd = process.cwd(),
630
893
  ): Promise<DeepInterviewCommandResult> {
631
894
  try {
895
+ const [firstArg, ...restArgs] = args;
896
+ if (isDeepInterviewStageVerb(firstArg)) return await runDeepInterviewStageCommand(firstArg, restArgs, cwd);
632
897
  if (isDeepInterviewSpecWriteInvocation(args)) return await handleSpecWrite(args, cwd);
633
898
  const resolved = await resolveDeepInterviewArgs(args, cwd);
634
899
  if (!resolved.idea) {
@@ -646,6 +911,7 @@ export async function runNativeDeepInterviewCommand(
646
911
  threshold_source: resolved.thresholdSource,
647
912
  idea: resolved.idea,
648
913
  language: resolved.language,
914
+ trace: resolved.trace,
649
915
  state_path: statePath,
650
916
  handoff: "/skill:deep-interview",
651
917
  };
@@ -654,12 +920,13 @@ export async function runNativeDeepInterviewCommand(
654
920
  : [
655
921
  `deep-interview seed state_path=${statePath}`,
656
922
  `resolution=${resolved.resolution} threshold=${resolved.threshold} threshold_source=${resolved.thresholdSource}`,
923
+ resolved.trace ? `trace=enabled bounded_paths=${resolved.trace.relevant_paths.length}` : undefined,
657
924
  "handoff=/skill:deep-interview",
658
925
  "",
659
926
  ].join("\n");
660
927
  return { status: 0, stdout };
661
928
  } catch (error) {
662
- if (error instanceof DeepInterviewCommandError) return { status: error.exitStatus, stderr: `${error.message}\n` };
929
+ if (error instanceof CommandError) return { status: error.exitStatus, stderr: `${error.message}\n` };
663
930
  return { status: 1, stderr: `${error instanceof Error ? error.message : String(error)}\n` };
664
931
  }
665
932
  }