@nanonets/graft 0.21.1 → 0.22.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 +549 -315
- package/dist/app/review-process.d.ts.map +1 -1
- package/dist/app/review-process.js +6 -5
- package/dist/app/review-process.js.map +1 -1
- package/dist/app/sources.js +2 -2
- package/dist/app/sources.js.map +1 -1
- package/dist/ask/ask.d.ts +12 -6
- package/dist/ask/ask.d.ts.map +1 -1
- package/dist/ask/ask.js +28 -38
- package/dist/ask/ask.js.map +1 -1
- package/dist/bin/graft.d.ts +3 -0
- package/dist/bin/graft.d.ts.map +1 -0
- package/dist/bin/graft.js +8 -0
- package/dist/bin/graft.js.map +1 -0
- package/dist/bin/trail.d.ts +3 -0
- package/dist/bin/trail.d.ts.map +1 -0
- package/dist/bin/trail.js +6 -0
- package/dist/bin/trail.js.map +1 -0
- package/dist/blast/blast-cli.d.ts.map +1 -1
- package/dist/blast/blast-cli.js +2 -1
- package/dist/blast/blast-cli.js.map +1 -1
- package/dist/blast/render.d.ts.map +1 -1
- package/dist/blast/render.js +3 -2
- package/dist/blast/render.js.map +1 -1
- package/dist/brand.d.ts +97 -0
- package/dist/brand.d.ts.map +1 -0
- package/dist/brand.js +254 -0
- package/dist/brand.js.map +1 -0
- package/dist/check/local-check.d.ts +104 -0
- package/dist/check/local-check.d.ts.map +1 -0
- package/dist/check/local-check.js +830 -0
- package/dist/check/local-check.js.map +1 -0
- package/dist/check/types.d.ts +31 -0
- package/dist/check/types.d.ts.map +1 -0
- package/dist/check/types.js +2 -0
- package/dist/check/types.js.map +1 -0
- package/dist/claude/format.d.ts +44 -1
- package/dist/claude/format.d.ts.map +1 -1
- package/dist/claude/format.js +113 -19
- package/dist/claude/format.js.map +1 -1
- package/dist/claude/hook-layers.d.ts +8 -0
- package/dist/claude/hook-layers.d.ts.map +1 -0
- package/dist/claude/hook-layers.js +72 -0
- package/dist/claude/hook-layers.js.map +1 -0
- package/dist/claude/hooks.d.ts +34 -0
- package/dist/claude/hooks.d.ts.map +1 -1
- package/dist/claude/hooks.js +220 -12
- package/dist/claude/hooks.js.map +1 -1
- package/dist/claude/init.d.ts +12 -1
- package/dist/claude/init.d.ts.map +1 -1
- package/dist/claude/init.js +48 -19
- package/dist/claude/init.js.map +1 -1
- package/dist/claude/session-metrics.d.ts +1 -1
- package/dist/claude/session-metrics.d.ts.map +1 -1
- package/dist/claude/session-metrics.js +11 -8
- package/dist/claude/session-metrics.js.map +1 -1
- package/dist/claude/settings-merge.d.ts +1 -0
- package/dist/claude/settings-merge.d.ts.map +1 -1
- package/dist/claude/settings-merge.js +21 -18
- package/dist/claude/settings-merge.js.map +1 -1
- package/dist/claude/shim-template.d.ts +17 -2
- package/dist/claude/shim-template.d.ts.map +1 -1
- package/dist/claude/shim-template.js +116 -22
- package/dist/claude/shim-template.js.map +1 -1
- package/dist/claude/skill-template.d.ts +10 -1
- package/dist/claude/skill-template.d.ts.map +1 -1
- package/dist/claude/skill-template.js +132 -1
- package/dist/claude/skill-template.js.map +1 -1
- package/dist/claude/state.d.ts +8 -0
- package/dist/claude/state.d.ts.map +1 -1
- package/dist/claude/state.js.map +1 -1
- package/dist/claude/statusline.d.ts.map +1 -1
- package/dist/claude/statusline.js +4 -1
- package/dist/claude/statusline.js.map +1 -1
- package/dist/claude/tally.js +1 -1
- package/dist/claude/tally.js.map +1 -1
- package/dist/cli-epilogue.d.ts +0 -6
- package/dist/cli-epilogue.d.ts.map +1 -1
- package/dist/cli-epilogue.js +5 -4
- package/dist/cli-epilogue.js.map +1 -1
- package/dist/cli-meta.d.ts +8 -0
- package/dist/cli-meta.d.ts.map +1 -1
- package/dist/cli-meta.js +28 -8
- package/dist/cli-meta.js.map +1 -1
- package/dist/cli-picker.d.ts.map +1 -1
- package/dist/cli-picker.js +11 -7
- package/dist/cli-picker.js.map +1 -1
- package/dist/cli.d.ts +0 -5
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +1039 -559
- package/dist/cli.js.map +1 -1
- package/dist/cloud/diff.d.ts +18 -0
- package/dist/cloud/diff.d.ts.map +1 -0
- package/dist/cloud/diff.js +58 -0
- package/dist/cloud/diff.js.map +1 -0
- package/dist/cloud/nudge.d.ts +66 -0
- package/dist/cloud/nudge.d.ts.map +1 -0
- package/dist/cloud/nudge.js +269 -0
- package/dist/cloud/nudge.js.map +1 -0
- package/dist/cloud/workspace-sync.d.ts +58 -0
- package/dist/cloud/workspace-sync.d.ts.map +1 -0
- package/dist/cloud/workspace-sync.js +268 -0
- package/dist/cloud/workspace-sync.js.map +1 -0
- package/dist/cloud/workspace.d.ts +159 -0
- package/dist/cloud/workspace.d.ts.map +1 -0
- package/dist/cloud/workspace.js +134 -0
- package/dist/cloud/workspace.js.map +1 -0
- package/dist/context/check.d.ts +1 -1
- package/dist/context/check.d.ts.map +1 -1
- package/dist/context/check.js +9 -8
- package/dist/context/check.js.map +1 -1
- package/dist/context/node-file.js +1 -1
- package/dist/context/node-file.js.map +1 -1
- package/dist/context/savings.d.ts.map +1 -1
- package/dist/context/savings.js +10 -7
- package/dist/context/savings.js.map +1 -1
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +3 -1
- package/dist/engine.js.map +1 -1
- package/dist/graph/build.d.ts +30 -0
- package/dist/graph/build.d.ts.map +1 -1
- package/dist/graph/build.js +65 -19
- package/dist/graph/build.js.map +1 -1
- package/dist/graph/cards.d.ts.map +1 -1
- package/dist/graph/cards.js +4 -2
- package/dist/graph/cards.js.map +1 -1
- package/dist/graph/check.d.ts.map +1 -1
- package/dist/graph/check.js +17 -18
- package/dist/graph/check.js.map +1 -1
- package/dist/graph/container.d.ts.map +1 -1
- package/dist/graph/container.js +7 -2
- package/dist/graph/container.js.map +1 -1
- package/dist/graph/extract-cache.d.ts +4 -0
- package/dist/graph/extract-cache.d.ts.map +1 -1
- package/dist/graph/extract-cache.js.map +1 -1
- package/dist/graph/extract.d.ts +2 -0
- package/dist/graph/extract.d.ts.map +1 -1
- package/dist/graph/extract.js +5 -32
- package/dist/graph/extract.js.map +1 -1
- package/dist/graph/generic.d.ts +7 -1
- package/dist/graph/generic.d.ts.map +1 -1
- package/dist/graph/generic.js +48 -8
- package/dist/graph/generic.js.map +1 -1
- package/dist/graph/native.d.ts +38 -0
- package/dist/graph/native.d.ts.map +1 -0
- package/dist/graph/native.js +169 -0
- package/dist/graph/native.js.map +1 -0
- package/dist/graph/refresh.d.ts.map +1 -1
- package/dist/graph/refresh.js +3 -2
- package/dist/graph/refresh.js.map +1 -1
- package/dist/graph/traverse-cli.d.ts.map +1 -1
- package/dist/graph/traverse-cli.js +4 -3
- package/dist/graph/traverse-cli.js.map +1 -1
- package/dist/graph/workspace-cli.d.ts +2 -0
- package/dist/graph/workspace-cli.d.ts.map +1 -1
- package/dist/graph/workspace-cli.js +13 -1
- package/dist/graph/workspace-cli.js.map +1 -1
- package/dist/graph/workspace.d.ts.map +1 -1
- package/dist/graph/workspace.js +6 -5
- package/dist/graph/workspace.js.map +1 -1
- package/dist/hosts/antigravity.d.ts +10 -3
- package/dist/hosts/antigravity.d.ts.map +1 -1
- package/dist/hosts/antigravity.js +27 -10
- package/dist/hosts/antigravity.js.map +1 -1
- package/dist/hosts/claude-global.d.ts +27 -4
- package/dist/hosts/claude-global.d.ts.map +1 -1
- package/dist/hosts/claude-global.js +90 -9
- package/dist/hosts/claude-global.js.map +1 -1
- package/dist/hosts/codex-hooks.d.ts.map +1 -1
- package/dist/hosts/codex-hooks.js +1 -2
- package/dist/hosts/codex-hooks.js.map +1 -1
- package/dist/hosts/config-write.d.ts.map +1 -1
- package/dist/hosts/config-write.js +2 -1
- package/dist/hosts/config-write.js.map +1 -1
- package/dist/hosts/cursor-hooks.d.ts +5 -2
- package/dist/hosts/cursor-hooks.d.ts.map +1 -1
- package/dist/hosts/cursor-hooks.js +14 -9
- package/dist/hosts/cursor-hooks.js.map +1 -1
- package/dist/hosts/init.d.ts +3 -0
- package/dist/hosts/init.d.ts.map +1 -1
- package/dist/hosts/init.js +32 -10
- package/dist/hosts/init.js.map +1 -1
- package/dist/hosts/instructions.d.ts +9 -4
- package/dist/hosts/instructions.d.ts.map +1 -1
- package/dist/hosts/instructions.js +19 -16
- package/dist/hosts/instructions.js.map +1 -1
- package/dist/hosts/mcp-config.d.ts +19 -4
- package/dist/hosts/mcp-config.d.ts.map +1 -1
- package/dist/hosts/mcp-config.js +81 -30
- package/dist/hosts/mcp-config.js.map +1 -1
- package/dist/hosts/plan.d.ts.map +1 -1
- package/dist/hosts/plan.js +11 -9
- package/dist/hosts/plan.js.map +1 -1
- package/dist/hosts/registry.d.ts +25 -2
- package/dist/hosts/registry.d.ts.map +1 -1
- package/dist/hosts/registry.js +53 -0
- package/dist/hosts/registry.js.map +1 -1
- package/dist/hosts/retract.d.ts.map +1 -1
- package/dist/hosts/retract.js +73 -33
- package/dist/hosts/retract.js.map +1 -1
- package/dist/hosts/sections.d.ts +17 -1
- package/dist/hosts/sections.d.ts.map +1 -1
- package/dist/hosts/sections.js +52 -2
- package/dist/hosts/sections.js.map +1 -1
- package/dist/mcp/instructions.d.ts +1 -25
- package/dist/mcp/instructions.d.ts.map +1 -1
- package/dist/mcp/instructions.js +6 -4
- package/dist/mcp/instructions.js.map +1 -1
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +7 -3
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/tool-names.d.ts +10 -3
- package/dist/mcp/tool-names.d.ts.map +1 -1
- package/dist/mcp/tool-names.js +13 -5
- package/dist/mcp/tool-names.js.map +1 -1
- package/dist/mcp/tools.d.ts.map +1 -1
- package/dist/mcp/tools.js +6 -5
- package/dist/mcp/tools.js.map +1 -1
- package/dist/notes/ask-notes.d.ts +8 -0
- package/dist/notes/ask-notes.d.ts.map +1 -0
- package/dist/notes/ask-notes.js +18 -0
- package/dist/notes/ask-notes.js.map +1 -0
- package/dist/notes/branches.d.ts +85 -0
- package/dist/notes/branches.d.ts.map +1 -0
- package/dist/notes/branches.js +238 -0
- package/dist/notes/branches.js.map +1 -0
- package/dist/notes/cold-start.d.ts +127 -0
- package/dist/notes/cold-start.d.ts.map +1 -0
- package/dist/notes/cold-start.js +476 -0
- package/dist/notes/cold-start.js.map +1 -0
- package/dist/notes/git-facts.d.ts +17 -0
- package/dist/notes/git-facts.d.ts.map +1 -0
- package/dist/notes/git-facts.js +117 -0
- package/dist/notes/git-facts.js.map +1 -0
- package/dist/notes/home.d.ts +87 -0
- package/dist/notes/home.d.ts.map +1 -0
- package/dist/notes/home.js +423 -0
- package/dist/notes/home.js.map +1 -0
- package/dist/notes/notes.d.ts +178 -0
- package/dist/notes/notes.d.ts.map +1 -0
- package/dist/notes/notes.js +498 -0
- package/dist/notes/notes.js.map +1 -0
- package/dist/notes/repo-trail.d.ts +16 -0
- package/dist/notes/repo-trail.d.ts.map +1 -0
- package/dist/notes/repo-trail.js +74 -0
- package/dist/notes/repo-trail.js.map +1 -0
- package/dist/notes/session-cost.d.ts +21 -0
- package/dist/notes/session-cost.d.ts.map +1 -0
- package/dist/notes/session-cost.js +162 -0
- package/dist/notes/session-cost.js.map +1 -0
- package/dist/search/grep-cli.d.ts.map +1 -1
- package/dist/search/grep-cli.js +4 -3
- package/dist/search/grep-cli.js.map +1 -1
- package/dist/skills/skills.d.ts +118 -0
- package/dist/skills/skills.d.ts.map +1 -0
- package/dist/skills/skills.js +370 -0
- package/dist/skills/skills.js.map +1 -0
- package/dist/telemetry/contract.d.ts +2 -14
- package/dist/telemetry/contract.d.ts.map +1 -1
- package/dist/telemetry/contract.js +39 -24
- package/dist/telemetry/contract.js.map +1 -1
- package/dist/telemetry/gate.d.ts.map +1 -1
- package/dist/telemetry/gate.js +2 -1
- package/dist/telemetry/gate.js.map +1 -1
- package/dist/telemetry/notice.d.ts +1 -1
- package/dist/telemetry/notice.d.ts.map +1 -1
- package/dist/telemetry/notice.js +6 -5
- package/dist/telemetry/notice.js.map +1 -1
- package/dist/telemetry/track.d.ts.map +1 -1
- package/dist/telemetry/track.js +5 -0
- package/dist/telemetry/track.js.map +1 -1
- package/dist/upkeep-run.d.ts +7 -0
- package/dist/upkeep-run.d.ts.map +1 -1
- package/dist/upkeep-run.js +52 -12
- package/dist/upkeep-run.js.map +1 -1
- package/dist/upkeep.d.ts +9 -19
- package/dist/upkeep.d.ts.map +1 -1
- package/dist/upkeep.js +38 -59
- package/dist/upkeep.js.map +1 -1
- package/dist/util/browser.d.ts +3 -0
- package/dist/util/browser.d.ts.map +1 -0
- package/dist/util/browser.js +14 -0
- package/dist/util/browser.js.map +1 -0
- package/dist/util/front-matter.d.ts +19 -0
- package/dist/util/front-matter.d.ts.map +1 -0
- package/dist/util/front-matter.js +21 -0
- package/dist/util/front-matter.js.map +1 -0
- package/dist/util/state.d.ts +1 -18
- package/dist/util/state.d.ts.map +1 -1
- package/dist/util/state.js +4 -2
- package/dist/util/state.js.map +1 -1
- package/dist/viz/assemble.js +1 -1
- package/dist/viz/assemble.js.map +1 -1
- package/dist/viz/serve.d.ts.map +1 -1
- package/dist/viz/serve.js +4 -3
- package/dist/viz/serve.js.map +1 -1
- package/package.json +7 -7
- package/scripts/pack-trail.mjs +53 -0
- package/scripts/postinstall.mjs +17 -2
- package/scripts/run-tests.mjs +4 -1
- package/dist/brain/attach.d.ts +0 -44
- package/dist/brain/attach.d.ts.map +0 -1
- package/dist/brain/attach.js +0 -63
- package/dist/brain/attach.js.map +0 -1
- package/dist/brain/claude-md.d.ts +0 -61
- package/dist/brain/claude-md.d.ts.map +0 -1
- package/dist/brain/claude-md.js +0 -171
- package/dist/brain/claude-md.js.map +0 -1
- package/dist/brain/connect.d.ts +0 -59
- package/dist/brain/connect.d.ts.map +0 -1
- package/dist/brain/connect.js +0 -80
- package/dist/brain/connect.js.map +0 -1
- package/dist/brain/context-files.d.ts +0 -79
- package/dist/brain/context-files.d.ts.map +0 -1
- package/dist/brain/context-files.js +0 -245
- package/dist/brain/context-files.js.map +0 -1
- package/dist/brain/link.d.ts +0 -106
- package/dist/brain/link.d.ts.map +0 -1
- package/dist/brain/link.js +0 -167
- package/dist/brain/link.js.map +0 -1
- package/dist/brain/pull.d.ts +0 -48
- package/dist/brain/pull.d.ts.map +0 -1
- package/dist/brain/pull.js +0 -257
- package/dist/brain/pull.js.map +0 -1
- package/dist/brain/push.d.ts +0 -155
- package/dist/brain/push.d.ts.map +0 -1
- package/dist/brain/push.js +0 -304
- package/dist/brain/push.js.map +0 -1
- package/dist/brain/signup.d.ts +0 -117
- package/dist/brain/signup.d.ts.map +0 -1
- package/dist/brain/signup.js +0 -276
- package/dist/brain/signup.js.map +0 -1
- package/dist/brain/upload.d.ts +0 -61
- package/dist/brain/upload.d.ts.map +0 -1
- package/dist/brain/upload.js +0 -210
- package/dist/brain/upload.js.map +0 -1
- package/dist/brain/watch.d.ts +0 -209
- package/dist/brain/watch.d.ts.map +0 -1
- package/dist/brain/watch.js +0 -397
- package/dist/brain/watch.js.map +0 -1
- package/dist/brain/wire.d.ts +0 -38
- package/dist/brain/wire.d.ts.map +0 -1
- package/dist/brain/wire.js +0 -133
- package/dist/brain/wire.js.map +0 -1
- package/dist/legacy-args.d.ts +0 -12
- package/dist/legacy-args.d.ts.map +0 -1
- package/dist/legacy-args.js +0 -31
- package/dist/legacy-args.js.map +0 -1
package/dist/brain/signup.js
DELETED
|
@@ -1,276 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Getting a brain without leaving the terminal.
|
|
3
|
-
*
|
|
4
|
-
* Until now a brain could only begin in the browser. You signed up on Trail, it
|
|
5
|
-
* created the brain, and handed you a `graft init --trail <id>:<token>` line to
|
|
6
|
-
* paste. That is the right way round when the website is where you already are,
|
|
7
|
-
* and the wrong way round when you are standing in a repository with graft
|
|
8
|
-
* already installed — which is where most people meet graft first.
|
|
9
|
-
*
|
|
10
|
-
* So `graft trail push` on an unlinked repo starts here instead of stopping.
|
|
11
|
-
* Graft opens a listener on loopback, sends the browser to Trail carrying the
|
|
12
|
-
* repository it is standing in and the port to answer on, and waits. Trail does
|
|
13
|
-
* the signing up, makes a brain for that repository, and redirects back to the
|
|
14
|
-
* listener with the brain id and its read token. The push then carries on as if
|
|
15
|
-
* the repo had been linked all along.
|
|
16
|
-
*
|
|
17
|
-
* Two things keep that safe. The listener binds to 127.0.0.1, so nothing off
|
|
18
|
-
* this machine can reach it. And it accepts only a handoff echoing the random
|
|
19
|
-
* state it just generated, so some other page the user happens to have open
|
|
20
|
-
* cannot push a brain of its own choosing into their repository.
|
|
21
|
-
*/
|
|
22
|
-
import { spawn } from "node:child_process";
|
|
23
|
-
import { createServer } from "node:http";
|
|
24
|
-
import { randomBytes, timingSafeEqual } from "node:crypto";
|
|
25
|
-
/** Default web host. Overridden by GRAFT_BRAIN_URL, for staging and self-hosted.
|
|
26
|
-
*
|
|
27
|
-
* Trail's own front end, not the shared `agents.nanonets.com` one that `link.ts`
|
|
28
|
-
* calls for the API. Both are served by the same backend, so either would mint a
|
|
29
|
-
* working token — but this URL is the one a person looks at, and it has to be
|
|
30
|
-
* the Trail-branded build, with Trail's Auth0 redirect behind the signup. */
|
|
31
|
-
const DEFAULT_WEB_BASE_URL = "https://app.trailhq.com";
|
|
32
|
-
/** How long the listener waits for the browser before giving up. A signup can
|
|
33
|
-
* involve reading an email, so this is minutes rather than seconds. */
|
|
34
|
-
export const HANDOFF_TIMEOUT_MS = 5 * 60 * 1000;
|
|
35
|
-
/** The one path the listener answers on. */
|
|
36
|
-
export const CALLBACK_PATH = "/graft/callback";
|
|
37
|
-
/** Constant-time compare of two states, length included. */
|
|
38
|
-
function sameState(got, want) {
|
|
39
|
-
const a = Buffer.from(got);
|
|
40
|
-
const b = Buffer.from(want);
|
|
41
|
-
if (a.length !== b.length)
|
|
42
|
-
return false;
|
|
43
|
-
return timingSafeEqual(a, b);
|
|
44
|
-
}
|
|
45
|
-
/** The page the user is left looking at. Deliberately plain: it exists to say
|
|
46
|
-
* "go back to your terminal", and it is served from a throwaway port that is
|
|
47
|
-
* about to close, so there is nothing to style around. */
|
|
48
|
-
function donePage(ok) {
|
|
49
|
-
const msg = ok
|
|
50
|
-
? "Your trail is connected. Return to your terminal — the push is already running."
|
|
51
|
-
: "That sign-up doesn't match this terminal. Run graft trail push again.";
|
|
52
|
-
return `<!doctype html><meta charset="utf-8"><title>graft</title><body style="font:15px/1.5 system-ui,sans-serif;margin:3rem auto;max-width:32rem;color:#1F2129"><p>${msg}</p><p style="color:#676767">You can close this tab.</p>`;
|
|
53
|
-
}
|
|
54
|
-
/**
|
|
55
|
-
* Start listening for the browser's handoff.
|
|
56
|
-
*
|
|
57
|
-
* Port 0 so the OS picks a free one: a fixed port would collide with whatever
|
|
58
|
-
* else the developer is running, and a second graft in another terminal.
|
|
59
|
-
*/
|
|
60
|
-
export async function startHandoff() {
|
|
61
|
-
const state = randomBytes(24).toString("base64url");
|
|
62
|
-
let settle = () => { };
|
|
63
|
-
const answered = new Promise((resolve) => {
|
|
64
|
-
settle = resolve;
|
|
65
|
-
});
|
|
66
|
-
const server = createServer((req, res) => {
|
|
67
|
-
const url = new URL(req.url ?? "/", "http://127.0.0.1");
|
|
68
|
-
if (url.pathname !== CALLBACK_PATH) {
|
|
69
|
-
res.writeHead(404, { "content-type": "text/plain" });
|
|
70
|
-
res.end("not found");
|
|
71
|
-
return;
|
|
72
|
-
}
|
|
73
|
-
// Checked before anything is read out of the query, so a mismatched handoff
|
|
74
|
-
// never reaches the link-writing path at all.
|
|
75
|
-
if (!sameState(url.searchParams.get("state") ?? "", state)) {
|
|
76
|
-
res.writeHead(400, { "content-type": "text/html; charset=utf-8" });
|
|
77
|
-
res.end(donePage(false));
|
|
78
|
-
return;
|
|
79
|
-
}
|
|
80
|
-
const brainId = (url.searchParams.get("brain") ?? "").trim();
|
|
81
|
-
const token = (url.searchParams.get("token") ?? "").trim();
|
|
82
|
-
if (!brainId || !token) {
|
|
83
|
-
res.writeHead(400, { "content-type": "text/html; charset=utf-8" });
|
|
84
|
-
res.end(donePage(false));
|
|
85
|
-
settle({ error: "sign-up came back incomplete · nothing was sent — run graft trail push again", reason: "bad_callback" });
|
|
86
|
-
return;
|
|
87
|
-
}
|
|
88
|
-
// 303 so the browser issues a plain GET, and Location built from
|
|
89
|
-
// GRAFT_BRAIN_URL rather than anything the query carried — the same reason
|
|
90
|
-
// the Trail side builds its callback rather than being told one.
|
|
91
|
-
res.writeHead(303, { location: brainUrl(brainId), "cache-control": "no-store" });
|
|
92
|
-
res.end();
|
|
93
|
-
// No `baseUrl` stored, matching `connect`: GRAFT_BRAIN_URL is read again on
|
|
94
|
-
// every use, so persisting it here would only freeze a host that the env
|
|
95
|
-
// var is already free to move.
|
|
96
|
-
settle({ link: { brainId, token } });
|
|
97
|
-
});
|
|
98
|
-
await new Promise((resolve, reject) => {
|
|
99
|
-
server.once("error", reject);
|
|
100
|
-
server.listen(0, "127.0.0.1", () => {
|
|
101
|
-
server.removeAllListeners("error");
|
|
102
|
-
resolve();
|
|
103
|
-
});
|
|
104
|
-
});
|
|
105
|
-
const port = server.address().port;
|
|
106
|
-
let closed = false;
|
|
107
|
-
const close = () => {
|
|
108
|
-
if (closed)
|
|
109
|
-
return;
|
|
110
|
-
closed = true;
|
|
111
|
-
server.close();
|
|
112
|
-
};
|
|
113
|
-
return {
|
|
114
|
-
port,
|
|
115
|
-
state,
|
|
116
|
-
close,
|
|
117
|
-
async wait(timeoutMs = HANDOFF_TIMEOUT_MS) {
|
|
118
|
-
let timer;
|
|
119
|
-
const timeout = new Promise((resolve) => {
|
|
120
|
-
timer = setTimeout(() => resolve({
|
|
121
|
-
error: `no sign-up after ${timeoutMs >= 60_000 ? `${Math.round(timeoutMs / 60_000)} minutes` : `${Math.max(1, Math.round(timeoutMs / 1000))} seconds`} · nothing was sent — run graft trail push again`,
|
|
122
|
-
reason: "timed_out",
|
|
123
|
-
}), timeoutMs);
|
|
124
|
-
// The timer must not hold the process open once the browser has answered.
|
|
125
|
-
timer.unref?.();
|
|
126
|
-
});
|
|
127
|
-
try {
|
|
128
|
-
return await Promise.race([answered, timeout]);
|
|
129
|
-
}
|
|
130
|
-
finally {
|
|
131
|
-
if (timer)
|
|
132
|
-
clearTimeout(timer);
|
|
133
|
-
close();
|
|
134
|
-
}
|
|
135
|
-
},
|
|
136
|
-
};
|
|
137
|
-
}
|
|
138
|
-
/** The Trail front end this machine is pointed at, without a trailing slash.
|
|
139
|
-
*
|
|
140
|
-
* Read at the moment it is needed rather than captured once, matching the rest
|
|
141
|
-
* of the brain code: GRAFT_BRAIN_URL is free to move between calls. */
|
|
142
|
-
export function webBaseUrl(baseUrl) {
|
|
143
|
-
return (process.env.GRAFT_BRAIN_URL || baseUrl || DEFAULT_WEB_BASE_URL).replace(/\/+$/, "");
|
|
144
|
-
}
|
|
145
|
-
/** Where the browser is sent once the handoff has been accepted.
|
|
146
|
-
*
|
|
147
|
-
* Back into Trail, at the screen that shows the brain being built. The
|
|
148
|
-
* alternative — leaving the person on a local page that says "go back to your
|
|
149
|
-
* terminal" — ends the flow on a blank throwaway served by a port that is about
|
|
150
|
-
* to close, at exactly the moment there is something to watch.
|
|
151
|
-
*
|
|
152
|
-
* NOT `/brain/<id>`, which is where this pointed first. That route redirects to
|
|
153
|
-
* the brain's graph, and the redirect fires the instant the row exists — which
|
|
154
|
-
* is minutes before it has any rules in it. Every terminal signup therefore
|
|
155
|
-
* landed on an empty visualisation of a brain that was, at that moment, being
|
|
156
|
-
* built perfectly well. The build screen is the same wait the browser-first
|
|
157
|
-
* flow shows, and it leads to the graph once there is a graph. */
|
|
158
|
-
export function brainUrl(brainId, baseUrl) {
|
|
159
|
-
return `${webBaseUrl(baseUrl)}/get-started?step=build&brain=${encodeURIComponent(brainId)}`;
|
|
160
|
-
}
|
|
161
|
-
/** Where a trail's suggested context-file changes are reviewed and accepted:
|
|
162
|
-
* the Context files overview, which lists every file the repo's agents read
|
|
163
|
-
* (CLAUDE.md, AGENTS.md, Cursor rules, folder files, skills) with what waits
|
|
164
|
-
* on each. Needs a Trail that has the page (NanoNets/assign#2957). */
|
|
165
|
-
export function reviewUrl(brainId, baseUrl) {
|
|
166
|
-
return `${webBaseUrl(baseUrl)}/brain/${encodeURIComponent(brainId)}/context-files`;
|
|
167
|
-
}
|
|
168
|
-
/** Where to send the browser for a repo's brain.
|
|
169
|
-
*
|
|
170
|
-
* No port when an agent runs the push: nothing stays listening on loopback, so
|
|
171
|
-
* Trail keeps the trail it made under `state` and graft asks for it by that. */
|
|
172
|
-
export function signupUrl(opts) {
|
|
173
|
-
const base = webBaseUrl(opts.baseUrl);
|
|
174
|
-
const q = new URLSearchParams({ step: "repo", graft_repo: opts.repo });
|
|
175
|
-
if (opts.port !== undefined)
|
|
176
|
-
q.set("graft_port", String(opts.port));
|
|
177
|
-
q.set("graft_state", opts.state);
|
|
178
|
-
return `${base}/get-started?${q.toString()}`;
|
|
179
|
-
}
|
|
180
|
-
/*
|
|
181
|
-
* Signing up when an agent runs the push.
|
|
182
|
-
*
|
|
183
|
-
* Claude Code, Cursor and the rest run `graft trail push` with no terminal, and
|
|
184
|
-
* show the person nothing until the command exits. A loopback listener cannot
|
|
185
|
-
* work there: the link would sit unseen inside a running command, and anything
|
|
186
|
-
* the browser is sent back to is gone by the time the person finishes signing
|
|
187
|
-
* up. So the push runs in two short steps instead. The first opens the sign-up
|
|
188
|
-
* page, saves the state it put in the link, and exits at once so the agent can
|
|
189
|
-
* tell the person what to do. The next asks Trail every couple of seconds,
|
|
190
|
-
* by that state, whether the sign-up has finished, and carries on with the push
|
|
191
|
-
* when it has.
|
|
192
|
-
*/
|
|
193
|
-
/** A fresh state for a sign-up link: 24 random bytes, which is what Trail
|
|
194
|
-
* accepts and what makes the link impossible to guess. */
|
|
195
|
-
export function newSignupState() {
|
|
196
|
-
return randomBytes(24).toString("base64url");
|
|
197
|
-
}
|
|
198
|
-
/** How long one agent-run push waits for the sign-up. Under the two minutes an
|
|
199
|
-
* agent gives a command by default, so the wait ends with a message it can read
|
|
200
|
-
* rather than a killed process. */
|
|
201
|
-
export const AGENT_WAIT_MS = 90 * 1000;
|
|
202
|
-
/** How often it asks. */
|
|
203
|
-
export const AGENT_POLL_MS = 2000;
|
|
204
|
-
/** How long a saved state is worth asking about: a minute under the fifteen
|
|
205
|
-
* Trail keeps an unclaimed sign-up, so graft never waits on one Trail dropped. */
|
|
206
|
-
export const PENDING_SIGNUP_TTL_MS = 14 * 60 * 1000;
|
|
207
|
-
/**
|
|
208
|
-
* Ask Trail once whether the sign-up for `state` has finished.
|
|
209
|
-
*
|
|
210
|
-
* A network error or a server error counts as "not yet": one bad request in a
|
|
211
|
-
* ninety-second wait is not a reason to give up on it.
|
|
212
|
-
*/
|
|
213
|
-
export async function claimSignup(state, apiBase, fetchImpl = fetch) {
|
|
214
|
-
let res;
|
|
215
|
-
try {
|
|
216
|
-
res = await fetchImpl(`${apiBase}/api/public/graft-handoffs/claim`, {
|
|
217
|
-
method: "POST",
|
|
218
|
-
headers: { "content-type": "application/json" },
|
|
219
|
-
body: JSON.stringify({ state }),
|
|
220
|
-
signal: AbortSignal.timeout(10_000),
|
|
221
|
-
});
|
|
222
|
-
}
|
|
223
|
-
catch {
|
|
224
|
-
return { pending: true };
|
|
225
|
-
}
|
|
226
|
-
if (res.status === 200) {
|
|
227
|
-
const body = (await res.json().catch(() => ({})));
|
|
228
|
-
if (body.brain_id && body.token)
|
|
229
|
-
return { link: { brainId: body.brain_id, token: body.token } };
|
|
230
|
-
return { pending: true };
|
|
231
|
-
}
|
|
232
|
-
await res.body?.cancel().catch(() => undefined);
|
|
233
|
-
if (res.status === 410) {
|
|
234
|
-
return { error: "that sign-up link was already used or has expired · run graft trail push again for a new one", reason: "expired" };
|
|
235
|
-
}
|
|
236
|
-
// An older Trail, without the route. Waiting on it would never end.
|
|
237
|
-
if (res.status === 404 || res.status === 405) {
|
|
238
|
-
return {
|
|
239
|
-
error: "this Trail can't hand a sign-up to an agent yet · run graft trail push in a terminal, or graft trail connect <trailId>:<token>",
|
|
240
|
-
reason: "unsupported",
|
|
241
|
-
};
|
|
242
|
-
}
|
|
243
|
-
return { pending: true };
|
|
244
|
-
}
|
|
245
|
-
/** Ask until the sign-up finishes, Trail says it never will, or `timeoutMs`
|
|
246
|
-
* passes — which comes back as `{ pending: true }`. */
|
|
247
|
-
export async function waitForSignup(state, apiBase, opts = {}) {
|
|
248
|
-
const deadline = Date.now() + (opts.timeoutMs ?? AGENT_WAIT_MS);
|
|
249
|
-
const interval = opts.intervalMs ?? AGENT_POLL_MS;
|
|
250
|
-
for (;;) {
|
|
251
|
-
const got = await claimSignup(state, apiBase, opts.fetchImpl);
|
|
252
|
-
if (!("pending" in got))
|
|
253
|
-
return got;
|
|
254
|
-
if (Date.now() + interval > deadline)
|
|
255
|
-
return got;
|
|
256
|
-
await new Promise((r) => setTimeout(r, interval));
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
/** Open the user's browser, best effort. A machine with no opener is not an
|
|
260
|
-
* error: the URL is printed too, and that is the fallback everywhere.
|
|
261
|
-
*
|
|
262
|
-
* GRAFT_NO_BROWSER leaves the printed URL as the only route, which is what a
|
|
263
|
-
* test wants, and what someone on a machine whose `open` does something
|
|
264
|
-
* surprising wants too. */
|
|
265
|
-
export function openBrowser(url) {
|
|
266
|
-
if (process.env.GRAFT_NO_BROWSER)
|
|
267
|
-
return;
|
|
268
|
-
const opener = process.platform === "darwin" ? "open" : process.platform === "win32" ? "start" : "xdg-open";
|
|
269
|
-
try {
|
|
270
|
-
spawn(opener, [url], { stdio: "ignore", detached: true, shell: process.platform === "win32" }).unref();
|
|
271
|
-
}
|
|
272
|
-
catch {
|
|
273
|
-
/* the printed URL is the fallback */
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
|
-
//# sourceMappingURL=signup.js.map
|
package/dist/brain/signup.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"signup.js","sourceRoot":"","sources":["../../src/brain/signup.ts"],"names":[],"mappings":"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"}
|
package/dist/brain/upload.d.ts
DELETED
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import type { RepoDigest } from "../app/history.js";
|
|
2
|
-
import { type BrainLink } from "./link.js";
|
|
3
|
-
/** The size of one chunk: the index-th slice of the gzip is bytes [i*CHUNK, (i+1)*CHUNK). */
|
|
4
|
-
export declare const CHUNK_BYTES: number;
|
|
5
|
-
/** Chunks in flight at once. */
|
|
6
|
-
export declare const CHUNK_CONCURRENCY = 4;
|
|
7
|
-
/** Waits before each retry. Four retries, so five attempts in all. */
|
|
8
|
-
export declare const RETRY_DELAYS_MS: readonly [500, 1000, 2000, 4000];
|
|
9
|
-
/** What the server said it accepts, from GET /repo. */
|
|
10
|
-
export interface UploadCaps {
|
|
11
|
-
/** `gzip_upload: true` — POST /repo takes `Content-Encoding: gzip`. */
|
|
12
|
-
gzip?: boolean;
|
|
13
|
-
/** `chunked_upload: true` — the /repo/uploads routes exist. */
|
|
14
|
-
chunked?: boolean;
|
|
15
|
-
}
|
|
16
|
-
export interface UploadOptions {
|
|
17
|
-
fetchImpl?: typeof fetch;
|
|
18
|
-
sleep?: (ms: number) => Promise<void>;
|
|
19
|
-
chunkBytes?: number;
|
|
20
|
-
concurrency?: number;
|
|
21
|
-
}
|
|
22
|
-
export type UploadResult = {
|
|
23
|
-
jobId: string;
|
|
24
|
-
} | {
|
|
25
|
-
error: string;
|
|
26
|
-
};
|
|
27
|
-
/** The digest as the exact bytes a single POST would carry, gzipped. */
|
|
28
|
-
export declare function gzipDigest(digest: RepoDigest): Promise<Buffer>;
|
|
29
|
-
/**
|
|
30
|
-
* The single POST to /repo — gzipped when the server takes it, plain otherwise.
|
|
31
|
-
* Not retried: a repeated POST of a whole ingest is not idempotent, and a 409
|
|
32
|
-
* for "already running" on the retry would read as a refusal.
|
|
33
|
-
*/
|
|
34
|
-
export declare function postDigestOnce(link: BrainLink, digest: RepoDigest, opts?: {
|
|
35
|
-
gzip?: boolean;
|
|
36
|
-
fetchImpl?: typeof fetch;
|
|
37
|
-
query?: string;
|
|
38
|
-
timeoutMs?: number;
|
|
39
|
-
}): Promise<Response>;
|
|
40
|
-
/**
|
|
41
|
-
* Upload the full digest by whichever route the server advertises.
|
|
42
|
-
*
|
|
43
|
-
* Chunked when `caps.chunked`; if the upload session cannot even be opened
|
|
44
|
-
* (a 404 from a server that advertised the flag but not the route), it falls
|
|
45
|
-
* back to the single POST rather than failing a push that would otherwise work.
|
|
46
|
-
*/
|
|
47
|
-
export declare function uploadDigest(link: BrainLink, digest: RepoDigest, caps: UploadCaps, opts?: UploadOptions): Promise<UploadResult>;
|
|
48
|
-
/**
|
|
49
|
-
* The chunked route:
|
|
50
|
-
*
|
|
51
|
-
* POST /repo/uploads {stage, auto_approve, chunks, bytes} → {upload_id}
|
|
52
|
-
* PUT /repo/uploads/:id/chunks/:index raw gzip slice, idempotent → 204
|
|
53
|
-
* POST /repo/uploads/:id/complete → today's /repo response
|
|
54
|
-
*
|
|
55
|
-
* `{fallback: true}` means the session could not be opened and nothing was
|
|
56
|
-
* sent, so the caller may use the single POST instead.
|
|
57
|
-
*/
|
|
58
|
-
export declare function uploadChunked(link: BrainLink, digest: RepoDigest, opts?: UploadOptions): Promise<UploadResult | {
|
|
59
|
-
fallback: true;
|
|
60
|
-
}>;
|
|
61
|
-
//# sourceMappingURL=upload.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"upload.d.ts","sourceRoot":"","sources":["../../src/brain/upload.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAc,KAAK,SAAS,EAAE,MAAM,WAAW,CAAC;AAIvD,6FAA6F;AAC7F,eAAO,MAAM,WAAW,QAAc,CAAC;AACvC,gCAAgC;AAChC,eAAO,MAAM,iBAAiB,IAAI,CAAC;AACnC,sEAAsE;AACtE,eAAO,MAAM,eAAe,kCAAmC,CAAC;AAEhE,uDAAuD;AACvD,MAAM,WAAW,UAAU;IACzB,uEAAuE;IACvE,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,+DAA+D;IAC/D,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,MAAM,YAAY,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAIjE,wEAAwE;AACxE,wBAAsB,UAAU,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAEpE;AAmDD;;;;GAIG;AACH,wBAAsB,cAAc,CAClC,IAAI,EAAE,SAAS,EACf,MAAM,EAAE,UAAU,EAClB,IAAI,GAAE;IAAE,IAAI,CAAC,EAAE,OAAO,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAO,GAC1F,OAAO,CAAC,QAAQ,CAAC,CAanB;AAED;;;;;;GAMG;AACH,wBAAsB,YAAY,CAChC,IAAI,EAAE,SAAS,EACf,MAAM,EAAE,UAAU,EAClB,IAAI,EAAE,UAAU,EAChB,IAAI,GAAE,aAAkB,GACvB,OAAO,CAAC,YAAY,CAAC,CAUvB;AAED;;;;;;;;;GASG;AACH,wBAAsB,aAAa,CACjC,IAAI,EAAE,SAAS,EACf,MAAM,EAAE,UAAU,EAClB,IAAI,GAAE,aAAkB,GACvB,OAAO,CAAC,YAAY,GAAG;IAAE,QAAQ,EAAE,IAAI,CAAA;CAAE,CAAC,CA0F5C"}
|
package/dist/brain/upload.js
DELETED
|
@@ -1,210 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Getting a digest to Trail quickly, and getting it there at all.
|
|
3
|
-
*
|
|
4
|
-
* A busy repository's digest is several megabytes of JSON — a thousand commit
|
|
5
|
-
* messages, two hundred threads of discussion, four thousand symbols — and it
|
|
6
|
-
* used to go up as one uncompressed POST with no retry. On a hotel connection
|
|
7
|
-
* that is a minute of upload and one dropped packet from starting over.
|
|
8
|
-
*
|
|
9
|
-
* JSON compresses about tenfold, so the body is gzipped whenever the server
|
|
10
|
-
* says it takes gzip. When it also says it takes chunked uploads, the gzip is
|
|
11
|
-
* cut into 1 MiB pieces and sent four at a time, each retried on its own: a
|
|
12
|
-
* blip costs one chunk, not the push. Against an older Trail neither flag is
|
|
13
|
-
* set and the upload is exactly the single POST it always was.
|
|
14
|
-
*/
|
|
15
|
-
import { gzip as gzipCb } from "node:zlib";
|
|
16
|
-
import { promisify } from "node:util";
|
|
17
|
-
import { baseUrlFor } from "./link.js";
|
|
18
|
-
const gzipAsync = promisify(gzipCb);
|
|
19
|
-
/** The size of one chunk: the index-th slice of the gzip is bytes [i*CHUNK, (i+1)*CHUNK). */
|
|
20
|
-
export const CHUNK_BYTES = 1024 * 1024;
|
|
21
|
-
/** Chunks in flight at once. */
|
|
22
|
-
export const CHUNK_CONCURRENCY = 4;
|
|
23
|
-
/** Waits before each retry. Four retries, so five attempts in all. */
|
|
24
|
-
export const RETRY_DELAYS_MS = [500, 1000, 2000, 4000];
|
|
25
|
-
const realSleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
26
|
-
/** The digest as the exact bytes a single POST would carry, gzipped. */
|
|
27
|
-
export async function gzipDigest(digest) {
|
|
28
|
-
return gzipAsync(Buffer.from(JSON.stringify(digest), "utf8"));
|
|
29
|
-
}
|
|
30
|
-
/** Retry on what a retry can fix: the network, the server, the rate limit. */
|
|
31
|
-
function retryable(status) {
|
|
32
|
-
return status >= 500 || status === 429;
|
|
33
|
-
}
|
|
34
|
-
/**
|
|
35
|
-
* One request, retried with backoff on network errors, 5xx and 429.
|
|
36
|
-
*
|
|
37
|
-
* Returns the last response when retries run out on a status (so the caller
|
|
38
|
-
* can print the server's own words), or throws the last network error.
|
|
39
|
-
*/
|
|
40
|
-
async function withRetry(send, sleep) {
|
|
41
|
-
let sawNetworkError = false;
|
|
42
|
-
let lastError;
|
|
43
|
-
for (let attempt = 0; attempt <= RETRY_DELAYS_MS.length; attempt++) {
|
|
44
|
-
if (attempt > 0)
|
|
45
|
-
await sleep(RETRY_DELAYS_MS[attempt - 1]);
|
|
46
|
-
try {
|
|
47
|
-
const res = await send();
|
|
48
|
-
if (!retryable(res.status) || attempt === RETRY_DELAYS_MS.length) {
|
|
49
|
-
return { res, attempts: attempt + 1, sawNetworkError };
|
|
50
|
-
}
|
|
51
|
-
// Drain it so the connection is released before the next attempt.
|
|
52
|
-
await res.arrayBuffer().catch(() => undefined);
|
|
53
|
-
}
|
|
54
|
-
catch (e) {
|
|
55
|
-
sawNetworkError = true;
|
|
56
|
-
lastError = e;
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
throw lastError instanceof Error ? lastError : new Error(String(lastError));
|
|
60
|
-
}
|
|
61
|
-
function authHeaders(link, extra = {}) {
|
|
62
|
-
return { authorization: `Bearer ${link.token}`, accept: "application/json", ...extra };
|
|
63
|
-
}
|
|
64
|
-
/** Today's response to an ingest, read the same way for every route that returns it. */
|
|
65
|
-
async function ingestResult(res) {
|
|
66
|
-
const text = await res.text();
|
|
67
|
-
if (!res.ok)
|
|
68
|
-
return { error: `Trail refused the upload: ${res.status} ${text.slice(0, 200)}` };
|
|
69
|
-
try {
|
|
70
|
-
return { jobId: String(JSON.parse(text).job_id ?? "") };
|
|
71
|
-
}
|
|
72
|
-
catch {
|
|
73
|
-
return { jobId: "" };
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
/**
|
|
77
|
-
* The single POST to /repo — gzipped when the server takes it, plain otherwise.
|
|
78
|
-
* Not retried: a repeated POST of a whole ingest is not idempotent, and a 409
|
|
79
|
-
* for "already running" on the retry would read as a refusal.
|
|
80
|
-
*/
|
|
81
|
-
export async function postDigestOnce(link, digest, opts = {}) {
|
|
82
|
-
const fetchImpl = opts.fetchImpl ?? fetch;
|
|
83
|
-
const url = `${baseUrlFor(link)}/api/public/brains/${encodeURIComponent(link.brainId)}/repo${opts.query ?? ""}`;
|
|
84
|
-
const json = JSON.stringify(digest);
|
|
85
|
-
const body = opts.gzip ? await gzipAsync(Buffer.from(json, "utf8")) : json;
|
|
86
|
-
const headers = authHeaders(link, { "content-type": "application/json" });
|
|
87
|
-
if (opts.gzip)
|
|
88
|
-
headers["content-encoding"] = "gzip";
|
|
89
|
-
return fetchImpl(url, {
|
|
90
|
-
method: "POST",
|
|
91
|
-
headers,
|
|
92
|
-
body: body,
|
|
93
|
-
...(opts.timeoutMs ? { signal: AbortSignal.timeout(opts.timeoutMs) } : {}),
|
|
94
|
-
});
|
|
95
|
-
}
|
|
96
|
-
/**
|
|
97
|
-
* Upload the full digest by whichever route the server advertises.
|
|
98
|
-
*
|
|
99
|
-
* Chunked when `caps.chunked`; if the upload session cannot even be opened
|
|
100
|
-
* (a 404 from a server that advertised the flag but not the route), it falls
|
|
101
|
-
* back to the single POST rather than failing a push that would otherwise work.
|
|
102
|
-
*/
|
|
103
|
-
export async function uploadDigest(link, digest, caps, opts = {}) {
|
|
104
|
-
if (caps.chunked) {
|
|
105
|
-
const chunked = await uploadChunked(link, digest, opts);
|
|
106
|
-
if (!("fallback" in chunked))
|
|
107
|
-
return chunked;
|
|
108
|
-
}
|
|
109
|
-
try {
|
|
110
|
-
return await ingestResult(await postDigestOnce(link, digest, { gzip: caps.gzip, fetchImpl: opts.fetchImpl }));
|
|
111
|
-
}
|
|
112
|
-
catch (e) {
|
|
113
|
-
return { error: `could not reach Trail: ${e instanceof Error ? e.message : e}` };
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
/**
|
|
117
|
-
* The chunked route:
|
|
118
|
-
*
|
|
119
|
-
* POST /repo/uploads {stage, auto_approve, chunks, bytes} → {upload_id}
|
|
120
|
-
* PUT /repo/uploads/:id/chunks/:index raw gzip slice, idempotent → 204
|
|
121
|
-
* POST /repo/uploads/:id/complete → today's /repo response
|
|
122
|
-
*
|
|
123
|
-
* `{fallback: true}` means the session could not be opened and nothing was
|
|
124
|
-
* sent, so the caller may use the single POST instead.
|
|
125
|
-
*/
|
|
126
|
-
export async function uploadChunked(link, digest, opts = {}) {
|
|
127
|
-
const fetchImpl = opts.fetchImpl ?? fetch;
|
|
128
|
-
const sleep = opts.sleep ?? realSleep;
|
|
129
|
-
const chunkBytes = opts.chunkBytes ?? CHUNK_BYTES;
|
|
130
|
-
const base = `${baseUrlFor(link)}/api/public/brains/${encodeURIComponent(link.brainId)}/repo/uploads`;
|
|
131
|
-
const gz = await gzipDigest(digest);
|
|
132
|
-
const chunks = Math.max(1, Math.ceil(gz.length / chunkBytes));
|
|
133
|
-
let uploadId = "";
|
|
134
|
-
try {
|
|
135
|
-
const { res } = await withRetry(() => fetchImpl(base, {
|
|
136
|
-
method: "POST",
|
|
137
|
-
headers: authHeaders(link, { "content-type": "application/json" }),
|
|
138
|
-
body: JSON.stringify({ stage: "full", auto_approve: digest.auto_approve, chunks, bytes: gz.length }),
|
|
139
|
-
}), sleep);
|
|
140
|
-
const text = await res.text();
|
|
141
|
-
if (res.status === 404 || res.status === 405)
|
|
142
|
-
return { fallback: true };
|
|
143
|
-
if (!res.ok) {
|
|
144
|
-
// 409 is the one refusal worth passing on as-is: an ingest is already
|
|
145
|
-
// running, and a single POST would be told the same.
|
|
146
|
-
if (res.status === 409)
|
|
147
|
-
return { error: `Trail refused the upload: ${res.status} ${text.slice(0, 200)}` };
|
|
148
|
-
return { fallback: true };
|
|
149
|
-
}
|
|
150
|
-
uploadId = String(JSON.parse(text).upload_id ?? "");
|
|
151
|
-
}
|
|
152
|
-
catch {
|
|
153
|
-
return { fallback: true };
|
|
154
|
-
}
|
|
155
|
-
if (!uploadId)
|
|
156
|
-
return { fallback: true };
|
|
157
|
-
// Chunks, four at a time, each retried on its own.
|
|
158
|
-
const concurrency = Math.max(1, opts.concurrency ?? CHUNK_CONCURRENCY);
|
|
159
|
-
let next = 0;
|
|
160
|
-
let failure = null;
|
|
161
|
-
const worker = async () => {
|
|
162
|
-
for (;;) {
|
|
163
|
-
if (failure)
|
|
164
|
-
return;
|
|
165
|
-
const i = next++;
|
|
166
|
-
if (i >= chunks)
|
|
167
|
-
return;
|
|
168
|
-
const slice = gz.subarray(i * chunkBytes, Math.min(gz.length, (i + 1) * chunkBytes));
|
|
169
|
-
try {
|
|
170
|
-
const { res } = await withRetry(() => fetchImpl(`${base}/${encodeURIComponent(uploadId)}/chunks/${i}`, {
|
|
171
|
-
method: "PUT",
|
|
172
|
-
headers: authHeaders(link, { "content-type": "application/octet-stream" }),
|
|
173
|
-
body: slice,
|
|
174
|
-
}), sleep);
|
|
175
|
-
if (!res.ok) {
|
|
176
|
-
const text = await res.text().catch(() => "");
|
|
177
|
-
failure = `Trail refused part ${i + 1} of ${chunks}: ${res.status} ${text.slice(0, 200)}`;
|
|
178
|
-
return;
|
|
179
|
-
}
|
|
180
|
-
await res.arrayBuffer().catch(() => undefined);
|
|
181
|
-
}
|
|
182
|
-
catch (e) {
|
|
183
|
-
failure = `could not send part ${i + 1} of ${chunks} to Trail: ${e instanceof Error ? e.message : e}`;
|
|
184
|
-
return;
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
};
|
|
188
|
-
await Promise.all(Array.from({ length: Math.min(concurrency, chunks) }, worker));
|
|
189
|
-
if (failure)
|
|
190
|
-
return { error: failure };
|
|
191
|
-
try {
|
|
192
|
-
const { res, sawNetworkError } = await withRetry(() => fetchImpl(`${base}/${encodeURIComponent(uploadId)}/complete`, {
|
|
193
|
-
method: "POST",
|
|
194
|
-
headers: authHeaders(link, { "content-type": "application/json" }),
|
|
195
|
-
body: "{}",
|
|
196
|
-
}), sleep);
|
|
197
|
-
// A complete that was lost on the way back may have started the ingest, so
|
|
198
|
-
// its retry being told "already running" means it worked. The watcher that
|
|
199
|
-
// follows reads the build either way.
|
|
200
|
-
if (res.status === 409 && sawNetworkError) {
|
|
201
|
-
await res.arrayBuffer().catch(() => undefined);
|
|
202
|
-
return { jobId: "" };
|
|
203
|
-
}
|
|
204
|
-
return await ingestResult(res);
|
|
205
|
-
}
|
|
206
|
-
catch (e) {
|
|
207
|
-
return { error: `could not reach Trail to finish the upload: ${e instanceof Error ? e.message : e}` };
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
//# sourceMappingURL=upload.js.map
|
package/dist/brain/upload.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"upload.js","sourceRoot":"","sources":["../../src/brain/upload.ts"],"names":[],"mappings":"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"}
|