toolroll 0.9.86 → 0.9.87

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 (171) hide show
  1. package/CHANGELOG.md +59 -0
  2. package/dist/agents-board.d.ts +12 -0
  3. package/dist/agents-board.js +26 -0
  4. package/dist/approval-rules-ui.d.ts +4 -1
  5. package/dist/approval-rules-ui.js +31 -15
  6. package/dist/assignment-ui.js +1 -1
  7. package/dist/backup-ui.d.ts +5 -4
  8. package/dist/backup-ui.js +65 -32
  9. package/dist/browser/terminal.css +1 -1
  10. package/dist/browser/terminal.js +57 -54
  11. package/dist/browser/workspace.css +2 -2
  12. package/dist/browser/workspace.js +35 -70
  13. package/dist/browser-crew.js +1 -1
  14. package/dist/browser-workspace.d.ts +329 -183
  15. package/dist/browser-workspace.js +10 -9
  16. package/dist/chat-controls.d.ts +1 -1
  17. package/dist/chat-controls.js +1 -1
  18. package/dist/chat-settings-page.d.ts +29 -9
  19. package/dist/chat-settings-page.js +59 -28
  20. package/dist/check-levels-ui.d.ts +2 -1
  21. package/dist/check-levels-ui.js +67 -58
  22. package/dist/contracts/cli.d.ts +43 -0
  23. package/dist/contracts/cli.js +4 -0
  24. package/dist/contracts/console-api.d.ts +1 -1
  25. package/dist/contracts/console-api.js +1 -1
  26. package/dist/credentials-ui.d.ts +5 -3
  27. package/dist/credentials-ui.js +58 -31
  28. package/dist/design/kit.css +685 -0
  29. package/dist/design/kit.d.ts +208 -0
  30. package/dist/design/kit.js +177 -0
  31. package/dist/design/tokens.css +19 -1
  32. package/dist/discord-settings.js +8 -4
  33. package/dist/export-ui.d.ts +6 -4
  34. package/dist/export-ui.js +18 -8
  35. package/dist/flow-changed.d.ts +14 -0
  36. package/dist/flow-changed.js +53 -0
  37. package/dist/flow-gallery-ui.d.ts +41 -4
  38. package/dist/flow-gallery-ui.js +95 -63
  39. package/dist/flow-starters-ui.d.ts +3 -9
  40. package/dist/flow-starters-ui.js +12 -23
  41. package/dist/flow-unattended-words.d.ts +20 -0
  42. package/dist/flow-unattended-words.js +24 -0
  43. package/dist/flow-unattended.d.ts +9 -5
  44. package/dist/flow-unattended.js +45 -23
  45. package/dist/flows-cli.js +7 -3
  46. package/dist/flows-ui.d.ts +12 -6
  47. package/dist/flows-ui.js +141 -30
  48. package/dist/integrations-ui.d.ts +6 -4
  49. package/dist/integrations-ui.js +34 -40
  50. package/dist/integrations.d.ts +2 -2
  51. package/dist/integrations.js +4 -4
  52. package/dist/kits-ui.d.ts +8 -10
  53. package/dist/kits-ui.js +29 -33
  54. package/dist/kits.js +1 -1
  55. package/dist/knowledge-ui.js +76 -19
  56. package/dist/ledger-view.d.ts +2 -0
  57. package/dist/ledger-view.js +41 -38
  58. package/dist/models-ui.d.ts +8 -3
  59. package/dist/models-ui.js +82 -59
  60. package/dist/monitoring-ui.d.ts +4 -2
  61. package/dist/monitoring-ui.js +44 -13
  62. package/dist/needs-you.d.ts +1 -1
  63. package/dist/needs-you.js +8 -0
  64. package/dist/operate-remote-arguments.js +1 -0
  65. package/dist/operate-remote.js +1 -1
  66. package/dist/operate.d.ts +1 -1
  67. package/dist/operate.js +38 -4
  68. package/dist/passwordless.d.ts +1 -1
  69. package/dist/passwordless.js +1 -1
  70. package/dist/people-audit-ui.d.ts +2 -1
  71. package/dist/people-audit-ui.js +25 -23
  72. package/dist/policy-ui.d.ts +3 -2
  73. package/dist/policy-ui.js +27 -21
  74. package/dist/policy.d.ts +3 -0
  75. package/dist/policy.js +14 -1
  76. package/dist/project-delete-ui.d.ts +4 -2
  77. package/dist/project-delete-ui.js +135 -126
  78. package/dist/project-knowledge.d.ts +10 -10
  79. package/dist/publish.d.ts +11 -0
  80. package/dist/publish.js +16 -3
  81. package/dist/pull-request-ui.d.ts +2 -1
  82. package/dist/pull-request-ui.js +39 -28
  83. package/dist/recipe-ui.d.ts +4 -2
  84. package/dist/recipe-ui.js +14 -4
  85. package/dist/release-adapters.d.ts +3 -0
  86. package/dist/release-adapters.js +22 -2
  87. package/dist/release-cli.js +81 -9
  88. package/dist/release.d.ts +21 -0
  89. package/dist/release.js +40 -4
  90. package/dist/releases.js +1 -1
  91. package/dist/request-budget-ui.d.ts +4 -2
  92. package/dist/request-budget-ui.js +30 -19
  93. package/dist/retention-ui.d.ts +4 -3
  94. package/dist/retention-ui.js +15 -12
  95. package/dist/scope.d.ts +3 -0
  96. package/dist/scope.js +6 -0
  97. package/dist/serve.d.ts +0 -1
  98. package/dist/serve.js +51 -7
  99. package/dist/server/agents-computers.d.ts +9 -0
  100. package/dist/server/agents-computers.js +67 -0
  101. package/dist/server/chat.js +16 -16
  102. package/dist/server/chrome.d.ts +1 -1
  103. package/dist/server/chrome.js +19 -9
  104. package/dist/server/console.css +2 -2
  105. package/dist/server/flows.js +64 -36
  106. package/dist/server/home.d.ts +35 -0
  107. package/dist/server/home.js +104 -0
  108. package/dist/server/http.d.ts +3 -0
  109. package/dist/server/http.js +5 -0
  110. package/dist/server/kit-standalone.d.ts +22 -0
  111. package/dist/server/kit-standalone.js +69 -0
  112. package/dist/server/kit.d.ts +405 -0
  113. package/dist/server/kit.js +361 -0
  114. package/dist/server/pages.d.ts +2 -1
  115. package/dist/server/pages.js +213 -174
  116. package/dist/server/people-tokens.js +26 -85
  117. package/dist/server/render-history.d.ts +51 -0
  118. package/dist/server/render-history.js +228 -0
  119. package/dist/server/render-new-task.d.ts +29 -0
  120. package/dist/server/render-new-task.js +96 -0
  121. package/dist/server/render-next.d.ts +63 -0
  122. package/dist/server/render-next.js +109 -0
  123. package/dist/server/render-pages.d.ts +22 -190
  124. package/dist/server/render-pages.js +123 -575
  125. package/dist/server/render-people.d.ts +24 -3
  126. package/dist/server/render-people.js +93 -72
  127. package/dist/server/render-projects.d.ts +103 -0
  128. package/dist/server/render-projects.js +247 -0
  129. package/dist/server/render-results.d.ts +5 -24
  130. package/dist/server/render-results.js +48 -185
  131. package/dist/server/render-settings.d.ts +5 -74
  132. package/dist/server/render-settings.js +102 -493
  133. package/dist/server/render-tasks.d.ts +35 -5
  134. package/dist/server/render-tasks.js +114 -85
  135. package/dist/server/route-table.js +20 -5
  136. package/dist/server/settings.js +276 -255
  137. package/dist/server/task-views.d.ts +8 -0
  138. package/dist/server/task-views.js +85 -2
  139. package/dist/server/tasks.d.ts +8 -0
  140. package/dist/server/tasks.js +95 -40
  141. package/dist/server/terminals.js +1 -1
  142. package/dist/server/welcome.d.ts +22 -0
  143. package/dist/server/welcome.js +69 -0
  144. package/dist/settings-groups-ui.d.ts +279 -0
  145. package/dist/settings-groups-ui.js +615 -0
  146. package/dist/settings-kit.d.ts +42 -6
  147. package/dist/settings-kit.js +69 -7
  148. package/dist/setup-guide.d.ts +2 -2
  149. package/dist/skills-ui.js +59 -7
  150. package/dist/slack-settings.js +12 -5
  151. package/dist/spend-ui.d.ts +45 -26
  152. package/dist/spend-ui.js +124 -56
  153. package/dist/sso-ui.d.ts +5 -2
  154. package/dist/sso-ui.js +63 -31
  155. package/dist/storage-ui.d.ts +3 -2
  156. package/dist/storage-ui.js +56 -50
  157. package/dist/store.d.ts +112 -3
  158. package/dist/store.js +292 -20
  159. package/dist/surface.js +5 -1
  160. package/dist/teams-settings.d.ts +2 -1
  161. package/dist/teams-settings.js +24 -41
  162. package/dist/telegram-settings.d.ts +0 -4
  163. package/dist/telegram-settings.js +52 -25
  164. package/dist/toolroll-update-ui.d.ts +8 -4
  165. package/dist/toolroll-update-ui.js +55 -45
  166. package/dist/tools-ui.d.ts +5 -3
  167. package/dist/tools-ui.js +107 -42
  168. package/dist/work-index.js +11 -7
  169. package/dist/workspace-ui.d.ts +1 -1
  170. package/dist/workspace-ui.js +7 -4
  171. package/package.json +1 -1
