etymd 0.14.0 → 0.16.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.
package/dist/cli.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { VERSION } from './chunk-623W6KVC.js';
2
+ import { VERSION } from './chunk-UYCGP5BS.js';
3
3
  import path from 'path';
4
4
  import { Command } from 'commander';
5
5
  import pc from 'picocolors';
@@ -21,7 +21,7 @@ ${pc.red("\u2716")} ${message}
21
21
  }
22
22
  var program = new Command();
23
23
  program.name("etymd").description(
24
- "Keep your agent instructions true \u2014 verify AGENTS.md & friends against the actual repo, on a budget, with drift caught over time."
24
+ "Keep your agent instructions true \u2014 verify AGENTS.md & friends, and the task you hand an agent, against the actual repo, on a budget, with drift caught over time."
25
25
  ).version(VERSION, "-v, --version").option("--cwd <dir>", "run against a different project directory", process.cwd());
26
26
  program.command("audit").description("Verify every instruction claim against the repo: ranked findings + ledger diff").option("--json", "print the machine-stable audit result as JSON").option("--truth", "truth lenses only (the doctor subset)").option(
27
27
  "--lens <id>",
@@ -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-42OHF7ON.js');
34
+ const { run } = await import('./audit-HBNXNGD6.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-AHA7VRRI.js');
47
+ const { run } = await import('./init-Z5O2WVRJ.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-QDOH2E7V.js');
55
+ const { run } = await import('./approve-K5FFTPA4.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-TVX3FKK4.js');
61
+ const { run } = await import('./scan-H3NF5IV5.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-CE5SD4JW.js');
67
+ const { run } = await import('./doctor-X6XAGKV7.js');
68
68
  await run({ cwd: resolveCwd(cmd), json: opts.json });
69
69
  })
70
70
  );
@@ -76,10 +76,31 @@ 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-ZUQK3CFL.js');
79
+ const { run } = await import('./brief-DOQ2DQEG.js');
80
80
  await run({ cwd: resolveCwd(cmd), human: opts.human });
81
81
  })
82
82
  );
83
+ program.command("premise").argument("[task]", "the task you are about to hand an agent, quoted").description(
84
+ "Before acting on a task: verify what it names against the repo, then brief the agent on what only it can verify"
85
+ ).option(
86
+ "--file <path>",
87
+ "read the task from a file (a plan, an issue, a prompt); `-` reads stdin"
88
+ ).option("--json", "print the machine-stable result as JSON (schema premise/1)").option("--no-brief", "do not write or print the agent brief").option(
89
+ "--fail-on <tier>",
90
+ "exit non-zero when findings at/above this tier exist (risk|gap|polish)"
91
+ ).action(
92
+ (task, opts, cmd) => action(async () => {
93
+ const { run } = await import('./premise-4QRU7LRI.js');
94
+ await run({
95
+ cwd: resolveCwd(cmd),
96
+ task,
97
+ file: opts.file,
98
+ json: opts.json,
99
+ brief: opts.brief,
100
+ failOn: opts.failOn
101
+ });
102
+ })
103
+ );
83
104
  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
