@openagt/dashboard 0.38.0 → 0.39.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 (139) hide show
  1. package/dist/daemon-runtime.d.ts.map +1 -1
  2. package/dist/daemon-runtime.js +30 -4
  3. package/dist/daemon-runtime.js.map +1 -1
  4. package/dist/daemon.d.ts.map +1 -1
  5. package/dist/daemon.js +2 -1
  6. package/dist/daemon.js.map +1 -1
  7. package/dist/dashboard/compress.d.ts +13 -1
  8. package/dist/dashboard/compress.d.ts.map +1 -1
  9. package/dist/dashboard/compress.js +16 -1
  10. package/dist/dashboard/compress.js.map +1 -1
  11. package/dist/dashboard/machine-runs.d.ts +41 -8
  12. package/dist/dashboard/machine-runs.d.ts.map +1 -1
  13. package/dist/dashboard/machine-runs.js +132 -34
  14. package/dist/dashboard/machine-runs.js.map +1 -1
  15. package/dist/dashboard/module-agents.d.ts +44 -0
  16. package/dist/dashboard/module-agents.d.ts.map +1 -0
  17. package/dist/dashboard/module-agents.js +25 -0
  18. package/dist/dashboard/module-agents.js.map +1 -0
  19. package/dist/dashboard/module-serve.d.ts +10 -1
  20. package/dist/dashboard/module-serve.d.ts.map +1 -1
  21. package/dist/dashboard/module-serve.js +25 -6
  22. package/dist/dashboard/module-serve.js.map +1 -1
  23. package/dist/dashboard/relay-endpoints.d.ts +8 -4
  24. package/dist/dashboard/relay-endpoints.d.ts.map +1 -1
  25. package/dist/dashboard/relay-endpoints.js +36 -7
  26. package/dist/dashboard/relay-endpoints.js.map +1 -1
  27. package/dist/dashboard/remote-run.d.ts +3 -2
  28. package/dist/dashboard/remote-run.d.ts.map +1 -1
  29. package/dist/dashboard/remote-run.js +6 -5
  30. package/dist/dashboard/remote-run.js.map +1 -1
  31. package/dist/dashboard/rpc-serve.d.ts +6 -3
  32. package/dist/dashboard/rpc-serve.d.ts.map +1 -1
  33. package/dist/dashboard/rpc-serve.js +33 -2
  34. package/dist/dashboard/rpc-serve.js.map +1 -1
  35. package/dist/dashboard/runs-watch.d.ts +32 -0
  36. package/dist/dashboard/runs-watch.d.ts.map +1 -0
  37. package/dist/dashboard/runs-watch.js +89 -0
  38. package/dist/dashboard/runs-watch.js.map +1 -0
  39. package/dist/dashboard/server.d.ts +4 -2
  40. package/dist/dashboard/server.d.ts.map +1 -1
  41. package/dist/dashboard/server.js +1 -1
  42. package/dist/dashboard/server.js.map +1 -1
  43. package/dist/dashboard/static.js +6 -6
  44. package/dist/dashboard/static.js.map +1 -1
  45. package/dist/dashboard-bundle/assets/host/module-CUc1n2SP.js +1 -0
  46. package/dist/dashboard-bundle/assets/host/react-B7Fi4tYT.js +1 -0
  47. package/dist/dashboard-bundle/assets/host/react-dom-client-owmMVl4T.js +1 -0
  48. package/dist/dashboard-bundle/assets/host/react-dom-oeGwGKD7.js +1 -0
  49. package/dist/dashboard-bundle/assets/host/react-jsx-runtime-Dxx08tyw.js +1 -0
  50. package/dist/dashboard-bundle/assets/main-Cv9CrCec.css +2 -0
  51. package/dist/dashboard-bundle/assets/main-dejlwmyP.js +149 -0
  52. package/dist/dashboard-bundle/assets/{module-D0SUS0dF.js → module-DR2oCWs5.js} +5 -5
  53. package/dist/dashboard-bundle/index.html +8 -8
  54. package/dist/dashboard-rpc/context.js +1 -1
  55. package/dist/dashboard-rpc/context.js.map +1 -1
  56. package/dist/dashboard-rpc/index.d.ts +2 -2
  57. package/dist/dashboard-rpc/index.d.ts.map +1 -1
  58. package/dist/dashboard-rpc/index.js +2 -2
  59. package/dist/dashboard-rpc/index.js.map +1 -1
  60. package/dist/dashboard-rpc/machines.d.ts +8 -0
  61. package/dist/dashboard-rpc/machines.d.ts.map +1 -1
  62. package/dist/dashboard-rpc/machines.js +25 -3
  63. package/dist/dashboard-rpc/machines.js.map +1 -1
  64. package/dist/dashboard-rpc/modules.d.ts +9 -9
  65. package/dist/dashboard-rpc/modules.d.ts.map +1 -1
  66. package/dist/dashboard-rpc/modules.js +14 -13
  67. package/dist/dashboard-rpc/modules.js.map +1 -1
  68. package/dist/dashboard-rpc/reads.d.ts +11 -2
  69. package/dist/dashboard-rpc/reads.d.ts.map +1 -1
  70. package/dist/dashboard-rpc/reads.js +42 -5
  71. package/dist/dashboard-rpc/reads.js.map +1 -1
  72. package/dist/dashboard-rpc/relay-dispatch.d.ts +6 -0
  73. package/dist/dashboard-rpc/relay-dispatch.d.ts.map +1 -1
  74. package/dist/dashboard-rpc/relay-dispatch.js +24 -1
  75. package/dist/dashboard-rpc/relay-dispatch.js.map +1 -1
  76. package/dist/dashboard-rpc/runs-changed.d.ts +8 -0
  77. package/dist/dashboard-rpc/runs-changed.d.ts.map +1 -0
  78. package/dist/dashboard-rpc/runs-changed.js +62 -0
  79. package/dist/dashboard-rpc/runs-changed.js.map +1 -0
  80. package/dist/dashboard-rpc/test-context.js +1 -1
  81. package/dist/dashboard-rpc/test-context.js.map +1 -1
  82. package/dist/module-types/dashboard/lib/use-async.d.ts +24 -6
  83. package/dist/module-types/dashboard/lib/use-modules.d.ts +4 -2
  84. package/dist/module-types/dashboard/module/index.d.ts +8 -31
  85. package/dist/module-types/src/dashboard/compress.d.ts +13 -1
  86. package/dist/module-types/src/dashboard/machine-runs.d.ts +41 -8
  87. package/dist/module-types/src/dashboard/module-agents.d.ts +43 -0
  88. package/dist/module-types/src/dashboard/module-serve.d.ts +10 -1
  89. package/dist/module-types/src/dashboard/remote-run.d.ts +3 -2
  90. package/dist/module-types/src/dashboard/rpc-serve.d.ts +6 -3
  91. package/dist/module-types/src/dashboard/runs-watch.d.ts +31 -0
  92. package/dist/module-types/src/dashboard-rpc/index.d.ts +2 -2
  93. package/dist/module-types/src/dashboard-rpc/machines.d.ts +8 -0
  94. package/dist/module-types/src/dashboard-rpc/modules.d.ts +9 -9
  95. package/dist/module-types/src/dashboard-rpc/reads.d.ts +11 -2
  96. package/dist/module-types/src/dashboard-rpc/runs-changed.d.ts +7 -0
  97. package/dist/module-types/src/project-hooks.d.ts +11 -1
  98. package/dist/module-types/src/store/branches.d.ts +2 -2
  99. package/dist/module-types/src/store/git-host.d.ts +2 -2
  100. package/dist/module-types/src/store/provided.d.ts +5 -4
  101. package/dist/module-types/src/store/queue.d.ts +3 -2
  102. package/dist/module-types/src/store/runs.d.ts +3 -2
  103. package/dist/module-types/src/store/tickets.d.ts +3 -2
  104. package/dist/project-hooks.d.ts +11 -1
  105. package/dist/project-hooks.d.ts.map +1 -1
  106. package/dist/project-hooks.js +21 -11
  107. package/dist/project-hooks.js.map +1 -1
  108. package/dist/store/branches.d.ts +2 -2
  109. package/dist/store/branches.d.ts.map +1 -1
  110. package/dist/store/branches.js +8 -2
  111. package/dist/store/branches.js.map +1 -1
  112. package/dist/store/git-host.d.ts +2 -2
  113. package/dist/store/git-host.d.ts.map +1 -1
  114. package/dist/store/git-host.js +7 -2
  115. package/dist/store/git-host.js.map +1 -1
  116. package/dist/store/provided.d.ts +5 -4
  117. package/dist/store/provided.d.ts.map +1 -1
  118. package/dist/store/provided.js +10 -9
  119. package/dist/store/provided.js.map +1 -1
  120. package/dist/store/queue.d.ts +3 -2
  121. package/dist/store/queue.d.ts.map +1 -1
  122. package/dist/store/queue.js +9 -2
  123. package/dist/store/queue.js.map +1 -1
  124. package/dist/store/runs.d.ts +3 -2
  125. package/dist/store/runs.d.ts.map +1 -1
  126. package/dist/store/runs.js +9 -2
  127. package/dist/store/runs.js.map +1 -1
  128. package/dist/store/tickets.d.ts +3 -2
  129. package/dist/store/tickets.d.ts.map +1 -1
  130. package/dist/store/tickets.js +9 -2
  131. package/dist/store/tickets.js.map +1 -1
  132. package/package.json +22 -22
  133. package/dist/dashboard-bundle/assets/main-BrPlt--h.js +0 -149
  134. package/dist/dashboard-bundle/assets/main-DgwPb5zO.css +0 -2
  135. package/dist/dashboard-bundle/host/module.js +0 -1
  136. package/dist/dashboard-bundle/host/react-dom-client.js +0 -1
  137. package/dist/dashboard-bundle/host/react-dom.js +0 -1
  138. package/dist/dashboard-bundle/host/react-jsx-runtime.js +0 -1
  139. package/dist/dashboard-bundle/host/react.js +0 -1
