ghostrail 0.3.0 → 0.5.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.
Files changed (41) hide show
  1. package/README.md +20 -1
  2. package/dist/cli/commands.d.ts +18 -3
  3. package/dist/cli/commands.d.ts.map +1 -1
  4. package/dist/cli/commands.js +189 -7
  5. package/dist/cli/commands.js.map +1 -1
  6. package/dist/cli.d.ts.map +1 -1
  7. package/dist/cli.js +3 -1
  8. package/dist/cli.js.map +1 -1
  9. package/dist/commands/help.d.ts.map +1 -1
  10. package/dist/commands/help.js +10 -0
  11. package/dist/commands/help.js.map +1 -1
  12. package/dist/factory/build.d.ts +2 -7
  13. package/dist/factory/build.d.ts.map +1 -1
  14. package/dist/factory/build.js +2 -16
  15. package/dist/factory/build.js.map +1 -1
  16. package/dist/init/template.d.ts +40 -0
  17. package/dist/init/template.d.ts.map +1 -0
  18. package/dist/init/template.js +89 -0
  19. package/dist/init/template.js.map +1 -0
  20. package/dist/secrets/editor.d.ts +16 -0
  21. package/dist/secrets/editor.d.ts.map +1 -0
  22. package/dist/secrets/editor.js +35 -0
  23. package/dist/secrets/editor.js.map +1 -0
  24. package/dist/secrets/env-file.d.ts +0 -13
  25. package/dist/secrets/env-file.d.ts.map +1 -1
  26. package/dist/secrets/env-file.js +6 -2
  27. package/dist/secrets/env-file.js.map +1 -1
  28. package/dist/secrets/index.d.ts +3 -0
  29. package/dist/secrets/index.d.ts.map +1 -1
  30. package/dist/secrets/index.js +3 -0
  31. package/dist/secrets/index.js.map +1 -1
  32. package/dist/secrets/known.d.ts +19 -0
  33. package/dist/secrets/known.d.ts.map +1 -0
  34. package/dist/secrets/known.js +23 -0
  35. package/dist/secrets/known.js.map +1 -0
  36. package/dist/secrets/setup.d.ts +44 -0
  37. package/dist/secrets/setup.d.ts.map +1 -0
  38. package/dist/secrets/setup.js +124 -0
  39. package/dist/secrets/setup.js.map +1 -0
  40. package/package.json +1 -1
  41. package/skill/ghostrail/SKILL.md +29 -2
