@nanonets/graft 0.19.0 → 0.20.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 -4
- package/dist/app/history.d.ts +1 -1
- package/dist/app/history.d.ts.map +1 -1
- package/dist/app/history.js +7 -1
- package/dist/app/history.js.map +1 -1
- package/dist/ask/ask.js +1 -1
- package/dist/brain/claude-md.d.ts +59 -0
- package/dist/brain/claude-md.d.ts.map +1 -0
- package/dist/brain/claude-md.js +170 -0
- package/dist/brain/claude-md.js.map +1 -0
- package/dist/brain/connect.d.ts +3 -3
- package/dist/brain/connect.js +7 -7
- package/dist/brain/link.d.ts +1 -1
- package/dist/brain/link.js +1 -1
- package/dist/brain/push.d.ts +29 -1
- package/dist/brain/push.d.ts.map +1 -1
- package/dist/brain/push.js +80 -2
- package/dist/brain/push.js.map +1 -1
- package/dist/brain/signup.js +4 -4
- package/dist/brain/watch.d.ts +1 -1
- package/dist/claude/init.d.ts.map +1 -1
- package/dist/claude/init.js +3 -1
- package/dist/claude/init.js.map +1 -1
- package/dist/cli.js +130 -27
- package/dist/cli.js.map +1 -1
- package/dist/legacy-args.d.ts +12 -0
- package/dist/legacy-args.d.ts.map +1 -0
- package/dist/legacy-args.js +31 -0
- package/dist/legacy-args.js.map +1 -0
- package/dist/telemetry/contract.d.ts +1 -1
- package/dist/telemetry/contract.js +2 -2
- package/dist/upkeep.d.ts +1 -1
- package/dist/upkeep.js +1 -1
- package/package.json +1 -1
package/dist/brain/push.js
CHANGED
|
@@ -104,7 +104,12 @@ export async function fetchExpectedRepo(link, fetchImpl = fetch) {
|
|
|
104
104
|
const body = (await res.json());
|
|
105
105
|
if (!body.repo?.slug)
|
|
106
106
|
return null;
|
|
107
|
-
return {
|
|
107
|
+
return {
|
|
108
|
+
slug: body.repo.slug,
|
|
109
|
+
status: String(body.repo.status ?? ""),
|
|
110
|
+
brainName: String(body.brain_name ?? ""),
|
|
111
|
+
earlyUpload: body.early_upload === true,
|
|
112
|
+
};
|
|
108
113
|
}
|
|
109
114
|
catch {
|
|
110
115
|
return null;
|
|
@@ -114,6 +119,78 @@ export async function fetchExpectedRepo(link, fetchImpl = fetch) {
|
|
|
114
119
|
export function sameRepo(a, b) {
|
|
115
120
|
return a.trim().toLowerCase() === b.trim().toLowerCase();
|
|
116
121
|
}
|
|
122
|
+
/** How many of the newest pull requests and commits the early upload carries —
|
|
123
|
+
* what Trail's quick CLAUDE.md pass reads, and no more. */
|
|
124
|
+
export const EARLY_THREADS = 30;
|
|
125
|
+
export const EARLY_COMMITS = 80;
|
|
126
|
+
/**
|
|
127
|
+
* The early upload: the instruction files, the newest pull requests and the
|
|
128
|
+
* newest commits, read before the rest of the history.
|
|
129
|
+
*
|
|
130
|
+
* Reading the history is most of a push's wait — up to 200 pull requests at two
|
|
131
|
+
* GitHub calls each — and Trail's first CLAUDE.md suggestions need none of it
|
|
132
|
+
* beyond the newest few. Sent first, they start while the full read is still
|
|
133
|
+
* going here, and the full upload that follows mines as before.
|
|
134
|
+
*
|
|
135
|
+
* Returns the threads it read, so the full read reuses them instead of asking
|
|
136
|
+
* GitHub twice. Null when there is nothing worth sending early.
|
|
137
|
+
*/
|
|
138
|
+
export async function buildEarlyDigest(root, opts = {}) {
|
|
139
|
+
const slug = repoSlugFromGit(root);
|
|
140
|
+
if (!slug)
|
|
141
|
+
return null;
|
|
142
|
+
const fetchImpl = opts.fetchImpl ?? fetch;
|
|
143
|
+
const token = githubToken();
|
|
144
|
+
// Oldest first, like the full read, so the newest are the tail.
|
|
145
|
+
const commits = readCommits(root).slice(-EARLY_COMMITS);
|
|
146
|
+
if (commits.length === 0)
|
|
147
|
+
return null;
|
|
148
|
+
let threads = [];
|
|
149
|
+
if (token) {
|
|
150
|
+
try {
|
|
151
|
+
threads = await readThreads(slug.owner, slug.name, token, fetchImpl, undefined, EARLY_THREADS);
|
|
152
|
+
}
|
|
153
|
+
catch {
|
|
154
|
+
threads = [];
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
const digest = buildDigest({
|
|
158
|
+
owner: slug.owner,
|
|
159
|
+
name: slug.name,
|
|
160
|
+
headSha: git(root, ["rev-parse", "HEAD"]) ?? "",
|
|
161
|
+
defaultBranch: currentBranch(root),
|
|
162
|
+
isPrivate: await isPrivate(slug.owner, slug.name, token, fetchImpl),
|
|
163
|
+
commits,
|
|
164
|
+
threads,
|
|
165
|
+
symbols: [],
|
|
166
|
+
sources: budgetSources(readAgentInstructions(root)),
|
|
167
|
+
autoApprove: true,
|
|
168
|
+
});
|
|
169
|
+
return { digest, threads };
|
|
170
|
+
}
|
|
171
|
+
/** Send the early upload. Best-effort: false on any failure, and the full
|
|
172
|
+
* upload still does everything. */
|
|
173
|
+
export async function pushEarlyDigest(link, digest, fetchImpl = fetch) {
|
|
174
|
+
const url = `${baseUrlFor(link)}/api/public/brains/${encodeURIComponent(link.brainId)}/repo?stage=early`;
|
|
175
|
+
try {
|
|
176
|
+
const res = await fetchImpl(url, {
|
|
177
|
+
method: "POST",
|
|
178
|
+
headers: {
|
|
179
|
+
authorization: `Bearer ${link.token}`,
|
|
180
|
+
"content-type": "application/json",
|
|
181
|
+
accept: "application/json",
|
|
182
|
+
},
|
|
183
|
+
body: JSON.stringify(digest),
|
|
184
|
+
signal: AbortSignal.timeout(15_000),
|
|
185
|
+
});
|
|
186
|
+
if (!res.ok)
|
|
187
|
+
return false;
|
|
188
|
+
return (await res.json()).early === true;
|
|
189
|
+
}
|
|
190
|
+
catch {
|
|
191
|
+
return false;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
117
194
|
/** Build the digest for the checkout at `root`. Reads nothing but text. */
|
|
118
195
|
export async function buildLocalDigest(root, graph, opts = {}) {
|
|
119
196
|
const slug = repoSlugFromGit(root);
|
|
@@ -131,7 +208,8 @@ export async function buildLocalDigest(root, graph, opts = {}) {
|
|
|
131
208
|
let warning;
|
|
132
209
|
if (token) {
|
|
133
210
|
try {
|
|
134
|
-
|
|
211
|
+
const known = new Map((opts.knownThreads ?? []).map((t) => [t.number, t]));
|
|
212
|
+
threads = await readThreads(slug.owner, slug.name, token, fetchImpl, undefined, undefined, known);
|
|
135
213
|
}
|
|
136
214
|
catch {
|
|
137
215
|
warning = "could not read pull-request discussion; mining commits and repo files only";
|
package/dist/brain/push.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"push.js","sourceRoot":"","sources":["../../src/brain/push.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EACL,WAAW,EACX,WAAW,EACX,WAAW,EACX,WAAW,
|
|
1
|
+
{"version":3,"file":"push.js","sourceRoot":"","sources":["../../src/brain/push.ts"],"names":[],"mappings":"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"}
|
package/dist/brain/signup.js
CHANGED
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
* Getting a brain without leaving the terminal.
|
|
3
3
|
*
|
|
4
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 --
|
|
5
|
+
* created the brain, and handed you a `graft init --trail <id>:<token>` line to
|
|
6
6
|
* paste. That is the right way round when the website is where you already are,
|
|
7
7
|
* and the wrong way round when you are standing in a repository with graft
|
|
8
8
|
* already installed — which is where most people meet graft first.
|
|
9
9
|
*
|
|
10
|
-
* So `graft
|
|
10
|
+
* So `graft trail push` on an unlinked repo starts here instead of stopping.
|
|
11
11
|
* Graft opens a listener on loopback, sends the browser to Trail carrying the
|
|
12
12
|
* repository it is standing in and the port to answer on, and waits. Trail does
|
|
13
13
|
* the signing up, makes a brain for that repository, and redirects back to the
|
|
@@ -48,7 +48,7 @@ function sameState(got, want) {
|
|
|
48
48
|
function donePage(ok) {
|
|
49
49
|
const msg = ok
|
|
50
50
|
? "Your brain is connected. Return to your terminal — the push is already running."
|
|
51
|
-
: "That handoff did not match this terminal. Run `graft
|
|
51
|
+
: "That handoff did not match this terminal. Run `graft trail push` again.";
|
|
52
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
53
|
}
|
|
54
54
|
/**
|
|
@@ -117,7 +117,7 @@ export async function startHandoff() {
|
|
|
117
117
|
async wait(timeoutMs = HANDOFF_TIMEOUT_MS) {
|
|
118
118
|
let timer;
|
|
119
119
|
const timeout = new Promise((resolve) => {
|
|
120
|
-
timer = setTimeout(() => resolve({ error: "timed out waiting for the browser — run `graft
|
|
120
|
+
timer = setTimeout(() => resolve({ error: "timed out waiting for the browser — run `graft trail push` again, or use the link above", reason: "timed_out" }), timeoutMs);
|
|
121
121
|
// The timer must not hold the process open once the browser has answered.
|
|
122
122
|
timer.unref?.();
|
|
123
123
|
});
|
package/dist/brain/watch.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Watching a brain being built, from the terminal.
|
|
3
3
|
*
|
|
4
|
-
* `graft
|
|
4
|
+
* `graft trail push` used to end at "it is being mined into rules now — a few
|
|
5
5
|
* minutes. Watch it finish in your browser." and hand the prompt straight back.
|
|
6
6
|
* That sentence is the last thing this process ever says about the work, and it
|
|
7
7
|
* is said BEFORE the part that actually fails: of the repo brains attempted in
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/claude/init.ts"],"names":[],"mappings":"AAIA,OAAO,EAAuB,KAAK,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAKlF,OAAO,EAA6B,KAAK,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAElF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAErD;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,YAAY,EAAE,CAWzD;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/claude/init.ts"],"names":[],"mappings":"AAIA,OAAO,EAAuB,KAAK,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAKlF,OAAO,EAA6B,KAAK,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAElF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAErD;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,YAAY,EAAE,CAWzD;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAarG;AAED,MAAM,WAAW,UAAU;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,8EAA8E;IAC9E,GAAG,EAAE,QAAQ,CAAC;IACd,2EAA2E;IAC3E,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,wBAAgB,OAAO,CACrB,GAAG,EAAE,MAAM,EACX,IAAI,GAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAO,GACtG,UAAU,CAsCZ"}
|
package/dist/claude/init.js
CHANGED
|
@@ -38,7 +38,9 @@ export function buildGraphIfMissing(dir, opts) {
|
|
|
38
38
|
if (opts.build === false || !opts.cliPath || hasGraftIndex(dir))
|
|
39
39
|
return false;
|
|
40
40
|
try {
|
|
41
|
-
|
|
41
|
+
// execArgv carries the loader graft itself was started with (tsx, when run
|
|
42
|
+
// from source), so the child can run a .ts entry point too.
|
|
43
|
+
execFileSync(process.execPath, [...process.execArgv, opts.cliPath, 'build', '.'], { cwd: dir, stdio: 'inherit', timeout: 300000 });
|
|
42
44
|
return true;
|
|
43
45
|
}
|
|
44
46
|
catch {
|
package/dist/claude/init.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/claude/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAC5E,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,mBAAmB,EAAoB,MAAM,2BAA2B,CAAC;AAClF,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,WAAW,EAAiB,MAAM,wBAAwB,CAAC;AAClF,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAGjD;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,GAAW;IACvC,MAAM,CAAC,GAAG,CAAC,IAAY,EAAE,IAAY,EAAE,OAA6B,QAAQ,EAAgB,EAAE,CAC5F,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IACxE,OAAO;QACL,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,EAAE,eAAe,CAAC,EAAE,gCAAgC,CAAC;QAC1E,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,EAAE,SAAS,EAAE,sBAAsB,CAAC,EAAE,iBAAiB,CAAC;QAC7E,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,EAAE,SAAS,EAAE,iBAAiB,CAAC,EAAE,YAAY,CAAC;QACnE,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,CAAC,EAAE,aAAa,CAAC;QACrE,yEAAyE;QACzE,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,WAAW,CAAC,EAAE,kBAAkB,EAAE,KAAK,CAAC;KACrD,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CAAC,GAAW,EAAE,IAA2C;IAC1F,2EAA2E;IAC3E,4EAA4E;IAC5E,oEAAoE;IACpE,IAAI,IAAI,CAAC,KAAK,KAAK,KAAK,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,aAAa,CAAC,GAAG,CAAC;QAAE,OAAO,KAAK,CAAC;IAC9E,IAAI,CAAC;QACH,YAAY,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/claude/init.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.js
CHANGED
|
@@ -19,8 +19,10 @@ import { hostIds } from "./hosts/registry.js";
|
|
|
19
19
|
import { parseBrainArg, connectBrain, pullBrain, brainStatus } from "./brain/connect.js";
|
|
20
20
|
import { rulesForPointers } from "./brain/attach.js";
|
|
21
21
|
import { clearLink } from "./brain/link.js";
|
|
22
|
-
import { buildLocalDigest, fetchExpectedRepo, pushDigest, repoSlugFromGit, sameRepo } from "./brain/push.js";
|
|
22
|
+
import { buildEarlyDigest, buildLocalDigest, fetchExpectedRepo, pushDigest, pushEarlyDigest, repoSlugFromGit, sameRepo, } from "./brain/push.js";
|
|
23
23
|
import { readLink, writeLink } from "./brain/link.js";
|
|
24
|
+
import { withLegacyNames } from "./legacy-args.js";
|
|
25
|
+
import { applyChanges, fetchAcceptedChanges, markApplied } from "./brain/claude-md.js";
|
|
24
26
|
import { watchBuild } from "./brain/watch.js";
|
|
25
27
|
import { openBrowser, signupUrl, startHandoff } from "./brain/signup.js";
|
|
26
28
|
import { contextDirFor } from "./context/node-file.js";
|
|
@@ -41,7 +43,7 @@ import { patchBuildConfig } from "./util/state.js";
|
|
|
41
43
|
import { normalizePathPrefix } from "./util/paths.js";
|
|
42
44
|
import { latestSession, formatSessionStats, sessionInputRate } from "./claude/session-metrics.js";
|
|
43
45
|
import { setInputRate } from "./context/savings.js";
|
|
44
|
-
import { formatUpdateNudge, maybeRefreshInBackground, readUpdateCache, refreshUpdateCache, writeStamp } from "./upkeep.js";
|
|
46
|
+
import { formatUpdateNudge, maybeRefreshInBackground, readUpdateCache, refreshUpdateCache, wiredHostIds, writeStamp } from "./upkeep.js";
|
|
45
47
|
import { errorCode, filesBucket, durationBucket, formatDebug, formatStatus, firstRunNotice, isTrackedCommand, langsValue, offReason, maybeFlushInBackground, patchState, runFlush, track, trackFirstRunIfNew, } from "./telemetry/index.js";
|
|
46
48
|
const program = new Command();
|
|
47
49
|
const currentVersion = readCurrentVersion(import.meta.url);
|
|
@@ -817,8 +819,15 @@ program
|
|
|
817
819
|
.option("--dry-run", "print every file init would touch, then exit without writing")
|
|
818
820
|
.option("-y, --yes", "skip the picker and wire every detected agent (the pre-0.8 default)")
|
|
819
821
|
.option("--no-global", "skip writes outside this repo (the ~/.codex/ config + hooks)")
|
|
820
|
-
.option("--
|
|
821
|
-
.action(
|
|
822
|
+
.option("--trail <handoff>", "attach a Trail: <brainId>:<token> (or a bare id with GRAFT_BRAIN_TOKEN set)")
|
|
823
|
+
.action((dir, opts) => runInitCommand(dir, opts));
|
|
824
|
+
/**
|
|
825
|
+
* `graft init`. Also run by `graft trail push` on a repo graft has not been set
|
|
826
|
+
* up in — the Trail pages start people at push, and a trail whose rules no
|
|
827
|
+
* coding agent reads is only half set up. `epilogue: false` leaves out the
|
|
828
|
+
* closing banner when push is going to keep talking.
|
|
829
|
+
*/
|
|
830
|
+
async function runInitCommand(dir, opts, how = {}) {
|
|
822
831
|
if (opts.listAgents) {
|
|
823
832
|
for (const id of [...hostIds(), "claude"])
|
|
824
833
|
console.log(id);
|
|
@@ -827,10 +836,10 @@ program
|
|
|
827
836
|
// Parsed before anything is written: a mistyped handoff should cost the user
|
|
828
837
|
// an error, not a half-wired repo they have to `graft uninstall` out of.
|
|
829
838
|
let brainLink;
|
|
830
|
-
if (opts.
|
|
831
|
-
const parsed = parseBrainArg(opts.
|
|
839
|
+
if (opts.trail) {
|
|
840
|
+
const parsed = parseBrainArg(opts.trail);
|
|
832
841
|
if ("error" in parsed) {
|
|
833
|
-
console.error(`✗ --
|
|
842
|
+
console.error(`✗ --trail: ${parsed.error}`);
|
|
834
843
|
process.exitCode = 1;
|
|
835
844
|
return;
|
|
836
845
|
}
|
|
@@ -919,7 +928,7 @@ program
|
|
|
919
928
|
wireTarget(target, ids, { home, cliPath, plan, opts, wantClaude });
|
|
920
929
|
}
|
|
921
930
|
// The brain comes last, after the graph exists: its rules are anchored to
|
|
922
|
-
// symbols, and `graft
|
|
931
|
+
// symbols, and `graft trail status` can only report how many of them resolve
|
|
923
932
|
// once there is a graph to resolve them against.
|
|
924
933
|
if (brainLink) {
|
|
925
934
|
const res = await connectBrain(repo, brainLink, { home, ids });
|
|
@@ -938,15 +947,16 @@ program
|
|
|
938
947
|
const graphs = (children.length ? children.map((c) => join(repo, c)) : [repo])
|
|
939
948
|
.map((d) => loadGraphCached(contextDirFor(d, children.length ? undefined : globalDir)))
|
|
940
949
|
.filter((g) => g !== null);
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
950
|
+
if (how.epilogue !== false)
|
|
951
|
+
console.error("\n" +
|
|
952
|
+
formatInitEpilogue({
|
|
953
|
+
graphBuilt: graphs.length > 0,
|
|
954
|
+
nodes: graphs.reduce((n, g) => n + g.meta.nodeCount, 0),
|
|
955
|
+
edges: graphs.reduce((n, g) => n + g.meta.edgeCount, 0),
|
|
956
|
+
}));
|
|
947
957
|
// Sorted so `claude,cursor` and `cursor,claude` aggregate as one value.
|
|
948
958
|
track("init_completed", { agents: [...ids].sort().join(","), consent: consent === undefined ? "unasked" : String(consent) }, { repo });
|
|
949
|
-
}
|
|
959
|
+
}
|
|
950
960
|
/** One repo's worth of `init` writes — the parent, then each workspace child. */
|
|
951
961
|
function wireTarget(repo, ids, ctx) {
|
|
952
962
|
const { home, cliPath, plan, wantClaude, opts } = ctx;
|
|
@@ -1078,9 +1088,10 @@ program
|
|
|
1078
1088
|
? `\n⚠ ${bad.length} file(s) could not be parsed and were left as-is — see above.`
|
|
1079
1089
|
: "\n✓ graft fully removed. `graft init` re-wires from scratch.");
|
|
1080
1090
|
});
|
|
1091
|
+
// `graft trail …` still works: see legacy-args.ts.
|
|
1081
1092
|
const brain = program
|
|
1082
|
-
.command("
|
|
1083
|
-
.description("The Trail
|
|
1093
|
+
.command("trail")
|
|
1094
|
+
.description("The Trail attached to this repo: the rules mined from its own history");
|
|
1084
1095
|
/**
|
|
1085
1096
|
* Get this repo a brain from the terminal, by sending the user through signup
|
|
1086
1097
|
* in their browser and catching the handoff on loopback.
|
|
@@ -1106,7 +1117,7 @@ async function signUpForBrain(repo, slug) {
|
|
|
1106
1117
|
// A non-interactive shell has nobody to click anything, so waiting five
|
|
1107
1118
|
// minutes for a browser that will never come is worse than saying so now.
|
|
1108
1119
|
if (!process.stderr.isTTY) {
|
|
1109
|
-
console.error("· not a terminal — open that link, then run `graft
|
|
1120
|
+
console.error("· not a terminal — open that link, then run `graft trail connect <brainId>:<token>` here");
|
|
1110
1121
|
// Its own outcome, not a timeout: nothing here could have opened a browser,
|
|
1111
1122
|
// so folding the two together would read as people abandoning signup when
|
|
1112
1123
|
// it is only a remote shell doing what it has to.
|
|
@@ -1151,7 +1162,7 @@ brain
|
|
|
1151
1162
|
// read the repo yet. Saying "0 rules" without saying why reads as a
|
|
1152
1163
|
// failure, and the next step is the whole point.
|
|
1153
1164
|
console.error("✓ attached this repo to the brain — it has no rules yet");
|
|
1154
|
-
console.error("· run `graft
|
|
1165
|
+
console.error("· run `graft trail push` to read this repository into it");
|
|
1155
1166
|
return;
|
|
1156
1167
|
}
|
|
1157
1168
|
console.error(`✓ pulled ${res.ruleCount} rule(s) from ${parsed.brainId}`);
|
|
@@ -1166,7 +1177,7 @@ brain
|
|
|
1166
1177
|
const repo = resolve(dir);
|
|
1167
1178
|
const res = await pullBrain(repo, { home: homedir() });
|
|
1168
1179
|
if (!res) {
|
|
1169
|
-
console.error("· no brain attached — run `graft
|
|
1180
|
+
console.error("· no brain attached — run `graft trail connect <brainId>:<token>`");
|
|
1170
1181
|
return;
|
|
1171
1182
|
}
|
|
1172
1183
|
if (res.warning) {
|
|
@@ -1216,16 +1227,48 @@ brain
|
|
|
1216
1227
|
process.exitCode = 1;
|
|
1217
1228
|
return;
|
|
1218
1229
|
}
|
|
1230
|
+
const label = expected?.slug ?? (here ? `${here.owner}/${here.name}` : "this repository");
|
|
1231
|
+
console.error(`· reading ${label} — commit messages, pull-request discussion and the docs in the tree.`);
|
|
1232
|
+
console.error(" No file contents leave this machine.");
|
|
1233
|
+
// The instruction file and the newest pull requests go first, when the brain
|
|
1234
|
+
// takes them: its CLAUDE.md suggestions start from those while the rest of
|
|
1235
|
+
// the history is still being read here. Not awaited — the full read starts
|
|
1236
|
+
// at once, reusing the threads the early one already fetched.
|
|
1237
|
+
let early = Promise.resolve();
|
|
1238
|
+
let knownThreads = [];
|
|
1239
|
+
if (expected?.earlyUpload) {
|
|
1240
|
+
const first = await buildEarlyDigest(repo);
|
|
1241
|
+
if (first) {
|
|
1242
|
+
knownThreads = first.threads;
|
|
1243
|
+
early = pushEarlyDigest(link, first.digest).then((ok) => {
|
|
1244
|
+
if (ok)
|
|
1245
|
+
console.error("· CLAUDE.md suggestions are on their way in your browser, from the newest pull requests");
|
|
1246
|
+
});
|
|
1247
|
+
}
|
|
1248
|
+
}
|
|
1249
|
+
// A repo graft was never set up in gets `graft init` first — after the early
|
|
1250
|
+
// upload has gone, so the CLAUDE.md suggestions are not held up by the graph
|
|
1251
|
+
// build. Same picker as init: it is how someone agrees to what gets written,
|
|
1252
|
+
// so a non-interactive push only says what to run.
|
|
1253
|
+
if (wiredHostIds(repo).length === 0) {
|
|
1254
|
+
if (process.stdin.isTTY && process.stderr.isTTY) {
|
|
1255
|
+
// Its one line of output lands before the picker, not across it.
|
|
1256
|
+
await early;
|
|
1257
|
+
console.error("· graft is not set up in this repo yet — setting it up first, the same as `graft init`");
|
|
1258
|
+
await runInitCommand(repo, { build: true, mcp: true, hooks: true, statusline: true, global: true }, { epilogue: false });
|
|
1259
|
+
}
|
|
1260
|
+
else {
|
|
1261
|
+
console.error("· graft is not set up in this repo — run `graft init` so your coding agent reads these rules");
|
|
1262
|
+
}
|
|
1263
|
+
}
|
|
1219
1264
|
// The graph is what symbol anchors are resolved against, so a rule mined
|
|
1220
1265
|
// here can later go stale on its own. Without one the ingest still works;
|
|
1221
1266
|
// its rules simply govern the repo rather than a symbol in it.
|
|
1222
1267
|
const graph = loadGraphCached(contextDirFor(repo, program.opts().dir));
|
|
1223
1268
|
if (!graph)
|
|
1224
1269
|
console.error("· no graph yet — run `graft build` first so rules can be anchored to symbols");
|
|
1225
|
-
const
|
|
1226
|
-
|
|
1227
|
-
console.error(" No file contents leave this machine.");
|
|
1228
|
-
const built = await buildLocalDigest(repo, graph, { autoApprove: opts.approve !== false });
|
|
1270
|
+
const built = await buildLocalDigest(repo, graph, { autoApprove: opts.approve !== false, knownThreads });
|
|
1271
|
+
await early;
|
|
1229
1272
|
if ("error" in built) {
|
|
1230
1273
|
console.error(`✗ ${built.error}`);
|
|
1231
1274
|
process.exitCode = 1;
|
|
@@ -1274,7 +1317,7 @@ brain
|
|
|
1274
1317
|
// A non-zero exit, unlike every other ending here: this is the one case
|
|
1275
1318
|
// where the work did not produce a brain, and a CI step that ran the push
|
|
1276
1319
|
// should hear about it the way it hears about any other failure.
|
|
1277
|
-
console.error(" Nothing was lost — the brain is still there. Run `graft
|
|
1320
|
+
console.error(" Nothing was lost — the brain is still there. Run `graft trail push` again to retry the read.");
|
|
1278
1321
|
process.exitCode = 1;
|
|
1279
1322
|
return;
|
|
1280
1323
|
}
|
|
@@ -1284,6 +1327,66 @@ brain
|
|
|
1284
1327
|
}
|
|
1285
1328
|
console.error("· still building after 15 minutes — it has not failed, it is just long. Watch it finish in your browser.");
|
|
1286
1329
|
});
|
|
1330
|
+
const claudeMd = program
|
|
1331
|
+
.command("claude-md")
|
|
1332
|
+
.description("The CLAUDE.md changes this repo's brain suggested and you accepted in Trail");
|
|
1333
|
+
claudeMd
|
|
1334
|
+
.command("pull")
|
|
1335
|
+
.description("Write the CLAUDE.md changes you accepted in Trail into this repo's instruction file")
|
|
1336
|
+
.argument("[dir]", "target repo directory", ".")
|
|
1337
|
+
.option("--dry-run", "show what would change without writing the file or telling Trail")
|
|
1338
|
+
.action(async (dir, opts) => {
|
|
1339
|
+
const repo = resolve(dir);
|
|
1340
|
+
const link = readLink(repo);
|
|
1341
|
+
if (!link) {
|
|
1342
|
+
console.error("✗ this repo has no brain attached — run `graft trail push` first");
|
|
1343
|
+
process.exitCode = 1;
|
|
1344
|
+
return;
|
|
1345
|
+
}
|
|
1346
|
+
const pulled = await fetchAcceptedChanges(link);
|
|
1347
|
+
if ("error" in pulled) {
|
|
1348
|
+
console.error(`✗ ${pulled.error}`);
|
|
1349
|
+
process.exitCode = 1;
|
|
1350
|
+
return;
|
|
1351
|
+
}
|
|
1352
|
+
if (pulled.changes.length === 0) {
|
|
1353
|
+
console.error("· nothing accepted yet — accept suggestions on the brain's CLAUDE.md page, then pull again");
|
|
1354
|
+
return;
|
|
1355
|
+
}
|
|
1356
|
+
// The file Trail read, or a new CLAUDE.md when the repo had none.
|
|
1357
|
+
const rel = pulled.path || "CLAUDE.md";
|
|
1358
|
+
const file = join(repo, rel);
|
|
1359
|
+
const { existsSync, readFileSync, writeFileSync } = await import("node:fs");
|
|
1360
|
+
const before = existsSync(file) ? readFileSync(file, "utf8") : "";
|
|
1361
|
+
const result = applyChanges(before, pulled.changes);
|
|
1362
|
+
for (const c of result.written)
|
|
1363
|
+
console.error(` + ${c.kind === "add" ? "new section" : "edit"} · ${c.heading}`);
|
|
1364
|
+
for (const c of result.present)
|
|
1365
|
+
console.error(` = already in the file · ${c.heading}`);
|
|
1366
|
+
for (const s of result.skipped)
|
|
1367
|
+
console.error(` ! skipped · ${s.change.heading} — ${s.why}`);
|
|
1368
|
+
if (opts.dryRun) {
|
|
1369
|
+
console.error(`· dry run: ${result.written.length} change(s) would be written to ${rel}; nothing was written`);
|
|
1370
|
+
return;
|
|
1371
|
+
}
|
|
1372
|
+
if (result.written.length > 0)
|
|
1373
|
+
writeFileSync(file, result.text);
|
|
1374
|
+
// Written now or already there: either way the page should stop listing it.
|
|
1375
|
+
const done = [...result.written, ...result.present].map((c) => c.id);
|
|
1376
|
+
const told = await markApplied(link, done);
|
|
1377
|
+
if (result.written.length > 0) {
|
|
1378
|
+
console.error(`✓ wrote ${result.written.length} change(s) to ${rel} — review and commit it like any other edit`);
|
|
1379
|
+
}
|
|
1380
|
+
else if (result.present.length > 0) {
|
|
1381
|
+
console.error(`✓ ${rel} already has every accepted change`);
|
|
1382
|
+
}
|
|
1383
|
+
if (!told)
|
|
1384
|
+
console.error("⚠ could not tell Trail which changes were written; the page may still list them");
|
|
1385
|
+
if (result.skipped.length > 0) {
|
|
1386
|
+
console.error(`· ${result.skipped.length} change(s) no longer match the local file — edit them on the CLAUDE.md page, or apply them by hand`);
|
|
1387
|
+
process.exitCode = 1;
|
|
1388
|
+
}
|
|
1389
|
+
});
|
|
1287
1390
|
brain
|
|
1288
1391
|
.command("status")
|
|
1289
1392
|
.description("Show the attached brain, how many rules are cached, and how many still match the code")
|
|
@@ -1303,7 +1406,7 @@ brain
|
|
|
1303
1406
|
return;
|
|
1304
1407
|
}
|
|
1305
1408
|
if (!link) {
|
|
1306
|
-
console.error("· no brain attached — run `graft
|
|
1409
|
+
console.error("· no brain attached — run `graft trail connect <brainId>:<token>`");
|
|
1307
1410
|
return;
|
|
1308
1411
|
}
|
|
1309
1412
|
console.error(`brain ${link.brainId}`);
|
|
@@ -1329,7 +1432,7 @@ brain
|
|
|
1329
1432
|
clearLink(resolve(dir));
|
|
1330
1433
|
console.error(`✓ detached the brain from ${repo}`);
|
|
1331
1434
|
});
|
|
1332
|
-
program.parseAsync().catch((err) => {
|
|
1435
|
+
program.parseAsync(withLegacyNames(process.argv)).catch((err) => {
|
|
1333
1436
|
console.error(err instanceof Error ? err.message : err);
|
|
1334
1437
|
process.exit(1);
|
|
1335
1438
|
});
|