etymd 0.13.0 → 0.15.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.
Files changed (38) hide show
  1. package/CHANGELOG.md +108 -0
  2. package/README.md +30 -19
  3. package/dist/{approve-YUT43YLC.js → approve-MA4Z3TBT.js} +5 -5
  4. package/dist/audit-YSALDC2L.js +11 -0
  5. package/dist/{brief-Z5S6OY2M.js → brief-DPZYSAMC.js} +5 -5
  6. package/dist/{chunk-PXRLOEN5.js → chunk-2RNQ6OLV.js} +146 -717
  7. package/dist/{chunk-DSAQ5S5D.js → chunk-CEO3BXQB.js} +3 -2
  8. package/dist/{chunk-D3R74TJ2.js → chunk-DBWDMIYO.js} +1 -1
  9. package/dist/{chunk-5BVKFJWM.js → chunk-HI7NWPRA.js} +79 -4
  10. package/dist/{chunk-2VLNI3L2.js → chunk-HOR4M6EC.js} +1 -1
  11. package/dist/chunk-IWG77WV3.js +758 -0
  12. package/dist/{chunk-DWL2IKZH.js → chunk-P6ATKV2R.js} +65 -3
  13. package/dist/{chunk-HRJJQCMT.js → chunk-UFNETE6P.js} +69 -20
  14. package/dist/{chunk-YXOAPMQH.js → chunk-Y6RZRED3.js} +2 -2
  15. package/dist/{chunk-LSZGCKIQ.js → chunk-YQZDYDAK.js} +1 -1
  16. package/dist/cli.js +42 -21
  17. package/dist/{config-XAH6PA5G.js → config-724Y3IOB.js} +1 -2
  18. package/dist/{context-F63RSIBH.js → context-JGKU4M7Z.js} +2 -4
  19. package/dist/doctor-Y3DWDEBT.js +18 -0
  20. package/dist/{fleet-YQ35KGEP.js → fleet-4FYZ3GBK.js} +11 -12
  21. package/dist/{gates-DU6SDH2M.js → gates-IBQ7HCAN.js} +6 -7
  22. package/dist/generate-KEX75XNG.js +5 -0
  23. package/dist/index.d.ts +173 -2
  24. package/dist/index.js +713 -198
  25. package/dist/{init-XJEYU2HC.js → init-H57H2JBE.js} +14 -13
  26. package/dist/ledger-T54JDHGP.js +6 -0
  27. package/dist/premise-VMC3UUIB.js +333 -0
  28. package/dist/scan-W4US23MU.js +5 -0
  29. package/dist/{scan-B24RZAV2.js → scan-XBOHDXAH.js} +5 -5
  30. package/dist/{screen-CS6PSG7U.js → screen-E4FC7W5N.js} +2 -1
  31. package/package.json +2 -2
  32. package/dist/audit-YRT4SWSQ.js +0 -12
  33. package/dist/chunk-F75Q43BC.js +0 -59
  34. package/dist/chunk-JHZ2BN4U.js +0 -67
  35. package/dist/doctor-7YKDXSKM.js +0 -19
  36. package/dist/generate-PMCP37DC.js +0 -6
  37. package/dist/ledger-4FOZ5HAB.js +0 -5
  38. package/dist/scan-QDNN7ER3.js +0 -5
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env node
2
- import { parseFailOnTier, runAudit, meetsFailOn } from './chunk-PXRLOEN5.js';
3
- import { print, section, theme, renderLensCoverage, renderFindings, renderLedgerDiff } from './chunk-5BVKFJWM.js';
2
+ import { runAudit } from './chunk-2RNQ6OLV.js';
3
+ import { parseFailOnTier, meetsFailOn } from './chunk-IWG77WV3.js';
4
+ import { print, section, theme, renderLensCoverage, renderFindings, renderLedgerDiff } from './chunk-HI7NWPRA.js';
4
5
 
5
6
  // src/commands/audit.ts
6
7
  async function run(opts) {
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  // package.json
3
3
  var package_default = {
4
- version: "0.13.0"};
4
+ version: "0.15.0"};
5
5
 
6
6
  // src/version.ts
7
7
  var VERSION = package_default.version;
@@ -1,6 +1,77 @@
1
1
  #!/usr/bin/env node
2
+ import { DEFAULT_CONFIG } from './chunk-P6ATKV2R.js';
3
+ import { readText, pathExists, approxTokens, wordCount } from './chunk-4VPBP6K6.js';
4
+ import { promises } from 'fs';
5
+ import path from 'path';
2
6
  import pc from 'picocolors';
3
7
 
