@openagt/dashboard 0.15.0 → 0.17.0

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 (144) hide show
  1. package/README.md +1 -1
  2. package/dist/built-in.d.ts.map +1 -1
  3. package/dist/built-in.js +1 -1
  4. package/dist/built-in.js.map +1 -1
  5. package/dist/client.d.ts +2 -0
  6. package/dist/client.d.ts.map +1 -1
  7. package/dist/client.js +4 -0
  8. package/dist/client.js.map +1 -1
  9. package/dist/daemon-runtime.d.ts.map +1 -1
  10. package/dist/daemon-runtime.js +13 -5
  11. package/dist/daemon-runtime.js.map +1 -1
  12. package/dist/daemon.d.ts.map +1 -1
  13. package/dist/daemon.js +8 -3
  14. package/dist/daemon.js.map +1 -1
  15. package/dist/dashboard/agent-handoff.d.ts +48 -1
  16. package/dist/dashboard/agent-handoff.d.ts.map +1 -1
  17. package/dist/dashboard/agent-handoff.js +82 -6
  18. package/dist/dashboard/agent-handoff.js.map +1 -1
  19. package/dist/dashboard/cache.d.ts +5 -0
  20. package/dist/dashboard/cache.d.ts.map +1 -1
  21. package/dist/dashboard/cache.js +2 -2
  22. package/dist/dashboard/cache.js.map +1 -1
  23. package/dist/dashboard/machine-call.d.ts +13 -1
  24. package/dist/dashboard/machine-call.d.ts.map +1 -1
  25. package/dist/dashboard/machine-call.js +22 -2
  26. package/dist/dashboard/machine-call.js.map +1 -1
  27. package/dist/dashboard/relay-endpoints.d.ts +12 -0
  28. package/dist/dashboard/relay-endpoints.d.ts.map +1 -1
  29. package/dist/dashboard/relay-endpoints.js +23 -3
  30. package/dist/dashboard/relay-endpoints.js.map +1 -1
  31. package/dist/dashboard/remote-run.d.ts +11 -1
  32. package/dist/dashboard/remote-run.d.ts.map +1 -1
  33. package/dist/dashboard/remote-run.js +32 -7
  34. package/dist/dashboard/remote-run.js.map +1 -1
  35. package/dist/dashboard/rpc-serve.d.ts +8 -3
  36. package/dist/dashboard/rpc-serve.d.ts.map +1 -1
  37. package/dist/dashboard/rpc-serve.js.map +1 -1
  38. package/dist/dashboard/types.d.ts +2 -0
  39. package/dist/dashboard/types.d.ts.map +1 -1
  40. package/dist/dashboard-bundle/assets/main-BEvNE_j-.js +141 -0
  41. package/dist/dashboard-bundle/assets/main-DYV5aTCD.css +2 -0
  42. package/dist/dashboard-bundle/assets/module-C6swDbeD.js +24 -0
  43. package/dist/dashboard-bundle/host/module.js +1 -1
  44. package/dist/dashboard-bundle/index.html +3 -3
  45. package/dist/dashboard-rpc/machines.d.ts +4 -1
  46. package/dist/dashboard-rpc/machines.d.ts.map +1 -1
  47. package/dist/dashboard-rpc/machines.js +5 -2
  48. package/dist/dashboard-rpc/machines.js.map +1 -1
  49. package/dist/dashboard-rpc/modules.d.ts.map +1 -1
  50. package/dist/dashboard-rpc/modules.js +5 -1
  51. package/dist/dashboard-rpc/modules.js.map +1 -1
  52. package/dist/dashboard-rpc/reads.d.ts +8 -2
  53. package/dist/dashboard-rpc/reads.d.ts.map +1 -1
  54. package/dist/dashboard-rpc/reads.js +14 -6
  55. package/dist/dashboard-rpc/reads.js.map +1 -1
  56. package/dist/dashboard-rpc/relay-agent.d.ts +2 -1
  57. package/dist/dashboard-rpc/relay-agent.d.ts.map +1 -1
  58. package/dist/dashboard-rpc/relay-agent.js +7 -4
  59. package/dist/dashboard-rpc/relay-agent.js.map +1 -1
  60. package/dist/dashboard-rpc/relay-dispatch.d.ts +2 -0
  61. package/dist/dashboard-rpc/relay-dispatch.d.ts.map +1 -1
  62. package/dist/dashboard-rpc/relay-dispatch.js +11 -5
  63. package/dist/dashboard-rpc/relay-dispatch.js.map +1 -1
  64. package/dist/events.d.ts +15 -15
  65. package/dist/events.d.ts.map +1 -1
  66. package/dist/module-types/dashboard/components/AddMachineDialog.d.ts +4 -0
  67. package/dist/module-types/dashboard/components/DiffStat.d.ts +8 -2
  68. package/dist/module-types/dashboard/components/FileIcon.d.ts +5 -0
  69. package/dist/module-types/dashboard/components/Markdown.d.ts +5 -0
  70. package/dist/module-types/dashboard/components/PaneHeader.d.ts +14 -0
  71. package/dist/module-types/dashboard/components/SettingsRows.d.ts +3 -2
  72. package/dist/module-types/dashboard/components/ui/context-menu.d.ts +3 -0
  73. package/dist/module-types/dashboard/components/ui/copy-button.d.ts +5 -0
  74. package/dist/module-types/dashboard/components/ui/dialog.d.ts +7 -0
  75. package/dist/module-types/dashboard/components/ui/scroll-area.d.ts +1 -4
  76. package/dist/module-types/dashboard/lib/machines.d.ts +15 -0
  77. package/dist/module-types/dashboard/lib/models.d.ts +12 -0
  78. package/dist/module-types/dashboard/lib/remote-target.d.ts +6 -0
  79. package/dist/module-types/dashboard/lib/use-modules.d.ts +3 -3
  80. package/dist/module-types/dashboard/module/index.d.ts +41 -20
  81. package/dist/module-types/dashboard/rpc/machines.d.ts +9 -0
  82. package/dist/module-types/src/client.d.ts +2 -0
  83. package/dist/module-types/src/dashboard/agent-handoff.d.ts +48 -1
  84. package/dist/module-types/src/dashboard/cache.d.ts +5 -0
  85. package/dist/module-types/src/dashboard/machine-call.d.ts +13 -1
  86. package/dist/module-types/src/dashboard/remote-run.d.ts +11 -1
  87. package/dist/module-types/src/dashboard/rpc-serve.d.ts +8 -3
  88. package/dist/module-types/src/dashboard/types.d.ts +2 -0
  89. package/dist/module-types/src/dashboard-rpc/machines.d.ts +4 -1
  90. package/dist/module-types/src/dashboard-rpc/reads.d.ts +8 -2
  91. package/dist/module-types/src/dashboard-rpc/relay-agent.d.ts +2 -1
  92. package/dist/module-types/src/events.d.ts +15 -15
  93. package/dist/module-types/src/package-services.d.ts +29 -0
  94. package/dist/module-types/src/project-hooks.d.ts +9 -1
  95. package/dist/module-types/src/project-modules.d.ts +3 -1
  96. package/dist/module-types/src/publish-levels.d.ts +4 -3
  97. package/dist/module-types/src/reached-by-line.d.ts +12 -0
  98. package/dist/module-types/src/registry.d.ts +31 -0
  99. package/dist/module-types/src/screens.d.ts +7 -5
  100. package/dist/module-types/src/store/agent-store.d.ts +8 -0
  101. package/dist/module-types/src/store/runs.d.ts +6 -0
  102. package/dist/package-services.d.ts +4 -1
  103. package/dist/package-services.d.ts.map +1 -1
  104. package/dist/package-services.js +10 -0
  105. package/dist/package-services.js.map +1 -1
  106. package/dist/project-hooks.d.ts +9 -1
  107. package/dist/project-hooks.d.ts.map +1 -1
  108. package/dist/project-hooks.js +6 -1
  109. package/dist/project-hooks.js.map +1 -1
  110. package/dist/project-modules.d.ts +3 -1
  111. package/dist/project-modules.d.ts.map +1 -1
  112. package/dist/project-modules.js +4 -2
  113. package/dist/project-modules.js.map +1 -1
  114. package/dist/publish-levels.d.ts +4 -3
  115. package/dist/publish-levels.d.ts.map +1 -1
  116. package/dist/publish-levels.js +5 -4
  117. package/dist/publish-levels.js.map +1 -1
  118. package/dist/reached-by-line.d.ts +13 -0
  119. package/dist/reached-by-line.d.ts.map +1 -0
  120. package/dist/reached-by-line.js +22 -0
  121. package/dist/reached-by-line.js.map +1 -0
  122. package/dist/registry.d.ts +31 -0
  123. package/dist/registry.d.ts.map +1 -1
  124. package/dist/registry.js +26 -1
  125. package/dist/registry.js.map +1 -1
  126. package/dist/screens.d.ts +7 -5
  127. package/dist/screens.d.ts.map +1 -1
  128. package/dist/screens.js +19 -8
  129. package/dist/screens.js.map +1 -1
  130. package/dist/store/agent-store.d.ts +8 -0
  131. package/dist/store/agent-store.d.ts.map +1 -1
  132. package/dist/store/agent-store.js.map +1 -1
  133. package/dist/store/run-record.js +1 -1
  134. package/dist/store/run-record.js.map +1 -1
  135. package/dist/store/runs.d.ts +6 -0
  136. package/dist/store/runs.d.ts.map +1 -1
  137. package/dist/store/runs.js +3 -1
  138. package/dist/store/runs.js.map +1 -1
  139. package/dist/terminal.js +4 -2
  140. package/dist/terminal.js.map +1 -1
  141. package/package.json +18 -16
  142. package/dist/dashboard-bundle/assets/main-BtmQIAUe.js +0 -140
  143. package/dist/dashboard-bundle/assets/main-DbqABoVD.css +0 -2
  144. package/dist/dashboard-bundle/assets/module-CFB4pxwP.js +0 -24
