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/CHANGELOG.md +52 -16
- package/README.md +114 -47
- package/dist/{approve-QDOH2E7V.js → approve-K5FFTPA4.js} +2 -2
- package/dist/{audit-42OHF7ON.js → audit-HBNXNGD6.js} +5 -4
- package/dist/{brief-ZUQK3CFL.js → brief-DOQ2DQEG.js} +2 -2
- package/dist/{fleet-F3XDEDCV.js → chunk-ANXGT7V3.js} +431 -466
- package/dist/{chunk-HWC6PKJM.js → chunk-EJM47PIF.js} +1 -1
- package/dist/{chunk-PAMWS665.js → chunk-FKDT4RBP.js} +2 -1
- package/dist/{chunk-UFNETE6P.js → chunk-OKJ3RGJB.js} +1 -1
- package/dist/{chunk-LT7JMVV3.js → chunk-UV3YIBDW.js} +43 -730
- package/dist/{chunk-623W6KVC.js → chunk-UYCGP5BS.js} +1 -1
- package/dist/chunk-Y4E6ERCM.js +783 -0
- package/dist/cli.js +78 -22
- package/dist/{doctor-CE5SD4JW.js → doctor-X6XAGKV7.js} +5 -4
- package/dist/fleet-UEFLKIRI.js +489 -0
- package/dist/{gates-F4YPKWJR.js → gates-NVWWKMT2.js} +3 -3
- package/dist/{generate-KEX75XNG.js → generate-YEARCSHW.js} +1 -1
- package/dist/index.d.ts +301 -20
- package/dist/index.js +958 -233
- package/dist/{init-AHA7VRRI.js → init-Z5O2WVRJ.js} +3 -3
- package/dist/premise-4QRU7LRI.js +368 -0
- package/dist/propose-IKE4CUIM.js +252 -0
- package/dist/scan-64Z6SNYF.js +5 -0
- package/dist/{scan-TVX3FKK4.js → scan-H3NF5IV5.js} +2 -2
- package/package.json +5 -5
- package/dist/scan-QRTH6HAP.js +0 -5
package/dist/cli.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { VERSION } from './chunk-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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|
|
|
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;
|
|
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-
|
|
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-
|
|
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("
|
|
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-
|
|
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
|
|
150
|
-
// did nothing, registering
|
|
151
|
-
// makes the flag work; the
|
|
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
|
|
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-
|
|
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
|
|
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-
|
|
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-
|
|
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-
|
|
3
|
-
import './chunk-
|
|
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-
|
|
7
|
-
import './chunk-
|
|
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';
|