@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.
@@ -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 { slug: body.repo.slug, status: String(body.repo.status ?? ""), brainName: String(body.brain_name ?? "") };
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
- threads = await readThreads(slug.owner, slug.name, token, fetchImpl);
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";
@@ -1 +1 @@
1
- {"version":3,"file":"push.js","sourceRoot":"","sources":["../../src/brain/push.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"push.js","sourceRoot":"","sources":["../../src/brain/push.ts"],"names":[],"mappings":"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"}
@@ -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 --brain <id>:<token>` line to
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 brain push` on an unlinked repo starts here instead of stopping.
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 brain push` again.";
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 brain push` again, or use the link above", reason: "timed_out" }), timeoutMs);
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
  });
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Watching a brain being built, from the terminal.
3
3
  *
4
- * `graft brain push` used to end at "it is being mined into rules now — a few
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,CAWrG;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"}
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"}
@@ -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
- execFileSync(process.execPath, [opts.cliPath, 'build', '.'], { cwd: dir, stdio: 'inherit', timeout: 300000 });
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 {
@@ -1 +1 @@
1
- {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/claude/init.ts"],"names":[],"mappings":"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"}
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,2EAA2E;QAC3E,4DAA4D;QAC5D,YAAY,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,GAAG,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;QACnI,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAcD,MAAM,UAAU,OAAO,CACrB,GAAW,EACX,OAAqG,EAAE;IAEvG,6EAA6E;IAC7E,MAAM,CAAC,QAAQ,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,CAAC,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAE9F,SAAS,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAEpD,MAAM,YAAY,GAAG,QAAQ,CAAC;IAC9B,IAAI,QAAQ,GAAwB,EAAE,CAAC;IACvC,IAAI,CAAC;QAAC,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC,CAAC,gCAAgC,CAAC,CAAC;IAC7G,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,kBAAkB,CAAC,QAAQ,EAAE,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;IAC3F,aAAa,CAAC,YAAY,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;IAEpE,MAAM,EAAE,GAAG,UAAU,CAAC;IACtB,MAAM,EAAE,GAAG,KAAK,CAAC;IACjB,MAAM,QAAQ,GAAG,aAAa,EAAE,CAAC,CAAC,kEAAkE;IACpG,aAAa,CAAC,EAAE,EAAE,cAAc,CAAC,QAAQ,CAAC,CAAC,CAAC;IAAC,SAAS,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;IAClE,aAAa,CAAC,EAAE,EAAE,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC;IAAC,SAAS,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;IAE7D,mFAAmF;IACnF,mFAAmF;IACnF,MAAM,SAAS,GAAG,KAAK,CAAC;IACxB,SAAS,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACnD,aAAa,CAAC,SAAS,EAAE,aAAa,EAAE,CAAC,CAAC;IAE1C,0EAA0E;IAC1E,qFAAqF;IACrF,2EAA2E;IAC3E,MAAM,GAAG,GAAG,YAAY,CAAC,QAAQ,EAAE,SAAS,EAAE,YAAY,EAAE,WAAW,EAAE,CAAC,CAAC;IAE3E,+EAA+E;IAC/E,gFAAgF;IAChF,8EAA8E;IAC9E,gFAAgF;IAChF,cAAc;IACd,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,mBAAmB,CAAC,IAAI,CAAC,IAAI,IAAI,OAAO,EAAE,CAAC,CAAC;IAExF,MAAM,KAAK,GAAG,mBAAmB,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IAC7C,OAAO,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;AAC3F,CAAC"}
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("--brain <handoff>", "attach a Trail brain: <brainId>:<token> (or a bare brain id with GRAFT_BRAIN_TOKEN set)")
821
- .action(async (dir, opts) => {
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.brain) {
831
- const parsed = parseBrainArg(opts.brain);
839
+ if (opts.trail) {
840
+ const parsed = parseBrainArg(opts.trail);
832
841
  if ("error" in parsed) {
833
- console.error(`✗ --brain: ${parsed.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 brain status` can only report how many of them resolve
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
- console.error("\n" +
942
- formatInitEpilogue({
943
- graphBuilt: graphs.length > 0,
944
- nodes: graphs.reduce((n, g) => n + g.meta.nodeCount, 0),
945
- edges: graphs.reduce((n, g) => n + g.meta.edgeCount, 0),
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("brain")
1083
- .description("The Trail brain attached to this repo: the rules mined from its own history");
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 brain connect <brainId>:<token>` here");
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 brain push` to read this repository into it");
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 brain connect <brainId>:<token>`");
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 label = expected?.slug ?? (here ? `${here.owner}/${here.name}` : "this repository");
1226
- console.error(`· reading ${label} — commit messages, pull-request discussion and the docs in the tree.`);
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 brain push` again to retry the read.");
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 brain connect <brainId>:<token>`");
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
  });