etymd 0.4.1 → 0.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,26 @@
1
1
  # etymd
2
2
 
3
+ ## 0.4.2
4
+
5
+ ### Patch Changes
6
+
7
+ - 52ebca8: Fix: `fleet add --profile corp` was silently ignored, registering employer repos as personal.
8
+
9
+ `fleet` declares its own `--profile` (the sweep filter), and commander hands a parent-declared
10
+ option the value even when it is typed after the subcommand. So `fleet add <dir> --profile corp`
11
+ left the subcommand's own option undefined, the placement fell back to personal, and the
12
+ personal branch records `path` and the RAW `remote` — writing the employer host and its internal
13
+ group structure into a manifest that is tracked and pushed. That is precisely the disclosure the
14
+ alias convention exists to prevent. The same shadowing class was already fixed for `--manifest`
15
+ and `--json`; `--profile` was missed.
16
+
17
+ Two changes, because the flag alone is not enough. The CLI now reads the merged option view, so
18
+ the flag works. And `fleet add` refuses outright when the target's remote matches a corp host
19
+ declared in the local manifest while the profile is not corp — the manifest already knows which
20
+ hosts are the employer's and the remote has just been read, so the tool has every fact needed to
21
+ prevent this without anyone remembering a flag. It refuses rather than auto-correcting:
22
+ placement is the user's decision, but it may not be made by omission.
23
+
3
24
  ## 0.4.1
4
25
 
5
26
  ### Patch Changes
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { section, theme, print, renderBaselineDrift, glyph } from './chunk-TADKOW6P.js';
3
- import { scanProject } from './chunk-RH2UAS25.js';
4
- import { VERSION } from './chunk-KIMFKLJB.js';
3
+ import { scanProject } from './chunk-HX5IYDCU.js';
4
+ import { VERSION } from './chunk-WWV5W2MM.js';
5
5
  import { readBaseline, summarizeBaselineDrift, isDriftEmpty, writeBaseline, deriveProfile } from './chunk-R74SJ7HS.js';
6
6
  import { PACK_VERSION } from './chunk-IGHES6AK.js';
7
7
  import './chunk-YLNQQZ5F.js';
@@ -1,12 +1,12 @@
1
1
  #!/usr/bin/env node
2
- export { run } from './chunk-XER37MLS.js';
3
- import './chunk-OWNWN2KF.js';
2
+ export { run } from './chunk-4AEYMVZK.js';
3
+ import './chunk-6G3JJMZ3.js';
4
4
  import './chunk-LT67FU2Y.js';
5
5
  import './chunk-WWBF4Y7K.js';
6
6
  import './chunk-NMZ3RHWW.js';
7
7
  import './chunk-TADKOW6P.js';
8
- import './chunk-RH2UAS25.js';
9
- import './chunk-KIMFKLJB.js';
8
+ import './chunk-HX5IYDCU.js';
9
+ import './chunk-WWV5W2MM.js';
10
10
  import './chunk-R74SJ7HS.js';
11
11
  import './chunk-IGHES6AK.js';
12
12
  import './chunk-YLNQQZ5F.js';
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { print, theme } from './chunk-TADKOW6P.js';
3
- import { scanProject } from './chunk-RH2UAS25.js';
4
- import './chunk-KIMFKLJB.js';
3
+ import { scanProject } from './chunk-HX5IYDCU.js';
4
+ import './chunk-WWV5W2MM.js';
5
5
  import { ETYMD_DIR } from './chunk-R74SJ7HS.js';
6
6
  import './chunk-IGHES6AK.js';
7
7
  import './chunk-YLNQQZ5F.js';
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { parseFailOnTier, runAudit, meetsFailOn } from './chunk-OWNWN2KF.js';
2
+ import { parseFailOnTier, runAudit, meetsFailOn } from './chunk-6G3JJMZ3.js';
3
3
  import { print, section, theme, renderLensCoverage, renderFindings, renderLedgerDiff } from './chunk-TADKOW6P.js';
4
4
 
5
5
  // src/commands/audit.ts
@@ -2,7 +2,7 @@
2
2
  import { measureContext } from './chunk-LT67FU2Y.js';
3
3
  import { readLedger, reconcileLedger, writeLedger, visibleFindings } from './chunk-WWBF4Y7K.js';
