etymd 0.12.0 → 0.14.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 (35) hide show
  1. package/CHANGELOG.md +112 -0
  2. package/dist/{approve-PP2QJQ3Y.js → approve-QDOH2E7V.js} +5 -5
  3. package/dist/audit-42OHF7ON.js +10 -0
  4. package/dist/{brief-GDLJEG6X.js → brief-ZUQK3CFL.js} +5 -5
  5. package/dist/{chunk-YFNRDXUY.js → chunk-623W6KVC.js} +1 -1
  6. package/dist/{chunk-5BVKFJWM.js → chunk-HI7NWPRA.js} +79 -4
  7. package/dist/{chunk-2VLNI3L2.js → chunk-HOR4M6EC.js} +1 -1
  8. package/dist/{chunk-MTVEJ33D.js → chunk-HWC6PKJM.js} +2 -2
  9. package/dist/{chunk-O3PHW4OP.js → chunk-LT7JMVV3.js} +127 -11
  10. package/dist/{chunk-DWL2IKZH.js → chunk-P6ATKV2R.js} +65 -3
  11. package/dist/{chunk-SWA4NQHB.js → chunk-PAMWS665.js} +2 -2
  12. package/dist/{chunk-HRJJQCMT.js → chunk-UFNETE6P.js} +69 -20
  13. package/dist/{chunk-LSZGCKIQ.js → chunk-YQZDYDAK.js} +1 -1
  14. package/dist/cli.js +20 -20
  15. package/dist/{config-XAH6PA5G.js → config-724Y3IOB.js} +1 -2
  16. package/dist/{context-F63RSIBH.js → context-JGKU4M7Z.js} +2 -4
  17. package/dist/doctor-CE5SD4JW.js +17 -0
  18. package/dist/{fleet-5NVOUIZD.js → fleet-F3XDEDCV.js} +10 -12
  19. package/dist/{gates-OS5V3P4C.js → gates-F4YPKWJR.js} +6 -7
  20. package/dist/generate-KEX75XNG.js +5 -0
  21. package/dist/index.d.ts +9 -1
  22. package/dist/index.js +223 -40
  23. package/dist/{init-EKQ33WYS.js → init-AHA7VRRI.js} +14 -13
  24. package/dist/ledger-T54JDHGP.js +6 -0
  25. package/dist/scan-QRTH6HAP.js +5 -0
  26. package/dist/{scan-XS4JPS7J.js → scan-TVX3FKK4.js} +5 -5
  27. package/dist/{screen-UF7VZ26C.js → screen-E4FC7W5N.js} +5 -4
  28. package/package.json +1 -1
  29. package/dist/audit-BXHJUTMJ.js +0 -12
  30. package/dist/chunk-F75Q43BC.js +0 -59
  31. package/dist/chunk-JHZ2BN4U.js +0 -67
  32. package/dist/doctor-7SLSUSVK.js +0 -19
  33. package/dist/generate-PMCP37DC.js +0 -6
  34. package/dist/ledger-4FOZ5HAB.js +0 -5
  35. package/dist/scan-N4BKVL5F.js +0 -5
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
- import { DEFAULT_CONFIG } from './chunk-DWL2IKZH.js';
3
- import { PACK_VERSION } from './chunk-LSZGCKIQ.js';
2
+ import { DEFAULT_CONFIG } from './chunk-P6ATKV2R.js';
3
+ import { PACK_VERSION } from './chunk-YQZDYDAK.js';
4
4
  import { readText, pathExists } from './chunk-4VPBP6K6.js';
5
5
  import path from 'path';
6
6
  import { createHash } from 'crypto';
@@ -132,16 +132,37 @@ ${[
132
132
  "md"
133
133
  );
134
134
  }
