@nanonets/graft 0.22.0 → 0.23.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.
- package/README.md +11 -10
- package/dist/app/checkout.d.ts +0 -32
- package/dist/app/checkout.d.ts.map +1 -1
- package/dist/app/checkout.js +0 -45
- package/dist/app/checkout.js.map +1 -1
- package/dist/app/identity.d.ts +0 -56
- package/dist/app/identity.d.ts.map +1 -1
- package/dist/app/identity.js +0 -119
- package/dist/app/identity.js.map +1 -1
- package/dist/app/main.js +0 -8
- package/dist/app/main.js.map +1 -1
- package/dist/app/server.d.ts +0 -20
- package/dist/app/server.d.ts.map +1 -1
- package/dist/app/server.js +0 -121
- package/dist/app/server.js.map +1 -1
- package/dist/ask/ask.d.ts +0 -3
- package/dist/ask/ask.d.ts.map +1 -1
- package/dist/ask/ask.js +1 -3
- package/dist/ask/ask.js.map +1 -1
- package/dist/brand.d.ts.map +1 -1
- package/dist/brand.js +4 -1
- package/dist/brand.js.map +1 -1
- package/dist/check/learning-edits.d.ts +9 -0
- package/dist/check/learning-edits.d.ts.map +1 -0
- package/dist/check/learning-edits.js +62 -0
- package/dist/check/learning-edits.js.map +1 -0
- package/dist/claude/format.d.ts +1 -9
- package/dist/claude/format.d.ts.map +1 -1
- package/dist/claude/format.js +6 -21
- package/dist/claude/format.js.map +1 -1
- package/dist/claude/hook-layers.d.ts.map +1 -1
- package/dist/claude/hook-layers.js +5 -3
- package/dist/claude/hook-layers.js.map +1 -1
- package/dist/claude/hooks.d.ts +6 -0
- package/dist/claude/hooks.d.ts.map +1 -1
- package/dist/claude/hooks.js +101 -14
- package/dist/claude/hooks.js.map +1 -1
- package/dist/claude/init.d.ts +38 -7
- package/dist/claude/init.d.ts.map +1 -1
- package/dist/claude/init.js +172 -33
- package/dist/claude/init.js.map +1 -1
- package/dist/claude/settings-merge.d.ts +23 -0
- package/dist/claude/settings-merge.d.ts.map +1 -1
- package/dist/claude/settings-merge.js +103 -7
- package/dist/claude/settings-merge.js.map +1 -1
- package/dist/claude/shim-template.d.ts.map +1 -1
- package/dist/claude/shim-template.js +39 -3
- package/dist/claude/shim-template.js.map +1 -1
- package/dist/claude/skill-template.d.ts +4 -3
- package/dist/claude/skill-template.d.ts.map +1 -1
- package/dist/claude/skill-template.js +25 -10
- package/dist/claude/skill-template.js.map +1 -1
- package/dist/claude/state.d.ts +1 -1
- package/dist/claude/state.d.ts.map +1 -1
- package/dist/cli-picker.d.ts +15 -0
- package/dist/cli-picker.d.ts.map +1 -1
- package/dist/cli-picker.js +33 -3
- package/dist/cli-picker.js.map +1 -1
- package/dist/cli.js +141 -60
- package/dist/cli.js.map +1 -1
- package/dist/cloud/diff.d.ts +2 -0
- package/dist/cloud/diff.d.ts.map +1 -1
- package/dist/cloud/diff.js +1 -0
- package/dist/cloud/diff.js.map +1 -1
- package/dist/context/map-dir.d.ts +13 -0
- package/dist/context/map-dir.d.ts.map +1 -0
- package/dist/context/map-dir.js +67 -0
- package/dist/context/map-dir.js.map +1 -0
- package/dist/context/node-file.d.ts +4 -3
- package/dist/context/node-file.d.ts.map +1 -1
- package/dist/context/node-file.js +18 -4
- package/dist/context/node-file.js.map +1 -1
- package/dist/hosts/claude-global.d.ts.map +1 -1
- package/dist/hosts/claude-global.js +31 -11
- package/dist/hosts/claude-global.js.map +1 -1
- package/dist/hosts/config-write.js +1 -1
- package/dist/hosts/config-write.js.map +1 -1
- package/dist/hosts/retract.d.ts.map +1 -1
- package/dist/hosts/retract.js +15 -6
- package/dist/hosts/retract.js.map +1 -1
- package/dist/notes/branches.d.ts +18 -1
- package/dist/notes/branches.d.ts.map +1 -1
- package/dist/notes/branches.js +73 -7
- package/dist/notes/branches.js.map +1 -1
- package/dist/notes/cold-start.d.ts +54 -4
- package/dist/notes/cold-start.d.ts.map +1 -1
- package/dist/notes/cold-start.js +97 -36
- package/dist/notes/cold-start.js.map +1 -1
- package/dist/notes/edit-overlap.d.ts +62 -0
- package/dist/notes/edit-overlap.d.ts.map +1 -0
- package/dist/notes/edit-overlap.js +202 -0
- package/dist/notes/edit-overlap.js.map +1 -0
- package/dist/notes/notes.d.ts +25 -4
- package/dist/notes/notes.d.ts.map +1 -1
- package/dist/notes/notes.js +65 -15
- package/dist/notes/notes.js.map +1 -1
- package/dist/notes/pr-reviews.d.ts +108 -0
- package/dist/notes/pr-reviews.d.ts.map +1 -0
- package/dist/notes/pr-reviews.js +325 -0
- package/dist/notes/pr-reviews.js.map +1 -0
- package/dist/notes/repo-trail.d.ts +3 -1
- package/dist/notes/repo-trail.d.ts.map +1 -1
- package/dist/notes/repo-trail.js +40 -3
- package/dist/notes/repo-trail.js.map +1 -1
- package/dist/notes/session-cost.d.ts +16 -4
- package/dist/notes/session-cost.d.ts.map +1 -1
- package/dist/notes/session-cost.js +120 -11
- package/dist/notes/session-cost.js.map +1 -1
- package/dist/telemetry/contract.d.ts.map +1 -1
- package/dist/telemetry/contract.js +6 -5
- package/dist/telemetry/contract.js.map +1 -1
- package/dist/upkeep-run.d.ts.map +1 -1
- package/dist/upkeep-run.js +4 -2
- package/dist/upkeep-run.js.map +1 -1
- package/dist/upkeep.js +2 -2
- package/dist/upkeep.js.map +1 -1
- package/dist/util/state.d.ts.map +1 -1
- package/dist/util/state.js +2 -1
- package/dist/util/state.js.map +1 -1
- package/package.json +1 -1
- package/dist/app/brain-build-process.d.ts +0 -22
- package/dist/app/brain-build-process.d.ts.map +0 -1
- package/dist/app/brain-build-process.js +0 -129
- package/dist/app/brain-build-process.js.map +0 -1
- package/dist/app/brain-build-worker.d.ts +0 -35
- package/dist/app/brain-build-worker.d.ts.map +0 -1
- package/dist/app/brain-build-worker.js +0 -56
- package/dist/app/brain-build-worker.js.map +0 -1
- package/dist/app/brain-build.d.ts +0 -160
- package/dist/app/brain-build.d.ts.map +0 -1
- package/dist/app/brain-build.js +0 -278
- package/dist/app/brain-build.js.map +0 -1
- package/dist/app/history.d.ts +0 -163
- package/dist/app/history.d.ts.map +0 -1
- package/dist/app/history.js +0 -319
- package/dist/app/history.js.map +0 -1
- package/dist/app/sources.d.ts +0 -81
- package/dist/app/sources.d.ts.map +0 -1
- package/dist/app/sources.js +0 -470
- package/dist/app/sources.js.map +0 -1
package/README.md
CHANGED
|
@@ -22,7 +22,7 @@ Trail-code gives Claude Code, Cursor, Codex and other coding agents a map of you
|
|
|
22
22
|
<a href="https://trailhq.com/graft"><img src="https://img.shields.io/badge/website-trailhq.com/graft-E5484D?style=for-the-badge" /></a>
|
|
23
23
|
<a href="https://discord.gg/zxmKweAA29"><img src="https://img.shields.io/badge/Discord-join-5865F2?style=for-the-badge&logo=discord&logoColor=white" /></a>
|
|
24
24
|
<a href="https://www.npmjs.com/package/@trailhq/trail-code"><img src="https://img.shields.io/npm/v/%40trailhq%2Ftrail-code?style=for-the-badge&logo=npm&logoColor=white&label=npm" /></a>
|
|
25
|
-
<a href="https://www.npmjs.com/package/@
|
|
25
|
+
<a href="https://www.npmjs.com/package/@nanonets/graft"><img src="https://img.shields.io/npm/dm/%40nanonets%2Fgraft?style=for-the-badge&logo=npm&logoColor=white&label=downloads" /></a>
|
|
26
26
|
<a href="https://nodejs.org"><img src="https://img.shields.io/node/v/%40trailhq%2Ftrail-code?style=for-the-badge&logo=nodedotjs&logoColor=white" /></a>
|
|
27
27
|
<img src="https://img.shields.io/badge/TypeScript-strict-3178C6?style=for-the-badge&logo=typescript&logoColor=white" />
|
|
28
28
|
<img src="https://img.shields.io/badge/License-MIT-20C997?style=for-the-badge" />
|
|
@@ -64,13 +64,13 @@ npm install -g @trailhq/trail-code && trail init
|
|
|
64
64
|
| Greps and opens file after file to find the code it needs | Gets the right files and functions with your prompt |
|
|
65
65
|
| Re-explores code a teammate already figured out last week | Starts from their learning: what they decided, what they ruled out, what to watch out for |
|
|
66
66
|
| Undoes a teammate's decision, because it never knew about it | `trail check` flags it before the PR, quoting who decided it and why |
|
|
67
|
-
| Finds out at merge time that a teammate changed the same
|
|
67
|
+
| Finds out at merge time that a teammate changed the same code | Says so right after it edits code a teammate's open branch also changes, and whether the two clash |
|
|
68
68
|
| Has to be told the same things every session | Starts from what you've told it before: `trail init` finds what you said more than once in your past sessions |
|
|
69
69
|
| You write and update CLAUDE.md by hand | Learnings are saved from your conversations, in files you can read |
|
|
70
70
|
|
|
71
71
|
**Same model, more tasks solved.** On SWE-bench Verified (real GitHub issues, graded by the maintainers' own tests), Claude Sonnet 5 solved **33 of 50** issues with the graft map and **27 of 50** without it, using 23% fewer tokens. [Details](#swe-bench-verified)
|
|
72
72
|
|
|
73
|
-
**Cheaper and faster.** Across 162 runs of the same agent on the same tasks: **32% lower cost**, **42% fewer tokens**, **60% less time**, and the same share of correct answers. On
|
|
73
|
+
**Cheaper and faster.** Across 162 runs of the same agent on the same tasks: **32% lower cost**, **42% fewer uncached input tokens**, **60% less time**, and the same share of correct answers. On PocketBase, 15 real tasks ran **21% cheaper** and **14% faster**. [Details](#benchmark)
|
|
74
74
|
|
|
75
75
|
---
|
|
76
76
|
|
|
@@ -94,7 +94,7 @@ npm install -g @trailhq/trail-code && trail init
|
|
|
94
94
|
Trail-code has two parts. Both run on your machine.
|
|
95
95
|
|
|
96
96
|
1. **The graft map: your code.** `trail init` parses your repo with tree-sitter into a map of every file, function and who calls what. No model, no API key. It refreshes itself when the code changes, uncommitted edits included. Your agent gets pointers to the matching files and functions with each prompt, and sees what depends on a file right after it edits it.
|
|
97
|
-
2. **Learnings: what you, your agents and your team know.** When a session works something out, or you correct how something is done, your agent saves it as a learning. The next session on that code, yours or a teammate's, starts from it instead of digging again. Learnings about the code are committed with the code; learnings about you stay on your machine. On day one, `trail init` starts you off with what you told Claude more than once in your past sessions.
|
|
97
|
+
2. **Learnings: what you, your agents and your team know.** When a session works something out, or you correct how something is done, your agent saves it as a learning. The next session on that code, yours or a teammate's, starts from it instead of digging again. Learnings about the code are committed with the code; learnings about you stay on your machine. On day one, `trail init` starts you off with what you told Claude more than once in your past sessions, and what reviewers flagged on more than one of the repo's merged PRs.
|
|
98
98
|
|
|
99
99
|
The graft map tells your agent *where* things are. Learnings tell it *why* they are that way, and *how* the work gets done here.
|
|
100
100
|
|
|
@@ -152,11 +152,11 @@ The graft map builds that understanding once, and keeps it current:
|
|
|
152
152
|
- **Plain files you can read.** Linked markdown nodes your agent opens and greps like any other file. No embeddings, no index to keep warm.
|
|
153
153
|
- **Summaries if you want them.** `trail build --deep` adds plain-English summaries of each part of the system, written by the model provider you choose, under your own key.
|
|
154
154
|
|
|
155
|
-
| | Cold
|
|
155
|
+
| | Cold agent | Agent with the graft map |
|
|
156
156
|
|---|---|---|
|
|
157
157
|
| SWE-bench Verified, 50 real issues | 27 solved | **33 solved (+12 pts)** |
|
|
158
|
-
| Our benchmark, 162 runs | baseline | **32% lower cost, 42% fewer tokens, 60% less time** |
|
|
159
|
-
|
|
|
158
|
+
| Our benchmark, 162 runs | baseline | **32% lower cost, 42% fewer uncached input tokens, 60% less time** |
|
|
159
|
+
| PocketBase, 15 real tasks | baseline | **21% cheaper, 14% faster** |
|
|
160
160
|
|
|
161
161
|
How it is measured: [Benchmark](#benchmark), [SWE-bench Verified](#swe-bench-verified) and [Tested on popular repos](#tested-on-popular-repos). How it is built: [the reference](#how-the-graph-gets-built).
|
|
162
162
|
|
|
@@ -226,10 +226,10 @@ checking 1 changed file against 1 learning and 0 skills
|
|
|
226
226
|
|
|
227
227
|
Kumar's Claude explains the override in the commit.
|
|
228
228
|
|
|
229
|
-
**4. Anirudh
|
|
229
|
+
**4. Anirudh edits the same constant.** Kumar's branch isn't merged yet. Right after the edit, Anirudh's Claude reads Kumar's change and says something like:
|
|
230
230
|
|
|
231
231
|
```text
|
|
232
|
-
|
|
232
|
+
🔀 trail · Kumar is also changing defaultRetryMax on kumar/retry. He raises it to 10 and you're lowering it, so the two clash.
|
|
233
233
|
```
|
|
234
234
|
|
|
235
235
|
None of this needs a server. Learnings travel through git, like the code they are about.
|
|
@@ -312,6 +312,7 @@ Coming soon: a Trail workspace, for your team's view across repos. A team page w
|
|
|
312
312
|
- **Personal learnings.** Kept in `~/.trail`. Never committed, never uploaded.
|
|
313
313
|
- **Repo learnings.** Files in your repo, shared through git like any other file.
|
|
314
314
|
- **Your past sessions.** `trail init` reads your own messages from Claude Code's transcripts for the repo, on your machine. Your own Claude Code does the reading, with Claude Sonnet under your login, so your messages go only to Anthropic, and it counts toward your Claude usage. None of it goes to Trail.
|
|
315
|
+
- **Your PR reviews.** When `gh` is installed and signed in, `trail init` reads the review comments on the repo's last 50 merged PRs with it, under your GitHub login. Anything that looks like a secret is taken out, and your own Claude Code reads them the same way. None of it goes to Trail.
|
|
315
316
|
- **If you connect a Trail workspace.** No learning goes to Trail until you do. Once connected, the learnings in the repos you picked go to Trail, including those on teammates' pushed branches. So does a record of each search and check that used them: the search text, the files, and whose learnings were shown. That is how the team page counts reuse.
|
|
316
317
|
- **Anonymous usage stats.** Buckets and fixed labels only, never the title, text or paths of a learning. [`TELEMETRY.md`](TELEMETRY.md) lists every field. Turn it off with `trail telemetry disable` or `DO_NOT_TRACK=1`.
|
|
317
318
|
|
|
@@ -611,7 +612,7 @@ When Claude Code is selected (it is by default), it gets more than the skill fil
|
|
|
611
612
|
- **auto-sync**: every query brings the graph up to date first, so an answer always describes the code as it is right now, uncommitted edits included. A query refreshes only what it reads; the markdown under `graft/` is refreshed by the background rebuild at the end of a turn that touched code. Both are structural and `$0`; auto-sync never calls the LLM on its own
|
|
612
613
|
- **context on tap**: each prompt pulls in the matching nodes and the learnings left on that code; editing a file surfaces what depends on it ("blast radius"); new sessions start with the repo map and how many learnings there are
|
|
613
614
|
- **the ask to save a learning**: after a turn of real digging with nothing saved, Claude is asked once a session to save one
|
|
614
|
-
- **overlap with teammates**: at session start, and every few minutes, it reads
|
|
615
|
+
- **overlap with teammates**: at session start, and every few minutes, it reads what teammates' open branches change, skipping any already merged or closed; when Claude edits a function or constant one of them also changes, it reads their change and tells you whether the two clash
|
|
615
616
|
|
|
616
617
|
<p align="center">
|
|
617
618
|
<img src="assets/graft-hook-blast-radius-demo.gif" alt="The post-edit hook: editing node-file.ts prints its blast radius (who depends on it) inline, the statusline flips stale → syncing → synced on its own, and the same dependents light up in the viewer" width="820"/>
|
package/dist/app/checkout.d.ts
CHANGED
|
@@ -41,38 +41,6 @@ export interface Checkout {
|
|
|
41
41
|
* {@link headDiffBase} is entirely about.
|
|
42
42
|
*/
|
|
43
43
|
export declare function checkoutPullRequest(req: CheckoutRequest): Checkout;
|
|
44
|
-
/** What a plain-repository checkout needs: no pull request, just a ref. */
|
|
45
|
-
export interface RepoCheckoutRequest {
|
|
46
|
-
owner: string;
|
|
47
|
-
repo: string;
|
|
48
|
-
/** Branch to read. Empty means "whatever HEAD points at" (the default branch). */
|
|
49
|
-
ref?: string;
|
|
50
|
-
token: string;
|
|
51
|
-
/** How much history to fetch. The default is deeper than a PR review needs
|
|
52
|
-
* because commit MESSAGES are the payload here, not a diff — 50 commits is a
|
|
53
|
-
* fortnight on an active repo and would mine almost nothing. */
|
|
54
|
-
depth?: number;
|
|
55
|
-
api?: string;
|
|
56
|
-
log?: (msg: string) => void;
|
|
57
|
-
}
|
|
58
|
-
/** A plain checkout: the tree, the commit it landed on, and the cleanup. */
|
|
59
|
-
export interface RepoCheckout {
|
|
60
|
-
dir: string;
|
|
61
|
-
headSha: string;
|
|
62
|
-
/** The branch actually checked out, resolved when the caller named none. */
|
|
63
|
-
branch: string;
|
|
64
|
-
cleanup: () => void;
|
|
65
|
-
}
|
|
66
|
-
/**
|
|
67
|
-
* Clone one repository at a ref, shallow, for reading rather than reviewing.
|
|
68
|
-
*
|
|
69
|
-
* Separate from {@link checkoutPullRequest} rather than a flag on it: that
|
|
70
|
-
* function's whole shape — two refspecs, the merge/head fallback, the diff-base
|
|
71
|
-
* resolution — exists to answer "what does this pull request change", and none
|
|
72
|
-
* of it applies to "read this repository's history". Sharing the hardened `git`
|
|
73
|
-
* runner is the part worth reusing.
|
|
74
|
-
*/
|
|
75
|
-
export declare function checkoutRepository(req: RepoCheckoutRequest): RepoCheckout;
|
|
76
44
|
/** Never let a token reach a log line, even inside git's own error text. */
|
|
77
45
|
export declare function redact(text: string, token: string): string;
|
|
78
46
|
//# sourceMappingURL=checkout.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"checkout.d.ts","sourceRoot":"","sources":["../../src/app/checkout.ts"],"names":[],"mappings":"AAoCA,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;uDAEmD;IACnD,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CAC7B;AAED,MAAM,WAAW,QAAQ;IACvB;kDAC8C;IAC9C,GAAG,EAAE,MAAM,CAAC;IACZ,+CAA+C;IAC/C,IAAI,EAAE,MAAM,CAAC;IACb;0EACsE;IACtE,GAAG,EAAE,OAAO,GAAG,MAAM,CAAC;IACtB;wBACoB;IACpB,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AA+CD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,eAAe,GAAG,QAAQ,CA2DlE;
|
|
1
|
+
{"version":3,"file":"checkout.d.ts","sourceRoot":"","sources":["../../src/app/checkout.ts"],"names":[],"mappings":"AAoCA,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;uDAEmD;IACnD,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CAC7B;AAED,MAAM,WAAW,QAAQ;IACvB;kDAC8C;IAC9C,GAAG,EAAE,MAAM,CAAC;IACZ,+CAA+C;IAC/C,IAAI,EAAE,MAAM,CAAC;IACb;0EACsE;IACtE,GAAG,EAAE,OAAO,GAAG,MAAM,CAAC;IACtB;wBACoB;IACpB,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AA+CD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,eAAe,GAAG,QAAQ,CA2DlE;AAsED,4EAA4E;AAC5E,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAI1D"}
|
package/dist/app/checkout.js
CHANGED
|
@@ -141,51 +141,6 @@ export function checkoutPullRequest(req) {
|
|
|
141
141
|
log(`${tag}: no refs/pull/${req.number}/merge (GitHub deletes it when a pull request closes), reviewing refs/pull/${req.number}/head against ${against}`);
|
|
142
142
|
return { dir, base: "refs/graft/base", ref, cleanup };
|
|
143
143
|
}
|
|
144
|
-
/**
|
|
145
|
-
* Clone one repository at a ref, shallow, for reading rather than reviewing.
|
|
146
|
-
*
|
|
147
|
-
* Separate from {@link checkoutPullRequest} rather than a flag on it: that
|
|
148
|
-
* function's whole shape — two refspecs, the merge/head fallback, the diff-base
|
|
149
|
-
* resolution — exists to answer "what does this pull request change", and none
|
|
150
|
-
* of it applies to "read this repository's history". Sharing the hardened `git`
|
|
151
|
-
* runner is the part worth reusing.
|
|
152
|
-
*/
|
|
153
|
-
export function checkoutRepository(req) {
|
|
154
|
-
const host = (req.api ?? "https://github.com").replace(/\/$/, "");
|
|
155
|
-
const dir = mkdtempSync(join(tmpdir(), `graft-repo-${req.owner}-${req.repo}-`));
|
|
156
|
-
const cleanup = () => rmSync(dir, { recursive: true, force: true });
|
|
157
|
-
const log = req.log ?? (() => { });
|
|
158
|
-
const tag = `${req.owner}/${req.repo}`;
|
|
159
|
-
const fail = (step, err) => {
|
|
160
|
-
cleanup();
|
|
161
|
-
throw new Error(`${tag}: ${step} failed: ${redact(err, req.token)}`);
|
|
162
|
-
};
|
|
163
|
-
const init = git(dir, ["init", "--quiet", "--initial-branch=graft-tmp"]);
|
|
164
|
-
if (!init.ok)
|
|
165
|
-
fail("init", init.err);
|
|
166
|
-
const remote = git(dir, ["remote", "add", "origin", `${host}/${req.owner}/${req.repo}.git`]);
|
|
167
|
-
if (!remote.ok)
|
|
168
|
-
fail("remote", remote.err);
|
|
169
|
-
const depth = req.depth ?? REPO_FETCH_DEPTH;
|
|
170
|
-
// A named branch is fetched by name; with none, `HEAD` resolves to whatever
|
|
171
|
-
// the remote's default branch is, which is what the caller means by "the
|
|
172
|
-
// repository" and saves an API round trip to look the name up.
|
|
173
|
-
const refspec = req.ref
|
|
174
|
-
? `+refs/heads/${req.ref}:refs/graft/head`
|
|
175
|
-
: `+HEAD:refs/graft/head`;
|
|
176
|
-
const fetched = git(dir, ["fetch", "--quiet", `--depth=${depth}`, "--no-recurse-submodules", "origin", refspec], req.token);
|
|
177
|
-
if (!fetched.ok)
|
|
178
|
-
fail("fetch", fetched.err);
|
|
179
|
-
const co = git(dir, ["checkout", "--quiet", "--detach", "refs/graft/head"]);
|
|
180
|
-
if (!co.ok)
|
|
181
|
-
fail("checkout", co.err);
|
|
182
|
-
const headSha = line(dir, ["rev-parse", "HEAD"]) ?? "";
|
|
183
|
-
const branch = req.ref ?? line(dir, ["rev-parse", "--abbrev-ref", "origin/HEAD"]) ?? "";
|
|
184
|
-
log(`${tag}: read ${req.ref || "HEAD"} at ${short(headSha)} (${depth} commits deep)`);
|
|
185
|
-
return { dir, headSha, branch: branch.replace(/^origin\//, ""), cleanup };
|
|
186
|
-
}
|
|
187
|
-
/** Default history depth for a repository read. See RepoCheckoutRequest.depth. */
|
|
188
|
-
const REPO_FETCH_DEPTH = 500;
|
|
189
144
|
/** The one fetch each attempt makes: the PR ref to review plus the base branch. */
|
|
190
145
|
function fetchArgs(req, pull, deepen = false) {
|
|
191
146
|
return [
|
package/dist/app/checkout.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"checkout.js","sourceRoot":"","sources":["../../src/app/checkout.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"checkout.js","sourceRoot":"","sources":["../../src/app/checkout.ts"],"names":[],"mappings":"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"}
|
package/dist/app/identity.d.ts
CHANGED
|
@@ -31,62 +31,6 @@ export type Fetch = (url: string, init?: {
|
|
|
31
31
|
* Tokens last an hour and a busy repository can fire a dozen webhooks a minute;
|
|
32
32
|
* without the cache every one of them spends a round trip and a signature.
|
|
33
33
|
*/
|
|
34
|
-
/**
|
|
35
|
-
* The installation id for one repository.
|
|
36
|
-
*
|
|
37
|
-
* Every existing caller gets the id from a webhook payload, because every
|
|
38
|
-
* existing caller is reacting to one. A request that names a repository instead
|
|
39
|
-
* has to look it up, and this is the only endpoint that answers it: it is
|
|
40
|
-
* App-JWT authed, so it works before any installation token exists.
|
|
41
|
-
*
|
|
42
|
-
* Returns null when the App is not installed on the repository — which is the
|
|
43
|
-
* expected answer for "the user pasted a repo we cannot see", not an error.
|
|
44
|
-
*/
|
|
45
|
-
/**
|
|
46
|
-
* Headers for a GitHub REST call, with or without a token.
|
|
47
|
-
*
|
|
48
|
-
* An empty token means anonymous, and anonymous has to mean NO authorization
|
|
49
|
-
* header — `Bearer ` with nothing after it is a 401, not a fallback. That
|
|
50
|
-
* distinction is the whole reason this is a function: a public repository read
|
|
51
|
-
* without an installation goes down exactly this path.
|
|
52
|
-
*/
|
|
53
|
-
export declare function ghHeaders(token: string): Record<string, string>;
|
|
54
|
-
/**
|
|
55
|
-
* An installation token for reading PUBLIC repositories the App is not
|
|
56
|
-
* installed on.
|
|
57
|
-
*
|
|
58
|
-
* GitHub answers any public resource to any installation token, at 5,000
|
|
59
|
-
* requests an hour. Anonymous answers the same resources at 60 an hour for the
|
|
60
|
-
* whole box, which one repository's pull-request walk spends in a minute — so
|
|
61
|
-
* without this, the second public repo of the hour reads as "we cannot see it".
|
|
62
|
-
*
|
|
63
|
-
* `owner` is our own account, so this borrows OUR installation's rate limit
|
|
64
|
-
* rather than some customer's. Falls back to the first installation, and to
|
|
65
|
-
* null when the App has none, in which case the caller reads anonymously.
|
|
66
|
-
*/
|
|
67
|
-
export declare function publicReadInstallation(creds: AppCredentials, owner: string, fetchImpl: Fetch, nowMs?: number, api?: string): Promise<number | null>;
|
|
68
|
-
export declare function installationFor(creds: AppCredentials, owner: string, repo: string, fetchImpl: Fetch, nowMs?: number, api?: string): Promise<number | null>;
|
|
69
|
-
/**
|
|
70
|
-
* Why a repository is unreachable, and where to send the user to fix it.
|
|
71
|
-
*
|
|
72
|
-
* Two failures look identical from `/repos/{o}/{r}/installation` — both 404 —
|
|
73
|
-
* and they need different sentences and different links. Either the App is not
|
|
74
|
-
* on the account at all, so they install it; or it is installed and this
|
|
75
|
-
* repository simply is not in its selected list, so they edit that list. Telling
|
|
76
|
-
* someone to install an App they already installed is the kind of dead end that
|
|
77
|
-
* ends the session.
|
|
78
|
-
*
|
|
79
|
-
* ownerId is the account's numeric id, which preselects the right account on
|
|
80
|
-
* GitHub's install screen. There is no equivalent for preselecting a repository;
|
|
81
|
-
* GitHub owns that checkbox list.
|
|
82
|
-
*/
|
|
83
|
-
export interface RepoAccessGap {
|
|
84
|
-
reason: "not_installed" | "repo_not_selected";
|
|
85
|
-
ownerId: number | null;
|
|
86
|
-
installationId: number | null;
|
|
87
|
-
}
|
|
88
|
-
/** Which of the two gaps applies to owner/repo. */
|
|
89
|
-
export declare function repoAccessGap(creds: AppCredentials, owner: string, fetchImpl: Fetch, nowMs?: number, api?: string): Promise<RepoAccessGap>;
|
|
90
34
|
export declare class InstallationTokens {
|
|
91
35
|
private readonly creds;
|
|
92
36
|
private readonly fetchImpl;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../../src/app/identity.ts"],"names":[],"mappings":"AAuBA,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,oCAAoC;IACpC,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;GAMG;AACH,wBAAgB,MAAM,CAAC,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAOnE;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,iFAAiF;AACjF,MAAM,MAAM,KAAK,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,KAAK,OAAO,CAAC;IACxH,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;CAC7B,CAAC,CAAC;AAOH;;;;;GAKG;AACH
|
|
1
|
+
{"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../../src/app/identity.ts"],"names":[],"mappings":"AAuBA,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,oCAAoC;IACpC,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;GAMG;AACH,wBAAgB,MAAM,CAAC,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAOnE;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,iFAAiF;AACjF,MAAM,MAAM,KAAK,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,KAAK,OAAO,CAAC;IACxH,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;CAC7B,CAAC,CAAC;AAOH;;;;;GAKG;AACH,qBAAa,kBAAkB;IAI3B,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,GAAG;IACpB,OAAO,CAAC,QAAQ,CAAC,GAAG;IANtB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAiC;gBAGpC,KAAK,EAAE,cAAc,EACrB,SAAS,EAAE,KAAK,EAChB,GAAG,GAAE,MAAM,MAAiB,EAC5B,GAAG,SAA2B;IAG3C,GAAG,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAuBlD,8EAA8E;IAC9E,UAAU,CAAC,cAAc,EAAE,MAAM,GAAG,IAAI;CAGzC;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAMjG"}
|
package/dist/app/identity.js
CHANGED
|
@@ -38,125 +38,6 @@ export function appJwt(creds, nowMs) {
|
|
|
38
38
|
* Tokens last an hour and a busy repository can fire a dozen webhooks a minute;
|
|
39
39
|
* without the cache every one of them spends a round trip and a signature.
|
|
40
40
|
*/
|
|
41
|
-
/**
|
|
42
|
-
* The installation id for one repository.
|
|
43
|
-
*
|
|
44
|
-
* Every existing caller gets the id from a webhook payload, because every
|
|
45
|
-
* existing caller is reacting to one. A request that names a repository instead
|
|
46
|
-
* has to look it up, and this is the only endpoint that answers it: it is
|
|
47
|
-
* App-JWT authed, so it works before any installation token exists.
|
|
48
|
-
*
|
|
49
|
-
* Returns null when the App is not installed on the repository — which is the
|
|
50
|
-
* expected answer for "the user pasted a repo we cannot see", not an error.
|
|
51
|
-
*/
|
|
52
|
-
/**
|
|
53
|
-
* Headers for a GitHub REST call, with or without a token.
|
|
54
|
-
*
|
|
55
|
-
* An empty token means anonymous, and anonymous has to mean NO authorization
|
|
56
|
-
* header — `Bearer ` with nothing after it is a 401, not a fallback. That
|
|
57
|
-
* distinction is the whole reason this is a function: a public repository read
|
|
58
|
-
* without an installation goes down exactly this path.
|
|
59
|
-
*/
|
|
60
|
-
export function ghHeaders(token) {
|
|
61
|
-
const headers = {
|
|
62
|
-
accept: "application/vnd.github+json",
|
|
63
|
-
"user-agent": "graft-app",
|
|
64
|
-
};
|
|
65
|
-
if (token)
|
|
66
|
-
headers.authorization = `Bearer ${token}`;
|
|
67
|
-
return headers;
|
|
68
|
-
}
|
|
69
|
-
/**
|
|
70
|
-
* An installation token for reading PUBLIC repositories the App is not
|
|
71
|
-
* installed on.
|
|
72
|
-
*
|
|
73
|
-
* GitHub answers any public resource to any installation token, at 5,000
|
|
74
|
-
* requests an hour. Anonymous answers the same resources at 60 an hour for the
|
|
75
|
-
* whole box, which one repository's pull-request walk spends in a minute — so
|
|
76
|
-
* without this, the second public repo of the hour reads as "we cannot see it".
|
|
77
|
-
*
|
|
78
|
-
* `owner` is our own account, so this borrows OUR installation's rate limit
|
|
79
|
-
* rather than some customer's. Falls back to the first installation, and to
|
|
80
|
-
* null when the App has none, in which case the caller reads anonymously.
|
|
81
|
-
*/
|
|
82
|
-
export async function publicReadInstallation(creds, owner, fetchImpl, nowMs = Date.now(), api = "https://api.github.com") {
|
|
83
|
-
const res = await fetchImpl(`${api}/app/installations?per_page=100`, {
|
|
84
|
-
headers: {
|
|
85
|
-
authorization: `Bearer ${appJwt(creds, nowMs)}`,
|
|
86
|
-
accept: "application/vnd.github+json",
|
|
87
|
-
"user-agent": "graft-app",
|
|
88
|
-
},
|
|
89
|
-
});
|
|
90
|
-
if (!res.ok)
|
|
91
|
-
return null;
|
|
92
|
-
const list = JSON.parse(await res.text());
|
|
93
|
-
if (!Array.isArray(list) || list.length === 0)
|
|
94
|
-
return null;
|
|
95
|
-
const wanted = owner.toLowerCase();
|
|
96
|
-
const mine = list.find((i) => (i.account?.login ?? "").toLowerCase() === wanted);
|
|
97
|
-
return (mine ?? list[0]).id ?? null;
|
|
98
|
-
}
|
|
99
|
-
export async function installationFor(creds, owner, repo, fetchImpl, nowMs = Date.now(), api = "https://api.github.com") {
|
|
100
|
-
const res = await fetchImpl(`${api}/repos/${owner}/${repo}/installation`, {
|
|
101
|
-
headers: {
|
|
102
|
-
authorization: `Bearer ${appJwt(creds, nowMs)}`,
|
|
103
|
-
accept: "application/vnd.github+json",
|
|
104
|
-
"user-agent": "graft-app",
|
|
105
|
-
},
|
|
106
|
-
});
|
|
107
|
-
if (res.status === 404)
|
|
108
|
-
return null;
|
|
109
|
-
if (!res.ok) {
|
|
110
|
-
const body = await res.text();
|
|
111
|
-
throw new Error(`installation lookup for ${owner}/${repo} failed: ${res.status} ${body.slice(0, 200)}`);
|
|
112
|
-
}
|
|
113
|
-
const parsed = JSON.parse(await res.text());
|
|
114
|
-
return typeof parsed.id === "number" ? parsed.id : null;
|
|
115
|
-
}
|
|
116
|
-
/** Which of the two gaps applies to owner/repo. */
|
|
117
|
-
export async function repoAccessGap(creds, owner, fetchImpl, nowMs = Date.now(), api = "https://api.github.com") {
|
|
118
|
-
const headers = {
|
|
119
|
-
authorization: `Bearer ${appJwt(creds, nowMs)}`,
|
|
120
|
-
accept: "application/vnd.github+json",
|
|
121
|
-
"user-agent": "graft-app",
|
|
122
|
-
};
|
|
123
|
-
// An account is an org or a user and the endpoints differ, so try the org one
|
|
124
|
-
// and fall back rather than making the caller know which it is.
|
|
125
|
-
for (const path of [`/orgs/${owner}/installation`, `/users/${owner}/installation`]) {
|
|
126
|
-
try {
|
|
127
|
-
const res = await fetchImpl(`${api}${path}`, { headers });
|
|
128
|
-
if (!res.ok)
|
|
129
|
-
continue;
|
|
130
|
-
const parsed = JSON.parse(await res.text());
|
|
131
|
-
return {
|
|
132
|
-
reason: "repo_not_selected",
|
|
133
|
-
ownerId: parsed.account?.id ?? null,
|
|
134
|
-
installationId: parsed.id ?? null,
|
|
135
|
-
};
|
|
136
|
-
}
|
|
137
|
-
catch {
|
|
138
|
-
// Try the other shape; a network failure here only costs a less specific
|
|
139
|
-
// message, never the whole answer.
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
return { reason: "not_installed", ownerId: await ownerIdFor(owner, fetchImpl, api), installationId: null };
|
|
143
|
-
}
|
|
144
|
-
/** The account's numeric id, for preselecting it on the install screen. */
|
|
145
|
-
async function ownerIdFor(owner, fetchImpl, api) {
|
|
146
|
-
try {
|
|
147
|
-
// Unauthenticated: a public account's id is public, and this runs on a path
|
|
148
|
-
// where the App has no installation token to use anyway.
|
|
149
|
-
const res = await fetchImpl(`${api}/users/${owner}`, {
|
|
150
|
-
headers: { accept: "application/vnd.github+json", "user-agent": "graft-app" },
|
|
151
|
-
});
|
|
152
|
-
if (!res.ok)
|
|
153
|
-
return null;
|
|
154
|
-
return JSON.parse(await res.text()).id ?? null;
|
|
155
|
-
}
|
|
156
|
-
catch {
|
|
157
|
-
return null;
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
41
|
export class InstallationTokens {
|
|
161
42
|
creds;
|
|
162
43
|
fetchImpl;
|
package/dist/app/identity.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"identity.js","sourceRoot":"","sources":["../../src/app/identity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEtE,iFAAiF;AACjF,MAAM,SAAS,GAAG,GAAG,CAAC,CAAC,uDAAuD;AAC9E,2DAA2D;AAC3D,MAAM,eAAe,GAAG,MAAM,CAAC;AAE/B,MAAM,MAAM,GAAG,CAAC,CAAkB,EAAU,EAAE,CAC5C,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;AAQ9F;;;;;;GAMG;AACH,MAAM,UAAU,MAAM,CAAC,KAAqB,EAAE,KAAa;IACzD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC1C,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;IACpE,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,GAAG,SAAS,EAAE,GAAG,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IACxF,MAAM,MAAM,GAAG,UAAU,CAAC,YAAY,CAAC,CAAC;IACxC,MAAM,CAAC,MAAM,CAAC,GAAG,MAAM,IAAI,OAAO,EAAE,CAAC,CAAC;IACtC,OAAO,GAAG,MAAM,IAAI,OAAO,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC;AACzE,CAAC;AAmBD;;;;;GAKG;AACH
|
|
1
|
+
{"version":3,"file":"identity.js","sourceRoot":"","sources":["../../src/app/identity.ts"],"names":[],"mappings":"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"}
|
package/dist/app/main.js
CHANGED
|
@@ -43,14 +43,6 @@ const { server, queue } = createApp({
|
|
|
43
43
|
// server that will not start reviews nothing at all, which is strictly worse
|
|
44
44
|
// than one whose old links go stale.
|
|
45
45
|
pageDir: process.env.GRAFT_PAGE_DIR,
|
|
46
|
-
// Optional for the same reason as pageDir: unset simply disables
|
|
47
|
-
// `POST /brain/build`, and a deployment that only reviews pull requests wants
|
|
48
|
-
// exactly that. The route is the one place the app writes to the platform, so
|
|
49
|
-
// it stays off until someone deliberately turns it on.
|
|
50
|
-
brainBuildSecret: process.env.GRAFT_BRAIN_BUILD_SECRET,
|
|
51
|
-
brainBaseUrl: process.env.GRAFT_BRAIN_URL,
|
|
52
|
-
publicToken: process.env.GRAFT_PUBLIC_GITHUB_TOKEN || process.env.GITHUB_TOKEN,
|
|
53
|
-
publicOwner: process.env.GRAFT_PUBLIC_INSTALLATION_OWNER,
|
|
54
46
|
});
|
|
55
47
|
/**
|
|
56
48
|
* Finish what is in flight before dying.
|
package/dist/app/main.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.js","sourceRoot":"","sources":["../../src/app/main.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,SAAS,QAAQ,CAAC,IAAY;IAC5B,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAChC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,CAAC,KAAK,CAAC,KAAK,IAAI,cAAc,CAAC,CAAC;QACvC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;GAIG;AACH,SAAS,UAAU;IACjB,MAAM,GAAG,GAAG,QAAQ,CAAC,uBAAuB,CAAC,CAAC;IAC9C,MAAM,GAAG,GAAG,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;IAClE,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC;QAC3D,OAAO,CAAC,KAAK,CAAC,8DAA8D,CAAC,CAAC;QAC9E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC;AAC9C,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,SAAS,CAAC;IAClC,KAAK,EAAE,QAAQ,CAAC,cAAc,CAAC;IAC/B,UAAU,EAAE,UAAU,EAAE;IACxB,aAAa,EAAE,QAAQ,CAAC,sBAAsB,CAAC;IAC/C,SAAS,EAAE,QAAQ,CAAC,kBAAkB,CAAC;IACvC,IAAI;IACJ,WAAW,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,CAAC,CAAC;IACvD,8EAA8E;IAC9E,4EAA4E;IAC5E,6EAA6E;IAC7E,6EAA6E;IAC7E,qCAAqC;IACrC,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,cAAc;
|
|
1
|
+
{"version":3,"file":"main.js","sourceRoot":"","sources":["../../src/app/main.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,SAAS,QAAQ,CAAC,IAAY;IAC5B,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAChC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,CAAC,KAAK,CAAC,KAAK,IAAI,cAAc,CAAC,CAAC;QACvC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;GAIG;AACH,SAAS,UAAU;IACjB,MAAM,GAAG,GAAG,QAAQ,CAAC,uBAAuB,CAAC,CAAC;IAC9C,MAAM,GAAG,GAAG,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;IAClE,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC;QAC3D,OAAO,CAAC,KAAK,CAAC,8DAA8D,CAAC,CAAC;QAC9E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC;AAC9C,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,SAAS,CAAC;IAClC,KAAK,EAAE,QAAQ,CAAC,cAAc,CAAC;IAC/B,UAAU,EAAE,UAAU,EAAE;IACxB,aAAa,EAAE,QAAQ,CAAC,sBAAsB,CAAC;IAC/C,SAAS,EAAE,QAAQ,CAAC,kBAAkB,CAAC;IACvC,IAAI;IACJ,WAAW,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,CAAC,CAAC;IACvD,8EAA8E;IAC9E,4EAA4E;IAC5E,6EAA6E;IAC7E,6EAA6E;IAC7E,qCAAqC;IACrC,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,cAAc;CACpC,CAAC,CAAC;AAEH;;;;;;GAMG;AACH,KAAK,MAAM,MAAM,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAU,EAAE,CAAC;IACpD,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE;QACtB,OAAO,CAAC,GAAG,CAAC,GAAG,MAAM,cAAc,KAAK,CAAC,IAAI,SAAS,CAAC,CAAC;QACxD,MAAM,CAAC,KAAK,EAAE,CAAC;QACf,KAAK,KAAK,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/C,UAAU,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,KAAK,EAAE,CAAC;IACpD,CAAC,CAAC,CAAC;AACL,CAAC"}
|
package/dist/app/server.d.ts
CHANGED
|
@@ -19,19 +19,12 @@
|
|
|
19
19
|
import { type Server } from "node:http";
|
|
20
20
|
import { type ReviewJob } from "./events.js";
|
|
21
21
|
import { type AppCredentials, type Fetch } from "./identity.js";
|
|
22
|
-
import { buildRepoIntoBrain, checkRepoAccess } from "./brain-build.js";
|
|
23
22
|
import { PageStore } from "./pages.js";
|
|
24
23
|
import { WorkQueue } from "./queue.js";
|
|
25
24
|
import type { reviewPullRequest } from "./review.js";
|
|
26
25
|
/** Seams for tests: nothing here has a default that touches the network. */
|
|
27
26
|
export interface AppSeams {
|
|
28
27
|
fetch?: Fetch;
|
|
29
|
-
/** Swapped out so a test can assert what the route handed the builder without
|
|
30
|
-
* cloning a repository or reaching GitHub. */
|
|
31
|
-
brainBuild?: typeof buildRepoIntoBrain;
|
|
32
|
-
/** Swapped out so a test can assert the access route's answers without
|
|
33
|
-
* reaching GitHub. */
|
|
34
|
-
brainAccess?: typeof checkRepoAccess;
|
|
35
28
|
/** Swapped out to assert what the queue was handed, without a clone — and, being
|
|
36
29
|
* called in-process, without the fork the default reviewer does. */
|
|
37
30
|
review?: typeof reviewPullRequest;
|
|
@@ -39,19 +32,6 @@ export interface AppSeams {
|
|
|
39
32
|
}
|
|
40
33
|
export interface AppConfig extends AppCredentials {
|
|
41
34
|
webhookSecret: string;
|
|
42
|
-
/** Shared secret for `POST /brain/build`. That route is called by the
|
|
43
|
-
* platform, not by GitHub, so it cannot use the webhook's payload signature —
|
|
44
|
-
* it takes a bearer token instead. Unset disables the route entirely, which
|
|
45
|
-
* is the right default for a deployment that only reviews pull requests. */
|
|
46
|
-
brainBuildSecret?: string;
|
|
47
|
-
/** Platform base URL the digest is posted to. Defaults to production. */
|
|
48
|
-
brainBaseUrl?: string;
|
|
49
|
-
/** Token for reading public repositories the App is not installed on.
|
|
50
|
-
* Optional — without it the read borrows one of our own installation's
|
|
51
|
-
* tokens, and only falls back to anonymous if the App has none. */
|
|
52
|
-
publicToken?: string;
|
|
53
|
-
/** Whose installation to borrow for that. Defaults to ours. */
|
|
54
|
-
publicOwner?: string;
|
|
55
35
|
/** Public origin, for the links put in comments, e.g. https://graft.example.com */
|
|
56
36
|
publicUrl: string;
|
|
57
37
|
/** Where pages are kept, so a restart does not strand the links already posted. */
|
package/dist/app/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/app/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,EAAsC,KAAK,MAAM,EAAuB,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/app/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,EAAsC,KAAK,MAAM,EAAuB,MAAM,WAAW,CAAC;AACjG,OAAO,EAAwB,KAAK,SAAS,EAAE,MAAM,aAAa,CAAC;AACnE,OAAO,EAAuC,KAAK,cAAc,EAAE,KAAK,KAAK,EAAE,MAAM,eAAe,CAAC;AACrG,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEvC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAKrD,4EAA4E;AAC5E,MAAM,WAAW,QAAQ;IACvB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd;wEACoE;IACpE,MAAM,CAAC,EAAE,OAAO,iBAAiB,CAAC;IAClC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,SAAU,SAAQ,cAAc;IAC/C,aAAa,EAAE,MAAM,CAAC;IACtB,mFAAmF;IACnF,SAAS,EAAE,MAAM,CAAC;IAClB,mFAAmF;IACnF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CAC7B;AAED,wBAAgB,SAAS,CACvB,MAAM,EAAE,SAAS,EACjB,KAAK,GAAE,QAAa,GACnB;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAAC,KAAK,EAAE,SAAS,CAAA;CAAE,CAkFnE"}
|