@mmnto/cli 1.13.0 → 1.14.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.
Files changed (130) hide show
  1. package/dist/commands/briefing.d.ts.map +1 -1
  2. package/dist/commands/briefing.js +3 -1
  3. package/dist/commands/briefing.js.map +1 -1
  4. package/dist/commands/briefing.test.js +1 -0
  5. package/dist/commands/briefing.test.js.map +1 -1
  6. package/dist/commands/compile-prune.test.d.ts +2 -0
  7. package/dist/commands/compile-prune.test.d.ts.map +1 -0
  8. package/dist/commands/compile-prune.test.js +116 -0
  9. package/dist/commands/compile-prune.test.js.map +1 -0
  10. package/dist/commands/compile.d.ts +37 -0
  11. package/dist/commands/compile.d.ts.map +1 -1
  12. package/dist/commands/compile.js +120 -11
  13. package/dist/commands/compile.js.map +1 -1
  14. package/dist/commands/doctor.d.ts +1 -1
  15. package/dist/commands/doctor.d.ts.map +1 -1
  16. package/dist/commands/doctor.js +12 -6
  17. package/dist/commands/doctor.js.map +1 -1
  18. package/dist/commands/doctor.test.js +33 -5
  19. package/dist/commands/doctor.test.js.map +1 -1
  20. package/dist/commands/extract-local.d.ts.map +1 -1
  21. package/dist/commands/extract-local.js +3 -1
  22. package/dist/commands/extract-local.js.map +1 -1
  23. package/dist/commands/extract-pr.d.ts.map +1 -1
  24. package/dist/commands/extract-pr.js +3 -1
  25. package/dist/commands/extract-pr.js.map +1 -1
  26. package/dist/commands/extract-scan.d.ts.map +1 -1
  27. package/dist/commands/extract-scan.js +3 -1
  28. package/dist/commands/extract-scan.js.map +1 -1
  29. package/dist/commands/extract-shared.d.ts.map +1 -1
  30. package/dist/commands/extract-shared.js +3 -1
  31. package/dist/commands/extract-shared.js.map +1 -1
  32. package/dist/commands/extract.test.js +2 -0
  33. package/dist/commands/extract.test.js.map +1 -1
  34. package/dist/commands/handoff.d.ts +17 -37
  35. package/dist/commands/handoff.d.ts.map +1 -1
  36. package/dist/commands/handoff.js +120 -273
  37. package/dist/commands/handoff.js.map +1 -1
  38. package/dist/commands/handoff.test.js +64 -277
  39. package/dist/commands/handoff.test.js.map +1 -1
  40. package/dist/commands/lint.d.ts.map +1 -1
  41. package/dist/commands/lint.js +2 -1
  42. package/dist/commands/lint.js.map +1 -1
  43. package/dist/commands/review-learn.d.ts.map +1 -1
  44. package/dist/commands/review-learn.js +3 -1
  45. package/dist/commands/review-learn.js.map +1 -1
  46. package/dist/commands/review-learn.test.js +1 -0
  47. package/dist/commands/review-learn.test.js.map +1 -1
  48. package/dist/commands/run-compiled-rules.d.ts +2 -0
  49. package/dist/commands/run-compiled-rules.d.ts.map +1 -1
  50. package/dist/commands/run-compiled-rules.js +63 -5
  51. package/dist/commands/run-compiled-rules.js.map +1 -1
  52. package/dist/commands/run-compiled-rules.test.js +382 -0
  53. package/dist/commands/run-compiled-rules.test.js.map +1 -1
  54. package/dist/commands/search.d.ts.map +1 -1
  55. package/dist/commands/search.js +3 -1
  56. package/dist/commands/search.js.map +1 -1
  57. package/dist/commands/shield.d.ts.map +1 -1
  58. package/dist/commands/shield.js +8 -4
  59. package/dist/commands/shield.js.map +1 -1
  60. package/dist/commands/shield.test.js +3 -1
  61. package/dist/commands/shield.test.js.map +1 -1
  62. package/dist/commands/spec.d.ts.map +1 -1
  63. package/dist/commands/spec.js +8 -2
  64. package/dist/commands/spec.js.map +1 -1
  65. package/dist/commands/spec.test.js +2 -0
  66. package/dist/commands/spec.test.js.map +1 -1
  67. package/dist/commands/stats.d.ts.map +1 -1
  68. package/dist/commands/stats.js +3 -1
  69. package/dist/commands/stats.js.map +1 -1
  70. package/dist/commands/triage.d.ts.map +1 -1
  71. package/dist/commands/triage.js +3 -1
  72. package/dist/commands/triage.js.map +1 -1
  73. package/dist/commands/triage.test.js +1 -0
  74. package/dist/commands/triage.test.js.map +1 -1
  75. package/dist/help.d.ts.map +1 -1
  76. package/dist/help.js +0 -1
  77. package/dist/help.js.map +1 -1
  78. package/dist/hooks/__tests__/auto-context.test.js +1 -0
  79. package/dist/hooks/__tests__/auto-context.test.js.map +1 -1
  80. package/dist/hooks/auto-context.d.ts.map +1 -1
  81. package/dist/hooks/auto-context.js +2 -2
  82. package/dist/hooks/auto-context.js.map +1 -1
  83. package/dist/index.js +8 -10
  84. package/dist/index.js.map +1 -1
  85. package/dist/orchestrators/anthropic-orchestrator.d.ts +0 -6
  86. package/dist/orchestrators/anthropic-orchestrator.d.ts.map +1 -1
  87. package/dist/orchestrators/anthropic-orchestrator.js +55 -1
  88. package/dist/orchestrators/anthropic-orchestrator.js.map +1 -1
  89. package/dist/orchestrators/anthropic-orchestrator.test.js +174 -0
  90. package/dist/orchestrators/anthropic-orchestrator.test.js.map +1 -1
  91. package/dist/orchestrators/gemini-orchestrator.d.ts.map +1 -1
  92. package/dist/orchestrators/gemini-orchestrator.js +25 -1
  93. package/dist/orchestrators/gemini-orchestrator.js.map +1 -1
  94. package/dist/orchestrators/gemini-orchestrator.test.js +38 -0
  95. package/dist/orchestrators/gemini-orchestrator.test.js.map +1 -1
  96. package/dist/orchestrators/ollama-orchestrator.d.ts.map +1 -1
  97. package/dist/orchestrators/ollama-orchestrator.js +18 -2
  98. package/dist/orchestrators/ollama-orchestrator.js.map +1 -1
  99. package/dist/orchestrators/ollama-orchestrator.test.js +34 -0
  100. package/dist/orchestrators/ollama-orchestrator.test.js.map +1 -1
  101. package/dist/orchestrators/openai-orchestrator.d.ts.map +1 -1
  102. package/dist/orchestrators/openai-orchestrator.js +19 -2
  103. package/dist/orchestrators/openai-orchestrator.js.map +1 -1
  104. package/dist/orchestrators/openai-orchestrator.test.js +38 -0
  105. package/dist/orchestrators/openai-orchestrator.test.js.map +1 -1
  106. package/dist/orchestrators/orchestrator.d.ts +38 -0
  107. package/dist/orchestrators/orchestrator.d.ts.map +1 -1
  108. package/dist/orchestrators/orchestrator.js.map +1 -1
  109. package/dist/orchestrators/orchestrator.test.js +115 -0
  110. package/dist/orchestrators/orchestrator.test.js.map +1 -1
  111. package/dist/orchestrators/shell-orchestrator.d.ts.map +1 -1
  112. package/dist/orchestrators/shell-orchestrator.js +11 -2
  113. package/dist/orchestrators/shell-orchestrator.js.map +1 -1
  114. package/dist/orchestrators/shell-orchestrator.test.js +69 -0
  115. package/dist/orchestrators/shell-orchestrator.test.js.map +1 -1
  116. package/dist/utils.d.ts +8 -0
  117. package/dist/utils.d.ts.map +1 -1
  118. package/dist/utils.js +85 -17
  119. package/dist/utils.js.map +1 -1
  120. package/dist/utils.test.js +198 -1
  121. package/dist/utils.test.js.map +1 -1
  122. package/package.json +2 -2
  123. package/dist/schemas/handoff-checkpoint.d.ts +0 -34
  124. package/dist/schemas/handoff-checkpoint.d.ts.map +0 -1
  125. package/dist/schemas/handoff-checkpoint.js +0 -13
  126. package/dist/schemas/handoff-checkpoint.js.map +0 -1
  127. package/dist/schemas/handoff-checkpoint.test.d.ts +0 -2
  128. package/dist/schemas/handoff-checkpoint.test.d.ts.map +0 -1
  129. package/dist/schemas/handoff-checkpoint.test.js +0 -65
  130. package/dist/schemas/handoff-checkpoint.test.js.map +0 -1