135
- var CONTENT_GATE_RESOLUTION = `GATE="\${CONTENT_GATE:-$(if [ -x ./dist/cli.js ]; then echo ./dist/cli.js; else command -v etymd || true; fi)}"`;
135
+ var SELF_PACKAGE_NAME = "etymd";
136
+ function isSelfBuildRepo(facts) {
137
+ return facts.publishRoute !== "none" && facts.name === SELF_PACKAGE_NAME;
138
+ }
139
+ function contentGateResolution(selfBuild) {
140
+ if (!selfBuild) return `GATE="\${CONTENT_GATE:-$(command -v etymd || true)}"`;
141
+ return `GATE="\${CONTENT_GATE:-$(if [ -x ./dist/cli.js ]; then echo ./dist/cli.js; else command -v etymd || true; fi)}"`;
142
+ }
143
+ function contentScreenCall(opts) {
144
+ const { args, envVar, blocking, indent } = opts;
145
+ const hint = `etymd: this checker does not understand 'screen' (needs etymd 0.11+) \u2014 upgrade it, or set ${envVar} to a checker that does.`;
146
+ return [
147
+ `${indent}if ! "$GATE" screen ${args}; then`,
148
+ `${indent} "$GATE" screen --help >/dev/null 2>&1 ||`,
149
+ `${indent} echo "${hint}" >&2`,
150
+ ...blocking ? [`${indent} exit 1`] : [],
151
+ `${indent}fi`
152
+ ].join("\n");
153
+ }
136
154
  function localHookCall(hook) {
137
155
  return `# Repo-owned checks. This file is generated and will be overwritten; \`.githooks/${hook}.local\`
138
156
  # is yours \u2014 etymd never reads, writes, or regenerates it. Put project-specific guards there.
157
+ # A guard running tests that build fixture repositories should scrub git's exported GIT_* names
158
+ # first \u2014 a child git inherits them and ignores its cwd, so the suite would hit the real repo:
159
+ # env $(env | grep -o '^GIT_[A-Za-z0-9_]*' | sed 's/^/-u /') <your command>
139
160
  LOCAL="$(dirname "$0")/${hook}.local"
140
161
  if [ -x "$LOCAL" ]; then
141
162
  "$LOCAL" "$@" || exit 1
142
163
  fi`;
143
164
  }
