grepmax 0.18.1 → 0.19.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 (64) hide show
  1. package/README.md +27 -2
  2. package/dist/commands/add.js +4 -2
  3. package/dist/commands/claude-code.js +1 -1
  4. package/dist/commands/codex.js +3 -1
  5. package/dist/commands/dead.js +2 -6
  6. package/dist/commands/doctor.js +26 -7
  7. package/dist/commands/extract.js +3 -5
  8. package/dist/commands/impact.js +6 -4
  9. package/dist/commands/index.js +7 -2
  10. package/dist/commands/log.js +4 -2
  11. package/dist/commands/mcp.js +587 -715
  12. package/dist/commands/peek.js +15 -9
  13. package/dist/commands/plugin.js +1 -1
  14. package/dist/commands/project.js +15 -5
  15. package/dist/commands/related.js +8 -9
  16. package/dist/commands/review.js +1 -1
  17. package/dist/commands/similar.js +4 -4
  18. package/dist/commands/status.js +5 -3
  19. package/dist/commands/summarize.js +6 -4
  20. package/dist/commands/test-find.js +2 -2
  21. package/dist/commands/trace.js +12 -5
  22. package/dist/commands/watch.js +9 -5
  23. package/dist/eval-graph-nav.js +4 -1
  24. package/dist/eval-graph-recovery-probe.js +56 -14
  25. package/dist/eval-graph-spotcheck.js +10 -2
  26. package/dist/eval-graph-totals.js +5 -2
  27. package/dist/eval-oss.js +212 -37
  28. package/dist/eval-seed.js +13 -4
  29. package/dist/index.js +9 -9
  30. package/dist/lib/daemon/daemon.js +22 -13
  31. package/dist/lib/daemon/ipc-handler.js +18 -5
  32. package/dist/lib/daemon/mlx-server-manager.js +11 -3
  33. package/dist/lib/daemon/process-manager.js +1 -2
  34. package/dist/lib/daemon/watcher-manager.js +4 -4
  35. package/dist/lib/graph/callsites.js +151 -25
  36. package/dist/lib/index/batch-processor.js +6 -5
  37. package/dist/lib/index/chunker.js +2 -0
  38. package/dist/lib/index/syncer.js +7 -6
  39. package/dist/lib/llm/diff.js +56 -11
  40. package/dist/lib/llm/investigate.js +12 -5
  41. package/dist/lib/llm/review.js +21 -8
  42. package/dist/lib/llm/server.js +16 -7
  43. package/dist/lib/output/agent-search-formatter.js +25 -3
  44. package/dist/lib/output/index-state-footer.js +1 -1
  45. package/dist/lib/review/risk.js +2 -4
  46. package/dist/lib/search/searcher.js +37 -11
  47. package/dist/lib/search/seed-weight.js +4 -1
  48. package/dist/lib/skeleton/symbol-extractor.js +2 -1
  49. package/dist/lib/utils/cross-project.js +5 -1
  50. package/dist/lib/utils/daemon-client.js +5 -1
  51. package/dist/lib/utils/git.js +10 -2
  52. package/dist/lib/utils/project-registry.js +3 -2
  53. package/dist/lib/utils/scope-filter.js +3 -1
  54. package/dist/lib/utils/watcher-launcher.js +4 -1
  55. package/dist/lib/utils/watcher-store.js +2 -1
  56. package/dist/lib/workers/embeddings/mlx-client.js +7 -2
  57. package/dist/lib/workers/pool.js +9 -6
  58. package/dist/lib/workers/process-child.js +1 -1
  59. package/package.json +22 -19
  60. package/plugins/grepmax/.claude-plugin/plugin.json +1 -1
  61. package/plugins/grepmax/hooks/cwd-changed.js +4 -1
  62. package/plugins/grepmax/hooks/pre-grep.js +2 -1
  63. package/plugins/grepmax/hooks/start.js +45 -10
  64. package/plugins/grepmax/hooks/subagent-start.js +1 -4
