@coool/opencode-adaptive 1.0.0 → 1.0.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 (380) hide show
  1. package/README.md +8 -7
  2. package/dist/adapters/codex-capacity/index.d.ts +0 -1
  3. package/dist/adapters/codex-capacity/index.js.map +1 -1
  4. package/dist/adapters/codex-capacity/parse.d.ts +2 -2
  5. package/dist/adapters/codex-capacity/parse.js +19 -3
  6. package/dist/adapters/codex-capacity/parse.js.map +1 -1
  7. package/dist/adapters/codex-capacity/reading.d.ts +0 -1
  8. package/dist/adapters/codex-capacity/reading.js.map +1 -1
  9. package/dist/adapters/codex-capacity/sensor.d.ts +0 -1
  10. package/dist/adapters/codex-capacity/sensor.js.map +1 -1
  11. package/dist/adapters/codex-capacity/types.d.ts +0 -4
  12. package/dist/adapters/codex-capacity/types.js +14 -0
  13. package/dist/adapters/codex-capacity/types.js.map +1 -1
  14. package/dist/adapters/opencode/escalation-tool.d.ts +0 -1
  15. package/dist/adapters/opencode/escalation-tool.js +5 -3
  16. package/dist/adapters/opencode/escalation-tool.js.map +1 -1
  17. package/dist/adapters/opencode/events.d.ts +0 -1
  18. package/dist/adapters/opencode/events.js.map +1 -1
  19. package/dist/adapters/opencode/hooks.d.ts +0 -1
  20. package/dist/adapters/opencode/hooks.js +24 -7
  21. package/dist/adapters/opencode/hooks.js.map +1 -1
  22. package/dist/adapters/opencode/index.d.ts +0 -1
  23. package/dist/adapters/opencode/index.js.map +1 -1
  24. package/dist/adapters/opencode/inventory.d.ts +0 -1
  25. package/dist/adapters/opencode/inventory.js.map +1 -1
  26. package/dist/adapters/opencode/report.d.ts +0 -1
  27. package/dist/adapters/opencode/report.js.map +1 -1
  28. package/dist/adapters/opencode/session-ops.d.ts +0 -1
  29. package/dist/adapters/opencode/session-ops.js.map +1 -1
  30. package/dist/adapters/opencode/storage.d.ts +0 -1
  31. package/dist/adapters/opencode/storage.js.map +1 -1
  32. package/dist/adapters/opencode/tier-tool.d.ts +0 -1
  33. package/dist/adapters/opencode/tier-tool.js.map +1 -1
  34. package/dist/adapters/opencode/types.d.ts +0 -1
  35. package/dist/adapters/opencode/types.js.map +1 -1
  36. package/dist/core/compatibility/gate.d.ts +0 -3
  37. package/dist/core/compatibility/gate.js +0 -4
  38. package/dist/core/compatibility/gate.js.map +1 -1
  39. package/dist/core/compatibility/index.d.ts +0 -1
  40. package/dist/core/compatibility/index.js.map +1 -1
  41. package/dist/core/compatibility/types.d.ts +0 -1
  42. package/dist/core/compatibility/types.js.map +1 -1
  43. package/dist/core/scheduler/admit.d.ts +0 -1
  44. package/dist/core/scheduler/admit.js +22 -21
  45. package/dist/core/scheduler/admit.js.map +1 -1
  46. package/dist/core/scheduler/escalate.d.ts +0 -1
  47. package/dist/core/scheduler/escalate.js +6 -17
  48. package/dist/core/scheduler/escalate.js.map +1 -1
  49. package/dist/core/scheduler/index.d.ts +0 -1
  50. package/dist/core/scheduler/index.js.map +1 -1
  51. package/dist/core/scheduler/mode.d.ts +0 -1
  52. package/dist/core/scheduler/mode.js.map +1 -1
  53. package/dist/core/scheduler/types.d.ts +2 -9
  54. package/dist/core/scheduler/types.js +2 -1
  55. package/dist/core/scheduler/types.js.map +1 -1
  56. package/dist/core/tier-policy/index.d.ts +0 -1
  57. package/dist/core/tier-policy/index.js.map +1 -1
  58. package/dist/core/tier-policy/resolve.d.ts +0 -1
  59. package/dist/core/tier-policy/resolve.js.map +1 -1
  60. package/dist/core/tier-policy/tier-list.d.ts +0 -1
  61. package/dist/core/tier-policy/tier-list.js.map +1 -1
  62. package/dist/core/tier-policy/types.d.ts +2 -1
  63. package/dist/core/tier-policy/types.js +4 -0
  64. package/dist/core/tier-policy/types.js.map +1 -1
  65. package/dist/core/work-unit/index.d.ts +0 -1
  66. package/dist/core/work-unit/index.js.map +1 -1
  67. package/dist/core/work-unit/interruption.d.ts +0 -1
  68. package/dist/core/work-unit/interruption.js.map +1 -1
  69. package/dist/core/work-unit/tracker.d.ts +11 -4
  70. package/dist/core/work-unit/tracker.js +26 -6
  71. package/dist/core/work-unit/tracker.js.map +1 -1
  72. package/dist/core/work-unit/types.d.ts +6 -1
  73. package/dist/core/work-unit/types.js.map +1 -1
  74. package/dist/execution/continuation/execute.d.ts +0 -1
  75. package/dist/execution/continuation/execute.js.map +1 -1
  76. package/dist/execution/continuation/index.d.ts +0 -2
  77. package/dist/execution/continuation/index.js +0 -1
  78. package/dist/execution/continuation/index.js.map +1 -1
  79. package/dist/execution/continuation/plan.d.ts +0 -1
  80. package/dist/execution/continuation/plan.js +1 -3
  81. package/dist/execution/continuation/plan.js.map +1 -1
  82. package/dist/execution/continuation/prompts.d.ts +0 -1
  83. package/dist/execution/continuation/prompts.js.map +1 -1
  84. package/dist/execution/continuation/types.d.ts +0 -2
  85. package/dist/execution/continuation/types.js.map +1 -1
  86. package/dist/execution/escalation/index.d.ts +0 -1
  87. package/dist/execution/escalation/index.js.map +1 -1
  88. package/dist/execution/escalation/types.d.ts +0 -1
  89. package/dist/execution/escalation/types.js.map +1 -1
  90. package/dist/execution/index.d.ts +0 -1
  91. package/dist/execution/index.js.map +1 -1
  92. package/dist/execution/parking/index.d.ts +0 -1
  93. package/dist/execution/parking/index.js.map +1 -1
  94. package/dist/execution/parking/plan.d.ts +0 -1
  95. package/dist/execution/parking/plan.js.map +1 -1
  96. package/dist/execution/retry/decide.d.ts +0 -1
  97. package/dist/execution/retry/decide.js +1 -2
  98. package/dist/execution/retry/decide.js.map +1 -1
  99. package/dist/execution/retry/index.d.ts +0 -1
  100. package/dist/execution/retry/index.js.map +1 -1
  101. package/dist/execution/retry/types.d.ts +0 -2
  102. package/dist/execution/retry/types.js.map +1 -1
  103. package/dist/gui-experimental.cjs +1 -1
  104. package/dist/gui.d.ts +0 -1
  105. package/dist/gui.js +6 -3
  106. package/dist/gui.js.map +1 -1
  107. package/dist/health/capacity/index.d.ts +0 -1
  108. package/dist/health/capacity/index.js.map +1 -1
  109. package/dist/health/capacity/merge.d.ts +0 -1
  110. package/dist/health/capacity/merge.js.map +1 -1
  111. package/dist/health/capacity/registry.d.ts +0 -1
  112. package/dist/health/capacity/registry.js.map +1 -1
  113. package/dist/health/capacity/types.d.ts +0 -1
  114. package/dist/health/capacity/types.js.map +1 -1
  115. package/dist/health/circuit-breaker/breaker.d.ts +8 -1
  116. package/dist/health/circuit-breaker/breaker.js +18 -0
  117. package/dist/health/circuit-breaker/breaker.js.map +1 -1
  118. package/dist/health/circuit-breaker/index.d.ts +0 -1
  119. package/dist/health/circuit-breaker/index.js.map +1 -1
  120. package/dist/health/circuit-breaker/types.d.ts +0 -1
  121. package/dist/health/circuit-breaker/types.js.map +1 -1
  122. package/dist/health/classifier/classify.d.ts +0 -1
  123. package/dist/health/classifier/classify.js.map +1 -1
  124. package/dist/health/classifier/index.d.ts +0 -1
  125. package/dist/health/classifier/index.js.map +1 -1
  126. package/dist/health/classifier/types.d.ts +0 -1
  127. package/dist/health/classifier/types.js.map +1 -1
  128. package/dist/health/index.d.ts +0 -1
  129. package/dist/health/index.js.map +1 -1
  130. package/dist/health/resource-health/index.d.ts +0 -1
  131. package/dist/health/resource-health/index.js.map +1 -1
  132. package/dist/health/resource-health/key.d.ts +0 -1
  133. package/dist/health/resource-health/key.js.map +1 -1
  134. package/dist/health/resource-health/registry.d.ts +6 -1
  135. package/dist/health/resource-health/registry.js +19 -1
  136. package/dist/health/resource-health/registry.js.map +1 -1
  137. package/dist/health/resource-health/transitions.d.ts +2 -4
  138. package/dist/health/resource-health/transitions.js +10 -18
  139. package/dist/health/resource-health/transitions.js.map +1 -1
  140. package/dist/health/resource-health/types.d.ts +7 -1
  141. package/dist/health/resource-health/types.js +1 -0
  142. package/dist/health/resource-health/types.js.map +1 -1
  143. package/dist/index.d.ts +0 -6
  144. package/dist/index.js +44 -19
  145. package/dist/index.js.map +1 -1
  146. package/dist/plugin-id.d.ts +0 -1
  147. package/dist/plugin-id.js.map +1 -1
  148. package/dist/rpc/definition.d.ts +24 -1
  149. package/dist/rpc/definition.js +28 -2
  150. package/dist/rpc/definition.js.map +1 -1
  151. package/dist/rpc/handlers.d.ts +12 -24
  152. package/dist/rpc/handlers.js +22 -8
  153. package/dist/rpc/handlers.js.map +1 -1
  154. package/dist/rpc/status.d.ts +0 -1
  155. package/dist/rpc/status.js.map +1 -1
  156. package/dist/rpc.d.ts +0 -1
  157. package/dist/rpc.js.map +1 -1
  158. package/dist/state/capacity/index.d.ts +0 -1
  159. package/dist/state/capacity/index.js.map +1 -1
  160. package/dist/state/capacity/parse.d.ts +0 -1
  161. package/dist/state/capacity/parse.js +14 -2
  162. package/dist/state/capacity/parse.js.map +1 -1
  163. package/dist/state/capacity/store.d.ts +0 -1
  164. package/dist/state/capacity/store.js +16 -2
  165. package/dist/state/capacity/store.js.map +1 -1
  166. package/dist/state/capacity/types.d.ts +0 -1
  167. package/dist/state/capacity/types.js.map +1 -1
  168. package/dist/state/health/index.d.ts +0 -1
  169. package/dist/state/health/index.js.map +1 -1
  170. package/dist/state/health/parse.d.ts +0 -1
  171. package/dist/state/health/parse.js +20 -4
  172. package/dist/state/health/parse.js.map +1 -1
  173. package/dist/state/health/store.d.ts +0 -1
  174. package/dist/state/health/store.js +16 -2
  175. package/dist/state/health/store.js.map +1 -1
  176. package/dist/state/health/types.d.ts +0 -1
  177. package/dist/state/health/types.js.map +1 -1
  178. package/dist/state/parked-work/index.d.ts +0 -1
  179. package/dist/state/parked-work/index.js.map +1 -1
  180. package/dist/state/parked-work/parse.d.ts +0 -1
  181. package/dist/state/parked-work/parse.js.map +1 -1
  182. package/dist/state/parked-work/store.d.ts +0 -1
  183. package/dist/state/parked-work/store.js +20 -3
  184. package/dist/state/parked-work/store.js.map +1 -1
  185. package/dist/state/parked-work/types.d.ts +0 -1
  186. package/dist/state/parked-work/types.js.map +1 -1
  187. package/dist/state/receipts/bound.d.ts +0 -1
  188. package/dist/state/receipts/bound.js.map +1 -1
  189. package/dist/state/receipts/index.d.ts +0 -1
  190. package/dist/state/receipts/index.js.map +1 -1
  191. package/dist/state/receipts/parse.d.ts +0 -1
  192. package/dist/state/receipts/parse.js.map +1 -1
  193. package/dist/state/receipts/store.d.ts +0 -1
  194. package/dist/state/receipts/store.js +24 -4
  195. package/dist/state/receipts/store.js.map +1 -1
  196. package/dist/state/receipts/types.d.ts +0 -1
  197. package/dist/state/receipts/types.js.map +1 -1
  198. package/dist/state/session-modes/index.d.ts +0 -1
  199. package/dist/state/session-modes/index.js.map +1 -1
  200. package/dist/state/session-modes/parse.d.ts +0 -1
  201. package/dist/state/session-modes/parse.js.map +1 -1
  202. package/dist/state/session-modes/store.d.ts +0 -1
  203. package/dist/state/session-modes/store.js +15 -1
  204. package/dist/state/session-modes/store.js.map +1 -1
  205. package/dist/state/session-modes/types.d.ts +0 -1
  206. package/dist/state/session-modes/types.js.map +1 -1
  207. package/dist/state/settings/index.d.ts +0 -1
  208. package/dist/state/settings/index.js.map +1 -1
  209. package/dist/state/settings/parse.d.ts +0 -1
  210. package/dist/state/settings/parse.js.map +1 -1
  211. package/dist/state/settings/store.d.ts +0 -1
  212. package/dist/state/settings/store.js +9 -1
  213. package/dist/state/settings/store.js.map +1 -1
  214. package/dist/state/settings/types.d.ts +0 -1
  215. package/dist/state/settings/types.js.map +1 -1
  216. package/dist/state/tier-requests/index.d.ts +4 -0
  217. package/dist/state/tier-requests/index.js +4 -0
  218. package/dist/state/tier-requests/index.js.map +1 -0
  219. package/dist/state/tier-requests/parse.d.ts +3 -0
  220. package/dist/state/tier-requests/parse.js +53 -0
  221. package/dist/state/tier-requests/parse.js.map +1 -0
  222. package/dist/state/tier-requests/store.d.ts +27 -0
  223. package/dist/state/tier-requests/store.js +96 -0
  224. package/dist/state/tier-requests/store.js.map +1 -0
  225. package/dist/state/tier-requests/types.d.ts +30 -0
  226. package/dist/state/tier-requests/types.js +7 -0
  227. package/dist/state/tier-requests/types.js.map +1 -0
  228. package/dist/supervisor/index.d.ts +0 -1
  229. package/dist/supervisor/index.js.map +1 -1
  230. package/dist/supervisor/log.d.ts +0 -1
  231. package/dist/supervisor/log.js.map +1 -1
  232. package/dist/supervisor/supervisor.d.ts +23 -6
  233. package/dist/supervisor/supervisor.js +397 -111
  234. package/dist/supervisor/supervisor.js.map +1 -1
  235. package/dist/supervisor/types.d.ts +0 -1
  236. package/dist/supervisor/types.js.map +1 -1
  237. package/dist/supervisor/view.d.ts +0 -1
  238. package/dist/supervisor/view.js.map +1 -1
  239. package/dist/tui.d.ts +0 -1
  240. package/dist/tui.js +14 -10
  241. package/dist/tui.js.map +1 -1
  242. package/dist/ui/gui/api.d.ts +0 -1
  243. package/dist/ui/gui/api.js.map +1 -1
  244. package/dist/ui/gui/view.d.ts +0 -1
  245. package/dist/ui/gui/view.js.map +1 -1
  246. package/dist/ui/tui/controller.d.ts +0 -1
  247. package/dist/ui/tui/controller.js +28 -12
  248. package/dist/ui/tui/controller.js.map +1 -1
  249. package/dist/ui/tui/menu.d.ts +1 -2
  250. package/dist/ui/tui/menu.js +2 -2
  251. package/dist/ui/tui/menu.js.map +1 -1
  252. package/dist/ui/tui/options.d.ts +0 -1
  253. package/dist/ui/tui/options.js.map +1 -1
  254. package/dist/ui/tui/receipts.d.ts +0 -1
  255. package/dist/ui/tui/receipts.js +4 -1
  256. package/dist/ui/tui/receipts.js.map +1 -1
  257. package/dist/ui/tui/status.d.ts +1 -2
  258. package/dist/ui/tui/status.js +4 -2
  259. package/dist/ui/tui/status.js.map +1 -1
  260. package/dist/ui/tui/tiers.d.ts +0 -1
  261. package/dist/ui/tui/tiers.js.map +1 -1
  262. package/package.json +2 -2
  263. package/dist/adapters/codex-capacity/index.d.ts.map +0 -1
  264. package/dist/adapters/codex-capacity/parse.d.ts.map +0 -1
  265. package/dist/adapters/codex-capacity/reading.d.ts.map +0 -1
  266. package/dist/adapters/codex-capacity/sensor.d.ts.map +0 -1
  267. package/dist/adapters/codex-capacity/types.d.ts.map +0 -1
  268. package/dist/adapters/opencode/escalation-tool.d.ts.map +0 -1
  269. package/dist/adapters/opencode/events.d.ts.map +0 -1
  270. package/dist/adapters/opencode/hooks.d.ts.map +0 -1
  271. package/dist/adapters/opencode/index.d.ts.map +0 -1
  272. package/dist/adapters/opencode/inventory.d.ts.map +0 -1
  273. package/dist/adapters/opencode/report.d.ts.map +0 -1
  274. package/dist/adapters/opencode/session-ops.d.ts.map +0 -1
  275. package/dist/adapters/opencode/storage.d.ts.map +0 -1
  276. package/dist/adapters/opencode/tier-tool.d.ts.map +0 -1
  277. package/dist/adapters/opencode/types.d.ts.map +0 -1
  278. package/dist/core/compatibility/gate.d.ts.map +0 -1
  279. package/dist/core/compatibility/index.d.ts.map +0 -1
  280. package/dist/core/compatibility/types.d.ts.map +0 -1
  281. package/dist/core/scheduler/admit.d.ts.map +0 -1
  282. package/dist/core/scheduler/escalate.d.ts.map +0 -1
  283. package/dist/core/scheduler/index.d.ts.map +0 -1
  284. package/dist/core/scheduler/mode.d.ts.map +0 -1
  285. package/dist/core/scheduler/types.d.ts.map +0 -1
  286. package/dist/core/tier-policy/index.d.ts.map +0 -1
  287. package/dist/core/tier-policy/resolve.d.ts.map +0 -1
  288. package/dist/core/tier-policy/tier-list.d.ts.map +0 -1
  289. package/dist/core/tier-policy/types.d.ts.map +0 -1
  290. package/dist/core/work-unit/index.d.ts.map +0 -1
  291. package/dist/core/work-unit/interruption.d.ts.map +0 -1
  292. package/dist/core/work-unit/tracker.d.ts.map +0 -1
  293. package/dist/core/work-unit/types.d.ts.map +0 -1
  294. package/dist/execution/continuation/execute.d.ts.map +0 -1
  295. package/dist/execution/continuation/index.d.ts.map +0 -1
  296. package/dist/execution/continuation/ledger.d.ts +0 -20
  297. package/dist/execution/continuation/ledger.d.ts.map +0 -1
  298. package/dist/execution/continuation/ledger.js +0 -31
  299. package/dist/execution/continuation/ledger.js.map +0 -1
  300. package/dist/execution/continuation/plan.d.ts.map +0 -1
  301. package/dist/execution/continuation/prompts.d.ts.map +0 -1
  302. package/dist/execution/continuation/types.d.ts.map +0 -1
  303. package/dist/execution/escalation/index.d.ts.map +0 -1
  304. package/dist/execution/escalation/types.d.ts.map +0 -1
  305. package/dist/execution/index.d.ts.map +0 -1
  306. package/dist/execution/parking/index.d.ts.map +0 -1
  307. package/dist/execution/parking/plan.d.ts.map +0 -1
  308. package/dist/execution/recovery/gate.d.ts +0 -20
  309. package/dist/execution/recovery/gate.d.ts.map +0 -1
  310. package/dist/execution/recovery/gate.js +0 -23
  311. package/dist/execution/recovery/gate.js.map +0 -1
  312. package/dist/execution/recovery/index.d.ts +0 -3
  313. package/dist/execution/recovery/index.d.ts.map +0 -1
  314. package/dist/execution/recovery/index.js +0 -2
  315. package/dist/execution/recovery/index.js.map +0 -1
  316. package/dist/execution/retry/decide.d.ts.map +0 -1
  317. package/dist/execution/retry/index.d.ts.map +0 -1
  318. package/dist/execution/retry/types.d.ts.map +0 -1
  319. package/dist/gui.d.ts.map +0 -1
  320. package/dist/health/capacity/index.d.ts.map +0 -1
  321. package/dist/health/capacity/merge.d.ts.map +0 -1
  322. package/dist/health/capacity/registry.d.ts.map +0 -1
  323. package/dist/health/capacity/types.d.ts.map +0 -1
  324. package/dist/health/circuit-breaker/breaker.d.ts.map +0 -1
  325. package/dist/health/circuit-breaker/index.d.ts.map +0 -1
  326. package/dist/health/circuit-breaker/types.d.ts.map +0 -1
  327. package/dist/health/classifier/classify.d.ts.map +0 -1
  328. package/dist/health/classifier/index.d.ts.map +0 -1
  329. package/dist/health/classifier/types.d.ts.map +0 -1
  330. package/dist/health/index.d.ts.map +0 -1
  331. package/dist/health/resource-health/index.d.ts.map +0 -1
  332. package/dist/health/resource-health/key.d.ts.map +0 -1
  333. package/dist/health/resource-health/registry.d.ts.map +0 -1
  334. package/dist/health/resource-health/transitions.d.ts.map +0 -1
  335. package/dist/health/resource-health/types.d.ts.map +0 -1
  336. package/dist/index.d.ts.map +0 -1
  337. package/dist/plugin-id.d.ts.map +0 -1
  338. package/dist/rpc/definition.d.ts.map +0 -1
  339. package/dist/rpc/handlers.d.ts.map +0 -1
  340. package/dist/rpc/status.d.ts.map +0 -1
  341. package/dist/rpc.d.ts.map +0 -1
  342. package/dist/state/capacity/index.d.ts.map +0 -1
  343. package/dist/state/capacity/parse.d.ts.map +0 -1
  344. package/dist/state/capacity/store.d.ts.map +0 -1
  345. package/dist/state/capacity/types.d.ts.map +0 -1
  346. package/dist/state/health/index.d.ts.map +0 -1
  347. package/dist/state/health/parse.d.ts.map +0 -1
  348. package/dist/state/health/store.d.ts.map +0 -1
  349. package/dist/state/health/types.d.ts.map +0 -1
  350. package/dist/state/parked-work/index.d.ts.map +0 -1
  351. package/dist/state/parked-work/parse.d.ts.map +0 -1
  352. package/dist/state/parked-work/store.d.ts.map +0 -1
  353. package/dist/state/parked-work/types.d.ts.map +0 -1
  354. package/dist/state/receipts/bound.d.ts.map +0 -1
  355. package/dist/state/receipts/index.d.ts.map +0 -1
  356. package/dist/state/receipts/parse.d.ts.map +0 -1
  357. package/dist/state/receipts/store.d.ts.map +0 -1
  358. package/dist/state/receipts/types.d.ts.map +0 -1
  359. package/dist/state/session-modes/index.d.ts.map +0 -1
  360. package/dist/state/session-modes/parse.d.ts.map +0 -1
  361. package/dist/state/session-modes/store.d.ts.map +0 -1
  362. package/dist/state/session-modes/types.d.ts.map +0 -1
  363. package/dist/state/settings/index.d.ts.map +0 -1
  364. package/dist/state/settings/parse.d.ts.map +0 -1
  365. package/dist/state/settings/store.d.ts.map +0 -1
  366. package/dist/state/settings/types.d.ts.map +0 -1
  367. package/dist/supervisor/index.d.ts.map +0 -1
  368. package/dist/supervisor/log.d.ts.map +0 -1
  369. package/dist/supervisor/supervisor.d.ts.map +0 -1
  370. package/dist/supervisor/types.d.ts.map +0 -1
  371. package/dist/supervisor/view.d.ts.map +0 -1
  372. package/dist/tui.d.ts.map +0 -1
  373. package/dist/ui/gui/api.d.ts.map +0 -1
  374. package/dist/ui/gui/view.d.ts.map +0 -1
  375. package/dist/ui/tui/controller.d.ts.map +0 -1
  376. package/dist/ui/tui/menu.d.ts.map +0 -1
  377. package/dist/ui/tui/options.d.ts.map +0 -1
  378. package/dist/ui/tui/receipts.d.ts.map +0 -1
  379. package/dist/ui/tui/status.d.ts.map +0 -1
  380. package/dist/ui/tui/tiers.d.ts.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"store.js","sourceRoot":"","sources":["../../../src/state/receipts/store.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../../src/state/receipts/store.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Bounded receipt store (ADP-030). Receipts live in a ring capped at\n * `MAX_RECEIPTS` (newest kept, oldest evicted) and persist through the\n * storage seam on every mutation. Ids are monotonic across restarts (they\n * continue from the persisted maximum) so a receipt can always be told apart\n * from its neighbors. Write failures propagate to the caller — the wiring\n * layer's fail-open wrapper decides how to degrade (ADP-031) — and the\n * in-memory ring is only advanced after a successful write, so memory and\n * disk never diverge.\n */\nimport { boundDecision, boundText } from \"./bound.js\"\nimport { parseReceiptsPayload } from \"./parse.js\"\nimport { MAX_RECEIPTS, RECEIPTS_VERSION } from \"./types.js\"\nimport type {\n Receipt,\n ReceiptInput,\n ReceiptOutcome,\n ReceiptsPayload,\n ReceiptsStorage,\n} from \"./types.js\"\n\nexport interface ReceiptRef {\n readonly sessionID: string\n /** When given, only receipts of that unit are updated; otherwise only receipts without a unit. */\n readonly unitID?: string | undefined\n}\n\nexport class ReceiptStore {\n #receipts: Receipt[] = []\n #counter = 0\n #queue: Promise<unknown> = Promise.resolve()\n\n constructor(private readonly storage: ReceiptsStorage) {}\n\n /** Rebuild from storage (restart behavior). A read failure yields an empty store. */\n load(): Promise<void> {\n return this.#serialize(() => this.#load())\n }\n\n async #load(): Promise<void> {\n let raw: unknown\n try {\n raw = await this.storage.read()\n } catch {\n this.#receipts = []\n return\n }\n const parsed = parseReceiptsPayload(raw)\n this.#receipts = parsed\n this.#counter = parsed.reduce((max, receipt) => Math.max(max, receipt.id), 0)\n }\n\n /** All retained receipts, oldest → newest. */\n snapshot(): readonly Receipt[] {\n return this.#receipts\n }\n\n record(input: ReceiptInput): Promise<Receipt> {\n return this.#serialize(() => this.#record(input))\n }\n\n async #record(input: ReceiptInput): Promise<Receipt> {\n // A receipt with no session can never be attributed to anything, and the\n // read path drops empty identifiers — persisting one would make it vanish\n // across a restart. Throw instead; the wiring layer fail-open-catches.\n if (input.sessionID.trim() === \"\") {\n throw new Error(\"invalid receipt: sessionID must be a non-empty string\")\n }\n const id = this.#counter + 1\n const receipt: Receipt = {\n id,\n at: input.at,\n // Identifiers are bounded with the same bound the read path applies, so\n // what is persisted is exactly what comes back (types.ts invariant).\n sessionID: boundText(input.sessionID),\n ...(input.unitID !== undefined ? { unitID: boundText(input.unitID) } : {}),\n ...(input.tier !== undefined ? { tier: input.tier } : {}),\n decision: boundDecision(input.decision),\n }\n const next =\n this.#receipts.length >= MAX_RECEIPTS\n ? [...this.#receipts.slice(1 - MAX_RECEIPTS), receipt]\n : [...this.#receipts, receipt]\n // Persist BEFORE committing memory: a write failure must leave memory and\n // disk consistent (the caller decides how to fail open).\n await this.#persist(next)\n this.#receipts = next\n this.#counter = id\n return receipt\n }\n\n /**\n * Attach a unit outcome to matching receipts that do not have one yet\n * (first outcome wins). Returns how many receipts were updated; zero\n * updates do not touch storage.\n */\n attachOutcome(ref: ReceiptRef, outcome: ReceiptOutcome): Promise<number> {\n return this.#serialize(() => this.#attachOutcome(ref, outcome))\n }\n\n async #attachOutcome(ref: ReceiptRef, outcome: ReceiptOutcome): Promise<number> {\n let updated = 0\n const next = this.#receipts.map((receipt) => {\n if (receipt.outcome !== undefined) return receipt\n if (receipt.sessionID !== ref.sessionID) return receipt\n const matches =\n ref.unitID !== undefined ? receipt.unitID === ref.unitID : receipt.unitID === undefined\n if (!matches) return receipt\n updated++\n return { ...receipt, outcome }\n })\n if (updated === 0) return 0\n await this.#persist(next)\n this.#receipts = next\n return updated\n }\n\n /**\n * Stamps the unit that just opened onto the session's pending unit-less\n * admission receipts (recorded in the awaited prompt hook, before the unit\n * existed). After adoption the receipt carries the unitID, so outcomes\n * attach to it like any unit-scoped receipt.\n *\n * One opened unit adopts ONE admission — the newest pending receipt. With\n * several pending receipts (a prompt admitted but superseded before its\n * unit ever opened), stamping all of them would attach this unit's outcome\n * to foreign admission decisions; the older receipts stay pending instead.\n */\n adoptUnit(sessionID: string, unitID: string): Promise<number> {\n return this.#serialize(() => this.#adoptUnit(sessionID, unitID))\n }\n\n async #adoptUnit(sessionID: string, unitID: string): Promise<number> {\n let target: number | undefined\n this.#receipts.forEach((receipt, index) => {\n if (receipt.unitID !== undefined || receipt.outcome !== undefined) return\n if (receipt.sessionID !== sessionID) return\n target = index\n })\n if (target === undefined) return 0\n const at = target\n const next = this.#receipts.map((receipt, index) =>\n index === at ? { ...receipt, unitID } : receipt,\n )\n await this.#persist(next)\n this.#receipts = next\n return 1\n }\n\n // Include reads in the chain so a reload cannot overwrite a newer commit.\n // A failed write rejects its caller without blocking subsequent operations.\n #serialize<T>(operation: () => Promise<T>): Promise<T> {\n const run = this.#queue.then(operation)\n this.#queue = run.catch(() => undefined)\n return run\n }\n\n /** Writes the given next state; the caller commits memory only on success. */\n async #persist(receipts: readonly Receipt[]): Promise<void> {\n const payload: ReceiptsPayload = {\n version: RECEIPTS_VERSION,\n receipts,\n }\n await this.storage.write(payload)\n }\n}\n"]}