144
- function generatePreCommitHook() {
165
+ function generatePreCommitHook(selfBuild = false) {
145
166
  return stampGenerated(`#!/usr/bin/env sh
146
167
  # etymd: process gate. Cheap, locally-knowable checks belong here (fast, blocks the commit).
147
168
 
@@ -153,9 +174,9 @@ ${localHookCall("pre-commit")}
153
174
  # commit anywhere, active only where you opted in.
154
175
  #
155
176
  # Bypass, with a reason: git commit --no-verify
156
- ${CONTENT_GATE_RESOLUTION}
177
+ ${contentGateResolution(selfBuild)}
157
178
  if [ -x "$GATE" ]; then
158
- "$GATE" screen --staged || exit 1
179
+ ${contentScreenCall({ args: "--staged", envVar: "CONTENT_GATE", blocking: true, indent: " " })}
159
180
  fi
160
181
 
161
182
  exit 0
@@ -210,7 +231,7 @@ function generateCommitMsgHook(gates) {
210
231
  # Bypass, with a reason: git commit --no-verify
211
232
  GATE="\${COMMIT_MSG_GATE:-$(command -v etymd || true)}"
212
233
  if [ -x "$GATE" ]; then
213
- "$GATE" screen --message "$1" || exit 1
234
+ ${contentScreenCall({ args: '--message "$1"', envVar: "COMMIT_MSG_GATE", blocking: true, indent: " " })}
214
235
  fi
215
236
  ${format}
216
237
  ${localHookCall("commit-msg")}
@@ -221,11 +242,24 @@ exit 0
221
242
  function shellcheckStep() {
222
243
  return `
223
244
  # Shell correctness. Scripts are discovered by shebang over TRACKED files at push time, so a
224
- # script added later is covered without regenerating this hook.
245
+ # script added later is covered without regenerating this hook. zsh is NOT in the checked set:
246
+ # the checker cannot parse it (SC1071 is a parser-level error no inline directive can silence),
247
+ # so checking it would fail every push on the parser, not on the script. Excluded \u2014 and said so
248
+ # at run time below, because a coverage hole that is silent is indistinguishable from coverage.
249
+ #
250
+ # "the checker", not its name, on purpose: a comment whose first word is that name is read as
251
+ # a DIRECTIVE, and an unparseable directive is itself an error (SC1072/SC1073). A hook that
252
+ # explains why it skips a shell dialect must not break the checker while doing it.
225
253
  if command -v shellcheck >/dev/null 2>&1; then
226
254
  scripts=$(git ls-files -z \\
227
- | xargs -0 -I{} sh -c 'head -1 "{}" 2>/dev/null | grep -qE "^#!.*[/ ](ba|da|z)?sh( |$)" && echo "{}"' \\
255
+ | xargs -0 -I{} sh -c 'head -1 "{}" 2>/dev/null | grep -qE "^#!.*[/ ](ba|da)?sh( |$)" && echo "{}"' \\
256
+ | sort)
257
+ zsh_scripts=$(git ls-files -z \\
258
+ | xargs -0 -I{} sh -c 'head -1 "{}" 2>/dev/null | grep -qE "^#!.*[/ ]zsh( |$)" && echo "{}"' \\
228
259
  | sort)
260
+ if [ -n "$zsh_scripts" ]; then
261
+ echo "\u203A shellcheck: $(printf '%s\\n' "$zsh_scripts" | wc -l | tr -d ' ') zsh script(s) excluded \u2014 shellcheck cannot parse zsh (SC1071); not checked, not failed"
262
+ fi
229
263
  if [ -n "$scripts" ]; then
230
264
  echo "\u203A shellcheck ($(printf '%s\\n' "$scripts" | wc -l | tr -d ' ') scripts, blocking at severity=warning)"
231
265
  printf '%s\\n' "$scripts" | xargs shellcheck -S warning || {
@@ -245,7 +279,15 @@ else
245
279
  echo "\u203A shellcheck skipped (not on PATH) \u2014 install it to gate this repo's shell scripts"
246
280
  fi`;
247
281
  }
248
- function generatePrePushHook(facts, gates) {
282
+ var SCRUBBED_RUNNER = `
283
+ # Gate steps run scrubbed of git's exported GIT_* names: a child git that inherits them ignores
284
+ # its cwd, so a hook-run suite building fixture repositories would operate on the real repo.
285
+ run_gate() (
286
+ # shellcheck disable=SC2046 # word-splitting is the point: one -u per exported GIT_* name
287
+ env $(env | grep -o '^GIT_[A-Za-z0-9_]*' | sed 's/^/-u /') "$@"
288
+ )
289
+ `;
290
+ function generatePrePushHook(facts, gates, selfBuild = false) {
249
291
  const run = runPrefix(facts.packageManager);
250
292
  const c = facts.commands;
251
293
  const candidates = gates?.commands?.length ? gates.commands : [c.formatCheck, c.typecheck, c.lint];
@@ -254,8 +296,9 @@ function generatePrePushHook(facts, gates) {
254
296
  (key) => Boolean(key) && (allowed.has(key) || isSafeGateCommand(c.raw[key]))
255
297
  ).map((key) => `${run} ${key}`);
256
298
  const shellStep = facts.shell?.scripts ? shellcheckStep() : "";
299
+ const runner = steps.length ? SCRUBBED_RUNNER : "";
257
300
  const body = steps.length ? steps.map((s) => `echo "\u203A ${s}"
258
- ${s} || exit 1`).join("\n") : shellStep ? (
301
+ run_gate ${s} || exit 1`).join("\n") : shellStep ? (
259
302
  // A repo whose executable surface is shell HAS a correctness command — it just is not in
260
303
  // package.json. Claiming "none detected" beside a step that is about to run would be the
261
304
  // tool contradicting itself.
@@ -272,22 +315,22 @@ fi`;
272
315
  return stampGenerated(`#!/usr/bin/env sh
273
316
  # etymd: correctness gate. Mirrors CI cheapest-first; blocks the push on any failure.
274
317
 
275
- ${localHookCall("pre-push")}
318
+ ${localHookCall("pre-push")}${runner}
276
319
  ${body}${shellStep}
277
320
  ${auditStep}
278
321
 
279
322
  # Content screen, second pass \u2014 the WHOLE TREE rather than one diff. Catches anything committed
280
323
  # with --no-verify and anything a rebase or merge brought in from elsewhere. Advisory here (it
281
324
  # never blocks the push): the blocking decision belongs at commit time, where the fix is cheap.
282
- ${CONTENT_GATE_RESOLUTION}
325
+ ${contentGateResolution(selfBuild)}
283
326
  if [ -x "$GATE" ]; then
284
- "$GATE" screen --tree --advisory || true
327
+ ${contentScreenCall({ args: "--tree --advisory", envVar: "CONTENT_GATE", blocking: false, indent: " " })}
285
328
  fi
286
329
 
287
330
  exit 0
288
331
  `);
289
332
  }
290
- function generateArtifactCheckScript() {
333
+ function generateArtifactCheckScript(selfBuild = false) {
291
334
  return stampGenerated(`#!/usr/bin/env sh
292
335
  # etymd: content screen \u2014 the published ARTIFACT, not the repository.
293
336
  #
@@ -298,7 +341,7 @@ function generateArtifactCheckScript() {
298
341
  # .etymd-screen-allow entries (with provenance) if you must exempt a string.
299
342
  set -eu
300
343
 
301
- ${CONTENT_GATE_RESOLUTION}
344
+ ${contentGateResolution(selfBuild)}
302
345
  [ -x "$GATE" ] || { echo "\u203A artifact-check: no checker installed \u2014 skipping."; exit 0; }
303
346
 
304
347
  WORK=$(mktemp -d)
@@ -311,7 +354,7 @@ if [ -f package.json ]; then
311
354
  tar -xzf "$WORK"/*.tgz -C "$WORK" 2>/dev/null || true
312
355
  fi
313
356
 
314
- "$GATE" screen --dir "$WORK" || exit 1
357
+ ${contentScreenCall({ args: '--dir "$WORK"', envVar: "CONTENT_GATE", blocking: true, indent: "" })}
315
358
  exit 0
316
359
  `);
317
360
  }
@@ -368,7 +411,13 @@ async function planWorkflow(root, facts, opts) {
368
411
  }
369
412
  if (opts.gates) {
370
413
  const existingPrePush = await readText(path.join(root, ".githooks", "pre-push"));
371
- await add(".githooks/pre-commit", generatePreCommitHook(), "Process gate (pre-commit)", true);
414
+ const selfBuild = isSelfBuildRepo(facts);
415
+ await add(
416
+ ".githooks/pre-commit",
417
+ generatePreCommitHook(selfBuild),
418
+ "Process gate (pre-commit)",
419
+ true
420
+ );
372
421
  await add(
373
422
  ".githooks/commit-msg",
374
423
  generateCommitMsgHook(opts.gateConfig),
@@ -384,14 +433,14 @@ async function planWorkflow(root, facts, opts) {
384
433
  };
385
434
  await add(
386
435
  ".githooks/pre-push",
387
- generatePrePushHook(facts, gateConfig),
436
+ generatePrePushHook(facts, gateConfig, selfBuild),
388
437
  "Correctness gate (pre-push)",
389
438
  true
390
439
  );
391
440
  if (opts.gateConfig?.publishGate ?? opts.publishGate ?? facts.publishable) {
392
441
  await add(
393
442
  "scripts/artifact-check.sh",
394
- generateArtifactCheckScript(),
443
+ generateArtifactCheckScript(selfBuild),
395
444
  "Content screen (published artifact)",
396
445
  true
397
446
  );
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
2
  // src/pack/version.ts
3
- var PACK_VERSION = "8";
3
+ var PACK_VERSION = "12";
4
4
 
5
5
  export { PACK_VERSION };
package/dist/cli.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { VERSION } from './chunk-YFNRDXUY.js';
2
+ import { VERSION } from './chunk-623W6KVC.js';
3
3
  import path from 'path';
4
4
  import { Command } from 'commander';
5
5
  import pc from 'picocolors';
@@ -31,7 +31,7 @@ program.command("audit").description("Verify every instruction claim against the
31
31
  "exit non-zero when findings at/above this tier exist (risk|gap|polish)"
32
32
  ).action(
33
33
  (opts, cmd) => action(async () => {
34
- const { run } = await import('./audit-BXHJUTMJ.js');
34
+ const { run } = await import('./audit-42OHF7ON.js');
35
35
  await run({
36
36
  cwd: resolveCwd(cmd),
37
37
  json: opts.json,
@@ -42,59 +42,59 @@ program.command("audit").description("Verify every instruction claim against the
42
42
  });
43
43
  })
44
44
  );
45
- program.command("init").description("Onboard the truth guard: approve the baseline; scaffold AGENTS.md only if missing").option("-y, --yes", "accept defaults without prompting (never overwrites)").action(
45
+ program.command("init").description("Onboard the truth guard: approve the baseline; scaffold AGENTS.md only if asked").option("-y, --yes", "accept defaults without prompting (never overwrites)").option("--with-agents", "also scaffold a minimal AGENTS.md where none exists (off by default)").action(
46
46
  (opts, cmd) => action(async () => {
47
- const { run } = await import('./init-EKQ33WYS.js');
48
- await run({ cwd: resolveCwd(cmd), yes: opts.yes });
47
+ const { run } = await import('./init-AHA7VRRI.js');
48
+ await run({ cwd: resolveCwd(cmd), yes: opts.yes, withAgents: opts.withAgents });
49
49
  })
50
50
  );
51
51
  program.command("approve").description(
52
52
  "Re-approve the committed baseline after intentional structural changes (non-interactive)"
53
53
  ).action(
54
54
  (_opts, cmd) => action(async () => {
55
- const { run } = await import('./approve-PP2QJQ3Y.js');
55
+ const { run } = await import('./approve-QDOH2E7V.js');
56
56
  await run({ cwd: resolveCwd(cmd) });
57
57
  })
58
58
  );
59
59
  program.command("scan").description("Deterministically reckon the project into a facts index").option("--json", "print the raw facts as JSON").option("--no-save", "do not write the .etymd cache").action(
60
60
  (opts, cmd) => action(async () => {
61
- const { run } = await import('./scan-XS4JPS7J.js');
61
+ const { run } = await import('./scan-TVX3FKK4.js');
62
62
  await run({ cwd: resolveCwd(cmd), json: opts.json, save: opts.save });
63
63
  })
64
64
  );
65
65
  program.command("doctor").description('Alias for `audit --truth` \u2014 "are the recorded instructions still true?"').option("--json", "print findings as JSON").action(
66
66
  (opts, cmd) => action(async () => {
67
- const { run } = await import('./doctor-7SLSUSVK.js');
67
+ const { run } = await import('./doctor-CE5SD4JW.js');
68
68
  await run({ cwd: resolveCwd(cmd), json: opts.json });
69
69
  })
70
70
  );
71
71
  program.command("context").description("Measure the always-loaded context footprint and flag extraction candidates").option("--json", "print the budget as JSON").action(
72
72
  (opts, cmd) => action(async () => {
73
- const { run } = await import('./context-F63RSIBH.js');
73
+ const { run } = await import('./context-JGKU4M7Z.js');
74
74
  await run({ cwd: resolveCwd(cmd), json: opts.json });
75
75
  })
76
76
  );
77
77
  program.command("brief").description("Emit a grounded briefing for the in-repo agent to complete the semantic layer").option("--human", "write a human onboarding brief instead of the agent briefing").action(
78
78
  (opts, cmd) => action(async () => {
79
- const { run } = await import('./brief-GDLJEG6X.js');
79
+ const { run } = await import('./brief-ZUQK3CFL.js');
80
80
  await run({ cwd: resolveCwd(cmd), human: opts.human });
81
81
  })
82
82
  );
83
83
  program.command("ledger").description("List every tracked finding grouped by status (open \xB7 accepted \xB7 dismissed \xB7 \u2026)").option("--json", "print the raw ledger as JSON").action(
84
84
  (opts, cmd) => action(async () => {
85
- const { list } = await import('./ledger-4FOZ5HAB.js');
85
+ const { list } = await import('./ledger-T54JDHGP.js');
86
86
  await list({ cwd: resolveCwd(cmd), json: opts.json });
87
87
  })
88
88
  );
89
89
  program.command("dismiss").argument("<finding-id>", "the finding id (from `etymd audit`) to dismiss").description("Dismiss a finding as a false positive / not applicable (hidden from future audits)").requiredOption("--reason <text>", "why it is dismissed \u2014 recorded so the decision survives").action(
90
90
  (id, opts, cmd) => action(async () => {
91
- const { dismiss } = await import('./ledger-4FOZ5HAB.js');
91
+ const { dismiss } = await import('./ledger-T54JDHGP.js');
92
92
  await dismiss({ cwd: resolveCwd(cmd), id, reason: opts.reason });
93
93
  })
94
94
  );
95
95
  program.command("accept").argument("<finding-id>", "the finding id (from `etymd audit`) to accept").description("Accept a real finding as a known trade-off (hidden from future audits)").option("--reason <text>", "optional note on why the trade-off is accepted").action(
96
96
  (id, opts, cmd) => action(async () => {
97
- const { accept } = await import('./ledger-4FOZ5HAB.js');
97
+ const { accept } = await import('./ledger-T54JDHGP.js');
98
98
  await accept({ cwd: resolveCwd(cmd), id, reason: opts.reason });
99
99
  })
100
100
  );
@@ -111,7 +111,7 @@ var fleet = program.command("fleet").description(
111
111
  "exit non-zero when findings at/above this tier exist (risk|gap|polish)"
112
112
  ).action(
113
113
  (opts, cmd) => action(async () => {
114
- const { sweep } = await import('./fleet-5NVOUIZD.js');
114
+ const { sweep } = await import('./fleet-F3XDEDCV.js');
115
115
  await sweep({
116
116
  cwd: resolveCwd(cmd),
117
117
  manifest: opts.manifest,
@@ -126,7 +126,7 @@ var fleet = program.command("fleet").description(
126
126
  );
127
127
  fleet.command("check").description("Validate the manifest pair only \u2014 no lenses: dangling mappings, duplicates, leaks").option("--manifest <file>", "the fleet manifest \u2014 required unless the cwd holds registry.json").option("--json", "print the findings as JSON (EXPERIMENTAL through 0.2.x)").action(
128
128
  (_opts, cmd) => action(async () => {
129
- const { check } = await import('./fleet-5NVOUIZD.js');
129
+ const { check } = await import('./fleet-F3XDEDCV.js');
130
130
  const opts = cmd.optsWithGlobals();
131
131
  await check({ cwd: resolveCwd(cmd), manifest: opts.manifest, json: opts.json });
132
132
  })
@@ -136,7 +136,7 @@ fleet.command("add").argument("<dir>", "directory of the project to register").d
136
136
  "public-repo | public-bound | private \u2014 mandatory for personal entries"
137
137
  ).option("-y, --yes", "skip prompts; every mandatory value must be passed as a flag").option("--manifest <file>", "the fleet manifest \u2014 required unless the cwd holds registry.json").action(
138
138
  (dir, opts, cmd) => action(async () => {
139
- const { add } = await import('./fleet-5NVOUIZD.js');
139
+ const { add } = await import('./fleet-F3XDEDCV.js');
140
140
  const shared = cmd.optsWithGlobals();
141
141
  await add({
142
142
  cwd: resolveCwd(cmd),
@@ -159,7 +159,7 @@ fleet.command("dismiss").argument("<name>", "the registered project name").argum
159
159
  "Dismiss a project's finding from any cwd \u2014 corp ledgers persist beside the manifest"
160
160
  ).requiredOption("--reason <text>", "why it is dismissed \u2014 recorded so the decision survives").option("--manifest <file>", "the fleet manifest \u2014 required unless the cwd holds registry.json").action(
161
161
  (name, id, _opts, cmd) => action(async () => {
162
- const { dismiss } = await import('./fleet-5NVOUIZD.js');
162
+ const { dismiss } = await import('./fleet-F3XDEDCV.js');
163
163
  const opts = cmd.optsWithGlobals();
164
164
  await dismiss({
165
165
  cwd: resolveCwd(cmd),
@@ -174,7 +174,7 @@ fleet.command("accept").argument("<name>", "the registered project name").argume
174
174
  "Accept a project's finding as a known trade-off \u2014 corp ledgers persist beside the manifest"
175
175
  ).option("--reason <text>", "optional note on why the trade-off is accepted").option("--manifest <file>", "the fleet manifest \u2014 required unless the cwd holds registry.json").action(
176
176
  (name, id, _opts, cmd) => action(async () => {
177
- const { accept } = await import('./fleet-5NVOUIZD.js');
177
+ const { accept } = await import('./fleet-F3XDEDCV.js');
178
178
  const opts = cmd.optsWithGlobals();
179
179
  await accept({ cwd: resolveCwd(cmd), manifest: opts.manifest, name, id, reason: opts.reason });
180
180
  })
@@ -186,7 +186,7 @@ program.command("screen").description(
186
186
  "fork's upstream remote: files byte-identical to its refs skip vocabulary-class patterns (secret patterns stay absolute)"
187
187
  ).action(
188
188
  (opts, cmd) => action(async () => {
189
- const { run } = await import('./screen-UF7VZ26C.js');
189
+ const { run } = await import('./screen-E4FC7W5N.js');
190
190
  const scope = opts.message ? "message" : opts.dir ? "dir" : opts.tree ? "tree" : "staged";
191
191
  await run({
192
192
  cwd: resolveCwd(cmd),
@@ -200,7 +200,7 @@ program.command("screen").description(
200
200
  );
201
201
  program.command("gates").description("Install the local git-hook gates (process \u2192 pre-commit, correctness \u2192 pre-push)").option("--ci", "note about the CI review gate (ships later; local gates install now)").option("-y, --yes", "skip prompts; never overwrites a hand-edited hook").action(
202
202
  (opts, cmd) => action(async () => {
203
- const { run } = await import('./gates-OS5V3P4C.js');
203
+ const { run } = await import('./gates-F4YPKWJR.js');
204
204
  await run({ cwd: resolveCwd(cmd), ci: opts.ci, yes: opts.yes });
205
205
  })
206
206
  );
@@ -1,4 +1,3 @@
1
1
  #!/usr/bin/env node
2
- export { CONFIG_FILE, DEFAULT_CONFIG, configPath, readConfig } from './chunk-DWL2IKZH.js';
3
- import './chunk-JHZ2BN4U.js';
2
+ export { CONFIG_FILE, DEFAULT_CONFIG, configPath, readConfig } from './chunk-P6ATKV2R.js';
4
3
  import './chunk-4VPBP6K6.js';
@@ -1,8 +1,6 @@
1
1
  #!/usr/bin/env node
2
- import { measureContext } from './chunk-F75Q43BC.js';
3
- import { readConfig } from './chunk-DWL2IKZH.js';
4
- import { print, renderContext } from './chunk-5BVKFJWM.js';
5
- import './chunk-JHZ2BN4U.js';
2
+ import { measureContext, print, renderContext } from './chunk-HI7NWPRA.js';
3
+ import { readConfig } from './chunk-P6ATKV2R.js';
6
4
  import './chunk-4VPBP6K6.js';
7
5
 
8
6
  // src/commands/context.ts
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env node
2
+ import { run } from './chunk-PAMWS665.js';
3
+ import './chunk-LT7JMVV3.js';
4
+ import './chunk-3E2IPCRY.js';
5
+ import './chunk-HI7NWPRA.js';
6
+ import './chunk-HWC6PKJM.js';
7
+ import './chunk-623W6KVC.js';
8
+ import './chunk-P6ATKV2R.js';
9
+ import './chunk-YQZDYDAK.js';
10
+ import './chunk-4VPBP6K6.js';
11
+
12
+ // src/commands/doctor.ts
13
+ async function run2(opts) {
14
+ await run({ cwd: opts.cwd, json: opts.json, truth: true });
15
+ }
16
+
17
+ export { run2 as run };
@@ -1,14 +1,12 @@
1
1
  #!/usr/bin/env node
2
- import { dismiss, accept } from './chunk-2VLNI3L2.js';
3
- import { parseFailOnTier, meetsFailOn, runAudit } from './chunk-O3PHW4OP.js';
4
- import './chunk-F75Q43BC.js';
2
+ import { dismiss, accept } from './chunk-HOR4M6EC.js';
3
+ import { parseFailOnTier, meetsFailOn, runAudit } from './chunk-LT7JMVV3.js';
5
4
  import { readLedger } from './chunk-3E2IPCRY.js';
6
- import { DEFAULT_CONFIG } from './chunk-DWL2IKZH.js';
7
- import { print, theme, section, renderFleetRows, renderFleetNotes, renderFindings, TIER_BADGE, glyph } from './chunk-5BVKFJWM.js';
8
- import { scanProject } from './chunk-MTVEJ33D.js';
9
- import './chunk-YFNRDXUY.js';
10
- import { ETYMD_DIR } from './chunk-JHZ2BN4U.js';
11
- import './chunk-LSZGCKIQ.js';
5
+ import { print, theme, section, renderFleetRows, renderFleetNotes, renderFindings, TIER_BADGE, glyph } from './chunk-HI7NWPRA.js';
6
+ import { scanProject } from './chunk-HWC6PKJM.js';
7
+ import './chunk-623W6KVC.js';
8
+ import { DEFAULT_CONFIG, ETYMD_DIR } from './chunk-P6ATKV2R.js';
9
+ import './chunk-YQZDYDAK.js';
12
10
  import { readText, pathExists, git, isDirectory } from './chunk-4VPBP6K6.js';
13
11
  import { promises } from 'fs';
14
12
  import os from 'os';
@@ -687,9 +685,9 @@ async function checkCorpEmails(manifest, findings, disclosures) {
687
685
  }
688
686
  }
689
687
  async function checkGateDrift(manifest, findings, disclosures) {
690
- const { planWorkflow } = await import('./generate-PMCP37DC.js');
691
- const { scanProject: scanProject2 } = await import('./scan-N4BKVL5F.js');
692
- const { readConfig } = await import('./config-XAH6PA5G.js');
688
+ const { planWorkflow } = await import('./generate-KEX75XNG.js');
689
+ const { scanProject: scanProject2 } = await import('./scan-QRTH6HAP.js');
690
+ const { readConfig } = await import('./config-724Y3IOB.js');
693
691
  for (const entry of manifest.entries) {
694
692
  const root = entry.resolvedRoot;
695
693
  if (!root || !await isDirectory(root)) continue;
@@ -1,12 +1,11 @@
1
1
  #!/usr/bin/env node
2
2
  import { applyFiles } from './chunk-GWGKEPRX.js';
3
- import { deriveFailOn, derivedCommands, planWorkflow, runPrefix, isSafeGateCommand } from './chunk-HRJJQCMT.js';
4
- import { readConfig, CONFIG_FILE, configPath } from './chunk-DWL2IKZH.js';
5
- import { section, print, glyph, theme, renderPlan } from './chunk-5BVKFJWM.js';
6
- import { scanProject } from './chunk-MTVEJ33D.js';
7
- import './chunk-YFNRDXUY.js';
8
- import './chunk-JHZ2BN4U.js';
9
- import './chunk-LSZGCKIQ.js';
3
+ import { deriveFailOn, derivedCommands, planWorkflow, runPrefix, isSafeGateCommand } from './chunk-UFNETE6P.js';
4
+ import { section, print, glyph, theme, renderPlan } from './chunk-HI7NWPRA.js';
5
+ import { scanProject } from './chunk-HWC6PKJM.js';
6
+ import './chunk-623W6KVC.js';
7
+ import { readConfig, CONFIG_FILE, configPath } from './chunk-P6ATKV2R.js';
8
+ import './chunk-YQZDYDAK.js';
10
9
  import { readText, git } from './chunk-4VPBP6K6.js';
11
10
  import { promises } from 'fs';
12
11
  import path from 'path';
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env node
2
+ export { deriveFailOn, derivedCommands, planWorkflow, riskReachability } from './chunk-UFNETE6P.js';
3
+ import './chunk-P6ATKV2R.js';
4
+ import './chunk-YQZDYDAK.js';
5
+ import './chunk-4VPBP6K6.js';
package/dist/index.d.ts CHANGED
@@ -154,6 +154,11 @@ interface ContextFile {
154
154
  role: string;
155
155
  words: number;
156
156
  approxTokens: number;
157
+ /**
158
+ * Other always-loaded names that are THIS SAME FILE — a symlink or hardlink resolving to one
159
+ * inode. Present so output can name every alias while the words are counted once.
160
+ */
161
+ aliases?: string[];
157
162
  }
158
163
  interface ContextBudget {
159
164
  files: ContextFile[];
@@ -811,8 +816,11 @@ declare const gateIntegrityLens: Lens;
811
816
  * The knowledge-pack version — bumped whenever templates, the rubric, or the encoded rules
812
817
  * change meaning. Stamped into facts, baselines, and generated artifacts so drift against the
813
818
  * pack is computable and `harvest` has something to diff.
819
+ *
820
+ * Gaps in the sequence are deliberate: a number stays retired even when the change that took it
821
+ * never shipped, so a version cited in a baseline or a record means exactly one pack, ever.
814
822
  */
815
- declare const PACK_VERSION = "8";
823
+ declare const PACK_VERSION = "12";
816
824
 
817
825
  declare const VERSION: string;
818
826
  declare const NAME: string;