8
+ var ALWAYS_LOADED = [
9
+ { path: "AGENTS.md", role: "operating contract" },
10
+ { path: "PROJECT_CONTEXT.md", role: "ground-truth state" },
11
+ { path: "CLAUDE.md", role: "Claude Code pointer" },
12
+ { path: "GEMINI.md", role: "Gemini pointer" },
13
+ { path: ".github/copilot-instructions.md", role: "Copilot instructions" },
14
+ { path: ".cursorrules", role: "Cursor rules (legacy)" }
15
+ ];
16
+ var EXTRACTION_THRESHOLD = DEFAULT_CONFIG.context.perFileWords;
17
+ function isAlwaysAppliedCursorRule(text) {
18
+ const fm = text.match(/^---\n([\s\S]*?)\n---/);
19
+ if (!fm) return true;
20
+ const frontmatter = fm[1] ?? "";
21
+ return /^\s*alwaysApply\s*:\s*true\s*$/m.test(frontmatter);
22
+ }
23
+ async function inodeKey(abs) {
24
+ try {
25
+ const st = await promises.stat(abs);
26
+ return st.ino ? `${st.dev}:${st.ino}` : null;
27
+ } catch {
28
+ return null;
29
+ }
30
+ }
31
+ function contextFileLabel(file) {
32
+ return file.aliases?.length ? [file.path, ...file.aliases].join(" \u2192 ") : file.path;
33
+ }
34
+ async function measureContext(root, perFileWords = EXTRACTION_THRESHOLD) {
35
+ const files = [];
36
+ const byInode = /* @__PURE__ */ new Map();
37
+ const record = async (rel, role, text) => {
38
+ const words = wordCount(text);
39
+ const key = await inodeKey(path.join(root, rel));
40
+ const seen = key ? byInode.get(key) : void 0;
41
+ if (seen) {
42
+ seen.aliases = [...seen.aliases ?? [], rel];
43
+ return;
44
+ }
45
+ const file = { path: rel, role, words, approxTokens: approxTokens(words) };
46
+ if (key) byInode.set(key, file);
47
+ files.push(file);
48
+ };
49
+ for (const spec of ALWAYS_LOADED) {
50
+ const text = await readText(path.join(root, spec.path));
51
+ if (text === null) continue;
52
+ await record(spec.path, spec.role, text);
53
+ }
54
+ const rulesDir = path.join(root, ".cursor", "rules");
55
+ if (await pathExists(rulesDir)) {
56
+ try {
57
+ for (const entry of await promises.readdir(rulesDir)) {
58
+ if (!entry.endsWith(".mdc") && !entry.endsWith(".md")) continue;
59
+ const text = await readText(path.join(rulesDir, entry));
60
+ if (text === null || !isAlwaysAppliedCursorRule(text)) continue;
61
+ await record(`.cursor/rules/${entry}`, "Cursor rule (always applied)", text);
62
+ }
63
+ } catch {
64
+ }
65
+ }
66
+ const totalWords = files.reduce((s, f) => s + f.words, 0);
67
+ return {
68
+ files: files.sort((a, b) => b.words - a.words),
69
+ totalWords,
70
+ totalApproxTokens: approxTokens(totalWords),
71
+ perFileWords,
72
+ extractionCandidates: files.filter((f) => f.words >= perFileWords)
73
+ };
74
+ }
4
75
  var theme = {
5
76
  brand: (s) => pc.magenta(pc.bold(s)),
6
77
  heading: (s) => pc.bold(s),
@@ -103,11 +174,13 @@ function renderContext(budget, threshold) {
103
174
  print(` ${theme.dim("no always-loaded agent files found \u2014 nothing loads every session yet")}`);
104
175
  return;
105
176
  }
106
- const pathWidth = maxWidth(budget.files.map((f) => f.path));
177
+ const pathWidth = maxWidth(budget.files.map((f) => contextFileLabel(f)));
107
178
  for (const f of budget.files) {
108
179
  const heavy = f.words >= threshold;
109
180
  const words = heavy ? theme.warn(`${f.words} w`) : `${f.words} w`;
110
- print(` ${pad(theme.info(f.path), pathWidth)} ${pad(words, 12)} ${theme.dim(f.role)}`);
181
+ print(
182
+ ` ${pad(theme.info(contextFileLabel(f)), pathWidth)} ${pad(words, 12)} ${theme.dim(f.role)}`
183
+ );
111
184
  }
112
185
  print();
113
186
  keyValues([
@@ -122,7 +195,9 @@ function renderContext(budget, threshold) {
122
195
  ` ${theme.dim("These load every session but are rarely all needed. Move to an on-demand skill:")}`
123
196
  );
124
197
  for (const f of budget.extractionCandidates) {
125
- print(` ${glyph.arrow} ${theme.info(f.path)} ${theme.dim(`(${f.words} words)`)}`);
198
+ print(
199
+ ` ${glyph.arrow} ${theme.info(contextFileLabel(f))} ${theme.dim(`(${f.words} words)`)}`
200
+ );
126
201
  }
127
202
  } else {
128
203
  print(` ${glyph.ok} ${theme.dim("lean \u2014 no single file is heavy enough to extract yet")}`);
@@ -262,4 +337,4 @@ function renderLedger(ledger) {
262
337
  }
263
338
  }
264
339
 
265
- export { TIER_BADGE, glyph, print, renderBaselineDrift, renderContext, renderFacts, renderFindings, renderFleetNotes, renderFleetRows, renderLedger, renderLedgerDiff, renderLensCoverage, renderPlan, section, theme };
340
+ export { TIER_BADGE, contextFileLabel, glyph, measureContext, print, renderBaselineDrift, renderContext, renderFacts, renderFindings, renderFleetNotes, renderFleetRows, renderLedger, renderLedgerDiff, renderLensCoverage, renderPlan, section, theme };
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { readLedger, resolveEntry, writeLedger } from './chunk-3E2IPCRY.js';
3
- import { print, renderLedger, glyph, theme } from './chunk-5BVKFJWM.js';
3
+ import { print, renderLedger, glyph, theme } from './chunk-HI7NWPRA.js';
4
4
 
5
5
  // src/commands/ledger.ts
6
6
  async function list(opts) {