@coool/opencode-adaptive 0.0.0-stage → 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 (334) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +99 -2
  3. package/dist/adapters/codex-capacity/index.d.ts +4 -0
  4. package/dist/adapters/codex-capacity/index.js +5 -0
  5. package/dist/adapters/codex-capacity/index.js.map +1 -0
  6. package/dist/adapters/codex-capacity/parse.d.ts +28 -0
  7. package/dist/adapters/codex-capacity/parse.js +146 -0
  8. package/dist/adapters/codex-capacity/parse.js.map +1 -0
  9. package/dist/adapters/codex-capacity/reading.d.ts +9 -0
  10. package/dist/adapters/codex-capacity/reading.js +45 -0
  11. package/dist/adapters/codex-capacity/reading.js.map +1 -0
  12. package/dist/adapters/codex-capacity/sensor.d.ts +23 -0
  13. package/dist/adapters/codex-capacity/sensor.js +30 -0
  14. package/dist/adapters/codex-capacity/sensor.js.map +1 -0
  15. package/dist/adapters/codex-capacity/types.d.ts +31 -0
  16. package/dist/adapters/codex-capacity/types.js +18 -0
  17. package/dist/adapters/codex-capacity/types.js.map +1 -0
  18. package/dist/adapters/opencode/escalation-tool.d.ts +51 -0
  19. package/dist/adapters/opencode/escalation-tool.js +61 -0
  20. package/dist/adapters/opencode/escalation-tool.js.map +1 -0
  21. package/dist/adapters/opencode/events.d.ts +23 -0
  22. package/dist/adapters/opencode/events.js +68 -0
  23. package/dist/adapters/opencode/events.js.map +1 -0
  24. package/dist/adapters/opencode/hooks.d.ts +34 -0
  25. package/dist/adapters/opencode/hooks.js +29 -0
  26. package/dist/adapters/opencode/hooks.js.map +1 -0
  27. package/dist/adapters/opencode/index.d.ts +16 -0
  28. package/dist/adapters/opencode/index.js +9 -0
  29. package/dist/adapters/opencode/index.js.map +1 -0
  30. package/dist/adapters/opencode/inventory.d.ts +30 -0
  31. package/dist/adapters/opencode/inventory.js +53 -0
  32. package/dist/adapters/opencode/inventory.js.map +1 -0
  33. package/dist/adapters/opencode/report.d.ts +91 -0
  34. package/dist/adapters/opencode/report.js +145 -0
  35. package/dist/adapters/opencode/report.js.map +1 -0
  36. package/dist/adapters/opencode/session-ops.d.ts +39 -0
  37. package/dist/adapters/opencode/session-ops.js +32 -0
  38. package/dist/adapters/opencode/session-ops.js.map +1 -0
  39. package/dist/adapters/opencode/storage.d.ts +15 -0
  40. package/dist/adapters/opencode/storage.js +8 -0
  41. package/dist/adapters/opencode/storage.js.map +1 -0
  42. package/dist/adapters/opencode/tier-tool.d.ts +37 -0
  43. package/dist/adapters/opencode/tier-tool.js +72 -0
  44. package/dist/adapters/opencode/tier-tool.js.map +1 -0
  45. package/dist/adapters/opencode/types.d.ts +101 -0
  46. package/dist/adapters/opencode/types.js +2 -0
  47. package/dist/adapters/opencode/types.js.map +1 -0
  48. package/dist/core/compatibility/gate.d.ts +7 -0
  49. package/dist/core/compatibility/gate.js +51 -0
  50. package/dist/core/compatibility/gate.js.map +1 -0
  51. package/dist/core/compatibility/index.d.ts +2 -0
  52. package/dist/core/compatibility/index.js +3 -0
  53. package/dist/core/compatibility/index.js.map +1 -0
  54. package/dist/core/compatibility/types.d.ts +53 -0
  55. package/dist/core/compatibility/types.js +27 -0
  56. package/dist/core/compatibility/types.js.map +1 -0
  57. package/dist/core/scheduler/admit.d.ts +6 -0
  58. package/dist/core/scheduler/admit.js +154 -0
  59. package/dist/core/scheduler/admit.js.map +1 -0
  60. package/dist/core/scheduler/escalate.d.ts +6 -0
  61. package/dist/core/scheduler/escalate.js +45 -0
  62. package/dist/core/scheduler/escalate.js.map +1 -0
  63. package/dist/core/scheduler/index.d.ts +4 -0
  64. package/dist/core/scheduler/index.js +5 -0
  65. package/dist/core/scheduler/index.js.map +1 -0
  66. package/dist/core/scheduler/mode.d.ts +8 -0
  67. package/dist/core/scheduler/mode.js +10 -0
  68. package/dist/core/scheduler/mode.js.map +1 -0
  69. package/dist/core/scheduler/types.d.ts +136 -0
  70. package/dist/core/scheduler/types.js +75 -0
  71. package/dist/core/scheduler/types.js.map +1 -0
  72. package/dist/core/tier-policy/index.d.ts +3 -0
  73. package/dist/core/tier-policy/index.js +4 -0
  74. package/dist/core/tier-policy/index.js.map +1 -0
  75. package/dist/core/tier-policy/resolve.d.ts +18 -0
  76. package/dist/core/tier-policy/resolve.js +52 -0
  77. package/dist/core/tier-policy/resolve.js.map +1 -0
  78. package/dist/core/tier-policy/tier-list.d.ts +10 -0
  79. package/dist/core/tier-policy/tier-list.js +23 -0
  80. package/dist/core/tier-policy/tier-list.js.map +1 -0
  81. package/dist/core/tier-policy/types.d.ts +86 -0
  82. package/dist/core/tier-policy/types.js +49 -0
  83. package/dist/core/tier-policy/types.js.map +1 -0
  84. package/dist/core/work-unit/index.d.ts +3 -0
  85. package/dist/core/work-unit/index.js +4 -0
  86. package/dist/core/work-unit/index.js.map +1 -0
  87. package/dist/core/work-unit/interruption.d.ts +7 -0
  88. package/dist/core/work-unit/interruption.js +12 -0
  89. package/dist/core/work-unit/interruption.js.map +1 -0
  90. package/dist/core/work-unit/tracker.d.ts +53 -0
  91. package/dist/core/work-unit/tracker.js +156 -0
  92. package/dist/core/work-unit/tracker.js.map +1 -0
  93. package/dist/core/work-unit/types.d.ts +151 -0
  94. package/dist/core/work-unit/types.js +23 -0
  95. package/dist/core/work-unit/types.js.map +1 -0
  96. package/dist/execution/continuation/execute.d.ts +18 -0
  97. package/dist/execution/continuation/execute.js +31 -0
  98. package/dist/execution/continuation/execute.js.map +1 -0
  99. package/dist/execution/continuation/index.d.ts +4 -0
  100. package/dist/execution/continuation/index.js +4 -0
  101. package/dist/execution/continuation/index.js.map +1 -0
  102. package/dist/execution/continuation/plan.d.ts +12 -0
  103. package/dist/execution/continuation/plan.js +18 -0
  104. package/dist/execution/continuation/plan.js.map +1 -0
  105. package/dist/execution/continuation/prompts.d.ts +7 -0
  106. package/dist/execution/continuation/prompts.js +8 -0
  107. package/dist/execution/continuation/prompts.js.map +1 -0
  108. package/dist/execution/continuation/types.d.ts +68 -0
  109. package/dist/execution/continuation/types.js +15 -0
  110. package/dist/execution/continuation/types.js.map +1 -0
  111. package/dist/execution/escalation/index.d.ts +1 -0
  112. package/dist/execution/escalation/index.js +2 -0
  113. package/dist/execution/escalation/index.js.map +1 -0
  114. package/dist/execution/escalation/types.d.ts +30 -0
  115. package/dist/execution/escalation/types.js +49 -0
  116. package/dist/execution/escalation/types.js.map +1 -0
  117. package/dist/execution/index.d.ts +4 -0
  118. package/dist/execution/index.js +5 -0
  119. package/dist/execution/index.js.map +1 -0
  120. package/dist/execution/parking/index.d.ts +2 -0
  121. package/dist/execution/parking/index.js +2 -0
  122. package/dist/execution/parking/index.js.map +1 -0
  123. package/dist/execution/parking/plan.d.ts +39 -0
  124. package/dist/execution/parking/plan.js +34 -0
  125. package/dist/execution/parking/plan.js.map +1 -0
  126. package/dist/execution/retry/decide.d.ts +29 -0
  127. package/dist/execution/retry/decide.js +75 -0
  128. package/dist/execution/retry/decide.js.map +1 -0
  129. package/dist/execution/retry/index.d.ts +2 -0
  130. package/dist/execution/retry/index.js +3 -0
  131. package/dist/execution/retry/index.js.map +1 -0
  132. package/dist/execution/retry/types.d.ts +64 -0
  133. package/dist/execution/retry/types.js +9 -0
  134. package/dist/execution/retry/types.js.map +1 -0
  135. package/dist/gui-experimental.cjs +1 -0
  136. package/dist/gui.d.ts +16 -0
  137. package/dist/gui.js +73 -0
  138. package/dist/gui.js.map +1 -0
  139. package/dist/health/capacity/index.d.ts +3 -0
  140. package/dist/health/capacity/index.js +4 -0
  141. package/dist/health/capacity/index.js.map +1 -0
  142. package/dist/health/capacity/merge.d.ts +57 -0
  143. package/dist/health/capacity/merge.js +154 -0
  144. package/dist/health/capacity/merge.js.map +1 -0
  145. package/dist/health/capacity/registry.d.ts +40 -0
  146. package/dist/health/capacity/registry.js +106 -0
  147. package/dist/health/capacity/registry.js.map +1 -0
  148. package/dist/health/capacity/types.d.ts +73 -0
  149. package/dist/health/capacity/types.js +6 -0
  150. package/dist/health/capacity/types.js.map +1 -0
  151. package/dist/health/circuit-breaker/breaker.d.ts +91 -0
  152. package/dist/health/circuit-breaker/breaker.js +150 -0
  153. package/dist/health/circuit-breaker/breaker.js.map +1 -0
  154. package/dist/health/circuit-breaker/index.d.ts +2 -0
  155. package/dist/health/circuit-breaker/index.js +3 -0
  156. package/dist/health/circuit-breaker/index.js.map +1 -0
  157. package/dist/health/circuit-breaker/types.d.ts +52 -0
  158. package/dist/health/circuit-breaker/types.js +13 -0
  159. package/dist/health/circuit-breaker/types.js.map +1 -0
  160. package/dist/health/classifier/classify.d.ts +8 -0
  161. package/dist/health/classifier/classify.js +245 -0
  162. package/dist/health/classifier/classify.js.map +1 -0
  163. package/dist/health/classifier/index.d.ts +2 -0
  164. package/dist/health/classifier/index.js +3 -0
  165. package/dist/health/classifier/index.js.map +1 -0
  166. package/dist/health/classifier/types.d.ts +71 -0
  167. package/dist/health/classifier/types.js +27 -0
  168. package/dist/health/classifier/types.js.map +1 -0
  169. package/dist/health/index.d.ts +4 -0
  170. package/dist/health/index.js +5 -0
  171. package/dist/health/index.js.map +1 -0
  172. package/dist/health/resource-health/index.d.ts +4 -0
  173. package/dist/health/resource-health/index.js +5 -0
  174. package/dist/health/resource-health/index.js.map +1 -0
  175. package/dist/health/resource-health/key.d.ts +18 -0
  176. package/dist/health/resource-health/key.js +54 -0
  177. package/dist/health/resource-health/key.js.map +1 -0
  178. package/dist/health/resource-health/registry.d.ts +46 -0
  179. package/dist/health/resource-health/registry.js +276 -0
  180. package/dist/health/resource-health/registry.js.map +1 -0
  181. package/dist/health/resource-health/transitions.d.ts +9 -0
  182. package/dist/health/resource-health/transitions.js +157 -0
  183. package/dist/health/resource-health/transitions.js.map +1 -0
  184. package/dist/health/resource-health/types.d.ts +122 -0
  185. package/dist/health/resource-health/types.js +44 -0
  186. package/dist/health/resource-health/types.js.map +1 -0
  187. package/dist/index.d.ts +11 -0
  188. package/dist/index.js +105 -0
  189. package/dist/index.js.map +1 -0
  190. package/dist/plugin-id.d.ts +2 -0
  191. package/dist/plugin-id.js +3 -0
  192. package/dist/plugin-id.js.map +1 -0
  193. package/dist/rpc/definition.d.ts +123 -0
  194. package/dist/rpc/definition.js +130 -0
  195. package/dist/rpc/definition.js.map +1 -0
  196. package/dist/rpc/handlers.d.ts +53 -0
  197. package/dist/rpc/handlers.js +125 -0
  198. package/dist/rpc/handlers.js.map +1 -0
  199. package/dist/rpc/status.d.ts +42 -0
  200. package/dist/rpc/status.js +45 -0
  201. package/dist/rpc/status.js.map +1 -0
  202. package/dist/rpc.d.ts +10 -0
  203. package/dist/rpc.js +8 -0
  204. package/dist/rpc.js.map +1 -0
  205. package/dist/state/capacity/index.d.ts +3 -0
  206. package/dist/state/capacity/index.js +4 -0
  207. package/dist/state/capacity/index.js.map +1 -0
  208. package/dist/state/capacity/parse.d.ts +2 -0
  209. package/dist/state/capacity/parse.js +122 -0
  210. package/dist/state/capacity/parse.js.map +1 -0
  211. package/dist/state/capacity/store.d.ts +18 -0
  212. package/dist/state/capacity/store.js +78 -0
  213. package/dist/state/capacity/store.js.map +1 -0
  214. package/dist/state/capacity/types.d.ts +37 -0
  215. package/dist/state/capacity/types.js +11 -0
  216. package/dist/state/capacity/types.js.map +1 -0
  217. package/dist/state/health/index.d.ts +4 -0
  218. package/dist/state/health/index.js +4 -0
  219. package/dist/state/health/index.js.map +1 -0
  220. package/dist/state/health/parse.d.ts +2 -0
  221. package/dist/state/health/parse.js +137 -0
  222. package/dist/state/health/parse.js.map +1 -0
  223. package/dist/state/health/store.d.ts +17 -0
  224. package/dist/state/health/store.js +69 -0
  225. package/dist/state/health/store.js.map +1 -0
  226. package/dist/state/health/types.d.ts +23 -0
  227. package/dist/state/health/types.js +5 -0
  228. package/dist/state/health/types.js.map +1 -0
  229. package/dist/state/parked-work/index.d.ts +4 -0
  230. package/dist/state/parked-work/index.js +4 -0
  231. package/dist/state/parked-work/index.js.map +1 -0
  232. package/dist/state/parked-work/parse.d.ts +6 -0
  233. package/dist/state/parked-work/parse.js +83 -0
  234. package/dist/state/parked-work/parse.js.map +1 -0
  235. package/dist/state/parked-work/store.d.ts +17 -0
  236. package/dist/state/parked-work/store.js +98 -0
  237. package/dist/state/parked-work/store.js.map +1 -0
  238. package/dist/state/parked-work/types.d.ts +41 -0
  239. package/dist/state/parked-work/types.js +7 -0
  240. package/dist/state/parked-work/types.js.map +1 -0
  241. package/dist/state/receipts/bound.d.ts +14 -0
  242. package/dist/state/receipts/bound.js +77 -0
  243. package/dist/state/receipts/bound.js.map +1 -0
  244. package/dist/state/receipts/index.d.ts +6 -0
  245. package/dist/state/receipts/index.js +5 -0
  246. package/dist/state/receipts/index.js.map +1 -0
  247. package/dist/state/receipts/parse.d.ts +6 -0
  248. package/dist/state/receipts/parse.js +226 -0
  249. package/dist/state/receipts/parse.js.map +1 -0
  250. package/dist/state/receipts/store.d.ts +34 -0
  251. package/dist/state/receipts/store.js +148 -0
  252. package/dist/state/receipts/store.js.map +1 -0
  253. package/dist/state/receipts/types.d.ts +61 -0
  254. package/dist/state/receipts/types.js +12 -0
  255. package/dist/state/receipts/types.js.map +1 -0
  256. package/dist/state/session-modes/index.d.ts +4 -0
  257. package/dist/state/session-modes/index.js +4 -0
  258. package/dist/state/session-modes/index.js.map +1 -0
  259. package/dist/state/session-modes/parse.d.ts +8 -0
  260. package/dist/state/session-modes/parse.js +62 -0
  261. package/dist/state/session-modes/parse.js.map +1 -0
  262. package/dist/state/session-modes/store.d.ts +20 -0
  263. package/dist/state/session-modes/store.js +87 -0
  264. package/dist/state/session-modes/store.js.map +1 -0
  265. package/dist/state/session-modes/types.d.ts +41 -0
  266. package/dist/state/session-modes/types.js +7 -0
  267. package/dist/state/session-modes/types.js.map +1 -0
  268. package/dist/state/settings/index.d.ts +4 -0
  269. package/dist/state/settings/index.js +4 -0
  270. package/dist/state/settings/index.js.map +1 -0
  271. package/dist/state/settings/parse.d.ts +33 -0
  272. package/dist/state/settings/parse.js +261 -0
  273. package/dist/state/settings/parse.js.map +1 -0
  274. package/dist/state/settings/store.d.ts +21 -0
  275. package/dist/state/settings/store.js +65 -0
  276. package/dist/state/settings/store.js.map +1 -0
  277. package/dist/state/settings/types.d.ts +62 -0
  278. package/dist/state/settings/types.js +12 -0
  279. package/dist/state/settings/types.js.map +1 -0
  280. package/dist/state/tier-requests/index.d.ts +4 -0
  281. package/dist/state/tier-requests/index.js +4 -0
  282. package/dist/state/tier-requests/index.js.map +1 -0
  283. package/dist/state/tier-requests/parse.d.ts +3 -0
  284. package/dist/state/tier-requests/parse.js +53 -0
  285. package/dist/state/tier-requests/parse.js.map +1 -0
  286. package/dist/state/tier-requests/store.d.ts +27 -0
  287. package/dist/state/tier-requests/store.js +96 -0
  288. package/dist/state/tier-requests/store.js.map +1 -0
  289. package/dist/state/tier-requests/types.d.ts +30 -0
  290. package/dist/state/tier-requests/types.js +7 -0
  291. package/dist/state/tier-requests/types.js.map +1 -0
  292. package/dist/supervisor/index.d.ts +4 -0
  293. package/dist/supervisor/index.js +4 -0
  294. package/dist/supervisor/index.js.map +1 -0
  295. package/dist/supervisor/log.d.ts +10 -0
  296. package/dist/supervisor/log.js +14 -0
  297. package/dist/supervisor/log.js.map +1 -0
  298. package/dist/supervisor/supervisor.d.ts +86 -0
  299. package/dist/supervisor/supervisor.js +1629 -0
  300. package/dist/supervisor/supervisor.js.map +1 -0
  301. package/dist/supervisor/types.d.ts +49 -0
  302. package/dist/supervisor/types.js +3 -0
  303. package/dist/supervisor/types.js.map +1 -0
  304. package/dist/supervisor/view.d.ts +3 -0
  305. package/dist/supervisor/view.js +4 -0
  306. package/dist/supervisor/view.js.map +1 -0
  307. package/dist/tui.d.ts +15 -0
  308. package/dist/tui.js +256 -0
  309. package/dist/tui.js.map +1 -0
  310. package/dist/ui/gui/api.d.ts +17 -0
  311. package/dist/ui/gui/api.js +21 -0
  312. package/dist/ui/gui/api.js.map +1 -0
  313. package/dist/ui/gui/view.d.ts +26 -0
  314. package/dist/ui/gui/view.js +49 -0
  315. package/dist/ui/gui/view.js.map +1 -0
  316. package/dist/ui/tui/controller.d.ts +97 -0
  317. package/dist/ui/tui/controller.js +415 -0
  318. package/dist/ui/tui/controller.js.map +1 -0
  319. package/dist/ui/tui/menu.d.ts +55 -0
  320. package/dist/ui/tui/menu.js +176 -0
  321. package/dist/ui/tui/menu.js.map +1 -0
  322. package/dist/ui/tui/options.d.ts +19 -0
  323. package/dist/ui/tui/options.js +17 -0
  324. package/dist/ui/tui/options.js.map +1 -0
  325. package/dist/ui/tui/receipts.d.ts +21 -0
  326. package/dist/ui/tui/receipts.js +112 -0
  327. package/dist/ui/tui/receipts.js.map +1 -0
  328. package/dist/ui/tui/status.d.ts +22 -0
  329. package/dist/ui/tui/status.js +92 -0
  330. package/dist/ui/tui/status.js.map +1 -0
  331. package/dist/ui/tui/tiers.d.ts +51 -0
  332. package/dist/ui/tui/tiers.js +108 -0
  333. package/dist/ui/tui/tiers.js.map +1 -0
  334. package/package.json +85 -4
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Resource health types (ADP-007, ADP-012, ADP-021).
3
+ *
4
+ * A resource is identified at the narrowest scope the evidence supports:
5
+ * provider → account → model → variant. Health states are a closed set and
6
+ * every transition between them is defined by the pure transition layer; the
7
+ * registry never invents states. The circuit breaker (ADP-019) is an
8
+ * orthogonal axis stored per resource record.
9
+ */
10
+ import { DEFAULT_BREAKER_CONFIG, } from "../circuit-breaker/types.js";
11
+ export const RESOURCE_SCOPES = [
12
+ "provider",
13
+ "account",
14
+ "model",
15
+ "variant",
16
+ ];
17
+ export const HEALTH_STATES = [
18
+ "healthy",
19
+ "draining",
20
+ "degraded",
21
+ "rate_limited",
22
+ "quota_exhausted",
23
+ "unavailable",
24
+ ];
25
+ export const DEFAULT_HEALTH_CONFIG = {
26
+ breaker: DEFAULT_BREAKER_CONFIG,
27
+ defaultRateLimitWindowMs: 30_000,
28
+ defaultQuotaWindowMs: 15 * 60_000,
29
+ };
30
+ /**
31
+ * Why an assessment blocks new work. Ordered from hardest to softest fact:
32
+ * hard resource states (unavailable, quota, rate limit) are direct evidence;
33
+ * breaker reasons are inferred from failure counts; draining is a policy
34
+ * request, not a health fact.
35
+ */
36
+ export const BLOCKED_REASONS = [
37
+ "unavailable",
38
+ "quota-exhausted",
39
+ "rate-limited",
40
+ "breaker-open",
41
+ "probe-in-flight",
42
+ "draining",
43
+ ];
44
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/health/resource-health/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EACL,sBAAsB,GAGvB,MAAM,6BAA6B,CAAA;AAGpC,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,UAAU;IACV,SAAS;IACT,OAAO;IACP,SAAS;CAC2B,CAAA;AAiBtC,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,SAAS;IACT,UAAU;IACV,UAAU;IACV,cAAc;IACd,iBAAiB;IACjB,aAAa;CACuB,CAAA;AA6DtC,MAAM,CAAC,MAAM,qBAAqB,GAAyB;IACzD,OAAO,EAAE,sBAAsB;IAC/B,wBAAwB,EAAE,MAAM;IAChC,oBAAoB,EAAE,EAAE,GAAG,MAAM;CAClC,CAAA;AAKD;;;;;GAKG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,aAAa;IACb,iBAAiB;IACjB,cAAc;IACd,cAAc;IACd,iBAAiB;IACjB,UAAU;CAC0B,CAAA","sourcesContent":["/**\n * Resource health types (ADP-007, ADP-012, ADP-021).\n *\n * A resource is identified at the narrowest scope the evidence supports:\n * provider → account → model → variant. Health states are a closed set and\n * every transition between them is defined by the pure transition layer; the\n * registry never invents states. The circuit breaker (ADP-019) is an\n * orthogonal axis stored per resource record.\n */\nimport {\n DEFAULT_BREAKER_CONFIG,\n type BreakerConfig,\n type BreakerRecord,\n} from \"../circuit-breaker/types.js\"\nimport type { FailureCategory } from \"../classifier/types.js\"\n\nexport const RESOURCE_SCOPES = [\n \"provider\",\n \"account\",\n \"model\",\n \"variant\",\n] as const satisfies readonly string[]\n\nexport type ResourceScope = (typeof RESOURCE_SCOPES)[number]\n\n/**\n * Hierarchical resource identity. The scope is derived from the most specific\n * field present, so callers attribute evidence at exactly the level they can\n * prove (e.g. a provider-wide outage without a model id stays at provider\n * scope; a per-variant failure quarantines only that variant).\n */\nexport interface ResourceKey {\n readonly providerID: string\n readonly accountID?: string | undefined\n readonly modelID?: string | undefined\n readonly variantID?: string | undefined\n}\n\nexport const HEALTH_STATES = [\n \"healthy\",\n \"draining\",\n \"degraded\",\n \"rate_limited\",\n \"quota_exhausted\",\n \"unavailable\",\n] as const satisfies readonly string[]\n\nexport type HealthState = (typeof HEALTH_STATES)[number]\n\n/**\n * A time-bounded window during which the current state is known to hold\n * (e.g. until a Retry-After delay or a quota reset elapses). Absent when no\n * reset time is known — recovery then relies on probes, observed successes,\n * or explicit resets.\n */\nexport interface ResourceWindow {\n readonly kind: \"rate-limit\" | \"quota\"\n readonly until: number\n}\n\nexport interface ResourceRecord {\n readonly key: ResourceKey\n readonly health: HealthState\n readonly breaker: BreakerRecord\n readonly window?: ResourceWindow | undefined\n readonly updatedAt: number\n}\n\n/**\n * Health evidence events. `failure` carries an already-classified category\n * (from the error classifier, ADP-009) plus the classification's\n * definitiveness and parsed retry delay. `capacity` carries a CapacitySensor\n * reading (ADP-020) — `exhausted: false` is positive evidence of capacity.\n * `reset` is the manual Control-mode recovery op.\n */\nexport type HealthEvent =\n | {\n readonly kind: \"failure\"\n readonly key: ResourceKey\n readonly category: FailureCategory\n readonly definitive: boolean\n readonly retryAfterMs?: number | undefined\n }\n | { readonly kind: \"success\"; readonly key: ResourceKey }\n | { readonly kind: \"drain\"; readonly key: ResourceKey }\n | {\n readonly kind: \"capacity\"\n readonly key: ResourceKey\n readonly exhausted: boolean\n readonly retryAfterMs?: number | undefined\n }\n | { readonly kind: \"reset\"; readonly key: ResourceKey }\n\nexport interface ResourceHealthConfig {\n readonly breaker: BreakerConfig\n /** Window applied to rate-limited evidence that carries no Retry-After. */\n readonly defaultRateLimitWindowMs: number\n /**\n * Window applied to quota exhaustion that carries no reset delay. Without\n * one the state would be permanent (it is persisted and rehydrated), so an\n * unknown reset re-admits the resource after this window and lets fresh\n * evidence re-mark it (ADP-012).\n */\n readonly defaultQuotaWindowMs: number\n}\n\nexport const DEFAULT_HEALTH_CONFIG: ResourceHealthConfig = {\n breaker: DEFAULT_BREAKER_CONFIG,\n defaultRateLimitWindowMs: 30_000,\n defaultQuotaWindowMs: 15 * 60_000,\n}\n\n/** Injected monotonic clock, milliseconds. */\nexport type Clock = () => number\n\n/**\n * Why an assessment blocks new work. Ordered from hardest to softest fact:\n * hard resource states (unavailable, quota, rate limit) are direct evidence;\n * breaker reasons are inferred from failure counts; draining is a policy\n * request, not a health fact.\n */\nexport const BLOCKED_REASONS = [\n \"unavailable\",\n \"quota-exhausted\",\n \"rate-limited\",\n \"breaker-open\",\n \"probe-in-flight\",\n \"draining\",\n] as const satisfies readonly string[]\n\nexport type BlockedReason = (typeof BLOCKED_REASONS)[number]\n\n/** Opaque single-probe admission token; validated on report. */\nexport interface ProbeTicket {\n readonly id: string\n readonly key: ResourceKey\n}\n\nexport type ProbeOutcome =\n { readonly success: true } | { readonly success: false; readonly category: FailureCategory }\n\n/**\n * Result of assessing whether a resource may take new work right now. The\n * `blocked` variant reports the winning blocker's key (which may be a wider\n * scope than the assessed key) and, when known, when the block can lift.\n */\nexport type Assessment =\n | { readonly kind: \"available\" }\n | { readonly kind: \"probe\"; readonly ticket: ProbeTicket }\n | {\n readonly kind: \"blocked\"\n readonly reason: BlockedReason\n readonly key: ResourceKey\n readonly retryAtMs?: number\n }\n"]}
@@ -0,0 +1,11 @@
1
+ import { Plugin } from "@opencode/plugin";
2
+ export { PLUGIN_ID } from "./plugin-id.js";
3
+ /**
4
+ * Entry point wired into OpenCode via `opencode.json(c)`. Setup glues the
5
+ * adapter touchpoints (session hooks, event subscription, storage) to the
6
+ * supervisor and returns a cleanup that disposes every registration.
7
+ * All supervision errors are fail-open (ADP-031): the supervisor's public
8
+ * entry points never throw; the event pump's stream errors are logged.
9
+ */
10
+ declare const _default: Plugin.Plugin;
11
+ export default _default;
package/dist/index.js ADDED
@@ -0,0 +1,105 @@
1
+ import { Plugin } from "@opencode/plugin";
2
+ import { isCodexHeaderName } from "./adapters/codex-capacity/index.js";
3
+ import { escalationTool, registerSessionHooks, subscribeSessions, tierTool, } from "./adapters/opencode/index.js";
4
+ import { PLUGIN_ID } from "./plugin-id.js";
5
+ import { adaptiveRpc } from "./rpc/definition.js";
6
+ import { adaptiveRpcHandlers } from "./rpc/handlers.js";
7
+ import { Supervisor, logFailOpen } from "./supervisor/index.js";
8
+ export { PLUGIN_ID } from "./plugin-id.js";
9
+ /**
10
+ * Entry point wired into OpenCode via `opencode.json(c)`. Setup glues the
11
+ * adapter touchpoints (session hooks, event subscription, storage) to the
12
+ * supervisor and returns a cleanup that disposes every registration.
13
+ * All supervision errors are fail-open (ADP-031): the supervisor's public
14
+ * entry points never throw; the event pump's stream errors are logged.
15
+ */
16
+ export default Plugin.define({
17
+ id: PLUGIN_ID,
18
+ async setup(context) {
19
+ const supervisor = new Supervisor({
20
+ session: context.session,
21
+ model: context.model,
22
+ storage: context.storage,
23
+ clock: () => Date.now(),
24
+ });
25
+ const hooks = await registerSessionHooks(context.session, {
26
+ onRetry: async (input) => {
27
+ await supervisor.handleRetry(input);
28
+ },
29
+ onModelRequest: async (report) => {
30
+ await supervisor.handleReport(report);
31
+ },
32
+ onHttpResponse: async (report) => {
33
+ await supervisor.handleReport(report);
34
+ },
35
+ onIdle: async (report) => {
36
+ await supervisor.handleReport(report);
37
+ },
38
+ onPrompt: async (report) => {
39
+ await supervisor.handleReport(report);
40
+ },
41
+ }, { capture: isCodexHeaderName });
42
+ const subscription = subscribeSessions(context.event, (report) => {
43
+ void supervisor.handleReport(report);
44
+ }, (error) => {
45
+ logFailOpen("events", error);
46
+ });
47
+ // Every disposal settles independently: a failing dispose is logged, never
48
+ // allowed to mask the other disposals or (during rollback) the original
49
+ // setup error. Disposals are awaited so a late rejection cannot land after
50
+ // the host considers the plugin gone.
51
+ const disposals = [];
52
+ const settled = async (name, dispose) => {
53
+ try {
54
+ await dispose();
55
+ }
56
+ catch (error) {
57
+ logFailOpen(name, error);
58
+ }
59
+ };
60
+ const settledAll = async () => {
61
+ for (const { name, dispose } of disposals) {
62
+ await settled(name, dispose);
63
+ }
64
+ };
65
+ for (const [index, hookRegistration] of hooks.entries()) {
66
+ disposals.push({ name: `hook ${String(index)}`, dispose: () => hookRegistration.dispose() });
67
+ }
68
+ disposals.push({
69
+ name: "events",
70
+ dispose: () => {
71
+ subscription.dispose();
72
+ },
73
+ });
74
+ // The typed escalation tool (T-18, ADP-015): the agent's self-report
75
+ // surface for stronger capability, applied at the next safe boundary.
76
+ // The tier tool (ADP-055): the agent declares the task's tier; the
77
+ // declaration steers the session's next admissions until cleared.
78
+ // Typed RPC (ADP-034/036): the only channel to the control surfaces.
79
+ // The settings-changed emitter resolves the registration lazily: handlers
80
+ // only run after `register` resolves, so the holder is always populated.
81
+ const rpcHolder = {};
82
+ const emit = (...args) =>
83
+ // The correlated tuple pairing is checked by the handler types; the
84
+ // registration forwards it to the host emitter untouched.
85
+ rpcHolder.registration?.events.emit(...args);
86
+ try {
87
+ const toolRegistration = await context.tool.transform((editor) => {
88
+ editor.add(escalationTool((sessionID, reason, evidence) => supervisor.noteEscalationRequest(sessionID, reason, evidence)));
89
+ editor.add(tierTool((sessionID, tier) => supervisor.noteTierRequest(sessionID, tier)));
90
+ });
91
+ disposals.push({ name: "tools", dispose: () => toolRegistration.dispose() });
92
+ const rpcRegistration = await context.rpc.register(adaptiveRpc, adaptiveRpcHandlers(supervisor, emit));
93
+ rpcHolder.registration = rpcRegistration;
94
+ disposals.push({ name: "rpc", dispose: () => rpcRegistration.dispose() });
95
+ }
96
+ catch (error) {
97
+ // Roll back everything already registered so a failure at the tool or
98
+ // rpc stage does not leak live hooks and the event pump.
99
+ await settledAll();
100
+ throw error;
101
+ }
102
+ return () => settledAll();
103
+ },
104
+ });
105
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { Plugin } from \"@opencode/plugin\"\nimport { isCodexHeaderName } from \"./adapters/codex-capacity/index.js\"\nimport {\n escalationTool,\n registerSessionHooks,\n subscribeSessions,\n tierTool,\n} from \"./adapters/opencode/index.js\"\nimport { PLUGIN_ID } from \"./plugin-id.js\"\nimport { adaptiveRpc } from \"./rpc/definition.js\"\nimport { adaptiveRpcHandlers } from \"./rpc/handlers.js\"\nimport type { RpcRegistration } from \"@opencode/plugin/promise/rpc\"\nimport type { AdaptiveRpcEmit } from \"./rpc/handlers.js\"\nimport { Supervisor, logFailOpen } from \"./supervisor/index.js\"\n\nexport { PLUGIN_ID } from \"./plugin-id.js\"\n\n/**\n * Entry point wired into OpenCode via `opencode.json(c)`. Setup glues the\n * adapter touchpoints (session hooks, event subscription, storage) to the\n * supervisor and returns a cleanup that disposes every registration.\n * All supervision errors are fail-open (ADP-031): the supervisor's public\n * entry points never throw; the event pump's stream errors are logged.\n */\nexport default Plugin.define({\n id: PLUGIN_ID,\n async setup(context) {\n const supervisor = new Supervisor({\n session: context.session,\n model: context.model,\n storage: context.storage,\n clock: () => Date.now(),\n })\n const hooks = await registerSessionHooks(\n context.session,\n {\n onRetry: async (input) => {\n await supervisor.handleRetry(input)\n },\n onModelRequest: async (report) => {\n await supervisor.handleReport(report)\n },\n onHttpResponse: async (report) => {\n await supervisor.handleReport(report)\n },\n onIdle: async (report) => {\n await supervisor.handleReport(report)\n },\n onPrompt: async (report) => {\n await supervisor.handleReport(report)\n },\n },\n { capture: isCodexHeaderName },\n )\n const subscription = subscribeSessions(\n context.event,\n (report) => {\n void supervisor.handleReport(report)\n },\n (error) => {\n logFailOpen(\"events\", error)\n },\n )\n // Every disposal settles independently: a failing dispose is logged, never\n // allowed to mask the other disposals or (during rollback) the original\n // setup error. Disposals are awaited so a late rejection cannot land after\n // the host considers the plugin gone.\n const disposals: { name: string; dispose: () => void | Promise<void> }[] = []\n const settled = async (name: string, dispose: () => void | Promise<void>): Promise<void> => {\n try {\n await dispose()\n } catch (error) {\n logFailOpen(name, error)\n }\n }\n const settledAll = async (): Promise<void> => {\n for (const { name, dispose } of disposals) {\n await settled(name, dispose)\n }\n }\n for (const [index, hookRegistration] of hooks.entries()) {\n disposals.push({ name: `hook ${String(index)}`, dispose: () => hookRegistration.dispose() })\n }\n disposals.push({\n name: \"events\",\n dispose: () => {\n subscription.dispose()\n },\n })\n // The typed escalation tool (T-18, ADP-015): the agent's self-report\n // surface for stronger capability, applied at the next safe boundary.\n // The tier tool (ADP-055): the agent declares the task's tier; the\n // declaration steers the session's next admissions until cleared.\n // Typed RPC (ADP-034/036): the only channel to the control surfaces.\n // The settings-changed emitter resolves the registration lazily: handlers\n // only run after `register` resolves, so the holder is always populated.\n const rpcHolder: { registration?: RpcRegistration<typeof adaptiveRpc> } = {}\n const emit: AdaptiveRpcEmit = (...args) =>\n // The correlated tuple pairing is checked by the handler types; the\n // registration forwards it to the host emitter untouched.\n rpcHolder.registration?.events.emit(...args)\n try {\n const toolRegistration = await context.tool.transform((editor) => {\n editor.add(\n escalationTool((sessionID, reason, evidence) =>\n supervisor.noteEscalationRequest(sessionID, reason, evidence),\n ),\n )\n editor.add(tierTool((sessionID, tier) => supervisor.noteTierRequest(sessionID, tier)))\n })\n disposals.push({ name: \"tools\", dispose: () => toolRegistration.dispose() })\n const rpcRegistration = await context.rpc.register(\n adaptiveRpc,\n adaptiveRpcHandlers(supervisor, emit),\n )\n rpcHolder.registration = rpcRegistration\n disposals.push({ name: \"rpc\", dispose: () => rpcRegistration.dispose() })\n } catch (error) {\n // Roll back everything already registered so a failure at the tool or\n // rpc stage does not leak live hooks and the event pump.\n await settledAll()\n throw error\n }\n return () => settledAll()\n },\n})\n"]}
@@ -0,0 +1,2 @@
1
+ /** The plugin identity shared by the server, TUI, and GUI entries. */
2
+ export declare const PLUGIN_ID = "coool.adaptive";
@@ -0,0 +1,3 @@
1
+ /** The plugin identity shared by the server, TUI, and GUI entries. */
2
+ export const PLUGIN_ID = "coool.adaptive";
3
+ //# sourceMappingURL=plugin-id.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin-id.js","sourceRoot":"","sources":["../src/plugin-id.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,MAAM,CAAC,MAAM,SAAS,GAAG,gBAAgB,CAAA","sourcesContent":["/** The plugin identity shared by the server, TUI, and GUI entries. */\nexport const PLUGIN_ID = \"coool.adaptive\"\n"]}
@@ -0,0 +1,123 @@
1
+ import type { StandardSchemaV1 } from "@standard-schema/spec";
2
+ import type { OperatingMode } from "../core/scheduler/types.js";
3
+ import type { SettingsPatch, SettingsV1 } from "../state/settings/index.js";
4
+ import type { PatchResult } from "../state/settings/types.js";
5
+ import type { SessionModeSetResult } from "../state/session-modes/index.js";
6
+ import type { TierRequestSetResult } from "./handlers.js";
7
+ import type { TierName } from "../core/tier-policy/types.js";
8
+ import type { Receipt } from "../state/receipts/types.js";
9
+ import type { StatusSnapshot } from "./status.js";
10
+ export declare const ADAPTIVE_RPC_ID = "coool.adaptive";
11
+ export declare const adaptiveRpc: {
12
+ readonly id: "coool.adaptive";
13
+ readonly methods: {
14
+ readonly "settings.get": {
15
+ readonly errors: {
16
+ internal: StandardSchemaV1<undefined, undefined>;
17
+ };
18
+ readonly input: StandardSchemaV1<undefined, undefined>;
19
+ readonly output: StandardSchemaV1<SettingsV1, SettingsV1>;
20
+ };
21
+ readonly "settings.set": {
22
+ readonly errors: {
23
+ internal: StandardSchemaV1<undefined, undefined>;
24
+ };
25
+ readonly input: StandardSchemaV1<SettingsPatch, SettingsPatch>;
26
+ readonly output: StandardSchemaV1<PatchResult, PatchResult>;
27
+ };
28
+ readonly "status.get": {
29
+ readonly errors: {
30
+ internal: StandardSchemaV1<undefined, undefined>;
31
+ };
32
+ readonly input: StandardSchemaV1<undefined, undefined>;
33
+ readonly output: StandardSchemaV1<StatusSnapshot, StatusSnapshot>;
34
+ };
35
+ readonly "receipts.list": {
36
+ readonly errors: {
37
+ internal: StandardSchemaV1<undefined, undefined>;
38
+ };
39
+ readonly input: StandardSchemaV1<undefined, undefined>;
40
+ readonly output: StandardSchemaV1<Receipt[], Receipt[]>;
41
+ };
42
+ readonly "session-mode.get": {
43
+ readonly errors: {
44
+ internal: StandardSchemaV1<undefined, undefined>;
45
+ };
46
+ readonly input: StandardSchemaV1<{
47
+ sessionID: string;
48
+ }, {
49
+ sessionID: string;
50
+ }>;
51
+ readonly output: StandardSchemaV1<{
52
+ mode: OperatingMode | null;
53
+ }, {
54
+ mode: OperatingMode | null;
55
+ }>;
56
+ };
57
+ readonly "session-mode.set": {
58
+ readonly errors: {
59
+ internal: StandardSchemaV1<undefined, undefined>;
60
+ };
61
+ readonly input: StandardSchemaV1<{
62
+ sessionID: string;
63
+ mode: OperatingMode | null;
64
+ }, {
65
+ sessionID: string;
66
+ mode: OperatingMode | null;
67
+ }>;
68
+ readonly output: StandardSchemaV1<SessionModeSetResult, SessionModeSetResult>;
69
+ };
70
+ readonly "tier-request.get": {
71
+ readonly errors: {
72
+ internal: StandardSchemaV1<undefined, undefined>;
73
+ };
74
+ readonly input: StandardSchemaV1<{
75
+ sessionID: string;
76
+ }, {
77
+ sessionID: string;
78
+ }>;
79
+ readonly output: StandardSchemaV1<{
80
+ tier: TierName | null;
81
+ }, {
82
+ tier: TierName | null;
83
+ }>;
84
+ };
85
+ readonly "tier-request.set": {
86
+ readonly errors: {
87
+ internal: StandardSchemaV1<undefined, undefined>;
88
+ };
89
+ readonly input: StandardSchemaV1<{
90
+ sessionID: string;
91
+ tier: string | null;
92
+ }, {
93
+ sessionID: string;
94
+ tier: string | null;
95
+ }>;
96
+ readonly output: StandardSchemaV1<TierRequestSetResult, TierRequestSetResult>;
97
+ };
98
+ };
99
+ readonly events: {
100
+ readonly "settings-changed": {
101
+ readonly schema: StandardSchemaV1<{
102
+ version: number;
103
+ }, {
104
+ version: number;
105
+ }>;
106
+ };
107
+ readonly "session-mode-changed": {
108
+ readonly schema: StandardSchemaV1<{
109
+ sessionID: string;
110
+ }, {
111
+ sessionID: string;
112
+ }>;
113
+ };
114
+ readonly "tier-request-changed": {
115
+ readonly schema: StandardSchemaV1<{
116
+ sessionID: string;
117
+ }, {
118
+ sessionID: string;
119
+ }>;
120
+ };
121
+ };
122
+ };
123
+ export type AdaptiveRpc = typeof adaptiveRpc;
@@ -0,0 +1,130 @@
1
+ /**
2
+ * Typed RPC definition (ADP-034/036): the only channel between the server
3
+ * plugin and the TUI/GUI surfaces. Surfaces hold no local settings state —
4
+ * they fetch snapshots, patch settings, and re-fetch on the `settings-changed`
5
+ * event (the server is the single source of truth). Session-mode overrides
6
+ * follow the same contract via `session-mode.get/set` and the
7
+ * `session-mode-changed` event (ADP-054); sticky per-session tier requests
8
+ * follow it via `tier-request.get/set` and `tier-request-changed` (ADP-055).
9
+ *
10
+ * Schema note: input schemas gate the wire shape (non-object patches are
11
+ * rejected as rpc.invalid_input); deeper validation happens in the handlers
12
+ * via the state parsers (`applyPatch` reports per-field errors instead), and
13
+ * output schemas are passthroughs over trusted server-side data.
14
+ *
15
+ * Every method declares one `internal` error with no data: handler failures
16
+ * are returned through the call context's error factory instead of thrown —
17
+ * a plain throw becomes a server defect and the client sees only the generic
18
+ * `rpc.internal` message (verified on the sibling @coool plugins).
19
+ */
20
+ import { Rpc } from "@opencode/schema/rpc";
21
+ import { MAX_SESSION_ID_LENGTH } from "../state/session-modes/types.js";
22
+ export const ADAPTIVE_RPC_ID = "coool.adaptive";
23
+ const RPC_VENDOR = "coool.adaptive";
24
+ const INTERNAL_ERROR = { internal: voidSchema() };
25
+ /**
26
+ * Identity schema: the wire value passes through unchanged; the type
27
+ * parameters carry the transport contract. `gate` optionally rejects values
28
+ * before they reach a handler; the failure message names the expectation so a
29
+ * rejected call is diagnosable from the wire error alone.
30
+ */
31
+ function schema(gate, expectation) {
32
+ return {
33
+ "~standard": {
34
+ version: 1,
35
+ vendor: RPC_VENDOR,
36
+ validate: (value) => gate(value) ? { value: value } : { issues: [{ message: expectation }] },
37
+ },
38
+ };
39
+ }
40
+ function voidSchema() {
41
+ return {
42
+ "~standard": {
43
+ version: 1,
44
+ vendor: RPC_VENDOR,
45
+ validate: (value) => value === undefined
46
+ ? { value: undefined }
47
+ : { issues: [{ message: "unexpected input: no input expected" }] },
48
+ },
49
+ };
50
+ }
51
+ const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
52
+ const isString = (value) => typeof value === "string";
53
+ /**
54
+ * `{ sessionID: string }` wire shape. Bounds checked here too: a session id
55
+ * beyond the bound cannot be a real host identifier and an empty string is
56
+ * never one, so neither reaches a handler or a store lookup.
57
+ */
58
+ const hasSessionID = (value) => {
59
+ if (!(isRecord(value) && isString(value["sessionID"])))
60
+ return false;
61
+ const sessionID = value["sessionID"];
62
+ // A session id beyond the bound cannot be a real host identifier and an
63
+ // empty string is never one; neither reaches a handler or a store lookup.
64
+ return sessionID.length > 0 && sessionID.length <= MAX_SESSION_ID_LENGTH;
65
+ };
66
+ /** `{ sessionID: string, mode: OperatingMode | null }` wire shape. */
67
+ const isSessionModeSet = (value) => isRecord(value) &&
68
+ isString(value["sessionID"]) &&
69
+ (value["mode"] === null || isString(value["mode"]));
70
+ /** `{ sessionID: string, tier: string | null }` wire shape. */
71
+ const isTierRequestSet = (value) => isRecord(value) &&
72
+ isString(value["sessionID"]) &&
73
+ (value["tier"] === null || isString(value["tier"]));
74
+ export const adaptiveRpc = Rpc.define({
75
+ id: ADAPTIVE_RPC_ID,
76
+ methods: {
77
+ "settings.get": {
78
+ errors: INTERNAL_ERROR,
79
+ input: voidSchema(),
80
+ output: schema(isRecord, "output must be an object"),
81
+ },
82
+ "settings.set": {
83
+ errors: INTERNAL_ERROR,
84
+ input: schema(isRecord, "input must be an object"),
85
+ output: schema(isRecord, "output must be an object"),
86
+ },
87
+ "status.get": {
88
+ errors: INTERNAL_ERROR,
89
+ input: voidSchema(),
90
+ output: schema(isRecord, "output must be an object"),
91
+ },
92
+ "receipts.list": {
93
+ errors: INTERNAL_ERROR,
94
+ input: voidSchema(),
95
+ output: schema(Array.isArray, "output must be an array"),
96
+ },
97
+ "session-mode.get": {
98
+ errors: INTERNAL_ERROR,
99
+ input: schema(hasSessionID, "input must be an object with a sessionID string"),
100
+ output: schema(isRecord, "output must be an object"),
101
+ },
102
+ "session-mode.set": {
103
+ errors: INTERNAL_ERROR,
104
+ input: schema(isSessionModeSet, "input must be an object with a sessionID string and a mode string or null"),
105
+ output: schema(isRecord, "output must be an object"),
106
+ },
107
+ "tier-request.get": {
108
+ errors: INTERNAL_ERROR,
109
+ input: schema(hasSessionID, "input must be an object with a sessionID string"),
110
+ output: schema(isRecord, "output must be an object"),
111
+ },
112
+ "tier-request.set": {
113
+ errors: INTERNAL_ERROR,
114
+ input: schema(isTierRequestSet, "input must be an object with a sessionID string and a tier string or null"),
115
+ output: schema(isRecord, "output must be an object"),
116
+ },
117
+ },
118
+ events: {
119
+ "settings-changed": {
120
+ schema: schema(isRecord, "event data must be an object"),
121
+ },
122
+ "session-mode-changed": {
123
+ schema: schema(hasSessionID, "event data must be an object with a sessionID string"),
124
+ },
125
+ "tier-request-changed": {
126
+ schema: schema(hasSessionID, "event data must be an object with a sessionID string"),
127
+ },
128
+ },
129
+ });
130
+ //# sourceMappingURL=definition.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"definition.js","sourceRoot":"","sources":["../../src/rpc/definition.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Typed RPC definition (ADP-034/036): the only channel between the server\n * plugin and the TUI/GUI surfaces. Surfaces hold no local settings state —\n * they fetch snapshots, patch settings, and re-fetch on the `settings-changed`\n * event (the server is the single source of truth). Session-mode overrides\n * follow the same contract via `session-mode.get/set` and the\n * `session-mode-changed` event (ADP-054); sticky per-session tier requests\n * follow it via `tier-request.get/set` and `tier-request-changed` (ADP-055).\n *\n * Schema note: input schemas gate the wire shape (non-object patches are\n * rejected as rpc.invalid_input); deeper validation happens in the handlers\n * via the state parsers (`applyPatch` reports per-field errors instead), and\n * output schemas are passthroughs over trusted server-side data.\n *\n * Every method declares one `internal` error with no data: handler failures\n * are returned through the call context's error factory instead of thrown —\n * a plain throw becomes a server defect and the client sees only the generic\n * `rpc.internal` message (verified on the sibling @coool plugins).\n */\nimport { Rpc } from \"@opencode/schema/rpc\"\nimport type { StandardSchemaV1 } from \"@standard-schema/spec\"\nimport type { OperatingMode } from \"../core/scheduler/types.js\"\nimport type { SettingsPatch, SettingsV1 } from \"../state/settings/index.js\"\nimport type { PatchResult } from \"../state/settings/types.js\"\nimport type { SessionModeSetResult } from \"../state/session-modes/index.js\"\nimport type { TierRequestSetResult } from \"./handlers.js\"\nimport type { TierName } from \"../core/tier-policy/types.js\"\nimport { MAX_SESSION_ID_LENGTH } from \"../state/session-modes/types.js\"\nimport type { Receipt } from \"../state/receipts/types.js\"\nimport type { StatusSnapshot } from \"./status.js\"\n\nexport const ADAPTIVE_RPC_ID = \"coool.adaptive\"\nconst RPC_VENDOR = \"coool.adaptive\"\n\nconst INTERNAL_ERROR = { internal: voidSchema() }\n\n/**\n * Identity schema: the wire value passes through unchanged; the type\n * parameters carry the transport contract. `gate` optionally rejects values\n * before they reach a handler; the failure message names the expectation so a\n * rejected call is diagnosable from the wire error alone.\n */\nfunction schema<T>(gate: (value: unknown) => boolean, expectation: string): StandardSchemaV1<T, T> {\n return {\n \"~standard\": {\n version: 1,\n vendor: RPC_VENDOR,\n validate: (value) =>\n gate(value) ? { value: value as T } : { issues: [{ message: expectation }] },\n },\n }\n}\n\nfunction voidSchema(): StandardSchemaV1<undefined, undefined> {\n return {\n \"~standard\": {\n version: 1,\n vendor: RPC_VENDOR,\n validate: (value) =>\n value === undefined\n ? { value: undefined }\n : { issues: [{ message: \"unexpected input: no input expected\" }] },\n },\n }\n}\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value)\n\nconst isString = (value: unknown): value is string => typeof value === \"string\"\n\n/**\n * `{ sessionID: string }` wire shape. Bounds checked here too: a session id\n * beyond the bound cannot be a real host identifier and an empty string is\n * never one, so neither reaches a handler or a store lookup.\n */\nconst hasSessionID = (value: unknown): boolean => {\n if (!(isRecord(value) && isString(value[\"sessionID\"]))) return false\n const sessionID = value[\"sessionID\"]\n // A session id beyond the bound cannot be a real host identifier and an\n // empty string is never one; neither reaches a handler or a store lookup.\n return sessionID.length > 0 && sessionID.length <= MAX_SESSION_ID_LENGTH\n}\n\n/** `{ sessionID: string, mode: OperatingMode | null }` wire shape. */\nconst isSessionModeSet = (value: unknown): boolean =>\n isRecord(value) &&\n isString(value[\"sessionID\"]) &&\n (value[\"mode\"] === null || isString(value[\"mode\"]))\n\n/** `{ sessionID: string, tier: string | null }` wire shape. */\nconst isTierRequestSet = (value: unknown): boolean =>\n isRecord(value) &&\n isString(value[\"sessionID\"]) &&\n (value[\"tier\"] === null || isString(value[\"tier\"]))\n\nexport const adaptiveRpc = Rpc.define({\n id: ADAPTIVE_RPC_ID,\n methods: {\n \"settings.get\": {\n errors: INTERNAL_ERROR,\n input: voidSchema(),\n output: schema<SettingsV1>(isRecord, \"output must be an object\"),\n },\n \"settings.set\": {\n errors: INTERNAL_ERROR,\n input: schema<SettingsPatch>(isRecord, \"input must be an object\"),\n output: schema<PatchResult>(isRecord, \"output must be an object\"),\n },\n \"status.get\": {\n errors: INTERNAL_ERROR,\n input: voidSchema(),\n output: schema<StatusSnapshot>(isRecord, \"output must be an object\"),\n },\n \"receipts.list\": {\n errors: INTERNAL_ERROR,\n input: voidSchema(),\n output: schema<Receipt[]>(Array.isArray, \"output must be an array\"),\n },\n \"session-mode.get\": {\n errors: INTERNAL_ERROR,\n input: schema<{ sessionID: string }>(\n hasSessionID,\n \"input must be an object with a sessionID string\",\n ),\n output: schema<{ mode: OperatingMode | null }>(isRecord, \"output must be an object\"),\n },\n \"session-mode.set\": {\n errors: INTERNAL_ERROR,\n input: schema<{ sessionID: string; mode: OperatingMode | null }>(\n isSessionModeSet,\n \"input must be an object with a sessionID string and a mode string or null\",\n ),\n output: schema<SessionModeSetResult>(isRecord, \"output must be an object\"),\n },\n \"tier-request.get\": {\n errors: INTERNAL_ERROR,\n input: schema<{ sessionID: string }>(\n hasSessionID,\n \"input must be an object with a sessionID string\",\n ),\n output: schema<{ tier: TierName | null }>(isRecord, \"output must be an object\"),\n },\n \"tier-request.set\": {\n errors: INTERNAL_ERROR,\n input: schema<{ sessionID: string; tier: string | null }>(\n isTierRequestSet,\n \"input must be an object with a sessionID string and a tier string or null\",\n ),\n output: schema<TierRequestSetResult>(isRecord, \"output must be an object\"),\n },\n },\n events: {\n \"settings-changed\": {\n schema: schema<{ version: number }>(isRecord, \"event data must be an object\"),\n },\n \"session-mode-changed\": {\n schema: schema<{ sessionID: string }>(\n hasSessionID,\n \"event data must be an object with a sessionID string\",\n ),\n },\n \"tier-request-changed\": {\n schema: schema<{ sessionID: string }>(\n hasSessionID,\n \"event data must be an object with a sessionID string\",\n ),\n },\n },\n})\n\nexport type AdaptiveRpc = typeof adaptiveRpc\n"]}
@@ -0,0 +1,53 @@
1
+ import type { OperatingMode } from "../core/scheduler/types.js";
2
+ import type { TierName } from "../core/tier-policy/types.js";
3
+ import type { PatchResult } from "../state/settings/types.js";
4
+ import type { SettingsPatch, SettingsV1 } from "../state/settings/index.js";
5
+ import type { Rpc } from "@opencode/schema/rpc";
6
+ import type { Receipt } from "../state/receipts/types.js";
7
+ import type { StatusSnapshot } from "./status.js";
8
+ import type { AdaptiveRpc } from "./definition.js";
9
+ export interface AdaptiveRpcSource {
10
+ settings(): Promise<SettingsV1>;
11
+ updateSettings(patch: SettingsPatch): Promise<PatchResult>;
12
+ status(): Promise<StatusSnapshot>;
13
+ receipts(): Promise<Receipt[]>;
14
+ getSessionMode(sessionID: string): Promise<OperatingMode | null>;
15
+ setSessionMode(sessionID: string, mode: OperatingMode | null): Promise<void>;
16
+ getTierRequest(sessionID: string): Promise<TierName | null>;
17
+ noteTierRequest(sessionID: string, tier: string): boolean;
18
+ setTierRequest(sessionID: string, tier: TierName | null): Promise<void>;
19
+ }
20
+ export type SettingsChangedEmit = (name: "settings-changed", data: {
21
+ version: number;
22
+ }) => unknown;
23
+ /**
24
+ * Correlated emit: each call site pairs the event name with its own payload
25
+ * shape — an invalid pairing is a type error, and the registration site can
26
+ * forward the tuple to the host emitter untouched.
27
+ */
28
+ export type AdaptiveRpcEmit = (...args: ["settings-changed", {
29
+ version: number;
30
+ }] | ["session-mode-changed", {
31
+ sessionID: string;
32
+ }] | ["tier-request-changed", {
33
+ sessionID: string;
34
+ }]) => unknown;
35
+ /** A successful tier-request write; mirrors the SessionModeSetResult convention. */
36
+ export type TierRequestSetResult = {
37
+ readonly ok: true;
38
+ } | {
39
+ readonly ok: false;
40
+ readonly errors: readonly string[];
41
+ };
42
+ type Methods = AdaptiveRpc["methods"];
43
+ type MethodName = Extract<keyof Methods, string>;
44
+ /** The subset of the host's RpcCallContext the handlers use (no plugin import). */
45
+ export interface AdaptiveRpcCallContext<Name extends MethodName> {
46
+ readonly error: Rpc.ErrorFactory<Methods[Name]>;
47
+ }
48
+ type HandlerErrorOf<Name extends MethodName> = Rpc.HandlerError<Methods[Name]>;
49
+ type HandlerOf<Name extends MethodName> = (input: Rpc.Output<Methods[Name]["input"]>, context: AdaptiveRpcCallContext<Name>) => Promise<Rpc.HandlerOutput<Methods[Name]["output"]> | HandlerErrorOf<Name>>;
50
+ export declare function adaptiveRpcHandlers(source: AdaptiveRpcSource, emit?: AdaptiveRpcEmit): {
51
+ [Name in MethodName]: HandlerOf<Name>;
52
+ };
53
+ export {};