@@ -1 +1 @@
1
- {"version":3,"file":"build.js","sourceRoot":"","sources":["../../src/factory/build.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"build.js","sourceRoot":"","sources":["../../src/factory/build.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ /** The provenance manifest `init` writes at the repo root. Committed with the repo. */
2
+ export declare const MANIFEST_FILE = "ghostrail.template.json";
3
+ /**
4
+ * What `init` wrote, and from which template and version. `files` maps a
5
+ * repo-relative path to the sha256 of the content as scaffolded, which is the
6
+ * baseline a later `--diff` compares against to tell a local edit apart from an
7
+ * upstream template change.
8
+ */
9
+ export interface TemplateManifest {
10
+ template: string;
11
+ version: string;
12
+ files: Record<string, string>;
13
+ }
14
+ /**
15
+ * How a scaffolded file stands relative to the shipped template. See
16
+ * `specs/template-provenance.spec.md` for the decision table.
17
+ */
18
+ export type FileStatus = "missing" | "up-to-date" | "unknown-baseline" | "upstream-changed" | "locally-modified" | "conflict";
19
+ /** sha256 of `content` as lowercase hex. No normalization: bytes are bytes. */
20
+ export declare function hashContent(content: string): string;
21
+ /**
22
+ * Classify one file from three content hashes. Total and mutually exclusive:
23
+ * every triple yields exactly one status. Never throws, never touches the disk.
24
+ *
25
+ * The baseline is what makes this more than a diff. Without it, "you edited
26
+ * this" and "the template moved" are indistinguishable, and reporting the wrong
27
+ * one would either hide an upstream fix or invite clobbering a customization.
28
+ */
29
+ export declare function classify(current: string | undefined, template: string, baseline: string | undefined): FileStatus;
30
+ /**
31
+ * The manifest to persist after an init run: existing baselines preserved, the
32
+ * files this run wrote layered on top, retargeted to the current template and
33
+ * version. Pure; neither argument is mutated.
34
+ */
35
+ export declare function mergeManifest(existing: TemplateManifest | undefined, template: string, version: string, written: Record<string, string>): TemplateManifest;
36
+ /** Read the manifest, or undefined if it is absent, unreadable, or malformed. */
37
+ export declare function readManifest(repoPath: string): Promise<TemplateManifest | undefined>;
38
+ /** Write the manifest as pretty JSON with a trailing newline. */
39
+ export declare function writeManifest(repoPath: string, manifest: TemplateManifest): Promise<void>;
40
+ //# sourceMappingURL=template.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"template.d.ts","sourceRoot":"","sources":["../../src/init/template.ts"],"names":[],"mappings":"AAIA,uFAAuF;AACvF,eAAO,MAAM,aAAa,4BAA4B,CAAC;AAEvD;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC/B;AAED;;;GAGG;AACH,MAAM,MAAM,UAAU,GAClB,SAAS,GACT,YAAY,GACZ,kBAAkB,GAClB,kBAAkB,GAClB,kBAAkB,GAClB,UAAU,CAAC;AAEf,+EAA+E;AAC/E,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED;;;;;;;GAOG;AACH,wBAAgB,QAAQ,CACtB,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,GAAG,SAAS,GAC3B,UAAU,CAOZ;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,gBAAgB,GAAG,SAAS,EACtC,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC9B,gBAAgB,CAMlB;AAyBD,iFAAiF;AACjF,wBAAsB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,GAAG,SAAS,CAAC,CAY1F;AAED,iEAAiE;AACjE,wBAAsB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAG/F"}
@@ -0,0 +1,89 @@
1
+ import { createHash } from "node:crypto";
2
+ import { readFile, writeFile } from "node:fs/promises";
3
+ import { join } from "node:path";
4
+ /** The provenance manifest `init` writes at the repo root. Committed with the repo. */
5
+ export const MANIFEST_FILE = "ghostrail.template.json";
6
+ /** sha256 of `content` as lowercase hex. No normalization: bytes are bytes. */
7
+ export function hashContent(content) {
8
+ return createHash("sha256").update(content, "utf8").digest("hex");
9
+ }
10
+ /**
11
+ * Classify one file from three content hashes. Total and mutually exclusive:
12
+ * every triple yields exactly one status. Never throws, never touches the disk.
13
+ *
14
+ * The baseline is what makes this more than a diff. Without it, "you edited
15
+ * this" and "the template moved" are indistinguishable, and reporting the wrong
16
+ * one would either hide an upstream fix or invite clobbering a customization.
17
+ */
18
+ export function classify(current, template, baseline) {
19
+ if (current === undefined)
20
+ return "missing";
21
+ if (current === template)
22
+ return "up-to-date";
23
+ if (baseline === undefined)
24
+ return "unknown-baseline";
25
+ if (baseline === current)
26
+ return "upstream-changed";
27
+ if (baseline === template)
28
+ return "locally-modified";
29
+ return "conflict";
30
+ }
31
+ /**
32
+ * The manifest to persist after an init run: existing baselines preserved, the
33
+ * files this run wrote layered on top, retargeted to the current template and
34
+ * version. Pure; neither argument is mutated.
35
+ */
36
+ export function mergeManifest(existing, template, version, written) {
37
+ return {
38
+ template,
39
+ version,
40
+ files: { ...(existing?.files ?? {}), ...written },
41
+ };
42
+ }
43
+ /** True if `value` is a plain object (not null, not an array). */
44
+ function isRecord(value) {
45
+ return typeof value === "object" && value !== null && !Array.isArray(value);
46
+ }
47
+ /**
48
+ * Validate a parsed manifest. Anything malformed is rejected outright rather
49
+ * than partially trusted: a bad manifest must degrade to "baseline unknown",
50
+ * never to a false claim that a file is unmodified.
51
+ */
52
+ function parseManifest(raw) {
53
+ if (!isRecord(raw))
54
+ return undefined;
55
+ const { template, version, files } = raw;
56
+ if (typeof template !== "string" || typeof version !== "string")
57
+ return undefined;
58
+ if (!isRecord(files))
59
+ return undefined;
60
+ const entries = {};
61
+ for (const [key, value] of Object.entries(files)) {
62
+ if (typeof value !== "string")
63
+ return undefined;
64
+ entries[key] = value;
65
+ }
66
+ return { template, version, files: entries };
67
+ }
68
+ /** Read the manifest, or undefined if it is absent, unreadable, or malformed. */
69
+ export async function readManifest(repoPath) {
70
+ let raw;
71
+ try {
72
+ raw = await readFile(join(repoPath, MANIFEST_FILE), "utf8");
73
+ }
74
+ catch {
75
+ return undefined;
76
+ }
77
+ try {
78
+ return parseManifest(JSON.parse(raw));
79
+ }
80
+ catch {
81
+ return undefined;
82
+ }
83
+ }
84
+ /** Write the manifest as pretty JSON with a trailing newline. */
85
+ export async function writeManifest(repoPath, manifest) {
86
+ const body = `${JSON.stringify(manifest, null, 2)}\n`;
87
+ await writeFile(join(repoPath, MANIFEST_FILE), body, "utf8");
88
+ }
89
+ //# sourceMappingURL=template.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"template.js","sourceRoot":"","sources":["../../src/init/template.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * The editor command to launch, as an argv array, from `$VISUAL` then
3
+ * `$EDITOR`. The value is split on whitespace so `code -w` works. A variable
4
+ * that is unset, empty, or only whitespace is skipped rather than chosen, so an
5
+ * empty `VISUAL` still falls through to `EDITOR`. Undefined when neither yields
6
+ * a command: the caller prints the path instead of guessing at an editor.
7
+ */
8
+ export declare function resolveEditor(env: Record<string, string | undefined>): string[] | undefined;
9
+ /**
10
+ * Run the editor on `path`, inheriting the terminal so a full-screen editor
11
+ * works, and resolve its exit code. Never rejects: a spawn failure resolves
12
+ * non-zero, because the file is already written by the time this runs and a
13
+ * failing editor is not a failing setup.
14
+ */
15
+ export declare function launchEditor(command: readonly string[], path: string): Promise<number>;
16
+ //# sourceMappingURL=editor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"editor.d.ts","sourceRoot":"","sources":["../../src/secrets/editor.ts"],"names":[],"mappings":"AAKA;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,GAAG,MAAM,EAAE,GAAG,SAAS,CAM3F;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAQtF"}
@@ -0,0 +1,35 @@
1
+ import { spawn } from "node:child_process";
2
+ /** The env vars that name an editor, in preference order. */
3
+ const EDITOR_VARS = ["VISUAL", "EDITOR"];
4
+ /**
5
+ * The editor command to launch, as an argv array, from `$VISUAL` then
6
+ * `$EDITOR`. The value is split on whitespace so `code -w` works. A variable
7
+ * that is unset, empty, or only whitespace is skipped rather than chosen, so an
8
+ * empty `VISUAL` still falls through to `EDITOR`. Undefined when neither yields
9
+ * a command: the caller prints the path instead of guessing at an editor.
10
+ */
11
+ export function resolveEditor(env) {
12
+ for (const name of EDITOR_VARS) {
13
+ const parts = (env[name] ?? "").split(/\s+/).filter((part) => part.length > 0);
14
+ if (parts.length > 0)
15
+ return parts;
16
+ }
17
+ return undefined;
18
+ }
19
+ /**
20
+ * Run the editor on `path`, inheriting the terminal so a full-screen editor
21
+ * works, and resolve its exit code. Never rejects: a spawn failure resolves
22
+ * non-zero, because the file is already written by the time this runs and a
23
+ * failing editor is not a failing setup.
24
+ */
25
+ export function launchEditor(command, path) {
26
+ const [file, ...args] = command;
27
+ if (file === undefined)
28
+ return Promise.resolve(1);
29
+ return new Promise((resolve) => {
30
+ const child = spawn(file, [...args, path], { stdio: "inherit" });
31
+ child.on("error", () => resolve(1));
32
+ child.on("close", (code) => resolve(code ?? 1));
33
+ });
34
+ }
35
+ //# sourceMappingURL=editor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"editor.js","sourceRoot":"","sources":["../../src/secrets/editor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAE3C,6DAA6D;AAC7D,MAAM,WAAW,GAAG,CAAC,QAAQ,EAAE,QAAQ,CAAU,CAAC;AAElD;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAAC,GAAuC;IACnE,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;QAC/B,MAAM,KAAK,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAC/E,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;YAAE,OAAO,KAAK,CAAC;IACrC,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,OAA0B,EAAE,IAAY;IACnE,MAAM,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,GAAG,OAAO,CAAC;IAChC,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IAClD,OAAO,IAAI,OAAO,CAAS,CAAC,OAAO,EAAE,EAAE;QACrC,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;QACjE,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;QACpC,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -1,16 +1,3 @@
1
- /**
2
- * Parse a dotenv-style file into key/value pairs.
3
- *
4
- * - One `KEY=VALUE` per line; an optional leading `export ` is stripped.
5
- * - Blank lines and lines whose first non-space character is `#` are ignored.
6
- * - The key is everything before the first `=`, trimmed. A line with no `=`, or
7
- * an empty key, is skipped.
8
- * - The value is everything after the first `=`, trimmed; if it is wholly wrapped
9
- * in matching single or double quotes, the quotes are removed (and the inner
10
- * text is not further trimmed). `=` characters in the value are preserved.
11
- *
12
- * Pure: no I/O, never throws for any string.
13
- */
14
1
  export declare function parseEnvFile(content: string): Record<string, string>;
15
2
  /** True if a variable name denotes a secret (by known name or suffix). */
16
3
  export declare function isSecretKey(key: string): boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"env-file.d.ts","sourceRoot":"","sources":["../../src/secrets/env-file.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAgBpE;AAwBD,0EAA0E;AAC1E,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAEhD;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,GAAG,MAAM,EAAE,CAUhF"}
1
+ {"version":3,"file":"env-file.d.ts","sourceRoot":"","sources":["../../src/secrets/env-file.ts"],"names":[],"mappings":"AAkBA,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAgBpE;AAwBD,0EAA0E;AAC1E,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAEhD;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,GAAG,MAAM,EAAE,CAUhF"}
@@ -1,7 +1,9 @@
1
1
  /**
2
2
  * Parse a dotenv-style file into key/value pairs.
3
3
  *
4
- * - One `KEY=VALUE` per line; an optional leading `export ` is stripped.
4
+ * - One `KEY=VALUE` per line; a leading `export` and the whitespace after it are
5
+ * stripped. Any whitespace separates them, as in a shell, so `export\tKEY=v`
6
+ * yields the key `KEY` rather than one literally named `export\tKEY`.
5
7
  * - Blank lines and lines whose first non-space character is `#` are ignored.
6
8
  * - The key is everything before the first `=`, trimmed. A line with no `=`, or
7
9
  * an empty key, is skipped.
@@ -11,13 +13,15 @@
11
13
  *
12
14
  * Pure: no I/O, never throws for any string.
13
15
  */
16
+ /** A leading shell `export` and whatever whitespace separates it from the key. */
17
+ const EXPORT_PREFIX = /^export\s+/;
14
18
  export function parseEnvFile(content) {
15
19
  const result = {};
16
20
  for (const rawLine of content.split("\n")) {
17
21
  const line = rawLine.trim();
18
22
  if (line.length === 0 || line.startsWith("#"))
19
23
  continue;
20
- const withoutExport = line.startsWith("export ") ? line.slice("export ".length) : line;
24
+ const withoutExport = line.replace(EXPORT_PREFIX, "");
21
25
  const eq = withoutExport.indexOf("=");
22
26
  if (eq === -1)
23
27
  continue;
@@ -1 +1 @@
1
- {"version":3,"file":"env-file.js","sourceRoot":"","sources":["../../src/secrets/env-file.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,YAAY,CAAC,OAAe;IAC1C,MAAM,MAAM,GAA2B,EAAE,CAAC;IAC1C,KAAK,MAAM,OAAO,IAAI,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QAC1C,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;QAC5B,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS;QAExD,MAAM,aAAa,GAAG,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QACvF,MAAM,EAAE,GAAG,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACtC,IAAI,EAAE,KAAK,CAAC,CAAC;YAAE,SAAS;QAExB,MAAM,GAAG,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QAC9C,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC;YAAE,SAAS;QAE/B,MAAM,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,aAAa,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IAC5D,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,OAAO,CAAC,KAAa;IAC5B,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;QACtB,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACvB,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACrC,IAAI,CAAC,KAAK,KAAK,GAAG,IAAI,KAAK,KAAK,GAAG,CAAC,IAAI,IAAI,KAAK,KAAK,EAAE,CAAC;YACvD,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,uFAAuF;AACvF,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAC;IAChC,gBAAgB;IAChB,mBAAmB;IACnB,UAAU;IACV,cAAc;IACd,WAAW;CACZ,CAAC,CAAC;AAEH,MAAM,kBAAkB,GAAG,mDAAmD,CAAC;AAE/E,0EAA0E;AAC1E,MAAM,UAAU,WAAW,CAAC,GAAW;IACrC,OAAO,iBAAiB,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,kBAAkB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACpE,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,GAAuC;IACpE,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QAC/C,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC,IAAI,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;YACrF,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YAChB,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACrB,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
1
+ {"version":3,"file":"env-file.js","sourceRoot":"","sources":["../../src/secrets/env-file.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,kFAAkF;AAClF,MAAM,aAAa,GAAG,YAAY,CAAC;AAEnC,MAAM,UAAU,YAAY,CAAC,OAAe;IAC1C,MAAM,MAAM,GAA2B,EAAE,CAAC;IAC1C,KAAK,MAAM,OAAO,IAAI,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QAC1C,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;QAC5B,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS;QAExD,MAAM,aAAa,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC;QACtD,MAAM,EAAE,GAAG,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACtC,IAAI,EAAE,KAAK,CAAC,CAAC;YAAE,SAAS;QAExB,MAAM,GAAG,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QAC9C,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC;YAAE,SAAS;QAE/B,MAAM,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,aAAa,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IAC5D,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,OAAO,CAAC,KAAa;IAC5B,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;QACtB,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACvB,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACrC,IAAI,CAAC,KAAK,KAAK,GAAG,IAAI,KAAK,KAAK,GAAG,CAAC,IAAI,IAAI,KAAK,KAAK,EAAE,CAAC;YACvD,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,uFAAuF;AACvF,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAC;IAChC,gBAAgB;IAChB,mBAAmB;IACnB,UAAU;IACV,cAAc;IACd,WAAW;CACZ,CAAC,CAAC;AAEH,MAAM,kBAAkB,GAAG,mDAAmD,CAAC;AAE/E,0EAA0E;AAC1E,MAAM,UAAU,WAAW,CAAC,GAAW;IACrC,OAAO,iBAAiB,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,kBAAkB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACpE,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,GAAuC;IACpE,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QAC/C,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC,IAAI,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;YACrF,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YAChB,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACrB,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -1,4 +1,7 @@
1
+ export { launchEditor, resolveEditor } from "./editor.js";
1
2
  export { isSecretKey, parseEnvFile, secretValuesOf } from "./env-file.js";
3
+ export { type CredentialKey, DEFAULT_FORWARD_ENV } from "./known.js";
4
+ export { appendPlaceholders, KNOWN_SECRETS, mentionedKeys, missingSecrets, readSecretsFile, renderFile, SECRETS_DIR_MODE, SECRETS_FILE_MODE, type SecretSpec, writeSecretsFile, } from "./setup.js";
2
5
  export { applyOverrides, GLOBAL_SECRETS_FILE, type LoadedEnv, loadEnvOverrides, REPO_SECRETS_FILE, } from "./load.js";
3
6
  export { REDACTION, redactSecrets } from "./redact.js";
4
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/secrets/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC1E,OAAO,EACL,cAAc,EACd,mBAAmB,EACnB,KAAK,SAAS,EACd,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/secrets/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC1D,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC1E,OAAO,EAAE,KAAK,aAAa,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACrE,OAAO,EACL,kBAAkB,EAClB,aAAa,EACb,aAAa,EACb,cAAc,EACd,eAAe,EACf,UAAU,EACV,gBAAgB,EAChB,iBAAiB,EACjB,KAAK,UAAU,EACf,gBAAgB,GACjB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,cAAc,EACd,mBAAmB,EACnB,KAAK,SAAS,EACd,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC"}
@@ -1,4 +1,7 @@
1
+ export { launchEditor, resolveEditor } from "./editor.js";
1
2
  export { isSecretKey, parseEnvFile, secretValuesOf } from "./env-file.js";
3
+ export { DEFAULT_FORWARD_ENV } from "./known.js";
4
+ export { appendPlaceholders, KNOWN_SECRETS, mentionedKeys, missingSecrets, readSecretsFile, renderFile, SECRETS_DIR_MODE, SECRETS_FILE_MODE, writeSecretsFile, } from "./setup.js";
2
5
  export { applyOverrides, GLOBAL_SECRETS_FILE, loadEnvOverrides, REPO_SECRETS_FILE, } from "./load.js";
3
6
  export { REDACTION, redactSecrets } from "./redact.js";
4
7
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/secrets/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC1E,OAAO,EACL,cAAc,EACd,mBAAmB,EAEnB,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/secrets/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC1D,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC1E,OAAO,EAAsB,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACrE,OAAO,EACL,kBAAkB,EAClB,aAAa,EACb,aAAa,EACb,cAAc,EACd,eAAe,EACf,UAAU,EACV,gBAAgB,EAChB,iBAAiB,EAEjB,gBAAgB,GACjB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,cAAc,EACd,mBAAmB,EAEnB,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Host env names forwarded into every container `docker exec` by default, so the
3
+ * agent and gate have the credentials they need. Only names are configured;
4
+ * values come from the process environment (after the secrets loader has applied
5
+ * them), and unset names are simply skipped. The container inherits nothing else.
6
+ *
7
+ * This is also the canonical list of credentials ghostrail reads, so
8
+ * `secrets-setup` scaffolds a placeholder for exactly these names. It lives in a
9
+ * leaf module so both consumers can share it without dragging in the factory's
10
+ * dependency graph.
11
+ *
12
+ * Agent auth covers both rails: ANTHROPIC_API_KEY bills metered API and wins if
13
+ * both are set; CLAUDE_CODE_OAUTH_TOKEN (from `claude setup-token`) bills the
14
+ * Pro/Max subscription when the API key is unset.
15
+ */
16
+ export declare const DEFAULT_FORWARD_ENV: readonly ["ANTHROPIC_API_KEY", "CLAUDE_CODE_OAUTH_TOKEN", "GH_TOKEN", "GITHUB_TOKEN", "LINEAR_API_KEY"];
17
+ /** A credential name ghostrail reads. */
18
+ export type CredentialKey = (typeof DEFAULT_FORWARD_ENV)[number];
19
+ //# sourceMappingURL=known.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"known.d.ts","sourceRoot":"","sources":["../../src/secrets/known.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,mBAAmB,yGAMtB,CAAC;AAEX,yCAAyC;AACzC,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,mBAAmB,CAAC,CAAC,MAAM,CAAC,CAAC"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Host env names forwarded into every container `docker exec` by default, so the
3
+ * agent and gate have the credentials they need. Only names are configured;
4
+ * values come from the process environment (after the secrets loader has applied
5
+ * them), and unset names are simply skipped. The container inherits nothing else.
6
+ *
7
+ * This is also the canonical list of credentials ghostrail reads, so
8
+ * `secrets-setup` scaffolds a placeholder for exactly these names. It lives in a
9
+ * leaf module so both consumers can share it without dragging in the factory's
10
+ * dependency graph.
11
+ *
12
+ * Agent auth covers both rails: ANTHROPIC_API_KEY bills metered API and wins if
13
+ * both are set; CLAUDE_CODE_OAUTH_TOKEN (from `claude setup-token`) bills the
14
+ * Pro/Max subscription when the API key is unset.
15
+ */
16
+ export const DEFAULT_FORWARD_ENV = [
17
+ "ANTHROPIC_API_KEY",
18
+ "CLAUDE_CODE_OAUTH_TOKEN",
19
+ "GH_TOKEN",
20
+ "GITHUB_TOKEN",
21
+ "LINEAR_API_KEY",
22
+ ];
23
+ //# sourceMappingURL=known.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"known.js","sourceRoot":"","sources":["../../src/secrets/known.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,mBAAmB;IACnB,yBAAyB;IACzB,UAAU;IACV,cAAc;IACd,gBAAgB;CACR,CAAC"}
@@ -0,0 +1,44 @@
1
+ /** One credential the secrets file can carry. */
2
+ export interface SecretSpec {
3
+ /** The variable name. */
4
+ key: string;
5
+ /** One line: what it is and where to get it. */
6
+ description: string;
7
+ }
8
+ /** The secrets file holds credentials, so it is created owner-only. */
9
+ export declare const SECRETS_FILE_MODE = 384;
10
+ /** The global config dir, created owner-only for the same reason. */
11
+ export declare const SECRETS_DIR_MODE = 448;
12
+ /** Every credential ghostrail reads, in forwarding order. */
13
+ export declare const KNOWN_SECRETS: readonly SecretSpec[];
14
+ /**
15
+ * The variable names the content refers to, whether as a live assignment or as a
16
+ * commented placeholder. Both count, so topping a file up never re-adds a
17
+ * placeholder the file already carries.
18
+ *
19
+ * Only names are returned. No value is read, returned, or surfaced.
20
+ */
21
+ export declare function mentionedKeys(content: string): Set<string>;
22
+ /**
23
+ * The known credentials the content does not mention, in `KNOWN_SECRETS` order.
24
+ * `undefined` content (no file yet) means every one of them is missing. Names
25
+ * the file carries that ghostrail does not read are ignored.
26
+ */
27
+ export declare function missingSecrets(content: string | undefined): SecretSpec[];
28
+ /**
29
+ * The full content of a fresh secrets file: a header, then a commented
30
+ * placeholder per spec. Every line is a comment, so creating the file never
31
+ * changes what ghostrail resolves.
32
+ */
33
+ export declare function renderFile(specs: readonly SecretSpec[]): string;
34
+ /**
35
+ * Append placeholder blocks for `specs` to existing content, preserving every
36
+ * byte of it up to its trailing newlines. Only the run of trailing newlines can
37
+ * change, which keeps repeated runs from stacking blank lines.
38
+ */
39
+ export declare function appendPlaceholders(existing: string, specs: readonly SecretSpec[]): string;
40
+ /** The secrets file's content, or undefined when it does not exist. */
41
+ export declare function readSecretsFile(path: string): Promise<string | undefined>;
42
+ /** Write the secrets file owner-only, creating its directory owner-only too. */
43
+ export declare function writeSecretsFile(path: string, content: string): Promise<void>;
44
+ //# sourceMappingURL=setup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/secrets/setup.ts"],"names":[],"mappings":"AAKA,iDAAiD;AACjD,MAAM,WAAW,UAAU;IACzB,yBAAyB;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,gDAAgD;IAChD,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,uEAAuE;AACvE,eAAO,MAAM,iBAAiB,MAAQ,CAAC;AACvC,qEAAqE;AACrE,eAAO,MAAM,gBAAgB,MAAQ,CAAC;AAkBtC,6DAA6D;AAC7D,eAAO,MAAM,aAAa,EAAE,SAAS,UAAU,EAG5C,CAAC;AASJ;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAU1D;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,UAAU,EAAE,CAIxE;AAyBD;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,SAAS,UAAU,EAAE,GAAG,MAAM,CAI/D;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,UAAU,EAAE,GAAG,MAAM,CAOzF;AAED,uEAAuE;AACvE,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAM/E;AAED,gFAAgF;AAChF,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAGnF"}
@@ -0,0 +1,124 @@
1
+ import { mkdir, readFile, writeFile } from "node:fs/promises";
2
+ import { dirname } from "node:path";
3
+ import { parseEnvFile } from "./env-file.js";
4
+ import { DEFAULT_FORWARD_ENV } from "./known.js";
5
+ /** The secrets file holds credentials, so it is created owner-only. */
6
+ export const SECRETS_FILE_MODE = 0o600;
7
+ /** The global config dir, created owner-only for the same reason. */
8
+ export const SECRETS_DIR_MODE = 0o700;
9
+ /**
10
+ * What each credential is for. Keyed by {@link CredentialKey}, so adding a name
11
+ * to `DEFAULT_FORWARD_ENV` without describing it here is a type error rather
12
+ * than a key silently missing from the scaffolded file.
13
+ */
14
+ const DESCRIPTIONS = {
15
+ ANTHROPIC_API_KEY: "Anthropic API key. Bills metered API usage, and wins over CLAUDE_CODE_OAUTH_TOKEN when both are set.",
16
+ CLAUDE_CODE_OAUTH_TOKEN: "From `claude setup-token`. Bills a Claude Pro/Max subscription; leave ANTHROPIC_API_KEY unset to use it.",
17
+ GH_TOKEN: "GitHub token with repo + pull-request write. Used to push factory branches and open PRs.",
18
+ GITHUB_TOKEN: "Alternative name for the GitHub token, read when GH_TOKEN is unset.",
19
+ LINEAR_API_KEY: "Linear personal API key (Settings > Security & Access). Required for every run.",
20
+ };
21
+ /** Every credential ghostrail reads, in forwarding order. */
22
+ export const KNOWN_SECRETS = DEFAULT_FORWARD_ENV.map((key) => ({
23
+ key,
24
+ description: DESCRIPTIONS[key],
25
+ }));
26
+ /**
27
+ * A commented placeholder line: a comment whose first content is `KEY=`, with an
28
+ * optional `export`. Requiring the `=` is what separates a placeholder from
29
+ * prose that merely names a variable.
30
+ */
31
+ const COMMENTED_ASSIGNMENT = /^#+\s*(?:export\s+)?([A-Za-z_][A-Za-z0-9_]*)\s*=/;
32
+ /**
33
+ * The variable names the content refers to, whether as a live assignment or as a
34
+ * commented placeholder. Both count, so topping a file up never re-adds a
35
+ * placeholder the file already carries.
36
+ *
37
+ * Only names are returned. No value is read, returned, or surfaced.
38
+ */
39
+ export function mentionedKeys(content) {
40
+ const keys = new Set(Object.keys(parseEnvFile(content)));
41
+ for (const rawLine of content.split("\n")) {
42
+ const line = rawLine.trim();
43
+ if (!line.startsWith("#"))
44
+ continue;
45
+ const match = COMMENTED_ASSIGNMENT.exec(line);
46
+ const key = match?.[1];
47
+ if (key !== undefined)
48
+ keys.add(key);
49
+ }
50
+ return keys;
51
+ }
52
+ /**
53
+ * The known credentials the content does not mention, in `KNOWN_SECRETS` order.
54
+ * `undefined` content (no file yet) means every one of them is missing. Names
55
+ * the file carries that ghostrail does not read are ignored.
56
+ */
57
+ export function missingSecrets(content) {
58
+ if (content === undefined)
59
+ return [...KNOWN_SECRETS];
60
+ const mentioned = mentionedKeys(content);
61
+ return KNOWN_SECRETS.filter((spec) => !mentioned.has(spec.key));
62
+ }
63
+ const HEADER = [
64
+ "# ghostrail credentials.",
65
+ "#",
66
+ "# ghostrail reads this file on every run, watch, respond, and triage. A value",
67
+ "# set here overrides the same variable in your environment (precedence: a",
68
+ "# repo's .ghostrail.env, then this file, then the ambient environment).",
69
+ "#",
70
+ "# Uncomment a line and fill in the value. Leave the rest commented: an",
71
+ "# uncommented empty value would blank out a working credential from your",
72
+ "# environment. This file is created mode 600 and belongs to you alone.",
73
+ ];
74
+ /**
75
+ * The description + commented placeholder block for one credential. A
76
+ * description carrying newlines becomes one comment line per line, so no input
77
+ * can produce an uncommented line and quietly turn the file into a live
78
+ * assignment.
79
+ */
80
+ function block(spec) {
81
+ const description = spec.description.split("\n").map((line) => `# ${line}`);
82
+ return ["", ...description, `# ${spec.key}=`];
83
+ }
84
+ /**
85
+ * The full content of a fresh secrets file: a header, then a commented
86
+ * placeholder per spec. Every line is a comment, so creating the file never
87
+ * changes what ghostrail resolves.
88
+ */
89
+ export function renderFile(specs) {
90
+ const lines = [...HEADER];
91
+ for (const spec of specs)
92
+ lines.push(...block(spec));
93
+ return `${lines.join("\n")}\n`;
94
+ }
95
+ /**
96
+ * Append placeholder blocks for `specs` to existing content, preserving every
97
+ * byte of it up to its trailing newlines. Only the run of trailing newlines can
98
+ * change, which keeps repeated runs from stacking blank lines.
99
+ */
100
+ export function appendPlaceholders(existing, specs) {
101
+ if (specs.length === 0)
102
+ return existing;
103
+ const base = existing.replace(/\n+$/, "");
104
+ const lines = ["# Added by ghostrail secrets-setup."];
105
+ for (const spec of specs)
106
+ lines.push(...block(spec));
107
+ const body = `${lines.join("\n")}\n`;
108
+ return base.trim().length === 0 ? body : `${base}\n\n${body}`;
109
+ }
110
+ /** The secrets file's content, or undefined when it does not exist. */
111
+ export async function readSecretsFile(path) {
112
+ try {
113
+ return await readFile(path, "utf8");
114
+ }
115
+ catch {
116
+ return undefined;
117
+ }
118
+ }
119
+ /** Write the secrets file owner-only, creating its directory owner-only too. */
120
+ export async function writeSecretsFile(path, content) {
121
+ await mkdir(dirname(path), { recursive: true, mode: SECRETS_DIR_MODE });
122
+ await writeFile(path, content, { encoding: "utf8", mode: SECRETS_FILE_MODE });
123
+ }
124
+ //# sourceMappingURL=setup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup.js","sourceRoot":"","sources":["../../src/secrets/setup.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ghostrail",
3
- "version": "0.3.0",
3
+ "version": "0.5.0",
4
4
  "description": "Open source software factory for coding agents. Config-driven loops, pluggable isolation backends, human merge gate.",
5
5
  "keywords": [
6
6
  "ai-agents",
@@ -5,7 +5,7 @@ user-invocable: true
5
5
  argument-hint: "[customize | init | doctor | status | run | respond | triage]"
6
6
  license: Apache-2.0
7
7
  metadata:
8
- version: 0.1.0
8
+ version: 0.2.0
9
9
  allowed-tools:
10
10
  - Read
11
11
  - Write
@@ -85,6 +85,28 @@ Scaffold the factory into this repo, then hand off to **customize**.
85
85
  3. Tell the user the two things the scaffold can't know (repo-specific prompt
86
86
  detail and the tracker filters), and offer to run **customize** now.
87
87
 
88
+ ### Already initialized? Check for template drift
89
+
90
+ If the repo already has `ghostrail.toml` and `prompts/`, do not re-run a bare
91
+ `init` and report "0 files written" as if nothing were wrong. Run:
92
+
93
+ ```
94
+ <GR> init <template> --diff
95
+ ```
96
+
97
+ It is read-only. It reports each scaffolded file as up to date, locally
98
+ customized, safe to take, a conflict, or missing, using the baseline recorded in
99
+ `ghostrail.template.json`. Summarize the rows that are not up to date, show the
100
+ `diff` command it printed, and offer to merge template changes in by hand.
101
+
102
+ Never suggest `--force` as the way to take a template update: it overwrites every
103
+ file, destroying the gate commands, tracker filters, and prompt edits that
104
+ **customize** wrote. Merging by hand is the correct path.
105
+
106
+ If it reports no recorded baseline, the repo predates provenance. Re-running a
107
+ bare `<GR> init` once adopts a baseline for every file that still matches the
108
+ template exactly, which is safe and improves later diffs.
109
+
88
110
  ---
89
111
 
90
112
  ## doctor
@@ -101,7 +123,12 @@ Diagnose a setup without changing anything. Check and report each, with the fix:
101
123
  - **Credentials** — report which of `LINEAR_API_KEY`, `GH_TOKEN`/`GITHUB_TOKEN`,
102
124
  and `ANTHROPIC_API_KEY` **or** `CLAUDE_CODE_OAUTH_TOKEN` are set. Report only
103
125
  set/unset, **never print a value**. Note that `ANTHROPIC_API_KEY` wins over the
104
- OAuth token, so it must be unset to bill a Pro/Max subscription.
126
+ OAuth token, so it must be unset to bill a Pro/Max subscription. Remember they
127
+ can come from a file as well as the environment: `~/.config/ghostrail/secrets.env`
128
+ and a repo's `.ghostrail.env`, which beat an exported variable of the same name.
129
+ When something is missing, the fix to suggest is `ghostrail secrets-setup --write`,
130
+ which scaffolds that file and opens it in the user's editor. Never offer to fill
131
+ in a value yourself.
105
132
  - **GitHub** — `gh auth status` succeeds.
106
133
  - **Container backend**, if `[backend].kind = "container"` — the configured
107
134
  `image` exists locally (`docker images`). If not, it must be built.