comisai 1.0.34 → 1.0.37

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 (448) hide show
  1. package/node_modules/@comis/agent/dist/background/auto-background-middleware.d.ts +11 -1
  2. package/node_modules/@comis/agent/dist/background/auto-background-middleware.js +30 -4
  3. package/node_modules/@comis/agent/dist/background/background-task-manager.d.ts +22 -2
  4. package/node_modules/@comis/agent/dist/background/background-task-manager.js +88 -40
  5. package/node_modules/@comis/agent/dist/background/background-task-persistence.js +34 -4
  6. package/node_modules/@comis/agent/dist/background/background-task-types.d.ts +59 -3
  7. package/node_modules/@comis/agent/dist/background/background-task-types.js +1 -1
  8. package/node_modules/@comis/agent/dist/background/completion-dispatcher.d.ts +130 -0
  9. package/node_modules/@comis/agent/dist/background/completion-dispatcher.js +215 -0
  10. package/node_modules/@comis/agent/dist/background/completion-formatter.d.ts +39 -0
  11. package/node_modules/@comis/agent/dist/background/completion-formatter.js +77 -0
  12. package/node_modules/@comis/agent/dist/background/completion-runner.d.ts +62 -0
  13. package/node_modules/@comis/agent/dist/background/completion-runner.js +234 -0
  14. package/node_modules/@comis/agent/dist/background/index.d.ts +10 -1
  15. package/node_modules/@comis/agent/dist/background/index.js +4 -0
  16. package/node_modules/@comis/agent/dist/background/session-resolver.d.ts +85 -0
  17. package/node_modules/@comis/agent/dist/background/session-resolver.js +78 -0
  18. package/node_modules/@comis/agent/dist/bootstrap/sections/messaging-sections.js +1 -0
  19. package/node_modules/@comis/agent/dist/bootstrap/sections/tool-descriptions.js +3 -3
  20. package/node_modules/@comis/agent/dist/bootstrap/sections/tooling-sections.d.ts +30 -2
  21. package/node_modules/@comis/agent/dist/bootstrap/sections/tooling-sections.js +51 -2
  22. package/node_modules/@comis/agent/dist/bootstrap/system-prompt-assembler.d.ts +22 -0
  23. package/node_modules/@comis/agent/dist/bootstrap/system-prompt-assembler.js +2 -2
  24. package/node_modules/@comis/agent/dist/bridge/bridge-event-handlers.d.ts +1 -5
  25. package/node_modules/@comis/agent/dist/bridge/bridge-event-handlers.js +2 -14
  26. package/node_modules/@comis/agent/dist/bridge/bridge-metrics.d.ts +43 -2
  27. package/node_modules/@comis/agent/dist/bridge/bridge-metrics.js +17 -2
  28. package/node_modules/@comis/agent/dist/bridge/pi-event-bridge.d.ts +32 -23
  29. package/node_modules/@comis/agent/dist/bridge/pi-event-bridge.js +145 -62
  30. package/node_modules/@comis/agent/dist/bridge/thinking-block-hash-invariant.d.ts +6 -7
  31. package/node_modules/@comis/agent/dist/bridge/thinking-block-hash-invariant.js +24 -25
  32. package/node_modules/@comis/agent/dist/budget/cost-tracker.d.ts +1 -1
  33. package/node_modules/@comis/agent/dist/context-engine/constants.d.ts +5 -5
  34. package/node_modules/@comis/agent/dist/context-engine/constants.js +12 -12
  35. package/node_modules/@comis/agent/dist/context-engine/context-engine.js +13 -4
  36. package/node_modules/@comis/agent/dist/context-engine/dag-annotator.d.ts +1 -2
  37. package/node_modules/@comis/agent/dist/context-engine/dag-annotator.js +1 -2
  38. package/node_modules/@comis/agent/dist/context-engine/llm-compaction.js +20 -16
  39. package/node_modules/@comis/agent/dist/context-engine/rehydration.js +6 -6
  40. package/node_modules/@comis/agent/dist/context-engine/signature-replay-scrubber.d.ts +12 -12
  41. package/node_modules/@comis/agent/dist/context-engine/signature-replay-scrubber.js +36 -22
  42. package/node_modules/@comis/agent/dist/context-engine/signature-surrogate-guard.d.ts +10 -10
  43. package/node_modules/@comis/agent/dist/context-engine/signature-surrogate-guard.js +14 -14
  44. package/node_modules/@comis/agent/dist/context-engine/thinking-block-cleaner.d.ts +11 -13
  45. package/node_modules/@comis/agent/dist/context-engine/thinking-block-cleaner.js +14 -15
  46. package/node_modules/@comis/agent/dist/context-engine/types-core.d.ts +15 -0
  47. package/node_modules/@comis/agent/dist/executor/cache-break-detection.d.ts +6 -6
  48. package/node_modules/@comis/agent/dist/executor/cache-break-detection.js +8 -8
  49. package/node_modules/@comis/agent/dist/executor/capability-index-context.d.ts +72 -0
  50. package/node_modules/@comis/agent/dist/executor/capability-index-context.js +329 -0
  51. package/node_modules/@comis/agent/dist/executor/drain-helper.d.ts +122 -0
  52. package/node_modules/@comis/agent/dist/executor/drain-helper.js +173 -0
  53. package/node_modules/@comis/agent/dist/executor/error-classifier.js +2 -2
  54. package/node_modules/@comis/agent/dist/executor/executor-context-engine-setup.d.ts +16 -0
  55. package/node_modules/@comis/agent/dist/executor/executor-context-engine-setup.js +46 -5
  56. package/node_modules/@comis/agent/dist/executor/executor-post-execution.d.ts +78 -4
  57. package/node_modules/@comis/agent/dist/executor/executor-post-execution.js +150 -31
  58. package/node_modules/@comis/agent/dist/executor/executor-prompt-runner.d.ts +7 -0
  59. package/node_modules/@comis/agent/dist/executor/executor-prompt-runner.js +26 -5
  60. package/node_modules/@comis/agent/dist/executor/executor-response-filter.d.ts +7 -6
  61. package/node_modules/@comis/agent/dist/executor/executor-response-filter.js +9 -42
  62. package/node_modules/@comis/agent/dist/executor/executor-tool-assembly.d.ts +18 -1
  63. package/node_modules/@comis/agent/dist/executor/executor-tool-assembly.js +20 -18
  64. package/node_modules/@comis/agent/dist/executor/gemini-cache-injector.d.ts +2 -2
  65. package/node_modules/@comis/agent/dist/executor/gemini-cache-injector.js +4 -4
  66. package/node_modules/@comis/agent/dist/executor/jit-guide-injector.d.ts +11 -2
  67. package/node_modules/@comis/agent/dist/executor/jit-guide-injector.js +16 -2
  68. package/node_modules/@comis/agent/dist/executor/phase-filter.d.ts +2 -2
  69. package/node_modules/@comis/agent/dist/executor/phase-filter.js +5 -7
  70. package/node_modules/@comis/agent/dist/executor/pi-executor.d.ts +21 -2
  71. package/node_modules/@comis/agent/dist/executor/pi-executor.js +96 -18
  72. package/node_modules/@comis/agent/dist/executor/post-batch-continuation.js +7 -7
  73. package/node_modules/@comis/agent/dist/executor/prompt-assembly.d.ts +9 -1
  74. package/node_modules/@comis/agent/dist/executor/prompt-assembly.js +15 -1
  75. package/node_modules/@comis/agent/dist/executor/stream-wrappers/request-body-injector.d.ts +1 -1
  76. package/node_modules/@comis/agent/dist/executor/stream-wrappers/request-body-injector.js +1 -1
  77. package/node_modules/@comis/agent/dist/executor/tool-deferral.d.ts +18 -27
  78. package/node_modules/@comis/agent/dist/executor/tool-deferral.js +34 -43
  79. package/node_modules/@comis/agent/dist/index.d.ts +17 -0
  80. package/node_modules/@comis/agent/dist/index.js +32 -11
  81. package/node_modules/@comis/agent/dist/model/auth-provider.d.ts +25 -2
  82. package/node_modules/@comis/agent/dist/model/auth-provider.js +6 -0
  83. package/node_modules/@comis/agent/dist/model/compaction-model-resolver.d.ts +3 -3
  84. package/node_modules/@comis/agent/dist/model/compaction-model-resolver.js +3 -3
  85. package/node_modules/@comis/agent/dist/model/model-registry-adapter.js +1 -1
  86. package/node_modules/@comis/agent/dist/model/model-scanner.js +1 -1
  87. package/node_modules/@comis/agent/dist/model/oauth-credential-store-file.d.ts +37 -0
  88. package/node_modules/@comis/agent/dist/model/oauth-credential-store-file.js +279 -0
  89. package/node_modules/@comis/agent/dist/model/oauth-credential-store-selector.d.ts +49 -0
  90. package/node_modules/@comis/agent/dist/model/oauth-credential-store-selector.js +50 -0
  91. package/node_modules/@comis/agent/dist/model/oauth-device-code.d.ts +57 -0
  92. package/node_modules/@comis/agent/dist/model/oauth-device-code.js +302 -0
  93. package/node_modules/@comis/agent/dist/model/oauth-env.d.ts +33 -0
  94. package/node_modules/@comis/agent/dist/model/oauth-env.js +38 -0
  95. package/node_modules/@comis/agent/dist/model/oauth-errors.d.ts +41 -0
  96. package/node_modules/@comis/agent/dist/model/oauth-errors.js +88 -0
  97. package/node_modules/@comis/agent/dist/model/oauth-identity.d.ts +53 -0
  98. package/node_modules/@comis/agent/dist/model/oauth-identity.js +141 -0
  99. package/node_modules/@comis/agent/dist/model/oauth-login-runner.d.ts +99 -0
  100. package/node_modules/@comis/agent/dist/model/oauth-login-runner.js +374 -0
  101. package/node_modules/@comis/agent/dist/model/oauth-tls-preflight.d.ts +58 -0
  102. package/node_modules/@comis/agent/dist/model/oauth-tls-preflight.js +82 -0
  103. package/node_modules/@comis/agent/dist/model/oauth-token-manager.d.ts +86 -16
  104. package/node_modules/@comis/agent/dist/model/oauth-token-manager.js +961 -66
  105. package/node_modules/@comis/agent/dist/model/operation-model-defaults.d.ts +9 -4
  106. package/node_modules/@comis/agent/dist/model/operation-model-defaults.js +36 -9
  107. package/node_modules/@comis/agent/dist/model/resolve-provider-api-key.d.ts +48 -0
  108. package/node_modules/@comis/agent/dist/model/resolve-provider-api-key.js +66 -0
  109. package/node_modules/@comis/agent/dist/provider/capabilities.d.ts +5 -5
  110. package/node_modules/@comis/agent/dist/provider/capabilities.js +10 -23
  111. package/node_modules/@comis/agent/dist/safety/tool-output-safety.js +3 -3
  112. package/node_modules/@comis/agent/dist/safety/tool-retry-breaker.d.ts +11 -1
  113. package/node_modules/@comis/agent/dist/safety/tool-retry-breaker.js +19 -22
  114. package/node_modules/@comis/agent/dist/session/comis-session-manager.d.ts +17 -3
  115. package/node_modules/@comis/agent/dist/session/comis-session-manager.js +1 -1
  116. package/node_modules/@comis/agent/dist/spawn/narrative-caster.d.ts +10 -0
  117. package/node_modules/@comis/agent/dist/spawn/narrative-caster.js +5 -1
  118. package/node_modules/@comis/agent/dist/spawn/pi-mono-adapters.d.ts +1 -1
  119. package/node_modules/@comis/agent/dist/spawn/pi-mono-adapters.js +5 -5
  120. package/node_modules/@comis/agent/dist/workspace/data-env.d.ts +38 -0
  121. package/node_modules/@comis/agent/dist/workspace/data-env.js +56 -0
  122. package/node_modules/@comis/agent/dist/workspace/index.d.ts +1 -0
  123. package/node_modules/@comis/agent/dist/workspace/index.js +1 -0
  124. package/node_modules/@comis/agent/dist/workspace/templates.js +5 -1
  125. package/node_modules/@comis/agent/package.json +1 -1
  126. package/node_modules/@comis/channels/dist/email/email-adapter.js +6 -6
  127. package/node_modules/@comis/channels/dist/email/imap-lifecycle.js +7 -7
  128. package/node_modules/@comis/channels/dist/index.d.ts +1 -1
  129. package/node_modules/@comis/channels/dist/index.js +1 -1
  130. package/node_modules/@comis/channels/dist/shared/channel-manager.d.ts +9 -3
  131. package/node_modules/@comis/channels/dist/shared/deliver-to-channel.js +12 -10
  132. package/node_modules/@comis/channels/dist/shared/inbound-gate.d.ts +1 -1
  133. package/node_modules/@comis/channels/dist/shared/inbound-gate.js +22 -7
  134. package/node_modules/@comis/channels/dist/shared/inbound-pipeline.d.ts +10 -3
  135. package/node_modules/@comis/channels/dist/shared/inbound-route.d.ts +1 -1
  136. package/node_modules/@comis/channels/dist/shared/inbound-route.js +13 -2
  137. package/node_modules/@comis/channels/dist/shared/response-filter.d.ts +11 -24
  138. package/node_modules/@comis/channels/dist/shared/response-filter.js +25 -53
  139. package/node_modules/@comis/channels/dist/telegram/telegram-adapter.js +1 -1
  140. package/node_modules/@comis/channels/package.json +1 -1
  141. package/node_modules/@comis/cli/dist/cli.js +2 -0
  142. package/node_modules/@comis/cli/dist/commands/agent.d.ts +3 -3
  143. package/node_modules/@comis/cli/dist/commands/agent.js +46 -3
  144. package/node_modules/@comis/cli/dist/commands/auth.d.ts +37 -0
  145. package/node_modules/@comis/cli/dist/commands/auth.js +433 -0
  146. package/node_modules/@comis/cli/dist/commands/doctor.d.ts +4 -1
  147. package/node_modules/@comis/cli/dist/commands/doctor.js +20 -5
  148. package/node_modules/@comis/cli/dist/commands/providers.d.ts +1 -2
  149. package/node_modules/@comis/cli/dist/commands/providers.js +5 -6
  150. package/node_modules/@comis/cli/dist/doctor/checks/oauth-health.d.ts +39 -0
  151. package/node_modules/@comis/cli/dist/doctor/checks/oauth-health.js +399 -0
  152. package/node_modules/@comis/cli/dist/doctor/types.d.ts +19 -0
  153. package/node_modules/@comis/cli/dist/index.d.ts +1 -0
  154. package/node_modules/@comis/cli/dist/index.js +10 -4
  155. package/node_modules/@comis/cli/dist/output/relative-time.d.ts +23 -0
  156. package/node_modules/@comis/cli/dist/output/relative-time.js +36 -0
  157. package/node_modules/@comis/cli/dist/wizard/non-interactive.js +17 -8
  158. package/node_modules/@comis/cli/dist/wizard/steps/03-provider.js +2 -1
  159. package/node_modules/@comis/cli/dist/wizard/steps/04-credentials.js +223 -34
  160. package/node_modules/@comis/cli/dist/wizard/steps/10-write-config.js +14 -0
  161. package/node_modules/@comis/cli/dist/wizard/steps/11-daemon-start.js +3 -3
  162. package/node_modules/@comis/cli/dist/wizard/types.d.ts +7 -0
  163. package/node_modules/@comis/cli/package.json +1 -1
  164. package/node_modules/@comis/core/dist/bootstrap.d.ts +1 -1
  165. package/node_modules/@comis/core/dist/config/env-substitution.d.ts +66 -0
  166. package/node_modules/@comis/core/dist/config/env-substitution.js +115 -0
  167. package/node_modules/@comis/core/dist/config/field-metadata.js +2 -0
  168. package/node_modules/@comis/core/dist/config/immutable-keys.js +4 -1
  169. package/node_modules/@comis/core/dist/config/index.d.ts +7 -1
  170. package/node_modules/@comis/core/dist/config/index.js +4 -1
  171. package/node_modules/@comis/core/dist/config/loader.js +61 -0
  172. package/node_modules/@comis/core/dist/config/managed-sections.d.ts +3 -3
  173. package/node_modules/@comis/core/dist/config/managed-sections.js +10 -5
  174. package/node_modules/@comis/core/dist/config/schema-agent.d.ts +4 -792
  175. package/node_modules/@comis/core/dist/config/schema-agent.js +16 -1
  176. package/node_modules/@comis/core/dist/config/schema-approvals.d.ts +0 -14
  177. package/node_modules/@comis/core/dist/config/schema-auto-reply-engine.d.ts +0 -6
  178. package/node_modules/@comis/core/dist/config/schema-background-tasks.d.ts +1 -6
  179. package/node_modules/@comis/core/dist/config/schema-background-tasks.js +7 -0
  180. package/node_modules/@comis/core/dist/config/schema-browser.d.ts +0 -18
  181. package/node_modules/@comis/core/dist/config/schema-channel.d.ts +0 -158
  182. package/node_modules/@comis/core/dist/config/schema-coalescer.d.ts +0 -5
  183. package/node_modules/@comis/core/dist/config/schema-daemon.d.ts +0 -32
  184. package/node_modules/@comis/core/dist/config/schema-delivery.d.ts +1 -17
  185. package/node_modules/@comis/core/dist/config/schema-delivery.js +2 -0
  186. package/node_modules/@comis/core/dist/config/schema-documentation.d.ts +0 -12
  187. package/node_modules/@comis/core/dist/config/schema-embedding.d.ts +0 -20
  188. package/node_modules/@comis/core/dist/config/schema-envelope.d.ts +0 -15
  189. package/node_modules/@comis/core/dist/config/schema-gateway.d.ts +0 -37
  190. package/node_modules/@comis/core/dist/config/schema-gemini-cache.d.ts +0 -4
  191. package/node_modules/@comis/core/dist/config/schema-gemini-cache.js +0 -2
  192. package/node_modules/@comis/core/dist/config/schema-integrations.d.ts +0 -318
  193. package/node_modules/@comis/core/dist/config/schema-lifecycle-reactions.d.ts +0 -18
  194. package/node_modules/@comis/core/dist/config/schema-memory-review.d.ts +0 -7
  195. package/node_modules/@comis/core/dist/config/schema-memory.d.ts +0 -16
  196. package/node_modules/@comis/core/dist/config/schema-messages.d.ts +0 -8
  197. package/node_modules/@comis/core/dist/config/schema-models.d.ts +0 -15
  198. package/node_modules/@comis/core/dist/config/schema-notification.d.ts +0 -5
  199. package/node_modules/@comis/core/dist/config/schema-oauth.d.ts +18 -0
  200. package/node_modules/@comis/core/dist/config/schema-oauth.js +19 -0
  201. package/node_modules/@comis/core/dist/config/schema-observability.d.ts +0 -38
  202. package/node_modules/@comis/core/dist/config/schema-output-retention.d.ts +34 -0
  203. package/node_modules/@comis/core/dist/config/schema-output-retention.js +48 -0
  204. package/node_modules/@comis/core/dist/config/schema-plugins.d.ts +0 -8
  205. package/node_modules/@comis/core/dist/config/schema-providers.d.ts +0 -64
  206. package/node_modules/@comis/core/dist/config/schema-queue.d.ts +0 -58
  207. package/node_modules/@comis/core/dist/config/schema-response-prefix.d.ts +0 -2
  208. package/node_modules/@comis/core/dist/config/schema-retry.d.ts +0 -6
  209. package/node_modules/@comis/core/dist/config/schema-scheduler.d.ts +0 -39
  210. package/node_modules/@comis/core/dist/config/schema-secrets.d.ts +0 -3
  211. package/node_modules/@comis/core/dist/config/schema-security.d.ts +0 -18
  212. package/node_modules/@comis/core/dist/config/schema-send-policy.d.ts +0 -13
  213. package/node_modules/@comis/core/dist/config/schema-sender-trust-display.d.ts +0 -5
  214. package/node_modules/@comis/core/dist/config/schema-serializer.js +2 -0
  215. package/node_modules/@comis/core/dist/config/schema-skills.d.ts +0 -63
  216. package/node_modules/@comis/core/dist/config/schema-skills.js +3 -4
  217. package/node_modules/@comis/core/dist/config/schema-streaming.d.ts +0 -38
  218. package/node_modules/@comis/core/dist/config/schema-telegram-file-guard.d.ts +0 -3
  219. package/node_modules/@comis/core/dist/config/schema-tooling.d.ts +87 -0
  220. package/node_modules/@comis/core/dist/config/schema-tooling.js +152 -0
  221. package/node_modules/@comis/core/dist/config/schema-verbosity.d.ts +0 -12
  222. package/node_modules/@comis/core/dist/config/schema-webhooks.d.ts +0 -40
  223. package/node_modules/@comis/core/dist/config/schema.d.ts +50 -37
  224. package/node_modules/@comis/core/dist/config/schema.js +9 -0
  225. package/node_modules/@comis/core/dist/context/context.d.ts +0 -4
  226. package/node_modules/@comis/core/dist/domain/approval-request.d.ts +0 -17
  227. package/node_modules/@comis/core/dist/domain/background-task-origin.d.ts +29 -0
  228. package/node_modules/@comis/core/dist/domain/background-task-origin.js +39 -0
  229. package/node_modules/@comis/core/dist/domain/delivery-origin.d.ts +0 -5
  230. package/node_modules/@comis/core/dist/domain/execution-graph.d.ts +0 -48
  231. package/node_modules/@comis/core/dist/domain/memory-entry.d.ts +0 -3
  232. package/node_modules/@comis/core/dist/domain/model-compat.d.ts +0 -4
  233. package/node_modules/@comis/core/dist/domain/normalized-message.d.ts +0 -15
  234. package/node_modules/@comis/core/dist/domain/provider-capabilities.d.ts +0 -6
  235. package/node_modules/@comis/core/dist/domain/rich-message.d.ts +0 -14
  236. package/node_modules/@comis/core/dist/domain/subagent-context-config.d.ts +0 -22
  237. package/node_modules/@comis/core/dist/domain/subagent-context-types.d.ts +0 -8
  238. package/node_modules/@comis/core/dist/event-bus/events-agent.d.ts +31 -0
  239. package/node_modules/@comis/core/dist/event-bus/events-infra.d.ts +76 -2
  240. package/node_modules/@comis/core/dist/exports/config.d.ts +2 -2
  241. package/node_modules/@comis/core/dist/exports/config.js +3 -1
  242. package/node_modules/@comis/core/dist/exports/domain.d.ts +2 -0
  243. package/node_modules/@comis/core/dist/exports/domain.js +1 -0
  244. package/node_modules/@comis/core/dist/exports/hooks.d.ts +1 -1
  245. package/node_modules/@comis/core/dist/exports/ports.d.ts +2 -2
  246. package/node_modules/@comis/core/dist/exports/ports.js +1 -1
  247. package/node_modules/@comis/core/dist/ports/channel-plugin.d.ts +0 -13
  248. package/node_modules/@comis/core/dist/ports/delivery-queue.d.ts +23 -0
  249. package/node_modules/@comis/core/dist/ports/delivery-queue.js +2 -0
  250. package/node_modules/@comis/core/dist/ports/index.d.ts +4 -0
  251. package/node_modules/@comis/core/dist/ports/index.js +5 -0
  252. package/node_modules/@comis/core/dist/ports/no-op-tool-capability.d.ts +30 -0
  253. package/node_modules/@comis/core/dist/ports/no-op-tool-capability.js +47 -0
  254. package/node_modules/@comis/core/dist/ports/oauth-credential-store.d.ts +64 -0
  255. package/node_modules/@comis/core/dist/ports/oauth-credential-store.js +37 -0
  256. package/node_modules/@comis/core/dist/ports/tool-capability.d.ts +165 -0
  257. package/node_modules/@comis/core/dist/ports/tool-capability.js +15 -0
  258. package/node_modules/@comis/core/dist/security/audit.d.ts +0 -11
  259. package/node_modules/@comis/core/dist/tool-metadata.d.ts +41 -1
  260. package/node_modules/@comis/core/dist/tool-metadata.js +1 -1
  261. package/node_modules/@comis/core/package.json +1 -1
  262. package/node_modules/@comis/daemon/bundled-skills/skill-creator/scripts/validate-skill.py +1 -1
  263. package/node_modules/@comis/daemon/dist/daemon-types.d.ts +23 -3
  264. package/node_modules/@comis/daemon/dist/daemon.js +168 -30
  265. package/node_modules/@comis/daemon/dist/index.d.ts +2 -0
  266. package/node_modules/@comis/daemon/dist/index.js +5 -0
  267. package/node_modules/@comis/daemon/dist/observability/channel-health-logger.js +3 -3
  268. package/node_modules/@comis/daemon/dist/observability/delivery-queue-logger.js +1 -1
  269. package/node_modules/@comis/daemon/dist/rpc/agent-handlers.d.ts +22 -1
  270. package/node_modules/@comis/daemon/dist/rpc/agent-handlers.js +84 -21
  271. package/node_modules/@comis/daemon/dist/rpc/agent-inline-workspace.d.ts +1 -1
  272. package/node_modules/@comis/daemon/dist/rpc/agent-inline-workspace.js +3 -3
  273. package/node_modules/@comis/daemon/dist/rpc/builtin-provider-guard.js +2 -2
  274. package/node_modules/@comis/daemon/dist/rpc/config-handlers.d.ts +9 -1
  275. package/node_modules/@comis/daemon/dist/rpc/config-handlers.js +104 -23
  276. package/node_modules/@comis/daemon/dist/rpc/credential-resolver.d.ts +30 -1
  277. package/node_modules/@comis/daemon/dist/rpc/credential-resolver.js +74 -11
  278. package/node_modules/@comis/daemon/dist/rpc/mcp-handlers.d.ts +8 -0
  279. package/node_modules/@comis/daemon/dist/rpc/mcp-handlers.js +22 -8
  280. package/node_modules/@comis/daemon/dist/rpc/model-handlers.d.ts +1 -1
  281. package/node_modules/@comis/daemon/dist/rpc/model-handlers.js +2 -2
  282. package/node_modules/@comis/daemon/dist/rpc/provider-handlers.js +9 -12
  283. package/node_modules/@comis/daemon/dist/rpc/rpc-dispatch.d.ts +1 -0
  284. package/node_modules/@comis/daemon/dist/rpc/rpc-dispatch.js +27 -2
  285. package/node_modules/@comis/daemon/dist/setup-docker-restart-warn.js +0 -1
  286. package/node_modules/@comis/daemon/dist/sub-agent-runner.d.ts +18 -0
  287. package/node_modules/@comis/daemon/dist/sub-agent-runner.js +41 -9
  288. package/node_modules/@comis/daemon/dist/wiring/index.d.ts +4 -0
  289. package/node_modules/@comis/daemon/dist/wiring/index.js +2 -0
  290. package/node_modules/@comis/daemon/dist/wiring/oauth-preflight.d.ts +21 -0
  291. package/node_modules/@comis/daemon/dist/wiring/oauth-preflight.js +134 -0
  292. package/node_modules/@comis/daemon/dist/wiring/setup-agents.d.ts +81 -2
  293. package/node_modules/@comis/daemon/dist/wiring/setup-agents.js +164 -3
  294. package/node_modules/@comis/daemon/dist/wiring/setup-background-completion-runner.d.ts +58 -0
  295. package/node_modules/@comis/daemon/dist/wiring/setup-background-completion-runner.js +59 -0
  296. package/node_modules/@comis/daemon/dist/wiring/setup-background-tasks.d.ts +10 -3
  297. package/node_modules/@comis/daemon/dist/wiring/setup-background-tasks.js +13 -7
  298. package/node_modules/@comis/daemon/dist/wiring/setup-channels.d.ts +9 -2
  299. package/node_modules/@comis/daemon/dist/wiring/setup-channels.js +35 -10
  300. package/node_modules/@comis/daemon/dist/wiring/setup-cross-session.d.ts +20 -5
  301. package/node_modules/@comis/daemon/dist/wiring/setup-cross-session.js +21 -16
  302. package/node_modules/@comis/daemon/dist/wiring/setup-delivery.d.ts +14 -5
  303. package/node_modules/@comis/daemon/dist/wiring/setup-delivery.js +65 -20
  304. package/node_modules/@comis/daemon/dist/wiring/setup-gateway.d.ts +4 -6
  305. package/node_modules/@comis/daemon/dist/wiring/setup-gateway.js +3 -5
  306. package/node_modules/@comis/daemon/dist/wiring/setup-heartbeat.d.ts +20 -5
  307. package/node_modules/@comis/daemon/dist/wiring/setup-heartbeat.js +11 -2
  308. package/node_modules/@comis/daemon/dist/wiring/setup-output-retention.d.ts +89 -0
  309. package/node_modules/@comis/daemon/dist/wiring/setup-output-retention.js +212 -0
  310. package/node_modules/@comis/daemon/dist/wiring/setup-schedulers.js +4 -0
  311. package/node_modules/@comis/daemon/dist/wiring/setup-tools.d.ts +18 -4
  312. package/node_modules/@comis/daemon/dist/wiring/setup-tools.js +29 -10
  313. package/node_modules/@comis/daemon/dist/wiring/tool-capability-adapter.d.ts +75 -0
  314. package/node_modules/@comis/daemon/dist/wiring/tool-capability-adapter.js +253 -0
  315. package/node_modules/@comis/daemon/package.json +1 -1
  316. package/node_modules/@comis/gateway/dist/index.d.ts +2 -0
  317. package/node_modules/@comis/gateway/dist/index.js +2 -0
  318. package/node_modules/@comis/gateway/dist/oauth/oauth-callback-route.d.ts +66 -0
  319. package/node_modules/@comis/gateway/dist/oauth/oauth-callback-route.js +212 -0
  320. package/node_modules/@comis/gateway/dist/server/hono-server.d.ts +14 -0
  321. package/node_modules/@comis/gateway/dist/server/hono-server.js +10 -0
  322. package/node_modules/@comis/gateway/dist/webhook/webhook-endpoint.d.ts +0 -4
  323. package/node_modules/@comis/gateway/package.json +1 -1
  324. package/node_modules/@comis/infra/dist/logging/log-fields.d.ts +23 -0
  325. package/node_modules/@comis/infra/package.json +1 -1
  326. package/node_modules/@comis/memory/dist/compaction.d.ts +3 -5
  327. package/node_modules/@comis/memory/dist/compaction.js +2 -3
  328. package/node_modules/@comis/memory/dist/delivery-queue-adapter.d.ts +2 -2
  329. package/node_modules/@comis/memory/dist/delivery-queue-adapter.js +49 -1
  330. package/node_modules/@comis/memory/dist/index.d.ts +2 -0
  331. package/node_modules/@comis/memory/dist/index.js +3 -0
  332. package/node_modules/@comis/memory/dist/memory-api.d.ts +1 -1
  333. package/node_modules/@comis/memory/dist/memory-api.js +1 -1
  334. package/node_modules/@comis/memory/dist/oauth-profile-schema.d.ts +17 -0
  335. package/node_modules/@comis/memory/dist/oauth-profile-schema.js +33 -0
  336. package/node_modules/@comis/memory/dist/oauth-profile-store-encrypted.d.ts +27 -0
  337. package/node_modules/@comis/memory/dist/oauth-profile-store-encrypted.js +144 -0
  338. package/node_modules/@comis/memory/dist/session-store.d.ts +1 -1
  339. package/node_modules/@comis/memory/dist/session-store.js +1 -1
  340. package/node_modules/@comis/memory/dist/sqlite-secret-store.d.ts +29 -3
  341. package/node_modules/@comis/memory/dist/sqlite-secret-store.js +11 -3
  342. package/node_modules/@comis/memory/package.json +1 -1
  343. package/node_modules/@comis/scheduler/dist/cron/cron-types.d.ts +0 -42
  344. package/node_modules/@comis/scheduler/dist/execution/execution-lock.d.ts +13 -0
  345. package/node_modules/@comis/scheduler/dist/execution/execution-lock.js +1 -1
  346. package/node_modules/@comis/scheduler/dist/execution/index.d.ts +2 -0
  347. package/node_modules/@comis/scheduler/dist/execution/index.js +2 -0
  348. package/node_modules/@comis/scheduler/dist/heartbeat/agent-heartbeat-source.d.ts +29 -8
  349. package/node_modules/@comis/scheduler/dist/heartbeat/agent-heartbeat-source.js +20 -8
  350. package/node_modules/@comis/scheduler/dist/index.d.ts +2 -0
  351. package/node_modules/@comis/scheduler/dist/index.js +2 -0
  352. package/node_modules/@comis/scheduler/dist/system-events/system-event-types.d.ts +0 -3
  353. package/node_modules/@comis/scheduler/dist/tasks/task-types.d.ts +0 -17
  354. package/node_modules/@comis/scheduler/package.json +1 -1
  355. package/node_modules/@comis/shared/dist/index.d.ts +3 -0
  356. package/node_modules/@comis/shared/dist/index.js +4 -0
  357. package/node_modules/@comis/shared/dist/mcp-tool-name.d.ts +78 -0
  358. package/node_modules/@comis/shared/dist/mcp-tool-name.js +92 -0
  359. package/node_modules/@comis/shared/dist/silent-tokens.d.ts +38 -0
  360. package/node_modules/@comis/shared/dist/silent-tokens.js +51 -0
  361. package/node_modules/@comis/shared/dist/visible-delivery.d.ts +28 -0
  362. package/node_modules/@comis/shared/dist/visible-delivery.js +16 -0
  363. package/node_modules/@comis/shared/package.json +1 -1
  364. package/node_modules/@comis/skills/dist/bridge/mcp-tool-bridge.d.ts +2 -13
  365. package/node_modules/@comis/skills/dist/bridge/mcp-tool-bridge.js +3 -21
  366. package/node_modules/@comis/skills/dist/bridge/schema-validator.d.ts +38 -0
  367. package/node_modules/@comis/skills/dist/bridge/schema-validator.js +169 -0
  368. package/node_modules/@comis/skills/dist/bridge/tool-metadata-enforcement.js +12 -0
  369. package/node_modules/@comis/skills/dist/bridge/tool-metadata-registry.js +133 -3
  370. package/node_modules/@comis/skills/dist/builtin/exec-diagnostics.d.ts +32 -0
  371. package/node_modules/@comis/skills/dist/builtin/exec-diagnostics.js +127 -0
  372. package/node_modules/@comis/skills/dist/builtin/exec-security.js +38 -0
  373. package/node_modules/@comis/skills/dist/builtin/exec-tool.d.ts +55 -9
  374. package/node_modules/@comis/skills/dist/builtin/exec-tool.js +392 -19
  375. package/node_modules/@comis/skills/dist/builtin/file-tools/grep-tool.js +6 -6
  376. package/node_modules/@comis/skills/dist/builtin/install-detour.d.ts +67 -0
  377. package/node_modules/@comis/skills/dist/builtin/install-detour.js +342 -0
  378. package/node_modules/@comis/skills/dist/builtin/platform/admin-manage-factory.js +5 -5
  379. package/node_modules/@comis/skills/dist/builtin/platform/agents-manage-tool.d.ts +7 -6
  380. package/node_modules/@comis/skills/dist/builtin/platform/agents-manage-tool.js +40 -29
  381. package/node_modules/@comis/skills/dist/builtin/platform/background-tasks-tool.d.ts +4 -1
  382. package/node_modules/@comis/skills/dist/builtin/platform/background-tasks-tool.js +3 -3
  383. package/node_modules/@comis/skills/dist/builtin/platform/cron-tool.js +1 -1
  384. package/node_modules/@comis/skills/dist/builtin/platform/gateway-tool.js +6 -6
  385. package/node_modules/@comis/skills/dist/builtin/platform/mcp-manage-tool.d.ts +1 -1
  386. package/node_modules/@comis/skills/dist/builtin/platform/mcp-manage-tool.js +9 -9
  387. package/node_modules/@comis/skills/dist/builtin/platform/message-tool.js +18 -0
  388. package/node_modules/@comis/skills/dist/builtin/platform/messaging-factory.d.ts +18 -1
  389. package/node_modules/@comis/skills/dist/builtin/platform/messaging-factory.js +18 -2
  390. package/node_modules/@comis/skills/dist/builtin/platform/models-manage-tool.js +3 -3
  391. package/node_modules/@comis/skills/dist/builtin/process-registry.d.ts +14 -0
  392. package/node_modules/@comis/skills/dist/builtin/process-tool.d.ts +24 -4
  393. package/node_modules/@comis/skills/dist/builtin/process-tool.js +25 -7
  394. package/node_modules/@comis/skills/dist/builtin/sandbox/bwrap-provider.d.ts +11 -0
  395. package/node_modules/@comis/skills/dist/builtin/sandbox/bwrap-provider.js +123 -1
  396. package/node_modules/@comis/skills/dist/builtin/sandbox/detect-provider.js +40 -15
  397. package/node_modules/@comis/skills/dist/index.d.ts +4 -1
  398. package/node_modules/@comis/skills/dist/index.js +3 -1
  399. package/node_modules/@comis/skills/dist/manifest/capability-parser.d.ts +44 -0
  400. package/node_modules/@comis/skills/dist/manifest/capability-parser.js +68 -0
  401. package/node_modules/@comis/skills/dist/manifest/schema.d.ts +44 -37
  402. package/node_modules/@comis/skills/dist/manifest/schema.js +35 -0
  403. package/node_modules/@comis/skills/dist/media/ssrf-fetcher.d.ts +7 -0
  404. package/node_modules/@comis/skills/dist/media/ssrf-fetcher.js +9 -2
  405. package/node_modules/@comis/skills/dist/registry/discovery.d.ts +8 -0
  406. package/node_modules/@comis/skills/dist/registry/discovery.js +10 -3
  407. package/node_modules/@comis/skills/dist/registry/skill-registry.d.ts +45 -1
  408. package/node_modules/@comis/skills/dist/registry/skill-registry.js +70 -7
  409. package/node_modules/@comis/skills/package.json +1 -1
  410. package/node_modules/@comis/web/dist/assets/{agent-detail-71BSbSfD.js → agent-detail-q8t1NB7w.js} +1 -1
  411. package/node_modules/@comis/web/dist/assets/{agent-editor-CTSDZhwT.js → agent-editor-B46io5gv.js} +1 -1
  412. package/node_modules/@comis/web/dist/assets/{agent-list-BEhni2ea.js → agent-list-DQ6g2Rcx.js} +1 -1
  413. package/node_modules/@comis/web/dist/assets/{billing-view-DVP1IvVs.js → billing-view-IWPR8LgF.js} +1 -1
  414. package/node_modules/@comis/web/dist/assets/{channel-detail-N_YK74xC.js → channel-detail-DlNNZuuC.js} +1 -1
  415. package/node_modules/@comis/web/dist/assets/{channel-list-DRk6ZJaF.js → channel-list-DhGwxiMc.js} +1 -1
  416. package/node_modules/@comis/web/dist/assets/{chat-console-Dm-GtSf9.js → chat-console-Nv6fM3Rc.js} +1 -1
  417. package/node_modules/@comis/web/dist/assets/{config-editor-CIferYX6.js → config-editor-BYKuJF76.js} +1 -1
  418. package/node_modules/@comis/web/dist/assets/{context-dag-browser-CL84rXXM.js → context-dag-browser-ClNEtzYE.js} +1 -1
  419. package/node_modules/@comis/web/dist/assets/{context-engine-B1HOTEZv.js → context-engine-BZJ6HChd.js} +1 -1
  420. package/node_modules/@comis/web/dist/assets/{delivery-view-Y6JKYVFw.js → delivery-view-Cb7I3vGu.js} +1 -1
  421. package/node_modules/@comis/web/dist/assets/{diagnostics-view-DWV1UQjz.js → diagnostics-view-9u9Lyu5a.js} +1 -1
  422. package/node_modules/@comis/web/dist/assets/{ic-chat-message-DfSERzzg.js → ic-chat-message-BFt3cVpx.js} +1 -1
  423. package/node_modules/@comis/web/dist/assets/{ic-connection-dot-CXyhlJup.js → ic-connection-dot-y77LZ3Gu.js} +1 -1
  424. package/node_modules/@comis/web/dist/assets/{ic-tool-call-DNmwTjek.js → ic-tool-call-qt6w1NQl.js} +1 -1
  425. package/node_modules/@comis/web/dist/assets/{index-CBr0Tm9_.js → index-8Tg9oc-C.js} +2 -2
  426. package/node_modules/@comis/web/dist/assets/{mcp-management-BaH2-vox.js → mcp-management-69dtH_kY.js} +2 -2
  427. package/node_modules/@comis/web/dist/assets/{media-config-CZLshJoN.js → media-config-BdjLj5c1.js} +1 -1
  428. package/node_modules/@comis/web/dist/assets/{media-test-C9NUWgo_.js → media-test-DuPqrixi.js} +1 -1
  429. package/node_modules/@comis/web/dist/assets/{memory-inspector-D_fmTcRN.js → memory-inspector-B-Pepbq-.js} +1 -1
  430. package/node_modules/@comis/web/dist/assets/{message-center-BBFlNCZn.js → message-center-B7l0yNYY.js} +1 -1
  431. package/node_modules/@comis/web/dist/assets/{models-BytGLm99.js → models-JHFHuv5S.js} +1 -1
  432. package/node_modules/@comis/web/dist/assets/{observe-view-VXtHqaqq.js → observe-view-r8mqhy4O.js} +1 -1
  433. package/node_modules/@comis/web/dist/assets/{pipeline-builder-CfXczlfJ.js → pipeline-builder-XjkiZRcR.js} +1 -1
  434. package/node_modules/@comis/web/dist/assets/{pipeline-history-CPmXFnbe.js → pipeline-history-CZqJv_Hj.js} +1 -1
  435. package/node_modules/@comis/web/dist/assets/{pipeline-history-detail-DcueTMs9.js → pipeline-history-detail-BEFGMoDy.js} +1 -1
  436. package/node_modules/@comis/web/dist/assets/{pipeline-list-B-xG5WZh.js → pipeline-list-B6q5LvO1.js} +1 -1
  437. package/node_modules/@comis/web/dist/assets/{pipeline-monitor-pnIOYaSY.js → pipeline-monitor-BNomXjVL.js} +1 -1
  438. package/node_modules/@comis/web/dist/assets/{scheduler-BtUIFHhA.js → scheduler-BJEjcGKA.js} +1 -1
  439. package/node_modules/@comis/web/dist/assets/{security-C8mWRq2y.js → security-2G1jhBfV.js} +1 -1
  440. package/node_modules/@comis/web/dist/assets/{session-detail-DgdkO5ka.js → session-detail-DmVPzFBR.js} +1 -1
  441. package/node_modules/@comis/web/dist/assets/{session-list-DcylcfTn.js → session-list-CsqMQoHs.js} +1 -1
  442. package/node_modules/@comis/web/dist/assets/{setup-wizard-BP5yjsuL.js → setup-wizard-CAdM-gSP.js} +1 -1
  443. package/node_modules/@comis/web/dist/assets/{skills-DXt1bX8Z.js → skills-2ODqKaWr.js} +1 -1
  444. package/node_modules/@comis/web/dist/assets/{subagents-C7YbUHXY.js → subagents-BFlwfTbD.js} +1 -1
  445. package/node_modules/@comis/web/dist/assets/{workspace-manager-DP6pW4wa.js → workspace-manager--CbOx_dI.js} +1 -1
  446. package/node_modules/@comis/web/dist/index.html +1 -1
  447. package/node_modules/@comis/web/package.json +1 -1
  448. package/package.json +25 -24
