@wrongstack/core 0.313.1 → 0.316.2

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 (290) hide show
  1. package/dist/chronicle/index.js +31 -31
  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 +39 -31
  7. package/dist/chronicle/sink.d.ts +13 -0
  8. package/dist/chronicle/sqlite-journal.d.ts +20 -2
  9. package/dist/{chunk-WOEZV3Q4.js → chunk-25LSLC3G.js} +2 -1
  10. package/dist/{chunk-AI4LLQ2U.js → chunk-27QIURLN.js} +229 -12
  11. package/dist/{chunk-I45KAW2N.js → chunk-3AGWVSS7.js} +38 -450
  12. package/dist/chunk-3BDV7RL3.js +211 -0
  13. package/dist/{chunk-NFAYHPRH.js → chunk-3ECENVHL.js} +10 -8
  14. package/dist/{chunk-FW5LDDMJ.js → chunk-45WI72ZB.js} +1576 -1156
  15. package/dist/{chunk-AT4V4XGI.js → chunk-4BMVPOHO.js} +539 -313
  16. package/dist/{chunk-YBUJCZ57.js → chunk-4I7HGVVA.js} +17 -5
  17. package/dist/{chunk-JVGPR3TS.js → chunk-4LCZVJVF.js} +7 -55
  18. package/dist/{chunk-4ZHTKJHM.js → chunk-4SJNS7OB.js} +36 -2
  19. package/dist/{chunk-AD7ZFZCS.js → chunk-5BMIE7QG.js} +3 -3
  20. package/dist/{chunk-IQ35HMQL.js → chunk-5YPSXQXM.js} +71 -24
  21. package/dist/chunk-6FHWXLPT.js +10 -0
  22. package/dist/{chunk-FIV4IJL7.js → chunk-6H5GEOET.js} +163 -20
  23. package/dist/{chunk-VB3H5WWB.js → chunk-6NWEVFEL.js} +2 -2
  24. package/dist/{chunk-E6I5RXVK.js → chunk-AYW5YINX.js} +2 -2
  25. package/dist/{chunk-DEIQMBD2.js → chunk-B7F4WVP4.js} +2 -2
  26. package/dist/{chunk-XQ2XGIBF.js → chunk-BPBKKBUK.js} +6 -7
  27. package/dist/{chunk-K4YUNKU7.js → chunk-BYD345OX.js} +2 -2
  28. package/dist/{chunk-LZDDLNCZ.js → chunk-C27KDLOX.js} +4 -4
  29. package/dist/{chunk-6AKOTGLM.js → chunk-CU546ESW.js} +7 -7
  30. package/dist/{chunk-ZZ4V3WIZ.js → chunk-DLHHXUAM.js} +10 -1
  31. package/dist/{chunk-BAKVJLEV.js → chunk-DOTHQSJ2.js} +28 -16
  32. package/dist/{chunk-KBZGE6LN.js → chunk-DYLPMV4Q.js} +4 -3
  33. package/dist/{chunk-52RTVH4M.js → chunk-F3JWNST7.js} +2 -2
  34. package/dist/{chunk-WEBMSQP2.js → chunk-FC2ZGRF3.js} +21 -4
  35. package/dist/{chunk-FHAMQS7Q.js → chunk-FCBTO76Z.js} +76 -146
  36. package/dist/{chunk-4LJJYBAU.js → chunk-FHZVFYSL.js} +9 -1
  37. package/dist/{chunk-W4A6QA3D.js → chunk-FWNLEZYG.js} +4 -3
  38. package/dist/{chunk-OJZEX73F.js → chunk-GDQ7CZRQ.js} +5 -1
  39. package/dist/{chunk-QVOVMXJR.js → chunk-GJJGJB2R.js} +32 -9
  40. package/dist/{chunk-4XV6IR37.js → chunk-HI3JGZR2.js} +7 -6
  41. package/dist/{chunk-FSWCWSTS.js → chunk-HMLIGAU7.js} +26 -26
  42. package/dist/{chunk-PFXFQQRT.js → chunk-HXKZ7OBQ.js} +7 -43
  43. package/dist/{chunk-2FQL4PDC.js → chunk-I7DALG7J.js} +5 -5
  44. package/dist/{chunk-GM54GJBU.js → chunk-IRUTEHCE.js} +3 -3
  45. package/dist/{chunk-TYW2GI5I.js → chunk-J2WRWR37.js} +40 -13
  46. package/dist/{chunk-ZEHUCJHY.js → chunk-JFPJ6LLQ.js} +2 -2
  47. package/dist/chunk-JMULFFLN.js +9 -0
  48. package/dist/{chunk-RD6DEE36.js → chunk-JO4MGB6Z.js} +94 -8
  49. package/dist/{chunk-5DSMEVA4.js → chunk-K6BXGITA.js} +7 -7
  50. package/dist/{chunk-O74MJHXU.js → chunk-KZMSZV32.js} +2 -2
  51. package/dist/{chunk-GFJOMSHG.js → chunk-LA7CLDRW.js} +6 -2
  52. package/dist/{chunk-M2WF6AXG.js → chunk-LSMMOS2Z.js} +7 -3
  53. package/dist/{chunk-ASX6AW36.js → chunk-LXWCMQNJ.js} +3 -3
  54. package/dist/{chunk-WZO23AWO.js → chunk-M27LIEKV.js} +72 -22
  55. package/dist/{chunk-JTHKOYWU.js → chunk-MJPHJRAL.js} +15 -15
  56. package/dist/{chunk-G5AAKEEZ.js → chunk-MTL4O5YR.js} +5 -5
  57. package/dist/chunk-NHJ75HXY.js +1 -0
  58. package/dist/{chunk-ZYU2YOJ6.js → chunk-NIOAGFPB.js} +29 -15
  59. package/dist/{chunk-Y2GE5TSI.js → chunk-NS52ISWS.js} +2 -2
  60. package/dist/{chunk-UIWONWVG.js → chunk-NSOFPKGT.js} +541 -148
  61. package/dist/{chunk-RCQYT2I4.js → chunk-NVIZG63R.js} +2 -2
  62. package/dist/{chunk-EPC3GZD4.js → chunk-OOYZPOXM.js} +2 -2
  63. package/dist/{chunk-7ZHZE5EO.js → chunk-OSGLYW5J.js} +2 -2
  64. package/dist/{chunk-CE4ZOCOI.js → chunk-PFCMSSUF.js} +9 -9
  65. package/dist/{chunk-GFXZTHNI.js → chunk-PGRVXIMY.js} +5 -5
  66. package/dist/{chunk-JJPMWPB6.js → chunk-PISBFBJN.js} +6 -6
  67. package/dist/chunk-POOOIWE5.js +9 -0
  68. package/dist/{chunk-5RP3QTRL.js → chunk-PQNS3U7Z.js} +20 -3
  69. package/dist/{chunk-3E244UDA.js → chunk-QSTSJOCK.js} +52 -6
  70. package/dist/{chunk-YUPMXOGP.js → chunk-RFQMOKWK.js} +3 -3
  71. package/dist/chunk-RTOTNK3P.js +484 -0
  72. package/dist/{chunk-SN2DQRL6.js → chunk-RXKSDUAU.js} +7 -7
  73. package/dist/{chunk-T3KGZBU5.js → chunk-S45JPKQN.js} +189 -43
  74. package/dist/{chunk-YNCVSFGF.js → chunk-SAFHACFA.js} +4 -1
  75. package/dist/{chunk-KI4L2DUL.js → chunk-TCCHINEF.js} +114 -19
  76. package/dist/{chunk-AWNQ6ED6.js → chunk-THEGTRAG.js} +7 -2
  77. package/dist/{chunk-2KKODIQU.js → chunk-TR4LQE7L.js} +15 -15
  78. package/dist/{chunk-GPQ3NJPR.js → chunk-TWJMGXCI.js} +3 -3
  79. package/dist/{chunk-H72H4XDU.js → chunk-U45AXT5D.js} +9 -9
  80. package/dist/{chunk-62V2AFVG.js → chunk-U4FWBSO3.js} +160 -73
  81. package/dist/{chunk-A455ATZB.js → chunk-UBGDX6FI.js} +8 -1
  82. package/dist/chunk-UJILKYES.js +75 -0
  83. package/dist/{chunk-KSJ5UTP7.js → chunk-ULMAQV3T.js} +84 -4
  84. package/dist/{chunk-CB2HFKTP.js → chunk-VVBP6KGT.js} +1 -1
  85. package/dist/{chunk-RPOA7IAE.js → chunk-W5VITDM2.js} +43 -25
  86. package/dist/{chunk-QRTG4XTI.js → chunk-WAHQVNWT.js} +7 -1
  87. package/dist/{chunk-SQP64RCS.js → chunk-WGGYRBXH.js} +3019 -2976
  88. package/dist/{chunk-K3G6JBUC.js → chunk-WLYKU45P.js} +679 -141
  89. package/dist/chunk-WP7BVANJ.js +53 -0
  90. package/dist/{chunk-GAZEWQEZ.js → chunk-XF4VUMKW.js} +2 -2
  91. package/dist/{chunk-PAAWLLZX.js → chunk-Y5YXDM7D.js} +2 -2
  92. package/dist/{chunk-65RDIOR2.js → chunk-YOPAUVU4.js} +162 -44
  93. package/dist/{chunk-FFSX2QDQ.js → chunk-YPT4A46F.js} +3 -3
  94. package/dist/chunk-YWXT3JNM.js +425 -0
  95. package/dist/{chunk-EFEHDQGY.js → chunk-ZHZ2Y2DH.js} +64 -10
  96. package/dist/{chunk-CQQL4ZOQ.js → chunk-ZT7JNIGX.js} +4 -3
  97. package/dist/coordination/agent-monitor.d.ts +9 -1
  98. package/dist/coordination/agent-subagent-runner.d.ts +1 -1
  99. package/dist/coordination/agents/agent-prompts.d.ts +8 -0
  100. package/dist/coordination/agents/index.d.ts +33 -1
  101. package/dist/coordination/agents/index.js +52 -22
  102. package/dist/coordination/agents/phase3-wave1-platform.d.ts +1 -3
  103. package/dist/coordination/agents/phase3-wave2-meta.d.ts +1 -3
  104. package/dist/coordination/agents/phase8-wave3-products.d.ts +1 -3
  105. package/dist/coordination/agents/phase9-wave4-platform-meta.d.ts +1 -3
  106. package/dist/coordination/agents/project-agent-identity.d.ts +11 -11
  107. package/dist/coordination/agents/types.d.ts +13 -2
  108. package/dist/coordination/brain-monitor.d.ts +30 -7
  109. package/dist/coordination/collab-debug.d.ts +1 -1
  110. package/dist/coordination/collab-pause.d.ts +1 -1
  111. package/dist/coordination/delegate-tool.d.ts +7 -5
  112. package/dist/coordination/director-kanban-queue-helpers.d.ts +1 -0
  113. package/dist/coordination/director-options.d.ts +7 -0
  114. package/dist/coordination/director-spawn-model.d.ts +17 -0
  115. package/dist/coordination/director-tools.d.ts +2 -2
  116. package/dist/coordination/director.d.ts +12 -0
  117. package/dist/coordination/dispatcher.d.ts +8 -0
  118. package/dist/coordination/fleet-bus.d.ts +35 -4
  119. package/dist/coordination/fleet-supervisor.d.ts +10 -2
  120. package/dist/coordination/fleet.d.ts +16 -7
  121. package/dist/coordination/index.d.ts +4 -0
  122. package/dist/coordination/index.js +86 -49
  123. package/dist/coordination/kanban-dispatch-port.d.ts +2 -2
  124. package/dist/coordination/mailbox-http-router.d.ts +4 -3
  125. package/dist/coordination/mailbox-http-validation.d.ts +1 -1
  126. package/dist/coordination/mailbox-project-server.js +15 -15
  127. package/dist/coordination/mailbox-types.d.ts +24 -6
  128. package/dist/coordination/model-tier-leader.d.ts +122 -0
  129. package/dist/coordination/model-tier.d.ts +122 -0
  130. package/dist/coordination/multi-agent-coordinator.d.ts +24 -0
  131. package/dist/coordination/origin-session.d.ts +16 -0
  132. package/dist/coordination/provider-status-tracker.d.ts +37 -5
  133. package/dist/coordination/session-note-hub.d.ts +44 -0
  134. package/dist/coordination/session-note-tool.d.ts +10 -0
  135. package/dist/core/agent.d.ts +1 -1
  136. package/dist/core/context.d.ts +22 -3
  137. package/dist/core/index.d.ts +2 -0
  138. package/dist/core/index.js +130 -38
  139. package/dist/core/request-conversation-binding.d.ts +37 -0
  140. package/dist/core/session-notes.d.ts +25 -0
  141. package/dist/core/system-prompt-builder.d.ts +11 -2
  142. package/dist/core/system-prompt-variants.d.ts +78 -0
  143. package/dist/design/index.js +3 -3
  144. package/dist/execution/auto-compaction-middleware.d.ts +11 -0
  145. package/dist/execution/autonomy-brain.d.ts +2 -1
  146. package/dist/execution/autonomy-prompt-contributor.d.ts +7 -2
  147. package/dist/execution/compaction-core.d.ts +4 -4
  148. package/dist/execution/eternal-autonomy.d.ts +1 -1
  149. package/dist/execution/index.js +138 -129
  150. package/dist/execution/model-runtime.d.ts +0 -7
  151. package/dist/execution/parallel-eternal-engine.d.ts +7 -7
  152. package/dist/extension/index.js +3 -3
  153. package/dist/goal/index.js +6 -6
  154. package/dist/hooks/index.js +3 -3
  155. package/dist/hq/index.js +14 -12
  156. package/dist/hq/persistence/event-log.d.ts +0 -1
  157. package/dist/hq/persistence.d.ts +4 -4
  158. package/dist/hq/publisher.d.ts +2 -0
  159. package/dist/index.d.ts +14 -11
  160. package/dist/index.js +728 -635
  161. package/dist/infrastructure/index.d.ts +4 -4
  162. package/dist/infrastructure/index.js +281 -260
  163. package/dist/infrastructure/token-counter.d.ts +9 -0
  164. package/dist/kernel/events/agent-events.d.ts +77 -3
  165. package/dist/kernel/events/brain-events.d.ts +12 -0
  166. package/dist/kernel/events/provider-events.d.ts +7 -1
  167. package/dist/kernel/events/session-events.d.ts +14 -0
  168. package/dist/kernel/events/tool-events.d.ts +13 -0
  169. package/dist/kernel/index.js +4 -4
  170. package/dist/mailbox-attach.d.ts +1 -1
  171. package/dist/models/index.js +10 -9
  172. package/dist/observability/event-bridge.d.ts +25 -5
  173. package/dist/observability/index.d.ts +9 -8
  174. package/dist/observability/index.js +459 -351
  175. package/dist/observability/tool-usage-source.d.ts +65 -0
  176. package/dist/plugin/index.d.ts +5 -0
  177. package/dist/plugin/index.js +66 -50
  178. package/dist/plugins/auto-review-plugin.d.ts +3 -2
  179. package/dist/plugins/review-finding-commands.d.ts +0 -8
  180. package/dist/{review-finding-store-DKAV3AS6.js → plugins/review-finding-store.js} +7 -6
  181. package/dist/plugins/review-finding-types.js +19 -0
  182. package/dist/plugins/review-report-integration.js +21 -0
  183. package/dist/{review-report-store-OWY3EC3N.js → plugins/review-report-store.js} +7 -6
  184. package/dist/plugins/review-report-types.js +13 -0
  185. package/dist/prompts/index.js +5 -5
  186. package/dist/registry/index.js +3 -3
  187. package/dist/registry/tool-registry.d.ts +59 -9
  188. package/dist/{registry-R23UBE7H.js → registry-7N4O3E7W.js} +5 -5
  189. package/dist/security/capabilities.d.ts +6 -0
  190. package/dist/security/file-permissions.d.ts +1 -1
  191. package/dist/security/index.js +47 -33
  192. package/dist/security/permission-policy.d.ts +12 -1
  193. package/dist/security/secret-scrubber.d.ts +15 -0
  194. package/dist/session-catalog/index.d.ts +1 -0
  195. package/dist/session-catalog/index.js +19 -14
  196. package/dist/session-catalog/project-server.js +30 -13
  197. package/dist/session-catalog/protocol.d.ts +32 -1
  198. package/dist/session-catalog/registry.d.ts +17 -1
  199. package/dist/session-catalog/session-agents.d.ts +56 -0
  200. package/dist/session-catalog/store-rebuild.d.ts +14 -0
  201. package/dist/session-catalog/store-schema.d.ts +26 -0
  202. package/dist/session-catalog/store.d.ts +27 -1
  203. package/dist/session-note-attach.d.ts +9 -0
  204. package/dist/skills/index.js +5 -5
  205. package/dist/statusline/index.d.ts +43 -0
  206. package/dist/statusline/index.js +102 -0
  207. package/dist/storage/board-store-port.d.ts +2 -2
  208. package/dist/storage/config-loader/in-project-policy.d.ts +29 -0
  209. package/dist/storage/config-loader.d.ts +3 -2
  210. package/dist/storage/file-session-writer.d.ts +4 -2
  211. package/dist/storage/goal-coordination.d.ts +6 -1
  212. package/dist/storage/goal-kanban.d.ts +4 -1
  213. package/dist/storage/index.d.ts +12 -4
  214. package/dist/storage/index.js +76 -61
  215. package/dist/storage/input-history-store.d.ts +2 -4
  216. package/dist/storage/memory-curator.d.ts +133 -0
  217. package/dist/storage/session-agent-attribution.d.ts +39 -0
  218. package/dist/storage/session-doctor.d.ts +109 -0
  219. package/dist/storage/session-event-bridge.d.ts +5 -7
  220. package/dist/storage/session-outcome.d.ts +42 -0
  221. package/dist/storage/session-recovery.d.ts +55 -0
  222. package/dist/storage/session-store/load-session-data.d.ts +11 -0
  223. package/dist/storage/session-store/prune-helpers.d.ts +1 -1
  224. package/dist/storage/session-store/resume-session.d.ts +0 -2
  225. package/dist/storage/session-store/types.d.ts +8 -0
  226. package/dist/storage/session-store.d.ts +3 -3
  227. package/dist/storage/session-summary-tracker.d.ts +8 -1
  228. package/dist/storage/session-write-buffer.d.ts +18 -0
  229. package/dist/storage/session-writer-truncate.d.ts +2 -0
  230. package/dist/tasking/index.js +2 -2
  231. package/dist/tools/fallback-manage-tools.d.ts +6 -4
  232. package/dist/tools/index.js +21 -21
  233. package/dist/tools/model-tier-set-tool.d.ts +66 -0
  234. package/dist/types/agent-bridge.d.ts +2 -1
  235. package/dist/types/config/mcp-features.d.ts +7 -0
  236. package/dist/types/config/model-tiers.d.ts +148 -0
  237. package/dist/types/config/root.d.ts +9 -0
  238. package/dist/types/config/tools.d.ts +73 -0
  239. package/dist/types/config.d.ts +1 -0
  240. package/dist/types/context.d.ts +2 -0
  241. package/dist/types/default-config.d.ts +6 -0
  242. package/dist/types/errors.d.ts +2 -1
  243. package/dist/types/index.d.ts +11 -9
  244. package/dist/types/index.js +25 -15
  245. package/dist/types/multi-agent.d.ts +43 -0
  246. package/dist/types/plugin.d.ts +1 -1
  247. package/dist/types/provider.d.ts +15 -0
  248. package/dist/types/runtime-capability-manifest.d.ts +1 -1
  249. package/dist/types/secret-scrubber.d.ts +15 -0
  250. package/dist/types/session-markers.d.ts +37 -10
  251. package/dist/types/session-markers.js +1 -1
  252. package/dist/types/session-timeline.d.ts +197 -0
  253. package/dist/types/session-timeline.js +12 -0
  254. package/dist/types/session.d.ts +172 -11
  255. package/dist/types/system-prompt.d.ts +27 -0
  256. package/dist/utils/config-backup.d.ts +9 -1
  257. package/dist/utils/heap-watchdog.js +2 -2
  258. package/dist/utils/index.js +50 -48
  259. package/dist/utils/message-invariants.d.ts +4 -1
  260. package/dist/utils/regex-guard.d.ts +1 -1
  261. package/dist/utils/socket-path.d.ts +1 -1
  262. package/dist/utils/token-estimate.d.ts +6 -2
  263. package/dist/utils/wstack-paths.d.ts +2 -0
  264. package/dist/wiring/proxy-rewrite.d.ts +28 -0
  265. package/dist/wiring/proxy-rewrite.js +7 -1
  266. package/dist/worktree/index.js +2 -2
  267. package/instructions/agents/explore-companion.md +45 -18
  268. package/instructions/agents/memory-curator.md +34 -22
  269. package/instructions/coordination/director-preamble.md +12 -7
  270. package/instructions/coordination/subagent-baseline.md +26 -5
  271. package/instructions/leader-after-task.md +4 -1
  272. package/instructions/llm/chimera-review.md +30 -9
  273. package/instructions/llm/memory-curator.md +31 -0
  274. package/instructions/sections/tool/delegation-compact.md +2 -0
  275. package/instructions/sections/tool/delegation-full.md +5 -1
  276. package/instructions/sections/tool/mailbox-compact.md +5 -1
  277. package/instructions/sections/tool/mailbox-full.md +3 -0
  278. package/instructions/sections/tool/session-note-compact.md +3 -0
  279. package/instructions/sections/tool/session-note-full.md +15 -0
  280. package/instructions/system-lite.md +9 -4
  281. package/instructions/system-pro.md +66 -143
  282. package/instructions/system.md +73 -175
  283. package/package.json +33 -5
  284. package/dist/chunk-2BUUIMQB.js +0 -225
  285. package/dist/chunk-FAYRX2AD.js +0 -13
  286. package/dist/chunk-H5E77KUJ.js +0 -15
  287. package/dist/chunk-M7BS2K6U.js +0 -1
  288. package/dist/coordination/agents.d.ts +0 -8
  289. package/dist/coordination/transport.d.ts +0 -2
  290. package/dist/storage/session-writer/session-writer-summary-tracker.d.ts +0 -28
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  SessionCatalogProjectClient
3
- } from "./chunk-52RTVH4M.js";
3
+ } from "./chunk-F3JWNST7.js";
4
4
  import {
5
5
  sessionCatalogProjectServerMetadataPath
6
- } from "./chunk-E6I5RXVK.js";
6
+ } from "./chunk-AYW5YINX.js";
7
7
 