@@ -1,4 +1,12 @@
1
1
  import { isRunId } from '../store/index.js';
2
+ /**
3
+ * What a list shows of a run, as one string to compare: what it is, how it stands, and its name.
4
+ * A run's card is written at every step it takes, with a later time and a higher cost, and none
5
+ * of that is a change a person waits on.
6
+ */
7
+ export function shownOf(run) {
8
+ return JSON.stringify([run.id, run.status, run.title, run.branch, run.pr?.number, run.endedAt]);
9
+ }
2
10
  /**
3
11
  * A computer's own runs, counted as they change, per project: each answer says where it leaves
4
12
  * the asker, and the next holds what changed after that. A count from before this OpenAgent
@@ -8,22 +16,47 @@ export class RunChanges {
8
16
  started = Math.random().toString(36).slice(2, 10);
9
17
  projects = new Map();
10
18
  answer(project, runs, since) {
11
- let known = this.projects.get(project);
12
- if (!known)
13
- this.projects.set(project, (known = { count: 0, seen: new Map() }));
19
+ const known = this.known(project);
14
20
  const ids = new Set();
15
21
  for (const run of runs) {
16
22
  ids.add(run.id);
17
23
  const said = JSON.stringify(run);
18
- if (known.seen.get(run.id)?.said !== said)
19
- known.seen.set(run.id, { said, at: ++known.count });
24
+ const before = known.seen.get(run.id);
25
+ if (before?.said === said)
26
+ continue;
27
+ const at = ++known.count;
28
+ const shown = shownOf(run);
29
+ known.seen.set(run.id, { said, at, shown, shownAt: before?.shown === shown ? before.shownAt : at });
30
+ }
31
+ // A run gone is a change too: an answer after it says so by its ids.
32
+ for (const id of known.seen.keys()) {
33
+ if (ids.has(id))
34
+ continue;
35
+ known.seen.delete(id);
36
+ known.goneAt = ++known.count;
20
37
  }
21
- for (const id of known.seen.keys())
22
- if (!ids.has(id))
23
- known.seen.delete(id);
24
38
  const after = this.countOf(since, known.count);
25
39
  return { at: `${this.started}.${known.count}`, runs: after === undefined ? [...runs] : runs.filter(run => known.seen.get(run.id).at > after), ids: [...ids] };
26
40
  }
41
+ /** Whether what a list shows of the runs changed after `since`, as of the last answer: a count not of this OpenAgent's says so. */
42
+ shownSince(project, since) {
43
+ const known = this.known(project);
44
+ const after = this.countOf(since, known.count);
45
+ if (after === undefined)
46
+ return true;
47
+ if (known.goneAt > after)
48
+ return true;
49
+ for (const run of known.seen.values())
50
+ if (run.shownAt > after)
51
+ return true;
52
+ return false;
53
+ }
54
+ known(project) {
55
+ let known = this.projects.get(project);
56
+ if (!known)
57
+ this.projects.set(project, (known = { count: 0, seen: new Map(), goneAt: 0 }));
58
+ return known;
59
+ }
27
60
  countOf(since, count) {
28
61
  if (typeof since !== 'string')
29
62
  return undefined;
@@ -66,10 +99,20 @@ export function withMachineRuns(records, machines) {
66
99
  return { ...run, status: 'unknown', ...(machine.seenAt !== undefined ? { seenAt: machine.seenAt } : {}) };
67
100
  });
