@openagt/dashboard 0.37.0 → 0.38.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 (158) hide show
  1. package/dist/client.d.ts +1 -0
  2. package/dist/client.d.ts.map +1 -1
  3. package/dist/client.js +1 -0
  4. package/dist/client.js.map +1 -1
  5. package/dist/computer-name.d.ts +3 -0
  6. package/dist/computer-name.d.ts.map +1 -0
  7. package/dist/computer-name.js +6 -0
  8. package/dist/computer-name.js.map +1 -0
  9. package/dist/daemon-runtime.d.ts.map +1 -1
  10. package/dist/daemon-runtime.js +37 -6
  11. package/dist/daemon-runtime.js.map +1 -1
  12. package/dist/daemon.d.ts.map +1 -1
  13. package/dist/daemon.js +4 -0
  14. package/dist/daemon.js.map +1 -1
  15. package/dist/dashboard/compress.d.ts +11 -0
  16. package/dist/dashboard/compress.d.ts.map +1 -0
  17. package/dist/dashboard/compress.js +40 -0
  18. package/dist/dashboard/compress.js.map +1 -0
  19. package/dist/dashboard/copied-logins.d.ts +54 -0
  20. package/dist/dashboard/copied-logins.d.ts.map +1 -0
  21. package/dist/dashboard/copied-logins.js +60 -0
  22. package/dist/dashboard/copied-logins.js.map +1 -0
  23. package/dist/dashboard/copy-logins.d.ts +5 -1
  24. package/dist/dashboard/copy-logins.d.ts.map +1 -1
  25. package/dist/dashboard/copy-logins.js +9 -3
  26. package/dist/dashboard/copy-logins.js.map +1 -1
  27. package/dist/dashboard/git-hosts.d.ts +2 -0
  28. package/dist/dashboard/git-hosts.d.ts.map +1 -1
  29. package/dist/dashboard/git-hosts.js +1 -1
  30. package/dist/dashboard/git-hosts.js.map +1 -1
  31. package/dist/dashboard/logins-sync.d.ts +146 -0
  32. package/dist/dashboard/logins-sync.d.ts.map +1 -0
  33. package/dist/dashboard/logins-sync.js +344 -0
  34. package/dist/dashboard/logins-sync.js.map +1 -0
  35. package/dist/dashboard/machine-runs.d.ts +78 -0
  36. package/dist/dashboard/machine-runs.d.ts.map +1 -0
  37. package/dist/dashboard/machine-runs.js +154 -0
  38. package/dist/dashboard/machine-runs.js.map +1 -0
  39. package/dist/dashboard/relay-endpoints.d.ts.map +1 -1
  40. package/dist/dashboard/relay-endpoints.js +5 -2
  41. package/dist/dashboard/relay-endpoints.js.map +1 -1
  42. package/dist/dashboard/remote-run.d.ts +17 -3
  43. package/dist/dashboard/remote-run.d.ts.map +1 -1
  44. package/dist/dashboard/remote-run.js +31 -5
  45. package/dist/dashboard/remote-run.js.map +1 -1
  46. package/dist/dashboard/rpc-serve.d.ts +3 -0
  47. package/dist/dashboard/rpc-serve.d.ts.map +1 -1
  48. package/dist/dashboard/rpc-serve.js +8 -9
  49. package/dist/dashboard/rpc-serve.js.map +1 -1
  50. package/dist/dashboard/static.d.ts.map +1 -1
  51. package/dist/dashboard/static.js +4 -2
  52. package/dist/dashboard/static.js.map +1 -1
  53. package/dist/dashboard-bundle/assets/main-BrPlt--h.js +149 -0
  54. package/dist/dashboard-bundle/assets/main-DgwPb5zO.css +2 -0
  55. package/dist/dashboard-bundle/assets/module-D0SUS0dF.js +14 -0
  56. package/dist/dashboard-bundle/host/module.js +1 -1
  57. package/dist/dashboard-bundle/index.html +5 -4
  58. package/dist/dashboard-rpc/accounts.d.ts +17 -1
  59. package/dist/dashboard-rpc/accounts.d.ts.map +1 -1
  60. package/dist/dashboard-rpc/accounts.js +46 -8
  61. package/dist/dashboard-rpc/accounts.js.map +1 -1
  62. package/dist/dashboard-rpc/context.js +1 -1
  63. package/dist/dashboard-rpc/context.js.map +1 -1
  64. package/dist/dashboard-rpc/copied-logins.d.ts +49 -0
  65. package/dist/dashboard-rpc/copied-logins.d.ts.map +1 -0
  66. package/dist/dashboard-rpc/copied-logins.js +179 -0
  67. package/dist/dashboard-rpc/copied-logins.js.map +1 -0
  68. package/dist/dashboard-rpc/index.d.ts +4 -1
  69. package/dist/dashboard-rpc/index.d.ts.map +1 -1
  70. package/dist/dashboard-rpc/index.js +8 -2
  71. package/dist/dashboard-rpc/index.js.map +1 -1
  72. package/dist/dashboard-rpc/logins.d.ts +18 -0
  73. package/dist/dashboard-rpc/logins.d.ts.map +1 -1
  74. package/dist/dashboard-rpc/logins.js +51 -7
  75. package/dist/dashboard-rpc/logins.js.map +1 -1
  76. package/dist/dashboard-rpc/machines.d.ts +7 -2
  77. package/dist/dashboard-rpc/machines.d.ts.map +1 -1
  78. package/dist/dashboard-rpc/machines.js +7 -5
  79. package/dist/dashboard-rpc/machines.js.map +1 -1
  80. package/dist/dashboard-rpc/people.d.ts +16 -0
  81. package/dist/dashboard-rpc/people.d.ts.map +1 -0
  82. package/dist/dashboard-rpc/people.js +32 -0
  83. package/dist/dashboard-rpc/people.js.map +1 -0
  84. package/dist/dashboard-rpc/reads.d.ts +20 -1
  85. package/dist/dashboard-rpc/reads.d.ts.map +1 -1
  86. package/dist/dashboard-rpc/reads.js +74 -8
  87. package/dist/dashboard-rpc/reads.js.map +1 -1
  88. package/dist/dashboard-rpc/relay-dispatch.js +2 -2
  89. package/dist/dashboard-rpc/relay-dispatch.js.map +1 -1
  90. package/dist/dashboard-rpc/server-logins.d.ts +22 -0
  91. package/dist/dashboard-rpc/server-logins.d.ts.map +1 -0
  92. package/dist/dashboard-rpc/server-logins.js +26 -0
  93. package/dist/dashboard-rpc/server-logins.js.map +1 -0
  94. package/dist/dashboard-rpc/test-context.js +1 -1
  95. package/dist/dashboard-rpc/test-context.js.map +1 -1
  96. package/dist/health.d.ts +20 -0
  97. package/dist/health.d.ts.map +1 -0
  98. package/dist/health.js +98 -0
  99. package/dist/health.js.map +1 -0
  100. package/dist/index.d.ts +1 -0
  101. package/dist/index.d.ts.map +1 -1
  102. package/dist/module-types/dashboard/components/FilterChips.d.ts +12 -0
  103. package/dist/module-types/dashboard/components/Page.d.ts +12 -0
  104. package/dist/module-types/dashboard/components/SidebarToggle.d.ts +4 -0
  105. package/dist/module-types/dashboard/components/StatTile.d.ts +15 -0
  106. package/dist/module-types/dashboard/components/ui/sheet.d.ts +10 -0
  107. package/dist/module-types/dashboard/components/ui/sidebar.d.ts +71 -0
  108. package/dist/module-types/dashboard/lib/use-mobile.d.ts +4 -0
  109. package/dist/module-types/dashboard/lib/use-modules.d.ts +3 -1
  110. package/dist/module-types/dashboard/module/index.d.ts +51 -1
  111. package/dist/module-types/src/client.d.ts +1 -0
  112. package/dist/module-types/src/computer-name.d.ts +2 -0
  113. package/dist/module-types/src/dashboard/compress.d.ts +10 -0
  114. package/dist/module-types/src/dashboard/copied-logins.d.ts +53 -0
  115. package/dist/module-types/src/dashboard/git-hosts.d.ts +2 -0
  116. package/dist/module-types/src/dashboard/logins-sync.d.ts +145 -0
  117. package/dist/module-types/src/dashboard/machine-runs.d.ts +77 -0
  118. package/dist/module-types/src/dashboard/remote-run.d.ts +17 -3
  119. package/dist/module-types/src/dashboard/rpc-serve.d.ts +3 -0
  120. package/dist/module-types/src/dashboard-rpc/accounts.d.ts +17 -1
  121. package/dist/module-types/src/dashboard-rpc/copied-logins.d.ts +48 -0
  122. package/dist/module-types/src/dashboard-rpc/index.d.ts +4 -1
  123. package/dist/module-types/src/dashboard-rpc/logins.d.ts +18 -0
  124. package/dist/module-types/src/dashboard-rpc/machines.d.ts +7 -2
  125. package/dist/module-types/src/dashboard-rpc/people.d.ts +15 -0
  126. package/dist/module-types/src/dashboard-rpc/reads.d.ts +20 -1
  127. package/dist/module-types/src/dashboard-rpc/server-logins.d.ts +21 -0
  128. package/dist/module-types/src/health.d.ts +19 -0
  129. package/dist/module-types/src/index.d.ts +1 -0
  130. package/dist/module-types/src/overview-layout.d.ts +37 -0
  131. package/dist/module-types/src/registry.d.ts +14 -0
  132. package/dist/module-types/src/store/agent-store.d.ts +15 -1
  133. package/dist/module-types/src/store/git-host.d.ts +6 -0
  134. package/dist/module-types/src/store/runs.d.ts +3 -1
  135. package/dist/module.css +1 -1
  136. package/dist/overview-layout.d.ts +38 -0
  137. package/dist/overview-layout.d.ts.map +1 -0
  138. package/dist/overview-layout.js +61 -0
  139. package/dist/overview-layout.js.map +1 -0
  140. package/dist/registry.d.ts +14 -0
  141. package/dist/registry.d.ts.map +1 -1
  142. package/dist/registry.js +31 -2
  143. package/dist/registry.js.map +1 -1
  144. package/dist/store/agent-store.d.ts +15 -1
  145. package/dist/store/agent-store.d.ts.map +1 -1
  146. package/dist/store/agent-store.js.map +1 -1
  147. package/dist/store/git-host.d.ts +6 -0
  148. package/dist/store/git-host.d.ts.map +1 -1
  149. package/dist/store/git-host.js +14 -0
  150. package/dist/store/git-host.js.map +1 -1
  151. package/dist/store/runs.d.ts +3 -1
  152. package/dist/store/runs.d.ts.map +1 -1
  153. package/dist/store/runs.js +1 -1
  154. package/dist/store/runs.js.map +1 -1
  155. package/package.json +24 -24
  156. package/dist/dashboard-bundle/assets/main-B_YIbzfX.js +0 -148
  157. package/dist/dashboard-bundle/assets/main-COZtHuZ-.css +0 -2
  158. package/dist/dashboard-bundle/assets/module-B_KMN8r0.js +0 -14
