@swarmvaultai/engine 3.16.1 → 3.17.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 (139) hide show
  1. package/dist/chunk-2CH2WWS4.js +1359 -0
  2. package/dist/chunk-2PN46RDI.js +26846 -0
  3. package/dist/chunk-333AMRSV.js +1056 -0
  4. package/dist/chunk-3GVEUYQZ.js +1641 -0
  5. package/dist/chunk-4MSSM2GH.js +1476 -0
  6. package/dist/chunk-563TZ4TZ.js +26573 -0
  7. package/dist/chunk-5GEPTIZE.js +26010 -0
  8. package/dist/chunk-5HNZ2WQI.js +1341 -0
  9. package/dist/chunk-5Q4IV4O3.js +1336 -0
  10. package/dist/chunk-65IRGGXX.js +27576 -0
  11. package/dist/chunk-6MO57J5C.js +988 -0
  12. package/dist/chunk-6UPHDGEB.js +1073 -0
  13. package/dist/chunk-75BU5TQ6.js +1690 -0
  14. package/dist/chunk-7O2HJSWQ.js +1686 -0
  15. package/dist/chunk-7QHDATCQ.js +1673 -0
  16. package/dist/chunk-B3FC4J3P.js +1214 -0
  17. package/dist/chunk-BTWPJEP2.js +1421 -0
  18. package/dist/chunk-CG67P2HB.js +1420 -0
  19. package/dist/chunk-CSPDMCON.js +26846 -0
  20. package/dist/chunk-CVFY54CF.js +24893 -0
  21. package/dist/chunk-CWLDFLH2.js +1163 -0
  22. package/dist/chunk-DAJAZPPO.js +26865 -0
  23. package/dist/chunk-EEWB4WGH.js +1056 -0
  24. package/dist/chunk-EXD4RWT3.js +1131 -0
  25. package/dist/chunk-F7HZZ3VM.js +931 -0
  26. package/dist/chunk-FD3LJQ4T.js +1216 -0
  27. package/dist/chunk-G2TH6ZTA.js +1468 -0
  28. package/dist/chunk-H3CDZYRE.js +1701 -0
  29. package/dist/chunk-HFU5S5NO.js +838 -0
  30. package/dist/chunk-HKU2T5JX.js +25213 -0
  31. package/dist/chunk-HOJ7NSYC.js +937 -0
  32. package/dist/chunk-HORJDLXV.js +27614 -0
  33. package/dist/chunk-HRRPWXRZ.js +1335 -0
  34. package/dist/chunk-HW72C7O2.js +1690 -0
  35. package/dist/chunk-IAEYFTUS.js +1159 -0
  36. package/dist/chunk-IHMJCCXR.js +1146 -0
  37. package/dist/chunk-JEWLYIHN.js +27619 -0
  38. package/dist/chunk-JJDJF2P3.js +27012 -0
  39. package/dist/chunk-JTRE7C7P.js +26062 -0
  40. package/dist/chunk-L7DKPPV4.js +27339 -0
  41. package/dist/chunk-LEUV6TWJ.js +1131 -0
  42. package/dist/chunk-MB7HPUTR.js +1364 -0
  43. package/dist/chunk-MZSUYTSL.js +998 -0
  44. package/dist/chunk-N56FAH4N.js +1404 -0
  45. package/dist/chunk-NCSZ4AKP.js +1057 -0
  46. package/dist/chunk-NECZ4MUE.js +1416 -0
  47. package/dist/chunk-NHGS4LOI.js +1346 -0
  48. package/dist/chunk-NUWZUYE7.js +1701 -0
  49. package/dist/chunk-OK5752AP.js +1325 -0
  50. package/dist/chunk-QMW7OISM.js +1063 -0
  51. package/dist/chunk-RN56HUXA.js +26972 -0
  52. package/dist/chunk-RSQRF4FV.js +1424 -0
  53. package/dist/chunk-S2E65WRI.js +26062 -0
  54. package/dist/chunk-SRHM3HP4.js +944 -0
  55. package/dist/chunk-U7JO257M.js +25017 -0
  56. package/dist/chunk-UQCF65BN.js +1623 -0
  57. package/dist/chunk-USSP4GVB.js +25064 -0
  58. package/dist/chunk-V7KX3AQD.js +26010 -0
  59. package/dist/chunk-VSDBQVSE.js +27584 -0
  60. package/dist/chunk-WOA5LSNB.js +26559 -0
  61. package/dist/chunk-WWP3VPEJ.js +26080 -0
  62. package/dist/chunk-YFKWMXJ6.js +26066 -0
  63. package/dist/chunk-Z552HHPV.js +26846 -0
  64. package/dist/chunk-ZQ5T64AR.js +1365 -0
  65. package/dist/hooks/claude.js +236 -19
  66. package/dist/hooks/codex.js +134 -6
  67. package/dist/hooks/copilot.js +95 -3
  68. package/dist/hooks/gemini.js +153 -5
  69. package/dist/hooks/opencode.js +4 -2
  70. package/dist/index.d.ts +19 -1
  71. package/dist/index.js +237 -3
  72. package/dist/memory-A4VPLUBA.js +32 -0
  73. package/dist/memory-DNSQCDHC.js +32 -0
  74. package/dist/memory-ECS3TSGC.js +32 -0
  75. package/dist/memory-FVIBFROA.js +32 -0
  76. package/dist/memory-G6I3DBW4.js +32 -0
  77. package/dist/memory-GFOW2QWQ.js +32 -0
  78. package/dist/memory-GSCQ6F53.js +32 -0
  79. package/dist/memory-HE6VWUPV.js +32 -0
  80. package/dist/memory-HEA7XNKB.js +32 -0
  81. package/dist/memory-HMP3Y4PQ.js +32 -0
  82. package/dist/memory-JRYTVHNH.js +32 -0
  83. package/dist/memory-K3NL5E3K.js +32 -0
  84. package/dist/memory-KANI73CX.js +32 -0
  85. package/dist/memory-KI5G2A4C.js +32 -0
  86. package/dist/memory-PK55JUKG.js +32 -0
  87. package/dist/memory-PK5JJNAG.js +32 -0
  88. package/dist/memory-PQWSJ4RR.js +32 -0
  89. package/dist/memory-QCVKS3H4.js +32 -0
  90. package/dist/memory-SAQPBIB4.js +32 -0
  91. package/dist/memory-SVGRP5KS.js +32 -0
  92. package/dist/memory-TQ46BGCI.js +32 -0
  93. package/dist/memory-YKQWWIVY.js +32 -0
  94. package/dist/memory-Z7BP5OSC.js +32 -0
  95. package/dist/registry-2QC3VN7M.js +12 -0
  96. package/dist/registry-2REAPKPO.js +12 -0
  97. package/dist/registry-2XHXZDGH.js +12 -0
  98. package/dist/registry-4C55ZCPL.js +12 -0
  99. package/dist/registry-4QRMVAHX.js +12 -0
  100. package/dist/registry-5SYH3Y3U.js +12 -0
  101. package/dist/registry-6KZMA3XM.js +12 -0
  102. package/dist/registry-7QACDJQQ.js +12 -0
  103. package/dist/registry-B7UXRBW3.js +12 -0
  104. package/dist/registry-FKEREVDO.js +12 -0
  105. package/dist/registry-FLSGGY2R.js +12 -0
  106. package/dist/registry-G7NSRYCO.js +12 -0
  107. package/dist/registry-GH4O3A7H.js +12 -0
  108. package/dist/registry-IBH6K2KK.js +12 -0
  109. package/dist/registry-ILDEBNCW.js +12 -0
  110. package/dist/registry-JFEW5RUP.js +12 -0
  111. package/dist/registry-JQYQOZYN.js +12 -0
  112. package/dist/registry-JR5WY22P.js +12 -0
  113. package/dist/registry-KLO5YIHP.js +12 -0
  114. package/dist/registry-KVJAO5DF.js +12 -0
  115. package/dist/registry-MYJX6AEE.js +12 -0
  116. package/dist/registry-NBLIJHZT.js +12 -0
  117. package/dist/registry-NLRWSN5J.js +12 -0
  118. package/dist/registry-NMXDBYIZ.js +12 -0
  119. package/dist/registry-OUB6W3LM.js +12 -0
  120. package/dist/registry-P5KRT66L.js +12 -0
  121. package/dist/registry-PGZWRXMD.js +12 -0
  122. package/dist/registry-QAG2ZYH3.js +12 -0
  123. package/dist/registry-SUXWCWB4.js +12 -0
  124. package/dist/registry-SYCRRA65.js +12 -0
  125. package/dist/registry-TYROWPR5.js +12 -0
  126. package/dist/registry-U23ML76I.js +12 -0
  127. package/dist/registry-U76DBOV3.js +12 -0
  128. package/dist/registry-UA42LQUQ.js +12 -0
  129. package/dist/registry-W6ZFRI73.js +12 -0
  130. package/dist/registry-X5PMZTZY.js +12 -0
  131. package/dist/registry-XIL5F33J.js +12 -0
  132. package/dist/registry-XOPLQNZY.js +12 -0
  133. package/dist/registry-YDXVCE4Q.js +12 -0
  134. package/dist/registry-YGVTLIZH.js +12 -0
  135. package/dist/registry-ZNW3FDED.js +12 -0
  136. package/dist/viewer/assets/{index-Cq5HAlrV.js → index-BZE-2FtS.js} +37 -37
  137. package/dist/viewer/index.html +1 -1
  138. package/dist/viewer/lib.js +29 -1
  139. package/package.json +1 -1