8
8
  // src/session-catalog/registry.ts
9
9
  import { randomUUID } from "node:crypto";
@@ -111,7 +111,8 @@ var ProjectSessionRegistry = class {
111
111
  reservation = await binding.client.call("reserve_resume", {
112
112
  targetSessionId: target.sessionId,
113
113
  requesterInstanceId: this.instanceId,
114
- ...this.current ? { currentSessionId: this.current.entry.sessionId } : {}
114
+ ...this.current ? { currentSessionId: this.current.entry.sessionId } : {},
115
+ ...target.reservationMs !== void 0 ? { reservationMs: target.reservationMs } : {}
115
116
  });
116
117
  } catch (error) {
117
118
  await this.closeBinding(binding).catch(() => void 0);
@@ -119,7 +120,18 @@ var ProjectSessionRegistry = class {
119
120
  }
120
121
  let settled = false;
121
122
  return {
122
- reservation,
123
+ get reservation() {
124
+ return reservation;
125
+ },
126
+ renew: async (reservationMs) => {
127
+ if (settled) return false;
128
+ reservation = await binding.client.call("renew_reservation", {
129
+ reservationId: reservation.reservationId,
130
+ requesterInstanceId: this.instanceId,
131
+ ...reservationMs !== void 0 ? { reservationMs } : {}
132
+ });
133
+ return true;
134
+ },
123
135
  activate: async (registration) => {
124
136
  if (settled) throw new Error("Resume reservation is already settled");
125
137
  const entry = this.fullEntry(registration);
@@ -348,4 +360,4 @@ export {
348
360
  getProjectSessionRegistry,
349
361
  hasProjectSessionRegistry
350
362
  };
351
- //# sourceMappingURL=chunk-YBUJCZ57.js.map
363
+ //# sourceMappingURL=chunk-4I7HGVVA.js.map
@@ -1,66 +1,19 @@
1
+ import {
2
+ validateResolution,
3
+ validateTransition
4
+ } from "./chunk-UJILKYES.js";
1
5
  import {
2
6
  SECRET_FILE_MODE
3
- } from "./chunk-H5E77KUJ.js";
7
+ } from "./chunk-6FHWXLPT.js";
4
8
  import {
5
9
  atomicWrite,
6
10
  withFileLock
7
- } from "./chunk-7ZHZE5EO.js";
11
+ } from "./chunk-OSGLYW5J.js";
8
12
 
9
13
  // src/plugins/review-finding-store.ts
10
14
  import { randomUUID } from "node:crypto";
11
15
  import * as fsp from "node:fs/promises";
12
16
  import * as path from "node:path";
13
-
14
- // src/plugins/review-finding-types.ts
15
- import { createHash } from "node:crypto";
16
- var InvalidTransitionError = class extends Error {
17
- from;
18
- to;
19
- constructor(from, to, reason) {
20
- const msg = reason ?? `Invalid transition from "${from}" to "${to}"`;
21
- super(msg);
22
- this.name = "InvalidTransitionError";
23
- this.from = from;
24
- this.to = to;
25
- }
26
- };
27
- function normalizeFingerprintTitle(title) {
28
- return title.trim().toLowerCase().replace(/[^\w\s]/g, "").replace(/\s+/g, " ").trim();
29
- }
30
- function computeFindingFingerprint(file, line, title) {
31
- const normalizedTitle = normalizeFingerprintTitle(title);
32
- const normalizedFile = file.replace(/\\/g, "/").trim().toLowerCase();
33
- const lineStr = line != null && line >= 0 ? String(line) : "0";
34
- const hash = createHash("sha256");
35
- hash.update(`${normalizedFile}:${lineStr}:${normalizedTitle}`);
36
- return hash.digest("hex");
37
- }
38
- var TRANSITION_MATRIX = {
39
- active: /* @__PURE__ */ new Set(["triaged", "ignored", "resolved"]),
40
- triaged: /* @__PURE__ */ new Set(["in_progress", "ignored", "resolved"]),
41
- in_progress: /* @__PURE__ */ new Set(["resolved", "active"]),
42
- ignored: /* @__PURE__ */ new Set(["active"]),
43
- resolved: /* @__PURE__ */ new Set(["active"])
44
- };
45
- function validateTransition(from, to) {
46
- if (from === to) return;
47
- const allowed = TRANSITION_MATRIX[from];
48
- if (!allowed?.has(to)) {
49
- throw new InvalidTransitionError(from, to);
50
- }
51
- }
52
- function validateResolution(status, outcome) {
53
- if (status !== "resolved") return;
54
- if (!outcome) {
55
- throw new InvalidTransitionError(
56
- "active",
57
- "resolved",
58
- 'A resolution outcome is required when transitioning to "resolved"'
59
- );
60
- }
61
- }
62
-
63
- // src/plugins/review-finding-store.ts
64
17
  var FINDING_RESOLVED_RETENTION_MS = 30 * 24 * 60 * 60 * 1e3;
65
18
  var FINDING_IGNORED_RETENTION_MS = 14 * 24 * 60 * 60 * 1e3;
66
19
  var FINDING_DEFAULT_PAGE_SIZE = 50;
@@ -354,7 +307,6 @@ var JsonlFindingStore = class {
354
307
  };
355
308
 
356
309
  export {
357
- computeFindingFingerprint,
358
310
  FINDING_RESOLVED_RETENTION_MS,
359
311
  FINDING_IGNORED_RETENTION_MS,
360
312
  FINDING_DEFAULT_PAGE_SIZE,
@@ -362,4 +314,4 @@ export {
362
314
  resolveFindingStorePath,
363
315
  JsonlFindingStore
364
316
  };
365
- //# sourceMappingURL=chunk-JVGPR3TS.js.map
317
+ //# sourceMappingURL=chunk-4LCZVJVF.js.map
@@ -29,7 +29,12 @@ function isProxyEligibleForRewrite(originalBaseUrl, proxyUrl) {
29
29
  return true;
30
30
  }
31
31
  function composeRewrittenUrl(originalBaseUrl, proxyUrl) {
32
- const parsedOriginal = new URL(originalBaseUrl);
32
+ let parsedOriginal;
33
+ try {
34
+ parsedOriginal = new URL(originalBaseUrl);
35
+ } catch {
36
+ return originalBaseUrl;
37
+ }
33
38
  const hostAndPath = `${parsedOriginal.host}${parsedOriginal.pathname}`;
34
39
  const trailingQuery = parsedOriginal.search || "";
35
40
  const trailingHash = parsedOriginal.hash || "";
@@ -38,6 +43,31 @@ function composeRewrittenUrl(originalBaseUrl, proxyUrl) {
38
43
  }
39
44
  var DEFAULT_PROXY_CONFIG = { enabled: false, url: "", active: false };
40
45
  var currentConfig = { ...DEFAULT_PROXY_CONFIG };
46
+ var proxyTransitionLogger;
47
+ function setProxyTransitionLogger(logger) {
48
+ proxyTransitionLogger = logger;
49
+ }
50
+ function sanitizeUrlForLog(raw) {
51
+ if (!raw) return "";
52
+ try {
53
+ const parsed = new URL(raw);
54
+ return `${parsed.protocol}//${parsed.host}${parsed.pathname}`;
55
+ } catch {
56
+ const cut = raw.search(/[?#\x00-\x1f\x7f]/);
57
+ return cut >= 0 ? raw.slice(0, cut) : raw;
58
+ }
59
+ }
60
+ function logProxyTransition(next, reason) {
61
+ const log = proxyTransitionLogger;
62
+ if (!log) return;
63
+ const url = sanitizeUrlForLog(currentConfig.url) || "<unset>";
64
+ const line = next ? `WrongProxy active=true (${reason}) \u2014 base-URL rewrites ON, proxy=${url}` : `WrongProxy active=false (${reason}) \u2014 base-URL rewrites OFF, proxy=${url}`;
65
+ try {
66
+ if (next) log.info(line);
67
+ else log.warn(line);
68
+ } catch {
69
+ }
70
+ }
41
71
  function getProxyConfig() {
42
72
  return currentConfig;
43
73
  }
@@ -94,6 +124,7 @@ function deactivateProxyOnConnectionFailure(err) {
94
124
  }
95
125
  function __resetProxyConfigForTests() {
96
126
  currentConfig = { ...DEFAULT_PROXY_CONFIG };
127
+ proxyTransitionLogger = void 0;
97
128
  listeners.clear();
98
129
  instantApplyChains.clear();
99
130
  }
@@ -170,6 +201,9 @@ export {
170
201
  PROXY_EXCLUDED_PROVIDERS,
171
202
  isProxyEligible,
172
203
  rewriteBaseUrl,
204
+ setProxyTransitionLogger,
205
+ sanitizeUrlForLog,
206
+ logProxyTransition,
173
207
  getProxyConfig,
174
208
  subscribeToProxyConfig,
175
209
  applyProxyConfig,
@@ -180,4 +214,4 @@ export {
180
214
  waitForProxyRoutingSettle,
181
215
  createProxyInstantApply
182
216
  };
183
- //# sourceMappingURL=chunk-4ZHTKJHM.js.map
217
+ //# sourceMappingURL=chunk-4SJNS7OB.js.map
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  ERROR_CODES,
3
3
  FsError
4
- } from "./chunk-WOEZV3Q4.js";
4
+ } from "./chunk-25LSLC3G.js";
5
5
 
6
6
  // src/utils/session-scoped-path.ts
7
7
  import * as path from "node:path";
8
8
  function sessionScopedPath(dir, sessionId, suffix) {
9
- if (!sessionId || sessionId.includes("\\") || sessionId.includes("..")) {
9
+ if (!sessionId || sessionId.includes("..") || sessionId.includes("\\")) {
10
10
  throw invalid(sessionId);
11
11
  }
12
12
  const resolved = path.resolve(dir, `${sessionId}${suffix}`);
@@ -43,4 +43,4 @@ export {
43
43
  sessionScopedPath,
44
44
  isSessionTranscriptFileName
45
45
  };
46
- //# sourceMappingURL=chunk-AD7ZFZCS.js.map
46
+ //# sourceMappingURL=chunk-5BMIE7QG.js.map
@@ -1,41 +1,41 @@
1
1
  import {
2
2
  decryptConfigSecrets
3
3
  } from "./chunk-YY6APYUM.js";
4
- import {
5
- DEFAULT_AUTONOMY_CONFIG,
6
- DEFAULT_CIRCUIT_BREAKER_CONFIG,
7
- DEFAULT_CONTEXT_CONFIG,
8
- DEFAULT_CONTEXT_WINDOW_MODE_ID,
9
- DEFAULT_SESSION_LOGGING_CONFIG,
10
- DEFAULT_TOOLS_CONFIG,
11
- isContextWindowModeSelectionId,
12
- listContextWindowModes,
13
- normalizeContextWindowModeId
14
- } from "./chunk-ZZ4V3WIZ.js";
15
4
  import {
16
5
  backupConfigFile
17
- } from "./chunk-CQQL4ZOQ.js";
6
+ } from "./chunk-ZT7JNIGX.js";
18
7
  import {
19
8
  safeParse
20
- } from "./chunk-RPOA7IAE.js";
9
+ } from "./chunk-W5VITDM2.js";
21
10
  import {
22
11
  FORBIDDEN_PROTO_KEYS,
23
12
  deepMerge
24
- } from "./chunk-DEIQMBD2.js";
13
+ } from "./chunk-B7F4WVP4.js";
25
14
  import {
26
15
  atomicWrite,
27
16
  withFileLock
28
- } from "./chunk-7ZHZE5EO.js";
17
+ } from "./chunk-OSGLYW5J.js";
29
18
  import {
30
19
  safeProfileName
31
- } from "./chunk-YNCVSFGF.js";
20
+ } from "./chunk-SAFHACFA.js";
21
+ import {
22
+ DEFAULT_AUTONOMY_CONFIG,
23
+ DEFAULT_CIRCUIT_BREAKER_CONFIG,
24
+ DEFAULT_CONTEXT_CONFIG,
25
+ DEFAULT_CONTEXT_WINDOW_MODE_ID,
26
+ DEFAULT_SESSION_LOGGING_CONFIG,
27
+ DEFAULT_TOOLS_CONFIG,
28
+ isContextWindowModeSelectionId,
29
+ listContextWindowModes,
30
+ normalizeContextWindowModeId
31
+ } from "./chunk-DLHHXUAM.js";
32
32
  import {
33
33
  DEFAULT_TUI_THINKING_WORD
34
34
  } from "./chunk-KJ2ZTQSL.js";
35
35
  import {
36
36
  ConfigError,
37
37
  ERROR_CODES
38
- } from "./chunk-WOEZV3Q4.js";
38
+ } from "./chunk-25LSLC3G.js";
39
39
  import {
40
40
  toErrorMessage
41
41
  } from "./chunk-TBRL2RCC.js";
