memorix 1.1.7 → 1.1.8
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.
- package/CHANGELOG.md +13 -0
- package/CLAUDE.md +6 -1
- package/README.md +21 -0
- package/README.zh-CN.md +21 -0
- package/TEAM.md +86 -86
- package/dist/cli/index.js +730 -150
- package/dist/cli/index.js.map +1 -1
- package/dist/dashboard/static/index.html +201 -201
- package/dist/dashboard/static/style.css +3584 -3584
- package/dist/index.js +15 -8
- package/dist/index.js.map +1 -1
- package/dist/memcode-runtime/CHANGELOG.md +13 -0
- package/dist/memcode-runtime/package.json +4 -4
- package/dist/sdk.js +15 -8
- package/dist/sdk.js.map +1 -1
- package/docs/AGENT_OPERATOR_PLAYBOOK.md +18 -0
- package/docs/DESIGN_DECISIONS.md +357 -357
- package/docs/SETUP.md +10 -0
- package/docs/dev-log/progress.txt +35 -26
- package/package.json +1 -1
- package/src/audit/index.ts +156 -156
- package/src/cli/commands/agent-integrations.ts +623 -0
- package/src/cli/commands/audit-list.ts +89 -89
- package/src/cli/commands/background.ts +659 -659
- package/src/cli/commands/cleanup.ts +255 -255
- package/src/cli/commands/doctor.ts +23 -0
- package/src/cli/commands/formation.ts +48 -48
- package/src/cli/commands/git-hook-install.ts +111 -111
- package/src/cli/commands/handoff.ts +66 -66
- package/src/cli/commands/hooks-status.ts +63 -63
- package/src/cli/commands/ingest-commit.ts +153 -153
- package/src/cli/commands/ingest-image.ts +73 -73
- package/src/cli/commands/ingest-log.ts +180 -180
- package/src/cli/commands/ingest.ts +44 -44
- package/src/cli/commands/integrate-shared.ts +15 -15
- package/src/cli/commands/lock.ts +96 -96
- package/src/cli/commands/message.ts +121 -121
- package/src/cli/commands/poll.ts +70 -70
- package/src/cli/commands/purge-all-memory.ts +85 -85
- package/src/cli/commands/purge-project-memory.ts +83 -83
- package/src/cli/commands/reasoning.ts +132 -132
- package/src/cli/commands/repair.ts +60 -0
- package/src/cli/commands/retention.ts +108 -108
- package/src/cli/commands/serve-shared.ts +118 -118
- package/src/cli/commands/setup.ts +3 -3
- package/src/cli/commands/skills.ts +123 -123
- package/src/cli/commands/task.ts +192 -192
- package/src/cli/commands/transfer.ts +73 -73
- package/src/cli/commands/uninstall-project-artifacts.ts +85 -85
- package/src/cli/index.ts +3 -1
- package/src/cli/tui/ChatView.tsx +234 -234
- package/src/cli/tui/CommandBar.tsx +312 -312
- package/src/cli/tui/ContextRail.tsx +118 -118
- package/src/cli/tui/HeaderBar.tsx +72 -72
- package/src/cli/tui/LogoBanner.tsx +51 -51
- package/src/cli/tui/Panels.tsx +632 -632
- package/src/cli/tui/Sidebar.tsx +179 -179
- package/src/cli/tui/chat-service.ts +742 -742
- package/src/cli/tui/data.ts +547 -547
- package/src/cli/tui/index.ts +41 -41
- package/src/cli/tui/markdown-render.tsx +371 -371
- package/src/cli/tui/theme.ts +178 -178
- package/src/cli/tui/use-mouse.ts +157 -157
- package/src/cli/tui/useNavigation.ts +56 -56
- package/src/cli/update-checker.ts +211 -211
- package/src/cli/version.ts +7 -7
- package/src/cli/workbench.ts +1 -1
- package/src/codegraph/context-pack.ts +5 -1
- package/src/codegraph/lite-provider.ts +5 -1
- package/src/codegraph/project-context.ts +5 -1
- package/src/compact/token-budget.ts +74 -74
- package/src/config/behavior.ts +59 -59
- package/src/dashboard/project-classification.ts +64 -64
- package/src/dashboard/static/index.html +201 -201
- package/src/dashboard/static/style.css +3584 -3584
- package/src/embedding/fastembed-provider.ts +142 -142
- package/src/embedding/transformers-provider.ts +111 -111
- package/src/git/extractor.ts +209 -209
- package/src/git/hooks-path.ts +85 -85
- package/src/git/noise-filter.ts +210 -210
- package/src/hooks/installers/index.ts +4 -4
- package/src/hooks/official-skills.ts +1 -1
- package/src/hooks/pattern-detector.ts +173 -173
- package/src/hooks/rules/memorix-agent-rules.md +2 -2
- package/src/hooks/significance-filter.ts +250 -250
- package/src/llm/memory-manager.ts +328 -328
- package/src/llm/provider.ts +885 -885
- package/src/llm/quality.ts +248 -248
- package/src/memory/attribution-guard.ts +249 -249
- package/src/memory/auto-relations.ts +107 -107
- package/src/memory/consolidation.ts +302 -302
- package/src/memory/disclosure-policy.ts +141 -141
- package/src/memory/entity-extractor.ts +197 -197
- package/src/memory/formation/evaluate.ts +217 -217
- package/src/memory/formation/extract.ts +361 -361
- package/src/memory/formation/index.ts +417 -417
- package/src/memory/formation/resolve.ts +344 -344
- package/src/memory/formation/types.ts +315 -315
- package/src/memory/freshness.ts +122 -122
- package/src/memory/graph.ts +197 -197
- package/src/memory/refs.ts +94 -94
- package/src/memory/retention.ts +433 -433
- package/src/memory/secret-filter.ts +79 -79
- package/src/memory/session.ts +523 -523
- package/src/multimodal/image-loader.ts +143 -143
- package/src/orchestrate/adapters/claude-stream.ts +192 -192
- package/src/orchestrate/adapters/claude.ts +111 -111
- package/src/orchestrate/adapters/codex-stream.ts +134 -134
- package/src/orchestrate/adapters/codex.ts +41 -41
- package/src/orchestrate/adapters/gemini-stream.ts +166 -166
- package/src/orchestrate/adapters/gemini.ts +42 -42
- package/src/orchestrate/adapters/index.ts +73 -73
- package/src/orchestrate/adapters/opencode-stream.ts +143 -143
- package/src/orchestrate/adapters/opencode.ts +47 -47
- package/src/orchestrate/adapters/spawn-helper.ts +286 -286
- package/src/orchestrate/adapters/types.ts +77 -77
- package/src/orchestrate/capability-router.ts +284 -284
- package/src/orchestrate/context-compact.ts +188 -188
- package/src/orchestrate/cost-tracker.ts +219 -219
- package/src/orchestrate/error-recovery.ts +191 -191
- package/src/orchestrate/evidence.ts +140 -140
- package/src/orchestrate/ledger.ts +110 -110
- package/src/orchestrate/memorix-bridge.ts +380 -380
- package/src/orchestrate/output-budget.ts +80 -80
- package/src/orchestrate/permission.ts +152 -152
- package/src/orchestrate/pipeline-trace.ts +131 -131
- package/src/orchestrate/prompt-builder.ts +155 -155
- package/src/orchestrate/ring-buffer.ts +37 -37
- package/src/orchestrate/task-graph.ts +389 -389
- package/src/orchestrate/verify-gate.ts +219 -219
- package/src/orchestrate/worktree.ts +232 -232
- package/src/project/aliases.ts +374 -374
- package/src/project/detector.ts +268 -268
- package/src/rules/adapters/claude-code.ts +99 -99
- package/src/rules/adapters/codex.ts +97 -97
- package/src/rules/adapters/copilot.ts +124 -124
- package/src/rules/adapters/cursor.ts +114 -114
- package/src/rules/adapters/kiro.ts +126 -126
- package/src/rules/adapters/trae.ts +56 -56
- package/src/rules/adapters/windsurf.ts +83 -83
- package/src/rules/syncer.ts +235 -235
- package/src/sdk.ts +327 -327
- package/src/search/intent-detector.ts +289 -289
- package/src/search/query-expansion.ts +52 -52
- package/src/server/formation-timeout.ts +27 -27
- package/src/skills/mini-skills.ts +386 -386
- package/src/store/chat-store.ts +119 -119
- package/src/store/file-lock.ts +100 -100
- package/src/store/graph-store.ts +249 -249
- package/src/store/mini-skill-store.ts +349 -349
- package/src/store/obs-store.ts +255 -255
- package/src/store/persistence-json.ts +212 -212
- package/src/store/persistence.ts +291 -291
- package/src/store/project-affinity.ts +195 -195
- package/src/store/session-store.ts +259 -259
- package/src/store/sqlite-store.ts +339 -339
- package/src/team/event-bus.ts +76 -76
- package/src/team/file-locks.ts +173 -173
- package/src/team/handoff.ts +167 -167
- package/src/team/messages.ts +203 -203
- package/src/team/poll.ts +132 -132
- package/src/team/tasks.ts +211 -211
- package/src/wiki/generator.ts +237 -237
- package/src/wiki/knowledge-graph.ts +334 -334
- package/src/wiki/types.ts +85 -85
- package/src/workspace/mcp-adapters/codex.ts +191 -191
- package/src/workspace/mcp-adapters/copilot.ts +105 -105
- package/src/workspace/mcp-adapters/cursor.ts +53 -53
- package/src/workspace/mcp-adapters/kiro.ts +64 -64
- package/src/workspace/mcp-adapters/opencode.ts +123 -123
- package/src/workspace/mcp-adapters/trae.ts +134 -134
- package/src/workspace/mcp-adapters/windsurf.ts +91 -91
- package/src/workspace/sanitizer.ts +60 -60
- 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.
|
|
3215
|
+
return true ? "1.1.8" : 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((
|
|
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
|
|
8153
|
+
return resolve4();
|
|
8154
8154
|
}
|
|
8155
8155
|
for (const doc of batch) {
|
|
8156
8156
|
try {
|
|
@@ -13762,7 +13762,7 @@ async function fetchWithRetry(url, apiKey, body, attempt = 0) {
|
|
|
13762
13762
|
const retryAfter = response.headers.get("retry-after");
|
|
13763
13763
|
const waitMs = retryAfter ? parseInt(retryAfter, 10) * 1e3 : delay;
|
|
13764
13764
|
console.error(`[memorix] Embedding API ${response.status}, retry ${attempt + 1}/${MAX_RETRIES} in ${waitMs}ms`);
|
|
13765
|
-
await new Promise((
|
|
13765
|
+
await new Promise((resolve4) => setTimeout(resolve4, waitMs));
|
|
13766
13766
|
return fetchWithRetry(url, apiKey, body, attempt + 1);
|
|
13767
13767
|
}
|
|
13768
13768
|
const errorText = await response.text().catch(() => "unknown error");
|
|
@@ -20793,7 +20793,7 @@ var init_official_skills = __esm({
|
|
|
20793
20793
|
"",
|
|
20794
20794
|
"## Search Rules",
|
|
20795
20795
|
"",
|
|
20796
|
-
"-
|
|
20796
|
+
"- 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
20797
|
"- 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
20798
|
'- 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
20799
|
"- Use `memorix_search` for a specific decision, bug, file, or prior change that the project context did not answer.",
|
|
@@ -21104,6 +21104,7 @@ var init_audit = __esm({
|
|
|
21104
21104
|
var installers_exports = {};
|
|
21105
21105
|
__export(installers_exports, {
|
|
21106
21106
|
detectInstalledAgents: () => detectInstalledAgents,
|
|
21107
|
+
getAgentRulesPath: () => getAgentRulesPath,
|
|
21107
21108
|
getGlobalConfigPath: () => getGlobalConfigPath,
|
|
21108
21109
|
getHookStatus: () => getHookStatus,
|
|
21109
21110
|
getProjectConfigPath: () => getProjectConfigPath,
|
|
@@ -21728,8 +21729,8 @@ async function installHooks(agent, projectRoot, global2 = false) {
|
|
|
21728
21729
|
try {
|
|
21729
21730
|
const { access: access3, unlink: unlink2 } = await import("fs/promises");
|
|
21730
21731
|
await access3(entry.path);
|
|
21731
|
-
const
|
|
21732
|
-
if (
|
|
21732
|
+
const basename5 = path13.basename(entry.path);
|
|
21733
|
+
if (basename5 === "AGENTS.md" || basename5 === "GEMINI.md" || basename5 === "CONTEXT.md") {
|
|
21733
21734
|
continue;
|
|
21734
21735
|
}
|
|
21735
21736
|
await unlink2(entry.path);
|
|
@@ -21970,7 +21971,7 @@ function getAgentRulesContent(agent, scope = "project") {
|
|
|
21970
21971
|
let frontmatter = "";
|
|
21971
21972
|
const contextNoun = scope === "global" ? "workspace" : "project";
|
|
21972
21973
|
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.
|
|
21974
|
+
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
21975
|
if (agent === "windsurf") {
|
|
21975
21976
|
frontmatter = "---\ntrigger: always_on\n---\n\n";
|
|
21976
21977
|
} else if (agent === "cursor") {
|
|
@@ -21988,7 +21989,7 @@ alwaysApply: true
|
|
|
21988
21989
|
"",
|
|
21989
21990
|
"## Start with Memory Autopilot",
|
|
21990
21991
|
"",
|
|
21991
|
-
`
|
|
21992
|
+
`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
21993
|
"",
|
|
21993
21994
|
'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
21995
|
"",
|
|
@@ -22082,8 +22083,8 @@ async function uninstallHooks(agent, projectRoot, global2 = false) {
|
|
|
22082
22083
|
const agentFiles = prevFiles.filter((e3) => e3.agent === agent);
|
|
22083
22084
|
for (const entry of agentFiles) {
|
|
22084
22085
|
try {
|
|
22085
|
-
const
|
|
22086
|
-
if (
|
|
22086
|
+
const basename5 = path13.basename(entry.path);
|
|
22087
|
+
if (basename5 === "AGENTS.md" || basename5 === "GEMINI.md" || basename5 === "CONTEXT.md") {
|
|
22087
22088
|
try {
|
|
22088
22089
|
const content = await fs9.readFile(entry.path, "utf-8");
|
|
22089
22090
|
const memorixStart = content.indexOf("# Memorix");
|
|
@@ -22209,8 +22210,10 @@ var init_installers = __esm({
|
|
|
22209
22210
|
// src/cli/commands/setup.ts
|
|
22210
22211
|
var setup_exports = {};
|
|
22211
22212
|
__export(setup_exports, {
|
|
22213
|
+
buildMemorixServer: () => buildMemorixServer,
|
|
22212
22214
|
buildSetupPlan: () => buildSetupPlan,
|
|
22213
22215
|
default: () => setup_default,
|
|
22216
|
+
getMcpAdapter: () => getMcpAdapter,
|
|
22214
22217
|
getSetupAgentTargets: () => getSetupAgentTargets,
|
|
22215
22218
|
getSetupIntegrationRows: () => getSetupIntegrationRows2,
|
|
22216
22219
|
installAntigravityPluginPackage: () => installAntigravityPluginPackage,
|
|
@@ -26328,7 +26331,8 @@ function walk(root, exclude, maxFiles) {
|
|
|
26328
26331
|
const rel = normalizeCodePath(relative(root, abs));
|
|
26329
26332
|
if (isExcluded(rel, exclude)) continue;
|
|
26330
26333
|
if (entry.isDirectory()) {
|
|
26331
|
-
if (entry.name === ".git" || entry.name === "node_modules") continue;
|
|
26334
|
+
if (entry.name === ".git" || entry.name === ".worktrees" || entry.name === ".tmp" || entry.name === "node_modules") continue;
|
|
26335
|
+
if (rel === ".claude/worktrees" || rel.startsWith(".claude/worktrees/")) continue;
|
|
26332
26336
|
visit(abs);
|
|
26333
26337
|
if (out.length >= maxFiles) return;
|
|
26334
26338
|
continue;
|
|
@@ -26420,7 +26424,10 @@ async function indexProjectLite(options2) {
|
|
|
26420
26424
|
"coverage/**",
|
|
26421
26425
|
".next/**",
|
|
26422
26426
|
".turbo/**",
|
|
26423
|
-
".git/**"
|
|
26427
|
+
".git/**",
|
|
26428
|
+
".tmp/**",
|
|
26429
|
+
".worktrees/**",
|
|
26430
|
+
".claude/worktrees/**"
|
|
26424
26431
|
];
|
|
26425
26432
|
const maxFiles = options2.maxFiles ?? 5e3;
|
|
26426
26433
|
const indexedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -26640,7 +26647,8 @@ function normalizePath2(path29) {
|
|
|
26640
26647
|
return path29.replace(/\\/g, "/");
|
|
26641
26648
|
}
|
|
26642
26649
|
function isGeneratedPath(path29) {
|
|
26643
|
-
|
|
26650
|
+
const normalized = normalizePath2(path29);
|
|
26651
|
+
return /(^|\/)(dist|build|coverage|\.next|\.turbo|node_modules|\.git|\.tmp|\.worktrees)(\/|$)/i.test(normalized) || /(^|\/)\.claude\/worktrees(\/|$)/i.test(normalized);
|
|
26644
26652
|
}
|
|
26645
26653
|
function suggestedReadRank(path29) {
|
|
26646
26654
|
const normalized = normalizePath2(path29);
|
|
@@ -27509,7 +27517,8 @@ function timestampOf(observation) {
|
|
|
27509
27517
|
return Date.parse(observation.updatedAt ?? observation.createdAt ?? "") || 0;
|
|
27510
27518
|
}
|
|
27511
27519
|
function isGeneratedPath2(path29) {
|
|
27512
|
-
|
|
27520
|
+
const normalized = path29.replace(/\\/g, "/");
|
|
27521
|
+
return /(^|\/)(dist|build|coverage|\.next|\.turbo|node_modules|\.git|\.tmp|\.worktrees)(\/|$)/i.test(normalized) || /(^|\/)\.claude\/worktrees(\/|$)/i.test(normalized);
|
|
27513
27522
|
}
|
|
27514
27523
|
function relevanceScore(observation, taskTokens) {
|
|
27515
27524
|
if (taskTokens.length === 0) return 0;
|
|
@@ -43369,12 +43378,12 @@ var init_stdio2 = __esm({
|
|
|
43369
43378
|
this.onclose?.();
|
|
43370
43379
|
}
|
|
43371
43380
|
send(message) {
|
|
43372
|
-
return new Promise((
|
|
43381
|
+
return new Promise((resolve4) => {
|
|
43373
43382
|
const json = serializeMessage(message);
|
|
43374
43383
|
if (this._stdout.write(json)) {
|
|
43375
|
-
|
|
43384
|
+
resolve4();
|
|
43376
43385
|
} else {
|
|
43377
|
-
this._stdout.once("drain",
|
|
43386
|
+
this._stdout.once("drain", resolve4);
|
|
43378
43387
|
}
|
|
43379
43388
|
});
|
|
43380
43389
|
}
|
|
@@ -45907,7 +45916,7 @@ var init_protocol = __esm({
|
|
|
45907
45916
|
return;
|
|
45908
45917
|
}
|
|
45909
45918
|
const pollInterval = task2.pollInterval ?? this._options?.defaultTaskPollInterval ?? 1e3;
|
|
45910
|
-
await new Promise((
|
|
45919
|
+
await new Promise((resolve4) => setTimeout(resolve4, pollInterval));
|
|
45911
45920
|
options2?.signal?.throwIfAborted();
|
|
45912
45921
|
}
|
|
45913
45922
|
} catch (error2) {
|
|
@@ -45924,7 +45933,7 @@ var init_protocol = __esm({
|
|
|
45924
45933
|
*/
|
|
45925
45934
|
request(request, resultSchema, options2) {
|
|
45926
45935
|
const { relatedRequestId, resumptionToken, onresumptiontoken, task, relatedTask } = options2 ?? {};
|
|
45927
|
-
return new Promise((
|
|
45936
|
+
return new Promise((resolve4, reject) => {
|
|
45928
45937
|
const earlyReject = (error2) => {
|
|
45929
45938
|
reject(error2);
|
|
45930
45939
|
};
|
|
@@ -46002,7 +46011,7 @@ var init_protocol = __esm({
|
|
|
46002
46011
|
if (!parseResult.success) {
|
|
46003
46012
|
reject(parseResult.error);
|
|
46004
46013
|
} else {
|
|
46005
|
-
|
|
46014
|
+
resolve4(parseResult.data);
|
|
46006
46015
|
}
|
|
46007
46016
|
} catch (error2) {
|
|
46008
46017
|
reject(error2);
|
|
@@ -46263,12 +46272,12 @@ var init_protocol = __esm({
|
|
|
46263
46272
|
}
|
|
46264
46273
|
} catch {
|
|
46265
46274
|
}
|
|
46266
|
-
return new Promise((
|
|
46275
|
+
return new Promise((resolve4, reject) => {
|
|
46267
46276
|
if (signal.aborted) {
|
|
46268
46277
|
reject(new McpError(ErrorCode.InvalidRequest, "Request cancelled"));
|
|
46269
46278
|
return;
|
|
46270
46279
|
}
|
|
46271
|
-
const timeoutId = setTimeout(
|
|
46280
|
+
const timeoutId = setTimeout(resolve4, interval);
|
|
46272
46281
|
signal.addEventListener("abort", () => {
|
|
46273
46282
|
clearTimeout(timeoutId);
|
|
46274
46283
|
reject(new McpError(ErrorCode.InvalidRequest, "Request cancelled"));
|
|
@@ -49316,7 +49325,7 @@ var require_compile = __commonJS({
|
|
|
49316
49325
|
const schOrFunc = root.refs[ref];
|
|
49317
49326
|
if (schOrFunc)
|
|
49318
49327
|
return schOrFunc;
|
|
49319
|
-
let _sch =
|
|
49328
|
+
let _sch = resolve4.call(this, root, ref);
|
|
49320
49329
|
if (_sch === void 0) {
|
|
49321
49330
|
const schema = (_a = root.localRefs) === null || _a === void 0 ? void 0 : _a[ref];
|
|
49322
49331
|
const { schemaId } = this.opts;
|
|
@@ -49343,7 +49352,7 @@ var require_compile = __commonJS({
|
|
|
49343
49352
|
function sameSchemaEnv(s1, s2) {
|
|
49344
49353
|
return s1.schema === s2.schema && s1.root === s2.root && s1.baseId === s2.baseId;
|
|
49345
49354
|
}
|
|
49346
|
-
function
|
|
49355
|
+
function resolve4(root, ref) {
|
|
49347
49356
|
let sch;
|
|
49348
49357
|
while (typeof (sch = this.refs[ref]) == "string")
|
|
49349
49358
|
ref = sch;
|
|
@@ -49977,7 +49986,7 @@ var require_fast_uri = __commonJS({
|
|
|
49977
49986
|
}
|
|
49978
49987
|
return uri;
|
|
49979
49988
|
}
|
|
49980
|
-
function
|
|
49989
|
+
function resolve4(baseURI, relativeURI, options2) {
|
|
49981
49990
|
const schemelessOptions = options2 ? Object.assign({ scheme: "null" }, options2) : { scheme: "null" };
|
|
49982
49991
|
const resolved = resolveComponent(parse5(baseURI, schemelessOptions), parse5(relativeURI, schemelessOptions), schemelessOptions, true);
|
|
49983
49992
|
schemelessOptions.skipEscape = true;
|
|
@@ -50235,7 +50244,7 @@ var require_fast_uri = __commonJS({
|
|
|
50235
50244
|
var fastUri = {
|
|
50236
50245
|
SCHEMES,
|
|
50237
50246
|
normalize,
|
|
50238
|
-
resolve:
|
|
50247
|
+
resolve: resolve4,
|
|
50239
50248
|
resolveComponent,
|
|
50240
50249
|
equal,
|
|
50241
50250
|
serialize,
|
|
@@ -54417,7 +54426,7 @@ var init_mcp = __esm({
|
|
|
54417
54426
|
let task = createTaskResult.task;
|
|
54418
54427
|
const pollInterval = task.pollInterval ?? 5e3;
|
|
54419
54428
|
while (task.status !== "completed" && task.status !== "failed" && task.status !== "cancelled") {
|
|
54420
|
-
await new Promise((
|
|
54429
|
+
await new Promise((resolve4) => setTimeout(resolve4, pollInterval));
|
|
54421
54430
|
const updatedTask = await extra.taskStore.getTask(taskId);
|
|
54422
54431
|
if (!updatedTask) {
|
|
54423
54432
|
throw new McpError(ErrorCode.InternalError, `Task ${taskId} not found during polling`);
|
|
@@ -54961,9 +54970,9 @@ async function createAutoRelations(obs, extracted, graphManager) {
|
|
|
54961
54970
|
}
|
|
54962
54971
|
}
|
|
54963
54972
|
for (const file of obs.filesModified) {
|
|
54964
|
-
const
|
|
54965
|
-
if (
|
|
54966
|
-
const matchedEntity = graphManager.findEntityByName(
|
|
54973
|
+
const basename5 = file.split("/").pop()?.replace(/\.\w+$/, "") ?? "";
|
|
54974
|
+
if (basename5.length < 3 || basename5.toLowerCase() === selfName) continue;
|
|
54975
|
+
const matchedEntity = graphManager.findEntityByName(basename5);
|
|
54967
54976
|
if (matchedEntity) {
|
|
54968
54977
|
relations.push({
|
|
54969
54978
|
from: obs.entityName,
|
|
@@ -54973,12 +54982,12 @@ async function createAutoRelations(obs, extracted, graphManager) {
|
|
|
54973
54982
|
}
|
|
54974
54983
|
}
|
|
54975
54984
|
if (relations.length === 0) return 0;
|
|
54976
|
-
const
|
|
54985
|
+
const unique2 = relations.filter(
|
|
54977
54986
|
(r4, i2, arr) => arr.findIndex(
|
|
54978
54987
|
(o3) => o3.from === r4.from && o3.to === r4.to && o3.relationType === r4.relationType
|
|
54979
54988
|
) === i2
|
|
54980
54989
|
);
|
|
54981
|
-
const created = await graphManager.createRelations(
|
|
54990
|
+
const created = await graphManager.createRelations(unique2);
|
|
54982
54991
|
return created.length;
|
|
54983
54992
|
}
|
|
54984
54993
|
var init_auto_relations = __esm({
|
|
@@ -56506,7 +56515,6 @@ var require_loader = __commonJS({
|
|
|
56506
56515
|
this.legacy = options2["legacy"] || false;
|
|
56507
56516
|
this.json = options2["json"] || false;
|
|
56508
56517
|
this.listener = options2["listener"] || null;
|
|
56509
|
-
this.maxTotalMergeKeys = typeof options2["maxTotalMergeKeys"] === "number" ? options2["maxTotalMergeKeys"] : 1e4;
|
|
56510
56518
|
this.implicitTypes = this.schema.compiledImplicit;
|
|
56511
56519
|
this.typeMap = this.schema.compiledTypeMap;
|
|
56512
56520
|
this.length = input.length;
|
|
@@ -56514,7 +56522,6 @@ var require_loader = __commonJS({
|
|
|
56514
56522
|
this.line = 0;
|
|
56515
56523
|
this.lineStart = 0;
|
|
56516
56524
|
this.lineIndent = 0;
|
|
56517
|
-
this.totalMergeKeys = 0;
|
|
56518
56525
|
this.documents = [];
|
|
56519
56526
|
}
|
|
56520
56527
|
function generateError(state, message) {
|
|
@@ -56599,9 +56606,6 @@ var require_loader = __commonJS({
|
|
|
56599
56606
|
sourceKeys = Object.keys(source);
|
|
56600
56607
|
for (index = 0, quantity = sourceKeys.length; index < quantity; index += 1) {
|
|
56601
56608
|
key = sourceKeys[index];
|
|
56602
|
-
if (state.maxTotalMergeKeys !== -1 && ++state.totalMergeKeys > state.maxTotalMergeKeys) {
|
|
56603
|
-
throwError(state, "merge keys exceeded maxTotalMergeKeys (" + state.maxTotalMergeKeys + ")");
|
|
56604
|
-
}
|
|
56605
56609
|
if (!_hasOwnProperty.call(destination, key)) {
|
|
56606
56610
|
setProperty(destination, key, source[key]);
|
|
56607
56611
|
overridableKeys[key] = true;
|
|
@@ -60918,7 +60922,7 @@ async function handleApi(req, res, dataDir, projectId, projectName, baseDir, pro
|
|
|
60918
60922
|
}
|
|
60919
60923
|
case "/config": {
|
|
60920
60924
|
const os5 = await import("os");
|
|
60921
|
-
const { existsSync:
|
|
60925
|
+
const { existsSync: existsSync26 } = await import("fs");
|
|
60922
60926
|
const { join: join32 } = await import("path");
|
|
60923
60927
|
let yml = {};
|
|
60924
60928
|
const configProjectRoot = effectiveProjectRoot;
|
|
@@ -60954,7 +60958,7 @@ async function handleApi(req, res, dataDir, projectId, projectName, baseDir, pro
|
|
|
60954
60958
|
if (fpath === null) {
|
|
60955
60959
|
files[key] = { exists: false, path: "unavailable", unavailable: true };
|
|
60956
60960
|
} else {
|
|
60957
|
-
files[key] = { exists:
|
|
60961
|
+
files[key] = { exists: existsSync26(fpath), path: fpath };
|
|
60958
60962
|
}
|
|
60959
60963
|
}
|
|
60960
60964
|
} catch {
|
|
@@ -61329,10 +61333,10 @@ async function buildTeamSnapshot(dataDir, projectId, scope, mode) {
|
|
|
61329
61333
|
}
|
|
61330
61334
|
}
|
|
61331
61335
|
function readBody(req) {
|
|
61332
|
-
return new Promise((
|
|
61336
|
+
return new Promise((resolve4, reject) => {
|
|
61333
61337
|
const chunks = [];
|
|
61334
61338
|
req.on("data", (c5) => chunks.push(c5));
|
|
61335
|
-
req.on("end", () =>
|
|
61339
|
+
req.on("end", () => resolve4(Buffer.concat(chunks).toString("utf-8")));
|
|
61336
61340
|
req.on("error", reject);
|
|
61337
61341
|
});
|
|
61338
61342
|
}
|
|
@@ -61420,7 +61424,7 @@ async function startDashboard(dataDir, port, staticDir, projectId, projectName,
|
|
|
61420
61424
|
await serveStatic(req, res, resolvedStaticDir);
|
|
61421
61425
|
}
|
|
61422
61426
|
});
|
|
61423
|
-
return new Promise((
|
|
61427
|
+
return new Promise((resolve4, reject) => {
|
|
61424
61428
|
server.on("error", (err) => {
|
|
61425
61429
|
if (err.code === "EADDRINUSE") {
|
|
61426
61430
|
console.error(`Port ${port} is already in use. Try: memorix dashboard --port ${port + 1}`);
|
|
@@ -61444,7 +61448,7 @@ async function startDashboard(dataDir, port, staticDir, projectId, projectName,
|
|
|
61444
61448
|
Press Ctrl+C to stop
|
|
61445
61449
|
`);
|
|
61446
61450
|
if (autoOpen) openBrowser(url);
|
|
61447
|
-
|
|
61451
|
+
resolve4();
|
|
61448
61452
|
});
|
|
61449
61453
|
});
|
|
61450
61454
|
}
|
|
@@ -61960,7 +61964,7 @@ The path should point to a directory containing a .git folder.`
|
|
|
61960
61964
|
};
|
|
61961
61965
|
const server = existingServer ?? new McpServer({
|
|
61962
61966
|
name: "memorix",
|
|
61963
|
-
version: true ? "1.1.
|
|
61967
|
+
version: true ? "1.1.8" : "1.0.1"
|
|
61964
61968
|
});
|
|
61965
61969
|
const originalRegisterTool = server.registerTool.bind(server);
|
|
61966
61970
|
server.registerTool = ((name, ...args) => {
|
|
@@ -62969,12 +62973,12 @@ Run with dryRun=false to apply.`
|
|
|
62969
62973
|
}]
|
|
62970
62974
|
};
|
|
62971
62975
|
}
|
|
62972
|
-
const
|
|
62973
|
-
await resolveObservations2(
|
|
62976
|
+
const unique2 = [...new Set(toResolve)];
|
|
62977
|
+
await resolveObservations2(unique2, "resolved");
|
|
62974
62978
|
return {
|
|
62975
62979
|
content: [{
|
|
62976
62980
|
type: "text",
|
|
62977
|
-
text: `[CLEANUP] Deduplicated: resolved ${
|
|
62981
|
+
text: `[CLEANUP] Deduplicated: resolved ${unique2.length} memory(ies)
|
|
62978
62982
|
|
|
62979
62983
|
${actions.join("\n")}`
|
|
62980
62984
|
}]
|
|
@@ -63299,10 +63303,10 @@ Archived memories are hidden from default search but can be found with status: "
|
|
|
63299
63303
|
);
|
|
63300
63304
|
let enableKG = isToolInProfile("create_entities", toolProfile);
|
|
63301
63305
|
try {
|
|
63302
|
-
const { homedir:
|
|
63306
|
+
const { homedir: homedir34 } = await import("os");
|
|
63303
63307
|
const { join: join32 } = await import("path");
|
|
63304
|
-
const { readFile:
|
|
63305
|
-
const raw = await
|
|
63308
|
+
const { readFile: readFile8 } = await import("fs/promises");
|
|
63309
|
+
const raw = await readFile8(join32(homedir34(), ".memorix", "settings.json"), "utf-8");
|
|
63306
63310
|
const s2 = JSON.parse(raw);
|
|
63307
63311
|
if (s2.knowledgeGraph === true) enableKG = true;
|
|
63308
63312
|
} catch {
|
|
@@ -64220,15 +64224,15 @@ ${json}
|
|
|
64220
64224
|
if (inControlPlane) {
|
|
64221
64225
|
const http = await import("http");
|
|
64222
64226
|
const postData = JSON.stringify({ projectId: project.id, projectName: project.name });
|
|
64223
|
-
await new Promise((
|
|
64227
|
+
await new Promise((resolve4) => {
|
|
64224
64228
|
const req = http.request({
|
|
64225
64229
|
hostname: "127.0.0.1",
|
|
64226
64230
|
port: portNum,
|
|
64227
64231
|
path: "/api/set-current-project",
|
|
64228
64232
|
method: "POST",
|
|
64229
64233
|
headers: { "Content-Type": "application/json", "Content-Length": Buffer.byteLength(postData) }
|
|
64230
|
-
}, () =>
|
|
64231
|
-
req.on("error", () =>
|
|
64234
|
+
}, () => resolve4());
|
|
64235
|
+
req.on("error", () => resolve4());
|
|
64232
64236
|
req.write(postData);
|
|
64233
64237
|
req.end();
|
|
64234
64238
|
});
|
|
@@ -64253,33 +64257,33 @@ ${json}
|
|
|
64253
64257
|
}
|
|
64254
64258
|
if (dashboardRunning) {
|
|
64255
64259
|
const { createConnection } = await import("net");
|
|
64256
|
-
const isAlive = await new Promise((
|
|
64260
|
+
const isAlive = await new Promise((resolve4) => {
|
|
64257
64261
|
const sock = createConnection(portNum, "127.0.0.1");
|
|
64258
64262
|
sock.once("connect", () => {
|
|
64259
64263
|
sock.destroy();
|
|
64260
|
-
|
|
64264
|
+
resolve4(true);
|
|
64261
64265
|
});
|
|
64262
64266
|
sock.once("error", () => {
|
|
64263
64267
|
sock.destroy();
|
|
64264
|
-
|
|
64268
|
+
resolve4(false);
|
|
64265
64269
|
});
|
|
64266
64270
|
setTimeout(() => {
|
|
64267
64271
|
sock.destroy();
|
|
64268
|
-
|
|
64272
|
+
resolve4(false);
|
|
64269
64273
|
}, 1e3);
|
|
64270
64274
|
});
|
|
64271
64275
|
if (isAlive) {
|
|
64272
64276
|
const http = await import("http");
|
|
64273
64277
|
const postData = JSON.stringify({ projectId: project.id, projectName: project.name });
|
|
64274
|
-
await new Promise((
|
|
64278
|
+
await new Promise((resolve4) => {
|
|
64275
64279
|
const req = http.request({
|
|
64276
64280
|
hostname: "127.0.0.1",
|
|
64277
64281
|
port: portNum,
|
|
64278
64282
|
path: "/api/set-current-project",
|
|
64279
64283
|
method: "POST",
|
|
64280
64284
|
headers: { "Content-Type": "application/json", "Content-Length": Buffer.byteLength(postData) }
|
|
64281
|
-
}, () =>
|
|
64282
|
-
req.on("error", () =>
|
|
64285
|
+
}, () => resolve4());
|
|
64286
|
+
req.on("error", () => resolve4());
|
|
64283
64287
|
req.write(postData);
|
|
64284
64288
|
req.end();
|
|
64285
64289
|
});
|
|
@@ -64325,18 +64329,18 @@ ${json}
|
|
|
64325
64329
|
dashboardRunning = false;
|
|
64326
64330
|
});
|
|
64327
64331
|
const { createConnection } = await import("net");
|
|
64328
|
-
await new Promise((
|
|
64332
|
+
await new Promise((resolve4) => {
|
|
64329
64333
|
const deadline = Date.now() + 5e3;
|
|
64330
64334
|
const tryConnect = () => {
|
|
64331
64335
|
const sock = createConnection(portNum, "127.0.0.1");
|
|
64332
64336
|
sock.once("connect", () => {
|
|
64333
64337
|
sock.destroy();
|
|
64334
|
-
|
|
64338
|
+
resolve4();
|
|
64335
64339
|
});
|
|
64336
64340
|
sock.once("error", () => {
|
|
64337
64341
|
sock.destroy();
|
|
64338
64342
|
if (Date.now() < deadline) setTimeout(tryConnect, 100);
|
|
64339
|
-
else
|
|
64343
|
+
else resolve4();
|
|
64340
64344
|
});
|
|
64341
64345
|
};
|
|
64342
64346
|
tryConnect();
|
|
@@ -64898,10 +64902,10 @@ Preview: ${analysis.description.slice(0, 300)}${analysis.description.length > 30
|
|
|
64898
64902
|
const { ensureHooksDir: ensureHooksDir2 } = await Promise.resolve().then(() => (init_hooks_path(), hooks_path_exports));
|
|
64899
64903
|
const resolved = ensureHooksDir2(project.rootPath);
|
|
64900
64904
|
if (resolved) {
|
|
64901
|
-
const { existsSync:
|
|
64905
|
+
const { existsSync: existsSync26, readFileSync: readFileSync22, writeFileSync: writeFileSync11, chmodSync: chmodSync2 } = await import("fs");
|
|
64902
64906
|
const { hookPath } = resolved;
|
|
64903
64907
|
const HOOK_MARKER3 = "# [memorix-git-hook]";
|
|
64904
|
-
const needsInstall = !
|
|
64908
|
+
const needsInstall = !existsSync26(hookPath) || !readFileSync22(hookPath, "utf-8").includes(HOOK_MARKER3);
|
|
64905
64909
|
if (needsInstall) {
|
|
64906
64910
|
const hookScript = `#!/bin/sh
|
|
64907
64911
|
${HOOK_MARKER3}
|
|
@@ -64910,7 +64914,7 @@ if command -v memorix >/dev/null 2>&1; then
|
|
|
64910
64914
|
memorix ingest commit --auto >/dev/null 2>&1 &
|
|
64911
64915
|
fi
|
|
64912
64916
|
`;
|
|
64913
|
-
if (
|
|
64917
|
+
if (existsSync26(hookPath)) {
|
|
64914
64918
|
const existing = readFileSync22(hookPath, "utf-8");
|
|
64915
64919
|
writeFileSync11(hookPath, existing.trimEnd() + `
|
|
64916
64920
|
|
|
@@ -65362,10 +65366,10 @@ function describeAutoUpdateFailure(error2, timeoutMs) {
|
|
|
65362
65366
|
async function fetchLatestVersion() {
|
|
65363
65367
|
try {
|
|
65364
65368
|
const { default: https } = await import("https");
|
|
65365
|
-
return new Promise((
|
|
65369
|
+
return new Promise((resolve4) => {
|
|
65366
65370
|
const req = https.get(REGISTRY_URL, { timeout: 5e3 }, (res) => {
|
|
65367
65371
|
if (res.statusCode !== 200) {
|
|
65368
|
-
|
|
65372
|
+
resolve4(null);
|
|
65369
65373
|
return;
|
|
65370
65374
|
}
|
|
65371
65375
|
let body = "";
|
|
@@ -65375,16 +65379,16 @@ async function fetchLatestVersion() {
|
|
|
65375
65379
|
res.on("end", () => {
|
|
65376
65380
|
try {
|
|
65377
65381
|
const data = JSON.parse(body);
|
|
65378
|
-
|
|
65382
|
+
resolve4(data.version ?? null);
|
|
65379
65383
|
} catch {
|
|
65380
|
-
|
|
65384
|
+
resolve4(null);
|
|
65381
65385
|
}
|
|
65382
65386
|
});
|
|
65383
65387
|
});
|
|
65384
|
-
req.on("error", () =>
|
|
65388
|
+
req.on("error", () => resolve4(null));
|
|
65385
65389
|
req.on("timeout", () => {
|
|
65386
65390
|
req.destroy();
|
|
65387
|
-
|
|
65391
|
+
resolve4(null);
|
|
65388
65392
|
});
|
|
65389
65393
|
});
|
|
65390
65394
|
} catch {
|
|
@@ -65533,7 +65537,7 @@ var init_serve = __esm({
|
|
|
65533
65537
|
const { StdioServerTransport: StdioServerTransport2 } = await Promise.resolve().then(() => (init_stdio2(), stdio_exports));
|
|
65534
65538
|
const { createMemorixServer: createMemorixServer2 } = await Promise.resolve().then(() => (init_server4(), server_exports2));
|
|
65535
65539
|
const { detectProject: detectProject2, findGitInSubdirs: findGitInSubdirs2, isSystemDirectory: isSystemDirectory2 } = await Promise.resolve().then(() => (init_detector(), detector_exports));
|
|
65536
|
-
const { homedir:
|
|
65540
|
+
const { homedir: homedir34 } = await import("os");
|
|
65537
65541
|
const { resolveServeProject: resolveServeProject2 } = await Promise.resolve().then(() => (init_serve_shared(), serve_shared_exports));
|
|
65538
65542
|
process.stdin.on("end", () => {
|
|
65539
65543
|
console.error("[memorix] stdin closed \u2014 exiting");
|
|
@@ -65543,16 +65547,16 @@ var init_serve = __esm({
|
|
|
65543
65547
|
try {
|
|
65544
65548
|
safeCwd = process.cwd();
|
|
65545
65549
|
} catch {
|
|
65546
|
-
safeCwd =
|
|
65550
|
+
safeCwd = homedir34();
|
|
65547
65551
|
}
|
|
65548
|
-
const { existsSync:
|
|
65552
|
+
const { existsSync: existsSync26, readFileSync: readFileSync22 } = await import("fs");
|
|
65549
65553
|
const path29 = await import("path");
|
|
65550
|
-
const lastRootFile = path29.join(
|
|
65554
|
+
const lastRootFile = path29.join(homedir34(), ".memorix", "last-project-root");
|
|
65551
65555
|
let lastKnownProjectRoot;
|
|
65552
|
-
if (
|
|
65556
|
+
if (existsSync26(lastRootFile)) {
|
|
65553
65557
|
try {
|
|
65554
65558
|
const lastRoot = readFileSync22(lastRootFile, "utf-8").trim();
|
|
65555
|
-
if (lastRoot &&
|
|
65559
|
+
if (lastRoot && existsSync26(lastRoot)) {
|
|
65556
65560
|
lastKnownProjectRoot = lastRoot;
|
|
65557
65561
|
}
|
|
65558
65562
|
} catch {
|
|
@@ -65564,7 +65568,7 @@ var init_serve = __esm({
|
|
|
65564
65568
|
envProjectRoot: process.env.MEMORIX_PROJECT_ROOT,
|
|
65565
65569
|
initCwd: process.env.INIT_CWD,
|
|
65566
65570
|
processCwd: safeCwd,
|
|
65567
|
-
homeDir:
|
|
65571
|
+
homeDir: homedir34(),
|
|
65568
65572
|
lastKnownProjectRoot
|
|
65569
65573
|
},
|
|
65570
65574
|
{ detectProject: detectProject2, findGitInSubdirs: findGitInSubdirs2, isSystemDirectory: isSystemDirectory2 }
|
|
@@ -65582,7 +65586,7 @@ var init_serve = __esm({
|
|
|
65582
65586
|
if (detected) {
|
|
65583
65587
|
try {
|
|
65584
65588
|
const { writeFileSync: writeFileSync11, mkdirSync: mkdirSync11 } = await import("fs");
|
|
65585
|
-
const memorixDir = path29.join(
|
|
65589
|
+
const memorixDir = path29.join(homedir34(), ".memorix");
|
|
65586
65590
|
mkdirSync11(memorixDir, { recursive: true });
|
|
65587
65591
|
writeFileSync11(path29.join(memorixDir, "last-project-root"), detected.rootPath, "utf-8");
|
|
65588
65592
|
} catch {
|
|
@@ -65600,7 +65604,7 @@ var init_serve = __esm({
|
|
|
65600
65604
|
try {
|
|
65601
65605
|
const { writeFileSync: writeFileSync11, mkdirSync: mkdirSync11 } = await import("fs");
|
|
65602
65606
|
const pathMod = await import("path");
|
|
65603
|
-
const memorixDir = pathMod.join(
|
|
65607
|
+
const memorixDir = pathMod.join(homedir34(), ".memorix");
|
|
65604
65608
|
mkdirSync11(memorixDir, { recursive: true });
|
|
65605
65609
|
writeFileSync11(pathMod.join(memorixDir, "last-project-root"), rootPath, "utf-8");
|
|
65606
65610
|
} catch {
|
|
@@ -66156,7 +66160,7 @@ var init_dist5 = __esm({
|
|
|
66156
66160
|
});
|
|
66157
66161
|
if (!chunk) {
|
|
66158
66162
|
if (i2 === 1) {
|
|
66159
|
-
await new Promise((
|
|
66163
|
+
await new Promise((resolve4) => setTimeout(resolve4));
|
|
66160
66164
|
maxReadCount = 3;
|
|
66161
66165
|
continue;
|
|
66162
66166
|
}
|
|
@@ -66664,9 +66668,9 @@ data:
|
|
|
66664
66668
|
const initRequest = messages.find((m4) => isInitializeRequest(m4));
|
|
66665
66669
|
const clientProtocolVersion = initRequest ? initRequest.params.protocolVersion : req.headers.get("mcp-protocol-version") ?? DEFAULT_NEGOTIATED_PROTOCOL_VERSION;
|
|
66666
66670
|
if (this._enableJsonResponse) {
|
|
66667
|
-
return new Promise((
|
|
66671
|
+
return new Promise((resolve4) => {
|
|
66668
66672
|
this._streamMapping.set(streamId, {
|
|
66669
|
-
resolveJson:
|
|
66673
|
+
resolveJson: resolve4,
|
|
66670
66674
|
cleanup: () => {
|
|
66671
66675
|
this._streamMapping.delete(streamId);
|
|
66672
66676
|
}
|
|
@@ -67068,8 +67072,8 @@ var init_serve_http = __esm({
|
|
|
67068
67072
|
const { isInitializeRequest: isInitializeRequest2 } = await Promise.resolve().then(() => (init_types4(), types_exports));
|
|
67069
67073
|
const { createMemorixServer: createMemorixServer2 } = await Promise.resolve().then(() => (init_server4(), server_exports2));
|
|
67070
67074
|
const { findGitInSubdirs: findGitInSubdirs2, detectProjectWithDiagnostics: detectProjectWithDiagnostics2 } = await Promise.resolve().then(() => (init_detector(), detector_exports));
|
|
67071
|
-
const { existsSync:
|
|
67072
|
-
const { homedir:
|
|
67075
|
+
const { existsSync: existsSync26, readFileSync: readFileSync22, writeFileSync: writeFileSync11, mkdirSync: mkdirSync11 } = await import("fs");
|
|
67076
|
+
const { homedir: homedir34 } = await import("os");
|
|
67073
67077
|
const earlyPath = await import("path");
|
|
67074
67078
|
const port = parseInt(args.port || "3211", 10);
|
|
67075
67079
|
const host = args.host || "127.0.0.1";
|
|
@@ -67078,15 +67082,15 @@ var init_serve_http = __esm({
|
|
|
67078
67082
|
try {
|
|
67079
67083
|
safeCwd = process.cwd();
|
|
67080
67084
|
} catch {
|
|
67081
|
-
safeCwd =
|
|
67085
|
+
safeCwd = homedir34();
|
|
67082
67086
|
}
|
|
67083
67087
|
let projectRoot = args.cwd || process.env.MEMORIX_PROJECT_ROOT || safeCwd;
|
|
67084
|
-
const lastRootFile = earlyPath.join(
|
|
67088
|
+
const lastRootFile = earlyPath.join(homedir34(), ".memorix", "last-project-root");
|
|
67085
67089
|
const initialCheck = detectProjectWithDiagnostics2(projectRoot);
|
|
67086
|
-
if (!initialCheck.project &&
|
|
67090
|
+
if (!initialCheck.project && existsSync26(lastRootFile)) {
|
|
67087
67091
|
try {
|
|
67088
67092
|
const lastRoot = readFileSync22(lastRootFile, "utf-8").trim();
|
|
67089
|
-
if (lastRoot &&
|
|
67093
|
+
if (lastRoot && existsSync26(lastRoot)) {
|
|
67090
67094
|
const lastCheck = detectProjectWithDiagnostics2(lastRoot);
|
|
67091
67095
|
if (lastCheck.project) {
|
|
67092
67096
|
console.error(`[memorix] No git at "${projectRoot}", restored last known project: ${lastRoot}`);
|
|
@@ -67129,13 +67133,13 @@ var init_serve_http = __esm({
|
|
|
67129
67133
|
}
|
|
67130
67134
|
}
|
|
67131
67135
|
function parseBody(req) {
|
|
67132
|
-
return new Promise((
|
|
67136
|
+
return new Promise((resolve4, reject) => {
|
|
67133
67137
|
const chunks = [];
|
|
67134
67138
|
req.on("data", (chunk) => chunks.push(chunk));
|
|
67135
67139
|
req.on("end", () => {
|
|
67136
67140
|
try {
|
|
67137
67141
|
const body = Buffer.concat(chunks).toString("utf-8");
|
|
67138
|
-
|
|
67142
|
+
resolve4(body ? JSON.parse(body) : void 0);
|
|
67139
67143
|
} catch (err) {
|
|
67140
67144
|
reject(err);
|
|
67141
67145
|
}
|
|
@@ -67294,8 +67298,8 @@ var init_serve_http = __esm({
|
|
|
67294
67298
|
try {
|
|
67295
67299
|
const { writeFileSync: writeFileSync12, mkdirSync: mkdirSync12 } = await import("fs");
|
|
67296
67300
|
const pathMod = await import("path");
|
|
67297
|
-
const { homedir:
|
|
67298
|
-
const memorixDir = pathMod.join(
|
|
67301
|
+
const { homedir: homedir35 } = await import("os");
|
|
67302
|
+
const memorixDir = pathMod.join(homedir35(), ".memorix");
|
|
67299
67303
|
mkdirSync12(memorixDir, { recursive: true });
|
|
67300
67304
|
writeFileSync12(pathMod.join(memorixDir, "last-project-root"), rootPath, "utf-8");
|
|
67301
67305
|
} catch {
|
|
@@ -67785,7 +67789,7 @@ var init_serve_http = __esm({
|
|
|
67785
67789
|
if (apiPath === "/config") {
|
|
67786
67790
|
const { projectId: configProjectId } = await resolveRequestProject(url);
|
|
67787
67791
|
const os5 = await import("os");
|
|
67788
|
-
const { existsSync:
|
|
67792
|
+
const { existsSync: existsSync27 } = await import("fs");
|
|
67789
67793
|
const { join: join32 } = await import("path");
|
|
67790
67794
|
const { loadYamlConfig: loadYamlConfig2 } = await Promise.resolve().then(() => (init_yaml_loader(), yaml_loader_exports));
|
|
67791
67795
|
const { loadFileConfig: loadFileConfig2, loadDotenv: loadDotenv2, getLoadedEnvFiles: getLoadedEnvFiles2 } = await Promise.resolve().then(() => (init_config(), config_exports));
|
|
@@ -67807,7 +67811,7 @@ var init_serve_http = __esm({
|
|
|
67807
67811
|
"legacy config.json": join32(home, ".memorix", "config.json")
|
|
67808
67812
|
};
|
|
67809
67813
|
for (const [key, fpath] of Object.entries(paths)) {
|
|
67810
|
-
files[key] = { exists:
|
|
67814
|
+
files[key] = { exists: existsSync27(fpath), path: fpath };
|
|
67811
67815
|
}
|
|
67812
67816
|
} else {
|
|
67813
67817
|
files["project memorix.yml"] = { exists: false, path: "unavailable", unavailable: true };
|
|
@@ -67818,7 +67822,7 @@ var init_serve_http = __esm({
|
|
|
67818
67822
|
"legacy config.json": join32(home, ".memorix", "config.json")
|
|
67819
67823
|
};
|
|
67820
67824
|
for (const [key, fpath] of Object.entries(userPaths)) {
|
|
67821
|
-
files[key] = { exists:
|
|
67825
|
+
files[key] = { exists: existsSync27(fpath), path: fpath };
|
|
67822
67826
|
}
|
|
67823
67827
|
}
|
|
67824
67828
|
const values = [];
|
|
@@ -68300,7 +68304,7 @@ var init_status = __esm({
|
|
|
68300
68304
|
const { getProjectDataDir: getProjectDataDir2 } = await Promise.resolve().then(() => (init_persistence(), persistence_exports));
|
|
68301
68305
|
const { getEmbeddingProvider: getEmbeddingProvider2 } = await Promise.resolve().then(() => (init_provider(), provider_exports));
|
|
68302
68306
|
const { getResolvedConfig: getResolvedConfig2, getResolvedAgentLane: getResolvedAgentLane2 } = await Promise.resolve().then(() => (init_resolved_config(), resolved_config_exports));
|
|
68303
|
-
const { existsSync:
|
|
68307
|
+
const { existsSync: existsSync26, readFileSync: readFileSync22 } = await import("fs");
|
|
68304
68308
|
we("memorix status");
|
|
68305
68309
|
const project = detectProject2();
|
|
68306
68310
|
if (!project) {
|
|
@@ -68386,7 +68390,7 @@ Embedding: ${embeddingStatus}${embeddingHint}`,
|
|
|
68386
68390
|
try {
|
|
68387
68391
|
const { resolveHooksDir: resolveHooksDir2 } = await Promise.resolve().then(() => (init_hooks_path(), hooks_path_exports));
|
|
68388
68392
|
const resolved2 = resolveHooksDir2(project.rootPath);
|
|
68389
|
-
if (resolved2 &&
|
|
68393
|
+
if (resolved2 && existsSync26(resolved2.hookPath)) {
|
|
68390
68394
|
const hookContent = readFileSync22(resolved2.hookPath, "utf-8");
|
|
68391
68395
|
if (hookContent.includes("# [memorix-git-hook]")) {
|
|
68392
68396
|
diagLines.push(` Git hook: installed [OK]`);
|
|
@@ -69828,9 +69832,9 @@ async function handleHookEvent(input) {
|
|
|
69828
69832
|
};
|
|
69829
69833
|
}
|
|
69830
69834
|
async function runHook(agentOverride, eventOverride) {
|
|
69831
|
-
const rawInput = await new Promise((
|
|
69835
|
+
const rawInput = await new Promise((resolve4) => {
|
|
69832
69836
|
const chunks = [];
|
|
69833
|
-
const finish = () =>
|
|
69837
|
+
const finish = () => resolve4(Buffer.concat(chunks).toString("utf-8").trim());
|
|
69834
69838
|
const timer = setTimeout(() => {
|
|
69835
69839
|
process.stdin.removeAllListeners("data");
|
|
69836
69840
|
process.stdin.removeAllListeners("end");
|
|
@@ -71974,6 +71978,492 @@ var init_background = __esm({
|
|
|
71974
71978
|
}
|
|
71975
71979
|
});
|
|
71976
71980
|
|
|
71981
|
+
// src/cli/commands/agent-integrations.ts
|
|
71982
|
+
var agent_integrations_exports = {};
|
|
71983
|
+
__export(agent_integrations_exports, {
|
|
71984
|
+
formatAgentIntegrationReport: () => formatAgentIntegrationReport,
|
|
71985
|
+
formatAgentRepairResult: () => formatAgentRepairResult,
|
|
71986
|
+
inspectAgentIntegrations: () => inspectAgentIntegrations,
|
|
71987
|
+
repairAgentIntegrations: () => repairAgentIntegrations
|
|
71988
|
+
});
|
|
71989
|
+
import { existsSync as existsSync21 } from "fs";
|
|
71990
|
+
import { mkdir as mkdir7, readFile as readFile7, writeFile as writeFile7 } from "fs/promises";
|
|
71991
|
+
import { basename as basename3, dirname as dirname7, resolve as resolve2 } from "path";
|
|
71992
|
+
import { homedir as homedir32 } from "os";
|
|
71993
|
+
function requestedAgents(agent) {
|
|
71994
|
+
const all = getSetupAgentTargets();
|
|
71995
|
+
if (!agent || agent === "all") return all;
|
|
71996
|
+
return all.includes(agent) ? [agent] : [];
|
|
71997
|
+
}
|
|
71998
|
+
function requestedMcpScopes(agent, scope) {
|
|
71999
|
+
if (scope === "local") return agent === "claude" ? ["local"] : [];
|
|
72000
|
+
if (scope === "project" || scope === "global") return [scope];
|
|
72001
|
+
return agent === "claude" ? ["local", "project", "global"] : ["project", "global"];
|
|
72002
|
+
}
|
|
72003
|
+
function requestedGuidanceScopes(scope) {
|
|
72004
|
+
if (scope === "project" || scope === "global") return [scope];
|
|
72005
|
+
if (scope === "local") return [];
|
|
72006
|
+
return ["project", "global"];
|
|
72007
|
+
}
|
|
72008
|
+
function unique(values) {
|
|
72009
|
+
return [...new Set(values)];
|
|
72010
|
+
}
|
|
72011
|
+
function worstStatus(statuses) {
|
|
72012
|
+
if (statuses.includes("repairable")) return "repairable";
|
|
72013
|
+
if (statuses.includes("missing")) return "missing";
|
|
72014
|
+
if (statuses.includes("ok")) return "ok";
|
|
72015
|
+
return "skipped";
|
|
72016
|
+
}
|
|
72017
|
+
function isMcpConfigAgent(agent) {
|
|
72018
|
+
return agent !== "pi";
|
|
72019
|
+
}
|
|
72020
|
+
function isActionableMcpRepairIssue(issue2) {
|
|
72021
|
+
return issue2 !== "memorix-server-missing";
|
|
72022
|
+
}
|
|
72023
|
+
function aggregateMcpStatus(checks) {
|
|
72024
|
+
const actionableRepair = checks.some(
|
|
72025
|
+
(check2) => check2.status === "repairable" && check2.issues.some(isActionableMcpRepairIssue)
|
|
72026
|
+
);
|
|
72027
|
+
if (actionableRepair) return "repairable";
|
|
72028
|
+
if (checks.some((check2) => check2.status === "ok")) return "ok";
|
|
72029
|
+
if (checks.some((check2) => check2.status === "repairable")) return "repairable";
|
|
72030
|
+
if (checks.some((check2) => check2.status === "missing")) return "missing";
|
|
72031
|
+
return "skipped";
|
|
72032
|
+
}
|
|
72033
|
+
function aggregateMcpIssues(checks) {
|
|
72034
|
+
const status = aggregateMcpStatus(checks);
|
|
72035
|
+
if (status === "repairable") {
|
|
72036
|
+
return unique(checks.filter((check2) => check2.status === "repairable").flatMap((check2) => check2.issues.filter(isActionableMcpRepairIssue)));
|
|
72037
|
+
}
|
|
72038
|
+
if (status === "missing") {
|
|
72039
|
+
return unique(checks.filter((check2) => check2.status === "missing").flatMap((check2) => check2.issues));
|
|
72040
|
+
}
|
|
72041
|
+
return [];
|
|
72042
|
+
}
|
|
72043
|
+
function aggregateGuidanceStatus(checks) {
|
|
72044
|
+
const projectCheck = checks.find((check2) => check2.scope === "project");
|
|
72045
|
+
if (projectCheck?.status === "repairable") return "repairable";
|
|
72046
|
+
if (checks.some((check2) => check2.status === "ok")) return "ok";
|
|
72047
|
+
if (checks.some((check2) => check2.status === "repairable")) return "repairable";
|
|
72048
|
+
if (checks.some((check2) => check2.status === "missing")) return "missing";
|
|
72049
|
+
return "skipped";
|
|
72050
|
+
}
|
|
72051
|
+
function aggregateGuidanceIssues(checks) {
|
|
72052
|
+
const status = aggregateGuidanceStatus(checks);
|
|
72053
|
+
if (status === "repairable") {
|
|
72054
|
+
const projectCheck = checks.find((check2) => check2.scope === "project");
|
|
72055
|
+
if (projectCheck?.status === "repairable") return projectCheck.issues;
|
|
72056
|
+
return unique(checks.filter((check2) => check2.status === "repairable").flatMap((check2) => check2.issues));
|
|
72057
|
+
}
|
|
72058
|
+
if (status === "missing") {
|
|
72059
|
+
return unique(checks.filter((check2) => check2.status === "missing").flatMap((check2) => check2.issues));
|
|
72060
|
+
}
|
|
72061
|
+
return [];
|
|
72062
|
+
}
|
|
72063
|
+
function asRecord2(value) {
|
|
72064
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
72065
|
+
}
|
|
72066
|
+
function looksLikeStaleMemorixCommand(server) {
|
|
72067
|
+
const text = [server.command, ...server.args ?? []].join(" ");
|
|
72068
|
+
return /[\\/]\.worktrees[\\/]/i.test(text) || /[\\/]dist[\\/]cli[\\/]index\.js/i.test(text);
|
|
72069
|
+
}
|
|
72070
|
+
function isRecommendedStdioServer(server) {
|
|
72071
|
+
const commandBase = basename3(server.command).toLowerCase().replace(/\.(cmd|ps1|exe)$/i, "");
|
|
72072
|
+
return commandBase === "memorix" && server.args?.[0] === "serve";
|
|
72073
|
+
}
|
|
72074
|
+
function sanitizeServer(server) {
|
|
72075
|
+
if (server.url) {
|
|
72076
|
+
return {
|
|
72077
|
+
transport: "http",
|
|
72078
|
+
url: server.url,
|
|
72079
|
+
envKeys: server.env ? Object.keys(server.env) : void 0
|
|
72080
|
+
};
|
|
72081
|
+
}
|
|
72082
|
+
return {
|
|
72083
|
+
transport: "stdio",
|
|
72084
|
+
command: server.command,
|
|
72085
|
+
args: server.args ?? [],
|
|
72086
|
+
alwaysLoad: server.alwaysLoad,
|
|
72087
|
+
envKeys: server.env ? Object.keys(server.env) : void 0
|
|
72088
|
+
};
|
|
72089
|
+
}
|
|
72090
|
+
function normalizeProjectKey(projectRoot) {
|
|
72091
|
+
return resolve2(projectRoot).replace(/\\/g, "/").toLowerCase();
|
|
72092
|
+
}
|
|
72093
|
+
function defaultClaudeProjectKey(projectRoot) {
|
|
72094
|
+
return resolve2(projectRoot).replace(/\\/g, "/");
|
|
72095
|
+
}
|
|
72096
|
+
function getClaudeLocalConfigPath() {
|
|
72097
|
+
return `${homedir32()}/.claude.json`;
|
|
72098
|
+
}
|
|
72099
|
+
function coerceClaudeLocalServer(name, value) {
|
|
72100
|
+
const entry = asRecord2(value);
|
|
72101
|
+
if (!entry) return null;
|
|
72102
|
+
const args = Array.isArray(entry.args) ? entry.args.map(String) : [];
|
|
72103
|
+
return {
|
|
72104
|
+
name,
|
|
72105
|
+
command: typeof entry.command === "string" ? entry.command : "",
|
|
72106
|
+
args,
|
|
72107
|
+
...asRecord2(entry.env) ? { env: entry.env } : {},
|
|
72108
|
+
...typeof entry.url === "string" ? { url: entry.url } : {},
|
|
72109
|
+
...entry.alwaysLoad === true ? { alwaysLoad: true } : {}
|
|
72110
|
+
};
|
|
72111
|
+
}
|
|
72112
|
+
function findClaudeLocalProject(config2, projectRoot) {
|
|
72113
|
+
const projects = asRecord2(config2.projects);
|
|
72114
|
+
if (!projects) return null;
|
|
72115
|
+
const target = normalizeProjectKey(projectRoot);
|
|
72116
|
+
for (const [key, value] of Object.entries(projects)) {
|
|
72117
|
+
if (normalizeProjectKey(key) !== target) continue;
|
|
72118
|
+
const project = asRecord2(value);
|
|
72119
|
+
return project ? { key, project } : null;
|
|
72120
|
+
}
|
|
72121
|
+
return null;
|
|
72122
|
+
}
|
|
72123
|
+
async function inspectClaudeLocalMcp(projectRoot) {
|
|
72124
|
+
const configPath = getClaudeLocalConfigPath();
|
|
72125
|
+
if (!existsSync21(configPath)) {
|
|
72126
|
+
return {
|
|
72127
|
+
scope: "local",
|
|
72128
|
+
path: configPath,
|
|
72129
|
+
exists: false,
|
|
72130
|
+
status: "missing",
|
|
72131
|
+
issues: ["mcp-config-missing"]
|
|
72132
|
+
};
|
|
72133
|
+
}
|
|
72134
|
+
let config2 = {};
|
|
72135
|
+
try {
|
|
72136
|
+
config2 = JSON.parse(await readFile7(configPath, "utf-8"));
|
|
72137
|
+
} catch {
|
|
72138
|
+
return {
|
|
72139
|
+
scope: "local",
|
|
72140
|
+
path: configPath,
|
|
72141
|
+
exists: true,
|
|
72142
|
+
status: "repairable",
|
|
72143
|
+
issues: ["mcp-config-unreadable"]
|
|
72144
|
+
};
|
|
72145
|
+
}
|
|
72146
|
+
const localProject = findClaudeLocalProject(config2, projectRoot);
|
|
72147
|
+
const pathLabel = localProject ? `${configPath}#projects[${localProject.key}]` : configPath;
|
|
72148
|
+
if (!localProject) {
|
|
72149
|
+
return {
|
|
72150
|
+
scope: "local",
|
|
72151
|
+
path: pathLabel,
|
|
72152
|
+
exists: true,
|
|
72153
|
+
status: "missing",
|
|
72154
|
+
issues: ["mcp-config-missing"]
|
|
72155
|
+
};
|
|
72156
|
+
}
|
|
72157
|
+
const servers = asRecord2(localProject.project.mcpServers);
|
|
72158
|
+
const server = coerceClaudeLocalServer("memorix", servers?.memorix);
|
|
72159
|
+
if (!server) {
|
|
72160
|
+
return {
|
|
72161
|
+
scope: "local",
|
|
72162
|
+
path: pathLabel,
|
|
72163
|
+
exists: true,
|
|
72164
|
+
status: "repairable",
|
|
72165
|
+
issues: ["memorix-server-missing"]
|
|
72166
|
+
};
|
|
72167
|
+
}
|
|
72168
|
+
const issues = [];
|
|
72169
|
+
if (!server.url && looksLikeStaleMemorixCommand(server)) issues.push("stale-command-path");
|
|
72170
|
+
if (!server.url && !isRecommendedStdioServer(server)) issues.push("nonstandard-mcp-command");
|
|
72171
|
+
if (server.alwaysLoad !== true) issues.push("claude-always-load-missing");
|
|
72172
|
+
return {
|
|
72173
|
+
scope: "local",
|
|
72174
|
+
path: pathLabel,
|
|
72175
|
+
exists: true,
|
|
72176
|
+
status: issues.length > 0 ? "repairable" : "ok",
|
|
72177
|
+
issues,
|
|
72178
|
+
server: sanitizeServer(server)
|
|
72179
|
+
};
|
|
72180
|
+
}
|
|
72181
|
+
async function installClaudeLocalMcpConfig(projectRoot) {
|
|
72182
|
+
const configPath = getClaudeLocalConfigPath();
|
|
72183
|
+
let config2 = {};
|
|
72184
|
+
try {
|
|
72185
|
+
config2 = JSON.parse(await readFile7(configPath, "utf-8"));
|
|
72186
|
+
} catch {
|
|
72187
|
+
config2 = {};
|
|
72188
|
+
}
|
|
72189
|
+
const projects = asRecord2(config2.projects) ?? {};
|
|
72190
|
+
const existing = findClaudeLocalProject({ ...config2, projects }, projectRoot);
|
|
72191
|
+
const projectKey = existing?.key ?? defaultClaudeProjectKey(projectRoot);
|
|
72192
|
+
const project = existing?.project ?? asRecord2(projects[projectKey]) ?? {};
|
|
72193
|
+
const mcpServers = asRecord2(project.mcpServers) ?? {};
|
|
72194
|
+
const server = buildMemorixServer("stdio");
|
|
72195
|
+
server.alwaysLoad = true;
|
|
72196
|
+
mcpServers.memorix = {
|
|
72197
|
+
type: "stdio",
|
|
72198
|
+
command: server.command,
|
|
72199
|
+
args: server.args,
|
|
72200
|
+
alwaysLoad: true
|
|
72201
|
+
};
|
|
72202
|
+
project.mcpServers = mcpServers;
|
|
72203
|
+
projects[projectKey] = project;
|
|
72204
|
+
config2.projects = projects;
|
|
72205
|
+
await mkdir7(dirname7(configPath), { recursive: true });
|
|
72206
|
+
await writeFile7(configPath, `${JSON.stringify(config2, null, 2)}
|
|
72207
|
+
`, "utf-8");
|
|
72208
|
+
}
|
|
72209
|
+
async function inspectMcp(agent, projectRoot, scope) {
|
|
72210
|
+
if (!isMcpConfigAgent(agent)) {
|
|
72211
|
+
return { status: "skipped", issues: ["mcp-managed-by-package"], checks: [] };
|
|
72212
|
+
}
|
|
72213
|
+
const adapter = getMcpAdapter(agent);
|
|
72214
|
+
const checks = [];
|
|
72215
|
+
for (const targetScope of requestedMcpScopes(agent, scope)) {
|
|
72216
|
+
if (agent === "claude" && targetScope === "local") {
|
|
72217
|
+
checks.push(await inspectClaudeLocalMcp(projectRoot));
|
|
72218
|
+
continue;
|
|
72219
|
+
}
|
|
72220
|
+
const configPath = adapter.getConfigPath(targetScope === "project" ? projectRoot : void 0);
|
|
72221
|
+
if (targetScope === "global" && configPath === adapter.getConfigPath(projectRoot)) continue;
|
|
72222
|
+
if (!existsSync21(configPath)) {
|
|
72223
|
+
checks.push({
|
|
72224
|
+
scope: targetScope,
|
|
72225
|
+
path: configPath,
|
|
72226
|
+
exists: false,
|
|
72227
|
+
status: "missing",
|
|
72228
|
+
issues: ["mcp-config-missing"]
|
|
72229
|
+
});
|
|
72230
|
+
continue;
|
|
72231
|
+
}
|
|
72232
|
+
const content = await readFile7(configPath, "utf-8");
|
|
72233
|
+
if (agent === "claude" && targetScope === "global") {
|
|
72234
|
+
try {
|
|
72235
|
+
const parsed = JSON.parse(content);
|
|
72236
|
+
if (asRecord2(parsed.projects) && !asRecord2(parsed.mcpServers)) {
|
|
72237
|
+
checks.push({
|
|
72238
|
+
scope: targetScope,
|
|
72239
|
+
path: configPath,
|
|
72240
|
+
exists: true,
|
|
72241
|
+
status: "missing",
|
|
72242
|
+
issues: ["mcp-config-missing"]
|
|
72243
|
+
});
|
|
72244
|
+
continue;
|
|
72245
|
+
}
|
|
72246
|
+
} catch {
|
|
72247
|
+
checks.push({
|
|
72248
|
+
scope: targetScope,
|
|
72249
|
+
path: configPath,
|
|
72250
|
+
exists: true,
|
|
72251
|
+
status: "repairable",
|
|
72252
|
+
issues: ["mcp-config-unreadable"]
|
|
72253
|
+
});
|
|
72254
|
+
continue;
|
|
72255
|
+
}
|
|
72256
|
+
}
|
|
72257
|
+
const servers = adapter.parse(content);
|
|
72258
|
+
const server = servers.find((entry) => entry.name === "memorix");
|
|
72259
|
+
if (!server) {
|
|
72260
|
+
checks.push({
|
|
72261
|
+
scope: targetScope,
|
|
72262
|
+
path: configPath,
|
|
72263
|
+
exists: true,
|
|
72264
|
+
status: "repairable",
|
|
72265
|
+
issues: ["memorix-server-missing"]
|
|
72266
|
+
});
|
|
72267
|
+
continue;
|
|
72268
|
+
}
|
|
72269
|
+
const issues = [];
|
|
72270
|
+
if (!server.url && looksLikeStaleMemorixCommand(server)) issues.push("stale-command-path");
|
|
72271
|
+
if (!server.url && !isRecommendedStdioServer(server)) issues.push("nonstandard-mcp-command");
|
|
72272
|
+
if (agent === "claude" && server.alwaysLoad !== true) issues.push("claude-always-load-missing");
|
|
72273
|
+
checks.push({
|
|
72274
|
+
scope: targetScope,
|
|
72275
|
+
path: configPath,
|
|
72276
|
+
exists: true,
|
|
72277
|
+
status: issues.length > 0 ? "repairable" : "ok",
|
|
72278
|
+
issues,
|
|
72279
|
+
server: sanitizeServer(server)
|
|
72280
|
+
});
|
|
72281
|
+
}
|
|
72282
|
+
return {
|
|
72283
|
+
status: aggregateMcpStatus(checks),
|
|
72284
|
+
issues: aggregateMcpIssues(checks),
|
|
72285
|
+
checks
|
|
72286
|
+
};
|
|
72287
|
+
}
|
|
72288
|
+
function isCurrentGuidance(content) {
|
|
72289
|
+
return content.includes("Memory Autopilot") && content.includes("Default first step for non-trivial coding work") && content.includes("memorix_project_context");
|
|
72290
|
+
}
|
|
72291
|
+
async function inspectGuidance(agent, projectRoot, scope) {
|
|
72292
|
+
if (!GUIDANCE_AGENTS.has(agent)) {
|
|
72293
|
+
return { status: "skipped", issues: ["guidance-managed-by-package"], checks: [] };
|
|
72294
|
+
}
|
|
72295
|
+
const checks = [];
|
|
72296
|
+
for (const targetScope of requestedGuidanceScopes(scope)) {
|
|
72297
|
+
const root = targetScope === "project" ? projectRoot : homedir32();
|
|
72298
|
+
const rulesPath = getAgentRulesPath(agent, root, targetScope === "global");
|
|
72299
|
+
if (!existsSync21(rulesPath)) {
|
|
72300
|
+
checks.push({
|
|
72301
|
+
scope: targetScope,
|
|
72302
|
+
path: rulesPath,
|
|
72303
|
+
exists: false,
|
|
72304
|
+
status: "missing",
|
|
72305
|
+
issues: ["guidance-missing"]
|
|
72306
|
+
});
|
|
72307
|
+
continue;
|
|
72308
|
+
}
|
|
72309
|
+
const content = await readFile7(rulesPath, "utf-8");
|
|
72310
|
+
const issues = isCurrentGuidance(content) ? [] : ["guidance-outdated"];
|
|
72311
|
+
checks.push({
|
|
72312
|
+
scope: targetScope,
|
|
72313
|
+
path: rulesPath,
|
|
72314
|
+
exists: true,
|
|
72315
|
+
status: issues.length > 0 ? "repairable" : "ok",
|
|
72316
|
+
issues
|
|
72317
|
+
});
|
|
72318
|
+
}
|
|
72319
|
+
return {
|
|
72320
|
+
status: aggregateGuidanceStatus(checks),
|
|
72321
|
+
issues: aggregateGuidanceIssues(checks),
|
|
72322
|
+
checks
|
|
72323
|
+
};
|
|
72324
|
+
}
|
|
72325
|
+
async function inspectAgentIntegrations(options2 = {}) {
|
|
72326
|
+
const projectRoot = options2.projectRoot ?? process.cwd();
|
|
72327
|
+
const scope = options2.scope === "local" || options2.scope === "project" || options2.scope === "global" || options2.scope === "all" ? options2.scope : "all";
|
|
72328
|
+
const agents = requestedAgents(options2.agent);
|
|
72329
|
+
const entries = [];
|
|
72330
|
+
for (const agent of agents) {
|
|
72331
|
+
entries.push({
|
|
72332
|
+
agent,
|
|
72333
|
+
mcp: await inspectMcp(agent, projectRoot, scope),
|
|
72334
|
+
guidance: await inspectGuidance(agent, projectRoot, scope)
|
|
72335
|
+
});
|
|
72336
|
+
}
|
|
72337
|
+
const entryStatuses = entries.map((entry) => worstStatus([entry.mcp.status, entry.guidance.status]));
|
|
72338
|
+
return {
|
|
72339
|
+
projectRoot,
|
|
72340
|
+
scope,
|
|
72341
|
+
entries,
|
|
72342
|
+
summary: {
|
|
72343
|
+
checked: entries.length,
|
|
72344
|
+
ok: entryStatuses.filter((status) => status === "ok").length,
|
|
72345
|
+
missing: entryStatuses.filter((status) => status === "missing").length,
|
|
72346
|
+
repairable: entryStatuses.filter((status) => status === "repairable").length
|
|
72347
|
+
},
|
|
72348
|
+
repairCommand: `memorix repair agents${options2.agent ? ` --agent ${options2.agent}` : ""}${scope === "all" ? "" : ` --scope ${scope}`}`
|
|
72349
|
+
};
|
|
72350
|
+
}
|
|
72351
|
+
function formatAgentIntegrationReport(report) {
|
|
72352
|
+
const lines = [
|
|
72353
|
+
"Memorix Agent Doctor",
|
|
72354
|
+
`Project: ${report.projectRoot}`,
|
|
72355
|
+
`Scope: ${report.scope}`,
|
|
72356
|
+
""
|
|
72357
|
+
];
|
|
72358
|
+
for (const entry of report.entries) {
|
|
72359
|
+
const status = worstStatus([entry.mcp.status, entry.guidance.status]);
|
|
72360
|
+
lines.push(`${entry.agent}: ${status}`);
|
|
72361
|
+
if (entry.mcp.issues.length > 0) lines.push(` MCP: ${entry.mcp.issues.join(", ")}`);
|
|
72362
|
+
if (entry.guidance.issues.length > 0) lines.push(` Guidance: ${entry.guidance.issues.join(", ")}`);
|
|
72363
|
+
}
|
|
72364
|
+
lines.push("");
|
|
72365
|
+
lines.push(`Repair: ${report.repairCommand}`);
|
|
72366
|
+
return lines.join("\n");
|
|
72367
|
+
}
|
|
72368
|
+
async function repairAgentIntegrations(options2 = {}) {
|
|
72369
|
+
const projectRoot = options2.projectRoot ?? process.cwd();
|
|
72370
|
+
const scope = options2.scope === "local" || options2.scope === "project" || options2.scope === "global" || options2.scope === "all" ? options2.scope : "all";
|
|
72371
|
+
const before = await inspectAgentIntegrations({ projectRoot, agent: options2.agent, scope });
|
|
72372
|
+
const changed = [];
|
|
72373
|
+
const skipped = [];
|
|
72374
|
+
const canInstallMissing = Boolean(options2.agent && scope !== "all");
|
|
72375
|
+
for (const entry of before.entries) {
|
|
72376
|
+
if (isMcpConfigAgent(entry.agent)) {
|
|
72377
|
+
for (const check2 of entry.mcp.checks) {
|
|
72378
|
+
if (check2.status === "ok" || check2.status === "skipped") continue;
|
|
72379
|
+
if (check2.status === "missing" && !canInstallMissing) {
|
|
72380
|
+
skipped.push(`${entry.agent}:mcp:${check2.scope}:missing`);
|
|
72381
|
+
continue;
|
|
72382
|
+
}
|
|
72383
|
+
if (!options2.dry) {
|
|
72384
|
+
if (entry.agent === "claude" && check2.scope === "local") {
|
|
72385
|
+
await installClaudeLocalMcpConfig(projectRoot);
|
|
72386
|
+
} else {
|
|
72387
|
+
await installMcpConfig({
|
|
72388
|
+
agent: entry.agent,
|
|
72389
|
+
projectRoot,
|
|
72390
|
+
global: check2.scope === "global",
|
|
72391
|
+
mcp: "stdio"
|
|
72392
|
+
});
|
|
72393
|
+
}
|
|
72394
|
+
}
|
|
72395
|
+
changed.push(`${entry.agent}:mcp:${check2.scope}`);
|
|
72396
|
+
}
|
|
72397
|
+
} else {
|
|
72398
|
+
skipped.push(`${entry.agent}:mcp`);
|
|
72399
|
+
}
|
|
72400
|
+
if (GUIDANCE_AGENTS.has(entry.agent)) {
|
|
72401
|
+
for (const check2 of entry.guidance.checks) {
|
|
72402
|
+
if (check2.status === "ok" || check2.status === "skipped") continue;
|
|
72403
|
+
if (check2.status === "missing" && !canInstallMissing) {
|
|
72404
|
+
skipped.push(`${entry.agent}:guidance:${check2.scope}:missing`);
|
|
72405
|
+
continue;
|
|
72406
|
+
}
|
|
72407
|
+
if (!options2.dry) {
|
|
72408
|
+
await installAgentGuidance(entry.agent, projectRoot, check2.scope === "global");
|
|
72409
|
+
}
|
|
72410
|
+
changed.push(`${entry.agent}:guidance:${check2.scope}`);
|
|
72411
|
+
}
|
|
72412
|
+
} else {
|
|
72413
|
+
skipped.push(`${entry.agent}:guidance`);
|
|
72414
|
+
}
|
|
72415
|
+
}
|
|
72416
|
+
return {
|
|
72417
|
+
projectRoot,
|
|
72418
|
+
scope,
|
|
72419
|
+
changed,
|
|
72420
|
+
skipped,
|
|
72421
|
+
before,
|
|
72422
|
+
after: options2.dry ? void 0 : await inspectAgentIntegrations({ projectRoot, agent: options2.agent, scope })
|
|
72423
|
+
};
|
|
72424
|
+
}
|
|
72425
|
+
function formatAgentRepairResult(result) {
|
|
72426
|
+
const lines = [
|
|
72427
|
+
"Memorix Agent Repair",
|
|
72428
|
+
`Project: ${result.projectRoot}`,
|
|
72429
|
+
`Scope: ${result.scope}`,
|
|
72430
|
+
""
|
|
72431
|
+
];
|
|
72432
|
+
if (result.changed.length === 0) {
|
|
72433
|
+
lines.push("No repairable agent integration issues found.");
|
|
72434
|
+
} else {
|
|
72435
|
+
lines.push("Changed:");
|
|
72436
|
+
for (const item of result.changed) lines.push(`- ${item}`);
|
|
72437
|
+
}
|
|
72438
|
+
if (result.skipped.length > 0) {
|
|
72439
|
+
lines.push("");
|
|
72440
|
+
lines.push("Skipped:");
|
|
72441
|
+
for (const item of result.skipped) lines.push(`- ${item}`);
|
|
72442
|
+
}
|
|
72443
|
+
return lines.join("\n");
|
|
72444
|
+
}
|
|
72445
|
+
var GUIDANCE_AGENTS;
|
|
72446
|
+
var init_agent_integrations = __esm({
|
|
72447
|
+
"src/cli/commands/agent-integrations.ts"() {
|
|
72448
|
+
"use strict";
|
|
72449
|
+
init_esm_shims();
|
|
72450
|
+
init_installers();
|
|
72451
|
+
init_setup();
|
|
72452
|
+
GUIDANCE_AGENTS = /* @__PURE__ */ new Set([
|
|
72453
|
+
"claude",
|
|
72454
|
+
"codex",
|
|
72455
|
+
"cursor",
|
|
72456
|
+
"windsurf",
|
|
72457
|
+
"copilot",
|
|
72458
|
+
"gemini-cli",
|
|
72459
|
+
"antigravity",
|
|
72460
|
+
"kiro",
|
|
72461
|
+
"opencode",
|
|
72462
|
+
"trae"
|
|
72463
|
+
]);
|
|
72464
|
+
}
|
|
72465
|
+
});
|
|
72466
|
+
|
|
71977
72467
|
// src/cli/commands/doctor.ts
|
|
71978
72468
|
var doctor_exports = {};
|
|
71979
72469
|
__export(doctor_exports, {
|
|
@@ -71991,6 +72481,14 @@ var init_doctor = __esm({
|
|
|
71991
72481
|
description: "Diagnose Memorix health \u2014 project identity, embedding, data, conflicts"
|
|
71992
72482
|
},
|
|
71993
72483
|
args: {
|
|
72484
|
+
agent: {
|
|
72485
|
+
type: "string",
|
|
72486
|
+
description: 'Agent to inspect for "doctor agents" (default: all)'
|
|
72487
|
+
},
|
|
72488
|
+
scope: {
|
|
72489
|
+
type: "string",
|
|
72490
|
+
description: 'Scope for "doctor agents": local, project, global, or all'
|
|
72491
|
+
},
|
|
71994
72492
|
json: {
|
|
71995
72493
|
type: "boolean",
|
|
71996
72494
|
description: "Output as JSON instead of human-readable text",
|
|
@@ -72003,9 +72501,23 @@ var init_doctor = __esm({
|
|
|
72003
72501
|
}
|
|
72004
72502
|
},
|
|
72005
72503
|
run: async ({ args }) => {
|
|
72006
|
-
const
|
|
72007
|
-
|
|
72008
|
-
|
|
72504
|
+
const positional = args._ ?? [];
|
|
72505
|
+
if (positional[0] === "agents") {
|
|
72506
|
+
const { inspectAgentIntegrations: inspectAgentIntegrations2, formatAgentIntegrationReport: formatAgentIntegrationReport2 } = await Promise.resolve().then(() => (init_agent_integrations(), agent_integrations_exports));
|
|
72507
|
+
const report2 = await inspectAgentIntegrations2({
|
|
72508
|
+
agent: args.agent,
|
|
72509
|
+
scope: args.scope
|
|
72510
|
+
});
|
|
72511
|
+
if (args.json) {
|
|
72512
|
+
console.log(JSON.stringify({ agents: report2 }, null, 2));
|
|
72513
|
+
} else {
|
|
72514
|
+
console.log(formatAgentIntegrationReport2(report2));
|
|
72515
|
+
}
|
|
72516
|
+
return;
|
|
72517
|
+
}
|
|
72518
|
+
const { existsSync: existsSync26, readFileSync: readFileSync22 } = await import("fs");
|
|
72519
|
+
const { join: join32, basename: basename5 } = await import("path");
|
|
72520
|
+
const { homedir: homedir34 } = await import("os");
|
|
72009
72521
|
const { execSync: execSync11 } = await import("child_process");
|
|
72010
72522
|
const report = {};
|
|
72011
72523
|
const issues = [];
|
|
@@ -72067,13 +72579,13 @@ var init_doctor = __esm({
|
|
|
72067
72579
|
}
|
|
72068
72580
|
lines.push("");
|
|
72069
72581
|
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(
|
|
72582
|
+
const memorixDir = join32(homedir34(), ".memorix");
|
|
72071
72583
|
const bgStatePath = join32(memorixDir, "background.json");
|
|
72072
72584
|
let bgRunning = false;
|
|
72073
72585
|
let bgPort = 0;
|
|
72074
72586
|
let bgPid = 0;
|
|
72075
72587
|
try {
|
|
72076
|
-
if (
|
|
72588
|
+
if (existsSync26(bgStatePath)) {
|
|
72077
72589
|
const bgState = JSON.parse(readFileSync22(bgStatePath, "utf-8"));
|
|
72078
72590
|
bgPid = bgState.pid;
|
|
72079
72591
|
bgPort = bgState.port;
|
|
@@ -72089,15 +72601,15 @@ var init_doctor = __esm({
|
|
|
72089
72601
|
lines.push(ok(`Background control plane running (PID ${bgPid}, port ${bgPort})`));
|
|
72090
72602
|
try {
|
|
72091
72603
|
const http = await import("http");
|
|
72092
|
-
const healthy = await new Promise((
|
|
72604
|
+
const healthy = await new Promise((resolve4) => {
|
|
72093
72605
|
const req = http.request({ hostname: "127.0.0.1", port: bgPort, path: "/api/team", timeout: 3e3 }, (res) => {
|
|
72094
72606
|
res.resume();
|
|
72095
|
-
|
|
72607
|
+
resolve4(res.statusCode === 200);
|
|
72096
72608
|
});
|
|
72097
|
-
req.on("error", () =>
|
|
72609
|
+
req.on("error", () => resolve4(false));
|
|
72098
72610
|
req.on("timeout", () => {
|
|
72099
72611
|
req.destroy();
|
|
72100
|
-
|
|
72612
|
+
resolve4(false);
|
|
72101
72613
|
});
|
|
72102
72614
|
req.end();
|
|
72103
72615
|
});
|
|
@@ -72120,15 +72632,15 @@ var init_doctor = __esm({
|
|
|
72120
72632
|
if (!bgRunning) {
|
|
72121
72633
|
try {
|
|
72122
72634
|
const http = await import("http");
|
|
72123
|
-
const portUsed = await new Promise((
|
|
72635
|
+
const portUsed = await new Promise((resolve4) => {
|
|
72124
72636
|
const req = http.request({ hostname: "127.0.0.1", port: 3211, path: "/api/team", timeout: 2e3 }, (res) => {
|
|
72125
72637
|
res.resume();
|
|
72126
|
-
|
|
72638
|
+
resolve4(res.statusCode === 200);
|
|
72127
72639
|
});
|
|
72128
|
-
req.on("error", () =>
|
|
72640
|
+
req.on("error", () => resolve4(false));
|
|
72129
72641
|
req.on("timeout", () => {
|
|
72130
72642
|
req.destroy();
|
|
72131
|
-
|
|
72643
|
+
resolve4(false);
|
|
72132
72644
|
});
|
|
72133
72645
|
req.end();
|
|
72134
72646
|
});
|
|
@@ -72166,7 +72678,7 @@ var init_doctor = __esm({
|
|
|
72166
72678
|
}
|
|
72167
72679
|
try {
|
|
72168
72680
|
const cachePath = join32(memorixDir, "embedding-cache.json");
|
|
72169
|
-
if (
|
|
72681
|
+
if (existsSync26(cachePath)) {
|
|
72170
72682
|
const cache4 = JSON.parse(readFileSync22(cachePath, "utf-8"));
|
|
72171
72683
|
const cacheCount = Object.keys(cache4).length;
|
|
72172
72684
|
lines.push(info(`Cached embeddings: ${cacheCount}`));
|
|
@@ -72181,7 +72693,7 @@ var init_doctor = __esm({
|
|
|
72181
72693
|
}
|
|
72182
72694
|
lines.push("");
|
|
72183
72695
|
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 &&
|
|
72696
|
+
if (dataDir && existsSync26(dataDir)) {
|
|
72185
72697
|
let obsCount = 0;
|
|
72186
72698
|
let activeCount = 0;
|
|
72187
72699
|
let ranCount = 0;
|
|
@@ -72252,7 +72764,7 @@ var init_doctor = __esm({
|
|
|
72252
72764
|
const overview = buildProjectContextOverview2({
|
|
72253
72765
|
project: {
|
|
72254
72766
|
id: projectId,
|
|
72255
|
-
name: projectName ||
|
|
72767
|
+
name: projectName || basename5(projectRoot || process.cwd()),
|
|
72256
72768
|
rootPath: projectRoot || process.cwd()
|
|
72257
72769
|
},
|
|
72258
72770
|
store: codeStore,
|
|
@@ -72297,7 +72809,7 @@ var init_doctor = __esm({
|
|
|
72297
72809
|
let conflictsFound = false;
|
|
72298
72810
|
if (dataDir) {
|
|
72299
72811
|
const lockFile = join32(dataDir, ".memorix.lock");
|
|
72300
|
-
if (
|
|
72812
|
+
if (existsSync26(lockFile)) {
|
|
72301
72813
|
try {
|
|
72302
72814
|
const lockData = JSON.parse(readFileSync22(lockFile, "utf-8"));
|
|
72303
72815
|
const lockAge = Date.now() - lockData.time;
|
|
@@ -72412,6 +72924,71 @@ var init_doctor = __esm({
|
|
|
72412
72924
|
}
|
|
72413
72925
|
});
|
|
72414
72926
|
|
|
72927
|
+
// src/cli/commands/repair.ts
|
|
72928
|
+
var repair_exports = {};
|
|
72929
|
+
__export(repair_exports, {
|
|
72930
|
+
default: () => repair_default
|
|
72931
|
+
});
|
|
72932
|
+
var repair_default;
|
|
72933
|
+
var init_repair = __esm({
|
|
72934
|
+
"src/cli/commands/repair.ts"() {
|
|
72935
|
+
"use strict";
|
|
72936
|
+
init_esm_shims();
|
|
72937
|
+
init_dist2();
|
|
72938
|
+
repair_default = defineCommand({
|
|
72939
|
+
meta: {
|
|
72940
|
+
name: "repair",
|
|
72941
|
+
description: "Repair Memorix-owned agent integration files"
|
|
72942
|
+
},
|
|
72943
|
+
args: {
|
|
72944
|
+
agent: {
|
|
72945
|
+
type: "string",
|
|
72946
|
+
description: "Agent to repair (default: all detected repairable entries)"
|
|
72947
|
+
},
|
|
72948
|
+
scope: {
|
|
72949
|
+
type: "string",
|
|
72950
|
+
description: "Scope: local, project, global, or all"
|
|
72951
|
+
},
|
|
72952
|
+
dry: {
|
|
72953
|
+
type: "boolean",
|
|
72954
|
+
description: "Show what would be repaired without writing files",
|
|
72955
|
+
default: false
|
|
72956
|
+
},
|
|
72957
|
+
json: {
|
|
72958
|
+
type: "boolean",
|
|
72959
|
+
description: "Emit machine-readable JSON output",
|
|
72960
|
+
default: false
|
|
72961
|
+
}
|
|
72962
|
+
},
|
|
72963
|
+
run: async ({ args }) => {
|
|
72964
|
+
const positional = args._ ?? [];
|
|
72965
|
+
const action = positional[0] || "agents";
|
|
72966
|
+
if (action !== "agents") {
|
|
72967
|
+
const message = "Usage: memorix repair agents [--agent <agent>] [--scope local|project|global|all] [--dry]";
|
|
72968
|
+
if (args.json) {
|
|
72969
|
+
console.log(JSON.stringify({ error: message }, null, 2));
|
|
72970
|
+
} else {
|
|
72971
|
+
console.log(message);
|
|
72972
|
+
}
|
|
72973
|
+
process.exitCode = 1;
|
|
72974
|
+
return;
|
|
72975
|
+
}
|
|
72976
|
+
const { repairAgentIntegrations: repairAgentIntegrations2, formatAgentRepairResult: formatAgentRepairResult2 } = await Promise.resolve().then(() => (init_agent_integrations(), agent_integrations_exports));
|
|
72977
|
+
const repair = await repairAgentIntegrations2({
|
|
72978
|
+
agent: args.agent,
|
|
72979
|
+
scope: args.scope,
|
|
72980
|
+
dry: !!args.dry
|
|
72981
|
+
});
|
|
72982
|
+
if (args.json) {
|
|
72983
|
+
console.log(JSON.stringify({ repair }, null, 2));
|
|
72984
|
+
} else {
|
|
72985
|
+
console.log(formatAgentRepairResult2(repair));
|
|
72986
|
+
}
|
|
72987
|
+
}
|
|
72988
|
+
});
|
|
72989
|
+
}
|
|
72990
|
+
});
|
|
72991
|
+
|
|
72415
72992
|
// src/cli/commands/dashboard.ts
|
|
72416
72993
|
var dashboard_exports = {};
|
|
72417
72994
|
__export(dashboard_exports, {
|
|
@@ -72582,14 +73159,14 @@ Project: ${projectName} (${projectId})
|
|
|
72582
73159
|
const highQuality = projectObs.filter((o3) => !isLowQuality(o3.title ?? ""));
|
|
72583
73160
|
const seen = /* @__PURE__ */ new Set();
|
|
72584
73161
|
const duplicates = [];
|
|
72585
|
-
const
|
|
73162
|
+
const unique2 = [];
|
|
72586
73163
|
for (const obs of highQuality) {
|
|
72587
73164
|
const key = `${obs.type}|${obs.title}|${obs.entityName}`;
|
|
72588
73165
|
if (seen.has(key)) {
|
|
72589
73166
|
duplicates.push(obs);
|
|
72590
73167
|
} else {
|
|
72591
73168
|
seen.add(key);
|
|
72592
|
-
|
|
73169
|
+
unique2.push(obs);
|
|
72593
73170
|
}
|
|
72594
73171
|
}
|
|
72595
73172
|
const noiseHits = [];
|
|
@@ -72604,7 +73181,7 @@ Project: ${projectName} (${projectId})
|
|
|
72604
73181
|
const toArchive = noiseHits.map((h3) => h3.obs);
|
|
72605
73182
|
console.log(`Analysis (active observations for ${projectId}):`);
|
|
72606
73183
|
console.log(` Total active: ${projectObs.length}`);
|
|
72607
|
-
console.log(` High quality: ${
|
|
73184
|
+
console.log(` High quality: ${unique2.length - toArchive.length}`);
|
|
72608
73185
|
console.log(` Low quality: ${lowQuality.length}`);
|
|
72609
73186
|
console.log(` Duplicates: ${duplicates.length}`);
|
|
72610
73187
|
if (args.noise) {
|
|
@@ -72651,8 +73228,8 @@ Project: ${projectName} (${projectId})
|
|
|
72651
73228
|
toRemove.length > 0 ? `delete ${toRemove.length}` : "",
|
|
72652
73229
|
toArchive.length > 0 ? `archive ${toArchive.length}` : ""
|
|
72653
73230
|
].filter(Boolean).join(" and ");
|
|
72654
|
-
const answer = await new Promise((
|
|
72655
|
-
rl.question(`Proceed to ${desc} observations? (y/N) `,
|
|
73231
|
+
const answer = await new Promise((resolve4) => {
|
|
73232
|
+
rl.question(`Proceed to ${desc} observations? (y/N) `, resolve4);
|
|
72656
73233
|
});
|
|
72657
73234
|
rl.close();
|
|
72658
73235
|
if (answer.trim().toLowerCase() !== "y") {
|
|
@@ -72945,8 +73522,8 @@ async function confirm(description) {
|
|
|
72945
73522
|
}
|
|
72946
73523
|
const readline = await import("readline");
|
|
72947
73524
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
72948
|
-
const answer = await new Promise((
|
|
72949
|
-
rl.question(`Proceed to ${description}? (y/N) `,
|
|
73525
|
+
const answer = await new Promise((resolve4) => {
|
|
73526
|
+
rl.question(`Proceed to ${description}? (y/N) `, resolve4);
|
|
72950
73527
|
});
|
|
72951
73528
|
rl.close();
|
|
72952
73529
|
return answer.trim().toLowerCase() === "y";
|
|
@@ -73258,8 +73835,8 @@ function spawnAgentWithStream(command, args, opts, stdinData, onStdoutLine, onCo
|
|
|
73258
73835
|
if (done) {
|
|
73259
73836
|
return Promise.resolve({ value: void 0, done: true });
|
|
73260
73837
|
}
|
|
73261
|
-
return new Promise((
|
|
73262
|
-
waiters.push({ resolve:
|
|
73838
|
+
return new Promise((resolve4) => {
|
|
73839
|
+
waiters.push({ resolve: resolve4 });
|
|
73263
73840
|
});
|
|
73264
73841
|
}
|
|
73265
73842
|
};
|
|
@@ -73299,7 +73876,7 @@ function spawnAgentWithStream(command, args, opts, stdinData, onStdoutLine, onCo
|
|
|
73299
73876
|
}, SIGKILL_GRACE_MS);
|
|
73300
73877
|
}, timeoutMs);
|
|
73301
73878
|
}
|
|
73302
|
-
const completion = new Promise((
|
|
73879
|
+
const completion = new Promise((resolve4) => {
|
|
73303
73880
|
let exitCode = null;
|
|
73304
73881
|
let exitSignal = null;
|
|
73305
73882
|
let exited = false;
|
|
@@ -73319,7 +73896,7 @@ function spawnAgentWithStream(command, args, opts, stdinData, onStdoutLine, onCo
|
|
|
73319
73896
|
const tail = stdinError ? `${stdinError}
|
|
73320
73897
|
${ring.toString()}` : ring.toString();
|
|
73321
73898
|
const baseResult = { exitCode, signal: exitSignal, tailOutput: tail, killed };
|
|
73322
|
-
|
|
73899
|
+
resolve4(onCompletion ? onCompletion(baseResult) : baseResult);
|
|
73323
73900
|
}
|
|
73324
73901
|
child.on("exit", (code, signal) => {
|
|
73325
73902
|
exited = true;
|
|
@@ -73346,7 +73923,7 @@ ${ring.toString()}` : ring.toString();
|
|
|
73346
73923
|
closeStream();
|
|
73347
73924
|
const tail = stdinError ? `${stdinError}
|
|
73348
73925
|
` : "";
|
|
73349
|
-
|
|
73926
|
+
resolve4({
|
|
73350
73927
|
exitCode: null,
|
|
73351
73928
|
signal: null,
|
|
73352
73929
|
tailOutput: `${tail}spawn error: ${err.message}
|
|
@@ -74349,8 +74926,8 @@ var init_pipeline_trace = __esm({
|
|
|
74349
74926
|
|
|
74350
74927
|
// src/orchestrate/worktree.ts
|
|
74351
74928
|
import { execSync as execSync7 } from "child_process";
|
|
74352
|
-
import { existsSync as
|
|
74353
|
-
import { join as join30, basename as
|
|
74929
|
+
import { existsSync as existsSync23, rmSync as rmSync2 } from "fs";
|
|
74930
|
+
import { join as join30, basename as basename4 } from "path";
|
|
74354
74931
|
function createWorktree(projectDir2, taskId, pipelineId) {
|
|
74355
74932
|
const shortId2 = taskId.slice(0, 8);
|
|
74356
74933
|
const shortPipeline = pipelineId.slice(0, 8);
|
|
@@ -74410,7 +74987,7 @@ function removeWorktree(projectDir2, worktreePath, branch) {
|
|
|
74410
74987
|
timeout: 1e4
|
|
74411
74988
|
});
|
|
74412
74989
|
} catch {
|
|
74413
|
-
if (
|
|
74990
|
+
if (existsSync23(worktreePath)) {
|
|
74414
74991
|
try {
|
|
74415
74992
|
rmSync2(worktreePath, { recursive: true, force: true });
|
|
74416
74993
|
} catch {
|
|
@@ -74458,7 +75035,7 @@ function listWorktrees(projectDir2) {
|
|
|
74458
75035
|
}
|
|
74459
75036
|
}
|
|
74460
75037
|
function extractTaskIdFromPath(worktreePath) {
|
|
74461
|
-
const name =
|
|
75038
|
+
const name = basename4(worktreePath);
|
|
74462
75039
|
const match = name.match(/^task-([a-f0-9]+)$/);
|
|
74463
75040
|
return match ? match[1] : null;
|
|
74464
75041
|
}
|
|
@@ -74488,7 +75065,7 @@ var init_worktree = __esm({
|
|
|
74488
75065
|
import { spawn as spawn2, execSync as execSync8 } from "child_process";
|
|
74489
75066
|
function runGate(gate, command, cwd, timeoutMs, outputBudget = DEFAULT_OUTPUT_BUDGET) {
|
|
74490
75067
|
const start = Date.now();
|
|
74491
|
-
return new Promise((
|
|
75068
|
+
return new Promise((resolve4) => {
|
|
74492
75069
|
const chunks = [];
|
|
74493
75070
|
let totalBytes = 0;
|
|
74494
75071
|
const proc = spawn2(command, {
|
|
@@ -74531,7 +75108,7 @@ function runGate(gate, command, cwd, timeoutMs, outputBudget = DEFAULT_OUTPUT_BU
|
|
|
74531
75108
|
const output = Buffer.concat(chunks).toString("utf-8");
|
|
74532
75109
|
const durationMs = Date.now() - start;
|
|
74533
75110
|
if (killed) {
|
|
74534
|
-
|
|
75111
|
+
resolve4({
|
|
74535
75112
|
gate,
|
|
74536
75113
|
passed: false,
|
|
74537
75114
|
output: output + `
|
|
@@ -74541,7 +75118,7 @@ function runGate(gate, command, cwd, timeoutMs, outputBudget = DEFAULT_OUTPUT_BU
|
|
|
74541
75118
|
});
|
|
74542
75119
|
return;
|
|
74543
75120
|
}
|
|
74544
|
-
|
|
75121
|
+
resolve4({
|
|
74545
75122
|
gate,
|
|
74546
75123
|
passed: code === 0,
|
|
74547
75124
|
output,
|
|
@@ -74551,7 +75128,7 @@ function runGate(gate, command, cwd, timeoutMs, outputBudget = DEFAULT_OUTPUT_BU
|
|
|
74551
75128
|
});
|
|
74552
75129
|
proc.on("error", (err) => {
|
|
74553
75130
|
clearTimeout(timer);
|
|
74554
|
-
|
|
75131
|
+
resolve4({
|
|
74555
75132
|
gate,
|
|
74556
75133
|
passed: false,
|
|
74557
75134
|
output: `[ERROR] Failed to spawn gate command: ${err.message}`,
|
|
@@ -75181,7 +75758,7 @@ function hashErrorPattern(errorOutput) {
|
|
|
75181
75758
|
return createHash8("sha256").update(sanitized).digest("hex").slice(0, 12);
|
|
75182
75759
|
}
|
|
75183
75760
|
function sleep2(ms) {
|
|
75184
|
-
return new Promise((
|
|
75761
|
+
return new Promise((resolve4) => setTimeout(() => resolve4([]), ms));
|
|
75185
75762
|
}
|
|
75186
75763
|
var DEFAULT_BRIDGE_CONFIG, _storeObservation, _searchObservations;
|
|
75187
75764
|
var init_memorix_bridge = __esm({
|
|
@@ -76142,7 +76719,7 @@ ${formatCostSummary(costSummary)}`);
|
|
|
76142
76719
|
}
|
|
76143
76720
|
}
|
|
76144
76721
|
function sleep3(ms) {
|
|
76145
|
-
return new Promise((
|
|
76722
|
+
return new Promise((resolve4) => setTimeout(resolve4, ms));
|
|
76146
76723
|
}
|
|
76147
76724
|
function isGitRepository(projectDir2) {
|
|
76148
76725
|
try {
|
|
@@ -80312,10 +80889,10 @@ function WorkbenchApp({ version: version2, onExitForInteractive }) {
|
|
|
80312
80889
|
}
|
|
80313
80890
|
try {
|
|
80314
80891
|
const { resolveHooksDir: resolveHooksDir2 } = await Promise.resolve().then(() => (init_hooks_path(), hooks_path_exports));
|
|
80315
|
-
const { existsSync:
|
|
80892
|
+
const { existsSync: existsSync26, readFileSync: readFileSync22, writeFileSync: writeFileSync11, unlinkSync: unlinkSync4 } = await import("fs");
|
|
80316
80893
|
const resolved = resolveHooksDir2(proj.rootPath);
|
|
80317
80894
|
const hookMarker = "# [memorix-git-hook]";
|
|
80318
|
-
if (!resolved || !
|
|
80895
|
+
if (!resolved || !existsSync26(resolved.hookPath)) {
|
|
80319
80896
|
setActionStatus("No post-commit hook found.");
|
|
80320
80897
|
return;
|
|
80321
80898
|
}
|
|
@@ -80470,7 +81047,7 @@ function WorkbenchApp({ version: version2, onExitForInteractive }) {
|
|
|
80470
81047
|
break;
|
|
80471
81048
|
}
|
|
80472
81049
|
case "3": {
|
|
80473
|
-
const { existsSync:
|
|
81050
|
+
const { existsSync: existsSync26, readFileSync: readFileSync22, writeFileSync: writeFileSync11, chmodSync: chmodSync2 } = await import("fs");
|
|
80474
81051
|
const { ensureHooksDir: ensureHooksDir2 } = await Promise.resolve().then(() => (init_hooks_path(), hooks_path_exports));
|
|
80475
81052
|
const hookMarker = "# [memorix-git-hook]";
|
|
80476
81053
|
const resolved = ensureHooksDir2(cwd);
|
|
@@ -80484,7 +81061,7 @@ if command -v memorix >/dev/null 2>&1; then
|
|
|
80484
81061
|
memorix ingest commit --auto >/dev/null 2>&1 &
|
|
80485
81062
|
fi
|
|
80486
81063
|
`;
|
|
80487
|
-
if (
|
|
81064
|
+
if (existsSync26(resolved.hookPath)) {
|
|
80488
81065
|
if (readFileSync22(resolved.hookPath, "utf-8").includes(hookMarker)) {
|
|
80489
81066
|
setActionStatus("Post-commit hook already installed.");
|
|
80490
81067
|
break;
|
|
@@ -80504,11 +81081,11 @@ ${hookScript}`, "utf-8");
|
|
|
80504
81081
|
break;
|
|
80505
81082
|
}
|
|
80506
81083
|
case "4": {
|
|
80507
|
-
const { existsSync:
|
|
81084
|
+
const { existsSync: existsSync26, readFileSync: readFileSync22, writeFileSync: writeFileSync11, unlinkSync: unlinkSync4 } = await import("fs");
|
|
80508
81085
|
const { resolveHooksDir: resolveHooksDir2 } = await Promise.resolve().then(() => (init_hooks_path(), hooks_path_exports));
|
|
80509
81086
|
const hookMarker = "# [memorix-git-hook]";
|
|
80510
81087
|
const resolved = resolveHooksDir2(cwd);
|
|
80511
|
-
if (!resolved || !
|
|
81088
|
+
if (!resolved || !existsSync26(resolved.hookPath)) {
|
|
80512
81089
|
setActionStatus("No post-commit hook found.");
|
|
80513
81090
|
break;
|
|
80514
81091
|
}
|
|
@@ -81268,14 +81845,14 @@ var main = defineCommand({
|
|
|
81268
81845
|
async run({ args }) {
|
|
81269
81846
|
let q3 = args.question || "";
|
|
81270
81847
|
if (!q3 && !process.stdin.isTTY) {
|
|
81271
|
-
q3 = await new Promise((
|
|
81848
|
+
q3 = await new Promise((resolve4) => {
|
|
81272
81849
|
let data = "";
|
|
81273
81850
|
process.stdin.setEncoding("utf-8");
|
|
81274
81851
|
process.stdin.on("data", (chunk) => {
|
|
81275
81852
|
data += chunk;
|
|
81276
81853
|
});
|
|
81277
|
-
process.stdin.on("end", () =>
|
|
81278
|
-
process.stdin.on("error", () =>
|
|
81854
|
+
process.stdin.on("end", () => resolve4(data.trim()));
|
|
81855
|
+
process.stdin.on("error", () => resolve4(""));
|
|
81279
81856
|
});
|
|
81280
81857
|
}
|
|
81281
81858
|
if (!q3) {
|
|
@@ -81356,6 +81933,7 @@ var main = defineCommand({
|
|
|
81356
81933
|
}
|
|
81357
81934
|
})),
|
|
81358
81935
|
doctor: () => Promise.resolve().then(() => (init_doctor(), doctor_exports)).then((m4) => m4.default),
|
|
81936
|
+
repair: () => Promise.resolve().then(() => (init_repair(), repair_exports)).then((m4) => m4.default),
|
|
81359
81937
|
dashboard: () => Promise.resolve().then(() => (init_dashboard(), dashboard_exports)).then((m4) => m4.default),
|
|
81360
81938
|
cleanup: () => Promise.resolve().then(() => (init_cleanup(), cleanup_exports)).then((m4) => m4.default),
|
|
81361
81939
|
uninstall: () => Promise.resolve().then(() => (init_uninstall(), uninstall_exports)).then((m4) => m4.default),
|
|
@@ -81416,6 +81994,7 @@ var main = defineCommand({
|
|
|
81416
81994
|
"bg",
|
|
81417
81995
|
"bs",
|
|
81418
81996
|
"doctor",
|
|
81997
|
+
"repair",
|
|
81419
81998
|
"dashboard",
|
|
81420
81999
|
"cleanup",
|
|
81421
82000
|
"uninstall",
|
|
@@ -81468,6 +82047,7 @@ var main = defineCommand({
|
|
|
81468
82047
|
console.error(" serve Start MCP server on stdio");
|
|
81469
82048
|
console.error(" init Create global defaults or project config");
|
|
81470
82049
|
console.error(" setup Install Memorix plugin/MCP/rules/hooks for an agent");
|
|
82050
|
+
console.error(" repair Repair Memorix-owned agent integration files");
|
|
81471
82051
|
console.error(" config Show TOML config paths and resolved values");
|
|
81472
82052
|
console.error(" integrate Install one IDE integration into the current repo");
|
|
81473
82053
|
console.error(" status Show project info + stats");
|