toolroll 0.9.54 → 0.9.56

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 (350) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/README.md +29 -12
  3. package/dist/action-ledger.d.ts +2 -4
  4. package/dist/action-ledger.js +2 -10
  5. package/dist/agent-onboard.js +4 -1
  6. package/dist/approval-policy.d.ts +5 -5
  7. package/dist/approval-policy.js +4 -4
  8. package/dist/approval-rules-ui.d.ts +3 -2
  9. package/dist/approval-rules-ui.js +17 -22
  10. package/dist/assignment-ui.d.ts +3 -2
  11. package/dist/assignment-ui.js +4 -11
  12. package/dist/backup-ui.d.ts +2 -1
  13. package/dist/backup-ui.js +16 -27
  14. package/dist/brand-mark.d.ts +3 -2
  15. package/dist/brand-mark.js +4 -4
  16. package/dist/browser/workspace.css +1 -1
  17. package/dist/browser/workspace.js +25 -25
  18. package/dist/browser-shell.d.ts +2 -1
  19. package/dist/browser-shell.js +9 -9
  20. package/dist/browser-workspace.d.ts +14 -15
  21. package/dist/browser-workspace.js +0 -3
  22. package/dist/budget-alerts.js +3 -3
  23. package/dist/chat-actions.d.ts +23 -18
  24. package/dist/chat-actions.js +110 -88
  25. package/dist/chat-ask.d.ts +2 -2
  26. package/dist/chat-ask.js +5 -5
  27. package/dist/chat-channel.d.ts +15 -15
  28. package/dist/chat-channel.js +20 -20
  29. package/dist/chat-controls.d.ts +0 -4
  30. package/dist/chat-controls.js +0 -1
  31. package/dist/chat-core.js +1 -1
  32. package/dist/chat-delivery-state.js +2 -2
  33. package/dist/chat-delivery.d.ts +2 -2
  34. package/dist/chat-delivery.js +27 -34
  35. package/dist/chat-flow.js +3 -3
  36. package/dist/chat-messages.d.ts +1 -1
  37. package/dist/chat-messages.js +4 -4
  38. package/dist/chat-migration.d.ts +1 -1
  39. package/dist/chat-migration.js +11 -11
  40. package/dist/chat-polish.d.ts +5 -4
  41. package/dist/chat-polish.js +9 -10
  42. package/dist/chat-rooms.js +3 -3
  43. package/dist/chat-warmth.d.ts +2 -2
  44. package/dist/check-levels-ui.d.ts +2 -1
  45. package/dist/check-levels-ui.js +26 -53
  46. package/dist/cli.d.ts +3 -1
  47. package/dist/cli.js +15 -10
  48. package/dist/coding-shipping-ui.d.ts +2 -1
  49. package/dist/coding-shipping-ui.js +6 -6
  50. package/dist/coding-ui.d.ts +3 -1
  51. package/dist/coding-ui.js +30 -29
  52. package/dist/contracts/chat-actions.d.ts +32 -27
  53. package/dist/contracts/chat-actions.js +29 -11
  54. package/dist/contracts/chat-content.d.ts +1 -1
  55. package/dist/contracts/chat-content.js +1 -1
  56. package/dist/contracts/chat-tables.js +4 -4
  57. package/dist/contracts/cli.d.ts +1 -3
  58. package/dist/contracts/console-api.d.ts +7 -7
  59. package/dist/contracts/console-api.js +13 -12
  60. package/dist/contracts/flow-propose.d.ts +3 -3
  61. package/dist/contracts/flow.d.ts +132 -125
  62. package/dist/contracts/flow.js +27 -12
  63. package/dist/contracts/health.d.ts +1 -3
  64. package/dist/contracts/lead-context.d.ts +1 -1
  65. package/dist/contracts/lead-context.js +2 -2
  66. package/dist/contracts/lead-tools.d.ts +20 -18
  67. package/dist/contracts/lead-tools.js +15 -15
  68. package/dist/contracts/stage-output.d.ts +1 -1
  69. package/dist/contracts/stage-output.js +1 -1
  70. package/dist/contracts/store-json.d.ts +23 -22
  71. package/dist/contracts/store-json.js +17 -17
  72. package/dist/contracts/{teammate-turn.d.ts → subagent-turn.d.ts} +5 -5
  73. package/dist/contracts/{teammate-turn.js → subagent-turn.js} +7 -7
  74. package/dist/control-ui.d.ts +5 -4
  75. package/dist/control-ui.js +9 -34
  76. package/dist/converse.d.ts +23 -23
  77. package/dist/converse.js +28 -28
  78. package/dist/coordinator-proposals.d.ts +2 -2
  79. package/dist/coordinator-proposals.js +1 -1
  80. package/dist/coordinator.js +1 -1
  81. package/dist/credentials-ui.d.ts +5 -4
  82. package/dist/credentials-ui.js +23 -24
  83. package/dist/demo-chat.d.ts +3 -3
  84. package/dist/demo-chat.js +29 -76
  85. package/dist/deprecations.d.ts +12 -0
  86. package/dist/deprecations.js +20 -0
  87. package/dist/desktop-update-gate.js +8 -4
  88. package/dist/desktop-update.js +6 -1
  89. package/dist/discord-chat.js +6 -6
  90. package/dist/discord-settings.d.ts +3 -2
  91. package/dist/discord-settings.js +17 -42
  92. package/dist/dispatch.d.ts +1 -1
  93. package/dist/dispatch.js +1 -1
  94. package/dist/envelope.js +10 -1
  95. package/dist/evidence-pack.d.ts +2 -1
  96. package/dist/evidence-pack.js +45 -49
  97. package/dist/export-ui.d.ts +7 -2
  98. package/dist/export-ui.js +4 -10
  99. package/dist/export.js +7 -7
  100. package/dist/flow-engine.d.ts +2 -2
  101. package/dist/flow-engine.js +21 -21
  102. package/dist/flow-gallery-ui.d.ts +4 -3
  103. package/dist/flow-gallery-ui.js +28 -43
  104. package/dist/flow-insights.d.ts +1 -1
  105. package/dist/flow-share.js +13 -8
  106. package/dist/flow-starters-ui.d.ts +2 -1
  107. package/dist/flow-starters-ui.js +12 -15
  108. package/dist/flow-steps.d.ts +5 -5
  109. package/dist/flow-steps.js +19 -19
  110. package/dist/flow-triggers.d.ts +2 -1
  111. package/dist/flow-triggers.js +17 -15
  112. package/dist/flows-cli.js +1 -1
  113. package/dist/flows-ui.d.ts +4 -3
  114. package/dist/flows-ui.js +38 -49
  115. package/dist/flows.js +21 -20
  116. package/dist/guides.js +112 -6
  117. package/dist/html.d.ts +76 -0
  118. package/dist/html.js +173 -0
  119. package/dist/integrations-ui.d.ts +2 -1
  120. package/dist/integrations-ui.js +19 -23
  121. package/dist/invoke.js +1 -1
  122. package/dist/kits-ui.d.ts +5 -4
  123. package/dist/kits-ui.js +22 -24
  124. package/dist/kits.d.ts +12 -12
  125. package/dist/kits.js +31 -31
  126. package/dist/knowledge-ui.d.ts +6 -5
  127. package/dist/knowledge-ui.js +26 -25
  128. package/dist/{mate-cli.d.ts → lead-cli.d.ts} +11 -11
  129. package/dist/{mate-cli.js → lead-cli.js} +38 -38
  130. package/dist/lead-commitments.js +4 -4
  131. package/dist/lead-context.d.ts +12 -2
  132. package/dist/lead-context.js +15 -17
  133. package/dist/{mate-contract.d.ts → lead-contract.d.ts} +3 -3
  134. package/dist/{mate-contract.js → lead-contract.js} +7 -6
  135. package/dist/{mate-doors.d.ts → lead-doors.d.ts} +6 -6
  136. package/dist/{mate-doors.js → lead-doors.js} +24 -24
  137. package/dist/lead-follow.d.ts +5 -5
  138. package/dist/lead-follow.js +9 -9
  139. package/dist/lead-people.d.ts +5 -5
  140. package/dist/lead-people.js +14 -14
  141. package/dist/{mate-progress.d.ts → lead-progress.d.ts} +9 -9
  142. package/dist/{mate-progress.js → lead-progress.js} +3 -3
  143. package/dist/{mate-tools.d.ts → lead-tools.d.ts} +19 -19
  144. package/dist/{mate-tools.js → lead-tools.js} +109 -101
  145. package/dist/{mate.d.ts → lead.d.ts} +27 -27
  146. package/dist/{mate.js → lead.js} +102 -102
  147. package/dist/ledger-view.d.ts +2 -1
  148. package/dist/ledger-view.js +27 -29
  149. package/dist/limits-ui.d.ts +3 -2
  150. package/dist/limits-ui.js +8 -8
  151. package/dist/live-bus.d.ts +50 -8
  152. package/dist/live-bus.js +133 -50
  153. package/dist/mcp-connect.d.ts +1 -1
  154. package/dist/mcp-connect.js +3 -3
  155. package/dist/mcp-core.js +1 -1
  156. package/dist/mcp-oauth.js +35 -36
  157. package/dist/memory-pass.d.ts +2 -2
  158. package/dist/memory-pass.js +7 -7
  159. package/dist/models-ui.d.ts +2 -1
  160. package/dist/models-ui.js +25 -35
  161. package/dist/monitoring-ui.d.ts +4 -3
  162. package/dist/monitoring-ui.js +13 -26
  163. package/dist/notification-rows.d.ts +2 -2
  164. package/dist/openrouter-models.d.ts +2 -1
  165. package/dist/openrouter-models.js +5 -9
  166. package/dist/operate.d.ts +3 -3
  167. package/dist/operate.js +46 -41
  168. package/dist/people-audit-ui.d.ts +2 -1
  169. package/dist/people-audit-ui.js +13 -13
  170. package/dist/policy-ui.d.ts +3 -2
  171. package/dist/policy-ui.js +17 -23
  172. package/dist/policy.d.ts +1 -1
  173. package/dist/principal.d.ts +1 -1
  174. package/dist/principal.js +2 -2
  175. package/dist/project-delete-ui.d.ts +4 -3
  176. package/dist/project-delete-ui.js +16 -28
  177. package/dist/project-delete.d.ts +1 -1
  178. package/dist/project-delete.js +26 -26
  179. package/dist/project-memory.js +1 -1
  180. package/dist/project-tools.d.ts +1 -1
  181. package/dist/project-tools.js +1 -1
  182. package/dist/pull-request-ui.d.ts +2 -1
  183. package/dist/pull-request-ui.js +17 -32
  184. package/dist/recipe-ui.d.ts +8 -7
  185. package/dist/recipe-ui.js +39 -32
  186. package/dist/release-adapters.d.ts +60 -0
  187. package/dist/release-adapters.js +435 -0
  188. package/dist/release-cli.d.ts +24 -0
  189. package/dist/release-cli.js +181 -0
  190. package/dist/release-gate.d.ts +80 -0
  191. package/dist/release-gate.js +150 -0
  192. package/dist/release-links.d.ts +29 -0
  193. package/dist/release-links.js +102 -0
  194. package/dist/release.d.ts +331 -0
  195. package/dist/release.js +550 -0
  196. package/dist/reply-shape.d.ts +2 -1
  197. package/dist/reply-shape.js +5 -5
  198. package/dist/repository-context-ui.d.ts +2 -1
  199. package/dist/repository-context-ui.js +2 -7
  200. package/dist/request-budget-ui.d.ts +2 -1
  201. package/dist/request-budget-ui.js +16 -16
  202. package/dist/result-review.d.ts +2 -3
  203. package/dist/result-review.js +3 -9
  204. package/dist/retention-ui.d.ts +7 -1
  205. package/dist/retention-ui.js +7 -11
  206. package/dist/retention.js +4 -4
  207. package/dist/scope.d.ts +2 -2
  208. package/dist/scout-report.d.ts +1 -1
  209. package/dist/scout-report.js +1 -1
  210. package/dist/serve.d.ts +11 -2
  211. package/dist/serve.js +105 -99
  212. package/dist/server/chat.d.ts +7 -10
  213. package/dist/server/chat.js +984 -1021
  214. package/dist/server/chrome.d.ts +291 -0
  215. package/dist/server/chrome.js +747 -0
  216. package/dist/server/console.css +2819 -0
  217. package/dist/server/flows.d.ts +2 -6
  218. package/dist/server/flows.js +854 -773
  219. package/dist/server/guards.d.ts +1 -1
  220. package/dist/server/guards.js +8 -5
  221. package/dist/server/handler-context.d.ts +1 -1
  222. package/dist/server/handler-context.js +1 -1
  223. package/dist/server/handler-registry.d.ts +8 -6
  224. package/dist/server/handler-registry.js +14 -2
  225. package/dist/server/http.d.ts +274 -0
  226. package/dist/server/http.js +239 -0
  227. package/dist/server/live.d.ts +34 -0
  228. package/dist/server/live.js +309 -0
  229. package/dist/server/pages.d.ts +2 -6
  230. package/dist/server/pages.js +808 -789
  231. package/dist/server/people-tokens.d.ts +1 -6
  232. package/dist/server/people-tokens.js +581 -573
  233. package/dist/server/remote.d.ts +4 -7
  234. package/dist/server/remote.js +39 -70
  235. package/dist/server/render-chat.d.ts +402 -0
  236. package/dist/server/render-chat.js +927 -0
  237. package/dist/server/render-pages.d.ts +535 -0
  238. package/dist/server/render-pages.js +1277 -0
  239. package/dist/server/render-people.d.ts +32 -0
  240. package/dist/server/render-people.js +121 -0
  241. package/dist/server/render-results.d.ts +744 -0
  242. package/dist/server/render-results.js +2237 -0
  243. package/dist/server/render-settings.d.ts +154 -0
  244. package/dist/server/render-settings.js +580 -0
  245. package/dist/server/render-tasks.d.ts +632 -0
  246. package/dist/server/render-tasks.js +2345 -0
  247. package/dist/server/request-context.d.ts +46 -0
  248. package/dist/server/request-context.js +17 -0
  249. package/dist/server/route-table.d.ts +25 -3
  250. package/dist/server/route-table.js +167 -77
  251. package/dist/server/runtime.d.ts +28 -20
  252. package/dist/server/runtime.js +7 -1
  253. package/dist/server/session.d.ts +138 -0
  254. package/dist/server/session.js +94 -0
  255. package/dist/server/settings.d.ts +1 -5
  256. package/dist/server/settings.js +2186 -2121
  257. package/dist/server/task-views.d.ts +11 -4
  258. package/dist/server/task-views.js +26 -22
  259. package/dist/server/tasks.d.ts +9 -9
  260. package/dist/server/tasks.js +1489 -1420
  261. package/dist/server-telemetry.d.ts +4 -3
  262. package/dist/server-telemetry.js +4 -8
  263. package/dist/setup-guide.d.ts +2 -2
  264. package/dist/skills-ui.d.ts +4 -3
  265. package/dist/skills-ui.js +14 -17
  266. package/dist/skills.d.ts +1 -1
  267. package/dist/skills.js +2 -1
  268. package/dist/slack-chat.d.ts +2 -2
  269. package/dist/slack-chat.js +6 -6
  270. package/dist/slack-settings.d.ts +3 -2
  271. package/dist/slack-settings.js +17 -42
  272. package/dist/spend-ui.d.ts +5 -4
  273. package/dist/spend-ui.js +17 -40
  274. package/dist/spend.d.ts +14 -14
  275. package/dist/spend.js +31 -31
  276. package/dist/sso-ui.d.ts +3 -2
  277. package/dist/sso-ui.js +26 -27
  278. package/dist/storage-ui.d.ts +2 -1
  279. package/dist/storage-ui.js +14 -33
  280. package/dist/store-baseline.d.ts +19 -0
  281. package/dist/store-baseline.js +2873 -0
  282. package/dist/store.d.ts +197 -249
  283. package/dist/store.js +747 -3084
  284. package/dist/subagent-admin.d.ts +53 -0
  285. package/dist/{teammate-admin.js → subagent-admin.js} +37 -37
  286. package/dist/{teammate-desk.d.ts → subagent-desk.d.ts} +22 -23
  287. package/dist/{teammate-desk.js → subagent-desk.js} +26 -35
  288. package/dist/{teammate-memory.d.ts → subagent-memory.d.ts} +17 -17
  289. package/dist/{teammate-memory.js → subagent-memory.js} +41 -41
  290. package/dist/{teammate-question.d.ts → subagent-question.d.ts} +6 -6
  291. package/dist/{teammate-question.js → subagent-question.js} +17 -17
  292. package/dist/{teammate-tools.d.ts → subagent-tools.d.ts} +18 -18
  293. package/dist/{teammate-tools.js → subagent-tools.js} +36 -36
  294. package/dist/{teammate-week.d.ts → subagent-week.d.ts} +10 -10
  295. package/dist/{teammate-week.js → subagent-week.js} +23 -23
  296. package/dist/{teammate-work.d.ts → subagent-work.d.ts} +21 -21
  297. package/dist/{teammate-work.js → subagent-work.js} +50 -50
  298. package/dist/subagents-ui.d.ts +22 -0
  299. package/dist/subagents-ui.js +137 -0
  300. package/dist/{teammates.d.ts → subagents.d.ts} +11 -11
  301. package/dist/{teammates.js → subagents.js} +21 -21
  302. package/dist/subscription-chat.d.ts +13 -13
  303. package/dist/subscription-chat.js +19 -19
  304. package/dist/surface.d.ts +19 -2
  305. package/dist/surface.js +20 -33
  306. package/dist/task-composer.d.ts +2 -1
  307. package/dist/task-composer.js +7 -7
  308. package/dist/task-status.d.ts +4 -3
  309. package/dist/task-status.js +15 -16
  310. package/dist/team-cli.d.ts +1 -0
  311. package/dist/team-cli.js +14 -2
  312. package/dist/team-http.d.ts +5 -9
  313. package/dist/team-http.js +5 -63
  314. package/dist/team-leads.js +13 -13
  315. package/dist/team-runtime.d.ts +2 -2
  316. package/dist/team-runtime.js +8 -8
  317. package/dist/team-ui.d.ts +2 -1
  318. package/dist/team-ui.js +2 -5
  319. package/dist/teams-chat.js +6 -6
  320. package/dist/teams-settings.d.ts +3 -2
  321. package/dist/teams-settings.js +20 -31
  322. package/dist/telegram-flow.d.ts +3 -3
  323. package/dist/telegram-flow.js +3 -3
  324. package/dist/{telegram-mate.d.ts → telegram-lead.d.ts} +5 -5
  325. package/dist/{telegram-mate.js → telegram-lead.js} +27 -27
  326. package/dist/telegram-settings.d.ts +3 -2
  327. package/dist/telegram-settings.js +14 -25
  328. package/dist/telegram-status.js +1 -1
  329. package/dist/telegram-team.d.ts +1 -1
  330. package/dist/telegram-team.js +5 -5
  331. package/dist/telegram.d.ts +1 -1
  332. package/dist/telegram.js +9 -30
  333. package/dist/text-limits.d.ts +18 -18
  334. package/dist/text-limits.js +18 -18
  335. package/dist/toolroll-update-ui.d.ts +3 -2
  336. package/dist/toolroll-update-ui.js +35 -39
  337. package/dist/toolroll-update.d.ts +8 -0
  338. package/dist/toolroll-update.js +45 -8
  339. package/dist/tools-ui.d.ts +5 -2
  340. package/dist/tools-ui.js +31 -31
  341. package/dist/when-html.d.ts +11 -3
  342. package/dist/when-html.js +5 -6
  343. package/dist/workspace-ui.d.ts +4 -2
  344. package/dist/workspace-ui.js +10 -10
  345. package/package.json +1 -2
  346. package/dist/server/shared.d.ts +0 -3151
  347. package/dist/server/shared.js +0 -12001
  348. package/dist/teammate-admin.d.ts +0 -53
  349. package/dist/teammates-ui.d.ts +0 -20
  350. package/dist/teammates-ui.js +0 -166
