@nanonets/graft 0.16.0 → 0.18.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 +9 -2
- package/dist/app/brain-build.d.ts +66 -0
- package/dist/app/brain-build.d.ts.map +1 -0
- package/dist/app/brain-build.js +169 -0
- package/dist/app/brain-build.js.map +1 -0
- package/dist/app/checkout.d.ts +53 -3
- package/dist/app/checkout.d.ts.map +1 -1
- package/dist/app/checkout.js +195 -27
- package/dist/app/checkout.js.map +1 -1
- package/dist/app/events.d.ts +7 -0
- package/dist/app/events.d.ts.map +1 -1
- package/dist/app/events.js +7 -2
- package/dist/app/events.js.map +1 -1
- package/dist/app/history.d.ts +128 -0
- package/dist/app/history.d.ts.map +1 -0
- package/dist/app/history.js +269 -0
- package/dist/app/history.js.map +1 -0
- package/dist/app/identity.d.ts +33 -0
- package/dist/app/identity.d.ts.map +1 -1
- package/dist/app/identity.js +72 -0
- package/dist/app/identity.js.map +1 -1
- package/dist/app/main.js +12 -0
- package/dist/app/main.js.map +1 -1
- package/dist/app/pages.d.ts +17 -0
- package/dist/app/pages.d.ts.map +1 -1
- package/dist/app/pages.js +112 -5
- package/dist/app/pages.js.map +1 -1
- package/dist/app/review-process.d.ts +66 -0
- package/dist/app/review-process.d.ts.map +1 -0
- package/dist/app/review-process.js +199 -0
- package/dist/app/review-process.js.map +1 -0
- package/dist/app/review-worker.d.ts +2 -0
- package/dist/app/review-worker.d.ts.map +1 -0
- package/dist/app/review-worker.js +108 -0
- package/dist/app/review-worker.js.map +1 -0
- package/dist/app/review.d.ts.map +1 -1
- package/dist/app/review.js +4 -1
- package/dist/app/review.js.map +1 -1
- package/dist/app/server.d.ts +22 -2
- package/dist/app/server.d.ts.map +1 -1
- package/dist/app/server.js +77 -3
- package/dist/app/server.js.map +1 -1
- package/dist/app/sources.d.ts +68 -0
- package/dist/app/sources.d.ts.map +1 -0
- package/dist/app/sources.js +341 -0
- package/dist/app/sources.js.map +1 -0
- package/dist/ask/ask.d.ts +6 -0
- package/dist/ask/ask.d.ts.map +1 -1
- package/dist/ask/ask.js +30 -2
- package/dist/ask/ask.js.map +1 -1
- package/dist/brain/attach.d.ts +44 -0
- package/dist/brain/attach.d.ts.map +1 -0
- package/dist/brain/attach.js +63 -0
- package/dist/brain/attach.js.map +1 -0
- package/dist/brain/connect.d.ts +59 -0
- package/dist/brain/connect.d.ts.map +1 -0
- package/dist/brain/connect.js +80 -0
- package/dist/brain/connect.js.map +1 -0
- package/dist/brain/link.d.ts +82 -0
- package/dist/brain/link.d.ts.map +1 -0
- package/dist/brain/link.js +136 -0
- package/dist/brain/link.js.map +1 -0
- package/dist/brain/push.d.ts +72 -0
- package/dist/brain/push.d.ts.map +1 -0
- package/dist/brain/push.js +191 -0
- package/dist/brain/push.js.map +1 -0
- package/dist/brain/wire.d.ts +38 -0
- package/dist/brain/wire.d.ts.map +1 -0
- package/dist/brain/wire.js +133 -0
- package/dist/brain/wire.js.map +1 -0
- package/dist/claude/format.d.ts.map +1 -1
- package/dist/claude/format.js +10 -3
- package/dist/claude/format.js.map +1 -1
- package/dist/claude/hooks.d.ts.map +1 -1
- package/dist/claude/hooks.js +32 -1
- package/dist/claude/hooks.js.map +1 -1
- package/dist/claude/init.d.ts +5 -0
- package/dist/claude/init.d.ts.map +1 -1
- package/dist/claude/init.js +9 -1
- package/dist/claude/init.js.map +1 -1
- package/dist/claude/session-metrics.d.ts +10 -0
- package/dist/claude/session-metrics.d.ts.map +1 -1
- package/dist/claude/session-metrics.js +25 -0
- package/dist/claude/session-metrics.js.map +1 -1
- package/dist/claude/settings-merge.d.ts +18 -0
- package/dist/claude/settings-merge.d.ts.map +1 -1
- package/dist/claude/settings-merge.js +42 -8
- package/dist/claude/settings-merge.js.map +1 -1
- package/dist/claude/skill-template.d.ts.map +1 -1
- package/dist/claude/skill-template.js +6 -0
- package/dist/claude/skill-template.js.map +1 -1
- package/dist/claude/state.d.ts +14 -0
- package/dist/claude/state.d.ts.map +1 -1
- package/dist/claude/state.js.map +1 -1
- package/dist/claude/tally.d.ts +27 -0
- package/dist/claude/tally.d.ts.map +1 -1
- package/dist/claude/tally.js +74 -1
- package/dist/claude/tally.js.map +1 -1
- package/dist/cli.js +210 -3
- package/dist/cli.js.map +1 -1
- package/dist/context/price.d.ts +49 -0
- package/dist/context/price.d.ts.map +1 -0
- package/dist/context/price.js +83 -0
- package/dist/context/price.js.map +1 -0
- package/dist/context/savings.d.ts +13 -3
- package/dist/context/savings.d.ts.map +1 -1
- package/dist/context/savings.js +44 -5
- package/dist/context/savings.js.map +1 -1
- package/dist/hosts/claude-global.d.ts +33 -0
- package/dist/hosts/claude-global.d.ts.map +1 -0
- package/dist/hosts/claude-global.js +118 -0
- package/dist/hosts/claude-global.js.map +1 -0
- package/dist/hosts/plan.d.ts.map +1 -1
- package/dist/hosts/plan.js +5 -1
- package/dist/hosts/plan.js.map +1 -1
- package/dist/hosts/retract.d.ts.map +1 -1
- package/dist/hosts/retract.js +33 -13
- package/dist/hosts/retract.js.map +1 -1
- package/dist/hosts/sections.d.ts +23 -2
- package/dist/hosts/sections.d.ts.map +1 -1
- package/dist/hosts/sections.js +25 -9
- package/dist/hosts/sections.js.map +1 -1
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +33 -4
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/tools.d.ts.map +1 -1
- package/dist/mcp/tools.js +5 -1
- package/dist/mcp/tools.js.map +1 -1
- package/dist/telemetry/gate.d.ts +14 -0
- package/dist/telemetry/gate.d.ts.map +1 -1
- package/dist/telemetry/gate.js +18 -2
- package/dist/telemetry/gate.js.map +1 -1
- package/dist/upkeep-run.d.ts.map +1 -1
- package/dist/upkeep-run.js +12 -2
- package/dist/upkeep-run.js.map +1 -1
- package/dist/upkeep.d.ts +18 -0
- package/dist/upkeep.d.ts.map +1 -1
- package/dist/upkeep.js +38 -0
- package/dist/upkeep.js.map +1 -1
- package/dist/util/state.d.ts +9 -0
- package/dist/util/state.d.ts.map +1 -1
- package/dist/util/state.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One review, in its own process. Forked by `./review-process.ts`, never imported.
|
|
3
|
+
*
|
|
4
|
+
* The whole file is glue: it waits for a `start`, calls the same
|
|
5
|
+
* `reviewPullRequest` the server used to call directly, and reports back. Nothing
|
|
6
|
+
* about a review changes by running here — that is the point. The two dependencies
|
|
7
|
+
* it cannot satisfy locally are wired to the parent instead:
|
|
8
|
+
*
|
|
9
|
+
* - `token` is handed over in the start message. This process never holds the
|
|
10
|
+
* App's private key, so a hostile repository that somehow got code running here
|
|
11
|
+
* finds one repository's short-lived token and not the App's identity.
|
|
12
|
+
* - `publish` is a round trip. The page store and the webhook secret its signed
|
|
13
|
+
* URLs are keyed on live with the HTTP server, and a page is only useful to the
|
|
14
|
+
* process that will serve it.
|
|
15
|
+
*
|
|
16
|
+
* Deliberately no `graft` state of its own: no lock, no cache directory, no
|
|
17
|
+
* telemetry. A review works on a throwaway clone in /tmp and takes its findings
|
|
18
|
+
* with it when it exits.
|
|
19
|
+
*/
|
|
20
|
+
import { reviewPullRequest } from "./review.js";
|
|
21
|
+
/** Publish requests waiting on the parent, by sequence number. */
|
|
22
|
+
const awaiting = new Map();
|
|
23
|
+
let seq = 0;
|
|
24
|
+
/** Fire and forget. `process.send` throws on a closed channel, and a log line is
|
|
25
|
+
* not worth crashing a review over — the `disconnect` handler below has already
|
|
26
|
+
* decided what a closed channel means. */
|
|
27
|
+
const send = (msg) => {
|
|
28
|
+
if (!process.connected)
|
|
29
|
+
return;
|
|
30
|
+
try {
|
|
31
|
+
process.send?.(msg);
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
/* parent went away mid-review */
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
/** Close the channel, or leave if it is already gone. Either way this is the end of
|
|
38
|
+
* the process — see the `disconnect` handler below. */
|
|
39
|
+
function bye() {
|
|
40
|
+
try {
|
|
41
|
+
if (process.connected)
|
|
42
|
+
process.disconnect?.();
|
|
43
|
+
else
|
|
44
|
+
process.exit(0);
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
process.exit(0);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* The last word, then close the channel.
|
|
52
|
+
*
|
|
53
|
+
* Sent with a callback because that callback is the flush: `done` has to be on the
|
|
54
|
+
* wire before the channel closes, or the parent sees a process that exited without
|
|
55
|
+
* reporting and turns a finished review into a failure.
|
|
56
|
+
*/
|
|
57
|
+
function finish(msg) {
|
|
58
|
+
if (!process.connected)
|
|
59
|
+
return bye();
|
|
60
|
+
try {
|
|
61
|
+
process.send?.(msg, () => bye());
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
bye();
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
async function run(start) {
|
|
68
|
+
try {
|
|
69
|
+
const result = await reviewPullRequest(start.job, {
|
|
70
|
+
token: async () => start.token,
|
|
71
|
+
fetch: globalThis.fetch,
|
|
72
|
+
api: start.api,
|
|
73
|
+
publish: (_job, html) => new Promise((resolve) => {
|
|
74
|
+
const id = (seq += 1);
|
|
75
|
+
awaiting.set(id, resolve);
|
|
76
|
+
send({ t: "publish", seq: id, html });
|
|
77
|
+
}),
|
|
78
|
+
log: (msg) => send({ t: "log", msg }),
|
|
79
|
+
});
|
|
80
|
+
finish({ t: "done", result });
|
|
81
|
+
}
|
|
82
|
+
catch (err) {
|
|
83
|
+
// `reviewPullRequest` has already run the token through `redact`, so this
|
|
84
|
+
// message is safe to put in the parent's log — which is where it is going.
|
|
85
|
+
finish({ t: "failed", message: err instanceof Error ? err.message : String(err) });
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* No parent, no point.
|
|
90
|
+
*
|
|
91
|
+
* A review whose channel has closed has nowhere to publish a page and nobody to
|
|
92
|
+
* report to. If the server process died, nothing will SIGKILL this one either, and
|
|
93
|
+
* without this it would sit in a clone for the rest of the parent's 15-minute
|
|
94
|
+
* ceiling. Going now leaves the same throwaway tree behind that a SIGKILL would —
|
|
95
|
+
* what it does not do is spend a quarter of an hour producing a review no one can
|
|
96
|
+
* receive.
|
|
97
|
+
*/
|
|
98
|
+
process.on("disconnect", () => process.exit(0));
|
|
99
|
+
process.on("message", (raw) => {
|
|
100
|
+
const msg = raw;
|
|
101
|
+
if (msg.t === "start") {
|
|
102
|
+
void run(msg);
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
awaiting.get(msg.seq)?.(msg.url);
|
|
106
|
+
awaiting.delete(msg.seq);
|
|
107
|
+
});
|
|
108
|
+
//# sourceMappingURL=review-worker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"review-worker.js","sourceRoot":"","sources":["../../src/app/review-worker.ts"],"names":[],"mappings":"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"}
|
package/dist/app/review.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"review.d.ts","sourceRoot":"","sources":["../../src/app/review.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAE3C,iFAAiF;AACjF,eAAO,MAAM,MAAM,gCAAgC,CAAC;AAIpD,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,CAAC,cAAc,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACnD,KAAK,EAAE,KAAK,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;qBAEiB;IACjB,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACnE,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CAC7B;AAED,MAAM,WAAW,YAAY;IAC3B,uDAAuD;IACvD,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,wBAAsB,iBAAiB,CAAC,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,YAAY,CAAC,
|
|
1
|
+
{"version":3,"file":"review.d.ts","sourceRoot":"","sources":["../../src/app/review.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAE3C,iFAAiF;AACjF,eAAO,MAAM,MAAM,gCAAgC,CAAC;AAIpD,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,CAAC,cAAc,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACnD,KAAK,EAAE,KAAK,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;qBAEiB;IACjB,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACnE,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CAC7B;AAED,MAAM,WAAW,YAAY;IAC3B,uDAAuD;IACvD,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,wBAAsB,iBAAiB,CAAC,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,YAAY,CAAC,CAsD/F"}
|
package/dist/app/review.js
CHANGED
|
@@ -21,7 +21,10 @@ const DEPTH = 2;
|
|
|
21
21
|
export async function reviewPullRequest(job, deps) {
|
|
22
22
|
const log = deps.log ?? (() => { });
|
|
23
23
|
const token = await deps.token(job.installationId);
|
|
24
|
-
|
|
24
|
+
// `log` goes into the checkout because a closed pull request is reviewed from
|
|
25
|
+
// `refs/pull/N/head` against a different basis than an open one, and the only
|
|
26
|
+
// place that difference is visible afterwards is this line.
|
|
27
|
+
const checkout = checkoutPullRequest({ owner: job.owner, repo: job.repo, number: job.number, baseRef: job.baseRef, token, log });
|
|
25
28
|
try {
|
|
26
29
|
log(`${job.owner}/${job.repo}#${job.number}: building`);
|
|
27
30
|
await buildGraph(checkout.dir);
|
package/dist/app/review.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"review.js","sourceRoot":"","sources":["../../src/app/review.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,mBAAmB,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAI5D,iFAAiF;AACjF,MAAM,CAAC,MAAM,MAAM,GAAG,6BAA6B,CAAC;AAEpD,MAAM,KAAK,GAAG,CAAC,CAAC;AAqBhB,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,GAAc,EAAE,IAAgB;IACtE,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IACnC,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IACnD,MAAM,QAAQ,GAAG,mBAAmB,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"review.js","sourceRoot":"","sources":["../../src/app/review.ts"],"names":[],"mappings":"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"}
|
package/dist/app/server.d.ts
CHANGED
|
@@ -9,24 +9,44 @@
|
|
|
9
9
|
* GitHub retries a delivery it considers failed and gives up after ten seconds,
|
|
10
10
|
* while a review takes tens of them — so the handler validates, queues, and
|
|
11
11
|
* answers 202. Everything real happens on the queue.
|
|
12
|
+
*
|
|
13
|
+
* "On the queue" used to mean "on this event loop", and that was the whole of a
|
|
14
|
+
* multi-minute outage: a review is synchronous end to end, so one in flight left
|
|
15
|
+
* this server unable to answer /healthz or serve a page it had already produced.
|
|
16
|
+
* The queue now runs each review in its own process (`./review-process.ts`) and
|
|
17
|
+
* everything in here is I/O again.
|
|
12
18
|
*/
|
|
13
19
|
import { type Server } from "node:http";
|
|
14
20
|
import { type ReviewJob } from "./events.js";
|
|
15
21
|
import { type AppCredentials, type Fetch } from "./identity.js";
|
|
22
|
+
import { buildRepoIntoBrain } from "./brain-build.js";
|
|
16
23
|
import { PageStore } from "./pages.js";
|
|
17
24
|
import { WorkQueue } from "./queue.js";
|
|
18
|
-
import { reviewPullRequest } from "./review.js";
|
|
25
|
+
import type { reviewPullRequest } from "./review.js";
|
|
19
26
|
/** Seams for tests: nothing here has a default that touches the network. */
|
|
20
27
|
export interface AppSeams {
|
|
21
28
|
fetch?: Fetch;
|
|
22
|
-
/** Swapped out
|
|
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 to assert what the queue was handed, without a clone — and, being
|
|
33
|
+
* called in-process, without the fork the default reviewer does. */
|
|
23
34
|
review?: typeof reviewPullRequest;
|
|
24
35
|
now?: () => number;
|
|
25
36
|
}
|
|
26
37
|
export interface AppConfig extends AppCredentials {
|
|
27
38
|
webhookSecret: string;
|
|
39
|
+
/** Shared secret for `POST /brain/build`. That route is called by the
|
|
40
|
+
* platform, not by GitHub, so it cannot use the webhook's payload signature —
|
|
41
|
+
* it takes a bearer token instead. Unset disables the route entirely, which
|
|
42
|
+
* is the right default for a deployment that only reviews pull requests. */
|
|
43
|
+
brainBuildSecret?: string;
|
|
44
|
+
/** Platform base URL the digest is posted to. Defaults to production. */
|
|
45
|
+
brainBaseUrl?: string;
|
|
28
46
|
/** Public origin, for the links put in comments, e.g. https://graft.example.com */
|
|
29
47
|
publicUrl: string;
|
|
48
|
+
/** Where pages are kept, so a restart does not strand the links already posted. */
|
|
49
|
+
pageDir?: string;
|
|
30
50
|
port?: number;
|
|
31
51
|
concurrency?: number;
|
|
32
52
|
api?: string;
|
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
|
|
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;AAEjG,OAAO,EAAwB,KAAK,SAAS,EAAE,MAAM,aAAa,CAAC;AACnE,OAAO,EAAuC,KAAK,cAAc,EAAE,KAAK,KAAK,EAAE,MAAM,eAAe,CAAC;AACrG,OAAO,EAAE,kBAAkB,EAA8C,MAAM,kBAAkB,CAAC;AAClG,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;kDAC8C;IAC9C,UAAU,CAAC,EAAE,OAAO,kBAAkB,CAAC;IACvC;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;;;gFAG4E;IAC5E,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,yEAAyE;IACzE,YAAY,CAAC,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,CAoInE"}
|
package/dist/app/server.js
CHANGED
|
@@ -9,21 +9,29 @@
|
|
|
9
9
|
* GitHub retries a delivery it considers failed and gives up after ten seconds,
|
|
10
10
|
* while a review takes tens of them — so the handler validates, queues, and
|
|
11
11
|
* answers 202. Everything real happens on the queue.
|
|
12
|
+
*
|
|
13
|
+
* "On the queue" used to mean "on this event loop", and that was the whole of a
|
|
14
|
+
* multi-minute outage: a review is synchronous end to end, so one in flight left
|
|
15
|
+
* this server unable to answer /healthz or serve a page it had already produced.
|
|
16
|
+
* The queue now runs each review in its own process (`./review-process.ts`) and
|
|
17
|
+
* everything in here is I/O again.
|
|
12
18
|
*/
|
|
13
19
|
import { createServer } from "node:http";
|
|
20
|
+
import { timingSafeEqual } from "node:crypto";
|
|
14
21
|
import { jobKey, reviewJobFor } from "./events.js";
|
|
15
22
|
import { InstallationTokens, verifySignature } from "./identity.js";
|
|
23
|
+
import { buildRepoIntoBrain, RepoNotAccessibleError } from "./brain-build.js";
|
|
16
24
|
import { PageStore } from "./pages.js";
|
|
17
25
|
import { WorkQueue } from "./queue.js";
|
|
18
|
-
import {
|
|
26
|
+
import { reviewInChildProcess } from "./review-process.js";
|
|
19
27
|
/** A webhook body larger than this is not a pull_request event we can use. */
|
|
20
28
|
const MAX_BODY_BYTES = 2 * 1024 * 1024;
|
|
21
29
|
export function createApp(config, seams = {}) {
|
|
22
30
|
const log = config.log ?? ((msg) => console.log(msg));
|
|
23
31
|
const fetchImpl = seams.fetch ?? globalThis.fetch;
|
|
24
|
-
const review = seams.review ??
|
|
32
|
+
const review = seams.review ?? reviewInChildProcess;
|
|
25
33
|
const tokens = new InstallationTokens(config, fetchImpl, seams.now ?? Date.now, config.api);
|
|
26
|
-
const pages = new PageStore({ secret: config.webhookSecret });
|
|
34
|
+
const pages = new PageStore({ secret: config.webhookSecret, dir: config.pageDir });
|
|
27
35
|
const origin = config.publicUrl.replace(/\/$/, "");
|
|
28
36
|
const queue = new WorkQueue(async (job) => {
|
|
29
37
|
const started = Date.now();
|
|
@@ -88,6 +96,60 @@ export function createApp(config, seams = {}) {
|
|
|
88
96
|
log(`${jobKey(decided.job)}: queued${decided.job.fromFork ? " (fork)" : ""}`);
|
|
89
97
|
return send(res, 202, "application/json", JSON.stringify({ queued: true }));
|
|
90
98
|
}
|
|
99
|
+
// Build one repository into a brain, on demand. Called by the platform when
|
|
100
|
+
// someone pastes a repository URL during onboarding — there is no webhook
|
|
101
|
+
// behind it, so it authenticates with a bearer token rather than a payload
|
|
102
|
+
// signature.
|
|
103
|
+
if (req.method === "POST" && url.pathname === "/brain/build") {
|
|
104
|
+
if (!config.brainBuildSecret)
|
|
105
|
+
return send(res, 404, "text/plain", "not found");
|
|
106
|
+
// Compared in constant time for the same reason verifySignature is: this
|
|
107
|
+
// is a long-lived shared secret, and a timing oracle on it is worth more
|
|
108
|
+
// to an attacker than one on a per-payload signature.
|
|
109
|
+
if (!bearerMatches(header(req, "authorization"), config.brainBuildSecret)) {
|
|
110
|
+
return send(res, 401, "text/plain", "unauthorized");
|
|
111
|
+
}
|
|
112
|
+
const body = await readBody(req);
|
|
113
|
+
if (body === null)
|
|
114
|
+
return send(res, 413, "text/plain", "payload too large");
|
|
115
|
+
let job;
|
|
116
|
+
try {
|
|
117
|
+
job = JSON.parse(body);
|
|
118
|
+
}
|
|
119
|
+
catch {
|
|
120
|
+
return send(res, 400, "text/plain", "bad json");
|
|
121
|
+
}
|
|
122
|
+
// brainId/brainToken are optional: without them the digest comes back in
|
|
123
|
+
// the response for the caller to ingest itself. See BrainBuildJob.
|
|
124
|
+
if (!job.owner || !job.repo) {
|
|
125
|
+
return send(res, 400, "application/json", JSON.stringify({ error: "owner and repo are required" }));
|
|
126
|
+
}
|
|
127
|
+
// Synchronous on purpose: the caller is a person waiting on a screen, and
|
|
128
|
+
// the platform's own import job is what makes the SLOW half (extraction and
|
|
129
|
+
// placement) asynchronous. This half is a shallow clone and a graph build.
|
|
130
|
+
try {
|
|
131
|
+
// The deployment's platform URL wins over anything a caller sends, so a
|
|
132
|
+
// request cannot redirect a repository's history to another host.
|
|
133
|
+
if (config.brainBaseUrl)
|
|
134
|
+
job.brainBaseUrl = config.brainBaseUrl;
|
|
135
|
+
const built = await (seams.brainBuild ?? buildRepoIntoBrain)(job, {
|
|
136
|
+
creds: config,
|
|
137
|
+
fetch: fetchImpl,
|
|
138
|
+
api: config.api,
|
|
139
|
+
log,
|
|
140
|
+
now: seams.now,
|
|
141
|
+
});
|
|
142
|
+
return send(res, 202, "application/json", JSON.stringify(built));
|
|
143
|
+
}
|
|
144
|
+
catch (e) {
|
|
145
|
+
if (e instanceof RepoNotAccessibleError) {
|
|
146
|
+
return send(res, 404, "application/json", JSON.stringify({ error: e.message, ...e.gap }));
|
|
147
|
+
}
|
|
148
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
149
|
+
log(`brain build ${job.owner}/${job.repo} failed: ${msg}`);
|
|
150
|
+
return send(res, 502, "application/json", JSON.stringify({ error: msg }));
|
|
151
|
+
}
|
|
152
|
+
}
|
|
91
153
|
return send(res, 404, "text/plain", "not found");
|
|
92
154
|
}
|
|
93
155
|
if (config.port !== undefined)
|
|
@@ -98,6 +160,18 @@ const header = (req, name) => {
|
|
|
98
160
|
const v = req.headers[name];
|
|
99
161
|
return Array.isArray(v) ? v[0] : v;
|
|
100
162
|
};
|
|
163
|
+
/** Constant-time `Authorization: Bearer <secret>` check. */
|
|
164
|
+
function bearerMatches(headerValue, secret) {
|
|
165
|
+
const prefix = "Bearer ";
|
|
166
|
+
if (!headerValue || !headerValue.startsWith(prefix))
|
|
167
|
+
return false;
|
|
168
|
+
const given = Buffer.from(headerValue.slice(prefix.length));
|
|
169
|
+
const want = Buffer.from(secret);
|
|
170
|
+
// timingSafeEqual throws on a length mismatch, which is itself a leak of the
|
|
171
|
+
// secret's length — but one byte of length is not worth a branch that skips
|
|
172
|
+
// the comparison, and the lengths here are fixed by deployment config.
|
|
173
|
+
return given.length === want.length && timingSafeEqual(given, want);
|
|
174
|
+
}
|
|
101
175
|
function send(res, status, type, body, extra = {}) {
|
|
102
176
|
res.writeHead(status, { "content-type": type, ...extra });
|
|
103
177
|
res.end(body);
|
package/dist/app/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/app/server.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/app/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import type { Fetch } from "./identity.js";
|
|
2
|
+
/** What kind of thing a source is, so extraction can weigh it. */
|
|
3
|
+
export type SourceKind = "agent_instructions" | "decision_doc" | "lint_config" | "ci_config" | "codeowners" | "branch_protection" | "revert" | "test_name" | "declined_issue";
|
|
4
|
+
/** One rule-bearing artefact. */
|
|
5
|
+
export interface HistorySource {
|
|
6
|
+
kind: SourceKind;
|
|
7
|
+
/** Repo-relative path, or an API-ish label like "branch protection: main". */
|
|
8
|
+
path: string;
|
|
9
|
+
text: string;
|
|
10
|
+
/** Deep link, where one exists (an issue, a reverted commit). */
|
|
11
|
+
url?: string;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Instruction files the team already wrote for coding agents.
|
|
15
|
+
*
|
|
16
|
+
* The single highest-precision source in a repository: someone sat down and
|
|
17
|
+
* wrote imperative rules for a machine to follow. Nothing has to be inferred.
|
|
18
|
+
*
|
|
19
|
+
* Graft's own managed blocks are stripped first. Without that the brain reads
|
|
20
|
+
* back graft's instructions about using graft, and then graft carries them into
|
|
21
|
+
* the same file — a loop that fills the rulebook with itself.
|
|
22
|
+
*/
|
|
23
|
+
export declare function readAgentInstructions(root: string): HistorySource[];
|
|
24
|
+
/** Architecture decision records and the docs that read like them. */
|
|
25
|
+
export declare function readDecisionDocs(root: string): HistorySource[];
|
|
26
|
+
/**
|
|
27
|
+
* Rules the team already encoded for a machine: linters, formatters, and the
|
|
28
|
+
* checks CI insists on. Nothing to infer — extraction only has to phrase them.
|
|
29
|
+
*/
|
|
30
|
+
export declare function readCodifiedRules(root: string): HistorySource[];
|
|
31
|
+
/** Who must approve what. A hard constraint, stated as a file. */
|
|
32
|
+
export declare function readCodeowners(root: string): HistorySource[];
|
|
33
|
+
/**
|
|
34
|
+
* Commits that undid another commit.
|
|
35
|
+
*
|
|
36
|
+
* "We tried this and took it back" is a rule available from nowhere else, and
|
|
37
|
+
* it is the one kind of history that says what NOT to do. The body of a revert
|
|
38
|
+
* usually names the commit it undoes and, when the author bothered, why.
|
|
39
|
+
*/
|
|
40
|
+
export declare function readReverts(root: string, max?: number): HistorySource[];
|
|
41
|
+
/**
|
|
42
|
+
* Test names, which are invariants someone wrote deliberately.
|
|
43
|
+
*
|
|
44
|
+
* `never retries on a card decline` is a rule stated as an assertion. Read from
|
|
45
|
+
* the graph's own symbols rather than by re-parsing, so this costs nothing:
|
|
46
|
+
* a test function is already a node.
|
|
47
|
+
*
|
|
48
|
+
* Only names that read like a sentence are kept. `TestFoo` is a label;
|
|
49
|
+
* `rejects an expired token` is a claim about how the system must behave.
|
|
50
|
+
*/
|
|
51
|
+
export declare function readTestNames(symbolNames: Array<{
|
|
52
|
+
name: string;
|
|
53
|
+
path: string;
|
|
54
|
+
}>, max?: number): HistorySource[];
|
|
55
|
+
/**
|
|
56
|
+
* Issues closed as not planned.
|
|
57
|
+
*
|
|
58
|
+
* A decision NOT to build something, which is half of what a codebase's rules
|
|
59
|
+
* are and is invisible everywhere else — nothing was committed, so no commit
|
|
60
|
+
* message records it.
|
|
61
|
+
*/
|
|
62
|
+
export declare function readDeclinedIssues(owner: string, repo: string, token: string, fetchImpl: Fetch, api?: string, max?: number): Promise<HistorySource[]>;
|
|
63
|
+
/** Required checks and reviewers on the default branch. */
|
|
64
|
+
export declare function readBranchProtection(owner: string, repo: string, branch: string, token: string, fetchImpl: Fetch, api?: string): Promise<HistorySource[]>;
|
|
65
|
+
export declare function budgetSources(sources: HistorySource[], maxChars?: number, maxCount?: number): HistorySource[];
|
|
66
|
+
/** Repo-relative path, for readers handed an absolute one. */
|
|
67
|
+
export declare function relPath(root: string, abs: string): string;
|
|
68
|
+
//# sourceMappingURL=sources.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sources.d.ts","sourceRoot":"","sources":["../../src/app/sources.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAE3C,kEAAkE;AAClE,MAAM,MAAM,UAAU,GAClB,oBAAoB,GACpB,cAAc,GACd,aAAa,GACb,WAAW,GACX,YAAY,GACZ,mBAAmB,GACnB,QAAQ,GACR,WAAW,GACX,gBAAgB,CAAC;AAErB,iCAAiC;AACjC,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,UAAU,CAAC;IACjB,8EAA8E;IAC9E,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,iEAAiE;IACjE,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAkCD;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,EAAE,CAenE;AASD,sEAAsE;AACtE,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,EAAE,CAiB9D;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,EAAE,CA0B/D;AAED,kEAAkE;AAClE,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,EAAE,CAM5D;AAiBD;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,SAAc,GAAG,aAAa,EAAE,CAe5E;AAKD;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAAC,WAAW,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,EAAE,GAAG,SAAiB,GAAG,aAAa,EAAE,CAUvH;AAqBD;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CACtC,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,KAAK,EAChB,GAAG,SAA2B,EAC9B,GAAG,SAAe,GACjB,OAAO,CAAC,aAAa,EAAE,CAAC,CAkC1B;AAED,2DAA2D;AAC3D,wBAAsB,oBAAoB,CACxC,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,KAAK,EAChB,GAAG,SAA2B,GAC7B,OAAO,CAAC,aAAa,EAAE,CAAC,CA2B1B;AAsBD,wBAAgB,aAAa,CAAC,OAAO,EAAE,aAAa,EAAE,EAAE,QAAQ,SAAkB,EAAE,QAAQ,SAAc,GAAG,aAAa,EAAE,CAW3H;AAED,8DAA8D;AAC9D,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAEzD"}
|