memorix 1.1.7 → 1.1.9

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 (185) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/CLAUDE.md +6 -1
  3. package/README.md +21 -0
  4. package/README.zh-CN.md +21 -0
  5. package/TEAM.md +86 -86
  6. package/dist/cli/index.js +852 -214
  7. package/dist/cli/index.js.map +1 -1
  8. package/dist/dashboard/static/index.html +201 -201
  9. package/dist/dashboard/static/style.css +3584 -3584
  10. package/dist/index.js +129 -62
  11. package/dist/index.js.map +1 -1
  12. package/dist/memcode-runtime/CHANGELOG.md +22 -0
  13. package/dist/memcode-runtime/package.json +4 -4
  14. package/dist/sdk.js +129 -62
  15. package/dist/sdk.js.map +1 -1
  16. package/docs/AGENT_OPERATOR_PLAYBOOK.md +18 -0
  17. package/docs/API_REFERENCE.md +2 -0
  18. package/docs/CONFIGURATION.md +18 -0
  19. package/docs/DESIGN_DECISIONS.md +357 -357
  20. package/docs/SETUP.md +10 -0
  21. package/docs/dev-log/progress.txt +23 -30
  22. package/package.json +1 -1
  23. package/src/audit/index.ts +156 -156
  24. package/src/cli/commands/agent-integrations.ts +623 -0
  25. package/src/cli/commands/audit-list.ts +89 -89
  26. package/src/cli/commands/background.ts +659 -659
  27. package/src/cli/commands/cleanup.ts +255 -255
  28. package/src/cli/commands/codegraph.ts +4 -0
  29. package/src/cli/commands/config-get.ts +9 -2
  30. package/src/cli/commands/doctor.ts +26 -0
  31. package/src/cli/commands/formation.ts +48 -48
  32. package/src/cli/commands/git-hook-install.ts +111 -111
  33. package/src/cli/commands/handoff.ts +66 -66
  34. package/src/cli/commands/hooks-status.ts +63 -63
  35. package/src/cli/commands/ingest-commit.ts +153 -153
  36. package/src/cli/commands/ingest-image.ts +73 -73
  37. package/src/cli/commands/ingest-log.ts +180 -180
  38. package/src/cli/commands/ingest.ts +44 -44
  39. package/src/cli/commands/integrate-shared.ts +15 -15
  40. package/src/cli/commands/lock.ts +96 -96
  41. package/src/cli/commands/message.ts +121 -121
  42. package/src/cli/commands/poll.ts +70 -70
  43. package/src/cli/commands/purge-all-memory.ts +85 -85
  44. package/src/cli/commands/purge-project-memory.ts +83 -83
  45. package/src/cli/commands/reasoning.ts +132 -132
  46. package/src/cli/commands/repair.ts +60 -0
  47. package/src/cli/commands/retention.ts +108 -108
  48. package/src/cli/commands/serve-shared.ts +118 -118
  49. package/src/cli/commands/setup.ts +3 -3
  50. package/src/cli/commands/skills.ts +123 -123
  51. package/src/cli/commands/task.ts +192 -192
  52. package/src/cli/commands/transfer.ts +73 -73
  53. package/src/cli/commands/uninstall-project-artifacts.ts +85 -85
  54. package/src/cli/index.ts +3 -1
  55. package/src/cli/tui/ChatView.tsx +234 -234
  56. package/src/cli/tui/CommandBar.tsx +312 -312
  57. package/src/cli/tui/ContextRail.tsx +118 -118
  58. package/src/cli/tui/HeaderBar.tsx +72 -72
  59. package/src/cli/tui/LogoBanner.tsx +51 -51
  60. package/src/cli/tui/Panels.tsx +632 -632
  61. package/src/cli/tui/Sidebar.tsx +179 -179
  62. package/src/cli/tui/chat-service.ts +742 -742
  63. package/src/cli/tui/data.ts +547 -547
  64. package/src/cli/tui/index.ts +41 -41
  65. package/src/cli/tui/markdown-render.tsx +371 -371
  66. package/src/cli/tui/theme.ts +178 -178
  67. package/src/cli/tui/use-mouse.ts +157 -157
  68. package/src/cli/tui/useNavigation.ts +56 -56
  69. package/src/cli/update-checker.ts +211 -211
  70. package/src/cli/version.ts +7 -7
  71. package/src/cli/workbench.ts +1 -1
  72. package/src/codegraph/auto-context.ts +6 -0
  73. package/src/codegraph/context-pack.ts +7 -6
  74. package/src/codegraph/exclude.ts +47 -0
  75. package/src/codegraph/lite-provider.ts +5 -24
  76. package/src/codegraph/project-context.ts +13 -15
  77. package/src/compact/token-budget.ts +74 -74
  78. package/src/config/behavior.ts +59 -59
  79. package/src/config/resolved-config.ts +6 -0
  80. package/src/config/toml-loader.ts +4 -0
  81. package/src/config/yaml-loader.ts +7 -0
  82. package/src/dashboard/project-classification.ts +64 -64
  83. package/src/dashboard/static/index.html +201 -201
  84. package/src/dashboard/static/style.css +3584 -3584
  85. package/src/embedding/fastembed-provider.ts +142 -142
  86. package/src/embedding/transformers-provider.ts +111 -111
  87. package/src/git/extractor.ts +209 -209
  88. package/src/git/hooks-path.ts +85 -85
  89. package/src/git/noise-filter.ts +210 -210
  90. package/src/hooks/installers/index.ts +4 -4
  91. package/src/hooks/official-skills.ts +1 -1
  92. package/src/hooks/pattern-detector.ts +173 -173
  93. package/src/hooks/rules/memorix-agent-rules.md +2 -2
  94. package/src/hooks/significance-filter.ts +250 -250
  95. package/src/llm/memory-manager.ts +328 -328
  96. package/src/llm/provider.ts +885 -885
  97. package/src/llm/quality.ts +248 -248
  98. package/src/memory/attribution-guard.ts +249 -249
  99. package/src/memory/auto-relations.ts +107 -107
  100. package/src/memory/consolidation.ts +302 -302
  101. package/src/memory/disclosure-policy.ts +141 -141
  102. package/src/memory/entity-extractor.ts +197 -197
  103. package/src/memory/formation/evaluate.ts +217 -217
  104. package/src/memory/formation/extract.ts +361 -361
  105. package/src/memory/formation/index.ts +417 -417
  106. package/src/memory/formation/resolve.ts +344 -344
  107. package/src/memory/formation/types.ts +315 -315
  108. package/src/memory/freshness.ts +122 -122
  109. package/src/memory/graph.ts +197 -197
  110. package/src/memory/refs.ts +94 -94
  111. package/src/memory/retention.ts +433 -433
  112. package/src/memory/secret-filter.ts +79 -79
  113. package/src/memory/session.ts +523 -523
  114. package/src/multimodal/image-loader.ts +143 -143
  115. package/src/orchestrate/adapters/claude-stream.ts +192 -192
  116. package/src/orchestrate/adapters/claude.ts +111 -111
  117. package/src/orchestrate/adapters/codex-stream.ts +134 -134
  118. package/src/orchestrate/adapters/codex.ts +41 -41
  119. package/src/orchestrate/adapters/gemini-stream.ts +166 -166
  120. package/src/orchestrate/adapters/gemini.ts +42 -42
  121. package/src/orchestrate/adapters/index.ts +73 -73
  122. package/src/orchestrate/adapters/opencode-stream.ts +143 -143
  123. package/src/orchestrate/adapters/opencode.ts +47 -47
  124. package/src/orchestrate/adapters/spawn-helper.ts +286 -286
  125. package/src/orchestrate/adapters/types.ts +77 -77
  126. package/src/orchestrate/capability-router.ts +284 -284
  127. package/src/orchestrate/context-compact.ts +188 -188
  128. package/src/orchestrate/cost-tracker.ts +219 -219
  129. package/src/orchestrate/error-recovery.ts +191 -191
  130. package/src/orchestrate/evidence.ts +140 -140
  131. package/src/orchestrate/ledger.ts +110 -110
  132. package/src/orchestrate/memorix-bridge.ts +380 -380
  133. package/src/orchestrate/output-budget.ts +80 -80
  134. package/src/orchestrate/permission.ts +152 -152
  135. package/src/orchestrate/pipeline-trace.ts +131 -131
  136. package/src/orchestrate/prompt-builder.ts +155 -155
  137. package/src/orchestrate/ring-buffer.ts +37 -37
  138. package/src/orchestrate/task-graph.ts +389 -389
  139. package/src/orchestrate/verify-gate.ts +219 -219
  140. package/src/orchestrate/worktree.ts +232 -232
  141. package/src/project/aliases.ts +374 -374
  142. package/src/project/detector.ts +268 -268
  143. package/src/rules/adapters/claude-code.ts +99 -99
  144. package/src/rules/adapters/codex.ts +97 -97
  145. package/src/rules/adapters/copilot.ts +124 -124
  146. package/src/rules/adapters/cursor.ts +114 -114
  147. package/src/rules/adapters/kiro.ts +126 -126
  148. package/src/rules/adapters/trae.ts +56 -56
  149. package/src/rules/adapters/windsurf.ts +83 -83
  150. package/src/rules/syncer.ts +235 -235
  151. package/src/sdk.ts +327 -327
  152. package/src/search/intent-detector.ts +289 -289
  153. package/src/search/query-expansion.ts +52 -52
  154. package/src/server/formation-timeout.ts +27 -27
  155. package/src/server.ts +3 -0
  156. package/src/skills/mini-skills.ts +386 -386
  157. package/src/store/chat-store.ts +119 -119
  158. package/src/store/file-lock.ts +100 -100
  159. package/src/store/graph-store.ts +249 -249
  160. package/src/store/mini-skill-store.ts +349 -349
  161. package/src/store/obs-store.ts +255 -255
  162. package/src/store/orama-store.ts +15 -8
  163. package/src/store/persistence-json.ts +212 -212
  164. package/src/store/persistence.ts +291 -291
  165. package/src/store/project-affinity.ts +195 -195
  166. package/src/store/session-store.ts +259 -259
  167. package/src/store/sqlite-store.ts +339 -339
  168. package/src/team/event-bus.ts +76 -76
  169. package/src/team/file-locks.ts +173 -173
  170. package/src/team/handoff.ts +167 -167
  171. package/src/team/messages.ts +203 -203
  172. package/src/team/poll.ts +132 -132
  173. package/src/team/tasks.ts +211 -211
  174. package/src/wiki/generator.ts +237 -237
  175. package/src/wiki/knowledge-graph.ts +334 -334
  176. package/src/wiki/types.ts +85 -85
  177. package/src/workspace/mcp-adapters/codex.ts +191 -191
  178. package/src/workspace/mcp-adapters/copilot.ts +105 -105
  179. package/src/workspace/mcp-adapters/cursor.ts +53 -53
  180. package/src/workspace/mcp-adapters/kiro.ts +64 -64
  181. package/src/workspace/mcp-adapters/opencode.ts +123 -123
  182. package/src/workspace/mcp-adapters/trae.ts +134 -134
  183. package/src/workspace/mcp-adapters/windsurf.ts +91 -91
  184. package/src/workspace/sanitizer.ts +60 -60
  185. package/src/workspace/workflow-sync.ts +131 -131
package/dist/cli/index.js CHANGED
@@ -3212,7 +3212,7 @@ ${import_picocolors.default.gray(m3)} ${s2}
3212
3212
 
3213
3213
  // src/cli/version.ts
3214
3214
  function getCliVersion() {
3215
- return true ? "1.1.7" : pkg.version;
3215
+ return true ? "1.1.9" : pkg.version;
3216
3216
  }