@@ -23,7 +23,7 @@
23
23
  */
24
24
  import { Type } from "typebox";
25
25
  import { spawn } from "node:child_process";
26
- import { createWriteStream, mkdirSync, writeFileSync, copyFileSync, statSync } from "node:fs";
26
+ import { createWriteStream, mkdirSync, writeFileSync, copyFileSync, statSync, existsSync } from "node:fs";
27
27
  import { tmpdir } from "node:os";
28
28
  import { randomBytes } from "node:crypto";
29
29
  import { safePath, PathTraversalError } from "@comis/core";
@@ -33,7 +33,9 @@ import { generateSessionId, appendOutput } from "./process-registry.js";
33
33
  import { truncateTail, formatSize, DEFAULT_MAX_BYTES } from "./truncate.js";
34
34
  import { createOutputCleaner } from "./output-cleaner.js";
35
35
  import { extractHeredoc, validateExecCommand, interpretExitCode } from "./exec-security.js";
36
+ import { matchExecRecoveryHint } from "./exec-diagnostics.js";
36
37
  import { tryGetContext } from "@comis/core";
38
+ import { parseInstallDetour, } from "./install-detour.js";
37
39
  // ---------------------------------------------------------------------------
38
40
  // Constants
39
41
  // ---------------------------------------------------------------------------