@@ -59,4 +59,3 @@ export interface ReceiptsStorage {
59
59
  read(): Promise<unknown>;
60
60
  write(payload: ReceiptsPayload): Promise<void>;
61
61
  }
62
- //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/state/receipts/types.ts"],"names":[],"mappings":"AAWA,MAAM,CAAC,MAAM,YAAY,GAAG,yBAAyB,CAAA;AACrD,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAA;AACjC,2EAA2E;AAC3E,MAAM,CAAC,MAAM,YAAY,GAAG,GAAG,CAAA;AAC/B;;;;;GAKG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,GAAG,CAAA"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/state/receipts/types.ts"],"names":[],"mappings":"AAWA,MAAM,CAAC,MAAM,YAAY,GAAG,yBAAyB,CAAA;AACrD,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAA;AACjC,2EAA2E;AAC3E,MAAM,CAAC,MAAM,YAAY,GAAG,GAAG,CAAA;AAC/B;;;;;GAKG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,GAAG,CAAA","sourcesContent":["/**\n * Decision receipts (ADP-030): small bounded local records explaining why\n * Adaptive made each decision. Receipts exist for explainability, debugging,\n * tests, and a future outcome-learning policy — never injected into prompts,\n * never leaving the machine. Retention is bounded (oldest evicted).\n */\nimport type { Decision } from \"../../core/scheduler/types.js\"\nimport type { TierName } from \"../../core/tier-policy/types.js\"\nimport type { InterruptReason } from \"../../core/work-unit/interruption.js\"\nimport type { FailureCategory } from \"../../health/classifier/types.js\"\n\nexport const RECEIPTS_KEY = \"coool.adaptive/receipts\"\nexport const RECEIPTS_VERSION = 1\n/** Product bound — not a user knob. The ring keeps the newest receipts. */\nexport const MAX_RECEIPTS = 200\n/**\n * Every free-text string stored in a receipt is truncated to this bound\n * before persisting (and re-truncated on read). Boundedness is the\n * no-secrets invariant: prompts, error bodies, and credentials have no\n * field to live in and no room to hide in.\n */\nexport const MAX_RECEIPT_TEXT = 128\n\nexport interface ReceiptMeta {\n /** Decision timestamp (adapter clock, ms epoch). */\n readonly at: number\n readonly sessionID: string\n readonly unitID?: string | undefined\n /** Required tier when routing named one (pins carry no tier). */\n readonly tier?: TierName | undefined\n}\n\nexport interface ReceiptInput extends ReceiptMeta {\n /** The decision exactly as the scheduler/mode wrapper produced it. */\n readonly decision: Decision\n}\n\n/**\n * Unit outcome attached after termination. Structured vocabulary only —\n * never the raw error text (ADP-030: no secrets, bounded records).\n */\nexport type ReceiptOutcome =\n | { readonly status: \"succeeded\" }\n | { readonly status: \"failed\"; readonly category: FailureCategory }\n | { readonly status: \"interrupted\"; readonly reason: InterruptReason }\n\nexport interface Receipt extends ReceiptMeta {\n /** Monotonic id assigned by the store; continues across restarts. */\n readonly id: number\n readonly decision: Decision\n readonly outcome?: ReceiptOutcome\n}\n\nexport interface ReceiptsPayload {\n readonly version: typeof RECEIPTS_VERSION\n readonly receipts: readonly Receipt[]\n}\n\n/** Storage seam — the adapter binds `RECEIPTS_KEY` to `ctx.storage`. */\nexport interface ReceiptsStorage {\n read(): Promise<unknown>\n write(payload: ReceiptsPayload): Promise<void>\n}\n"]}
@@ -2,4 +2,3 @@ export { parseSessionModesPayload, isValidSessionID } from "./parse.js";
2
2
  export { SessionModeStore } from "./store.js";
