@memoraone/mcp 0.1.38 → 0.1.40
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/dist/cli.cjs +10630 -2440
- package/dist/daemon.cjs +634 -90
- package/dist/index.cjs +770 -226
- package/package.json +4 -2
package/dist/daemon.cjs
CHANGED
|
@@ -89,8 +89,50 @@ var HASH_SOCKET_FILENAME_RE = new RegExp(
|
|
|
89
89
|
`^mcp-[0-9a-f]{${BINDING_SOCKET_HASH_LENGTH}}\\.sock$`,
|
|
90
90
|
"i"
|
|
91
91
|
);
|
|
92
|
-
var IDE_TYPES = [
|
|
92
|
+
var IDE_TYPES = [
|
|
93
|
+
"cursor",
|
|
94
|
+
"copilot-vscode",
|
|
95
|
+
"jetbrains",
|
|
96
|
+
"claude-code",
|
|
97
|
+
"windsurf",
|
|
98
|
+
"opencode",
|
|
99
|
+
"codex",
|
|
100
|
+
"zed",
|
|
101
|
+
"kiro",
|
|
102
|
+
"visual-studio",
|
|
103
|
+
"cline",
|
|
104
|
+
"roo-code",
|
|
105
|
+
// dormant: unsupported for setup/connect
|
|
106
|
+
"auggie",
|
|
107
|
+
"continue",
|
|
108
|
+
// dormant: unsupported for setup/connect
|
|
109
|
+
"copilot-cli",
|
|
110
|
+
"kiro-cli",
|
|
111
|
+
"cline-cli",
|
|
112
|
+
"continue-cli",
|
|
113
|
+
// dormant: unsupported (no writer; wire id only)
|
|
114
|
+
"claude-desktop",
|
|
115
|
+
"gemini-cli",
|
|
116
|
+
// dormant: individual-user CLI unsupported; writer kept internal
|
|
117
|
+
"antigravity",
|
|
118
|
+
"antigravity-cli",
|
|
119
|
+
// Antigravity CLI (agy); shares MCP config with IDE; identity from clientInfo
|
|
120
|
+
"goose",
|
|
121
|
+
"junie",
|
|
122
|
+
"xcode",
|
|
123
|
+
"copilot-jetbrains",
|
|
124
|
+
"copilot-visual-studio"
|
|
125
|
+
];
|
|
93
126
|
var IDE_TYPE_SET = new Set(IDE_TYPES);
|
|
127
|
+
var IDE_TYPE_CLI_CHOICES = IDE_TYPES.join("|");
|
|
128
|
+
var IDE_TYPE_ALTERNATION = [...IDE_TYPES].sort((a, b) => b.length - a.length).join("|");
|
|
129
|
+
var LEGACY_SOCKET_FILENAME_RE = new RegExp(
|
|
130
|
+
`^mcp-([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})(?:-([0-9a-f]{12}))?(?:-(${IDE_TYPE_ALTERNATION}))?\\.sock$`,
|
|
131
|
+
"i"
|
|
132
|
+
);
|
|
133
|
+
var IDE_FROM_COMMAND_LINE_RE = new RegExp(
|
|
134
|
+
`--ide\\s+(${IDE_TYPE_ALTERNATION})(?:\\s|$)`
|
|
135
|
+
);
|
|
94
136
|
function parseIdeType(value) {
|
|
95
137
|
if (value === void 0 || value.trim() === "" || !IDE_TYPE_SET.has(value)) {
|
|
96
138
|
return void 0;
|
|
@@ -107,16 +149,19 @@ function parseIdeTypeFromArgv(args) {
|
|
|
107
149
|
}
|
|
108
150
|
return parseIdeType(args[idx + 1]);
|
|
109
151
|
}
|
|
110
|
-
function resolveBindingIdeType(env2 = process.env) {
|
|
152
|
+
function resolveBindingIdeType(env2 = process.env, ideTypeOverride) {
|
|
153
|
+
if (ideTypeOverride !== void 0) {
|
|
154
|
+
return ideTypeOverride;
|
|
155
|
+
}
|
|
111
156
|
return resolveIdeTypeFromEnv(env2) ?? "";
|
|
112
157
|
}
|
|
113
|
-
function getBindingSocketFilename(binding, env2 = process.env) {
|
|
114
|
-
const ideType = resolveBindingIdeType(env2);
|
|
158
|
+
function getBindingSocketFilename(binding, env2 = process.env, ideTypeOverride) {
|
|
159
|
+
const ideType = resolveBindingIdeType(env2, ideTypeOverride);
|
|
115
160
|
const hash = hashBindingIdentity(binding.repositoryBindingId, binding.workspaceRoot, ideType);
|
|
116
161
|
return `mcp-${hash}.sock`;
|
|
117
162
|
}
|
|
118
|
-
function getBindingSocketPath(binding, env2 = process.env) {
|
|
119
|
-
return path2.join(BASE_DIR, getBindingSocketFilename(binding, env2));
|
|
163
|
+
function getBindingSocketPath(binding, env2 = process.env, ideTypeOverride) {
|
|
164
|
+
return path2.join(BASE_DIR, getBindingSocketFilename(binding, env2, ideTypeOverride));
|
|
120
165
|
}
|
|
121
166
|
function ensureBaseDir() {
|
|
122
167
|
fs.mkdirSync(BASE_DIR, { recursive: true });
|
|
@@ -1501,7 +1546,7 @@ var EnvSchema = import_v4.z.object({
|
|
|
1501
1546
|
MEMORAONE_AGENT_NAME: import_v4.z.string().min(1).optional(),
|
|
1502
1547
|
MEMORAONE_AGENT_TYPE: import_v4.z.string().min(1).optional(),
|
|
1503
1548
|
MEMORAONE_SOURCE: import_v4.z.string().min(1).optional(),
|
|
1504
|
-
MEMORAONE_IDE_TYPE: import_v4.z.enum(
|
|
1549
|
+
MEMORAONE_IDE_TYPE: import_v4.z.enum(IDE_TYPES).optional(),
|
|
1505
1550
|
MEMORAONE_WORKLOG: import_v4.z.string().min(1).optional(),
|
|
1506
1551
|
MEMORAONE_HEARTBEAT: import_v4.z.string().min(1).optional(),
|
|
1507
1552
|
MEMORAONE_HEARTBEAT_INTERVAL_MS: import_v4.z.string().min(1).optional()
|
|
@@ -1550,7 +1595,9 @@ var config2 = {
|
|
|
1550
1595
|
devMode: parseBooleanFlag2(parsed.data.MEMORAONE_DEV_MODE, false),
|
|
1551
1596
|
worklogEnabled: parseBooleanFlag2(parsed.data.MEMORAONE_WORKLOG, true),
|
|
1552
1597
|
heartbeatEnabled: parseBooleanFlag2(parsed.data.MEMORAONE_HEARTBEAT, true),
|
|
1553
|
-
|
|
1598
|
+
// Cadence is owned by LOCAL_MCP_HEARTBEAT_INTERVAL_MS in heartbeat.ts (1_000).
|
|
1599
|
+
// Env override is accepted for forward-compat but the timer path ignores it.
|
|
1600
|
+
heartbeatIntervalMs: Number.parseInt(parsed.data.MEMORAONE_HEARTBEAT_INTERVAL_MS ?? "1000", 10)
|
|
1554
1601
|
};
|
|
1555
1602
|
|
|
1556
1603
|
// src/initializeBinding.ts
|
|
@@ -1842,8 +1889,79 @@ var logCommandShape = {
|
|
|
1842
1889
|
// src/tools/bindingStatus.ts
|
|
1843
1890
|
var bindingStatusShape = {};
|
|
1844
1891
|
|
|
1845
|
-
// src/tools/
|
|
1892
|
+
// src/tools/listTimeline.ts
|
|
1846
1893
|
var import_v411 = require("zod/v4");
|
|
1894
|
+
var listTimelineDescription = "List timeline events for the project bound to this Local MCP installation.";
|
|
1895
|
+
var listTimelineInputSchema = import_v411.z.object({
|
|
1896
|
+
since: import_v411.z.string().optional(),
|
|
1897
|
+
concept: import_v411.z.string().optional(),
|
|
1898
|
+
kind: import_v411.z.union([import_v411.z.string(), import_v411.z.array(import_v411.z.string())]).optional(),
|
|
1899
|
+
sort: import_v411.z.enum(["newest", "oldest"]).optional(),
|
|
1900
|
+
limit: import_v411.z.number().int().min(1).max(200).optional(),
|
|
1901
|
+
cursor: import_v411.z.string().optional()
|
|
1902
|
+
}).strict();
|
|
1903
|
+
|
|
1904
|
+
// src/tools/listConcepts.ts
|
|
1905
|
+
var import_v412 = require("zod/v4");
|
|
1906
|
+
var listConceptsDescription = "List concepts for the project bound to this Local MCP installation.";
|
|
1907
|
+
var listConceptsInputSchema = import_v412.z.object({
|
|
1908
|
+
q: import_v412.z.string().min(1).optional(),
|
|
1909
|
+
tag: import_v412.z.string().min(1).optional(),
|
|
1910
|
+
parent_id: import_v412.z.string().min(1).optional(),
|
|
1911
|
+
limit: import_v412.z.number().int().min(1).max(200).optional(),
|
|
1912
|
+
cursor: import_v412.z.string().min(1).optional()
|
|
1913
|
+
}).strict();
|
|
1914
|
+
|
|
1915
|
+
// src/tools/getConcept.ts
|
|
1916
|
+
var import_v413 = require("zod/v4");
|
|
1917
|
+
var getConceptDescription = "Get one concept by ID from the project bound to this Local MCP installation.";
|
|
1918
|
+
var getConceptInputSchema = import_v413.z.object({
|
|
1919
|
+
id: import_v413.z.string().trim().min(1)
|
|
1920
|
+
}).strict();
|
|
1921
|
+
|
|
1922
|
+
// src/tools/createConceptVersion.ts
|
|
1923
|
+
var import_v414 = require("zod/v4");
|
|
1924
|
+
var createConceptVersionDescription = "Create a version of a concept in the project bound to this Local MCP installation.";
|
|
1925
|
+
var createConceptVersionInputSchema = import_v414.z.object({
|
|
1926
|
+
id: import_v414.z.string().trim().min(1),
|
|
1927
|
+
value: import_v414.z.unknown(),
|
|
1928
|
+
reason: import_v414.z.string().optional(),
|
|
1929
|
+
confidence: import_v414.z.number().finite().min(0).max(1).optional(),
|
|
1930
|
+
source_ref: import_v414.z.string().optional(),
|
|
1931
|
+
tags: import_v414.z.array(import_v414.z.string()).optional(),
|
|
1932
|
+
parent_id: import_v414.z.union([import_v414.z.string(), import_v414.z.null()]).optional()
|
|
1933
|
+
}).strict();
|
|
1934
|
+
function isJsonValue(value) {
|
|
1935
|
+
if (value === null) return true;
|
|
1936
|
+
if (typeof value === "boolean" || typeof value === "string") return true;
|
|
1937
|
+
if (typeof value === "number") return Number.isFinite(value);
|
|
1938
|
+
if (Array.isArray(value)) return value.every(isJsonValue);
|
|
1939
|
+
if (typeof value !== "object") return false;
|
|
1940
|
+
const prototype = Object.getPrototypeOf(value);
|
|
1941
|
+
if (prototype !== Object.prototype && prototype !== null) return false;
|
|
1942
|
+
return Object.values(value).every(isJsonValue);
|
|
1943
|
+
}
|
|
1944
|
+
|
|
1945
|
+
// src/tools/toolInventory.ts
|
|
1946
|
+
var LOCAL_MCP_TOOL_NAMES = [
|
|
1947
|
+
"memora_ask_with_memory",
|
|
1948
|
+
"memora_post_event",
|
|
1949
|
+
"memora_create_fact",
|
|
1950
|
+
"memora_add_personal_context",
|
|
1951
|
+
"memora_get_personal_context",
|
|
1952
|
+
"memora_log_intent",
|
|
1953
|
+
"memora_log_change_summary",
|
|
1954
|
+
"memora_log_tool_result",
|
|
1955
|
+
"memora_log_command",
|
|
1956
|
+
"memora_status",
|
|
1957
|
+
"memora_list_timeline",
|
|
1958
|
+
"memora_list_concepts",
|
|
1959
|
+
"memora_get_concept",
|
|
1960
|
+
"memora_create_concept_version"
|
|
1961
|
+
];
|
|
1962
|
+
|
|
1963
|
+
// src/tools/handlers/postEvent.ts
|
|
1964
|
+
var import_v415 = require("zod/v4");
|
|
1847
1965
|
var crypto4 = __toESM(require("crypto"), 1);
|
|
1848
1966
|
|
|
1849
1967
|
// src/runContext.ts
|
|
@@ -1899,14 +2017,14 @@ function generateRunId() {
|
|
|
1899
2017
|
}
|
|
1900
2018
|
|
|
1901
2019
|
// src/tools/handlers/postEvent.ts
|
|
1902
|
-
var postEventInputSchema =
|
|
1903
|
-
kind:
|
|
1904
|
-
actor:
|
|
1905
|
-
identifier:
|
|
1906
|
-
id:
|
|
2020
|
+
var postEventInputSchema = import_v415.z.object({
|
|
2021
|
+
kind: import_v415.z.string().min(1),
|
|
2022
|
+
actor: import_v415.z.object({
|
|
2023
|
+
identifier: import_v415.z.string().min(1),
|
|
2024
|
+
id: import_v415.z.string().min(1).optional()
|
|
1907
2025
|
}),
|
|
1908
|
-
content:
|
|
1909
|
-
metadata:
|
|
2026
|
+
content: import_v415.z.record(import_v415.z.string(), import_v415.z.any()),
|
|
2027
|
+
metadata: import_v415.z.record(import_v415.z.string(), import_v415.z.any()).optional()
|
|
1910
2028
|
});
|
|
1911
2029
|
function buildPostEventContentFields(content) {
|
|
1912
2030
|
if (typeof content.message === "string") {
|
|
@@ -1978,10 +2096,10 @@ async function handlePostEvent(client, args) {
|
|
|
1978
2096
|
}
|
|
1979
2097
|
|
|
1980
2098
|
// src/tools/handlers/createFact.ts
|
|
1981
|
-
var
|
|
1982
|
-
var createFactInputSchema =
|
|
1983
|
-
content:
|
|
1984
|
-
metadata:
|
|
2099
|
+
var import_v416 = require("zod/v4");
|
|
2100
|
+
var createFactInputSchema = import_v416.z.object({
|
|
2101
|
+
content: import_v416.z.string().min(1),
|
|
2102
|
+
metadata: import_v416.z.record(import_v416.z.string(), import_v416.z.any()).optional()
|
|
1985
2103
|
});
|
|
1986
2104
|
async function handleCreateFact(client, args) {
|
|
1987
2105
|
const parsed2 = createFactInputSchema.parse(args ?? {});
|
|
@@ -2026,13 +2144,13 @@ async function handleCreateFact(client, args) {
|
|
|
2026
2144
|
}
|
|
2027
2145
|
|
|
2028
2146
|
// src/tools/handlers/addPersonalContext.ts
|
|
2029
|
-
var
|
|
2030
|
-
var addPersonalContextInputSchema =
|
|
2031
|
-
content:
|
|
2032
|
-
category:
|
|
2033
|
-
tags:
|
|
2034
|
-
scope_type:
|
|
2035
|
-
scope_id:
|
|
2147
|
+
var import_v417 = require("zod/v4");
|
|
2148
|
+
var addPersonalContextInputSchema = import_v417.z.object({
|
|
2149
|
+
content: import_v417.z.string().min(1),
|
|
2150
|
+
category: import_v417.z.string().optional(),
|
|
2151
|
+
tags: import_v417.z.array(import_v417.z.string()).optional(),
|
|
2152
|
+
scope_type: import_v417.z.enum(["general", "project"]).optional(),
|
|
2153
|
+
scope_id: import_v417.z.string().optional()
|
|
2036
2154
|
});
|
|
2037
2155
|
async function handleAddPersonalContext(client, args) {
|
|
2038
2156
|
const parsed2 = addPersonalContextInputSchema.parse(args ?? {});
|
|
@@ -2068,12 +2186,12 @@ async function handleAddPersonalContext(client, args) {
|
|
|
2068
2186
|
}
|
|
2069
2187
|
|
|
2070
2188
|
// src/tools/handlers/getPersonalContext.ts
|
|
2071
|
-
var
|
|
2072
|
-
var getPersonalContextInputSchema =
|
|
2073
|
-
query:
|
|
2074
|
-
scope_type:
|
|
2075
|
-
scope_id:
|
|
2076
|
-
limit:
|
|
2189
|
+
var import_v418 = require("zod/v4");
|
|
2190
|
+
var getPersonalContextInputSchema = import_v418.z.object({
|
|
2191
|
+
query: import_v418.z.string().optional(),
|
|
2192
|
+
scope_type: import_v418.z.enum(["general", "project"]).optional(),
|
|
2193
|
+
scope_id: import_v418.z.string().optional(),
|
|
2194
|
+
limit: import_v418.z.number().int().positive().optional()
|
|
2077
2195
|
});
|
|
2078
2196
|
function buildPersonalContextPath(parsed2) {
|
|
2079
2197
|
const params = new URLSearchParams();
|
|
@@ -2110,13 +2228,13 @@ async function handleGetPersonalContext(client, args) {
|
|
|
2110
2228
|
}
|
|
2111
2229
|
|
|
2112
2230
|
// src/tools/handlers/askWithMemory.ts
|
|
2113
|
-
var
|
|
2114
|
-
var askWithMemoryInputSchema =
|
|
2115
|
-
question:
|
|
2116
|
-
code_context:
|
|
2117
|
-
file_path:
|
|
2118
|
-
selected_text:
|
|
2119
|
-
language:
|
|
2231
|
+
var import_v419 = require("zod/v4");
|
|
2232
|
+
var askWithMemoryInputSchema = import_v419.z.object({
|
|
2233
|
+
question: import_v419.z.string().min(1),
|
|
2234
|
+
code_context: import_v419.z.object({
|
|
2235
|
+
file_path: import_v419.z.string().optional(),
|
|
2236
|
+
selected_text: import_v419.z.string().optional(),
|
|
2237
|
+
language: import_v419.z.string().optional()
|
|
2120
2238
|
}).optional()
|
|
2121
2239
|
});
|
|
2122
2240
|
function isAskWithMemoryResponse(value) {
|
|
@@ -2152,13 +2270,13 @@ async function handleAskWithMemory(client, args) {
|
|
|
2152
2270
|
}
|
|
2153
2271
|
|
|
2154
2272
|
// src/tools/handlers/logIntent.ts
|
|
2155
|
-
var
|
|
2156
|
-
var logIntentInputSchema =
|
|
2157
|
-
intent:
|
|
2158
|
-
message:
|
|
2159
|
-
context:
|
|
2160
|
-
intent_source:
|
|
2161
|
-
run_id:
|
|
2273
|
+
var import_v420 = require("zod/v4");
|
|
2274
|
+
var logIntentInputSchema = import_v420.z.object({
|
|
2275
|
+
intent: import_v420.z.enum(["task", "decision"]),
|
|
2276
|
+
message: import_v420.z.string().min(1),
|
|
2277
|
+
context: import_v420.z.record(import_v420.z.string(), import_v420.z.any()).optional(),
|
|
2278
|
+
intent_source: import_v420.z.string().optional().default("cursor_chat"),
|
|
2279
|
+
run_id: import_v420.z.string().min(1).optional()
|
|
2162
2280
|
});
|
|
2163
2281
|
async function handleLogIntent(client, args) {
|
|
2164
2282
|
const parsed2 = logIntentInputSchema.parse(args ?? {});
|
|
@@ -2200,18 +2318,18 @@ async function handleLogIntent(client, args) {
|
|
|
2200
2318
|
}
|
|
2201
2319
|
|
|
2202
2320
|
// src/tools/handlers/logChangeSummary.ts
|
|
2203
|
-
var
|
|
2204
|
-
var logChangeSummaryInputSchema =
|
|
2205
|
-
summary:
|
|
2206
|
-
scope:
|
|
2207
|
-
files:
|
|
2208
|
-
stats:
|
|
2209
|
-
files:
|
|
2210
|
-
add:
|
|
2211
|
-
del:
|
|
2321
|
+
var import_v421 = require("zod/v4");
|
|
2322
|
+
var logChangeSummaryInputSchema = import_v421.z.object({
|
|
2323
|
+
summary: import_v421.z.string().min(1),
|
|
2324
|
+
scope: import_v421.z.string().min(1).optional(),
|
|
2325
|
+
files: import_v421.z.array(import_v421.z.string().min(1)).optional(),
|
|
2326
|
+
stats: import_v421.z.object({
|
|
2327
|
+
files: import_v421.z.number().int().nonnegative().optional(),
|
|
2328
|
+
add: import_v421.z.number().int().nonnegative().optional(),
|
|
2329
|
+
del: import_v421.z.number().int().nonnegative().optional()
|
|
2212
2330
|
}).optional(),
|
|
2213
|
-
commit:
|
|
2214
|
-
run_id:
|
|
2331
|
+
commit: import_v421.z.string().min(1).optional(),
|
|
2332
|
+
run_id: import_v421.z.string().min(1).optional()
|
|
2215
2333
|
});
|
|
2216
2334
|
async function handleLogChangeSummary(client, args) {
|
|
2217
2335
|
const parsed2 = logChangeSummaryInputSchema.parse(args ?? {});
|
|
@@ -2246,17 +2364,17 @@ async function handleLogChangeSummary(client, args) {
|
|
|
2246
2364
|
}
|
|
2247
2365
|
|
|
2248
2366
|
// src/tools/handlers/logToolResult.ts
|
|
2249
|
-
var
|
|
2250
|
-
var logToolResultInputSchema =
|
|
2251
|
-
tool:
|
|
2252
|
-
status:
|
|
2253
|
-
summary:
|
|
2254
|
-
run_id:
|
|
2255
|
-
duration_ms:
|
|
2256
|
-
error_code:
|
|
2257
|
-
error_message:
|
|
2258
|
-
error_kind:
|
|
2259
|
-
stats:
|
|
2367
|
+
var import_v422 = require("zod/v4");
|
|
2368
|
+
var logToolResultInputSchema = import_v422.z.object({
|
|
2369
|
+
tool: import_v422.z.string().min(1),
|
|
2370
|
+
status: import_v422.z.enum(["ok", "error", "partial"]),
|
|
2371
|
+
summary: import_v422.z.string().min(1),
|
|
2372
|
+
run_id: import_v422.z.string().min(1).optional(),
|
|
2373
|
+
duration_ms: import_v422.z.number().int().nonnegative().optional(),
|
|
2374
|
+
error_code: import_v422.z.string().min(1).optional(),
|
|
2375
|
+
error_message: import_v422.z.string().min(1).optional(),
|
|
2376
|
+
error_kind: import_v422.z.enum(["infra", "logic", "auth", "rate_limit", "validation", "unknown"]).optional(),
|
|
2377
|
+
stats: import_v422.z.record(import_v422.z.string(), import_v422.z.any()).optional()
|
|
2260
2378
|
});
|
|
2261
2379
|
async function handleLogToolResult(client, args) {
|
|
2262
2380
|
const parsed2 = logToolResultInputSchema.parse(args ?? {});
|
|
@@ -2294,15 +2412,15 @@ async function handleLogToolResult(client, args) {
|
|
|
2294
2412
|
}
|
|
2295
2413
|
|
|
2296
2414
|
// src/tools/handlers/logCommand.ts
|
|
2297
|
-
var
|
|
2298
|
-
var logCommandInputSchema =
|
|
2299
|
-
cmd:
|
|
2300
|
-
summary:
|
|
2301
|
-
cwd:
|
|
2302
|
-
exit_code:
|
|
2303
|
-
duration_ms:
|
|
2304
|
-
run_id:
|
|
2305
|
-
stats:
|
|
2415
|
+
var import_v423 = require("zod/v4");
|
|
2416
|
+
var logCommandInputSchema = import_v423.z.object({
|
|
2417
|
+
cmd: import_v423.z.string().min(1),
|
|
2418
|
+
summary: import_v423.z.string().min(1),
|
|
2419
|
+
cwd: import_v423.z.string().min(1).optional(),
|
|
2420
|
+
exit_code: import_v423.z.number().int().optional(),
|
|
2421
|
+
duration_ms: import_v423.z.number().int().nonnegative().optional(),
|
|
2422
|
+
run_id: import_v423.z.string().min(1).optional(),
|
|
2423
|
+
stats: import_v423.z.record(import_v423.z.string(), import_v423.z.any()).optional()
|
|
2306
2424
|
});
|
|
2307
2425
|
async function handleLogCommand(client, args) {
|
|
2308
2426
|
const parsed2 = logCommandInputSchema.parse(args ?? {});
|
|
@@ -2337,6 +2455,244 @@ async function handleLogCommand(client, args) {
|
|
|
2337
2455
|
return { ok: true };
|
|
2338
2456
|
}
|
|
2339
2457
|
|
|
2458
|
+
// src/tools/responseProjection.ts
|
|
2459
|
+
var timelineItemKeys = [
|
|
2460
|
+
"id",
|
|
2461
|
+
"ts",
|
|
2462
|
+
"kind",
|
|
2463
|
+
"concept",
|
|
2464
|
+
"old_value",
|
|
2465
|
+
"new_value",
|
|
2466
|
+
"reason",
|
|
2467
|
+
"confidence",
|
|
2468
|
+
"links",
|
|
2469
|
+
"source_ref",
|
|
2470
|
+
"redacted",
|
|
2471
|
+
"redaction_reason",
|
|
2472
|
+
"summary",
|
|
2473
|
+
"consolidated_of"
|
|
2474
|
+
];
|
|
2475
|
+
var conceptVersionKeys = [
|
|
2476
|
+
"version",
|
|
2477
|
+
"ts",
|
|
2478
|
+
"reason",
|
|
2479
|
+
"confidence",
|
|
2480
|
+
"source_ref",
|
|
2481
|
+
"value"
|
|
2482
|
+
];
|
|
2483
|
+
function invalidResponse() {
|
|
2484
|
+
throw new Error("Invalid Memora response");
|
|
2485
|
+
}
|
|
2486
|
+
function isRecord(value) {
|
|
2487
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2488
|
+
}
|
|
2489
|
+
function pickFields(raw, keys) {
|
|
2490
|
+
const result = {};
|
|
2491
|
+
for (const key of keys) {
|
|
2492
|
+
if (Object.prototype.hasOwnProperty.call(raw, key) && raw[key] !== void 0) {
|
|
2493
|
+
result[key] = raw[key];
|
|
2494
|
+
}
|
|
2495
|
+
}
|
|
2496
|
+
return result;
|
|
2497
|
+
}
|
|
2498
|
+
function pickConceptVersion(raw) {
|
|
2499
|
+
return pickFields(raw, conceptVersionKeys);
|
|
2500
|
+
}
|
|
2501
|
+
function pickConceptItem(raw) {
|
|
2502
|
+
if (typeof raw.id !== "string" || raw.id.trim() === "") invalidResponse();
|
|
2503
|
+
const item = { id: raw.id };
|
|
2504
|
+
if (Object.prototype.hasOwnProperty.call(raw, "tags")) {
|
|
2505
|
+
if (!Array.isArray(raw.tags) || !raw.tags.every((tag) => typeof tag === "string")) {
|
|
2506
|
+
invalidResponse();
|
|
2507
|
+
}
|
|
2508
|
+
item.tags = raw.tags;
|
|
2509
|
+
}
|
|
2510
|
+
if (Object.prototype.hasOwnProperty.call(raw, "parent_id")) {
|
|
2511
|
+
if (raw.parent_id !== null && typeof raw.parent_id !== "string") invalidResponse();
|
|
2512
|
+
item.parent_id = raw.parent_id;
|
|
2513
|
+
}
|
|
2514
|
+
if (Object.prototype.hasOwnProperty.call(raw, "latest")) {
|
|
2515
|
+
if (raw.latest === null) {
|
|
2516
|
+
item.latest = null;
|
|
2517
|
+
} else if (isRecord(raw.latest)) {
|
|
2518
|
+
item.latest = pickConceptVersion(raw.latest);
|
|
2519
|
+
} else {
|
|
2520
|
+
invalidResponse();
|
|
2521
|
+
}
|
|
2522
|
+
}
|
|
2523
|
+
return item;
|
|
2524
|
+
}
|
|
2525
|
+
function normalizeCursor(raw) {
|
|
2526
|
+
for (const key of ["next_cursor", "nextCursor"]) {
|
|
2527
|
+
if (!Object.prototype.hasOwnProperty.call(raw, key)) continue;
|
|
2528
|
+
const value = raw[key];
|
|
2529
|
+
if (value === null) return null;
|
|
2530
|
+
if (typeof value === "string") return value;
|
|
2531
|
+
invalidResponse();
|
|
2532
|
+
}
|
|
2533
|
+
return null;
|
|
2534
|
+
}
|
|
2535
|
+
function projectTimelineResponse(data) {
|
|
2536
|
+
if (!isRecord(data) || !Array.isArray(data.items) || !isRecord(data.page)) {
|
|
2537
|
+
invalidResponse();
|
|
2538
|
+
}
|
|
2539
|
+
if (typeof data.page.limit !== "number" || !Number.isFinite(data.page.limit) || data.page.sort !== "newest" && data.page.sort !== "oldest") {
|
|
2540
|
+
invalidResponse();
|
|
2541
|
+
}
|
|
2542
|
+
const items = data.items.map((entry) => {
|
|
2543
|
+
if (!isRecord(entry)) invalidResponse();
|
|
2544
|
+
return pickFields(entry, timelineItemKeys);
|
|
2545
|
+
});
|
|
2546
|
+
return {
|
|
2547
|
+
items,
|
|
2548
|
+
page: {
|
|
2549
|
+
limit: data.page.limit,
|
|
2550
|
+
sort: data.page.sort,
|
|
2551
|
+
next_cursor: normalizeCursor(data.page)
|
|
2552
|
+
}
|
|
2553
|
+
};
|
|
2554
|
+
}
|
|
2555
|
+
function projectConceptListResponse(data, requestedLimit) {
|
|
2556
|
+
if (!isRecord(data)) invalidResponse();
|
|
2557
|
+
let entries;
|
|
2558
|
+
if (Object.prototype.hasOwnProperty.call(data, "rows")) {
|
|
2559
|
+
entries = data.rows;
|
|
2560
|
+
} else if (Object.prototype.hasOwnProperty.call(data, "items")) {
|
|
2561
|
+
entries = data.items;
|
|
2562
|
+
} else {
|
|
2563
|
+
invalidResponse();
|
|
2564
|
+
}
|
|
2565
|
+
if (!Array.isArray(entries)) invalidResponse();
|
|
2566
|
+
let cursorSource = data;
|
|
2567
|
+
if (!Object.prototype.hasOwnProperty.call(data, "next_cursor") && !Object.prototype.hasOwnProperty.call(data, "nextCursor") && Object.prototype.hasOwnProperty.call(data, "page")) {
|
|
2568
|
+
if (!isRecord(data.page)) invalidResponse();
|
|
2569
|
+
cursorSource = data.page;
|
|
2570
|
+
}
|
|
2571
|
+
return {
|
|
2572
|
+
items: entries.map((entry) => {
|
|
2573
|
+
if (!isRecord(entry)) invalidResponse();
|
|
2574
|
+
return pickConceptItem(entry);
|
|
2575
|
+
}),
|
|
2576
|
+
page: {
|
|
2577
|
+
limit: requestedLimit ?? 50,
|
|
2578
|
+
next_cursor: normalizeCursor(cursorSource)
|
|
2579
|
+
}
|
|
2580
|
+
};
|
|
2581
|
+
}
|
|
2582
|
+
function projectConceptResponse(data) {
|
|
2583
|
+
if (!isRecord(data)) invalidResponse();
|
|
2584
|
+
const item = pickConceptItem(data);
|
|
2585
|
+
if (!Object.prototype.hasOwnProperty.call(data, "history")) {
|
|
2586
|
+
return { ...item, history: [] };
|
|
2587
|
+
}
|
|
2588
|
+
if (!Array.isArray(data.history)) invalidResponse();
|
|
2589
|
+
const history = data.history.map((entry) => {
|
|
2590
|
+
if (!isRecord(entry)) invalidResponse();
|
|
2591
|
+
return pickConceptVersion(entry);
|
|
2592
|
+
});
|
|
2593
|
+
return { ...item, history };
|
|
2594
|
+
}
|
|
2595
|
+
function projectCreatedConceptVersionResponse(data) {
|
|
2596
|
+
if (!isRecord(data)) invalidResponse();
|
|
2597
|
+
return pickConceptItem(data);
|
|
2598
|
+
}
|
|
2599
|
+
|
|
2600
|
+
// src/tools/handlers/toolRequestError.ts
|
|
2601
|
+
function rethrowToolRequestError(toolName, error) {
|
|
2602
|
+
if (error instanceof SyntaxError) {
|
|
2603
|
+
throw new Error("Invalid Memora response");
|
|
2604
|
+
}
|
|
2605
|
+
if (!(error instanceof MemoraOneHttpError)) throw error;
|
|
2606
|
+
let detail = "request failed";
|
|
2607
|
+
if (error.status === 401) detail = "authentication failed";
|
|
2608
|
+
else if (error.status === 403) detail = "connection unavailable";
|
|
2609
|
+
else if (error.status === 404) detail = "resource not found";
|
|
2610
|
+
else if (error.status === 409) detail = "conflict";
|
|
2611
|
+
else if (error.status >= 500) detail = "backend error";
|
|
2612
|
+
throw new Error(`${toolName} failed: ${error.status} ${detail}`);
|
|
2613
|
+
}
|
|
2614
|
+
|
|
2615
|
+
// src/tools/handlers/listTimeline.ts
|
|
2616
|
+
function buildQuery(input) {
|
|
2617
|
+
const parts = [];
|
|
2618
|
+
const append = (key, value) => {
|
|
2619
|
+
parts.push(`${encodeURIComponent(key)}=${encodeURIComponent(value)}`);
|
|
2620
|
+
};
|
|
2621
|
+
if (input.since !== void 0) append("since", input.since);
|
|
2622
|
+
if (input.concept !== void 0) append("concept", input.concept);
|
|
2623
|
+
if (input.kind !== void 0) {
|
|
2624
|
+
for (const kind of Array.isArray(input.kind) ? input.kind : [input.kind]) {
|
|
2625
|
+
append("kind", kind);
|
|
2626
|
+
}
|
|
2627
|
+
}
|
|
2628
|
+
if (input.sort !== void 0) append("sort", input.sort);
|
|
2629
|
+
if (input.limit !== void 0) append("limit", String(input.limit));
|
|
2630
|
+
if (input.cursor !== void 0) append("cursor", input.cursor);
|
|
2631
|
+
return parts.length === 0 ? "" : `?${parts.join("&")}`;
|
|
2632
|
+
}
|
|
2633
|
+
async function handleListTimeline(client, args) {
|
|
2634
|
+
const input = listTimelineInputSchema.parse(args ?? {});
|
|
2635
|
+
try {
|
|
2636
|
+
return projectTimelineResponse(await client.get(`/timeline${buildQuery(input)}`));
|
|
2637
|
+
} catch (error) {
|
|
2638
|
+
rethrowToolRequestError("memora_list_timeline", error);
|
|
2639
|
+
}
|
|
2640
|
+
}
|
|
2641
|
+
|
|
2642
|
+
// src/tools/handlers/listConcepts.ts
|
|
2643
|
+
function buildQuery2(input) {
|
|
2644
|
+
const parts = [];
|
|
2645
|
+
const append = (key, value) => {
|
|
2646
|
+
parts.push(`${encodeURIComponent(key)}=${encodeURIComponent(value)}`);
|
|
2647
|
+
};
|
|
2648
|
+
if (input.q !== void 0) append("q", input.q);
|
|
2649
|
+
if (input.tag !== void 0) append("tag", input.tag);
|
|
2650
|
+
if (input.parent_id !== void 0) append("parent_id", input.parent_id);
|
|
2651
|
+
if (input.limit !== void 0) append("limit", String(input.limit));
|
|
2652
|
+
if (input.cursor !== void 0) append("cursor", input.cursor);
|
|
2653
|
+
return parts.length === 0 ? "" : `?${parts.join("&")}`;
|
|
2654
|
+
}
|
|
2655
|
+
async function handleListConcepts(client, args) {
|
|
2656
|
+
const input = listConceptsInputSchema.parse(args ?? {});
|
|
2657
|
+
try {
|
|
2658
|
+
const data = await client.get(`/concepts${buildQuery2(input)}`);
|
|
2659
|
+
return projectConceptListResponse(data, input.limit);
|
|
2660
|
+
} catch (error) {
|
|
2661
|
+
rethrowToolRequestError("memora_list_concepts", error);
|
|
2662
|
+
}
|
|
2663
|
+
}
|
|
2664
|
+
|
|
2665
|
+
// src/tools/handlers/getConcept.ts
|
|
2666
|
+
async function handleGetConcept(client, args) {
|
|
2667
|
+
const input = getConceptInputSchema.parse(args ?? {});
|
|
2668
|
+
try {
|
|
2669
|
+
const data = await client.get(`/concepts/${encodeURIComponent(input.id)}`);
|
|
2670
|
+
return projectConceptResponse(data);
|
|
2671
|
+
} catch (error) {
|
|
2672
|
+
rethrowToolRequestError("memora_get_concept", error);
|
|
2673
|
+
}
|
|
2674
|
+
}
|
|
2675
|
+
|
|
2676
|
+
// src/tools/handlers/createConceptVersion.ts
|
|
2677
|
+
async function handleCreateConceptVersion(client, args) {
|
|
2678
|
+
const input = createConceptVersionInputSchema.parse(args ?? {});
|
|
2679
|
+
if (!isJsonValue(input.value)) {
|
|
2680
|
+
throw new Error("Invalid arguments: value must be a valid JSON value");
|
|
2681
|
+
}
|
|
2682
|
+
const body = { value: input.value };
|
|
2683
|
+
if (input.reason !== void 0) body.reason = input.reason;
|
|
2684
|
+
if (input.confidence !== void 0) body.confidence = input.confidence;
|
|
2685
|
+
if (input.source_ref !== void 0) body.source_ref = input.source_ref;
|
|
2686
|
+
if (input.tags !== void 0) body.tags = input.tags;
|
|
2687
|
+
if (input.parent_id !== void 0) body.parent_id = input.parent_id;
|
|
2688
|
+
try {
|
|
2689
|
+
const path14 = `/concepts/${encodeURIComponent(input.id)}/versions`;
|
|
2690
|
+
return projectCreatedConceptVersionResponse(await client.post(path14, body));
|
|
2691
|
+
} catch (error) {
|
|
2692
|
+
rethrowToolRequestError("memora_create_concept_version", error);
|
|
2693
|
+
}
|
|
2694
|
+
}
|
|
2695
|
+
|
|
2340
2696
|
// src/tools/handlers/bindingStatus.ts
|
|
2341
2697
|
function buildBindingStatus(binding, options = {}) {
|
|
2342
2698
|
const status = {
|
|
@@ -2387,8 +2743,9 @@ function isHeartbeatDebugEnabled() {
|
|
|
2387
2743
|
const value = String(process.env.MEMORAONE_DEBUG_HEARTBEAT ?? "").trim().toLowerCase();
|
|
2388
2744
|
return ["1", "true", "yes", "on"].includes(value);
|
|
2389
2745
|
}
|
|
2746
|
+
var LOCAL_MCP_HEARTBEAT_INTERVAL_MS = 1e3;
|
|
2390
2747
|
function resolveHeartbeatIntervalMs() {
|
|
2391
|
-
return
|
|
2748
|
+
return LOCAL_MCP_HEARTBEAT_INTERVAL_MS;
|
|
2392
2749
|
}
|
|
2393
2750
|
function redactSensitiveText(text) {
|
|
2394
2751
|
return text.replace(/mcs_[A-Za-z0-9_-]+/g, "mcs_[redacted]").replace(/mia_[A-Za-z0-9_-]+/g, "mia_[redacted]").replace(/mir_[A-Za-z0-9_-]+/g, "mir_[redacted]").replace(/mcc_[A-Za-z0-9_-]+/g, "mcc_[redacted]").replace(/Bearer\s+\S+/gi, "Bearer [redacted]");
|
|
@@ -2498,6 +2855,7 @@ async function sendProjectHeartbeat(client, ctx) {
|
|
|
2498
2855
|
}
|
|
2499
2856
|
function createDaemonHeartbeat(opts) {
|
|
2500
2857
|
let interval = null;
|
|
2858
|
+
let runGeneration = 0;
|
|
2501
2859
|
let client = null;
|
|
2502
2860
|
let announced = false;
|
|
2503
2861
|
let studioActive = null;
|
|
@@ -2566,21 +2924,24 @@ function createDaemonHeartbeat(opts) {
|
|
|
2566
2924
|
studioActive = true;
|
|
2567
2925
|
}
|
|
2568
2926
|
};
|
|
2569
|
-
const tick = async () => {
|
|
2570
|
-
if (!client) return;
|
|
2927
|
+
const tick = async (generation) => {
|
|
2928
|
+
if (!client || generation !== runGeneration) return;
|
|
2571
2929
|
const outcome = await sendProjectHeartbeat(client, ctx);
|
|
2930
|
+
if (generation !== runGeneration || !interval) return;
|
|
2572
2931
|
applyHeartbeatOutcome(outcome);
|
|
2573
2932
|
};
|
|
2574
2933
|
const beginInterval = () => {
|
|
2575
2934
|
if (interval) return;
|
|
2576
2935
|
const intervalMs = resolveHeartbeatIntervalMs();
|
|
2936
|
+
const generation = runGeneration;
|
|
2577
2937
|
log2(
|
|
2578
2938
|
`daemon owns heartbeat for binding=${opts.binding.repositoryBindingId} project=${opts.binding.projectId} ideType=${ctx.ideType ?? "unknown"} interval=${intervalMs}ms`
|
|
2579
2939
|
);
|
|
2580
|
-
void tick();
|
|
2581
2940
|
interval = setInterval(() => {
|
|
2582
|
-
void tick();
|
|
2941
|
+
void tick(generation);
|
|
2583
2942
|
}, intervalMs);
|
|
2943
|
+
interval.unref?.();
|
|
2944
|
+
void tick(generation);
|
|
2584
2945
|
};
|
|
2585
2946
|
const start = async () => {
|
|
2586
2947
|
if (!config2.heartbeatEnabled) {
|
|
@@ -2613,6 +2974,7 @@ function createDaemonHeartbeat(opts) {
|
|
|
2613
2974
|
}
|
|
2614
2975
|
};
|
|
2615
2976
|
const stop = () => {
|
|
2977
|
+
runGeneration += 1;
|
|
2616
2978
|
if (interval) {
|
|
2617
2979
|
clearInterval(interval);
|
|
2618
2980
|
interval = null;
|
|
@@ -2632,7 +2994,7 @@ function createDaemonHeartbeat(opts) {
|
|
|
2632
2994
|
return;
|
|
2633
2995
|
}
|
|
2634
2996
|
if (client && interval) {
|
|
2635
|
-
void tick();
|
|
2997
|
+
void tick(runGeneration);
|
|
2636
2998
|
}
|
|
2637
2999
|
};
|
|
2638
3000
|
const getIdeType = () => ctx.ideType;
|
|
@@ -2652,12 +3014,125 @@ function createDaemonHeartbeat(opts) {
|
|
|
2652
3014
|
}
|
|
2653
3015
|
|
|
2654
3016
|
// src/ideType.ts
|
|
3017
|
+
var RELIABLE_CLIENT_INFO_NAMES = /* @__PURE__ */ new Map([
|
|
3018
|
+
// Existing
|
|
3019
|
+
["claude-code", "claude-code"],
|
|
3020
|
+
["devin", "windsurf"],
|
|
3021
|
+
["windsurf", "windsurf"],
|
|
3022
|
+
// Zed
|
|
3023
|
+
["zed", "zed"],
|
|
3024
|
+
// Kiro IDE (exact only — not generic "kiro …" mcp-remote wrappers)
|
|
3025
|
+
["kiro", "kiro"],
|
|
3026
|
+
// Visual Studio (never Visual Studio Code)
|
|
3027
|
+
["visual studio", "visual-studio"],
|
|
3028
|
+
["visual-studio", "visual-studio"],
|
|
3029
|
+
// Cline IDE
|
|
3030
|
+
["cline", "cline"],
|
|
3031
|
+
// Roo Code
|
|
3032
|
+
["roo code", "roo-code"],
|
|
3033
|
+
["roo-code", "roo-code"],
|
|
3034
|
+
// Auggie / Augment Code (canonical wire ID: auggie)
|
|
3035
|
+
["auggie", "auggie"],
|
|
3036
|
+
["augment", "auggie"],
|
|
3037
|
+
["augment code", "auggie"],
|
|
3038
|
+
["augment-code", "auggie"],
|
|
3039
|
+
// Continue IDE (not bare "continue")
|
|
3040
|
+
["continue-client", "continue"],
|
|
3041
|
+
// Continue CLI
|
|
3042
|
+
["continue-cli-client", "continue-cli"],
|
|
3043
|
+
["continue-cli", "continue-cli"],
|
|
3044
|
+
["continue cli", "continue-cli"],
|
|
3045
|
+
// Copilot CLI (not GitHub Copilot in VS Code)
|
|
3046
|
+
["github-copilot-developer", "copilot-cli"],
|
|
3047
|
+
["copilot-cli", "copilot-cli"],
|
|
3048
|
+
["copilot cli", "copilot-cli"],
|
|
3049
|
+
// Kiro CLI (explicit CLI names only — not Amazon Q / Q-DEV-CLI)
|
|
3050
|
+
["kiro-cli", "kiro-cli"],
|
|
3051
|
+
["kiro cli", "kiro-cli"],
|
|
3052
|
+
// Cline CLI
|
|
3053
|
+
["cline-cli", "cline-cli"],
|
|
3054
|
+
["cline cli", "cline-cli"],
|
|
3055
|
+
// Claude Desktop (never bare "claude"; never claude-code)
|
|
3056
|
+
["claude-ai", "claude-desktop"],
|
|
3057
|
+
["claude-desktop", "claude-desktop"],
|
|
3058
|
+
["claude desktop", "claude-desktop"],
|
|
3059
|
+
// Gemini CLI (not bare "gemini")
|
|
3060
|
+
["gemini-cli", "gemini-cli"],
|
|
3061
|
+
["gemini cli", "gemini-cli"],
|
|
3062
|
+
// Google Antigravity IDE vs CLI (shared MCP config; clientInfo distinguishes)
|
|
3063
|
+
["antigravity", "antigravity"],
|
|
3064
|
+
["antigravity ide", "antigravity"],
|
|
3065
|
+
["antigravity-client", "antigravity-cli"],
|
|
3066
|
+
// Goose
|
|
3067
|
+
["goose", "goose"],
|
|
3068
|
+
// JetBrains Junie (distinct from generic jetbrains / copilot-jetbrains)
|
|
3069
|
+
["junie", "junie"],
|
|
3070
|
+
// GitHub Copilot for Xcode
|
|
3071
|
+
["xcode", "xcode"],
|
|
3072
|
+
["copilot-xcode", "xcode"],
|
|
3073
|
+
["github-copilot-xcode", "xcode"],
|
|
3074
|
+
// GitHub Copilot for JetBrains (distinct from jetbrains AI Assistant)
|
|
3075
|
+
["copilot-jetbrains", "copilot-jetbrains"],
|
|
3076
|
+
["github-copilot-jetbrains", "copilot-jetbrains"],
|
|
3077
|
+
["github copilot jetbrains", "copilot-jetbrains"],
|
|
3078
|
+
// GitHub Copilot in Visual Studio (distinct from visual-studio / copilot-vscode)
|
|
3079
|
+
["copilot-visual-studio", "copilot-visual-studio"],
|
|
3080
|
+
["github-copilot-visual-studio", "copilot-visual-studio"],
|
|
3081
|
+
["github copilot visual studio", "copilot-visual-studio"]
|
|
3082
|
+
]);
|
|
3083
|
+
function mapReliableClientInfoName(name) {
|
|
3084
|
+
if (typeof name !== "string") {
|
|
3085
|
+
return void 0;
|
|
3086
|
+
}
|
|
3087
|
+
const normalized = name.trim().toLowerCase();
|
|
3088
|
+
if (normalized === "") {
|
|
3089
|
+
return void 0;
|
|
3090
|
+
}
|
|
3091
|
+
const exact = RELIABLE_CLIENT_INFO_NAMES.get(normalized);
|
|
3092
|
+
if (exact) {
|
|
3093
|
+
return exact;
|
|
3094
|
+
}
|
|
3095
|
+
if (/^windsurf[\s_-].+$/.test(normalized)) {
|
|
3096
|
+
return "windsurf";
|
|
3097
|
+
}
|
|
3098
|
+
return void 0;
|
|
3099
|
+
}
|
|
3100
|
+
function mapReliableHostIdentity(env2) {
|
|
3101
|
+
if (env2.WINDSURF_IDE_TYPE === "windsurf") {
|
|
3102
|
+
return "windsurf";
|
|
3103
|
+
}
|
|
3104
|
+
if (env2.ACP_BACKEND === "windsurf") {
|
|
3105
|
+
return "windsurf";
|
|
3106
|
+
}
|
|
3107
|
+
if (env2.__CFBundleIdentifier === "com.exafunction.windsurf") {
|
|
3108
|
+
return "windsurf";
|
|
3109
|
+
}
|
|
3110
|
+
if (env2.__CFBundleIdentifier === "com.anthropic.claudefordesktop") {
|
|
3111
|
+
return "claude-desktop";
|
|
3112
|
+
}
|
|
3113
|
+
if (env2.__CFBundleIdentifier === "dev.zed.Zed") {
|
|
3114
|
+
return "zed";
|
|
3115
|
+
}
|
|
3116
|
+
if (Object.prototype.hasOwnProperty.call(env2, "COPILOT_CLI")) {
|
|
3117
|
+
return "copilot-cli";
|
|
3118
|
+
}
|
|
3119
|
+
return void 0;
|
|
3120
|
+
}
|
|
2655
3121
|
function inferIdeType(params, options = {}) {
|
|
2656
3122
|
const env2 = options.env ?? process.env;
|
|
2657
3123
|
const argv = (options.argv ?? process.argv).join(" ").toLowerCase();
|
|
2658
|
-
const
|
|
2659
|
-
|
|
2660
|
-
|
|
3124
|
+
const hasExplicitConfigOption = Object.prototype.hasOwnProperty.call(options, "configIdeType");
|
|
3125
|
+
const explicitHint = hasExplicitConfigOption ? options.configIdeType : resolveIdeTypeFromEnv(env2) ?? config2.ideType;
|
|
3126
|
+
const fromClientInfo = mapReliableClientInfoName(params?.clientInfo?.name);
|
|
3127
|
+
if (fromClientInfo) {
|
|
3128
|
+
return fromClientInfo;
|
|
3129
|
+
}
|
|
3130
|
+
const fromHost = mapReliableHostIdentity(env2);
|
|
3131
|
+
if (fromHost) {
|
|
3132
|
+
return fromHost;
|
|
3133
|
+
}
|
|
3134
|
+
if (explicitHint) {
|
|
3135
|
+
return explicitHint;
|
|
2661
3136
|
}
|
|
2662
3137
|
const clientInfoName = String(params?.clientInfo?.name ?? "").toLowerCase();
|
|
2663
3138
|
const clientInfoVersion = String(params?.clientInfo?.version ?? "").toLowerCase();
|
|
@@ -2682,7 +3157,7 @@ function inferIdeType(params, options = {}) {
|
|
|
2682
3157
|
if (hasJetBrainsSignals) {
|
|
2683
3158
|
return "jetbrains";
|
|
2684
3159
|
}
|
|
2685
|
-
const hasVsCodeSignals = envKeys.some((key) => key.startsWith("VSCODE_")) || /(visual studio code|vscode|vs code
|
|
3160
|
+
const hasVsCodeSignals = envKeys.some((key) => key.startsWith("VSCODE_")) || /(visual studio code|vscode|vs code)/.test(clientInfoName) || /(visual studio code|vscode|vs code)/.test(argv);
|
|
2686
3161
|
if (hasVsCodeSignals) {
|
|
2687
3162
|
return "copilot-vscode";
|
|
2688
3163
|
}
|
|
@@ -2814,7 +3289,11 @@ async function main(opts = {}) {
|
|
|
2814
3289
|
`[memoraone-mcp] refreshed stale cached binding ${reconciled.binding.repositoryBindingId}: project=${reconciled.binding.projectId}`
|
|
2815
3290
|
);
|
|
2816
3291
|
try {
|
|
2817
|
-
const socketPath = getBindingSocketPath(
|
|
3292
|
+
const socketPath = getBindingSocketPath(
|
|
3293
|
+
opts.daemonBindingHint,
|
|
3294
|
+
process.env,
|
|
3295
|
+
runtime.ideType ?? ""
|
|
3296
|
+
);
|
|
2818
3297
|
writeBindingSidecar(socketPath, reconciled.binding, runtime.ideType ?? "");
|
|
2819
3298
|
} catch (err) {
|
|
2820
3299
|
console.error(
|
|
@@ -3007,6 +3486,71 @@ async function main(opts = {}) {
|
|
|
3007
3486
|
}
|
|
3008
3487
|
);
|
|
3009
3488
|
registeredToolNames.push("memora_log_command");
|
|
3489
|
+
server.registerTool(
|
|
3490
|
+
"memora_list_timeline",
|
|
3491
|
+
{
|
|
3492
|
+
description: listTimelineDescription,
|
|
3493
|
+
inputSchema: listTimelineInputSchema
|
|
3494
|
+
},
|
|
3495
|
+
async (args) => runWithSessionContext(sessionContext, async () => {
|
|
3496
|
+
if (!runtime.client || !runtime.projectId) return notInitializedResult;
|
|
3497
|
+
const result = await handleListTimeline(runtime.client, args);
|
|
3498
|
+
return {
|
|
3499
|
+
content: [{ type: "text", text: JSON.stringify(result) }]
|
|
3500
|
+
};
|
|
3501
|
+
})
|
|
3502
|
+
);
|
|
3503
|
+
registeredToolNames.push("memora_list_timeline");
|
|
3504
|
+
server.registerTool(
|
|
3505
|
+
"memora_list_concepts",
|
|
3506
|
+
{
|
|
3507
|
+
description: listConceptsDescription,
|
|
3508
|
+
inputSchema: listConceptsInputSchema
|
|
3509
|
+
},
|
|
3510
|
+
async (args) => runWithSessionContext(sessionContext, async () => {
|
|
3511
|
+
if (!runtime.client || !runtime.projectId) return notInitializedResult;
|
|
3512
|
+
const result = await handleListConcepts(runtime.client, args);
|
|
3513
|
+
return {
|
|
3514
|
+
content: [{ type: "text", text: JSON.stringify(result) }]
|
|
3515
|
+
};
|
|
3516
|
+
})
|
|
3517
|
+
);
|
|
3518
|
+
registeredToolNames.push("memora_list_concepts");
|
|
3519
|
+
server.registerTool(
|
|
3520
|
+
"memora_get_concept",
|
|
3521
|
+
{
|
|
3522
|
+
description: getConceptDescription,
|
|
3523
|
+
inputSchema: getConceptInputSchema
|
|
3524
|
+
},
|
|
3525
|
+
async (args) => runWithSessionContext(sessionContext, async () => {
|
|
3526
|
+
if (!runtime.client || !runtime.projectId) return notInitializedResult;
|
|
3527
|
+
const result = await handleGetConcept(runtime.client, args);
|
|
3528
|
+
return {
|
|
3529
|
+
content: [{ type: "text", text: JSON.stringify(result) }]
|
|
3530
|
+
};
|
|
3531
|
+
})
|
|
3532
|
+
);
|
|
3533
|
+
registeredToolNames.push("memora_get_concept");
|
|
3534
|
+
server.registerTool(
|
|
3535
|
+
"memora_create_concept_version",
|
|
3536
|
+
{
|
|
3537
|
+
description: createConceptVersionDescription,
|
|
3538
|
+
inputSchema: createConceptVersionInputSchema
|
|
3539
|
+
},
|
|
3540
|
+
async (args) => runWithSessionContext(sessionContext, async () => {
|
|
3541
|
+
if (!runtime.client || !runtime.projectId) return notInitializedResult;
|
|
3542
|
+
const result = await handleCreateConceptVersion(runtime.client, args);
|
|
3543
|
+
return {
|
|
3544
|
+
content: [{ type: "text", text: JSON.stringify(result) }]
|
|
3545
|
+
};
|
|
3546
|
+
})
|
|
3547
|
+
);
|
|
3548
|
+
registeredToolNames.push("memora_create_concept_version");
|
|
3549
|
+
if (registeredToolNames.length !== LOCAL_MCP_TOOL_NAMES.length || registeredToolNames.some(
|
|
3550
|
+
(name) => !LOCAL_MCP_TOOL_NAMES.includes(name)
|
|
3551
|
+
)) {
|
|
3552
|
+
throw new Error("Local MCP tool registration inventory mismatch");
|
|
3553
|
+
}
|
|
3010
3554
|
server.server.setRequestHandler(
|
|
3011
3555
|
import_types.InitializeRequestSchema,
|
|
3012
3556
|
async (request) => runWithSessionContext(sessionContext, async () => {
|
|
@@ -3249,7 +3793,7 @@ async function runDaemon() {
|
|
|
3249
3793
|
const repositoryBindingId = parseBindingIdFromArgv();
|
|
3250
3794
|
const binding = parseBindingFromEnv(repositoryBindingId);
|
|
3251
3795
|
const ideType = parseIdeTypeFromArgv(process.argv.slice(2)) ?? config2.ideType ?? resolveIdeTypeFromEnv();
|
|
3252
|
-
const socketPath = getBindingSocketPath(binding, process.env);
|
|
3796
|
+
const socketPath = getBindingSocketPath(binding, process.env, ideType);
|
|
3253
3797
|
let nextSessionId = 1;
|
|
3254
3798
|
let activeSessions = 0;
|
|
3255
3799
|
let shuttingDown = false;
|