ghostrail 0.2.0 → 0.4.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 +19 -0
- package/dist/agent/claude-code.d.ts.map +1 -1
- package/dist/agent/claude-code.js +11 -4
- package/dist/agent/claude-code.js.map +1 -1
- package/dist/backend/container.d.ts.map +1 -1
- package/dist/backend/container.js +24 -2
- package/dist/backend/container.js.map +1 -1
- package/dist/backend/docker.d.ts +6 -1
- package/dist/backend/docker.d.ts.map +1 -1
- package/dist/backend/docker.js +7 -2
- package/dist/backend/docker.js.map +1 -1
- package/dist/backend/local-worktree.d.ts.map +1 -1
- package/dist/backend/local-worktree.js +15 -2
- package/dist/backend/local-worktree.js.map +1 -1
- package/dist/backend/types.d.ts +14 -0
- package/dist/backend/types.d.ts.map +1 -1
- package/dist/cli/commands.d.ts +4 -3
- package/dist/cli/commands.d.ts.map +1 -1
- package/dist/cli/commands.js +116 -6
- package/dist/cli/commands.js.map +1 -1
- package/dist/commands/help.d.ts.map +1 -1
- package/dist/commands/help.js +5 -0
- package/dist/commands/help.js.map +1 -1
- package/dist/factory/build.d.ts.map +1 -1
- package/dist/factory/build.js +3 -0
- package/dist/factory/build.js.map +1 -1
- package/dist/init/template.d.ts +40 -0
- package/dist/init/template.d.ts.map +1 -0
- package/dist/init/template.js +89 -0
- package/dist/init/template.js.map +1 -0
- package/dist/loop/engine.d.ts +2 -0
- package/dist/loop/engine.d.ts.map +1 -1
- package/dist/loop/engine.js +1 -0
- package/dist/loop/engine.js.map +1 -1
- package/dist/respond/respond.d.ts +2 -0
- package/dist/respond/respond.d.ts.map +1 -1
- package/dist/respond/respond.js +1 -0
- package/dist/respond/respond.js.map +1 -1
- package/dist/triage/engine.d.ts +2 -0
- package/dist/triage/engine.d.ts.map +1 -1
- package/dist/triage/engine.js +1 -0
- package/dist/triage/engine.js.map +1 -1
- package/dist/vendor/skilltend/registry.d.ts.map +1 -1
- package/dist/vendor/skilltend/registry.js +351 -0
- package/dist/vendor/skilltend/registry.js.map +1 -1
- package/package.json +1 -1
- package/skill/ghostrail/SKILL.md +23 -1
package/README.md
CHANGED
|
@@ -46,6 +46,25 @@ ghostrail skill uninstall # remove it (never touches another product's skill)
|
|
|
46
46
|
ghostrail self-update # update the CLI, then its skill
|
|
47
47
|
```
|
|
48
48
|
|
|
49
|
+
## Keeping up with template changes
|
|
50
|
+
|
|
51
|
+
`ghostrail init` records what it scaffolded in `ghostrail.template.json`, so a
|
|
52
|
+
later release can tell a file *you* edited apart from one the *template* changed.
|
|
53
|
+
Commit that file with the repo.
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
ghostrail init code-local --diff # read-only: how do my files differ?
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Each scaffolded file reports as up to date, locally customized, safe to take
|
|
60
|
+
(the template moved, yours is untouched), a conflict (both moved), or missing.
|
|
61
|
+
For anything that needs a look it prints the exact `diff` command against the
|
|
62
|
+
shipped template. It never writes, so it is safe to run at any time.
|
|
63
|
+
|
|
64
|
+
Scaffolded before this existed? Re-run `ghostrail init` once. It adopts a
|
|
65
|
+
baseline for every file that still matches the template exactly, which leaves
|
|
66
|
+
only your genuinely edited files unknown.
|
|
67
|
+
|
|
49
68
|
`ghostrail artifacts` lists the shared references in your global store
|
|
50
69
|
(`~/.config/ghostrail/artifacts/`), staged into each run so the same voice and
|
|
51
70
|
rules apply across every factory instance.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claude-code.d.ts","sourceRoot":"","sources":["../../src/agent/claude-code.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAI1E,+EAA+E;AAC/E,eAAO,MAAM,WAAW,2BAA2B,CAAC;AAEpD,MAAM,WAAW,iBAAiB;IAChC,4EAA4E;IAC5E,MAAM,EAAE,MAAM,CAAC;IACf,4EAA4E;IAC5E,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;IAChC,8EAA8E;IAC9E,MAAM,EAAE,MAAM,CAAC;IACf,6CAA6C;IAC7C,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,aAAa,CAAC;IAC/C,sDAAsD;IACtD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,oCAAoC;IACpC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,2BAA2B;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kEAAkE;IAClE,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,iBAAiB,GAAG,MAAM,EAAE,CAwBpE;AAYD;;;;;;GAMG;AACH,qBAAa,eAAgB,YAAW,KAAK;IAO/B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC;IANxC;;;;;OAKG;gBAC0B,UAAU,CAAC,EAAE,MAAM,YAAA;IAE1C,GAAG,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"claude-code.d.ts","sourceRoot":"","sources":["../../src/agent/claude-code.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAI1E,+EAA+E;AAC/E,eAAO,MAAM,WAAW,2BAA2B,CAAC;AAEpD,MAAM,WAAW,iBAAiB;IAChC,4EAA4E;IAC5E,MAAM,EAAE,MAAM,CAAC;IACf,4EAA4E;IAC5E,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;IAChC,8EAA8E;IAC9E,MAAM,EAAE,MAAM,CAAC;IACf,6CAA6C;IAC7C,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,aAAa,CAAC;IAC/C,sDAAsD;IACtD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,oCAAoC;IACpC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,2BAA2B;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kEAAkE;IAClE,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,iBAAiB,GAAG,MAAM,EAAE,CAwBpE;AAYD;;;;;;GAMG;AACH,qBAAa,eAAgB,YAAW,KAAK;IAO/B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC;IANxC;;;;;OAKG;gBAC0B,UAAU,CAAC,EAAE,MAAM,YAAA;IAE1C,GAAG,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;CA4CxD"}
|
|
@@ -59,6 +59,13 @@ export class ClaudeCodeAgent {
|
|
|
59
59
|
}
|
|
60
60
|
async run(context) {
|
|
61
61
|
const { backend, workspace, item, agent, guardrails } = context;
|
|
62
|
+
// Precedence matters. `workspace.profilePath` is the path in the BACKEND's
|
|
63
|
+
// address space — the host dir for local-worktree, an in-container dir for
|
|
64
|
+
// container — so it always wins. The constructor's host path is only a
|
|
65
|
+
// fallback for a backend that shares the host filesystem and reports no
|
|
66
|
+
// path; on an isolating backend it would point at nothing, which is why a
|
|
67
|
+
// backend that stages a profile must report where it put it.
|
|
68
|
+
const profileDir = workspace.profilePath ?? this.profileDir;
|
|
62
69
|
const template = await readFile(backend, workspace, agent.prompt);
|
|
63
70
|
if (template === undefined) {
|
|
64
71
|
return { status: "failed", error: `could not read prompt file: ${agent.prompt}` };
|
|
@@ -68,15 +75,15 @@ export class ClaudeCodeAgent {
|
|
|
68
75
|
allowedTools: agent.allowedTools,
|
|
69
76
|
addDir: ".",
|
|
70
77
|
maxBudgetUsd: guardrails.budgetUsdPerItem,
|
|
71
|
-
...(
|
|
78
|
+
...(profileDir === undefined
|
|
72
79
|
? {}
|
|
73
|
-
: { settingsPath: join(
|
|
80
|
+
: { settingsPath: join(profileDir, ".claude", "settings.json") }),
|
|
74
81
|
});
|
|
75
82
|
const run = await backend.exec(workspace, ["claude", ...args], {
|
|
76
83
|
timeoutMs: guardrails.timeoutMs,
|
|
77
|
-
...(
|
|
84
|
+
...(profileDir === undefined
|
|
78
85
|
? {}
|
|
79
|
-
: { env: { HOME:
|
|
86
|
+
: { env: { HOME: profileDir, CLAUDE_CONFIG_DIR: join(profileDir, ".claude") } }),
|
|
80
87
|
});
|
|
81
88
|
if (run.timedOut) {
|
|
82
89
|
return { status: "failed", error: "agent timed out" };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claude-code.js","sourceRoot":"","sources":["../../src/agent/claude-code.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAIjC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAE/C,+EAA+E;AAC/E,MAAM,CAAC,MAAM,WAAW,GAAG,wBAAwB,CAAC;AAqBpD;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,OAA0B;IACxD,MAAM,IAAI,GAAG;QACX,IAAI;QACJ,OAAO,CAAC,MAAM;QACd,iBAAiB;QACjB,OAAO,CAAC,YAAY,IAAI,MAAM;QAC9B,mBAAmB;QACnB,OAAO,CAAC,cAAc,IAAI,aAAa;QACvC,WAAW;QACX,OAAO,CAAC,MAAM;KACf,CAAC;IACF,IAAI,OAAO,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;QACvC,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;IAChD,CAAC;IACD,IAAI,OAAO,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACpC,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IAC9D,CAAC;IACD,IAAI,OAAO,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;QACvC,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC;IAC9D,CAAC;IACD,IAAI,OAAO,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;QAChC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;IACtC,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,iFAAiF;AACjF,KAAK,UAAU,QAAQ,CACrB,OAAgB,EAChB,SAAoB,EACpB,IAAY;IAEZ,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC;IAC5D,OAAO,MAAM,CAAC,QAAQ,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;AAC3D,CAAC;AAED;;;;;;GAMG;AACH,MAAM,OAAO,eAAe;IAOG;IAN7B;;;;;OAKG;IACH,YAA6B,UAAmB;QAAnB,eAAU,GAAV,UAAU,CAAS;IAAG,CAAC;IAEpD,KAAK,CAAC,GAAG,CAAC,OAAqB;QAC7B,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"claude-code.js","sourceRoot":"","sources":["../../src/agent/claude-code.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"container.d.ts","sourceRoot":"","sources":["../../src/backend/container.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"container.d.ts","sourceRoot":"","sources":["../../src/backend/container.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EACV,OAAO,EACP,WAAW,EACX,UAAU,EACV,OAAO,EACP,aAAa,EACb,SAAS,EACV,MAAM,YAAY,CAAC;AAQpB;;;;;;GAMG;AACH,MAAM,WAAW,uBAAuB;IACtC;;;;;OAKG;IACH,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/B,uEAAuE;IACvE,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;CAC1C;AAED,qBAAa,gBAAiB,YAAW,OAAO;IAC9C,QAAQ,CAAC,IAAI,eAAQ;IACrB,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAoB;IAC/C,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAqC;gBAE7C,OAAO,GAAE,uBAA4B;IAKjD,wEAAwE;IACxE,OAAO,CAAC,YAAY;IASpB,yDAAyD;IACzD,OAAO,CAAC,gBAAgB;IAMxB,uDAAuD;WAC1C,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAKtC,SAAS,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,SAAS,CAAC;IAgExD,IAAI,CACF,SAAS,EAAE,SAAS,EACpB,OAAO,EAAE,SAAS,MAAM,EAAE,EAC1B,OAAO,GAAE,WAAgB,GACxB,OAAO,CAAC,UAAU,CAAC;IAKtB,MAAM,CACJ,SAAS,EAAE,SAAS,EACpB,OAAO,EAAE,SAAS,MAAM,EAAE,EAC1B,KAAK,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,EAC9B,OAAO,GAAE,WAAgB,GACxB,OAAO,CAAC,UAAU,CAAC;IAShB,QAAQ,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;CAGpD"}
|
|
@@ -3,7 +3,7 @@ import { mkdir, rm } from "node:fs/promises";
|
|
|
3
3
|
import { tmpdir } from "node:os";
|
|
4
4
|
import { join } from "node:path";
|
|
5
5
|
import process from "node:process";
|
|
6
|
-
import { DEFAULT_CONTAINER_IMAGE, dockerCpArgs, dockerExecArgs, dockerRmArgs, dockerRunArgs, } from "./docker.js";
|
|
6
|
+
import { CONTAINER_PROFILE_DIR, DEFAULT_CONTAINER_IMAGE, dockerCpArgs, dockerExecArgs, dockerRmArgs, dockerRunArgs, } from "./docker.js";
|
|
7
7
|
import { CLONE_TOKEN_ENV, cloneCredentialArgs } from "./git-credentials.js";
|
|
8
8
|
import { spawnCollect } from "./proc.js";
|
|
9
9
|
const KIND = "container";
|
|
@@ -68,7 +68,29 @@ export class ContainerBackend {
|
|
|
68
68
|
await docker(dockerRmArgs(name));
|
|
69
69
|
throw new Error(`docker cp failed: ${cp.stderr.trim()}`);
|
|
70
70
|
}
|
|
71
|
-
|
|
71
|
+
// The container shares no filesystem with the host, so a profile has to be
|
|
72
|
+
// copied in; the agent then points HOME at the in-container path.
|
|
73
|
+
let profilePath;
|
|
74
|
+
if (spec.profileDir !== undefined) {
|
|
75
|
+
const mk = await docker(dockerExecArgs(name, ["mkdir", "-p", CONTAINER_PROFILE_DIR], {}));
|
|
76
|
+
if (mk.exitCode !== 0) {
|
|
77
|
+
await docker(dockerRmArgs(name));
|
|
78
|
+
throw new Error(`profile mkdir failed: ${mk.stderr.trim()}`);
|
|
79
|
+
}
|
|
80
|
+
const cpProfile = await docker(dockerCpArgs(`${spec.profileDir}/.`, name, CONTAINER_PROFILE_DIR));
|
|
81
|
+
if (cpProfile.exitCode !== 0) {
|
|
82
|
+
await docker(dockerRmArgs(name));
|
|
83
|
+
throw new Error(`profile copy failed: ${cpProfile.stderr.trim()}`);
|
|
84
|
+
}
|
|
85
|
+
profilePath = CONTAINER_PROFILE_DIR;
|
|
86
|
+
}
|
|
87
|
+
return {
|
|
88
|
+
id,
|
|
89
|
+
backend: KIND,
|
|
90
|
+
ref: name,
|
|
91
|
+
branch: spec.branch,
|
|
92
|
+
...(profilePath === undefined ? {} : { profilePath }),
|
|
93
|
+
};
|
|
72
94
|
}
|
|
73
95
|
finally {
|
|
74
96
|
await rm(hostClone, { recursive: true, force: true });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"container.js","sourceRoot":"","sources":["../../src/backend/container.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"container.js","sourceRoot":"","sources":["../../src/backend/container.ts"],"names":[],"mappings":"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"}
|
package/dist/backend/docker.d.ts
CHANGED
|
@@ -3,6 +3,11 @@ import type { ExecOptions } from "./types.js";
|
|
|
3
3
|
export declare const DEFAULT_CONTAINER_IMAGE = "alpine:3";
|
|
4
4
|
/** Working directory inside every container. */
|
|
5
5
|
export declare const CONTAINER_WORKDIR = "/work";
|
|
6
|
+
/**
|
|
7
|
+
* Where a staged Claude profile lands inside the container. Deliberately outside
|
|
8
|
+
* {@link CONTAINER_WORKDIR} so it is never part of the repo the agent commits.
|
|
9
|
+
*/
|
|
10
|
+
export declare const CONTAINER_PROFILE_DIR = "/ghostrail-profile";
|
|
6
11
|
/**
|
|
7
12
|
* Build `docker run` args for a long-lived, detached container that idles until
|
|
8
13
|
* torn down. The container is named `name`, works out of {@link CONTAINER_WORKDIR},
|
|
@@ -16,7 +21,7 @@ export declare function dockerRunArgs(name: string, image: string): string[];
|
|
|
16
21
|
*/
|
|
17
22
|
export declare function dockerExecArgs(name: string, command: readonly string[], options?: ExecOptions): string[];
|
|
18
23
|
/** Build `docker cp` args to copy host `source` into `name`'s work dir. */
|
|
19
|
-
export declare function dockerCpArgs(source: string, name: string): string[];
|
|
24
|
+
export declare function dockerCpArgs(source: string, name: string, dest?: string): string[];
|
|
20
25
|
/** Build `docker rm -f` args to force-remove container `name`. */
|
|
21
26
|
export declare function dockerRmArgs(name: string): string[];
|
|
22
27
|
//# sourceMappingURL=docker.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"docker.d.ts","sourceRoot":"","sources":["../../src/backend/docker.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,iEAAiE;AACjE,eAAO,MAAM,uBAAuB,aAAa,CAAC;AAElD,gDAAgD;AAChD,eAAO,MAAM,iBAAiB,UAAU,CAAC;AAEzC;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAEnE;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,SAAS,MAAM,EAAE,EAC1B,OAAO,GAAE,WAAgB,GACxB,MAAM,EAAE,CAYV;AAED,2EAA2E;AAC3E,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"docker.d.ts","sourceRoot":"","sources":["../../src/backend/docker.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,iEAAiE;AACjE,eAAO,MAAM,uBAAuB,aAAa,CAAC;AAElD,gDAAgD;AAChD,eAAO,MAAM,iBAAiB,UAAU,CAAC;AAEzC;;;GAGG;AACH,eAAO,MAAM,qBAAqB,uBAAuB,CAAC;AAE1D;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAEnE;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,SAAS,MAAM,EAAE,EAC1B,OAAO,GAAE,WAAgB,GACxB,MAAM,EAAE,CAYV;AAED,2EAA2E;AAC3E,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,SAAoB,GAAG,MAAM,EAAE,CAE7F;AAED,kEAAkE;AAClE,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAEnD"}
|
package/dist/backend/docker.js
CHANGED
|
@@ -2,6 +2,11 @@
|
|
|
2
2
|
export const DEFAULT_CONTAINER_IMAGE = "alpine:3";
|
|
3
3
|
/** Working directory inside every container. */
|
|
4
4
|
export const CONTAINER_WORKDIR = "/work";
|
|
5
|
+
/**
|
|
6
|
+
* Where a staged Claude profile lands inside the container. Deliberately outside
|
|
7
|
+
* {@link CONTAINER_WORKDIR} so it is never part of the repo the agent commits.
|
|
8
|
+
*/
|
|
9
|
+
export const CONTAINER_PROFILE_DIR = "/ghostrail-profile";
|
|
5
10
|
/**
|
|
6
11
|
* Build `docker run` args for a long-lived, detached container that idles until
|
|
7
12
|
* torn down. The container is named `name`, works out of {@link CONTAINER_WORKDIR},
|
|
@@ -28,8 +33,8 @@ export function dockerExecArgs(name, command, options = {}) {
|
|
|
28
33
|
return args;
|
|
29
34
|
}
|
|
30
35
|
/** Build `docker cp` args to copy host `source` into `name`'s work dir. */
|
|
31
|
-
export function dockerCpArgs(source, name) {
|
|
32
|
-
return ["cp", source, `${name}:${
|
|
36
|
+
export function dockerCpArgs(source, name, dest = CONTAINER_WORKDIR) {
|
|
37
|
+
return ["cp", source, `${name}:${dest}`];
|
|
33
38
|
}
|
|
34
39
|
/** Build `docker rm -f` args to force-remove container `name`. */
|
|
35
40
|
export function dockerRmArgs(name) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"docker.js","sourceRoot":"","sources":["../../src/backend/docker.ts"],"names":[],"mappings":"AAEA,iEAAiE;AACjE,MAAM,CAAC,MAAM,uBAAuB,GAAG,UAAU,CAAC;AAElD,gDAAgD;AAChD,MAAM,CAAC,MAAM,iBAAiB,GAAG,OAAO,CAAC;AAEzC;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,IAAY,EAAE,KAAa;IACvD,OAAO,CAAC,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,iBAAiB,EAAE,KAAK,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC;AAC5F,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAC5B,IAAY,EACZ,OAA0B,EAC1B,UAAuB,EAAE;IAEzB,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC;IACtB,MAAM,OAAO,GACX,OAAO,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,iBAAiB,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,iBAAiB,CAAC;IACxF,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACzB,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;QAChB,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;YACvD,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,GAAG,IAAI,KAAK,EAAE,CAAC,CAAC;QACrC,CAAC;IACH,CAAC;IACD,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,OAAO,CAAC,CAAC;IAC5B,OAAO,IAAI,CAAC;AACd,CAAC;AAED,2EAA2E;AAC3E,MAAM,UAAU,YAAY,CAAC,MAAc,EAAE,IAAY;
|
|
1
|
+
{"version":3,"file":"docker.js","sourceRoot":"","sources":["../../src/backend/docker.ts"],"names":[],"mappings":"AAEA,iEAAiE;AACjE,MAAM,CAAC,MAAM,uBAAuB,GAAG,UAAU,CAAC;AAElD,gDAAgD;AAChD,MAAM,CAAC,MAAM,iBAAiB,GAAG,OAAO,CAAC;AAEzC;;;GAGG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,oBAAoB,CAAC;AAE1D;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,IAAY,EAAE,KAAa;IACvD,OAAO,CAAC,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,iBAAiB,EAAE,KAAK,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC;AAC5F,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAC5B,IAAY,EACZ,OAA0B,EAC1B,UAAuB,EAAE;IAEzB,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC;IACtB,MAAM,OAAO,GACX,OAAO,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,iBAAiB,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,iBAAiB,CAAC;IACxF,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACzB,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;QAChB,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;YACvD,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,GAAG,IAAI,KAAK,EAAE,CAAC,CAAC;QACrC,CAAC;IACH,CAAC;IACD,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,OAAO,CAAC,CAAC;IAC5B,OAAO,IAAI,CAAC;AACd,CAAC;AAED,2EAA2E;AAC3E,MAAM,UAAU,YAAY,CAAC,MAAc,EAAE,IAAY,EAAE,IAAI,GAAG,iBAAiB;IACjF,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,IAAI,IAAI,EAAE,CAAC,CAAC;AAC3C,CAAC;AAED,kEAAkE;AAClE,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AAC5B,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"local-worktree.d.ts","sourceRoot":"","sources":["../../src/backend/local-worktree.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EACV,OAAO,EACP,WAAW,EACX,UAAU,EACV,OAAO,EACP,aAAa,EACb,SAAS,EACV,MAAM,YAAY,CAAC;AAIpB;;;;GAIG;AACH,qBAAa,oBAAqB,YAAW,OAAO;IAClD,QAAQ,CAAC,IAAI,oBAAQ;IACrB,4EAA4E;IAC5E,OAAO,CAAC,QAAQ,CAAC,eAAe,CAA6B;IAEvD,SAAS,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"local-worktree.d.ts","sourceRoot":"","sources":["../../src/backend/local-worktree.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EACV,OAAO,EACP,WAAW,EACX,UAAU,EACV,OAAO,EACP,aAAa,EACb,SAAS,EACV,MAAM,YAAY,CAAC;AAIpB;;;;GAIG;AACH,qBAAa,oBAAqB,YAAW,OAAO;IAClD,QAAQ,CAAC,IAAI,oBAAQ;IACrB,4EAA4E;IAC5E,OAAO,CAAC,QAAQ,CAAC,eAAe,CAA6B;IAEvD,SAAS,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,SAAS,CAAC;IA4DxD,IAAI,CACF,SAAS,EAAE,SAAS,EACpB,OAAO,EAAE,SAAS,MAAM,EAAE,EAC1B,OAAO,GAAE,WAAgB,GACxB,OAAO,CAAC,UAAU,CAAC;IAItB,MAAM,CACJ,SAAS,EAAE,SAAS,EACpB,OAAO,EAAE,SAAS,MAAM,EAAE,EAC1B,KAAK,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,EAC9B,OAAO,GAAE,WAAgB,GACxB,OAAO,CAAC,UAAU,CAAC;IAIhB,QAAQ,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAUnD,OAAO,CAAC,WAAW;CAIpB"}
|
|
@@ -36,7 +36,13 @@ export class LocalWorktreeBackend {
|
|
|
36
36
|
await rm(dir, { recursive: true, force: true });
|
|
37
37
|
throw new Error(`local-clone checkout failed: ${checkout.stderr.trim()}`);
|
|
38
38
|
}
|
|
39
|
-
return {
|
|
39
|
+
return {
|
|
40
|
+
id,
|
|
41
|
+
backend: KIND,
|
|
42
|
+
ref: dir,
|
|
43
|
+
branch: spec.branch,
|
|
44
|
+
...(spec.profileDir === undefined ? {} : { profilePath: spec.profileDir }),
|
|
45
|
+
};
|
|
40
46
|
}
|
|
41
47
|
// "create" makes a new branch off the base; "attach" checks out an existing branch.
|
|
42
48
|
const addArgs = spec.mode === "attach"
|
|
@@ -47,7 +53,14 @@ export class LocalWorktreeBackend {
|
|
|
47
53
|
throw new Error(`local-worktree provision failed: ${result.stderr.trim() || result.stdout.trim()}`);
|
|
48
54
|
}
|
|
49
55
|
this.repoByWorkspace.set(id, spec.repoPath);
|
|
50
|
-
|
|
56
|
+
// The agent runs on this host, so the profile is already reachable in place.
|
|
57
|
+
return {
|
|
58
|
+
id,
|
|
59
|
+
backend: KIND,
|
|
60
|
+
ref: dir,
|
|
61
|
+
branch: spec.branch,
|
|
62
|
+
...(spec.profileDir === undefined ? {} : { profilePath: spec.profileDir }),
|
|
63
|
+
};
|
|
51
64
|
}
|
|
52
65
|
exec(workspace, command, options = {}) {
|
|
53
66
|
return spawnCollect(command, this.execOptions(workspace, options));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"local-worktree.js","sourceRoot":"","sources":["../../src/backend/local-worktree.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,OAAO,MAAM,cAAc,CAAC;AACnC,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC5E,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAUzC,MAAM,IAAI,GAAG,gBAAgB,CAAC;AAE9B;;;;GAIG;AACH,MAAM,OAAO,oBAAoB;IACtB,IAAI,GAAG,IAAI,CAAC;IACrB,4EAA4E;IAC3D,eAAe,GAAG,IAAI,GAAG,EAAkB,CAAC;IAE7D,KAAK,CAAC,SAAS,CAAC,IAAmB;QACjC,MAAM,EAAE,GAAG,UAAU,EAAE,CAAC;QACxB,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,EAAE,cAAc,EAAE,EAAE,CAAC,CAAC;QAC/C,MAAM,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,cAAc,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAEjE,IAAI,IAAI,CAAC,KAAK,KAAK,IAAI,EAAE,CAAC;YACxB,+EAA+E;YAC/E,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC;YAC/D,MAAM,QAAQ,GAAG,mBAAmB,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,KAAK,SAAS,CAAC,CAAC;YACzE,MAAM,SAAS,GAAG,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC,eAAe,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC;YACnF,MAAM,KAAK,GAAG,MAAM,YAAY,CAC9B,CAAC,KAAK,EAAE,GAAG,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,EAC5D,SAAS,CACV,CAAC;YACF,IAAI,KAAK,CAAC,QAAQ,KAAK,CAAC,EAAE,CAAC;gBACzB,MAAM,IAAI,KAAK,CACb,iCAAiC,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAC9E,CAAC;YACJ,CAAC;YACD,MAAM,YAAY,GAChB,IAAI,CAAC,IAAI,KAAK,QAAQ;gBACpB,CAAC,CAAC,CAAC,UAAU,EAAE,IAAI,CAAC,MAAM,CAAC;gBAC3B,CAAC,CAAC,CAAC,UAAU,EAAE,IAAI,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;YACvD,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,YAAY,CAAC,CAAC,CAAC;YACzE,IAAI,QAAQ,CAAC,QAAQ,KAAK,CAAC,EAAE,CAAC;gBAC5B,MAAM,EAAE,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;gBAChD,MAAM,IAAI,KAAK,CAAC,gCAAgC,QAAQ,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YAC5E,CAAC;YACD,OAAO,EAAE,EAAE,EAAE,
|
|
1
|
+
{"version":3,"file":"local-worktree.js","sourceRoot":"","sources":["../../src/backend/local-worktree.ts"],"names":[],"mappings":"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"}
|
package/dist/backend/types.d.ts
CHANGED
|
@@ -34,6 +34,13 @@ export interface ProvisionSpec {
|
|
|
34
34
|
clone?: boolean;
|
|
35
35
|
/** Container image, for backends that need one. Ignored by local-worktree. */
|
|
36
36
|
image?: string;
|
|
37
|
+
/**
|
|
38
|
+
* Host path to a composed Claude profile to make available to the run. A
|
|
39
|
+
* backend that isolates the filesystem must copy it in; one that shares the
|
|
40
|
+
* host filesystem can use it where it is. Either way the resulting
|
|
41
|
+
* backend-local path comes back as {@link Workspace.profilePath}.
|
|
42
|
+
*/
|
|
43
|
+
profileDir?: string;
|
|
37
44
|
}
|
|
38
45
|
/** A provisioned, isolated working copy. Opaque handle addressed by `ref`. */
|
|
39
46
|
export interface Workspace {
|
|
@@ -48,6 +55,13 @@ export interface Workspace {
|
|
|
48
55
|
ref: string;
|
|
49
56
|
/** The branch the work happens on. */
|
|
50
57
|
branch: string;
|
|
58
|
+
/**
|
|
59
|
+
* Where {@link ProvisionSpec.profileDir} ended up, expressed in the backend's
|
|
60
|
+
* own address space: the host path for local-worktree, a path inside the
|
|
61
|
+
* container for container. Undefined when no profile was requested. The agent
|
|
62
|
+
* must use this rather than the host path, which may not exist in the backend.
|
|
63
|
+
*/
|
|
64
|
+
profilePath?: string;
|
|
51
65
|
}
|
|
52
66
|
export interface ExecOptions {
|
|
53
67
|
/** Directory to run in, relative to the workspace root. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/backend/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,wDAAwD;AACxD,MAAM,WAAW,aAAa;IAC5B;;;OAGG;IACH,QAAQ,EAAE,MAAM,CAAC;IACjB,kFAAkF;IAClF,UAAU,EAAE,MAAM,CAAC;IACnB,yFAAyF;IACzF,MAAM,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,IAAI,CAAC,EAAE,QAAQ,GAAG,QAAQ,CAAC;IAC3B;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,8EAA8E;IAC9E,KAAK,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/backend/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,wDAAwD;AACxD,MAAM,WAAW,aAAa;IAC5B;;;OAGG;IACH,QAAQ,EAAE,MAAM,CAAC;IACjB,kFAAkF;IAClF,UAAU,EAAE,MAAM,CAAC;IACnB,yFAAyF;IACzF,MAAM,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,IAAI,CAAC,EAAE,QAAQ,GAAG,QAAQ,CAAC;IAC3B;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,8EAA8E;IAC9E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;;OAKG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,8EAA8E;AAC9E,MAAM,WAAW,SAAS;IACxB,uCAAuC;IACvC,EAAE,EAAE,MAAM,CAAC;IACX,yCAAyC;IACzC,OAAO,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,GAAG,EAAE,MAAM,CAAC;IACZ,sCAAsC;IACtC,MAAM,EAAE,MAAM,CAAC;IACf;;;;;OAKG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,WAAW;IAC1B,2DAA2D;IAC3D,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,mDAAmD;IACnD,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,wEAAwE;IACxE,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,2EAA2E;AAC3E,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,kEAAkE;IAClE,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,2CAA2C;AAC3C,MAAM,WAAW,OAAO;IACtB,MAAM,EAAE,QAAQ,GAAG,QAAQ,CAAC;IAC5B,IAAI,EAAE,MAAM,CAAC;CACd;AAED,qCAAqC;AACrC,MAAM,WAAW,OAAO;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,iFAAiF;IACjF,SAAS,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IACnD,0EAA0E;IAC1E,IAAI,CACF,SAAS,EAAE,SAAS,EACpB,OAAO,EAAE,SAAS,MAAM,EAAE,EAC1B,OAAO,CAAC,EAAE,WAAW,GACpB,OAAO,CAAC,UAAU,CAAC,CAAC;IACvB,yFAAyF;IACzF,MAAM,CACJ,SAAS,EAAE,SAAS,EACpB,OAAO,EAAE,SAAS,MAAM,EAAE,EAC1B,KAAK,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,EAC9B,OAAO,CAAC,EAAE,WAAW,GACpB,OAAO,CAAC,UAAU,CAAC,CAAC;IACvB,qFAAqF;IACrF,QAAQ,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/C"}
|
package/dist/cli/commands.d.ts
CHANGED
|
@@ -49,9 +49,10 @@ export declare function cmdArtifacts(argv: readonly string[], streams: CommandSt
|
|
|
49
49
|
/** The quickstart templates bundled with the package. */
|
|
50
50
|
export declare const TEMPLATES: readonly ["code-local", "content-loop"];
|
|
51
51
|
/**
|
|
52
|
-
* `ghostrail init <template> [--repo <path>] [--force]`: scaffold
|
|
53
|
-
* and `prompts/` from a quickstart template. Safe for a fresh OR
|
|
54
|
-
* existing files are left untouched (skipped) unless `--force`
|
|
52
|
+
* `ghostrail init <template> [--repo <path>] [--force|--diff]`: scaffold
|
|
53
|
+
* `ghostrail.toml` and `prompts/` from a quickstart template. Safe for a fresh OR
|
|
54
|
+
* an existing repo: existing files are left untouched (skipped) unless `--force`
|
|
55
|
+
* is given. `--diff` reports drift instead of writing anything.
|
|
55
56
|
*/
|
|
56
57
|
export declare function cmdInit(argv: readonly string[], streams: CommandStreams, cwd?: string): Promise<number>;
|
|
57
58
|
interface SkillFlags {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../src/cli/commands.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../src/cli/commands.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/commands.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { access,
|
|
1
|
+
import { access, mkdir, readFile, readdir, stat, writeFile } from "node:fs/promises";
|
|
2
2
|
import { homedir } from "node:os";
|
|
3
3
|
import { dirname, isAbsolute, join, sep } from "node:path";
|
|
4
4
|
import process from "node:process";
|
|
@@ -10,6 +10,7 @@ import { parseDuration } from "../config/duration.js";
|
|
|
10
10
|
import { parseMergedConfig } from "../config/load.js";
|
|
11
11
|
import { STORE_DIR, buildLoopDeps, buildRespondDeps, buildTriageDeps, resolveRepoSlug, } from "../factory/build.js";
|
|
12
12
|
import { GlobalStore, resolveGlobalDir } from "../global/store.js";
|
|
13
|
+
import { classify, hashContent, mergeManifest, readManifest, writeManifest, } from "../init/template.js";
|
|
13
14
|
import { FileLock } from "../lock/file-lock.js";
|
|
14
15
|
import { runTick } from "../loop/engine.js";
|
|
15
16
|
import { watchLoop } from "../loop/watch.js";
|
|
@@ -357,15 +358,87 @@ async function scaffoldFiles(srcDir) {
|
|
|
357
358
|
}
|
|
358
359
|
return wanted;
|
|
359
360
|
}
|
|
361
|
+
/** Manifest keys are always posix-separated so a manifest is portable. */
|
|
362
|
+
function manifestKey(rel) {
|
|
363
|
+
return rel.split(sep).join("/");
|
|
364
|
+
}
|
|
365
|
+
/** Read a file's content, or undefined if it is not there. */
|
|
366
|
+
async function readIfPresent(path) {
|
|
367
|
+
try {
|
|
368
|
+
return await readFile(path, "utf8");
|
|
369
|
+
}
|
|
370
|
+
catch {
|
|
371
|
+
return undefined;
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
/** Human-readable label per status, plus whether the file wants a look. */
|
|
375
|
+
const STATUS_LABEL = {
|
|
376
|
+
missing: "missing (the template has it, this repo does not)",
|
|
377
|
+
"up-to-date": "up to date",
|
|
378
|
+
"unknown-baseline": "differs (no recorded baseline)",
|
|
379
|
+
"upstream-changed": "template changed, yours is untouched (safe to take)",
|
|
380
|
+
"locally-modified": "locally customized, template unchanged",
|
|
381
|
+
conflict: "conflict (you and the template both changed it)",
|
|
382
|
+
};
|
|
383
|
+
/**
|
|
384
|
+
* `ghostrail init <template> --diff`: report how each scaffolded file stands
|
|
385
|
+
* against the template shipped with this CLI. Strictly read-only, including the
|
|
386
|
+
* manifest, so it is safe to run at any time.
|
|
387
|
+
*/
|
|
388
|
+
async function reportTemplateDiff(template, srcDir, repo, streams) {
|
|
389
|
+
const manifest = await readManifest(repo);
|
|
390
|
+
const rels = await scaffoldFiles(srcDir);
|
|
391
|
+
const rows = [];
|
|
392
|
+
let known = 0;
|
|
393
|
+
for (const rel of rels) {
|
|
394
|
+
const key = manifestKey(rel);
|
|
395
|
+
const templateContent = await readFile(join(srcDir, rel), "utf8");
|
|
396
|
+
const current = await readIfPresent(join(repo, rel));
|
|
397
|
+
const baseline = manifest?.files[key];
|
|
398
|
+
if (baseline !== undefined)
|
|
399
|
+
known++;
|
|
400
|
+
rows.push({
|
|
401
|
+
rel: key,
|
|
402
|
+
status: classify(current === undefined ? undefined : hashContent(current), hashContent(templateContent), baseline),
|
|
403
|
+
});
|
|
404
|
+
}
|
|
405
|
+
// A manifest with no baselines for these files tells us nothing, so do not
|
|
406
|
+
// present it as provenance just because the file exists.
|
|
407
|
+
const from = known === 0 || manifest === undefined
|
|
408
|
+
? "no recorded baseline, so local edits cannot be told apart from template changes"
|
|
409
|
+
: `scaffolded from ${manifest.template} @ ${manifest.version}`;
|
|
410
|
+
streams.out(`${template} vs ${repo} (${from})\n\n`);
|
|
411
|
+
const width = Math.max(...rows.map((row) => row.rel.length));
|
|
412
|
+
for (const row of rows) {
|
|
413
|
+
streams.out(` ${row.rel.padEnd(width)} ${STATUS_LABEL[row.status]}\n`);
|
|
414
|
+
}
|
|
415
|
+
const review = rows.filter((row) => row.status !== "up-to-date");
|
|
416
|
+
if (review.length === 0) {
|
|
417
|
+
streams.out(`\neverything matches the template shipped with ghostrail ${VERSION}\n`);
|
|
418
|
+
return 0;
|
|
419
|
+
}
|
|
420
|
+
streams.out("\ndiff against the shipped template to see what changed:\n");
|
|
421
|
+
for (const row of review) {
|
|
422
|
+
streams.out(` diff -u ${join(repo, row.rel)} ${join(srcDir, row.rel)}\n`);
|
|
423
|
+
}
|
|
424
|
+
if (known === 0) {
|
|
425
|
+
streams.out("\nno baselines recorded for this repo, so the statuses above cannot tell a\n" +
|
|
426
|
+
"local edit from a template change. `ghostrail init` (without --diff) adopts\n" +
|
|
427
|
+
"a baseline for every file that still matches the template exactly.\n");
|
|
428
|
+
}
|
|
429
|
+
return 0;
|
|
430
|
+
}
|
|
360
431
|
/**
|
|
361
|
-
* `ghostrail init <template> [--repo <path>] [--force]`: scaffold
|
|
362
|
-
* and `prompts/` from a quickstart template. Safe for a fresh OR
|
|
363
|
-
* existing files are left untouched (skipped) unless `--force`
|
|
432
|
+
* `ghostrail init <template> [--repo <path>] [--force|--diff]`: scaffold
|
|
433
|
+
* `ghostrail.toml` and `prompts/` from a quickstart template. Safe for a fresh OR
|
|
434
|
+
* an existing repo: existing files are left untouched (skipped) unless `--force`
|
|
435
|
+
* is given. `--diff` reports drift instead of writing anything.
|
|
364
436
|
*/
|
|
365
437
|
export async function cmdInit(argv, streams, cwd = process.cwd()) {
|
|
366
438
|
let template;
|
|
367
439
|
let repo = cwd;
|
|
368
440
|
let force = false;
|
|
441
|
+
let diff = false;
|
|
369
442
|
for (let i = 0; i < argv.length; i++) {
|
|
370
443
|
const arg = argv[i];
|
|
371
444
|
const next = argv[i + 1];
|
|
@@ -376,28 +449,65 @@ export async function cmdInit(argv, streams, cwd = process.cwd()) {
|
|
|
376
449
|
else if (arg === "--force" || arg === "-f") {
|
|
377
450
|
force = true;
|
|
378
451
|
}
|
|
452
|
+
else if (arg === "--diff") {
|
|
453
|
+
diff = true;
|
|
454
|
+
}
|
|
379
455
|
else if (arg !== undefined && !arg.startsWith("-")) {
|
|
380
456
|
template ??= arg;
|
|
381
457
|
}
|
|
382
458
|
}
|
|
383
459
|
if (template === undefined || !TEMPLATES.includes(template)) {
|
|
384
|
-
streams.err(`usage: ghostrail init <template> [--repo <path>] [--force]\ntemplates: ${TEMPLATES.join(", ")}\n`);
|
|
460
|
+
streams.err(`usage: ghostrail init <template> [--repo <path>] [--force|--diff]\ntemplates: ${TEMPLATES.join(", ")}\n`);
|
|
461
|
+
return 1;
|
|
462
|
+
}
|
|
463
|
+
if (diff && force) {
|
|
464
|
+
streams.err("init: --diff is read-only and cannot be combined with --force\n");
|
|
385
465
|
return 1;
|
|
386
466
|
}
|
|
387
467
|
const srcDir = join(templatesDir(), template);
|
|
468
|
+
if (diff) {
|
|
469
|
+
try {
|
|
470
|
+
return await reportTemplateDiff(template, srcDir, repo, streams);
|
|
471
|
+
}
|
|
472
|
+
catch (error) {
|
|
473
|
+
streams.err(`init --diff failed: ${error instanceof Error ? error.message : String(error)}\n`);
|
|
474
|
+
return 1;
|
|
475
|
+
}
|
|
476
|
+
}
|
|
388
477
|
const written = [];
|
|
389
478
|
const skipped = [];
|
|
479
|
+
// Baselines for the files this run actually wrote. A skipped file gets no
|
|
480
|
+
// entry: we do not know what it was scaffolded from, and recording the user's
|
|
481
|
+
// current content would later read as "never edited", which is worse than
|
|
482
|
+
// admitting the baseline is unknown.
|
|
483
|
+
const baselines = {};
|
|
390
484
|
try {
|
|
485
|
+
const existing = await readManifest(repo);
|
|
391
486
|
for (const rel of await scaffoldFiles(srcDir)) {
|
|
487
|
+
const key = manifestKey(rel);
|
|
392
488
|
const to = join(repo, rel);
|
|
489
|
+
const content = await readFile(join(srcDir, rel), "utf8");
|
|
490
|
+
const templateHash = hashContent(content);
|
|
393
491
|
if (!force && (await pathExists(to))) {
|
|
394
492
|
skipped.push(rel);
|
|
493
|
+
// One case where a skipped file's baseline is not a guess: it already
|
|
494
|
+
// matches the template byte for byte, so it provably is what init
|
|
495
|
+
// writes. That is what makes adoption work for a repo scaffolded before
|
|
496
|
+
// provenance existed. Never overwrite a baseline already recorded.
|
|
497
|
+
if (existing?.files[key] === undefined) {
|
|
498
|
+
const current = await readIfPresent(to);
|
|
499
|
+
if (current !== undefined && hashContent(current) === templateHash) {
|
|
500
|
+
baselines[key] = templateHash;
|
|
501
|
+
}
|
|
502
|
+
}
|
|
395
503
|
continue;
|
|
396
504
|
}
|
|
397
505
|
await mkdir(dirname(to), { recursive: true });
|
|
398
|
-
await
|
|
506
|
+
await writeFile(to, content, "utf8");
|
|
399
507
|
written.push(rel);
|
|
508
|
+
baselines[key] = templateHash;
|
|
400
509
|
}
|
|
510
|
+
await writeManifest(repo, mergeManifest(existing, template, VERSION, baselines));
|
|
401
511
|
}
|
|
402
512
|
catch (error) {
|
|
403
513
|
streams.err(`init failed: ${error instanceof Error ? error.message : String(error)}\n`);
|