@nanonets/graft 0.7.1 → 0.8.1
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 +170 -70
- package/dist/ask/ask.d.ts +14 -0
- package/dist/ask/ask.d.ts.map +1 -1
- package/dist/ask/ask.js +24 -5
- package/dist/ask/ask.js.map +1 -1
- package/dist/claude/format.d.ts +1 -1
- package/dist/claude/format.d.ts.map +1 -1
- package/dist/claude/format.js +6 -3
- package/dist/claude/format.js.map +1 -1
- package/dist/claude/hooks.d.ts +15 -0
- package/dist/claude/hooks.d.ts.map +1 -1
- package/dist/claude/hooks.js +55 -4
- package/dist/claude/hooks.js.map +1 -1
- package/dist/claude/init.d.ts +17 -0
- package/dist/claude/init.d.ts.map +1 -1
- package/dist/claude/init.js +45 -19
- package/dist/claude/init.js.map +1 -1
- package/dist/claude/settings-merge.d.ts.map +1 -1
- package/dist/claude/settings-merge.js +9 -1
- package/dist/claude/settings-merge.js.map +1 -1
- package/dist/claude/skill-template.d.ts.map +1 -1
- package/dist/claude/skill-template.js +31 -8
- package/dist/claude/skill-template.js.map +1 -1
- package/dist/claude/state.d.ts +2 -20
- package/dist/claude/state.d.ts.map +1 -1
- package/dist/claude/state.js +9 -72
- package/dist/claude/state.js.map +1 -1
- package/dist/cli-picker.d.ts +60 -0
- package/dist/cli-picker.d.ts.map +1 -0
- package/dist/cli-picker.js +268 -0
- package/dist/cli-picker.js.map +1 -0
- package/dist/cli.js +104 -13
- package/dist/cli.js.map +1 -1
- package/dist/context/check.d.ts +21 -0
- package/dist/context/check.d.ts.map +1 -1
- package/dist/context/check.js +32 -1
- package/dist/context/check.js.map +1 -1
- package/dist/engine.d.ts +2 -0
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +1 -0
- package/dist/engine.js.map +1 -1
- package/dist/graph/build.d.ts +13 -2
- package/dist/graph/build.d.ts.map +1 -1
- package/dist/graph/build.js +93 -19
- package/dist/graph/build.js.map +1 -1
- package/dist/graph/extract-cache.d.ts +96 -0
- package/dist/graph/extract-cache.d.ts.map +1 -0
- package/dist/graph/extract-cache.js +199 -0
- package/dist/graph/extract-cache.js.map +1 -0
- package/dist/graph/fingerprint.d.ts +70 -0
- package/dist/graph/fingerprint.d.ts.map +1 -0
- package/dist/graph/fingerprint.js +147 -0
- package/dist/graph/fingerprint.js.map +1 -0
- package/dist/graph/load.d.ts +11 -0
- package/dist/graph/load.d.ts.map +1 -1
- package/dist/graph/load.js +14 -0
- package/dist/graph/load.js.map +1 -1
- package/dist/graph/refresh.d.ts +49 -0
- package/dist/graph/refresh.d.ts.map +1 -0
- package/dist/graph/refresh.js +202 -0
- package/dist/graph/refresh.js.map +1 -0
- package/dist/graph/source-files.d.ts +18 -0
- package/dist/graph/source-files.d.ts.map +1 -0
- package/dist/graph/source-files.js +36 -0
- package/dist/graph/source-files.js.map +1 -0
- package/dist/graph/traverse-cli.d.ts.map +1 -1
- package/dist/graph/traverse-cli.js +16 -6
- package/dist/graph/traverse-cli.js.map +1 -1
- package/dist/hosts/codex-hooks.d.ts +8 -0
- package/dist/hosts/codex-hooks.d.ts.map +1 -1
- package/dist/hosts/codex-hooks.js +27 -4
- package/dist/hosts/codex-hooks.js.map +1 -1
- package/dist/hosts/init.d.ts +2 -0
- package/dist/hosts/init.d.ts.map +1 -1
- package/dist/hosts/init.js +5 -2
- package/dist/hosts/init.js.map +1 -1
- package/dist/hosts/mcp-config.d.ts +18 -0
- package/dist/hosts/mcp-config.d.ts.map +1 -1
- package/dist/hosts/mcp-config.js +31 -7
- package/dist/hosts/mcp-config.js.map +1 -1
- package/dist/hosts/plan.d.ts +32 -0
- package/dist/hosts/plan.d.ts.map +1 -0
- package/dist/hosts/plan.js +67 -0
- package/dist/hosts/plan.js.map +1 -0
- package/dist/hosts/registry.d.ts.map +1 -1
- package/dist/hosts/registry.js +9 -0
- package/dist/hosts/registry.js.map +1 -1
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +5 -2
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/tools.d.ts +2 -2
- package/dist/mcp/tools.d.ts.map +1 -1
- package/dist/mcp/tools.js +108 -88
- package/dist/mcp/tools.js.map +1 -1
- package/dist/search/grep-cli.js +1 -1
- package/dist/search/grep-cli.js.map +1 -1
- package/dist/util/state.d.ts +45 -0
- package/dist/util/state.d.ts.map +1 -0
- package/dist/util/state.js +121 -0
- package/dist/util/state.js.map +1 -0
- package/package.json +1 -1
package/dist/claude/state.js
CHANGED
|
@@ -1,83 +1,20 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Claude Code session state. The shared `graft/.cache/` pieces (the statusline's
|
|
3
|
+
* `Stats` snapshot and the build lock) live in `../util/state.js` so the graph's
|
|
4
|
+
* pre-query auto-refresh can take the same lock; they are re-exported here so
|
|
5
|
+
* every existing import path keeps working.
|
|
6
|
+
*/
|
|
7
|
+
import { join } from 'node:path';
|
|
8
|
+
import { cacheDir, readJson, writeJsonAtomic } from '../util/state.js';
|
|
9
|
+
export { LOCK_STALE_MS, acquireLock, acquireLockIn, releaseLockIn, cacheDir, emptyStats, patchStats, readStats, releaseLock, writeJsonAtomic, writeStats, } from '../util/state.js';
|
|
8
10
|
function emptySession() {
|
|
9
11
|
return { lastQuery: null, perAgentQuery: {}, graftReads: 0, sourceReads: 0, savedTokens: 0, injectedPointers: [] };
|
|
10
12
|
}
|
|
11
|
-
export function cacheDir(projectDir) { return join(projectDir, 'graft', '.cache'); }
|
|
12
|
-
function statsPath(d) { return join(cacheDir(d), 'stats.json'); }
|
|
13
13
|
function sessionPath(d, id) { return join(cacheDir(d), 'session', `${id}.json`); }
|
|
14
|
-
function lockPath(d) { return join(cacheDir(d), '.sync.lock'); }
|
|
15
|
-
function readJson(p) {
|
|
16
|
-
try {
|
|
17
|
-
return JSON.parse(readFileSync(p, 'utf8'));
|
|
18
|
-
}
|
|
19
|
-
catch {
|
|
20
|
-
return null;
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
function writeJsonAtomic(p, value) {
|
|
24
|
-
mkdirSync(dirname(p), { recursive: true });
|
|
25
|
-
const tmp = `${p}.${process.pid}.tmp`;
|
|
26
|
-
writeFileSync(tmp, JSON.stringify(value, null, 2));
|
|
27
|
-
renameSync(tmp, p);
|
|
28
|
-
}
|
|
29
|
-
export function readStats(d) { return readJson(statsPath(d)); }
|
|
30
|
-
export function writeStats(d, s) { writeJsonAtomic(statsPath(d), s); }
|
|
31
|
-
// Best-effort read-modify-write; not atomic across concurrent processes, but acceptable
|
|
32
|
-
// for episodic hook writes (worst case is a lost update, not corruption).
|
|
33
|
-
export function patchStats(d, patch) {
|
|
34
|
-
const next = { ...(readStats(d) ?? emptyStats()), ...patch };
|
|
35
|
-
writeStats(d, next);
|
|
36
|
-
return next;
|
|
37
|
-
}
|
|
38
14
|
export function readSession(d, id) {
|
|
39
15
|
return readJson(sessionPath(d, id)) ?? emptySession();
|
|
40
16
|
}
|
|
41
17
|
export function writeSession(d, id, s) {
|
|
42
18
|
writeJsonAtomic(sessionPath(d, id), s);
|
|
43
19
|
}
|
|
44
|
-
export function acquireLock(d) {
|
|
45
|
-
const p = lockPath(d);
|
|
46
|
-
mkdirSync(cacheDir(d), { recursive: true });
|
|
47
|
-
const payload = JSON.stringify({ pid: process.pid, at: new Date().toISOString() });
|
|
48
|
-
try {
|
|
49
|
-
writeFileSync(p, payload, { flag: 'wx' }); // atomic exclusive create
|
|
50
|
-
return true;
|
|
51
|
-
}
|
|
52
|
-
catch (e) {
|
|
53
|
-
if (e?.code !== 'EEXIST')
|
|
54
|
-
throw e;
|
|
55
|
-
let stale;
|
|
56
|
-
try {
|
|
57
|
-
stale = Date.now() - statSync(p).mtimeMs >= LOCK_STALE_MS;
|
|
58
|
-
}
|
|
59
|
-
catch {
|
|
60
|
-
stale = true;
|
|
61
|
-
}
|
|
62
|
-
if (!stale)
|
|
63
|
-
return false;
|
|
64
|
-
try {
|
|
65
|
-
rmSync(p);
|
|
66
|
-
}
|
|
67
|
-
catch { /* another process reclaimed it */ }
|
|
68
|
-
try {
|
|
69
|
-
writeFileSync(p, payload, { flag: 'wx' });
|
|
70
|
-
return true;
|
|
71
|
-
}
|
|
72
|
-
catch (e2) {
|
|
73
|
-
if (e2?.code === 'EEXIST')
|
|
74
|
-
return false;
|
|
75
|
-
throw e2;
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
export function releaseLock(d) { try {
|
|
80
|
-
rmSync(lockPath(d));
|
|
81
|
-
}
|
|
82
|
-
catch { /* already gone */ } }
|
|
83
20
|
//# sourceMappingURL=state.js.map
|
package/dist/claude/state.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state.js","sourceRoot":"","sources":["../../src/claude/state.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"state.js","sourceRoot":"","sources":["../../src/claude/state.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAEvE,OAAO,EACL,aAAa,EACb,WAAW,EACX,aAAa,EACb,aAAa,EACb,QAAQ,EACR,UAAU,EACV,UAAU,EACV,SAAS,EACT,WAAW,EACX,eAAe,EACf,UAAU,GACX,MAAM,kBAAkB,CAAC;AAe1B,SAAS,YAAY;IACnB,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,aAAa,EAAE,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,gBAAgB,EAAE,EAAE,EAAE,CAAC;AACrH,CAAC;AAED,SAAS,WAAW,CAAC,CAAS,EAAE,EAAU,IAAY,OAAO,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;AAE1G,MAAM,UAAU,WAAW,CAAC,CAAS,EAAE,EAAU;IAC/C,OAAO,QAAQ,CAAe,WAAW,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,YAAY,EAAE,CAAC;AACtE,CAAC;AACD,MAAM,UAAU,YAAY,CAAC,CAAS,EAAE,EAAU,EAAE,CAAe;IACjE,eAAe,CAAC,WAAW,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;AACzC,CAAC"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import type { HostPlan, PlannedWrite } from './hosts/plan.js';
|
|
2
|
+
/** `/Users/me/.codex/x` → `~/.codex/x`, for display only. */
|
|
3
|
+
export declare function tilde(path: string, home: string): string;
|
|
4
|
+
/**
|
|
5
|
+
* One-line summary of what selecting a host writes: repo-relative paths, then
|
|
6
|
+
* a count for anything landing outside the repo — those are the writes users
|
|
7
|
+
* can't see in `git status`, so they get named explicitly.
|
|
8
|
+
*/
|
|
9
|
+
export declare function describeWrites(writes: PlannedWrite[], repo: string, home: string, maxShown?: number): string;
|
|
10
|
+
export interface PickerRow {
|
|
11
|
+
id: string;
|
|
12
|
+
detected: boolean;
|
|
13
|
+
summary: string;
|
|
14
|
+
/** True when selecting this host writes outside the repo. */
|
|
15
|
+
hasGlobal: boolean;
|
|
16
|
+
}
|
|
17
|
+
export interface PickerState {
|
|
18
|
+
rows: PickerRow[];
|
|
19
|
+
cursor: number;
|
|
20
|
+
checked: ReadonlySet<string>;
|
|
21
|
+
done: boolean;
|
|
22
|
+
aborted: boolean;
|
|
23
|
+
}
|
|
24
|
+
/** Claude Code starts checked — it's the deep integration — everything else off. */
|
|
25
|
+
export declare function initialPickerState(plan: HostPlan[], repo: string, home: string): PickerState;
|
|
26
|
+
export type PickerKey = 'up' | 'down' | 'space' | 'all' | 'enter' | 'abort';
|
|
27
|
+
export declare const KEY_UP = "\u001B[A";
|
|
28
|
+
export declare const KEY_DOWN = "\u001B[B";
|
|
29
|
+
export declare const KEY_ESC = "\u001B";
|
|
30
|
+
export declare const KEY_CTRL_C = "\u0003";
|
|
31
|
+
/** A single keypress → the key we act on, or null to ignore. */
|
|
32
|
+
export declare function keyOf(chunk: string): PickerKey | null;
|
|
33
|
+
/**
|
|
34
|
+
* Split a raw stdin chunk into keypresses. A terminal is free to batch bytes —
|
|
35
|
+
* held keys, pasted input, or a pty replaying a script all arrive as one chunk —
|
|
36
|
+
* so a chunk is a sequence, never a single key. CSI sequences (ESC '[' final)
|
|
37
|
+
* are consumed whole so an arrow key never reads as a bare ESC (i.e. abort).
|
|
38
|
+
*/
|
|
39
|
+
export declare function keysOf(chunk: string): PickerKey[];
|
|
40
|
+
export declare function reducePicker(state: PickerState, key: PickerKey): PickerState;
|
|
41
|
+
export declare function renderPicker(state: PickerState, tty?: boolean): string;
|
|
42
|
+
/** Ids in plan order, so output ordering never depends on toggle order. */
|
|
43
|
+
export declare function pickedIds(state: PickerState): string[];
|
|
44
|
+
/**
|
|
45
|
+
* Drive the picker on a real terminal. Resolves the chosen ids, or null if the
|
|
46
|
+
* user cancelled — in which case the caller must write nothing.
|
|
47
|
+
*/
|
|
48
|
+
export declare function runPicker(plan: HostPlan[], repo: string, home: string): Promise<string[] | null>;
|
|
49
|
+
/**
|
|
50
|
+
* Shown when there's no TTY to prompt on and no flag saying what to wire.
|
|
51
|
+
* Writing nothing is deliberate: a scripted run shouldn't get files for every
|
|
52
|
+
* agent the machine happens to have installed.
|
|
53
|
+
*/
|
|
54
|
+
export declare function formatNonInteractiveHelp(detectedIds: string[]): string;
|
|
55
|
+
/**
|
|
56
|
+
* `--dry-run` output: every path init would touch, repo writes first, then a
|
|
57
|
+
* separate section for anything outside the repo.
|
|
58
|
+
*/
|
|
59
|
+
export declare function formatPlan(plan: HostPlan[], ids: string[], repo: string, home: string, tty?: boolean): string;
|
|
60
|
+
//# sourceMappingURL=cli-picker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-picker.d.ts","sourceRoot":"","sources":["../src/cli-picker.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAM9D,6DAA6D;AAC7D,wBAAgB,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAExD;AAWD;;;;GAIG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,YAAY,EAAE,EACtB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,QAAQ,SAAI,GACX,MAAM,CAiBR;AAED,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,6DAA6D;IAC7D,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,SAAS,EAAE,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC7B,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,oFAAoF;AACpF,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,QAAQ,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,WAAW,CAa5F;AAED,MAAM,MAAM,SAAS,GAAG,IAAI,GAAG,MAAM,GAAG,OAAO,GAAG,KAAK,GAAG,OAAO,GAAG,OAAO,CAAC;AAE5E,eAAO,MAAM,MAAM,aAAW,CAAC;AAC/B,eAAO,MAAM,QAAQ,aAAW,CAAC;AACjC,eAAO,MAAM,OAAO,WAAS,CAAC;AAC9B,eAAO,MAAM,UAAU,WAAS,CAAC;AAEjC,gEAAgE;AAChE,wBAAgB,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAUrD;AAED;;;;;GAKG;AACH,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,CAkBjD;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,WAAW,EAAE,GAAG,EAAE,SAAS,GAAG,WAAW,CAsB5E;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,WAAW,EAAE,GAAG,UAAO,GAAG,MAAM,CAqBnE;AAED,2EAA2E;AAC3E,wBAAgB,SAAS,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,EAAE,CAEtD;AAED;;;GAGG;AACH,wBAAsB,SAAS,CAC7B,IAAI,EAAE,QAAQ,EAAE,EAChB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,CAiD1B;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,MAAM,CAmBtE;AAED;;;GAGG;AACH,wBAAgB,UAAU,CACxB,IAAI,EAAE,QAAQ,EAAE,EAChB,GAAG,EAAE,MAAM,EAAE,EACb,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,GAAG,UAAgC,GAClC,MAAM,CA4BR"}
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `graft init`'s agent picker and `--dry-run` plan printer.
|
|
3
|
+
*
|
|
4
|
+
* Split three ways so the logic is testable without a TTY: `renderPicker` and
|
|
5
|
+
* `reducePicker` are pure, `runPicker` is the only part that touches stdin.
|
|
6
|
+
*/
|
|
7
|
+
import { relative, dirname, sep } from 'node:path';
|
|
8
|
+
const indigo = (s) => `\x1b[38;2;84;111;255m${s}\x1b[0m`;
|
|
9
|
+
const muted = (s) => `\x1b[38;5;244m${s}\x1b[0m`;
|
|
10
|
+
const amber = (s) => `\x1b[38;5;179m${s}\x1b[0m`;
|
|
11
|
+
/** `/Users/me/.codex/x` → `~/.codex/x`, for display only. */
|
|
12
|
+
export function tilde(path, home) {
|
|
13
|
+
return path === home || path.startsWith(home + sep) ? `~${path.slice(home.length)}` : path;
|
|
14
|
+
}
|
|
15
|
+
/** Deepest directory containing every given path. */
|
|
16
|
+
function commonDir(paths) {
|
|
17
|
+
const split = paths.map((p) => dirname(p).split(sep));
|
|
18
|
+
const first = split[0] ?? [];
|
|
19
|
+
let i = 0;
|
|
20
|
+
while (i < first.length && split.every((s) => s[i] === first[i]))
|
|
21
|
+
i++;
|
|
22
|
+
return first.slice(0, i).join(sep);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* One-line summary of what selecting a host writes: repo-relative paths, then
|
|
26
|
+
* a count for anything landing outside the repo — those are the writes users
|
|
27
|
+
* can't see in `git status`, so they get named explicitly.
|
|
28
|
+
*/
|
|
29
|
+
export function describeWrites(writes, repo, home, maxShown = 3) {
|
|
30
|
+
const repoPaths = writes.filter((w) => w.scope === 'repo').map((w) => relative(repo, w.path));
|
|
31
|
+
const globals = writes.filter((w) => w.scope === 'global');
|
|
32
|
+
const parts = [];
|
|
33
|
+
if (repoPaths.length > 0) {
|
|
34
|
+
parts.push(repoPaths.length <= maxShown
|
|
35
|
+
? repoPaths.join(', ')
|
|
36
|
+
: `${repoPaths.slice(0, maxShown).join(', ')} +${repoPaths.length - maxShown} more`);
|
|
37
|
+
}
|
|
38
|
+
if (globals.length > 0) {
|
|
39
|
+
const where = tilde(commonDir(globals.map((w) => w.path)), home);
|
|
40
|
+
parts.push(`+ ${globals.length} in ${where}/ (machine-wide)`);
|
|
41
|
+
}
|
|
42
|
+
if (!writes.some((w) => w.kind === 'mcp'))
|
|
43
|
+
parts.push('no MCP');
|
|
44
|
+
return parts.join(' · ');
|
|
45
|
+
}
|
|
46
|
+
/** Claude Code starts checked — it's the deep integration — everything else off. */
|
|
47
|
+
export function initialPickerState(plan, repo, home) {
|
|
48
|
+
return {
|
|
49
|
+
rows: plan.map((p) => ({
|
|
50
|
+
id: p.id,
|
|
51
|
+
detected: p.detected,
|
|
52
|
+
summary: describeWrites(p.writes, repo, home),
|
|
53
|
+
hasGlobal: p.writes.some((w) => w.scope === 'global'),
|
|
54
|
+
})),
|
|
55
|
+
cursor: 0,
|
|
56
|
+
checked: new Set(plan.some((p) => p.id === 'claude') ? ['claude'] : []),
|
|
57
|
+
done: false,
|
|
58
|
+
aborted: false,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
export const KEY_UP = '\x1b[A';
|
|
62
|
+
export const KEY_DOWN = '\x1b[B';
|
|
63
|
+
export const KEY_ESC = '\x1b';
|
|
64
|
+
export const KEY_CTRL_C = '\x03';
|
|
65
|
+
/** A single keypress → the key we act on, or null to ignore. */
|
|
66
|
+
export function keyOf(chunk) {
|
|
67
|
+
switch (chunk) {
|
|
68
|
+
case KEY_UP:
|
|
69
|
+
case 'k': return 'up';
|
|
70
|
+
case KEY_DOWN:
|
|
71
|
+
case 'j': return 'down';
|
|
72
|
+
case ' ': return 'space';
|
|
73
|
+
case 'a': return 'all';
|
|
74
|
+
case '\r':
|
|
75
|
+
case '\n': return 'enter';
|
|
76
|
+
case KEY_ESC:
|
|
77
|
+
case KEY_CTRL_C:
|
|
78
|
+
case 'q': return 'abort';
|
|
79
|
+
default: return null;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Split a raw stdin chunk into keypresses. A terminal is free to batch bytes —
|
|
84
|
+
* held keys, pasted input, or a pty replaying a script all arrive as one chunk —
|
|
85
|
+
* so a chunk is a sequence, never a single key. CSI sequences (ESC '[' final)
|
|
86
|
+
* are consumed whole so an arrow key never reads as a bare ESC (i.e. abort).
|
|
87
|
+
*/
|
|
88
|
+
export function keysOf(chunk) {
|
|
89
|
+
const keys = [];
|
|
90
|
+
let i = 0;
|
|
91
|
+
while (i < chunk.length) {
|
|
92
|
+
let token;
|
|
93
|
+
if (chunk[i] === KEY_ESC && chunk[i + 1] === '[') {
|
|
94
|
+
// ESC '[' then optional parameter bytes, then one final byte @-~.
|
|
95
|
+
let j = i + 2;
|
|
96
|
+
while (j < chunk.length && !/[@-~]/.test(chunk[j]))
|
|
97
|
+
j++;
|
|
98
|
+
token = chunk.slice(i, Math.min(j + 1, chunk.length));
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
token = chunk[i];
|
|
102
|
+
}
|
|
103
|
+
i += token.length;
|
|
104
|
+
const key = keyOf(token);
|
|
105
|
+
if (key !== null)
|
|
106
|
+
keys.push(key);
|
|
107
|
+
}
|
|
108
|
+
return keys;
|
|
109
|
+
}
|
|
110
|
+
export function reducePicker(state, key) {
|
|
111
|
+
const n = state.rows.length;
|
|
112
|
+
switch (key) {
|
|
113
|
+
case 'up':
|
|
114
|
+
return { ...state, cursor: (state.cursor - 1 + n) % n };
|
|
115
|
+
case 'down':
|
|
116
|
+
return { ...state, cursor: (state.cursor + 1) % n };
|
|
117
|
+
case 'space': {
|
|
118
|
+
const next = new Set(state.checked);
|
|
119
|
+
const id = state.rows[state.cursor].id;
|
|
120
|
+
if (next.has(id))
|
|
121
|
+
next.delete(id);
|
|
122
|
+
else
|
|
123
|
+
next.add(id);
|
|
124
|
+
return { ...state, checked: next };
|
|
125
|
+
}
|
|
126
|
+
case 'all': {
|
|
127
|
+
const allOn = state.rows.every((r) => state.checked.has(r.id));
|
|
128
|
+
return { ...state, checked: new Set(allOn ? [] : state.rows.map((r) => r.id)) };
|
|
129
|
+
}
|
|
130
|
+
case 'enter':
|
|
131
|
+
return { ...state, done: true };
|
|
132
|
+
case 'abort':
|
|
133
|
+
return { ...state, aborted: true };
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
export function renderPicker(state, tty = true) {
|
|
137
|
+
const dim = tty ? muted : (s) => s;
|
|
138
|
+
const hot = tty ? indigo : (s) => s;
|
|
139
|
+
const warn = tty ? amber : (s) => s;
|
|
140
|
+
// Pad on the plain label so the summary column lines up regardless of which
|
|
141
|
+
// rows carry the '(not detected)' tag or the cursor's colour codes.
|
|
142
|
+
const label = (r) => `${r.id}${r.detected ? '' : ' (not detected)'}`;
|
|
143
|
+
const width = Math.max(...state.rows.map((r) => label(r).length));
|
|
144
|
+
const lines = ['graft init — select what to wire into this repo:', ''];
|
|
145
|
+
for (const [i, row] of state.rows.entries()) {
|
|
146
|
+
const here = i === state.cursor;
|
|
147
|
+
const box = state.checked.has(row.id) ? '[x]' : '[ ]';
|
|
148
|
+
const gap = ' '.repeat(width - label(row).length);
|
|
149
|
+
const name = here ? hot(row.id) : row.id;
|
|
150
|
+
const tag = row.detected ? '' : dim(' (not detected)');
|
|
151
|
+
const summary = row.hasGlobal ? warn(row.summary) : dim(row.summary);
|
|
152
|
+
lines.push(`${here ? '›' : ' '} ${box} ${name}${tag}${gap} ${summary}`);
|
|
153
|
+
}
|
|
154
|
+
lines.push('', dim('↑↓ move · space toggle · a all · enter confirm · esc cancel'));
|
|
155
|
+
return lines.join('\n');
|
|
156
|
+
}
|
|
157
|
+
/** Ids in plan order, so output ordering never depends on toggle order. */
|
|
158
|
+
export function pickedIds(state) {
|
|
159
|
+
return state.rows.filter((r) => state.checked.has(r.id)).map((r) => r.id);
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Drive the picker on a real terminal. Resolves the chosen ids, or null if the
|
|
163
|
+
* user cancelled — in which case the caller must write nothing.
|
|
164
|
+
*/
|
|
165
|
+
export async function runPicker(plan, repo, home) {
|
|
166
|
+
let state = initialPickerState(plan, repo, home);
|
|
167
|
+
const out = process.stderr;
|
|
168
|
+
const stdin = process.stdin;
|
|
169
|
+
let lastLines = 0;
|
|
170
|
+
const draw = () => {
|
|
171
|
+
if (lastLines > 0)
|
|
172
|
+
out.write(`\x1b[${lastLines}A\x1b[0J`);
|
|
173
|
+
const text = renderPicker(state);
|
|
174
|
+
out.write(`${text}\n`);
|
|
175
|
+
lastLines = text.split('\n').length;
|
|
176
|
+
};
|
|
177
|
+
const wasRaw = Boolean(stdin.isRaw);
|
|
178
|
+
stdin.setRawMode?.(true);
|
|
179
|
+
stdin.resume();
|
|
180
|
+
draw();
|
|
181
|
+
try {
|
|
182
|
+
return await new Promise((resolve) => {
|
|
183
|
+
// Both listeners come off together: a leftover 'end' would otherwise fire
|
|
184
|
+
// after a confirmed pick and redraw the picker over init's own output.
|
|
185
|
+
const finish = (onData) => {
|
|
186
|
+
stdin.off('data', onData);
|
|
187
|
+
stdin.off('end', onEnd);
|
|
188
|
+
draw();
|
|
189
|
+
resolve(state.aborted ? null : pickedIds(state));
|
|
190
|
+
};
|
|
191
|
+
const onData = (buf) => {
|
|
192
|
+
const keys = keysOf(buf.toString('utf8'));
|
|
193
|
+
if (keys.length === 0)
|
|
194
|
+
return;
|
|
195
|
+
for (const key of keys) {
|
|
196
|
+
state = reducePicker(state, key);
|
|
197
|
+
if (state.done || state.aborted) {
|
|
198
|
+
finish(onData);
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
draw();
|
|
203
|
+
};
|
|
204
|
+
// A closed stdin (piped input that ran out) must not hang the prompt.
|
|
205
|
+
const onEnd = () => { state = { ...state, aborted: true }; finish(onData); };
|
|
206
|
+
stdin.on('data', onData);
|
|
207
|
+
stdin.on('end', onEnd);
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
finally {
|
|
211
|
+
stdin.setRawMode?.(wasRaw);
|
|
212
|
+
stdin.pause();
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Shown when there's no TTY to prompt on and no flag saying what to wire.
|
|
217
|
+
* Writing nothing is deliberate: a scripted run shouldn't get files for every
|
|
218
|
+
* agent the machine happens to have installed.
|
|
219
|
+
*/
|
|
220
|
+
export function formatNonInteractiveHelp(detectedIds) {
|
|
221
|
+
const list = detectedIds.length > 0 ? detectedIds.join(", ") : "none";
|
|
222
|
+
const examples = [
|
|
223
|
+
...(detectedIds.length > 0
|
|
224
|
+
? [
|
|
225
|
+
[`graft init --agents ${detectedIds.join(" ")}`, "wire these"],
|
|
226
|
+
["graft init --yes", "same, without spelling them out"],
|
|
227
|
+
]
|
|
228
|
+
: []),
|
|
229
|
+
["graft init --agents claude", "Claude Code only"],
|
|
230
|
+
["graft init --dry-run", "list every file first"],
|
|
231
|
+
];
|
|
232
|
+
const width = Math.max(...examples.map(([cmd]) => cmd.length));
|
|
233
|
+
return [
|
|
234
|
+
"graft init: no TTY to prompt on, and no --agents/--yes given — nothing written.",
|
|
235
|
+
`detected: ${list}`,
|
|
236
|
+
"",
|
|
237
|
+
...examples.map(([cmd, note]) => ` ${cmd.padEnd(width)} # ${note}`),
|
|
238
|
+
].join("\n");
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* `--dry-run` output: every path init would touch, repo writes first, then a
|
|
242
|
+
* separate section for anything outside the repo.
|
|
243
|
+
*/
|
|
244
|
+
export function formatPlan(plan, ids, repo, home, tty = Boolean(process.stderr.isTTY)) {
|
|
245
|
+
const dim = tty ? muted : (s) => s;
|
|
246
|
+
const warn = tty ? amber : (s) => s;
|
|
247
|
+
const writes = plan.filter((p) => ids.includes(p.id)).flatMap((p) => p.writes);
|
|
248
|
+
if (writes.length === 0)
|
|
249
|
+
return 'would write — nothing (no agents selected)';
|
|
250
|
+
const pad = (rows, f) => {
|
|
251
|
+
const w = Math.max(...rows.map((r) => f(r.path).length));
|
|
252
|
+
return rows.map((r) => ` ${f(r.path).padEnd(w)} ${dim(r.what)}`);
|
|
253
|
+
};
|
|
254
|
+
const lines = [];
|
|
255
|
+
const repoWrites = writes.filter((w) => w.scope === 'repo');
|
|
256
|
+
if (repoWrites.length > 0) {
|
|
257
|
+
lines.push('would write — this repo:', ...pad(repoWrites, (p) => relative(repo, p)));
|
|
258
|
+
}
|
|
259
|
+
const globalWrites = writes.filter((w) => w.scope === 'global');
|
|
260
|
+
if (globalWrites.length > 0) {
|
|
261
|
+
if (lines.length)
|
|
262
|
+
lines.push('');
|
|
263
|
+
lines.push(warn('would write — your machine, affects ALL repos:'), ...pad(globalWrites, (p) => tilde(p, home)), '', dim('suppress the out-of-repo writes with --no-global'));
|
|
264
|
+
}
|
|
265
|
+
lines.push('', dim('nothing was written (--dry-run)'));
|
|
266
|
+
return lines.join('\n');
|
|
267
|
+
}
|
|
268
|
+
//# sourceMappingURL=cli-picker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-picker.js","sourceRoot":"","sources":["../src/cli-picker.ts"],"names":[],"mappings":"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"}
|