@@ -66,7 +66,8 @@ var CONFIG_BEHAVIOR_DEFAULTS = {
66
66
  autoExtendLimit: DEFAULT_TOOLS_CONFIG.autoExtendLimit,
67
67
  restrictToProjectRoot: DEFAULT_TOOLS_CONFIG.restrictToProjectRoot,
68
68
  kanbanGovernance: DEFAULT_TOOLS_CONFIG.kanbanGovernance,
69
- loopDetection: DEFAULT_TOOLS_CONFIG.loopDetection
69
+ loopDetection: DEFAULT_TOOLS_CONFIG.loopDetection,
70
+ autoThin: { ...DEFAULT_TOOLS_CONFIG.autoThin }
70
71
  },
71
72
  log: { level: "info" },
72
73
  features: {
@@ -244,7 +245,8 @@ function repairConfigDefaults(input) {
244
245
  continue;
245
246
  }
246
247
  const defaultIsArray = Array.isArray(defaultValue);
247
- const compatible = defaultIsArray ? Array.isArray(current) : !Array.isArray(current) && typeof current === typeof defaultValue;
248
+ const defaultIsNumber = typeof defaultValue === "number";
249
+ const compatible = defaultIsArray ? Array.isArray(current) : defaultIsNumber ? typeof current === "number" && Number.isFinite(current) : !Array.isArray(current) && typeof current === typeof defaultValue;
248
250
  if (!compatible) {
249
251
  target[key] = cloneJsonValue(defaultValue);
250
252
  changes.push({ path: path2, action: "replaced" });
@@ -282,7 +284,8 @@ function envBoolOptional(v) {
282
284
  }
283
285
  var LOG_LEVELS = /* @__PURE__ */ new Set(["error", "warn", "info", "debug", "trace"]);
284
286
  function envLogLevel(v) {
285
- return LOG_LEVELS.has(v) ? v : "info";
287
+ const norm = v.trim().toLowerCase();
288
+ return LOG_LEVELS.has(norm) ? norm : "info";
286
289
  }
287
290
  var defaultIndexing = {
288
291
  onSessionStart: true,
@@ -339,6 +342,10 @@ var IN_PROJECT_ALLOWED_KEYS = /* @__PURE__ */ new Set([
339
342
  "autonomy",
340
343
  "indexing",
341
344
  "session",
345
+ // Journal retention. 'retentionDays' is clamped up to 7 on read precisely so
346
+ // a repo-committed config cannot flush recent evidence; 0 (auto-purge off)
347
+ // only ever keeps more.
348
+ "chronicle",
342
349
  "log",
343
350
  "launch",
344
351
  "nextPrediction",
@@ -347,6 +354,10 @@ var IN_PROJECT_ALLOWED_KEYS = /* @__PURE__ */ new Set([
347
354
  "configScope",
348
355
  "maxConcurrent",
349
356
  "uiLocale",
357
+ // Cosmetic only: the TUI owns the canonical preset list and falls back to
358
+ // 'catppuccin' for an unknown value, so the worst a repo can do is pick a
359
+ // colour scheme.
360
+ "themePreset",
350
361
  "fallbackModels",
351
362
  "fallbackBridge",
352
363
  "fallbackProfiles",
@@ -359,8 +370,17 @@ var IN_PROJECT_ALLOWED_KEYS = /* @__PURE__ */ new Set([
359
370
  "modelAvailabilitySchedule",
360
371
  "fallbackAuto",
361
372
  "fallbackStickiness",
373
+ // The countdown before the UI auto-accepts the next fallback candidate.
374
+ // Grants a repo nothing it does not already have: 'fallbackModels' and
375
+ // 'fallbackProfiles' above already let it choose the candidate itself.
376
+ "fallbackGateSeconds",
362
377
  "models",
363
378
  "modelMatrix",
379
+ // Same class as 'modelMatrix' and 'fallbackProfiles' directly above: a tier
380
+ // only NAMES a profile/provider/model the user already configured, and its
381
+ // budget fields (maxCostUsd / maxIterations / timeoutMs) can only clamp a
382
+ // subagent DOWNWARD. No credential or exec surface.
383
+ "modelTiers",
364
384
  "circuitBreaker",
365
385
  "adaptiveConcurrency",
366
386
  "modelRuntime"
@@ -387,6 +407,10 @@ var KNOWN_DENIED_IN_PROJECT = [
387
407
  reason: "Carries the my.wrongstack.com machine token credential and endpoint URL."
388
408
  },
389
409
  { key: "yolo", reason: "Disables all permission confirmation prompts." },
410
+ {
411
+ key: "systemPrompt",
412
+ reason: "Selects the baseline identity prompt. The 'lite' variant drops whole sections of system.md \u2014 including 'Tool output trust boundary', the passage that tells the agent not to obey instructions found in repo content. A repo-committed config could therefore switch off the very rule that protects the user from that repo."
413
+ },
390
414
  { key: "extensions", reason: "Per-plugin config can carry command/credential fields." },
391
415
  { key: "hq", reason: "Carries HQ client token credential and endpoint URL." },
392
416
  { key: "acp", reason: "Per-agent ACP command/args/env override \u2192 arbitrary command exec (RCE)." },
@@ -407,7 +431,7 @@ var KNOWN_DENIED_IN_PROJECT = [
407
431
  reason: "Bounds how many of the user's OTHER configured providers may be swept in as last-resort failover. Setting it to 0 from a repo-committed config would silently strip that depth during an outage. It was already stripped in practice (absent from the allow-list) but was missing from the key registry, so this gate never checked it."
408
432
  }
409
433
  ];
410
- var KNOWN_CONFIG_TOP_LEVEL_KEYS = /* @__PURE__ */ new Set([
434
+ var KNOWN_CONFIG_TOP_LEVEL_KEY_LIST = [
411
435
  "version",
412
436
  "activeProfile",
413
437
  "provider",
@@ -459,8 +483,16 @@ var KNOWN_CONFIG_TOP_LEVEL_KEYS = /* @__PURE__ */ new Set([
459
483
  "acp",
460
484
  "fleet",
461
485
  "brain",
462
- "git"
463
- ]);
486
+ "git",
487
+ "themePreset",
488
+ "modelTiers",
489
+ "fallbackGateSeconds",
490
+ "chronicle",
491
+ "systemPrompt"
492
+ ];
493
+ var KNOWN_CONFIG_TOP_LEVEL_KEYS = new Set(
494
+ KNOWN_CONFIG_TOP_LEVEL_KEY_LIST
495
+ );
464
496
  var IN_PROJECT_DENIED_PATHS = [
465
497
  {
466
498
  path: "tools.exec.allow",
@@ -518,6 +550,21 @@ var IN_PROJECT_DENIED_PATHS = [
518
550
  path: "tools.kanbanGovernance",
519
551
  reason: "Repo-committed config could disable a Kanban governance gate the operator switched on, letting product mutations run outside any managed card."
520
552
  },
553
+ {
554
+ // The whole subtree, not just `enabled`: a repo could ship
555
+ // `tools.autoThin = { enabled: true, idleDays: 0, minInvocations: 999 }`
556
+ // and disable every tool the operator wants, on first boot, before any
557
+ // user-facing dry-run. Same operator-owned class as `tools.exec.allow`.
558
+ path: "tools.autoThin",
559
+ reason: "Stats-driven tool auto-thinning is an operator decision: a repo-committed config could disable tools the operator wants by shipping a permissive threshold."
560
+ },
561
+ {
562
+ // The audit-trail parallel of `disabledTools`. A repo could otherwise
563
+ // downgrade every user disable to `auto-thinned`, hiding operator intent
564
+ // in `/tool autothin status` and undoing it en masse.
565
+ path: "tools.disabledToolMeta",
566
+ reason: "Disabled-tool audit-trail metadata; a repo-committed entry could obscure operator-authored disables as auto-thinned."
567
+ },
521
568
  {
522
569
  // The bridge spawn path resolves the CLI entry by walking UP from the
523
570
  // project root, so a repo that ships its own `packages/cli/dist/index.js`
@@ -1393,4 +1440,4 @@ export {
1393
1440
  normalizeInlineProviderModels,
1394
1441
  DefaultConfigLoader
1395
1442
  };
1396
- //# sourceMappingURL=chunk-IQ35HMQL.js.map
1443
+ //# sourceMappingURL=chunk-5YPSXQXM.js.map
@@ -0,0 +1,10 @@
1
+ // src/security/file-permissions.ts
2
+ import { restrictDirPermissions, restrictFilePermissions, SECRET_DIR_MODE, SECRET_FILE_MODE } from "@wrongstack/persistence";
3
+
4
+ export {
5
+ restrictDirPermissions,
6
+ restrictFilePermissions,
7
+ SECRET_DIR_MODE,
8
+ SECRET_FILE_MODE
9
+ };
10
+ //# sourceMappingURL=chunk-6FHWXLPT.js.map
@@ -1,30 +1,43 @@
1
1
  import {
2
2
  toolMutates
3
- } from "./chunk-ZEHUCJHY.js";
3
+ } from "./chunk-JFPJ6LLQ.js";
4
4
  import {
5
5
  allServers
6
6
  } from "./chunk-FXQLIX3K.js";
7
7
  import {
8
8
  resolvePluginEnablement
9
9
  } from "./chunk-3XPVB7BA.js";
10
+ import {
11
+ activeTierConfig,
12
+ evaluateLeaderTierSwitch,
13
+ isValidMatrixKey,
14
+ leaderTierPolicy,
15
+ listTierIds,
16
+ phaseForRole,
17
+ resolveSubagentModelTarget,
18
+ resolveTier
19
+ } from "./chunk-RTOTNK3P.js";
10
20
  import {
11
21
  CouncilOrchestrator,
12
22
  DEFAULT_COUNCIL_PROFILE_REGISTRY,
13
23
  OneShotOrchestrator,
14
24
  validateCouncilOptions
15
- } from "./chunk-CE4ZOCOI.js";
16
- import {
17
- isValidMatrixKey,
18
- phaseForRole,
19
- resolveSubagentModelTarget
20
- } from "./chunk-2BUUIMQB.js";
25
+ } from "./chunk-PFCMSSUF.js";
21
26
  import {
22
27
  AGENT_CATALOG
23
- } from "./chunk-FHAMQS7Q.js";
28
+ } from "./chunk-FCBTO76Z.js";
29
+ import {
30
+ mcpQualifiedToolName,
31
+ mcpServerToolPrefix,
32
+ readJsonObjectFile,
33
+ setJsonPath,
34
+ updateJsonObjectFile,
35
+ validateAgainstSchema
36
+ } from "./chunk-YPT4A46F.js";
24
37
  import {
25
38
  ToolCapabilities,
26
39
  getDangerousCapabilities
27
- } from "./chunk-A455ATZB.js";
40
+ } from "./chunk-UBGDX6FI.js";
28
41
  import {
29
42
  normalizeModelRef,
30
43
  parseModelRef
@@ -33,19 +46,11 @@ import {
33
46
  GOVERNED_TOOL_EXECUTOR_META_KEY
34
47
  } from "./chunk-XBDP4QPW.js";
35
48
  import {
36
- mcpQualifiedToolName,
37
- mcpServerToolPrefix,
38
- readJsonObjectFile,
39
- setJsonPath,
40
- updateJsonObjectFile,
41
- validateAgainstSchema
42
- } from "./chunk-FFSX2QDQ.js";
49
+ expectDefined
50
+ } from "./chunk-PFZO3C6H.js";
43
51
  import {
44
52
  toErrorMessage
45
53
  } from "./chunk-TBRL2RCC.js";
46
- import {
47
- expectDefined
48
- } from "./chunk-PFZO3C6H.js";
49
54
 
50
55
  // src/tools/council-tool.ts
51
56
  var COUNCIL_TOOL_NAME = "council";
@@ -1406,6 +1411,143 @@ ${content}`);
1406
1411
  };
1407
1412
  }
1408
1413
 
1414
+ // src/tools/model-tier-set-tool.ts
1415
+ var LEADER_TIER_SET_TOOL_NAME = "leader_tier_set";
1416
+ var SCHEMA = {
1417
+ type: "object",
1418
+ properties: {
1419
+ action: {
1420
+ type: "string",
1421
+ enum: ["show", "set"],
1422
+ description: "show \u2014 the active tier, every configured level and what it resolves to, plus the switch policy. set \u2014 request a move to another tier."
1423
+ },
1424
+ tier: {
1425
+ type: "string",
1426
+ description: 'Target tier id for "set" (e.g. "budget", "standard", "premium").'
1427
+ },
1428
+ reason: {
1429
+ type: "string",
1430
+ description: "Why the switch is warranted, in one sentence. Shown to the user in propose mode, so say what about the work changed \u2014 not just that a cheaper model exists."
1431
+ }
1432
+ },
1433
+ required: ["action"],
1434
+ additionalProperties: false
1435
+ };
1436
+ function createModelTierSetTool(opts) {
1437
+ return {
1438
+ name: LEADER_TIER_SET_TOOL_NAME,
1439
+ description: `Inspect or change the leader's own cost tier (e.g. "budget" | "standard" | "premium"). Use "set" when the nature of the work has changed enough to justify a different class of model \u2014 dropping to a cheap tier for mechanical work, or asking for an expensive one when a decision is genuinely hard. Every request is checked against the user's guard rails (minimum dwell between switches, target context window, spend ceiling, and whether the saving covers the prompt-cache re-warm the switch causes). By default an allowed switch is PROPOSED to the user rather than applied.`,
1440
+ usageHint: 'Start with {action:"show"} to see the levels and the policy. Then {action:"set", tier, reason}. A refusal explains which guard rejected it; do not retry the same switch immediately.',
1441
+ category: "config",
1442
+ inputSchema: SCHEMA,
1443
+ permission: "auto",
1444
+ mutating: true,
1445
+ riskTier: "standard",
1446
+ icon: "settings",
1447
+ async execute(input) {
1448
+ const config = opts.getConfig();
1449
+ const tiers = activeTierConfig(config);
1450
+ if (!tiers) {
1451
+ return {
1452
+ status: "error",
1453
+ message: "The model-tier layer is not enabled. Set `modelTiers.enabled = true` and define `modelTiers.levels` first."
1454
+ };
1455
+ }
1456
+ const currentTier = opts.getCurrentTier?.();
1457
+ const policy = leaderTierPolicy(config);
1458
+ if (input.action === "show") {
1459
+ const lines = [
1460
+ ` active tier: ${currentTier ?? "(unset \u2014 routing table decides per spawn)"}`,
1461
+ ` leader mode: ${policy.mode}`,
1462
+ ` dwell: ${policy.dwellTurns} turn(s) \xB7 min saving: $${policy.minSavingsUsd} \xB7 context-fill cap: ${Math.round(policy.maxContextFillForSwitch * 100)}%` + (policy.maxTier ? ` \xB7 ceiling: ${policy.maxTier}` : ""),
1463
+ ""
1464
+ ];
1465
+ for (const id of listTierIds(config)) {
1466
+ const resolved2 = resolveTier(config, { tier: id });
1467
+ const target = resolved2?.model ? `${resolved2.provider ?? config.provider}/${resolved2.model}` : "(no model \u2014 profile empty or unresolvable)";
1468
+ const budget = resolved2?.budget ?? {};
1469
+ const budgetBits = [
1470
+ budget.maxCostUsd !== void 0 ? `$${budget.maxCostUsd}` : "",
1471
+ budget.maxIterations !== void 0 ? `${budget.maxIterations} iters` : "",
1472
+ budget.maxToolCalls !== void 0 ? `${budget.maxToolCalls} tools` : ""
1473
+ ].filter(Boolean);
1474
+ lines.push(
1475
+ ` ${id}${id === currentTier ? " *" : ""}: ${target}` + (budgetBits.length ? ` [${budgetBits.join(" \xB7 ")}]` : "")
1476
+ );
1477
+ }
1478
+ return { status: "ok", message: lines.join("\n") };
1479
+ }
1480
+ if (!input.tier) {
1481
+ return { status: "error", message: 'Provide "tier" for the "set" action.' };
1482
+ }
1483
+ const resolved = resolveTier(config, { tier: input.tier });
1484
+ if (!resolved?.model) {
1485
+ const available = listTierIds(config);
1486
+ return {
1487
+ status: "error",
1488
+ message: `Tier "${input.tier}" does not resolve to a model${available.length ? ` (configured tiers: ${available.join(", ")})` : ""}.`
1489
+ };
1490
+ }
1491
+ const targetProvider = resolved.provider ?? config.provider;
1492
+ const targetModel = resolved.model;
1493
+ const contextTokens = opts.getContextTokens?.();
1494
+ const haveContext = typeof contextTokens === "number" && contextTokens > 0;
1495
+ const [fromEconomics, toEconomics] = haveContext ? await Promise.all([
1496
+ opts.getModelEconomics?.(config.provider, config.model) ?? Promise.resolve(void 0),
1497
+ opts.getModelEconomics?.(targetProvider, targetModel) ?? Promise.resolve(void 0)
1498
+ ]) : [void 0, void 0];
1499
+ const verdict = evaluateLeaderTierSwitch(config, {
1500
+ ...currentTier ? { fromTier: currentTier } : {},
1501
+ toTier: input.tier,
1502
+ contextTokens: haveContext ? contextTokens : 0,
1503
+ // A host that does not track switches must not be permanently blocked
1504
+ // by the dwell guard, so an unknown count reads as "long ago".
1505
+ turnsSinceSwitch: opts.getTurnsSinceTierSwitch?.() ?? Number.MAX_SAFE_INTEGER,
1506
+ economics: { from: fromEconomics ?? {}, to: toEconomics ?? {} }
1507
+ });
1508
+ if (!verdict.allowed) {
1509
+ return { status: "error", message: `Refused (${verdict.code}): ${verdict.reason}` };
1510
+ }
1511
+ const proposal = {
1512
+ fromTier: currentTier,
1513
+ toTier: input.tier,
1514
+ target: { provider: targetProvider, model: targetModel },
1515
+ reason: input.reason?.trim() || verdict.reason,
1516
+ projectedSavingsUsd: verdict.economics.projectedSavingsUsd,
1517
+ reWarmCostUsd: verdict.economics.reWarmCostUsd
1518
+ };
1519
+ if (verdict.mode === "propose") {
1520
+ await opts.onTierProposed?.(proposal);
1521
+ return {
1522
+ status: "proposed",
1523
+ message: `Proposed: ${currentTier ?? "current"} \u2192 ${input.tier} (${targetProvider}/${targetModel}). ${verdict.reason} Awaiting the user \u2014 the model has NOT been changed. Set \`modelTiers.leader.mode = "auto"\` to let this apply without asking.`
1524
+ };
1525
+ }
1526
+ if (opts.switchProviderAndModel) {
1527
+ const switchError = await opts.switchProviderAndModel(targetProvider, targetModel);
1528
+ if (switchError) {
1529
+ return {
1530
+ status: "error",
1531
+ message: `Could not switch to ${targetProvider}/${targetModel}: ${switchError}. Config was not changed.`
1532
+ };
1533
+ }
1534
+ }
1535
+ await opts.updateConfig((cfg) => {
1536
+ cfg["provider"] = targetProvider;
1537
+ cfg["model"] = targetModel;
1538
+ if (resolved.fallbackModels?.length) cfg["fallbackModels"] = [...resolved.fallbackModels];
1539
+ });
1540
+ opts.onTierSwitched?.(input.tier);
1541
+ const liveNote = opts.switchProviderAndModel ? "" : " (config updated \u2014 the live session keeps its current model until restart or /setmodel)";
1542
+ return {
1543
+ status: "ok",
1544
+ message: `\u2713 Leader tier \u2192 ${input.tier} (${targetProvider}/${targetModel})${liveNote}
1545
+ ${verdict.reason}`
1546
+ };
1547
+ }
1548
+ };
1549
+ }
1550
+
1409
1551
  // src/tools/fallback-manage-tools.ts
1410
1552
  function createFallbackManageTools(opts) {
1411
1553
  return [
@@ -1416,6 +1558,7 @@ function createFallbackManageTools(opts) {
1416
1558
  createProviderManageTool(opts),
1417
1559
  createProviderKeySetTool(opts),
1418
1560
  createLeaderModelSetTool(opts),
1561
+ createModelTierSetTool(opts),
1419
1562
  createSystemConfigViewTool(opts)
1420
1563
  ];
1421
1564
  }
@@ -2260,4 +2403,4 @@ export {
2260
2403
  PLUGIN_MANAGER_TOOL_NAME,
2261
2404
  createPluginManagerTool
2262
2405
  };
2263
- //# sourceMappingURL=chunk-FIV4IJL7.js.map
2406
+ //# sourceMappingURL=chunk-6H5GEOET.js.map
@@ -138,7 +138,7 @@ function buildChildEnv(optsOrSessionId) {
138
138
  if (opts.extra) {
139
139
  Object.assign(out, opts.extra);
140
140
  }
141
- if (opts.sessionId) out["WRONGSTACK_SESSION_ID"] = opts.sessionId;
141
+ if (opts.sessionId) out["WRONGSTACK_SESSION_ID"] = opts.sessionId.replace(/\\/g, "/");
142
142
  return out;
143
143
  }
144
144
 
@@ -148,4 +148,4 @@ export {
148
148
  getChildEnvGitIdentity,
149
149
  buildChildEnv
150
150
  };
151
- //# sourceMappingURL=chunk-VB3H5WWB.js.map
151
+ //# sourceMappingURL=chunk-6NWEVFEL.js.map