@isaacriehm/cairn 0.19.1 → 0.22.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.
@@ -0,0 +1,85 @@
1
+ /**
2
+ * `cairn migrate` — bring `.cairn/` state up to the current Cairn version.
3
+ *
4
+ * Runs the coded migration registry: `safe` migrations apply automatically;
5
+ * `review` migrations apply only with `--all` (operator-confirmed). `--dry-run`
6
+ * reports what would run without touching anything. Replaces the scattered
7
+ * `cairn fix <X>` version-keyed repairs.
8
+ */
9
+ import { existsSync } from "node:fs";
10
+ import { resolve } from "node:path";
11
+ import { isAdopted, runMigrations } from "@isaacriehm/cairn-core";
12
+ function parseRepoFlag(argv) {
13
+ const idx = argv.indexOf("--repo");
14
+ if (idx === -1)
15
+ return process.cwd();
16
+ const candidate = argv[idx + 1];
17
+ if (candidate === undefined || candidate.startsWith("--")) {
18
+ console.error("--repo requires a path argument");
19
+ process.exit(2);
20
+ }
21
+ return resolve(candidate);
22
+ }
23
+ function ensureAdopted(repoRoot) {
24
+ if (!existsSync(repoRoot)) {
25
+ console.error(`cairn: repo root does not exist: ${repoRoot}`);
26
+ process.exit(2);
27
+ }
28
+ if (!isAdopted(repoRoot)) {
29
+ console.error(`cairn: ${repoRoot} is not cairn-adopted (no config.yaml). Run \`cairn init\` first.`);
30
+ process.exit(2);
31
+ }
32
+ }
33
+ function icon(status) {
34
+ switch (status) {
35
+ case "applied":
36
+ return "✓";
37
+ case "noop":
38
+ return "○";
39
+ case "queued":
40
+ case "would-queue":
41
+ return "⚠";
42
+ case "failed":
43
+ return "✗";
44
+ case "would-apply":
45
+ return "→";
46
+ }
47
+ }
48
+ export async function migrateCli(argv) {
49
+ const repoRoot = parseRepoFlag(argv);
50
+ ensureAdopted(repoRoot);
51
+ const dryRun = argv.includes("--dry-run");
52
+ const includeReview = argv.includes("--all");
53
+ const result = await runMigrations({ repoRoot, dryRun, includeReview });
54
+ if (!result.ran) {
55
+ process.stdout.write("⬡ cairn migrate — another migration is in progress (lock held); skipped.\n");
56
+ process.exit(0);
57
+ }
58
+ process.stdout.write(`⬡ cairn migrate — pin ${result.pin} → ${result.current}${dryRun ? " (dry-run)" : ""}\n`);
59
+ if (result.outcomes.length === 0) {
60
+ if (result.newPin !== null) {
61
+ process.stdout.write(` ✓ Nothing pending — pin bumped to ${result.newPin}.\n`);
62
+ }
63
+ else {
64
+ process.stdout.write(" ✓ Already up to date.\n");
65
+ }
66
+ process.exit(0);
67
+ }
68
+ for (const o of result.outcomes) {
69
+ process.stdout.write(` ${icon(o.status)} ${o.id} — ${o.detail}\n`);
70
+ }
71
+ process.stdout.write("\n");
72
+ const failed = result.outcomes.filter((o) => o.status === "failed").length;
73
+ if (result.newPin !== null) {
74
+ process.stdout.write(` Pin advanced to ${result.newPin}.\n`);
75
+ }
76
+ if (result.pendingReview.length > 0) {
77
+ process.stdout.write(` ${result.pendingReview.length} review migration(s) need confirmation — re-run with \`cairn migrate --all\`.\n`);
78
+ }
79
+ if (failed > 0) {
80
+ process.stdout.write(` ${failed} migration(s) failed — state left at last good.\n`);
81
+ process.exit(1);
82
+ }
83
+ process.exit(0);
84
+ }
85
+ //# sourceMappingURL=migrate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrate.js","sourceRoot":"","sources":["../../src/cli/migrate.ts"],"names":[],"mappings":"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"}
package/dist/cli/scope.js CHANGED
@@ -5,7 +5,7 @@
5
5
  */