@@ -9,8 +9,8 @@ export async function runCompiledRules(options) {
9
9
  const path = await import('node:path');
10
10
  const { bold, errorColor, log, success: successColor } = await import('../ui.js');
11
11
  const { writeOutput } = await import('../utils.js');
12
- const { applyAstRulesToAdditions, applyRulesToAdditions, enrichWithAstContext, extractAddedLines, loadCompiledRules, loadRuleMetrics, matchesGlob, recordContextHit, recordSuppression, recordTrigger, saveRuleMetrics, setCoreLogger, TotemError, } = await import('@mmnto/totem');
13
- const { diff, cwd, totemDir, format, outPath, exportPaths, ignorePatterns, tag } = options;
12
+ const { applyAstRulesToAdditions, applyRulesToAdditions, enrichWithAstContext, extractAddedLines, loadCompiledRules, loadRuleMetrics, matchesGlob, recordContextHit, recordSuppression, recordTrigger, resolveGitRoot, safeExec, saveRuleMetrics, setCoreLogger, TotemError, } = await import('@mmnto/totem');
13
+ const { diff, cwd, totemDir, format, outPath, exportPaths, ignorePatterns, tag, isStaged } = options;
14
14
  // Wire core logger to CLI UI (ADR-071: core must not use console.warn directly)
15
15
  setCoreLogger({ warn: (msg) => log.warn(tag, msg) });
16
16
  try {
@@ -22,7 +22,26 @@ export async function runCompiledRules(options) {
22
22
  throw new TotemError('NO_RULES', `No compiled rules found at ${totemDir}/${COMPILED_RULES_FILE}.`, "Run 'totem compile' to generate rules.");
23
23
  }
24
24
  log.info(tag, `Running ${rules.length} rules (zero LLM)...`);
25
- // Extract additions, exclude compiled rules file and export targets
25
+ // Extract additions, exclude compiled rules file, export targets, and binary files
26
+ const BINARY_EXTENSIONS = new Set([
27
+ '.png',
28
+ '.jpg',
29
+ '.jpeg',
30
+ '.gif',
31
+ '.mp4',
32
+ '.pdf',
33
+ '.zip',
34
+ '.tar',
35
+ '.gz',
36
+ '.woff',
37
+ '.woff2',
38
+ '.eot',
39
+ '.ttf',
40
+ '.mp3',
41
+ '.wav',
42
+ '.ico',
43
+ '.bin',
44
+ ]);
26
45
  const rulesRelPath = path.join(totemDir, COMPILED_RULES_FILE).replace(/\\/g, '/');
27
46
  const excluded = new Set([rulesRelPath]);
28
47
  if (exportPaths) {
@@ -32,10 +51,14 @@ export async function runCompiledRules(options) {
32
51
  }
33
52
  const additions = extractAddedLines(diff)
34
53
  .filter((a) => !excluded.has(a.file))
54
+ .filter((a) => !BINARY_EXTENSIONS.has(path.extname(a.file).toLowerCase()))
35
55
  .filter((a) => !ignorePatterns || !ignorePatterns.some((pattern) => matchesGlob(a.file, pattern)));
56
+ // Resolve repo root once — git diff paths are always repo-root-relative,
57
+ // so both staged and non-staged paths need the repo root for file resolution.
58
+ const repoRoot = resolveGitRoot(cwd);
36
59
  // Enrich with AST context
37
60
  try {
38
- await enrichWithAstContext(additions, { cwd });
61
+ await enrichWithAstContext(additions, { cwd: repoRoot ?? cwd });
39
62
  const classified = additions.filter((a) => a.astContext !== undefined).length;
40
63
  if (classified > 0) {
41
64
  log.dim(tag, `AST classified ${classified}/${additions.length} additions`);
@@ -75,9 +98,44 @@ export async function runCompiledRules(options) {
75
98
  if (astRules.length > 0) {
76
99
  log.dim(tag, `Running ${astRules.length} AST rule(s)...`);
77
100
  try {
78
- astViolations = await applyAstRulesToAdditions(rules, additions, cwd, ruleEventCallback, (msg) => log.warn(tag, msg));
101
+ const workingDirectory = repoRoot ?? cwd;
102
+ let readStrategy = undefined;
103
+ if (isStaged) {
104
+ if (repoRoot) {
105
+ readStrategy = async (filePath) => {
106
+ try {
107
+ // 1. Detect symlinks explicitly (git ls-files -s returns mode 120000).
108
+ // The `--` separator prevents filePath values starting with `-` from
109
+ // being interpreted as git options.
110
+ const lsOutput = safeExec('git', ['ls-files', '--recurse-submodules', '-s', '--', filePath], { cwd: repoRoot, env: { ...process.env, LC_ALL: 'C' } });
111
+ if (lsOutput.startsWith('120000 ')) {
112
+ return null; // Explicitly exclude symlinks from AST checks
113
+ }
114
+ // 2. Read staged content
115
+ const content = safeExec('git', ['show', `:${filePath}`], {
116
+ cwd: repoRoot,
117
+ trim: false,
118
+ env: { ...process.env, LC_ALL: 'C' },
119
+ });
120
+ // 3. Normalize CRLF to LF specifically for the staged callback
121
+ // Disk-read callback preserves existing behavior per Invariant #4.
122
+ return content.replace(/\r\n/g, '\n');
123
+ }
124
+ catch (err) {
125
+ // Explicit throw per Failure Mode 1 decision
126
+ throw new TotemError('STAGED_READ_FAILED', `Failed to read staged content for ${filePath}`, `git show :${filePath} failed. The file may not exist in the index or may be staged for deletion. Ensure --staged is used correctly.`, { cause: err });
127
+ }
128
+ };
129
+ }
130
+ }
131
+ astViolations = await applyAstRulesToAdditions(rules, additions, workingDirectory, ruleEventCallback, (msg) => log.warn(tag, msg), readStrategy);
79
132
  }
80
133
  catch (err) {
134
+ // STAGED_READ_FAILED must propagate — the pre-commit guarantee depends
135
+ // on surfacing staged-read failures rather than silently falling back.
136
+ if (err instanceof TotemError && err.code === 'STAGED_READ_FAILED') {
137
+ throw err;
138
+ }
81
139
  const msg = err instanceof Error ? err.message : String(err);
82
140
  const isWasmFailure = /not initialized|wasm|web-tree-sitter/i.test(msg);
83
141
  if (process.env['TOTEM_LITE'] === '1' && isWasmFailure) {
@@ -1 +1 @@
1
- {"version":3,"file":"run-compiled-rules.js","sourceRoot":"","sources":["../../src/commands/run-compiled-rules.ts"],"names":[],"mappings":"AA2BA,uDAAuD;AAEvD,MAAM,mBAAmB,GAAG,qBAAqB,CAAC;AAElD,uDAAuD;AAEvD;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,OAAgC;IAEhC,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,CAAC;IACvC,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,OAAO,EAAE,YAAY,EAAE,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,CAAC;IAClF,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,CAAC;IACpD,MAAM,EACJ,wBAAwB,EACxB,qBAAqB,EACrB,oBAAoB,EACpB,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,EACf,WAAW,EACX,gBAAgB,EAChB,iBAAiB,EACjB,aAAa,EACb,eAAe,EACf,aAAa,EACb,UAAU,GACX,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,CAAC;IAEjC,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC;IAE3F,gFAAgF;IAChF,aAAa,CAAC,EAAE,IAAI,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;IACrD,IAAI,CAAC;QACH,MAAM,gBAAgB,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,IAAI,GAAG,EAAE,QAAQ,CAAC,CAAC;QAExE,sBAAsB;QACtB,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,mBAAmB,CAAC,CAAC;QACnE,MAAM,KAAK,GAAG,iBAAiB,CAAC,SAAS,CAAC,CAAC;QAE3C,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,MAAM,IAAI,UAAU,CAClB,UAAU,EACV,8BAA8B,QAAQ,IAAI,mBAAmB,GAAG,EAChE,wCAAwC,CACzC,CAAC;QACJ,CAAC;QAED,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,WAAW,KAAK,CAAC,MAAM,sBAAsB,CAAC,CAAC;QAE7D,oEAAoE;QACpE,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,mBAAmB,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QAClF,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC;QACzC,IAAI,WAAW,EAAE,CAAC;YAChB,KAAK,MAAM,EAAE,IAAI,WAAW,EAAE,CAAC;gBAC7B,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC;YACvC,CAAC;QACH,CAAC;QACD,MAAM,SAAS,GAAG,iBAAiB,CAAC,IAAI,CAAC;aACtC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;aACpC,MAAM,CACL,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,cAAc,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAC1F,CAAC;QAEJ,0BAA0B;QAC1B,IAAI,CAAC;YACH,MAAM,oBAAoB,CAAC,SAAS,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;YAC/C,MAAM,UAAU,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,MAAM,CAAC;YAC9E,IAAI,UAAU,GAAG,CAAC,EAAE,CAAC;gBACnB,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,kBAAkB,UAAU,IAAI,SAAS,CAAC,MAAM,YAAY,CAAC,CAAC;YAC7E,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,8DAA8D,CAAC,CAAC;QAC/E,CAAC;QAED,+BAA+B;QAC/B,MAAM,EAAE,iBAAiB,EAAE,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,CAAC;QAC3D,MAAM,OAAO,GAAG,eAAe,CAAC,gBAAgB,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;QAC9E,MAAM,iBAAiB,GAAG,CACxB,KAA6B,EAC7B,IAAY,EACZ,OAA0B,EAC1B,EAAE;YACF,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;gBACxB,aAAa,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;gBAC7B,gBAAgB,CAAC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC;YACvD,CAAC;iBAAM,CAAC;gBACN,iBAAiB,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;gBACjC,0CAA0C;gBAC1C,IAAI,OAAO,EAAE,CAAC;oBACZ,iBAAiB,CACf,gBAAgB,EAChB;wBACE,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;wBACnC,IAAI,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU;wBACrD,MAAM,EAAE,IAAI;wBACZ,IAAI,EAAE,OAAO,CAAC,IAAI;wBAClB,IAAI,EAAE,OAAO,CAAC,IAAI;wBAClB,aAAa,EAAE,OAAO,CAAC,aAAa,IAAI,EAAE;wBAC1C,MAAM,EAAE,MAAM;qBACf,EACD,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,CAC3B,CAAC;gBACJ,CAAC;YACH,CAAC;QACH,CAAC,CAAC;QACF,MAAM,eAAe,GAAG,qBAAqB,CAAC,KAAK,EAAE,SAAS,EAAE,iBAAiB,CAAC,CAAC;QAEnF,4EAA4E;QAC5E,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,KAAK,IAAI,CAAC,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC;QACpF,IAAI,aAAa,GAAgB,EAAE,CAAC;QACpC,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxB,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,WAAW,QAAQ,CAAC,MAAM,iBAAiB,CAAC,CAAC;YAC1D,IAAI,CAAC;gBACH,aAAa,GAAG,MAAM,wBAAwB,CAC5C,KAAK,EACL,SAAS,EACT,GAAG,EACH,iBAAiB,EACjB,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,CAC5B,CAAC;YACJ,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;gBAC7D,MAAM,aAAa,GAAG,uCAAuC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBACxE,IAAI,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,KAAK,GAAG,IAAI,aAAa,EAAE,CAAC;oBACvD,uEAAuE;oBACvE,yEAAyE;oBACzE,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,gDAAgD,GAAG,EAAE,CAAC,CAAC;gBACvE,CAAC;qBAAM,CAAC;oBACN,MAAM,GAAG,CAAC;gBACZ,CAAC;YACH,CAAC;QACH,CAAC;QAED,MAAM,UAAU,GAAG,CAAC,GAAG,eAAe,EAAE,GAAG,aAAa,CAAC,CAAC;QAE1D,oDAAoD;QACpD,sEAAsE;QACtE,MAAM,SAAS,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC7D,MAAM,cAAc,GAAmB,EAAE,CAAC;QAC1C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAChD,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;gBAC3F,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS;qBAC5B,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;qBACtE,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;gBAC1B,MAAM,QAAQ,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE;oBACvC,MAAM,aAAa,GAAG,QAAQ,CAAC,MAAM,KAAK,CAAC,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;oBAC1F,MAAM,aAAa,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;oBACjE,OAAO,aAAa,IAAI,CAAC,aAAa,CAAC;gBACzC,CAAC,CAAC,CAAC;gBACH,IAAI,CAAC,QAAQ;oBAAE,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC3C,CAAC;QACH,CAAC;QACD,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC9B,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,cAAc,CAAC,MAAM,wCAAwC,CAAC,CAAC;QACjF,CAAC;QAED,IAAI,CAAC;YACH,eAAe,CAAC,gBAAgB,EAAE,OAAO,CAAC,CAAC;QAC7C,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,GAAG,CAAC,IAAI,CACN,GAAG,EACH,gCAAgC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CACnF,CAAC;QACJ,CAAC;QAED,oFAAoF;QACpF,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,IAAI,OAAO,CAAC,KAAK,OAAO,CAAC,CAAC;QAClF,MAAM,QAAQ,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,IAAI,OAAO,CAAC,KAAK,SAAS,CAAC,CAAC;QAEtF,mDAAmD;QACnD,MAAM,EAAE,kBAAkB,EAAE,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,CAAC;QAC5D,MAAM,QAAQ,GAAG,UAAU,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;QAEpD,eAAe;QACf,IAAI,MAAc,CAAC;QAEnB,IAAI,MAAM,KAAK,OAAO,EAAE,CAAC;YACvB,MAAM,EAAE,aAAa,EAAE,UAAU,EAAE,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,CAAC;YACnE,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,CAAC;YACtD,MAAM,GAAG,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAC3C,MAAM,OAAO,GAAI,GAAG,CAAC,oBAAoB,CAAyB,CAAC,OAAO,CAAC;YAC3E,MAAM,UAAU,GAAG,UAAU,CAAC,GAAG,CAAC,IAAI,SAAS,CAAC;YAChD,8DAA8D;YAC9D,uEAAuE;YACvE,wDAAwD;YACxD,MAAM,KAAK,GAAG,aAAa,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,CAAC;YAEpE,kEAAkE;YAClE,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACxB,MAAM,cAAc,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC;gBAC9D,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC;oBACnC,EAAE,EAAE,uBAAuB;oBAC3B,gBAAgB,EAAE;wBAChB,IAAI,EAAE,qEAAqE;qBAC5E;iBACF,CAAC,CAAC;gBACH,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC;oBACzB,MAAM,EAAE,uBAAuB;oBAC/B,SAAS,EAAE,cAAc;oBACzB,KAAK,EAAE,MAAM;oBACb,OAAO,EAAE;wBACP,IAAI,EAAE,GAAG,QAAQ,CAAC,MAAM,qIAAqI;qBAC9J;oBACD,SAAS,EAAE;wBACT;4BACE,gBAAgB,EAAE;gCAChB,gBAAgB,EAAE,EAAE,GAAG,EAAE,4BAA4B,EAAE;gCACvD,MAAM,EAAE,EAAE,SAAS,EAAE,CAAC,EAAE;6BACzB;yBACF;qBACF;iBACF,CAAC,CAAC;YACL,CAAC;YAED,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QAC1C,CAAC;aAAM,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;YAC7B,MAAM,GAAG,IAAI,CAAC,SAAS,CACrB;gBACE,IAAI,EAAE,MAAM,CAAC,MAAM,KAAK,CAAC;gBACzB,KAAK,EAAE,KAAK,CAAC,MAAM;gBACnB,MAAM,EAAE,MAAM,CAAC,MAAM;gBACrB,QAAQ,EAAE,QAAQ,CAAC,MAAM;gBACzB,QAAQ;gBACR,UAAU;aACX,EACD,IAAI,EACJ,CAAC,CACF,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,MAAM,KAAK,GAAa,EAAE,CAAC;YAE3B,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACjD,+DAA+D;gBAC/D,IAAI,OAAO,EAAE,CAAC;oBACZ,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;oBAC1B,KAAK,CAAC,IAAI,CAAC,kBAAkB,KAAK,CAAC,MAAM,gBAAgB,CAAC,CAAC;oBAC3D,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;oBACf,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;oBAC1B,KAAK,CAAC,IAAI,CAAC,gDAAgD,CAAC,CAAC;gBAC/D,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;gBAC1B,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBACtB,KAAK,CAAC,IAAI,CACR,cAAc,MAAM,CAAC,MAAM,YAAY,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,QAAQ,CAAC,MAAM,aAAa,CAAC,CAAC,CAAC,EAAE,WAAW,KAAK,CAAC,MAAM,SAAS,CACpI,CAAC;gBACJ,CAAC;qBAAM,CAAC;oBACN,KAAK,CAAC,IAAI,CACR,cAAc,QAAQ,CAAC,MAAM,gCAAgC,KAAK,CAAC,MAAM,SAAS,CACnF,CAAC;gBACJ,CAAC;gBAED,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBACtB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;oBACf,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;oBACzB,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;wBACvB,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,UAAU,QAAQ,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;wBAClE,KAAK,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,IAAI,CAAC,OAAO,KAAK,CAAC,CAAC;wBACjD,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,aAAa,GAAG,CAAC,CAAC;wBAClD,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;wBAC3C,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;oBACjB,CAAC;gBACH,CAAC;gBAED,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBACxB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;oBACf,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;oBAC3B,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;wBACzB,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,UAAU,QAAQ,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;wBAClE,KAAK,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,IAAI,CAAC,OAAO,KAAK,CAAC,CAAC;wBACjD,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,aAAa,GAAG,CAAC,CAAC;wBAClD,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;wBAC3C,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;oBACjB,CAAC;gBACH,CAAC;YACH,CAAC;YACD,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC5B,CAAC;QAED,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAC7B,IAAI,OAAO;YAAE,GAAG,CAAC,OAAO,CAAC,GAAG,EAAE,cAAc,OAAO,EAAE,CAAC,CAAC;QAEvD,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtB,MAAM,YAAY,GAAG,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;YAC9C,MAAM,UAAU,GAAG,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,QAAQ,CAAC,MAAM,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC;YAChF,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,YAAY,YAAY,MAAM,MAAM,CAAC,MAAM,YAAY,UAAU,EAAE,CAAC,CAAC;YACnF,MAAM,IAAI,UAAU,CAClB,eAAe,EACf,qBAAqB,EACrB,mEAAmE,CACpE,CAAC;QACJ,CAAC;aAAM,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC/B,MAAM,YAAY,GAAG,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;YAChD,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,YAAY,YAAY,MAAM,QAAQ,CAAC,MAAM,uBAAuB,CAAC,CAAC;QACtF,CAAC;aAAM,CAAC;YACN,MAAM,YAAY,GAAG,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;YAChD,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,YAAY,YAAY,MAAM,KAAK,CAAC,MAAM,sBAAsB,CAAC,CAAC;QAClF,CAAC;QAED,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IACjD,CAAC;YAAS,CAAC;QACT,aAAa,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,GAAE,CAAC,EAAE,CAAC,CAAC;IACpC,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"run-compiled-rules.js","sourceRoot":"","sources":["../../src/commands/run-compiled-rules.ts"],"names":[],"mappings":"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"}
@@ -268,6 +268,25 @@ describe('runCompiledRules', () => {
268
268
  });
269
269
  expect(result.violations).toHaveLength(0);
270
270
  });
271
+ it('excludes binary files from scanning', async () => {
272
+ const rules = [
273
+ makeRule('console\\.log\\("foo"\\)', 'No foo log', 'No foo log', {
274
+ engine: 'ast-grep',
275
+ astGrepPattern: 'console.log("foo")',
276
+ }),
277
+ ];
278
+ writeRules(tmpDir, rules);
279
+ // Diff that changes a binary file (.png)
280
+ const diff = makeDiff('assets/logo.png', ' console.log("foo");');
281
+ const result = await runCompiledRules({
282
+ diff,
283
+ cwd: tmpDir,
284
+ totemDir: TOTEM_DIR,
285
+ format: 'json',
286
+ tag: 'Test',
287
+ });
288
+ expect(result.violations).toHaveLength(0);
289
+ });
271
290
  // ─── Ignore patterns ────────────────────────────────
272
291
  // ─── SARIF output ──────────────────────────────────
273
292
  it('SARIF output excludes warning-severity findings', async () => {
@@ -488,6 +507,369 @@ describe('runCompiledRules', () => {
488
507
  expect(events[0].justification).toBe('needed for monitoring');
489
508
  expect(events[0].source).toBe('lint');
490
509
  });
510
+ // ─── readStrategy / isStaged ────────────────────────
511
+ describe('readStrategy / isStaged', () => {
512
+ it('constructs readStrategy and reads staged content via the underlying staged read when isStaged is true', async () => {
513
+ const rules = [
514
+ makeRule('console\\.log\\("foo"\\)', 'No foo log', 'No foo log', {
515
+ engine: 'ast-grep',
516
+ astGrepPattern: 'console.log("foo")',
517
+ }),
518
+ ];
519
+ writeRules(tmpDir, rules);
520
+ const diff = makeDiff('src/app.ts', ' console.log("foo");');
521
+ const mockResolveGitRoot = vi.spyOn(totem, 'resolveGitRoot').mockReturnValue(tmpDir);
522
+ const mockExec = vi
523
+ .spyOn(totem, 'safeExec')
524
+ .mockImplementation((cmd, args) => {
525
+ if (!args)
526
+ return '';
527
+ if (args[0] === 'ls-files' && args[1] === '--recurse-submodules' && args[2] === '-s') {
528
+ return '100644 hash 0\tsrc/app.ts\n';
529
+ }
530
+ if (args[0] === 'show') {
531
+ return '// context\n console.log("foo");\n// context\n';
532
+ }
533
+ return '';
534
+ });
535
+ let violations = [];
536
+ try {
537
+ const result = await runCompiledRules({
538
+ diff,
539
+ cwd: tmpDir,
540
+ totemDir: TOTEM_DIR,
541
+ format: 'json',
542
+ tag: 'Test',
543
+ isStaged: true,
544
+ });
545
+ violations = result.violations;
546
+ }
547
+ catch (err) {
548
+ if (err instanceof Error &&
549
+ err.name === 'TotemError' &&
550
+ err.message.includes('Violations detected')) {
551
+ violations = [1]; // We just need to know it matched
552
+ }
553
+ else {
554
+ throw err;
555
+ }
556
+ }
557
+ expect(violations).toHaveLength(1);
558
+ mockResolveGitRoot.mockRestore();
559
+ mockExec.mockRestore();
560
+ });
561
+ it('filters symlinks via the underlying index check mode 120000', async () => {
562
+ const rules = [
563
+ makeRule('console\\.log\\("foo"\\)', 'No foo log', 'No foo log', {
564
+ engine: 'ast-grep',
565
+ astGrepPattern: 'console.log("foo")',
566
+ }),
567
+ ];
568
+ writeRules(tmpDir, rules);
569
+ const diff = makeDiff('src/app.ts', ' console.log("foo");');
570
+ const mockResolveGitRoot = vi.spyOn(totem, 'resolveGitRoot').mockReturnValue(tmpDir);
571
+ const mockExec = vi
572
+ .spyOn(totem, 'safeExec')
573
+ .mockImplementation((cmd, args) => {
574
+ if (!args)
575
+ return '';
576
+ if (args[0] === 'ls-files' && args[1] === '--recurse-submodules' && args[2] === '-s') {
577
+ return '120000 hash 0\tsrc/app.ts\n'; // Symlink
578
+ }
579
+ if (args[0] === 'show') {
580
+ return 'console.log("foo");\n'; // Should not be called
581
+ }
582
+ return '';
583
+ });
584
+ try {
585
+ const result = await runCompiledRules({
586
+ diff,
587
+ cwd: tmpDir,
588
+ totemDir: TOTEM_DIR,
589
+ format: 'json',
590
+ tag: 'Test',
591
+ isStaged: true,
592
+ });
593
+ expect(result.violations).toHaveLength(0);
594
+ }
595
+ finally {
596
+ mockResolveGitRoot.mockRestore();
597
+ mockExec.mockRestore();
598
+ }
599
+ });
600
+ it('normalizes CRLF to LF in staged content', async () => {
601
+ const rules = [
602
+ makeRule('console\\.log\\("foo"\\)', 'No foo log', 'No foo log', {
603
+ engine: 'ast-grep',
604
+ astGrepPattern: 'console.log("foo")',
605
+ }),
606
+ ];
607
+ writeRules(tmpDir, rules);
608
+ const diff = makeDiff('src/app.ts', ' console.log("foo");');
609
+ const mockResolveGitRoot = vi.spyOn(totem, 'resolveGitRoot').mockReturnValue(tmpDir);
610
+ const mockExec = vi
611
+ .spyOn(totem, 'safeExec')
612
+ .mockImplementation((cmd, args) => {
613
+ if (!args)
614
+ return '';
615
+ if (args[0] === 'ls-files' && args[1] === '--recurse-submodules' && args[2] === '-s') {
616
+ return '100644 hash 0\tsrc/app.ts\n';
617
+ }
618
+ if (args[0] === 'show') {
619
+ return '// context\r\n console.log("foo");\r\n// context\r\n';
620
+ }
621
+ return '';
622
+ });
623
+ let violations = [];
624
+ try {
625
+ const result = await runCompiledRules({
626
+ diff,
627
+ cwd: tmpDir,
628
+ totemDir: TOTEM_DIR,
629
+ format: 'json',
630
+ tag: 'Test',
631
+ isStaged: true,
632
+ });
633
+ violations = result.violations;
634
+ }
635
+ catch (err) {
636
+ if (err instanceof Error &&
637
+ err.name === 'TotemError' &&
638
+ err.message.includes('Violations detected')) {
639
+ violations = [1];
640
+ }
641
+ else {
642
+ throw err;
643
+ }
644
+ }
645
+ expect(violations).toHaveLength(1);
646
+ mockResolveGitRoot.mockRestore();
647
+ mockExec.mockRestore();
648
+ });
649
+ it('throws STAGED_READ_FAILED when the underlying staged read fails', async () => {
650
+ const rules = [
651
+ makeRule('console\\.log\\("foo"\\)', 'No foo log', 'No foo log', {
652
+ engine: 'ast-grep',
653
+ astGrepPattern: 'console.log("foo")',
654
+ }),
655
+ ];
656
+ writeRules(tmpDir, rules);
657
+ const diff = makeDiff('src/app.ts', ' console.log("foo");');
658
+ const mockResolveGitRoot = vi.spyOn(totem, 'resolveGitRoot').mockReturnValue(tmpDir);
659
+ const mockExec = vi
660
+ .spyOn(totem, 'safeExec')
661
+ .mockImplementation((cmd, args) => {
662
+ if (!args)
663
+ return '';
664
+ if (args[0] === 'ls-files' && args[1] === '--recurse-submodules' && args[2] === '-s') {
665
+ return '100644 hash 0\tsrc/app.ts\n';
666
+ }
667
+ if (args[0] === 'show') {
668
+ throw new Error('[Totem Error] Command failed: show :src/app.ts');
669
+ }
670
+ return '';
671
+ });
672
+ try {
673
+ await expect(runCompiledRules({
674
+ diff,
675
+ cwd: tmpDir,
676
+ totemDir: TOTEM_DIR,
677
+ format: 'json',
678
+ tag: 'Test',
679
+ isStaged: true,
680
+ })).rejects.toThrow('Failed to read staged content');
681
+ }
682
+ finally {
683
+ mockResolveGitRoot.mockRestore();
684
+ mockExec.mockRestore();
685
+ }
686
+ });
687
+ it('does not construct readStrategy when isStaged is false', async () => {
688
+ const rules = [
689
+ makeRule('console\\.log\\("foo"\\)', 'No foo log', 'No foo log', {
690
+ engine: 'ast-grep',
691
+ astGrepPattern: 'console.log("foo")',
692
+ }),
693
+ ];
694
+ writeRules(tmpDir, rules);
695
+ fs.mkdirSync(path.join(tmpDir, 'src'), { recursive: true });
696
+ fs.writeFileSync(path.join(tmpDir, 'src', 'app.ts'), '// context\n console.log("foo");\n// context\n');
697
+ const diff = makeDiff('src/app.ts', ' console.log("foo");');
698
+ const mockExec = vi.spyOn(totem, 'safeExec').mockImplementation(() => {
699
+ throw new Error('[Totem Error] Should not be called');
700
+ });
701
+ let violations = [];
702
+ try {
703
+ const result = await runCompiledRules({
704
+ diff,
705
+ cwd: tmpDir,
706
+ totemDir: TOTEM_DIR,
707
+ format: 'json',
708
+ tag: 'Test',
709
+ isStaged: false,
710
+ });
711
+ violations = result.violations;
712
+ }
713
+ catch (err) {
714
+ if (err instanceof Error &&
715
+ err.name === 'TotemError' &&
716
+ err.message.includes('Violations detected')) {
717
+ violations = [1];
718
+ }
719
+ else {
720
+ throw err;
721
+ }
722
+ }
723
+ // AST engine runs with disk-read fallback
724
+ expect(violations).toHaveLength(1);
725
+ mockExec.mockRestore();
726
+ });
727
+ it('uses repo root as workingDirectory when cwd is a subdirectory', async () => {
728
+ const rules = [
729
+ makeRule('console\\.log\\("foo"\\)', 'No foo log', 'No foo log', {
730
+ engine: 'ast-grep',
731
+ astGrepPattern: 'console.log("foo")',
732
+ }),
733
+ ];
734
+ writeRules(tmpDir, rules);
735
+ const diff = makeDiff('src/app.ts', ' console.log("foo");');
736
+ const subDir = path.join(tmpDir, 'sub', 'dir');
737
+ fs.mkdirSync(subDir, { recursive: true });
738
+ const mockResolveGitRoot = vi.spyOn(totem, 'resolveGitRoot').mockReturnValue(tmpDir);
739
+ const mockExec = vi
740
+ .spyOn(totem, 'safeExec')
741
+ .mockImplementation((cmd, args) => {
742
+ if (!args)
743
+ return '';
744
+ if (args[0] === 'ls-files' && args[1] === '--recurse-submodules' && args[2] === '-s') {
745
+ return '100644 hash 0\tsrc/app.ts\n';
746
+ }
747
+ if (args[0] === 'show') {
748
+ return '// context\n console.log("foo");\n// context\n';
749
+ }
750
+ return '';
751
+ });
752
+ const spyAst = vi.spyOn(totem, 'applyAstRulesToAdditions');
753
+ let violations = [];
754
+ try {
755
+ const result = await runCompiledRules({
756
+ diff,
757
+ cwd: subDir,
758
+ totemDir: TOTEM_DIR,
759
+ format: 'json',
760
+ tag: 'Test',
761
+ isStaged: true,
762
+ configRoot: tmpDir,
763
+ });
764
+ violations = result.violations;
765
+ }
766
+ catch (err) {
767
+ if (err instanceof Error &&
768
+ err.name === 'TotemError' &&
769
+ err.message.includes('Violations detected')) {
770
+ violations = [1];
771
+ }
772
+ else {
773
+ throw err;
774
+ }
775
+ }
776
+ expect(violations).toHaveLength(1);
777
+ expect(spyAst).toHaveBeenCalled();
778
+ // Check that workingDirectory passed to applyAstRulesToAdditions is tmpDir (repo root), not subDir
779
+ expect(spyAst.mock.calls[0][2]).toBe(tmpDir);
780
+ mockResolveGitRoot.mockRestore();
781
+ mockExec.mockRestore();
782
+ spyAst.mockRestore();
783
+ });
784
+ it('uses repo root as workingDirectory for non-staged path from a subdirectory (#1312)', async () => {
785
+ const rules = [
786
+ makeRule('console\\.log\\("foo"\\)', 'No foo log', 'No foo log', {
787
+ engine: 'ast-grep',
788
+ astGrepPattern: 'console.log("foo")',
789
+ }),
790
+ ];
791
+ writeRules(tmpDir, rules);
792
+ // Write the file at repo root so AST can read it
793
+ fs.mkdirSync(path.join(tmpDir, 'src'), { recursive: true });
794
+ fs.writeFileSync(path.join(tmpDir, 'src', 'app.ts'), '// context\n console.log("foo");\n// context\n');
795
+ const diff = makeDiff('src/app.ts', ' console.log("foo");');
796
+ const subDir = path.join(tmpDir, 'sub', 'dir');
797
+ fs.mkdirSync(subDir, { recursive: true });
798
+ const mockResolveGitRoot = vi.spyOn(totem, 'resolveGitRoot').mockReturnValue(tmpDir);
799
+ const spyAst = vi.spyOn(totem, 'applyAstRulesToAdditions');
800
+ let violations = [];
801
+ try {
802
+ const result = await runCompiledRules({
803
+ diff,
804
+ cwd: subDir,
805
+ totemDir: TOTEM_DIR,
806
+ format: 'json',
807
+ tag: 'Test',
808
+ isStaged: false,
809
+ configRoot: tmpDir,
810
+ });
811
+ violations = result.violations;
812
+ }
813
+ catch (err) {
814
+ if (err instanceof Error &&
815
+ err.name === 'TotemError' &&
816
+ err.message.includes('Violations detected')) {
817
+ violations = [1];
818
+ }
819
+ else {
820
+ throw err;
821
+ }
822
+ }
823
+ expect(violations).toHaveLength(1);
824
+ expect(spyAst).toHaveBeenCalled();
825
+ // Non-staged path must also resolve against repo root, not subDir
826
+ expect(spyAst.mock.calls[0][2]).toBe(tmpDir);
827
+ mockResolveGitRoot.mockRestore();
828
+ spyAst.mockRestore();
829
+ });
830
+ it('falls back to original cwd when not in a git repo (resolveGitRoot returns null)', async () => {
831
+ const rules = [
832
+ makeRule('console\\.log\\("foo"\\)', 'No foo log', 'No foo log', {
833
+ engine: 'ast-grep',
834
+ astGrepPattern: 'console.log("foo")',
835
+ }),
836
+ ];
837
+ writeRules(tmpDir, rules);
838
+ fs.mkdirSync(path.join(tmpDir, 'src'), { recursive: true });
839
+ fs.writeFileSync(path.join(tmpDir, 'src', 'app.ts'), '// context\n console.log("foo");\n// context\n');
840
+ const diff = makeDiff('src/app.ts', ' console.log("foo");');
841
+ const mockResolveGitRoot = vi.spyOn(totem, 'resolveGitRoot').mockReturnValue(null);
842
+ const mockExec = vi.spyOn(totem, 'safeExec').mockImplementation(() => {
843
+ throw new Error('[Totem Error] Should not be called');
844
+ });
845
+ let violations = [];
846
+ try {
847
+ const result = await runCompiledRules({
848
+ diff,
849
+ cwd: tmpDir,
850
+ totemDir: TOTEM_DIR,
851
+ format: 'json',
852
+ tag: 'Test',
853
+ isStaged: true,
854
+ });
855
+ violations = result.violations;
856
+ }
857
+ catch (err) {
858
+ if (err instanceof Error &&
859
+ err.name === 'TotemError' &&
860
+ err.message.includes('Violations detected')) {
861
+ violations = [1];
862
+ }
863
+ else {
864
+ throw err;
865
+ }
866
+ }
867
+ // Should gracefully fallback to disk read and process rules
868
+ expect(violations).toHaveLength(1);
869
+ mockResolveGitRoot.mockRestore();
870
+ mockExec.mockRestore();
871
+ });
872
+ });
491
873
  });
492
874
  describe('TOTEM_LITE graceful AST degradation', () => {
493
875
  let tmpDir;