@sayknow-cli/coding-agent 0.3.16 → 0.4.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 (1474) hide show
  1. package/CHANGELOG.md +52 -0
  2. package/package.json +127 -110
  3. package/scripts/build-sdk-package-smoke.ts +132 -0
  4. package/scripts/capture-notifications-settings-showcase.ts +435 -0
  5. package/scripts/compile-args.ts +5 -2
  6. package/scripts/g005-daemon-smoke.ts +4 -5
  7. package/scripts/g011-daemon-path-smoke.ts +5 -5
  8. package/scripts/generate-hotkeys-docs.ts +74 -0
  9. package/scripts/generate-sdk-adapter-parity-manifest.ts +163 -0
  10. package/scripts/generate-sdk-operation-inventory.ts +914 -0
  11. package/scripts/generate-telegram-baseline-manifest.ts +128 -0
  12. package/scripts/manifest-schema.ts +124 -0
  13. package/scripts/run-test-manifest.ts +153 -0
  14. package/scripts/run-threat-model-check.ts +217 -0
  15. package/scripts/verify-skc-sdk-canonicalization.ts +3647 -0
  16. package/scripts/verify-skc-sdk-rename.ts +90 -0
  17. package/src/append-only-mode.ts +1 -1
  18. package/src/async/job-manager.ts +455 -69
  19. package/src/cli/args.ts +43 -12
  20. package/src/cli/auth-gateway-cli.ts +2 -2
  21. package/src/cli/config-cli.ts +77 -3
  22. package/src/cli/daemon-cli.ts +63 -14
  23. package/src/cli/launch-disposition.ts +42 -0
  24. package/src/cli/list-models.ts +1 -1
  25. package/src/cli/notify-cli.ts +373 -283
  26. package/src/cli/session-picker.ts +20 -3
  27. package/src/cli/setup-cli.ts +1 -1
  28. package/src/cli/worktree-cli.ts +9 -287
  29. package/src/cli.ts +31 -11
  30. package/src/commands/config.ts +1 -1
  31. package/src/commands/daemon.ts +50 -6
  32. package/src/commands/gc.ts +11 -1
  33. package/src/commands/harness.ts +127 -142
  34. package/src/commands/launch.ts +11 -6
  35. package/src/commands/mcp-serve.ts +97 -13
  36. package/src/commands/mcp.ts +2 -2
  37. package/src/commands/notify.ts +44 -7
  38. package/src/commands/sdk.ts +453 -0
  39. package/src/commands/ultragoal.ts +4 -1
  40. package/src/commands/worktree.ts +10 -53
  41. package/src/commit/agentic/agent.ts +1 -0
  42. package/src/config/atomic-yaml-patch.ts +490 -0
  43. package/src/config/file-lock.ts +105 -43
  44. package/src/config/keybindings.ts +64 -20
  45. package/src/config/model-auth.ts +9 -0
  46. package/src/config/model-bindings-applier.ts +139 -0
  47. package/src/config/model-discovery-manager.ts +224 -0
  48. package/src/config/model-equivalence.ts +66 -0
  49. package/src/config/model-profile-activation.ts +233 -86
  50. package/src/config/model-profiles.ts +52 -49
  51. package/src/config/model-registry.ts +5 -4
  52. package/src/config/model-resolver.ts +487 -410
  53. package/src/config/model-selector-value.ts +50 -0
  54. package/src/config/models-config-schema.ts +17 -23
  55. package/src/config/settings-schema.ts +372 -21
  56. package/src/config/settings.ts +1120 -182
  57. package/src/coordinator-mcp/model-preset.ts +74 -20
  58. package/src/coordinator-mcp/policy.ts +76 -11
  59. package/src/coordinator-mcp/question-gate-codec.ts +274 -0
  60. package/src/coordinator-mcp/question-state.ts +778 -0
  61. package/src/coordinator-mcp/server.ts +3120 -3111
  62. package/src/daemon/builtin.ts +8 -5
  63. package/src/daemon/control-types.ts +1 -1
  64. package/src/daemon/runtime.ts +2 -2
  65. package/src/debug/index.ts +1 -1
  66. package/src/defaults/skc/skills/team/SKILL.md +27 -13
  67. package/src/defaults/skc/skills/ultragoal/SKILL.md +0 -2
  68. package/src/discovery/helpers.ts +1 -50
  69. package/src/discovery/mcp-json.ts +327 -20
  70. package/src/edit/index.ts +64 -0
  71. package/src/eval/js/shared/runtime.ts +1 -1
  72. package/src/eval/py/env.ts +26 -0
  73. package/src/eval/py/index.ts +2 -2
  74. package/src/eval/py/kernel.ts +5 -3
  75. package/src/export/html/template.generated.ts +1 -1
  76. package/src/export/html/template.js +52 -18
  77. package/src/extensibility/custom-tools/types.ts +1 -1
  78. package/src/extensibility/extensions/compact-handler.ts +3 -3
  79. package/src/extensibility/extensions/get-commands-handler.ts +2 -2
  80. package/src/extensibility/extensions/loader.ts +77 -5
  81. package/src/extensibility/extensions/runner.ts +124 -7
  82. package/src/extensibility/extensions/types.ts +215 -18
  83. package/src/extensibility/hooks/runner.ts +2 -2
  84. package/src/extensibility/hooks/types.ts +1 -1
  85. package/src/extensibility/plugins/marketplace/manager.ts +94 -10
  86. package/src/extensibility/runtime-skill-discovery.ts +33 -13
  87. package/src/extensibility/shared-events.ts +2 -0
  88. package/src/extensibility/skc-plugins/installer.ts +16 -16
  89. package/src/extensibility/slash-commands.ts +3 -3
  90. package/src/goals/continuation-timeout-guard.ts +79 -0
  91. package/src/goals/runtime.ts +7 -5
  92. package/src/goals/state.ts +18 -0
  93. package/src/harness-control-plane/lifecycle-reconciliation.ts +64 -0
  94. package/src/harness-control-plane/operate.ts +9 -9
  95. package/src/harness-control-plane/owner.ts +341 -41
  96. package/src/harness-control-plane/phase-rollup.ts +4 -7
  97. package/src/harness-control-plane/receipt-ingest.ts +5 -0
  98. package/src/harness-control-plane/receipt-spool.ts +51 -7
  99. package/src/harness-control-plane/receipts.ts +0 -1
  100. package/src/harness-control-plane/sdk-transport.ts +395 -0
  101. package/src/harness-control-plane/session-lease.ts +12 -130
  102. package/src/harness-control-plane/session-transport.ts +94 -0
  103. package/src/harness-control-plane/types.ts +1 -1
  104. package/src/hindsight/backend.ts +26 -27
  105. package/src/hindsight/client.ts +65 -2
  106. package/src/hindsight/state.ts +101 -32
  107. package/src/hooks/skill-state.ts +17 -11
  108. package/src/i18n/messages/en.ts +1 -0
  109. package/src/internal-urls/agent-protocol.ts +76 -5
  110. package/src/internal-urls/docs-index.generated.ts +44 -37
  111. package/src/internal-urls/local-protocol.ts +420 -18
  112. package/src/lsp/client.ts +43 -7
  113. package/src/lsp/config.ts +145 -26
  114. package/src/lsp/index.ts +7 -91
  115. package/src/lsp/lspmux.ts +39 -10
  116. package/src/lsp/path-trust.ts +81 -0
  117. package/src/main.ts +451 -236
  118. package/src/memories/index.ts +1 -0
  119. package/src/memories/storage.ts +6 -2
  120. package/src/modes/DESIGN.md +258 -0
  121. package/src/modes/acp/acp-agent.ts +1236 -2612
  122. package/src/modes/acp/acp-client-bridge.ts +2 -20
  123. package/src/modes/acp/acp-event-mapper.ts +18 -2
  124. package/src/modes/acp/acp-mode.ts +8 -36
  125. package/src/modes/acp/permission-mode.ts +25 -0
  126. package/src/modes/acp/startup-options.ts +6 -0
  127. package/src/modes/action-registry.ts +165 -0
  128. package/src/modes/bridge/bridge-mode.ts +6 -4
  129. package/src/modes/components/agent-dashboard.ts +37 -17
  130. package/src/modes/components/ansi-display-validator.ts +54 -0
  131. package/src/modes/components/chrome.ts +40 -0
  132. package/src/modes/components/command-palette.ts +168 -0
  133. package/src/modes/components/custom-editor.ts +105 -33
  134. package/src/modes/components/custom-provider-wizard.ts +77 -15
  135. package/src/modes/components/index.ts +2 -1
  136. package/src/modes/components/model-selector.ts +93 -35
  137. package/src/modes/components/notifications-settings-editor.ts +1403 -0
  138. package/src/modes/components/pet-capability.ts +115 -0
  139. package/src/modes/components/pet-selector.ts +15 -23
  140. package/src/modes/components/plan-preview-overlay.ts +295 -0
  141. package/src/modes/components/queue-mode-selector.ts +10 -27
  142. package/src/modes/components/queue-pane.ts +79 -0
  143. package/src/modes/components/read-tool-group.ts +13 -0
  144. package/src/modes/components/sayknow-pet-widget.ts +169 -20
  145. package/src/modes/components/session-observer-overlay.ts +213 -775
  146. package/src/modes/components/sessions-dashboard.ts +181 -0
  147. package/src/modes/components/settings-selector.ts +89 -12
  148. package/src/modes/components/show-images-selector.ts +10 -24
  149. package/src/modes/components/status-line/types.ts +1 -1
  150. package/src/modes/components/status-line.ts +1 -969
  151. package/src/modes/components/tasks-pane.ts +73 -0
  152. package/src/modes/components/theme-selector.ts +11 -31
  153. package/src/modes/components/tool-execution.ts +22 -0
  154. package/src/modes/components/tool-status-header.ts +1056 -0
  155. package/src/modes/components/tool-transcript-format.ts +393 -0
  156. package/src/modes/components/transcript-viewer-overlay.ts +446 -0
  157. package/src/modes/components/welcome.ts +4 -4
  158. package/src/modes/controllers/btw-controller.ts +1 -0
  159. package/src/modes/controllers/command-controller.ts +25 -17
  160. package/src/modes/controllers/event-controller.ts +14 -18
  161. package/src/modes/controllers/extension-ui-controller.ts +441 -37
  162. package/src/modes/controllers/goal-mode-controller.ts +493 -0
  163. package/src/modes/controllers/input-controller.ts +889 -263
  164. package/src/modes/controllers/mode-gate.ts +24 -0
  165. package/src/modes/controllers/plan-mode-controller.ts +519 -0
  166. package/src/modes/controllers/runtime-mcp-command-controller.ts +3 -0
  167. package/src/modes/controllers/selector-controller.ts +957 -54
  168. package/src/modes/controllers/stt-controller.ts +125 -0
  169. package/src/modes/index.ts +0 -22
  170. package/src/modes/interactive-mode.ts +376 -1130
  171. package/src/modes/jobs-observer.ts +3 -0
  172. package/src/modes/prompt-action-autocomplete.ts +7 -0
  173. package/src/modes/rpc/rpc-mode.ts +3 -1
  174. package/src/modes/runtime-init.ts +320 -6
  175. package/src/modes/shared/agent-wire/approval-gate.ts +9 -11
  176. package/src/modes/shared/agent-wire/command-dispatch.ts +3 -1
  177. package/src/modes/shared/agent-wire/deep-interview-gate.ts +65 -111
  178. package/src/modes/shared/agent-wire/event-contract.ts +7 -8
  179. package/src/modes/shared/agent-wire/event-envelope.ts +9 -17
  180. package/src/modes/shared/agent-wire/event-observation.ts +16 -7
  181. package/src/modes/shared/agent-wire/workflow-gate-broker.ts +1331 -89
  182. package/src/modes/shared/agent-wire/workflow-gate-schema.ts +19 -17
  183. package/src/modes/shared/agent-wire/workflow-gate-types.ts +407 -0
  184. package/src/modes/tasks-aggregator.ts +199 -0
  185. package/src/modes/transcript-item-registry.ts +229 -0
  186. package/src/modes/types.ts +63 -21
  187. package/src/modes/utils/ui-helpers.ts +17 -9
  188. package/src/notifications/index.ts +8 -2
  189. package/src/plan-mode/approved-plan.ts +3 -1
  190. package/src/prompts/agent-fragments/ralplan-persistence.md +6 -0
  191. package/src/prompts/agent-fragments/restricted-bash.md +1 -0
  192. package/src/prompts/agents/architect.md +3 -8
  193. package/src/prompts/agents/critic.md +3 -8
  194. package/src/prompts/agents/executor.md +3 -0
  195. package/src/prompts/agents/planner.md +4 -12
  196. package/src/prompts/system/custom-system-prompt.md +2 -24
  197. package/src/prompts/system/plan-mode-approved.md +8 -0
  198. package/src/prompts/system/system-prompt.md +18 -94
  199. package/src/prompts/tools/bash.md +4 -4
  200. package/src/prompts/tools/browser.md +15 -52
  201. package/src/prompts/tools/find.md +2 -2
  202. package/src/prompts/tools/hashline.md +13 -55
  203. package/src/prompts/tools/lsp.md +3 -3
  204. package/src/prompts/tools/read.md +3 -6
  205. package/src/prompts/tools/search-tool-bm25.md +0 -2
  206. package/src/prompts/tools/search.md +2 -4
  207. package/src/prompts/tools/skill-discovery.md +1 -2
  208. package/src/prompts/tools/task.md +1 -1
  209. package/src/runtime-mcp/client.ts +94 -19
  210. package/src/runtime-mcp/config.ts +27 -15
  211. package/src/runtime-mcp/discoverable-tool-metadata.ts +16 -13
  212. package/src/runtime-mcp/manager.ts +359 -106
  213. package/src/runtime-mcp/oauth-discovery.ts +116 -26
  214. package/src/runtime-mcp/oauth-flow.ts +42 -12
  215. package/src/runtime-mcp/transports/http.ts +49 -19
  216. package/src/runtime-mcp/transports/stdio.ts +47 -28
  217. package/src/runtime-mcp/types.ts +10 -0
  218. package/src/sdk/acp/adapter.ts +418 -0
  219. package/src/sdk/acp/index.ts +2 -0
  220. package/src/sdk/broker/broker.ts +877 -0
  221. package/src/sdk/broker/discovery.ts +238 -0
  222. package/src/sdk/broker/ensure.ts +393 -0
  223. package/src/sdk/broker/identity.ts +42 -0
  224. package/src/sdk/broker/index.ts +8 -0
  225. package/src/sdk/broker/internal-source-marker-2178.txt +1 -0
  226. package/src/sdk/broker/internal-source.bunfig.toml +1 -0
  227. package/src/sdk/broker/internal.ts +10 -0
  228. package/src/sdk/broker/lifecycle-codec.ts +11 -0
  229. package/src/sdk/broker/lifecycle-ledger.ts +583 -0
  230. package/src/sdk/broker/lifecycle.ts +3413 -0
  231. package/src/sdk/broker/process-incarnation.ts +151 -0
  232. package/src/sdk/broker/runtime.ts +164 -0
  233. package/src/sdk/broker/session-index.ts +678 -0
  234. package/src/sdk/broker/state-version.ts +47 -0
  235. package/src/sdk/broker/transport.ts +125 -0
  236. package/src/sdk/bus/attachment-registry.ts +23 -0
  237. package/src/sdk/bus/chat-adapters.ts +147 -0
  238. package/src/sdk/bus/chat-command-policy.ts +107 -0
  239. package/src/sdk/bus/chat-daemon-cli.ts +278 -0
  240. package/src/sdk/bus/chat-daemon-control.ts +1101 -0
  241. package/src/sdk/bus/chat-daemon-runtime.ts +527 -0
  242. package/src/sdk/bus/chat-effect-journal.ts +363 -0
  243. package/src/sdk/bus/config-commands.ts +192 -0
  244. package/src/sdk/bus/config.ts +568 -0
  245. package/src/sdk/bus/conversation-store.ts +367 -0
  246. package/src/sdk/bus/daemon-paths.ts +34 -0
  247. package/src/sdk/bus/discord-conversation.ts +85 -0
  248. package/src/sdk/bus/discord-daemon.ts +2292 -0
  249. package/src/sdk/bus/discord-live-provider.ts +521 -0
  250. package/src/sdk/bus/discord-provider.ts +56 -0
  251. package/src/sdk/bus/engine.ts +100 -0
  252. package/src/sdk/bus/helpers.ts +135 -0
  253. package/src/sdk/bus/html-format.ts +518 -0
  254. package/src/sdk/bus/index.ts +4961 -0
  255. package/src/sdk/bus/lifecycle-commands.ts +291 -0
  256. package/src/sdk/bus/lifecycle-control-runtime.ts +1409 -0
  257. package/src/sdk/bus/lifecycle-orchestrator.ts +458 -0
  258. package/src/sdk/bus/managed-daemon.ts +163 -0
  259. package/src/sdk/bus/native-runtime-compatibility.ts +42 -0
  260. package/src/sdk/bus/natives-augment.d.ts +63 -0
  261. package/src/sdk/bus/notification-orchestration.ts +535 -0
  262. package/src/sdk/bus/notification-service.ts +1174 -0
  263. package/src/sdk/bus/operator-runtime.ts +171 -0
  264. package/src/sdk/bus/rate-limit-pool.ts +276 -0
  265. package/src/sdk/bus/recent-activity.ts +279 -0
  266. package/src/sdk/bus/reply-sent-store.ts +134 -0
  267. package/src/sdk/bus/rich-document.ts +258 -0
  268. package/src/sdk/bus/rich-draft.ts +107 -0
  269. package/src/sdk/bus/rich-render.ts +135 -0
  270. package/src/sdk/bus/session-control.ts +439 -0
  271. package/src/sdk/bus/slack-conversation.ts +74 -0
  272. package/src/sdk/bus/slack-daemon.ts +2144 -0
  273. package/src/sdk/bus/slack-live-provider.ts +380 -0
  274. package/src/sdk/bus/slack-provider.ts +76 -0
  275. package/src/sdk/bus/telegram-cli.ts +194 -0
  276. package/src/sdk/bus/telegram-daemon-cli.ts +292 -0
  277. package/src/sdk/bus/telegram-daemon-contract.ts +27 -0
  278. package/src/sdk/bus/telegram-daemon-control.ts +642 -0
  279. package/src/sdk/bus/telegram-daemon.ts +6675 -0
  280. package/src/sdk/bus/telegram-reference.ts +436 -0
  281. package/src/sdk/bus/telegram-setup.ts +663 -0
  282. package/src/sdk/bus/threaded-inbound.ts +141 -0
  283. package/src/sdk/bus/threaded-render.ts +294 -0
  284. package/src/sdk/bus/topic-registry.ts +364 -0
  285. package/src/sdk/cli/index.ts +1 -0
  286. package/src/sdk/cli/session-cli.ts +275 -0
  287. package/src/sdk/client/client.ts +1 -0
  288. package/src/sdk/client/discovery.ts +108 -0
  289. package/src/sdk/client/index.ts +2 -0
  290. package/src/sdk/host/control/dispatch.ts +388 -0
  291. package/src/sdk/host/control/index.ts +10 -0
  292. package/src/sdk/host/control/operations.ts +68 -0
  293. package/src/sdk/host/events.ts +91 -0
  294. package/src/sdk/host/host.ts +338 -0
  295. package/src/sdk/host/index.ts +4 -0
  296. package/src/sdk/host/query/cursor.ts +189 -0
  297. package/src/sdk/host/query/handlers.ts +531 -0
  298. package/src/sdk/host/query/index.ts +3 -0
  299. package/src/sdk/host/query/revision-store.ts +1149 -0
  300. package/src/sdk/host/reverse-leases.ts +325 -0
  301. package/src/sdk/host/types.ts +29 -0
  302. package/src/sdk/index.ts +14 -0
  303. package/src/sdk/lifecycle-session.ts +39 -0
  304. package/src/sdk/mcp/index.ts +1 -0
  305. package/src/sdk/mcp/server.ts +332 -0
  306. package/src/sdk/models.ts +168 -0
  307. package/src/sdk/protocol/adapter-validation.ts +48 -0
  308. package/src/sdk/protocol/operation-inventory.generated.json +4719 -0
  309. package/src/sdk/protocol/operation-registry.ts +312 -0
  310. package/src/sdk/session-directory.ts +141 -0
  311. package/src/sdk/session.ts +2869 -0
  312. package/src/sdk/startup-capability.ts +189 -0
  313. package/src/secrets/index.ts +53 -10
  314. package/src/secrets/obfuscator.ts +21 -18
  315. package/src/secrets/regex.ts +2 -0
  316. package/src/session/agent-session.ts +5602 -2138
  317. package/src/session/agent-storage.ts +18 -0
  318. package/src/session/artifacts.ts +188 -23
  319. package/src/session/cache-economics.ts +25 -8
  320. package/src/session/context-estimation.ts +7 -2
  321. package/src/session/default-model-selection.ts +93 -0
  322. package/src/session/fallback-chain-controller.ts +186 -0
  323. package/src/session/internal/managed-session-scope.ts +2402 -0
  324. package/src/session/internal/managed-session-storage.ts +1559 -0
  325. package/src/session/messages.ts +91 -2
  326. package/src/session/session-manager-internal.ts +33 -0
  327. package/src/session/session-manager.ts +2578 -392
  328. package/src/session/session-storage.ts +550 -40
  329. package/src/session/streaming-output.ts +6 -0
  330. package/src/session/volatile-context-pruning.ts +78 -0
  331. package/src/session/yield-queue.ts +20 -0
  332. package/src/setup/credential-auto-import.ts +291 -35
  333. package/src/setup/hermes/templates/operator-instructions.v1.md +4 -6
  334. package/src/setup/provider-onboarding.ts +36 -61
  335. package/src/setup/provider-presets.json +5 -0
  336. package/src/skc-runtime/deep-interview-recorder.ts +70 -3
  337. package/src/skc-runtime/deep-interview-state.ts +441 -5
  338. package/src/skc-runtime/gc-render.ts +19 -1
  339. package/src/skc-runtime/gc-runtime.ts +68 -3
  340. package/src/skc-runtime/goal-mode-request.ts +55 -8
  341. package/src/skc-runtime/launch-worktree.ts +5 -5
  342. package/src/skc-runtime/linux-proc.ts +71 -0
  343. package/src/skc-runtime/managed-owner-admission.ts +352 -0
  344. package/src/skc-runtime/managed-owner-supervisor.ts +162 -0
  345. package/src/skc-runtime/psmux-detect.ts +82 -4
  346. package/src/skc-runtime/ralplan-runtime.ts +74 -90
  347. package/src/skc-runtime/session-resolution.ts +18 -3
  348. package/src/skc-runtime/session-state-sidecar.ts +47 -138
  349. package/src/skc-runtime/state-argv.ts +292 -0
  350. package/src/skc-runtime/state-migrations.ts +1 -1
  351. package/src/skc-runtime/state-runtime.ts +387 -451
  352. package/src/skc-runtime/state-writer.ts +36 -40
  353. package/src/skc-runtime/team-launch.ts +319 -0
  354. package/src/skc-runtime/team-notify.ts +326 -0
  355. package/src/skc-runtime/team-runtime.ts +8 -2
  356. package/src/skc-runtime/team-store.ts +828 -0
  357. package/src/skc-runtime/team-workers.ts +962 -0
  358. package/src/skc-runtime/tmux-owner-isolation-cli.ts +55 -28
  359. package/src/skc-runtime/tmux-owner-isolation.ts +136 -11
  360. package/src/skc-runtime/tmux-sessions.ts +23 -34
  361. package/src/skc-runtime/ultragoal-change-set.ts +172 -0
  362. package/src/skc-runtime/ultragoal-evidence.ts +874 -0
  363. package/src/skc-runtime/ultragoal-guard.ts +136 -18
  364. package/src/skc-runtime/ultragoal-owner-loss-recovery.ts +328 -0
  365. package/src/skc-runtime/ultragoal-pipeline.ts +306 -0
  366. package/src/skc-runtime/ultragoal-receipt-freshness.ts +102 -1
  367. package/src/skc-runtime/ultragoal-runtime.ts +325 -1322
  368. package/src/skc-runtime/windows-powershell-command.ts +58 -0
  369. package/src/skc-runtime/workflow-cli-common.ts +30 -0
  370. package/src/skc-runtime/workflow-manifest.generated.json +58 -0
  371. package/src/skc-runtime/workflow-manifest.ts +18 -0
  372. package/src/skill-state/active-state.ts +3 -13
  373. package/src/skill-state/workflow-mutation-guard.ts +661 -0
  374. package/src/skill-state/workflow-state-contract.ts +6 -41
  375. package/src/slash-commands/builtin-registry.ts +115 -41
  376. package/src/system-prompt.ts +37 -44
  377. package/src/task/agents.ts +19 -1
  378. package/src/task/executor.ts +223 -45
  379. package/src/task/index.ts +124 -56
  380. package/src/thinking.ts +21 -6
  381. package/src/tool-discovery/tool-index.ts +20 -134
  382. package/src/tools/ask-answer-registry.ts +16 -2
  383. package/src/tools/ast-edit.ts +1 -1
  384. package/src/tools/bash-allowed-prefixes.ts +79 -29
  385. package/src/tools/bash-skill-urls.ts +14 -3
  386. package/src/tools/bash.ts +40 -2
  387. package/src/tools/browser/STEALTH-THIRD-PARTY-NOTICES.md +26 -0
  388. package/src/tools/browser/benchmark/detector-report.ts +157 -0
  389. package/src/tools/browser/benchmark/run-suite.ts +39 -0
  390. package/src/tools/browser/dead-tab-recovery.ts +78 -0
  391. package/src/tools/browser/launch.ts +127 -20
  392. package/src/tools/browser/profile-discovery.ts +63 -0
  393. package/src/tools/browser/profile-posture.ts +59 -0
  394. package/src/tools/browser/profile-reuse.ts +102 -0
  395. package/src/tools/browser/profile-warmup.ts +109 -0
  396. package/src/tools/browser/readable.ts +1 -1
  397. package/src/tools/browser/registry.ts +87 -11
  398. package/src/tools/browser/screenshot-format.ts +34 -0
  399. package/src/tools/browser/tab-protocol.ts +4 -0
  400. package/src/tools/browser/tab-supervisor.ts +392 -142
  401. package/src/tools/browser/tab-worker-entry.ts +33 -14
  402. package/src/tools/browser/tab-worker-path-resolver.ts +67 -0
  403. package/src/tools/browser/tab-worker-smoke.ts +87 -0
  404. package/src/tools/browser/tab-worker.ts +8 -6
  405. package/src/tools/browser.ts +6 -0
  406. package/src/tools/computer.ts +10 -3
  407. package/src/tools/cron.ts +30 -16
  408. package/src/tools/fetch.ts +11 -4
  409. package/src/tools/index.ts +88 -32
  410. package/src/tools/output-meta.ts +19 -7
  411. package/src/tools/path-utils.ts +42 -35
  412. package/src/tools/plan-mode-guard.ts +1 -0
  413. package/src/tools/puppeteer/14_stealth_permissions.txt +57 -0
  414. package/src/tools/puppeteer/15_stealth_webrtc.txt +60 -0
  415. package/src/tools/read.ts +226 -65
  416. package/src/tools/resource-gc.ts +125 -36
  417. package/src/tools/search-tool-bm25.ts +11 -74
  418. package/src/tools/sqlite-reader.ts +3 -2
  419. package/src/tools/subagent-render.ts +19 -8
  420. package/src/tools/subagent.ts +129 -34
  421. package/src/tools/telegram-send.ts +2 -2
  422. package/src/utils/event-bus.ts +9 -4
  423. package/src/utils/file-mentions.ts +4 -4
  424. package/src/utils/image-loading.ts +85 -34
  425. package/src/utils/image-resize.ts +16 -9
  426. package/src/utils/pasted-image-loading.ts +514 -0
  427. package/src/utils/pasted-image-path.ts +223 -98
  428. package/src/web/scrapers/html-to-markdown.ts +68 -0
  429. package/src/web/scrapers/readthedocs.ts +1 -1
  430. package/src/web/scrapers/types.ts +1 -68
  431. package/src/web/search/index.ts +3 -3
  432. package/src/web/search/providers/openai-compatible.ts +76 -23
  433. package/dist/types/append-only-mode.d.ts +0 -31
  434. package/dist/types/async/index.d.ts +0 -2
  435. package/dist/types/async/job-manager.d.ts +0 -328
  436. package/dist/types/async/support.d.ts +0 -2
  437. package/dist/types/autoresearch/dashboard.d.ts +0 -4
  438. package/dist/types/autoresearch/git.d.ts +0 -36
  439. package/dist/types/autoresearch/helpers.d.ts +0 -24
  440. package/dist/types/autoresearch/index.d.ts +0 -2
  441. package/dist/types/autoresearch/state.d.ts +0 -17
  442. package/dist/types/autoresearch/storage.d.ts +0 -142
  443. package/dist/types/autoresearch/tools/init-experiment.d.ts +0 -31
  444. package/dist/types/autoresearch/tools/log-experiment.d.ts +0 -23
  445. package/dist/types/autoresearch/tools/run-experiment.d.ts +0 -8
  446. package/dist/types/autoresearch/tools/update-notes.d.ts +0 -12
  447. package/dist/types/autoresearch/types.d.ts +0 -154
  448. package/dist/types/build-metadata.d.ts +0 -7
  449. package/dist/types/capability/context-file.d.ts +0 -17
  450. package/dist/types/capability/extension-module.d.ts +0 -15
  451. package/dist/types/capability/extension.d.ts +0 -28
  452. package/dist/types/capability/fs.d.ts +0 -20
  453. package/dist/types/capability/hook.d.ts +0 -19
  454. package/dist/types/capability/index.d.ts +0 -80
  455. package/dist/types/capability/instruction.d.ts +0 -17
  456. package/dist/types/capability/mcp.d.ts +0 -49
  457. package/dist/types/capability/prompt.d.ts +0 -15
  458. package/dist/types/capability/rule.d.ts +0 -69
  459. package/dist/types/capability/settings.d.ts +0 -15
  460. package/dist/types/capability/skill.d.ts +0 -36
  461. package/dist/types/capability/slash-command.d.ts +0 -17
  462. package/dist/types/capability/ssh.d.ts +0 -23
  463. package/dist/types/capability/system-prompt.d.ts +0 -15
  464. package/dist/types/capability/tool.d.ts +0 -19
  465. package/dist/types/capability/types.d.ts +0 -154
  466. package/dist/types/cli/agents-cli.d.ts +0 -12
  467. package/dist/types/cli/args.d.ts +0 -57
  468. package/dist/types/cli/auth-broker-cli.d.ts +0 -25
  469. package/dist/types/cli/auth-gateway-cli.d.ts +0 -18
  470. package/dist/types/cli/classify-install-target.d.ts +0 -8
  471. package/dist/types/cli/commands/init-xdg.d.ts +0 -1
  472. package/dist/types/cli/completion-cli.d.ts +0 -41
  473. package/dist/types/cli/config-cli.d.ts +0 -23
  474. package/dist/types/cli/daemon-cli.d.ts +0 -27
  475. package/dist/types/cli/fast-help.d.ts +0 -1
  476. package/dist/types/cli/file-processor.d.ts +0 -11
  477. package/dist/types/cli/fixture-report.d.ts +0 -20
  478. package/dist/types/cli/fixture-report.test.d.ts +0 -1
  479. package/dist/types/cli/grep-cli.d.ts +0 -17
  480. package/dist/types/cli/initial-message.d.ts +0 -17
  481. package/dist/types/cli/list-models.d.ts +0 -36
  482. package/dist/types/cli/local-provider-smoke.d.ts +0 -59
  483. package/dist/types/cli/malloc-env-guard.d.ts +0 -65
  484. package/dist/types/cli/malloc-env-guard.test.d.ts +0 -1
  485. package/dist/types/cli/mcp-cli.d.ts +0 -25
  486. package/dist/types/cli/migrate-cli.d.ts +0 -20
  487. package/dist/types/cli/nofile-limit.d.ts +0 -11
  488. package/dist/types/cli/notify-cli.d.ts +0 -39
  489. package/dist/types/cli/plugin-cli.d.ts +0 -34
  490. package/dist/types/cli/read-cli.d.ts +0 -4
  491. package/dist/types/cli/session-picker.d.ts +0 -4
  492. package/dist/types/cli/setup-cli.d.ts +0 -73
  493. package/dist/types/cli/shell-cli.d.ts +0 -8
  494. package/dist/types/cli/skills-cli.d.ts +0 -9
  495. package/dist/types/cli/ssh-cli.d.ts +0 -21
  496. package/dist/types/cli/stats-cli.d.ts +0 -17
  497. package/dist/types/cli/telegram-cli.d.ts +0 -13
  498. package/dist/types/cli/update-cli.d.ts +0 -108
  499. package/dist/types/cli/web-search-cli.d.ts +0 -32
  500. package/dist/types/cli/worktree-cli.d.ts +0 -26
  501. package/dist/types/cli.d.ts +0 -140
  502. package/dist/types/commands/acp.d.ts +0 -12
  503. package/dist/types/commands/agents.d.ts +0 -34
  504. package/dist/types/commands/auth-broker.d.ts +0 -54
  505. package/dist/types/commands/auth-gateway.d.ts +0 -32
  506. package/dist/types/commands/codex-native-hook.d.ts +0 -6
  507. package/dist/types/commands/commit.d.ts +0 -27
  508. package/dist/types/commands/completion.d.ts +0 -29
  509. package/dist/types/commands/config.d.ts +0 -33
  510. package/dist/types/commands/contribution-prep.d.ts +0 -18
  511. package/dist/types/commands/coordinator.d.ts +0 -19
  512. package/dist/types/commands/daemon.d.ts +0 -45
  513. package/dist/types/commands/deep-interview.d.ts +0 -54
  514. package/dist/types/commands/gc.d.ts +0 -26
  515. package/dist/types/commands/grep.d.ts +0 -42
  516. package/dist/types/commands/harness.d.ts +0 -43
  517. package/dist/types/commands/launch.d.ts +0 -131
  518. package/dist/types/commands/local-provider.d.ts +0 -34
  519. package/dist/types/commands/mcp-serve.d.ts +0 -24
  520. package/dist/types/commands/mcp.d.ts +0 -70
  521. package/dist/types/commands/migrate.d.ts +0 -33
  522. package/dist/types/commands/notify.d.ts +0 -47
  523. package/dist/types/commands/plugin.d.ts +0 -58
  524. package/dist/types/commands/ralplan.d.ts +0 -7
  525. package/dist/types/commands/read.d.ts +0 -15
  526. package/dist/types/commands/rlm.d.ts +0 -10
  527. package/dist/types/commands/session.d.ts +0 -30
  528. package/dist/types/commands/setup.d.ts +0 -105
  529. package/dist/types/commands/shell.d.ts +0 -21
  530. package/dist/types/commands/skills.d.ts +0 -26
  531. package/dist/types/commands/ssh.d.ts +0 -48
  532. package/dist/types/commands/state.d.ts +0 -7
  533. package/dist/types/commands/stats.d.ts +0 -25
  534. package/dist/types/commands/team.d.ts +0 -24
  535. package/dist/types/commands/telegram.d.ts +0 -22
  536. package/dist/types/commands/ultragoal.d.ts +0 -8
  537. package/dist/types/commands/update.d.ts +0 -20
  538. package/dist/types/commands/web-search.d.ts +0 -87
  539. package/dist/types/commands/worktree.d.ts +0 -34
  540. package/dist/types/commit/agentic/agent.d.ts +0 -31
  541. package/dist/types/commit/agentic/fallback.d.ts +0 -5
  542. package/dist/types/commit/agentic/index.d.ts +0 -2
  543. package/dist/types/commit/agentic/state.d.ts +0 -58
  544. package/dist/types/commit/agentic/tools/analyze-file.d.ts +0 -19
  545. package/dist/types/commit/agentic/tools/git-file-diff.d.ts +0 -10
  546. package/dist/types/commit/agentic/tools/git-hunk.d.ts +0 -9
  547. package/dist/types/commit/agentic/tools/git-overview.d.ts +0 -9
  548. package/dist/types/commit/agentic/tools/index.d.ts +0 -16
  549. package/dist/types/commit/agentic/tools/propose-changelog.d.ts +0 -28
  550. package/dist/types/commit/agentic/tools/propose-commit.d.ts +0 -36
  551. package/dist/types/commit/agentic/tools/recent-commits.d.ts +0 -7
  552. package/dist/types/commit/agentic/tools/schemas.d.ts +0 -27
  553. package/dist/types/commit/agentic/tools/split-commit.d.ts +0 -53
  554. package/dist/types/commit/agentic/topo-sort.d.ts +0 -4
  555. package/dist/types/commit/agentic/trivial.d.ts +0 -7
  556. package/dist/types/commit/agentic/validation.d.ts +0 -20
  557. package/dist/types/commit/analysis/conventional.d.ts +0 -22
  558. package/dist/types/commit/analysis/index.d.ts +0 -4
  559. package/dist/types/commit/analysis/scope.d.ts +0 -6
  560. package/dist/types/commit/analysis/summary.d.ts +0 -19
  561. package/dist/types/commit/analysis/validation.d.ts +0 -8
  562. package/dist/types/commit/changelog/detect.d.ts +0 -2
  563. package/dist/types/commit/changelog/generate.d.ts +0 -30
  564. package/dist/types/commit/changelog/index.d.ts +0 -30
  565. package/dist/types/commit/changelog/parse.d.ts +0 -2
  566. package/dist/types/commit/cli.d.ts +0 -3
  567. package/dist/types/commit/git/diff.d.ts +0 -5
  568. package/dist/types/commit/index.d.ts +0 -4
  569. package/dist/types/commit/map-reduce/index.d.ts +0 -28
  570. package/dist/types/commit/map-reduce/map-phase.d.ts +0 -17
  571. package/dist/types/commit/map-reduce/reduce-phase.d.ts +0 -13
  572. package/dist/types/commit/map-reduce/utils.d.ts +0 -2
  573. package/dist/types/commit/message.d.ts +0 -2
  574. package/dist/types/commit/model-selection.d.ts +0 -15
  575. package/dist/types/commit/pipeline.d.ts +0 -5
  576. package/dist/types/commit/shared-llm.d.ts +0 -54
  577. package/dist/types/commit/types.d.ts +0 -78
  578. package/dist/types/commit/utils/exclusions.d.ts +0 -4
  579. package/dist/types/commit/utils.d.ts +0 -20
  580. package/dist/types/config/config-file.d.ts +0 -58
  581. package/dist/types/config/file-lock-gc.d.ts +0 -5
  582. package/dist/types/config/file-lock.d.ts +0 -36
  583. package/dist/types/config/keybindings.d.ts +0 -364
  584. package/dist/types/config/model-equivalence.d.ts +0 -24
  585. package/dist/types/config/model-profile-activation.d.ts +0 -65
  586. package/dist/types/config/model-profiles.d.ts +0 -39
  587. package/dist/types/config/model-registry.d.ts +0 -473
  588. package/dist/types/config/model-resolver.d.ts +0 -217
  589. package/dist/types/config/models-config-schema.d.ts +0 -700
  590. package/dist/types/config/prompt-templates.d.ts +0 -32
  591. package/dist/types/config/resolve-config-value.d.ts +0 -17
  592. package/dist/types/config/settings-schema.d.ts +0 -4223
  593. package/dist/types/config/settings.d.ts +0 -158
  594. package/dist/types/config/skill-settings-defaults.d.ts +0 -14
  595. package/dist/types/config/telegram-autostart.d.ts +0 -14
  596. package/dist/types/config/telegram-env-bridge.d.ts +0 -18
  597. package/dist/types/config.d.ts +0 -66
  598. package/dist/types/coordinator/contract.d.ts +0 -4
  599. package/dist/types/coordinator-mcp/model-preset.d.ts +0 -45
  600. package/dist/types/coordinator-mcp/policy.d.ts +0 -27
  601. package/dist/types/coordinator-mcp/safety.d.ts +0 -26
  602. package/dist/types/coordinator-mcp/server.d.ts +0 -139
  603. package/dist/types/coordinator-mcp/session-reaper.d.ts +0 -53
  604. package/dist/types/cursor.d.ts +0 -24
  605. package/dist/types/daemon/builtin.d.ts +0 -20
  606. package/dist/types/daemon/control-types.d.ts +0 -67
  607. package/dist/types/daemon/operator-contract.d.ts +0 -47
  608. package/dist/types/daemon/runtime.d.ts +0 -25
  609. package/dist/types/dap/client.d.ts +0 -39
  610. package/dist/types/dap/config.d.ts +0 -6
  611. package/dist/types/dap/index.d.ts +0 -4
  612. package/dist/types/dap/session.d.ts +0 -108
  613. package/dist/types/dap/types.d.ts +0 -524
  614. package/dist/types/debug/crash-diagnostics.d.ts +0 -45
  615. package/dist/types/debug/index.d.ts +0 -15
  616. package/dist/types/debug/log-formatting.d.ts +0 -4
  617. package/dist/types/debug/log-viewer.d.ts +0 -68
  618. package/dist/types/debug/profiler.d.ts +0 -24
  619. package/dist/types/debug/raw-sse-buffer.d.ts +0 -44
  620. package/dist/types/debug/raw-sse.d.ts +0 -16
  621. package/dist/types/debug/report-bundle.d.ts +0 -55
  622. package/dist/types/debug/runtime-gauges.d.ts +0 -6
  623. package/dist/types/debug/system-info.d.ts +0 -26
  624. package/dist/types/deep-interview/plaintext-gate-guard.d.ts +0 -11
  625. package/dist/types/deep-interview/render-middleware.d.ts +0 -6
  626. package/dist/types/defaults/skc/extensions/grok-build/index.d.ts +0 -1
  627. package/dist/types/defaults/skc/extensions/grok-cli-vendor/src/index.d.ts +0 -1
  628. package/dist/types/defaults/skc/extensions/grok-cli-vendor/src/models/catalog.d.ts +0 -29
  629. package/dist/types/defaults/skc/extensions/grok-cli-vendor/src/payload/sanitize.d.ts +0 -27
  630. package/dist/types/defaults/skc/extensions/grok-cli-vendor/src/provider/billing.d.ts +0 -8
  631. package/dist/types/defaults/skc/extensions/grok-cli-vendor/src/provider/register.d.ts +0 -5
  632. package/dist/types/defaults/skc/extensions/grok-cli-vendor/src/provider/stream.d.ts +0 -10
  633. package/dist/types/defaults/skc/extensions/grok-cli-vendor/src/provider/usage.d.ts +0 -2
  634. package/dist/types/defaults/skc/extensions/grok-cli-vendor/src/shared/base-url.d.ts +0 -2
  635. package/dist/types/defaults/skc/extensions/grok-cli-vendor/src/shared/errors.d.ts +0 -38
  636. package/dist/types/defaults/skc-defaults.d.ts +0 -64
  637. package/dist/types/defaults/skc-grok-cli.d.ts +0 -5
  638. package/dist/types/discovery/agents-md.d.ts +0 -1
  639. package/dist/types/discovery/agents.d.ts +0 -12
  640. package/dist/types/discovery/builtin.d.ts +0 -1
  641. package/dist/types/discovery/claude-plugins.d.ts +0 -1
  642. package/dist/types/discovery/claude.d.ts +0 -1
  643. package/dist/types/discovery/cline.d.ts +0 -1
  644. package/dist/types/discovery/codex.d.ts +0 -1
  645. package/dist/types/discovery/cursor.d.ts +0 -19
  646. package/dist/types/discovery/gemini.d.ts +0 -1
  647. package/dist/types/discovery/github.d.ts +0 -1
  648. package/dist/types/discovery/helpers.d.ts +0 -271
  649. package/dist/types/discovery/index.d.ts +0 -48
  650. package/dist/types/discovery/mcp-json.d.ts +0 -1
  651. package/dist/types/discovery/opencode.d.ts +0 -1
  652. package/dist/types/discovery/plugin-dir-roots.d.ts +0 -15
  653. package/dist/types/discovery/ssh.d.ts +0 -1
  654. package/dist/types/discovery/substitute-plugin-root.d.ts +0 -1
  655. package/dist/types/discovery/vscode.d.ts +0 -1
  656. package/dist/types/discovery/windsurf.d.ts +0 -15
  657. package/dist/types/edit/apply-patch/index.d.ts +0 -35
  658. package/dist/types/edit/apply-patch/parser.d.ts +0 -34
  659. package/dist/types/edit/diff.d.ts +0 -75
  660. package/dist/types/edit/file-read-cache.d.ts +0 -25
  661. package/dist/types/edit/index.d.ts +0 -58
  662. package/dist/types/edit/modes/apply-patch.d.ts +0 -24
  663. package/dist/types/edit/modes/patch.d.ts +0 -99
  664. package/dist/types/edit/modes/replace.d.ts +0 -149
  665. package/dist/types/edit/normalize.d.ts +0 -43
  666. package/dist/types/edit/notebook.d.ts +0 -26
  667. package/dist/types/edit/read-file.d.ts +0 -8
  668. package/dist/types/edit/renderer.d.ts +0 -110
  669. package/dist/types/edit/streaming.d.ts +0 -66
  670. package/dist/types/eval/backend.d.ts +0 -40
  671. package/dist/types/eval/index.d.ts +0 -4
  672. package/dist/types/eval/js/context-manager.d.ts +0 -27
  673. package/dist/types/eval/js/executor.d.ts +0 -29
  674. package/dist/types/eval/js/index.d.ts +0 -10
  675. package/dist/types/eval/js/shared/helpers.d.ts +0 -38
  676. package/dist/types/eval/js/shared/indirect-eval.d.ts +0 -14
  677. package/dist/types/eval/js/shared/prelude.d.ts +0 -1
  678. package/dist/types/eval/js/shared/rewrite-imports.d.ts +0 -6
  679. package/dist/types/eval/js/shared/runtime.d.ts +0 -47
  680. package/dist/types/eval/js/shared/types.d.ts +0 -24
  681. package/dist/types/eval/js/tool-bridge.d.ts +0 -18
  682. package/dist/types/eval/js/worker-core.d.ts +0 -5
  683. package/dist/types/eval/js/worker-entry.d.ts +0 -1
  684. package/dist/types/eval/js/worker-protocol.d.ts +0 -77
  685. package/dist/types/eval/py/display.d.ts +0 -25
  686. package/dist/types/eval/py/executor.d.ts +0 -88
  687. package/dist/types/eval/py/index.d.ts +0 -10
  688. package/dist/types/eval/py/kernel.d.ts +0 -65
  689. package/dist/types/eval/py/prelude.d.ts +0 -1
  690. package/dist/types/eval/py/runtime.d.ts +0 -29
  691. package/dist/types/eval/py/tool-bridge.d.ts +0 -20
  692. package/dist/types/eval/types.d.ts +0 -52
  693. package/dist/types/exa/factory.d.ts +0 -13
  694. package/dist/types/exa/index.d.ts +0 -20
  695. package/dist/types/exa/mcp-client.d.ts +0 -45
  696. package/dist/types/exa/render.d.ts +0 -19
  697. package/dist/types/exa/researcher.d.ts +0 -9
  698. package/dist/types/exa/search.d.ts +0 -9
  699. package/dist/types/exa/types.d.ts +0 -155
  700. package/dist/types/exa/websets.d.ts +0 -9
  701. package/dist/types/exec/bash-executor.d.ts +0 -64
  702. package/dist/types/exec/exec.d.ts +0 -25
  703. package/dist/types/exec/idle-timeout-watchdog.d.ts +0 -18
  704. package/dist/types/exec/non-interactive-env.d.ts +0 -1
  705. package/dist/types/export/custom-share.d.ts +0 -20
  706. package/dist/types/export/html/index.d.ts +0 -10
  707. package/dist/types/export/html/template.generated.d.ts +0 -1
  708. package/dist/types/export/html/template.macro.d.ts +0 -5
  709. package/dist/types/export/ttsr.d.ts +0 -55
  710. package/dist/types/extensibility/custom-commands/bundled/ci-green/index.d.ts +0 -9
  711. package/dist/types/extensibility/custom-commands/index.d.ts +0 -2
  712. package/dist/types/extensibility/custom-commands/loader.d.ts +0 -29
  713. package/dist/types/extensibility/custom-commands/types.d.ts +0 -106
  714. package/dist/types/extensibility/custom-tools/index.d.ts +0 -6
  715. package/dist/types/extensibility/custom-tools/loader.d.ts +0 -69
  716. package/dist/types/extensibility/custom-tools/types.d.ts +0 -229
  717. package/dist/types/extensibility/custom-tools/wrapper.d.ts +0 -24
  718. package/dist/types/extensibility/extensions/compact-handler.d.ts +0 -26
  719. package/dist/types/extensibility/extensions/get-commands-handler.d.ts +0 -29
  720. package/dist/types/extensibility/extensions/index.d.ts +0 -9
  721. package/dist/types/extensibility/extensions/loader.d.ts +0 -43
  722. package/dist/types/extensibility/extensions/prefix-command-bridge.d.ts +0 -35
  723. package/dist/types/extensibility/extensions/runner.d.ts +0 -135
  724. package/dist/types/extensibility/extensions/types.d.ts +0 -920
  725. package/dist/types/extensibility/extensions/wrapper.d.ts +0 -55
  726. package/dist/types/extensibility/hooks/index.d.ts +0 -5
  727. package/dist/types/extensibility/hooks/loader.d.ts +0 -89
  728. package/dist/types/extensibility/hooks/runner.d.ts +0 -126
  729. package/dist/types/extensibility/hooks/tool-wrapper.d.ts +0 -25
  730. package/dist/types/extensibility/hooks/types.d.ts +0 -431
  731. package/dist/types/extensibility/plugins/doctor.d.ts +0 -3
  732. package/dist/types/extensibility/plugins/git-url.d.ts +0 -34
  733. package/dist/types/extensibility/plugins/index.d.ts +0 -8
  734. package/dist/types/extensibility/plugins/installer.d.ts +0 -5
  735. package/dist/types/extensibility/plugins/legacy-pi-compat.d.ts +0 -2
  736. package/dist/types/extensibility/plugins/loader.d.ts +0 -31
  737. package/dist/types/extensibility/plugins/manager.d.ts +0 -65
  738. package/dist/types/extensibility/plugins/marketplace/cache.d.ts +0 -41
  739. package/dist/types/extensibility/plugins/marketplace/fetcher.d.ts +0 -48
  740. package/dist/types/extensibility/plugins/marketplace/index.d.ts +0 -6
  741. package/dist/types/extensibility/plugins/marketplace/manager.d.ts +0 -57
  742. package/dist/types/extensibility/plugins/marketplace/registry.d.ts +0 -34
  743. package/dist/types/extensibility/plugins/marketplace/source-resolver.d.ts +0 -28
  744. package/dist/types/extensibility/plugins/marketplace/types.d.ts +0 -130
  745. package/dist/types/extensibility/plugins/parser.d.ts +0 -52
  746. package/dist/types/extensibility/plugins/security-scanner.d.ts +0 -31
  747. package/dist/types/extensibility/plugins/types.d.ts +0 -149
  748. package/dist/types/extensibility/runtime-skill-discovery.d.ts +0 -20
  749. package/dist/types/extensibility/shared-events.d.ts +0 -281
  750. package/dist/types/extensibility/skc-plugins/activation.d.ts +0 -14
  751. package/dist/types/extensibility/skc-plugins/compiler.d.ts +0 -19
  752. package/dist/types/extensibility/skc-plugins/constrained-hooks.d.ts +0 -29
  753. package/dist/types/extensibility/skc-plugins/index.d.ts +0 -18
  754. package/dist/types/extensibility/skc-plugins/injection.d.ts +0 -40
  755. package/dist/types/extensibility/skc-plugins/installer.d.ts +0 -13
  756. package/dist/types/extensibility/skc-plugins/loader.d.ts +0 -3
  757. package/dist/types/extensibility/skc-plugins/mcp-policy.d.ts +0 -26
  758. package/dist/types/extensibility/skc-plugins/observability.d.ts +0 -27
  759. package/dist/types/extensibility/skc-plugins/paths.d.ts +0 -8
  760. package/dist/types/extensibility/skc-plugins/prompt-appendix.d.ts +0 -16
  761. package/dist/types/extensibility/skc-plugins/registry.d.ts +0 -32
  762. package/dist/types/extensibility/skc-plugins/runtime-adapters.d.ts +0 -64
  763. package/dist/types/extensibility/skc-plugins/schema.d.ts +0 -3
  764. package/dist/types/extensibility/skc-plugins/session-validation.d.ts +0 -42
  765. package/dist/types/extensibility/skc-plugins/state.d.ts +0 -9
  766. package/dist/types/extensibility/skc-plugins/tools.d.ts +0 -8
  767. package/dist/types/extensibility/skc-plugins/types.d.ts +0 -220
  768. package/dist/types/extensibility/skc-plugins/validation.d.ts +0 -11
  769. package/dist/types/extensibility/skills.d.ts +0 -82
  770. package/dist/types/extensibility/slash-commands.d.ts +0 -48
  771. package/dist/types/extensibility/tool-proxy.d.ts +0 -4
  772. package/dist/types/extensibility/typebox.d.ts +0 -155
  773. package/dist/types/extensibility/utils.d.ts +0 -12
  774. package/dist/types/goals/index.d.ts +0 -3
  775. package/dist/types/goals/runtime.d.ts +0 -63
  776. package/dist/types/goals/state.d.ts +0 -32
  777. package/dist/types/goals/tools/goal-tool.d.ts +0 -62
  778. package/dist/types/harness-control-plane/classifier.d.ts +0 -13
  779. package/dist/types/harness-control-plane/control-endpoint.d.ts +0 -31
  780. package/dist/types/harness-control-plane/finalize.d.ts +0 -60
  781. package/dist/types/harness-control-plane/gc-adapter.d.ts +0 -3
  782. package/dist/types/harness-control-plane/operate.d.ts +0 -35
  783. package/dist/types/harness-control-plane/owner.d.ts +0 -53
  784. package/dist/types/harness-control-plane/phase-rollup.d.ts +0 -23
  785. package/dist/types/harness-control-plane/preserve.d.ts +0 -19
  786. package/dist/types/harness-control-plane/receipt-ingest.d.ts +0 -19
  787. package/dist/types/harness-control-plane/receipt-spool.d.ts +0 -19
  788. package/dist/types/harness-control-plane/receipts.d.ts +0 -149
  789. package/dist/types/harness-control-plane/rpc-adapter.d.ts +0 -69
  790. package/dist/types/harness-control-plane/seams.d.ts +0 -21
  791. package/dist/types/harness-control-plane/session-lease.d.ts +0 -65
  792. package/dist/types/harness-control-plane/state-machine.d.ts +0 -24
  793. package/dist/types/harness-control-plane/storage.d.ts +0 -81
  794. package/dist/types/harness-control-plane/types.d.ts +0 -187
  795. package/dist/types/hashline/anchors.d.ts +0 -20
  796. package/dist/types/hashline/apply.d.ts +0 -14
  797. package/dist/types/hashline/constants.d.ts +0 -19
  798. package/dist/types/hashline/diff-preview.d.ts +0 -2
  799. package/dist/types/hashline/diff.d.ts +0 -17
  800. package/dist/types/hashline/execute.d.ts +0 -4
  801. package/dist/types/hashline/hash.d.ts +0 -123
  802. package/dist/types/hashline/index.d.ts +0 -13
  803. package/dist/types/hashline/input.d.ts +0 -11
  804. package/dist/types/hashline/parser.d.ts +0 -7
  805. package/dist/types/hashline/prefixes.d.ts +0 -7
  806. package/dist/types/hashline/recovery.d.ts +0 -27
  807. package/dist/types/hashline/stream.d.ts +0 -2
  808. package/dist/types/hashline/types.d.ts +0 -77
  809. package/dist/types/hindsight/backend.d.ts +0 -13
  810. package/dist/types/hindsight/bank.d.ts +0 -54
  811. package/dist/types/hindsight/client.d.ts +0 -224
  812. package/dist/types/hindsight/config.d.ts +0 -51
  813. package/dist/types/hindsight/content.d.ts +0 -70
  814. package/dist/types/hindsight/index.d.ts +0 -8
  815. package/dist/types/hindsight/mental-models.d.ts +0 -125
  816. package/dist/types/hindsight/state.d.ts +0 -99
  817. package/dist/types/hindsight/transcript.d.ts +0 -28
  818. package/dist/types/hooks/codex-native-hooks-config.d.ts +0 -29
  819. package/dist/types/hooks/native-skill-hook.d.ts +0 -28
  820. package/dist/types/hooks/skill-keywords.d.ts +0 -18
  821. package/dist/types/hooks/skill-state.d.ts +0 -93
  822. package/dist/types/i18n/index.d.ts +0 -38
  823. package/dist/types/i18n/messages/de.d.ts +0 -2
  824. package/dist/types/i18n/messages/de.messages.d.ts +0 -1
  825. package/dist/types/i18n/messages/de.settings.d.ts +0 -1
  826. package/dist/types/i18n/messages/en.d.ts +0 -81
  827. package/dist/types/i18n/messages/es.d.ts +0 -2
  828. package/dist/types/i18n/messages/es.messages.d.ts +0 -1
  829. package/dist/types/i18n/messages/es.settings.d.ts +0 -1
  830. package/dist/types/i18n/messages/fr.d.ts +0 -2
  831. package/dist/types/i18n/messages/fr.messages.d.ts +0 -1
  832. package/dist/types/i18n/messages/fr.settings.d.ts +0 -1
  833. package/dist/types/i18n/messages/ja.d.ts +0 -2
  834. package/dist/types/i18n/messages/ja.messages.d.ts +0 -1
  835. package/dist/types/i18n/messages/ja.settings.d.ts +0 -1
  836. package/dist/types/i18n/messages/ko.d.ts +0 -2
  837. package/dist/types/i18n/messages/ko.messages.d.ts +0 -1
  838. package/dist/types/i18n/messages/ko.settings.d.ts +0 -1
  839. package/dist/types/i18n/messages/zh.d.ts +0 -2
  840. package/dist/types/i18n/messages/zh.messages.d.ts +0 -1
  841. package/dist/types/i18n/messages/zh.settings.d.ts +0 -1
  842. package/dist/types/index.d.ts +0 -33
  843. package/dist/types/internal-urls/agent-protocol.d.ts +0 -12
  844. package/dist/types/internal-urls/artifact-protocol.d.ts +0 -6
  845. package/dist/types/internal-urls/docs-index.generated.d.ts +0 -2
  846. package/dist/types/internal-urls/index.d.ts +0 -20
  847. package/dist/types/internal-urls/issue-pr-protocol.d.ts +0 -17
  848. package/dist/types/internal-urls/json-query.d.ts +0 -30
  849. package/dist/types/internal-urls/local-protocol.d.ts +0 -43
  850. package/dist/types/internal-urls/mcp-protocol.d.ts +0 -12
  851. package/dist/types/internal-urls/memory-protocol.d.ts +0 -23
  852. package/dist/types/internal-urls/parse.d.ts +0 -19
  853. package/dist/types/internal-urls/registry-helpers.d.ts +0 -11
  854. package/dist/types/internal-urls/router.d.ts +0 -14
  855. package/dist/types/internal-urls/rule-protocol.d.ts +0 -6
  856. package/dist/types/internal-urls/skc-protocol.d.ts +0 -12
  857. package/dist/types/internal-urls/skill-protocol.d.ts +0 -13
  858. package/dist/types/internal-urls/types.d.ts +0 -109
  859. package/dist/types/lsp/client.d.ts +0 -66
  860. package/dist/types/lsp/clients/biome-client.d.ts +0 -16
  861. package/dist/types/lsp/clients/index.d.ts +0 -19
  862. package/dist/types/lsp/clients/lsp-linter-client.d.ts +0 -16
  863. package/dist/types/lsp/clients/swiftlint-client.d.ts +0 -20
  864. package/dist/types/lsp/config.d.ts +0 -65
  865. package/dist/types/lsp/edits.d.ts +0 -23
  866. package/dist/types/lsp/index.d.ts +0 -130
  867. package/dist/types/lsp/lspmux.d.ts +0 -58
  868. package/dist/types/lsp/render.d.ts +0 -32
  869. package/dist/types/lsp/startup-events.d.ts +0 -12
  870. package/dist/types/lsp/types.d.ts +0 -306
  871. package/dist/types/lsp/utils.d.ts +0 -108
  872. package/dist/types/main.d.ts +0 -139
  873. package/dist/types/memories/index.d.ts +0 -28
  874. package/dist/types/memories/storage.d.ts +0 -110
  875. package/dist/types/memory-backend/index.d.ts +0 -4
  876. package/dist/types/memory-backend/local-backend.d.ts +0 -9
  877. package/dist/types/memory-backend/off-backend.d.ts +0 -7
  878. package/dist/types/memory-backend/resolve.d.ts +0 -15
  879. package/dist/types/memory-backend/types.d.ts +0 -61
  880. package/dist/types/migrate/action-planner.d.ts +0 -11
  881. package/dist/types/migrate/adapters/claude-code.d.ts +0 -2
  882. package/dist/types/migrate/adapters/codex.d.ts +0 -5
  883. package/dist/types/migrate/adapters/index.d.ts +0 -45
  884. package/dist/types/migrate/adapters/opencode.d.ts +0 -2
  885. package/dist/types/migrate/executor.d.ts +0 -2
  886. package/dist/types/migrate/mcp-mapper.d.ts +0 -20
  887. package/dist/types/migrate/report.d.ts +0 -18
  888. package/dist/types/migrate/skill-normalizer.d.ts +0 -27
  889. package/dist/types/migrate/types.d.ts +0 -126
  890. package/dist/types/modes/acp/acp-agent.d.ts +0 -78
  891. package/dist/types/modes/acp/acp-client-bridge.d.ts +0 -9
  892. package/dist/types/modes/acp/acp-event-mapper.d.ts +0 -36
  893. package/dist/types/modes/acp/acp-mode.d.ts +0 -17
  894. package/dist/types/modes/acp/index.d.ts +0 -2
  895. package/dist/types/modes/acp/terminal-auth.d.ts +0 -6
  896. package/dist/types/modes/bridge/auth.d.ts +0 -12
  897. package/dist/types/modes/bridge/bridge-client-bridge.d.ts +0 -9
  898. package/dist/types/modes/bridge/bridge-mode.d.ts +0 -47
  899. package/dist/types/modes/bridge/bridge-ui-context.d.ts +0 -88
  900. package/dist/types/modes/bridge/event-stream.d.ts +0 -8
  901. package/dist/types/modes/components/agent-dashboard.d.ts +0 -21
  902. package/dist/types/modes/components/assistant-message.d.ts +0 -20
  903. package/dist/types/modes/components/bash-execution.d.ts +0 -29
  904. package/dist/types/modes/components/bordered-loader.d.ts +0 -11
  905. package/dist/types/modes/components/branch-summary-message.d.ts +0 -13
  906. package/dist/types/modes/components/btw-panel.d.ts +0 -16
  907. package/dist/types/modes/components/compaction-summary-message.d.ts +0 -13
  908. package/dist/types/modes/components/countdown-timer.d.ts +0 -14
  909. package/dist/types/modes/components/custom-editor.d.ts +0 -69
  910. package/dist/types/modes/components/custom-message.d.ts +0 -15
  911. package/dist/types/modes/components/custom-model-preset-wizard.d.ts +0 -12
  912. package/dist/types/modes/components/custom-provider-wizard.d.ts +0 -10
  913. package/dist/types/modes/components/diff.d.ts +0 -11
  914. package/dist/types/modes/components/dynamic-border.d.ts +0 -14
  915. package/dist/types/modes/components/eval-execution.d.ts +0 -23
  916. package/dist/types/modes/components/execution-shared.d.ts +0 -46
  917. package/dist/types/modes/components/extensions/extension-dashboard.d.ts +0 -26
  918. package/dist/types/modes/components/extensions/extension-list.d.ts +0 -39
  919. package/dist/types/modes/components/extensions/index.d.ts +0 -8
  920. package/dist/types/modes/components/extensions/inspector-panel.d.ts +0 -8
  921. package/dist/types/modes/components/extensions/state-manager.d.ts +0 -50
  922. package/dist/types/modes/components/extensions/types.d.ts +0 -151
  923. package/dist/types/modes/components/footer.d.ts +0 -30
  924. package/dist/types/modes/components/history-search.d.ts +0 -7
  925. package/dist/types/modes/components/hook-editor.d.ts +0 -18
  926. package/dist/types/modes/components/hook-input.d.ts +0 -15
  927. package/dist/types/modes/components/hook-message.d.ts +0 -15
  928. package/dist/types/modes/components/hook-selector.d.ts +0 -59
  929. package/dist/types/modes/components/index.d.ts +0 -35
  930. package/dist/types/modes/components/irc-sidebar.d.ts +0 -32
  931. package/dist/types/modes/components/jobs-overlay-model.d.ts +0 -31
  932. package/dist/types/modes/components/jobs-overlay.d.ts +0 -30
  933. package/dist/types/modes/components/keybinding-hints.d.ts +0 -40
  934. package/dist/types/modes/components/login-dialog.d.ts +0 -32
  935. package/dist/types/modes/components/message-frame.d.ts +0 -42
  936. package/dist/types/modes/components/model-selector.d.ts +0 -60
  937. package/dist/types/modes/components/oauth-selector.d.ts +0 -17
  938. package/dist/types/modes/components/pet-selector.d.ts +0 -11
  939. package/dist/types/modes/components/plugin-selector.d.ts +0 -26
  940. package/dist/types/modes/components/plugin-settings.d.ts +0 -66
  941. package/dist/types/modes/components/provider-onboarding-selector.d.ts +0 -7
  942. package/dist/types/modes/components/queue-mode-selector.d.ts +0 -9
  943. package/dist/types/modes/components/queued-message-selector.d.ts +0 -12
  944. package/dist/types/modes/components/read-tool-group.d.ts +0 -30
  945. package/dist/types/modes/components/runtime-mcp-add-wizard.d.ts +0 -26
  946. package/dist/types/modes/components/sayknow-pet-widget.d.ts +0 -59
  947. package/dist/types/modes/components/session-observer-overlay.d.ts +0 -11
  948. package/dist/types/modes/components/session-selector.d.ts +0 -43
  949. package/dist/types/modes/components/settings-defs.d.ts +0 -50
  950. package/dist/types/modes/components/settings-selector.d.ts +0 -64
  951. package/dist/types/modes/components/show-images-selector.d.ts +0 -9
  952. package/dist/types/modes/components/skill-hud/render.d.ts +0 -2
  953. package/dist/types/modes/components/skill-message.d.ts +0 -10
  954. package/dist/types/modes/components/status-line/context-thresholds.d.ts +0 -4
  955. package/dist/types/modes/components/status-line/git-utils.d.ts +0 -28
  956. package/dist/types/modes/components/status-line/index.d.ts +0 -4
  957. package/dist/types/modes/components/status-line/presets.d.ts +0 -3
  958. package/dist/types/modes/components/status-line/segments.d.ts +0 -5
  959. package/dist/types/modes/components/status-line/separators.d.ts +0 -3
  960. package/dist/types/modes/components/status-line/token-rate.d.ts +0 -10
  961. package/dist/types/modes/components/status-line/types.d.ts +0 -83
  962. package/dist/types/modes/components/status-line.d.ts +0 -94
  963. package/dist/types/modes/components/theme-selector.d.ts +0 -10
  964. package/dist/types/modes/components/thinking-selector.d.ts +0 -15
  965. package/dist/types/modes/components/todo-reminder.d.ts +0 -13
  966. package/dist/types/modes/components/tool-execution.d.ts +0 -55
  967. package/dist/types/modes/components/tree-selector.d.ts +0 -31
  968. package/dist/types/modes/components/ttsr-notification.d.ts +0 -13
  969. package/dist/types/modes/components/two-column-body.d.ts +0 -9
  970. package/dist/types/modes/components/user-message-selector.d.ts +0 -28
  971. package/dist/types/modes/components/user-message.d.ts +0 -8
  972. package/dist/types/modes/components/visual-truncate.d.ts +0 -19
  973. package/dist/types/modes/components/welcome.d.ts +0 -46
  974. package/dist/types/modes/controllers/btw-controller.d.ts +0 -10
  975. package/dist/types/modes/controllers/command-controller-shared.d.ts +0 -47
  976. package/dist/types/modes/controllers/command-controller.d.ts +0 -40
  977. package/dist/types/modes/controllers/event-controller.d.ts +0 -21
  978. package/dist/types/modes/controllers/extension-ui-controller.d.ts +0 -80
  979. package/dist/types/modes/controllers/input-controller.d.ts +0 -42
  980. package/dist/types/modes/controllers/runtime-mcp-command-controller.d.ts +0 -10
  981. package/dist/types/modes/controllers/selector-controller.d.ts +0 -68
  982. package/dist/types/modes/controllers/ssh-command-controller.d.ts +0 -10
  983. package/dist/types/modes/controllers/todo-command-controller.d.ts +0 -7
  984. package/dist/types/modes/emoji-autocomplete.d.ts +0 -16
  985. package/dist/types/modes/index.d.ts +0 -10
  986. package/dist/types/modes/interactive-mode.d.ts +0 -297
  987. package/dist/types/modes/irc-observation-ledger.d.ts +0 -22
  988. package/dist/types/modes/jobs-observer.d.ts +0 -57
  989. package/dist/types/modes/oauth-manual-input.d.ts +0 -8
  990. package/dist/types/modes/print-mode.d.ts +0 -44
  991. package/dist/types/modes/prompt-action-autocomplete.d.ts +0 -50
  992. package/dist/types/modes/rpc/host-tools.d.ts +0 -1
  993. package/dist/types/modes/rpc/host-uris.d.ts +0 -1
  994. package/dist/types/modes/rpc/rpc-client.d.ts +0 -299
  995. package/dist/types/modes/rpc/rpc-mode.d.ts +0 -86
  996. package/dist/types/modes/rpc/rpc-socket-security.d.ts +0 -10
  997. package/dist/types/modes/rpc/rpc-types.d.ts +0 -810
  998. package/dist/types/modes/runtime-init.d.ts +0 -21
  999. package/dist/types/modes/session-observer-registry.d.ts +0 -26
  1000. package/dist/types/modes/shared/agent-wire/approval-gate.d.ts +0 -57
  1001. package/dist/types/modes/shared/agent-wire/command-contract.d.ts +0 -18
  1002. package/dist/types/modes/shared/agent-wire/command-dispatch.d.ts +0 -37
  1003. package/dist/types/modes/shared/agent-wire/command-validation.d.ts +0 -2
  1004. package/dist/types/modes/shared/agent-wire/deep-interview-gate.d.ts +0 -102
  1005. package/dist/types/modes/shared/agent-wire/event-contract.d.ts +0 -103
  1006. package/dist/types/modes/shared/agent-wire/event-envelope.d.ts +0 -60
  1007. package/dist/types/modes/shared/agent-wire/event-observation.d.ts +0 -37
  1008. package/dist/types/modes/shared/agent-wire/handshake.d.ts +0 -56
  1009. package/dist/types/modes/shared/agent-wire/host-tool-bridge.d.ts +0 -16
  1010. package/dist/types/modes/shared/agent-wire/host-uri-bridge.d.ts +0 -17
  1011. package/dist/types/modes/shared/agent-wire/protocol.d.ts +0 -25
  1012. package/dist/types/modes/shared/agent-wire/responses.d.ts +0 -4
  1013. package/dist/types/modes/shared/agent-wire/scopes.d.ts +0 -18
  1014. package/dist/types/modes/shared/agent-wire/session-registry.d.ts +0 -25
  1015. package/dist/types/modes/shared/agent-wire/ui-request-broker.d.ts +0 -42
  1016. package/dist/types/modes/shared/agent-wire/ui-result.d.ts +0 -27
  1017. package/dist/types/modes/shared/agent-wire/unattended-action-policy.d.ts +0 -29
  1018. package/dist/types/modes/shared/agent-wire/unattended-audit.d.ts +0 -68
  1019. package/dist/types/modes/shared/agent-wire/unattended-run-controller.d.ts +0 -166
  1020. package/dist/types/modes/shared/agent-wire/unattended-session.d.ts +0 -127
  1021. package/dist/types/modes/shared/agent-wire/workflow-gate-broker.d.ts +0 -154
  1022. package/dist/types/modes/shared/agent-wire/workflow-gate-schema.d.ts +0 -39
  1023. package/dist/types/modes/shared.d.ts +0 -15
  1024. package/dist/types/modes/slash-command-visibility.d.ts +0 -1
  1025. package/dist/types/modes/theme/defaults/index.d.ts +0 -652
  1026. package/dist/types/modes/theme/mermaid-cache.d.ts +0 -9
  1027. package/dist/types/modes/theme/shimmer.d.ts +0 -38
  1028. package/dist/types/modes/theme/theme.d.ts +0 -275
  1029. package/dist/types/modes/tmux-scroll.d.ts +0 -18
  1030. package/dist/types/modes/types.d.ts +0 -318
  1031. package/dist/types/modes/utils/abort-message.d.ts +0 -4
  1032. package/dist/types/modes/utils/context-usage.d.ts +0 -36
  1033. package/dist/types/modes/utils/hotkeys-markdown.d.ts +0 -5
  1034. package/dist/types/modes/utils/injected-user-submission.d.ts +0 -52
  1035. package/dist/types/modes/utils/irc-message.d.ts +0 -38
  1036. package/dist/types/modes/utils/keybinding-matchers.d.ts +0 -10
  1037. package/dist/types/modes/utils/terminal-bell.d.ts +0 -3
  1038. package/dist/types/modes/utils/tools-markdown.d.ts +0 -5
  1039. package/dist/types/modes/utils/ui-helpers.d.ts +0 -75
  1040. package/dist/types/notifications/attachment-registry.d.ts +0 -17
  1041. package/dist/types/notifications/chat-adapters.d.ts +0 -9
  1042. package/dist/types/notifications/config-commands.d.ts +0 -64
  1043. package/dist/types/notifications/config.d.ts +0 -132
  1044. package/dist/types/notifications/daemon-paths.d.ts +0 -17
  1045. package/dist/types/notifications/engine.d.ts +0 -59
  1046. package/dist/types/notifications/helpers.d.ts +0 -55
  1047. package/dist/types/notifications/html-format.d.ts +0 -75
  1048. package/dist/types/notifications/index.d.ts +0 -219
  1049. package/dist/types/notifications/lifecycle-commands.d.ts +0 -69
  1050. package/dist/types/notifications/lifecycle-control-runtime.d.ts +0 -107
  1051. package/dist/types/notifications/lifecycle-orchestrator.d.ts +0 -144
  1052. package/dist/types/notifications/managed-daemon.d.ts +0 -48
  1053. package/dist/types/notifications/notification-service.d.ts +0 -144
  1054. package/dist/types/notifications/operator-runtime.d.ts +0 -52
  1055. package/dist/types/notifications/rate-limit-pool.d.ts +0 -113
  1056. package/dist/types/notifications/recent-activity.d.ts +0 -39
  1057. package/dist/types/notifications/reply-sent-store.d.ts +0 -53
  1058. package/dist/types/notifications/rich-draft.d.ts +0 -68
  1059. package/dist/types/notifications/rich-render.d.ts +0 -90
  1060. package/dist/types/notifications/telegram-cli.d.ts +0 -19
  1061. package/dist/types/notifications/telegram-daemon-cli.d.ts +0 -28
  1062. package/dist/types/notifications/telegram-daemon-control.d.ts +0 -70
  1063. package/dist/types/notifications/telegram-daemon.d.ts +0 -558
  1064. package/dist/types/notifications/telegram-reference.d.ts +0 -136
  1065. package/dist/types/notifications/threaded-inbound.d.ts +0 -77
  1066. package/dist/types/notifications/threaded-render.d.ts +0 -88
  1067. package/dist/types/notifications/topic-registry.d.ts +0 -89
  1068. package/dist/types/plan-mode/approved-plan.d.ts +0 -49
  1069. package/dist/types/plan-mode/state.d.ts +0 -6
  1070. package/dist/types/registry/agent-registry.d.ts +0 -64
  1071. package/dist/types/reminders/star-reminder.d.ts +0 -115
  1072. package/dist/types/research-plan/index.d.ts +0 -1
  1073. package/dist/types/research-plan/ledger.d.ts +0 -33
  1074. package/dist/types/rlm/artifacts.d.ts +0 -9
  1075. package/dist/types/rlm/complete-research-tool.d.ts +0 -35
  1076. package/dist/types/rlm/data-context.d.ts +0 -6
  1077. package/dist/types/rlm/index.d.ts +0 -47
  1078. package/dist/types/rlm/notebook.d.ts +0 -12
  1079. package/dist/types/rlm/preset.d.ts +0 -23
  1080. package/dist/types/rlm/python-tool.d.ts +0 -16
  1081. package/dist/types/rlm/report.d.ts +0 -14
  1082. package/dist/types/rlm/types.d.ts +0 -37
  1083. package/dist/types/runtime/process-lifecycle.d.ts +0 -108
  1084. package/dist/types/runtime-api-key.d.ts +0 -7
  1085. package/dist/types/runtime-credential-selector.d.ts +0 -7
  1086. package/dist/types/runtime-mcp/client.d.ts +0 -74
  1087. package/dist/types/runtime-mcp/config-writer.d.ts +0 -89
  1088. package/dist/types/runtime-mcp/config.d.ts +0 -77
  1089. package/dist/types/runtime-mcp/discoverable-tool-metadata.d.ts +0 -7
  1090. package/dist/types/runtime-mcp/index.d.ts +0 -18
  1091. package/dist/types/runtime-mcp/json-rpc.d.ts +0 -22
  1092. package/dist/types/runtime-mcp/loader.d.ts +0 -45
  1093. package/dist/types/runtime-mcp/manager.d.ts +0 -195
  1094. package/dist/types/runtime-mcp/oauth-discovery.d.ts +0 -40
  1095. package/dist/types/runtime-mcp/oauth-flow.d.ts +0 -59
  1096. package/dist/types/runtime-mcp/render.d.ts +0 -25
  1097. package/dist/types/runtime-mcp/smithery-auth.d.ts +0 -16
  1098. package/dist/types/runtime-mcp/smithery-connect.d.ts +0 -38
  1099. package/dist/types/runtime-mcp/smithery-registry.d.ts +0 -51
  1100. package/dist/types/runtime-mcp/tool-bridge.d.ts +0 -86
  1101. package/dist/types/runtime-mcp/tool-cache.d.ts +0 -8
  1102. package/dist/types/runtime-mcp/transports/http.d.ts +0 -36
  1103. package/dist/types/runtime-mcp/transports/index.d.ts +0 -5
  1104. package/dist/types/runtime-mcp/transports/stdio.d.ts +0 -29
  1105. package/dist/types/runtime-mcp/types.d.ts +0 -349
  1106. package/dist/types/sdk.d.ts +0 -256
  1107. package/dist/types/secrets/index.d.ts +0 -9
  1108. package/dist/types/secrets/obfuscator.d.ts +0 -23
  1109. package/dist/types/secrets/regex.d.ts +0 -2
  1110. package/dist/types/session/agent-session.d.ts +0 -1238
  1111. package/dist/types/session/agent-storage.d.ts +0 -101
  1112. package/dist/types/session/artifacts.d.ts +0 -64
  1113. package/dist/types/session/auth-broker-config.d.ts +0 -13
  1114. package/dist/types/session/auth-storage.d.ts +0 -6
  1115. package/dist/types/session/blob-store.d.ts +0 -160
  1116. package/dist/types/session/cache-economics.d.ts +0 -79
  1117. package/dist/types/session/client-bridge.d.ts +0 -88
  1118. package/dist/types/session/context-estimation.d.ts +0 -31
  1119. package/dist/types/session/contribution-prep.d.ts +0 -47
  1120. package/dist/types/session/file-mention-pruning.d.ts +0 -8
  1121. package/dist/types/session/history-storage.d.ts +0 -16
  1122. package/dist/types/session/messages.d.ts +0 -169
  1123. package/dist/types/session/provider-safety-stop.d.ts +0 -5
  1124. package/dist/types/session/session-dump-format.d.ts +0 -22
  1125. package/dist/types/session/session-manager.d.ts +0 -781
  1126. package/dist/types/session/session-storage.d.ts +0 -230
  1127. package/dist/types/session/streaming-output.d.ts +0 -209
  1128. package/dist/types/session/tool-choice-queue.d.ts +0 -84
  1129. package/dist/types/session/yield-queue.d.ts +0 -24
  1130. package/dist/types/setup/credential-auto-import.d.ts +0 -63
  1131. package/dist/types/setup/credential-import.d.ts +0 -82
  1132. package/dist/types/setup/hermes-setup.d.ts +0 -78
  1133. package/dist/types/setup/host-plugin-setup.d.ts +0 -39
  1134. package/dist/types/setup/model-onboarding-guidance.d.ts +0 -9
  1135. package/dist/types/setup/provider-onboarding.d.ts +0 -52
  1136. package/dist/types/skc-runtime/cli-write-receipt.d.ts +0 -24
  1137. package/dist/types/skc-runtime/deep-interview-ambiguity.d.ts +0 -39
  1138. package/dist/types/skc-runtime/deep-interview-recorder.d.ts +0 -114
  1139. package/dist/types/skc-runtime/deep-interview-runtime.d.ts +0 -36
  1140. package/dist/types/skc-runtime/deep-interview-state.d.ts +0 -127
  1141. package/dist/types/skc-runtime/gc-render.d.ts +0 -6
  1142. package/dist/types/skc-runtime/gc-runtime.d.ts +0 -134
  1143. package/dist/types/skc-runtime/goal-mode-request.d.ts +0 -53
  1144. package/dist/types/skc-runtime/launch-tmux.d.ts +0 -78
  1145. package/dist/types/skc-runtime/launch-worktree.d.ts +0 -46
  1146. package/dist/types/skc-runtime/ledger-event-renderer.d.ts +0 -68
  1147. package/dist/types/skc-runtime/psmux-detect.d.ts +0 -78
  1148. package/dist/types/skc-runtime/ralplan-runtime.d.ts +0 -26
  1149. package/dist/types/skc-runtime/restricted-role-agent-bash.d.ts +0 -3
  1150. package/dist/types/skc-runtime/session-layout.d.ts +0 -59
  1151. package/dist/types/skc-runtime/session-resolution.d.ts +0 -47
  1152. package/dist/types/skc-runtime/session-state-sidecar.d.ts +0 -70
  1153. package/dist/types/skc-runtime/state-graph.d.ts +0 -4
  1154. package/dist/types/skc-runtime/state-migrations.d.ts +0 -33
  1155. package/dist/types/skc-runtime/state-renderer.d.ts +0 -70
  1156. package/dist/types/skc-runtime/state-runtime.d.ts +0 -38
  1157. package/dist/types/skc-runtime/state-schema.d.ts +0 -319
  1158. package/dist/types/skc-runtime/state-validation.d.ts +0 -6
  1159. package/dist/types/skc-runtime/state-writer.d.ts +0 -244
  1160. package/dist/types/skc-runtime/team-gc.d.ts +0 -7
  1161. package/dist/types/skc-runtime/team-runtime.d.ts +0 -355
  1162. package/dist/types/skc-runtime/tmux-common.d.ts +0 -111
  1163. package/dist/types/skc-runtime/tmux-gc.d.ts +0 -7
  1164. package/dist/types/skc-runtime/tmux-owner-isolation-cli.d.ts +0 -5
  1165. package/dist/types/skc-runtime/tmux-owner-isolation.d.ts +0 -309
  1166. package/dist/types/skc-runtime/tmux-sessions.d.ts +0 -94
  1167. package/dist/types/skc-runtime/ultragoal-guard.d.ts +0 -93
  1168. package/dist/types/skc-runtime/ultragoal-receipt-freshness.d.ts +0 -42
  1169. package/dist/types/skc-runtime/ultragoal-runtime.d.ts +0 -410
  1170. package/dist/types/skc-runtime/workflow-command-ref.d.ts +0 -43
  1171. package/dist/types/skc-runtime/workflow-manifest.d.ts +0 -54
  1172. package/dist/types/skill-state/active-state.d.ts +0 -126
  1173. package/dist/types/skill-state/canonical-skills.d.ts +0 -3
  1174. package/dist/types/skill-state/deep-interview-mutation-guard.d.ts +0 -38
  1175. package/dist/types/skill-state/initial-phase.d.ts +0 -12
  1176. package/dist/types/skill-state/workflow-hud.d.ts +0 -83
  1177. package/dist/types/skill-state/workflow-state-contract.d.ts +0 -57
  1178. package/dist/types/skill-state/workflow-state-version.d.ts +0 -3
  1179. package/dist/types/slash-commands/acp-builtins.d.ts +0 -18
  1180. package/dist/types/slash-commands/builtin-registry.d.ts +0 -24
  1181. package/dist/types/slash-commands/helpers/context-report.d.ts +0 -7
  1182. package/dist/types/slash-commands/helpers/fast-status-report.d.ts +0 -82
  1183. package/dist/types/slash-commands/helpers/format.d.ts +0 -10
  1184. package/dist/types/slash-commands/helpers/mcp.d.ts +0 -3
  1185. package/dist/types/slash-commands/helpers/parse.d.ts +0 -33
  1186. package/dist/types/slash-commands/helpers/ssh.d.ts +0 -3
  1187. package/dist/types/slash-commands/helpers/todo.d.ts +0 -3
  1188. package/dist/types/slash-commands/helpers/usage-report.d.ts +0 -7
  1189. package/dist/types/slash-commands/types.d.ts +0 -120
  1190. package/dist/types/ssh/config-writer.d.ts +0 -49
  1191. package/dist/types/ssh/connection-manager.d.ts +0 -33
  1192. package/dist/types/ssh/ssh-executor.d.ts +0 -37
  1193. package/dist/types/ssh/sshfs-mount.d.ts +0 -6
  1194. package/dist/types/ssh/utils.d.ts +0 -2
  1195. package/dist/types/stt/downloader.d.ts +0 -9
  1196. package/dist/types/stt/index.d.ts +0 -3
  1197. package/dist/types/stt/recorder.d.ts +0 -13
  1198. package/dist/types/stt/setup.d.ts +0 -18
  1199. package/dist/types/stt/stt-controller.d.ts +0 -16
  1200. package/dist/types/stt/transcriber.d.ts +0 -16
  1201. package/dist/types/system-prompt.d.ts +0 -118
  1202. package/dist/types/task/agents.d.ts +0 -28
  1203. package/dist/types/task/commands.d.ts +0 -35
  1204. package/dist/types/task/discovery.d.ts +0 -19
  1205. package/dist/types/task/executor.d.ts +0 -127
  1206. package/dist/types/task/fork-context-advisory.d.ts +0 -13
  1207. package/dist/types/task/fork-context-budget.d.ts +0 -7
  1208. package/dist/types/task/id.d.ts +0 -7
  1209. package/dist/types/task/index.d.ts +0 -43
  1210. package/dist/types/task/name-generator.d.ts +0 -16
  1211. package/dist/types/task/output-manager.d.ts +0 -36
  1212. package/dist/types/task/parallel.d.ts +0 -34
  1213. package/dist/types/task/receipt.d.ts +0 -89
  1214. package/dist/types/task/render.d.ts +0 -28
  1215. package/dist/types/task/roi-reconciliation.d.ts +0 -27
  1216. package/dist/types/task/simple-mode.d.ts +0 -8
  1217. package/dist/types/task/skc-command.d.ts +0 -7
  1218. package/dist/types/task/spawn-gate.d.ts +0 -29
  1219. package/dist/types/task/subprocess-tool-registry.d.ts +0 -72
  1220. package/dist/types/task/token-log.d.ts +0 -30
  1221. package/dist/types/task/token-log.test.d.ts +0 -1
  1222. package/dist/types/task/types.d.ts +0 -516
  1223. package/dist/types/task/worktree.d.ts +0 -94
  1224. package/dist/types/thinking-metadata.d.ts +0 -16
  1225. package/dist/types/thinking.d.ts +0 -22
  1226. package/dist/types/tool-discovery/tool-index.d.ts +0 -112
  1227. package/dist/types/tools/archive-reader.d.ts +0 -40
  1228. package/dist/types/tools/ask-answer-registry.d.ts +0 -18
  1229. package/dist/types/tools/ask.d.ts +0 -123
  1230. package/dist/types/tools/ast-edit.d.ts +0 -77
  1231. package/dist/types/tools/ast-grep.d.ts +0 -69
  1232. package/dist/types/tools/auto-generated-guard.d.ts +0 -17
  1233. package/dist/types/tools/bash-allowed-prefixes.d.ts +0 -10
  1234. package/dist/types/tools/bash-command-fixup.d.ts +0 -11
  1235. package/dist/types/tools/bash-interactive.d.ts +0 -16
  1236. package/dist/types/tools/bash-interceptor.d.ts +0 -24
  1237. package/dist/types/tools/bash-pty-selection.d.ts +0 -7
  1238. package/dist/types/tools/bash-skill-urls.d.ts +0 -31
  1239. package/dist/types/tools/bash.d.ts +0 -157
  1240. package/dist/types/tools/bisect.d.ts +0 -81
  1241. package/dist/types/tools/browser/actions.d.ts +0 -54
  1242. package/dist/types/tools/browser/attach.d.ts +0 -50
  1243. package/dist/types/tools/browser/launch.d.ts +0 -62
  1244. package/dist/types/tools/browser/readable.d.ts +0 -17
  1245. package/dist/types/tools/browser/registry.d.ts +0 -57
  1246. package/dist/types/tools/browser/render.d.ts +0 -53
  1247. package/dist/types/tools/browser/tab-protocol.d.ts +0 -144
  1248. package/dist/types/tools/browser/tab-supervisor.d.ts +0 -109
  1249. package/dist/types/tools/browser/tab-worker-entry.d.ts +0 -1
  1250. package/dist/types/tools/browser/tab-worker.d.ts +0 -19
  1251. package/dist/types/tools/browser.d.ts +0 -211
  1252. package/dist/types/tools/calculator.d.ts +0 -76
  1253. package/dist/types/tools/checkpoint.d.ts +0 -63
  1254. package/dist/types/tools/composer-bash-policy.d.ts +0 -14
  1255. package/dist/types/tools/computer/render.d.ts +0 -17
  1256. package/dist/types/tools/computer-gc.d.ts +0 -23
  1257. package/dist/types/tools/computer.d.ts +0 -465
  1258. package/dist/types/tools/conflict-detect.d.ts +0 -205
  1259. package/dist/types/tools/context.d.ts +0 -19
  1260. package/dist/types/tools/cron.d.ts +0 -91
  1261. package/dist/types/tools/debug.d.ts +0 -209
  1262. package/dist/types/tools/eval.d.ts +0 -108
  1263. package/dist/types/tools/fetch.d.ts +0 -84
  1264. package/dist/types/tools/file-recorder.d.ts +0 -13
  1265. package/dist/types/tools/find.d.ts +0 -95
  1266. package/dist/types/tools/fs-cache-invalidation.d.ts +0 -15
  1267. package/dist/types/tools/gh-format.d.ts +0 -6
  1268. package/dist/types/tools/gh-renderer.d.ts +0 -25
  1269. package/dist/types/tools/gh.d.ts +0 -356
  1270. package/dist/types/tools/github-cache.d.ts +0 -103
  1271. package/dist/types/tools/grouped-file-output.d.ts +0 -36
  1272. package/dist/types/tools/hindsight-recall.d.ts +0 -21
  1273. package/dist/types/tools/hindsight-reflect.d.ts +0 -23
  1274. package/dist/types/tools/hindsight-retain.d.ts +0 -27
  1275. package/dist/types/tools/image-gen.d.ts +0 -79
  1276. package/dist/types/tools/index.d.ts +0 -371
  1277. package/dist/types/tools/irc.d.ts +0 -79
  1278. package/dist/types/tools/job.d.ts +0 -78
  1279. package/dist/types/tools/json-tree.d.ts +0 -23
  1280. package/dist/types/tools/jtd-to-json-schema.d.ts +0 -29
  1281. package/dist/types/tools/jtd-to-typescript.d.ts +0 -26
  1282. package/dist/types/tools/jtd-utils.d.ts +0 -42
  1283. package/dist/types/tools/list-limit.d.ts +0 -12
  1284. package/dist/types/tools/match-line-format.d.ts +0 -11
  1285. package/dist/types/tools/monitor.d.ts +0 -54
  1286. package/dist/types/tools/output-meta.d.ts +0 -204
  1287. package/dist/types/tools/path-utils.d.ts +0 -147
  1288. package/dist/types/tools/plan-mode-guard.d.ts +0 -18
  1289. package/dist/types/tools/read.d.ts +0 -85
  1290. package/dist/types/tools/recipe/index.d.ts +0 -45
  1291. package/dist/types/tools/recipe/render.d.ts +0 -36
  1292. package/dist/types/tools/recipe/runner.d.ts +0 -60
  1293. package/dist/types/tools/recipe/runners/cargo.d.ts +0 -16
  1294. package/dist/types/tools/recipe/runners/index.d.ts +0 -2
  1295. package/dist/types/tools/recipe/runners/just.d.ts +0 -2
  1296. package/dist/types/tools/recipe/runners/make.d.ts +0 -2
  1297. package/dist/types/tools/recipe/runners/pkg.d.ts +0 -2
  1298. package/dist/types/tools/recipe/runners/task.d.ts +0 -2
  1299. package/dist/types/tools/render-mermaid.d.ts +0 -37
  1300. package/dist/types/tools/render-utils.d.ts +0 -158
  1301. package/dist/types/tools/renderers.d.ts +0 -26
  1302. package/dist/types/tools/resolve.d.ts +0 -80
  1303. package/dist/types/tools/resource-gc.d.ts +0 -54
  1304. package/dist/types/tools/review.d.ts +0 -63
  1305. package/dist/types/tools/search-tool-bm25.d.ts +0 -65
  1306. package/dist/types/tools/search.d.ts +0 -93
  1307. package/dist/types/tools/skill-discovery.d.ts +0 -40
  1308. package/dist/types/tools/skill.d.ts +0 -48
  1309. package/dist/types/tools/sqlite-reader.d.ts +0 -94
  1310. package/dist/types/tools/ssh.d.ts +0 -67
  1311. package/dist/types/tools/subagent-render.d.ts +0 -31
  1312. package/dist/types/tools/subagent.d.ts +0 -117
  1313. package/dist/types/tools/telegram-send.d.ts +0 -39
  1314. package/dist/types/tools/todo-write.d.ts +0 -120
  1315. package/dist/types/tools/tool-errors.d.ts +0 -33
  1316. package/dist/types/tools/tool-result.d.ts +0 -30
  1317. package/dist/types/tools/tool-timeouts.d.ts +0 -56
  1318. package/dist/types/tools/ultragoal-ask-guard.d.ts +0 -12
  1319. package/dist/types/tools/vim.d.ts +0 -58
  1320. package/dist/types/tools/write.d.ts +0 -59
  1321. package/dist/types/tools/yield.d.ts +0 -25
  1322. package/dist/types/tui/code-cell.d.ts +0 -32
  1323. package/dist/types/tui/file-list.d.ts +0 -22
  1324. package/dist/types/tui/hyperlink.d.ts +0 -42
  1325. package/dist/types/tui/index.d.ts +0 -11
  1326. package/dist/types/tui/output-block.d.ts +0 -28
  1327. package/dist/types/tui/status-line.d.ts +0 -18
  1328. package/dist/types/tui/tree-list.d.ts +0 -19
  1329. package/dist/types/tui/types.d.ts +0 -13
  1330. package/dist/types/tui/utils.d.ts +0 -36
  1331. package/dist/types/utils/changelog.d.ts +0 -37
  1332. package/dist/types/utils/clipboard.d.ts +0 -22
  1333. package/dist/types/utils/cmux-workspace.d.ts +0 -52
  1334. package/dist/types/utils/command-args.d.ts +0 -9
  1335. package/dist/types/utils/commit-message-generator.d.ts +0 -7
  1336. package/dist/types/utils/edit-mode.d.ts +0 -13
  1337. package/dist/types/utils/event-bus.d.ts +0 -6
  1338. package/dist/types/utils/external-editor.d.ts +0 -19
  1339. package/dist/types/utils/file-display-mode.d.ts +0 -27
  1340. package/dist/types/utils/file-mentions.d.ts +0 -25
  1341. package/dist/types/utils/git.d.ts +0 -393
  1342. package/dist/types/utils/image-loading.d.ts +0 -26
  1343. package/dist/types/utils/image-resize.d.ts +0 -39
  1344. package/dist/types/utils/lang-from-path.d.ts +0 -8
  1345. package/dist/types/utils/linkedom.d.ts +0 -4
  1346. package/dist/types/utils/markit.d.ts +0 -7
  1347. package/dist/types/utils/open.d.ts +0 -2
  1348. package/dist/types/utils/pasted-image-path.d.ts +0 -32
  1349. package/dist/types/utils/session-color.d.ts +0 -10
  1350. package/dist/types/utils/shell-snapshot.d.ts +0 -5
  1351. package/dist/types/utils/sixel.d.ts +0 -21
  1352. package/dist/types/utils/title-generator.d.ts +0 -31
  1353. package/dist/types/utils/tool-choice.d.ts +0 -20
  1354. package/dist/types/utils/tools-manager.d.ts +0 -9
  1355. package/dist/types/vim/buffer.d.ts +0 -41
  1356. package/dist/types/vim/commands.d.ts +0 -6
  1357. package/dist/types/vim/engine.d.ts +0 -47
  1358. package/dist/types/vim/parser.d.ts +0 -3
  1359. package/dist/types/vim/render.d.ts +0 -25
  1360. package/dist/types/vim/types.d.ts +0 -182
  1361. package/dist/types/web/insane/bridge.d.ts +0 -103
  1362. package/dist/types/web/insane/url-guard.d.ts +0 -25
  1363. package/dist/types/web/kagi.d.ts +0 -23
  1364. package/dist/types/web/parallel.d.ts +0 -58
  1365. package/dist/types/web/scrapers/artifacthub.d.ts +0 -6
  1366. package/dist/types/web/scrapers/arxiv.d.ts +0 -5
  1367. package/dist/types/web/scrapers/aur.d.ts +0 -5
  1368. package/dist/types/web/scrapers/biorxiv.d.ts +0 -5
  1369. package/dist/types/web/scrapers/bluesky.d.ts +0 -5
  1370. package/dist/types/web/scrapers/brew.d.ts +0 -5
  1371. package/dist/types/web/scrapers/cheatsh.d.ts +0 -8
  1372. package/dist/types/web/scrapers/chocolatey.d.ts +0 -5
  1373. package/dist/types/web/scrapers/choosealicense.d.ts +0 -2
  1374. package/dist/types/web/scrapers/cisa-kev.d.ts +0 -5
  1375. package/dist/types/web/scrapers/clojars.d.ts +0 -5
  1376. package/dist/types/web/scrapers/coingecko.d.ts +0 -5
  1377. package/dist/types/web/scrapers/crates-io.d.ts +0 -5
  1378. package/dist/types/web/scrapers/crossref.d.ts +0 -2
  1379. package/dist/types/web/scrapers/devto.d.ts +0 -5
  1380. package/dist/types/web/scrapers/discogs.d.ts +0 -8
  1381. package/dist/types/web/scrapers/discourse.d.ts +0 -5
  1382. package/dist/types/web/scrapers/dockerhub.d.ts +0 -5
  1383. package/dist/types/web/scrapers/docs-rs.d.ts +0 -2
  1384. package/dist/types/web/scrapers/fdroid.d.ts +0 -5
  1385. package/dist/types/web/scrapers/firefox-addons.d.ts +0 -2
  1386. package/dist/types/web/scrapers/flathub.d.ts +0 -2
  1387. package/dist/types/web/scrapers/github-gist.d.ts +0 -5
  1388. package/dist/types/web/scrapers/github.d.ts +0 -12
  1389. package/dist/types/web/scrapers/gitlab.d.ts +0 -5
  1390. package/dist/types/web/scrapers/go-pkg.d.ts +0 -5
  1391. package/dist/types/web/scrapers/hackage.d.ts +0 -5
  1392. package/dist/types/web/scrapers/hackernews.d.ts +0 -2
  1393. package/dist/types/web/scrapers/hex.d.ts +0 -5
  1394. package/dist/types/web/scrapers/huggingface.d.ts +0 -2
  1395. package/dist/types/web/scrapers/iacr.d.ts +0 -5
  1396. package/dist/types/web/scrapers/index.d.ts +0 -84
  1397. package/dist/types/web/scrapers/jetbrains-marketplace.d.ts +0 -2
  1398. package/dist/types/web/scrapers/lemmy.d.ts +0 -2
  1399. package/dist/types/web/scrapers/lobsters.d.ts +0 -5
  1400. package/dist/types/web/scrapers/mastodon.d.ts +0 -5
  1401. package/dist/types/web/scrapers/maven.d.ts +0 -6
  1402. package/dist/types/web/scrapers/mdn.d.ts +0 -2
  1403. package/dist/types/web/scrapers/metacpan.d.ts +0 -5
  1404. package/dist/types/web/scrapers/musicbrainz.d.ts +0 -5
  1405. package/dist/types/web/scrapers/npm.d.ts +0 -5
  1406. package/dist/types/web/scrapers/nuget.d.ts +0 -5
  1407. package/dist/types/web/scrapers/nvd.d.ts +0 -5
  1408. package/dist/types/web/scrapers/ollama.d.ts +0 -2
  1409. package/dist/types/web/scrapers/open-vsx.d.ts +0 -5
  1410. package/dist/types/web/scrapers/opencorporates.d.ts +0 -5
  1411. package/dist/types/web/scrapers/openlibrary.d.ts +0 -5
  1412. package/dist/types/web/scrapers/orcid.d.ts +0 -5
  1413. package/dist/types/web/scrapers/osv.d.ts +0 -5
  1414. package/dist/types/web/scrapers/packagist.d.ts +0 -5
  1415. package/dist/types/web/scrapers/pub-dev.d.ts +0 -5
  1416. package/dist/types/web/scrapers/pubmed.d.ts +0 -5
  1417. package/dist/types/web/scrapers/pypi.d.ts +0 -5
  1418. package/dist/types/web/scrapers/rawg.d.ts +0 -2
  1419. package/dist/types/web/scrapers/readthedocs.d.ts +0 -2
  1420. package/dist/types/web/scrapers/reddit.d.ts +0 -5
  1421. package/dist/types/web/scrapers/repology.d.ts +0 -5
  1422. package/dist/types/web/scrapers/rfc.d.ts +0 -5
  1423. package/dist/types/web/scrapers/rubygems.d.ts +0 -5
  1424. package/dist/types/web/scrapers/searchcode.d.ts +0 -2
  1425. package/dist/types/web/scrapers/sec-edgar.d.ts +0 -5
  1426. package/dist/types/web/scrapers/semantic-scholar.d.ts +0 -2
  1427. package/dist/types/web/scrapers/snapcraft.d.ts +0 -2
  1428. package/dist/types/web/scrapers/sourcegraph.d.ts +0 -2
  1429. package/dist/types/web/scrapers/spdx.d.ts +0 -5
  1430. package/dist/types/web/scrapers/spotify.d.ts +0 -8
  1431. package/dist/types/web/scrapers/stackoverflow.d.ts +0 -6
  1432. package/dist/types/web/scrapers/terraform.d.ts +0 -5
  1433. package/dist/types/web/scrapers/tldr.d.ts +0 -7
  1434. package/dist/types/web/scrapers/twitter.d.ts +0 -5
  1435. package/dist/types/web/scrapers/types.d.ts +0 -83
  1436. package/dist/types/web/scrapers/utils.d.ts +0 -32
  1437. package/dist/types/web/scrapers/vimeo.d.ts +0 -5
  1438. package/dist/types/web/scrapers/vscode-marketplace.d.ts +0 -5
  1439. package/dist/types/web/scrapers/w3c.d.ts +0 -2
  1440. package/dist/types/web/scrapers/wikidata.d.ts +0 -5
  1441. package/dist/types/web/scrapers/wikipedia.d.ts +0 -5
  1442. package/dist/types/web/scrapers/youtube.d.ts +0 -13
  1443. package/dist/types/web/search/index.d.ts +0 -118
  1444. package/dist/types/web/search/provider.d.ts +0 -55
  1445. package/dist/types/web/search/providers/anthropic.d.ts +0 -32
  1446. package/dist/types/web/search/providers/base.d.ts +0 -90
  1447. package/dist/types/web/search/providers/brave.d.ts +0 -27
  1448. package/dist/types/web/search/providers/codex.d.ts +0 -35
  1449. package/dist/types/web/search/providers/duckduckgo.d.ts +0 -57
  1450. package/dist/types/web/search/providers/exa.d.ts +0 -52
  1451. package/dist/types/web/search/providers/gemini.d.ts +0 -57
  1452. package/dist/types/web/search/providers/insane.d.ts +0 -53
  1453. package/dist/types/web/search/providers/jina.d.ts +0 -26
  1454. package/dist/types/web/search/providers/kagi.d.ts +0 -24
  1455. package/dist/types/web/search/providers/kimi.d.ts +0 -27
  1456. package/dist/types/web/search/providers/openai-compatible.d.ts +0 -9
  1457. package/dist/types/web/search/providers/parallel.d.ts +0 -15
  1458. package/dist/types/web/search/providers/perplexity.d.ts +0 -38
  1459. package/dist/types/web/search/providers/searxng.d.ts +0 -44
  1460. package/dist/types/web/search/providers/synthetic.d.ts +0 -21
  1461. package/dist/types/web/search/providers/tavily.d.ts +0 -29
  1462. package/dist/types/web/search/providers/text-citations.d.ts +0 -23
  1463. package/dist/types/web/search/providers/utils.d.ts +0 -88
  1464. package/dist/types/web/search/providers/xai.d.ts +0 -64
  1465. package/dist/types/web/search/providers/zai.d.ts +0 -28
  1466. package/dist/types/web/search/render.d.ts +0 -36
  1467. package/dist/types/web/search/types.d.ts +0 -372
  1468. package/dist/types/web/search/utils.d.ts +0 -4
  1469. package/dist/types/workflow/workflow-intent-diff.d.ts +0 -25
  1470. package/dist/types/workflow/workflow-intent-report-consumer.d.ts +0 -50
  1471. package/dist/types/workflow/workflow-intent-report-schema.d.ts +0 -2
  1472. package/dist/types/workflow/workflow-intent-report.d.ts +0 -48
  1473. package/dist/types/workspace-tree.d.ts +0 -42
  1474. package/src/sdk.ts +0 -2623
