@framers/agentos-ext-github 0.6.0 → 0.8.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 (37) hide show
  1. package/README.md +42 -8
  2. package/dist/__tests__/app.test.js +218 -1
  3. package/dist/__tests__/app.test.js.map +1 -1
  4. package/dist/__tests__/links.test.d.ts +8 -0
  5. package/dist/__tests__/links.test.d.ts.map +1 -0
  6. package/dist/__tests__/links.test.js +182 -0
  7. package/dist/__tests__/links.test.js.map +1 -0
  8. package/dist/__tests__/refs.test.d.ts +7 -0
  9. package/dist/__tests__/refs.test.d.ts.map +1 -0
  10. package/dist/__tests__/refs.test.js +420 -0
  11. package/dist/__tests__/refs.test.js.map +1 -0
  12. package/dist/app/installations.d.ts +57 -6
  13. package/dist/app/installations.d.ts.map +1 -1
  14. package/dist/app/installations.js +113 -14
  15. package/dist/app/installations.js.map +1 -1
  16. package/dist/app/reconcile.d.ts +20 -7
  17. package/dist/app/reconcile.d.ts.map +1 -1
  18. package/dist/app/reconcile.js +36 -14
  19. package/dist/app/reconcile.js.map +1 -1
  20. package/dist/documents/GitHubDocumentsConnector.d.ts +74 -17
  21. package/dist/documents/GitHubDocumentsConnector.d.ts.map +1 -1
  22. package/dist/documents/GitHubDocumentsConnector.js +118 -20
  23. package/dist/documents/GitHubDocumentsConnector.js.map +1 -1
  24. package/dist/documents/index.d.ts +21 -8
  25. package/dist/documents/index.d.ts.map +1 -1
  26. package/dist/documents/index.js +21 -8
  27. package/dist/documents/index.js.map +1 -1
  28. package/dist/documents/links.d.ts +50 -0
  29. package/dist/documents/links.d.ts.map +1 -0
  30. package/dist/documents/links.js +216 -0
  31. package/dist/documents/links.js.map +1 -0
  32. package/dist/documents/tree.d.ts +44 -0
  33. package/dist/documents/tree.d.ts.map +1 -1
  34. package/dist/documents/tree.js +68 -0
  35. package/dist/documents/tree.js.map +1 -1
  36. package/manifest.json +1 -1
  37. package/package.json +3 -3