package/README.md CHANGED
@@ -2,6 +2,14 @@
2
2
  <h1>grepmax</h1>
3
3
  <p><em>Slash tokens. Save time. Semantic search for your coding agent.</em></p>
4
4
 
5
+ <a href="https://www.npmjs.com/package/grepmax">
6
+ <img src="https://img.shields.io/npm/v/grepmax.svg" alt="npm version" />
7
+ </a>
8
+
9
+ <a href="https://www.npmjs.com/package/grepmax">
10
+ <img src="https://img.shields.io/npm/dm/grepmax.svg" alt="npm downloads" />
11
+ </a>
12
+
5
13
  <a href="https://opensource.org/licenses/Apache-2.0">
6
14
  <img src="https://img.shields.io/badge/License-Apache%202.0-blue.svg" alt="License: Apache 2.0" />
7
15
  </a>
@@ -24,7 +32,7 @@ Natural-language search that works like `grep`. Fast, local, and built for codin
24
32
  - **Role Detection:** Distinguishes `ORCHESTRATION` (high-level logic) from `DEFINITION` (types/classes).
25
33
  - **Local & Private:** 100% local embeddings via ONNX (CPU) or MLX (Apple Silicon GPU).
26
34
  - **Centralized Index:** One database at `~/.gmax/` — index once, search from anywhere.
27
- - **Agent-Ready:** `--agent` flag returns compact one-line output — ~90% fewer tokens than default.
35
+ - **Agent-Ready:** `--agent` flag returns compact one-line output — ~89% fewer tokens than default.
28
36
 
29
37
  ## Quick Start
30
38
 
@@ -124,7 +132,12 @@ Plugins auto-update when you run `npm install -g grepmax@latest` — no need to
124
132
  | `extract_symbol` | Complete function/class body by symbol name. |
125
133
  | `peek_symbol` | Compact overview: signature + callers + callees. |
126
134
  | `dead` | Unused-symbol check via call graph. Returns `DEAD`, `PUBLIC EXPORT`, or `LIVE` with caller count. |
135
+ | `audit` | Graph summary: god nodes, hub files, and dead-code candidates in one call. |
136
+ | `get_neighbors` | Graph primitive: symbols reachable from a node along call edges within N hops. |
137
+ | `find_paths` | Graph primitive: shortest call-graph path between two symbols. |
138
+ | `subgraph_for_files` | Graph primitive: local dependency subgraph for a set of files. |
127
139
  | `list_symbols` | Indexed symbols with role and export status. |
140
+ | `list_projects` | List every indexed project (name, root, status, chunks) to pick a search scope. |
128
141
  | `index_status` | Index health: chunks, files, projects, watcher status. |
129
142
  | `summarize_project` | Project overview: languages, structure, key symbols, entry points. |
130
143
  | `summarize_directory` | Generate LLM summaries for indexed chunks. |
@@ -138,6 +151,7 @@ Plugins auto-update when you run `npm install -g grepmax@latest` — no need to
138
151
  | `investigate` | Agentic codebase Q&A using local LLM + gmax tools. |
139
152
  | `review_commit` | Review a git commit for bugs, security issues, and breaking changes. |
140
153
  | `review_report` | Get accumulated code review findings for the current project. |
154
+ | `review_risk` | Deterministic risk ranking of symbols a commit touches (blast radius × tests × churn). No LLM. |
141
155
 
142
156
  ## Search Options
143
157
 
@@ -157,11 +171,19 @@ gmax "query" [options]
157
171
  | `--symbol` | Append call graph after results. | `false` |
158
172
  | `--imports` | Prepend file imports per result. | `false` |
159
173
  | `--name <regex>` | Filter by symbol name. | — |
