toolroll 0.9.55 → 0.9.57

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 (223) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/README.md +24 -8
  3. package/dist/action-ledger.d.ts +2 -4
  4. package/dist/action-ledger.js +2 -10
  5. package/dist/approval-policy.d.ts +5 -5
  6. package/dist/approval-policy.js +4 -4
  7. package/dist/approval-rules-ui.js +2 -2
  8. package/dist/assignment-adapters.d.ts +5 -0
  9. package/dist/assignment.d.ts +24 -3
  10. package/dist/assignment.js +36 -10
  11. package/dist/browser/workspace.js +5 -5
  12. package/dist/browser-workspace.d.ts +12 -12
  13. package/dist/browser-workspace.js +1 -1
  14. package/dist/budget-alerts.js +3 -3
  15. package/dist/chat-actions.d.ts +23 -18
  16. package/dist/chat-actions.js +110 -88
  17. package/dist/chat-ask.d.ts +2 -2
  18. package/dist/chat-ask.js +5 -5
  19. package/dist/chat-channel.d.ts +15 -15
  20. package/dist/chat-channel.js +20 -20
  21. package/dist/chat-controls.d.ts +0 -4
  22. package/dist/chat-controls.js +0 -1
  23. package/dist/chat-core.js +1 -1
  24. package/dist/chat-delivery-state.js +2 -2
  25. package/dist/chat-delivery.d.ts +2 -2
  26. package/dist/chat-delivery.js +30 -37
  27. package/dist/chat-flow.js +3 -3
  28. package/dist/chat-messages.d.ts +1 -1
  29. package/dist/chat-messages.js +4 -4
  30. package/dist/chat-migration.d.ts +1 -1
  31. package/dist/chat-migration.js +11 -11
  32. package/dist/chat-rooms.js +3 -3
  33. package/dist/chat-voice.js +1 -1
  34. package/dist/chat-warmth.d.ts +2 -2
  35. package/dist/check-levels.d.ts +3 -0
  36. package/dist/check-levels.js +5 -0
  37. package/dist/cli.d.ts +1 -1
  38. package/dist/cli.js +6 -7
  39. package/dist/contracts/chat-actions.d.ts +32 -27
  40. package/dist/contracts/chat-actions.js +29 -11
  41. package/dist/contracts/chat-content.d.ts +1 -1
  42. package/dist/contracts/chat-content.js +1 -1
  43. package/dist/contracts/chat-tables.js +4 -4
  44. package/dist/contracts/console-api.d.ts +6 -6
  45. package/dist/contracts/console-api.js +7 -7
  46. package/dist/contracts/flow-propose.d.ts +3 -3
  47. package/dist/contracts/flow.d.ts +132 -125
  48. package/dist/contracts/flow.js +27 -12
  49. package/dist/contracts/lead-context.d.ts +1 -1
  50. package/dist/contracts/lead-context.js +2 -2
  51. package/dist/contracts/lead-tools.d.ts +20 -18
  52. package/dist/contracts/lead-tools.js +15 -15
  53. package/dist/contracts/stage-output.d.ts +1 -1
  54. package/dist/contracts/stage-output.js +1 -1
  55. package/dist/contracts/store-json.d.ts +23 -22
  56. package/dist/contracts/store-json.js +17 -17
  57. package/dist/contracts/{teammate-turn.d.ts → subagent-turn.d.ts} +5 -5
  58. package/dist/contracts/{teammate-turn.js → subagent-turn.js} +7 -7
  59. package/dist/converse.d.ts +23 -23
  60. package/dist/converse.js +28 -28
  61. package/dist/coordinator-proposals.d.ts +2 -2
  62. package/dist/coordinator-proposals.js +1 -1
  63. package/dist/coordinator.js +1 -1
  64. package/dist/deprecations.d.ts +12 -0
  65. package/dist/deprecations.js +20 -0
  66. package/dist/desktop-update-gate.js +8 -4
  67. package/dist/desktop-update.js +6 -1
  68. package/dist/discord-chat.js +6 -6
  69. package/dist/dispatch.d.ts +1 -1
  70. package/dist/dispatch.js +1 -1
  71. package/dist/dispose.js +0 -5
  72. package/dist/envelope.js +0 -1
  73. package/dist/export-ui.js +1 -1
  74. package/dist/export.js +7 -7
  75. package/dist/flow-engine.d.ts +2 -2
  76. package/dist/flow-engine.js +21 -21
  77. package/dist/flow-insights.d.ts +1 -1
  78. package/dist/flow-share.js +13 -8
  79. package/dist/flow-steps.d.ts +5 -5
  80. package/dist/flow-steps.js +19 -19
  81. package/dist/flow-triggers.d.ts +1 -1
  82. package/dist/flow-triggers.js +1 -1
  83. package/dist/flows-cli.js +1 -1
  84. package/dist/flows-ui.js +20 -20
  85. package/dist/flows.js +19 -19
  86. package/dist/guides.js +4 -3
  87. package/dist/invoke.js +1 -1
  88. package/dist/kits-ui.js +5 -5
  89. package/dist/kits.d.ts +12 -12
  90. package/dist/kits.js +31 -31
  91. package/dist/{mate-cli.d.ts → lead-cli.d.ts} +11 -11
  92. package/dist/{mate-cli.js → lead-cli.js} +38 -38
  93. package/dist/lead-commitments.js +4 -4
  94. package/dist/lead-context.d.ts +2 -2
  95. package/dist/lead-context.js +9 -9
  96. package/dist/{mate-contract.d.ts → lead-contract.d.ts} +3 -3
  97. package/dist/{mate-contract.js → lead-contract.js} +7 -6
  98. package/dist/{mate-doors.d.ts → lead-doors.d.ts} +6 -6
  99. package/dist/{mate-doors.js → lead-doors.js} +24 -24
  100. package/dist/lead-follow.d.ts +5 -5
  101. package/dist/lead-follow.js +9 -9
  102. package/dist/lead-people.d.ts +5 -5
  103. package/dist/lead-people.js +14 -14
  104. package/dist/{mate-progress.d.ts → lead-progress.d.ts} +9 -9
  105. package/dist/{mate-progress.js → lead-progress.js} +3 -3
  106. package/dist/lead-status.d.ts +1 -1
  107. package/dist/lead-status.js +2 -2
  108. package/dist/{mate-tools.d.ts → lead-tools.d.ts} +19 -19
  109. package/dist/{mate-tools.js → lead-tools.js} +109 -101
  110. package/dist/{mate.d.ts → lead.d.ts} +27 -27
  111. package/dist/{mate.js → lead.js} +102 -102
  112. package/dist/limits-ui.d.ts +1 -1
  113. package/dist/limits-ui.js +1 -1
  114. package/dist/mcp-connect.d.ts +1 -1
  115. package/dist/mcp-connect.js +3 -3
  116. package/dist/mcp-core.js +1 -1
  117. package/dist/memory-pass.d.ts +2 -2
  118. package/dist/memory-pass.js +7 -7
  119. package/dist/notification-rows.d.ts +2 -2
  120. package/dist/operate.d.ts +3 -3
  121. package/dist/operate.js +52 -42
  122. package/dist/policy.d.ts +1 -1
  123. package/dist/principal.d.ts +1 -1
  124. package/dist/principal.js +2 -2
  125. package/dist/project-delete-ui.js +1 -1
  126. package/dist/project-delete.d.ts +1 -1
  127. package/dist/project-delete.js +26 -26
  128. package/dist/project-memory.js +1 -1
  129. package/dist/project-tools.d.ts +1 -1
  130. package/dist/project-tools.js +1 -1
  131. package/dist/proof.d.ts +9 -0
  132. package/dist/proof.js +12 -0
  133. package/dist/recipe-ui.js +1 -1
  134. package/dist/release-coverage.d.ts +16 -0
  135. package/dist/release-coverage.js +92 -0
  136. package/dist/retention.js +4 -4
  137. package/dist/scope.d.ts +2 -2
  138. package/dist/scout-report.d.ts +1 -1
  139. package/dist/scout-report.js +1 -1
  140. package/dist/serve.js +40 -45
  141. package/dist/server/chat.d.ts +4 -4
  142. package/dist/server/chat.js +105 -103
  143. package/dist/server/chrome.js +3 -3
  144. package/dist/server/flows.js +69 -62
  145. package/dist/server/guards.js +3 -3
  146. package/dist/server/http.d.ts +3 -3
  147. package/dist/server/http.js +1 -1
  148. package/dist/server/live.js +6 -6
  149. package/dist/server/people-tokens.js +1 -1
  150. package/dist/server/remote.js +12 -10
  151. package/dist/server/render-chat.d.ts +30 -30
  152. package/dist/server/render-chat.js +33 -33
  153. package/dist/server/render-pages.js +2 -2
  154. package/dist/server/render-results.d.ts +4 -1
  155. package/dist/server/render-results.js +23 -9
  156. package/dist/server/render-settings.d.ts +7 -0
  157. package/dist/server/render-settings.js +3 -0
  158. package/dist/server/route-table.js +9 -7
  159. package/dist/server/runtime.d.ts +13 -13
  160. package/dist/server/settings.js +14 -13
  161. package/dist/server/tasks.js +34 -30
  162. package/dist/setup-guide.d.ts +2 -2
  163. package/dist/slack-chat.d.ts +2 -2
  164. package/dist/slack-chat.js +6 -6
  165. package/dist/spend-ui.d.ts +3 -3
  166. package/dist/spend-ui.js +9 -9
  167. package/dist/spend.d.ts +14 -14
  168. package/dist/spend.js +31 -31
  169. package/dist/store-baseline.d.ts +19 -0
  170. package/dist/store-baseline.js +2873 -0
  171. package/dist/store.d.ts +200 -254
  172. package/dist/store.js +830 -3152
  173. package/dist/subagent-admin.d.ts +53 -0
  174. package/dist/{teammate-admin.js → subagent-admin.js} +37 -37
  175. package/dist/{teammate-desk.d.ts → subagent-desk.d.ts} +22 -23
  176. package/dist/{teammate-desk.js → subagent-desk.js} +26 -35
  177. package/dist/{teammate-memory.d.ts → subagent-memory.d.ts} +17 -17
  178. package/dist/{teammate-memory.js → subagent-memory.js} +41 -41
  179. package/dist/{teammate-question.d.ts → subagent-question.d.ts} +6 -6
  180. package/dist/{teammate-question.js → subagent-question.js} +17 -17
  181. package/dist/{teammate-tools.d.ts → subagent-tools.d.ts} +18 -18
  182. package/dist/{teammate-tools.js → subagent-tools.js} +36 -36
  183. package/dist/{teammate-week.d.ts → subagent-week.d.ts} +10 -10
  184. package/dist/{teammate-week.js → subagent-week.js} +23 -23
  185. package/dist/{teammate-work.d.ts → subagent-work.d.ts} +21 -21
  186. package/dist/{teammate-work.js → subagent-work.js} +50 -50
  187. package/dist/subagents-ui.d.ts +22 -0
  188. package/dist/{teammates-ui.js → subagents-ui.js} +45 -45
  189. package/dist/{teammates.d.ts → subagents.d.ts} +11 -11
  190. package/dist/{teammates.js → subagents.js} +21 -21
  191. package/dist/subscription-chat.d.ts +13 -13
  192. package/dist/subscription-chat.js +19 -19
  193. package/dist/surface.d.ts +19 -2
  194. package/dist/surface.js +7 -31
  195. package/dist/task-outcome-cli.js +3 -1
  196. package/dist/task-status.d.ts +59 -7
  197. package/dist/task-status.js +132 -16
  198. package/dist/team-cli.d.ts +1 -0
  199. package/dist/team-cli.js +14 -2
  200. package/dist/team-leads.js +13 -13
  201. package/dist/team-runtime.d.ts +2 -2
  202. package/dist/team-runtime.js +9 -9
  203. package/dist/teams-chat.js +6 -6
  204. package/dist/telegram-flow.d.ts +3 -3
  205. package/dist/telegram-flow.js +3 -3
  206. package/dist/{telegram-mate.d.ts → telegram-lead.d.ts} +5 -5
  207. package/dist/{telegram-mate.js → telegram-lead.js} +27 -27
  208. package/dist/telegram-status.d.ts +11 -4
  209. package/dist/telegram-status.js +18 -11
  210. package/dist/telegram-team.d.ts +1 -1
  211. package/dist/telegram-team.js +5 -5
  212. package/dist/telegram.d.ts +1 -1
  213. package/dist/telegram.js +13 -34
  214. package/dist/text-limits.d.ts +18 -18
  215. package/dist/text-limits.js +18 -18
  216. package/dist/toolroll-update.d.ts +8 -0
  217. package/dist/toolroll-update.js +45 -8
  218. package/dist/work-index.d.ts +6 -1
  219. package/dist/work-index.js +50 -8
  220. package/dist/workspace-ui.js +2 -1
  221. package/package.json +1 -2
  222. package/dist/teammate-admin.d.ts +0 -53
  223. package/dist/teammates-ui.d.ts +0 -21