@@ -57,6 +57,10 @@ function resolveToolName(input) {
57
57
  const shaped = input ?? {};
58
58
  return String(shaped.toolName ?? shaped.tool_name ?? shaped.tool?.name ?? shaped.name ?? "");
59
59
  }
60
+ function resolveToolInput(input) {
61
+ const shaped = input ?? {};
62
+ return shaped.toolInput ?? shaped.tool_input ?? {};
63
+ }
60
64
  async function hasReport(cwd) {
61
65
  try {
62
66
  await fs.access(reportPath(cwd));
@@ -96,6 +100,102 @@ async function resetSession(cwd, agentKey) {
96
100
  function isBroadSearchTool(toolName) {
97
101
  return /grep|glob|search|find/i.test(toolName);
98
102
  }
103
+ function collectCommandCandidates(node, acc = []) {
104
+ if (!node || typeof node !== "object") {
105
+ return acc;
106
+ }
107
+ if (Array.isArray(node)) {
108
+ for (const item of node) {
109
+ collectCommandCandidates(item, acc);
110
+ }
111
+ return acc;
112
+ }
113
+ for (const [key, value] of Object.entries(node)) {
114
+ if (["command", "cmd", "script", "bash", "shell"].includes(key) && typeof value === "string") {
115
+ acc.push(value);
116
+ continue;
117
+ }
118
+ collectCommandCandidates(value, acc);
119
+ }
120
+ return acc;
121
+ }
122
+ var VAULT_ARTIFACT_SEGMENTS = ["wiki", "raw", "state", "agent", "inbox"];
123
+ function isVaultArtifactSearch(input, cwd) {
124
+ const artifactRoot = artifactRootDir(cwd);
125
+ const candidates = [...collectCandidatePaths(input), ...collectCommandCandidates(input)];
126
+ return candidates.some((candidate) => {
127
+ if (typeof candidate !== "string" || candidate.length === 0) {
128
+ return false;
129
+ }
130
+ const normalized = candidate.replaceAll("\\", "/");
131
+ if (VAULT_ARTIFACT_SEGMENTS.some(
132
+ (segment) => normalized.includes(`${segment}/`) && normalized.match(new RegExp(`(^|[\\s'"=/])${segment}/`))
133
+ )) {
134
+ return true;
135
+ }
136
+ const resolved = path.resolve(cwd, candidate);
137
+ return VAULT_ARTIFACT_SEGMENTS.some(
138
+ (segment) => resolved.startsWith(path.join(artifactRoot, segment) + path.sep) || resolved === path.join(artifactRoot, segment)
139
+ );
140
+ });
141
+ }
142
+ async function isNarrowSearch(input) {
143
+ const toolInput = resolveToolInput(input);
144
+ const candidate = toolInput?.path;
145
+ if (typeof candidate !== "string" || candidate.length === 0) {
146
+ return false;
147
+ }
148
+ try {
149
+ const stats = await fs.stat(candidate);
150
+ return stats.isFile();
151
+ } catch {
152
+ return false;
153
+ }
154
+ }
155
+ async function resolveGraphFirstMode(cwd) {
156
+ const fromEnv = process.env.SWARMVAULT_GRAPH_FIRST?.trim().toLowerCase();
157
+ if (fromEnv === "deny" || fromEnv === "context" || fromEnv === "off") {
158
+ return fromEnv;
159
+ }
160
+ try {
161
+ const raw = await fs.readFile(path.join(cwd, "swarmvault.config.json"), "utf8");
162
+ const parsed = JSON.parse(raw);
163
+ const fromConfig = typeof parsed?.hooks?.graphFirst === "string" ? parsed.hooks.graphFirst.toLowerCase() : "";
164
+ if (fromConfig === "deny" || fromConfig === "context" || fromConfig === "off") {
165
+ return fromConfig;
166
+ }
167
+ } catch {
168
+ }
169
+ return "deny";
170
+ }
171
+ async function readWatchStaleness(cwd) {
172
+ const watchDir = path.join(artifactRootDir(cwd), "state", "watch");
173
+ let lastRunAt;
174
+ let lastRunSuccess;
175
+ let pendingCount = 0;
176
+ let found = false;
177
+ try {
178
+ const raw = await fs.readFile(path.join(watchDir, "status.json"), "utf8");
179
+ const parsed = JSON.parse(raw);
180
+ lastRunAt = typeof parsed?.lastRun?.finishedAt === "string" ? parsed.lastRun.finishedAt : void 0;
181
+ lastRunSuccess = typeof parsed?.lastRun?.success === "boolean" ? parsed.lastRun.success : void 0;
182
+ found = true;
183
+ } catch {
184
+ }
185
+ try {
186
+ const raw = await fs.readFile(path.join(watchDir, "pending-semantic-refresh.json"), "utf8");
187
+ const parsed = JSON.parse(raw);
188
+ if (Array.isArray(parsed)) {
189
+ pendingCount = parsed.length;
190
+ found = true;
191
+ }
192
+ } catch {
193
+ }
194
+ if (!found) {
195
+ return null;
196
+ }
197
+ return { lastRunAt, lastRunSuccess, pendingSemanticRefreshCount: pendingCount };
198
+ }
99
199
  async function readHookInput() {
100
200
  let body = "";
101
201
  for await (const chunk of process.stdin) {
@@ -110,7 +210,52 @@ async function readHookInput() {
110
210
  return {};
111
211
  }
112
212
  }
113
- var REPORT_NOTE = "SwarmVault graph report exists at wiki/graph/report.md, or at $SWARMVAULT_OUT/wiki/graph/report.md when SWARMVAULT_OUT is set. Read it before broad grep/glob searching.";
213
+ var GRAPH_FIRST_COMMANDS = [
214
+ '- `swarmvault graph query "<seed>"` \u2014 top matches with page paths plus an inline excerpt of the best page; usually answers where-is/what-calls in one command',
215
+ '- `swarmvault graph explain "<node>"` \u2014 compact node summary with neighbors and its wiki page',
216
+ "- `swarmvault graph blast <target>` \u2014 reverse-import impact analysis for change-impact questions",
217
+ "- `wiki/graph/report.md` \u2014 orientation report (architecture, communities, key nodes)",
218
+ "Do not add `--json` to these \u2014 the plain output is far smaller and already structured.",
219
+ "Trust the graph/wiki answer for orientation questions; verify in source only when you are about to edit or the evidence conflicts. Answer directly in chat \u2014 do not write answer files unless asked for a durable artifact."
220
+ ];
221
+ function buildGraphFirstNote(staleness) {
222
+ const lines = [
223
+ "This repo has a SwarmVault code graph. To save tokens, answer code-understanding questions (where is X, what calls Y, how is Z structured, impact of changing W) from the graph instead of reading or grepping source files:",
224
+ ...GRAPH_FIRST_COMMANDS,
225
+ "Read source files directly only when you are about to edit them, or when the graph lacks the detail you need.",
226
+ "After your edits the SwarmVault hook refreshes the graph automatically."
227
+ ];
228
+ if (staleness?.pendingSemanticRefreshCount) {
229
+ lines.push(
230
+ `Note: ${staleness.pendingSemanticRefreshCount} non-code change(s) await semantic refresh \u2014 run \`swarmvault compile\` when convenient.`
231
+ );
232
+ }
233
+ if (staleness?.lastRunSuccess === false) {
234
+ lines.push(
235
+ "Note: the last graph refresh failed \u2014 run `swarmvault graph status` then `swarmvault graph update` before relying on the graph."
236
+ );
237
+ }
238
+ return lines.join("\n");
239
+ }
240
+ function extractSearchTerm(input) {
241
+ const toolInput = resolveToolInput(input);
242
+ for (const key of ["pattern", "query", "regex"]) {
243
+ const value = toolInput?.[key];
244
+ if (typeof value === "string" && value.length > 0) {
245
+ return value;
246
+ }
247
+ }
248
+ return "<your term>";
249
+ }
250
+ function buildDenyReason(toolName, input) {
251
+ const term = extractSearchTerm(input).slice(0, 120);
252
+ return [
253
+ `SwarmVault graph-first: this repo has a compiled code graph that answers structure questions in far fewer tokens than ${toolName || "broad search"}.`,
254
+ `Run: swarmvault graph query "${term}" \u2014 it prints the top matches with page paths plus an inline excerpt of the best page, which usually answers the question without reading source. Add --context calls for caller/impact questions. Do not add --json (much larger output).`,
255
+ "Trust that answer for orientation questions instead of re-verifying in source files.",
256
+ "If the graph does not answer, repeat this exact search \u2014 it will be allowed for the rest of the session."
257
+ ].join(" ");
258
+ }
114
259
 
115
260
  // src/hooks/gemini.ts
116
261
  var AGENT_KEY = "gemini";
@@ -128,11 +273,12 @@ async function main() {
128
273
  }
129
274
  if (mode === "session-start") {
130
275
  await resetSession(cwd, AGENT_KEY);
276
+ const graphFirstNote = buildGraphFirstNote(await readWatchStaleness(cwd));
131
277
  emit({
132
- systemMessage: REPORT_NOTE,
278
+ systemMessage: graphFirstNote,
133
279
  hookSpecificOutput: {
134
280
  hookEventName: "SessionStart",
135
- additionalContext: "SwarmVault graph report: wiki/graph/report.md"
281
+ additionalContext: graphFirstNote
136
282
  }
137
283
  });
138
284
  process.exit(0);
@@ -143,8 +289,10 @@ async function main() {
143
289
  emit({});
144
290
  process.exit(0);
145
291
  }
146
- if (isBroadSearchTool(toolName) && !await hasSeenReport(cwd, AGENT_KEY)) {
147
- emit({ systemMessage: REPORT_NOTE });
292
+ const graphFirstMode = await resolveGraphFirstMode(cwd);
293
+ if (graphFirstMode !== "off" && isBroadSearchTool(toolName) && !isVaultArtifactSearch(input, cwd) && !await isNarrowSearch(input) && !await hasSeenReport(cwd, AGENT_KEY)) {
294
+ await markReportRead(cwd, AGENT_KEY);
295
+ emit({ systemMessage: buildDenyReason(toolName, input) });
148
296
  process.exit(0);
149
297
  }
150
298
  emit({});
@@ -20,12 +20,13 @@ async function swarmvaultGraphFirst({ client }) {
20
20
  });
21
21
  }
22
22
  }
23
+ const graphFirstNote = "SwarmVault graph-first: this repo has a compiled code graph. Answer structure questions (where is X, what calls Y) with `swarmvault graph query|explain|path --json`, `swarmvault query`, or wiki/graph/report.md instead of broad grep/glob. Read source files only when editing them or when the graph lacks detail.";
23
24
  return {
24
25
  async "session.created"(input) {
25
26
  reportSeen = false;
26
27
  const cwd = input?.session?.cwd ?? process.cwd();
27
28
  if (await hasReport(cwd)) {
28
- await note("SwarmVault graph report exists. Read wiki/graph/report.md before broad workspace searching.");
29
+ await note(graphFirstNote);
29
30
  }
30
31
  },
31
32
  async "tool.execute.before"(input) {
@@ -39,7 +40,8 @@ async function swarmvaultGraphFirst({ client }) {
39
40
  return;
40
41
  }
41
42
  if (!reportSeen && ["glob", "grep"].includes(String(input?.tool ?? ""))) {
42
- await note("SwarmVault graph report exists. Read wiki/graph/report.md before broad workspace searching.");
43
+ reportSeen = true;
44
+ await note(graphFirstNote);
43
45
  }
44
46
  }
45
47
  };
package/dist/index.d.ts CHANGED
@@ -1007,6 +1007,8 @@ interface GraphQueryResult {
1007
1007
  communities: string[];
1008
1008
  summary: string;
1009
1009
  matches: GraphQueryMatch[];
1010
+ /** Wiki-relative page path for the top match, when one resolves. */
1011
+ topMatchPagePath?: string;
1010
1012
  filters?: GraphQueryFilters;
1011
1013
  filterStats?: GraphQueryFilterStats;
1012
1014
  }
@@ -1597,6 +1599,12 @@ interface WatchOptions {
1597
1599
  overrideRoots?: string[];
1598
1600
  force?: boolean;
1599
1601
  maxGraphShrinkRatio?: number;
1602
+ /**
1603
+ * Explicit file fast path: refresh only these files (code-only) instead of
1604
+ * walking every tracked repo root. Used by agent post-edit hooks and
1605
+ * `swarmvault graph update --file <path>`.
1606
+ */
1607
+ files?: string[];
1600
1608
  }
1601
1609
  interface GraphShrinkDimension {
1602
1610
  before: number;
@@ -1686,6 +1694,8 @@ interface WatchController {
1686
1694
  interface InstallAgentOptions {
1687
1695
  hook?: boolean;
1688
1696
  scope?: "project" | "user";
1697
+ /** Register the SwarmVault MCP server in the agent's project MCP config. */
1698
+ mcp?: boolean;
1689
1699
  }
1690
1700
  interface InstallAgentResult {
1691
1701
  agent: AgentType;
@@ -2702,6 +2712,12 @@ declare function listTrackedRepoRoots(rootDir: string): Promise<string[]>;
2702
2712
  declare function checkTrackedRepoChanges(rootDir: string, repoRoots?: string[]): Promise<GraphStatusChange[]>;
2703
2713
  declare function syncTrackedRepos(rootDir: string, options?: IngestOptions, repoRoots?: string[]): Promise<RepoSyncResult>;
2704
2714
  declare function syncTrackedReposForWatch(rootDir: string, options?: IngestOptions, repoRoots?: string[]): Promise<WatchRepoSyncResult>;
2715
+ /**
2716
+ * Per-file variant of `syncTrackedReposForWatch`: refreshes only the given
2717
+ * files instead of walking every tracked repo root. Powers
2718
+ * `swarmvault graph update --file <path>` (the agent post-edit fast path).
2719
+ */
2720
+ declare function syncTrackedFiles(rootDir: string, filePaths: string[], options?: IngestOptions): Promise<WatchRepoSyncResult>;
2705
2721
  declare function ingestInputDetailed(rootDir: string, input: string, options?: IngestOptions): Promise<InputIngestResult>;
2706
2722
  declare function ingestInput(rootDir: string, input: string, options?: IngestOptions): Promise<SourceManifest>;
2707
2723
  declare function addInput(rootDir: string, input: string, options?: AddOptions): Promise<AddResult>;
@@ -3301,6 +3317,8 @@ type WatchCycleResult = {
3301
3317
  pendingSemanticRefreshPaths: string[];
3302
3318
  changedPages: string[];
3303
3319
  lintFindingCount?: number;
3320
+ /** Files deferred to the next refresh because another refresh held the lock. */
3321
+ queuedFiles?: string[];
3304
3322
  };
3305
3323
  /**
3306
3324
  * Compute the effective list of repository roots that `swarmvault watch --repo` should track.
@@ -3339,4 +3357,4 @@ declare function createWebSearchAdapter(id: string, config: WebSearchProviderCon
3339
3357
  type WebSearchTaskId = "deepLintProvider" | "queryProvider" | "exploreProvider";
3340
3358
  declare function getWebSearchAdapterForTask(rootDir: string, task: WebSearchTaskId): Promise<WebSearchAdapter>;
3341
3359
 
3342
- export { ALL_MIGRATIONS, type AddOptions, type AddResult, type AgentInstallStatus, type AgentInstallTargetStatus, type AgentMemoryDecision, type AgentMemoryNote, type AgentMemoryResumeFormat, type AgentMemoryTask, type AgentMemoryTaskResult, type AgentMemoryTaskStatus, type AgentMemoryTaskSummary, type AgentType, type AiExportFile, type AiExportOptions, type AiExportResult, type AnalyzedTerm, type ApprovalBundleType, type ApprovalChangeType, type ApprovalDetail, type ApprovalDiffHunk, type ApprovalDiffLine, type ApprovalEntry, type ApprovalEntryDetail, type ApprovalEntryLabel, type ApprovalEntryStatus, type ApprovalFrontmatterChange, type ApprovalManifest, type ApprovalStructuredDiff, type ApprovalSummary, type AskChatOptions, type AskChatResult, type AudioTranscriptionRequest, type AudioTranscriptionResponse, type BenchmarkArtifact, type BenchmarkByClassEntry, type BenchmarkOptions, type BenchmarkQuestionResult, type BenchmarkSummary, type BlastRadiusResult, type BuildContextPackOptions, type BuildContextPackResult, type CandidatePromotionConfig, type CandidateRecord, type ChartDatum, type ChartSpec, type ClaimStatus, type CodeAnalysis, type CodeDiagnostic, type CodeImport, type CodeIndexArtifact, type CodeIndexEntry, type CodeLanguage, type CodeRelation, type CodeSymbol, type CodeSymbolKind, type CommandRoleExecutorConfig, type CompileOptions, type CompileResult, type CompileState, type ConsolidationConfig, type ConsolidationPromotion, type ConsolidationResult, type ContextPack, type ContextPackFormat, type ContextPackItem, type ContextPackItemKind, type ContextPackOmittedItem, type ContextPackSummary, DEFAULT_CONSOLIDATION_CONFIG, DEFAULT_HALF_LIFE_DAYS, DEFAULT_HALF_LIFE_DAYS_BY_SOURCE_CLASS, DEFAULT_PROMOTION_CONFIG, DEFAULT_REDACTION_PATTERNS, DEFAULT_STALE_THRESHOLD, type DegradationOutcome, type DirectoryIngestFailure, type DirectoryIngestResult, type DirectoryIngestSkip, type EmbeddingCacheArtifact, type EmbeddingCacheEntry, type EvidenceClass, type ExploreOptions, type ExploreResult, type ExploreStepResult, type ExtractionClaim, type ExtractionKind, type ExtractionTerm, type FinishMemoryTaskOptions, type Freshness, type FreshnessConfig, type GenerationAttachment, type GenerationRequest, type GenerationResponse, type GitHookStatus, type GraphArtifact, type GraphClusterRefreshResult, type GraphCommunityResult, type GraphCycle, type GraphCycleResult, type GraphDiffResult, type GraphEdge, type GraphExplainNeighbor, type GraphExplainResult, type GraphExportFormat, type GraphExportResult, type GraphHyperedge, type GraphNode, type GraphPage, type GraphPathResult, type GraphPushCounts, type GraphPushNeo4jOptions, type GraphPushResult, type GraphQueryFilterStats, type GraphQueryFilters, type GraphQueryMatch, type GraphQueryRelationGroup, type GraphQueryResult, type GraphReportArtifact, type GraphShareArtifact, type GraphShareBundleFile, type GraphShrinkDimension, type GraphShrinkGuardResult, type GraphStatsResult, type GraphStatusChange, type GraphStatusResult, type GraphValidationIssue, type GraphValidationResult, type GraphValidationSeverity, type GuidedSessionMode, type GuidedSourceSessionAnswers, type GuidedSourceSessionQuestion, type GuidedSourceSessionRecord, type GuidedSourceSessionStatus, type ImageGenerationRequest, type ImageGenerationResponse, type ImageVisionExtraction, type InboxImportResult, type InboxImportSkip, type IngestOptions, type InitOptions, type InputIngestResult, type InstallAgentOptions, type InstallAgentResult, LARGE_REPO_NODE_THRESHOLD, LOCAL_WHISPER_MODEL_SIZES, type LintFinding, type LintOptions, type LocalWhisperAdapterOptions, type LocalWhisperBinaryDiscovery, LocalWhisperProviderAdapter, type LocalWhisperSetupStatus, type ManagedSourceAddOptions, type ManagedSourceAddResult, type ManagedSourceDeleteResult, type ManagedSourceKind, type ManagedSourceRecord, type ManagedSourceReloadOptions, type ManagedSourceReloadResult, type ManagedSourceStatus, type ManagedSourceSyncCounts, type ManagedSourcesArtifact, type MemoryTier, type MigrationPlan, type MigrationResult, type MigrationStep, type Neo4jGraphSinkConfig, OPENAI_COMPATIBLE_CAPABILITY_MATRIX, type OpenAiCompatiblePresetId, type OrchestrationConfig, type OrchestrationFinding, type OrchestrationProposal, type OrchestrationRole, type OrchestrationRoleConfig, type OrchestrationRoleResult, type OutputAsset, type OutputAssetRole, type OutputFormat, type OutputOrigin, type PageKind, type PageManager, type PageStatus, type PendingSemanticRefreshEntry, type Polarity, type PromotionDecision, type PromotionGateKind, type PromotionGateResult, type PromotionSession, type ProviderAdapter, type ProviderCapability, type ProviderConfig, type ProviderConfigAddOptions, type ProviderConfigAddResult, type ProviderConfigEntry, type ProviderConfigRemoveOptions, type ProviderConfigRemoveResult, type ProviderPresetCapability, type ProviderRegistrationOptions, type ProviderRegistrationResult, type ProviderRoleExecutorConfig, type ProviderTaskKey, type ProviderType, type QueryOptions, type QueryResult, type RedactionMatchSummary, type RedactionPatternConfig, type RedactionSettings, type RedactionSummary, type RepoSyncResult, type ResolvedLargeRepoDefaults, type ResolvedPaths, type ResumeMemoryTaskOptions, type ResumeMemoryTaskResult, type RetrievalConfig, type RetrievalDoctorResult, type RetrievalManifest, type RetrievalStatus, type ReviewActionResult, type RoleExecutorConfig, SWARMVAULT_OUT_ENV, type SceneElement, type SceneSpec, type ScheduleController, type ScheduleJobConfig, type ScheduleStateRecord, type ScheduleTriggerConfig, type ScheduledCompileTask, type ScheduledConsolidateTask, type ScheduledExploreTask, type ScheduledLintTask, type ScheduledQueryTask, type ScheduledRunResult, type ScheduledTaskConfig, type SearchResult, type SourceAnalysis, type SourceAttachment, type SourceCaptureType, type SourceClaim, type SourceClass, type SourceExtractionArtifact, type SourceGuideResult, type SourceKind, type SourceManifest, type SourceRationale, type SourceReviewResult, type StartMemoryTaskOptions, type SynthesizedHubEdge, type SynthesizedHubNode, type SynthesizedHyperedgeHubs, type UpdateMemoryTaskOptions, type VaultChatSession, type VaultChatSessionSummary, type VaultChatTurn, type VaultConfig, type VaultDashboardPack, type VaultDoctorAction, type VaultDoctorCheck, type VaultDoctorCounts, type VaultDoctorRecommendation, type VaultDoctorRecommendationPriority, type VaultDoctorReport, type VaultDoctorSafeAction, type VaultDoctorStatus, type VaultProfileConfig, type VaultProfilePreset, type VaultVersionRecord, type WatchConfig, type WatchController, type WatchOptions, type WatchRepoSyncResult, type WatchRunRecord, type WatchStatusResult, type WebSearchAdapter, type WebSearchProviderConfig, type WebSearchProviderType, type WebSearchResult, type WhisperRunResult, type WhisperRunner, acceptApproval, addInput, addManagedSource, addProviderConfig, addWatchedRoot, agentTypeSchema, applyDecayToPages, archiveCandidate, askChatSession, assertProviderCapability, autoCommitWikiChanges, benchmarkVault, blastRadius, blastRadiusVault, bootstrapDemo, buildConfiguredRedactor, buildContextPack, buildGraphShareArtifact, buildGraphTree, buildMemoryGraphElements, buildRedactor, checkTrackedRepoChanges, compileVault, computeDecayScore, consolidateVault, createMcpServer, createProvider, createSupersessionEdge, createWebSearchAdapter, defaultVaultConfig, defaultVaultSchema, deleteChatSession, deleteContextPack, deleteManagedSource, detectVaultVersion, discoverLocalWhisperBinary, doctorRetrieval, doctorVault, downloadWhisperModel, ensureMemoryLedger, estimatePageTokens, estimateTokens, evaluateCandidateForPromotion, evaluateGraphShrinkGuard, expectedModelPath, explainGraphVault, exploreVault, exportAiPack, exportGraphFormat, exportGraphHtml, exportGraphReportHtml, exportGraphTree, exportObsidianCanvas, exportObsidianVault, findGraphCycles, finishMemoryTask, getAgentInstallStatus, getGitHookStatus, getGraphCommunityVault, getGraphStatus, getProviderConfigEntry, getProviderForTask, getRetrievalStatus, getWatchStatus, getWebSearchAdapterForTask, getWorkspaceInfo, graphDiff, graphStats, graphStatsVault, guideManagedSource, guideSourceScope, importInbox, ingestDirectory, ingestInput, ingestInputDetailed, initVault, initWorkspace, installAgent, installConfiguredAgents, installGitHooks, lintVault, listApprovals, listCandidates, listChatSessions, listContextPacks, listGodNodes, listGraphHyperedges, listManagedSourceRecords, listManifests, listMemoryTasks, listPages, listProviderConfigEntries, listSchedules, listTrackedRepoRoots, listWatchedRoots, loadMemoryTaskPages, loadVaultConfig, loadVaultSchema, loadVaultSchemas, lookupPresetCapabilities, markSuperseded, memoryTaskHashes, mergeGraphFiles, modelDownloadUrl, pathGraphVault, persistDecayFrontmatter, planMigration, previewCandidatePromotions, projectGraphAfterRemovals, promoteCandidate, providerCapabilitySchema, providerTypeSchema, pushGraphNeo4j, queryGraphVault, queryVault, readApproval, readChatSession, readContextPack, readExtractedText, readGraphReport, readMemoryTask, readPage, rebuildRetrievalIndex, refreshGraphClusters, registerLocalWhisperProvider, rejectApproval, reloadManagedSources, removeProviderConfig, removeWatchedRoot, renderContextPackLlms, renderContextPackMarkdown, renderGraphShareBundleFiles, renderGraphShareMarkdown, renderGraphSharePreviewHtml, renderGraphShareSvg, renderGraphTreeHtml, renderMemoryTaskMarkdown, resetDecay, resolveArtifactRootDir, resolveConsolidationConfig, resolveDecayConfig, resolveLargeRepoDefaults, resolvePaths, resolveRedactionPatterns, resolveRetrievalConfig, resolveWatchedRepoRoots, resumeMemoryTask, resumeSourceSession, reviewManagedSource, reviewSourceScope, runAutoPromotion, runConsolidation, runDecayPass, runMigration, runSchedule, runWatchCycle, searchVault, serveSchedules, stageGeneratedOutputPages, startGraphServer, startMcpServer, startMemoryTask, summarizeLocalWhisperSetup, syncTrackedRepos, syncTrackedReposForWatch, synthesizeHyperedgeHubs, trimToTokenBudget, uninstallGitHooks, updateMemoryTask, validateGraphArtifact, validateGraphVault, watchVault, webSearchProviderTypeSchema, withCapabilityFallback, writeRetrievalManifest };
3360
+ export { ALL_MIGRATIONS, type AddOptions, type AddResult, type AgentInstallStatus, type AgentInstallTargetStatus, type AgentMemoryDecision, type AgentMemoryNote, type AgentMemoryResumeFormat, type AgentMemoryTask, type AgentMemoryTaskResult, type AgentMemoryTaskStatus, type AgentMemoryTaskSummary, type AgentType, type AiExportFile, type AiExportOptions, type AiExportResult, type AnalyzedTerm, type ApprovalBundleType, type ApprovalChangeType, type ApprovalDetail, type ApprovalDiffHunk, type ApprovalDiffLine, type ApprovalEntry, type ApprovalEntryDetail, type ApprovalEntryLabel, type ApprovalEntryStatus, type ApprovalFrontmatterChange, type ApprovalManifest, type ApprovalStructuredDiff, type ApprovalSummary, type AskChatOptions, type AskChatResult, type AudioTranscriptionRequest, type AudioTranscriptionResponse, type BenchmarkArtifact, type BenchmarkByClassEntry, type BenchmarkOptions, type BenchmarkQuestionResult, type BenchmarkSummary, type BlastRadiusResult, type BuildContextPackOptions, type BuildContextPackResult, type CandidatePromotionConfig, type CandidateRecord, type ChartDatum, type ChartSpec, type ClaimStatus, type CodeAnalysis, type CodeDiagnostic, type CodeImport, type CodeIndexArtifact, type CodeIndexEntry, type CodeLanguage, type CodeRelation, type CodeSymbol, type CodeSymbolKind, type CommandRoleExecutorConfig, type CompileOptions, type CompileResult, type CompileState, type ConsolidationConfig, type ConsolidationPromotion, type ConsolidationResult, type ContextPack, type ContextPackFormat, type ContextPackItem, type ContextPackItemKind, type ContextPackOmittedItem, type ContextPackSummary, DEFAULT_CONSOLIDATION_CONFIG, DEFAULT_HALF_LIFE_DAYS, DEFAULT_HALF_LIFE_DAYS_BY_SOURCE_CLASS, DEFAULT_PROMOTION_CONFIG, DEFAULT_REDACTION_PATTERNS, DEFAULT_STALE_THRESHOLD, type DegradationOutcome, type DirectoryIngestFailure, type DirectoryIngestResult, type DirectoryIngestSkip, type EmbeddingCacheArtifact, type EmbeddingCacheEntry, type EvidenceClass, type ExploreOptions, type ExploreResult, type ExploreStepResult, type ExtractionClaim, type ExtractionKind, type ExtractionTerm, type FinishMemoryTaskOptions, type Freshness, type FreshnessConfig, type GenerationAttachment, type GenerationRequest, type GenerationResponse, type GitHookStatus, type GraphArtifact, type GraphClusterRefreshResult, type GraphCommunityResult, type GraphCycle, type GraphCycleResult, type GraphDiffResult, type GraphEdge, type GraphExplainNeighbor, type GraphExplainResult, type GraphExportFormat, type GraphExportResult, type GraphHyperedge, type GraphNode, type GraphPage, type GraphPathResult, type GraphPushCounts, type GraphPushNeo4jOptions, type GraphPushResult, type GraphQueryFilterStats, type GraphQueryFilters, type GraphQueryMatch, type GraphQueryRelationGroup, type GraphQueryResult, type GraphReportArtifact, type GraphShareArtifact, type GraphShareBundleFile, type GraphShrinkDimension, type GraphShrinkGuardResult, type GraphStatsResult, type GraphStatusChange, type GraphStatusResult, type GraphValidationIssue, type GraphValidationResult, type GraphValidationSeverity, type GuidedSessionMode, type GuidedSourceSessionAnswers, type GuidedSourceSessionQuestion, type GuidedSourceSessionRecord, type GuidedSourceSessionStatus, type ImageGenerationRequest, type ImageGenerationResponse, type ImageVisionExtraction, type InboxImportResult, type InboxImportSkip, type IngestOptions, type InitOptions, type InputIngestResult, type InstallAgentOptions, type InstallAgentResult, LARGE_REPO_NODE_THRESHOLD, LOCAL_WHISPER_MODEL_SIZES, type LintFinding, type LintOptions, type LocalWhisperAdapterOptions, type LocalWhisperBinaryDiscovery, LocalWhisperProviderAdapter, type LocalWhisperSetupStatus, type ManagedSourceAddOptions, type ManagedSourceAddResult, type ManagedSourceDeleteResult, type ManagedSourceKind, type ManagedSourceRecord, type ManagedSourceReloadOptions, type ManagedSourceReloadResult, type ManagedSourceStatus, type ManagedSourceSyncCounts, type ManagedSourcesArtifact, type MemoryTier, type MigrationPlan, type MigrationResult, type MigrationStep, type Neo4jGraphSinkConfig, OPENAI_COMPATIBLE_CAPABILITY_MATRIX, type OpenAiCompatiblePresetId, type OrchestrationConfig, type OrchestrationFinding, type OrchestrationProposal, type OrchestrationRole, type OrchestrationRoleConfig, type OrchestrationRoleResult, type OutputAsset, type OutputAssetRole, type OutputFormat, type OutputOrigin, type PageKind, type PageManager, type PageStatus, type PendingSemanticRefreshEntry, type Polarity, type PromotionDecision, type PromotionGateKind, type PromotionGateResult, type PromotionSession, type ProviderAdapter, type ProviderCapability, type ProviderConfig, type ProviderConfigAddOptions, type ProviderConfigAddResult, type ProviderConfigEntry, type ProviderConfigRemoveOptions, type ProviderConfigRemoveResult, type ProviderPresetCapability, type ProviderRegistrationOptions, type ProviderRegistrationResult, type ProviderRoleExecutorConfig, type ProviderTaskKey, type ProviderType, type QueryOptions, type QueryResult, type RedactionMatchSummary, type RedactionPatternConfig, type RedactionSettings, type RedactionSummary, type RepoSyncResult, type ResolvedLargeRepoDefaults, type ResolvedPaths, type ResumeMemoryTaskOptions, type ResumeMemoryTaskResult, type RetrievalConfig, type RetrievalDoctorResult, type RetrievalManifest, type RetrievalStatus, type ReviewActionResult, type RoleExecutorConfig, SWARMVAULT_OUT_ENV, type SceneElement, type SceneSpec, type ScheduleController, type ScheduleJobConfig, type ScheduleStateRecord, type ScheduleTriggerConfig, type ScheduledCompileTask, type ScheduledConsolidateTask, type ScheduledExploreTask, type ScheduledLintTask, type ScheduledQueryTask, type ScheduledRunResult, type ScheduledTaskConfig, type SearchResult, type SourceAnalysis, type SourceAttachment, type SourceCaptureType, type SourceClaim, type SourceClass, type SourceExtractionArtifact, type SourceGuideResult, type SourceKind, type SourceManifest, type SourceRationale, type SourceReviewResult, type StartMemoryTaskOptions, type SynthesizedHubEdge, type SynthesizedHubNode, type SynthesizedHyperedgeHubs, type UpdateMemoryTaskOptions, type VaultChatSession, type VaultChatSessionSummary, type VaultChatTurn, type VaultConfig, type VaultDashboardPack, type VaultDoctorAction, type VaultDoctorCheck, type VaultDoctorCounts, type VaultDoctorRecommendation, type VaultDoctorRecommendationPriority, type VaultDoctorReport, type VaultDoctorSafeAction, type VaultDoctorStatus, type VaultProfileConfig, type VaultProfilePreset, type VaultVersionRecord, type WatchConfig, type WatchController, type WatchOptions, type WatchRepoSyncResult, type WatchRunRecord, type WatchStatusResult, type WebSearchAdapter, type WebSearchProviderConfig, type WebSearchProviderType, type WebSearchResult, type WhisperRunResult, type WhisperRunner, acceptApproval, addInput, addManagedSource, addProviderConfig, addWatchedRoot, agentTypeSchema, applyDecayToPages, archiveCandidate, askChatSession, assertProviderCapability, autoCommitWikiChanges, benchmarkVault, blastRadius, blastRadiusVault, bootstrapDemo, buildConfiguredRedactor, buildContextPack, buildGraphShareArtifact, buildGraphTree, buildMemoryGraphElements, buildRedactor, checkTrackedRepoChanges, compileVault, computeDecayScore, consolidateVault, createMcpServer, createProvider, createSupersessionEdge, createWebSearchAdapter, defaultVaultConfig, defaultVaultSchema, deleteChatSession, deleteContextPack, deleteManagedSource, detectVaultVersion, discoverLocalWhisperBinary, doctorRetrieval, doctorVault, downloadWhisperModel, ensureMemoryLedger, estimatePageTokens, estimateTokens, evaluateCandidateForPromotion, evaluateGraphShrinkGuard, expectedModelPath, explainGraphVault, exploreVault, exportAiPack, exportGraphFormat, exportGraphHtml, exportGraphReportHtml, exportGraphTree, exportObsidianCanvas, exportObsidianVault, findGraphCycles, finishMemoryTask, getAgentInstallStatus, getGitHookStatus, getGraphCommunityVault, getGraphStatus, getProviderConfigEntry, getProviderForTask, getRetrievalStatus, getWatchStatus, getWebSearchAdapterForTask, getWorkspaceInfo, graphDiff, graphStats, graphStatsVault, guideManagedSource, guideSourceScope, importInbox, ingestDirectory, ingestInput, ingestInputDetailed, initVault, initWorkspace, installAgent, installConfiguredAgents, installGitHooks, lintVault, listApprovals, listCandidates, listChatSessions, listContextPacks, listGodNodes, listGraphHyperedges, listManagedSourceRecords, listManifests, listMemoryTasks, listPages, listProviderConfigEntries, listSchedules, listTrackedRepoRoots, listWatchedRoots, loadMemoryTaskPages, loadVaultConfig, loadVaultSchema, loadVaultSchemas, lookupPresetCapabilities, markSuperseded, memoryTaskHashes, mergeGraphFiles, modelDownloadUrl, pathGraphVault, persistDecayFrontmatter, planMigration, previewCandidatePromotions, projectGraphAfterRemovals, promoteCandidate, providerCapabilitySchema, providerTypeSchema, pushGraphNeo4j, queryGraphVault, queryVault, readApproval, readChatSession, readContextPack, readExtractedText, readGraphReport, readMemoryTask, readPage, rebuildRetrievalIndex, refreshGraphClusters, registerLocalWhisperProvider, rejectApproval, reloadManagedSources, removeProviderConfig, removeWatchedRoot, renderContextPackLlms, renderContextPackMarkdown, renderGraphShareBundleFiles, renderGraphShareMarkdown, renderGraphSharePreviewHtml, renderGraphShareSvg, renderGraphTreeHtml, renderMemoryTaskMarkdown, resetDecay, resolveArtifactRootDir, resolveConsolidationConfig, resolveDecayConfig, resolveLargeRepoDefaults, resolvePaths, resolveRedactionPatterns, resolveRetrievalConfig, resolveWatchedRepoRoots, resumeMemoryTask, resumeSourceSession, reviewManagedSource, reviewSourceScope, runAutoPromotion, runConsolidation, runDecayPass, runMigration, runSchedule, runWatchCycle, searchVault, serveSchedules, stageGeneratedOutputPages, startGraphServer, startMcpServer, startMemoryTask, summarizeLocalWhisperSetup, syncTrackedFiles, syncTrackedRepos, syncTrackedReposForWatch, synthesizeHyperedgeHubs, trimToTokenBudget, uninstallGitHooks, updateMemoryTask, validateGraphArtifact, validateGraphVault, watchVault, webSearchProviderTypeSchema, withCapabilityFallback, writeRetrievalManifest };
package/dist/index.js CHANGED
@@ -121,6 +121,7 @@ import {
121
121
  searchVault,
122
122
  stageGeneratedOutputPages,
123
123
  startMemoryTask,
124
+ syncTrackedFiles,
124
125
  syncTrackedRepos,
125
126
  syncTrackedReposForWatch,
126
127
  updateMemoryTask,
@@ -130,7 +131,7 @@ import {
130
131
  writeGuidedSourceSession,
131
132
  writeRetrievalManifest,
132
133
  writeWatchStatusArtifact
133
- } from "./chunk-TQIIJVVG.js";
134
+ } from "./chunk-JEWLYIHN.js";
134
135
  import {
135
136
  LocalWhisperProviderAdapter,
136
137
  SWARMVAULT_OUT_ENV,
@@ -1235,6 +1236,68 @@ async function predictRemovedSourceIdsFromRepoSync(rootDir, options) {
1235
1236
  )
1236
1237
  ];
1237
1238
  }
1239
+ var REFRESH_LOCK_DIRNAME = "refresh.lock";
1240
+ var REFRESH_QUEUE_FILENAME = "refresh-queue.json";
1241
+ var REFRESH_LOCK_STALE_MS = 10 * 6e4;
1242
+ var MAX_FILE_REFRESH_ROUNDS = 5;
1243
+ function refreshLockDir(watchDir) {
1244
+ return path4.join(watchDir, REFRESH_LOCK_DIRNAME);
1245
+ }
1246
+ async function tryAcquireRefreshLock(watchDir) {
1247
+ const lockDir = refreshLockDir(watchDir);
1248
+ await fs4.mkdir(watchDir, { recursive: true });
1249
+ const writeOwner = () => fs4.writeFile(
1250
+ path4.join(lockDir, "owner.json"),
1251
+ `${JSON.stringify({ pid: process2.pid, acquiredAt: (/* @__PURE__ */ new Date()).toISOString() })}
1252
+ `,
1253
+ "utf8"
1254
+ );
1255
+ try {
1256
+ await fs4.mkdir(lockDir, { recursive: false });
1257
+ await writeOwner();
1258
+ return true;
1259
+ } catch {
1260
+ try {
1261
+ const stat = await fs4.stat(lockDir);
1262
+ if (Date.now() - stat.mtimeMs > REFRESH_LOCK_STALE_MS) {
1263
+ await fs4.rm(lockDir, { recursive: true, force: true });
1264
+ await fs4.mkdir(lockDir, { recursive: false });
1265
+ await writeOwner();
1266
+ return true;
1267
+ }
1268
+ } catch {
1269
+ }
1270
+ return false;
1271
+ }
1272
+ }
1273
+ async function releaseRefreshLock(watchDir) {
1274
+ await fs4.rm(refreshLockDir(watchDir), { recursive: true, force: true });
1275
+ }
1276
+ async function enqueueRefreshFiles(watchDir, files) {
1277
+ await fs4.mkdir(watchDir, { recursive: true });
1278
+ const queuePath = path4.join(watchDir, REFRESH_QUEUE_FILENAME);
1279
+ let existing = [];
1280
+ try {
1281
+ const parsed = JSON.parse(await fs4.readFile(queuePath, "utf8"));
1282
+ if (Array.isArray(parsed)) {
1283
+ existing = parsed.filter((entry) => typeof entry === "string");
1284
+ }
1285
+ } catch {
1286
+ }
1287
+ const merged = [.../* @__PURE__ */ new Set([...existing, ...files])];
1288
+ await fs4.writeFile(queuePath, `${JSON.stringify(merged, null, 2)}
1289
+ `, "utf8");
1290
+ }
1291
+ async function drainRefreshQueue(watchDir) {
1292
+ const queuePath = path4.join(watchDir, REFRESH_QUEUE_FILENAME);
1293
+ try {
1294
+ const parsed = JSON.parse(await fs4.readFile(queuePath, "utf8"));
1295
+ await fs4.rm(queuePath, { force: true });
1296
+ return Array.isArray(parsed) ? parsed.filter((entry) => typeof entry === "string") : [];
1297
+ } catch {
1298
+ return [];
1299
+ }
1300
+ }
1238
1301
  function hasIgnoredRepoSegment(baseDir, targetPath) {
1239
1302
  const relativePath = path4.relative(baseDir, targetPath);
1240
1303
  if (!relativePath || relativePath.startsWith("..")) {
@@ -1369,8 +1432,128 @@ async function performWatchCycle(rootDir, paths, options, codeOnly = false) {
1369
1432
  lintFindingCount
1370
1433
  };
1371
1434
  }
1435
+ async function runFileRefreshCycle(rootDir, paths, options, files) {
1436
+ const resolvedFiles = [...new Set(files.map((candidate) => path4.resolve(rootDir, candidate)))];
1437
+ const emptyResult = {
1438
+ watchedRepoRoots: [],
1439
+ importedCount: 0,
1440
+ scannedCount: 0,
1441
+ attachmentCount: 0,
1442
+ repoImportedCount: 0,
1443
+ repoUpdatedCount: 0,
1444
+ repoRemovedCount: 0,
1445
+ repoScannedCount: 0,
1446
+ pendingSemanticRefreshCount: 0,
1447
+ pendingSemanticRefreshPaths: [],
1448
+ changedPages: []
1449
+ };
1450
+ if (!await tryAcquireRefreshLock(paths.watchDir)) {
1451
+ await enqueueRefreshFiles(paths.watchDir, resolvedFiles);
1452
+ return { ...emptyResult, queuedFiles: resolvedFiles };
1453
+ }
1454
+ const startedAt = /* @__PURE__ */ new Date();
1455
+ const reasons = resolvedFiles.map((file) => `file:${path4.relative(rootDir, file) || file}`);
1456
+ let success = true;
1457
+ let error;
1458
+ const result = { ...emptyResult };
1459
+ try {
1460
+ const seenRoots = /* @__PURE__ */ new Set();
1461
+ const changedPages = /* @__PURE__ */ new Set();
1462
+ let pendingFiles = resolvedFiles;
1463
+ let rounds = 0;
1464
+ while (pendingFiles.length > 0 && rounds < MAX_FILE_REFRESH_ROUNDS) {
1465
+ rounds += 1;
1466
+ const repoSync = await syncTrackedFiles(rootDir, pendingFiles);
1467
+ const compile = await compileVault(rootDir, { codeOnly: true });
1468
+ const pendingSemanticRefresh = await mergePendingSemanticRefresh(rootDir, repoSync.pendingSemanticRefresh);
1469
+ const stalePagePaths = await markPagesStaleForSources(
1470
+ rootDir,
1471
+ pendingSemanticRefresh.map((entry) => entry.sourceId).filter((sourceId) => Boolean(sourceId))
1472
+ );
1473
+ for (const repoRoot of repoSync.repoRoots) {
1474
+ seenRoots.add(repoRoot);
1475
+ }
1476
+ for (const page of [...compile.changedPages, ...stalePagePaths]) {
1477
+ changedPages.add(page);
1478
+ }
1479
+ result.scannedCount += repoSync.scannedCount;
1480
+ result.repoScannedCount += repoSync.scannedCount;
1481
+ result.repoImportedCount += repoSync.imported.length;
1482
+ result.repoUpdatedCount += repoSync.updated.length;
1483
+ result.repoRemovedCount += repoSync.removed.length;
1484
+ result.pendingSemanticRefreshCount = pendingSemanticRefresh.length;
1485
+ result.pendingSemanticRefreshPaths = pendingSemanticRefresh.map((entry) => entry.path);
1486
+ pendingFiles = await drainRefreshQueue(paths.watchDir);
1487
+ }
1488
+ if (pendingFiles.length > 0) {
1489
+ await enqueueRefreshFiles(paths.watchDir, pendingFiles);
1490
+ result.queuedFiles = pendingFiles;
1491
+ }
1492
+ result.watchedRepoRoots = [...seenRoots].sort((left, right) => left.localeCompare(right));
1493
+ result.changedPages = [...changedPages];
1494
+ if (options.lint) {
1495
+ result.lintFindingCount = (await lintVault(rootDir)).length;
1496
+ }
1497
+ return result;
1498
+ } catch (caught) {
1499
+ success = false;
1500
+ error = caught instanceof Error ? caught.message : String(caught);
1501
+ throw caught;
1502
+ } finally {
1503
+ await releaseRefreshLock(paths.watchDir);
1504
+ const finishedAt = /* @__PURE__ */ new Date();
1505
+ const runSummary = {
1506
+ startedAt: startedAt.toISOString(),
1507
+ finishedAt: finishedAt.toISOString(),
1508
+ durationMs: finishedAt.getTime() - startedAt.getTime(),
1509
+ inputDir: paths.inboxDir,
1510
+ reasons,
1511
+ importedCount: result.repoImportedCount + result.repoUpdatedCount,
1512
+ scannedCount: result.scannedCount,
1513
+ attachmentCount: 0,
1514
+ changedPages: result.changedPages,
1515
+ repoImportedCount: result.repoImportedCount,
1516
+ repoUpdatedCount: result.repoUpdatedCount,
1517
+ repoRemovedCount: result.repoRemovedCount,
1518
+ repoScannedCount: result.repoScannedCount,
1519
+ pendingSemanticRefreshCount: result.pendingSemanticRefreshCount,
1520
+ pendingSemanticRefreshPaths: result.pendingSemanticRefreshPaths,
1521
+ lintFindingCount: result.lintFindingCount,
1522
+ success,
1523
+ error
1524
+ };
1525
+ await recordSession(rootDir, {
1526
+ operation: "watch",
1527
+ title: `File refresh for ${reasons.join(", ")}`,
1528
+ startedAt: startedAt.toISOString(),
1529
+ finishedAt: finishedAt.toISOString(),
1530
+ success,
1531
+ error,
1532
+ changedPages: result.changedPages,
1533
+ lintFindingCount: result.lintFindingCount,
1534
+ lines: [
1535
+ `reasons=${reasons.join(",")}`,
1536
+ `repo_imported=${result.repoImportedCount}`,
1537
+ `repo_updated=${result.repoUpdatedCount}`,
1538
+ `repo_removed=${result.repoRemovedCount}`,
1539
+ `pending_semantic_refresh=${result.pendingSemanticRefreshCount}`,
1540
+ `lint=${result.lintFindingCount ?? 0}`
1541
+ ]
1542
+ });
1543
+ await appendWatchRun(rootDir, runSummary);
1544
+ await writeWatchStatusArtifact(rootDir, {
1545
+ generatedAt: finishedAt.toISOString(),
1546
+ watchedRepoRoots: result.watchedRepoRoots,
1547
+ lastRun: runSummary,
1548
+ pendingSemanticRefresh: await readPendingSemanticRefresh(rootDir)
1549
+ });
1550
+ }
1551
+ }
1372
1552
  async function runWatchCycle(rootDir, options = {}) {
1373
1553
  const { paths } = await initWorkspace(rootDir);
1554
+ if (options.files && options.files.length > 0) {
1555
+ return runFileRefreshCycle(rootDir, paths, options, options.files);
1556
+ }
1374
1557
  const previousGraph = await readJsonFile(paths.graphPath);
1375
1558
  const startedAt = /* @__PURE__ */ new Date();
1376
1559
  let success = true;
@@ -3509,8 +3692,26 @@ function renderHtmlStandalone(graph) {
3509
3692
  var seedPageIds = coreUnique(matches.filter(function(m) { return m.type === "page"; }).map(function(m) { return m.id; }));
3510
3693
  var visitedEdgeIdList = Object.keys(visitedEdgeIds);
3511
3694
 
3695
+ var topMatchParts = matches.slice(0, 8).map(function(m) {
3696
+ var pagePath;
3697
+ if (m.type === "page") {
3698
+ pagePath = (CORE_PAGE_BY_ID[m.id] && CORE_PAGE_BY_ID[m.id].path) || m.id;
3699
+ } else if (m.type === "node") {
3700
+ var matchNode = CORE_NODE_BY_ID[m.id];
3701
+ var matchPageId = matchNode && matchNode.pageId;
3702
+ if (matchPageId) pagePath = (CORE_PAGE_BY_ID[matchPageId] && CORE_PAGE_BY_ID[matchPageId].path) || matchPageId;
3703
+ }
3704
+ return (m.label || m.id) + " (" + m.type + ", score " + m.score + (pagePath ? ", page " + pagePath : "") + ")";
3705
+ });
3706
+ var topMatchesLine = matches.length
3707
+ ? "Top matches: " + topMatchParts.join("; ") + (matches.length > 8 ? " (+" + (matches.length - 8) + " more)" : "")
3708
+ : "Top matches: none";
3709
+ var seedsLine = seeds.length
3710
+ ? "Seeds: " + seeds.slice(0, 15).join(", ") + (seeds.length > 15 ? " (+" + (seeds.length - 15) + " more)" : "")
3711
+ : "Seeds: none";
3512
3712
  var summary = [
3513
- "Seeds: " + (seeds.join(", ") || "none"),
3713
+ topMatchesLine,
3714
+ seedsLine,
3514
3715
  "Visited nodes: " + visitedNodeIds.length,
3515
3716
  "Visited edges: " + visitedEdgeIdList.length,
3516
3717
  "Touched group patterns: " + hyperedgeIds.length,
@@ -5510,7 +5711,7 @@ import path12 from "path";
5510
5711
  import { McpServer, ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
5511
5712
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
5512
5713
  import { z } from "zod";
5513
- var SERVER_VERSION = "3.16.1";
5714
+ var SERVER_VERSION = "3.17.0";
5514
5715
  var codeLanguageSchema = z.enum([
5515
5716
  "javascript",
5516
5717
  "jsx",
@@ -6175,6 +6376,38 @@ async function createMcpServer(rootDir) {
6175
6376
  return asToolText(status);
6176
6377
  })
6177
6378
  );
6379
+ server.registerTool(
6380
+ "graph_status",
6381
+ {
6382
+ description: "Read-only graph freshness check: graph/report presence, tracked repo changes since the last refresh, and the recommended refresh command.",
6383
+ inputSchema: {
6384
+ repoRoots: z.array(z.string()).optional().describe("Optional repo roots to check instead of configured/tracked roots")
6385
+ }
6386
+ },
6387
+ safeHandler(async ({ repoRoots }) => {
6388
+ const status = await getGraphStatus(rootDir, { repoRoots });
6389
+ return asToolText(status);
6390
+ })
6391
+ );
6392
+ server.registerTool(
6393
+ "update_graph",
6394
+ {
6395
+ description: "Code-only graph refresh. With files, refreshes just those files (fast path used after edits); otherwise walks tracked repo roots.",
6396
+ inputSchema: {
6397
+ files: z.array(z.string()).optional().describe("Refresh only these files instead of walking every tracked repo root"),
6398
+ force: z.boolean().optional().describe("Allow updates even when node or edge counts shrink sharply")
6399
+ }
6400
+ },
6401
+ safeHandler(async ({ files, force }) => {
6402
+ const result = await runWatchCycle(rootDir, {
6403
+ repo: true,
6404
+ codeOnly: true,
6405
+ force: force ?? false,
6406
+ files: files?.length ? files : void 0
6407
+ });
6408
+ return asToolText(result);
6409
+ })
6410
+ );
6178
6411
  server.registerTool(
6179
6412
  "consolidate",
6180
6413
  {
@@ -9929,6 +10162,7 @@ export {
9929
10162
  startMcpServer,
9930
10163
  startMemoryTask,
9931
10164
  summarizeLocalWhisperSetup,
10165
+ syncTrackedFiles,
9932
10166
  syncTrackedRepos,
9933
10167
  syncTrackedReposForWatch,
9934
10168
  synthesizeHyperedgeHubs,
@@ -0,0 +1,32 @@
1
+ import {
2
+ buildMemoryGraphElements,
3
+ ensureMemoryLedger,
4
+ estimateMemoryTaskTokens,
5
+ finishMemoryTask,
6
+ listMemoryTasks,
7
+ loadMemoryTaskPages,
8
+ memoryTaskHashes,
9
+ memoryTaskPageRecord,
10
+ readMemoryTask,
11
+ renderMemoryTaskMarkdown,
12
+ resumeMemoryTask,
13
+ startMemoryTask,
14
+ updateMemoryTask
15
+ } from "./chunk-CSPDMCON.js";
16
+ import "./chunk-75BU5TQ6.js";
17
+ import "./chunk-NAIERP4C.js";
18
+ export {
19
+ buildMemoryGraphElements,
20
+ ensureMemoryLedger,
21
+ estimateMemoryTaskTokens,
22
+ finishMemoryTask,
23
+ listMemoryTasks,
24
+ loadMemoryTaskPages,
25
+ memoryTaskHashes,
26
+ memoryTaskPageRecord,
27
+ readMemoryTask,
28
+ renderMemoryTaskMarkdown,
29
+ resumeMemoryTask,
30
+ startMemoryTask,
31
+ updateMemoryTask
32
+ };