@reposkein/mcp 0.4.0 → 0.5.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 (45) hide show
  1. package/README.md +3 -0
  2. package/binary-digests.json +4 -4
  3. package/dist/cli/view.js +27 -6
  4. package/dist/cli/view.js.map +1 -1
  5. package/dist/index.d.ts +8 -56
  6. package/dist/index.js +38 -402
  7. package/dist/index.js.map +1 -1
  8. package/dist/indexer/indexLock.d.ts +13 -0
  9. package/dist/indexer/indexLock.js +66 -0
  10. package/dist/indexer/indexLock.js.map +1 -0
  11. package/dist/indexer/runIndexer.d.ts +8 -0
  12. package/dist/indexer/runIndexer.js +12 -0
  13. package/dist/indexer/runIndexer.js.map +1 -1
  14. package/dist/serve/serve.d.ts +95 -0
  15. package/dist/serve/serve.js +581 -0
  16. package/dist/serve/serve.js.map +1 -0
  17. package/dist/serve/tokens.d.ts +49 -0
  18. package/dist/serve/tokens.js +108 -0
  19. package/dist/serve/tokens.js.map +1 -0
  20. package/dist/serve/watch.d.ts +73 -0
  21. package/dist/serve/watch.js +135 -0
  22. package/dist/serve/watch.js.map +1 -0
  23. package/dist/server/createMcpServer.d.ts +129 -0
  24. package/dist/server/createMcpServer.js +464 -0
  25. package/dist/server/createMcpServer.js.map +1 -0
  26. package/dist/store/JsonlGraphStore.d.ts +5 -1
  27. package/dist/store/JsonlGraphStore.js +6 -2
  28. package/dist/store/JsonlGraphStore.js.map +1 -1
  29. package/dist/store/teamConfig.d.ts +10 -6
  30. package/dist/store/teamConfig.js +23 -17
  31. package/dist/store/teamConfig.js.map +1 -1
  32. package/dist/tools/recordDecision.d.ts +3 -0
  33. package/dist/tools/recordDecision.js +1 -1
  34. package/dist/tools/recordDecision.js.map +1 -1
  35. package/dist/tools/writeSemanticSummary.d.ts +4 -1
  36. package/dist/tools/writeSemanticSummary.js +5 -2
  37. package/dist/tools/writeSemanticSummary.js.map +1 -1
  38. package/dist/viz/assets/index-BnqIVYFE.css +1 -0
  39. package/dist/viz/assets/index-IhtszTp0.js +5 -0
  40. package/dist/viz/assets/{r3f-BZY3QR6_.js → r3f-Bn9htB92.js} +1 -1
  41. package/dist/viz/assets/{tanstack-CjXr-L-s.js → tanstack-CSzx6NDA.js} +7 -7
  42. package/dist/viz/index.html +4 -4
  43. package/package.json +1 -1
  44. package/dist/viz/assets/index-CxqeGuRS.css +0 -1
  45. package/dist/viz/assets/index-DiNZyrXx.js +0 -9
package/dist/index.js CHANGED
@@ -6,62 +6,16 @@ import { runDoctor, resolveDoctorRepoPath } from "./cli/doctor.js";
6
6
  import { runAdr } from "./cli/adr.js";
7
7
  import { runView, runExport, parseViewArgs } from "./cli/view.js";
8
8
  import { runStats } from "./cli/stats.js";
9
- import { existsSync, realpathSync } from "node:fs";
10
- import { join } from "node:path";
11
- import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
9
+ import { runServe, parseServeArgs } from "./serve/serve.js";
10
+ import { realpathSync } from "node:fs";
12
11
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
13
- import { z } from "zod";
14
- import { Neo4jGraphStore } from "./store/Neo4jGraphStore.js";
15
- import { UnconfiguredStore } from "./store/UnconfiguredStore.js";
16
- import { JsonlGraphStore } from "./store/JsonlGraphStore.js";
17
- import { makeReadCypher } from "./tools/readCypher.js";
18
- import { makeGetContextProfile } from "./tools/getContextProfile.js";
19
- import { makeWriteSemanticSummary } from "./tools/writeSemanticSummary.js";
20
- import { makeInitCpgSkeleton, makeReindexFile } from "./tools/indexerTools.js";
21
- import { makeSemanticFind } from "./tools/semanticFind.js";
22
- import { makeTemporalContext } from "./tools/temporalContext.js";
23
- import { makeImpact } from "./tools/impact.js";
24
- import { makeRecordDecision } from "./tools/recordDecision.js";
25
- import { makeSetDecisionStatus } from "./tools/setDecisionStatus.js";
26
- import { makeReaffirmDecision } from "./tools/reaffirmDecision.js";
27
- import { makeListDecisions } from "./tools/listDecisions.js";
28
- import { makeGetDecision } from "./tools/getDecision.js";
29
12
  import { resolveRepoId } from "./store/repoId.js";