174
+ | `--in <subpath>` | Restrict to a sub-path of the project (repeatable). | — |
175
+ | `--seed-file <path>` | Bias results toward files in your working context (repeatable). | — |
176
+ | `--seed-symbol <name>` | Bias results toward an identifier you're working with (repeatable). | — |
160
177
  | `--skeleton` | Show file skeletons for top matches. | `false` |
161
178
  | `--context-for-llm` | Full function bodies + imports per result. | `false` |
162
179
  | `--budget <tokens>` | Cap output tokens (for `--context-for-llm`). | `8000` |
163
180
  | `--explain` | Show scoring breakdown per result. | `false` |
181
+ | `--scores` | Show relevance scores. | `false` |
182
+ | `--compact` | Compact hits view (paths + line ranges + role/preview). | `false` |
183
+ | `--plain` | Disable ANSI colors and use simpler formatting. | `false` |
184
+ | `-c, --content` | Show full chunk content instead of snippets. | `false` |
164
185
  | `-C <n>` | Context lines before/after. | `0` |
186
+ | `-s, --sync` | Sync local files to the store before searching. | `false` |
165
187
  | `--root <dir>` | Search a different project. | cwd |
166
188
  | `--all-projects` | Search every indexed project; results grouped by project. | `false` |
167
189
  | `--projects <list>` | Search only these projects (comma-separated names). | — |
@@ -251,7 +273,10 @@ All data lives in `~/.gmax/`:
251
273
 
252
274
  **Pipeline:** Walk (gitignore-aware) → Chunk (Tree-sitter) → Embed (384-dim Granite via ONNX/MLX) → Store (LanceDB + LMDB) → Search (vector + FTS + RRF fusion + ColBERT rerank)
253
275
 
254
- **Supported Languages:** TypeScript, JavaScript, Python, Go, Rust, Java, C#, C++, C, Ruby, PHP, Swift, Kotlin, JSON, YAML, Markdown, SQL, Shell.
276
+ **Supported Languages:**
277
+
278
+ - *Structure-aware* (Tree-sitter chunking + call graph): TypeScript, JavaScript/JSX, Python, Go, Rust, Java, C#, C++, C, Ruby, PHP, Swift, Kotlin, Scala, Lua, Bash, JSON.
279
+ - *Text-indexed* (semantic search only, no call graph): Markdown, YAML, CSS, HTML, SQL, TOML, XML, and other common formats.
255
280
 
256
281
  ## Configuration
257
282
 
@@ -147,7 +147,7 @@ Examples:
147
147
  }
148
148
  const names = children.map((c) => c.name).join(", ");
149
149
  console.log(`Absorbing ${children.length} sub-project(s): ${names}`);
150
- const { ensureDaemonRunning: checkDaemon, sendStreamingCommand: sendCmd } = yield Promise.resolve().then(() => __importStar(require("../lib/utils/daemon-client")));
150
+ const { ensureDaemonRunning: checkDaemon, sendStreamingCommand: sendCmd, } = yield Promise.resolve().then(() => __importStar(require("../lib/utils/daemon-client")));
151
151
  const daemonUp = yield checkDaemon();