@@ -20,7 +20,7 @@ export declare function limitsView(windows: readonly {
20
20
  observedAt: string;
21
21
  }[], budgets: readonly BudgetState[], names: {
22
22
  project: (repo: string) => string;
23
- teammate: (id: number) => string;
23
+ subagent: (id: number) => string;
24
24
  }, now: Date): BrowserLimits | null;
25
25
  /** The same tiles for the page without scripts. */
26
26
  export declare function limitsHtml(limits: BrowserLimits | null): Html;
package/dist/limits-ui.js CHANGED
@@ -38,7 +38,7 @@ export function limitsView(windows, budgets, names, now) {
38
38
  for (const budget of budgets) {
39
39
  const over = budget.spentMicrousd >= budget.limitMicrousd;
40
40
  const name = budget.scope === "installation" ? "Everything" : budget.scope === "project" ? names.project(budget.key)
41
- : budget.scope === "teammate" ? names.teammate(Number(budget.key)) : budget.key;
41
+ : budget.scope === "subagent" ? names.subagent(Number(budget.key)) : budget.key;
42
42
  tiles.push({
43
43
  key: `budget:${budget.id}`, name, window: "Budget", value: usd(budget.spentMicrousd), unit: `of ${usd(budget.limitMicrousd)}`,
44
44
  percent: budget.percent, tone: over ? (budget.hardStop ? "danger" : "warning") : budget.percent >= 80 ? "warning" : "neutral", marks: [50, 80], href: "/spend",
@@ -159,7 +159,7 @@ export declare function finishConnect(store: Store, visit: ConnectVisit, code: s
159
159
  ok: false;
160
160
  said: string;
161
161
  }>;
162
- /** Keep connected services signed in: any token expiring within ten minutes is refreshed (the worker's pass, and before a teammate's call). */
162
+ /** Keep connected services signed in: any token expiring within ten minutes is refreshed (the worker's pass, and before a subagent's call). */
163
163
  export declare function refreshConnections(store: Store, repos: readonly string[], now: Date, options?: {
164
164
  fetcher?: Fetch;
165
165
  home?: string;
@@ -8,7 +8,7 @@
8
8
  * with this console's callback, and sends the person to the service to sign
9
9
  * in. The callback trades the code for tokens, which live in the tool's own
10
10
  * secrets file (never the database, never a log), and the tool joins the
11
- * project like any other: tested, listed, and given to teammates under rules.
11
+ * project like any other: tested, listed, and given to subagents under rules.
12
12
  * The worker refreshes tokens before they expire.
13
13
  */
14
14
  import { createHash, randomBytes } from "node:crypto";
@@ -382,10 +382,10 @@ export async function finishConnect(store, visit, code, now, options = {}) {
382
382
  if (options.test === false)
383
383
  return { ok: true, said: `${service.label} is connected to ${to}.` };
384
384
  const tested = await testToolOf(store, visit.repo, spec.name, now, { home, ...(options.omitEnv === undefined ? {} : { omitEnv: options.omitEnv }) });
385
- return tested?.ok ? { ok: true, said: `${service.label} is connected to ${to}: ${tested.tools.length} action${tested.tools.length === 1 ? "" : "s"}. Let a teammate use it from its page.` }
385
+ return tested?.ok ? { ok: true, said: `${service.label} is connected to ${to}: ${tested.tools.length} action${tested.tools.length === 1 ? "" : "s"}. Let a subagent use it from its page.` }
386
386
  : { ok: true, said: `${service.label} is signed in for ${to}, but its test didn't pass yet: ${tested?.problem ?? "no answer"}.` };
387
387
  }
388
- /** Keep connected services signed in: any token expiring within ten minutes is refreshed (the worker's pass, and before a teammate's call). */
388
+ /** Keep connected services signed in: any token expiring within ten minutes is refreshed (the worker's pass, and before a subagent's call). */
389
389
  export async function refreshConnections(store, repos, now, options = {}) {
390
390
  const fetcher = options.fetcher ?? fetch, home = options.home ?? homedir();
391
391
  const report = { refreshed: 0, problems: [] };
package/dist/mcp-core.js CHANGED
@@ -17,7 +17,7 @@ import { GATEWAY_TOOL_INPUTS, GATEWAY_TOOL_OUTPUTS } from "./contracts/gateway-t
17
17
  import { reportToolOutput } from "./contracts/lead-tools.js";
18
18
  import { PACKAGE_VERSION } from "./version.js";
19
19
  import { authenticateCoordinator, fileCoordinatorProposal, statusFor, listTasksFor, taskDetailFor, } from "./coordinator.js";
20
- import { ISO_STAMP_RULE, decisionOver, decisionsOver, labelRepos, queueOver, recapOver } from "./mate-tools.js";
20
+ import { ISO_STAMP_RULE, decisionOver, decisionsOver, labelRepos, queueOver, recapOver } from "./lead-tools.js";
21
21
  import { proposeAsCoordinator } from "./coordinator-proposals.js";
22
22
  export const MODERN = "2026-07-28";
23
23
  export const LEGACY = "2025-11-25";
@@ -1,5 +1,5 @@
1
1
  import type { Store } from './store.js';
2
- import { performSubscriptionMateRequest } from './subscription-chat.js';
2
+ import { performSubscriptionLeadRequest } from './subscription-chat.js';
3
3
  import { type MemoryProposal, type Verdict } from './contracts/memory-pass.js';
4
4
  export type { MemoryProposal, Verdict };
5
5
  /** One session's trace, in characters (TEXT_LIMITS.memoryTrace). */
@@ -66,7 +66,7 @@ export declare function defaultAnalyzer(store: Store, options: {
66
66
  env?: NodeJS.ProcessEnv;
67
67
  fetcher?: typeof fetch;
68
68
  timeoutMs?: number;
69
- runner?: Parameters<typeof performSubscriptionMateRequest>[1];
69
+ runner?: Parameters<typeof performSubscriptionLeadRequest>[1];
70
70
  }): MemoryAnalyzer;
71
71
  /**
72
72
  * Read the analyser's answer with the tolerant parse-side schema, then keep only claims whose quote
@@ -17,8 +17,8 @@ import { basename, join } from 'node:path';
17
17
  import { scanForSecrets, readVerifiedArtifact } from './evidence.js';
18
18
  import { changeKnowledge, knowledgeView } from './project-knowledge.js';
19
19
  import { listDecisions, recordDecision } from './project-memory.js';
20
- import { composeMateRequest, performMateRequest, isDirectChatProvider, CHAT_KEY_ENV } from './converse.js';
21
- import { performSubscriptionMateRequest } from './subscription-chat.js';
20
+ import { composeLeadRequest, performLeadRequest, isDirectChatProvider, CHAT_KEY_ENV } from './converse.js';
21
+ import { performSubscriptionLeadRequest } from './subscription-chat.js';
22
22
  import { TEXT_LIMITS } from './text-limits.js';
23
23
  import { contractError, parseContract } from './contracts/contract.js';
24
24
  import { MEMORY_VERDICT_MODEL_SCHEMA, MEMORY_VERDICT_VERSION, memoryEvidenceSchema, memoryProposalSchema, memoryVerdictReadSchema, readSavedVerdict, savedVerdictSchema } from './contracts/memory-pass.js';
@@ -138,11 +138,11 @@ function fileSources(repo, kind, home) {
138
138
  /** The plane's own sessions: lead threads that touched the project, and finished crew runs with their handoff and check output. */
139
139
  function planeSources(store, repo, evidenceRoot) {
140
140
  const out = [];
141
- const threads = store.handle.prepare(`SELECT c.thread AS thread, c.id AS conversation, MAX(m.id) AS last, MAX(m.created_at) AS at FROM team_conversation c JOIN mate_message m ON m.thread=c.thread
141
+ const threads = store.handle.prepare(`SELECT c.thread AS thread, c.id AS conversation, MAX(m.id) AS last, MAX(m.created_at) AS at FROM team_conversation c JOIN lead_message m ON m.thread=c.thread
142
142
  WHERE EXISTS (SELECT 1 FROM json_each(c.projects_json) WHERE value=?) GROUP BY c.thread`).all(repo);
143
143
  for (const row of threads) {
144
144
  const thread = Number(row['thread']);
145
- out.push({ id: `lead:${thread}:${Number(row['last'])}`, repo, kind: 'lead', source: `conversation:${String(row['conversation'])}`, at: String(row['at']), trace: () => redact(store.handle.prepare('SELECT role,text FROM mate_message WHERE thread=? ORDER BY id LIMIT 400').all(thread).map(m => `${m['role']}: ${clip(String(m['text']), 4000)}`).join('\n')) });
145
+ out.push({ id: `lead:${thread}:${Number(row['last'])}`, repo, kind: 'lead', source: `conversation:${String(row['conversation'])}`, at: String(row['at']), trace: () => redact(store.handle.prepare('SELECT role,text FROM lead_message WHERE thread=? ORDER BY id LIMIT 400').all(thread).map(m => `${m['role']}: ${clip(String(m['text']), 4000)}`).join('\n')) });
146
146
  }
147
147
  const runs = store.handle.prepare(`SELECT r.id, r.role, r.finished_at, r.handoff, t.external_id FROM run r JOIN task_ref t ON t.id=r.task_ref WHERE t.repo=? AND r.role IN ('builder','repair') AND r.outcome IS NOT NULL ORDER BY r.id DESC LIMIT 100`).all(repo);
148
148
  for (const row of runs) {
@@ -207,12 +207,12 @@ export function defaultAnalyzer(store, options) {
207
207
  }
208
208
  if (!key)
209
209
  return { ok: false, problem: `No ${config.provider} key is available for the backward pass.` };
210
- const request = composeMateRequest({ provider: config.provider, model: config.model, key, system, dataDocument, history, tools: [] });
211
- const answer = await performMateRequest(request, config.provider, AbortSignal.timeout(options.timeoutMs ?? 120_000), options.fetcher);
210
+ const request = composeLeadRequest({ provider: config.provider, model: config.model, key, system, dataDocument, history, tools: [] });
211
+ const answer = await performLeadRequest(request, config.provider, AbortSignal.timeout(options.timeoutMs ?? 120_000), options.fetcher);
212
212
  return answer.ok ? { ok: true, text: answer.answer.text } : { ok: false, problem: answer.problem };
213
213
  }
214
214
  // The verdict's own schema is the harness's structured output, so the answer is the verdict itself.
215
- const answer = await performSubscriptionMateRequest({ provider: config.provider, model: config.model, system, dataDocument, history, tools: [], outputSchema: MEMORY_VERDICT_MODEL_SCHEMA, timeoutMs: options.timeoutMs ?? 180_000 }, options.runner);
215
+ const answer = await performSubscriptionLeadRequest({ provider: config.provider, model: config.model, system, dataDocument, history, tools: [], outputSchema: MEMORY_VERDICT_MODEL_SCHEMA, timeoutMs: options.timeoutMs ?? 180_000 }, options.runner);
216
216
  return answer.ok ? { ok: true, text: answer.answer.text } : { ok: false, problem: answer.problem };
217
217
  };
218
218
  }
@@ -1,11 +1,11 @@
1
1
  /** Saved notifications, read and told apart without a store: the row readers, the lifecycle key and the predicates
2
2
  * the store and the chat core (chat-messages.ts) share. A leaf: it imports types only. */
3
- import type { MateProposal, Notification, NotificationReceipt } from "./store.js";
3
+ import type { LeadProposal, Notification, NotificationReceipt } from "./store.js";
4
4
  /** The one task a card is about: a task its confirmation created (a new
5
5
  * task, a revision), else the task it names (and, for feedback on a result,
6
6
  * that result). Null for a card about no single task. A pointer for
7
7
  * replies, never an authority. */
8
- export declare function proposalTaskOf(proposal: MateProposal | null): {
8
+ export declare function proposalTaskOf(proposal: LeadProposal | null): {
9
9
  task: string;
10
10
  run: number | null;
11
11
  } | null;
package/dist/operate.d.ts CHANGED
@@ -7,7 +7,7 @@ import type { FetchLike } from "./flow-share.js";
7
7
  import { type Store } from "./store.js";
8
8
  import { type DispatchAdapter } from "./sync.js";
9
9
  import { type TelegramTransport } from "./telegram.js";
10
- import { type MateCliSeams } from "./mate-cli.js";
10
+ import { type LeadCliSeams } from "./lead-cli.js";
11
11
  import { type Principal, type RemoteSource } from "./operate-remote.js";
12
12
  import { type PublishExec } from "./publish.js";
13
13
  import { type Runner as CommandRunner } from "./builder.js";
@@ -71,8 +71,8 @@ export type OperateOptions = {
71
71
  flowFetch?: FetchLike;
72
72
  /** Injected by tests: how `integrations` checks reach services (fetch, gh, sign-in checks, mail servers). */
73
73
  integrationIo?: Partial<IntegrationIo>;
74
- /** Injected by tests: the mate's provider fetch, key environment, and stdin lines. */
75
- mateSeams?: MateCliSeams;
74
+ /** Injected by tests: the lead's provider fetch, key environment, and stdin lines. */
75
+ leadSeams?: LeadCliSeams;
76
76
  /** Test seam for the short indexed wait loop. */
77
77
  waitSleep?: (milliseconds: number) => Promise<void>;
78
78
  /** Injected by tests: `onboard`'s home folder, terminal and probes. */
package/dist/operate.js CHANGED
@@ -22,7 +22,7 @@ import { checkoutPlan, cleanCheckouts, discardCheckout, finishedCheckouts, slimK
22
22
  import { closeOutCheckouts, closeOutRuns, stoppedWords } from "./run-closeout.js";
23
23
  import { MIN_DAYS, RETENTION_KINDS, countWords, dailyRetention, isRetentionKind, lastSweepAt, parsePeriod, periodLabel, periodWords, retentionPlan, sweepWords } from "./retention.js";
24
24
  import { checkPolicy, parseList, policyParts } from "./policy.js";
25
- import { billingOf, budgetHoldWords, budgetLabel, budgetStates, monthNamed, monthOf, spendItems, teammateNames, usd as spendUsd } from "./spend.js";
25
+ import { billingOf, budgetHoldWords, budgetLabel, budgetStates, monthNamed, monthOf, spendItems, subagentNames, usd as spendUsd } from "./spend.js";
26
26
  import { spendCsv } from "./spend-ui.js";
27
27
  import { buildExport, exportSummary, exportZip, writeExportFolder } from "./export.js";
28
28
  import { startBudgetAlerts } from "./budget-alerts.js";
@@ -43,8 +43,8 @@ import { origin, readMonitoring } from "./monitoring-settings.js";
43
43
  import { logEvent } from "./log.js";
44
44
  import { FLOW_EVERY_MS, flowHousekeeping, moveCards, moveCardsAfter } from "./flow-cadence.js";
45
45
  import { readHooksBase, scheduleFromWords } from "./flow-triggers.js";
46
- import { sendTeammateSummaries } from "./teammate-admin.js";
47
- import { runRequestedUndos, sendTeammateWeeklies } from "./teammate-week.js";
46
+ import { sendSubagentSummaries } from "./subagent-admin.js";
47
+ import { runRequestedUndos, sendSubagentWeeklies } from "./subagent-week.js";
48
48
  import { refreshConnections } from "./mcp-connect.js";
49
49
  import { followDiscord } from "./discord.js";
50
50
  import { followTeams } from "./teams.js";
@@ -156,8 +156,8 @@ import { bridgePass, clearBotToken, createTransport, followBridge, hashPairingCo
156
156
  import { scanRepo } from "./capscan.js";
157
157
  import { computeGaps, describeCapability } from "./gaps.js";
158
158
  import { ask as promptAsk, askHidden as promptHidden, confirm as promptConfirm, interactive as promptInteractive, underAgent } from "./prompt.js";
159
- import { runMateCli, answerContextLines } from "./mate-cli.js";
160
- import { confirmCoordinatorProposal, dismissCoordinatorProposal } from "./mate-doors.js";
159
+ import { runLeadCli, answerContextLines } from "./lead-cli.js";
160
+ import { confirmCoordinatorProposal, dismissCoordinatorProposal } from "./lead-doors.js";
161
161
  import { verifyApproverByPassword as approverByPassword } from "./principal.js";
162
162
  import { activeRemote, REMOTE_MESSAGES, REMOTE_REFUSED_FLAGS, REMOTE_SCOPES, RemoteRefusal, remoteAllows, remoteLensOf, remoteProjectOf, remoteRowOf, remoteSecret, reproveRemote, withRemote } from "./operate-remote.js";
163
163
  import { projectAuthority } from "./project-access.js";
@@ -179,7 +179,7 @@ import { CHAT_APPROVE_ALL, presetTerms, modeTermsJson, modeDigestOf, modeTermsFr
179
179
  import { WorktreePool } from "./worktree.js";
180
180
  import { requestTaskStop, resumeTaskStop, taskControlOf } from "./task-control.js";
181
181
  import { worktreeAdoptionNotice } from "./worktree-notices.js";
182
- import { workIndexPage, WorkIndexCursorError } from "./work-index.js";
182
+ import { workIndexPage, workIndexTask, WorkIndexCursorError } from "./work-index.js";
183
183
  import { readExecutorOf } from "./read-executor.js";
184
184
  import { parseWorkView } from "./workspace-ui.js";
185
185
  import { taskWorkSummaryOf } from "./work-summary.js";
@@ -256,9 +256,9 @@ export const OPERATE_HELP = `toolroll — operating the queue
256
256
  toolroll integrations [--json] which integrations work: Connected, Not set up or Broken, and what to do (--saved: no new checks)
257
257
  toolroll monitoring where the audit stream and traces go, and how each destination is doing
258
258
  toolroll check-progress <run> current or final approved check progress
259
- toolroll spend [--month YYYY-MM] [--csv] what agent work cost, by project, person, teammate and model
259
+ toolroll spend [--month YYYY-MM] [--csv] what agent work cost, by project, person, subagent and model
260
260
  toolroll export --out <path> [--zip] everything Toolroll knows, in a folder or .zip (no secrets)
261
- toolroll budget list|set|remove monthly budgets (--all | --project <p> | --person <name> | --teammate <id>) --usd <n> [--alerts-only]
261
+ toolroll budget list|set|remove monthly budgets (--all | --project <p> | --person <name> | --subagent <id>) --usd <n> [--alerts-only]
262
262
  toolroll notifications [quiet|all] how chats reach you: only when you're needed (the default), or every step
263
263
  toolroll notifications digest <HH:MM>|off one evening message: what finished, what waits, what failed
264
264
  toolroll notifications mute|unmute --repo <p> no pings for a project; the console and digest keep it
@@ -477,7 +477,7 @@ Agents — which provider and model each phase runs on
477
477
  toolroll chat --as <you> [--repo <path>…] [--say "…"] [--end]
478
478
  [--ceiling-usd <n>] [--json] (password at the prompt;
479
479
  --token <t> only for scripts — it lands in shell history)
480
- the mate: one conversation across your projects, the same thread the
480
+ your lead: one conversation across your projects, the same thread the
481
481
  console shows; the password mints a spending session once; it reads
482
482
  and proposes, you confirm cards (confirm N / dismiss N / open N;
483
483
  confirm N yes for an irreversible answer)
@@ -625,7 +625,7 @@ export const OPERATE_VALUE_FLAGS = new Set([
625
625
  // v103: the ledger chain and evidence packs.
626
626
  "checkpoint", "out", "from", "to",
627
627
  // v105: spend and budgets.
628
- "month", "usd", "person", "teammate",
628
+ "month", "usd", "person", "subagent", "teammate",
629
629
  // Sprint 8: the organisation policy.
630
630
  "providers", "models", "tools",
631
631
  "project-root", "schedule", "ceiling", "require",
@@ -869,7 +869,7 @@ async function dispatchOn(command, positional, flags, repoList, base, options, e
869
869
  ...(options.flowFetch === undefined ? {} : { flowFetch: options.flowFetch }),
870
870
  ...(options.integrationIo === undefined ? {} : { integrationIo: options.integrationIo }),
871
871
  ...(options.shouldStop === undefined ? {} : { shouldStop: options.shouldStop }),
872
- ...(options.mateSeams === undefined ? {} : { mateSeams: options.mateSeams }),
872
+ ...(options.leadSeams === undefined ? {} : { leadSeams: options.leadSeams }),
873
873
  ...(options.waitSleep === undefined ? {} : { waitSleep: options.waitSleep }),
874
874
  ...(options.releaseIo === undefined ? {} : { releaseIo: options.releaseIo }),
875
875
  ...(options.installBin === undefined ? {} : { installBin: options.installBin }),
@@ -1023,7 +1023,7 @@ function telegramCanDeliver(context, token) {
1023
1023
  function telegramConversation(context, options = {}) {
1024
1024
  return {
1025
1025
  evidenceRoot: context.evidenceRoot,
1026
- ...(context.mateSeams?.subscriptionRunner === undefined ? {} : { subscriptionRunner: context.mateSeams.subscriptionRunner }),
1026
+ ...(context.leadSeams?.subscriptionRunner === undefined ? {} : { subscriptionRunner: context.leadSeams.subscriptionRunner }),
1027
1027
  // Re-read on every card and every `/task`: the same console-url chat
1028
1028
  // links use, held to an https origin, and — inside `up`, where this
1029
1029
  // process also serves the console — equal to that console's own
@@ -2273,25 +2273,25 @@ async function tickCommand(flags, context) {
2273
2273
  const replyPass = housekeeping?.replies ?? { read: 0, taken: 0, problem: null };
2274
2274
  const stepPass = housekeeping?.steps ?? { ran: 0, problems: [] };
2275
2275
  const flowPass = housekeeping?.flows ?? { moved: 0, filed: [], problems: [] };
2276
- // Each AI teammate's daily summary to its manager (v92), once, after 5 pm; its weekly report (v97), Monday mornings.
2276
+ // Each subagent's daily summary to its manager (v92), once, after 5 pm; its weekly report (v97), Monday mornings.
2277
2277
  if (!buildsOnly)
2278
2278
  try {
2279
- sendTeammateSummaries(store, repo, clock());
2280
- sendTeammateWeeklies(store, repo, clock());
2279
+ sendSubagentSummaries(store, repo, clock());
2280
+ sendSubagentWeeklies(store, repo, clock());
2281
2281
  }
2282
2282
  catch (error) {
2283
- flowPass.problems.push(`teammate summaries: ${error instanceof Error ? error.message : "could not send"}`);
2283
+ flowPass.problems.push(`subagent summaries: ${error instanceof Error ? error.message : "could not send"}`);
2284
2284
  }
2285
- // Undoing a teammate's tool call asked for in chat (v97): made here, as the person who asked.
2285
+ // Undoing a subagent's tool call asked for in chat (v97): made here, as the person who asked.
2286
2286
  if (!buildsOnly && context.shouldStop?.() !== true) {
2287
2287
  try {
2288
2288
  await runRequestedUndos(store, {}, clock());
2289
2289
  }
2290
2290
  catch (error) {
2291
- flowPass.problems.push(`teammate undo: ${error instanceof Error ? error.message : "could not run"}`);
2291
+ flowPass.problems.push(`subagent undo: ${error instanceof Error ? error.message : "could not run"}`);
2292
2292
  }
2293
2293
  }
2294
- // Tools connected by signing in: a sign-in that runs out within ten minutes is renewed here, so a build or a teammate's call starts with a fresh one.
2294
+ // Tools connected by signing in: a sign-in that runs out within ten minutes is renewed here, so a build or a subagent's call starts with a fresh one.
2295
2295
  if (!buildsOnly && context.shouldStop?.() !== true) {
2296
2296
  try {
2297
2297
  flowPass.problems.push(...(await refreshConnections(store, [repo], clock(), context.flowStepIo?.fetch === undefined ? {} : { fetcher: context.flowStepIo.fetch })).problems);
@@ -6050,19 +6050,19 @@ async function runWatchLoop(args) {
6050
6050
  : startTelegramFollower({ context, publicUrl: text(flags, "public-url"), signal: followController.signal, progress, label: "watch: bridge", died: { prefix: "watch: ", then: "taps wait for the next watch" } });
6051
6051
  const slackFollower = followSlack({ store, dir: dirname(context.databaseFile), signal: followController.signal,
6052
6052
  readProjects: telegramReadProjects(context), evidenceRoot: context.evidenceRoot,
6053
- ...(context.mateSeams?.subscriptionRunner ? { subscriptionRunner: context.mateSeams.subscriptionRunner } : {}),
6053
+ ...(context.leadSeams?.subscriptionRunner ? { subscriptionRunner: context.leadSeams.subscriptionRunner } : {}),
6054
6054
  origin: () => phoneOrigin(process.env, dirname(context.databaseFile), { serverOrigin: text(flags, "public-url") ?? null }),
6055
6055
  notifications: () => effectivePrimary(process.env, dirname(context.databaseFile), loadBotToken(process.env, context.telegramTokenFile) !== null).channel === "slack",
6056
6056
  }).catch(() => progress("watch: Slack stopped. Check Slack settings before reconnecting."));
6057
6057
  const teamsFollower = followTeams({ store, dir: dirname(context.databaseFile), signal: followController.signal,
6058
6058
  readProjects: telegramReadProjects(context), evidenceRoot: context.evidenceRoot,
6059
- ...(context.mateSeams?.subscriptionRunner ? { subscriptionRunner: context.mateSeams.subscriptionRunner } : {}),
6059
+ ...(context.leadSeams?.subscriptionRunner ? { subscriptionRunner: context.leadSeams.subscriptionRunner } : {}),
6060
6060
  origin: () => phoneOrigin(process.env, dirname(context.databaseFile), { serverOrigin: text(flags, "public-url") ?? null }),
6061
6061
  notifications: () => effectivePrimary(process.env, dirname(context.databaseFile), loadBotToken(process.env, context.telegramTokenFile) !== null).channel === "teams",
6062
6062
  }).catch(() => progress("watch: Teams stopped. Check Teams settings before reconnecting."));
6063
6063
  const discordFollower = followDiscord({ store, dir: dirname(context.databaseFile), signal: followController.signal,
6064
6064
  readProjects: telegramReadProjects(context), evidenceRoot: context.evidenceRoot,
6065
- ...(context.mateSeams?.subscriptionRunner ? { subscriptionRunner: context.mateSeams.subscriptionRunner } : {}),
6065
+ ...(context.leadSeams?.subscriptionRunner ? { subscriptionRunner: context.leadSeams.subscriptionRunner } : {}),
6066
6066
  origin: () => phoneOrigin(process.env, dirname(context.databaseFile), { serverOrigin: text(flags, "public-url") ?? null }),
6067
6067
  notifications: () => effectivePrimary(process.env, dirname(context.databaseFile), loadBotToken(process.env, context.telegramTokenFile) !== null).channel === "discord",
6068
6068
  }).catch(() => progress("watch: Discord stopped. Check Discord settings before reconnecting."));
@@ -8307,10 +8307,10 @@ async function statusCommand(positional, flags, context) {
8307
8307
  // that belongs to the installation or other projects (updates, integrations, builds by project, unsent replies).
8308
8308
  const lens = context.principal?.lens ?? null;
8309
8309
  if (lens !== null) {
8310
- const status = installationStatus(context.store, context.clock(), viewer, lens);
8310
+ const status = installationStatus(context.store, context.clock(), viewer, lens, context.evidenceRoot);
8311
8311
  return succeed(context.write, context.json, command, { ...status, projects: [] }, () => renderInstallationStatus(status, true));
8312
8312
  }
8313
- const status = installationStatus(context.store, context.clock(), viewer);
8313
+ const status = installationStatus(context.store, context.clock(), viewer, null, context.evidenceRoot);
8314
8314
  // One line, only when a newer Toolroll exists; offline or switched off says nothing.
8315
8315
  const current = PACKAGE_VERSION;
8316
8316
  const method = installMethod(context.installBin);
@@ -8927,6 +8927,7 @@ function listTasks(flags, context) {
8927
8927
  view: parseWorkView(rawView ?? null), limit, cursor: text(flags, 'cursor') ?? null,
8928
8928
  ...(wanted === undefined ? {} : { state: wanted }),
8929
8929
  ...(text(flags, 'repo') === undefined ? {} : { project: text(flags, 'repo') }),
8930
+ root: context.evidenceRoot,
8930
8931
  };
8931
8932
  const refused = (error) => {
8932
8933
  if (!(error instanceof WorkIndexCursorError))
@@ -8990,10 +8991,18 @@ function showTask(positional, context) {
8990
8991
  const repo = store.lookupRef(blocker)?.repo;
8991
8992
  return repo != null && lens.includes(repo);
8992
8993
  });
8994
+ const work = taskWorkSummaryOf(store, id, now, access);
8995
+ const current = assignmentOf(store, id, now, access, context.evidenceRoot);
8996
+ // Read the same saved facts and statusOf path as task list. File health remains
8997
+ // in the assignment diagnostics and action-time guards; it cannot rewrite history.
8998
+ const listed = workIndexTask(store, id, now, access, context.evidenceRoot);
8999
+ const shared = listed === null ? null : { headline: listed.status.label, sentence: listed.status.detail };
9000
+ const primaryAction = listed === null ? work?.primaryAction ?? null : listed.primaryAction;
8993
9001
  const detail = {
8994
9002
  task,
8995
- work: taskWorkSummaryOf(store, id, now, access),
8996
- assignment: assignmentBrief(assignmentOf(store, id, now, access, context.evidenceRoot)),
9003
+ work: work === null || listed === null ? work : { ...work, status: { ...work.status, label: listed.status.label, detail: listed.status.detail, tone: listed.status.tone }, primaryAction },
9004
+ status: shared === null ? null : { headline: shared.headline, sentence: shared.sentence },
9005
+ assignment: assignmentBrief(current),
8997
9006
  ref: ref.id,
8998
9007
  // One phrase for every inaccessible blocker, so even their number stays private.
8999
9008
  blockedBy: visibleBlockers.length === blockers.length ? visibleBlockers : [...visibleBlockers, "a task in another project"],
@@ -9033,8 +9042,8 @@ function showTask(positional, context) {
9033
9042
  `${task.id} ${task.state}${ref.deliverable === "report" ? " (scout — delivers a report)" : ""}`,
9034
9043
  ` ${task.title}`,
9035
9044
  ...(detail.work === null ? [] : [
9036
- ` status: ${detail.work.status.label}`,
9037
- ...(detail.work.primaryAction === null ? [] : [` next: ${detail.work.primaryAction.label}${detail.work.primaryAction.target.decisionId === null ? "" : ` — decision #${detail.work.primaryAction.target.decisionId}`}`]),
9045
+ ` status: ${shared?.headline ?? detail.work.status.label}${shared === null ? "" : ` — ${shared.sentence}`}`,
9046
+ ...(primaryAction === null ? [] : [` next: ${primaryAction.label}${primaryAction.target.decisionId === null ? "" : ` — decision #${primaryAction.target.decisionId}`}`]),
9038
9047
  ]),
9039
9048
  // The closed machine-authored verdict (Priority 2), computed once at
9040
9049
  // completion — never re-derived here. Same words `verdictWords`
@@ -9042,7 +9051,7 @@ function showTask(positional, context) {
9042
9051
  ...(task.state !== "done" || detail.proofVerdict === null
9043
9052
  ? []
9044
9053
  : [
9045
- ` proof: ${proofVerdictWords(detail.proofVerdict, detail.proofReasons).word}${detail.proofAccepted ? " (accepted)" : ""}`,
9054
+ ` proof: ${proofVerdictWords(current?.receipt?.runId === latestFinished?.id ? current?.readiness?.verdict ?? detail.proofVerdict : detail.proofVerdict, detail.proofReasons).word}${detail.proofAccepted ? " (accepted)" : ""}`,
9046
9055
  ...(detail.proofReasons.length > 0 ? [` ${detail.proofReasons.join("; ")}`] : []),
9047
9056
  ...matrixWords(detail.proofMatrix),
9048
9057
  ...(detail.semanticCoverage === null ? [] : coverageWords(detail.semanticCoverage).map(line => ` ${line}`)),
@@ -9987,7 +9996,7 @@ function describeApproveFailure(reason, id) {
9987
9996
  if (reason === "requester")
9988
9997
  return `you filed ${id}, and this project needs someone else to approve it`;
9989
9998
  if (reason === "person-required")
9990
- return `${id} is protected work: a person has to approve it, not an operating mode, a schedule or an AI teammate`;
9999
+ return `${id} is protected work: a person has to approve it, not an operating mode, a schedule or a subagent`;
9991
10000
  if (reason === "second-approver")
9992
10001
  return `your approval of ${id} is recorded; it is protected work, so a second person needs to approve it (toolroll task approve ${id} as them)`;
9993
10002
  if (reason === "no-approvers") {
@@ -10104,7 +10113,7 @@ async function chatCommand(flags, context) {
10104
10113
  return fail(write, json, "chat", "usage", "Choose --follow or --no-follow.", EXIT.usage);
10105
10114
  const credentials = await askCredentials(flags, context);
10106
10115
  if (credentials === null) {
10107
- return fail(write, json, "chat", "usage", "the mate takes your name and password — `--as <you>` and the hidden prompt; `--token <t>` only where a script must (it lands in shell history)", EXIT.usage);
10116
+ return fail(write, json, "chat", "usage", "the lead takes your name and password — `--as <you>` and the hidden prompt; `--token <t>` only where a script must (it lands in shell history)", EXIT.usage);
10108
10117
  }
10109
10118
  const ceilingGiven = text(flags, "ceiling-usd");
10110
10119
  // The ceiling: the `--repo` list, or the ENROLLED registry beside the
@@ -10120,7 +10129,7 @@ async function chatCommand(flags, context) {
10120
10129
  return fail(write, json, "chat", "registry", "the enrolled-project registry could not be read — name projects with --repo", EXIT.refused);
10121
10130
  repos = loaded.repos;
10122
10131
  }
10123
- const result = await runMateCli({
10132
+ const result = await runLeadCli({
10124
10133
  store,
10125
10134
  databaseFile: context.databaseFile,
10126
10135
  write,
@@ -10131,7 +10140,7 @@ async function chatCommand(flags, context) {
10131
10140
  end: flags.has("end"),
10132
10141
  ...(flags.has("follow") || flags.has("no-follow") ? { follow: flags.has("follow") && !flags.has("no-follow") } : {}),
10133
10142
  ceilingUsd: ceilingGiven === undefined ? undefined : Number(ceilingGiven),
10134
- ...(context.mateSeams === undefined ? {} : { seams: { ...context.mateSeams, clock: context.mateSeams.clock ?? context.clock } }),
10143
+ ...(context.leadSeams === undefined ? {} : { seams: { ...context.leadSeams, clock: context.leadSeams.clock ?? context.clock } }),
10135
10144
  ...(context.evidenceRoot === undefined ? {} : { evidenceRoot: context.evidenceRoot }),
10136
10145
  // The console's own address (and its public one): links there read as "the task", "the result", "Settings → Lead".
10137
10146
  appOrigin: [loadConsoleUrl(process.env, dirname(context.databaseFile)), phoneOrigin(process.env, dirname(context.databaseFile))],
@@ -10698,7 +10707,7 @@ async function projectDeleteCommand(positional, flags, context) {
10698
10707
  `Deleted ${repo}: ${holdingsWords(done.removed)}.`, ...done.left.map(one => `Git kept ${one}.`), `The ledger records it as entry #${done.ledgerId}.`,
10699
10708
  ]);
10700
10709
  }
10701
- /** `spend [--month YYYY-MM] [--csv]` (v105): what agent work cost in a month, by project, person, teammate and model. */
10710
+ /** `spend [--month YYYY-MM] [--csv]` (v105): what agent work cost in a month, by project, person, subagent and model. */
10702
10711
  function spendCommand(flags, context) {
10703
10712
  const command = "spend";
10704
10713
  for (const name of flags.keys())
@@ -10708,7 +10717,7 @@ function spendCommand(flags, context) {
10708
10717
  if (month === null)
10709
10718
  return fail(context.write, context.json, command, "usage", "Use spend --month YYYY-MM.", EXIT.usage);
10710
10719
  const items = spendItems(context.store.handle, month.from, month.to);
10711
- const names = teammateNames(context.store.handle);
10720
+ const names = subagentNames(context.store.handle);
10712
10721
  if (flags.has("csv")) {
10713
10722
  context.write(spendCsv(items, names).replace(/^\ufeff/, "").trimEnd());
10714
10723
  return EXIT.ok;
@@ -10722,7 +10731,7 @@ function spendCommand(flags, context) {
10722
10731
  byProject.set(item.project, (byProject.get(item.project) ?? 0) + (item.microusd ?? 0));
10723
10732
  // v105: subscription work is $0; what binds it is its plan's windows, as the provider last said.
10724
10733
  const limits = context.store.providerLimits();
10725
- const windows = limitsView(limits, [], { project: repo => basename(repo), teammate: id => String(id) }, context.clock())?.tiles ?? [];
10734
+ const windows = limitsView(limits, [], { project: repo => basename(repo), subagent: id => String(id) }, context.clock())?.tiles ?? [];
10726
10735
  // Sized routing: each tier's tasks, time to a result and plan use, and what the tiers saved.
10727
10736
  const tiers = tierReport(context.store.handle, month.from, month.to, items);
10728
10737
  return succeed(context.write, context.json, command, { month: month.name, totalMicrousd: total, unpriced, items: items.length, budgets, limits, tiers: { rows: tiers.rows, saved: tiers.saved } }, () => [
@@ -10825,21 +10834,22 @@ async function budgetCommand(positional, flags, context) {
10825
10834
  const store = context.store;
10826
10835
  if (action === undefined || action === "list") {
10827
10836
  const budgets = store.monthSpend(context.clock()).budgets;
10828
- return succeed(context.write, context.json, command, { budgets }, () => budgets.length === 0 ? ["No budgets. `budget set --all|--project <path>|--person <name>|--teammate <id> --usd <n>` makes one."]
10837
+ return succeed(context.write, context.json, command, { budgets }, () => budgets.length === 0 ? ["No budgets. `budget set --all|--project <path>|--person <name>|--subagent <id> --usd <n>` makes one."]
10829
10838
  : budgets.map(one => `#${one.id} ${budgetLabel(one).replace(/'s$/, "")}: ${spendUsd(one.spentMicrousd)} of ${spendUsd(one.limitMicrousd)} this month (${one.percent}%)${one.hardStop ? ", stops API work at 100%" : ", alerts only"}`));
10830
10839
  }
10831
10840
  if (action !== "set" && action !== "remove")
10832
10841
  return fail(context.write, context.json, command, "usage", "Use budget list, budget set or budget remove.", EXIT.usage);
10833
- const allowed = new Set(["all", "project", "person", "teammate", "usd", "alerts-only", "as", "token", "token-file", "token-env", "db", "json"]);
10842
+ // --teammate: the flag's name before D5, still read this release.
10843
+ const allowed = new Set(["all", "project", "person", "subagent", "teammate", "usd", "alerts-only", "as", "token", "token-file", "token-env", "db", "json"]);
10834
10844
  for (const name of flags.keys())
10835
10845
  if (!allowed.has(name))
10836
10846
  return fail(context.write, context.json, command, "usage", `--${name} is not a budget option.`, EXIT.usage);
10837
10847
  const chosen = [flags.has("all") ? { scope: "installation", key: "*" } : null,
10838
10848
  text(flags, "project") === undefined ? null : { scope: "project", key: resolve(text(flags, "project")) },
10839
10849
  text(flags, "person") === undefined ? null : { scope: "person", key: text(flags, "person") },
10840
- text(flags, "teammate") === undefined ? null : { scope: "teammate", key: text(flags, "teammate") }].filter(one => one !== null);
10850
+ (text(flags, "subagent") ?? text(flags, "teammate")) === undefined ? null : { scope: "subagent", key: (text(flags, "subagent") ?? text(flags, "teammate")) }].filter(one => one !== null);
10841
10851
  if (chosen.length !== 1)
10842
- return fail(context.write, context.json, command, "usage", "Name one of --all, --project <path>, --person <name> or --teammate <id>.", EXIT.usage);
10852
+ return fail(context.write, context.json, command, "usage", "Name one of --all, --project <path>, --person <name> or --subagent <id>.", EXIT.usage);
10843
10853
  const target = chosen[0];
10844
10854
  const acting = await askCredentials(flags, context);
10845
10855
  const verified = acting === null ? null : authenticateApprover(store, acting.name, acting.token);
@@ -10848,9 +10858,9 @@ async function budgetCommand(positional, flags, context) {
10848
10858
  }
10849
10859
  const known = target.scope === "installation" || (target.scope === "project" ? store.knownRepos().includes(target.key)
10850
10860
  : target.scope === "person" ? store.accountFacts().some(one => one.name === target.key && one.revokedAt === null)
10851
- : store.handle.prepare("SELECT 1 FROM teammate WHERE id = ?").get(Number(target.key)) !== undefined);
10861
+ : store.handle.prepare("SELECT 1 FROM subagent WHERE id = ?").get(Number(target.key)) !== undefined);
10852
10862
  if (!known)
10853
- return fail(context.write, context.json, command, "not-found", "That isn't a project, person or teammate here.", EXIT.refused);
10863
+ return fail(context.write, context.json, command, "not-found", "That isn't a project, person or subagent here.", EXIT.refused);
10854
10864
  if (action === "remove") {
10855
10865
  const existing = store.budgets().find(one => one.scope === target.scope && one.key === target.key);
10856
10866
  if (existing === undefined || !store.removeBudget(existing.id, acting.name, context.clock()))
package/dist/policy.d.ts CHANGED
@@ -15,7 +15,7 @@
15
15
  * (lowered), or, when there is none, doesn't run (refused); the words say which.
16
16
  *
17
17
  * Every road that admits work asks here: scope approval, the tick before a
18
- * run starts (and build() as the last look), the lead and project chats, teammates and flow steps.
18
+ * run starts (and build() as the last look), the lead and project chats, subagents and flow steps.
19
19
  */
20
20
  import type { Database } from "./store.js";
21
21
  import type { ExecutionProfile } from "./scope.js";
@@ -9,7 +9,7 @@ export type VerifiedApprover = {
9
9
  readonly repos: readonly string[];
10
10
  readonly ceilingDigest: string;
11
11
  };
12
- /** The mate's ceiling digest: the admitted repos IN ORDER, hashed — `rN`
12
+ /** The lead's ceiling digest: the admitted repos IN ORDER, hashed — `rN`
13
13
  * is an index, so two surfaces naming the same repos in a different order
14
14
  * hold different ceilings (slice-2 review, finding 3). */
15
15
  export declare function ceilingDigestOf(repos: readonly string[]): string;
package/dist/principal.js CHANGED
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * The branded approver principal (mate arc, ruling 3).
3
3
  *
4
- * Every act the mate proposes and every confirmation an operator taps
4
+ * Every act the lead proposes and every confirmation an operator taps
5
5
  * runs under a principal that PROVES it was authenticated — a password
6
6
  * ceremony, or a cookie session the edge already proved (csrf, role,
7
7
  * generation) and this module re-proves against the approver row. The
@@ -15,7 +15,7 @@
15
15
  */
16
16
  import { createHash } from "node:crypto";
17
17
  import { authenticateAccount } from "./scope.js";
18
- /** The mate's ceiling digest: the admitted repos IN ORDER, hashed — `rN`
18
+ /** The lead's ceiling digest: the admitted repos IN ORDER, hashed — `rN`
19
19
  * is an index, so two surfaces naming the same repos in a different order
20
20
  * hold different ceilings (slice-2 review, finding 3). */
21
21
  export function ceilingDigestOf(repos) {
@@ -49,7 +49,7 @@ export function projectDeleteConfirmHtml(view, problem) {
49
49
  "The checkouts and branches Toolroll made",
50
50
  ...(h.chats > 0 ? [count(h.chats, "chat")] : []),
51
51
  ...(h.flows > 0 ? [`${count(h.flows, "flow")} and ${count(h.cards, "card")}`] : []),
52
- ...(h.teammates > 0 ? [count(h.teammates, "teammate")] : []),
52
+ ...(h.subagents > 0 ? [count(h.subagents, "subagent")] : []),
53
53
  "Its budgets, settings and knowledge",
54
54
  ];
55
55
  return html `<section class="project-delete">${problem === null ? "" : html `<p class="problem" role="alert">${problem}</p>`}<p>This removes:</p><ul class="removes">${items.map(one => html `<li>${one}</li>`)}</ul><p>The repository at <span class="path">${view.repo}</span> and its own branches stay. The ledger keeps its history. There's no undo.</p>${postForm("/settings/project/delete", html `<label>Your Toolroll password<input type="password" name="password" autocomplete="current-password"></label><div class="actions"><button type="submit" class="danger">Delete project</button><a href="/settings/project?repo=${encodeURIComponent(view.repo)}">Cancel</a></div>`, { hidden: { repo: view.repo, name: view.name, step: "delete" } })}</section>`;
@@ -12,7 +12,7 @@ export type ProjectHoldings = {
12
12
  chats: number;
13
13
  flows: number;
14
14
  cards: number;
15
- teammates: number;
15
+ subagents: number;
16
16
  budgets: number;
17
17
  settings: number;
18
18
  };