@@ -74,6 +76,12 @@ const ExecParams = Type.Object({
74
76
  maxItems: 8,
75
77
  description: "Secret/credential NAMES (not values) to inject as env vars into the subprocess. Use this to pass API tokens to CLI tools like wrangler/gh/gcloud/kubectl without tripping the env-var allowlist. Names are resolved server-side via SecretManager; values never flow through agent context. Call env_list first to discover available names. Platform-managed secrets (referenced by the daemon config, e.g. ANTHROPIC_API_KEY) are rejected. Raw-interpreter commands (python -c, node -e, bash -c, etc.) are rejected with secretRefs to prevent trivial echo-to-stdout leaks. Example: {command: 'npx wrangler pages deploy ./dist', secretRefs: ['CLOUDFLARE_API_TOKEN', 'CLOUDFLARE_ACCOUNT_ID']}",
76
78
  })),
79
+ allowInstallDetour: Type.Optional(Type.Boolean({
80
+ description: "Request an operator-approved override when the user explicitly needs " +
81
+ "package installation despite an equivalent connected MCP server or " +
82
+ "available skill. Submits an approval request — does NOT self-authorize. " +
83
+ "Per-commandDigest scoped (one approval does not cover a different install).",
84
+ })),
77
85
  });
78
86
  // ---------------------------------------------------------------------------
