agent-bober 0.17.0 → 0.18.0

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 (364) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/CHANGELOG.md +25 -0
  4. package/README.md +169 -6
  5. package/dist/chat/answerer.d.ts +17 -0
  6. package/dist/chat/answerer.d.ts.map +1 -0
  7. package/dist/chat/answerer.js +52 -0
  8. package/dist/chat/answerer.js.map +1 -0
  9. package/dist/chat/approval-cursor.d.ts +25 -0
  10. package/dist/chat/approval-cursor.d.ts.map +1 -0
  11. package/dist/chat/approval-cursor.js +61 -0
  12. package/dist/chat/approval-cursor.js.map +1 -0
  13. package/dist/chat/approval-reader.d.ts +11 -0
  14. package/dist/chat/approval-reader.d.ts.map +1 -0
  15. package/dist/chat/approval-reader.js +20 -0
  16. package/dist/chat/approval-reader.js.map +1 -0
  17. package/dist/chat/careful-sidecar.d.ts +15 -0
  18. package/dist/chat/careful-sidecar.d.ts.map +1 -0
  19. package/dist/chat/careful-sidecar.js +39 -0
  20. package/dist/chat/careful-sidecar.js.map +1 -0
  21. package/dist/chat/chat-session.d.ts +129 -0
  22. package/dist/chat/chat-session.d.ts.map +1 -0
  23. package/dist/chat/chat-session.js +470 -0
  24. package/dist/chat/chat-session.js.map +1 -0
  25. package/dist/chat/completion-tailer.d.ts +27 -0
  26. package/dist/chat/completion-tailer.d.ts.map +1 -0
  27. package/dist/chat/completion-tailer.js +187 -0
  28. package/dist/chat/completion-tailer.js.map +1 -0
  29. package/dist/chat/conversation-store.d.ts +22 -0
  30. package/dist/chat/conversation-store.d.ts.map +1 -0
  31. package/dist/chat/conversation-store.js +66 -0
  32. package/dist/chat/conversation-store.js.map +1 -0
  33. package/dist/chat/cursor-store.d.ts +23 -0
  34. package/dist/chat/cursor-store.d.ts.map +1 -0
  35. package/dist/chat/cursor-store.js +42 -0
  36. package/dist/chat/cursor-store.js.map +1 -0
  37. package/dist/chat/pid-sidecar.d.ts +22 -0
  38. package/dist/chat/pid-sidecar.d.ts.map +1 -0
  39. package/dist/chat/pid-sidecar.js +42 -0
  40. package/dist/chat/pid-sidecar.js.map +1 -0
  41. package/dist/chat/roster-reader.d.ts +16 -0
  42. package/dist/chat/roster-reader.d.ts.map +1 -0
  43. package/dist/chat/roster-reader.js +39 -0
  44. package/dist/chat/roster-reader.js.map +1 -0
  45. package/dist/chat/run-spawner.d.ts +71 -0
  46. package/dist/chat/run-spawner.d.ts.map +1 -0
  47. package/dist/chat/run-spawner.js +121 -0
  48. package/dist/chat/run-spawner.js.map +1 -0
  49. package/dist/chat/slash-commands.d.ts +36 -0
  50. package/dist/chat/slash-commands.d.ts.map +1 -0
  51. package/dist/chat/slash-commands.js +133 -0
  52. package/dist/chat/slash-commands.js.map +1 -0
  53. package/dist/chat/steer-cleanup.d.ts +12 -0
  54. package/dist/chat/steer-cleanup.d.ts.map +1 -0
  55. package/dist/chat/steer-cleanup.js +60 -0
  56. package/dist/chat/steer-cleanup.js.map +1 -0
  57. package/dist/chat/turn-classifier.d.ts +43 -0
  58. package/dist/chat/turn-classifier.d.ts.map +1 -0
  59. package/dist/chat/turn-classifier.js +150 -0
  60. package/dist/chat/turn-classifier.js.map +1 -0
  61. package/dist/cli/commands/blackboard.d.ts +33 -0
  62. package/dist/cli/commands/blackboard.d.ts.map +1 -0
  63. package/dist/cli/commands/blackboard.js +114 -0
  64. package/dist/cli/commands/blackboard.js.map +1 -0
  65. package/dist/cli/commands/chat.d.ts +13 -0
  66. package/dist/cli/commands/chat.d.ts.map +1 -0
  67. package/dist/cli/commands/chat.js +43 -0
  68. package/dist/cli/commands/chat.js.map +1 -0
  69. package/dist/cli/commands/evolve.d.ts +18 -0
  70. package/dist/cli/commands/evolve.d.ts.map +1 -0
  71. package/dist/cli/commands/evolve.js +72 -0
  72. package/dist/cli/commands/evolve.js.map +1 -0
  73. package/dist/cli/commands/facts.d.ts +15 -0
  74. package/dist/cli/commands/facts.d.ts.map +1 -0
  75. package/dist/cli/commands/facts.js +213 -0
  76. package/dist/cli/commands/facts.js.map +1 -0
  77. package/dist/cli/commands/init.d.ts +9 -0
  78. package/dist/cli/commands/init.d.ts.map +1 -1
  79. package/dist/cli/commands/init.js +1 -1
  80. package/dist/cli/commands/init.js.map +1 -1
  81. package/dist/cli/commands/medical.d.ts +24 -0
  82. package/dist/cli/commands/medical.d.ts.map +1 -0
  83. package/dist/cli/commands/medical.js +132 -0
  84. package/dist/cli/commands/medical.js.map +1 -0
  85. package/dist/cli/commands/memory.d.ts +2 -1
  86. package/dist/cli/commands/memory.d.ts.map +1 -1
  87. package/dist/cli/commands/memory.js +94 -7
  88. package/dist/cli/commands/memory.js.map +1 -1
  89. package/dist/cli/commands/plan.d.ts.map +1 -1
  90. package/dist/cli/commands/plan.js +29 -3
  91. package/dist/cli/commands/plan.js.map +1 -1
  92. package/dist/cli/commands/replay.d.ts +17 -0
  93. package/dist/cli/commands/replay.d.ts.map +1 -0
  94. package/dist/cli/commands/replay.js +261 -0
  95. package/dist/cli/commands/replay.js.map +1 -0
  96. package/dist/cli/commands/run.d.ts +9 -0
  97. package/dist/cli/commands/run.d.ts.map +1 -1
  98. package/dist/cli/commands/run.js +27 -1
  99. package/dist/cli/commands/run.js.map +1 -1
  100. package/dist/cli/commands/sprint.d.ts.map +1 -1
  101. package/dist/cli/commands/sprint.js +17 -3
  102. package/dist/cli/commands/sprint.js.map +1 -1
  103. package/dist/cli/commands/update.d.ts +18 -0
  104. package/dist/cli/commands/update.d.ts.map +1 -0
  105. package/dist/cli/commands/update.js +81 -0
  106. package/dist/cli/commands/update.js.map +1 -0
  107. package/dist/cli/index.js +15 -0
  108. package/dist/cli/index.js.map +1 -1
  109. package/dist/config/defaults.d.ts.map +1 -1
  110. package/dist/config/defaults.js +8 -0
  111. package/dist/config/defaults.js.map +1 -1
  112. package/dist/config/role-providers.d.ts +1 -1
  113. package/dist/config/role-providers.d.ts.map +1 -1
  114. package/dist/config/role-providers.js +6 -1
  115. package/dist/config/role-providers.js.map +1 -1
  116. package/dist/config/schema.d.ts +467 -222
  117. package/dist/config/schema.d.ts.map +1 -1
  118. package/dist/config/schema.js +25 -0
  119. package/dist/config/schema.js.map +1 -1
  120. package/dist/contracts/eval-result.d.ts +84 -84
  121. package/dist/contracts/spec.d.ts +28 -28
  122. package/dist/contracts/sprint-contract.d.ts +4 -4
  123. package/dist/fleet/critic-deep.d.ts +53 -0
  124. package/dist/fleet/critic-deep.d.ts.map +1 -0
  125. package/dist/fleet/critic-deep.js +199 -0
  126. package/dist/fleet/critic-deep.js.map +1 -0
  127. package/dist/fleet/decomposer-deep-constants.d.ts +4 -0
  128. package/dist/fleet/decomposer-deep-constants.d.ts.map +1 -0
  129. package/dist/fleet/decomposer-deep-constants.js +14 -0
  130. package/dist/fleet/decomposer-deep-constants.js.map +1 -0
  131. package/dist/fleet/decomposer-deep-types.d.ts +8 -0
  132. package/dist/fleet/decomposer-deep-types.d.ts.map +1 -0
  133. package/dist/fleet/decomposer-deep-types.js +9 -0
  134. package/dist/fleet/decomposer-deep-types.js.map +1 -0
  135. package/dist/fleet/decomposer-deep.d.ts +51 -0
  136. package/dist/fleet/decomposer-deep.d.ts.map +1 -0
  137. package/dist/fleet/decomposer-deep.js +261 -0
  138. package/dist/fleet/decomposer-deep.js.map +1 -0
  139. package/dist/fleet/decomposer.d.ts +22 -0
  140. package/dist/fleet/decomposer.d.ts.map +1 -0
  141. package/dist/fleet/decomposer.js +144 -0
  142. package/dist/fleet/decomposer.js.map +1 -0
  143. package/dist/fleet/index.d.ts +93 -0
  144. package/dist/fleet/index.d.ts.map +1 -1
  145. package/dist/fleet/index.js +230 -2
  146. package/dist/fleet/index.js.map +1 -1
  147. package/dist/fleet/manifest-write.d.ts +30 -0
  148. package/dist/fleet/manifest-write.d.ts.map +1 -0
  149. package/dist/fleet/manifest-write.js +90 -0
  150. package/dist/fleet/manifest-write.js.map +1 -0
  151. package/dist/fleet/manifest.d.ts +6 -6
  152. package/dist/fleet/shared-blackboard.d.ts +51 -0
  153. package/dist/fleet/shared-blackboard.d.ts.map +1 -0
  154. package/dist/fleet/shared-blackboard.js +79 -0
  155. package/dist/fleet/shared-blackboard.js.map +1 -0
  156. package/dist/fleet/synthesis.d.ts +16 -0
  157. package/dist/fleet/synthesis.d.ts.map +1 -0
  158. package/dist/fleet/synthesis.js +22 -0
  159. package/dist/fleet/synthesis.js.map +1 -0
  160. package/dist/fleet/tier-policy.d.ts +18 -0
  161. package/dist/fleet/tier-policy.d.ts.map +1 -0
  162. package/dist/fleet/tier-policy.js +53 -0
  163. package/dist/fleet/tier-policy.js.map +1 -0
  164. package/dist/fleet/tool-role-guard.d.ts +24 -0
  165. package/dist/fleet/tool-role-guard.d.ts.map +1 -0
  166. package/dist/fleet/tool-role-guard.js +55 -0
  167. package/dist/fleet/tool-role-guard.js.map +1 -0
  168. package/dist/incident/resolution-verify.d.ts +4 -4
  169. package/dist/incident/types.d.ts +8 -8
  170. package/dist/mcp/run-manager.d.ts +9 -1
  171. package/dist/mcp/run-manager.d.ts.map +1 -1
  172. package/dist/mcp/run-manager.js.map +1 -1
  173. package/dist/medical/adapters/apple-health.d.ts +32 -0
  174. package/dist/medical/adapters/apple-health.d.ts.map +1 -0
  175. package/dist/medical/adapters/apple-health.js +100 -0
  176. package/dist/medical/adapters/apple-health.js.map +1 -0
  177. package/dist/medical/audit.d.ts +31 -0
  178. package/dist/medical/audit.d.ts.map +1 -0
  179. package/dist/medical/audit.js +56 -0
  180. package/dist/medical/audit.js.map +1 -0
  181. package/dist/medical/consent.d.ts +37 -0
  182. package/dist/medical/consent.d.ts.map +1 -0
  183. package/dist/medical/consent.js +73 -0
  184. package/dist/medical/consent.js.map +1 -0
  185. package/dist/medical/disclaimer.d.ts +11 -0
  186. package/dist/medical/disclaimer.d.ts.map +1 -0
  187. package/dist/medical/disclaimer.js +21 -0
  188. package/dist/medical/disclaimer.js.map +1 -0
  189. package/dist/medical/egress.d.ts +30 -0
  190. package/dist/medical/egress.d.ts.map +1 -0
  191. package/dist/medical/egress.js +50 -0
  192. package/dist/medical/egress.js.map +1 -0
  193. package/dist/medical/engine.d.ts +73 -0
  194. package/dist/medical/engine.d.ts.map +1 -0
  195. package/dist/medical/engine.js +333 -0
  196. package/dist/medical/engine.js.map +1 -0
  197. package/dist/medical/guardrails.d.ts +47 -0
  198. package/dist/medical/guardrails.d.ts.map +1 -0
  199. package/dist/medical/guardrails.js +92 -0
  200. package/dist/medical/guardrails.js.map +1 -0
  201. package/dist/medical/health-store.d.ts +80 -0
  202. package/dist/medical/health-store.d.ts.map +1 -0
  203. package/dist/medical/health-store.js +204 -0
  204. package/dist/medical/health-store.js.map +1 -0
  205. package/dist/medical/inference.d.ts +22 -0
  206. package/dist/medical/inference.d.ts.map +1 -0
  207. package/dist/medical/inference.js +39 -0
  208. package/dist/medical/inference.js.map +1 -0
  209. package/dist/medical/ingestion.d.ts +33 -0
  210. package/dist/medical/ingestion.d.ts.map +1 -0
  211. package/dist/medical/ingestion.js +52 -0
  212. package/dist/medical/ingestion.js.map +1 -0
  213. package/dist/medical/numerics.d.ts +66 -0
  214. package/dist/medical/numerics.d.ts.map +1 -0
  215. package/dist/medical/numerics.js +216 -0
  216. package/dist/medical/numerics.js.map +1 -0
  217. package/dist/medical/red-flag.d.ts +42 -0
  218. package/dist/medical/red-flag.d.ts.map +1 -0
  219. package/dist/medical/red-flag.js +161 -0
  220. package/dist/medical/red-flag.js.map +1 -0
  221. package/dist/medical/refusal.d.ts +46 -0
  222. package/dist/medical/refusal.d.ts.map +1 -0
  223. package/dist/medical/refusal.js +131 -0
  224. package/dist/medical/refusal.js.map +1 -0
  225. package/dist/medical/retrieval/grounding-critic.d.ts +34 -0
  226. package/dist/medical/retrieval/grounding-critic.d.ts.map +1 -0
  227. package/dist/medical/retrieval/grounding-critic.js +153 -0
  228. package/dist/medical/retrieval/grounding-critic.js.map +1 -0
  229. package/dist/medical/retrieval/literature.d.ts +78 -0
  230. package/dist/medical/retrieval/literature.d.ts.map +1 -0
  231. package/dist/medical/retrieval/literature.js +292 -0
  232. package/dist/medical/retrieval/literature.js.map +1 -0
  233. package/dist/medical/retrieval/medline-source.d.ts +72 -0
  234. package/dist/medical/retrieval/medline-source.d.ts.map +1 -0
  235. package/dist/medical/retrieval/medline-source.js +120 -0
  236. package/dist/medical/retrieval/medline-source.js.map +1 -0
  237. package/dist/medical/team.d.ts +15 -0
  238. package/dist/medical/team.d.ts.map +1 -0
  239. package/dist/medical/team.js +44 -0
  240. package/dist/medical/team.js.map +1 -0
  241. package/dist/medical/types.d.ts +175 -0
  242. package/dist/medical/types.d.ts.map +1 -0
  243. package/dist/medical/types.js +8 -0
  244. package/dist/medical/types.js.map +1 -0
  245. package/dist/medical/whoop/whoop-client.d.ts +114 -0
  246. package/dist/medical/whoop/whoop-client.d.ts.map +1 -0
  247. package/dist/medical/whoop/whoop-client.js +226 -0
  248. package/dist/medical/whoop/whoop-client.js.map +1 -0
  249. package/dist/medical/whoop/whoop-sync.d.ts +25 -0
  250. package/dist/medical/whoop/whoop-sync.d.ts.map +1 -0
  251. package/dist/medical/whoop/whoop-sync.js +97 -0
  252. package/dist/medical/whoop/whoop-sync.js.map +1 -0
  253. package/dist/medical/whoop/whoop-token.d.ts +44 -0
  254. package/dist/medical/whoop/whoop-token.d.ts.map +1 -0
  255. package/dist/medical/whoop/whoop-token.js +66 -0
  256. package/dist/medical/whoop/whoop-token.js.map +1 -0
  257. package/dist/orchestrator/context-handoff.d.ts +60 -60
  258. package/dist/orchestrator/contract-materialization.d.ts +33 -0
  259. package/dist/orchestrator/contract-materialization.d.ts.map +1 -0
  260. package/dist/orchestrator/contract-materialization.js +113 -0
  261. package/dist/orchestrator/contract-materialization.js.map +1 -0
  262. package/dist/orchestrator/memory/distill.d.ts +4 -1
  263. package/dist/orchestrator/memory/distill.d.ts.map +1 -1
  264. package/dist/orchestrator/memory/distill.js +41 -1
  265. package/dist/orchestrator/memory/distill.js.map +1 -1
  266. package/dist/orchestrator/memory/fact-detector.d.ts +61 -0
  267. package/dist/orchestrator/memory/fact-detector.d.ts.map +1 -0
  268. package/dist/orchestrator/memory/fact-detector.js +153 -0
  269. package/dist/orchestrator/memory/fact-detector.js.map +1 -0
  270. package/dist/orchestrator/memory/fact-judge.d.ts +19 -0
  271. package/dist/orchestrator/memory/fact-judge.d.ts.map +1 -0
  272. package/dist/orchestrator/memory/fact-judge.js +121 -0
  273. package/dist/orchestrator/memory/fact-judge.js.map +1 -0
  274. package/dist/orchestrator/memory/fact-retrieve.d.ts +52 -0
  275. package/dist/orchestrator/memory/fact-retrieve.d.ts.map +1 -0
  276. package/dist/orchestrator/memory/fact-retrieve.js +117 -0
  277. package/dist/orchestrator/memory/fact-retrieve.js.map +1 -0
  278. package/dist/orchestrator/memory/hygiene.d.ts +66 -0
  279. package/dist/orchestrator/memory/hygiene.d.ts.map +1 -0
  280. package/dist/orchestrator/memory/hygiene.js +153 -0
  281. package/dist/orchestrator/memory/hygiene.js.map +1 -0
  282. package/dist/orchestrator/memory/reconcile.d.ts +47 -0
  283. package/dist/orchestrator/memory/reconcile.d.ts.map +1 -0
  284. package/dist/orchestrator/memory/reconcile.js +116 -0
  285. package/dist/orchestrator/memory/reconcile.js.map +1 -0
  286. package/dist/orchestrator/memory/retrieve.d.ts +5 -3
  287. package/dist/orchestrator/memory/retrieve.d.ts.map +1 -1
  288. package/dist/orchestrator/memory/retrieve.js +9 -6
  289. package/dist/orchestrator/memory/retrieve.js.map +1 -1
  290. package/dist/orchestrator/pipeline.d.ts +19 -3
  291. package/dist/orchestrator/pipeline.d.ts.map +1 -1
  292. package/dist/orchestrator/pipeline.js +63 -52
  293. package/dist/orchestrator/pipeline.js.map +1 -1
  294. package/dist/orchestrator/planner-agent.d.ts.map +1 -1
  295. package/dist/orchestrator/planner-agent.js +16 -1
  296. package/dist/orchestrator/planner-agent.js.map +1 -1
  297. package/dist/orchestrator/selfimprove/eval-guards.d.ts +51 -0
  298. package/dist/orchestrator/selfimprove/eval-guards.d.ts.map +1 -0
  299. package/dist/orchestrator/selfimprove/eval-guards.js +120 -0
  300. package/dist/orchestrator/selfimprove/eval-guards.js.map +1 -0
  301. package/dist/orchestrator/selfimprove/gepa.d.ts +74 -0
  302. package/dist/orchestrator/selfimprove/gepa.d.ts.map +1 -0
  303. package/dist/orchestrator/selfimprove/gepa.js +227 -0
  304. package/dist/orchestrator/selfimprove/gepa.js.map +1 -0
  305. package/dist/orchestrator/selfimprove/replay-harness.d.ts +65 -0
  306. package/dist/orchestrator/selfimprove/replay-harness.d.ts.map +1 -0
  307. package/dist/orchestrator/selfimprove/replay-harness.js +134 -0
  308. package/dist/orchestrator/selfimprove/replay-harness.js.map +1 -0
  309. package/dist/orchestrator/selfimprove/replay-store.d.ts +45 -0
  310. package/dist/orchestrator/selfimprove/replay-store.d.ts.map +1 -0
  311. package/dist/orchestrator/selfimprove/replay-store.js +119 -0
  312. package/dist/orchestrator/selfimprove/replay-store.js.map +1 -0
  313. package/dist/orchestrator/selfimprove/replay-types.d.ts +32 -0
  314. package/dist/orchestrator/selfimprove/replay-types.d.ts.map +1 -0
  315. package/dist/orchestrator/selfimprove/replay-types.js +15 -0
  316. package/dist/orchestrator/selfimprove/replay-types.js.map +1 -0
  317. package/dist/orchestrator/workflow/engine.d.ts +3 -1
  318. package/dist/orchestrator/workflow/engine.d.ts.map +1 -1
  319. package/dist/orchestrator/workflow/selector.d.ts +18 -0
  320. package/dist/orchestrator/workflow/selector.d.ts.map +1 -1
  321. package/dist/orchestrator/workflow/selector.js +41 -0
  322. package/dist/orchestrator/workflow/selector.js.map +1 -1
  323. package/dist/orchestrator/workflow/ts-engine.d.ts +3 -1
  324. package/dist/orchestrator/workflow/ts-engine.d.ts.map +1 -1
  325. package/dist/orchestrator/workflow/ts-engine.js +2 -2
  326. package/dist/orchestrator/workflow/ts-engine.js.map +1 -1
  327. package/dist/orchestrator/workflow/workflow-engine.d.ts +3 -1
  328. package/dist/orchestrator/workflow/workflow-engine.d.ts.map +1 -1
  329. package/dist/orchestrator/workflow/workflow-engine.js +3 -3
  330. package/dist/orchestrator/workflow/workflow-engine.js.map +1 -1
  331. package/dist/state/facts.d.ts +110 -0
  332. package/dist/state/facts.d.ts.map +1 -0
  333. package/dist/state/facts.js +208 -0
  334. package/dist/state/facts.js.map +1 -0
  335. package/dist/state/guidance.d.ts +37 -0
  336. package/dist/state/guidance.d.ts.map +1 -0
  337. package/dist/state/guidance.js +144 -0
  338. package/dist/state/guidance.js.map +1 -0
  339. package/dist/state/history.d.ts +2 -2
  340. package/dist/state/index.d.ts +1 -1
  341. package/dist/state/index.d.ts.map +1 -1
  342. package/dist/state/index.js +1 -1
  343. package/dist/state/index.js.map +1 -1
  344. package/dist/state/memory.d.ts +43 -11
  345. package/dist/state/memory.d.ts.map +1 -1
  346. package/dist/state/memory.js +93 -15
  347. package/dist/state/memory.js.map +1 -1
  348. package/dist/state/pause.d.ts +47 -0
  349. package/dist/state/pause.d.ts.map +1 -0
  350. package/dist/state/pause.js +146 -0
  351. package/dist/state/pause.js.map +1 -0
  352. package/dist/state/sprint-state.d.ts +8 -0
  353. package/dist/state/sprint-state.d.ts.map +1 -1
  354. package/dist/state/sprint-state.js +32 -1
  355. package/dist/state/sprint-state.js.map +1 -1
  356. package/dist/teams/registry.d.ts +16 -0
  357. package/dist/teams/registry.d.ts.map +1 -0
  358. package/dist/teams/registry.js +53 -0
  359. package/dist/teams/registry.js.map +1 -0
  360. package/dist/teams/types.d.ts +25 -0
  361. package/dist/teams/types.d.ts.map +1 -0
  362. package/dist/teams/types.js +2 -0
  363. package/dist/teams/types.js.map +1 -0
  364. package/package.json +3 -1
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://anthropic.com/claude-code/marketplace.schema.json",
3
3
  "name": "agent-bober",