30
- import { RepoSession } from "./store/repoSession.js";
31
- import { makeCache } from "./store/repoContextCache.js";
32
- import { ensureGraph } from "./indexer/ensureGraph.js";
33
- import { ensureIndexerBinary, packageVersion } from "./indexer/fetchBinary.js";
34
- import { spawnIndexer } from "./indexer/runIndexer.js";
35
- import { SessionLogger, resolveSessionId } from "./store/sessionLog.js";
36
- import { createToolLogger } from "./store/instrumentTool.js";
37
- /** Selects the store backend.
38
- * REPOSKEIN_STORE = "jsonl" | "neo4j" | "auto" (default "auto").
39
- * - auto: JSONL if <repoPath>/.reposkein/nodes.jsonl exists, else Neo4j if
40
- * NEO4J_PASSWORD is set, else Unconfigured.
41
- * - jsonl: JSONL if available, else Unconfigured.
42
- * - neo4j: Neo4j if configured, else Unconfigured. */
43
- function buildStore(repoPath, repoId) {
44
- const mode = (process.env.REPOSKEIN_STORE ?? "auto").toLowerCase();
45
- const jsonlReady = !!repoPath && !!repoId && existsSync(join(repoPath, ".reposkein", "nodes.jsonl"));
46
- const neo4j = () => {
47
- try {
48
- return Neo4jGraphStore.fromEnv();
49
- }
50
- catch {
51
- return new UnconfiguredStore();
52
- }
53
- };
54
- if (mode === "jsonl") {
55
- return jsonlReady ? new JsonlGraphStore(repoPath, repoId) : new UnconfiguredStore();
56
- }
57
- if (mode === "neo4j") {
58
- return neo4j();
59
- }
60
- // auto
61
- if (jsonlReady)
62
- return new JsonlGraphStore(repoPath, repoId);
63
- return neo4j();
64
- }
13
+ import { createMcpServer } from "./server/createMcpServer.js";
14
+ import { packageVersion } from "./indexer/fetchBinary.js";
15
+ /** Re-exported from `server/createMcpServer.ts`, where the tool registration
16
+ * now lives (REP-17 extracted it so `serve --http` can build one server PER
17
+ * CONNECTION). Kept here because these are this module's public surface. */
18
+ export { repoRequiredMessage, repoUnindexedMessage, getContextProfileInputSchema, recordDecisionInputSchema, setDecisionStatusInputSchema, reaffirmDecisionInputSchema, listDecisionsInputSchema, getDecisionInputSchema, createMcpServer, buildStore, WRITE_TOOLS, } from "./server/createMcpServer.js";
65
19
  const HELP_TEXT = `reposkein-mcp — deterministic code-graph MCP server
66
20
 
67
21
  Usage:
@@ -72,6 +26,7 @@ Usage:
72
26
  reposkein-mcp adr <sub> ... decision-log utilities
73
27
  reposkein-mcp stats [path] session usage report (calls, tokens saved vs grep)
74
28
  reposkein-mcp view [path] open the constellation viewer (--export <dir> for a static site)
29
+ reposkein-mcp serve --http ADVANCED, OPTIONAL: shared remote server — MCP over Streamable HTTP + the viewer/API in one process, bearer-token auth, read-only by default (see docs/REMOTE.md)
75
30
  reposkein-mcp --help show this help
76
31
  reposkein-mcp --version print the package version
77
32
 
@@ -85,360 +40,21 @@ Repo resolution (used by the server and by [path]-less CLI commands):
85
40
  naming the candidates — set REPOSKEIN_REPO_PATH (or pass a path) to pick one.
86
41
 
87
42
  Docs: https://github.com/reposkein/reposkein/tree/main/mcp#readme`;
