etymd 0.17.0 → 0.19.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.
Files changed (29) hide show
  1. package/CHANGELOG.md +68 -0
  2. package/README.md +10 -5
  3. package/dist/{approve-VN4EDBR5.js → approve-J6JU7MBX.js} +3 -3
  4. package/dist/audit-5N2TU2X7.js +11 -0
  5. package/dist/{brief-7MWP35UI.js → brief-NHHILXIH.js} +3 -3
  6. package/dist/{chunk-YQZDYDAK.js → chunk-2DRA7S67.js} +1 -1
  7. package/dist/{chunk-446EZNAQ.js → chunk-6DJMKZGK.js} +83 -10
  8. package/dist/chunk-7N5JDXQG.js +109 -0
  9. package/dist/{chunk-ANFNXFRI.js → chunk-GFUDKTC5.js} +2 -2
  10. package/dist/{chunk-BUMOGHQA.js → chunk-KQFEKOON.js} +1 -1
  11. package/dist/{chunk-LVR2DPR7.js → chunk-M7XDP6FT.js} +30 -3
  12. package/dist/{chunk-PIJZUDDQ.js → chunk-PQISPOB2.js} +191 -130
  13. package/dist/{chunk-WKP7M2B3.js → chunk-UMKC3OWQ.js} +11 -6
  14. package/dist/{chunk-FNA4R5KT.js → chunk-WKP72Z3J.js} +59 -11
  15. package/dist/cli.js +16 -16
  16. package/dist/{doctor-R4QDCAN5.js → doctor-264Q5PLY.js} +6 -6
  17. package/dist/{fleet-WPYEVHVL.js → fleet-VT625Q2J.js} +22 -6
  18. package/dist/{gates-3HRGYCYY.js → gates-YUMSTKUG.js} +5 -4
  19. package/dist/{generate-FSJQFQPV.js → generate-62GQSCKH.js} +3 -2
  20. package/dist/index.d.ts +21 -3
  21. package/dist/index.js +379 -58
  22. package/dist/{init-6RULX5JZ.js → init-G4XXFXVD.js} +5 -4
  23. package/dist/{premise-GFWHSR3K.js → premise-RNMAKMVA.js} +9 -5
  24. package/dist/{propose-IYNOIWAO.js → propose-35JXMEPH.js} +6 -6
  25. package/dist/scan-F6OW4ANK.js +5 -0
  26. package/dist/{scan-LLWW4YOU.js → scan-PJH32H7C.js} +3 -3
  27. package/package.json +2 -2
  28. package/dist/audit-PHAK5HEW.js +0 -11
  29. package/dist/scan-5SC47FSM.js +0 -5
package/dist/cli.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { VERSION } from './chunk-BUMOGHQA.js';
2
+ import { VERSION } from './chunk-KQFEKOON.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-PHAK5HEW.js');
34
+ const { run } = await import('./audit-5N2TU2X7.js');
35
35
  await run({
36
36
  cwd: resolveCwd(cmd),
37
37
  json: opts.json,
@@ -44,7 +44,7 @@ program.command("audit").description("Verify every instruction claim against the
44
44
  );
45
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-6RULX5JZ.js');
47
+ const { run } = await import('./init-G4XXFXVD.js');
48
48
  await run({ cwd: resolveCwd(cmd), yes: opts.yes, withAgents: opts.withAgents });
49
49
  })
50
50
  );
@@ -52,19 +52,19 @@ 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-VN4EDBR5.js');
55
+ const { run } = await import('./approve-J6JU7MBX.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-LLWW4YOU.js');
61
+ const { run } = await import('./scan-PJH32H7C.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-R4QDCAN5.js');
67
+ const { run } = await import('./doctor-264Q5PLY.js');
68
68
  await run({ cwd: resolveCwd(cmd), json: opts.json });
69
69
  })
70
70
  );