3217
3217
  var init_version = __esm({
3218
3218
  "src/cli/version.ts"() {
@@ -8145,12 +8145,12 @@ async function removeMultipleAsync(orama, ids, batchSize, language, skipHooks) {
8145
8145
  if (!skipHooks) {
8146
8146
  await runMultipleHook(orama.beforeRemoveMultiple, orama, docIdsForHooks);
8147
8147
  }
8148
- await new Promise((resolve3, reject) => {
8148
+ await new Promise((resolve4, reject) => {
8149
8149
  let i2 = 0;
8150
8150
  async function _removeMultiple() {
8151
8151
  const batch = ids.slice(i2 * batchSize, ++i2 * batchSize);
8152
8152
  if (!batch.length) {
8153
- return resolve3();
8153
+ return resolve4();
8154
8154
  }
8155
8155
  for (const doc of batch) {
8156
8156
  try {
@@ -12429,6 +12429,7 @@ function loadYamlConfig(projectRoot) {
12429
12429
  agent: { ...userConfig.agent, ...projectConfig.agent },
12430
12430
  embedding: { ...userConfig.embedding, ...projectConfig.embedding },
12431
12431
  git: { ...userConfig.git, ...projectConfig.git },
12432
+ codegraph: { ...userConfig.codegraph, ...projectConfig.codegraph },
12432
12433
  behavior: { ...userConfig.behavior, ...projectConfig.behavior },
12433
12434
  server: { ...userConfig.server, ...projectConfig.server },
12434
12435
  team: { ...userConfig.team, ...projectConfig.team }
@@ -12531,6 +12532,7 @@ function mergeTomlConfig(base, override) {
12531
12532
  embedding: { ...base.embedding, ...override.embedding },
12532
12533
  hooks: { ...base.hooks, ...override.hooks },
12533
12534
  git: { ...base.git, ...override.git },
12535
+ codegraph: { ...base.codegraph, ...override.codegraph },
12534
12536
  server: { ...base.server, ...override.server }
12535
12537
  };
12536
12538
  }
@@ -13154,6 +13156,9 @@ function getResolvedConfig(options2 = {}) {
13154
13156
  excludePatterns: firstArray(toml.git?.exclude_patterns, yaml4.git?.excludePatterns),
13155
13157
  noiseKeywords: firstArray(toml.git?.noise_keywords, yaml4.git?.noiseKeywords)
13156
13158
  },
13159
+ codegraph: {
13160
+ excludePatterns: firstArray(toml.codegraph?.exclude_patterns, yaml4.codegraph?.excludePatterns)
13161
+ },
13157
13162
  server: {
13158
13163
  transport: first(toml.server?.transport, yaml4.server?.transport),
13159
13164
  dashboard: firstBool(toml.server?.dashboard, yaml4.server?.dashboard),
@@ -13762,7 +13767,7 @@ async function fetchWithRetry(url, apiKey, body, attempt = 0) {
13762
13767
  const retryAfter = response.headers.get("retry-after");
13763
13768
  const waitMs = retryAfter ? parseInt(retryAfter, 10) * 1e3 : delay;
13764
13769
  console.error(`[memorix] Embedding API ${response.status}, retry ${attempt + 1}/${MAX_RETRIES} in ${waitMs}ms`);
13765
- await new Promise((resolve3) => setTimeout(resolve3, waitMs));
13770
+ await new Promise((resolve4) => setTimeout(resolve4, waitMs));
13766
13771
  return fetchWithRetry(url, apiKey, body, attempt + 1);
13767
13772
  }
13768
13773
  const errorText = await response.text().catch(() => "unknown error");
@@ -15701,8 +15706,12 @@ function makeEntryKey(projectId, observationId) {
15701
15706
  return `${projectId ?? ""}::${observationId}`;
15702
15707
  }
15703
15708
  function rememberObservationDoc(doc) {
15704
- if (!doc.projectId || typeof doc.observationId !== "number") return;
15705
- docByObservationKey.set(makeEntryKey(doc.projectId, doc.observationId), doc);
15709
+ const publicDoc = { ...doc };
15710
+ delete publicDoc.embedding;
15711
+ if (doc.projectId && typeof doc.observationId === "number") {
15712
+ docByObservationKey.set(makeEntryKey(doc.projectId, doc.observationId), publicDoc);
15713
+ }
15714
+ return publicDoc;
15706
15715
  }
15707
15716
  function isCommandLikeQuery(query) {
15708
15717
  return COMMAND_LIKE_QUERY2.test(query);
@@ -15804,14 +15813,14 @@ async function batchGenerateEmbeddings(texts) {
15804
15813
  }
15805
15814
  async function hydrateIndex(observations2) {
15806
15815
  const database = await getDb();
15807
- const currentCount = await count2(database);
15808
- if (currentCount > 0) return 0;
15809
15816
  let inserted = 0;
15810
15817
  for (const obs of observations2) {
15811
15818
  if (!obs || !obs.id || !obs.projectId) continue;
15812
15819
  try {
15820
+ const id = makeOramaObservationId(obs.projectId, obs.id);
15821
+ if (getByID(database, id)) continue;
15813
15822
  const doc = {
15814
- id: makeOramaObservationId(obs.projectId, obs.id),
15823
+ id,
15815
15824
  observationId: obs.id,
15816
15825
  entityName: obs.entityName || "",
15817
15826
  type: obs.type || "discovery",
@@ -15905,6 +15914,7 @@ async function searchObservations(options2) {
15905
15914
  let searchParams = {
15906
15915
  term: originalQuery,
15907
15916
  limit: requestLimit,
15917
+ includeVectors: true,
15908
15918
  ...Object.keys(filters).length > 0 ? { where: filters } : {},
15909
15919
  // Search specific fields (not tokens, accessCount, etc.)
15910
15920
  properties: ["title", "entityName", "narrative", "facts", "concepts", "filesModified"],
@@ -15976,6 +15986,7 @@ async function searchObservations(options2) {
15976
15986
  const vectorOnlyParams = {
15977
15987
  term: "",
15978
15988
  limit: requestLimit,
15989
+ includeVectors: true,
15979
15990
  ...Object.keys(filters).length > 0 ? { where: filters } : {},
15980
15991
  mode: "vector",
15981
15992
  vector: {
@@ -16274,6 +16285,7 @@ async function getObservationsByIds(ids, projectId) {
16274
16285
  }
16275
16286
  const searchResult = await search2(database, {
16276
16287
  term: "",
16288
+ includeVectors: true,
16277
16289
  where: {
16278
16290
  observationId: { eq: id },
16279
16291
  ...projectId ? { projectId } : {}
@@ -16281,7 +16293,7 @@ async function getObservationsByIds(ids, projectId) {
16281
16293
  limit: 1
16282
16294
  });
16283
16295
  if (searchResult.hits.length > 0) {
16284
- results.push(searchResult.hits[0].document);
16296
+ results.push(rememberObservationDoc(searchResult.hits[0].document));
16285
16297
  }
16286
16298
  }
16287
16299
  return results;
@@ -20793,7 +20805,7 @@ var init_official_skills = __esm({
20793
20805
  "",
20794
20806
  "## Search Rules",
20795
20807
  "",
20796
- "- Use `memorix_project_context` before broad continuation work, unfamiliar code changes, ad-hoc file reads, or dev-log reads. Pass the user's actual task so Memorix can choose a bugfix, feature, release, onboarding, refactor, docs, test, or general brief. Start by reading its suggested files.",
20808
+ "- Default first step for non-trivial coding work: call `memorix_project_context` before progress files, dev-log reads, ad-hoc file reads, or git archaeology. Pass the user's actual task so Memorix can choose a bugfix, feature, release, onboarding, refactor, docs, test, or general brief. Start by reading its suggested files.",
20797
20809
  "- In Claude Code headless/print-mode, an initial MCP `pending` status is not a failure by itself. Prefer MCP first: use the client's tool discovery/dynamic loading to find `memorix_project_context` when it is not in the first visible tool list.",
20798
20810
  '- Run `memorix context --task "<task>"` from the shell only after MCP is unavailable, disabled, or not discoverable, and pass the user\'s real task text. Do not skip memory, wait indefinitely on `pending`, or hand-write tool-call syntax.',
20799
20811
  "- Use `memorix_search` for a specific decision, bug, file, or prior change that the project context did not answer.",
@@ -21104,6 +21116,7 @@ var init_audit = __esm({
21104
21116
  var installers_exports = {};
21105
21117
  __export(installers_exports, {
21106
21118
  detectInstalledAgents: () => detectInstalledAgents,
21119
+ getAgentRulesPath: () => getAgentRulesPath,
21107
21120
  getGlobalConfigPath: () => getGlobalConfigPath,
21108
21121
  getHookStatus: () => getHookStatus,
21109
21122
  getProjectConfigPath: () => getProjectConfigPath,
@@ -21728,8 +21741,8 @@ async function installHooks(agent, projectRoot, global2 = false) {
21728
21741
  try {
21729
21742
  const { access: access3, unlink: unlink2 } = await import("fs/promises");
21730
21743
  await access3(entry.path);
21731
- const basename4 = path13.basename(entry.path);
21732
- if (basename4 === "AGENTS.md" || basename4 === "GEMINI.md" || basename4 === "CONTEXT.md") {
21744
+ const basename5 = path13.basename(entry.path);
21745
+ if (basename5 === "AGENTS.md" || basename5 === "GEMINI.md" || basename5 === "CONTEXT.md") {
21733
21746
  continue;
21734
21747
  }
21735
21748
  await unlink2(entry.path);
@@ -21970,7 +21983,7 @@ function getAgentRulesContent(agent, scope = "project") {
21970
21983
  let frontmatter = "";
21971
21984
  const contextNoun = scope === "global" ? "workspace" : "project";
21972
21985
  const title = scope === "global" ? "# Memorix \u2014 Memory Tools for Active Workspaces" : "# Memorix \u2014 Project Memory Tools";
21973
- const intro = scope === "global" ? "Use Memorix when the active workspace has Memorix tools available and prior context would materially help. Do not assume every workspace is configured for Memorix." : "This repository is configured to use Memorix for persistent cross-session memory. Memory tools are available when you need context from prior sessions or when you learn something worth saving.";
21986
+ const intro = scope === "global" ? "Use Memorix when the active workspace has Memorix tools available and prior context would materially help. For non-trivial coding work, Memory Autopilot is the default entry point before local progress notes or broad file exploration. Do not assume every workspace is configured for Memorix." : "This repository is configured to use Memorix for persistent cross-session memory. For non-trivial coding work, Memory Autopilot is the default entry point before local progress notes or broad file exploration.";
21974
21987
  if (agent === "windsurf") {
21975
21988
  frontmatter = "---\ntrigger: always_on\n---\n\n";
21976
21989
  } else if (agent === "cursor") {
@@ -21988,7 +22001,7 @@ alwaysApply: true
21988
22001
  "",
21989
22002
  "## Start with Memory Autopilot",
21990
22003
  "",
21991
- `For starting or continuing code work, use \`memorix_project_context\` with the user's actual task before ad-hoc file reads, dev-log reads, or git archaeology. Memorix will choose a task-lensed brief (bugfix, feature, release, onboarding, refactor, docs, test, or general). Treat its "Start here" files as the first ${contextNoun} files to inspect.`,
22004
+ `Default first step for non-trivial coding work: call \`memorix_project_context\` with the user's actual task before progress files, dev-log reads, ad-hoc file reads, or git archaeology. Memorix will choose a task-lensed brief (bugfix, feature, release, onboarding, refactor, docs, test, or general). Treat its "Start here" files as the first ${contextNoun} files to inspect.`,
21992
22005
  "",
21993
22006
  'If the MCP tool is not visible yet but the client supports tool discovery or dynamic loading, search/select `memorix_project_context` first. Run `memorix context --task "<task>"` only after MCP is unavailable, disabled, or not discoverable, and pass the user\'s real task text. Do not skip memory, wait indefinitely on MCP startup, or hand-write tool-call syntax.',
21994
22007
  "",
@@ -22082,8 +22095,8 @@ async function uninstallHooks(agent, projectRoot, global2 = false) {
22082
22095
  const agentFiles = prevFiles.filter((e3) => e3.agent === agent);
22083
22096
  for (const entry of agentFiles) {
22084
22097
  try {
22085
- const basename4 = path13.basename(entry.path);
22086
- if (basename4 === "AGENTS.md" || basename4 === "GEMINI.md" || basename4 === "CONTEXT.md") {
22098
+ const basename5 = path13.basename(entry.path);
22099
+ if (basename5 === "AGENTS.md" || basename5 === "GEMINI.md" || basename5 === "CONTEXT.md") {
22087
22100
  try {
22088
22101
  const content = await fs9.readFile(entry.path, "utf-8");
22089
22102
  const memorixStart = content.indexOf("# Memorix");
@@ -22209,8 +22222,10 @@ var init_installers = __esm({
22209
22222
  // src/cli/commands/setup.ts
22210
22223
  var setup_exports = {};
22211
22224
  __export(setup_exports, {
22225
+ buildMemorixServer: () => buildMemorixServer,
22212
22226
  buildSetupPlan: () => buildSetupPlan,
22213
22227
  default: () => setup_default,
22228
+ getMcpAdapter: () => getMcpAdapter,
22214
22229
  getSetupAgentTargets: () => getSetupAgentTargets,
22215
22230
  getSetupIntegrationRows: () => getSetupIntegrationRows2,
22216
22231
  installAntigravityPluginPackage: () => installAntigravityPluginPackage,
@@ -23255,11 +23270,17 @@ __export(config_get_exports, {
23255
23270
  function readDotted(source, key) {
23256
23271
  let cursor = source;
23257
23272
  for (const part of key.split(".")) {
23258
- if (!cursor || typeof cursor !== "object" || !(part in cursor)) return void 0;
23259
- cursor = cursor[part];
23273
+ if (!cursor || typeof cursor !== "object") return void 0;
23274
+ const record2 = cursor;
23275
+ const normalizedPart = part in record2 ? part : snakeToCamel(part);
23276
+ if (!(normalizedPart in record2)) return void 0;
23277
+ cursor = record2[normalizedPart];
23260
23278
  }
23261
23279
  return cursor;
23262
23280
  }
23281
+ function snakeToCamel(value) {
23282
+ return value.replace(/_([a-z])/g, (_4, char) => char.toUpperCase());
23283
+ }
23263
23284
  function formatValue(value, key) {
23264
23285
  if (typeof value === "string") return shouldRedactKey(key) ? "<redacted>" : value;
23265
23286
  if (typeof value === "number" || typeof value === "boolean") return String(value);
@@ -26286,6 +26307,58 @@ var init_current_facts = __esm({
26286
26307
  }
26287
26308
  });
26288
26309
 
26310
+ // src/codegraph/exclude.ts
26311
+ function normalizeCodeGraphExcludePatterns(exclude) {
26312
+ return [.../* @__PURE__ */ new Set([
26313
+ ...DEFAULT_CODEGRAPH_EXCLUDES,
26314
+ ...(exclude ?? []).map((pattern) => pattern.trim()).filter(Boolean)
26315
+ ])];
26316
+ }
26317
+ function isCodeGraphExcludedPath(path29, exclude) {
26318
+ const normalized = normalizeCodePath2(path29);
26319
+ return normalizeCodeGraphExcludePatterns(exclude).some((pattern) => matchesPattern(normalized, normalizeCodePath2(pattern)));
26320
+ }
26321
+ function normalizeCodePath2(path29) {
26322
+ return path29.replace(/\\/g, "/").replace(/^\.\/+/, "");
26323
+ }
26324
+ function matchesPattern(path29, pattern) {
26325
+ if (pattern.endsWith("/**")) {
26326
+ const base = pattern.slice(0, -3);
26327
+ if (base.startsWith("**/")) {
26328
+ const suffix = base.slice(3);
26329
+ return path29 === suffix || path29.endsWith(`/${suffix}`) || path29.includes(`/${suffix}/`);
26330
+ }
26331
+ if (!base.includes("/")) {
26332
+ return path29 === base || path29.startsWith(`${base}/`) || path29.includes(`/${base}/`);
26333
+ }
26334
+ return path29 === base || path29.startsWith(`${base}/`);
26335
+ }
26336
+ if (pattern.startsWith("**/")) {
26337
+ const suffix = pattern.slice(3);
26338
+ return path29 === suffix || path29.endsWith(`/${suffix}`);
26339
+ }
26340
+ return path29 === pattern || path29.startsWith(`${pattern}/`);
26341
+ }
26342
+ var DEFAULT_CODEGRAPH_EXCLUDES;
26343
+ var init_exclude = __esm({
26344
+ "src/codegraph/exclude.ts"() {
26345
+ "use strict";
26346
+ init_esm_shims();
26347
+ DEFAULT_CODEGRAPH_EXCLUDES = [
26348
+ "node_modules/**",
26349
+ "dist/**",
26350
+ "build/**",
26351
+ "coverage/**",
26352
+ ".next/**",
26353
+ ".turbo/**",
26354
+ ".git/**",
26355
+ ".tmp/**",
26356
+ ".worktrees/**",
26357
+ ".claude/worktrees/**"
26358
+ ];
26359
+ }
26360
+ });
26361
+
26289
26362
  // src/codegraph/lite-provider.ts
26290
26363
  import { createHash as createHash4 } from "crypto";
26291
26364
  import { readdirSync as readdirSync2, readFileSync as readFileSync8, statSync as statSync2 } from "fs";
@@ -26301,18 +26374,6 @@ function languageForPath(path29) {
26301
26374
  const ext = extension(path29);
26302
26375
  return LANGUAGE_BY_EXTENSION.get(ext) ?? "unknown";
26303
26376
  }
26304
- function isExcluded(path29, exclude) {
26305
- const normalized = normalizeCodePath(path29);
26306
- return exclude.some((pattern) => {
26307
- const p2 = normalizeCodePath(pattern);
26308
- if (p2.endsWith("/**")) {
26309
- const base = p2.slice(0, -3);
26310
- return normalized === base || normalized.startsWith(`${base}/`);
26311
- }
26312
- if (p2.startsWith("**/")) return normalized.endsWith(p2.slice(3));
26313
- return normalized === p2 || normalized.startsWith(`${p2}/`);
26314
- });
26315
- }
26316
26377
  function walk(root, exclude, maxFiles) {
26317
26378
  const out = [];
26318
26379
  const visit = (dir) => {
@@ -26326,9 +26387,10 @@ function walk(root, exclude, maxFiles) {
26326
26387
  for (const entry of entries) {
26327
26388
  const abs = join20(dir, entry.name);
26328
26389
  const rel = normalizeCodePath(relative(root, abs));
26329
- if (isExcluded(rel, exclude)) continue;
26390
+ if (isCodeGraphExcludedPath(rel, exclude)) continue;
26330
26391
  if (entry.isDirectory()) {
26331
- if (entry.name === ".git" || entry.name === "node_modules") continue;
26392
+ if (entry.name === ".git" || entry.name === ".worktrees" || entry.name === ".tmp" || entry.name === "node_modules") continue;
26393
+ if (rel === ".claude/worktrees" || rel.startsWith(".claude/worktrees/")) continue;
26332
26394
  visit(abs);
26333
26395
  if (out.length >= maxFiles) return;
26334
26396
  continue;
@@ -26413,15 +26475,7 @@ function extractImportEdges(projectId, file, text, indexedAt) {
26413
26475
  return edges;
26414
26476
  }
26415
26477
  async function indexProjectLite(options2) {
26416
- const exclude = options2.exclude ?? [
26417
- "node_modules/**",
26418
- "dist/**",
26419
- "build/**",
26420
- "coverage/**",
26421
- ".next/**",
26422
- ".turbo/**",
26423
- ".git/**"
26424
- ];
26478
+ const exclude = normalizeCodeGraphExcludePatterns(options2.exclude);
26425
26479
  const maxFiles = options2.maxFiles ?? 5e3;
26426
26480
  const indexedAt = (/* @__PURE__ */ new Date()).toISOString();
26427
26481
  const paths = walk(options2.projectRoot, exclude, maxFiles);
@@ -26460,6 +26514,7 @@ var init_lite_provider = __esm({
26460
26514
  "use strict";
26461
26515
  init_esm_shims();
26462
26516
  init_ids();
26517
+ init_exclude();
26463
26518
  LANGUAGE_BY_EXTENSION = /* @__PURE__ */ new Map([
26464
26519
  [".ts", "typescript"],
26465
26520
  [".tsx", "typescript"],
@@ -26636,23 +26691,17 @@ function countLanguages(files) {
26636
26691
  }
26637
26692
  return [...counts.entries()].map(([language, files2]) => ({ language, files: files2 })).sort((a3, b3) => a3.language.localeCompare(b3.language));
26638
26693
  }
26639
- function normalizePath2(path29) {
26640
- return path29.replace(/\\/g, "/");
26641
- }
26642
- function isGeneratedPath(path29) {
26643
- return /(^|\/)(dist|build|coverage|\.next|\.turbo|node_modules)\//i.test(normalizePath2(path29));
26644
- }
26645
26694
  function suggestedReadRank(path29) {
26646
- const normalized = normalizePath2(path29);
26695
+ const normalized = path29.replace(/\\/g, "/");
26647
26696
  if (normalized.startsWith("src/")) return 0;
26648
26697
  if (normalized.startsWith("tests/") || normalized.startsWith("test/")) return 0;
26649
26698
  if (normalized.startsWith("packages/") && normalized.includes("/src/")) return 2;
26650
26699
  return 3;
26651
26700
  }
26652
- function compactSuggestedReads(paths, limit = 8) {
26653
- return uniq(paths).filter((path29) => !isGeneratedPath(path29)).sort((a3, b3) => suggestedReadRank(a3) - suggestedReadRank(b3)).slice(0, limit);
26701
+ function compactSuggestedReads(paths, limit = 8, exclude) {
26702
+ return uniq(paths).filter((path29) => !isCodeGraphExcludedPath(path29, exclude)).sort((a3, b3) => suggestedReadRank(a3) - suggestedReadRank(b3)).slice(0, limit);
26654
26703
  }
26655
- function collectGraph(store2, projectId, observations2) {
26704
+ function collectGraph(store2, projectId, observations2, exclude) {
26656
26705
  const files = store2.listFiles(projectId);
26657
26706
  const symbols = files.flatMap((file) => store2.listSymbolsForFile(file.id));
26658
26707
  const filesById = new Map(files.map((file) => [file.id, file]));
@@ -26674,7 +26723,9 @@ function collectGraph(store2, projectId, observations2) {
26674
26723
  freshness[result.status] += 1;
26675
26724
  const observation = observationsById.get(ref.observationId);
26676
26725
  if (!observation) continue;
26677
- if (result.status === "current" && file) suggestedReads.push(file.path);
26726
+ const excluded = file ? isCodeGraphExcludedPath(file.path, exclude) : false;
26727
+ if (result.status === "current" && file && !excluded) suggestedReads.push(file.path);
26728
+ if (excluded) continue;
26678
26729
  sources.push({
26679
26730
  observationId: observation.id,
26680
26731
  title: observation.title,
@@ -26691,12 +26742,12 @@ function collectGraph(store2, projectId, observations2) {
26691
26742
  refs,
26692
26743
  freshness,
26693
26744
  sources,
26694
- suggestedReads: compactSuggestedReads(suggestedReads)
26745
+ suggestedReads: compactSuggestedReads(suggestedReads, 8, exclude)
26695
26746
  };
26696
26747
  }
26697
26748
  function buildProjectContextOverview(input) {
26698
26749
  const active = activeObservations(input.observations, input.project.id);
26699
- const graph = collectGraph(input.store, input.project.id, active);
26750
+ const graph = collectGraph(input.store, input.project.id, active, input.exclude);
26700
26751
  const status = input.store.status(input.project.id);
26701
26752
  return {
26702
26753
  project: input.project,
@@ -26720,7 +26771,7 @@ function buildProjectContextOverview(input) {
26720
26771
  function buildProjectContextExplain(input) {
26721
26772
  const overview = buildProjectContextOverview(input);
26722
26773
  const active = activeObservations(input.observations, input.project.id);
26723
- const graph = collectGraph(input.store, input.project.id, active);
26774
+ const graph = collectGraph(input.store, input.project.id, active, input.exclude);
26724
26775
  return {
26725
26776
  project: input.project,
26726
26777
  sources: graph.sources.sort((a3, b3) => a3.observationId - b3.observationId || (a3.path ?? "").localeCompare(b3.path ?? "")),
@@ -26774,11 +26825,12 @@ var init_project_context = __esm({
26774
26825
  "use strict";
26775
26826
  init_esm_shims();
26776
26827
  init_freshness2();
26828
+ init_exclude();
26777
26829
  }
26778
26830
  });
26779
26831
 
26780
26832
  // src/codegraph/task-lens.ts
26781
- function normalizePath3(path29) {
26833
+ function normalizePath2(path29) {
26782
26834
  return path29.replace(/\\/g, "/");
26783
26835
  }
26784
26836
  function tokenize3(text) {
@@ -26808,7 +26860,7 @@ function resolveTaskLens(task) {
26808
26860
  return best.score > 0 ? LENSES[best.id] : LENSES.general;
26809
26861
  }
26810
26862
  function pathKindScore(path29, lens) {
26811
- const normalized = normalizePath3(path29).toLowerCase();
26863
+ const normalized = normalizePath2(path29).toLowerCase();
26812
26864
  const name = normalized.split("/").pop() ?? normalized;
26813
26865
  const inDocs = normalized.startsWith("docs/") || name === "readme.md" || name.includes("readme");
26814
26866
  const isTest = /(^|\/)(tests?|__tests__|spec|fixtures?)\//.test(normalized) || /\.(test|spec)\.[cm]?[jt]sx?$/.test(normalized) || /\.(test|spec)\.py$/.test(normalized);
@@ -26857,7 +26909,7 @@ function sourceTaskMatchScore(source, task) {
26857
26909
  return 0;
26858
26910
  }
26859
26911
  function fallbackPathRank(path29) {
26860
- const normalized = normalizePath3(path29);
26912
+ const normalized = normalizePath2(path29);
26861
26913
  if (normalized.startsWith("src/")) return 0;
26862
26914
  if (normalized.startsWith("tests/") || normalized.startsWith("test/")) return 1;
26863
26915
  if (normalized.startsWith("packages/") && normalized.includes("/src/")) return 2;
@@ -26866,7 +26918,7 @@ function fallbackPathRank(path29) {
26866
26918
  }
26867
26919
  function rankLensPaths(paths, lens, task) {
26868
26920
  const tokens = tokenize3(task ?? "");
26869
- return [...new Set(paths.map(normalizePath3))].map((path29, index) => ({
26921
+ return [...new Set(paths.map(normalizePath2))].map((path29, index) => ({
26870
26922
  path: path29,
26871
26923
  index,
26872
26924
  score: pathKindScore(path29, lens) + tokenScore(path29, tokens),
@@ -27120,6 +27172,7 @@ async function buildAutoProjectContext(input) {
27120
27172
  const now = input.now ?? /* @__PURE__ */ new Date();
27121
27173
  const task = input.task?.trim();
27122
27174
  const lens = resolveTaskLens(task);
27175
+ const exclude = input.exclude ?? getResolvedConfig({ projectRoot: input.project.rootPath }).codegraph.excludePatterns;
27123
27176
  const store2 = new CodeGraphStore();
27124
27177
  await store2.init(input.dataDir);
27125
27178
  const initialStatus = store2.status(input.project.id);
@@ -27137,7 +27190,8 @@ async function buildAutoProjectContext(input) {
27137
27190
  try {
27138
27191
  const indexed = await indexProjectLite({
27139
27192
  projectId: input.project.id,
27140
- projectRoot: input.project.rootPath
27193
+ projectRoot: input.project.rootPath,
27194
+ exclude
27141
27195
  });
27142
27196
  store2.replaceProjectIndex(input.project.id, indexed);
27143
27197
  const backfill = await backfillMissingObservationCodeRefs(
@@ -27157,12 +27211,14 @@ async function buildAutoProjectContext(input) {
27157
27211
  const overview = buildProjectContextOverview({
27158
27212
  project: input.project,
27159
27213
  store: store2,
27160
- observations: input.observations
27214
+ observations: input.observations,
27215
+ exclude
27161
27216
  });
27162
27217
  const explain = buildProjectContextExplain({
27163
27218
  project: input.project,
27164
27219
  store: store2,
27165
- observations: input.observations
27220
+ observations: input.observations,
27221
+ exclude
27166
27222
  });
27167
27223
  return {
27168
27224
  project: input.project,
@@ -27372,6 +27428,7 @@ var init_auto_context = __esm({
27372
27428
  "src/codegraph/auto-context.ts"() {
27373
27429
  "use strict";
27374
27430
  init_esm_shims();
27431
+ init_resolved_config();
27375
27432
  init_binder();
27376
27433
  init_current_facts();
27377
27434
  init_lite_provider();
@@ -27508,9 +27565,6 @@ function tokenize4(text) {
27508
27565
  function timestampOf(observation) {
27509
27566
  return Date.parse(observation.updatedAt ?? observation.createdAt ?? "") || 0;
27510
27567
  }
27511
- function isGeneratedPath2(path29) {
27512
- return /(^|\/)(dist|build|coverage|\.next|\.turbo|node_modules)\//i.test(path29.replace(/\\/g, "/"));
27513
- }
27514
27568
  function relevanceScore(observation, taskTokens) {
27515
27569
  if (taskTokens.length === 0) return 0;
27516
27570
  const title = observation.title.toLowerCase();
@@ -27561,7 +27615,8 @@ function assembleContextPackForTask(input) {
27561
27615
  refs,
27562
27616
  files,
27563
27617
  symbols,
27564
- suggestedVerification: input.suggestedVerification
27618
+ suggestedVerification: input.suggestedVerification,
27619
+ exclude: input.exclude
27565
27620
  });
27566
27621
  }
27567
27622
  function assembleContextPack(input) {
@@ -27580,6 +27635,7 @@ function assembleContextPack(input) {
27580
27635
  observationIdsWithRefs.add(ref.observationId);
27581
27636
  const file = ref.fileId ? files.get(ref.fileId) : void 0;
27582
27637
  const symbol = ref.symbolId ? symbols.get(ref.symbolId) : void 0;
27638
+ if (file && isCodeGraphExcludedPath(file.path, input.exclude)) continue;
27583
27639
  const freshness = evaluateCodeRefFreshness(ref, file, symbol);
27584
27640
  if (freshness.status === "current") {
27585
27641
  const memoryKey = `${observation.id}:${freshness.status}`;
@@ -27645,8 +27701,8 @@ function buildContextPackPrompt(pack) {
27645
27701
  const reliableMemories = pack.memories.filter((memory) => memory.status === "current");
27646
27702
  const unboundMemories = pack.memories.filter((memory) => memory.status === "unbound");
27647
27703
  const lines = ["## Task", pack.task, "", "## Reliable Memories"];
27648
- const visibleCodeFacts = pack.codeFacts.filter((fact) => !isGeneratedPath2(fact.path)).slice(0, 5);
27649
- const visibleSuggestedReads = pack.suggestedReads.filter((path29) => !isGeneratedPath2(path29)).slice(0, 5);
27704
+ const visibleCodeFacts = pack.codeFacts.filter((fact) => !isCodeGraphExcludedPath(fact.path)).slice(0, 5);
27705
+ const visibleSuggestedReads = pack.suggestedReads.filter((path29) => !isCodeGraphExcludedPath(path29)).slice(0, 5);
27650
27706
  if (reliableMemories.length === 0) lines.push("- none");
27651
27707
  for (const memory of reliableMemories) {
27652
27708
  lines.push(`- #${memory.id} ${memory.status}: [${memory.type}] ${memory.title} (${memory.reason})`);
@@ -27681,6 +27737,7 @@ var init_context_pack = __esm({
27681
27737
  "use strict";
27682
27738
  init_esm_shims();
27683
27739
  init_freshness2();
27740
+ init_exclude();
27684
27741
  }
27685
27742
  });
27686
27743
 
@@ -27719,6 +27776,7 @@ var init_codegraph = __esm({
27719
27776
  init_lite_provider();
27720
27777
  init_context_pack();
27721
27778
  init_binder();
27779
+ init_resolved_config();
27722
27780
  init_observations();
27723
27781
  init_operator_shared();
27724
27782
  codegraph_default = defineCommand({
@@ -27741,6 +27799,7 @@ var init_codegraph = __esm({
27741
27799
  const store2 = new CodeGraphStore();
27742
27800
  await store2.init(dataDir);
27743
27801
  const explicitAction = Boolean(positional[0] || args.action);
27802
+ const exclude = getResolvedConfig({ projectRoot: project.rootPath }).codegraph.excludePatterns;
27744
27803
  switch (action) {
27745
27804
  case "status": {
27746
27805
  const status = store2.status(project.id);
@@ -27753,7 +27812,8 @@ ${formatUsageHint()}`;
27753
27812
  case "refresh": {
27754
27813
  const indexed = await indexProjectLite({
27755
27814
  projectId: project.id,
27756
- projectRoot: project.rootPath
27815
+ projectRoot: project.rootPath,
27816
+ exclude
27757
27817
  });
27758
27818
  store2.replaceProjectIndex(project.id, indexed);
27759
27819
  const activeObservations2 = getAllObservations().filter((obs) => obs.projectId === project.id && (obs.status ?? "active") === "active");
@@ -27784,7 +27844,8 @@ ${formatUsageHint()}`;
27784
27844
  projectId: project.id,
27785
27845
  task,
27786
27846
  observations: observations2,
27787
- limit
27847
+ limit,
27848
+ exclude
27788
27849
  });
27789
27850
  emitResult({ project, pack }, buildContextPackPrompt(pack), asJson);
27790
27851
  return;
@@ -43369,12 +43430,12 @@ var init_stdio2 = __esm({
43369
43430
  this.onclose?.();
43370
43431
  }
43371
43432
  send(message) {
43372
- return new Promise((resolve3) => {
43433
+ return new Promise((resolve4) => {
43373
43434
  const json = serializeMessage(message);
43374
43435
  if (this._stdout.write(json)) {
43375
- resolve3();
43436
+ resolve4();
43376
43437
  } else {
43377
- this._stdout.once("drain", resolve3);
43438
+ this._stdout.once("drain", resolve4);
43378
43439
  }
43379
43440
  });
43380
43441
  }
@@ -45907,7 +45968,7 @@ var init_protocol = __esm({
45907
45968
  return;
45908
45969
  }
45909
45970
  const pollInterval = task2.pollInterval ?? this._options?.defaultTaskPollInterval ?? 1e3;
45910
- await new Promise((resolve3) => setTimeout(resolve3, pollInterval));
45971
+ await new Promise((resolve4) => setTimeout(resolve4, pollInterval));
45911
45972
  options2?.signal?.throwIfAborted();
45912
45973
  }
45913
45974
  } catch (error2) {
@@ -45924,7 +45985,7 @@ var init_protocol = __esm({
45924
45985
  */
45925
45986
  request(request, resultSchema, options2) {
45926
45987
  const { relatedRequestId, resumptionToken, onresumptiontoken, task, relatedTask } = options2 ?? {};
45927
- return new Promise((resolve3, reject) => {
45988
+ return new Promise((resolve4, reject) => {
45928
45989
  const earlyReject = (error2) => {
45929
45990
  reject(error2);
45930
45991
  };
@@ -46002,7 +46063,7 @@ var init_protocol = __esm({
46002
46063
  if (!parseResult.success) {
46003
46064
  reject(parseResult.error);
46004
46065
  } else {
46005
- resolve3(parseResult.data);
46066
+ resolve4(parseResult.data);
46006
46067
  }
46007
46068
  } catch (error2) {
46008
46069
  reject(error2);
@@ -46263,12 +46324,12 @@ var init_protocol = __esm({
46263
46324
  }
46264
46325
  } catch {
46265
46326
  }
46266
- return new Promise((resolve3, reject) => {
46327
+ return new Promise((resolve4, reject) => {
46267
46328
  if (signal.aborted) {
46268
46329
  reject(new McpError(ErrorCode.InvalidRequest, "Request cancelled"));
46269
46330
  return;
46270
46331
  }
46271
- const timeoutId = setTimeout(resolve3, interval);
46332
+ const timeoutId = setTimeout(resolve4, interval);
46272
46333
  signal.addEventListener("abort", () => {
46273
46334
  clearTimeout(timeoutId);
46274
46335
  reject(new McpError(ErrorCode.InvalidRequest, "Request cancelled"));
@@ -49316,7 +49377,7 @@ var require_compile = __commonJS({
49316
49377
  const schOrFunc = root.refs[ref];
49317
49378
  if (schOrFunc)
49318
49379
  return schOrFunc;
49319
- let _sch = resolve3.call(this, root, ref);
49380
+ let _sch = resolve4.call(this, root, ref);
49320
49381
  if (_sch === void 0) {
49321
49382
  const schema = (_a = root.localRefs) === null || _a === void 0 ? void 0 : _a[ref];
49322
49383
  const { schemaId } = this.opts;
@@ -49343,7 +49404,7 @@ var require_compile = __commonJS({
49343
49404
  function sameSchemaEnv(s1, s2) {
49344
49405
  return s1.schema === s2.schema && s1.root === s2.root && s1.baseId === s2.baseId;
49345
49406
  }
49346
- function resolve3(root, ref) {
49407
+ function resolve4(root, ref) {
49347
49408
  let sch;
49348
49409
  while (typeof (sch = this.refs[ref]) == "string")
49349
49410
  ref = sch;
@@ -49977,7 +50038,7 @@ var require_fast_uri = __commonJS({
49977
50038
  }
49978
50039
  return uri;
49979
50040
  }
49980
- function resolve3(baseURI, relativeURI, options2) {
50041
+ function resolve4(baseURI, relativeURI, options2) {
49981
50042
  const schemelessOptions = options2 ? Object.assign({ scheme: "null" }, options2) : { scheme: "null" };
49982
50043
  const resolved = resolveComponent(parse5(baseURI, schemelessOptions), parse5(relativeURI, schemelessOptions), schemelessOptions, true);
49983
50044
  schemelessOptions.skipEscape = true;
@@ -50235,7 +50296,7 @@ var require_fast_uri = __commonJS({
50235
50296
  var fastUri = {
50236
50297
  SCHEMES,
50237
50298
  normalize,
50238
- resolve: resolve3,
50299
+ resolve: resolve4,
50239
50300
  resolveComponent,
50240
50301
  equal,
50241
50302
  serialize,
@@ -54417,7 +54478,7 @@ var init_mcp = __esm({
54417
54478
  let task = createTaskResult.task;
54418
54479
  const pollInterval = task.pollInterval ?? 5e3;
54419
54480
  while (task.status !== "completed" && task.status !== "failed" && task.status !== "cancelled") {
54420
- await new Promise((resolve3) => setTimeout(resolve3, pollInterval));
54481
+ await new Promise((resolve4) => setTimeout(resolve4, pollInterval));
54421
54482
  const updatedTask = await extra.taskStore.getTask(taskId);
54422
54483
  if (!updatedTask) {
54423
54484
  throw new McpError(ErrorCode.InternalError, `Task ${taskId} not found during polling`);
@@ -54961,9 +55022,9 @@ async function createAutoRelations(obs, extracted, graphManager) {
54961
55022
  }
54962
55023
  }
54963
55024
  for (const file of obs.filesModified) {
54964
- const basename4 = file.split("/").pop()?.replace(/\.\w+$/, "") ?? "";
54965
- if (basename4.length < 3 || basename4.toLowerCase() === selfName) continue;
54966
- const matchedEntity = graphManager.findEntityByName(basename4);
55025
+ const basename5 = file.split("/").pop()?.replace(/\.\w+$/, "") ?? "";
55026
+ if (basename5.length < 3 || basename5.toLowerCase() === selfName) continue;
55027
+ const matchedEntity = graphManager.findEntityByName(basename5);
54967
55028
  if (matchedEntity) {
54968
55029
  relations.push({
54969
55030
  from: obs.entityName,
@@ -54973,12 +55034,12 @@ async function createAutoRelations(obs, extracted, graphManager) {
54973
55034
  }
54974
55035
  }
54975
55036
  if (relations.length === 0) return 0;
54976
- const unique = relations.filter(
55037
+ const unique2 = relations.filter(
54977
55038
  (r4, i2, arr) => arr.findIndex(
54978
55039
  (o3) => o3.from === r4.from && o3.to === r4.to && o3.relationType === r4.relationType
54979
55040
  ) === i2
54980
55041
  );
54981
- const created = await graphManager.createRelations(unique);
55042
+ const created = await graphManager.createRelations(unique2);
54982
55043
  return created.length;
54983
55044
  }
54984
55045
  var init_auto_relations = __esm({
@@ -56506,7 +56567,6 @@ var require_loader = __commonJS({
56506
56567
  this.legacy = options2["legacy"] || false;
56507
56568
  this.json = options2["json"] || false;
56508
56569
  this.listener = options2["listener"] || null;
56509
- this.maxTotalMergeKeys = typeof options2["maxTotalMergeKeys"] === "number" ? options2["maxTotalMergeKeys"] : 1e4;
56510
56570
  this.implicitTypes = this.schema.compiledImplicit;
56511
56571
  this.typeMap = this.schema.compiledTypeMap;
56512
56572
  this.length = input.length;
@@ -56514,7 +56574,6 @@ var require_loader = __commonJS({
56514
56574
  this.line = 0;
56515
56575
  this.lineStart = 0;
56516
56576
  this.lineIndent = 0;
56517
- this.totalMergeKeys = 0;
56518
56577
  this.documents = [];
56519
56578
  }
56520
56579
  function generateError(state, message) {
@@ -56599,9 +56658,6 @@ var require_loader = __commonJS({
56599
56658
  sourceKeys = Object.keys(source);
56600
56659
  for (index = 0, quantity = sourceKeys.length; index < quantity; index += 1) {
56601
56660
  key = sourceKeys[index];
56602
- if (state.maxTotalMergeKeys !== -1 && ++state.totalMergeKeys > state.maxTotalMergeKeys) {
56603
- throwError(state, "merge keys exceeded maxTotalMergeKeys (" + state.maxTotalMergeKeys + ")");
56604
- }
56605
56661
  if (!_hasOwnProperty.call(destination, key)) {
56606
56662
  setProperty(destination, key, source[key]);
56607
56663
  overridableKeys[key] = true;
@@ -60918,7 +60974,7 @@ async function handleApi(req, res, dataDir, projectId, projectName, baseDir, pro
60918
60974
  }
60919
60975
  case "/config": {
60920
60976
  const os5 = await import("os");
60921
- const { existsSync: existsSync25 } = await import("fs");
60977
+ const { existsSync: existsSync26 } = await import("fs");
60922
60978
  const { join: join32 } = await import("path");
60923
60979
  let yml = {};
60924
60980
  const configProjectRoot = effectiveProjectRoot;
@@ -60954,7 +61010,7 @@ async function handleApi(req, res, dataDir, projectId, projectName, baseDir, pro
60954
61010
  if (fpath === null) {
60955
61011
  files[key] = { exists: false, path: "unavailable", unavailable: true };
60956
61012
  } else {
60957
- files[key] = { exists: existsSync25(fpath), path: fpath };
61013
+ files[key] = { exists: existsSync26(fpath), path: fpath };
60958
61014
  }
60959
61015
  }
60960
61016
  } catch {
@@ -61329,10 +61385,10 @@ async function buildTeamSnapshot(dataDir, projectId, scope, mode) {
61329
61385
  }
61330
61386
  }
61331
61387
  function readBody(req) {
61332
- return new Promise((resolve3, reject) => {
61388
+ return new Promise((resolve4, reject) => {
61333
61389
  const chunks = [];
61334
61390
  req.on("data", (c5) => chunks.push(c5));
61335
- req.on("end", () => resolve3(Buffer.concat(chunks).toString("utf-8")));
61391
+ req.on("end", () => resolve4(Buffer.concat(chunks).toString("utf-8")));
61336
61392
  req.on("error", reject);
61337
61393
  });
61338
61394
  }
@@ -61420,7 +61476,7 @@ async function startDashboard(dataDir, port, staticDir, projectId, projectName,
61420
61476
  await serveStatic(req, res, resolvedStaticDir);
61421
61477
  }
61422
61478
  });
61423
- return new Promise((resolve3, reject) => {
61479
+ return new Promise((resolve4, reject) => {
61424
61480
  server.on("error", (err) => {
61425
61481
  if (err.code === "EADDRINUSE") {
61426
61482
  console.error(`Port ${port} is already in use. Try: memorix dashboard --port ${port + 1}`);
@@ -61444,7 +61500,7 @@ async function startDashboard(dataDir, port, staticDir, projectId, projectName,
61444
61500
  Press Ctrl+C to stop
61445
61501
  `);
61446
61502
  if (autoOpen) openBrowser(url);
61447
- resolve3();
61503
+ resolve4();
61448
61504
  });
61449
61505
  });
61450
61506
  }
@@ -61960,7 +62016,7 @@ The path should point to a directory containing a .git folder.`
61960
62016
  };
61961
62017
  const server = existingServer ?? new McpServer({
61962
62018
  name: "memorix",
61963
- version: true ? "1.1.7" : "1.0.1"
62019
+ version: true ? "1.1.9" : "1.0.1"
61964
62020
  });
61965
62021
  const originalRegisterTool = server.registerTool.bind(server);
61966
62022
  server.registerTool = ((name, ...args) => {
@@ -62662,15 +62718,18 @@ _Search mode: ${getLastSearchMode2(project.id)}_`;
62662
62718
  return withFreshIndex(async () => {
62663
62719
  const { CodeGraphStore: CodeGraphStore2 } = await Promise.resolve().then(() => (init_store(), store_exports));
62664
62720
  const { assembleContextPackForTask: assembleContextPackForTask2, buildContextPackPrompt: buildContextPackPrompt2 } = await Promise.resolve().then(() => (init_context_pack(), context_pack_exports));
62721
+ const { getResolvedConfig: getResolvedConfig2 } = await Promise.resolve().then(() => (init_resolved_config(), resolved_config_exports));
62665
62722
  const store2 = new CodeGraphStore2();
62666
62723
  await store2.init(projectDir2);
62724
+ const exclude = getResolvedConfig2({ projectRoot: project.rootPath }).codegraph.excludePatterns;
62667
62725
  const observations2 = getAllObservations().filter((obs) => obs.projectId === project.id && (obs.status ?? "active") === "active").reverse();
62668
62726
  const pack = assembleContextPackForTask2({
62669
62727
  store: store2,
62670
62728
  projectId: project.id,
62671
62729
  task,
62672
62730
  observations: observations2,
62673
- limit: typeof limit === "number" ? limit : 20
62731
+ limit: typeof limit === "number" ? limit : 20,
62732
+ exclude
62674
62733
  });
62675
62734
  const text = buildContextPackPrompt2(pack);
62676
62735
  return {
@@ -62969,12 +63028,12 @@ Run with dryRun=false to apply.`
62969
63028
  }]
62970
63029
  };
62971
63030
  }
62972
- const unique = [...new Set(toResolve)];
62973
- await resolveObservations2(unique, "resolved");
63031
+ const unique2 = [...new Set(toResolve)];
63032
+ await resolveObservations2(unique2, "resolved");
62974
63033
  return {
62975
63034
  content: [{
62976
63035
  type: "text",
62977
- text: `[CLEANUP] Deduplicated: resolved ${unique.length} memory(ies)
63036
+ text: `[CLEANUP] Deduplicated: resolved ${unique2.length} memory(ies)
62978
63037
 
62979
63038
  ${actions.join("\n")}`
62980
63039
  }]
@@ -63299,10 +63358,10 @@ Archived memories are hidden from default search but can be found with status: "
63299
63358
  );
63300
63359
  let enableKG = isToolInProfile("create_entities", toolProfile);
63301
63360
  try {
63302
- const { homedir: homedir33 } = await import("os");
63361
+ const { homedir: homedir34 } = await import("os");
63303
63362
  const { join: join32 } = await import("path");
63304
- const { readFile: readFile7 } = await import("fs/promises");
63305
- const raw = await readFile7(join32(homedir33(), ".memorix", "settings.json"), "utf-8");
63363
+ const { readFile: readFile8 } = await import("fs/promises");
63364
+ const raw = await readFile8(join32(homedir34(), ".memorix", "settings.json"), "utf-8");
63306
63365
  const s2 = JSON.parse(raw);
63307
63366
  if (s2.knowledgeGraph === true) enableKG = true;
63308
63367
  } catch {
@@ -64220,15 +64279,15 @@ ${json}
64220
64279
  if (inControlPlane) {
64221
64280
  const http = await import("http");
64222
64281
  const postData = JSON.stringify({ projectId: project.id, projectName: project.name });
64223
- await new Promise((resolve3) => {
64282
+ await new Promise((resolve4) => {
64224
64283
  const req = http.request({
64225
64284
  hostname: "127.0.0.1",
64226
64285
  port: portNum,
64227
64286
  path: "/api/set-current-project",
64228
64287
  method: "POST",
64229
64288
  headers: { "Content-Type": "application/json", "Content-Length": Buffer.byteLength(postData) }
64230
- }, () => resolve3());
64231
- req.on("error", () => resolve3());
64289
+ }, () => resolve4());
64290
+ req.on("error", () => resolve4());
64232
64291
  req.write(postData);
64233
64292
  req.end();
64234
64293
  });
@@ -64253,33 +64312,33 @@ ${json}
64253
64312
  }
64254
64313
  if (dashboardRunning) {
64255
64314
  const { createConnection } = await import("net");
64256
- const isAlive = await new Promise((resolve3) => {
64315
+ const isAlive = await new Promise((resolve4) => {
64257
64316
  const sock = createConnection(portNum, "127.0.0.1");
64258
64317
  sock.once("connect", () => {
64259
64318
  sock.destroy();
64260
- resolve3(true);
64319
+ resolve4(true);
64261
64320
  });
64262
64321
  sock.once("error", () => {
64263
64322
  sock.destroy();
64264
- resolve3(false);
64323
+ resolve4(false);
64265
64324
  });
64266
64325
  setTimeout(() => {
64267
64326
  sock.destroy();
64268
- resolve3(false);
64327
+ resolve4(false);
64269
64328
  }, 1e3);
64270
64329
  });
64271
64330
  if (isAlive) {
64272
64331
  const http = await import("http");
64273
64332
  const postData = JSON.stringify({ projectId: project.id, projectName: project.name });
64274
- await new Promise((resolve3) => {
64333
+ await new Promise((resolve4) => {
64275
64334
  const req = http.request({
64276
64335
  hostname: "127.0.0.1",
64277
64336
  port: portNum,
64278
64337
  path: "/api/set-current-project",
64279
64338
  method: "POST",
64280
64339
  headers: { "Content-Type": "application/json", "Content-Length": Buffer.byteLength(postData) }
64281
- }, () => resolve3());
64282
- req.on("error", () => resolve3());
64340
+ }, () => resolve4());
64341
+ req.on("error", () => resolve4());
64283
64342
  req.write(postData);
64284
64343
  req.end();
64285
64344
  });
@@ -64325,18 +64384,18 @@ ${json}
64325
64384
  dashboardRunning = false;
64326
64385
  });
64327
64386
  const { createConnection } = await import("net");
64328
- await new Promise((resolve3) => {
64387
+ await new Promise((resolve4) => {
64329
64388
  const deadline = Date.now() + 5e3;
64330
64389
  const tryConnect = () => {
64331
64390
  const sock = createConnection(portNum, "127.0.0.1");
64332
64391
  sock.once("connect", () => {
64333
64392
  sock.destroy();
64334
- resolve3();
64393
+ resolve4();
64335
64394
  });
64336
64395
  sock.once("error", () => {
64337
64396
  sock.destroy();
64338
64397
  if (Date.now() < deadline) setTimeout(tryConnect, 100);
64339
- else resolve3();
64398
+ else resolve4();
64340
64399
  });
64341
64400
  };
64342
64401
  tryConnect();
@@ -64898,10 +64957,10 @@ Preview: ${analysis.description.slice(0, 300)}${analysis.description.length > 30
64898
64957
  const { ensureHooksDir: ensureHooksDir2 } = await Promise.resolve().then(() => (init_hooks_path(), hooks_path_exports));
64899
64958
  const resolved = ensureHooksDir2(project.rootPath);
64900
64959
  if (resolved) {
64901
- const { existsSync: existsSync25, readFileSync: readFileSync22, writeFileSync: writeFileSync11, chmodSync: chmodSync2 } = await import("fs");
64960
+ const { existsSync: existsSync26, readFileSync: readFileSync22, writeFileSync: writeFileSync11, chmodSync: chmodSync2 } = await import("fs");
64902
64961
  const { hookPath } = resolved;
64903
64962
  const HOOK_MARKER3 = "# [memorix-git-hook]";
64904
- const needsInstall = !existsSync25(hookPath) || !readFileSync22(hookPath, "utf-8").includes(HOOK_MARKER3);
64963
+ const needsInstall = !existsSync26(hookPath) || !readFileSync22(hookPath, "utf-8").includes(HOOK_MARKER3);
64905
64964
  if (needsInstall) {
64906
64965
  const hookScript = `#!/bin/sh
64907
64966
  ${HOOK_MARKER3}
@@ -64910,7 +64969,7 @@ if command -v memorix >/dev/null 2>&1; then
64910
64969
  memorix ingest commit --auto >/dev/null 2>&1 &
64911
64970
  fi
64912
64971
  `;
64913
- if (existsSync25(hookPath)) {
64972
+ if (existsSync26(hookPath)) {
64914
64973
  const existing = readFileSync22(hookPath, "utf-8");
64915
64974
  writeFileSync11(hookPath, existing.trimEnd() + `
64916
64975
 
@@ -65362,10 +65421,10 @@ function describeAutoUpdateFailure(error2, timeoutMs) {
65362
65421
  async function fetchLatestVersion() {
65363
65422
  try {
65364
65423
  const { default: https } = await import("https");
65365
- return new Promise((resolve3) => {
65424
+ return new Promise((resolve4) => {
65366
65425
  const req = https.get(REGISTRY_URL, { timeout: 5e3 }, (res) => {
65367
65426
  if (res.statusCode !== 200) {
65368
- resolve3(null);
65427
+ resolve4(null);
65369
65428
  return;
65370
65429
  }
65371
65430
  let body = "";
@@ -65375,16 +65434,16 @@ async function fetchLatestVersion() {
65375
65434
  res.on("end", () => {
65376
65435
  try {
65377
65436
  const data = JSON.parse(body);
65378
- resolve3(data.version ?? null);
65437
+ resolve4(data.version ?? null);
65379
65438
  } catch {
65380
- resolve3(null);
65439
+ resolve4(null);
65381
65440
  }
65382
65441
  });
65383
65442
  });
65384
- req.on("error", () => resolve3(null));
65443
+ req.on("error", () => resolve4(null));
65385
65444
  req.on("timeout", () => {
65386
65445
  req.destroy();
65387
- resolve3(null);
65446
+ resolve4(null);
65388
65447
  });
65389
65448
  });
65390
65449
  } catch {
@@ -65533,7 +65592,7 @@ var init_serve = __esm({
65533
65592
  const { StdioServerTransport: StdioServerTransport2 } = await Promise.resolve().then(() => (init_stdio2(), stdio_exports));
65534
65593
  const { createMemorixServer: createMemorixServer2 } = await Promise.resolve().then(() => (init_server4(), server_exports2));
65535
65594
  const { detectProject: detectProject2, findGitInSubdirs: findGitInSubdirs2, isSystemDirectory: isSystemDirectory2 } = await Promise.resolve().then(() => (init_detector(), detector_exports));
65536
- const { homedir: homedir33 } = await import("os");
65595
+ const { homedir: homedir34 } = await import("os");
65537
65596
  const { resolveServeProject: resolveServeProject2 } = await Promise.resolve().then(() => (init_serve_shared(), serve_shared_exports));
65538
65597
  process.stdin.on("end", () => {
65539
65598
  console.error("[memorix] stdin closed \u2014 exiting");
@@ -65543,16 +65602,16 @@ var init_serve = __esm({
65543
65602
  try {
65544
65603
  safeCwd = process.cwd();
65545
65604
  } catch {
65546
- safeCwd = homedir33();
65605
+ safeCwd = homedir34();
65547
65606
  }
65548
- const { existsSync: existsSync25, readFileSync: readFileSync22 } = await import("fs");
65607
+ const { existsSync: existsSync26, readFileSync: readFileSync22 } = await import("fs");
65549
65608
  const path29 = await import("path");
65550
- const lastRootFile = path29.join(homedir33(), ".memorix", "last-project-root");
65609
+ const lastRootFile = path29.join(homedir34(), ".memorix", "last-project-root");
65551
65610
  let lastKnownProjectRoot;
65552
- if (existsSync25(lastRootFile)) {
65611
+ if (existsSync26(lastRootFile)) {
65553
65612
  try {
65554
65613
  const lastRoot = readFileSync22(lastRootFile, "utf-8").trim();
65555
- if (lastRoot && existsSync25(lastRoot)) {
65614
+ if (lastRoot && existsSync26(lastRoot)) {
65556
65615
  lastKnownProjectRoot = lastRoot;
65557
65616
  }
65558
65617
  } catch {
@@ -65564,7 +65623,7 @@ var init_serve = __esm({
65564
65623
  envProjectRoot: process.env.MEMORIX_PROJECT_ROOT,
65565
65624
  initCwd: process.env.INIT_CWD,
65566
65625
  processCwd: safeCwd,
65567
- homeDir: homedir33(),
65626
+ homeDir: homedir34(),
65568
65627
  lastKnownProjectRoot
65569
65628
  },
65570
65629
  { detectProject: detectProject2, findGitInSubdirs: findGitInSubdirs2, isSystemDirectory: isSystemDirectory2 }
@@ -65582,7 +65641,7 @@ var init_serve = __esm({
65582
65641
  if (detected) {
65583
65642
  try {
65584
65643
  const { writeFileSync: writeFileSync11, mkdirSync: mkdirSync11 } = await import("fs");
65585
- const memorixDir = path29.join(homedir33(), ".memorix");
65644
+ const memorixDir = path29.join(homedir34(), ".memorix");
65586
65645
  mkdirSync11(memorixDir, { recursive: true });
65587
65646
  writeFileSync11(path29.join(memorixDir, "last-project-root"), detected.rootPath, "utf-8");
65588
65647
  } catch {
@@ -65600,7 +65659,7 @@ var init_serve = __esm({
65600
65659
  try {
65601
65660
  const { writeFileSync: writeFileSync11, mkdirSync: mkdirSync11 } = await import("fs");
65602
65661
  const pathMod = await import("path");
65603
- const memorixDir = pathMod.join(homedir33(), ".memorix");
65662
+ const memorixDir = pathMod.join(homedir34(), ".memorix");
65604
65663
  mkdirSync11(memorixDir, { recursive: true });
65605
65664
  writeFileSync11(pathMod.join(memorixDir, "last-project-root"), rootPath, "utf-8");
65606
65665
  } catch {
@@ -66156,7 +66215,7 @@ var init_dist5 = __esm({
66156
66215
  });
66157
66216
  if (!chunk) {
66158
66217
  if (i2 === 1) {
66159
- await new Promise((resolve3) => setTimeout(resolve3));
66218
+ await new Promise((resolve4) => setTimeout(resolve4));
66160
66219
  maxReadCount = 3;
66161
66220
  continue;
66162
66221
  }
@@ -66664,9 +66723,9 @@ data:
66664
66723
  const initRequest = messages.find((m4) => isInitializeRequest(m4));
66665
66724
  const clientProtocolVersion = initRequest ? initRequest.params.protocolVersion : req.headers.get("mcp-protocol-version") ?? DEFAULT_NEGOTIATED_PROTOCOL_VERSION;
66666
66725
  if (this._enableJsonResponse) {
66667
- return new Promise((resolve3) => {
66726
+ return new Promise((resolve4) => {
66668
66727
  this._streamMapping.set(streamId, {
66669
- resolveJson: resolve3,
66728
+ resolveJson: resolve4,
66670
66729
  cleanup: () => {
66671
66730
  this._streamMapping.delete(streamId);
66672
66731
  }
@@ -67068,8 +67127,8 @@ var init_serve_http = __esm({
67068
67127
  const { isInitializeRequest: isInitializeRequest2 } = await Promise.resolve().then(() => (init_types4(), types_exports));
67069
67128
  const { createMemorixServer: createMemorixServer2 } = await Promise.resolve().then(() => (init_server4(), server_exports2));
67070
67129
  const { findGitInSubdirs: findGitInSubdirs2, detectProjectWithDiagnostics: detectProjectWithDiagnostics2 } = await Promise.resolve().then(() => (init_detector(), detector_exports));
67071
- const { existsSync: existsSync25, readFileSync: readFileSync22, writeFileSync: writeFileSync11, mkdirSync: mkdirSync11 } = await import("fs");
67072
- const { homedir: homedir33 } = await import("os");
67130
+ const { existsSync: existsSync26, readFileSync: readFileSync22, writeFileSync: writeFileSync11, mkdirSync: mkdirSync11 } = await import("fs");
67131
+ const { homedir: homedir34 } = await import("os");
67073
67132
  const earlyPath = await import("path");
67074
67133
  const port = parseInt(args.port || "3211", 10);
67075
67134
  const host = args.host || "127.0.0.1";
@@ -67078,15 +67137,15 @@ var init_serve_http = __esm({
67078
67137
  try {
67079
67138
  safeCwd = process.cwd();
67080
67139
  } catch {
67081
- safeCwd = homedir33();
67140
+ safeCwd = homedir34();
67082
67141
  }
67083
67142
  let projectRoot = args.cwd || process.env.MEMORIX_PROJECT_ROOT || safeCwd;
67084
- const lastRootFile = earlyPath.join(homedir33(), ".memorix", "last-project-root");
67143
+ const lastRootFile = earlyPath.join(homedir34(), ".memorix", "last-project-root");
67085
67144
  const initialCheck = detectProjectWithDiagnostics2(projectRoot);
67086
- if (!initialCheck.project && existsSync25(lastRootFile)) {
67145
+ if (!initialCheck.project && existsSync26(lastRootFile)) {
67087
67146
  try {
67088
67147
  const lastRoot = readFileSync22(lastRootFile, "utf-8").trim();
67089
- if (lastRoot && existsSync25(lastRoot)) {
67148
+ if (lastRoot && existsSync26(lastRoot)) {
67090
67149
  const lastCheck = detectProjectWithDiagnostics2(lastRoot);
67091
67150
  if (lastCheck.project) {
67092
67151
  console.error(`[memorix] No git at "${projectRoot}", restored last known project: ${lastRoot}`);
@@ -67129,13 +67188,13 @@ var init_serve_http = __esm({
67129
67188
  }
67130
67189
  }
67131
67190
  function parseBody(req) {
67132
- return new Promise((resolve3, reject) => {
67191
+ return new Promise((resolve4, reject) => {
67133
67192
  const chunks = [];
67134
67193
  req.on("data", (chunk) => chunks.push(chunk));
67135
67194
  req.on("end", () => {
67136
67195
  try {
67137
67196
  const body = Buffer.concat(chunks).toString("utf-8");
67138
- resolve3(body ? JSON.parse(body) : void 0);
67197
+ resolve4(body ? JSON.parse(body) : void 0);
67139
67198
  } catch (err) {
67140
67199
  reject(err);
67141
67200
  }
@@ -67294,8 +67353,8 @@ var init_serve_http = __esm({
67294
67353
  try {
67295
67354
  const { writeFileSync: writeFileSync12, mkdirSync: mkdirSync12 } = await import("fs");
67296
67355
  const pathMod = await import("path");
67297
- const { homedir: homedir34 } = await import("os");
67298
- const memorixDir = pathMod.join(homedir34(), ".memorix");
67356
+ const { homedir: homedir35 } = await import("os");
67357
+ const memorixDir = pathMod.join(homedir35(), ".memorix");
67299
67358
  mkdirSync12(memorixDir, { recursive: true });
67300
67359
  writeFileSync12(pathMod.join(memorixDir, "last-project-root"), rootPath, "utf-8");
67301
67360
  } catch {
@@ -67785,7 +67844,7 @@ var init_serve_http = __esm({
67785
67844
  if (apiPath === "/config") {
67786
67845
  const { projectId: configProjectId } = await resolveRequestProject(url);
67787
67846
  const os5 = await import("os");
67788
- const { existsSync: existsSync26 } = await import("fs");
67847
+ const { existsSync: existsSync27 } = await import("fs");
67789
67848
  const { join: join32 } = await import("path");
67790
67849
  const { loadYamlConfig: loadYamlConfig2 } = await Promise.resolve().then(() => (init_yaml_loader(), yaml_loader_exports));
67791
67850
  const { loadFileConfig: loadFileConfig2, loadDotenv: loadDotenv2, getLoadedEnvFiles: getLoadedEnvFiles2 } = await Promise.resolve().then(() => (init_config(), config_exports));
@@ -67807,7 +67866,7 @@ var init_serve_http = __esm({
67807
67866
  "legacy config.json": join32(home, ".memorix", "config.json")
67808
67867
  };
67809
67868
  for (const [key, fpath] of Object.entries(paths)) {
67810
- files[key] = { exists: existsSync26(fpath), path: fpath };
67869
+ files[key] = { exists: existsSync27(fpath), path: fpath };
67811
67870
  }
67812
67871
  } else {
67813
67872
  files["project memorix.yml"] = { exists: false, path: "unavailable", unavailable: true };
@@ -67818,7 +67877,7 @@ var init_serve_http = __esm({
67818
67877
  "legacy config.json": join32(home, ".memorix", "config.json")
67819
67878
  };
67820
67879
  for (const [key, fpath] of Object.entries(userPaths)) {
67821
- files[key] = { exists: existsSync26(fpath), path: fpath };
67880
+ files[key] = { exists: existsSync27(fpath), path: fpath };
67822
67881
  }
67823
67882
  }
67824
67883
  const values = [];
@@ -68300,7 +68359,7 @@ var init_status = __esm({
68300
68359
  const { getProjectDataDir: getProjectDataDir2 } = await Promise.resolve().then(() => (init_persistence(), persistence_exports));
68301
68360
  const { getEmbeddingProvider: getEmbeddingProvider2 } = await Promise.resolve().then(() => (init_provider(), provider_exports));
68302
68361
  const { getResolvedConfig: getResolvedConfig2, getResolvedAgentLane: getResolvedAgentLane2 } = await Promise.resolve().then(() => (init_resolved_config(), resolved_config_exports));
68303
- const { existsSync: existsSync25, readFileSync: readFileSync22 } = await import("fs");
68362
+ const { existsSync: existsSync26, readFileSync: readFileSync22 } = await import("fs");
68304
68363
  we("memorix status");
68305
68364
  const project = detectProject2();
68306
68365
  if (!project) {
@@ -68386,7 +68445,7 @@ Embedding: ${embeddingStatus}${embeddingHint}`,
68386
68445
  try {
68387
68446
  const { resolveHooksDir: resolveHooksDir2 } = await Promise.resolve().then(() => (init_hooks_path(), hooks_path_exports));
68388
68447
  const resolved2 = resolveHooksDir2(project.rootPath);
68389
- if (resolved2 && existsSync25(resolved2.hookPath)) {
68448
+ if (resolved2 && existsSync26(resolved2.hookPath)) {
68390
68449
  const hookContent = readFileSync22(resolved2.hookPath, "utf-8");
68391
68450
  if (hookContent.includes("# [memorix-git-hook]")) {
68392
68451
  diagLines.push(` Git hook: installed [OK]`);
@@ -69828,9 +69887,9 @@ async function handleHookEvent(input) {
69828
69887
  };
69829
69888
  }
69830
69889
  async function runHook(agentOverride, eventOverride) {
69831
- const rawInput = await new Promise((resolve3) => {
69890
+ const rawInput = await new Promise((resolve4) => {
69832
69891
  const chunks = [];
69833
- const finish = () => resolve3(Buffer.concat(chunks).toString("utf-8").trim());
69892
+ const finish = () => resolve4(Buffer.concat(chunks).toString("utf-8").trim());
69834
69893
  const timer = setTimeout(() => {
69835
69894
  process.stdin.removeAllListeners("data");
69836
69895
  process.stdin.removeAllListeners("end");
@@ -71466,7 +71525,7 @@ function getMemorixDir() {
71466
71525
  const home = process.env.HOME || process.env.USERPROFILE || "";
71467
71526
  return home.replace(/\\/g, "/") + "/.memorix";
71468
71527
  }
71469
- function normalizePath4(p2) {
71528
+ function normalizePath3(p2) {
71470
71529
  return process.platform === "win32" ? p2.replace(/\//g, "\\") : p2;
71471
71530
  }
71472
71531
  function getStateFilePath() {
@@ -71632,7 +71691,7 @@ async function doStart(port) {
71632
71691
  ` Port: ${port}`,
71633
71692
  ` Dashboard: http://127.0.0.1:${port}/`,
71634
71693
  ` MCP: http://127.0.0.1:${port}/mcp`,
71635
- ` Logs: ${normalizePath4(logFile)}`,
71694
+ ` Logs: ${normalizePath3(logFile)}`,
71636
71695
  ""
71637
71696
  ].join("\n");
71638
71697
  process.stderr.write(startMsg + "\n");
@@ -71646,7 +71705,7 @@ async function doStart(port) {
71646
71705
  }
71647
71706
  if (!isProcessRunning(pid)) {
71648
71707
  console.error("[ERROR] Background process exited unexpectedly.");
71649
- console.error(` Check logs: ${normalizePath4(logFile)}`);
71708
+ console.error(` Check logs: ${normalizePath3(logFile)}`);
71650
71709
  clearState();
71651
71710
  process.exitCode = 1;
71652
71711
  return;
@@ -71784,7 +71843,7 @@ async function doStatus() {
71784
71843
  if (state.instanceToken) console.log(` Instance: ${state.instanceToken.slice(0, 8)}\u2026`);
71785
71844
  console.log(` Dashboard: http://127.0.0.1:${state.port}/`);
71786
71845
  console.log(` MCP: http://127.0.0.1:${state.port}/mcp`);
71787
- console.log(` Logs: ${normalizePath4(state.logFile)}`);
71846
+ console.log(` Logs: ${normalizePath3(state.logFile)}`);
71788
71847
  if (health.ok && health.data) {
71789
71848
  const d3 = health.data;
71790
71849
  console.log("");
@@ -71974,6 +72033,492 @@ var init_background = __esm({
71974
72033
  }
71975
72034
  });
71976
72035
 
72036
+ // src/cli/commands/agent-integrations.ts
72037
+ var agent_integrations_exports = {};
72038
+ __export(agent_integrations_exports, {
72039
+ formatAgentIntegrationReport: () => formatAgentIntegrationReport,
72040
+ formatAgentRepairResult: () => formatAgentRepairResult,
72041
+ inspectAgentIntegrations: () => inspectAgentIntegrations,
72042
+ repairAgentIntegrations: () => repairAgentIntegrations
72043
+ });
72044
+ import { existsSync as existsSync21 } from "fs";
72045
+ import { mkdir as mkdir7, readFile as readFile7, writeFile as writeFile7 } from "fs/promises";
72046
+ import { basename as basename3, dirname as dirname7, resolve as resolve2 } from "path";
72047
+ import { homedir as homedir32 } from "os";
72048
+ function requestedAgents(agent) {
72049
+ const all = getSetupAgentTargets();
72050
+ if (!agent || agent === "all") return all;
72051
+ return all.includes(agent) ? [agent] : [];
72052
+ }
72053
+ function requestedMcpScopes(agent, scope) {
72054
+ if (scope === "local") return agent === "claude" ? ["local"] : [];
72055
+ if (scope === "project" || scope === "global") return [scope];
72056
+ return agent === "claude" ? ["local", "project", "global"] : ["project", "global"];
72057
+ }
72058
+ function requestedGuidanceScopes(scope) {
72059
+ if (scope === "project" || scope === "global") return [scope];
72060
+ if (scope === "local") return [];
72061
+ return ["project", "global"];
72062
+ }
72063
+ function unique(values) {
72064
+ return [...new Set(values)];
72065
+ }
72066
+ function worstStatus(statuses) {
72067
+ if (statuses.includes("repairable")) return "repairable";
72068
+ if (statuses.includes("missing")) return "missing";
72069
+ if (statuses.includes("ok")) return "ok";
72070
+ return "skipped";
72071
+ }
72072
+ function isMcpConfigAgent(agent) {
72073
+ return agent !== "pi";
72074
+ }
72075
+ function isActionableMcpRepairIssue(issue2) {
72076
+ return issue2 !== "memorix-server-missing";
72077
+ }
72078
+ function aggregateMcpStatus(checks) {
72079
+ const actionableRepair = checks.some(
72080
+ (check2) => check2.status === "repairable" && check2.issues.some(isActionableMcpRepairIssue)
72081
+ );
72082
+ if (actionableRepair) return "repairable";
72083
+ if (checks.some((check2) => check2.status === "ok")) return "ok";
72084
+ if (checks.some((check2) => check2.status === "repairable")) return "repairable";
72085
+ if (checks.some((check2) => check2.status === "missing")) return "missing";
72086
+ return "skipped";
72087
+ }
72088
+ function aggregateMcpIssues(checks) {
72089
+ const status = aggregateMcpStatus(checks);
72090
+ if (status === "repairable") {
72091
+ return unique(checks.filter((check2) => check2.status === "repairable").flatMap((check2) => check2.issues.filter(isActionableMcpRepairIssue)));
72092
+ }
72093
+ if (status === "missing") {
72094
+ return unique(checks.filter((check2) => check2.status === "missing").flatMap((check2) => check2.issues));
72095
+ }
72096
+ return [];
72097
+ }
72098
+ function aggregateGuidanceStatus(checks) {
72099
+ const projectCheck = checks.find((check2) => check2.scope === "project");
72100
+ if (projectCheck?.status === "repairable") return "repairable";
72101
+ if (checks.some((check2) => check2.status === "ok")) return "ok";
72102
+ if (checks.some((check2) => check2.status === "repairable")) return "repairable";
72103
+ if (checks.some((check2) => check2.status === "missing")) return "missing";
72104
+ return "skipped";
72105
+ }
72106
+ function aggregateGuidanceIssues(checks) {
72107
+ const status = aggregateGuidanceStatus(checks);
72108
+ if (status === "repairable") {
72109
+ const projectCheck = checks.find((check2) => check2.scope === "project");
72110
+ if (projectCheck?.status === "repairable") return projectCheck.issues;
72111
+ return unique(checks.filter((check2) => check2.status === "repairable").flatMap((check2) => check2.issues));
72112
+ }
72113
+ if (status === "missing") {
72114
+ return unique(checks.filter((check2) => check2.status === "missing").flatMap((check2) => check2.issues));
72115
+ }
72116
+ return [];
72117
+ }
72118
+ function asRecord2(value) {
72119
+ return value && typeof value === "object" && !Array.isArray(value) ? value : null;
72120
+ }
72121
+ function looksLikeStaleMemorixCommand(server) {
72122
+ const text = [server.command, ...server.args ?? []].join(" ");
72123
+ return /[\\/]\.worktrees[\\/]/i.test(text) || /[\\/]dist[\\/]cli[\\/]index\.js/i.test(text);
72124
+ }
72125
+ function isRecommendedStdioServer(server) {
72126
+ const commandBase = basename3(server.command).toLowerCase().replace(/\.(cmd|ps1|exe)$/i, "");
72127
+ return commandBase === "memorix" && server.args?.[0] === "serve";
72128
+ }
72129
+ function sanitizeServer(server) {
72130
+ if (server.url) {
72131
+ return {
72132
+ transport: "http",
72133
+ url: server.url,
72134
+ envKeys: server.env ? Object.keys(server.env) : void 0
72135
+ };
72136
+ }
72137
+ return {
72138
+ transport: "stdio",
72139
+ command: server.command,
72140
+ args: server.args ?? [],
72141
+ alwaysLoad: server.alwaysLoad,
72142
+ envKeys: server.env ? Object.keys(server.env) : void 0
72143
+ };
72144
+ }
72145
+ function normalizeProjectKey(projectRoot) {
72146
+ return resolve2(projectRoot).replace(/\\/g, "/").toLowerCase();
72147
+ }
72148
+ function defaultClaudeProjectKey(projectRoot) {
72149
+ return resolve2(projectRoot).replace(/\\/g, "/");
72150
+ }
72151
+ function getClaudeLocalConfigPath() {
72152
+ return `${homedir32()}/.claude.json`;
72153
+ }
72154
+ function coerceClaudeLocalServer(name, value) {
72155
+ const entry = asRecord2(value);
72156
+ if (!entry) return null;
72157
+ const args = Array.isArray(entry.args) ? entry.args.map(String) : [];
72158
+ return {
72159
+ name,
72160
+ command: typeof entry.command === "string" ? entry.command : "",
72161
+ args,
72162
+ ...asRecord2(entry.env) ? { env: entry.env } : {},
72163
+ ...typeof entry.url === "string" ? { url: entry.url } : {},
72164
+ ...entry.alwaysLoad === true ? { alwaysLoad: true } : {}
72165
+ };
72166
+ }
72167
+ function findClaudeLocalProject(config2, projectRoot) {
72168
+ const projects = asRecord2(config2.projects);
72169
+ if (!projects) return null;
72170
+ const target = normalizeProjectKey(projectRoot);
72171
+ for (const [key, value] of Object.entries(projects)) {
72172
+ if (normalizeProjectKey(key) !== target) continue;
72173
+ const project = asRecord2(value);
72174
+ return project ? { key, project } : null;
72175
+ }
72176
+ return null;
72177
+ }
72178
+ async function inspectClaudeLocalMcp(projectRoot) {
72179
+ const configPath = getClaudeLocalConfigPath();
72180
+ if (!existsSync21(configPath)) {
72181
+ return {
72182
+ scope: "local",
72183
+ path: configPath,
72184
+ exists: false,
72185
+ status: "missing",
72186
+ issues: ["mcp-config-missing"]
72187
+ };
72188
+ }
72189
+ let config2 = {};
72190
+ try {
72191
+ config2 = JSON.parse(await readFile7(configPath, "utf-8"));
72192
+ } catch {
72193
+ return {
72194
+ scope: "local",
72195
+ path: configPath,
72196
+ exists: true,
72197
+ status: "repairable",
72198
+ issues: ["mcp-config-unreadable"]
72199
+ };
72200
+ }
72201
+ const localProject = findClaudeLocalProject(config2, projectRoot);
72202
+ const pathLabel = localProject ? `${configPath}#projects[${localProject.key}]` : configPath;
72203
+ if (!localProject) {
72204
+ return {
72205
+ scope: "local",
72206
+ path: pathLabel,
72207
+ exists: true,
72208
+ status: "missing",
72209
+ issues: ["mcp-config-missing"]
72210
+ };
72211
+ }
72212
+ const servers = asRecord2(localProject.project.mcpServers);
72213
+ const server = coerceClaudeLocalServer("memorix", servers?.memorix);
72214
+ if (!server) {
72215
+ return {
72216
+ scope: "local",
72217
+ path: pathLabel,
72218
+ exists: true,
72219
+ status: "repairable",
72220
+ issues: ["memorix-server-missing"]
72221
+ };
72222
+ }
72223
+ const issues = [];
72224
+ if (!server.url && looksLikeStaleMemorixCommand(server)) issues.push("stale-command-path");
72225
+ if (!server.url && !isRecommendedStdioServer(server)) issues.push("nonstandard-mcp-command");
72226
+ if (server.alwaysLoad !== true) issues.push("claude-always-load-missing");
72227
+ return {
72228
+ scope: "local",
72229
+ path: pathLabel,
72230
+ exists: true,
72231
+ status: issues.length > 0 ? "repairable" : "ok",
72232
+ issues,
72233
+ server: sanitizeServer(server)
72234
+ };
72235
+ }
72236
+ async function installClaudeLocalMcpConfig(projectRoot) {
72237
+ const configPath = getClaudeLocalConfigPath();
72238
+ let config2 = {};
72239
+ try {
72240
+ config2 = JSON.parse(await readFile7(configPath, "utf-8"));
72241
+ } catch {
72242
+ config2 = {};
72243
+ }
72244
+ const projects = asRecord2(config2.projects) ?? {};
72245
+ const existing = findClaudeLocalProject({ ...config2, projects }, projectRoot);
72246
+ const projectKey = existing?.key ?? defaultClaudeProjectKey(projectRoot);
72247
+ const project = existing?.project ?? asRecord2(projects[projectKey]) ?? {};
72248
+ const mcpServers = asRecord2(project.mcpServers) ?? {};
72249
+ const server = buildMemorixServer("stdio");
72250
+ server.alwaysLoad = true;
72251
+ mcpServers.memorix = {
72252
+ type: "stdio",
72253
+ command: server.command,
72254
+ args: server.args,
72255
+ alwaysLoad: true
72256
+ };
72257
+ project.mcpServers = mcpServers;
72258
+ projects[projectKey] = project;
72259
+ config2.projects = projects;
72260
+ await mkdir7(dirname7(configPath), { recursive: true });
72261
+ await writeFile7(configPath, `${JSON.stringify(config2, null, 2)}
72262
+ `, "utf-8");
72263
+ }
72264
+ async function inspectMcp(agent, projectRoot, scope) {
72265
+ if (!isMcpConfigAgent(agent)) {
72266
+ return { status: "skipped", issues: ["mcp-managed-by-package"], checks: [] };
72267
+ }
72268
+ const adapter = getMcpAdapter(agent);
72269
+ const checks = [];
72270
+ for (const targetScope of requestedMcpScopes(agent, scope)) {
72271
+ if (agent === "claude" && targetScope === "local") {
72272
+ checks.push(await inspectClaudeLocalMcp(projectRoot));
72273
+ continue;
72274
+ }
72275
+ const configPath = adapter.getConfigPath(targetScope === "project" ? projectRoot : void 0);
72276
+ if (targetScope === "global" && configPath === adapter.getConfigPath(projectRoot)) continue;
72277
+ if (!existsSync21(configPath)) {
72278
+ checks.push({
72279
+ scope: targetScope,
72280
+ path: configPath,
72281
+ exists: false,
72282
+ status: "missing",
72283
+ issues: ["mcp-config-missing"]
72284
+ });
72285
+ continue;
72286
+ }
72287
+ const content = await readFile7(configPath, "utf-8");
72288
+ if (agent === "claude" && targetScope === "global") {
72289
+ try {
72290
+ const parsed = JSON.parse(content);
72291
+ if (asRecord2(parsed.projects) && !asRecord2(parsed.mcpServers)) {
72292
+ checks.push({
72293
+ scope: targetScope,
72294
+ path: configPath,
72295
+ exists: true,
72296
+ status: "missing",
72297
+ issues: ["mcp-config-missing"]
72298
+ });
72299
+ continue;
72300
+ }
72301
+ } catch {
72302
+ checks.push({
72303
+ scope: targetScope,
72304
+ path: configPath,
72305
+ exists: true,
72306
+ status: "repairable",
72307
+ issues: ["mcp-config-unreadable"]
72308
+ });
72309
+ continue;
72310
+ }
72311
+ }
72312
+ const servers = adapter.parse(content);
72313
+ const server = servers.find((entry) => entry.name === "memorix");
72314
+ if (!server) {
72315
+ checks.push({
72316
+ scope: targetScope,
72317
+ path: configPath,
72318
+ exists: true,
72319
+ status: "repairable",
72320
+ issues: ["memorix-server-missing"]
72321
+ });
72322
+ continue;
72323
+ }
72324
+ const issues = [];
72325
+ if (!server.url && looksLikeStaleMemorixCommand(server)) issues.push("stale-command-path");
72326
+ if (!server.url && !isRecommendedStdioServer(server)) issues.push("nonstandard-mcp-command");
72327
+ if (agent === "claude" && server.alwaysLoad !== true) issues.push("claude-always-load-missing");
72328
+ checks.push({
72329
+ scope: targetScope,
72330
+ path: configPath,
72331
+ exists: true,
72332
+ status: issues.length > 0 ? "repairable" : "ok",
72333
+ issues,
72334
+ server: sanitizeServer(server)
72335
+ });
72336
+ }
72337
+ return {
72338
+ status: aggregateMcpStatus(checks),
72339
+ issues: aggregateMcpIssues(checks),
72340
+ checks
72341
+ };
72342
+ }
72343
+ function isCurrentGuidance(content) {
72344
+ return content.includes("Memory Autopilot") && content.includes("Default first step for non-trivial coding work") && content.includes("memorix_project_context");
72345
+ }
72346
+ async function inspectGuidance(agent, projectRoot, scope) {
72347
+ if (!GUIDANCE_AGENTS.has(agent)) {
72348
+ return { status: "skipped", issues: ["guidance-managed-by-package"], checks: [] };
72349
+ }
72350
+ const checks = [];
72351
+ for (const targetScope of requestedGuidanceScopes(scope)) {
72352
+ const root = targetScope === "project" ? projectRoot : homedir32();
72353
+ const rulesPath = getAgentRulesPath(agent, root, targetScope === "global");
72354
+ if (!existsSync21(rulesPath)) {
72355
+ checks.push({
72356
+ scope: targetScope,
72357
+ path: rulesPath,
72358
+ exists: false,
72359
+ status: "missing",
72360
+ issues: ["guidance-missing"]
72361
+ });
72362
+ continue;
72363
+ }
72364
+ const content = await readFile7(rulesPath, "utf-8");
72365
+ const issues = isCurrentGuidance(content) ? [] : ["guidance-outdated"];
72366
+ checks.push({
72367
+ scope: targetScope,
72368
+ path: rulesPath,
72369
+ exists: true,
72370
+ status: issues.length > 0 ? "repairable" : "ok",
72371
+ issues
72372
+ });
72373
+ }
72374
+ return {
72375
+ status: aggregateGuidanceStatus(checks),
72376
+ issues: aggregateGuidanceIssues(checks),
72377
+ checks
72378
+ };
72379
+ }
72380
+ async function inspectAgentIntegrations(options2 = {}) {
72381
+ const projectRoot = options2.projectRoot ?? process.cwd();
72382
+ const scope = options2.scope === "local" || options2.scope === "project" || options2.scope === "global" || options2.scope === "all" ? options2.scope : "all";
72383
+ const agents = requestedAgents(options2.agent);
72384
+ const entries = [];
72385
+ for (const agent of agents) {
72386
+ entries.push({
72387
+ agent,
72388
+ mcp: await inspectMcp(agent, projectRoot, scope),
72389
+ guidance: await inspectGuidance(agent, projectRoot, scope)
72390
+ });
72391
+ }
72392
+ const entryStatuses = entries.map((entry) => worstStatus([entry.mcp.status, entry.guidance.status]));
72393
+ return {
72394
+ projectRoot,
72395
+ scope,
72396
+ entries,
72397
+ summary: {
72398
+ checked: entries.length,
72399
+ ok: entryStatuses.filter((status) => status === "ok").length,
72400
+ missing: entryStatuses.filter((status) => status === "missing").length,
72401
+ repairable: entryStatuses.filter((status) => status === "repairable").length
72402
+ },
72403
+ repairCommand: `memorix repair agents${options2.agent ? ` --agent ${options2.agent}` : ""}${scope === "all" ? "" : ` --scope ${scope}`}`
72404
+ };
72405
+ }
72406
+ function formatAgentIntegrationReport(report) {
72407
+ const lines = [
72408
+ "Memorix Agent Doctor",
72409
+ `Project: ${report.projectRoot}`,
72410
+ `Scope: ${report.scope}`,
72411
+ ""
72412
+ ];
72413
+ for (const entry of report.entries) {
72414
+ const status = worstStatus([entry.mcp.status, entry.guidance.status]);
72415
+ lines.push(`${entry.agent}: ${status}`);
72416
+ if (entry.mcp.issues.length > 0) lines.push(` MCP: ${entry.mcp.issues.join(", ")}`);
72417
+ if (entry.guidance.issues.length > 0) lines.push(` Guidance: ${entry.guidance.issues.join(", ")}`);
72418
+ }
72419
+ lines.push("");
72420
+ lines.push(`Repair: ${report.repairCommand}`);
72421
+ return lines.join("\n");
72422
+ }
72423
+ async function repairAgentIntegrations(options2 = {}) {
72424
+ const projectRoot = options2.projectRoot ?? process.cwd();
72425
+ const scope = options2.scope === "local" || options2.scope === "project" || options2.scope === "global" || options2.scope === "all" ? options2.scope : "all";
72426
+ const before = await inspectAgentIntegrations({ projectRoot, agent: options2.agent, scope });
72427
+ const changed = [];
72428
+ const skipped = [];
72429
+ const canInstallMissing = Boolean(options2.agent && scope !== "all");
72430
+ for (const entry of before.entries) {
72431
+ if (isMcpConfigAgent(entry.agent)) {
72432
+ for (const check2 of entry.mcp.checks) {
72433
+ if (check2.status === "ok" || check2.status === "skipped") continue;
72434
+ if (check2.status === "missing" && !canInstallMissing) {
72435
+ skipped.push(`${entry.agent}:mcp:${check2.scope}:missing`);
72436
+ continue;
72437
+ }
72438
+ if (!options2.dry) {
72439
+ if (entry.agent === "claude" && check2.scope === "local") {
72440
+ await installClaudeLocalMcpConfig(projectRoot);
72441
+ } else {
72442
+ await installMcpConfig({
72443
+ agent: entry.agent,
72444
+ projectRoot,
72445
+ global: check2.scope === "global",
72446
+ mcp: "stdio"
72447
+ });
72448
+ }
72449
+ }
72450
+ changed.push(`${entry.agent}:mcp:${check2.scope}`);
72451
+ }
72452
+ } else {
72453
+ skipped.push(`${entry.agent}:mcp`);
72454
+ }
72455
+ if (GUIDANCE_AGENTS.has(entry.agent)) {
72456
+ for (const check2 of entry.guidance.checks) {
72457
+ if (check2.status === "ok" || check2.status === "skipped") continue;
72458
+ if (check2.status === "missing" && !canInstallMissing) {
72459
+ skipped.push(`${entry.agent}:guidance:${check2.scope}:missing`);
72460
+ continue;
72461
+ }
72462
+ if (!options2.dry) {
72463
+ await installAgentGuidance(entry.agent, projectRoot, check2.scope === "global");
72464
+ }
72465
+ changed.push(`${entry.agent}:guidance:${check2.scope}`);
72466
+ }
72467
+ } else {
72468
+ skipped.push(`${entry.agent}:guidance`);
72469
+ }
72470
+ }
72471
+ return {
72472
+ projectRoot,
72473
+ scope,
72474
+ changed,
72475
+ skipped,
72476
+ before,
72477
+ after: options2.dry ? void 0 : await inspectAgentIntegrations({ projectRoot, agent: options2.agent, scope })
72478
+ };
72479
+ }
72480
+ function formatAgentRepairResult(result) {
72481
+ const lines = [
72482
+ "Memorix Agent Repair",
72483
+ `Project: ${result.projectRoot}`,
72484
+ `Scope: ${result.scope}`,
72485
+ ""
72486
+ ];
72487
+ if (result.changed.length === 0) {
72488
+ lines.push("No repairable agent integration issues found.");
72489
+ } else {
72490
+ lines.push("Changed:");
72491
+ for (const item of result.changed) lines.push(`- ${item}`);
72492
+ }
72493
+ if (result.skipped.length > 0) {
72494
+ lines.push("");
72495
+ lines.push("Skipped:");
72496
+ for (const item of result.skipped) lines.push(`- ${item}`);
72497
+ }
72498
+ return lines.join("\n");
72499
+ }
72500
+ var GUIDANCE_AGENTS;
72501
+ var init_agent_integrations = __esm({
72502
+ "src/cli/commands/agent-integrations.ts"() {
72503
+ "use strict";
72504
+ init_esm_shims();
72505
+ init_installers();
72506
+ init_setup();
72507
+ GUIDANCE_AGENTS = /* @__PURE__ */ new Set([
72508
+ "claude",
72509
+ "codex",
72510
+ "cursor",
72511
+ "windsurf",
72512
+ "copilot",
72513
+ "gemini-cli",
72514
+ "antigravity",
72515
+ "kiro",
72516
+ "opencode",
72517
+ "trae"
72518
+ ]);
72519
+ }
72520
+ });
72521
+
71977
72522
  // src/cli/commands/doctor.ts
71978
72523
  var doctor_exports = {};
71979
72524
  __export(doctor_exports, {
@@ -71991,6 +72536,14 @@ var init_doctor = __esm({
71991
72536
  description: "Diagnose Memorix health \u2014 project identity, embedding, data, conflicts"
71992
72537
  },
71993
72538
  args: {
72539
+ agent: {
72540
+ type: "string",
72541
+ description: 'Agent to inspect for "doctor agents" (default: all)'
72542
+ },
72543
+ scope: {
72544
+ type: "string",
72545
+ description: 'Scope for "doctor agents": local, project, global, or all'
72546
+ },
71994
72547
  json: {
71995
72548
  type: "boolean",
71996
72549
  description: "Output as JSON instead of human-readable text",
@@ -72003,9 +72556,23 @@ var init_doctor = __esm({
72003
72556
  }
72004
72557
  },
72005
72558
  run: async ({ args }) => {
72006
- const { existsSync: existsSync25, readFileSync: readFileSync22 } = await import("fs");
72007
- const { join: join32, basename: basename4 } = await import("path");
72008
- const { homedir: homedir33 } = await import("os");
72559
+ const positional = args._ ?? [];
72560
+ if (positional[0] === "agents") {
72561
+ const { inspectAgentIntegrations: inspectAgentIntegrations2, formatAgentIntegrationReport: formatAgentIntegrationReport2 } = await Promise.resolve().then(() => (init_agent_integrations(), agent_integrations_exports));
72562
+ const report2 = await inspectAgentIntegrations2({
72563
+ agent: args.agent,
72564
+ scope: args.scope
72565
+ });
72566
+ if (args.json) {
72567
+ console.log(JSON.stringify({ agents: report2 }, null, 2));
72568
+ } else {
72569
+ console.log(formatAgentIntegrationReport2(report2));
72570
+ }
72571
+ return;
72572
+ }
72573
+ const { existsSync: existsSync26, readFileSync: readFileSync22 } = await import("fs");
72574
+ const { join: join32, basename: basename5 } = await import("path");
72575
+ const { homedir: homedir34 } = await import("os");
72009
72576
  const { execSync: execSync11 } = await import("child_process");
72010
72577
  const report = {};
72011
72578
  const issues = [];
@@ -72067,13 +72634,13 @@ var init_doctor = __esm({
72067
72634
  }
72068
72635
  lines.push("");
72069
72636
  lines.push("\u250C\u2500 Runtime Mode \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
72070
- const memorixDir = join32(homedir33(), ".memorix");
72637
+ const memorixDir = join32(homedir34(), ".memorix");
72071
72638
  const bgStatePath = join32(memorixDir, "background.json");
72072
72639
  let bgRunning = false;
72073
72640
  let bgPort = 0;
72074
72641
  let bgPid = 0;
72075
72642
  try {
72076
- if (existsSync25(bgStatePath)) {
72643
+ if (existsSync26(bgStatePath)) {
72077
72644
  const bgState = JSON.parse(readFileSync22(bgStatePath, "utf-8"));
72078
72645
  bgPid = bgState.pid;
72079
72646
  bgPort = bgState.port;
@@ -72089,15 +72656,15 @@ var init_doctor = __esm({
72089
72656
  lines.push(ok(`Background control plane running (PID ${bgPid}, port ${bgPort})`));
72090
72657
  try {
72091
72658
  const http = await import("http");
72092
- const healthy = await new Promise((resolve3) => {
72659
+ const healthy = await new Promise((resolve4) => {
72093
72660
  const req = http.request({ hostname: "127.0.0.1", port: bgPort, path: "/api/team", timeout: 3e3 }, (res) => {
72094
72661
  res.resume();
72095
- resolve3(res.statusCode === 200);
72662
+ resolve4(res.statusCode === 200);
72096
72663
  });
72097
- req.on("error", () => resolve3(false));
72664
+ req.on("error", () => resolve4(false));
72098
72665
  req.on("timeout", () => {
72099
72666
  req.destroy();
72100
- resolve3(false);
72667
+ resolve4(false);
72101
72668
  });
72102
72669
  req.end();
72103
72670
  });
@@ -72120,15 +72687,15 @@ var init_doctor = __esm({
72120
72687
  if (!bgRunning) {
72121
72688
  try {
72122
72689
  const http = await import("http");
72123
- const portUsed = await new Promise((resolve3) => {
72690
+ const portUsed = await new Promise((resolve4) => {
72124
72691
  const req = http.request({ hostname: "127.0.0.1", port: 3211, path: "/api/team", timeout: 2e3 }, (res) => {
72125
72692
  res.resume();
72126
- resolve3(res.statusCode === 200);
72693
+ resolve4(res.statusCode === 200);
72127
72694
  });
72128
- req.on("error", () => resolve3(false));
72695
+ req.on("error", () => resolve4(false));
72129
72696
  req.on("timeout", () => {
72130
72697
  req.destroy();
72131
- resolve3(false);
72698
+ resolve4(false);
72132
72699
  });
72133
72700
  req.end();
72134
72701
  });
@@ -72166,7 +72733,7 @@ var init_doctor = __esm({
72166
72733
  }
72167
72734
  try {
72168
72735
  const cachePath = join32(memorixDir, "embedding-cache.json");
72169
- if (existsSync25(cachePath)) {
72736
+ if (existsSync26(cachePath)) {
72170
72737
  const cache4 = JSON.parse(readFileSync22(cachePath, "utf-8"));
72171
72738
  const cacheCount = Object.keys(cache4).length;
72172
72739
  lines.push(info(`Cached embeddings: ${cacheCount}`));
@@ -72181,7 +72748,7 @@ var init_doctor = __esm({
72181
72748
  }
72182
72749
  lines.push("");
72183
72750
  lines.push("\u250C\u2500 Data Status \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
72184
- if (dataDir && existsSync25(dataDir)) {
72751
+ if (dataDir && existsSync26(dataDir)) {
72185
72752
  let obsCount = 0;
72186
72753
  let activeCount = 0;
72187
72754
  let ranCount = 0;
@@ -72247,16 +72814,19 @@ var init_doctor = __esm({
72247
72814
  try {
72248
72815
  const { CodeGraphStore: CodeGraphStore2 } = await Promise.resolve().then(() => (init_store(), store_exports));
72249
72816
  const { buildProjectContextOverview: buildProjectContextOverview2 } = await Promise.resolve().then(() => (init_project_context(), project_context_exports));
72817
+ const { getResolvedConfig: getResolvedConfig2 } = await Promise.resolve().then(() => (init_resolved_config(), resolved_config_exports));
72250
72818
  const codeStore = new CodeGraphStore2();
72251
72819
  await codeStore.init(dataDir);
72820
+ const exclude = getResolvedConfig2({ projectRoot: projectRoot || process.cwd() }).codegraph.excludePatterns;
72252
72821
  const overview = buildProjectContextOverview2({
72253
72822
  project: {
72254
72823
  id: projectId,
72255
- name: projectName || basename4(projectRoot || process.cwd()),
72824
+ name: projectName || basename5(projectRoot || process.cwd()),
72256
72825
  rootPath: projectRoot || process.cwd()
72257
72826
  },
72258
72827
  store: codeStore,
72259
- observations: projectObservations
72828
+ observations: projectObservations,
72829
+ exclude
72260
72830
  });
72261
72831
  const languageText = overview.code.languages.length > 0 ? overview.code.languages.map((item) => `${item.language} ${item.files}`).join(", ") : "none indexed yet";
72262
72832
  if (overview.code.files > 0) {
@@ -72297,7 +72867,7 @@ var init_doctor = __esm({
72297
72867
  let conflictsFound = false;
72298
72868
  if (dataDir) {
72299
72869
  const lockFile = join32(dataDir, ".memorix.lock");
72300
- if (existsSync25(lockFile)) {
72870
+ if (existsSync26(lockFile)) {
72301
72871
  try {
72302
72872
  const lockData = JSON.parse(readFileSync22(lockFile, "utf-8"));
72303
72873
  const lockAge = Date.now() - lockData.time;
@@ -72412,6 +72982,71 @@ var init_doctor = __esm({
72412
72982
  }
72413
72983
  });
72414
72984
 
72985
+ // src/cli/commands/repair.ts
72986
+ var repair_exports = {};
72987
+ __export(repair_exports, {
72988
+ default: () => repair_default
72989
+ });
72990
+ var repair_default;
72991
+ var init_repair = __esm({
72992
+ "src/cli/commands/repair.ts"() {
72993
+ "use strict";
72994
+ init_esm_shims();
72995
+ init_dist2();
72996
+ repair_default = defineCommand({
72997
+ meta: {
72998
+ name: "repair",
72999
+ description: "Repair Memorix-owned agent integration files"
73000
+ },
73001
+ args: {
73002
+ agent: {
73003
+ type: "string",
73004
+ description: "Agent to repair (default: all detected repairable entries)"
73005
+ },
73006
+ scope: {
73007
+ type: "string",
73008
+ description: "Scope: local, project, global, or all"
73009
+ },
73010
+ dry: {
73011
+ type: "boolean",
73012
+ description: "Show what would be repaired without writing files",
73013
+ default: false
73014
+ },
73015
+ json: {
73016
+ type: "boolean",
73017
+ description: "Emit machine-readable JSON output",
73018
+ default: false
73019
+ }
73020
+ },
73021
+ run: async ({ args }) => {
73022
+ const positional = args._ ?? [];
73023
+ const action = positional[0] || "agents";
73024
+ if (action !== "agents") {
73025
+ const message = "Usage: memorix repair agents [--agent <agent>] [--scope local|project|global|all] [--dry]";
73026
+ if (args.json) {
73027
+ console.log(JSON.stringify({ error: message }, null, 2));
73028
+ } else {
73029
+ console.log(message);
73030
+ }
73031
+ process.exitCode = 1;
73032
+ return;
73033
+ }
73034
+ const { repairAgentIntegrations: repairAgentIntegrations2, formatAgentRepairResult: formatAgentRepairResult2 } = await Promise.resolve().then(() => (init_agent_integrations(), agent_integrations_exports));
73035
+ const repair = await repairAgentIntegrations2({
73036
+ agent: args.agent,
73037
+ scope: args.scope,
73038
+ dry: !!args.dry
73039
+ });
73040
+ if (args.json) {
73041
+ console.log(JSON.stringify({ repair }, null, 2));
73042
+ } else {
73043
+ console.log(formatAgentRepairResult2(repair));
73044
+ }
73045
+ }
73046
+ });
73047
+ }
73048
+ });
73049
+
72415
73050
  // src/cli/commands/dashboard.ts
72416
73051
  var dashboard_exports = {};
72417
73052
  __export(dashboard_exports, {
@@ -72582,14 +73217,14 @@ Project: ${projectName} (${projectId})
72582
73217
  const highQuality = projectObs.filter((o3) => !isLowQuality(o3.title ?? ""));
72583
73218
  const seen = /* @__PURE__ */ new Set();
72584
73219
  const duplicates = [];
72585
- const unique = [];
73220
+ const unique2 = [];
72586
73221
  for (const obs of highQuality) {
72587
73222
  const key = `${obs.type}|${obs.title}|${obs.entityName}`;
72588
73223
  if (seen.has(key)) {
72589
73224
  duplicates.push(obs);
72590
73225
  } else {
72591
73226
  seen.add(key);
72592
- unique.push(obs);
73227
+ unique2.push(obs);
72593
73228
  }
72594
73229
  }
72595
73230
  const noiseHits = [];
@@ -72604,7 +73239,7 @@ Project: ${projectName} (${projectId})
72604
73239
  const toArchive = noiseHits.map((h3) => h3.obs);
72605
73240
  console.log(`Analysis (active observations for ${projectId}):`);
72606
73241
  console.log(` Total active: ${projectObs.length}`);
72607
- console.log(` High quality: ${unique.length - toArchive.length}`);
73242
+ console.log(` High quality: ${unique2.length - toArchive.length}`);
72608
73243
  console.log(` Low quality: ${lowQuality.length}`);
72609
73244
  console.log(` Duplicates: ${duplicates.length}`);
72610
73245
  if (args.noise) {
@@ -72651,8 +73286,8 @@ Project: ${projectName} (${projectId})
72651
73286
  toRemove.length > 0 ? `delete ${toRemove.length}` : "",
72652
73287
  toArchive.length > 0 ? `archive ${toArchive.length}` : ""
72653
73288
  ].filter(Boolean).join(" and ");
72654
- const answer = await new Promise((resolve3) => {
72655
- rl.question(`Proceed to ${desc} observations? (y/N) `, resolve3);
73289
+ const answer = await new Promise((resolve4) => {
73290
+ rl.question(`Proceed to ${desc} observations? (y/N) `, resolve4);
72656
73291
  });
72657
73292
  rl.close();
72658
73293
  if (answer.trim().toLowerCase() !== "y") {
@@ -72945,8 +73580,8 @@ async function confirm(description) {
72945
73580
  }
72946
73581
  const readline = await import("readline");
72947
73582
  const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
72948
- const answer = await new Promise((resolve3) => {
72949
- rl.question(`Proceed to ${description}? (y/N) `, resolve3);
73583
+ const answer = await new Promise((resolve4) => {
73584
+ rl.question(`Proceed to ${description}? (y/N) `, resolve4);
72950
73585
  });
72951
73586
  rl.close();
72952
73587
  return answer.trim().toLowerCase() === "y";
@@ -73258,8 +73893,8 @@ function spawnAgentWithStream(command, args, opts, stdinData, onStdoutLine, onCo
73258
73893
  if (done) {
73259
73894
  return Promise.resolve({ value: void 0, done: true });
73260
73895
  }
73261
- return new Promise((resolve3) => {
73262
- waiters.push({ resolve: resolve3 });
73896
+ return new Promise((resolve4) => {
73897
+ waiters.push({ resolve: resolve4 });
73263
73898
  });
73264
73899
  }
73265
73900
  };
@@ -73299,7 +73934,7 @@ function spawnAgentWithStream(command, args, opts, stdinData, onStdoutLine, onCo
73299
73934
  }, SIGKILL_GRACE_MS);
73300
73935
  }, timeoutMs);
73301
73936
  }
73302
- const completion = new Promise((resolve3) => {
73937
+ const completion = new Promise((resolve4) => {
73303
73938
  let exitCode = null;
73304
73939
  let exitSignal = null;
73305
73940
  let exited = false;
@@ -73319,7 +73954,7 @@ function spawnAgentWithStream(command, args, opts, stdinData, onStdoutLine, onCo
73319
73954
  const tail = stdinError ? `${stdinError}
73320
73955
  ${ring.toString()}` : ring.toString();
73321
73956
  const baseResult = { exitCode, signal: exitSignal, tailOutput: tail, killed };
73322
- resolve3(onCompletion ? onCompletion(baseResult) : baseResult);
73957
+ resolve4(onCompletion ? onCompletion(baseResult) : baseResult);
73323
73958
  }
73324
73959
  child.on("exit", (code, signal) => {
73325
73960
  exited = true;
@@ -73346,7 +73981,7 @@ ${ring.toString()}` : ring.toString();
73346
73981
  closeStream();
73347
73982
  const tail = stdinError ? `${stdinError}
73348
73983
  ` : "";
73349
- resolve3({
73984
+ resolve4({
73350
73985
  exitCode: null,
73351
73986
  signal: null,
73352
73987
  tailOutput: `${tail}spawn error: ${err.message}
@@ -74249,8 +74884,8 @@ function buildIdleReasons(available, dispatchedNames, config2, excludeAgents) {
74249
74884
  const excluded = excludeAgents ?? /* @__PURE__ */ new Set();
74250
74885
  for (const adapter of available) {
74251
74886
  if (dispatchedNames.has(adapter.name)) continue;
74252
- const isExcluded2 = excluded.has(adapter.name);
74253
- if (isExcluded2) {
74887
+ const isExcluded = excluded.has(adapter.name);
74888
+ if (isExcluded) {
74254
74889
  result.push({ name: adapter.name, reason: "excluded due to prior failure" });
74255
74890
  } else {
74256
74891
  const inAnyPref = Object.values(DEFAULT_ROLE_PREFERENCES).some((prefs) => prefs.includes(adapter.name));
@@ -74349,8 +74984,8 @@ var init_pipeline_trace = __esm({
74349
74984
 
74350
74985
  // src/orchestrate/worktree.ts
74351
74986
  import { execSync as execSync7 } from "child_process";
74352
- import { existsSync as existsSync22, rmSync as rmSync2 } from "fs";
74353
- import { join as join30, basename as basename3 } from "path";
74987
+ import { existsSync as existsSync23, rmSync as rmSync2 } from "fs";
74988
+ import { join as join30, basename as basename4 } from "path";
74354
74989
  function createWorktree(projectDir2, taskId, pipelineId) {
74355
74990
  const shortId2 = taskId.slice(0, 8);
74356
74991
  const shortPipeline = pipelineId.slice(0, 8);
@@ -74410,7 +75045,7 @@ function removeWorktree(projectDir2, worktreePath, branch) {
74410
75045
  timeout: 1e4
74411
75046
  });
74412
75047
  } catch {
74413
- if (existsSync22(worktreePath)) {
75048
+ if (existsSync23(worktreePath)) {
74414
75049
  try {
74415
75050
  rmSync2(worktreePath, { recursive: true, force: true });
74416
75051
  } catch {
@@ -74458,7 +75093,7 @@ function listWorktrees(projectDir2) {
74458
75093
  }
74459
75094
  }
74460
75095
  function extractTaskIdFromPath(worktreePath) {
74461
- const name = basename3(worktreePath);
75096
+ const name = basename4(worktreePath);
74462
75097
  const match = name.match(/^task-([a-f0-9]+)$/);
74463
75098
  return match ? match[1] : null;
74464
75099
  }
@@ -74488,7 +75123,7 @@ var init_worktree = __esm({
74488
75123
  import { spawn as spawn2, execSync as execSync8 } from "child_process";
74489
75124
  function runGate(gate, command, cwd, timeoutMs, outputBudget = DEFAULT_OUTPUT_BUDGET) {
74490
75125
  const start = Date.now();
74491
- return new Promise((resolve3) => {
75126
+ return new Promise((resolve4) => {
74492
75127
  const chunks = [];
74493
75128
  let totalBytes = 0;
74494
75129
  const proc = spawn2(command, {
@@ -74531,7 +75166,7 @@ function runGate(gate, command, cwd, timeoutMs, outputBudget = DEFAULT_OUTPUT_BU
74531
75166
  const output = Buffer.concat(chunks).toString("utf-8");
74532
75167
  const durationMs = Date.now() - start;
74533
75168
  if (killed) {
74534
- resolve3({
75169
+ resolve4({
74535
75170
  gate,
74536
75171
  passed: false,
74537
75172
  output: output + `
@@ -74541,7 +75176,7 @@ function runGate(gate, command, cwd, timeoutMs, outputBudget = DEFAULT_OUTPUT_BU
74541
75176
  });
74542
75177
  return;
74543
75178
  }
74544
- resolve3({
75179
+ resolve4({
74545
75180
  gate,
74546
75181
  passed: code === 0,
74547
75182
  output,
@@ -74551,7 +75186,7 @@ function runGate(gate, command, cwd, timeoutMs, outputBudget = DEFAULT_OUTPUT_BU
74551
75186
  });
74552
75187
  proc.on("error", (err) => {
74553
75188
  clearTimeout(timer);
74554
- resolve3({
75189
+ resolve4({
74555
75190
  gate,
74556
75191
  passed: false,
74557
75192
  output: `[ERROR] Failed to spawn gate command: ${err.message}`,
@@ -75181,7 +75816,7 @@ function hashErrorPattern(errorOutput) {
75181
75816
  return createHash8("sha256").update(sanitized).digest("hex").slice(0, 12);
75182
75817
  }
75183
75818
  function sleep2(ms) {
75184
- return new Promise((resolve3) => setTimeout(() => resolve3([]), ms));
75819
+ return new Promise((resolve4) => setTimeout(() => resolve4([]), ms));
75185
75820
  }
75186
75821
  var DEFAULT_BRIDGE_CONFIG, _storeObservation, _searchObservations;
75187
75822
  var init_memorix_bridge = __esm({
@@ -76142,7 +76777,7 @@ ${formatCostSummary(costSummary)}`);
76142
76777
  }
76143
76778
  }
76144
76779
  function sleep3(ms) {
76145
- return new Promise((resolve3) => setTimeout(resolve3, ms));
76780
+ return new Promise((resolve4) => setTimeout(resolve4, ms));
76146
76781
  }
76147
76782
  function isGitRepository(projectDir2) {
76148
76783
  try {
@@ -80312,10 +80947,10 @@ function WorkbenchApp({ version: version2, onExitForInteractive }) {
80312
80947
  }
80313
80948
  try {
80314
80949
  const { resolveHooksDir: resolveHooksDir2 } = await Promise.resolve().then(() => (init_hooks_path(), hooks_path_exports));
80315
- const { existsSync: existsSync25, readFileSync: readFileSync22, writeFileSync: writeFileSync11, unlinkSync: unlinkSync4 } = await import("fs");
80950
+ const { existsSync: existsSync26, readFileSync: readFileSync22, writeFileSync: writeFileSync11, unlinkSync: unlinkSync4 } = await import("fs");
80316
80951
  const resolved = resolveHooksDir2(proj.rootPath);
80317
80952
  const hookMarker = "# [memorix-git-hook]";
80318
- if (!resolved || !existsSync25(resolved.hookPath)) {
80953
+ if (!resolved || !existsSync26(resolved.hookPath)) {
80319
80954
  setActionStatus("No post-commit hook found.");
80320
80955
  return;
80321
80956
  }
@@ -80470,7 +81105,7 @@ function WorkbenchApp({ version: version2, onExitForInteractive }) {
80470
81105
  break;
80471
81106
  }
80472
81107
  case "3": {
80473
- const { existsSync: existsSync25, readFileSync: readFileSync22, writeFileSync: writeFileSync11, chmodSync: chmodSync2 } = await import("fs");
81108
+ const { existsSync: existsSync26, readFileSync: readFileSync22, writeFileSync: writeFileSync11, chmodSync: chmodSync2 } = await import("fs");
80474
81109
  const { ensureHooksDir: ensureHooksDir2 } = await Promise.resolve().then(() => (init_hooks_path(), hooks_path_exports));
80475
81110
  const hookMarker = "# [memorix-git-hook]";
80476
81111
  const resolved = ensureHooksDir2(cwd);
@@ -80484,7 +81119,7 @@ if command -v memorix >/dev/null 2>&1; then
80484
81119
  memorix ingest commit --auto >/dev/null 2>&1 &
80485
81120
  fi
80486
81121
  `;
80487
- if (existsSync25(resolved.hookPath)) {
81122
+ if (existsSync26(resolved.hookPath)) {
80488
81123
  if (readFileSync22(resolved.hookPath, "utf-8").includes(hookMarker)) {
80489
81124
  setActionStatus("Post-commit hook already installed.");
80490
81125
  break;
@@ -80504,11 +81139,11 @@ ${hookScript}`, "utf-8");
80504
81139
  break;
80505
81140
  }
80506
81141
  case "4": {
80507
- const { existsSync: existsSync25, readFileSync: readFileSync22, writeFileSync: writeFileSync11, unlinkSync: unlinkSync4 } = await import("fs");
81142
+ const { existsSync: existsSync26, readFileSync: readFileSync22, writeFileSync: writeFileSync11, unlinkSync: unlinkSync4 } = await import("fs");
80508
81143
  const { resolveHooksDir: resolveHooksDir2 } = await Promise.resolve().then(() => (init_hooks_path(), hooks_path_exports));
80509
81144
  const hookMarker = "# [memorix-git-hook]";
80510
81145
  const resolved = resolveHooksDir2(cwd);
80511
- if (!resolved || !existsSync25(resolved.hookPath)) {
81146
+ if (!resolved || !existsSync26(resolved.hookPath)) {
80512
81147
  setActionStatus("No post-commit hook found.");
80513
81148
  break;
80514
81149
  }
@@ -81268,14 +81903,14 @@ var main = defineCommand({
81268
81903
  async run({ args }) {
81269
81904
  let q3 = args.question || "";
81270
81905
  if (!q3 && !process.stdin.isTTY) {
81271
- q3 = await new Promise((resolve3) => {
81906
+ q3 = await new Promise((resolve4) => {
81272
81907
  let data = "";
81273
81908
  process.stdin.setEncoding("utf-8");
81274
81909
  process.stdin.on("data", (chunk) => {
81275
81910
  data += chunk;
81276
81911
  });
81277
- process.stdin.on("end", () => resolve3(data.trim()));
81278
- process.stdin.on("error", () => resolve3(""));
81912
+ process.stdin.on("end", () => resolve4(data.trim()));
81913
+ process.stdin.on("error", () => resolve4(""));
81279
81914
  });
81280
81915
  }
81281
81916
  if (!q3) {
@@ -81356,6 +81991,7 @@ var main = defineCommand({
81356
81991
  }
81357
81992
  })),
81358
81993
  doctor: () => Promise.resolve().then(() => (init_doctor(), doctor_exports)).then((m4) => m4.default),
81994
+ repair: () => Promise.resolve().then(() => (init_repair(), repair_exports)).then((m4) => m4.default),
81359
81995
  dashboard: () => Promise.resolve().then(() => (init_dashboard(), dashboard_exports)).then((m4) => m4.default),
81360
81996
  cleanup: () => Promise.resolve().then(() => (init_cleanup(), cleanup_exports)).then((m4) => m4.default),
81361
81997
  uninstall: () => Promise.resolve().then(() => (init_uninstall(), uninstall_exports)).then((m4) => m4.default),
@@ -81416,6 +82052,7 @@ var main = defineCommand({
81416
82052
  "bg",
81417
82053
  "bs",
81418
82054
  "doctor",
82055
+ "repair",
81419
82056
  "dashboard",
81420
82057
  "cleanup",
81421
82058
  "uninstall",
@@ -81468,6 +82105,7 @@ var main = defineCommand({
81468
82105
  console.error(" serve Start MCP server on stdio");
81469
82106
  console.error(" init Create global defaults or project config");
81470
82107
  console.error(" setup Install Memorix plugin/MCP/rules/hooks for an agent");
82108
+ console.error(" repair Repair Memorix-owned agent integration files");
81471
82109
  console.error(" config Show TOML config paths and resolved values");
81472
82110
  console.error(" integrate Install one IDE integration into the current repo");
81473
82111
  console.error(" status Show project info + stats");