@@ -1,5 +1,5 @@
1
- import type { Store, TeammateCallRow, TeammateRow } from "./store.js";
2
- import { type ToolIo } from "./teammate-tools.js";
1
+ import type { Store, SubagentCallRow, SubagentRow } from "./store.js";
2
+ import { type ToolIo } from "./subagent-tools.js";
3
3
  type Done = {
4
4
  ok: true;
5
5
  said: string;
@@ -38,20 +38,20 @@ export type Week = {
38
38
  }[];
39
39
  };
40
40
  /** The undo action a call's rule names, when there is one and the call can still be undone. */
41
- export declare function undoFor(store: Store, call: TeammateCallRow): string | null;
42
- /** The last seven days (or since a time) for one teammate. */
43
- export declare function weekOf(store: Store, mate: TeammateRow, now: Date, since?: string): Week;
41
+ export declare function undoFor(store: Store, call: SubagentCallRow): string | null;
42
+ /** The last seven days (or since a time) for one subagent. */
43
+ export declare function weekOf(store: Store, mate: SubagentRow, now: Date, since?: string): Week;
44
44
  /** The week in words its manager reads at a glance. */
45
- export declare function weekWords(mate: TeammateRow, week: Week): string;
46
- /** Each Monday from 9:00 (this computer's time), the week's report to each active teammate's manager, once; or now, for one. */
47
- export declare function sendTeammateWeeklies(store: Store, repo: string, now: Date, only?: number | null): number;
45
+ export declare function weekWords(mate: SubagentRow, week: Week): string;
46
+ /** Each Monday from 9:00 (this computer's time), the week's report to each active subagent's manager, once; or now, for one. */
47
+ export declare function sendSubagentWeeklies(store: Store, repo: string, now: Date, only?: number | null): number;
48
48
  /**
49
49
  * A person asks to undo one of its tool calls with the action its manager
50
50
  * named: the undo call is recorded at once (the same input, as them), and
51
51
  * made by finishUndo — right away on the page, or by the worker's next pass
52
52
  * when it was asked for in chat. Both calls keep their receipts.
53
53
  */