3
3
  export { SESSION_MODES_KEY, SESSION_MODES_VERSION, MAX_SESSION_MODE_RECORDS, MAX_SESSION_ID_LENGTH, } from "./types.js";
4
4
  export type { SessionModeRecord, SessionModesPayload, SessionModeSetResult, SessionModesStorage, } from "./types.js";
5
- //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/state/session-modes/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AACvE,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAC7C,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,wBAAwB,EACxB,qBAAqB,GACtB,MAAM,YAAY,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/state/session-modes/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AACvE,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAC7C,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,wBAAwB,EACxB,qBAAqB,GACtB,MAAM,YAAY,CAAA","sourcesContent":["export { parseSessionModesPayload, isValidSessionID } from \"./parse.js\"\nexport { SessionModeStore } from \"./store.js\"\nexport {\n SESSION_MODES_KEY,\n SESSION_MODES_VERSION,\n MAX_SESSION_MODE_RECORDS,\n MAX_SESSION_ID_LENGTH,\n} from \"./types.js\"\nexport type {\n SessionModeRecord,\n SessionModesPayload,\n SessionModeSetResult,\n SessionModesStorage,\n} from \"./types.js\"\n"]}
@@ -6,4 +6,3 @@ import type { SessionModeRecord } from "./types.js";
6
6
  */
7
7
  export declare function isValidSessionID(raw: unknown): raw is string;
8
8
  export declare function parseSessionModesPayload(raw: unknown): SessionModeRecord[];
