@openagt/dashboard 0.40.0 → 0.41.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 (129) hide show
  1. package/dist/built-in.d.ts +5 -0
  2. package/dist/built-in.d.ts.map +1 -1
  3. package/dist/built-in.js +7 -0
  4. package/dist/built-in.js.map +1 -1
  5. package/dist/clone-project.d.ts +11 -0
  6. package/dist/clone-project.d.ts.map +1 -1
  7. package/dist/clone-project.js +38 -12
  8. package/dist/clone-project.js.map +1 -1
  9. package/dist/daemon-runtime.d.ts.map +1 -1
  10. package/dist/daemon-runtime.js +216 -63
  11. package/dist/daemon-runtime.js.map +1 -1
  12. package/dist/daemon.js +2 -2
  13. package/dist/daemon.js.map +1 -1
  14. package/dist/dashboard/activity.d.ts +2 -2
  15. package/dist/dashboard/activity.d.ts.map +1 -1
  16. package/dist/dashboard/activity.js +2 -2
  17. package/dist/dashboard/activity.js.map +1 -1
  18. package/dist/dashboard/elsewhere.d.ts +92 -0
  19. package/dist/dashboard/elsewhere.d.ts.map +1 -0
  20. package/dist/dashboard/elsewhere.js +155 -0
  21. package/dist/dashboard/elsewhere.js.map +1 -0
  22. package/dist/dashboard/interventions.d.ts +6 -0
  23. package/dist/dashboard/interventions.d.ts.map +1 -1
  24. package/dist/dashboard/interventions.js.map +1 -1
  25. package/dist/dashboard/machine-interventions.d.ts +52 -0
  26. package/dist/dashboard/machine-interventions.d.ts.map +1 -0
  27. package/dist/dashboard/machine-interventions.js +117 -0
  28. package/dist/dashboard/machine-interventions.js.map +1 -0
  29. package/dist/dashboard/module-serve.d.ts +6 -0
  30. package/dist/dashboard/module-serve.d.ts.map +1 -1
  31. package/dist/dashboard/module-serve.js +11 -1
  32. package/dist/dashboard/module-serve.js.map +1 -1
  33. package/dist/dashboard/overview.d.ts +20 -5
  34. package/dist/dashboard/overview.d.ts.map +1 -1
  35. package/dist/dashboard/overview.js +28 -8
  36. package/dist/dashboard/overview.js.map +1 -1
  37. package/dist/dashboard/projects.d.ts +11 -2
  38. package/dist/dashboard/projects.d.ts.map +1 -1
  39. package/dist/dashboard/projects.js +3 -2
  40. package/dist/dashboard/projects.js.map +1 -1
  41. package/dist/dashboard/relay-endpoints.d.ts +2 -0
  42. package/dist/dashboard/relay-endpoints.d.ts.map +1 -1
  43. package/dist/dashboard/relay-endpoints.js +4 -2
  44. package/dist/dashboard/relay-endpoints.js.map +1 -1
  45. package/dist/dashboard/rpc-serve.d.ts +21 -1
  46. package/dist/dashboard/rpc-serve.d.ts.map +1 -1
  47. package/dist/dashboard/rpc-serve.js +9 -3
  48. package/dist/dashboard/rpc-serve.js.map +1 -1
  49. package/dist/dashboard/server.d.ts +2 -0
  50. package/dist/dashboard/server.d.ts.map +1 -1
  51. package/dist/dashboard/server.js +6 -4
  52. package/dist/dashboard/server.js.map +1 -1
  53. package/dist/dashboard/types.d.ts +3 -1
  54. package/dist/dashboard/types.d.ts.map +1 -1
  55. package/dist/dashboard-bundle/assets/host/module-BcFzlJhp.js +1 -0
  56. package/dist/dashboard-bundle/assets/main-Ca6eaXat.css +2 -0
  57. package/dist/dashboard-bundle/assets/main-rpNhGecV.js +148 -0
  58. package/dist/dashboard-bundle/assets/{module-C8GDq0nb.js → module-Bhd9t16k.js} +5 -5
  59. package/dist/dashboard-bundle/index.html +4 -4
  60. package/dist/dashboard-rpc/context.js +1 -1
  61. package/dist/dashboard-rpc/context.js.map +1 -1
  62. package/dist/dashboard-rpc/index.d.ts +1 -1
  63. package/dist/dashboard-rpc/index.d.ts.map +1 -1
  64. package/dist/dashboard-rpc/index.js +1 -1
  65. package/dist/dashboard-rpc/index.js.map +1 -1
  66. package/dist/dashboard-rpc/machines.d.ts +18 -3
  67. package/dist/dashboard-rpc/machines.d.ts.map +1 -1
  68. package/dist/dashboard-rpc/machines.js +78 -21
  69. package/dist/dashboard-rpc/machines.js.map +1 -1
  70. package/dist/dashboard-rpc/modules.d.ts.map +1 -1
  71. package/dist/dashboard-rpc/modules.js +19 -3
  72. package/dist/dashboard-rpc/modules.js.map +1 -1
  73. package/dist/dashboard-rpc/projects.d.ts +14 -0
  74. package/dist/dashboard-rpc/projects.d.ts.map +1 -1
  75. package/dist/dashboard-rpc/projects.js +48 -5
  76. package/dist/dashboard-rpc/projects.js.map +1 -1
  77. package/dist/dashboard-rpc/reads.d.ts +6 -0
  78. package/dist/dashboard-rpc/reads.d.ts.map +1 -1
  79. package/dist/dashboard-rpc/reads.js +48 -14
  80. package/dist/dashboard-rpc/reads.js.map +1 -1
  81. package/dist/dashboard-rpc/relay-dispatch.d.ts +12 -0
  82. package/dist/dashboard-rpc/relay-dispatch.d.ts.map +1 -1
  83. package/dist/dashboard-rpc/relay-dispatch.js +42 -7
  84. package/dist/dashboard-rpc/relay-dispatch.js.map +1 -1
  85. package/dist/dashboard-rpc/runs-changed.d.ts.map +1 -1
  86. package/dist/dashboard-rpc/runs-changed.js +14 -6
  87. package/dist/dashboard-rpc/runs-changed.js.map +1 -1
  88. package/dist/dashboard-rpc/test-context.d.ts +3 -1
  89. package/dist/dashboard-rpc/test-context.d.ts.map +1 -1
  90. package/dist/dashboard-rpc/test-context.js +13 -1
  91. package/dist/dashboard-rpc/test-context.js.map +1 -1
  92. package/dist/module-types/dashboard/components/MachineMark.d.ts +14 -0
  93. package/dist/module-types/dashboard/lib/models.d.ts +6 -0
  94. package/dist/module-types/dashboard/rpc/machines.d.ts +35 -0
  95. package/dist/module-types/src/built-in.d.ts +5 -0
  96. package/dist/module-types/src/clone-project.d.ts +11 -0
  97. package/dist/module-types/src/dashboard/activity.d.ts +2 -2
  98. package/dist/module-types/src/dashboard/elsewhere.d.ts +91 -0
  99. package/dist/module-types/src/dashboard/interventions.d.ts +6 -0
  100. package/dist/module-types/src/dashboard/machine-interventions.d.ts +51 -0
  101. package/dist/module-types/src/dashboard/module-serve.d.ts +6 -0
  102. package/dist/module-types/src/dashboard/overview.d.ts +20 -5
  103. package/dist/module-types/src/dashboard/projects.d.ts +11 -2
  104. package/dist/module-types/src/dashboard/rpc-serve.d.ts +21 -1
  105. package/dist/module-types/src/dashboard/types.d.ts +3 -1
  106. package/dist/module-types/src/dashboard-rpc/index.d.ts +1 -1
  107. package/dist/module-types/src/dashboard-rpc/machines.d.ts +18 -3
  108. package/dist/module-types/src/dashboard-rpc/projects.d.ts +14 -0
  109. package/dist/module-types/src/dashboard-rpc/reads.d.ts +6 -0
  110. package/dist/module-types/src/dashboard-rpc/relay-dispatch.d.ts +28 -0
  111. package/dist/module-types/src/project-modules.d.ts +19 -0
  112. package/dist/module-types/src/registry.d.ts +8 -0
  113. package/dist/module-types/src/repository-address.d.ts +6 -0
  114. package/dist/project-modules.d.ts +19 -0
  115. package/dist/project-modules.d.ts.map +1 -1
  116. package/dist/project-modules.js +42 -2
  117. package/dist/project-modules.js.map +1 -1
  118. package/dist/registry.d.ts +8 -0
  119. package/dist/registry.d.ts.map +1 -1
  120. package/dist/registry.js +13 -2
  121. package/dist/registry.js.map +1 -1
  122. package/dist/repository-address.d.ts +6 -0
  123. package/dist/repository-address.d.ts.map +1 -1
  124. package/dist/repository-address.js +9 -0
  125. package/dist/repository-address.js.map +1 -1
  126. package/package.json +15 -15
  127. package/dist/dashboard-bundle/assets/host/module-JRfd42hf.js +0 -1
  128. package/dist/dashboard-bundle/assets/main-BhC5aJ1h.css +0 -2
  129. package/dist/dashboard-bundle/assets/main-Bo8Pao9A.js +0 -148
