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,19 +1,19 @@
1
- import { type MateProgress } from "./mate-progress.js";
2
- import type { ChatConfig, MateSession, MateThread, Store } from "./store.js";
1
+ import { type LeadProgress } from "./lead-progress.js";
2
+ import type { ChatConfig, LeadSession, LeadThread, Store } from "./store.js";
3
3
  import type { Integration } from "./integrations.js";
4
4
  import type { VerifiedApprover } from "./principal.js";
5
- import { type MateHistoryMessage } from "./converse.js";
6
- import { type SubscriptionMateRunner } from "./subscription-chat.js";
5
+ import { type LeadHistoryMessage } from "./converse.js";
6
+ import { type SubscriptionLeadRunner } from "./subscription-chat.js";
7
7
  import { type LeadChannel } from './lead-context.js';
8
- export declare const MATE_MESSAGE_MAX_CHARS = 2000;
8
+ export declare const LEAD_MESSAGE_MAX_CHARS = 2000;
9
9
  /** The thread's recent history the model sees, most recent first until the cap. */
10
- export declare const MATE_HISTORY_CAP_BYTES = 16384;
11
- export declare const MATE_HISTORY_MAX_MESSAGES = 40;
12
- export type MateTurnInput = {
10
+ export declare const LEAD_HISTORY_CAP_BYTES = 16384;
11
+ export declare const LEAD_HISTORY_MAX_MESSAGES = 40;
12
+ export type LeadTurnInput = {
13
13
  store: Store;
14
14
  who: VerifiedApprover;
15
- session: MateSession;
16
- thread: MateThread;
15
+ session: LeadSession;
16
+ thread: LeadThread;
17
17
  /** The installation's chat configuration: provider, model, pinned price, caps. */
18
18
  config: ChatConfig;
19
19
  /** Direct API key; subscription providers use their cached harness login. */
@@ -33,11 +33,11 @@ export type MateTurnInput = {
33
33
  context?: string;
34
34
  fetcher?: typeof fetch;
35
35
  /** Injected by tests; production invokes the isolated local harness. */
36
- subscriptionRunner?: SubscriptionMateRunner;
36
+ subscriptionRunner?: SubscriptionLeadRunner;
37
37
  /** Live progress for someone watching (chat streaming): the steps, the
38
38
  * tools in plain words, and the reply as it is written. Display only;
39
39
  * never called with text that looks like a secret. */
40
- onProgress?: (event: MateProgress) => void;
40
+ onProgress?: (event: LeadProgress) => void;
41
41
  clock?: () => Date;
42
42
  /** Where evidence lives — get_task reads a scout's report from here. */
43
43
  evidenceRoot?: string;
@@ -62,14 +62,14 @@ export type MateTurnInput = {
62
62
  ok: true;
63
63
  } | {
64
64
  ok: false;
65
- reason: MateChannelProblem;
65
+ reason: LeadChannelProblem;
66
66
  }>;
67
67
  };
68
- /** Why a chat's standing changed under a turn: each has its own plain words (MATE_CHANNEL_COPY). */
69
- export type MateChannelProblem = "unpaired" | "not-approver" | "projects-changed" | "projects-unreadable" | "member-changed" | "access-changed";
70
- export type MateRefusal = "empty-message" | "secret-in-message" | "secret-in-context" | "standing" | "unpriced" | "ceiling-changed" | "not-yours" | "thread-closed" | "latched" | "concurrent" | "daily-cap" | "session-exhausted" | "session-ended" | "over-budget" | "monthly-budget" | "policy" | "invalid-request" | "request-changed" | "channel";
71
- export type MateFailure = "provider-error" | "timeout" | "malformed-reply" | "secret-refused" | "latched" | "revoked" | "superseded";
72
- export type MateTurnOutcome = {
68
+ /** Why a chat's standing changed under a turn: each has its own plain words (LEAD_CHANNEL_COPY). */
69
+ export type LeadChannelProblem = "unpaired" | "not-approver" | "projects-changed" | "projects-unreadable" | "member-changed" | "access-changed";
70
+ export type LeadRefusal = "empty-message" | "secret-in-message" | "secret-in-context" | "standing" | "unpriced" | "ceiling-changed" | "not-yours" | "thread-closed" | "latched" | "concurrent" | "daily-cap" | "session-exhausted" | "session-ended" | "over-budget" | "monthly-budget" | "policy" | "invalid-request" | "request-changed" | "channel";
71
+ export type LeadFailure = "provider-error" | "timeout" | "malformed-reply" | "secret-refused" | "latched" | "revoked" | "superseded";
72
+ export type LeadTurnOutcome = {
73
73
  ok: true;
74
74
  replayed?: false;
75
75
  turn: number;
@@ -85,22 +85,22 @@ export type MateTurnOutcome = {
85
85
  turn: number;
86
86
  } | {
87
87
  ok: false;
88
- refused: MateRefusal;
88
+ refused: LeadRefusal;
89
89
  message: string;
90
90
  } | {
91
91
  ok: false;
92
92
  turn: number;
93
- failed: MateFailure;
93
+ failed: LeadFailure;
94
94
  message: string;
95
95
  unknownSpend: boolean;
96
96
  saved?: boolean;
97
97
  };
98
98
  /** What happened, what it means, and one next step: plain words a person can act on, never internal terms. */
99
- export declare const MATE_REFUSAL_COPY: Record<MateRefusal, string>;
99
+ export declare const LEAD_REFUSAL_COPY: Record<LeadRefusal, string>;
100
100
  /** A turn stopped because its chat's standing changed: what happened, what it means, one next step. */
101
- export declare const MATE_CHANNEL_COPY: Record<MateChannelProblem, string>;
101
+ export declare const LEAD_CHANNEL_COPY: Record<LeadChannelProblem, string>;
102
102
  /** Why a reply did not finish, in the same three parts: what happened, what it means, one next step. */
103
- export declare const MATE_FAILURE_COPY: {
103
+ export declare const LEAD_FAILURE_COPY: {
104
104
  readonly stopped: "This reply was stopped before it finished, from another window or by a newer message. Nothing it proposed was kept. Send your message again if you still need an answer.";
105
105
  readonly ended: "Your sign-in or this conversation ended while the lead was answering. Nothing it proposed was kept. Sign in again or start a new chat, then send your message again.";
106
106
  readonly tooLong: string;
@@ -119,12 +119,12 @@ export declare const MATE_FAILURE_COPY: {
119
119
  readonly unusable: "The lead's answer couldn't be used, so it was thrown away. Nothing was kept. Send your message again.";
120
120
  };
121
121
  /** A failed turn's saved reason as plain words, for a surface that reads the turn back later (a restart, a delivery retry). */
122
- export declare function mateFailureText(reason: string | null): string;
122
+ export declare function leadFailureText(reason: string | null): string;
123
123
  /** How long a provider that ignored its abort at the turn's deadline is waited for before the turn ends without it.
124
124
  * Its process group was already killed at the deadline; this only bounds the wait for the transport to say so. */
125
- export declare const MATE_ABORT_GRACE_MS = 5000;
125
+ export declare const LEAD_ABORT_GRACE_MS = 5000;
126
126
  /** The last messages of the thread as provider-neutral history, newest kept first until the byte cap. */
127
- export declare function historyFor(store: Store, thread: number, queuedMessageId?: number): MateHistoryMessage[];
127
+ export declare function historyFor(store: Store, thread: number, queuedMessageId?: number): LeadHistoryMessage[];
128
128
  /** "read 3 · proposed 1 · 2 steps" — counts only, never results (ruling 11). */
129
129
  export declare function activitySummary(reads: number, proposals: number, steps: number): string;
130
- export declare function runMateTurn(input: MateTurnInput): Promise<MateTurnOutcome>;
130
+ export declare function runLeadTurn(input: LeadTurnInput): Promise<LeadTurnOutcome>;
@@ -1,30 +1,30 @@
1
1
  import { Buffer } from "node:buffer";
2
- import { mateToolFailureReason, mateToolLabel } from "./mate-progress.js";
2
+ import { leadToolFailureReason, leadToolLabel } from "./lead-progress.js";
3
3
  import { createHash } from "node:crypto";
4
- import { mateTimeoutNotice } from "./store.js";
4
+ import { leadTimeoutNotice } from "./store.js";
5
5
  import { RESULT_IMAGES_PER_TURN_CAP } from "./chat-evidence.js";
6
6
  import { isVerifiedApprover, reproveApprover } from "./principal.js";
7
- import { MATE_MAX_CALLS_PER_STEP, MATE_MAX_STEPS, MATE_TOOL_RESULT_CAP_BYTES, TURN_WALL_CLOCK_MS, composeMateRequest, credentialKeyOf, isDirectChatProvider, mateWorstCaseForPrice, performMateRequest, priceForConfig, settleForPrice, subscriptionCredentialKey, } from "./converse.js";
7
+ import { LEAD_MAX_CALLS_PER_STEP, LEAD_MAX_STEPS, LEAD_TOOL_RESULT_CAP_BYTES, TURN_WALL_CLOCK_MS, composeLeadRequest, credentialKeyOf, isDirectChatProvider, leadWorstCaseForPrice, performLeadRequest, priceForConfig, settleForPrice, subscriptionCredentialKey, } from "./converse.js";
8
8
  import { redactSecretLines, scanForSecrets } from "./evidence.js";
9
9
  import { redactSecretAssignments } from "./builder.js";
10
- import { MATE_CONTRACT } from "./mate-contract.js";
11
- import { MATE_MAX_PROPOSALS_PER_TURN, MATE_TOOL_SCHEMAS, executeMateTool, isMateTool, mateViewContextFor, projectLabelForMate, redactForMate, toolResultBytes } from "./mate-tools.js";
12
- import { composeSubscriptionMatePrompt, performSubscriptionMateRequest } from "./subscription-chat.js";
10
+ import { LEAD_CONTRACT } from "./lead-contract.js";
11
+ import { LEAD_MAX_PROPOSALS_PER_TURN, LEAD_TOOL_SCHEMAS, executeLeadTool, isLeadTool, leadViewContextFor, projectLabelForLead, redactForLead, toolResultBytes } from "./lead-tools.js";
12
+ import { composeSubscriptionLeadPrompt, performSubscriptionLeadRequest } from "./subscription-chat.js";
13
13
  import { LEAD_REPLY_LIMITS, leadContext } from './lead-context.js';
14
14
  import { shortenAsk } from './text-limits.js';
15
15
  import { envValue } from "./names.js";
16
16
  import { deliverableClaim, deliverableRepair, dropDeliverableClaims, replyCarriesDeliverable } from "./reply-shape.js";
17
- export const MATE_MESSAGE_MAX_CHARS = 2_000;
17
+ export const LEAD_MESSAGE_MAX_CHARS = 2_000;
18
18
  /** Where a promise made this turn is reported: the chat app it arrived on, or this conversation for the console and terminal. */
19
19
  function promiseChannelOfTurn(channel) {
20
20
  return channel === undefined ? undefined : channel === "console" || channel === "terminal" ? "chat" : channel;
21
21
  }
22
22
  /** The thread's recent history the model sees, most recent first until the cap. */
23
- export const MATE_HISTORY_CAP_BYTES = 16_384;
24
- export const MATE_HISTORY_MAX_MESSAGES = 40;
23
+ export const LEAD_HISTORY_CAP_BYTES = 16_384;
24
+ export const LEAD_HISTORY_MAX_MESSAGES = 40;
25
25
  /** What happened, what it means, and one next step: plain words a person can act on, never internal terms. */
26
- export const MATE_REFUSAL_COPY = {
27
- "empty-message": `That message was empty or too long, so it wasn't sent. Write 1 to ${MATE_MESSAGE_MAX_CHARS} characters and send it again.`,
26
+ export const LEAD_REFUSAL_COPY = {
27
+ "empty-message": `That message was empty or too long, so it wasn't sent. Write 1 to ${LEAD_MESSAGE_MAX_CHARS} characters and send it again.`,
28
28
  "secret-in-message": "That message looks like it contains a password or key, so it wasn't sent or saved. Remove it and send the message again.",
29
29
  "secret-in-context": "Something saved in your projects looks like a password or key, so the lead can't read your projects safely. Remove it from the task or note it's in, then try again.",
30
30
  standing: "Your sign-in changed, so the lead can't act for you right now. Sign in again.",
@@ -45,7 +45,7 @@ export const MATE_REFUSAL_COPY = {
45
45
  channel: "This conversation's connection changed, so the message wasn't sent. Reconnect it, then send again.",
46
46
  };
47
47
  /** A turn stopped because its chat's standing changed: what happened, what it means, one next step. */
48
- export const MATE_CHANNEL_COPY = {
48
+ export const LEAD_CHANNEL_COPY = {
49
49
  unpaired: "This chat is no longer connected to your account, so the reply was stopped. Nothing it proposed was kept. Connect the chat again in Settings, then send your message again.",
50
50
  "not-approver": "Your account can no longer approve work here, so the reply was stopped. Nothing it proposed was kept. Ask an owner to restore your access, then send your message again.",
51
51
  "projects-changed": "The projects this chat can see changed while the lead was answering, so the reply was stopped. Nothing it proposed was kept. Send your message again.",
@@ -54,10 +54,10 @@ export const MATE_CHANNEL_COPY = {
54
54
  "access-changed": "This chat's access changed while the lead was answering, so the reply was stopped. Nothing it proposed was kept. Reconnect the chat, then send your message again.",
55
55
  };
56
56
  /** Why a reply did not finish, in the same three parts: what happened, what it means, one next step. */
57
- export const MATE_FAILURE_COPY = {
57
+ export const LEAD_FAILURE_COPY = {
58
58
  stopped: "This reply was stopped before it finished, from another window or by a newer message. Nothing it proposed was kept. Send your message again if you still need an answer.",
59
59
  ended: "Your sign-in or this conversation ended while the lead was answering. Nothing it proposed was kept. Sign in again or start a new chat, then send your message again.",
60
- tooLong: mateTimeoutNotice(false),
60
+ tooLong: leadTimeoutNotice(false),
61
61
  secretRead: "Something the lead read looked like a password or key, so it stopped before sending it anywhere. Nothing was kept. Remove the password or key from that task or note, then ask again.",
62
62
  secretReply: "The lead's reply contained something that looked like a password or key, so it was thrown away. Nothing was kept. Ask again, without asking for a password or key.",
63
63
  paused: "An earlier reply stopped before its cost was known, so chat is paused. This message wasn't answered. Confirm that earlier reply on the Chat page, then send again.",
@@ -66,29 +66,29 @@ export const MATE_FAILURE_COPY = {
66
66
  unreadable: "The chat provider sent back an answer that couldn't be read, so it was thrown away. Nothing was kept. Send your message again.",
67
67
  signIn: "The chat provider couldn't answer; its sign-in may have expired. Nothing was kept. Sign in to it again on this computer, then send your message again.",
68
68
  refused: "The chat provider turned the request down. Nothing was kept or charged. Try again in a minute; if it keeps happening, check the provider in Settings → Lead.",
69
- tooLongUnknownCost: mateTimeoutNotice(false, true),
69
+ tooLongUnknownCost: leadTimeoutNotice(false, true),
70
70
  lostUnknownCost: "The chat provider stopped responding partway through, and the cost isn't known, so chat is paused. Nothing it proposed was kept. Confirm the cost on the Chat page to turn chat back on.",
71
71
  unreadableUnknownCost: "The chat provider sent back an answer that couldn't be read, and its cost isn't known, so chat is paused. Nothing it proposed was kept. Confirm the cost on the Chat page to turn chat back on.",
72
72
  empty: "The lead sent back an empty answer. Nothing was kept. Send your message again.",
73
73
  unusable: "The lead's answer couldn't be used, so it was thrown away. Nothing was kept. Send your message again.",
74
74
  };
75
75
  /** A failed turn's saved reason as plain words, for a surface that reads the turn back later (a restart, a delivery retry). */
76
- export function mateFailureText(reason) {
76
+ export function leadFailureText(reason) {
77
77
  switch (reason) {
78
78
  case "timeout":
79
- case "crashed": return MATE_FAILURE_COPY.tooLong;
80
- case "malformed-reply": return MATE_FAILURE_COPY.unreadable;
81
- case "secret-refused": return MATE_FAILURE_COPY.secretReply;
82
- case "latched": return MATE_FAILURE_COPY.paused;
83
- case "revoked": return MATE_FAILURE_COPY.ended;
84
- case "superseded": return MATE_FAILURE_COPY.stopped;
85
- case "provider-error": return MATE_FAILURE_COPY.refused;
79
+ case "crashed": return LEAD_FAILURE_COPY.tooLong;
80
+ case "malformed-reply": return LEAD_FAILURE_COPY.unreadable;
81
+ case "secret-refused": return LEAD_FAILURE_COPY.secretReply;
82
+ case "latched": return LEAD_FAILURE_COPY.paused;
83
+ case "revoked": return LEAD_FAILURE_COPY.ended;
84
+ case "superseded": return LEAD_FAILURE_COPY.stopped;
85
+ case "provider-error": return LEAD_FAILURE_COPY.refused;
86
86
  default: return "The lead's reply didn't finish. Nothing it proposed was kept. Send your message again.";
87
87
  }
88
88
  }
89
89
  /** How long a provider that ignored its abort at the turn's deadline is waited for before the turn ends without it.
90
90
  * Its process group was already killed at the deadline; this only bounds the wait for the transport to say so. */
91
- export const MATE_ABORT_GRACE_MS = 5_000;
91
+ export const LEAD_ABORT_GRACE_MS = 5_000;
92
92
  const LATE = Symbol("late");
93
93
  /** The work's own result, or LATE once `ms` passes: the turn's clock, not the work, decides when the person hears back. */
94
94
  function settleBy(work, ms) {
@@ -99,7 +99,7 @@ function settleBy(work, ms) {
99
99
  const READ_TOOLS = new Set(["get_brief", "get_project_context", "get_actions", "get_action_status", "get_skills", "get_acceptance_evidence", "recap", "list_repos", "list_tasks", "get_task", "get_result", "get_result_images", "get_controls", "get_agents", "get_project_knowledge", "get_task_conversation", "get_diff", "get_check_log", "get_project_tools", "get_flows", "get_flow_insights", "list_decisions", "get_decision", "queue"]);
100
100
  /** The last messages of the thread as provider-neutral history, newest kept first until the byte cap. */
101
101
  export function historyFor(store, thread, queuedMessageId) {
102
- const rows = store.listMateMessages(thread, MATE_HISTORY_MAX_MESSAGES);
102
+ const rows = store.listLeadMessages(thread, LEAD_HISTORY_MAX_MESSAGES);
103
103
  const kept = [];
104
104
  let bytes = 0;
105
105
  for (let index = rows.length - 1; index >= 0; index--) {
@@ -109,9 +109,9 @@ export function historyFor(store, thread, queuedMessageId) {
109
109
  if (queuedMessageId !== undefined && (row.id === queuedMessageId || row.role === 'operator' && row.turn === null))
110
110
  continue;
111
111
  bytes += Buffer.byteLength(row.text, "utf8");
112
- if (bytes > MATE_HISTORY_CAP_BYTES)
112
+ if (bytes > LEAD_HISTORY_CAP_BYTES)
113
113
  break;
114
- const author = queuedMessageId !== undefined && row.role === 'operator' && row.turn !== null ? store.getMateTurn(row.turn)?.approver : undefined;
114
+ const author = queuedMessageId !== undefined && row.role === 'operator' && row.turn !== null ? store.getLeadTurn(row.turn)?.approver : undefined;
115
115
  kept.unshift(row.role === "operator" ? { role: "operator", text: author ? `From ${author}:\n${row.text}` : row.text } : { role: "assistant", text: row.text, calls: [] });
116
116
  }
117
117
  // A history must open with the operator: a leading assistant reply without its question is dropped.
@@ -126,17 +126,17 @@ export function activitySummary(reads, proposals, steps) {
126
126
  /** A tool result as the model sees it, measured as embedded; over the cap it becomes a typed refusal. */
127
127
  function capped(value) {
128
128
  const text = JSON.stringify(value);
129
- if (toolResultBytes(text) <= MATE_TOOL_RESULT_CAP_BYTES)
129
+ if (toolResultBytes(text) <= LEAD_TOOL_RESULT_CAP_BYTES)
130
130
  return text;
131
131
  return JSON.stringify({ ok: false, message: "that result is over the size cap — ask for less: one project, one state, or a smaller limit" });
132
132
  }
133
- export async function runMateTurn(input) {
133
+ export async function runLeadTurn(input) {
134
134
  const { store, who, session, thread, config } = input;
135
135
  const clock = input.clock ?? (() => new Date());
136
136
  const fetcher = input.fetcher ?? fetch;
137
- const refuse = (refused) => ({ ok: false, refused, message: MATE_REFUSAL_COPY[refused] });
137
+ const refuse = (refused) => ({ ok: false, refused, message: LEAD_REFUSAL_COPY[refused] });
138
138
  const message = input.message.trim();
139
- if (message === "" || message.length > MATE_MESSAGE_MAX_CHARS)
139
+ if (message === "" || message.length > LEAD_MESSAGE_MAX_CHARS)
140
140
  return refuse("empty-message");
141
141
  // Secrets refuse BEFORE any row or request exists — nothing stored, nothing sent.
142
142
  if (scanForSecrets(message).length > 0)
@@ -170,8 +170,8 @@ export async function runMateTurn(input) {
170
170
  return refuse("invalid-request");
171
171
  // Replays are read-only, but still require today's authority, not the
172
172
  // session/thread snapshots supplied by a previous browser page.
173
- const liveSession = store.getMateSession(session.id);
174
- const liveThread = store.getMateThread(thread.id);
173
+ const liveSession = store.getLeadSession(session.id);
174
+ const liveThread = store.getLeadThread(thread.id);
175
175
  const sharedThread = liveThread !== null && store.canUseTeamMateThread(who.name, who.generation, liveThread.id);
176
176
  if (liveSession?.approver !== who.name || (liveThread?.approver !== who.name && !sharedThread) || liveSession.credentialKey !== credentialKey)
177
177
  return refuse("not-yours");
@@ -184,28 +184,28 @@ export async function runMateTurn(input) {
184
184
  if (liveSession.ceilingDigest !== who.ceilingDigest || liveThread.ceilingDigest !== who.ceilingDigest)
185
185
  return refuse("ceiling-changed");
186
186
  const digest = createHash("sha256").update(JSON.stringify([thread.id, message, input.context ?? null])).digest("hex");
187
- const receipt = request === undefined ? null : store.mateRequestReceipt(session.id, request);
187
+ const receipt = request === undefined ? null : store.leadRequestReceipt(session.id, request);
188
188
  if (receipt !== null)
189
189
  return receipt.digest === digest ? { ok: true, replayed: true, turn: receipt.turn } : refuse("request-changed");
190
190
  // The channel's standing, proved before anything is admitted or sent.
191
191
  if (input.revalidate !== undefined && !(await input.revalidate()).ok)
192
192
  return refuse("channel");
193
193
  let now = clock();
194
- store.sweepStaleMateTurns(now);
195
- const view = mateViewContextFor(store, who);
194
+ store.sweepStaleLeadTurns(now);
195
+ const view = leadViewContextFor(store, who);
196
196
  // Names in the bundle are deliberate (the lead's, the person's first name, project labels); everything else is scrubbed.
197
- const document = leadContext(store, who.repos, now, { owner: who.name, thread: thread.id, redact: text => redactForMate(text, view),
198
- projectName: (path, index) => projectLabelForMate(path, index, view.names),
197
+ const document = leadContext(store, who.repos, now, { owner: who.name, thread: thread.id, redact: text => redactForLead(text, view),
198
+ projectName: (path, index) => projectLabelForLead(path, index, view.names),
199
199
  ...(input.evidenceRoot === undefined ? {} : { evidenceRoot: input.evidenceRoot }), ...(input.channel === undefined ? {} : { channel: input.channel }), ...(input.leadName === undefined ? {} : { leadName: input.leadName }) });
200
200
  const authoredMessage = input.queuedMessageId === undefined ? message : `From ${who.name}:\n${message}`;
201
- const historyMessage = input.context === undefined ? authoredMessage : `${redactForMate(input.context, view)}\n\n${authoredMessage}`;
201
+ const historyMessage = input.context === undefined ? authoredMessage : `${redactForLead(input.context, view)}\n\n${authoredMessage}`;
202
202
  const history = [...historyFor(store, thread.id, input.queuedMessageId), { role: "operator", text: historyMessage }];
203
203
  const composeDirect = (key) => {
204
204
  if (!direct)
205
205
  throw new Error("not a direct chat provider");
206
- return composeMateRequest({ provider: directProvider, model: config.model, key, system: MATE_CONTRACT, dataDocument: document, history, tools: MATE_TOOL_SCHEMAS });
206
+ return composeLeadRequest({ provider: directProvider, model: config.model, key, system: LEAD_CONTRACT, dataDocument: document, history, tools: LEAD_TOOL_SCHEMAS });
207
207
  };
208
- const composeSubscription = () => composeSubscriptionMatePrompt({ system: MATE_CONTRACT, dataDocument: document, history, tools: MATE_TOOL_SCHEMAS });
208
+ const composeSubscription = () => composeSubscriptionLeadPrompt({ system: LEAD_CONTRACT, dataDocument: document, history, tools: LEAD_TOOL_SCHEMAS });
209
209
  // The exact outbound base is scanned whole. Only direct API traffic needs
210
210
  // a worst-case dollar reservation; subscription traffic records zero.
211
211
  const base = direct ? composeDirect("").body : composeSubscription();
@@ -214,9 +214,9 @@ export async function runMateTurn(input) {
214
214
  // Fit the bounded tool loop to the already-authorized remaining allowance.
215
215
  // Context/history growth must not demand a larger budget for a simple reply.
216
216
  // Each chosen step retains the same worst-case call/output accounting.
217
- let maxSteps = MATE_MAX_STEPS;
217
+ let maxSteps = LEAD_MAX_STEPS;
218
218
  const baseBytes = Buffer.byteLength(base, "utf8");
219
- const reserveFor = (steps) => direct ? mateWorstCaseForPrice(price, baseBytes, { steps }) : 0;
219
+ const reserveFor = (steps) => direct ? leadWorstCaseForPrice(price, baseBytes, { steps }) : 0;
220
220
  if (direct) {
221
221
  const remaining = Math.min(liveSession.ceilingMicrousd - liveSession.spentMicrousd, config.weeklyCeilingMicrousd - store.chatWeeklySpendMicrousd(credentialKey, now));
222
222
  while (maxSteps > 1 && reserveFor(maxSteps) > remaining)
@@ -224,12 +224,12 @@ export async function runMateTurn(input) {
224
224
  }
225
225
  const reserved = reserveFor(maxSteps);
226
226
  const admitted = store.transact(() => {
227
- const existing = request === undefined ? null : store.mateRequestReceipt(session.id, request);
227
+ const existing = request === undefined ? null : store.leadRequestReceipt(session.id, request);
228
228
  if (existing !== null)
229
229
  return existing.digest === digest
230
230
  ? { ok: true, replayed: true, turnId: existing.turn }
231
231
  : { ok: false, reason: "request-changed" };
232
- const opened = store.openMateTurn({
232
+ const opened = store.openLeadTurn({
233
233
  approver: who.name,
234
234
  session: session.id,
235
235
  thread: thread.id,
@@ -243,13 +243,13 @@ export async function runMateTurn(input) {
243
243
  if (!opened.ok)
244
244
  return opened;
245
245
  const turnId = opened.id;
246
- const started = store.startMateTurn(turnId, now);
246
+ const started = store.startLeadTurn(turnId, now);
247
247
  if (!started.ok)
248
- throw new Error("new mate turn could not start");
248
+ throw new Error("new lead turn could not start");
249
249
  if (input.queuedMessageId === undefined)
250
- store.appendMateMessage({ thread: thread.id, turn: turnId, role: "operator", text: message }, now);
250
+ store.appendLeadMessage({ thread: thread.id, turn: turnId, role: "operator", text: message }, now);
251
251
  else {
252
- const bound = store.handle.prepare("UPDATE mate_message SET turn=? WHERE id=? AND thread=? AND role='operator' AND turn IS NULL AND text=?")
252
+ const bound = store.handle.prepare("UPDATE lead_message SET turn=? WHERE id=? AND thread=? AND role='operator' AND turn IS NULL AND text=?")
253
253
  .run(turnId, input.queuedMessageId, thread.id, message);
254
254
  if (Number(bound.changes) !== 1)
255
255
  throw new Error('The queued message changed before admission.');
@@ -279,63 +279,63 @@ export async function runMateTurn(input) {
279
279
  const searchedMemory = new Map();
280
280
  const checkedCapabilities = new Map();
281
281
  /** The turn's one question to its owner: shown with the reply only once the turn answers; a failed turn drops it. */
282
- const ask = (question, options) => store.recordMateAsk({ turn: turnId, thread: thread.id, question, options }, clock());
282
+ const ask = (question, options) => store.recordLeadAsk({ turn: turnId, thread: thread.id, question, options }, clock());
283
283
  let tokensIn = 0;
284
284
  let tokensOut = 0;
285
285
  let settled = 0;
286
286
  const draft = (kind, payload) => {
287
- if (proposals >= MATE_MAX_PROPOSALS_PER_TURN)
287
+ if (proposals >= LEAD_MAX_PROPOSALS_PER_TURN)
288
288
  return null;
289
289
  proposals++;
290
- return store.draftMateProposal({ thread: thread.id, turn: turnId, kind, payload, ceilingDigest: who.ceilingDigest }, clock());
290
+ return store.draftLeadProposal({ thread: thread.id, turn: turnId, kind, payload, ceilingDigest: who.ceilingDigest }, clock());
291
291
  };
292
292
  /** The screenshots a tool selected, kept under THIS turn: a failed turn deletes them with its drafts; a channel plans sends only from an answered turn. */
293
293
  const selectEvidence = (rows) => {
294
- store.recordMateTurnEvidence(turnId, rows, RESULT_IMAGES_PER_TURN_CAP, clock());
295
- if (store.getMateTurn(turnId)?.state !== "running")
294
+ store.recordLeadTurnEvidence(turnId, rows, RESULT_IMAGES_PER_TURN_CAP, clock());
295
+ if (store.getLeadTurn(turnId)?.state !== "running")
296
296
  return [];
297
- return store.listMateTurnEvidence(turnId).map(one => one.artifact);
297
+ return store.listLeadTurnEvidence(turnId).map(one => one.artifact);
298
298
  };
299
299
  /** The turn ends failed: its drafts are deleted, its cost settled — the whole reservation when any of it is unknown. */
300
300
  const fail = (failed, message, unknownSpend) => {
301
301
  now = clock();
302
- store.finalizeMateTurn(turnId, started.generation, { state: "failed", settledMicrousd: settled, unknownSpend, tokensIn, tokensOut, failureReason: failed }, now);
303
- store.dropMateAsk(turnId);
302
+ store.finalizeLeadTurn(turnId, started.generation, { state: "failed", settledMicrousd: settled, unknownSpend, tokensIn, tokensOut, failureReason: failed }, now);
303
+ store.dropLeadAsk(turnId);
304
304
  return { ok: false, turn: turnId, failed, message, unknownSpend };
305
305
  };
306
306
  /** The turn stopped at its deadline: the notice is saved in the thread with whatever its completed tool calls proposed, in
307
307
  * the same write that ends the turn, so a refresh, another device or a restart shows the same outcome. */
308
308
  const timedOut = (unknownSpend) => {
309
309
  now = clock();
310
- const message = mateTimeoutNotice(proposals > 0, unknownSpend);
311
- const saved = store.finalizeMateTurn(turnId, started.generation, { state: "failed", settledMicrousd: settled, unknownSpend, tokensIn, tokensOut, failureReason: "timeout", keepProposals: true, message: { text: message, activity: activitySummary(reads, proposals, steps) } }, now);
312
- store.dropMateAsk(turnId);
310
+ const message = leadTimeoutNotice(proposals > 0, unknownSpend);
311
+ const saved = store.finalizeLeadTurn(turnId, started.generation, { state: "failed", settledMicrousd: settled, unknownSpend, tokensIn, tokensOut, failureReason: "timeout", keepProposals: true, message: { text: message, activity: activitySummary(reads, proposals, steps) } }, now);
312
+ store.dropLeadAsk(turnId);
313
313
  if (!saved)
314
- return { ok: false, turn: turnId, failed: "superseded", message: MATE_FAILURE_COPY.stopped, unknownSpend: false };
314
+ return { ok: false, turn: turnId, failed: "superseded", message: LEAD_FAILURE_COPY.stopped, unknownSpend: false };
315
315
  return { ok: false, turn: turnId, failed: "timeout", message, unknownSpend, saved: true };
316
316
  };
317
317
  const deadlineLeft = () => TURN_WALL_CLOCK_MS - (clock().getTime() - turnStartedAt);
318
318
  /** The channel's standing, bounded by the turn's deadline: a lookup that never answers cannot hold the turn open. */
319
- const revalidated = async () => input.revalidate === undefined ? { ok: true } : settleBy(input.revalidate(), deadlineLeft() + MATE_ABORT_GRACE_MS);
319
+ const revalidated = async () => input.revalidate === undefined ? { ok: true } : settleBy(input.revalidate(), deadlineLeft() + LEAD_ABORT_GRACE_MS);
320
320
  /** The turn's own row, re-read: still running under our generation, or someone ended it under us. */
321
321
  const stillOurs = () => {
322
- const row = store.getMateTurn(turnId);
322
+ const row = store.getLeadTurn(turnId);
323
323
  return row !== null && row.state === "running" && row.generation === started.generation;
324
324
  };
325
325
  // The channel lookup can await external state. Re-read all local authority
326
326
  // AFTER it resolves, immediately before sending context or using a tool.
327
327
  const guard = (channel) => {
328
328
  if (!stillOurs())
329
- return { ok: false, turn: turnId, failed: "superseded", message: MATE_FAILURE_COPY.stopped, unknownSpend: false };
329
+ return { ok: false, turn: turnId, failed: "superseded", message: LEAD_FAILURE_COPY.stopped, unknownSpend: false };
330
330
  if (channel === LATE)
331
331
  return timedOut(false);
332
332
  if (!channel.ok)
333
- return fail("revoked", MATE_CHANNEL_COPY[channel.reason] ?? MATE_CHANNEL_COPY["access-changed"], false);
333
+ return fail("revoked", LEAD_CHANNEL_COPY[channel.reason] ?? LEAD_CHANNEL_COPY["access-changed"], false);
334
334
  const standing = reproveApprover(store, who);
335
- const liveSession = store.getMateSession(session.id);
336
- const liveThread = store.getMateThread(thread.id);
335
+ const liveSession = store.getLeadSession(session.id);
336
+ const liveThread = store.getLeadThread(thread.id);
337
337
  if (!standing.ok || liveSession === null || liveSession.endedAt !== null || liveThread === null || liveThread.closedAt !== null) {
338
- return fail("revoked", MATE_FAILURE_COPY.ended, false);
338
+ return fail("revoked", LEAD_FAILURE_COPY.ended, false);
339
339
  }
340
340
  return null;
341
341
  };
@@ -351,7 +351,7 @@ export async function runMateTurn(input) {
351
351
  const replyLimit = input.channel === undefined ? null : LEAD_REPLY_LIMITS[input.channel];
352
352
  const unbacked = (text) => {
353
353
  const claim = deliverableClaim(text);
354
- if (claim === null || shownControl || replyCarriesDeliverable(text) || store.listMateTurnEvidence(turnId).length > 0)
354
+ if (claim === null || shownControl || replyCarriesDeliverable(text) || store.listLeadTurnEvidence(turnId).length > 0)
355
355
  return null;
356
356
  return claim;
357
357
  };
@@ -367,42 +367,42 @@ export async function runMateTurn(input) {
367
367
  // Tool results join the outbound body: scanned again before every dispatch.
368
368
  const outbound = typeof request === "string" ? request : request.body;
369
369
  if (scanForSecrets(outbound).length > 0) {
370
- return fail("secret-refused", MATE_FAILURE_COPY.secretRead, false);
370
+ return fail("secret-refused", LEAD_FAILURE_COPY.secretRead, false);
371
371
  }
372
- const step = store.openMateStep({ mateTurn: turnId, generation: started.generation, approver: who.name, credentialKey, provider: config.provider, model: config.model, deadlineMs: remainingMs + 10_000 }, now);
372
+ const step = store.openLeadStep({ leadTurn: turnId, generation: started.generation, approver: who.name, credentialKey, provider: config.provider, model: config.model, deadlineMs: remainingMs + 10_000 }, now);
373
373
  if (!step.ok) {
374
374
  if (step.reason === "latched")
375
- return fail("latched", MATE_FAILURE_COPY.paused, false);
376
- return { ok: false, turn: turnId, failed: "superseded", message: MATE_FAILURE_COPY.stopped, unknownSpend: false };
375
+ return fail("latched", LEAD_FAILURE_COPY.paused, false);
376
+ return { ok: false, turn: turnId, failed: "superseded", message: LEAD_FAILURE_COPY.stopped, unknownSpend: false };
377
377
  }
378
378
  const stepStarted = store.startChatTurn(step.id, now);
379
379
  if (!stepStarted.ok)
380
- return fail("provider-error", MATE_FAILURE_COPY.notStarted, false);
380
+ return fail("provider-error", LEAD_FAILURE_COPY.notStarted, false);
381
381
  steps++;
382
382
  progress({ kind: "step", turn: turnId, step: steps });
383
383
  const requestBytes = Buffer.byteLength(outbound, "utf8");
384
384
  let result;
385
385
  // The turn owns its deadline (lead-stall, release check 2438): at the deadline the request is aborted, which ends a
386
- // harness's whole process group, and a provider that still has not settled MATE_ABORT_GRACE_MS later is left behind.
386
+ // harness's whole process group, and a provider that still has not settled LEAD_ABORT_GRACE_MS later is left behind.
387
387
  // Whatever it says after that is never read; the turn has already ended with its notice.
388
388
  const controller = new AbortController();
389
389
  const abortAt = setTimeout(() => controller.abort(), remainingMs);
390
- const settle = (work) => settleBy(work, remainingMs + MATE_ABORT_GRACE_MS)
390
+ const settle = (work) => settleBy(work, remainingMs + LEAD_ABORT_GRACE_MS)
391
391
  .then(value => value === LATE || controller.signal.aborted ? { ok: false, problem: "timeout" } : value)
392
392
  .finally(() => clearTimeout(abortAt));
393
393
  if (direct) {
394
- result = await settle(performMateRequest(request, directProvider, controller.signal, fetcher)
394
+ result = await settle(performLeadRequest(request, directProvider, controller.signal, fetcher)
395
395
  .catch(() => ({ ok: false, problem: "network" })));
396
396
  }
397
397
  else {
398
- const runner = input.subscriptionRunner ?? performSubscriptionMateRequest;
398
+ const runner = input.subscriptionRunner ?? performSubscriptionLeadRequest;
399
399
  result = await settle((async () => runner({
400
400
  provider: subscriptionProvider,
401
401
  model: config.model,
402
- system: MATE_CONTRACT,
402
+ system: LEAD_CONTRACT,
403
403
  dataDocument: document,
404
404
  history,
405
- tools: MATE_TOOL_SCHEMAS,
405
+ tools: LEAD_TOOL_SCHEMAS,
406
406
  timeoutMs: remainingMs,
407
407
  signal: controller.signal,
408
408
  // The reply as it is written; text that looks like a secret is
@@ -417,12 +417,12 @@ export async function runMateTurn(input) {
417
417
  if (!direct) {
418
418
  finishStep({ state: "failed", failureReason: result.problem === "timeout" ? "timeout" : result.problem === "malformed-reply" ? "malformed-reply" : "provider-error", settledMicrousd: 0 });
419
419
  const message = result.problem === "not-found"
420
- ? MATE_FAILURE_COPY.notInstalled
420
+ ? LEAD_FAILURE_COPY.notInstalled
421
421
  : result.problem === "timeout"
422
- ? MATE_FAILURE_COPY.tooLong
422
+ ? LEAD_FAILURE_COPY.tooLong
423
423
  : result.problem === "malformed-reply"
424
- ? MATE_FAILURE_COPY.unreadable
425
- : MATE_FAILURE_COPY.signIn;
424
+ ? LEAD_FAILURE_COPY.unreadable
425
+ : LEAD_FAILURE_COPY.signIn;
426
426
  if (result.problem === "timeout")
427
427
  return timedOut(false);
428
428
  return fail(result.problem === "malformed-reply" ? "malformed-reply" : "provider-error", message, false);
@@ -430,7 +430,7 @@ export async function runMateTurn(input) {
430
430
  if (result.problem.startsWith("status-")) {
431
431
  // The provider ANSWERED with an error: nothing billed for this step.
432
432
  finishStep({ state: "failed", failureReason: "provider-error", settledMicrousd: 0 });
433
- return fail("provider-error", MATE_FAILURE_COPY.refused, false);
433
+ return fail("provider-error", LEAD_FAILURE_COPY.refused, false);
434
434
  }
435
435
  if (result.problem === "timeout") {
436
436
  finishStep({ state: "failed", failureReason: "timeout", settledMicrousd: null, unknownSpend: true });
@@ -438,17 +438,17 @@ export async function runMateTurn(input) {
438
438
  }
439
439
  if (result.problem === "network") {
440
440
  finishStep({ state: "failed", failureReason: "provider-error", settledMicrousd: null, unknownSpend: true });
441
- return fail("provider-error", MATE_FAILURE_COPY.lostUnknownCost, true);
441
+ return fail("provider-error", LEAD_FAILURE_COPY.lostUnknownCost, true);
442
442
  }
443
443
  finishStep({ state: "failed", failureReason: "malformed-reply", settledMicrousd: null, unknownSpend: true });
444
- return fail("malformed-reply", MATE_FAILURE_COPY.unreadableUnknownCost, true);
444
+ return fail("malformed-reply", LEAD_FAILURE_COPY.unreadableUnknownCost, true);
445
445
  }
446
446
  const answer = result.answer;
447
447
  // Usage that cannot be true — more input tokens than bytes sent — is a
448
448
  // malformed reply with unknown cost, never a number to settle by.
449
449
  if (direct && answer.tokensIn > requestBytes) {
450
450
  finishStep({ state: "failed", failureReason: "malformed-reply", settledMicrousd: null, unknownSpend: true });
451
- return fail("malformed-reply", MATE_FAILURE_COPY.unreadableUnknownCost, true);
451
+ return fail("malformed-reply", LEAD_FAILURE_COPY.unreadableUnknownCost, true);
452
452
  }
453
453
  // The pinned math, or the provider's own reported charge when HIGHER.
454
454
  const stepSettled = direct
@@ -467,7 +467,7 @@ export async function runMateTurn(input) {
467
467
  return changed;
468
468
  if (answer.calls.length === 0) {
469
469
  if (answer.text.trim() === "")
470
- return fail("malformed-reply", MATE_FAILURE_COPY.empty, false);
470
+ return fail("malformed-reply", LEAD_FAILURE_COPY.empty, false);
471
471
  // "Here's the screenshot" with nothing attached or linked: one repair step to attach it or drop the claim; never the claim alone.
472
472
  const claim = unbacked(answer.text);
473
473
  if (claim !== null && !repaired && steps < maxSteps) {
@@ -486,11 +486,11 @@ export async function runMateTurn(input) {
486
486
  reply = candidate;
487
487
  break;
488
488
  }
489
- if (answer.calls.length > MATE_MAX_CALLS_PER_STEP)
490
- return fail("malformed-reply", MATE_FAILURE_COPY.unusable, false);
489
+ if (answer.calls.length > LEAD_MAX_CALLS_PER_STEP)
490
+ return fail("malformed-reply", LEAD_FAILURE_COPY.unusable, false);
491
491
  for (const call of answer.calls) {
492
- if (!isMateTool(call.name))
493
- return fail("malformed-reply", MATE_FAILURE_COPY.unusable, false);
492
+ if (!isLeadTool(call.name))
493
+ return fail("malformed-reply", LEAD_FAILURE_COPY.unusable, false);
494
494
  }
495
495
  history.push({ role: "assistant", text: answer.text, calls: answer.calls });
496
496
  for (const [index, call] of answer.calls.entries()) {
@@ -501,13 +501,13 @@ export async function runMateTurn(input) {
501
501
  }
502
502
  // Position within this turn is unique even if a provider reuses call ids.
503
503
  const progressId = `${turnId}:${steps}:${index}`;
504
- progress({ kind: "tool", turn: turnId, step: steps, id: progressId, label: mateToolLabel(call.name) });
505
- const outcome = executeMateTool({ store, who, now: clock(), draft, selectEvidence, step: steps, readDecisions, readResults, searchedMemory, checkedCapabilities, ask, ...(input.integrations === undefined ? {} : { integrations: input.integrations }), thread: thread.id, turn: turnId, ...(promiseChannelOfTurn(input.channel) === undefined ? {} : { channel: promiseChannelOfTurn(input.channel) }), ...(input.evidenceRoot === undefined ? {} : { evidenceRoot: input.evidenceRoot }), ...(input.mediaDelivery === undefined ? {} : { mediaDelivery: input.mediaDelivery }) }, call.name, call.args, view);
504
+ progress({ kind: "tool", turn: turnId, step: steps, id: progressId, label: leadToolLabel(call.name) });
505
+ const outcome = executeLeadTool({ store, who, now: clock(), draft, selectEvidence, step: steps, readDecisions, readResults, searchedMemory, checkedCapabilities, ask, ...(input.integrations === undefined ? {} : { integrations: input.integrations }), thread: thread.id, turn: turnId, ...(promiseChannelOfTurn(input.channel) === undefined ? {} : { channel: promiseChannelOfTurn(input.channel) }), ...(input.evidenceRoot === undefined ? {} : { evidenceRoot: input.evidenceRoot }), ...(input.mediaDelivery === undefined ? {} : { mediaDelivery: input.mediaDelivery }) }, call.name, call.args, view);
506
506
  let displayOutcome = { state: "succeeded" };
507
507
  if (!outcome.ok) {
508
- const reason = mateToolFailureReason(call.name, outcome.message);
508
+ const reason = leadToolFailureReason(call.name, outcome.message);
509
509
  displayOutcome = { state: "failed", reason: scanForSecrets(reason).length === 0
510
- ? reason : `That step didn't work (${mateToolLabel(call.name)}).` };
510
+ ? reason : `That step didn't work (${leadToolLabel(call.name)}).` };
511
511
  }
512
512
  progress({ kind: "tool-result", turn: turnId, step: steps, id: progressId, outcome: displayOutcome });
513
513
  if (READ_TOOLS.has(call.name))
@@ -516,7 +516,7 @@ export async function runMateTurn(input) {
516
516
  shownControl = true;
517
517
  // Opt-in, local diagnostics for end-to-end runs: what the lead asked of each tool and what came back (its start), keys
518
518
  // blanked. Each line stays whole JSON so a run can assert on what a tool returned rather than on the model's words.
519
- if (envValue(process.env, "MATE_TRACE") === "1") {
519
+ if (envValue(process.env, "LEAD_TRACE") === "1" || envValue(process.env, "MATE_TRACE") === "1") { // MATE_TRACE: the name before D5
520
520
  const blanked = (_, value) => typeof value === "string" ? redactSecretAssignments(redactSecretLines(value, scanForSecrets(value))) : value;
521
521
  const args = JSON.stringify(call.args, blanked).slice(0, 1500);
522
522
  const result = JSON.stringify(outcome.ok ? outcome.body : null, blanked)?.slice(0, 2000) ?? null;
@@ -528,16 +528,16 @@ export async function runMateTurn(input) {
528
528
  if (reply === null) {
529
529
  stoppedAtCap = true;
530
530
  const last = lastText.trim() === "" || unbacked(lastText) === null ? lastText.trim() : dropDeliverableClaims(lastText);
531
- reply = `${last === "" ? "" : `${last}\n\n`}(I stopped here: this answer needed more steps than ${maxSteps < MATE_MAX_STEPS ? "this conversation's remaining spending allows" : "one reply allows"}. Ask me to carry on.)`;
531
+ reply = `${last === "" ? "" : `${last}\n\n`}(I stopped here: this answer needed more steps than ${maxSteps < LEAD_MAX_STEPS ? "this conversation's remaining spending allows" : "one reply allows"}. Ask me to carry on.)`;
532
532
  }
533
533
  // Ruling 11: model text is scanned before it becomes durable.
534
534
  if (scanForSecrets(reply).length > 0)
535
- return fail("secret-refused", MATE_FAILURE_COPY.secretReply, false);
535
+ return fail("secret-refused", LEAD_FAILURE_COPY.secretReply, false);
536
536
  now = clock();
537
537
  const activity = activitySummary(reads, proposals, steps);
538
538
  // One write (finding 12): settle, debit, promote the drafts, append the assistant text.
539
- const finalized = store.finalizeMateTurn(turnId, started.generation, { state: "answered", settledMicrousd: settled, tokensIn, tokensOut, message: { text: reply, activity } }, now);
539
+ const finalized = store.finalizeLeadTurn(turnId, started.generation, { state: "answered", settledMicrousd: settled, tokensIn, tokensOut, message: { text: reply, activity } }, now);
540
540
  if (!finalized)
541
- return { ok: false, turn: turnId, failed: "superseded", message: MATE_FAILURE_COPY.stopped, unknownSpend: false };
541
+ return { ok: false, turn: turnId, failed: "superseded", message: LEAD_FAILURE_COPY.stopped, unknownSpend: false };
542
542
  return { ok: true, turn: turnId, reply, activity, proposals, steps, stoppedAtCap, settledMicrousd: settled };
543
543
  }