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
package/dist/coding-ui.js CHANGED
@@ -1,24 +1,23 @@
1
1
  import { randomUUID } from 'node:crypto';
2
- const escape = (value) => String(value ?? '').replace(/[&<>"']/g, c => ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;' }[c]));
3
- const hidden = (values) => Object.entries(values).map(([name, value]) => `<input type="hidden" name="${escape(name)}" value="${escape(value)}">`).join('');
2
+ import { html, joinHtml, postForm } from './html.js';
4
3
  function linkedText(text) {
5
4
  const pattern = /\[([^\]\n]+)\]\((https?:\/\/[^\s)]+)\)|\x60([^\x60\n]+)\x60|\*\*([^*\n]+)\*\*|(https?:\/\/[^\s<>]+)/g;
6
5
  let end = 0;
7
- let output = '';
6
+ const output = [];
8
7
  for (const match of text.matchAll(pattern)) {
9
- output += escape(text.slice(end, match.index));
8
+ output.push(html `${text.slice(end, match.index)}`);
10
9
  if (match[3] !== undefined)
11
- output += `<code>${escape(match[3])}</code>`;
10
+ output.push(html `<code>${match[3]}</code>`);
12
11
  else if (match[4] !== undefined)
13
- output += `<strong>${escape(match[4])}</strong>`;
12
+ output.push(html `<strong>${match[4]}</strong>`);
14
13
  else {
15
14
  const raw = match[2] ?? match[5];
16
15
  const url = raw.replace(/[.,;!?]+$/, '');
17
- output += `<a href="${escape(url)}" target="_blank" rel="noopener noreferrer">${escape(match[1] ?? url)}</a>${escape(raw.slice(url.length))}`;
16
+ output.push(html `<a href="${url}" target="_blank" rel="noopener noreferrer">${match[1] ?? url}</a>${raw.slice(url.length)}`);
18
17
  }
19
18
  end = match.index + match[0].length;
20
19
  }
21
- return output + escape(text.slice(end));
20
+ return html `${output}${text.slice(end)}`;
22
21
  }