68
101
  }
69
- /** How long a machine's answer stands before it is asked again: a page asks every few seconds. */
70
- const KEPT_MS = 5_000;
102
+ /**
103
+ * How long a computer holds a call for its runs when nothing a list shows changed since it last
104
+ * answered: it answers at the first such change, else with what else changed once this is up, and
105
+ * is asked again.
106
+ */
107
+ export const RUNS_WAIT_MS = 25_000;
108
+ /** How long a machine's runs of a project are followed after a page last asked for them. */
109
+ const WANTED_MS = 60_000;
71
110
  /** How long a machine that did not answer is left before it is asked again. */
72
111
  const UNANSWERED_MS = 10_000;
112
+ /** The least time between two asks of one machine for one project. */
113
+ const ASK_GAP_MS = 1_000;
114
+ /** How long a machine that answered at once with no change a list shows is left: it does not hold the call, and is asked as a page reads. */
115
+ const HELD_NOT_MS = 5_000;
73
116
  /** How long a list waits for a machine's first answer: one that is off does not hold a page. */
74
117
  const FIRST_WAIT_MS = 1_500;
75
118
  /** How many machine-and-project answers are kept before the memory starts over. */
@@ -85,70 +128,125 @@ function runOf(value, host) {
85
128
  return run.host === host ? run : undefined;
86
129
  }
87
130
  /**
88
- * What each saved machine said last of its runs of a project, asked again behind the page once
89
- * its answer is a few seconds old: a page is answered at once with what is known, and waits only
90
- * for a machine's first answer, and not long. One ask at a time per machine and project; each
91
- * holds only what changed since the one before ({@link OwnRuns}).
131
+ * What each saved machine says of its runs of a project, followed while a page wants them: one call
132
+ * to each machine is kept open, which the machine answers when its runs change
133
+ * ({@link RUNS_WAIT_MS}), and asked again at once from where the answer left off ({@link OwnRuns}).
134
+ * So what is kept is what the machine says now, and whoever listens to the project's address is
135
+ * told the moment it changes. A page is answered at once with what is known, and waits only for a
136
+ * machine's first answer, and not long.
92
137
  */