105
  (opts, cmd) => action(async () => {
85
106
  const { list } = await import('./ledger-T54JDHGP.js');
@@ -103,15 +124,15 @@ var fleet = program.command("fleet").description(
103
124
  ).option(
104
125
  "--manifest <file>",
105
126
  "the fleet manifest (registry.json / legacy sources.json) \u2014 required unless the cwd holds registry.json"
106
- ).option("--only <names...>", "sweep only these registered names").option("--profile <profile>", "sweep only entries with this profile (personal|corp)").option("--truth", "truth lenses only per repo (the doctor subset)").option(
127
+ ).option("--only <names...>", "sweep only these registered names").option("--profile <profile>", "sweep only entries with this profile (personal|guarded)").option("--truth", "truth lenses only per repo (the doctor subset)").option(
107
128
  "--persist-ledgers",
108
- "persist per-repo ledgers \u2014 personal-profile entries that already carry .etymd only; corp worktrees are never written"
129
+ "persist per-repo ledgers \u2014 personal-profile entries that already carry .etymd only; guarded worktrees are never written"
109
130
  ).option("--json", "print the machine schema (EXPERIMENTAL through 0.2.x, local-only)").option(
110
131
  "--fail-on <tier>",
111
132
  "exit non-zero when findings at/above this tier exist (risk|gap|polish)"
112
133
  ).action(
113
134
  (opts, cmd) => action(async () => {
114
- const { sweep } = await import('./fleet-F3XDEDCV.js');
135
+ const { sweep } = await import('./fleet-UEFLKIRI.js');
115
136
  await sweep({
116
137
  cwd: resolveCwd(cmd),
117
138
  manifest: opts.manifest,
@@ -126,17 +147,32 @@ var fleet = program.command("fleet").description(
126
147
  );
127
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(
128
149
  (_opts, cmd) => action(async () => {
129
- const { check } = await import('./fleet-F3XDEDCV.js');
150
+ const { check } = await import('./fleet-UEFLKIRI.js');
130
151
  const opts = cmd.optsWithGlobals();
131
152
  await check({ cwd: resolveCwd(cmd), manifest: opts.manifest, json: opts.json });
132
153
  })
133
154
  );
134
- fleet.command("add").argument("<dir>", "directory of the project to register").description("Register a project \u2014 refuses to write an entry missing a mandatory field").option("--name <name>", "registered name (defaults to the directory's basename)").option("--kind <kind>", "entry kind (defaults to a value derived from the scan)").option("--profile <profile>", "personal | corp (default: personal)").option(
155
+ fleet.command("board").description(
156
+ "Render the fleet board: every project's milestones (contract key `milestones`) plus a ranked initiatives table"
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
+ (opts, cmd) => action(async () => {
159
+ const { board } = await import('./fleet-UEFLKIRI.js');
160
+ const shared = cmd.optsWithGlobals();
161
+ await board({
162
+ cwd: resolveCwd(cmd),
163
+ manifest: shared.manifest,
164
+ initiatives: opts.initiatives,
165
+ out: opts.out,
166
+ json: opts.json ?? shared.json
167
+ });
168
+ })
169
+ );
170
+ fleet.command("add").argument("<dir>", "directory of the project to register").description("Register a project \u2014 refuses to write an entry missing a mandatory field").option("--name <name>", "registered name (defaults to the directory's basename)").option("--kind <kind>", "entry kind (defaults to a value derived from the scan)").option("--profile <profile>", "personal | guarded (default: personal)").option(
135
171
  "--trust <level>",
136
172
  "public-repo | public-bound | private \u2014 mandatory for personal entries"
137
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(
138
174
  (dir, opts, cmd) => action(async () => {
139
- const { add } = await import('./fleet-F3XDEDCV.js');
175
+ const { add } = await import('./fleet-UEFLKIRI.js');
140
176
  const shared = cmd.optsWithGlobals();
141
177
  await add({
142
178
  cwd: resolveCwd(cmd),
@@ -146,9 +182,9 @@ fleet.command("add").argument("<dir>", "directory of the project to register").d
146
182
  kind: opts.kind,
147
183
  // `fleet` declares its own --profile (the sweep filter), and commander hands a
148
184
  // 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.
185
+ // `fleet add <dir> --profile guarded` left opts.profile undefined and the flag silently
186
+ // did nothing, registering guarded repos as personal. Reading the merged view is what
187
+ // makes the flag work; the guarded-remote guard in add() is what makes forgetting it safe.
152
188
  profile: opts.profile ?? shared.profile,
153
189
  trust: opts.trust,
154
190
  yes: opts.yes
@@ -156,10 +192,10 @@ fleet.command("add").argument("<dir>", "directory of the project to register").d
156
192
  })
157
193
  );
158
194
  fleet.command("dismiss").argument("<name>", "the registered project name").argument("<finding-id>", "the finding id (from `etymd fleet`) to dismiss").description(
159
- "Dismiss a project's finding from any cwd \u2014 corp ledgers persist beside the manifest"
195
+ "Dismiss a project's finding from any cwd \u2014 guarded ledgers persist beside the manifest"
160
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(
161
197
  (name, id, _opts, cmd) => action(async () => {
162
- const { dismiss } = await import('./fleet-F3XDEDCV.js');
198
+ const { dismiss } = await import('./fleet-UEFLKIRI.js');
163
199
  const opts = cmd.optsWithGlobals();
164
200
  await dismiss({
165
201
  cwd: resolveCwd(cmd),
@@ -171,14 +207,34 @@ fleet.command("dismiss").argument("<name>", "the registered project name").argum
171
207
  })
172
208
  );
173
209
  fleet.command("accept").argument("<name>", "the registered project name").argument("<finding-id>", "the finding id (from `etymd fleet`) to accept").description(
174
- "Accept a project's finding as a known trade-off \u2014 corp ledgers persist beside the manifest"
210
+ "Accept a project's finding as a known trade-off \u2014 guarded ledgers persist beside the manifest"
175
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(
176
212
  (name, id, _opts, cmd) => action(async () => {
177
- const { accept } = await import('./fleet-F3XDEDCV.js');
213
+ const { accept } = await import('./fleet-UEFLKIRI.js');
178
214
  const opts = cmd.optsWithGlobals();
179
215
  await accept({ cwd: resolveCwd(cmd), manifest: opts.manifest, name, id, reason: opts.reason });
180
216
  })
181
217
  );
218
+ program.command("propose").description(
219
+ "Score improvement findings + recurring classes against a fleet rubric \u2014 proposal records, read-only (schema proposal/1, EXPERIMENTAL)"
220
+ ).requiredOption(
221
+ "--rubric <file>",
222
+ "the rubric file \u2014 one `criterion: <weight>` line per criterion; etymd ships none"
223
+ ).option(
224
+ "--manifest <file>",
225
+ "the fleet manifest \u2014 runs a read-only sweep now (no delta baseline move)"
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
+ (opts, cmd) => action(async () => {
228
+ const { run } = await import('./propose-IKE4CUIM.js');
229
+ await run({
230
+ cwd: resolveCwd(cmd),
231
+ manifest: opts.manifest,
232
+ from: opts.from,
233
+ rubric: opts.rubric,
234
+ json: opts.json
235
+ });
236
+ })
237
+ );
182
238
  program.command("screen").description(
183
239
  "Content screen: check for text that must never be published. Bring your own patterns \u2014 etymd ships none."
184
240
  ).option("--staged", "screen what a commit is about to add (default)").option("--tree", "screen every tracked file \u2014 what is about to leave the machine").option("--message <file>", "screen a commit message (the commit-msg hook's $1)").option("--dir <dir>", "screen an unpacked build artifact \u2014 what actually ships").option("--patterns <file>", "pattern file (default: ~/.config/etymd/screen-patterns)").option("--advisory", "report without failing").option(
@@ -200,7 +256,7 @@ program.command("screen").description(
200
256
  );
201
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(
202
258
  (opts, cmd) => action(async () => {
203
- const { run } = await import('./gates-F4YPKWJR.js');
259
+ const { run } = await import('./gates-NVWWKMT2.js');
204
260
  await run({ cwd: resolveCwd(cmd), ci: opts.ci, yes: opts.yes });
205
261
  })
206
262
  );
@@ -1,10 +1,11 @@
1
1
  #!/usr/bin/env node
2
- import { run } from './chunk-PAMWS665.js';
3
- import './chunk-LT7JMVV3.js';
2
+ import { run } from './chunk-FKDT4RBP.js';
3
+ import './chunk-UV3YIBDW.js';
4
+ import './chunk-Y4E6ERCM.js';
4
5
  import './chunk-3E2IPCRY.js';
5
6
  import './chunk-HI7NWPRA.js';
6
- import './chunk-HWC6PKJM.js';
7
- import './chunk-623W6KVC.js';
7
+ import './chunk-EJM47PIF.js';
8
+ import './chunk-UYCGP5BS.js';
8
9
  import './chunk-P6ATKV2R.js';
9
10
  import './chunk-YQZDYDAK.js';
10
11
  import './chunk-4VPBP6K6.js';