grepmax 0.26.26 → 0.26.28

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 (36) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/README.md +40 -0
  3. package/dist/commands/audit.js +28 -260
  4. package/dist/commands/context.js +42 -26
  5. package/dist/commands/dead.js +37 -35
  6. package/dist/commands/doctor.js +280 -10
  7. package/dist/commands/extract.js +79 -49
  8. package/dist/commands/impact.js +74 -20
  9. package/dist/commands/log.js +25 -25
  10. package/dist/commands/mcp.js +622 -474
  11. package/dist/commands/peek.js +49 -47
  12. package/dist/commands/project.js +29 -107
  13. package/dist/commands/related.js +43 -52
  14. package/dist/commands/search-run.js +23 -8
  15. package/dist/commands/search.js +7 -2
  16. package/dist/commands/similar.js +50 -76
  17. package/dist/commands/skeleton.js +137 -83
  18. package/dist/commands/status.js +90 -25
  19. package/dist/commands/surprises.js +73 -16
  20. package/dist/commands/symbols.js +58 -77
  21. package/dist/commands/test-find.js +51 -17
  22. package/dist/commands/trace.js +26 -11
  23. package/dist/lib/daemon/daemon.js +26 -0
  24. package/dist/lib/daemon/graph-handler.js +853 -0
  25. package/dist/lib/daemon/ipc-handler.js +19 -2
  26. package/dist/lib/daemon/read-verbs.js +105 -0
  27. package/dist/lib/daemon/rows-handler.js +665 -0
  28. package/dist/lib/daemon/vector-handler.js +199 -0
  29. package/dist/lib/store/vector-db.js +1 -1
  30. package/dist/lib/utils/daemon-client.js +11 -0
  31. package/dist/lib/utils/store-access.js +381 -0
  32. package/dist/lib/utils/tests-footer.js +19 -2
  33. package/dist/lib/utils/watcher-launcher.js +10 -0
  34. package/package.json +2 -2
  35. package/plugins/grepmax/.claude-plugin/plugin.json +1 -1
  36. package/scripts/postinstall.js +0 -69
@@ -53,6 +53,7 @@ const logger_1 = require("../utils/logger");
53
53
  const operation_coordinator_1 = require("../utils/operation-coordinator");
54
54
  const path_containment_1 = require("../utils/path-containment");
55
55
  const project_registry_1 = require("../utils/project-registry");