93
138
  export class MachineRunsKept {
94
139
  ask;
95
140
  seen;
96
141
  now;
142
+ pause;
97
143
  kept = new Map();
144
+ listeners = new Map();
98
145
  constructor(
99
- /** Ask the machine for its runs of the project at `address`, since what it answered last. */
146
+ /** Ask the machine for its runs of the project at `address`, since what it answered last: it answers when they change. */
100
147
  ask,
101
148
  /** Told each time a machine answered. */
102
- seen = () => { }, now = Date.now) {
149
+ seen = () => { }, now = Date.now,
150
+ /** Wait before the next ask. */
151
+ pause = ms => new Promise(done => setTimeout(done, ms).unref())) {
103
152
  this.ask = ask;
104
153
  this.seen = seen;
105
154
  this.now = now;
155
+ this.pause = pause;
106
156
  }
157
+ /** The machines' runs of the project at `address`, followed from now on for a while: a page reads them every few seconds. */
107
158
  async of(machines, address) {
108
159
  return Promise.all(machines.map(async (machine) => {
109
160
  const key = `${machine.url} ${address}`;
110
- let entry = this.kept.get(key);
111
- if (!entry) {
161
+ let found = this.kept.get(key);
162
+ if (!found) {
112
163
  if (this.kept.size >= MAX_KEPT)
113
164
  this.kept.clear();
114
- this.kept.set(key, (entry = { runs: new Map(), answered: false, until: 0 }));
115
- }
116
- const first = entry.until === 0;
117
- if (entry.until <= this.now()) {
118
- const held = entry;
119
- held.asking ??= this.askAgain(machine, address, held).finally(() => (held.asking = undefined));
165
+ this.kept.set(key, (found = { runs: new Map(), answered: false, asked: false, wanted: 0 }));
120
166
  }
121
- if (first && entry.asking)
122
- await Promise.race([entry.asking, new Promise(done => setTimeout(done, FIRST_WAIT_MS).unref())]);
167
+ const entry = found;
168
+ entry.wanted = this.now() + WANTED_MS;
169
+ entry.following ??= this.follow(machine, address, entry).finally(() => (entry.following = undefined));
170
+ if (!entry.asked)
171
+ await Promise.race([(entry.first ??= new Promise(done => (entry.answer = done))), new Promise(done => setTimeout(done, FIRST_WAIT_MS).unref())]);
123
172
  const seenAt = entry.seenAt ?? machine.seenAt;
124
173
  return { host: machine.host, runs: [...entry.runs.values()], answered: entry.answered, ...(seenAt !== undefined ? { seenAt } : {}) };
125
174
  }));
126
175
  }
176
+ /** Follow nothing more: each machine's call is let go once it is answered. */
177
+ stop() {
178
+ this.kept.clear();
179
+ }
180
+ /** Tell `changed` each time a machine's runs of the project at `address` change, until the answer is called. */
181
+ listen(address, changed) {
182
+ let listening = this.listeners.get(address);
183
+ if (!listening)
184
+ this.listeners.set(address, (listening = new Set()));
185
+ const listener = () => changed();
186
+ listening.add(listener);
187
+ return () => {
188
+ listening.delete(listener);
189
+ if (listening.size === 0 && this.listeners.get(address) === listening)
190
+ this.listeners.delete(address);
191
+ };
192
+ }
193
+ async follow(machine, address, entry) {
194
+ while (entry.wanted > this.now() && this.kept.get(`${machine.url} ${address}`) === entry) {
195
+ const asked = this.now();
196
+ const said = await this.askAgain(machine, address, entry);
197
+ const took = this.now() - asked;
198
+ const gap = said === 'nothing' ? UNANSWERED_MS : said === 'kept' && took < ASK_GAP_MS ? HELD_NOT_MS : ASK_GAP_MS - took;
199
+ entry.asked = true;
200
+ entry.answer?.();
201
+ if (gap > 0)
202
+ await this.pause(gap);
203
+ }
204
+ }
205
+ /** Ask once, and keep what the machine said: whether a change a list shows was told, nothing such changed, or it did not answer. */
127
206
  async askAgain(machine, address, entry) {
128
207
  try {
129
208
  const said = (await this.ask(machine, address, entry.at));
130
209
  if (!said || typeof said.at !== 'string' || !Array.isArray(said.runs) || !Array.isArray(said.ids))
131
210
  throw new Error('the machine answered something else than its runs');
211
+ // A change a list shows is told: a run's step, with its later time and higher cost, is only kept.
212
+ let changed = !entry.answered;
132
213
  for (const value of said.runs) {
133
214
  const run = runOf(value, machine.host);
134
- if (run)
135
- entry.runs.set(run.id, run);
215
+ if (!run)
216
+ continue;
217
+ const before = entry.runs.get(run.id);
218
+ if (!before || shownOf(before) !== shownOf(run))
219
+ changed = true;
220
+ entry.runs.set(run.id, run);
136
221
  }
137
222
  const ids = new Set(said.ids);
138
- for (const id of entry.runs.keys())
139
- if (!ids.has(id))
140
- entry.runs.delete(id);
223
+ for (const id of entry.runs.keys()) {
224
+ if (ids.has(id))
225
+ continue;
226
+ entry.runs.delete(id);
227
+ changed = true;
228
+ }
141
229
  entry.at = said.at;
142
230
  entry.answered = true;
143
231
  entry.seenAt = new Date(this.now()).toISOString();
144
- entry.until = this.now() + KEPT_MS;
145
232
  this.seen(machine, entry.seenAt);
233
+ if (!changed)
234
+ return 'kept';
235
+ this.tell(address);
236
+ return 'told';
146
237
  }
147
238
  catch {
148
239
  // What it said last stands, and it is asked again from where that left off.
149
- entry.answered = false;
150
- entry.until = this.now() + UNANSWERED_MS;
240
+ if (entry.answered) {
241
+ entry.answered = false;
242
+ this.tell(address);
243
+ }
244
+ return 'nothing';
151
245
  }
152
246
  }
247
+ tell(address) {
248
+ for (const listener of [...(this.listeners.get(address) ?? [])])
249
+ listener();
250
+ }
153
251
  }
154
252
  //# sourceMappingURL=machine-runs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"machine-runs.js","sourceRoot":"","sources":["../../src/dashboard/machine-runs.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"machine-runs.js","sourceRoot":"","sources":["../../src/dashboard/machine-runs.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ import type { AgentMeta, AgentStatus } from '../store/agent-store.js';
2
+ /** One run of a project, as a module sees it: what a page or a card shows of a run, and no more. */
3
+ export interface ModuleAgent {
4
+ /** The run's id, the one `ModuleHost.openAgent` takes. */
5
+ id: string;
6
+ /** The run's branch, the name the agent gave its work, when its record carries one. */
7
+ name?: string;
8
+ /** What the run was asked, as typed or as queued; absent when its record carries none. */
9
+ ask?: string;
10
+ /** How it stands: `unknown` while the computer it runs on does not answer, whatever its record last said. */
11
+ status: AgentStatus;
12
+ /** ISO 8601. */
13
+ startedAt: string;
14
+ /** ISO 8601, once it ended. */
15
+ endedAt?: string;
16
+ /** Its short name, as a list of runs shows it. */
17
+ title?: string;
18
+ /** Whose run it is, by the email its record is kept under. */
19
+ person?: string;
20
+ /** What it cost so far, in US dollars. */
21
+ cost?: number;
22
+ /** The coding agent that runs it (`claude-code`, `codex`, …) and its model. */
23
+ driver?: string;
24
+ model?: string;
25
+ /** The saved machine it runs on, by the name it was given; absent for a run of this computer's. */
26
+ machine?: string;
27
+ /** While its status is `unknown`: when its computer was last seen, ISO, if it was. */
28
+ seenAt?: string;
29
+ }
30
+ /**
31
+ * Which of a project's runs a module asks for, when not all of them: a project keeps every run it
32
+ * ever made, hundreds, and a card shows a few. Both given, a run must be both.
33
+ */
34
+ export interface ModuleAgentsWanted {
35
+ /** These runs only, by id: the ones holding a claim. */
36
+ ids?: string[];
37
+ /** The runs started at this time or later, ISO 8601: the last 30 days. */
38
+ since?: string;
39
+ }
40
+ /** A run as a module sees it. */
41
+ export declare function moduleAgentOf(agent: AgentMeta): ModuleAgent;
42
+ /** The runs a module asked for, as it sees them. */
43
+ export declare function moduleAgents(agents: readonly AgentMeta[], wanted?: ModuleAgentsWanted): ModuleAgent[];
44
+ //# sourceMappingURL=module-agents.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"module-agents.d.ts","sourceRoot":"","sources":["../../src/dashboard/module-agents.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAA;AAErE,oGAAoG;AACpG,MAAM,WAAW,WAAW;IAC1B,0DAA0D;IAC1D,EAAE,EAAE,MAAM,CAAA;IACV,uFAAuF;IACvF,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,0FAA0F;IAC1F,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,6GAA6G;IAC7G,MAAM,EAAE,WAAW,CAAA;IACnB,gBAAgB;IAChB,SAAS,EAAE,MAAM,CAAA;IACjB,+BAA+B;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,kDAAkD;IAClD,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,8DAA8D;IAC9D,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,0CAA0C;IAC1C,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,+EAA+E;IAC/E,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,mGAAmG;IACnG,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,sFAAsF;IACtF,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IACjC,wDAAwD;IACxD,GAAG,CAAC,EAAE,MAAM,EAAE,CAAA;IACd,0EAA0E;IAC1E,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,iCAAiC;AACjC,wBAAgB,aAAa,CAAC,KAAK,EAAE,SAAS,GAAG,WAAW,CAgB3D;AAED,oDAAoD;AACpD,wBAAgB,YAAY,CAAC,MAAM,EAAE,SAAS,SAAS,EAAE,EAAE,MAAM,GAAE,kBAAuB,GAAG,WAAW,EAAE,CAIzG"}
@@ -0,0 +1,25 @@
1
+ /** A run as a module sees it. */
2
+ export function moduleAgentOf(agent) {
3
+ return {
4
+ id: agent.id,
5
+ status: agent.status,
6
+ startedAt: agent.startedAt,
7
+ ...(agent.branch ? { name: agent.branch } : {}),
8
+ ...(agent.intent ? { ask: agent.intent } : {}),
9
+ ...(agent.endedAt ? { endedAt: agent.endedAt } : {}),
10
+ ...(agent.title ? { title: agent.title } : {}),
11
+ ...(agent.person ? { person: agent.person } : {}),
12
+ ...(agent.cost !== undefined ? { cost: agent.cost } : {}),
13
+ ...(agent.driver ? { driver: agent.driver } : {}),
14
+ ...(agent.model ? { model: agent.model } : {}),
15
+ ...(agent.remoteLabel ? { machine: agent.remoteLabel } : {}),
16
+ ...(agent.seenAt ? { seenAt: agent.seenAt } : {}),
17
+ };
18
+ }
19
+ /** The runs a module asked for, as it sees them. */
20
+ export function moduleAgents(agents, wanted = {}) {
21
+ const ids = wanted.ids ? new Set(wanted.ids) : undefined;
22
+ const since = wanted.since !== undefined ? Date.parse(wanted.since) : undefined;
23
+ return agents.filter(agent => (!ids || ids.has(agent.id)) && (since === undefined || Date.parse(agent.startedAt) >= since)).map(moduleAgentOf);
24
+ }
25
+ //# sourceMappingURL=module-agents.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"module-agents.js","sourceRoot":"","sources":["../../src/dashboard/module-agents.ts"],"names":[],"mappings":"AA0CA,iCAAiC;AACjC,MAAM,UAAU,aAAa,CAAC,KAAgB;IAC5C,OAAO;QACL,EAAE,EAAE,KAAK,CAAC,EAAE;QACZ,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/C,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9C,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACpD,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9C,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACjD,GAAG,CAAC,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACzD,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACjD,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9C,GAAG,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5D,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAClD,CAAA;AACH,CAAC;AAED,oDAAoD;AACpD,MAAM,UAAU,YAAY,CAAC,MAA4B,EAAE,MAAM,GAAuB,EAAE;IACxF,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;IACxD,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;IAC/E,OAAO,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,KAAK,SAAS,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,aAAa,CAAC,CAAA;AAChJ,CAAC"}
@@ -9,11 +9,20 @@ export declare const COMPUTER_MODULES_PREFIX = "/_computer-modules";
9
9
  export declare function moduleUrl(projectId: string, module: Pick<ProjectModule, 'package' | 'entry'>): string;
10
10
  /** The URL the browser part of one of the computer's modules is served at. */
11
11
  export declare function computerModuleUrl(module: Pick<ProjectModule, 'package' | 'entry'>): string;
12
+ /**
13
+ * A module's URL with its entry file's version (`?v=`): a browser keeps that file for good, and
14
+ * the next version of the module is another URL. Without the file there to read, the URL as it is.
15
+ */
16
+ export declare function versionedModuleUrl(url: string, module: Pick<ProjectModule, 'dir' | 'entry'>): Promise<string>;
12
17
  /**
13
18
  * Serve one module file (#1774): the project must be registered, the package must be a module of
14
19
  * that project, and the file must sit inside the module's browser part's own directory. Anything else is a
15
20
  * 404, never a fallback: a module URL is asked for by the dashboard's loader, not typed by a person.
16
- * Served as `no-cache`, since a module is rebuilt in place under the same name.
21
+ * Asked for with the file's own version ({@link versionedModuleUrl}), it is kept for good: a page
22
+ * opened again does not ask for it at all. Otherwise it is served as `no-cache`, since a module is
23
+ * rebuilt in place under the same name (its stylesheet, a file another of its files imports, a URL
24
+ * naming a version gone since), with a tag of the file's own: a page opened again asks with it and
25
+ * is answered "not changed", with no body. Sent gzipped, a module's code being a page's largest file.
17
26
  */
18
27
  export declare function serveModuleFile(req: IncomingMessage, res: ServerResponse, pathname: string, projects?: ProjectsProvider): Promise<void>;
19
28
  /** Serve one file of a module that is the computer's: as {@link serveModuleFile}, with no project to be registered. */
@@ -1 +1 @@
1
- {"version":3,"file":"module-serve.d.ts","sourceRoot":"","sources":["../../src/dashboard/module-serve.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAEhE,OAAO,EAA2B,KAAK,gBAAgB,EAAE,MAAM,eAAe,CAAA;AAC9E,OAAO,EAAqD,KAAK,aAAa,EAAE,MAAM,uBAAuB,CAAA;AAE7G,sGAAsG;AACtG,eAAO,MAAM,cAAc,cAAc,CAAA;AAEzC,2HAA2H;AAC3H,eAAO,MAAM,uBAAuB,uBAAuB,CAAA;AAI3D,qEAAqE;AACrE,wBAAgB,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,aAAa,EAAE,SAAS,GAAG,OAAO,CAAC,GAAG,MAAM,CAErG;AAED,8EAA8E;AAC9E,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,IAAI,CAAC,aAAa,EAAE,SAAS,GAAG,OAAO,CAAC,GAAG,MAAM,CAE1F;AAUD;;;;;GAKG;AACH,wBAAsB,eAAe,CACnC,GAAG,EAAE,eAAe,EACpB,GAAG,EAAE,cAAc,EACnB,QAAQ,EAAE,MAAM,EAChB,QAAQ,GAAE,gBAA4C,GACrD,OAAO,CAAC,IAAI,CAAC,CAOf;AAED,uHAAuH;AACvH,wBAAsB,uBAAuB,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAExH"}
1
+ {"version":3,"file":"module-serve.d.ts","sourceRoot":"","sources":["../../src/dashboard/module-serve.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAIhE,OAAO,EAA2B,KAAK,gBAAgB,EAAE,MAAM,eAAe,CAAA;AAC9E,OAAO,EAAqD,KAAK,aAAa,EAAE,MAAM,uBAAuB,CAAA;AAE7G,sGAAsG;AACtG,eAAO,MAAM,cAAc,cAAc,CAAA;AAEzC,2HAA2H;AAC3H,eAAO,MAAM,uBAAuB,uBAAuB,CAAA;AAI3D,qEAAqE;AACrE,wBAAgB,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,aAAa,EAAE,SAAS,GAAG,OAAO,CAAC,GAAG,MAAM,CAErG;AAED,8EAA8E;AAC9E,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,IAAI,CAAC,aAAa,EAAE,SAAS,GAAG,OAAO,CAAC,GAAG,MAAM,CAE1F;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,aAAa,EAAE,KAAK,GAAG,OAAO,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAGnH;AAUD;;;;;;;;;GASG;AACH,wBAAsB,eAAe,CACnC,GAAG,EAAE,eAAe,EACpB,GAAG,EAAE,cAAc,EACnB,QAAQ,EAAE,MAAM,EAChB,QAAQ,GAAE,gBAA4C,GACrD,OAAO,CAAC,IAAI,CAAC,CAOf;AAED,uHAAuH;AACvH,wBAAsB,uBAAuB,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAExH"}
@@ -1,4 +1,6 @@
1
- import { readFile } from 'node:fs/promises';
1
+ import { readFile, stat } from 'node:fs/promises';
2
+ import { join } from 'node:path';
3
+ import { fileTag, fileVersion, sendBody } from './compress.js';
2
4
  import { contentTypeFor } from './content-type.js';
3
5
  import { defaultProjectsProvider } from './projects.js';
4
6
  import { findComputerModule, findProjectModule, moduleFile } from '../project-modules.js';
@@ -15,6 +17,14 @@ export function moduleUrl(projectId, module) {
15
17
  export function computerModuleUrl(module) {
16
18
  return `${COMPUTER_MODULES_PREFIX}/${encodeURIComponent(module.package)}/${encoded(module.entry)}`;
17
19
  }
20
+ /**
21
+ * A module's URL with its entry file's version (`?v=`): a browser keeps that file for good, and
22
+ * the next version of the module is another URL. Without the file there to read, the URL as it is.
23
+ */
24
+ export async function versionedModuleUrl(url, module) {
25
+ const facts = await stat(join(module.dir, module.entry)).catch(() => undefined);
26
+ return facts ? `${url}?v=${fileVersion(facts)}` : url;
27
+ }
18
28
  function decode(segment) {
19
29
  try {
20
30
  return decodeURIComponent(segment);
@@ -27,7 +37,11 @@ function decode(segment) {
27
37
  * Serve one module file (#1774): the project must be registered, the package must be a module of
28
38
  * that project, and the file must sit inside the module's browser part's own directory. Anything else is a
29
39
  * 404, never a fallback: a module URL is asked for by the dashboard's loader, not typed by a person.
30
- * Served as `no-cache`, since a module is rebuilt in place under the same name.
40
+ * Asked for with the file's own version ({@link versionedModuleUrl}), it is kept for good: a page
41
+ * opened again does not ask for it at all. Otherwise it is served as `no-cache`, since a module is
42
+ * rebuilt in place under the same name (its stylesheet, a file another of its files imports, a URL
43
+ * naming a version gone since), with a tag of the file's own: a page opened again asks with it and
44
+ * is answered "not changed", with no body. Sent gzipped, a module's code being a page's largest file.
31
45
  */
32
46
  export async function serveModuleFile(req, res, pathname, projects = defaultProjectsProvider()) {
33
47
  const [projectSegment, ...rest] = pathname.slice(MODULES_PREFIX.length + 1).split('/');
@@ -52,10 +66,15 @@ async function serveFileOf(req, res, [packageSegment, ...rest], find) {
52
66
  return notFound();
53
67
  const module = await find(pkg).catch(() => undefined);
54
68
  const file = module ? await moduleFile(module, rel.join('/')) : undefined;
55
- const body = file ? await readFile(file).catch(() => undefined) : undefined;
56
- if (!file || body === undefined)
69
+ const facts = file ? await stat(file).catch(() => undefined) : undefined;
70
+ const body = file && facts ? await readFile(file).catch(() => undefined) : undefined;
71
+ if (!file || !facts || body === undefined)
57
72
  return notFound();
58
- res.writeHead(200, { 'content-type': contentTypeFor(file), 'cache-control': 'no-cache' });
59
- res.end(req.method === 'HEAD' ? undefined : body);
73
+ const asked = new URL(req.url ?? '/', 'http://x').searchParams.get('v');
74
+ const cacheControl = asked === fileVersion(facts) ? 'public, max-age=31536000, immutable' : 'no-cache';
75
+ const headers = { 'content-type': contentTypeFor(file), 'cache-control': cacheControl, etag: fileTag(facts) };
76
+ if (req.method === 'HEAD')
77
+ return void res.writeHead(200, headers).end();
78
+ await sendBody(req, res, 200, headers, body, `${file} ${facts.mtimeMs} ${facts.size}`);
60
79
  }
61
80
  //# sourceMappingURL=module-serve.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"module-serve.js","sourceRoot":"","sources":["../../src/dashboard/module-serve.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"module-serve.js","sourceRoot":"","sources":["../../src/dashboard/module-serve.ts"],"names":[],"mappings":"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"}
@@ -19,6 +19,8 @@ import { type GivenLogins, type MachineLogins } from './machine-logins.js';
19
19
  * machine with its key there.
20
20
  * - `POST /_relay/rpc` (#1067 slice 2) runs one whitelisted run-scoped RPC (a read/diff/steer/handoff/
21
21
  * push/PR) against this machine's own checkout for the daemon relaying an agent here, answering {result}.
22
+ * - `POST /_relay/machine` runs one whitelisted machine-wide RPC, no project's (the logins and settings
23
+ * the person's own computer brings up to its own), answering {result}.
22
24
  * - `GET /_relay/project?project=<address>` says where this machine's copy of a project stands, and
23
25
  * `POST /_relay/project` has this machine clone the project when it has none: the answer comes at
24
26
  * once and the clone goes on by itself, so the caller asks again until the project is there.
@@ -28,10 +30,10 @@ import { type GivenLogins, type MachineLogins } from './machine-logins.js';
28
30
  * `{github?, claude?, from?}` hands them over (machine-logins.ts). Only an OpenAgent that is one
29
31
  * person's, on another person's computer, answers it.
30
32
  *
31
- * All but the ping name their project by its repository's address, and work in this machine's own
32
- * project cloned from it. A call that names none, or one this machine does not have, starts and
33
- * reads nothing: there is no project a call falls back to. Only the call that asks for a project
34
- * brings one here.
33
+ * All but the ping and the machine-wide calls name their project by its repository's address, and
34
+ * work in this machine's own project cloned from it. A call that names none, or one this machine
35
+ * does not have, starts and reads nothing: there is no project a call falls back to. Only the call
36
+ * that asks for a project brings one here.
35
37
  */
36
38
  export declare const RELAY_PREFIX = "/_relay";
37
39
  /**
@@ -55,6 +57,8 @@ export interface RelayHandlers {
55
57
  /** Run one whitelisted read/steer/handoff RPC against THIS machine's own checkout, for the daemon
56
58
  * relaying an agent here (#1067 slice 2); the caller wraps the result as {result}. */
57
59
  rpc?: (projectId: string, fn: string, args: unknown[]) => Promise<unknown>;
60
+ /** Run one whitelisted machine-wide RPC here, for the person's own computer; the caller wraps the result as {result}. */
61
+ machine?: (fn: string, args: unknown[]) => Promise<unknown>;
58
62
  /** Where the live screen of a run here answers; nothing when the run has none. */
59
63
  screen?: (projectId: string, agentId: string) => Promise<string | undefined>;
60
64
  /** Where this machine's copy of the project at `address` stands; with `bring`, clone and add it when there is none. */
@@ -1 +1 @@
1
- {"version":3,"file":"relay-endpoints.d.ts","sourceRoot":"","sources":["../../src/dashboard/relay-endpoints.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAEhE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAClD,OAAO,KAAK,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AACrE,OAAO,EAA4B,KAAK,YAAY,EAAE,KAAK,YAAY,EAAyB,MAAM,iBAAiB,CAAA;AAEvH,OAAO,EAA6B,KAAK,WAAW,EAAE,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAOrG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,eAAO,MAAM,YAAY,YAAY,CAAA;AAErC;;;;;;;;GAQG;AACH,eAAO,MAAM,YAAY,sBAAsB,CAAA;AAE/C,yJAAyJ;AACzJ,eAAO,MAAM,UAAU,4HAA0H,CAAA;AAEjJ,kGAAkG;AAClG,MAAM,WAAW,aAAa;IAC5B,kGAAkG;IAClG,OAAO,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAA;IACzD,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,KAAK,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAA;IACtH,UAAU,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,KAAK,MAAM,IAAI,CAAA;IACxG;2FACuF;IACvF,GAAG,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;IAC1E,kFAAkF;IAClF,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAA;IAC5E,uHAAuH;IACvH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,YAAY,KAAK,OAAO,CAAC,YAAY,CAAC,CAAA;IACxE,oHAAoH;IACpH,MAAM,CAAC,EAAE;QACP,IAAI,EAAE,MAAM,OAAO,CAAC,aAAa,CAAC,CAAA;QAClC,IAAI,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,OAAO,CAAC;YAAE,EAAE,EAAE,IAAI,CAAC;YAAC,MAAM,EAAE,aAAa,CAAA;SAAE,GAAG;YAAE,EAAE,EAAE,KAAK,CAAC;YAAC,KAAK,EAAE,MAAM,CAAA;SAAE,CAAC,CAAA;KAC1G,CAAA;CACF;AAgBD,+FAA+F;AAC/F,wBAAsB,kBAAkB,CACtC,GAAG,EAAE,eAAe,EACpB,GAAG,EAAE,cAAc,EACnB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,aAAa,GAAG,SAAS,GAClC,OAAO,CAAC,IAAI,CAAC,CAiBf"}
1
+ {"version":3,"file":"relay-endpoints.d.ts","sourceRoot":"","sources":["../../src/dashboard/relay-endpoints.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAEhE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAClD,OAAO,KAAK,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AACrE,OAAO,EAA4B,KAAK,YAAY,EAAE,KAAK,YAAY,EAAyB,MAAM,iBAAiB,CAAA;AAEvH,OAAO,EAA6B,KAAK,WAAW,EAAE,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAOrG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,eAAO,MAAM,YAAY,YAAY,CAAA;AAErC;;;;;;;;GAQG;AACH,eAAO,MAAM,YAAY,sBAAsB,CAAA;AAE/C,yJAAyJ;AACzJ,eAAO,MAAM,UAAU,4HAA0H,CAAA;AAEjJ,kGAAkG;AAClG,MAAM,WAAW,aAAa;IAC5B,kGAAkG;IAClG,OAAO,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAA;IACzD,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,KAAK,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAA;IACtH,UAAU,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,KAAK,MAAM,IAAI,CAAA;IACxG;2FACuF;IACvF,GAAG,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;IAC1E,yHAAyH;IACzH,OAAO,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;IAC3D,kFAAkF;IAClF,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAA;IAC5E,uHAAuH;IACvH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,YAAY,KAAK,OAAO,CAAC,YAAY,CAAC,CAAA;IACxE,oHAAoH;IACpH,MAAM,CAAC,EAAE;QACP,IAAI,EAAE,MAAM,OAAO,CAAC,aAAa,CAAC,CAAA;QAClC,IAAI,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,OAAO,CAAC;YAAE,EAAE,EAAE,IAAI,CAAC;YAAC,MAAM,EAAE,aAAa,CAAA;SAAE,GAAG;YAAE,EAAE,EAAE,KAAK,CAAC;YAAC,KAAK,EAAE,MAAM,CAAA;SAAE,CAAC,CAAA;KAC1G,CAAA;CACF;AAgBD,+FAA+F;AAC/F,wBAAsB,kBAAkB,CACtC,GAAG,EAAE,eAAe,EACpB,GAAG,EAAE,cAAc,EACnB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,aAAa,GAAG,SAAS,GAClC,OAAO,CAAC,IAAI,CAAC,CAkBf"}
@@ -7,7 +7,7 @@ import { end, readJsonBody, requireGet, sendJson } from './http.js';
7
7
  import { passToScreen, screenCallOf } from './screen.js';
8
8
  import { isRunId } from '../store/index.js';
9
9
  import { openagentVersion } from '../version.js';
10
- import { isRelayRead } from '../dashboard-rpc/relay-dispatch.js';
10
+ import { isMachineRead, isRelayRead } from '../dashboard-rpc/relay-dispatch.js';
11
11
  /**
12
12
  * The machine-side of the remote-agent relay (#1067): the endpoints through which another
13
13
  * machine's daemon runs a session here and watches it. They live under `/_relay`. This daemon
@@ -24,6 +24,8 @@ import { isRelayRead } from '../dashboard-rpc/relay-dispatch.js';
24
24
  * machine with its key there.
25
25
  * - `POST /_relay/rpc` (#1067 slice 2) runs one whitelisted run-scoped RPC (a read/diff/steer/handoff/
26
26
  * push/PR) against this machine's own checkout for the daemon relaying an agent here, answering {result}.
27
+ * - `POST /_relay/machine` runs one whitelisted machine-wide RPC, no project's (the logins and settings
28
+ * the person's own computer brings up to its own), answering {result}.
27
29
  * - `GET /_relay/project?project=<address>` says where this machine's copy of a project stands, and
28
30
  * `POST /_relay/project` has this machine clone the project when it has none: the answer comes at
29
31
  * once and the clone goes on by itself, so the caller asks again until the project is there.
@@ -33,10 +35,10 @@ import { isRelayRead } from '../dashboard-rpc/relay-dispatch.js';
33
35
  * `{github?, claude?, from?}` hands them over (machine-logins.ts). Only an OpenAgent that is one
34
36
  * person's, on another person's computer, answers it.
35
37
  *
36
- * All but the ping name their project by its repository's address, and work in this machine's own
37
- * project cloned from it. A call that names none, or one this machine does not have, starts and
38
- * reads nothing: there is no project a call falls back to. Only the call that asks for a project
39
- * brings one here.
38
+ * All but the ping and the machine-wide calls name their project by its repository's address, and
39
+ * work in this machine's own project cloned from it. A call that names none, or one this machine
40
+ * does not have, starts and reads nothing: there is no project a call falls back to. Only the call
41
+ * that asks for a project brings one here.
40
42
  */
41
43
  export const RELAY_PREFIX = '/_relay';
42
44
  /**
@@ -59,9 +61,9 @@ const MAX_START_BODY = 256 * 1024;
59
61
  /** Route a `/_relay/*` request. A host that wired no relay handlers 404s every relay route. */
60
62
  export async function handleRelayRequest(req, res, pathname, handlers) {
61
63
  // A call that may only watch: a GET reads, and is answered. Anything else acts and is refused,
62
- // but for a relayed function, whose name says whether it reads (handleRpc).
64
+ // but for a relayed function, whose name says whether it reads (handleRpc, handleMachine).
63
65
  const watch = req.headers[WATCH_HEADER] !== undefined;
64
- if (watch && req.method !== 'GET' && pathname !== `${RELAY_PREFIX}/rpc`)
66
+ if (watch && req.method !== 'GET' && pathname !== `${RELAY_PREFIX}/rpc` && pathname !== `${RELAY_PREFIX}/machine`)
65
67
  return end(res, 403, WATCH_ONLY);
66
68
  // Ping is a pure reachability probe (#1072): it needs no wired handlers and starts nothing,
67
69
  // so it answers even on a host that enabled no relay.
@@ -75,6 +77,8 @@ export async function handleRelayRequest(req, res, pathname, handlers) {
75
77
  return handleEvents(req, res, handlers);
76
78
  if (pathname === `${RELAY_PREFIX}/rpc`)
77
79
  return handleRpc(req, res, handlers, watch);
80
+ if (pathname === `${RELAY_PREFIX}/machine`)
81
+ return handleMachine(req, res, handlers, watch);
78
82
  if (pathname === `${RELAY_PREFIX}/project`)
79
83
  return handleProject(req, res, handlers);
80
84
  if (pathname === `${RELAY_PREFIX}/logins`)
@@ -271,4 +275,29 @@ async function handleRpc(req, res, handlers, watch) {
271
275
  end(res, 500, err instanceof Error ? err.message : 'rpc failed');
272
276
  }
273
277
  }
278
+ /** `POST /_relay/machine` `{fn, args}`: run one whitelisted machine-wide RPC here, answering {result}. */
279
+ async function handleMachine(req, res, handlers, watch) {
280
+ if (req.method !== 'POST')
281
+ return end(res, 405, 'method not allowed', { allow: 'POST' });
282
+ if (!handlers.machine)
283
+ return end(res, 404, 'relay machine calls not enabled');
284
+ let body;
285
+ try {
286
+ body = (await readJsonBody(req, MAX_RPC_BODY));
287
+ }
288
+ catch {
289
+ return end(res, 400, 'invalid request body');
290
+ }
291
+ const fn = typeof body.fn === 'string' ? body.fn : '';
292
+ if (!fn)
293
+ return end(res, 400, 'missing rpc name');
294
+ if (watch && !isMachineRead(fn))
295
+ return end(res, 403, WATCH_ONLY);
296
+ try {
297
+ sendJson(res, { result: await handlers.machine(fn, Array.isArray(body.args) ? body.args : []) });
298
+ }
299
+ catch (err) {
300
+ end(res, 500, err instanceof Error ? err.message : 'rpc failed');
301
+ }
302
+ }
274
303
  //# sourceMappingURL=relay-endpoints.js.map