@wrongstack/core 0.313.0 → 0.316.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 (343) hide show
  1. package/dist/chronicle/index.js +84 -6391
  2. package/dist/chronicle/legacy-journal-import.d.ts +0 -6
  3. package/dist/chronicle/metrics-ingest.d.ts +14 -0
  4. package/dist/chronicle/metrics-schema.d.ts +10 -1
  5. package/dist/chronicle/metrics-store.d.ts +20 -2
  6. package/dist/chronicle/project-server.js +98 -4874
  7. package/dist/chronicle/sink.d.ts +13 -0
  8. package/dist/chronicle/sqlite-journal.d.ts +20 -2
  9. package/dist/chunk-25LSLC3G.js +334 -0
  10. package/dist/chunk-27QIURLN.js +1073 -0
  11. package/dist/chunk-2FK4WTFF.js +207 -0
  12. package/dist/chunk-2YU4WVBW.js +134 -0
  13. package/dist/chunk-3AGWVSS7.js +4608 -0
  14. package/dist/chunk-3BDV7RL3.js +211 -0
  15. package/dist/chunk-3ECENVHL.js +325 -0
  16. package/dist/chunk-3XPVB7BA.js +135 -0
  17. package/dist/chunk-45WI72ZB.js +16884 -0
  18. package/dist/chunk-4BMVPOHO.js +3748 -0
  19. package/dist/chunk-4I7HGVVA.js +363 -0
  20. package/dist/chunk-4LCZVJVF.js +317 -0
  21. package/dist/chunk-4SJNS7OB.js +217 -0
  22. package/dist/chunk-4VWO3ZXL.js +342 -0
  23. package/dist/chunk-57GEWK5X.js +26 -0
  24. package/dist/chunk-5BMIE7QG.js +46 -0
  25. package/dist/chunk-5S437PRC.js +50 -0
  26. package/dist/chunk-5XDUGTKN.js +511 -0
  27. package/dist/chunk-5YPSXQXM.js +1443 -0
  28. package/dist/chunk-6FHWXLPT.js +10 -0
  29. package/dist/chunk-6H5GEOET.js +2406 -0
  30. package/dist/chunk-6NWEVFEL.js +151 -0
  31. package/dist/chunk-AYW5YINX.js +58 -0
  32. package/dist/chunk-B4AMLZPB.js +9 -0
  33. package/dist/chunk-B7F4WVP4.js +65 -0
  34. package/dist/chunk-BJHVULHO.js +55 -0
  35. package/dist/chunk-BPBKKBUK.js +2085 -0
  36. package/dist/chunk-BYD345OX.js +589 -0
  37. package/dist/chunk-C27KDLOX.js +279 -0
  38. package/dist/chunk-CU546ESW.js +597 -0
  39. package/dist/chunk-DLHHXUAM.js +172 -0
  40. package/dist/chunk-DOTHQSJ2.js +429 -0
  41. package/dist/chunk-DYLPMV4Q.js +711 -0
  42. package/dist/chunk-EODDVJBM.js +82 -0
  43. package/dist/chunk-F3JWNST7.js +361 -0
  44. package/dist/chunk-FC2ZGRF3.js +140 -0
  45. package/dist/chunk-FCBTO76Z.js +5786 -0
  46. package/dist/chunk-FHZVFYSL.js +396 -0
  47. package/dist/chunk-FNXVT7HF.js +52 -0
  48. package/dist/chunk-FWNLEZYG.js +259 -0
  49. package/dist/chunk-FXQLIX3K.js +211 -0
  50. package/dist/chunk-G5S3S5ZN.js +38 -0
  51. package/dist/chunk-GDQ7CZRQ.js +116 -0
  52. package/dist/chunk-GJJGJB2R.js +1374 -0
  53. package/dist/chunk-GTCU6DZ3.js +1 -0
  54. package/dist/chunk-HA4ZYA6T.js +178 -0
  55. package/dist/chunk-HI3JGZR2.js +188 -0
  56. package/dist/chunk-HMLIGAU7.js +395 -0
  57. package/dist/chunk-HXKZ7OBQ.js +303 -0
  58. package/dist/chunk-I7DALG7J.js +292 -0
  59. package/dist/chunk-IRUTEHCE.js +960 -0
  60. package/dist/chunk-IYFBFX34.js +86 -0
  61. package/dist/chunk-J2WRWR37.js +1104 -0
  62. package/dist/chunk-JFPJ6LLQ.js +129 -0
  63. package/dist/chunk-JMULFFLN.js +9 -0
  64. package/dist/chunk-JO4MGB6Z.js +1264 -0
  65. package/dist/chunk-JVKB2TBL.js +48 -0
  66. package/dist/chunk-JX7VBZDK.js +31 -0
  67. package/dist/chunk-K6BXGITA.js +931 -0
  68. package/dist/chunk-KDQJCT2J.js +45 -0
  69. package/dist/chunk-KJ2ZTQSL.js +47 -0
  70. package/dist/chunk-KZMSZV32.js +187 -0
  71. package/dist/chunk-LA7CLDRW.js +129 -0
  72. package/dist/chunk-LHOA5DWA.js +28 -0
  73. package/dist/chunk-LSMMOS2Z.js +119 -0
  74. package/dist/chunk-LX5QWLBL.js +27 -0
  75. package/dist/chunk-LXWCMQNJ.js +789 -0
  76. package/dist/chunk-M27LIEKV.js +2829 -0
  77. package/dist/chunk-MJPHJRAL.js +663 -0
  78. package/dist/chunk-MTL4O5YR.js +228 -0
  79. package/dist/chunk-NDBIPFNY.js +102 -0
  80. package/dist/chunk-NEMIWEXC.js +1199 -0
  81. package/dist/chunk-NHJ75HXY.js +1 -0
  82. package/dist/chunk-NIOAGFPB.js +1510 -0
  83. package/dist/chunk-NS52ISWS.js +355 -0
  84. package/dist/chunk-NSOFPKGT.js +5352 -0
  85. package/dist/chunk-NVIZG63R.js +757 -0
  86. package/dist/chunk-O37BQ65S.js +21 -0
  87. package/dist/chunk-OOYZPOXM.js +308 -0
  88. package/dist/chunk-OSGLYW5J.js +28 -0
  89. package/dist/chunk-PFCMSSUF.js +1640 -0
  90. package/dist/chunk-PFZO3C6H.js +14 -0
  91. package/dist/chunk-PGRVXIMY.js +158 -0
  92. package/dist/chunk-PHH7LD45.js +113 -0
  93. package/dist/chunk-PISBFBJN.js +109 -0
  94. package/dist/chunk-POOOIWE5.js +9 -0
  95. package/dist/chunk-PQNS3U7Z.js +1240 -0
  96. package/dist/chunk-QSTSJOCK.js +402 -0
  97. package/dist/chunk-RFQMOKWK.js +282 -0
  98. package/dist/chunk-RJIZEJ42.js +30 -0
  99. package/dist/chunk-RTOTNK3P.js +484 -0
  100. package/dist/chunk-RXKSDUAU.js +1172 -0
  101. package/dist/chunk-S45JPKQN.js +3317 -0
  102. package/dist/chunk-SAFHACFA.js +152 -0
  103. package/dist/chunk-SQJVFEBV.js +41 -0
  104. package/dist/chunk-SVT4RNTR.js +49 -0
  105. package/dist/chunk-SWUFN7XM.js +43 -0
  106. package/dist/chunk-SXMVYC5H.js +174 -0
  107. package/dist/chunk-SZ6AYUIZ.js +23 -0
  108. package/dist/chunk-TBRL2RCC.js +9 -0
  109. package/dist/chunk-TCCHINEF.js +655 -0
  110. package/dist/chunk-THEGTRAG.js +316 -0
  111. package/dist/chunk-TR4LQE7L.js +2256 -0
  112. package/dist/chunk-TRT2HRWZ.js +18 -0
  113. package/dist/chunk-TWJMGXCI.js +900 -0
  114. package/dist/chunk-U45AXT5D.js +1023 -0
  115. package/dist/chunk-U4FWBSO3.js +509 -0
  116. package/dist/chunk-UBGDX6FI.js +147 -0
  117. package/dist/chunk-UJILKYES.js +75 -0
  118. package/dist/chunk-ULMAQV3T.js +234 -0
  119. package/dist/chunk-VVBP6KGT.js +9 -0
  120. package/dist/chunk-W5VITDM2.js +168 -0
  121. package/dist/chunk-WAHQVNWT.js +194 -0
  122. package/dist/chunk-WBPVKEEE.js +227 -0
  123. package/dist/chunk-WGGYRBXH.js +5434 -0
  124. package/dist/chunk-WLYKU45P.js +5770 -0
  125. package/dist/chunk-WP7BVANJ.js +53 -0
  126. package/dist/chunk-WQQON3SV.js +473 -0
  127. package/dist/chunk-WQTOVMGV.js +119 -0
  128. package/dist/chunk-XBDP4QPW.js +7 -0
  129. package/dist/chunk-XEBHSJLT.js +103 -0
  130. package/dist/chunk-XF4VUMKW.js +231 -0
  131. package/dist/chunk-XQ2ECNK3.js +1 -0
  132. package/dist/chunk-Y5YXDM7D.js +74 -0
  133. package/dist/chunk-YOPAUVU4.js +2588 -0
  134. package/dist/chunk-YPT4A46F.js +362 -0
  135. package/dist/chunk-YWXT3JNM.js +425 -0
  136. package/dist/chunk-YY6APYUM.js +49 -0
  137. package/dist/chunk-Z2IJUO45.js +691 -0
  138. package/dist/chunk-ZHZ2Y2DH.js +1643 -0
  139. package/dist/chunk-ZT7JNIGX.js +152 -0
  140. package/dist/coordination/agent-monitor.d.ts +9 -1
  141. package/dist/coordination/agent-subagent-runner.d.ts +1 -1
  142. package/dist/coordination/agents/agent-prompts.d.ts +8 -0
  143. package/dist/coordination/agents/index.d.ts +33 -1
  144. package/dist/coordination/agents/index.js +184 -6269
  145. package/dist/coordination/agents/phase3-wave1-platform.d.ts +1 -3
  146. package/dist/coordination/agents/phase3-wave2-meta.d.ts +1 -3
  147. package/dist/coordination/agents/phase8-wave3-products.d.ts +1 -3
  148. package/dist/coordination/agents/phase9-wave4-platform-meta.d.ts +1 -3
  149. package/dist/coordination/agents/project-agent-identity.d.ts +11 -11
  150. package/dist/coordination/agents/types.d.ts +13 -2
  151. package/dist/coordination/brain-monitor.d.ts +30 -7
  152. package/dist/coordination/collab-debug.d.ts +1 -1
  153. package/dist/coordination/collab-pause.d.ts +1 -1
  154. package/dist/coordination/delegate-tool.d.ts +7 -5
  155. package/dist/coordination/director-kanban-queue-helpers.d.ts +1 -0
  156. package/dist/coordination/director-options.d.ts +7 -0
  157. package/dist/coordination/director-spawn-model.d.ts +17 -0
  158. package/dist/coordination/director-tools.d.ts +2 -2
  159. package/dist/coordination/director.d.ts +12 -0
  160. package/dist/coordination/dispatcher.d.ts +8 -0
  161. package/dist/coordination/fleet-bus.d.ts +35 -4
  162. package/dist/coordination/fleet-supervisor.d.ts +10 -2
  163. package/dist/coordination/fleet.d.ts +16 -7
  164. package/dist/coordination/index.d.ts +4 -0
  165. package/dist/coordination/index.js +402 -34324
  166. package/dist/coordination/kanban-dispatch-port.d.ts +2 -2
  167. package/dist/coordination/mailbox-http-router.d.ts +4 -3
  168. package/dist/coordination/mailbox-http-validation.d.ts +1 -1
  169. package/dist/coordination/mailbox-project-server.js +48 -3276
  170. package/dist/coordination/mailbox-types.d.ts +24 -6
  171. package/dist/coordination/model-tier-leader.d.ts +122 -0
  172. package/dist/coordination/model-tier.d.ts +122 -0
  173. package/dist/coordination/multi-agent-coordinator.d.ts +24 -0
  174. package/dist/coordination/origin-session.d.ts +16 -0
  175. package/dist/coordination/provider-status-tracker.d.ts +41 -5
  176. package/dist/coordination/session-note-hub.d.ts +44 -0
  177. package/dist/coordination/session-note-tool.d.ts +10 -0
  178. package/dist/core/agent.d.ts +15 -2
  179. package/dist/core/context.d.ts +22 -3
  180. package/dist/core/index.d.ts +2 -0
  181. package/dist/core/index.js +239 -12360
  182. package/dist/core/model-ref.js +5 -23
  183. package/dist/core/provider-runner.d.ts +36 -1
  184. package/dist/core/request-conversation-binding.d.ts +37 -0
  185. package/dist/core/session-notes.d.ts +25 -0
  186. package/dist/core/system-prompt-builder.d.ts +11 -2
  187. package/dist/core/system-prompt-variants.d.ts +78 -0
  188. package/dist/design/index.js +50 -1087
  189. package/dist/execution/auto-compaction-middleware.d.ts +11 -0
  190. package/dist/execution/autonomy-brain.d.ts +2 -1
  191. package/dist/execution/autonomy-prompt-contributor.d.ts +7 -2
  192. package/dist/execution/compaction-core.d.ts +4 -4
  193. package/dist/execution/eternal-autonomy.d.ts +1 -1
  194. package/dist/execution/index.d.ts +1 -1
  195. package/dist/execution/index.js +1615 -21895
  196. package/dist/execution/model-runtime.d.ts +0 -7
  197. package/dist/execution/parallel-eternal-engine.d.ts +7 -7
  198. package/dist/execution/prompt-enhancer.js +16 -535
  199. package/dist/execution/retry-policy.d.ts +31 -1
  200. package/dist/extension/index.js +7 -311
  201. package/dist/goal/index.js +33 -3435
  202. package/dist/hooks/index.js +14 -1138
  203. package/dist/hq/index.js +114 -5139
  204. package/dist/hq/persistence/event-log.d.ts +0 -1
  205. package/dist/hq/persistence.d.ts +4 -4
  206. package/dist/hq/protocol.js +21 -668
  207. package/dist/hq/publisher.d.ts +2 -0
  208. package/dist/index.d.ts +14 -11
  209. package/dist/index.js +1502 -92655
  210. package/dist/infrastructure/index.d.ts +4 -4
  211. package/dist/infrastructure/index.js +504 -5230
  212. package/dist/infrastructure/token-counter.d.ts +9 -0
  213. package/dist/kernel/events/agent-events.d.ts +77 -3
  214. package/dist/kernel/events/brain-events.d.ts +12 -0
  215. package/dist/kernel/events/provider-events.d.ts +22 -1
  216. package/dist/kernel/events/session-events.d.ts +14 -0
  217. package/dist/kernel/events/tool-events.d.ts +13 -0
  218. package/dist/kernel/index.js +14 -992
  219. package/dist/mailbox-attach.d.ts +1 -1
  220. package/dist/models/index.js +41 -1117
  221. package/dist/notifications/index.js +3 -108
  222. package/dist/observability/event-bridge.d.ts +25 -5
  223. package/dist/observability/index.d.ts +9 -8
  224. package/dist/observability/index.js +477 -631
  225. package/dist/observability/tool-usage-source.d.ts +65 -0
  226. package/dist/plugin/index.d.ts +5 -0
  227. package/dist/plugin/index.js +600 -14835
  228. package/dist/plugins/auto-review-plugin.d.ts +3 -2
  229. package/dist/plugins/review-finding-commands.d.ts +0 -8
  230. package/dist/plugins/review-finding-store.js +22 -0
  231. package/dist/plugins/review-finding-types.js +19 -0
  232. package/dist/plugins/review-report-integration.js +21 -0
  233. package/dist/plugins/review-report-store.js +20 -0
  234. package/dist/plugins/review-report-types.js +13 -0
  235. package/dist/prompts/index.js +14 -948
  236. package/dist/registry/index.js +9 -822
  237. package/dist/registry/tool-registry.d.ts +59 -9
  238. package/dist/registry-7N4O3E7W.js +14 -0
  239. package/dist/replay/index.js +6 -84
  240. package/dist/security/capabilities.d.ts +6 -0
  241. package/dist/security/file-permissions.d.ts +1 -1
  242. package/dist/security/index.js +161 -2235
  243. package/dist/security/permission-policy.d.ts +12 -1
  244. package/dist/security/secret-scrubber.d.ts +15 -0
  245. package/dist/session-catalog/index.d.ts +1 -0
  246. package/dist/session-catalog/index.js +41 -2103
  247. package/dist/session-catalog/project-server.js +59 -1435
  248. package/dist/session-catalog/protocol.d.ts +32 -1
  249. package/dist/session-catalog/registry.d.ts +17 -1
  250. package/dist/session-catalog/session-agents.d.ts +56 -0
  251. package/dist/session-catalog/store-rebuild.d.ts +14 -0
  252. package/dist/session-catalog/store-schema.d.ts +26 -0
  253. package/dist/session-catalog/store.d.ts +27 -1
  254. package/dist/session-note-attach.d.ts +9 -0
  255. package/dist/skills/index.js +35 -1578
  256. package/dist/statusline/index.d.ts +43 -0
  257. package/dist/statusline/index.js +102 -0
  258. package/dist/storage/board-store-port.d.ts +2 -2
  259. package/dist/storage/config-loader/in-project-policy.d.ts +29 -0
  260. package/dist/storage/config-loader.d.ts +3 -2
  261. package/dist/storage/file-session-writer.d.ts +4 -2
  262. package/dist/storage/goal-coordination.d.ts +6 -1
  263. package/dist/storage/goal-kanban.d.ts +4 -1
  264. package/dist/storage/index.d.ts +12 -4
  265. package/dist/storage/index.js +198 -15601
  266. package/dist/storage/input-history-store.d.ts +2 -4
  267. package/dist/storage/memory-curator.d.ts +133 -0
  268. package/dist/storage/session-agent-attribution.d.ts +39 -0
  269. package/dist/storage/session-doctor.d.ts +109 -0
  270. package/dist/storage/session-event-bridge.d.ts +5 -7
  271. package/dist/storage/session-outcome.d.ts +42 -0
  272. package/dist/storage/session-recovery.d.ts +55 -0
  273. package/dist/storage/session-store/load-session-data.d.ts +11 -0
  274. package/dist/storage/session-store/prune-helpers.d.ts +1 -1
  275. package/dist/storage/session-store/resume-session.d.ts +0 -2
  276. package/dist/storage/session-store/types.d.ts +8 -0
  277. package/dist/storage/session-store.d.ts +3 -3
  278. package/dist/storage/session-summary-tracker.d.ts +8 -1
  279. package/dist/storage/session-write-buffer.d.ts +18 -0
  280. package/dist/storage/session-writer-truncate.d.ts +2 -0
  281. package/dist/tasking/index.js +10 -676
  282. package/dist/tools/fallback-manage-tools.d.ts +6 -4
  283. package/dist/tools/index.js +52 -9590
  284. package/dist/tools/model-tier-set-tool.d.ts +66 -0
  285. package/dist/types/agent-bridge.d.ts +2 -1
  286. package/dist/types/config/autonomy.d.ts +5 -0
  287. package/dist/types/config/mcp-features.d.ts +7 -0
  288. package/dist/types/config/model-tiers.d.ts +148 -0
  289. package/dist/types/config/root.d.ts +9 -0
  290. package/dist/types/config/tools.d.ts +73 -0
  291. package/dist/types/config/ui.d.ts +1 -1
  292. package/dist/types/config.d.ts +1 -0
  293. package/dist/types/context.d.ts +2 -0
  294. package/dist/types/default-config.d.ts +6 -0
  295. package/dist/types/errors.d.ts +20 -1
  296. package/dist/types/index.d.ts +11 -9
  297. package/dist/types/index.js +131 -1342
  298. package/dist/types/multi-agent.d.ts +43 -0
  299. package/dist/types/plugin.d.ts +1 -1
  300. package/dist/types/provider-runner.d.ts +8 -0
  301. package/dist/types/provider.d.ts +15 -0
  302. package/dist/types/runtime-capability-manifest.d.ts +1 -1
  303. package/dist/types/secret-scrubber.d.ts +15 -0
  304. package/dist/types/session-markers.d.ts +37 -10
  305. package/dist/types/session-markers.js +8 -144
  306. package/dist/types/session-timeline.d.ts +197 -0
  307. package/dist/types/session-timeline.js +12 -0
  308. package/dist/types/session.d.ts +172 -11
  309. package/dist/types/system-prompt.d.ts +27 -0
  310. package/dist/utils/config-backup.d.ts +9 -1
  311. package/dist/utils/error.js +3 -4
  312. package/dist/utils/expect-defined.js +3 -9
  313. package/dist/utils/heap-watchdog.js +6 -706
  314. package/dist/utils/index.js +271 -5685
  315. package/dist/utils/message-invariants.d.ts +4 -1
  316. package/dist/utils/regex-guard.d.ts +1 -1
  317. package/dist/utils/sage-output-block.js +5 -42
  318. package/dist/utils/socket-path.d.ts +1 -1
  319. package/dist/utils/token-estimate.d.ts +6 -2
  320. package/dist/utils/wstack-paths.d.ts +2 -0
  321. package/dist/wiring/proxy-rewrite.d.ts +46 -0
  322. package/dist/wiring/proxy-rewrite.js +24 -121
  323. package/dist/worktree/index.js +6 -887
  324. package/instructions/agents/explore-companion.md +45 -18
  325. package/instructions/agents/memory-curator.md +34 -22
  326. package/instructions/coordination/director-preamble.md +12 -7
  327. package/instructions/coordination/subagent-baseline.md +26 -5
  328. package/instructions/leader-after-task.md +4 -1
  329. package/instructions/llm/chimera-review.md +30 -9
  330. package/instructions/llm/memory-curator.md +31 -0
  331. package/instructions/sections/tool/delegation-compact.md +2 -0
  332. package/instructions/sections/tool/delegation-full.md +5 -1
  333. package/instructions/sections/tool/mailbox-compact.md +5 -1
  334. package/instructions/sections/tool/mailbox-full.md +3 -0
  335. package/instructions/sections/tool/session-note-compact.md +3 -0
  336. package/instructions/sections/tool/session-note-full.md +15 -0
  337. package/instructions/system-lite.md +9 -4
  338. package/instructions/system-pro.md +66 -143
  339. package/instructions/system.md +73 -175
  340. package/package.json +32 -4
  341. package/dist/coordination/agents.d.ts +0 -8
  342. package/dist/coordination/transport.d.ts +0 -2
  343. package/dist/storage/session-writer/session-writer-summary-tracker.d.ts +0 -28