@@ -0,0 +1,3647 @@
1
+ #!/usr/bin/env bun
2
+
3
+ import * as fs from "node:fs/promises";
4
+ import * as os from "node:os";
5
+ import * as path from "node:path";
6
+ import { type ParserPlugin, parse } from "@babel/parser";
7
+ import traverse, { type Binding, type NodePath } from "@babel/traverse";
8
+ import * as t from "@babel/types";
9
+
10
+ const repoRoot = process.env.SKC_SDK_CANONICALIZATION_SCAN_ROOT
11
+ ? path.resolve(process.env.SKC_SDK_CANONICALIZATION_SCAN_ROOT)
12
+ : path.resolve(import.meta.dir, "..", "..", "..");
13
+ const scannerPath = "packages/coding-agent/scripts/verify-skc-sdk-canonicalization.ts";
14
+ const packageManifestPath = "packages/coding-agent/package.json";
15
+ const retiredPythonRpcPackagePath = "python/skc-rpc/";
16
+ const bridgeClientPackageManifestPath = "packages/bridge-client/package.json";
17
+ const bridgeClientPackageName = "@sayknow-cli/bridge-client";
18
+ const bridgeOrUnattendedImportPattern =
19
+ /(?:\b(?:import|export)\s+(?:type\s+)?(?:[^"'`;]*?\s+from\s+)?|\bimport\s*\(\s*)["'][^"']*(?:(?:^|\/)unattended)(?:["'/]|$)/g;
20
+ const bridgeClientImportPattern = /(?:\bfrom\s*|\bimport\s*\(\s*)["'](@sayknow-cli\/bridge-client[^"']*)["']/g;
21
+ const legacyBridgeClientSurfacePattern = /\b(?:BridgeClient|handshake|commands|SSE|control)\b/;
22
+
23
+ const pythonUnattendedProtocolClientPattern =
24
+ /\b(?:negotiate_unattended|UnattendedAccepted|UnattendedBudget|parse_unattended_accepted|workflow_gate_response)\b/g;
25
+ const pythonSkcRpcImportPattern = /^\s*(?:from\s+skc_rpc(?:\.|\s)|import\s+skc_rpc(?:\.|\s|,|$))/gm;
26
+ const retiredExternalModeInvocationPatterns = [
27
+ /--mode(?:\s+|=)["']?(?:rpc|bridge|unattended)[A-Za-z0-9_.-]*(?:\b|["'])/gi,
28
+ /["']--mode["']\s*,\s*["'](?:rpc|bridge|unattended)[A-Za-z0-9_.-]*["']/gi,
29
+ ];
30
+ const constructedRetiredIngressPatterns = [
31
+ /\[\s*["']r["']\s*,\s*["']pc["']\s*\]\.join\(\s*["']{2}\s*\)/g,
32
+ /["']r["']\s*\+\s*["']pc["']/g,
33
+ /`(?:r|\$\{\s*["']r["']\s*\})(?:pc|\$\{\s*["']pc["']\s*\})`/g,
34
+ /\[\s*["']brid["']\s*,\s*["']ge["']\s*\]\.join\(\s*["']{2}\s*\)/gi,
35
+ /`(?:brid|\$\{\s*["']brid["']\s*\})(?:ge|\$\{\s*["']ge["']\s*\})`/gi,
36
+ /\[\s*["']un["']\s*,\s*["']attended["']\s*\]\.join\(\s*["']{2}\s*\)/gi,
37
+ /`(?:un|\$\{\s*["']un["']\s*\})(?:attended|\$\{\s*["']attended["']\s*\})`/gi,
38
+ /["'](?:\.\/)?modes\/["']\s*\+\s*["'](?:rpc|bridge|unattended)[A-Za-z0-9_.-]*["']/gi,
39
+ /\[\s*["'](?:\.\/)?modes["']\s*,\s*["'](?:rpc|bridge|unattended)[A-Za-z0-9_.-]*["']\s*\]\.join\(\s*["']\/["']\s*\)/gi,
40
+ ];
41
+ const retiredModeValuePattern = /^(?:rpc|bridge|unattended)[A-Za-z0-9_.-]*$/i;
42
+ const retiredModeArgumentPattern = /^--mode(?:\s+|=)(?:rpc|bridge|unattended)[A-Za-z0-9_.-]*$/i;
43
+ const MAX_STATIC_FILE_STEPS = 1_024;
44
+ const MAX_STATIC_EXPRESSION_STEPS = 256;
45
+ const MAX_STATIC_ALIAS_HOPS = 64;
46
+
47
+ const allowedRpcModeInvocationTests = new Set([
48
+ "packages/coding-agent/test/sdk-downgrade-rollback.test.ts",
49
+ "packages/coding-agent/test/sdk-removed-ingresses.test.ts",
50
+ ]);
51
+ const retiredAgentWireSubpaths = [
52
+ "./modes/shared/agent-wire/host-tool-bridge",
53
+ "./modes/shared/agent-wire/host-uri-bridge",
54
+ "./modes/shared/agent-wire/ui-request-broker",
55
+ "./modes/shared/agent-wire/ui-result",
56
+ "./modes/shared/agent-wire/wire-types",
57
+ ] as const;
58
+ const retiredTmuxMachineBusPaths = new Set(["scripts/skc-session/prompt.sh", "scripts/skc-session/tail.sh"]);
59
+ const machineTmuxDocumentationPaths = new Set([
60
+ "docs/skc-session-clawhip-routing.md",
61
+ "packages/coding-agent/src/setup/hermes/templates/operator-instructions.v1.md",
62
+ ]);
63
+ const machineTmuxDocumentationPattern =
64
+ /(?:scripts\/skc-session\/(?:prompt|tail)\.sh|\b(?:load-buffer|paste-buffer|send-keys|capture-pane|pipe-pane)\b|(?:\.\/)?(?:scripts\/)?skc-session\/create\.sh(?:[ \t]+(?:"[^"\n]*"|'[^'\n]*'|[^\s]+)){3})/g;
65
+ function normalizeShellContinuations(contents: string): string {
66
+ return contents.replace(/\\\r?\n[ \t]*/g, " ");
67
+ }
68
+
69
+ type TmuxMachineBusPrimitive =
70
+ | "load-buffer"
71
+ | "paste-buffer"
72
+ | "send-keys"
73
+ | "capture-pane"
74
+ | "pipe-pane"
75
+ | "set-buffer";
76
+
77
+ const tmuxMachineBusPrimitives: readonly TmuxMachineBusPrimitive[] = [
78
+ "load-buffer",
79
+ "paste-buffer",
80
+ "send-keys",
81
+ "capture-pane",
82
+ "pipe-pane",
83
+ "set-buffer",
84
+ ];
85
+
86
+ interface TmuxPrimitiveOccurrence {
87
+ primitive: TmuxMachineBusPrimitive;
88
+ start: number;
89
+ end: number;
90
+ }
91
+
92
+ interface StaticStringAssignment {
93
+ name: string;
94
+ expression: string;
95
+ start: number;
96
+ }
97
+
98
+ function maskCodeComments(contents: string): string {
99
+ let masked = "";
100
+ let quote: "'" | '"' | "`" | undefined;
101
+ for (let index = 0; index < contents.length; index++) {
102
+ const character = contents[index];
103
+ if (quote) {
104
+ masked += character;
105
+ if (character === "\\") {
106
+ masked += contents[index + 1] ?? "";
107
+ index++;
108
+ } else if (character === quote) {
109
+ quote = undefined;
110
+ }
111
+ continue;
112
+ }
113
+ if (character === "'" || character === '"' || character === "`") {
114
+ quote = character;
115
+ masked += character;
116
+ continue;
117
+ }
118
+ if (character === "/" && contents[index + 1] === "/") {
119
+ while (index < contents.length && contents[index] !== "\n") {
120
+ masked += " ";
121
+ index++;
122
+ }
123
+ masked += contents[index] ?? "";
124
+ continue;
125
+ }
126
+ if (character === "/" && contents[index + 1] === "*") {
127
+ masked += " ";
128
+ index++;
129
+ while (index + 1 < contents.length && !(contents[index] === "*" && contents[index + 1] === "/")) {
130
+ masked += contents[index] === "\n" ? "\n" : " ";
131
+ index++;
132
+ }
133
+ if (index + 1 < contents.length) {
134
+ masked += " ";
135
+ index++;
136
+ }
137
+ continue;
138
+ }
139
+ masked += character;
140
+ }
141
+ return masked;
142
+ }
143
+
144
+ function quotedStringValue(expression: string): string | undefined {
145
+ const match = /^(["'])([^\\\r\n]*)\1$/.exec(expression.trim());
146
+ return match?.[2];
147
+ }
148
+
149
+ function staticStringValue(expression: string, bindings: ReadonlyMap<string, string>): string | undefined {
150
+ const trimmed = expression.trim();
151
+ const literal = quotedStringValue(trimmed);
152
+ if (literal !== undefined) return literal;
153
+ if (/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(trimmed)) return bindings.get(trimmed);
154
+ if (trimmed.startsWith("`") && trimmed.endsWith("`")) {
155
+ const interpolated = trimmed
156
+ .slice(1, -1)
157
+ .replace(/\$\{\s*([A-Za-z_$][A-Za-z0-9_$]*)\s*\}/g, (source, name: string) => bindings.get(name) ?? source);
158
+ return interpolated.includes("${") ? undefined : interpolated;
159
+ }
160
+ const join = /^\[\s*([^\]]*?)\s*\]\.join\(\s*(["'])([^\\\r\n]*)\2\s*\)$/.exec(trimmed);
161
+ if (join) {
162
+ const parts = join[1].split(",").map(part => staticStringValue(part, bindings));
163
+ return parts.every((part): part is string => part !== undefined) ? parts.join(join[3]) : undefined;
164
+ }
165
+ const parts = trimmed.split("+").map(part => part.trim());
166
+ if (parts.length > 1) {
167
+ const values = parts.map(part => staticStringValue(part, bindings));
168
+ return values.every((part): part is string => part !== undefined) ? values.join("") : undefined;
169
+ }
170
+ return undefined;
171
+ }
172
+
173
+ function staticStringBindings(contents: string): {
174
+ assignments: StaticStringAssignment[];
175
+ masked: string;
176
+ values: ReadonlyMap<string, string>;
177
+ } {
178
+ const masked = maskCodeComments(contents);
179
+ const assignments: StaticStringAssignment[] = [];
180
+ for (const match of masked.matchAll(/\b(?:const|let|var)\s+([A-Za-z_$][A-Za-z0-9_$]*)\s*=\s*([^;\r\n]+);?/g)) {
181
+ const expression = match[2];
182
+ const start = (match.index ?? 0) + match[0].lastIndexOf(expression);
183
+ assignments.push({ name: match[1], expression, start });
184
+ }
185
+ const values = new Map<string, string>();
186
+ for (let pass = 0; pass < assignments.length; pass++) {
187
+ let changed = false;
188
+ for (const assignment of assignments) {
189
+ const value = staticStringValue(assignment.expression, values);
190
+ if (value === undefined || values.get(assignment.name) === value) continue;
191
+ values.set(assignment.name, value);
192
+ changed = true;
193
+ }
194
+ if (!changed) break;
195
+ }
196
+ return { assignments, masked, values };
197
+ }
198
+
199
+ function tmuxPrimitiveOccurrences(contents: string): TmuxPrimitiveOccurrence[] {
200
+ const { assignments, masked, values: bindings } = staticStringBindings(contents);
201
+ const occurrences = new Map<string, TmuxPrimitiveOccurrence>();
202
+ const add = (primitive: TmuxMachineBusPrimitive, start: number, end: number) => {
203
+ occurrences.set(`${primitive}:${start}`, { primitive, start, end });
204
+ };
205
+ for (const match of masked.matchAll(
206
+ /["'`](load-buffer|paste-buffer|send-keys|capture-pane|pipe-pane|set-buffer)["'`]/g,
207
+ )) {
208
+ add(match[1] as TmuxMachineBusPrimitive, match.index ?? 0, (match.index ?? 0) + match[0].length);
209
+ }
210
+ for (const match of masked.matchAll(/\b(load-buffer|paste-buffer|send-keys|capture-pane|pipe-pane|set-buffer)\b/g)) {
211
+ add(match[1] as TmuxMachineBusPrimitive, match.index ?? 0, (match.index ?? 0) + match[0].length);
212
+ }
213
+ for (const primitive of tmuxMachineBusPrimitives) {
214
+ const [prefix, suffix] = primitive.split("-");
215
+ const construction = new RegExp(
216
+ "(?:\\[\\s*[\"']" +
217
+ prefix +
218
+ "[\"']\\s*,\\s*[\"']-?" +
219
+ suffix +
220
+ "[\"']\\s*\\]\\s*\\.join\\(\\s*[\"']-?[\"']\\s*\\)|[\"']" +
221
+ prefix +
222
+ "[\"']\\s*\\+\\s*[\"']-?" +
223
+ suffix +
224
+ "[\"']|`(?:" +
225
+ prefix +
226
+ "|\\$\\{\\s*[\"']" +
227
+ prefix +
228
+ "[\"']\\s*\\})-(?:" +
229
+ suffix +
230
+ "|\\$\\{\\s*[\"']" +
231
+ suffix +
232
+ "[\"']\\s*\\})`)",
233
+ "g",
234
+ );
235
+ for (const match of masked.matchAll(construction)) {
236
+ add(primitive, match.index ?? 0, (match.index ?? 0) + match[0].length);
237
+ }
238
+ }
239
+ for (const assignment of assignments) {
240
+ const value = bindings.get(assignment.name);
241
+ if (value && tmuxMachineBusPrimitives.includes(value as TmuxMachineBusPrimitive)) {
242
+ add(value as TmuxMachineBusPrimitive, assignment.start, assignment.start + assignment.expression.length);
243
+ }
244
+ }
245
+ return [...occurrences.values()].sort((left, right) => left.start - right.start);
246
+ }
247
+
248
+ function resolveExportTarget(exports: Record<string, unknown>, subpath: string): unknown {
249
+ if (Object.hasOwn(exports, subpath)) return exports[subpath];
250
+ const candidates = Object.entries(exports)
251
+ .filter(([key]) => key.includes("*"))
252
+ .map(([key, target]) => {
253
+ const [prefix, suffix] = key.split("*");
254
+ return subpath.startsWith(prefix) && subpath.endsWith(suffix) ? { key, target } : undefined;
255
+ })
256
+ .filter((candidate): candidate is { key: string; target: unknown } => candidate !== undefined)
257
+ .sort((left, right) => right.key.length - left.key.length);
258
+ return candidates[0]?.target;
259
+ }
260
+
261
+ function exportTargetStrings(target: unknown): string[] {
262
+ if (typeof target === "string") return [target];
263
+ if (!target || typeof target !== "object") return [];
264
+ return Object.values(target as Record<string, unknown>).flatMap(exportTargetStrings);
265
+ }
266
+
267
+ function retiredIngressSource(file: string): boolean {
268
+ return /\/src\/(?:modes\/(?:rpc|bridge|unattended)[A-Za-z0-9_.-]*(?:\/|$)|(?:rpc|bridge|unattended)[A-Za-z0-9_.-]*(?:\/|\.[cm]?[jt]sx?$))/i.test(
269
+ file,
270
+ );
271
+ }
272
+
273
+ function broadExportReachesSource(
274
+ exports: Record<string, unknown>,
275
+ exportPath: string,
276
+ target: unknown,
277
+ sourcePath: string,
278
+ ): boolean {
279
+ for (const targetPath of exportTargetStrings(target)) {
280
+ if (!targetPath.includes("*")) continue;
281
+ const [prefix, suffix] = targetPath.split("*");
282
+ if (!sourcePath.startsWith(prefix) || !sourcePath.endsWith(suffix)) continue;
283
+ const wildcard = sourcePath.slice(prefix.length, sourcePath.length - suffix.length);
284
+ const resolved = resolveExportTarget(exports, exportPath.replace("*", wildcard));
285
+ if (exportTargetStrings(resolved).length > 0) return true;
286
+ }
287
+ return false;
288
+ }
289
+
290
+ function isPython(file: string): boolean {
291
+ return file.endsWith(".py");
292
+ }
293
+
294
+ function isPythonDistributionMetadata(file: string): boolean {
295
+ return /(?:^|\/)(?:pyproject\.toml|setup\.(?:py|cfg)|requirements(?:[-._][^/]*)?\.txt)$/.test(file);
296
+ }
297
+
298
+ function isPackageMetadata(file: string): boolean {
299
+ return file.endsWith("package.json") || isPythonDistributionMetadata(file);
300
+ }
301
+
302
+ function isGeneratedDocumentationIndex(file: string): boolean {
303
+ return file === "packages/coding-agent/src/internal-urls/docs-index.generated.ts";
304
+ }
305
+
306
+ function isHistoricalLegacyPythonRpcArtifact(file: string): boolean {
307
+ return (
308
+ file.startsWith("artifacts/") ||
309
+ file.startsWith("issues/") ||
310
+ file.includes("/artifacts/") ||
311
+ file.includes("/issues/") ||
312
+ /(?:^|\/)(?:CHANGELOG|HISTORY)\.[^/]+$/i.test(file)
313
+ );
314
+ }
315
+
316
+ function isActiveLegacyPythonRpcTarget(file: string): boolean {
317
+ if (
318
+ isGeneratedDocumentationIndex(file) ||
319
+ isHistoricalLegacyPythonRpcArtifact(file) ||
320
+ /(?:^|\/)(?:test|tests|fixtures)(?:\/|$)/.test(file)
321
+ )
322
+ return false;
323
+ if (isPackageMetadata(file)) return true;
324
+ return (
325
+ file.startsWith("src/") ||
326
+ file.startsWith("scripts/") ||
327
+ /^(?:packages|python)\/[^/]+\/(?:src|scripts)\//.test(file)
328
+ );
329
+ }
330
+
331
+ function legacyPythonRpcViolations(file: string, contents: string): string[] {
332
+ const violations: string[] = [];
333
+ if (isPython(file)) {
334
+ for (const match of contents.matchAll(pythonSkcRpcImportPattern)) {
335
+ violations.push(`${file}:${lineNumber(contents, match.index ?? 0)}: imports removed skc_rpc Python client`);
336
+ }
337
+ for (const match of contents.matchAll(pythonUnattendedProtocolClientPattern)) {
338
+ violations.push(
339
+ `${file}:${lineNumber(contents, match.index ?? 0)}: uses removed Python unattended protocol client ${match[0]}`,
340
+ );
341
+ }
342
+ }
343
+ if (isPythonDistributionMetadata(file)) {
344
+ for (const match of contents.matchAll(/\bskc-rpc\b/gi)) {
345
+ violations.push(
346
+ `${file}:${lineNumber(contents, match.index ?? 0)}: declares removed skc-rpc distribution metadata`,
347
+ );
348
+ }
349
+ }
350
+ return violations;
351
+ }
352
+
353
+ type RetiredModeSourceType = "unambiguous" | "commonjs" | "module";
354
+ type StaticAnalysisBudgetKind = "file_steps" | "expression_steps" | "alias_hops";
355
+ type StaticStringResult = { kind: "known"; value: string } | { kind: "unknown"; reason: string };
356
+ type StaticArrayResult = { kind: "known"; values: string[] } | { kind: "unknown"; reason: string };
357
+ type StaticDefinitionResult = { kind: "definition"; definition: StaticDefinition } | StaticStringResult;
358
+
359
+ interface RetiredModeParserOptions {
360
+ sourceType: RetiredModeSourceType;
361
+ plugins: ParserPlugin[];
362
+ }
363
+
364
+ interface StaticAnalysisFileState {
365
+ steps: number;
366
+ }
367
+
368
+ interface StaticEvaluationContext {
369
+ file: string;
370
+ expressionSteps: number;
371
+ aliasHops: number;
372
+ activeBindings: Set<Binding>;
373
+ evaluationSteps: NodePath<t.Expression>[];
374
+ }
375
+
376
+ interface StaticDefinition {
377
+ expressionPath: NodePath<t.Expression>;
378
+ start: number;
379
+ end: number;
380
+ }
381
+
382
+ class StaticAnalysisParseError extends Error {
383
+ constructor(file: string, line: number, column: number) {
384
+ super(`${file}:${line}:${column}: static retired-mode analysis parse failed`);
385
+ this.name = "StaticAnalysisParseError";
386
+ }
387
+ }
388
+
389
+ class StaticAnalysisBudgetExceeded extends Error {
390
+ constructor(file: string, node: t.Node, kind: StaticAnalysisBudgetKind, limit: number, observed: number) {
391
+ const location = staticNodeLocation(node);
392
+ super(
393
+ `${file}:${location.line}:${location.column}: static retired-mode analysis budget exceeded (kind=${kind}, limit=${limit}, observed=${observed})`,
394
+ );
395
+ this.name = "StaticAnalysisBudgetExceeded";
396
+ }
397
+ }
398
+
399
+ function isExecutableSource(file: string): boolean {
400
+ return /\.(?:[cm]?[jt]sx?|py)$/.test(file);
401
+ }
402
+
403
+ function retiredModeParserOptions(file: string): RetiredModeParserOptions | undefined {
404
+ const importAttributePlugins: ParserPlugin[] = ["importAttributes"];
405
+ if (file.endsWith(".d.mts")) {
406
+ return {
407
+ sourceType: "module",
408
+ plugins: [["typescript", { dts: true, disallowAmbiguousJSXLike: true }]],
409
+ };
410
+ }
411
+ if (file.endsWith(".d.cts")) {
412
+ return {
413
+ sourceType: "commonjs",
414
+ plugins: [["typescript", { dts: true, disallowAmbiguousJSXLike: true }]],
415
+ };
416
+ }
417
+ if (file.endsWith(".d.ts")) {
418
+ return { sourceType: "unambiguous", plugins: [["typescript", { dts: true }]] };
419
+ }
420
+ if (file.endsWith(".tsx")) return { sourceType: "unambiguous", plugins: ["typescript", "jsx"] };
421
+ if (file.endsWith(".mts")) {
422
+ return {
423
+ sourceType: "unambiguous",
424
+ plugins: [["typescript", { disallowAmbiguousJSXLike: true }]],
425
+ };
426
+ }
427
+ if (file.endsWith(".cts")) {
428
+ return {
429
+ sourceType: "commonjs",
430
+ plugins: [["typescript", { disallowAmbiguousJSXLike: true }]],
431
+ };
432
+ }
433
+ if (file.endsWith(".ts")) return { sourceType: "unambiguous", plugins: ["typescript"] };
434
+ if (file.endsWith(".jsx")) return { sourceType: "unambiguous", plugins: ["jsx", ...importAttributePlugins] };
435
+ if (file.endsWith(".cjs")) return { sourceType: "commonjs", plugins: importAttributePlugins };
436
+ if (file.endsWith(".js") || file.endsWith(".mjs")) {
437
+ return { sourceType: "unambiguous", plugins: importAttributePlugins };
438
+ }
439
+ return undefined;
440
+ }
441
+
442
+ function parserErrorLocation(error: unknown): { line: number; column: number } {
443
+ const parserError = error as { loc?: unknown };
444
+ const location = parserError.loc;
445
+ if (location && typeof location === "object") {
446
+ const parserLocation = location as { line?: unknown; column?: unknown };
447
+ if (typeof parserLocation.line === "number" && typeof parserLocation.column === "number") {
448
+ return { line: parserLocation.line, column: parserLocation.column };
449
+ }
450
+ }
451
+ return { line: 1, column: 0 };
452
+ }
453
+
454
+ function parseRetiredModeSource(file: string, contents: string): t.File | undefined {
455
+ const options = retiredModeParserOptions(file);
456
+ if (!options) return undefined;
457
+ try {
458
+ return parse(contents, options);
459
+ } catch (error) {
460
+ const location = parserErrorLocation(error);
461
+ throw new StaticAnalysisParseError(file, location.line, location.column);
462
+ }
463
+ }
464
+
465
+ function staticNodeLocation(node: t.Node): { line: number; column: number } {
466
+ return { line: node.loc?.start.line ?? 1, column: node.loc?.start.column ?? 0 };
467
+ }
468
+
469
+ function staticNodeOffset(node: t.Node): number | undefined {
470
+ return typeof node.start === "number" ? node.start : undefined;
471
+ }
472
+
473
+ function staticNodeEnd(node: t.Node): number | undefined {
474
+ return typeof node.end === "number" ? node.end : undefined;
475
+ }
476
+
477
+ function staticKnown(value: string): StaticStringResult {
478
+ return { kind: "known", value };
479
+ }
480
+
481
+ function staticUnknown(reason: string): StaticStringResult {
482
+ return { kind: "unknown", reason };
483
+ }
484
+
485
+ function staticExpressionPath(path: NodePath, key: string): NodePath<t.Expression> | undefined {
486
+ const childPath = path.get(key) as NodePath | NodePath[];
487
+ if (Array.isArray(childPath) || !childPath.isExpression()) return undefined;
488
+ return childPath;
489
+ }
490
+
491
+ function staticExecutionContext(path: NodePath): NodePath | undefined {
492
+ let current: NodePath | null = path;
493
+ while (current) {
494
+ if (current.isProgram() || current.isFunction()) return current;
495
+ current = current.parentPath;
496
+ }
497
+ return undefined;
498
+ }
499
+
500
+ function isExecutionContextAncestor(ancestor: NodePath, descendant: NodePath): boolean {
501
+ let current: NodePath | null = descendant;
502
+ while (current) {
503
+ if (current.node === ancestor.node) return true;
504
+ current = current.parentPath;
505
+ }
506
+ return false;
507
+ }
508
+
509
+ function recordStaticEvaluationStep(path: NodePath<t.Expression>, context: StaticEvaluationContext): void {
510
+ context.evaluationSteps.push(path);
511
+ context.expressionSteps++;
512
+ if (context.expressionSteps > MAX_STATIC_EXPRESSION_STEPS) {
513
+ throw new StaticAnalysisBudgetExceeded(
514
+ context.file,
515
+ path.node,
516
+ "expression_steps",
517
+ MAX_STATIC_EXPRESSION_STEPS,
518
+ context.expressionSteps,
519
+ );
520
+ }
521
+ }
522
+
523
+ function commitStaticFileSteps(
524
+ evaluationSteps: readonly NodePath<t.Expression>[],
525
+ file: string,
526
+ fileState: StaticAnalysisFileState,
527
+ ): void {
528
+ for (const path of evaluationSteps) {
529
+ fileState.steps++;
530
+ if (fileState.steps > MAX_STATIC_FILE_STEPS) {
531
+ throw new StaticAnalysisBudgetExceeded(file, path.node, "file_steps", MAX_STATIC_FILE_STEPS, fileState.steps);
532
+ }
533
+ }
534
+ }
535
+
536
+ function incrementStaticAliasHop(path: NodePath<t.Identifier>, context: StaticEvaluationContext): void {
537
+ context.aliasHops++;
538
+ if (context.aliasHops > MAX_STATIC_ALIAS_HOPS) {
539
+ throw new StaticAnalysisBudgetExceeded(
540
+ context.file,
541
+ path.node,
542
+ "alias_hops",
543
+ MAX_STATIC_ALIAS_HOPS,
544
+ context.aliasHops,
545
+ );
546
+ }
547
+ }
548
+
549
+ function bindingInitializer(binding: Binding): StaticDefinitionResult {
550
+ if (!binding.path.isVariableDeclarator()) return staticUnknown("unsupported binding");
551
+ const declaration = binding.path.node;
552
+ if (!t.isIdentifier(declaration.id) || declaration.id.name !== binding.identifier.name) {
553
+ return staticUnknown("unsupported binding");
554
+ }
555
+ const initializerPath = staticExpressionPath(binding.path, "init");
556
+ if (!initializerPath) return staticUnknown("missing initializer");
557
+ const start = staticNodeOffset(initializerPath.node);
558
+ const end = staticNodeEnd(initializerPath.node);
559
+ if (start === undefined || end === undefined) return staticUnknown("missing initializer position");
560
+ return { kind: "definition", definition: { expressionPath: initializerPath, start, end } };
561
+ }
562
+
563
+ function assignmentPathForViolation(violationPath: NodePath): NodePath<t.AssignmentExpression> | undefined {
564
+ if (violationPath.isAssignmentExpression()) return violationPath;
565
+ const parentPath = violationPath.parentPath;
566
+ if (parentPath?.isAssignmentExpression() && parentPath.node.left === violationPath.node) return parentPath;
567
+ return undefined;
568
+ }
569
+
570
+ function staticAssignmentDefinition(binding: Binding, violationPath: NodePath): StaticDefinitionResult {
571
+ const assignmentPath = assignmentPathForViolation(violationPath);
572
+ if (assignmentPath?.node.operator !== "=") return staticUnknown("unsupported write");
573
+ if (!t.isIdentifier(assignmentPath.node.left)) return staticUnknown("unsupported write");
574
+ if (assignmentPath.scope.getBinding(assignmentPath.node.left.name) !== binding) {
575
+ return staticUnknown("unsupported write");
576
+ }
577
+ if (!assignmentPath.parentPath?.isExpressionStatement()) return staticUnknown("ambiguous write");
578
+ const expressionPath = staticExpressionPath(assignmentPath, "right");
579
+ if (!expressionPath) return staticUnknown("unsupported write");
580
+ const start = staticNodeOffset(assignmentPath.node);
581
+ const end = staticNodeEnd(assignmentPath.node);
582
+ if (start === undefined || end === undefined) return staticUnknown("missing write position");
583
+ return { kind: "definition", definition: { expressionPath, start, end } };
584
+ }
585
+
586
+ function isUnambiguousStaticWrite(path: NodePath<t.AssignmentExpression>, context: NodePath): boolean {
587
+ let current: NodePath | null = path.parentPath;
588
+ while (current && current.node !== context.node) {
589
+ if (
590
+ current.isIfStatement() ||
591
+ current.isSwitchCase() ||
592
+ current.isForStatement() ||
593
+ current.isForInStatement() ||
594
+ current.isForOfStatement() ||
595
+ current.isWhileStatement() ||
596
+ current.isDoWhileStatement() ||
597
+ current.isTryStatement() ||
598
+ current.isConditionalExpression() ||
599
+ current.isLogicalExpression()
600
+ ) {
601
+ return false;
602
+ }
603
+ current = current.parentPath;
604
+ }
605
+ return current !== null;
606
+ }
607
+
608
+ function staticReachingDefinition(identifierPath: NodePath<t.Identifier>, binding: Binding): StaticDefinitionResult {
609
+ const initialDefinition = bindingInitializer(binding);
610
+ if (initialDefinition.kind !== "definition") return initialDefinition;
611
+ const useOffset = staticNodeOffset(identifierPath.node);
612
+ const bindingContext = staticExecutionContext(binding.path);
613
+ const useContext = staticExecutionContext(identifierPath);
614
+ if (useOffset === undefined || !bindingContext || !useContext) return staticUnknown("missing use position");
615
+ if (bindingContext.node !== useContext.node) {
616
+ if (binding.kind !== "const" || !binding.constant || !isExecutionContextAncestor(bindingContext, useContext)) {
617
+ return staticUnknown("ambiguous cross-context binding");
618
+ }
619
+ return initialDefinition;
620
+ }
621
+ if (initialDefinition.definition.end > useOffset) return staticUnknown("direct TDZ");
622
+
623
+ let selectedDefinition = initialDefinition.definition;
624
+ for (const violationPath of binding.constantViolations) {
625
+ const violationContext = staticExecutionContext(violationPath);
626
+ if (!violationContext || violationContext.node !== bindingContext.node) {
627
+ return staticUnknown("ambiguous cross-context write");
628
+ }
629
+ const violationOffset = staticNodeOffset(violationPath.node);
630
+ if (violationOffset === undefined) return staticUnknown("missing write position");
631
+ if (violationOffset >= useOffset) continue;
632
+ const writeDefinition = staticAssignmentDefinition(binding, violationPath);
633
+ if (writeDefinition.kind !== "definition") return writeDefinition;
634
+ if (writeDefinition.definition.end > useOffset) return staticUnknown("ambiguous write order");
635
+ const assignmentPath = assignmentPathForViolation(violationPath);
636
+ if (!assignmentPath || !isUnambiguousStaticWrite(assignmentPath, bindingContext)) {
637
+ return staticUnknown("ambiguous write");
638
+ }
639
+ if (writeDefinition.definition.start === selectedDefinition.start) return staticUnknown("ambiguous write order");
640
+ if (writeDefinition.definition.start > selectedDefinition.start) selectedDefinition = writeDefinition.definition;
641
+ }
642
+ return { kind: "definition", definition: selectedDefinition };
643
+ }
644
+
645
+ function evaluateStaticArrayElements(
646
+ path: NodePath<t.ArrayExpression>,
647
+ context: StaticEvaluationContext,
648
+ ): StaticArrayResult {
649
+ recordStaticEvaluationStep(path, context);
650
+ const elementPaths = path.get("elements");
651
+ if (!Array.isArray(elementPaths)) return { kind: "unknown", reason: "unsupported array" };
652
+ const values: string[] = [];
653
+ for (const elementPath of elementPaths) {
654
+ if (!elementPath.isExpression()) return { kind: "unknown", reason: "unsupported array element" };
655
+ const value = evaluateStaticString(elementPath, context);
656
+ if (value.kind !== "known") return value;
657
+ values.push(value.value);
658
+ }
659
+ return { kind: "known", values };
660
+ }
661
+
662
+ function evaluateStaticJoin(path: NodePath<t.CallExpression>, context: StaticEvaluationContext): StaticStringResult {
663
+ if (path.node.optional) return staticUnknown("unsupported call");
664
+ const calleePath = staticExpressionPath(path, "callee");
665
+ if (!calleePath?.isMemberExpression()) return staticUnknown("unsupported call");
666
+ if (
667
+ calleePath.node.computed ||
668
+ calleePath.node.optional ||
669
+ !t.isIdentifier(calleePath.node.property, { name: "join" })
670
+ ) {
671
+ return staticUnknown("unsupported call");
672
+ }
673
+ const objectPath = staticExpressionPath(calleePath, "object");
674
+ if (!objectPath?.isArrayExpression()) return staticUnknown("unsupported call");
675
+ const argumentPaths = path.get("arguments");
676
+ if (!Array.isArray(argumentPaths) || argumentPaths.length > 1) return staticUnknown("unsupported call");
677
+ let separator = ",";
678
+ if (argumentPaths.length === 1) {
679
+ const separatorPath = argumentPaths[0];
680
+ if (!separatorPath.isExpression()) return staticUnknown("unsupported call");
681
+ const separatorResult = evaluateStaticString(separatorPath, context);
682
+ if (separatorResult.kind !== "known") return separatorResult;
683
+ separator = separatorResult.value;
684
+ }
685
+ const arrayResult = evaluateStaticArrayElements(objectPath as NodePath<t.ArrayExpression>, context);
686
+ return arrayResult.kind === "known" ? staticKnown(arrayResult.values.join(separator)) : arrayResult;
687
+ }
688
+
689
+ function evaluateStaticIdentifier(path: NodePath<t.Identifier>, context: StaticEvaluationContext): StaticStringResult {
690
+ const binding = path.scope.getBinding(path.node.name);
691
+ if (!binding) return staticUnknown("missing binding");
692
+ if (context.activeBindings.has(binding)) return staticUnknown("binding cycle");
693
+ const definition = staticReachingDefinition(path, binding);
694
+ if (definition.kind !== "definition") return definition;
695
+ context.activeBindings.add(binding);
696
+ try {
697
+ incrementStaticAliasHop(path, context);
698
+ return evaluateStaticString(definition.definition.expressionPath, context);
699
+ } finally {
700
+ context.activeBindings.delete(binding);
701
+ }
702
+ }
703
+
704
+ function evaluateStaticString(path: NodePath<t.Expression>, context: StaticEvaluationContext): StaticStringResult {
705
+ recordStaticEvaluationStep(path, context);
706
+ const node = path.node;
707
+ if (t.isStringLiteral(node)) return staticKnown(node.value);
708
+ if (t.isIdentifier(node)) return evaluateStaticIdentifier(path as NodePath<t.Identifier>, context);
709
+ if (
710
+ t.isTSAsExpression(node) ||
711
+ t.isTSTypeAssertion(node) ||
712
+ t.isTSSatisfiesExpression(node) ||
713
+ t.isTSNonNullExpression(node) ||
714
+ t.isParenthesizedExpression(node)
715
+ ) {
716
+ const expressionPath = staticExpressionPath(path, "expression");
717
+ return expressionPath ? evaluateStaticString(expressionPath, context) : staticUnknown("unsupported wrapper");
718
+ }
719
+ if (t.isTemplateLiteral(node)) {
720
+ const expressionPaths = path.get("expressions");
721
+ if (!Array.isArray(expressionPaths) || expressionPaths.length !== node.expressions.length) {
722
+ return staticUnknown("unsupported template");
723
+ }
724
+ let value = "";
725
+ for (let index = 0; index < node.quasis.length; index++) {
726
+ const cooked = node.quasis[index]?.value.cooked;
727
+ if (cooked === null || cooked === undefined) return staticUnknown("unsupported template");
728
+ value += cooked;
729
+ if (index === expressionPaths.length) continue;
730
+ const expressionPath = expressionPaths[index];
731
+ if (!expressionPath.isExpression()) return staticUnknown("unsupported template");
732
+ const expressionResult = evaluateStaticString(expressionPath, context);
733
+ if (expressionResult.kind !== "known") return expressionResult;
734
+ value += expressionResult.value;
735
+ }
736
+ return staticKnown(value);
737
+ }
738
+ if (t.isBinaryExpression(node) && node.operator === "+") {
739
+ const leftPath = staticExpressionPath(path, "left");
740
+ const rightPath = staticExpressionPath(path, "right");
741
+ if (!leftPath || !rightPath) return staticUnknown("unsupported binary expression");
742
+ const left = evaluateStaticString(leftPath, context);
743
+ if (left.kind !== "known") return left;
744
+ const right = evaluateStaticString(rightPath, context);
745
+ return right.kind === "known" ? staticKnown(left.value + right.value) : right;
746
+ }
747
+ if (t.isCallExpression(node)) return evaluateStaticJoin(path as NodePath<t.CallExpression>, context);
748
+ return staticUnknown("unsupported expression");
749
+ }
750
+
751
+ function isStaticModeCandidate(
752
+ elements: readonly ({ path: NodePath<t.Expression>; value: string | undefined } | undefined)[],
753
+ ): boolean {
754
+ return elements.some(element => element?.value === "--mode" || /^--mode(?:\s+|=)/.test(element?.value ?? ""));
755
+ }
756
+
757
+ function staticRetiredModeInvocationViolations(file: string, contents: string): string[] {
758
+ const ast = parseRetiredModeSource(file, contents);
759
+ if (!ast) return [];
760
+ const fileState: StaticAnalysisFileState = { steps: 0 };
761
+ const violations = new Set<string>();
762
+ traverse(ast, {
763
+ ArrayExpression(arrayPath) {
764
+ const elementPaths = arrayPath.get("elements");
765
+ if (!Array.isArray(elementPaths)) return;
766
+ const evaluationSteps: NodePath<t.Expression>[] = [];
767
+ const elements: Array<{ path: NodePath<t.Expression>; value: string | undefined } | undefined> = [];
768
+ for (const elementPath of elementPaths) {
769
+ if (!elementPath.isExpression()) {
770
+ elements.push(undefined);
771
+ continue;
772
+ }
773
+ const context: StaticEvaluationContext = {
774
+ file,
775
+ expressionSteps: 0,
776
+ aliasHops: 0,
777
+ activeBindings: new Set<Binding>(),
778
+ evaluationSteps,
779
+ };
780
+ const result = evaluateStaticString(elementPath, context);
781
+ elements.push({ path: elementPath, value: result.kind === "known" ? result.value : undefined });
782
+ }
783
+ if (!isStaticModeCandidate(elements)) return;
784
+ commitStaticFileSteps(evaluationSteps, file, fileState);
785
+ for (let index = 0; index < elements.length; index++) {
786
+ const current = elements[index];
787
+ if (!current?.value) continue;
788
+ const preceding = index > 0 ? elements[index - 1] : undefined;
789
+ if (
790
+ !retiredModeArgumentPattern.test(current.value) &&
791
+ !(preceding?.value === "--mode" && retiredModeValuePattern.test(current.value))
792
+ )
793
+ continue;
794
+ const violationPath = preceding?.value === "--mode" ? preceding.path : current.path;
795
+ violations.add(`${file}:${staticNodeLocation(violationPath.node).line}: invokes removed --mode rpc`);
796
+ }
797
+ },
798
+ });
799
+ return [...violations];
800
+ }
801
+
802
+ function legacyRpcModeAliasViolations(file: string, contents: string): string[] {
803
+ const { masked, values: bindings } = staticStringBindings(contents);
804
+ const violations: string[] = [];
805
+ for (const match of masked.matchAll(/\[[^\]\r\n]*\]/g)) {
806
+ const argv = match[0].slice(1, -1).split(",");
807
+ for (let index = 0; index < argv.length; index++) {
808
+ const expression = argv[index].trim();
809
+ if (!/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(expression)) continue;
810
+ const value = staticStringValue(expression, bindings);
811
+ const preceding = index > 0 ? staticStringValue(argv[index - 1], bindings) : undefined;
812
+ if (
813
+ value !== undefined &&
814
+ (retiredModeArgumentPattern.test(value) || (preceding === "--mode" && retiredModeValuePattern.test(value)))
815
+ ) {
816
+ violations.push(`${file}:${lineNumber(contents, match.index ?? 0)}: invokes removed --mode rpc`);
817
+ }
818
+ }
819
+ }
820
+ return violations;
821
+ }
822
+
823
+ function rpcModeInvocationViolations(file: string, contents: string): string[] {
824
+ if (isGeneratedDocumentationIndex(file) || !isExecutableSource(file) || allowedRpcModeInvocationTests.has(file))
825
+ return [];
826
+ const patterns = [...retiredExternalModeInvocationPatterns, ...constructedRetiredIngressPatterns];
827
+ const violations = patterns.flatMap(pattern =>
828
+ [...contents.matchAll(pattern)].map(
829
+ match => `${file}:${lineNumber(contents, match.index ?? 0)}: invokes removed --mode rpc`,
830
+ ),
831
+ );
832
+ if (retiredModeParserOptions(file)) {
833
+ violations.push(...staticRetiredModeInvocationViolations(file, contents));
834
+ } else {
835
+ violations.push(...legacyRpcModeAliasViolations(file, contents));
836
+ }
837
+ return [...new Set(violations)];
838
+ }
839
+
840
+ function bridgeClientPackageMetadataViolation(file: string, contents: string): string | undefined {
841
+ if (
842
+ !file.endsWith("package.json") ||
843
+ (file !== bridgeClientPackageManifestPath && !contents.includes(bridgeClientPackageName))
844
+ )
845
+ return undefined;
846
+ try {
847
+ const manifest = JSON.parse(contents) as {
848
+ catalog?: Record<string, unknown>;
849
+ dependencies?: Record<string, unknown>;
850
+ name?: unknown;
851
+ optionalDependencies?: Record<string, unknown>;
852
+ peerDependencies?: Record<string, unknown>;
853
+ workspaces?: { catalog?: Record<string, unknown> };
854
+ };
855
+ if (file === bridgeClientPackageManifestPath) {
856
+ if (manifest.name !== bridgeClientPackageName)
857
+ return `${file}: is not the canonical bridge-client package manifest`;
858
+ if (
859
+ Object.keys(manifest.dependencies ?? {}).length > 0 ||
860
+ Object.keys(manifest.peerDependencies ?? {}).length > 0 ||
861
+ Object.keys(manifest.optionalDependencies ?? {}).length > 0
862
+ )
863
+ return `${file}: canonical bridge-client package must remain runtime-dependency-free`;
864
+ return undefined;
865
+ }
866
+ if (
867
+ file === "package.json" &&
868
+ (typeof manifest.catalog?.[bridgeClientPackageName] === "string" ||
869
+ typeof manifest.workspaces?.catalog?.[bridgeClientPackageName] === "string")
870
+ )
871
+ return undefined;
872
+ if (file === packageManifestPath && typeof manifest.dependencies?.[bridgeClientPackageName] === "string")
873
+ return undefined;
874
+ } catch {
875
+ return `${file}: declares unsupported bridge-client package metadata`;
876
+ }
877
+
878
+ return `${file}: declares unsupported bridge-client package metadata`;
879
+ }
880
+
881
+ function bridgeClientImportViolations(file: string, contents: string): string[] {
882
+ const violations: string[] = [];
883
+ for (const match of contents.matchAll(bridgeClientImportPattern)) {
884
+ const specifier = match[1];
885
+ const start = match.index ?? 0;
886
+ if (specifier !== bridgeClientPackageName) {
887
+ violations.push(`${file}:${lineNumber(contents, start)}: imports unsupported bridge-client subpath`);
888
+ continue;
889
+ }
890
+ const statementStart = Math.max(contents.lastIndexOf(";", start), contents.lastIndexOf("\n", start - 512));
891
+ const statement = contents.slice(statementStart + 1, start);
892
+ if (legacyBridgeClientSurfacePattern.test(statement)) {
893
+ violations.push(`${file}:${lineNumber(contents, start)}: imports historical bridge-client protocol surface`);
894
+ }
895
+ }
896
+ if (!isGeneratedDocumentationIndex(file) && /\.[cm]?[jt]sx?$/u.test(file) && /\bBridgeClient\b/.test(contents)) {
897
+ violations.push(`${file}: historical BridgeClient surface survived`);
898
+ }
899
+ return violations;
900
+ }
901
+
902
+ function bridgeClientOwnershipViolations(file: string, contents: string): string[] {
903
+ if (!file.startsWith("packages/bridge-client/src/") || !/\.(?:[cm]?[jt]sx?)$/u.test(file)) return [];
904
+ const violations: string[] = [];
905
+ for (const match of contents.matchAll(relativeImportPattern)) {
906
+ const specifier = match[1] ?? match[2];
907
+ const start = match.index ?? 0;
908
+ if (
909
+ specifier.startsWith(".") &&
910
+ !path.posix
911
+ .normalize(path.posix.join(path.posix.dirname(file), specifier))
912
+ .startsWith("packages/bridge-client/")
913
+ ) {
914
+ violations.push(`${file}:${lineNumber(contents, start)}: bridge-client import escapes its package`);
915
+ }
916
+ if (
917
+ /(?:^|\/)(?:coding-agent|agent-session|sdk\/(?:host|session)|session)(?:\/|$)|@sayknow-cli\/coding-agent/.test(
918
+ specifier,
919
+ )
920
+ ) {
921
+ violations.push(
922
+ `${file}:${lineNumber(contents, start)}: bridge-client imports coding-agent or AgentSession authority`,
923
+ );
924
+ }
925
+ if (/\b(?:AgentSession|SessionManager|SessionHost|HostControl|SdkHost|SDKHost|HostSession)\b/.test(match[0])) {
926
+ violations.push(`${file}:${lineNumber(contents, start)}: bridge-client imports host or session authority`);
927
+ }
928
+ if (/^node:(?:net|http|https|child_process)(?:\/|$)/.test(specifier)) {
929
+ violations.push(
930
+ `${file}:${lineNumber(contents, start)}: bridge-client imports server or process ownership module ${specifier}`,
931
+ );
932
+ }
933
+ if (legacyBridgeClientSurfacePattern.test(match[0])) {
934
+ violations.push(`${file}:${lineNumber(contents, start)}: bridge-client imports historical protocol surface`);
935
+ }
936
+ }
937
+ for (const pattern of [
938
+ /\b(?:AgentSession|SessionManager|SessionHost|HostControl|SdkHost|SDKHost|HostSession)\b/g,
939
+ /\b(?:Bun\.serve|(?:createServer|createSecureServer)\s*\(|\.listen\s*\(|(?:spawn|spawnSync|exec|execFile|fork)\s*\(|process\.)/g,
940
+ ]) {
941
+ for (const match of contents.matchAll(pattern)) {
942
+ violations.push(
943
+ `${file}:${lineNumber(contents, match.index ?? 0)}: bridge-client owns forbidden host, session, server, listener, or process authority`,
944
+ );
945
+ }
946
+ }
947
+ for (const match of contents.matchAll(/\b(?:BridgeClient|handshake|commands|SSE)\b/g)) {
948
+ violations.push(
949
+ `${file}:${lineNumber(contents, match.index ?? 0)}: bridge-client retains historical protocol symbol ${match[0]}`,
950
+ );
951
+ }
952
+ return [...new Set(violations)];
953
+ }
954
+
955
+ // These are the only server owners permitted to couple a listener to session/control internals.
956
+ const sanctionedServerHosts = new Map<string, string>([
957
+ [
958
+ "packages/coding-agent/src/sdk/bus/index.ts",
959
+ "NotificationServer is the SDK-owned notification host and wires the sanctioned SDK control surface.",
960
+ ],
961
+ [
962
+ "packages/coding-agent/src/sdk/broker/transport.ts",
963
+ "BrokerTransport is the SDK-owned broker WebSocket transport.",
964
+ ],
965
+ [
966
+ "packages/coding-agent/src/harness-control-plane/control-endpoint.ts",
967
+ "ControlServer owns a private owner-local Unix socket; it is not an external session server.",
968
+ ],
969
+ ]);
970
+
971
+ function commandOutput(command: string[]): string {
972
+ const result = Bun.spawnSync(command, { cwd: repoRoot, stdout: "pipe", stderr: "pipe" });
973
+ if (result.exitCode !== 0) {
974
+ throw new Error(`${command.join(" ")} failed: ${new TextDecoder().decode(result.stderr)}`);
975
+ }
976
+ return new TextDecoder().decode(result.stdout);
977
+ }
978
+
979
+ function isSource(file: string): boolean {
980
+ return /\.(?:[cm]?[jt]sx?|json|py|toml)$/.test(file);
981
+ }
982
+
983
+ const teamRuntimeTmuxPath = "packages/coding-agent/src/skc-runtime/team-runtime.ts";
984
+ const teamWorkersTmuxPath = "packages/coding-agent/src/skc-runtime/team-workers.ts";
985
+
986
+ const coordinatorMcpRoot = "packages/coding-agent/src/coordinator-mcp/server.ts";
987
+ function isPublishedSkcSessionShellHelper(file: string): boolean {
988
+ return file.startsWith("scripts/skc-session/") && file.endsWith(".sh");
989
+ }
990
+
991
+ interface ShellStructure {
992
+ parentheses: number;
993
+ braces: number;
994
+ controls: number;
995
+ }
996
+
997
+ function shellStructureBefore(contents: string, offset: number): ShellStructure {
998
+ const structure: ShellStructure = { parentheses: 0, braces: 0, controls: 0 };
999
+ let quote: "'" | '"' | undefined;
1000
+ let word = "";
1001
+ const commitWord = () => {
1002
+ if (["if", "while", "until", "for", "case", "select"].includes(word)) structure.controls++;
1003
+ if (["fi", "done", "esac"].includes(word)) structure.controls = Math.max(0, structure.controls - 1);
1004
+ word = "";
1005
+ };
1006
+ for (let index = 0; index < offset; index++) {
1007
+ const character = contents[index];
1008
+ if (quote) {
1009
+ if (character === "\\" && quote === '"') index++;
1010
+ else if (character === quote) quote = undefined;
1011
+ continue;
1012
+ }
1013
+ if (character === "'" || character === '"') {
1014
+ commitWord();
1015
+ quote = character;
1016
+ continue;
1017
+ }
1018
+ if (character === "#") {
1019
+ commitWord();
1020
+ while (index < offset && contents[index] !== "\n") index++;
1021
+ continue;
1022
+ }
1023
+ if (/[A-Za-z_]/.test(character)) {
1024
+ word += character;
1025
+ continue;
1026
+ }
1027
+ if (/[0-9]/.test(character) && word) {
1028
+ word += character;
1029
+ continue;
1030
+ }
1031
+ commitWord();
1032
+ if (character === "(") structure.parentheses++;
1033
+ if (character === ")") structure.parentheses = Math.max(0, structure.parentheses - 1);
1034
+ if (character === "{" && contents[index - 1] !== "$") structure.braces++;
1035
+ if (character === "}") structure.braces = Math.max(0, structure.braces - 1);
1036
+ }
1037
+ commitWord();
1038
+ return structure;
1039
+ }
1040
+
1041
+ function hasLeadingShellContinuation(contents: string, offset: number): boolean {
1042
+ const lines = normalizeShellContinuations(contents.slice(0, offset)).split(/\r?\n/);
1043
+ for (let index = lines.length - 1; index >= 0; index--) {
1044
+ const line = lines[index].replace(/(?:^|\s)#.*$/, "").trim();
1045
+ if (line) return /(?:&&|\|\||\|)$/.test(line);
1046
+ }
1047
+ return false;
1048
+ }
1049
+
1050
+ function isUnconditionalTopLevelShellPosition(contents: string, offset: number): boolean {
1051
+ const structure = shellStructureBefore(contents, offset);
1052
+ if (structure.parentheses !== 0 || structure.braces !== 0 || structure.controls !== 0) return false;
1053
+ return !hasLeadingShellContinuation(contents, offset);
1054
+ }
1055
+
1056
+ interface ShellRange {
1057
+ start: number;
1058
+ end: number;
1059
+ }
1060
+
1061
+ function shellArrayAssignmentRanges(contents: string): ShellRange[] {
1062
+ const ranges: ShellRange[] = [];
1063
+ const assignments = /\b[A-Za-z_][A-Za-z0-9_]*\s*=\s*\(/g;
1064
+ for (const assignment of contents.matchAll(assignments)) {
1065
+ const openingParen = (assignment.index ?? 0) + assignment[0].lastIndexOf("(");
1066
+ let depth = 1;
1067
+ let quote: "'" | '"' | undefined;
1068
+ for (let index = openingParen + 1; index < contents.length; index++) {
1069
+ const character = contents[index];
1070
+ if (quote) {
1071
+ if (character === "\\" && quote === '"') index++;
1072
+ else if (character === quote) quote = undefined;
1073
+ continue;
1074
+ }
1075
+ if (character === "'" || character === '"') {
1076
+ quote = character;
1077
+ continue;
1078
+ }
1079
+ if (character === "(") depth++;
1080
+ if (character === ")") depth--;
1081
+ if (depth === 0) {
1082
+ ranges.push({ start: assignment.index ?? 0, end: index + 1 });
1083
+ break;
1084
+ }
1085
+ }
1086
+ }
1087
+ return ranges;
1088
+ }
1089
+
1090
+ function shellSkcBinaryReferenceViolations(contents: string): ShellRange[] {
1091
+ const normalizedContents = normalizeShellContinuations(contents);
1092
+ const arrayRanges = shellArrayAssignmentRanges(normalizedContents);
1093
+ const references = /(["']?)\$(?:SKC_BIN|SKC_SESSION_SKC_BIN|\{(?:SKC_BIN|SKC_SESSION_SKC_BIN)\})\1/g;
1094
+ const violations: ShellRange[] = [];
1095
+ for (const reference of normalizedContents.matchAll(references)) {
1096
+ const start = reference.index ?? 0;
1097
+ const before = normalizedContents.slice(0, start);
1098
+ if (/(?:^|[\s"'])SKC_SESSION_SKC_BIN\s*=\s*$/.test(before)) continue;
1099
+ if (arrayRanges.some(range => start >= range.start && start < range.end)) {
1100
+ violations.push({ start, end: start + reference[0].length });
1101
+ continue;
1102
+ }
1103
+ const lineStart = before.lastIndexOf("\n") + 1;
1104
+ const lineEnd = normalizedContents.indexOf("\n", start);
1105
+ const line = normalizedContents.slice(lineStart, lineEnd === -1 ? normalizedContents.length : lineEnd);
1106
+ const linePrefix = normalizedContents.slice(lineStart, start);
1107
+ const lastConditionalOpen = linePrefix.lastIndexOf("[[");
1108
+ const lastConditionalClose = linePrefix.lastIndexOf("]]");
1109
+ const isConditionalCheck = lastConditionalOpen > lastConditionalClose;
1110
+ const isPythonHeredocArgument = /^\s*python3\s+-\s+.*<<["']PY["']\s*$/.test(line);
1111
+ const isCommandLookup = /\bcommand\s+-v\s*$/.test(linePrefix);
1112
+ const statementStart =
1113
+ Math.max(
1114
+ before.lastIndexOf("\n"),
1115
+ before.lastIndexOf(";"),
1116
+ before.lastIndexOf("|"),
1117
+ before.lastIndexOf("&"),
1118
+ before.lastIndexOf("("),
1119
+ ) + 1;
1120
+ const prefix = before.slice(statementStart);
1121
+ const isDirectInvocation = /^\s*$/.test(prefix);
1122
+ const isTimedInvocation = /^\s*timeout\s+(?:"[^"\r\n]*"|'[^'\r\n]*'|[^\s]+)\s+$/.test(prefix);
1123
+ if (
1124
+ !isDirectInvocation &&
1125
+ !isTimedInvocation &&
1126
+ !isConditionalCheck &&
1127
+ !isPythonHeredocArgument &&
1128
+ !isCommandLookup
1129
+ ) {
1130
+ violations.push({ start, end: start + reference[0].length });
1131
+ }
1132
+ }
1133
+ return violations;
1134
+ }
1135
+
1136
+ function pythonFirstArgument(contents: string, openingParen: number): { text: string; start: number } | undefined {
1137
+ let depth = 0;
1138
+ let quote: "'" | '"' | undefined;
1139
+ for (let index = openingParen + 1; index < contents.length; index++) {
1140
+ const character = contents[index];
1141
+ if (quote) {
1142
+ if (character === "\\") {
1143
+ index++;
1144
+ } else if (character === quote) {
1145
+ quote = undefined;
1146
+ }
1147
+ continue;
1148
+ }
1149
+ if (character === "'" || character === '"') {
1150
+ quote = character;
1151
+ continue;
1152
+ }
1153
+ if (character === "(" || character === "[" || character === "{") {
1154
+ depth++;
1155
+ continue;
1156
+ }
1157
+ if (character === ")" || character === "]" || character === "}") {
1158
+ if (depth === 0 && character === ")") {
1159
+ return { text: contents.slice(openingParen + 1, index), start: openingParen + 1 };
1160
+ }
1161
+ depth--;
1162
+ continue;
1163
+ }
1164
+ if (character === "," && depth === 0) {
1165
+ return { text: contents.slice(openingParen + 1, index), start: openingParen + 1 };
1166
+ }
1167
+ }
1168
+ return undefined;
1169
+ }
1170
+
1171
+ function tmuxCreateStartupViolations(file: string, contents: string): string[] {
1172
+ if (file !== "scripts/skc-session/create.sh") return [];
1173
+ const violations: string[] = [];
1174
+ const violation = (offset: number, detail: string) =>
1175
+ violations.push(`${file}:${lineNumber(contents, offset)}: ${detail}`);
1176
+ const exactArityGuard =
1177
+ /^\s*\[\[\s+\$#\s+-eq\s+2\s+\]\]\s+\|\|\s+\{\s*echo\s+["']Usage:\s+\$0\s+<session-name>\s+<worktree-path>["']\s+>&2;\s+exit\s+2;\s*\}\s*$/gm;
1178
+ const arityGuards = [...contents.matchAll(exactArityGuard)];
1179
+ const topLevelArityGuards = arityGuards.filter(guard =>
1180
+ isUnconditionalTopLevelShellPosition(contents, guard.index ?? 0),
1181
+ );
1182
+ const twoOperandArityChecks = [...contents.matchAll(/\[\[\s+\$#\s+-eq\s+2\s+\]\]/g)];
1183
+ const arityGuard = topLevelArityGuards[0] ?? arityGuards[0];
1184
+ if (arityGuards.length !== 1 || topLevelArityGuards.length !== 1 || twoOperandArityChecks.length !== 1) {
1185
+ violation(arityGuard?.index ?? 0, "human-only tmux owner must have one fail-closed exact two-operand guard");
1186
+ }
1187
+ const positionalRewrites = [...contents.matchAll(/^\s*(?:set\s+--(?:\s|$)|shift(?:\s|$))/gm)];
1188
+ if (positionalRewrites.length > 0) {
1189
+ violation(
1190
+ positionalRewrites[0].index ?? 0,
1191
+ "human-only tmux owner must not rewrite positional arguments before launch",
1192
+ );
1193
+ }
1194
+ const guardStart = arityGuard?.index ?? 0;
1195
+ const guardNeutralizers = [
1196
+ ...contents.matchAll(
1197
+ /(?:^|\n)\s*(?:(?:function\s+)?(?:exit|echo)\s*(?:\(\s*\))?\s*\{|alias\s+(?:exit|echo)\b|enable\s+-n\s+(?:exit|echo)\b)/gm,
1198
+ ),
1199
+ ].filter(match => (match.index ?? 0) < guardStart);
1200
+ if (guardNeutralizers.length > 0) {
1201
+ violation(
1202
+ guardNeutralizers[0].index ?? 0,
1203
+ "human-only tmux owner must not neutralize the exact two-operand guard",
1204
+ );
1205
+ }
1206
+
1207
+ const canonicalCommand = /^\s*command\s*=\s*\[\s*os\.environ\[\s*["']SKC_SESSION_SKC_BIN["']\s*\]\s*\]\s*$/gm;
1208
+ const canonicalCommands = [...contents.matchAll(canonicalCommand)];
1209
+ const commandMutations = [
1210
+ ...contents.matchAll(/\bcommand\s*(?:\[[^\]\n]*\]\s*=|\.\s*[A-Za-z_][A-Za-z0-9_]*\s*\(|\+=|=)/g),
1211
+ ];
1212
+ if (
1213
+ canonicalCommands.length !== 1 ||
1214
+ commandMutations.length !== 1 ||
1215
+ commandMutations[0]?.index !== canonicalCommands[0]?.index
1216
+ ) {
1217
+ violation(
1218
+ commandMutations[0]?.index ?? 0,
1219
+ "human-only tmux owner must launch exactly SKC_SESSION_SKC_BIN with zero startup arguments",
1220
+ );
1221
+ }
1222
+ const canonicalInteractivePopenAssignment =
1223
+ /^\s*child\s*=\s*subprocess\.Popen\(\s*command\s*(?:,\s*cwd\s*=\s*os\.environ\[\s*["']SKC_SESSION_WORKDIR["']\s*\])?\s*\)\s*$/;
1224
+ const expectedLifecycleCallsites = [
1225
+ {
1226
+ operation: "terminal observer",
1227
+ pattern:
1228
+ /\bcompleted\s*=\s*subprocess\.run\(\s*\[\s*os\.environ\[\s*["']SKC_SESSION_SKC_BIN["']\s*\]\s*,\s*["']--internal-tmux-owner-isolation["']\s*\]\s*,/g,
1229
+ },
1230
+ {
1231
+ operation: "owner-isolation plan",
1232
+ pattern:
1233
+ /\bPLAN_RESPONSE\s*=\s*"\$\(\s*printf\s+["'][^"']*["']\s+"\$PLAN_LINE"\s*\|\s*"\$SKC_BIN"\s+--internal-tmux-owner-isolation\s*\)"/g,
1234
+ },
1235
+ {
1236
+ operation: "post-spawn proof",
1237
+ pattern:
1238
+ /\bPOST_SPAWN_RESPONSE\s*=\s*"\$\(\s*printf\s+["'][^"']*["']\s+"\$PLAN_LINE"\s*\|\s*"\$SKC_BIN"\s+--internal-tmux-owner-isolation\s*\)"/g,
1239
+ },
1240
+ {
1241
+ operation: "generation publication",
1242
+ pattern:
1243
+ /\bGENERATION_PUBLISH_RESPONSE\s*=\s*"\$\(\s*printf\s+["'][^"']*["']\s+"\$GENERATION_PUBLISH_REQUEST"\s*\|\s*"\$SKC_BIN"\s+--internal-tmux-owner-isolation\s*\)"/g,
1244
+ },
1245
+ {
1246
+ operation: "terminal monitor",
1247
+ pattern:
1248
+ /\bif\s+verdict\s*=\s*"\$\(\s*printf\s+["'][^"']*["']\s+"\$request"\s*\|\s*timeout\s+"[^"]+"\s+"\$SKC_SESSION_SKC_BIN"\s+--internal-tmux-owner-isolation\s*\)"\s*;\s*then/g,
1249
+ },
1250
+ ];
1251
+ const expectedLifecycleRanges: ShellRange[] = [];
1252
+ for (const callsite of expectedLifecycleCallsites) {
1253
+ const matches = [...contents.matchAll(callsite.pattern)];
1254
+ if (matches.length !== 1) {
1255
+ violation(
1256
+ matches[0]?.index ?? 0,
1257
+ `human-only tmux owner must bind one exact ${callsite.operation} lifecycle callsite`,
1258
+ );
1259
+ continue;
1260
+ }
1261
+ const match = matches[0];
1262
+ expectedLifecycleRanges.push({ start: match.index ?? 0, end: (match.index ?? 0) + match[0].length });
1263
+ }
1264
+ const pythonCommandAssignment =
1265
+ /^\s*[A-Za-z_][A-Za-z0-9_]*\s*=\s*(?=(?:\(\s*)?(?:command\b|\[\s*\*?command\b|[A-Za-z_][A-Za-z0-9_]*(?:\.[A-Za-z_][A-Za-z0-9_]*)*\s*\(\s*command\b))[^\n]*$/gm;
1266
+ for (const match of contents.matchAll(pythonCommandAssignment)) {
1267
+ if (canonicalInteractivePopenAssignment.test(match[0])) continue;
1268
+ violation(match.index ?? 0, "human-only tmux owner must not construct or wrap a non-lifecycle SKC argv");
1269
+ }
1270
+
1271
+ const allowedSkcEnvironmentReferences: ShellRange[] = canonicalCommands.map(match => ({
1272
+ start: match.index ?? 0,
1273
+ end: (match.index ?? 0) + match[0].length,
1274
+ }));
1275
+ const allowedCommandReferences = [...allowedSkcEnvironmentReferences];
1276
+ const subprocessCalls = /\bsubprocess\.(Popen|run|call|check_call|check_output)\s*\(/g;
1277
+ let interactiveLaunches = 0;
1278
+ for (const match of contents.matchAll(subprocessCalls)) {
1279
+ const openingParen = (match.index ?? 0) + match[0].lastIndexOf("(");
1280
+ const argument = pythonFirstArgument(contents, openingParen);
1281
+ if (!argument) continue;
1282
+ const lineStart = contents.lastIndexOf("\n", match.index ?? 0) + 1;
1283
+ const lineEnd = contents.indexOf("\n", match.index ?? 0);
1284
+ const line = contents.slice(lineStart, lineEnd === -1 ? contents.length : lineEnd);
1285
+ const isInteractiveLaunch =
1286
+ match[1] === "Popen" && argument.text.trim() === "command" && canonicalInteractivePopenAssignment.test(line);
1287
+ const isLifecycleCall =
1288
+ /^\s*\[\s*os\.environ\[\s*["']SKC_SESSION_SKC_BIN["']\s*\]\s*,\s*["']--internal-tmux-owner-isolation["']\s*\]\s*$/.test(
1289
+ argument.text,
1290
+ );
1291
+ if (isInteractiveLaunch) {
1292
+ interactiveLaunches++;
1293
+ allowedCommandReferences.push({ start: lineStart, end: lineEnd === -1 ? contents.length : lineEnd });
1294
+ continue;
1295
+ }
1296
+ if (isLifecycleCall) {
1297
+ const lifecycleStart = match.index ?? 0;
1298
+ if (!expectedLifecycleRanges.some(range => lifecycleStart >= range.start && lifecycleStart < range.end)) {
1299
+ violation(
1300
+ lifecycleStart,
1301
+ "human-only tmux owner must bind owner-isolation to its expected lifecycle callsite",
1302
+ );
1303
+ continue;
1304
+ }
1305
+ allowedSkcEnvironmentReferences.push({ start: argument.start, end: argument.start + argument.text.length });
1306
+ continue;
1307
+ }
1308
+ if (/\bcommand\b|os\.environ\[\s*["']SKC_SESSION_SKC_BIN["']\s*\]/.test(argument.text)) {
1309
+ violation(
1310
+ match.index ?? 0,
1311
+ "human-only tmux owner must invoke SKC only with zero interactive argv or the exact owner-isolation lifecycle argv",
1312
+ );
1313
+ }
1314
+ }
1315
+ for (const match of contents.matchAll(/\[\s*["']skc["'](?:\s*,|\s*\])/g)) {
1316
+ violation(match.index ?? 0, "human-only tmux owner must not launch a literal skc executable");
1317
+ }
1318
+ for (const match of contents.matchAll(/(?:^|\n)\s*(?:export\s+)?[A-Za-z_][A-Za-z0-9_]*\s*=\s*["']skc["']\s*$/gm)) {
1319
+ violation(match.index ?? 0, "human-only tmux owner must not alias or wrap the skc executable");
1320
+ }
1321
+ for (const match of contents.matchAll(
1322
+ /(?:^|\n)\s*(?:alias\s+[A-Za-z_][A-Za-z0-9_]*\s*=\s*['"]?skc\b|(?:function\s+)?[A-Za-z_][A-Za-z0-9_]*\s*\(\s*\)\s*\{[^\n]*\bskc\b)/gm,
1323
+ )) {
1324
+ violation(match.index ?? 0, "human-only tmux owner must not alias or wrap the skc executable");
1325
+ }
1326
+ for (const match of contents.matchAll(
1327
+ /(?:^|[|;&({]\s*|\b(?:command|exec|env|sudo|nice|nohup)\s+)["']?skc["']?(?=\s|$)/gm,
1328
+ )) {
1329
+ violation(match.index ?? 0, "human-only tmux owner must not launch a literal skc executable");
1330
+ }
1331
+ for (const match of contents.matchAll(
1332
+ /\benv(?:\s+(?:[A-Za-z_][A-Za-z0-9_]*=(?:"[^"]*"|'[^']*'|[^\s]+)|"[^"]*"|'[^']*'))*\s+["']?skc["']?(?=\s|$)/gm,
1333
+ )) {
1334
+ violation(match.index ?? 0, "human-only tmux owner must not launch a literal skc executable");
1335
+ }
1336
+ for (const match of contents.matchAll(/\b(?:bash|sh)\s+-c\s+(["'])[^\r\n]*?\bskc\b/g)) {
1337
+ violation(match.index ?? 0, "human-only tmux owner must not alias or wrap the skc executable");
1338
+ }
1339
+ if (interactiveLaunches !== 1) {
1340
+ violation(0, "human-only tmux owner must launch exactly one zero-argv interactive SKC process");
1341
+ }
1342
+ for (const match of contents.matchAll(/\bcommand\b/g)) {
1343
+ const offset = match.index ?? 0;
1344
+ const lineStart = contents.lastIndexOf("\n", offset) + 1;
1345
+ const before = contents.slice(lineStart, offset);
1346
+ const lineEnd = contents.indexOf("\n", offset);
1347
+ const after = contents.slice(offset + match[0].length, lineEnd === -1 ? contents.length : lineEnd);
1348
+ if (/\bcommand\s+-[^\s]*\s*$/.test(before) || /^\s+-[A-Za-z]/.test(after)) continue;
1349
+ if (!allowedCommandReferences.some(range => offset >= range.start && offset < range.end)) {
1350
+ violation(offset, "human-only tmux owner must not construct or wrap a non-lifecycle SKC argv");
1351
+ }
1352
+ }
1353
+ for (const match of contents.matchAll(/["']command["']/g)) {
1354
+ violation(match.index ?? 0, "human-only tmux owner must not construct or wrap a non-lifecycle SKC argv");
1355
+ }
1356
+ for (const match of contents.matchAll(/\b(?:globals|locals|vars|getattr|setattr|delattr|eval|exec)\s*\(/g)) {
1357
+ violation(match.index ?? 0, "human-only tmux owner must not construct or wrap a non-lifecycle SKC argv");
1358
+ }
1359
+ for (const match of contents.matchAll(/os\.environ\[\s*["']SKC_SESSION_SKC_BIN["']\s*\]/g)) {
1360
+ const offset = match.index ?? 0;
1361
+ if (!allowedSkcEnvironmentReferences.some(range => offset >= range.start && offset < range.end)) {
1362
+ violation(offset, "human-only tmux owner must not construct or wrap a non-lifecycle SKC argv");
1363
+ }
1364
+ }
1365
+
1366
+ const normalizedContents = normalizeShellContinuations(contents);
1367
+ const normalizedExpectedLifecycleRanges = expectedLifecycleCallsites.flatMap(callsite =>
1368
+ [...normalizedContents.matchAll(callsite.pattern)].map(match => ({
1369
+ start: match.index ?? 0,
1370
+ end: (match.index ?? 0) + match[0].length,
1371
+ })),
1372
+ );
1373
+ const shellSkcInvocations =
1374
+ /(?:^|[|;&(]\s*|\b(?:command|exec)\s+|\btimeout\s+(?:"[^"\r\n]*"|'[^'\r\n]*'|[^\s]+)\s+)(["']?)\$(?:SKC_BIN|SKC_SESSION_SKC_BIN|\{(?:SKC_BIN|SKC_SESSION_SKC_BIN)\})\1([^\r\n;|&)]*)/gm;
1375
+ for (const match of normalizedContents.matchAll(shellSkcInvocations)) {
1376
+ const argumentsText = (match[2] ?? "").trim().replace(/["']$/, "");
1377
+ const isLifecycleCall = /^(?:["']?--internal-tmux-owner-isolation["']?)$/.test(argumentsText);
1378
+ const invocationStart = match.index ?? 0;
1379
+ if (
1380
+ !isLifecycleCall ||
1381
+ !normalizedExpectedLifecycleRanges.some(range => invocationStart >= range.start && invocationStart < range.end)
1382
+ ) {
1383
+ violation(invocationStart, "human-only tmux owner invokes SKC with a non-lifecycle startup argument");
1384
+ }
1385
+ }
1386
+ for (const reference of shellSkcBinaryReferenceViolations(contents)) {
1387
+ violation(reference.start, "human-only tmux owner must not construct or wrap a non-lifecycle SKC argv");
1388
+ }
1389
+ for (const match of contents.matchAll(/\bSKC_SESSION_FLAGS\b/g)) {
1390
+ violation(match.index ?? 0, "human-only tmux owner exposes caller-provided startup arguments");
1391
+ }
1392
+ return violations;
1393
+ }
1394
+
1395
+ const canonicalSdkClientModule = "packages/coding-agent/src/sdk/client/client.ts";
1396
+ const coordinatorDirectAuthorityPatterns = [
1397
+ /\bimport\s+(?:type\s+)?[\s\S]*?\sfrom\s*["'][^"']*(?:session\/agent-session|sdk\/session|sdk\/host\/control)["']/g,
1398
+ /\b(?:new\s+)?AgentSession\b/g,
1399
+ /\b(?:agentSession|agent_session|session)\s*\.\s*(?:prompt|promptCustomMessage|abort|abortAndPrompt|followUp|answer)\s*\(/g,
1400
+ ];
1401
+
1402
+ function braceBlockRange(contents: string, openingBrace: number): ShellRange | undefined {
1403
+ const structural = maskCodeComments(contents.slice(openingBrace));
1404
+ let depth = 0;
1405
+ let quote: "'" | '"' | "`" | undefined;
1406
+ for (let relative = 0; relative < structural.length; relative++) {
1407
+ const character = structural[relative];
1408
+ if (quote) {
1409
+ if (character === "\\") relative++;
1410
+ else if (character === quote) quote = undefined;
1411
+ continue;
1412
+ }
1413
+ if (character === "'" || character === '"' || character === "`") {
1414
+ quote = character;
1415
+ continue;
1416
+ }
1417
+ if (character === "{") depth++;
1418
+ if (character === "}") depth--;
1419
+ if (depth === 0) return { start: openingBrace, end: openingBrace + relative + 1 };
1420
+ }
1421
+ return undefined;
1422
+ }
1423
+
1424
+ function exactTeamRuntimeSendKeysRanges(contents: string): ShellRange[] {
1425
+ const guardMatches = [...contents.matchAll(/if\s*\(\s*useSendKeysFallback\s*\)\s*\{/g)];
1426
+ const payloadMatches = [
1427
+ ...contents.matchAll(
1428
+ /Bun\.spawnSync\(\s*\[\s*config\.tmux_command\s*,\s*["']send-keys["']\s*,\s*["']-l["']\s*,\s*["']-t["']\s*,\s*paneId\s*,\s*workerCommand\s*\]\s*,\s*\{[\s\S]{0,200}?stdout\s*:\s*["']ignore["'][\s\S]{0,200}?stderr\s*:\s*["']ignore["'][\s\S]{0,100}?\}\s*\)\s*;/g,
1429
+ ),
1430
+ ];
1431
+ const continuationPromptMatches = [
1432
+ ...contents.matchAll(
1433
+ /(?:const\s+SKC_TEAM_CONTINUATION_PROMPT\s*=\s*["']Continue only your current claimed SKC team task\. Re-read current SKC team state; do not replay prior output; report status\.["']\s*;|import\s*\{[\s\S]{0,1000}?\bSKC_TEAM_CONTINUATION_PROMPT\b[\s\S]{0,1000}?\}\s*from\s*["']\.\/team-workers["']\s*;)/g,
1434
+ ),
1435
+ ];
1436
+ const continuationMatches = [
1437
+ ...contents.matchAll(
1438
+ /const\s+args\s*=\s*Object\.freeze\(\s*\[\s*["']send-keys["']\s*,\s*["']-l["']\s*,\s*["']-t["']\s*,\s*worker\.pane_id\s*,\s*SKC_TEAM_CONTINUATION_PROMPT\s*,\s*["'];["']\s*,\s*["']send-keys["']\s*,\s*["']-t["']\s*,\s*worker\.pane_id\s*,\s*["']Enter["']\s*,?\s*\]\s*\)\s*;\s*const\s+dispatch\s*=\s*skcTeamRuntimeTestSeams\?\.continuationTmuxDispatch\s*\?\s*skcTeamRuntimeTestSeams\.continuationTmuxDispatch\(config\.tmux_command\s*,\s*args\)\s*:\s*Bun\.spawnSync\(\[config\.tmux_command\s*,\s*\.\.\.args\]\s*,\s*\{\s*stdout\s*:\s*["']ignore["']\s*,\s*stderr\s*:\s*["']ignore["']\s*,\s*timeout\s*:\s*SKC_TEAM_CONTINUATION_DISPATCH_TIMEOUT_MS\s*,?\s*\}\s*\)\s*;/g,
1439
+ ),
1440
+ ];
1441
+ const enterMatches = [
1442
+ ...contents.matchAll(
1443
+ /const\s+sendKeys\s*=\s*Bun\.spawnSync\(\s*\[\s*config\.tmux_command\s*,\s*["']send-keys["']\s*,\s*["']-t["']\s*,\s*paneId\s*,\s*["']Enter["']\s*\]\s*,\s*\{[\s\S]{0,200}?stdout\s*:\s*["']ignore["'][\s\S]{0,200}?stderr\s*:\s*["']ignore["'][\s\S]{0,100}?\}\s*\)\s*;/g,
1444
+ ),
1445
+ ];
1446
+ const fallbackPredicateMatches = [
1447
+ ...contents.matchAll(
1448
+ /function\s+shouldDispatchWorkerWithSendKeys\([^)]*\)\s*:\s*boolean\s*\{\s*return\s+platform\s*===\s*["']win32["']\s*\|\|\s*path\.basename\(tmuxCommand\)\.toLowerCase\(\)\s*===\s*["']psmux["']\s*;\s*\}/g,
1449
+ ),
1450
+ ];
1451
+ const useFallbackMatches = [
1452
+ ...contents.matchAll(
1453
+ /const\s+useSendKeysFallback\s*=\s*shouldDispatchWorkerWithSendKeys\(config\.tmux_command\)\s*;/g,
1454
+ ),
1455
+ ];
1456
+ const splitWorkerCommandMatches = [
1457
+ ...contents.matchAll(/\.\.\.\(useSendKeysFallback\s*\?\s*\[\]\s*:\s*\[workerCommand\]\)\s*,/g),
1458
+ ];
1459
+ if (
1460
+ guardMatches.length !== 1 ||
1461
+ payloadMatches.length !== 1 ||
1462
+ enterMatches.length !== 1 ||
1463
+ continuationPromptMatches.length !== 1 ||
1464
+ continuationMatches.length !== 1 ||
1465
+ fallbackPredicateMatches.length !== 1 ||
1466
+ useFallbackMatches.length !== 1 ||
1467
+ splitWorkerCommandMatches.length !== 1
1468
+ )
1469
+ return [];
1470
+ const guardStart = guardMatches[0].index ?? 0;
1471
+ const payloadStart = payloadMatches[0].index ?? 0;
1472
+ const enterStart = enterMatches[0].index ?? 0;
1473
+ const voidStart = contents.indexOf("void sendKeys.exitCode;", enterStart);
1474
+ if (
1475
+ (useFallbackMatches[0].index ?? 0) >= (splitWorkerCommandMatches[0].index ?? 0) ||
1476
+ (splitWorkerCommandMatches[0].index ?? 0) >= guardStart ||
1477
+ payloadStart >= enterStart ||
1478
+ voidStart < enterStart
1479
+ )
1480
+ return [];
1481
+ const guard = guardMatches[0];
1482
+ const openingBrace = (guard.index ?? 0) + guard[0].lastIndexOf("{");
1483
+ const range = braceBlockRange(contents, openingBrace);
1484
+ const continuationFunction =
1485
+ /async\s+function\s+continueStalledSkcTeamWorkers\s*\([^)]*\)\s*:\s*Promise<void>\s*\{/.exec(contents);
1486
+ const monitorFence = /await\s+withSkcTeamTaskMutation\([\s\S]{0,500}?async\s+capability\s*=>\s*\{/.exec(contents);
1487
+ if (!range || !continuationFunction || !monitorFence) return [];
1488
+ const continuationOpeningBrace = (continuationFunction.index ?? 0) + continuationFunction[0].lastIndexOf("{");
1489
+ const continuationRange = braceBlockRange(contents, continuationOpeningBrace);
1490
+ const monitorOpeningBrace = (monitorFence.index ?? 0) + monitorFence[0].lastIndexOf("{");
1491
+ const monitorRange = braceBlockRange(contents, monitorOpeningBrace);
1492
+ if (!continuationRange || !monitorRange) return [];
1493
+ const monitorBody = contents.slice(monitorRange.start, monitorRange.end);
1494
+ const continuationCall = /await\s+continueStalledSkcTeamWorkers\s*\(/.exec(monitorBody);
1495
+ const reconciliationCall = /await\s+reconcileSkcTeamStaleClaimsUnlocked\s*\(/.exec(monitorBody);
1496
+ const continuationStart = continuationMatches[0].index ?? 0;
1497
+ const finalValidationStart = contents.lastIndexOf("const revalidationReason =", continuationStart);
1498
+ const skippedBranch = finalValidationStart === -1 ? "" : contents.slice(finalValidationStart, continuationStart);
1499
+ if (
1500
+ payloadStart < range.start ||
1501
+ payloadStart >= range.end ||
1502
+ enterStart < range.start ||
1503
+ enterStart >= range.end ||
1504
+ contents.indexOf("void sendKeys.exitCode;", enterStart) >= range.end ||
1505
+ continuationStart < continuationRange.start ||
1506
+ continuationStart >= continuationRange.end ||
1507
+ finalValidationStart < continuationRange.start ||
1508
+ !continuationCall ||
1509
+ !reconciliationCall ||
1510
+ (continuationCall.index ?? 0) >= (reconciliationCall.index ?? 0) ||
1511
+ !/if\s*\(\s*revalidationReason\s*\)[\s\S]*?return\s*;/.test(skippedBranch)
1512
+ )
1513
+ return [];
1514
+ return [
1515
+ { start: payloadStart, end: payloadStart + payloadMatches[0][0].length },
1516
+ { start: enterStart, end: enterStart + enterMatches[0][0].length },
1517
+ {
1518
+ start: continuationMatches[0].index ?? 0,
1519
+ end: (continuationMatches[0].index ?? 0) + continuationMatches[0][0].length,
1520
+ },
1521
+ ];
1522
+ }
1523
+
1524
+ function isExactTmuxScrollCopyModeSendKeys(
1525
+ file: string,
1526
+ contents: string,
1527
+ occurrence: TmuxPrimitiveOccurrence,
1528
+ ): boolean {
1529
+ if (file !== "packages/coding-agent/src/modes/tmux-scroll.ts" || occurrence.primitive !== "send-keys") return false;
1530
+ const openingBracket = contents.lastIndexOf("[", occurrence.start);
1531
+ const closingBracket = contents.indexOf("]", occurrence.end);
1532
+ if (openingBracket === -1 || closingBracket === -1) return false;
1533
+ return /^\[\s*["']send-keys["']\s*,\s*\.\.\.targetArgs\s*,\s*["']-X["']\s*,\s*(?:["']history-bottom["']|["']search-backward["']\s*,\s*TMUX_PREVIOUS_USER_INPUT_SEARCH_PATTERN)\s*\]$/.test(
1534
+ contents.slice(openingBracket, closingBracket + 1),
1535
+ );
1536
+ }
1537
+
1538
+ function isTypeOnlyTmuxPrimitiveOccurrence(contents: string, occurrence: TmuxPrimitiveOccurrence): boolean {
1539
+ const lineStart = contents.lastIndexOf("\n", occurrence.start) + 1;
1540
+ const lineEnd = contents.indexOf("\n", occurrence.end);
1541
+ return /^\s*(?:export\s+)?type\b/.test(contents.slice(lineStart, lineEnd === -1 ? contents.length : lineEnd));
1542
+ }
1543
+
1544
+ function tmuxMachineBusViolations(file: string, contents: string): string[] {
1545
+ if (isGeneratedDocumentationIndex(file)) return [];
1546
+ const allowedTeamFallbackRanges = file === teamRuntimeTmuxPath ? exactTeamRuntimeSendKeysRanges(contents) : [];
1547
+ const violations: string[] = [];
1548
+ for (const occurrence of tmuxPrimitiveOccurrences(contents)) {
1549
+ const isExactTeamFallback =
1550
+ occurrence.primitive === "send-keys" &&
1551
+ allowedTeamFallbackRanges.some(range => occurrence.start >= range.start && occurrence.end <= range.end);
1552
+ if (
1553
+ isExactTeamFallback ||
1554
+ isExactTmuxScrollCopyModeSendKeys(file, contents, occurrence) ||
1555
+ isTypeOnlyTmuxPrimitiveOccurrence(contents, occurrence)
1556
+ )
1557
+ continue;
1558
+ const detail =
1559
+ occurrence.primitive === "capture-pane" || occurrence.primitive === "pipe-pane"
1560
+ ? `tmux ${occurrence.primitive} pane access is outside sanctioned test fixtures`
1561
+ : `tmux ${occurrence.primitive} content injection is outside sanctioned process lifecycle`;
1562
+ violations.push(`${file}:${lineNumber(contents, occurrence.start)}: ${detail}`);
1563
+ }
1564
+ return violations;
1565
+ }
1566
+
1567
+ function lineNumber(contents: string, offset: number): number {
1568
+ return contents.slice(0, offset).split(/\r?\n/).length;
1569
+ }
1570
+
1571
+ const machineEntrypoints = new Map<string, string>([
1572
+ ["packages/coding-agent/src/modes/acp/acp-agent.ts", "ACP"],
1573
+ ["packages/coding-agent/src/commands/mcp-serve.ts", "MCP"],
1574
+ ["packages/coding-agent/src/sdk/cli/session-cli.ts", "daemon session CLI"],
1575
+ ]);
1576
+
1577
+ const machineWrapperEntrypoints = new Map<string, string>([
1578
+ ["packages/coding-agent/src/commands/acp.ts", "ACP command"],
1579
+ ["packages/coding-agent/src/commands/daemon.ts", "daemon command"],
1580
+ ["packages/coding-agent/src/commands/mcp-serve.ts", "MCP command"],
1581
+ ["packages/coding-agent/src/sdk/cli/session-cli.ts", "daemon session CLI"],
1582
+ ]);
1583
+ const rootAcpEntrypoint = "packages/coding-agent/src/main.ts";
1584
+ const directMachineWrapperRoutePattern =
1585
+ /(?:\b(?:import|export)\s+(?:type\s+)?(?:[\s\S]*?\s+from\s+)?["'][^"']*(?:session\/agent-session|sdk\/session|sdk\/host\/(?:control|query)|session\/client-bridge|modes\/(?:rpc|bridge)|\/(?:rpc|bridge)(?=[-"'/.]|$)|unattended)(?:[-"'/.]|$)|\bimport\s*\(\s*["'][^"']*(?:session\/agent-session|sdk\/session|sdk\/host\/(?:control|query)|session\/client-bridge|modes\/(?:rpc|bridge)|\/(?:rpc|bridge)(?=[-"'/.]|$)|unattended)(?:[-"'/.]|$)|["'](?:rpc|bridge)(?:[-"'/.]|$)|--mode(?:\s+|=)["']?rpc(?:\b|["'])|["']--mode["']\s*,\s*["']rpc["']|\b(?:new\s+)?AgentSession\b|\b(?:agentSession|agent_session|session)\s*\.\s*(?:prompt|promptCustomMessage|abort|abortAndPrompt|followUp|answer)\s*\(|(?:Bun\.(?:spawn|spawnSync)|runner)\s*\(\s*\[[^\]]*?\b(?:tmux|tmux_command)\b)/g;
1586
+
1587
+ function directMachineWrapperRouteViolations(file: string, owner: string, contents: string): string[] {
1588
+ return [...contents.matchAll(directMachineWrapperRoutePattern)].map(
1589
+ match =>
1590
+ `${file}:${lineNumber(contents, match.index ?? 0)}: ${owner} wrapper bypasses SDK/ACP/Coordinator through direct session, RPC, or tmux routing (${match[0]})`,
1591
+ );
1592
+ }
1593
+
1594
+ function rootAcpModeViolations(contents: string): string[] {
1595
+ const branch = /if\s*\(\s*mode\s*===\s*["']acp["']\s*\)\s*\{([\s\S]*?)\n\s*\}\s*else\s*\{/.exec(contents)?.[1];
1596
+ if (branch === undefined) return [`${rootAcpEntrypoint}: root --mode acp lacks an isolated ACP dispatch branch`];
1597
+ const violations: string[] = [];
1598
+ if (
1599
+ !/await\s*\(\s*deps\.runAcpMode\s*\?\?\s*\(await import\(["']\.\/modes\/acp["']\)\)\.runAcpMode\)\s*\(/.test(
1600
+ branch,
1601
+ )
1602
+ ) {
1603
+ violations.push(`${rootAcpEntrypoint}: root --mode acp must dispatch only through the SDK ACP bootstrap`);
1604
+ }
1605
+ const branchOffset = contents.indexOf(branch);
1606
+ for (const match of branch.matchAll(directMachineWrapperRoutePattern)) {
1607
+ violations.push(
1608
+ `${rootAcpEntrypoint}:${lineNumber(contents, branchOffset + (match.index ?? 0))}: root --mode acp bypasses SDK ACP through direct session, RPC, or tmux routing (${match[0]})`,
1609
+ );
1610
+ }
1611
+ return violations;
1612
+ }
1613
+
1614
+ const relativeImportPattern =
1615
+ /(?:import|export)\s+(?:type\s+)?(?:[^"'`;]*?\s+from\s+)?["']([^"']+)["']|import\s*\(\s*["']([^"']+)["']\s*\)/g;
1616
+ const sourceExtensions = [".ts", ".tsx", ".mts", ".cts"];
1617
+
1618
+ function isProductionTypeScript(file: string): boolean {
1619
+ return (
1620
+ file.startsWith("packages/coding-agent/src/") &&
1621
+ /\.(?:[cm]?tsx?)$/.test(file) &&
1622
+ !/\.(?:test|spec)\.[cm]?tsx?$/.test(file)
1623
+ );
1624
+ }
1625
+
1626
+ function isProductionTypeScriptOrJavaScript(file: string): boolean {
1627
+ return (
1628
+ file.startsWith("packages/coding-agent/src/") &&
1629
+ /\.(?:[cm]?[jt]sx?)$/.test(file) &&
1630
+ !/\.(?:test|spec)\.[cm]?[jt]sx?$/.test(file)
1631
+ );
1632
+ }
1633
+
1634
+ function relativeImports(contents: string): string[] {
1635
+ return [...contents.matchAll(relativeImportPattern)]
1636
+ .map(match => match[1] ?? match[2])
1637
+ .filter(specifier => specifier.startsWith("."));
1638
+ }
1639
+
1640
+ function resolveRelativeImport(importer: string, specifier: string, sourceFiles: Set<string>): string | undefined {
1641
+ const resolved = path.posix.normalize(path.posix.join(path.posix.dirname(importer), specifier));
1642
+ const extension = path.posix.extname(resolved);
1643
+ const nodeNextSourceExtensions =
1644
+ extension === ".js" ? [".ts", ".tsx"] : extension === ".mjs" ? [".mts"] : extension === ".cjs" ? [".cts"] : [];
1645
+ const candidates = extension
1646
+ ? [
1647
+ ...nodeNextSourceExtensions.map(
1648
+ sourceExtension => `${resolved.slice(0, -extension.length)}${sourceExtension}`,
1649
+ ),
1650
+ resolved,
1651
+ ]
1652
+ : [
1653
+ ...sourceExtensions.map(sourceExtension => `${resolved}${sourceExtension}`),
1654
+ ...sourceExtensions.map(sourceExtension => `${resolved}/index${sourceExtension}`),
1655
+ ];
1656
+ return candidates.find(candidate => sourceFiles.has(candidate));
1657
+ }
1658
+
1659
+ function importGraphReaches(root: string, target: string, contentsByFile: Map<string, string>): boolean {
1660
+ const sourceFiles = new Set(contentsByFile.keys());
1661
+ const pending = [root];
1662
+ const visited = new Set<string>();
1663
+ while (pending.length > 0) {
1664
+ const current = pending.shift();
1665
+ if (!current || visited.has(current)) continue;
1666
+ if (current === target) return true;
1667
+ visited.add(current);
1668
+ for (const specifier of relativeImports(contentsByFile.get(current) ?? "")) {
1669
+ const resolved = resolveRelativeImport(current, specifier, sourceFiles);
1670
+ if (resolved && !visited.has(resolved)) pending.push(resolved);
1671
+ }
1672
+ }
1673
+ return false;
1674
+ }
1675
+
1676
+ function scanPackageExports(contents: string, sourceFiles: readonly string[]): string[] {
1677
+ let manifest: { exports?: Record<string, unknown> };
1678
+ try {
1679
+ manifest = JSON.parse(contents) as { exports?: Record<string, unknown> };
1680
+ } catch (error) {
1681
+ return [
1682
+ `${packageManifestPath}: invalid package manifest: ${error instanceof Error ? error.message : String(error)}`,
1683
+ ];
1684
+ }
1685
+ if (!manifest.exports || typeof manifest.exports !== "object") return [];
1686
+
1687
+ const violations: string[] = [];
1688
+ for (const [exportPath, target] of Object.entries(manifest.exports)) {
1689
+ if (target === null) continue;
1690
+ if (/^\.\/modes\/rpc(?:[A-Za-z0-9_./-]|$)/i.test(exportPath)) {
1691
+ violations.push(
1692
+ `${packageManifestPath}: removed RPC mode remains externally exported as ${JSON.stringify(exportPath)}`,
1693
+ );
1694
+ }
1695
+ if (/(?:^|\/|[-_])(?:bridge|unattended)[A-Za-z0-9_.-]*(?:\/|$)/i.test(exportPath)) {
1696
+ violations.push(
1697
+ `${packageManifestPath}: removed bridge or unattended surface remains externally exported as ${JSON.stringify(exportPath)}`,
1698
+ );
1699
+ }
1700
+ }
1701
+ for (const sourceFile of sourceFiles) {
1702
+ if (!retiredIngressSource(sourceFile)) continue;
1703
+ const sourcePath = `./${sourceFile.slice("packages/coding-agent/".length)}`;
1704
+ for (const [exportPath, target] of Object.entries(manifest.exports)) {
1705
+ if (!exportPath.includes("*")) continue;
1706
+ if (broadExportReachesSource(manifest.exports, exportPath, target, sourcePath)) {
1707
+ violations.push(
1708
+ `${packageManifestPath}: retired ingress source ${sourceFile} is reachable through broad export ${JSON.stringify(exportPath)}`,
1709
+ );
1710
+ }
1711
+ }
1712
+ }
1713
+ for (const subpath of retiredAgentWireSubpaths) {
1714
+ if (resolveExportTarget(manifest.exports, subpath) != null) {
1715
+ violations.push(
1716
+ `${packageManifestPath}: retired agent-wire surface remains externally exported as ${JSON.stringify(subpath)}`,
1717
+ );
1718
+ }
1719
+ }
1720
+ return violations;
1721
+ }
1722
+
1723
+ function forbiddenMachineModule(file: string): string | undefined {
1724
+ if (file === "packages/coding-agent/src/modes/acp/acp-event-mapper.ts") return undefined;
1725
+ if (file === "packages/coding-agent/src/main.ts" || file === "packages/coding-agent/src/modes/interactive-mode.ts")
1726
+ return "process bootstrap/main session host";
1727
+ if (file === "packages/coding-agent/src/sdk/session.ts") return "direct session mutation module";
1728
+ if (file === "packages/coding-agent/src/session/agent-session.ts") return "AgentSession";
1729
+ if (file.startsWith("packages/coding-agent/src/runtime-mcp/")) return "MCPManager";
1730
+ if (file === "packages/coding-agent/src/extensibility/extensions/runner.ts") return "extension runner";
1731
+ if (
1732
+ file === "packages/coding-agent/src/session/client-bridge.ts" ||
1733
+ file === "packages/coding-agent/src/modes/acp/acp-client-bridge.ts"
1734
+ )
1735
+ return "direct client bridge";
1736
+ if (
1737
+ file === "packages/coding-agent/src/sdk/host/control.ts" ||
1738
+ file === "packages/coding-agent/src/sdk/host/query.ts"
1739
+ )
1740
+ return "host control/query dispatch";
1741
+ if (file.startsWith("packages/coding-agent/src/session/")) return "direct session mutation module";
1742
+ return undefined;
1743
+ }
1744
+
1745
+ function scanMachineImportGraphs(contentsByFile: Map<string, string>): string[] {
1746
+ const sourceFiles = new Set(contentsByFile.keys());
1747
+ const violations: string[] = [];
1748
+ for (const [root, owner] of machineEntrypoints) {
1749
+ if (!sourceFiles.has(root)) continue;
1750
+ const pending = [{ file: root, chain: [root] }];
1751
+ const visited = new Set<string>();
1752
+ while (pending.length > 0) {
1753
+ const current = pending.shift();
1754
+ if (!current || visited.has(current.file)) continue;
1755
+ visited.add(current.file);
1756
+ const forbidden = current.file === root ? undefined : forbiddenMachineModule(current.file);
1757
+ if (forbidden) {
1758
+ violations.push(
1759
+ `${root}: ${owner} machine entrypoint reaches forbidden ${forbidden} via ${current.chain.join(" -> ")}`,
1760
+ );
1761
+ continue;
1762
+ }
1763
+ if (current.file === "packages/coding-agent/src/modes/acp/acp-event-mapper.ts") continue;
1764
+ for (const specifier of relativeImports(contentsByFile.get(current.file) ?? "")) {
1765
+ const target = resolveRelativeImport(current.file, specifier, sourceFiles);
1766
+ if (target && !visited.has(target)) pending.push({ file: target, chain: [...current.chain, target] });
1767
+ }
1768
+ }
1769
+ }
1770
+ return violations;
1771
+ }
1772
+
1773
+ async function scan(): Promise<string[]> {
1774
+ const deleted = new Set(commandOutput(["git", "ls-files", "-z", "--deleted"]).split("\0").filter(Boolean));
1775
+ const files = commandOutput(["git", "ls-files", "-z", "--cached", "--others", "--exclude-standard"])
1776
+ .split("\0")
1777
+ .filter(file => file && !deleted.has(file));
1778
+ const violations: string[] = [];
1779
+ const contentsByFile = new Map<string, string>();
1780
+
1781
+ for (const file of files) {
1782
+ if (retiredIngressSource(file)) {
1783
+ violations.push(`${file}: retired RPC/bridge/unattended ingress source survived`);
1784
+ }
1785
+
1786
+ if (file.startsWith(retiredPythonRpcPackagePath)) {
1787
+ violations.push(`${file}: retired Python skc-rpc package source survived`);
1788
+ }
1789
+ if (retiredTmuxMachineBusPaths.has(file)) {
1790
+ violations.push(`${file}: retired tmux machine prompt or viewing helper survived`);
1791
+ }
1792
+ if (machineTmuxDocumentationPaths.has(file)) {
1793
+ const contents = await Bun.file(path.join(repoRoot, file)).text();
1794
+ const normalizedContents = normalizeShellContinuations(contents);
1795
+ for (const match of normalizedContents.matchAll(machineTmuxDocumentationPattern)) {
1796
+ violations.push(
1797
+ `${file}:${lineNumber(normalizedContents, match.index ?? 0)}: published machine documentation directs tmux prompt or viewing access`,
1798
+ );
1799
+ }
1800
+ }
1801
+ if (isPublishedSkcSessionShellHelper(file)) {
1802
+ const contents = await Bun.file(path.join(repoRoot, file)).text();
1803
+ const occurrences = tmuxPrimitiveOccurrences(contents);
1804
+ for (const match of contents.matchAll(
1805
+ /\b(?:load-buffer|paste-buffer|send-keys|capture-pane|pipe-pane|set-buffer)\b/g,
1806
+ )) {
1807
+ const start = match.index ?? 0;
1808
+ if (!occurrences.some(occurrence => start >= occurrence.start && start < occurrence.end)) {
1809
+ occurrences.push({
1810
+ primitive: match[0] as TmuxMachineBusPrimitive,
1811
+ start,
1812
+ end: start + match[0].length,
1813
+ });
1814
+ }
1815
+ }
1816
+ for (const occurrence of occurrences) {
1817
+ violations.push(
1818
+ `${file}:${lineNumber(contents, occurrence.start)}: published shell helper performs tmux machine prompt injection or pane viewing`,
1819
+ );
1820
+ }
1821
+ violations.push(...tmuxCreateStartupViolations(file, contents));
1822
+ }
1823
+ if (file === scannerPath || !isSource(file)) continue;
1824
+
1825
+ let contents: string;
1826
+ try {
1827
+ contents = await Bun.file(path.join(repoRoot, file)).text();
1828
+ } catch (error) {
1829
+ throw new Error(
1830
+ `Unable to scan tracked file ${file}: ${error instanceof Error ? error.message : String(error)}`,
1831
+ );
1832
+ }
1833
+ violations.push(...rpcModeInvocationViolations(file, contents));
1834
+ if (isActiveLegacyPythonRpcTarget(file)) violations.push(...legacyPythonRpcViolations(file, contents));
1835
+ if (file === packageManifestPath) violations.push(...scanPackageExports(contents, files));
1836
+ violations.push(...bridgeClientImportViolations(file, contents));
1837
+ violations.push(...bridgeClientOwnershipViolations(file, contents));
1838
+ const bridgeClientMetadataViolation = bridgeClientPackageMetadataViolation(file, contents);
1839
+ if (bridgeClientMetadataViolation) violations.push(bridgeClientMetadataViolation);
1840
+
1841
+ if (isProductionTypeScript(file)) contentsByFile.set(file, contents);
1842
+ const wrapper = machineWrapperEntrypoints.get(file);
1843
+ if (wrapper) violations.push(...directMachineWrapperRouteViolations(file, wrapper, contents));
1844
+ if (file === rootAcpEntrypoint) violations.push(...rootAcpModeViolations(contents));
1845
+
1846
+ for (const match of contents.matchAll(
1847
+ /(?:import|export)\s+(?:type\s+)?(?:[\s\S]*?\s+from\s+)?["'][^"']*modes\/(?:rpc|bridge|unattended)[A-Za-z0-9_.-]*(?:["'/]|$)/gi,
1848
+ )) {
1849
+ violations.push(
1850
+ `${file}:${lineNumber(contents, match.index ?? 0)}: imports removed modes/rpc or modes/bridge`,
1851
+ );
1852
+ }
1853
+ for (const match of contents.matchAll(bridgeOrUnattendedImportPattern)) {
1854
+ violations.push(`${file}:${lineNumber(contents, match.index ?? 0)}: imports removed unattended surface`);
1855
+ }
1856
+
1857
+ for (const match of contents.matchAll(/\bSKC_BRIDGE_[A-Z0-9_]*\b/g)) {
1858
+ violations.push(
1859
+ `${file}:${lineNumber(contents, match.index ?? 0)}: forbidden bridge environment reference ${match[0]}`,
1860
+ );
1861
+ }
1862
+
1863
+ if (file === "packages/coding-agent/src/cli.ts") {
1864
+ const modeFlag = /mode:\s*Flags\.string\([\s\S]*?options:\s*\[([^\]]*)\]/.exec(contents);
1865
+ if (modeFlag && /["'](?:rpc|rpc-ui|bridge)["']/.test(modeFlag[1])) {
1866
+ violations.push(`${file}: --mode option retains rpc, rpc-ui, or bridge`);
1867
+ }
1868
+ }
1869
+ if (file === "packages/coding-agent/src/commands/acp.ts") {
1870
+ if (
1871
+ !/parsed\.mode\s*=\s*["']acp["']/.test(contents) ||
1872
+ !/runRootCommand\s*\(\s*parsed\s*,\s*args\s*\)/.test(contents)
1873
+ ) {
1874
+ violations.push(`${file}: shipped ACP command does not dispatch through the root ACP bootstrap`);
1875
+ }
1876
+ }
1877
+ if (file === "packages/coding-agent/src/commands/daemon.ts") {
1878
+ if (!/runSdkSessionCli\s*\(/.test(contents)) {
1879
+ violations.push(`${file}: shipped daemon session command does not dispatch the SDK session CLI`);
1880
+ }
1881
+ }
1882
+ if (file === "packages/coding-agent/src/modes/acp/acp-agent.ts") {
1883
+ if (!/from\s*["'][^"']*sdk\/acp(?:\/adapter)?["']/.test(contents)) {
1884
+ violations.push(`${file}: shipped ACP entrypoint does not import the SDK ACP adapter`);
1885
+ }
1886
+ for (const match of contents.matchAll(/\brecord\.session\.(?:prompt|promptCustomMessage|abort)\s*\(/g)) {
1887
+ violations.push(
1888
+ `${file}:${lineNumber(contents, match.index ?? 0)}: shipped ACP entrypoint bypasses SDK control`,
1889
+ );
1890
+ }
1891
+ }
1892
+ if (file === "packages/coding-agent/src/commands/mcp-serve.ts") {
1893
+ if (
1894
+ !/from\s*["'][^"']*sdk\/mcp\/server["']/.test(contents) ||
1895
+ !/from\s*["'][^"']*coordinator-mcp\/server["']/.test(contents) ||
1896
+ !/runSdkMcpStdio\s*\(/.test(contents) ||
1897
+ !/runCoordinatorMcpStdio\s*\(/.test(contents)
1898
+ ) {
1899
+ violations.push(`${file}: shipped MCP command does not dispatch the SDK MCP server`);
1900
+ }
1901
+ }
1902
+
1903
+ const createsListener =
1904
+ /\b(?:Bun\.(?:serve|listen)|\w+\.createServer\s*\(|\w+\.listen\s*\(|new\s+NotificationServer\s*\()/.test(
1905
+ contents,
1906
+ );
1907
+ const importsSessionInternals =
1908
+ /import[\s\S]*?from\s*["'][^"']*(?:agent-session|sdk\/host\/control|session\/agent-session)["']/.test(
1909
+ contents,
1910
+ );
1911
+ if (
1912
+ createsListener &&
1913
+ importsSessionInternals &&
1914
+ file.startsWith("packages/coding-agent/src/") &&
1915
+ !sanctionedServerHosts.has(file)
1916
+ ) {
1917
+ violations.push(`${file}: listener imports AgentSession or dispatch internals outside a sanctioned host`);
1918
+ }
1919
+
1920
+ if (isProductionTypeScriptOrJavaScript(file)) {
1921
+ if (file === coordinatorMcpRoot) {
1922
+ for (const occurrence of tmuxPrimitiveOccurrences(contents)) {
1923
+ const detail =
1924
+ occurrence.primitive === "capture-pane" || occurrence.primitive === "pipe-pane"
1925
+ ? "coordinator MCP reads tmux pane content outside SDK queries"
1926
+ : `tmux ${occurrence.primitive} content injection is outside sanctioned process lifecycle`;
1927
+ violations.push(`${file}:${lineNumber(contents, occurrence.start)}: ${detail}`);
1928
+ }
1929
+ } else {
1930
+ violations.push(...tmuxMachineBusViolations(file, contents));
1931
+ }
1932
+ if (
1933
+ file === teamWorkersTmuxPath &&
1934
+ !/^export const SKC_TEAM_CONTINUATION_PROMPT =\n\t"Continue only your current claimed SKC team task\. Re-read current SKC team state; do not replay prior output; report status\.";$/m.test(
1935
+ contents,
1936
+ )
1937
+ )
1938
+ violations.push(
1939
+ `${file}: stalled-worker continuation prompt must remain the exact source-controlled literal`,
1940
+ );
1941
+ }
1942
+ if (file === coordinatorMcpRoot) {
1943
+ for (const pattern of coordinatorDirectAuthorityPatterns) {
1944
+ for (const match of contents.matchAll(pattern)) {
1945
+ violations.push(
1946
+ `${file}:${lineNumber(contents, match.index ?? 0)}: coordinator MCP directly mutates AgentSession or control internals`,
1947
+ );
1948
+ }
1949
+ }
1950
+ }
1951
+ }
1952
+ violations.push(...scanMachineImportGraphs(contentsByFile));
1953
+ if (
1954
+ contentsByFile.has(coordinatorMcpRoot) &&
1955
+ !importGraphReaches(coordinatorMcpRoot, canonicalSdkClientModule, contentsByFile)
1956
+ ) {
1957
+ violations.push(
1958
+ `${coordinatorMcpRoot}: coordinator MCP does not reach the canonical SDK client through its import graph`,
1959
+ );
1960
+ }
1961
+ return violations;
1962
+ }
1963
+
1964
+ interface SelfTestFixtureOptions {
1965
+ expectedDiagnostics?: readonly string[];
1966
+ timeoutMs?: number;
1967
+ }
1968
+
1969
+ async function runSelfTestFixture(
1970
+ files: Record<string, string>,
1971
+ expectedExitCode: number,
1972
+ expectedOutput?: string,
1973
+ options: SelfTestFixtureOptions = {},
1974
+ ): Promise<void> {
1975
+ const fixture = await fs.mkdtemp(path.join(os.tmpdir(), "skc-sdk-canonicalization-"));
1976
+ try {
1977
+ for (const [file, contents] of Object.entries(files)) {
1978
+ const destination = path.join(fixture, file);
1979
+ await fs.mkdir(path.dirname(destination), { recursive: true });
1980
+ await fs.writeFile(destination, contents);
1981
+ }
1982
+ const init = Bun.spawnSync(["git", "init", "-q"], { cwd: fixture, stdout: "pipe", stderr: "pipe" });
1983
+ const add = Bun.spawnSync(["git", "add", "."], { cwd: fixture, stdout: "pipe", stderr: "pipe" });
1984
+ if (init.exitCode !== 0 || add.exitCode !== 0) throw new Error("unable to create scanner self-test fixture");
1985
+ const timeoutMs = options.timeoutMs ?? 10_000;
1986
+ const scanner = Bun.spawn([process.execPath, import.meta.path], {
1987
+ cwd: repoRoot,
1988
+ env: { ...process.env, SKC_SDK_CANONICALIZATION_SCAN_ROOT: fixture },
1989
+ stdout: "pipe",
1990
+ stderr: "pipe",
1991
+ timeout: timeoutMs,
1992
+ });
1993
+ const [exitCode, stdout, stderr] = await Promise.all([
1994
+ scanner.exited,
1995
+ new Response(scanner.stdout).text(),
1996
+ new Response(scanner.stderr).text(),
1997
+ ]);
1998
+ const output = `${stdout}${stderr}`;
1999
+ if (scanner.signalCode !== null) {
2000
+ throw new Error(`self-test timed out after ${timeoutMs}ms: ${output}`);
2001
+ }
2002
+ if (exitCode !== expectedExitCode) {
2003
+ throw new Error(`self-test expected exit ${expectedExitCode}, got ${exitCode}: ${output}`);
2004
+ }
2005
+ if (expectedOutput && !output.includes(expectedOutput)) {
2006
+ throw new Error(`self-test expected output ${JSON.stringify(expectedOutput)}, got: ${output}`);
2007
+ }
2008
+ if (options.expectedDiagnostics) {
2009
+ const diagnostics = output.split(/\r?\n/).filter(line => line.endsWith(": invokes removed --mode rpc"));
2010
+ if (
2011
+ diagnostics.length !== options.expectedDiagnostics.length ||
2012
+ diagnostics.some((diagnostic, index) => diagnostic !== options.expectedDiagnostics?.[index])
2013
+ ) {
2014
+ throw new Error(
2015
+ `self-test expected diagnostics ${JSON.stringify(options.expectedDiagnostics)}, got ${JSON.stringify(diagnostics)}`,
2016
+ );
2017
+ }
2018
+ }
2019
+ } finally {
2020
+ await fs.rm(fixture, { recursive: true, force: true });
2021
+ }
2022
+ }
2023
+
2024
+ const retiredModeFixtureDirectory = "packages/coding-agent/test/fixtures/";
2025
+
2026
+ function retiredModeFixturePath(name: string): string {
2027
+ return `${retiredModeFixtureDirectory}${name}`;
2028
+ }
2029
+
2030
+ function retiredModeDiagnostic(file: string, line = 1): string {
2031
+ return `${file}:${line}: invokes removed --mode rpc`;
2032
+ }
2033
+
2034
+ interface ExactRetiredModeFixtureOptions {
2035
+ expectedOutput?: string;
2036
+ timeoutMs?: number;
2037
+ }
2038
+
2039
+ async function runExactRetiredModeFixture(
2040
+ name: string,
2041
+ contents: string,
2042
+ expectedExitCode: number,
2043
+ expectedDiagnostics: readonly string[],
2044
+ options: ExactRetiredModeFixtureOptions = {},
2045
+ ): Promise<void> {
2046
+ const file = retiredModeFixturePath(name);
2047
+ await runSelfTestFixture({ [file]: contents }, expectedExitCode, options.expectedOutput, {
2048
+ expectedDiagnostics,
2049
+ timeoutMs: options.timeoutMs,
2050
+ });
2051
+ }
2052
+
2053
+ function staticBinaryExpression(left: string, right: string, operandCount: number): string {
2054
+ return [JSON.stringify(left), JSON.stringify(right), ...Array.from({ length: operandCount - 2 }, () => '""')].join(
2055
+ " + ",
2056
+ );
2057
+ }
2058
+
2059
+ function sourceLocationAt(contents: string, offset: number): { line: number; column: number } {
2060
+ return {
2061
+ line: lineNumber(contents, offset),
2062
+ column: offset - contents.lastIndexOf("\n", offset - 1) - 1,
2063
+ };
2064
+ }
2065
+
2066
+ function staticBudgetDiagnostic(
2067
+ file: string,
2068
+ location: { line: number; column: number },
2069
+ kind: StaticAnalysisBudgetKind,
2070
+ limit: number,
2071
+ observed: number,
2072
+ ): string {
2073
+ return `${file}:${location.line}:${location.column}: static retired-mode analysis budget exceeded (kind=${kind}, limit=${limit}, observed=${observed})`;
2074
+ }
2075
+
2076
+ function aliasChainSource(bindingCount: number): string {
2077
+ const bindings = Array.from({ length: bindingCount }, (_, index) =>
2078
+ index === 0 ? 'const a0 = "rpc";' : `const a${index} = a${index - 1};`,
2079
+ );
2080
+ return `${bindings.join("\n")}\nBun.spawnSync(["--mode", a${bindingCount - 1}]);\n`;
2081
+ }
2082
+
2083
+ async function selfTest(): Promise<void> {
2084
+ await runSelfTestFixture(
2085
+ { "packages/coding-agent/package.json": '{"exports":{"./modes/rpc/*":"./src/modes/rpc/*.ts"}}\n' },
2086
+ 1,
2087
+ "removed RPC mode remains externally exported",
2088
+ );
2089
+ await runSelfTestFixture(
2090
+ { "packages/coding-agent/package.json": '{"exports":{"./modes/rpc-compat/*":"./src/modes/rpc-compat/*.ts"}}\n' },
2091
+ 1,
2092
+ "removed RPC mode remains externally exported",
2093
+ );
2094
+ await runSelfTestFixture(
2095
+ {
2096
+ "packages/coding-agent/test/fixtures/rpc-compat-mode.ts": 'Bun.spawnSync(["skc", "--mode", "rpc-compat"]);\n',
2097
+ },
2098
+ 1,
2099
+ "invokes removed --mode rpc",
2100
+ );
2101
+ await runSelfTestFixture(
2102
+ {
2103
+ "packages/coding-agent/test/fixtures/bridge-compat-mode.ts":
2104
+ 'Bun.spawnSync(["skc", "--mode", "bridge-compat"]);\n',
2105
+ },
2106
+ 1,
2107
+ "invokes removed --mode rpc",
2108
+ );
2109
+ await runSelfTestFixture(
2110
+ {
2111
+ "packages/coding-agent/test/fixtures/aliased-retired-modes.ts":
2112
+ 'const rpcMode = "rpc";\nlet bridgeMode = "bridge-compat";\nvar unattendedMode = "unattended";\nBun.spawnSync(["skc", "--mode", rpcMode]);\nBun.spawnSync(["skc", "--mode", bridgeMode]);\nBun.spawnSync(["skc", "--mode", unattendedMode]);\n',
2113
+ },
2114
+ 1,
2115
+ "invokes removed --mode rpc",
2116
+ );
2117
+ await runSelfTestFixture(
2118
+ {
2119
+ "packages/coding-agent/test/fixtures/constructed-aliased-retired-modes.ts":
2120
+ 'const rpcPrefix = "r";\nconst rpcMode = rpcPrefix + "pc";\nconst bridgeMode = ["brid", "ge-compat"].join("");\nconst unattendedPrefix = "un";\nvar unattendedMode = unattendedPrefix + "attended";\nconst args = ["skc", "--mode", rpcMode];\nBun.spawnSync(args);\nBun.spawnSync(["skc", "--mode", bridgeMode]);\nBun.spawnSync(["skc", "--mode", unattendedMode]);\n',
2121
+ },
2122
+ 1,
2123
+ "invokes removed --mode rpc",
2124
+ );
2125
+ await runExactRetiredModeFixture(
2126
+ "typed-rpc-alias.ts",
2127
+ 'const retiredMode: string = "rpc"; Bun.spawnSync(["skc", "--mode", retiredMode]);\n',
2128
+ 1,
2129
+ [retiredModeDiagnostic(retiredModeFixturePath("typed-rpc-alias.ts"))],
2130
+ );
2131
+ await runExactRetiredModeFixture(
2132
+ "typed-bridge-alias.ts",
2133
+ 'const retiredMode: string = "bridge-compat"; Bun.spawnSync(["skc", "--mode", retiredMode]);\n',
2134
+ 1,
2135
+ [retiredModeDiagnostic(retiredModeFixturePath("typed-bridge-alias.ts"))],
2136
+ );
2137
+ await runExactRetiredModeFixture(
2138
+ "typed-unattended-alias.ts",
2139
+ 'const retiredMode: string = "unattended"; Bun.spawnSync(["skc", "--mode", retiredMode]);\n',
2140
+ 1,
2141
+ [retiredModeDiagnostic(retiredModeFixturePath("typed-unattended-alias.ts"))],
2142
+ );
2143
+ await runExactRetiredModeFixture(
2144
+ "ts-as-string.ts",
2145
+ 'const mode = "rpc" as string; Bun.spawnSync(["skc", "--mode", mode]);\n',
2146
+ 1,
2147
+ [retiredModeDiagnostic(retiredModeFixturePath("ts-as-string.ts"))],
2148
+ );
2149
+ await runExactRetiredModeFixture(
2150
+ "ts-as-const.ts",
2151
+ 'const mode = "rpc" as const; Bun.spawnSync(["skc", "--mode", mode]);\n',
2152
+ 1,
2153
+ [retiredModeDiagnostic(retiredModeFixturePath("ts-as-const.ts"))],
2154
+ );
2155
+ await runExactRetiredModeFixture(
2156
+ "ts-use-assertion.ts",
2157
+ 'const mode = "rpc"; Bun.spawnSync(["skc", "--mode", mode as string]);\n',
2158
+ 1,
2159
+ [retiredModeDiagnostic(retiredModeFixturePath("ts-use-assertion.ts"))],
2160
+ );
2161
+ await runExactRetiredModeFixture(
2162
+ "ts-angle-assertion.ts",
2163
+ 'const mode = <string>"rpc"; Bun.spawnSync(["skc", "--mode", mode]);\n',
2164
+ 1,
2165
+ [retiredModeDiagnostic(retiredModeFixturePath("ts-angle-assertion.ts"))],
2166
+ );
2167
+ await runExactRetiredModeFixture(
2168
+ "ts-satisfies.ts",
2169
+ 'const mode = "rpc" satisfies string; Bun.spawnSync(["skc", "--mode", mode]);\n',
2170
+ 1,
2171
+ [retiredModeDiagnostic(retiredModeFixturePath("ts-satisfies.ts"))],
2172
+ );
2173
+ await runExactRetiredModeFixture(
2174
+ "ts-non-null.ts",
2175
+ 'const mode = ("rpc" as string)!; Bun.spawnSync(["skc", "--mode", mode]);\n',
2176
+ 1,
2177
+ [retiredModeDiagnostic(retiredModeFixturePath("ts-non-null.ts"))],
2178
+ );
2179
+ await runExactRetiredModeFixture(
2180
+ "parenthesized-alias.ts",
2181
+ 'const mode = (("rpc")); Bun.spawnSync(["skc", "--mode", mode]);\n',
2182
+ 1,
2183
+ [retiredModeDiagnostic(retiredModeFixturePath("parenthesized-alias.ts"))],
2184
+ );
2185
+ await runExactRetiredModeFixture(
2186
+ "typed-alias-chain.ts",
2187
+ 'const prefix: string = "r"; const mode = (prefix + "pc") as string; Bun.spawnSync(["skc", "--mode", mode]);\n',
2188
+ 1,
2189
+ [retiredModeDiagnostic(retiredModeFixturePath("typed-alias-chain.ts"))],
2190
+ );
2191
+ await runExactRetiredModeFixture(
2192
+ "template-alias.ts",
2193
+ `const prefix = "r"; const mode = \`\${prefix}pc\`; Bun.spawnSync(["skc", "--mode", mode]);\n`,
2194
+ 1,
2195
+ [retiredModeDiagnostic(retiredModeFixturePath("template-alias.ts"))],
2196
+ );
2197
+ await runExactRetiredModeFixture(
2198
+ "literal-join-alias.ts",
2199
+ 'const mode = ["r", "pc"].join(""); Bun.spawnSync(["skc", "--mode", mode]);\n',
2200
+ 1,
2201
+ [retiredModeDiagnostic(retiredModeFixturePath("literal-join-alias.ts"))],
2202
+ );
2203
+ await runExactRetiredModeFixture(
2204
+ "constructed-mode-flag-alias.ts",
2205
+ 'const flag = ["--", "mode"].join(""); const mode: string = "rpc"; Bun.spawnSync(["skc", flag, mode]);\n',
2206
+ 1,
2207
+ [retiredModeDiagnostic(retiredModeFixturePath("constructed-mode-flag-alias.ts"))],
2208
+ );
2209
+ await runExactRetiredModeFixture(
2210
+ "constructed-mode-flag-join.ts",
2211
+ 'Bun.spawnSync(["skc", ["--m", "ode"].join(""), "rpc"]);\n',
2212
+ 1,
2213
+ [retiredModeDiagnostic(retiredModeFixturePath("constructed-mode-flag-join.ts"))],
2214
+ );
2215
+ await runExactRetiredModeFixture(
2216
+ "constructed-mode-flag-binary.ts",
2217
+ 'const mode: string = "rpc"; Bun.spawnSync(["skc", "--m" + "ode", mode]);\n',
2218
+ 1,
2219
+ [retiredModeDiagnostic(retiredModeFixturePath("constructed-mode-flag-binary.ts"))],
2220
+ );
2221
+ await runExactRetiredModeFixture(
2222
+ "constructed-mode-flag-template.ts",
2223
+ `const suffix = "ode"; Bun.spawnSync(["skc", \`--m\${suffix}\`, "rpc"]);\n`,
2224
+ 1,
2225
+ [retiredModeDiagnostic(retiredModeFixturePath("constructed-mode-flag-template.ts"))],
2226
+ );
2227
+ await runExactRetiredModeFixture(
2228
+ "constructed-mode-flag-aliased.ts",
2229
+ 'const flag = ["--m", "ode"].join(""); const mode: string = "rpc"; Bun.spawnSync(["skc", flag, mode]);\n',
2230
+ 1,
2231
+ [retiredModeDiagnostic(retiredModeFixturePath("constructed-mode-flag-aliased.ts"))],
2232
+ );
2233
+ await runExactRetiredModeFixture(
2234
+ "inner-retired-shadow.ts",
2235
+ 'const mode = "acp";\n{ const mode: string = "rpc"; Bun.spawnSync(["skc", "--mode", mode]); }\n',
2236
+ 1,
2237
+ [retiredModeDiagnostic(retiredModeFixturePath("inner-retired-shadow.ts"), 2)],
2238
+ );
2239
+ await runExactRetiredModeFixture(
2240
+ "closure-forward-const.ts",
2241
+ 'const launch = () => Bun.spawnSync(["skc", "--mode", mode]);\nconst mode = "rpc";\nlaunch();\n',
2242
+ 1,
2243
+ [retiredModeDiagnostic(retiredModeFixturePath("closure-forward-const.ts"), 1)],
2244
+ );
2245
+ await runExactRetiredModeFixture(
2246
+ "safe-block-shadow.ts",
2247
+ 'const mode = "rpc"; { const mode = "acp"; Bun.spawnSync(["skc", "--mode", mode]); }\n',
2248
+ 0,
2249
+ [],
2250
+ );
2251
+ await runExactRetiredModeFixture(
2252
+ "parameter-shadow.ts",
2253
+ 'const mode = "rpc"; function launch(mode: string) { Bun.spawnSync(["skc", "--mode", mode]); } launch("acp");\n',
2254
+ 0,
2255
+ [],
2256
+ );
2257
+ await runExactRetiredModeFixture(
2258
+ "catch-shadow.ts",
2259
+ 'const mode = "rpc"; try { throw "acp"; } catch (mode) { Bun.spawnSync(["skc", "--mode", mode]); }\n',
2260
+ 0,
2261
+ [],
2262
+ );
2263
+ await runExactRetiredModeFixture(
2264
+ "destructure-shadow.ts",
2265
+ 'const mode = "rpc"; const { mode: shadow } = { mode: "acp" }; Bun.spawnSync(["skc", "--mode", shadow]);\n',
2266
+ 0,
2267
+ [],
2268
+ );
2269
+ await runExactRetiredModeFixture(
2270
+ "sibling-shadow.ts",
2271
+ '{ const mode = "rpc"; void mode; } { const mode = "acp"; Bun.spawnSync(["skc", "--mode", mode]); }\n',
2272
+ 0,
2273
+ [],
2274
+ );
2275
+ await runExactRetiredModeFixture(
2276
+ "direct-tdz.ts",
2277
+ 'Bun.spawnSync(["skc", "--mode", mode]); const mode = "rpc";\n',
2278
+ 0,
2279
+ [],
2280
+ );
2281
+ await runExactRetiredModeFixture(
2282
+ "pre-use-safe-to-retired.ts",
2283
+ 'let mode = "acp"; mode = "rpc"; Bun.spawnSync(["skc", "--mode", mode]);\n',
2284
+ 1,
2285
+ [retiredModeDiagnostic(retiredModeFixturePath("pre-use-safe-to-retired.ts"))],
2286
+ );
2287
+ await runExactRetiredModeFixture(
2288
+ "pre-use-retired-to-safe.ts",
2289
+ 'let mode = "rpc"; mode = "acp"; Bun.spawnSync(["skc", "--mode", mode]);\n',
2290
+ 0,
2291
+ [],
2292
+ );
2293
+ await runExactRetiredModeFixture(
2294
+ "later-safe-write.ts",
2295
+ 'let mode = "rpc"; Bun.spawnSync(["skc", "--mode", mode]); mode = "acp";\n',
2296
+ 1,
2297
+ [retiredModeDiagnostic(retiredModeFixturePath("later-safe-write.ts"))],
2298
+ );
2299
+ await runExactRetiredModeFixture(
2300
+ "later-retired-write.ts",
2301
+ 'let mode = "acp"; Bun.spawnSync(["skc", "--mode", mode]); mode = "rpc";\n',
2302
+ 0,
2303
+ [],
2304
+ );
2305
+ await runExactRetiredModeFixture(
2306
+ "branch-write.ts",
2307
+ 'let mode = "acp"; if (condition) mode = "rpc"; Bun.spawnSync(["skc", "--mode", mode]);\n',
2308
+ 0,
2309
+ [],
2310
+ );
2311
+ await runExactRetiredModeFixture(
2312
+ "compound-write.ts",
2313
+ 'let mode = "rpc"; mode += "-compat"; Bun.spawnSync(["skc", "--mode", mode]);\n',
2314
+ 0,
2315
+ [],
2316
+ );
2317
+ await runExactRetiredModeFixture(
2318
+ "update-write.ts",
2319
+ 'let mode = "rpc"; mode++; Bun.spawnSync(["skc", "--mode", mode]);\n',
2320
+ 0,
2321
+ [],
2322
+ );
2323
+ await runExactRetiredModeFixture(
2324
+ "dynamic-member-controls.ts",
2325
+ 'const dynamicMode = process.env.MODE; const state = { mode: "rpc" }; Bun.spawnSync(["skc", "--mode", dynamicMode]); Bun.spawnSync(["skc", "--mode", state.mode]);\n',
2326
+ 0,
2327
+ [],
2328
+ );
2329
+ await runExactRetiredModeFixture(
2330
+ "typed-acp-control.ts",
2331
+ 'const mode: string = "acp"; Bun.spawnSync(["skc", "--mode", mode]);\n',
2332
+ 0,
2333
+ [],
2334
+ );
2335
+ await runExactRetiredModeFixture("unused-retired-alias.ts", 'const mode = "rpc"; void mode;\n', 0, []);
2336
+ await runExactRetiredModeFixture(
2337
+ "unrelated-array.ts",
2338
+ 'const values = ["rpc", "bridge-compat", "unattended"]; void values;\n',
2339
+ 0,
2340
+ [],
2341
+ );
2342
+ await runExactRetiredModeFixture(
2343
+ "cycle.ts",
2344
+ 'const a = b; const b = a; Bun.spawnSync(["skc", "--mode", a]);\n',
2345
+ 0,
2346
+ [],
2347
+ { timeoutMs: 2_000 },
2348
+ );
2349
+ await runExactRetiredModeFixture("deduplicated-direct-mode.ts", 'Bun.spawnSync(["skc", "--mode", "rpc"]);\n', 1, [
2350
+ retiredModeDiagnostic(retiredModeFixturePath("deduplicated-direct-mode.ts")),
2351
+ ]);
2352
+ await runExactRetiredModeFixture(
2353
+ "harmless-comment.ts",
2354
+ '// RPC compatibility was retired; use ACP instead.\nconst mode = "acp";\nvoid mode;\n',
2355
+ 0,
2356
+ [],
2357
+ );
2358
+ const parserFixtures: ReadonlyArray<readonly [string, string]> = [
2359
+ ["parser-js.js", 'const mode = "acp";\n'],
2360
+ ["parser-jsx.jsx", "const element = <div />;\nvoid element;\n"],
2361
+ ["parser-mjs.mjs", 'export const mode = "acp";\n'],
2362
+ ["parser-cjs.cjs", 'const mode = "acp";\n'],
2363
+ ["parser-ts.ts", 'const mode: string = "acp";\n'],
2364
+ ["parser-tsx.tsx", "const element: JSX.Element = <div />;\nvoid element;\n"],
2365
+ ["parser-mts.mts", 'export const mode: string = "acp";\n'],
2366
+ ["parser-cts.cts", 'const mode: string = "acp";\n'],
2367
+ ["parser-d-ts.d.ts", "declare const mode: string;\n"],
2368
+ ["parser-d-mts.d.mts", "export declare const mode: string;\n"],
2369
+ ["parser-d-cts.d.cts", "declare const mode: string;\n"],
2370
+ ["parser-import-attributes.js", 'import value from "./fixture.json" with { type: "json" };\nvoid value;\n'],
2371
+ ["parser-shebang.js", '#!/usr/bin/env bun\nconst mode = "acp";\n'],
2372
+ ];
2373
+ for (const [name, contents] of parserFixtures) {
2374
+ await runExactRetiredModeFixture(name, contents, 0, []);
2375
+ }
2376
+ const malformedSource = "const mode: string = ;\n";
2377
+ await runExactRetiredModeFixture("malformed.ts", malformedSource, 2, [], {
2378
+ expectedOutput: `${retiredModeFixturePath("malformed.ts")}:1:21: static retired-mode analysis parse failed`,
2379
+ });
2380
+ await runSelfTestFixture(
2381
+ {
2382
+ "packages/coding-agent/test/fixtures/python-text-only.py":
2383
+ 'def launch():\n subprocess.run(["skc", "--mode", "rpc"])\n',
2384
+ },
2385
+ 1,
2386
+ undefined,
2387
+ {
2388
+ expectedDiagnostics: [retiredModeDiagnostic("packages/coding-agent/test/fixtures/python-text-only.py", 2)],
2389
+ },
2390
+ );
2391
+ // 128/129 literals joined by binary nodes consume exactly 255/257 expression steps.
2392
+ const expressionUnderSource = `Bun.spawnSync(["--mode", ${staticBinaryExpression("r", "pc", 128)}]);\n`;
2393
+ await runExactRetiredModeFixture("expression-step-under-limit.ts", expressionUnderSource, 1, [
2394
+ retiredModeDiagnostic(retiredModeFixturePath("expression-step-under-limit.ts")),
2395
+ ]);
2396
+ const expressionOverSource = `Bun.spawnSync(["--mode", ${staticBinaryExpression("r", "pc", 129)}]);\n`;
2397
+ const expressionOverOffset = expressionOverSource.lastIndexOf('""');
2398
+ await runExactRetiredModeFixture("expression-step-over-limit.ts", expressionOverSource, 2, [], {
2399
+ expectedOutput: staticBudgetDiagnostic(
2400
+ retiredModeFixturePath("expression-step-over-limit.ts"),
2401
+ sourceLocationAt(expressionOverSource, expressionOverOffset),
2402
+ "expression_steps",
2403
+ 256,
2404
+ 257,
2405
+ ),
2406
+ });
2407
+ // a63 through a0 follows 64 bindings and evaluates 65 nodes including the literal initializer.
2408
+ const aliasUnderSource = aliasChainSource(64);
2409
+ await runExactRetiredModeFixture("alias-hop-under-limit.ts", aliasUnderSource, 1, [
2410
+ retiredModeDiagnostic(retiredModeFixturePath("alias-hop-under-limit.ts"), 65),
2411
+ ]);
2412
+ const aliasOverSource = aliasChainSource(65);
2413
+ const aliasOverOffset = aliasOverSource.indexOf("a0;", aliasOverSource.indexOf("const a1"));
2414
+ await runExactRetiredModeFixture("alias-hop-over-limit.ts", aliasOverSource, 2, [], {
2415
+ expectedOutput: staticBudgetDiagnostic(
2416
+ retiredModeFixturePath("alias-hop-over-limit.ts"),
2417
+ sourceLocationAt(aliasOverSource, aliasOverOffset),
2418
+ "alias_hops",
2419
+ 64,
2420
+ 65,
2421
+ ),
2422
+ });
2423
+ // Four arrays each consume one --mode literal plus a 255-node safe value: 4 × 256 = 1,024.
2424
+ const fileUnderSource = Array.from(
2425
+ { length: 4 },
2426
+ () => `["--mode", ${staticBinaryExpression("a", "cp", 128)}];`,
2427
+ ).join("\n");
2428
+ await runExactRetiredModeFixture("file-step-under-limit.ts", `${fileUnderSource}\n`, 0, []);
2429
+ const fileOverSource = `${fileUnderSource}\n["--mode", "acp"];\n`;
2430
+ const fileOverOffset = fileOverSource.lastIndexOf('"--mode"');
2431
+ await runExactRetiredModeFixture("file-step-over-limit.ts", fileOverSource, 2, [], {
2432
+ expectedOutput: staticBudgetDiagnostic(
2433
+ retiredModeFixturePath("file-step-over-limit.ts"),
2434
+ sourceLocationAt(fileOverSource, fileOverOffset),
2435
+ "file_steps",
2436
+ 1_024,
2437
+ 1_025,
2438
+ ),
2439
+ });
2440
+ const unrelatedFileBudgetSource = Array.from(
2441
+ { length: 4 },
2442
+ () => `["unrelated", ${staticBinaryExpression("a", "cp", 128)}];`,
2443
+ ).join("\n");
2444
+ await runExactRetiredModeFixture(
2445
+ "unrelated-file-step-control.ts",
2446
+ `${unrelatedFileBudgetSource}\n["--mode", "rpc"];\n`,
2447
+ 1,
2448
+ [retiredModeDiagnostic(retiredModeFixturePath("unrelated-file-step-control.ts"), 5)],
2449
+ );
2450
+
2451
+ await runSelfTestFixture(
2452
+ { "packages/coding-agent/src/modes/bridge-compat/legacy.ts": "export const retired = true;\n" },
2453
+ 1,
2454
+ "retired RPC/bridge/unattended ingress source survived",
2455
+ );
2456
+ await runSelfTestFixture(
2457
+ {
2458
+ "packages/coding-agent/test/fixtures/constructed-rpc-option.ts":
2459
+ 'const mode = ["r", "pc"].join("");\nconst flags = { options: [mode] };\nvoid flags;\n',
2460
+ },
2461
+ 1,
2462
+ "invokes removed --mode rpc",
2463
+ );
2464
+ await runSelfTestFixture(
2465
+ {
2466
+ "packages/coding-agent/src/consumer.ts":
2467
+ 'const legacyIngress = ["./modes", "unattended-compat"].join("/");\nvoid legacyIngress;\n',
2468
+ },
2469
+ 1,
2470
+ "invokes removed --mode rpc",
2471
+ );
2472
+ await runSelfTestFixture(
2473
+ {
2474
+ "packages/coding-agent/package.json":
2475
+ '{"exports":{"./commands/skc-runtime-bridge":"./src/bridge.ts","./unattended":"./src/unattended.ts"}}\n',
2476
+ },
2477
+ 1,
2478
+ "removed bridge or unattended surface remains externally exported",
2479
+ );
2480
+ await runSelfTestFixture(
2481
+ {
2482
+ "packages/coding-agent/package.json":
2483
+ '{"exports":{"./modes/rpc/*":null,"./commands/skc-runtime-bridge":null,"./unattended":null,"./modes/shared/agent-wire/*":null}}\n',
2484
+ },
2485
+ 0,
2486
+ );
2487
+ await runSelfTestFixture(
2488
+ {
2489
+ "packages/coding-agent/package.json": '{"exports":{"./modes/*":{"import":"./src/modes/*.ts"}}}\n',
2490
+ },
2491
+ 1,
2492
+ "retired agent-wire surface remains externally exported",
2493
+ );
2494
+ await runSelfTestFixture(
2495
+ {
2496
+ "packages/coding-agent/package.json":
2497
+ '{"exports":{"./modes/*":{"import":"./src/modes/*.ts"},"./modes/shared/agent-wire/*":null}}\n',
2498
+ },
2499
+ 0,
2500
+ );
2501
+ await runSelfTestFixture(
2502
+ {
2503
+ "packages/coding-agent/package.json": '{"exports":{"./*":"./src/*.ts"}}\n',
2504
+ "packages/coding-agent/src/unattended/legacy.ts": "export const retired = true;\n",
2505
+ },
2506
+ 1,
2507
+ "retired ingress source packages/coding-agent/src/unattended/legacy.ts is reachable through broad export",
2508
+ );
2509
+ await runSelfTestFixture(
2510
+ {
2511
+ "packages/coding-agent/package.json": '{"exports":{"./*":"./src/*.ts"}}\n',
2512
+ "packages/coding-agent/src/rpc.ts": "export const retired = true;\n",
2513
+ },
2514
+ 1,
2515
+ "retired ingress source packages/coding-agent/src/rpc.ts is reachable through broad export",
2516
+ );
2517
+ await runSelfTestFixture(
2518
+ {
2519
+ "packages/coding-agent/package.json": '{"exports":{"./*":"./src/*.ts"}}\n',
2520
+ "packages/coding-agent/src/bridge.ts": "export const retired = true;\n",
2521
+ },
2522
+ 1,
2523
+ "retired ingress source packages/coding-agent/src/bridge.ts is reachable through broad export",
2524
+ );
2525
+ await runSelfTestFixture(
2526
+ {
2527
+ "packages/coding-agent/package.json": '{"exports":{"./*":"./src/*.ts"}}\n',
2528
+ "packages/coding-agent/src/unattended.ts": "export const retired = true;\n",
2529
+ },
2530
+ 1,
2531
+ "retired ingress source packages/coding-agent/src/unattended.ts is reachable through broad export",
2532
+ );
2533
+ await runSelfTestFixture(
2534
+ {
2535
+ "packages/coding-agent/package.json": '{"exports":{"./runtime-mcp/*":"./src/runtime-mcp/*.ts"}}\n',
2536
+ "packages/coding-agent/src/runtime-mcp/tool-bridge.ts": "export const neutral = true;\n",
2537
+ },
2538
+ 0,
2539
+ );
2540
+ const realManifest = await Bun.file(path.join(repoRoot, packageManifestPath)).text();
2541
+ await runSelfTestFixture({ [packageManifestPath]: realManifest }, 0);
2542
+ await runSelfTestFixture(
2543
+ {
2544
+ "package.json": '{"catalog":{"@sayknow-cli/bridge-client":"0.10.1"}}\n',
2545
+ "packages/bridge-client/package.json": '{"name":"@sayknow-cli/bridge-client"}\n',
2546
+ "packages/bridge-client/src/index.ts": "export class SdkClient {}\nexport type SdkClientOptions = {};\n",
2547
+ "packages/coding-agent/package.json": '{"dependencies":{"@sayknow-cli/bridge-client":"catalog:"}}\n',
2548
+ "packages/coding-agent/src/sdk/client/client.ts":
2549
+ 'export { SdkClient } from "@sayknow-cli/bridge-client";\nexport type { SdkClientOptions } from "@sayknow-cli/bridge-client";\n',
2550
+ },
2551
+ 0,
2552
+ );
2553
+ await runSelfTestFixture(
2554
+ {
2555
+ "packages/bridge-client/package.json":
2556
+ '{"name":"@sayknow-cli/bridge-client","dependencies":{"unsafe":"1.0.0"}}\n',
2557
+ },
2558
+ 1,
2559
+ "canonical bridge-client package must remain runtime-dependency-free",
2560
+ );
2561
+ await runSelfTestFixture(
2562
+ {
2563
+ "packages/bridge-client/src/client.ts": 'import { HostControl } from "./host-control";\nvoid HostControl;\n',
2564
+ },
2565
+ 1,
2566
+ "bridge-client imports host or session authority",
2567
+ );
2568
+ await runSelfTestFixture(
2569
+ {
2570
+ "packages/bridge-client/src/client.ts": 'Bun.serve({ fetch() { return new Response("ok"); } });\n',
2571
+ },
2572
+ 1,
2573
+ "bridge-client owns forbidden host, session, server, listener, or process authority",
2574
+ );
2575
+ await runSelfTestFixture(
2576
+ {
2577
+ "packages/bridge-client/src/client.ts":
2578
+ 'import { AgentSession } from "../../coding-agent/src/session/agent-session";\nvoid AgentSession;\n',
2579
+ },
2580
+ 1,
2581
+ "bridge-client import escapes its package",
2582
+ );
2583
+ await runSelfTestFixture(
2584
+ {
2585
+ "packages/bridge-client/src/client.ts":
2586
+ 'import { SdkClient } from "@sayknow-cli/coding-agent";\nvoid SdkClient;\n',
2587
+ },
2588
+ 1,
2589
+ "bridge-client imports coding-agent or AgentSession authority",
2590
+ );
2591
+ await runSelfTestFixture(
2592
+ { "packages/renamed-workspace/package.json": '{"name":"@sayknow-cli/bridge-client"}\n' },
2593
+ 1,
2594
+ "declares unsupported bridge-client package metadata",
2595
+ );
2596
+ await runSelfTestFixture(
2597
+ {
2598
+ "packages/coding-agent/src/consumer.ts":
2599
+ 'import { BridgeClient } from "@sayknow-cli/bridge-client";\nvoid BridgeClient;\n',
2600
+ },
2601
+ 1,
2602
+ "historical BridgeClient surface survived",
2603
+ );
2604
+ await runSelfTestFixture(
2605
+ {
2606
+ "packages/coding-agent/src/consumer.ts":
2607
+ 'import { handshake } from "@sayknow-cli/bridge-client";\nvoid handshake;\n',
2608
+ },
2609
+ 1,
2610
+ "imports historical bridge-client protocol surface",
2611
+ );
2612
+ await runSelfTestFixture(
2613
+ {
2614
+ "packages/coding-agent/src/consumer.ts":
2615
+ 'import { commands } from "@sayknow-cli/bridge-client";\nvoid commands;\n',
2616
+ },
2617
+ 1,
2618
+ "imports historical bridge-client protocol surface",
2619
+ );
2620
+ await runSelfTestFixture(
2621
+ {
2622
+ "packages/coding-agent/src/consumer.ts":
2623
+ 'import { SdkClient } from "@sayknow-cli/bridge-client/commands";\nvoid SdkClient;\n',
2624
+ },
2625
+ 1,
2626
+ "imports unsupported bridge-client subpath",
2627
+ );
2628
+ await runSelfTestFixture(
2629
+ {
2630
+ "packages/coding-agent/src/consumer.ts": 'import { SSE } from "@sayknow-cli/bridge-client";\nvoid SSE;\n',
2631
+ },
2632
+ 1,
2633
+ "imports historical bridge-client protocol surface",
2634
+ );
2635
+ await runSelfTestFixture(
2636
+ {
2637
+ "packages/coding-agent/src/consumer.ts":
2638
+ 'import { control } from "@sayknow-cli/bridge-client";\nvoid control;\n',
2639
+ },
2640
+ 1,
2641
+ "imports historical bridge-client protocol surface",
2642
+ );
2643
+ await runSelfTestFixture(
2644
+ {
2645
+ "packages/coding-agent/src/consumer.ts":
2646
+ 'import { legacyUnattended } from "./unattended";\nvoid legacyUnattended;\n',
2647
+ },
2648
+ 1,
2649
+ "imports removed unattended surface",
2650
+ );
2651
+ await runSelfTestFixture(
2652
+ {
2653
+ "packages/coding-agent/test/fixtures/neutral-name.ts": 'Bun.spawnSync(["skc", "--mode", "rpc"]);\n',
2654
+ },
2655
+ 1,
2656
+ "invokes removed --mode rpc",
2657
+ );
2658
+ await runSelfTestFixture(
2659
+ {
2660
+ "packages/coding-agent/test/fixtures/neutral-expect.ts":
2661
+ 'expect(Bun.spawnSync(["skc", "--mode", "rpc"])).toBeDefined();\n',
2662
+ },
2663
+ 1,
2664
+ "invokes removed --mode rpc",
2665
+ );
2666
+ await runSelfTestFixture({ "docs/rpc-removal.md": "The RPC compatibility fixture was removed.\n" }, 0);
2667
+ await runSelfTestFixture(
2668
+ { "scripts/skc-session/prompt.sh": "#!/usr/bin/env bash\n" },
2669
+ 1,
2670
+ "retired tmux machine prompt or viewing helper survived",
2671
+ );
2672
+ await runSelfTestFixture(
2673
+ {
2674
+ "scripts/skc-session/unsafe.sh":
2675
+ "#!/usr/bin/env bash\ntmux load-buffer -b prompt -\ntmux capture-pane -p -t session\n",
2676
+ },
2677
+ 1,
2678
+ "published shell helper performs tmux machine prompt injection or pane viewing",
2679
+ );
2680
+ const canonicalCreateFixture = `#!/usr/bin/env bash
2681
+ [[ $# -eq 2 ]] || { echo "Usage: $0 <session-name> <worktree-path>" >&2; exit 2; }
2682
+ command = [os.environ["SKC_SESSION_SKC_BIN"]]
2683
+ child = subprocess.Popen(command)
2684
+ completed = subprocess.run([os.environ["SKC_SESSION_SKC_BIN"], "--internal-tmux-owner-isolation"], input="{}")
2685
+ PLAN_RESPONSE="$(printf '%s\\n' "$PLAN_LINE" | "$SKC_BIN" --internal-tmux-owner-isolation)"
2686
+ POST_SPAWN_RESPONSE="$(printf '%s\\n' "$PLAN_LINE" | "$SKC_BIN" --internal-tmux-owner-isolation)"
2687
+ GENERATION_PUBLISH_RESPONSE="$(printf '%s\\n' "$GENERATION_PUBLISH_REQUEST" | "$SKC_BIN" --internal-tmux-owner-isolation)"
2688
+ if verdict="$(printf '%s\\n' "$request" | timeout "1s" "$SKC_SESSION_SKC_BIN" --internal-tmux-owner-isolation)"; then
2689
+ true
2690
+ fi
2691
+ `;
2692
+ await runSelfTestFixture({ "scripts/skc-session/create.sh": canonicalCreateFixture }, 0);
2693
+ await runSelfTestFixture(
2694
+ { "scripts/skc-session/create.sh": `${canonicalCreateFixture}\nsubprocess.Popen(["skc"])\n` },
2695
+ 1,
2696
+ "must not launch a literal skc executable",
2697
+ );
2698
+ await runSelfTestFixture(
2699
+ { "scripts/skc-session/create.sh": `${canonicalCreateFixture}\nlauncher="skc"\n"$launcher"\n` },
2700
+ 1,
2701
+ "must not alias or wrap the skc executable",
2702
+ );
2703
+ await runSelfTestFixture(
2704
+ {
2705
+ "scripts/skc-session/create.sh": `${canonicalCreateFixture}\nrunner(){ skc --internal-tmux-owner-isolation; }\nrunner\n`,
2706
+ },
2707
+ 1,
2708
+ "must not alias or wrap the skc executable",
2709
+ );
2710
+ await runSelfTestFixture(
2711
+ { "scripts/skc-session/create.sh": `${canonicalCreateFixture}\n"$SKC_BIN" --internal-tmux-owner-isolation\n` },
2712
+ 1,
2713
+ "invokes SKC with a non-lifecycle startup argument",
2714
+ );
2715
+ await runSelfTestFixture(
2716
+ { "scripts/skc-session/create.sh": `${canonicalCreateFixture}\nSKC_SESSION_FLAGS=unsafe\n` },
2717
+ 1,
2718
+ "exposes caller-provided startup arguments",
2719
+ );
2720
+ await runSelfTestFixture(
2721
+ {
2722
+ "scripts/skc-session/create.sh": canonicalCreateFixture.replace(
2723
+ '[[ $# -eq 2 ]] || { echo "Usage: $0 <session-name> <worktree-path>" >&2; exit 2; }',
2724
+ "[[ $# -eq 2 ]] || true",
2725
+ ),
2726
+ },
2727
+ 1,
2728
+ "must have one fail-closed exact two-operand guard",
2729
+ );
2730
+ await runSelfTestFixture(
2731
+ {
2732
+ "scripts/skc-session/create.sh": canonicalCreateFixture.replace(
2733
+ '[[ $# -eq 2 ]] || { echo "Usage: $0 <session-name> <worktree-path>" >&2; exit 2; }',
2734
+ 'set -- rewritten positional arguments\n[[ $# -eq 2 ]] || { echo "Usage: $0 <session-name> <worktree-path>" >&2; exit 2; }',
2735
+ ),
2736
+ },
2737
+ 1,
2738
+ "must not rewrite positional arguments before launch",
2739
+ );
2740
+ await runSelfTestFixture(
2741
+ {
2742
+ "scripts/skc-session/create.sh": canonicalCreateFixture.replace(
2743
+ '[[ $# -eq 2 ]] || { echo "Usage: $0 <session-name> <worktree-path>" >&2; exit 2; }',
2744
+ 'shift\n[[ $# -eq 2 ]] || { echo "Usage: $0 <session-name> <worktree-path>" >&2; exit 2; }',
2745
+ ),
2746
+ },
2747
+ 1,
2748
+ "must not rewrite positional arguments before launch",
2749
+ );
2750
+ await runSelfTestFixture(
2751
+ {
2752
+ "scripts/skc-session/create.sh": canonicalCreateFixture.replace(
2753
+ '[[ $# -eq 2 ]] || { echo "Usage: $0 <session-name> <worktree-path>" >&2; exit 2; }',
2754
+ 'exit(){ return 0; }\n[[ $# -eq 2 ]] || { echo "Usage: $0 <session-name> <worktree-path>" >&2; exit 2; }',
2755
+ ),
2756
+ },
2757
+ 1,
2758
+ "must not neutralize the exact two-operand guard",
2759
+ );
2760
+ await runSelfTestFixture(
2761
+ {
2762
+ "scripts/skc-session/create.sh": canonicalCreateFixture.replace(
2763
+ '[[ $# -eq 2 ]] || { echo "Usage: $0 <session-name> <worktree-path>" >&2; exit 2; }',
2764
+ 'if false; then\n[[ $# -eq 2 ]] || { echo "Usage: $0 <session-name> <worktree-path>" >&2; exit 2; }\nfi',
2765
+ ),
2766
+ },
2767
+ 1,
2768
+ "must have one fail-closed exact two-operand guard",
2769
+ );
2770
+ await runSelfTestFixture(
2771
+ {
2772
+ "scripts/skc-session/create.sh": canonicalCreateFixture.replace(
2773
+ '[[ $# -eq 2 ]] || { echo "Usage: $0 <session-name> <worktree-path>" >&2; exit 2; }',
2774
+ 'guard() {\n[[ $# -eq 2 ]] || { echo "Usage: $0 <session-name> <worktree-path>" >&2; exit 2; }\n}',
2775
+ ),
2776
+ },
2777
+ 1,
2778
+ "must have one fail-closed exact two-operand guard",
2779
+ );
2780
+ await runSelfTestFixture(
2781
+ {
2782
+ "scripts/skc-session/create.sh": canonicalCreateFixture.replace(
2783
+ '[[ $# -eq 2 ]] || { echo "Usage: $0 <session-name> <worktree-path>" >&2; exit 2; }',
2784
+ '(\n[[ $# -eq 2 ]] || { echo "Usage: $0 <session-name> <worktree-path>" >&2; exit 2; }\n) || true',
2785
+ ),
2786
+ },
2787
+ 1,
2788
+ "must have one fail-closed exact two-operand guard",
2789
+ );
2790
+ await runSelfTestFixture(
2791
+ {
2792
+ "scripts/skc-session/create.sh": canonicalCreateFixture.replace(
2793
+ '[[ $# -eq 2 ]] || { echo "Usage: $0 <session-name> <worktree-path>" >&2; exit 2; }',
2794
+ '{\n[[ $# -eq 2 ]] || { echo "Usage: $0 <session-name> <worktree-path>" >&2; exit 2; }\n} || true',
2795
+ ),
2796
+ },
2797
+ 1,
2798
+ "must have one fail-closed exact two-operand guard",
2799
+ );
2800
+ await runSelfTestFixture(
2801
+ {
2802
+ "scripts/skc-session/create.sh": canonicalCreateFixture.replace(
2803
+ '[[ $# -eq 2 ]] || { echo "Usage: $0 <session-name> <worktree-path>" >&2; exit 2; }',
2804
+ 'true &&\n[[ $# -eq 2 ]] || { echo "Usage: $0 <session-name> <worktree-path>" >&2; exit 2; }',
2805
+ ),
2806
+ },
2807
+ 1,
2808
+ "must have one fail-closed exact two-operand guard",
2809
+ );
2810
+ await runSelfTestFixture(
2811
+ {
2812
+ "scripts/skc-session/create.sh": canonicalCreateFixture.replace(
2813
+ '[[ $# -eq 2 ]] || { echo "Usage: $0 <session-name> <worktree-path>" >&2; exit 2; }',
2814
+ 'true && \\\n[[ $# -eq 2 ]] || { echo "Usage: $0 <session-name> <worktree-path>" >&2; exit 2; }',
2815
+ ),
2816
+ },
2817
+ 1,
2818
+ "must have one fail-closed exact two-operand guard",
2819
+ );
2820
+ await runSelfTestFixture(
2821
+ {
2822
+ "scripts/skc-session/create.sh": canonicalCreateFixture.replace(
2823
+ "child = subprocess.Popen(command)",
2824
+ 'command.extend(["--file", "task.md"])\nchild = subprocess.Popen(command)',
2825
+ ),
2826
+ },
2827
+ 1,
2828
+ "must launch exactly SKC_SESSION_SKC_BIN with zero startup arguments",
2829
+ );
2830
+ await runSelfTestFixture(
2831
+ {
2832
+ "scripts/skc-session/create.sh": canonicalCreateFixture.replace(
2833
+ "child = subprocess.Popen(command)",
2834
+ 'command.append("--file")\nchild = subprocess.Popen(command)',
2835
+ ),
2836
+ },
2837
+ 1,
2838
+ "must launch exactly SKC_SESSION_SKC_BIN with zero startup arguments",
2839
+ );
2840
+ await runSelfTestFixture(
2841
+ {
2842
+ "scripts/skc-session/create.sh": canonicalCreateFixture.replace(
2843
+ "child = subprocess.Popen(command)",
2844
+ 'command.insert(1, "--file")\nchild = subprocess.Popen(command)',
2845
+ ),
2846
+ },
2847
+ 1,
2848
+ "must launch exactly SKC_SESSION_SKC_BIN with zero startup arguments",
2849
+ );
2850
+ await runSelfTestFixture(
2851
+ {
2852
+ "scripts/skc-session/create.sh": canonicalCreateFixture.replace(
2853
+ "child = subprocess.Popen(command)",
2854
+ 'command += ["--file", "task.md"]\nchild = subprocess.Popen(command)',
2855
+ ),
2856
+ },
2857
+ 1,
2858
+ "must launch exactly SKC_SESSION_SKC_BIN with zero startup arguments",
2859
+ );
2860
+ await runSelfTestFixture(
2861
+ {
2862
+ "scripts/skc-session/create.sh": canonicalCreateFixture.replace(
2863
+ "child = subprocess.Popen(command)",
2864
+ "mutate(command)\nchild = subprocess.Popen(command)",
2865
+ ),
2866
+ },
2867
+ 1,
2868
+ "must not construct or wrap a non-lifecycle SKC argv",
2869
+ );
2870
+ await runSelfTestFixture(
2871
+ {
2872
+ "scripts/skc-session/create.sh": canonicalCreateFixture.replace(
2873
+ "child = subprocess.Popen(command)",
2874
+ 'getattr(command, "append")("--file")\nchild = subprocess.Popen(command)',
2875
+ ),
2876
+ },
2877
+ 1,
2878
+ "must not construct or wrap a non-lifecycle SKC argv",
2879
+ );
2880
+ await runSelfTestFixture(
2881
+ {
2882
+ "scripts/skc-session/create.sh": canonicalCreateFixture.replace(
2883
+ "child = subprocess.Popen(command)",
2884
+ 'globals()["command"].append("--file")\nchild = subprocess.Popen(command)',
2885
+ ),
2886
+ },
2887
+ 1,
2888
+ "must not construct or wrap a non-lifecycle SKC argv",
2889
+ );
2890
+ await runSelfTestFixture(
2891
+ {
2892
+ "scripts/skc-session/create.sh": canonicalCreateFixture.replace(
2893
+ "child = subprocess.Popen(command)",
2894
+ `vars()[f'{"com"}mand'] = ["skc", "--file"]\nchild = subprocess.Popen(command)`,
2895
+ ),
2896
+ },
2897
+ 1,
2898
+ "must not construct or wrap a non-lifecycle SKC argv",
2899
+ );
2900
+ await runSelfTestFixture(
2901
+ {
2902
+ "scripts/skc-session/create.sh": canonicalCreateFixture.replace(
2903
+ "child = subprocess.Popen(command)",
2904
+ 'child = subprocess.Popen(command + ["--file", "task.md"])',
2905
+ ),
2906
+ },
2907
+ 1,
2908
+ "must invoke SKC only with zero interactive argv or the exact owner-isolation lifecycle argv",
2909
+ );
2910
+ await runSelfTestFixture(
2911
+ {
2912
+ "scripts/skc-session/create.sh": canonicalCreateFixture.replace(
2913
+ "child = subprocess.Popen(command)",
2914
+ 'launch = command + ["--file", "task.md"]\nchild = subprocess.Popen(launch)',
2915
+ ),
2916
+ },
2917
+ 1,
2918
+ "must not construct or wrap a non-lifecycle SKC argv",
2919
+ );
2920
+ await runSelfTestFixture(
2921
+ {
2922
+ "scripts/skc-session/create.sh": `${canonicalCreateFixture}\nlaunch = [os.environ["SKC_SESSION_SKC_BIN"], "--file", "task.md"]\nsubprocess.Popen(launch)\n`,
2923
+ },
2924
+ 1,
2925
+ "must not construct or wrap a non-lifecycle SKC argv",
2926
+ );
2927
+ await runSelfTestFixture(
2928
+ {
2929
+ "scripts/skc-session/create.sh": canonicalCreateFixture.replace(
2930
+ '[os.environ["SKC_SESSION_SKC_BIN"], "--internal-tmux-owner-isolation"]',
2931
+ '[\n os.environ["SKC_SESSION_SKC_BIN"],\n "--internal-tmux-owner-isolation",\n "--file",\n "task.md",\n]',
2932
+ ),
2933
+ },
2934
+ 1,
2935
+ "must invoke SKC only with zero interactive argv or the exact owner-isolation lifecycle argv",
2936
+ );
2937
+ await runSelfTestFixture(
2938
+ {
2939
+ "scripts/skc-session/create.sh": canonicalCreateFixture.replace(
2940
+ '"$SKC_BIN" --internal-tmux-owner-isolation',
2941
+ 'captured=$("$SKC_BIN" --file task.md)',
2942
+ ),
2943
+ },
2944
+ 1,
2945
+ "invokes SKC with a non-lifecycle startup argument",
2946
+ );
2947
+ await runSelfTestFixture(
2948
+ {
2949
+ "scripts/skc-session/create.sh": canonicalCreateFixture.replace(
2950
+ '"$SKC_BIN" --internal-tmux-owner-isolation',
2951
+ 'command "$SKC_BIN" --file task.md',
2952
+ ),
2953
+ },
2954
+ 1,
2955
+ "invokes SKC with a non-lifecycle startup argument",
2956
+ );
2957
+ await runSelfTestFixture(
2958
+ {
2959
+ "scripts/skc-session/create.sh": canonicalCreateFixture.replace(
2960
+ '"$SKC_BIN" --internal-tmux-owner-isolation',
2961
+ 'exec "$SKC_BIN" --file task.md',
2962
+ ),
2963
+ },
2964
+ 1,
2965
+ "invokes SKC with a non-lifecycle startup argument",
2966
+ );
2967
+ await runSelfTestFixture(
2968
+ {
2969
+ "scripts/skc-session/create.sh": canonicalCreateFixture.replace(
2970
+ '"$SKC_BIN" --internal-tmux-owner-isolation',
2971
+ 'command -p "$SKC_BIN" --file task.md',
2972
+ ),
2973
+ },
2974
+ 1,
2975
+ "must not construct or wrap a non-lifecycle SKC argv",
2976
+ );
2977
+ await runSelfTestFixture(
2978
+ {
2979
+ "scripts/skc-session/create.sh": canonicalCreateFixture.replace(
2980
+ '"$SKC_BIN" --internal-tmux-owner-isolation',
2981
+ 'exec -a skc "$SKC_BIN" --file task.md',
2982
+ ),
2983
+ },
2984
+ 1,
2985
+ "must not construct or wrap a non-lifecycle SKC argv",
2986
+ );
2987
+ await runSelfTestFixture(
2988
+ {
2989
+ "scripts/skc-session/create.sh": canonicalCreateFixture.replace(
2990
+ '"$SKC_BIN" --internal-tmux-owner-isolation',
2991
+ 'LAUNCH=(\n "$SKC_BIN"\n --file\n task.md\n)\n"$' + '{LAUNCH[@]}"',
2992
+ ),
2993
+ },
2994
+ 1,
2995
+ "must not construct or wrap a non-lifecycle SKC argv",
2996
+ );
2997
+ await runSelfTestFixture(
2998
+ {
2999
+ "scripts/skc-session/create.sh": canonicalCreateFixture.replace(
3000
+ '"$SKC_BIN" --internal-tmux-owner-isolation',
3001
+ 'launcher="$SKC_BIN"\n"$launcher" --file task.md',
3002
+ ),
3003
+ },
3004
+ 1,
3005
+ "must not construct or wrap a non-lifecycle SKC argv",
3006
+ );
3007
+ await runSelfTestFixture(
3008
+ {
3009
+ "scripts/skc-session/create.sh": canonicalCreateFixture.replace(
3010
+ '"$SKC_BIN" --internal-tmux-owner-isolation',
3011
+ '"$SKC_BIN" --internal-tmux-owner-isolation \\\n --file task.md',
3012
+ ),
3013
+ },
3014
+ 1,
3015
+ "invokes SKC with a non-lifecycle startup argument",
3016
+ );
3017
+ await runSelfTestFixture(
3018
+ {
3019
+ "scripts/skc-session/create.sh": canonicalCreateFixture.replace(
3020
+ '"$SKC_BIN" --internal-tmux-owner-isolation',
3021
+ '"$SKC_BIN" \\\n --file task.md',
3022
+ ),
3023
+ },
3024
+ 1,
3025
+ "invokes SKC with a non-lifecycle startup argument",
3026
+ );
3027
+ await runSelfTestFixture(
3028
+ {
3029
+ "scripts/skc-session/create.sh": canonicalCreateFixture.replace(
3030
+ '"$SKC_BIN" --internal-tmux-owner-isolation',
3031
+ '"$SKC_BIN" \\\n session status',
3032
+ ),
3033
+ },
3034
+ 1,
3035
+ "invokes SKC with a non-lifecycle startup argument",
3036
+ );
3037
+ await runSelfTestFixture(
3038
+ {
3039
+ "scripts/skc-session/create.sh": canonicalCreateFixture.replace(
3040
+ '"$SKC_BIN" --internal-tmux-owner-isolation',
3041
+ '"$SKC_BIN" \\\n "write a prompt"',
3042
+ ),
3043
+ },
3044
+ 1,
3045
+ "invokes SKC with a non-lifecycle startup argument",
3046
+ );
3047
+ await runSelfTestFixture(
3048
+ {
3049
+ "scripts/skc-session/create.sh": canonicalCreateFixture.replace(
3050
+ '"$SKC_BIN" --internal-tmux-owner-isolation',
3051
+ '"$SKC_BIN" --internal-tmux-owner-isolation \\\n "write a prompt"',
3052
+ ),
3053
+ },
3054
+ 1,
3055
+ "invokes SKC with a non-lifecycle startup argument",
3056
+ );
3057
+ const realCreate = await Bun.file(path.join(repoRoot, "scripts/skc-session/create.sh")).text();
3058
+ await runSelfTestFixture({ "scripts/skc-session/create.sh": realCreate }, 0);
3059
+ await runSelfTestFixture(
3060
+ { "scripts/skc-session/watch-output.sh": "#!/usr/bin/env bash\n$TMUX_BIN \\\n pipe-pane -t session 'sink'\n" },
3061
+ 1,
3062
+ "published shell helper performs tmux machine prompt injection or pane viewing",
3063
+ );
3064
+ await runSelfTestFixture(
3065
+ { "docs/skc-session-clawhip-routing.md": "$TMUX_BIN \\\n pipe-pane -t owner 'sink'\n" },
3066
+ 1,
3067
+ "published machine documentation directs tmux prompt or viewing access",
3068
+ );
3069
+ await runSelfTestFixture(
3070
+ {
3071
+ "docs/skc-session-clawhip-routing.md": './scripts/skc-session/create.sh bot /repo \\\n --print "task"\n',
3072
+ },
3073
+ 1,
3074
+ "published machine documentation directs tmux prompt or viewing access",
3075
+ );
3076
+ await runSelfTestFixture(
3077
+ { "scripts/skc-session/watch-output.sh": "#!/usr/bin/env bash\ntmux pipe-pane -t session 'sink'\n" },
3078
+ 1,
3079
+ "published shell helper performs tmux machine prompt injection or pane viewing",
3080
+ );
3081
+ await runSelfTestFixture(
3082
+ { "docs/skc-session-clawhip-routing.md": "scripts/skc-session/tail.sh visible output\n" },
3083
+ 1,
3084
+ "published machine documentation directs tmux prompt or viewing access",
3085
+ );
3086
+ await runSelfTestFixture(
3087
+ { "docs/skc-session-clawhip-routing.md": "tmux pipe-pane -t owner 'sink'\n" },
3088
+ 1,
3089
+ "published machine documentation directs tmux prompt or viewing access",
3090
+ );
3091
+ await runSelfTestFixture(
3092
+ { "docs/skc-session-clawhip-routing.md": './scripts/skc-session/create.sh bot /repo --print "task"\n' },
3093
+ 1,
3094
+ "published machine documentation directs tmux prompt or viewing access",
3095
+ );
3096
+ await runSelfTestFixture(
3097
+ {
3098
+ "docs/skc-session-clawhip-routing.md": "./scripts/skc-session/create.sh bot /repo\n",
3099
+ },
3100
+ 0,
3101
+ );
3102
+ await runSelfTestFixture(
3103
+ {
3104
+ "packages/coding-agent/src/unsanctioned.ts": 'Bun.spawnSync(["tmux", "send-keys", "-t", "pane", "prompt"]);\n',
3105
+ },
3106
+ 1,
3107
+ "tmux send-keys content injection is outside sanctioned process lifecycle",
3108
+ );
3109
+ await runSelfTestFixture(
3110
+ {
3111
+ "packages/coding-agent/src/skc-runtime/team-runtime.ts":
3112
+ 'Bun.spawnSync([config.tmux_command, "send-keys", "-t", paneId, "prompt"]);\n',
3113
+ },
3114
+ 1,
3115
+ "tmux send-keys content injection is outside sanctioned process lifecycle",
3116
+ );
3117
+ const canonicalTeamRuntimeSendKeysFixture = `
3118
+ async function continueStalledSkcTeamWorkers(): Promise<void> {
3119
+ const revalidationReason = null;
3120
+ if (revalidationReason) return;
3121
+ function shouldDispatchWorkerWithSendKeys(tmuxCommand: string, platform: NodeJS.Platform = process.platform): boolean {
3122
+ return platform === "win32" || path.basename(tmuxCommand).toLowerCase() === "psmux";
3123
+ }
3124
+ const useSendKeysFallback = shouldDispatchWorkerWithSendKeys(config.tmux_command);
3125
+ const splitArgs = [...(useSendKeysFallback ? [] : [workerCommand]),];
3126
+ if (useSendKeysFallback) {
3127
+ Bun.spawnSync([config.tmux_command, "send-keys", "-l", "-t", paneId, workerCommand], {
3128
+ stdout: "ignore",
3129
+ stderr: "ignore",
3130
+ });
3131
+ const sendKeys = Bun.spawnSync([config.tmux_command, "send-keys", "-t", paneId, "Enter"], {
3132
+ stdout: "ignore",
3133
+ stderr: "ignore",
3134
+ });
3135
+ void sendKeys.exitCode;
3136
+ }
3137
+ const SKC_TEAM_CONTINUATION_PROMPT = "Continue only your current claimed SKC team task. Re-read current SKC team state; do not replay prior output; report status.";
3138
+ const SKC_TEAM_CONTINUATION_DISPATCH_TIMEOUT_MS = 5_000;
3139
+ const args = Object.freeze([
3140
+ "send-keys",
3141
+ "-l",
3142
+ "-t",
3143
+ worker.pane_id,
3144
+ SKC_TEAM_CONTINUATION_PROMPT,
3145
+ ";",
3146
+ "send-keys",
3147
+ "-t",
3148
+ worker.pane_id,
3149
+ "Enter",
3150
+ ]);
3151
+
3152
+ const dispatch = skcTeamRuntimeTestSeams?.continuationTmuxDispatch
3153
+ ? skcTeamRuntimeTestSeams.continuationTmuxDispatch(config.tmux_command, args)
3154
+ : Bun.spawnSync([config.tmux_command, ...args], {
3155
+ stdout: "ignore",
3156
+ stderr: "ignore",
3157
+ timeout: SKC_TEAM_CONTINUATION_DISPATCH_TIMEOUT_MS,
3158
+ });
3159
+ }
3160
+ async function monitorSkcTeam(): Promise<void> {
3161
+ await withSkcTeamTaskMutation(taskStore(dir), async capability => {
3162
+ await continueStalledSkcTeamWorkers();
3163
+ await reconcileSkcTeamStaleClaimsUnlocked(workerOrchestrationRuntime, teamName, dir, config, env, capability);
3164
+ });
3165
+ }
3166
+ `;
3167
+ await runSelfTestFixture(
3168
+ { "packages/coding-agent/src/skc-runtime/team-runtime.ts": canonicalTeamRuntimeSendKeysFixture },
3169
+ 0,
3170
+ );
3171
+ await runSelfTestFixture(
3172
+ {
3173
+ "packages/coding-agent/src/skc-runtime/team-runtime.ts": canonicalTeamRuntimeSendKeysFixture.replace(
3174
+ "async function continueStalledSkcTeamWorkers(): Promise<void>",
3175
+ "async function relocatedContinuation(): Promise<void>",
3176
+ ),
3177
+ },
3178
+ 1,
3179
+ "tmux send-keys content injection is outside sanctioned process lifecycle",
3180
+ );
3181
+ await runSelfTestFixture(
3182
+ {
3183
+ "packages/coding-agent/src/skc-runtime/team-runtime.ts": canonicalTeamRuntimeSendKeysFixture.replace(
3184
+ "if (revalidationReason) return;",
3185
+ "if (revalidationReason) {}",
3186
+ ),
3187
+ },
3188
+ 1,
3189
+ "tmux send-keys content injection is outside sanctioned process lifecycle",
3190
+ );
3191
+ await runSelfTestFixture(
3192
+ {
3193
+ "packages/coding-agent/src/skc-runtime/team-runtime.ts": canonicalTeamRuntimeSendKeysFixture.replace(
3194
+ "await continueStalledSkcTeamWorkers();",
3195
+ "",
3196
+ ),
3197
+ },
3198
+ 1,
3199
+ "tmux send-keys content injection is outside sanctioned process lifecycle",
3200
+ );
3201
+ await runSelfTestFixture(
3202
+ {
3203
+ "packages/coding-agent/src/skc-runtime/team-runtime.ts": canonicalTeamRuntimeSendKeysFixture.replace(
3204
+ "await continueStalledSkcTeamWorkers();\n\t\tawait reconcileSkcTeamStaleClaimsUnlocked(workerOrchestrationRuntime, teamName, dir, config, env, capability);",
3205
+ "await reconcileSkcTeamStaleClaimsUnlocked(workerOrchestrationRuntime, teamName, dir, config, env, capability);\n\t\tawait continueStalledSkcTeamWorkers();",
3206
+ ),
3207
+ },
3208
+ 1,
3209
+ "tmux send-keys content injection is outside sanctioned process lifecycle",
3210
+ );
3211
+ await runSelfTestFixture(
3212
+ {
3213
+ "packages/coding-agent/src/skc-runtime/team-runtime.ts": canonicalTeamRuntimeSendKeysFixture.replace(
3214
+ "const dispatch =",
3215
+ 'args.push("forged");\nconst dispatch =',
3216
+ ),
3217
+ },
3218
+ 1,
3219
+ "tmux send-keys content injection is outside sanctioned process lifecycle",
3220
+ );
3221
+ await runSelfTestFixture(
3222
+ {
3223
+ "packages/coding-agent/src/skc-runtime/team-runtime.ts": canonicalTeamRuntimeSendKeysFixture.replace(
3224
+ "report status.",
3225
+ "report injected status.",
3226
+ ),
3227
+ },
3228
+ 1,
3229
+ "tmux send-keys content injection is outside sanctioned process lifecycle",
3230
+ );
3231
+ await runSelfTestFixture(
3232
+ {
3233
+ "packages/coding-agent/src/skc-runtime/team-runtime.ts": canonicalTeamRuntimeSendKeysFixture.replace(
3234
+ 'return platform === "win32" || path.basename(tmuxCommand).toLowerCase() === "psmux";',
3235
+ "return true;",
3236
+ ),
3237
+ },
3238
+ 1,
3239
+ "tmux send-keys content injection is outside sanctioned process lifecycle",
3240
+ );
3241
+ await runSelfTestFixture(
3242
+ {
3243
+ "packages/coding-agent/src/skc-runtime/team-runtime.ts": canonicalTeamRuntimeSendKeysFixture.replace(
3244
+ 'return platform === "win32" || path.basename(tmuxCommand).toLowerCase() === "psmux";',
3245
+ 'return platform === "win32" || path.basename(tmuxCommand).toLowerCase() === "psmux" || tmuxCommand === "tmux";',
3246
+ ),
3247
+ },
3248
+ 1,
3249
+ "tmux send-keys content injection is outside sanctioned process lifecycle",
3250
+ );
3251
+ await runSelfTestFixture(
3252
+ {
3253
+ "packages/coding-agent/src/skc-runtime/team-runtime.ts": `${canonicalTeamRuntimeSendKeysFixture}\nBun.spawnSync([config.tmux_command, "send-keys", "-t", paneId, "prompt"]);\n`,
3254
+ },
3255
+ 1,
3256
+ "tmux send-keys content injection is outside sanctioned process lifecycle",
3257
+ );
3258
+ await runSelfTestFixture(
3259
+ {
3260
+ "packages/coding-agent/src/skc-runtime/team-runtime.ts": canonicalTeamRuntimeSendKeysFixture.replaceAll(
3261
+ "worker.pane_id",
3262
+ '"%99"',
3263
+ ),
3264
+ },
3265
+ 1,
3266
+ "tmux send-keys content injection is outside sanctioned process lifecycle",
3267
+ );
3268
+ await runSelfTestFixture(
3269
+ {
3270
+ "packages/coding-agent/src/skc-runtime/team-runtime.ts": canonicalTeamRuntimeSendKeysFixture.replace(
3271
+ 'SKC_TEAM_CONTINUATION_PROMPT,\n\t";",',
3272
+ "`$" + "{SKC_TEAM_CONTINUATION_PROMPT}" + '`,\n\t";",',
3273
+ ),
3274
+ },
3275
+ 1,
3276
+ "tmux send-keys content injection is outside sanctioned process lifecycle",
3277
+ );
3278
+ await runSelfTestFixture(
3279
+ {
3280
+ "packages/coding-agent/src/skc-runtime/team-runtime.ts": canonicalTeamRuntimeSendKeysFixture.replace(
3281
+ '"send-keys",\n\t"-l",\n\t"-t",\n\tworker.pane_id,\n\tSKC_TEAM_CONTINUATION_PROMPT,\n\t";",\n\t"send-keys",\n\t"-t",\n\tworker.pane_id,\n\t"Enter",',
3282
+ '"send-keys", "-t", worker.pane_id, "Enter", ";", "send-keys", "-l", "-t", worker.pane_id, SKC_TEAM_CONTINUATION_PROMPT,',
3283
+ ),
3284
+ },
3285
+ 1,
3286
+ "tmux send-keys content injection is outside sanctioned process lifecycle",
3287
+ );
3288
+ await runSelfTestFixture(
3289
+ {
3290
+ "packages/coding-agent/src/skc-runtime/team-runtime.ts": canonicalTeamRuntimeSendKeysFixture.replace(
3291
+ "Bun.spawnSync([config.tmux_command, ...args]",
3292
+ 'Bun.spawnSync([config.tmux_command, "run-shell", ...args]',
3293
+ ),
3294
+ },
3295
+ 1,
3296
+ "tmux send-keys content injection is outside sanctioned process lifecycle",
3297
+ );
3298
+ await runSelfTestFixture(
3299
+ {
3300
+ "packages/coding-agent/src/coordinator-mcp/server.ts":
3301
+ 'import { SdkClient } from "../sdk/client/client";\nBun.spawnSync(["tmux", "paste-buffer", "-t", "pane"]);\nvoid SdkClient;\n',
3302
+ "packages/coding-agent/src/sdk/client/client.ts": "export class SdkClient {}\n",
3303
+ },
3304
+ 1,
3305
+ "tmux paste-buffer content injection is outside sanctioned process lifecycle",
3306
+ );
3307
+ await runSelfTestFixture(
3308
+ {
3309
+ "packages/coding-agent/src/coordinator-mcp/server.ts":
3310
+ 'import { SdkClient } from "../sdk/client/client";\nBun.spawnSync(["tmux", "set-buffer", "prompt"]);\nvoid SdkClient;\n',
3311
+ "packages/coding-agent/src/sdk/client/client.ts": "export class SdkClient {}\n",
3312
+ },
3313
+ 1,
3314
+ "tmux set-buffer content injection is outside sanctioned process lifecycle",
3315
+ );
3316
+ await runSelfTestFixture(
3317
+ {
3318
+ "packages/coding-agent/src/coordinator-mcp/server.ts":
3319
+ 'import { SdkClient } from "../sdk/client/client";\nBun.spawnSync(["tmux", "capture-pane", "-p"]);\nvoid SdkClient;\n',
3320
+ "packages/coding-agent/src/sdk/client/client.ts": "export class SdkClient {}\n",
3321
+ },
3322
+ 1,
3323
+ "coordinator MCP reads tmux pane content outside SDK queries",
3324
+ );
3325
+ await runSelfTestFixture(
3326
+ {
3327
+ "packages/coding-agent/src/unsanctioned-pane.ts": 'Bun.spawnSync(["tmux", "capture-pane", "-p"]);\n',
3328
+ },
3329
+ 1,
3330
+ "tmux capture-pane pane access is outside sanctioned test fixtures",
3331
+ );
3332
+ await runSelfTestFixture(
3333
+ {
3334
+ "packages/coding-agent/src/unsanctioned-pane.ts": 'Bun.spawnSync("$TMUX_BIN capture-pane -p -t pane");\n',
3335
+ },
3336
+ 1,
3337
+ "tmux capture-pane pane access is outside sanctioned test fixtures",
3338
+ );
3339
+ await runSelfTestFixture(
3340
+ {
3341
+ "packages/coding-agent/src/unsanctioned-pane.ts":
3342
+ 'const paneViewer = ["capture", "pane"].join("-");\nBun.spawnSync(["tmux", paneViewer, "-p"]);\n',
3343
+ },
3344
+ 1,
3345
+ "tmux capture-pane pane access is outside sanctioned test fixtures",
3346
+ );
3347
+ await runSelfTestFixture(
3348
+ {
3349
+ "packages/coding-agent/src/unsanctioned-pane.js":
3350
+ 'const paneViewer = ["pipe", "pane"].join("-");\nBun.spawnSync(["tmux", paneViewer, "sink"]);\n',
3351
+ },
3352
+ 1,
3353
+ "tmux pipe-pane pane access is outside sanctioned test fixtures",
3354
+ );
3355
+ await runSelfTestFixture(
3356
+ {
3357
+ "packages/coding-agent/src/unsanctioned-pane.js": 'Bun.spawnSync(["tmux", "pipe-pane", "sink"]);\n',
3358
+ },
3359
+ 1,
3360
+ "tmux pipe-pane pane access is outside sanctioned test fixtures",
3361
+ );
3362
+ await runSelfTestFixture(
3363
+ {
3364
+ "packages/coding-agent/src/unsanctioned-pane.ts":
3365
+ "const paneAction = `capture-$" +
3366
+ '{"pane"}`;\nconst executable = ["tm", "ux"].join("");\nconst argv = [executable, paneAction, "-p"];\nconst invoke = Bun.spawnSync;\ninvoke(argv);\n',
3367
+ },
3368
+ 1,
3369
+ "tmux capture-pane pane access is outside sanctioned test fixtures",
3370
+ );
3371
+ await runSelfTestFixture(
3372
+ {
3373
+ "packages/coding-agent/src/unsanctioned-pane.ts":
3374
+ 'const paneAction = "pipe" + "-pane";\nfunction runTmux(argv: string[]) { return Bun.spawnSync(["tmux", ...argv]); }\nrunTmux([paneAction, "sink"]);\n',
3375
+ },
3376
+ 1,
3377
+ "tmux pipe-pane pane access is outside sanctioned test fixtures",
3378
+ );
3379
+ await runSelfTestFixture(
3380
+ {
3381
+ "packages/coding-agent/src/unsanctioned-input.ts":
3382
+ 'const executable = ["tm", "ux"].join("");\nconst primitive = ["send", "keys"].join("-");\nconst argv = [executable, primitive, "-t", "pane", "prompt"];\nconst invoke = Bun.spawnSync;\ninvoke(argv);\n',
3383
+ },
3384
+ 1,
3385
+ "tmux send-keys content injection is outside sanctioned process lifecycle",
3386
+ );
3387
+ await runSelfTestFixture(
3388
+ {
3389
+ "packages/coding-agent/src/unsanctioned-input.ts":
3390
+ 'const primitive = "paste" + "-buffer";\nfunction runTmux(argv: string[]) { return Bun.spawnSync(["tmux", ...argv]); }\nrunTmux([primitive, "-t", "pane"]);\n',
3391
+ },
3392
+ 1,
3393
+ "tmux paste-buffer content injection is outside sanctioned process lifecycle",
3394
+ );
3395
+ await runSelfTestFixture(
3396
+ {
3397
+ "packages/coding-agent/test/fixtures/sanctioned-tmux-pane.ts":
3398
+ 'Bun.spawnSync(["tmux", "capture-pane", "-p"]);\nBun.spawnSync(["tmux", "pipe-pane", "sink"]);\n',
3399
+ },
3400
+ 0,
3401
+ );
3402
+ await runSelfTestFixture(
3403
+ {
3404
+ "packages/coding-agent/src/coordinator-mcp/server.ts":
3405
+ 'import { SdkClient } from "../sdk/client/client";\nimport { AgentSession } from "../session/agent-session";\nconst session = {} as AgentSession;\nsession.prompt("bypass");\nvoid SdkClient;\n',
3406
+ "packages/coding-agent/src/sdk/client/client.ts": "export class SdkClient {}\n",
3407
+ "packages/coding-agent/src/session/agent-session.ts": "export class AgentSession {}\n",
3408
+ },
3409
+ 1,
3410
+ "coordinator MCP directly mutates AgentSession or control internals",
3411
+ );
3412
+ await runSelfTestFixture(
3413
+ {
3414
+ "packages/coding-agent/src/coordinator-mcp/server.ts":
3415
+ 'import { SdkClient } from "../sdk/client/client";\nimport { control } from "../sdk/host/control";\ncontrol({ operation: "turn.prompt" });\nvoid SdkClient;\n',
3416
+ "packages/coding-agent/src/sdk/client/client.ts": "export class SdkClient {}\n",
3417
+ "packages/coding-agent/src/sdk/host/control.ts": "export function control(): void {}\n",
3418
+ },
3419
+ 1,
3420
+ "coordinator MCP directly mutates AgentSession or control internals",
3421
+ );
3422
+ await runSelfTestFixture(
3423
+ {
3424
+ "packages/coding-agent/src/coordinator-mcp/server.ts":
3425
+ 'import { SdkClient } from "../sdk/client/client";\nasync function writeSessionState() { await fs.writeFile("metadata.json", "{}\\n"); }\nvoid SdkClient;\n',
3426
+ "packages/coding-agent/src/sdk/client/client.ts": "export class SdkClient {}\n",
3427
+ },
3428
+ 0,
3429
+ );
3430
+ await runSelfTestFixture(
3431
+ {
3432
+ "packages/coding-agent/src/coordinator-mcp/server.ts": "export const server = true;\n",
3433
+ "packages/coding-agent/src/sdk/client/client.ts": "export class SdkClient {}\n",
3434
+ },
3435
+ 1,
3436
+ "coordinator MCP does not reach the canonical SDK client through its import graph",
3437
+ );
3438
+ await runSelfTestFixture(
3439
+ {
3440
+ "packages/coding-agent/src/coordinator-mcp/server.ts":
3441
+ 'import { SdkClient } from "../sdk/client/client";\nexport async function startProcessLifecycle() { Bun.spawn(["tmux", "new-session", "-d"]); return SdkClient; }\n',
3442
+ "packages/coding-agent/src/sdk/client/client.ts": "export class SdkClient {}\n",
3443
+ },
3444
+ 0,
3445
+ );
3446
+ await runSelfTestFixture(
3447
+ {
3448
+ "packages/coding-agent/src/bridge-env.ts":
3449
+ "const endpoint = process.env.SKC_BRIDGE_ENDPOINT;\nvoid endpoint;\n",
3450
+ },
3451
+ 1,
3452
+ "forbidden bridge environment reference SKC_BRIDGE_ENDPOINT",
3453
+ );
3454
+ await runSelfTestFixture(
3455
+ {
3456
+ "packages/coding-agent/src/cli.ts":
3457
+ 'const flags = { mode: Flags.string({ options: ["interactive", "rpc"] }) };\nvoid flags;\n',
3458
+ },
3459
+ 1,
3460
+ "--mode option retains rpc, rpc-ui, or bridge",
3461
+ );
3462
+ await runSelfTestFixture(
3463
+ { "python/skc-rpc/src/skc_rpc/client.py": "class RpcClient: pass\n" },
3464
+ 1,
3465
+ "retired Python skc-rpc package source survived",
3466
+ );
3467
+ await runSelfTestFixture(
3468
+ { "python/roboskc/src/controller.py": "from skc_rpc import RpcClient\n" },
3469
+ 1,
3470
+ "imports removed skc_rpc Python client",
3471
+ );
3472
+ await runSelfTestFixture(
3473
+ { "scripts/legacy-controller.py": 'subprocess.run(["skc", "--mode", "rpc"])\n' },
3474
+ 1,
3475
+ "invokes removed --mode rpc",
3476
+ );
3477
+ await runSelfTestFixture(
3478
+ { "python/roboskc/pyproject.toml": '[project]\ndependencies = ["skc-rpc>=0.1.0"]\n' },
3479
+ 1,
3480
+ "declares removed skc-rpc distribution metadata",
3481
+ );
3482
+ await runSelfTestFixture(
3483
+ { "python/roboskc/src/controller.py": 'client.negotiate_unattended(actor="legacy")\n' },
3484
+ 1,
3485
+ "uses removed Python unattended protocol client negotiate_unattended",
3486
+ );
3487
+ await runSelfTestFixture(
3488
+ {
3489
+ "packages/coding-agent/test/sdk-downgrade-rollback.test.ts":
3490
+ 'const legacy = "skc --mode rpc";\nvoid legacy;\n',
3491
+ },
3492
+ 0,
3493
+ );
3494
+ await runSelfTestFixture(
3495
+ {
3496
+ "packages/coding-agent/test/sdk-removed-ingresses.test.ts":
3497
+ 'const rejected = ["--mode", "rpc"];\nvoid rejected;\n',
3498
+ },
3499
+ 0,
3500
+ );
3501
+ await runSelfTestFixture({ "docs/sdk-migration.md": "`--mode rpc` has been removed; use the SDK instead.\n" }, 0);
3502
+ await runSelfTestFixture(
3503
+ {
3504
+ "packages/coding-agent/src/internal-urls/docs-index.generated.ts":
3505
+ 'export const docs = "--mode rpc has been removed";\n',
3506
+ },
3507
+ 0,
3508
+ );
3509
+ await runSelfTestFixture({ "artifacts/closure-report.json": '{"legacy":"skc --mode rpc"}\n' }, 0);
3510
+ await runSelfTestFixture(
3511
+ { "packages/coding-agent/src/consumer.ts": 'import { legacyRpc } from "./modes/rpc/legacy";\nvoid legacyRpc;\n' },
3512
+ 1,
3513
+ "imports removed modes/rpc or modes/bridge",
3514
+ );
3515
+ await runSelfTestFixture(
3516
+ {
3517
+ "packages/coding-agent/src/unsanctioned-listener.ts":
3518
+ 'import { AgentSession } from "./agent-session";\nBun.serve({ fetch() { return new Response("ok"); } });\nvoid AgentSession;\n',
3519
+ },
3520
+ 1,
3521
+ "listener imports AgentSession or dispatch internals outside a sanctioned host",
3522
+ );
3523
+ await runSelfTestFixture(
3524
+ { "packages/coding-agent/src/modes/rpc/zombie.ts": "export const zombie = true;\n" },
3525
+ 1,
3526
+ "retired RPC/bridge/unattended ingress source survived",
3527
+ );
3528
+ await runSelfTestFixture(
3529
+ { "packages/coding-agent/src/modes/unattended/zombie.ts": "export const zombie = true;\n" },
3530
+ 1,
3531
+ "retired RPC/bridge/unattended ingress source survived",
3532
+ );
3533
+ await runSelfTestFixture(
3534
+ { "packages/coding-agent/src/bridge/zombie.ts": "export const zombie = true;\n" },
3535
+ 1,
3536
+ "retired RPC/bridge/unattended ingress source survived",
3537
+ );
3538
+ await runSelfTestFixture(
3539
+ { "packages/coding-agent/src/unattended/zombie.ts": "export const zombie = true;\n" },
3540
+ 1,
3541
+ "retired RPC/bridge/unattended ingress source survived",
3542
+ );
3543
+ await runSelfTestFixture(
3544
+ {
3545
+ "packages/coding-agent/src/modes/acp/acp-agent.ts":
3546
+ 'import { AgentSession } from "../../core/agent-session";\nconst record = {} as { session: AgentSession };\nrecord.session.prompt("bypass");\n',
3547
+ },
3548
+ 1,
3549
+ "shipped ACP entrypoint does not import the SDK ACP adapter",
3550
+ );
3551
+ await runSelfTestFixture(
3552
+ {
3553
+ "packages/coding-agent/src/commands/mcp-serve.ts":
3554
+ 'import { runCoordinatorMcpServer } from "../coordinator-mcp/server";\nvoid runCoordinatorMcpServer;\n',
3555
+ },
3556
+ 1,
3557
+ "shipped MCP command does not dispatch the SDK MCP server",
3558
+ );
3559
+ await runSelfTestFixture(
3560
+ {
3561
+ "packages/coding-agent/src/modes/acp/acp-agent.ts":
3562
+ 'import { AcpSdkAdapter } from "../../sdk/acp";\nimport "./harmless-wrapper";\nvoid AcpSdkAdapter;\n',
3563
+ "packages/coding-agent/src/modes/acp/harmless-wrapper.ts":
3564
+ 'import { AgentSession } from "../../session/agent-session";\nvoid AgentSession;\n',
3565
+ "packages/coding-agent/src/session/agent-session.ts": "export class AgentSession {}\n",
3566
+ },
3567
+ 1,
3568
+ "ACP machine entrypoint reaches forbidden AgentSession",
3569
+ );
3570
+ await runSelfTestFixture(
3571
+ {
3572
+ "packages/coding-agent/src/commands/mcp-serve.ts":
3573
+ 'import { runSdkMcpStdio } from "../sdk/mcp/server";\nimport "../harmless-wrapper";\nvoid runSdkMcpStdio;\n',
3574
+ "packages/coding-agent/src/harmless-wrapper.ts":
3575
+ 'import { ClientBridge } from "./session/client-bridge";\nvoid ClientBridge;\n',
3576
+ "packages/coding-agent/src/session/client-bridge.ts": "export class ClientBridge {}\n",
3577
+ },
3578
+ 1,
3579
+ "MCP machine entrypoint reaches forbidden direct client bridge",
3580
+ );
3581
+ await runSelfTestFixture(
3582
+ {
3583
+ "packages/coding-agent/src/commands/mcp-serve.ts":
3584
+ 'import { runSdkMcpStdio } from "../sdk/mcp/server.js";\nimport "../wrapper.js";\nvoid runSdkMcpStdio;\n',
3585
+ "packages/coding-agent/src/wrapper.ts":
3586
+ 'import { ClientBridge } from "./session/client-bridge.js";\nvoid ClientBridge;\n',
3587
+ "packages/coding-agent/src/session/client-bridge.ts": "export class ClientBridge {}\n",
3588
+ },
3589
+ 1,
3590
+ "MCP machine entrypoint reaches forbidden direct client bridge",
3591
+ );
3592
+ await runSelfTestFixture(
3593
+ {
3594
+ "packages/coding-agent/src/modes/acp/acp-agent.ts":
3595
+ 'import { AcpSdkAdapter } from "../../sdk/acp";\nimport "./adapter-wrapper";\nvoid AcpSdkAdapter;\n',
3596
+ "packages/coding-agent/src/modes/acp/adapter-wrapper.ts":
3597
+ 'import { SdkClient } from "../../sdk/client";\nvoid SdkClient;\n',
3598
+ "packages/coding-agent/src/sdk/client.ts": "export class SdkClient {}\n",
3599
+ },
3600
+ 0,
3601
+ );
3602
+ await runSelfTestFixture(
3603
+ {
3604
+ "packages/coding-agent/src/commands/acp.ts":
3605
+ 'import { AgentSession } from "../session/agent-session";\nvoid AgentSession;\n',
3606
+ },
3607
+ 1,
3608
+ "ACP command wrapper bypasses SDK/ACP/Coordinator through direct session, RPC, or tmux routing",
3609
+ );
3610
+ await runSelfTestFixture(
3611
+ {
3612
+ "packages/coding-agent/src/commands/daemon.ts": 'Bun.spawn(["tmux", "new-session", "-d"]);\n',
3613
+ },
3614
+ 1,
3615
+ "daemon command wrapper bypasses SDK/ACP/Coordinator through direct session, RPC, or tmux routing",
3616
+ );
3617
+ await runSelfTestFixture(
3618
+ {
3619
+ "packages/coding-agent/src/commands/mcp-serve.ts": 'import { RpcClient } from "../rpc";\nvoid RpcClient;\n',
3620
+ },
3621
+ 1,
3622
+ "MCP command wrapper bypasses SDK/ACP/Coordinator through direct session, RPC, or tmux routing",
3623
+ );
3624
+ await runSelfTestFixture(
3625
+ {
3626
+ "packages/coding-agent/src/main.ts":
3627
+ 'const mode = "acp";\nif (mode === "acp") {\n const session = new AgentSession();\n session.prompt("bypass");\n} else {\n void 0;\n}\n',
3628
+ },
3629
+ 1,
3630
+ "root --mode acp bypasses SDK ACP through direct session, RPC, or tmux routing",
3631
+ );
3632
+ }
3633
+
3634
+ if (process.argv.includes("--self-test")) await selfTest();
3635
+ try {
3636
+ const violations = await scan();
3637
+ if (violations.length > 0) {
3638
+ process.stderr.write(`SKC SDK canonicalization violations found:\n${violations.join("\n")}\n`);
3639
+ process.exit(1);
3640
+ }
3641
+ process.stdout.write(
3642
+ `SKC SDK canonicalization verification passed (${sanctionedServerHosts.size} sanctioned server hosts).\n`,
3643
+ );
3644
+ } catch (error) {
3645
+ process.stderr.write(`${error instanceof Error ? error.message : String(error)}\n`);
3646
+ process.exit(2);
3647
+ }