@@ -0,0 +1,420 @@
1
+ /**
2
+ * @fileoverview A link's ref settled through GitHub's matching references, a tree planned with what it leaves out and
3
+ * why, and a repository's documentation listed and compared at a named branch or commit, over a fetch stand-in that
4
+ * answers a repository's branches, references and trees and records each request.
5
+ */
6
+ import { generateKeyPairSync } from 'node:crypto';
7
+ import { describe, expect, it } from 'vitest';
8
+ import { DEFAULT_MAX_FILE_BYTES, GitHubApiError, GitHubAppCredential, GitHubDocumentsConnector, GitHubNoAnswer, IMAGE_EXTENSIONS, pathFilter, planTree, } from '../documents/index.js';
9
+ /** A JSON answer. */
10
+ function json(body, status = 200) {
11
+ return new Response(JSON.stringify(body), { status, headers: { 'content-type': 'application/json' } });
12
+ }
13
+ const BASE = 'https://stand-in.test';
14
+ const INSTALLATION = 5;
15
+ const HANDBOOK = { id: 77, fullName: 'acme-team/handbook', defaultBranch: 'main' };
16
+ /** A repository with no commit yet: GitHub answers its references 409. */
17
+ const EMPTY = { id: 80, fullName: 'acme-team/empty', defaultBranch: 'main' };
18
+ const MAIN = '1'.repeat(40);
19
+ const RELEASE = '2'.repeat(40);
20
+ const RELEASE_10 = '3'.repeat(40);
21
+ const RELEASE_NOTES = '4'.repeat(40);
22
+ const DOCS_1 = '5'.repeat(40);
23
+ /** The release branch's head after a push. */
24
+ const RELEASE_NEXT = '6'.repeat(40);
25
+ /** A commit a link pins. */
26
+ const PINNED = '9f2c4e6a'.repeat(5);
27
+ /** The handbook's branches by name. Git keeps no branch beside one under its name; the stand-in does, so the longest wins. */
28
+ const BRANCHES = {
29
+ main: MAIN,
30
+ release: RELEASE,
31
+ 'release/1.0': RELEASE_10,
32
+ 'release-notes': RELEASE_NOTES,
33
+ 'docs#1': DOCS_1,
34
+ };
35
+ /** The handbook's trees by commit. */
36
+ const TREES = {
37
+ [MAIN]: [
38
+ { path: 'README.md', sha: 'r1', size: 120 },
39
+ { path: 'docs/agenda.md', sha: 'a1', size: 300 },
40
+ ],
41
+ [RELEASE]: [
42
+ { path: 'README.md', sha: 'r1', size: 120 },
43
+ { path: 'docs/agenda.md', sha: 'a2', size: 320 },
44
+ { path: 'docs/setup.md', sha: 's1', size: 200 },
45
+ ],
46
+ [RELEASE_NEXT]: [
47
+ { path: 'README.md', sha: 'r1', size: 120 },
48
+ { path: 'docs/agenda.md', sha: 'a3', size: 330 },
49
+ ],
50
+ [RELEASE_10]: [{ path: 'docs/setup.md', sha: 's10', size: 210 }],
51
+ [PINNED]: [
52
+ { path: 'README.md', sha: 'r0', size: 100 },
53
+ { path: 'docs/old.md', sha: 'o1', size: 50 },
54
+ ],
55
+ };
56
+ /** A stand-in GitHub holding the handbook and the empty repository. */
57
+ function github() {
58
+ const seen = [];
59
+ const fetchImpl = async (input, init) => {
60
+ const href = typeof input === 'string' ? input : input instanceof URL ? input.href : input.url;
61
+ seen.push({ method: init?.method ?? 'GET', url: href, headers: new Headers(init?.headers) });
62
+ const url = new URL(href);
63
+ const path = url.pathname;
64
+ if (path === `/app/installations/${INSTALLATION}/access_tokens`) {
65
+ return json({ token: 'ghs_documents', expires_at: new Date(Date.now() + 3_600_000).toISOString() }, 201);
66
+ }
67
+ const matching = '/repositories/77/git/matching-refs/heads/';
68
+ if (path.startsWith(matching)) {
69
+ // GitHub answers every reference whose name starts with the one asked for.
70
+ const prefix = `refs/heads/${decodeURIComponent(path.slice(matching.length))}`;
71
+ const references = Object.entries(BRANCHES).map(([name, sha]) => ({ ref: `refs/heads/${name}`, object: { type: 'commit', sha } }));
72
+ return json(references.filter((reference) => reference.ref.startsWith(prefix)));
73
+ }
74
+ if (path.startsWith('/repositories/80/git/matching-refs/'))
75
+ return json({ message: 'Git Repository is empty.' }, 409);
76
+ const branches = '/repositories/77/branches/';
77
+ if (path.startsWith(branches)) {
78
+ const name = decodeURIComponent(path.slice(branches.length));
79
+ const sha = BRANCHES[name];
80
+ return sha === undefined ? json({ message: 'Branch not found' }, 404) : json({ name, commit: { sha } });
81
+ }
82
+ const trees = '/repositories/77/git/trees/';
83
+ const entries = path.startsWith(trees) && url.searchParams.get('recursive') === '1' ? TREES[path.slice(trees.length)] : undefined;
84
+ if (entries !== undefined) {
85
+ return json({ sha: path.slice(trees.length), truncated: false, tree: entries.map((entry) => ({ mode: '100644', type: 'blob', ...entry })) });
86
+ }
87
+ return json({ message: 'Not Found' }, 404);
88
+ };
89
+ return { fetchImpl, seen };
90
+ }
91
+ const keys = generateKeyPairSync('rsa', {
92
+ modulusLength: 2048,
93
+ publicKeyEncoding: { type: 'spki', format: 'pem' },
94
+ privateKeyEncoding: { type: 'pkcs1', format: 'pem' },
95
+ });
96
+ /** A connector to the handbook and the empty repository, on the stand-in. */
97
+ function connectorOn(stand, filter = {}) {
98
+ const credential = new GitHubAppCredential({ clientId: 'Iv23liTESTCLIENT', privateKey: keys.privateKey }, stand.fetchImpl, BASE);
99
+ return new GitHubDocumentsConnector(credential, INSTALLATION, [HANDBOOK, EMPTY], filter, stand.fetchImpl, BASE);
100
+ }
101
+ /** The requests made other than for an installation token, as their paths and queries. */
102
+ function reads(seen) {
103
+ return seen.filter((request) => !request.url.endsWith('/access_tokens')).map((request) => request.url.slice(BASE.length));
104
+ }
105
+ /** A plan as its paths and outcomes. */
106
+ function outcomes(plan) {
107
+ return plan.map((planned) => [planned.path, planned.outcome]);
108
+ }
109
+ /** A blob of ten bytes, or of `size`. */
110
+ function blob(path, size = 10) {
111
+ return { path, sha: `b-${path}`, size };
112
+ }
113
+ describe('resolveRef', () => {
114
+ it("settles a branch holding a slash with one request to GitHub's matching references, by the repository's id", async () => {
115
+ const stand = github();
116
+ expect(await connectorOn(stand).resolveRef(77, 'release/1.0/docs/setup.md')).toEqual({ ref: 'release/1.0', path: 'docs/setup.md', commit: false });
117
+ expect(reads(stand.seen)).toEqual(['/repositories/77/git/matching-refs/heads/release']);
118
+ const request = stand.seen.find((seen) => seen.url.includes('/matching-refs/'));
119
+ expect(request?.headers.get('authorization')).toBe('Bearer ghs_documents');
120
+ expect(request?.headers.get('x-github-api-version')).toBe('2026-03-10');
121
+ });
122
+ it('takes the longest branch that is the text or starts it at a slash, never one that only starts with the same letters', async () => {
123
+ const connector = connectorOn(github());
124
+ expect(await connector.resolveRef(77, 'main/docs')).toEqual({ ref: 'main', path: 'docs', commit: false });
125
+ expect(await connector.resolveRef(77, 'release/docs/setup.md')).toEqual({ ref: 'release', path: 'docs/setup.md', commit: false });
126
+ expect(await connector.resolveRef(77, 'release/1.0')).toEqual({ ref: 'release/1.0', path: '', commit: false });
127
+ expect(await connector.resolveRef(77, 'release-notes/2026.md')).toEqual({ ref: 'release-notes', path: '2026.md', commit: false });
128
+ // No branch starts with the segment: the segment alone is the ref, and the listing at it answers GitHub's 404.
129
+ expect(await connector.resolveRef(77, 'nightly/docs')).toEqual({ ref: 'nightly', path: 'docs', commit: false });
130
+ });
131
+ it('asks for the first segment encoded, so a branch holding a # is asked for whole', async () => {
132
+ const stand = github();
133
+ expect(await connectorOn(stand).resolveRef(77, 'docs#1/guide.md')).toEqual({ ref: 'docs#1', path: 'guide.md', commit: false });
134
+ expect(reads(stand.seen)).toEqual(['/repositories/77/git/matching-refs/heads/docs%231']);
135
+ });
136
+ it('takes a commit of 40 hexadecimal characters in either case, and HEAD as the default branch, with no request', async () => {
137
+ const stand = github();
138
+ const connector = connectorOn(stand);
139
+ expect(await connector.resolveRef(77, `${PINNED}/docs/old.md`)).toEqual({ ref: PINNED, path: 'docs/old.md', commit: true });
140
+ expect(await connector.resolveRef(77, `${PINNED.toUpperCase()}/docs`)).toEqual({ ref: PINNED, path: 'docs', commit: true });
141
+ expect(await connector.resolveRef(77, PINNED)).toEqual({ ref: PINNED, path: '', commit: true });
142
+ expect(await connector.resolveRef(77, 'HEAD/docs/agenda.md')).toEqual({ ref: 'main', path: 'docs/agenda.md', commit: false });
143
+ expect(stand.seen).toEqual([]);
144
+ });
145
+ it('refuses, before any request, a text with an empty, . or .. segment, a repository outside the link and an aborted call', async () => {
146
+ const stand = github();
147
+ const connector = connectorOn(stand);
148
+ for (const text of ['', '/main/docs', 'main/', 'main//docs', './docs', 'main/./docs', 'main/../secret', '..']) {
149
+ const failure = await connector.resolveRef(77, text).catch((error) => error);
150
+ expect(failure, text).toBeInstanceOf(TypeError);
151
+ expect(failure.message).not.toContain('secret');
152
+ }
153
+ await expect(connector.resolveRef(79, 'main/docs')).rejects.toThrow('repository 79 is not part of this link');
154
+ const aborted = await connector.resolveRef(77, '', AbortSignal.abort()).catch((error) => error);
155
+ expect(aborted).toBeInstanceOf(GitHubNoAnswer);
156
+ expect(aborted.reason).toBe('cancelled');
157
+ expect(stand.seen).toEqual([]);
158
+ });
159
+ it("throws GitHub's refusal of the references, never a ref it did not read", async () => {
160
+ const failure = await connectorOn(github())
161
+ .resolveRef(80, 'main/docs')
162
+ .catch((error) => error);
163
+ expect(failure).toBeInstanceOf(GitHubApiError);
164
+ expect(failure.status).toBe(409);
165
+ });
166
+ });
167
+ describe('planTree', () => {
168
+ const TREE = [
169
+ blob('src/index.ts', 50),
170
+ blob('README.md', 120),
171
+ blob('docs/big.md', 12 * 1024 * 1024),
172
+ blob('assets/logo.png', 4096),
173
+ blob('docs/budget.pdf', 2048),
174
+ blob('node_modules/x/README.md'),
175
+ blob('docs/agenda.md', 300),
176
+ ];
177
+ it('answers every file in path order: the documentation a note, the rest skipped with its reason', () => {
178
+ expect(outcomes(planTree(TREE))).toEqual([
179
+ ['README.md', 'note'],
180
+ ['assets/logo.png', { skipped: 'image' }],
181
+ ['docs/agenda.md', 'note'],
182
+ ['docs/big.md', { skipped: 'size' }],
183
+ ['docs/budget.pdf', 'note'],
184
+ ['node_modules/x/README.md', { skipped: 'folder' }],
185
+ ['src/index.ts', { skipped: 'code' }],
186
+ ]);
187
+ expect(planTree(TREE, { includeCode: true }).find((planned) => planned.path === 'src/index.ts')?.outcome).toBe('note');
188
+ });
189
+ it('tells code left out from code a tool wrote, a file of no kind it reads, and a code file past its own bound', () => {
190
+ const blobs = [
191
+ blob('package.json'),
192
+ blob('config/settings.yaml'),
193
+ blob('LICENSE'),
194
+ blob('web/app.min.js'),
195
+ blob('web/app.js'),
196
+ blob('src/huge.ts', 2_000_000),
197
+ blob('docs/long.md', 2_000_000),
198
+ ];
199
+ expect(outcomes(planTree(blobs))).toEqual([
200
+ ['LICENSE', { skipped: 'kind' }],
201
+ ['config/settings.yaml', { skipped: 'kind' }],
202
+ ['docs/long.md', 'note'],
203
+ ['package.json', { skipped: 'kind' }],
204
+ ['src/huge.ts', { skipped: 'code' }],
205
+ ['web/app.js', { skipped: 'code' }],
206
+ ['web/app.min.js', { skipped: 'code' }],
207
+ ]);
208
+ expect(outcomes(planTree(blobs, { includeCode: true, maxCodeBytes: 1_048_576 }))).toEqual([
209
+ ['LICENSE', { skipped: 'kind' }],
210
+ ['config/settings.yaml', { skipped: 'kind' }],
211
+ ['docs/long.md', 'note'],
212
+ ['package.json', { skipped: 'kind' }],
213
+ ['src/huge.ts', { skipped: 'size' }],
214
+ ['web/app.js', 'note'],
215
+ ['web/app.min.js', { skipped: 'generated' }],
216
+ ]);
217
+ });
218
+ it('bounds a code file by maxCodeBytes while code is asked for, even when the filter names its extension as documentation', () => {
219
+ const blobs = [blob('docs/guide.md', 2_000_000), blob('src/huge.ts', 2_000_000), blob('src/small.ts', 100)];
220
+ const filter = { extensions: ['.md', '.ts'], maxCodeBytes: 1_048_576 };
221
+ expect(outcomes(planTree(blobs, { ...filter, includeCode: true }))).toEqual([
222
+ ['docs/guide.md', 'note'],
223
+ ['src/huge.ts', { skipped: 'size' }],
224
+ ['src/small.ts', 'note'],
225
+ ]);
226
+ // Without code asked for, an extension the filter names is documentation alone, under maxFileBytes.
227
+ expect(outcomes(planTree(blobs, filter))).toEqual([
228
+ ['docs/guide.md', 'note'],
229
+ ['src/huge.ts', 'note'],
230
+ ['src/small.ts', 'note'],
231
+ ]);
232
+ });
233
+ it('keeps the documentation first under the file count and the code in the room left, the rest past the count', () => {
234
+ const blobs = [blob('api/a.ts'), blob('api/b.ts'), blob('app/c.py'), blob('docs/guide.md'), blob('docs/z.md')];
235
+ expect(outcomes(planTree(blobs, { includeCode: true, maxFiles: 3 }))).toEqual([
236
+ ['api/a.ts', 'note'],
237
+ ['api/b.ts', { skipped: 'count' }],
238
+ ['app/c.py', { skipped: 'count' }],
239
+ ['docs/guide.md', 'note'],
240
+ ['docs/z.md', 'note'],
241
+ ]);
242
+ expect(outcomes(planTree(blobs, { maxFiles: 1 }))).toEqual([
243
+ ['api/a.ts', { skipped: 'code' }],
244
+ ['api/b.ts', { skipped: 'code' }],
245
+ ['app/c.py', { skipped: 'code' }],
246
+ ['docs/guide.md', 'note'],
247
+ ['docs/z.md', { skipped: 'count' }],
248
+ ]);
249
+ });
250
+ it('answers as notes exactly what pathFilter keeps under the same filter', () => {
251
+ const blobs = [
252
+ ...TREE,
253
+ blob('web/app.min.js'),
254
+ blob('web/app.js'),
255
+ blob('docs/x.min.js'),
256
+ blob('package.json'),
257
+ blob('vendor/y.md'),
258
+ blob('src/big.ts', DEFAULT_MAX_FILE_BYTES + 1),
259
+ ...Array.from({ length: 6 }, (_, index) => blob(`notes/n${index}.md`)),
260
+ ...Array.from({ length: 6 }, (_, index) => blob(`lib/m${index}.py`)),
261
+ ];
262
+ const filters = [
263
+ {},
264
+ { includeCode: true },
265
+ { maxFiles: 4 },
266
+ { includeCode: true, maxFiles: 9 },
267
+ { includeCode: true, maxFiles: 12 },
268
+ { extensions: ['.md', '.js'] },
269
+ { includeCode: true, extensions: ['.md', '.js'] },
270
+ { skipFolders: [] },
271
+ { maxFileBytes: 100 },
272
+ ];
273
+ for (const filter of filters) {
274
+ const notes = planTree(blobs, filter)
275
+ .filter((planned) => planned.outcome === 'note')
276
+ .map(({ path, sha, size }) => ({ path, sha, size }));
277
+ expect(notes, JSON.stringify(filter)).toEqual(pathFilter(filter)(blobs));
278
+ }
279
+ });
280
+ it('reads the image extensions it is given, and keeps as documentation any extension the filter names', () => {
281
+ const blobs = [blob('art/cover.png'), blob('art/scan.jxl')];
282
+ expect(outcomes(planTree(blobs))).toEqual([
283
+ ['art/cover.png', { skipped: 'image' }],
284
+ ['art/scan.jxl', { skipped: 'kind' }],
285
+ ]);
286
+ expect(outcomes(planTree(blobs, { imageExtensions: ['.JXL'] }))).toEqual([
287
+ ['art/cover.png', { skipped: 'kind' }],
288
+ ['art/scan.jxl', { skipped: 'image' }],
289
+ ]);
290
+ expect(outcomes(planTree(blobs, { extensions: ['.png'] }))).toEqual([
291
+ ['art/cover.png', 'note'],
292
+ ['art/scan.jxl', { skipped: 'kind' }],
293
+ ]);
294
+ expect(IMAGE_EXTENSIONS).toContain('.svg');
295
+ });
296
+ it('answers new objects holding the path, the sha, the size and the outcome alone, and refuses a code bound that is not a size', () => {
297
+ const held = { path: 'README.md', sha: 'r1', size: 120, mode: '100644' };
298
+ expect(planTree([held])).toEqual([{ path: 'README.md', sha: 'r1', size: 120, outcome: 'note' }]);
299
+ for (const maxCodeBytes of [-1, Number.NaN, 1.5, Number.POSITIVE_INFINITY]) {
300
+ expect(() => planTree([], { maxCodeBytes }), String(maxCodeBytes)).toThrow(TypeError);
301
+ }
302
+ });
303
+ });
304
+ describe('the listing at a named branch or commit', () => {
305
+ it("lists the head of the branch at names, a slash in its name included, and a commit with no branch read", async () => {
306
+ const stand = github();
307
+ const connector = connectorOn(stand);
308
+ expect(await connector.list({ ids: ['77'], at: 'release' })).toEqual({
309
+ items: [
310
+ { id: '77:README.md', title: 'README.md', size: 120, version: `r1@${RELEASE}` },
311
+ { id: '77:docs/agenda.md', title: 'docs/agenda.md', size: 320, version: `a2@${RELEASE}` },
312
+ { id: '77:docs/setup.md', title: 'docs/setup.md', size: 200, version: `s1@${RELEASE}` },
313
+ ],
314
+ gone: [],
315
+ });
316
+ expect((await connector.list({ ids: ['77'], at: 'release/1.0' })).items).toEqual([
317
+ { id: '77:docs/setup.md', title: 'docs/setup.md', size: 210, version: `s10@${RELEASE_10}` },
318
+ ]);
319
+ expect((await connector.list({ ids: ['77'], at: PINNED.toUpperCase() })).items).toEqual([
320
+ { id: '77:README.md', title: 'README.md', size: 100, version: `r0@${PINNED}` },
321
+ { id: '77:docs/old.md', title: 'docs/old.md', size: 50, version: `o1@${PINNED}` },
322
+ ]);
323
+ expect(reads(stand.seen)).toEqual([
324
+ '/repositories/77/branches/release',
325
+ `/repositories/77/git/trees/${RELEASE}?recursive=1`,
326
+ '/repositories/77/branches/release%2F1.0',
327
+ `/repositories/77/git/trees/${RELEASE_10}?recursive=1`,
328
+ `/repositories/77/git/trees/${PINNED}?recursive=1`,
329
+ ]);
330
+ });
331
+ it("compares at the head of the branch at names when no push names a commit", async () => {
332
+ const stand = github();
333
+ const changes = await connectorOn(stand).changesSince(JSON.stringify({ 'README.md': 'r1' }), { ids: ['77'], at: 'release' });
334
+ expect(changes.changed.map((item) => item.version)).toEqual([`a2@${RELEASE}`, `s1@${RELEASE}`]);
335
+ expect(changes.gone).toEqual([]);
336
+ expect(reads(stand.seen)).toEqual(['/repositories/77/branches/release', `/repositories/77/git/trees/${RELEASE}?recursive=1`]);
337
+ });
338
+ it('compares a push to the branch at names, and answers a push to any other branch, the default included, with no change and no request', async () => {
339
+ const stand = github();
340
+ const connector = connectorOn(stand);
341
+ const previous = JSON.stringify({ 'README.md': 'r1', 'docs/agenda.md': 'a2', 'docs/setup.md': 's1' });
342
+ const changes = await connector.changesSince(previous, { ids: ['77'], at: 'release', ref: 'refs/heads/release', after: RELEASE_NEXT });
343
+ expect(changes.changed).toEqual([{ id: '77:docs/agenda.md', title: 'docs/agenda.md', size: 330, version: `a3@${RELEASE_NEXT}` }]);
344
+ expect(changes.gone).toEqual([{ id: '77:docs/setup.md', reason: 'removed' }]);
345
+ expect(reads(stand.seen)).toEqual([`/repositories/77/git/trees/${RELEASE_NEXT}?recursive=1`]);
346
+ const before = stand.seen.length;
347
+ expect(await connector.changesSince(previous, { ids: ['77'], at: 'release', ref: 'refs/heads/main', after: MAIN })).toEqual({ changed: [], gone: [], cursor: previous });
348
+ expect(await connector.changesSince(previous, { ids: ['77'], at: 'release/1.0', ref: 'refs/heads/release', after: RELEASE_NEXT })).toEqual({
349
+ changed: [],
350
+ gone: [],
351
+ cursor: previous,
352
+ });
353
+ expect(stand.seen.length).toBe(before);
354
+ });
355
+ it('compares a commit at itself, so a push never changes it, and refuses an after naming another commit', async () => {
356
+ const stand = github();
357
+ const connector = connectorOn(stand);
358
+ const cursor = JSON.stringify({ 'README.md': 'r0', 'docs/old.md': 'o1' });
359
+ expect(await connector.changesSince(cursor, { ids: ['77'], at: PINNED })).toEqual({ changed: [], gone: [], cursor });
360
+ expect(await connector.changesSince(null, { ids: ['77'], at: PINNED.toUpperCase(), after: PINNED })).toEqual({
361
+ changed: [
362
+ { id: '77:README.md', title: 'README.md', size: 100, version: `r0@${PINNED}` },
363
+ { id: '77:docs/old.md', title: 'docs/old.md', size: 50, version: `o1@${PINNED}` },
364
+ ],
365
+ gone: [],
366
+ cursor,
367
+ });
368
+ expect(reads(stand.seen)).toEqual([`/repositories/77/git/trees/${PINNED}?recursive=1`, `/repositories/77/git/trees/${PINNED}?recursive=1`]);
369
+ const before = stand.seen.length;
370
+ expect(await connector.changesSince(cursor, { ids: ['77'], at: PINNED, ref: 'refs/heads/main', after: MAIN })).toEqual({ changed: [], gone: [], cursor });
371
+ await expect(connector.changesSince(cursor, { ids: ['77'], at: PINNED, after: MAIN })).rejects.toBeInstanceOf(TypeError);
372
+ expect(stand.seen.length).toBe(before);
373
+ });
374
+ it('reads head at a named branch or commit, and at the default branch when handed a signal alone as before', async () => {
375
+ const stand = github();
376
+ const connector = connectorOn(stand);
377
+ expect(await connector.head(77, 'release/1.0')).toBe(RELEASE_10);
378
+ expect(await connector.head(77, PINNED.toUpperCase())).toBe(PINNED);
379
+ expect(await connector.head(77)).toBe(MAIN);
380
+ expect(await connector.head(77, new AbortController().signal)).toBe(MAIN);
381
+ expect(await connector.head(77, undefined, new AbortController().signal)).toBe(MAIN);
382
+ expect(reads(stand.seen)).toEqual([
383
+ '/repositories/77/branches/release%2F1.0',
384
+ '/repositories/77/branches/main',
385
+ '/repositories/77/branches/main',
386
+ '/repositories/77/branches/main',
387
+ ]);
388
+ });
389
+ it('refuses, before any request, an at that is neither a branch name nor a commit, and an at over other than one repository', async () => {
390
+ const stand = github();
391
+ const connector = connectorOn(stand);
392
+ const names = ['', 'feature..x', 'feature x', '-x', 'HEAD', '@', 'release/', '/release', 'release//1.0', 'x.lock', 'docs/.hidden', 'end.'];
393
+ for (const at of [...names, 'a~1', 'a^', 'a:b', 'a?', 'a*', 'a[1]', 'a\\b', 'a@{1}', 'a\tb']) {
394
+ await expect(connector.list({ ids: ['77'], at }), at).rejects.toBeInstanceOf(TypeError);
395
+ await expect(connector.changesSince(null, { ids: ['77'], at }), at).rejects.toBeInstanceOf(TypeError);
396
+ await expect(connector.head(77, at), at).rejects.toBeInstanceOf(TypeError);
397
+ }
398
+ await expect(connector.list({ ids: ['77', '80'], at: 'release' })).rejects.toBeInstanceOf(TypeError);
399
+ await expect(connector.list({ ids: [], at: 'release' })).rejects.toBeInstanceOf(TypeError);
400
+ expect(stand.seen).toEqual([]);
401
+ });
402
+ it('answers an aborted call cancelled before it checks at', async () => {
403
+ const stand = github();
404
+ const connector = connectorOn(stand);
405
+ const aborted = AbortSignal.abort();
406
+ const calls = [
407
+ () => connector.list({ ids: ['77'], at: '' }, aborted),
408
+ () => connector.changesSince(null, { ids: ['77'], at: '' }, aborted),
409
+ () => connector.head(77, '', aborted),
410
+ () => connector.head(77, 'release', aborted),
411
+ ];
412
+ for (const call of calls) {
413
+ const failure = await call().catch((error) => error);
414
+ expect(failure).toBeInstanceOf(GitHubNoAnswer);
415
+ expect(failure.reason).toBe('cancelled');
416
+ }
417
+ expect(stand.seen).toEqual([]);
418
+ });
419
+ });
420
+ //# sourceMappingURL=refs.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"refs.test.js","sourceRoot":"","sources":["../../src/__tests__/refs.test.ts"],"names":[],"mappings":"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"}
@@ -1,8 +1,9 @@
1
1
  /**
2
2
  * @fileoverview What a user token reaches (the person, the app's installations they can access, and the repositories
3
- * of an installation they can read), the app's own installations, listed and removed with its JWT, and the repositories
4
- * an installation reaches, listed with an installation token. Each function takes `{ fetchImpl, apiBase, timeoutMs }`
5
- * last: `fetch`, GitHub's API and a 30-second deadline a call when absent.
3
+ * of an installation they can read), the app's own installations, listed, read one at a time and removed with its JWT,
4
+ * each with when it was suspended, and the repositories an installation reaches, listed with an installation token, and
5
+ * those of them a caller holds that it no longer reaches. Each function takes `{ fetchImpl, apiBase, timeoutMs }` last:
6
+ * `fetch`, GitHub's API and a 30-second deadline a call when absent.
6
7
  * @module agentos-ext-github/app/installations
7
8
  */
