@polderlabs/bizar-omp 0.6.1 → 0.6.3

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 (403) hide show
  1. package/README.md +59 -2
  2. package/dist/cli/agents-ink.d.ts.map +1 -1
  3. package/dist/cli/agents-ink.js +11 -10
  4. package/dist/cli/agents-ink.js.map +1 -1
  5. package/dist/cli/agents.d.ts +1 -0
  6. package/dist/cli/agents.d.ts.map +1 -1
  7. package/dist/cli/agents.js +11 -0
  8. package/dist/cli/agents.js.map +1 -1
  9. package/dist/cli/directory-selector.d.ts +36 -0
  10. package/dist/cli/directory-selector.d.ts.map +1 -1
  11. package/dist/cli/directory-selector.js +25 -0
  12. package/dist/cli/directory-selector.js.map +1 -1
  13. package/dist/cli/main.js +0 -0
  14. package/dist/cli/omb-commands.d.ts +30 -0
  15. package/dist/cli/omb-commands.d.ts.map +1 -0
  16. package/dist/cli/omb-commands.js +109 -0
  17. package/dist/cli/omb-commands.js.map +1 -0
  18. package/dist/cli/omb-daemon.d.ts +1 -0
  19. package/dist/cli/omb-daemon.d.ts.map +1 -1
  20. package/dist/cli/omb-daemon.js +15 -1
  21. package/dist/cli/omb-daemon.js.map +1 -1
  22. package/dist/cli/omb-dashboard.d.ts +1 -1
  23. package/dist/cli/omb-dashboard.d.ts.map +1 -1
  24. package/dist/cli/omb-dashboard.js +2 -1
  25. package/dist/cli/omb-dashboard.js.map +1 -1
  26. package/dist/cli/omb-runtime.d.ts +42 -0
  27. package/dist/cli/omb-runtime.d.ts.map +1 -0
  28. package/dist/cli/omb-runtime.js +507 -0
  29. package/dist/cli/omb-runtime.js.map +1 -0
  30. package/dist/cli/omb-tray.d.ts +3 -0
  31. package/dist/cli/omb-tray.d.ts.map +1 -0
  32. package/dist/cli/omb-tray.js +44 -0
  33. package/dist/cli/omb-tray.js.map +1 -0
  34. package/dist/cli/omb.js +8 -33
  35. package/dist/cli/omb.js.map +1 -1
  36. package/dist/extension.d.ts +2 -1
  37. package/dist/extension.d.ts.map +1 -1
  38. package/dist/extension.js +160 -33
  39. package/dist/extension.js.map +1 -1
  40. package/dist/omp/daemon-service.d.ts.map +1 -1
  41. package/dist/omp/daemon-service.js +6 -3
  42. package/dist/omp/daemon-service.js.map +1 -1
  43. package/dist/omp/daemon.d.ts +1 -0
  44. package/dist/omp/daemon.d.ts.map +1 -1
  45. package/dist/omp/daemon.js +1 -1
  46. package/dist/omp/daemon.js.map +1 -1
  47. package/dist/omp/dashboard-html.d.ts.map +1 -1
  48. package/dist/omp/dashboard-html.js +360 -38
  49. package/dist/omp/dashboard-html.js.map +1 -1
  50. package/dist/omp/model-role-assignment.d.ts +166 -1
  51. package/dist/omp/model-role-assignment.d.ts.map +1 -1
  52. package/dist/omp/model-role-assignment.js +393 -4
  53. package/dist/omp/model-role-assignment.js.map +1 -1
  54. package/dist/omp/omb-sessions.d.ts +44 -0
  55. package/dist/omp/omb-sessions.d.ts.map +1 -1
  56. package/dist/omp/omb-sessions.js +160 -52
  57. package/dist/omp/omb-sessions.js.map +1 -1
  58. package/dist/omp/omb-settings.d.ts +16 -0
  59. package/dist/omp/omb-settings.d.ts.map +1 -1
  60. package/dist/omp/omb-settings.js +55 -3
  61. package/dist/omp/omb-settings.js.map +1 -1
  62. package/dist/omp/run-log.d.ts +26 -0
  63. package/dist/omp/run-log.d.ts.map +1 -0
  64. package/dist/omp/run-log.js +24 -0
  65. package/dist/omp/run-log.js.map +1 -0
  66. package/dist/omp/tmux.d.ts +38 -2
  67. package/dist/omp/tmux.d.ts.map +1 -1
  68. package/dist/omp/tmux.js +231 -46
  69. package/dist/omp/tmux.js.map +1 -1
  70. package/dist/omp/tray.d.ts +2 -0
  71. package/dist/omp/tray.d.ts.map +1 -1
  72. package/dist/omp/tray.js +31 -5
  73. package/dist/omp/tray.js.map +1 -1
  74. package/dist/src/cli/agents-ink.d.ts +25 -0
  75. package/dist/src/cli/agents-ink.js +517 -0
  76. package/dist/src/cli/agents-ink.js.map +1 -0
  77. package/dist/src/cli/agents.d.ts +14 -0
  78. package/dist/src/cli/agents.js +197 -0
  79. package/dist/src/cli/agents.js.map +1 -0
  80. package/dist/src/cli/directory-selector.d.ts +60 -0
  81. package/dist/src/cli/directory-selector.js +208 -0
  82. package/dist/src/cli/directory-selector.js.map +1 -0
  83. package/dist/src/cli/doctor.d.ts +41 -0
  84. package/dist/src/cli/doctor.js +31 -0
  85. package/dist/src/cli/doctor.js.map +1 -0
  86. package/dist/src/cli/install.d.ts +129 -0
  87. package/dist/src/cli/install.js +164 -0
  88. package/dist/src/cli/install.js.map +1 -0
  89. package/dist/src/cli/main.d.ts +2 -0
  90. package/dist/src/cli/main.js +117 -0
  91. package/dist/src/cli/main.js.map +1 -0
  92. package/dist/src/cli/migrate.d.ts +18 -0
  93. package/dist/src/cli/migrate.js +14 -0
  94. package/dist/src/cli/migrate.js.map +1 -0
  95. package/dist/src/cli/omb-commands.d.ts +29 -0
  96. package/dist/src/cli/omb-commands.js +107 -0
  97. package/dist/src/cli/omb-commands.js.map +1 -0
  98. package/dist/src/cli/omb-daemon.d.ts +2 -0
  99. package/dist/src/cli/omb-daemon.js +135 -0
  100. package/dist/src/cli/omb-daemon.js.map +1 -0
  101. package/dist/src/cli/omb-dashboard.d.ts +12 -0
  102. package/dist/src/cli/omb-dashboard.js +113 -0
  103. package/dist/src/cli/omb-dashboard.js.map +1 -0
  104. package/dist/src/cli/omb-invocation.d.ts +8 -0
  105. package/dist/src/cli/omb-invocation.js +41 -0
  106. package/dist/src/cli/omb-invocation.js.map +1 -0
  107. package/dist/src/cli/omb-runtime.d.ts +41 -0
  108. package/dist/src/cli/omb-runtime.js +371 -0
  109. package/dist/src/cli/omb-runtime.js.map +1 -0
  110. package/dist/src/cli/omb-tray.d.ts +2 -0
  111. package/dist/src/cli/omb-tray.js +38 -0
  112. package/dist/src/cli/omb-tray.js.map +1 -0
  113. package/dist/src/cli/omb.d.ts +2 -0
  114. package/dist/src/cli/omb.js +31 -0
  115. package/dist/src/cli/omb.js.map +1 -0
  116. package/dist/src/cli/omp-theme.d.ts +17 -0
  117. package/dist/src/cli/omp-theme.js +22 -0
  118. package/dist/src/cli/omp-theme.js.map +1 -0
  119. package/dist/src/cli/process.d.ts +6 -0
  120. package/dist/src/cli/process.js +54 -0
  121. package/dist/src/cli/process.js.map +1 -0
  122. package/dist/src/cli/run.d.ts +2 -0
  123. package/dist/src/cli/run.js +5 -0
  124. package/dist/src/cli/run.js.map +1 -0
  125. package/dist/src/cli/setup-ui.d.ts +37 -0
  126. package/dist/src/cli/setup-ui.js +90 -0
  127. package/dist/src/cli/setup-ui.js.map +1 -0
  128. package/dist/src/core/acceptance.d.ts +32 -0
  129. package/dist/src/core/acceptance.js +87 -0
  130. package/dist/src/core/acceptance.js.map +1 -0
  131. package/dist/src/core/errors.d.ts +20 -0
  132. package/dist/src/core/errors.js +30 -0
  133. package/dist/src/core/errors.js.map +1 -0
  134. package/dist/src/core/evidence.d.ts +10 -0
  135. package/dist/src/core/evidence.js +35 -0
  136. package/dist/src/core/evidence.js.map +1 -0
  137. package/dist/src/core/policies.d.ts +10 -0
  138. package/dist/src/core/policies.js +60 -0
  139. package/dist/src/core/policies.js.map +1 -0
  140. package/dist/src/core/recovery.d.ts +6 -0
  141. package/dist/src/core/recovery.js +56 -0
  142. package/dist/src/core/recovery.js.map +1 -0
  143. package/dist/src/core/transitions.d.ts +13 -0
  144. package/dist/src/core/transitions.js +59 -0
  145. package/dist/src/core/transitions.js.map +1 -0
  146. package/dist/src/core/types.d.ts +256 -0
  147. package/dist/src/core/types.js +2 -0
  148. package/dist/src/core/types.js.map +1 -0
  149. package/dist/src/extension.d.ts +60 -0
  150. package/dist/src/extension.js +538 -0
  151. package/dist/src/extension.js.map +1 -0
  152. package/dist/src/index.d.ts +29 -0
  153. package/dist/src/index.js +30 -0
  154. package/dist/src/index.js.map +1 -0
  155. package/dist/src/omp/autonomous-settings.d.ts +14 -0
  156. package/dist/src/omp/autonomous-settings.js +65 -0
  157. package/dist/src/omp/autonomous-settings.js.map +1 -0
  158. package/dist/src/omp/capabilities.d.ts +23 -0
  159. package/dist/src/omp/capabilities.js +6 -0
  160. package/dist/src/omp/capabilities.js.map +1 -0
  161. package/dist/src/omp/compatibility.d.ts +30 -0
  162. package/dist/src/omp/compatibility.js +34 -0
  163. package/dist/src/omp/compatibility.js.map +1 -0
  164. package/dist/src/omp/completion.d.ts +7 -0
  165. package/dist/src/omp/completion.js +10 -0
  166. package/dist/src/omp/completion.js.map +1 -0
  167. package/dist/src/omp/config.d.ts +10 -0
  168. package/dist/src/omp/config.js +14 -0
  169. package/dist/src/omp/config.js.map +1 -0
  170. package/dist/src/omp/context.d.ts +15 -0
  171. package/dist/src/omp/context.js +3 -0
  172. package/dist/src/omp/context.js.map +1 -0
  173. package/dist/src/omp/daemon-service.d.ts +25 -0
  174. package/dist/src/omp/daemon-service.js +483 -0
  175. package/dist/src/omp/daemon-service.js.map +1 -0
  176. package/dist/src/omp/daemon.d.ts +48 -0
  177. package/dist/src/omp/daemon.js +194 -0
  178. package/dist/src/omp/daemon.js.map +1 -0
  179. package/dist/src/omp/dashboard-html.d.ts +3 -0
  180. package/dist/src/omp/dashboard-html.js +419 -0
  181. package/dist/src/omp/dashboard-html.js.map +1 -0
  182. package/dist/src/omp/dispatch-admission.d.ts +2 -0
  183. package/dist/src/omp/dispatch-admission.js +12 -0
  184. package/dist/src/omp/dispatch-admission.js.map +1 -0
  185. package/dist/src/omp/integration-recovery.d.ts +10 -0
  186. package/dist/src/omp/integration-recovery.js +18 -0
  187. package/dist/src/omp/integration-recovery.js.map +1 -0
  188. package/dist/src/omp/isolation-policy.d.ts +14 -0
  189. package/dist/src/omp/isolation-policy.js +9 -0
  190. package/dist/src/omp/isolation-policy.js.map +1 -0
  191. package/dist/src/omp/lifecycle.d.ts +14 -0
  192. package/dist/src/omp/lifecycle.js +14 -0
  193. package/dist/src/omp/lifecycle.js.map +1 -0
  194. package/dist/src/omp/memory.d.ts +16 -0
  195. package/dist/src/omp/memory.js +4 -0
  196. package/dist/src/omp/memory.js.map +1 -0
  197. package/dist/src/omp/model-role-assignment.d.ts +296 -0
  198. package/dist/src/omp/model-role-assignment.js +559 -0
  199. package/dist/src/omp/model-role-assignment.js.map +1 -0
  200. package/dist/src/omp/model-roles.d.ts +19 -0
  201. package/dist/src/omp/model-roles.js +6 -0
  202. package/dist/src/omp/model-roles.js.map +1 -0
  203. package/dist/src/omp/omb-sessions.d.ts +122 -0
  204. package/dist/src/omp/omb-sessions.js +512 -0
  205. package/dist/src/omp/omb-sessions.js.map +1 -0
  206. package/dist/src/omp/omb-settings.d.ts +35 -0
  207. package/dist/src/omp/omb-settings.js +104 -0
  208. package/dist/src/omp/omb-settings.js.map +1 -0
  209. package/dist/src/omp/result-reconciliation.d.ts +2 -0
  210. package/dist/src/omp/result-reconciliation.js +9 -0
  211. package/dist/src/omp/result-reconciliation.js.map +1 -0
  212. package/dist/src/omp/rpc.d.ts +67 -0
  213. package/dist/src/omp/rpc.js +4 -0
  214. package/dist/src/omp/rpc.js.map +1 -0
  215. package/dist/src/omp/run-log.d.ts +25 -0
  216. package/dist/src/omp/run-log.js +24 -0
  217. package/dist/src/omp/run-log.js.map +1 -0
  218. package/dist/src/omp/session-activity.d.ts +70 -0
  219. package/dist/src/omp/session-activity.js +361 -0
  220. package/dist/src/omp/session-activity.js.map +1 -0
  221. package/dist/src/omp/session-controls.d.ts +17 -0
  222. package/dist/src/omp/session-controls.js +14 -0
  223. package/dist/src/omp/session-controls.js.map +1 -0
  224. package/dist/src/omp/tmux.d.ts +89 -0
  225. package/dist/src/omp/tmux.js +445 -0
  226. package/dist/src/omp/tmux.js.map +1 -0
  227. package/dist/src/omp/tray-icons.d.ts +5 -0
  228. package/dist/src/omp/tray-icons.js +78 -0
  229. package/dist/src/omp/tray-icons.js.map +1 -0
  230. package/dist/src/omp/tray.d.ts +23 -0
  231. package/dist/src/omp/tray.js +167 -0
  232. package/dist/src/omp/tray.js.map +1 -0
  233. package/dist/src/services/budget.d.ts +19 -0
  234. package/dist/src/services/budget.js +10 -0
  235. package/dist/src/services/budget.js.map +1 -0
  236. package/dist/src/services/candidate-local.d.ts +13 -0
  237. package/dist/src/services/candidate-local.js +15 -0
  238. package/dist/src/services/candidate-local.js.map +1 -0
  239. package/dist/src/services/candidates.d.ts +20 -0
  240. package/dist/src/services/candidates.js +100 -0
  241. package/dist/src/services/candidates.js.map +1 -0
  242. package/dist/src/services/evidence-bundle.d.ts +17 -0
  243. package/dist/src/services/evidence-bundle.js +21 -0
  244. package/dist/src/services/evidence-bundle.js.map +1 -0
  245. package/dist/src/services/inspector.d.ts +11 -0
  246. package/dist/src/services/inspector.js +6 -0
  247. package/dist/src/services/inspector.js.map +1 -0
  248. package/dist/src/services/lessons.d.ts +13 -0
  249. package/dist/src/services/lessons.js +11 -0
  250. package/dist/src/services/lessons.js.map +1 -0
  251. package/dist/src/services/projection.d.ts +21 -0
  252. package/dist/src/services/projection.js +10 -0
  253. package/dist/src/services/projection.js.map +1 -0
  254. package/dist/src/services/readiness.d.ts +4 -0
  255. package/dist/src/services/readiness.js +35 -0
  256. package/dist/src/services/readiness.js.map +1 -0
  257. package/dist/src/services/recipes.d.ts +15 -0
  258. package/dist/src/services/recipes.js +42 -0
  259. package/dist/src/services/recipes.js.map +1 -0
  260. package/dist/src/services/recovery.d.ts +19 -0
  261. package/dist/src/services/recovery.js +9 -0
  262. package/dist/src/services/recovery.js.map +1 -0
  263. package/dist/src/services/review.d.ts +15 -0
  264. package/dist/src/services/review.js +9 -0
  265. package/dist/src/services/review.js.map +1 -0
  266. package/dist/src/storage/journal-recovery.d.ts +10 -0
  267. package/dist/src/storage/journal-recovery.js +33 -0
  268. package/dist/src/storage/journal-recovery.js.map +1 -0
  269. package/dist/src/storage/journal.d.ts +12 -0
  270. package/dist/src/storage/journal.js +82 -0
  271. package/dist/src/storage/journal.js.map +1 -0
  272. package/dist/src/storage/migrations.d.ts +22 -0
  273. package/dist/src/storage/migrations.js +107 -0
  274. package/dist/src/storage/migrations.js.map +1 -0
  275. package/dist/src/storage/repository-identity.d.ts +11 -0
  276. package/dist/src/storage/repository-identity.js +67 -0
  277. package/dist/src/storage/repository-identity.js.map +1 -0
  278. package/dist/src/storage/resources.d.ts +66 -0
  279. package/dist/src/storage/resources.js +148 -0
  280. package/dist/src/storage/resources.js.map +1 -0
  281. package/dist/src/tools/evidence.d.ts +8 -0
  282. package/dist/src/tools/evidence.js +9 -0
  283. package/dist/src/tools/evidence.js.map +1 -0
  284. package/dist/src/tools/integrate.d.ts +13 -0
  285. package/dist/src/tools/integrate.js +90 -0
  286. package/dist/src/tools/integrate.js.map +1 -0
  287. package/dist/src/tools/result.d.ts +9 -0
  288. package/dist/src/tools/result.js +2 -0
  289. package/dist/src/tools/result.js.map +1 -0
  290. package/dist/src/tools/verify.d.ts +13 -0
  291. package/dist/src/tools/verify.js +61 -0
  292. package/dist/src/tools/verify.js.map +1 -0
  293. package/dist/src/tools/workflow.d.ts +8 -0
  294. package/dist/src/tools/workflow.js +65 -0
  295. package/dist/src/tools/workflow.js.map +1 -0
  296. package/dist/src/workflows/direct.d.ts +9 -0
  297. package/dist/src/workflows/direct.js +2 -0
  298. package/dist/src/workflows/direct.js.map +1 -0
  299. package/dist/src/workflows/implement.d.ts +2 -0
  300. package/dist/src/workflows/implement.js +4 -0
  301. package/dist/src/workflows/implement.js.map +1 -0
  302. package/dist/src/workflows/plan.d.ts +17 -0
  303. package/dist/src/workflows/plan.js +6 -0
  304. package/dist/src/workflows/plan.js.map +1 -0
  305. package/dist/src/workflows/research.d.ts +15 -0
  306. package/dist/src/workflows/research.js +2 -0
  307. package/dist/src/workflows/research.js.map +1 -0
  308. package/dist/src/workflows/review.d.ts +15 -0
  309. package/dist/src/workflows/review.js +2 -0
  310. package/dist/src/workflows/review.js.map +1 -0
  311. package/dist/src/workflows/verify.d.ts +9 -0
  312. package/dist/src/workflows/verify.js +2 -0
  313. package/dist/src/workflows/verify.js.map +1 -0
  314. package/dist/tests/acceptance.test.d.ts +1 -0
  315. package/dist/tests/acceptance.test.js +27 -0
  316. package/dist/tests/acceptance.test.js.map +1 -0
  317. package/dist/tests/agents.test.d.ts +1 -0
  318. package/dist/tests/agents.test.js +369 -0
  319. package/dist/tests/agents.test.js.map +1 -0
  320. package/dist/tests/candidates.test.d.ts +1 -0
  321. package/dist/tests/candidates.test.js +60 -0
  322. package/dist/tests/candidates.test.js.map +1 -0
  323. package/dist/tests/core.test.d.ts +1 -0
  324. package/dist/tests/core.test.js +39 -0
  325. package/dist/tests/core.test.js.map +1 -0
  326. package/dist/tests/daemon.test.d.ts +1 -0
  327. package/dist/tests/daemon.test.js +157 -0
  328. package/dist/tests/daemon.test.js.map +1 -0
  329. package/dist/tests/dashboard.test.d.ts +1 -0
  330. package/dist/tests/dashboard.test.js +414 -0
  331. package/dist/tests/dashboard.test.js.map +1 -0
  332. package/dist/tests/directory-selector.test.d.ts +1 -0
  333. package/dist/tests/directory-selector.test.js +93 -0
  334. package/dist/tests/directory-selector.test.js.map +1 -0
  335. package/dist/tests/doctor.test.d.ts +1 -0
  336. package/dist/tests/doctor.test.js +32 -0
  337. package/dist/tests/doctor.test.js.map +1 -0
  338. package/dist/tests/install.test.d.ts +1 -0
  339. package/dist/tests/install.test.js +101 -0
  340. package/dist/tests/install.test.js.map +1 -0
  341. package/dist/tests/integration.test.d.ts +1 -0
  342. package/dist/tests/integration.test.js +49 -0
  343. package/dist/tests/integration.test.js.map +1 -0
  344. package/dist/tests/journal.test.d.ts +1 -0
  345. package/dist/tests/journal.test.js +50 -0
  346. package/dist/tests/journal.test.js.map +1 -0
  347. package/dist/tests/model-role-assignment.test.d.ts +1 -0
  348. package/dist/tests/model-role-assignment.test.js +294 -0
  349. package/dist/tests/model-role-assignment.test.js.map +1 -0
  350. package/dist/tests/omb-runtime.test.d.ts +1 -0
  351. package/dist/tests/omb-runtime.test.js +554 -0
  352. package/dist/tests/omb-runtime.test.js.map +1 -0
  353. package/dist/tests/omb-session-actions.test.d.ts +1 -0
  354. package/dist/tests/omb-session-actions.test.js +191 -0
  355. package/dist/tests/omb-session-actions.test.js.map +1 -0
  356. package/dist/tests/omb-settings.test.d.ts +1 -0
  357. package/dist/tests/omb-settings.test.js +82 -0
  358. package/dist/tests/omb-settings.test.js.map +1 -0
  359. package/dist/tests/omp-contract.test.d.ts +1 -0
  360. package/dist/tests/omp-contract.test.js +362 -0
  361. package/dist/tests/omp-contract.test.js.map +1 -0
  362. package/dist/tests/process.test.d.ts +1 -0
  363. package/dist/tests/process.test.js +12 -0
  364. package/dist/tests/process.test.js.map +1 -0
  365. package/dist/tests/psmux-windows.test.d.ts +1 -0
  366. package/dist/tests/psmux-windows.test.js +105 -0
  367. package/dist/tests/psmux-windows.test.js.map +1 -0
  368. package/dist/tests/recovery.test.d.ts +1 -0
  369. package/dist/tests/recovery.test.js +9 -0
  370. package/dist/tests/recovery.test.js.map +1 -0
  371. package/dist/tests/resources.test.d.ts +1 -0
  372. package/dist/tests/resources.test.js +55 -0
  373. package/dist/tests/resources.test.js.map +1 -0
  374. package/dist/tests/session-activity.test.d.ts +1 -0
  375. package/dist/tests/session-activity.test.js +159 -0
  376. package/dist/tests/session-activity.test.js.map +1 -0
  377. package/dist/tests/setup-ui.test.d.ts +1 -0
  378. package/dist/tests/setup-ui.test.js +37 -0
  379. package/dist/tests/setup-ui.test.js.map +1 -0
  380. package/dist/tests/storage-integrity.test.d.ts +1 -0
  381. package/dist/tests/storage-integrity.test.js +88 -0
  382. package/dist/tests/storage-integrity.test.js.map +1 -0
  383. package/dist/tests/tmux.test.d.ts +1 -0
  384. package/dist/tests/tmux.test.js +239 -0
  385. package/dist/tests/tmux.test.js.map +1 -0
  386. package/dist/tests/tray.test.d.ts +1 -0
  387. package/dist/tests/tray.test.js +37 -0
  388. package/dist/tests/tray.test.js.map +1 -0
  389. package/dist/tests/verification.test.d.ts +1 -0
  390. package/dist/tests/verification.test.js +61 -0
  391. package/dist/tests/verification.test.js.map +1 -0
  392. package/dist/tests/workflow-features.test.d.ts +1 -0
  393. package/dist/tests/workflow-features.test.js +82 -0
  394. package/dist/tests/workflow-features.test.js.map +1 -0
  395. package/dist/tests/workflow-safety.test.d.ts +1 -0
  396. package/dist/tests/workflow-safety.test.js +57 -0
  397. package/dist/tests/workflow-safety.test.js.map +1 -0
  398. package/docs/compatibility/baseline.json +1 -1
  399. package/docs/decisions/console-handoff.md +5 -0
  400. package/docs/releases/0.6.2.md +32 -0
  401. package/docs/releases/0.6.3.md +27 -0
  402. package/package.json +1 -1
  403. package/skills/bizar-omp/SKILL.md +2 -1