4
- "description": "Marketplace for the Bober multi-agent harness — installs the bober plugin (24 skills + 10 subagents) so updates propagate via `/plugin update` instead of per-project copies.",
4
+ "description": "Marketplace for the Bober multi-agent harness — installs the bober plugin (24 skills + 11 subagents) so updates propagate via `/plugin update` instead of per-project copies.",
5
5
  "owner": {
6
6
  "name": "BOBER3r"
7
7
  },
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "bober",
3
3
  "description": "Generator-Evaluator multi-agent harness for building applications autonomously with Claude",
4
- "version": "0.15.0",
4
+ "version": "0.18.0",
5
5
  "author": { "name": "BOBER3r" },
6
6
  "homepage": "https://agentbober.com",
7
7
  "repository": "https://github.com/BOBER3r/agent-bober",
package/CHANGELOG.md CHANGED
@@ -7,6 +7,31 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.18.0] — 2026-06-23
11
+
12
+ ### Fixed
13
+
14
+ - **Standalone `plan` → `sprint` flow**: `plan` now materializes sprint contracts to `.bober/contracts/` after planning. Previously only the `run` pipeline did this, so a standalone `plan` followed by `sprint` failed with "No sprint contracts found." `plan answer` likewise materializes contracts when it resolves a spec to `ready`, and the next-step hints now correctly point to `npx agent-bober sprint`.
15
+
16
+ ### Added
17
+
18
+ - **Shared `materializeContracts` helper** (`src/orchestrator/contract-materialization.ts`) used by both `plan` and the `run` pipeline as the single source of truth for spec → contract materialization. It prefers valid embedded `spec.sprints[]` (e.g. planner-authored contracts), falling back to feature-derived generation when they are absent or invalid. Contract ids are now deterministic and zero-padded (`sprint-<specId>-NN`) so `listContracts` ordering matches execution order at ten or more sprints.
19
+ - **`run` honors embedded `spec.sprints[]`**: when the planner emits valid embedded contracts, `run` uses them and skips the per-feature precision LLM calls.
20
+
21
+ ### Changed
22
+
23
+ - **`sprint` scopes to the active spec**: contract selection is now filtered to the latest spec's `specId`, so stale contracts from other specs are not executed. `sprint` also refuses a `needs-clarification` spec (printing the open questions and the correct `plan answer` command) and gives a clearer empty-contracts message pointing at `plan` or `run`.
24
+
25
+ ## [0.17.1] — 2026-06-13
26
+
27
+ ### Added
28
+
29
+ - **`agent-bober update` command**: refreshes a project's installed Claude Code slash commands (`.claude/commands/`) and agent definitions (`.claude/agents/`) from the currently-installed package — the end-user upgrade path after `npm i -g agent-bober@latest`. It respects the project's recorded `mode`/`preset` so the installed command set matches what `init` chose, and it is **non-destructive**: `bober.config.json`, `.bober/` state, and `.gitignore` are never touched. Errors out (exit 1) if no `bober.config.json` is present.
30
+
31
+ ### Fixed
32
+
33
+ - **Plugin manifest version drift**: `.claude-plugin/plugin.json` was pinned at `0.15.0` and the marketplace/README advertised "10 subagents"; both now track the real release (`0.17.x`, 11 subagents) so `/plugin update bober` advertises the correct version.
34
+
10
35
  ## [0.17.0] — 2026-06-13