79
87
  // cwd resolution
@@ -200,6 +208,39 @@ export function buildSpawnCommand(command, cwd, sandboxConfig, workspacePath, te
200
208
  // ---------------------------------------------------------------------------
201
209
  /** Valid secret env var name (same rule as env.set). */
202
210
  const SECRET_REF_NAME_PATTERN = /^[A-Z][A-Z0-9_]*$/;
211
+ /**
212
+ * Workspace-internal data env resolver.
213
+ *
214
+ * Returns env vars (PATH, MPLCONFIGDIR, XDG_CACHE_HOME, MPLBACKEND,
215
+ * PIP_DISABLE_PIP_VERSION_CHECK) derived from `workspaceDir` so python /
216
+ * matplotlib subprocesses do NOT inherit the daemon's host PATH or
217
+ * cache-dir defaults. (15s pip-install hot path; matplotlib Fontconfig
218
+ * error from a non-writable default cache dir).
219
+ *
220
+ * Defined inline to avoid a cross-package import from `@comis/agent`
221
+ * (`@comis/skills` does not depend on `@comis/agent` -- they are siblings
222
+ * wired together at the daemon composition root, mirroring the
223
+ * `bridge-event-handlers.ts` "Defined inline to avoid cross-package
224
+ * import" precedent). The shape mirrors
225
+ * `packages/agent/src/workspace/data-env.ts` verbatim; if the contract
226
+ * diverges, lift this into `@comis/shared`. The agent-side `data-env.ts`
227
+ * remains the canonical owner of the no-host-env contract.
228
+ *
229
+ * This helper does NOT read host env. The values are pure derivations
230
+ * from workspaceDir + safePath (no path.join).
231
+ */
232
+ function resolveDataEnv(opts) {
233
+ const venvBin = safePath(opts.workspaceDir, "venv", "bin");
234
+ const cacheDir = safePath(opts.workspaceDir, ".cache");
235
+ const mplDir = safePath(cacheDir, "matplotlib");
236
+ return {
237
+ PATH: venvBin,
238
+ MPLCONFIGDIR: mplDir,
239
+ XDG_CACHE_HOME: cacheDir,
240
+ MPLBACKEND: "Agg",
241
+ PIP_DISABLE_PIP_VERSION_CHECK: "1",
242
+ };
243
+ }
203
244
  /**
204
245
  * Detect raw-interpreter command shapes. When `secretRefs` is present,
205
246
  * these are refused because they make `echo $TOKEN` / `print(os.environ)`
@@ -270,21 +311,116 @@ function resolveSecretRefs(refs, secretManager, platformSecretNames) {
270
311
  return { ok: true, env };
271
312
  }
272
313
  // ---------------------------------------------------------------------------
273
- // Factory
314
+ // Install-detour helpers
274
315
  // ---------------------------------------------------------------------------
316
+ /**
317
+ * Map package manager to the structured ecosystem field used by the
318
+ * `tool:install_detour_detected` event payload (closed shape).
319
+ */
320
+ function ecosystemFor(pm) {
321
+ return pm === "pip" ? "python" : "node";
322
+ }
323
+ /**
324
+ * Build the structured install-detour hint augmentation for advise mode.
325
+ * Returns BOTH a string (for `details.installDetourHint`) AND a sibling
326
+ * `[hint]` content block (for the `result.content` array). Primary content,
327
+ * stdout, stderr, exitCode, and status are NEVER mutated by callers.
328
+ *
329
+ * Hint is informational; primary signal stays on the
330
+ * exec result envelope.
331
+ */
332
+ export function buildInstallDetourHint(decision) {
333
+ const lines = decision.overlaps.map((o) => {
334
+ const cluster = o.cluster ? ` (cluster: ${o.cluster})` : "";
335
+ return o.sourceType === "mcp"
336
+ ? `- ${o.packageName} -> connected MCP server "${o.sourceName}"${cluster}`
337
+ : `- ${o.packageName} -> available skill "${o.sourceName}"${cluster}`;
338
+ });
339
+ const text = `[hint] Installed packages overlap available capabilities:\n${lines.join("\n")}\n` +
340
+ `If you can use these capabilities directly, do so before relying on the install.`;
341
+ return {
342
+ installDetourHint: text,
343
+ hintContentBlock: { type: "text", text },
344
+ };
345
+ }
346
+ /**
347
+ * Build the verbatim soft-stop error template. Returns `null` when
348
+ * no overlap source remains connected/visible at error-build time
349
+ * (overlaps disappeared mid-call; refusal no longer justified).
350
+ * Caller falls through to spawn in that case.
351
+ *
352
+ * Bullet count == filtered-overlap count. Cluster shown in parens when defined.
353
+ * MCP overlaps say `connected MCP server`; skill overlaps say `available skill`.
354
+ * NO provider-specific tool names; NO self-authorizing override wording.
355
+ */
356
+ function buildSoftStopErrorTemplate(decision, port) {
357
+ // Re-check connection/visibility at error time, not parser time.
358
+ // The connected-server set may have drifted since parse. Filter to overlaps
359
+ // whose source is currently reachable.
360
+ const connectedServers = new Set(port.getConnectedMcpServers());
361
+ const visibleSkills = new Set(port.getPromptSkillCapabilities().map((s) => s.name));
362
+ const filtered = decision.overlaps.filter((o) => o.sourceType === "mcp" ? connectedServers.has(o.sourceName) : visibleSkills.has(o.sourceName));
363
+ if (filtered.length === 0)
364
+ return null; // overlaps disappeared — fall through
365
+ const bullets = filtered.map((o) => {
366
+ const cluster = o.cluster ? ` (cluster: ${o.cluster})` : "";
367
+ return o.sourceType === "mcp"
368
+ ? `- ${o.packageName} -> connected MCP server "${o.sourceName}"${cluster}`
369
+ : `- ${o.packageName} -> available skill "${o.sourceName}"${cluster}`;
370
+ });
371
+ return [
372
+ "Refused: install overlaps with available capability source(s).",
373
+ "",
374
+ "Overlapping packages:",
375
+ ...bullets,
376
+ "",
377
+ "To proceed, choose one:",
378
+ "1. Use the connected tool(s) or available skill(s) listed above for the overlapping work.",
379
+ "2. If you only need the non-overlapping packages, rerun exec with the overlapping ones removed.",
380
+ "3. If you genuinely need the install despite the overlap, ask the user/operator to approve the install-detour override, then rerun this exact command with `allowInstallDetour: true`.",
381
+ ].join("\n");
382
+ }
383
+ /**
384
+ * Build the closed `tool:install_detour_detected` event payload from a
385
+ * decision + the action/mode tags. Sanitized only:
386
+ * NEVER includes `command`, `rawCommand`, `stdout`, `stderr`, raw shell
387
+ * fragments, URLs, paths, or credentials.
388
+ */
389
+ function buildInstallDetourEventPayload(decision, mode, action) {
390
+ const ctx = tryGetContext();
391
+ return {
392
+ agentId: ctx?.sessionKey ?? "unknown", // sessionKey-as-agentId convention
393
+ sessionKey: ctx?.sessionKey ?? "unknown",
394
+ traceId: ctx?.traceId,
395
+ packageManager: decision.packageManager,
396
+ commandDigest: decision.commandDigest,
397
+ packages: decision.packages.map((p) => ({
398
+ normalizedName: p,
399
+ ecosystem: ecosystemFor(decision.packageManager),
400
+ })),
401
+ overlaps: decision.overlaps.map((o) => ({
402
+ packageName: o.packageName,
403
+ sourceType: o.sourceType,
404
+ sourceName: o.sourceName,
405
+ reason: o.reason,
406
+ })),
407
+ mode,
408
+ action,
409
+ timestamp: Date.now(),
410
+ };
411
+ }
275
412
  /**
276
413
  * Create an exec tool for shell command execution.
277
414
  *
278
- * @param workspacePath - Default working directory for commands
279
- * @param registry - ProcessRegistry for background process tracking
280
- * @param logger - Optional structured logger for DEBUG-level operation logging
281
- * @param subprocessEnv - Optional filtered env for subprocesses (defense-in-depth)
282
- * @param sandboxConfig - Optional sandbox configuration for OS-level isolation
283
- * @param eventBus - Optional TypedEventBus for emitting command:blocked audit events
284
- * @param getToolResultsDir - Optional getter for session tool-results directory
285
- * @returns AgentTool implementing the exec interface
415
+ * Backward compat NOT preserved (memory `feedback_no_backward_compat`).
416
+ *
417
+ * @param deps - Dependencies bundle. See `ExecToolDeps` for field semantics.
418
+ * `toolCapabilityPort` is REQUIRED; `approvalGate` is optional but
419
+ * required for the soft-stop override path.
420
+ * @returns AgentTool implementing the exec interface.
286
421
  */
287
- export function createExecTool(workspacePath, registry, secretManager, platformSecretNames, logger, subprocessEnv, sandboxConfig, eventBus, getToolResultsDir) {
422
+ export function createExecTool(deps) {
423
+ const { workspacePath, registry, secretManager, platformSecretNames, logger, subprocessEnv, sandboxConfig, eventBus, getToolResultsDir, } = deps;
288
424
  // Comis extension: promptGuidelines is not part of AgentTool type, use object
289
425
  // spread to avoid excess property checks in the return statement.
290
426
  const guidelines = {
@@ -364,9 +500,132 @@ export function createExecTool(workspacePath, registry, secretManager, platformS
364
500
  });
365
501
  throwToolError("permission_denied", validationError.message);
366
502
  }
503
+ // ===================================================================
504
+ // Install-detour mode policy gate
505
+ //
506
+ // Runs synchronously BEFORE any subprocess spawn. soft-stop refuses
507
+ // pre-spawn; observe and advise fall through to spawn after emitting
508
+ // events.
509
+ //
510
+ // The decision is computed ONCE here and propagated to:
511
+ // - Event emission (this block)
512
+ // - ProcessSession population at all 3 spawn sites
513
+ // - Foreground / auto-bg / explicit-bg envelope augmentation (advise)
514
+ // - process.status retroactive augmentation (read back from session)
515
+ // ===================================================================
516
+ const installDetourMode = deps.toolCapabilityPort.getInstallDetourMode();
517
+ const installDetourDecision = parseInstallDetour(command, deps.toolCapabilityPort);
518
+ const allowInstallDetourOverride = readBooleanParam(p, "allowInstallDetour", false) ?? false;
519
+ // Track the terminal action emitted by the mode cascade for the per-call INFO log.
520
+ // Initialized to "no-decision" because the parser may return null (no install form /
521
+ // no overlap); when null, the mode cascade and the log block both short-circuit (the
522
+ // log lives inside `if (decision !== null)`).
523
+ let terminalAction = "no-decision";
524
+ if (installDetourDecision !== null) {
525
+ // Decision is non-null only when overlaps.length > 0 (parser contract).
526
+ if (installDetourMode === "observe") {
527
+ for (const overlap of installDetourDecision.overlaps) {
528
+ // Scope each emit to the single overlap so downstream
529
+ // consumers receive distinct per-overlap payloads.
530
+ // The spread keeps packageManager / commandDigest /
531
+ // packages identical across the N events for a single call —
532
+ // only `overlaps[]` differs.
533
+ eventBus?.emit("tool:install_detour_detected", buildInstallDetourEventPayload({ ...installDetourDecision, overlaps: [overlap] }, "observe", "observed"));
534
+ terminalAction = "observed";
535
+ }
536
+ // Fall through to spawn (observe runs unchanged)
537
+ }
538
+ else if (installDetourMode === "advise") {
539
+ for (const overlap of installDetourDecision.overlaps) {
540
+ // Scope each emit to the single overlap.
541
+ // See observe-loop comment above for the rationale.
542
+ eventBus?.emit("tool:install_detour_detected", buildInstallDetourEventPayload({ ...installDetourDecision, overlaps: [overlap] }, "advise", "hinted"));
543
+ terminalAction = "hinted";
544
+ }
545
+ // Fall through to spawn; envelope augmentation applied at completion sites
546
+ }
547
+ else if (installDetourMode === "soft-stop") {
548
+ if (!allowInstallDetourOverride) {
549
+ // Refuse pre-spawn, single soft_stopped event
550
+ eventBus?.emit("tool:install_detour_detected", buildInstallDetourEventPayload(installDetourDecision, "soft-stop", "soft_stopped"));
551
+ terminalAction = "soft_stopped";
552
+ const errorMessage = buildSoftStopErrorTemplate(installDetourDecision, deps.toolCapabilityPort);
553
+ if (errorMessage === null) {
554
+ // Overlaps disappeared mid-call. Fall through to spawn.
555
+ logger?.debug({
556
+ toolName: "exec",
557
+ commandDigest: installDetourDecision.commandDigest,
558
+ mode: "soft-stop",
559
+ outcome: "overlaps-disappeared",
560
+ }, "install-detour overlap sources disappeared mid-call; falling through to spawn");
561
+ }
562
+ else {
563
+ throwToolError("permission_denied", errorMessage);
564
+ }
565
+ }
566
+ else {
567
+ // allowInstallDetour: true → submit approval request
568
+ const ctx = tryGetContext();
569
+ if (!deps.approvalGate || !ctx) {
570
+ // Fail-closed: missing gate or missing context → emit override_denied + throw
571
+ eventBus?.emit("tool:install_detour_detected", buildInstallDetourEventPayload(installDetourDecision, "soft-stop", "override_denied"));
572
+ terminalAction = "override_denied";
573
+ const errorMessage = buildSoftStopErrorTemplate(installDetourDecision, deps.toolCapabilityPort);
574
+ throwToolError("permission_denied", errorMessage ?? "Install-detour override denied: missing approval gate or request context.");
575
+ }
576
+ else {
577
+ // Emit override_requested BEFORE awaiting (event-pair contract)
578
+ eventBus?.emit("tool:install_detour_detected", buildInstallDetourEventPayload(installDetourDecision, "soft-stop", "override_requested"));
579
+ terminalAction = "override_requested";
580
+ const resolution = await deps.approvalGate.requestApproval({
581
+ toolName: "exec",
582
+ action: `exec.install_detour.override:${installDetourDecision.commandDigest}`,
583
+ params: {
584
+ // sanitized only
585
+ packageManager: installDetourDecision.packageManager,
586
+ packages: installDetourDecision.packages,
587
+ overlaps: installDetourDecision.overlaps,
588
+ mode: "soft-stop",
589
+ commandDigest: installDetourDecision.commandDigest,
590
+ },
591
+ agentId: ctx.userId ?? "unknown",
592
+ sessionKey: ctx.sessionKey,
593
+ trustLevel: (ctx.trustLevel ?? "admin"),
594
+ channelType: ctx.channelType,
595
+ });
596
+ if (!resolution.approved) {
597
+ eventBus?.emit("tool:install_detour_detected", buildInstallDetourEventPayload(installDetourDecision, "soft-stop", "override_denied"));
598
+ terminalAction = "override_denied";
599
+ throwToolError("permission_denied", `Install-detour override denied: ${resolution.reason ?? "no reason given"}`);
600
+ }
601
+ // Approved — emit overridden, fall through to spawn UNAUGMENTED.
602
+ eventBus?.emit("tool:install_detour_detected", buildInstallDetourEventPayload(installDetourDecision, "soft-stop", "overridden"));
603
+ terminalAction = "overridden";
604
+ }
605
+ }
606
+ }
607
+ // Per-call INFO log summarizing the policy-gate evaluation
608
+ // (AGENTS.md §2.7 object-first convention).
609
+ // Fires for every command where a decision was produced AND a mode branch ran.
610
+ // The `terminalAction` field reflects the LAST emitted action for this call.
611
+ // For multi-event paths (observe/advise: 1-per-overlap; soft-stop with override:
612
+ // 2-event pair), `terminalAction` is the last action in the cascade for the call.
613
+ logger?.info({
614
+ toolName: "exec",
615
+ commandDigest: installDetourDecision.commandDigest,
616
+ packageManager: installDetourDecision.packageManager,
617
+ packageCount: installDetourDecision.packages.length,
618
+ overlapCount: installDetourDecision.overlaps.length,
619
+ mode: installDetourMode,
620
+ action: terminalAction,
621
+ }, "install-detour policy gate evaluated");
622
+ }
623
+ // ===================================================================
624
+ // End install-detour mode block
625
+ // ===================================================================
367
626
  // Detect --break-system-packages for post-execution warning
368
627
  const breakSystemWarning = command.includes("--break-system-packages")
369
- ? "\u26a0\ufe0f WARNING: --break-system-packages modifies the system Python. Use a virtualenv instead: python3 -m venv .venv && .venv/bin/pip install ...\n\n"
628
+ ? "\u26a0\ufe0f WARNING: --break-system-packages modifies the system Python. Use a virtualenv: the workspace's pre-warmed venv (venv/bin/pip install ...) or a per-project one (python3 -m venv projects/<name>/.venv).\n\n"
370
629
  : "";
371
630
  // Log command start (truncate command to 200 chars for security)
372
631
  logger?.debug({ toolName: "exec", command: command.slice(0, 200), background, pty, ...(description && { description }) }, "Exec command start");
@@ -414,10 +673,48 @@ export function createExecTool(workspacePath, registry, secretManager, platformS
414
673
  }, "Exec resolved secretRefs for subprocess");
415
674
  }
