@ahpd/server 0.1.0 → 0.2.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 (170) hide show
  1. package/README.md +87 -81
  2. package/dist/config.d.ts +65 -0
  3. package/dist/config.js +75 -0
  4. package/dist/daemon.d.ts +26 -0
  5. package/dist/daemon.js +160 -0
  6. package/dist/main.d.ts +2 -0
  7. package/dist/main.js +297 -0
  8. package/dist/pty.d.ts +12 -0
  9. package/dist/pty.js +56 -0
  10. package/package.json +15 -25
  11. package/dist/automations.d.ts +0 -4
  12. package/dist/automations.d.ts.map +0 -1
  13. package/dist/automations.js +0 -191
  14. package/dist/automations.js.map +0 -1
  15. package/dist/catalog.d.ts +0 -48
  16. package/dist/catalog.d.ts.map +0 -1
  17. package/dist/catalog.js +0 -51
  18. package/dist/catalog.js.map +0 -1
  19. package/dist/changes.d.ts +0 -4
  20. package/dist/changes.d.ts.map +0 -1
  21. package/dist/changes.js +0 -601
  22. package/dist/changes.js.map +0 -1
  23. package/dist/cron.d.ts +0 -43
  24. package/dist/cron.d.ts.map +0 -1
  25. package/dist/cron.js +0 -211
  26. package/dist/cron.js.map +0 -1
  27. package/dist/git.d.ts +0 -16
  28. package/dist/git.d.ts.map +0 -1
  29. package/dist/git.js +0 -126
  30. package/dist/git.js.map +0 -1
  31. package/dist/host.d.ts +0 -24
  32. package/dist/host.d.ts.map +0 -1
  33. package/dist/host.js +0 -5850
  34. package/dist/host.js.map +0 -1
  35. package/dist/index.d.ts +0 -36
  36. package/dist/index.d.ts.map +0 -1
  37. package/dist/index.js +0 -34
  38. package/dist/index.js.map +0 -1
  39. package/dist/listen.d.ts +0 -3
  40. package/dist/listen.d.ts.map +0 -1
  41. package/dist/listen.js +0 -183
  42. package/dist/listen.js.map +0 -1
  43. package/dist/paging.d.ts +0 -38
  44. package/dist/paging.d.ts.map +0 -1
  45. package/dist/paging.js +0 -53
  46. package/dist/paging.js.map +0 -1
  47. package/dist/paths.d.ts +0 -15
  48. package/dist/paths.d.ts.map +0 -1
  49. package/dist/paths.js +0 -19
  50. package/dist/paths.js.map +0 -1
  51. package/dist/resources.d.ts +0 -122
  52. package/dist/resources.d.ts.map +0 -1
  53. package/dist/resources.js +0 -494
  54. package/dist/resources.js.map +0 -1
  55. package/dist/rpc.d.ts +0 -63
  56. package/dist/rpc.d.ts.map +0 -1
  57. package/dist/rpc.js +0 -208
  58. package/dist/rpc.js.map +0 -1
  59. package/dist/scheduled.d.ts +0 -48
  60. package/dist/scheduled.d.ts.map +0 -1
  61. package/dist/scheduled.js +0 -325
  62. package/dist/scheduled.js.map +0 -1
  63. package/dist/terminals.d.ts +0 -29
  64. package/dist/terminals.d.ts.map +0 -1
  65. package/dist/terminals.js +0 -346
  66. package/dist/terminals.js.map +0 -1
  67. package/dist/tools.d.ts +0 -18
  68. package/dist/tools.d.ts.map +0 -1
  69. package/dist/tools.js +0 -65
  70. package/dist/tools.js.map +0 -1
  71. package/dist/types/agent.d.ts +0 -245
  72. package/dist/types/agent.d.ts.map +0 -1
  73. package/dist/types/agent.js +0 -3
  74. package/dist/types/agent.js.map +0 -1
  75. package/dist/types/automations.d.ts +0 -164
  76. package/dist/types/automations.d.ts.map +0 -1
  77. package/dist/types/automations.js +0 -3
  78. package/dist/types/automations.js.map +0 -1
  79. package/dist/types/catalog.d.ts +0 -30
  80. package/dist/types/catalog.d.ts.map +0 -1
  81. package/dist/types/catalog.js +0 -3
  82. package/dist/types/catalog.js.map +0 -1
  83. package/dist/types/changes.d.ts +0 -272
  84. package/dist/types/changes.d.ts.map +0 -1
  85. package/dist/types/changes.js +0 -3
  86. package/dist/types/changes.js.map +0 -1
  87. package/dist/types/common.d.ts +0 -9
  88. package/dist/types/common.d.ts.map +0 -1
  89. package/dist/types/common.js +0 -3
  90. package/dist/types/common.js.map +0 -1
  91. package/dist/types/host.d.ts +0 -372
  92. package/dist/types/host.d.ts.map +0 -1
  93. package/dist/types/host.js +0 -3
  94. package/dist/types/host.js.map +0 -1
  95. package/dist/types/index.d.ts +0 -20
  96. package/dist/types/index.d.ts.map +0 -1
  97. package/dist/types/index.js +0 -8
  98. package/dist/types/index.js.map +0 -1
  99. package/dist/types/listen.d.ts +0 -48
  100. package/dist/types/listen.d.ts.map +0 -1
  101. package/dist/types/listen.js +0 -3
  102. package/dist/types/listen.js.map +0 -1
  103. package/dist/types/paging.d.ts +0 -10
  104. package/dist/types/paging.d.ts.map +0 -1
  105. package/dist/types/paging.js +0 -3
  106. package/dist/types/paging.js.map +0 -1
  107. package/dist/types/probe.d.ts +0 -46
  108. package/dist/types/probe.d.ts.map +0 -1
  109. package/dist/types/probe.js +0 -3
  110. package/dist/types/probe.js.map +0 -1
  111. package/dist/types/resources.d.ts +0 -83
  112. package/dist/types/resources.d.ts.map +0 -1
  113. package/dist/types/resources.js +0 -3
  114. package/dist/types/resources.js.map +0 -1
  115. package/dist/types/rpc.d.ts +0 -65
  116. package/dist/types/rpc.d.ts.map +0 -1
  117. package/dist/types/rpc.js +0 -3
  118. package/dist/types/rpc.js.map +0 -1
  119. package/dist/types/session.d.ts +0 -395
  120. package/dist/types/session.d.ts.map +0 -1
  121. package/dist/types/session.js +0 -3
  122. package/dist/types/session.js.map +0 -1
  123. package/dist/types/terminals.d.ts +0 -131
  124. package/dist/types/terminals.d.ts.map +0 -1
  125. package/dist/types/terminals.js +0 -3
  126. package/dist/types/terminals.js.map +0 -1
  127. package/dist/types/wire.d.ts +0 -62
  128. package/dist/types/wire.d.ts.map +0 -1
  129. package/dist/types/wire.js +0 -13
  130. package/dist/types/wire.js.map +0 -1
  131. package/dist/types/worktrees.d.ts +0 -86
  132. package/dist/types/worktrees.d.ts.map +0 -1
  133. package/dist/types/worktrees.js +0 -3
  134. package/dist/types/worktrees.js.map +0 -1
  135. package/dist/worktrees.d.ts +0 -27
  136. package/dist/worktrees.d.ts.map +0 -1
  137. package/dist/worktrees.js +0 -152
  138. package/dist/worktrees.js.map +0 -1
  139. package/src/automations.ts +0 -204
  140. package/src/catalog.ts +0 -53
  141. package/src/changes.ts +0 -629
  142. package/src/cron.ts +0 -251
  143. package/src/git.ts +0 -132
  144. package/src/host.ts +0 -5947
  145. package/src/index.ts +0 -40
  146. package/src/listen.ts +0 -240
  147. package/src/paging.ts +0 -56
  148. package/src/paths.ts +0 -19
  149. package/src/resources.ts +0 -513
  150. package/src/rpc.ts +0 -222
  151. package/src/scheduled.ts +0 -369
  152. package/src/terminals.ts +0 -353
  153. package/src/tools.ts +0 -64
  154. package/src/types/agent.ts +0 -255
  155. package/src/types/automations.ts +0 -164
  156. package/src/types/catalog.ts +0 -26
  157. package/src/types/changes.ts +0 -266
  158. package/src/types/common.ts +0 -9
  159. package/src/types/host.ts +0 -386
  160. package/src/types/index.ts +0 -27
  161. package/src/types/listen.ts +0 -53
  162. package/src/types/paging.ts +0 -11
  163. package/src/types/probe.ts +0 -42
  164. package/src/types/resources.ts +0 -107
  165. package/src/types/rpc.ts +0 -68
  166. package/src/types/session.ts +0 -415
  167. package/src/types/terminals.ts +0 -133
  168. package/src/types/wire.ts +0 -69
  169. package/src/types/worktrees.ts +0 -91
  170. package/src/worktrees.ts +0 -162
