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.
Files changed (39) hide show
  1. package/CHANGELOG.md +66 -0
  2. package/README.md +23 -2
  3. package/dist/{approve-6TMXJLOI.js → approve-OUJ4UPGK.js} +5 -5
  4. package/dist/audit-A75FVXHD.js +12 -0
  5. package/dist/{brief-X64HK325.js → brief-MYUESUMM.js} +7 -7
  6. package/dist/{chunk-SGW7OPHZ.js → chunk-2KVQBL4E.js} +1 -1
  7. package/dist/{chunk-V2SOHPXF.js → chunk-2VLNI3L2.js} +1 -1
  8. package/dist/{chunk-OAFYLBVG.js → chunk-3E2IPCRY.js} +3 -3
  9. package/dist/{chunk-IV3FYVTS.js → chunk-4VPBP6K6.js} +4 -3
  10. package/dist/{chunk-WTD2EIMN.js → chunk-5GQ52DK6.js} +5 -5
  11. package/dist/{chunk-YVGC3E6U.js → chunk-DWL2IKZH.js} +3 -3
  12. package/dist/{chunk-IPOAD67U.js → chunk-F75Q43BC.js} +4 -4
  13. package/dist/{chunk-EF6BPBG6.js → chunk-GWGKEPRX.js} +2 -2
  14. package/dist/{chunk-R6CVJ5D7.js → chunk-HRJJQCMT.js} +9 -13
  15. package/dist/{chunk-K34AVLDP.js → chunk-J7XVOTZL.js} +1 -1
  16. package/dist/{chunk-C7LBUFNU.js → chunk-JHZ2BN4U.js} +3 -3
  17. package/dist/{chunk-KQMQJJZK.js → chunk-JVLWM27I.js} +9 -9
  18. package/dist/{chunk-OIYNP6Y6.js → chunk-LSZGCKIQ.js} +1 -1
  19. package/dist/cli.js +19 -19
  20. package/dist/config-XAH6PA5G.js +4 -0
  21. package/dist/{context-K6DZNWAV.js → context-F63RSIBH.js} +4 -4
  22. package/dist/doctor-OZQTOUFR.js +19 -0
  23. package/dist/{fleet-4PPNUIDJ.js → fleet-Z7W3QBEV.js} +18 -18
  24. package/dist/{gates-Q7FMVUQP.js → gates-47YTMMLZ.js} +10 -10
  25. package/dist/generate-PMCP37DC.js +6 -0
  26. package/dist/index.d.ts +1 -1
  27. package/dist/index.js +137 -141
  28. package/dist/{init-YYGRFIHQ.js → init-QLGIYFCX.js} +10 -10
  29. package/dist/ledger-4FOZ5HAB.js +5 -0
  30. package/dist/{scan-VO776GM7.js → scan-VWEXWM6G.js} +5 -5
  31. package/dist/scan-W7RHZVSF.js +5 -0
  32. package/dist/{screen-MOQP6XC7.js → screen-NSWNC7VQ.js} +80 -10
  33. package/package.json +4 -4
  34. package/dist/audit-FGDX2AYS.js +0 -12
  35. package/dist/config-TPK5LYDM.js +0 -4
  36. package/dist/doctor-W3UZK7KS.js +0 -19
  37. package/dist/generate-NLHGTRZB.js +0 -6
  38. package/dist/ledger-B2XGANTH.js +0 -5
  39. package/dist/scan-PJSZGUG7.js +0 -5
package/dist/index.js CHANGED
@@ -1,10 +1,10 @@
1
- import { execFile } from 'node:child_process';
2
- import { promises } from 'node:fs';
3
- import { promisify } from 'node:util';
4
- import path from 'node:path';
5
- import { createHash } from 'node:crypto';
1
+ import { execFile } from 'child_process';
2
+ import { promises } from 'fs';
3
+ import path2 from 'path';
4
+ import { promisify } from 'util';
5
+ import { createHash } from 'crypto';
6
6
  import YAML from 'yaml';
7
- import os from 'node:os';
7
+ import os from 'os';
8
8
 
9
9
  var __defProp = Object.defineProperty;
10
10
  var __getOwnPropNames = Object.getOwnPropertyNames;