416
675
  }
417
- // Build environment (use filtered subprocess env instead of raw process.env)
676
+ // Build environment (use filtered subprocess env instead of raw process.env).
418
677
  const baseEnv = subprocessEnv ?? process.env;
678
+ // Workspace-internal env split into two halves:
679
+ //
680
+ // 1. Always-on: MPLCONFIGDIR / XDG_CACHE_HOME / MPLBACKEND /
681
+ // PIP_DISABLE_PIP_VERSION_CHECK. Eliminates the matplotlib
682
+ // `Fontconfig error` regardless of which venv layout (workspace-
683
+ // root `venv/`, per-project `.venv/`, none) the agent uses --
684
+ // the host `/root/.cache/matplotlib` may be read-only under
685
+ // `ProtectSystem=strict`; the workspace cache dir is always
686
+ // writable. Also prevents host XDG_CACHE_HOME leakage.
687
+ //
688
+ // 2. Conditional: PATH gets `${workspacePath}/venv/bin` prepended
689
+ // only when that directory actually exists (i.e. the Dockerfile
690
+ // pre-warm landed and wasn't shadowed by a stale volume). This
691
+ // closes the 15s pip-install hot path for prewarm users without
692
+ // shadowing per-project `projects/<name>/.venv/bin/python`
693
+ // invocations the agent makes directly.
694
+ //
695
+ // Order: spread baseEnv -> override with dataEnv -> userEnv (so
696
+ // the agent can still pin a specific value via `env: {...}`) ->
697
+ // server-resolved secrets (always last; agent cannot override).
698
+ const dataEnv = resolveDataEnv({ workspaceDir: workspacePath });
699
+ const venvBin = safePath(workspacePath, "venv", "bin");
700
+ if (existsSync(venvBin)) {
701
+ logger?.debug({ toolName: "exec", workspaceDir: workspacePath, hint: "Prepending workspace-prewarmed venv/bin to PATH" }, "Exec workspace venv detected");
702
+ // Prepend venv bin so `python` / `pip` resolve to the prewarm
703
+ // while system binaries (bash, sh, node, git, curl) remain
704
+ // reachable via baseEnv.PATH.
705
+ if (dataEnv.PATH && baseEnv.PATH) {
706
+ dataEnv.PATH = `${dataEnv.PATH}:${baseEnv.PATH}`;
707
+ }
708
+ }
709
+ else {
710
+ // No prewarm on this workspace -- drop the venv-only PATH so
711
+ // baseEnv.PATH wins. The matplotlib + cache dir env vars survive
712
+ // and still kill the Fontconfig warning universally.
713
+ delete dataEnv.PATH;
714
+ }
419
715
  const env = {
420
716
  ...baseEnv,
717
+ ...dataEnv,
421
718
  ...(userEnv ?? {}),
422
719
  ...(resolvedSecretEnv ?? {}),
423
720
  };