152
152
  for (const child of children) {
153
153
  if (daemonUp) {
@@ -158,7 +158,9 @@ Examples:
158
158
  // Direct mode: delete vectors and MetaCache entries
159
159
  const childPaths = (0, project_root_1.ensureProjectPaths)(child.root);
160
160
  const db = new vector_db_1.VectorDB(childPaths.lancedbDir);
161
- const childPrefix = child.root.endsWith("/") ? child.root : `${child.root}/`;
161
+ const childPrefix = child.root.endsWith("/")
162
+ ? child.root
163
+ : `${child.root}/`;
162
164
  yield db.deletePathsWithPrefix(childPrefix);
163
165
  const { MetaCache } = yield Promise.resolve().then(() => __importStar(require("../lib/store/meta-cache")));
164
166
  const mc = new MetaCache(childPaths.lmdbPath);
@@ -43,9 +43,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
43
43
  };
44
44
  Object.defineProperty(exports, "__esModule", { value: true });
45
45
  exports.installClaudeCode = void 0;
46
+ const node_child_process_1 = require("node:child_process");
46
47
  const fs = __importStar(require("node:fs"));
47
48
  const path = __importStar(require("node:path"));
48
- const node_child_process_1 = require("node:child_process");
49
49
  const commander_1 = require("commander");
50
50
  function runClaudeCommand(args) {
51
51
  return new Promise((resolve, reject) => {
@@ -57,7 +57,9 @@ function writeSkillToAgents(skill) {
57
57
  const markerRe = new RegExp(`\n?${SKILL_START}[\\s\\S]*?${SKILL_END}\n?`, "g");
58
58
  const cleaned = content.replace(markerRe, "");
59
59
  // Remove legacy content (everything between --- blocks mentioning gmax)
60
- const withoutLegacy = cleaned.replace(/---[\s\S]*?(?:gmax|--compact)[\s\S]*?(?=\n<!-- |$)/, "").trim();
60
+ const withoutLegacy = cleaned
61
+ .replace(/---[\s\S]*?(?:gmax|--compact)[\s\S]*?(?=\n<!-- |$)/, "")
62
+ .trim();
61
63
  node_fs_1.default.writeFileSync(AGENTS_PATH, withoutLegacy ? `${withoutLegacy}\n\n${block}` : block);
62
64
  }
63
65
  else {
@@ -50,8 +50,8 @@ const agent_errors_1 = require("../lib/utils/agent-errors");
50
50
  const exit_1 = require("../lib/utils/exit");
51
51
  const filter_builder_1 = require("../lib/utils/filter-builder");
52
52
  const project_registry_1 = require("../lib/utils/project-registry");
53
- const stale_hint_1 = require("../lib/utils/stale-hint");
54
53
  const project_root_1 = require("../lib/utils/project-root");
54
+ const stale_hint_1 = require("../lib/utils/stale-hint");
55
55
  const useColors = process.stdout.isTTY && !process.env.NO_COLOR;
56
56
  const style = {
57
57
  bold: (s) => (useColors ? `\x1b[1m${s}\x1b[22m` : s),
@@ -148,11 +148,7 @@ exports.dead = new commander_1.Command("dead")
148
148
  const isExported = Boolean(defRow.is_exported);
149
149
  const builder = new graph_builder_1.GraphBuilder(vectorDb, scope.pathPrefix, scope.excludePrefixes);
150
150
  const callers = yield builder.getCallers(symbol);
151
- const status = callers.length === 0
152
- ? isExported
153
- ? "PUBLIC_EXPORT"
154
- : "DEAD"
155
- : "LIVE";
151
+ const status = callers.length === 0 ? (isExported ? "PUBLIC_EXPORT" : "DEAD") : "LIVE";
156
152
  const topCallers = callers
157
153
  .slice(0, TOP_CALLERS)
158
154
  .map((c) => ({ file: c.file, line: c.line }));
@@ -135,7 +135,10 @@ exports.doctor = new commander_1.Command("doctor")
135
135
  embedUp = res.ok;
136
136
  }
137
137
  catch (err) {
138
- embedError = err.code === "ECONNREFUSED" ? "connection refused" : (err.message || String(err));
138
+ embedError =
139
+ err.code === "ECONNREFUSED"
140
+ ? "connection refused"
141
+ : err.message || String(err);
139
142
  }
140
143
  console.log(`${embedUp ? "ok" : "WARN"} MLX Embed: ${embedUp ? "running (port 8100)" : `not running${embedError ? ` (${embedError})` : ""}`}`);
141
144
  if (embedUp) {
@@ -234,7 +237,12 @@ exports.doctor = new commander_1.Command("doctor")
234
237
  try {
235
238
  const diskStats = fs.statfsSync(config_1.PATHS.lancedbDir);
236
239
  availBytes = diskStats.bavail * diskStats.bsize;
237
- diskLevel = availBytes < config_1.DISK_CRITICAL_BYTES ? "CRITICAL" : availBytes < config_1.DISK_LOW_BYTES ? "LOW" : "ok";
240
+ diskLevel =
241
+ availBytes < config_1.DISK_CRITICAL_BYTES
242
+ ? "CRITICAL"
243
+ : availBytes < config_1.DISK_LOW_BYTES
244
+ ? "LOW"
245
+ : "ok";
238
246
  }
239
247
  catch (_g) { }
240
248
  const staleChunkerProjects = projects.filter((p) => {
@@ -247,7 +255,10 @@ exports.doctor = new commander_1.Command("doctor")
247
255
  // (a dim change can't be auto-fixed in the shared fixed-dim table; that's
248
256
  // the deferred Phase 1B re-embed work).
249
257
  const staleEmbeddingProjects = projects.filter((p) => p.status === "indexed" &&
250
- (0, config_1.describeEmbeddingGap)({ modelTier: p.modelTier, vectorDim: p.vectorDim }, { modelTier: globalConfig.modelTier, vectorDim: globalConfig.vectorDim }) !== null);
258
+ (0, config_1.describeEmbeddingGap)({ modelTier: p.modelTier, vectorDim: p.vectorDim }, {
259
+ modelTier: globalConfig.modelTier,
260
+ vectorDim: globalConfig.vectorDim,
261
+ }) !== null);
251
262
  if (opts.agent) {
252
263
  const fields = [
253
264
  "index_health",
@@ -281,7 +292,10 @@ exports.doctor = new commander_1.Command("doctor")
281
292
  ].join("\t"));
282
293
  }
283
294
  for (const p of staleEmbeddingProjects) {
284
- const gap = (0, config_1.describeEmbeddingGap)({ modelTier: p.modelTier, vectorDim: p.vectorDim }, { modelTier: globalConfig.modelTier, vectorDim: globalConfig.vectorDim });
295
+ const gap = (0, config_1.describeEmbeddingGap)({ modelTier: p.modelTier, vectorDim: p.vectorDim }, {
296
+ modelTier: globalConfig.modelTier,
297
+ vectorDim: globalConfig.vectorDim,
298
+ });
285
299
  if (!gap)
286
300
  continue;
287
301
  console.log([
@@ -361,7 +375,10 @@ exports.doctor = new commander_1.Command("doctor")
361
375
  // the shared fixed-dim table (deferred Phase 1B), so we point at the
362
376
  // manual reset instead.
363
377
  if (staleEmbeddingProjects.length > 0) {
364
- const gaps = staleEmbeddingProjects.map((p) => (0, config_1.describeEmbeddingGap)({ modelTier: p.modelTier, vectorDim: p.vectorDim }, { modelTier: globalConfig.modelTier, vectorDim: globalConfig.vectorDim }));
378
+ const gaps = staleEmbeddingProjects.map((p) => (0, config_1.describeEmbeddingGap)({ modelTier: p.modelTier, vectorDim: p.vectorDim }, {
379
+ modelTier: globalConfig.modelTier,
380
+ vectorDim: globalConfig.vectorDim,
381
+ }));
365
382
  const anyBreaking = gaps.some((g) => (g === null || g === void 0 ? void 0 : g.severity) === "breaking");
366
383
  console.log(`${anyBreaking ? "WARN" : "INFO"} Stale embedding: ${staleEmbeddingProjects.length} project(s) indexed with a different embedding model/dim — run 'gmax index --reset' per project`);
367
384
  staleEmbeddingProjects.forEach((p, i) => {
@@ -391,8 +408,10 @@ exports.doctor = new commander_1.Command("doctor")
391
408
  try {
392
409
  const { MetaCache } = yield Promise.resolve().then(() => __importStar(require("../lib/store/meta-cache")));
393
410
  const mc = new MetaCache(config_1.PATHS.lmdbPath);
394
- for (const project of projects.filter(p => p.status === "indexed")) {
395
- const prefix = project.root.endsWith("/") ? project.root : `${project.root}/`;
411
+ for (const project of projects.filter((p) => p.status === "indexed")) {
412
+ const prefix = project.root.endsWith("/")
413
+ ? project.root
414
+ : `${project.root}/`;
396
415
  const cachedCount = (yield mc.getKeysWithPrefix(prefix)).size;
397
416
  const vectorCount = yield db.countDistinctFilesForPath(prefix);
398
417
  if (cachedCount > 0) {
@@ -107,8 +107,8 @@ exports.extract = new commander_1.Command("extract")
107
107
  .description("Extract full function/class body by symbol name")
108
108
  .argument("<symbol>", "The symbol to extract")
109
109
  .option("--root <dir>", "Project root directory")
110
- .option("--in <subpath>", "Restrict to a sub-path of the project (repeatable)", (value, prev) => (prev ? [...prev, value] : [value]))
111
- .option("--exclude <subpath>", "Exclude a sub-path of the project (repeatable)", (value, prev) => (prev ? [...prev, value] : [value]))
110
+ .option("--in <subpath>", "Restrict to a sub-path of the project (repeatable)", (value, prev) => prev ? [...prev, value] : [value])
111
+ .option("--exclude <subpath>", "Exclude a sub-path of the project (repeatable)", (value, prev) => prev ? [...prev, value] : [value])
112
112
  .option("--agent", "Compact output for AI agents", false)
113
113
  .option("--imports", "Prepend file imports", false)
114
114
  .option("--no-tests", "Suppress the tests footer")
@@ -146,9 +146,7 @@ exports.extract = new commander_1.Command("extract")
146
146
  const byLang = (0, language_1.groupByLanguage)(chunks);
147
147
  if (byLang.size >= 2) {
148
148
  const rel = (p) => p.startsWith(projectRoot) ? p.slice(projectRoot.length + 1) : p;
149
- const lines = [
150
- `Symbol '${symbol}' is defined in multiple languages:`,
151
- ];
149
+ const lines = [`Symbol '${symbol}' is defined in multiple languages:`];
152
150
  for (const [lang, group] of byLang) {
153
151
  const c = group[0];
154
152
  lines.push(` ${lang.padEnd(6)} ${rel(c.path)}:${c.startLine + 1}`);
@@ -51,15 +51,15 @@ const vector_db_1 = require("../lib/store/vector-db");
51
51
  const agent_errors_1 = require("../lib/utils/agent-errors");
52
52
  const exit_1 = require("../lib/utils/exit");
53
53
  const project_registry_1 = require("../lib/utils/project-registry");
54
- const stale_hint_1 = require("../lib/utils/stale-hint");
55
54
  const project_root_1 = require("../lib/utils/project-root");
55
+ const stale_hint_1 = require("../lib/utils/stale-hint");
56
56
  exports.impact = new commander_1.Command("impact")
57
57
  .description("Analyze change impact: dependents and affected tests")
58
58
  .argument("<target>", "Symbol name or file path")
59
59
  .option("-d, --depth <n>", "Caller traversal depth (default 1, max 3)", "1")
60
60
  .option("--root <dir>", "Project root directory")
61
- .option("--in <subpath>", "Restrict to a sub-path of the project (repeatable)", (value, prev) => (prev ? [...prev, value] : [value]))
62
- .option("--exclude <subpath>", "Exclude a sub-path of the project (repeatable)", (value, prev) => (prev ? [...prev, value] : [value]))
61
+ .option("--in <subpath>", "Restrict to a sub-path of the project (repeatable)", (value, prev) => prev ? [...prev, value] : [value])
62
+ .option("--exclude <subpath>", "Exclude a sub-path of the project (repeatable)", (value, prev) => prev ? [...prev, value] : [value])
63
63
  .option("--no-tests", "Skip affected-test analysis; show production blast radius only")
64
64
  .option("--agent", "Compact output for AI agents", false)
65
65
  .action((target, opts) => __awaiter(void 0, void 0, void 0, function* () {
@@ -87,7 +87,9 @@ exports.impact = new commander_1.Command("impact")
87
87
  }
88
88
  // Resolve the target's own file path for exclusion
89
89
  const targetPath = resolvedAsFile
90
- ? (target.startsWith("/") ? target : path.resolve(projectRoot, target))
90
+ ? target.startsWith("/")
91
+ ? target
92
+ : path.resolve(projectRoot, target)
91
93
  : undefined;
92
94
  const excludePaths = targetPath ? new Set([targetPath]) : undefined;
93
95
  const { resolveScope } = yield Promise.resolve().then(() => __importStar(require("../lib/utils/scope-filter")));
@@ -46,8 +46,8 @@ exports.index = void 0;
46
46
  const path = __importStar(require("node:path"));
47
47
  const commander_1 = require("commander");
48
48
  const config_1 = require("../config");
49
- const index_config_1 = require("../lib/index/index-config");
50
49
  const grammar_loader_1 = require("../lib/index/grammar-loader");
50
+ const index_config_1 = require("../lib/index/index-config");
51
51
  const sync_helpers_1 = require("../lib/index/sync-helpers");
52
52
  const syncer_1 = require("../lib/index/syncer");
53
53
  const setup_helpers_1 = require("../lib/setup/setup-helpers");
@@ -113,7 +113,12 @@ Examples:
113
113
  // Daemon mode: IPC streaming — daemon handles watcher pause/resume internally
114
114
  const { spinner, onProgress } = (0, sync_helpers_1.createIndexingSpinner)(projectRoot, "Indexing...", { verbose: options.verbose });
115
115
  try {
116
- const done = yield sendStreamingCommand({ cmd: "index", root: projectRoot, reset: options.reset, dryRun: options.dryRun }, (msg) => {
116
+ const done = yield sendStreamingCommand({
117
+ cmd: "index",
118
+ root: projectRoot,
119
+ reset: options.reset,
120
+ dryRun: options.dryRun,
121
+ }, (msg) => {
117
122
  var _a, _b, _c;
118
123
  onProgress({
119
124
  processed: (_a = msg.processed) !== null && _a !== void 0 ? _a : 0,
@@ -97,7 +97,8 @@ function printHuman(commits, projectRoot, targetPaths) {
97
97
  if (targetPaths && targetPaths.length > 1) {
98
98
  const targetSet = new Set(targetPaths);
99
99
  const touched = c.numstatLines
100
- .filter((n) => targetSet.has(n.path) || targetSet.has(path.resolve(projectRoot, n.path)))
100
+ .filter((n) => targetSet.has(n.path) ||
101
+ targetSet.has(path.resolve(projectRoot, n.path)))
101
102
  .map((n) => relativize(n.path, projectRoot));
102
103
  if (touched.length > 0) {
103
104
  console.log(` ${style.dim(`via: ${touched.join(", ")}`)}`);
@@ -112,7 +113,8 @@ function printAgent(commits, projectRoot, targetPaths) {
112
113
  let touched = "";
113
114
  if (targetSet) {
114
115
  const touchedPaths = c.numstatLines
115
- .filter((n) => targetSet.has(n.path) || targetSet.has(path.resolve(projectRoot, n.path)))
116
+ .filter((n) => targetSet.has(n.path) ||
117
+ targetSet.has(path.resolve(projectRoot, n.path)))
116
118
  .map((n) => relativize(n.path, projectRoot));
117
119
  touched = touchedPaths.join(",");
118
120
  }