@@ -0,0 +1,14 @@
1
+ import { type ReactNode } from 'react';
2
+ export interface PaneHeaderSlots {
3
+ title: HTMLElement | null;
4
+ actions: HTMLElement | null;
5
+ }
6
+ export declare const PaneHeaderContext: import("react").Context<PaneHeaderSlots>;
7
+ /** In place of the pane's name in its card's header. */
8
+ export declare function PaneTitle({ children }: {
9
+ children: ReactNode;
10
+ }): import("react").ReactPortal | null;
11
+ /** In the pane's card's header, before the buttons that let it fill the page and close it. */
12
+ export declare function PaneActions({ children }: {
13
+ children: ReactNode;
14
+ }): import("react").ReactPortal | null;
@@ -1,8 +1,9 @@
1
1
  import type { ReactNode } from 'react';
2
- /** One section of the Settings page: a titled card of rows. */
3
- export declare function SettingsSection({ title, description, children }: {
2
+ /** One section of the Settings page: a titled card of rows, with what it offers as a whole (`action`, a button) beside its title. */
3
+ export declare function SettingsSection({ title, description, action, children }: {
4
4
  title: string;
5
5
  description?: string;
6
+ action?: ReactNode;
6
7
  children: ReactNode;
7
8
  }): import("react").JSX.Element;
8
9
  /** One setting: what it is and what it does on the left, its control on the right. */
@@ -0,0 +1,3 @@
1
+ import { ContextMenu as BaseContextMenu } from '@base-ui-components/react/context-menu';
2
+ export declare const ContextMenu: typeof BaseContextMenu.Root;
3
+ export declare const ContextMenuTrigger: import("react").ForwardRefExoticComponent<import("@base-ui-components/react/context-menu").ContextMenuTriggerProps & import("react").RefAttributes<HTMLDivElement>>;
@@ -0,0 +1,5 @@
1
+ export declare function CopyButton({ text, label, className }: {
2
+ text: string;
3
+ label: string;
4
+ className?: string;
5
+ }): import("react").JSX.Element;
@@ -0,0 +1,7 @@
1
+ import type { ReactNode } from 'react';
2
+ export declare function Dialog({ open, onOpenChange, title, children, }: {
3
+ open: boolean;
4
+ onOpenChange: (open: boolean) => void;
5
+ title: ReactNode;
6
+ children: ReactNode;
7
+ }): import("react").JSX.Element;
@@ -1,8 +1,5 @@
1
- import type { Ref } from 'react';
2
1
  import { ScrollArea as ScrollAreaPrimitive } from '@base-ui-components/react/scroll-area';
3
- export declare function ScrollArea({ className, children, viewportRef, viewportClassName, ...props }: ScrollAreaPrimitive.Root.Props & {
4
- /** The scrolled element, for a rail that scrolls itself (ViewsRail). */
5
- viewportRef?: Ref<HTMLDivElement>;
2
+ export declare function ScrollArea({ className, children, viewportClassName, ...props }: ScrollAreaPrimitive.Root.Props & {
6
3
  /** Extra classes on the viewport — where the height cap belongs when the Root has no definite
7
4
  * height. A `max-h-*` on the Root only caps the box; the viewport's `h-full` cannot resolve
8
5
  * against a parent's max-height, so the content grows instead of scrolling. Put the cap here. */
@@ -0,0 +1,15 @@
1
+ import { type AddMachineResult, type Machine, type RemoveMachineResult } from '../rpc/machines.js';
2
+ export type { Machine };
3
+ /** Read the list from the daemon again. A read that fails keeps what is shown. */
4
+ export declare function refreshMachines(): Promise<void>;
5
+ /** Save the machine a pasted link names; the list is read again once the daemon has it. */
6
+ export declare function addMachine(pasted: string, label?: string): Promise<AddMachineResult>;
7
+ /**
8
+ * Take a saved machine off the list, and answer whether the daemon did, with its reason when it
9
+ * did not. The list is read again either way, so a machine the daemon did not remove is still shown.
10
+ * A removed machine is no longer where the next run starts (#1072): that run would point at
11
+ * something that is not in the list.
12
+ */
13
+ export declare function removeMachine(id: string): Promise<RemoveMachineResult>;
14
+ /** The saved machines as reactive state: empty until the daemon has answered. */
15
+ export declare function useMachines(): Machine[];
@@ -14,6 +14,18 @@ export declare function driverOptions(models: ModelsView | undefined): DriverOpt
14
14
  * the id itself: that is what the run was given or ran.
15
15
  */
16
16
  export declare function modelName(models: DriverModels | undefined, id: string): string;
17
+ /**
18
+ * The effort levels the picked model offers, by the coding agent's own names and in its own order
19
+ * (`DriverModel.efforts`). Empty for a model that takes none, for an agent that could not list its
20
+ * models, and before the daemon has answered — the control is simply not there then.
21
+ */
22
+ export declare function modelEfforts(models: ModelsView | undefined, driver: string | undefined, id: string | undefined): readonly string[];
23
+ /**
24
+ * How much conversation the picked model holds, by the coding agent's own word (Codex says it; for
25
+ * Claude it is what the driver knows of the family). `undefined` for a model nobody has said it
26
+ * of — nothing here guesses one.
27
+ */
28
+ export declare function modelContextWindow(models: ModelsView | undefined, driver: string | undefined, id: string | undefined): number | undefined;
17
29
  export type { DriverModels, ModelsView };
18
30
  /** A coding agent as a module offers it: its name for the run (`claude-code`), its label, its models, and why it lists none. */
19
31
  export type CodingAgent = DriverOption;
@@ -0,0 +1,6 @@
1
+ /** Pick a saved machine (by id) as the run's target, or null to go back to this machine. */
2
+ export declare function selectMachine(id: string | null): void;
3
+ /** The picked machine's id, read at submit time to say where the run starts. */
4
+ export declare function getSelectedMachineId(): string | null;
5
+ /** The picked machine's id as reactive state; null on the server and until one is picked. */
6
+ export declare function useSelectedMachineId(): string | null;
@@ -14,7 +14,7 @@ export interface MountedCard extends ModuleCard {
14
14
  package: string;
15
15
  projects: string[];
16
16
  }
17
- /** A side-rail tab as the shell mounts it: the tab, plus the package it came from and the projects that have it. */
17
+ /** A pane as the shell mounts it: the pane, plus the package it came from and the projects that have it. */
18
18
  export interface MountedPanel extends ModulePanel {
19
19
  package: string;
20
20
  projects: string[];
@@ -45,7 +45,7 @@ export interface MountedModules {
45
45
  /** Every package's cards, in the order the Overview draws the ones it draws: by `order`, then by package name. */
46
46
  cards: MountedCard[];
47
47
  linkActions: MountedLinkAction[];
48
- /** The side-rail tabs, in package order. */
48
+ /** The panes beside the chat, in package order. */
49
49
  panels: MountedPanel[];
50
50
  /** The run slots, one entry per module that has any, in package order. */
51
51
  runSlots: MountedRunSlots[];
@@ -68,7 +68,7 @@ export declare function byMountOrder(a: {
68
68
  }): number;
69
69
  /**
70
70
  * What the registered projects' modules add (#1774), in package order: the pages, a segment two
71
- * modules claim going to the first, the cards (#1818), sorted by their order then their package, the link actions, the side-rail tabs, the run slots, the Settings sections (sorted as the cards are) and the usage bar's stop line (the first module's that declares one),
71
+ * modules claim going to the first, the cards (#1818), sorted by their order then their package, the link actions, the panes, the run slots, the Settings sections (sorted as the cards are) and the usage bar's stop line (the first module's that declares one),
72
72
  * every one of them, each carrying the package it came from and the projects that have it. `loaded` is false until the module list has
73
73
  * been read and every module in it imported, so the shell can tell "no such page" from "not
74
74
  * loaded yet". A change of `reloadKey` reads the list again at once; what is mounted stays until
@@ -176,7 +176,7 @@ export interface ModuleSchedule {
176
176
  read(host: ModuleHost, project: ModuleProject): Promise<ModuleScheduledCommand[]>;
177
177
  }
178
178
  /**
179
- * The Context as a side-rail tab sees it (#504): the files the next run is pointed at. A tab may
179
+ * The Context as a pane sees it (#504): the files the next run is pointed at. A pane may
180
180
  * show which files are in it and add or remove one.
181
181
  */
182
182
  export interface ModuleContext {
@@ -185,19 +185,19 @@ export interface ModuleContext {
185
185
  /** Add the path to the Context, or take it out when it is in. */
186
186
  toggle(path: string): void;
187
187
  }
188
- /** What a side-rail tab is rendered with: the project on screen, the run selected in it (if any), the Context. */
188
+ /** What a pane is rendered with: the project on screen, the run selected in it (if any), the Context. */
189
189
  export interface ModulePanelProps {
190
190
  projectId: string;
191
191
  /** The run whose page this is; absent on the project's own page. */
192
192
  agentId?: string;
193
193
  /**
194
194
  * How many events the run's feed has shown: it grows each time the agent does something, so a
195
- * tab showing what the agent changes reads again then, rather than on its next poll. Absent on
195
+ * pane showing what the agent changes reads again then, rather than on its next poll. Absent on
196
196
  * the project's own page.
197
197
  */
198
198
  activity?: number;
199
199
  /**
200
- * On a tab that lists what a run changed (`changes`): the changed file a click in the chat
200
+ * On a pane that lists what a run changed (`changes`): the changed file a click in the chat
201
201
  * asked to see, by its path in the run's checkout. `at` tells one ask from the next for the
202
202
  * same file. Absent until a file is asked for.
203
203
  */
@@ -208,30 +208,33 @@ export interface ModulePanelProps {
208
208
  context: ModuleContext;
209
209
  }
210
210
  /**
211
- * A tab a module adds to the side rail (#492), shown on every project's page and every run's page
212
- * of the projects that have the module, before the dashboard's own tabs. A tab with nothing to
213
- * show says so inside it: the rail cannot know a module is empty without rendering it.
211
+ * A pane a module adds beside the chat (#492), on every project's page and every run's page of
212
+ * the projects that have the module: an icon at the end of the page's top bar opens it, in a
213
+ * column with the other open panes. A pane with nothing to show says so inside it: the top bar
214
+ * cannot know a module is empty without rendering it.
214
215
  */
215
216
  export interface ModulePanel {
216
- /** Which tab this is among the module's own, for the rail's key and its remembered pick. */
217
+ /** Which pane this is among the module's own, for its key and for remembering that it is open. */
217
218
  id: string;
218
- /** The tab's label. */
219
+ /** The pane's name: on its card, and what its icon is called. */
219
220
  label: string;
220
- /** The tab's tooltip: one sentence on what it shows. */
221
+ /** The icon's tooltip: one sentence on what the pane shows. */
221
222
  help: string;
222
- /** A count shown on the tab beside its label; none when absent or 0. */
223
- count?(props: ModulePanelProps): number;
223
+ /** The pane's icon in the top bar, drawn at the size its `className` gives. */
224
+ icon: ComponentType<{
225
+ className?: string;
226
+ }>;
224
227
  /**
225
- * This tab lists what a run changed. The chat's row of a changed file then opens the side panel
226
- * on it, and hands it the file as `reveal`. Without such a tab, those rows open nothing.
228
+ * This pane lists what a run changed. The chat's row of a changed file then opens it, and
229
+ * hands it the file as `reveal`. Without such a pane, those rows open nothing.
227
230
  */
228
231
  changes?: true;
229
232
  /**
230
- * This tab shows a run's live screen ({@link ModuleHost.watchScreen}). The chat's row of a live
231
- * screen then opens the side panel on it. Without such a tab, that row is a line of text.
233
+ * This pane shows a run's live screen ({@link ModuleHost.watchScreen}). The chat's row of a live
234
+ * screen then opens it. Without such a pane, that row is a line of text.
232
235
  */
233
236
  screen?: true;
234
- /** The tab's contents. */
237
+ /** The pane's contents. They may put their own things in the card's header: {@link PaneTitle}, {@link PaneActions}. */
235
238
  Panel: ComponentType<ModulePanelProps>;
236
239
  }
237
240
  /** What a run slot is rendered with: the run, and whether its agent is working. */
@@ -257,7 +260,7 @@ export interface ModuleDefinition {
257
260
  cards?: ModuleCard[];
258
261
  /** The actions the module offers on the links dashboard pages show, wherever the link's project has the module's package. */
259
262
  linkActions?: LinkAction[];
260
- /** The tabs the module adds to the side rail. */
263
+ /** The panes the module adds beside the chat. */
261
264
  panels?: ModulePanel[];
262
265
  /** What the module adds to a run's page. */
263
266
  run?: ModuleRunSlots;
@@ -348,6 +351,11 @@ export interface ModuleHost {
348
351
  * pastes it under Machines. This computer is let in there with it, once, and keeps its key.
349
352
  */
350
353
  addMachine(link: string, label?: string): Promise<MachineAdded>;
354
+ /**
355
+ * Take a saved machine off the list, by its id, and this computer out of the machine: its key
356
+ * there stops working. Refused, with the reason, while a run is at work there.
357
+ */
358
+ removeMachine(id: string): Promise<MachineRemoved>;
351
359
  /**
352
360
  * What the live screen of a run shows, as the screen's own stream of bytes, until `signal` ends
353
361
  * it; nothing when the run has no live screen. OpenAgent asks the computer the run is on, which
@@ -365,6 +373,8 @@ export interface ModuleMachine {
365
373
  url: string;
366
374
  /** The OpenAgent it runs; absent for a machine that does not answer right now. */
367
375
  version?: string;
376
+ /** The id the machine lists this computer under, among the devices that are in there. */
377
+ device?: string;
368
378
  }
369
379
  /** What {@link ModuleHost.machines} answers. */
370
380
  export interface ModuleMachines {
@@ -379,6 +389,13 @@ export type MachineAdded = {
379
389
  ok: false;
380
390
  error: string;
381
391
  };
392
+ /** How removing a machine went: done, or refused, with the reason. */
393
+ export type MachineRemoved = {
394
+ ok: true;
395
+ } | {
396
+ ok: false;
397
+ error: string;
398
+ };
382
399
  /** What the dashboard knows about the module it is serving: every service but the commands and the reads, which it binds to the package. */
383
400
  export type ModuleHostBase = Omit<ModuleHost, 'runCommand' | 'act' | 'runComputerCommand' | 'read'>;
384
401
  /**
@@ -412,17 +429,21 @@ export { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '.
412
429
  export { Popover, PopoverContent, PopoverTrigger } from '../components/ui/popover.js';
413
430
  export { RangeSlider } from '../components/ui/slider.js';
414
431
  export { Separator } from '../components/ui/separator.js';
415
- export { PreviewCard } from '@base-ui-components/react/preview-card';
416
432
  export { DiffStat } from '../components/DiffStat.js';
417
433
  export { ScrollArea } from '../components/ui/scroll-area.js';
418
434
  export { Tooltip, TooltipTrigger, TooltipContent } from '../components/ui/tooltip.js';
419
- export { DropdownMenu, DropdownMenuContent, DropdownMenuCheckboxItem, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger } from '../components/ui/dropdown-menu.js';
435
+ export { DropdownMenu, DropdownMenuContent, DropdownMenuCheckboxItem, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger } from '../components/ui/dropdown-menu.js';
436
+ export { ContextMenu, ContextMenuTrigger } from '../components/ui/context-menu.js';
437
+ export { PaneTitle, PaneActions } from '../components/PaneHeader.js';
438
+ export { FileIcon } from '../components/FileIcon.js';
420
439
  export { Markdown } from '../components/Markdown.js';
421
440
  export { StartAgentButton } from '../components/StartAgentButton.js';
422
441
  export { LinkActions, type ProjectLinks, type LinkTargets } from '../components/LinkActions.js';
423
442
  export { cn } from '../lib/utils.js';
424
443
  export { SettingsSection, SettingsRow, SettingsSelectRow, type SettingsOption } from '../components/SettingsRows.js';
425
444
  export { QrCode } from '../components/QrCode.js';
445
+ export { AddMachineDialog } from '../components/AddMachineDialog.js';
446
+ export { reachedByLine } from '../../src/client.js';
426
447
  export { useCodingAgents, type CodingAgent } from '../lib/models.js';
427
448
  export { MAX_SPEND_OFFSET } from '../../src/preference-defaults.js';
428
449
  export { formatRelative, formatDateTime, formatDuration, formatAge } from '../lib/format-date.js';
@@ -0,0 +1,9 @@
1
+ import type * as impl from '../../src/dashboard-rpc/machines.js';
2
+ export type * from '../../src/dashboard-rpc/machines.js';
3
+ export declare const onMachines: () => Promise<impl.Machine[]>;
4
+ export declare const sendAddMachine: (pasted: string, label?: string | undefined) => Promise<impl.AddMachineResult>;
5
+ export declare const sendRemoveMachine: (id: string) => Promise<impl.RemoveMachineResult>;
6
+ export declare const onMachinesReachable: () => Promise<Record<string, boolean>>;
7
+ export declare const onMachineVersions: () => Promise<impl.MachineVersions>;
8
+ export declare const sendProjectToMachine: (projectId: string, machineId: string) => Promise<impl.ProjectOnMachine>;
9
+ export declare const onProjectOnMachine: (projectId: string, machineId: string) => Promise<impl.ProjectOnMachine>;
@@ -12,5 +12,7 @@ export { SeenTracker } from './dashboard/keyed-watcher.js';
12
12
  export type { ProjectionRead } from './dashboard/projects.js';
13
13
  export { NOTIFICATION_DEFAULTS, MAX_SPEND_OFFSET, notifies, browserNotifyEnabled, notifyCategoryEnabled, type NotifyCategory } from './preference-defaults.js';
14
14
  export { parseMachineLink } from './machine-link.js';
15
+ export { reachedByLine } from './reached-by-line.js';
16
+ export { isLoopbackHost } from './loopback-host.js';
15
17
  export { bridgeChoiceRequest } from './dashboard/bridge-question.js';
16
18
  export { cloudRunState, cloudRunActive, CLOUD_SESSION_WINDOW_MS, type CloudRunState } from './cloud-run-state.js';
@@ -1,3 +1,4 @@
1
+ import { type GitRunner } from '@openagt/agent-data';
1
2
  import { type LinkedPr, type BranchPrLookup } from './pull-requests.js';
2
3
  import type { Cached } from './cache.js';
3
4
  import type { AgentMeta } from '../store/index.js';
@@ -60,6 +61,30 @@ export interface AgentHandoff {
60
61
  pr?: LinkedPr;
61
62
  /** The PR is not known yet, rather than absent (#1028): the lookup is still running. */
62
63
  prPending?: boolean;
64
+ /**
65
+ * The session kept committing after its PR merged or closed (#1512): the branch holds commits
66
+ * on top of the PR's head, so the PR is not the answer to that work, which needs a pull request
67
+ * of its own.
68
+ */
69
+ movedPastPr?: boolean;
70
+ /**
71
+ * What a pull request for this branch would carry beyond the run's own work: the branch measured
72
+ * against the project's default branch, for a run started from another branch.
73
+ *
74
+ * A run started from a branch of this machine sits on that branch's unlanded commits, and its own
75
+ * work is measured from where it began ({@link base}) — which is the right count of what the run
76
+ * did. The pull request, though, goes to the default branch, so that branch's work rides along in
77
+ * it. Absent when a pull request would carry exactly what the run did, which is every run started
78
+ * from the branch the project starts agents from.
79
+ */
80
+ carries?: {
81
+ /** The branch a pull request would go to, as the branches provider names it. */
82
+ base: string;
83
+ commits: number;
84
+ files: number;
85
+ insertions: number;
86
+ deletions: number;
87
+ };
63
88
  /**
64
89
  * The files the session changed and never committed, read from its own checkout (#1173).
65
90
  *
@@ -93,6 +118,14 @@ export interface AgentHandoffDeps {
93
118
  order?: 'first' | 'latest';
94
119
  /** The commit the run's own work begins at ({@link AgentMeta.baseCommit}): what the branch is measured from. */
95
120
  from?: string;
121
+ /** How git is asked whether the branch holds commits on top of its PR's head (default the real one). */
122
+ git?: GitRunner;
123
+ /**
124
+ * When the run ended ({@link AgentMeta.endedAt}), so a pull request it opened on its way out is
125
+ * not missed: a cached answer read while the run still worked cannot know about one, and the bar
126
+ * would go on offering to open a request the branch already has. See {@link lookupAgentPr}.
127
+ */
128
+ endedAt?: string;
96
129
  }
97
130
  /**
98
131
  * The branch an agent's work is on: what was recorded while the checkout existed (#799/#1277).
@@ -118,6 +151,20 @@ export declare function leftNothing(agent: {
118
151
  pr?: unknown;
119
152
  landed?: string;
120
153
  }, host?: string): boolean;
154
+ /**
155
+ * Whether a cached pull request answer is from before the run ended, and so cannot have seen what
156
+ * the run did on its way out.
157
+ *
158
+ * A run told to publish its own work opens its pull request as it finishes. The lookup cached while
159
+ * it was still working says the branch has none, and that answer lives for a minute — long enough
160
+ * for the bar to offer "Open PR" for a branch that already has one, which is the single mistake
161
+ * that bar exists to prevent. An answer taken before the run's own end is thrown away rather than
162
+ * trusted; one taken after it has seen everything the run did.
163
+ *
164
+ * Nothing is thrown away for a run still going (no end to be older than), for an answer that was
165
+ * never read, or for a record whose end is not a date.
166
+ */
167
+ export declare function answeredBefore(at: number | undefined, endedAt: string | undefined): boolean;
121
168
  /** The cached single-PR read {@link resolveAgentPr} asks for the recorded PR's current state. */
122
169
  export type CachedBranchPrLookup = (cwd: string, branch?: string) => Promise<Cached<LinkedPr | undefined>>;
123
170
  /** What {@link resolveAgentPr} needs to know about an agent: structurally satisfied by {@link AgentMeta}. */
@@ -178,7 +225,7 @@ export declare function readAgentHandoff(cwd: string, branch: string, deps?: Age
178
225
  * record kept, and the answer says landed. A branch gone because the run changed nothing is said
179
226
  * as that, not as lost work. Undefined for a run with neither a branch nor a landed commit.
180
227
  */
181
- export declare function readRunHandoff(cwd: string, agent: Pick<AgentMeta, 'id' | 'startedAt' | 'branch' | 'baseCommit' | 'landed' | 'status' | 'host' | 'pr'>, deps?: AgentHandoffDeps): Promise<AgentHandoff | undefined>;
228
+ export declare function readRunHandoff(cwd: string, agent: Pick<AgentMeta, 'id' | 'startedAt' | 'endedAt' | 'branch' | 'baseCommit' | 'landed' | 'status' | 'host' | 'pr'>, deps?: AgentHandoffDeps): Promise<AgentHandoff | undefined>;
182
229
  /**
183
230
  * What a handoff action did. The PR's `number` rides along with its `url` (E6), because the number
184
231
  * is the fact worth *recording* — every surface that wants an agent's PR then reads it off the agent
@@ -23,6 +23,11 @@ export interface Cached<T> {
23
23
  value: T | undefined;
24
24
  /** True when no value is known yet and a read is still running. */
25
25
  pending: boolean;
26
+ /**
27
+ * When this value was read, for a caller that knows of something that happened since and cannot
28
+ * be in it — a pull request the run opened as it ended, say. Absent while nothing is known yet.
29
+ */
30
+ at?: number;
26
31
  }
27
32
  /** Clock seam, so the tests do not sleep. */
28
33
  export type Now = () => number;
@@ -1,9 +1,21 @@
1
1
  /** What a call says when the machine at the address shows another key than the one it was added with. */
2
2
  export declare const NOT_THE_MACHINE = "what answers at this address is not the machine that was added: add the machine again, with a new link";
3
+ /** How this computer says which one it is to a machine's door, with every call: the door lists it once by it. */
4
+ export declare const COMPUTER_HEADER = "x-openagent-computer";
5
+ /** Say which computer this is from here on, with every call to a machine. Set once, when OpenAgent starts. */
6
+ export declare function sayComputer(id: string | undefined): void;
7
+ /** The word OpenAgent was told to say, as the home file keeps it: what its own packages are handed, to say the same. */
8
+ export declare function computerSaid(): string | undefined;
9
+ /**
10
+ * The word this computer says to one machine's door, made from the word it keeps and that door's
11
+ * address: each door hears another word, so one that a machine learned says nothing at any other.
12
+ * A door's own package makes the same word for the line it keeps to that door.
13
+ */
14
+ export declare function computerWordFor(word: string, door: string): string;
3
15
  export interface MachineCall {
4
16
  method?: string;
5
17
  headers?: Record<string, string>;
6
18
  body?: string;
7
19
  signal?: AbortSignal;
8
20
  }
9
- export declare function machineFetch(url: string, pin: string | undefined, init?: MachineCall): Promise<Response>;
21
+ export declare function machineFetch(url: string, pin: string | undefined, call?: MachineCall): Promise<Response>;
@@ -58,6 +58,9 @@ export declare function remoteFacts(target: MachineAccess): Promise<{
58
58
  }>;
59
59
  /** The OpenAgent a saved machine runs, as its ping tells it; nothing for a machine that does not answer, or does not say. */
60
60
  export declare function remoteVersion(target: MachineAccess): Promise<string | undefined>;
61
+ /** A machine refused a call and said why: the message is the machine's own words, for the person to read. */
62
+ export declare class MachineRefusal extends Error {
63
+ }
61
64
  /** What asking to be let in came to: this computer's key there, or why not, in words. */
62
65
  export type EnterResult = {
63
66
  ok: true;
@@ -71,6 +74,12 @@ export type EnterResult = {
71
74
  * is good once: a link used before, or older than a few minutes, is refused.
72
75
  */
73
76
  export declare function enterRemote(door: string, code: string, name: string, pin?: string): Promise<EnterResult>;
77
+ /**
78
+ * The id a machine lists this computer under, among the devices that are in there: a door hands
79
+ * out a key as that id, a dot, and the secret. Never the secret; `undefined` for a key of
80
+ * another shape, so nothing of one is ever taken for an id.
81
+ */
82
+ export declare function deviceIdOf(key: string): string | undefined;
74
83
  /**
75
84
  * Take this computer out of a machine: its key there stops working. Whether the machine did;
76
85
  * one that cannot be reached keeps the key until this computer is removed there by hand.
@@ -121,7 +130,8 @@ export interface BringProject {
121
130
  * holds this computer's key there, so a read/diff/handoff/push/PR for a relayed agent runs ON the machine: POST
122
131
  * {fn, args} to the remote's /_relay/rpc with the key (no Origin), returning the machine's
123
132
  * result. Throws on an unreachable machine or a non-2xx so the caller falls back to its own empty/error
124
- * shape, the same way a failed local read does.
133
+ * shape, the same way a failed local read does. A refusal the machine gave a reason for is thrown
134
+ * as a {@link MachineRefusal}, so the reason can be shown in place of that shape's own words.
125
135
  */
126
136
  export declare function relayRpc(target: RemoteTarget, fn: string, args: unknown[]): Promise<unknown>;
127
137
  /**
@@ -18,6 +18,11 @@ export type RemoveProjectHandler = (projectId: string, files: boolean) => Remove
18
18
  * rather than a file on disk (#426), and the daemon feeds an agent it is relaying from a machine (#1067).
19
19
  * Returns undefined when there is no in-memory stream, so `onEvents` falls back to tailing the log. */
20
20
  export type EventsSource = (projectId: string, agentId?: string) => AsyncIterable<OpenAgentEvent> | undefined;
21
+ /** A saved machine as a run's row needs it: the name it was given, and its address. */
22
+ export interface SavedMachine {
23
+ label: string;
24
+ url: string;
25
+ }
21
26
  /** Look up the machine a relayed agent (#1067) executes on, or undefined for an ordinary local agent. The
22
27
  * daemon wires this from its live relayed-agent map; a run-scoped RPC uses it to forward a remote agent's
23
28
  * read/steer/handoff to that machine instead of resolving a (nonexistent) local checkout. */
@@ -42,10 +47,10 @@ export interface RemoteAgents {
42
47
  /** Follow a run that runs on a saved machine, when it is not followed yet: its events then stream here, as for a run this computer sent. */
43
48
  follow(projectId: string, agentId: string): Promise<void>;
44
49
  /**
45
- * The name a saved machine was given, by its computer's own name, as the records of its runs
46
- * carry it: asked of the machines first, when one has not said its name yet.
50
+ * The saved machine, by its computer's own name, as the records of its runs carry it: the name
51
+ * it was given and its address. Asked of the machines first, when one has not said its name yet.
47
52
  */
48
- machineNames(): Promise<(host: string) => string | undefined>;
53
+ machineNames(): Promise<(host: string) => SavedMachine | undefined>;
49
54
  }
50
55
  /**
51
56
  * What every RPC acts through.
@@ -71,6 +71,8 @@ export interface OnboardingSuggestion {
71
71
  export interface StartAgentOptions {
72
72
  /** The model to run on. */
73
73
  model?: string;
74
+ /** How hard that model may think, by the coding agent's own names (`medium`, `high`, …): what the model lists as its efforts. */
75
+ effort?: string;
74
76
  /** Which coding agent the run is on: `claude-code` or `codex`. */
75
77
  driver?: string;
76
78
  /** The person's saved pick of how far the run takes its work when the agent finishes. Absent, none is saved: the daemon starts the run at `commit`. A saved pick the project is not offered is held to the furthest the project goes with no pull request. */
@@ -39,14 +39,17 @@ export declare function onMachinesReachable(): Promise<Record<string, boolean>>;
39
39
  export interface MachineVersions {
40
40
  /** This computer's own. */
41
41
  version: string;
42
- /** Each saved machine, with its version when it answers and says. */
42
+ /** Each saved machine, with its version when it answers and says, and the id it lists this computer under among its devices. */
43
43
  machines: (Machine & {
44
44
  version?: string;
45
+ device?: string;
45
46
  })[];
46
47
  }
47
48
  /**
48
49
  * The saved machines with the OpenAgent each runs, beside this computer's own: how a page tells
49
50
  * that a machine fell behind this computer. One short call to each, with this computer's key.
51
+ * The key itself is never told: only the id the machine lists this computer under, which a page
52
+ * that lists the machine's devices names this computer by.
50
53
  */
51
54
  export declare function onMachineVersions(): Promise<MachineVersions>;
52
55
  /** Whether a saved machine has a project of this computer's: `there` is false while the machine clones it. */
@@ -16,6 +16,7 @@ import type { AgentWorktree } from '../dashboard/types.js';
16
16
  import type { OpenAgentEvent } from '../events.js';
17
17
  import type { BridgeEvent, BridgeHello, BridgeQuestion } from '../dashboard/bridge-endpoints.js';
18
18
  import type { BridgeAnswer, BridgeContact, BridgeVersion } from '../dashboard/bridge-store.js';
19
+ import type { SavedMachine } from '../dashboard/rpc-serve.js';
19
20
  /**
20
21
  * The project's runs, most-recent first (or `[]`). The archived (finished) runs
21
22
  * from `agents/`, plus every live agent prepended — so the sidebar shows an in-progress
@@ -59,6 +60,11 @@ export declare function markCloudWaiting(agent: AgentMeta): AgentMeta;
59
60
  * with no recorded host predates the field and passes through untouched.
60
61
  */
61
62
  export declare function markOtherHost(agent: AgentMeta, thisHost?: string): AgentMeta;
63
+ /**
64
+ * What a run's row says of the saved machine it runs on: the name the machine was given, and
65
+ * that it is a person's own computer reached by its line, when it is one.
66
+ */
67
+ export declare function onMachine(machine: SavedMachine): Pick<AgentMeta, 'remoteLabel' | 'remoteByLine'>;
62
68
  /**
63
69
  * A run whose record names the computer of a saved machine runs on that machine, whoever started
64
70
  * it there, and reads like one this computer sent: by the name the machine was given. The record
@@ -66,7 +72,7 @@ export declare function markOtherHost(agent: AgentMeta, thisHost?: string): Agen
66
72
  * own page too, and after this daemon forgot the runs it sent. A run of this computer, and one of
67
73
  * a computer that is no saved machine, pass through untouched.
68
74
  */
69
- export declare function markMachine(agent: AgentMeta, machineOf: (host: string) => string | undefined, thisHost?: string): AgentMeta;
75
+ export declare function markMachine(agent: AgentMeta, machineOf: (host: string) => SavedMachine | undefined, thisHost?: string): AgentMeta;
70
76
  /**
71
77
  * A run that ended clean while the process its card names is still alive on this host is marked
72
78
  * saving: the tool that runs it saves the run's record and cleans up its checkout after the card says
@@ -137,7 +143,7 @@ export declare function onDashboard(): Promise<DashboardData>;
137
143
  * file git sees (tracked + untracked, honoring .gitignore), repo-relative and sorted, via
138
144
  * `git ls-files`. Localhost-only by nature — the relay has no checkout, so it resolves `[]`.
139
145
  * Pass a live `agentId` to list that agent's worktree instead of the project root (#738). The
140
- * Files tab reads its own list, through its module.
146
+ * Files pane reads its own list, through its module.
141
147
  */
142
148
  export declare function onProjectFiles(projectId: string, agentId?: string): Promise<string[]>;
143
149
  /** The project's page on its git host and the git host's name (#489, #1820), or null: no git host package, no remote there, or the relay. */
@@ -9,6 +9,7 @@ export declare function asArrived<T>(call: () => Promise<T>): Promise<T>;
9
9
  * knows nothing of the run, a read
10
10
  * is answered from what this computer holds of the run, its record when it has one, and
11
11
  * anything that would change the run answers `unreachable`: it is never done here in the
12
- * machine's place.
12
+ * machine's place. A machine that refused and said why (one that only lets its server watch) is
13
+ * answered in its own words, where `unreachable` has words of its own to replace.
13
14
  */
14
15
  export declare function relayOr<T>(agentId: string | undefined, fn: string, args: unknown[], local: () => Promise<T>, unreachable: T): Promise<T>;
@@ -96,6 +96,15 @@ export type OpenAgentEvent = {
96
96
  kind: 'intent';
97
97
  text: string;
98
98
  }
99
+ /**
100
+ * The short name the session was given, emitted once, soon after it opens: a small model's two
101
+ * to five words for what the person asked, which is what every list of sessions shows instead of
102
+ * the prompt's first line.
103
+ */
104
+ | {
105
+ kind: 'title';
106
+ text: string;
107
+ }
99
108
  /** The wrapped agent's own progress, forwarded verbatim (never gated on). */
100
109
  | {
101
110
  kind: 'driver';
@@ -103,9 +112,11 @@ export type OpenAgentEvent = {
103
112
  }
104
113
  /**
105
114
  * A live screen something the agent ran is showing: where it answers, on the loopback of the
106
- * computer the run is on, live while it is the newest open screen at that address and the run
107
- * has not ended. `label` names what it showed then. The same address with `ended` says the
108
- * screen has gone. A diary line a command appends itself (agent-driver's `DIARY_ENV`);
115
+ * computer the run is on, live while it is the newest open screen at that address. `label`
116
+ * names what it showed then. The same address with `ended` says the screen has gone, and with
117
+ * `until` that it outlives the run, up to that time: a screen is a browser the person looks at
118
+ * and clicks in, which the run ending does not take from them. Both of those are rows a reader
119
+ * shows nothing for. A diary line a command appends itself (agent-driver's `DIARY_ENV`);
109
120
  * OpenAgent passes a watcher's calls on to the address (dashboard/screen.ts) and knows nothing
110
121
  * of what the screen is.
111
122
  */
@@ -114,6 +125,7 @@ export type OpenAgentEvent = {
114
125
  url: string;
115
126
  label: string;
116
127
  ended?: true;
128
+ until?: string;
117
129
  }
118
130
  /** An OpenAgent-level log line. */
119
131
  | {
@@ -135,18 +147,6 @@ export type OpenAgentEvent = {
135
147
  headline: string;
136
148
  detail?: string;
137
149
  }
138
- /**
139
- * An ad-hoc markdown view the agent pushed to show the user (#441), e.g. a plan,
140
- * a summary, or a diff writeup. Non-blocking (unlike a `choice`): the dashboard
141
- * renders it as a view in the right rail. `id` is stable per title, so re-showing
142
- * the same view updates it in place rather than stacking a duplicate.
143
- */
144
- | {
145
- kind: 'view';
146
- id: string;
147
- title: string;
148
- markdown: string;
149
- }
150
150
  /**
151
151
  * The pull request this session's work is on (E6), the moment one is opened for it.
152
152
  *