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,14 +1,14 @@
1
1
  /**
2
- * What a teammate remembers (v95), and how it learns from its people.
2
+ * What a subagent remembers (v95), and how it learns from its people.
3
3
  *
4
4
  * Memory is short facts, each a line: what its people told it ("this week,
5
5
  * offer free shipping instead of a refund" — v92's notes), and what it kept
6
6
  * from its own turns ("Sam prefers email to phone"). Every turn reads what
7
7
  * its people said lately, and what it kept that fits the card. People search,
8
- * edit and forget any of it on the teammate's page or through the lead.
8
+ * edit and forget any of it on the subagent's page or through the lead.
9
9
  *
10
10
  * Learning: when its manager approves the same ask-first tool action again
11
- * and again (five in a row, none denied), the teammate suggests loosening
11
+ * and again (five in a row, none denied), the subagent suggests loosening
12
12
  * that one rule — "You approved my last 5 refunds (amount 55 to 70): may I
13
13
  * make them on my own up to 75?" — as a question its manager accepts or
14
14
  * not, in their chat app or on its page. Accepting changes only that rule,
@@ -16,12 +16,12 @@
16
16
  */
17
17
  import { scanForSecrets } from "./evidence.js";
18
18
  import { notifyPeople } from "./flow-people.js";
19
- import { labelOf, nameOf } from "./teammate-admin.js";
20
- import { defaultRule, numberFields, setToolRules } from "./teammate-tools.js";
19
+ import { labelOf, nameOf } from "./subagent-admin.js";
20
+ import { defaultRule, numberFields, setToolRules } from "./subagent-tools.js";
21
21
  export const MEMORY_CHARS = 300;
22
- /** Facts a teammate keeps on its own: past this, its oldest are forgotten. What people told it is never dropped this way. */
22
+ /** Facts a subagent keeps on its own: past this, its oldest are forgotten. What people told it is never dropped this way. */
23
23
  export const MEMORY_CAP = 300;
24
- /** Approvals in a row of one action before the teammate suggests loosening its rule. */
24
+ /** Approvals in a row of one action before the subagent suggests loosening its rule. */
25
25
  export const SUGGEST_AFTER = 5;
26
26
  export const ACCEPT = "accept", DISMISS = "dismiss";
27
27
  const STOP = new Set("about after again also been before being could does doing from have here into just like more most much must only other over same some such than that their them then there these they this those through very want were what when where which while will with would your yours please thanks thank hello".split(" "));
@@ -45,57 +45,57 @@ export function cleanMemory(text) {
45
45
  if (line.length > MEMORY_CHARS)
46
46
  return { ok: false, said: `Keep a memory to ${MEMORY_CHARS} characters; put lasting rules in its soul file.` };
47
47
  if (scanForSecrets(line).length > 0)
48
- return { ok: false, said: "That looks like a key or password. Keep secrets out of a teammate's memory." };
48
+ return { ok: false, said: "That looks like a key or password. Keep secrets out of a subagent's memory." };
49
49
  return { ok: true, text: line };
50
50
  }