4
4
  import { DEFAULT_CONFIG, readConfig, CONFIG_FILE } from './chunk-NMZ3RHWW.js';
5
- import { scanProject, expandFileGlobs } from './chunk-RH2UAS25.js';
5
+ import { scanProject, expandFileGlobs } from './chunk-HX5IYDCU.js';
6
6
  import { ETYMD_DIR, writeCachedFacts, readBaseline, deriveProfile, baselineCarriesMachinePath, BASELINE_FILE } from './chunk-R74SJ7HS.js';
7
7
  import { PACK_VERSION } from './chunk-IGHES6AK.js';
8
8
  import { pathExists, readJson, git, readText, isDirectory, matchesAnyGlob, isCiEnvironment, normalizeRelPath } from './chunk-YLNQQZ5F.js';
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { VERSION } from './chunk-KIMFKLJB.js';
2
+ import { VERSION } from './chunk-WWV5W2MM.js';
3
3
  import { PACK_VERSION } from './chunk-IGHES6AK.js';
4
4
  import { normalizeRelPath, isDirectory, readJson, git, matchesAnyGlob, pathExists, readText } from './chunk-YLNQQZ5F.js';
5
5
  import path from 'node:path';
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  // package.json
3
3
  var package_default = {
4
- version: "0.4.1"};
4
+ version: "0.4.2"};
5
5
 
6
6
  // src/version.ts
7
7
  var VERSION = package_default.version;
package/dist/cli.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { VERSION } from './chunk-KIMFKLJB.js';
2
+ import { VERSION } from './chunk-WWV5W2MM.js';
3
3
  import path from 'node: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-UJU3336P.js');
34
+ const { run } = await import('./audit-GUG2QFZM.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 missing").option("-y, --yes", "accept defaults without prompting (never overwrites)").action(
46
46
  (opts, cmd) => action(async () => {
47
- const { run } = await import('./init-7GNB74BE.js');
47
+ const { run } = await import('./init-Q5Q7IGZS.js');
48
48
  await run({ cwd: resolveCwd(cmd), yes: opts.yes });
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-DTYNGGXH.js');
55
+ const { run } = await import('./approve-FISVPFL2.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-6YOKI3JW.js');
61
+ const { run } = await import('./scan-UVNX52J5.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-W6DW3OK6.js');
67
+ const { run } = await import('./doctor-SOLNC37X.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-5UZLZ3CW.js');
79
+ const { run } = await import('./brief-UF6KV7SG.js');
80
80
  await run({ cwd: resolveCwd(cmd), human: opts.human });
81
81
  })
82
82
  );
@@ -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-77SSSFZO.js');
114
+ const { sweep } = await import('./fleet-UTFZKYNH.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-77SSSFZO.js');
129
+ const { check } = await import('./fleet-UTFZKYNH.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-77SSSFZO.js');
139
+ const { add } = await import('./fleet-UTFZKYNH.js');
140
140
  const shared = cmd.optsWithGlobals();
141
141
  await add({
142
142
  cwd: resolveCwd(cmd),
@@ -144,7 +144,12 @@ fleet.command("add").argument("<dir>", "directory of the project to register").d
144
144
  target: dir,
145
145
  name: opts.name,
146
146
  kind: opts.kind,
147
- profile: opts.profile,
147
+ // `fleet` declares its own --profile (the sweep filter), and commander hands a
148
+ // parent-declared option the value even when it is typed AFTER the subcommand — so
149
+ // `fleet add <dir> --profile corp` left opts.profile undefined and the flag silently
150
+ // did nothing, registering employer repos as personal. Reading the merged view is what
151
+ // makes the flag work; the corp-remote guard in add() is what makes forgetting it safe.
152
+ profile: opts.profile ?? shared.profile,
148
153
  trust: opts.trust,
149
154
  yes: opts.yes
150
155
  });
@@ -154,7 +159,7 @@ fleet.command("dismiss").argument("<name>", "the registered project name").argum
154
159
  "Dismiss a project's finding from any cwd \u2014 corp ledgers persist beside the manifest"