@@ -0,0 +1,35 @@
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, owner?: 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>;
10
+ export declare const sendProjectHere: (projectId: string) => Promise<impl.ProjectOnMachine>;
11
+ export declare const onProjectHere: (projectId: string) => Promise<impl.ProjectOnMachine>;
12
+ export declare const onMachineStartCheck: (projectId: string, machineId: string, driver?: string | undefined) => Promise<import("../../src/project-hooks.js").StartReadiness | null>;
13
+ export declare const onMachineModels: (machineId: string) => Promise<import("./models.js").ModelsView | null>;
14
+ export declare const onComputersThrough: (machineId: string) => Promise<impl.ComputersThrough>;
15
+ export declare const sendAddComputerThrough: (machineId: string, computerId: string) => Promise<impl.AddMachineResult>;
16
+ export declare const onMachinePerson: (machineId: string) => Promise<impl.MachinePerson>;
17
+ export declare const sendRemoveMachineDevice: (machineId: string, deviceId: string) => Promise<impl.MachinePerson>;
18
+ export declare const sendRenameMachine: (id: string, label: string) => Promise<impl.AddMachineResult>;
19
+ export declare const sendLetMachineIn: (machineId: string, link: string) => Promise<{
20
+ ok: true;
21
+ } | {
22
+ ok: false;
23
+ error: string;
24
+ }>;
25
+ export declare const sendMachineCode: (machineId: string) => Promise<{
26
+ ok: true;
27
+ value: impl.MachineCode;
28
+ } | {
29
+ ok: false;
30
+ error: string;
31
+ }>;
32
+ export declare const sendMachineTold: (machineId: string) => Promise<{
33
+ ok: boolean;
34
+ }>;
35
+ export declare const onMachineLogins: (machineId: string) => Promise<impl.MachineLoginsResult>;
@@ -39,6 +39,11 @@ export declare function builtInPackages(): Promise<ProjectPackage[]>;
39
39
  export declare function builtInPackagesOf(root: string): Promise<ProjectPackage[]>;
40
40
  /** The project's own installed packages, less the names OpenAgent brings itself. */
41
41
  export declare function ownPackages(root: string): Promise<ProjectPackage[]>;
42
+ /**
43
+ * Every package OpenAgent brings to projects, the picked ones too, whatever a project holds: the
44
+ * copy a module's page is served from on a computer where no project of its own has the module.
45
+ */
46
+ export declare function broughtToProjects(): Promise<ProjectPackage[]>;
42
47
  /** The packages that are this computer's: see {@link COMPUTER_PACKAGES}. */
43
48
  export declare function computerPackages(): Promise<ProjectPackage[]>;