@@ -126,7 +126,172 @@ export declare const BIZAR_ROLE_PROFILES: readonly RoleProfile[];
126
126
  export declare const BIZAR_MODEL_ROLE_AGENT_PROMPT: string;
127
127
  export declare function isLocalModel(model: AvailableModel): boolean;
128
128
  export declare function planBizarModelRoles(query: ModelQuery): RoleAssignmentPlan;
129
- export declare function applyRoleAssignmentPlan(current: Record<string, unknown>, plan: RoleAssignmentPlan, expectedRolesHash?: string): Record<string, unknown>;
129
+ /**
130
+ * Pure mapping copy: applies a plan onto a settings map without mutating or
131
+ * validating it. Staleness is checked by the caller that owns the write, so no
132
+ * caller can pass a hash of the same object it is about to overwrite.
133
+ */
134
+ export declare function applyRoleAssignmentPlan(current: Record<string, unknown>, plan: RoleAssignmentPlan): Record<string, unknown>;
130
135
  export declare function formatRoleAssignmentPlan(plan: RoleAssignmentPlan): string;
136
+ /**
137
+ * Native tool the agent calls to persist a reviewed distribution. The command
138
+ * handler cannot make a model call itself, so `/bizar-models` gathers the
139
+ * catalog, then hands the bounded evaluation to the active agent, which must
140
+ * call this tool for anything to be written.
141
+ */
142
+ export declare const BIZAR_MODEL_ROLE_TOOL = "bizar_apply_model_roles";
143
+ /**
144
+ * Longest operator notice OMP's status line can carry without clipping.
145
+ *
146
+ * `ctx.ui.notify(message, "info")` renders through the host status line, which
147
+ * builds exactly one text component and folds it onto two screen lines at the
148
+ * default 80-column terminal width — roughly 300 characters. The model-role
149
+ * command's own report (catalog movement, headline, and a line per role) runs
150
+ * far past that, so the tail silently never appears. A `warning`/`error` notice
151
+ * is not an alternative: those draw the full error banner.
152
+ */
153
+ export declare const OPERATOR_NOTICE_LIMIT = 300;
154
+ /**
155
+ * Fit a report into the status line, clipping from the front. Catalog movement
156
+ * and the applied-map verdict sit before the per-role lines, so a truncated
157
+ * notice always keeps the lines that say what happened and loses the tail.
158
+ */
159
+ export declare function clipOperatorNotice(report: string, limit?: number): string;
160
+ /** Settings surface role assignment needs, with both members guaranteed present. */
161
+ export interface RoleAssignmentSettings {
162
+ get(path: string): unknown;
163
+ set(path: string, value: unknown): void;
164
+ }
165
+ export type RoleAssignmentRoute = {
166
+ kind: "agent";
167
+ settings: RoleAssignmentSettings;
168
+ models: AvailableModel[];
169
+ send: (content: string) => void;
170
+ } | {
171
+ kind: "local-plan";
172
+ settings: RoleAssignmentSettings;
173
+ models: AvailableModel[];
174
+ } | {
175
+ kind: "agent-prompt-only";
176
+ send: (content: string) => void;
177
+ } | {
178
+ kind: "unsupported";
179
+ };
180
+ /**
181
+ * Decide how this host can distribute roles. An agent evaluation needs both the
182
+ * live catalog and a way to reach the agent; a host without agent messaging
183
+ * falls back to deterministic scoring; a host without any of it cannot assign
184
+ * roles and says so instead of writing a partial mapping.
185
+ */
186
+ export declare function roleAssignmentRoute(host: {
187
+ settings?: {
188
+ get?(path: string): unknown;
189
+ set?(path: string, value: unknown): void;
190
+ };
191
+ models?: readonly AvailableModel[];
192
+ sendUserMessage?: (content: string, options?: {
193
+ deliverAs?: "steer" | "followUp" | "aside";
194
+ }) => void;
195
+ }): RoleAssignmentRoute;
196
+ /** One model's normalized capability fields. Missing metadata stays explicitly unknown. */
197
+ export interface CatalogModelRecord {
198
+ selector: string;
199
+ fields: Record<string, string>;
200
+ }
201
+ /** Catalog observation persisted between `/bizar-models` invocations. */
202
+ export interface CatalogSnapshot {
203
+ digest: string;
204
+ capturedAt: number;
205
+ models: CatalogModelRecord[];
206
+ }
207
+ export interface CatalogChange {
208
+ kind: "added" | "removed" | "changed";
209
+ selector: string;
210
+ detail: string;
211
+ }
212
+ export interface CatalogDelta {
213
+ firstObservation: boolean;
214
+ added: CatalogChange[];
215
+ removed: CatalogChange[];
216
+ changed: CatalogChange[];
217
+ unchanged: number;
218
+ modelCount: number;
219
+ }
220
+ /** Normalize a catalog into a comparable, digestible observation. */
221
+ export declare function snapshotCatalog(models: readonly AvailableModel[], capturedAt?: number): CatalogSnapshot;
222
+ /** Accept only a well-formed stored snapshot; anything else counts as no prior observation. */
223
+ export declare function parseCatalogSnapshot(value: unknown): CatalogSnapshot | undefined;
224
+ /** Compare the freshly read catalog against the previously observed one. */
225
+ export declare function diffCatalog(previous: CatalogSnapshot | undefined, next: CatalogSnapshot): CatalogDelta;
226
+ /** Compact, bounded catalog report. Detail lines are capped so the summary stays readable. */
227
+ export declare function formatCatalogDelta(delta: CatalogDelta): string;
228
+ export interface RoleRecommendation {
229
+ role: string;
230
+ selector: string;
231
+ rationale?: string;
232
+ }
233
+ export interface RoleRecommendationReview {
234
+ accepted: RoleRecommendation[];
235
+ /** Selectors rewritten to the catalog's own spelling, reported so the agent sees the repair. */
236
+ normalized: Array<{
237
+ role: string;
238
+ from: string;
239
+ to: string;
240
+ }>;
241
+ rejected: Array<{
242
+ role: string;
243
+ selector?: string;
244
+ reason: string;
245
+ }>;
246
+ }
247
+ /**
248
+ * Validate an agent-proposed distribution against the live catalog. A selector
249
+ * must name a catalog entry: only its casing is repaired (to the spelling the
250
+ * catalog reports, when that fold is unambiguous), and nothing is inferred from
251
+ * a model name. Unknown roles and unresolvable selectors are rejected rather
252
+ * than guessed.
253
+ */
254
+ export declare function reviewRoleRecommendations(value: unknown, options: {
255
+ roles: readonly string[];
256
+ models: readonly AvailableModel[];
257
+ resolve?: (selector: string) => unknown;
258
+ }): RoleRecommendationReview;
259
+ /** Turn accepted recommendations into the same plan shape the local planner produces. */
260
+ export declare function planFromRecommendations(review: RoleRecommendationReview, models: readonly AvailableModel[]): RoleAssignmentPlan;
261
+ /** Before/after mapping limited to the Bizar roles, including explicit unchanged entries. */
262
+ export declare function formatRoleMapping(before: Record<string, unknown>, after: Record<string, unknown>, roles?: readonly string[]): string;
263
+ /** Settings surface a role commit writes to, plus the resolver that vets selectors. */
264
+ export interface RoleCommitInput {
265
+ settings: {
266
+ get(path: string): unknown;
267
+ set(path: string, value: unknown): void;
268
+ };
269
+ resolve(selector: string): unknown;
270
+ plan: RoleAssignmentPlan;
271
+ delta: CatalogDelta;
272
+ /** How the distribution was decided, reported back to the operator. */
273
+ source: string;
274
+ }
275
+ /** Present value as an object map; anything else is treated as empty. */
276
+ export declare function recordOf(value: unknown): Record<string, unknown>;
277
+ /**
278
+ * Resolve every proposed selector before writing anything, then persist the
279
+ * whole mapping in one `modelRoles` update. An unresolvable selector or an
280
+ * empty plan writes nothing at all, unrelated settings and non-Bizar roles are
281
+ * copied through untouched, and re-running against the current mapping is a
282
+ * no-op. The caller records the observed catalog only after this returns.
283
+ */
284
+ export declare function commitRolePlan(input: RoleCommitInput): string;
285
+ /**
286
+ * Bounded evaluation request handed to the active agent. It carries only the
287
+ * live catalog, the current mapping and the deterministic baseline, so the
288
+ * agent can decide quickly without further research.
289
+ */
290
+ export declare function buildAgentEvaluationRequest(input: {
291
+ models: readonly AvailableModel[];
292
+ currentRoles: Record<string, unknown>;
293
+ baseline: RoleAssignmentPlan;
294
+ delta: CatalogDelta;
295
+ }): string;
131
296
  export {};