package/dist/changes.js DELETED
@@ -1,601 +0,0 @@
1
- /** What git says a directory has changed, as a host's `ChangesetSource`. */
2
- import { execFile } from 'node:child_process';
3
- import { readFile, rm, writeFile } from 'node:fs/promises';
4
- /**
5
- * How many lines a file has, for one git will not count.
6
- *
7
- * Capped, because this is a *summary* and a row saying 40,000 is worth no more
8
- * than one saying a lot - and reading a hundred-megabyte file to find that out
9
- * is the expensive way to learn nothing.
10
- */
11
- const lines = async (path) => {
12
- try {
13
- const text = await readFile(path, 'utf8');
14
- if (text === '')
15
- return 0;
16
- return text.split('\n').length - (text.endsWith('\n') ? 1 : 0);
17
- }
18
- catch {
19
- return 0;
20
- }
21
- };
22
- /**
23
- * How many lines differ between two versions, without diffing them.
24
- *
25
- * A count, not a diff: the rows carry both sides and a client renders the
26
- * real thing from those. Computing a proper LCS here to fill in two numbers
27
- * would be the same work twice, once where nobody can see it.
28
- */
29
- const counted = (before, after) => {
30
- const was = before === '' ? [] : before.split('\n');
31
- const now = after === '' ? [] : after.split('\n');
32
- const shared = new Set(was);
33
- const added = now.filter((row) => !shared.has(row)).length;
34
- const kept_ = new Set(now);
35
- const removed = was.filter((row) => !kept_.has(row)).length;
36
- return { added, removed };
37
- };
38
- /** One `git` run, as text, or nothing when it would not run. */
39
- const git = (dir, args) => new Promise((answer) => {
40
- execFile('git', ['-C', dir, ...args], { timeout: 5000, maxBuffer: 32 * 1024 * 1024 }, (error, out) => answer(error ? undefined : out.toString()));
41
- });
42
- /**
43
- * One `git` run, with the failure kept.
44
- *
45
- * `git` above answers `undefined` for every kind of not-working, which is the
46
- * right shape for a question - a directory that is not a repository has no
47
- * diff, and why is not interesting. An *operation* is the other case: somebody
48
- * pressed a button, it did not work, and the only useful thing to say is what
49
- * git said.
50
- */
51
- const run = (dir, args) => new Promise((answer) => {
52
- execFile('git', ['-C', dir, ...args], { timeout: 30000, maxBuffer: 32 * 1024 * 1024 }, (error, out, errOut) => answer({
53
- ok: !error,
54
- out: out.toString(),
55
- err: errOut.toString().trim() || (error ? error.message : ''),
56
- }));
57
- });
58
- /** The path a `file://` URI names, or nothing for a URI that names none. */
59
- const pathIn = (dir, uri) => {
60
- if (!uri.startsWith('file://'))
61
- return undefined;
62
- const path = uri.slice('file://'.length);
63
- // Inside the directory this changeset is about, and not merely starting with
64
- // its name: `/src/brb` must not reach `/src/brb_framework`.
65
- return path === dir || path.startsWith(`${dir}/`) ? path : undefined;
66
- };
67
- /**
68
- * The scheme for the side of an edit that is not on disk.
69
- *
70
- * `before` is what a file *used to be*, so no `file://` URI addresses it and
71
- * the filesystem port cannot serve it. This host mints its own URI and
72
- * resolves it itself, which is what `ChangesetSource.read` is for.
73
- */
74
- const BEFORE = 'ahp-git:';
75
- const beforeUri = (dir, path) => `${BEFORE}//${dir}/${path}`;
76
- /**
77
- * The scheme for a side that was *captured* rather than read.
78
- *
79
- * A turn's changeset is what the files looked like on either side of that
80
- * turn, and neither side is on disk once a later turn has run. Both are held
81
- * here and served from here.
82
- */
83
- const CAPTURED = 'ahp-edit:';
84
- /**
85
- * The verbs this source offers, declared once.
86
- *
87
- * Ids and labels follow the reference host's where it has one - a client that
88
- * special-cases `commit` should find it spelled the way it expects - and every
89
- * one of them writes, which is what the host gates on.
90
- */
91
- const COMMIT = {
92
- id: 'commit',
93
- label: 'Commit',
94
- description: 'Commit the working tree, including files git has not been told about',
95
- scopes: ['changeset'],
96
- icon: 'git-commit',
97
- group: 'commit',
98
- writes: true,
99
- };
100
- const DISCARD = {
101
- id: 'discard',
102
- label: 'Discard Changes',
103
- description: 'Put this file back the way HEAD has it',
104
- scopes: ['resource'],
105
- confirmation: 'Discard the changes to this file? This cannot be undone.',
106
- icon: 'discard',
107
- writes: true,
108
- };
109
- /**
110
- * Undoing the agent rather than undoing the working tree.
111
- *
112
- * Separate from `discard` because the two put a file back to different places:
113
- * `discard` goes to HEAD, which is where a person's own uncommitted work goes
114
- * too, and this goes to the state the turn found the file in - which is only
115
- * knowable because both sides were captured as the tool ran.
116
- */
117
- const REVERT = {
118
- id: 'revert',
119
- label: 'Revert This File',
120
- description: 'Put this file back the way the agent found it',
121
- scopes: ['resource'],
122
- confirmation: 'Put this file back the way the agent found it? Anything written since is lost.',
123
- icon: 'discard',
124
- writes: true,
125
- };
126
- export function gitChanges() {
127
- /**
128
- * What each turn changed, per session.
129
- *
130
- * `session -> turn -> path -> both sides`. Held rather than derived because
131
- * git cannot answer it: a working tree says what it looks like now, so a
132
- * turn asked about after two more have run would be handed their work too.
133
- */
134
- const seen = new Map();
135
- /** The text held for a captured side, by the URI minted for it. */
136
- const kept = new Map();
137
- /**
138
- * Which files somebody has ticked off, per changeset.
139
- *
140
- * A reader's bookkeeping rather than anything about the files: keyed by the
141
- * scope being read, because reviewing a turn is not reviewing the session
142
- * that contains it.
143
- */
144
- const reviewed = new Map();
145
- const reviewKey = (session, scope) => `${session}\u0000${scope}`;
146
- const capturedUri = (session, turn, path, phase) => `${CAPTURED}//${encodeURIComponent(session)}/${encodeURIComponent(turn)}/${phase}${path}`;
147
- /**
148
- * Fold a run of turns into one edit per file.
149
- *
150
- * The first `before` and the last `after`, which is what a range of turns
151
- * changed taken together: a file edited three times was found in one state
152
- * and left in another, and the two states in between are the middle of a
153
- * diff nobody asked for.
154
- */
155
- const fold = (turns) => {
156
- const flat = new Map();
157
- for (const files of turns) {
158
- for (const [path, sides] of files) {
159
- const already = flat.get(path);
160
- // The first `before` and the last `after`: a session's changeset is
161
- // the whole conversation as one edit, not the last turn of it.
162
- flat.set(path, {
163
- ...(already?.before !== undefined ? { before: already.before } : sides.before !== undefined ? { before: sides.before } : {}),
164
- ...(sides.after !== undefined ? { after: sides.after } : already?.after !== undefined ? { after: already.after } : {}),
165
- });
166
- }
167
- }
168
- return flat;
169
- };
170
- /** Every file a session has touched, in the order it touched them. */
171
- const across = (session) => fold([...(seen.get(session) ?? new Map()).values()]);
172
- /**
173
- * The turns from one to another, inclusive.
174
- *
175
- * Insertion order is turn order - a turn is first seen when its first tool
176
- * runs - so a range is a slice. Either end being unknown is a question about
177
- * something that did not happen, and answers nothing rather than everything.
178
- */
179
- const between = (session, from, to) => {
180
- const turns = seen.get(session);
181
- if (!turns)
182
- return undefined;
183
- const order = [...turns.keys()];
184
- const start = order.indexOf(from);
185
- const end = order.indexOf(to);
186
- if (start < 0 || end < 0)
187
- return undefined;
188
- const [lo, hi] = start <= end ? [start, end] : [end, start];
189
- return fold(order.slice(lo, hi + 1).map((id) => turns.get(id)));
190
- };
191
- /**
192
- * Captured sides as the protocol's rows, with both sides fetchable.
193
- *
194
- * Minting a URI and remembering what is behind it are the same act, so they
195
- * are done in the same place: a row that names content nothing can resolve
196
- * is a row that opens onto an error.
197
- */
198
- const rowsOf = (session, turn, files) => {
199
- const ticked = reviewed.get(reviewKey(session, turn));
200
- return [...files].map(([path, sides]) => {
201
- const uri = `file://${path}`;
202
- const before = capturedUri(session, turn, path, 'before');
203
- const after = capturedUri(session, turn, path, 'after');
204
- if (sides.before !== undefined)
205
- kept.set(before, sides.before);
206
- if (sides.after !== undefined)
207
- kept.set(after, sides.after);
208
- return {
209
- id: uri,
210
- edit: {
211
- // An empty `before` is a file the turn created, and the protocol
212
- // says a creation by leaving the side out rather than by a word.
213
- ...(sides.before ? { before: { uri, content: { uri: before } } } : {}),
214
- ...(sides.after !== undefined ? { after: { uri, content: { uri: after } } } : {}),
215
- diff: counted(sides.before ?? '', sides.after ?? ''),
216
- },
217
- // Absent is not-yet-reviewed, which is what the protocol says a
218
- // missing value means, so only a tick is worth sending.
219
- ...(ticked?.has(uri) ? { reviewed: true } : {}),
220
- };
221
- });
222
- };
223
- /**
224
- * The files one captured scope holds, by absolute path.
225
- *
226
- * The same branch `state` takes, wanted twice: an operation on a captured
227
- * scope needs the side the turn *found* the file in, and there is nowhere
228
- * else that survives - git only ever knows what the tree looks like now.
229
- */
230
- const capturedFor = (session, scope) => {
231
- if (scope === 'session')
232
- return across(session);
233
- if (scope.startsWith('compare/')) {
234
- const [from, to] = scope.slice('compare/'.length).split('/');
235
- if (!from || !to)
236
- return undefined;
237
- return between(session, from, to);
238
- }
239
- if (scope.startsWith('turn/'))
240
- return seen.get(session)?.get(scope.slice('turn/'.length));
241
- return undefined;
242
- };
243
- /** The last answer per directory, so a catalogue of rows is not a hundred `git` runs. */
244
- const held = new Map();
245
- /**
246
- * What changed, as one pass over `git status` and one over `git diff`.
247
- *
248
- * `--porcelain=v1 -z` because a filename may contain anything a shell would
249
- * otherwise eat, newlines included; the NUL form is the only one that
250
- * survives a path somebody made on purpose.
251
- */
252
- const look = async (dir) => {
253
- const status = await git(dir, ['status', '--porcelain=v1', '-z', '--untracked-files=all']);
254
- if (status === undefined)
255
- return undefined;
256
- /** Line counts per path, for the files git can already diff. */
257
- const counts = new Map();
258
- const numstat = await git(dir, ['diff', '--numstat', '-z', 'HEAD']) ?? '';
259
- /*
260
- * `added<TAB>removed<TAB>path` per record, NUL between records.
261
- *
262
- * The tabs are *inside* a record and only the separator is NUL, which is
263
- * the whole point of `-z`: a path may contain a tab, and it may contain a
264
- * newline, and neither ends the record. A rename writes an empty path and
265
- * then two records of its own, old name and new.
266
- */
267
- const counted = numstat.split('\0');
268
- for (let i = 0; i < counted.length; i++) {
269
- const record = counted[i];
270
- if (record === '')
271
- continue;
272
- const [rawAdded, rawRemoved, path] = record.split('\t');
273
- // `-` on both sides is a binary file, which has no lines to count.
274
- const added = Number(rawAdded);
275
- const removed = Number(rawRemoved);
276
- const named = path === '' || path === undefined
277
- // A rename: the two records after this one are the old and new names,
278
- // and it is the new one the working tree has.
279
- ? (i += 2, counted[i])
280
- : path;
281
- if (!named)
282
- continue;
283
- counts.set(named, {
284
- added: Number.isFinite(added) ? added : 0,
285
- removed: Number.isFinite(removed) ? removed : 0,
286
- });
287
- }
288
- const files = [];
289
- const summary = { files: 0, additions: 0, deletions: 0 };
290
- const records = status.split('\0').filter((record) => record !== '');
291
- for (const record of records) {
292
- // `XY <path>`: two status letters, a space, then the path.
293
- const code = record.slice(0, 2);
294
- const path = record.slice(3);
295
- if (path === '')
296
- continue;
297
- const gone = code.includes('D');
298
- const fresh = code.includes('A') || code.includes('?');
299
- const uri = `file://${dir}/${path}`;
300
- // An untracked file is in no diff against HEAD, so git reports nothing
301
- // for it. Every line of it is an addition, which is what it is.
302
- const count = counts.get(path) ?? (fresh
303
- ? { added: await lines(`${dir}/${path}`), removed: 0 }
304
- : { added: 0, removed: 0 });
305
- files.push({
306
- id: uri,
307
- edit: {
308
- // Absent `before` is a creation and absent `after` a deletion. The
309
- // protocol says both by leaving a side out rather than by a word.
310
- ...(fresh ? {} : {
311
- before: { uri, content: { uri: beforeUri(dir, path) } },
312
- }),
313
- ...(gone ? {} : {
314
- after: { uri, content: { uri } },
315
- }),
316
- diff: { added: count.added, removed: count.removed },
317
- },
318
- });
319
- summary.files = (summary.files ?? 0) + 1;
320
- summary.additions = (summary.additions ?? 0) + count.added;
321
- summary.deletions = (summary.deletions ?? 0) + count.removed;
322
- }
323
- return { files, summary };
324
- };
325
- return {
326
- scopes: (dir, session) => {
327
- const scopes = held.has(dir)
328
- ? [{
329
- id: 'uncommitted',
330
- label: 'Uncommitted Changes',
331
- description: 'The working tree, against HEAD',
332
- changeKind: 'uncommitted',
333
- // Not reviewable: the working tree is whatever it is now, and a
334
- // tick against a file that something else may rewrite underneath it
335
- // is bookkeeping about a thing that has moved.
336
- }]
337
- : [];
338
- const turns = seen.get(session);
339
- if (!turns || turns.size === 0)
340
- return scopes;
341
- // The session's own first. A client showing one changeset shows the
342
- // first that needs no variable filling in, and what a *conversation*
343
- // changed is the one that belongs beside a conversation - the working
344
- // tree includes whatever else happened to the directory meanwhile.
345
- return [
346
- {
347
- id: 'session',
348
- label: 'This Session',
349
- description: 'Everything this conversation changed',
350
- changeKind: 'session',
351
- reviewable: true,
352
- },
353
- ...scopes,
354
- // Templates, which is how the protocol offers a scope that has to be
355
- // filled in: a client expands them from turns it can already see.
356
- {
357
- id: 'turn/{turnId}',
358
- label: 'This Turn',
359
- description: 'What one turn changed',
360
- changeKind: 'turn',
361
- reviewable: true,
362
- },
363
- {
364
- id: 'compare/{originalTurnId}/{modifiedTurnId}',
365
- label: 'Between Two Turns',
366
- description: 'What changed from one turn to another',
367
- changeKind: 'compare-turns',
368
- reviewable: true,
369
- },
370
- ];
371
- },
372
- state: async (dir, session, scope) => {
373
- if (scope === 'uncommitted') {
374
- const found = held.get(dir) ?? await look(dir);
375
- if (!found)
376
- return undefined;
377
- return { status: 'ready', files: found.files };
378
- }
379
- if (scope === 'session') {
380
- const files = across(session);
381
- if (files.size === 0)
382
- return { status: 'ready', files: [] };
383
- return { status: 'ready', files: rowsOf(session, 'session', files) };
384
- }
385
- if (scope.startsWith('compare/')) {
386
- const [from, to] = scope.slice('compare/'.length).split('/');
387
- if (!from || !to)
388
- return undefined;
389
- const files = between(session, from, to);
390
- if (!files)
391
- return undefined;
392
- return { status: 'ready', files: rowsOf(session, `compare/${from}/${to}`, files) };
393
- }
394
- if (scope.startsWith('turn/')) {
395
- const turn = scope.slice('turn/'.length);
396
- const files = seen.get(session)?.get(turn);
397
- // A turn nobody has heard of is not an empty changeset - it is a
398
- // question about something that did not happen.
399
- if (!files)
400
- return undefined;
401
- return { status: 'ready', files: rowsOf(session, turn, files) };
402
- }
403
- return undefined;
404
- },
405
- /*
406
- * Both sides of a file, captured as the tool runs.
407
- *
408
- * `before` is read as the tool is announced and `after` when its result
409
- * arrives. A file that did not exist reads as empty, which is what a
410
- * creation is.
411
- */
412
- observe: (dir, session, turnId, path, phase) => {
413
- void (async () => {
414
- const text = await readFile(path, 'utf8').catch(() => undefined);
415
- const turns = seen.get(session) ?? new Map();
416
- seen.set(session, turns);
417
- const files = turns.get(turnId) ?? new Map();
418
- turns.set(turnId, files);
419
- const sides = files.get(path) ?? {};
420
- // The first `before` wins: a turn that edits one file twice found it
421
- // in one state, and the second read is already its own work.
422
- if (phase === 'before' && sides.before === undefined)
423
- sides.before = text ?? '';
424
- if (phase === 'after')
425
- sides.after = text ?? '';
426
- files.set(path, sides);
427
- kept.set(capturedUri(session, turnId, path, phase), text ?? '');
428
- /*
429
- * A file that has changed again is not the file that was reviewed.
430
- *
431
- * The protocol makes this the server's job - it is the authority on
432
- * what changed - and says to reset explicitly rather than leave a tick
433
- * standing against content nobody has read. Only on `after`, because
434
- * `before` is the state a tick was about.
435
- */
436
- if (phase === 'after') {
437
- for (const scope of [turnId, 'session']) {
438
- reviewed.get(reviewKey(session, scope))?.delete(`file://${path}`);
439
- }
440
- }
441
- })().catch(() => { });
442
- },
443
- summary: (dir) => held.get(dir)?.summary,
444
- /*
445
- * The `before` side, out of git rather than off the disk.
446
- *
447
- * `git show HEAD:<path>` is what the file was at the last commit, which is
448
- * the only place that version still exists.
449
- */
450
- read: async (uri) => {
451
- // Captured sides are held, not fetched: neither is on disk any more.
452
- if (uri.startsWith(CAPTURED)) {
453
- const text = kept.get(uri);
454
- return text === undefined ? undefined : { data: text, encoding: 'utf-8' };
455
- }
456
- if (!uri.startsWith(BEFORE))
457
- return undefined;
458
- const rest = uri.slice(`${BEFORE}//`.length);
459
- // The directory is the longest known one this URI starts with: a path
460
- // has slashes and so does a directory, and splitting on the first one
461
- // would name neither.
462
- const dir = [...held.keys()]
463
- .filter((known) => rest.startsWith(`${known}/`))
464
- .sort((a, b) => b.length - a.length)[0];
465
- if (dir === undefined)
466
- return undefined;
467
- const path = rest.slice(dir.length + 1);
468
- const data = await git(dir, ['show', `HEAD:${path}`]);
469
- // A file that is not in HEAD has no before, and empty is the truthful
470
- // answer for one: it did not exist.
471
- return { data: data ?? '', encoding: 'utf-8' };
472
- },
473
- /*
474
- * Ticked off, or cleared.
475
- *
476
- * The one thing a client may write here, and it writes nothing to disk:
477
- * it is a reader's note about a diff they are working through. Answers
478
- * whether it moved, so a client that ticks a file already ticked does not
479
- * make every other client redraw.
480
- */
481
- review: (_dir, session, scope, files, isReviewed) => {
482
- const key = reviewKey(session, scope);
483
- const ticked = reviewed.get(key) ?? new Set();
484
- reviewed.set(key, ticked);
485
- let moved = false;
486
- for (const file of files) {
487
- if (isReviewed && !ticked.has(file)) {
488
- ticked.add(file);
489
- moved = true;
490
- }
491
- if (!isReviewed && ticked.delete(file))
492
- moved = true;
493
- }
494
- return moved;
495
- },
496
- /**
497
- * What can be done to one scope, and only what can be done *now*.
498
- *
499
- * A working tree with nothing in it offers no commit, and a scope holding
500
- * no captured files offers no revert - an operation advertised against
501
- * nothing is a button that fails when pressed, and the protocol's whole
502
- * access model is that a client may only invoke what it was offered.
503
- */
504
- operations: (dir, session, scope) => {
505
- // Not a repository. `held` is only ever set for a directory `git status`
506
- // answered for, which is the same question as "is there git here".
507
- if (!held.has(dir))
508
- return [];
509
- if (scope === 'uncommitted')
510
- return held.get(dir)?.summary?.files ? [COMMIT, DISCARD] : [];
511
- const files = capturedFor(session, scope);
512
- return files && files.size > 0 ? [REVERT] : [];
513
- },
514
- /*
515
- * Run one.
516
- *
517
- * Everything about *whether* this is allowed happened before the call: the
518
- * host checked the id against what `operations` offered for this scope,
519
- * checked the target against the operation's scopes, and checked that a
520
- * write grant is held. What is left is the doing, and saying what git said
521
- * when it did not work.
522
- */
523
- invoke: async ({ dir, session, scope, operationId, target, subject }) => {
524
- if (operationId === 'commit') {
525
- // `-A`, including files git has not been told about: the changeset this
526
- // was invoked on counted untracked files as changes, and committing
527
- // less than was listed would commit something other than what was
528
- // shown.
529
- const staged = await run(dir, ['add', '-A']);
530
- if (!staged.ok)
531
- throw new Error(`Could not stage: ${staged.err}`);
532
- // The session's own title, which is the sentence somebody already wrote
533
- // about this work. A generated one would need the agent, and running a
534
- // turn to commit a turn is a lot of machinery for a subject line.
535
- const line = (subject ?? '').split('\n')[0]?.trim();
536
- const message = line !== undefined && line !== '' ? line : 'Changes from an agent session';
537
- const done = await run(dir, ['commit', '-m', message]);
538
- if (!done.ok)
539
- throw new Error(`Could not commit: ${done.err || done.out.trim()}`);
540
- const at = (await git(dir, ['rev-parse', '--short', 'HEAD']))?.trim();
541
- return { message: at ? `Committed ${at}: ${message}` : `Committed: ${message}` };
542
- }
543
- const path = target?.resource === undefined ? undefined : pathIn(dir, target.resource);
544
- // Refused rather than clamped: a target outside this directory is a
545
- // client asking to write somewhere this changeset is not about.
546
- if (path === undefined)
547
- throw new Error('That file is not in this directory.');
548
- const named = path.slice(dir.length + 1);
549
- if (operationId === 'discard') {
550
- /*
551
- * Tracked and untracked are different undos.
552
- *
553
- * A file git knows goes back to HEAD; a file it does not was never
554
- * anywhere else, so putting it back means removing it. `restore` will
555
- * not do the second - it fails on a pathspec it has no record of - so
556
- * the failure is the signal to try the other one.
557
- */
558
- const back = await run(dir, ['restore', '--staged', '--worktree', '--source=HEAD', '--', path]);
559
- if (!back.ok) {
560
- const cleaned = await run(dir, ['clean', '-f', '--', path]);
561
- if (!cleaned.ok)
562
- throw new Error(`Could not discard: ${back.err || cleaned.err}`);
563
- }
564
- return { message: `Discarded ${named}` };
565
- }
566
- if (operationId === 'revert') {
567
- const sides = capturedFor(session, scope)?.get(path);
568
- if (!sides)
569
- throw new Error('This changeset does not hold that file.');
570
- /*
571
- * No `before` is a file the turn created, and putting a creation back
572
- * means it should not be there.
573
- *
574
- * Empty counts as none, which is the same reading `rowsOf` gives when
575
- * it decides whether to draw a `before` side at all - one rule, so a
576
- * row that shows as a creation reverts as one.
577
- */
578
- if (sides.before === undefined || sides.before === '') {
579
- await rm(path, { force: true });
580
- return { message: `Removed ${named}, which this changeset created` };
581
- }
582
- await writeFile(path, sides.before, 'utf8');
583
- return { message: `Reverted ${named}` };
584
- }
585
- throw new Error(`No operation called ${operationId}`);
586
- },
587
- refresh: async (dir) => {
588
- const found = await look(dir);
589
- const before = JSON.stringify(held.get(dir)?.summary ?? null);
590
- if (!found) {
591
- if (!held.has(dir))
592
- return false;
593
- held.delete(dir);
594
- return true;
595
- }
596
- held.set(dir, found);
597
- return JSON.stringify(found.summary) !== before;
598
- },
599
- };
600
- }
601
- //# sourceMappingURL=changes.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"changes.js","sourceRoot":"","sources":["../src/changes.ts"],"names":[],"mappings":"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"}