155
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(
156
161
  (name, id, _opts, cmd) => action(async () => {
157
- const { dismiss } = await import('./fleet-77SSSFZO.js');
162
+ const { dismiss } = await import('./fleet-UTFZKYNH.js');
158
163
  const opts = cmd.optsWithGlobals();
159
164
  await dismiss({
160
165
  cwd: resolveCwd(cmd),
@@ -169,7 +174,7 @@ fleet.command("accept").argument("<name>", "the registered project name").argume
169
174
  "Accept a project's finding as a known trade-off \u2014 corp ledgers persist beside the manifest"
170
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(
171
176
  (name, id, _opts, cmd) => action(async () => {
172
- const { accept } = await import('./fleet-77SSSFZO.js');
177
+ const { accept } = await import('./fleet-UTFZKYNH.js');
173
178
  const opts = cmd.optsWithGlobals();
174
179
  await accept({ cwd: resolveCwd(cmd), manifest: opts.manifest, name, id, reason: opts.reason });
175
180
  })
@@ -191,7 +196,7 @@ program.command("screen").description(
191
196
  );
192
197
  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(
193
198
  (opts, cmd) => action(async () => {
194
- const { run } = await import('./gates-LTM5PE7R.js');
199
+ const { run } = await import('./gates-YUUV7YI4.js');
195
200
  await run({ cwd: resolveCwd(cmd), ci: opts.ci, yes: opts.yes });
196
201
  })
197
202
  );
@@ -1,12 +1,12 @@
1
1
  #!/usr/bin/env node
2
- import { run } from './chunk-XER37MLS.js';
3
- import './chunk-OWNWN2KF.js';
2
+ import { run } from './chunk-4AEYMVZK.js';
3
+ import './chunk-6G3JJMZ3.js';
4
4
  import './chunk-LT67FU2Y.js';
5
5
  import './chunk-WWBF4Y7K.js';
6
6
  import './chunk-NMZ3RHWW.js';
7
7
  import './chunk-TADKOW6P.js';
8
- import './chunk-RH2UAS25.js';
9
- import './chunk-KIMFKLJB.js';
8
+ import './chunk-HX5IYDCU.js';
9
+ import './chunk-WWV5W2MM.js';
10
10
  import './chunk-R74SJ7HS.js';
11
11
  import './chunk-IGHES6AK.js';
12
12
  import './chunk-YLNQQZ5F.js';
@@ -1,12 +1,12 @@
1
1
  #!/usr/bin/env node
2
2
  import { dismiss, accept } from './chunk-MMPV67FW.js';
3
- import { parseFailOnTier, meetsFailOn, runAudit } from './chunk-OWNWN2KF.js';
3
+ import { parseFailOnTier, meetsFailOn, runAudit } from './chunk-6G3JJMZ3.js';
4
4
  import './chunk-LT67FU2Y.js';
5
5
  import { readLedger } from './chunk-WWBF4Y7K.js';
6
6
  import { DEFAULT_CONFIG } from './chunk-NMZ3RHWW.js';
7
7
  import { print, theme, section, renderFleetRows, renderFleetNotes, renderFindings, TIER_BADGE, glyph } from './chunk-TADKOW6P.js';
8
- import { scanProject } from './chunk-RH2UAS25.js';
9
- import './chunk-KIMFKLJB.js';
8
+ import { scanProject } from './chunk-HX5IYDCU.js';
9
+ import './chunk-WWV5W2MM.js';
10
10
  import { ETYMD_DIR } from './chunk-R74SJ7HS.js';
11
11
  import './chunk-IGHES6AK.js';
12
12
  import { readText, pathExists, git, isDirectory } from './chunk-YLNQQZ5F.js';
@@ -688,7 +688,7 @@ async function checkCorpEmails(manifest, findings, disclosures) {
688
688
  }
689
689
  async function checkGateDrift(manifest, findings, disclosures) {
690
690
  const { planWorkflow } = await import('./generate-CBMTNN7P.js');
691
- const { scanProject: scanProject2 } = await import('./scan-XZH57E4I.js');
691
+ const { scanProject: scanProject2 } = await import('./scan-NWZ65YWB.js');
692
692
  const { readConfig } = await import('./config-MX7OYI7F.js');
693
693
  for (const entry of manifest.entries) {
694
694
  const root = entry.resolvedRoot;
@@ -1177,6 +1177,12 @@ async function add(opts) {
1177
1177
  } else if (opts.trust) {
1178
1178
  throw new Error("corp entries take no `trust` \u2014 `profile: corp` already implies it");
1179
1179
  }
1180
+ const corpHost = remote ? manifest.corpHosts.find((h) => remote.includes(h)) : void 0;
1181
+ if (corpHost && profile !== "corp") {
1182
+ throw new Error(
1183
+ `\`${name}\` has a remote on the corp host \`${corpHost}\`, but --profile is \`${profile}\`. A personal entry records its path and raw remote in the TRACKED manifest \u2014 register it with \`--profile corp\` (alias-only, machine-pinned), or move it out of the fleet root.`
1184
+ );
1185
+ }
1180
1186
  const entry = profile === "corp" ? { name, kind, profile, private: true } : {
1181
1187
  name,
1182
1188
  kind,
@@ -3,8 +3,8 @@ import { applyFiles } from './chunk-EF6BPBG6.js';
3
3
  import { derivedCommands, planWorkflow, runPrefix, isSafeGateCommand } from './chunk-OX3LUOZR.js';
4
4
  import { readConfig, CONFIG_FILE, configPath } from './chunk-NMZ3RHWW.js';
5
5
  import { section, print, glyph, theme, renderPlan } from './chunk-TADKOW6P.js';
6
- import { scanProject } from './chunk-RH2UAS25.js';
7
- import './chunk-KIMFKLJB.js';
6
+ import { scanProject } from './chunk-HX5IYDCU.js';
7
+ import './chunk-WWV5W2MM.js';
8
8
  import './chunk-R74SJ7HS.js';
9
9
  import './chunk-IGHES6AK.js';
10
10
  import { readText, git } from './chunk-YLNQQZ5F.js';
package/dist/index.js CHANGED
@@ -29,7 +29,7 @@ var init_package = __esm({
29
29
  "package.json"() {
30
30
  package_default = {
31
31
  name: "etymd",
32
- version: "0.4.1",
32
+ version: "0.4.2",
33
33
  description: "Keep your agent instructions true \u2014 verify AGENTS.md, CLAUDE.md, rules & skills against the actual repo, with drift caught over time and a regression ledger.",
34
34
  keywords: [
35
35
  "cli",
@@ -3,8 +3,8 @@ import { applyFiles } from './chunk-EF6BPBG6.js';
3
3
  import { planWorkflow } from './chunk-OX3LUOZR.js';
4
4
  import './chunk-NMZ3RHWW.js';
5
5
  import { theme, renderFacts, print, renderPlan, section, glyph } from './chunk-TADKOW6P.js';
6
- import { scanProject } from './chunk-RH2UAS25.js';
7
- import { VERSION } from './chunk-KIMFKLJB.js';
6
+ import { scanProject } from './chunk-HX5IYDCU.js';
7
+ import { VERSION } from './chunk-WWV5W2MM.js';
8
8
  import { writeCachedFacts, deriveProfile, writeBaseline, CACHE_DIR } from './chunk-R74SJ7HS.js';
9
9
  import { PACK_VERSION } from './chunk-IGHES6AK.js';
10
10
  import { git, readText } from './chunk-YLNQQZ5F.js';
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env node
2
+ export { scanProject } from './chunk-HX5IYDCU.js';
3
+ import './chunk-WWV5W2MM.js';
4
+ import './chunk-IGHES6AK.js';
5
+ import './chunk-YLNQQZ5F.js';
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { print, renderFacts, theme } from './chunk-TADKOW6P.js';
3
- import { scanProject } from './chunk-RH2UAS25.js';
4
- import './chunk-KIMFKLJB.js';
3
+ import { scanProject } from './chunk-HX5IYDCU.js';
4
+ import './chunk-WWV5W2MM.js';
5
5
  import { writeCachedFacts } from './chunk-R74SJ7HS.js';
6
6
  import './chunk-IGHES6AK.js';
7
7
  import './chunk-YLNQQZ5F.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "etymd",
3
- "version": "0.4.1",
3
+ "version": "0.4.2",
4
4
  "description": "Keep your agent instructions true — verify AGENTS.md, CLAUDE.md, rules & skills against the actual repo, with drift caught over time and a regression ledger.",
5
5
  "keywords": [
6
6
  "cli",
@@ -1,5 +0,0 @@
1
- #!/usr/bin/env node
2
- export { scanProject } from './chunk-RH2UAS25.js';
3
- import './chunk-KIMFKLJB.js';
4
- import './chunk-IGHES6AK.js';
5
- import './chunk-YLNQQZ5F.js';