etymd 0.10.0 → 0.11.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 +66 -0
- package/README.md +23 -2
- package/dist/{approve-6TMXJLOI.js → approve-OUJ4UPGK.js} +5 -5
- package/dist/audit-A75FVXHD.js +12 -0
- package/dist/{brief-X64HK325.js → brief-MYUESUMM.js} +7 -7
- package/dist/{chunk-SGW7OPHZ.js → chunk-2KVQBL4E.js} +1 -1
- package/dist/{chunk-V2SOHPXF.js → chunk-2VLNI3L2.js} +1 -1
- package/dist/{chunk-OAFYLBVG.js → chunk-3E2IPCRY.js} +3 -3
- package/dist/{chunk-IV3FYVTS.js → chunk-4VPBP6K6.js} +4 -3
- package/dist/{chunk-WTD2EIMN.js → chunk-5GQ52DK6.js} +5 -5
- package/dist/{chunk-YVGC3E6U.js → chunk-DWL2IKZH.js} +3 -3
- package/dist/{chunk-IPOAD67U.js → chunk-F75Q43BC.js} +4 -4
- package/dist/{chunk-EF6BPBG6.js → chunk-GWGKEPRX.js} +2 -2
- package/dist/{chunk-R6CVJ5D7.js → chunk-HRJJQCMT.js} +9 -13
- package/dist/{chunk-K34AVLDP.js → chunk-J7XVOTZL.js} +1 -1
- package/dist/{chunk-C7LBUFNU.js → chunk-JHZ2BN4U.js} +3 -3
- package/dist/{chunk-KQMQJJZK.js → chunk-JVLWM27I.js} +9 -9
- package/dist/{chunk-OIYNP6Y6.js → chunk-LSZGCKIQ.js} +1 -1
- package/dist/cli.js +19 -19
- package/dist/config-XAH6PA5G.js +4 -0
- package/dist/{context-K6DZNWAV.js → context-F63RSIBH.js} +4 -4
- package/dist/doctor-OZQTOUFR.js +19 -0
- package/dist/{fleet-4PPNUIDJ.js → fleet-Z7W3QBEV.js} +18 -18
- package/dist/{gates-Q7FMVUQP.js → gates-47YTMMLZ.js} +10 -10
- package/dist/generate-PMCP37DC.js +6 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +137 -141
- package/dist/{init-YYGRFIHQ.js → init-QLGIYFCX.js} +10 -10
- package/dist/ledger-4FOZ5HAB.js +5 -0
- package/dist/{scan-VO776GM7.js → scan-VWEXWM6G.js} +5 -5
- package/dist/scan-W7RHZVSF.js +5 -0
- package/dist/{screen-MOQP6XC7.js → screen-NSWNC7VQ.js} +80 -10
- package/package.json +4 -4
- package/dist/audit-FGDX2AYS.js +0 -12
- package/dist/config-TPK5LYDM.js +0 -4
- package/dist/doctor-W3UZK7KS.js +0 -19
- package/dist/generate-NLHGTRZB.js +0 -6
- package/dist/ledger-B2XGANTH.js +0 -5
- package/dist/scan-PJSZGUG7.js +0 -5
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { applyFiles } from './chunk-
|
|
3
|
-
import { planWorkflow } from './chunk-
|
|
4
|
-
import './chunk-
|
|
2
|
+
import { applyFiles } from './chunk-GWGKEPRX.js';
|
|
3
|
+
import { planWorkflow } from './chunk-HRJJQCMT.js';
|
|
4
|
+
import './chunk-DWL2IKZH.js';
|
|
5
5
|
import { theme, renderFacts, print, renderPlan, section, glyph } from './chunk-5BVKFJWM.js';
|
|
6
|
-
import { scanProject } from './chunk-
|
|
7
|
-
import { VERSION } from './chunk-
|
|
8
|
-
import { writeCachedFacts, deriveProfile, writeBaseline, CACHE_DIR } from './chunk-
|
|
9
|
-
import { PACK_VERSION } from './chunk-
|
|
10
|
-
import { git, readText } from './chunk-
|
|
11
|
-
import { promises } from '
|
|
12
|
-
import path from '
|
|
6
|
+
import { scanProject } from './chunk-5GQ52DK6.js';
|
|
7
|
+
import { VERSION } from './chunk-J7XVOTZL.js';
|
|
8
|
+
import { writeCachedFacts, deriveProfile, writeBaseline, CACHE_DIR } from './chunk-JHZ2BN4U.js';
|
|
9
|
+
import { PACK_VERSION } from './chunk-LSZGCKIQ.js';
|
|
10
|
+
import { git, readText } from './chunk-4VPBP6K6.js';
|
|
11
|
+
import { promises } from 'fs';
|
|
12
|
+
import path from 'path';
|
|
13
13
|
import { intro, spinner, select, confirm, outro, isCancel, cancel } from '@clack/prompts';
|
|
14
14
|
|
|
15
15
|
function bail() {
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { print, renderFacts, theme } from './chunk-5BVKFJWM.js';
|
|
3
|
-
import { scanProject } from './chunk-
|
|
4
|
-
import './chunk-
|
|
5
|
-
import { writeCachedFacts } from './chunk-
|
|
6
|
-
import './chunk-
|
|
7
|
-
import './chunk-
|
|
3
|
+
import { scanProject } from './chunk-5GQ52DK6.js';
|
|
4
|
+
import './chunk-J7XVOTZL.js';
|
|
5
|
+
import { writeCachedFacts } from './chunk-JHZ2BN4U.js';
|
|
6
|
+
import './chunk-LSZGCKIQ.js';
|
|
7
|
+
import './chunk-4VPBP6K6.js';
|
|
8
8
|
|
|
9
9
|
// src/commands/scan.ts
|
|
10
10
|
async function run(opts) {
|
|
@@ -1,14 +1,54 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { print, glyph, theme, section } from './chunk-5BVKFJWM.js';
|
|
3
|
-
import { git, readText, pathExists } from './chunk-
|
|
4
|
-
import { promises } from '
|
|
5
|
-
import path from '
|
|
3
|
+
import { git, readText, pathExists } from './chunk-4VPBP6K6.js';
|
|
4
|
+
import { promises } from 'fs';
|
|
5
|
+
import path from 'path';
|
|
6
6
|
|
|
7
7
|
var MACHINE_PATH_RE = /\/(?:Users|home)\/[A-Za-z0-9._-]+\//;
|
|
8
8
|
var ALLOW_MARKER = "allow-published-string";
|
|
9
9
|
var ALLOW_FILE = ".etymd-screen-allow";
|
|
10
10
|
var LEGACY_ALLOW_FILE = ".artifact-check-allow";
|
|
11
|
-
|
|
11
|
+
var LABELED_LINE = /^(pattern|reason|date|author)[ \t]+(.*)$/;
|
|
12
|
+
function compileAllow(raw) {
|
|
13
|
+
const entries = [];
|
|
14
|
+
let current = null;
|
|
15
|
+
const close = () => {
|
|
16
|
+
if (current) entries.push(current);
|
|
17
|
+
current = null;
|
|
18
|
+
};
|
|
19
|
+
for (const rawLine of raw.split("\n")) {
|
|
20
|
+
const l = rawLine.trim();
|
|
21
|
+
if (!l || l.startsWith("#")) continue;
|
|
22
|
+
const labeled = LABELED_LINE.exec(l);
|
|
23
|
+
if (labeled) {
|
|
24
|
+
const [, label = "", value = ""] = labeled;
|
|
25
|
+
if (label === "pattern") {
|
|
26
|
+
close();
|
|
27
|
+
current = makeAllowEntry(value);
|
|
28
|
+
} else if (current) {
|
|
29
|
+
if (label === "reason") current.reason = value.trim();
|
|
30
|
+
else if (label === "date") current.date = value.trim();
|
|
31
|
+
else current.author = value.trim();
|
|
32
|
+
}
|
|
33
|
+
} else {
|
|
34
|
+
close();
|
|
35
|
+
current = makeAllowEntry(l);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
close();
|
|
39
|
+
return entries;
|
|
40
|
+
}
|
|
41
|
+
function makeAllowEntry(patternStr) {
|
|
42
|
+
try {
|
|
43
|
+
return { pattern: new RegExp(patternStr, "i"), isSelfName: false };
|
|
44
|
+
} catch {
|
|
45
|
+
return {
|
|
46
|
+
pattern: new RegExp(patternStr.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), "i"),
|
|
47
|
+
isSelfName: false
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
function compilePatterns(raw) {
|
|
12
52
|
return raw.split("\n").map((l) => l.trim()).filter((l) => l && !l.startsWith("#")).map((l) => {
|
|
13
53
|
try {
|
|
14
54
|
return new RegExp(l, "i");
|
|
@@ -66,7 +106,7 @@ function screenText(text, file, patterns, allow = []) {
|
|
|
66
106
|
const lines = text.split("\n");
|
|
67
107
|
for (const [i, line] of lines.entries()) {
|
|
68
108
|
if (line.includes(ALLOW_MARKER)) continue;
|
|
69
|
-
if (allow.some((
|
|
109
|
+
if (allow.some((entry) => entry.pattern.test(line))) continue;
|
|
70
110
|
for (const re of patterns) {
|
|
71
111
|
if (re.test(line)) {
|
|
72
112
|
hits.push({ file, line: i + 1, text: line.trim().slice(0, 160), reason: String(re) });
|
|
@@ -122,15 +162,42 @@ async function run(opts) {
|
|
|
122
162
|
);
|
|
123
163
|
return;
|
|
124
164
|
}
|
|
125
|
-
const patterns =
|
|
165
|
+
const patterns = compilePatterns(rawPatterns);
|
|
126
166
|
if (!patterns.length) {
|
|
127
167
|
print(` ${glyph.partial} ${theme.dim(`${patternPath} has no active patterns \u2014 skipping.`)}`);
|
|
128
168
|
return;
|
|
129
169
|
}
|
|
130
|
-
const
|
|
131
|
-
const
|
|
170
|
+
const usingLegacy = !await pathExists(path.join(opts.cwd, ALLOW_FILE)) && await pathExists(path.join(opts.cwd, LEGACY_ALLOW_FILE));
|
|
171
|
+
const allowRaw = usingLegacy ? await readText(path.join(opts.cwd, LEGACY_ALLOW_FILE)) : await readText(path.join(opts.cwd, ALLOW_FILE));
|
|
172
|
+
const allowEntries = allowRaw ? compileAllow(allowRaw) : [];
|
|
132
173
|
const selves = await selfIdentities(opts.cwd);
|
|
174
|
+
const validatedEntries = allowEntries.filter((entry) => {
|
|
175
|
+
if (entry.isSelfName) return true;
|
|
176
|
+
if (isSelfName(entry.pattern, selves)) {
|
|
177
|
+
entry.isSelfName = true;
|
|
178
|
+
return true;
|
|
179
|
+
}
|
|
180
|
+
if (!entry.reason || !entry.date || !entry.author) {
|
|
181
|
+
print(
|
|
182
|
+
` ${glyph.partial} ${theme.warn(`Missing provenance for exemption pattern`)} ${theme.dim(String(entry.pattern))}`
|
|
183
|
+
);
|
|
184
|
+
print(
|
|
185
|
+
` ${theme.dim("Format: a `pattern` line, then `reason`, `date`, `author` lines \u2014 a bare pattern line is a self-name exemption")}`
|
|
186
|
+
);
|
|
187
|
+
return false;
|
|
188
|
+
}
|
|
189
|
+
return true;
|
|
190
|
+
});
|
|
191
|
+
const allow = validatedEntries;
|
|
133
192
|
const active = selves.length ? patterns.filter((re) => !isSelfName(re, selves)) : patterns;
|
|
193
|
+
if (usingLegacy) {
|
|
194
|
+
print(
|
|
195
|
+
` ${glyph.partial} ${theme.warn(`Using legacy ${LEGACY_ALLOW_FILE} file \u2014 rename to ${ALLOW_FILE} and add provenance`)}`
|
|
196
|
+
);
|
|
197
|
+
print(
|
|
198
|
+
` ${theme.dim("New format: a `pattern` line, then `reason`, `date`, `author` lines per entry")}`
|
|
199
|
+
);
|
|
200
|
+
}
|
|
134
201
|
const hits = [];
|
|
135
202
|
let scanned = 0;
|
|
136
203
|
let skippedBinary = 0;
|
|
@@ -174,12 +241,15 @@ async function run(opts) {
|
|
|
174
241
|
hits.push(...screenText(raw, rel, active, allow));
|
|
175
242
|
}
|
|
176
243
|
}
|
|
177
|
-
if (!hits.length) return;
|
|
178
244
|
section(
|
|
179
245
|
`Content screen ${theme.dim(
|
|
180
246
|
`\xB7 ${opts.scope} \xB7 ${scanned} file(s)${skippedBinary ? ` \xB7 ${skippedBinary} binary skipped` : ""}`
|
|
181
247
|
)}`
|
|
182
248
|
);
|
|
249
|
+
if (!hits.length) {
|
|
250
|
+
print(` ${glyph.ok} ${theme.dim("clean")}`);
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
183
253
|
for (const h of hits) {
|
|
184
254
|
print(` ${theme.warn(h.file)}${theme.dim(`:${h.line}`)} ${theme.dim(`(${h.reason})`)}`);
|
|
185
255
|
print(` ${h.text}`);
|
|
@@ -194,4 +264,4 @@ async function run(opts) {
|
|
|
194
264
|
if (!opts.advisory) process.exitCode = 1;
|
|
195
265
|
}
|
|
196
266
|
|
|
197
|
-
export { isSelfName, patternLiteral, readScreenable, run, screenText, selfIdentities };
|
|
267
|
+
export { compileAllow, isSelfName, patternLiteral, readScreenable, run, screenText, selfIdentities };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "etymd",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0",
|
|
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",
|
|
@@ -69,12 +69,12 @@
|
|
|
69
69
|
"yaml": "2.9.0"
|
|
70
70
|
},
|
|
71
71
|
"devDependencies": {
|
|
72
|
-
"@changesets/cli": "2.
|
|
72
|
+
"@changesets/cli": "2.31.1",
|
|
73
73
|
"@types/node": "22.10.2",
|
|
74
74
|
"prettier": "3.4.2",
|
|
75
|
-
"tsup": "8.
|
|
75
|
+
"tsup": "8.5.1",
|
|
76
76
|
"typescript": "5.7.2",
|
|
77
|
-
"vitest": "
|
|
77
|
+
"vitest": "4.1.10"
|
|
78
78
|
},
|
|
79
79
|
"publishConfig": {
|
|
80
80
|
"access": "public"
|
package/dist/audit-FGDX2AYS.js
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
export { run } from './chunk-SGW7OPHZ.js';
|
|
3
|
-
import './chunk-KQMQJJZK.js';
|
|
4
|
-
import './chunk-IPOAD67U.js';
|
|
5
|
-
import './chunk-OAFYLBVG.js';
|
|
6
|
-
import './chunk-YVGC3E6U.js';
|
|
7
|
-
import './chunk-5BVKFJWM.js';
|
|
8
|
-
import './chunk-WTD2EIMN.js';
|
|
9
|
-
import './chunk-K34AVLDP.js';
|
|
10
|
-
import './chunk-C7LBUFNU.js';
|
|
11
|
-
import './chunk-OIYNP6Y6.js';
|
|
12
|
-
import './chunk-IV3FYVTS.js';
|
package/dist/config-TPK5LYDM.js
DELETED
package/dist/doctor-W3UZK7KS.js
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import { run } from './chunk-SGW7OPHZ.js';
|
|
3
|
-
import './chunk-KQMQJJZK.js';
|
|
4
|
-
import './chunk-IPOAD67U.js';
|
|
5
|
-
import './chunk-OAFYLBVG.js';
|
|
6
|
-
import './chunk-YVGC3E6U.js';
|
|
7
|
-
import './chunk-5BVKFJWM.js';
|
|
8
|
-
import './chunk-WTD2EIMN.js';
|
|
9
|
-
import './chunk-K34AVLDP.js';
|
|
10
|
-
import './chunk-C7LBUFNU.js';
|
|
11
|
-
import './chunk-OIYNP6Y6.js';
|
|
12
|
-
import './chunk-IV3FYVTS.js';
|
|
13
|
-
|
|
14
|
-
// src/commands/doctor.ts
|
|
15
|
-
async function run2(opts) {
|
|
16
|
-
await run({ cwd: opts.cwd, json: opts.json, truth: true });
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export { run2 as run };
|
package/dist/ledger-B2XGANTH.js
DELETED