@wrongstack/core 0.287.0 → 0.291.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (339) hide show
  1. package/dist/agent-status-tracker.d.ts +13 -0
  2. package/dist/agent-status-tracker.d.ts.map +1 -1
  3. package/dist/boot.d.ts.map +1 -1
  4. package/dist/chronicle/context.d.ts +13 -0
  5. package/dist/chronicle/context.d.ts.map +1 -0
  6. package/dist/chronicle/decision-adapter.d.ts +13 -0
  7. package/dist/chronicle/decision-adapter.d.ts.map +1 -0
  8. package/dist/chronicle/domain-adapter.d.ts +13 -0
  9. package/dist/chronicle/domain-adapter.d.ts.map +1 -0
  10. package/dist/chronicle/file-observer.d.ts +20 -0
  11. package/dist/chronicle/file-observer.d.ts.map +1 -0
  12. package/dist/chronicle/health-monitor.d.ts +11 -0
  13. package/dist/chronicle/health-monitor.d.ts.map +1 -0
  14. package/dist/chronicle/identity.d.ts +18 -0
  15. package/dist/chronicle/identity.d.ts.map +1 -0
  16. package/dist/chronicle/index.d.ts +16 -0
  17. package/dist/chronicle/index.d.ts.map +1 -0
  18. package/dist/chronicle/index.js +2555 -0
  19. package/dist/chronicle/index.js.map +7 -0
  20. package/dist/chronicle/journal.d.ts +81 -0
  21. package/dist/chronicle/journal.d.ts.map +1 -0
  22. package/dist/chronicle/process-adapter.d.ts +14 -0
  23. package/dist/chronicle/process-adapter.d.ts.map +1 -0
  24. package/dist/chronicle/prompt-manifest.d.ts +34 -0
  25. package/dist/chronicle/prompt-manifest.d.ts.map +1 -0
  26. package/dist/chronicle/provider-adapter.d.ts +13 -0
  27. package/dist/chronicle/provider-adapter.d.ts.map +1 -0
  28. package/dist/chronicle/query.d.ts +108 -0
  29. package/dist/chronicle/query.d.ts.map +1 -0
  30. package/dist/chronicle/rollup-adapter.d.ts +14 -0
  31. package/dist/chronicle/rollup-adapter.d.ts.map +1 -0
  32. package/dist/chronicle/stream-adapter.d.ts +13 -0
  33. package/dist/chronicle/stream-adapter.d.ts.map +1 -0
  34. package/dist/chronicle/tool-adapter.d.ts +15 -0
  35. package/dist/chronicle/tool-adapter.d.ts.map +1 -0
  36. package/dist/chronicle/types.d.ts +82 -0
  37. package/dist/chronicle/types.d.ts.map +1 -0
  38. package/dist/coordination/agent-monitor.d.ts +40 -0
  39. package/dist/coordination/agent-monitor.d.ts.map +1 -1
  40. package/dist/coordination/agent-subagent-runner.d.ts +7 -1
  41. package/dist/coordination/agent-subagent-runner.d.ts.map +1 -1
  42. package/dist/coordination/agents/phase6-domain.d.ts.map +1 -1
  43. package/dist/coordination/autonomous-coordinator.d.ts +2 -0
  44. package/dist/coordination/autonomous-coordinator.d.ts.map +1 -1
  45. package/dist/coordination/brain-monitor.d.ts +1 -1
  46. package/dist/coordination/brain.d.ts +3 -2
  47. package/dist/coordination/brain.d.ts.map +1 -1
  48. package/dist/coordination/collab-debug.d.ts +0 -9
  49. package/dist/coordination/collab-debug.d.ts.map +1 -1
  50. package/dist/coordination/coordinator/error-classifier.d.ts.map +1 -1
  51. package/dist/coordination/dep-watcher.d.ts +2 -1
  52. package/dist/coordination/dep-watcher.d.ts.map +1 -1
  53. package/dist/coordination/director/director-collab.d.ts +1 -1
  54. package/dist/coordination/director/director-collab.d.ts.map +1 -1
  55. package/dist/coordination/director-tools.d.ts.map +1 -1
  56. package/dist/coordination/director.d.ts +10 -1
  57. package/dist/coordination/director.d.ts.map +1 -1
  58. package/dist/coordination/file-author-tracker.d.ts.map +1 -1
  59. package/dist/coordination/fleet-bus.d.ts.map +1 -1
  60. package/dist/coordination/fleet-event-validation.d.ts +0 -7
  61. package/dist/coordination/fleet-event-validation.d.ts.map +1 -1
  62. package/dist/coordination/fleet-spawn.d.ts.map +1 -1
  63. package/dist/coordination/fleet-supervisor.d.ts +1 -1
  64. package/dist/coordination/fleet-supervisor.d.ts.map +1 -1
  65. package/dist/coordination/fleet.d.ts +0 -44
  66. package/dist/coordination/fleet.d.ts.map +1 -1
  67. package/dist/coordination/global-mailbox.d.ts +7 -1
  68. package/dist/coordination/global-mailbox.d.ts.map +1 -1
  69. package/dist/coordination/index.d.ts +5 -3
  70. package/dist/coordination/index.d.ts.map +1 -1
  71. package/dist/coordination/index.js +2426 -299
  72. package/dist/coordination/index.js.map +4 -4
  73. package/dist/coordination/knowledge-graph.d.ts +2 -1
  74. package/dist/coordination/knowledge-graph.d.ts.map +1 -1
  75. package/dist/coordination/large-answer-store.d.ts +0 -6
  76. package/dist/coordination/large-answer-store.d.ts.map +1 -1
  77. package/dist/coordination/mail-tools.d.ts +2 -2
  78. package/dist/coordination/mail-tools.d.ts.map +1 -1
  79. package/dist/coordination/mailbox-hooks.d.ts +2 -0
  80. package/dist/coordination/mailbox-hooks.d.ts.map +1 -1
  81. package/dist/coordination/mailbox-http-router.d.ts +43 -0
  82. package/dist/coordination/mailbox-http-router.d.ts.map +1 -0
  83. package/dist/coordination/mailbox-message-codec.d.ts +35 -0
  84. package/dist/coordination/mailbox-message-codec.d.ts.map +1 -1
  85. package/dist/coordination/mailbox-tool.d.ts +1 -1
  86. package/dist/coordination/mailbox-tool.d.ts.map +1 -1
  87. package/dist/coordination/mailbox-types.d.ts +170 -10
  88. package/dist/coordination/mailbox-types.d.ts.map +1 -1
  89. package/dist/coordination/mailbox.d.ts +1 -1
  90. package/dist/coordination/mailbox.d.ts.map +1 -1
  91. package/dist/coordination/package-author-tracker.d.ts.map +1 -1
  92. package/dist/coordination/provider-status-tracker.d.ts +236 -0
  93. package/dist/coordination/provider-status-tracker.d.ts.map +1 -0
  94. package/dist/coordination/subagent-budget.d.ts +2 -1
  95. package/dist/coordination/subagent-budget.d.ts.map +1 -1
  96. package/dist/core/agent-loop.d.ts +8 -3
  97. package/dist/core/agent-loop.d.ts.map +1 -1
  98. package/dist/core/agent-response.d.ts +5 -4
  99. package/dist/core/agent-response.d.ts.map +1 -1
  100. package/dist/core/agent-tools.d.ts +1 -1
  101. package/dist/core/agent-tools.d.ts.map +1 -1
  102. package/dist/core/agent.d.ts +4 -2
  103. package/dist/core/agent.d.ts.map +1 -1
  104. package/dist/core/context.d.ts +55 -1
  105. package/dist/core/context.d.ts.map +1 -1
  106. package/dist/core/fallback-model.d.ts +14 -8
  107. package/dist/core/fallback-model.d.ts.map +1 -1
  108. package/dist/core/fallback-profile-manager.d.ts +118 -0
  109. package/dist/core/fallback-profile-manager.d.ts.map +1 -0
  110. package/dist/core/fleet-pulse.d.ts +2 -1
  111. package/dist/core/fleet-pulse.d.ts.map +1 -1
  112. package/dist/core/iteration-limit.d.ts +2 -1
  113. package/dist/core/iteration-limit.d.ts.map +1 -1
  114. package/dist/core/mailbox-loop.d.ts +16 -1
  115. package/dist/core/mailbox-loop.d.ts.map +1 -1
  116. package/dist/core/model-availability-calendar.d.ts +27 -0
  117. package/dist/core/model-availability-calendar.d.ts.map +1 -0
  118. package/dist/core/provider-runner.d.ts.map +1 -1
  119. package/dist/core/system-prompt-builder.d.ts +2 -1
  120. package/dist/core/system-prompt-builder.d.ts.map +1 -1
  121. package/dist/defaults/index.js +1920 -598
  122. package/dist/defaults/index.js.map +4 -4
  123. package/dist/execution/auto-compaction-middleware.d.ts +3 -2
  124. package/dist/execution/auto-compaction-middleware.d.ts.map +1 -1
  125. package/dist/execution/compaction-core.d.ts.map +1 -1
  126. package/dist/execution/council-brain.d.ts +28 -49
  127. package/dist/execution/council-brain.d.ts.map +1 -1
  128. package/dist/execution/council-orchestrator.d.ts +30 -0
  129. package/dist/execution/council-orchestrator.d.ts.map +1 -1
  130. package/dist/execution/enhance-recovery.d.ts +8 -0
  131. package/dist/execution/enhance-recovery.d.ts.map +1 -1
  132. package/dist/execution/error-handler.d.ts +2 -2
  133. package/dist/execution/error-handler.d.ts.map +1 -1
  134. package/dist/execution/eternal-autonomy.d.ts.map +1 -1
  135. package/dist/execution/index.js +2600 -1903
  136. package/dist/execution/index.js.map +4 -4
  137. package/dist/execution/intelligent-compactor.d.ts +0 -16
  138. package/dist/execution/intelligent-compactor.d.ts.map +1 -1
  139. package/dist/execution/model-runtime.d.ts.map +1 -1
  140. package/dist/execution/one-shot-llm.d.ts +9 -1
  141. package/dist/execution/one-shot-llm.d.ts.map +1 -1
  142. package/dist/execution/prompt-enhancer.d.ts +36 -0
  143. package/dist/execution/prompt-enhancer.d.ts.map +1 -1
  144. package/dist/execution/prompt-enhancer.js +158 -10
  145. package/dist/execution/prompt-enhancer.js.map +2 -2
  146. package/dist/execution/retry-policy.d.ts +0 -13
  147. package/dist/execution/retry-policy.d.ts.map +1 -1
  148. package/dist/execution/skill-loader.d.ts.map +1 -1
  149. package/dist/execution/tool-executor.d.ts.map +1 -1
  150. package/dist/goal/checkpoint.d.ts.map +1 -0
  151. package/dist/{autophase/auto-phase-planner.d.ts → goal/goal-planner.d.ts} +8 -8
  152. package/dist/goal/goal-planner.d.ts.map +1 -0
  153. package/dist/{autophase/auto-phase-runner.d.ts → goal/goal-runner.d.ts} +10 -10
  154. package/dist/goal/goal-runner.d.ts.map +1 -0
  155. package/dist/{autophase → goal}/index.d.ts +3 -3
  156. package/dist/goal/index.d.ts.map +1 -0
  157. package/dist/goal/phase-graph-builder.d.ts.map +1 -0
  158. package/dist/{autophase → goal}/phase-orchestrator.d.ts +2 -2
  159. package/dist/goal/phase-orchestrator.d.ts.map +1 -0
  160. package/dist/goal/phase-store.d.ts.map +1 -0
  161. package/dist/{autophase → goal}/types.d.ts +2 -2
  162. package/dist/goal/types.d.ts.map +1 -0
  163. package/dist/hq/auth-store.d.ts.map +1 -1
  164. package/dist/hq/commands.d.ts +2 -1
  165. package/dist/hq/commands.d.ts.map +1 -1
  166. package/dist/hq/exposure.d.ts +66 -0
  167. package/dist/hq/exposure.d.ts.map +1 -0
  168. package/dist/hq/index.d.ts +1 -0
  169. package/dist/hq/index.d.ts.map +1 -1
  170. package/dist/hq/index.js +190 -21
  171. package/dist/hq/index.js.map +4 -4
  172. package/dist/hq/mailbox-mapper.d.ts +13 -1
  173. package/dist/hq/mailbox-mapper.d.ts.map +1 -1
  174. package/dist/hq/protocol/browser.d.ts +9 -1
  175. package/dist/hq/protocol/browser.d.ts.map +1 -1
  176. package/dist/hq/protocol/client.d.ts +2 -2
  177. package/dist/hq/protocol/client.d.ts.map +1 -1
  178. package/dist/hq/protocol/core.d.ts.map +1 -1
  179. package/dist/hq/protocol/mailbox.d.ts +6 -0
  180. package/dist/hq/protocol/mailbox.d.ts.map +1 -1
  181. package/dist/hq/protocol/session.d.ts +4 -0
  182. package/dist/hq/protocol/session.d.ts.map +1 -1
  183. package/dist/hq/publisher.d.ts.map +1 -1
  184. package/dist/index.d.ts +34 -25
  185. package/dist/index.d.ts.map +1 -1
  186. package/dist/index.js +30287 -22214
  187. package/dist/index.js.map +4 -4
  188. package/dist/infrastructure/index.js +60 -5
  189. package/dist/infrastructure/index.js.map +2 -2
  190. package/dist/kernel/events/agent-events.d.ts +33 -1
  191. package/dist/kernel/events/agent-events.d.ts.map +1 -1
  192. package/dist/kernel/events/file-events.d.ts +65 -0
  193. package/dist/kernel/events/file-events.d.ts.map +1 -0
  194. package/dist/kernel/events/memory-events.d.ts +36 -0
  195. package/dist/kernel/events/memory-events.d.ts.map +1 -1
  196. package/dist/kernel/events/network-events.d.ts +60 -0
  197. package/dist/kernel/events/network-events.d.ts.map +1 -0
  198. package/dist/kernel/events/process-events.d.ts +44 -0
  199. package/dist/kernel/events/process-events.d.ts.map +1 -0
  200. package/dist/kernel/events/provider-events.d.ts +89 -0
  201. package/dist/kernel/events/provider-events.d.ts.map +1 -1
  202. package/dist/kernel/events/tool-events.d.ts +10 -0
  203. package/dist/kernel/events/tool-events.d.ts.map +1 -1
  204. package/dist/kernel/events/worktree-events.d.ts +1 -1
  205. package/dist/kernel/events.d.ts +14 -1
  206. package/dist/kernel/events.d.ts.map +1 -1
  207. package/dist/kernel/index.js +2 -1
  208. package/dist/kernel/index.js.map +2 -2
  209. package/dist/kernel/tokens.d.ts +3 -1
  210. package/dist/kernel/tokens.d.ts.map +1 -1
  211. package/dist/mailbox-attach.d.ts.map +1 -1
  212. package/dist/models/index.js.map +2 -2
  213. package/dist/observability/index.d.ts +3 -0
  214. package/dist/observability/index.d.ts.map +1 -1
  215. package/dist/observability/index.js +278 -0
  216. package/dist/observability/index.js.map +4 -4
  217. package/dist/observability/network-telemetry.d.ts +15 -0
  218. package/dist/observability/network-telemetry.d.ts.map +1 -0
  219. package/dist/observability/process-telemetry.d.ts +18 -0
  220. package/dist/observability/process-telemetry.d.ts.map +1 -0
  221. package/dist/observability/redact-command.d.ts +20 -0
  222. package/dist/observability/redact-command.d.ts.map +1 -0
  223. package/dist/plugins/auto-review-plugin.d.ts +56 -3
  224. package/dist/plugins/auto-review-plugin.d.ts.map +1 -1
  225. package/dist/plugins/chimera-plugin.d.ts +164 -5
  226. package/dist/plugins/chimera-plugin.d.ts.map +1 -1
  227. package/dist/plugins/review-context-builder.d.ts +52 -0
  228. package/dist/plugins/review-context-builder.d.ts.map +1 -0
  229. package/dist/security/index.d.ts +1 -0
  230. package/dist/security/index.d.ts.map +1 -1
  231. package/dist/security/index.js +186 -9
  232. package/dist/security/index.js.map +4 -4
  233. package/dist/security/kanban-boundary.d.ts +10 -0
  234. package/dist/security/kanban-boundary.d.ts.map +1 -0
  235. package/dist/security/permission-policy.d.ts +1 -0
  236. package/dist/security/permission-policy.d.ts.map +1 -1
  237. package/dist/session-registry.d.ts +80 -0
  238. package/dist/session-registry.d.ts.map +1 -1
  239. package/dist/skills/index.js.map +2 -2
  240. package/dist/storage/config-loader.d.ts +7 -0
  241. package/dist/storage/config-loader.d.ts.map +1 -1
  242. package/dist/storage/file-session-writer.d.ts +20 -7
  243. package/dist/storage/file-session-writer.d.ts.map +1 -1
  244. package/dist/storage/goal-coordination.d.ts +40 -0
  245. package/dist/storage/goal-coordination.d.ts.map +1 -0
  246. package/dist/storage/goal-store.d.ts +9 -5
  247. package/dist/storage/goal-store.d.ts.map +1 -1
  248. package/dist/storage/index.d.ts +4 -2
  249. package/dist/storage/index.d.ts.map +1 -1
  250. package/dist/storage/index.js +1066 -226
  251. package/dist/storage/index.js.map +4 -4
  252. package/dist/storage/memory-consolidator.d.ts +49 -4
  253. package/dist/storage/memory-consolidator.d.ts.map +1 -1
  254. package/dist/storage/memory-graph-backend.d.ts +11 -0
  255. package/dist/storage/memory-graph-backend.d.ts.map +1 -1
  256. package/dist/storage/provider-config-watcher.d.ts +19 -0
  257. package/dist/storage/provider-config-watcher.d.ts.map +1 -1
  258. package/dist/storage/session-event-bridge.d.ts +2 -2
  259. package/dist/storage/session-event-bridge.d.ts.map +1 -1
  260. package/dist/storage/session-resume-validation.d.ts +10 -0
  261. package/dist/storage/session-resume-validation.d.ts.map +1 -1
  262. package/dist/storage/session-rewind-apply.d.ts +53 -0
  263. package/dist/storage/session-rewind-apply.d.ts.map +1 -0
  264. package/dist/storage/session-rewinder.d.ts.map +1 -1
  265. package/dist/storage/session-store.d.ts.map +1 -1
  266. package/dist/tasking/index.js.map +1 -1
  267. package/dist/tasking/task-store.d.ts +1 -1
  268. package/dist/tools/council-tool.d.ts +3 -0
  269. package/dist/tools/council-tool.d.ts.map +1 -1
  270. package/dist/tools/fallback-manage-tools.d.ts +82 -0
  271. package/dist/tools/fallback-manage-tools.d.ts.map +1 -0
  272. package/dist/tools/index.d.ts +1 -0
  273. package/dist/tools/index.d.ts.map +1 -1
  274. package/dist/tools/index.js +3423 -192
  275. package/dist/tools/index.js.map +4 -4
  276. package/dist/tools/one-shot-llm-tool.d.ts +2 -0
  277. package/dist/tools/one-shot-llm-tool.d.ts.map +1 -1
  278. package/dist/types/config.d.ts +76 -7
  279. package/dist/types/config.d.ts.map +1 -1
  280. package/dist/types/file-event-record.d.ts +68 -0
  281. package/dist/types/file-event-record.d.ts.map +1 -0
  282. package/dist/types/index.d.ts +1 -0
  283. package/dist/types/index.d.ts.map +1 -1
  284. package/dist/types/index.js +13 -8
  285. package/dist/types/index.js.map +3 -3
  286. package/dist/types/memory.d.ts +12 -0
  287. package/dist/types/memory.d.ts.map +1 -1
  288. package/dist/types/multi-agent.d.ts +12 -1
  289. package/dist/types/multi-agent.d.ts.map +1 -1
  290. package/dist/types/one-shot-llm.d.ts +16 -7
  291. package/dist/types/one-shot-llm.d.ts.map +1 -1
  292. package/dist/types/provider.d.ts +1 -1
  293. package/dist/types/provider.d.ts.map +1 -1
  294. package/dist/types/session.d.ts +68 -2
  295. package/dist/types/session.d.ts.map +1 -1
  296. package/dist/types/tool-executor.d.ts +2 -0
  297. package/dist/types/tool-executor.d.ts.map +1 -1
  298. package/dist/types/tool.d.ts +5 -0
  299. package/dist/types/tool.d.ts.map +1 -1
  300. package/dist/utils/atomic-write.d.ts.map +1 -1
  301. package/dist/utils/index.d.ts +10 -10
  302. package/dist/utils/index.d.ts.map +1 -1
  303. package/dist/utils/index.js +497 -254
  304. package/dist/utils/index.js.map +4 -4
  305. package/dist/utils/message-invariants.d.ts +9 -0
  306. package/dist/utils/message-invariants.d.ts.map +1 -1
  307. package/dist/utils/safe-json.d.ts +1 -1
  308. package/dist/utils/safe-json.d.ts.map +1 -1
  309. package/dist/utils/term.d.ts +279 -0
  310. package/dist/utils/term.d.ts.map +1 -1
  311. package/dist/utils/tool-wire-compact.d.ts +9 -0
  312. package/dist/utils/tool-wire-compact.d.ts.map +1 -1
  313. package/dist/utils/wstack-paths.d.ts +12 -2
  314. package/dist/utils/wstack-paths.d.ts.map +1 -1
  315. package/dist/worktree/worktree-manager.d.ts +1 -1
  316. package/dist/worktree/worktree-manager.d.ts.map +1 -1
  317. package/instructions/agents/ios.md +113 -0
  318. package/instructions/agents/search.md +1 -1
  319. package/instructions/llm/chimera-review.md +66 -9
  320. package/instructions/llm/memory-consolidator.md +4 -12
  321. package/instructions/llm/prompt-enhancer.md +3 -1
  322. package/instructions/sections/tool/common-patterns.md +3 -3
  323. package/instructions/system.md +40 -5
  324. package/package.json +7 -3
  325. package/skills/auto-review/SKILL.md +176 -0
  326. package/skills/mnemosyne/SKILL.md +156 -0
  327. package/skills/mnemosyne/instructions/agent-prompt.md +200 -0
  328. package/dist/autophase/auto-phase-planner.d.ts.map +0 -1
  329. package/dist/autophase/auto-phase-runner.d.ts.map +0 -1
  330. package/dist/autophase/checkpoint.d.ts.map +0 -1
  331. package/dist/autophase/index.d.ts.map +0 -1
  332. package/dist/autophase/phase-graph-builder.d.ts.map +0 -1
  333. package/dist/autophase/phase-orchestrator.d.ts.map +0 -1
  334. package/dist/autophase/phase-store.d.ts.map +0 -1
  335. package/dist/autophase/types.d.ts.map +0 -1
  336. /package/dist/{autophase → goal}/checkpoint.d.ts +0 -0
  337. /package/dist/{autophase → goal}/phase-graph-builder.d.ts +0 -0
  338. /package/dist/{autophase → goal}/phase-store.d.ts +0 -0
  339. /package/instructions/{autophase → goal}/phase-planner.md +0 -0