88
- /** Structured, actionable message for repo-scoped tool calls when no repo
89
- * resolved (see `resolveRepoPath`). Names the discovered candidates when
90
- * resolution failed due to workspace-mode ambiguity, and points at
91
- * `list_repos` / `select_repo` so the agent can pick one instead of
92
- * abandoning the tools. */
93
- // Exported for the regression test below (repoRequiredMessage.test.ts) — it
94
- // must keep pointing agents at list_repos/select_repo, not just the env var.
95
- export function repoRequiredMessage(resolution) {
96
- if (resolution.candidates && resolution.candidates.length > 0) {
97
- return (`Multiple RepoSkein repos were found under ${process.cwd()} and none is selected: ` +
98
- resolution.candidates.join(", ") +
99
- ". Call list_repos to see them, then select_repo with one of its `path` or `name` " +
100
- "values (or set REPOSKEIN_REPO_PATH) to use this tool.");
101
- }
102
- return ("No RepoSkein repo found (checked the current directory, its ancestors, and its " +
103
- "immediate subdirectories for .reposkein/). Run `reposkein-mcp init` in the repository " +
104
- "you want to work with, call list_repos to check what was discovered, or set " +
105
- "REPOSKEIN_REPO_PATH to its root.");
106
- }
107
- // Exported for the regression test below (repoRequiredMessage.test.ts) — it
108
- // must name the found path and the fix (`reposkein-mcp index`), not repeat
109
- // the generic "no repo found" message: a repo WAS found here, it's just not
110
- // indexed yet (or, if `.reposkein/` isn't actually there, misconfigured).
111
- export function repoUnindexedMessage(repoPath) {
112
- if (existsSync(join(repoPath, ".reposkein"))) {
113
- return (`Found .reposkein/ at ${repoPath}, but it has no meta.json (not indexed yet). ` +
114
- `Run \`reposkein-mcp index ${repoPath}\` (or the init_cpg_skeleton tool) to build it, ` +
115
- "then retry this call.");
116
- }
117
- return (`${repoPath} has no .reposkein/ directory. Run \`reposkein-mcp init ${repoPath}\` there, ` +
118
- "or point REPOSKEIN_REPO_PATH / select_repo at a repo that already has one.");
119
- }
120
- // Exported for the regression test. `hops` MUST stay a bounded integer: a literal union
121
- // (z.union([z.literal(1), z.literal(2)])) serialises to JSON-Schema `anyOf:[{const:1},{const:2}]`,
122
- // which Gemini's tool-schema validator 400-rejects — and one bad tool declaration fails the
123
- // whole request, breaking every Gemini model whenever a reposkein tool is in the payload.
124
- export const getContextProfileInputSchema = {
125
- node_id: z.string().optional(),
126
- file_path: z.string().optional(),
127
- name: z.string().optional(),
128
- hops: z.number().int().min(1).max(2).optional(),
129
- federated: z.boolean().optional(),
130
- };
131
- // Exported for the schema regression test (no anyOf/oneOf — see the hops note
132
- // above; z.enum serialises to a plain `enum`, which every provider accepts).
133
- export const recordDecisionInputSchema = {
134
- title: z.string(),
135
- context: z.string(),
136
- decision: z.string(),
137
- consequences: z.string().optional(),
138
- alternatives: z.string().optional(),
139
- status: z.enum(["proposed", "accepted"]).optional(),
140
- anchor_node_ids: z.array(z.string()).max(20).optional(),
141
- anchor_paths: z.array(z.string()).max(20).optional(),
142
- supersedes: z.array(z.string()).max(5).optional(),
143
- };
144
- export const setDecisionStatusInputSchema = {
145
- decision_id: z.string(),
146
- status: z.enum(["accepted", "rejected", "deprecated"]),
147
- };
148
- export const reaffirmDecisionInputSchema = {
149
- decision_id: z.string(),
150
- };
151
- export const listDecisionsInputSchema = {
152
- status: z.enum(["proposed", "accepted", "rejected", "deprecated", "superseded"]).optional(),
153
- anchor: z.string().optional(),
154
- q: z.string().optional(),
155
- limit: z.number().int().min(1).max(50).optional(),
156
- };
157
- export const getDecisionInputSchema = {
158
- decision_id: z.string(),
159
- };
43
+ /** Starts the MCP server on the stdio transport the default and only
44
+ * transport for a single developer. One `createMcpServer` per process, with
45
+ * full write capability and the historical REPOSKEIN_AGENT identity
46
+ * fallback: unchanged by REP-17. */
160
47
  export async function main() {
161
- // Zero-config repo resolution: explicit arg (n/a here) > REPOSKEIN_REPO_PATH >
162
- // walk-up (nearest ancestor with .reposkein/) > walk-down (workspace mode).
163
- // See store/resolveRepoPath.ts for the full precedence + ambiguity rules.
164
- // Session-scoped resolution: `select_repo` (below) can override this for
165
- // the rest of the connection. Precedence: select_repo > REPOSKEIN_REPO_PATH
166
- // > walk-up > walk-down. See store/repoSession.ts.
167
- const session = new RepoSession({
48
+ const server = createMcpServer({
168
49
  cwd: process.cwd(),
169
50
  envRepoPath: process.env.REPOSKEIN_REPO_PATH,
170
51
  });
171
- // REP-20 session usage stats: one instrumentation point for every tool
172
- // call, wrapping the handler passed to `server.registerTool` below (each
173
- // call site does `withLog("tool_name", async (args) => {...})` — logging
174
- // logic itself lives only in instrumentTool.ts/sessionLog.ts, never in a
175
- // handler body). Session id = this process's lifetime (start-timestamp +
176
- // pid), overridable via REPOSKEIN_SESSION_ID for reproducible tests/tooling.
177
- // `cachedResolve` (used by `resolveActiveRepo` below, and by the two
178
- // handlers that gate on repoPath alone) memoizes `session.resolve()` per
179
- // call, so the handler's own resolution and the logger's are the same
180
- // filesystem walk, not two — see instrumentTool.ts for why and how.
181
- const sessionLogger = new SessionLogger(resolveSessionId(process.env));
182
- const { withLog, cachedResolve } = createToolLogger(session, sessionLogger);
183
- // Per-repoPath {repoId, store} cache. Constructing a JsonlGraphStore is
184
- // cheap (it lazily loads/re-parses its graph per call, keyed by file
185
- // mtime) but re-running resolveRepoId/ensureGraph/buildStore on every tool
186
- // call would still be wasted work for the common single-repo case, and
187
- // rebuilding the store object would also throw away that per-instance
188
- // mtime cache — so one context is built per repoPath and reused, letting
189
- // `select_repo` switch back and forth cheaply too.
190
- //
191
- // Only a SUCCESSFUL resolution (repoId defined) is cached — see
192
- // store/repoContextCache.ts. A repo whose `.reposkein/` exists but isn't
193
- // indexed yet (no meta.json) is a transient, fixable state: an agent might
194
- // run `reposkein-mcp index` (or init_cpg_skeleton) out-of-band and expect
195
- // the very next call in this same session to pick it up. Caching that
196
- // failure would freeze the session on a stale "not found" forever,
197
- // undercutting select_repo's whole no-restart-needed point.
198
- const getRepoContext = makeCache(async (path) => {
199
- const id = resolveRepoId(path, process.env.REPOSKEIN_REPO_ID);
200
- // Build the graph if the repo has none yet. Derived JSONL is
201
- // git-ignored, so a fresh clone arrives without it; without this the
202
- // first query on a newly selected repo would fail on one that indexes
203
- // fine in seconds.
204
- await ensureGraph(path, id, {
205
- mode: (process.env.REPOSKEIN_STORE ?? "auto").toLowerCase(),
206
- neo4jConfigured: !!process.env.NEO4J_PASSWORD,
207
- });
208
- return { repoId: id, store: buildStore(path, id) };
209
- }, (ctx) => !!ctx.repoId);
210
- /** Resolves the session's current repo for a repo-scoped tool call.
211
- * Re-evaluated on every call (not once at startup) so `select_repo`
212
- * actually takes effect for calls made after it. Uses `cachedResolve`
213
- * (not `session.resolve()` directly) so this and the REP-20 logging
214
- * wrapper share one filesystem walk per call. */
215
- async function resolveActiveRepo() {
216
- const resolution = cachedResolve();
217
- if (!resolution.repoPath)
218
- return { ok: false, message: repoRequiredMessage(resolution) };
219
- const ctx = await getRepoContext(resolution.repoPath);
220
- // Distinct from repoRequiredMessage: a repo path WAS resolved here — the
221
- // problem is it isn't indexed (or doesn't actually have .reposkein/),
222
- // not that none could be found at all. See repoUnindexedMessage.
223
- if (!ctx.repoId)
224
- return { ok: false, message: repoUnindexedMessage(resolution.repoPath) };
225
- return { ok: true, repoPath: resolution.repoPath, repoId: ctx.repoId, store: ctx.store };
226
- }
227
- const errResult = (message) => ({ content: [{ type: "text", text: message }], isError: true });
228
- const server = new McpServer({ name: "@reposkein/mcp", version: "0.0.0" });
229
- server.registerTool("list_repos", {
230
- title: "List discovered repos",
231
- description: "Enumerate the RepoSkein repos discovered from the server's working directory (walk-up: the nearest ancestor with .reposkein/; walk-down/workspace mode: subdirectories, when no ancestor has one). Single-repo setups return exactly one entry. In workspace mode (multiple sibling repos, no default selected), use this to see the candidates, then `select_repo` one before calling other repo-scoped tools.",
232
- inputSchema: {},
233
- }, withLog("list_repos", async () => {
234
- const repos = session.list();
235
- return {
236
- content: [
237
- {
238
- type: "text",
239
- text: JSON.stringify({
240
- mode: repos.length > 1 ? "workspace" : "single",
241
- repos,
242
- }),
243
- },
244
- ],
245
- };
246
- }));
247
- server.registerTool("select_repo", {
248
- title: "Select the active repo",
249
- description: "Set the session-active repo for all subsequent repo-scoped tool calls (get_context_profile, semantic_find, impact, decisions, etc.) — the fix for workspace-mode ambiguity (list_repos returned more than one candidate). Pass a `repo` value from list_repos: its `path` or its `name`. Overrides REPOSKEIN_REPO_PATH and any earlier select_repo call for the rest of this connection; stays in effect until called again.",
250
- inputSchema: { repo: z.string() },
251
- }, withLog("select_repo", async (args) => {
252
- const result = session.select(args.repo);
253
- if (!result.ok)
254
- return errResult(result.error);
255
- return { content: [{ type: "text", text: JSON.stringify({ ok: true, selected: result.repo }) }] };
256
- }));
257
- server.registerTool("read_cypher", {
258
- title: "Read-only Cypher query",
259
- description: "Run a read-only Cypher query against the RepoSkein graph. Writes are rejected. Filter by `n.repo_id = $repo_id` (or `n.repo_id IN $repo_ids`); pass `federated: true` to span this repo and its nested repos via `$repo_ids`. Results are capped (200 rows / 64KB).",
260
- inputSchema: {
261
- query: z.string(),
262
- params: z.record(z.string(), z.unknown()).optional(),
263
- federated: z.boolean().optional(),
264
- },
265
- }, withLog("read_cypher", async (args) => {
266
- // read_cypher tolerates an unresolved repo (falls back to whatever
267
- // buildStore(undefined, undefined) picks — Neo4j if configured, else
268
- // UnconfiguredStore — matching its pre-existing, non-gated behavior).
269
- const resolution = cachedResolve();
270
- const ctx = resolution.repoPath
271
- ? await getRepoContext(resolution.repoPath)
272
- : { repoId: undefined, store: buildStore(undefined, undefined) };
273
- return makeReadCypher(ctx.store, ctx.repoId)(args);
274
- }));
275
- server.registerTool("get_context_profile", {
276
- title: "Get context profile",
277
- description: "Resolve a function/class (by node_id, file_path+name, or name) and return its caller/callee neighborhood (hops 1-2) with inlined prose and an enrichment_needed list. Never guesses — returns candidates if a name is ambiguous. Pass federated:true to resolve and traverse across nested repos.",
278
- inputSchema: getContextProfileInputSchema,
279
- }, withLog("get_context_profile", async (args) => {
280
- const active = await resolveActiveRepo();
281
- if (!active.ok)
282
- return errResult(active.message);
283
- return makeGetContextProfile(active.store, active.repoId, active.repoPath)(args);
284
- }));
285
- server.registerTool("write_semantic_summary", {
286
- title: "Write semantic summary",
287
- description: "Attach a 1-3 sentence plain-text business-logic summary to a node, stamped with its current content hash for staleness tracking. Plain text only (no markdown links or code fences), max 1000 chars.",
288
- inputSchema: {
289
- node_id: z.string(),
290
- summary: z.string(),
291
- model: z.string().optional(),
292
- },
293
- }, withLog("write_semantic_summary", async (args) => {
294
- const active = await resolveActiveRepo();
295
- if (!active.ok)
296
- return errResult(active.message);
297
- return makeWriteSemanticSummary(active.store, active.repoId)(args);
298
- }));
299
- server.registerTool("init_cpg_skeleton", {
300
- title: "Build the code graph",
301
- description: "Index the repository with the native indexer and load it into the graph database. Run once on a fresh repo (or to rebuild). Returns node/edge counts.",
302
- inputSchema: {
303
- path: z.string().optional(),
304
- full: z.boolean().optional(),
305
- },
306
- }, withLog("init_cpg_skeleton", async (args) => {
307
- const active = await resolveActiveRepo();
308
- if (!active.ok)
309
- return errResult(active.message);
310
- // repoPath is threaded through explicitly (see indexerTools.ts) so this
311
- // always targets the resolved active repo, not a cwd/env-based guess —
312
- // an explicit args.path still wins inside makeInitCpgSkeleton itself.
313
- return makeInitCpgSkeleton(active.repoId, active.repoPath)(args);
314
- }));
315
- server.registerTool("reindex_file", {
316
- title: "Reindex after editing",
317
- description: "Refresh the graph after editing a source file (pass its path). v1 performs a full reindex.",
318
- inputSchema: { path: z.string() },
319
- }, withLog("reindex_file", async (args) => {
320
- const active = await resolveActiveRepo();
321
- if (!active.ok)
322
- return errResult(active.message);
323
- // repoPath threaded explicitly — reindex_file has no path override of
324
- // its own, so without this it would silently reindex whatever
325
- // REPOSKEIN_REPO_PATH/cwd points at instead of the selected repo.
326
- return makeReindexFile(active.repoId, active.repoPath)(args);
327
- }));
328
- server.registerTool("semantic_find", {
329
- title: "Find code by meaning",
330
- description: "Rank functions/classes by a lexical match over their qualified names, signatures, and agent-written summaries — the entry point to seed get_context_profile when you don't know where to start. Returns ranked node_ids. Architecture decisions are part of the corpus: \"why\" questions (why don't we X, what did we decide about Y) surface Decision rows — follow up with get_decision. federated:true spans nested repos.",
331
- inputSchema: {
332
- query: z.string(),
333
- limit: z.number().int().min(1).max(25).optional(),
334
- kind: z.enum(["Function", "Class", "Interface", "Enum", "Decision"]).optional(),
335
- federated: z.boolean().optional(),
336
- },
337
- }, withLog("semantic_find", async (args) => {
338
- const active = await resolveActiveRepo();
339
- if (!active.ok)
340
- return errResult(active.message);
341
- return makeSemanticFind(active.store, active.repoId, active.repoPath, undefined, { decisions: true })(args);
342
- }));
343
- server.registerTool("get_temporal_context", {
344
- title: "Git temporal context",
345
- description: "Git-derived signals for a file: how often/recently it changes, who owns it, and which files most often change together with it (co-change) — answers \"what else should I touch?\". Advisory (derived from git history, not the committed graph). Before a cross-cutting change, use this to find files that historically change together.",
346
- inputSchema: { path: z.string() },
347
- }, withLog("get_temporal_context", async (args) => {
348
- // Gated on repoPath only (not repoId/store) — it reads from .git directly.
349
- const resolution = cachedResolve();
350
- if (!resolution.repoPath)
351
- return errResult(repoRequiredMessage(resolution));
352
- return makeTemporalContext(resolution.repoPath)(args);
353
- }));
354
- server.registerTool("impact", {
355
- title: "Change impact + covering tests",
356
- description: "Given a function/class, return its transitive callers (what could break if you change it) split into impacted code vs the tests that cover it (what to run). Resolves by node_id, file_path+name, or name. federated:true spans nested repos.",
357
- inputSchema: {
358
- node_id: z.string().optional(),
359
- file_path: z.string().optional(),
360
- name: z.string().optional(),
361
- depth: z.number().int().min(1).max(5).optional(),
362
- federated: z.boolean().optional(),
363
- },
364
- }, withLog("impact", async (args) => {
365
- const active = await resolveActiveRepo();
366
- if (!active.ok)
367
- return errResult(active.message);
368
- return makeImpact(active.store, active.repoId, active.repoPath)(args);
369
- }));
370
- // Decision tools are gated on repoPath + repoId: records live as committed
371
- // files under <repoPath>/.reposkein/decisions/, the graph is used only for
372
- // anchor resolution and hash stamping (Phase 1 — no GraphStore changes).
373
- // `resolveActiveRepo` already requires both, so it doubles as the gate.
374
- server.registerTool("record_decision", {
375
- title: "Record an architecture decision",
376
- description: "Record an Architecture Decision Record (ADR): why a significant design choice was made, anchored to the graph nodes and paths it governs. Use for decisions that affect structure, dependencies, interfaces, or construction techniques — not renames, formatting, or routine fixes. Records land as status \"proposed\" (the user ratifies via set_decision_status); pass supersedes to replace an earlier decision. Plain text only; anchors are stamped with the current content hash for drift tracking.",
377
- inputSchema: recordDecisionInputSchema,
378
- }, withLog("record_decision", async (args) => {
379
- const active = await resolveActiveRepo();
380
- if (!active.ok)
381
- return errResult(active.message);
382
- // Best-effort reindex before stamping anchors so a decision recorded
383
- // right after an edit reflects the working tree, not the last index.
384
- const decisionRefresh = async () => {
385
- const bin = await ensureIndexerBinary();
386
- await spawnIndexer(bin, ["index", "--json", "--repo-id", active.repoId, active.repoPath]);
387
- };
388
- return makeRecordDecision(active.store, active.repoId, active.repoPath, { refresh: decisionRefresh })(args);
389
- }));
390
- server.registerTool("set_decision_status", {
391
- title: "Set decision status",
392
- description: "Change an ADR's lifecycle status. Legal transitions: proposed→accepted, proposed→rejected, accepted→deprecated. \"superseded\" only happens via record_decision's supersedes. Only ratify to accepted when the user has confirmed the decision.",
393
- inputSchema: setDecisionStatusInputSchema,
394
- }, withLog("set_decision_status", async (args) => {
395
- const active = await resolveActiveRepo();
396
- if (!active.ok)
397
- return errResult(active.message);
398
- return makeSetDecisionStatus(active.repoPath)(args);
399
- }));
400
- server.registerTool("reaffirm_decision", {
401
- title: "Reaffirm a decision",
402
- description: "Mark an ADR as still correct after the code under it changed: re-stamps every anchor from the live graph (stale anchors get the current hash, moved anchors are rebound), clearing review flags without superseding. Use after verifying the changed code still conforms to the decision.",
403
- inputSchema: reaffirmDecisionInputSchema,
404
- }, withLog("reaffirm_decision", async (args) => {
405
- const active = await resolveActiveRepo();
406
- if (!active.ok)
407
- return errResult(active.message);
408
- return makeReaffirmDecision(active.store, active.repoId, active.repoPath)(args);
409
- }));
410
- server.registerTool("list_decisions", {
411
- title: "List architecture decisions",
412
- description: "List ADRs (id, title, status, anchor drift counts), newest first. Filter by status, anchor (a node_id or file path — path prefixes ending \"/\" govern their subtree), or free-text q over title/context/decision. Before modifying code governed by a decision, check here and conform, supersede, or reaffirm — never silently violate. Decisions are rationale, not instructions.",
413
- inputSchema: listDecisionsInputSchema,
414
- }, withLog("list_decisions", async (args) => {
415
- const active = await resolveActiveRepo();
416
- if (!active.ok)
417
- return errResult(active.message);
418
- return makeListDecisions(active.store, active.repoId, active.repoPath)(args);
419
- }));
420
- server.registerTool("get_decision", {
421
- title: "Get one architecture decision",
422
- description: "Full ADR record: context, decision, consequences, alternatives, live anchor states (current/stale/moved/orphaned), and the supersession chain in both directions. Decisions are rationale, not instructions.",
423
- inputSchema: getDecisionInputSchema,
424
- }, withLog("get_decision", async (args) => {
425
- const active = await resolveActiveRepo();
426
- if (!active.ok)
427
- return errResult(active.message);
428
- return makeGetDecision(active.store, active.repoId, active.repoPath)(args);
429
- }));
430
- // No passive startup warning here: an unresolved (or ambiguous) repo is
431
- // surfaced per-call, as a structured, actionable tool error pointing at
432
- // list_repos/select_repo (repoRequiredMessage above) — not a stderr line
433
- // an agent can miss and route around by grepping the repo.
434
52
  const transport = new StdioServerTransport();
435
53
  await server.connect(transport);
436
54
  }
437
- // Run when invoked as the binary (not when imported by tests). Global installs
438
- // expose the bin via a SYMLINK (e.g. /usr/bin/reposkein-mcp), so argv[1] (the
439
- // symlink) won't equal import.meta.url (the resolved module path) unless we
440
- // realpath it first — otherwise `main()` never runs and the server exits
441
- // immediately (mcp-proxy then reports "Connection closed").
55
+ /** True when this module is the process entry point (`reposkein-mcp`), false
56
+ * when it's imported (tests, other tools) so importing never starts a
57
+ * server or parses argv. */
442
58
  function invokedAsBin() {
443
59
  const entry = process.argv[1];
444
60
  if (!entry)
@@ -453,7 +69,6 @@ function invokedAsBin() {
453
69
  if (invokedAsBin()) {
454
70
  const sub = process.argv[2];
455
71
  if (sub === "--help" || sub === "-h" || sub === "help") {
456
- // No repo resolution, no config warnings — just usage, per requirement #3.
457
72
  console.log(HELP_TEXT);
458
73
  process.exit(0);
459
74
  }
@@ -518,6 +133,27 @@ if (invokedAsBin()) {
518
133
  .then((code) => process.exit(code))
519
134
  .catch((err) => { console.error(err); process.exit(1); });
520
135
  }
136
+ else if (sub === "serve") {
137
+ // OPTIONAL remote mode (REP-17). `--http` is required and explicit: no
138
+ // subcommand of this CLI opens a socket by accident.
139
+ const { repoPath, opts, http } = parseServeArgs(process.argv.slice(3));
140
+ if (!http) {
141
+ console.error("reposkein serve: --http is required (it is the only transport this subcommand serves).\n" +
142
+ " Usage: reposkein-mcp serve --http [path] [--port N] [--host H] [--watch-interval SECONDS]\n" +
143
+ " This is an advanced, optional deployment — see docs/REMOTE.md. For normal use, run\n" +
144
+ " `reposkein-mcp` with no subcommand (stdio).");
145
+ process.exit(1);
146
+ }
147
+ const serveRepoId = resolveRepoId(repoPath, process.env.REPOSKEIN_REPO_ID);
148
+ if (!serveRepoId) {
149
+ console.error(`reposkein serve: could not resolve a repo id for ${repoPath} (no .reposkein/meta.json, no REPOSKEIN_REPO_ID).\n` +
150
+ " Run `reposkein-mcp init` there first.");
151
+ process.exit(1);
152
+ }
153
+ runServe(repoPath, serveRepoId, opts)
154
+ .then((code) => process.exit(code))
155
+ .catch((err) => { console.error(err); process.exit(1); });
156
+ }
521
157
  else {
522
158
  main().catch((err) => { console.error(err); process.exit(1); });
523
159
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /** True when an indexer run is in progress OR queued.
2
+ *
3
+ * Deliberately counts waiters, not just the active holder: the HEAD watcher
4
+ * uses this to SKIP a tick rather than queue behind a tool call, and a tick
5
+ * that queued would fire a redundant index the moment the tool's run
6
+ * finished — for a HEAD the tool's own run has by then already indexed. */
7
+ export declare function isIndexLockHeld(): boolean;
8
+ /** Runs `fn` with exclusive access to the indexer. */
9
+ export declare function withIndexLock<T>(fn: () => Promise<T>): Promise<T>;
10
+ /** Test-only: drains the queue so one suite's leftovers can't wedge the next.
11
+ * Never call this from production code — it does not cancel a running
12
+ * holder, it only waits for the queue to empty. */
13
+ export declare function drainIndexLock(): Promise<void>;
@@ -0,0 +1,66 @@
1
+ import { AsyncLocalStorage } from "node:async_hooks";
2
+ /** Process-wide mutual exclusion for indexer invocations.
3
+ *
4
+ * Every `reposkein-indexer` run writes into the served checkout's
5
+ * `.reposkein/` — `nodes.jsonl`, `edges.jsonl`, the committed summary shards,
6
+ * the pending-drift delta. Two runs at once on one checkout interleave those
7
+ * writes, and the loser's output is whatever the filesystem happened to
8
+ * order last. That was survivable while the server was one stdio process
9
+ * serving one agent: index runs were driven by one caller, one at a time.
10
+ *
11
+ * `serve --http` (REP-17) removes that accident. A write-capable tool call
12
+ * (`reindex_file`, `init_cpg_skeleton`, `record_decision`'s pre-stamp
13
+ * refresh) can now land while the HEAD watcher is mid-reindex, from a
14
+ * different connection, with no shared call stack to serialize them. So the
15
+ * serialization has to be explicit and it has to be somewhere no future
16
+ * caller can forget it — which is inside `spawnIndexer` itself, the single
17
+ * choke point every invocation passes through.
18
+ *
19
+ * Reentrancy-safe: a lock holder that (now or later) reaches `spawnIndexer`
20
+ * again runs straight through instead of deadlocking the process against
21
+ * itself. FIFO: waiters run in arrival order, so a queued tool call can't be
22
+ * starved by a fast-polling watcher. */
23
+ const reentrant = new AsyncLocalStorage();
24
+ /** Tail of the FIFO queue: resolves when every already-queued holder is done. */
25
+ let tail = Promise.resolve();
26
+ /** Holders plus waiters. Drives `isIndexLockHeld` (see its doc comment). */
27
+ let outstanding = 0;
28
+ /** True when an indexer run is in progress OR queued.
29
+ *
30
+ * Deliberately counts waiters, not just the active holder: the HEAD watcher
31
+ * uses this to SKIP a tick rather than queue behind a tool call, and a tick
32
+ * that queued would fire a redundant index the moment the tool's run
33
+ * finished — for a HEAD the tool's own run has by then already indexed. */
34
+ export function isIndexLockHeld() {
35
+ return outstanding > 0;
36
+ }
37
+ /** Runs `fn` with exclusive access to the indexer. */
38
+ export async function withIndexLock(fn) {
39
+ // Already ours (a nested spawn inside a lock-holding operation): proceed.
40
+ if (reentrant.getStore())
41
+ return fn();
42
+ outstanding++;
43
+ let release;
44
+ const mine = new Promise((r) => {
45
+ release = r;
46
+ });
47
+ const prior = tail;
48
+ // A rejection can't come from `mine` (release never throws), but chain
49
+ // defensively: a broken tail would wedge every future acquisition.
50
+ tail = prior.then(() => mine).catch(() => undefined);
51
+ try {
52
+ await prior;
53
+ return await reentrant.run(true, fn);
54
+ }
55
+ finally {
56
+ outstanding--;
57
+ release();
58
+ }
59
+ }
60
+ /** Test-only: drains the queue so one suite's leftovers can't wedge the next.
61
+ * Never call this from production code — it does not cancel a running
62
+ * holder, it only waits for the queue to empty. */
63
+ export async function drainIndexLock() {
64
+ await tail;
65
+ }
66
+ //# sourceMappingURL=indexLock.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"indexLock.js","sourceRoot":"","sources":["../../src/indexer/indexLock.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAErD;;;;;;;;;;;;;;;;;;;;yCAoByC;AAEzC,MAAM,SAAS,GAAG,IAAI,iBAAiB,EAAQ,CAAC;AAEhD,iFAAiF;AACjF,IAAI,IAAI,GAAkB,OAAO,CAAC,OAAO,EAAE,CAAC;AAC5C,4EAA4E;AAC5E,IAAI,WAAW,GAAG,CAAC,CAAC;AAEpB;;;;;4EAK4E;AAC5E,MAAM,UAAU,eAAe;IAC7B,OAAO,WAAW,GAAG,CAAC,CAAC;AACzB,CAAC;AAED,sDAAsD;AACtD,MAAM,CAAC,KAAK,UAAU,aAAa,CAAI,EAAoB;IACzD,0EAA0E;IAC1E,IAAI,SAAS,CAAC,QAAQ,EAAE;QAAE,OAAO,EAAE,EAAE,CAAC;IAEtC,WAAW,EAAE,CAAC;IACd,IAAI,OAAoB,CAAC;IACzB,MAAM,IAAI,GAAG,IAAI,OAAO,CAAO,CAAC,CAAC,EAAE,EAAE;QACnC,OAAO,GAAG,CAAC,CAAC;IACd,CAAC,CAAC,CAAC;IACH,MAAM,KAAK,GAAG,IAAI,CAAC;IACnB,uEAAuE;IACvE,mEAAmE;IACnE,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;IACrD,IAAI,CAAC;QACH,MAAM,KAAK,CAAC;QACZ,OAAO,MAAM,SAAS,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IACvC,CAAC;YAAS,CAAC;QACT,WAAW,EAAE,CAAC;QACd,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED;;oDAEoD;AACpD,MAAM,CAAC,KAAK,UAAU,cAAc;IAClC,MAAM,IAAI,CAAC;AACb,CAAC"}