51
- /** Keep one thing: from a person (what they told it), or from the teammate itself on a turn. The same words twice are kept once. */
51
+ /** Keep one thing: from a person (what they told it), or from the subagent itself on a turn. The same words twice are kept once. */
52
52
  export function remember(store, mate, text, from, now) {
53
- const clean = cleanMemory(from.source === "teammate" ? text.slice(0, MEMORY_CHARS) : text);
53
+ const clean = cleanMemory(from.source === "subagent" ? text.slice(0, MEMORY_CHARS) : text);
54
54
  if (!clean.ok)
55
55
  return clean;
56
- const same = store.teammateMemories(mate.id).find(one => one.text.toLowerCase() === clean.text.toLowerCase());
56
+ const same = store.subagentMemories(mate.id).find(one => one.text.toLowerCase() === clean.text.toLowerCase());
57
57
  if (same !== undefined)
58
58
  return { ok: true, said: `${nameOf(mate)} already remembers that.`, id: same.id };
59
59
  // Saying nearly the same thing again on the same card (another turn of the same visit) refreshes what it kept instead of adding a second line.
60
- if (from.source === "teammate" && from.card !== undefined && from.card !== null) {
61
- const near = store.teammateMemories(mate.id, { source: "teammate" }).find(one => one.card === from.card && similar(one.text, clean.text));
60
+ if (from.source === "subagent" && from.card !== undefined && from.card !== null) {
61
+ const near = store.subagentMemories(mate.id, { source: "subagent" }).find(one => one.card === from.card && similar(one.text, clean.text));
62
62
  if (near !== undefined) {
63
- store.editTeammateMemory(near.id, clean.text, from.by, now);
63
+ store.editSubagentMemory(near.id, clean.text, from.by, now);
64
64
  return { ok: true, said: `${nameOf(mate)} already remembers that.`, id: near.id };
65
65
  }
66
66
  }
67
- const id = store.addTeammateMemory({ teammate: mate.id, text: clean.text, source: from.source, card: from.card ?? null, by: from.by }, now);
68
- if (from.source === "teammate")
69
- for (const old of store.teammateMemories(mate.id, { source: "teammate" }).slice(MEMORY_CAP))
70
- store.forgetTeammateMemory(old.id, "limit", now);
67
+ const id = store.addSubagentMemory({ subagent: mate.id, text: clean.text, source: from.source, card: from.card ?? null, by: from.by }, now);
68
+ if (from.source === "subagent")
69
+ for (const old of store.subagentMemories(mate.id, { source: "subagent" }).slice(MEMORY_CAP))
70
+ store.forgetSubagentMemory(old.id, "limit", now);
71
71
  return { ok: true, said: `${nameOf(mate)} will remember that.`, id };
72
72
  }
73
- /** Something a person tells a teammate (the page's "Tell Maya something", or the lead): kept in its memory, read by every turn while it's among the latest ten. */
74
- export function tellTeammate(store, mate, note, by, now) {
73
+ /** Something a person tells a subagent (the page's "Tell Maya something", or the lead): kept in its memory, read by every turn while it's among the latest ten. */
74
+ export function tellSubagent(store, mate, note, by, now) {
75
75
  const kept = remember(store, mate, note, { source: "person", by }, now);
76
76
  return kept.ok ? { ok: true, said: `${nameOf(mate)} will keep that in mind.` } : kept;
77
77
  }
78
78
  export function editMemory(store, mate, id, text, by, now) {
79
- const memory = store.teammateMemory(id);
80
- if (memory === null || memory.teammate !== mate.id)
79
+ const memory = store.subagentMemory(id);
80
+ if (memory === null || memory.subagent !== mate.id)
81
81
  return { ok: false, said: "It doesn't remember that any more." };
82
82
  const clean = cleanMemory(text);
83
83
  if (!clean.ok)
84
84
  return clean;
85
- store.editTeammateMemory(id, clean.text, by, now);
85
+ store.editSubagentMemory(id, clean.text, by, now);
86
86
  return { ok: true, said: "Saved." };
87
87
  }
88
88
  export function forgetMemory(store, mate, id, by, now) {
89
- const memory = store.teammateMemory(id);
90
- if (memory === null || memory.teammate !== mate.id)
89
+ const memory = store.subagentMemory(id);
90
+ if (memory === null || memory.subagent !== mate.id)
91
91
  return { ok: false, said: "It doesn't remember that any more." };
92
- store.forgetTeammateMemory(id, by, now);
92
+ store.forgetSubagentMemory(id, by, now);
93
93
  return { ok: true, said: `${nameOf(mate)} forgot it.` };
94
94
  }
95
95
  /** Memories whose text holds every word searched for. */
96
96
  export function searchMemories(store, mate, query) {
97
97
  const words = query.toLowerCase().split(/[^\p{L}\p{N}$]+/u).filter(one => one.length >= 2);
98
- return store.teammateMemories(mate.id, { words, limit: 100 });
98
+ return store.subagentMemories(mate.id, { words, limit: 100 });
99
99
  }
100
100
  /**
101
101
  * What one turn reads: what its people told it lately (oldest first), and
@@ -103,13 +103,13 @@ export function searchMemories(store, mate, query) {
103
103
  * words, then its newest — up to eight.
104
104
  */
105
105
  export function memoriesFor(store, mate, cardText, now) {
106
- const told = store.teammateMemories(mate.id, { source: "person", limit: 10 }).reverse();
107
- const own = store.teammateMemories(mate.id, { source: "teammate", limit: MEMORY_CAP });
106
+ const told = store.subagentMemories(mate.id, { source: "person", limit: 10 }).reverse();
107
+ const own = store.subagentMemories(mate.id, { source: "subagent", limit: MEMORY_CAP });
108
108
  const words = wordsOf(cardText);
109
109
  const scored = own.map(one => ({ one, score: words.filter(word => one.text.toLowerCase().includes(word)).length })).filter(one => one.score > 0)
110
110
  .sort((a, b) => b.score - a.score || b.one.id - a.one.id).slice(0, 6).map(one => one.one);
111
111
  const kept = [...scored, ...own.filter(one => !scored.includes(one))].slice(0, 8);
112
- store.markTeammateMemoriesUsed(kept.map(one => one.id), now);
112
+ store.markSubagentMemoriesUsed(kept.map(one => one.id), now);
113
113
  return { told, kept };
114
114
  }
115
115
  const numberOf = (value) => typeof value === "number" && Number.isFinite(value) ? value
@@ -119,22 +119,22 @@ export const roundUp = (value) => { const step = value < 20 ? 1 : value < 100 ?
119
119
  /**
120
120
  * After a person approves an ask-first call: when they have approved this
121
121
  * action enough times in a row since it last suggested anything about it,
122
- * the teammate suggests the rule that would have let it make them all.
122
+ * the subagent suggests the rule that would have let it make them all.
123
123
  */
124
124
  export function considerSuggestion(store, mate, approved, now) {
125
- const grant = store.teammateGrant(mate.id, approved.tool);
125
+ const grant = store.subagentGrant(mate.id, approved.tool);
126
126
  const info = grant?.actions.find(one => one.name === approved.action);
127
127
  if (grant === null || info === undefined)
128
128
  return null;
129
129
  const rule = grant.rules[approved.action] ?? defaultRule(info);
130
130
  if (rule.use === "never" || (rule.use === "free" && rule.limit === undefined))
131
131
  return null;
132
- const earlier = store.teammateSuggestionsFor(mate.id, approved.tool, approved.action);
132
+ const earlier = store.subagentSuggestionsFor(mate.id, approved.tool, approved.action);
133
133
  if (earlier.some(one => one.state === "open"))
134
134
  return null;
135
135
  const since = earlier[0]?.createdAt ?? "";
136
136
  const run = [];
137
- for (const call of store.teammateCallsOf(mate.id, 400).filter(one => one.tool === approved.tool && one.action === approved.action && one.rule === "ask" && one.decidedBy !== null && (one.decidedAt ?? "") > since)) {
137
+ for (const call of store.subagentCallsOf(mate.id, 400).filter(one => one.tool === approved.tool && one.action === approved.action && one.rule === "ask" && one.decidedBy !== null && (one.decidedAt ?? "") > since)) {
138
138
  if (call.state === "denied")
139
139
  break;
140
140
  run.push(call);
@@ -162,8 +162,8 @@ export function considerSuggestion(store, mate, approved, now) {
162
162
  const said = suggested.limit === undefined
163
163
  ? `You approved my last ${run.length} ${approved.action} calls on ${approved.tool}. May I make them on my own from now on?`
164
164
  : `You approved my last ${run.length} ${approved.action} calls on ${approved.tool}${range}. May I make them on my own up to ${suggested.limit.field} ${suggested.limit.over}, and ask you above that?`;
165
- const id = store.addTeammateSuggestion({ teammate: mate.id, tool: approved.tool, action: approved.action, rule: suggested, was: rule, evidence: run.map(one => one.id), said }, now);
166
- const question = store.openTeammateQuestion({ teammate: mate.id, card: card.id, entry: approved.entry, question: said, options: [{ id: ACCEPT, label: "Yes, change it" }, { id: DISMISS, label: "Not now" }], askedOf: mate.manager, suggestion: id }, now);
165
+ const id = store.addSubagentSuggestion({ subagent: mate.id, tool: approved.tool, action: approved.action, rule: suggested, was: rule, evidence: run.map(one => one.id), said }, now);
166
+ const question = store.openSubagentQuestion({ subagent: mate.id, card: card.id, entry: approved.entry, question: said, options: [{ id: ACCEPT, label: "Yes, change it" }, { id: DISMISS, label: "Not now" }], askedOf: mate.manager, suggestion: id }, now);
167
167
  if (question === null)
168
168
  return id;
169
169
  notifyPeople(store, card, [mate.manager], null, { key: `teammate-q:${question}`, attention: false, subject: `${labelOf(mate)} suggests a rule change`,
@@ -172,24 +172,24 @@ export function considerSuggestion(store, mate, approved, now) {
172
172
  }
173
173
  /** Its manager answers a suggestion: accept changes the one rule (if it is still what it was), anything else leaves it; their words are remembered. */
174
174
  export function answerSuggestion(store, mate, suggestion, answer, now) {
175
- const offered = store.teammateSuggestion(suggestion);
175
+ const offered = store.subagentSuggestion(suggestion);
176
176
  if (offered === null || offered.state !== "open")
177
177
  return { ok: false, said: "That suggestion was already answered." };
178
178
  if (answer.choice === ACCEPT) {
179
- const grant = store.teammateGrant(mate.id, offered.tool);
179
+ const grant = store.subagentGrant(mate.id, offered.tool);
180
180
  const current = grant === null ? null : grant.rules[offered.action] ?? null;
181
181
  const { undo: _undo, ...compared } = current ?? { use: "never" };
182
182
  if (current === null || JSON.stringify(compared) !== JSON.stringify((({ undo: _was, ...rest }) => rest)(offered.was))) {
183
- store.decideTeammateSuggestion(offered.id, "stale", null, now);
183
+ store.decideSubagentSuggestion(offered.id, "stale", null, now);
184
184
  return { ok: false, said: "Its rules changed since it suggested this, so nothing was changed." };
185
185
  }
186
186
  const changed = setToolRules(store, mate, offered.tool, { [offered.action]: { use: offered.rule.use, limit: offered.rule.limit ?? null, undo: current.undo ?? "" } }, answer.by, now);
187
187
  if (!changed.ok)
188
188
  return changed;
189
- store.decideTeammateSuggestion(offered.id, "accepted", answer.by, now);
189
+ store.decideSubagentSuggestion(offered.id, "accepted", answer.by, now);
190
190
  return { ok: true, said: `Changed. ${nameOf(mate)} makes ${offered.action} calls on its own ${offered.rule.limit === undefined ? "from now on" : `up to ${offered.rule.limit.field} ${offered.rule.limit.over}`}.` };
191
191
  }
192
- store.decideTeammateSuggestion(offered.id, "dismissed", answer.by, now);
192
+ store.decideSubagentSuggestion(offered.id, "dismissed", answer.by, now);
193
193
  if (answer.text !== null && answer.text.trim() !== "")
194
194
  remember(store, mate, `About ${offered.action} on ${offered.tool}: ${answer.text.trim()}`.slice(0, MEMORY_CHARS), { source: "person", by: answer.by }, now);
195
195
  return { ok: true, said: "Left as it is." };
@@ -1,13 +1,13 @@
1
1
  import type { ChatBinding, ChatContent, ChatEvent, ChatState } from "./chat-delivery-state.js";
2
- import type { Store, TelegramBinding, TeammateQuestionRow } from "./store.js";
3
- import type { InlineButton } from "./telegram-mate.js";
4
- /** The key notifyPeople gives a teammate's question: flow-card:<card>:teammate-q:<question>:<person>. */
5
- export declare const TEAMMATE_Q_KEY: RegExp;
2
+ import type { Store, TelegramBinding, SubagentQuestionRow } from "./store.js";
3
+ import type { InlineButton } from "./telegram-lead.js";
4
+ /** The key notifyPeople gives a subagent's question: flow-card:<card>:teammate-q:<question>:<person>. */
5
+ export declare const SUBAGENT_Q_KEY: RegExp;
6
6
  export declare const IN_WORDS = "Answer in words";
7
7
  /** The question a notice is about, while it is still open. */
8
- export declare function openQuestionOf(store: Store, dedupeKey: string): TeammateQuestionRow | null;
8
+ export declare function openQuestionOf(store: Store, dedupeKey: string): SubagentQuestionRow | null;
9
9
  /** Buttons for the question, minted before the send (for the person it asks only); `place` stamps the message they land on. */
10
- export declare function telegramQuestionButtons(store: Store, binding: TelegramBinding, question: TeammateQuestionRow, now: Date): {
10
+ export declare function telegramQuestionButtons(store: Store, binding: TelegramBinding, question: SubagentQuestionRow, now: Date): {
11
11
  keyboard: InlineButton[][];
12
12
  tokens: string[];
13
13
  } | null;
@@ -1,32 +1,32 @@
1
1
  /**
2
- * A teammate's question, answered in the chat app (v93).
2
+ * A subagent's question, answered in the chat app (v93).
3
3
  *
4
- * When a teammate asks its person something ("Refund all $200, or half?"),
5
- * the notice reaches them in their chat app under the teammate's name, with
4
+ * When a subagent asks its person something ("Refund all $200, or half?"),
5
+ * the notice reaches them in their chat app under the subagent's name, with
6
6
  * one button per option and one to answer in their own words. A tap answers
7
7
  * at once; "Answer in words" opens a prompt: on Telegram, a reply to it; in
8
8
  * Slack, Discord and Teams, their next message in their chat with Standing
9
9
  * Orders ("cancel" leaves it). Either way the answer goes through the same
10
- * door as the card's own panel (answerTeammateQuestion): once, and only from
10
+ * door as the card's own panel (answerSubagentQuestion): once, and only from
11
11
  * the person it was asked of. Answered anywhere, every button retires.
12
12
  */
13
13
  import { randomBytes } from "node:crypto";
14
14
  import { partContent, savedChatPart } from "./chat-delivery-state.js";
15
- import { answerTeammateQuestion } from "./teammate-work.js";
16
- import { labelOf } from "./teammate-admin.js";
15
+ import { answerSubagentQuestion } from "./subagent-work.js";
16
+ import { labelOf } from "./subagent-admin.js";
17
17
  import { telegramButton } from "./contracts/telegram-callback.js";
18
- /** The key notifyPeople gives a teammate's question: flow-card:<card>:teammate-q:<question>:<person>. */
19
- export const TEAMMATE_Q_KEY = /^flow-card:[1-9][0-9]{0,14}:teammate-q:([1-9][0-9]{0,14}):/;
18
+ /** The key notifyPeople gives a subagent's question: flow-card:<card>:teammate-q:<question>:<person>. */
19
+ export const SUBAGENT_Q_KEY = /^flow-card:[1-9][0-9]{0,14}:teammate-q:([1-9][0-9]{0,14}):/;
20
20
  export const IN_WORDS = "Answer in words";
21
21
  const PROMPT_MS = 30 * 60_000;
22
22
  const ANSWER_CHARS = 2000;
23
23
  /** The question a notice is about, while it is still open. */
24
24
  export function openQuestionOf(store, dedupeKey) {
25
- const match = TEAMMATE_Q_KEY.exec(dedupeKey);
26
- const question = match === null ? null : store.teammateQuestion(Number(match[1]));
25
+ const match = SUBAGENT_Q_KEY.exec(dedupeKey);
26
+ const question = match === null ? null : store.subagentQuestion(Number(match[1]));
27
27
  return question !== null && question.state === "open" ? question : null;
28
28
  }
29
- const who = (store, question) => { const mate = store.getTeammate(question.teammate); return mate === null ? "Your teammate" : labelOf(mate).split(" · ")[0]; };
29
+ const who = (store, question) => { const mate = store.getSubagent(question.subagent); return mate === null ? "Your subagent" : labelOf(mate).split(" · ")[0]; };
30
30
  /** Everyone else's buttons retire once a question is answered anywhere. */
31
31
  function retireEverywhere(store, question, now, state) {
32
32
  store.retireTelegramQuestion(question, now);
@@ -51,7 +51,7 @@ export function telegramQuestionButtons(store, binding, question, now) {
51
51
  export function applyTelegramQuestionTap(store, binding, action, message, now) {
52
52
  if (action.consumedAt !== null || action.expiresAt <= now.toISOString())
53
53
  return [{ kind: "ack", text: "That was already answered, or these buttons are too old." }];
54
- const question = store.teammateQuestion(action.question);
54
+ const question = store.subagentQuestion(action.question);
55
55
  if (question === null || question.state !== "open") {
56
56
  store.retireTelegramQuestion(action.question, now);
57
57
  return [{ kind: "ack", text: "That was already answered." }];
@@ -59,7 +59,7 @@ export function applyTelegramQuestionTap(store, binding, action, message, now) {
59
59
  if (action.choice === null)
60
60
  return [{ kind: "ack", text: "Send your answer" }, { kind: "prompt", question: question.id, placeholder: "Your answer",
61
61
  text: `Your answer to ${who(store, question)}: “${question.question}” Reply to this message.` }];
62
- const answered = answerTeammateQuestion(store, question.id, { choice: action.choice, text: null, by: binding.approver, via: "telegram" }, now);
62
+ const answered = answerSubagentQuestion(store, question.id, { choice: action.choice, text: null, by: binding.approver, via: "telegram" }, now);
63
63
  if (!answered.ok)
64
64
  return [{ kind: "ack", text: answered.said.slice(0, 190) }];
65
65
  retireEverywhere(store, question.id, now);
@@ -75,7 +75,7 @@ export function applyTelegramQuestionReply(store, binding, prompt, text, now) {
75
75
  return "Send the answer itself as a reply.";
76
76
  if (said.length > ANSWER_CHARS)
77
77
  return `Keep it under ${ANSWER_CHARS.toLocaleString("en-US")} characters.`;
78
- const answered = answerTeammateQuestion(store, prompt.question, { choice: null, text: said, by: binding.approver, via: "telegram" }, now);
78
+ const answered = answerSubagentQuestion(store, prompt.question, { choice: null, text: said, by: binding.approver, via: "telegram" }, now);
79
79
  retireEverywhere(store, prompt.question, now);
80
80
  return answered.ok ? `✅ ${answered.said}` : answered.said;
81
81
  }
@@ -117,7 +117,7 @@ export function applyChatQuestionTap(options, event, binding, token, now) {
117
117
  return true;
118
118
  }
119
119
  const questionId = Number(action["question"]), part = Number(action["part"]);
120
- const question = store.teammateQuestion(questionId);
120
+ const question = store.subagentQuestion(questionId);
121
121
  if (action["consumed"] !== null || String(action["expires"]) <= now.toISOString() || question === null || question.state !== "open") {
122
122
  retireEverywhere(store, questionId, now, state);
123
123
  repaint(state, part, event, "This was already answered.");
@@ -132,7 +132,7 @@ export function applyChatQuestionTap(options, event, binding, token, now) {
132
132
  say(`Your next message here is your answer to ${who(store, question)}: “${question.question}” Send “cancel” to leave it.`);
133
133
  return true;
134
134
  }
135
- const answered = answerTeammateQuestion(store, questionId, { choice: String(action["choice"]), text: null, by: binding.approver, via: options.label.toLowerCase() }, now);
135
+ const answered = answerSubagentQuestion(store, questionId, { choice: String(action["choice"]), text: null, by: binding.approver, via: options.label.toLowerCase() }, now);
136
136
  if (!answered.ok) {
137
137
  say(answered.said);
138
138
  return true;
@@ -169,7 +169,7 @@ export function answerChatQuestionPrompt(options, event, binding, input, now) {
169
169
  say(`That's too long to take from here. Keep it under ${ANSWER_CHARS.toLocaleString("en-US")} characters, or answer on the card.`);
170
170
  return true;
171
171
  }
172
- const answered = answerTeammateQuestion(store, questionId, { choice: null, text: said, by: binding.approver, via: options.label.toLowerCase() }, now);
172
+ const answered = answerSubagentQuestion(store, questionId, { choice: null, text: said, by: binding.approver, via: options.label.toLowerCase() }, now);
173
173
  retireEverywhere(store, questionId, now, state);
174
174
  say(answered.ok ? `✅ ${answered.said}` : answered.said);
175
175
  return true;
@@ -1,6 +1,6 @@
1
1
  import type { ToolCaller } from "./flow-actions.js";
2
2
  import { type ProjectTool, type ToolSpec } from "./project-tools.js";
3
- import type { Store, TeammateCallRow, TeammateGrantRow, TeammateRow, ToolActionInfo, ToolRule } from "./store.js";
3
+ import type { Store, SubagentCallRow, SubagentGrantRow, SubagentRow, ToolActionInfo, ToolRule } from "./store.js";
4
4
  /** Lists what a tool offers; injectable so tests never start a server. */
5
5
  export type ToolLister = (spec: ToolSpec, values: Record<string, string>) => Promise<{
6
6
  ok: true;
@@ -32,11 +32,11 @@ export declare function withActions(rules: Record<string, ToolRule>, actions: re
32
32
  rules: Record<string, ToolRule>;
33
33
  };
34
34
  /** The rule that applies to one call with this input, and why, in words. */
35
- export declare function ruleFor(grant: Pick<TeammateGrantRow, "actions" | "rules">, action: string, input: Record<string, unknown>): {
35
+ export declare function ruleFor(grant: Pick<SubagentGrantRow, "actions" | "rules">, action: string, input: Record<string, unknown>): {
36
36
  use: ToolRule["use"];
37
37
  why: string;
38
38
  };
39
- /** A rule in words, for the teammate's turn and its page. */
39
+ /** A rule in words, for the subagent's turn and its page. */
40
40
  export declare function ruleWords(rule: ToolRule): string;
41
41
  /** Number fields an action's input declares: what a limit can be set on. */
42
42
  export declare function numberFields(action: Pick<ToolActionInfo, "input">): string[];
@@ -51,17 +51,17 @@ export type OfferedTool = {
51
51
  input: string;
52
52
  rule: string;
53
53
  };
54
- /** What a teammate may use now: its grants' actions on tools the project still has, "never" left out. */
55
- export declare function offeredTools(store: Store, mate: TeammateRow): OfferedTool[];
54
+ /** What a subagent may use now: its grants' actions on tools the project still has, "never" left out. */
55
+ export declare function offeredTools(store: Store, mate: SubagentRow): OfferedTool[];
56
56
  /** Before a turn: re-list tools whose listing is old (or never happened), so the turn sees what they offer today. A tool that can't be reached keeps its last listing. */
57
- export declare function refreshGrants(store: Store, mate: TeammateRow, now: Date, io: ToolIo): Promise<void>;
58
- /** Let a teammate use one of the project's tools. Its actions start at their defaults: reading is free, everything else asks first. */
59
- export declare function grantTool(store: Store, mate: TeammateRow, tool: string, by: string, now: Date, io?: ToolIo): Promise<Done>;
57
+ export declare function refreshGrants(store: Store, mate: SubagentRow, now: Date, io: ToolIo): Promise<void>;
58
+ /** Let a subagent use one of the project's tools. Its actions start at their defaults: reading is free, everything else asks first. */
59
+ export declare function grantTool(store: Store, mate: SubagentRow, tool: string, by: string, now: Date, io?: ToolIo): Promise<Done>;
60
60
  /** A grant from what the tool offers (or, not reachable now, the names its last test found). */
61
- export declare function grantListed(store: Store, mate: TeammateRow, tool: ProjectTool, actions: ToolActionInfo[] | null, by: string, now: Date): Done;
62
- export declare function revokeTool(store: Store, mate: TeammateRow, tool: string, by: string, now?: Date): Done;
61
+ export declare function grantListed(store: Store, mate: SubagentRow, tool: ProjectTool, actions: ToolActionInfo[] | null, by: string, now: Date): Done;
62
+ export declare function revokeTool(store: Store, mate: SubagentRow, tool: string, by: string, now?: Date): Done;
63
63
  /** Check one rule: an action the tool offers, a known use, and a limit on one of its number fields. */
64
- export declare function checkRule(grant: Pick<TeammateGrantRow, "tool" | "actions">, action: string, rule: {
64
+ export declare function checkRule(grant: Pick<SubagentGrantRow, "tool" | "actions">, action: string, rule: {
65
65
  use: unknown;
66
66
  limit?: {
67
67
  field: unknown;
@@ -76,7 +76,7 @@ export declare function checkRule(grant: Pick<TeammateGrantRow, "tool" | "action
76
76
  said: string;
77
77
  };
78
78
  /** Set the rules for some of a granted tool's actions; the others keep theirs. */
79
- export declare function setToolRules(store: Store, mate: TeammateRow, tool: string, changes: Record<string, {
79
+ export declare function setToolRules(store: Store, mate: SubagentRow, tool: string, changes: Record<string, {
80
80
  use: unknown;
81
81
  limit?: {
82
82
  field: unknown;
@@ -87,17 +87,17 @@ export declare function setToolRules(store: Store, mate: TeammateRow, tool: stri
87
87
  /**
88
88
  * Make one call now: a free one, or one a person approved (exactly as they
89
89
  * saw it). What the tool said is kept on the receipt, secrets scrubbed; a
90
- * tool that says it failed is an answer the teammate reads, not trouble.
90
+ * tool that says it failed is an answer the subagent reads, not trouble.
91
91
  */
92
- export declare function makeCall(store: Store, call: TeammateCallRow, repo: string, io: ToolIo, now: Date, options?: {
92
+ export declare function makeCall(store: Store, call: SubagentCallRow, repo: string, io: ToolIo, now: Date, options?: {
93
93
  byPerson?: boolean;
94
- }): Promise<TeammateCallRow>;
94
+ }): Promise<SubagentCallRow>;
95
95
  /** A receipt in words: what happened to the call. */
96
- export declare function callOutcome(call: TeammateCallRow): string;
96
+ export declare function callOutcome(call: SubagentCallRow): string;
97
97
  /** A receipt as a person reads it on the card: what happened, and who decided. */
98
- export declare function receiptWords(store: Store, call: TeammateCallRow): string;
98
+ export declare function receiptWords(store: Store, call: SubagentCallRow): string;
99
99
  /** The Tools section's form, read into rule changes: every action the grant knows. */
100
- export declare function rulesFromForm(grant: Pick<TeammateGrantRow, "actions">, field: (key: string) => string | null): Record<string, {
100
+ export declare function rulesFromForm(grant: Pick<SubagentGrantRow, "actions">, field: (key: string) => string | null): Record<string, {
101
101
  use: unknown;
102
102
  limit?: {
103
103
  field: unknown;
@@ -1,20 +1,20 @@
1
1
  /**
2
- * The tools a teammate may use (v94), and its rule for each of their actions.
2
+ * The tools a subagent may use (v94), and its rule for each of their actions.
3
3
  *
4
- * A teammate never calls a tool itself. On its turn it may ask for one call
4
+ * A subagent never calls a tool itself. On its turn it may ask for one call
5
5
  * ("use_tool": which action, with what input, and why), and Toolroll
6
6
  * checks the rule its manager set for that action:
7
7
  *
8
- * - do it: the call is made and its answer goes back to the teammate, whose
8
+ * - do it: the call is made and its answer goes back to the subagent, whose
9
9
  * turn goes on;
10
10
  * - ask first: the exact call goes to the zone's person, in their chat app
11
11
  * and on the card. Approve makes exactly that call; Deny doesn't; words
12
- * tell the teammate what to do instead;
12
+ * tell the subagent what to do instead;
13
13
  * - never: the action isn't offered at all.
14
14
  *
15
15
  * "Do it" can ask first above a number in the input ("refunds up to $50"),
16
16
  * so a limit holds in code, not only in the soul file's words. Every call,
17
- * made or not, is a receipt on the card and on the teammate's page.
17
+ * made or not, is a receipt on the card and on the subagent's page.
18
18
  */
19
19
  import { redactSecretLines, scanForSecrets } from "./evidence.js";
20
20
  import { scrubSecrets } from "./flow-secrets.js";
@@ -52,7 +52,7 @@ export function ruleFor(grant, action, input) {
52
52
  }
53
53
  return { use: "free", why: "" };
54
54
  }
55
- /** A rule in words, for the teammate's turn and its page. */
55
+ /** A rule in words, for the subagent's turn and its page. */
56
56
  export function ruleWords(rule) {
57
57
  if (rule.use === "never")
58
58
  return "never";
@@ -91,12 +91,12 @@ export function callWords(tool, action, input, cap = 300) {
91
91
  const line = `${tool} → ${action}${parts.length === 0 ? "" : ` · ${parts.join(" · ")}`}`;
92
92
  return line.length <= cap ? line : `${line.slice(0, cap - 1)}…`;
93
93
  }
94
- /** What a teammate may use now: its grants' actions on tools the project still has, "never" left out. */
94
+ /** What a subagent may use now: its grants' actions on tools the project still has, "never" left out. */
95
95
  export function offeredTools(store, mate) {
96
96
  const present = new Set(projectToolsOf(store, mate.repo).map(one => one.name));
97
97
  // Sprint 8: a tool the organisation policy doesn't allow isn't offered.
98
98
  const policy = store.orgPolicy();
99
- return store.teammateGrants(mate.id).filter(grant => present.has(grant.tool) && toolRefusal(policy, grant.tool) === null).flatMap(grant => grant.actions.flatMap(action => {
99
+ return store.subagentGrants(mate.id).filter(grant => present.has(grant.tool) && toolRefusal(policy, grant.tool) === null).flatMap(grant => grant.actions.flatMap(action => {
100
100
  const rule = grant.rules[action.name] ?? defaultRule(action);
101
101
  if (rule.use === "never")
102
102
  return [];
@@ -107,7 +107,7 @@ export function offeredTools(store, mate) {
107
107
  /** Before a turn: re-list tools whose listing is old (or never happened), so the turn sees what they offer today. A tool that can't be reached keeps its last listing. */
108
108
  export async function refreshGrants(store, mate, now, io) {
109
109
  const tools = projectToolsOf(store, mate.repo);
110
- for (const grant of store.teammateGrants(mate.id)) {
110
+ for (const grant of store.subagentGrants(mate.id)) {
111
111
  if (grant.listedAt !== null && now.getTime() - Date.parse(grant.listedAt) < LISTING_MS)
112
112
  continue;
113
113
  const tool = tools.find(one => one.name === grant.tool);
@@ -116,18 +116,18 @@ export async function refreshGrants(store, mate, now, io) {
116
116
  const listed = await listed_(tool, mate.repo, io);
117
117
  if (!listed.ok)
118
118
  continue;
119
- store.saveTeammateGrant({ teammate: mate.id, tool: grant.tool, ...withActions(grant.rules, listed.actions), listedAt: now.toISOString() }, grant.updatedBy, now);
119
+ store.saveSubagentGrant({ subagent: mate.id, tool: grant.tool, ...withActions(grant.rules, listed.actions), listedAt: now.toISOString() }, grant.updatedBy, now);
120
120
  }
121
121
  }
122
122
  const listed_ = (tool, repo, io) => (io.listTools ?? ((spec, values) => listProjectToolActions(spec, values, { timeoutMs: 60_000, omitEnv: ALL_CREDENTIAL_ENV })))(tool.spec, readToolSecrets(repo, tool.name, io.toolHome));
123
123
  /** Names only, from the tool's last test: what a grant starts with when it can't be listed right now. */
124
124
  const namesOnly = (tool) => (tool.lastTest?.tools ?? []).map(name => ({ name, about: "", input: null, readOnly: false }));
125
- /** Let a teammate use one of the project's tools. Its actions start at their defaults: reading is free, everything else asks first. */
125
+ /** Let a subagent use one of the project's tools. Its actions start at their defaults: reading is free, everything else asks first. */
126
126
  export async function grantTool(store, mate, tool, by, now, io = {}) {
127
127
  const found = projectToolsOf(store, mate.repo).find(one => one.name === tool);
128
128
  if (found === undefined)
129
129
  return { ok: false, said: `This project has no tool called ${tool}. Add it on the Tools page first.` };
130
- if (store.teammateGrant(mate.id, tool) !== null)
130
+ if (store.subagentGrant(mate.id, tool) !== null)
131
131
  return { ok: true, said: `It can already use ${tool}.` };
132
132
  const listed = await listed_(found, mate.repo, io);
133
133
  return grantListed(store, mate, found, listed.ok ? listed.actions : null, by, now);
@@ -137,18 +137,18 @@ export function grantListed(store, mate, tool, actions, by, now) {
137
137
  const offered = actions ?? namesOnly(tool);
138
138
  if (offered.length === 0)
139
139
  return { ok: false, said: `${tool.name} didn't say what it can do. Test it on the Tools page, then try again.` };
140
- store.saveTeammateGrant({ teammate: mate.id, tool: tool.name, ...withActions({}, offered), listedAt: actions === null ? null : now.toISOString() }, by, now);
140
+ store.saveSubagentGrant({ subagent: mate.id, tool: tool.name, ...withActions({}, offered), listedAt: actions === null ? null : now.toISOString() }, by, now);
141
141
  const free = offered.filter(one => defaultRule(one).use === "free").length;
142
142
  return { ok: true, said: `It can use ${tool.name} now: ${free} of its ${offered.length} action${offered.length === 1 ? "" : "s"} freely (the ones that only read), and the rest after a person approves each call. Change that under Tools.` };
143
143
  }
144
144
  export function revokeTool(store, mate, tool, by, now = new Date()) {
145
- for (const call of store.teammateCallsOf(mate.id, 200).filter(one => one.tool === tool && one.state === "asked")) {
146
- store.moveTeammateCall(call.id, ["asked"], { state: "refused", result: `It can't use ${tool} any more.` }, new Date());
147
- const question = store.teammateQuestionForCall(call.id);
145
+ for (const call of store.subagentCallsOf(mate.id, 200).filter(one => one.tool === tool && one.state === "asked")) {
146
+ store.moveSubagentCall(call.id, ["asked"], { state: "refused", result: `It can't use ${tool} any more.` }, new Date());
147
+ const question = store.subagentQuestionForCall(call.id);
148
148
  if (question !== null)
149
- store.dropTeammateQuestion(question.id, new Date());
149
+ store.dropSubagentQuestion(question.id, new Date());
150
150
  }
151
- return store.dropTeammateGrant(mate.id, tool, by, now) ? { ok: true, said: `It can't use ${tool} any more.` } : { ok: true, said: `It wasn't using ${tool}.` };
151
+ return store.dropSubagentGrant(mate.id, tool, by, now) ? { ok: true, said: `It can't use ${tool} any more.` } : { ok: true, said: `It wasn't using ${tool}.` };
152
152
  }
153
153
  /** Check one rule: an action the tool offers, a known use, and a limit on one of its number fields. */
154
154
  export function checkRule(grant, action, rule) {
@@ -176,7 +176,7 @@ export function checkRule(grant, action, rule) {
176
176
  }
177
177
  /** Set the rules for some of a granted tool's actions; the others keep theirs. */
178
178
  export function setToolRules(store, mate, tool, changes, by, now) {
179
- const grant = store.teammateGrant(mate.id, tool);
179
+ const grant = store.subagentGrant(mate.id, tool);
180
180
  if (grant === null)
181
181
  return { ok: false, said: `It doesn't use ${tool}. Let it use ${tool} first.` };
182
182
  const rules = { ...grant.rules };
@@ -186,35 +186,35 @@ export function setToolRules(store, mate, tool, changes, by, now) {
186
186
  return { ok: false, said: checked.said };
187
187
  rules[action] = checked.rule;
188
188
  }
189
- store.saveTeammateGrant({ teammate: mate.id, tool, actions: grant.actions, rules }, by, now);
189
+ store.saveSubagentGrant({ subagent: mate.id, tool, actions: grant.actions, rules }, by, now);
190
190
  return { ok: true, said: "Saved. Its next turn uses these rules." };
191
191
  }
192
192
  const blank = (text) => redactSecretLines(text, scanForSecrets(text));
193
193
  /**
194
194
  * Make one call now: a free one, or one a person approved (exactly as they
195
195
  * saw it). What the tool said is kept on the receipt, secrets scrubbed; a
196
- * tool that says it failed is an answer the teammate reads, not trouble.
196
+ * tool that says it failed is an answer the subagent reads, not trouble.
197
197
  */
198
198
  export async function makeCall(store, call, repo, io, now, options = {}) {
199
199
  // Its rules are read again at the moment of the call: a tool taken away, or an action set to never, since it was approved stops it.
200
- // (A person's own undo (v97) needs the tool still granted, not the teammate's rule for that action.)
201
- const grant = store.teammateGrant(call.teammate, call.tool);
200
+ // (A person's own undo (v97) needs the tool still granted, not the subagent's rule for that action.)
201
+ const grant = store.subagentGrant(call.subagent, call.tool);
202
202
  if (grant === null || (options.byPerson !== true && ruleFor(grant, call.action, call.input).use === "never")) {
203
- store.moveTeammateCall(call.id, ["approved", "running"], { state: "refused", result: "Its rules changed before the call was made." }, now);
204
- return store.teammateCall(call.id);
203
+ store.moveSubagentCall(call.id, ["approved", "running"], { state: "refused", result: "Its rules changed before the call was made." }, now);
204
+ return store.subagentCall(call.id);
205
205
  }
206
206
  // Sprint 8: nor does a call to a tool the organisation policy doesn't allow (a person's undo included).
207
207
  const disallowed = toolRefusal(store.orgPolicy(), call.tool);
208
208
  if (disallowed !== null) {
209
- store.moveTeammateCall(call.id, ["approved", "running"], { state: "refused", result: disallowed }, now);
210
- return store.teammateCall(call.id);
209
+ store.moveSubagentCall(call.id, ["approved", "running"], { state: "refused", result: disallowed }, now);
210
+ return store.subagentCall(call.id);
211
211
  }
212
- if (call.state !== "running" && !store.moveTeammateCall(call.id, ["approved"], { state: "running" }, now))
213
- return store.teammateCall(call.id);
212
+ if (call.state !== "running" && !store.moveSubagentCall(call.id, ["approved"], { state: "running" }, now))
213
+ return store.subagentCall(call.id);
214
214
  const tool = projectToolsOf(store, repo).find(one => one.name === call.tool);
215
215
  if (tool === undefined) {
216
- store.moveTeammateCall(call.id, ["running"], { state: "failed", result: `There's no tool called ${call.tool} in this project any more.` }, now);
217
- return store.teammateCall(call.id);
216
+ store.moveSubagentCall(call.id, ["running"], { state: "failed", result: `There's no tool called ${call.tool} in this project any more.` }, now);
217
+ return store.subagentCall(call.id);
218
218
  }
219
219
  const values = readToolSecrets(repo, tool.name, io.toolHome);
220
220
  let answer;
@@ -226,8 +226,8 @@ export async function makeCall(store, call, repo, io, now, options = {}) {
226
226
  }
227
227
  const text = answer.ok ? blank(scrubSecrets(answer.text, values)).trim() : answer.problem;
228
228
  const kept = text.length <= RESULT_CHARS ? text : `${text.slice(0, RESULT_CHARS - 1)}…`;
229
- store.moveTeammateCall(call.id, ["running"], { state: answer.ok && !answer.isError ? "done" : "failed", result: kept || (answer.ok ? "(no answer)" : "It couldn't be reached.") }, now);
230
- return store.teammateCall(call.id);
229
+ store.moveSubagentCall(call.id, ["running"], { state: answer.ok && !answer.isError ? "done" : "failed", result: kept || (answer.ok ? "(no answer)" : "It couldn't be reached.") }, now);
230
+ return store.subagentCall(call.id);
231
231
  }
232
232
  /** A receipt in words: what happened to the call. */
233
233
  export function callOutcome(call) {
@@ -245,15 +245,15 @@ export function callOutcome(call) {
245
245
  export function receiptWords(store, call) {
246
246
  switch (call.state) {
247
247
  case "asked": {
248
- const question = store.teammateQuestionForCall(call.id);
248
+ const question = store.subagentQuestionForCall(call.id);
249
249
  return `Waiting for ${question?.askedOf ?? "a person"} to approve`;
250
250
  }
251
251
  case "approved":
252
252
  case "running": return call.decidedBy === null ? "Making it now" : `${call.decidedBy} approved · making it now`;
253
- case "done": return call.undoneBy !== null ? `Done · undone by ${call.undoneBy}` : call.undoOf !== null ? `Undid ${store.teammateCall(call.undoOf)?.action ?? "a call"} · done` : call.decidedBy === null ? "Done" : `${call.decidedBy} approved · done`;
253
+ case "done": return call.undoneBy !== null ? `Done · undone by ${call.undoneBy}` : call.undoOf !== null ? `Undid ${store.subagentCall(call.undoOf)?.action ?? "a call"} · done` : call.decidedBy === null ? "Done" : `${call.decidedBy} approved · done`;
254
254
  case "failed": return call.decidedBy === null ? "Failed" : `${call.decidedBy} approved · failed`;
255
255
  case "denied": {
256
- const said = store.teammateQuestionForCall(call.id)?.answer;
256
+ const said = store.subagentQuestionForCall(call.id)?.answer;
257
257
  return `${call.decidedBy ?? "A person"} said no${said ? `: ${said}` : ""}`;
258
258
  }
259
259
  default: return `Not made: ${call.result ?? "outside its rules"}`;