44
49
  /**
@@ -66,3 +66,14 @@ export interface CloneOptions {
66
66
  * folder a second ask could take for the project.
67
67
  */
68
68
  export declare function cloneProject(typed: string, opts?: CloneOptions): Promise<Cloned>;
69
+ /**
70
+ * Whether this computer's logins read the repository at the address, asked of its host without
71
+ * cloning anything: what a run of a project cloned here first would hit before it starts. The
72
+ * answer is the clone's own words when they cannot.
73
+ */
74
+ export declare function canRead(typed: string, opts?: CloneOptions, subject?: string): Promise<{
75
+ ok: true;
76
+ } | {
77
+ ok: false;
78
+ error: string;
79
+ }>;
@@ -22,8 +22,8 @@ export interface Activity {
22
22
  }
23
23
  /** Injectable seam so {@link buildActivity} is unit-testable off disk. */
24
24
  export interface ActivityDeps {
25
- /** A project's runs, live prepended to the archived history, newest-first. Defaults to disk. */
26
- readAgents?: (cwd: string) => Promise<AgentMeta[]>;
25
+ /** A project's runs, live prepended to the archived history, newest-first: off its folder by default, as its computer says them for another computer's. */
26
+ readAgents?: (project: ProjectSummary) => Promise<AgentMeta[]>;
27
27
  }
28
28
  /**
29
29
  * Build the cross-project activity feed: for each registered project's most recent agents, one
@@ -0,0 +1,91 @@
1
+ import type { ProjectSummary } from './projects.js';
2
+ /**
3
+ * The projects of the person's other computers, as this one lists them beside its own: a
4
+ * laptop's on its server, a server's on the laptop. Each computer says its own projects only
5
+ * ({@link OwnProject}), over the relay of the saved machine it is, and only a computer that is
6
+ * the person's own is asked: a computer of another person's, shared on a server, keeps its
7
+ * projects to its person.
8
+ *
9
+ * A project this computer has too, by its repository's address, is listed once, as this
10
+ * computer's: a run of it goes to any computer that has it, by "Run on". One only another
11
+ * computer has is listed as that computer's, under an id of its own ({@link elsewhereId}): what
12
+ * the page asks of it is asked of that computer, and a run of it starts there unless another
13
+ * computer is picked, which clones it first. What a computer said last is kept, so its projects
14
+ * stay listed while it is off.
15
+ */
16
+ /** What a computer says of one of its own projects to another computer of the person's. */
17
+ export interface OwnProject {
18
+ /** Its id there. */
19
+ id: string;
20
+ name: string;
21
+ /** Its folder there. */
22
+ path: string;
23
+ /** Its repository's address ({@link import('../repository-address.js').repositoryAddress}), when it has one. */
24
+ address?: string;
25
+ /** The same address in the letters its `origin` is written with: what another computer clones it from. */
26
+ spelling?: string;
27
+ /** Whether the agents' records of it go to its repository's remote: a copy cloned from it takes the same answer. */
28
+ share: boolean;
29
+ gitHost: boolean;
30
+ activated: boolean;
31
+ lastActivityAt?: string;
32
+ /** The packages that bring it a module's pages there (Queue, Tickets, Automations): the pages it has here too. */
33
+ modules?: string[];
34
+ }
35
+ /** What a computer answered as its projects, the ones that read as projects: anything else is dropped. */
36
+ export declare function ownProjectsOf(said: unknown): OwnProject[];
37
+ /** The id here of a project of another computer's: its id there, and the mark of the saved machine it is. */
38
+ export declare function elsewhereId(projectId: string, machineId: string): string;
39
+ /** Whether an id is that of another computer's project, not one of this computer's own. */
40
+ export declare function isElsewhereId(id: unknown): id is string;
41
+ /** How a call about the project names it to its computer: its repository's address, or its id there when it has none. */
42
+ export declare function lineNameOf(project: Pick<OwnProject, 'id' | 'address'>): string;
43
+ /** The project's id on its computer, from how a call named it there: undefined for an address. */
44
+ export declare function idInLineName(name: string): string | undefined;
45
+ /** A saved machine of the person's own, with what it said of its projects last. */
46
+ export interface OwnMachine {
47
+ id: string;
48
+ projects?: OwnProject[];
49
+ }
50
+ /** A project of another computer's: the saved machine it is on, and the project as that computer said it. */
51
+ export interface ElsewhereHome<M extends OwnMachine = OwnMachine> {
52
+ machine: M;
53
+ project: OwnProject;
54
+ }
55
+ /** The listing of another computer's project, as the page lists projects: marked with the saved machine it is on. */
56
+ export declare function elsewhereSummary(home: ElsewhereHome): ProjectSummary;
57
+ /**
58
+ * The projects of the person's other computers that this one does not have, each listed once:
59
+ * one whose repository's address is a project here is this computer's, and of two computers
60
+ * with the same repository the first one listed has it. A project with no address is only its
61
+ * own computer's, and listed for it.
62
+ */
63
+ export declare function elsewhereHomes<M extends OwnMachine>(machines: readonly M[], ownAddresses: ReadonlySet<string>): ElsewhereHome<M>[];
64
+ /** The project of another computer's with this id, among the saved machines, whether it is listed here or not. */
65
+ export declare function homeOf<M extends OwnMachine>(machines: readonly M[], id: string): ElsewhereHome<M> | undefined;
66
+ /** How long a computer's word on its projects is taken before it is asked again. */
67
+ export declare const PROJECTS_KEPT_MS = 20000;
68
+ /** How long a list waits for a computer never answered before: what it says after comes at the next list. */
69
+ export declare const FIRST_WAIT_MS = 3000;
70
+ /**
71
+ * Each of the person's computers asked for its projects at most every {@link PROJECTS_KEPT_MS}, and
72
+ * what it said kept by `keep` (the saved machine's record), so a list is made of what each said
73
+ * last: at once, while each is asked again behind it. One never answered yet is waited for a
74
+ * little, the first time.
75
+ */
76
+ export declare class OwnProjectsAsked<M extends OwnMachine> {
77
+ /** Ask the machine for its projects. */
78
+ private readonly ask;
79
+ /** Keep what the machine said, when it answered and said otherwise than it had. */
80
+ private readonly keep;
81
+ private readonly now;
82
+ private readonly asked;
83
+ constructor(
84
+ /** Ask the machine for its projects. */
85
+ ask: (machine: M) => Promise<unknown>,
86
+ /** Keep what the machine said, when it answered and said otherwise than it had. */
87
+ keep: (machine: M, projects: OwnProject[]) => Promise<void>, now?: () => number);
88
+ /** Ask each machine whose word is old, and wait for the ones never heard from, a little. */
89
+ refresh(machines: readonly M[]): Promise<void>;
90
+ private askOne;
91
+ }
@@ -4,6 +4,7 @@ import type { ProjectSummary, ProjectionRead } from './projects.js';
4
4
  import { type BranchesFor } from '../store/branches.js';