@@ -435,9 +732,9 @@ export function createExecTool(workspacePath, registry, secretManager, platformS
435
732
  logger?.debug({ toolName: "exec", stdinLength: input.length }, "Exec stdin write");
436
733
  }
437
734
  if (background) {
438
- return executeBackground(command, cwd, finalEnv, input, registry, logger, sandboxConfig, workspacePath, tempDir, description, pty);
735
+ return executeBackground(command, cwd, finalEnv, input, registry, logger, sandboxConfig, workspacePath, tempDir, description, pty, installDetourDecision ?? undefined, installDetourMode);
439
736
  }
440
- const result = await executeForeground(command, cwd, finalEnv, timeoutMs, input, signal, onUpdate, logger, sandboxConfig, workspacePath, tempDir, registry, autoBackgroundMs, pty, description, toolCallId, getToolResultsDir);
737
+ const result = await executeForeground(command, cwd, finalEnv, timeoutMs, input, signal, onUpdate, logger, sandboxConfig, workspacePath, tempDir, registry, autoBackgroundMs, pty, description, toolCallId, getToolResultsDir, installDetourDecision ?? undefined, installDetourMode);
441
738
  // Prepend --break-system-packages warning to stdout so the LLM sees it
442
739
  if (breakSystemWarning && result.details) {
443
740
  const details = result.details;
@@ -469,7 +766,7 @@ function escalateToBackground(ctx) {
469
766
  id: generateSessionId(),
470
767
  command: ctx.command,
471
768
  pid: ctx.child.pid,
472
- startedAt: Math.round(ctx.startTime),
769
+ startedAt: ctx.startTimeMs,
473
770
  status: "running",
474
771
  exitCode: undefined,
475
772
  stdout: ctx.stdoutBuf,
@@ -479,6 +776,14 @@ function escalateToBackground(ctx) {
479
776
  sandboxed: !!ctx.sandboxConfig,
480
777
  autoBackgrounded: true,
481
778
  ...(ctx.description && { description: ctx.description }),
779
+ // Spawn-time decision capture (advise+overlap only).
780
+ // observe-mode runs unchanged with no retroactive hint; soft-stop refused calls
781
+ // never reach a session-creation site (refused pre-spawn).
782
+ ...(ctx.installDetourDecision !== null
783
+ && ctx.installDetourDecision !== undefined
784
+ && ctx.installDetourDecision.overlaps.length > 0
785
+ && ctx.installDetourMode === "advise"
786
+ && { installDetourDecision: ctx.installDetourDecision }),
482
787
  };
483
788
  // Re-wire stdout/stderr from rolling buffer to session append
484
789
  const bgStdoutCleaner = createOutputCleaner();
@@ -506,6 +811,27 @@ function escalateToBackground(ctx) {
506
811
  ctx.logger?.info({ toolName: "exec", sessionId: session.id, pid: ctx.child.pid, durationMs: Math.round(performance.now() - ctx.startTime), ...(ctx.description && { description: ctx.description }) }, "Exec auto-backgrounded after threshold");
507
812
  if (ctx.spillStream)
508
813
  ctx.spillStream.end();
814
+ // Auto-bg envelope augmentation in advise mode
815
+ if (ctx.installDetourMode === "advise" &&
816
+ ctx.installDetourDecision !== null &&
817
+ ctx.installDetourDecision !== undefined &&
818
+ ctx.installDetourDecision.overlaps.length > 0) {
819
+ const hint = buildInstallDetourHint(ctx.installDetourDecision);
820
+ const augmented = jsonResult({
821
+ status: "backgrounded",
822
+ sessionId: session.id,
823
+ pid: ctx.child.pid,
824
+ stdoutSoFar: truncateTail(ctx.stdoutBuf).content,
825
+ stderrSoFar: truncateTail(ctx.stderrBuf).content,
826
+ ...(ctx.description && { description: ctx.description }),
827
+ installDetourHint: hint.installDetourHint,
828
+ });
829
+ ctx.resolve({
830
+ content: [...augmented.content, hint.hintContentBlock],
831
+ details: augmented.details,
832
+ });
833
+ return;
834
+ }
509
835
  ctx.resolve(jsonResult({
510
836
  status: "backgrounded",
511
837
  sessionId: session.id,
@@ -518,8 +844,9 @@ function escalateToBackground(ctx) {
518
844
  // ---------------------------------------------------------------------------
519
845
  // Foreground execution
520
846
  // ---------------------------------------------------------------------------
521
- function executeForeground(command, cwd, env, timeoutMs, input, signal, onUpdate, logger, sandboxConfig, workspacePath, tempDir, registry, autoBackgroundMs, pty, description, toolCallId, getToolResultsDir) {
847
+ function executeForeground(command, cwd, env, timeoutMs, input, signal, onUpdate, logger, sandboxConfig, workspacePath, tempDir, registry, autoBackgroundMs, pty, description, toolCallId, getToolResultsDir, installDetourDecision, installDetourMode) {
522
848
  const startTime = performance.now();
849
+ const startTimeMs = Date.now();
523
850
  return new Promise((resolve) => {
524
851
  const { bin, args, cwd: spawnCwd } = buildSpawnCommand(command, cwd, sandboxConfig, workspacePath ?? cwd, tempDir ?? tmpdir(), pty);
525
852
  const child = spawn(bin, args, {
@@ -653,11 +980,14 @@ function executeForeground(command, cwd, env, timeoutMs, input, signal, onUpdate
653
980
  if (resolved)
654
981
  return;
655
982
  escalateToBackground({
656
- command, child, startTime, stdoutBuf, stderrBuf,
983
+ command, child, startTime, startTimeMs, stdoutBuf, stderrBuf,
657
984
  registry, sandboxConfig, logger, spillStream,
658
985
  signal, onAbort, timeoutTimer, resolve,
659
986
  setResolved: () => { resolved = true; },
660
987
  description,
988
+ // Forward install-detour spawn-time decision + mode
989
+ ...(installDetourDecision !== undefined && { installDetourDecision }),
990
+ ...(installDetourMode !== undefined && { installDetourMode }),
661
991
  });
662
992
  }, effectiveAutoMs)
663
993
  : null;
@@ -722,6 +1052,14 @@ function executeForeground(command, cwd, env, timeoutMs, input, signal, onUpdate
722
1052
  if (aborted) {
723
1053
  finalStderr += (finalStderr ? "\n" : "") + "Process aborted by signal";
724
1054
  }
1055
+ // Recovery diagnostics: prepend a `RECOVERY HINT:` line for known-recoverable
1056
+ // failures (e.g. Python ModuleNotFoundError + missing pyproject.toml). Same
1057
+ // surfacing pattern as breakSystemWarning on stdout — gives the LLM an
1058
+ // actionable next step at the HEAD of stderr instead of buried in JSON.
1059
+ const recoveryHint = matchExecRecoveryHint({ stderr: finalStderr, exitCode, cwd });
1060
+ if (recoveryHint) {
1061
+ finalStderr = recoveryHint + (finalStderr ? "\n" + finalStderr : "");
1062
+ }
725
1063
  const durationMs = Math.round(performance.now() - startTime);
726
1064
  logger?.debug({ toolName: "exec", durationMs, exitCode, ...(description && { description }) }, "Exec command complete");
727
1065
  const result = {
@@ -782,6 +1120,19 @@ function executeForeground(command, cwd, env, timeoutMs, input, signal, onUpdate
782
1120
  }
783
1121
  }
784
1122
  }
1123
+ // Foreground completion envelope augmentation
1124
+ if (installDetourMode === "advise" &&
1125
+ installDetourDecision !== undefined &&
1126
+ installDetourDecision.overlaps.length > 0) {
1127
+ const hint = buildInstallDetourHint(installDetourDecision);
1128
+ result.installDetourHint = hint.installDetourHint;
1129
+ const augmented = jsonResult(result);
1130
+ resolve({
1131
+ content: [...augmented.content, hint.hintContentBlock],
1132
+ details: augmented.details,
1133
+ });
1134
+ return;
1135
+ }
785
1136
  resolve(jsonResult(result));
786
1137
  });
787
1138
  // Handle spawn errors
@@ -809,7 +1160,7 @@ function executeForeground(command, cwd, env, timeoutMs, input, signal, onUpdate
809
1160
  // ---------------------------------------------------------------------------
810
1161
  // Background execution
811
1162
  // ---------------------------------------------------------------------------
812
- function executeBackground(command, cwd, env, input, registry, logger, sandboxConfig, workspacePath, tempDir, description, pty) {
1163
+ function executeBackground(command, cwd, env, input, registry, logger, sandboxConfig, workspacePath, tempDir, description, pty, installDetourDecision, installDetourMode) {
813
1164
  const sessionId = generateSessionId();
814
1165
  const { bin, args, cwd: spawnCwd } = buildSpawnCommand(command, cwd, sandboxConfig, workspacePath ?? cwd, tempDir ?? tmpdir(), pty);
815
1166
  const child = spawn(bin, args, {
@@ -831,6 +1182,11 @@ function executeBackground(command, cwd, env, input, registry, logger, sandboxCo
831
1182
  maxOutputChars: BACKGROUND_MAX_OUTPUT_CHARS,
832
1183
  sandboxed: !!sandboxConfig,
833
1184
  ...(description && { description }),
1185
+ // Spawn-time decision capture (advise+overlap only).
1186
+ ...(installDetourDecision !== undefined
1187
+ && installDetourDecision.overlaps.length > 0
1188
+ && installDetourMode === "advise"
1189
+ && { installDetourDecision }),
834
1190
  };
835
1191
  // Output cleaners for stateful UTF-8 decode + ANSI strip + CR normalize + binary sanitize
836
1192
  const stdoutCleaner = createOutputCleaner();
@@ -877,6 +1233,23 @@ function executeBackground(command, cwd, env, input, registry, logger, sandboxCo
877
1233
  // Register in ProcessRegistry
878
1234
  registry.add(session);
879
1235
  logger?.debug({ toolName: "exec", sessionId, pid: child.pid }, "Background process spawned");
1236
+ // Explicit-bg envelope augmentation in advise mode
1237
+ if (installDetourMode === "advise" &&
1238
+ installDetourDecision !== undefined &&
1239
+ installDetourDecision.overlaps.length > 0) {
1240
+ const hint = buildInstallDetourHint(installDetourDecision);
1241
+ const augmented = jsonResult({
1242
+ status: "started",
1243
+ sessionId,
1244
+ pid: child.pid,
1245
+ ...(description && { description }),
1246
+ installDetourHint: hint.installDetourHint,
1247
+ });
1248
+ return {
1249
+ content: [...augmented.content, hint.hintContentBlock],
1250
+ details: augmented.details,
1251
+ };
1252
+ }
880
1253
  return jsonResult({
881
1254
  status: "started",
882
1255
  sessionId,
@@ -148,22 +148,22 @@ function buildRipgrepArgs(pattern, outputMode, options = {}) {
148
148
  }
149
149
  // Pattern (use -e to avoid pattern being confused with flags)
150
150
  args.push("-e", pattern);
151
- // Phase 9: filtering
151
+ // Filtering
152
152
  if (options.glob)
153
153
  args.push("--glob", options.glob);
154
154
  if (options.type)
155
155
  args.push("--type", options.type);
156
- // Phase 9: case-insensitive
156
+ // Case-insensitive
157
157
  if (options.caseInsensitive)
158
158
  args.push("-i");
159
159
  // Literal mode (fixed-strings)
160
160
  if (options.literal) {
161
161
  args.push("--fixed-strings");
162
162
  }
163
- // Phase 9: multiline
163
+ // Multiline
164
164
  if (options.multiline)
165
165
  args.push("-U", "--multiline-dotall");
166
- // Phase 9: context lines (content mode only -- ignored for other modes)
166
+ // Context lines (content mode only -- ignored for other modes)
167
167
  if (outputMode === "content") {
168
168
  if (options.afterContext !== undefined)
169
169
  args.push("-A", String(options.afterContext));
@@ -172,7 +172,7 @@ function buildRipgrepArgs(pattern, outputMode, options = {}) {
172
172
  if (options.context !== undefined)
173
173
  args.push("-C", String(options.context));
174
174
  }
175
- // Phase 9: per-file match limit for pagination efficiency (content mode only)
175
+ // Per-file match limit for pagination efficiency (content mode only)
176
176
  if (outputMode === "content") {
177
177
  const headLimit = options.headLimit ?? 250;
178
178
  const offset = options.offset ?? 0;
@@ -327,7 +327,7 @@ export function createComisGrepTool(workspacePath, logger, readOnlyPaths, shared
327
327
  const outputMode = outputModeRaw && OUTPUT_MODES.includes(outputModeRaw)
328
328
  ? outputModeRaw
329
329
  : "content";
330
- // Phase 9: new parameters
330
+ // Optional filter / formatting parameters
331
331
  const glob = readStringParam(params, "glob", false);
332
332
  const type = readStringParam(params, "type", false);
333
333
  const caseInsensitive = readBooleanParam(params, "-i", false) ?? false;