54
- export declare function requestUndo(store: Store, mate: TeammateRow, id: number, by: string, now: Date): {
54
+ export declare function requestUndo(store: Store, mate: SubagentRow, id: number, by: string, now: Date): {
55
55
  ok: true;
56
56
  call: number;
57
57
  said: string;
@@ -64,5 +64,5 @@ export declare function finishUndo(store: Store, id: number, io: ToolIo, now: Da
64
64
  /** The worker's pass: undo calls asked for in chat, made now. */
65
65
  export declare function runRequestedUndos(store: Store, io: ToolIo, now: Date): Promise<number>;
66
66
  /** Undo, on the page: asked for and made at once. */
67
- export declare function undoCall(store: Store, mate: TeammateRow, id: number, by: string, io: ToolIo, now: Date): Promise<Done>;
67
+ export declare function undoCall(store: Store, mate: SubagentRow, id: number, by: string, io: ToolIo, now: Date): Promise<Done>;
68
68
  export {};
@@ -1,5 +1,5 @@
1
1
  /**
2
- * A teammate's week (v97): what it did, what it cost, what its people
2
+ * A subagent's week (v97): what it did, what it cost, what its people
3
3
  * overrode, and its receipts — on its page, and each Monday morning to its
4
4
  * manager in their chat app.
5
5
  *
@@ -13,29 +13,29 @@
13
13
  * keep their receipts.
14
14
  */
15
15
  import { flowCardHref } from "./flow-engine.js";
16
- import { labelOf, nameOf } from "./teammate-admin.js";
17
- import { callWords, makeCall } from "./teammate-tools.js";
16
+ import { labelOf, nameOf } from "./subagent-admin.js";
17
+ import { callWords, makeCall } from "./subagent-tools.js";
18
18
  const WEEK_MS = 7 * 86_400_000;
19
19
  const money = (usd) => usd < 0.01 ? "under 1¢" : usd < 10 ? `$${usd.toFixed(2)}` : `$${Math.round(usd)}`;
20
20
  /** The undo action a call's rule names, when there is one and the call can still be undone. */
21
21
  export function undoFor(store, call) {
22
22
  if (call.state !== "done" || call.undoneBy !== null || call.undoOf !== null)
23
23
  return null;
24
- const grant = store.teammateGrant(call.teammate, call.tool);
24
+ const grant = store.subagentGrant(call.subagent, call.tool);
25
25
  const undo = grant?.rules[call.action]?.undo;
26
26
  return undo !== undefined && grant.actions.some(one => one.name === undo) ? undo : null;
27
27
  }
28
- /** The last seven days (or since a time) for one teammate. */
28
+ /** The last seven days (or since a time) for one subagent. */
29
29
  export function weekOf(store, mate, now, since = new Date(now.getTime() - WEEK_MS).toISOString()) {
30
- const turns = store.teammateTurns(mate.id, since);
30
+ const turns = store.subagentTurns(mate.id, since);
31
31
  const costs = turns.map(one => one.costUsd).filter((one) => one !== null);
32
- const events = store.teammateEvents(mate.id, 5000, since);
32
+ const events = store.subagentEvents(mate.id, 5000, since);
33
33
  const count = (kind) => events.filter(one => one.kind === kind).length;
34
- const calls = store.teammateCallsOf(mate.id, 5000, since).filter(one => one.undoOf === null);
34
+ const calls = store.subagentCallsOf(mate.id, 5000, since).filter(one => one.undoOf === null);
35
35
  const hrefOf = (card) => { const found = card === null ? null : store.getFlowCard(card); return found === null ? null : flowCardHref(found.flow, found.id); };
36
36
  const name = nameOf(mate);
37
37
  const denied = calls.filter(one => one.state === "denied").map(one => {
38
- const words = store.teammateQuestionForCall(one.id)?.answer;
38
+ const words = store.subagentQuestionForCall(one.id)?.answer;
39
39
  return { said: `${one.decidedBy ?? "Someone"} turned down ${callWords(one.tool, one.action, one.input, 160)}${words ? `: “${words.slice(0, 160)}”` : ""}`, at: one.decidedAt ?? one.createdAt, href: hrefOf(one.card) };
40
40
  });
41
41
  const moved = store.flowMovesOverridden(`${name} (AI)`, since).map(one => ({ said: `${one.by} moved “${one.title.slice(0, 80)}” after ${name} did`, at: one.at, href: flowCardHref(one.flow, one.card) }));
@@ -63,22 +63,22 @@ export function weekWords(mate, week) {
63
63
  ];
64
64
  return lines.join("\n");
65
65
  }
66
- /** Each Monday from 9:00 (this computer's time), the week's report to each active teammate's manager, once; or now, for one. */
67
- export function sendTeammateWeeklies(store, repo, now, only = null) {
66
+ /** Each Monday from 9:00 (this computer's time), the week's report to each active subagent's manager, once; or now, for one. */
67
+ export function sendSubagentWeeklies(store, repo, now, only = null) {
68
68
  const monday = new Date(now);
69
69
  monday.setHours(9, 0, 0, 0);
70
70
  monday.setDate(monday.getDate() - ((monday.getDay() + 6) % 7));
71
71
  let sent = 0;
72
- for (const mate of store.teammates([repo])) {
73
- // One a week, from Monday 9:00; a teammate that joined since then has its first next Monday.
72
+ for (const mate of store.subagents([repo])) {
73
+ // One a week, from Monday 9:00; a subagent that joined since then has its first next Monday.
74
74
  if (only !== null ? mate.id !== only : mate.state !== "active" || now < monday || (mate.weeklyAt ?? mate.createdAt) >= monday.toISOString())
75
75
  continue;
76
- store.updateTeammate(mate.id, { weeklyAt: now.toISOString() }, "weekly", now);
76
+ store.updateSubagent(mate.id, { weeklyAt: now.toISOString() }, "weekly", now);
77
77
  const week = weekOf(store, mate, now);
78
78
  if (week.turns === 0 && only === null)
79
79
  continue;
80
80
  store.enqueueNotification({ dedupeKey: `teammate-weekly:${mate.id}:${now.toISOString().slice(0, only === null ? 10 : 19)}`, kind: "teammate-weekly", recipient: mate.manager,
81
- subject: `${labelOf(mate)}: the week`, body: weekWords(mate, week), link: `/teammates/${mate.id}#week`, source: { project: repo } }, now);
81
+ subject: `${labelOf(mate)}: the week`, body: weekWords(mate, week), link: `/settings/lead/subagents/${mate.id}#week`, source: { project: repo } }, now);
82
82
  sent++;
83
83
  }
84
84
  return sent;
@@ -90,36 +90,36 @@ export function sendTeammateWeeklies(store, repo, now, only = null) {
90
90
  * when it was asked for in chat. Both calls keep their receipts.
91
91
  */
92
92
  export function requestUndo(store, mate, id, by, now) {
93
- const call = store.teammateCall(id);
94
- if (call === null || call.teammate !== mate.id)
93
+ const call = store.subagentCall(id);
94
+ if (call === null || call.subagent !== mate.id)
95
95
  return { ok: false, said: "No such call." };
96
96
  const undo = undoFor(store, call);
97
97
  if (undo === null)
98
98
  return { ok: false, said: call.undoneBy !== null ? `${call.undoneBy} already undid it.` : "That call can't be undone here." };
99
99
  return store.transact(() => {
100
- if (!store.markTeammateCallUndone(call.id, by, now))
100
+ if (!store.markSubagentCallUndone(call.id, by, now))
101
101
  return { ok: false, said: "Someone undid it just now." };
102
- const made = store.addTeammateCall({ teammate: mate.id, card: call.card, entry: call.entry, tool: call.tool, action: undo, input: call.input, rule: "free",
102
+ const made = store.addSubagentCall({ subagent: mate.id, card: call.card, entry: call.entry, tool: call.tool, action: undo, input: call.input, rule: "free",
103
103
  why: `${by} undid ${call.action} (call ${call.id}).`, state: "approved", undoOf: call.id, decidedBy: by }, now);
104
104
  return { ok: true, call: made, said: `Undoing it with ${undo}.` };
105
105
  });
106
106
  }
107
107
  /** Make a requested undo call; if the tool says it failed, the original call stands (and can be undone again). */
108
108
  export async function finishUndo(store, id, io, now) {
109
- const pending = store.teammateCall(id);
110
- const mate = pending === null ? null : store.getTeammate(pending.teammate);
109
+ const pending = store.subagentCall(id);
110
+ const mate = pending === null ? null : store.getSubagent(pending.subagent);
111
111
  if (pending === null || mate === null || pending.undoOf === null || pending.state !== "approved")
112
112
  return { ok: false, said: "That undo was already made." };
113
113
  const made = await makeCall(store, pending, mate.repo, io, now, { byPerson: true });
114
114
  if (made.state === "done")
115
115
  return { ok: true, said: `Undone: ${callWords(made.tool, made.action, made.input, 120)}. ${made.result ?? ""}`.trim() };
116
- store.clearTeammateCallUndone(pending.undoOf, now);
116
+ store.clearSubagentCallUndone(pending.undoOf, now);
117
117
  return { ok: false, said: `The undo call failed: ${made.result ?? "no answer"}. The original call stands.` };
118
118
  }
119
119
  /** The worker's pass: undo calls asked for in chat, made now. */
120
120
  export async function runRequestedUndos(store, io, now) {
121
121
  let made = 0;
122
- for (const call of store.pendingTeammateUndos()) {
122
+ for (const call of store.pendingSubagentUndos()) {
123
123
  await finishUndo(store, call.id, io, now);
124
124
  made++;
125
125
  }
@@ -1,66 +1,66 @@
1
1
  /**
2
- * A teammate's turn on a card (v92), run by the flow step pass.
2
+ * A subagent's turn on a card (v92), run by the flow step pass.
3
3
  *
4
4
  * The turn reads the zone, the card (as data) and what its people told it,
5
- * and answers with one decision (teammates.ts). This carries the decision
5
+ * and answers with one decision (subagents.ts). This carries the decision
6
6
  * out within the zone's own choices, and writes it down — what it did and
7
- * why — in the card's history and the teammate's log:
7
+ * why — in the card's history and the subagent's log:
8
8
  *
9
9
  * - "Person decides" zone: approve (the draft as written, or as it rewrote
10
10
  * it), send back with a note, or hand it to the zone's person, whose
11
11
  * decision then arrives in their chat app as always.
12
- * - "Teammate handles it" zone: pick one of the zone's answers (its text is
12
+ * - "Subagent handles it" zone: pick one of the zone's answers (its text is
13
13
  * kept for the next zones), ask its person a question and wait for the
14
14
  * answer, or say it can't and take the failure path.
15
15
  *
16
16
  * Either way (v94), before it decides it may use the project tools its
17
17
  * manager let it use: each call is checked against its rule for that action
18
- * (teammate-tools.ts), made at once or put to its person first, and kept as
18
+ * (subagent-tools.ts), made at once or put to its person first, and kept as
19
19
  * a receipt; the turn goes on with what the tool answered.
20
20
  */
21
- import type { FlowCardRow, FlowRow, Store, TeammateRow } from "./store.js";
21
+ import type { FlowCardRow, FlowRow, Store, SubagentRow } from "./store.js";
22
22
  import type { FlowDefinition, FlowStage } from "./flows.js";
23
- import { type TurnRunner } from "./teammates.js";
24
- import { type ToolIo } from "./teammate-tools.js";
23
+ import { type TurnRunner } from "./subagents.js";
24
+ import { type ToolIo } from "./subagent-tools.js";
25
25
  /** A question waits for its answer this long before the step is due again on its own: never, in practice. */
26
26
  export declare const ASKED = "9999-12-31T00:00:00.000Z";
27
27
  /** v94: tool calls one visit of a card may make, and turns one step run may take, before it must decide with what it has. */
28
28
  export declare const CALLS_PER_VISIT = 12;
29
- /** The two answers an ask-first call offers; words instead tell the teammate what to do. */
29
+ /** The two answers an ask-first call offers; words instead tell the subagent what to do. */
30
30
  export declare const APPROVE = "approve", DENY = "deny";
31
- export type TeammateOutcome = {
31
+ export type SubagentOutcome = {
32
32
  state: "passed" | "failed" | "retry" | "waiting";
33
33
  said: string;
34
34
  log?: string;
35
35
  decisionJson?: string;
36
36
  nextAt?: string;
37
37
  };
38
- /** The Claude model a teammate's turns run on: its own, or the lead chat's Claude model, or Claude's default. */
39
- export declare function teammateModel(store: Store, mate: TeammateRow): string;
40
- /** Whether a teammate can take a turn now: active, readable, and under its daily limit. */
41
- export declare function teammateReady(store: Store, mate: TeammateRow | null, now: Date): {
38
+ /** The Claude model a subagent's turns run on: its own, or the lead chat's Claude model, or Claude's default. */
39
+ export declare function subagentModel(store: Store, mate: SubagentRow): string;
40
+ /** Whether a subagent can take a turn now: active, readable, and under its daily limit. */
41
+ export declare function subagentReady(store: Store, mate: SubagentRow | null, now: Date): {
42
42
  ok: true;
43
43
  } | {
44
44
  ok: false;
45
45
  why: string;
46
46
  };
47
- /** The answers a "Teammate handles it" zone offers, each with the zone it leads to. */
47
+ /** The answers a "Subagent handles it" zone offers, each with the zone it leads to. */
48
48
  export declare function handleAnswers(stage: FlowStage): {
49
49
  answer: string;
50
50
  to: string | null;
51
51
  }[];
52
52
  /**
53
- * Run one teammate turn on a card and carry out what it decided. With tools
53
+ * Run one subagent turn on a card and carry out what it decided. With tools
54
54
  * (v94) a turn is a short loop: each tool call it asks for is made (or put to
55
55
  * its person, and the turn waits), and it decides again with the answer —
56
56
  * until it decides, or it has used its tools as much as a visit allows.
57
57
  */
58
- export declare function teammateTurn(store: Store, flow: FlowRow, definition: FlowDefinition, stage: FlowStage, card: FlowCardRow, mate: TeammateRow, now: Date, io: {
58
+ export declare function subagentTurn(store: Store, flow: FlowRow, definition: FlowDefinition, stage: FlowStage, card: FlowCardRow, mate: SubagentRow, now: Date, io: {
59
59
  turn?: TurnRunner;
60
60
  evidenceRoot?: string;
61
- } & ToolIo): Promise<TeammateOutcome>;
62
- /** A person answers a teammate's question: once, by the person it was asked of; the card's turn is due again. */
63
- export declare function answerTeammateQuestion(store: Store, id: number, answer: {
61
+ } & ToolIo): Promise<SubagentOutcome>;
62
+ /** A person answers a subagent's question: once, by the person it was asked of; the card's turn is due again. */
63
+ export declare function answerSubagentQuestion(store: Store, id: number, answer: {
64
64
  choice: string | null;
65
65
  text: string | null;
66
66
  by: string;
@@ -73,4 +73,4 @@ export declare function answerTeammateQuestion(store: Store, id: number, answer:
73
73
  said: string;
74
74
  };
75
75
  /** A card's link, for messages about it. */
76
- export declare const teammateCardHref: (flow: number, card: number) => string;
76
+ export declare const subagentCardHref: (flow: number, card: number) => string;
@@ -1,12 +1,12 @@
1
1
  import { decideFlowCard, draftFor, flowCardHref } from "./flow-engine.js";
2
2
  import { wholeDraft } from "./flow-draft.js";
3
3
  import { notifyPeople } from "./flow-people.js";
4
- import { claudeTurnRunner, parseSoul, readTurn, teammateActor, teammateLabel, TURN_TIMEOUT_MS, turnOverruns, turnPrompt } from "./teammates.js";
4
+ import { claudeTurnRunner, parseSoul, readTurn, subagentActor, subagentLabel, TURN_TIMEOUT_MS, turnOverruns, turnPrompt } from "./subagents.js";
5
5
  import { passOn, shortenAsk, TEXT_LIMITS } from "./text-limits.js";
6
6
  import { LIMITS } from "./decision.js";
7
- import { callName, callOutcome, callWords, inputProblem, makeCall, offeredTools, refreshGrants, ruleFor } from "./teammate-tools.js";
8
- import { answerSuggestion, considerSuggestion, memoriesFor, remember } from "./teammate-memory.js";
9
- import { replyToAsker } from "./teammate-desk.js";
7
+ import { callName, callOutcome, callWords, inputProblem, makeCall, offeredTools, refreshGrants, ruleFor } from "./subagent-tools.js";
8
+ import { answerSuggestion, considerSuggestion, memoriesFor, remember } from "./subagent-memory.js";
9
+ import { replyToAsker } from "./subagent-desk.js";
10
10
  import { claudeMachineBilling } from "./spend.js";
11
11
  /** A question waits for its answer this long before the step is due again on its own: never, in practice. */
12
12
  export const ASKED = "9999-12-31T00:00:00.000Z";
@@ -15,35 +15,35 @@ const CARRY_ON = "Carry on";
15
15
  /** v94: tool calls one visit of a card may make, and turns one step run may take, before it must decide with what it has. */
16
16
  export const CALLS_PER_VISIT = 12;
17
17
  const TURNS_PER_RUN = 8;
18
- /** The two answers an ask-first call offers; words instead tell the teammate what to do. */
18
+ /** The two answers an ask-first call offers; words instead tell the subagent what to do. */
19
19
  export const APPROVE = "approve", DENY = "deny";
20
20
  const startOfDay = (now) => { const day = new Date(now); day.setHours(0, 0, 0, 0); return day.toISOString(); };
21
- /** The Claude model a teammate's turns run on: its own, or the lead chat's Claude model, or Claude's default. */
22
- export function teammateModel(store, mate) {
21
+ /** The Claude model a subagent's turns run on: its own, or the lead chat's Claude model, or Claude's default. */
22
+ export function subagentModel(store, mate) {
23
23
  const config = store.getChatConfig();
24
24
  return mate.model ?? (config?.provider === "claude-subscription" ? config.model : "default");
25
25
  }
26
- /** Whether a teammate can take a turn now: active, readable, and under its daily limit. */
27
- export function teammateReady(store, mate, now) {
26
+ /** Whether a subagent can take a turn now: active, readable, and under its daily limit. */
27
+ export function subagentReady(store, mate, now) {
28
28
  if (mate === null)
29
29
  return { ok: false, why: "gone" };
30
30
  if (mate.state !== "active")
31
31
  return { ok: false, why: "paused" };
32
32
  if (!parseSoul(mate.soul).ok)
33
33
  return { ok: false, why: "its soul file can't be read" };
34
- if (store.teammateTurnsSince(mate.id, startOfDay(now)) >= mate.dailyTurns)
34
+ if (store.subagentTurnsSince(mate.id, startOfDay(now)) >= mate.dailyTurns)
35
35
  return { ok: false, why: `it reached today's limit of ${mate.dailyTurns} turns` };
36
36
  // v105: its turns bill as this computer's Claude does with no key from us; billed to a key, a budget holds them.
37
- const held = store.budgetGate(now)({ project: mate.repo, person: null, teammate: mate.id, agents: [{ provider: "claude", billing: claudeMachineBilling(store.handle) }] });
37
+ const held = store.budgetGate(now)({ project: mate.repo, person: null, subagent: mate.id, agents: [{ provider: "claude", billing: claudeMachineBilling(store.handle) }] });
38
38
  if (held.over !== null)
39
39
  return { ok: false, why: held.why === "used-up" ? "a monthly budget its work counts toward is used up" : "a monthly budget can't price its work yet" };
40
40
  // Sprint 8: its turns run on Claude, with its own model or the lead chat's: the organisation policy has to allow them.
41
- const disallowed = store.agentPolicyRefusal("claude", teammateModel(store, mate));
41
+ const disallowed = store.agentPolicyRefusal("claude", subagentModel(store, mate));
42
42
  if (disallowed !== null)
43
43
  return { ok: false, why: disallowed };
44
44
  return { ok: true };
45
45
  }
46
- /** The answers a "Teammate handles it" zone offers, each with the zone it leads to. */
46
+ /** The answers a "Subagent handles it" zone offers, each with the zone it leads to. */
47
47
  export function handleAnswers(stage) {
48
48
  return stage.routes !== undefined && stage.routes.length > 0 ? stage.routes : [{ answer: CARRY_ON, to: stage.next }];
49
49
  }
@@ -54,7 +54,7 @@ function contextOf(store, flow, definition, stage, card, mate, tools = [], spent
54
54
  throw new Error(soul.problem);
55
55
  const title = (id) => definition.stages.find(one => one.id === id)?.title ?? id;
56
56
  const draft = stage.kind === "approval" ? draftFor(definition, stage) : null;
57
- const question = store.teammateQuestionFor(card.id, card.entry);
57
+ const question = store.subagentQuestionFor(card.id, card.entry);
58
58
  // v95: what its people told it lately, and what it kept that fits this card.
59
59
  const memory = memoriesFor(store, mate, `${card.title}\n${card.description ?? ""}`, new Date());
60
60
  return {
@@ -72,28 +72,28 @@ function contextOf(store, flow, definition, stage, card, mate, tools = [], spent
72
72
  notes: memory.told.map(one => ({ by: one.createdBy, text: one.text })),
73
73
  memory: memory.kept.map(one => one.text),
74
74
  tools, toolsSpent: spent,
75
- calls: store.teammateCallsOn(card.id, card.entry).map(call => {
76
- const question = call.state === "denied" ? store.teammateQuestionForCall(call.id) : null;
75
+ calls: store.subagentCallsOn(card.id, card.entry).map(call => {
76
+ const question = call.state === "denied" ? store.subagentQuestionForCall(call.id) : null;
77
77
  return { name: callName(call.tool, call.action), input: JSON.stringify(call.input), outcome: callOutcome(call),
78
78
  said: call.state === "denied" ? question?.answer ?? null : call.state === "asked" ? null : call.result };
79
79
  }),
80
80
  };
81
81
  }
82
82
  /**
83
- * Run one teammate turn on a card and carry out what it decided. With tools
83
+ * Run one subagent turn on a card and carry out what it decided. With tools
84
84
  * (v94) a turn is a short loop: each tool call it asks for is made (or put to
85
85
  * its person, and the turn waits), and it decides again with the answer —
86
86
  * until it decides, or it has used its tools as much as a visit allows.
87
87
  */
88
- export async function teammateTurn(store, flow, definition, stage, card, mate, now, io) {
89
- const model = teammateModel(store, mate);
90
- if (store.teammateGrants(mate.id).length > 0) {
88
+ export async function subagentTurn(store, flow, definition, stage, card, mate, now, io) {
89
+ const model = subagentModel(store, mate);
90
+ if (store.subagentGrants(mate.id).length > 0) {
91
91
  try {
92
92
  await refreshGrants(store, mate, now, io);
93
93
  }
94
94
  catch { /* the last listing stands */ }
95
95
  // Calls a person approved since the last turn are made first, exactly as they approved them.
96
- for (const call of store.teammateCallsOn(card.id, card.entry).filter(one => one.state === "approved" && one.undoOf === null))
96
+ for (const call of store.subagentCallsOn(card.id, card.entry).filter(one => one.state === "approved" && one.undoOf === null))
97
97
  await makeCall(store, call, flow.repo, io, now);
98
98
  }
99
99
  const log = [];
@@ -101,14 +101,14 @@ export async function teammateTurn(store, flow, definition, stage, card, mate, n
101
101
  let shorten;
102
102
  let shortened = false;
103
103
  for (let turn = 1;; turn++) {
104
- const made = store.teammateCallsOn(card.id, card.entry).length;
104
+ const made = store.subagentCallsOn(card.id, card.entry).length;
105
105
  const spent = made >= CALLS_PER_VISIT || turn > TURNS_PER_RUN;
106
106
  const tools = spent ? [] : offeredTools(store, mate);
107
107
  const context = { ...contextOf(store, flow, definition, stage, card, mate, tools, spent && made > 0), ...(shorten === undefined ? {} : { shorten }) };
108
108
  const asked = Date.now();
109
109
  const reply = await (io.turn ?? claudeTurnRunner())({ model, prompt: turnPrompt(context), timeoutMs: TURN_TIMEOUT_MS });
110
110
  // v97: every turn is kept with what it cost, for its weekly report.
111
- store.addTeammateTurn({ teammate: mate.id, card: card.id, model, ok: reply.ok, ms: reply.ok ? reply.ms : Date.now() - asked, costUsd: reply.costUsd ?? null, tokensIn: reply.tokensIn ?? null, tokensOut: reply.tokensOut ?? null }, now);
111
+ store.addSubagentTurn({ subagent: mate.id, card: card.id, model, ok: reply.ok, ms: reply.ok ? reply.ms : Date.now() - asked, costUsd: reply.costUsd ?? null, tokensIn: reply.tokensIn ?? null, tokensOut: reply.tokensOut ?? null }, now);
112
112
  if (!reply.ok)
113
113
  return { state: "retry", said: reply.said, ...(log.length === 0 ? {} : { log: log.join("\n\n") }) };
114
114
  const read = readTurn(reply.value, context);
@@ -126,7 +126,7 @@ export async function teammateTurn(store, flow, definition, stage, card, mate, n
126
126
  }
127
127
  shorten = undefined;
128
128
  if (answer.remember !== "")
129
- remember(store, mate, answer.remember, { source: "teammate", card: card.id, by: teammateActor({ name: context.name }) }, now);
129
+ remember(store, mate, answer.remember, { source: "subagent", card: card.id, by: subagentActor({ name: context.name }) }, now);
130
130
  if (answer.action !== "use_tool") {
131
131
  const outcome = carryOut(store, flow, definition, stage, card, mate, context, answer, now, io, header);
132
132
  return log.length === 0 ? outcome : { ...outcome, log: `${log.join("\n\n")}\n\n${outcome.log ?? ""}`.trim() };
@@ -145,8 +145,8 @@ export async function teammateTurn(store, flow, definition, stage, card, mate, n
145
145
  async function useTool(store, flow, stage, card, mate, context, answer, io, now) {
146
146
  const split = answer.tool.indexOf(".");
147
147
  const tool = split < 0 ? answer.tool : answer.tool.slice(0, split), action = split < 0 ? "" : answer.tool.slice(split + 1);
148
- const receipt = { teammate: mate.id, card: card.id, entry: card.entry, tool: tool.slice(0, 40), action: action.slice(0, 64) || "(none)", why: answer.reason };
149
- const refuse = (input, said) => { store.addTeammateCall({ ...receipt, input, rule: "never", state: "refused", result: said }, now); return null; };
148
+ const receipt = { subagent: mate.id, card: card.id, entry: card.entry, tool: tool.slice(0, 40), action: action.slice(0, 64) || "(none)", why: answer.reason };
149
+ const refuse = (input, said) => { store.addSubagentCall({ ...receipt, input, rule: "never", state: "refused", result: said }, now); return null; };
150
150
  if (!(context.tools ?? []).some(one => one.name === answer.tool))
151
151
  return refuse({}, `There's no ${answer.tool} among the tools you may use.`);
152
152
  let input;
@@ -159,7 +159,7 @@ async function useTool(store, flow, stage, card, mate, context, answer, io, now)
159
159
  catch {
160
160
  return refuse({}, "Its input wasn't a JSON object.");
161
161
  }
162
- const grant = store.teammateGrant(mate.id, tool);
162
+ const grant = store.subagentGrant(mate.id, tool);
163
163
  const info = grant.actions.find(one => one.name === action);
164
164
  const problem = inputProblem(info, input);
165
165
  if (problem !== null)
@@ -168,18 +168,18 @@ async function useTool(store, flow, stage, card, mate, context, answer, io, now)
168
168
  if (rule.use === "never")
169
169
  return refuse(input, rule.why);
170
170
  if (rule.use === "free") {
171
- const id = store.addTeammateCall({ ...receipt, input, rule: "free", state: "running" }, now);
172
- await makeCall(store, store.teammateCall(id), flow.repo, io, now);
171
+ const id = store.addSubagentCall({ ...receipt, input, rule: "free", state: "running" }, now);
172
+ await makeCall(store, store.subagentCall(id), flow.repo, io, now);
173
173
  return null;
174
174
  }
175
175
  // Ask first: its person approves this exact call, in their chat app or on the card.
176
176
  const soul = { name: context.name, role: context.role };
177
- const id = store.addTeammateCall({ ...receipt, input, rule: "ask", state: "asked", result: rule.why }, now);
177
+ const id = store.addSubagentCall({ ...receipt, input, rule: "ask", state: "asked", result: rule.why }, now);
178
178
  const words = callWords(tool, action, input, 480);
179
- const question = store.openTeammateQuestion({ teammate: mate.id, card: card.id, entry: card.entry, question: `Use ${words}?`, options: [{ id: APPROVE, label: "Approve" }, { id: DENY, label: "Deny" }], askedOf: context.person, toolCall: id }, now);
179
+ const question = store.openSubagentQuestion({ subagent: mate.id, card: card.id, entry: card.entry, question: `Use ${words}?`, options: [{ id: APPROVE, label: "Approve" }, { id: DENY, label: "Deny" }], askedOf: context.person, toolCall: id }, now);
180
180
  if (question === null)
181
181
  return { state: "failed", said: "It asked to make the same call twice." };
182
- notifyPeople(store, card, [context.person], null, { key: `teammate-q:${question}`, attention: true, subject: `${teammateLabel(soul)} asks to use ${action} on “${card.title}”`,
182
+ notifyPeople(store, card, [context.person], null, { key: `teammate-q:${question}`, attention: true, subject: `${subagentLabel(soul)} asks to use ${action} on “${card.title}”`,
183
183
  body: `${words}\n\n${answer.reason === "" ? "" : `Why: ${answer.reason}\n`}(${rule.why})\n\nApprove makes exactly this call. Deny stops it. Or answer in words to tell ${context.name} what to do instead.`,
184
184
  }, now);
185
185
  if (stage.kind !== "approval")
@@ -196,17 +196,17 @@ function keptWhole(store, flow, card, author, text, limit, holds, what, now) {
196
196
  }
197
197
  function carryOut(store, flow, definition, stage, card, mate, context, answer, now, io, header) {
198
198
  const soul = { name: context.name, role: context.role };
199
- const actor = teammateActor(soul), label = teammateLabel(soul);
199
+ const actor = subagentActor(soul), label = subagentLabel(soul);
200
200
  const decisionJson = JSON.stringify(answer);
201
201
  const log = `${header}\n\n${decisionJson}`;
202
- const event = (kind, said) => store.addTeammateEvent({ teammate: mate.id, card: card.id, entry: card.entry, kind, said, detail: { flow: flow.id, zone: stage.id, action: answer.action, reason: answer.reason } }, now);
202
+ const event = (kind, said) => store.addSubagentEvent({ subagent: mate.id, card: card.id, entry: card.entry, kind, said, detail: { flow: flow.id, zone: stage.id, action: answer.action, reason: answer.reason } }, now);
203
203
  const titleOf = (id) => definition.stages.find(one => one.id === id)?.title ?? "the next zone";
204
204
  const repos = [flow.repo];
205
205
  const note = (text) => keptWhole(store, flow, card, actor, text, LIMITS.note, "a note holds", `${label}'s note`, now);
206
206
  if (answer.action === "approve" || answer.action === "send_back") {
207
207
  const draft = draftFor(definition, stage);
208
208
  const decided = decideFlowCard(store, {
209
- card: card.id, decision: answer.action === "approve" ? "approve" : "send-back", note: answer.action === "approve" ? answer.reason || null : note(answer.note), actor, repos, teammate: mate.handle, entry: card.entry, where: "a teammate",
209
+ card: card.id, decision: answer.action === "approve" ? "approve" : "send-back", note: answer.action === "approve" ? answer.reason || null : note(answer.note), actor, repos, subagent: mate.handle, entry: card.entry, where: "a subagent",
210
210
  ...(answer.action === "approve" && draft !== null && answer.text !== "" ? { draft: wholeDraft(answer.text) } : {}),
211
211
  ...(io.evidenceRoot === undefined ? {} : { evidenceRoot: io.evidenceRoot }),
212
212
  }, now);
@@ -223,7 +223,7 @@ function carryOut(store, flow, definition, stage, card, mate, context, answer, n
223
223
  }
224
224
  if (answer.action === "ask") {
225
225
  const options = answer.options.map((label, at) => ({ id: `o${at + 1}`, label }));
226
- const opened = store.openTeammateQuestion({ teammate: mate.id, card: card.id, entry: card.entry, question: answer.question, options, askedOf: context.person }, now);
226
+ const opened = store.openSubagentQuestion({ subagent: mate.id, card: card.id, entry: card.entry, question: answer.question, options, askedOf: context.person }, now);
227
227
  if (opened === null)
228
228
  return { state: "failed", said: "It asked twice about the same visit.", log, decisionJson };
229
229
  event("asked", `Asked ${context.person} about “${card.title}”: ${answer.question}`);
@@ -260,10 +260,10 @@ function carryOut(store, flow, definition, stage, card, mate, context, answer, n
260
260
  store.moveFlowCard(card.id, { to: picked.to, outcome: "ok", actor, historyNote: `${actor}: ${picked.answer === CARRY_ON ? "" : `${picked.answer}. `}${answer.reason}`.trim(), expectEntry: card.entry }, now);
261
261
  return { state: "passed", said, log, decisionJson };
262
262
  }
263
- /** A person answers a teammate's question: once, by the person it was asked of; the card's turn is due again. */
264
- export function answerTeammateQuestion(store, id, answer, now) {
263
+ /** A person answers a subagent's question: once, by the person it was asked of; the card's turn is due again. */
264
+ export function answerSubagentQuestion(store, id, answer, now) {
265
265
  return store.transact(() => {
266
- const question = store.teammateQuestion(id);
266
+ const question = store.subagentQuestion(id);
267
267
  if (question === null || question.state !== "open")
268
268
  return { ok: false, said: "That question was already answered." };
269
269
  if (question.askedOf !== answer.by)
@@ -275,28 +275,28 @@ export function answerTeammateQuestion(store, id, answer, now) {
275
275
  const card = store.getFlowCard(question.card);
276
276
  // v95: a rule change it suggested to its manager. Nothing about the card waits on it.
277
277
  if (question.suggestion !== null) {
278
- const mate = store.getTeammate(question.teammate);
279
- const decided = mate === null ? { ok: false, said: "That teammate is off the team." } : answerSuggestion(store, mate, question.suggestion, { choice: choice?.id ?? null, text, by: answer.by }, now);
280
- store.answerTeammateQuestion(id, { choice: choice?.id ?? null, text, by: answer.by, via: answer.via }, now);
281
- store.addTeammateEvent({ teammate: question.teammate, card: question.card, entry: question.entry, kind: "answered", said: `${answer.by}: ${[choice?.label, text].filter(Boolean).join(" — ")}`, by: answer.by }, now);
278
+ const mate = store.getSubagent(question.subagent);
279
+ const decided = mate === null ? { ok: false, said: "That subagent is off the team." } : answerSuggestion(store, mate, question.suggestion, { choice: choice?.id ?? null, text, by: answer.by }, now);
280
+ store.answerSubagentQuestion(id, { choice: choice?.id ?? null, text, by: answer.by, via: answer.via }, now);
281
+ store.addSubagentEvent({ subagent: question.subagent, card: question.card, entry: question.entry, kind: "answered", said: `${answer.by}: ${[choice?.label, text].filter(Boolean).join(" — ")}`, by: answer.by }, now);
282
282
  return decided;
283
283
  }
284
284
  // v94: an ask-first tool call. Approve makes exactly that call (on the card's next turn); Deny, or words alone, don't.
285
285
  if (question.toolCall !== null) {
286
286
  if (card === null || card.state !== "active" || card.entry !== question.entry) {
287
- store.moveTeammateCall(question.toolCall, ["asked"], { state: "refused", result: "The card moved on before anyone approved it." }, now);
288
- store.dropTeammateQuestion(id, now);
287
+ store.moveSubagentCall(question.toolCall, ["asked"], { state: "refused", result: "The card moved on before anyone approved it." }, now);
288
+ store.dropSubagentQuestion(id, now);
289
289
  return { ok: false, said: "That card has moved on, so nothing was done." };
290
290
  }
291
- if (!store.moveTeammateCall(question.toolCall, ["asked"], { state: choice?.id === APPROVE ? "approved" : "denied", decidedBy: answer.by }, now))
291
+ if (!store.moveSubagentCall(question.toolCall, ["asked"], { state: choice?.id === APPROVE ? "approved" : "denied", decidedBy: answer.by }, now))
292
292
  return { ok: false, said: "That call was already decided." };
293
293
  // v95: approving the same action again and again teaches it to suggest a looser rule.
294
- const mate = store.getTeammate(question.teammate), call = store.teammateCall(question.toolCall);
294
+ const mate = store.getSubagent(question.subagent), call = store.subagentCall(question.toolCall);
295
295
  if (choice?.id === APPROVE && mate !== null && call !== null)
296
296
  considerSuggestion(store, mate, call, now);
297
297
  }
298
- store.answerTeammateQuestion(id, { choice: choice?.id ?? null, text, by: answer.by, via: answer.via }, now);
299
- store.addTeammateEvent({ teammate: question.teammate, card: question.card, entry: question.entry, kind: "answered", said: `${answer.by}: ${[choice?.label, text].filter(Boolean).join(" — ")}`, by: answer.by }, now);
298
+ store.answerSubagentQuestion(id, { choice: choice?.id ?? null, text, by: answer.by, via: answer.via }, now);
299
+ store.addSubagentEvent({ subagent: question.subagent, card: question.card, entry: question.entry, kind: "answered", said: `${answer.by}: ${[choice?.label, text].filter(Boolean).join(" — ")}`, by: answer.by }, now);
300
300
  if (card !== null && card.state === "active" && card.entry === question.entry) {
301
301
  store.updateFlowCard(card.id, { waiting: null }, now);
302
302
  store.wakeFlowStep(card.id, card.entry, now);
@@ -305,4 +305,4 @@ export function answerTeammateQuestion(store, id, answer, now) {
305
305
  });
306
306
  }
307
307
  /** A card's link, for messages about it. */
308
- export const teammateCardHref = (flow, card) => flowCardHref(flow, card);
308
+ export const subagentCardHref = (flow, card) => flowCardHref(flow, card);
@@ -0,0 +1,22 @@
1
+ /**
2
+ * The Subagents pages (v92): who is on the team, and one page per subagent —
3
+ * what it asks you, its soul file, what it did and why, what you told it,
4
+ * and its settings. Server-rendered forms, like the other settings pages.
5
+ */
6
+ import type { Store, SubagentRow } from "./store.js";
7
+ import { type Html } from "./html.js";
8
+ /** v94: the Tools section's rule rows; a limit's fields show only while "Up to a limit" is chosen. */
9
+ export declare const SUBAGENT_CSS = ".subagent-tools .tool-grant{border-top:1px solid var(--so-line);padding-top:12px;margin-top:12px}.subagent-tools .tool-grant:first-of-type{border-top:0;margin-top:0;padding-top:0}.subagent-tools h3{font-size:1rem;margin:0 0 4px}.subagent-tools .tool-rule{display:grid;gap:6px;padding:10px 0;border-bottom:1px solid var(--so-line)}.subagent-tools .tool-rule:last-of-type{border-bottom:0}.subagent-tools .tool-rule .meta{display:block}.subagent-tools select,.subagent-tools input{max-width:100%;box-sizing:border-box}.subagent-tools .tool-limit{display:none;flex-wrap:wrap;align-items:center;gap:6px}.subagent-tools .tool-rule:has(option[value=\"limit\"]:checked) .tool-limit{display:flex}.subagent-tools .tool-rule>select{width:auto;min-width:16em}.subagent-tools .tool-limit select{width:auto}.subagent-tools .tool-limit input{width:7em}.subagent-tools .tool-buttons{display:flex;flex-wrap:wrap;gap:8px;margin-top:8px}.subagent-tools button{min-height:44px}.subagent-activity li{overflow-wrap:anywhere}.subagent-memory .memory-tell,.subagent-memory .memory-search{display:flex;flex-wrap:wrap;gap:8px;align-items:flex-end;margin:0 0 12px}.subagent-memory .memory-tell textarea{flex:1 1 280px}.subagent-memory .memory-search input{flex:1 1 220px}.subagent-memory button{min-height:44px}.subagent-memories{list-style:none;padding:0;margin:0}.subagent-memories li{padding:10px 0;border-top:1px solid var(--so-line);overflow-wrap:anywhere}.subagent-memories li:first-child{border-top:0}.subagent-memories .meta{display:block;font-size:.85rem}.subagent-memories details.memory-edit{border:0;padding:0;margin:2px 0 0;background:transparent;box-shadow:none}.memory-edit summary{cursor:pointer;min-height:32px;display:inline-flex;align-items:center;font-size:.85rem;font-weight:400;color:var(--so-muted)}.tool-undo{border:0;padding:0;margin:8px 0;background:transparent;box-shadow:none}.tool-undo summary{cursor:pointer;min-height:36px;display:inline-flex;align-items:center;font-size:.9rem}.tool-undo-row{display:flex;flex-wrap:wrap;gap:6px;align-items:center;margin:6px 0}.tool-undo-row select{width:auto}.subagent-overrides,.subagent-undo{padding-left:18px}.subagent-undo li{margin:6px 0}.subagent-undo form{display:inline}.subagent-week h3{font-size:1rem;margin:14px 0 4px}.subagent-week button{min-height:44px}.subagent-routines{list-style:none;padding:0;margin:8px 0}.subagent-routines li{display:grid;gap:4px;padding:10px 0;border-top:1px solid var(--so-line)}.subagent-routines li:first-child{border-top:0}.routine-buttons{display:flex;flex-wrap:wrap;gap:8px}.routine-buttons button,.routine-add button{min-height:44px}.routine-add{display:flex;flex-wrap:wrap;gap:8px;align-items:flex-end;margin:8px 0}.routine-add label{display:grid;gap:4px;flex:1 1 200px}.routine-add label:first-of-type{flex:0 1 180px}.subagent-actions,.question-options{display:flex;flex-wrap:wrap;gap:8px;margin:8px 0}.subagent-actions form,.question-options form{margin:0}.memory-edit form{display:grid;gap:8px;margin-top:6px}.memory-buttons{display:flex;flex-wrap:wrap;gap:8px}@media(max-width:600px){.subagent-tools select,.subagent-tools input{font-size:16px}}";
10
+ /** A blank soul file: the sections a subagent reads, to fill in. */
11
+ export declare const BLANK_SOUL = "---\nname: \nrole: \n---\n\n## Who you are\n\n\n## How you write\n\n\n## What you know\n\n\n## Decide on your own\n- \n\n## Ask first\n- \n\n## Never\n- \n";
12
+ export declare function subagentsListHtml(store: Store, mates: readonly SubagentRow[], projects: readonly string[], projectName: (repo: string) => string, canCreate: boolean, notice: {
13
+ said?: string | null;
14
+ problem?: string | null;
15
+ adding?: boolean;
16
+ }): Html;
17
+ export declare function subagentPageHtml(store: Store, mate: SubagentRow, viewer: string, projectName: (repo: string) => string, canManage: boolean, approvers: readonly string[], notice: {
18
+ said?: string | null;
19
+ problem?: string | null;
20
+ soulDraft?: string | null;
21
+ query?: string | null;
22
+ }): Html;