@@ -12,7 +12,7 @@ export function browserWorkActionHref(item) {
12
12
  if (action.code === 'inspect-decisions')
13
13
  return '/';
14
14
  if (action.code === 'sign-in')
15
- return '/settings#providers';
15
+ return '/settings/agents#providers';
16
16
  if (action.code === 'answer-agent' && runId !== null)
17
17
  return `/agents?run=${runId}`;
18
18
  if (action.code === 'confirm-stopped')
@@ -4,7 +4,6 @@
4
4
  import { type DisplayState, type StateCounts } from './agent-state-words.js';
5
5
  import type { TeamSnapshot } from './team-contract.js';
6
6
  import type { RunActivity } from './activity-line.js';
7
- import type { BrandIconId } from './brand-icons.js';
8
7
  import type { AssignmentSnapshot } from './assignment.js';
9
8
  export { browserCrewFromIndex, browserWorkActionHref } from './browser-crew.js';
10
9
  import type { Store } from './store.js';
@@ -166,11 +165,29 @@ export type BrowserLink = {
166
165
  };
167
166
  export type BrowserTasksView = {
168
167
  kind: 'tasks';
168
+ /** List (rows under group headings) or Board (the same index as columns). */
169
+ layout: 'list' | 'board';
170
+ /** The status filters (All, Needs you, Running, Queued, Finished), as addresses with their counts. */
169
171
  tabs: (BrowserLink & {
172
+ key?: string;
170
173
  count: number;
171
174
  active: boolean;
172
175
  })[];
173
- /** Tasks waiting on a person in this view's scope ("3 need you" beside the title). */
176
+ /** The project filter: All and each project in view (null with one project). */
177
+ projects?: {
178
+ key: string;
179
+ label: string;
180
+ href: string;
181
+ active: boolean;
182
+ }[] | null;
183
+ /** The List and Board addresses for this same filter. */
184
+ layouts: {
185
+ list: string;
186
+ board: string;
187
+ };
188
+ /** The scope the counts cover, in words ("in payments-api", "across all your projects"). */
189
+ scope?: string;
190
+ /** Tasks waiting on a person in this view's scope. */
174
191
  needsYou: number;
175
192
  /** All and Needs you list their rows in these groups, in this order (empty ones left out); null: one plain list. */
176
193
  groups: {
@@ -178,33 +195,21 @@ export type BrowserTasksView = {
178
195
  label: string;
179
196
  count: number;
180
197
  }[] | null;
181
- rows: {
182
- id: string;
183
- title: string;
198
+ rows: BrowserTaskRow[];
199
+ /** The Board view's columns (Needs you, Queued, Running, Finished); null in the List view. */
200
+ board?: {
201
+ key: 'needs' | 'queued' | 'running' | 'finished';
202
+ label: string;
203
+ count: number;
184
204
  href: string;
185
- project: string | null;
186
- age: string;
187
- status: {
188
- label: string;
189
- tone: StatusTone;
190
- token: string;
191
- };
192
- /** What a Needs you row asks: its group. */
193
- ask: Ask | null;
194
- /** The row's chip under its group: the specific ask (Plan, Result, Mismatch, Plan changed, Failed, Builder offline), or none. */
195
- chip: AskChip | null;
196
- group: BrowserTaskGroup;
197
- action: BrowserLink | null;
198
- detail: string | null;
199
- problem: string | null;
200
- notes: string[];
201
- /** Put away, or Restore in Archived (task-tidy.md): a POST to the task's own route; null for a viewer or live work. */
202
- tidy?: {
203
- action: string;
204
- label: 'Put away' | 'Restore';
205
- returnTo: string;
206
- } | null;
207
- }[];
205
+ empty: string;
206
+ rows: BrowserTaskRow[];
207
+ }[] | null;
208
+ /** Archived tasks, offered at the foot of Finished (and current in Archived). */
209
+ archived?: (BrowserLink & {
210
+ count: number;
211
+ active: boolean;
212
+ }) | null;
208
213
  empty: {
209
214
  text: string;
210
215
  action: BrowserLink | null;
@@ -224,6 +229,40 @@ export type BrowserTasksView = {
224
229
  active: boolean;
225
230
  })[];
226
231
  };
232
+ export type BrowserTaskRow = {
233
+ id: string;
234
+ title: string;
235
+ href: string;
236
+ project: string | null;
237
+ age: string;
238
+ status: {
239
+ label: string;
240
+ tone: StatusTone;
241
+ token: string;
242
+ };
243
+ /** The row's chip word and tone (src/design/KIT.md): the ask under Needs you, else the headline. */
244
+ word: {
245
+ word: string;
246
+ tone: '' | 'needs' | 'ask' | 'live' | 'done' | 'failed';
247
+ };
248
+ /** What a Needs you row asks: its group. */
249
+ ask: Ask | null;
250
+ /** The row's chip under its group: the specific ask (Plan, Result, Mismatch, Plan changed, Failed, Builder offline), or none. */
251
+ chip: AskChip | null;
252
+ group: BrowserTaskGroup;
253
+ /** The status rank: 0 waits on a person, 1 runs, 2 queued or waiting, 3 finished, 4 stopped or put away. */
254
+ rank: number;
255
+ action: BrowserLink | null;
256
+ detail: string | null;
257
+ problem: string | null;
258
+ notes: string[];
259
+ /** Put away, or Restore in Archived (task-tidy.md): a POST to the task's own route; null for a viewer or live work. */
260
+ tidy?: {
261
+ action: string;
262
+ label: 'Put away' | 'Restore';
263
+ returnTo: string;
264
+ } | null;
265
+ };
227
266
  /** One limit: a plan's usage window ("Claude · 5-hour, 48%") or a monthly budget ("shop · Budget, $4.20 of $10"). */
228
267
  export type BrowserTaskGroup = WorkIndexGroup;
229
268
  export type BrowserLimitTile = {
@@ -250,135 +289,6 @@ export type BrowserUsageChip = {
250
289
  href: string;
251
290
  title: string;
252
291
  };
253
- export type BrowserSettingsView = {
254
- kind: 'settings';
255
- said: string | null;
256
- /** Using it from a phone, under Chat apps (approvers only). */
257
- phone?: BrowserPhoneCard;
258
- /** The settings destinations under short headings; a chat app's tile says whether it is connected and gets alerts. */
259
- groups: BrowserSettingsGroup[];
260
- theme: 'system' | 'light' | 'dark';
261
- /** The signal colour chosen for this browser (Settings → Appearance), "#rrggbb"; chart magenta by default. */
262
- accent: string;
263
- accentPresets: {
264
- id: string;
265
- name: string;
266
- year: number | null;
267
- hex: string;
268
- }[];
269
- permission: {
270
- mode: string;
271
- canManage: boolean;
272
- changed: string | null;
273
- } | null;
274
- quality: {
275
- mode: string;
276
- canManage: boolean;
277
- changed: string | null;
278
- } | null;
279
- providers: {
280
- provider: string;
281
- name: string;
282
- tone: 'ok' | 'warn' | 'off' | 'neutral';
283
- words: string;
284
- connection: {
285
- words: string;
286
- facts: string;
287
- checkAction: string;
288
- } | null;
289
- usage: string;
290
- envName: string;
291
- subscriptionCapable: boolean;
292
- mode: 'subscription' | 'api-key';
293
- set: boolean;
294
- }[] | null;
295
- legacyWebhookWarning?: string;
296
- services: {
297
- configured: string[];
298
- channel: string | null;
299
- implicit: boolean;
300
- } | null;
301
- push: {
302
- available: boolean;
303
- devices: {
304
- id: number;
305
- words: string;
306
- state: string;
307
- removable: boolean;
308
- }[];
309
- } | null;
310
- /** Quiet chat: how chats reach this person, and their evening digest time (null: off). */
311
- chat?: {
312
- mode: 'quiet' | 'all';
313
- digestAt: string | null;
314
- /** Whether a result's saved screenshots follow its chat message: off, the first one, or up to 4. */
315
- screenshots?: 'off' | 'first' | 'all';
316
- /** Each project this person can see; a muted one sends no pings but stays in Tasks and the digest. */
317
- projects?: {
318
- repo: string;
319
- name: string;
320
- muted: boolean;
321
- }[];
322
- } | null;
323
- digest: {
324
- every: string;
325
- held: string | null;
326
- } | null;
327
- telegram: {
328
- state: string;
329
- current: string;
330
- /** v98: how the bot's messages reach Toolroll (pushed, or asked for), in words. */
331
- delivery?: string | null;
332
- };
333
- /** Each worker: how many tasks it runs at once, and what it is running now. */
334
- workers?: {
335
- name: string;
336
- tone: 'ok' | 'warn' | 'off';
337
- state: string;
338
- capacity: number;
339
- busy: number;
340
- running: {
341
- taskId: string;
342
- title: string;
343
- href: string;
344
- project: string | null;
345
- }[];
346
- }[] | null;
347
- /** v87: the mail server Send email steps use (approvers only); the password is never shown back. */
348
- email?: {
349
- set: boolean;
350
- host: string;
351
- port: number;
352
- secure: boolean;
353
- user: string;
354
- from: string;
355
- /** v89: where Email inbox triggers read (IMAP), and a Google account connected instead of a mail server (`redirect`: the address to register with Google, when this page's address can take one). */
356
- imapHost: string;
357
- imapPort: number;
358
- google: {
359
- connected: string | null;
360
- clientId: string;
361
- redirect: string | null;
362
- };
363
- } | null;
364
- /** The installation's first Ready result, in words ("first result in 7 min"); null before it arrives. */
365
- firstResult?: string | null;
366
- /** Settings → Updates: this version, the latest known one and its notes, how to update, the daily-check switch, and each worker's version. */
367
- updates?: BrowserUpdates | null;
368
- };
369
- /** A tile's `brand` is a chat app's logo (brand-mark.ts), drawn in place of its icon. */
370
- export type BrowserSettingsGroup = {
371
- title: string;
372
- tiles: {
373
- href: string;
374
- label: string;
375
- brand?: BrandIconId;
376
- status?: {
377
- tone: 'ok' | 'warn' | 'off';
378
- words: string;
379
- };
380
- }[];
381
- };
382
292
  export type BrowserUpdates = {
383
293
  current: string;
384
294
  /** The latest release the last check found; null before any check has worked. */
@@ -590,10 +500,61 @@ export type BrowserTaskView = {
590
500
  } | null;
591
501
  /** Where the approval sits: under the header when it is the thing to do now, else at the top of the Plan tab. */
592
502
  approvalPlacement?: "lead" | "plan";
503
+ /** The kit approval box (src/design/KIT.md): the act's form and the facts that decide password, one click or none;
504
+ * `planHtml` is what it signs, for the Plan tab. Null when nothing waits on this person's approval here. */
505
+ approve?: {
506
+ action: string;
507
+ fields: Record<string, string>;
508
+ label: string;
509
+ heading: string;
510
+ text: string;
511
+ kind: import("./design/kit.js").ApprovalKind;
512
+ facts: {
513
+ passwordless: boolean;
514
+ remembered: boolean;
515
+ automatic?: boolean;
516
+ };
517
+ /** When a remembered password stops counting (ISO); the page words it in the viewer's zone. */
518
+ rememberedUntil: string | null;
519
+ planHtml: string;
520
+ } | null;
521
+ /** Ship: the pull request's checks, each on one time axis (task ship's twin). Null: no checks read yet. */
522
+ ship?: {
523
+ pr: number;
524
+ head: string;
525
+ state: "running" | "passed" | "failed" | "none";
526
+ rows: import("./design/kit.js").TimingRow[];
527
+ summary: string;
528
+ observedAt: string;
529
+ } | null;
530
+ /** A release's own steps (release status's twin). Null: this task is no release, or nothing recorded. */
531
+ release?: {
532
+ tag: string;
533
+ version: string;
534
+ pr: number | null;
535
+ state: "running" | "waiting" | "failed" | "done";
536
+ rows: import("./design/kit.js").TimingRow[];
537
+ headline: string;
538
+ stopped: {
539
+ step: string;
540
+ message: string;
541
+ at: string;
542
+ } | null;
543
+ startedAt: string;
544
+ } | null;
545
+ /** How the plan was approved: by whom and how, or the rule that approved it automatically. */
546
+ approved?: {
547
+ by: string;
548
+ at: string;
549
+ automatic: boolean;
550
+ rule: string | null;
551
+ how: string;
552
+ version: string;
553
+ } | null;
593
554
  /** ⋯ More actions: the task's secondary acts, the same order on the task and agent pages, destructive last. */
594
555
  more?: BrowserTaskMore[];
595
556
  };
596
- export type BrowserTaskTab = "activity" | "result" | "plan";
557
+ export type BrowserTaskTab = "activity" | "result" | "plan" | "attempts";
597
558
  /** One ⋯ item: a plain link, a copy of this page's address, a one-click POST (never a ceremony), or a go-to that switches
598
559
  * to the tab holding the item's own form, opens it and focuses it (`target`: that element's id). */
599
560
  export type BrowserTaskMore = {
@@ -618,44 +579,34 @@ export type BrowserProjectRow = {
618
579
  name: string;
619
580
  path: string;
620
581
  shortPath: string;
582
+ /** The project's own page (/projects/<name>). */
583
+ href: string;
584
+ /** The session's open project. */
621
585
  open: boolean;
622
586
  /** When it was last opened here; null for a project only seen in the queue. */
623
587
  openedAt: string | null;
624
- knowledgeHref: string;
625
- /** Settings → Projects → Pull requests for this project, and whether they are on. */
626
- pullRequests?: {
627
- href: string;
628
- on: boolean;
629
- };
630
- /** Settings → Projects → Checks for this project, and its level in words. */
631
- checks?: {
632
- href: string;
633
- level: string;
634
- };
635
- /** What waits, runs, queues or finished today; null when not scanned. */
636
- peek: {
637
- label: string;
638
- href: string;
639
- tone: 'attention' | 'info' | 'neutral' | 'success';
640
- }[] | null;
588
+ /** The row's chip: something waits on this person, or runs; null for neither. */
589
+ status: 'needs' | 'running' | null;
590
+ /** Its counts in words ("2 need you · 1 running"); null when not scanned. */
591
+ summary: string | null;
641
592
  };
642
593
  export type BrowserProjectsView = {
643
594
  kind: 'projects';
644
- activity?: {
645
- project: string;
646
- report: import('./project-outcomes.js').ProjectOutcomes | null;
647
- };
648
595
  /** Arrived from New task: choosing where the task belongs. */
649
596
  choosing: boolean;
597
+ /** A refusal that belongs to the page, not to one form (already says what didn't change). */
650
598
  problem: string | null;
599
+ /** A neutral line (a finished clone). */
600
+ said: string | null;
651
601
  returnTo: string;
652
602
  recent: BrowserProjectRow[];
653
603
  available: BrowserProjectRow[];
654
- /** The add roads; `html` carries the server's GitHub-link and exact-path forms. */
604
+ /** The add ways (the server's forms), the clone review a preview minted, and whether the drawer opens at once
605
+ * (a refused GitHub link, shown next to its field). */
655
606
  add: {
656
- browse: string | null;
657
- github: string | null;
658
607
  html: string;
608
+ review: string | null;
609
+ openOnLoad: boolean;
659
610
  };
660
611
  };
661
612
  export type BrowserResultTab = 'summary' | 'changes' | 'checks';
@@ -1272,6 +1223,8 @@ export type BrowserFlowView = {
1272
1223
  body: string;
1273
1224
  timeoutMinutes: number;
1274
1225
  version: number;
1226
+ /** The content digest the panel showed: an approval of a held script carries it back. */
1227
+ digest: string;
1275
1228
  savedBy: string;
1276
1229
  savedAt: string;
1277
1230
  usedHere: string[];
@@ -1314,6 +1267,11 @@ export type BrowserFlowView = {
1314
1267
  optional: string | null;
1315
1268
  }[];
1316
1269
  schedulesDigest: string;
1270
+ /** The latest grant a change ended early (flow-unattended.ts unattendedViewOf): why and when. */
1271
+ ended?: {
1272
+ why: string;
1273
+ at: string;
1274
+ } | null;
1317
1275
  };
1318
1276
  /** Browser use (flow-browser.ts browserViewOf): null when no zone says it starts a browser. */
1319
1277
  browser: {
@@ -1498,9 +1456,107 @@ export type BrowserAgentsView = {
1498
1456
  empty: string | null;
1499
1457
  /** The Live grid (?view=live): every running agent's live output, watching only. */
1500
1458
  live?: boolean;
1459
+ /** The Finished group's window (?window=), 24 hours unless the address says otherwise. */
1460
+ window?: AgentLaneWindow;
1461
+ /** The computers that build (what /fleet showed), for a person with access to the whole installation; null otherwise. */
1462
+ computers?: BrowserComputers | null;
1463
+ /** Which model runs each phase (what /system showed), for a person with access to the whole installation. */
1464
+ phases?: BrowserAgentPhase[] | null;
1465
+ /** The rest of what /system showed: workspaces, the background service, notifications and external work. */
1466
+ system?: BrowserAgentsSystem | null;
1467
+ /** This person may open terminals (an installation-wide operator in a browser). */
1468
+ terminals?: boolean;
1469
+ /** What a computer act said, in fixed words (a retired computer, by the name the store knows). */
1470
+ computerSaid?: {
1471
+ tone: 'info' | 'error';
1472
+ text: string;
1473
+ } | null;
1501
1474
  };
1502
- export type BrowserView = BrowserTasksView | BrowserSettingsView | BrowserTaskView | BrowserProjectsView | BrowserResultView | BrowserFlowView | BrowserAgentsView;
1475
+ /** One computer that builds (a registered runner): what it is doing and what waits for it. */
1476
+ export type BrowserComputer = {
1477
+ name: string;
1478
+ host: string;
1479
+ state: 'building' | 'idle' | 'offline';
1480
+ capacity: number;
1481
+ /** Retired, listed only while tasks are still reserved for it. */
1482
+ retired: boolean;
1483
+ /** Its live builds this person may see; `hidden` counts the ones in projects they can't. */
1484
+ building: {
1485
+ taskId: string;
1486
+ title: string;
1487
+ href: string;
1488
+ project: string | null;
1489
+ }[];
1490
+ hidden: number;
1491
+ heardAt: string;
1492
+ registeredAt: string;
1493
+ /** The projects it takes work from, that this person may see. */
1494
+ projects: string[];
1495
+ /** The operator's note on its queue (display only). */
1496
+ note: string | null;
1497
+ /** Queued tasks reserved for it, that this person may see. */
1498
+ reserved: {
1499
+ id: string;
1500
+ title: string;
1501
+ href: string;
1502
+ project: string | null;
1503
+ taken: boolean;
1504
+ }[];
1505
+ };
1506
+ export type BrowserComputers = {
1507
+ list: BrowserComputer[];
1508
+ /** Register, retire, move reserved work and notes: an approver in a browser session. */
1509
+ manage: boolean;
1510
+ /** The queue's revision, for a move (POST /queue/move). */
1511
+ queueRevision: number;
1512
+ /** Queued tasks no computer is reserved for. */
1513
+ shared: number;
1514
+ };
1515
+ export type BrowserAgentPhase = {
1516
+ phase: 'plan' | 'build' | 'repair' | 'review';
1517
+ /** The provider and model in words; null when it can't be worked out (`problem` says why). */
1518
+ model: string | null;
1519
+ problem: string | null;
1520
+ /** Where the choice comes from, in words ("Set for the whole installation by alex"). */
1521
+ source: string;
1522
+ /** This provider reports tokens, not dollars. */
1523
+ noDollars: boolean;
1524
+ };
1525
+ export type BrowserAgentsSystem = {
1526
+ workspaces: {
1527
+ name: string;
1528
+ branch: string;
1529
+ state: 'building' | 'free' | 'needs review';
1530
+ }[];
1531
+ /** The background service's latest run on the open project: running since `at`, or ended at `at`. */
1532
+ service: {
1533
+ running: boolean;
1534
+ at: string;
1535
+ built: number;
1536
+ broke: number;
1537
+ } | null;
1538
+ outbox: number;
1539
+ external: {
1540
+ repo: string;
1541
+ state: string;
1542
+ }[];
1543
+ };
1544
+ export type BrowserView = BrowserTasksView | BrowserTaskView | BrowserProjectsView | BrowserResultView | BrowserFlowView | BrowserAgentsView | BrowserHomeView | BrowserSearchView;
1503
1545
  export type BrowserWorkspace = {
1546
+ /** The one Needs-you count (tasks only) with its scope: the Tasks list's own count for the project in view (`scope`,
1547
+ * a project path) or every project (null), its words ("5 need you in payments-api") and the list it opens. */
1548
+ needsYou?: {
1549
+ count: number;
1550
+ saturated: boolean;
1551
+ scope: string | null;
1552
+ label: string;
1553
+ href: string;
1554
+ };
1555
+ /** The same Needs-you count for each project (`path` null: work with no project), from the same work index totals. */
1556
+ needsYouByProject?: {
1557
+ path: string | null;
1558
+ count: number;
1559
+ }[];
1504
1560
  version: 1;
1505
1561
  path: string;
1506
1562
  title: string;
@@ -1573,6 +1629,96 @@ export type BrowserWorkspace = {
1573
1629
  /** The Chat landing's live view: who is working now, four counts, and Catch up in tabs. */
1574
1630
  home?: BrowserHome | null;
1575
1631
  };
1632
+ /** Home ("/"): one sentence that answers "what needs me?", four counts that agree with the Tasks filters they open,
1633
+ * what waits on this person grouped by what it asks, what is running, and the selected item answered in place. */
1634
+ export type BrowserHomeView = {
1635
+ kind: 'home';
1636
+ /** "7 need you across 2 projects.", derived from the same counts as the figures. */
1637
+ say: string;
1638
+ /** The project in view (a path) or every project (null), and the scope links (null with one project). */
1639
+ project: string | null;
1640
+ scopes: {
1641
+ key: string;
1642
+ label: string;
1643
+ href: string;
1644
+ active: boolean;
1645
+ }[] | null;
1646
+ counts: {
1647
+ key: 'needs' | 'running' | 'queued' | 'finished';
1648
+ label: string;
1649
+ value: number;
1650
+ href: string;
1651
+ }[];
1652
+ groups: {
1653
+ key: 'decide' | 'review' | 'unblock' | 'running';
1654
+ label: string;
1655
+ rows: BrowserHomeRow[];
1656
+ }[];
1657
+ /** More waits than the list shows: open them all in Tasks. */
1658
+ more: {
1659
+ count: number;
1660
+ href: string;
1661
+ } | null;
1662
+ newTask: string;
1663
+ /** The lead's message box, where chat is allowed for this person: a POST to /chat in this scope. */
1664
+ ask: {
1665
+ project: string | null;
1666
+ placeholder: string;
1667
+ } | null;
1668
+ empty: {
1669
+ title: string;
1670
+ text: string;
1671
+ } | null;
1672
+ };
1673
+ export type BrowserHomeRow = {
1674
+ id: string;
1675
+ title: string;
1676
+ href: string;
1677
+ project: string | null;
1678
+ age: string;
1679
+ chip: {
1680
+ word: string;
1681
+ tone: '' | 'needs' | 'ask' | 'live' | 'done' | 'failed';
1682
+ };
1683
+ /** One line: what it asks, or what the agent is doing now. */
1684
+ line: string | null;
1685
+ /** The one act that resolves it (a link), or null. */
1686
+ action: {
1687
+ label: string;
1688
+ href: string;
1689
+ } | null;
1690
+ /** An agent's question, answered in place (POST /d/<id>/answer, one click); null when it must be answered on its page. */
1691
+ question: {
1692
+ id: number;
1693
+ text: string;
1694
+ recap: string;
1695
+ options: {
1696
+ id: string;
1697
+ label: string;
1698
+ consequence: string;
1699
+ recommended: boolean;
1700
+ }[];
1701
+ } | null;
1702
+ };
1703
+ /** Search ("/search"): the places and the tasks in view that match the words; the ⌘K menu's "See all results". */
1704
+ export type BrowserSearchView = {
1705
+ kind: 'search';
1706
+ q: string;
1707
+ tasks: {
1708
+ id: string;
1709
+ title: string;
1710
+ href: string;
1711
+ project: string | null;
1712
+ age: string;
1713
+ chip: {
1714
+ word: string;
1715
+ tone: '' | 'needs' | 'ask' | 'live' | 'done' | 'failed';
1716
+ };
1717
+ archived: boolean;
1718
+ }[];
1719
+ /** More tasks exist than were read: the Tasks list has them all. */
1720
+ truncated: boolean;
1721
+ };
1576
1722
  /** One agent at work now: its task and the machine's own phase, in words. */
1577
1723
  export type BrowserHomeAgent = {
1578
1724
  runId: number;
@@ -96,16 +96,17 @@ export function browserProjectsOf(projects) {
96
96
  }
97
97
  export function browserNavigationOf(path, project = null, needsYou = 0, tasksProject = project, needsYouLabel) {
98
98
  const pathname = path.split('?')[0].split('#')[0];
99
- const knowledge = pathname === '/settings/knowledge' || pathname.startsWith('/settings/knowledge/');
99
+ const under = (...roots) => roots.some(root => pathname === root || pathname.startsWith(`${root}/`));
100
+ // The rail (UI revamp, wave B): Home carries the one Needs-you count; the lead chat and an agent's question live
101
+ // under Home, a task's pages under Tasks, every computer and terminal under Agents, every setting under Settings.
100
102
  return [
101
- { label: 'Chat', href: '/chat', active: pathname === '/chat' },
102
- { label: 'Tasks', href: `/work${tasksProject === null ? '' : `?project=${encodeURIComponent(tasksProject)}`}`,
103
- active: pathname === '/work' || pathname === '/tasks' || pathname.startsWith('/t/') || pathname.startsWith('/r/'),
103
+ { label: 'Home', href: '/', active: pathname === '/' || pathname === '/chat' || under('/d', '/activity', '/morning'),
104
104
  ...(needsYou > 0 ? { count: needsYou, ...(needsYouLabel === undefined ? {} : { countLabel: needsYouLabel }) } : {}) },
105
- { label: 'Agents', href: '/agents', active: pathname === '/agents' || pathname === '/peek' },
106
- { label: 'Flows', href: '/flows', active: pathname === '/flows' || pathname.startsWith('/flows/') },
107
- { label: 'Projects', href: '/projects', active: pathname === '/projects' },
108
- { label: 'Knowledge', href: `/settings/knowledge${project === null ? '' : `?repo=${encodeURIComponent(project)}`}`, active: knowledge },
109
- { label: 'Settings', href: '/settings', active: !knowledge && (pathname === '/settings' || pathname.startsWith('/settings/')) },
105
+ { label: 'Tasks', href: `/work${tasksProject === null ? '' : `?project=${encodeURIComponent(tasksProject)}`}`,
106
+ active: under('/work', '/tasks', '/t', '/r', '/done', '/board', '/queue', '/inbox', '/review') },
107
+ { label: 'Flows', href: '/flows', active: under('/flows', '/recipes', '/kits', '/routines') },
108
+ { label: 'Agents', href: '/agents', active: under('/agents', '/peek', '/term', '/fleet', '/system', '/runs') },
109
+ { label: 'Projects', href: '/projects', active: under('/projects') },
110
+ { label: 'Settings', href: '/settings', active: under('/settings', '/spend', '/mode', '/people', '/ledger', '/menu') },
110
111
  ];
111
112
  }
@@ -76,7 +76,7 @@ export declare const CHAT_CONTROLS: {
76
76
  };
77
77
  readonly providers: {
78
78
  readonly label: "Connect an agent";
79
- readonly href: "/settings#providers";
79
+ readonly href: "/settings/agents#providers";
80
80
  };
81
81
  readonly skills: {
82
82
  readonly label: "Manage skills";
@@ -21,7 +21,7 @@ export const CHAT_CONTROLS = {
21
21
  integrations: { label: "Set up integrations", href: "/settings/integrations" },
22
22
  settings: { label: "Open settings", href: "/settings" },
23
23
  permissions: { label: "Review permissions", href: "/settings" },
24
- providers: { label: "Connect an agent", href: "/settings#providers" },
24
+ providers: { label: "Connect an agent", href: "/settings/agents#providers" },
25
25
  skills: { label: "Manage skills", href: "/settings/skills" },
26
26
  tools: { label: "Manage tools", href: "/settings/tools" },
27
27
  knowledge: { label: "Edit project knowledge", href: "/settings/knowledge" },