@@ -10,10 +10,12 @@ export interface MountedLinkAction extends LinkAction {
10
10
  package: string;
11
11
  projects: string[];
12
12
  }
13
- /** A card as the shell mounts it (#1818): the card, plus the package it came from and the projects that have it. */
13
+ /** A card as the shell mounts it (#1818): the card, plus the package it came from, the projects that have it, and whether it is the computer's. */
14
14
  export interface MountedCard extends ModuleCard {
15
15
  package: string;
16
16
  projects: string[];
17
+ /** A package of this computer's (its devices): the card is on every Overview, whichever project is picked. */
18
+ computer: boolean;
17
19
  }
18
20
  /** A pane as the shell mounts it: the pane, plus the package it came from and the projects that have it. */
19
21
  export interface MountedPanel extends ModulePanel {
@@ -1,7 +1,9 @@
1
+ import type { Health } from '../../src/health.js';
2
+ import type { CardWidth } from '../../src/overview-layout.js';
1
3
  import { type ComponentType } from 'react';
2
4
  import type { AgentStatus } from '../../src/index.js';
3
5
  import type { ModuleCommandResult, ModuleReadResult } from '../rpc/modules.js';
4
- export type { ModuleCommandResult, ModuleReadResult, AgentStatus };
6
+ export type { ModuleCommandResult, ModuleReadResult, AgentStatus, CardWidth, Health };
5
7
  /** A registered project that has the module's package, as a page gets it. */
6
8
  export interface ModuleProject {
7
9
  id: string;
@@ -113,6 +115,12 @@ export interface ModuleCardProps {
113
115
  export interface ModuleCard {
114
116
  /** Which card this is, for the shell's key and its error line; never shown as a title. */
115
117
  id: string;
118
+ /** Its name where the person arranges the Overview's cards: what its title says ("Hot tickets"). */
119
+ label: string;
120
+ /** How wide it stands until the person picks: half the Overview when unsaid. */
121
+ width?: CardWidth;
122
+ /** The narrowest it fits: a third of the Overview when unsaid. */
123
+ minWidth?: CardWidth;
116
124
  /** Its place among every installed package's cards, lower first; 50 when unsaid, ties by package name. */
117
125
  order?: number;
118
126
  /** The card itself. */
@@ -302,9 +310,25 @@ export interface ModuleAgent {
302
310
  name?: string;
303
311
  /** What the run was asked, as typed or as queued; absent when its record carries none. */
304
312
  ask?: string;
313
+ /** How it stands: `unknown` while the computer it runs on does not answer, whatever its record last said. */
305
314
  status: AgentStatus;
306
315
  /** ISO 8601. */
307
316
  startedAt: string;
317
+ /** ISO 8601, once it ended. */
318
+ endedAt?: string;
319
+ /** Its short name, as a list of runs shows it. */
320
+ title?: string;
321
+ /** Whose run it is, by the email its record is kept under. */
322
+ person?: string;
323
+ /** What it cost so far, in US dollars. */
324
+ cost?: number;
325
+ /** The coding agent that runs it (`claude-code`, `codex`, …) and its model. */
326
+ driver?: string;
327
+ model?: string;
328
+ /** The saved machine it runs on, by the name it was given; absent for a run of this computer's. */
329
+ machine?: string;
330
+ /** While its status is `unknown`: when its computer was last seen, ISO, if it was. */
331
+ seenAt?: string;
308
332
  }
309
333
  /** What starting a run answered: the run's id, or in words why there is none. */
310
334
  export type StartRunResult = {
@@ -362,6 +386,13 @@ export interface ModuleHost {
362
386
  openPage(segment: string, path?: string[], projectId?: string): void;
363
387
  /** The address of a page a module adds, with the project picked in the dashboard: a link's `href`, for a link that also opens in a new tab. */
364
388
  pageHref(segment: string): string;
389
+ /** Open an entry of Settings over the page, by its id: `openSettings('devices')`. */
390
+ openSettings(entry: string): void;
391
+ /**
392
+ * The accounts behind a project's commit emails at its git host, each with its login and picture:
393
+ * an email the host knows nobody for, or a project with no git host, is left out. Kept a day.
394
+ */
395
+ gitHostPeople(projectId: string, emails: string[]): Promise<ModuleHostPerson[]>;
365
396
  /**
366
397
  * Start a run in one project with this prompt, with the person's own picks (which tool, which
367
398
  * model, where it runs), and land on it, unless `land` is false: then the dashboard stays where
@@ -415,6 +446,11 @@ export interface ModuleHost {
415
446
  * it said is another computer's data, to read as such; `unknown` for a machine that does not say.
416
447
  */
417
448
  machinePerson(machineId: string): Promise<ModuleMachinePerson>;
449
+ /**
450
+ * A saved server of the person's uses this computer's logins from now on: each account this
451
+ * computer is logged in to gets a login of the server's own there, as Settings › Accounts says.
452
+ */
453
+ useLoginsOn(machineId: string): Promise<MachineAdded>;
418
454
  /** Take one of that person's devices out at the machine, by its id there; answers as {@link machinePerson} does, after. */
419
455
  removeMachineDevice(machineId: string, deviceId: string): Promise<ModuleMachinePerson>;
420
456
  /**
@@ -426,6 +462,13 @@ export interface ModuleHost {
426
462
  /** Send the live screen of a run what the person did on it, as JSON; whether the screen took it. */
427
463
  sendToScreen(projectId: string, agentId: string, input: unknown): Promise<boolean>;
428
464
  }
465
+ /** A person of a project, as its git host knows them. */
466
+ export interface ModuleHostPerson {
467
+ email: string;
468
+ login: string;
469
+ /** A picture of them: an https address. */
470
+ avatar?: string;
471
+ }
429
472
  /** A saved machine, as a module sees it: never this computer's key there. */
430
473
  export interface ModuleMachine {
431
474
  /** Where the machine answers, as an origin (`https://203.0.113.5`): what it is known by. */
@@ -434,6 +477,8 @@ export interface ModuleMachine {
434
477
  url: string;
435
478
  /** The OpenAgent it runs; absent for a machine that does not answer right now. */
436
479
  version?: string;
480
+ /** How it stands, as it says: its memory, disk and load; absent for one that does not answer, or does not say. */
481
+ health?: Health;
437
482
  /** The id the machine lists this computer under, among the devices that are in there. */
438
483
  device?: string;
439
484
  /** Whose computer it is, by their GitHub account, when it is another person's shared with everyone on a server. */
@@ -450,6 +495,8 @@ export interface ModuleMachines {
450
495
  version: string;
451
496
  /** This computer's own name, as another machine lists it: "Suleimans-MacBook-Pro". */
452
497
  name?: string;
498
+ /** How this computer stands: its memory, disk and load. */
499
+ health?: Health;
453
500
  machines: ModuleMachine[];
454
501
  }
455
502
  /** How saving a machine went: done, or stopped, with the reason. */
@@ -547,6 +594,9 @@ export { Tooltip, TooltipTrigger, TooltipContent } from '../components/ui/toolti
547
594
  export { DropdownMenu, DropdownMenuContent, DropdownMenuCheckboxItem, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger } from '../components/ui/dropdown-menu.js';
548
595
  export { ContextMenu, ContextMenuTrigger } from '../components/ui/context-menu.js';
549
596
  export { PaneTitle, PaneActions } from '../components/PaneHeader.js';
597
+ export { Page } from '../components/Page.js';
598
+ export { StatTile } from '../components/StatTile.js';
599
+ export { FilterChips, type FilterChip } from '../components/FilterChips.js';
550
600
  export { FileIcon } from '../components/FileIcon.js';
551
601
  export { Markdown } from '../components/Markdown.js';
552
602
  export { StartAgentButton } from '../components/StartAgentButton.js';
@@ -17,3 +17,4 @@ export { reachedByLine } from './reached-by-line.js';
17
17
  export { isLoopbackHost } from './loopback-host.js';
18
18
  export { bridgeChoiceRequest } from './dashboard/bridge-question.js';
19
19
  export { cloudRunState, cloudRunActive, CLOUD_SESSION_WINDOW_MS, type CloudRunState } from './cloud-run-state.js';
20
+ export { ALL_PROJECTS, CARD_WIDTHS, arrangeCards, widthsFor, type CardPlace, type CardWidth, type LayoutCard, type OverviewLayouts } from './overview-layout.js';
@@ -0,0 +1,2 @@
1
+ /** This computer's name as a person knows it: its host name, without the `.local` a Mac adds on its network. */
2
+ export declare function computerName(): string;
@@ -0,0 +1,10 @@
1
+ import type { IncomingMessage, OutgoingHttpHeaders, ServerResponse } from 'node:http';
2
+ /** Whether the caller takes a gzipped answer: every browser says so. */
3
+ export declare function takesGzip(req: IncomingMessage): boolean;
4
+ /** The types worth packing: text. A picture or a font is packed already. */
5
+ export declare function isText(contentType: string): boolean;
6
+ /**
7
+ * Send `body`, gzipped when the caller takes it, it is text and not small. `key` names a body that
8
+ * is the same each time it is sent (a file of the page), so it is packed once.
9
+ */
10
+ export declare function sendBody(req: IncomingMessage, res: ServerResponse, status: number, headers: OutgoingHttpHeaders, body: Buffer | string, key?: string): Promise<void>;
@@ -0,0 +1,53 @@
1
+ /** One of an account's usage windows, as a page names it: `5 h`, `week`, `month`, and how much of it is gone. */
2
+ export interface UsageWindow {
3
+ label: string;
4
+ percent: number;
5
+ }
6
+ /** What a copied login is a login of: a coding agent's account, or a git host's. */
7
+ export type CopiedKind = 'claude' | 'codex' | 'git';
8
+ /** One login a computer of the person's handed over, as this server keeps it: never the login itself. */
9
+ export interface CopiedLogin {
10
+ kind: CopiedKind;
11
+ /** A git host's account: the host. */
12
+ host?: string;
13
+ /** Which of the computer's accounts it is: `own` for its own login, else the account's name there, or its login at the git host. */
14
+ source: string;
15
+ /** The name of its row here. */
16
+ name: string;
17
+ /** Who the account is, as the computer said when it handed it over: a switch to another account says another. */
18
+ who: string;
19
+ /** The computer it came from, by its name. */
20
+ from: string;
21
+ /** The computer no longer has it, and the person said to keep it here. */
22
+ kept?: true;
23
+ /** A git host's account the computer's runs use: the server's do too. */
24
+ runs?: true;
25
+ /** How full it is, as the computer last read it. */
26
+ usage?: {
27
+ windows: UsageWindow[];
28
+ at: number;
29
+ };
30
+ }
31
+ /** A login handed over: what it is, and the login itself, which goes where its tool reads it. */
32
+ export interface GivenLogin {
33
+ kind: CopiedKind;
34
+ host?: string;
35
+ source: string;
36
+ name: string;
37
+ who: string;
38
+ from: string;
39
+ runs?: boolean;
40
+ }
41
+ /** Where the file is: beside OpenAgent's other files in the person's config folder. */
42
+ export declare function copiedPath(env?: NodeJS.ProcessEnv): string;
43
+ export declare const isKind: (value: unknown) => value is CopiedKind;
44
+ /** A word a computer said: a name, an account, a host. Never long, never a line break. */
45
+ export declare const isWord: (value: unknown, max?: number) => value is string;
46
+ export declare function readUsage(value: unknown): CopiedLogin['usage'] | undefined;
47
+ /** The logins this server keeps from the person's computers. Forgiving: none on a file that does not read. */
48
+ export declare function readCopied(): CopiedLogin[];
49
+ export declare function writeCopied(logins: CopiedLogin[]): void;
50
+ /** The same login of the same computer: its kind, its host, and which of the computer's accounts it is. */
51
+ export declare const same: (a: Pick<CopiedLogin, 'kind' | 'host' | 'source'>, b: Pick<CopiedLogin, 'kind' | 'host' | 'source'>) => boolean;
52
+ /** The copied login of an account row here, by its kind and its name. */
53
+ export declare function copiedOf(kind: CopiedKind, name: string, host?: string): CopiedLogin | undefined;
@@ -7,6 +7,8 @@ export interface GitHostAccount {
7
7
  runs: boolean;
8
8
  /** Whether the tool could use it when asked. */
9
9
  ok: boolean;
10
+ /** On a server: the computer of the person's whose login it is. */
11
+ from?: string;
10
12
  }
11
13
  /** What a git host's package answers of it. */
12
14
  export interface GitHostProvider {
@@ -0,0 +1,145 @@
1
+ import { type Mint } from '@openagt/agent-driver-claude';
2
+ import { type CodexLogin, type CodexLoginOptions } from '@openagt/agent-driver-codex';
3
+ import { type MachineRecord, type Preferences } from '../registry.js';
4
+ import { type MachineAccess } from './remote-run.js';
5
+ import { type CopiedKind, type UsageWindow } from './copied-logins.js';
6
+ /**
7
+ * A computer's side of a server that uses its logins (`copied-logins.ts` is the server's side).
8
+ * Once the person said so for a server of their own, this computer keeps the server's logins as
9
+ * its own: every account it is logged in to, a coding agent's or a git host's, gets a login of the
10
+ * server's own there, and a login that changes here changes there.
11
+ *
12
+ * A login is never shared by both: each computer renews its own, and a login renewed on one
13
+ * computer would log the other one out. What can go as it is goes as it is, with nothing to
14
+ * press: a git host's token, which its host never renews, and a Claude account added here, which
15
+ * is a login made for a computer nobody sits at already. What cannot is made anew for the server,
16
+ * in this computer's browser, with one press of the person's: their own Claude login (Claude
17
+ * Code's `setup-token`), and any Codex account (a sign-in of its own). Nothing here is logged out.
18
+ *
19
+ * What the person no longer has here stays there until they say: kept, or taken off. A login
20
+ * taken off there is deleted there and ends nothing.
21
+ *
22
+ * The person's settings follow the same way: what they change here is changed there, the next
23
+ * minute. A setting changed on the server's own page stays, until the same one changes here.
24
+ */
25
+ /** One of this computer's accounts, as a server gets it. */
26
+ export interface LocalLogin {
27
+ kind: CopiedKind;
28
+ host?: string;
29
+ /** Which account it is here: `own` for the agent's own login, else its name here, or its login at the git host. */
30
+ source: string;
31
+ name: string;
32
+ /** Who the account is: another one under the same `source` is a switch. */
33
+ who: string;
34
+ /** A git host's account this computer's runs use. */
35
+ runs?: boolean;
36
+ /** The login as it is, for one that can go as it is; none for one made anew for the server. */
37
+ secret?: () => Promise<string>;
38
+ }
39
+ /** How one of this computer's accounts stands on a server. */
40
+ export interface LoginThere {
41
+ kind: CopiedKind;
42
+ host?: string;
43
+ source: string;
44
+ name: string;
45
+ /**
46
+ * `there`: the server has it. `allow`: it waits for the person's press, which makes the server a
47
+ * login of its own. `switched`: the server has another account of this one's, which the
48
+ * person no longer is here: the press makes this one's. `failed`: it did not get there.
49
+ */
50
+ state: 'there' | 'allow' | 'switched' | 'failed';
51
+ /** `switched`: the account the server has. */
52
+ was?: string;
53
+ error?: string;
54
+ }
55
+ /** One of this computer's servers, and how its logins stand there. */
56
+ export interface ServerLogins {
57
+ machineId: string;
58
+ label: string;
59
+ /** The person said the server uses this computer's logins. */
60
+ on: boolean;
61
+ /** It answered when last asked. */
62
+ reachable: boolean;
63
+ logins: LoginThere[];
64
+ /** What the server has of this computer's that this computer no longer has: the person keeps it there, or takes it off. */
65
+ left: {
66
+ kind: CopiedKind;
67
+ host?: string;
68
+ source: string;
69
+ name: string;
70
+ }[];
71
+ /** The press under way: the login being made, and the page it signs in at. */
72
+ allowing?: {
73
+ name: string;
74
+ url?: string;
75
+ };
76
+ /** Why the last press stopped. */
77
+ failed?: string;
78
+ }
79
+ /** What the sync reaches for, swapped in tests. */
80
+ export declare const syncWiring: {
81
+ /** The environment the daemon was started with: whose saved machines, whose logins. */
82
+ env: NodeJS.ProcessEnv;
83
+ machines: () => Promise<MachineRecord[]>;
84
+ /** Whether a machine is a server, and answers. */
85
+ facts: (machine: MachineAccess) => Promise<{
86
+ server?: true;
87
+ version?: string;
88
+ }>;
89
+ call: (machine: MachineAccess, fn: string, args: unknown[]) => Promise<{
90
+ ok: true;
91
+ ret: unknown;
92
+ } | {
93
+ ok: false;
94
+ error: string;
95
+ }>;
96
+ /** This computer's own logins. */
97
+ local: () => Promise<LocalLogin[]>;
98
+ /** How full each of this computer's accounts is, as its own page reads it. */
99
+ usage: () => Promise<{
100
+ kind: CopiedKind;
101
+ source: string;
102
+ windows: UsageWindow[];
103
+ at: number;
104
+ }[]>;
105
+ /** This computer's settings. */
106
+ preferences: () => Promise<Preferences>;
107
+ mint: Mint;
108
+ loginCodex: (opts: CodexLoginOptions) => Promise<CodexLogin>;
109
+ computer: () => string;
110
+ };
111
+ /** The person's own Claude login here, as Claude Code keeps who it is: none when it is logged in to no account. */
112
+ export declare function claudeOwnAccount(env?: NodeJS.ProcessEnv): {
113
+ name: string;
114
+ who: string;
115
+ } | undefined;
116
+ /** Every account this computer is logged in to: its coding agents' and its git hosts'. */
117
+ export declare function localLogins(env?: NodeJS.ProcessEnv): Promise<LocalLogin[]>;
118
+ /** Bring every server that uses this computer's logins up to them, and note how each stands; a saved machine that is no server of the person's is left out. */
119
+ export declare function syncLogins(): Promise<ServerLogins[]>;
120
+ /** The servers as last read, with the press under way on each: read anew when none were read yet. */
121
+ export declare function serverLogins(): Promise<ServerLogins[]>;
122
+ /**
123
+ * The person's press for a server: each of this computer's accounts that waits for it gets a
124
+ * login of the server's own, made in this computer's browser, one after the other. Answers at
125
+ * once; how it goes is in {@link serverLogins}.
126
+ */
127
+ export declare function allowLogins(machineId: string): Promise<{
128
+ ok: true;
129
+ } | {
130
+ ok: false;
131
+ error: string;
132
+ }>;
133
+ /** Keep, or take off, a login the server has of this computer's that this computer no longer has. */
134
+ export declare function settleLeft(machineId: string, which: {
135
+ kind: CopiedKind;
136
+ host?: string;
137
+ source: string;
138
+ }, keep: boolean): Promise<{
139
+ ok: true;
140
+ } | {
141
+ ok: false;
142
+ error: string;
143
+ }>;
144
+ /** Keep every server that uses this computer's logins up to them, from now on: a minute apart, the first a moment after the start. */
145
+ export declare function startLoginsSync(env: NodeJS.ProcessEnv): () => void;
@@ -0,0 +1,77 @@
1
+ import { type AgentMeta } from '../store/index.js';
2
+ /**
3
+ * The runs of another computer, as this one lists them: a laptop's on its server, a server's on
4
+ * the laptop. Each computer answers for its own runs only, as they stand right now, over the relay
5
+ * of the saved machine it is ({@link RunChanges}); this computer takes what it says over the
6
+ * records of those runs it holds, which come through a project's shared records and stop at
7
+ * whatever was shared last ({@link withMachineRuns}). So how a computer's runs stand never
8
+ * depends on its records being shared: a computer that does not answer has its runs known by what
9
+ * it said last, or by their records, and none of them going: their status is `unknown`.
10
+ */
11
+ /** What a computer answers for its own runs of a project. */
12
+ export interface OwnRuns {
13
+ /** What to ask with next time, as `since`: the answer then holds only the runs that changed after this one. */
14
+ at: string;
15
+ /** Its runs that changed since the `since` it was asked with; every one when there was none, or one it does not know. */
16
+ runs: AgentMeta[];
17
+ /** Every one of its runs of the project, by id: a run the asker holds that is not here is gone. */
18
+ ids: string[];
19
+ }
20
+ /**
21
+ * A computer's own runs, counted as they change, per project: each answer says where it leaves
22
+ * the asker, and the next holds what changed after that. A count from before this OpenAgent
23
+ * started, or from no answer of its, is answered with every run.
24
+ */
25
+ export declare class RunChanges {
26
+ private readonly started;
27
+ private readonly projects;
28
+ answer(project: string, runs: readonly AgentMeta[], since?: unknown): OwnRuns;
29
+ private countOf;
30
+ }
31
+ /** A saved machine's runs of one project, as this computer last heard them. */
32
+ export interface MachineRuns {
33
+ /** The computer's own name, as the records of its runs carry it. */
34
+ host: string;
35
+ /** Its runs as it said them last, since this OpenAgent started. */
36
+ runs: readonly AgentMeta[];
37
+ /** It answered the last time it was asked. */
38
+ answered: boolean;
39
+ /** When it last answered, ISO, when this computer knows. */
40
+ seenAt?: string;
41
+ }
42
+ /**
43
+ * A project's runs with what its saved machines said of theirs: a machine's word on a run of its
44
+ * own wins over the run's record, and a run of its own with no record here yet is listed too. A
45
+ * machine's run that is going is going only by its machine's word just now: one whose machine did
46
+ * not answer, or that its machine did not say, reads `unknown`, with when its machine was last
47
+ * seen. The runs of every other computer pass through as recorded.
48
+ */
49
+ export declare function withMachineRuns(records: AgentMeta[], machines: readonly MachineRuns[]): AgentMeta[];
50
+ /** A saved machine to ask for its runs: where it answers and its computer's own name. */
51
+ export interface AskedMachine {
52
+ url: string;
53
+ host: string;
54
+ /** When it last answered, ISO, as kept with the machine. */
55
+ seenAt?: string;
56
+ }
57
+ /**
58
+ * What each saved machine said last of its runs of a project, asked again behind the page once
59
+ * its answer is a few seconds old: a page is answered at once with what is known, and waits only
60
+ * for a machine's first answer, and not long. One ask at a time per machine and project; each
61
+ * holds only what changed since the one before ({@link OwnRuns}).
62
+ */
63
+ export declare class MachineRunsKept {
64
+ /** Ask the machine for its runs of the project at `address`, since what it answered last. */
65
+ private readonly ask;
66
+ /** Told each time a machine answered. */
67
+ private readonly seen;
68
+ private readonly now;
69
+ private readonly kept;
70
+ constructor(
71
+ /** Ask the machine for its runs of the project at `address`, since what it answered last. */
72
+ ask: (machine: AskedMachine, address: string, since: string | undefined) => Promise<unknown>,
73
+ /** Told each time a machine answered. */
74
+ seen?: (machine: AskedMachine, at: string) => void, now?: () => number);
75
+ of(machines: readonly AskedMachine[], address: string): Promise<MachineRuns[]>;
76
+ private askAgain;
77
+ }
@@ -1,3 +1,4 @@
1
+ import { type Health } from '../health.js';
1
2
  import { EventStream } from '../event-stream.js';
2
3
  import type { OpenAgentEvent } from '../events.js';
3
4
  import type { AgentMeta } from '../store/index.js';
@@ -50,13 +51,15 @@ export type RelayStartResult = StartAgentResult | {
50
51
  export declare function pingRemote(target: MachineAccess): Promise<boolean>;
51
52
  /**
52
53
  * What a saved machine says of itself in its ping: the OpenAgent it runs, the computer's own
53
- * name, which the records of its runs carry, and the ids it is listed under at the doors of the
54
- * machines it saved. Nothing for a machine that does not answer, or does not say.
54
+ * name, which the records of its runs carry, the ids it is listed under at the doors of the
55
+ * machines it saved, and whether it is a server. Nothing for a machine that does not answer, or does not say.
55
56
  */
56
57
  export declare function remoteFacts(target: MachineAccess): Promise<{
57
58
  version?: string;
58
59
  host?: string;
59
60
  listed?: string[];
61
+ server?: true;
62
+ health?: Health;
60
63
  }>;
61
64
  /** The OpenAgent a saved machine runs, as its ping tells it; nothing for a machine that does not answer, or does not say. */
62
65
  export declare function remoteVersion(target: MachineAccess): Promise<string | undefined>;
@@ -158,7 +161,7 @@ export interface BringProject {
158
161
  * shape, the same way a failed local read does. A refusal the machine gave a reason for is thrown
159
162
  * as a {@link MachineRefusal}, so the reason can be shown in place of that shape's own words.
160
163
  */
161
- export declare function relayRpc(target: RemoteTarget, fn: string, args: unknown[]): Promise<unknown>;
164
+ export declare function relayRpc(target: RemoteTarget, fn: string, args: unknown[], timeoutMs?: number): Promise<unknown>;
162
165
  /**
163
166
  * Fetch-stream a remote agent's newline-delimited events into `onEvent` until the remote closes the
164
167
  * body, the agent ends, or `cancel()` is called. A 401 (this computer was removed there) ends the stream
@@ -258,6 +261,17 @@ export declare function remoteAddMachine(machine: MachineAccess, link: string, l
258
261
  ok: false;
259
262
  error: string;
260
263
  }>;
264
+ /**
265
+ * Call one of a machine's own functions, as its page calls it, with this computer's key there:
266
+ * what the machine answers is its own words, to read as data. Why not, when it did not answer.
267
+ */
268
+ export declare function machineCall(machine: MachineAccess, fn: string, args: unknown[], timeoutMs?: number): Promise<{
269
+ ok: true;
270
+ ret: unknown;
271
+ } | {
272
+ ok: false;
273
+ error: string;
274
+ }>;
261
275
  /** The logins this computer's person has on a machine of another person's, as that machine says (machine-logins.ts). */
262
276
  export declare function remoteLogins(machine: MachineAccess): Promise<{
263
277
  ok: true;
@@ -8,6 +8,7 @@ import type { ProjectErrorsReader } from '../project-errors.js';
8
8
  import type { AddProjectResult, RemoveProjectResult, StartAgentOptions, StartAgentResult, StartedInResult } from './types.js';
9
9
  import type { AgentMeta } from '../store/index.js';
10
10
  import type { RemoteTarget } from './remote-run.js';
11
+ import type { MachineRuns } from './machine-runs.js';
11
12
  /** Wired by the daemon so `sendStart` can reach the daemon's own `startAgent` closure. */
12
13
  export type StartAgentHandler = (prompt: string, options: StartAgentOptions, projectId?: string) => StartAgentResult | Promise<StartAgentResult>;
13
14
  /** Wired by the daemon so `sendAddProject` can install + register a repo (#433). */
@@ -53,6 +54,8 @@ export interface RemoteAgents {
53
54
  * it was given and its address. Asked of the machines first, when one has not said its name yet.
54
55
  */
55
56
  machineNames(): Promise<(host: string) => SavedMachine | undefined>;
57
+ /** What each saved machine said last of its own runs of the project at `projectPath`, asked again once that is a few seconds old (machine-runs.ts). */
58
+ machineRuns(projectPath: string): Promise<MachineRuns[]>;
56
59
  }
57
60
  /**
58
61
  * What every RPC acts through.
@@ -16,6 +16,8 @@ export interface AccountRow {
16
16
  id: string;
17
17
  /** Its name as shown: the person's own goes by the agent's name for them until they give it one. */
18
18
  name: string;
19
+ /** A login of the person's own computer, by that computer's name: a server's copy of it. */
20
+ from?: string;
19
21
  /** The person's own login, which the agent keeps: it is never removed. */
20
22
  own: boolean;
21
23
  /** When an added one was added, ISO 8601. */
@@ -32,11 +34,19 @@ export interface AccountRow {
32
34
  /** An account being added: the browser is open on the agent's page, or the login is being kept. */
33
35
  export interface AccountAdding {
34
36
  name: string;
35
- /** The page to sign in at, when the agent gave one: what a person copies into a private window when the browser is signed in to another account. */
37
+ /** The page to sign in at, when the agent gave one: what a person copies into a private window when the browser is signed in to another account, or opens on their device where this computer has no browser. */
36
38
  url?: string;
39
+ /** No browser here: the code Codex gave, which the person types at {@link url}. */
40
+ code?: string;
41
+ /** No browser here: Claude's page shows a code once the person said yes, which they paste back. */
42
+ paste?: true;
37
43
  }
38
44
  export interface AccountsView {
39
45
  accounts: AccountRow[];
46
+ /** This computer's own name: what its own login's row says it is on. */
47
+ computer: string;
48
+ /** On a server: the computer of the person's whose logins it uses, by its name. */
49
+ from?: string;
40
50
  adding?: AccountAdding;
41
51
  /** Why the last add did not go through. */
42
52
  failed?: string;
@@ -55,6 +65,10 @@ export declare const accountsWiring: {
55
65
  codexFolder: (account: AgentAccount) => string;
56
66
  codexWho: (home: string) => Promise<CodexWho>;
57
67
  codexUsage: (home: string) => Promise<DriverRateWindow[]>;
68
+ /** No browser on this computer: a server's. */
69
+ headless: () => boolean;
70
+ /** This computer's own name. */
71
+ computer: () => string;
58
72
  };
59
73
  /** An agent's accounts in the order runs try them, each with how full it is and whether a limit keeps it out. */
60
74
  export declare function onAgentAccounts(agent: AccountsAgent): Promise<AccountsView>;
@@ -70,6 +84,8 @@ export type AccountResult = {
70
84
  * in {@link onAgentAccounts}.
71
85
  */
72
86
  export declare function sendAddAgentAccount(agent: AccountsAgent, name: string): Promise<AccountResult>;
87
+ /** Hand Claude Code the code its page showed the person, on a computer with no browser of its own. */
88
+ export declare function sendAgentAccountCode(agent: AccountsAgent, code: string): Promise<AccountResult>;
73
89
  /**
74
90
  * Remove an added account. A Claude login is not ended: it is good until its year is over, or until
75
91
  * it is taken back on claude.ai. A Codex account's folder, its login in it, goes with it.
@@ -0,0 +1,48 @@
1
+ import { type CopiedKind, type CopiedLogin, type GivenLogin, type UsageWindow } from '../dashboard/copied-logins.js';
2
+ import { type AccountResult } from './accounts.js';
3
+ /** What the RPCs reach for, swapped in tests. */
4
+ export declare const copiedWiring: {
5
+ /** Whether this OpenAgent is a server's: only a server takes logins. */
6
+ server: () => boolean;
7
+ /** Where a Codex account's sign-in is kept, a folder each. */
8
+ codexDir: () => string;
9
+ /** Run a git host's package command for `host`, with `input` on its standard input. */
10
+ gitHost: (host: string, args: string[], input?: string) => Promise<{
11
+ ok: true;
12
+ output: unknown;
13
+ } | {
14
+ ok: false;
15
+ error: string;
16
+ }>;
17
+ };
18
+ /** What the server says it keeps, to the computer that asks. */
19
+ export type CopiedView = {
20
+ ok: true;
21
+ logins: Omit<CopiedLogin, 'usage'>[];
22
+ } | {
23
+ ok: false;
24
+ error: string;
25
+ };
26
+ /** What the server keeps from the person's computers, without how full each is: what a computer compares its own with. */
27
+ export declare function onCopiedLogins(): Promise<CopiedView>;
28
+ /**
29
+ * Take a login a computer of the person's handed over: it goes where its tool reads it, in place
30
+ * of what the same account of the same computer had here before. `secret` is the login: a
31
+ * Claude login, a Codex sign-in as Codex keeps it, a git host's token.
32
+ */
33
+ export declare function sendCopiedLogin(given: GivenLogin, secret: string): Promise<AccountResult>;
34
+ /** Take a login a computer handed over off this server: it is deleted here, and goes on working wherever else it is. */
35
+ export declare function sendForgetCopiedLogin(which: Pick<CopiedLogin, 'kind' | 'host' | 'source'>): Promise<AccountResult>;
36
+ /**
37
+ * Keep a login the computer no longer has: the person said to. It is no longer that account of the
38
+ * computer's, so the computer's next login under the same account takes a place of its own.
39
+ */
40
+ export declare function sendKeepCopiedLogin(which: Pick<CopiedLogin, 'kind' | 'host' | 'source'>): Promise<AccountResult>;
41
+ /** How full each login is, as the computer read it: shown on this server's page, whose own reading a Claude login made for it cannot make. */
42
+ export declare function sendCopiedUsage(readings: {
43
+ kind: CopiedKind;
44
+ host?: string;
45
+ source: string;
46
+ windows: UsageWindow[];
47
+ at: number;
48
+ }[]): Promise<AccountResult>;
@@ -10,8 +10,11 @@ export { onMachines, sendAddMachine, sendRemoveMachine, onMachinesReachable, onM
10
10
  export { onModules, runModuleCommand, runComputerCommand, runComputerCommandOn, readModule, type DashboardModule, type ModuleCommandResult, type ModuleReadResult } from './modules.js';
11
11
  export { onProjectSkills, sendChangeSkills, sendProjectSkills, type ProjectSkills, type ProjectSkill, type ChangeSkillsResult } from './skills.js';
12
12
  export { onPerson, type Person } from './person.js';
13
+ export { onGitHostPeople, type HostPerson } from './people.js';
13
14
  export { onGitHosts, sendUseGitHostAccount, sendGitHostLogin, sendGitHostInstall, onAgentState, sendAgentFix, onProjectAccounts, sendProjectAccounts, type GitHostsView, type GitHostRow, type GitHostAccount, type GitHostProvider, type AgentState, type ProjectAccountsView, type ProjectAgentAccounts } from './logins.js';
14
- export { onAgentAccounts, sendAddAgentAccount, sendRemoveAgentAccount, sendUseAgentAccountFirst, sendNameOwnAgentAccount, type AccountsAgent, type AccountRow, type AccountWindow, type AccountAdding, type AccountsView, type AccountResult } from './accounts.js';
15
+ export { onServerLogins, sendUseLoginsOn, sendAllowLogins, sendSettleLogin, type ServerLoginsView, type ServerLogins, type LoginThere } from './server-logins.js';
16
+ export { onCopiedLogins, sendCopiedLogin, sendForgetCopiedLogin, sendKeepCopiedLogin, sendCopiedUsage, type CopiedView } from './copied-logins.js';
17
+ export { onAgentAccounts, sendAddAgentAccount, sendAgentAccountCode, sendRemoveAgentAccount, sendUseAgentAccountFirst, sendNameOwnAgentAccount, type AccountsAgent, type AccountRow, type AccountWindow, type AccountAdding, type AccountsView, type AccountResult } from './accounts.js';
15
18
  import { streamAgentEvents } from './events.js';
16
19
  /** One RPC: called with whatever the browser sent, answering with whatever JSON.stringify keeps. */
17
20
  export type RpcHandler = (...args: never[]) => unknown;