@@ -0,0 +1,1104 @@
1
+ import {
2
+ SYSTEM_BLOCK_SOURCE,
3
+ buildLiveNextStepsGateBlock
4
+ } from "./chunk-M27LIEKV.js";
5
+ import {
6
+ color,
7
+ writeErr
8
+ } from "./chunk-4VWO3ZXL.js";
9
+ import {
10
+ buildCompletedWorkLedgerBlock
11
+ } from "./chunk-ZHZ2Y2DH.js";
12
+ import {
13
+ estimateTextTokens,
14
+ estimateToolDefTokens,
15
+ estimateToolInputTokens,
16
+ estimateToolResultTokens
17
+ } from "./chunk-HMLIGAU7.js";
18
+ import {
19
+ expectDefined
20
+ } from "./chunk-PFZO3C6H.js";
21
+
22
+ // src/utils/assert-never.ts
23
+ function assertNever(x, message) {
24
+ const err = new Error(
25
+ message ?? `Unhandled case: ${JSON.stringify(x)}`
26
+ );
27
+ err.name = "AssertNeverError";
28
+ throw err;
29
+ }
30
+
31
+ // src/utils/connectivity.ts
32
+ var DEFAULT_PROBE_URL = "https://1.1.1.1";
33
+ var DEFAULT_TIMEOUT_MS = 5e3;
34
+ var DEFAULT_TTL_MS = 3e4;
35
+ var cached;
36
+ async function checkConnectivity(opts) {
37
+ const url = opts?.probeUrl ?? DEFAULT_PROBE_URL;
38
+ const timeout = opts?.timeoutMs ?? DEFAULT_TIMEOUT_MS;
39
+ const ttl = opts?.ttlMs ?? DEFAULT_TTL_MS;
40
+ if (cached && ttl > 0 && Date.now() - cached.at < ttl) {
41
+ return cached.ok;
42
+ }
43
+ cached = { ok: await probe(url, timeout), at: Date.now() };
44
+ return cached.ok;
45
+ }
46
+ async function probe(url, timeoutMs) {
47
+ const controller = new AbortController();
48
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
49
+ if (typeof timer.unref === "function") timer.unref();
50
+ try {
51
+ await fetch(url, { method: "HEAD", signal: controller.signal });
52
+ return true;
53
+ } catch {
54
+ return false;
55
+ } finally {
56
+ clearTimeout(timer);
57
+ }
58
+ }
59
+ function resetConnectivityCache() {
60
+ cached = void 0;
61
+ }
62
+
63
+ // src/utils/context-breakdown.ts
64
+ var SYSTEM_BLOCK_SOURCES = [
65
+ "identity",
66
+ "tool-usage",
67
+ "environment",
68
+ "skills",
69
+ "mode",
70
+ "plan",
71
+ "leader-after-task",
72
+ "contributor",
73
+ "ledger",
74
+ "glossary",
75
+ "peers",
76
+ "nextsteps",
77
+ "other"
78
+ ];
79
+ function emptyBySource() {
80
+ const out = {};
81
+ for (const key of SYSTEM_BLOCK_SOURCES) out[key] = 0;
82
+ return out;
83
+ }
84
+ function isMcpTool(tool) {
85
+ return (tool.capabilities?.includes("mcp.proxy") ?? false) || tool.name.startsWith("mcp__");
86
+ }
87
+ function mcpServerOf(tool) {
88
+ const parts = tool.name.split("__");
89
+ return parts.length >= 3 && parts[0] === "mcp" ? parts[1] ?? "mcp" : "mcp";
90
+ }
91
+ function safeBuild(fn, warn = () => {
92
+ }) {
93
+ try {
94
+ return fn();
95
+ } catch (e) {
96
+ warn(e);
97
+ return void 0;
98
+ }
99
+ }
100
+ function resolveEffectiveMaxContext(ctx) {
101
+ const metaLimit = ctx.meta?.["effectiveMaxContext"];
102
+ const providerMax = ctx.provider.capabilities.maxContext;
103
+ return typeof metaLimit === "number" && metaLimit > 0 ? metaLimit : typeof providerMax === "number" && providerMax > 0 ? providerMax : 2e5;
104
+ }
105
+ function getContextBreakdown(ctx) {
106
+ const bySource = emptyBySource();
107
+ let systemTotal = 0;
108
+ for (const block of ctx.systemPrompt) {
109
+ const tokens = estimateTextTokens(block.text);
110
+ systemTotal += tokens;
111
+ bySource[SYSTEM_BLOCK_SOURCE.get(block) ?? "other"] += tokens;
112
+ }
113
+ let toolsBuiltin = 0;
114
+ let toolsMcp = 0;
115
+ const mcpByServer = {};
116
+ for (const tool of ctx.tools) {
117
+ const tokens = estimateToolDefTokens(tool);
118
+ if (isMcpTool(tool)) {
119
+ toolsMcp += tokens;
120
+ const server = mcpServerOf(tool);
121
+ mcpByServer[server] = (mcpByServer[server] ?? 0) + tokens;
122
+ } else {
123
+ toolsBuiltin += tokens;
124
+ }
125
+ }
126
+ let histText = 0;
127
+ let histToolInputs = 0;
128
+ let histToolResults = 0;
129
+ let histThinking = 0;
130
+ let histOther = 0;
131
+ for (const msg of ctx.messages) {
132
+ if (typeof msg.content === "string") {
133
+ histText += estimateTextTokens(msg.content);
134
+ continue;
135
+ }
136
+ for (const b of msg.content) {
137
+ switch (b.type) {
138
+ case "text":
139
+ histText += estimateTextTokens(b.text);
140
+ break;
141
+ case "tool_use":
142
+ histToolInputs += estimateToolInputTokens(b.input);
143
+ break;
144
+ case "tool_result":
145
+ histToolResults += estimateToolResultTokens(b.content);
146
+ break;
147
+ case "thinking": {
148
+ let str;
149
+ try {
150
+ str = JSON.stringify(b) ?? "";
151
+ } catch {
152
+ str = String(b);
153
+ }
154
+ histThinking += estimateTextTokens(str);
155
+ break;
156
+ }
157
+ default: {
158
+ let str;
159
+ try {
160
+ str = JSON.stringify(b) ?? "";
161
+ } catch {
162
+ str = String(b);
163
+ }
164
+ histOther += estimateTextTokens(str);
165
+ }
166
+ }
167
+ }
168
+ }
169
+ const warnings = [];
170
+ const warn = (e) => {
171
+ const msg = e instanceof Error ? e.message : String(e);
172
+ warnings.push(msg);
173
+ };
174
+ const ledgerBlock = safeBuild(() => buildCompletedWorkLedgerBlock(ctx), warn);
175
+ const nextstepsBlock = safeBuild(() => buildLiveNextStepsGateBlock(ctx), warn);
176
+ const ledger = ledgerBlock ? estimateTextTokens(ledgerBlock.text) : 0;
177
+ const nextsteps = nextstepsBlock ? estimateTextTokens(nextstepsBlock.text) : 0;
178
+ const toolsTotal = toolsBuiltin + toolsMcp;
179
+ const historyTotal = histText + histToolInputs + histToolResults + histThinking + histOther;
180
+ const volatileTotal = ledger + nextsteps;
181
+ const total = systemTotal + toolsTotal + historyTotal + volatileTotal;
182
+ const effectiveMaxContext = resolveEffectiveMaxContext(ctx);
183
+ return {
184
+ system: { total: systemTotal, bySource },
185
+ tools: {
186
+ total: toolsTotal,
187
+ builtin: toolsBuiltin,
188
+ mcp: toolsMcp,
189
+ count: ctx.tools.length,
190
+ mcpByServer
191
+ },
192
+ history: {
193
+ total: historyTotal,
194
+ text: histText,
195
+ toolInputs: histToolInputs,
196
+ toolResults: histToolResults,
197
+ thinking: histThinking,
198
+ other: histOther,
199
+ messageCount: ctx.messages.length
200
+ },
201
+ volatile: { ledger, nextsteps, total: volatileTotal },
202
+ total,
203
+ effectiveMaxContext,
204
+ usedPct: effectiveMaxContext > 0 ? total / effectiveMaxContext : 0,
205
+ warnings
206
+ };
207
+ }
208
+
209
+ // src/utils/crash-shield.ts
210
+ var CRASH_STORM_WINDOW_MS = 6e4;
211
+ var CRASH_STORM_LIMIT = 20;
212
+ var fatalSalvageHooks = [];
213
+ function addFatalSalvageHook(hook) {
214
+ fatalSalvageHooks.push(hook);
215
+ return () => {
216
+ const idx = fatalSalvageHooks.indexOf(hook);
217
+ if (idx >= 0) fatalSalvageHooks.splice(idx, 1);
218
+ };
219
+ }
220
+ function runFatalSalvageSync() {
221
+ for (const hook of [...fatalSalvageHooks]) {
222
+ try {
223
+ hook();
224
+ } catch {
225
+ }
226
+ }
227
+ }
228
+ function isBrokenOutputConsumer(error) {
229
+ if (typeof error !== "object" || error === null || !("code" in error)) return false;
230
+ return error.code === "EPIPE" || error.code === "ECONNRESET" || error.code === "ECONNABORTED";
231
+ }
232
+ function installCrashShield(options = {}) {
233
+ const target = options.target ?? process;
234
+ const exit = options.exit ?? ((code) => process.exit(code));
235
+ const write = options.write ?? ((s) => void writeErr(s));
236
+ const recent = [];
237
+ const isStorming = () => {
238
+ const now = Date.now();
239
+ recent.push(now);
240
+ while (recent.length > 0 && now - recent[0] > CRASH_STORM_WINDOW_MS) {
241
+ recent.shift();
242
+ }
243
+ return recent.length > CRASH_STORM_LIMIT;
244
+ };
245
+ const report = (kind, reason) => {
246
+ try {
247
+ const detail = reason instanceof Error ? reason.stack ?? reason.message : String(reason);
248
+ write(`[wrongstack] ${kind} (recovered \u2014 please report): ${detail}
249
+ `);
250
+ } catch {
251
+ }
252
+ };
253
+ const guard = (kind) => (reason) => {
254
+ if (isBrokenOutputConsumer(reason)) return;
255
+ report(kind, reason);
256
+ if (isStorming()) {
257
+ report(
258
+ kind,
259
+ new Error(
260
+ `error storm: >${CRASH_STORM_LIMIT} in ${CRASH_STORM_WINDOW_MS / 1e3}s \u2014 exiting`
261
+ )
262
+ );
263
+ runFatalSalvageSync();
264
+ exit(1);
265
+ }
266
+ };
267
+ const onRejection = guard("unhandled promise rejection");
268
+ const onException = guard("uncaught exception");
269
+ target.on("unhandledRejection", onRejection);
270
+ target.on("uncaughtException", onException);
271
+ return () => {
272
+ target.off("unhandledRejection", onRejection);
273
+ target.off("uncaughtException", onException);
274
+ };
275
+ }
276
+
277
+ // src/utils/diff.ts
278
+ function myersDiff(a, b) {
279
+ const N = a.length;
280
+ const M = b.length;
281
+ const max = N + M;
282
+ if (max === 0) return [];
283
+ const v = /* @__PURE__ */ new Map();
284
+ v.set(1, 0);
285
+ const trace = [];
286
+ for (let d = 0; d <= max; d++) {
287
+ const snapshot = new Map(v);
288
+ trace.push(snapshot);
289
+ for (let k = -d; k <= d; k += 2) {
290
+ const left = v.get(k - 1) ?? -1;
291
+ const right = v.get(k + 1) ?? -1;
292
+ let x;
293
+ if (k === -d || k !== d && left < right) {
294
+ x = right;
295
+ } else {
296
+ x = left + 1;
297
+ }
298
+ let y = x - k;
299
+ while (x < N && y < M && a[x] === b[y]) {
300
+ x++;
301
+ y++;
302
+ }
303
+ v.set(k, x);
304
+ if (x >= N && y >= M) {
305
+ return backtrack(trace, a, b, N, M, d);
306
+ }
307
+ }
308
+ }
309
+ return [];
310
+ }
311
+ function backtrack(trace, a, b, N, M, finalD) {
312
+ const edits = [];
313
+ let x = N;
314
+ let y = M;
315
+ for (let d = finalD; d > 0; d--) {
316
+ const v = trace[d];
317
+ if (!v) break;
318
+ const k = x - y;
319
+ const left = v.get(k - 1) ?? -1;
320
+ const right = v.get(k + 1) ?? -1;
321
+ let prevK;
322
+ if (k === -d || k !== d && left < right) {
323
+ prevK = k + 1;
324
+ } else {
325
+ prevK = k - 1;
326
+ }
327
+ const prevX = v.get(prevK) ?? 0;
328
+ const prevY = prevX - prevK;
329
+ while (x > prevX && y > prevY) {
330
+ edits.push({ op: "equal", a: x - 1, b: y - 1, line: a[x - 1] ?? "" });
331
+ x--;
332
+ y--;
333
+ }
334
+ if (d > 0) {
335
+ if (x === prevX) {
336
+ edits.push({ op: "insert", a: x, b: y - 1, line: b[y - 1] ?? "" });
337
+ } else {
338
+ edits.push({ op: "delete", a: x - 1, b: y, line: a[x - 1] ?? "" });
339
+ }
340
+ x = prevX;
341
+ y = prevY;
342
+ }
343
+ }
344
+ while (x > 0 && y > 0) {
345
+ edits.push({ op: "equal", a: x - 1, b: y - 1, line: a[x - 1] ?? "" });
346
+ x--;
347
+ y--;
348
+ }
349
+ return edits.reverse();
350
+ }
351
+ function unifiedDiff(oldText, newText, opts = {}) {
352
+ const context = opts.context ?? 3;
353
+ const a = oldText.replace(/\r\n/g, "\n").split("\n");
354
+ const b = newText.replace(/\r\n/g, "\n").split("\n");
355
+ if (a[a.length - 1] === "") a.pop();
356
+ if (b[b.length - 1] === "") b.pop();
357
+ const edits = myersDiff(a, b);
358
+ if (edits.every((e) => e.op === "equal")) return "";
359
+ const hunks = [];
360
+ let i = 0;
361
+ while (i < edits.length) {
362
+ while (i < edits.length && edits[i]?.op === "equal") i++;
363
+ if (i >= edits.length) break;
364
+ const hunkStart = Math.max(0, i - context);
365
+ const lines = [];
366
+ let aStart = (edits[hunkStart]?.a ?? 0) + 1;
367
+ let bStart = (edits[hunkStart]?.b ?? 0) + 1;
368
+ let aCount = 0;
369
+ let bCount = 0;
370
+ let cursor = hunkStart;
371
+ let trailing = 0;
372
+ while (cursor < edits.length) {
373
+ const e = edits[cursor];
374
+ if (!e) break;
375
+ if (e.op === "equal") {
376
+ trailing++;
377
+ if (trailing > context * 2) break;
378
+ } else {
379
+ trailing = 0;
380
+ }
381
+ if (e.op === "equal") {
382
+ lines.push(` ${e.line}`);
383
+ aCount++;
384
+ bCount++;
385
+ } else if (e.op === "delete") {
386
+ lines.push(`-${e.line}`);
387
+ aCount++;
388
+ } else {
389
+ lines.push(`+${e.line}`);
390
+ bCount++;
391
+ }
392
+ cursor++;
393
+ }
394
+ while (lines.length > 0 && lines[lines.length - 1]?.startsWith(" ") && trailing > context) {
395
+ lines.pop();
396
+ aCount--;
397
+ bCount--;
398
+ trailing--;
399
+ }
400
+ if (aCount === 0) aStart = 0;
401
+ if (bCount === 0) bStart = 0;
402
+ hunks.push({ aStart, bStart, lines });
403
+ i = cursor;
404
+ }
405
+ if (hunks.length === 0) return "";
406
+ let out = "";
407
+ out += `--- ${opts.fromFile ?? "a"}
408
+ `;
409
+ out += `+++ ${opts.toFile ?? "b"}
410
+ `;
411
+ for (const h of hunks) {
412
+ let aCount = 0;
413
+ let bCount = 0;
414
+ for (const l of h.lines) {
415
+ if (l.startsWith(" ")) {
416
+ aCount++;
417
+ bCount++;
418
+ } else if (l.startsWith("-")) aCount++;
419
+ else if (l.startsWith("+")) bCount++;
420
+ }
421
+ out += `@@ -${h.aStart},${aCount} +${h.bStart},${bCount} @@
422
+ `;
423
+ out += `${h.lines.join("\n")}
424
+ `;
425
+ }
426
+ return out;
427
+ }
428
+
429
+ // src/utils/env-typed.ts
430
+ function envBool(key, env = process.env) {
431
+ const raw = env[key];
432
+ if (raw === void 0 || raw === "") return false;
433
+ return !/^(0|false|no|off)$/i.test(raw.trim());
434
+ }
435
+ function envBoolOptional(key, env = process.env) {
436
+ const raw = env[key];
437
+ if (raw === void 0 || raw === "") return void 0;
438
+ return !/^(0|false|no|off)$/i.test(raw.trim());
439
+ }
440
+ function envInt(key, options = { default: 0 }, env = process.env) {
441
+ const raw = env[key];
442
+ if (raw === void 0 || raw === "") return options.default;
443
+ const parsed = Number.parseInt(raw, 10);
444
+ if (!Number.isFinite(parsed)) return options.default;
445
+ if (options.min !== void 0 && parsed < options.min) return options.default;
446
+ if (options.max !== void 0 && parsed > options.max) return options.default;
447
+ return parsed;
448
+ }
449
+ function envFloat(key, options = { default: 0 }, env = process.env) {
450
+ const raw = env[key];
451
+ if (raw === void 0 || raw === "") return options.default;
452
+ const parsed = Number.parseFloat(raw);
453
+ if (!Number.isFinite(parsed)) return options.default;
454
+ if (options.min !== void 0 && parsed < options.min) return options.default;
455
+ if (options.max !== void 0 && parsed > options.max) return options.default;
456
+ return parsed;
457
+ }
458
+ function envString(key, env = process.env) {
459
+ const raw = env[key];
460
+ if (raw === void 0) return void 0;
461
+ const trimmed = raw.trim();
462
+ return trimmed === "" ? void 0 : trimmed;
463
+ }
464
+ function envEnum(key, allowed, options, env = process.env) {
465
+ const raw = envString(key, env);
466
+ if (raw === void 0) return options.default;
467
+ return allowed.includes(raw) ? raw : options.default;
468
+ }
469
+
470
+ // src/utils/glob-expand.ts
471
+ import * as fsp from "node:fs/promises";
472
+ import { isAbsolute, resolve } from "node:path";
473
+ var GLOB_CHARS = /* @__PURE__ */ new Set(["*", "?", "["]);
474
+ var IS_WINDOWS = typeof process !== "undefined" && process.platform === "win32";
475
+ var SEP = IS_WINDOWS ? "\\" : "/";
476
+ function isGlob(p) {
477
+ for (const c of p) {
478
+ if (GLOB_CHARS.has(c)) return true;
479
+ }
480
+ return false;
481
+ }
482
+ function globToRegex(pat) {
483
+ let i = 0;
484
+ let re = "^";
485
+ while (i < pat.length) {
486
+ const c = expectDefined(pat[i]);
487
+ if (c === "*") {
488
+ if (pat[i + 1] === "*") {
489
+ re += ".*";
490
+ i += 2;
491
+ if (pat[i] === "/") i++;
492
+ } else {
493
+ re += "[^/\\\\]*";
494
+ i++;
495
+ }
496
+ } else if (c === "?") {
497
+ re += "[^/\\\\]";
498
+ i++;
499
+ } else if (c === "[") {
500
+ const closeIndex = pat.indexOf("]", i + 1);
501
+ if (closeIndex === -1) {
502
+ re += "\\[";
503
+ i++;
504
+ continue;
505
+ }
506
+ let cls = "[";
507
+ i++;
508
+ if (pat[i] === "!" || pat[i] === "^") {
509
+ cls += "^";
510
+ i++;
511
+ }
512
+ while (i < pat.length && pat[i] !== "]") {
513
+ const ch = pat[i] ?? "";
514
+ if (ch === "\\") cls += "\\\\";
515
+ else if (ch === "]" || ch === "^") cls += `\\${ch}`;
516
+ else cls += ch;
517
+ i++;
518
+ }
519
+ cls += "]";
520
+ re += cls;
521
+ i++;
522
+ } else {
523
+ re += c.replace(/[.+^${}()|\\]/g, "\\$&");
524
+ i++;
525
+ }
526
+ }
527
+ return new RegExp(re + "$");
528
+ }
529
+ function baseDir(pat) {
530
+ let firstGlob = pat.length;
531
+ for (let i = 0; i < pat.length; i++) {
532
+ if (GLOB_CHARS.has(expectDefined(pat[i]))) {
533
+ firstGlob = i;
534
+ break;
535
+ }
536
+ }
537
+ const cut = Math.max(
538
+ pat.lastIndexOf(SEP, firstGlob - 1),
539
+ pat.lastIndexOf("/", firstGlob - 1)
540
+ );
541
+ return cut < 0 ? "." : pat.slice(0, cut);
542
+ }
543
+ async function expandGlob(pattern) {
544
+ if (!isGlob(pattern)) return [pattern];
545
+ const normalized = pattern.replace(/\\/g, "/");
546
+ const results = /* @__PURE__ */ new Set();
547
+ const abs = isAbsolute(pattern);
548
+ const base = baseDir(pattern);
549
+ const baseNorm = base.replace(/\\/g, "/");
550
+ const relPat = base === "." ? normalized : normalized.slice(baseNorm.length + 1);
551
+ async function walk(dir, pat) {
552
+ let entries;
553
+ try {
554
+ entries = await fsp.readdir(dir, { withFileTypes: true });
555
+ } catch {
556
+ return;
557
+ }
558
+ if (pat.startsWith("**/")) {
559
+ const rest = pat.slice(3);
560
+ await walk(dir, rest);
561
+ for (const e of entries) {
562
+ if (e.isDirectory()) {
563
+ const subDir = `${dir}${SEP}${e.name}`;
564
+ await walk(subDir, pat);
565
+ }
566
+ }
567
+ return;
568
+ }
569
+ if (pat === "**") {
570
+ for (const e of entries) {
571
+ const full = `${dir}${SEP}${e.name}`;
572
+ results.add(abs ? resolve(full) : full);
573
+ if (e.isDirectory()) {
574
+ await walk(full, "**");
575
+ }
576
+ }
577
+ return;
578
+ }
579
+ const firstSlash = pat.indexOf("/");
580
+ if (firstSlash < 0) {
581
+ const re = globToRegex(pat);
582
+ for (const e of entries) {
583
+ if (re.test(e.name)) {
584
+ const full = `${dir}${SEP}${e.name}`;
585
+ results.add(abs ? resolve(full) : full);
586
+ }
587
+ }
588
+ return;
589
+ }
590
+ const currentSeg = pat.slice(0, firstSlash);
591
+ const remainingPat = pat.slice(firstSlash + 1);
592
+ if (isGlob(currentSeg)) {
593
+ const re = globToRegex(currentSeg);
594
+ for (const e of entries) {
595
+ if (e.isDirectory() && re.test(e.name)) {
596
+ const subDir = `${dir}${SEP}${e.name}`;
597
+ await walk(subDir, remainingPat);
598
+ }
599
+ }
600
+ } else {
601
+ for (const e of entries) {
602
+ if (e.isDirectory() && e.name === currentSeg) {
603
+ const subDir = `${dir}${SEP}${e.name}`;
604
+ await walk(subDir, remainingPat);
605
+ }
606
+ }
607
+ }
608
+ }
609
+ await walk(base === "." ? "." : base, relPat);
610
+ return [...results];
611
+ }
612
+
613
+ // src/utils/incoming-images.ts
614
+ var MAX_INCOMING_IMAGES = 8;
615
+ var MAX_INCOMING_IMAGE_BYTES = 8 * 1024 * 1024;
616
+ var ALLOWED_IMAGE_MEDIA_TYPES = /* @__PURE__ */ new Set([
617
+ "image/png",
618
+ "image/jpeg",
619
+ "image/webp",
620
+ "image/gif"
621
+ ]);
622
+ function isAllowedImageMediaType(mediaType) {
623
+ return ALLOWED_IMAGE_MEDIA_TYPES.has(mediaType.toLowerCase());
624
+ }
625
+ function isValidImageBase64(base64) {
626
+ return /^[A-Za-z0-9+/]+={0,2}$/.test(base64);
627
+ }
628
+ function base64DecodedBytes(base64) {
629
+ return Math.floor(base64.length * 3 / 4);
630
+ }
631
+ var IncomingImageError = class extends Error {
632
+ constructor(message) {
633
+ super(message);
634
+ this.name = "IncomingImageError";
635
+ }
636
+ };
637
+ var DATA_URL_RE = /^data:([a-z0-9.+-]+\/[a-z0-9.+-]+)?(?:;[a-z0-9-]+=[^;,]*)*(;base64)?,/i;
638
+ function splitDataUrl(data) {
639
+ const match = DATA_URL_RE.exec(data);
640
+ if (!match) return { base64: data.trim() };
641
+ return {
642
+ base64: data.slice(match[0].length).trim(),
643
+ mediaType: match[1]?.toLowerCase()
644
+ };
645
+ }
646
+ function parseIncomingImages(images, legacyImageBase64) {
647
+ const raw = [...images ?? []];
648
+ if (legacyImageBase64) raw.push({ data: legacyImageBase64 });
649
+ if (raw.length === 0) return [];
650
+ if (raw.length > MAX_INCOMING_IMAGES) {
651
+ throw new IncomingImageError(
652
+ `Too many images: ${raw.length} (max ${MAX_INCOMING_IMAGES} per message).`
653
+ );
654
+ }
655
+ return raw.map((img, i) => {
656
+ const { base64, mediaType: fromUrl } = splitDataUrl(img.data ?? "");
657
+ const mediaType = (img.mediaType ?? fromUrl ?? "image/png").toLowerCase();
658
+ if (!isAllowedImageMediaType(mediaType)) {
659
+ throw new IncomingImageError(
660
+ `Image ${i + 1}: unsupported media type "${mediaType}" (allowed: ${[...ALLOWED_IMAGE_MEDIA_TYPES].join(", ")}).`
661
+ );
662
+ }
663
+ if (!base64) {
664
+ throw new IncomingImageError(`Image ${i + 1}: empty image data.`);
665
+ }
666
+ if (!isValidImageBase64(base64)) {
667
+ throw new IncomingImageError(`Image ${i + 1}: data is not valid base64.`);
668
+ }
669
+ const bytes = base64DecodedBytes(base64);
670
+ if (bytes > MAX_INCOMING_IMAGE_BYTES) {
671
+ throw new IncomingImageError(
672
+ `Image ${i + 1}: ${(bytes / (1024 * 1024)).toFixed(1)} MB exceeds the ${MAX_INCOMING_IMAGE_BYTES / (1024 * 1024)} MB limit.`
673
+ );
674
+ }
675
+ return {
676
+ type: "image",
677
+ source: { type: "base64", media_type: mediaType, data: base64 }
678
+ };
679
+ });
680
+ }
681
+ function buildUserContentBlocks(text, images) {
682
+ const blocks = [...images];
683
+ if (text) blocks.push({ type: "text", text });
684
+ return blocks;
685
+ }
686
+
687
+ // src/utils/merge-custom-models.ts
688
+ function mergeCustomModelDefs(providerCustomModels, configModels) {
689
+ const out = {};
690
+ if (providerCustomModels) {
691
+ for (const [id, def] of Object.entries(providerCustomModels)) {
692
+ out[id] = { ...def };
693
+ }
694
+ }
695
+ if (configModels) {
696
+ for (const [id, def] of Object.entries(configModels)) {
697
+ out[id] = { ...def };
698
+ }
699
+ }
700
+ if (Object.keys(out).length === 0) return void 0;
701
+ return out;
702
+ }
703
+
704
+ // src/utils/newline-normalize.ts
705
+ function detectNewlineStyle(text) {
706
+ if (typeof text !== "string") return "lf";
707
+ let lf = 0;
708
+ let crlf = 0;
709
+ let cr = 0;
710
+ for (let i = 0; i < text.length; i++) {
711
+ const c = text.charCodeAt(i);
712
+ if (c === 13) {
713
+ if (text.charCodeAt(i + 1) === 10) {
714
+ crlf++;
715
+ i++;
716
+ } else {
717
+ cr++;
718
+ }
719
+ } else if (c === 10) {
720
+ lf++;
721
+ }
722
+ }
723
+ if (crlf > lf && crlf > cr) return "crlf";
724
+ if (cr > lf && cr > crlf) return "cr";
725
+ return "lf";
726
+ }
727
+ function toStyle(text, style) {
728
+ if (typeof text !== "string") return "";
729
+ const normalized = text.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
730
+ if (style === "lf") return normalized;
731
+ if (style === "crlf") return normalized.replace(/\n/g, "\r\n");
732
+ return normalized.replace(/\n/g, "\r");
733
+ }
734
+ function normalizeToLf(text) {
735
+ if (typeof text !== "string") return "";
736
+ return text.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
737
+ }
738
+
739
+ // src/utils/path-segment.ts
740
+ import * as path from "node:path";
741
+ var MAX_PATH_SEGMENT_LENGTH = 256;
742
+ function isSafePathSegment(value) {
743
+ if (typeof value !== "string" || value.length === 0 || value.length > MAX_PATH_SEGMENT_LENGTH) return false;
744
+ if (value === "." || value === "..") return false;
745
+ if (value.includes("/") || value.includes("\\")) return false;
746
+ if (value.includes("\0")) return false;
747
+ if (value.includes(":")) return false;
748
+ return true;
749
+ }
750
+ function resolveContainedPath(root, ...segments) {
751
+ if (segments.length === 0) return null;
752
+ for (const segment of segments) {
753
+ if (!isSafePathSegment(segment)) return null;
754
+ }
755
+ const resolvedRoot = path.resolve(root);
756
+ const candidate = path.resolve(resolvedRoot, ...segments);
757
+ if (candidate === resolvedRoot) return null;
758
+ if (!candidate.startsWith(resolvedRoot + path.sep)) return null;
759
+ return candidate;
760
+ }
761
+
762
+ // src/utils/project-watch.ts
763
+ import * as fs from "node:fs";
764
+ import * as path2 from "node:path";
765
+ var REGISTRY_KEY = /* @__PURE__ */ Symbol.for("wrongstack.projectWatchRegistry");
766
+ var globalScope = globalThis;
767
+ if (!globalScope[REGISTRY_KEY]) globalScope[REGISTRY_KEY] = /* @__PURE__ */ new Map();
768
+ var registry = globalScope[REGISTRY_KEY];
769
+ function registryKey(root) {
770
+ const resolved = path2.resolve(root);
771
+ return process.platform === "win32" ? resolved.toLowerCase() : resolved;
772
+ }
773
+ function watchProjectTree(root, listener, opts) {
774
+ const key = registryKey(root);
775
+ let entry = registry.get(key);
776
+ if (!entry || entry.dead) {
777
+ const subscribers = /* @__PURE__ */ new Set();
778
+ const watcher = fs.watch(
779
+ path2.resolve(root),
780
+ { recursive: true, persistent: false },
781
+ (eventType, filename) => {
782
+ const event = {
783
+ eventType: eventType === "rename" ? "rename" : "change",
784
+ filename: filename === null ? null : String(filename)
785
+ };
786
+ for (const sub of subscribers) {
787
+ try {
788
+ sub.listener(event);
789
+ } catch (error) {
790
+ sub.onError?.(error);
791
+ }
792
+ }
793
+ }
794
+ );
795
+ const created = { watcher, subscribers, dead: false };
796
+ const retire = () => {
797
+ created.dead = true;
798
+ if (registry.get(key) === created) registry.delete(key);
799
+ };
800
+ watcher.on("error", (error) => {
801
+ retire();
802
+ for (const sub of subscribers) sub.onError?.(error);
803
+ });
804
+ watcher.on("close", retire);
805
+ registry.set(key, created);
806
+ entry = created;
807
+ }
808
+ const active = entry;
809
+ const subscriber = { listener, onError: opts?.onError };
810
+ active.subscribers.add(subscriber);
811
+ let closed = false;
812
+ return {
813
+ close() {
814
+ if (closed) return;
815
+ closed = true;
816
+ active.subscribers.delete(subscriber);
817
+ if (active.subscribers.size === 0 && !active.dead) {
818
+ active.dead = true;
819
+ if (registry.get(key) === active) registry.delete(key);
820
+ try {
821
+ active.watcher.close();
822
+ } catch {
823
+ }
824
+ }
825
+ }
826
+ };
827
+ }
828
+
829
+ // src/utils/regex-guard.ts
830
+ import {
831
+ capSubject,
832
+ compileUserRegex,
833
+ MAX_SUBJECT_LEN
834
+ } from "@wrongstack/primitives";
835
+
836
+ // src/utils/sleep.ts
837
+ function sleep(ms) {
838
+ return new Promise((resolve4) => setTimeout(resolve4, ms));
839
+ }
840
+
841
+ // src/utils/slug.ts
842
+ function slugify(name, fallback = "prompt", maxLen = 64) {
843
+ if (typeof name !== "string") return fallback;
844
+ return name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, maxLen).replace(/-+$/g, "") || fallback;
845
+ }
846
+
847
+ // src/utils/task-format.ts
848
+ function computeTaskItemProgress(tasks) {
849
+ let completed = 0;
850
+ let pending = 0;
851
+ let inProgress = 0;
852
+ let blocked = 0;
853
+ let failed = 0;
854
+ let review = 0;
855
+ let estimatedHours = 0;
856
+ const actualHours = 0;
857
+ for (const t of tasks) {
858
+ switch (t.status) {
859
+ case "completed":
860
+ completed++;
861
+ break;
862
+ case "pending":
863
+ pending++;
864
+ break;
865
+ case "in_progress":
866
+ inProgress++;
867
+ break;
868
+ case "blocked":
869
+ blocked++;
870
+ break;
871
+ case "failed":
872
+ failed++;
873
+ break;
874
+ case "review":
875
+ review++;
876
+ break;
877
+ }
878
+ estimatedHours += t.estimateHours ?? 0;
879
+ }
880
+ return {
881
+ total: tasks.length,
882
+ pending,
883
+ inProgress,
884
+ blocked,
885
+ failed,
886
+ review,
887
+ completed,
888
+ percentComplete: tasks.length > 0 ? Math.round(completed / tasks.length * 100) : 0,
889
+ estimatedHours,
890
+ actualHours
891
+ };
892
+ }
893
+ var STATUS_ICON = {
894
+ pending: "\u25CB",
895
+ in_progress: "\u25D0",
896
+ blocked: "\u2298",
897
+ failed: "\u2717",
898
+ review: "\u25D1",
899
+ completed: "\u25CF"
900
+ };
901
+ var PRIORITY_ICON = {
902
+ critical: "\u{1F534}",
903
+ high: "\u{1F7E0}",
904
+ medium: "\u{1F7E1}",
905
+ low: "\u{1F7E2}"
906
+ };
907
+ var TYPE_ICON = {
908
+ feature: "\u26A1",
909
+ bugfix: "\u{1F41B}",
910
+ refactor: "\u267B\uFE0F",
911
+ docs: "\u{1F4DD}",
912
+ test: "\u{1F9EA}",
913
+ chore: "\u{1F527}"
914
+ };
915
+ function formatTaskProgress(tasks) {
916
+ const p = computeTaskItemProgress(tasks);
917
+ if (p.total === 0) return "No tasks.";
918
+ const barWidth = 24;
919
+ const filled = Math.round(p.percentComplete / 100 * barWidth);
920
+ const empty = barWidth - filled;
921
+ const bar = "\u2588".repeat(filled) + "\u2591".repeat(empty);
922
+ return [
923
+ `${color.bold("Tasks")} [${bar}] ${p.percentComplete}%`,
924
+ ` ${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`,
925
+ p.estimatedHours > 0 ? ` ${color.dim(`est. ${p.estimatedHours}h`)}` : ""
926
+ ].filter(Boolean).join("\n");
927
+ }
928
+ function formatTaskList(tasks) {
929
+ if (tasks.length === 0) return "No tasks.";
930
+ const order = ["in_progress", "blocked", "review", "pending", "failed", "completed"];
931
+ const groups = /* @__PURE__ */ new Map();
932
+ for (const t of tasks) {
933
+ const list = groups.get(t.status) ?? [];
934
+ list.push(t);
935
+ groups.set(t.status, list);
936
+ }
937
+ const lines = [];
938
+ lines.push(color.dim(`Tasks (${tasks.length} total):`));
939
+ for (const status of order) {
940
+ const group = groups.get(status);
941
+ if (!group || group.length === 0) continue;
942
+ const icon = STATUS_ICON[status];
943
+ lines.push(` ${icon} ${status.toUpperCase()} (${group.length})`);
944
+ for (const t of group) {
945
+ const prio = PRIORITY_ICON[t.priority];
946
+ const type = TYPE_ICON[t.type];
947
+ const deps = t.dependsOn && t.dependsOn.length > 0 ? ` ${color.dim("\u2190")} ${color.dim(t.dependsOn.map((d) => d.slice(0, 8)).join(", "))}` : "";
948
+ const who = t.assignee ? ` ${color.dim(`@${t.assignee}`)}` : "";
949
+ const hrs = t.estimateHours ? ` ${color.dim(`${t.estimateHours}h`)}` : "";
950
+ lines.push(` ${type} ${prio} ${t.title}${deps}${who}${hrs}`);
951
+ }
952
+ }
953
+ return lines.join("\n");
954
+ }
955
+
956
+ // src/utils/terminal-sanitize.ts
957
+ var ANSI_RE = /\x1b\[[0-?]*[ -/]*[@-~]/g;
958
+ var ANSI_OSC_RE = /\x1b\][\s\S]*?(?:\x07|\x1b\\)/g;
959
+ var ANSI_CONTROL_STRING_RE = /\x1b[P^_X][\s\S]*?\x1b\\/g;
960
+ var ANSI_ESCAPE_RE = /\x1b[ -/]*[@-~]/g;
961
+ var BIDI_AND_ZERO_WIDTH_RE = /[​-‏‪-‮⁦-⁩]/g;
962
+ function sanitizeTerminalText(value, tabWidth = 2) {
963
+ const tab = " ".repeat(Math.max(1, Math.min(8, Math.floor(tabWidth))));
964
+ const withoutEscapes = value.replace(ANSI_OSC_RE, "").replace(ANSI_CONTROL_STRING_RE, "").replace(ANSI_RE, "").replace(ANSI_ESCAPE_RE, "").replace(BIDI_AND_ZERO_WIDTH_RE, "").replace(/\t/g, tab).replace(/\r/g, "");
965
+ let safe = "";
966
+ for (const char of withoutEscapes) {
967
+ const code = char.codePointAt(0) ?? 0;
968
+ if (char === "\n" || code >= 32 && code !== 127 && !(code >= 128 && code <= 159)) {
969
+ safe += char;
970
+ }
971
+ }
972
+ return safe;
973
+ }
974
+ function sanitizeTerminalPreview(value, opts = {}) {
975
+ const maxLines = opts.maxLines ?? 40;
976
+ const maxChars = opts.maxChars ?? 8e3;
977
+ const safe = sanitizeTerminalText(value, opts.tabWidth);
978
+ let truncated = false;
979
+ let clipped = safe;
980
+ if (clipped.length > maxChars) {
981
+ clipped = clipped.slice(0, maxChars);
982
+ truncated = true;
983
+ }
984
+ const lines = clipped.split("\n");
985
+ if (lines.length > maxLines) {
986
+ clipped = lines.slice(0, maxLines).join("\n");
987
+ truncated = true;
988
+ }
989
+ return { text: clipped, truncated };
990
+ }
991
+
992
+ // src/utils/tool-result-render-mode.ts
993
+ var DEFAULT_TOOL_RESULT_RENDER_MODE = "extend";
994
+ function normalizeToolResultRenderMode(value) {
995
+ if (typeof value !== "string") return void 0;
996
+ const raw = value.trim().toLowerCase();
997
+ if (raw === "extend" || raw === "extended" || raw === "full") return "extend";
998
+ if (raw === "simple" || raw === "short" || raw === "brief") return "simple";
999
+ return void 0;
1000
+ }
1001
+ function resolveToolResultRenderMode(modes, toolName) {
1002
+ return normalizeToolResultRenderMode(modes?.[toolName]) ?? DEFAULT_TOOL_RESULT_RENDER_MODE;
1003
+ }
1004
+ function setToolResultRenderMode(registry2, name, mode) {
1005
+ if (typeof registry2.setResultRenderMode === "function") {
1006
+ return registry2.setResultRenderMode(name, mode);
1007
+ }
1008
+ return false;
1009
+ }
1010
+ function getToolResultRenderMode(registry2, name) {
1011
+ return registry2.getResultRenderMode?.(name) ?? DEFAULT_TOOL_RESULT_RENDER_MODE;
1012
+ }
1013
+ function applyToolResultRenderModes(registry2, modes) {
1014
+ if (typeof registry2.applyResultRenderModes === "function") {
1015
+ return registry2.applyResultRenderModes(modes);
1016
+ }
1017
+ const entries = Object.entries(modes ?? {});
1018
+ const missing = [];
1019
+ let applied = 0;
1020
+ for (const [name, rawMode] of entries) {
1021
+ const mode = normalizeToolResultRenderMode(rawMode);
1022
+ if (!mode) continue;
1023
+ if (setToolResultRenderMode(registry2, name, mode)) applied++;
1024
+ else missing.push(name);
1025
+ }
1026
+ return { applied, missing };
1027
+ }
1028
+
1029
+ // src/utils/walk-ignore.ts
1030
+ var DEFAULT_WALK_IGNORE_DIRS = Object.freeze([
1031
+ "node_modules",
1032
+ ".git",
1033
+ "dist",
1034
+ "build",
1035
+ ".next",
1036
+ ".nuxt",
1037
+ ".turbo",
1038
+ "coverage",
1039
+ ".nyc_output",
1040
+ "__snapshots__",
1041
+ "__pycache__",
1042
+ ".venv",
1043
+ "venv",
1044
+ "target",
1045
+ ".cache",
1046
+ ".parcel-cache",
1047
+ ".pnpm-store",
1048
+ ".gradle"
1049
+ ]);
1050
+ var DEFAULT_WALK_IGNORE_SET = new Set(DEFAULT_WALK_IGNORE_DIRS);
1051
+
1052
+ export {
1053
+ watchProjectTree,
1054
+ DEFAULT_WALK_IGNORE_DIRS,
1055
+ DEFAULT_WALK_IGNORE_SET,
1056
+ assertNever,
1057
+ checkConnectivity,
1058
+ resetConnectivityCache,
1059
+ getContextBreakdown,
1060
+ addFatalSalvageHook,
1061
+ runFatalSalvageSync,
1062
+ installCrashShield,
1063
+ unifiedDiff,
1064
+ envBool,
1065
+ envBoolOptional,
1066
+ envInt,
1067
+ envFloat,
1068
+ envString,
1069
+ envEnum,
1070
+ expandGlob,
1071
+ MAX_INCOMING_IMAGES,
1072
+ MAX_INCOMING_IMAGE_BYTES,
1073
+ ALLOWED_IMAGE_MEDIA_TYPES,
1074
+ isAllowedImageMediaType,
1075
+ isValidImageBase64,
1076
+ base64DecodedBytes,
1077
+ IncomingImageError,
1078
+ parseIncomingImages,
1079
+ buildUserContentBlocks,
1080
+ mergeCustomModelDefs,
1081
+ detectNewlineStyle,
1082
+ toStyle,
1083
+ normalizeToLf,
1084
+ MAX_PATH_SEGMENT_LENGTH,
1085
+ isSafePathSegment,
1086
+ resolveContainedPath,
1087
+ capSubject,
1088
+ compileUserRegex,
1089
+ MAX_SUBJECT_LEN,
1090
+ sleep,
1091
+ slugify,
1092
+ computeTaskItemProgress,
1093
+ formatTaskProgress,
1094
+ formatTaskList,
1095
+ sanitizeTerminalText,
1096
+ sanitizeTerminalPreview,
1097
+ DEFAULT_TOOL_RESULT_RENDER_MODE,
1098
+ normalizeToolResultRenderMode,
1099
+ resolveToolResultRenderMode,
1100
+ setToolResultRenderMode,
1101
+ getToolResultRenderMode,
1102
+ applyToolResultRenderModes
1103
+ };
1104
+ //# sourceMappingURL=chunk-J2WRWR37.js.map