11
36
 
12
37
  ### Added
package/README.md CHANGED
@@ -80,7 +80,7 @@ Install the plugin from its marketplace, then install `bober`:
80
80
  /plugin install bober@agent-bober
81
81
  ```
82
82
 
83
- This installs 24 skills + 10 subagents. Update later with `/plugin update bober`. The plugin runs the Researcher → Planner → Curator → Generator → Evaluator pipeline as Claude Code subagents on your Claude subscription — provider selection (the [Capability Matrix](#capability-matrix)) does **not** apply in this mode.
83
+ This installs 24 skills + 11 subagents. Update later with `/plugin update bober`. The plugin runs the Researcher → Planner → Curator → Generator → Evaluator pipeline as Claude Code subagents on your Claude subscription — provider selection (the [Capability Matrix](#capability-matrix)) does **not** apply in this mode.
84
84
 
85
85
  ### npm CLI / MCP Server
86
86
 
@@ -92,6 +92,15 @@ npm install -g agent-bober
92
92
  npx agent-bober init
93
93
  ```
94
94
 
95
+ **Updating later:** upgrade the package, then refresh each project's installed commands/agents:
96
+
97
+ ```bash
98
+ npm i -g agent-bober@latest # upgrade the global CLI/engine
99
+ agent-bober update # in each project: refresh .claude/ commands + agents (config untouched)
100
+ ```
101
+
102
+ `update` re-emits `.claude/commands/` and `.claude/agents/` from the new package version without touching your `bober.config.json` or `.bober/` state. Claude Code **plugin** users update separately with `/plugin update bober` (the plugin tracks the GitHub repo, not npm).
103
+
95
104
  This is required to use the DeepSeek / claude-code providers, run bober headlessly or in CI, or expose the MCP server. A few plugin skills (`bober.plan`, `bober.sprint`, `bober.impact`, `bober.onboard`, `bober.graph`) also shell out to the `agent-bober` CLI, so installing it unlocks their full behavior. Graph features additionally require the separate [`tokensave`](#graph-tokensave-integration) binary.
96
105
 
97
106
  agent-bober works in multiple environments:
@@ -202,15 +211,27 @@ agent-bober is **provider-agnostic**. Use any LLM provider for any agent role. M
202
211
 
203
212
  ### Supported Providers
204
213
 
205
- | Provider | Shorthands | API Key |
214
+ | Provider | Shorthands | API Key (env var) |
206
215
  |----------|-----------|---------|
207
216
  | **Anthropic** (default) | `opus`, `sonnet`, `haiku` | `ANTHROPIC_API_KEY` |
217
+ | **DeepSeek** | `deepseek`, `deepseek-v4-pro`, `deepseek-v4-flash` | `DEEPSEEK_API_KEY` |
208
218
  | **OpenAI** | Any OpenAI model ID | `OPENAI_API_KEY` |
209
219
  | **Google Gemini** | `gemini-pro`, `gemini-flash` | `GOOGLE_API_KEY` or `GEMINI_API_KEY` |
210
- | **OpenAI-Compatible** | Any model (Ollama, LM Studio, Groq, DeepSeek, etc.) | Optional |
220
+ | **OpenAI-Compatible** | Any model (Ollama, LM Studio, Groq, custom endpoints) | Optional (none for local servers) |
211
221
 
212
222
  Shorthands resolve to the latest model version automatically. You can also pass any full model ID directly -- it will be sent to the provider as-is.
213
223
 
224
+ > **Which API key do I need? (read this first)**
225
+ >
226
+ > **The default is Anthropic, so `ANTHROPIC_API_KEY` on its own means every role calls Claude — nothing else.** Setting `ANTHROPIC_API_KEY` does **not** turn on DeepSeek. Provider selection is **config-driven, not key-driven**: a key is only used if a role is actually pointed at that provider.
227
+ >
228
+ > To use **DeepSeek** you need **three** things together:
229
+ > 1. `npm install openai` — the OpenAI SDK is the OpenAI-compatible client DeepSeek runs through (an optional peer dependency).
230
+ > 2. `export DEEPSEEK_API_KEY=sk-...` — get a key at <https://platform.deepseek.com>. (`ANTHROPIC_API_KEY` is **not** needed if no role uses Anthropic.)
231
+ > 3. Point one or more roles at DeepSeek in `bober.config.json` — see [DeepSeek setup (full example)](#deepseek-setup-full-example) below.
232
+ >
233
+ > DeepSeek is **not** reachable with the `--provider` CLI flag alone (that flag only swaps the provider name; DeepSeek also needs its model + endpoint) — configure it in `bober.config.json`.
234
+
214
235
  ### Capability Matrix
215
236
 
216
237
  > **This matrix applies to the standalone CLI / programmatic provider layer only** (`npx agent-bober run …`), where bober calls each provider's API directly. It does **not** apply to the **Claude Code plugin**: when you run a skill like `/bober-run` inside Claude Code, the roles are spawned as Claude Code subagents on your Claude subscription, so provider selection (including `claude-code`) does not apply. See [Claude Code Plugin](#claude-code-plugin) below.
@@ -237,6 +258,65 @@ Each `claude -p` call injects approximately **40,000 tokens of system-prompt ove
237
258
 
238
259
  See [`docs/providers.md`](docs/providers.md) for copy-paste config snippets for each provider.
239
260
 
261
+ ### DeepSeek setup (full example)
262
+
263
+ DeepSeek runs through the built-in OpenAI-compatible adapter pointed at `https://api.deepseek.com`. End-to-end:
264
+
265
+ **1. Install the OpenAI-compatible client** (one-time):
266
+
267
+ ```bash
268
+ npm install openai
269
+ ```
270
+
271
+ **2. Export your DeepSeek key** (get one at <https://platform.deepseek.com>):
272
+
273
+ ```bash
274
+ export DEEPSEEK_API_KEY=sk-...
275
+ ```
276
+
277
+ **3a. Configure roles — shorthand (simplest).** Set only the `model`; the provider (`openai-compat`) and the `https://api.deepseek.com` endpoint are inferred automatically:
278
+
279
+ ```jsonc
280
+ // bober.config.json — DeepSeek for every role
281
+ {
282
+ "planner": { "model": "deepseek-v4-pro" },
283
+ "researcher": { "model": "deepseek-v4-flash" },
284
+ "curator": { "model": "deepseek-v4-pro" },
285
+ "generator": { "model": "deepseek-v4-pro" },
286
+ "evaluator": { "model": "deepseek-v4-flash" }
287
+ }
288
+ ```
289
+
290
+ **3b. Configure roles — explicit (equivalent).** Spell out the provider and endpoint if you prefer — also the form to use for a self-hosted DeepSeek-compatible gateway:
291
+
292
+ ```jsonc
293
+ {
294
+ "generator": {
295
+ "provider": "openai-compat",
296
+ "model": "deepseek-v4-pro",
297
+ "endpoint": "https://api.deepseek.com"
298
+ }
299
+ }
300
+ ```
301
+
302
+ **4. Run:**
303
+
304
+ ```bash
305
+ agent-bober run "Build a REST API with auth and CRUD"
306
+ ```
307
+
308
+ > Use `"provider": "openai-compat"` (as in 3b), **not** `"provider": "deepseek"` — `deepseek` is a *model* shorthand, not a provider name, so `"provider": "deepseek"` is rejected as an unsupported provider.
309
+
310
+ **Mix providers** — e.g. plan on Claude (highest quality) and generate/evaluate on DeepSeek (cheaper). You then need **both** `ANTHROPIC_API_KEY` and `DEEPSEEK_API_KEY` in your environment:
311
+
312
+ ```jsonc
313
+ {
314
+ "planner": { "model": "opus" },
315
+ "generator": { "model": "deepseek-v4-pro" },
316
+ "evaluator": { "model": "deepseek-v4-flash" }
317
+ }
318
+ ```
319
+
240
320
  ### Configuration
241
321
 
242
322
  Set providers per agent role in `bober.config.json`:
@@ -427,15 +507,40 @@ The `/bober-principles` command also triggers auto-discovery when called with no
427
507
 
428
508
  ```bash
429
509
  npx agent-bober init [preset] # Initialize project (with provider selection)
430
- npx agent-bober plan "feature" # Run the planner
510
+ npx agent-bober update # Refresh .claude/ commands + agents after upgrading the package
511
+ npx agent-bober plan "feature" # Run the planner (also materializes sprint contracts)
431
512
  npx agent-bober plan answer <specId> # Resolve clarification questions interactively
432
513
  npx agent-bober plan answer <specId> <questionId> "..." # Resolve a single clarification question
433
- npx agent-bober sprint # Execute next sprint
514
+ npx agent-bober sprint # Execute next sprint (consumes plan's contracts)
434
515
  npx agent-bober eval # Evaluate current sprint
435
516
  npx agent-bober run "feature" # Full autonomous loop
517
+ npx agent-bober run "feature" --team example # Full autonomous loop using the 'example' team
518
+ npx agent-bober chat # Interactive chat REPL (roster + memory aware)
519
+ npx agent-bober chat example # Interactive chat REPL using the 'example' team
436
520
  npx agent-bober mcp # Start MCP server (Cursor/Windsurf)
437
521
  ```
438
522
 
523
+ #### Chat Steer Commands (Phase 2 — mid-flight HITL)
524
+
525
+ Inside the `bober chat` REPL you can steer in-flight runs with these commands:
526
+
527
+ | Command | Description |
528
+ |---|---|
529
+ | `/careful [on\|off]` | Toggle approval gates for new runs. When ON, new runs spawn with `--approve-gates post-research,post-plan,post-sprint` and pause at each curated gate waiting for human input. |
530
+ | `/approve <checkpointId>` | Approve a pending checkpoint (e.g. `post-plan`, `post-sprint`) and resume the run. |
531
+ | `/reject <checkpointId> [feedback]` | Reject a pending checkpoint with optional feedback for the run to use on retry. |
532
+ | `/tell <runId> <text>` | Queue free-text guidance for a run — applied at the next pipeline boundary. |
533
+ | `/pause <runId>` | Soft-pause a run at the next cooperative boundary. The process stays alive. |
534
+ | `/resume <runId>` | Resume a soft-paused run. |
535
+ | `/stop <runId>` | Hard-stop a run by killing its process (contrast with `/pause` which is cooperative). |
536
+ | `/runs` | List all active and recent runs. |
537
+ | `/help` | Show the full command list. |
538
+ | `/exit` | Exit the chat session. |
539
+
540
+ **Curated gates** (triggered by `--approve-gates`): `post-research`, `post-plan`, `post-sprint`. Each gate pauses the run and surfaces a notice in the next chat turn. Use `/approve` or `/reject` to resolve.
541
+
542
+ **Limitation:** Only one careful run at a time is fully supported. Pending markers are checkpointId-keyed in a shared `.bober/approvals/` directory, so two concurrent careful runs that hit the same gate id would collide. The non-chat equivalents (`list-approvals`, `approve`, `reject`) remain available as fallback. See `docs/chat-steer.md` for the full model and the documented limitations.
543
+
439
544
  #### New Commands (Sprints 9–25)
440
545
 
441
546
  The following commands were added after the initial release. Full reference in [COMMANDS.md](./COMMANDS.md).
@@ -471,7 +576,7 @@ npx agent-bober playbook search '<symptom>' # Search by symptom
471
576
 
472
577
  #### Clarification gating
473
578
 
474
- When the planner can't fully decompose a feature without more information, it stops with `status: "needs-clarification"` instead of fabricating sprints. The CLI surfaces the open questions and you resolve them via `plan answer`. After the last question is answered the spec auto-promotes to `status: "ready"` and the next `sprint`/`run` proceeds. See the **Architecture** section for the full lifecycle.
579
+ When the planner can't fully decompose a feature without more information, it stops with `status: "needs-clarification"` instead of fabricating sprints — and writes **no** contracts. The CLI surfaces the open questions and you resolve them via `plan answer`. After the last question is answered the spec auto-promotes to `status: "ready"`, its sprint contracts are materialized into `.bober/contracts/`, and the next `sprint`/`run` proceeds. See the **Architecture** section for the full lifecycle.
475
580
 
476
581
  ### Fully Autonomous Mode (no human in the loop)
477
582
 
@@ -509,6 +614,17 @@ agent-bober init nextjs
509
614
  agent-bober run "Build a complete dashboard with auth, CRUD, and charts" --provider openai
510
615
  ```
511
616
 
617
+ For **DeepSeek**, set `DEEPSEEK_API_KEY` and point your roles at the `deepseek` model in `bober.config.json` — the `--provider` flag alone is not enough, since DeepSeek also needs its model + endpoint (see [DeepSeek setup (full example)](#deepseek-setup-full-example)):
618
+
619
+ ```bash
620
+ npm install openai
621
+ export DEEPSEEK_API_KEY=sk-...
622
+ cd your-project
623
+ agent-bober init nextjs
624
+ # in bober.config.json set "model": "deepseek-v4-pro" on the roles you want
625
+ agent-bober run "Build a complete dashboard with auth, CRUD, and charts"
626
+ ```
627
+
512
628
  ---
513
629
 
514
630
  ## Lens Panels (multi-perspective evaluation & architecture)
@@ -537,6 +653,38 @@ Leave `lenses` empty to use the full built-in set; `maxConcurrent` bounds how ma
537
653
 
538
654
  ---
539
655
 
656
+ ## Teams
657
+
658
+ agent-bober supports domain-agnostic **teams** — named configurations that route each run or chat session to a distinct set of providers, a separate memory namespace, and a chosen pipeline shape. **Adding a team is data, not code**: declare it in `bober.config.json`, no source changes required.
659
+
660
+ ```jsonc
661
+ {
662
+ "defaultTeam": "programming", // Active team when --team / chat <team> is omitted
663
+ "teams": {
664
+ "example": {
665
+ "displayName": "Example research team",
666
+ "memoryNamespace": "example", // Lessons land in .bober/memory/example/
667
+ "pipelineShape": "ts",
668
+ "providers": { "chat": "openai" }
669
+ }
670
+ }
671
+ }
672
+ ```
673
+
674
+ ```bash
675
+ npx agent-bober run "summarise research" --team example
676
+ npx agent-bober chat example
677
+ ```
678
+
679
+ The built-in **programming** team is always available (no config entry needed) and uses
680
+ the default `.bober/memory/` path and the project's configured providers.
681
+
682
+ For full documentation on the three differentiation axes (provider routing / memory
683
+ namespace / pipeline shape), the built-in programming team, and the deferred
684
+ `.bober/teams/*.json` file registry, see [docs/teams.md](./docs/teams.md).
685
+
686
+ ---
687
+
540
688
  ## Configuration
541
689
 
542
690
  All configuration lives in `bober.config.json` at your project root. The `init` command creates this file from a template, and you can customize it afterward.
@@ -652,6 +800,17 @@ All configuration lives in `bober.config.json` at your project root. The `init`
652
800
  "lint": "npm run lint",
653
801
  "dev": "npm run dev",
654
802
  "typecheck": "npx tsc --noEmit"
803
+ },
804
+
805
+ // -- Teams (NEW: adding a team is data, not code) ----
806
+ "defaultTeam": "programming", // Optional. Active team when --team / chat <team> is omitted.
807
+ "teams": { // Optional. Each entry is a team defined purely as DATA.
808
+ "example": {
809
+ "displayName": "Example research team",
810
+ "memoryNamespace": "example", // Lessons land in .bober/memory/example/
811
+ "pipelineShape": "ts", // "ts" | "skill" | "workflow"
812
+ "providers": { "chat": "openai" } // Partial role->provider override; unset roles keep defaults
813
+ }
655
814
  }
656
815
  }
657
816
  ```
@@ -947,6 +1106,10 @@ All bober state lives in the `.bober/` directory:
947
1106
  briefings/ Sprint Briefings (curated codebase context per sprint)
948
1107
  eval-results/ Evaluation result logs
949
1108
  handoffs/ Context handoff documents
1109
+ memory/ Self-improvement memory (per-team namespaced)
1110
+ INDEX.md Distilled lessons index (planner-read)
1111
+ QUARANTINE.md Pruned/contradictory lessons (moved, never deleted)
1112
+ facts.db Bi-temporal SQLite semantic-facts store (auto-produced, planner-read)
950
1113
  progress.md Human-readable progress tracker
951
1114
  history.jsonl Machine-readable event log
952
1115
  ```
@@ -0,0 +1,17 @@
1
+ import type { LLMClient } from "../providers/types.js";
2
+ import type { TurnRecord } from "./conversation-store.js";
3
+ export declare class Answerer {
4
+ private readonly llm;
5
+ private readonly model;
6
+ constructor(llm: LLMClient, model: string);
7
+ /**
8
+ * Produce an answer to the user's input, given context.
9
+ *
10
+ * @param input - The current user message.
11
+ * @param rosterSummary - Compact string summary of active runs.
12
+ * @param memoryDistill - Compact string of lessons from .bober/memory/.
13
+ * @param recentHistory - Recent prior turns for conversation context.
14
+ */
15
+ answer(input: string, rosterSummary: string, memoryDistill: string, recentHistory: TurnRecord[]): Promise<string>;
16
+ }
17
+ //# sourceMappingURL=answerer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"answerer.d.ts","sourceRoot":"","sources":["../../src/chat/answerer.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,SAAS,EAAe,MAAM,uBAAuB,CAAC;AACpE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAI1D,qBAAa,QAAQ;IACnB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAY;IAChC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;gBAEnB,GAAG,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM;IAKzC;;;;;;;OAOG;IACG,MAAM,CACV,KAAK,EAAE,MAAM,EACb,aAAa,EAAE,MAAM,EACrB,aAAa,EAAE,MAAM,EACrB,aAAa,EAAE,UAAU,EAAE,GAC1B,OAAO,CAAC,MAAM,CAAC;CAiCnB"}
@@ -0,0 +1,52 @@
1
+ // ── answerer.ts ──────────────────────────────────────────────────────
2
+ //
3
+ // Composes roster summary + memory distill + recent history into one
4
+ // LLMClient.chat call (no jsonObjectMode) and returns the text response.
5
+ // ── Answerer ──────────────────────────────────────────────────────────
6
+ export class Answerer {
7
+ llm;
8
+ model;
9
+ constructor(llm, model) {
10
+ this.llm = llm;
11
+ this.model = model;
12
+ }
13
+ /**
14
+ * Produce an answer to the user's input, given context.
15
+ *
16
+ * @param input - The current user message.
17
+ * @param rosterSummary - Compact string summary of active runs.
18
+ * @param memoryDistill - Compact string of lessons from .bober/memory/.
19
+ * @param recentHistory - Recent prior turns for conversation context.
20
+ */
21
+ async answer(input, rosterSummary, memoryDistill, recentHistory) {
22
+ const systemParts = [
23
+ "You are bober, an AI assistant integrated with the agent-bober engineering workflow.",
24
+ "",
25
+ "You have access to the following context:",
26
+ "",
27
+ "## Active Runs",
28
+ rosterSummary || "No runs found.",
29
+ "",
30
+ "## Project Memory (Lessons Learned)",
31
+ memoryDistill || "No lessons recorded yet.",
32
+ "",
33
+ "Answer the user's question concisely and helpfully.",
34
+ "If the user asks about runs or agents, use the Active Runs context above.",
35
+ "If the user asks about past mistakes or learnings, use the Project Memory context.",
36
+ ];
37
+ const system = systemParts.join("\n");
38
+ // Build message history from stored turns + current input
39
+ const messages = [];
40
+ for (const turn of recentHistory) {
41
+ messages.push({ role: turn.role, content: turn.content });
42
+ }
43
+ messages.push({ role: "user", content: input });
44
+ const response = await this.llm.chat({
45
+ model: this.model,
46
+ system,
47
+ messages,
48
+ });
49
+ return response.text;
50
+ }
51
+ }
52
+ //# sourceMappingURL=answerer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"answerer.js","sourceRoot":"","sources":["../../src/chat/answerer.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,EAAE;AACF,qEAAqE;AACrE,yEAAyE;AAKzE,yEAAyE;AAEzE,MAAM,OAAO,QAAQ;IACF,GAAG,CAAY;IACf,KAAK,CAAS;IAE/B,YAAY,GAAc,EAAE,KAAa;QACvC,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;QACf,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACrB,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,MAAM,CACV,KAAa,EACb,aAAqB,EACrB,aAAqB,EACrB,aAA2B;QAE3B,MAAM,WAAW,GAAa;YAC5B,sFAAsF;YACtF,EAAE;YACF,2CAA2C;YAC3C,EAAE;YACF,gBAAgB;YAChB,aAAa,IAAI,gBAAgB;YACjC,EAAE;YACF,qCAAqC;YACrC,aAAa,IAAI,0BAA0B;YAC3C,EAAE;YACF,qDAAqD;YACrD,2EAA2E;YAC3E,oFAAoF;SACrF,CAAC;QACF,MAAM,MAAM,GAAG,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAEtC,0DAA0D;QAC1D,MAAM,QAAQ,GAAkB,EAAE,CAAC;QACnC,KAAK,MAAM,IAAI,IAAI,aAAa,EAAE,CAAC;YACjC,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;QAC5D,CAAC;QACD,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;QAEhD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC;YACnC,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,MAAM;YACN,QAAQ;SACT,CAAC,CAAC;QAEH,OAAO,QAAQ,CAAC,IAAI,CAAC;IACvB,CAAC;CACF"}
@@ -0,0 +1,25 @@
1
+ import type { PendingMarker } from "../state/approval-state.js";
2
+ /**
3
+ * Stable identity key for a pending marker.
4
+ * Changes when a gate is re-requested in a later round (different requestedAt),
5
+ * but is stable while the gate remains at the same requestedAt.
6
+ */
7
+ export declare function markerKey(m: PendingMarker): string;
8
+ export declare class ApprovalCursor {
9
+ private readonly projectRoot;
10
+ private readonly sessionId;
11
+ constructor(projectRoot: string, sessionId: string);
12
+ private path;
13
+ /**
14
+ * Read the set of already-announced marker keys.
15
+ * Returns empty set on missing file or malformed JSON — never throws.
16
+ */
17
+ private readFile;
18
+ /**
19
+ * Return the subset of markers not yet announced, and atomically record
20
+ * them as announced for this session. Idempotent: calling again with
21
+ * the same markers returns [].
22
+ */
23
+ filterNew(markers: PendingMarker[]): Promise<PendingMarker[]>;
24
+ }
25
+ //# sourceMappingURL=approval-cursor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"approval-cursor.d.ts","sourceRoot":"","sources":["../../src/chat/approval-cursor.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAYhE;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,aAAa,GAAG,MAAM,CAElD;AAID,qBAAa,cAAc;IAEvB,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,QAAQ,CAAC,SAAS;gBADT,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM;IAGpC,OAAO,CAAC,IAAI;IASZ;;;OAGG;YACW,QAAQ;IAQtB;;;;OAIG;IACG,SAAS,CAAC,OAAO,EAAE,aAAa,EAAE,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC;CAmBpE"}
@@ -0,0 +1,61 @@
1
+ // ── approval-cursor.ts ────────────────────────────────────────────────
2
+ //
3
+ // Tracks which pending markers have already been announced in chat, by
4
+ // key `${checkpointId}@${requestedAt}`. Persists at
5
+ // .bober/chat/<sessionId>.approvals-cursor.json. Mirrors cursor-store.ts.
6
+ import { readFile, writeFile } from "node:fs/promises";
7
+ import { join } from "node:path";
8
+ import { ensureDir } from "../utils/fs.js";
9
+ const EMPTY = { announced: [] };
10
+ // ── Helpers ───────────────────────────────────────────────────────────
11
+ /**
12
+ * Stable identity key for a pending marker.
13
+ * Changes when a gate is re-requested in a later round (different requestedAt),
14
+ * but is stable while the gate remains at the same requestedAt.
15
+ */
16
+ export function markerKey(m) {
17
+ return `${m.checkpointId}@${m.requestedAt}`;
18
+ }
19
+ // ── ApprovalCursor ────────────────────────────────────────────────────
20
+ export class ApprovalCursor {
21
+ projectRoot;
22
+ sessionId;
23
+ constructor(projectRoot, sessionId) {
24
+ this.projectRoot = projectRoot;
25
+ this.sessionId = sessionId;
26
+ }
27
+ path() {
28
+ return join(this.projectRoot, ".bober", "chat", `${this.sessionId}.approvals-cursor.json`);
29
+ }
30
+ /**
31
+ * Read the set of already-announced marker keys.
32
+ * Returns empty set on missing file or malformed JSON — never throws.
33
+ */
34
+ async readFile() {
35
+ try {
36
+ return JSON.parse(await readFile(this.path(), "utf-8"));
37
+ }
38
+ catch {
39
+ return { ...EMPTY };
40
+ }
41
+ }
42
+ /**
43
+ * Return the subset of markers not yet announced, and atomically record
44
+ * them as announced for this session. Idempotent: calling again with
45
+ * the same markers returns [].
46
+ */
47
+ async filterNew(markers) {
48
+ const file = await this.readFile();
49
+ const seen = new Set(file.announced);
50
+ const fresh = markers.filter((m) => !seen.has(markerKey(m)));
51
+ if (fresh.length > 0) {
52
+ for (const m of fresh) {
53
+ seen.add(markerKey(m));
54
+ }
55
+ await ensureDir(join(this.projectRoot, ".bober", "chat"));
56
+ await writeFile(this.path(), JSON.stringify({ announced: [...seen] }, null, 2) + "\n", { encoding: "utf-8", mode: 0o600 });
57
+ }
58
+ return fresh;
59
+ }
60
+ }
61
+ //# sourceMappingURL=approval-cursor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"approval-cursor.js","sourceRoot":"","sources":["../../src/chat/approval-cursor.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,EAAE;AACF,uEAAuE;AACvE,oDAAoD;AACpD,0EAA0E;AAE1E,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAS3C,MAAM,KAAK,GAAkB,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC;AAE/C,yEAAyE;AAEzE;;;;GAIG;AACH,MAAM,UAAU,SAAS,CAAC,CAAgB;IACxC,OAAO,GAAG,CAAC,CAAC,YAAY,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;AAC9C,CAAC;AAED,yEAAyE;AAEzE,MAAM,OAAO,cAAc;IAEN;IACA;IAFnB,YACmB,WAAmB,EACnB,SAAiB;QADjB,gBAAW,GAAX,WAAW,CAAQ;QACnB,cAAS,GAAT,SAAS,CAAQ;IACjC,CAAC;IAEI,IAAI;QACV,OAAO,IAAI,CACT,IAAI,CAAC,WAAW,EAChB,QAAQ,EACR,MAAM,EACN,GAAG,IAAI,CAAC,SAAS,wBAAwB,CAC1C,CAAC;IACJ,CAAC;IAED;;;OAGG;IACK,KAAK,CAAC,QAAQ;QACpB,IAAI,CAAC;YACH,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,OAAO,CAAC,CAAkB,CAAC;QAC3E,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,GAAG,KAAK,EAAE,CAAC;QACtB,CAAC;IACH,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,SAAS,CAAC,OAAwB;QACtC,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,QAAQ,EAAE,CAAC;QACnC,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACrC,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAE7D,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACrB,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;gBACtB,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;YACzB,CAAC;YACD,MAAM,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC;YAC1D,MAAM,SAAS,CACb,IAAI,CAAC,IAAI,EAAE,EACX,IAAI,CAAC,SAAS,CAAC,EAAE,SAAS,EAAE,CAAC,GAAG,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EACxD,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CACnC,CAAC;QACJ,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC;CACF"}
@@ -0,0 +1,11 @@
1
+ import type { PendingMarker } from "../state/approval-state.js";
2
+ export declare class ApprovalReader {
3
+ private readonly projectRoot;
4
+ constructor(projectRoot: string);
5
+ /**
6
+ * Read all pending markers from .bober/approvals/*.pending.json.
7
+ * Missing dir => []; corrupt files skipped silently (delegated to listPending).
8
+ */
9
+ read(): Promise<PendingMarker[]>;
10
+ }
11
+ //# sourceMappingURL=approval-reader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"approval-reader.d.ts","sourceRoot":"","sources":["../../src/chat/approval-reader.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAIhE,qBAAa,cAAc;IACb,OAAO,CAAC,QAAQ,CAAC,WAAW;gBAAX,WAAW,EAAE,MAAM;IAEhD;;;OAGG;IACG,IAAI,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC;CAGvC"}
@@ -0,0 +1,20 @@
1
+ // ── approval-reader.ts ────────────────────────────────────────────────
2
+ //
3
+ // Read-only wrapper over listPending for chat context.
4
+ // NEVER writes approval markers (Sprint 3 owns the write path).
5
+ import { listPending } from "../state/approval-state.js";
6
+ // ── ApprovalReader ────────────────────────────────────────────────────
7
+ export class ApprovalReader {
8
+ projectRoot;
9
+ constructor(projectRoot) {
10
+ this.projectRoot = projectRoot;
11
+ }
12
+ /**
13
+ * Read all pending markers from .bober/approvals/*.pending.json.
14
+ * Missing dir => []; corrupt files skipped silently (delegated to listPending).
15
+ */
16
+ async read() {
17
+ return listPending(this.projectRoot);
18
+ }
19
+ }
20
+ //# sourceMappingURL=approval-reader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"approval-reader.js","sourceRoot":"","sources":["../../src/chat/approval-reader.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,EAAE;AACF,uDAAuD;AACvD,gEAAgE;AAEhE,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAGzD,yEAAyE;AAEzE,MAAM,OAAO,cAAc;IACI;IAA7B,YAA6B,WAAmB;QAAnB,gBAAW,GAAX,WAAW,CAAQ;IAAG,CAAC;IAEpD;;;OAGG;IACH,KAAK,CAAC,IAAI;QACR,OAAO,WAAW,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IACvC,CAAC;CACF"}
@@ -0,0 +1,15 @@
1
+ export declare class CarefulSidecar {
2
+ private readonly projectRoot;
3
+ private readonly sessionId;
4
+ constructor(projectRoot: string, sessionId: string);
5
+ private path;
6
+ /**
7
+ * Read the careful flag. Missing/malformed file => false (autopilot). Never throws.
8
+ */
9
+ isCareful(): Promise<boolean>;
10
+ /**
11
+ * Persist the careful flag atomically.
12
+ */
13
+ setCareful(on: boolean): Promise<void>;
14
+ }
15
+ //# sourceMappingURL=careful-sidecar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"careful-sidecar.d.ts","sourceRoot":"","sources":["../../src/chat/careful-sidecar.ts"],"names":[],"mappings":"AAYA,qBAAa,cAAc;IAEvB,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,QAAQ,CAAC,SAAS;gBADT,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM;IAGpC,OAAO,CAAC,IAAI;IAIZ;;OAEG;IACG,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC;IASnC;;OAEG;IACG,UAAU,CAAC,EAAE,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;CAQ7C"}
@@ -0,0 +1,39 @@
1
+ // ── careful-sidecar.ts ─────────────────────────────────────────────────
2
+ //
3
+ // Persists the per-session "careful mode" toggle at
4
+ // .bober/chat/<sessionId>.careful.json. Default off → autopilot (Phase 1).
5
+ import { readFile, writeFile } from "node:fs/promises";
6
+ import { join } from "node:path";
7
+ import { ensureDir } from "../utils/fs.js";
8
+ // ── CarefulSidecar ────────────────────────────────────────────────────
9
+ export class CarefulSidecar {
10
+ projectRoot;
11
+ sessionId;
12
+ constructor(projectRoot, sessionId) {
13
+ this.projectRoot = projectRoot;
14
+ this.sessionId = sessionId;
15
+ }
16
+ path() {
17
+ return join(this.projectRoot, ".bober", "chat", `${this.sessionId}.careful.json`);
18
+ }
19
+ /**
20
+ * Read the careful flag. Missing/malformed file => false (autopilot). Never throws.
21
+ */
22
+ async isCareful() {
23
+ try {
24
+ const data = JSON.parse(await readFile(this.path(), "utf-8"));
25
+ return data.careful === true;
26
+ }
27
+ catch {
28
+ return false;
29
+ }
30
+ }
31
+ /**
32
+ * Persist the careful flag atomically.
33
+ */
34
+ async setCareful(on) {
35
+ await ensureDir(join(this.projectRoot, ".bober", "chat"));
36
+ await writeFile(this.path(), JSON.stringify({ careful: on }, null, 2) + "\n", { encoding: "utf-8", mode: 0o600 });
37
+ }
38
+ }
39
+ //# sourceMappingURL=careful-sidecar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"careful-sidecar.js","sourceRoot":"","sources":["../../src/chat/careful-sidecar.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,EAAE;AACF,oDAAoD;AACpD,2EAA2E;AAE3E,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C,yEAAyE;AAEzE,MAAM,OAAO,cAAc;IAEN;IACA;IAFnB,YACmB,WAAmB,EACnB,SAAiB;QADjB,gBAAW,GAAX,WAAW,CAAQ;QACnB,cAAS,GAAT,SAAS,CAAQ;IACjC,CAAC;IAEI,IAAI;QACV,OAAO,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC,SAAS,eAAe,CAAC,CAAC;IACpF,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,SAAS;QACb,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,OAAO,CAAC,CAA0B,CAAC;YACvF,OAAO,IAAI,CAAC,OAAO,KAAK,IAAI,CAAC;QAC/B,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,UAAU,CAAC,EAAW;QAC1B,MAAM,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC;QAC1D,MAAM,SAAS,CACb,IAAI,CAAC,IAAI,EAAE,EACX,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAC/C,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CACnC,CAAC;IACJ,CAAC;CACF"}