5
5
  import { type PrLister } from './pull-requests.js';
6
6
  import { type BridgeQuestion } from './bridge-question.js';
7
+ import type { MachineKind } from '../reached-by-line.js';
7
8
  export { interventionKey } from './keys.js';
8
9
  /**
9
10
  * One item awaiting the human: an open `pr` to review and merge or close, a run `awaiting` the
@@ -42,6 +43,11 @@ export interface Intervention {
42
43
  files?: number;
43
44
  /** When the PR was opened (`pr`) or the agent last updated (the other two), ISO, for ordering. */
44
45
  createdAt?: string;
46
+ /** The computer the run it is about runs on, when that is one of the person's other computers: the saved machine's name and kind. */
47
+ computer?: {
48
+ name: string;
49
+ kind: MachineKind;
50
+ };
45
51
  }
46
52
  /** Injectable seam so {@link buildInterventions} is unit-testable off disk. */
47
53
  export interface InterventionsDeps {
@@ -0,0 +1,51 @@
1
+ import type { Intervention } from './interventions.js';
2
+ import type { ProjectionRead } from './projects.js';
3
+ /**
4
+ * The Human Queue of the person's other computers, beside this one's own: what needs the person in
5
+ * a run there (its question, the work it left unpublished, the PR it opened) and the PRs of a
6
+ * project only another computer has. Each computer says the items of its own projects only, never
7
+ * the ones it lists of other computers', so two computers never ask each other in a circle. Here
8
+ * each item is named by the project as it is listed here: this computer's own of the same
9
+ * repository, else the other computer's under its id here; and an item of a run there is marked
10
+ * with that computer.
11
+ */
12
+ /** What the person's other computers said of their Human Queues, each as named here, and the projects here that one which did not answer has. */
13
+ export interface MachinesQueue {
14
+ said: ProjectionRead<Intervention>[];
15
+ /** Projects here whose items on a computer that did not answer are not known: none of them is read whole. */
16
+ unread: string[];
17
+ }
18
+ /** What a computer answered as its Human Queue, the items that read as items, each in the fields an item has: anything else is dropped. */
19
+ export declare function interventionsOf(said: unknown): ProjectionRead<Intervention>;
20
+ /**
21
+ * A computer's Human Queue as named here: each item by `idHere` of its project's id there, and one
22
+ * about a run marked with the computer it runs on. An item of a project not listed here is dropped.
23
+ */
24
+ export declare function namedHere(said: ProjectionRead<Intervention>, idHere: (theirs: string) => string | undefined, computer: NonNullable<Intervention['computer']>): ProjectionRead<Intervention>;
25
+ /**
26
+ * This computer's Human Queue with what the other computers said: each item named as its project is
27
+ * here (`names`, by id: one not listed is dropped), once, newest first. Of a PR both list, the one
28
+ * a run opened is kept: its row opens the run. A project is read whole when every computer that has
29
+ * it answered.
30
+ */
31
+ export declare function withMachinesQueue(own: ProjectionRead<Intervention>, machines: MachinesQueue, names: ReadonlyMap<string, string>): ProjectionRead<Intervention>;
32
+ /** How long a computer's Human Queue is taken before it is asked again: a page asks every few seconds. */
33
+ export declare const QUEUE_KEPT_MS = 10000;
34
+ /** How long a Human Queue waits for a computer never answered before: what it says after comes at the next read. */
35
+ export declare const QUEUE_FIRST_WAIT_MS = 3000;
36
+ /**
37
+ * Each machine asked at most every {@link QUEUE_KEPT_MS}, and what it said last kept: a read is
38
+ * answered at once with that while the machine is asked again behind it. One never answered yet is
39
+ * waited for a little; one whose last ask failed has nothing kept, so its items are not taken as
40
+ * still there.
41
+ */
42
+ export declare class AnswersKept<M extends {
43
+ id: string;
44
+ }, T> {
45
+ private readonly ask;
46
+ private readonly now;
47
+ private readonly kept;
48
+ constructor(ask: (machine: M) => Promise<T>, now?: () => number);
49
+ /** What each machine said last, by its id: one that never answered, or whose last ask failed, has none. */
50
+ of(machines: readonly M[]): Promise<Map<string, T>>;
51
+ }
@@ -5,10 +5,14 @@ import { type ProjectModule } from '../project-modules.js';
5
5
  export declare const MODULES_PREFIX = "/_modules";
6
6
  /** Where the files of the computer's modules are served, which are no project's: `/_computer-modules/<package>/<file>`. */
7
7
  export declare const COMPUTER_MODULES_PREFIX = "/_computer-modules";
8
+ /** Where the files of the modules OpenAgent brings to projects are served from its own copy: `/_brought-modules/<package>/<file>`. */
9
+ export declare const BROUGHT_MODULES_PREFIX = "/_brought-modules";
8
10
  /** The URL a module's browser part is served at from one project. */
9
11
  export declare function moduleUrl(projectId: string, module: Pick<ProjectModule, 'package' | 'entry'>): string;
10
12
  /** The URL the browser part of one of the computer's modules is served at. */
11
13
  export declare function computerModuleUrl(module: Pick<ProjectModule, 'package' | 'entry'>): string;
14
+ /** The URL the browser part of a module OpenAgent brings to projects is served at from its own copy. */
15
+ export declare function broughtModuleUrl(module: Pick<ProjectModule, 'package' | 'entry'>): string;
12
16
  /**
13
17
  * A module's URL with its entry file's version (`?v=`): a browser keeps that file for good, and
14
18
  * the next version of the module is another URL. Without the file there to read, the URL as it is.
@@ -27,3 +31,5 @@ export declare function versionedModuleUrl(url: string, module: Pick<ProjectModu
27
31
  export declare function serveModuleFile(req: IncomingMessage, res: ServerResponse, pathname: string, projects?: ProjectsProvider): Promise<void>;
28
32
  /** Serve one file of a module that is the computer's: as {@link serveModuleFile}, with no project to be registered. */
29
33
  export declare function serveComputerModuleFile(req: IncomingMessage, res: ServerResponse, pathname: string): Promise<void>;
34
+ /** Serve one file of a module OpenAgent brings to projects, from its own copy: as {@link serveComputerModuleFile}. */
35
+ export declare function serveBroughtModuleFile(req: IncomingMessage, res: ServerResponse, pathname: string): Promise<void>;
@@ -1,6 +1,7 @@
1
1
  import { type LiveAgent, type AgentMeta, type AgentStatus } from '../store/index.js';
2
2
  import type { ProjectSummary } from './projects.js';
3
3
  import { type ProjectQueue } from './queue.js';
4
+ import type { MachineKind } from '../reached-by-line.js';
4
5
  /** One project's in-flight run, surfaced in the Overview's "working now" list. */
5
6
  export interface ActiveAgent {
6
7
  projectId: string;
@@ -21,8 +22,14 @@ export interface ActiveAgent {
21
22
  * cloud side is the agent, and "no agents working" over a waiting cloud session was a lie.
22
23
  */
23
24
  cloud?: 'in-cloud' | 'waiting';
24
- /** The machine whose daemon started it (#1648), only when that is not this one. */
25
- host?: string;
25
+ /**
26
+ * The computer it runs on, only when that is not this one: the saved machine's name and kind for
27
+ * a run of one of the person's other computers, else the computer its record names (#1648).
28
+ */
29
+ computer?: {
30
+ name: string;
31
+ kind?: MachineKind;
32
+ };
26
33
  }
27
34
  /** One recently active project, most-recent first. */
28
35
  export interface RecentProject {
@@ -47,7 +54,8 @@ export interface RecentAgent {
47
54
  }
48
55
  /** Injectable reader so {@link buildRecentAgents} is unit-testable off disk. */
49
56
  export interface RecentAgentsDeps {
50
- agents?: (cwd: string) => Promise<AgentMeta[]>;
57
+ /** A project's runs: off its folder for one of this computer's, as its computer says them for another's. */
58
+ agents?: (project: ProjectSummary) => Promise<AgentMeta[]>;
51
59
  }
52
60
  /**
53
61
  * Every project's sessions pooled and sorted newest-first (capped), so the shared sidebar (#shared-
@@ -65,13 +73,20 @@ export interface OverviewDeps {
65
73
  /** Whether the bridge holds a question for that cloud session (default: the daemon's bridge store). */
66
74
  waiting?: (sessionId: string) => boolean;
67
75
  now?: () => number;
76
+ /**
77
+ * The runs the person's other computers say they run of a project, each marked with the saved
78
+ * machine it is (`remoteLabel`): of a project this computer has too, and of one only they have.
79
+ */
80
+ machineRuns?: (project: ProjectSummary) => Promise<AgentMeta[]>;
68
81
  /** This machine's hostname; `node:os` in production. */
69
82
  host?: string;
70
83
  }
71
84
  /**
72
85
  * Build the cross-project Overview: the running agents (every live agent of each project, one per
73
- * worktree since #736), the total of open queue entries (from {@link collectQueue}), and the most
74
- * recently active projects (by {@link ProjectSummary.lastActivityAt}). Forgiving — a project
86
+ * worktree since #736, and every run the person's other computers say is running), the total of
87
+ * open queue entries (from {@link collectQueue}), and the most recently active projects (by
88
+ * {@link ProjectSummary.lastActivityAt}). A project of another computer's ({@link ProjectSummary.machine})
89
+ * has no folder here: only what its computer says of its runs is read. Forgiving — a project
75
90
  * with no live run, or none running, simply contributes nothing to `active`.
76
91
  */
77
92
  export declare function buildOverview(projects: ProjectSummary[], deps?: OverviewDeps): Promise<Overview>;
@@ -12,8 +12,15 @@ import { type GitHostFor } from '../store/git-host.js';
12
12
  export interface ProjectSummary {
13
13
  /** Registry id (stable, URL-safe). */
14
14
  id: string;
15
- /** Absolute repo path. */
15
+ /** Absolute repo path: on the computer the project is on. */
16
16
  path: string;
17
+ /**
18
+ * The saved machine the project is on, when it is not on this computer (elsewhere.ts): what the
19
+ * page asks of it is asked there, and a run of it starts there unless another computer is picked.
20
+ */
21
+ machine?: string;
22
+ /** The packages that bring a module's pages to a project of another computer's, as that computer said them. */
23
+ modules?: string[];
17
24
  /** Display name (the path's basename). */
18
25
  name: string;
19
26
  /** True when the repo still has its `.openagent/` marker. */
@@ -56,10 +63,12 @@ export interface SummarizeDeps {
56
63
  readAgents?: (path: string) => Promise<AgentMeta[]>;
57
64
  /** The project's git host. Defaults to {@link projectGitHost}. */
58
65
  gitHost?: GitHostFor;
66
+ /** The project's name. Defaults to {@link projectNameOf}: its repository's. */
67
+ name?: (path: string) => Promise<string>;
59
68
  }
60
69
  /** A project's runs, live prepended to the archived history. Forgiving: a failed read is `[]`. */
61
70
  /**
62
- * Derive a {@link ProjectSummary} from a registry record: its display name, whether
71
+ * Derive a {@link ProjectSummary} from a registry record: its name (its repository's), whether
63
72
  * it is still activated, and its last activity. Forgiving: a failed read reads as an
64
73
  * inactive project with no activity, never a throw.
65
74
  *
@@ -1,4 +1,7 @@
1
1
  import type { IncomingMessage, ServerResponse } from 'node:http';
2
+ import { type OwnProject } from './elsewhere.js';
3
+ import type { MachinesQueue } from './machine-interventions.js';
4
+ import type { ProjectSummary } from './projects.js';
2
5
  import type { OpenAgentEvent } from '../events.js';
3
6
  import type { PreferencesStore } from '../registry.js';
4
7
  import type { QuotaSource } from './quota.js';
@@ -7,7 +10,7 @@ import type { BridgeBrowserOwner } from '../bridge-browser.js';
7
10
  import type { ProjectErrorsReader } from '../project-errors.js';
8
11
  import type { AddProjectResult, RemoveProjectResult, StartAgentOptions, StartAgentResult, StartedInResult } from './types.js';
9
12
  import type { AgentMeta } from '../store/index.js';
10
- import type { RemoteTarget } from './remote-run.js';
13
+ import type { BringProject, RelayProject, RemoteTarget } from './remote-run.js';
11
14
  import type { MachineRuns } from './machine-runs.js';
12
15
  /** Wired by the daemon so `sendStart` can reach the daemon's own `startAgent` closure. */
13
16
  export type StartAgentHandler = (prompt: string, options: StartAgentOptions, projectId?: string) => StartAgentResult | Promise<StartAgentResult>;
@@ -58,6 +61,23 @@ export interface RemoteAgents {
58
61
  machineRuns(projectPath: string): Promise<MachineRuns[]>;
59
62
  /** Tell `changed` each time a saved machine's runs of the project at `projectPath` change, until the answer is called. */
60
63
  followRuns(projectPath: string, changed: () => void): () => void;
64
+ /** The projects of the person's other computers that this one does not have, each marked with the saved machine it is on (elsewhere.ts). */
65
+ elsewhere(): Promise<ProjectSummary[]>;
66
+ /** What the computer another computer's project is on says of its own runs of it, followed for a while from now on. */
67
+ elsewhereRuns(projectId: string): Promise<MachineRuns[]>;
68
+ /** Tell `changed` each time the runs of another computer's project change there, until the answer is called. */
69
+ followElsewhereRuns(projectId: string, changed: () => void): () => void;
70
+ /** Another computer's project by its id here: the saved machine it is on, and the project as that computer said it. */
71
+ elsewhereHome(projectId: string): Promise<{
72
+ machine: string;
73
+ project: OwnProject;
74
+ } | undefined>;
75
+ /** Make a page's call about another computer's project on that computer, and answer what it answered. */
76
+ forward(projectId: string, fn: string, args: unknown[]): Promise<unknown>;
77
+ /** What the person's other computers say of their Human Queues, each named as its project is here (machine-interventions.ts). */
78
+ machinesQueue(): Promise<MachinesQueue>;
79
+ /** Where this computer's copy of the project at `address` stands; with `bring`, cloned and added when there is none, on its own. */
80
+ bringHere(address: string, bring?: BringProject): Promise<RelayProject>;
61
81
  }
62
82
  /**
63
83
  * What every RPC acts through.
@@ -119,12 +119,14 @@ export interface StartAgentOptions {
119
119
  * there is none. `driver` is the coding agent the hook said runs it: what another computer that
120
120
  * follows the run shows, since the run's record stays on this one. `notThere` marks the one
121
121
  * refusal a page can do something about: the machine the run was sent to does not have the
122
- * project yet, and can clone it.
122
+ * project yet, and can clone it. `projectId` is the project the run started in, when it is not the
123
+ * one the start named: this computer's own copy of a project another computer of the person's has.
123
124
  */
124
125
  export type StartAgentResult = {
125
126
  ok: true;
126
127
  agentId: string;
127
128
  driver?: string;
129
+ projectId?: string;
128
130
  } | {
129
131
  ok: false;
130
132
  error: string;
@@ -1,7 +1,7 @@
1
1
  export { onAgents, onModuleAgents, onAgent, onAgentsDoing, onDocs, onQueue, onOverview, onRecentAgents, onInterventions, onActivity, onDashboard, onGitHostHome, onRepositoryOffer, onGitStatus, onProjectFiles, onRetainedWorktrees, onAgentWorktree, onAgentHandoff, onBridgeQuestion, onBridgeStatus, onBridgeToken, onBridgeEvents, onBridgeAnswer, onBridgeBrowser } from './reads.js';
2
2
  export { sendStop, sendChoice, sendBridgeAnswer, sendBridgeAnswerCancel, sendBridgeBrowser, sendMessage, sendStart, sendOpenInApp, sendRemoveWorktree, sendDeleteAgent, sendOpenPullRequest, sendPush, sendMergeBranch, sendMerge, sendCreateRepository } from './control.js';
3
3
  export { streamAgentEvents, type LiveFeedEvent, type PartialMessage, type StreamSync } from './events.js';
4
- export { onProjects, sendAddProject, sendStartedAgain, onCloneTarget, sendAddProjectFromAddress, sendRemoveProject, onRecordsReach, sendShareRecords, sendPickProjectDirectory, onOnboarding, onCommands, onStartCheck, type ProjectLauncher } from './projects.js';
4
+ export { onProjects, sendAddProject, sendStartedAgain, onCloneTarget, sendAddProjectFromAddress, sendRemoveProject, onRecordsReach, sendShareRecords, sendPickProjectDirectory, onOnboarding, onCommands, onStartCheck, onCloneCheck, type ProjectLauncher } from './projects.js';
5
5
  export { onPreferences, savePreferences, patchPreferences, onProjectPresets, saveProjectPresets, onEditors, type SavePreferencesResult, type PatchPreferencesResult, } from './preferences.js';
6
6
  export { type EditorInfo } from '../dashboard/open-in-app.js';
7
7
  export { onQuota } from './quota.js';
@@ -1,6 +1,7 @@
1
1
  import { type Health } from '../health.js';
2
2
  import { type MachineLogins } from '../dashboard/machine-logins.js';
3
3
  import { type StartReadiness } from '../project-hooks.js';
4
+ import type { ModelsView } from '../dashboard/models.js';
4
5
  /** A saved machine as the browser sees it: no key. */
5
6
  export interface Machine {
6
7
  id: string;
@@ -211,8 +212,22 @@ export declare function sendProjectToMachine(projectId: string, machineId: strin
211
212
  export declare function onProjectOnMachine(projectId: string, machineId: string): Promise<ProjectOnMachine>;
212
213
  /**
213
214
  * What would stop a run sent to a saved machine, as the machine says from its own copy of the
214
- * project: its coding agent there, installed and logged in. `null` when there is nothing to say:
215
- * a machine that does not answer, does not have the project yet (it clones it at the first run),
216
- * or has no check.
215
+ * project: its coding agent there, installed and logged in. A machine that does not have the
216
+ * project yet clones it at the first run, and says before it whether it could: its coding agent,
217
+ * and whether its logins read the repository. `null` when there is nothing to say: a machine that
218
+ * does not answer, or one with no check.
217
219
  */
218
220
  export declare function onMachineStartCheck(projectId: string, machineId: string, driver?: string): Promise<StartReadiness | null>;
221
+ /**
222
+ * The models each coding agent offers on a saved machine, as it asked its own: a run sent there is
223
+ * given one of these. `null` when it does not answer, or runs an OpenAgent that is not asked this.
224
+ */
225
+ export declare function onMachineModels(machineId: string): Promise<ModelsView | null>;
226
+ /**
227
+ * Have this computer clone a project only another computer of the person's has (elsewhere.ts),
228
+ * for a run here: on its own, as for a machine that is sent a run. {@link onProjectHere} says when
229
+ * it is here. Nothing happens when it is here already, or on its way.
230
+ */
231
+ export declare function sendProjectHere(projectId: string): Promise<ProjectOnMachine>;
232
+ /** Whether this computer has another computer's project by now, or why it will not. */
233
+ export declare function onProjectHere(projectId: string): Promise<ProjectOnMachine>;
@@ -3,8 +3,15 @@ import { type BranchReach } from '@openagt/agent-data';
3
3
  import { type StartReadiness } from '../project-hooks.js';
4
4
  import { type PickDirectoryResult } from '../pick-directory.js';
5
5
  import type { ProjectSummary } from '../dashboard/projects.js';
6
+ import type { OwnProject } from '../dashboard/elsewhere.js';
6
7
  import type { AddProjectResult, OnboardingSuggestion, RemoveProjectResult, StartedInResult } from '../dashboard/types.js';
7
8
  export declare function onProjects(): Promise<ProjectSummary[]>;
9
+ /**
10
+ * This computer's own projects, for another computer of the person's that lists them beside its
11
+ * own (elsewhere.ts): each with the address another computer names it by and clones it from, and
12
+ * whether its agents' records are shared. Never the projects this computer lists of others.
13
+ */
14
+ export declare function onOwnProjects(): Promise<OwnProject[]>;
8
15
  /**
9
16
  * Add a project from the dashboard (#396/#433): install the repo and register it so it joins the
10
17
  * Projects list. Like `sendStart` this needs the daemon (it spawns git + writes the shared
@@ -110,3 +117,10 @@ export declare function onCommands(projectId: string): Promise<ProjectLauncher |
110
117
  * `null` for an unknown project or one without a check hook: nothing to say.
111
118
  */
112
119
  export declare function onStartCheck(projectId: string, driver?: string): Promise<StartReadiness | null>;
120
+ /**
121
+ * What would stop a run of a project this computer clones first, asked before it does: its coding
122
+ * agent, installed and logged in, and whether its logins read the repository at the address. A
123
+ * computer that does not have the project yet has no check hook of it to run. `as` is what the
124
+ * asker calls this computer, so the words read right on its page.
125
+ */
126
+ export declare function onCloneCheck(address: string, driver?: string, as?: string): Promise<StartReadiness>;
@@ -173,6 +173,12 @@ export declare function onRecentAgents(): Promise<RecentAgent[]>;
173
173
  * backlog the moment the git host answers.
174
174
  */
175
175
  export declare function onInterventions(): Promise<ProjectionRead<Intervention>>;
176
+ /**
177
+ * This computer's own Human Queue, for another computer of the person's that shows it beside its
178
+ * own (machine-interventions.ts): the items of this computer's projects only, never of the
179
+ * projects it lists of other computers, so no computer asks back the one that asked it.
180
+ */
181
+ export declare function onOwnInterventions(): Promise<ProjectionRead<Intervention>>;
176
182
  /**
177
183
  * The cross-project "New activity" feed (#627): recent run started/finished transitions, newest
178
184
  * first, with the projects that were read whole beside them (#1625) — see {@link onInterventions}.
@@ -0,0 +1,28 @@
1
+ /** The names a relay caller may invoke. */
2
+ export declare const RELAY_RPC_NAMES: readonly string[];
3
+ /**
4
+ * The calls a page makes about another computer's project (elsewhere.ts) that this computer passes
5
+ * on to that computer as they are: every relayed one but a start, which goes where "Run on" says,
6
+ * and a computer's own runs, which only a computer asks for.
7
+ */
8
+ export declare const ELSEWHERE_FORWARDED: ReadonlySet<string>;
9
+ /** Whether a relayed RPC only reads. A name that is not on the whitelist is no read. */
10
+ export declare function isRelayRead(fn: string): boolean;
11
+ /**
12
+ * Whether one relayed call only reads, here: a read by its name, or a module's command that its
13
+ * package says only reads, as this computer's own copy of the module says it. The caller's word
14
+ * for it counts for nothing: a server holding this computer's key could call any command a read.
15
+ */
16
+ export declare function isRelayReadCall(projectId: string, fn: string, args: readonly unknown[]): Promise<boolean>;
17
+ /**
18
+ * Dispatch one relayed RPC against `projectId` (this machine's own id for the project). `args[0]`
19
+ * from the caller is the remote daemon's project id and is meaningless here, so it is replaced
20
+ * with `projectId`; the rest (path, agentId, ...) carry through unchanged. Throws on an unknown name.
21
+ */
22
+ export declare function dispatchRelayRpc(projectId: string, fn: string, args: unknown[]): Promise<unknown>;
23
+ /** The machine-wide names a relay caller may invoke. */
24
+ export declare const MACHINE_RPC_NAMES: readonly string[];
25
+ /** Whether a machine-wide call only reads. A name that is not on the whitelist is no read. */
26
+ export declare function isMachineRead(fn: string): boolean;
27
+ /** Dispatch one machine-wide call, its arguments as the caller gave them. Throws on an unknown name. */
28
+ export declare function dispatchMachineRpc(fn: string, args: unknown[]): Promise<unknown>;
@@ -20,7 +20,20 @@ export interface ProjectModule {
20
20
  bins: Record<string, string>;
21
21
  /** The module's server part, an absolute path inside the package, when it has one. */
22
22
  server?: string;
23
+ /**
24
+ * The commands that only read, by command name: the first word of the arguments, or `""` for
25
+ * the command with no word (flags only). What a computer that lets its server only watch answers
26
+ * of the module; any other command changes something there, and is refused. The package says
27
+ * them: `"openagent": { "reads": { "<command>": ["list", ""] } }`.
28
+ */
29
+ reads: Record<string, string[]>;
23
30
  }
31
+ /**
32
+ * Whether running the module's command with these arguments only reads, as its package says
33
+ * ({@link ProjectModule.reads}): its first word is a read, or it has no word and its bare form is
34
+ * one, every argument then being a flag.
35
+ */
36
+ export declare function commandReads(module: Pick<ProjectModule, 'bins' | 'reads'>, args: readonly unknown[], command?: string): boolean;
24
37
  /**
25
38
  * The modules a project has: each of its dependencies whose package.json exports `./dashboard` to
26
39
  * a file that exists inside the package, plus the modules among the packages OpenAgent brings to
@@ -37,6 +50,12 @@ export declare function findProjectModule(root: string, name: string): Promise<P
37
50
  export declare function readComputerModules(): Promise<ProjectModule[]>;
38
51
  /** The one module of this computer's that `name` names, or undefined. */
39
52
  export declare function findComputerModule(name: string): Promise<ProjectModule | undefined>;
53
+ /**
54
+ * The module of a package OpenAgent brings to projects, from OpenAgent's own copy: the page of
55
+ * another computer's project, on a computer where no project of its own has it. Undefined for any
56
+ * other package.
57
+ */
58
+ export declare function findBroughtModule(name: string): Promise<ProjectModule | undefined>;
40
59
  /**
41
60
  * The file a module serves at `rel`, a path relative to its module's directory: its module, its
42
61
  * stylesheet, a chunk. `undefined` for a path that leaves that directory (symlinks resolved) or
@@ -1,5 +1,6 @@
1
1
  import { type OverviewLayouts } from './overview-layout.js';
2
2
  import { type PublishPick } from './publish-levels.js';
3
+ import { type OwnProject } from './dashboard/elsewhere.js';
3
4
  /**
4
5
  * The multi-project registry (#390): the list of projects the user has
5
6
  * installed OpenAgent into, kept as a single JSON file `.bashrc`-style —
@@ -58,6 +59,8 @@ export interface MachineRecord {
58
59
  listed?: string[];
59
60
  /** When the machine last answered for its runs, ISO, kept to the minute: what its runs say while it does not answer. */
60
61
  seenAt?: string;
62
+ /** Its own projects, as it said them last (elsewhere.ts): a computer of the person's own lists them while it does not answer. */
63
+ projects?: OwnProject[];
61
64
  }
62
65
  /** A GitHub account's name: letters, digits and single dashes, at most 39. */
63
66
  export declare function isAccount(value: unknown): value is string;
@@ -348,6 +351,11 @@ export declare function noteSeen(machine: {
348
351
  id: string;
349
352
  key: string;
350
353
  }, at: string, fs?: RegistryFs, env?: NodeJS.ProcessEnv): Promise<void>;
354
+ /** Keep what a saved machine said of its own projects: the same machine, by its key, or nothing is written. */
355
+ export declare function noteProjects(machine: {
356
+ id: string;
357
+ key: string;
358
+ }, projects: OwnProject[], fs?: RegistryFs, env?: NodeJS.ProcessEnv): Promise<void>;
351
359
  /** Write down that the person was told their logins are copied to a saved machine of another person's. Answers whether it is saved. */
352
360
  export declare function tellMachine(id: string, fs?: RegistryFs, env?: NodeJS.ProcessEnv): Promise<boolean>;
353
361
  /** Say whether a saved server uses this computer's logins. Answers whether it is saved. */
@@ -26,5 +26,11 @@ export declare function spellingOfRemote(remote: string): string | undefined;
26
26
  * machine only.
27
27
  */
28
28
  export declare function repositoryAddress(cwd: string, git?: GitRunner): Promise<string | undefined>;
29
+ /**
30
+ * A project's name: its repository's, the last part of its address in the letters `origin` writes
31
+ * it with, so the project reads the same on every computer whatever its folder there is called.
32
+ * A project with no address is its folder's.
33
+ */
34
+ export declare function projectNameOf(cwd: string, git?: GitRunner): Promise<string>;
29
35
  /** The same address in the letters the `origin` remote is written with: see {@link spellingOfRemote}. */
30
36
  export declare function repositorySpelling(cwd: string, git?: GitRunner): Promise<string | undefined>;