@wrongstack/core 0.297.0 → 0.298.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (806) hide show
  1. package/dist/chronicle/index.js +126 -22
  2. package/dist/chronicle/project-server-client.d.ts +12 -0
  3. package/dist/chronicle/project-server-protocol.d.ts +22 -0
  4. package/dist/chronicle/project-server.js +238 -157
  5. package/dist/coordination/agents/index.js +136 -1
  6. package/dist/coordination/agents/role-skills.d.ts +3 -2
  7. package/dist/coordination/brain-trace.d.ts +2 -1
  8. package/dist/coordination/director/director-task-registry.d.ts +12 -0
  9. package/dist/coordination/fleet-supervisor.d.ts +21 -0
  10. package/dist/coordination/index.d.ts +23 -21
  11. package/dist/coordination/index.js +16493 -16068
  12. package/dist/coordination/mail-tools.d.ts +3 -3
  13. package/dist/coordination/mailbox-credential-store.d.ts +22 -2
  14. package/dist/coordination/mailbox-credential-throttle.d.ts +63 -0
  15. package/dist/coordination/mailbox-project-server-client.d.ts +16 -0
  16. package/dist/coordination/mailbox-project-server-protocol.d.ts +43 -5
  17. package/dist/coordination/mailbox-project-server.js +508 -253
  18. package/dist/coordination/provider-status-tracker.d.ts +2 -0
  19. package/dist/coordination/remote-mailbox-credential-store.d.ts +5 -5
  20. package/dist/coordination/remote-mailbox.d.ts +8 -4
  21. package/dist/coordination/sqlite-mailbox-credentials.d.ts +11 -0
  22. package/dist/core/fallback-profile-manager.d.ts +14 -0
  23. package/dist/core/index.js +451 -137
  24. package/dist/core/instruction-bundle.d.ts +12 -0
  25. package/dist/core/system-prompt-builder.d.ts +14 -0
  26. package/dist/core/system-prompt-skill-bodies.d.ts +1 -1
  27. package/dist/core/system-prompt-skill-text.d.ts +1 -2
  28. package/dist/defaults/index.js +2191 -1208
  29. package/dist/design/index.js +47 -8
  30. package/dist/execution/design-materialize.d.ts +22 -0
  31. package/dist/execution/index.js +495 -248
  32. package/dist/execution/skill-loader.d.ts +10 -1
  33. package/dist/execution/tool-error-taxonomy.d.ts +31 -0
  34. package/dist/execution/tool-executor.d.ts +1 -0
  35. package/dist/goal/index.js +3 -1
  36. package/dist/hooks/index.js +5 -0
  37. package/dist/hq/auth-audit.d.ts +6 -0
  38. package/dist/hq/auth-store.d.ts +59 -3
  39. package/dist/hq/index.js +401 -101
  40. package/dist/hq/kanban-store.d.ts +3 -0
  41. package/dist/hq/protocol/core.d.ts +3 -15
  42. package/dist/hq/protocol/envelope.d.ts +29 -0
  43. package/dist/hq/protocol/governance.d.ts +34 -0
  44. package/dist/hq/protocol/project.d.ts +3 -0
  45. package/dist/hq/protocol/resume.d.ts +1 -1
  46. package/dist/hq/protocol.d.ts +9 -8
  47. package/dist/hq/protocol.js +675 -0
  48. package/dist/index.js +9012 -6916
  49. package/dist/infrastructure/index.js +199 -102
  50. package/dist/kernel/events/session-events.d.ts +3 -0
  51. package/dist/kernel/events/tool-events.d.ts +3 -1
  52. package/dist/models/index.js +1 -1
  53. package/dist/observability/index.js +27 -0
  54. package/dist/observability/prometheus.d.ts +11 -0
  55. package/dist/plugin/index.d.ts +5 -1
  56. package/dist/plugin/index.js +988 -558
  57. package/dist/plugins/auto-review-plugin.d.ts +1 -11
  58. package/dist/plugins/review-store-maintenance.d.ts +26 -0
  59. package/dist/plugins/review-types.d.ts +6 -0
  60. package/dist/security/auto-approve-policy.d.ts +37 -0
  61. package/dist/security/capabilities.d.ts +45 -1
  62. package/dist/security/error-sanitize.d.ts +49 -0
  63. package/dist/security/file-permissions.d.ts +41 -0
  64. package/dist/security/index.d.ts +9 -6
  65. package/dist/security/index.js +3008 -2029
  66. package/dist/security/permission-helpers.d.ts +93 -0
  67. package/dist/security/permission-policy.d.ts +37 -35
  68. package/dist/security/secret-vault.d.ts +17 -0
  69. package/dist/security/totp.d.ts +86 -0
  70. package/dist/skills/frontmatter.d.ts +12 -1
  71. package/dist/skills/github-fetcher.d.ts +48 -0
  72. package/dist/skills/index.js +137 -26
  73. package/dist/skills/limits.d.ts +19 -0
  74. package/dist/skills/skill-installer.d.ts +13 -0
  75. package/dist/storage/index.js +929 -733
  76. package/dist/storage/provider-config-watcher.d.ts +1 -0
  77. package/dist/storage/session-helpers.d.ts +1 -0
  78. package/dist/storage/session-store.d.ts +9 -2
  79. package/dist/storage/session-workspace-checkpoints.d.ts +5 -0
  80. package/dist/tools/fallback-manage-tools.d.ts +6 -0
  81. package/dist/tools/index.js +287 -131
  82. package/dist/tools/mcp-use.d.ts +1 -1
  83. package/dist/types/blocks.d.ts +7 -0
  84. package/dist/types/config/autonomy.d.ts +15 -7
  85. package/dist/types/config/mcp-features.d.ts +9 -1
  86. package/dist/types/config/root.d.ts +10 -4
  87. package/dist/types/context-window.d.ts +15 -0
  88. package/dist/types/index.d.ts +1 -1
  89. package/dist/types/secret-vault.d.ts +8 -0
  90. package/dist/types/session.d.ts +2 -0
  91. package/dist/types/skill.d.ts +56 -0
  92. package/dist/types/tool-executor.d.ts +2 -0
  93. package/dist/utils/env-typed.d.ts +64 -0
  94. package/dist/utils/glob-match.d.ts +21 -1
  95. package/dist/utils/heap-watchdog.js +1 -1
  96. package/dist/utils/incoming-images.d.ts +19 -0
  97. package/dist/utils/index.d.ts +16 -12
  98. package/dist/utils/index.js +3128 -2800
  99. package/dist/utils/path-segment.d.ts +29 -0
  100. package/dist/utils/sage-output-block.js +48 -0
  101. package/dist/utils/win32-cmd.d.ts +25 -0
  102. package/dist/worktree/index.js +5 -0
  103. package/instructions/llm/chimera-review.md +4 -6
  104. package/package.json +13 -4
  105. package/skills/auto-review/SKILL.md +11 -76
  106. package/skills/chimera/SKILL.md +31 -49
  107. package/skills/data-governance/SKILL.md +92 -0
  108. package/skills/wrongstack-kanban/SKILL.md +125 -64
  109. package/dist/agent-status-helpers.d.ts.map +0 -1
  110. package/dist/agent-status-tracker.d.ts.map +0 -1
  111. package/dist/boot.d.ts.map +0 -1
  112. package/dist/chronicle/context.d.ts.map +0 -1
  113. package/dist/chronicle/decision-adapter.d.ts.map +0 -1
  114. package/dist/chronicle/domain-adapter.d.ts.map +0 -1
  115. package/dist/chronicle/event-hash.d.ts.map +0 -1
  116. package/dist/chronicle/file-observer.d.ts.map +0 -1
  117. package/dist/chronicle/health-monitor.d.ts.map +0 -1
  118. package/dist/chronicle/identity.d.ts.map +0 -1
  119. package/dist/chronicle/index.d.ts.map +0 -1
  120. package/dist/chronicle/index.js.map +0 -7
  121. package/dist/chronicle/journal.d.ts.map +0 -1
  122. package/dist/chronicle/legacy-journal-import.d.ts.map +0 -1
  123. package/dist/chronicle/metrics-store.d.ts.map +0 -1
  124. package/dist/chronicle/partition-filename.d.ts.map +0 -1
  125. package/dist/chronicle/partition-range-cache.d.ts.map +0 -1
  126. package/dist/chronicle/process-adapter.d.ts.map +0 -1
  127. package/dist/chronicle/project-access.d.ts.map +0 -1
  128. package/dist/chronicle/project-server-client.d.ts.map +0 -1
  129. package/dist/chronicle/project-server-endpoint.d.ts.map +0 -1
  130. package/dist/chronicle/project-server-protocol.d.ts.map +0 -1
  131. package/dist/chronicle/project-server.d.ts.map +0 -1
  132. package/dist/chronicle/project-server.js.map +0 -7
  133. package/dist/chronicle/prompt-manifest.d.ts.map +0 -1
  134. package/dist/chronicle/provider-adapter.d.ts.map +0 -1
  135. package/dist/chronicle/query.d.ts.map +0 -1
  136. package/dist/chronicle/review-adapter.d.ts.map +0 -1
  137. package/dist/chronicle/rollup-adapter.d.ts.map +0 -1
  138. package/dist/chronicle/sink.d.ts.map +0 -1
  139. package/dist/chronicle/sqlite-journal.d.ts.map +0 -1
  140. package/dist/chronicle/sqlite-query.d.ts.map +0 -1
  141. package/dist/chronicle/stream-adapter.d.ts.map +0 -1
  142. package/dist/chronicle/tool-adapter.d.ts.map +0 -1
  143. package/dist/chronicle/types.d.ts.map +0 -1
  144. package/dist/coordination/adaptive-concurrency.d.ts.map +0 -1
  145. package/dist/coordination/agent-bridge.d.ts.map +0 -1
  146. package/dist/coordination/agent-monitor.d.ts.map +0 -1
  147. package/dist/coordination/agent-subagent-runner.d.ts.map +0 -1
  148. package/dist/coordination/agents/agent-prompts.d.ts.map +0 -1
  149. package/dist/coordination/agents/index.d.ts.map +0 -1
  150. package/dist/coordination/agents/index.js.map +0 -7
  151. package/dist/coordination/agents/phase1-discovery.d.ts.map +0 -1
  152. package/dist/coordination/agents/phase2-planning.d.ts.map +0 -1
  153. package/dist/coordination/agents/phase3-build.d.ts.map +0 -1
  154. package/dist/coordination/agents/phase3-techstack.d.ts.map +0 -1
  155. package/dist/coordination/agents/phase3-wave1-platform.d.ts.map +0 -1
  156. package/dist/coordination/agents/phase3-wave2-meta.d.ts.map +0 -1
  157. package/dist/coordination/agents/phase4-verify.d.ts.map +0 -1
  158. package/dist/coordination/agents/phase5-review.d.ts.map +0 -1
  159. package/dist/coordination/agents/phase6-domain.d.ts.map +0 -1
  160. package/dist/coordination/agents/phase7-knowledge.d.ts.map +0 -1
  161. package/dist/coordination/agents/phase8-delivery.d.ts.map +0 -1
  162. package/dist/coordination/agents/phase8-wave3-products.d.ts.map +0 -1
  163. package/dist/coordination/agents/phase9-meta.d.ts.map +0 -1
  164. package/dist/coordination/agents/phase9-wave4-platform-meta.d.ts.map +0 -1
  165. package/dist/coordination/agents/project-agent-config-validation.d.ts.map +0 -1
  166. package/dist/coordination/agents/project-agent-consolidation.d.ts.map +0 -1
  167. package/dist/coordination/agents/project-agent-files.d.ts.map +0 -1
  168. package/dist/coordination/agents/project-agent-identity-types.d.ts.map +0 -1
  169. package/dist/coordination/agents/project-agent-identity.d.ts.map +0 -1
  170. package/dist/coordination/agents/project-agent-knowledge-manifests.d.ts.map +0 -1
  171. package/dist/coordination/agents/project-agent-learning-entries.d.ts.map +0 -1
  172. package/dist/coordination/agents/project-agent-learning-normalize.d.ts.map +0 -1
  173. package/dist/coordination/agents/project-agent-learning-policy.d.ts.map +0 -1
  174. package/dist/coordination/agents/project-agent-learning-structured.d.ts.map +0 -1
  175. package/dist/coordination/agents/project-agent-paths.d.ts.map +0 -1
  176. package/dist/coordination/agents/project-agent-profile.d.ts.map +0 -1
  177. package/dist/coordination/agents/role-skills.d.ts.map +0 -1
  178. package/dist/coordination/agents/types.d.ts.map +0 -1
  179. package/dist/coordination/agents.d.ts.map +0 -1
  180. package/dist/coordination/auto-extend.d.ts.map +0 -1
  181. package/dist/coordination/autonomous-brain.d.ts.map +0 -1
  182. package/dist/coordination/autonomous-coordinator.d.ts.map +0 -1
  183. package/dist/coordination/brain-cache.d.ts.map +0 -1
  184. package/dist/coordination/brain-heuristics.d.ts.map +0 -1
  185. package/dist/coordination/brain-ledger.d.ts.map +0 -1
  186. package/dist/coordination/brain-monitor.d.ts.map +0 -1
  187. package/dist/coordination/brain-rules.d.ts.map +0 -1
  188. package/dist/coordination/brain-telemetry.d.ts.map +0 -1
  189. package/dist/coordination/brain-trace.d.ts.map +0 -1
  190. package/dist/coordination/brain.d.ts.map +0 -1
  191. package/dist/coordination/change-manager.d.ts.map +0 -1
  192. package/dist/coordination/checkpoint-wiring.d.ts.map +0 -1
  193. package/dist/coordination/collab-bus.d.ts.map +0 -1
  194. package/dist/coordination/collab-debug-types.d.ts.map +0 -1
  195. package/dist/coordination/collab-debug.d.ts.map +0 -1
  196. package/dist/coordination/collab-director-host.d.ts.map +0 -1
  197. package/dist/coordination/commit-safety.d.ts.map +0 -1
  198. package/dist/coordination/consensus-protocol.d.ts.map +0 -1
  199. package/dist/coordination/coordinator/error-classifier.d.ts.map +0 -1
  200. package/dist/coordination/delegate-tool.d.ts.map +0 -1
  201. package/dist/coordination/dep-watcher-bridge.d.ts.map +0 -1
  202. package/dist/coordination/dep-watcher.d.ts.map +0 -1
  203. package/dist/coordination/director/director-btw-notes.d.ts.map +0 -1
  204. package/dist/coordination/director/director-budget-policy.d.ts.map +0 -1
  205. package/dist/coordination/director/director-collab.d.ts.map +0 -1
  206. package/dist/coordination/director/director-errors.d.ts.map +0 -1
  207. package/dist/coordination/director/director-task-registry.d.ts.map +0 -1
  208. package/dist/coordination/director/director-toolset.d.ts.map +0 -1
  209. package/dist/coordination/director-basic-tools.d.ts.map +0 -1
  210. package/dist/coordination/director-collab-tools.d.ts.map +0 -1
  211. package/dist/coordination/director-host-contracts.d.ts.map +0 -1
  212. package/dist/coordination/director-input-helpers.d.ts.map +0 -1
  213. package/dist/coordination/director-kanban-queue-helpers.d.ts.map +0 -1
  214. package/dist/coordination/director-options.d.ts.map +0 -1
  215. package/dist/coordination/director-prompts.d.ts.map +0 -1
  216. package/dist/coordination/director-quality-gate-tool.d.ts.map +0 -1
  217. package/dist/coordination/director-session.d.ts.map +0 -1
  218. package/dist/coordination/director-spawn-model.d.ts.map +0 -1
  219. package/dist/coordination/director-tools.d.ts.map +0 -1
  220. package/dist/coordination/director.d.ts.map +0 -1
  221. package/dist/coordination/dispatcher.d.ts.map +0 -1
  222. package/dist/coordination/file-author-tracker.d.ts.map +0 -1
  223. package/dist/coordination/fleet-bus.d.ts.map +0 -1
  224. package/dist/coordination/fleet-event-validation.d.ts.map +0 -1
  225. package/dist/coordination/fleet-manager.d.ts.map +0 -1
  226. package/dist/coordination/fleet-spawn.d.ts.map +0 -1
  227. package/dist/coordination/fleet-status-tool.d.ts.map +0 -1
  228. package/dist/coordination/fleet-supervisor.d.ts.map +0 -1
  229. package/dist/coordination/fleet.d.ts.map +0 -1
  230. package/dist/coordination/global-mailbox-completion.d.ts.map +0 -1
  231. package/dist/coordination/global-mailbox-paths.d.ts.map +0 -1
  232. package/dist/coordination/icoordinator.d.ts.map +0 -1
  233. package/dist/coordination/ifleet-manager.d.ts.map +0 -1
  234. package/dist/coordination/in-memory-transport.d.ts.map +0 -1
  235. package/dist/coordination/index.d.ts.map +0 -1
  236. package/dist/coordination/index.js.map +0 -7
  237. package/dist/coordination/knowledge-graph.d.ts.map +0 -1
  238. package/dist/coordination/large-answer-store.d.ts.map +0 -1
  239. package/dist/coordination/mail-tools.d.ts.map +0 -1
  240. package/dist/coordination/mailbox-actions.d.ts.map +0 -1
  241. package/dist/coordination/mailbox-auth-types.d.ts.map +0 -1
  242. package/dist/coordination/mailbox-codecs.d.ts.map +0 -1
  243. package/dist/coordination/mailbox-constants.d.ts.map +0 -1
  244. package/dist/coordination/mailbox-credential-store.d.ts.map +0 -1
  245. package/dist/coordination/mailbox-events.d.ts.map +0 -1
  246. package/dist/coordination/mailbox-health.d.ts.map +0 -1
  247. package/dist/coordination/mailbox-hooks.d.ts.map +0 -1
  248. package/dist/coordination/mailbox-http-auth.d.ts.map +0 -1
  249. package/dist/coordination/mailbox-http-rate-limit.d.ts.map +0 -1
  250. package/dist/coordination/mailbox-http-router.d.ts.map +0 -1
  251. package/dist/coordination/mailbox-http-validation.d.ts.map +0 -1
  252. package/dist/coordination/mailbox-message-codec.d.ts.map +0 -1
  253. package/dist/coordination/mailbox-parse-state.d.ts.map +0 -1
  254. package/dist/coordination/mailbox-project-server-client.d.ts.map +0 -1
  255. package/dist/coordination/mailbox-project-server-endpoint.d.ts.map +0 -1
  256. package/dist/coordination/mailbox-project-server-protocol.d.ts.map +0 -1
  257. package/dist/coordination/mailbox-project-server.d.ts.map +0 -1
  258. package/dist/coordination/mailbox-project-server.js.map +0 -7
  259. package/dist/coordination/mailbox-receipt-folding.d.ts.map +0 -1
  260. package/dist/coordination/mailbox-registry-codec.d.ts.map +0 -1
  261. package/dist/coordination/mailbox-retention-state.d.ts.map +0 -1
  262. package/dist/coordination/mailbox-status-mappers.d.ts.map +0 -1
  263. package/dist/coordination/mailbox-tool.d.ts.map +0 -1
  264. package/dist/coordination/mailbox-type-properties.d.ts.map +0 -1
  265. package/dist/coordination/mailbox-types.d.ts.map +0 -1
  266. package/dist/coordination/model-matrix.d.ts.map +0 -1
  267. package/dist/coordination/multi-agent-coordinator.d.ts.map +0 -1
  268. package/dist/coordination/multi-agent-timeout.d.ts.map +0 -1
  269. package/dist/coordination/null-fleet-bus.d.ts.map +0 -1
  270. package/dist/coordination/package-author-tracker.d.ts.map +0 -1
  271. package/dist/coordination/package-outdated-watcher.d.ts.map +0 -1
  272. package/dist/coordination/provider-status-tracker.d.ts.map +0 -1
  273. package/dist/coordination/remote-mailbox-credential-store.d.ts.map +0 -1
  274. package/dist/coordination/remote-mailbox.d.ts.map +0 -1
  275. package/dist/coordination/single-instance-mailbox.d.ts.map +0 -1
  276. package/dist/coordination/spawn-budget.d.ts.map +0 -1
  277. package/dist/coordination/sqlite-mailbox-compaction.d.ts.map +0 -1
  278. package/dist/coordination/sqlite-mailbox-credentials.d.ts.map +0 -1
  279. package/dist/coordination/sqlite-mailbox-rows.d.ts.map +0 -1
  280. package/dist/coordination/sqlite-mailbox-schema.d.ts.map +0 -1
  281. package/dist/coordination/sqlite-mailbox.d.ts.map +0 -1
  282. package/dist/coordination/subagent-budget.d.ts.map +0 -1
  283. package/dist/coordination/subagent-nicknames.d.ts.map +0 -1
  284. package/dist/coordination/subagent-result-tool.d.ts.map +0 -1
  285. package/dist/coordination/task-auctioneer.d.ts.map +0 -1
  286. package/dist/coordination/task-dag.d.ts.map +0 -1
  287. package/dist/coordination/techstack-mailbox-consumer.d.ts.map +0 -1
  288. package/dist/coordination/transport.d.ts.map +0 -1
  289. package/dist/coordination/worktree-task-runner.d.ts.map +0 -1
  290. package/dist/core/agent-internals.d.ts.map +0 -1
  291. package/dist/core/agent-loop.d.ts.map +0 -1
  292. package/dist/core/agent-response.d.ts.map +0 -1
  293. package/dist/core/agent-tools.d.ts.map +0 -1
  294. package/dist/core/agent-types.d.ts.map +0 -1
  295. package/dist/core/agent.d.ts.map +0 -1
  296. package/dist/core/btw.d.ts.map +0 -1
  297. package/dist/core/context.d.ts.map +0 -1
  298. package/dist/core/continue-intent.d.ts.map +0 -1
  299. package/dist/core/continue-to-next-iteration.d.ts.map +0 -1
  300. package/dist/core/conversation-state.d.ts.map +0 -1
  301. package/dist/core/fallback-model.d.ts.map +0 -1
  302. package/dist/core/fallback-profile-manager.d.ts.map +0 -1
  303. package/dist/core/fleet-pulse.d.ts.map +0 -1
  304. package/dist/core/index.d.ts.map +0 -1
  305. package/dist/core/index.js.map +0 -7
  306. package/dist/core/input-builder.d.ts.map +0 -1
  307. package/dist/core/instruction-bundle.d.ts.map +0 -1
  308. package/dist/core/iteration-limit.d.ts.map +0 -1
  309. package/dist/core/mailbox-loop.d.ts.map +0 -1
  310. package/dist/core/model-availability-calendar.d.ts.map +0 -1
  311. package/dist/core/model-ref.d.ts.map +0 -1
  312. package/dist/core/model-ref.js.map +0 -7
  313. package/dist/core/modes/brief.d.ts.map +0 -1
  314. package/dist/core/modes/default.d.ts.map +0 -1
  315. package/dist/core/modes/teach.d.ts.map +0 -1
  316. package/dist/core/provider-runner.d.ts.map +0 -1
  317. package/dist/core/queued-messages.d.ts.map +0 -1
  318. package/dist/core/request-provider-binding.d.ts.map +0 -1
  319. package/dist/core/run-env.d.ts.map +0 -1
  320. package/dist/core/streaming-response-builder.d.ts.map +0 -1
  321. package/dist/core/system-prompt-blocks.d.ts.map +0 -1
  322. package/dist/core/system-prompt-builder.d.ts.map +0 -1
  323. package/dist/core/system-prompt-environment-probes.d.ts.map +0 -1
  324. package/dist/core/system-prompt-environment.d.ts.map +0 -1
  325. package/dist/core/system-prompt-memory-skills.d.ts.map +0 -1
  326. package/dist/core/system-prompt-plan.d.ts.map +0 -1
  327. package/dist/core/system-prompt-shell.d.ts.map +0 -1
  328. package/dist/core/system-prompt-skill-bodies.d.ts.map +0 -1
  329. package/dist/core/system-prompt-skill-text.d.ts.map +0 -1
  330. package/dist/defaults/index.d.ts.map +0 -1
  331. package/dist/defaults/index.js.map +0 -7
  332. package/dist/design/index.d.ts.map +0 -1
  333. package/dist/design/index.js.map +0 -7
  334. package/dist/execution/auto-compaction-middleware.d.ts.map +0 -1
  335. package/dist/execution/autonomous-runner.d.ts.map +0 -1
  336. package/dist/execution/autonomy-brain.d.ts.map +0 -1
  337. package/dist/execution/autonomy-prompt-contributor.d.ts.map +0 -1
  338. package/dist/execution/brain-chain.d.ts.map +0 -1
  339. package/dist/execution/brain-circuit.d.ts.map +0 -1
  340. package/dist/execution/brain-evaluation.d.ts.map +0 -1
  341. package/dist/execution/brain-runtime-constants.d.ts.map +0 -1
  342. package/dist/execution/brain-runtime.d.ts.map +0 -1
  343. package/dist/execution/compaction-core.d.ts.map +0 -1
  344. package/dist/execution/compaction-scoring.d.ts.map +0 -1
  345. package/dist/execution/compaction-summary-cache.d.ts.map +0 -1
  346. package/dist/execution/compactor.d.ts.map +0 -1
  347. package/dist/execution/council-brain.d.ts.map +0 -1
  348. package/dist/execution/council-orchestrator.d.ts.map +0 -1
  349. package/dist/execution/council-personas.d.ts.map +0 -1
  350. package/dist/execution/council-profiles.d.ts.map +0 -1
  351. package/dist/execution/council-prompts.d.ts.map +0 -1
  352. package/dist/execution/council-resolution.d.ts.map +0 -1
  353. package/dist/execution/design-color.d.ts.map +0 -1
  354. package/dist/execution/design-detect.d.ts.map +0 -1
  355. package/dist/execution/design-kit-loader.d.ts.map +0 -1
  356. package/dist/execution/design-materialize.d.ts.map +0 -1
  357. package/dist/execution/design-project-store.d.ts.map +0 -1
  358. package/dist/execution/design-tune.d.ts.map +0 -1
  359. package/dist/execution/design-verify.d.ts.map +0 -1
  360. package/dist/execution/enhance-recovery.d.ts.map +0 -1
  361. package/dist/execution/error-handler.d.ts.map +0 -1
  362. package/dist/execution/eternal-autonomy-types.d.ts.map +0 -1
  363. package/dist/execution/eternal-autonomy.d.ts.map +0 -1
  364. package/dist/execution/goal-preamble.d.ts.map +0 -1
  365. package/dist/execution/index.d.ts.map +0 -1
  366. package/dist/execution/index.js.map +0 -7
  367. package/dist/execution/intelligent-compactor.d.ts.map +0 -1
  368. package/dist/execution/model-runtime.d.ts.map +0 -1
  369. package/dist/execution/one-shot-llm.d.ts.map +0 -1
  370. package/dist/execution/parallel-eternal-engine.d.ts.map +0 -1
  371. package/dist/execution/prompt-enhancer.d.ts.map +0 -1
  372. package/dist/execution/prompt-enhancer.js.map +0 -7
  373. package/dist/execution/prompt-loader.d.ts.map +0 -1
  374. package/dist/execution/provider-runner-impl.d.ts.map +0 -1
  375. package/dist/execution/regex-patterns.d.ts.map +0 -1
  376. package/dist/execution/retry-policy.d.ts.map +0 -1
  377. package/dist/execution/selective-compactor.d.ts.map +0 -1
  378. package/dist/execution/skill-loader.d.ts.map +0 -1
  379. package/dist/execution/strategy-compactor.d.ts.map +0 -1
  380. package/dist/execution/subagent-compaction.d.ts.map +0 -1
  381. package/dist/execution/tool-executor-logging.d.ts.map +0 -1
  382. package/dist/execution/tool-executor-results.d.ts.map +0 -1
  383. package/dist/execution/tool-executor-stream.d.ts.map +0 -1
  384. package/dist/execution/tool-executor-support.d.ts.map +0 -1
  385. package/dist/execution/tool-executor.d.ts.map +0 -1
  386. package/dist/extension/extension-points.d.ts.map +0 -1
  387. package/dist/extension/index.d.ts.map +0 -1
  388. package/dist/extension/index.js.map +0 -7
  389. package/dist/extension/registry.d.ts.map +0 -1
  390. package/dist/fleet-notifier.d.ts.map +0 -1
  391. package/dist/goal/checkpoint.d.ts.map +0 -1
  392. package/dist/goal/goal-assessor.d.ts.map +0 -1
  393. package/dist/goal/goal-planner.d.ts.map +0 -1
  394. package/dist/goal/goal-runner.d.ts.map +0 -1
  395. package/dist/goal/index.d.ts.map +0 -1
  396. package/dist/goal/index.js.map +0 -7
  397. package/dist/goal/phase-board-mutations.d.ts.map +0 -1
  398. package/dist/goal/phase-graph-builder.d.ts.map +0 -1
  399. package/dist/goal/phase-orchestrator-integration.d.ts.map +0 -1
  400. package/dist/goal/phase-orchestrator-queries.d.ts.map +0 -1
  401. package/dist/goal/phase-orchestrator-runtime.d.ts.map +0 -1
  402. package/dist/goal/phase-orchestrator-types.d.ts.map +0 -1
  403. package/dist/goal/phase-orchestrator.d.ts.map +0 -1
  404. package/dist/goal/phase-store.d.ts.map +0 -1
  405. package/dist/goal/types.d.ts.map +0 -1
  406. package/dist/hooks/http-executor.d.ts.map +0 -1
  407. package/dist/hooks/index.d.ts.map +0 -1
  408. package/dist/hooks/index.js.map +0 -7
  409. package/dist/hooks/registry.d.ts.map +0 -1
  410. package/dist/hooks/runner.d.ts.map +0 -1
  411. package/dist/hooks/shell-executor.d.ts.map +0 -1
  412. package/dist/hooks/shell-hooks-equal.d.ts.map +0 -1
  413. package/dist/hq/alerts.d.ts.map +0 -1
  414. package/dist/hq/auth-audit.d.ts.map +0 -1
  415. package/dist/hq/auth-store.d.ts.map +0 -1
  416. package/dist/hq/bootstrap-store.d.ts.map +0 -1
  417. package/dist/hq/brain-bridge.d.ts.map +0 -1
  418. package/dist/hq/bridge-context.d.ts.map +0 -1
  419. package/dist/hq/commands.d.ts.map +0 -1
  420. package/dist/hq/cost-bridge.d.ts.map +0 -1
  421. package/dist/hq/exposure.d.ts.map +0 -1
  422. package/dist/hq/factory.d.ts.map +0 -1
  423. package/dist/hq/fleet-bridge.d.ts.map +0 -1
  424. package/dist/hq/index.d.ts.map +0 -1
  425. package/dist/hq/index.js.map +0 -7
  426. package/dist/hq/kanban-store.d.ts.map +0 -1
  427. package/dist/hq/mailbox-mapper.d.ts.map +0 -1
  428. package/dist/hq/persistence/event-log.d.ts.map +0 -1
  429. package/dist/hq/persistence/jsonl-io.d.ts.map +0 -1
  430. package/dist/hq/persistence/simple-log.d.ts.map +0 -1
  431. package/dist/hq/persistence/snapshot-store.d.ts.map +0 -1
  432. package/dist/hq/persistence/timeseries-store.d.ts.map +0 -1
  433. package/dist/hq/persistence.d.ts.map +0 -1
  434. package/dist/hq/protocol/brain.d.ts.map +0 -1
  435. package/dist/hq/protocol/browser.d.ts.map +0 -1
  436. package/dist/hq/protocol/client.d.ts.map +0 -1
  437. package/dist/hq/protocol/core.d.ts.map +0 -1
  438. package/dist/hq/protocol/fleet.d.ts.map +0 -1
  439. package/dist/hq/protocol/kanban.d.ts.map +0 -1
  440. package/dist/hq/protocol/mailbox.d.ts.map +0 -1
  441. package/dist/hq/protocol/mcp.d.ts.map +0 -1
  442. package/dist/hq/protocol/peer.d.ts.map +0 -1
  443. package/dist/hq/protocol/project.d.ts.map +0 -1
  444. package/dist/hq/protocol/resume.d.ts.map +0 -1
  445. package/dist/hq/protocol/session.d.ts.map +0 -1
  446. package/dist/hq/protocol/tool.d.ts.map +0 -1
  447. package/dist/hq/protocol.d.ts.map +0 -1
  448. package/dist/hq/publisher.d.ts.map +0 -1
  449. package/dist/hq/redaction.d.ts.map +0 -1
  450. package/dist/hq/session-bridge.d.ts.map +0 -1
  451. package/dist/hq/tool-bridge.d.ts.map +0 -1
  452. package/dist/hq/transcript-mapper.d.ts.map +0 -1
  453. package/dist/hq/worktree-bridge.d.ts.map +0 -1
  454. package/dist/hq/write-queues.d.ts.map +0 -1
  455. package/dist/index.d.ts.map +0 -1
  456. package/dist/index.js.map +0 -7
  457. package/dist/infrastructure/context-manager.d.ts.map +0 -1
  458. package/dist/infrastructure/index.d.ts.map +0 -1
  459. package/dist/infrastructure/index.js.map +0 -7
  460. package/dist/infrastructure/logger.d.ts.map +0 -1
  461. package/dist/infrastructure/mcp-servers.d.ts.map +0 -1
  462. package/dist/infrastructure/path-resolver.d.ts.map +0 -1
  463. package/dist/infrastructure/provider-cache-ledger.d.ts.map +0 -1
  464. package/dist/infrastructure/token-counter.d.ts.map +0 -1
  465. package/dist/kernel/container.d.ts.map +0 -1
  466. package/dist/kernel/events/agent-events.d.ts.map +0 -1
  467. package/dist/kernel/events/brain-events.d.ts.map +0 -1
  468. package/dist/kernel/events/file-events.d.ts.map +0 -1
  469. package/dist/kernel/events/fleet-events.d.ts.map +0 -1
  470. package/dist/kernel/events/memory-events.d.ts.map +0 -1
  471. package/dist/kernel/events/network-events.d.ts.map +0 -1
  472. package/dist/kernel/events/process-events.d.ts.map +0 -1
  473. package/dist/kernel/events/provider-events.d.ts.map +0 -1
  474. package/dist/kernel/events/sdd-events.d.ts.map +0 -1
  475. package/dist/kernel/events/session-events.d.ts.map +0 -1
  476. package/dist/kernel/events/tool-events.d.ts.map +0 -1
  477. package/dist/kernel/events/worktree-events.d.ts.map +0 -1
  478. package/dist/kernel/events.d.ts.map +0 -1
  479. package/dist/kernel/index.d.ts.map +0 -1
  480. package/dist/kernel/index.js.map +0 -7
  481. package/dist/kernel/pipeline.d.ts.map +0 -1
  482. package/dist/kernel/run-controller.d.ts.map +0 -1
  483. package/dist/kernel/tokens.d.ts.map +0 -1
  484. package/dist/mailbox-attach.d.ts.map +0 -1
  485. package/dist/middleware/collab-pause.d.ts.map +0 -1
  486. package/dist/models/alibaba-token-plan-catalog.d.ts.map +0 -1
  487. package/dist/models/codex-catalog.d.ts.map +0 -1
  488. package/dist/models/index.d.ts.map +0 -1
  489. package/dist/models/index.js.map +0 -7
  490. package/dist/models/llm-selector.d.ts.map +0 -1
  491. package/dist/models/mode-store.d.ts.map +0 -1
  492. package/dist/models/model-intelligence.d.ts.map +0 -1
  493. package/dist/models/model-router.d.ts.map +0 -1
  494. package/dist/models/models-registry.d.ts.map +0 -1
  495. package/dist/models/provider-model-resolve.d.ts.map +0 -1
  496. package/dist/notifications/index.d.ts.map +0 -1
  497. package/dist/notifications/index.js.map +0 -7
  498. package/dist/notifications/notifier-impl.d.ts.map +0 -1
  499. package/dist/notifications/notifier.d.ts.map +0 -1
  500. package/dist/notifications/types.d.ts.map +0 -1
  501. package/dist/observability/event-bridge.d.ts.map +0 -1
  502. package/dist/observability/health.d.ts.map +0 -1
  503. package/dist/observability/index.d.ts.map +0 -1
  504. package/dist/observability/index.js.map +0 -7
  505. package/dist/observability/metrics.d.ts.map +0 -1
  506. package/dist/observability/network-telemetry.d.ts.map +0 -1
  507. package/dist/observability/otel-tracer.d.ts.map +0 -1
  508. package/dist/observability/otlp-metrics.d.ts.map +0 -1
  509. package/dist/observability/otlp-traces.d.ts.map +0 -1
  510. package/dist/observability/process-telemetry.d.ts.map +0 -1
  511. package/dist/observability/prometheus.d.ts.map +0 -1
  512. package/dist/observability/redact-command.d.ts.map +0 -1
  513. package/dist/observability/tracer.d.ts.map +0 -1
  514. package/dist/plugin/api.d.ts.map +0 -1
  515. package/dist/plugin/config.d.ts.map +0 -1
  516. package/dist/plugin/index.d.ts.map +0 -1
  517. package/dist/plugin/index.js.map +0 -7
  518. package/dist/plugin/loader.d.ts.map +0 -1
  519. package/dist/plugins/auto-review-plugin.d.ts.map +0 -1
  520. package/dist/plugins/chimera-plugin.d.ts.map +0 -1
  521. package/dist/plugins/prompts-plugin.d.ts.map +0 -1
  522. package/dist/plugins/review-claim-registry.d.ts.map +0 -1
  523. package/dist/plugins/review-context-builder.d.ts.map +0 -1
  524. package/dist/plugins/review-finding-commands.d.ts.map +0 -1
  525. package/dist/plugins/review-finding-integration.d.ts.map +0 -1
  526. package/dist/plugins/review-finding-parser.d.ts.map +0 -1
  527. package/dist/plugins/review-finding-store.d.ts.map +0 -1
  528. package/dist/plugins/review-finding-types.d.ts.map +0 -1
  529. package/dist/plugins/review-report-integration.d.ts.map +0 -1
  530. package/dist/plugins/review-report-store.d.ts.map +0 -1
  531. package/dist/plugins/review-report-types.d.ts.map +0 -1
  532. package/dist/plugins/review-types.d.ts.map +0 -1
  533. package/dist/plugins/skills-plugin.d.ts.map +0 -1
  534. package/dist/plugins/sync-plugin.d.ts.map +0 -1
  535. package/dist/prompts/index.d.ts.map +0 -1
  536. package/dist/prompts/prompt-installer.d.ts.map +0 -1
  537. package/dist/prompts/prompt-manifest-store.d.ts.map +0 -1
  538. package/dist/registry/index.d.ts.map +0 -1
  539. package/dist/registry/index.js.map +0 -7
  540. package/dist/registry/provider-registry.d.ts.map +0 -1
  541. package/dist/registry/slash-command-registry.d.ts.map +0 -1
  542. package/dist/registry/tool-registry.d.ts.map +0 -1
  543. package/dist/replay/hash.d.ts.map +0 -1
  544. package/dist/replay/index.d.ts.map +0 -1
  545. package/dist/replay/index.js.map +0 -7
  546. package/dist/replay/replay-provider-runner.d.ts.map +0 -1
  547. package/dist/security/capabilities.d.ts.map +0 -1
  548. package/dist/security/config-secrets.d.ts.map +0 -1
  549. package/dist/security/directory-permission-policy.d.ts.map +0 -1
  550. package/dist/security/directory-policy-schema.d.ts.map +0 -1
  551. package/dist/security/index.d.ts.map +0 -1
  552. package/dist/security/index.js.map +0 -7
  553. package/dist/security/kanban-boundary.d.ts.map +0 -1
  554. package/dist/security/permission-policy-schema.d.ts.map +0 -1
  555. package/dist/security/permission-policy.d.ts.map +0 -1
  556. package/dist/security/readonly-permission-policy.d.ts.map +0 -1
  557. package/dist/security/secret-scrubber.d.ts.map +0 -1
  558. package/dist/security/secret-vault.d.ts.map +0 -1
  559. package/dist/security/trust-boundary.d.ts.map +0 -1
  560. package/dist/security/yolo-risk.d.ts.map +0 -1
  561. package/dist/session-registry-atomic-file.d.ts.map +0 -1
  562. package/dist/session-registry-types.d.ts.map +0 -1
  563. package/dist/session-registry.d.ts.map +0 -1
  564. package/dist/skills/foreign-sources.d.ts.map +0 -1
  565. package/dist/skills/frontmatter.d.ts.map +0 -1
  566. package/dist/skills/github-fetcher.d.ts.map +0 -1
  567. package/dist/skills/index.d.ts.map +0 -1
  568. package/dist/skills/index.js.map +0 -7
  569. package/dist/skills/limits.d.ts.map +0 -1
  570. package/dist/skills/manifest-store.d.ts.map +0 -1
  571. package/dist/skills/registry/github-direct-adapter.d.ts.map +0 -1
  572. package/dist/skills/registry/registry-adapter.d.ts.map +0 -1
  573. package/dist/skills/registry/skills-sh-adapter.d.ts.map +0 -1
  574. package/dist/skills/skill-generator.d.ts.map +0 -1
  575. package/dist/skills/skill-installer.d.ts.map +0 -1
  576. package/dist/storage/annotations-store.d.ts.map +0 -1
  577. package/dist/storage/attachment-store.d.ts.map +0 -1
  578. package/dist/storage/cloud-sync.d.ts.map +0 -1
  579. package/dist/storage/completed-work-checkpoint.d.ts.map +0 -1
  580. package/dist/storage/config-loader/bootstrap.d.ts.map +0 -1
  581. package/dist/storage/config-loader/default-repair.d.ts.map +0 -1
  582. package/dist/storage/config-loader/defaults.d.ts.map +0 -1
  583. package/dist/storage/config-loader/diagnostics.d.ts.map +0 -1
  584. package/dist/storage/config-loader/env-overrides.d.ts.map +0 -1
  585. package/dist/storage/config-loader/in-project-policy.d.ts.map +0 -1
  586. package/dist/storage/config-loader/inline-provider-models.d.ts.map +0 -1
  587. package/dist/storage/config-loader/legacy-sage-migration.d.ts.map +0 -1
  588. package/dist/storage/config-loader/path-identity.d.ts.map +0 -1
  589. package/dist/storage/config-loader/types.d.ts.map +0 -1
  590. package/dist/storage/config-loader/validation.d.ts.map +0 -1
  591. package/dist/storage/config-loader.d.ts.map +0 -1
  592. package/dist/storage/config-migration.d.ts.map +0 -1
  593. package/dist/storage/config-store.d.ts.map +0 -1
  594. package/dist/storage/director-state.d.ts.map +0 -1
  595. package/dist/storage/file-session-writer.d.ts.map +0 -1
  596. package/dist/storage/goal-coordination.d.ts.map +0 -1
  597. package/dist/storage/goal-kanban.d.ts.map +0 -1
  598. package/dist/storage/goal-store.d.ts.map +0 -1
  599. package/dist/storage/index.d.ts.map +0 -1
  600. package/dist/storage/index.js.map +0 -7
  601. package/dist/storage/input-history-store.d.ts.map +0 -1
  602. package/dist/storage/memory-backend.d.ts.map +0 -1
  603. package/dist/storage/memory-consolidator.d.ts.map +0 -1
  604. package/dist/storage/memory-graph-backend.d.ts.map +0 -1
  605. package/dist/storage/plan-store.d.ts.map +0 -1
  606. package/dist/storage/plan-templates.d.ts.map +0 -1
  607. package/dist/storage/prompt-store.d.ts.map +0 -1
  608. package/dist/storage/prompt-usage-store.d.ts.map +0 -1
  609. package/dist/storage/provider-config-watcher.d.ts.map +0 -1
  610. package/dist/storage/queue-store.d.ts.map +0 -1
  611. package/dist/storage/recovery-lock.d.ts.map +0 -1
  612. package/dist/storage/replay-log-store.d.ts.map +0 -1
  613. package/dist/storage/session-analyzer.d.ts.map +0 -1
  614. package/dist/storage/session-checkpoint-cas.d.ts.map +0 -1
  615. package/dist/storage/session-event-bridge.d.ts.map +0 -1
  616. package/dist/storage/session-helpers.d.ts.map +0 -1
  617. package/dist/storage/session-id-resolver.d.ts.map +0 -1
  618. package/dist/storage/session-id.d.ts.map +0 -1
  619. package/dist/storage/session-read-scrubber.d.ts.map +0 -1
  620. package/dist/storage/session-reader.d.ts.map +0 -1
  621. package/dist/storage/session-recovery.d.ts.map +0 -1
  622. package/dist/storage/session-resume-validation.d.ts.map +0 -1
  623. package/dist/storage/session-rewind-apply.d.ts.map +0 -1
  624. package/dist/storage/session-rewinder.d.ts.map +0 -1
  625. package/dist/storage/session-store/delete-session-artifacts.d.ts.map +0 -1
  626. package/dist/storage/session-store/delete-session-guards.d.ts.map +0 -1
  627. package/dist/storage/session-store/directory-scan.d.ts.map +0 -1
  628. package/dist/storage/session-store/directory-session-files.d.ts.map +0 -1
  629. package/dist/storage/session-store/events.d.ts.map +0 -1
  630. package/dist/storage/session-store/fork-session.d.ts.map +0 -1
  631. package/dist/storage/session-store/index-reader.d.ts.map +0 -1
  632. package/dist/storage/session-store/load-cache.d.ts.map +0 -1
  633. package/dist/storage/session-store/load-session-data.d.ts.map +0 -1
  634. package/dist/storage/session-store/paths.d.ts.map +0 -1
  635. package/dist/storage/session-store/prune-helpers.d.ts.map +0 -1
  636. package/dist/storage/session-store/replay.d.ts.map +0 -1
  637. package/dist/storage/session-store/search-events.d.ts.map +0 -1
  638. package/dist/storage/session-store/shard-manifest.d.ts.map +0 -1
  639. package/dist/storage/session-store/summary-builder.d.ts.map +0 -1
  640. package/dist/storage/session-store/summary-header.d.ts.map +0 -1
  641. package/dist/storage/session-store/types.d.ts.map +0 -1
  642. package/dist/storage/session-store.d.ts.map +0 -1
  643. package/dist/storage/session-summary.d.ts.map +0 -1
  644. package/dist/storage/session-tool-call-ends.d.ts.map +0 -1
  645. package/dist/storage/session-writer-scrubber.d.ts.map +0 -1
  646. package/dist/storage/session-writer-truncate.d.ts.map +0 -1
  647. package/dist/storage/storage-concurrency.d.ts.map +0 -1
  648. package/dist/storage/task-store.d.ts.map +0 -1
  649. package/dist/storage/todos-checkpoint.d.ts.map +0 -1
  650. package/dist/storage/tool-audit-log.d.ts.map +0 -1
  651. package/dist/tasking/index.d.ts.map +0 -1
  652. package/dist/tasking/index.js.map +0 -7
  653. package/dist/tasking/task-store.d.ts.map +0 -1
  654. package/dist/tasking/task-tracker.d.ts.map +0 -1
  655. package/dist/tools/council-tool.d.ts.map +0 -1
  656. package/dist/tools/fallback-chain-manage-tool.d.ts.map +0 -1
  657. package/dist/tools/fallback-favorite-manage-tool.d.ts.map +0 -1
  658. package/dist/tools/fallback-manage-helpers.d.ts.map +0 -1
  659. package/dist/tools/fallback-manage-tool-options.d.ts.map +0 -1
  660. package/dist/tools/fallback-manage-tools.d.ts.map +0 -1
  661. package/dist/tools/fallback-model-ref-parse.d.ts.map +0 -1
  662. package/dist/tools/fallback-provider-key-store.d.ts.map +0 -1
  663. package/dist/tools/fallback-system-config-view-tool.d.ts.map +0 -1
  664. package/dist/tools/index.d.ts.map +0 -1
  665. package/dist/tools/index.js.map +0 -7
  666. package/dist/tools/mcp-control.d.ts.map +0 -1
  667. package/dist/tools/mcp-use.d.ts.map +0 -1
  668. package/dist/tools/one-shot-llm-tool.d.ts.map +0 -1
  669. package/dist/tools/plugin-manager.d.ts.map +0 -1
  670. package/dist/types/agent-bridge.d.ts.map +0 -1
  671. package/dist/types/attachment.d.ts.map +0 -1
  672. package/dist/types/autonomy.d.ts.map +0 -1
  673. package/dist/types/blocks.d.ts.map +0 -1
  674. package/dist/types/compactor.d.ts.map +0 -1
  675. package/dist/types/config/autonomy.d.ts.map +0 -1
  676. package/dist/types/config/context.d.ts.map +0 -1
  677. package/dist/types/config/fleet-chat.d.ts.map +0 -1
  678. package/dist/types/config/mcp-features.d.ts.map +0 -1
  679. package/dist/types/config/providers.d.ts.map +0 -1
  680. package/dist/types/config/root.d.ts.map +0 -1
  681. package/dist/types/config/runtime.d.ts.map +0 -1
  682. package/dist/types/config/skills-fleet-brain.d.ts.map +0 -1
  683. package/dist/types/config/tools.d.ts.map +0 -1
  684. package/dist/types/config.d.ts.map +0 -1
  685. package/dist/types/context-evidence.d.ts.map +0 -1
  686. package/dist/types/context-window.d.ts.map +0 -1
  687. package/dist/types/council.d.ts.map +0 -1
  688. package/dist/types/default-config.d.ts.map +0 -1
  689. package/dist/types/design-kit.d.ts.map +0 -1
  690. package/dist/types/error-handler.d.ts.map +0 -1
  691. package/dist/types/errors.d.ts.map +0 -1
  692. package/dist/types/file-event-record.d.ts.map +0 -1
  693. package/dist/types/hooks.d.ts.map +0 -1
  694. package/dist/types/index.d.ts.map +0 -1
  695. package/dist/types/index.js.map +0 -7
  696. package/dist/types/input-reader.d.ts.map +0 -1
  697. package/dist/types/logger.d.ts.map +0 -1
  698. package/dist/types/memory.d.ts.map +0 -1
  699. package/dist/types/messages.d.ts.map +0 -1
  700. package/dist/types/mode-prompts.d.ts.map +0 -1
  701. package/dist/types/mode.d.ts.map +0 -1
  702. package/dist/types/models-registry.d.ts.map +0 -1
  703. package/dist/types/multi-agent.d.ts.map +0 -1
  704. package/dist/types/observability.d.ts.map +0 -1
  705. package/dist/types/one-shot-llm.d.ts.map +0 -1
  706. package/dist/types/path-resolver.d.ts.map +0 -1
  707. package/dist/types/permission.d.ts.map +0 -1
  708. package/dist/types/plugin.d.ts.map +0 -1
  709. package/dist/types/prompt-registry.d.ts.map +0 -1
  710. package/dist/types/prompt.d.ts.map +0 -1
  711. package/dist/types/provider-runner.d.ts.map +0 -1
  712. package/dist/types/provider.d.ts.map +0 -1
  713. package/dist/types/quota-regex.d.ts.map +0 -1
  714. package/dist/types/renderer.d.ts.map +0 -1
  715. package/dist/types/retry-policy.d.ts.map +0 -1
  716. package/dist/types/secret-scrubber.d.ts.map +0 -1
  717. package/dist/types/secret-vault.d.ts.map +0 -1
  718. package/dist/types/selector.d.ts.map +0 -1
  719. package/dist/types/session-markers.d.ts.map +0 -1
  720. package/dist/types/session-markers.js.map +0 -7
  721. package/dist/types/session-reader.d.ts.map +0 -1
  722. package/dist/types/session-rewinder.d.ts.map +0 -1
  723. package/dist/types/session.d.ts.map +0 -1
  724. package/dist/types/side-effect.d.ts.map +0 -1
  725. package/dist/types/skill.d.ts.map +0 -1
  726. package/dist/types/slash-command.d.ts.map +0 -1
  727. package/dist/types/spec.d.ts.map +0 -1
  728. package/dist/types/system-prompt-contributor.d.ts.map +0 -1
  729. package/dist/types/system-prompt.d.ts.map +0 -1
  730. package/dist/types/task-graph.d.ts.map +0 -1
  731. package/dist/types/token-counter.d.ts.map +0 -1
  732. package/dist/types/tool-executor.d.ts.map +0 -1
  733. package/dist/types/tool-markers.d.ts.map +0 -1
  734. package/dist/types/tool.d.ts.map +0 -1
  735. package/dist/types/utility-types.d.ts.map +0 -1
  736. package/dist/utils/assert-never.d.ts.map +0 -1
  737. package/dist/utils/atomic-write.d.ts.map +0 -1
  738. package/dist/utils/cache-key.d.ts.map +0 -1
  739. package/dist/utils/child-env.d.ts.map +0 -1
  740. package/dist/utils/color.d.ts.map +0 -1
  741. package/dist/utils/compaction-preview.d.ts.map +0 -1
  742. package/dist/utils/config-backup.d.ts.map +0 -1
  743. package/dist/utils/config-json.d.ts.map +0 -1
  744. package/dist/utils/connectivity.d.ts.map +0 -1
  745. package/dist/utils/context-breakdown.d.ts.map +0 -1
  746. package/dist/utils/context-evidence.d.ts.map +0 -1
  747. package/dist/utils/continuous-memory-profiler.d.ts.map +0 -1
  748. package/dist/utils/crash-shield.d.ts.map +0 -1
  749. package/dist/utils/deep-merge.d.ts.map +0 -1
  750. package/dist/utils/diff.d.ts.map +0 -1
  751. package/dist/utils/error.d.ts.map +0 -1
  752. package/dist/utils/error.js.map +0 -7
  753. package/dist/utils/expect-defined.d.ts.map +0 -1
  754. package/dist/utils/expect-defined.js.map +0 -7
  755. package/dist/utils/glob-expand.d.ts.map +0 -1
  756. package/dist/utils/glob-match.d.ts.map +0 -1
  757. package/dist/utils/heap-watchdog-types.d.ts.map +0 -1
  758. package/dist/utils/heap-watchdog.d.ts.map +0 -1
  759. package/dist/utils/heap-watchdog.js.map +0 -7
  760. package/dist/utils/incoming-images.d.ts.map +0 -1
  761. package/dist/utils/index.d.ts.map +0 -1
  762. package/dist/utils/index.js.map +0 -7
  763. package/dist/utils/instruction-file.d.ts.map +0 -1
  764. package/dist/utils/ip-guard.d.ts.map +0 -1
  765. package/dist/utils/json-repair.d.ts.map +0 -1
  766. package/dist/utils/json-schema-validate.d.ts.map +0 -1
  767. package/dist/utils/lru-cache.d.ts.map +0 -1
  768. package/dist/utils/memory-flight-recorder.d.ts.map +0 -1
  769. package/dist/utils/merge-custom-models.d.ts.map +0 -1
  770. package/dist/utils/merge-models-payload.d.ts.map +0 -1
  771. package/dist/utils/message-invariants.d.ts.map +0 -1
  772. package/dist/utils/newline-normalize.d.ts.map +0 -1
  773. package/dist/utils/perf-profile.d.ts.map +0 -1
  774. package/dist/utils/pid.d.ts.map +0 -1
  775. package/dist/utils/project-identity.d.ts.map +0 -1
  776. package/dist/utils/project-watch.d.ts.map +0 -1
  777. package/dist/utils/regex-guard.d.ts.map +0 -1
  778. package/dist/utils/safe-json.d.ts.map +0 -1
  779. package/dist/utils/sage-output-block.d.ts.map +0 -1
  780. package/dist/utils/session-scoped-path.d.ts.map +0 -1
  781. package/dist/utils/sleep.d.ts.map +0 -1
  782. package/dist/utils/slug.d.ts.map +0 -1
  783. package/dist/utils/socket-path.d.ts.map +0 -1
  784. package/dist/utils/sqlite-warning.d.ts.map +0 -1
  785. package/dist/utils/string.d.ts.map +0 -1
  786. package/dist/utils/task-format.d.ts.map +0 -1
  787. package/dist/utils/term.d.ts.map +0 -1
  788. package/dist/utils/todos-format.d.ts.map +0 -1
  789. package/dist/utils/token-estimate.d.ts.map +0 -1
  790. package/dist/utils/tool-description-mode.d.ts.map +0 -1
  791. package/dist/utils/tool-name.d.ts.map +0 -1
  792. package/dist/utils/tool-output-serializer.d.ts.map +0 -1
  793. package/dist/utils/tool-result-render-mode.d.ts.map +0 -1
  794. package/dist/utils/tool-subject.d.ts.map +0 -1
  795. package/dist/utils/tool-wire-compact.d.ts.map +0 -1
  796. package/dist/utils/tree-kill.d.ts.map +0 -1
  797. package/dist/utils/tree-kill.js.map +0 -7
  798. package/dist/utils/ulid.d.ts.map +0 -1
  799. package/dist/utils/walk-ignore.d.ts.map +0 -1
  800. package/dist/utils/wstack-paths.d.ts.map +0 -1
  801. package/dist/worktree/index.d.ts.map +0 -1
  802. package/dist/worktree/index.js.map +0 -7
  803. package/dist/worktree/worktree-git.d.ts.map +0 -1
  804. package/dist/worktree/worktree-managed-ops.d.ts.map +0 -1
  805. package/dist/worktree/worktree-manager.d.ts.map +0 -1
  806. package/dist/worktree/worktree-types.d.ts.map +0 -1
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../src/utils/assert-never.ts", "../../src/utils/atomic-write.ts", "../../src/utils/error.ts", "../../src/types/errors.ts", "../../src/utils/child-env.ts", "../../src/utils/term.ts", "../../src/utils/color.ts", "../../src/utils/config-backup.ts", "../../src/utils/connectivity.ts", "../../src/utils/cache-key.ts", "../../src/utils/config-json.ts", "../../src/utils/context-evidence.ts", "../../src/utils/expect-defined.ts", "../../src/utils/message-invariants.ts", "../../src/utils/tool-wire-compact.ts", "../../src/utils/token-estimate.ts", "../../src/core/agent-response.ts", "../../src/core/system-prompt-blocks.ts", "../../src/utils/context-breakdown.ts", "../../src/utils/deep-merge.ts", "../../src/utils/diff.ts", "../../src/utils/glob-expand.ts", "../../src/utils/glob-match.ts", "../../src/utils/incoming-images.ts", "../../src/utils/ip-guard.ts", "../../src/utils/instruction-file.ts", "../../src/utils/json-repair.ts", "../../src/utils/json-schema-validate.ts", "../../src/utils/merge-custom-models.ts", "../../src/utils/merge-models-payload.ts", "../../src/utils/newline-normalize.ts", "../../src/utils/perf-profile.ts", "../../src/utils/pid.ts", "../../src/utils/project-identity.ts", "../../src/utils/ulid.ts", "../../src/utils/regex-guard.ts", "../../src/utils/safe-json.ts", "../../src/utils/session-scoped-path.ts", "../../src/utils/socket-path.ts", "../../src/utils/sqlite-warning.ts", "../../src/utils/sleep.ts", "../../src/utils/slug.ts", "../../src/utils/string.ts", "../../src/utils/task-format.ts", "../../src/utils/todos-format.ts", "../../src/utils/tool-description-mode.ts", "../../src/utils/tool-output-serializer.ts", "../../src/utils/tool-result-render-mode.ts", "../../src/utils/tool-subject.ts", "../../src/utils/tool-name.ts", "../../src/utils/project-watch.ts", "../../src/utils/walk-ignore.ts", "../../src/utils/wstack-paths.ts", "../../src/utils/heap-watchdog.ts", "../../src/utils/memory-flight-recorder.ts", "../../src/utils/continuous-memory-profiler.ts"],
4
- "sourcesContent": ["/**\n * Exhaustiveness check for discriminated union switches.\n * Place in the `default` branch of a switch over a union type\n * to get a compile-time error when a new variant is added.\n *\n * @example\n * switch (block.type) {\n * case 'text': return renderText(block);\n * case 'tool_use': return renderToolUse(block);\n * default: return assertNever(block);\n * }\n */\nexport function assertNever(x: never, message?: string): never {\n const err = new Error(\n message ?? `Unhandled case: ${JSON.stringify(x)}`,\n );\n err.name = 'AssertNeverError';\n throw err;\n}\n", "import type { FileHandle } from 'node:fs/promises';\nimport {\n type AtomicWriteOptions,\n createPersistencePrimitives,\n type FileLockOptions,\n} from '@wrongstack/persistence';\nimport { FsError } from '../types/errors.js';\n\nexport type { AtomicWriteOptions, FileLockOptions } from '@wrongstack/persistence';\n\nconst primitives = createPersistencePrimitives({\n createLockTimeoutError: ({ targetPath, timeoutMs }) =>\n new FsError({\n message: `Timed out waiting for file lock: ${targetPath}`,\n code: 'FS_ATOMIC_WRITE_FAILED',\n path: targetPath,\n context: { timeoutMs },\n }),\n});\n\nexport const atomicWrite: (\n targetPath: string,\n content: string | Uint8Array,\n opts?: AtomicWriteOptions,\n) => Promise<void> = primitives.atomicWrite;\n/**\n * Atomic replace that streams its new contents instead of taking them as one\n * buffer. Use when the replacement is large enough that materializing it would\n * itself be the memory problem (log rotation, tail compaction).\n */\nexport const atomicReplaceWithWriter: <T>(\n targetPath: string,\n write: (handle: FileHandle) => Promise<T>,\n opts?: AtomicWriteOptions,\n) => Promise<T> = primitives.atomicReplaceWithWriter;\nexport const ensureDir: (dir: string) => Promise<void> = primitives.ensureDir;\nexport const withFileLock: <T>(\n targetPath: string,\n fn: () => Promise<T>,\n opts?: FileLockOptions,\n) => Promise<T> = primitives.withFileLock;\n", "/**\n * Converts an unknown error value to a human-readable string.\n * Used in 40+ files across the codebase to normalize error messaging.\n */\nexport function toErrorMessage(err: unknown): string {\n return err instanceof Error ? err.message : String(err);\n}\n", "import { toErrorMessage } from '../utils/error.js';\n\n/**\n * WrongStack error hierarchy.\n *\n * Every error thrown by the framework is a `WrongStackError` with a\n * machine-readable `code`, a `subsystem` tag, and a `severity` level.\n * This lets consumers (CLI, TUI, plugins, tests) branch on structured\n * data instead of parsing error messages.\n */\n\n// \u2500\u2500 Error codes \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Machine-readable error codes as frozen constants.\n *\n * Use `ERROR_CODES.X` instead of raw string literals for:\n * - IDE autocomplete and compile-time validation\n * - Safe refactoring (rename updates all usages)\n * - Plugin extensibility (extend the object to add custom codes)\n *\n * The `ErrorCode` type is derived from this object, so adding a new\n * code here automatically updates the type without extra changes.\n */\nexport const ERROR_CODES = {\n // Provider\n PROVIDER_RATE_LIMITED: 'PROVIDER_RATE_LIMITED',\n PROVIDER_AUTH_FAILED: 'PROVIDER_AUTH_FAILED',\n PROVIDER_OVERLOADED: 'PROVIDER_OVERLOADED',\n PROVIDER_INVALID_REQUEST: 'PROVIDER_INVALID_REQUEST',\n PROVIDER_SERVER_ERROR: 'PROVIDER_SERVER_ERROR',\n PROVIDER_NETWORK_ERROR: 'PROVIDER_NETWORK_ERROR',\n PROVIDER_CONTEXT_OVERFLOW: 'PROVIDER_CONTEXT_OVERFLOW',\n // Tool\n TOOL_NOT_FOUND: 'TOOL_NOT_FOUND',\n TOOL_PERMISSION_DENIED: 'TOOL_PERMISSION_DENIED',\n TOOL_EXECUTION_FAILED: 'TOOL_EXECUTION_FAILED',\n TOOL_TIMEOUT: 'TOOL_TIMEOUT',\n TOOL_INPUT_INVALID: 'TOOL_INPUT_INVALID',\n // Config\n CONFIG_INVALID: 'CONFIG_INVALID',\n CONFIG_NOT_FOUND: 'CONFIG_NOT_FOUND',\n CONFIG_PARSE_FAILED: 'CONFIG_PARSE_FAILED',\n CONFIG_MIGRATION_NEEDED: 'CONFIG_MIGRATION_NEEDED',\n // Plugin\n PLUGIN_LOAD_FAILED: 'PLUGIN_LOAD_FAILED',\n PLUGIN_API_MISMATCH: 'PLUGIN_API_MISMATCH',\n PLUGIN_MISSING_DEPENDENCY: 'PLUGIN_MISSING_DEPENDENCY',\n // Agent\n AGENT_ITERATION_LIMIT: 'AGENT_ITERATION_LIMIT',\n AGENT_CONTEXT_OVERFLOW: 'AGENT_CONTEXT_OVERFLOW',\n AGENT_ABORTED: 'AGENT_ABORTED',\n AGENT_RUN_FAILED: 'AGENT_RUN_FAILED',\n // Session\n SESSION_NOT_FOUND: 'SESSION_NOT_FOUND',\n SESSION_CORRUPTED: 'SESSION_CORRUPTED',\n SESSION_WRITE_FAILED: 'SESSION_WRITE_FAILED',\n // Container / Registry\n CONTAINER_TOKEN_ALREADY_BOUND: 'CONTAINER_TOKEN_ALREADY_BOUND',\n CONTAINER_TOKEN_NOT_BOUND: 'CONTAINER_TOKEN_NOT_BOUND',\n CONTAINER_CIRCULAR_DEPENDENCY: 'CONTAINER_CIRCULAR_DEPENDENCY',\n REGISTRY_DUPLICATE: 'REGISTRY_DUPLICATE',\n REGISTRY_NOT_FOUND: 'REGISTRY_NOT_FOUND',\n REGISTRY_INVALID: 'REGISTRY_INVALID',\n // File system\n FS_READ_FAILED: 'FS_READ_FAILED',\n FS_WRITE_FAILED: 'FS_WRITE_FAILED',\n FS_MKDIR_FAILED: 'FS_MKDIR_FAILED',\n FS_DELETE_FAILED: 'FS_DELETE_FAILED',\n FS_ATOMIC_WRITE_FAILED: 'FS_ATOMIC_WRITE_FAILED',\n // SDD (Spec-Driven Development)\n SDD_VALIDATION_FAILED: 'SDD_VALIDATION_FAILED',\n SDD_PARSE_FAILED: 'SDD_PARSE_FAILED',\n SDD_INVALID_STATE: 'SDD_INVALID_STATE',\n SDD_NOT_READY: 'SDD_NOT_READY',\n // General\n VALIDATION_ERROR: 'VALIDATION_ERROR',\n PARSE_FAILED: 'PARSE_FAILED',\n UNKNOWN: 'UNKNOWN',\n} as const;\n\n/**\n * Union type derived from `ERROR_CODES`. Using `typeof ERROR_CODES[keyof typeof ERROR_CODES]`\n * instead of a string literal union means TypeScript auto-updates the type whenever\n * a new code is added to `ERROR_CODES` \u2014 no need to keep two lists in sync.\n */\nexport type ErrorCode = (typeof ERROR_CODES)[keyof typeof ERROR_CODES];\n\nexport type ErrorSubsystem =\n | 'provider'\n | 'tool'\n | 'config'\n | 'plugin'\n | 'agent'\n | 'session'\n | 'sdd'\n | 'container'\n | 'fs'\n | 'general';\nexport type ErrorSeverity = 'fatal' | 'error' | 'warning';\n\n// \u2500\u2500 Base error class \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport class WrongStackError extends Error {\n readonly code: ErrorCode;\n readonly subsystem: ErrorSubsystem;\n readonly severity: ErrorSeverity;\n readonly recoverable: boolean;\n readonly context?: Record<string, unknown> | undefined;\n\n constructor(opts: {\n message: string;\n code: ErrorCode;\n subsystem: ErrorSubsystem;\n severity?: ErrorSeverity | undefined;\n recoverable?: boolean | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super(opts.message, { cause: opts.cause });\n this.name = 'WrongStackError';\n this.code = opts.code;\n this.subsystem = opts.subsystem;\n this.severity = opts.severity ?? 'error';\n this.recoverable = opts.recoverable ?? false;\n this.context = opts.context;\n }\n\n /**\n * Render a one-line user-facing description.\n * Subclasses should override for domain-specific formatting.\n */\n describe(): string {\n const ctx = this.context ? ` ${formatContext(this.context)}` : '';\n return `${this.code}: ${this.message}${ctx}`;\n }\n}\n\nfunction formatContext(ctx: Record<string, unknown>): string {\n const parts = Object.entries(ctx)\n .filter(([, v]) => v !== undefined)\n .slice(0, 3)\n .map(([k, v]) => `${k}=${String(v)}`);\n return parts.length > 0 ? `[${parts.join(' ')}]` : '';\n}\n\n// \u2500\u2500 Specific error classes \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Tool execution errors \u2014 thrown by ToolExecutor and individual tools.\n */\nexport class ToolError extends WrongStackError {\n readonly toolName: string;\n\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n | 'TOOL_NOT_FOUND'\n | 'TOOL_PERMISSION_DENIED'\n | 'TOOL_EXECUTION_FAILED'\n | 'TOOL_TIMEOUT'\n | 'TOOL_INPUT_INVALID'\n >;\n toolName: string;\n recoverable?: boolean | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'tool',\n recoverable: opts.recoverable,\n context: { tool: opts.toolName, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'ToolError';\n this.toolName = opts.toolName;\n }\n}\n\n/**\n * Config loading / validation errors.\n */\nexport class ConfigError extends WrongStackError {\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'CONFIG_INVALID' | 'CONFIG_NOT_FOUND' | 'CONFIG_PARSE_FAILED' | 'CONFIG_MIGRATION_NEEDED'\n >;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'config',\n severity: 'fatal',\n recoverable: false,\n context: opts.context,\n cause: opts.cause,\n });\n this.name = 'ConfigError';\n }\n}\n\n/**\n * Plugin loading / lifecycle errors.\n */\nexport class PluginError extends WrongStackError {\n readonly pluginName: string;\n\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'PLUGIN_LOAD_FAILED' | 'PLUGIN_API_MISMATCH' | 'PLUGIN_MISSING_DEPENDENCY'\n >;\n pluginName: string;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'plugin',\n severity: 'error',\n recoverable: opts.code === ERROR_CODES.PLUGIN_MISSING_DEPENDENCY,\n context: { plugin: opts.pluginName, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'PluginError';\n this.pluginName = opts.pluginName;\n }\n}\n\n/**\n * Agent runtime errors \u2014 thrown by Agent.run when a non-WrongStackError\n * escapes the inner loop, so callers always see a structured error.\n */\nexport class AgentError extends WrongStackError {\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'AGENT_ITERATION_LIMIT' | 'AGENT_CONTEXT_OVERFLOW' | 'AGENT_ABORTED' | 'AGENT_RUN_FAILED'\n >;\n recoverable?: boolean | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'agent',\n severity: opts.code === ERROR_CODES.AGENT_ABORTED ? 'warning' : 'error',\n recoverable: opts.recoverable ?? opts.code === ERROR_CODES.AGENT_ITERATION_LIMIT,\n context: opts.context,\n cause: opts.cause,\n });\n this.name = 'AgentError';\n }\n}\n\n/**\n * Wrap an arbitrary thrown value into a `WrongStackError` so the caller\n * always gets a structured error. Pass-throughs WrongStackError instances\n * unchanged; raw `Error`s and primitives get an `AGENT_RUN_FAILED` wrapper\n * with the original preserved as `cause`.\n */\nexport function toWrongStackError(\n err: unknown,\n code: Extract<ErrorCode, 'AGENT_RUN_FAILED' | 'AGENT_ABORTED' | 'UNKNOWN'> = ERROR_CODES.AGENT_RUN_FAILED,\n): WrongStackError {\n if (err instanceof WrongStackError) return err;\n const message = toErrorMessage(err);\n return new AgentError({\n message,\n code: code === 'UNKNOWN' ? ERROR_CODES.AGENT_RUN_FAILED : code,\n cause: err,\n });\n}\n\n/**\n * Session storage errors.\n */\nexport class SessionError extends WrongStackError {\n readonly sessionId?: string | undefined;\n\n constructor(opts: {\n message: string;\n code: Extract<ErrorCode, 'SESSION_NOT_FOUND' | 'SESSION_CORRUPTED' | 'SESSION_WRITE_FAILED'>;\n sessionId?: string | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'session',\n severity: opts.code === ERROR_CODES.SESSION_WRITE_FAILED ? 'error' : 'warning',\n recoverable: opts.code !== ERROR_CODES.SESSION_CORRUPTED,\n context: { sessionId: opts.sessionId, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'SessionError';\n this.sessionId = opts.sessionId;\n }\n}\n\n/**\n * SDD (Spec-Driven Development) errors \u2014 spec validation, parsing, and\n * state machine violations in the AISpecBuilder, TaskFlow, and TaskTracker.\n */\nexport class SddError extends WrongStackError {\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'SDD_VALIDATION_FAILED' | 'SDD_PARSE_FAILED' | 'SDD_INVALID_STATE' | 'SDD_NOT_READY'\n >;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'sdd',\n severity: opts.code === ERROR_CODES.SDD_PARSE_FAILED ? 'warning' : 'error',\n recoverable: opts.code === ERROR_CODES.SDD_NOT_READY,\n context: opts.context,\n cause: opts.cause,\n });\n this.name = 'SddError';\n }\n}\n\n/**\n * File system operation errors.\n */\nexport class FsError extends WrongStackError {\n readonly path?: string | undefined;\n\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'FS_READ_FAILED' | 'FS_WRITE_FAILED' | 'FS_MKDIR_FAILED' | 'FS_DELETE_FAILED' | 'FS_ATOMIC_WRITE_FAILED'\n >;\n path?: string | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'fs',\n severity: 'error',\n recoverable: opts.code !== ERROR_CODES.FS_READ_FAILED,\n context: { path: opts.path, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'FsError';\n this.path = opts.path;\n }\n}\n\n/**\n * HTTP fetch error \u2014 thrown when a network request returns a non-OK status.\n * Carries the response status so {@link classifyToolError} can branch on it\n * (429 \u2192 transient, 404 \u2192 not_found, 401 \u2192 permission) without duck-typing\n * the error via `'response' in err`.\n *\n * P3 #18 (before-release.md): the previous `'response' in err` check caught\n * any Error with a `response` property, including custom errors, proxy\n * objects, or mocked errors in tests. `instanceof FetchError` is reliable.\n *\n * Tools and providers that make HTTP requests and need the executor to\n * classify their failures should throw `new FetchError({ status, message })`\n * instead of a bare `Error` with an ad-hoc `response` field.\n */\nexport class FetchError extends WrongStackError {\n readonly status: number;\n\n constructor(opts: {\n message: string;\n status: number;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: ERROR_CODES.VALIDATION_ERROR,\n subsystem: 'general',\n severity: 'error',\n recoverable: opts.status === 429 || opts.status >= 500,\n context: { status: opts.status, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'FetchError';\n this.status = opts.status;\n }\n}\n\n/**\n * Tool input validation error \u2014 thrown when a tool's input fails a validation\n * check that the JSON Schema cannot express (e.g. `old_string === new_string`\n * in edit, or a cross-field invariant). Use this instead of a bare\n * `throw new Error('...validation...')` so {@link classifyToolError} can\n * match on `instanceof` rather than a locale-dependent message substring.\n *\n * P2 #6 (before-release.md): the previous `err.message.includes('validation')`\n * check misclassified any error whose message happened to contain \"validation\"\n * (e.g. a third-party \"input validation timeout\") as a VALIDATION error.\n *\n * Named `ToolValidationError` (not `ValidationError`) to avoid colliding with\n * the existing `ValidationError` interface exported by json-schema-validate.ts\n * (a validation-result shape, not an Error subclass).\n */\nexport class ToolValidationError extends WrongStackError {\n constructor(opts: {\n message: string;\n /** Field path or tool name that failed validation, for diagnostics. */\n field?: string | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: ERROR_CODES.VALIDATION_ERROR,\n subsystem: 'general',\n severity: 'error',\n recoverable: false,\n context: { field: opts.field, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'ToolValidationError';\n }\n}\n\n/**\n * Response / payload parse error \u2014 thrown when an upstream HTTP response,\n * file, or data structure is well-formed at the transport layer (HTTP 200,\n * valid JSON) but is missing required fields or has an unexpected shape.\n *\n * Distinct from `ConfigError(CONFIG_PARSE_FAILED)` (which is specifically\n * for config-file parsing) and `FetchError` (which covers HTTP non-OK\n * responses). `ParseError` fills the gap: the request succeeded but the\n * response body couldn't be interpreted.\n *\n * Common sites: OAuth token responses missing `access_token`, device-code\n * responses missing `device_code`, registry responses with unexpected\n * schemas.\n */\nexport class ParseError extends WrongStackError {\n readonly source?: string | undefined;\n\n constructor(opts: {\n message: string;\n /**\n * What was being parsed \u2014 e.g. `'oauth-token-response'`,\n * `'device-code-response'`. Lets consumers distinguish parse failures\n * from different upstream APIs without parsing the message.\n */\n source?: string | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: ERROR_CODES.PARSE_FAILED,\n subsystem: 'general',\n severity: 'error',\n recoverable: false,\n context: { source: opts.source, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'ParseError';\n this.source = opts.source;\n }\n}\n\n// \u2500\u2500 Type guards \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport function isWrongStackError(err: unknown): err is WrongStackError {\n return err instanceof WrongStackError;\n}\n\nexport function isToolError(err: unknown): err is ToolError {\n return err instanceof ToolError;\n}\n\nexport function isConfigError(err: unknown): err is ConfigError {\n return err instanceof ConfigError;\n}\n\nexport function isPluginError(err: unknown): err is PluginError {\n return err instanceof PluginError;\n}\n\nexport function isSessionError(err: unknown): err is SessionError {\n return err instanceof SessionError;\n}\n\nexport function isAgentError(err: unknown): err is AgentError {\n return err instanceof AgentError;\n}\n\nexport function isFsError(err: unknown): err is FsError {\n return err instanceof FsError;\n}\n\nexport function isToolValidationError(err: unknown): err is ToolValidationError {\n return err instanceof ToolValidationError;\n}\n\nexport function isFetchError(err: unknown): err is FetchError {\n return err instanceof FetchError;\n}\n\nexport function isParseError(err: unknown): err is ParseError {\n return err instanceof ParseError;\n}\n\nexport function isSddError(err: unknown): err is SddError {\n return err instanceof SddError;\n}\n", "/**\n * Build a sanitized child-process environment.\n *\n * The bash/exec tools and MCP stdio transports execute LLM-generated or\n * configured commands. The parent process carries provider API keys\n * (ANTHROPIC_API_KEY, OPENAI_API_KEY, ...), VCS tokens (GITHUB_TOKEN),\n * and cloud credentials. Forwarding those to a child is an exfiltration\n * vector even with `permission: 'confirm'` \u2014 a compromised MCP server\n * or a cleverly composed shell pipeline can leak secrets.\n *\n * Strategy: copy a small, explicit allowlist of variables that real builds\n * need, then copy anything else that does NOT look secret-bearing. This\n * preserves user-friendly behavior (locale, terminal, npm config) while\n * blocking the obvious leak channels. Two value-side guards back up the\n * name-based filter:\n * - any value carrying an embedded URI credential (`scheme://user:pass@host`,\n * e.g. `DATABASE_URL`/`REDIS_URL`/`*_DSN`) is dropped (WS-01);\n * - `NODE_OPTIONS` is forwarded but with module-preload directives\n * (`--require`/`--import`/`--loader`) stripped so a parent-set value can't\n * inject code into node children (WS-02).\n *\n * Override with `WRONGSTACK_CHILD_ENV_PASSTHROUGH=1` to forward the full\n * parent environment unchanged (opt-in for advanced users who understand\n * the risk).\n */\n\nconst ALLOWED_KEYS = new Set<string>([\n 'PATH',\n 'HOME',\n 'USER',\n 'USERNAME',\n 'LOGNAME',\n 'SHELL',\n 'LANG',\n 'LC_ALL',\n 'LC_CTYPE',\n 'TERM',\n 'TZ',\n 'TMPDIR',\n 'TEMP',\n 'TMP',\n 'PWD',\n 'OLDPWD',\n 'COMSPEC',\n 'SYSTEMROOT',\n 'SYSTEMDRIVE',\n 'WINDIR',\n 'PROGRAMFILES',\n 'PROGRAMFILES(X86)',\n 'PROGRAMDATA',\n 'APPDATA',\n 'LOCALAPPDATA',\n 'USERPROFILE',\n 'PUBLIC',\n 'PATHEXT',\n]);\n\n// Substring match against env-var names (case-insensitive). Bias toward\n// false-positives \u2014 a missing var is recoverable, an exfiltrated key is not.\n// Only consulted for vars NOT on the curated allowlist; PWD/PASSWD-style\n// false positives there are avoided by checking allowlist first.\nconst SECRET_NAME_PARTS = [\n 'TOKEN',\n 'SECRET',\n 'PASSWORD',\n 'PASSWD',\n 'AUTH',\n 'CRED',\n 'BEARER',\n 'COOKIE',\n 'PRIVATE',\n];\n\nfunction looksSecret(name: string): boolean {\n const upper = name.toUpperCase();\n for (const p of SECRET_NAME_PARTS) {\n if (upper.includes(p)) return true;\n }\n // KEY is tricky \u2014 PUBLIC_KEY is fine to forward but most _KEY vars are\n // secrets. Require word boundary so KEYBOARD_LAYOUT etc. are not flagged.\n if (/(?:^|_)KEY(?:$|_|S$)/i.test(upper)) return true;\n if (/API[_-]?KEY/i.test(upper)) return true;\n if (/ACCESS[_-]?KEY/i.test(upper)) return true;\n if (/SESSION[_-]?ID/i.test(upper) === false && /SESSION/i.test(upper)) {\n // SESSION_ID is metadata (we set our own); other SESSION_* often holds\n // session cookies. Be conservative.\n return true;\n }\n return false;\n}\n\n/**\n * Value-side secret detection (WS-01). The name-based `looksSecret` filter\n * misses connection-string variables whose NAME is innocuous but whose VALUE\n * embeds a password \u2014 e.g. `DATABASE_URL=postgres://user:pass@host`,\n * `REDIS_URL=redis://:pass@host`, `MONGO_URI`, `AMQP_URL`, `*_DSN`. Forwarding\n * these to a child (bash/exec/MCP server) leaks the embedded credential.\n *\n * Matches a URI userinfo component that contains a password, i.e.\n * `scheme://[user]:<password>@host`. Deliberately precise: a credential-free\n * URL (`https://api.example.com`, `https://user@host` with no password) is NOT\n * matched, so non-secret `*_URL` knobs (registries, endpoints) still forward.\n */\nfunction valueHasEmbeddedCredential(value: string): boolean {\n // scheme:// then optional user, a ':' , a non-empty password, then '@'.\n // Userinfo chars stop at '/', whitespace, ':' (separator) and '@'.\n return /\\b[a-z][a-z0-9+.-]*:\\/\\/[^/\\s:@]*:[^/\\s@]+@/i.test(value);\n}\n\n/**\n * Code-injection directives that turn `NODE_OPTIONS` into an RCE channel by\n * preloading an arbitrary module into every node child process (WS-02).\n */\nconst NODE_OPTIONS_INJECTION_FLAG =\n /^(?:--require|-r|--import|--loader|--experimental-loader)$/;\nconst NODE_OPTIONS_INJECTION_FLAG_EQ =\n /^(?:--require|-r|--import|--loader|--experimental-loader)=/;\n\n/**\n * Strip module-preload directives from a `NODE_OPTIONS` value while preserving\n * benign flags (`--no-warnings`, `--max-old-space-size=\u2026`, etc.). Handles both\n * the `--require=./x.js` and space-separated `--require ./x.js` forms. Returns\n * the sanitized string (possibly empty).\n */\nexport function sanitizeNodeOptions(value: string): string {\n const tokens = value.split(/\\s+/).filter(Boolean);\n const kept: string[] = [];\n for (let i = 0; i < tokens.length; i++) {\n const tok = tokens[i] as string;\n if (NODE_OPTIONS_INJECTION_FLAG_EQ.test(tok)) continue; // --require=./x\n if (NODE_OPTIONS_INJECTION_FLAG.test(tok)) {\n i++; // also drop the following path token (--require ./x)\n continue;\n }\n kept.push(tok);\n }\n return kept.join(' ');\n}\n\nexport interface BuildChildEnvOptions {\n /** Session ID to inject as WRONGSTACK_SESSION_ID. */\n sessionId?: string | undefined;\n /** Additional env vars to merge (takes priority over filtered parent env). */\n extra?: NodeJS.ProcessEnv | undefined;\n}\n\n/**\n * Commit identity applied to every git-touching child process via the\n * `GIT_AUTHOR_*` / `GIT_COMMITTER_*` env vars. Env-var identity outranks\n * every `git config` layer (repo/global/system), so commits made by any\n * tool (git tool, bash/exec, worktree manager, plugins) carry this\n * name/email without touching the user's git config \u2014 hand-made commits\n * in a normal terminal are unaffected.\n */\nexport interface GitIdentity {\n name?: string | undefined;\n email?: string | undefined;\n}\n\nlet gitIdentity: GitIdentity | null = null;\n\n/**\n * Set (or clear with `null`) the git commit identity injected by\n * `buildChildEnv()`. Wired at boot from the user-level `config.git.identity`\n * (the config loader strips `git` from repo-committed in-project configs \u2014\n * identity spoofing must not be repo-controllable) and re-applied at runtime\n * by the `/gitid` slash command.\n */\nexport function configureChildEnvGitIdentity(identity: GitIdentity | null | undefined): void {\n const name = identity?.name?.trim();\n const email = identity?.email?.trim();\n gitIdentity = name || email ? { name: name || undefined, email: email || undefined } : null;\n}\n\n/** Current configured git identity, or null when none is set. */\nexport function getChildEnvGitIdentity(): Readonly<GitIdentity> | null {\n return gitIdentity;\n}\n\n/**\n * Build a filtered child-process environment suitable for bash, exec, and\n * MCP server subprocesses. Strips API keys, tokens, and other credentials\n * while preserving system/tooling variables.\n */\nexport function buildChildEnv(optsOrSessionId?: BuildChildEnvOptions | string): NodeJS.ProcessEnv {\n const opts: BuildChildEnvOptions =\n typeof optsOrSessionId === 'string'\n ? { sessionId: optsOrSessionId }\n : (optsOrSessionId ?? {});\n\n // WRONGSTACK_CHILD_ENV_PASSTHROUGH may NOT be set via config file.\n // It is a privileged override that opt-outs the entire credential filter\n // and must only be set by the operator's shell environment (real env var,\n // not something a config file injects into process.env). Config-file\n // sources do NOT go through process.env \u2014 only the actual shell environment\n // does \u2014 so checking Object.prototype.hasOwnProperty.call(process.env, ...)\n // is sufficient to exclude config-driven values.\n const hasOwn = Object.hasOwn(process.env, 'WRONGSTACK_CHILD_ENV_PASSTHROUGH');\n const legacyHasOwn = Object.hasOwn(process.env, 'WRONGSTACK_BASH_ENV_PASSTHROUGH');\n const passthrough = (hasOwn && process.env['WRONGSTACK_CHILD_ENV_PASSTHROUGH'] === '1')\n || (legacyHasOwn && process.env['WRONGSTACK_BASH_ENV_PASSTHROUGH'] === '1');\n if (passthrough && !process.env['CI']) {\n console.warn(\n '[agent] WARNING: WRONGSTACK_*_ENV_PASSTHROUGH=1 is active \u2014\\n' +\n ' all parent env vars (including API keys) forwarded to child processes.\\n' +\n ' Do not use on shared or multi-tenant systems.'\n );\n }\n const out: NodeJS.ProcessEnv = {};\n\n // The CLI entry defaults NODE_ENV=production (so React/Ink resolve their\n // production builds \u2014 see cli-main) and marks the injection with this\n // flag. The injected value must NOT reach children: NODE_ENV=production\n // makes `pnpm install` skip devDependencies and flips test-runner\n // behavior. Strip both vars whenever the flag says wrongstack set them \u2014\n // a NODE_ENV genuinely exported by the operator's shell (flag absent)\n // is forwarded unchanged. Applies in passthrough mode too: passthrough\n // means \"the operator's real environment\", which this value is not.\n const nodeEnvDefaulted = process.env['WRONGSTACK_NODE_ENV_DEFAULTED'] === '1';\n\n for (const [k, v] of Object.entries(process.env)) {\n if (v === undefined) continue;\n if (nodeEnvDefaulted && (k === 'NODE_ENV' || k === 'WRONGSTACK_NODE_ENV_DEFAULTED')) continue;\n if (passthrough) {\n out[k] = v;\n continue;\n }\n const upper = k.toUpperCase();\n // 0. Strip any value with an embedded URI credential (user:pass@host),\n // regardless of the variable name (WS-01). Applied before the allowlist\n // so even a \"system\" name carrying a connection string is caught.\n if (valueHasEmbeddedCredential(v)) continue;\n // 1. Forward names on the explicit allowlist \u2014 these are well-known\n // non-secret system variables (PATH, HOME, LANG, ...).\n if (ALLOWED_KEYS.has(upper)) {\n out[k] = v;\n continue;\n }\n // 2. Strip anything that looks like a secret.\n if (looksSecret(upper)) continue;\n // NODE_OPTIONS is forwarded (builds rely on flags like --no-warnings) but\n // module-preload directives (--require/--import/--loader) are stripped \u2014\n // they would let a parent-set NODE_OPTIONS inject code into every node\n // child (WS-02 defense-in-depth).\n if (upper === 'NODE_OPTIONS') {\n const sanitized = sanitizeNodeOptions(v);\n if (sanitized) out[k] = sanitized;\n continue;\n }\n // 3. Forward tooling-prefixed vars that builds commonly need, unless\n // they already failed the secret check above.\n if (\n upper.startsWith('NODE_') ||\n upper.startsWith('NPM_') ||\n upper.startsWith('PNPM_') ||\n upper.startsWith('YARN_') ||\n upper.startsWith('GIT_') ||\n upper.startsWith('CI') ||\n upper.startsWith('XDG_') ||\n // Our own non-secret knobs (WRONGSTACK_HOME, WRONGSTACK_SESSION_ID, \u2026).\n // Secrets never live in WRONGSTACK_* env vars (they're in the encrypted\n // vault). Forwarding keeps child wstack processes \u2014 e.g. ones spawned\n // by the test suite \u2014 inside the same redirected global root.\n upper.startsWith('WRONGSTACK_') ||\n upper === 'EDITOR' ||\n upper === 'VISUAL' ||\n upper === 'PAGER'\n ) {\n out[k] = v;\n }\n }\n\n // Configured commit identity. Applied in passthrough mode too \u2014 it is the\n // operator's explicit intent, not a parent-env leak. Placed BEFORE the\n // extras merge so a caller-provided GIT_* override still wins.\n if (gitIdentity) {\n if (gitIdentity.name) {\n out['GIT_AUTHOR_NAME'] = gitIdentity.name;\n out['GIT_COMMITTER_NAME'] = gitIdentity.name;\n }\n if (gitIdentity.email) {\n out['GIT_AUTHOR_EMAIL'] = gitIdentity.email;\n out['GIT_COMMITTER_EMAIL'] = gitIdentity.email;\n }\n }\n\n // Merge explicit extras AFTER filtering. Callers MUST treat `opts.extra`\n // as a small, user-authored allowlist (e.g. MCP server tokens, LSP env\n // overrides from config). Do NOT pass `process.env` or any object derived\n // from it \u2014 that would defeat the parent-env scrub above. The secret\n // filter is intentionally skipped here so legitimate secret-bearing\n // tokens the user explicitly configured can still reach the child.\n if (opts.extra) {\n Object.assign(out, opts.extra);\n }\n\n if (opts.sessionId) out['WRONGSTACK_SESSION_ID'] = opts.sessionId;\n return out;\n}\n", "/**\n * TTY detection helpers \u2014 the single source of truth for \"is this process\n * running against a real terminal?\". Replaces ad-hoc `process.stdin.isTTY`\n * / `process.stdout.isTTY` checks scattered across the codebase so that:\n *\n * 1. test code can mock a single module instead of stubbing `isTTY` on\n * every ReadStream/WriteStream the test happens to touch;\n * 2. a future TTY-detection source (an env var override, a Windows\n * ConPTY workaround, \u2026) lands in one place;\n * 3. `isInteractive()` encodes the rule the project already used inline\n * (\"both streams are TTYs AND we're not running under CI\") in one\n * testable helper instead of the same 3-condition check in two\n * different files.\n *\n * Scope: detection only. Raw-mode control (`setRawMode`), resize\n * subscriptions, and write-injection belong to a future, larger TTY\n * abstraction; this module is the smallest pull that gives us a\n * testable seam and dedups 20+ call sites.\n */\n\nconst hasStdout = (): boolean => typeof process !== 'undefined' && !!process.stdout;\nconst hasStdin = (): boolean => typeof process !== 'undefined' && !!process.stdin;\n\n/** True when `process.stdout` is attached to a terminal (not a pipe/file). */\nexport function isStdoutTTY(): boolean {\n return hasStdout() && Boolean(process.stdout.isTTY);\n}\n\n/** True when `process.stdin` is attached to a terminal (not a pipe/file). */\nexport function isStdinTTY(): boolean {\n return hasStdin() && Boolean(process.stdin.isTTY);\n}\n\n/**\n * True when the current process is an interactive session: both stdin and\n * stdout are TTYs. Callers that also need a \"not a single-shot invocation\"\n * or \"not under CI\" check should layer that on top \u2014 keeping this helper\n * minimal preserves the original inline checks it replaces.\n */\nexport function isInteractive(): boolean {\n return isStdinTTY() && isStdoutTTY();\n}\n\n/** Current terminal size in characters, with a 24\u00D780 fallback for non-TTYs. */\nexport function getTermSize(): { rows: number; cols: number } {\n if (!hasStdout()) return { rows: 24, cols: 80 };\n return {\n rows: process.stdout.rows ?? 24,\n cols: process.stdout.columns ?? 80,\n };\n}\n\n/**\n * Subscribe to terminal resize events. `cb` is called with the new size each\n * time the underlying stream emits `resize`. Returns a cleanup function the\n * caller MUST call on dispose to remove the listener \u2014 leaving a stale\n * `resize` listener on a disposed component leaks the closure (and the\n * component itself, transitively) until the process exits.\n *\n * The stream argument defaults to `process.stdout`. Pass an explicit\n * `NodeJS.WriteStream` when the caller already owns one (e.g. a status line\n * that targets an injected `out` for testability). For non-TTY streams no\n * listener is registered and the returned cleanup is a no-op.\n */\nexport function onResize(\n cb: (size: { rows: number; cols: number }) => void,\n stream: NodeJS.WriteStream = process.stdout,\n): () => void {\n if (!stream || typeof stream.on !== 'function') return () => {};\n const handler = (): void => {\n cb({\n rows: stream.rows ?? 24,\n cols: stream.columns ?? 80,\n });\n };\n stream.on('resize', handler);\n return () => {\n stream.off('resize', handler);\n };\n}\n\n/**\n * Toggle raw mode on a TTY stdin stream. Returns `true` when the toggle was\n * applied, `false` when the stream is null, not a TTY, or doesn't expose\n * `setRawMode` (pipes, file descriptors, Windows ConPTY edge cases). Callers\n * that need to restore the previous mode should snapshot `input.isRaw`\n * BEFORE the call and pass the value to a second call to flip back.\n *\n * Use this helper to drop the now-redundant\n * `if (input.isTTY) input.setRawMode(...)` ceremony at every call site.\n */\nexport function setRawMode(input: NodeJS.ReadStream, mode: boolean): boolean {\n if (input?.isTTY !== true) return false;\n if (typeof input.setRawMode !== 'function') return false;\n input.setRawMode(mode);\n return true;\n}\n\n/**\n * Bracket installed by the interactive input reader while a `readline`\n * prompt is on screen. Out-of-band terminal writes \u2014 logger WARN/INFO\n * lines, async activity from the Telegram bridge, etc. \u2014 go to the same\n * physical terminal as the half-typed prompt but readline has no idea they\n * happened, so it never repaints. The result is the classic corruption the\n * user sees: every async line strands the in-progress draft as a fresh\n * scrollback row (sometimes with its cursor underline).\n *\n * The guard closes that gap. `suspend()` wipes the draft row so the message\n * prints clean; `resume()` repaints the prompt + draft (cursor preserved).\n * When no prompt is active the guard is `null` and writes pass straight\n * through \u2014 so agent-turn output (spinner, renderer) is untouched.\n */\nexport interface OutputLineGuard {\n /** Clear the current input row right before an out-of-band write. */\n suspend(): void;\n /** Repaint the prompt + in-progress draft right after the write. */\n resume(): void;\n}\n\nlet activeOutputGuard: OutputLineGuard | null = null;\n\n/**\n * Register (or clear, with `null`) the guard that brackets out-of-band\n * writes. Installed by {@link writeOut}/{@link writeErr} consumers \u2014 in\n * practice the CLI's readline input reader \u2014 only while a prompt is live.\n * Idempotent; the most recent caller wins.\n */\nexport function setOutputLineGuard(guard: OutputLineGuard | null): void {\n activeOutputGuard = guard;\n}\n\n/**\n * Stream-agnostic write primitive. Returns `false` when the stream is\n * missing or doesn't expose `write` so callers can degrade silently under\n * hostile host environments (closed pipe, mock injects `null`, test\n * replaces the stream with a stub).\n *\n * When an {@link OutputLineGuard} is installed (a readline prompt is on\n * screen) the write is bracketed by `suspend()`/`resume()` so the user's\n * half-typed input survives the interruption instead of being stranded in\n * scrollback. The guard's own redraw uses raw stream writes \u2014 never\n * `writeOut`/`writeErr` \u2014 so there is no re-entrancy here.\n *\n * **Not exported in the public API.** Exposed only inside `term.ts` for\n * `writeOut` / `writeErr` to share a single implementation. If a caller\n * needs to write to an arbitrary stream, they should call `writeOut` (or\n * `writeErr`) with an explicit `stream` argument \u2014 the named functions\n * are the public surface so the \"this is the standard error stream\"\n * intent stays visible at every call site.\n */\nfunction writeTo(\n s: string,\n stream: NodeJS.WriteStream | undefined,\n): boolean {\n if (!stream || typeof stream.write !== 'function') return false;\n const guard = activeOutputGuard;\n if (!guard) {\n stream.write(s);\n return true;\n }\n // A prompt is live \u2014 wipe the draft row, emit the message, repaint.\n guard.suspend();\n stream.write(s);\n guard.resume();\n return true;\n}\n\n/**\n * Write `s` to `stream` (defaults to `process.stdout`). Returns `false`\n * when the stream is missing or doesn't expose `write` so callers can\n * degrade silently under hostile host environments (closed pipe, mock\n * injects `null`, test replaces the stream with a stub).\n *\n * Why a helper:\n * 1. **Single seam for output capture in tests** \u2014 stub `writeOut` once\n * and assert on what the rest of the codebase intended to print,\n * without spying on `process.stdout.write` (which is brittle and\n * leaks across parallel test files).\n * 2. **Stream swap without grep** \u2014 routing the CLI's output to a\n * logger or `out.log` becomes a one-line change at process boot.\n * 3. **Defensive default** \u2014 closes the \"what if `process.stdout` is\n * `null`\" gap that currently exists at ~50 call sites that just\n * call `process.stdout.write(s)` and crash on certain Windows\n * redirect invocations.\n *\n * Call-site migration is staged: this commit introduces the helper, a\n * follow-up commit replaces the 50+ `process.stdout.write(...)` sites\n * with `writeOut(...)`. Until that migration lands, both forms coexist\n * and `writeOut` is the preferred form for new code.\n */\nexport function writeOut(\n s: string,\n stream: NodeJS.WriteStream = process.stdout,\n): boolean {\n return writeTo(s, stream);\n}\n\n/**\n * Symmetric partner of `writeOut` for the standard error stream. Same shape,\n * same defensive contract, same single-seam-for-tests story \u2014 just defaults to\n * `process.stderr` instead of `process.stdout`.\n *\n * Use this in code paths that emit error/diagnostic/warning text. Keeping\n * these two helpers split (rather than a single `writeTo(s, stream)`) means\n * the call site reads as a clear intent signal: \"I am writing an error\" vs.\n * \"I am writing a result\" \u2014 which matters for callers that decide between\n * stdout/stderr routing (e.g. `--quiet` flags, log-level filtering,\n * structured-log rewriters that fork on stream).\n *\n * Stderr writes from the core logger (see `infrastructure/logger.ts`) and from\n * the TUI guard (see `tui/run-tui.ts`) used to call `process.stderr.write`\n * directly. Routing them through this helper lets tests stub the stream at\n * one boundary and lets future logging middleware (e.g. a JSON-line rewriter)\n * swap the destination for the entire process in one place.\n */\nexport function writeErr(\n s: string,\n stream: NodeJS.WriteStream = process.stderr,\n): boolean {\n return writeTo(s, stream);\n}\n\n// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// TerminalCapability \u2014 startup capability profile\n// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Color depth the terminal can render.\n *\n * 0 = no color (dumb, redirected, `TERM=dumb`)\n * 1 = 16 colors (basic ANSI)\n * 2 = 256 colors (ANSI 256 + bright variants)\n * 3 = 16.7M / 24-bit truecolor\n */\nexport type ColorDepth = 0 | 1 | 2 | 3;\n\n/**\n * Mouse tracking protocol the terminal speaks.\n *\n * 'none' \u2014 no mouse reporting\n * 'x10' \u2014 basic button press/release, capped at 223 columns\n * 'urxvt'\u2014 URXVT extension, supports >223 cols\n * 'sgr' \u2014 SGR extended mode, modern standard, no column cap\n */\nexport type MouseProtocol = 'none' | 'x10' | 'urxvt' | 'sgr';\n\n/**\n * A snapshot of the terminal's capabilities and identity, computed once at\n * startup. Call {@link detectTerminal} once and pass the result through your\n * app \u2014 never re-detect mid-session.\n *\n * Query once \u2192 adapt once. Re-querying on every render is wrong because\n * `$TERM` is static for the process lifetime and stdout.isTTY can only go\n * from true\u2192false (never the reverse), so a mid-session change means the\n * process was started in a terminal and then something went wrong.\n */\nexport interface TerminalCapability {\n /** True when both stdin and stdout are attached to a terminal. */\n isRealTTY: boolean;\n /**\n * Whether the terminal speaks color.\n *\n * Uses the industry-standard precedence:\n * `FORCE_COLOR=0` \u2192 0 (disabled)\n * `FORCE_COLOR` \u2192 3 (force truecolor)\n * `NO_COLOR=\u2026` \u2192 0 (opted out)\n * `COLORTERM=truecolor|24bit` \u2192 3\n * `TERM=\u2026truecolor|24bit` \u2192 3 (some emulators advertise it)\n * `TERM=\u2026256color` \u2192 2\n * fallback \u2192 1\n *\n * Note: `TERM=dumb` always produces 0 even if `COLORTERM=truecolor` is set \u2014\n * `dumb` terminals are non-interactive by definition.\n */\n colorDepth: ColorDepth;\n /**\n * Whether `stdout` can be written to. Determined once at startup from\n * `stdout?.isTTY ?? false`. Even when `isRealTTY` is true, `stdout` may be\n * writable=false (e.g. the terminal was closed mid-session).\n */\n stdoutWritable: boolean;\n /**\n * Best mouse protocol the terminal speaks. Progressive enhancement:\n * attempt SGR first, fall back to URXVT, then X10, then 'none'.\n *\n * The caller (typically the App component) decides whether to enable\n * tracking at all \u2014 this only reports what the terminal CAN understand.\n */\n mouseProtocol: MouseProtocol;\n /**\n * Whether the terminal title can be set via OSC 0 / OSC 2.\n * True when stdout is a TTY and `$TERM` is not `dumb`.\n */\n canSetTitle: boolean;\n /**\n * Whether the terminal understands the tmux DCS passthrough prefix.\n * Detected by seeing `$TERM=tmux*`. When true, escape sequences should be\n * wrapped: `\\x1bPtmux;\\x1b${seq}\\x1b\\\\`.\n */\n isTmux: boolean;\n /**\n * Whether the terminal is on Windows using the legacy conhost backend\n * (cmd.exe, PowerShell non-ConPTY) rather than ConPTY (Windows Terminal,\n * VS Code Integrated Terminal). Used to apply Windows-specific raw-mode\n * handoff logic.\n *\n * Detected by: platform === 'win32' AND `!process.stdout.getColorDepth?.()`\n * (ConPTY exposes color depth; conhost does not). Also false on non-Windows.\n */\n isWindowsConhost: boolean;\n}\n\n/**\n * Parse `process.env.TERM` into a color-depth guess.\n *\n * We intentionally do NOT use the `supports-color` npm package here because\n * (a) it adds a dependency, (b) it resolves at module-import time, and (c) we\n * need to factor in `FORCE_COLOR` / `NO_COLOR` which may be set after import.\n * This pure function is trivial to test and predictable regardless of import\n * order.\n */\nfunction parseColorDepth(env: { FORCE_COLOR?: string; NO_COLOR?: string; COLORTERM?: string; TERM?: string; }): ColorDepth {\n // `FORCE_COLOR=0` is an explicit opt-out, even when `COLORTERM=truecolor`.\n if (env.FORCE_COLOR === '0') return 0;\n // `FORCE_COLOR` with no value or any truthy value forces truecolor.\n if (env.FORCE_COLOR !== undefined) return 3;\n // Explicit user opt-out.\n if (typeof env.NO_COLOR === 'string' && env.NO_COLOR !== '') return 0;\n // Explicit terminal advertisement.\n const colorterm = (env.COLORTERM ?? '').toLowerCase();\n if (colorterm === 'truecolor' || colorterm === '24bit') return 3;\n // TERM strings that advertise rich color.\n const term = (env.TERM ?? '').toLowerCase();\n if (term.includes('truecolor') || term.includes('24bit')) return 3;\n if (term.includes('256color')) return 2;\n // TERM=dumb = no interactive capability at all.\n if (term === 'dumb') return 0;\n // Default to 16-color \u2014 the safest floor. Modern terminals all override this.\n return 1;\n}\n\n/**\n * Detect the best mouse protocol the terminal speaks.\n *\n * Uses the `$TERM` string as a proxy since Node.js has no runtime query for\n * mouse capability (DECSET 1000/1002/1003 responses are not standardized for\n * programmatic use). The approximation is:\n * - `tmux` + `screen` = SGR (they proxy it)\n * - `xterm*`, `rxvt*`, `konsole`, `gnome*` = SGR (post-2013)\n * - `linux`, `vt100`, `dumb` = none\n * - Everything else = URXVT / X10 (try SGR, fall back gracefully in mouse.ts)\n *\n * This is advisory only. The App component gates mouse tracking behind an\n * explicit user/setting opt-in; false positives just mean the tracking enable\n * sequence is ignored harmlessly.\n */\nfunction parseMouseProtocol(term: string): MouseProtocol {\n const t = term.toLowerCase();\n // Terminals that reliably support SGR (1006) mode.\n if (\n t.startsWith('xterm') ||\n t.startsWith('tmux') ||\n t.startsWith('screen') ||\n t.includes('rxvt-unicode') ||\n t.includes('urxvt') ||\n t.includes('konsole') ||\n t.includes('gnome') ||\n t.includes('foot') ||\n t.includes('alacritty') ||\n t.includes('wezterm') ||\n t.includes('kitty') ||\n t.includes('vscode') ||\n t.includes('Apple_Terminal')\n ) {\n return 'sgr';\n }\n // Known mouse-capable but older terminals.\n if (t.startsWith('rxvt') || t.startsWith('linux') || t.includes('Eterm')) {\n return 'urxvt';\n }\n // vt100 / dumb \u2014 no mouse.\n if (t === 'vt100' || t === 'dumb') return 'none';\n // Default: assume SGR is safe to try; mouse.ts falls back silently.\n return 'sgr';\n}\n\n/**\n * Detect the terminal's capabilities and identity at startup.\n *\n * Call once, early in process boot, before any event-loop async has had a\n * chance to corrupt the read of `process.stdout.isTTY`. Store the result and\n * pass it through the app \u2014 do NOT call this on every render.\n *\n * All `env` lookups default gracefully to safe values when the env var is\n * absent or empty, so the return value is deterministic regardless of what\n * the host's environment looks like.\n */\nexport function detectTerminal(\n opts: {\n stdin?: NodeJS.ReadStream | null;\n stdout?: NodeJS.WriteStream | null;\n env?: typeof process.env;\n } = {},\n): TerminalCapability {\n const stdin = opts.stdin ?? process.stdin;\n const stdout = opts.stdout ?? process.stdout;\n const env = opts.env ?? process.env;\n\n const isRealTTY = (stdin?.isTTY ?? false) && (stdout?.isTTY ?? false);\n const stdoutWritable = isRealTTY && typeof stdout?.write === 'function';\n const term = env.TERM ?? '';\n const isTmux = term.toLowerCase().startsWith('tmux');\n const isWindowsConhost = isRealTTY\n && process.platform === 'win32'\n && typeof (stdout as NodeJS.WriteStream & { getColorDepth?: unknown }).getColorDepth !== 'function';\n\n return {\n isRealTTY,\n colorDepth: isRealTTY ? parseColorDepth(env) : 0,\n stdoutWritable,\n mouseProtocol: parseMouseProtocol(term),\n canSetTitle: isRealTTY && term !== 'dumb',\n isTmux,\n isWindowsConhost,\n };\n}\n\n// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// TerminalLifecycle \u2014 raw-mode lifecycle manager\n// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Lifecycle owner for the TTY stdin raw-mode state machine.\n *\n * Raw mode is the most dangerous primitive in TUI code. Getting it wrong leaves\n * the user's terminal in a broken state (line-buffered, no echo) that requires\n * closing and reopening the terminal to recover. This class enforces a strict\n * acquire \u2192 hold \u2192 release lifecycle:\n *\n * - `acquire()` may be called only once (idempotent \u2014 subsequent calls no-op).\n * - `release()` restores the previous mode exactly once.\n * - `release()` is called automatically on process `exit` and `beforeExit`.\n * - Any signal handler (SIGINT, SIGTERM, SIGHUP) that calls `release()` clears\n * its own registration so double-signals don't double-restore.\n *\n * Use this instead of calling `setRawMode()` directly at every call site. The\n * single instance lives at module scope in `run-tui.ts`; components that need\n * to signal \"TUI is shutting down\" call `terminalLifecycle.requestExit()` rather\n * than calling `release()` directly.\n */\nexport class TerminalLifecycle {\n private _active = false;\n\n /**\n * The stdin stream we took raw mode on. Set by `acquire()`; undefined before\n * first call. Used by `release()` and by the ConPTY race-closer in\n * `acquire()`.\n */\n private _stdin: NodeJS.ReadStream | undefined;\n\n /**\n * The `isRaw` snapshot captured before the first `acquire()` call, so\n * `release()` restores to the pre-TUI state rather than blindly disabling\n * raw mode. Null when `acquire()` has never been called.\n */\n private _wasRaw: boolean | null = null;\n\n /**\n * Whether stdin was paused before the TUI took ownership. Readline closes\n * its interface by pausing the shared process stream, so raw mode alone is\n * not enough to make Ink receive bytes during the boot-prompt -> TUI handoff.\n */\n private _wasPaused: boolean | null = null;\n\n /**\n * Request the process to exit. Set the flag, trigger any registered\n * `onRequestExit` callback (typically Ink's `unmount()`), and arm a\n * deadline timer. When the timer fires the process is hard-exited.\n *\n * Safe to call multiple times: subsequent calls no-op after the first.\n */\n requestExit: (exitCode?: number) => void;\n\n /**\n * Callback invoked when `requestExit` is called. Registered by the Ink\n * mount point so unmount() runs before the deadline timer fires.\n */\n onRequestExit: (() => void | Promise<void>) | null = null;\n\n constructor() {\n // Build the requestExit closure here so subclasses / tests can override\n // `requestExit` before calling `acquire()`.\n let exitCode = 0;\n let requested = false;\n this.requestExit = (code = 0) => {\n exitCode = code;\n if (requested) return;\n requested = true;\n // Let the Ink unmount handler run (if registered).\n try {\n this.onRequestExit?.();\n } catch {\n // unmount handler threw \u2014 proceed to hard exit.\n }\n // Hard-exit deadline. `unref()` so the timer doesn't keep the event\n // loop alive if everything else has settled.\n setTimeout(() => process.exit(exitCode), 5_000).unref();\n };\n }\n\n /** True while raw mode is held. */\n get active(): boolean {\n return this._active;\n }\n\n /**\n * Acquire raw mode on `stdin`. Idempotent \u2014 calling twice is safe; only the\n * first call has any effect.\n *\n * On Windows ConPTY, calls `setRawMode` twice: once immediately, then again\n * after the next event-loop tick. This closes the ConPTY race where\n * `readline`'s cleanup (registered before this class is constructed) can\n * restore the original cooked mode after we set raw mode but before Ink's\n * render loop takes over the stdin fd. The double-call ensures the last\n * writer wins.\n *\n * @param stdin - The stdin stream (defaults to `process.stdin`).\n * @returns `true` if raw mode was acquired; `false` if stdin is not a TTY\n * or already shut down.\n */\n acquire(stdin: NodeJS.ReadStream = process.stdin): boolean {\n if (this._active) return false;\n\n // Guard: must be a real TTY, must have setRawMode.\n if (stdin?.isTTY !== true) return false;\n if (typeof stdin.setRawMode !== 'function') return false;\n\n // Snapshot the pre-TUI raw state so release() restores correctly.\n this._wasRaw = stdin.isRaw ?? false;\n this._wasPaused = stdin.isPaused();\n this._stdin = stdin;\n\n stdin.setRawMode(true);\n // A preceding readline prompt normally leaves process.stdin paused.\n // Explicitly start the stream before Ink installs its input listener;\n // otherwise the UI can render perfectly while every key appears dead.\n stdin.resume();\n this._active = true;\n\n // Windows ConPTY double-acquire: schedule a second setRawMode on the next\n // tick so we win the race against readline's \"restore original mode\".\n // Safe on non-Windows (no-op: process.platform !== 'win32').\n if (process.platform === 'win32') {\n setImmediate(() => {\n if (this._active && this._stdin?.isTTY) {\n this._stdin.setRawMode?.(true);\n }\n });\n }\n\n return true;\n }\n\n /**\n * Release raw mode and restore the terminal to the state it was in before\n * `acquire()` was called. Idempotent \u2014 subsequent calls are no-ops.\n *\n * Call this on: SIGINT, SIGTERM, SIGHUP, SIGBREAK, and `process.exit`.\n *\n * \u26A0 **Windows caveat**: `setRawMode(false)` on ConPTY restores the original\n * console mode captured when the process started \u2014 not the mode captured by\n * `acquire()`. On ConPTY, the original mode was already raw (ConPTY starts\n * raw), so this call is typically a no-op on Windows Terminal. On conhost.exe\n * it may restore cooked mode, which is correct for that backend.\n */\n release(): void {\n if (!this._active) return;\n this._active = false;\n\n const stdin = this._stdin;\n if (stdin?.isTTY === true) {\n // Restore to pre-TUI state rather than blindly disabling raw mode.\n stdin.setRawMode?.(this._wasRaw ?? false);\n if (this._wasPaused) stdin.pause();\n }\n this._stdin = undefined;\n this._wasRaw = null;\n this._wasPaused = null;\n }\n\n /**\n * Synchronously reset all terminal state written by the TUI layer:\n * raw mode, SGR attributes, cursor visibility, and mouse tracking.\n *\n * Intended for the final `process.on('exit')` handler where async is\n * impossible. Uses `\\x1b[0m` (SGR reset), `\\x1b[?25h` (cursor show),\n * and `\\x1b[?9l` (mouse off) \u2014 all safe to emit even if the terminal does\n * not understand them (unknown CSI sequences are silently ignored).\n *\n * Safe to call multiple times from multiple exit paths because each write\n * is a constant-time synchronous stream write.\n *\n * @param stdout - Stream to reset (defaults to `process.stdout`).\n */\n reset(stdout: NodeJS.WriteStream = process.stdout): void {\n if (typeof stdout?.write !== 'function') return;\n // SGR reset \u2014 clears bold, color, underline, etc.\n stdout.write('\\x1b[0m');\n // Cursor show (in case Ink's unmount left it hidden).\n stdout.write('\\x1b[?25h');\n // Mouse tracking off (all three DECRST sequences \u2014 safe no-ops if never set).\n stdout.write('\\x1b[?1003l\\x1b[?1002l\\x1b[?1000l');\n }\n}\n\n// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// safeEscape \u2014 guarded escape-sequence emitter\n// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Result of emitting an escape sequence. Distinguishes the three distinct\n * failure modes so callers can degrade gracefully.\n */\nexport interface EscapeEmitResult {\n /** `true` when the sequence was written to the stream. */\n ok: boolean;\n /**\n * Human-readable reason when `ok` is `false`. One of:\n * `'not_a_tty'` \u2014 stdout is not a terminal (pipe / redirect / CI)\n * `'unwritable'` \u2014 stdout.write is missing or threw\n * `'empty'` \u2014 `sequence` was the empty string\n */\n reason: 'not_a_tty' | 'unwritable' | 'empty';\n}\n\n/**\n * A terminal escape sequence with its optional string terminator.\n *\n * OSC (title, color palette) sequences MUST be terminated with `BEL (\\x07)`\n * or `ST (\\x1b\\\\)` or the terminal stays in command mode and corrupts\n * subsequent output. CSI sequences (colors, cursor movement) are\n * self-terminating and do not need a terminator byte.\n */\nexport interface EscapeSequence {\n /** The raw sequence, e.g. `\\x1b[38;2;255;0;0m`. */\n raw: string;\n /**\n * Optional terminator byte required by OSC/DCS families.\n * `undefined` for CSI sequences; `\\x07` (BEL) for OSC; `\\x1b\\\\` (ST) for DCS.\n */\n terminator?: string;\n}\n\n/**\n * Shared OSC/DCS terminator bytes.\n *\n * BEL (`\\x07`) is understood by iTerm2, Konsole, mintty, foot, and\n * Windows Terminal. ST (`\\x1b\\\\`) is the strict DEC standard equivalent.\n * Prefer BEL for compatibility; fall back to ST if the terminal's response\n * to BEL is observed to be garbled.\n */\nexport const ESCAPE_TERMINATOR = Object.freeze({\n BEL: '\\x07', // OSC 0 / OSC 2 (title)\n ST: '\\x1b\\\\', // DCS / strict OSC\n});\n\n/**\n * Emit a terminal escape sequence safely.\n *\n * Rules enforced:\n * 1. Empty string \u2192 returns `ok: false, reason: 'empty'`, no write.\n * 2. Not a TTY \u2192 returns `ok: false, reason: 'not_a_tty'`, no write.\n * 3. Stream write throws \u2192 returns `ok: false, reason: 'unwritable'`.\n * 4. OSC/DCS sequences MUST have a terminator byte (guarded assertion).\n * A missing terminator on an OSC sequence corrupts output on terminals\n * that don't understand the sequence \u2014 this function refuses to emit it.\n *\n * @param sequence - The sequence to emit. CSI sequences need no terminator.\n * OSC/DCS sequences must carry `terminator: '\\x07'` or `'\\x1b\\\\'`.\n * @param stdout - Stream to write to (defaults to `process.stdout`).\n * @returns Result indicating success or the specific failure mode.\n */\nexport function safeEmit(\n sequence: EscapeSequence | string,\n stdout: NodeJS.WriteStream = process.stdout,\n): EscapeEmitResult {\n const raw = typeof sequence === 'string' ? sequence : sequence.raw;\n const term = typeof sequence === 'string' ? undefined : sequence.terminator;\n\n if (!raw) {\n return { ok: false, reason: 'empty' };\n }\n if (stdout?.isTTY !== true) {\n return { ok: false, reason: 'not_a_tty' };\n }\n\n // For OSC/DCS sequences (which include `[` or `]` in the body), verify a\n // terminator is present. CSI sequences start with `\\x1b[` and are\n // self-terminating; we treat any sequence that is not a known OSC/DCS\n // as CSI and allow through. OSC starts with `\\x1b]`; DCS with `\\x1bP`.\n if (raw.startsWith('\\x1b]') || raw.startsWith('\\x1bP')) {\n // Assertion: terminator must be provided. Belt-and-suspenders against\n // callers that forget to append `\\x07` \u2014 this prevents corrupted output.\n if (!term) {\n // Defensive: append BEL rather than crashing. This is the only case\n // where we mutate the sequence. The assert-then-fallback pattern is\n // intentional: we catch programmer error in development but degrade\n // safely in production rather than throwing.\n void term; // suppress unused-variable warning\n const safe = `${raw}\\x07`;\n try {\n stdout.write(safe);\n } catch {\n return { ok: false, reason: 'unwritable' };\n }\n return { ok: true, reason: 'empty' }; // reason field is ignored when ok=true\n }\n try {\n stdout.write(`${raw}${term}`);\n } catch {\n return { ok: false, reason: 'unwritable' };\n }\n return { ok: true, reason: 'empty' };\n }\n\n // CSI sequence \u2014 self-terminating.\n try {\n stdout.write(raw);\n } catch {\n return { ok: false, reason: 'unwritable' };\n }\n return { ok: true, reason: 'empty' };\n}\n\n/**\n * Build an OSC 0 / OSC 2 (window/tab title) sequence with a safe terminator.\n *\n * The terminator defaults to `BEL (\\x07)` for broad terminal compatibility.\n * Use `terminator: ESCAPE_TERMINATOR.ST` for stricter terminals that interpret\n * BEL as a beep.\n *\n * @param title - The title string. Embedded BEL bytes are stripped.\n * @param terminator - Defaults to `ESCAPE_TERMINATOR.BEL`.\n */\nexport function buildTitleSequence(\n title: string,\n terminator: string = ESCAPE_TERMINATOR.BEL,\n): EscapeSequence {\n return {\n raw: `\\x1b]0;${title.replace(/\\x07/g, '')}`,\n terminator,\n };\n}\n\n/**\n * Build an SGR (Select Graphic Rendition) color/style sequence.\n *\n * @param codes - SGR parameter list, e.g. `[31]` (red foreground),\n * `[1;32]` (bold green), `[38;2;255;128;0]` (truecolor orange).\n */\nexport function buildSgrSequence(...codes: number[]): EscapeSequence {\n return { raw: `\\x1b[${codes.join(';')}m` };\n}\n\n/**\n * Emit a title sequence. Convenience wrapper around `safeEmit` + `buildTitleSequence`.\n *\n * @param title - The title string.\n * @param stdout - Target stream.\n */\nexport function setTitle(\n title: string,\n stdout: NodeJS.WriteStream = process.stdout,\n): boolean {\n return safeEmit(buildTitleSequence(title), stdout).ok;\n}\n", "import { isStdoutTTY } from './term.js';\n\nconst isColorTty = (): boolean => {\n if (envFlag(process.env.NO_COLOR)) return false;\n if (envFlag(process.env.FORCE_COLOR)) return true;\n return isStdoutTTY();\n};\n\nfunction envFlag(value: string | undefined): boolean {\n if (value === undefined) return false;\n if (value.trim() === '') return false;\n return !/^(0|false|no|off)$/i.test(value.trim());\n}\n\nconst COLOR = isColorTty();\n\nconst wrap =\n (open: string, close: string) =>\n (s: string): string =>\n COLOR ? `\\x1b[${open}m${s}\\x1b[${close}m` : s;\n\nexport const color = {\n reset: wrap('0', '0'),\n bold: wrap('1', '22'),\n dim: wrap('2', '22'),\n italic: wrap('3', '23'),\n underline: wrap('4', '24'),\n red: wrap('31', '39'),\n green: wrap('32', '39'),\n yellow: wrap('33', '39'),\n blue: wrap('34', '39'),\n magenta: wrap('35', '39'),\n cyan: wrap('36', '39'),\n gray: wrap('90', '39'),\n amber: wrap('38;5;214', '39'),\n pink: wrap('38;5;205', '39'),\n bgRed: wrap('41', '49'),\n bgGreen: wrap('42', '49'),\n};\n\nexport function stripAnsi(s: string): string {\n return s.replace(/\\x1b\\[[0-9;]*[A-Za-z]/g, '');\n}\n", "import * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\n\n/**\n * Minimal paths object needed for config backup \u2014 just the global root\n * from which we derive the backup history directory.\n */\nexport interface ConfigBackupPaths {\n globalRoot: string;\n}\n\n/**\n * Backup directory for config file history.\n * Every config write creates a timestamped snapshot here so the user can\n * recover from accidental changes. Backups are never cleaned up automatically.\n */\nexport function configHistoryDir(globalRoot: string): string {\n return path.join(globalRoot, 'config-history');\n}\n\n/**\n * Derive a human-readable slug for a config file path relative to the\n * ~/.wrongstack root. Examples:\n * config.json \u2192 config\n * profiles/default/config.json \u2192 profiles-default-config\n */\nfunction configSlug(absolutePath: string, globalRoot: string): string {\n const rel = path.relative(globalRoot, absolutePath);\n const normalized = rel.replace(/\\\\/g, '/').replace(/\\.json$/i, '');\n return normalized.replace(/\\//g, '-');\n}\n\n/**\n * Before overwriting a config file, save its current content to the\n * config-history directory with a timestamp. Best-effort: failures are\n * silently ignored so they never block the config write itself.\n */\nexport async function backupConfigFile(\n filePath: string,\n paths: ConfigBackupPaths,\n): Promise<void> {\n let currentContent: string;\n try {\n currentContent = await fs.readFile(filePath, 'utf8');\n if (!currentContent.trim()) return;\n } catch {\n return; // ENOENT or other error \u2014 no current content to back up\n }\n\n const now = new Date();\n const ts = now.toISOString()\n .replace(/[:.]/g, '-')\n .replace(/Z$/, '');\n const slug = configSlug(filePath, paths.globalRoot);\n const backupDir = configHistoryDir(paths.globalRoot);\n const backupFile = path.join(backupDir, `${slug}-${ts}.json`);\n\n try {\n await fs.mkdir(backupDir, { recursive: true });\n await fs.writeFile(backupFile, currentContent, { mode: 0o600, encoding: 'utf8' });\n } catch {\n // best-effort \u2014 never block the config write for a backup failure\n }\n}\n", "/**\n * Lightweight outbound internet connectivity check.\n *\n * Probes a reliable public endpoint to determine if the current machine\n * has working outbound internet access. Used during provider-error handling\n * to distinguish \"the provider's API is down\" from \"our internet is down\" \u2014\n * the two need different remediation (wait vs. fix local network).\n *\n * The result is cached for a short TTL so rapid successive checks don't\n * hammer the probe target.\n */\n\nconst DEFAULT_PROBE_URL = 'https://1.1.1.1';\nconst DEFAULT_TIMEOUT_MS = 5_000;\nconst DEFAULT_TTL_MS = 30_000;\n\ninterface ConnectivityCache {\n ok: boolean;\n at: number;\n}\n\nlet cached: ConnectivityCache | undefined;\n\n/**\n * Returns `true` when the probe endpoint responds successfully (any HTTP\n * status that isn't a server-side failure), `false` on network error or\n * timeout. The result is cached for `ttlMs` (default 30 s).\n *\n * Probing `1.1.1.1` (Cloudflare DNS) is intentional: it's a CDN-backed\n * static page served from virtually every PoP, so a failure almost certainly\n * means the local network is down rather than the probe target being\n * unreachable.\n */\nexport async function checkConnectivity(opts?: {\n /** Probe URL. Default: https://1.1.1.1 */\n probeUrl?: string;\n /** Per-request timeout in ms. Default: 5000 (5 s). */\n timeoutMs?: number;\n /** Cache TTL in ms. Default: 30000 (30 s). Set 0 to force a fresh probe. */\n ttlMs?: number;\n}): Promise<boolean> {\n const url = opts?.probeUrl ?? DEFAULT_PROBE_URL;\n const timeout = opts?.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n const ttl = opts?.ttlMs ?? DEFAULT_TTL_MS;\n\n // Respect a non-expired cache entry\n if (cached && ttl > 0 && Date.now() - cached.at < ttl) {\n return cached.ok;\n }\n\n cached = { ok: await probe(url, timeout), at: Date.now() };\n return cached.ok;\n}\n\nasync function probe(url: string, timeoutMs: number): Promise<boolean> {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n try {\n // The response body is irrelevant; any HTTP response (including\n // 4xx/5xx from the probe target) means the network path works \u2014\n // the server reached us back.\n await fetch(url, { method: 'HEAD', signal: controller.signal });\n return true;\n } catch {\n return false;\n } finally {\n clearTimeout(timer);\n }\n}\n\n/**\n * Reset the cached connectivity result so the next call performs a fresh\n * probe. Useful during error recovery when the network state may have\n * changed.\n */\nexport function resetConnectivityCache(): void {\n cached = undefined;\n}\n", "import { createHash } from 'node:crypto';\nimport type { TextBlock } from '../types/blocks.js';\n\nconst keyCache = new WeakMap<readonly TextBlock[], string>();\n\n/**\n * Derive a stable, provider-agnostic cache-partition key from a frozen\n * system-prompt epoch. Requests that share the same stable prefix produce the\n * same key, so provider backends route them to the same automatic-cache\n * partition \u2014 this is what OpenAI's `prompt_cache_key` (and Gemini implicit\n * routing) needs to actually hit the cache on load-balanced deployments.\n *\n * Keyed off the volatile-free `ctx.systemPrompt` epoch array (the per-turn\n * ledger/next-steps blocks are appended AFTER this array, so they never enter\n * the key). Cached by array identity in a WeakMap \u2014 the sha-256 runs once per\n * epoch (a new array = a new epoch, e.g. on mode switch), not per request.\n *\n * Anthropic ignores this field (it uses `ttl` + `cache_control` markers), so\n * setting it is harmless there; only the wires that read `req.cache.key` act on\n * it, gated by their own capability flags.\n */\nexport function deriveCachePrefixKey(systemPrompt: readonly TextBlock[]): string {\n const cached = keyCache.get(systemPrompt);\n if (cached !== undefined) return cached;\n const h = createHash('sha256');\n for (const block of systemPrompt) h.update(block.text).update('\u0000');\n // 128 bits of hex is ample collision resistance for a routing key and keeps\n // the value short enough for provider length limits (OpenAI caps at 128 chars).\n const key = `ws-${h.digest('hex').slice(0, 32)}`;\n keyCache.set(systemPrompt, key);\n return key;\n}\n", "import * as fs from 'node:fs/promises';\nimport { atomicWrite } from './atomic-write.js';\n\nexport type JsonObject = Record<string, unknown>;\nexport type JsonPathSegment = string | number;\nexport type JsonPath = readonly JsonPathSegment[];\n\nexport async function readJsonObjectFile(filePath: string): Promise<JsonObject> {\n try {\n const parsed = JSON.parse(await fs.readFile(filePath, 'utf8')) as unknown;\n return isJsonObject(parsed) ? parsed : {};\n } catch {\n return {};\n }\n}\n\nexport async function jsonObjectFileExists(filePath: string): Promise<boolean> {\n try {\n await fs.access(filePath);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function writeJsonObjectFile(filePath: string, value: JsonObject): Promise<void> {\n await atomicWrite(filePath, JSON.stringify(value, null, 2), { mode: 0o600 });\n}\n\nexport async function updateJsonObjectFile(\n filePath: string,\n mutator: (config: JsonObject) => void | JsonObject | Promise<void | JsonObject>,\n): Promise<JsonObject> {\n const config = await readJsonObjectFile(filePath);\n const maybeNext = await mutator(config);\n const next = maybeNext && isJsonObject(maybeNext) ? maybeNext : config;\n await writeJsonObjectFile(filePath, next);\n return next;\n}\n\nexport function getJsonPath(root: unknown, path: JsonPath): unknown {\n let current = root;\n for (const segment of path) {\n if (typeof segment === 'number') {\n if (!Array.isArray(current)) return undefined;\n current = current[segment];\n continue;\n }\n if (!isJsonObject(current)) return undefined;\n current = current[segment];\n }\n return current;\n}\n\nexport function setJsonPath(root: JsonObject, path: JsonPath, value: unknown): JsonObject {\n if (path.length === 0) {\n if (!isJsonObject(value)) throw new Error('Root config value must be an object');\n return value;\n }\n const parent = ensureJsonParent(root, path);\n const leaf = lastPathSegment(path);\n if (typeof leaf === 'number') {\n if (!Array.isArray(parent)) throw new Error(`Cannot set numeric segment ${leaf} on non-array parent`);\n parent[leaf] = value;\n } else {\n if (!isJsonObject(parent)) throw new Error(`Cannot set property ${leaf} on non-object parent`);\n parent[leaf] = value;\n }\n return root;\n}\n\nexport function removeJsonPath(root: JsonObject, path: JsonPath): boolean {\n if (path.length === 0) return false;\n const parent = getJsonPath(root, path.slice(0, -1));\n const leaf = lastPathSegment(path);\n if (typeof leaf === 'number') {\n if (!Array.isArray(parent) || leaf < 0 || leaf >= parent.length) return false;\n parent.splice(leaf, 1);\n return true;\n }\n if (!isJsonObject(parent) || !(leaf in parent)) return false;\n delete parent[leaf];\n return true;\n}\n\nexport async function setJsonPathInFile(filePath: string, path: JsonPath, value: unknown): Promise<JsonObject> {\n return updateJsonObjectFile(filePath, (config) => setJsonPath(config, path, value));\n}\n\nexport async function removeJsonPathInFile(filePath: string, path: JsonPath): Promise<JsonObject> {\n return updateJsonObjectFile(filePath, (config) => {\n removeJsonPath(config, path);\n });\n}\n\nexport function isJsonObject(value: unknown): value is JsonObject {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction lastPathSegment(path: JsonPath): JsonPathSegment {\n const segment = path[path.length - 1];\n /* v8 ignore next -- defensive: callers guard path.length === 0 before here */\n if (segment === undefined) throw new Error('Invalid empty JSON path');\n return segment;\n}\n\nfunction ensureJsonParent(root: JsonObject, path: JsonPath): JsonObject | unknown[] {\n let current: JsonObject | unknown[] = root;\n for (let i = 0; i < path.length - 1; i += 1) {\n const segment = path[i];\n const nextSegment = path[i + 1];\n /* v8 ignore next -- defensive: sparse-array paths are never produced by callers */\n if (segment === undefined) throw new Error('Invalid empty JSON path segment');\n const nextContainer = typeof nextSegment === 'number' ? [] : {};\n\n if (typeof segment === 'number') {\n if (!Array.isArray(current)) throw new Error(`Cannot traverse numeric segment ${segment} on non-array parent`);\n if (!isJsonObject(current[segment]) && !Array.isArray(current[segment])) current[segment] = nextContainer;\n current = current[segment] as JsonObject | unknown[];\n } else {\n if (!isJsonObject(current)) throw new Error(`Cannot traverse property ${segment} on non-object parent`);\n if (!isJsonObject(current[segment]) && !Array.isArray(current[segment])) current[segment] = nextContainer;\n current = current[segment] as JsonObject | unknown[];\n }\n }\n return current;\n}\n", "import * as path from 'node:path';\nimport type { Context } from '../core/context.js';\nimport type { TextBlock } from '../types/blocks.js';\nimport type { CompactReport } from '../types/compactor.js';\nimport type {\n CompletedWorkEvidence,\n CompletedWorkSource,\n ContextEvidenceState,\n ToolOutputMetadata,\n} from '../types/context-evidence.js';\nimport type { Message } from '../types/messages.js';\n\nconst MAX_TOOL_CALLS = 80;\nconst MAX_FACTS = 40;\nconst MAX_ERRORS = 20;\nconst MAX_DIGEST_CHARS = 4_000;\n/** Cap for the per-iteration reference scan \u2014 see markAssistantReferencedEvidence. */\nconst RECENT_TOOL_CALL_SCAN_LIMIT = 20;\n/** Cap content fed to file/symbol regex extractors (first N chars). */\nconst EXTRACT_CONTENT_CAP_CHARS = 10_000;\n/** Only scan the last N lines for error patterns \u2014 errors surface at the bottom. */\nconst EXTRACT_ERROR_TAIL_LINES = 200;\n\nconst WRITE_TOOLS = new Set(['edit', 'write', 'replace', 'patch']);\nconst READ_TOOLS = new Set(['read', 'grep', 'glob', 'ls', 'tree']);\n\nexport function createContextEvidenceState(): ContextEvidenceState {\n return {\n sessionGoals: [],\n implicitFacts: [],\n activeErrors: [],\n toolCalls: [],\n fileGraph: {},\n repeatedReads: [],\n completedWork: [],\n updatedAt: Date.now(),\n };\n}\n\nexport interface RecordToolOutputEvidenceInput {\n toolUseId: string;\n toolName: string;\n input: unknown;\n content: string;\n ok: boolean;\n outputBytes?: number | undefined;\n outputTokens?: number | undefined;\n outputLines?: number | undefined;\n}\n\nexport function recordUserIntentEvidence(ctx: Context, text: string): void {\n const intent = normalizeWhitespace(text).slice(0, 700);\n if (!intent) return;\n const state = ensureEvidence(ctx);\n state.currentIntent = { text: intent, updatedAt: Date.now() };\n if (state.sessionGoals.length === 0 || isGoalish(intent)) {\n pushUniqueBounded(state.sessionGoals, intent, 8);\n }\n state.updatedAt = Date.now();\n}\n\nexport function recordToolOutputEvidence(\n ctx: Context,\n input: RecordToolOutputEvidenceInput,\n): ToolOutputMetadata {\n const state = ensureEvidence(ctx);\n // Cap content for regex extraction. File paths and symbol declarations\n // appear near the top of tool output (import blocks, function definitions),\n // so the first 10KB captures them. Without this cap, matchAll() runs over\n // the full output \u2014 e.g. a 50KB file read triggers ~100KB of regex scanning\n // across two patterns in extractSymbols plus the extractFiles pass.\n const scanContent = input.content.length > EXTRACT_CONTENT_CAP_CHARS\n ? input.content.slice(0, EXTRACT_CONTENT_CAP_CHARS)\n : input.content;\n const files = extractFiles(ctx, input.toolName, input.input, scanContent);\n const symbols = extractSymbols(scanContent, input.input);\n const commands = extractCommands(input.toolName, input.input);\n const errors = extractErrors(input.content);\n const summary = summarizeToolOutput(input.toolName, input.input, input.content, {\n files,\n symbols,\n errors,\n ok: input.ok,\n });\n\n const metadata: ToolOutputMetadata = {\n toolUseId: input.toolUseId,\n toolName: input.toolName,\n ok: input.ok,\n inputSummary: summarizeInput(input.input),\n summary,\n files,\n symbols,\n commands,\n errors,\n status: 'seen',\n referenceCount: 0,\n seenAt: Date.now(),\n outputBytes: input.outputBytes,\n outputTokens: input.outputTokens,\n outputLines: input.outputLines,\n };\n\n state.toolCalls.push(metadata);\n if (state.toolCalls.length > MAX_TOOL_CALLS) {\n state.toolCalls.splice(0, state.toolCalls.length - MAX_TOOL_CALLS);\n }\n\n updateFileGraph(state, metadata);\n updateRepeatedReadSignals(state, metadata);\n if (errors.length > 0) {\n for (const err of errors) pushUniqueBounded(state.activeErrors, err, MAX_ERRORS);\n }\n const fact = implicitFactFor(metadata);\n if (fact) pushUniqueBounded(state.implicitFacts, fact, MAX_FACTS);\n state.updatedAt = Date.now();\n return metadata;\n}\n\nexport function markAssistantReferencedEvidence(ctx: Context, text: string): void {\n const state = ensureEvidence(ctx);\n const haystack = text.toLowerCase();\n if (!haystack.trim()) return;\n\n // Only scan the most recent tool calls. The assistant almost always\n // references the files/symbols it just worked on \u2014 older entries are\n // rarely re-referenced. Scanning the full list (up to 80 entries) means\n // worst case: 80 \u00D7 (files + symbols) includes() calls per iteration,\n // each O(responseText.length), which degrades as the conversation grows.\n // The last 20 captures the realistic reference window at \u00BC the cost.\n const recent = state.toolCalls.length > RECENT_TOOL_CALL_SCAN_LIMIT\n ? state.toolCalls.slice(-RECENT_TOOL_CALL_SCAN_LIMIT)\n : state.toolCalls;\n for (const tool of recent) {\n if (!metadataReferencedByText(tool, haystack)) continue;\n tool.status = 'referenced';\n tool.referenceCount++;\n tool.referencedAt = Date.now();\n for (const file of tool.files) {\n const node = state.fileGraph[file];\n if (node) node.referenced = true;\n }\n }\n state.updatedAt = Date.now();\n}\n\nexport function buildContextEvidenceDigest(ctx: Context): string {\n const state = ensureEvidence(ctx);\n const lines: string[] = [];\n\n if (state.currentIntent?.text) {\n lines.push(`intent: ${state.currentIntent.text}`);\n }\n\n const goals = state.sessionGoals.slice(-3);\n if (goals.length > 0) {\n lines.push('session_goals:');\n for (const goal of goals) lines.push(`- ${goal}`);\n }\n\n const activeErrors = state.activeErrors.slice(-5);\n if (activeErrors.length > 0) {\n lines.push('active_errors:');\n for (const err of activeErrors) lines.push(`- ${err}`);\n }\n\n const files = Object.values(state.fileGraph)\n .sort((a, b) => (b.writes - a.writes) || (b.reads - a.reads) || a.path.localeCompare(b.path))\n .slice(0, 12);\n if (files.length > 0) {\n lines.push('dependency_graph:');\n for (const file of files) {\n const actions = [\n file.reads > 0 ? `read ${file.reads}x` : '',\n file.writes > 0 ? `write ${file.writes}x` : '',\n ].filter(Boolean).join(', ');\n const refs = file.referenced ? '; referenced by assistant' : '';\n const via = file.lastToolUseId ? `; last via ${file.lastToolUseId}` : '';\n lines.push(`- ${file.path} (${actions || 'seen'}${refs}${via})`);\n }\n }\n\n const referenced = state.toolCalls\n .filter((tool) => tool.status === 'referenced')\n .slice(-10);\n const recentSeen = state.toolCalls\n .filter((tool) => tool.status === 'seen')\n .slice(-5);\n const trail = [...referenced, ...recentSeen];\n if (trail.length > 0) {\n lines.push('tool_trail:');\n for (const tool of trail) {\n const size = tool.outputTokens ? `; ~${tool.outputTokens} tokens` : '';\n const filesText = tool.files.length > 0 ? `; files=${tool.files.slice(0, 4).join(', ')}` : '';\n const symbolsText = tool.symbols.length > 0 ? `; symbols=${tool.symbols.slice(0, 4).join(', ')}` : '';\n lines.push(\n `- ${tool.toolUseId} ${tool.toolName} ${tool.status}: ${tool.summary}${filesText}${symbolsText}${size}`,\n );\n }\n }\n\n const facts = state.implicitFacts.slice(-8);\n if (facts.length > 0) {\n lines.push('implicit_facts:');\n for (const fact of facts) lines.push(`- ${fact}`);\n }\n\n const digest = lines.join('\\n');\n if (digest.length <= MAX_DIGEST_CHARS) return digest;\n return `${digest.slice(0, MAX_DIGEST_CHARS)}... [+${digest.length - MAX_DIGEST_CHARS} chars]`;\n}\n\nexport function repeatedReadPressure(ctx: Context): number {\n return ensureEvidence(ctx).repeatedReads.reduce((max, item) => Math.max(max, item.count), 0);\n}\n\n/** Marker prefixing the forced evidence-floor system message (also its dedupe key). */\nconst CONTEXT_STATE_MARKER = '[context_state]';\n\n/**\n * Stable issue keys emitted by `checkCompactionQuality` and consumed by\n * `injectEvidenceFloor`. Using typed consts instead of raw string literals\n * ensures the producer/consumer contract is typechecker-enforced \u2014 any new\n * issue key must be added here and both sides will be updated together.\n */\nconst QUALITY_ISSUE = {\n missingIntent: 'missing intent anchor',\n missingPathTrail: 'missing tool/path trail',\n} as const;\n\n/**\n * Deterministic post-compaction sanity check. Cheap and local: records whether\n * the compacted context still carries an intent anchor and a tool/path trail.\n * Shared across all compactors so they report quality the same way (previously\n * only HybridCompactor did). Advisory on its own \u2014 pair with\n * `injectEvidenceFloor` to actually repair a flagged loss.\n */\nexport function checkCompactionQuality(\n ctx: Context,\n opts: {\n collapsedDigest?: string | undefined;\n evidenceDigest?: string | undefined;\n reduced: boolean;\n },\n): CompactReport['quality'] {\n const evidence = ctx.contextEvidence;\n const digest = `${opts.collapsedDigest ?? ''}\\n${opts.evidenceDigest ?? ''}`;\n const hasIntent = Boolean(\n evidence?.currentIntent?.text ||\n /\\b(intent|goal|session_goals|hedef|amac|istiyorum|gerekiyor)\\b/i.test(digest),\n );\n const hasPathTrail = Boolean(\n Object.keys(evidence?.fileGraph ?? {}).length > 0 ||\n (evidence?.toolCalls.length ?? 0) > 0 ||\n /\\b(dependency_graph|tool_trail|files=)\\b/i.test(digest),\n );\n const issues: string[] = [];\n if (opts.reduced && !hasIntent) issues.push(QUALITY_ISSUE.missingIntent);\n if (opts.reduced && !hasPathTrail) issues.push(QUALITY_ISSUE.missingPathTrail);\n return { ok: issues.length === 0, hasIntent, hasPathTrail, issues };\n}\n\n/**\n * Enforce an evidence floor: when `checkCompactionQuality` flags that\n * compaction dropped the intent anchor or tool/path trail, prepend a compact\n * `[context_state]` system message rebuilt from the live evidence state so the\n * session goal is never silently lost. Idempotent (won't double-inject) and a\n * no-op when quality is fine or there is no evidence to inject. Returns true\n * when it injected a block (so the caller re-estimates tokens).\n */\nexport function injectEvidenceFloor(\n ctx: Context,\n quality: CompactReport['quality'] | undefined,\n): boolean {\n if (!quality || quality.ok) return false;\n const needsRepair =\n quality.issues.includes(QUALITY_ISSUE.missingIntent) ||\n quality.issues.includes(QUALITY_ISSUE.missingPathTrail);\n if (!needsRepair) return false;\n\n const digest = buildContextEvidenceDigest(ctx);\n if (!digest.trim()) return false;\n\n const already = ctx.messages.some(\n (m) => typeof m.content === 'string' && m.content.startsWith(CONTEXT_STATE_MARKER),\n );\n if (already) return false;\n\n const block: Message = { role: 'system', content: `${CONTEXT_STATE_MARKER}\\n${digest}` };\n ctx.state.replaceMessages([block, ...ctx.messages]);\n return true;\n}\n\nfunction ensureEvidence(ctx: Context): ContextEvidenceState {\n if (!ctx.contextEvidence) {\n (ctx as never as { contextEvidence: ContextEvidenceState }).contextEvidence =\n createContextEvidenceState();\n }\n // States restored from sessions persisted before the completed-work\n // ledger existed lack the array \u2014 heal in place so recorders can push.\n ctx.contextEvidence.completedWork ??= [];\n return ctx.contextEvidence;\n}\n\n// \u2500\u2500 Completed-work ledger \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** Bound on retained ledger entries \u2014 oldest are dropped first. */\nconst MAX_COMPLETED_WORK = 50;\n/** How many (newest) entries render into the system-prompt block. */\nconst LEDGER_BLOCK_ITEMS = 20;\n\n/** Marker prefixing the ledger's system-prompt block (also used to find/replace it). */\nexport const COMPLETED_WORK_LEDGER_MARKER = '[completed_work_ledger]';\n\nexport interface RecordCompletedWorkInput {\n /** Stable dedupe key, e.g. `task:<id>` \u2014 re-completion updates in place. */\n key: string;\n source: CompletedWorkSource;\n summary: string;\n /** Optional pointer to proof (test run, commit hash, file path). */\n evidence?: string | undefined;\n /** Epoch ms; defaults to now. */\n completedAt?: number | undefined;\n}\n\n/**\n * Append one finished unit of work to the session ledger. The provider request\n * composer renders this state as a volatile tail block; the stable system-prompt\n * prefix is never mutated here.\n */\nexport function recordCompletedWorkEvidence(\n ctx: Context,\n input: RecordCompletedWorkInput,\n): CompletedWorkEvidence {\n const state = ensureEvidence(ctx);\n const entry: CompletedWorkEvidence = {\n key: input.key,\n source: input.source,\n summary: normalizeWhitespace(input.summary).slice(0, 300),\n completedAt: input.completedAt ?? Date.now(),\n ...(input.evidence !== undefined && { evidence: input.evidence }),\n };\n const existing = state.completedWork.findIndex((item) => item.key === entry.key);\n if (existing >= 0) state.completedWork.splice(existing, 1);\n state.completedWork.push(entry);\n if (state.completedWork.length > MAX_COMPLETED_WORK) {\n state.completedWork.splice(0, state.completedWork.length - MAX_COMPLETED_WORK);\n }\n state.updatedAt = Date.now();\n return entry;\n}\n\n/** Render the ledger's system-prompt block text (marker + newest entries). */\nexport function formatCompletedWorkLedger(items: readonly CompletedWorkEvidence[]): string {\n const lines = items\n .slice(-LEDGER_BLOCK_ITEMS)\n .map(\n (item) =>\n `- [${item.source}] ${item.summary}${item.evidence ? ` (evidence: ${item.evidence})` : ''}`,\n );\n return (\n `${COMPLETED_WORK_LEDGER_MARKER}\\n` +\n 'Work already completed this session \u2014 do not redo it; build on it:\\n' +\n lines.join('\\n')\n );\n}\n\n/** Build the current volatile completed-work block without mutating the prompt. */\nexport function buildCompletedWorkLedgerBlock(ctx: Context): TextBlock | undefined {\n const items = ensureEvidence(ctx).completedWork;\n if (items.length === 0) return undefined;\n return {\n type: 'text',\n text: formatCompletedWorkLedger(items),\n cache_control: { type: 'ephemeral' },\n };\n}\n\n/**\n * @deprecated Volatile state must be composed at request time. Kept as a\n * compatibility no-op for embedders importing the old helper.\n */\nexport function syncCompletedWorkLedgerBlock(_ctx: Context): void {\n // Intentionally empty. Mutating ctx.systemPrompt invalidates provider prefix caches.\n}\n\nfunction isGoalish(text: string): boolean {\n return /\\b(goal|objective|task|need|want|implement|fix|improve|refactor|add|remove|hedef|amac|istiyorum|gerekiyor|iyilestir|duzelt|ekle|kaldir)\\b/i.test(text);\n}\n\nfunction normalizeWhitespace(text: string): string {\n return text.replace(/\\s+/g, ' ').trim();\n}\n\nfunction pushUniqueBounded(list: string[], value: string, max: number): void {\n const normalized = normalizeWhitespace(value);\n /* v8 ignore next -- unreachable: every caller passes already-normalized non-empty text */\n if (!normalized) return;\n const existing = list.findIndex((item) => item.toLowerCase() === normalized.toLowerCase());\n if (existing >= 0) list.splice(existing, 1);\n list.push(normalized);\n if (list.length > max) list.splice(0, list.length - max);\n}\n\nfunction extractFiles(\n ctx: Context,\n toolName: string,\n input: unknown,\n content: string,\n): string[] {\n const out = new Set<string>();\n for (const value of inputPathValues(input)) addPath(ctx, out, value);\n\n if (toolName === 'grep' || toolName === 'glob' || toolName === 'bash') {\n const re = /(?:(?:[A-Za-z]:)?[./\\\\]?[\\w@.-]+(?:[\\\\/][\\w@(). -]+)+\\.[A-Za-z0-9]{1,12})/g;\n for (const match of content.matchAll(re)) addPath(ctx, out, match[0]);\n }\n\n return [...out].slice(0, 30);\n}\n\nfunction inputPathValues(input: unknown): string[] {\n const values: string[] = [];\n const visit = (value: unknown, key?: string): void => {\n if (typeof value === 'string') {\n if (key && /^(path|file|files|fromFile|toFile|dir|cwd)$/i.test(key)) values.push(value);\n return;\n }\n if (Array.isArray(value)) {\n for (const item of value) visit(item, key);\n return;\n }\n if (!value || typeof value !== 'object') return;\n for (const [k, v] of Object.entries(value as Record<string, unknown>)) visit(v, k);\n };\n visit(input);\n return values;\n}\n\nfunction addPath(ctx: Context, out: Set<string>, raw: string): void {\n const clean = raw.trim().replace(/^[\"'`]+|[\"'`),;:]+$/g, '');\n if (!clean || clean.length > 260) return;\n let normalized = clean.replace(/\\\\/g, '/');\n try {\n const abs = path.isAbsolute(clean) ? path.resolve(clean) : null;\n if (abs) {\n const rel = path.relative(ctx.projectRoot, abs);\n if (!rel.startsWith('..') && !path.isAbsolute(rel)) {\n normalized = rel.replace(/\\\\/g, '/');\n }\n }\n } catch {\n // Keep the best-effort normalized string.\n }\n if (normalized.length > 0) out.add(normalized);\n}\n\nfunction extractSymbols(content: string, input: unknown): string[] {\n const out = new Set<string>();\n const patterns = [\n /\\b(?:function|class|interface|type|enum|const|let|var|def|fn|struct)\\s+([A-Za-z_$][\\w$]*)/g,\n /\\b(?:export\\s+)?(?:async\\s+)?function\\s+([A-Za-z_$][\\w$]*)/g,\n ];\n for (const re of patterns) {\n for (const match of content.matchAll(re)) {\n if (match[1]) out.add(match[1]);\n if (out.size >= 30) break;\n }\n }\n\n const pattern = input && typeof input === 'object'\n ? (input as Record<string, unknown>)['pattern']\n : undefined;\n if (typeof pattern === 'string' && /^[A-Za-z_$][\\w$]*$/.test(pattern)) {\n out.add(pattern);\n }\n\n return [...out].slice(0, 30);\n}\n\nfunction extractCommands(toolName: string, input: unknown): string[] {\n if (toolName !== 'bash' && toolName !== 'exec' && toolName !== 'shell') return [];\n if (!input || typeof input !== 'object') return [];\n const command = (input as Record<string, unknown>)['command'];\n if (typeof command !== 'string') return [];\n return [command.slice(0, 220)];\n}\n\nfunction extractErrors(content: string): string[] {\n const allLines = content.split(/\\r?\\n/);\n // Only scan the last N lines \u2014 errors and stack traces surface at the\n // bottom of tool output. Scanning all lines means one regex test per line,\n // so a 2000-line file read costs 2000 regex evaluations for no gain since\n // the interesting errors are always at the tail.\n const lines = allLines.length > EXTRACT_ERROR_TAIL_LINES\n ? allLines.slice(-EXTRACT_ERROR_TAIL_LINES)\n : allLines;\n const errors: string[] = [];\n for (const line of lines) {\n if (!/\\b(error|exception|failed|failure|fatal|panic|timeout|denied|enoent|eacces|eperm|typeerror|syntaxerror)\\b/i.test(line)) continue;\n errors.push(normalizeWhitespace(line).slice(0, 260));\n if (errors.length >= 5) break;\n }\n return errors;\n}\n\nfunction summarizeInput(input: unknown): string | undefined {\n if (!input || typeof input !== 'object') return undefined;\n const obj = input as Record<string, unknown>;\n const parts: string[] = [];\n for (const key of ['path', 'file', 'pattern', 'glob', 'command']) {\n const value = obj[key];\n if (typeof value === 'string') parts.push(`${key}=${value.slice(0, 160)}`);\n }\n return parts.length > 0 ? parts.join(', ') : undefined;\n}\n\nfunction summarizeToolOutput(\n toolName: string,\n input: unknown,\n content: string,\n opts: { files: string[]; symbols: string[]; errors: string[]; ok: boolean },\n): string {\n if (!opts.ok && opts.errors.length > 0) return opts.errors[0] ?? `${toolName} failed`;\n if (toolName === 'read' && opts.files[0]) return `read ${opts.files[0]}`;\n if (toolName === 'grep') {\n const pattern = input && typeof input === 'object'\n ? (input as Record<string, unknown>)['pattern']\n : undefined;\n return `searched ${typeof pattern === 'string' ? pattern : 'pattern'} (${opts.files.length} file hint(s))`;\n }\n if ((toolName === 'edit' || toolName === 'write') && opts.files[0]) {\n return `${toolName === 'write' ? 'wrote' : 'edited'} ${opts.files[0]}`;\n }\n const firstLine = normalizeWhitespace(content.split(/\\r?\\n/).find((line) => line.trim()) ?? '');\n return firstLine ? firstLine.slice(0, 220) : `${toolName} returned no text`;\n}\n\nfunction updateFileGraph(state: ContextEvidenceState, metadata: ToolOutputMetadata): void {\n const writes = WRITE_TOOLS.has(metadata.toolName) ? 1 : 0;\n const reads = writes === 0 && (READ_TOOLS.has(metadata.toolName) || metadata.files.length > 0)\n ? 1\n : 0;\n for (const file of metadata.files) {\n const existing = state.fileGraph[file] ?? {\n path: file,\n reads: 0,\n writes: 0,\n tools: [],\n referenced: false,\n };\n existing.reads += reads;\n existing.writes += writes;\n existing.lastToolUseId = metadata.toolUseId;\n pushUniqueBounded(existing.tools, `${metadata.toolName}#${metadata.toolUseId}`, 8);\n state.fileGraph[file] = existing;\n }\n}\n\nfunction updateRepeatedReadSignals(state: ContextEvidenceState, metadata: ToolOutputMetadata): void {\n if (metadata.toolName !== 'read' || metadata.files.length === 0) {\n state.lastReadPath = undefined;\n return;\n }\n const file = metadata.files[0] as string;\n if (state.lastReadPath === file) {\n const existing = state.repeatedReads.find((item) => item.file === file);\n if (existing) {\n existing.count++;\n existing.lastToolUseId = metadata.toolUseId;\n } else {\n state.repeatedReads.push({ file, count: 2, lastToolUseId: metadata.toolUseId });\n }\n if (state.repeatedReads.length > 10) state.repeatedReads.shift();\n }\n state.lastReadPath = file;\n}\n\nfunction implicitFactFor(metadata: ToolOutputMetadata): string | undefined {\n if (metadata.errors.length > 0) return `${metadata.toolName}#${metadata.toolUseId} exposed error: ${metadata.errors[0]}`;\n if (metadata.toolName === 'read' && metadata.files[0]) {\n const size = metadata.outputLines ? ` (${metadata.outputLines} line(s) returned)` : '';\n return `read ${metadata.files[0]}${size}`;\n }\n if ((metadata.toolName === 'edit' || metadata.toolName === 'write') && metadata.files[0]) {\n return `${metadata.toolName} changed ${metadata.files[0]}`;\n }\n if (metadata.status === 'referenced') return `${metadata.toolName}#${metadata.toolUseId} was referenced`;\n return undefined;\n}\n\nfunction metadataReferencedByText(metadata: ToolOutputMetadata, haystack: string): boolean {\n for (const file of metadata.files) {\n const f = file.toLowerCase();\n const base = path.basename(file).toLowerCase();\n if (f && haystack.includes(f)) return true;\n if (base && haystack.includes(base)) return true;\n }\n for (const symbol of metadata.symbols) {\n if (symbol.length >= 3 && haystack.includes(symbol.toLowerCase())) return true;\n }\n for (const err of metadata.errors) {\n const head = err.slice(0, 80).toLowerCase();\n if (head.length >= 12 && haystack.includes(head)) return true;\n }\n return false;\n}\n", "/** Assert a value is neither null nor undefined. Throws if it is.\n * Useful after optional chaining and indexed access when the\n * control flow guarantees the value exists but TypeScript can't\n * prove it (e.g. after a check on a related field). */\nexport function expectDefined<T>(value: T | null | undefined, label?: string): T {\n if (value === null || value === undefined) {\n const err = new Error(label ? `Expected ${label} to be defined` : 'Expected value to be defined');\n err.name = 'ExpectDefinedError';\n throw err;\n }\n return value;\n}\n", "import type { ContentBlock, ToolResultBlock, ToolUseBlock } from '../types/blocks.js';\nimport type { Message } from '../types/messages.js';\nimport { expectDefined } from './expect-defined.js';\nexport interface MessageRepairReport {\n changed: boolean;\n removedToolUses: string[];\n removedToolResults: string[];\n removedMessages: number;\n}\n\nexport interface MessageRepairResult {\n messages: Message[];\n report: MessageRepairReport;\n}\n\n/**\n * Repair provider-level tool-call adjacency invariants.\n *\n * Anthropic requires every assistant `tool_use` block to have a matching\n * `tool_result` block in the immediately following user message. Manual\n * context surgery (summary/prune) can cut through the middle of such an\n * exchange. This function removes only the now-orphaned protocol blocks,\n * preserving surrounding text/images/thinking blocks where possible.\n */\nexport function repairToolUseAdjacency(messages: Message[]): MessageRepairResult {\n const removedToolUses: string[] = [];\n const removedToolResults: string[] = [];\n let removedMessages = 0;\n let changed = false;\n const out: Message[] = [];\n\n for (let i = 0; i < messages.length; i++) {\n const original = expectDefined(messages[i]);\n let msg = original;\n\n if (hasToolUse(msg)) {\n const nextIds = toolResultIds(messages[i + 1]);\n const filtered = mapContent(msg, (blocks) => {\n const next: ContentBlock[] = [];\n for (const block of blocks) {\n if (block.type === 'tool_use' && !nextIds.has(block.id)) {\n removedToolUses.push(block.id);\n changed = true;\n continue;\n }\n next.push(block);\n }\n return next;\n });\n msg = filtered ?? msg;\n }\n\n if (hasToolResult(msg)) {\n const allowed = toolUseIds(out[out.length - 1]);\n const filtered = mapContent(msg, (blocks) => {\n const next: ContentBlock[] = [];\n for (const block of blocks) {\n if (block.type === 'tool_result' && !allowed.has(block.tool_use_id)) {\n removedToolResults.push(block.tool_use_id);\n changed = true;\n continue;\n }\n next.push(block);\n }\n return next;\n });\n msg = filtered ?? msg;\n }\n\n if (isEmptyMessage(msg)) {\n removedMessages++;\n changed = true;\n continue;\n }\n out.push(msg);\n }\n\n return {\n messages: changed ? out : messages,\n report: { changed, removedToolUses, removedToolResults, removedMessages },\n };\n}\n\nfunction hasToolUse(msg: Message | undefined): boolean {\n return contentBlocks(msg).some((b): b is ToolUseBlock => b.type === 'tool_use');\n}\n\nfunction hasToolResult(msg: Message | undefined): boolean {\n return contentBlocks(msg).some((b): b is ToolResultBlock => b.type === 'tool_result');\n}\n\nfunction toolUseIds(msg: Message | undefined): Set<string> {\n const ids = new Set<string>();\n if (msg?.role !== 'assistant') return ids;\n for (const block of contentBlocks(msg)) {\n if (block.type === 'tool_use') ids.add(block.id);\n }\n return ids;\n}\n\nfunction toolResultIds(msg: Message | undefined): Set<string> {\n const ids = new Set<string>();\n if (msg?.role !== 'user') return ids;\n for (const block of contentBlocks(msg)) {\n if (block.type === 'tool_result') ids.add(block.tool_use_id);\n }\n return ids;\n}\n\nfunction contentBlocks(msg: Message | undefined): ContentBlock[] {\n return msg && Array.isArray(msg.content) ? msg.content : [];\n}\n\nfunction mapContent(msg: Message, fn: (blocks: ContentBlock[]) => ContentBlock[]): Message | null {\n if (!Array.isArray(msg.content)) return msg;\n const next = fn(msg.content);\n if (next.length === msg.content.length && next.every((b, idx) => b === msg.content[idx])) {\n return msg;\n }\n return { ...msg, content: next };\n}\n\n/**\n * True when a message content payload carries meaningful information for\n * the provider: non-whitespace text, a tool call/result, thinking with\n * text or a signature, or any other block type.\n *\n * False for empty strings/arrays and for arrays whose only blocks are\n * empty or whitespace-only text \u2014 the shape persisted when a stream is\n * interrupted before the first meaningful delta (issue #271). Strict\n * providers reject such assistant turns, so repair and replay paths must\n * treat them as empty.\n */\nexport function hasMeaningfulContent(content: Message['content']): boolean {\n if (typeof content === 'string') return content.trim().length > 0;\n for (const block of content) {\n if (block.type === 'text') {\n if (block.text.trim().length > 0) return true;\n continue;\n }\n if (block.type === 'thinking') {\n // Signature-only thinking blocks are valid and required for replay;\n // blocks with neither text nor signature are provider-rejected noise.\n if (block.thinking.trim().length > 0 || block.signature) return true;\n continue;\n }\n // tool_use, tool_result, image, redacted_thinking, \u2026 \u2014 always meaningful.\n return true;\n }\n return false;\n}\n\nfunction isEmptyMessage(msg: Message): boolean {\n return !hasMeaningfulContent(msg.content);\n}\n", "import type { JSONSchema } from '../types/tool.js';\n\nexport interface ToolWireDefinitionLike {\n name: string;\n description?: string | undefined;\n inputSchema: unknown;\n}\n\nexport interface CompactToolDefinitionForWireOptions {\n /** Top-level tool description budget. */\n descriptionMaxChars?: number | undefined;\n /** Per-JSON-Schema `description` annotation budget. */\n schemaDescriptionMaxChars?: number | undefined;\n}\n\nexport interface CompactWireToolDefinition {\n name: string;\n description: string;\n inputSchema: Record<string, unknown>;\n}\n\nconst TOOL_DESCRIPTION_MAX_CHARS = 400;\nconst SCHEMA_DESCRIPTION_MAX_CHARS = 120;\n\nconst compactCache = new WeakMap<object, CompactWireToolDefinition>();\n\n/**\n * Return the provider-wire version of a tool definition.\n *\n * Tool schemas remain structurally intact: validation keywords, property\n * names, required fields, enum values, and nested shapes are preserved. The\n * only reduction is on human prose annotations (`description`), which are the\n * largest repeated cost in provider tool declarations.\n */\nexport function compactToolDefinitionForWire(\n tool: ToolWireDefinitionLike,\n opts: CompactToolDefinitionForWireOptions = {},\n): CompactWireToolDefinition {\n const useDefaultOptions =\n opts.descriptionMaxChars === undefined && opts.schemaDescriptionMaxChars === undefined;\n if (useDefaultOptions && typeof tool === 'object' && tool !== null) {\n const cached = compactCache.get(tool);\n if (cached) return cached;\n }\n\n const compact: CompactWireToolDefinition = {\n name: tool.name,\n description: compactDescription(\n tool.description ?? '',\n opts.descriptionMaxChars ?? TOOL_DESCRIPTION_MAX_CHARS,\n ),\n inputSchema: normalizeTopLevelToolSchema(\n compactSchemaDescriptions(\n tool.inputSchema,\n opts.schemaDescriptionMaxChars ?? SCHEMA_DESCRIPTION_MAX_CHARS,\n ),\n ),\n };\n\n if (useDefaultOptions && typeof tool === 'object' && tool !== null) {\n compactCache.set(tool, compact);\n }\n return compact;\n}\n\n/**\n * Tool inputs are always JSON objects, but dynamically supplied MCP/plugin\n * schemas sometimes express that object as a top-level oneOf/anyOf/allOf.\n * Anthropic-family endpoints reject those combinators at the input_schema\n * root (including when reached through an OpenAI-compatible gateway such as\n * OmniRoute). Keep nested combinators intact and flatten only the root.\n * Runtime validation still uses the tool's original schema.\n */\nexport function normalizeTopLevelToolSchema(\n schema: Record<string, unknown>,\n): Record<string, unknown> {\n const combinators = (['oneOf', 'anyOf', 'allOf'] as const)\n .map((keyword) => ({ keyword, branches: schema[keyword] }))\n .filter((entry): entry is { keyword: 'oneOf' | 'anyOf' | 'allOf'; branches: unknown[] } =>\n Array.isArray(entry.branches),\n );\n if (combinators.length === 0) return schema;\n\n const out: Record<string, unknown> = { ...schema, type: 'object' };\n delete out['oneOf'];\n delete out['anyOf'];\n delete out['allOf'];\n\n const properties: Record<string, unknown> = isRecord(schema['properties'])\n ? { ...schema['properties'] }\n : {};\n let required = stringSet(schema['required']);\n\n for (const { keyword, branches } of combinators) {\n const objectBranches = branches.filter(isRecord);\n for (const branch of objectBranches) {\n if (isRecord(branch['properties'])) Object.assign(properties, branch['properties']);\n }\n\n const branchRequired = objectBranches.map((branch) => stringSet(branch['required']));\n if (keyword === 'allOf') {\n for (const fields of branchRequired) for (const field of fields) required.add(field);\n } else if (branchRequired.length > 0) {\n const common = new Set(\n [...branchRequired[0]!].filter((field) =>\n branchRequired.slice(1).every((fields) => fields.has(field)),\n ),\n );\n required = new Set([...required, ...common]);\n }\n }\n\n out['properties'] = properties;\n if (required.size > 0) out['required'] = [...required];\n else delete out['required'];\n return out;\n}\n\nfunction stringSet(value: unknown): Set<string> {\n return new Set(\n Array.isArray(value) ? value.filter((item): item is string => typeof item === 'string') : [],\n );\n}\n\nexport function compactSchemaDescriptions(\n schema: unknown,\n maxDescriptionChars = SCHEMA_DESCRIPTION_MAX_CHARS,\n): Record<string, unknown> {\n const compact = compactSchemaNode(schema, maxDescriptionChars);\n return isRecord(compact) ? compact : { type: 'object', properties: {} };\n}\n\nfunction compactSchemaNode(node: unknown, maxDescriptionChars: number): unknown {\n if (Array.isArray(node)) {\n return node.map((item) => compactSchemaNode(item, maxDescriptionChars));\n }\n if (!isRecord(node)) return node;\n\n const out: JSONSchema = {};\n for (const [key, value] of Object.entries(node)) {\n if (key === 'description' && typeof value === 'string') {\n out[key] = compactDescription(value, maxDescriptionChars);\n } else {\n out[key] = compactSchemaNode(value, maxDescriptionChars);\n }\n }\n return out;\n}\n\nexport function compactDescription(text: string, maxChars: number): string {\n const normalized = text.replace(/\\s+/g, ' ').trim();\n if (normalized.length <= maxChars) return normalized;\n if (maxChars <= 20) return normalized.slice(0, maxChars);\n\n const hardLimit = maxChars - 12;\n const boundary = findSemanticBoundary(normalized, hardLimit);\n const head = normalized.slice(0, boundary > 0 ? boundary : hardLimit).trimEnd();\n return `${head} ...`;\n}\n\nexport function findSemanticBoundary(text: string, limit: number): number {\n const punctuation = Math.max(\n text.lastIndexOf('. ', limit),\n text.lastIndexOf('; ', limit),\n text.lastIndexOf(': ', limit),\n );\n if (punctuation >= Math.floor(limit * 0.45)) return punctuation + 1;\n\n const comma = text.lastIndexOf(', ', limit);\n if (comma >= Math.floor(limit * 0.6)) return comma + 1;\n\n const space = text.lastIndexOf(' ', limit);\n return space >= Math.floor(limit * 0.6) ? space : limit;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return !!value && typeof value === 'object' && !Array.isArray(value);\n}\n", "import type { Message } from '../types/messages.js';\nimport { compactToolDefinitionForWire } from './tool-wire-compact.js';\n\n/**\n * Shared token estimation with JSON.stringify caching.\n * Avoids repeated stringification of tool input objects.\n *\n * ## Calibration\n *\n * `estimateRequestTokens` uses a fixed 3.5 chars/token heuristic \u2014 a\n * conservative overestimate that prevents underestimation but reduces\n * accuracy. After each API call, call `recordActualUsage()` with the\n * provider-authoritative effective prompt tokens (`input + cacheRead +\n * cacheWrite` after adapter normalization). The module maintains a rolling\n * average of `actual / estimated` ratio (EWM, \u03B1=0.3) and applies it to\n * subsequent calls via `estimateRequestTokensCalibrated`.\n *\n * Calibration is per-module (shared across all callers), which is\n * sufficient: the chars/token ratio is a property of the tokenizer,\n * not the model. Uncalibrated calls (before any samples, or when\n * `recordActualUsage` is not called) fall back to the uncalibrated\n * estimate so nothing breaks.\n */\n\nconst RoughTokenEstimate = (text: string, charsPerToken = 3.5): number =>\n Math.max(1, Math.ceil(text.length / charsPerToken));\n\n/** Calibration state: actual/estimated ratio via exponential weighted moving average. */\ninterface CalState {\n ratio: number; // current calibration multiplier (actual / estimated)\n count: number; // number of samples recorded\n prevEst: number; // estimated tokens from the most recent estimateRequestTokens call\n}\n\n/** EWM \u03B1 \u2014 higher = faster adaptation, more volatile. */\nconst CAL_ALPHA = 0.3;\n\n/**\n * Calibration is keyed so that, in a multi-agent / model-switching process,\n * each (provider, model) tokenizer gets its own ratio instead of all of them\n * collapsing onto one shared number. Callers that don't pass a key use the\n * shared `__global__` bucket \u2014 that preserves the original single-session\n * behavior and keeps all existing call sites working unchanged.\n */\nconst CALIBRATION_GLOBAL_KEY = '__global__';\nconst _cals = new Map<string, CalState>();\n\nfunction calState(key: string): CalState {\n let state = _cals.get(key);\n if (!state) {\n state = { ratio: 1.0, count: 0, prevEst: 0 };\n _cals.set(key, state);\n }\n return state;\n}\n\nconst MIN_SAMPLES_FOR_CALIBRATION = 3;\n\n/**\n * Fallback chars/token ratios per model family for providers that don't return\n * usage data. Used when `recordActualUsage` receives zero/negative tokens and\n * we have enough samples to trust the fallback. Keys are lowercase prefixes.\n */\nconst MODEL_FAMILY_RATIO: Record<string, number> = {\n // Anthropic: ~3.8-4.0 chars/token depending on model\n claude: 3.8,\n // OpenAI: ~4.0 chars/token\n 'gpt-4': 4.0,\n 'gpt-3.5': 4.0,\n // Google: ~3.5 chars/token\n gemini: 3.5,\n // DeepSeek: ~3.5 chars/token\n deepseek: 3.5,\n};\n\n/**\n * Cache of computed estimates keyed by a compact HASH of the stringified input \u2014\n * NOT the stringified input itself. The estimator is called per tool_use and per\n * tool_result on every context-window check, and the source strings are full tool\n * payloads (file reads, command output). Keying the Map by those strings meant the\n * cache retained up to 50 000 full payloads \u2014 hundreds of MB \u2014 for a value that is\n * a single number. We now key by `\"<len>:<djb2>\"` (\u224815 chars) and never retain the\n * payload. A hash collision (same length AND djb2) at worst returns a slightly-off\n * heuristic token estimate, which only nudges compaction timing \u2014 never correctness.\n */\nconst ESTIMATE_CACHE = new Map<string, number>();\n/** Insertion-order queue for O(1) LRU eviction: shift from front on overcapacity. */\nconst _estimateCacheOrder: string[] = [];\n\nconst ESTIMATE_CACHE_MAX_SIZE = 50_000;\n\n/** Compact collision-resistant key: length prefix + 32-bit DJB2 of the source. */\nfunction estimateCacheKey(source: string): string {\n let h = 5381;\n for (let i = 0; i < source.length; i++) {\n h = ((h << 5) + h + source.charCodeAt(i)) | 0;\n }\n return `${source.length}:${h >>> 0}`;\n}\n\nfunction getCachedEstimate(source: string, compute: (source: string) => number): number {\n const key = estimateCacheKey(source);\n const existing = ESTIMATE_CACHE.get(key);\n if (existing !== undefined) return existing;\n if (ESTIMATE_CACHE.size >= ESTIMATE_CACHE_MAX_SIZE) {\n // Evict oldest half \u2014 O(1) per eviction (array shift + Map.delete) instead\n // of O(n) iteration over all 50 000 keys in the Map.\n while (ESTIMATE_CACHE.size > Math.floor(ESTIMATE_CACHE_MAX_SIZE / 2)) {\n const oldest = _estimateCacheOrder.shift();\n if (oldest !== undefined) ESTIMATE_CACHE.delete(oldest);\n }\n }\n // Compute on the full source (never retained); only the hash key + number stay.\n const estimate = compute(source);\n ESTIMATE_CACHE.set(key, estimate);\n _estimateCacheOrder.push(key);\n return estimate;\n}\n\n/**\n * Estimate tokens for a tool_use block input.\n * Caches the stringified result keyed by the stable string representation\n * to avoid repeated JSON.stringify calls during context window checks.\n */\nexport function estimateToolInputTokens(input: unknown): number {\n if (typeof input === 'string') return RoughTokenEstimate(input);\n if (input === null || typeof input !== 'object') {\n return RoughTokenEstimate(String(input));\n }\n // JSON.stringify is called once to form the cache key; RoughTokenEstimate\n // is deferred only on cache miss (compute callback), not wrapped unnecessarily.\n return getCachedEstimate(JSON.stringify(input), (key) => RoughTokenEstimate(key));\n}\n\n/**\n * Estimate tokens for a tool_result content.\n */\nexport function estimateToolResultTokens(content: string | unknown): number {\n if (typeof content === 'string') return RoughTokenEstimate(content);\n return getCachedEstimate(JSON.stringify(content), (key) => RoughTokenEstimate(key));\n}\n\n/**\n * Estimate tokens for a text block.\n */\nexport function estimateTextTokens(text: string): number {\n return RoughTokenEstimate(text);\n}\n\n/**\n * Compute and cache the token estimate for a single message. This is the\n * canonical per-message estimator \u2014 called once by ConversationState on\n * append/replace so the O(n\u00B7m) content-block walk happens at mutation time,\n * not on every context-pressure check.\n */\nexport function computeMessageTokens(msg: Message): number {\n if (typeof msg.content === 'string') return estimateTextTokens(msg.content);\n let total = 0;\n for (const b of msg.content) {\n if (b.type === 'text') total += estimateTextTokens(b.text);\n else if (b.type === 'tool_use') total += estimateToolInputTokens(b.input);\n else if (b.type === 'tool_result') total += estimateToolResultTokens(b.content);\n else total += RoughTokenEstimate(JSON.stringify(b));\n }\n return total;\n}\n\n/**\n * Estimate tokens for an array of messages (text + tool I/O), using the shared\n * 3.5 chars/token basis. This is the single canonical message-array estimator \u2014\n * compactors, the context_manager tool, and the `/context` display all route\n * through it so the number a user sees matches the number compaction decides on.\n *\n * When a message carries a pre-computed `_estTokens` field (set by\n * ConversationState on append/replace), it is used directly instead of\n * re-walking the content blocks \u2014 turning the O(n\u00B7m) scan into an O(n)\n * sum for fully-cached arrays.\n */\nexport function estimateMessageTokens(messages: readonly Message[]): number {\n let total = 0;\n for (const m of messages) {\n if (typeof m._estTokens === 'number' && m._estTokens > 0) {\n total += m._estTokens;\n continue;\n }\n total += computeMessageTokens(m);\n }\n return total;\n}\n\n/**\n * Real-usage-anchored input-token count. Given the provider's authoritative\n * prompt-token count from the last response (`anchorTokens`, a REAL number) and\n * the `messages.length` of the request that produced it (`anchorMsgCount`),\n * returns `anchorTokens + estimate(messages appended since)` \u2014 so everything up\n * to the last turn is exact and only the newest, not-yet-sent messages are\n * estimated. This is deliberately NOT calibrated: the base is already real, and\n * on the next response the whole thing re-anchors to the new real count.\n *\n * Returns `null` when there is no usable anchor (no response yet, or the\n * message array shrank below the anchor \u2014 e.g. after compaction \u2014 in which case\n * the caller falls back to a full estimate until the next response re-anchors).\n */\nexport function realAnchoredInputTokens(\n messages: readonly Message[],\n anchorTokens: number | undefined,\n anchorMsgCount: number | undefined,\n): number | null {\n if (typeof anchorTokens !== 'number' || anchorTokens <= 0) return null;\n if (typeof anchorMsgCount !== 'number' || anchorMsgCount < 0) return null;\n if (messages.length < anchorMsgCount) return null;\n const delta = anchorMsgCount === messages.length ? 0 : estimateMessageTokens(messages.slice(anchorMsgCount));\n return anchorTokens + delta;\n}\n\n/**\n * Rough estimate of tokens in a tool definition (name + description + schema).\n * Accounts for the JSON-serialized inputSchema which is sent to the API\n * but NOT included in roughEstimate(content).\n */\nexport function estimateToolDefTokens(tool: {\n name: string;\n description?: string | undefined;\n inputSchema: unknown;\n}): number {\n // Fast path: pre-computed by ToolRegistry at registration time.\n const cached = (tool as { _estDefTokens?: number | undefined })._estDefTokens;\n if (typeof cached === 'number' && cached > 0) return cached;\n\n const compact = compactToolDefinitionForWire(tool);\n return (\n RoughTokenEstimate(tool.name) +\n RoughTokenEstimate(compact.description) +\n RoughTokenEstimate(JSON.stringify(compact.inputSchema))\n );\n}\n\n/**\n * Estimate the total API request token count: system prompt + tool definitions\n * + conversation messages. Use this for context-window bar calculations\n * instead of roughEstimate (which only counts messages).\n *\n * The overhead ratio (overhead / messages) varies by conversation length:\n * - Short conversations (< 10 messages): ~30-50% overhead (large system+tools)\n * - Medium (10-50 messages): ~15-30%\n * - Long (> 50 messages): ~5-15%\n *\n * Returns { messages, systemPrompt, tools, total } for debugging display.\n */\nexport interface RequestTokenBreakdown {\n messages: number;\n systemPrompt: number;\n tools: number;\n total: number;\n}\n\nexport function estimateRequestTokens(\n messages: unknown,\n systemPrompt: unknown,\n tools: { name: string; description?: string | undefined; inputSchema: unknown }[],\n calibrationKey: string = CALIBRATION_GLOBAL_KEY,\n): RequestTokenBreakdown {\n // Messages: apply the same logic as roughEstimate\n let messagesTokens = 0;\n if (typeof messages === 'string') {\n messagesTokens = RoughTokenEstimate(messages);\n } else if (Array.isArray(messages)) {\n for (const m of messages) {\n if (typeof m === 'object' && m !== null && 'content' in m) {\n // Fast path: pre-computed per-message token estimate (set by\n // ConversationState on append/replace). Skips the O(m) content-block\n // walk entirely for cached messages.\n const cached = (m as { _estTokens?: number | undefined })._estTokens;\n if (typeof cached === 'number' && cached > 0) {\n messagesTokens += cached;\n continue;\n }\n const content = (m as { content: unknown }).content;\n if (typeof content === 'string') {\n messagesTokens += RoughTokenEstimate(content);\n } else if (Array.isArray(content)) {\n for (const b of content) {\n if (typeof b === 'object' && b !== null) {\n if ((b as { type?: string | undefined }).type === 'text') {\n messagesTokens += RoughTokenEstimate((b as { text: string }).text);\n } else {\n messagesTokens += RoughTokenEstimate(JSON.stringify(b));\n }\n }\n }\n }\n }\n }\n }\n\n // System prompt\n let systemTokens = 0;\n if (typeof systemPrompt === 'string') {\n systemTokens = RoughTokenEstimate(systemPrompt);\n } else if (Array.isArray(systemPrompt)) {\n for (const b of systemPrompt) {\n if (\n typeof b === 'object' &&\n b !== null &&\n (b as { type?: string | undefined }).type === 'text'\n ) {\n systemTokens += RoughTokenEstimate((b as { text: string }).text);\n }\n }\n }\n\n // Tool definitions\n let toolsTokens = 0;\n for (const t of tools) {\n toolsTokens += estimateToolDefTokens(t);\n }\n\n const total = messagesTokens + systemTokens + toolsTokens;\n\n // Record the raw estimate for calibration: the next recordActualUsage()\n // call will pair this against the actual API usage so the rolling ratio\n // stays in sync with the real chars/token ratio of the content.\n calState(calibrationKey).prevEst = total;\n\n return {\n messages: messagesTokens,\n systemPrompt: systemTokens,\n tools: toolsTokens,\n total,\n };\n}\n\n/**\n * Record the actual API input token count after a provider call so\n * `estimateRequestTokensCalibrated` can self-correct on subsequent calls.\n *\n * Prefer passing `estimatedInputTokens` explicitly (the calibrated pre-flight\n * estimate from the middleware) \u2014 this avoids race conditions when other code\n * also calls `estimateRequestTokens` between the pre-flight and this call\n * (e.g. audit logging in agent.ts).\n *\n * When `estimatedInputTokens` is omitted, falls back to the keyed bucket's\n * `prevEst` for backward compatibility with callers that don't have the\n * pre-flight value. `calibrationKey` selects the per-(provider,model) bucket\n * (defaults to the shared global bucket).\n */\nexport function recordActualUsage(\n actualInputTokens: number,\n estimatedInputTokens?: number,\n calibrationKey: string = CALIBRATION_GLOBAL_KEY,\n): void {\n if (actualInputTokens <= 0) return;\n const cal = calState(calibrationKey);\n const est = estimatedInputTokens ?? cal.prevEst;\n if (est <= 0) return;\n\n const sampleRatio = actualInputTokens / est;\n if (cal.count === 0) {\n cal.ratio = sampleRatio;\n } else {\n // EWM: new = \u03B1 * sample + (1-\u03B1) * old \u2192 \u03B1=0.3 = fast initial converge\n cal.ratio = CAL_ALPHA * sampleRatio + (1 - CAL_ALPHA) * cal.ratio;\n }\n // Sanity bound: keep the rolling ratio within [0.5, 1.5] so a sequence\n // of bad samples can't blow up the calibration for everyone.\n cal.ratio = Math.min(1.5, Math.max(0.5, cal.ratio));\n cal.count++;\n}\n\n/**\n * Returns the current calibration state for a bucket. Exposed for debugging\n * and tests \u2014 not needed by normal callers.\n */\nexport function getCalibrationState(calibrationKey: string = CALIBRATION_GLOBAL_KEY): {\n ratio: number;\n count: number;\n calibrated: boolean;\n} {\n const cal = calState(calibrationKey);\n return {\n ratio: cal.ratio,\n count: cal.count,\n calibrated: cal.count >= MIN_SAMPLES_FOR_CALIBRATION,\n };\n}\n\n/**\n * Like `estimateRequestTokens` but applies the rolling calibration factor\n * so context pressure readings converge on reality within a few iterations.\n *\n * Before any `recordActualUsage` samples are collected, returns the same\n * result as `estimateRequestTokens` (ratio = 1.0, no distortion).\n * After `MIN_SAMPLES_FOR_CALIBRATION` samples, applies the calibrated\n * multiplier capped to the range [0.5, 1.5] as a sanity bound.\n */\nexport function estimateRequestTokensCalibrated(\n messages: unknown,\n systemPrompt: unknown,\n tools: { name: string; description?: string | undefined; inputSchema: unknown }[],\n calibrationKey: string = CALIBRATION_GLOBAL_KEY,\n): RequestTokenBreakdown {\n const result = estimateRequestTokens(messages, systemPrompt, tools, calibrationKey);\n const cal = calState(calibrationKey);\n\n if (cal.count >= MIN_SAMPLES_FOR_CALIBRATION) {\n const safeRatio = Math.min(1.5, Math.max(0.5, cal.ratio));\n return {\n messages: Math.round(result.messages * safeRatio),\n systemPrompt: Math.round(result.systemPrompt * safeRatio),\n tools: Math.round(result.tools * safeRatio),\n total: Math.round(result.total * safeRatio),\n };\n }\n\n // No calibration samples yet \u2014 fall back to model-family ratio if available,\n // otherwise use the uncalibrated estimate (ratio = 1.0).\n const fallbackRatio = getModelFamilyRatio(calibrationKey);\n if (fallbackRatio !== null) {\n return {\n messages: Math.round(result.messages * fallbackRatio),\n systemPrompt: Math.round(result.systemPrompt * fallbackRatio),\n tools: Math.round(result.tools * fallbackRatio),\n total: Math.round(result.total * fallbackRatio),\n };\n }\n\n return result;\n}\n\n/** Per-block sample cap for the density scan \u2014 bounds work on giant blocks. */\nconst DENSITY_SAMPLE_PER_BLOCK = 4_096;\n/** Hard cap on total sampled chars so the density scan stays cheap. */\nconst DENSITY_SAMPLE_TOTAL_CAP = 2_000_000;\n\n/**\n * Estimate a **token-density multiplier** for content that the flat 3.5\n * chars/token basis under-counts. The basis is tuned for ASCII English\n * (~4 chars/token); CJK, and other high-codepoint scripts tokenize at ~1.5-2\n * chars/token, so a message that is mostly CJK carries up to ~2.3\u00D7 the tokens\n * the flat basis predicts. Long unbroken ASCII runs (base64, minified blobs)\n * pack slightly denser too. This scans a bounded sample and returns a\n * multiplier in [1, 2.5] \u2014 always \u2265 1, so it can only push the estimate UP,\n * never down. Used only by the send-time overflow guard, never for display.\n */\nfunction textDensityMultiplier(messages: readonly Message[]): number {\n let sampled = 0;\n let nonAscii = 0;\n let maxRun = 0;\n const consider = (s: string): void => {\n const n = Math.min(s.length, DENSITY_SAMPLE_PER_BLOCK);\n let run = 0;\n for (let i = 0; i < n; i++) {\n const c = s.charCodeAt(i);\n if (c > 127) nonAscii++;\n if (c === 32 || c === 9 || c === 10 || c === 13) {\n if (run > maxRun) maxRun = run;\n run = 0;\n } else {\n run++;\n }\n }\n if (run > maxRun) maxRun = run;\n sampled += n;\n };\n\n for (const m of messages) {\n if (typeof m.content === 'string') {\n consider(m.content);\n } else if (Array.isArray(m.content)) {\n for (const b of m.content) {\n if (b.type === 'text') consider(b.text);\n else if (b.type === 'tool_result' && typeof b.content === 'string') consider(b.content);\n else if (b.type === 'thinking') consider(b.thinking);\n }\n }\n if (sampled >= DENSITY_SAMPLE_TOTAL_CAP) break;\n }\n\n if (sampled === 0) return 1;\n const nonAsciiRatio = nonAscii / sampled;\n // 3.5 chars/token at 0% non-ASCII \u2192 1.5 at 100% (heavy CJK).\n let charsPerToken = 3.5 - 2.0 * nonAsciiRatio;\n // A very long unbroken ASCII run (base64/minified) packs a little denser.\n if (maxRun > 2_000 && nonAsciiRatio < 0.1) charsPerToken = Math.min(charsPerToken, 3.0);\n const multiplier = 3.5 / Math.max(1.4, charsPerToken);\n return Math.min(2.5, Math.max(1, multiplier));\n}\n\n/**\n * Never-undercount upper bound for the request token total, for the **send\n * guard** only. Takes the flat estimate and scales it up by the greater of the\n * content-density multiplier and the calibration ceiling, so the guarded value\n * satisfies `real \u2264 upperBound`. The context bar and `/context` keep using the\n * calibrated estimate \u2014 this deliberately over-counts, which is only ever safe\n * for the \"must this be trimmed before sending?\" decision.\n */\nexport function estimateRequestTokensUpperBound(\n messages: unknown,\n systemPrompt: unknown,\n tools: { name: string; description?: string | undefined; inputSchema: unknown }[],\n calibrationKey: string = CALIBRATION_GLOBAL_KEY,\n): RequestTokenBreakdown {\n const base = estimateRequestTokens(messages, systemPrompt, tools, calibrationKey);\n const density = Array.isArray(messages)\n ? textDensityMultiplier(messages as readonly Message[])\n : 1;\n const cal = calState(calibrationKey);\n const calCeiling =\n cal.count >= MIN_SAMPLES_FOR_CALIBRATION ? Math.min(1.5, Math.max(1, cal.ratio)) : 1;\n const mult = Math.max(density, calCeiling);\n if (mult <= 1) return base;\n return {\n messages: Math.ceil(base.messages * mult),\n systemPrompt: Math.ceil(base.systemPrompt * mult),\n tools: Math.ceil(base.tools * mult),\n total: Math.ceil(base.total * mult),\n };\n}\n\n/** Look up the fallback chars/token ratio for a calibration key (e.g. \"provider/model\"). */\nfunction getModelFamilyRatio(calibrationKey: string): number | null {\n const lower = calibrationKey.toLowerCase();\n for (const [family, ratio] of Object.entries(MODEL_FAMILY_RATIO)) {\n if (lower.includes(family)) return ratio / 3.5; // MODEL_FAMILY_RATIO is chars/token, we need multiplier\n }\n return null;\n}\n\n/**\n * Resets calibration state. Primarily for tests that run in the same\n * process and need a clean slate between suites. With no argument it clears\n * every bucket (including the global one); pass a key to reset just that bucket.\n */\nexport function resetCalibration(calibrationKey?: string): void {\n if (calibrationKey === undefined) {\n _cals.clear();\n return;\n }\n _cals.delete(calibrationKey);\n}\n", "/**\n * Response processing handler \u2014 extracted from Agent class.\n * Handles provider response pipeline, event emission, session\n * persistence, text rendering, and autonomous continuation parsing.\n */\n\nimport { isTextBlock, type TextBlock } from '../types/blocks.js';\nimport type { Provider, Request, Response } from '../types/provider.js';\nimport { deriveCachePrefixKey } from '../utils/cache-key.js';\nimport {\n buildCompletedWorkLedgerBlock,\n markAssistantReferencedEvidence,\n} from '../utils/context-evidence.js';\nimport { toErrorMessage } from '../utils/error.js';\nimport { hasMeaningfulContent, repairToolUseAdjacency } from '../utils/message-invariants.js';\nimport type { AgentInternals } from './agent-internals.js';\nimport { type Context, resolveEventSessionId, type RunOptions } from './context.js';\nimport { type ContinueDirective, parseContinueDirective } from './continue-to-next-iteration.js';\nimport { bindRequestProvider } from './request-provider-binding.js';\n\ninterface ProcessResponseResult {\n finalText: string;\n aborted: boolean;\n done: boolean;\n directive?: ContinueDirective | undefined;\n}\n\nexport interface AgentResponseHandler {\n buildAndRunRequestPipeline(opts: RunOptions): Promise<{ request: Request; provider: Provider }>;\n processResponse(\n raw: Response,\n req: Request,\n requestProvider?: Provider,\n ): Promise<ProcessResponseResult>;\n}\n\nconst MAX_TODO_SNAPSHOT_ITEMS = 10;\nconst MAX_TODO_SNAPSHOT_CONTENT = 180;\n\n/**\n * Build the leader-only, per-request decision gate for `<nextsteps>`.\n *\n * The base system prompt is intentionally frozen for provider caching, while\n * todos change during tool execution. Keeping this block volatile makes the\n * final-response contract follow the live todo state on every iteration.\n */\nexport function buildLiveNextStepsGateBlock(\n ctx: Pick<Context, 'agentId' | 'todos'>,\n): TextBlock | undefined {\n if (ctx.agentId !== 'leader') return undefined;\n\n const openTodos = ctx.todos.filter(\n (todo) => todo.status === 'pending' || todo.status === 'in_progress',\n );\n\n if (openTodos.length === 0) {\n return {\n type: 'text',\n text: [\n '[nextsteps_gate]',\n 'Authoritative live state for this request: open todos = 0.',\n 'On the final response, you MUST take exactly one branch:',\n '1. If at least one genuinely useful follow-on action exists, include a balanced <nextsteps> block containing 1-4 exact prompt messages that can be submitted back to you through the current TUI or WebUI input.',\n 'Every item must ask the agent to perform work. Never put a human-only chore or an instruction addressed to the user inside <nextsteps>; natural-language agent-directed imperatives are valid and need not be shell commands.',\n '2. If no useful follow-on action truly exists, omit <nextsteps> and explicitly tell the user in normal prose that no further steps are needed for this task.',\n 'Silently omitting both is invalid. Do not decide by chance, tone, or response length, and do not invent filler suggestions.',\n '[/nextsteps_gate]',\n ].join('\\n'),\n cache_control: { type: 'ephemeral' },\n };\n }\n\n const todoSnapshot = openTodos.slice(0, MAX_TODO_SNAPSHOT_ITEMS).map((todo) => {\n const normalized = todo.content.replace(/\\s+/g, ' ').trim();\n const content =\n normalized.length > MAX_TODO_SNAPSHOT_CONTENT\n ? `${normalized.slice(0, MAX_TODO_SNAPSHOT_CONTENT - 1)}\u2026`\n : normalized;\n return `- [${todo.status}] ${content}`;\n });\n const omitted = openTodos.length - todoSnapshot.length;\n if (omitted > 0) todoSnapshot.push(`- \u2026and ${omitted} more open todo(s)`);\n\n return {\n type: 'text',\n text: [\n '[nextsteps_gate]',\n `Authoritative live state for this request: open todos = ${openTodos.length}.`,\n 'You MUST omit <nextsteps> entirely while these todos remain open. Continue or finish the tracked work; do not propose unrelated follow-on work.',\n 'Open todo snapshot:',\n ...todoSnapshot,\n '[/nextsteps_gate]',\n ].join('\\n'),\n cache_control: { type: 'ephemeral' },\n };\n}\n\nexport function createAgentResponseHandler(a: AgentInternals): AgentResponseHandler {\n // Each assigned prompt array is one explicit cache epoch. Freeze it at the\n // first request boundary so turn-time code cannot silently invalidate the\n // provider prefix by pushing/replacing blocks in place. Lifecycle actions\n // such as a mode switch may assign a new array, which becomes a new epoch.\n const stabilizedPromptEpochs = new WeakSet<TextBlock[]>();\n\n function stabilizePromptEpoch(): void {\n const prompt = a.ctx.systemPrompt;\n if (stabilizedPromptEpochs.has(prompt)) return;\n for (const block of prompt) {\n if (block.cache_control) Object.freeze(block.cache_control);\n Object.freeze(block);\n }\n Object.freeze(prompt);\n stabilizedPromptEpochs.add(prompt);\n }\n\n async function buildAndRunRequestPipeline(\n opts: RunOptions,\n ): Promise<{ request: Request; provider: Provider }> {\n // Only scan for tool-use adjacency issues when tool content has been\n // added since the last scan. Pure text responses and iterations without\n // tool calls don't introduce new adjacency problems \u2014 skipping the O(n)\n // message-array walk saves ~1-3ms per iteration on large contexts.\n if (a.ctx.toolAdjacencyDirty) {\n const repaired = repairToolUseAdjacency(a.ctx.messages);\n a.ctx.toolAdjacencyDirty = false;\n if (repaired.report.changed) {\n a.ctx.state.replaceMessages(repaired.messages);\n a.events.emit('context.repaired', {\n sessionId: resolveEventSessionId(a.ctx),\n ctx: a.ctx,\n ...repaired.report,\n });\n a.logger.warn(\n `Repaired context tool adjacency: removed ${repaired.report.removedToolUses.length} tool_use block(s), ` +\n `${repaired.report.removedToolResults.length} tool_result block(s), ` +\n `${repaired.report.removedMessages} empty message(s)`,\n );\n }\n }\n stabilizePromptEpoch();\n const volatileLedger = buildCompletedWorkLedgerBlock(a.ctx);\n const liveNextStepsGate = buildLiveNextStepsGateBlock(a.ctx);\n const volatileBlocks = [volatileLedger, liveNextStepsGate].filter(\n (block): block is TextBlock => block !== undefined,\n );\n const system =\n volatileBlocks.length > 0 ? [...a.ctx.systemPrompt, ...volatileBlocks] : a.ctx.systemPrompt;\n // A picker/WebUI switch can still be building a provider while\n // auto-continue prepares the next iteration. Wait immediately before\n // capturing the request identity so that iteration cannot retain the old\n // model by racing the switch.\n await a.ctx.waitForModelTransition();\n // Capture provider and model as one request identity. A live /model switch\n // may replace ctx.provider while the async request pipeline or provider\n // call is pending; this request must still finish under the identity it\n // started with.\n const provider = a.ctx.provider;\n const baseReq: Request = {\n model: opts.model ?? a.ctx.model,\n system,\n messages: a.ctx.messages,\n tools: a.tools.list(),\n // `maxTokens` is deliberately NOT set here. The provider adapter\n // resolves the ceiling from the catalog entry for the model in\n // `req.model`, which is the only source that stays correct across a\n // `/model` switch, a fallback hop, or a subagent on a model-matrix\n // entry \u2014 `provider.capabilities` is resolved once, for the model the\n // session booted on, and pinning it here would override the accurate\n // per-request value with a stale one. Callers that genuinely want a\n // smaller response (one-shot LLM helpers, compaction, the brain) still\n // set `maxTokens` on their own Request and keep priority over the\n // catalog.\n // Provider-agnostic cache-partition key from the stable prompt epoch.\n // Wires that support prompt caching (OpenAI `prompt_cache_key`) read it;\n // the config `ttl` is merged over this by the ModelRuntime middleware.\n cache: { key: deriveCachePrefixKey(a.ctx.systemPrompt) },\n };\n const request = await a.pipelines.request.run(baseReq);\n bindRequestProvider(request, provider);\n return { request, provider };\n }\n\n async function processResponse(\n raw: Response,\n req: Request,\n requestProvider: Provider = a.ctx.provider,\n ): Promise<ProcessResponseResult> {\n let res = raw;\n res = await a.pipelines.response.run(res);\n a.events.emit('provider.response', {\n sessionId: resolveEventSessionId(a.ctx),\n ctx: a.ctx,\n model: req.model,\n content: res.content,\n usage: res.usage,\n stopReason: res.stopReason,\n });\n a.ctx.tokenCounter.account(res.usage, req.model, requestProvider.id);\n\n // Issue #271: never append or persist a semantically empty assistant\n // response (e.g. a stream interrupted before the first meaningful delta,\n // which the response builders represent as a single empty text block).\n // Strict providers reject empty assistant turns on the next request, and\n // once journaled, the malformed turn survived every repair path. Partial\n // text, tool calls, and thinking content remain meaningful and are kept.\n if (hasMeaningfulContent(res.content)) {\n // Persist the semantic provider response before its exact-state\n // projection. The conversation journal drains independently, so state\n // mutation first can race `message_appended` ahead of `llm_response`.\n await a.ctx.session.append({\n type: 'llm_response',\n ts: new Date().toISOString(),\n content: res.content,\n stopReason: res.stopReason,\n usage: res.usage,\n });\n a.ctx.state.appendMessage({ role: 'assistant', content: res.content });\n // If the assistant emitted tool_use blocks, mark the message adjacency\n // as potentially needing repair before the next provider request.\n if (!a.ctx.toolAdjacencyDirty) {\n for (const block of res.content) {\n if (block.type === 'tool_use') {\n a.ctx.toolAdjacencyDirty = true;\n break;\n }\n }\n }\n // Tool execution is a side-effect boundary: ensure the response containing\n // its tool_use blocks has reached the session writer before any tool runs.\n // FileSessionWriter keeps failed batches queued for retry; alternate\n // writers may reject, which is logged without masking the provider result.\n try {\n await a.ctx.flushConversationJournal();\n await a.ctx.session.flush();\n } catch (err) {\n (a.logger.debug ?? a.logger.warn)?.(`LLM response flush failed: ${toErrorMessage(err)}`);\n }\n } else {\n a.logger.warn('Empty assistant response \u2014 not appended to context or session', {\n model: req.model,\n stopReason: res.stopReason,\n aborted: a.ctx.signal.aborted,\n });\n }\n\n if (a.ctx.signal.aborted) {\n // M3: collect into an array and join at the end. `finalText += block.text`\n // is O(n\u00B2) on V8 for many concatenations because each `+=` may allocate\n // a new backing string. For a typical 4-block response this is moot,\n // but the streaming-text path concatenates the *full* response in chunks\n // \u2014 and long autonomous loops with verbose reasoning can hit dozens of\n // chunks, making the cost visible. `Array.push` + single `join('')` is\n // amortized O(n).\n const parts: string[] = [];\n for (const block of res.content) {\n if (isTextBlock(block)) parts.push(block.text);\n }\n return { finalText: parts.join(''), aborted: true, done: false };\n }\n\n const parts: string[] = [];\n const streamed = requestProvider.capabilities.streaming;\n for (const block of res.content) {\n if (isTextBlock(block)) {\n const rendered = await a.pipelines.assistantOutput.run(block);\n parts.push(rendered.text);\n if (!streamed) a.renderer?.write(rendered);\n }\n }\n const finalText = parts.join('');\n markAssistantReferencedEvidence(a.ctx, finalText);\n\n let directive: ContinueDirective = 'none';\n if (finalText) {\n directive = parseContinueDirective(finalText);\n }\n\n return { finalText, aborted: false, done: false, directive };\n }\n\n return { buildAndRunRequestPipeline, processResponse };\n}\n", "/**\n * Block provenance and the stateless render helpers of the system-prompt build.\n *\n * Split out of `system-prompt-builder.ts`. Everything here is pure: it depends\n * only on its arguments, so it moved out of the builder class unchanged.\n * `SystemBlockSource` / `SYSTEM_BLOCK_SOURCE` keep their re-export from\n * `system-prompt-builder.ts`, which remains the public import site.\n *\n * @module core/system-prompt-blocks\n */\nimport type { MailboxAgentStatus } from '../coordination/mailbox-types.js';\nimport type { TextBlock } from '../types/blocks.js';\nimport type { Tool } from '../types/tool.js';\nimport type { InstructionBundle } from './instruction-bundle.js';\n\n/**\n * The section of the system prompt a given TextBlock originated from. Used by\n * `getContextBreakdown()` to attribute real token counts per category in the\n * `/context` display.\n */\nexport type SystemBlockSource =\n | 'identity' // layer1 \u2014 instructions/system.md\n | 'tool-usage' // layer2 \u2014 tool prose summary\n | 'environment' // layer3 \u2014 OS/git/date/skills-in-scope\n | 'skills' // layer4 \u2014 Active Skills bodies (+ memory when injectMemory)\n | 'mode' // layer5 mode prompt + mode-skill hint\n | 'plan' // layer6 \u2014 active plan\n | 'leader-after-task' // leader-only after-task affordances\n | 'contributor' // plugin-contributed volatile blocks\n | 'ledger' // volatile completed-work ledger (request-time)\n | 'nextsteps'; // volatile next-steps gate (request-time)\n\n/**\n * Side-table mapping each system-prompt TextBlock to the section it came from.\n * Kept as a WeakMap rather than a field on TextBlock so the label never reaches\n * the wire: the provider adapters spread blocks verbatim (Anthropic non-ttl\n * `: b`, OpenAI `stripCacheControl` rest-spread), so any extra field would leak.\n * Block identities survive `flattenSystemPromptRegions` into `ctx.systemPrompt`,\n * so a later read of `ctx.systemPrompt` resolves the same entries.\n */\nexport const SYSTEM_BLOCK_SOURCE = new WeakMap<TextBlock, SystemBlockSource>();\n\n/** Tag a freshly-built block with its origin, returning the same reference. */\nexport function tagBlock(block: TextBlock, source: SystemBlockSource): TextBlock {\n SYSTEM_BLOCK_SOURCE.set(block, source);\n return block;\n}\n\nexport function shortSessionId(sessionId: string): string {\n const leaf = sessionId.split('/').pop() ?? sessionId;\n return leaf.length > 12 ? `${leaf.slice(0, 12)}\u2026` : leaf;\n}\n\nexport function instructionSection(\n bundle: InstructionBundle,\n key: string,\n vars: Record<string, string | number> = {},\n): string {\n const template = bundle.sections?.[key];\n if (!template) return '';\n return template.replace(/\\{\\{\\s*([a-zA-Z0-9_.-]+)\\s*\\}\\}/g, (match, name: string) => {\n const value = vars[name];\n return value === undefined ? match : String(value);\n });\n}\n\nexport function renderToolSelectionBoundary(tool: Tool): string {\n const selection = tool.selection;\n if (!selection?.doNotUseWhen.trim()) return '';\n const alternatives = selection.useInstead?.filter(Boolean) ?? [];\n const instead =\n alternatives.length > 0\n ? ` Use ${alternatives.map((name) => `\\`${name}\\``).join(' or ')} instead.`\n : '';\n return `Do not use when ${selection.doNotUseWhen.trim()}${instead}`;\n}\n\n/**\n * Cheap content fingerprint of the online agents array. The mailbox\n * rebuilds the array as a fresh object on every status check, so caching\n * by reference always misses \u2014 this lets the renderOnlineAgents and\n * buildToolUsage caches detect rendered identity/status/task/tool changes\n * instead.\n *\n * O(n) over every field rendered in the peer snapshot. This matters because\n * status/task/tool changes should invalidate the prompt just like joins and\n * leaves do. Uses FNV-1a over character codes; a collision would only leave a\n * stale cosmetic snapshot in the prompt.\n */\nexport function agentsFingerprint(agents: readonly MailboxAgentStatus[] | undefined): string {\n if (!agents || agents.length === 0) return '0';\n let h = 0x811c9dc5;\n for (const a of agents) {\n const fields = [\n a.agentId,\n a.name,\n a.source,\n a.sessionId,\n a.status,\n a.currentTask,\n a.currentTool,\n a.online ? '1' : '0',\n ];\n for (const field of fields) {\n const value = field ?? '';\n for (let i = 0; i < value.length; i++) {\n h ^= value.charCodeAt(i);\n h = Math.imul(h, 0x01000193) >>> 0;\n }\n h ^= 0xff;\n h = Math.imul(h, 0x01000193) >>> 0;\n }\n }\n return `${agents.length}:${h.toString(36)}`;\n}\n", "import { buildLiveNextStepsGateBlock } from '../core/agent-response.js';\nimport {\n SYSTEM_BLOCK_SOURCE,\n type SystemBlockSource,\n} from '../core/system-prompt-builder.js';\nimport type { Context } from '../core/context.js';\nimport type { TextBlock } from '../types/blocks.js';\nimport type { Tool } from '../types/tool.js';\nimport { buildCompletedWorkLedgerBlock } from './context-evidence.js';\nimport {\n estimateTextTokens,\n estimateToolDefTokens,\n estimateToolInputTokens,\n estimateToolResultTokens,\n} from './token-estimate.js';\n\n/**\n * Real, per-category token accounting for the live context window \u2014 the data\n * behind an honest `/context` display. Every number is measured from the actual\n * assembled inputs (`ctx.systemPrompt`, `ctx.tools`, `ctx.messages`) using the\n * same 3.5-chars/token estimator the compactor and live bar use, so the total\n * here reconciles with the context-fill bar. It replaces the hardcoded fake\n * percentages the TUI dashboard used to show.\n */\nexport interface ContextBreakdown {\n system: {\n total: number;\n /** Tokens attributed to each system-prompt section (see SystemBlockSource). */\n bySource: Record<SystemBlockSource | 'other', number>;\n };\n tools: {\n total: number;\n builtin: number;\n mcp: number;\n /** Number of tool definitions in the request. */\n count: number;\n /** MCP tool tokens grouped by originating server. */\n mcpByServer: Record<string, number>;\n };\n history: {\n total: number;\n /** User/assistant text + tool_use inputs + thinking. */\n text: number;\n /** tool_result output content. */\n toolResults: number;\n messageCount: number;\n };\n volatile: {\n /** Completed-work ledger, appended to `system` at request time. */\n ledger: number;\n /** Next-steps gate, appended to `system` at request time. */\n nextsteps: number;\n total: number;\n };\n /** system.total + tools.total + history.total + volatile.total. */\n total: number;\n effectiveMaxContext: number;\n /** total / effectiveMaxContext \u2014 may exceed 1 before compaction fires. */\n usedPct: number;\n /**\n * Non-fatal build warnings encountered during breakdown computation.\n * Empty when everything succeeded; populated when volatile blocks\n * (ledger, nextsteps) threw during construction and were silently omitted.\n */\n warnings: string[];\n}\n\nconst SYSTEM_BLOCK_SOURCES: readonly (SystemBlockSource | 'other')[] = [\n 'identity',\n 'tool-usage',\n 'environment',\n 'skills',\n 'mode',\n 'plan',\n 'leader-after-task',\n 'contributor',\n 'ledger',\n 'nextsteps',\n 'other',\n];\n\nfunction emptyBySource(): Record<SystemBlockSource | 'other', number> {\n const out = {} as Record<SystemBlockSource | 'other', number>;\n for (const key of SYSTEM_BLOCK_SOURCES) out[key] = 0;\n return out;\n}\n\n/** An MCP-proxied tool, identified by capability first then the `mcp__` prefix. */\nfunction isMcpTool(tool: Tool): boolean {\n return (tool.capabilities?.includes('mcp.proxy') ?? false) || tool.name.startsWith('mcp__');\n}\n\n/** Server segment of a `mcp__<server>__<tool>` name, or a generic bucket. */\nfunction mcpServerOf(tool: Tool): string {\n const parts = tool.name.split('__');\n return parts.length >= 3 && parts[0] === 'mcp' ? (parts[1] ?? 'mcp') : 'mcp';\n}\n\nfunction safeBuild(\n fn: () => TextBlock | undefined,\n warn: (e: unknown) => void = () => {},\n): TextBlock | undefined {\n try {\n return fn();\n } catch (e) {\n warn(e);\n return undefined;\n }\n}\n\n/**\n * Mirror the denominator the agent loop (`currentMaxContext`) and the\n * auto-compaction middleware use: an explicit `effectiveMaxContext` override\n * wins, then the provider window, then a safe default. Inline-replicated here\n * to keep this module free of an `execution/`/`core/` runtime dependency for\n * the denominator (the builders it already imports are the only exception).\n */\nfunction resolveEffectiveMaxContext(ctx: Context): number {\n const metaLimit = ctx.meta?.['effectiveMaxContext'];\n const providerMax = ctx.provider.capabilities.maxContext;\n return typeof metaLimit === 'number' && metaLimit > 0\n ? metaLimit\n : typeof providerMax === 'number' && providerMax > 0\n ? providerMax\n : 200_000;\n}\n\n/**\n * Compute the real per-category token breakdown of a live context. Safe to call\n * interactively (e.g. from `/context`): it walks the full message array once, so\n * it is O(messages\u00B7blocks), not the O(1) cached path the per-turn bar uses.\n */\nexport function getContextBreakdown(ctx: Context): ContextBreakdown {\n // --- System prompt: attributed per section via the builder's WeakMap tag ---\n const bySource = emptyBySource();\n let systemTotal = 0;\n for (const block of ctx.systemPrompt) {\n const tokens = estimateTextTokens(block.text);\n systemTotal += tokens;\n bySource[SYSTEM_BLOCK_SOURCE.get(block) ?? 'other'] += tokens;\n }\n\n // --- Tool definitions: builtin vs MCP (grouped by server) ---\n let toolsBuiltin = 0;\n let toolsMcp = 0;\n const mcpByServer: Record<string, number> = {};\n for (const tool of ctx.tools) {\n const tokens = estimateToolDefTokens(tool);\n if (isMcpTool(tool)) {\n toolsMcp += tokens;\n const server = mcpServerOf(tool);\n mcpByServer[server] = (mcpByServer[server] ?? 0) + tokens;\n } else {\n toolsBuiltin += tokens;\n }\n }\n\n // --- Conversation history: text/tool_use/thinking vs tool_result output ---\n let histText = 0;\n let histToolResults = 0;\n for (const msg of ctx.messages) {\n if (typeof msg.content === 'string') {\n histText += estimateTextTokens(msg.content);\n continue;\n }\n for (const b of msg.content) {\n switch (b.type) {\n case 'text':\n histText += estimateTextTokens(b.text);\n break;\n case 'tool_use':\n histText += estimateToolInputTokens(b.input);\n break;\n case 'tool_result':\n histToolResults += estimateToolResultTokens(b.content);\n break;\n case 'thinking':\n histText += estimateTextTokens(b.thinking);\n break;\n default:\n histText += estimateTextTokens(JSON.stringify(b));\n }\n }\n }\n\n // --- Volatile per-turn blocks: re-derived (they live in the request, not\n // in ctx.systemPrompt) and tagged by construction. ---\n const warnings: string[] = [];\n const warn = (e: unknown) => {\n const msg = e instanceof Error ? e.message : String(e);\n warnings.push(msg);\n };\n const ledgerBlock = safeBuild(() => buildCompletedWorkLedgerBlock(ctx), warn);\n const nextstepsBlock = safeBuild(() => buildLiveNextStepsGateBlock(ctx), warn);\n const ledger = ledgerBlock ? estimateTextTokens(ledgerBlock.text) : 0;\n const nextsteps = nextstepsBlock ? estimateTextTokens(nextstepsBlock.text) : 0;\n\n const toolsTotal = toolsBuiltin + toolsMcp;\n const historyTotal = histText + histToolResults;\n const volatileTotal = ledger + nextsteps;\n const total = systemTotal + toolsTotal + historyTotal + volatileTotal;\n const effectiveMaxContext = resolveEffectiveMaxContext(ctx);\n\n return {\n system: { total: systemTotal, bySource },\n tools: {\n total: toolsTotal,\n builtin: toolsBuiltin,\n mcp: toolsMcp,\n count: ctx.tools.length,\n mcpByServer,\n },\n history: {\n total: historyTotal,\n text: histText,\n toolResults: histToolResults,\n messageCount: ctx.messages.length,\n },\n volatile: { ledger, nextsteps, total: volatileTotal },\n total,\n effectiveMaxContext,\n usedPct: effectiveMaxContext > 0 ? total / effectiveMaxContext : 0,\n warnings,\n };\n}\n", "/**\n * Deep merge utility \u2014 safely merges nested objects with configurable\n * conflict resolution, array merging, and prototype-pollution guarding.\n *\n * Used by:\n * - config-loader (config layer merging with primitive-array concatenation)\n * - secret-vault (config patching)\n * - json-path (json_merge tool with prefer-base / prefer-patch semantics)\n *\n * @module utils/deep-merge\n */\n\n// ---------------------------------------------------------------------------\n// Prototype-pollution guard \u2014 shared set of forbidden __proto__ keys\n// ---------------------------------------------------------------------------\n\nexport const FORBIDDEN_PROTO_KEYS = new Set([\n '__proto__',\n 'constructor',\n 'prototype',\n '__defineGetter__',\n '__defineSetter__',\n '__lookupGetter__',\n '__lookupSetter__',\n]);\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/** True when every element is a primitive or null (no nested objects/arrays). */\nexport function isPrimitiveArray(a: unknown[]): boolean {\n return a.every((v) => v === null || (typeof v !== 'object' && typeof v !== 'function'));\n}\n\n// ---------------------------------------------------------------------------\n// Options\n// ---------------------------------------------------------------------------\n\nexport interface DeepMergeOptions {\n /**\n * Which side wins on collision for scalars and arrays.\n *\n * - `'prefer-patch'` (default): patch value replaces base value.\n * - `'prefer-base'`: base value is kept, patch value is ignored.\n */\n conflictResolution?: 'prefer-base' | 'prefer-patch';\n\n /**\n * How to handle array values.\n *\n * - `'replace'` (default): patch array replaces base array entirely.\n * - `'concat-primitives'`: when both values are primitive arrays,\n * they are concatenated and deduped (via Set). Non-primitive\n * arrays still replace the base wholesale.\n */\n arrayMode?: 'replace' | 'concat-primitives';\n\n /**\n * Skip prototype-pollution keys (`__proto__`, `constructor`, etc.).\n * Enabled by default. Only disable when you control both inputs\n * and the keyset (e.g. when merging trusted JSON schemas).\n */\n protectProto?: boolean;\n\n /**\n * Optional callback fired when a non-primitive (object) array is\n * replaced wholesale (only relevant with `arrayMode: 'concat-primitives'`).\n * Receives the key name, existing array length, and patch array length.\n * Used by config-loader for debug logging.\n */\n onNonPrimitiveArrayReplace?: (\n key: string,\n existingLen: number,\n patchLen: number,\n ) => void;\n}\n\n// ---------------------------------------------------------------------------\n// Implementation\n// ---------------------------------------------------------------------------\n\n/**\n * Recursively merge `patch` into `base`, returning a new object.\n *\n * - Nested plain objects are merged recursively.\n * - Arrays are handled per `options.arrayMode`.\n * - Scalar collisions are resolved per `options.conflictResolution`.\n * - `null` and non-object values in `patch` replace the base value\n * (unless `conflictResolution` is `'prefer-base'`).\n * - Keys in `base` that are absent from `patch` are preserved.\n * - `FORBIDDEN_PROTO_KEYS` are skipped in the patch (unless\n * `options.protectProto` is set to `false`).\n *\n * The function is generic over `T extends Record<string, unknown>` for\n * callers that pass typed config objects, but the runtime signature\n * also accepts `unknown` inputs (used by the json-path plugin).\n */\nexport function deepMerge<T extends Record<string, unknown>>(\n base: T,\n patch: Record<string, unknown>,\n options?: DeepMergeOptions,\n): T;\n\nexport function deepMerge(\n base: unknown,\n patch: unknown,\n options?: DeepMergeOptions,\n): unknown;\n\nexport function deepMerge(\n base: unknown,\n patch: unknown,\n options: DeepMergeOptions = {},\n): unknown {\n const {\n conflictResolution = 'prefer-patch',\n arrayMode = 'replace',\n protectProto = true,\n onNonPrimitiveArrayReplace,\n } = options;\n\n // Non-object / null handling \u2014 delegate to conflict resolution.\n if (typeof base !== 'object' || base === null) {\n return conflictResolution === 'prefer-patch' ? patch : base;\n }\n if (typeof patch !== 'object' || patch === null) {\n return conflictResolution === 'prefer-patch' ? patch : base;\n }\n\n // Arrays \u2014 handled *before* the object merge so array-of-objects\n // aren't accidentally treated as plain records.\n if (Array.isArray(base) && Array.isArray(patch)) {\n if (\n arrayMode === 'concat-primitives' &&\n isPrimitiveArray(base) &&\n isPrimitiveArray(patch)\n ) {\n return [...new Set([...base, ...patch])];\n }\n return conflictResolution === 'prefer-patch' ? patch : base;\n }\n\n // If only one side is an array, treat as scalar collision.\n if (Array.isArray(base) || Array.isArray(patch)) {\n return conflictResolution === 'prefer-patch' ? patch : base;\n }\n\n // Plain object merge.\n const baseObj = base as Record<string, unknown>;\n const patchObj = patch as Record<string, unknown>;\n const out: Record<string, unknown> = { ...baseObj };\n\n for (const [k, v] of Object.entries(patchObj)) {\n if (protectProto && FORBIDDEN_PROTO_KEYS.has(k)) continue;\n\n const existing = out[k];\n if (\n v !== null &&\n typeof v === 'object' &&\n !Array.isArray(v) &&\n existing !== null &&\n typeof existing === 'object' &&\n !Array.isArray(existing)\n ) {\n // Recursive merge for nested plain objects.\n out[k] = deepMerge(existing, v, options);\n } else if (Array.isArray(v) && Array.isArray(existing)) {\n // Delegate to top-level array handling so arrayMode\n // (e.g. 'concat-primitives') applies to nested arrays too.\n // Fire debug hook when a non-primitive array replaces an existing\n // array (for non-primitive arrays, concat-primitives is a no-op and\n // the result is always a wholesale replacement).\n if (onNonPrimitiveArrayReplace && !isPrimitiveArray(v)) {\n onNonPrimitiveArrayReplace(k, existing.length, v.length);\n }\n out[k] = deepMerge(existing, v, options);\n } else if (v !== undefined) {\n // Fire debug hook when a non-primitive (object) array replaces an\n // existing value in concat-primitives mode.\n if (\n onNonPrimitiveArrayReplace &&\n Array.isArray(v) &&\n !isPrimitiveArray(v)\n ) {\n const existingLen = Array.isArray(existing) ? existing.length : 0;\n onNonPrimitiveArrayReplace(k, existingLen, v.length);\n }\n out[k] = v;\n }\n // When v === undefined, leave the existing value untouched\n // (this matches config-loader's behaviour: undefined in patch\n // means \"don't change this key\").\n }\n\n return out;\n}\n", "/**\n * Myers diff with unified-format output. No external dependencies.\n * Operates on arrays of lines (newline-terminated or stripped).\n */\n\ninterface Edit {\n op: 'equal' | 'insert' | 'delete';\n a: number;\n b: number;\n line: string;\n}\n\nfunction myersDiff(a: string[], b: string[]): Edit[] {\n const N = a.length;\n const M = b.length;\n const max = N + M;\n if (max === 0) return [];\n\n const v = new Map<number, number>();\n v.set(1, 0);\n const trace: Map<number, number>[] = [];\n\n for (let d = 0; d <= max; d++) {\n const snapshot = new Map(v);\n trace.push(snapshot);\n for (let k = -d; k <= d; k += 2) {\n const left = v.get(k - 1) ?? -1;\n const right = v.get(k + 1) ?? -1;\n let x: number;\n if (k === -d || (k !== d && left < right)) {\n x = right;\n } else {\n x = left + 1;\n }\n let y = x - k;\n while (x < N && y < M && a[x] === b[y]) {\n x++;\n y++;\n }\n v.set(k, x);\n if (x >= N && y >= M) {\n return backtrack(trace, a, b, N, M, d);\n }\n }\n }\n return [];\n}\n\nfunction backtrack(\n trace: Map<number, number>[],\n a: string[],\n b: string[],\n N: number,\n M: number,\n finalD: number,\n): Edit[] {\n const edits: Edit[] = [];\n let x = N;\n let y = M;\n for (let d = finalD; d > 0; d--) {\n const v = trace[d];\n if (!v) break;\n const k = x - y;\n const left = v.get(k - 1) ?? -1;\n const right = v.get(k + 1) ?? -1;\n let prevK: number;\n if (k === -d || (k !== d && left < right)) {\n prevK = k + 1;\n } else {\n prevK = k - 1;\n }\n const prevX = v.get(prevK) ?? 0;\n const prevY = prevX - prevK;\n while (x > prevX && y > prevY) {\n edits.push({ op: 'equal', a: x - 1, b: y - 1, line: a[x - 1] ?? '' });\n x--;\n y--;\n }\n if (d > 0) {\n if (x === prevX) {\n edits.push({ op: 'insert', a: x, b: y - 1, line: b[y - 1] ?? '' });\n } else {\n edits.push({ op: 'delete', a: x - 1, b: y, line: a[x - 1] ?? '' });\n }\n x = prevX;\n y = prevY;\n }\n }\n while (x > 0 && y > 0) {\n edits.push({ op: 'equal', a: x - 1, b: y - 1, line: a[x - 1] ?? '' });\n x--;\n y--;\n }\n return edits.reverse();\n}\n\nexport interface UnifiedDiffOptions {\n context?: number | undefined;\n fromFile?: string | undefined;\n toFile?: string | undefined;\n}\n\nexport function unifiedDiff(\n oldText: string,\n newText: string,\n opts: UnifiedDiffOptions = {},\n): string {\n const context = opts.context ?? 3;\n const a = oldText.split('\\n');\n const b = newText.split('\\n');\n // Handle trailing newline: split adds an empty string we don't want to diff\n if (a[a.length - 1] === '') a.pop();\n if (b[b.length - 1] === '') b.pop();\n const edits = myersDiff(a, b);\n if (edits.every((e) => e.op === 'equal')) return '';\n\n const hunks: { aStart: number; bStart: number; lines: string[] }[] = [];\n let i = 0;\n while (i < edits.length) {\n while (i < edits.length && edits[i]?.op === 'equal') i++;\n if (i >= edits.length) break;\n const hunkStart = Math.max(0, i - context);\n const lines: string[] = [];\n let aStart = (edits[hunkStart]?.a ?? 0) + 1;\n let bStart = (edits[hunkStart]?.b ?? 0) + 1;\n let aCount = 0;\n let bCount = 0;\n let cursor = hunkStart;\n let trailing = 0;\n while (cursor < edits.length) {\n const e = edits[cursor];\n if (!e) break;\n if (e.op === 'equal') {\n trailing++;\n if (trailing > context * 2) break;\n } else {\n trailing = 0;\n }\n if (e.op === 'equal') {\n lines.push(` ${e.line}`);\n aCount++;\n bCount++;\n } else if (e.op === 'delete') {\n lines.push(`-${e.line}`);\n aCount++;\n } else {\n lines.push(`+${e.line}`);\n bCount++;\n }\n cursor++;\n }\n // Trim trailing context lines beyond `context`\n while (lines.length > 0 && lines[lines.length - 1]?.startsWith(' ') && trailing > context) {\n lines.pop();\n aCount--;\n bCount--;\n trailing--;\n }\n if (aCount === 0) aStart = 0;\n if (bCount === 0) bStart = 0;\n hunks.push({ aStart, bStart, lines });\n i = cursor;\n }\n if (hunks.length === 0) return '';\n\n let out = '';\n out += `--- ${opts.fromFile ?? 'a'}\\n`;\n out += `+++ ${opts.toFile ?? 'b'}\\n`;\n for (const h of hunks) {\n let aCount = 0;\n let bCount = 0;\n for (const l of h.lines) {\n if (l.startsWith(' ')) {\n aCount++;\n bCount++;\n } else if (l.startsWith('-')) aCount++;\n else if (l.startsWith('+')) bCount++;\n }\n out += `@@ -${h.aStart},${aCount} +${h.bStart},${bCount} @@\\n`;\n out += `${h.lines.join('\\n')}\\n`;\n }\n return out;\n}\n", "import { expectDefined } from './expect-defined.js';\n/**\n * Glob pattern \u2192 concrete file path expansion.\n *\n * Supports: *, **, ?, [...]\n * Does NOT support brace expansion {a,b}.\n *\n * Returns the input as-is if it contains no glob metacharacters.\n * On Windows, both / and \\ are accepted as path separators.\n */\n\nimport * as fsp from 'node:fs/promises';\nimport { isAbsolute, resolve } from 'node:path';\nconst GLOB_CHARS = new Set(['*', '?', '[']);\nconst IS_WINDOWS = typeof process !== 'undefined' && process.platform === 'win32';\nconst SEP = IS_WINDOWS ? '\\\\' : '/';\n\nfunction isGlob(p: string): boolean {\n for (const c of p) {\n if (GLOB_CHARS.has(c)) return true;\n }\n return false;\n}\n\nfunction globToRegex(pat: string): RegExp {\n let i = 0;\n let re = '^';\n while (i < pat.length) {\n const c = expectDefined(pat[i]);\n if (c === '*') {\n if (pat[i + 1] === '*') {\n re += '.*';\n i += 2;\n if (pat[i] === '/') i++;\n } else {\n re += '[^/\\\\\\\\]*';\n i++;\n }\n } else if (c === '?') {\n re += '[^/\\\\\\\\]';\n i++;\n } else if (c === '[') {\n let cls = '[';\n i++;\n if (pat[i] === '!' || pat[i] === '^') {\n cls += '^';\n i++;\n }\n while (i < pat.length && pat[i] !== ']') {\n const ch = pat[i] ?? '';\n if (ch === '\\\\') cls += '\\\\\\\\';\n else if (ch === ']' || ch === '^') cls += `\\\\${ch}`;\n else cls += ch;\n i++;\n }\n cls += ']';\n re += cls;\n i++;\n } else {\n re += c.replace(/[.+^${}()|\\\\]/g, '\\\\$&');\n i++;\n }\n }\n return new RegExp(re + '$');\n}\n\nfunction baseDir(pat: string): string {\n // Deepest literal directory prefix: cut at the last separator BEFORE the\n // first glob char. Scanning from the end instead finds separators inside\n // glob segments \u2014 '**/*.ts' would yield base '**' on POSIX (native sep '/').\n let firstGlob = pat.length;\n for (let i = 0; i < pat.length; i++) {\n if (GLOB_CHARS.has(expectDefined(pat[i]))) {\n firstGlob = i;\n break;\n }\n }\n const cut = Math.max(\n pat.lastIndexOf(SEP, firstGlob - 1),\n pat.lastIndexOf('/', firstGlob - 1),\n );\n return cut < 0 ? '.' : pat.slice(0, cut);\n}\n\n/**\n * Resolve `pattern` to the set of concrete file paths it matches.\n * Literal paths (no glob chars) are returned as-is.\n *\n * @example\n * await expandGlob('src/**\\/*.ts') // \u2192 ['src/a.ts', 'src/b/c.ts', ...]\n * await expandGlob('foo.txt') // \u2192 ['foo.txt']\n */\nexport async function expandGlob(pattern: string): Promise<string[]> {\n if (!isGlob(pattern)) return [pattern];\n\n const results = new Set<string>();\n const abs = isAbsolute(pattern);\n const base = abs ? baseDir(pattern) : baseDir(pattern);\n const relPat = base === '.' ? pattern : pattern.slice(base.length + 1);\n\n async function walk(dir: string, pat: string): Promise<void> {\n let entries: string[];\n try {\n entries = await fsp.readdir(dir);\n } catch {\n return;\n }\n\n const firstGlob = pat.search(/[*?[[]/);\n\n if (firstGlob < 0) {\n const re = globToRegex(pat);\n for (const e of entries) {\n if (re.test(e)) {\n const full = `${dir}${SEP}${e}`;\n results.add(abs ? resolve(full) : full);\n }\n }\n return;\n }\n\n const before = pat.slice(0, firstGlob);\n const rest = pat.slice(firstGlob);\n\n if (before.endsWith('**')) {\n // Match at current dir then recurse into subdirs\n await walk(dir, rest);\n for (const e of entries) {\n const full = `${dir}${SEP}${e}`;\n try {\n const stat = await fsp.stat(full);\n if (stat.isDirectory()) await walk(full, rest);\n } catch {\n /* skip inaccessible */\n }\n }\n } else if (before === '') {\n // Pattern starts with a glob char \u2014 match files in current dir only\n const re = globToRegex(rest);\n for (const e of entries) {\n if (re.test(e)) {\n const full = `${dir}${SEP}${e}`;\n results.add(abs ? resolve(full) : full);\n }\n }\n } else {\n // Literal segment(s) before the glob \u2014 descend into matching subdir\n const seg = before.replace(/[*?[\\]]/g, '').replace(/\\/$/, '');\n if (entries.includes(seg)) {\n const full = `${dir}${SEP}${seg}`;\n try {\n const stat = await fsp.stat(full);\n if (stat.isDirectory()) await walk(full, rest);\n } catch {\n /* skip */\n }\n }\n }\n }\n\n await walk(base === '.' ? '.' : base, relPat);\n return [...results];\n}\n", "import { expectDefined } from './expect-defined.js';\n/**\n * Minimal glob matcher for trust patterns.\n * Supports: *, **, ?, character classes [abc], [a-z], negation [!...] or [^...].\n *\n * Compiled regexes are cached so repeated calls with the same pattern\n * avoid recompilation overhead.\n */\n\nfunction escapeRegex(s: string): string {\n return s.replace(/[.+^${}()|\\\\]/g, '\\\\$&');\n}\n\n// Module-level cache to avoid recompiling the same pattern on every call.\n// LRU-ish eviction keeps unbounded growth in check for long-running processes.\nconst COMPILED_GLOB_CACHE = new Map<string, RegExp>();\nconst CACHE_MAX_SIZE = 2000;\n\n// Matches nothing \u2014 `[^\\s\\S]` can never be satisfied. Used as the cached\n// result for patterns that fail to compile (e.g. an over-long auto-trusted\n// command) so one bad trust entry degrades to \"no match\" instead of throwing.\nconst NEVER_MATCH = /[^\\s\\S]/;\n\nfunction getCachedGlob(pattern: string): RegExp {\n const cached = COMPILED_GLOB_CACHE.get(pattern);\n if (cached) return cached;\n if (COMPILED_GLOB_CACHE.size >= CACHE_MAX_SIZE) {\n // Evict oldest 25% when at capacity\n const keys = [...COMPILED_GLOB_CACHE.keys()];\n for (let i = 0; i < Math.floor(CACHE_MAX_SIZE / 4); i++) {\n COMPILED_GLOB_CACHE.delete(expectDefined(keys[i]));\n }\n }\n let re: RegExp;\n try {\n re = compileGlob(pattern);\n } catch {\n // A pathological trust pattern (over MAX_GLOB_PATTERN_LEN \u2014 e.g. a long\n // one-liner auto-trusted in YOLO/Auto mode) must NOT throw out of every\n // subsequent permission check and break unrelated commands like `true`\n // or `ls` (#20). Cache a never-matching regex so the bad entry is inert.\n re = NEVER_MATCH;\n }\n COMPILED_GLOB_CACHE.set(pattern, re);\n return re;\n}\n\n// Cap glob pattern length to prevent excessively long compiled regexes.\nconst MAX_GLOB_PATTERN_LEN = 1024;\n\nexport function compileGlob(pattern: string): RegExp {\n if (pattern.length > MAX_GLOB_PATTERN_LEN) {\n throw new Error(`Glob pattern exceeds ${MAX_GLOB_PATTERN_LEN} characters`);\n }\n let i = 0;\n let re = '^';\n while (i < pattern.length) {\n const c = pattern[i];\n if (c === '*') {\n if (pattern[i + 1] === '*') {\n // ** matches any number of chars including /\n re += '.*';\n i += 2;\n // Skip trailing slash so '**/x' matches 'x'\n if (pattern[i] === '/') i++;\n } else {\n // single * matches any chars except /\n re += '[^/]*';\n i++;\n }\n } else if (c === '?') {\n re += '[^/]';\n i++;\n } else if (c === '[') {\n let cls = '[';\n i++;\n if (pattern[i] === '!' || pattern[i] === '^') {\n cls += '^';\n i++;\n }\n while (i < pattern.length && pattern[i] !== ']') {\n const ch = pattern[i] ?? '';\n // Inside a regex class, only `]`, `\\`, and `^`/`-` at boundaries need\n // escaping. We've already consumed the leading `^`; the rest are\n // literal. Escape `\\` defensively and pass the rest through verbatim\n // so ranges like `a-z` continue to work.\n if (ch === '\\\\') {\n cls += '\\\\\\\\';\n } else if (ch === ']' || ch === '^') {\n cls += `\\\\${ch}`;\n } else {\n cls += ch;\n }\n i++;\n }\n cls += ']';\n re += cls;\n i++; // skip closing ]\n } else {\n re += escapeRegex(c ?? '');\n i++;\n }\n }\n re += '$';\n return new RegExp(re);\n}\n\nexport function matchGlob(pattern: string, input: string): boolean {\n return getCachedGlob(pattern).test(input);\n}\n\nexport function matchAny(patterns: string[], input: string): boolean {\n return patterns.some((p) => matchGlob(p, input));\n}\n", "import type { ContentBlock, ImageBlock } from '../types/blocks.js';\n\n/**\n * Wire shape for one image attached to a WebUI `user_message`. `data` may be\n * a bare base64 string or a full `data:` URL (the client normally strips the\n * prefix, but legacy senders shipped the whole URL).\n */\nexport interface IncomingImagePayload {\n data: string;\n mediaType?: string | undefined;\n /** Original filename, when the image came from a file picker or drop. */\n name?: string | undefined;\n}\n\nexport const MAX_INCOMING_IMAGES = 8;\n\n/**\n * Decoded-byte cap per image. The WebUI client downscales before sending, so\n * anything larger than this is either a bypassed client or an abuse attempt.\n * Kept under the servers' WS maxPayload once base64 overhead (~4/3) and the\n * surrounding JSON envelope are added.\n */\nexport const MAX_INCOMING_IMAGE_BYTES = 8 * 1024 * 1024;\n\n/** Media types every supported vision wire accepts (Anthropic passthrough,\n * OpenAI data-URLs, Gemini inlineData). */\nconst ALLOWED_IMAGE_MEDIA_TYPES = new Set<string>([\n 'image/png',\n 'image/jpeg',\n 'image/webp',\n 'image/gif',\n]);\n\n/** Validation failure on user-supplied image payloads. The message is safe to\n * echo back to the client verbatim. */\nexport class IncomingImageError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'IncomingImageError';\n }\n}\n\nconst DATA_URL_RE = /^data:([a-z0-9.+-]+\\/[a-z0-9.+-]+)?(?:;[a-z0-9-]+=[^;,]*)*(;base64)?,/i;\n\nfunction splitDataUrl(data: string): { base64: string; mediaType?: string | undefined } {\n const match = DATA_URL_RE.exec(data);\n if (!match) return { base64: data.trim() };\n return {\n base64: data.slice(match[0].length).trim(),\n mediaType: match[1]?.toLowerCase(),\n };\n}\n\n/**\n * Validate and normalize the `images` field of a `user_message` payload into\n * canonical {@link ImageBlock}s. Accepts the legacy single `imageBase64`\n * field (a data-URL) as a trailing entry so old clients keep working.\n *\n * Throws {@link IncomingImageError} on count/size/media-type violations.\n */\nexport function parseIncomingImages(\n images?: readonly IncomingImagePayload[] | undefined,\n legacyImageBase64?: string | undefined,\n): ImageBlock[] {\n const raw: IncomingImagePayload[] = [...(images ?? [])];\n if (legacyImageBase64) raw.push({ data: legacyImageBase64 });\n if (raw.length === 0) return [];\n if (raw.length > MAX_INCOMING_IMAGES) {\n throw new IncomingImageError(\n `Too many images: ${raw.length} (max ${MAX_INCOMING_IMAGES} per message).`,\n );\n }\n\n return raw.map((img, i) => {\n const { base64, mediaType: fromUrl } = splitDataUrl(img.data ?? '');\n const mediaType = (img.mediaType ?? fromUrl ?? 'image/png').toLowerCase();\n if (!ALLOWED_IMAGE_MEDIA_TYPES.has(mediaType)) {\n throw new IncomingImageError(\n `Image ${i + 1}: unsupported media type \"${mediaType}\" (allowed: ${[...ALLOWED_IMAGE_MEDIA_TYPES].join(', ')}).`,\n );\n }\n if (!base64) {\n throw new IncomingImageError(`Image ${i + 1}: empty image data.`);\n }\n // Base64 alphabet check \u2014 cheap linear scan that rejects raw binary or\n // JSON smuggled into the field before it reaches a provider wire.\n if (!/^[A-Za-z0-9+/]+={0,2}$/.test(base64)) {\n throw new IncomingImageError(`Image ${i + 1}: data is not valid base64.`);\n }\n const bytes = Math.floor((base64.length * 3) / 4);\n if (bytes > MAX_INCOMING_IMAGE_BYTES) {\n throw new IncomingImageError(\n `Image ${i + 1}: ${(bytes / (1024 * 1024)).toFixed(1)} MB exceeds the ${MAX_INCOMING_IMAGE_BYTES / (1024 * 1024)} MB limit.`,\n );\n }\n return {\n type: 'image',\n source: { type: 'base64', media_type: mediaType, data: base64 },\n } satisfies ImageBlock;\n });\n}\n\n/**\n * Assemble the agent input for a user message that carries images: image\n * blocks first (the order vision providers prefer), then the text block.\n */\nexport function buildUserContentBlocks(\n text: string,\n images: readonly ImageBlock[],\n): ContentBlock[] {\n const blocks: ContentBlock[] = [...images];\n if (text) blocks.push({ type: 'text', text });\n return blocks;\n}\n", "/**\n * Shared IP-address guards for SSRF protection.\n *\n * Exported so `fetch.ts` (tools), `web-search/index.ts` (plugins), and any\n * other package that needs to validate IPs can all consume the same logic.\n * Any future additions (e.g. extra CIDR blocks) need only be made here.\n */\n\nimport * as dns from 'node:dns/promises';\nimport * as net from 'node:net';\n\n/**\n * True if `addr` is in a private / loopback / link-local / reserved / CGNAT /\n * multicast range. `net.isIP` is called by the caller first so `addr` is\n * guaranteed to be a canonical dotted-quad at this point.\n */\nexport function isPrivateIPv4(addr: string): boolean {\n const parts = addr.split('.').map((p) => Number.parseInt(p, 10));\n if (parts.length !== 4 || parts.some((n) => Number.isNaN(n) || n < 0 || n > 255)) {\n return true; // defensive: malformed \u2192 block\n }\n const [a, b, c] = parts as [number, number, number, number];\n if (a === 0) return true; // 0.0.0.0/8 \"this host\"\n if (a === 10) return true; // 10.0.0.0/8 private\n if (a === 127) return true; // 127.0.0.0/8 loopback\n if (a === 169 && b === 254) return true; // 169.254.0.0/16 link-local + AWS/GCE/Azure IMDS\n if (a === 172 && b >= 16 && b <= 31) return true; // 172.16.0.0/12 private\n if (a === 192 && b === 168) return true; // 192.168.0.0/16 private\n if (a === 192 && b === 0 && c === 0) return true; // 192.0.0.0/24 reserved\n if (a === 100 && b >= 64 && b <= 127) return true; // 100.64.0.0/10 CGNAT\n if (a >= 224) return true; // 224.0.0.0/4 multicast + 240.0.0.0/4 reserved\n return false;\n}\n\n/**\n * True if `raw` (an IPv6 literal, already lowercased) is loopback / unique-local /\n * link-local / unspecified / IPv4-mapped-private.\n */\nexport function isPrivateIPv6(raw: string): boolean {\n const lower = raw.toLowerCase();\n if (lower === '::' || lower === '::1') return true; // loopback / unspecified\n\n // Expand to 8-group canonical form so range checks don't have to handle every\n // shorthand notation. Returns null on malformed input \u2014 we conservatively\n // block in that case rather than leaking.\n const groups = expandIPv6(lower);\n if (!groups) return true;\n\n // IPv4-mapped: ::ffff:0:0/96 \u2192 groups[0..5] all 0, groups[6..7] hold the\n // embedded IPv4 as two 16-bit words. Node URL normalises the dotted form to\n // this representation (e.g. ::ffff:127.0.0.1 \u2192 ::ffff:7f00:1).\n if (\n groups[0] === 0 &&\n groups[1] === 0 &&\n groups[2] === 0 &&\n groups[3] === 0 &&\n groups[4] === 0 &&\n groups[5] === 0xffff\n ) {\n const a = (groups[6] ?? 0) >> 8;\n const b = (groups[6] ?? 0) & 0xff;\n const c = (groups[7] ?? 0) >> 8;\n const d = (groups[7] ?? 0) & 0xff;\n return isPrivateIPv4(`${a}.${b}.${c}.${d}`);\n }\n\n const high = groups[0] ?? 0;\n if ((high & 0xfe00) === 0xfc00) return true; // fc00::/7 unique local (fc..fd)\n if ((high & 0xffc0) === 0xfe80) return true; // fe80::/10 link-local\n if ((high & 0xff00) === 0xff00) return true; // ff00::/8 multicast\n return false;\n}\n\n/**\n * Expand an IPv6 string into exactly 8 16-bit numbers. Handles `::` compression.\n * Returns null on malformed input \u2014 caller should treat that as \"block\".\n */\nexport function expandIPv6(addr: string): number[] | null {\n const parts = addr.split('::');\n if (parts.length > 2) return null;\n\n const parseGroups = (s: string): number[] | null => {\n if (s === '') return [];\n const out: number[] = [];\n for (const g of s.split(':')) {\n if (g.length === 0 || g.length > 4) return null;\n const n = Number.parseInt(g, 16);\n if (Number.isNaN(n) || n < 0 || n > 0xffff) return null;\n out.push(n);\n }\n return out;\n };\n\n if (parts.length === 1) {\n const groups = parseGroups(parts[0] ?? '');\n if (groups?.length !== 8) return null;\n return groups;\n }\n\n const head = parseGroups(parts[0] ?? '');\n const tail = parseGroups(parts[1] ?? '');\n if (!head || !tail) return null;\n const fill = 8 - head.length - tail.length;\n if (fill < 0) return null;\n return [...head, ...new Array<number>(fill).fill(0), ...tail];\n}\n\n/**\n * Convenience: throw if `hostname` resolves to a private / loopback IP.\n * Use as a pre-flight check before opening a socket.\n *\n * \u26A0\uFE0F This is not sufficient alone \u2014 connections must also use a pinned\n * dispatcher (so the OS re-uses the already-resolved address) or the same\n * check must be applied after every redirect hop. See `guardedLookup` in\n * `fetch.ts` for the connection-level enforcement.\n */\nexport async function assertNotPrivateHost(hostname: string): Promise<void> {\n const host =\n hostname.startsWith('[') && hostname.endsWith(']') ? hostname.slice(1, -1) : hostname;\n\n if (host === 'localhost' || host.endsWith('.localhost')) {\n throw new Error('fetch: blocked localhost target');\n }\n\n const ipVersion = net.isIP(host);\n if (ipVersion === 4) {\n if (isPrivateIPv4(host)) {\n throw new Error(`fetch: blocked private/loopback address \"${host}\"`);\n }\n } else if (ipVersion === 6) {\n if (isPrivateIPv6(host)) {\n throw new Error(`fetch: blocked private/loopback address \"${host}\"`);\n }\n } else {\n // Hostname \u2014 resolve and reject if ANY record is private.\n try {\n const records = await dns.lookup(host, { all: true });\n for (const r of records) {\n // dns.lookup family: 4 = IPv4, 6 = IPv6\n const bad = r.family === 4 ? isPrivateIPv4(r.address) : isPrivateIPv6(r.address);\n if (bad) {\n throw new Error(`fetch: resolved to private address ${r.address}`);\n }\n }\n } catch (err) {\n if (err instanceof Error && err.message.startsWith('fetch:')) throw err;\n // DNS failure \u2014 let fetch handle it rather than doubling the error.\n }\n }\n}\n", "import { readFileSync, statSync } from 'node:fs';\nimport * as path from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\n/**\n * Cache of resolved instruction text, keyed by the relative path. Bundled\n * instruction files are immutable for the process lifetime, so re-reading them\n * on every call (some callers do so per LLM request) is wasted disk I/O.\n */\nconst textCache = new Map<string, string>();\n\n/** Resolved once \u2014 the candidate roots only depend on this module's location. */\nlet rootCandidates: string[] | undefined;\n\nexport function readBundledInstructionText(relativePath: string): string {\n const cached = textCache.get(relativePath);\n if (cached !== undefined) return cached;\n\n let resolved = '';\n for (const root of instructionRootCandidates()) {\n try {\n resolved = readFileSync(path.join(root, relativePath), 'utf8').trimEnd();\n break;\n } catch {\n // try next candidate\n }\n }\n textCache.set(relativePath, resolved);\n return resolved;\n}\n\nexport function renderInstructionTemplate(\n template: string,\n values: Record<string, string>,\n): string {\n return template.replace(/\\{\\{\\s*([a-zA-Z0-9_.-]+)\\s*\\}\\}/g, (match, key: string) =>\n Object.hasOwn(values, key) ? (values[key] ?? '') : match,\n );\n}\n\nfunction instructionRootCandidates(): string[] {\n if (rootCandidates !== undefined) return rootCandidates;\n const here = path.dirname(fileURLToPath(import.meta.url));\n const candidates = [\n path.resolve(here, '../../instructions'),\n path.resolve(here, '../instructions'),\n path.resolve(here, 'instructions'),\n ];\n rootCandidates = candidates.sort((a, b) => Number(!isDirectory(a)) - Number(!isDirectory(b)));\n return rootCandidates;\n}\n\nfunction isDirectory(candidate: string): boolean {\n try {\n return statSync(candidate).isDirectory();\n } catch {\n return false;\n }\n}\n", "import { expectDefined } from './expect-defined.js';\n\n/**\n * Attempt to close an incomplete JSON object string by auto-closing braces\n * and completing any unclosed double-quoted string values.\n *\n * Strategy:\n * 1. Compute origOpen from the ORIGINAL input (how many braces are unclosed).\n * 2. Add that many closing braces. If result is now valid JSON \u2192 return it.\n * 3. If still invalid: trim trailing whitespace, strip trailing backslash.\n * 4. Walk backwards to detect an unclosed string value.\n * - Quote followed by `:` \u2192 key-name, skip\n * - Quote followed by `,` `}` or end-of-string \u2192 toggle in/out of string\n * 5. If we end INSIDE a string (unclosed opening `\"`), append `\"` + origOpen `}`.\n *\n * Known limitations:\n * - Strings whose content ends with a `\"` character cannot be repaired\n * (algorithm can't distinguish content-`\"` from string-terminator `\"`).\n * - Input ending in bare `:` (incomplete value expression) can't be meaningfully repaired.\n * - Bare `{` returns unchanged.\n * - If origOpen=0 (braces balanced) but string is unclosed, repair is skipped\n * (the input would be valid JSON per JSON.parse, so it's returned as-is).\n */\nexport function completePartialObject(s: string): string {\n if (!s.trim().startsWith('{')) return s;\n if (tryParse(s).ok) return s;\n return repairTruncated(s);\n}\n\nfunction repairTruncated(s: string): string {\n // Single forward scan capturing the structural state at the truncation point:\n // the open-container stack, whether we are inside a string, a dangling escape,\n // and where the last significant (non-trailing-whitespace) character sits.\n const stack: ('{' | '[')[] = [];\n let inString = false;\n let escaped = false;\n let sawKey = false; // have we seen any string (i.e. real content) yet?\n let prevSig = ''; // last significant char seen outside of a string\n let contentEnd = 0; // index just past the last significant char\n // Count unbalanced `{` accumulated *inside* the currently-open string value,\n // so a truncation mid-string like `\"a{` can be balanced before closing it.\n let stringBraceDepth = 0;\n\n for (let i = 0; i < s.length; i++) {\n const ch = expectDefined(s[i]);\n if (inString) {\n contentEnd = i + 1;\n if (escaped) {\n escaped = false;\n continue;\n }\n if (ch === '\\\\') {\n escaped = true;\n continue;\n }\n if (ch === '\"') {\n inString = false;\n prevSig = '\"';\n stringBraceDepth = 0;\n continue;\n }\n if (ch === '{') stringBraceDepth++;\n else if (ch === '}' && stringBraceDepth > 0) stringBraceDepth--;\n continue;\n }\n if (ch === ' ' || ch === '\\t' || ch === '\\n' || ch === '\\r') continue;\n contentEnd = i + 1;\n if (ch === '\"') {\n inString = true;\n sawKey = true;\n stringBraceDepth = 0;\n prevSig = '\"';\n } else if (ch === '{' || ch === '[') {\n stack.push(ch);\n prevSig = ch;\n } else if (ch === '}' || ch === ']') {\n stack.pop();\n prevSig = ch;\n } else {\n prevSig = ch;\n }\n }\n\n // A lone open brace (or anything with no key/content) can't be meaningfully\n // completed \u2014 return it untouched.\n if (!sawKey && !inString) return s;\n\n // Drop trailing whitespace that sits outside any string.\n let result = s.slice(0, contentEnd);\n\n if (inString) {\n // A dangling lone backslash can't begin a valid escape \u2014 drop it.\n if (escaped) {\n result = result.slice(0, -1);\n } else if (endsWithInvalidEscape(result)) {\n // A trailing invalid escape (e.g. `\\}`) can't be completed into valid\n // JSON \u2014 strip the backslash and its bogus escapee.\n result = result.slice(0, -2);\n }\n // Balance braces opened inside the truncated string before closing it.\n if (stringBraceDepth > 0) result += '}'.repeat(stringBraceDepth);\n result += '\"';\n } else if (prevSig === ':') {\n // A key with no value (e.g. `{\"k\":`) \u2014 complete it to null.\n result += 'null';\n }\n\n // Close any still-open containers in reverse order.\n for (let k = stack.length - 1; k >= 0; k--) {\n result += stack[k] === '{' ? '}' : ']';\n }\n\n // Last resort: an empty value sitting before an existing close (`{\"k\":}`)\n // leaves invalid JSON \u2014 fill it with null.\n if (!tryParse(result).ok) {\n const patched = result.replace(/:(\\s*)([}\\]])/g, ':null$2');\n if (tryParse(patched).ok) result = patched;\n }\n\n return result;\n}\n\nconst VALID_ESCAPE = new Set(['\"', '\\\\', '/', 'b', 'f', 'n', 'r', 't', 'u']);\n\n/** True when `str` ends with a backslash escape that JSON does not allow. */\nfunction endsWithInvalidEscape(str: string): boolean {\n const last = str[str.length - 1];\n if (str[str.length - 2] !== '\\\\' || last === undefined) return false;\n if (VALID_ESCAPE.has(last)) return false;\n // The backslash must itself be unescaped (odd run of backslashes before it).\n let backslashes = 0;\n for (let k = str.length - 2; k >= 0 && str[k] === '\\\\'; k--) backslashes++;\n return backslashes % 2 === 1;\n}\n\nfunction tryParse(s: string): { ok: true; value: unknown } | { ok: false } {\n try {\n return { ok: true, value: JSON.parse(s) };\n } catch {\n return { ok: false };\n }\n}\n", "/**\n * Minimal JSON Schema validator \u2014 covers the subset needed for plugin\n * configSchema validation and tool inputSchema sanity checks. Intentionally\n * small (~80 lines, zero deps) and tolerant: unknown keywords are ignored so\n * authors can mix in non-standard extensions without breaking validation.\n *\n * NOT for full JSON Schema 2020-12 conformance. If a plugin needs $ref,\n * conditional schemas, format validation, or anything else exotic, it should\n * bring its own ajv-based validator and call this only for the cheap path.\n */\nimport type { JSONSchema } from '../types/tool.js';\n\nexport interface ValidationError {\n path: string;\n message: string;\n}\n\nexport interface ValidationResult {\n ok: boolean;\n errors: ValidationError[];\n}\n\nexport function validateAgainstSchema(value: unknown, schema: JSONSchema): ValidationResult {\n const errors: ValidationError[] = [];\n walk(value, schema, '', errors, 0);\n return { ok: errors.length === 0, errors };\n}\n\n/**\n * Maximum nesting depth before the validator stops recursing and reports a\n * \"schema too deep\" error. Deeply nested input (e.g. batch_tool_use with 100\n * nested calls \u2192 tool_use \u2192 input) can otherwise hit `RangeError: Maximum\n * call stack size exceeded` and crash the tool executor.\n *\n * 64 is generous: real-world tool schemas rarely nest beyond 5-6 levels, and\n * even pathological inputs (deeply recursive JSON) stay well under this.\n * The limit is a safety net against unbounded recursion, not a tight bound.\n */\nconst MAX_SCHEMA_DEPTH = 64;\n\nfunction walk(\n value: unknown,\n schema: JSONSchema,\n path: string,\n errors: ValidationError[],\n depth: number,\n): void {\n // P2 #8 (before-release.md): cap recursion depth to prevent\n // `RangeError: Maximum call stack size exceeded` on deeply nested input.\n // Push a validation error and stop descending \u2014 the caller still gets a\n // usable (ok: false) result instead of a crash.\n if (depth > MAX_SCHEMA_DEPTH) {\n errors.push({\n path: path || '<root>',\n message: `schema nesting exceeds maximum depth (${MAX_SCHEMA_DEPTH})`,\n });\n return;\n }\n if (schema.enum !== undefined) {\n if (!enumIncludes(schema.enum, value)) {\n errors.push({\n path: path || '<root>',\n message: `expected one of ${JSON.stringify(schema.enum)}, got ${JSON.stringify(value)}`,\n });\n return;\n }\n }\n\n if (typeof schema.type === 'string') {\n if (!checkType(value, schema.type)) {\n errors.push({\n path: path || '<root>',\n message: `expected ${schema.type}, got ${describeType(value)} (${previewValue(value)})`,\n });\n return;\n }\n }\n\n if (schema.type === 'object' && isPlainObject(value)) {\n const obj = value as Record<string, unknown>;\n for (const req of schema.required ?? []) {\n if (!(req in obj)) {\n const expected = schema.properties?.[req]?.type;\n errors.push({\n path: joinPath(path, req),\n message: `required property missing${typeof expected === 'string' ? ` (expected ${expected})` : ''}`,\n });\n }\n }\n if (schema.properties) {\n for (const [key, subSchema] of Object.entries(schema.properties)) {\n if (key in obj) {\n walk(obj[key], subSchema, joinPath(path, key), errors, depth + 1);\n }\n }\n }\n }\n\n if (schema.type === 'array' && Array.isArray(value) && schema.items) {\n for (let i = 0; i < value.length; i++) {\n walk(value[i], schema.items as JSONSchema, `${path}[${i}]`, errors, depth + 1);\n }\n }\n}\n\nexport interface CoercionResult {\n value: unknown;\n /** True when at least one leaf was rewritten. */\n changed: boolean;\n}\n\n/**\n * Best-effort, lossless coercion of a value toward a JSON Schema. Models \u2014\n * especially through OpenAI-compatible proxies \u2014 frequently deliver\n * arguments with the right *content* in the wrong *type*: numbers and\n * booleans encoded as strings (\"5\", \"true\"), scalars where a string is\n * expected, or a whole nested object serialized into a JSON string.\n *\n * Only conversions that cannot lose information are applied:\n * - string \u2192 number/integer when the whole trimmed string parses cleanly\n * - string \"true\"/\"false\" \u2192 boolean\n * - number/boolean \u2192 string when a string is expected\n * - JSON-serialized string \u2192 object/array when the parse yields that shape\n * Recurses into `properties`/`items`. Returns the (possibly new) value and\n * whether anything changed \u2014 callers should re-validate before trusting it.\n */\nexport function coerceAgainstSchema(value: unknown, schema: JSONSchema): CoercionResult {\n return coerceWalk(value, schema, 0);\n}\n\nfunction coerceWalk(value: unknown, schema: JSONSchema, depth: number): CoercionResult {\n if (depth > MAX_SCHEMA_DEPTH) return { value, changed: false };\n\n const type = typeof schema.type === 'string' ? schema.type : undefined;\n\n // Leaf conversions (only when the current type does NOT already match).\n if (type && !checkType(value, type)) {\n if (type === 'string' && (typeof value === 'number' || typeof value === 'boolean')) {\n return { value: String(value), changed: true };\n }\n if ((type === 'number' || type === 'integer') && typeof value === 'string') {\n const trimmed = value.trim();\n if (trimmed !== '' && /^-?(\\d+\\.?\\d*|\\.\\d+)([eE][+-]?\\d+)?$/.test(trimmed)) {\n const num = Number(trimmed);\n if (!Number.isNaN(num) && (type === 'number' || Number.isInteger(num))) {\n return { value: num, changed: true };\n }\n }\n return { value, changed: false };\n }\n if (type === 'boolean' && typeof value === 'string') {\n const lowered = value.trim().toLowerCase();\n if (lowered === 'true') return { value: true, changed: true };\n if (lowered === 'false') return { value: false, changed: true };\n return { value, changed: false };\n }\n if ((type === 'object' || type === 'array') && typeof value === 'string') {\n // A nested structure serialized into a string (double-encoded args).\n try {\n const parsed: unknown = JSON.parse(value);\n if (checkType(parsed, type)) {\n // Recurse so leaves inside the revived structure also coerce.\n return { value: coerceWalk(parsed, schema, depth + 1).value, changed: true };\n }\n } catch {\n // fall through \u2014 leave as-is, validation will report it\n }\n return { value, changed: false };\n }\n return { value, changed: false };\n }\n\n // Structural recursion.\n if (type === 'object' && isPlainObject(value) && schema.properties) {\n const obj = value as Record<string, unknown>;\n let changed = false;\n const out: Record<string, unknown> = { ...obj };\n for (const [key, subSchema] of Object.entries(schema.properties)) {\n if (!(key in obj)) continue;\n const r = coerceWalk(obj[key], subSchema, depth + 1);\n if (r.changed) {\n out[key] = r.value;\n changed = true;\n }\n }\n return changed ? { value: out, changed } : { value, changed: false };\n }\n\n if (type === 'array' && Array.isArray(value) && schema.items) {\n let changed = false;\n const out = value.map((item) => {\n const r = coerceWalk(item, schema.items as JSONSchema, depth + 1);\n if (r.changed) changed = true;\n return r.value;\n });\n return changed ? { value: out, changed } : { value, changed: false };\n }\n\n return { value, changed: false };\n}\n\nfunction checkType(value: unknown, type: string): boolean {\n switch (type) {\n case 'string':\n return typeof value === 'string';\n case 'number':\n return typeof value === 'number' && !Number.isNaN(value);\n case 'integer':\n return typeof value === 'number' && Number.isInteger(value);\n case 'boolean':\n return typeof value === 'boolean';\n case 'null':\n return value === null;\n case 'array':\n return Array.isArray(value);\n case 'object':\n return isPlainObject(value);\n default:\n return true;\n }\n}\n\nfunction isPlainObject(v: unknown): boolean {\n return typeof v === 'object' && v !== null && !Array.isArray(v);\n}\n\nfunction describeType(v: unknown): string {\n if (v === null) return 'null';\n if (Array.isArray(v)) return 'array';\n return typeof v;\n}\n\n/** Short serialized preview of the offending value for error messages. */\nfunction previewValue(v: unknown): string {\n try {\n const s = JSON.stringify(v);\n if (s === undefined) return String(v);\n return s.length > 80 ? `${s.slice(0, 80)}\u2026` : s;\n } catch {\n return String(v);\n }\n}\n\nfunction joinPath(parent: string, key: string): string {\n if (!parent) return key;\n return `${parent}.${key}`;\n}\n\nfunction enumIncludes(values: readonly unknown[], value: unknown): boolean {\n if (value === null || typeof value !== 'object') return values.includes(value);\n return values.some((candidate) => deepEqual(candidate, value));\n}\n\nfunction deepEqual(a: unknown, b: unknown): boolean {\n if (a === b) return true;\n if (typeof a !== typeof b) return false;\n if (a === null || b === null) return a === b;\n if (Array.isArray(a) && Array.isArray(b)) {\n return a.length === b.length && a.every((v, i) => deepEqual(v, b[i]));\n }\n if (typeof a === 'object' && typeof b === 'object') {\n const ak = Object.keys(a as object);\n const bk = Object.keys(b as object);\n if (ak.length !== bk.length) return false;\n return ak.every((k) =>\n deepEqual((a as Record<string, unknown>)[k], (b as Record<string, unknown>)[k]),\n );\n }\n return false;\n}\n", "import type { CustomModelDefinition } from '../types/config.js';\n\n/**\n * Merge per-provider `customModels` into top-level `configModels`.\n *\n * Keys present in `configModels` always win over `providerCustomModels`\n * when the same model id appears in both places. This lets the user\n * override provider-attached definitions from the top-level config.\n *\n * Pure: never mutates its inputs.\n */\nexport function mergeCustomModelDefs(\n providerCustomModels: Record<string, CustomModelDefinition> | undefined,\n configModels: Record<string, CustomModelDefinition> | undefined,\n): Record<string, CustomModelDefinition> | undefined {\n const out: Record<string, CustomModelDefinition> = {};\n\n // Layer 1: provider-level definitions (weaker).\n if (providerCustomModels) {\n for (const [id, def] of Object.entries(providerCustomModels)) {\n out[id] = { ...def };\n }\n }\n\n // Layer 2: top-level definitions (stronger).\n if (configModels) {\n for (const [id, def] of Object.entries(configModels)) {\n out[id] = { ...def }; // top-level overwrites provider-level\n }\n }\n\n if (Object.keys(out).length === 0) return undefined;\n return out;\n}\n", "import type {\n ModelsDevModel,\n ModelsDevProvider,\n ModelsDevPayload,\n} from '../types/models-registry.js';\n\n// Magic keys in the overlay payload that signal deletions rather than additions.\nconst REMOVE_PROVIDERS_KEY = '_removeProviders';\nconst REMOVE_MODELS_KEY = '_removeModels';\n\n/**\n * Deep-merge a curated `overlay` payload on top of a `base` payload (both in\n * the models.dev `api.json` shape). The overlay always wins: it can add\n * providers/models the base lacks and override fields the base gets wrong.\n *\n * NEW: The overlay also supports two magic keys for removal:\n *\n * `_removeProviders` (string[]) \u2014 provider ids to DELETE from the result.\n * `_removeModels` (Record<string, string[]>) \u2014 per-provider model ids to\n * delete from that provider's model list.\n *\n * Removals are applied AFTER the merge pass so the overlay can add and then\n * selectively strip away unwanted entries from the base catalog.\n *\n * Precedence rules:\n * - Provider present in both \u2192 scalar fields (`name`, `npm`, `api`, `env`,\n * `doc`) come from the overlay when set; `models` maps merge by model id.\n * - Provider only in the overlay \u2192 added wholesale.\n * - Model present in both \u2192 overlay model fields override base model fields\n * (`{ ...base, ...overlay }`), with the nested `limit` / `cost` /\n * `modalities` objects merged one level deeper so an overlay can fix just\n * `limit.context` without restating the rest of the model.\n * - Model only in the overlay \u2192 added.\n *\n * Pure: never mutates its inputs.\n */\nexport function mergeModelsPayload(\n base: ModelsDevPayload,\n overlay: ModelsDevPayload,\n): ModelsDevPayload {\n // Step 1: extract removal directives before the merge loop\n const removeProviders: string[] = Array.isArray(overlay[REMOVE_PROVIDERS_KEY])\n ? (overlay[REMOVE_PROVIDERS_KEY] as string[])\n : [];\n const removeModels: Record<string, string[]> =\n overlay[REMOVE_MODELS_KEY] && typeof overlay[REMOVE_MODELS_KEY] === 'object'\n ? (overlay[REMOVE_MODELS_KEY] as unknown as Record<string, string[]>)\n : {};\n\n // Step 2: conventional deep-merge (add/override only)\n const out: ModelsDevPayload = {};\n for (const [id, provider] of Object.entries(base)) {\n out[id] = cloneProvider(provider);\n }\n for (const [id, ovProvider] of Object.entries(overlay)) {\n // Skip magic keys\n if (id === REMOVE_PROVIDERS_KEY || id === REMOVE_MODELS_KEY) continue;\n const existing = out[id];\n out[id] = existing ? mergeProvider(existing, ovProvider) : cloneProvider(ovProvider);\n }\n\n // Step 3: apply removals\n for (const providerId of removeProviders) {\n delete out[providerId];\n }\n for (const [providerId, modelIds] of Object.entries(removeModels)) {\n const provider = out[providerId];\n if (!provider?.models) continue;\n for (const modelId of modelIds) {\n delete provider.models[modelId];\n }\n }\n\n return out;\n}\n\nfunction mergeProvider(base: ModelsDevProvider, overlay: ModelsDevProvider): ModelsDevProvider {\n const models: Record<string, ModelsDevModel> = {};\n for (const [mid, m] of Object.entries(base.models ?? {})) {\n models[mid] = { ...m };\n }\n for (const [mid, ovModel] of Object.entries(overlay.models ?? {})) {\n const existing = models[mid];\n models[mid] = existing ? mergeModel(existing, ovModel) : { ...ovModel };\n }\n return {\n ...base,\n // Overlay scalar fields win when explicitly provided; otherwise keep base.\n ...stripUndefined({\n id: overlay.id,\n name: overlay.name,\n npm: overlay.npm,\n api: overlay.api,\n env: overlay.env,\n doc: overlay.doc,\n }),\n models,\n };\n}\n\nfunction mergeModel(base: ModelsDevModel, overlay: ModelsDevModel): ModelsDevModel {\n const merged: ModelsDevModel = { ...base, ...overlay };\n // One level deeper for the structured fields so a partial overlay (e.g. only\n // `limit.context`) doesn't blow away the base's other sub-fields.\n if (base.limit || overlay.limit) {\n merged.limit = { ...base.limit, ...overlay.limit };\n }\n if (base.cost || overlay.cost) {\n merged.cost = { ...base.cost, ...overlay.cost };\n }\n if (base.modalities || overlay.modalities) {\n merged.modalities = { ...base.modalities, ...overlay.modalities };\n }\n return merged;\n}\n\nfunction cloneProvider(p: ModelsDevProvider): ModelsDevProvider {\n const models: Record<string, ModelsDevModel> = {};\n for (const [mid, m] of Object.entries(p.models ?? {})) {\n models[mid] = { ...m };\n }\n return { ...p, models };\n}\n\n/** Drop keys whose value is `undefined` so they don't clobber base fields. */\nfunction stripUndefined<T extends Record<string, unknown>>(obj: T): Partial<T> {\n const out: Partial<T> = {};\n for (const [k, v] of Object.entries(obj)) {\n if (v !== undefined) out[k as keyof T] = v as T[keyof T];\n }\n return out;\n}\n", "export type NewlineStyle = 'lf' | 'crlf' | 'cr';\n\nexport function detectNewlineStyle(text: string): NewlineStyle {\n let lf = 0;\n let crlf = 0;\n let cr = 0;\n for (let i = 0; i < text.length; i++) {\n const c = text.charCodeAt(i);\n if (c === 0x0d) {\n if (text.charCodeAt(i + 1) === 0x0a) {\n crlf++;\n i++;\n } else {\n cr++;\n }\n } else if (c === 0x0a) {\n lf++;\n }\n }\n if (crlf > lf && crlf > cr) return 'crlf';\n if (cr > lf && cr > crlf) return 'cr';\n return 'lf';\n}\n\nexport function toStyle(text: string, style: NewlineStyle): string {\n const normalized = text.replace(/\\r\\n/g, '\\n').replace(/\\r/g, '\\n');\n if (style === 'lf') return normalized;\n if (style === 'crlf') return normalized.replace(/\\n/g, '\\r\\n');\n return normalized.replace(/\\n/g, '\\r');\n}\n\nexport function normalizeToLf(text: string): string {\n return text.replace(/\\r\\n/g, '\\n').replace(/\\r/g, '\\n');\n}\n", "/**\n * Process-wide performance profile.\n *\n * `WRONGSTACK_PERF_PROFILE` (alias `WSTACK_PERF_PROFILE`):\n * - `balanced` (default) \u2014 current throughput-oriented defaults\n * - `frugal` / `cimri` \u2014 lower CPU concurrency, leaner SQLite caches,\n * coarser UI stream paint. Correctness and APIs unchanged.\n */\n\nexport type PerfProfile = 'balanced' | 'frugal';\n\n/**\n * Long-lived IPC daemons default to `frugal`.\n *\n * The SQLite pragmas below are per *connection*, and a daemon holds its\n * connections for its whole lifetime \u2014 the codebase-index daemon measured\n * 336MB RSS, essentially all of it the 128MiB page cache plus 512MiB mmap\n * reservation, while sitting idle. A foreground host pays that cost briefly;\n * a daemon pays it for hours. An explicit `WRONGSTACK_PERF_PROFILE` from the\n * operator still wins in both directions.\n */\nlet daemonDefaults = false;\n\n/** Call once from a daemon entry point, before opening any store. */\nexport function useDaemonPerfDefaults(): void {\n daemonDefaults = true;\n}\n\n/** Resolve the active profile from the environment (evaluated each call). */\nexport function getPerfProfile(): PerfProfile {\n const explicit = process.env.WRONGSTACK_PERF_PROFILE ?? process.env.WSTACK_PERF_PROFILE;\n if (explicit === undefined || explicit.trim() === '') {\n return daemonDefaults ? 'frugal' : 'balanced';\n }\n const raw = explicit.trim().toLowerCase();\n if (raw === 'frugal' || raw === 'cimri' || raw === 'low' || raw === 'eco') {\n return 'frugal';\n }\n return 'balanced';\n}\n\nexport function isFrugalPerf(): boolean {\n return getPerfProfile() === 'frugal';\n}\n\n/** Parallel file-parse batch size for the codebase indexer. */\nexport function indexParallelBatchSize(availableCores: number): number {\n const cores = Math.max(1, Math.floor(availableCores) || 1);\n if (isFrugalPerf()) {\n // Serial-ish: at most 4 files concurrent, never more than core count.\n return Math.min(4, cores);\n }\n // Historical default: cores\u00D74, hard-capped at 40.\n return Math.min(cores * 4, 40);\n}\n\n/**\n * SQLite page-cache / mmap sizes in KiB (negative PRAGMA = KiB units for cache).\n * Frugal keeps correctness; just spends less RSS.\n */\nexport function sqliteCachePragmas(): { cacheSizeKiB: number; mmapBytes: number } {\n if (isFrugalPerf()) {\n return { cacheSizeKiB: 16_384, mmapBytes: 64 * 1024 * 1024 }; // 16 MiB / 64 MiB\n }\n return { cacheSizeKiB: 131_072, mmapBytes: 512 * 1024 * 1024 }; // 128 MiB / 512 MiB\n}\n\n/** sage store defaults (slightly smaller than index). */\nexport function SageCachePragmas(): { cacheSizeKiB: number; mmapBytes: number } {\n if (isFrugalPerf()) {\n return { cacheSizeKiB: 8_192, mmapBytes: 32 * 1024 * 1024 }; // 8 MiB / 32 MiB\n }\n return { cacheSizeKiB: 65_536, mmapBytes: 256 * 1024 * 1024 }; // 64 MiB / 256 MiB\n}\n\n/**\n * TUI stream paint interval. Higher = fewer React dispatches (less CPU/heap\n * churn). Balanced keeps the historical ~10fps; frugal ~6\u20137fps.\n */\nexport function tuiStreamFlushMs(): number {\n return isFrugalPerf() ? 150 : 100;\n}\n", "/**\n * Process-liveness probing.\n *\n * This predicate was copy-pasted across six subsystems (session registry, HQ\n * auth store, director state, fleet notifier, recovery lock, mailbox lock)\n * with four different semantics. The dangerous variant was `catch { return\n * false }`: on POSIX, `process.kill(pid, 0)` throws EPERM when the process\n * EXISTS but belongs to another user (or runs elevated), so a bare catch\n * reports a live process as dead. Callers then \"reclaim\" resources that are\n * still owned \u2014 the director-state lock would be stolen from a running\n * director, and live sessions were pruned from the registry.\n *\n * Everything that asks \"is this pid alive?\" must go through here.\n */\n\n/**\n * True iff `pid` names a live process.\n *\n * POSIX: `process.kill(pid, 0)` succeeds for our own processes, throws EPERM\n * for processes we may not signal (alive, just not ours), and throws ESRCH\n * once the pid is gone.\n * Windows (Node 22+): the same call succeeds when the process exists and\n * throws otherwise.\n *\n * Deliberately fails CLOSED on an unrecognized error code \u2014 reporting \"dead\"\n * for an unknown failure is the conservative answer for the pruning callers,\n * which is why lock owners that must not be displaced (see\n * `single-instance-mailbox`) layer a second, platform-specific check on top.\n */\nexport function isPidAlive(pid: number): boolean {\n if (!Number.isInteger(pid) || pid <= 0) return false;\n if (pid === process.pid) return true;\n try {\n process.kill(pid, 0);\n return true;\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code;\n /* v8 ignore next -- platform/permission-specific: EPERM means alive but owned by another user */\n if (code === 'EPERM') return true;\n return false;\n }\n}\n", "import * as fs from 'node:fs';\nimport * as fsPromises from 'node:fs/promises';\nimport * as path from 'node:path';\nimport { atomicWrite } from './atomic-write.js';\nimport { isUlid, ulid } from './ulid.js';\n\nexport const PROJECT_IDENTITY_VERSION = 1 as const;\nexport const PROJECT_ID_PREFIX = 'proj_';\nexport const PROJECT_IDENTITY_RELATIVE_PATH = path.join('.wrongstack', 'project.json');\n\nexport interface ProjectIdentityFile {\n version: typeof PROJECT_IDENTITY_VERSION;\n projectId: string;\n}\n\nexport interface EnsureProjectIdentityResult {\n identity: ProjectIdentityFile;\n created: boolean;\n}\n\nexport interface RekeyProjectIdentityResult {\n previous?: ProjectIdentityFile | undefined;\n identity: ProjectIdentityFile;\n}\n\nconst PROJECT_GITIGNORE_RULES = [\n '.wrongstack/',\n '!/.wrongstack/',\n '/.wrongstack/*',\n '!/.wrongstack/project.json',\n] as const;\n\nexport function projectIdentityPath(projectRoot: string): string {\n return path.join(projectRoot, PROJECT_IDENTITY_RELATIVE_PATH);\n}\n\nexport function createProjectId(seedTime: number = Date.now()): string {\n return `${PROJECT_ID_PREFIX}${ulid(seedTime)}`;\n}\n\nexport function isProjectId(value: string): boolean {\n return value.startsWith(PROJECT_ID_PREFIX) && isUlid(value.slice(PROJECT_ID_PREFIX.length));\n}\n\nexport function readProjectIdentitySync(projectRoot: string): ProjectIdentityFile | undefined {\n const filePath = projectIdentityPath(projectRoot);\n try {\n return parseProjectIdentity(fs.readFileSync(filePath, 'utf8'), filePath);\n } catch (error) {\n if (isMissingFileError(error)) return undefined;\n throw error;\n }\n}\n\nexport async function readProjectIdentity(\n projectRoot: string,\n): Promise<ProjectIdentityFile | undefined> {\n const filePath = projectIdentityPath(projectRoot);\n try {\n return parseProjectIdentity(await fsPromises.readFile(filePath, 'utf8'), filePath);\n } catch (error) {\n if (isMissingFileError(error)) return undefined;\n throw error;\n }\n}\n\nexport async function ensureProjectIdentity(\n projectRoot: string,\n idFactory: () => string = createProjectId,\n): Promise<EnsureProjectIdentityResult> {\n const existing = await readProjectIdentity(projectRoot);\n if (existing) return { identity: existing, created: false };\n\n const filePath = projectIdentityPath(projectRoot);\n const identity = makeIdentity(idFactory());\n await fsPromises.mkdir(path.dirname(filePath), { recursive: true });\n\n try {\n await fsPromises.writeFile(filePath, serializeProjectIdentity(identity), {\n encoding: 'utf8',\n flag: 'wx',\n });\n return { identity, created: true };\n } catch (error) {\n if (!isAlreadyExistsError(error)) throw error;\n const winner = await readProjectIdentity(projectRoot);\n if (!winner) throw error;\n return { identity: winner, created: false };\n }\n}\n\nexport async function rekeyProjectIdentity(\n projectRoot: string,\n idFactory: () => string = createProjectId,\n): Promise<RekeyProjectIdentityResult> {\n const previous = await readProjectIdentity(projectRoot);\n const identity = makeIdentity(idFactory());\n const filePath = projectIdentityPath(projectRoot);\n await fsPromises.mkdir(path.dirname(filePath), { recursive: true });\n await atomicWrite(filePath, serializeProjectIdentity(identity));\n return { previous, identity };\n}\n\n/**\n * Keep runtime state ignored while allowing the small, explicitly shared\n * WrongStack project contract to travel with the repository.\n */\nexport async function ensureProjectGitignore(projectRoot: string): Promise<void> {\n const filePath = path.join(projectRoot, '.gitignore');\n let content = '';\n try {\n content = await fsPromises.readFile(filePath, 'utf8');\n } catch (error) {\n if (!isMissingFileError(error)) throw error;\n }\n\n const hadTrailingNewline = content.endsWith('\\n');\n const lines = content.length === 0 ? [] : content.split(/\\r?\\n/);\n if (hadTrailingNewline) lines.pop();\n\n let changed = false;\n for (let index = 0; index < lines.length; index++) {\n if (lines[index]?.trim() === '.wrongstack/*') {\n lines[index] = '.wrongstack/';\n changed = true;\n }\n }\n\n for (const entry of PROJECT_GITIGNORE_RULES) {\n if (!lines.some((line) => line.trim() === entry)) {\n if (entry === '.wrongstack/' && lines.length > 0 && lines.at(-1) !== '') lines.push('');\n lines.push(entry);\n changed = true;\n }\n }\n\n if (!changed) return;\n await fsPromises.writeFile(filePath, `${lines.join('\\n')}\\n`, 'utf8');\n}\n\nfunction makeIdentity(projectId: string): ProjectIdentityFile {\n if (!isProjectId(projectId)) {\n throw new Error(`Invalid WrongStack project id: ${projectId}`);\n }\n return { version: PROJECT_IDENTITY_VERSION, projectId };\n}\n\nfunction parseProjectIdentity(raw: string, filePath: string): ProjectIdentityFile {\n let value: unknown;\n try {\n value = JSON.parse(raw);\n } catch {\n throw new Error(`Invalid JSON in WrongStack project identity file: ${filePath}`);\n }\n if (typeof value !== 'object' || value === null) {\n throw new Error(`Invalid WrongStack project identity file: ${filePath}`);\n }\n const record = value as Record<string, unknown>;\n if (record['version'] !== PROJECT_IDENTITY_VERSION) {\n throw new Error(`Unsupported WrongStack project identity version in ${filePath}`);\n }\n if (typeof record['projectId'] !== 'string' || !isProjectId(record['projectId'])) {\n throw new Error(`Invalid projectId in WrongStack project identity file: ${filePath}`);\n }\n return { version: PROJECT_IDENTITY_VERSION, projectId: record['projectId'] };\n}\n\nfunction serializeProjectIdentity(identity: ProjectIdentityFile): string {\n return `${JSON.stringify(identity, null, 2)}\\n`;\n}\n\nfunction isMissingFileError(error: unknown): boolean {\n return (error as NodeJS.ErrnoException | undefined)?.code === 'ENOENT';\n}\n\nfunction isAlreadyExistsError(error: unknown): boolean {\n return (error as NodeJS.ErrnoException | undefined)?.code === 'EEXIST';\n}\n", "import { randomBytes } from 'node:crypto';\n\n/**\n * Crockford base32 alphabet (excludes I, L, O, U to avoid ambiguity).\n */\nconst ENCODING = '0123456789ABCDEFGHJKMNPQRSTVWXYZ';\nconst ENCODING_LEN = ENCODING.length;\nconst TIME_LEN = 10;\nconst RANDOM_LEN = 16;\n\nfunction encodeTime(now: number, len: number): string {\n let mod: number;\n let str = '';\n for (let i = len - 1; i >= 0; i--) {\n mod = now % ENCODING_LEN;\n str = ENCODING[mod] + str;\n now = (now - mod) / ENCODING_LEN;\n }\n return str;\n}\n\nfunction encodeRandom(len: number): string {\n const bytes = randomBytes(len);\n let str = '';\n for (let i = 0; i < len; i++) {\n str += ENCODING[(bytes[i] as number) % ENCODING_LEN];\n }\n return str;\n}\n\n/**\n * Generate a ULID \u2014 a 26-char Crockford-base32 identifier whose first 10 chars\n * encode the millisecond timestamp (so IDs sort lexicographically by creation\n * time) followed by 16 chars of randomness. Zero runtime dependencies.\n *\n * The codebase convention is \"IDs are ULIDs\"; use this for any new store key.\n */\nexport function ulid(seedTime: number = Date.now()): string {\n return encodeTime(seedTime, TIME_LEN) + encodeRandom(RANDOM_LEN);\n}\n\n/** True for a well-formed 26-char Crockford-base32 ULID. */\nexport function isUlid(value: string): boolean {\n if (value.length !== TIME_LEN + RANDOM_LEN) return false;\n for (const ch of value) {\n if (!ENCODING.includes(ch)) return false;\n }\n return true;\n}\n", "/**\n * Compile a user-supplied regex with conservative bounds against ReDoS.\n *\n * Duplicated from @wrongstack/tools/_regex.ts to avoid a circular\n * dependency (tools depends on core, not vice versa). Keep both copies\n * in sync if the heuristics change.\n *\n * V8's regex engine is backtracking-based and cannot interrupt a\n * synchronous match \u2014 a pattern like `(a+)+$` against a sufficiently\n * long line will pin a worker for seconds.\n */\n\nconst MAX_PATTERN_LEN = 512;\n\n// Heuristics for catastrophic-backtracking constructs.\nconst DANGEROUS_PATTERNS: ReadonlyArray<RegExp> = [\n /(\\([^)]*[+*][^)]*\\))[+*]/, // (a+)+, (.*)+, etc\n /(\\(\\?:[^)]*[+*][^)]*\\))[+*]/, // same, with non-capturing group\n];\n\nexport interface CompileResult {\n ok: true;\n regex: RegExp;\n}\n\nexport interface CompileFail {\n ok: false;\n reason: string;\n}\n\nexport function compileUserRegex(pattern: string, flags: string): CompileResult | CompileFail {\n if (typeof pattern !== 'string') {\n return { ok: false, reason: 'pattern must be a string' };\n }\n if (pattern.length === 0) {\n return { ok: false, reason: 'pattern is empty' };\n }\n if (pattern.length > MAX_PATTERN_LEN) {\n return { ok: false, reason: `pattern exceeds ${MAX_PATTERN_LEN} characters` };\n }\n for (const rx of DANGEROUS_PATTERNS) {\n if (rx.test(pattern)) {\n return {\n ok: false,\n reason:\n 'pattern looks vulnerable to catastrophic backtracking \u2014 rewrite without nested quantifiers',\n };\n }\n }\n try {\n return { ok: true, regex: new RegExp(pattern, flags) };\n } catch (err) {\n return {\n ok: false,\n reason: err instanceof Error ? err.message : 'invalid regex',\n };\n }\n}\n", "import { toErrorMessage } from './error.js';\n\nexport interface SafeParseResult<T> {\n ok: boolean;\n value?: T | undefined;\n error?: string | undefined;\n}\n\nexport function safeParse<T = unknown>(input: string, maxBytes = 5_000_000): SafeParseResult<T> {\n if (Buffer.byteLength(input, 'utf8') > maxBytes) {\n return { ok: false, error: `Input exceeds limit (${maxBytes} bytes)` };\n }\n try {\n return { ok: true, value: JSON.parse(input) as T };\n } catch (err) {\n return {\n ok: false,\n error: toErrorMessage(err),\n };\n }\n}\n\nexport function safeStringify(value: unknown, pretty = false): string {\n const seen = new WeakSet();\n const replacer = (_k: string, v: unknown): unknown => {\n if (typeof v === 'bigint') return v.toString();\n if (v instanceof Error) {\n return { name: v.name, message: v.message, stack: v.stack };\n }\n if (typeof v === 'object' && v !== null) {\n if (seen.has(v as object)) return '[Circular]';\n seen.add(v as object);\n }\n return v;\n };\n try {\n return JSON.stringify(value, replacer, pretty ? 2 : undefined) ?? 'null';\n } catch (err) {\n return JSON.stringify({\n __serialization_error: toErrorMessage(err),\n });\n }\n}\n\n/**\n * Attempt to parse JSON5-style input and return a valid JSON string.\n * Handles trailing commas, line/block comments, and unquoted keys\n * that are common in provider output.\n *\n * Returns the sanitized string if it parses successfully as JSON,\n * or `null` if the input cannot be made valid. Callers use this to\n * decide whether to proceed with the parsed result or fall back to\n * raw handling.\n */\nexport function sanitizeJsonString(s: string): string | null {\n let out = s.trim();\n\n // Stage 1: strip line and block comments outside JSON string values.\n out = stripJsonComments(out);\n\n // Stage 2: strip trailing commas before } or ]\n out = out.replace(/,(\\s*[}\\]])/g, '$1');\n\n // Stage 3: escape literal control characters that appear *inside* string\n // values. Models frequently emit raw newlines/tabs inside a code payload\n // (e.g. edit's old_string/new_string) instead of the required \\n / \\t, which\n // makes JSON.parse throw. This is the single most common malformed-args case.\n out = escapeControlCharsInStrings(out);\n\n // Stage 4: attempt full parse; return null if it fails so callers can\n // distinguish \"already valid JSON\" from \"unrecoverable\".\n try {\n JSON.parse(out);\n return out;\n } catch {\n return null; // stripped but still not valid JSON; caller handles it\n }\n}\n\n/**\n * Strip a Markdown code-fence wrapper from a payload.\n *\n * Models occasionally return tool-call arguments wrapped in ```json fences\n * (or embedded in prose around one) instead of bare JSON. Returns the inner\n * content when the input starts with a fence (closing fence optional, so a\n * truncated stream still unwraps) or contains one complete fenced block;\n * returns null when no fence is present. Callers should only invoke this\n * after a direct parse failed, so fences inside legitimate string values are\n * never touched.\n */\nexport function stripCodeFences(s: string): string | null {\n const trimmed = s.trim();\n // Whole-payload fence: ```lang? \u2026 ```? (closer optional for truncation)\n const opener = /^```[\\w+-]*[ \\t]*\\r?\\n?/.exec(trimmed);\n if (opener) {\n const inner = trimmed.slice(opener[0].length).replace(/(\\r?\\n)?[ \\t]*```[ \\t]*$/, '');\n return inner.trim();\n }\n // Fence embedded in prose: extract the first complete fenced block.\n const embedded = /```[\\w+-]*[ \\t]*\\r?\\n([\\s\\S]*?)\\r?\\n[ \\t]*```/.exec(trimmed);\n if (embedded) return (embedded[1] ?? '').trim();\n return null;\n}\n\n/**\n * Walk the string tracking whether we are inside a JSON string literal and\n * replace raw control characters (U+0000\u2013U+001F) that appear inside strings\n * with their valid JSON escape sequences. Characters outside strings are left\n * untouched (insignificant whitespace stays as-is). Already-escaped sequences\n * are not double-escaped because we only act on *literal* control bytes.\n */\nfunction escapeControlCharsInStrings(s: string): string {\n let inString = false;\n let out = '';\n for (let i = 0; i < s.length; i++) {\n const c = s.charAt(i);\n if (c === '\"' && (i === 0 || s[i - 1] !== '\\\\')) {\n inString = !inString;\n out += c;\n continue;\n }\n const code = c.charCodeAt(0);\n if (inString && code < 0x20) {\n switch (c) {\n case '\\n':\n out += '\\\\n';\n break;\n case '\\r':\n out += '\\\\r';\n break;\n case '\\t':\n out += '\\\\t';\n break;\n case '\\b':\n out += '\\\\b';\n break;\n case '\\f':\n out += '\\\\f';\n break;\n default:\n out += `\\\\u${code.toString(16).padStart(4, '0')}`;\n }\n continue;\n }\n out += c;\n }\n return out;\n}\n\nfunction stripJsonComments(s: string): string {\n let inString = false;\n let escaped = false;\n const chars: string[] = [];\n let i = 0;\n\n while (i < s.length) {\n const c = s.charAt(i);\n\n if (inString) {\n chars.push(c);\n if (escaped) {\n escaped = false;\n } else if (c === '\\\\') {\n escaped = true;\n } else if (c === '\"') {\n inString = false;\n }\n i++;\n continue;\n }\n\n if (c === '\"') {\n inString = true;\n chars.push(c);\n i++;\n continue;\n }\n\n if (c === '/' && s.charAt(i + 1) === '/') {\n while (i < s.length && s.charAt(i) !== '\\n') i++;\n continue;\n }\n\n if (c === '/' && s.charAt(i + 1) === '*') {\n const end = s.indexOf('*/', i + 2);\n if (end === -1) {\n // Preserve an unterminated opener so the final JSON.parse rejects it.\n chars.push(s.slice(i));\n break;\n }\n i = end + 2;\n continue;\n }\n\n chars.push(c);\n i++;\n }\n\n return chars.join('');\n}\n", "import * as path from 'node:path';\nimport { ERROR_CODES, FsError } from '../types/errors.js';\n\n/**\n * Resolve `<dir>/<sessionId><suffix>` for per-session sidecar files\n * (annotations, audit chain, replay log, the session JSONL itself).\n *\n * Modern session ids are date-sharded (\"2026-06-11/sess_<ULID>\"),\n * so a forward slash is a legitimate shard separator \u2014 NOT traversal.\n * Escape attempts are blocked two ways: an explicit ban on `..` and\n * backslashes, plus a resolved-path containment check that rejects any\n * id whose resolved target leaves `dir`. Character bans alone are how\n * several stores ended up throwing on every modern session id.\n */\nexport function sessionScopedPath(dir: string, sessionId: string, suffix: string): string {\n if (!sessionId || sessionId.includes('\\\\') || sessionId.includes('..')) {\n throw invalid(sessionId);\n }\n const resolved = path.resolve(dir, `${sessionId}${suffix}`);\n const rel = path.relative(path.resolve(dir), resolved);\n if (rel.startsWith('..') || path.isAbsolute(rel)) {\n throw invalid(sessionId);\n }\n return resolved;\n}\n\nfunction invalid(sessionId: string): FsError {\n return new FsError({\n message: `Invalid sessionId: ${sessionId}`,\n code: ERROR_CODES.FS_DELETE_FAILED,\n path: sessionId,\n context: { reason: 'path_traversal' },\n });\n}\n", "/**\n * Re-export of the Unix socket path-length helpers from\n * `@wrongstack/persistence` so packages that depend on core (tools, sage)\n * share one implementation with packages that depend on persistence directly\n * (kanban). See `packages/persistence/src/socket-path.ts` for rationale.\n */\nexport {\n assertUnixSocketPathWithinLimit,\n checkUnixSocketPath,\n type UnixSocketPathCheck,\n unixSocketPathLimit,\n} from '@wrongstack/persistence';\n", "const SQLITE_EXPERIMENTAL_WARNING_RE = /sqlite is an experimental feature/i;\n\nfunction isSqliteExperimentalWarning(warning: unknown, rest: readonly unknown[]): boolean {\n const message = typeof warning === 'string' ? warning : warning instanceof Error ? warning.message : '';\n const typeOrOptions = rest[0];\n const warningType =\n typeof warning === 'string'\n ? typeof typeOrOptions === 'string'\n ? typeOrOptions\n : typeof typeOrOptions === 'object' &&\n typeOrOptions !== null &&\n 'type' in typeOrOptions &&\n typeof typeOrOptions.type === 'string'\n ? typeOrOptions.type\n : ''\n : warning instanceof Error\n ? warning.name\n : '';\n const warningCode =\n typeof warning === 'string'\n ? typeof typeOrOptions === 'object' &&\n typeOrOptions !== null &&\n 'code' in typeOrOptions &&\n typeof typeOrOptions.code === 'string'\n ? typeOrOptions.code\n : typeof rest[1] === 'string'\n ? rest[1]\n : ''\n : warning instanceof Error && 'code' in warning && typeof warning.code === 'string'\n ? warning.code\n : '';\n\n return (\n SQLITE_EXPERIMENTAL_WARNING_RE.test(message) &&\n (warningType === 'ExperimentalWarning' || warningCode === 'ExperimentalWarning')\n );\n}\n\n/**\n * Run a synchronous `node:sqlite` load while filtering only Node's built-in\n * SQLite ExperimentalWarning. All other warnings still go through the original\n * process warning path, and the patch is removed before returning.\n */\nexport function withSqliteExperimentalWarningSuppressed<T>(run: () => T): T {\n const originalEmitWarning = process.emitWarning;\n const forwardWarning = originalEmitWarning.bind(process) as (\n warning: unknown,\n ...rest: unknown[]\n ) => void;\n\n process.emitWarning = ((warning: unknown, ...rest: unknown[]): void => {\n if (isSqliteExperimentalWarning(warning, rest)) return;\n forwardWarning(warning, ...rest);\n }) as typeof process.emitWarning;\n\n try {\n return run();\n } finally {\n process.emitWarning = originalEmitWarning;\n }\n}\n", "/** Resolve a promise after `ms` milliseconds. Prefer this over raw\n * `setTimeout` wrappers so all delay sites use a single implementation\n * and an abortable variant can be introduced without a codebase-wide hunt. */\nexport function sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n", "/**\n * Turn an arbitrary string into a filesystem- and URL-safe lowercase slug.\n *\n * Collapses every run of non-alphanumeric characters into a single hyphen,\n * trims leading/trailing hyphens, and caps the length. Returns `fallback`\n * when the input slugifies to the empty string.\n *\n * Used as the stable dedup + registry key for prompts. (Distinct from the\n * project-folder slug in `wstack-paths.ts`, which has its own `'project'`\n * fallback and shorter cap.)\n */\nexport function slugify(name: string, fallback = 'prompt', maxLen = 64): string {\n return (\n name\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '')\n .slice(0, maxLen)\n .replace(/-+$/g, '') || fallback\n );\n}\n", "/**\n * String utilities shared across the WrongStack codebase.\n */\n\n/**\n * Truncate a string to at most `max` characters, appending an ellipsis if it\n * was longer. Returns the original string unchanged when it fits.\n */\nexport function truncate(s: string, max: number): string {\n return s.length <= max ? s : `${s.slice(0, max - 1)}\u2026`;\n}\n", "import type {\n TaskPriority,\n TaskStatus,\n TaskType,\n TaskProgress as TaskGraphProgress,\n} from '../types/task-graph.js';\nimport { color } from './color.js';\n\n// Re-export graph types for convenience\nexport type { TaskStatus, TaskPriority, TaskType };\n\n// ---------------------------------------------------------------------------\n// Session-level task item \u2014 mirrors TaskNode but with string timestamps\n// for JSON serialization and a flat-list structure (no graph edges).\n// ---------------------------------------------------------------------------\n\nexport interface TaskItem {\n id: string;\n title: string;\n description?: string | undefined;\n type: TaskType;\n priority: TaskPriority;\n status: TaskStatus;\n /** IDs of tasks this one depends on. */\n dependsOn?: string[] | undefined;\n /** Agent/subagent name assigned to this task. */\n assignee?: string | undefined;\n estimateHours?: number | undefined;\n tags?: string[] | undefined;\n createdAt: string;\n updatedAt: string;\n}\n\n// ---------------------------------------------------------------------------\n// Progress (re-export computeTaskItemProgress adapted for TaskItem[])\n// ---------------------------------------------------------------------------\n\nexport function computeTaskItemProgress(tasks: TaskItem[]): TaskGraphProgress {\n let completed = 0;\n let pending = 0;\n let inProgress = 0;\n let blocked = 0;\n let failed = 0;\n let review = 0;\n let estimatedHours = 0;\n const actualHours = 0;\n for (const t of tasks) {\n switch (t.status) {\n case 'completed':\n completed++;\n break;\n case 'pending':\n pending++;\n break;\n case 'in_progress':\n inProgress++;\n break;\n case 'blocked':\n blocked++;\n break;\n case 'failed':\n failed++;\n break;\n case 'review':\n review++;\n break;\n }\n estimatedHours += t.estimateHours ?? 0;\n }\n return {\n total: tasks.length,\n pending,\n inProgress,\n blocked,\n failed,\n review,\n completed,\n percentComplete: tasks.length > 0 ? Math.round((completed / tasks.length) * 100) : 0,\n estimatedHours,\n actualHours,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Icons\n// ---------------------------------------------------------------------------\n\nconst STATUS_ICON: Record<TaskStatus, string> = {\n pending: '\u25CB',\n in_progress: '\u25D0',\n blocked: '\u2298',\n failed: '\u2717',\n review: '\u25D1',\n completed: '\u25CF',\n};\n\nconst PRIORITY_ICON: Record<TaskPriority, string> = {\n critical: '\uD83D\uDD34',\n high: '\uD83D\uDFE0',\n medium: '\uD83D\uDFE1',\n low: '\uD83D\uDFE2',\n};\n\nconst TYPE_ICON: Record<TaskType, string> = {\n feature: '\u26A1',\n bugfix: '\uD83D\uDC1B',\n refactor: '\u267B\uFE0F',\n docs: '\uD83D\uDCDD',\n test: '\uD83E\uDDEA',\n chore: '\uD83D\uDD27',\n};\n\n// ---------------------------------------------------------------------------\n// Formatting\n// ---------------------------------------------------------------------------\n\nexport function formatTaskProgress(tasks: TaskItem[]): string {\n const p = computeTaskItemProgress(tasks);\n if (p.total === 0) return 'No tasks.';\n const barWidth = 24;\n const filled = Math.round((p.percentComplete / 100) * barWidth);\n const empty = barWidth - filled;\n const bar = '\u2588'.repeat(filled) + '\u2591'.repeat(empty);\n return [\n `${color.bold('Tasks')} [${bar}] ${p.percentComplete}%`,\n ` ${color.green('\u25CF')} ${p.completed} done \u2502 ${color.yellow('\u25D0')} ${p.inProgress} active \u2502 ${color.dim('\u25CB')} ${p.pending} pending \u2502 \u2298 ${p.blocked} blocked \u2502 \u2717 ${p.failed} failed`,\n p.estimatedHours > 0\n ? ` ${color.dim(`est. ${p.estimatedHours}h`)}`\n : '',\n ]\n .filter(Boolean)\n .join('\\n');\n}\n\nexport function formatTaskList(tasks: TaskItem[]): string {\n if (tasks.length === 0) return 'No tasks.';\n\n // Group by status\n const order: TaskStatus[] = ['in_progress', 'blocked', 'review', 'pending', 'failed', 'completed'];\n const groups = new Map<TaskStatus, TaskItem[]>();\n for (const t of tasks) {\n const list = groups.get(t.status) ?? [];\n list.push(t);\n groups.set(t.status, list);\n }\n\n const lines: string[] = [];\n lines.push(color.dim(`Tasks (${tasks.length} total):`));\n\n for (const status of order) {\n const group = groups.get(status);\n if (!group || group.length === 0) continue;\n const icon = STATUS_ICON[status];\n lines.push(` ${icon} ${status.toUpperCase()} (${group.length})`);\n for (const t of group) {\n const prio = PRIORITY_ICON[t.priority];\n const type = TYPE_ICON[t.type];\n const deps =\n t.dependsOn && t.dependsOn.length > 0\n ? ` ${color.dim('\u2190')} ${color.dim(t.dependsOn.map((d) => d.slice(0, 8)).join(', '))}`\n : '';\n const who = t.assignee ? ` ${color.dim(`@${t.assignee}`)}` : '';\n const hrs = t.estimateHours ? ` ${color.dim(`${t.estimateHours}h`)}` : '';\n lines.push(` ${type} ${prio} ${t.title}${deps}${who}${hrs}`);\n }\n }\n\n return lines.join('\\n');\n}\n", "import type { TodoItem } from '../core/context.js';\nimport { color } from './color.js';\n\n/**\n * Canonical text rendering of the live todo list, shared by the CLI's\n * `/todos` slash command and the TUI's auto-echo (which prints the same\n * snapshot to chat history each time the `todo` tool mutates the list).\n *\n * Layout: a header line with the `done/total done` count, then one row\n * per item \u2014 `[ ]` pending, `[~]` in-progress, `[x]` completed. In-\n * progress rows prefer `activeForm` (\"Building the project\") over the\n * imperative `content` (\"Build the project\") when present.\n *\n * Returned as a single newline-joined string so callers can hand it\n * straight to a history dispatcher or stdout.\n */\nexport function formatTodosList(todos: TodoItem[]): string {\n if (todos.length === 0) return 'No todos.';\n const lines: string[] = [];\n const done = todos.filter((t) => t.status === 'completed').length;\n lines.push(color.dim(`Todos (${done}/${todos.length} done):`));\n todos.forEach((t, i) => {\n const mark =\n t.status === 'completed'\n ? color.green('[x]')\n : t.status === 'in_progress'\n ? color.yellow('[~]')\n : color.dim('[ ]');\n const text = t.status === 'in_progress' && t.activeForm ? t.activeForm : t.content;\n const label = t.status === 'completed' ? color.dim(text) : text;\n lines.push(` ${color.dim(String(i + 1).padStart(2))}. ${mark} ${label}`);\n });\n return lines.join('\\n');\n}\n\n/**\n * True when the todos list still has at least one unfinished item \u2014 either\n * `pending` (not started) or `in_progress` (underway). The REPL and other\n * post-turn handlers call this to decide whether to surface `<nextsteps>`\n * suggestions to the user: as long as the agent has open todos, finishing\n * them takes priority over offering new prompt options. Surfacing\n * `<nextsteps>` mid-task is what causes YOLO+auto mode and the autonomy\n * 'auto' loop to prematurely pivot away from the in-flight todo list.\n *\n * Returns false for an empty / undefined list (nothing pending, nothing to\n * block on) and false for an all-completed list. Treats any non-array input\n * (legacy contexts, mocks) as \"no todos\" rather than throwing.\n */\nexport function hasOpenTodos(todos: readonly TodoItem[] | undefined | null): boolean {\n if (!Array.isArray(todos) || todos.length === 0) return false;\n return todos.some((t) => t.status === 'pending' || t.status === 'in_progress');\n}\n", "import type { ToolDescriptionMode, ToolDescriptionModeConfig } from '../types/config.js';\nimport type { Tool } from '../types/tool.js';\n\nexport const DEFAULT_TOOL_DESCRIPTION_MODE: ToolDescriptionMode = 'extend';\n\nconst ORIGINAL_TOOL_DESCRIPTION = Symbol.for('wrongstack.tool.originalDescription');\n\ninterface OriginalToolDescription {\n description: string;\n usageHint?: string | undefined;\n}\n\ntype ToolWithOriginalDescription = Tool & {\n [ORIGINAL_TOOL_DESCRIPTION]?: OriginalToolDescription | undefined;\n};\n\nexport interface ToolDescriptionRegistryLike {\n get(name: string): Tool | undefined;\n list(): Tool[];\n wrap?(name: string, wrapper: (tool: Tool) => Tool, owner?: string): void;\n setDescriptionMode?(name: string, mode: ToolDescriptionMode): boolean;\n applyDescriptionModes?(\n modes?: ToolDescriptionModeConfig,\n ): { applied: number; missing: string[] };\n getDescriptionMode?(name: string): ToolDescriptionMode;\n}\n\nexport function normalizeToolDescriptionMode(value: unknown): ToolDescriptionMode | undefined {\n if (typeof value !== 'string') return undefined;\n const raw = value.trim().toLowerCase();\n if (raw === 'extend' || raw === 'extended' || raw === 'full') return 'extend';\n if (raw === 'simple' || raw === 'short' || raw === 'brief') return 'simple';\n return undefined;\n}\n\nexport function resolveToolDescriptionMode(\n modes: ToolDescriptionModeConfig | undefined,\n toolName: string,\n): ToolDescriptionMode {\n return normalizeToolDescriptionMode(modes?.[toolName]) ?? DEFAULT_TOOL_DESCRIPTION_MODE;\n}\n\nexport function simplifyToolDescription(\n text: string,\n opts: { maxSentences?: number | undefined; maxChars?: number | undefined } = {},\n): string {\n const maxSentences = Math.max(1, opts.maxSentences ?? 2);\n const maxChars = Math.max(40, opts.maxChars ?? 180);\n const normalized = text\n .replace(/\\r\\n?/g, '\\n')\n .split('\\n')\n .map((line) => line.trim())\n .filter(Boolean)\n .join(' ')\n .replace(/\\s+/g, ' ')\n .trim();\n\n if (normalized.length <= maxChars) return normalized;\n\n const sentences = normalized.match(/[^.!?]+[.!?]+(?=\\s|$)|[^.!?]+$/g) ?? [normalized];\n const selected: string[] = [];\n for (const sentence of sentences) {\n selected.push(sentence.trim());\n const candidate = selected.join(' ');\n if (selected.length >= maxSentences || candidate.length >= maxChars) break;\n }\n\n /* v8 ignore next -- defensive: selected always has \u22651 non-empty sentence so summary is never falsy */\n const summary = selected.join(' ').trim() || normalized;\n if (summary.length <= maxChars) return summary;\n\n const hardLimit = maxChars - 4;\n const boundary = findWordBoundary(summary, hardLimit);\n /* v8 ignore next -- findWordBoundary always returns >0 (semantic/space/limit floor), so the hardLimit fallback is dead */\n return `${summary.slice(0, boundary > 0 ? boundary : hardLimit).trimEnd()} ...`;\n}\n\nexport function applyToolDescriptionModeToTool(\n tool: Tool,\n mode: ToolDescriptionMode,\n): Tool {\n const existingOriginal = getOriginalDescription(tool);\n if (mode === 'extend' && !existingOriginal) return tool;\n\n const original = existingOriginal ?? {\n description: tool.description,\n usageHint: tool.usageHint,\n };\n\n const next =\n mode === 'simple'\n ? withDescription(tool, {\n description: simplifyToolDescription(original.description),\n usageHint:\n original.usageHint === undefined\n ? undefined\n : simplifyToolDescription(original.usageHint),\n })\n : withDescription(tool, original);\n\n return attachOriginalDescription(next, original);\n}\n\nexport function setToolDescriptionMode(\n registry: ToolDescriptionRegistryLike,\n name: string,\n mode: ToolDescriptionMode,\n): boolean {\n if (typeof registry.setDescriptionMode === 'function') {\n return registry.setDescriptionMode(name, mode);\n }\n if (!registry.get(name) || typeof registry.wrap !== 'function') return false;\n registry.wrap(\n name,\n (tool) => applyToolDescriptionModeToTool(tool, mode),\n 'tool-description-mode',\n );\n return true;\n}\n\nexport function getToolDescriptionMode(\n registry: ToolDescriptionRegistryLike,\n name: string,\n): ToolDescriptionMode {\n return registry.getDescriptionMode?.(name) ?? DEFAULT_TOOL_DESCRIPTION_MODE;\n}\n\nexport function applyToolDescriptionModes(\n registry: ToolDescriptionRegistryLike,\n modes?: ToolDescriptionModeConfig,\n): { applied: number; missing: string[] } {\n if (typeof registry.applyDescriptionModes === 'function') {\n return registry.applyDescriptionModes(modes);\n }\n\n const entries = Object.entries(modes ?? {});\n const missing: string[] = [];\n let applied = 0;\n for (const [name, rawMode] of entries) {\n const mode = normalizeToolDescriptionMode(rawMode);\n if (!mode) continue;\n if (setToolDescriptionMode(registry, name, mode)) applied++;\n else missing.push(name);\n }\n return { applied, missing };\n}\n\nfunction getOriginalDescription(tool: Tool): OriginalToolDescription | undefined {\n return (tool as ToolWithOriginalDescription)[ORIGINAL_TOOL_DESCRIPTION];\n}\n\nfunction attachOriginalDescription(tool: Tool, original: OriginalToolDescription): Tool {\n Object.defineProperty(tool, ORIGINAL_TOOL_DESCRIPTION, {\n configurable: true,\n enumerable: false,\n value: original,\n writable: true,\n });\n return tool;\n}\n\nfunction withDescription(tool: Tool, next: OriginalToolDescription): Tool {\n const copy: Tool = {\n ...tool,\n description: next.description,\n usageHint: next.usageHint,\n };\n if (next.usageHint === undefined) {\n delete (copy as { usageHint?: string | undefined }).usageHint;\n }\n return copy;\n}\n\nfunction findWordBoundary(text: string, limit: number): number {\n const semantic = Math.max(\n text.lastIndexOf('. ', limit),\n text.lastIndexOf('; ', limit),\n text.lastIndexOf(', ', limit),\n );\n if (semantic > 40) return semantic + 1;\n const space = text.lastIndexOf(' ', limit);\n return space > 40 ? space : limit;\n}\n", "/**\n * Tool output serialization utilities.\n * Extracted from Agent.executeTools to allow reuse and consistent output handling.\n */\n\nexport interface ToolOutputSerializerOptions {\n perIterationOutputCapBytes?: number | undefined;\n estimator?: ((text: string) => number) | undefined;\n}\n\nexport interface ToolOutputSerializeContext {\n toolName?: string | undefined;\n input?: unknown;\n /**\n * Optional reference to the Tool object. When present and the tool defines\n * a `serialize()` method, the serializer delegates to it instead of the\n * central `renderToolObject()` switch (P3 #21).\n */\n tool?: { serialize?: (output: unknown, input: unknown) => string } | undefined;\n}\n\ntype RecordValue = Record<string, unknown>;\n\nconst DEFAULT_LIST_LIMIT = 500;\nconst LOG_ENTRY_LIMIT = 200;\nconst INLINE_LIMIT = 240;\nconst GREP_FILE_LIMIT = 80;\nconst GREP_MATCHES_PER_FILE = 3;\nconst DIFF_INLINE_LINE_LIMIT = 260;\nconst DIFF_HUNK_LIMIT = 8;\nconst DIFF_HUNK_CONTEXT = 14;\n\n// Pre-compiled regex \u2014 used in parseGrepContentLine() for every grep match line.\n// Compiling once at module load avoids repeated RegExp construction overhead.\nconst GREP_LINE_RE = /^(.+?):(\\d+):(.*)$/;\n\nexport function createToolOutputSerializer(opts: ToolOutputSerializerOptions = {}) {\n const capBytes = opts.perIterationOutputCapBytes ?? 100_000;\n\n function serialize(value: unknown, context: ToolOutputSerializeContext = {}): string {\n if (typeof value === 'string') return value;\n if (value === null || value === undefined) return '';\n if (typeof value === 'object') {\n if (Array.isArray(value)) return value.map((item) => serialize(item)).join('\\n');\n // P3 #21 (before-release.md): prefer the tool's own serialize() method\n // when it defines one \u2014 lets tools own their output formatting without\n // adding a branch to the central renderToolObject() god function.\n if (context.tool?.serialize) {\n try {\n return context.tool.serialize(value, context.input);\n } catch {\n // Fall through to the central renderer if the tool's serializer\n // throws \u2014 never let a formatting error break the tool result.\n }\n }\n if (context.toolName) {\n const compact = renderToolObject(context.toolName, value as RecordValue, context.input);\n if (compact !== undefined) return compact;\n return renderGenericToolObject(context.toolName, value as RecordValue);\n }\n if ('text' in (value as Record<string, unknown>)) {\n const t = (value as Record<string, unknown>).text;\n return typeof t === 'string' ? t : JSON.stringify(value, null, 2);\n }\n try {\n return JSON.stringify(value, null, 2);\n } catch {\n return String(value);\n }\n }\n return String(value);\n }\n\n function enforceCap(text: string, remainingBudget: number): { text: string; newBudget: number } {\n if (remainingBudget <= 0) {\n return { text: '[truncated: iteration output cap exceeded]', newBudget: 0 };\n }\n const textBytes = Buffer.byteLength(text, 'utf8');\n if (textBytes <= remainingBudget) {\n return { text, newBudget: remainingBudget - textBytes };\n }\n const marker = `\\n\u2026[truncated ${textBytes - remainingBudget} bytes]\u2026\\n`;\n const markerBytes = Buffer.byteLength(marker, 'utf8');\n const available = remainingBudget - markerBytes;\n if (available <= 0) {\n return { text: '[truncated: iteration output cap exceeded]', newBudget: 0 };\n }\n const half = Math.floor(available / 2);\n const first = text.slice(0, half);\n const second = text.slice(text.length - half);\n return { text: `${first}${marker}${second}`, newBudget: 0 };\n }\n\n return { serialize, enforceCap, capBytes };\n}\n\nfunction renderToolObject(toolName: string, obj: RecordValue, input: unknown): string | undefined {\n if (toolName === 'read' && typeof obj['text'] === 'string') {\n return joinSections([\n renderHeader(\n `read: ${stringFromInput(input, 'path') ?? stringField(obj, 'path') ?? '<unknown>'}`,\n {\n offset: numberFromInput(input, 'offset'),\n limit: numberFromInput(input, 'limit'),\n total_lines: obj['total_lines'],\n encoding: obj['encoding'],\n truncated: obj['truncated'],\n cached: obj['cached'],\n note: obj['note'],\n },\n ),\n obj['text'],\n ]);\n }\n\n if (toolName === 'grep' && Array.isArray(obj['matches'])) {\n const matches = stringArrayField(obj, 'matches');\n return joinSections([\n renderHeader(`grep: ${stringFromInput(input, 'pattern') ?? '<pattern>'}`, {\n path: stringFromInput(input, 'path'),\n glob: stringFromInput(input, 'glob'),\n mode: stringFromInput(input, 'output_mode'),\n count: obj['count'],\n shown: matches.length,\n truncated: obj['truncated'],\n used: obj['used'],\n }),\n renderGrepMatches(matches, stringFromInput(input, 'output_mode')),\n ]);\n }\n\n if (toolName === 'patch' && Array.isArray(obj['files'])) {\n const files = stringArrayField(obj, 'files');\n return joinSections([\n renderHeader('patch', {\n applied: obj['applied'],\n rejected: obj['rejected'],\n files: files.length,\n dry_run: obj['dry_run'],\n }),\n typeof obj['message'] === 'string' ? `message:\\n${obj['message']}` : undefined,\n files.length > 0 ? `files:\\n${renderStringList(files)}` : undefined,\n ]);\n }\n\n if (toolName === 'glob' && Array.isArray(obj['files'])) {\n const files = stringArrayField(obj, 'files');\n return joinSections([\n renderHeader(\n `${toolName}: ${stringFromInput(input, 'pattern') ?? stringFromInput(input, 'files') ?? stringFromInput(input, 'path') ?? ''}`.trim(),\n {\n path: stringFromInput(input, 'path'),\n files: files.length,\n truncated: obj['truncated'],\n },\n ),\n renderStringList(files, '(no files)'),\n ]);\n }\n\n if (toolName === 'tree' && typeof obj['tree'] === 'string') {\n return joinSections([\n renderHeader(\n `tree: ${stringField(obj, 'path') ?? stringFromInput(input, 'path') ?? '<cwd>'}`,\n {\n total_files: obj['total_files'],\n total_dirs: obj['total_dirs'],\n truncated: obj['truncated'],\n },\n ),\n obj['tree'],\n ]);\n }\n\n if (toolName === 'fetch' && typeof obj['content'] === 'string') {\n return joinSections([\n renderHeader(\n `fetch: ${stringField(obj, 'url') ?? stringFromInput(input, 'url') ?? '<url>'}`,\n {\n status: obj['status'],\n content_type: obj['content_type'],\n },\n ),\n obj['content'],\n ]);\n }\n\n if (toolName === 'replace' && Array.isArray(obj['results'])) {\n const results = obj['results'].filter(isRecord);\n const sections: Array<string | undefined> = [\n renderHeader('replace', {\n files_modified: obj['files_modified'],\n total_replacements: obj['total_replacements'],\n dry_run: obj['dry_run'],\n }),\n ];\n for (const r of results.slice(0, DEFAULT_LIST_LIMIT)) {\n sections.push(\n joinSections([\n renderHeader(`file: ${stringField(r, 'path') ?? '<unknown>'}`, {\n replacements: r['replacements'],\n }),\n typeof r['diff'] === 'string' ? r['diff'] : undefined,\n ]),\n );\n }\n if (results.length > DEFAULT_LIST_LIMIT) {\n sections.push(`[serializer omitted ${results.length - DEFAULT_LIST_LIMIT} result item(s)]`);\n }\n return joinSections(sections);\n }\n\n if (typeof obj['diff'] === 'string') {\n const diff = obj['diff'];\n // matched_by: 'exact' is the default and carries no information \u2014 only\n // surface the field when a fallback tier actually fired.\n const matchedBy =\n typeof obj['matched_by'] === 'string' && obj['matched_by'] !== 'exact'\n ? obj['matched_by']\n : undefined;\n const syntaxErrors = Array.isArray(obj['syntax_errors'])\n ? obj['syntax_errors'].filter((e): e is string => typeof e === 'string')\n : [];\n return joinSections([\n renderHeader(toolName, {\n path: obj['path'],\n replacements: obj['replacements'],\n bytes_written: obj['bytes_written'],\n created: obj['created'],\n matched_by: matchedBy,\n note: obj['note'],\n files: Array.isArray(obj['files']) ? obj['files'].length : undefined,\n truncated: obj['truncated'],\n mode: obj['mode'],\n }),\n compactDiff(diff),\n syntaxErrors.length > 0 ? `syntax_errors:\\n${renderStringList(syntaxErrors)}` : undefined,\n ]);\n }\n\n if (toolName === 'test' && typeof obj['output'] === 'string') {\n return renderTestOutput(obj, input);\n }\n\n if (\n (toolName === 'typecheck' || toolName === 'lint' || toolName === 'format') &&\n typeof obj['output'] === 'string'\n ) {\n return renderVerifierOutput(toolName, obj, input);\n }\n\n if (hasCommandOutputShape(obj)) {\n return renderCommandOutput(toolName, obj, input);\n }\n\n if (toolName === 'json' && typeof obj['formatted'] === 'string') {\n return joinSections([\n renderHeader('json', {\n type: obj['type'],\n keys: Array.isArray(obj['keys']) ? obj['keys'].length : undefined,\n query: stringFromInput(input, 'query'),\n error: obj['error'],\n }),\n obj['formatted'],\n ]);\n }\n\n if (toolName === 'logs' && Array.isArray(obj['entries'])) {\n const entries = obj['entries'].filter(isRecord);\n const lines = entries.slice(0, LOG_ENTRY_LIMIT).map((entry) => {\n const ts = stringField(entry, 'timestamp') ?? '';\n const level = stringField(entry, 'level') ?? 'info';\n const message = stringField(entry, 'message') ?? '';\n const source = stringField(entry, 'source');\n return [ts, level, source, message].filter(Boolean).join(' ');\n });\n if (entries.length > LOG_ENTRY_LIMIT) {\n lines.push(`[serializer omitted ${entries.length - LOG_ENTRY_LIMIT} log entry item(s)]`);\n }\n return joinSections([\n renderHeader(`logs: ${stringField(obj, 'source') ?? '<source>'}`, {\n total: obj['total'],\n shown: Math.min(entries.length, LOG_ENTRY_LIMIT),\n truncated: obj['truncated'],\n stream_mode: obj['stream_mode'],\n }),\n lines.length > 0 ? lines.join('\\n') : '(no log entries)',\n ]);\n }\n\n if (toolName === 'audit' && Array.isArray(obj['vulnerabilities'])) {\n const vulns = obj['vulnerabilities'].filter(isRecord);\n const lines = vulns.slice(0, DEFAULT_LIST_LIMIT).map((v) => {\n const severity = stringField(v, 'severity') ?? 'unknown';\n const pkg = stringField(v, 'package') ?? '<package>';\n const title = stringField(v, 'title') ?? '';\n const url = stringField(v, 'url');\n return [severity, pkg, title, url].filter(Boolean).join(' | ');\n });\n if (vulns.length > DEFAULT_LIST_LIMIT) {\n lines.push(`[serializer omitted ${vulns.length - DEFAULT_LIST_LIMIT} vulnerability item(s)]`);\n }\n return joinSections([\n renderHeader('audit', {\n exit_code: obj['exit_code'],\n total: obj['total'],\n summary: obj['summary'],\n truncated: obj['truncated'],\n }),\n lines.length > 0 ? lines.join('\\n') : stringField(obj, 'output'),\n ]);\n }\n\n if (toolName === 'outdated' && Array.isArray(obj['packages'])) {\n const packages = obj['packages'].filter(isRecord);\n const lines = packages\n .slice(0, DEFAULT_LIST_LIMIT)\n .map((p) =>\n [\n stringField(p, 'name') ?? '<package>',\n `current=${stringField(p, 'current') ?? 'unknown'}`,\n `wanted=${stringField(p, 'wanted') ?? 'unknown'}`,\n `latest=${stringField(p, 'latest') ?? 'unknown'}`,\n stringField(p, 'type'),\n ]\n .filter(Boolean)\n .join(' | '),\n );\n if (packages.length > DEFAULT_LIST_LIMIT) {\n lines.push(`[serializer omitted ${packages.length - DEFAULT_LIST_LIMIT} package item(s)]`);\n }\n return joinSections([\n renderHeader('outdated', {\n exit_code: obj['exit_code'],\n total: obj['total'],\n truncated: obj['truncated'],\n }),\n lines.length > 0 ? lines.join('\\n') : stringField(obj, 'output'),\n ]);\n }\n\n return undefined;\n}\n\nfunction renderTestOutput(obj: RecordValue, input: unknown): string {\n const exitCode = numberField(obj, 'exit_code') ?? 0;\n const failed = numberField(obj, 'failed') ?? 0;\n const output = stringField(obj, 'output') ?? '';\n const header = renderHeader(`test: ${stringField(obj, 'runner') ?? 'runner'}`, {\n exit_code: obj['exit_code'],\n tests_run: obj['tests_run'],\n passed: obj['passed'],\n failed: obj['failed'],\n duration_ms: obj['duration_ms'],\n truncated: obj['truncated'],\n files: inputListSummary(input, 'files'),\n grep: stringFromInput(input, 'grep'),\n });\n\n if (exitCode === 0 && failed === 0) {\n return joinSections([\n header,\n joinSections([\n 'report:',\n `status=passed`,\n `tests_run=${obj['tests_run'] ?? 0}`,\n `passed=${obj['passed'] ?? 0}`,\n `failed=${obj['failed'] ?? 0}`,\n `duration_ms=${obj['duration_ms'] ?? 0}`,\n extractSpoolNote(output),\n ]),\n ]);\n }\n\n return joinSections([\n header,\n `error_context:\\n${compactFailureOutput(output || '(no runner output)')}`,\n ]);\n}\n\nfunction renderVerifierOutput(toolName: string, obj: RecordValue, input: unknown): string {\n const exitCode = numberField(obj, 'exit_code') ?? 0;\n const errors = numberField(obj, 'errors') ?? 0;\n const warnings = numberField(obj, 'warnings') ?? 0;\n const output = stringField(obj, 'output') ?? '';\n const changed = numberField(obj, 'files_changed') ?? 0;\n const header = renderHeader(toolName, {\n exit_code: obj['exit_code'],\n errors: obj['errors'],\n warnings: obj['warnings'],\n files_checked: obj['files_checked'],\n files_changed: obj['files_changed'],\n fix_applied: obj['fix_applied'],\n fixer: obj['fixer'],\n linter: obj['linter'],\n project: obj['project'],\n truncated: obj['truncated'],\n files: inputListSummary(input, 'files'),\n cwd: stringFromInput(input, 'cwd'),\n });\n\n if (exitCode === 0 && errors === 0 && (toolName !== 'format' || changed === 0)) {\n return joinSections([\n header,\n joinSections([\n 'report:',\n 'status=passed',\n `errors=${errors}`,\n `warnings=${warnings}`,\n toolName === 'format' ? `files_changed=${changed}` : undefined,\n extractSpoolNote(output),\n ]),\n ]);\n }\n\n if (exitCode === 0 && toolName === 'format') {\n return joinSections([\n header,\n joinSections([\n 'report:',\n 'status=changed',\n `files_changed=${changed}`,\n extractSpoolNote(output),\n ]),\n ]);\n }\n\n return joinSections([\n header,\n `error_context:\\n${compactFailureOutput(output || '(no verifier output)')}`,\n ]);\n}\n\nfunction renderGrepMatches(matches: string[], mode: string | undefined): string {\n if (matches.length === 0) return '(no matches)';\n if (mode === 'files_with_matches') return renderStringList(matches, '(no files)');\n if (mode === 'count') return renderStringList(matches, '(no counts)');\n\n const groups = new Map<string, string[]>();\n const passthrough: string[] = [];\n for (const match of matches) {\n const parsed = parseGrepContentLine(match);\n if (!parsed) {\n passthrough.push(match);\n continue;\n }\n const list = groups.get(parsed.file) ?? [];\n list.push(`${parsed.line}:${parsed.text}`);\n groups.set(parsed.file, list);\n }\n\n if (groups.size === 0) return renderStringList(matches, '(no matches)');\n\n const sections: string[] = [];\n let fileIndex = 0;\n for (const [file, lines] of groups) {\n fileIndex++;\n if (fileIndex > GREP_FILE_LIMIT) break;\n const shown = lines.slice(0, GREP_MATCHES_PER_FILE);\n sections.push(\n `${file} (${lines.length} match(es), showing ${shown.length})\\n${shown.join('\\n')}`,\n );\n }\n if (groups.size > GREP_FILE_LIMIT) {\n sections.push(`[serializer omitted ${groups.size - GREP_FILE_LIMIT} file group(s)]`);\n }\n if (passthrough.length > 0) {\n sections.push(`ungrouped:\\n${renderStringList(passthrough, '', 50)}`);\n }\n return sections.join('\\n');\n}\n\nfunction parseGrepContentLine(\n line: string,\n): { file: string; line: string; text: string } | undefined {\n const match = GREP_LINE_RE.exec(line);\n if (!match?.[1] || !match[2]) return undefined;\n return { file: match[1], line: match[2], text: match[3] ?? '' };\n}\n\nfunction compactDiff(diff: string): string {\n const lines = diff.split(/\\r?\\n/);\n if (lines.length <= DIFF_INLINE_LINE_LIMIT) return diff;\n\n const fileCount = Math.max(\n new Set(\n lines\n .map(\n (line) => /^diff --git\\s+a\\/(.+?)\\s+b\\//.exec(line)?.[1] ?? /^---\\s+(.+)/.exec(line)?.[1],\n )\n .filter(Boolean),\n ).size,\n 0,\n );\n const hunks = lines.filter((line) => line.startsWith('@@')).length;\n const added = lines.filter((line) => line.startsWith('+') && !line.startsWith('+++')).length;\n const removed = lines.filter((line) => line.startsWith('-') && !line.startsWith('---')).length;\n\n // Collect [start, end] intervals as we scan lines sequentially.\n // Intervals are naturally ordered by line index \u2014 no sort needed.\n const intervals: Array<[number, number]> = [];\n let hunkCount = 0;\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i] ?? '';\n if (line.startsWith('diff --git') || line.startsWith('--- ') || line.startsWith('+++ ')) {\n intervals.push([i, i]);\n continue;\n }\n if (!line.startsWith('@@')) continue;\n if (hunkCount >= DIFF_HUNK_LIMIT) continue;\n hunkCount++;\n intervals.push([i, Math.min(lines.length - 1, i + DIFF_HUNK_CONTEXT)]);\n }\n\n if (intervals.length === 0) {\n return joinSections([\n renderHeader('diff_summary', {\n files: fileCount,\n hunks,\n added,\n removed,\n lines: lines.length,\n }),\n lines.slice(0, DIFF_INLINE_LINE_LIMIT).join('\\n'),\n `[serializer omitted ${Math.max(0, lines.length - DIFF_INLINE_LINE_LIMIT)} diff line(s)]`,\n ]);\n }\n\n // Merge overlapping / adjacent intervals in a single O(n) pass.\n // Intervals are already in ascending order from the sequential scan.\n const merged: Array<[number, number]> = [intervals[0]!];\n for (let i = 1; i < intervals.length; i++) {\n const last = merged[merged.length - 1]!;\n const current = intervals[i]!;\n if (current[0] <= last[1] + 1) {\n last[1] = Math.max(last[1], current[1]);\n } else {\n merged.push(current);\n }\n }\n\n // Build excerpt from merged intervals \u2014 O(n), no sort.\n const excerpt: string[] = [];\n let prevLine = -1;\n for (const [start, end] of merged) {\n if (start > prevLine + 1) {\n const omitted = prevLine === -1 ? start : start - prevLine - 1;\n excerpt.push(`[serializer omitted ${omitted} diff line(s)]`);\n }\n for (let j = start; j <= end; j++) {\n excerpt.push(lines[j] ?? '');\n }\n prevLine = end;\n }\n\n const trailing = lines.length - prevLine - 1;\n if (trailing > 0) excerpt.push(`[serializer omitted ${trailing} trailing diff line(s)]`);\n\n return joinSections([\n renderHeader('diff_summary', {\n files: fileCount,\n hunks,\n shown_hunks: Math.min(hunks, DIFF_HUNK_LIMIT),\n added,\n removed,\n lines: lines.length,\n }),\n excerpt.join('\\n'),\n ]);\n}\n\nfunction compactFailureOutput(output: string): string {\n const lines = output.split(/\\r?\\n/);\n if (lines.length <= 260) return output.trimEnd();\n\n const selected = new Set<number>();\n const marker =\n /\\b(fail|failed|failure|error|exception|assertionerror|expected|received|actual|timeout|stack)\\b/i;\n let markerHits = 0;\n for (let i = 0; i < lines.length; i++) {\n if (!marker.test(lines[i] ?? '')) continue;\n markerHits++;\n for (let j = Math.max(0, i - 4); j <= Math.min(lines.length - 1, i + 10); j++) {\n selected.add(j);\n }\n }\n\n if (markerHits === 0) {\n return lines.slice(-220).join('\\n').trimEnd();\n }\n\n const ordered = [...selected].sort((a, b) => a - b);\n const out: string[] = [];\n let previous = -1;\n for (const index of ordered) {\n if (index > previous + 1) {\n const omitted = previous === -1 ? index : index - previous - 1;\n out.push(`[serializer omitted ${omitted} line(s)]`);\n }\n out.push(lines[index] ?? '');\n previous = index;\n }\n return out.join('\\n').trimEnd();\n}\n\nfunction extractSpoolNote(output: string): string | undefined {\n return output\n .split(/\\r?\\n/)\n .find((line) => line.startsWith('[output truncated') && line.includes('full'));\n}\n\nfunction hasCommandOutputShape(obj: RecordValue): boolean {\n return (\n typeof obj['stdout'] === 'string' ||\n typeof obj['stderr'] === 'string' ||\n typeof obj['output'] === 'string' ||\n typeof obj['exitCode'] === 'number' ||\n typeof obj['exit_code'] === 'number'\n );\n}\n\nfunction renderCommandOutput(toolName: string, obj: RecordValue, input: unknown): string {\n const command = stringField(obj, 'command') ?? stringFromInput(input, 'command');\n const args = stringArrayField(obj, 'args');\n const commandLine = command ? [command, ...args].join(' ') : undefined;\n const output = stringField(obj, 'output');\n const stdout = stringField(obj, 'stdout');\n const stderr = stringField(obj, 'stderr');\n return joinSections([\n renderHeader(commandLine ? `${toolName}: ${commandLine}` : toolName, {\n exit_code: obj['exit_code'] ?? obj['exitCode'],\n timed_out: obj['timed_out'],\n pid: obj['pid'],\n allowed: obj['allowed'],\n truncated: obj['truncated'],\n runner: obj['runner'],\n linter: obj['linter'],\n fixer: obj['fixer'],\n project: obj['project'],\n tests_run: obj['tests_run'],\n passed: obj['passed'],\n failed: obj['failed'],\n duration_ms: obj['duration_ms'],\n errors: obj['errors'],\n warnings: obj['warnings'],\n files_checked: obj['files_checked'],\n files_changed: obj['files_changed'],\n fix_applied: obj['fix_applied'],\n }),\n stringField(obj, 'error') ? `error:\\n${stringField(obj, 'error')}` : undefined,\n output ? `output:\\n${output}` : undefined,\n stdout ? `stdout:\\n${stdout}` : undefined,\n stderr ? `stderr:\\n${stderr}` : undefined,\n ]);\n}\n\nfunction renderGenericToolObject(toolName: string, obj: RecordValue): string {\n const scalars: RecordValue = {};\n const blocks: string[] = [];\n for (const [key, value] of Object.entries(obj)) {\n if (value === undefined) continue;\n if (isScalar(value)) {\n const inline = String(value);\n if (inline.length <= INLINE_LIMIT && !inline.includes('\\n')) {\n scalars[key] = value;\n } else {\n blocks.push(`${key}:\\n${inline}`);\n }\n continue;\n }\n if (Array.isArray(value)) {\n if (value.every((item) => typeof item === 'string')) {\n blocks.push(`${key}:\\n${renderStringList(value as string[])}`);\n } else {\n blocks.push(`${key}:\\n${renderUnknownList(value)}`);\n }\n continue;\n }\n blocks.push(`${key}: ${clipInline(oneLineJson(value))}`);\n }\n return joinSections([renderHeader(toolName, scalars), ...blocks]);\n}\n\nfunction renderHeader(label: string, fields: RecordValue): string {\n const parts = Object.entries(fields)\n .filter(([, value]) => value !== undefined && value !== null && value !== '')\n .map(([key, value]) => `${key}=${clipInline(formatInlineValue(value))}`);\n return parts.length > 0 ? `${label} (${parts.join(' ')})` : label;\n}\n\nfunction renderStringList(items: string[], empty = '', limit = DEFAULT_LIST_LIMIT): string {\n if (items.length === 0) return empty;\n const shown = items.slice(0, limit);\n const omitted = items.length - shown.length;\n return [\n ...shown,\n ...(omitted > 0\n ? [`[serializer omitted ${omitted} item(s); narrow the request for more]`]\n : []),\n ].join('\\n');\n}\n\nfunction renderUnknownList(items: unknown[], limit = DEFAULT_LIST_LIMIT): string {\n const shown = items.slice(0, limit).map((item) => clipInline(oneLineJson(item), 1_000));\n const omitted = items.length - shown.length;\n if (omitted > 0)\n shown.push(`[serializer omitted ${omitted} item(s); narrow the request for more]`);\n return shown.join('\\n');\n}\n\nfunction joinSections(sections: Array<string | undefined>): string {\n return sections\n .map((section) => (typeof section === 'string' ? section.trimEnd() : undefined))\n .filter((section): section is string => !!section)\n .join('\\n');\n}\n\nfunction formatInlineValue(value: unknown): string {\n /* v8 ignore next -- no renderHeader field is ever an array (all callers pass scalars) */\n if (Array.isArray(value)) return `[${value.map(formatInlineValue).join(',')}]`;\n if (isScalar(value)) return String(value);\n return oneLineJson(value);\n}\n\nfunction clipInline(value: string, max = INLINE_LIMIT): string {\n const compact = value.replace(/\\s+/g, ' ').trim();\n return compact.length <= max\n ? compact\n : `${compact.slice(0, max - 15)}...(${compact.length} chars)`;\n}\n\nfunction oneLineJson(value: unknown): string {\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n}\n\nfunction stringField(obj: RecordValue, key: string): string | undefined {\n const value = obj[key];\n return typeof value === 'string' ? value : undefined;\n}\n\nfunction numberField(obj: RecordValue, key: string): number | undefined {\n const value = obj[key];\n return typeof value === 'number' ? value : undefined;\n}\n\nfunction stringArrayField(obj: RecordValue, key: string): string[] {\n const value = obj[key];\n return Array.isArray(value)\n ? value.filter((item): item is string => typeof item === 'string')\n : [];\n}\n\nfunction stringFromInput(input: unknown, key: string): string | undefined {\n if (!isRecord(input)) return undefined;\n const value = input[key];\n return typeof value === 'string' ? value : undefined;\n}\n\nfunction numberFromInput(input: unknown, key: string): number | undefined {\n if (!isRecord(input)) return undefined;\n const value = input[key];\n return typeof value === 'number' ? value : undefined;\n}\n\nfunction inputListSummary(input: unknown, key: string): string | undefined {\n if (!isRecord(input)) return undefined;\n const value = input[key];\n if (typeof value === 'string') return value;\n if (Array.isArray(value)) return value.filter((item) => typeof item === 'string').join(',');\n return undefined;\n}\n\nfunction isRecord(value: unknown): value is RecordValue {\n return !!value && typeof value === 'object' && !Array.isArray(value);\n}\n\nfunction isScalar(value: unknown): value is string | number | boolean | null {\n return value === null || ['string', 'number', 'boolean'].includes(typeof value);\n}\n\n/**\n * Render a tool result body for inclusion in the `tool.executed` event.\n * Tool outputs can be large (file dumps, command output); UIs only want a\n * preview line, so cap at ~400 chars with an ellipsis marker.\n */\nexport function truncateForEvent(content: string, max = 400): string {\n if (!content) return '';\n return content.length <= max ? content : `${content.slice(0, max - 1)}\u2026`;\n}\n\n/**\n * Derive size signals (bytes / tokens / lines) for the chip rendered beside\n * each tool result. Computed once over the FULL `content` BEFORE the\n * 400-char event preview is taken.\n *\n * - bytes: UTF-8 byte length (multi-byte aware).\n * - tokens: standard ~3.5 chars/token heuristic.\n * - lines: read prefixes lines with `<n>\u2192`; for shell/grep/logs we fall\n * back to a newline count. Undefined for tools without a line notion.\n */\nconst READ_LINE_PREFIX_RE = /^\\s*\\d+\u2192/gm;\n\nexport function sizeSignals(\n toolName: string | undefined,\n content: string,\n): { outputBytes: number; outputTokens: number; outputLines: number | undefined } {\n if (!content || content.length === 0) {\n return { outputBytes: 0, outputTokens: 0, outputLines: undefined };\n }\n const outputBytes = Buffer.byteLength(content, 'utf8');\n const outputTokens = Math.max(1, Math.round(outputBytes / 3.5));\n let outputLines: number | undefined;\n if (toolName === 'read') {\n READ_LINE_PREFIX_RE.lastIndex = 0;\n let count = 0;\n while (READ_LINE_PREFIX_RE.exec(content) !== null) count++;\n if (count > 0) outputLines = count;\n } else if (\n toolName === 'bash' ||\n toolName === 'shell' ||\n toolName === 'grep' ||\n toolName === 'logs'\n ) {\n let nl = 0;\n for (let i = 0; i < content.length; i++) if (content.charCodeAt(i) === 10) nl++;\n outputLines = nl + (content.endsWith('\\n') ? 0 : 1);\n }\n return { outputBytes, outputTokens, outputLines };\n}\n", "import type {\n ToolResultRenderMode,\n ToolResultRenderModeConfig,\n} from '../types/config.js';\nimport type { Tool } from '../types/tool.js';\n\nexport const DEFAULT_TOOL_RESULT_RENDER_MODE: ToolResultRenderMode = 'extend';\n\n/**\n * Normalize a raw value to a {@link ToolResultRenderMode}. Accepts the\n * canonical strings (`'extend' | 'simple'`) plus a few synonyms so the\n * slash command feels forgiving (`extended`/`full` \u2192 `extend`,\n * `short`/`brief` \u2192 `simple`). Returns `undefined` for anything else so\n * the caller can reject unknown input without throwing.\n */\nexport function normalizeToolResultRenderMode(value: unknown): ToolResultRenderMode | undefined {\n if (typeof value !== 'string') return undefined;\n const raw = value.trim().toLowerCase();\n if (raw === 'extend' || raw === 'extended' || raw === 'full') return 'extend';\n if (raw === 'simple' || raw === 'short' || raw === 'brief') return 'simple';\n return undefined;\n}\n\n/**\n * Look up the result-render mode for `toolName` from a config map. Falls\n * back to the default `'extend'` when the map is missing the entry.\n */\nexport function resolveToolResultRenderMode(\n modes: ToolResultRenderModeConfig | undefined,\n toolName: string,\n): ToolResultRenderMode {\n return normalizeToolResultRenderMode(modes?.[toolName]) ?? DEFAULT_TOOL_RESULT_RENDER_MODE;\n}\n\n/**\n * Subset of {@link import('../registry/tool-registry.js').ToolRegistry}\n * the result-render-mode setters need. Decouples this module from the\n * concrete registry class so it can be reused by tests and by tools\n * that wrap their own registry.\n */\nexport interface ToolResultRenderModeRegistryLike {\n get(name: string): Tool | undefined;\n setResultRenderMode?(name: string, mode: ToolResultRenderMode): boolean;\n applyResultRenderModes?(\n modes?: ToolResultRenderModeConfig,\n ): { applied: number; missing: string[] };\n getResultRenderMode?(name: string): ToolResultRenderMode;\n}\n\n/**\n * Set a single tool's result-render mode on a registry. Prefers the\n * registry's native accessor (so it can update any internal state, e.g.\n * usage caches); falls back to a no-op so callers stay decoupled from\n * the registry implementation.\n */\nexport function setToolResultRenderMode(\n registry: ToolResultRenderModeRegistryLike,\n name: string,\n mode: ToolResultRenderMode,\n): boolean {\n if (typeof registry.setResultRenderMode === 'function') {\n return registry.setResultRenderMode(name, mode);\n }\n return false;\n}\n\n/**\n * Look up the current result-render mode for a single tool. Returns the\n * registry's view if it has one, otherwise the default. This is what the\n * tool-executor calls on each tool invocation to decide whether the next\n * `writeToolResult` should be `simple` or `extend`.\n */\nexport function getToolResultRenderMode(\n registry: ToolResultRenderModeRegistryLike,\n name: string,\n): ToolResultRenderMode {\n return registry.getResultRenderMode?.(name) ?? DEFAULT_TOOL_RESULT_RENDER_MODE;\n}\n\n/**\n * Bulk-apply a config map (`tools.resultRenderMode`) to a registry.\n * Mirrors {@link import('./tool-description-mode.js').applyToolDescriptionModes}\n * for symmetry with the LLM-side description mode.\n */\nexport function applyToolResultRenderModes(\n registry: ToolResultRenderModeRegistryLike,\n modes?: ToolResultRenderModeConfig,\n): { applied: number; missing: string[] } {\n if (typeof registry.applyResultRenderModes === 'function') {\n return registry.applyResultRenderModes(modes);\n }\n\n const entries = Object.entries(modes ?? {});\n const missing: string[] = [];\n let applied = 0;\n for (const [name, rawMode] of entries) {\n const mode = normalizeToolResultRenderMode(rawMode);\n if (!mode) continue;\n if (setToolResultRenderMode(registry, name, mode)) applied++;\n else missing.push(name);\n }\n return { applied, missing };\n}", "const GLOB_METACHARACTERS = /[*?[\\]]/g;\n\nexport function escapeGlobSubject(value: string): string {\n return value.replace(GLOB_METACHARACTERS, (char) => `\\\\${char}`);\n}\n\nexport function normalizePathSubject(value: string): string {\n return escapeGlobSubject(value.replace(/\\\\/g, '/'));\n}\n\nexport function isPathSubjectKey(subjectKey: string): boolean {\n return subjectKey === 'path' || subjectKey === 'file' || subjectKey === 'files';\n}\n\nexport function subjectForToolInput(\n toolName: string,\n input: unknown,\n subjectKey?: string,\n): string | undefined {\n if (!input || typeof input !== 'object') return undefined;\n const obj = input as Record<string, unknown>;\n\n if (subjectKey) {\n const value = obj[subjectKey];\n if (typeof value === 'string') {\n return isPathSubjectKey(subjectKey) ? normalizePathSubject(value) : escapeGlobSubject(value);\n }\n }\n\n if (toolName === 'bash' && typeof obj.command === 'string') {\n return escapeGlobSubject(obj.command);\n }\n if (typeof obj.path === 'string') {\n return normalizePathSubject(obj.path);\n }\n if (typeof obj.url === 'string') {\n return escapeGlobSubject(obj.url);\n }\n if (typeof obj.name === 'string') {\n return escapeGlobSubject(obj.name);\n }\n return undefined;\n}\n", "/**\n * Provider-wire tool name constraints.\n *\n * Anthropic-family endpoints (including gateways that translate to the\n * Anthropic wire, e.g. OmniRoute routing to `cc/...` models) validate every\n * tool name against `^[a-zA-Z0-9_-]{1,128}$` and reject the whole request\n * with a 400 (`tools.N.custom.name: String should match pattern ...`) when\n * one name contains a dot, colon, space, or exceeds 128 chars. MCP server\n * names and remote MCP tool names are user/third-party controlled, so the\n * qualified `mcp__<server>__<tool>` names must be sanitized at registration\n * time \u2014 the registry, permission policy, and provider wire all see the\n * same sanitized name, so no reverse mapping is needed on the response\n * path. The wrapped tool still calls the remote server with the ORIGINAL\n * tool name.\n */\n\nexport const WIRE_TOOL_NAME_MAX_LENGTH = 128;\nexport const WIRE_TOOL_NAME_PATTERN = /^[a-zA-Z0-9_-]{1,128}$/;\n\n/**\n * Coerce an arbitrary string into a provider-safe tool name: every char\n * outside `[a-zA-Z0-9_-]` becomes `_`, and the result is clamped to 128\n * chars (clamped from the end so namespace prefixes like `mcp__server__`\n * survive). Empty input falls back to `'tool'`.\n */\nexport function sanitizeWireToolName(name: string): string {\n const replaced = name.replace(/[^a-zA-Z0-9_-]/g, '_');\n const clamped = replaced.slice(0, WIRE_TOOL_NAME_MAX_LENGTH);\n return clamped.length > 0 ? clamped : 'tool';\n}\n\n/** Sanitized `mcp__<server>__` namespace prefix for a server's tools. */\nexport function mcpServerToolPrefix(serverName: string): string {\n return `mcp__${sanitizeWireToolName(serverName)}__`;\n}\n\n/**\n * Build the qualified registry/wire name for an MCP tool. Both the server\n * segment and the tool segment are sanitized independently (so the `__`\n * separators stay intact for prefix matching), then the whole name is\n * clamped to the 128-char wire limit.\n */\nexport function mcpQualifiedToolName(serverName: string, toolName: string): string {\n return sanitizeWireToolName(\n `${mcpServerToolPrefix(serverName)}${sanitizeWireToolName(toolName)}`,\n );\n}\n", "/**\n * Shared recursive project-tree watcher.\n *\n * Several subsystems each used to open their own `fs.watch(projectRoot,\n * {recursive:true})` \u2014 the codebase indexer, the chronicle file observer, and\n * the WebUI indexing mirror. Every recursive watch makes the OS track the\n * whole tree independently, so a single runtime paid that cost 2\u20133\u00D7. This\n * registry keeps ONE watcher per resolved root per process and fans events\n * out to all subscribers; the watcher closes when the last subscriber leaves.\n *\n * The registry lives behind a `Symbol.for` global so it stays a singleton\n * even if core is loaded twice (Windows path-casing double-load).\n *\n * @module utils/project-watch\n */\n\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\n\nexport interface ProjectWatchEvent {\n eventType: 'rename' | 'change';\n /** Path relative to the watched root as delivered by the OS, or null when omitted. */\n filename: string | null;\n}\n\nexport interface ProjectWatchSubscription {\n close(): void;\n}\n\ninterface Subscriber {\n listener: (event: ProjectWatchEvent) => void;\n onError?: ((error: unknown) => void) | undefined;\n}\n\ninterface WatchEntry {\n watcher: fs.FSWatcher;\n subscribers: Set<Subscriber>;\n /** Set once the underlying watcher errored or closed \u2014 dead entries are never reused. */\n dead: boolean;\n}\n\nconst REGISTRY_KEY = Symbol.for('wrongstack.projectWatchRegistry');\nconst globalScope = globalThis as { [REGISTRY_KEY]?: Map<string, WatchEntry> };\nif (!globalScope[REGISTRY_KEY]) globalScope[REGISTRY_KEY] = new Map();\nconst registry: Map<string, WatchEntry> = globalScope[REGISTRY_KEY];\n\nfunction registryKey(root: string): string {\n const resolved = path.resolve(root);\n return process.platform === 'win32' ? resolved.toLowerCase() : resolved;\n}\n\n/**\n * Subscribe to recursive change events under `root`, sharing one OS watcher\n * per root per process. Throws when the platform cannot create the watcher\n * (no recursive support, permission) and no live shared watcher exists \u2014\n * callers that can degrade should try/catch exactly as they would `fs.watch`.\n *\n * The watcher is non-persistent: it never keeps the process alive.\n */\nexport function watchProjectTree(\n root: string,\n listener: (event: ProjectWatchEvent) => void,\n opts?: { onError?: ((error: unknown) => void) | undefined },\n): ProjectWatchSubscription {\n const key = registryKey(root);\n let entry = registry.get(key);\n if (!entry || entry.dead) {\n const subscribers = new Set<Subscriber>();\n const watcher = fs.watch(\n path.resolve(root),\n { recursive: true, persistent: false },\n (eventType, filename) => {\n const event: ProjectWatchEvent = {\n eventType: eventType === 'rename' ? 'rename' : 'change',\n filename: filename === null ? null : String(filename),\n };\n for (const sub of subscribers) {\n try {\n sub.listener(event);\n } catch (error) {\n sub.onError?.(error);\n }\n }\n },\n );\n const created: WatchEntry = { watcher, subscribers, dead: false };\n const retire = (): void => {\n created.dead = true;\n if (registry.get(key) === created) registry.delete(key);\n };\n watcher.on('error', (error) => {\n // A watcher that errored is closed by Node \u2014 mark the entry dead so the\n // next acquire creates a fresh one instead of reusing a corpse.\n retire();\n for (const sub of subscribers) sub.onError?.(error);\n });\n // Watchers can also close without first emitting `error` (for example when\n // the watched tree disappears). Never leave that closed handle reusable.\n watcher.on('close', retire);\n registry.set(key, created);\n entry = created;\n }\n\n const active = entry;\n const subscriber: Subscriber = { listener, onError: opts?.onError };\n active.subscribers.add(subscriber);\n\n let closed = false;\n return {\n close() {\n if (closed) return;\n closed = true;\n active.subscribers.delete(subscriber);\n if (active.subscribers.size === 0 && !active.dead) {\n active.dead = true;\n if (registry.get(key) === active) registry.delete(key);\n try {\n active.watcher.close();\n } catch {\n /* already closed */\n }\n }\n },\n };\n}\n", "/**\n * Canonical directory-name ignore list for recursive tree walkers.\n *\n * Every walker that enumerates the project tree (glob, grep's native\n * fallback, tree, the codebase indexer, the chronicle file observer, the\n * semantic-search indexer, project fingerprinting, security scans) should\n * start from this list instead of hand-rolling its own \u2014 the hand-rolled\n * copies drifted, and a walker missing `.turbo` or `__pycache__` pays for\n * it by walking thousands of artifact files.\n *\n * The list is intentionally conservative: only dependency stores, VCS\n * internals, and build/cache artifacts that are never the subject of a\n * search. Directories a user may legitimately target (`.wrongstack`,\n * `vendor`, `out`) are NOT here \u2014 walkers with stricter needs append their\n * own entries.\n *\n * @module utils/walk-ignore\n */\n\n/** Directory basenames every recursive walker skips (matched per path segment). */\nexport const DEFAULT_WALK_IGNORE_DIRS: readonly string[] = Object.freeze([\n 'node_modules',\n '.git',\n 'dist',\n 'build',\n '.next',\n '.nuxt',\n '.turbo',\n 'coverage',\n '.nyc_output',\n '__snapshots__',\n '__pycache__',\n '.venv',\n 'venv',\n 'target',\n '.cache',\n '.parcel-cache',\n '.pnpm-store',\n '.gradle',\n]);\n\n/** Set form of {@link DEFAULT_WALK_IGNORE_DIRS} for per-segment membership checks. */\nexport const DEFAULT_WALK_IGNORE_SET: ReadonlySet<string> = new Set(DEFAULT_WALK_IGNORE_DIRS);\n", "import { createHash } from 'node:crypto';\nimport * as fs from 'node:fs';\nimport * as os from 'node:os';\nimport * as path from 'node:path';\n\n/**\n * Path layout. All developer-level state lives in ~/.wrongstack/.\n * Per-project state is keyed by the canonical project root under\n * ~/.wrongstack/projects/<slug>/. Linked Git worktrees resolve to their main\n * checkout so coordination and durable state are shared across worktrees.\n *\n * The ONLY thing inside the project tree is the optional\n * .wrongstack/AGENTS.md (committed) and .wrongstack/skills/ (committed).\n */\n\nexport interface WstackPaths {\n /** ~/.wrongstack \u2014 global root. */\n globalRoot: string;\n /** Active profile name resolved from the bootstrap config. */\n profileName: string;\n /** ~/.wrongstack/profiles/<activeProfile> \u2014 active user-profile root. */\n profileDir: string;\n /** Absolute project root. */\n projectRoot: string;\n /** Home directory (~) \u2014 base for foreign tool state (~/.codex, ~/.agents, \u2026). */\n homeDir: string;\n /**\n * ~/.wrongstack/profiles/<activeProfile> \u2014 directory for profile-scoped\n * user state (mode.json, statusline.json, custom-context-modes.json, \u2026).\n */\n configDir: string;\n /** ~/.wrongstack/config.json \u2014 bootstrap config (activeProfile + version). */\n globalConfig: string;\n /**\n * ~/.wrongstack/profiles \u2014 directory containing per-profile configs.\n * Each profile has its own subdirectory with a config.json.\n */\n profilesDir: string;\n /**\n * Resolve the config path for a named profile.\n * Returns ~/.wrongstack/profiles/<name>/config.json.\n */\n profileConfig: (name: string) => string;\n /** Resolve ~/.wrongstack/profiles/<name>/statusline.json */\n profileStatuslineConfig: (name: string) => string;\n /** Resolve ~/.wrongstack/profiles/<name>/mode.json */\n profileModeConfig: (name: string) => string;\n /** Resolve ~/.wrongstack/profiles/<name>/provider-status.json */\n profileProviderStatus: (name: string) => string;\n /** Resolve ~/.wrongstack/profiles/<name>/update-cache.json */\n profileUpdateCache: (name: string) => string;\n /** ~/.wrongstack/.key \u2014 32 random bytes, mode 0600, AES-GCM key for the secret vault. */\n secretsKey: string;\n /** ~/.wrongstack/profiles/<activeProfile>/memory.md \u2014 profile memory. */\n globalMemory: string;\n /** ~/.wrongstack/profiles/<activeProfile>/skills \u2014 profile skills. */\n globalSkills: string;\n /** ~/.claude/skills \u2014 user-global skills from foreign coding agents (Claude Code, Codex, \u2026). Read-only. */\n globalClaudeSkills: string;\n /** ~/.wrongstack/profiles/<activeProfile>/design-kits \u2014 profile Design Studio kits. */\n globalDesignKits: string;\n /** ~/.wrongstack/profiles/<activeProfile>/prompts \u2014 profile prompt library. */\n globalPrompts: string;\n /** ~/.wrongstack/profiles/<activeProfile>/instructions \u2014 profile instruction overrides. */\n globalInstructions: string;\n /** ~/.wrongstack/profiles/<activeProfile>/prompt-usage.json \u2014 prompt usage. */\n promptUsage: string;\n /** ~/.wrongstack/cache \u2014 fetched data (models.dev, etc.). */\n cacheDir: string;\n /** ~/.wrongstack/cache/models.dev.json */\n modelsCache: string;\n /** ~/.wrongstack/cache/models-overlay.json \u2014 cached curated overlay. */\n modelsOverlayCache: string;\n /**\n * Per-project codebase symbol index (SQLite). Lives under the global project\n * dir \u2014 NOT inside the repo \u2014 so it never clutters the working tree or needs\n * gitignoring. `~/.wrongstack/projects/<hash>/codebase-index`.\n */\n projectCodebaseIndex: string;\n /** ~/.wrongstack/profiles/<activeProfile>/history \u2014 REPL line history. */\n historyFile: string;\n /** ~/.wrongstack/logs/wrongstack.log */\n logFile: string;\n /** ~/.wrongstack/projects/<hash> */\n projectDir: string;\n /** ~/.wrongstack/projects/<hash>/memory.md */\n projectMemory: string;\n /** ~/.wrongstack/projects/<hash>/sessions */\n projectSessions: string;\n /** ~/.wrongstack/projects/<hash>/trust.json */\n projectTrust: string;\n /** ~/.wrongstack/projects/<hash>/meta.json */\n projectMeta: string;\n /** ~/.wrongstack/projects/<hash>/config.local.json \u2014 optional override */\n projectLocalConfig: string;\n /** <project>/.wrongstack/config.json \u2014 per-project settings (safe fields only).\n * This lives inside the project root so it can be gitignored or shared. */\n inProjectConfig: string;\n /** <project>/.wrongstack/AGENTS.md \u2014 committed project memory. */\n inProjectAgentsFile: string;\n /** <project>/.wrongstack/skills \u2014 committed project skills. */\n inProjectSkills: string;\n /** <project>/.claude/skills \u2014 project skills authored for foreign coding agents (Claude Code, \u2026). Read-only. */\n inProjectClaudeSkills: string;\n /** <project>/.wrongstack/prompts \u2014 committed project prompt library. */\n inProjectPrompts: string;\n /** <project>/.wrongstack/instructions \u2014 committed project instruction overrides. */\n inProjectInstructions: string;\n /** <project>/.wrongstack/design-kits \u2014 committed project Design Studio kits. */\n inProjectDesignKits: string;\n /** <project>/.wrongstack/worktrees \u2014 git worktrees for per-phase isolation (gitignored). */\n inProjectWorktrees: string;\n /** Stable hash for the canonical project root (shared by linked Git worktrees). */\n projectHash: string;\n /** Human-readable canonical project slug, shared by linked Git worktrees. */\n projectSlug: string;\n /** ~/.wrongstack/projects/<hash>/goal.json \u2014 goal persistence */\n projectGoal: string;\n /** ~/.wrongstack/projects/<hash>/input-history.json \u2014 TUI prompt input history */\n projectInputHistory: string;\n /** ~/.wrongstack/projects/<hash>/specs \u2014 SDD spec files */\n projectSpecs: string;\n /** ~/.wrongstack/projects/<hash>/task-graphs \u2014 SDD task graphs */\n projectTaskGraphs: string;\n /** ~/.wrongstack/projects/<hash>/sdd-session.json \u2014 SDD session state */\n projectSddSession: string;\n /** ~/.wrongstack/projects/<hash>/plan.json \u2014 plan persistence */\n projectPlan: string;\n /** ~/.wrongstack/projects/<hash>/autophase \u2014 Goal phase-graph JSON files (dir name kept for backward compat) */\n projectAutophase: string;\n /** ~/.wrongstack/projects/<hash>/sdd-boards \u2014 live SDD board snapshots + JSONL event logs */\n projectSddBoards: string;\n /** ~/.wrongstack/profiles/<activeProfile>/sync.json \u2014 CloudSync configuration */\n syncConfig: string;\n /** ~/.wrongstack/config-history \u2014 timestamped backups on every config write */\n configHistoryDir: string;\n /** Function to get the status.json path for a project given its hash. */\n projectStatus: (projectHash: string) => string;\n}\n\n/**\n * Resolve the stable project identity root used by global WrongStack state.\n *\n * A linked Git worktree has its own checkout path and a `.git` *file* that\n * points into `<main>/.git/worktrees/<name>`. Its `commondir` points back to\n * the main checkout's `.git` directory. Treating the linked checkout path as\n * the project identity would split one repository into multiple session,\n * registry, and mailbox directories \u2014 agents in different worktrees would be\n * unable to see or message each other.\n *\n * Project-local paths still use the caller's actual checkout. Only global\n * state identity is canonicalized. Non-Git projects, normal checkouts, Git\n * submodules, and separate-git-dir layouts keep their existing identity.\n */\nexport function canonicalProjectRoot(absRoot: string): string {\n const checkoutRoot = path.resolve(absRoot);\n const dotGit = path.join(checkoutRoot, '.git');\n\n try {\n if (!fs.statSync(dotGit).isFile()) return checkoutRoot;\n\n const gitDirLine = fs.readFileSync(dotGit, 'utf8').trim();\n const match = /^gitdir:\\s*(.+)$/i.exec(gitDirLine);\n if (!match?.[1]) return checkoutRoot;\n\n const gitDir = path.resolve(checkoutRoot, match[1].trim());\n const commonDirFile = path.join(gitDir, 'commondir');\n if (!fs.statSync(commonDirFile).isFile()) return checkoutRoot;\n\n const commonDir = path.resolve(gitDir, fs.readFileSync(commonDirFile, 'utf8').trim());\n // Linked worktrees created by Git share the main checkout's `.git` dir.\n // A submodule or --separate-git-dir layout may point elsewhere; do not\n // guess a working-tree root for those shapes.\n if (path.basename(commonDir).toLowerCase() !== '.git') return checkoutRoot;\n return path.dirname(commonDir);\n } catch {\n // Missing/malformed administrative files must never make path resolution\n // fail. Falling back preserves the pre-canonicalization behavior.\n return checkoutRoot;\n }\n}\n\nexport function projectHash(absRoot: string): string {\n return createHash('sha256').update(canonicalProjectRoot(absRoot)).digest('hex').slice(0, 12);\n}\n\n/**\n * Human-readable project directory name: slugified folder name + short hash\n * suffix for uniqueness. e.g. `wrongstack-a1b2c3` instead of `3024e5e6fa58`.\n */\nexport function projectSlug(absRoot: string): string {\n const identityRoot = canonicalProjectRoot(absRoot);\n const base = slugify(path.basename(identityRoot));\n const hash = createHash('sha256').update(identityRoot).digest('hex').slice(0, 6);\n return `${base}-${hash}`;\n}\n\n/** Turn a folder name into a filesystem-safe lowercase slug. */\nfunction slugify(name: string): string {\n return (\n name\n .toLowerCase()\n // Collapse any run of non-alphanumeric chars into a single hyphen.\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '')\n .slice(0, 40) || 'project'\n );\n}\n\nexport interface WstackPathOptions {\n userHome?: string | undefined;\n projectRoot: string;\n /** Override the global root (e.g. for tests). Default: `${userHome}/.wrongstack`. */\n globalRoot?: string | undefined;\n /** Explicit profile override. Otherwise read from the root bootstrap config. */\n profileName?: string | undefined;\n}\n\n/** Make an untrusted profile name safe for use as one path segment. */\nexport function safeProfileName(name: string | undefined): string {\n const safe = (name ?? '').replace(/[/\\\\:]/g, '_').replace(/\\.\\./g, '_').trim();\n return safe || 'default';\n}\n\n/**\n * Resolve the selected profile from ~/.wrongstack/config.json. The root file\n * is bootstrap metadata only; a missing/corrupt bootstrap selects `default`.\n */\nexport function activeProfileName(globalRoot: string): string {\n try {\n const parsed = JSON.parse(fs.readFileSync(path.join(globalRoot, 'config.json'), 'utf8')) as {\n activeProfile?: unknown;\n };\n return safeProfileName(typeof parsed.activeProfile === 'string' ? parsed.activeProfile : undefined);\n } catch {\n return 'default';\n }\n}\n\n/**\n * The global `~/.wrongstack` root, honoring the `WRONGSTACK_HOME` env\n * override. The override exists so tests (and sandboxed runs) can redirect\n * ALL global state \u2014 config, secrets, logs, projects/, mailboxes \u2014 away from\n * the real user home. Before it existed, `pnpm test` booted runtimes against\n * the real `~/.wrongstack`: it read the user's real config.json (starting a\n * second live Telegram poller), appended to the real wrongstack.log, and left\n * ~20k orphaned fixture dirs under projects/.\n *\n * Every code path that wants the global dir must come through here (or\n * through `resolveWstackPaths`) instead of `path.join(os.homedir(), '.wrongstack')`.\n */\nexport function wstackGlobalRoot(): string {\n const fromEnv = process.env['WRONGSTACK_HOME'];\n if (fromEnv && fromEnv.trim().length > 0) return path.resolve(fromEnv);\n return path.join(os.homedir(), '.wrongstack');\n}\n\nexport function resolveWstackPaths(opts: WstackPathOptions): WstackPaths {\n // Precedence: explicit globalRoot > explicit userHome (callers/tests that\n // pass one expect paths under it) > WRONGSTACK_HOME env > real home dir.\n const globalRoot =\n opts.globalRoot ?? (opts.userHome ? path.join(opts.userHome, '.wrongstack') : wstackGlobalRoot());\n // Home dir for FOREIGN tool state (Claude Code's ~/.claude). Independent of\n // WRONGSTACK_HOME, which redirects only WrongStack state: a real user's\n // Claude skills live in their real home, but tests pass `userHome` to keep\n // both `.wrongstack` and `.claude` under a temp dir.\n const homeDir = opts.userHome ?? os.homedir();\n const profileName = safeProfileName(opts.profileName ?? activeProfileName(globalRoot));\n const profileDir = path.join(globalRoot, 'profiles', profileName);\n const hash = projectHash(opts.projectRoot);\n const slug = projectSlug(opts.projectRoot);\n const projectDir = path.join(globalRoot, 'projects', slug);\n return {\n globalRoot,\n profileName,\n profileDir,\n projectRoot: opts.projectRoot,\n homeDir,\n configDir: profileDir,\n globalConfig: path.join(globalRoot, 'config.json'),\n profilesDir: path.join(globalRoot, 'profiles'),\n profileConfig: (name: string) => {\n return path.join(globalRoot, 'profiles', safeProfileName(name), 'config.json');\n },\n profileStatuslineConfig: (name: string) => {\n return path.join(globalRoot, 'profiles', safeProfileName(name), 'statusline.json');\n },\n profileModeConfig: (name: string) => {\n return path.join(globalRoot, 'profiles', safeProfileName(name), 'mode.json');\n },\n profileProviderStatus: (name: string) => {\n return path.join(globalRoot, 'profiles', safeProfileName(name), 'provider-status.json');\n },\n profileUpdateCache: (name: string) => {\n return path.join(globalRoot, 'profiles', safeProfileName(name), 'update-cache.json');\n },\n secretsKey: path.join(globalRoot, '.key'),\n globalMemory: path.join(profileDir, 'memory.md'),\n globalSkills: path.join(profileDir, 'skills'),\n globalClaudeSkills: path.join(homeDir, '.claude', 'skills'),\n globalDesignKits: path.join(profileDir, 'design-kits'),\n globalPrompts: path.join(profileDir, 'prompts'),\n globalInstructions: path.join(profileDir, 'instructions'),\n promptUsage: path.join(profileDir, 'prompt-usage.json'),\n cacheDir: path.join(globalRoot, 'cache'),\n modelsCache: path.join(globalRoot, 'cache', 'models.dev.json'),\n modelsOverlayCache: path.join(globalRoot, 'cache', 'models-overlay.json'),\n historyFile: path.join(profileDir, 'history'),\n logFile: path.join(globalRoot, 'logs', 'wrongstack.log'),\n projectDir,\n projectCodebaseIndex: path.join(projectDir, 'codebase-index'),\n projectMemory: path.join(projectDir, 'memory.md'),\n projectSessions: path.join(projectDir, 'sessions'),\n projectTrust: path.join(projectDir, 'trust.json'),\n projectMeta: path.join(projectDir, 'meta.json'),\n projectLocalConfig: path.join(projectDir, 'config.local.json'),\n inProjectConfig: path.join(opts.projectRoot, '.wrongstack', 'config.json'),\n inProjectAgentsFile: path.join(opts.projectRoot, '.wrongstack', 'AGENTS.md'),\n inProjectSkills: path.join(opts.projectRoot, '.wrongstack', 'skills'),\n inProjectClaudeSkills: path.join(opts.projectRoot, '.claude', 'skills'),\n inProjectPrompts: path.join(opts.projectRoot, '.wrongstack', 'prompts'),\n inProjectInstructions: path.join(opts.projectRoot, '.wrongstack', 'instructions'),\n inProjectDesignKits: path.join(opts.projectRoot, '.wrongstack', 'design-kits'),\n inProjectWorktrees: path.join(opts.projectRoot, '.wrongstack', 'worktrees'),\n projectHash: hash,\n projectSlug: slug,\n projectGoal: path.join(projectDir, 'goal.json'),\n projectInputHistory: path.join(projectDir, 'input-history.json'),\n projectSpecs: path.join(projectDir, 'specs'),\n projectTaskGraphs: path.join(projectDir, 'task-graphs'),\n projectSddSession: path.join(projectDir, 'sdd-session.json'),\n projectPlan: path.join(projectDir, 'plan.json'),\n projectAutophase: path.join(projectDir, 'autophase'),\n projectSddBoards: path.join(projectDir, 'sdd-boards'),\n syncConfig: path.join(profileDir, 'sync.json'),\n configHistoryDir: path.join(globalRoot, 'config-history'),\n projectStatus: (projectHash: string) => path.join(globalRoot, 'projects', projectHash, 'status.json'),\n };\n}\n", "/**\n * heap-watchdog \u2014 periodic V8 heap sampling for long-running CLI/WebUI sessions.\n *\n * Extracted from the TUI's heap-watchdog so that every surface (CLI headless,\n * WebUI server, TUI) shares one implementation. Long autonomous sessions (10h+)\n * have hit `FATAL ERROR: Ineffective mark-compacts near heap limit` with nothing\n * attributing WHAT grew. This watchdog:\n *\n * - samples `process.memoryUsage()` + `v8.getHeapStatistics()` on an interval\n * - appends a JSONL diagnostic line to `~/.wrongstack/logs/heap.jsonl` every\n * `logEveryMs`, including caller-supplied structure sizes\n * - fires `onWarn` when heap usage crosses WARN (60%) / CRITICAL (85%)\n * of the V8 heap limit, once per crossing (re-arms with hysteresis)\n * - clears stale `performance.mark()`/`performance.measure()` entries to\n * prevent unintentional leakage from React dev tools or other dependencies\n *\n * The log line is intentionally flat JSON so `jq`/spreadsheets can plot it.\n */\nimport * as fs from 'node:fs';\nimport * as fsp from 'node:fs/promises';\nimport * as path from 'node:path';\nimport { PerformanceObserver, constants as performanceConstants } from 'node:perf_hooks';\nimport * as v8 from 'node:v8';\nimport type {\n HeapDiagnosticFields,\n HeapSample,\n HeapWatchdogOptions,\n} from './heap-watchdog-types.js';\nimport { createMemoryFlightRecorder } from './memory-flight-recorder.js';\nimport { wstackGlobalRoot } from './wstack-paths.js';\n\nexport type {\n HeapDiagnosticFields,\n HeapDiagnosticValue,\n HeapSample,\n HeapWatchdogOptions,\n} from './heap-watchdog-types.js';\n\nconst MB = 1024 * 1024;\n\nexport function defaultHeapLogPath(): string {\n const override = process.env['WRONGSTACK_HEAP_LOG_PATH']?.trim();\n if (override) return path.resolve(override);\n return path.join(wstackGlobalRoot(), 'logs', 'heap.jsonl');\n}\n\nexport function takeHeapSample(): HeapSample {\n const m = process.memoryUsage();\n const heap = v8.getHeapStatistics();\n const spaces = v8.getHeapSpaceStatistics();\n const spaceUsed = (name: string): number =>\n spaces.find((space) => space.space_name === name)?.space_used_size ?? 0;\n const limit = heap.heap_size_limit || 0;\n let activeResources = 0;\n let activeResourceTypes = '';\n try {\n const resources = process.getActiveResourcesInfo?.() ?? [];\n activeResources = resources.length;\n const counts = new Map<string, number>();\n for (const resource of resources) counts.set(resource, (counts.get(resource) ?? 0) + 1);\n activeResourceTypes = [...counts]\n .sort(([left], [right]) => left.localeCompare(right))\n .map(([resource, count]) => `${resource}=${count}`)\n .join(',');\n } catch {\n // getActiveResourcesInfo can throw during OOM teardown\n }\n return {\n ts: new Date().toISOString(),\n rss: m.rss,\n heapUsed: m.heapUsed,\n heapTotal: m.heapTotal,\n external: m.external,\n arrayBuffers: m.arrayBuffers,\n nativeResidual: Math.max(0, m.rss - m.heapTotal - m.external),\n oldSpaceUsed: spaceUsed('old_space'),\n newSpaceUsed: spaceUsed('new_space'),\n largeObjectSpaceUsed: spaceUsed('large_object_space'),\n codeSpaceUsed: spaceUsed('code_space'),\n mallocedMemory: heap.malloced_memory,\n peakMallocedMemory: heap.peak_malloced_memory,\n nativeContexts: heap.number_of_native_contexts,\n detachedContexts: heap.number_of_detached_contexts,\n activeResources,\n activeResourceTypes,\n heapLimit: limit,\n load: limit > 0 ? m.heapUsed / limit : 0,\n };\n}\n\n/**\n * Start the watchdog. Returns an async stop function \u2014 await it on exit when\n * the final diagnostic sample must reach storage. All I/O is best-effort and\n * serialized; a failed append never throws into the caller.\n */\nexport function startHeapWatchdog(opts: HeapWatchdogOptions = {}): () => Promise<void> {\n const profileMode = process.env['WRONGSTACK_MEMORY_PROFILE'] === '1';\n const sampleEveryMs = opts.sampleEveryMs ?? (profileMode ? 5_000 : 30_000);\n const logEveryMs = opts.logEveryMs ?? (profileMode ? 5_000 : 60_000);\n const logPath = opts.logPath ?? defaultHeapLogPath();\n const warnAt = opts.warnAt ?? 0.6;\n const criticalAt = opts.criticalAt ?? 0.85;\n // Hysteresis: once fired, a level re-arms only after load falls this far\n // below its threshold \u2014 prevents a flapping boundary from spamming chat.\n const REARM_MARGIN = 0.05;\n\n let warnArmed = true;\n let criticalArmed = true;\n let lastLogAt = 0;\n let writeInFlight = false;\n let pendingLine: string | undefined;\n let drainPromise: Promise<void> | undefined;\n let stopped = false;\n let dirReady = false;\n const flightRecorder = createMemoryFlightRecorder();\n let gcMajorCount = 0;\n let gcMinorCount = 0;\n let gcIncrementalCount = 0;\n let gcWeakCallbackCount = 0;\n let gcDurationMs = 0;\n let postGcHeapUsed = 0;\n let postMajorGcHeapUsed = 0;\n let lastGcAt = 0;\n let lastMajorGcAt = 0;\n const gcObserver = new PerformanceObserver((list) => {\n for (const entry of list.getEntries()) {\n const kind = (entry as PerformanceEntry & { detail?: { kind?: number } }).detail?.kind ?? 0;\n if ((kind & performanceConstants.NODE_PERFORMANCE_GC_MAJOR) !== 0) gcMajorCount++;\n if ((kind & performanceConstants.NODE_PERFORMANCE_GC_MINOR) !== 0) gcMinorCount++;\n if ((kind & performanceConstants.NODE_PERFORMANCE_GC_INCREMENTAL) !== 0) {\n gcIncrementalCount++;\n }\n if ((kind & performanceConstants.NODE_PERFORMANCE_GC_WEAKCB) !== 0) gcWeakCallbackCount++;\n gcDurationMs += entry.duration;\n postGcHeapUsed = process.memoryUsage().heapUsed;\n if ((kind & performanceConstants.NODE_PERFORMANCE_GC_MAJOR) !== 0) {\n postMajorGcHeapUsed = postGcHeapUsed;\n lastMajorGcAt = Date.now();\n }\n lastGcAt = Date.now();\n }\n });\n try {\n gcObserver.observe({ entryTypes: ['gc'] });\n } catch {\n // GC performance entries are unavailable on some runtimes.\n }\n const collectRuntimeStats = (): HeapDiagnosticFields => ({\n gcMajorCount,\n gcMinorCount,\n gcIncrementalCount,\n gcWeakCallbackCount,\n gcDurationMs: Math.round(gcDurationMs),\n postGcHeapUsed,\n postMajorGcHeapUsed,\n lastGcAgoMs: lastGcAt > 0 ? Date.now() - lastGcAt : -1,\n lastMajorGcAgoMs: lastMajorGcAt > 0 ? Date.now() - lastMajorGcAt : -1,\n });\n const writeDiagnosticLine =\n opts.writeDiagnosticLine ??\n (async (targetPath: string, line: string): Promise<void> => {\n if (!dirReady) {\n await fsp.mkdir(path.dirname(targetPath), { recursive: true });\n dirReady = true;\n }\n await fsp.appendFile(targetPath, `${line}\\n`, 'utf8');\n });\n\n const drainWrites = async (firstLine: string): Promise<void> => {\n let line: string | undefined = firstLine;\n while (line !== undefined) {\n try {\n await writeDiagnosticLine(logPath, line);\n } catch {\n // Diagnostic writes are best-effort. A later pending sample retries.\n }\n line = pendingLine;\n pendingLine = undefined;\n }\n writeInFlight = false;\n };\n\n const append = (line: string): void => {\n if (stopped) return;\n if (writeInFlight) {\n // Keep only the freshest sample while storage is slow. A promise chain\n // retained every queued JSON line and could itself become a heap leak.\n pendingLine = line;\n return;\n }\n writeInFlight = true;\n drainPromise = drainWrites(line);\n };\n\n const appendTerminalSample = (\n event: 'memory.flight_recorder.crash' | 'memory.flight_recorder.exit',\n error?: unknown,\n origin?: string,\n ): void => {\n if (stopped) return;\n let extras: HeapDiagnosticFields = {};\n try {\n extras = opts.collectStats?.() ?? {};\n } catch {\n // Terminal evidence must survive a broken collector.\n }\n try {\n const sample = takeHeapSample();\n const runtimeStats = collectRuntimeStats();\n fs.mkdirSync(path.dirname(logPath), { recursive: true });\n fs.appendFileSync(\n logPath,\n `${JSON.stringify({\n ...extras,\n ...runtimeStats,\n event,\n ...(origin ? { crashOrigin: origin } : {}),\n ...(error instanceof Error\n ? { errorName: error.name, errorMessage: error.message.slice(0, 1_000) }\n : {}),\n pid: process.pid,\n ...sample,\n exitCode: process.exitCode,\n })}\\n`,\n 'utf8',\n );\n } catch {\n // There is no safer fallback during process teardown.\n }\n };\n const onUncaughtException = (error: Error, origin: NodeJS.UncaughtExceptionOrigin): void => {\n appendTerminalSample('memory.flight_recorder.crash', error, origin);\n };\n const onProcessExit = (): void => {\n appendTerminalSample('memory.flight_recorder.exit');\n };\n process.on('uncaughtExceptionMonitor', onUncaughtException);\n process.on('exit', onProcessExit);\n\n const tick = (): void => {\n // User-timing hygiene. Node keeps every performance.mark()/measure()\n // entry in the global timeline until explicitly cleared \u2014 there is no\n // browser DevTools consuming them. React's development build (Component\n // Performance Track) measures every component render, which leaked\n // ~3 GB of PerformanceMeasure objects over a long TUI session before\n // NODE_ENV defaulted to production. Clearing here is belt-and-braces\n // against ANY dependency that emits user timings; the per-interval\n // count is logged so a regression is visible in heap.jsonl.\n let userTimings = 0;\n try {\n userTimings =\n performance.getEntriesByType('mark').length +\n performance.getEntriesByType('measure').length;\n if (userTimings > 0) {\n performance.clearMarks();\n performance.clearMeasures();\n }\n } catch {\n // performance API unavailable \u2014 nothing to clean\n }\n\n const s = takeHeapSample();\n let extras: HeapDiagnosticFields = {};\n try {\n extras = opts.collectStats?.() ?? {};\n } catch {\n // collectStats must not break sampling\n }\n const runtimeStats = collectRuntimeStats();\n const diagnosticStats = { ...extras, ...runtimeStats };\n const memoryDiagnosis = flightRecorder.observe(s, diagnosticStats);\n // Threshold callbacks \u2014 critical first so a single giant jump surfaces\n // the stronger message, not both.\n if (s.load >= criticalAt && criticalArmed) {\n criticalArmed = false;\n warnArmed = false;\n opts.onWarn?.(\n 'critical',\n `Heap critical: ${Math.round(s.heapUsed / MB)} MB of ~${Math.round(s.heapLimit / MB)} MB V8 limit (${Math.round(s.load * 100)}%). ` +\n `An out-of-memory crash is likely soon \u2014 finish/checkpoint work and restart the session. Diagnostics: ${logPath}`,\n s,\n );\n } else if (s.load >= warnAt && warnArmed) {\n warnArmed = false;\n opts.onWarn?.(\n 'warn',\n `Heap high: ${Math.round(s.heapUsed / MB)} MB of ~${Math.round(s.heapLimit / MB)} MB V8 limit (${Math.round(s.load * 100)}%). ` +\n `Memory diagnostics are being recorded to ${logPath}`,\n s,\n );\n }\n // Re-arm with hysteresis.\n if (!warnArmed && s.load < warnAt - REARM_MARGIN) warnArmed = true;\n if (!criticalArmed && s.load < criticalAt - REARM_MARGIN) criticalArmed = true;\n\n // Periodic diagnostic line; also force one on every fired threshold so\n // the crossing itself is always on disk even between log intervals.\n const due = Date.now() - lastLogAt >= logEveryMs;\n const crossed = s.load >= warnAt;\n const captured = typeof memoryDiagnosis['memoryCaptureReason'] === 'string';\n if (due || crossed || captured) {\n lastLogAt = Date.now();\n // Put canonical fields last so a buggy collector cannot overwrite pid,\n // timestamps or memory readings with stale values.\n append(\n JSON.stringify({\n ...extras,\n ...runtimeStats,\n ...memoryDiagnosis,\n pid: process.pid,\n ...s,\n userTimings,\n }),\n );\n }\n };\n\n const timer = setInterval(tick, sampleEveryMs);\n timer.unref?.();\n // Immediate first sample so a session that OOMs early still leaves a trace.\n tick();\n\n return async () => {\n stopped = true;\n clearInterval(timer);\n gcObserver.disconnect();\n process.removeListener('uncaughtExceptionMonitor', onUncaughtException);\n process.removeListener('exit', onProcessExit);\n await drainPromise;\n await flightRecorder.stop();\n };\n}\n\ninterface SharedHeapWatchdogContributor {\n collectStats?: (() => HeapDiagnosticFields) | undefined;\n onWarn?: HeapWatchdogOptions['onWarn'];\n}\n\nconst sharedContributors = new Map<number, SharedHeapWatchdogContributor>();\nlet nextSharedContributorId = 1;\nlet sharedSamplerActive = false;\nlet stopSharedSampler: (() => Promise<void>) | undefined;\n\nfunction collectSharedStats(): HeapDiagnosticFields {\n const merged: HeapDiagnosticFields = {};\n for (const contributor of sharedContributors.values()) {\n try {\n Object.assign(merged, contributor.collectStats?.() ?? {});\n } catch {\n // One diagnostics contributor must not hide sibling counters.\n }\n }\n return merged;\n}\n\nfunction warnSharedContributors(\n level: 'warn' | 'critical',\n message: string,\n sample: HeapSample,\n): void {\n for (const contributor of sharedContributors.values()) {\n try {\n contributor.onWarn?.(level, message, sample);\n } catch {\n // Warning handlers are observational and must not break the sampler.\n }\n }\n}\n\n/**\n * Start or join the single process-wide watchdog.\n *\n * WrongStack's CLI mounts downstream surfaces (TUI/WebUI) inside the same Node\n * process. Each surface used to start its own timer and append alternating\n * partial records for the same PID. Contributors now share one sampler while\n * still attaching surface-specific counters and warning handlers.\n *\n * The first contributor owns cadence/path/writer options. Later contributors\n * only add `collectStats` and `onWarn`. The sampler stops after the final\n * contributor unregisters.\n */\nexport function startSharedHeapWatchdog(opts: HeapWatchdogOptions = {}): () => Promise<void> {\n if (\n process.env['NODE_ENV'] === 'test' &&\n !sharedSamplerActive &&\n opts.logPath === undefined &&\n opts.writeDiagnosticLine === undefined\n ) {\n return async () => undefined;\n }\n const id = nextSharedContributorId++;\n sharedContributors.set(id, {\n collectStats: opts.collectStats,\n onWarn: opts.onWarn,\n });\n\n if (!sharedSamplerActive) {\n sharedSamplerActive = true;\n stopSharedSampler = startHeapWatchdog({\n ...opts,\n collectStats: collectSharedStats,\n onWarn: warnSharedContributors,\n });\n }\n\n let stopped = false;\n return async () => {\n if (stopped) return;\n stopped = true;\n sharedContributors.delete(id);\n if (sharedContributors.size > 0 || !sharedSamplerActive) return;\n const stop = stopSharedSampler;\n if (!stop) return;\n sharedSamplerActive = false;\n stopSharedSampler = undefined;\n await stop();\n };\n}\n", "import * as fsp from 'node:fs/promises';\nimport * as path from 'node:path';\nimport {\n type ContinuousMemoryProfiler,\n type MemoryProfileArtifact,\n startContinuousMemoryProfiler,\n} from './continuous-memory-profiler.js';\nimport type { HeapDiagnosticFields, HeapSample } from './heap-watchdog-types.js';\nimport { wstackGlobalRoot } from './wstack-paths.js';\n\nconst MB = 1024 * 1024;\nconst HOUR_MS = 60 * 60 * 1000;\nconst DEFAULT_WINDOW_MS = 5 * 60 * 1000;\nconst DEFAULT_MINIMUM_WINDOW_MS = 2 * 60 * 1000;\nconst DEFAULT_COOLDOWN_MS = 15 * 60 * 1000;\nconst DEFAULT_CONTINUOUS_CAPTURE_MS = 5 * 60 * 1000;\nconst MAX_OBSERVATIONS = 24;\nconst MAX_CAPTURE_SESSIONS = 12;\nconst MAX_CAPTURES_PER_SESSION = 6;\nconst SESSION_MAX_AGE_MS = 7 * 24 * HOUR_MS;\n\ntype CaptureReason =\n | 'absolute-heap'\n | 'detached-contexts'\n | 'heap-growth'\n | 'heap-load'\n | 'interval'\n | 'native-rss-growth';\n\nexport interface MemoryFlightObservation {\n at: number;\n heapUsed: number;\n rss: number;\n nativeResidual: number;\n}\n\nexport interface MemoryCaptureEvent {\n reason: CaptureReason;\n capturedAt: string;\n pid: number;\n sample: HeapSample;\n stats: HeapDiagnosticFields;\n diagnosis: HeapDiagnosticFields;\n observations: readonly MemoryFlightObservation[];\n}\n\nexport interface MemoryCaptureWriter {\n readonly artifactDir: string;\n capture(event: MemoryCaptureEvent): Promise<void>;\n diagnostics?(): HeapDiagnosticFields;\n stop(): Promise<void>;\n}\n\nexport interface MemoryFlightRecorder {\n readonly artifactDir: string;\n observe(sample: HeapSample, stats: HeapDiagnosticFields): HeapDiagnosticFields;\n stop(): Promise<void>;\n}\n\nexport interface MemoryFlightRecorderOptions {\n now?: (() => number) | undefined;\n diagnosticsRoot?: string | undefined;\n windowMs?: number | undefined;\n minimumWindowMs?: number | undefined;\n cooldownMs?: number | undefined;\n continuousCaptureMs?: number | undefined;\n warmupMs?: number | undefined;\n absoluteHeapBytes?: number | undefined;\n heapGrowthBytes?: number | undefined;\n heapGrowthBytesPerHour?: number | undefined;\n nativeGrowthBytes?: number | undefined;\n nativeGrowthBytesPerHour?: number | undefined;\n captureWriter?: MemoryCaptureWriter | undefined;\n enabled?: boolean | undefined;\n}\n\nfunction timestampSlug(date = new Date()): string {\n return date.toISOString().replaceAll(':', '').replaceAll('.', '-');\n}\n\nasync function pruneCaptureFiles(artifactDir: string): Promise<void> {\n const entries = await fsp.readdir(artifactDir, { withFileTypes: true });\n const captures = entries\n .filter(\n (entry) => entry.isFile() && entry.name.startsWith('event-') && entry.name.endsWith('.json'),\n )\n .map((entry) => entry.name)\n .sort();\n const remove = captures.slice(0, Math.max(0, captures.length - MAX_CAPTURES_PER_SESSION));\n await Promise.all(\n remove.flatMap((eventName) => {\n const stem = eventName.slice('event-'.length, -'.json'.length);\n return [\n fsp.rm(path.join(artifactDir, eventName), { force: true }),\n fsp.rm(path.join(artifactDir, `allocations-${stem}.heapprofile`), { force: true }),\n fsp.rm(path.join(artifactDir, `allocations-${stem}.pb.gz`), { force: true }),\n ];\n }),\n );\n}\n\nasync function pruneOldSessions(root: string, currentDir: string): Promise<void> {\n const entries = await fsp.readdir(root, { withFileTypes: true });\n const sessions = await Promise.all(\n entries\n .filter((entry) => entry.isDirectory() && entry.name !== path.basename(currentDir))\n .map(async (entry) => {\n const fullPath = path.join(root, entry.name);\n const stat = await fsp.stat(fullPath);\n return { fullPath, mtimeMs: stat.mtimeMs };\n }),\n );\n sessions.sort((a, b) => b.mtimeMs - a.mtimeMs);\n const now = Date.now();\n await Promise.all(\n sessions\n .filter(\n (session, index) =>\n now - session.mtimeMs > SESSION_MAX_AGE_MS ||\n (index >= MAX_CAPTURE_SESSIONS && now - session.mtimeMs > 24 * HOUR_MS),\n )\n .map((session) => fsp.rm(session.fullPath, { recursive: true, force: true })),\n );\n}\n\nclass ContinuousMemoryCaptureWriter implements MemoryCaptureWriter {\n readonly artifactDir: string;\n private readonly root: string;\n private readonly ready: Promise<void>;\n private profiler: ContinuousMemoryProfiler | undefined;\n private profilerBackend = 'initializing';\n private fallbackReason: string | undefined;\n private startError: string | undefined;\n private lastSummary:\n | {\n sampledBytes: number;\n sampledObjects: number;\n sampleCount: number;\n topStack?: string | undefined;\n topStackBytes?: number | undefined;\n }\n | undefined;\n private stopped = false;\n\n constructor(root: string) {\n this.root = root;\n this.artifactDir = path.join(root, `${timestampSlug()}-pid-${process.pid}`);\n this.ready = this.start().catch((error) => {\n this.startError = error instanceof Error ? error.message : String(error);\n this.profilerBackend = 'unavailable';\n });\n }\n\n private async start(): Promise<void> {\n const started = await startContinuousMemoryProfiler();\n this.profiler = started.profiler;\n this.profilerBackend = started.profiler.backend;\n this.fallbackReason = started.fallbackReason;\n }\n\n diagnostics(): HeapDiagnosticFields {\n return {\n memoryProfilerBackend: this.profilerBackend,\n ...(this.fallbackReason ? { memoryProfilerFallbackReason: this.fallbackReason } : {}),\n ...(this.startError ? { memoryProfilerStartError: this.startError } : {}),\n ...(this.lastSummary\n ? {\n memoryProfileSampledBytes: this.lastSummary.sampledBytes,\n memoryProfileSampledObjects: this.lastSummary.sampledObjects,\n memoryProfileSampleCount: this.lastSummary.sampleCount,\n memoryProfileTopStack: this.lastSummary.topStack,\n memoryProfileTopStackBytes: this.lastSummary.topStackBytes,\n }\n : {}),\n };\n }\n\n async capture(event: MemoryCaptureEvent): Promise<void> {\n await this.ready;\n if (this.stopped) return;\n let profile: MemoryProfileArtifact | undefined;\n let captureError = this.startError;\n if (!captureError && this.profiler) {\n try {\n profile = await this.profiler.capture();\n const top = profile.summary?.topStacks[0];\n if (profile.summary) {\n this.lastSummary = {\n sampledBytes: profile.summary.sampledBytes,\n sampledObjects: profile.summary.sampledObjects,\n sampleCount: profile.summary.sampleCount,\n topStack: top?.frames.join(' <- '),\n topStackBytes: top?.bytes,\n };\n }\n } catch (error) {\n captureError = error instanceof Error ? error.message : String(error);\n }\n }\n\n await fsp.mkdir(this.artifactDir, { recursive: true });\n const stem = `${timestampSlug(new Date(event.capturedAt))}-${event.reason}`;\n await fsp.writeFile(\n path.join(this.artifactDir, `event-${stem}.json`),\n `${JSON.stringify(\n {\n ...event,\n profilerBackend: profile?.backend ?? this.profilerBackend,\n ...(profile?.summary ? { allocationSummary: profile.summary } : {}),\n ...(this.fallbackReason ? { profilerFallbackReason: this.fallbackReason } : {}),\n ...(captureError ? { captureError } : {}),\n },\n null,\n 2,\n )}\\n`,\n 'utf8',\n );\n if (profile) {\n await fsp.writeFile(\n path.join(this.artifactDir, `allocations-${stem}${profile.extension}`),\n profile.data,\n );\n }\n await Promise.all([\n pruneCaptureFiles(this.artifactDir),\n fsp\n .mkdir(this.root, { recursive: true })\n .then(() => pruneOldSessions(this.root, this.artifactDir)),\n ]);\n }\n\n async stop(): Promise<void> {\n if (this.stopped) return;\n this.stopped = true;\n await this.ready;\n await this.profiler?.stop();\n }\n}\n\nfunction disabledWriter(artifactDir: string): MemoryCaptureWriter {\n return {\n artifactDir,\n capture: async () => undefined,\n stop: async () => undefined,\n };\n}\n\nexport function createMemoryFlightRecorder(\n options: MemoryFlightRecorderOptions = {},\n): MemoryFlightRecorder {\n const now = options.now ?? Date.now;\n const startedAt = now();\n const root = options.diagnosticsRoot ?? path.join(wstackGlobalRoot(), 'diagnostics', 'memory');\n const enabled =\n options.enabled ??\n (process.env['WRONGSTACK_MEMORY_FLIGHT_RECORDER'] !== '0' &&\n process.env['NODE_ENV'] !== 'test');\n const writer =\n options.captureWriter ??\n (enabled\n ? new ContinuousMemoryCaptureWriter(root)\n : disabledWriter(path.join(root, `${timestampSlug()}-pid-${process.pid}`)));\n const observations: MemoryFlightObservation[] = [];\n const windowMs = options.windowMs ?? DEFAULT_WINDOW_MS;\n const minimumWindowMs = options.minimumWindowMs ?? DEFAULT_MINIMUM_WINDOW_MS;\n const cooldownMs = options.cooldownMs ?? DEFAULT_COOLDOWN_MS;\n const continuousCaptureMs = options.continuousCaptureMs ?? DEFAULT_CONTINUOUS_CAPTURE_MS;\n const warmupMs = options.warmupMs ?? 60_000;\n let lastSignalCaptureAt = Number.NEGATIVE_INFINITY;\n let lastContinuousCaptureAt = startedAt;\n let captureInFlight = false;\n let capturePromise: Promise<void> | undefined;\n\n const observe = (sample: HeapSample, stats: HeapDiagnosticFields): HeapDiagnosticFields => {\n const at = now();\n const postGcHeapUsed =\n typeof stats['postGcHeapUsed'] === 'number' ? stats['postGcHeapUsed'] : 0;\n const postMajorGcHeapUsed =\n typeof stats['postMajorGcHeapUsed'] === 'number' ? stats['postMajorGcHeapUsed'] : 0;\n const lastGcAgoMs = typeof stats['lastGcAgoMs'] === 'number' ? stats['lastGcAgoMs'] : -1;\n const lastMajorGcAgoMs =\n typeof stats['lastMajorGcAgoMs'] === 'number' ? stats['lastMajorGcAgoMs'] : -1;\n const retainedHeapUsed =\n postMajorGcHeapUsed > 0 && lastMajorGcAgoMs >= 0 && lastMajorGcAgoMs <= windowMs\n ? postMajorGcHeapUsed\n : postGcHeapUsed > 0 && lastGcAgoMs >= 0 && lastGcAgoMs <= minimumWindowMs\n ? postGcHeapUsed\n : sample.heapUsed;\n observations.push({\n at,\n heapUsed: retainedHeapUsed,\n rss: sample.rss,\n nativeResidual: sample.nativeResidual ?? 0,\n });\n while (\n observations.length > MAX_OBSERVATIONS ||\n (observations.length > 1 && at - (observations[0]?.at ?? at) > windowMs)\n ) {\n observations.shift();\n }\n\n const first = observations[0] ?? observations.at(-1);\n const elapsedMs = first ? Math.max(0, at - first.at) : 0;\n const heapGrowthBytes = first ? retainedHeapUsed - first.heapUsed : 0;\n const rssGrowthBytes = first ? sample.rss - first.rss : 0;\n const nativeGrowthBytes = first ? (sample.nativeResidual ?? 0) - first.nativeResidual : 0;\n const heapGrowthBytesPerHour =\n elapsedMs > 0 ? Math.round((heapGrowthBytes / elapsedMs) * HOUR_MS) : 0;\n const rssGrowthBytesPerHour =\n elapsedMs > 0 ? Math.round((rssGrowthBytes / elapsedMs) * HOUR_MS) : 0;\n const nativeGrowthBytesPerHour =\n elapsedMs > 0 ? Math.round((nativeGrowthBytes / elapsedMs) * HOUR_MS) : 0;\n\n let signal = 'stable';\n if ((sample.detachedContexts ?? 0) > 0) signal = 'detached-contexts';\n else if (heapGrowthBytes >= 32 * MB && heapGrowthBytesPerHour > 0) signal = 'js-retention';\n else if (nativeGrowthBytes >= 64 * MB && nativeGrowthBytesPerHour > 0) signal = 'native-rss';\n\n const diagnosis: HeapDiagnosticFields = {\n memorySignal: signal,\n memoryWindowMs: elapsedMs,\n retainedHeapUsed,\n transientHeapBytes: Math.max(0, sample.heapUsed - retainedHeapUsed),\n heapGrowthBytes,\n rssGrowthBytes,\n nativeGrowthBytes,\n heapGrowthBytesPerHour,\n rssGrowthBytesPerHour,\n nativeGrowthBytesPerHour,\n memoryArtifactDir: writer.artifactDir,\n ...(writer.diagnostics?.() ?? {}),\n };\n\n let reason: CaptureReason | undefined;\n if (at - startedAt >= warmupMs) {\n if ((sample.detachedContexts ?? 0) > 0) reason = 'detached-contexts';\n else if (sample.load >= 0.45) reason = 'heap-load';\n else if (sample.heapUsed >= (options.absoluteHeapBytes ?? 768 * MB)) {\n reason = 'absolute-heap';\n } else if (\n elapsedMs >= minimumWindowMs &&\n heapGrowthBytes >= (options.heapGrowthBytes ?? 32 * MB) &&\n heapGrowthBytesPerHour >= (options.heapGrowthBytesPerHour ?? 192 * MB)\n ) {\n reason = 'heap-growth';\n } else if (\n elapsedMs >= minimumWindowMs &&\n nativeGrowthBytes >= (options.nativeGrowthBytes ?? 128 * MB) &&\n nativeGrowthBytesPerHour >= (options.nativeGrowthBytesPerHour ?? 256 * MB)\n ) {\n reason = 'native-rss-growth';\n }\n }\n\n const signalCaptureDue = reason !== undefined && at - lastSignalCaptureAt >= cooldownMs;\n const intervalCaptureDue = at - lastContinuousCaptureAt >= continuousCaptureMs;\n const captureReason = signalCaptureDue ? reason : intervalCaptureDue ? 'interval' : undefined;\n if (enabled && captureReason && !captureInFlight) {\n if (captureReason !== 'interval') lastSignalCaptureAt = at;\n lastContinuousCaptureAt = at;\n captureInFlight = true;\n diagnosis['memoryCaptureReason'] = captureReason;\n capturePromise = writer\n .capture({\n reason: captureReason,\n capturedAt: new Date(at).toISOString(),\n pid: process.pid,\n sample,\n stats,\n diagnosis: { ...diagnosis },\n observations: observations.map((observation) => ({ ...observation })),\n })\n .catch(() => {\n // Diagnostics must never surface as an unhandled runtime rejection.\n })\n .finally(() => {\n captureInFlight = false;\n capturePromise = undefined;\n });\n }\n return diagnosis;\n };\n\n return {\n artifactDir: writer.artifactDir,\n observe,\n stop: async () => {\n await capturePromise;\n await writer.stop();\n },\n };\n}\n", "import { Session } from 'node:inspector/promises';\n\nconst DEFAULT_SAMPLE_INTERVAL_BYTES = 512 * 1024;\nconst DEFAULT_STACK_DEPTH = 64;\nconst MAX_SUMMARY_STACKS = 20;\nconst MAX_FRAMES_PER_STACK = 12;\n\ntype Numeric = number | bigint;\n\ninterface PprofFunction {\n id: Numeric;\n name: Numeric;\n filename: Numeric;\n}\n\ninterface PprofLocation {\n id: Numeric;\n line: Array<{ functionId: Numeric; line: Numeric }>;\n}\n\ninterface PprofProfile {\n function: PprofFunction[];\n location: PprofLocation[];\n sample: Array<{ locationId: Numeric[]; value: Numeric[] }>;\n stringTable: { strings: string[] };\n}\n\nexport interface MemoryAllocationStack {\n bytes: number;\n objects: number;\n frames: string[];\n}\n\nexport interface MemoryAllocationSummary {\n sampledBytes: number;\n sampledObjects: number;\n sampleCount: number;\n topStacks: MemoryAllocationStack[];\n}\n\nexport interface MemoryProfileArtifact {\n backend: 'datadog-pprof' | 'node-inspector';\n data: Buffer | string;\n extension: '.heapprofile' | '.pb.gz';\n summary?: MemoryAllocationSummary | undefined;\n}\n\nexport interface ContinuousMemoryProfiler {\n readonly backend: MemoryProfileArtifact['backend'];\n capture(): Promise<MemoryProfileArtifact>;\n stop(): Promise<void>;\n}\n\nexport interface ContinuousMemoryProfilerStart {\n profiler: ContinuousMemoryProfiler;\n fallbackReason?: string | undefined;\n}\n\ninterface DatadogPprofModule {\n encode(profile: unknown): Promise<Buffer>;\n heap: {\n profile(): PprofProfile;\n start(intervalBytes: number, stackDepth: number): void;\n stop(): void;\n };\n}\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction numeric(value: Numeric | undefined): number {\n if (typeof value === 'bigint') return Number(value);\n return typeof value === 'number' && Number.isFinite(value) ? value : 0;\n}\n\nfunction summarizePprof(profile: PprofProfile): MemoryAllocationSummary {\n const strings = profile.stringTable.strings;\n const functions = new Map(profile.function.map((entry) => [numeric(entry.id), entry]));\n const locations = new Map(profile.location.map((entry) => [numeric(entry.id), entry]));\n const stacks = new Map<string, MemoryAllocationStack>();\n let sampledBytes = 0;\n let sampledObjects = 0;\n\n for (const sample of profile.sample) {\n const objects = numeric(sample.value[0]);\n const bytes = numeric(sample.value[1]);\n sampledObjects += objects;\n sampledBytes += bytes;\n const frames = sample.locationId.slice(0, MAX_FRAMES_PER_STACK).flatMap((locationId) => {\n const location = locations.get(numeric(locationId));\n const line = location?.line[0];\n const fn = line ? functions.get(numeric(line.functionId)) : undefined;\n if (!fn) return [];\n const name = strings[numeric(fn.name)] || '(anonymous)';\n const filename = strings[numeric(fn.filename)] || '';\n const lineNumber = numeric(line?.line);\n return [filename ? `${name} (${filename}${lineNumber > 0 ? `:${lineNumber}` : ''})` : name];\n });\n if (frames.length === 0) frames.push('(unknown)');\n const key = frames.join('\\n');\n const existing = stacks.get(key);\n if (existing) {\n existing.bytes += bytes;\n existing.objects += objects;\n } else {\n stacks.set(key, { bytes, objects, frames });\n }\n }\n\n return {\n sampledBytes,\n sampledObjects,\n sampleCount: profile.sample.length,\n topStacks: [...stacks.values()]\n .sort((left, right) => right.bytes - left.bytes)\n .slice(0, MAX_SUMMARY_STACKS),\n };\n}\n\nasync function startDatadogProfiler(): Promise<ContinuousMemoryProfiler> {\n const pprof = (await import('@datadog/pprof')) as DatadogPprofModule;\n pprof.heap.start(DEFAULT_SAMPLE_INTERVAL_BYTES, DEFAULT_STACK_DEPTH);\n let stopped = false;\n\n return {\n backend: 'datadog-pprof',\n capture: async () => {\n if (stopped) throw new Error('Continuous memory profiler is stopped');\n const profile = pprof.heap.profile();\n return {\n backend: 'datadog-pprof',\n data: await pprof.encode(profile),\n extension: '.pb.gz',\n summary: summarizePprof(profile),\n };\n },\n stop: async () => {\n if (stopped) return;\n stopped = true;\n pprof.heap.stop();\n },\n };\n}\n\nasync function startInspectorProfiler(): Promise<ContinuousMemoryProfiler> {\n const session = new Session();\n session.connect();\n try {\n await session.post('HeapProfiler.enable');\n await session.post('HeapProfiler.startSampling', {\n samplingInterval: DEFAULT_SAMPLE_INTERVAL_BYTES,\n includeObjectsCollectedByMajorGC: false,\n includeObjectsCollectedByMinorGC: false,\n });\n } catch (error) {\n try {\n session.disconnect();\n } catch {\n // The connection may already be torn down after a startup failure.\n }\n throw error;\n }\n\n let stopped = false;\n return {\n backend: 'node-inspector',\n capture: async () => {\n if (stopped) throw new Error('Continuous memory profiler is stopped');\n const result = await session.post('HeapProfiler.stopSampling');\n await session.post('HeapProfiler.startSampling', {\n samplingInterval: DEFAULT_SAMPLE_INTERVAL_BYTES,\n includeObjectsCollectedByMajorGC: false,\n includeObjectsCollectedByMinorGC: false,\n });\n return {\n backend: 'node-inspector',\n data: JSON.stringify(result.profile),\n extension: '.heapprofile',\n };\n },\n stop: async () => {\n if (stopped) return;\n stopped = true;\n try {\n await session.post('HeapProfiler.disable');\n } catch {\n // Profiling is diagnostic-only; shutdown must remain reliable.\n }\n try {\n session.disconnect();\n } catch {\n // Already disconnected.\n }\n },\n };\n}\n\n/**\n * Start allocation sampling inside the current process.\n *\n * The native pprof backend samples continuously without opening an inspector\n * port. The optional dependency may be missing on unsupported platforms, so\n * Node's built-in Inspector sampling remains a functional fallback.\n */\nexport async function startContinuousMemoryProfiler(): Promise<ContinuousMemoryProfilerStart> {\n try {\n return { profiler: await startDatadogProfiler() };\n } catch (error) {\n const fallbackReason = errorMessage(error);\n return {\n profiler: await startInspectorProfiler(),\n fallbackReason,\n };\n }\n}\n"],
5
- "mappings": "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",
6
- "names": ["cached", "fs", "path", "path", "cached", "cached", "isAbsolute", "resolve", "walk", "stat", "cached", "path", "cached", "path", "fs", "path", "path", "resolve", "registry", "isRecord", "registry", "fs", "path", "createHash", "fs", "path", "slugify", "projectHash", "fs", "fsp", "path", "fsp", "path", "stat", "MB"]
7
- }