@@ -167,7 +167,7 @@ async function withFileLock(targetPath, fn, opts = {}) {
167
167
  const dir = path.dirname(targetPath);
168
168
  await fs.mkdir(dir, { recursive: true });
169
169
  const lockPath = path.join(dir, `.${path.basename(targetPath)}.lock`);
170
- const timeoutMs = opts.timeoutMs ?? 5e3;
170
+ const timeoutMs = opts.timeoutMs ?? 15e3;
171
171
  const staleMs = opts.staleMs ?? 3e4;
172
172
  const started = Date.now();
173
173
  let handle;
@@ -177,6 +177,13 @@ async function withFileLock(targetPath, fn, opts = {}) {
177
177
  await handle.writeFile(`${process.pid}:${Date.now()}`);
178
178
  break;
179
179
  } catch (err) {
180
+ if (handle) {
181
+ await handle.close().catch(() => {
182
+ });
183
+ await fs.unlink(lockPath).catch(() => {
184
+ });
185
+ handle = void 0;
186
+ }
180
187
  const code = err.code;
181
188
  if (code === "ENOENT") {
182
189
  await fs.mkdir(dir, { recursive: true });
@@ -426,64 +433,222 @@ function buildChildEnv(optsOrSessionId) {
426
433
 
427
434
  // src/utils/term.ts
428
435
  var hasStdout = () => typeof process !== "undefined" && !!process.stdout;
429
- var hasStdin = () => typeof process !== "undefined" && !!process.stdin;
430
436
  function isStdoutTTY() {
431
437
  return hasStdout() && Boolean(process.stdout.isTTY);
432
438
  }
433
- function isStdinTTY() {
434
- return hasStdin() && Boolean(process.stdin.isTTY);
435
- }
436
- function isInteractive() {
437
- return isStdinTTY() && isStdoutTTY();
438
- }
439
- function getTermSize() {
440
- if (!hasStdout()) return { rows: 24, cols: 80 };
439
+ function parseColorDepth(env) {
440
+ if (env.FORCE_COLOR === "0") return 0;
441
+ if (env.FORCE_COLOR !== void 0) return 3;
442
+ if (typeof env.NO_COLOR === "string" && env.NO_COLOR !== "") return 0;
443
+ const colorterm = (env.COLORTERM ?? "").toLowerCase();
444
+ if (colorterm === "truecolor" || colorterm === "24bit") return 3;
445
+ const term = (env.TERM ?? "").toLowerCase();
446
+ if (term.includes("truecolor") || term.includes("24bit")) return 3;
447
+ if (term.includes("256color")) return 2;
448
+ if (term === "dumb") return 0;
449
+ return 1;
450
+ }
451
+ function parseMouseProtocol(term) {
452
+ const t = term.toLowerCase();
453
+ if (t.startsWith("xterm") || t.startsWith("tmux") || t.startsWith("screen") || t.includes("rxvt-unicode") || t.includes("urxvt") || t.includes("konsole") || t.includes("gnome") || t.includes("foot") || t.includes("alacritty") || t.includes("wezterm") || t.includes("kitty") || t.includes("vscode") || t.includes("Apple_Terminal")) {
454
+ return "sgr";
455
+ }
456
+ if (t.startsWith("rxvt") || t.startsWith("linux") || t.includes("Eterm")) {
457
+ return "urxvt";
458
+ }
459
+ if (t === "vt100" || t === "dumb") return "none";
460
+ return "sgr";
461
+ }
462
+ function detectTerminal(opts = {}) {
463
+ const stdin = opts.stdin ?? process.stdin;
464
+ const stdout = opts.stdout ?? process.stdout;
465
+ const env = opts.env ?? process.env;
466
+ const isRealTTY = (stdin?.isTTY ?? false) && (stdout?.isTTY ?? false);
467
+ const stdoutWritable = isRealTTY && typeof stdout?.write === "function";
468
+ const term = env.TERM ?? "";
469
+ const isTmux = term.toLowerCase().startsWith("tmux");
470
+ const isWindowsConhost = isRealTTY && process.platform === "win32" && typeof stdout.getColorDepth !== "function";
441
471
  return {
442
- rows: process.stdout.rows ?? 24,
443
- cols: process.stdout.columns ?? 80
472
+ isRealTTY,
473
+ colorDepth: isRealTTY ? parseColorDepth(env) : 0,
474
+ stdoutWritable,
475
+ mouseProtocol: parseMouseProtocol(term),
476
+ canSetTitle: isRealTTY && term !== "dumb",
477
+ isTmux,
478
+ isWindowsConhost
444
479
  };
445
480
  }
446
- function onResize(cb, stream = process.stdout) {
447
- if (!stream || typeof stream.on !== "function") return () => {
448
- };
449
- const handler = () => {
450
- cb({
451
- rows: stream.rows ?? 24,
452
- cols: stream.columns ?? 80
453
- });
454
- };
455
- stream.on("resize", handler);
456
- return () => {
457
- stream.off("resize", handler);
458
- };
459
- }
460
- function setRawMode(input, mode) {
461
- if (input?.isTTY !== true) return false;
462
- if (typeof input.setRawMode !== "function") return false;
463
- input.setRawMode(mode);
464
- return true;
465
- }
466
- var activeOutputGuard = null;
467
- function setOutputLineGuard(guard) {
468
- activeOutputGuard = guard;
469
- }
470
- function writeTo(s, stream) {
471
- if (!stream || typeof stream.write !== "function") return false;
472
- const guard = activeOutputGuard;
473
- if (!guard) {
474
- stream.write(s);
481
+ var TerminalLifecycle = class {
482
+ _active = false;
483
+ /**
484
+ * The stdin stream we took raw mode on. Set by `acquire()`; undefined before
485
+ * first call. Used by `release()` and by the ConPTY race-closer in
486
+ * `acquire()`.
487
+ */
488
+ _stdin;
489
+ /**
490
+ * The `isRaw` snapshot captured before the first `acquire()` call, so
491
+ * `release()` restores to the pre-TUI state rather than blindly disabling
492
+ * raw mode. Null when `acquire()` has never been called.
493
+ */
494
+ _wasRaw = null;
495
+ /**
496
+ * Request the process to exit. Set the flag, trigger any registered
497
+ * `onRequestExit` callback (typically Ink's `unmount()`), and arm a
498
+ * deadline timer. When the timer fires the process is hard-exited.
499
+ *
500
+ * Safe to call multiple times: subsequent calls no-op after the first.
501
+ */
502
+ requestExit;
503
+ /**
504
+ * Callback invoked when `requestExit` is called. Registered by the Ink
505
+ * mount point so unmount() runs before the deadline timer fires.
506
+ */
507
+ onRequestExit = null;
508
+ constructor() {
509
+ let exitCode = 0;
510
+ let requested = false;
511
+ this.requestExit = (code = 0) => {
512
+ exitCode = code;
513
+ if (requested) return;
514
+ requested = true;
515
+ try {
516
+ this.onRequestExit?.();
517
+ } catch {
518
+ }
519
+ setTimeout(() => process.exit(exitCode), 5e3).unref();
520
+ };
521
+ }
522
+ /** True while raw mode is held. */
523
+ get active() {
524
+ return this._active;
525
+ }
526
+ /**
527
+ * Acquire raw mode on `stdin`. Idempotent — calling twice is safe; only the
528
+ * first call has any effect.
529
+ *
530
+ * On Windows ConPTY, calls `setRawMode` twice: once immediately, then again
531
+ * after the next event-loop tick. This closes the ConPTY race where
532
+ * `readline`'s cleanup (registered before this class is constructed) can
533
+ * restore the original cooked mode after we set raw mode but before Ink's
534
+ * render loop takes over the stdin fd. The double-call ensures the last
535
+ * writer wins.
536
+ *
537
+ * @param stdin - The stdin stream (defaults to `process.stdin`).
538
+ * @returns `true` if raw mode was acquired; `false` if stdin is not a TTY
539
+ * or already shut down.
540
+ */
541
+ acquire(stdin = process.stdin) {
542
+ if (this._active) return false;
543
+ if (stdin?.isTTY !== true) return false;
544
+ if (typeof stdin.setRawMode !== "function") return false;
545
+ this._wasRaw = stdin.isRaw ?? false;
546
+ this._stdin = stdin;
547
+ stdin.setRawMode(true);
548
+ this._active = true;
549
+ if (process.platform === "win32") {
550
+ setImmediate(() => {
551
+ if (this._active && this._stdin?.isTTY) {
552
+ this._stdin.setRawMode?.(true);
553
+ }
554
+ });
555
+ }
475
556
  return true;
476
557
  }
477
- guard.suspend();
478
- stream.write(s);
479
- guard.resume();
480
- return true;
558
+ /**
559
+ * Release raw mode and restore the terminal to the state it was in before
560
+ * `acquire()` was called. Idempotent — subsequent calls are no-ops.
561
+ *
562
+ * Call this on: SIGINT, SIGTERM, SIGHUP, SIGBREAK, and `process.exit`.
563
+ *
564
+ * ⚠ **Windows caveat**: `setRawMode(false)` on ConPTY restores the original
565
+ * console mode captured when the process started — not the mode captured by
566
+ * `acquire()`. On ConPTY, the original mode was already raw (ConPTY starts
567
+ * raw), so this call is typically a no-op on Windows Terminal. On conhost.exe
568
+ * it may restore cooked mode, which is correct for that backend.
569
+ */
570
+ release() {
571
+ if (!this._active) return;
572
+ this._active = false;
573
+ const stdin = this._stdin;
574
+ if (stdin?.isTTY === true) {
575
+ stdin.setRawMode?.(this._wasRaw ?? false);
576
+ }
577
+ this._stdin = void 0;
578
+ this._wasRaw = null;
579
+ }
580
+ /**
581
+ * Synchronously reset all terminal state written by the TUI layer:
582
+ * raw mode, SGR attributes, cursor visibility, and mouse tracking.
583
+ *
584
+ * Intended for the final `process.on('exit')` handler where async is
585
+ * impossible. Uses `\x1b[0m` (SGR reset), `\x1b[?25h` (cursor show),
586
+ * and `\x1b[?9l` (mouse off) — all safe to emit even if the terminal does
587
+ * not understand them (unknown CSI sequences are silently ignored).
588
+ *
589
+ * Safe to call multiple times from multiple exit paths because each write
590
+ * is a constant-time synchronous stream write.
591
+ *
592
+ * @param stdout - Stream to reset (defaults to `process.stdout`).
593
+ */
594
+ reset(stdout = process.stdout) {
595
+ if (typeof stdout?.write !== "function") return;
596
+ stdout.write("\x1B[0m");
597
+ stdout.write("\x1B[?25h");
598
+ stdout.write("\x1B[?1003l\x1B[?1002l\x1B[?1000l");
599
+ }
600
+ };
601
+ var ESCAPE_TERMINATOR = Object.freeze({
602
+ BEL: "\x07",
603
+ // OSC 0 / OSC 2 (title)
604
+ ST: "\x1B\\"
605
+ // DCS / strict OSC
606
+ });
607
+ function safeEmit(sequence, stdout = process.stdout) {
608
+ const raw = typeof sequence === "string" ? sequence : sequence.raw;
609
+ const term = typeof sequence === "string" ? void 0 : sequence.terminator;
610
+ if (!raw) {
611
+ return { ok: false, reason: "empty" };
612
+ }
613
+ if (stdout?.isTTY !== true) {
614
+ return { ok: false, reason: "not_a_tty" };
615
+ }
616
+ if (raw.startsWith("\x1B]") || raw.startsWith("\x1BP")) {
617
+ if (!term) {
618
+ void term;
619
+ const safe = `${raw}\x07`;
620
+ try {
621
+ stdout.write(safe);
622
+ } catch {
623
+ return { ok: false, reason: "unwritable" };
624
+ }
625
+ return { ok: true, reason: "empty" };
626
+ }
627
+ try {
628
+ stdout.write(`${raw}${term}`);
629
+ } catch {
630
+ return { ok: false, reason: "unwritable" };
631
+ }
632
+ return { ok: true, reason: "empty" };
633
+ }
634
+ try {
635
+ stdout.write(raw);
636
+ } catch {
637
+ return { ok: false, reason: "unwritable" };
638
+ }
639
+ return { ok: true, reason: "empty" };
481
640
  }
482
- function writeOut(s, stream = process.stdout) {
483
- return writeTo(s, stream);
641
+ function buildTitleSequence(title, terminator = ESCAPE_TERMINATOR.BEL) {
642
+ return {
643
+ raw: `\x1B]0;${title.replace(/\x07/g, "")}`,
644
+ terminator
645
+ };
484
646
  }
485
- function writeErr(s, stream = process.stderr) {
486
- return writeTo(s, stream);
647
+ function buildSgrSequence(...codes) {
648
+ return { raw: `\x1B[${codes.join(";")}m` };
649
+ }
650
+ function setTitle(title, stdout = process.stdout) {
651
+ return safeEmit(buildTitleSequence(title), stdout).ok;
487
652
  }
488
653
 
489
654
  // src/utils/color.ts
@@ -1953,6 +2118,16 @@ function stripUndefined(obj) {
1953
2118
  }
1954
2119
 
1955
2120
  // src/utils/message-invariants.ts
2121
+ function hasMeaningfulContent(content) {
2122
+ if (typeof content === "string") return content.trim().length > 0;
2123
+ return content.some((block) => {
2124
+ if (block.type === "text") return block.text.trim().length > 0;
2125
+ if (block.type === "thinking") {
2126
+ return block.thinking.trim().length > 0 || Boolean(block.signature);
2127
+ }
2128
+ return true;
2129
+ });
2130
+ }
1956
2131
  function repairToolUseAdjacency(messages) {
1957
2132
  const removedToolUses = [];
1958
2133
  const removedToolResults = [];
@@ -2040,8 +2215,7 @@ function mapContent(msg, fn) {
2040
2215
  return { ...msg, content: next };
2041
2216
  }
2042
2217
  function isEmptyMessage(msg) {
2043
- if (typeof msg.content === "string") return msg.content.trim().length === 0;
2044
- return msg.content.length === 0;
2218
+ return !hasMeaningfulContent(msg.content);
2045
2219
  }
2046
2220
 
2047
2221
  // src/utils/newline-normalize.ts
@@ -2114,7 +2288,7 @@ function compileUserRegex(pattern, flags) {
2114
2288
 
2115
2289
  // src/utils/safe-json.ts
2116
2290
  function safeParse(input, maxBytes = 5e6) {
2117
- if (input.length > maxBytes) {
2291
+ if (Buffer.byteLength(input, "utf8") > maxBytes) {
2118
2292
  return { ok: false, error: `Input exceeds limit (${maxBytes} bytes)` };
2119
2293
  }
2120
2294
  try {
@@ -2149,7 +2323,7 @@ function safeStringify(value, pretty = false) {
2149
2323
  }
2150
2324
  function sanitizeJsonString(s) {
2151
2325
  let out = s.trim();
2152
- out = stripSingleLineComments(out);
2326
+ out = stripJsonComments(out);
2153
2327
  out = out.replace(/,(\s*[}\]])/g, "$1");
2154
2328
  out = escapeControlCharsInStrings(out);
2155
2329
  try {
@@ -2207,20 +2381,45 @@ function escapeControlCharsInStrings(s) {
2207
2381
  }
2208
2382
  return out;
2209
2383
  }
2210
- function stripSingleLineComments(s) {
2384
+ function stripJsonComments(s) {
2211
2385
  let inString = false;
2386
+ let escaped = false;
2212
2387
  const chars = [];
2213
2388
  let i = 0;
2214
2389
  while (i < s.length) {
2215
2390
  const c = s.charAt(i);
2216
- if (c === '"' && (i === 0 || s.charAt(i - 1) !== "\\")) {
2217
- inString = !inString;
2391
+ if (inString) {
2218
2392
  chars.push(c);
2219
- } else if (c === "/" && s.charAt(i + 1) === "/" && !inString) {
2220
- while (i < s.length && s.charAt(i) !== "\n") i++;
2221
- } else {
2393
+ if (escaped) {
2394
+ escaped = false;
2395
+ } else if (c === "\\") {
2396
+ escaped = true;
2397
+ } else if (c === '"') {
2398
+ inString = false;
2399
+ }
2400
+ i++;
2401
+ continue;
2402
+ }
2403
+ if (c === '"') {
2404
+ inString = true;
2222
2405
  chars.push(c);
2406
+ i++;
2407
+ continue;
2408
+ }
2409
+ if (c === "/" && s.charAt(i + 1) === "/") {
2410
+ while (i < s.length && s.charAt(i) !== "\n") i++;
2411
+ continue;
2412
+ }
2413
+ if (c === "/" && s.charAt(i + 1) === "*") {
2414
+ const end = s.indexOf("*/", i + 2);
2415
+ if (end === -1) {
2416
+ chars.push(s.slice(i));
2417
+ break;
2418
+ }
2419
+ i = end + 2;
2420
+ continue;
2223
2421
  }
2422
+ chars.push(c);
2224
2423
  i++;
2225
2424
  }
2226
2425
  return chars.join("");
@@ -2248,51 +2447,16 @@ function invalid(sessionId) {
2248
2447
  });
2249
2448
  }
2250
2449
 
2251
- // src/utils/slug.ts
2252
- function slugify(name, fallback = "prompt", maxLen = 64) {
2253
- return name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, maxLen).replace(/-+$/g, "") || fallback;
2254
- }
2255
-
2256
- // src/utils/ulid.ts
2257
- import { randomBytes as randomBytes2 } from "node:crypto";
2258
- var ENCODING = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
2259
- var ENCODING_LEN = ENCODING.length;
2260
- var TIME_LEN = 10;
2261
- var RANDOM_LEN = 16;
2262
- function encodeTime(now, len) {
2263
- let mod;
2264
- let str = "";
2265
- for (let i = len - 1; i >= 0; i--) {
2266
- mod = now % ENCODING_LEN;
2267
- str = ENCODING[mod] + str;
2268
- now = (now - mod) / ENCODING_LEN;
2269
- }
2270
- return str;
2271
- }
2272
- function encodeRandom(len) {
2273
- const bytes = randomBytes2(len);
2274
- let str = "";
2275
- for (let i = 0; i < len; i++) {
2276
- str += ENCODING[bytes[i] % ENCODING_LEN];
2277
- }
2278
- return str;
2279
- }
2280
- function ulid(seedTime = Date.now()) {
2281
- return encodeTime(seedTime, TIME_LEN) + encodeRandom(RANDOM_LEN);
2282
- }
2283
- function isUlid(value) {
2284
- if (value.length !== TIME_LEN + RANDOM_LEN) return false;
2285
- for (const ch of value) {
2286
- if (!ENCODING.includes(ch)) return false;
2287
- }
2288
- return true;
2289
- }
2290
-
2291
2450
  // src/utils/sleep.ts
2292
2451
  function sleep(ms) {
2293
2452
  return new Promise((resolve5) => setTimeout(resolve5, ms));
2294
2453
  }
2295
2454
 
2455
+ // src/utils/slug.ts
2456
+ function slugify(name, fallback = "prompt", maxLen = 64) {
2457
+ return name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, maxLen).replace(/-+$/g, "") || fallback;
2458
+ }
2459
+
2296
2460
  // src/utils/string.ts
2297
2461
  function truncate(s, max) {
2298
2462
  return s.length <= max ? s : `${s.slice(0, max - 1)}\u2026`;
@@ -2426,41 +2590,6 @@ function hasOpenTodos(todos) {
2426
2590
  return todos.some((t) => t.status === "pending" || t.status === "in_progress");
2427
2591
  }
2428
2592
 
2429
- // src/utils/tool-subject.ts
2430
- var GLOB_METACHARACTERS = /[*?[\]]/g;
2431
- function escapeGlobSubject(value) {
2432
- return value.replace(GLOB_METACHARACTERS, (char) => `\\${char}`);
2433
- }
2434
- function normalizePathSubject(value) {
2435
- return escapeGlobSubject(value.replace(/\\/g, "/"));
2436
- }
2437
- function isPathSubjectKey(subjectKey) {
2438
- return subjectKey === "path" || subjectKey === "file" || subjectKey === "files";
2439
- }
2440
- function subjectForToolInput(toolName, input, subjectKey) {
2441
- if (!input || typeof input !== "object") return void 0;
2442
- const obj = input;
2443
- if (subjectKey) {
2444
- const value = obj[subjectKey];
2445
- if (typeof value === "string") {
2446
- return isPathSubjectKey(subjectKey) ? normalizePathSubject(value) : escapeGlobSubject(value);
2447
- }
2448
- }
2449
- if (toolName === "bash" && typeof obj.command === "string") {
2450
- return escapeGlobSubject(obj.command);
2451
- }
2452
- if (typeof obj.path === "string") {
2453
- return normalizePathSubject(obj.path);
2454
- }
2455
- if (typeof obj.url === "string") {
2456
- return escapeGlobSubject(obj.url);
2457
- }
2458
- if (typeof obj.name === "string") {
2459
- return escapeGlobSubject(obj.name);
2460
- }
2461
- return void 0;
2462
- }
2463
-
2464
2593
  // src/utils/tool-wire-compact.ts
2465
2594
  var TOOL_DESCRIPTION_MAX_CHARS = 400;
2466
2595
  var SCHEMA_DESCRIPTION_MAX_CHARS = 120;
@@ -2477,9 +2606,11 @@ function compactToolDefinitionForWire(tool, opts = {}) {
2477
2606
  tool.description ?? "",
2478
2607
  opts.descriptionMaxChars ?? TOOL_DESCRIPTION_MAX_CHARS
2479
2608
  ),
2480
- inputSchema: compactSchemaDescriptions(
2481
- tool.inputSchema,
2482
- opts.schemaDescriptionMaxChars ?? SCHEMA_DESCRIPTION_MAX_CHARS
2609
+ inputSchema: normalizeTopLevelToolSchema(
2610
+ compactSchemaDescriptions(
2611
+ tool.inputSchema,
2612
+ opts.schemaDescriptionMaxChars ?? SCHEMA_DESCRIPTION_MAX_CHARS
2613
+ )
2483
2614
  )
2484
2615
  };
2485
2616
  if (useDefaultOptions && typeof tool === "object" && tool !== null) {
@@ -2487,6 +2618,44 @@ function compactToolDefinitionForWire(tool, opts = {}) {
2487
2618
  }
2488
2619
  return compact;
2489
2620
  }
2621
+ function normalizeTopLevelToolSchema(schema) {
2622
+ const combinators = ["oneOf", "anyOf", "allOf"].map((keyword) => ({ keyword, branches: schema[keyword] })).filter(
2623
+ (entry) => Array.isArray(entry.branches)
2624
+ );
2625
+ if (combinators.length === 0) return schema;
2626
+ const out = { ...schema, type: "object" };
2627
+ delete out["oneOf"];
2628
+ delete out["anyOf"];
2629
+ delete out["allOf"];
2630
+ const properties = isRecord(schema["properties"]) ? { ...schema["properties"] } : {};
2631
+ let required = stringSet(schema["required"]);
2632
+ for (const { keyword, branches } of combinators) {
2633
+ const objectBranches = branches.filter(isRecord);
2634
+ for (const branch of objectBranches) {
2635
+ if (isRecord(branch["properties"])) Object.assign(properties, branch["properties"]);
2636
+ }
2637
+ const branchRequired = objectBranches.map((branch) => stringSet(branch["required"]));
2638
+ if (keyword === "allOf") {
2639
+ for (const fields of branchRequired) for (const field of fields) required.add(field);
2640
+ } else if (branchRequired.length > 0) {
2641
+ const common = new Set(
2642
+ [...branchRequired[0]].filter(
2643
+ (field) => branchRequired.slice(1).every((fields) => fields.has(field))
2644
+ )
2645
+ );
2646
+ required = /* @__PURE__ */ new Set([...required, ...common]);
2647
+ }
2648
+ }
2649
+ out["properties"] = properties;
2650
+ if (required.size > 0) out["required"] = [...required];
2651
+ else delete out["required"];
2652
+ return out;
2653
+ }
2654
+ function stringSet(value) {
2655
+ return new Set(
2656
+ Array.isArray(value) ? value.filter((item) => typeof item === "string") : []
2657
+ );
2658
+ }
2490
2659
  function compactSchemaDescriptions(schema, maxDescriptionChars = SCHEMA_DESCRIPTION_MAX_CHARS) {
2491
2660
  const compact = compactSchemaNode(schema, maxDescriptionChars);
2492
2661
  return isRecord(compact) ? compact : { type: "object", properties: {} };
@@ -2727,6 +2896,114 @@ function resetCalibration(calibrationKey) {
2727
2896
  _cals.delete(calibrationKey);
2728
2897
  }
2729
2898
 
2899
+ // src/utils/tool-description-mode.ts
2900
+ var DEFAULT_TOOL_DESCRIPTION_MODE = "extend";
2901
+ var ORIGINAL_TOOL_DESCRIPTION = /* @__PURE__ */ Symbol.for("wrongstack.tool.originalDescription");
2902
+ function normalizeToolDescriptionMode(value) {
2903
+ if (typeof value !== "string") return void 0;
2904
+ const raw = value.trim().toLowerCase();
2905
+ if (raw === "extend" || raw === "extended" || raw === "full") return "extend";
2906
+ if (raw === "simple" || raw === "short" || raw === "brief") return "simple";
2907
+ return void 0;
2908
+ }
2909
+ function resolveToolDescriptionMode(modes, toolName) {
2910
+ return normalizeToolDescriptionMode(modes?.[toolName]) ?? DEFAULT_TOOL_DESCRIPTION_MODE;
2911
+ }
2912
+ function simplifyToolDescription(text, opts = {}) {
2913
+ const maxSentences = Math.max(1, opts.maxSentences ?? 2);
2914
+ const maxChars = Math.max(40, opts.maxChars ?? 180);
2915
+ const normalized = text.replace(/\r\n?/g, "\n").split("\n").map((line) => line.trim()).filter(Boolean).join(" ").replace(/\s+/g, " ").trim();
2916
+ if (normalized.length <= maxChars) return normalized;
2917
+ const sentences = normalized.match(/[^.!?]+[.!?]+(?=\s|$)|[^.!?]+$/g) ?? [normalized];
2918
+ const selected = [];
2919
+ for (const sentence of sentences) {
2920
+ selected.push(sentence.trim());
2921
+ const candidate = selected.join(" ");
2922
+ if (selected.length >= maxSentences || candidate.length >= maxChars) break;
2923
+ }
2924
+ const summary = selected.join(" ").trim() || normalized;
2925
+ if (summary.length <= maxChars) return summary;
2926
+ const hardLimit = maxChars - 4;
2927
+ const boundary = findWordBoundary(summary, hardLimit);
2928
+ return `${summary.slice(0, boundary > 0 ? boundary : hardLimit).trimEnd()} ...`;
2929
+ }
2930
+ function applyToolDescriptionModeToTool(tool, mode) {
2931
+ const existingOriginal = getOriginalDescription(tool);
2932
+ if (mode === "extend" && !existingOriginal) return tool;
2933
+ const original = existingOriginal ?? {
2934
+ description: tool.description,
2935
+ usageHint: tool.usageHint
2936
+ };
2937
+ const next = mode === "simple" ? withDescription(tool, {
2938
+ description: simplifyToolDescription(original.description),
2939
+ usageHint: original.usageHint === void 0 ? void 0 : simplifyToolDescription(original.usageHint)
2940
+ }) : withDescription(tool, original);
2941
+ return attachOriginalDescription(next, original);
2942
+ }
2943
+ function setToolDescriptionMode(registry, name, mode) {
2944
+ if (typeof registry.setDescriptionMode === "function") {
2945
+ return registry.setDescriptionMode(name, mode);
2946
+ }
2947
+ if (!registry.get(name) || typeof registry.wrap !== "function") return false;
2948
+ registry.wrap(
2949
+ name,
2950
+ (tool) => applyToolDescriptionModeToTool(tool, mode),
2951
+ "tool-description-mode"
2952
+ );
2953
+ return true;
2954
+ }
2955
+ function getToolDescriptionMode(registry, name) {
2956
+ return registry.getDescriptionMode?.(name) ?? DEFAULT_TOOL_DESCRIPTION_MODE;
2957
+ }
2958
+ function applyToolDescriptionModes(registry, modes) {
2959
+ if (typeof registry.applyDescriptionModes === "function") {
2960
+ return registry.applyDescriptionModes(modes);
2961
+ }
2962
+ const entries = Object.entries(modes ?? {});
2963
+ const missing = [];
2964
+ let applied = 0;
2965
+ for (const [name, rawMode] of entries) {
2966
+ const mode = normalizeToolDescriptionMode(rawMode);
2967
+ if (!mode) continue;
2968
+ if (setToolDescriptionMode(registry, name, mode)) applied++;
2969
+ else missing.push(name);
2970
+ }
2971
+ return { applied, missing };
2972
+ }
2973
+ function getOriginalDescription(tool) {
2974
+ return tool[ORIGINAL_TOOL_DESCRIPTION];
2975
+ }
2976
+ function attachOriginalDescription(tool, original) {
2977
+ Object.defineProperty(tool, ORIGINAL_TOOL_DESCRIPTION, {
2978
+ configurable: true,
2979
+ enumerable: false,
2980
+ value: original,
2981
+ writable: true
2982
+ });
2983
+ return tool;
2984
+ }
2985
+ function withDescription(tool, next) {
2986
+ const copy = {
2987
+ ...tool,
2988
+ description: next.description,
2989
+ usageHint: next.usageHint
2990
+ };
2991
+ if (next.usageHint === void 0) {
2992
+ delete copy.usageHint;
2993
+ }
2994
+ return copy;
2995
+ }
2996
+ function findWordBoundary(text, limit) {
2997
+ const semantic = Math.max(
2998
+ text.lastIndexOf(". ", limit),
2999
+ text.lastIndexOf("; ", limit),
3000
+ text.lastIndexOf(", ", limit)
3001
+ );
3002
+ if (semantic > 40) return semantic + 1;
3003
+ const space = text.lastIndexOf(" ", limit);
3004
+ return space > 40 ? space : limit;
3005
+ }
3006
+
2730
3007
  // src/utils/tool-output-serializer.ts
2731
3008
  var DEFAULT_LIST_LIMIT = 500;
2732
3009
  var LOG_ENTRY_LIMIT = 200;
@@ -3390,114 +3667,6 @@ function isScalar(value) {
3390
3667
  return value === null || ["string", "number", "boolean"].includes(typeof value);
3391
3668
  }
3392
3669
 
3393
- // src/utils/tool-description-mode.ts
3394
- var DEFAULT_TOOL_DESCRIPTION_MODE = "extend";
3395
- var ORIGINAL_TOOL_DESCRIPTION = /* @__PURE__ */ Symbol.for("wrongstack.tool.originalDescription");
3396
- function normalizeToolDescriptionMode(value) {
3397
- if (typeof value !== "string") return void 0;
3398
- const raw = value.trim().toLowerCase();
3399
- if (raw === "extend" || raw === "extended" || raw === "full") return "extend";
3400
- if (raw === "simple" || raw === "short" || raw === "brief") return "simple";
3401
- return void 0;
3402
- }
3403
- function resolveToolDescriptionMode(modes, toolName) {
3404
- return normalizeToolDescriptionMode(modes?.[toolName]) ?? DEFAULT_TOOL_DESCRIPTION_MODE;
3405
- }
3406
- function simplifyToolDescription(text, opts = {}) {
3407
- const maxSentences = Math.max(1, opts.maxSentences ?? 2);
3408
- const maxChars = Math.max(40, opts.maxChars ?? 180);
3409
- const normalized = text.replace(/\r\n?/g, "\n").split("\n").map((line) => line.trim()).filter(Boolean).join(" ").replace(/\s+/g, " ").trim();
3410
- if (normalized.length <= maxChars) return normalized;
3411
- const sentences = normalized.match(/[^.!?]+[.!?]+(?=\s|$)|[^.!?]+$/g) ?? [normalized];
3412
- const selected = [];
3413
- for (const sentence of sentences) {
3414
- selected.push(sentence.trim());
3415
- const candidate = selected.join(" ");
3416
- if (selected.length >= maxSentences || candidate.length >= maxChars) break;
3417
- }
3418
- const summary = selected.join(" ").trim() || normalized;
3419
- if (summary.length <= maxChars) return summary;
3420
- const hardLimit = maxChars - 4;
3421
- const boundary = findWordBoundary(summary, hardLimit);
3422
- return `${summary.slice(0, boundary > 0 ? boundary : hardLimit).trimEnd()} ...`;
3423
- }
3424
- function applyToolDescriptionModeToTool(tool, mode) {
3425
- const existingOriginal = getOriginalDescription(tool);
3426
- if (mode === "extend" && !existingOriginal) return tool;
3427
- const original = existingOriginal ?? {
3428
- description: tool.description,
3429
- usageHint: tool.usageHint
3430
- };
3431
- const next = mode === "simple" ? withDescription(tool, {
3432
- description: simplifyToolDescription(original.description),
3433
- usageHint: original.usageHint === void 0 ? void 0 : simplifyToolDescription(original.usageHint)
3434
- }) : withDescription(tool, original);
3435
- return attachOriginalDescription(next, original);
3436
- }
3437
- function setToolDescriptionMode(registry, name, mode) {
3438
- if (typeof registry.setDescriptionMode === "function") {
3439
- return registry.setDescriptionMode(name, mode);
3440
- }
3441
- if (!registry.get(name) || typeof registry.wrap !== "function") return false;
3442
- registry.wrap(
3443
- name,
3444
- (tool) => applyToolDescriptionModeToTool(tool, mode),
3445
- "tool-description-mode"
3446
- );
3447
- return true;
3448
- }
3449
- function getToolDescriptionMode(registry, name) {
3450
- return registry.getDescriptionMode?.(name) ?? DEFAULT_TOOL_DESCRIPTION_MODE;
3451
- }
3452
- function applyToolDescriptionModes(registry, modes) {
3453
- if (typeof registry.applyDescriptionModes === "function") {
3454
- return registry.applyDescriptionModes(modes);
3455
- }
3456
- const entries = Object.entries(modes ?? {});
3457
- const missing = [];
3458
- let applied = 0;
3459
- for (const [name, rawMode] of entries) {
3460
- const mode = normalizeToolDescriptionMode(rawMode);
3461
- if (!mode) continue;
3462
- if (setToolDescriptionMode(registry, name, mode)) applied++;
3463
- else missing.push(name);
3464
- }
3465
- return { applied, missing };
3466
- }
3467
- function getOriginalDescription(tool) {
3468
- return tool[ORIGINAL_TOOL_DESCRIPTION];
3469
- }
3470
- function attachOriginalDescription(tool, original) {
3471
- Object.defineProperty(tool, ORIGINAL_TOOL_DESCRIPTION, {
3472
- configurable: true,
3473
- enumerable: false,
3474
- value: original,
3475
- writable: true
3476
- });
3477
- return tool;
3478
- }
3479
- function withDescription(tool, next) {
3480
- const copy = {
3481
- ...tool,
3482
- description: next.description,
3483
- usageHint: next.usageHint
3484
- };
3485
- if (next.usageHint === void 0) {
3486
- delete copy.usageHint;
3487
- }
3488
- return copy;
3489
- }
3490
- function findWordBoundary(text, limit) {
3491
- const semantic = Math.max(
3492
- text.lastIndexOf(". ", limit),
3493
- text.lastIndexOf("; ", limit),
3494
- text.lastIndexOf(", ", limit)
3495
- );
3496
- if (semantic > 40) return semantic + 1;
3497
- const space = text.lastIndexOf(" ", limit);
3498
- return space > 40 ? space : limit;
3499
- }
3500
-
3501
3670
  // src/utils/tool-result-render-mode.ts
3502
3671
  var DEFAULT_TOOL_RESULT_RENDER_MODE = "extend";
3503
3672
  function normalizeToolResultRenderMode(value) {
@@ -3535,6 +3704,76 @@ function applyToolResultRenderModes(registry, modes) {
3535
3704
  return { applied, missing };
3536
3705
  }
3537
3706
 
3707
+ // src/utils/tool-subject.ts
3708
+ var GLOB_METACHARACTERS = /[*?[\]]/g;
3709
+ function escapeGlobSubject(value) {
3710
+ return value.replace(GLOB_METACHARACTERS, (char) => `\\${char}`);
3711
+ }
3712
+ function normalizePathSubject(value) {
3713
+ return escapeGlobSubject(value.replace(/\\/g, "/"));
3714
+ }
3715
+ function isPathSubjectKey(subjectKey) {
3716
+ return subjectKey === "path" || subjectKey === "file" || subjectKey === "files";
3717
+ }
3718
+ function subjectForToolInput(toolName, input, subjectKey) {
3719
+ if (!input || typeof input !== "object") return void 0;
3720
+ const obj = input;
3721
+ if (subjectKey) {
3722
+ const value = obj[subjectKey];
3723
+ if (typeof value === "string") {
3724
+ return isPathSubjectKey(subjectKey) ? normalizePathSubject(value) : escapeGlobSubject(value);
3725
+ }
3726
+ }
3727
+ if (toolName === "bash" && typeof obj.command === "string") {
3728
+ return escapeGlobSubject(obj.command);
3729
+ }
3730
+ if (typeof obj.path === "string") {
3731
+ return normalizePathSubject(obj.path);
3732
+ }
3733
+ if (typeof obj.url === "string") {
3734
+ return escapeGlobSubject(obj.url);
3735
+ }
3736
+ if (typeof obj.name === "string") {
3737
+ return escapeGlobSubject(obj.name);
3738
+ }
3739
+ return void 0;
3740
+ }
3741
+
3742
+ // src/utils/ulid.ts
3743
+ import { randomBytes as randomBytes2 } from "node:crypto";
3744
+ var ENCODING = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
3745
+ var ENCODING_LEN = ENCODING.length;
3746
+ var TIME_LEN = 10;
3747
+ var RANDOM_LEN = 16;
3748
+ function encodeTime(now, len) {
3749
+ let mod;
3750
+ let str = "";
3751
+ for (let i = len - 1; i >= 0; i--) {
3752
+ mod = now % ENCODING_LEN;
3753
+ str = ENCODING[mod] + str;
3754
+ now = (now - mod) / ENCODING_LEN;
3755
+ }
3756
+ return str;
3757
+ }
3758
+ function encodeRandom(len) {
3759
+ const bytes = randomBytes2(len);
3760
+ let str = "";
3761
+ for (let i = 0; i < len; i++) {
3762
+ str += ENCODING[bytes[i] % ENCODING_LEN];
3763
+ }
3764
+ return str;
3765
+ }
3766
+ function ulid(seedTime = Date.now()) {
3767
+ return encodeTime(seedTime, TIME_LEN) + encodeRandom(RANDOM_LEN);
3768
+ }
3769
+ function isUlid(value) {
3770
+ if (value.length !== TIME_LEN + RANDOM_LEN) return false;
3771
+ for (const ch of value) {
3772
+ if (!ENCODING.includes(ch)) return false;
3773
+ }
3774
+ return true;
3775
+ }
3776
+
3538
3777
  // src/utils/wstack-paths.ts
3539
3778
  import { createHash } from "node:crypto";
3540
3779
  import * as fs3 from "node:fs";
@@ -3587,6 +3826,11 @@ function resolveWstackPaths(opts) {
3587
3826
  homeDir,
3588
3827
  configDir: globalRoot,
3589
3828
  globalConfig: path4.join(globalRoot, "config.json"),
3829
+ profilesDir: path4.join(globalRoot, "profiles"),
3830
+ profileConfig: (name) => {
3831
+ const safe = name.replace(/[/\\:]/g, "_").replace(/\.\./g, "_");
3832
+ return path4.join(globalRoot, "profiles", safe || "default", "config.json");
3833
+ },
3590
3834
  secretsKey: path4.join(globalRoot, ".key"),
3591
3835
  globalMemory: path4.join(globalRoot, "memory.md"),
3592
3836
  globalSkills: path4.join(globalRoot, "skills"),
@@ -3633,10 +3877,12 @@ export {
3633
3877
  COMPLETED_WORK_LEDGER_MARKER,
3634
3878
  DEFAULT_TOOL_DESCRIPTION_MODE,
3635
3879
  DEFAULT_TOOL_RESULT_RENDER_MODE,
3880
+ ESCAPE_TERMINATOR,
3636
3881
  FORBIDDEN_PROTO_KEYS,
3637
3882
  IncomingImageError,
3638
3883
  MAX_INCOMING_IMAGES,
3639
3884
  MAX_INCOMING_IMAGE_BYTES,
3885
+ TerminalLifecycle,
3640
3886
  applyToolDescriptionModeToTool,
3641
3887
  applyToolDescriptionModes,
3642
3888
  applyToolResultRenderModes,
@@ -3646,6 +3892,8 @@ export {
3646
3892
  buildChildEnv,
3647
3893
  buildCompletedWorkLedgerBlock,
3648
3894
  buildContextEvidenceDigest,
3895
+ buildSgrSequence,
3896
+ buildTitleSequence,
3649
3897
  buildUserContentBlocks,
3650
3898
  canonicalProjectRoot,
3651
3899
  coerceAgainstSchema,
@@ -3662,6 +3910,7 @@ export {
3662
3910
  createToolOutputSerializer,
3663
3911
  deepMerge,
3664
3912
  detectNewlineStyle,
3913
+ detectTerminal,
3665
3914
  ensureDir,
3666
3915
  escapeGlobSubject,
3667
3916
  estimateMessageTokens,
@@ -3681,18 +3930,15 @@ export {
3681
3930
  getCalibrationState,
3682
3931
  getChildEnvGitIdentity,
3683
3932
  getJsonPath,
3684
- getTermSize,
3685
3933
  getToolDescriptionMode,
3686
3934
  getToolResultRenderMode,
3935
+ hasMeaningfulContent,
3687
3936
  hasOpenTodos,
3688
- isInteractive,
3689
3937
  isJsonObject,
3690
3938
  isPathSubjectKey,
3691
3939
  isPrimitiveArray,
3692
3940
  isPrivateIPv4,
3693
3941
  isPrivateIPv6,
3694
- isStdinTTY,
3695
- isStdoutTTY,
3696
3942
  isUlid,
3697
3943
  jsonObjectFileExists,
3698
3944
  markAssistantReferencedEvidence,
@@ -3704,7 +3950,6 @@ export {
3704
3950
  normalizeToLf,
3705
3951
  normalizeToolDescriptionMode,
3706
3952
  normalizeToolResultRenderMode,
3707
- onResize,
3708
3953
  parseIncomingImages,
3709
3954
  projectHash,
3710
3955
  projectSlug,
@@ -3721,6 +3966,7 @@ export {
3721
3966
  resolveToolDescriptionMode,
3722
3967
  resolveToolResultRenderMode,
3723
3968
  resolveWstackPaths,
3969
+ safeEmit,
3724
3970
  safeParse,
3725
3971
  safeStringify,
3726
3972
  sanitizeJsonString,
@@ -3728,8 +3974,7 @@ export {
3728
3974
  sessionScopedPath,
3729
3975
  setJsonPath,
3730
3976
  setJsonPathInFile,
3731
- setOutputLineGuard,
3732
- setRawMode,
3977
+ setTitle,
3733
3978
  setToolDescriptionMode,
3734
3979
  setToolResultRenderMode,
3735
3980
  simplifyToolDescription,
@@ -3747,9 +3992,7 @@ export {
3747
3992
  updateJsonObjectFile,
3748
3993
  validateAgainstSchema,
3749
3994
  withFileLock,
3750
- writeErr,
3751
3995
  writeJsonObjectFile,
3752
- writeOut,
3753
3996
  wstackGlobalRoot
3754
3997
  };
3755
3998
  //# sourceMappingURL=index.js.map