@@ -20,7 +20,7 @@ var __export = (target, all) => {
20
20
  var PACK_VERSION;
21
21
  var init_version = __esm({
22
22
  "src/pack/version.ts"() {
23
- PACK_VERSION = "7";
23
+ PACK_VERSION = "8";
24
24
  }
25
25
  });
26
26
 
@@ -30,7 +30,7 @@ var init_package = __esm({
30
30
  "package.json"() {
31
31
  package_default = {
32
32
  name: "etymd",
33
- version: "0.10.0",
33
+ version: "0.11.0",
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",
@@ -99,12 +99,12 @@ var init_package = __esm({
99
99
  yaml: "2.9.0"
100
100
  },
101
101
  devDependencies: {
102
- "@changesets/cli": "2.27.11",
102
+ "@changesets/cli": "2.31.1",
103
103
  "@types/node": "22.10.2",
104
104
  prettier: "3.4.2",
105
- tsup: "8.3.5",
105
+ tsup: "8.5.1",
106
106
  typescript: "5.7.2",
107
- vitest: "2.1.8"
107
+ vitest: "4.1.10"
108
108
  },
109
109
  publishConfig: {
110
110
  access: "public"
@@ -244,15 +244,15 @@ async function detectPackageManager(root, pkg) {
244
244
  ["bun.lockb", "bun"]
245
245
  ];
246
246
  for (const [file, pm] of lock) {
247
- if (await pathExists(path.join(root, file))) return pm;
247
+ if (await pathExists(path2.join(root, file))) return pm;
248
248
  }
249
249
  return "unknown";
250
250
  }
251
251
  async function detectWorkspace(root, pkg) {
252
- if (await pathExists(path.join(root, "nx.json"))) return { kind: "nx", packageGlobs: [] };
253
- if (await pathExists(path.join(root, "turbo.json"))) return { kind: "turbo", packageGlobs: [] };
254
- if (await pathExists(path.join(root, "lerna.json"))) return { kind: "lerna", packageGlobs: [] };
255
- const pnpmWs = await readText(path.join(root, "pnpm-workspace.yaml"));
252
+ if (await pathExists(path2.join(root, "nx.json"))) return { kind: "nx", packageGlobs: [] };
253
+ if (await pathExists(path2.join(root, "turbo.json"))) return { kind: "turbo", packageGlobs: [] };
254
+ if (await pathExists(path2.join(root, "lerna.json"))) return { kind: "lerna", packageGlobs: [] };
255
+ const pnpmWs = await readText(path2.join(root, "pnpm-workspace.yaml"));
256
256
  if (pnpmWs) {
257
257
  const globs = pnpmWs.split("\n").map((l) => l.match(/^\s*-\s*["']?([^"'#]+)["']?/)?.[1]?.trim()).filter((g) => Boolean(g));
258
258
  return { kind: "pnpm", packageGlobs: globs };
@@ -270,21 +270,21 @@ async function listWorkspacePackages(root, globs) {
270
270
  const found = [];
271
271
  const seen = /* @__PURE__ */ new Set();
272
272
  const addFromDir = async (dir) => {
273
- const pkgPath = path.join(dir, "package.json");
273
+ const pkgPath = path2.join(dir, "package.json");
274
274
  if (seen.has(pkgPath)) return;
275
275
  const pkg = await readJson(pkgPath);
276
276
  if (!pkg?.name) return;
277
277
  seen.add(pkgPath);
278
278
  found.push({
279
279
  name: pkg.name,
280
- dir: path.relative(root, dir) || ".",
280
+ dir: path2.relative(root, dir) || ".",
281
281
  private: Boolean(pkg.private),
282
282
  version: pkg.version
283
283
  });
284
284
  };
285
285
  for (const glob of globs) {
286
286
  const base = glob.replace(/\/\*\*?$/, "");
287
- const parent = path.join(root, base);
287
+ const parent = path2.join(root, base);
288
288
  if (!await isDirectory(parent)) continue;
289
289
  let entries;
290
290
  try {
@@ -294,7 +294,7 @@ async function listWorkspacePackages(root, globs) {
294
294
  }
295
295
  for (const entry of entries) {
296
296
  if (IGNORED_DIRS.has(entry) || entry.startsWith(".")) continue;
297
- const child = path.join(parent, entry);
297
+ const child = path2.join(parent, entry);
298
298
  if (await isDirectory(child)) await addFromDir(child);
299
299
  }
300
300
  }
@@ -307,7 +307,7 @@ async function expandFileGlobs(root, globs, cap = 500) {
307
307
  if (out.size >= cap) return;
308
308
  let entries;
309
309
  try {
310
- entries = await promises.readdir(path.join(root, rel), { withFileTypes: true });
310
+ entries = await promises.readdir(path2.join(root, rel), { withFileTypes: true });
311
311
  } catch {
312
312
  return;
313
313
  }
@@ -334,7 +334,7 @@ async function expandFileGlobs(root, globs, cap = 500) {
334
334
  (r) => ![...roots].some((other) => other !== r && (other === "" || r.startsWith(other + "/")))
335
335
  );
336
336
  for (const r of minimal) {
337
- if (r && !await isDirectory(path.join(root, r))) continue;
337
+ if (r && !await isDirectory(path2.join(root, r))) continue;
338
338
  await walk(r);
339
339
  }
340
340
  return [...out].sort();
@@ -363,13 +363,13 @@ function detectFrameworks(pkg) {
363
363
  return out;
364
364
  }
365
365
  async function detectCi(root) {
366
- if (await pathExists(path.join(root, ".gitlab-ci.yml"))) {
366
+ if (await pathExists(path2.join(root, ".gitlab-ci.yml"))) {
367
367
  return { system: "gitlab", files: [".gitlab-ci.yml"] };
368
368
  }
369
- const workflows = path.join(root, ".github", "workflows");
369
+ const workflows = path2.join(root, ".github", "workflows");
370
370
  if (await isDirectory(workflows)) {
371
371
  try {
372
- const files = (await promises.readdir(workflows)).filter((f) => f.endsWith(".yml") || f.endsWith(".yaml")).map((f) => path.join(".github/workflows", f));
372
+ const files = (await promises.readdir(workflows)).filter((f) => f.endsWith(".yml") || f.endsWith(".yaml")).map((f) => path2.join(".github/workflows", f));
373
373
  if (files.length) return { system: "github", files };
374
374
  } catch {
375
375
  }
@@ -384,7 +384,7 @@ async function hasLintStagedConfig(root, pkg) {
384
384
  ".lintstagedrc.js",
385
385
  "lint-staged.config.js"
386
386
  ]) {
387
- if (await pathExists(path.join(root, f))) return true;
387
+ if (await pathExists(path2.join(root, f))) return true;
388
388
  }
389
389
  return false;
390
390
  }
@@ -392,50 +392,50 @@ async function detectHooks(root, hooksPath, pkg) {
392
392
  const lintStaged = await hasLintStagedConfig(root, pkg);
393
393
  if (hooksPath) {
394
394
  if (hooksPath.replace(/\/+$/, "") === ".husky/_") {
395
- const base2 = path.join(root, ".husky");
395
+ const base2 = path2.join(root, ".husky");
396
396
  return {
397
397
  source: "husky",
398
398
  dir: ".husky",
399
- preCommit: await pathExists(path.join(base2, "pre-commit")),
400
- prePush: await pathExists(path.join(base2, "pre-push")),
401
- commitMsg: await pathExists(path.join(base2, "commit-msg")),
399
+ preCommit: await pathExists(path2.join(base2, "pre-commit")),
400
+ prePush: await pathExists(path2.join(base2, "pre-push")),
401
+ commitMsg: await pathExists(path2.join(base2, "commit-msg")),
402
402
  lintStaged
403
403
  };
404
404
  }
405
- const base = path.join(root, hooksPath);
405
+ const base = path2.join(root, hooksPath);
406
406
  return {
407
407
  source: hooksPath === ".githooks" ? "githooks" : "custom",
408
408
  dir: hooksPath,
409
- preCommit: await pathExists(path.join(base, "pre-commit")),
410
- prePush: await pathExists(path.join(base, "pre-push")),
411
- commitMsg: await pathExists(path.join(base, "commit-msg")),
409
+ preCommit: await pathExists(path2.join(base, "pre-commit")),
410
+ prePush: await pathExists(path2.join(base, "pre-push")),
411
+ commitMsg: await pathExists(path2.join(base, "commit-msg")),
412
412
  lintStaged
413
413
  };
414
414
  }
415
- if (await isDirectory(path.join(root, ".githooks"))) {
416
- const base = path.join(root, ".githooks");
415
+ if (await isDirectory(path2.join(root, ".githooks"))) {
416
+ const base = path2.join(root, ".githooks");
417
417
  return {
418
418
  source: "githooks",
419
419
  dir: ".githooks",
420
- preCommit: await pathExists(path.join(base, "pre-commit")),
421
- prePush: await pathExists(path.join(base, "pre-push")),
422
- commitMsg: await pathExists(path.join(base, "commit-msg")),
420
+ preCommit: await pathExists(path2.join(base, "pre-commit")),
421
+ prePush: await pathExists(path2.join(base, "pre-push")),
422
+ commitMsg: await pathExists(path2.join(base, "commit-msg")),
423
423
  lintStaged
424
424
  };
425
425
  }
426
- if (await isDirectory(path.join(root, ".husky"))) {
427
- const base = path.join(root, ".husky");
426
+ if (await isDirectory(path2.join(root, ".husky"))) {
427
+ const base = path2.join(root, ".husky");
428
428
  return {
429
429
  source: "husky",
430
430
  dir: ".husky",
431
- preCommit: await pathExists(path.join(base, "pre-commit")),
432
- prePush: await pathExists(path.join(base, "pre-push")),
433
- commitMsg: await pathExists(path.join(base, "commit-msg")),
431
+ preCommit: await pathExists(path2.join(base, "pre-commit")),
432
+ prePush: await pathExists(path2.join(base, "pre-push")),
433
+ commitMsg: await pathExists(path2.join(base, "commit-msg")),
434
434
  lintStaged
435
435
  };
436
436
  }
437
437
  const legacyHooks = pkg?.husky?.hooks;
438
- const configText = legacyHooks ? null : await readText(path.join(root, "husky.config.js"));
438
+ const configText = legacyHooks ? null : await readText(path2.join(root, "husky.config.js"));
439
439
  if (legacyHooks || configText) {
440
440
  const hookNamed = (name) => legacyHooks ? Boolean(legacyHooks[name]) : Boolean(configText && configText.includes(name));
441
441
  return {
@@ -466,10 +466,10 @@ async function detectShellSurface(root, isRepo) {
466
466
  if (!listed) return { scripts: 0 };
467
467
  const files = listed.split("\0").filter(Boolean);
468
468
  const byExtension = files.filter((f) => SHELL_EXT.test(f));
469
- const candidates = files.filter((f) => !path.basename(f).includes("."));
469
+ const candidates = files.filter((f) => !path2.basename(f).includes("."));
470
470
  const SHEBANG_PROBE_CAP = 400;
471
471
  const probed = await Promise.all(
472
- candidates.slice(0, SHEBANG_PROBE_CAP).map(async (f) => SHELL_SHEBANG.test(await firstLine(path.join(root, f))))
472
+ candidates.slice(0, SHEBANG_PROBE_CAP).map(async (f) => SHELL_SHEBANG.test(await firstLine(path2.join(root, f))))
473
473
  );
474
474
  return { scripts: byExtension.length + probed.filter(Boolean).length };
475
475
  }
@@ -477,12 +477,12 @@ async function detectArtifacts(root) {
477
477
  const artifacts = await Promise.all(
478
478
  ARTIFACT_SPECS.map(async (spec) => ({
479
479
  ...spec,
480
- exists: await pathExists(path.join(root, spec.path))
480
+ exists: await pathExists(path2.join(root, spec.path))
481
481
  }))
482
482
  );
483
483
  let adrFiles = false;
484
484
  try {
485
- adrFiles = (await promises.readdir(path.join(root, "docs"))).some((f) => /^\d{4}-.+\.md$/.test(f));
485
+ adrFiles = (await promises.readdir(path2.join(root, "docs"))).some((f) => /^\d{4}-.+\.md$/.test(f));
486
486
  } catch {
487
487
  }
488
488
  artifacts.push({
@@ -511,7 +511,7 @@ async function walkTree(root) {
511
511
  for (const entry of entries) {
512
512
  if (entry.name.startsWith(".") || IGNORED_DIRS.has(entry.name)) continue;
513
513
  if (entry.isDirectory()) {
514
- total += await countFiles(path.join(dir, entry.name));
514
+ total += await countFiles(path2.join(dir, entry.name));
515
515
  } else if (entry.isFile()) {
516
516
  total += 1;
517
517
  state.budget -= 1;
@@ -534,7 +534,7 @@ async function walkTree(root) {
534
534
  if (!entry.isDirectory()) continue;
535
535
  if (IGNORED_DIRS.has(entry.name)) continue;
536
536
  if (entry.name.startsWith(".") && !MEANINGFUL_DOT_DIRS.has(entry.name)) continue;
537
- dirs.push({ name: entry.name, files: await countFiles(path.join(root, entry.name)) });
537
+ dirs.push({ name: entry.name, files: await countFiles(path2.join(root, entry.name)) });
538
538
  }
539
539
  dirs.sort((a, b) => b.files - a.files);
540
540
  return { dirs, truncated: state.truncated };
@@ -782,8 +782,8 @@ async function collectFreshness(abs, isRepo, artifacts, upstreamRemote) {
782
782
  return facts;
783
783
  }
784
784
  async function scanProject(root, opts = {}) {
785
- const abs = path.resolve(root);
786
- const rootPkg = await readJson(path.join(abs, "package.json"));
785
+ const abs = path2.resolve(root);
786
+ const rootPkg = await readJson(path2.join(abs, "package.json"));
787
787
  const [packageManager, workspace, ci, artifacts, tree, isRepo] = await Promise.all([
788
788
  detectPackageManager(abs, rootPkg),
789
789
  detectWorkspace(abs, rootPkg),
@@ -810,7 +810,7 @@ async function scanProject(root, opts = {}) {
810
810
  packVersion: PACK_VERSION,
811
811
  generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
812
812
  root: abs,
813
- name: rootPkg?.name ?? path.basename(abs),
813
+ name: rootPkg?.name ?? path2.basename(abs),
814
814
  git: {
815
815
  isRepo,
816
816
  branch: branch ?? void 0,
@@ -847,13 +847,13 @@ var init_scan = __esm({
847
847
  }
848
848
  });
849
849
  function cacheFactsPath(root) {
850
- return path.join(root, CACHE_FACTS_FILE);
850
+ return path2.join(root, CACHE_FACTS_FILE);
851
851
  }
852
852
  function baselinePath(root) {
853
- return path.join(root, BASELINE_FILE);
853
+ return path2.join(root, BASELINE_FILE);
854
854
  }
855
855
  async function writeJsonFile(target, data) {
856
- await promises.mkdir(path.dirname(target), { recursive: true });
856
+ await promises.mkdir(path2.dirname(target), { recursive: true });
857
857
  await promises.writeFile(target, JSON.stringify(data, null, 2) + "\n", "utf8");
858
858
  return target;
859
859
  }
@@ -887,9 +887,9 @@ var init_facts = __esm({
887
887
  "src/core/facts.ts"() {
888
888
  init_util();
889
889
  ETYMD_DIR = ".etymd";
890
- CACHE_DIR = path.join(ETYMD_DIR, "cache");
891
- CACHE_FACTS_FILE = path.join(CACHE_DIR, "facts.json");
892
- BASELINE_FILE = path.join(ETYMD_DIR, "baseline.json");
890
+ CACHE_DIR = path2.join(ETYMD_DIR, "cache");
891
+ CACHE_FACTS_FILE = path2.join(CACHE_DIR, "facts.json");
892
+ BASELINE_FILE = path2.join(ETYMD_DIR, "baseline.json");
893
893
  }
894
894
  });
895
895
 
@@ -902,7 +902,7 @@ __export(config_exports, {
902
902
  readConfig: () => readConfig
903
903
  });
904
904
  function configPath(root) {
905
- return path.join(root, CONFIG_FILE);
905
+ return path2.join(root, CONFIG_FILE);
906
906
  }
907
907
  function readGlobList(value, key, problems) {
908
908
  if (value === void 0) return void 0;
@@ -1001,7 +1001,7 @@ var init_config = __esm({
1001
1001
  "src/core/config.ts"() {
1002
1002
  init_facts();
1003
1003
  init_util();
1004
- CONFIG_FILE = path.join(ETYMD_DIR, "config.json");
1004
+ CONFIG_FILE = path2.join(ETYMD_DIR, "config.json");
1005
1005
  DEFAULT_CONFIG = {
1006
1006
  instructions: { include: [], exclude: [] },
1007
1007
  context: { perFileWords: 4e3, totalWords: 8e3 },
@@ -1269,7 +1269,7 @@ ${auditStep}
1269
1269
  # with --no-verify and anything a rebase or merge brought in from elsewhere. Advisory here (it
1270
1270
  # never blocks the push): the blocking decision belongs at commit time, where the fix is cheap.
1271
1271
  ${CONTENT_GATE_RESOLUTION}
1272
- if [ -x "$GATE" ] && [ "\${CONTENT_GATE_PREPUSH:-1}" = "1" ]; then
1272
+ if [ -x "$GATE" ]; then
1273
1273
  "$GATE" screen --tree --advisory || true
1274
1274
  fi
1275
1275
 
@@ -1283,14 +1283,10 @@ function generateArtifactCheckScript() {
1283
1283
  # Wire it into the irreversible moment:
1284
1284
  # package.json \u2192 "prepublishOnly": "./scripts/artifact-check.sh"
1285
1285
  #
1286
- # No-op where no checker is installed. Bypass is deliberate and loud: ARTIFACT_CHECK_SKIP=1.
1286
+ # The artifact gate is the one check that sees what actually SHIPS \u2014 bypass with
1287
+ # .etymd-screen-allow entries (with provenance) if you must exempt a string.
1287
1288
  set -eu
1288
1289
 
1289
- if [ "\${ARTIFACT_CHECK_SKIP:-0}" = "1" ]; then
1290
- echo "\u203A artifact-check: SKIPPED by ARTIFACT_CHECK_SKIP=1"
1291
- exit 0
1292
- fi
1293
-
1294
1290
  ${CONTENT_GATE_RESOLUTION}
1295
1291
  [ -x "$GATE" ] || { echo "\u203A artifact-check: no checker installed \u2014 skipping."; exit 0; }
1296
1292
 
@@ -1313,7 +1309,7 @@ var init_templates = __esm({
1313
1309
  "src/pack/templates.ts"() {
1314
1310
  init_version();
1315
1311
  GENERATION_MARKER_RE = /^(?:# |<!-- )etymd:generated pack-v\S+ ([0-9a-f]{16})(?: -->)?$/;
1316
- CONTENT_GATE_RESOLUTION = `GATE="\${CONTENT_GATE:-$(command -v etymd || true)}"`;
1312
+ CONTENT_GATE_RESOLUTION = `GATE="\${CONTENT_GATE:-$(if [ -x ./dist/cli.js ]; then echo ./dist/cli.js; else command -v etymd || true; fi)}"`;
1317
1313
  COMMIT_TYPES = [
1318
1314
  "feat",
1319
1315
  "fix",
@@ -1370,7 +1366,7 @@ function deriveFailOn(facts, recorded) {
1370
1366
  async function planWorkflow(root, facts, opts) {
1371
1367
  const out = [];
1372
1368
  const add = async (rel, contents, label, executable = false) => {
1373
- const abs = path.join(root, rel);
1369
+ const abs = path2.join(root, rel);
1374
1370
  const exists = await pathExists(abs);
1375
1371
  const existing = exists ? await readText(abs) : null;
1376
1372
  const differs = exists ? existing !== contents : void 0;
@@ -1389,7 +1385,7 @@ async function planWorkflow(root, facts, opts) {
1389
1385
  await add("AGENTS.md", generateAgentsMd(facts), "Minimal operating contract (scaffold)");
1390
1386
  }
1391
1387
  if (opts.gates) {
1392
- const existingPrePush = await readText(path.join(root, ".githooks", "pre-push"));
1388
+ const existingPrePush = await readText(path2.join(root, ".githooks", "pre-push"));
1393
1389
  await add(".githooks/pre-commit", generatePreCommitHook(), "Process gate (pre-commit)", true);
1394
1390
  await add(
1395
1391
  ".githooks/commit-msg",
@@ -1453,18 +1449,18 @@ function isAlwaysAppliedCursorRule(text) {
1453
1449
  async function measureContext(root, perFileWords = EXTRACTION_THRESHOLD) {
1454
1450
  const files = [];
1455
1451
  for (const spec of ALWAYS_LOADED) {
1456
- const abs = path.join(root, spec.path);
1452
+ const abs = path2.join(root, spec.path);
1457
1453
  const text = await readText(abs);
1458
1454
  if (text === null) continue;
1459
1455
  const words = wordCount(text);
1460
1456
  files.push({ path: spec.path, role: spec.role, words, approxTokens: approxTokens(words) });
1461
1457
  }
1462
- const rulesDir = path.join(root, ".cursor", "rules");
1458
+ const rulesDir = path2.join(root, ".cursor", "rules");
1463
1459
  if (await pathExists(rulesDir)) {
1464
1460
  try {
1465
1461
  for (const entry of await promises.readdir(rulesDir)) {
1466
1462
  if (!entry.endsWith(".mdc") && !entry.endsWith(".md")) continue;
1467
- const text = await readText(path.join(rulesDir, entry));
1463
+ const text = await readText(path2.join(rulesDir, entry));
1468
1464
  if (text === null || !isAlwaysAppliedCursorRule(text)) continue;
1469
1465
  const words = wordCount(text);
1470
1466
  files.push({
@@ -1497,8 +1493,8 @@ async function applyFiles(root, files, overwrite = /* @__PURE__ */ new Set()) {
1497
1493
  skipped.push(file.path);
1498
1494
  continue;
1499
1495
  }
1500
- const abs = path.join(root, file.path);
1501
- await promises.mkdir(path.dirname(abs), { recursive: true });
1496
+ const abs = path2.join(root, file.path);
1497
+ await promises.mkdir(path2.dirname(abs), { recursive: true });
1502
1498
  await promises.writeFile(abs, file.contents, "utf8");
1503
1499
  if (file.executable) await promises.chmod(abs, 493);
1504
1500
  written.push(file.path);
@@ -1799,14 +1795,14 @@ function parseGithubWorkflow(text, file, scripts) {
1799
1795
  return { jobs, parseErrors };
1800
1796
  }
1801
1797
  async function companionOf(root, hooksDir, hook, hookText, scripts) {
1802
- const rel = path.posix.join(hooksDir.split(path.sep).join("/"), `${hook}.local`);
1798
+ const rel = path2.posix.join(hooksDir.split(path2.sep).join("/"), `${hook}.local`);
1803
1799
  if (!hookText.includes(`${hook}.local`)) return null;
1804
- const abs = path.join(root, hooksDir, `${hook}.local`);
1800
+ const abs = path2.join(root, hooksDir, `${hook}.local`);
1805
1801
  const text = await readText(abs);
1806
1802
  if (text === null) return null;
1807
1803
  const [executable, hookExecutable] = await Promise.all([
1808
1804
  isExecutable(abs),
1809
- isExecutable(path.join(root, hooksDir, hook))
1805
+ isExecutable(path2.join(root, hooksDir, hook))
1810
1806
  ]);
1811
1807
  if (executable === false && hookExecutable === true) return { rel, tools: [], state: "inert" };
1812
1808
  return {
@@ -1823,7 +1819,7 @@ async function localHookTools(root, facts, scripts) {
1823
1819
  const inertCompanions = [];
1824
1820
  const readHook = async (name) => {
1825
1821
  if (!hooks.dir) return empty;
1826
- const text = await readText(path.join(root, hooks.dir, name));
1822
+ const text = await readText(path2.join(root, hooks.dir, name));
1827
1823
  if (!text) return empty;
1828
1824
  const tools = new Set(matchTools(text, scripts));
1829
1825
  const companion = await companionOf(root, hooks.dir, name, text, scripts);
@@ -1847,10 +1843,10 @@ async function localHookTools(root, facts, scripts) {
1847
1843
  ]);
1848
1844
  } else if (hooks.source === "husky-legacy") {
1849
1845
  const pkg = await readJson(
1850
- path.join(root, "package.json")
1846
+ path2.join(root, "package.json")
1851
1847
  );
1852
1848
  const legacy = pkg?.husky?.hooks ?? {};
1853
- const configText = await readText(path.join(root, "husky.config.js"));
1849
+ const configText = await readText(path2.join(root, "husky.config.js"));
1854
1850
  const forHook = (name) => {
1855
1851
  const cmd = legacy[name] ?? (configText?.includes(name) ? configText : void 0);
1856
1852
  return cmd ? matchTools(cmd, scripts) : [];
@@ -1861,7 +1857,7 @@ async function localHookTools(root, facts, scripts) {
1861
1857
  }
1862
1858
  let lintStaged = [];
1863
1859
  if (hooks.lintStaged) {
1864
- const pkg = await readJson(path.join(root, "package.json"));
1860
+ const pkg = await readJson(path2.join(root, "package.json"));
1865
1861
  const config = pkg?.["lint-staged"];
1866
1862
  const commands = [];
1867
1863
  const collect = (v) => {
@@ -1891,7 +1887,7 @@ async function localHookTools(root, facts, scripts) {
1891
1887
  };
1892
1888
  }
1893
1889
  async function detectThresholds(root, scripts, ciJobs) {
1894
- const sonarConfigured = await pathExists(path.join(root, "sonar-project.properties")) || ciJobs.some((j) => j.tools.includes("sonar"));
1890
+ const sonarConfigured = await pathExists(path2.join(root, "sonar-project.properties")) || ciJobs.some((j) => j.tools.includes("sonar"));
1895
1891
  let coverageThresholdLocal = false;
1896
1892
  for (const f of [
1897
1893
  "jest.config.js",
@@ -1903,7 +1899,7 @@ async function detectThresholds(root, scripts, ciJobs) {
1903
1899
  "vitest.config.js",
1904
1900
  "vitest.config.mts"
1905
1901
  ]) {
1906
- const text = await readText(path.join(root, f));
1902
+ const text = await readText(path2.join(root, f));
1907
1903
  if (text && /coverageThreshold|thresholds\s*:/.test(text)) {
1908
1904
  coverageThresholdLocal = true;
1909
1905
  break;
@@ -1911,7 +1907,7 @@ async function detectThresholds(root, scripts, ciJobs) {
1911
1907
  }
1912
1908
  if (!coverageThresholdLocal) {
1913
1909
  const pkg = await readJson(
1914
- path.join(root, "package.json")
1910
+ path2.join(root, "package.json")
1915
1911
  );
1916
1912
  coverageThresholdLocal = Boolean(pkg?.jest?.coverageThreshold);
1917
1913
  }
@@ -1924,7 +1920,7 @@ async function buildGateInventory(root, facts) {
1924
1920
  const inheritedIncludes = [];
1925
1921
  const parseErrors = [];
1926
1922
  if (facts.ci.system === "gitlab") {
1927
- const text = await readText(path.join(root, ".gitlab-ci.yml"));
1923
+ const text = await readText(path2.join(root, ".gitlab-ci.yml"));
1928
1924
  if (text) {
1929
1925
  const parsed = parseGitlabCi(text, ".gitlab-ci.yml", scripts);
1930
1926
  jobs.push(...parsed.jobs);
@@ -1932,7 +1928,7 @@ async function buildGateInventory(root, facts) {
1932
1928
  for (const inc of parsed.inheritedIncludes) {
1933
1929
  if (inc.startsWith("local: ")) {
1934
1930
  const rel = inc.slice("local: ".length).replace(/^\//, "");
1935
- const subText = await readText(path.join(root, rel));
1931
+ const subText = await readText(path2.join(root, rel));
1936
1932
  if (subText) {
1937
1933
  const sub = parseGitlabCi(subText, rel, scripts);
1938
1934
  jobs.push(...sub.jobs);
@@ -1948,7 +1944,7 @@ async function buildGateInventory(root, facts) {
1948
1944
  }
1949
1945
  } else if (facts.ci.system === "github") {
1950
1946
  for (const file of facts.ci.files) {
1951
- const text = await readText(path.join(root, file));
1947
+ const text = await readText(path2.join(root, file));
1952
1948
  if (!text) continue;
1953
1949
  const parsed = parseGithubWorkflow(text, file, scripts);
1954
1950
  jobs.push(...parsed.jobs);
@@ -1959,7 +1955,7 @@ async function buildGateInventory(root, facts) {
1959
1955
  localHookTools(root, facts, scripts),
1960
1956
  detectThresholds(root, scripts, jobs)
1961
1957
  ]);
1962
- const pkg = await readJson(path.join(root, "package.json"));
1958
+ const pkg = await readJson(path2.join(root, "package.json"));
1963
1959
  const deps = { ...pkg?.dependencies, ...pkg?.devDependencies };
1964
1960
  const commitlintDep = Boolean(deps["@commitlint/cli"] ?? deps["commitlint"]);
1965
1961
  return {
@@ -2381,7 +2377,7 @@ var stateFreshnessLens = {
2381
2377
  }
2382
2378
  }
2383
2379
  for (const a of stateArtifacts) {
2384
- const text = await readText(path.join(ctx.root, a.path));
2380
+ const text = await readText(path2.join(ctx.root, a.path));
2385
2381
  if (text === null) {
2386
2382
  disclosures.push(`${a.path} could not be read \u2014 unexamined, not clean.`);
2387
2383
  outOfScope.push(a.path);
@@ -2402,7 +2398,7 @@ var stateFreshnessLens = {
2402
2398
  }
2403
2399
  }
2404
2400
  for (const a of decisionArtifacts) {
2405
- const text = await readText(path.join(ctx.root, a.path));
2401
+ const text = await readText(path2.join(ctx.root, a.path));
2406
2402
  if (text === null) {
2407
2403
  disclosures.push(
2408
2404
  `${a.path} recognized as a decisions convention (directory) \u2014 age-exempt; per-entry format checks apply only to marker-carrying decisions files.`
@@ -2455,7 +2451,7 @@ init_util();
2455
2451
  async function listInstructionFiles(root, facts, scope) {
2456
2452
  const files = [];
2457
2453
  const add = async (rel) => {
2458
- const text = await readText(path.join(root, rel));
2454
+ const text = await readText(path2.join(root, rel));
2459
2455
  if (text !== null) files.push({ path: normalizeRelPath(rel), text });
2460
2456
  };
2461
2457
  const singleFileArtifacts = [
@@ -2471,21 +2467,21 @@ async function listInstructionFiles(root, facts, scope) {
2471
2467
  const artifact = facts.artifacts.find((a) => a.id === id);
2472
2468
  if (artifact?.exists) await add(artifact.path);
2473
2469
  }
2474
- const rulesDir = path.join(root, ".cursor", "rules");
2470
+ const rulesDir = path2.join(root, ".cursor", "rules");
2475
2471
  if (await isDirectory(rulesDir)) {
2476
2472
  try {
2477
2473
  for (const entry of await promises.readdir(rulesDir)) {
2478
2474
  if (entry.endsWith(".md") || entry.endsWith(".mdc"))
2479
- await add(path.join(".cursor/rules", entry));
2475
+ await add(path2.join(".cursor/rules", entry));
2480
2476
  }
2481
2477
  } catch {
2482
2478
  }
2483
2479
  }
2484
- const skillsDir = path.join(root, ".claude", "skills");
2480
+ const skillsDir = path2.join(root, ".claude", "skills");
2485
2481
  if (await isDirectory(skillsDir)) {
2486
2482
  try {
2487
2483
  for (const entry of await promises.readdir(skillsDir)) {
2488
- const skill = path.join(".claude/skills", entry, "SKILL.md");
2484
+ const skill = path2.join(".claude/skills", entry, "SKILL.md");
2489
2485
  await add(skill);
2490
2486
  }
2491
2487
  } catch {
@@ -2513,7 +2509,7 @@ async function listStateDocuments(root, facts) {
2513
2509
  const docs = [];
2514
2510
  for (const artifact of facts.artifacts) {
2515
2511
  if (artifact.kind !== "state" || !artifact.exists) continue;
2516
- const text = await readText(path.join(root, artifact.path));
2512
+ const text = await readText(path2.join(root, artifact.path));
2517
2513
  if (text !== null) docs.push({ path: normalizeRelPath(artifact.path), text });
2518
2514
  }
2519
2515
  return docs;
@@ -2797,28 +2793,28 @@ var instructionTruthLens = {
2797
2793
  const knownScripts = new Set(Object.keys(facts.commands.raw));
2798
2794
  for (const pkg of facts.packages) {
2799
2795
  const pkgJson = await readJson(
2800
- path.join(root, pkg.dir, "package.json")
2796
+ path2.join(root, pkg.dir, "package.json")
2801
2797
  );
2802
2798
  for (const key of Object.keys(pkgJson?.scripts ?? {})) knownScripts.add(key);
2803
2799
  }
2804
2800
  const pathResolves = async (claim) => {
2805
- const bases = [root, ...facts.packages.map((p) => path.join(root, p.dir))];
2801
+ const bases = [root, ...facts.packages.map((p) => path2.join(root, p.dir))];
2806
2802
  for (const base of bases) {
2807
- if (await pathExists(path.join(base, claim))) return true;
2808
- if (await pathExists(path.join(base, "src", claim))) return true;
2809
- if (await pathExists(path.join(base, "scripts", claim))) return true;
2803
+ if (await pathExists(path2.join(base, claim))) return true;
2804
+ if (await pathExists(path2.join(base, "src", claim))) return true;
2805
+ if (await pathExists(path2.join(base, "scripts", claim))) return true;
2810
2806
  }
2811
2807
  return false;
2812
2808
  };
2813
2809
  const binResolves = async (name) => {
2814
- const bases = [root, ...facts.packages.map((p) => path.join(root, p.dir))];
2810
+ const bases = [root, ...facts.packages.map((p) => path2.join(root, p.dir))];
2815
2811
  for (const base of bases) {
2816
- if (await pathExists(path.join(base, "node_modules", ".bin", name))) return true;
2812
+ if (await pathExists(path2.join(base, "node_modules", ".bin", name))) return true;
2817
2813
  }
2818
2814
  return false;
2819
2815
  };
2820
- const nodeModulesInstalled = await pathExists(path.join(root, "node_modules"));
2821
- const manifestExists = await pathExists(path.join(root, "package.json")) || facts.packages.length > 0;
2816
+ const nodeModulesInstalled = await pathExists(path2.join(root, "node_modules"));
2817
+ const manifestExists = await pathExists(path2.join(root, "package.json")) || facts.packages.length > 0;
2822
2818
  let totalFilteredSkipped = 0;
2823
2819
  let binaryResolved = 0;
2824
2820
  let unverifiableCommands = 0;
@@ -2910,7 +2906,7 @@ var instructionTruthLens = {
2910
2906
  }
2911
2907
  }
2912
2908
  for (const ref of extractDocRefs(file.text)) {
2913
- if (await pathExists(path.join(root, ref))) continue;
2909
+ if (await pathExists(path2.join(root, ref))) continue;
2914
2910
  findings.push(
2915
2911
  finding2({
2916
2912
  id: `${LENS_ID4}/dangling-ref:${file.path}:${ref}`,
@@ -2934,7 +2930,7 @@ var instructionTruthLens = {
2934
2930
  if (stateDocs.length) {
2935
2931
  for (const artifact of facts.artifacts) {
2936
2932
  if (artifact.kind !== "decisions" || !artifact.exists) continue;
2937
- const text = await readText(path.join(root, artifact.path));
2933
+ const text = await readText(path2.join(root, artifact.path));
2938
2934
  if (text === null) continue;
2939
2935
  const entries = parseDecisionEntries(text);
2940
2936
  if (!entries.length) continue;
@@ -3068,14 +3064,14 @@ function rankFindings(findings) {
3068
3064
  // src/engine/ledger.ts
3069
3065
  init_util();
3070
3066
  function ledgerPath(root) {
3071
- return path.join(root, ".etymd", "ledger.json");
3067
+ return path2.join(root, ".etymd", "ledger.json");
3072
3068
  }
3073
3069
  async function readLedger(root) {
3074
3070
  return await readJson(ledgerPath(root)) ?? { version: 1, entries: [] };
3075
3071
  }
3076
3072
  async function writeLedger(root, ledger) {
3077
3073
  const target = ledgerPath(root);
3078
- await promises.mkdir(path.dirname(target), { recursive: true });
3074
+ await promises.mkdir(path2.dirname(target), { recursive: true });
3079
3075
  await promises.writeFile(target, JSON.stringify(ledger, null, 2) + "\n", "utf8");
3080
3076
  }
3081
3077
  function belongsToAny(id, paths) {
@@ -3160,7 +3156,7 @@ var LENSES = [
3160
3156
  async function runAudit(root, opts = {}) {
3161
3157
  const facts = await scanProject(root, { upstreamRemote: opts.upstreamRemote });
3162
3158
  const ledgerRoot = opts.ledgerRoot ?? root;
3163
- if (!opts.readOnlyRoot && ((opts.persistLedger ?? true) || await pathExists(path.join(root, ETYMD_DIR)))) {
3159
+ if (!opts.readOnlyRoot && ((opts.persistLedger ?? true) || await pathExists(path2.join(root, ETYMD_DIR)))) {
3164
3160
  await writeCachedFacts(root, facts);
3165
3161
  }
3166
3162
  const baseline = await readBaseline(root);
@@ -3220,7 +3216,7 @@ function isFleetTrust(value) {
3220
3216
  }
3221
3217
  function expandTilde(p) {
3222
3218
  if (p === "~") return os.homedir();
3223
- if (p.startsWith("~/")) return path.join(os.homedir(), p.slice(2));
3219
+ if (p.startsWith("~/")) return path2.join(os.homedir(), p.slice(2));
3224
3220
  return p;
3225
3221
  }
3226
3222
  var REBUILD_RECIPE = 'rebuild it beside the manifest: {"machineProfile":"corp","dirs":{"<name>":"~/path/to/worktree"}}';
@@ -3255,7 +3251,7 @@ async function readLocal(localPath, problems) {
3255
3251
  if (!parsed) {
3256
3252
  problems.push({
3257
3253
  kind: "parse-error",
3258
- file: path.basename(localPath),
3254
+ file: path2.basename(localPath),
3259
3255
  detail: "must contain a JSON object \u2014 local mappings unusable"
3260
3256
  });
3261
3257
  return { present: true, data: {} };
@@ -3264,7 +3260,7 @@ async function readLocal(localPath, problems) {
3264
3260
  } catch (err) {
3265
3261
  problems.push({
3266
3262
  kind: "parse-error",
3267
- file: path.basename(localPath),
3263
+ file: path2.basename(localPath),
3268
3264
  detail: `not valid JSON (${err instanceof Error ? err.message : String(err)}) \u2014 local mappings unusable`
3269
3265
  });
3270
3266
  return { present: true, data: {} };
@@ -3332,13 +3328,13 @@ function loadRegistryEntries(projects, manifest, manifestFile) {
3332
3328
  } else {
3333
3329
  const dir = manifest.localDirs[name];
3334
3330
  if (!dir) {
3335
- entry.unresolved = `no \`dirs\` mapping for \`${name}\` in ${path.basename(manifest.localPath)}`;
3331
+ entry.unresolved = `no \`dirs\` mapping for \`${name}\` in ${path2.basename(manifest.localPath)}`;
3336
3332
  } else {
3337
- entry.resolvedRoot = path.resolve(manifest.dir, expandTilde(dir));
3333
+ entry.resolvedRoot = path2.resolve(manifest.dir, expandTilde(dir));
3338
3334
  }
3339
3335
  }
3340
3336
  } else if (entry.path) {
3341
- entry.resolvedRoot = path.resolve(manifest.root ?? manifest.dir, expandTilde(entry.path));
3337
+ entry.resolvedRoot = path2.resolve(manifest.root ?? manifest.dir, expandTilde(entry.path));
3342
3338
  } else {
3343
3339
  entry.unresolved = "personal entry declares no `path` \u2014 nothing to resolve";
3344
3340
  }
@@ -3347,7 +3343,7 @@ function loadRegistryEntries(projects, manifest, manifestFile) {
3347
3343
  if (corpNames.length && !manifest.localPresent) {
3348
3344
  manifest.problems.push({
3349
3345
  kind: "local-missing",
3350
- file: path.basename(manifest.localPath),
3346
+ file: path2.basename(manifest.localPath),
3351
3347
  detail: `${corpNames.length} corp/private entr${corpNames.length === 1 ? "y" : "ies"} (${corpNames.join(", ")}) cannot resolve without it \u2014 ${REBUILD_RECIPE}`
3352
3348
  });
3353
3349
  }
@@ -3376,19 +3372,19 @@ function loadCorpusEntries(sources, manifest, manifestFile) {
3376
3372
  };
3377
3373
  const localDir = manifest.localDirs[name];
3378
3374
  if (localDir) {
3379
- entry.resolvedRoot = path.resolve(manifest.dir, "..", expandTilde(localDir));
3375
+ entry.resolvedRoot = path2.resolve(manifest.dir, "..", expandTilde(localDir));
3380
3376
  } else if (entry.path) {
3381
- entry.resolvedRoot = path.resolve(manifest.dir, expandTilde(entry.path));
3377
+ entry.resolvedRoot = path2.resolve(manifest.dir, expandTilde(entry.path));
3382
3378
  } else {
3383
- entry.resolvedRoot = path.resolve(manifest.dir, "..", name);
3379
+ entry.resolvedRoot = path2.resolve(manifest.dir, "..", name);
3384
3380
  }
3385
3381
  manifest.entries.push(entry);
3386
3382
  }
3387
3383
  }
3388
3384
  async function loadFleetManifest(manifestPath) {
3389
- const abs = path.resolve(manifestPath);
3390
- const dir = path.dirname(abs);
3391
- const manifestFile = path.basename(abs);
3385
+ const abs = path2.resolve(manifestPath);
3386
+ const dir = path2.dirname(abs);
3387
+ const manifestFile = path2.basename(abs);
3392
3388
  const raw = await readText(abs);
3393
3389
  if (raw === null) {
3394
3390
  throw new Error(`cannot read fleet manifest \`${abs}\``);
@@ -3400,7 +3396,7 @@ async function loadFleetManifest(manifestPath) {
3400
3396
  corpHosts: [],
3401
3397
  labels: {},
3402
3398
  localDirs: {},
3403
- localPath: path.join(dir, "registry.local.json"),
3399
+ localPath: path2.join(dir, "registry.local.json"),
3404
3400
  localPresent: false,
3405
3401
  entries: [],
3406
3402
  problems: []
@@ -3433,7 +3429,7 @@ async function loadFleetManifest(manifestPath) {
3433
3429
  manifest.corpHosts = Array.isArray(local.data.corpHosts) ? local.data.corpHosts.filter((h) => typeof h === "string") : [];
3434
3430
  manifest.machineProfile = local.data.machineProfile === "corp" || local.data.machineProfile === "personal" ? local.data.machineProfile : void 0;
3435
3431
  const rootRaw = asString(local.data.root) ?? asString(parsed.root);
3436
- if (rootRaw) manifest.root = path.resolve(dir, expandTilde(rootRaw));
3432
+ if (rootRaw) manifest.root = path2.resolve(dir, expandTilde(rootRaw));
3437
3433
  const orientationRec = asRecord(parsed.orientation);
3438
3434
  if (orientationRec) {
3439
3435
  const orientationRoot = asString(orientationRec.root);
@@ -3455,7 +3451,7 @@ async function loadFleetManifest(manifestPath) {
3455
3451
  loadRegistryEntries(parsed.projects, manifest, manifestFile);
3456
3452
  } else if (Array.isArray(parsed.sources)) {
3457
3453
  manifest.shape = "corpus";
3458
- manifest.localPath = path.join(dir, "sources.local.json");
3454
+ manifest.localPath = path2.join(dir, "sources.local.json");
3459
3455
  const local = await readLocal(manifest.localPath, manifest.problems);
3460
3456
  manifest.localPresent = local.present;
3461
3457
  manifest.localDirs = asStringMap(local.data.dirs);
@@ -3511,9 +3507,9 @@ function finding3(id, tier, claim, evidence, why, action) {
3511
3507
  };
3512
3508
  }
3513
3509
  function corpPersistenceRoot(manifest, name) {
3514
- const corpDir = path.join(manifest.dir, "corp");
3515
- const root = path.resolve(corpDir, name);
3516
- if (path.dirname(root) !== corpDir || root === corpDir) {
3510
+ const corpDir = path2.join(manifest.dir, "corp");
3511
+ const root = path2.resolve(corpDir, name);
3512
+ if (path2.dirname(root) !== corpDir || root === corpDir) {
3517
3513
  throw new Error(
3518
3514
  `entry name ${JSON.stringify(name)} escapes the corp persistence zone \u2014 refusing to resolve a ledger root for it`
3519
3515
  );
@@ -3545,7 +3541,7 @@ async function realpathOr(p) {
3545
3541
  try {
3546
3542
  return await promises.realpath(p);
3547
3543
  } catch {
3548
- return path.resolve(p);
3544
+ return path2.resolve(p);
3549
3545
  }
3550
3546
  }
3551
3547
  function emailMatchesCorpHosts(email, hosts) {
@@ -3568,8 +3564,8 @@ var PROBLEM_TIER = {
3568
3564
  async function checkManifest(manifest) {
3569
3565
  const findings = [];
3570
3566
  const disclosures = [];
3571
- const manifestFile = path.basename(manifest.manifestPath);
3572
- const localFile = path.basename(manifest.localPath);
3567
+ const manifestFile = path2.basename(manifest.manifestPath);
3568
+ const localFile = path2.basename(manifest.localPath);
3573
3569
  for (const p of manifest.problems) {
3574
3570
  findings.push(
3575
3571
  finding3(
@@ -3721,7 +3717,7 @@ async function checkCorpWallArtifacts(entries, findings) {
3721
3717
  for (const entry of entries) {
3722
3718
  if (entry.profile !== "corp" || !entry.resolvedRoot) continue;
3723
3719
  for (const artifact of CORP_WALL_ARTIFACTS) {
3724
- if (await pathExists(path.join(entry.resolvedRoot, artifact))) {
3720
+ if (await pathExists(path2.join(entry.resolvedRoot, artifact))) {
3725
3721
  findings.push(
3726
3722
  finding3(
3727
3723
  `${FLEET_LENS}/corp-artifact-in-repo:${entry.name}:${artifact}`,
@@ -3755,9 +3751,9 @@ async function checkCoverage(manifest, findings, disclosures) {
3755
3751
  const dirents = await promises.readdir(manifest.root, { withFileTypes: true });
3756
3752
  for (const d of dirents) {
3757
3753
  if (!d.isDirectory() || d.name.startsWith(".")) continue;
3758
- const dir = path.join(manifest.root, d.name);
3754
+ const dir = path2.join(manifest.root, d.name);
3759
3755
  if (registered.has(await realpathOr(dir))) continue;
3760
- if (!await pathExists(path.join(dir, ".git"))) continue;
3756
+ if (!await pathExists(path2.join(dir, ".git"))) continue;
3761
3757
  const remotes = await git(dir, ["config", "--get-regexp", "^remote\\..*\\.url"]);
3762
3758
  if (!remotes) continue;
3763
3759
  const corpRemote = manifest.corpHosts.find((h) => remotes.includes(h));
@@ -3816,7 +3812,7 @@ async function checkHygieneNeedles(manifest, findings, disclosures) {
3816
3812
  ...new Set(
3817
3813
  [
3818
3814
  ...Object.values(manifest.labels),
3819
- ...Object.values(manifest.localDirs).map((d) => path.basename(expandNeedleDir(d))),
3815
+ ...Object.values(manifest.localDirs).map((d) => path2.basename(expandNeedleDir(d))),
3820
3816
  ...manifest.corpHosts
3821
3817
  ].filter((n) => n.length >= 3)
3822
3818
  )
@@ -4019,7 +4015,7 @@ async function sweepEntry(manifest, entry, opts) {
4019
4015
  }
4020
4016
  }
4021
4017
  const corp = entry.profile === "corp";
4022
- const optedIn = !corp && await pathExists(path.join(root, ETYMD_DIR));
4018
+ const optedIn = !corp && await pathExists(path2.join(root, ETYMD_DIR));
4023
4019
  const result = await runAudit(root, {
4024
4020
  kind: opts.kind,
4025
4021
  persistLedger: !corp && opts.persistLedgers === true && optedIn,
@@ -4037,7 +4033,7 @@ async function sweepEntry(manifest, entry, opts) {
4037
4033
  project.staleAfterDays = result.config.config.state.staleAfterDays;
4038
4034
  for (const [key, value] of Object.entries(entry.contract)) {
4039
4035
  if (key === "placement" || !value) continue;
4040
- const exists = await pathExists(path.join(root, value.replace(/#.*$/, "")));
4036
+ const exists = await pathExists(path2.join(root, value.replace(/#.*$/, "")));
4041
4037
  project.disclosures.push(
4042
4038
  `contract override \`${key}: ${value}\` \u2014 registered, existence-checked only (${exists ? "present" : "MISSING"})`
4043
4039
  );