6
6
  import { existsSync } from "node:fs";
7
7
  import { resolve } from "node:path";
8
- import { rebuildScopeIndex } from "@isaacriehm/cairn-core";
8
+ import { isAdopted, rebuildScopeIndex } from "@isaacriehm/cairn-core";
9
9
  function usage() {
10
10
  console.error("Usage: cairn scope <subcommand>\n" +
11
11
  " rebuild re-run mapper LLM and rewrite scope-index.yaml\n" +
@@ -29,8 +29,8 @@ async function rebuildHandler(argv) {
29
29
  console.error(`cairn scope rebuild: repo root does not exist: ${repoRoot}`);
30
30
  process.exit(2);
31
31
  }
32
- if (!existsSync(`${repoRoot}/.cairn`)) {
33
- console.error(`cairn scope rebuild: ${repoRoot} is not cairn-adopted (no .cairn/). Run \`cairn init\` first.`);
32
+ if (!isAdopted(repoRoot)) {
33
+ console.error(`cairn scope rebuild: ${repoRoot} is not cairn-adopted (no config.yaml). Run \`cairn init\` first.`);
34
34
  process.exit(2);
35
35
  }
36
36
  process.stdout.write("⬡ cairn scope rebuild — deterministic regex rescan…\n");
@@ -1 +1 @@
1
- {"version":3,"file":"scope.js","sourceRoot":"","sources":["../../src/cli/scope.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAE3D,SAAS,KAAK;IACZ,OAAO,CAAC,KAAK,CACX,mCAAmC;QACjC,kEAAkE;QAClE,sDAAsD,CACzD,CAAC;IACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,SAAS,aAAa,CAAC,IAAc;IACnC,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACnC,IAAI,GAAG,KAAK,CAAC,CAAC;QAAE,OAAO,OAAO,CAAC,GAAG,EAAE,CAAC;IACrC,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;IAChC,IAAI,SAAS,KAAK,SAAS,IAAI,SAAS,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QAC1D,OAAO,CAAC,KAAK,CAAC,iCAAiC,CAAC,CAAC;QACjD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,OAAO,OAAO,CAAC,SAAS,CAAC,CAAC;AAC5B,CAAC;AAED,KAAK,UAAU,cAAc,CAAC,IAAc;IAC1C,MAAM,QAAQ,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;IACrC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC1B,OAAO,CAAC,KAAK,CAAC,kDAAkD,QAAQ,EAAE,CAAC,CAAC;QAC5E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,IAAI,CAAC,UAAU,CAAC,GAAG,QAAQ,SAAS,CAAC,EAAE,CAAC;QACtC,OAAO,CAAC,KAAK,CACX,wBAAwB,QAAQ,+DAA+D,CAChG,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,uDAAuD,CAAC,CAAC;IAC9E,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,iBAAiB,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC;QACrD,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC;YAC9C,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC;YACxC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC;QAChB,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,aAAa,OAAO,MAAM,MAAM,CAAC,eAAe,QAC9C,MAAM,CAAC,eAAe,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GACtC,cAAc,MAAM,CAAC,UAAU,OAAO,CACvC,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC7D,OAAO,CAAC,KAAK,CAAC,wCAAwC,GAAG,EAAE,CAAC,CAAC;QAC7D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,IAAc;IAC3C,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,QAAQ,GAAG,EAAE,CAAC;QACZ,KAAK,SAAS;YACZ,MAAM,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;YACpC,OAAO;QACT,KAAK,SAAS,CAAC;QACf;YACE,OAAO,CAAC,KAAK,CAAC,oCAAoC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YAClE,KAAK,EAAE,CAAC;IACZ,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"scope.js","sourceRoot":"","sources":["../../src/cli/scope.ts"],"names":[],"mappings":"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"}
@@ -1,18 +1,22 @@
1
1
  /**
2
- * `cairn sensor-run` — invoked by the cairn git hooks (pre-commit,
3
- * commit-msg).
2
+ * `cairn sensor-run` — the live sensor gate. Invoked by the cairn git hooks
3
+ * (pre-commit, commit-msg) and by CI.
4
4
  *
5
- * On `--staged` this runs the **component registry check** against staged
6
- * files and blocks the commit (exit 1) on any hard finding — missing `@cairn`
7
- * header, missing required tag, invalid category, or duplicate name. This is
8
- * the first real execution path for the pre-commit gate (it was previously a
9
- * no-op stub). Soft findings (export mismatch, alias collision) print as
10
- * warnings without blocking.
5
+ * Modes:
6
+ * --staged pre-commit. Runs the component-registry check + the
7
+ * sensor sweep (Layer A stub catalog, Layer C
8
+ * structural, decision-assertions) over the STAGED
9
+ * tree. Blocks the commit (exit 1) on any hard
10
+ * finding; soft findings print as warnings.
11
+ * --diff <range> CI. Runs the same sweep over a committed range
12
+ * (e.g. `origin/main..HEAD`). Report-only unless
13
+ * `--strict` is also passed.
14
+ * --strict with --diff: exit 1 on any hard finding.
15
+ * --commit-msg <path> commit-msg hook. There are no commit-message
16
+ * sensors by design, so this is an intentional clean
17
+ * pass (kept so already-installed hooks don't error).
11
18
  *
12
- * `--commit-msg` is reserved for future commit-message sensors; it passes
13
- * cleanly today.
14
- *
15
- * Exits 0 on a clean tree or a repo with no component config; exits 1 only on
16
- * a hard component finding.
19
+ * Exits 0 on a clean tree or a repo with no component config. Exits 1 only on
20
+ * a hard finding (component or sensor) at a blocking gate.
17
21
  */
18
22
  export declare function sensorRunCli(argv: string[]): Promise<void>;
@@ -1,27 +1,33 @@
1
1
  /**
2
- * `cairn sensor-run` — invoked by the cairn git hooks (pre-commit,
3
- * commit-msg).
2
+ * `cairn sensor-run` — the live sensor gate. Invoked by the cairn git hooks
3
+ * (pre-commit, commit-msg) and by CI.
4
4
  *
5
- * On `--staged` this runs the **component registry check** against staged
6
- * files and blocks the commit (exit 1) on any hard finding — missing `@cairn`
7
- * header, missing required tag, invalid category, or duplicate name. This is
8
- * the first real execution path for the pre-commit gate (it was previously a
9
- * no-op stub). Soft findings (export mismatch, alias collision) print as
10
- * warnings without blocking.
5
+ * Modes:
6
+ * --staged pre-commit. Runs the component-registry check + the
7
+ * sensor sweep (Layer A stub catalog, Layer C
8
+ * structural, decision-assertions) over the STAGED
9
+ * tree. Blocks the commit (exit 1) on any hard
10
+ * finding; soft findings print as warnings.
11
+ * --diff <range> CI. Runs the same sweep over a committed range
12
+ * (e.g. `origin/main..HEAD`). Report-only unless
13
+ * `--strict` is also passed.
14
+ * --strict with --diff: exit 1 on any hard finding.
15
+ * --commit-msg <path> commit-msg hook. There are no commit-message
16
+ * sensors by design, so this is an intentional clean
17
+ * pass (kept so already-installed hooks don't error).
11
18
  *
12
- * `--commit-msg` is reserved for future commit-message sensors; it passes
13
- * cleanly today.
14
- *
15
- * Exits 0 on a clean tree or a repo with no component config; exits 1 only on
16
- * a hard component finding.
19
+ * Exits 0 on a clean tree or a repo with no component config. Exits 1 only on
20
+ * a hard finding (component or sensor) at a blocking gate.
17
21
  */
18
22
  import { execFileSync } from "node:child_process";
19
23
  import { existsSync } from "node:fs";
20
24
  import { join, resolve } from "node:path";
21
- import { runComponentCheck } from "@isaacriehm/cairn-core";
25
+ import { getRangeDiff, getStagedDiff, runComponentCheck, runSensorsOnDiff, } from "@isaacriehm/cairn-core";
22
26
  function findRepoRoot(start) {
23
27
  let cur = resolve(start);
24
28
  for (let i = 0; i < 80; i++) {
29
+ // Repo-root discovery probe: physical in-repo `.cairn/` (committed mode).
30
+ // Literal join is intentional — ghost resolves via the global registry.
25
31
  if (existsSync(join(cur, ".cairn")))
26
32
  return cur;
27
33
  const parent = resolve(cur, "..");
@@ -47,11 +53,24 @@ function stagedFiles(repoRoot) {
47
53
  function parseFlags(argv) {
48
54
  let trigger = null;
49
55
  let commitMsgPath = null;
56
+ let diffRange = null;
57
+ let strict = false;
50
58
  for (let i = 0; i < argv.length; i++) {
51
59
  const a = argv[i];
52
60
  if (a === "--staged") {
53
61
  trigger = "pre-commit";
54
62
  }
63
+ else if (a === "--strict") {
64
+ strict = true;
65
+ }
66
+ else if (a === "--diff") {
67
+ trigger = "diff";
68
+ const next = argv[i + 1];
69
+ if (typeof next === "string" && !next.startsWith("--")) {
70
+ diffRange = next;
71
+ i += 1;
72
+ }
73
+ }
55
74
  else if (a === "--commit-msg") {
56
75
  trigger = "commit-msg";
57
76
  const next = argv[i + 1];
@@ -63,13 +82,22 @@ function parseFlags(argv) {
63
82
  }
64
83
  if (trigger === null)
65
84
  return null;
66
- return { trigger, commitMsgPath };
85
+ return { trigger, commitMsgPath, diffRange, strict };
86
+ }
87
+ /** Print every sensor finding, ERROR for hard / WARN for soft. */
88
+ function printFindings(sweep) {
89
+ for (const r of sweep.results) {
90
+ for (const f of r.findings) {
91
+ const tag = f.severity === "hard" ? "ERROR" : "WARN ";
92
+ console.error(`${tag} ${f.sensor_id}: ${f.message}`);
93
+ }
94
+ }
67
95
  }
68
96
  export async function sensorRunCli(argv) {
69
97
  const flags = parseFlags(argv);
70
98
  if (flags === null) {
71
- console.error("Usage: cairn sensor-run --staged | --commit-msg <path>\n" +
72
- "Invoked by the cairn pre-commit / commit-msg git hooks.");
99
+ console.error("Usage: cairn sensor-run --staged | --diff <range> [--strict] | --commit-msg <path>\n" +
100
+ "Invoked by the cairn pre-commit / commit-msg git hooks and by CI.");
73
101
  process.exit(2);
74
102
  }
75
103
  const repoRoot = findRepoRoot(process.cwd());
@@ -77,27 +105,45 @@ export async function sensorRunCli(argv) {
77
105
  // Not a cairn-adopted repo — hooks call us defensively, exit clean.
78
106
  process.exit(0);
79
107
  }
80
- // commit-msg has no sensors wired yet — clean pass.
108
+ // commit-msg: no commit-message sensors by design — clean pass.
81
109
  if (flags.trigger === "commit-msg") {
82
110
  process.exit(0);
83
111
  }
84
- // ── pre-commit: component registry check on staged files ──────────────
85
- const staged = stagedFiles(repoRoot);
86
- const result = runComponentCheck(repoRoot, { files: staged });
87
- if (result.findings.length === 0) {
112
+ // ── CI diff sweep ─────────────────────────────────────────────────────
113
+ if (flags.trigger === "diff") {
114
+ const range = flags.diffRange ?? "origin/main..HEAD";
115
+ const diff = await getRangeDiff(repoRoot, range);
116
+ const sweep = await runSensorsOnDiff({ repoRoot, diff, runId: `ci:${range}` });
117
+ printFindings(sweep);
118
+ if (sweep.hard_failures > 0 && flags.strict) {
119
+ console.error(`\nCairn sensor sweep FAILED — ${sweep.hard_failures} hard finding(s) over ${range}.`);
120
+ process.exit(1);
121
+ }
88
122
  process.exit(0);
89
123
  }
90
- for (const f of result.findings) {
124
+ // ── pre-commit: component check + sensor sweep on the staged tree ──────
125
+ const staged = stagedFiles(repoRoot);
126
+ const componentResult = runComponentCheck(repoRoot, { files: staged });
127
+ let hardFailures = componentResult.hardFailures;
128
+ for (const f of componentResult.findings) {
91
129
  const tag = f.severity === "hard" ? "ERROR" : "WARN ";
92
130
  console.error(`${tag} component: ${f.message}`);
93
131
  }
94
- if (result.hardFailures > 0) {
95
- console.error(`\nCairn component check FAILED — ${result.hardFailures} hard finding(s). ` +
96
- "Fix the @cairn headers, then re-commit (or `git commit --no-verify` to bypass; " +
132
+ const stagedDiff = await getStagedDiff(repoRoot);
133
+ const sweep = await runSensorsOnDiff({
134
+ repoRoot,
135
+ diff: stagedDiff,
136
+ runId: "pre-commit",
137
+ });
138
+ printFindings(sweep);
139
+ hardFailures += sweep.hard_failures;
140
+ if (hardFailures > 0) {
141
+ console.error(`\nCairn pre-commit gate FAILED — ${hardFailures} hard finding(s). ` +
142
+ "Fix them, then re-commit (or `git commit --no-verify` to bypass; " +
97
143
  "the bypass is flagged at the next session and caught by CI).");
98
144
  process.exit(1);
99
145
  }
100
- // soft-only — surface as warnings, don't block.
146
+ // soft-only — surfaced as warnings above, don't block.
101
147
  process.exit(0);
102
148
  }
103
149
  //# sourceMappingURL=sensor-run.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"sensor-run.js","sourceRoot":"","sources":["../../src/cli/sensor-run.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sensor-run.js","sourceRoot":"","sources":["../../src/cli/sensor-run.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EACL,YAAY,EACZ,aAAa,EACb,iBAAiB,EACjB,gBAAgB,GAEjB,MAAM,wBAAwB,CAAC;AAIhC,SAAS,YAAY,CAAC,KAAa;IACjC,IAAI,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;IACzB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;QAC5B,0EAA0E;QAC1E,wEAAwE;QACxE,IAAI,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;YAAE,OAAO,GAAG,CAAC;QAChD,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAClC,IAAI,MAAM,KAAK,GAAG;YAAE,OAAO,IAAI,CAAC;QAChC,GAAG,GAAG,MAAM,CAAC;IACf,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,yEAAyE;AACzE,SAAS,WAAW,CAAC,QAAgB;IACnC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,YAAY,CACtB,KAAK,EACL,CAAC,MAAM,EAAE,UAAU,EAAE,aAAa,EAAE,oBAAoB,EAAE,IAAI,CAAC,EAC/D,EAAE,GAAG,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,GAAG,IAAI,GAAG,IAAI,EAAE,CAC/C,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QACnB,OAAO,GAAG;aACP,KAAK,CAAC,IAAI,CAAC;aACX,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;aAC3B,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IACzC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,SAAS,UAAU,CAAC,IAAc;IAMhC,IAAI,OAAO,GAAmB,IAAI,CAAC;IACnC,IAAI,aAAa,GAAkB,IAAI,CAAC;IACxC,IAAI,SAAS,GAAkB,IAAI,CAAC;IACpC,IAAI,MAAM,GAAG,KAAK,CAAC;IACnB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,IAAI,CAAC,KAAK,UAAU,EAAE,CAAC;YACrB,OAAO,GAAG,YAAY,CAAC;QACzB,CAAC;aAAM,IAAI,CAAC,KAAK,UAAU,EAAE,CAAC;YAC5B,MAAM,GAAG,IAAI,CAAC;QAChB,CAAC;aAAM,IAAI,CAAC,KAAK,QAAQ,EAAE,CAAC;YAC1B,OAAO,GAAG,MAAM,CAAC;YACjB,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YACzB,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;gBACvD,SAAS,GAAG,IAAI,CAAC;gBACjB,CAAC,IAAI,CAAC,CAAC;YACT,CAAC;QACH,CAAC;aAAM,IAAI,CAAC,KAAK,cAAc,EAAE,CAAC;YAChC,OAAO,GAAG,YAAY,CAAC;YACvB,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YACzB,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;gBACvD,aAAa,GAAG,IAAI,CAAC;gBACrB,CAAC,IAAI,CAAC,CAAC;YACT,CAAC;QACH,CAAC;IACH,CAAC;IACD,IAAI,OAAO,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAClC,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC;AACvD,CAAC;AAED,kEAAkE;AAClE,SAAS,aAAa,CAAC,KAAwB;IAC7C,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;QAC9B,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC;YAC3B,MAAM,GAAG,GAAG,CAAC,CAAC,QAAQ,KAAK,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC;YACtD,OAAO,CAAC,KAAK,CAAC,GAAG,GAAG,IAAI,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;QACvD,CAAC;IACH,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,IAAc;IAC/C,MAAM,KAAK,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;IAC/B,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QACnB,OAAO,CAAC,KAAK,CACX,sFAAsF;YACpF,mEAAmE,CACtE,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,QAAQ,GAAG,YAAY,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IAC7C,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;QACtB,oEAAoE;QACpE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,gEAAgE;IAChE,IAAI,KAAK,CAAC,OAAO,KAAK,YAAY,EAAE,CAAC;QACnC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,yEAAyE;IACzE,IAAI,KAAK,CAAC,OAAO,KAAK,MAAM,EAAE,CAAC;QAC7B,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS,IAAI,mBAAmB,CAAC;QACrD,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;QACjD,MAAM,KAAK,GAAG,MAAM,gBAAgB,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,KAAK,EAAE,EAAE,CAAC,CAAC;QAC/E,aAAa,CAAC,KAAK,CAAC,CAAC;QACrB,IAAI,KAAK,CAAC,aAAa,GAAG,CAAC,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;YAC5C,OAAO,CAAC,KAAK,CACX,iCAAiC,KAAK,CAAC,aAAa,yBAAyB,KAAK,GAAG,CACtF,CAAC;YACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,0EAA0E;IAC1E,MAAM,MAAM,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC;IACrC,MAAM,eAAe,GAAG,iBAAiB,CAAC,QAAQ,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;IAEvE,IAAI,YAAY,GAAG,eAAe,CAAC,YAAY,CAAC;IAChD,KAAK,MAAM,CAAC,IAAI,eAAe,CAAC,QAAQ,EAAE,CAAC;QACzC,MAAM,GAAG,GAAG,CAAC,CAAC,QAAQ,KAAK,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC;QACtD,OAAO,CAAC,KAAK,CAAC,GAAG,GAAG,eAAe,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;IAClD,CAAC;IAED,MAAM,UAAU,GAAG,MAAM,aAAa,CAAC,QAAQ,CAAC,CAAC;IACjD,MAAM,KAAK,GAAG,MAAM,gBAAgB,CAAC;QACnC,QAAQ;QACR,IAAI,EAAE,UAAU;QAChB,KAAK,EAAE,YAAY;KACpB,CAAC,CAAC;IACH,aAAa,CAAC,KAAK,CAAC,CAAC;IACrB,YAAY,IAAI,KAAK,CAAC,aAAa,CAAC;IAEpC,IAAI,YAAY,GAAG,CAAC,EAAE,CAAC;QACrB,OAAO,CAAC,KAAK,CACX,oCAAoC,YAAY,oBAAoB;YAClE,mEAAmE;YACnE,8DAA8D,CACjE,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,uDAAuD;IACvD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@isaacriehm/cairn",
3
- "version": "0.19.1",
3
+ "version": "0.22.1",
4
4
  "description": "Cairn — state + context-loading layer for AI coding agents.",
5
5
  "author": "Isaac Riehm",
6
6
  "license": "MIT",
@@ -37,7 +37,7 @@
37
37
  "dependencies": {
38
38
  "simple-git": "^3.36.0",
39
39
  "yaml": "^2.9.0",
40
- "@isaacriehm/cairn-core": "0.19.1"
40
+ "@isaacriehm/cairn-core": "0.22.1"
41
41
  },
42
42
  "devDependencies": {
43
43
  "@types/node": "^25.9.2",
@@ -47,16 +47,34 @@
47
47
  },
48
48
  "scripts": {
49
49
  "build": "tsc -b",
50
- "typecheck": "tsc -b --noEmit",
50
+ "typecheck": "tsc -b",
51
51
  "clean": "rm -rf dist *.tsbuildinfo",
52
52
  "dev": "tsx src/cli/index.ts",
53
53
  "check:layout": "tsx scripts/check-layout.ts",
54
+ "smoke:cairn-home": "tsx scripts/smoke-cairn-home.ts",
55
+ "smoke:cli-path": "tsx scripts/smoke-cli-path.ts",
56
+ "smoke:ghost-init": "tsx scripts/smoke-ghost-init.ts",
57
+ "smoke:ghost-gc": "tsx scripts/smoke-ghost-gc.ts",
58
+ "smoke:ghost-hooks": "tsx scripts/smoke-ghost-hooks.ts",
59
+ "smoke:ghost-adopt-mcp": "tsx scripts/smoke-ghost-adopt-mcp.ts",
60
+ "smoke:hooks-clobber": "tsx scripts/smoke-hooks-clobber.ts",
61
+ "smoke:ghost-reanchor": "tsx scripts/smoke-ghost-reanchor.ts",
62
+ "smoke:ghost-backup": "tsx scripts/smoke-ghost-backup.ts",
63
+ "smoke:ghost-components": "tsx scripts/smoke-ghost-components.ts",
64
+ "smoke:ghost-freshness": "tsx scripts/smoke-ghost-freshness.ts",
65
+ "smoke:ghost-reconfirm": "tsx scripts/smoke-ghost-reconfirm.ts",
66
+ "smoke:ghost-cleanups": "tsx scripts/smoke-ghost-cleanups.ts",
67
+ "smoke:lens-ghost": "tsx scripts/smoke-lens-ghost.ts",
54
68
  "smoke:gc": "tsx scripts/smoke-gc.ts",
55
69
  "smoke:init": "tsx scripts/smoke-init.ts",
56
70
  "smoke:session-start": "tsx scripts/smoke-session-start.ts",
57
71
  "smoke:status-line": "tsx scripts/smoke-status-line.ts",
58
72
  "smoke:handoff": "tsx scripts/smoke-handoff.ts",
59
73
  "smoke:scope-index": "tsx scripts/smoke-scope-index.ts",
74
+ "smoke:config-globs": "tsx scripts/smoke-config-globs.ts",
75
+ "smoke:sensor-gate": "tsx scripts/smoke-sensor-gate.ts",
76
+ "smoke:migrate": "tsx scripts/smoke-migrate.ts",
77
+ "smoke:update-check": "tsx scripts/smoke-update-check.ts",
60
78
  "smoke:read-enrich": "tsx scripts/smoke-read-enrich.ts",
61
79
  "smoke:ingestion-baseline": "tsx scripts/smoke-ingestion-baseline.ts",
62
80
  "smoke:lock": "tsx scripts/smoke-lock.ts",
@@ -81,9 +99,7 @@
81
99
  "smoke:phase-ready-surface": "tsx scripts/smoke-phase-ready-surface.ts",
82
100
  "smoke:mission-phase-brief": "tsx scripts/smoke-mission-phase-brief.ts",
83
101
  "smoke:id-content-addressed": "tsx scripts/smoke-id-content-addressed.ts",
84
- "smoke:attention-serve": "tsx scripts/smoke-attention-serve.ts",
85
102
  "smoke:topic-index": "tsx scripts/smoke-topic-index.ts",
86
- "smoke:propose-decision": "tsx scripts/smoke-propose-decision.ts",
87
103
  "smoke:tag-cli": "tsx scripts/smoke-tag-cli.ts",
88
104
  "smoke:llm-prompt-eval": "tsx scripts/smoke-llm-prompt-eval.ts",
89
105
  "smoke:llm-detect-components": "tsx scripts/smoke-llm-detect-components.ts",
@@ -105,7 +121,8 @@
105
121
  "smoke:rebuild-derived": "tsx scripts/smoke-rebuild-derived.ts",
106
122
  "smoke:claude-rule-import": "tsx scripts/smoke-claude-rule-import.ts",
107
123
  "smoke:components": "tsx scripts/smoke-components.ts",
108
- "smokes": "pnpm smoke:rebuild-derived && pnpm smoke:claude-rule-import && pnpm smoke:components && pnpm smoke:plugin-layout && pnpm smoke:resolve-attention && pnpm smoke:stop-hook && pnpm smoke:events && pnpm smoke:session-state && pnpm smoke:status-line && pnpm smoke:session-start && pnpm smoke:handoff && pnpm smoke:scope-index && pnpm smoke:read-enrich && pnpm smoke:init && pnpm smoke:ingestion-baseline && pnpm smoke:gc && pnpm smoke:lock && pnpm smoke:source-comments && pnpm smoke:rules-merge && pnpm smoke:join && pnpm smoke:bypass-detection && pnpm smoke:bootstrap-guard && pnpm smoke:e2e-adoption && pnpm smoke:e2e-daily-flow && pnpm smoke:plugin-bundle && pnpm smoke:init-phases-state && pnpm smoke:init-phases-all && pnpm smoke:init-mcp-tools && pnpm smoke:init-progress-heartbeat && pnpm smoke:stop-debounce && pnpm smoke:phase-ready-surface && pnpm smoke:mission-phase-brief && pnpm smoke:curator-validate && pnpm smoke:essay-shape-detector && pnpm smoke:entity-orphan && pnpm smoke:repo-root-anchor && pnpm smoke:bug-mine-0.13.3 && pnpm smoke:bug-mine-0.13.5 && pnpm smoke:bug-mine-0.13.8 && pnpm smoke:bug-mine-0.13.10",
124
+ "smoke:units-multilang": "tsx scripts/smoke-units-multilang.ts",
125
+ "smokes": "pnpm smoke:cairn-home && pnpm smoke:cli-path && pnpm smoke:ghost-init && pnpm smoke:ghost-gc && pnpm smoke:ghost-hooks && pnpm smoke:ghost-adopt-mcp && pnpm smoke:hooks-clobber && pnpm smoke:ghost-reanchor && pnpm smoke:ghost-backup && pnpm smoke:ghost-components && pnpm smoke:ghost-freshness && pnpm smoke:ghost-reconfirm && pnpm smoke:ghost-cleanups && pnpm smoke:lens-ghost && pnpm smoke:rebuild-derived && pnpm smoke:claude-rule-import && pnpm smoke:components && pnpm smoke:units-multilang && pnpm smoke:plugin-layout && pnpm smoke:resolve-attention && pnpm smoke:stop-hook && pnpm smoke:events && pnpm smoke:session-state && pnpm smoke:status-line && pnpm smoke:session-start && pnpm smoke:handoff && pnpm smoke:scope-index && pnpm smoke:config-globs && pnpm smoke:sensor-gate && pnpm smoke:migrate && pnpm smoke:update-check && pnpm smoke:read-enrich && pnpm smoke:init && pnpm smoke:ingestion-baseline && pnpm smoke:gc && pnpm smoke:lock && pnpm smoke:source-comments && pnpm smoke:rules-merge && pnpm smoke:join && pnpm smoke:bypass-detection && pnpm smoke:bootstrap-guard && pnpm smoke:e2e-adoption && pnpm smoke:e2e-daily-flow && pnpm smoke:plugin-bundle && pnpm smoke:init-phases-state && pnpm smoke:init-phases-all && pnpm smoke:init-mcp-tools && pnpm smoke:init-progress-heartbeat && pnpm smoke:stop-debounce && pnpm smoke:phase-ready-surface && pnpm smoke:mission-phase-brief && pnpm smoke:curator-validate && pnpm smoke:essay-shape-detector && pnpm smoke:entity-orphan && pnpm smoke:repo-root-anchor && pnpm smoke:bug-mine-0.13.3 && pnpm smoke:bug-mine-0.13.5 && pnpm smoke:bug-mine-0.13.8 && pnpm smoke:bug-mine-0.13.10",
109
126
  "smokes:all": "pnpm run \"/^smoke:/\""
110
127
  }
111
128
  }