9
- //# sourceMappingURL=parse.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"parse.js","sourceRoot":"","sources":["../../../src/state/session-modes/parse.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAA;AAE/D,OAAO,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAA;AAGzE,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;AAC7E,CAAC;AAED,SAAS,cAAc,CAAC,GAAY;IAClC,OAAO,OAAO,GAAG,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAA;AACxD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,GAAY;IAC3C,OAAO,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,GAAG,CAAC,MAAM,IAAI,qBAAqB,CAAA;AACzF,CAAC;AAED,SAAS,cAAc,CAAC,GAAY;IAClC,OAAO,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAA;AAChD,CAAC;AAED,SAAS,SAAS,CAAC,GAAY;IAC7B,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAA;IAC7C,OAAQ,eAAqC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAE,GAAqB,CAAC,CAAC,CAAC,SAAS,CAAA;AAClG,CAAC;AAED,SAAS,WAAW,CAAC,GAAY;IAC/B,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,SAAS,CAAA;IACpC,MAAM,SAAS,GAAG,cAAc,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAA;IAClD,MAAM,IAAI,GAAG,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAA;IACnC,MAAM,SAAS,GAAG,GAAG,CAAC,WAAW,CAAC,CAAA;IAClC,IAAI,SAAS,KAAK,SAAS,IAAI,IAAI,KAAK,SAAS,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC;QAAE,OAAO,SAAS,CAAA;IACjG,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,CAAA;AACvC,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,GAAY;IACnD,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,EAAE,CAAA;IAC7B,IAAI,GAAG,CAAC,SAAS,CAAC,KAAK,qBAAqB;QAAE,OAAO,EAAE,CAAA;IACvD,MAAM,IAAI,GAAG,GAAG,CAAC,SAAS,CAAC,CAAA;IAC3B,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC;QAAE,OAAO,EAAE,CAAA;IACnC,wEAAwE;IACxE,qEAAqE;IACrE,MAAM,SAAS,GAAG,IAAI,GAAG,EAA6B,CAAA;IACtD,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC;QACvC,MAAM,MAAM,GAAG,WAAW,CAAC,KAAK,CAAC,CAAA;QACjC,IAAI,MAAM,KAAK,SAAS;YAAE,SAAQ;QAClC,MAAM,IAAI,GAAG,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;QAC5C,IAAI,IAAI,KAAK,SAAS,IAAI,MAAM,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS;YACzD,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAA;IAC3C,CAAC;IACD,OAAO,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,CAAA;AAChC,CAAC"}
1
+ {"version":3,"file":"parse.js","sourceRoot":"","sources":["../../../src/state/session-modes/parse.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAA;AAE/D,OAAO,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAA;AAGzE,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;AAC7E,CAAC;AAED,SAAS,cAAc,CAAC,GAAY;IAClC,OAAO,OAAO,GAAG,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAA;AACxD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,GAAY;IAC3C,OAAO,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,GAAG,CAAC,MAAM,IAAI,qBAAqB,CAAA;AACzF,CAAC;AAED,SAAS,cAAc,CAAC,GAAY;IAClC,OAAO,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAA;AAChD,CAAC;AAED,SAAS,SAAS,CAAC,GAAY;IAC7B,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAA;IAC7C,OAAQ,eAAqC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAE,GAAqB,CAAC,CAAC,CAAC,SAAS,CAAA;AAClG,CAAC;AAED,SAAS,WAAW,CAAC,GAAY;IAC/B,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,SAAS,CAAA;IACpC,MAAM,SAAS,GAAG,cAAc,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAA;IAClD,MAAM,IAAI,GAAG,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAA;IACnC,MAAM,SAAS,GAAG,GAAG,CAAC,WAAW,CAAC,CAAA;IAClC,IAAI,SAAS,KAAK,SAAS,IAAI,IAAI,KAAK,SAAS,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC;QAAE,OAAO,SAAS,CAAA;IACjG,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,CAAA;AACvC,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,GAAY;IACnD,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,EAAE,CAAA;IAC7B,IAAI,GAAG,CAAC,SAAS,CAAC,KAAK,qBAAqB;QAAE,OAAO,EAAE,CAAA;IACvD,MAAM,IAAI,GAAG,GAAG,CAAC,SAAS,CAAC,CAAA;IAC3B,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC;QAAE,OAAO,EAAE,CAAA;IACnC,wEAAwE;IACxE,qEAAqE;IACrE,MAAM,SAAS,GAAG,IAAI,GAAG,EAA6B,CAAA;IACtD,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC;QACvC,MAAM,MAAM,GAAG,WAAW,CAAC,KAAK,CAAC,CAAA;QACjC,IAAI,MAAM,KAAK,SAAS;YAAE,SAAQ;QAClC,MAAM,IAAI,GAAG,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;QAC5C,IAAI,IAAI,KAAK,SAAS,IAAI,MAAM,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS;YACzD,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAA;IAC3C,CAAC;IACD,OAAO,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,CAAA;AAChC,CAAC","sourcesContent":["/**\n * Read-side parsing for persisted session-mode overrides. Total like every\n * `state/` parser: it accepts `unknown` and returns typed records, dropping\n * anything invalid — a corrupted file can never take the plugin down\n * (ADP-031). A partially corrupted payload keeps its good entries.\n */\nimport { OPERATING_MODES } from \"../../core/scheduler/types.js\"\nimport type { OperatingMode } from \"../../core/scheduler/types.js\"\nimport { MAX_SESSION_ID_LENGTH, SESSION_MODES_VERSION } from \"./types.js\"\nimport type { SessionModeRecord } from \"./types.js\"\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value)\n}\n\nfunction isFiniteNumber(raw: unknown): raw is number {\n return typeof raw === \"number\" && Number.isFinite(raw)\n}\n\n/**\n * A non-empty bounded session identifier. Unlike the health parser's provider\n * identifiers (truncated on read), an over-long sessionID is dropped: the id\n * is a host identity, not a label, and no real session id exceeds the bound.\n */\nexport function isValidSessionID(raw: unknown): raw is string {\n return typeof raw === \"string\" && raw.length > 0 && raw.length <= MAX_SESSION_ID_LENGTH\n}\n\nfunction parseSessionID(raw: unknown): string | undefined {\n return isValidSessionID(raw) ? raw : undefined\n}\n\nfunction parseMode(raw: unknown): OperatingMode | undefined {\n if (typeof raw !== \"string\") return undefined\n return (OPERATING_MODES as readonly string[]).includes(raw) ? (raw as OperatingMode) : undefined\n}\n\nfunction parseRecord(raw: unknown): SessionModeRecord | undefined {\n if (!isRecord(raw)) return undefined\n const sessionID = parseSessionID(raw[\"sessionID\"])\n const mode = parseMode(raw[\"mode\"])\n const updatedAt = raw[\"updatedAt\"]\n if (sessionID === undefined || mode === undefined || !isFiniteNumber(updatedAt)) return undefined\n return { sessionID, mode, updatedAt }\n}\n\nexport function parseSessionModesPayload(raw: unknown): SessionModeRecord[] {\n if (!isRecord(raw)) return []\n if (raw[\"version\"] !== SESSION_MODES_VERSION) return []\n const list = raw[\"records\"]\n if (!Array.isArray(list)) return []\n // A hostile or duplicated payload can carry the same session twice; the\n // most recently updated record wins so `get` is not order-dependent.\n const bySession = new Map<string, SessionModeRecord>()\n for (const entry of list.slice(0, 512)) {\n const record = parseRecord(entry)\n if (record === undefined) continue\n const kept = bySession.get(record.sessionID)\n if (kept === undefined || record.updatedAt > kept.updatedAt)\n bySession.set(record.sessionID, record)\n }\n return [...bySession.values()]\n}\n"]}
@@ -18,4 +18,3 @@ export declare class SessionModeStore {
18
18
  */
19
19
  set(sessionID: string, mode: OperatingMode | null): Promise<void>;
20
20
  }
21
- //# sourceMappingURL=store.d.ts.map
@@ -13,12 +13,16 @@ export class SessionModeStore {
13
13
  storage;
14
14
  clock;
15
15
  #records = [];
16
+ #queue = Promise.resolve();
16
17
  constructor(storage, clock) {
17
18
  this.storage = storage;
18
19
  this.clock = clock;
19
20
  }
20
21
  /** Rebuild from storage (restart behavior). A read failure yields an empty store. */
21
- async load() {
22
+ load() {
23
+ return this.#serialize(() => this.#load());
24
+ }
25
+ async #load() {
22
26
  let raw;
23
27
  try {
24
28
  raw = await this.storage.read();
@@ -52,6 +56,9 @@ export class SessionModeStore {
52
56
  if (mode !== null && !OPERATING_MODES.includes(mode)) {
53
57
  throw new Error(`mode must be one of ${OPERATING_MODES.join(", ")} or null`);
54
58
  }
59
+ return this.#serialize(() => this.#set(sessionID, mode));
60
+ }
61
+ async #set(sessionID, mode) {
55
62
  const updatedAt = this.clock();
56
63
  const kept = this.#records.filter((record) => record.sessionID !== sessionID);
57
64
  const next = mode === null
@@ -63,6 +70,13 @@ export class SessionModeStore {
63
70
  await this.storage.write(payload);
64
71
  this.#records = next;
65
72
  }
73
+ // Reloads share the mutation queue so stale reads cannot overwrite commits.
74
+ // Recover only the queue tail: the failed operation still rejects its caller.
75
+ #serialize(operation) {
76
+ const run = this.#queue.then(operation);
77
+ this.#queue = run.catch(() => undefined);
78
+ return run;
79
+ }
66
80
  }
67
81
  /** Keep the newest records when over the cap. */
68
82
  function bound(records, max) {
@@ -1 +1 @@
1
- {"version":3,"file":"store.js","sourceRoot":"","sources":["../../../src/state/session-modes/store.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../../src/state/session-modes/store.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Bounded per-session operating-mode override store. Keeps the most recently\n * updated records (bounded, least-recently-updated evicted) and persists on\n * every change. As everywhere else in `state/`, memory is only advanced after\n * a successful write, so memory and disk never diverge; write failures\n * propagate to the caller — the wiring layer's fail-open wrapper decides how\n * to degrade (ADP-031).\n */\nimport { parseSessionModesPayload, isValidSessionID } from \"./parse.js\"\nimport { MAX_SESSION_ID_LENGTH, MAX_SESSION_MODE_RECORDS, SESSION_MODES_VERSION } from \"./types.js\"\nimport type { OperatingMode } from \"../../core/scheduler/types.js\"\nimport type { SessionModeRecord, SessionModesPayload, SessionModesStorage } from \"./types.js\"\nimport { OPERATING_MODES } from \"../../core/scheduler/types.js\"\n\nexport class SessionModeStore {\n #records: SessionModeRecord[] = []\n #queue: Promise<void> = Promise.resolve()\n\n constructor(\n private readonly storage: SessionModesStorage,\n private readonly clock: () => number,\n ) {}\n\n /** Rebuild from storage (restart behavior). A read failure yields an empty store. */\n load(): Promise<void> {\n return this.#serialize(() => this.#load())\n }\n\n async #load(): Promise<void> {\n let raw: unknown\n try {\n raw = await this.storage.read()\n } catch {\n this.#records = []\n return\n }\n this.#records = parseSessionModesPayload(raw)\n }\n\n /** All retained records. */\n snapshot(): readonly SessionModeRecord[] {\n return this.#records\n }\n\n /** The session's override, or `null` when it follows the global mode. */\n get(sessionID: string): OperatingMode | null {\n return this.#records.find((record) => record.sessionID === sessionID)?.mode ?? null\n }\n\n /**\n * Set (or with `null`, remove) one session's override. The bound keeps the\n * most recently updated records — overrides for long-gone sessions matter\n * less than the ones being actively steered.\n */\n async set(sessionID: string, mode: OperatingMode | null): Promise<void> {\n // Defensive re-validation at the persistence boundary: the RPC handler\n // validates first and reports named errors; these guards keep malformed\n // in-process callers from persisting junk.\n if (!isValidSessionID(sessionID)) {\n throw new Error(\n `sessionID must be a non-empty string of at most ${String(MAX_SESSION_ID_LENGTH)} characters`,\n )\n }\n if (mode !== null && !(OPERATING_MODES as readonly string[]).includes(mode)) {\n throw new Error(`mode must be one of ${OPERATING_MODES.join(\", \")} or null`)\n }\n return this.#serialize(() => this.#set(sessionID, mode))\n }\n\n async #set(sessionID: string, mode: OperatingMode | null): Promise<void> {\n const updatedAt = this.clock()\n const kept = this.#records.filter((record) => record.sessionID !== sessionID)\n const next =\n mode === null\n ? kept\n : bound([...kept, { sessionID, mode, updatedAt }], MAX_SESSION_MODE_RECORDS)\n // Persist BEFORE committing memory: a write failure must leave memory\n // and disk consistent (the caller decides how to fail open).\n const payload: SessionModesPayload = { version: SESSION_MODES_VERSION, records: next }\n await this.storage.write(payload)\n this.#records = next\n }\n\n // Reloads share the mutation queue so stale reads cannot overwrite commits.\n // Recover only the queue tail: the failed operation still rejects its caller.\n #serialize(operation: () => Promise<void>): Promise<void> {\n const run = this.#queue.then(operation)\n this.#queue = run.catch(() => undefined)\n return run\n }\n}\n\n/** Keep the newest records when over the cap. */\nfunction bound(records: SessionModeRecord[], max: number): SessionModeRecord[] {\n if (records.length <= max) return records\n return [...records].sort((left, right) => right.updatedAt - left.updatedAt).slice(0, max)\n}\n"]}
@@ -39,4 +39,3 @@ export interface SessionModesStorage {
39
39
  read(): Promise<unknown>;
40
40
  write(payload: SessionModesPayload): Promise<void>;
41
41
  }
42
- //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/state/session-modes/types.ts"],"names":[],"mappings":"AAWA,MAAM,CAAC,MAAM,iBAAiB,GAAG,8BAA8B,CAAA;AAC/D,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAA;AACtC,gFAAgF;AAChF,MAAM,CAAC,MAAM,wBAAwB,GAAG,GAAG,CAAA;AAC3C,oEAAoE;AACpE,MAAM,CAAC,MAAM,qBAAqB,GAAG,GAAG,CAAA"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/state/session-modes/types.ts"],"names":[],"mappings":"AAWA,MAAM,CAAC,MAAM,iBAAiB,GAAG,8BAA8B,CAAA;AAC/D,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAA;AACtC,gFAAgF;AAChF,MAAM,CAAC,MAAM,wBAAwB,GAAG,GAAG,CAAA;AAC3C,oEAAoE;AACpE,MAAM,CAAC,MAAM,qBAAqB,GAAG,GAAG,CAAA","sourcesContent":["/**\n * Persisted per-session operating-mode overrides (ADP-054). The operating mode\n * is otherwise a global setting, but supervision decisions are made per\n * session — the override lets one session run under a different mode without\n * touching the global default. Records persist through the storage seam like\n * every other state: the host's TUI-mode plugin reconciliation can serve RPC\n * from an instance whose event-pump hooks live on another instance, and a\n * restart must not silently drop explicit user intent.\n */\nimport type { OperatingMode } from \"../../core/scheduler/types.js\"\n\nexport const SESSION_MODES_KEY = \"coool.adaptive/session-modes\"\nexport const SESSION_MODES_VERSION = 1\n/** Product bound — not a user knob. Keeps the most recently updated records. */\nexport const MAX_SESSION_MODE_RECORDS = 512\n/** A session id beyond this bound is not a real host identifier. */\nexport const MAX_SESSION_ID_LENGTH = 128\n\nexport interface SessionModeRecord {\n readonly sessionID: string\n readonly mode: OperatingMode\n readonly updatedAt: number\n}\n\nexport interface SessionModesPayload {\n readonly version: typeof SESSION_MODES_VERSION\n readonly records: readonly SessionModeRecord[]\n}\n\n/**\n * A successful override write. Mirrors the settings patch-result convention:\n * validation failures are per-field errors, internal failures throw (the\n * RPC handler degrades them fail-open).\n */\nexport type SessionModeSetResult =\n { readonly ok: true } | { readonly ok: false; readonly errors: readonly string[] }\n\n/** Storage seam — the adapter binds `SESSION_MODES_KEY` to `ctx.storage`. */\nexport interface SessionModesStorage {\n read(): Promise<unknown>\n write(payload: SessionModesPayload): Promise<void>\n}\n"]}
@@ -2,4 +2,3 @@ export { defaultSettings, applyPatch, migrateSettings, parseAgentTiers, parseMod
2
2
  export { SettingsStore } from "./store.js";
3
3
  export { MAX_AGENT_TIERS, MAX_TIER_RESOURCES, SETTINGS_KEY, SETTINGS_VERSION } from "./types.js";
4
4
  export type { PatchResult, SettingsPatch, SettingsStorage, SettingsV1 } from "./types.js";
5
- //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/state/settings/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,UAAU,EACV,eAAe,EACf,eAAe,EACf,SAAS,EACT,QAAQ,EACR,cAAc,GACf,MAAM,YAAY,CAAA;AACnB,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAC1C,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/state/settings/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,UAAU,EACV,eAAe,EACf,eAAe,EACf,SAAS,EACT,QAAQ,EACR,cAAc,GACf,MAAM,YAAY,CAAA;AACnB,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAC1C,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA","sourcesContent":["export {\n defaultSettings,\n applyPatch,\n migrateSettings,\n parseAgentTiers,\n parseMode,\n parsePin,\n parseTierLists,\n} from \"./parse.js\"\nexport { SettingsStore } from \"./store.js\"\nexport { MAX_AGENT_TIERS, MAX_TIER_RESOURCES, SETTINGS_KEY, SETTINGS_VERSION } from \"./types.js\"\nexport type { PatchResult, SettingsPatch, SettingsStorage, SettingsV1 } from \"./types.js\"\n"]}
@@ -31,4 +31,3 @@ export declare function applyPatch(current: SettingsV1, patch: unknown): {
31
31
  ok: false;
32
32
  errors: string[];
33
33
  };
34
- //# sourceMappingURL=parse.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"parse.js","sourceRoot":"","sources":["../../../src/state/settings/parse.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"parse.js","sourceRoot":"","sources":["../../../src/state/settings/parse.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Bounded shape validation and migration-on-read (ADP-036). Every parser is\n * total: it accepts `unknown` and either returns a typed value or `undefined`\n * — the read path always falls back to a default rather than throwing, so a\n * corrupted record can never take the plugin (or the host) down (ADP-031).\n *\n * Plain objects are never indexed with untrusted strings beyond own-property\n * checks (`Object.hasOwn`) — prototype-chain keys like \"toString\" must not be\n * mistaken for data (project-wide audit rule).\n */\nimport { OPERATING_MODES } from \"../../core/scheduler/types.js\"\nimport type { OperatingMode } from \"../../core/scheduler/types.js\"\nimport { normalizeTierList } from \"../../core/tier-policy/tier-list.js\"\nimport { TIERS } from \"../../core/tier-policy/types.js\"\nimport type { TierName } from \"../../core/tier-policy/types.js\"\nimport type { ModelRef } from \"../../core/work-unit/types.js\"\nimport { MAX_AGENT_TIERS, MAX_TIER_RESOURCES, SETTINGS_VERSION } from \"./types.js\"\nimport type { SettingsV1 } from \"./types.js\"\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value)\n}\n\n/** One field's patch-path parse outcome: a validated value or a field error. */\ntype FieldParse<T> = { ok: true; value: T } | { ok: false; error: string }\n\n/**\n * Quoted, bounded rendering of an untrusted patch value inside an error\n * message (errors travel to surfaces over RPC; JSON.stringify is only ever\n * called on strings here, so a cyclic object cannot make applyPatch throw).\n */\nfunction describePatchValue(value: unknown): string {\n if (typeof value === \"string\") {\n const quoted = JSON.stringify(value)\n return quoted.length > 64 ? `${quoted.slice(0, 64)}…` : quoted\n }\n if (value === null) return \"null\"\n if (typeof value === \"object\") return \"object\"\n if (typeof value === \"number\" || typeof value === \"boolean\") return String(value)\n return typeof value\n}\n\nexport function parseMode(raw: unknown): OperatingMode | undefined {\n if (typeof raw !== \"string\") return undefined\n return OPERATING_MODES.find((mode) => mode === raw)\n}\n\n/**\n * Legacy persisted value: v1 settings written before the `control → active`\n * rename store `mode: \"control\"`. Migration-on-read maps it; patches stay\n * strict (wire input must use the current vocabulary).\n */\nfunction parseLegacyMode(raw: unknown): OperatingMode | undefined {\n return raw === \"control\" ? \"active\" : parseMode(raw)\n}\n\nexport function parseTierLists(\n raw: unknown,\n): Readonly<Record<TierName, readonly ModelRef[]>> | undefined {\n if (!isRecord(raw)) return undefined\n const tiers = {} as Record<TierName, readonly ModelRef[]>\n for (const tier of TIERS) {\n tiers[tier] = normalizeTierListValue(raw[tier])\n }\n return tiers\n}\n\n/** Shared per-tier normalization (drop invalid, dedupe, cap) for both paths. */\nfunction normalizeTierListValue(list: unknown): readonly ModelRef[] {\n return Array.isArray(list)\n ? normalizeTierList(\n list.map(parseModelRef).filter((ref): ref is ModelRef => ref !== undefined),\n ).slice(0, MAX_TIER_RESOURCES)\n : []\n}\n\nexport function parseModelRef(raw: unknown): ModelRef | undefined {\n if (!isRecord(raw)) return undefined\n const providerID = raw[\"providerID\"]\n const id = raw[\"id\"]\n const variant = raw[\"variant\"]\n if (typeof providerID !== \"string\" || providerID === \"\") return undefined\n if (typeof id !== \"string\" || id === \"\") return undefined\n return {\n providerID,\n id,\n ...(typeof variant === \"string\" && variant !== \"\" ? { variant } : {}),\n }\n}\n\nexport function parsePin(raw: unknown): ModelRef | null | undefined {\n if (raw === null) return null\n return parseModelRef(raw)\n}\n\nexport function parseAgentTiers(raw: unknown): Readonly<Record<string, TierName>> | undefined {\n if (!isRecord(raw)) return undefined\n const entries: [string, TierName][] = []\n for (const [agent, tier] of Object.entries(raw)) {\n if (agent === \"\") continue\n const parsed = parseModelessTier(tier)\n if (parsed === undefined) continue\n entries.push([agent, parsed])\n if (entries.length === MAX_AGENT_TIERS) break\n }\n // `Object.fromEntries` creates own data properties, so even a \"__proto__\"\n // key from JSON input cannot pollute the prototype here.\n return Object.fromEntries(entries)\n}\n\nfunction parseModelessTier(raw: unknown): TierName | undefined {\n if (typeof raw !== \"string\") return undefined\n return TIERS.find((tier) => tier === raw)\n}\n\n/**\n * Patch-path tier-list validation. Unlike the read path (which fills missing\n * or unusable tiers with `[]`), a patch that names `tiers` REPLACES the whole\n * map — silently filling an omitted key with `[]` would wipe that tier's\n * configured resources, so every key must be present and array-typed. List\n * contents still go through the shared normalization (drop invalid, dedupe,\n * cap), which is repair of user-typed entries rather than data loss.\n */\nfunction parseTierListsPatch(\n raw: unknown,\n): FieldParse<Readonly<Record<TierName, readonly ModelRef[]>>> {\n if (!isRecord(raw)) return { ok: false, error: \"invalid tiers\" }\n const missing = TIERS.filter((tier) => raw[tier] === undefined)\n if (missing.length > 0) {\n const named = missing.map((tier) => JSON.stringify(tier)).join(\", \")\n return { ok: false, error: `invalid tiers: missing ${named}` }\n }\n const tiers = {} as Record<TierName, readonly ModelRef[]>\n for (const tier of TIERS) {\n const list = raw[tier]\n if (!Array.isArray(list)) {\n return { ok: false, error: `invalid tiers: ${JSON.stringify(tier)} must be an array` }\n }\n tiers[tier] = normalizeTierListValue(list)\n }\n return { ok: true, value: tiers }\n}\n\n/**\n * Patch-path agent-tier validation. Unlike the read path (which drops invalid\n * entries as migration-on-read repair), a patch REPLACES the whole map —\n * silently dropping entries would let a single typo wipe the persisted hints,\n * so any invalid entry (and an over-cap patch) is rejected with an error that\n * names the offending field and value.\n */\nfunction parseAgentTiersPatch(raw: unknown): FieldParse<Readonly<Record<string, TierName>>> {\n if (!isRecord(raw)) return { ok: false, error: \"invalid agentTiers\" }\n const entries: [string, TierName][] = []\n for (const [agent, tier] of Object.entries(raw)) {\n if (entries.length === MAX_AGENT_TIERS) {\n return {\n ok: false,\n error: `invalid agentTiers: more than ${String(MAX_AGENT_TIERS)} entries`,\n }\n }\n if (agent === \"\") return { ok: false, error: \"invalid agentTiers: empty agent name\" }\n const parsed = parseModelessTier(tier)\n if (parsed === undefined) {\n return {\n ok: false,\n error: `invalid agentTiers entry ${describePatchValue(agent)}: ${describePatchValue(tier)}`,\n }\n }\n entries.push([agent, parsed])\n }\n // `Object.fromEntries` creates own data properties, so even a \"__proto__\"\n // key from JSON input cannot pollute the prototype here.\n return { ok: true, value: Object.fromEntries(entries) }\n}\n\n/** Settings with nothing configured: OBSERVE, empty tiers, no pin (ADP-029/032). */\nexport function defaultSettings(): SettingsV1 {\n return {\n version: SETTINGS_VERSION,\n mode: \"observe\",\n tiers: { quick: [], standard: [], advanced: [] },\n pin: null,\n agentTiers: {},\n inviteDismissed: false,\n }\n}\n\n/**\n * Migration-on-read. `undefined`/absent record → defaults (first install);\n * versionless (v0 draft) and v1 records are validated field-wise with\n * defaults for unusable fields; a record written by a NEWER version is\n * returned as defaults rather than guessed at (and is only re-persisted once\n * the user changes something, which stamps the current version).\n */\nexport function migrateSettings(raw: unknown): SettingsV1 {\n if (!isRecord(raw)) return defaultSettings()\n const version = raw[\"version\"]\n if (version !== SETTINGS_VERSION && version !== 0 && version !== undefined) {\n return defaultSettings()\n }\n return fieldsFrom(raw)\n}\n\nfunction fieldsFrom(raw: Record<string, unknown>): SettingsV1 {\n const mode = parseLegacyMode(raw[\"mode\"]) ?? \"observe\"\n const tiers = parseTierLists(raw[\"tiers\"]) ?? defaultSettings().tiers\n const pin = parsePin(raw[\"pin\"]) ?? null\n const agentTiers = parseAgentTiers(raw[\"agentTiers\"]) ?? {}\n const inviteDismissed = raw[\"inviteDismissed\"] === true\n return { version: SETTINGS_VERSION, mode, tiers, pin, agentTiers, inviteDismissed }\n}\n\n/**\n * Validate a patch against current settings. The patch is WIRE input (unknown\n * by contract — surfaces send untrusted JSON over RPC; the SettingsPatch type\n * documents the expected shape, the field parsers enforce it). Invalid fields\n * collect error strings (at most one per field, five fields); a valid patch\n * produces a NEW settings object (inputs are never mutated).\n */\nexport function applyPatch(\n current: SettingsV1,\n patch: unknown,\n): { ok: true; settings: SettingsV1 } | { ok: false; errors: string[] } {\n if (!isRecord(patch)) return { ok: false, errors: [\"invalid patch\"] }\n const request = patch as {\n mode?: unknown\n tiers?: unknown\n pin?: unknown\n agentTiers?: unknown\n inviteDismissed?: unknown\n }\n const errors: string[] = []\n let mode = current.mode\n let tiers = current.tiers\n let pin = current.pin\n let agentTiers = current.agentTiers\n let inviteDismissed = current.inviteDismissed\n\n if (request.mode !== undefined) {\n const parsed = parseMode(request.mode)\n if (parsed === undefined) errors.push(\"invalid mode\")\n else mode = parsed\n }\n if (request.tiers !== undefined) {\n const parsed = parseTierListsPatch(request.tiers)\n if (parsed.ok) tiers = parsed.value\n else errors.push(parsed.error)\n }\n // `pin === null` is a meaningful clear and must not read as absence.\n if (request.pin !== undefined) {\n const parsed = parsePin(request.pin)\n if (parsed === undefined) errors.push(\"invalid pin\")\n else pin = parsed\n }\n if (request.agentTiers !== undefined) {\n const parsed = parseAgentTiersPatch(request.agentTiers)\n if (parsed.ok) agentTiers = parsed.value\n else errors.push(parsed.error)\n }\n if (request.inviteDismissed !== undefined) {\n if (typeof request.inviteDismissed !== \"boolean\") errors.push(\"invalid inviteDismissed\")\n else inviteDismissed = request.inviteDismissed\n }\n\n if (errors.length > 0) return { ok: false, errors }\n return {\n ok: true,\n settings: { version: SETTINGS_VERSION, mode, tiers, pin, agentTiers, inviteDismissed },\n }\n}\n"]}
@@ -19,4 +19,3 @@ export declare class SettingsStore {
19
19
  */
20
20
  update(patch: SettingsPatch): Promise<PatchResult>;
21
21
  }
22
- //# sourceMappingURL=store.d.ts.map
@@ -24,7 +24,15 @@ export class SettingsStore {
24
24
  * defaults instead of breaking setup; the record is not rewritten here, so
25
25
  * a later successful patch simply re-stamps the current version.
26
26
  */
27
- async load() {
27
+ load() {
28
+ // No rejection tail: #load is total (the read is caught and
29
+ // migrateSettings never throws), so run cannot reject and poison the
30
+ // chain — unlike update(), whose write can fail.
31
+ const run = this.#queue.then(() => this.#load());
32
+ this.#queue = run;
33
+ return run;
34
+ }
35
+ async #load() {
28
36
  let raw;
29
37
  try {
30
38
  raw = await this.storage.read();
@@ -1 +1 @@
1
- {"version":3,"file":"store.js","sourceRoot":"","sources":["../../../src/state/settings/store.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAExD,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAE5C,MAAM,OAAO,aAAa;IAKK;IAJ7B,QAAQ,GAAe,eAAe,EAAE,CAAA;IACxC,mEAAmE;IACnE,MAAM,GAAqB,OAAO,CAAC,OAAO,EAAE,CAAA;IAE5C,YAA6B,OAAwB;QAAxB,YAAO,GAAP,OAAO,CAAiB;IAAG,CAAC;IAEzD,mEAAmE;IACnE,GAAG;QACD,OAAO,IAAI,CAAC,QAAQ,CAAA;IACtB,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,IAAI;QACR,IAAI,GAAY,CAAA;QAChB,IAAI,CAAC;YACH,GAAG,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAA;QACjC,CAAC;QAAC,MAAM,CAAC;YACP,GAAG,GAAG,SAAS,CAAA;QACjB,CAAC;QACD,IAAI,CAAC,QAAQ,GAAG,eAAe,CAAC,GAAG,CAAC,CAAA;QACpC,OAAO,IAAI,CAAC,QAAQ,CAAA;IACtB,CAAC;IAED;;;;;OAKG;IACH,MAAM,CAAC,KAAoB;QACzB,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE;YACtC,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAA;YAC/C,IAAI,CAAC,MAAM,CAAC,EAAE;gBAAE,OAAO,MAAM,CAAA;YAC7B,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;YACzC,IAAI,CAAC,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAA;YAC/B,OAAO,MAAM,CAAA;QACf,CAAC,CAAC,CAAA;QACF,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAA;QACxC,OAAO,GAAG,CAAA;IACZ,CAAC;CACF"}
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../../src/state/settings/store.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAExD,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAE5C,MAAM,OAAO,aAAa;IAKK;IAJ7B,QAAQ,GAAe,eAAe,EAAE,CAAA;IACxC,mEAAmE;IACnE,MAAM,GAAqB,OAAO,CAAC,OAAO,EAAE,CAAA;IAE5C,YAA6B,OAAwB;QAAxB,YAAO,GAAP,OAAO,CAAiB;IAAG,CAAC;IAEzD,mEAAmE;IACnE,GAAG;QACD,OAAO,IAAI,CAAC,QAAQ,CAAA;IACtB,CAAC;IAED;;;;OAIG;IACH,IAAI;QACF,4DAA4D;QAC5D,qEAAqE;QACrE,iDAAiD;QACjD,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,CAAA;QAChD,IAAI,CAAC,MAAM,GAAG,GAAG,CAAA;QACjB,OAAO,GAAG,CAAA;IACZ,CAAC;IAED,KAAK,CAAC,KAAK;QACT,IAAI,GAAY,CAAA;QAChB,IAAI,CAAC;YACH,GAAG,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAA;QACjC,CAAC;QAAC,MAAM,CAAC;YACP,GAAG,GAAG,SAAS,CAAA;QACjB,CAAC;QACD,IAAI,CAAC,QAAQ,GAAG,eAAe,CAAC,GAAG,CAAC,CAAA;QACpC,OAAO,IAAI,CAAC,QAAQ,CAAA;IACtB,CAAC;IAED;;;;;OAKG;IACH,MAAM,CAAC,KAAoB;QACzB,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE;YACtC,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAA;YAC/C,IAAI,CAAC,MAAM,CAAC,EAAE;gBAAE,OAAO,MAAM,CAAA;YAC7B,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;YACzC,IAAI,CAAC,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAA;YAC/B,OAAO,MAAM,CAAA;QACf,CAAC,CAAC,CAAA;QACF,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAA;QACxC,OAAO,GAAG,CAAA;IACZ,CAAC;CACF","sourcesContent":["/**\n * Settings store (ADP-036): the server-side single source of truth. Loads\n * once at setup (migration-on-read), serves synchronous snapshots to the\n * scheduler, and persists validated patches. Reads fail open to defaults\n * (ADP-031); write failures propagate to the caller so surfaces can report\n * them — the in-memory snapshot is only advanced after a successful write.\n */\nimport { applyPatch, migrateSettings } from \"./parse.js\"\nimport type { PatchResult, SettingsPatch, SettingsStorage, SettingsV1 } from \"./types.js\"\nimport { defaultSettings } from \"./parse.js\"\n\nexport class SettingsStore {\n #current: SettingsV1 = defaultSettings()\n /** Tail of the update chain; keeps awaiting updates serialized. */\n #queue: Promise<unknown> = Promise.resolve()\n\n constructor(private readonly storage: SettingsStorage) {}\n\n /** Current snapshot (defaults until the first successful load). */\n get(): SettingsV1 {\n return this.#current\n }\n\n /**\n * Read + migrate the persisted record. A storage read failure degrades to\n * defaults instead of breaking setup; the record is not rewritten here, so\n * a later successful patch simply re-stamps the current version.\n */\n load(): Promise<SettingsV1> {\n // No rejection tail: #load is total (the read is caught and\n // migrateSettings never throws), so run cannot reject and poison the\n // chain — unlike update(), whose write can fail.\n const run = this.#queue.then(() => this.#load())\n this.#queue = run\n return run\n }\n\n async #load(): Promise<SettingsV1> {\n let raw: unknown\n try {\n raw = await this.storage.read()\n } catch {\n raw = undefined\n }\n this.#current = migrateSettings(raw)\n return this.#current\n }\n\n /**\n * Validate, persist, then adopt. Invalid patches change nothing. Updates\n * serialize through a promise chain so two concurrent callers cannot both\n * patch the same base snapshot and lose one write (the chain swallows\n * rejections — a failed update must not poison the next one).\n */\n update(patch: SettingsPatch): Promise<PatchResult> {\n const run = this.#queue.then(async () => {\n const result = applyPatch(this.#current, patch)\n if (!result.ok) return result\n await this.storage.write(result.settings)\n this.#current = result.settings\n return result\n })\n this.#queue = run.catch(() => undefined)\n return run\n }\n}\n"]}
@@ -60,4 +60,3 @@ export interface SettingsStorage {
60
60
  read(): Promise<unknown>;
61
61
  write(settings: SettingsV1): Promise<void>;
62
62
  }
63
- //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/state/settings/types.ts"],"names":[],"mappings":"AASA,sFAAsF;AACtF,MAAM,CAAC,MAAM,YAAY,GAAG,yBAAyB,CAAA;AAErD,uCAAuC;AACvC,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAA;AAEjC;;;;GAIG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,EAAE,CAAA;AACpC,MAAM,CAAC,MAAM,eAAe,GAAG,EAAE,CAAA"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/state/settings/types.ts"],"names":[],"mappings":"AASA,sFAAsF;AACtF,MAAM,CAAC,MAAM,YAAY,GAAG,yBAAyB,CAAA;AAErD,uCAAuC;AACvC,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAA;AAEjC;;;;GAIG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,EAAE,CAAA;AACpC,MAAM,CAAC,MAAM,eAAe,GAAG,EAAE,CAAA","sourcesContent":["/**\n * Durable settings (ADP-036): versioned, migrated on read, persisted through\n * `ctx.storage` under a single key. The server plugin owns the store; TUI and\n * GUI surfaces only read snapshots and send patches (ADP-034/036).\n */\nimport type { OperatingMode } from \"../../core/scheduler/types.js\"\nimport type { TierName } from \"../../core/tier-policy/types.js\"\nimport type { ModelRef } from \"../../core/work-unit/types.js\"\n\n/** Storage key for the settings record (see architecture \"Persistence ownership\"). */\nexport const SETTINGS_KEY = \"coool.adaptive/settings\"\n\n/** Current settings schema version. */\nexport const SETTINGS_VERSION = 1\n\n/**\n * Product bounds, not user knobs: they keep a hostile or buggy write from\n * growing state without limit. (Patch error lists need no cap: at most one\n * error per field, and the patch has five fields.)\n */\nexport const MAX_TIER_RESOURCES = 32\nexport const MAX_AGENT_TIERS = 64\n\nexport interface SettingsV1 {\n readonly version: typeof SETTINGS_VERSION\n /** OFF does nothing; OBSERVE is the safe default after install (ADP-029/032). */\n readonly mode: OperatingMode\n /** Ordered per-tier resource lists; order is user policy and never reordered (ADP-005). */\n readonly tiers: Readonly<Record<TierName, readonly ModelRef[]>>\n /**\n * Global explicit user pin. `null` = no pin. A pin names a concrete model\n * and outranks every other routing input (ADP-002).\n */\n readonly pin: ModelRef | null\n /** User-configured agent → tier hints (role level of the ladder, ADP-002). */\n readonly agentTiers: Readonly<Record<string, TierName>>\n /** First-install invitation dismissed (ADP-032: shown once, never nagged). */\n readonly inviteDismissed: boolean\n}\n\n/**\n * Partial update as sent by surfaces over RPC. Field absence means \"leave\n * unchanged\"; `pin: null` explicitly clears the pin.\n */\nexport interface SettingsPatch {\n readonly mode?: OperatingMode | undefined\n readonly tiers?: Readonly<Record<TierName, readonly ModelRef[]>> | undefined\n readonly pin?: ModelRef | null | undefined\n readonly agentTiers?: Readonly<Record<string, TierName>> | undefined\n readonly inviteDismissed?: boolean | undefined\n}\n\nexport type PatchResult =\n | { readonly ok: true; readonly settings: SettingsV1 }\n | {\n readonly ok: false\n readonly errors: readonly string[]\n }\n\n/**\n * Narrow storage seam so the store stays decoupled from `@opencode/plugin`\n * (only `adapters/opencode` may touch the host API). The adapter binds the\n * settings key and translates `ctx.storage`.\n */\nexport interface SettingsStorage {\n read(): Promise<unknown>\n write(settings: SettingsV1): Promise<void>\n}\n"]}
@@ -0,0 +1,4 @@
1
+ export { parseTierRequestsPayload, isValidSessionID } from "./parse.js";
2
+ export { TierRequestStore } from "./store.js";
3
+ export { TIER_REQUESTS_KEY, TIER_REQUESTS_VERSION, MAX_TIER_REQUEST_RECORDS, MAX_SESSION_ID_LENGTH, } from "./types.js";
4
+ export type { TierRequestRecord, TierRequestsPayload, TierRequestsStorage } from "./types.js";
@@ -0,0 +1,4 @@
1
+ export { parseTierRequestsPayload, isValidSessionID } from "./parse.js";
2
+ export { TierRequestStore } from "./store.js";
3
+ export { TIER_REQUESTS_KEY, TIER_REQUESTS_VERSION, MAX_TIER_REQUEST_RECORDS, MAX_SESSION_ID_LENGTH, } from "./types.js";
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/state/tier-requests/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AACvE,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAC7C,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,wBAAwB,EACxB,qBAAqB,GACtB,MAAM,YAAY,CAAA","sourcesContent":["export { parseTierRequestsPayload, isValidSessionID } from \"./parse.js\"\nexport { TierRequestStore } from \"./store.js\"\nexport {\n TIER_REQUESTS_KEY,\n TIER_REQUESTS_VERSION,\n MAX_TIER_REQUEST_RECORDS,\n MAX_SESSION_ID_LENGTH,\n} from \"./types.js\"\nexport type { TierRequestRecord, TierRequestsPayload, TierRequestsStorage } from \"./types.js\"\n"]}
@@ -0,0 +1,3 @@
1
+ import type { TierRequestRecord } from "./types.js";
2
+ export { isValidSessionID } from "../session-modes/parse.js";
3
+ export declare function parseTierRequestsPayload(raw: unknown): TierRequestRecord[];
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Read-side parsing for persisted tier requests. Total like every `state/`
3
+ * parser: it accepts `unknown` and returns typed records, dropping anything
4
+ * invalid — a corrupted file can never take the plugin down (ADP-031). A
5
+ * partially corrupted payload keeps its good entries.
6
+ */
7
+ import { TIERS } from "../../core/tier-policy/types.js";
8
+ import { isValidSessionID } from "../session-modes/parse.js";
9
+ import { TIER_REQUESTS_VERSION } from "./types.js";
10
+ export { isValidSessionID } from "../session-modes/parse.js";
11
+ function isRecord(value) {
12
+ return typeof value === "object" && value !== null && !Array.isArray(value);
13
+ }
14
+ function isFiniteNumber(raw) {
15
+ return typeof raw === "number" && Number.isFinite(raw);
16
+ }
17
+ function parseTier(raw) {
18
+ if (typeof raw !== "string")
19
+ return undefined;
20
+ return TIERS.includes(raw) ? raw : undefined;
21
+ }
22
+ function parseRecord(raw) {
23
+ if (!isRecord(raw))
24
+ return undefined;
25
+ const sessionID = isValidSessionID(raw["sessionID"]) ? raw["sessionID"] : undefined;
26
+ const tier = parseTier(raw["tier"]);
27
+ const updatedAt = raw["updatedAt"];
28
+ if (sessionID === undefined || tier === undefined || !isFiniteNumber(updatedAt))
29
+ return undefined;
30
+ return { sessionID, tier, updatedAt };
31
+ }
32
+ export function parseTierRequestsPayload(raw) {
33
+ if (!isRecord(raw))
34
+ return [];
35
+ if (raw["version"] !== TIER_REQUESTS_VERSION)
36
+ return [];
37
+ const list = raw["records"];
38
+ if (!Array.isArray(list))
39
+ return [];
40
+ // A hostile or duplicated payload can carry the same session twice; the
41
+ // most recently updated record wins so `get` is not order-dependent.
42
+ const bySession = new Map();
43
+ for (const entry of list.slice(0, 512)) {
44
+ const record = parseRecord(entry);
45
+ if (record === undefined)
46
+ continue;
47
+ const kept = bySession.get(record.sessionID);
48
+ if (kept === undefined || record.updatedAt > kept.updatedAt)
49
+ bySession.set(record.sessionID, record);
50
+ }
51
+ return [...bySession.values()];
52
+ }
53
+ //# sourceMappingURL=parse.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse.js","sourceRoot":"","sources":["../../../src/state/tier-requests/parse.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,KAAK,EAAE,MAAM,iCAAiC,CAAA;AAEvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAA;AAC5D,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAA;AAGlD,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAA;AAE5D,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;AAC7E,CAAC;AAED,SAAS,cAAc,CAAC,GAAY;IAClC,OAAO,OAAO,GAAG,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAA;AACxD,CAAC;AAED,SAAS,SAAS,CAAC,GAAY;IAC7B,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAA;IAC7C,OAAQ,KAA2B,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAE,GAAgB,CAAC,CAAC,CAAC,SAAS,CAAA;AACnF,CAAC;AAED,SAAS,WAAW,CAAC,GAAY;IAC/B,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,SAAS,CAAA;IACpC,MAAM,SAAS,GAAG,gBAAgB,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;IACnF,MAAM,IAAI,GAAG,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAA;IACnC,MAAM,SAAS,GAAG,GAAG,CAAC,WAAW,CAAC,CAAA;IAClC,IAAI,SAAS,KAAK,SAAS,IAAI,IAAI,KAAK,SAAS,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC;QAAE,OAAO,SAAS,CAAA;IACjG,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,CAAA;AACvC,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,GAAY;IACnD,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,EAAE,CAAA;IAC7B,IAAI,GAAG,CAAC,SAAS,CAAC,KAAK,qBAAqB;QAAE,OAAO,EAAE,CAAA;IACvD,MAAM,IAAI,GAAG,GAAG,CAAC,SAAS,CAAC,CAAA;IAC3B,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC;QAAE,OAAO,EAAE,CAAA;IACnC,wEAAwE;IACxE,qEAAqE;IACrE,MAAM,SAAS,GAAG,IAAI,GAAG,EAA6B,CAAA;IACtD,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC;QACvC,MAAM,MAAM,GAAG,WAAW,CAAC,KAAK,CAAC,CAAA;QACjC,IAAI,MAAM,KAAK,SAAS;YAAE,SAAQ;QAClC,MAAM,IAAI,GAAG,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;QAC5C,IAAI,IAAI,KAAK,SAAS,IAAI,MAAM,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS;YACzD,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAA;IAC3C,CAAC;IACD,OAAO,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,CAAA;AAChC,CAAC","sourcesContent":["/**\n * Read-side parsing for persisted tier requests. Total like every `state/`\n * parser: it accepts `unknown` and returns typed records, dropping anything\n * invalid — a corrupted file can never take the plugin down (ADP-031). A\n * partially corrupted payload keeps its good entries.\n */\nimport { TIERS } from \"../../core/tier-policy/types.js\"\nimport type { TierName } from \"../../core/tier-policy/types.js\"\nimport { isValidSessionID } from \"../session-modes/parse.js\"\nimport { TIER_REQUESTS_VERSION } from \"./types.js\"\nimport type { TierRequestRecord } from \"./types.js\"\n\nexport { isValidSessionID } from \"../session-modes/parse.js\"\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value)\n}\n\nfunction isFiniteNumber(raw: unknown): raw is number {\n return typeof raw === \"number\" && Number.isFinite(raw)\n}\n\nfunction parseTier(raw: unknown): TierName | undefined {\n if (typeof raw !== \"string\") return undefined\n return (TIERS as readonly string[]).includes(raw) ? (raw as TierName) : undefined\n}\n\nfunction parseRecord(raw: unknown): TierRequestRecord | undefined {\n if (!isRecord(raw)) return undefined\n const sessionID = isValidSessionID(raw[\"sessionID\"]) ? raw[\"sessionID\"] : undefined\n const tier = parseTier(raw[\"tier\"])\n const updatedAt = raw[\"updatedAt\"]\n if (sessionID === undefined || tier === undefined || !isFiniteNumber(updatedAt)) return undefined\n return { sessionID, tier, updatedAt }\n}\n\nexport function parseTierRequestsPayload(raw: unknown): TierRequestRecord[] {\n if (!isRecord(raw)) return []\n if (raw[\"version\"] !== TIER_REQUESTS_VERSION) return []\n const list = raw[\"records\"]\n if (!Array.isArray(list)) return []\n // A hostile or duplicated payload can carry the same session twice; the\n // most recently updated record wins so `get` is not order-dependent.\n const bySession = new Map<string, TierRequestRecord>()\n for (const entry of list.slice(0, 512)) {\n const record = parseRecord(entry)\n if (record === undefined) continue\n const kept = bySession.get(record.sessionID)\n if (kept === undefined || record.updatedAt > kept.updatedAt)\n bySession.set(record.sessionID, record)\n }\n return [...bySession.values()]\n}\n"]}
@@ -0,0 +1,27 @@
1
+ import type { TierName } from "../../core/tier-policy/types.js";
2
+ import type { TierRequestRecord, TierRequestsStorage } from "./types.js";
3
+ export declare class TierRequestStore {
4
+ #private;
5
+ private readonly storage;
6
+ private readonly clock;
7
+ constructor(storage: TierRequestsStorage, clock: () => number);
8
+ /** Rebuild from storage (restart behavior). A read failure yields an empty store. */
9
+ load(): Promise<void>;
10
+ /** All retained records. */
11
+ snapshot(): readonly TierRequestRecord[];
12
+ /** The session's request, or `null` when it follows the routing ladder. */
13
+ get(sessionID: string): TierName | null;
14
+ /**
15
+ * Set (or with `null`, remove) one session's request. The bound keeps the
16
+ * most recently updated records — requests for long-gone sessions matter
17
+ * less than the ones being actively steered.
18
+ */
19
+ set(sessionID: string, tier: TierName | null): Promise<void>;
20
+ /**
21
+ * Resolve only after every operation queued before this call has committed.
22
+ * The `adaptive_tier` tool records its request fire-and-forget (the tool
23
+ * handler is sync on the RPC surface), so readers — routing and the control
24
+ * surfaces — flush before reading to observe it deterministically.
25
+ */
26
+ flush(): Promise<void>;
27
+ }
@@ -0,0 +1,96 @@
1
+ /**
2
+ * Bounded per-session tier-request store. Keeps the most recently updated
3
+ * records (bounded, least-recently-updated evicted) and persists on every
4
+ * change. As everywhere else in `state/`, memory is only advanced after a
5
+ * successful write, so memory and disk never diverge; write failures
6
+ * propagate to the caller — the wiring layer's fail-open wrapper decides how
7
+ * to degrade (ADP-031).
8
+ */
9
+ import { TIERS, isTierName } from "../../core/tier-policy/types.js";
10
+ import { parseTierRequestsPayload, isValidSessionID } from "./parse.js";
11
+ import { MAX_SESSION_ID_LENGTH, MAX_TIER_REQUEST_RECORDS, TIER_REQUESTS_VERSION } from "./types.js";
12
+ export class TierRequestStore {
13
+ storage;
14
+ clock;
15
+ #records = [];
16
+ #queue = Promise.resolve();
17
+ constructor(storage, clock) {
18
+ this.storage = storage;
19
+ this.clock = clock;
20
+ }
21
+ /** Rebuild from storage (restart behavior). A read failure yields an empty store. */
22
+ load() {
23
+ return this.#serialize(() => this.#load());
24
+ }
25
+ async #load() {
26
+ let raw;
27
+ try {
28
+ raw = await this.storage.read();
29
+ }
30
+ catch {
31
+ this.#records = [];
32
+ return;
33
+ }
34
+ this.#records = parseTierRequestsPayload(raw);
35
+ }
36
+ /** All retained records. */
37
+ snapshot() {
38
+ return this.#records;
39
+ }
40
+ /** The session's request, or `null` when it follows the routing ladder. */
41
+ get(sessionID) {
42
+ return this.#records.find((record) => record.sessionID === sessionID)?.tier ?? null;
43
+ }
44
+ /**
45
+ * Set (or with `null`, remove) one session's request. The bound keeps the
46
+ * most recently updated records — requests for long-gone sessions matter
47
+ * less than the ones being actively steered.
48
+ */
49
+ async set(sessionID, tier) {
50
+ // Defensive re-validation at the persistence boundary: the tool and the
51
+ // RPC handler validate first; these guards keep malformed in-process
52
+ // callers from persisting junk.
53
+ if (!isValidSessionID(sessionID)) {
54
+ throw new Error(`sessionID must be a non-empty string of at most ${String(MAX_SESSION_ID_LENGTH)} characters`);
55
+ }
56
+ if (tier !== null && !isTierName(tier)) {
57
+ throw new Error(`tier must be one of ${TIERS.join(", ")} or null`);
58
+ }
59
+ return this.#serialize(() => this.#set(sessionID, tier));
60
+ }
61
+ async #set(sessionID, tier) {
62
+ const updatedAt = this.clock();
63
+ const kept = this.#records.filter((record) => record.sessionID !== sessionID);
64
+ const next = tier === null
65
+ ? kept
66
+ : bound([...kept, { sessionID, tier, updatedAt }], MAX_TIER_REQUEST_RECORDS);
67
+ // Persist BEFORE committing memory: a write failure must leave memory
68
+ // and disk consistent (the caller decides how to fail open).
69
+ const payload = { version: TIER_REQUESTS_VERSION, records: next };
70
+ await this.storage.write(payload);
71
+ this.#records = next;
72
+ }
73
+ /**
74
+ * Resolve only after every operation queued before this call has committed.
75
+ * The `adaptive_tier` tool records its request fire-and-forget (the tool
76
+ * handler is sync on the RPC surface), so readers — routing and the control
77
+ * surfaces — flush before reading to observe it deterministically.
78
+ */
79
+ flush() {
80
+ return this.#serialize(() => Promise.resolve());
81
+ }
82
+ // Reloads share the mutation queue so stale reads cannot overwrite commits.
83
+ // Recover only the queue tail: the failed operation still rejects its caller.
84
+ #serialize(operation) {
85
+ const run = this.#queue.then(operation);
86
+ this.#queue = run.catch(() => undefined);
87
+ return run;
88
+ }
89
+ }
90
+ /** Keep the newest records when over the cap. */
91
+ function bound(records, max) {
92
+ if (records.length <= max)
93
+ return records;
94
+ return [...records].sort((left, right) => right.updatedAt - left.updatedAt).slice(0, max);
95
+ }
96
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../../src/state/tier-requests/store.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Bounded per-session tier-request store. Keeps the most recently updated\n * records (bounded, least-recently-updated evicted) and persists on every\n * change. As everywhere else in `state/`, memory is only advanced after a\n * successful write, so memory and disk never diverge; write failures\n * propagate to the caller — the wiring layer's fail-open wrapper decides how\n * to degrade (ADP-031).\n */\nimport { TIERS, isTierName } from \"../../core/tier-policy/types.js\"\nimport { parseTierRequestsPayload, isValidSessionID } from \"./parse.js\"\nimport { MAX_SESSION_ID_LENGTH, MAX_TIER_REQUEST_RECORDS, TIER_REQUESTS_VERSION } from \"./types.js\"\nimport type { TierName } from \"../../core/tier-policy/types.js\"\nimport type { TierRequestRecord, TierRequestsPayload, TierRequestsStorage } from \"./types.js\"\n\nexport class TierRequestStore {\n #records: TierRequestRecord[] = []\n #queue: Promise<void> = Promise.resolve()\n\n constructor(\n private readonly storage: TierRequestsStorage,\n private readonly clock: () => number,\n ) {}\n\n /** Rebuild from storage (restart behavior). A read failure yields an empty store. */\n load(): Promise<void> {\n return this.#serialize(() => this.#load())\n }\n\n async #load(): Promise<void> {\n let raw: unknown\n try {\n raw = await this.storage.read()\n } catch {\n this.#records = []\n return\n }\n this.#records = parseTierRequestsPayload(raw)\n }\n\n /** All retained records. */\n snapshot(): readonly TierRequestRecord[] {\n return this.#records\n }\n\n /** The session's request, or `null` when it follows the routing ladder. */\n get(sessionID: string): TierName | null {\n return this.#records.find((record) => record.sessionID === sessionID)?.tier ?? null\n }\n\n /**\n * Set (or with `null`, remove) one session's request. The bound keeps the\n * most recently updated records — requests for long-gone sessions matter\n * less than the ones being actively steered.\n */\n async set(sessionID: string, tier: TierName | null): Promise<void> {\n // Defensive re-validation at the persistence boundary: the tool and the\n // RPC handler validate first; these guards keep malformed in-process\n // callers from persisting junk.\n if (!isValidSessionID(sessionID)) {\n throw new Error(\n `sessionID must be a non-empty string of at most ${String(MAX_SESSION_ID_LENGTH)} characters`,\n )\n }\n if (tier !== null && !isTierName(tier)) {\n throw new Error(`tier must be one of ${TIERS.join(\", \")} or null`)\n }\n return this.#serialize(() => this.#set(sessionID, tier))\n }\n\n async #set(sessionID: string, tier: TierName | null): Promise<void> {\n const updatedAt = this.clock()\n const kept = this.#records.filter((record) => record.sessionID !== sessionID)\n const next =\n tier === null\n ? kept\n : bound([...kept, { sessionID, tier, updatedAt }], MAX_TIER_REQUEST_RECORDS)\n // Persist BEFORE committing memory: a write failure must leave memory\n // and disk consistent (the caller decides how to fail open).\n const payload: TierRequestsPayload = { version: TIER_REQUESTS_VERSION, records: next }\n await this.storage.write(payload)\n this.#records = next\n }\n\n /**\n * Resolve only after every operation queued before this call has committed.\n * The `adaptive_tier` tool records its request fire-and-forget (the tool\n * handler is sync on the RPC surface), so readers — routing and the control\n * surfaces — flush before reading to observe it deterministically.\n */\n flush(): Promise<void> {\n return this.#serialize(() => Promise.resolve())\n }\n\n // Reloads share the mutation queue so stale reads cannot overwrite commits.\n // Recover only the queue tail: the failed operation still rejects its caller.\n #serialize(operation: () => Promise<void>): Promise<void> {\n const run = this.#queue.then(operation)\n this.#queue = run.catch(() => undefined)\n return run\n }\n}\n\n/** Keep the newest records when over the cap. */\nfunction bound(records: TierRequestRecord[], max: number): TierRequestRecord[] {\n if (records.length <= max) return records\n return [...records].sort((left, right) => right.updatedAt - left.updatedAt).slice(0, max)\n}\n"]}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Persisted per-session tier requests (ADP-055). The agent declares the tier
3
+ * of the task it is starting through the `adaptive_tier` tool and the request
4
+ * steers the session's admissions until cleared. The host's TUI-mode plugin
5
+ * reconciliation can serve RPC from an instance whose routing hooks live on
6
+ * another instance, and a restart must not silently drop the agent's explicit
7
+ * declaration — the records persist through the storage seam like every other
8
+ * state (mirroring the session-mode overrides, ADP-054).
9
+ */
10
+ import type { TierName } from "../../core/tier-policy/types.js";
11
+ export declare const TIER_REQUESTS_KEY = "coool.adaptive/tier-requests";
12
+ export declare const TIER_REQUESTS_VERSION = 1;
13
+ /** Product bound — not a user knob. Keeps the most recently updated records. */
14
+ export declare const MAX_TIER_REQUEST_RECORDS = 512;
15
+ /** A session id beyond this bound is not a real host identifier. */
16
+ export declare const MAX_SESSION_ID_LENGTH = 128;
17
+ export interface TierRequestRecord {
18
+ readonly sessionID: string;
19
+ readonly tier: TierName;
20
+ readonly updatedAt: number;
21
+ }
22
+ export interface TierRequestsPayload {
23
+ readonly version: typeof TIER_REQUESTS_VERSION;
24
+ readonly records: readonly TierRequestRecord[];
25
+ }
26
+ /** Storage seam — the adapter binds `TIER_REQUESTS_KEY` to `ctx.storage`. */
27
+ export interface TierRequestsStorage {
28
+ read(): Promise<unknown>;
29
+ write(payload: TierRequestsPayload): Promise<void>;
30
+ }
@@ -0,0 +1,7 @@
1
+ export const TIER_REQUESTS_KEY = "coool.adaptive/tier-requests";
2
+ export const TIER_REQUESTS_VERSION = 1;
3
+ /** Product bound — not a user knob. Keeps the most recently updated records. */
4
+ export const MAX_TIER_REQUEST_RECORDS = 512;
5
+ /** A session id beyond this bound is not a real host identifier. */
6
+ export const MAX_SESSION_ID_LENGTH = 128;
7
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/state/tier-requests/types.ts"],"names":[],"mappings":"AAWA,MAAM,CAAC,MAAM,iBAAiB,GAAG,8BAA8B,CAAA;AAC/D,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAA;AACtC,gFAAgF;AAChF,MAAM,CAAC,MAAM,wBAAwB,GAAG,GAAG,CAAA;AAC3C,oEAAoE;AACpE,MAAM,CAAC,MAAM,qBAAqB,GAAG,GAAG,CAAA","sourcesContent":["/**\n * Persisted per-session tier requests (ADP-055). The agent declares the tier\n * of the task it is starting through the `adaptive_tier` tool and the request\n * steers the session's admissions until cleared. The host's TUI-mode plugin\n * reconciliation can serve RPC from an instance whose routing hooks live on\n * another instance, and a restart must not silently drop the agent's explicit\n * declaration — the records persist through the storage seam like every other\n * state (mirroring the session-mode overrides, ADP-054).\n */\nimport type { TierName } from \"../../core/tier-policy/types.js\"\n\nexport const TIER_REQUESTS_KEY = \"coool.adaptive/tier-requests\"\nexport const TIER_REQUESTS_VERSION = 1\n/** Product bound — not a user knob. Keeps the most recently updated records. */\nexport const MAX_TIER_REQUEST_RECORDS = 512\n/** A session id beyond this bound is not a real host identifier. */\nexport const MAX_SESSION_ID_LENGTH = 128\n\nexport interface TierRequestRecord {\n readonly sessionID: string\n readonly tier: TierName\n readonly updatedAt: number\n}\n\nexport interface TierRequestsPayload {\n readonly version: typeof TIER_REQUESTS_VERSION\n readonly records: readonly TierRequestRecord[]\n}\n\n/** Storage seam — the adapter binds `TIER_REQUESTS_KEY` to `ctx.storage`. */\nexport interface TierRequestsStorage {\n read(): Promise<unknown>\n write(payload: TierRequestsPayload): Promise<void>\n}\n"]}