132
297
  //# sourceMappingURL=model-role-assignment.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"model-role-assignment.d.ts","sourceRoot":"","sources":["../../src/omp/model-role-assignment.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"model-role-assignment.d.ts","sourceRoot":"","sources":["../../src/omp/model-role-assignment.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,5 @@
1
+ import { createHash } from "node:crypto";
2
+ import { ContractError } from "../core/errors.js";
1
3
  /** Native-compatible defaults used until an operator runs model-role assignment. */
2
4
  export const BIZAR_MODEL_ROLES = {
3
5
  bizar_orchestrator: "@default",
@@ -54,6 +56,21 @@ export const BIZAR_MODEL_ROLE_AGENT_PROMPT = [
54
56
  "Preserve non-Bizar roles and unrelated settings, make no project or credential changes, and report only a compact role-to-selector table plus unresolved roles.",
55
57
  ].join(" ");
56
58
  const selectorFor = (model) => `${model.provider}/${model.id}`;
59
+ /**
60
+ * Catalog text comes from providers, so it is data, not instruction. Collapse
61
+ * every control character (including newlines, which would otherwise fabricate
62
+ * request lines) and cap the length of each provider-controlled value before it
63
+ * reaches the agent prompt.
64
+ */
65
+ const sanitizeCatalogText = (value, limit = 96) => {
66
+ const collapsed = value.replace(/[\u0000-\u001f\u007f]+/g, " ").replace(/\s+/g, " ").trim();
67
+ return collapsed.length > limit ? `${collapsed.slice(0, limit)}…` : collapsed;
68
+ };
69
+ /** Provider part of a `provider/model` selector, or `alias` for a bare native alias. */
70
+ const selectorProvider = (selector) => {
71
+ const separator = selector.indexOf("/");
72
+ return separator > 0 ? selector.slice(0, separator) : "alias";
73
+ };
57
74
  const hasTextInput = (model) => !model.input || model.input.length === 0 || model.input.includes("text");
58
75
  const THINKING_LEVELS = ["minimal", "low", "medium", "high", "xhigh", "max"];
59
76
  function thinkingLevels(value) {
@@ -101,7 +118,10 @@ function qualityScore(model, profile) {
101
118
  const output = Math.min(1, Math.log10(Math.max(1, model.maxTokens ?? 0)) / 6);
102
119
  const reasoning = model.reasoning ? 1 : 0;
103
120
  const thinking = maxThinkingRank(model) / 5;
104
- const costPenalty = Math.min(1, Math.log10(1 + hourlyCost(model)) / 3);
121
+ // Unknown pricing is scored at the middle of the penalty range, never at the
122
+ // cheap end: a model whose cost metadata is missing must not win a
123
+ // cost-sensitive role by omission, and it is reported as `cost: unknown`.
124
+ const costPenalty = modelCostKnown(model) ? Math.min(1, Math.log10(1 + hourlyCost(model)) / 3) : 0.5;
105
125
  // A role may prefer locally hosted models (free per token, on-device).
106
126
  // The bonus is additive and opt-in per profile: a local model that fits
107
127
  // overtakes comparable cloud models, while a mismatch still falls back.
@@ -149,9 +169,12 @@ export function planBizarModelRoles(query) {
149
169
  return { assignments, unavailable, modelCount: models.length };
150
170
  }
151
171
  function modelCostKnown(model) { return typeof model.cost?.input === "number" && typeof model.cost?.output === "number"; }
152
- export function applyRoleAssignmentPlan(current, plan, expectedRolesHash = JSON.stringify(current)) {
153
- if (JSON.stringify(current) !== expectedRolesHash)
154
- throw new Error("Model-role settings changed since preview; refusing to overwrite the operator's edit");
172
+ /**
173
+ * Pure mapping copy: applies a plan onto a settings map without mutating or
174
+ * validating it. Staleness is checked by the caller that owns the write, so no
175
+ * caller can pass a hash of the same object it is about to overwrite.
176
+ */
177
+ export function applyRoleAssignmentPlan(current, plan) {
155
178
  const next = { ...current };
156
179
  for (const assignment of plan.assignments)
157
180
  next[assignment.role] = assignment.selector;
@@ -167,4 +190,370 @@ export function formatRoleAssignmentPlan(plan) {
167
190
  lines.push("No settings were changed because the plan is incomplete.");
168
191
  return lines.join("\n");
169
192
  }
193
+ /**
194
+ * Native tool the agent calls to persist a reviewed distribution. The command
195
+ * handler cannot make a model call itself, so `/bizar-models` gathers the
196
+ * catalog, then hands the bounded evaluation to the active agent, which must
197
+ * call this tool for anything to be written.
198
+ */
199
+ export const BIZAR_MODEL_ROLE_TOOL = "bizar_apply_model_roles";
200
+ /**
201
+ * Longest operator notice OMP's status line can carry without clipping.
202
+ *
203
+ * `ctx.ui.notify(message, "info")` renders through the host status line, which
204
+ * builds exactly one text component and folds it onto two screen lines at the
205
+ * default 80-column terminal width — roughly 300 characters. The model-role
206
+ * command's own report (catalog movement, headline, and a line per role) runs
207
+ * far past that, so the tail silently never appears. A `warning`/`error` notice
208
+ * is not an alternative: those draw the full error banner.
209
+ */
210
+ export const OPERATOR_NOTICE_LIMIT = 300;
211
+ /**
212
+ * Fit a report into the status line, clipping from the front. Catalog movement
213
+ * and the applied-map verdict sit before the per-role lines, so a truncated
214
+ * notice always keeps the lines that say what happened and loses the tail.
215
+ */
216
+ export function clipOperatorNotice(report, limit = OPERATOR_NOTICE_LIMIT) {
217
+ const text = report.trim();
218
+ if (text.length <= limit)
219
+ return text;
220
+ const dropped = text.length - limit;
221
+ const note = `…clipped; ${dropped} more characters in the session log`;
222
+ if (note.length >= limit)
223
+ return note.slice(-limit);
224
+ const head = text.slice(0, limit - note.length - 1).trimEnd();
225
+ return `${head} ${note}`;
226
+ }
227
+ /**
228
+ * Decide how this host can distribute roles. An agent evaluation needs both the
229
+ * live catalog and a way to reach the agent; a host without agent messaging
230
+ * falls back to deterministic scoring; a host without any of it cannot assign
231
+ * roles and says so instead of writing a partial mapping.
232
+ */
233
+ export function roleAssignmentRoute(host) {
234
+ const settingsHost = host.settings;
235
+ const get = settingsHost?.get?.bind(settingsHost);
236
+ const set = settingsHost?.set?.bind(settingsHost);
237
+ const sendMessage = host.sendUserMessage;
238
+ // OMP queues an explicit `followUp` without starting a turn, and only
239
+ // auto-continues it when the transcript tail is already assistant/toolResult:
240
+ // in a session that has not run a turn yet the evaluation stays queued behind
241
+ // the user's next prompt instead of running. `aside` starts a turn at an idle
242
+ // session, and while streaming it is injected at the next step boundary
243
+ // instead of aborting the in-flight tool batch.
244
+ const send = sendMessage ? (content) => { sendMessage(content, { deliverAs: "aside" }); } : undefined;
245
+ const models = host.models ? [...host.models] : [];
246
+ if (get && set && models.length > 0) {
247
+ const settings = { get, set };
248
+ return send ? { kind: "agent", settings, models, send } : { kind: "local-plan", settings, models };
249
+ }
250
+ return send ? { kind: "agent-prompt-only", send } : { kind: "unsupported" };
251
+ }
252
+ function catalogFields(model) {
253
+ const levels = thinkingLevels(model.thinking);
254
+ return {
255
+ provider: model.provider,
256
+ contextWindow: typeof model.contextWindow === "number" ? String(model.contextWindow) : "unknown",
257
+ maxTokens: typeof model.maxTokens === "number" ? String(model.maxTokens) : "unknown",
258
+ reasoning: model.reasoning === true ? "yes" : model.reasoning === false ? "no" : "unknown",
259
+ thinking: levels.length > 0 ? levels.join(",") : "unknown",
260
+ cost: modelCostKnown(model) ? `${model.cost?.input}/${model.cost?.output}` : "unknown",
261
+ input: model.input && model.input.length > 0 ? [...model.input].sort().join(",") : "unknown",
262
+ locality: isLocalModel(model) ? "local" : "remote",
263
+ };
264
+ }
265
+ const describeFields = (fields) => Object.keys(fields).sort().map(key => `${key}=${sanitizeCatalogText(fields[key], 64)}`).join(" ");
266
+ function describeFieldChanges(prior, next) {
267
+ return Object.keys(next).sort().flatMap(key => {
268
+ const before = prior[key] ?? "unknown";
269
+ return before === next[key] ? [] : [`${key} ${before} -> ${next[key]}`];
270
+ });
271
+ }
272
+ /** Normalize a catalog into a comparable, digestible observation. */
273
+ export function snapshotCatalog(models, capturedAt = Date.now()) {
274
+ const records = models
275
+ .map(model => ({ selector: selectorFor(model), fields: catalogFields(model) }))
276
+ .sort((left, right) => left.selector.localeCompare(right.selector));
277
+ const lines = records.map(({ selector, fields }) => `${selector}|${describeFields(fields)}`);
278
+ return { digest: createHash("sha256").update(lines.join("\n")).digest("hex"), capturedAt, models: records };
279
+ }
280
+ /** Accept only a well-formed stored snapshot; anything else counts as no prior observation. */
281
+ export function parseCatalogSnapshot(value) {
282
+ if (!value || typeof value !== "object" || Array.isArray(value))
283
+ return undefined;
284
+ const record = value;
285
+ if (typeof record.digest !== "string" || !Array.isArray(record.models))
286
+ return undefined;
287
+ const models = [];
288
+ for (const entry of record.models) {
289
+ if (!entry || typeof entry !== "object" || Array.isArray(entry))
290
+ return undefined;
291
+ const model = entry;
292
+ if (typeof model.selector !== "string" || !model.fields || typeof model.fields !== "object" || Array.isArray(model.fields))
293
+ return undefined;
294
+ const fields = {};
295
+ for (const [key, field] of Object.entries(model.fields)) {
296
+ if (typeof field !== "string")
297
+ return undefined;
298
+ fields[key] = field;
299
+ }
300
+ models.push({ selector: model.selector, fields });
301
+ }
302
+ return { digest: record.digest, capturedAt: typeof record.capturedAt === "number" ? record.capturedAt : 0, models };
303
+ }
304
+ /** Compare the freshly read catalog against the previously observed one. */
305
+ export function diffCatalog(previous, next) {
306
+ const before = new Map((previous?.models ?? []).map(model => [model.selector, model.fields]));
307
+ const after = new Map(next.models.map(model => [model.selector, model.fields]));
308
+ const added = [];
309
+ const removed = [];
310
+ const changed = [];
311
+ let unchanged = 0;
312
+ for (const [selector, fields] of after) {
313
+ const prior = before.get(selector);
314
+ if (!prior) {
315
+ added.push({ kind: "added", selector, detail: describeFields(fields) });
316
+ continue;
317
+ }
318
+ const differences = describeFieldChanges(prior, fields);
319
+ if (differences.length > 0)
320
+ changed.push({ kind: "changed", selector, detail: differences.join("; ") });
321
+ else
322
+ unchanged += 1;
323
+ }
324
+ for (const selector of before.keys()) {
325
+ if (!after.has(selector))
326
+ removed.push({ kind: "removed", selector, detail: "no longer returned by the authenticated catalog" });
327
+ }
328
+ return { firstObservation: previous === undefined, added, removed, changed, unchanged, modelCount: next.models.length };
329
+ }
330
+ /** Compact, bounded catalog report. Detail lines are capped so the summary stays readable. */
331
+ export function formatCatalogDelta(delta) {
332
+ if (delta.firstObservation)
333
+ return `Catalog: first observation, ${delta.modelCount} available models recorded.`;
334
+ const headline = `Catalog: ${delta.added.length} added, ${delta.removed.length} removed, ${delta.changed.length} changed, ${delta.unchanged} unchanged (${delta.modelCount} available).`;
335
+ const all = [...delta.added, ...delta.removed, ...delta.changed];
336
+ const details = all
337
+ .slice(0, 8)
338
+ .map(change => ` ${change.kind === "added" ? "+" : change.kind === "removed" ? "-" : "~"} ${change.selector}: ${change.detail}`);
339
+ if (all.length > details.length)
340
+ details.push(` … ${all.length - details.length} more changes not shown`);
341
+ return [headline, ...details].join("\n");
342
+ }
343
+ const RECOMMENDATION_REJECTED = "expected {\"assignment\":[{\"role\":..,\"selector\":..}]} or a role-to-selector object";
344
+ function recommendationCandidates(value) {
345
+ if (Array.isArray(value))
346
+ return value;
347
+ if (!value || typeof value !== "object")
348
+ return undefined;
349
+ const record = value;
350
+ if (Array.isArray(record.assignment))
351
+ return record.assignment;
352
+ if (Array.isArray(record.assignments))
353
+ return record.assignments;
354
+ if (record.roles && typeof record.roles === "object" && !Array.isArray(record.roles)) {
355
+ return Object.entries(record.roles).map(([role, selector]) => ({ role, selector }));
356
+ }
357
+ return undefined;
358
+ }
359
+ /**
360
+ * Catalog selectors keyed by case-folded spelling. A fold shared by two catalog
361
+ * entries is dropped, so a repair never picks one of two live models.
362
+ */
363
+ function caseFoldedSelectors(selectors) {
364
+ const folded = new Map();
365
+ const ambiguous = new Set();
366
+ for (const selector of selectors) {
367
+ const key = selector.toLowerCase();
368
+ if (ambiguous.has(key))
369
+ continue;
370
+ if (folded.has(key)) {
371
+ folded.delete(key);
372
+ ambiguous.add(key);
373
+ continue;
374
+ }
375
+ folded.set(key, selector);
376
+ }
377
+ return folded;
378
+ }
379
+ /**
380
+ * Validate an agent-proposed distribution against the live catalog. A selector
381
+ * must name a catalog entry: only its casing is repaired (to the spelling the
382
+ * catalog reports, when that fold is unambiguous), and nothing is inferred from
383
+ * a model name. Unknown roles and unresolvable selectors are rejected rather
384
+ * than guessed.
385
+ */
386
+ export function reviewRoleRecommendations(value, options) {
387
+ const candidates = recommendationCandidates(value);
388
+ if (!candidates)
389
+ return { accepted: [], normalized: [], rejected: [{ role: "*", reason: RECOMMENDATION_REJECTED }] };
390
+ const known = new Set(options.roles);
391
+ const selectors = new Set(options.models.map(model => selectorFor(model)));
392
+ const folded = caseFoldedSelectors(selectors);
393
+ const accepted = [];
394
+ const normalized = [];
395
+ const rejected = [];
396
+ const seen = new Set();
397
+ for (const candidate of candidates) {
398
+ if (!candidate || typeof candidate !== "object" || Array.isArray(candidate)) {
399
+ rejected.push({ role: "*", reason: "each recommendation must be an object with role and selector" });
400
+ continue;
401
+ }
402
+ const entry = candidate;
403
+ const role = typeof entry.role === "string" ? entry.role.trim() : "";
404
+ const selector = typeof entry.selector === "string" ? entry.selector.trim() : "";
405
+ if (!role || !selector) {
406
+ rejected.push({ role: role || "*", selector: selector || undefined, reason: "each recommendation needs both a role and a selector" });
407
+ continue;
408
+ }
409
+ if (!known.has(role)) {
410
+ rejected.push({ role: role || "*", selector: selector || undefined, reason: "not a Bizar model role" });
411
+ continue;
412
+ }
413
+ if (seen.has(role)) {
414
+ rejected.push({ role, selector, reason: "duplicate recommendation for this role" });
415
+ continue;
416
+ }
417
+ if (selectors.size === 0 && !options.resolve) {
418
+ rejected.push({ role, selector: selector || undefined, reason: "the host exposed no model catalog to validate against" });
419
+ continue;
420
+ }
421
+ const catalogSelector = selectors.has(selector) ? selector : folded.get(selector.toLowerCase());
422
+ if (catalogSelector === undefined && !options.resolve?.(selector)) {
423
+ rejected.push({
424
+ role,
425
+ selector,
426
+ reason: options.resolve ? "selector is not resolvable in the live catalog or by an OMP model alias" : "selector is not in the live catalog",
427
+ });
428
+ continue;
429
+ }
430
+ seen.add(role);
431
+ const rationale = typeof entry.rationale === "string" && entry.rationale.trim() ? entry.rationale.trim() : undefined;
432
+ if (catalogSelector !== undefined && catalogSelector !== selector)
433
+ normalized.push({ role, from: selector, to: catalogSelector });
434
+ accepted.push({ role, selector: catalogSelector ?? selector, rationale });
435
+ }
436
+ return { accepted, normalized, rejected };
437
+ }
438
+ /** Turn accepted recommendations into the same plan shape the local planner produces. */
439
+ export function planFromRecommendations(review, models) {
440
+ const bySelector = new Map(models.map(model => [selectorFor(model), model]));
441
+ const assignments = [];
442
+ for (const recommendation of review.accepted) {
443
+ // A selector the review accepted through the host resolver (a native alias
444
+ // such as `@smol`, or an effort suffix) has no catalog record; it is carried
445
+ // through with unknown metadata instead of being dropped here, so the write
446
+ // gate stays the single place that decides resolvability.
447
+ const model = bySelector.get(recommendation.selector) ?? { provider: selectorProvider(recommendation.selector), id: recommendation.selector };
448
+ assignments.push({
449
+ role: recommendation.role,
450
+ selector: recommendation.selector,
451
+ model,
452
+ rationale: recommendation.rationale ?? "agent-selected distribution",
453
+ alternatives: [],
454
+ metadata: { cost: modelCostKnown(model) ? "known" : "unknown", locality: isLocalModel(model) ? "provider-hint" : "unknown" },
455
+ });
456
+ }
457
+ return {
458
+ assignments,
459
+ unavailable: review.rejected.map(item => ({ role: item.role, reason: item.reason })),
460
+ modelCount: models.length,
461
+ };
462
+ }
463
+ /** Before/after mapping limited to the Bizar roles, including explicit unchanged entries. */
464
+ export function formatRoleMapping(before, after, roles = Object.keys(BIZAR_MODEL_ROLES)) {
465
+ return roles.map(role => {
466
+ const prior = typeof before[role] === "string" ? before[role] : "(unset)";
467
+ const next = typeof after[role] === "string" ? after[role] : "(unset)";
468
+ if (prior === next)
469
+ return `- ${role}: ${next} (unchanged)`;
470
+ return `- ${role}: ${prior} -> ${next}`;
471
+ }).join("\n");
472
+ }
473
+ /** Present value as an object map; anything else is treated as empty. */
474
+ export function recordOf(value) {
475
+ return value && typeof value === "object" && !Array.isArray(value) ? value : {};
476
+ }
477
+ /**
478
+ * Resolve every proposed selector before writing anything, then persist the
479
+ * whole mapping in one `modelRoles` update. An unresolvable selector or an
480
+ * empty plan writes nothing at all, unrelated settings and non-Bizar roles are
481
+ * copied through untouched, and re-running against the current mapping is a
482
+ * no-op. The caller records the observed catalog only after this returns.
483
+ */
484
+ export function commitRolePlan(input) {
485
+ const roles = Object.keys(BIZAR_MODEL_ROLES);
486
+ const before = recordOf(input.settings.get("modelRoles"));
487
+ if (input.plan.assignments.length === 0) {
488
+ const reasons = input.plan.unavailable.map(({ role, reason }) => `${role}: ${reason}`).join("; ");
489
+ throw new ContractError(`Bizar model mapping skipped: no Bizar role had an eligible catalog candidate.${reasons ? ` ${reasons}` : ""}`);
490
+ }
491
+ const unresolved = input.plan.assignments.filter(({ selector }) => !input.resolve(selector));
492
+ if (unresolved.length > 0) {
493
+ throw new ContractError(`Bizar model mapping refused; OMP could not resolve ${unresolved.map(({ role, selector }) => `${role}=${selector}`).join(", ")}. No settings were written.`);
494
+ }
495
+ // Re-read immediately before writing: selector resolution and the plan were
496
+ // computed against the mapping read above, so a concurrent edit in that window
497
+ // must refuse the commit instead of being overwritten.
498
+ const current = recordOf(input.settings.get("modelRoles"));
499
+ if (JSON.stringify(current) !== JSON.stringify(before)) {
500
+ throw new ContractError("Bizar model-role settings changed while the distribution was being resolved; nothing was written. Re-run /bizar-models.");
501
+ }
502
+ const after = applyRoleAssignmentPlan(before, input.plan);
503
+ const changed = JSON.stringify(after) !== JSON.stringify(before);
504
+ if (changed)
505
+ input.settings.set("modelRoles", after);
506
+ const covered = new Set(input.plan.assignments.map(({ role }) => role));
507
+ const uncovered = roles.filter(role => !covered.has(role));
508
+ const lines = [
509
+ formatCatalogDelta(input.delta),
510
+ `Assigned ${input.plan.assignments.length}/${roles.length} Bizar roles from ${input.plan.modelCount} available OMP models (${input.source}); modelRoles ${changed ? "updated" : "already current, left as is"}.`,
511
+ formatRoleMapping(before, after, roles),
512
+ ];
513
+ if (uncovered.length > 0)
514
+ lines.push(`Left unchanged (not assigned by this evaluation): ${uncovered.join(", ")}.`);
515
+ if (input.plan.unavailable.length > 0)
516
+ lines.push(`Not applied: ${input.plan.unavailable.map(({ role, reason }) => `${role} (${reason})`).join("; ")}.`);
517
+ return lines.join("\n");
518
+ }
519
+ /**
520
+ * Bounded evaluation request handed to the active agent. It carries only the
521
+ * live catalog, the current mapping and the deterministic baseline, so the
522
+ * agent can decide quickly without further research.
523
+ */
524
+ export function buildAgentEvaluationRequest(input) {
525
+ const catalogLines = input.models
526
+ .map(model => `${sanitizeCatalogText(selectorFor(model))} ${describeFields(catalogFields(model))}`)
527
+ .sort();
528
+ const currentLines = BIZAR_ROLE_PROFILES.map(profile => {
529
+ const selector = typeof input.currentRoles[profile.role] === "string" ? sanitizeCatalogText(input.currentRoles[profile.role]) : "(unset)";
530
+ return `${profile.role} = ${selector} :: ${profile.purpose}; ${profile.preference} preference; ${profile.requiresReasoning ? "reasoning required" : "reasoning optional"}; context >= ${profile.minContextWindow}${profile.preferDistinctFrom ? `; prefer distinct from ${profile.preferDistinctFrom}` : ""}`;
531
+ });
532
+ const baselineLines = input.baseline.assignments.map(assignment => `${assignment.role} = ${assignment.selector}`);
533
+ const missing = input.baseline.unavailable.map(item => `${item.role} (${item.reason})`);
534
+ return [
535
+ "Evaluate the Bizar model-role distribution for the current OMP catalog and apply it with the native tool `" + BIZAR_MODEL_ROLE_TOOL + "`.",
536
+ "This is a bounded evaluation: use only the catalog below, make no other settings or credential changes, and do not run further research.",
537
+ "",
538
+ "Rules",
539
+ `- Call \`${BIZAR_MODEL_ROLE_TOOL}\` exactly once with {"assignment":[{"role":"...","selector":"...","rationale":"..."}]} covering every Bizar role you consider resolved.`,
540
+ "- Use selectors exactly as listed in AVAILABLE MODELS; never invent or guess a selector.",
541
+ "- Treat metadata reported as unknown as unknown: never infer capability, cost or locality from a model name.",
542
+ "- Judge each role by purpose, reasoning need, context window, speed, cost and locality; keep provider diversity, and prefer a model distinct from the orchestrator for bizar_advisor.",
543
+ "- One short clause per rationale, no prose report.",
544
+ "",
545
+ "CATALOG CHANGES SINCE LAST OBSERVATION",
546
+ formatCatalogDelta(input.delta),
547
+ "",
548
+ `AVAILABLE MODELS (${input.models.length})`,
549
+ ...catalogLines,
550
+ "",
551
+ "CURRENT ROLE MAPPING (existing assignments are re-evaluated, not trusted)",
552
+ ...currentLines,
553
+ "",
554
+ "DETERMINISTIC BASELINE (override only with a concrete catalog reason)",
555
+ ...baselineLines,
556
+ ...(missing.length > 0 ? [`Unresolved by the baseline: ${missing.join(", ")}`] : []),
557
+ ].join("\n");
558
+ }
170
559
  //# sourceMappingURL=model-role-assignment.js.map