56
+ const read_verbs_1 = require("./read-verbs");
56
57
  const DAEMON_VERSION = (() => {
57
58
  try {
58
59
  return JSON.parse(fs.readFileSync(path.join(__dirname, "../../../package.json"), "utf-8")).version;
@@ -148,6 +149,7 @@ function handleCommand(daemon, cmd, conn) {
148
149
  rebuildPending: daemon.hasUnfinishedRebuild(),
149
150
  capabilities: {
150
151
  exclusiveGenerationRebuild: exports.EXCLUSIVE_GENERATION_REBUILD_PROTOCOL,
152
+ readVerbs: read_verbs_1.READ_VERBS_PROTOCOL,
151
153
  },
152
154
  };
153
155
  case "watch": {
@@ -373,8 +375,23 @@ function handleCommand(daemon, cmd, conn) {
373
375
  return yield daemon.llmStop();
374
376
  case "llm-status":
375
377
  return daemon.llmStatus();
376
- default:
377
- return { ok: false, error: `unknown command: ${cmd.cmd}` };
378
+ // --- Read verbs (registry in read-verbs.ts) ---
379
+ default: {
380
+ const verb = (0, read_verbs_1.getReadVerb)(cmd.cmd);
381
+ if (!verb)
382
+ return { ok: false, error: `unknown command: ${cmd.cmd}` };
383
+ // Same abort wiring as `search`: a client ctrl-C closes the socket,
384
+ // which cancels the in-flight read instead of letting it run on.
385
+ const ac = new AbortController();
386
+ const onClose = () => ac.abort();
387
+ conn.on("close", onClose);
388
+ try {
389
+ return yield daemon.runSharedOperation(String(cmd.cmd), ac.signal, (signal) => verb(cmd, { daemon, conn, signal }));
390
+ }
391
+ finally {
392
+ conn.off("close", onClose);
393
+ }
394
+ }
378
395
  }
379
396
  }
380
397
  catch (err) {
@@ -0,0 +1,105 @@
1
+ "use strict";
2
+ /**
3
+ * Registry for daemon read verbs.
4
+ *
5
+ * The daemon is meant to be the only process that opens the store, so every
6
+ * read-only CLI command becomes a thin IPC client. Rather than growing one more
7
+ * `case` in `ipc-handler.ts` per verb (and making that file a merge magnet),
8
+ * verbs register here and `ipc-handler`'s `default:` looks them up before it
9
+ * reports `unknown command`.
10
+ *
11
+ * Each verb runs through `Daemon.runSharedOperation(verbName, ...)`, so an
12
+ * exclusive rebuild answers DAEMON_BUSY naming the verb instead of racing it,
13
+ * and its abort signal is bound to socket close exactly like `search`.
14
+ *
15
+ * Verbs are request/response only: one JSON line in, one JSON line out. Anything
16
+ * that needs progress belongs in the streaming command set instead.
17
+ *
18
+ * Handlers live beside `search-handler.ts` (`graph-handler.ts`,
19
+ * `rows-handler.ts`, `vector-handler.ts`), each taking a narrow deps interface
20
+ * so `ipc-handler` tests can drive them with a fake `Daemon`.
21
+ */
22
+ Object.defineProperty(exports, "__esModule", { value: true });
23
+ exports.READ_VERBS_PROTOCOL = void 0;
24
+ exports.registerReadVerbs = registerReadVerbs;
25
+ exports.getReadVerb = getReadVerb;
26
+ exports.readVerbNames = readVerbNames;
27
+ exports.clearReadVerbs = clearReadVerbs;
28
+ exports.registerGraphVerbs = registerGraphVerbs;
29
+ const graph_handler_1 = require("./graph-handler");
30
+ /** Bumped when the verb wire shapes change incompatibly. */
31
+ exports.READ_VERBS_PROTOCOL = 1;
32
+ const registry = new Map();
33
+ /**
34
+ * Register one or more verbs. Re-registering a name replaces it, which keeps
35
+ * hot-reload and test setup simple; duplicate names across packages are a bug,
36
+ * so the collision is logged when it happens with a different handler.
37
+ */
38
+ function registerReadVerbs(entries) {
39
+ const iterable = entries[Symbol.iterator];
40
+ const pairs = typeof iterable === "function"
41
+ ? entries
42
+ : Object.entries(entries);
43
+ for (const [name, handler] of pairs) {
44
+ registry.set(name, handler);
45
+ }
46
+ }
47
+ function getReadVerb(name) {
48
+ return typeof name === "string" ? registry.get(name) : undefined;
49
+ }
50
+ function readVerbNames() {
51
+ return [...registry.keys()].sort();
52
+ }
53
+ /** Test hook: drop every registration. */
54
+ function clearReadVerbs() {
55
+ registry.clear();
56
+ }
57
+ // ---------------------------------------------------------------------------
58
+ // graph verbs (WP-B) — graph.resolve, graph.tests, graph.dependents,
59
+ // graph.trace, graph.peek, graph.dead, graph.audit; handlers in
60
+ // graph-handler.ts.
61
+ //
62
+ // `graph.peek` is not in the plan's table: `peek` needs its defining-chunk rows
63
+ // and its `is_exported`/`end_line` metadata alongside the graph, and those
64
+ // selects would otherwise land in WP-C's `rows.locate`. Keeping them in one
65
+ // composite verb costs one round trip instead of four and keeps peek's
66
+ // rendering (and its `fs.readFileSync` signature extraction) unchanged.
67
+ //
68
+ // WP-D added four more for the MCP tools that have no CLI twin:
69
+ // `graph.neighbors`, `graph.paths` and `graph.subgraph` are the GraphBuilder
70
+ // traversal primitives behind `get_neighbors` / `find_paths` /
71
+ // `subgraph_for_files` — distinct entry points with their own hop and size
72
+ // bounds, which is why they are separate verbs rather than options on
73
+ // `graph.trace`. `graph.risk` is the store half of `review_risk`: the git half
74
+ // (diff, churn) stays with the caller, exactly as `extract` keeps its body read.
75
+ // ---------------------------------------------------------------------------
76
+ /**
77
+ * Called once from the Daemon constructor rather than at module load, so that
78
+ * importing this registry (as `ipc-handler` and its tests do) does not populate
79
+ * it behind a test's back.
80
+ */
81
+ function registerGraphVerbs() {
82
+ registerReadVerbs((0, graph_handler_1.createGraphVerbs)((ctx) => ctx.daemon.storeReadDeps()));
83
+ }
84
+ // ---------------------------------------------------------------------------
85
+ // rows verbs (WP-C) — rows.symbols, rows.project, rows.locate, rows.skeleton.
86
+ // Handlers and their `registerRowsVerbs()` live in rows-handler.ts;
87
+ // `Daemon.start()` calls it, because registering at module scope would make the
88
+ // registry non-empty on import and break the assertions in
89
+ // tests/ipc-read-verbs.test.ts.
90
+ //
91
+ // `rows.project` is not in the plan's table: `symbols` and `project` were to
92
+ // share one row-proxy verb. `project.ts` selects up to 200 000 rows with two
93
+ // symbol-array columns, and the platform project holds 266 753 chunks, so the
94
+ // proxy shape would push hundreds of megabytes through the daemon's event loop
95
+ // for a summary that fits in a few kilobytes. Both verbs return the finished
96
+ // aggregate instead — see the rows-handler.ts header.
97
+ //
98
+ // WP-C also shipped `rows.tests` for `extract`'s footer; WP-D removed it. It
99
+ // wrapped the same `findTests` call `graph.tests` does, and `extract` now sends
100
+ // that verb, so the duplicate wire shape is gone before any daemon served it.
101
+ // ---------------------------------------------------------------------------
102
+ // ---------------------------------------------------------------------------
103
+ // vector verbs (WP-C) — vector.similar, vector.surprises; handlers and
104
+ // `registerVectorVerbs()` in vector-handler.ts, called from `Daemon.start()`.
105
+ // ---------------------------------------------------------------------------