etymd 0.9.0 → 0.9.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.
- package/CHANGELOG.md +20 -0
- package/dist/{approve-H4UMLKRJ.js → approve-HED3NCTE.js} +2 -2
- package/dist/{audit-22SOGKLY.js → audit-Y35XVD6Z.js} +4 -4
- package/dist/{brief-VKNKPZJF.js → brief-2CXAUDNN.js} +2 -2
- package/dist/{chunk-E3CVCK5X.js → chunk-AQM4GYGN.js} +1 -1
- package/dist/{chunk-5P7KZV4W.js → chunk-KGVRZ6WC.js} +1 -1
- package/dist/{chunk-ZA7GVR63.js → chunk-ULM25GWG.js} +1 -1
- package/dist/{chunk-MUNRU2LF.js → chunk-UN7IAYM6.js} +1 -1
- package/dist/cli.js +14 -14
- package/dist/{doctor-ITR74ZUE.js → doctor-DXXQJ2L3.js} +4 -4
- package/dist/{fleet-CTBMXRHV.js → fleet-DPJSZDEY.js} +4 -4
- package/dist/{gates-X7WY7IRK.js → gates-RR3V4PII.js} +2 -2
- package/dist/index.js +1 -1
- package/dist/{init-ROJ6LQX3.js → init-RC35RS5J.js} +2 -2
- package/dist/scan-KX522VKV.js +5 -0
- package/dist/{scan-2ODW52EK.js → scan-MBXSD5RO.js} +2 -2
- package/dist/{screen-6R6NXDSY.js → screen-EHNK6ANK.js} +28 -4
- package/package.json +1 -1
- package/dist/scan-VL4DW5ZT.js +0 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
# etymd
|
|
2
2
|
|
|
3
|
+
## 0.9.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 8967d26: Content screen: skip binary files, and say how many were skipped
|
|
8
|
+
|
|
9
|
+
Compressed bytes contain any short sequence eventually, so a short pattern
|
|
10
|
+
matches inside binary assets by accident and is reported as a "line" of
|
|
11
|
+
mojibake. Every pattern added to a pattern file therefore raised the
|
|
12
|
+
false-positive rate across every repo that holds assets.
|
|
13
|
+
|
|
14
|
+
The cost of a noisy gate is not the noise. It is that the gate's answer becomes
|
|
15
|
+
"bypass again", and a trained-in `--no-verify` is what eventually waves a real
|
|
16
|
+
finding through with the rest.
|
|
17
|
+
|
|
18
|
+
Files whose first 8KB contain a NUL byte are now skipped rather than screened,
|
|
19
|
+
which closes that for every pattern at once instead of anchoring one pattern at
|
|
20
|
+
a time. The count is reported in the summary header (`· N binary skipped`), so
|
|
21
|
+
"no findings" can never quietly mean "the bytes were never looked at".
|
|
22
|
+
|
|
3
23
|
## 0.9.0
|
|
4
24
|
|
|
5
25
|
### Minor Changes
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { section, theme, print, renderBaselineDrift, glyph } from './chunk-5BVKFJWM.js';
|
|
3
|
-
import { scanProject } from './chunk-
|
|
4
|
-
import { VERSION } from './chunk-
|
|
3
|
+
import { scanProject } from './chunk-UN7IAYM6.js';
|
|
4
|
+
import { VERSION } from './chunk-AQM4GYGN.js';
|
|
5
5
|
import { readBaseline, summarizeBaselineDrift, isDriftEmpty, writeBaseline, deriveProfile } from './chunk-C7LBUFNU.js';
|
|
6
6
|
import { PACK_VERSION } from './chunk-6DUDIVIC.js';
|
|
7
7
|
import './chunk-IV3FYVTS.js';
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
export { run } from './chunk-
|
|
3
|
-
import './chunk-
|
|
2
|
+
export { run } from './chunk-ULM25GWG.js';
|
|
3
|
+
import './chunk-KGVRZ6WC.js';
|
|
4
4
|
import './chunk-JSUYV26K.js';
|
|
5
5
|
import './chunk-OAFYLBVG.js';
|
|
6
6
|
import './chunk-D2RI3CCT.js';
|
|
7
7
|
import './chunk-5BVKFJWM.js';
|
|
8
|
-
import './chunk-
|
|
9
|
-
import './chunk-
|
|
8
|
+
import './chunk-UN7IAYM6.js';
|
|
9
|
+
import './chunk-AQM4GYGN.js';
|
|
10
10
|
import './chunk-C7LBUFNU.js';
|
|
11
11
|
import './chunk-6DUDIVIC.js';
|
|
12
12
|
import './chunk-IV3FYVTS.js';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { print, theme } from './chunk-5BVKFJWM.js';
|
|
3
|
-
import { scanProject } from './chunk-
|
|
4
|
-
import './chunk-
|
|
3
|
+
import { scanProject } from './chunk-UN7IAYM6.js';
|
|
4
|
+
import './chunk-AQM4GYGN.js';
|
|
5
5
|
import { ETYMD_DIR } from './chunk-C7LBUFNU.js';
|
|
6
6
|
import './chunk-6DUDIVIC.js';
|
|
7
7
|
import './chunk-IV3FYVTS.js';
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { measureContext } from './chunk-JSUYV26K.js';
|
|
3
3
|
import { readLedger, reconcileLedger, writeLedger, visibleFindings } from './chunk-OAFYLBVG.js';
|
|
4
4
|
import { DEFAULT_CONFIG, readConfig, CONFIG_FILE } from './chunk-D2RI3CCT.js';
|
|
5
|
-
import { scanProject, expandFileGlobs } from './chunk-
|
|
5
|
+
import { scanProject, expandFileGlobs } from './chunk-UN7IAYM6.js';
|
|
6
6
|
import { ETYMD_DIR, writeCachedFacts, readBaseline, deriveProfile, baselineCarriesMachinePath, BASELINE_FILE } from './chunk-C7LBUFNU.js';
|
|
7
7
|
import { PACK_VERSION } from './chunk-6DUDIVIC.js';
|
|
8
8
|
import { pathExists, readJson, readText, isDirectory, matchesAnyGlob, git, normalizeRelPath, isCiEnvironment, isExecutable } from './chunk-IV3FYVTS.js';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { parseFailOnTier, runAudit, meetsFailOn } from './chunk-
|
|
2
|
+
import { parseFailOnTier, runAudit, meetsFailOn } from './chunk-KGVRZ6WC.js';
|
|
3
3
|
import { print, section, theme, renderLensCoverage, renderFindings, renderLedgerDiff } from './chunk-5BVKFJWM.js';
|
|
4
4
|
|
|
5
5
|
// src/commands/audit.ts
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { VERSION } from './chunk-
|
|
2
|
+
import { VERSION } from './chunk-AQM4GYGN.js';
|
|
3
3
|
import { PACK_VERSION } from './chunk-6DUDIVIC.js';
|
|
4
4
|
import { normalizeRelPath, isDirectory, readJson, git, matchesAnyGlob, pathExists, readText } from './chunk-IV3FYVTS.js';
|
|
5
5
|
import path from 'node:path';
|
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-AQM4GYGN.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-
|
|
34
|
+
const { run } = await import('./audit-Y35XVD6Z.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-
|
|
47
|
+
const { run } = await import('./init-RC35RS5J.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-
|
|
55
|
+
const { run } = await import('./approve-HED3NCTE.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-MBXSD5RO.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-DXXQJ2L3.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-
|
|
79
|
+
const { run } = await import('./brief-2CXAUDNN.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-
|
|
114
|
+
const { sweep } = await import('./fleet-DPJSZDEY.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-
|
|
129
|
+
const { check } = await import('./fleet-DPJSZDEY.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-
|
|
139
|
+
const { add } = await import('./fleet-DPJSZDEY.js');
|
|
140
140
|
const shared = cmd.optsWithGlobals();
|
|
141
141
|
await add({
|
|
142
142
|
cwd: resolveCwd(cmd),
|
|
@@ -159,7 +159,7 @@ fleet.command("dismiss").argument("<name>", "the registered project name").argum
|
|
|
159
159
|
"Dismiss a project's finding from any cwd \u2014 corp ledgers persist beside the manifest"
|
|
160
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(
|
|
161
161
|
(name, id, _opts, cmd) => action(async () => {
|
|
162
|
-
const { dismiss } = await import('./fleet-
|
|
162
|
+
const { dismiss } = await import('./fleet-DPJSZDEY.js');
|
|
163
163
|
const opts = cmd.optsWithGlobals();
|
|
164
164
|
await dismiss({
|
|
165
165
|
cwd: resolveCwd(cmd),
|
|
@@ -174,7 +174,7 @@ fleet.command("accept").argument("<name>", "the registered project name").argume
|
|
|
174
174
|
"Accept a project's finding as a known trade-off \u2014 corp ledgers persist beside the manifest"
|
|
175
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(
|
|
176
176
|
(name, id, _opts, cmd) => action(async () => {
|
|
177
|
-
const { accept } = await import('./fleet-
|
|
177
|
+
const { accept } = await import('./fleet-DPJSZDEY.js');
|
|
178
178
|
const opts = cmd.optsWithGlobals();
|
|
179
179
|
await accept({ cwd: resolveCwd(cmd), manifest: opts.manifest, name, id, reason: opts.reason });
|
|
180
180
|
})
|
|
@@ -183,7 +183,7 @@ program.command("screen").description(
|
|
|
183
183
|
"Content screen: check for text that must never be published. Bring your own patterns \u2014 etymd ships none."
|
|
184
184
|
).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").action(
|
|
185
185
|
(opts, cmd) => action(async () => {
|
|
186
|
-
const { run } = await import('./screen-
|
|
186
|
+
const { run } = await import('./screen-EHNK6ANK.js');
|
|
187
187
|
const scope = opts.message ? "message" : opts.dir ? "dir" : opts.tree ? "tree" : "staged";
|
|
188
188
|
await run({
|
|
189
189
|
cwd: resolveCwd(cmd),
|
|
@@ -196,7 +196,7 @@ program.command("screen").description(
|
|
|
196
196
|
);
|
|
197
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(
|
|
198
198
|
(opts, cmd) => action(async () => {
|
|
199
|
-
const { run } = await import('./gates-
|
|
199
|
+
const { run } = await import('./gates-RR3V4PII.js');
|
|
200
200
|
await run({ cwd: resolveCwd(cmd), ci: opts.ci, yes: opts.yes });
|
|
201
201
|
})
|
|
202
202
|
);
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { run } from './chunk-
|
|
3
|
-
import './chunk-
|
|
2
|
+
import { run } from './chunk-ULM25GWG.js';
|
|
3
|
+
import './chunk-KGVRZ6WC.js';
|
|
4
4
|
import './chunk-JSUYV26K.js';
|
|
5
5
|
import './chunk-OAFYLBVG.js';
|
|
6
6
|
import './chunk-D2RI3CCT.js';
|
|
7
7
|
import './chunk-5BVKFJWM.js';
|
|
8
|
-
import './chunk-
|
|
9
|
-
import './chunk-
|
|
8
|
+
import './chunk-UN7IAYM6.js';
|
|
9
|
+
import './chunk-AQM4GYGN.js';
|
|
10
10
|
import './chunk-C7LBUFNU.js';
|
|
11
11
|
import './chunk-6DUDIVIC.js';
|
|
12
12
|
import './chunk-IV3FYVTS.js';
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { dismiss, accept } from './chunk-V2SOHPXF.js';
|
|
3
|
-
import { parseFailOnTier, meetsFailOn, runAudit } from './chunk-
|
|
3
|
+
import { parseFailOnTier, meetsFailOn, runAudit } from './chunk-KGVRZ6WC.js';
|
|
4
4
|
import './chunk-JSUYV26K.js';
|
|
5
5
|
import { readLedger } from './chunk-OAFYLBVG.js';
|
|
6
6
|
import { DEFAULT_CONFIG } from './chunk-D2RI3CCT.js';
|
|
7
7
|
import { print, theme, section, renderFleetRows, renderFleetNotes, renderFindings, TIER_BADGE, glyph } from './chunk-5BVKFJWM.js';
|
|
8
|
-
import { scanProject } from './chunk-
|
|
9
|
-
import './chunk-
|
|
8
|
+
import { scanProject } from './chunk-UN7IAYM6.js';
|
|
9
|
+
import './chunk-AQM4GYGN.js';
|
|
10
10
|
import { ETYMD_DIR } from './chunk-C7LBUFNU.js';
|
|
11
11
|
import './chunk-6DUDIVIC.js';
|
|
12
12
|
import { readText, pathExists, git, isDirectory } from './chunk-IV3FYVTS.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-IPY5QIR5.js');
|
|
691
|
-
const { scanProject: scanProject2 } = await import('./scan-
|
|
691
|
+
const { scanProject: scanProject2 } = await import('./scan-KX522VKV.js');
|
|
692
692
|
const { readConfig } = await import('./config-7WCVZCM6.js');
|
|
693
693
|
for (const entry of manifest.entries) {
|
|
694
694
|
const root = entry.resolvedRoot;
|
|
@@ -3,8 +3,8 @@ import { applyFiles } from './chunk-EF6BPBG6.js';
|
|
|
3
3
|
import { deriveFailOn, derivedCommands, planWorkflow, runPrefix, isSafeGateCommand } from './chunk-WENIJMVV.js';
|
|
4
4
|
import { readConfig, CONFIG_FILE, configPath } from './chunk-D2RI3CCT.js';
|
|
5
5
|
import { section, print, glyph, theme, renderPlan } from './chunk-5BVKFJWM.js';
|
|
6
|
-
import { scanProject } from './chunk-
|
|
7
|
-
import './chunk-
|
|
6
|
+
import { scanProject } from './chunk-UN7IAYM6.js';
|
|
7
|
+
import './chunk-AQM4GYGN.js';
|
|
8
8
|
import './chunk-C7LBUFNU.js';
|
|
9
9
|
import './chunk-6DUDIVIC.js';
|
|
10
10
|
import { readText, git } from './chunk-IV3FYVTS.js';
|
package/dist/index.js
CHANGED
|
@@ -30,7 +30,7 @@ var init_package = __esm({
|
|
|
30
30
|
"package.json"() {
|
|
31
31
|
package_default = {
|
|
32
32
|
name: "etymd",
|
|
33
|
-
version: "0.9.
|
|
33
|
+
version: "0.9.1",
|
|
34
34
|
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.",
|
|
35
35
|
keywords: [
|
|
36
36
|
"cli",
|
|
@@ -3,8 +3,8 @@ import { applyFiles } from './chunk-EF6BPBG6.js';
|
|
|
3
3
|
import { planWorkflow } from './chunk-WENIJMVV.js';
|
|
4
4
|
import './chunk-D2RI3CCT.js';
|
|
5
5
|
import { theme, renderFacts, print, renderPlan, section, glyph } from './chunk-5BVKFJWM.js';
|
|
6
|
-
import { scanProject } from './chunk-
|
|
7
|
-
import { VERSION } from './chunk-
|
|
6
|
+
import { scanProject } from './chunk-UN7IAYM6.js';
|
|
7
|
+
import { VERSION } from './chunk-AQM4GYGN.js';
|
|
8
8
|
import { writeCachedFacts, deriveProfile, writeBaseline, CACHE_DIR } from './chunk-C7LBUFNU.js';
|
|
9
9
|
import { PACK_VERSION } from './chunk-6DUDIVIC.js';
|
|
10
10
|
import { git, readText } from './chunk-IV3FYVTS.js';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { print, renderFacts, theme } from './chunk-5BVKFJWM.js';
|
|
3
|
-
import { scanProject } from './chunk-
|
|
4
|
-
import './chunk-
|
|
3
|
+
import { scanProject } from './chunk-UN7IAYM6.js';
|
|
4
|
+
import './chunk-AQM4GYGN.js';
|
|
5
5
|
import { writeCachedFacts } from './chunk-C7LBUFNU.js';
|
|
6
6
|
import './chunk-6DUDIVIC.js';
|
|
7
7
|
import './chunk-IV3FYVTS.js';
|
|
@@ -58,6 +58,17 @@ async function walk(dir, out, depth = 0) {
|
|
|
58
58
|
else out.push(abs);
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
|
+
var BINARY_SNIFF_BYTES = 8192;
|
|
62
|
+
async function readScreenable(p) {
|
|
63
|
+
let buf;
|
|
64
|
+
try {
|
|
65
|
+
buf = await promises.readFile(p);
|
|
66
|
+
} catch {
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
if (buf.subarray(0, BINARY_SNIFF_BYTES).includes(0)) return "binary";
|
|
70
|
+
return buf.toString("utf8");
|
|
71
|
+
}
|
|
61
72
|
async function run(opts) {
|
|
62
73
|
const patternPath = opts.patterns ?? process.env.ETYMD_SCREEN_PATTERNS ?? process.env.PUBLIC_REPO_PATTERNS ?? path.join(process.env.HOME ?? "", ".config", "etymd", "screen-patterns");
|
|
63
74
|
const rawPatterns = await readText(patternPath);
|
|
@@ -83,6 +94,7 @@ async function run(opts) {
|
|
|
83
94
|
const active = self ? patterns.filter((re) => !isSelfName(re, self)) : patterns;
|
|
84
95
|
const hits = [];
|
|
85
96
|
let scanned = 0;
|
|
97
|
+
let skippedBinary = 0;
|
|
86
98
|
if (opts.scope === "message") {
|
|
87
99
|
const file = opts.target;
|
|
88
100
|
if (!file) throw new Error("--message needs the message file path (the commit-msg hook's $1)");
|
|
@@ -97,8 +109,12 @@ async function run(opts) {
|
|
|
97
109
|
const files = [];
|
|
98
110
|
await walk(dir, files);
|
|
99
111
|
for (const f of files) {
|
|
100
|
-
const raw = await
|
|
112
|
+
const raw = await readScreenable(f);
|
|
101
113
|
if (raw === null) continue;
|
|
114
|
+
if (raw === "binary") {
|
|
115
|
+
skippedBinary++;
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
102
118
|
scanned++;
|
|
103
119
|
hits.push(...screenText(raw, path.relative(dir, f), active, allow));
|
|
104
120
|
}
|
|
@@ -109,14 +125,22 @@ async function run(opts) {
|
|
|
109
125
|
if (rel === ALLOW_FILE || rel === LEGACY_ALLOW_FILE) continue;
|
|
110
126
|
const abs = path.join(opts.cwd, rel);
|
|
111
127
|
if (!await pathExists(abs)) continue;
|
|
112
|
-
const raw = await
|
|
128
|
+
const raw = await readScreenable(abs);
|
|
113
129
|
if (raw === null) continue;
|
|
130
|
+
if (raw === "binary") {
|
|
131
|
+
skippedBinary++;
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
114
134
|
scanned++;
|
|
115
135
|
hits.push(...screenText(raw, rel, active, allow));
|
|
116
136
|
}
|
|
117
137
|
}
|
|
118
138
|
if (!hits.length) return;
|
|
119
|
-
section(
|
|
139
|
+
section(
|
|
140
|
+
`Content screen ${theme.dim(
|
|
141
|
+
`\xB7 ${opts.scope} \xB7 ${scanned} file(s)${skippedBinary ? ` \xB7 ${skippedBinary} binary skipped` : ""}`
|
|
142
|
+
)}`
|
|
143
|
+
);
|
|
120
144
|
for (const h of hits) {
|
|
121
145
|
print(` ${theme.warn(h.file)}${theme.dim(`:${h.line}`)} ${theme.dim(`(${h.reason})`)}`);
|
|
122
146
|
print(` ${h.text}`);
|
|
@@ -131,4 +155,4 @@ async function run(opts) {
|
|
|
131
155
|
if (!opts.advisory) process.exitCode = 1;
|
|
132
156
|
}
|
|
133
157
|
|
|
134
|
-
export { isSelfName, run, screenText };
|
|
158
|
+
export { isSelfName, readScreenable, run, screenText };
|
package/package.json
CHANGED