23
22
  function friendlyCodingError(message) {
24
23
  return /already has an active writer/i.test(message)
@@ -27,57 +26,59 @@ function friendlyCodingError(message) {
27
26
  }
28
27
  function noticeHtml(message) {
29
28
  const friendly = friendlyCodingError(message);
30
- return escape(friendly) + (friendly === message ? '' : `<details><summary>Technical details</summary><pre>${escape(message)}</pre></details>`);
29
+ return html `${friendly}${friendly === message ? '' : html `<details><summary>Technical details</summary><pre>${message}</pre></details>`}`;
31
30
  }
32
31
  const sessionUrl = (id) => `/code/${encodeURIComponent(id)}`;
33
32
  const active = (status) => ['starting', 'working', 'needs-input', 'stopping'].includes(status);
34
33
  const stateLabel = (session, requests = []) => ({ starting: 'Starting Codex', ready: 'Ready', working: 'Working', 'needs-input': requests.some(r => r.kind !== 'questions') ? 'Permission needed' : 'Needs your answer', stopping: 'Stopping', interrupted: 'Stopped', failed: 'Stopped with an error', uncertain: 'Delivery not confirmed', closed: 'Session closed' }[session.status]);
35
34
  function itemHtml(item) {
36
35
  if (item.type === 'reasoning')
37
- return '';
36
+ return html ``;
38
37
  const role = ['user', 'userMessage'].includes(item.type) ? 'You' : ['agent', 'assistant', 'agentMessage'].includes(item.type) ? 'Codex' : null;
39
38
  if (role)
40
- return `<article class="coding-message${role === 'You' ? ' coding-user' : ''}" data-coding-item="${escape(item.id)}"><strong>${role}</strong><div class="coding-text">${linkedText(item.text)}</div></article>`;
39
+ return html `<article class="coding-message${role === 'You' ? ' coding-user' : ''}" data-coding-item="${item.id}"><strong>${role}</strong><div class="coding-text">${linkedText(item.text)}</div></article>`;
41
40
  const title = { commandExecution: 'Command', fileChange: 'File changes', mcpToolCall: 'Tool', reasoning: 'Reasoning', plan: 'Plan', error: 'Error' }[item.type] ?? 'Activity';
42
- return `<details class="coding-tool" data-coding-item="${escape(item.id)}"><summary>${title}${item.status ? ` <span class="coding-meta">${escape(item.status)}</span>` : ''}</summary><pre>${escape(item.text)}</pre></details>`;
41
+ return html `<details class="coding-tool" data-coding-item="${item.id}"><summary>${title}${item.status ? html ` <span class="coding-meta">${item.status}</span>` : ''}</summary><pre>${item.text}</pre></details>`;
43
42
  }
44
- function requestHtml(request, session, csrf) {
43
+ function requestHtml(request, session) {
45
44
  const questions = request.kind === 'questions';
46
- const body = questions ? request.questions.map((q, index) => `<label>${escape(q.question)}<input type="text" name="question:${escape(q.id)}"${q.options.length ? ` list="coding-options-${escape(request.id)}-${index}"` : ''} required autocomplete="off">${q.options.length ? `<datalist id="coding-options-${escape(request.id)}-${index}">${q.options.map(o => `<option value="${escape(o.label)}">${escape(o.description)}</option>`).join('')}</datalist>` : ''}</label>`).join('') : `<pre class="coding-permission-detail">${escape(request.detail)}</pre><label>Password to approve this request<input type="password" name="password" autocomplete="current-password" required></label>`;
47
- return `<section class="coding-request" data-coding-request="${escape(request.id)}"><h3>${escape(request.title || (questions ? 'Your answer' : 'Allow extra access?'))}</h3><form method="post" action="${sessionUrl(session)}/answer" data-coding-form="answer">${hidden({ csrf, requestId: request.id })}${body}<div class="coding-actions"><button type="submit" name="decision" value="accept">${questions ? 'Send answer' : 'Approve access'}</button><button type="submit" name="decision" value="decline" formnovalidate class="coding-secondary">${questions ? 'Cancel question' : 'Decline'}</button></div></form></section>`;
45
+ const body = questions ? request.questions.map((q, index) => html `<label>${q.question}<input type="text" name="question:${q.id}"${q.options.length ? html ` list="coding-options-${request.id}-${index}"` : ''} required autocomplete="off">${q.options.length ? html `<datalist id="coding-options-${request.id}-${index}">${q.options.map(o => html `<option value="${o.label}">${o.description}</option>`)}</datalist>` : ''}</label>`) : html `<pre class="coding-permission-detail">${request.detail}</pre><label>Password to approve this request<input type="password" name="password" autocomplete="current-password" required></label>`;
46
+ return html `<section class="coding-request" data-coding-request="${request.id}"><h3>${request.title || (questions ? 'Your answer' : 'Allow extra access?')}</h3>${postForm(`${sessionUrl(session)}/answer`, html `${body}<div class="coding-actions"><button type="submit" name="decision" value="accept">${questions ? 'Send answer' : 'Approve access'}</button><button type="submit" name="decision" value="decline" formnovalidate class="coding-secondary">${questions ? 'Cancel question' : 'Decline'}</button></div>`, { attrs: { 'data-coding-form': 'answer' }, hidden: { requestId: request.id } })}</section>`;
48
47
  }
49
- function controlsHtml(session, csrf) {
48
+ function controlsHtml(session) {
50
49
  if (active(session.status) && session.turnId)
51
- return `<form method="post" action="${sessionUrl(session.id)}/stop" data-coding-form="stop">${hidden({ csrf })}<button class="coding-secondary"${session.status === 'stopping' ? ' disabled' : ''}>Stop</button></form>`;
50
+ return postForm(`${sessionUrl(session.id)}/stop`, html `<button class="coding-secondary"${session.status === 'stopping' ? html ` disabled` : ''}>Stop</button>`, { attrs: { 'data-coding-form': 'stop' } });
52
51
  if (session.status === 'uncertain')
53
- return `<form method="post" action="${sessionUrl(session.id)}/${session.deliveryReviewRequired ? 'continue' : 'recover'}" data-coding-form="recover">${hidden({ csrf })}<button>${session.deliveryReviewRequired ? (session.nativeThreadId ? 'Continue with saved work' : 'Keep work and close session') : 'Check saved session'}</button></form>`;
52
+ return postForm(`${sessionUrl(session.id)}/${session.deliveryReviewRequired ? 'continue' : 'recover'}`, html `<button>${session.deliveryReviewRequired ? (session.nativeThreadId ? 'Continue with saved work' : 'Keep work and close session') : 'Check saved session'}</button>`, { attrs: { 'data-coding-form': 'recover' } });
54
53
  if (!session.nativeThreadId && ['closed', 'failed', 'interrupted'].includes(session.status))
55
- return '';
54
+ return html ``;
56
55
  if (['failed', 'interrupted'].includes(session.status))
57
- return `<form method="post" action="${sessionUrl(session.id)}/resume" data-coding-form="resume">${hidden({ csrf })}<button>Resume session</button></form>`;
58
- return '';
56
+ return postForm(`${sessionUrl(session.id)}/resume`, html `<button>Resume session</button>`, { attrs: { 'data-coding-form': 'resume' } });
57
+ return html ``;
59
58
  }
60
59
  export function codingWorkspaceHtml(input) {
61
60
  const { selected, csrf } = input;
62
61
  const selectedRepo = selected?.session.repo ?? input.project;
63
62
  const projectName = (repo) => input.projects.find(p => p.path === repo)?.name ?? repo.split('/').filter(Boolean).at(-1) ?? repo;
64
63
  const newUrl = `/code${selectedRepo ? `?project=${encodeURIComponent(selectedRepo)}` : ''}`;
65
- const sessions = input.sessions.map(session => `<li><a href="${sessionUrl(session.id)}"${selected?.session.id === session.id ? ' aria-current="page"' : ''}><span>${escape(session.title)}</span><small>${escape(projectName(session.repo))} · <span data-coding-status-for="${escape(session.id)}">${escape(stateLabel(session))}</span></small></a></li>`).join('');
66
- const sidebar = `<aside class="coding-sidebar"><div class="coding-sidebar-top"><h2>Sessions</h2>${selected ? `<a class="coding-link-button" href="${escape(newUrl)}">New session</a>` : ''}</div><nav class="coding-session-list" aria-label="Coding sessions"><ul>${sessions || '<li class="coding-meta">No sessions yet.</li>'}</ul></nav><details class="coding-mobile-sessions"><summary>Sessions${input.sessions.length ? ` (${input.sessions.length})` : ''}</summary><nav aria-label="Coding sessions"><ul>${sessions || '<li class="coding-meta">No sessions yet.</li>'}</ul></nav></details></aside>`;
67
- const warning = !input.available ? '<p class="coding-notice">Codex is unavailable on this installation. Install and sign in to Codex on the host to start coding.</p>' : '';
64
+ const sessions = joinHtml(input.sessions.map(session => html `<li><a href="${sessionUrl(session.id)}"${selected?.session.id === session.id ? html ` aria-current="page"` : ''}><span>${session.title}</span><small>${projectName(session.repo)} · <span data-coding-status-for="${session.id}">${stateLabel(session)}</span></small></a></li>`));
65
+ const sessionItems = input.sessions.length ? sessions : html `<li class="coding-meta">No sessions yet.</li>`;
66
+ const sidebar = html `<aside class="coding-sidebar"><div class="coding-sidebar-top"><h2>Sessions</h2>${selected ? html `<a class="coding-link-button" href="${newUrl}">New session</a>` : ''}</div><nav class="coding-session-list" aria-label="Coding sessions"><ul>${sessionItems}</ul></nav><details class="coding-mobile-sessions"><summary>Sessions${input.sessions.length ? ` (${input.sessions.length})` : ''}</summary><nav aria-label="Coding sessions"><ul>${sessionItems}</ul></nav></details></aside>`;
67
+ const warning = !input.available ? html `<p class="coding-notice">Codex is unavailable on this installation. Install and sign in to Codex on the host to start coding.</p>` : '';
68
68
  const error = input.error ?? selected?.session.error ?? '';
69
69
  let main;
70
70
  if (!selected) {
71
- const options = input.projects.map(p => `<option value="${escape(p.path)}"${selectedRepo === p.path ? ' selected' : ''}>${escape(p.name)}</option>`).join('');
72
- main = `<header class="coding-header"><h1>Build with Codex</h1></header>${warning}${input.projects.length ? `<form method="post" action="/code/start" data-coding-form="start" class="coding-start">${hidden({ csrf, requestId: randomUUID() })}<label>Project<select name="repo" required>${options}</select></label><label>What would you like to change?<textarea name="prompt" rows="5" required maxlength="24000" placeholder="Describe the result you want…">${escape(input.draft ?? '')}</textarea></label><details class="coding-options"><summary>Session options</summary><label>Title <span class="coding-meta">Optional</span><input name="title" maxlength="160" autocomplete="off"></label><label>Model <span class="coding-meta">Optional; uses the installed default</span><input name="model" maxlength="120" placeholder="Installed default" autocomplete="off"></label></details><p class="coding-terms">Codex uses this installation’s login and edits a separate copy of this project. It can run commands and read files outside the project. Connected tools (MCP servers) keep their own access to this computer and connected services. Additional command and file access requires your approval.</p><label>Password to start<input type="password" name="password" autocomplete="current-password" required></label><button type="submit"${input.available ? '' : ' disabled'}>Start coding</button></form>` : '<div class="coding-empty"><p>Add a project to start coding.</p><a class="coding-link-button" href="/projects">Open projects</a></div>'}`;
71
+ const options = input.projects.map(p => html `<option value="${p.path}"${selectedRepo === p.path ? html ` selected` : ''}>${p.name}</option>`);
72
+ main = html `<header class="coding-header"><h1>Build with Codex</h1></header>${warning}${input.projects.length ? postForm('/code/start', html `<label>Project<select name="repo" required>${options}</select></label><label>What would you like to change?<textarea name="prompt" rows="5" required maxlength="24000" placeholder="Describe the result you want…">${input.draft ?? ''}</textarea></label><details class="coding-options"><summary>Session options</summary><label>Title <span class="coding-meta">Optional</span><input name="title" maxlength="160" autocomplete="off"></label><label>Model <span class="coding-meta">Optional; uses the installed default</span><input name="model" maxlength="120" placeholder="Installed default" autocomplete="off"></label></details><p class="coding-terms">Codex uses this installation’s login and edits a separate copy of this project. It can run commands and read files outside the project. Connected tools (MCP servers) keep their own access to this computer and connected services. Additional command and file access requires your approval.</p><label>Password to start<input type="password" name="password" autocomplete="current-password" required></label><button type="submit"${input.available ? '' : html ` disabled`}>Start coding</button>`, { attrs: { 'data-coding-form': 'start', class: 'coding-start' }, hidden: { requestId: randomUUID() } }) : html `<div class="coding-empty"><p>Add a project to start coding.</p><a class="coding-link-button" href="/projects">Open projects</a></div>`}`;
73
73
  }
74
74
  else {
75
75
  const s = selected.session;
76
76
  const blocked = !s.nativeThreadId || !['ready', 'working', 'failed', 'interrupted'].includes(s.status);
77
- const messages = selected.items.filter(item => item.type !== 'reasoning').map(itemHtml).join('');
78
- main = `<header class="coding-header"><div><h1>${escape(s.title)}</h1><p class="coding-meta">${escape(projectName(s.repo))} · Codex${s.model ? ` · ${escape(s.model)}` : ''}</p></div><details class="coding-session-detail"><summary aria-label="Session details">Details</summary><dl><dt>Branch</dt><dd>${escape(s.branch)}</dd><dt>Worktree</dt><dd>${escape(s.worktree)}</dd><dt>Native session</dt><dd>${escape(s.nativeThreadId ?? 'Not established')}</dd>${s.initialRequest ? `<dt>Initial request</dt><dd class="coding-text">${escape(s.initialRequest.prompt)}</dd>` : ''}</dl></details></header><div class="coding-state-row"><p id="coding-state" role="status">${escape(stateLabel(s, selected.requests))}</p><div id="coding-controls">${controlsHtml(s, csrf)}</div></div><div id="coding-requests">${selected.requests.map(r => requestHtml(r, s.id, csrf)).join('')}</div><div id="coding-conversation" class="coding-conversation" tabindex="0" aria-label="Conversation"${s.status === 'closed' && !messages ? ' hidden' : ''}>${messages || '<p class="coding-meta coding-no-messages">No messages yet.</p>'}</div><button type="button" id="coding-latest" class="coding-secondary" hidden>Latest update ↓</button><form method="post" action="${sessionUrl(s.id)}/send" data-coding-form="send" class="coding-composer"${s.status === 'closed' ? ' hidden' : ''}>${hidden({ csrf, requestId: randomUUID() })}<label for="coding-prompt">Message Codex</label><textarea id="coding-prompt" name="prompt" rows="2" maxlength="24000" required placeholder="Describe a change or ask about the result…">${escape(input.draft ?? '')}</textarea><div class="coding-actions"><button type="submit"${blocked ? ' disabled' : ''}>${s.status === 'working' ? 'Send update' : 'Send message'}</button></div></form><details id="coding-changes" class="coding-changes"><summary>Changes</summary><div id="coding-change-content"><p class="coding-meta">Open to load the current changes.</p></div><button type="button" id="coding-refresh-changes" class="coding-secondary">Refresh changes</button><noscript><a href="${sessionUrl(s.id)}/changes">View changes</a></noscript><p id="coding-shipping"${['closed', 'uncertain'].includes(s.status) ? ' hidden' : ''}><a class="coding-link-button" href="${sessionUrl(s.id)}/ship">Review for shipping</a></p></details>`;
77
+ const messages = selected.items.filter(item => item.type !== 'reasoning').map(itemHtml);
78
+ const composer = postForm(`${sessionUrl(s.id)}/send`, html `<label for="coding-prompt">Message Codex</label><textarea id="coding-prompt" name="prompt" rows="2" maxlength="24000" required placeholder="Describe a change or ask about the result…">${input.draft ?? ''}</textarea><div class="coding-actions"><button type="submit"${blocked ? html ` disabled` : ''}>${s.status === 'working' ? 'Send update' : 'Send message'}</button></div>`, { attrs: { 'data-coding-form': 'send', class: 'coding-composer', hidden: s.status === 'closed' }, hidden: { requestId: randomUUID() } });
79
+ main = html `<header class="coding-header"><div><h1>${s.title}</h1><p class="coding-meta">${projectName(s.repo)} · Codex${s.model ? html ` · ${s.model}` : ''}</p></div><details class="coding-session-detail"><summary aria-label="Session details">Details</summary><dl><dt>Branch</dt><dd>${s.branch}</dd><dt>Worktree</dt><dd>${s.worktree}</dd><dt>Native session</dt><dd>${s.nativeThreadId ?? 'Not established'}</dd>${s.initialRequest ? html `<dt>Initial request</dt><dd class="coding-text">${s.initialRequest.prompt}</dd>` : ''}</dl></details></header><div class="coding-state-row"><p id="coding-state" role="status">${stateLabel(s, selected.requests)}</p><div id="coding-controls">${controlsHtml(s)}</div></div><div id="coding-requests">${selected.requests.map(r => requestHtml(r, s.id))}</div><div id="coding-conversation" class="coding-conversation" tabindex="0" aria-label="Conversation"${s.status === 'closed' && messages.length === 0 ? html ` hidden` : ''}>${messages.length ? messages : html `<p class="coding-meta coding-no-messages">No messages yet.</p>`}</div><button type="button" id="coding-latest" class="coding-secondary" hidden>Latest update ↓</button>${composer}<details id="coding-changes" class="coding-changes"><summary>Changes</summary><div id="coding-change-content"><p class="coding-meta">Open to load the current changes.</p></div><button type="button" id="coding-refresh-changes" class="coding-secondary">Refresh changes</button><noscript><a href="${sessionUrl(s.id)}/changes">View changes</a></noscript><p id="coding-shipping"${['closed', 'uncertain'].includes(s.status) ? html ` hidden` : ''}><a class="coding-link-button" href="${sessionUrl(s.id)}/ship">Review for shipping</a></p></details>`;
79
80
  }
80
- return `<section class="coding-workspace" data-coding-session="${escape(selected?.session.id ?? '')}" data-coding-owner="${escape(selected?.session.owner ?? input.owner ?? '')}" data-coding-project="${escape(selectedRepo ?? input.projects[0]?.path ?? '')}" data-coding-status="${escape(selected?.session.status ?? '')}" data-coding-native-thread="${Boolean(selected?.session.nativeThreadId)}" data-coding-revision="${selected?.revision ?? -1}" data-coding-csrf="${escape(csrf)}">${sidebar}<div class="coding-main"><div id="coding-error" class="coding-notice" role="alert"${error ? '' : ' hidden'}>${noticeHtml(error)}</div><p id="coding-connection" class="coding-meta" role="status" hidden></p>${main}</div></section>`;
81
+ return html `<section class="coding-workspace" data-coding-session="${selected?.session.id ?? ''}" data-coding-owner="${selected?.session.owner ?? input.owner ?? ''}" data-coding-project="${selectedRepo ?? input.projects[0]?.path ?? ''}" data-coding-status="${selected?.session.status ?? ''}" data-coding-native-thread="${String(Boolean(selected?.session.nativeThreadId))}" data-coding-revision="${selected?.revision ?? -1}" data-coding-csrf="${csrf}">${sidebar}<div class="coding-main"><div id="coding-error" class="coding-notice" role="alert"${error ? '' : html ` hidden`}>${noticeHtml(error)}</div><p id="coding-connection" class="coding-meta" role="status" hidden></p>${main}</div></section>`;
81
82
  }
82
83
  export const CODING_CSS = `
83
84
  .coding-workspace{display:grid;grid-template-columns:224px minmax(0,1fr);gap:24px;max-width:1220px;min-width:0;margin:0 auto;overflow-wrap:anywhere}
@@ -146,35 +146,40 @@ export declare const chatActionRequestSchemas: {
146
146
  readonly flow_trigger_remove: z.ZodObject<{
147
147
  trigger: z.ZodInt;
148
148
  }, z.core.$strict>;
149
- readonly teammate_create: z.ZodObject<{
149
+ readonly subagent_create: z.ZodObject<{
150
150
  repo: z.ZodString;
151
151
  template: z.ZodOptional<z.ZodUnknown>;
152
152
  name: z.ZodOptional<z.ZodUnknown>;
153
153
  soul: z.ZodOptional<z.ZodUnknown>;
154
154
  }, z.core.$strict>;
155
- readonly teammate_soul: z.ZodObject<{
156
- teammate: z.ZodInt;
155
+ readonly subagent_soul: z.ZodObject<{
156
+ subagent: z.ZodInt;
157
157
  soul: z.ZodString;
158
158
  }, z.core.$strict>;
159
- readonly teammate_state: z.ZodObject<{
160
- teammate: z.ZodInt;
159
+ readonly subagent_state: z.ZodObject<{
160
+ subagent: z.ZodInt;
161
161
  state: z.ZodEnum<{
162
162
  active: "active";
163
163
  paused: "paused";
164
164
  removed: "removed";
165
165
  }>;
166
166
  }, z.core.$strict>;
167
- readonly teammate_note: z.ZodObject<{
168
- teammate: z.ZodInt;
167
+ readonly subagent_note: z.ZodObject<{
168
+ subagent: z.ZodInt;
169
169
  note: z.ZodString;
170
170
  }, z.core.$strict>;
171
- readonly teammate_answer: z.ZodObject<{
171
+ /** D5: the lead delegates — "ask Rosa to …" — as a card on the subagent's desk. */
172
+ readonly subagent_ask: z.ZodObject<{
173
+ subagent: z.ZodInt;
174
+ text: z.ZodString;
175
+ }, z.core.$strict>;
176
+ readonly subagent_answer: z.ZodObject<{
172
177
  question: z.ZodInt;
173
178
  choice: z.ZodOptional<z.ZodUnknown>;
174
179
  text: z.ZodOptional<z.ZodUnknown>;
175
180
  }, z.core.$strict>;
176
- readonly teammate_tools: z.ZodObject<{
177
- teammate: z.ZodInt;
181
+ readonly subagent_tools: z.ZodObject<{
182
+ subagent: z.ZodInt;
178
183
  tool: z.ZodString;
179
184
  change: z.ZodEnum<{
180
185
  grant: "grant";
@@ -187,8 +192,8 @@ export declare const chatActionRequestSchemas: {
187
192
  limitOver: z.ZodOptional<z.ZodUnknown>;
188
193
  undoWith: z.ZodOptional<z.ZodUnknown>;
189
194
  }, z.core.$strict>;
190
- readonly teammate_memory: z.ZodObject<{
191
- teammate: z.ZodInt;
195
+ readonly subagent_memory: z.ZodObject<{
196
+ subagent: z.ZodInt;
192
197
  memory: z.ZodInt;
193
198
  change: z.ZodEnum<{
194
199
  edit: "edit";
@@ -196,8 +201,8 @@ export declare const chatActionRequestSchemas: {
196
201
  }>;
197
202
  text: z.ZodOptional<z.ZodUnknown>;
198
203
  }, z.core.$strict>;
199
- readonly teammate_routine: z.ZodObject<{
200
- teammate: z.ZodInt;
204
+ readonly subagent_routine: z.ZodObject<{
205
+ subagent: z.ZodInt;
201
206
  change: z.ZodEnum<{
202
207
  add: "add";
203
208
  remove: "remove";
@@ -206,8 +211,8 @@ export declare const chatActionRequestSchemas: {
206
211
  schedule: z.ZodOptional<z.ZodUnknown>;
207
212
  text: z.ZodOptional<z.ZodUnknown>;
208
213
  }, z.core.$strict>;
209
- readonly teammate_undo: z.ZodObject<{
210
- teammate: z.ZodInt;
214
+ readonly subagent_undo: z.ZodObject<{
215
+ subagent: z.ZodInt;
211
216
  call: z.ZodInt;
212
217
  }, z.core.$strict>;
213
218
  readonly kit_setup: z.ZodObject<{
@@ -294,17 +299,18 @@ export declare const sharedActionSchema: z.ZodObject<{
294
299
  skill_import: "skill_import";
295
300
  skill_restore: "skill_restore";
296
301
  skill_test: "skill_test";
302
+ subagent_answer: "subagent_answer";
303
+ subagent_ask: "subagent_ask";
304
+ subagent_create: "subagent_create";
305
+ subagent_memory: "subagent_memory";
306
+ subagent_note: "subagent_note";
307
+ subagent_routine: "subagent_routine";
308
+ subagent_soul: "subagent_soul";
309
+ subagent_state: "subagent_state";
310
+ subagent_tools: "subagent_tools";
311
+ subagent_undo: "subagent_undo";
297
312
  task_cancel: "task_cancel";
298
313
  task_resume: "task_resume";
299
- teammate_answer: "teammate_answer";
300
- teammate_create: "teammate_create";
301
- teammate_memory: "teammate_memory";
302
- teammate_note: "teammate_note";
303
- teammate_routine: "teammate_routine";
304
- teammate_soul: "teammate_soul";
305
- teammate_state: "teammate_state";
306
- teammate_tools: "teammate_tools";
307
- teammate_undo: "teammate_undo";
308
314
  tool_add: "tool_add";
309
315
  tool_remove: "tool_remove";
310
316
  }>;
@@ -324,5 +330,4 @@ export declare function upgradeUnversionedSharedAction(body: Record<string, unkn
324
330
  export declare const SHARED_ACTION_UPGRADES: {
325
331
  readonly 0: typeof upgradeUnversionedSharedAction;
326
332
  };
327
- /** Legacy readers checked only the envelope. Confirmation still prepares the request again before acting. */
328
- export declare function readSharedAction(input: unknown): ContractResult<SharedAction>;
333
+ export declare function readSharedAction(given: unknown): ContractResult<SharedAction>;
@@ -57,18 +57,20 @@ export const chatActionRequestSchemas = {
57
57
  flow_trigger_pause: z.strictObject({ trigger: id }),
58
58
  flow_trigger_resume: z.strictObject({ trigger: id }),
59
59
  flow_trigger_remove: z.strictObject({ trigger: id }),
60
- teammate_create: z.strictObject({ repo: words, template: z.unknown().optional(), name: z.unknown().optional(), soul: z.unknown().optional() }),
61
- teammate_soul: z.strictObject({ teammate: id, soul: words }),
62
- teammate_state: z.strictObject({ teammate: id, state: z.enum(["active", "paused", "removed"]) }),
63
- teammate_note: z.strictObject({ teammate: id, note: words }),
64
- teammate_answer: z.strictObject({ question: id, choice: z.unknown().optional(), text: z.unknown().optional() }),
65
- teammate_tools: z.strictObject({
66
- teammate: id, tool: words, change: z.enum(["grant", "revoke", "rule"]), action: z.unknown().optional(), use: z.unknown().optional(),
60
+ subagent_create: z.strictObject({ repo: words, template: z.unknown().optional(), name: z.unknown().optional(), soul: z.unknown().optional() }),
61
+ subagent_soul: z.strictObject({ subagent: id, soul: words }),
62
+ subagent_state: z.strictObject({ subagent: id, state: z.enum(["active", "paused", "removed"]) }),
63
+ subagent_note: z.strictObject({ subagent: id, note: words }),
64
+ /** D5: the lead delegates — "ask Rosa to …" — as a card on the subagent's desk. */
65
+ subagent_ask: z.strictObject({ subagent: id, text: words }),
66
+ subagent_answer: z.strictObject({ question: id, choice: z.unknown().optional(), text: z.unknown().optional() }),
67
+ subagent_tools: z.strictObject({
68
+ subagent: id, tool: words, change: z.enum(["grant", "revoke", "rule"]), action: z.unknown().optional(), use: z.unknown().optional(),
67
69
  limitField: z.unknown().optional(), limitOver: z.unknown().optional(), undoWith: z.unknown().optional(),
68
70
  }),
69
- teammate_memory: z.strictObject({ teammate: id, memory: id, change: z.enum(["edit", "forget"]), text: z.unknown().optional() }),
70
- teammate_routine: z.strictObject({ teammate: id, change: z.enum(["add", "remove"]), routine: z.unknown().optional(), schedule: z.unknown().optional(), text: z.unknown().optional() }),
71
- teammate_undo: z.strictObject({ teammate: id, call: id }),
71
+ subagent_memory: z.strictObject({ subagent: id, memory: id, change: z.enum(["edit", "forget"]), text: z.unknown().optional() }),
72
+ subagent_routine: z.strictObject({ subagent: id, change: z.enum(["add", "remove"]), routine: z.unknown().optional(), schedule: z.unknown().optional(), text: z.unknown().optional() }),
73
+ subagent_undo: z.strictObject({ subagent: id, call: id }),
72
74
  kit_setup: z.strictObject({ repo: words, kit: words }),
73
75
  decision_record: z.strictObject({ repo: words, claim: words, why: words, supersedes: id.optional(), source: words.optional() }),
74
76
  decision_retire: z.strictObject({ repo: words, decision: id, reason: words }),
@@ -120,7 +122,23 @@ const under = (prefix, issues) => issues.map(issue => {
120
122
  return { ...issue, path, line: `${path}${issue.line.slice(issue.path.length)}` };
121
123
  });
122
124
  /** Legacy readers checked only the envelope. Confirmation still prepares the request again before acting. */
123
- export function readSharedAction(input) {
125
+ /**
126
+ * D5 (schema v117): a subagent action was a "teammate_…" one, naming its "teammate", before. A saved card reads in today's
127
+ * words, so a conversation's history still shows it; its stamp was made over the old words, so confirming it asks for
128
+ * a fresh proposal, as any card drafted before a change does.
129
+ */
130
+ function legacySubagentAction(input) {
131
+ if (input === null || typeof input !== "object" || Array.isArray(input))
132
+ return input;
133
+ const row = input;
134
+ if (typeof row["operation"] !== "string" || !row["operation"].startsWith("teammate_"))
135
+ return input;
136
+ const renamed = (value) => value === null || typeof value !== "object" || Array.isArray(value) ? value
137
+ : Object.fromEntries(Object.entries(value).map(([key, one]) => [key === "teammate" ? "subagent" : key, one]));
138
+ return { ...row, operation: `subagent_${row["operation"].slice("teammate_".length)}`, request: renamed(row["request"]), ...(Object.hasOwn(row, "state") ? { state: renamed(row["state"]) } : {}) };
139
+ }
140
+ export function readSharedAction(given) {
141
+ const input = legacySubagentAction(given);
124
142
  const read = readVersioned(sharedActionSchema, input, SHARED_ACTION_UPGRADES);
125
143
  if (!read.ok)
126
144
  return read;
@@ -67,7 +67,7 @@ export declare const chatContentShape: {
67
67
  entry: z.ZodInt;
68
68
  held: z.ZodString;
69
69
  }, z.core.$strict>>;
70
- /** A teammate's question's buttons ride this part (v93): each option, then one to answer in words (choice null). */
70
+ /** A subagent's question's buttons ride this part (v93): each option, then one to answer in words (choice null). */
71
71
  question: z.ZodOptional<z.ZodObject<{
72
72
  id: z.ZodInt;
73
73
  choices: z.ZodArray<z.ZodObject<{
@@ -37,7 +37,7 @@ export const chatContentShape = {
37
37
  choose: z.strictObject({ card: id, entry: z.int(), options: z.array(z.strictObject({ choice: z.int(), label: z.string() })) }).optional(),
38
38
  /** "Use this as your note?" Yes / No about the person's message `held` (an event id), for one choice's visit. */
39
39
  note: z.strictObject({ card: id, entry: z.int(), held: z.string() }).optional(),
40
- /** A teammate's question's buttons ride this part (v93): each option, then one to answer in words (choice null). */
40
+ /** A subagent's question's buttons ride this part (v93): each option, then one to answer in words (choice null). */
41
41
  question: z.strictObject({ id, choices: z.array(z.strictObject({ choice: z.string().nullable(), label: z.string() })) }).optional(),
42
42
  /** The lead's question to its owner rides this part: its options, then "Something else". */
43
43
  ask: z.strictObject({ turn: id, options: z.array(z.string()) }).optional(),
@@ -55,7 +55,7 @@ CREATE INDEX IF NOT EXISTS chat_part_message ON chat_part(provider, message);
55
55
  -- A button rides its planned part, or (Telegram) the binding, chat and message it was placed on.
56
56
  CREATE TABLE IF NOT EXISTS chat_action (
57
57
  ${PROVIDER}, token TEXT NOT NULL, part INTEGER, binding INTEGER, chat TEXT, message TEXT,
58
- proposal INTEGER REFERENCES mate_proposal(id) ON DELETE CASCADE,
58
+ proposal INTEGER REFERENCES lead_proposal(id) ON DELETE CASCADE,
59
59
  decision INTEGER REFERENCES decision(id) ON DELETE CASCADE, option_id TEXT, note_digest TEXT,
60
60
  phase TEXT NOT NULL CHECK (phase IN ('confirm','dismiss','yes','cancel','choose')),
61
61
  created TEXT, expires TEXT, consumed TEXT,
@@ -135,17 +135,17 @@ CREATE TABLE IF NOT EXISTS chat_flow_note (
135
135
  FOREIGN KEY (provider, part) REFERENCES chat_part(provider, id)
136
136
  );
137
137
  CREATE INDEX IF NOT EXISTS chat_flow_note_visit ON chat_flow_note(card, entry);
138
- -- A teammate's question: one button per option and one to answer in words (choice NULL).
138
+ -- A subagent's question: one button per option and one to answer in words (choice NULL).
139
139
  CREATE TABLE IF NOT EXISTS chat_question_action (
140
140
  ${PROVIDER}, token TEXT NOT NULL, part INTEGER, binding INTEGER, chat TEXT, message TEXT,
141
- question INTEGER NOT NULL REFERENCES teammate_question(id), choice TEXT, created TEXT, expires TEXT NOT NULL, consumed TEXT,
141
+ question INTEGER NOT NULL REFERENCES subagent_question(id), choice TEXT, created TEXT, expires TEXT NOT NULL, consumed TEXT,
142
142
  PRIMARY KEY (provider, token),
143
143
  FOREIGN KEY (provider, part) REFERENCES chat_part(provider, id)
144
144
  );
145
145
  CREATE INDEX IF NOT EXISTS chat_question_action_question ON chat_question_action(question);
146
146
  CREATE TABLE IF NOT EXISTS chat_question_prompt (
147
147
  ${PROVIDER}, id INTEGER NOT NULL, binding INTEGER NOT NULL, chat TEXT, message TEXT,
148
- question INTEGER NOT NULL REFERENCES teammate_question(id), created TEXT NOT NULL, expires TEXT NOT NULL, consumed TEXT,
148
+ question INTEGER NOT NULL REFERENCES subagent_question(id), created TEXT NOT NULL, expires TEXT NOT NULL, consumed TEXT,
149
149
  PRIMARY KEY (provider, id)
150
150
  );
151
151
  CREATE INDEX IF NOT EXISTS chat_question_prompt_open ON chat_question_prompt(provider, binding, consumed);
@@ -323,13 +323,12 @@ export declare const COMMAND_OUTPUTS: {
323
323
  assets: "assets";
324
324
  auth: "auth";
325
325
  chat: "chat";
326
- "chat-stream": "chat-stream";
327
326
  cli: "cli";
328
327
  console: "console";
329
328
  decisions: "decisions";
330
- "flow-stream": "flow-stream";
331
329
  flows: "flows";
332
330
  health: "health";
331
+ live: "live";
333
332
  mcp: "mcp";
334
333
  metrics: "metrics";
335
334
  other: "other";
@@ -339,7 +338,6 @@ export declare const COMMAND_OUTPUTS: {
339
338
  settings: "settings";
340
339
  tasks: "tasks";
341
340
  team: "team";
342
- "team-stream": "team-stream";
343
341
  }> & z.core.$partial, z.ZodObject<{
344
342
  count: z.ZodNumber;
345
343
  p50Ms: z.ZodNullable<z.ZodNumber>;
@@ -71,7 +71,7 @@ export declare const CONSOLE_FORMS: {
71
71
  readonly skillsRevise: FormContract<"feedback" | "nonce" | "repo" | "run">;
72
72
  readonly skillsChange: FormContract<"action" | "content" | "files" | "identity" | "method" | "nonce" | "repo" | "restore" | "revision" | "sample" | "sha" | "url">;
73
73
  readonly kit: FormContract<"repo">;
74
- readonly teammates: FormContract<"choice" | "dailyTurns" | "id" | "manager" | "model" | "name" | "note" | "op" | "repo" | "schedule" | "soul" | "state" | "template" | "text" | "tool" | `field.${string}` | `over.${string}` | `undo.${string}` | `use.${string}`>;
74
+ readonly subagents: FormContract<"choice" | "dailyTurns" | "id" | "manager" | "model" | "name" | "note" | "op" | "repo" | "schedule" | "soul" | "state" | "template" | "text" | "tool" | `field.${string}` | `over.${string}` | `undo.${string}` | `use.${string}`>;
75
75
  readonly galleryUse: FormContract<string>;
76
76
  readonly flows: FormContract<"about" | "address" | "answers" | "approve" | "body" | "choice" | "confirm" | "decision" | "definition" | "description" | "document" | "draft" | "entry" | "file" | "key" | "label" | "language" | "name" | "note" | "owner" | "password" | "previewed" | "remove" | "repo" | "revision" | "secret" | "stage" | "template" | "timeoutMinutes" | "title" | "trigger" | "url" | "value" | "watching" | `param.${string}`>;
77
77
  readonly spendBudget: FormContract<"action" | "password" | "stop" | "target" | "usd">;
@@ -140,11 +140,11 @@ export declare const CONSOLE_FORMS: {
140
140
  readonly leadAbout: FormContract<"about">;
141
141
  readonly leadPromiseCancel: FormContract<"promise">;
142
142
  readonly chatConfig: FormContract<"daily-turns" | "forget-key" | "key" | "model" | "off" | "provider" | "return" | "token" | "weekly-usd">;
143
- readonly mateMint: FormContract<"ceiling-usd" | "follow" | "return" | "token">;
144
- readonly mateFollow: FormContract<"enabled" | "return">;
145
- readonly mateEnd: FormContract<"return">;
146
- readonly mateStop: FormContract<"return" | "turn">;
147
- readonly mateProposal: FormContract<"confirm" | "nonce" | "return" | "token">;
143
+ readonly leadMint: FormContract<"ceiling-usd" | "follow" | "return" | "token">;
144
+ readonly leadFollow: FormContract<"enabled" | "return">;
145
+ readonly leadEnd: FormContract<"return">;
146
+ readonly leadStop: FormContract<"return" | "turn">;
147
+ readonly leadProposal: FormContract<"confirm" | "nonce" | "return" | "token">;
148
148
  readonly coordinatorProposal: FormContract<"confirm" | "return">;
149
149
  readonly chat: FormContract<"message" | "mode" | "project" | "request" | "request-session" | "result" | "task" | "token">;
150
150
  readonly chatFile: FormContract<"token">;
@@ -177,7 +177,7 @@ export declare const CONSOLE_FORMS: {
177
177
  };
178
178
  export type ConsoleFormName = keyof typeof CONSOLE_FORMS;
179
179
  /** The console POSTs whose handlers read no field (sign-out not even the shared guard): their contract is the empty form. */
180
- export declare const BODILESS_POSTS: readonly ["POST /settings/lead/on", "POST /r/<run>/draft-repair", "POST /ledger/checkpoint", "POST /settings/backups/now", "POST /mode/revoke", "POST /settings/telegram/retry", "POST /providers/<provider>/resume", "POST /logout", "POST /t/<task>/unhold", "POST /t/<task>/plan", "POST /t/<task>/retry-review"];
180
+ export declare const BODILESS_POSTS: readonly ["POST /settings/models/<unknown action>", "POST /settings/lead/on", "POST /r/<run>/draft-repair", "POST /ledger/checkpoint", "POST /settings/backups/now", "POST /mode/revoke", "POST /settings/telegram/retry", "POST /providers/<provider>/resume", "POST /logout", "POST /t/<task>/unhold", "POST /t/<task>/plan", "POST /t/<task>/retry-review"];
181
181
  /** The field names a console form's handler may read. */
182
182
  export type FormFieldOf<N extends ConsoleFormName> = (typeof CONSOLE_FORMS)[N] extends FormContract<infer K> ? K : never;
183
183
  /** `GET /ledger?format=json`: the chain's state, a page of entries (newest first) and the cursor for the next. */
@@ -61,7 +61,7 @@ export function readForm(body, contract, report = toStderr) {
61
61
  // ---- every console form ------------------------------------------------------------------------------------------
62
62
  //
63
63
  // One per route (or per verb, where one route takes several bodies). A family whose sub-routes share one dispatch —
64
- // `/code/*`, `/flows/*`, the teammate pages, Slack/Teams/Discord — has one contract naming every field its handlers
64
+ // `/code/*`, `/flows/*`, the subagent pages, Slack/Teams/Discord — has one contract naming every field its handlers
65
65
  // read. Every body also passes through `mutationGuardForm` (the shared CSRF and duplicate check, unchanged) and
66
66
  // `ledgerTargetForm` (the project a request is recorded against).
67
67
  export const CONSOLE_FORMS = {
@@ -73,14 +73,14 @@ export const CONSOLE_FORMS = {
73
73
  mutationGuard: formContract("POST (every signed-in form)", ["csrf", "token", "digest", "nonce", "confirm"]),
74
74
  ledgerTarget: formContract("POST (the action ledger's project)", ["repo"]),
75
75
  projectCeiling: formContract("POST (project ceiling)", ["repo"]),
76
- demo: formContract("POST /chat/demo/<act>", ["message", "note"]),
76
+ demo: formContract("POST /chat/demo/ask, /chat/demo/<id>/approve|change|revise|complete", ["message", "note"]),
77
77
  updatesDismiss: formContract("POST /settings/updates/dismiss", ["version", "quiet", "return"]),
78
78
  updatesChecks: formContract("POST /settings/updates/checks", ["check"]),
79
- code: formContract("POST /code, /code/start, /code/<session>/<act>", ["repo", "password", "title", "model", "prompt", "requestId", "base", "candidate", "goal", "acceptance", "visual", "decision", "answers"], { prefixes: ["question:"] }),
79
+ code: formContract("POST /code, /code/start, /code/<session>/<act>, /code/<anything else>", ["repo", "password", "title", "model", "prompt", "requestId", "base", "candidate", "goal", "acceptance", "visual", "decision", "answers"], { prefixes: ["question:"] }),
80
80
  skillsRevise: formContract("POST /settings/skills/revise", ["run", "repo", "feedback", "nonce"]),
81
81
  skillsChange: formContract("POST /settings/skills/import, /settings/skills/change", ["repo", "identity", "revision", "method", "content", "files", "url", "action", "sha", "sample", "nonce", "restore"]),
82
82
  kit: formContract("POST /kits/<kit>/<act>", ["repo"]),
83
- teammates: formContract("POST /teammates/new, /teammates/<id>/<part>, /teammates/questions/<id>/answer", ["choice", "text", "repo", "template", "name", "soul", "op", "id", "schedule", "tool", "state", "note", "model", "dailyTurns", "manager"], { prefixes: ["use.", "undo.", "field.", "over."] }),
83
+ subagents: formContract("POST /settings/lead/subagents/new, /settings/lead/subagents/<id>/<part>, /settings/lead/subagents/questions/<id>/answer", ["choice", "text", "repo", "template", "name", "soul", "op", "id", "schedule", "tool", "state", "note", "model", "dailyTurns", "manager"], { prefixes: ["use.", "undo.", "field.", "over."] }),
84
84
  galleryUse: formContract("POST /flows/new/<template>", ["repo", "send-result", "name", "intent", "previewed"], { dynamic: true }),
85
85
  flows: formContract("POST /flows/new, /flows/example, /flows/import, /flows/<id>/<act>, /flows/<id>/cards/<card>/<act>, /flows/<id>/triggers/<trigger>/<act>", ["repo", "document", "url", "confirm", "previewed", "template", "name", "answers", "password", "secret", "trigger", "approve", "remove", "about", "body", "timeoutMinutes", "language", "file", "address", "key", "definition", "owner", "revision", "value", "title", "description", "stage", "decision", "note", "draft", "choice", "entry", "label", "watching"], { prefixes: ["param."] }),
86
86
  spendBudget: formContract("POST /spend/budget", ["password", "target", "action", "usd", "stop"]),
@@ -111,11 +111,11 @@ export const CONSOLE_FORMS = {
111
111
  knowledgeChange: formContract("POST /settings/knowledge/change", ["repo", "action", "identity", "revision", "instructions", "title", "content", "path", "id", "restore"]),
112
112
  learningChange: formContract("POST /settings/learning/change", ["repo", "action", "identity", "revision", "lesson", "version", "sha"]),
113
113
  projectSetup: formContract("POST /control/setup-preview, /control/setup-approve, /control/instructions-preview, /control/instructions-approve", ["repo", "nonce", "fingerprint", "token", "provider", "model", "command", "seconds"]),
114
- slack: formContract("POST /settings/slack/<connect|pair|unpair|disconnect|alerts>", ["password", "app-token", "bot-token"]),
114
+ slack: formContract("POST /settings/slack/connect|pair|unpair|disconnect|alerts", ["password", "app-token", "bot-token"]),
115
115
  chatApproval: formContract("POST /settings/chat-approval/confirm, /settings/chat-approval/save, /settings/chat-approval/off", ["scope", "full-access", "cap-usd", "nonce", "digest", "token"]),
116
116
  telegramPair: formContract("POST /settings/telegram/pair, /settings/telegram/unpair", ["password"]),
117
- teams: formContract("POST /settings/teams/<connect|pair|unpair|disconnect|alerts>", ["password", "app-id", "tenant", "secret"]),
118
- discord: formContract("POST /settings/discord/<connect|pair|unpair|disconnect|alerts>", ["password", "bot-token"]),
117
+ teams: formContract("POST /settings/teams/connect|pair|unpair|disconnect|alerts", ["password", "app-id", "tenant", "secret"]),
118
+ discord: formContract("POST /settings/discord/connect|pair|unpair|disconnect|alerts", ["password", "bot-token"]),
119
119
  messaging: formContract("POST /settings/messaging", ["primary"]),
120
120
  permissionDefault: formContract("POST /settings/permission-default", ["permission-mode"]),
121
121
  qualityDefault: formContract("POST /settings/quality-default", ["quality-mode"]),
@@ -149,11 +149,11 @@ export const CONSOLE_FORMS = {
149
149
  leadAbout: formContract("POST /settings/lead/about", ["about"]),
150
150
  leadPromiseCancel: formContract("POST /settings/lead/promise/cancel", ["promise"]),
151
151
  chatConfig: formContract("POST /chat/config", ["return", "token", "off", "forget-key", "provider", "model", "weekly-usd", "daily-turns", "key"]),
152
- mateMint: formContract("POST /chat/mate/mint", ["return", "ceiling-usd", "token", "follow"]),
153
- mateFollow: formContract("POST /chat/mate/follow", ["enabled", "return"]),
154
- mateEnd: formContract("POST /chat/mate/end", ["return"]),
155
- mateStop: formContract("POST /chat/mate/stop", ["return", "turn"]),
156
- mateProposal: formContract("POST /chat/proposal/<id>/confirm|dismiss", ["return", "nonce", "confirm", "token"]),
152
+ leadMint: formContract("POST /chat/mate/mint", ["return", "ceiling-usd", "token", "follow"]),
153
+ leadFollow: formContract("POST /chat/mate/follow", ["enabled", "return"]),
154
+ leadEnd: formContract("POST /chat/mate/end", ["return"]),
155
+ leadStop: formContract("POST /chat/mate/stop", ["return", "turn"]),
156
+ leadProposal: formContract("POST /chat/proposal/<id>/confirm|dismiss", ["return", "nonce", "confirm", "token"]),
157
157
  coordinatorProposal: formContract("POST /proposals/<id>/confirm|dismiss", ["return", "confirm"]),
158
158
  chat: formContract("POST /chat", ["task", "project", "result", "mode", "request", "request-session", "message", "token"]),
159
159
  chatFile: formContract("POST /chat/file/<id>", ["token"]),
@@ -188,6 +188,7 @@ export const CONSOLE_FORMS = {
188
188
  };
189
189
  /** The console POSTs whose handlers read no field (sign-out not even the shared guard): their contract is the empty form. */
190
190
  export const BODILESS_POSTS = [
191
+ "POST /settings/models/<unknown action>",
191
192
  "POST /settings/lead/on",
192
193
  "POST /r/<run>/draft-repair",
193
194
  "POST /ledger/checkpoint",
@@ -81,7 +81,7 @@ export declare const proposeFlowInputSchema: z.ZodObject<{
81
81
  ifFails: z.ZodOptional<z.ZodString>;
82
82
  next: z.ZodOptional<z.ZodString>;
83
83
  remindAfter: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodInt]>>;
84
- teammate: z.ZodOptional<z.ZodString>;
84
+ subagent: z.ZodOptional<z.ZodString>;
85
85
  thenMoveTo: z.ZodOptional<z.ZodString>;
86
86
  }, z.core.$strict>, z.ZodObject<{
87
87
  id: z.ZodOptional<z.ZodString>;
@@ -214,7 +214,7 @@ export declare const proposeFlowInputSchema: z.ZodObject<{
214
214
  }, z.core.$strict>, z.ZodObject<{
215
215
  id: z.ZodOptional<z.ZodString>;
216
216
  title: z.ZodString;
217
- kind: z.ZodLiteral<"teammate">;
217
+ kind: z.ZodLiteral<"subagent">;
218
218
  ifFails: z.ZodOptional<z.ZodString>;
219
219
  instructions: z.ZodOptional<z.ZodString>;
220
220
  next: z.ZodOptional<z.ZodString>;
@@ -224,7 +224,7 @@ export declare const proposeFlowInputSchema: z.ZodObject<{
224
224
  answer: z.ZodString;
225
225
  goesTo: z.ZodString;
226
226
  }, z.core.$strict>>>;
227
- teammate: z.ZodOptional<z.ZodString>;
227
+ subagent: z.ZodOptional<z.ZodString>;
228
228
  }, z.core.$strict>, z.ZodObject<{
229
229
  id: z.ZodOptional<z.ZodString>;
230
230
  title: z.ZodString;