@@ -76,7 +76,7 @@ program.command("context").description("Measure the always-loaded context footpr
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-7MWP35UI.js');
79
+ const { run } = await import('./brief-NHHILXIH.js');
80
80
  await run({ cwd: resolveCwd(cmd), human: opts.human });
81
81
  })
82
82
  );
@@ -90,7 +90,7 @@ program.command("premise").argument("[task]", "the task you are about to hand an
90
90
  "exit non-zero when findings at/above this tier exist (risk|gap|polish)"
91
91
  ).action(
92
92
  (task, opts, cmd) => action(async () => {
93
- const { run } = await import('./premise-GFWHSR3K.js');
93
+ const { run } = await import('./premise-RNMAKMVA.js');
94
94
  await run({
95
95
  cwd: resolveCwd(cmd),
96
96
  task,
@@ -132,7 +132,7 @@ var fleet = program.command("fleet").description(
132
132
  "exit non-zero when findings at/above this tier exist (risk|gap|polish)"
133
133
  ).action(
134
134
  (opts, cmd) => action(async () => {
135
- const { sweep } = await import('./fleet-WPYEVHVL.js');
135
+ const { sweep } = await import('./fleet-VT625Q2J.js');
136
136
  await sweep({
137
137
  cwd: resolveCwd(cmd),
138
138
  manifest: opts.manifest,
@@ -147,7 +147,7 @@ var fleet = program.command("fleet").description(
147
147
  );
148
148
  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(
149
149
  (_opts, cmd) => action(async () => {
150
- const { check } = await import('./fleet-WPYEVHVL.js');
150
+ const { check } = await import('./fleet-VT625Q2J.js');
151
151
  const opts = cmd.optsWithGlobals();
152
152
  await check({ cwd: resolveCwd(cmd), manifest: opts.manifest, json: opts.json });
153
153
  })
@@ -156,7 +156,7 @@ fleet.command("board").description(
156
156
  "Render the fleet board: every project's milestones (contract key `milestones`) plus a ranked initiatives table"
157
157
  ).option("--manifest <file>", "the fleet manifest \u2014 required unless the cwd holds registry.json").option("--initiatives <file>", "the hand-edited initiatives table (rank | id | initiative | \u2026)").option("--out <file>", "write the Markdown board here instead of printing it").option("--json", "print the board as JSON (EXPERIMENTAL)").action(
158
158
  (opts, cmd) => action(async () => {
159
- const { board } = await import('./fleet-WPYEVHVL.js');
159
+ const { board } = await import('./fleet-VT625Q2J.js');
160
160
  const shared = cmd.optsWithGlobals();
161
161
  await board({
162
162
  cwd: resolveCwd(cmd),
@@ -172,7 +172,7 @@ fleet.command("add").argument("<dir>", "directory of the project to register").d
172
172
  "public-repo | public-bound | private \u2014 mandatory for personal entries"
173
173
  ).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(
174
174
  (dir, opts, cmd) => action(async () => {
175
- const { add } = await import('./fleet-WPYEVHVL.js');
175
+ const { add } = await import('./fleet-VT625Q2J.js');
176
176
  const shared = cmd.optsWithGlobals();
177
177
  await add({
178
178
  cwd: resolveCwd(cmd),
@@ -195,7 +195,7 @@ fleet.command("dismiss").argument("<name>", "the registered project name").argum
195
195
  "Dismiss a project's finding from any cwd \u2014 guarded ledgers persist beside the manifest"
196
196
  ).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(
197
197
  (name, id, _opts, cmd) => action(async () => {
198
- const { dismiss } = await import('./fleet-WPYEVHVL.js');
198
+ const { dismiss } = await import('./fleet-VT625Q2J.js');
199
199
  const opts = cmd.optsWithGlobals();
200
200
  await dismiss({
201
201
  cwd: resolveCwd(cmd),
@@ -210,7 +210,7 @@ fleet.command("accept").argument("<name>", "the registered project name").argume
210
210
  "Accept a project's finding as a known trade-off \u2014 guarded ledgers persist beside the manifest"
211
211
  ).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(
212
212
  (name, id, _opts, cmd) => action(async () => {
213
- const { accept } = await import('./fleet-WPYEVHVL.js');
213
+ const { accept } = await import('./fleet-VT625Q2J.js');
214
214
  const opts = cmd.optsWithGlobals();
215
215
  await accept({ cwd: resolveCwd(cmd), manifest: opts.manifest, name, id, reason: opts.reason });
216
216
  })
@@ -225,7 +225,7 @@ program.command("propose").description(
225
225
  "the fleet manifest \u2014 runs a read-only sweep now (no delta baseline move)"
226
226
  ).option("--from <file>", "read a stored `etymd fleet --json` output instead of sweeping").option("--json", "print the proposal/1 records as JSON (EXPERIMENTAL)").action(
227
227
  (opts, cmd) => action(async () => {
228
- const { run } = await import('./propose-IYNOIWAO.js');
228
+ const { run } = await import('./propose-35JXMEPH.js');
229
229
  await run({
230
230
  cwd: resolveCwd(cmd),
231
231
  manifest: opts.manifest,
@@ -256,7 +256,7 @@ program.command("screen").description(
256
256
  );
257
257
  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(
258
258
  (opts, cmd) => action(async () => {
259
- const { run } = await import('./gates-3HRGYCYY.js');
259
+ const { run } = await import('./gates-YUMSTKUG.js');
260
260
  await run({ cwd: resolveCwd(cmd), ci: opts.ci, yes: opts.yes });
261
261
  })
262
262
  );
@@ -1,13 +1,13 @@
1
1
  #!/usr/bin/env node
2
- import { run } from './chunk-ANFNXFRI.js';
3
- import './chunk-WKP7M2B3.js';
4
- import './chunk-FNA4R5KT.js';
2
+ import { run } from './chunk-GFUDKTC5.js';
3
+ import './chunk-UMKC3OWQ.js';
4
+ import './chunk-WKP72Z3J.js';
5
5
  import './chunk-3E2IPCRY.js';
6
6
  import './chunk-HI7NWPRA.js';
7
- import './chunk-446EZNAQ.js';
8
- import './chunk-BUMOGHQA.js';
7
+ import './chunk-6DJMKZGK.js';
8
+ import './chunk-KQFEKOON.js';
9
9
  import './chunk-P6ATKV2R.js';
10
- import './chunk-YQZDYDAK.js';
10
+ import './chunk-2DRA7S67.js';
11
11
  import './chunk-4VPBP6K6.js';
12
12
 
13
13
  // src/commands/doctor.ts
@@ -1,14 +1,15 @@
1
1
  #!/usr/bin/env node
2
2
  import { dismiss, accept } from './chunk-HOR4M6EC.js';
3
- import { sweepFleet, FLEET_JSON_SCHEMA, checkManifest, FLEET_TRUST_VALUES, isFleetTrust, MILESTONES_FILE, parseMilestones, parseInitiatives, BOARD_JSON_SCHEMA, renderBoard, loadFleetManifest, fleetLedgerTarget, ensureFindingRecorded } from './chunk-LVR2DPR7.js';
4
- import './chunk-WKP7M2B3.js';
5
- import { parseFailOnTier, meetsFailOn } from './chunk-FNA4R5KT.js';
3
+ import { sweepFleet, FLEET_JSON_SCHEMA, checkManifest, FLEET_TRUST_VALUES, isFleetTrust, MILESTONES_FILE, parseMilestones, parseInitiatives, BOARD_JSON_SCHEMA, renderBoard, loadFleetManifest, fleetLedgerTarget, ensureFindingRecorded } from './chunk-M7XDP6FT.js';
4
+ import './chunk-UMKC3OWQ.js';
5
+ import { parseFailOnTier, meetsFailOn } from './chunk-WKP72Z3J.js';
6
6
  import './chunk-3E2IPCRY.js';
7
+ import { generateClaudePointerMd } from './chunk-PQISPOB2.js';
7
8
  import { print, theme, section, renderFleetRows, renderFleetNotes, renderFindings, TIER_BADGE, glyph } from './chunk-HI7NWPRA.js';
8
- import { scanProject } from './chunk-446EZNAQ.js';
9
- import './chunk-BUMOGHQA.js';
9
+ import { checkClaudePointer, scanProject } from './chunk-6DJMKZGK.js';
10
+ import './chunk-KQFEKOON.js';
10
11
  import './chunk-P6ATKV2R.js';
11
- import './chunk-YQZDYDAK.js';
12
+ import './chunk-2DRA7S67.js';
12
13
  import { readText, pathExists, git } from './chunk-4VPBP6K6.js';
13
14
  import { promises } from 'fs';
14
15
  import os from 'os';
@@ -234,6 +235,21 @@ async function add(opts) {
234
235
  if (manifest.entries.some((e) => e.name === name)) {
235
236
  throw new Error(`\`${name}\` is already registered \u2014 resolution is keyed by name`);
236
237
  }
238
+ const pointer = await checkClaudePointer(absTarget);
239
+ if (!pointer.ok && pointer.kind === "no-import") {
240
+ throw new Error(
241
+ `\`${name}\` has a CLAUDE.md that hides its AGENTS.md from Claude Code (${pointer.detail}). Add a full-line \`@AGENTS.md\` import to it, e.g.:
242
+
243
+ ${generateClaudePointerMd().trimEnd().split("\n").join("\n")}
244
+
245
+ \u2014 or symlink either file to the other, or delete the CLAUDE.md \u2014 then re-run \`etymd fleet add\`.`
246
+ );
247
+ }
248
+ if (!pointer.ok) {
249
+ print(
250
+ ` ${theme.warn("note")} ${pointer.detail}. Update Claude Code, or add a CLAUDE.md containing \`@AGENTS.md\`.`
251
+ );
252
+ }
237
253
  const facts = await scanProject(absTarget);
238
254
  const remote = facts.git.isRepo ? await git(absTarget, ["remote", "get-url", "origin"]) : null;
239
255
  section(`Fleet add ${theme.dim(`\xB7 ${name} \xB7 ${absTarget}`)}`);
@@ -1,11 +1,12 @@
1
1
  #!/usr/bin/env node
2
2
  import { applyFiles } from './chunk-GWGKEPRX.js';
3
- import { deriveFailOn, derivedCommands, planWorkflow, runPrefix, isSafeGateCommand } from './chunk-PIJZUDDQ.js';
3
+ import { deriveFailOn, derivedCommands, planWorkflow } from './chunk-7N5JDXQG.js';
4
+ import { runPrefix, isSafeGateCommand } from './chunk-PQISPOB2.js';
4
5
  import { section, print, glyph, theme, renderPlan } from './chunk-HI7NWPRA.js';
5
- import { scanProject } from './chunk-446EZNAQ.js';
6
- import './chunk-BUMOGHQA.js';
6
+ import { scanProject } from './chunk-6DJMKZGK.js';
7
+ import './chunk-KQFEKOON.js';
7
8
  import { readConfig, CONFIG_FILE, configPath } from './chunk-P6ATKV2R.js';
8
- import './chunk-YQZDYDAK.js';
9
+ import './chunk-2DRA7S67.js';
9
10
  import { readText, git } from './chunk-4VPBP6K6.js';
10
11
  import { promises } from 'fs';
11
12
  import path from 'path';
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env node
2
- export { deriveFailOn, derivedCommands, planWorkflow, riskReachability } from './chunk-PIJZUDDQ.js';
2
+ export { deriveFailOn, derivedCommands, planWorkflow, riskReachability } from './chunk-7N5JDXQG.js';
3
+ import './chunk-PQISPOB2.js';
3
4
  import './chunk-P6ATKV2R.js';
4
- import './chunk-YQZDYDAK.js';
5
+ import './chunk-2DRA7S67.js';
5
6
  import './chunk-4VPBP6K6.js';
package/dist/index.d.ts CHANGED
@@ -66,6 +66,11 @@ interface GitFacts {
66
66
  isRepo: boolean;
67
67
  branch?: string;
68
68
  head?: string;
69
+ /**
70
+ * `core.hooksPath`, stated repo-relative whenever the directory sits inside the worktree — git
71
+ * accepts an absolute spelling of the same directory, and the spelling is neither a fact nor
72
+ * something a committed baseline should carry. Absolute only when it points outside the repo.
73
+ */
69
74
  hooksPath?: string;
70
75
  husky: boolean;
71
76
  /** Distinct commit authors in recent history — the solo-vs-team profile signal. */
@@ -793,8 +798,12 @@ interface TruthEnv {
793
798
  manifestExists: boolean;
794
799
  /** The root plus every workspace package dir — where claims are resolved. */
795
800
  bases: string[];
796
- /** A repo-relative claim resolves in the root, any workspace package, or their src/ scripts/. */
797
- pathResolves(claim: string): Promise<boolean>;
801
+ /**
802
+ * A repo-relative claim resolves in the root, any workspace package, their src/ scripts/, or
803
+ * the directory of the file making the claim (`fromDir`) — a nested instruction file writes
804
+ * references the way an agent reading it resolves them: against its siblings.
805
+ */
806
+ pathResolves(claim: string, fromDir?: string): Promise<boolean>;
798
807
  /** `yarn X` / `pnpm X` may legitimately run an installed node_modules/.bin binary. */
799
808
  binResolves(name: string): Promise<boolean>;
800
809
  }
@@ -807,6 +816,8 @@ interface ClaimCounters {
807
816
  unverifiableCommands: number;
808
817
  gitignoredSkipped: number;
809
818
  prospectiveSkipped: number;
819
+ /** Path claims whose every mention sits beside the URL it is fetched from — another tree. */
820
+ fetchedSkipped: number;
810
821
  placeholderSkipped: number;
811
822
  /** Decision references naming another record (a fleet-level ledger) — not this repo's. */
812
823
  qualifiedRefsSkipped: number;
@@ -995,8 +1006,15 @@ declare function extractCommandClaims(text: string): CommandClaims;
995
1006
  interface PathClaims {
996
1007
  /** Claims to verify against the repo. */
997
1008
  paths: string[];
1009
+ /** Slash-terminated directory claims — candidate bases for resolving sibling references. */
1010
+ dirs: string[];
998
1011
  /** Claims whose every mention sits in create-this prose — skipped, counted, disclosed. */
999
1012
  prospective: string[];
1013
+ /**
1014
+ * Claims whose every mention sits beside the URL they are fetched from — another tree's
1015
+ * files, unverifiable here. Skipped, counted, disclosed.
1016
+ */
1017
+ fetched: string[];
1000
1018
  /** Claims whose every mention sits behind a namespace prefix (`pc:`) — another repo's tree. */
1001
1019
  namespaced: string[];
1002
1020
  /** Naming stand-ins (`my-custom-skill`) — never real claims. */
@@ -1109,7 +1127,7 @@ declare const gateIntegrityLens: Lens;
1109
1127
  * Gaps in the sequence are deliberate: a number stays retired even when the change that took it
1110
1128
  * never shipped, so a version cited in a baseline or a record means exactly one pack, ever.
1111
1129
  */
1112
- declare const PACK_VERSION = "12";
1130
+ declare const PACK_VERSION = "15";
1113
1131
 
1114
1132
  declare const VERSION: string;
1115
1133
  declare const NAME: string;