8
9
  import type { GitHubAppCredential } from './credential.js';
@@ -22,6 +23,14 @@ export interface GitHubInstallation {
22
23
  id: number;
23
24
  account: GitHubAccount | null;
24
25
  }
26
+ /** One installation as the app's own calls answer it (`listInstallations`, `getInstallation`): with when it was suspended. */
27
+ export interface AppInstallation extends GitHubInstallation {
28
+ /**
29
+ * When the installation was suspended (GitHub's `suspended_at`, an ISO 8601 time), or null while it is not. GitHub
30
+ * blocks a suspended installation's access to the API and its webhook events until it is unsuspended.
31
+ */
32
+ suspendedAt: string | null;
33
+ }
25
34
  /** A repository a user token can read in an installation. */
26
35
  export interface UserRepository {
27
36
  id: number;
@@ -45,6 +54,13 @@ export declare function installationsOfUser(token: string, { fetchImpl, apiBase,
45
54
  * across every page: those the person owns, collaborates on or reaches through an organization.
46
55
  */
47
56
  export declare function repositoriesOfUser(token: string, installationId: number, { fetchImpl, apiBase, timeoutMs }?: GitHubApiOptions): Promise<UserRepository[]>;
57
+ /**
58
+ * An installation's repositories changed while each of {@link LISTING_READS} reads of its listing was read (its pages
59
+ * disagreed on GitHub's `total_count`), so no read is whole. The message names nothing of the installation.
60
+ */
61
+ export declare class GitHubListingChanged extends Error {
62
+ constructor();
63
+ }
48
64
  /**
49
65
  * Every repository an installation reaches (`GET /installation/repositories`), across every page, read with an
50
66
  * installation token that reads their metadata and nothing else (`credential.metadataToken`): the whole of what the
@@ -52,11 +68,46 @@ export declare function repositoriesOfUser(token: string, installationId: number
52
68
  * made is missing from it. The token is minted with the credential's own fetch; the pages are read with `fetchImpl`. A
53
69
  * held token GitHub refuses (401, as it refuses every token of an installation it no longer has) is dropped and one
54
70
  * new token asked for, once. A refused token request throws `GitHubApiError` (404 for an installation GitHub no longer
55
- * has), so a lost installation never reads as one that reaches no repository.
71
+ * has), so a lost installation never reads as one that reaches no repository. The listing is read a page at a time, and
72
+ * a repository added to or taken off the installation between two pages changes GitHub's `total_count` and can move
73
+ * another one past a page's end: a read whose pages disagree on that count is read again, up to three reads, and then
74
+ * {@link GitHubListingChanged} is thrown. An addition and a removal between the same two pages leave the count as it
75
+ * was and can still move one past a page's end, so {@link repositoriesLost} reads the listing twice before it answers a
76
+ * repository lost.
56
77
  */
57
78
  export declare function repositoriesOfInstallation(credential: GitHubAppCredential, installationId: number, { fetchImpl, apiBase, timeoutMs }?: GitHubApiOptions): Promise<InstallationRepository[]>;
58
- /** Every installation of the app (`GET /app/installations`, with its JWT), across every page. */
59
- export declare function listInstallations(credential: GitHubAppCredential, { fetchImpl, apiBase, timeoutMs }?: GitHubApiOptions): Promise<GitHubInstallation[]>;
79
+ /**
80
+ * Which of the repositories `held` an installation no longer reaches: those missing from its listing
81
+ * (`repositoriesOfInstallation`, each read one whose pages agree on GitHub's count) read twice, the second listing read
82
+ * only when the first misses one. An addition and a removal between the same two pages of a listing leave the count as
83
+ * it was and can move a repository the installation still reaches past a page's end, so a repository missing from one
84
+ * listing alone is not answered lost; one missing from both is. Answers in the order of `held`, each id once, and makes
85
+ * no request for an empty `held`. A refused listing, and one that kept changing (`GitHubListingChanged`), throws, so a
86
+ * failure never answers a repository lost.
87
+ *
88
+ * @param credential The app's credential, whose metadata token the listings are read with.
89
+ * @param installationId The installation.
90
+ * @param held The repositories the caller holds for the installation.
91
+ * @param options Where calls go.
92
+ */
93
+ export declare function repositoriesLost(credential: GitHubAppCredential, installationId: number, held: readonly number[], options?: GitHubApiOptions): Promise<number[]>;
94
+ /**
95
+ * Every installation of the app (`GET /app/installations`, with its JWT), across every page, each with when GitHub
96
+ * suspended it. The listing is read a page at a time, so an installation removed while it is read can move another one
97
+ * past a page's end, and that one is missing from the answer: `reconcileInstallations` asks for each linked
98
+ * installation it misses by its own address (`getInstallation`) before it answers one gone.
99
+ */
100
+ export declare function listInstallations(credential: GitHubAppCredential, { fetchImpl, apiBase, timeoutMs }?: GitHubApiOptions): Promise<AppInstallation[]>;
101
+ /**
102
+ * One installation of the app (`GET /app/installations/{installation_id}`, with its JWT), with when GitHub suspended
103
+ * it, or null when GitHub no longer has it (404). Any other refusal throws {@link GitHubApiError}, and a call that gets
104
+ * no answer throws `GitHubNoAnswer`, so an installation is never answered gone on a failure.
105
+ *
106
+ * @param credential The app's credential.
107
+ * @param installationId The installation.
108
+ * @param options Where calls go.
109
+ */
110
+ export declare function getInstallation(credential: GitHubAppCredential, installationId: number, { fetchImpl, apiBase, timeoutMs }?: GitHubApiOptions): Promise<AppInstallation | null>;
60
111
  /**
61
112
  * Uninstalls the app from an account (`DELETE /app/installations/{installation_id}`, with its JWT). Answers without an
62
113
  * error on a 2xx (202 at the pinned API version, where GitHub has taken the removal and does it in the background; 204
@@ -1 +1 @@
1
- {"version":3,"file":"installations.d.ts","sourceRoot":"","sources":["../../src/app/installations.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAC3D,OAAO,EAWL,KAAK,gBAAgB,EACtB,MAAM,WAAW,CAAC;AAEnB,0CAA0C;AAC1C,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;CACf;AAED,uGAAuG;AACvG,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,4EAA4E;AAC5E,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,aAAa,GAAG,IAAI,CAAC;CAC/B;AAED,6DAA6D;AAC7D,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,2EAA2E;AAC3E,MAAM,WAAW,sBAAsB;IACrC,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,oIAAoI;AACpI,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,aAAa,CAMvD;AAsBD,mGAAmG;AACnG,wBAAsB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,SAAiB,EAAE,OAAyB,EAAE,SAAS,EAAE,GAAE,gBAAqB,GAAG,OAAO,CAAC,UAAU,CAAC,CAGxJ;AAED,sGAAsG;AACtG,wBAAsB,mBAAmB,CACvC,KAAK,EAAE,MAAM,EACb,EAAE,SAAiB,EAAE,OAAyB,EAAE,SAAS,EAAE,GAAE,gBAAqB,GACjF,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAI/B;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CACtC,KAAK,EAAE,MAAM,EACb,cAAc,EAAE,MAAM,EACtB,EAAE,SAAiB,EAAE,OAAyB,EAAE,SAAS,EAAE,GAAE,gBAAqB,GACjF,OAAO,CAAC,cAAc,EAAE,CAAC,CAE3B;AAED;;;;;;;;GAQG;AACH,wBAAsB,0BAA0B,CAC9C,UAAU,EAAE,mBAAmB,EAC/B,cAAc,EAAE,MAAM,EACtB,EAAE,SAAiB,EAAE,OAAyB,EAAE,SAAS,EAAE,GAAE,gBAAqB,GACjF,OAAO,CAAC,sBAAsB,EAAE,CAAC,CASnC;AAED,iGAAiG;AACjG,wBAAsB,iBAAiB,CACrC,UAAU,EAAE,mBAAmB,EAC/B,EAAE,SAAiB,EAAE,OAAyB,EAAE,SAAS,EAAE,GAAE,gBAAqB,GACjF,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAI/B;AAED;;;;;GAKG;AACH,wBAAsB,qBAAqB,CACzC,UAAU,EAAE,mBAAmB,EAC/B,cAAc,EAAE,MAAM,EACtB,EAAE,SAAiB,EAAE,OAAyB,EAAE,SAAS,EAAE,GAAE,gBAAqB,GACjF,OAAO,CAAC,IAAI,CAAC,CAQf"}
1
+ {"version":3,"file":"installations.d.ts","sourceRoot":"","sources":["../../src/app/installations.ts"],"names":[],"mappings":"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"}