memorix 1.5.0 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +37 -0
- package/README.md +3 -3
- package/README.zh-CN.md +3 -3
- package/dist/cli/index.js +452 -109
- package/dist/index.js +376 -87
- package/dist/maintenance-runner.js +174 -41
- package/dist/media-audio-runner.js +174 -41
- package/dist/media-video-runner.js +174 -41
- package/dist/memcode-runtime/CHANGELOG.md +37 -0
- package/dist/sdk.js +375 -86
- package/dist/types.d.ts +2 -0
- package/dist/vector-backfill-runner.js +174 -41
- package/docs/1.2.4-PERSISTENT-MEMORY-DELIVERY.md +1 -1
- package/docs/API_REFERENCE.md +1 -1
- package/docs/DEVELOPMENT.md +5 -3
- package/package.json +1 -1
- package/plugins/claude/memorix/.claude-plugin/plugin.json +1 -1
- package/plugins/codebuddy/memorix/.codebuddy-plugin/plugin.json +1 -1
- package/plugins/codex/memorix/.codex-plugin/plugin.json +1 -1
- package/plugins/copilot/memorix/plugin.json +1 -1
- package/plugins/gemini/memorix/gemini-extension.json +1 -1
- package/plugins/omp/memorix/package.json +1 -1
- package/plugins/openclaw/memorix/.codex-plugin/plugin.json +1 -1
- package/plugins/pi/memorix/package.json +1 -1
- package/server.json +2 -2
- package/src/cli/commands/codegraph.ts +48 -5
- package/src/cli/commands/context.ts +20 -4
- package/src/cli/commands/resume.ts +4 -0
- package/src/codegraph/auto-context.ts +4 -1
- package/src/codegraph/context-pack.ts +3 -1
- package/src/codegraph/external-provider.ts +93 -0
- package/src/embedding/api-provider.ts +105 -22
- package/src/embedding/provider.ts +2 -0
- package/src/hooks/installers/index.ts +1 -1
- package/src/hooks/official-skills.ts +3 -3
- package/src/hooks/rules/memorix-agent-rules.md +1 -1
- package/src/knowledge/context-receipt.ts +41 -0
- package/src/knowledge/workflows.ts +6 -3
- package/src/knowledge/workset.ts +56 -2
- package/src/llm/provider.ts +17 -8
- package/src/memory/formation/extract.ts +6 -3
- package/src/memory/formation/index.ts +2 -1
- package/src/memory/formation/resolve.ts +10 -6
- package/src/memory/formation/types.ts +3 -1
- package/src/memory/long-term.ts +7 -1
- package/src/server.ts +29 -13
- package/src/store/orama-store.ts +6 -4
- package/src/timeout.ts +67 -0
- package/src/types.ts +2 -0
package/dist/cli/index.js
CHANGED
|
@@ -3221,7 +3221,7 @@ ${import_picocolors.default.gray(m3)} ${s4}
|
|
|
3221
3221
|
|
|
3222
3222
|
// src/cli/version.ts
|
|
3223
3223
|
function getCliVersion() {
|
|
3224
|
-
return true ? "1.
|
|
3224
|
+
return true ? "1.6.0" : pkg.version;
|
|
3225
3225
|
}
|
|
3226
3226
|
var init_version = __esm({
|
|
3227
3227
|
"src/cli/version.ts"() {
|
|
@@ -22327,6 +22327,8 @@ function getPreferredBatchSize(config2) {
|
|
|
22327
22327
|
}
|
|
22328
22328
|
function parseBatchLimit(error40) {
|
|
22329
22329
|
if (!(error40 instanceof Error)) return null;
|
|
22330
|
+
const status = error40 instanceof EmbeddingAPIError ? error40.status : Number(error40.message.match(/Embedding API error \((\d{3})\)/i)?.[1] ?? 0);
|
|
22331
|
+
if (status > 0 && status !== 400) return null;
|
|
22330
22332
|
const explicit = error40.message.match(/should not be larger than\s+(\d+)/i);
|
|
22331
22333
|
if (explicit) return parseInt(explicit[1], 10);
|
|
22332
22334
|
if (/batch size/i.test(error40.message)) {
|
|
@@ -22339,37 +22341,99 @@ async function fetchWithRetry(url2, apiKey, body, options = {}, attempt = 0, nat
|
|
|
22339
22341
|
const controller = new AbortController();
|
|
22340
22342
|
const timeoutMs = typeof options.timeoutMs === "number" && Number.isFinite(options.timeoutMs) ? Math.max(100, Math.min(Math.floor(options.timeoutMs), 6e4)) : 1e4;
|
|
22341
22343
|
const timeout = setTimeout(() => controller.abort(), timeoutMs);
|
|
22344
|
+
const signal = options.signal ? AbortSignal.any([options.signal, controller.signal]) : controller.signal;
|
|
22342
22345
|
let response;
|
|
22343
22346
|
try {
|
|
22344
22347
|
response = await fetch(url2, {
|
|
22345
22348
|
method: "POST",
|
|
22346
22349
|
headers: nativeGemini ? { "Content-Type": "application/json", "x-goog-api-key": apiKey } : { "Content-Type": "application/json", "Authorization": `Bearer ${apiKey}` },
|
|
22347
22350
|
body: JSON.stringify(body),
|
|
22348
|
-
signal
|
|
22351
|
+
signal
|
|
22349
22352
|
});
|
|
22350
22353
|
} catch (err) {
|
|
22351
22354
|
clearTimeout(timeout);
|
|
22352
|
-
if (err instanceof Error && err.name === "AbortError") {
|
|
22355
|
+
if (err instanceof Error && (err.name === "AbortError" || controller.signal.aborted || options.signal?.aborted)) {
|
|
22353
22356
|
throw new Error(`Embedding API timeout after ${timeoutMs}ms: ${url2}`);
|
|
22354
22357
|
}
|
|
22355
22358
|
throw err;
|
|
22356
22359
|
}
|
|
22357
|
-
|
|
22358
|
-
|
|
22359
|
-
|
|
22360
|
+
try {
|
|
22361
|
+
if (response.ok) {
|
|
22362
|
+
return await raceWithAbort(
|
|
22363
|
+
response.json(),
|
|
22364
|
+
signal
|
|
22365
|
+
);
|
|
22366
|
+
}
|
|
22367
|
+
if (options.retry !== false && (response.status === 429 || response.status >= 500) && attempt < MAX_RETRIES2) {
|
|
22368
|
+
const delay2 = BASE_DELAY_MS * Math.pow(2, attempt);
|
|
22369
|
+
const retryAfter = response.headers.get("retry-after");
|
|
22370
|
+
const parsedRetryAfter = retryAfter ? parseInt(retryAfter, 10) * 1e3 : NaN;
|
|
22371
|
+
const waitMs = Number.isFinite(parsedRetryAfter) ? parsedRetryAfter : delay2;
|
|
22372
|
+
console.error(`[memorix] Embedding API ${response.status}, retry ${attempt + 1}/${MAX_RETRIES2} in ${waitMs}ms`);
|
|
22373
|
+
await waitForRetry(waitMs, options.signal);
|
|
22374
|
+
return fetchWithRetry(url2, apiKey, body, options, attempt + 1, nativeGemini);
|
|
22375
|
+
}
|
|
22376
|
+
const errorText2 = await raceWithAbort(
|
|
22377
|
+
response.text().catch(() => "unknown error"),
|
|
22378
|
+
signal
|
|
22379
|
+
);
|
|
22380
|
+
throw new EmbeddingAPIError(response.status, errorText2);
|
|
22381
|
+
} catch (err) {
|
|
22382
|
+
if (err instanceof Error && (err.name === "AbortError" || controller.signal.aborted || options.signal?.aborted)) {
|
|
22383
|
+
throw new Error(`Embedding API timeout after ${timeoutMs}ms: ${url2}`);
|
|
22384
|
+
}
|
|
22385
|
+
throw err;
|
|
22386
|
+
} finally {
|
|
22387
|
+
clearTimeout(timeout);
|
|
22360
22388
|
}
|
|
22361
|
-
|
|
22362
|
-
|
|
22363
|
-
|
|
22364
|
-
|
|
22365
|
-
|
|
22389
|
+
}
|
|
22390
|
+
function abortError() {
|
|
22391
|
+
const error40 = new Error("Embedding API request aborted");
|
|
22392
|
+
error40.name = "AbortError";
|
|
22393
|
+
return error40;
|
|
22394
|
+
}
|
|
22395
|
+
function raceWithAbort(promise2, signal) {
|
|
22396
|
+
if (signal.aborted) return Promise.reject(abortError());
|
|
22397
|
+
return new Promise((resolve6, reject) => {
|
|
22398
|
+
const onAbort = () => {
|
|
22399
|
+
signal.removeEventListener("abort", onAbort);
|
|
22400
|
+
reject(abortError());
|
|
22401
|
+
};
|
|
22402
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
22403
|
+
promise2.then(
|
|
22404
|
+
(value) => {
|
|
22405
|
+
signal.removeEventListener("abort", onAbort);
|
|
22406
|
+
resolve6(value);
|
|
22407
|
+
},
|
|
22408
|
+
(error40) => {
|
|
22409
|
+
signal.removeEventListener("abort", onAbort);
|
|
22410
|
+
reject(error40);
|
|
22411
|
+
}
|
|
22412
|
+
);
|
|
22413
|
+
});
|
|
22414
|
+
}
|
|
22415
|
+
async function waitForRetry(waitMs, signal) {
|
|
22416
|
+
if (!signal) {
|
|
22366
22417
|
await new Promise((resolve6) => setTimeout(resolve6, waitMs));
|
|
22367
|
-
return
|
|
22418
|
+
return;
|
|
22368
22419
|
}
|
|
22369
|
-
const
|
|
22370
|
-
throw new Error(
|
|
22420
|
+
const abortSignal = signal;
|
|
22421
|
+
if (abortSignal.aborted) throw new Error("Embedding API retry aborted");
|
|
22422
|
+
await new Promise((resolve6, reject) => {
|
|
22423
|
+
const timer = setTimeout(done, waitMs);
|
|
22424
|
+
const onAbort = () => {
|
|
22425
|
+
clearTimeout(timer);
|
|
22426
|
+
abortSignal.removeEventListener("abort", onAbort);
|
|
22427
|
+
reject(new Error("Embedding API retry aborted"));
|
|
22428
|
+
};
|
|
22429
|
+
function done() {
|
|
22430
|
+
abortSignal.removeEventListener("abort", onAbort);
|
|
22431
|
+
resolve6();
|
|
22432
|
+
}
|
|
22433
|
+
abortSignal.addEventListener("abort", onAbort, { once: true });
|
|
22434
|
+
});
|
|
22371
22435
|
}
|
|
22372
|
-
var cache3, MAX_CACHE_SIZE3, diskCacheDirty2, diskSaveTimer, diskCacheLoaded, diskCacheLoadPromise, MAX_INPUT_CHARS, MAX_CONCURRENCY, DISK_SAVE_DEBOUNCE_MS, DEFAULT_MAX_BATCH_SIZE, DASHSCOPE_MAX_BATCH_SIZE, MAX_RETRIES2, BASE_DELAY_MS, APIEmbeddingProvider;
|
|
22436
|
+
var cache3, MAX_CACHE_SIZE3, diskCacheDirty2, diskSaveTimer, diskCacheLoaded, diskCacheLoadPromise, MAX_INPUT_CHARS, MAX_CONCURRENCY, DISK_SAVE_DEBOUNCE_MS, DEFAULT_MAX_BATCH_SIZE, DASHSCOPE_MAX_BATCH_SIZE, MAX_RETRIES2, BASE_DELAY_MS, EmbeddingAPIError, APIEmbeddingProvider;
|
|
22373
22437
|
var init_api_provider = __esm({
|
|
22374
22438
|
"src/embedding/api-provider.ts"() {
|
|
22375
22439
|
"use strict";
|
|
@@ -22388,6 +22452,14 @@ var init_api_provider = __esm({
|
|
|
22388
22452
|
DASHSCOPE_MAX_BATCH_SIZE = 10;
|
|
22389
22453
|
MAX_RETRIES2 = 3;
|
|
22390
22454
|
BASE_DELAY_MS = 500;
|
|
22455
|
+
EmbeddingAPIError = class extends Error {
|
|
22456
|
+
status;
|
|
22457
|
+
constructor(status, detail) {
|
|
22458
|
+
super(`Embedding API error (${status}): ${detail}`);
|
|
22459
|
+
this.name = "EmbeddingAPIError";
|
|
22460
|
+
this.status = status;
|
|
22461
|
+
}
|
|
22462
|
+
};
|
|
22391
22463
|
APIEmbeddingProvider = class _APIEmbeddingProvider {
|
|
22392
22464
|
name;
|
|
22393
22465
|
dimensions;
|
|
@@ -22599,15 +22671,14 @@ var init_api_provider = __esm({
|
|
|
22599
22671
|
}
|
|
22600
22672
|
} catch (error40) {
|
|
22601
22673
|
const providerLimit = parseBatchLimit(error40);
|
|
22602
|
-
|
|
22603
|
-
if (chunkTexts.length > 1 && fallbackSize < chunkTexts.length) {
|
|
22674
|
+
if (providerLimit !== null && chunkTexts.length > 1 && providerLimit < chunkTexts.length) {
|
|
22604
22675
|
console.error(
|
|
22605
|
-
`[memorix] Embedding batch too large for provider, retrying in chunks of ${
|
|
22676
|
+
`[memorix] Embedding batch too large for provider, retrying in chunks of ${providerLimit}`
|
|
22606
22677
|
);
|
|
22607
|
-
for (let start = 0; start < chunkTexts.length; start +=
|
|
22678
|
+
for (let start = 0; start < chunkTexts.length; start += providerLimit) {
|
|
22608
22679
|
await processChunk(
|
|
22609
|
-
chunkTexts.slice(start, start +
|
|
22610
|
-
chunkIndices.slice(start, start +
|
|
22680
|
+
chunkTexts.slice(start, start + providerLimit),
|
|
22681
|
+
chunkIndices.slice(start, start + providerLimit)
|
|
22611
22682
|
);
|
|
22612
22683
|
}
|
|
22613
22684
|
return;
|
|
@@ -23471,22 +23542,23 @@ function getLLMConfig() {
|
|
|
23471
23542
|
function setLLMConfig(config2) {
|
|
23472
23543
|
currentConfig = config2;
|
|
23473
23544
|
}
|
|
23474
|
-
async function callLLM(systemPrompt, userMessage) {
|
|
23545
|
+
async function callLLM(systemPrompt, userMessage, signal) {
|
|
23475
23546
|
if (!currentConfig) {
|
|
23476
23547
|
throw new Error("LLM not configured. Set MEMORIX_LLM_API_KEY or OPENAI_API_KEY.");
|
|
23477
23548
|
}
|
|
23478
23549
|
if (currentConfig.provider === "anthropic") {
|
|
23479
|
-
return callAnthropic(systemPrompt, userMessage);
|
|
23550
|
+
return callAnthropic(systemPrompt, userMessage, signal);
|
|
23480
23551
|
}
|
|
23481
|
-
return callOpenAICompatible(systemPrompt, userMessage);
|
|
23552
|
+
return callOpenAICompatible(systemPrompt, userMessage, signal);
|
|
23482
23553
|
}
|
|
23483
|
-
async function callOpenAICompatible(systemPrompt, userMessage) {
|
|
23554
|
+
async function callOpenAICompatible(systemPrompt, userMessage, signal) {
|
|
23484
23555
|
const config2 = currentConfig;
|
|
23485
23556
|
let base = config2.baseUrl.replace(/\/+$/, "");
|
|
23486
23557
|
if (!base.endsWith("/v1")) base += "/v1";
|
|
23487
23558
|
const url2 = `${base}/chat/completions`;
|
|
23559
|
+
const fetchSignal = signal ? AbortSignal.any([signal, AbortSignal.timeout(LLM_CALL_TIMEOUT_MS)]) : AbortSignal.timeout(LLM_CALL_TIMEOUT_MS);
|
|
23488
23560
|
const response = await fetch(url2, {
|
|
23489
|
-
signal:
|
|
23561
|
+
signal: fetchSignal,
|
|
23490
23562
|
method: "POST",
|
|
23491
23563
|
headers: {
|
|
23492
23564
|
"Content-Type": "application/json",
|
|
@@ -23503,10 +23575,10 @@ async function callOpenAICompatible(systemPrompt, userMessage) {
|
|
|
23503
23575
|
})
|
|
23504
23576
|
});
|
|
23505
23577
|
if (!response.ok) {
|
|
23506
|
-
const error40 = await readResponseText(response,
|
|
23578
|
+
const error40 = await readResponseText(response, signal, 64 * 1024).catch(() => "unknown error");
|
|
23507
23579
|
throw new Error(`LLM API error (${response.status}): ${error40}`);
|
|
23508
23580
|
}
|
|
23509
|
-
const data = await readResponseJson(response);
|
|
23581
|
+
const data = await readResponseJson(response, signal);
|
|
23510
23582
|
return {
|
|
23511
23583
|
content: data.choices[0]?.message?.content ?? "",
|
|
23512
23584
|
usage: data.usage ? {
|
|
@@ -23515,11 +23587,12 @@ async function callOpenAICompatible(systemPrompt, userMessage) {
|
|
|
23515
23587
|
} : void 0
|
|
23516
23588
|
};
|
|
23517
23589
|
}
|
|
23518
|
-
async function callAnthropic(systemPrompt, userMessage) {
|
|
23590
|
+
async function callAnthropic(systemPrompt, userMessage, signal) {
|
|
23519
23591
|
const config2 = currentConfig;
|
|
23520
23592
|
const url2 = `${config2.baseUrl}/messages`;
|
|
23593
|
+
const fetchSignal = signal ? AbortSignal.any([signal, AbortSignal.timeout(LLM_CALL_TIMEOUT_MS)]) : AbortSignal.timeout(LLM_CALL_TIMEOUT_MS);
|
|
23521
23594
|
const response = await fetch(url2, {
|
|
23522
|
-
signal:
|
|
23595
|
+
signal: fetchSignal,
|
|
23523
23596
|
method: "POST",
|
|
23524
23597
|
headers: {
|
|
23525
23598
|
"Content-Type": "application/json",
|
|
@@ -23537,10 +23610,10 @@ async function callAnthropic(systemPrompt, userMessage) {
|
|
|
23537
23610
|
})
|
|
23538
23611
|
});
|
|
23539
23612
|
if (!response.ok) {
|
|
23540
|
-
const error40 = await readResponseText(response,
|
|
23613
|
+
const error40 = await readResponseText(response, signal, 64 * 1024).catch(() => "unknown error");
|
|
23541
23614
|
throw new Error(`Anthropic API error (${response.status}): ${error40}`);
|
|
23542
23615
|
}
|
|
23543
|
-
const data = await readResponseJson(response);
|
|
23616
|
+
const data = await readResponseJson(response, signal);
|
|
23544
23617
|
return {
|
|
23545
23618
|
content: data.content[0]?.text ?? "",
|
|
23546
23619
|
usage: data.usage ? {
|
|
@@ -24045,6 +24118,57 @@ function withTimeout(promise2, ms2, label) {
|
|
|
24045
24118
|
);
|
|
24046
24119
|
});
|
|
24047
24120
|
}
|
|
24121
|
+
function withTimeoutSignal(operation, ms2, label, parentSignal) {
|
|
24122
|
+
const controller = new AbortController();
|
|
24123
|
+
const signal = parentSignal ? AbortSignal.any([parentSignal, controller.signal]) : controller.signal;
|
|
24124
|
+
return new Promise((resolve6, reject) => {
|
|
24125
|
+
let settled = false;
|
|
24126
|
+
let timedOut = false;
|
|
24127
|
+
let timer;
|
|
24128
|
+
const cleanup = () => {
|
|
24129
|
+
if (timer !== void 0) clearTimeout(timer);
|
|
24130
|
+
parentSignal?.removeEventListener("abort", onParentAbort);
|
|
24131
|
+
};
|
|
24132
|
+
const onParentAbort = () => {
|
|
24133
|
+
if (settled || timedOut) return;
|
|
24134
|
+
settled = true;
|
|
24135
|
+
cleanup();
|
|
24136
|
+
reject(parentSignal?.reason ?? new Error(`${label} aborted`));
|
|
24137
|
+
};
|
|
24138
|
+
parentSignal?.addEventListener("abort", onParentAbort, { once: true });
|
|
24139
|
+
timer = setTimeout(() => {
|
|
24140
|
+
if (settled) return;
|
|
24141
|
+
timedOut = true;
|
|
24142
|
+
controller.abort(new Error(`${label} timed out after ${ms2}ms`));
|
|
24143
|
+
settled = true;
|
|
24144
|
+
cleanup();
|
|
24145
|
+
reject(new Error(`${label} timed out after ${ms2}ms`));
|
|
24146
|
+
}, ms2);
|
|
24147
|
+
let pending;
|
|
24148
|
+
try {
|
|
24149
|
+
pending = operation(signal);
|
|
24150
|
+
} catch (error40) {
|
|
24151
|
+
settled = true;
|
|
24152
|
+
cleanup();
|
|
24153
|
+
reject(error40);
|
|
24154
|
+
return;
|
|
24155
|
+
}
|
|
24156
|
+
pending.then(
|
|
24157
|
+
(value) => {
|
|
24158
|
+
if (settled) return;
|
|
24159
|
+
settled = true;
|
|
24160
|
+
cleanup();
|
|
24161
|
+
resolve6(value);
|
|
24162
|
+
},
|
|
24163
|
+
(error40) => {
|
|
24164
|
+
if (settled) return;
|
|
24165
|
+
settled = true;
|
|
24166
|
+
cleanup();
|
|
24167
|
+
reject(timedOut ? new Error(`${label} timed out after ${ms2}ms`) : error40);
|
|
24168
|
+
}
|
|
24169
|
+
);
|
|
24170
|
+
});
|
|
24171
|
+
}
|
|
24048
24172
|
var init_timeout = __esm({
|
|
24049
24173
|
"src/timeout.ts"() {
|
|
24050
24174
|
"use strict";
|
|
@@ -178220,7 +178344,13 @@ async function maintainLongTermMemories(input) {
|
|
|
178220
178344
|
}
|
|
178221
178345
|
for (const group of groups.values()) {
|
|
178222
178346
|
if (group.length < 2) continue;
|
|
178223
|
-
group.sort((a4, b4) =>
|
|
178347
|
+
group.sort((a4, b4) => {
|
|
178348
|
+
const byCreatedAt = Date.parse(b4.createdAt) - Date.parse(a4.createdAt);
|
|
178349
|
+
if (byCreatedAt !== 0) return byCreatedAt;
|
|
178350
|
+
const byUpdatedAt = Date.parse(b4.updatedAt) - Date.parse(a4.updatedAt);
|
|
178351
|
+
if (byUpdatedAt !== 0) return byUpdatedAt;
|
|
178352
|
+
return b4.id.localeCompare(a4.id);
|
|
178353
|
+
});
|
|
178224
178354
|
const newest = group[0];
|
|
178225
178355
|
for (const older of group.slice(1)) {
|
|
178226
178356
|
try {
|
|
@@ -181948,6 +182078,7 @@ var init_task_lens = __esm({
|
|
|
181948
182078
|
var workflows_exports = {};
|
|
181949
182079
|
__export(workflows_exports, {
|
|
181950
182080
|
WORKFLOW_ADAPTER_TARGETS: () => WORKFLOW_ADAPTER_TARGETS,
|
|
182081
|
+
WORKFLOW_AGENT_TARGETS: () => WORKFLOW_AGENT_TARGETS,
|
|
181951
182082
|
applyWorkflowAdapter: () => applyWorkflowAdapter,
|
|
181952
182083
|
importWindsurfWorkflows: () => importWindsurfWorkflows,
|
|
181953
182084
|
parseWorkflowMarkdown: () => parseWorkflowMarkdown,
|
|
@@ -182013,7 +182144,7 @@ function optionalStatus(data) {
|
|
|
182013
182144
|
return value;
|
|
182014
182145
|
}
|
|
182015
182146
|
function normalizeAgents(values) {
|
|
182016
|
-
const unknown2 = values.filter((value) => !
|
|
182147
|
+
const unknown2 = values.filter((value) => !WORKFLOW_AGENT_TARGETS.includes(value));
|
|
182017
182148
|
if (unknown2.length > 0) {
|
|
182018
182149
|
throw new Error("workflow frontmatter has unsupported agent: " + unknown2[0]);
|
|
182019
182150
|
}
|
|
@@ -182289,7 +182420,7 @@ function taskScore(workflow, task) {
|
|
|
182289
182420
|
return { score, reasons: [...new Set(reasons)] };
|
|
182290
182421
|
}
|
|
182291
182422
|
function selectWorkflows(input) {
|
|
182292
|
-
const selected = input.workflows.filter((workflow) => workflow.status === "active").map((workflow) => {
|
|
182423
|
+
const selected = input.workflows.filter((workflow) => workflow.status === "active" && (!input.agent || workflow.compatibleAgents.includes(input.agent))).map((workflow) => {
|
|
182293
182424
|
const match2 = taskScore(workflow, input.task);
|
|
182294
182425
|
const cautions = input.store && input.projectId ? input.store.recentFailureCautions(input.projectId, workflow.id) : [];
|
|
182295
182426
|
return {
|
|
@@ -182569,7 +182700,7 @@ async function selectWorkspaceWorkflows(input) {
|
|
|
182569
182700
|
errors: synced.errors
|
|
182570
182701
|
};
|
|
182571
182702
|
}
|
|
182572
|
-
var
|
|
182703
|
+
var WORKFLOW_AGENT_TARGETS, WORKFLOW_ADAPTER_TARGETS, STATUS_VALUES, LENS_TERMS, GENERIC_WORKFLOW_LENSES, GENERIC_WORKFLOW_TERMS;
|
|
182573
182704
|
var init_workflows2 = __esm({
|
|
182574
182705
|
"src/knowledge/workflows.ts"() {
|
|
182575
182706
|
"use strict";
|
|
@@ -182581,7 +182712,7 @@ var init_workflows2 = __esm({
|
|
|
182581
182712
|
init_workflow_store();
|
|
182582
182713
|
init_outcome_store();
|
|
182583
182714
|
init_task_lens();
|
|
182584
|
-
|
|
182715
|
+
WORKFLOW_AGENT_TARGETS = [
|
|
182585
182716
|
"windsurf",
|
|
182586
182717
|
"cursor",
|
|
182587
182718
|
"claude-code",
|
|
@@ -184736,16 +184867,18 @@ async function searchObservations(options) {
|
|
|
184736
184867
|
);
|
|
184737
184868
|
} else {
|
|
184738
184869
|
const EMBEDDING_TIMEOUT_MS = 15e3;
|
|
184739
|
-
queryVector = await
|
|
184740
|
-
provider2.embedInput ? provider2.embedInput(
|
|
184870
|
+
queryVector = await withTimeoutSignal(
|
|
184871
|
+
(signal) => provider2.embedInput ? provider2.embedInput(
|
|
184741
184872
|
{ modality: "text", text: expandedEmbeddingQuery },
|
|
184742
|
-
{ intent: "query", timeoutMs: EMBEDDING_TIMEOUT_MS, retry: false }
|
|
184873
|
+
{ intent: "query", timeoutMs: EMBEDDING_TIMEOUT_MS, retry: false, signal }
|
|
184743
184874
|
) : provider2.embed(expandedEmbeddingQuery, {
|
|
184744
184875
|
timeoutMs: EMBEDDING_TIMEOUT_MS,
|
|
184745
|
-
retry: false
|
|
184876
|
+
retry: false,
|
|
184877
|
+
signal
|
|
184746
184878
|
}),
|
|
184747
184879
|
EMBEDDING_TIMEOUT_MS,
|
|
184748
|
-
"Embedding"
|
|
184880
|
+
"Embedding",
|
|
184881
|
+
options.signal
|
|
184749
184882
|
);
|
|
184750
184883
|
mark("embedding");
|
|
184751
184884
|
const cjkRatio = (originalQuery.match(/[\u4e00-\u9fff\u3040-\u309f\u30a0-\u30ff\uac00-\ud7af]/g) || []).length / originalQuery.length;
|
|
@@ -190999,8 +191132,8 @@ var init_official_skills = __esm({
|
|
|
190999
191132
|
"",
|
|
191000
191133
|
"| Situation | Prefer | CLI fallback |",
|
|
191001
191134
|
"|---|---|---|",
|
|
191002
|
-
'| Starting a coding task and needing the best task-lensed project map | `memorix_project_context` with the user\'s task | `memorix context "<task>" --json` |',
|
|
191003
|
-
'| Continuing prior project work | `memorix_project_context` with the user\'s task | `memorix resume "<task>" --json` |',
|
|
191135
|
+
'| Starting a coding task and needing the best task-lensed project map | `memorix_project_context` with the user\'s task | `memorix context "<task>" --brief-json` |',
|
|
191136
|
+
'| Continuing prior project work | `memorix_project_context` with the user\'s task | `memorix resume "<task>" --brief-json` |',
|
|
191004
191137
|
'| Need structured refs/freshness for code-bound memories | `memorix_context_pack` | `memorix codegraph context-pack --task "<topic>"` |',
|
|
191005
191138
|
'| Explicit memory graph question | `memorix_graph_context` | `memorix memory graph-context --query "<topic>"` |',
|
|
191006
191139
|
'| Specific past decision, bug, file, or change | `memorix_search` | `memorix memory search --query "<topic>"` |',
|
|
@@ -191013,7 +191146,7 @@ var init_official_skills = __esm({
|
|
|
191013
191146
|
"",
|
|
191014
191147
|
"- 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.",
|
|
191015
191148
|
"- 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.",
|
|
191016
|
-
'- Continuation fallback is mandatory: when the user asks to continue, resume, take over, or explain prior work and MCP cannot be called in this turn, run `memorix resume "<task>" --json` exactly once before inspecting files, Git history, progress notes, or guessing. The absence of `.memorix` or visible memory files never proves project memory is empty. For a new task, use `memorix context "<task>" --json` instead. If that one command fails, report it and proceed normally; do not probe help, enumerate commands, or chain broad searches.',
|
|
191149
|
+
'- Continuation fallback is mandatory: when the user asks to continue, resume, take over, or explain prior work and MCP cannot be called in this turn, run `memorix resume "<task>" --brief-json` exactly once before inspecting files, Git history, progress notes, or guessing. The absence of `.memorix` or visible memory files never proves project memory is empty. For a new task, use `memorix context "<task>" --brief-json` instead. Use `--json` only when a diagnostic needs the detailed legacy payload. If that one command fails, report it and proceed normally; do not probe help, enumerate commands, or chain broad searches.',
|
|
191017
191150
|
"- After a successful `memorix_project_context`, the brief is the default retrieval boundary. Do not call more Memorix retrieval tools after a complete brief. Use Context Pack, search, or detail only when the brief lacks a specific reference, freshness field, or fact needed for the task, or when the user explicitly asks for deeper history. In MCP, name that missing fact in `purpose` when intentionally expanding beyond the brief. Do not retrieve the same decision twice just to confirm an already-complete brief.",
|
|
191018
191151
|
"- If the user asks for read-only work or says not to modify files, do not call `memorix_store` just to record an assessment. Store only when the user explicitly asks to preserve it.",
|
|
191019
191152
|
"- Use `memorix_search` for a specific decision, bug, file, or prior change that the project context did not answer. Fetch detail only for a result you still need after the brief.",
|
|
@@ -192272,7 +192405,7 @@ alwaysApply: true
|
|
|
192272
192405
|
"",
|
|
192273
192406
|
`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). When the task is continuing prior work, the same brief also includes a bounded prior-work projection. Treat its "Start here" files as the first ${contextNoun} files to inspect.`,
|
|
192274
192407
|
"",
|
|
192275
|
-
'If the MCP tool is not visible yet but the client supports tool discovery or dynamic loading, search/select `memorix_project_context` first. Continuation fallback is mandatory: when the user asks to continue, resume, take over, or explain prior work and MCP cannot be called in this turn, run exactly one CLI brief with the user\'s real task before inspecting files, Git history, progress notes, or guessing: `memorix resume "<task>" --json`. For a new task, use `memorix context "<task>" --json` instead. The absence of `.memorix` or visible memory files never proves project memory is empty. If that one command fails, report it and proceed normally. Do not probe help, enumerate commands, chain broad searches, wait indefinitely on MCP startup, or hand-write tool-call syntax.',
|
|
192408
|
+
'If the MCP tool is not visible yet but the client supports tool discovery or dynamic loading, search/select `memorix_project_context` first. Continuation fallback is mandatory: when the user asks to continue, resume, take over, or explain prior work and MCP cannot be called in this turn, run exactly one CLI brief with the user\'s real task before inspecting files, Git history, progress notes, or guessing: `memorix resume "<task>" --brief-json`. For a new task, use `memorix context "<task>" --brief-json` instead. The absence of `.memorix` or visible memory files never proves project memory is empty. Use `--json` only when a diagnostic needs the detailed legacy payload. If that one command fails, report it and proceed normally. Do not probe help, enumerate commands, chain broad searches, wait indefinitely on MCP startup, or hand-write tool-call syntax.',
|
|
192276
192409
|
"",
|
|
192277
192410
|
"After a successful `memorix_project_context` result, the brief is the default retrieval boundary. Do not call more Memorix retrieval tools after a complete brief. Use `memorix_context_pack`, `memorix_search`, or `memorix_detail` only when the brief lacks a specific reference, freshness field, or fact needed for the task, or when the user explicitly asks for deeper history. In MCP, name that missing fact in `purpose` when intentionally expanding beyond the brief. Do not retrieve the same decision twice just to confirm an already-complete brief.",
|
|
192278
192411
|
"If the user asks for read-only work or says not to modify files, do not call `memorix_store` just to record an assessment. Store only when the user explicitly asks to preserve it.",
|
|
@@ -194314,6 +194447,15 @@ function workflowOutput(selection) {
|
|
|
194314
194447
|
cautions: selection.cautions.map((caution) => short(caution, 22))
|
|
194315
194448
|
};
|
|
194316
194449
|
}
|
|
194450
|
+
function workflowLoadout(agent, selections) {
|
|
194451
|
+
if (!agent) return void 0;
|
|
194452
|
+
return {
|
|
194453
|
+
agent,
|
|
194454
|
+
workflowIds: selections.map((selection) => selection.workflow.id),
|
|
194455
|
+
requiredContext: unique(selections.flatMap((selection) => selection.workflow.requiredContext)).map((item) => short(item, 18)).slice(0, 4),
|
|
194456
|
+
allowedTools: unique(selections.flatMap((selection) => selection.workflow.allowedTools)).map((item) => short(item, 12)).slice(0, 6)
|
|
194457
|
+
};
|
|
194458
|
+
}
|
|
194317
194459
|
function appendLine(lines, candidate2, maxTokens, omitted, omittedKind, selected, receiptSelection) {
|
|
194318
194460
|
const next = lines.length ? lines.join("\n") + "\n" + candidate2 : candidate2;
|
|
194319
194461
|
if (countTextTokens(next) <= maxTokens) {
|
|
@@ -194774,6 +194916,22 @@ function renderTaskWorksetPrompt(input) {
|
|
|
194774
194916
|
);
|
|
194775
194917
|
}
|
|
194776
194918
|
}
|
|
194919
|
+
if (input.agentLoadout) {
|
|
194920
|
+
appendLine(lines, "", maxTokens, omitted, "agent-loadout-heading");
|
|
194921
|
+
appendLine(lines, "Agent loadout (" + input.agentLoadout.agent + ")", maxTokens, omitted, "agent-loadout-heading");
|
|
194922
|
+
for (const required2 of input.agentLoadout.requiredContext.slice(0, 2)) {
|
|
194923
|
+
appendLine(lines, "- Need: " + required2, maxTokens, omitted, "agent-loadout-context");
|
|
194924
|
+
}
|
|
194925
|
+
if (input.agentLoadout.allowedTools.length > 0) {
|
|
194926
|
+
appendLine(
|
|
194927
|
+
lines,
|
|
194928
|
+
"- Workflow tools: " + input.agentLoadout.allowedTools.join(", "),
|
|
194929
|
+
maxTokens,
|
|
194930
|
+
omitted,
|
|
194931
|
+
"agent-loadout-tools"
|
|
194932
|
+
);
|
|
194933
|
+
}
|
|
194934
|
+
}
|
|
194777
194935
|
if (input.verification.length > 0) {
|
|
194778
194936
|
appendLine(lines, "", maxTokens, omitted, "verification-heading");
|
|
194779
194937
|
appendLine(lines, "Verify", maxTokens, omitted, "verification-heading");
|
|
@@ -194865,6 +195023,7 @@ async function buildTaskWorkset(input) {
|
|
|
194865
195023
|
let workspace;
|
|
194866
195024
|
let pages = [];
|
|
194867
195025
|
let workflows = [];
|
|
195026
|
+
let workflowSelections = [];
|
|
194868
195027
|
try {
|
|
194869
195028
|
workspace = await preferredWorkspace(input.projectId, input.dataDir);
|
|
194870
195029
|
if (workspace) {
|
|
@@ -194881,14 +195040,15 @@ async function buildTaskWorkset(input) {
|
|
|
194881
195040
|
if (task) {
|
|
194882
195041
|
const workflowStore = new WorkflowStore();
|
|
194883
195042
|
await workflowStore.init(input.dataDir);
|
|
194884
|
-
|
|
195043
|
+
workflowSelections = selectWorkflows({
|
|
194885
195044
|
workflows: workflowStore.listWorkflows(workspace.id, "active"),
|
|
194886
195045
|
task,
|
|
194887
195046
|
projectId: input.projectId,
|
|
194888
195047
|
store: workflowStore,
|
|
195048
|
+
...input.agent ? { agent: input.agent } : {},
|
|
194889
195049
|
limit: 2
|
|
194890
195050
|
});
|
|
194891
|
-
workflows =
|
|
195051
|
+
workflows = workflowSelections.map(workflowOutput);
|
|
194892
195052
|
for (const workflow of workflows) {
|
|
194893
195053
|
for (const caution of workflow.cautions) {
|
|
194894
195054
|
cautions.push({ kind: "workflow-failed-verification", message: caution });
|
|
@@ -194910,6 +195070,10 @@ async function buildTaskWorkset(input) {
|
|
|
194910
195070
|
workflows
|
|
194911
195071
|
});
|
|
194912
195072
|
const governedDurableIds = new Set(governed.durableMemory.map((memory) => memory.id));
|
|
195073
|
+
const agentLoadout = workflowLoadout(
|
|
195074
|
+
input.agent,
|
|
195075
|
+
workflowSelections.filter((selection2) => governed.workflows.some((workflow) => workflow.id === selection2.workflow.id))
|
|
195076
|
+
);
|
|
194913
195077
|
const evidenceIds = unique(governed.claims.flatMap((claim) => evidenceIdsForClaim(
|
|
194914
195078
|
claim,
|
|
194915
195079
|
evidenceByClaim.get(claim.id) ?? []
|
|
@@ -194954,6 +195118,7 @@ async function buildTaskWorkset(input) {
|
|
|
194954
195118
|
pages: pages.filter((page) => page.claimIds.some((claimId) => governed.claims.some((claim) => claim.id === claimId))),
|
|
194955
195119
|
durableMemory: governed.durableMemory,
|
|
194956
195120
|
workflows: governed.workflows,
|
|
195121
|
+
...agentLoadout ? { agentLoadout } : {},
|
|
194957
195122
|
cautions: normalizedCautions,
|
|
194958
195123
|
verification,
|
|
194959
195124
|
evidenceIds,
|
|
@@ -195172,10 +195337,12 @@ var init_current_facts = __esm({
|
|
|
195172
195337
|
var external_provider_exports = {};
|
|
195173
195338
|
__export(external_provider_exports, {
|
|
195174
195339
|
DEFAULT_EXTERNAL_CODEGRAPH_TIMEOUT_MS: () => DEFAULT_EXTERNAL_CODEGRAPH_TIMEOUT_MS,
|
|
195340
|
+
EXTERNAL_CODEGRAPH_LIFECYCLE_TIMEOUT_MS: () => EXTERNAL_CODEGRAPH_LIFECYCLE_TIMEOUT_MS,
|
|
195175
195341
|
MAX_EXTERNAL_CODEGRAPH_OUTPUT_BYTES: () => MAX_EXTERNAL_CODEGRAPH_OUTPUT_BYTES,
|
|
195176
195342
|
MAX_EXTERNAL_CODEGRAPH_TIMEOUT_MS: () => MAX_EXTERNAL_CODEGRAPH_TIMEOUT_MS,
|
|
195177
195343
|
getExternalCodeGraphContext: () => getExternalCodeGraphContext,
|
|
195178
|
-
inspectExternalCodeGraph: () => inspectExternalCodeGraph
|
|
195344
|
+
inspectExternalCodeGraph: () => inspectExternalCodeGraph,
|
|
195345
|
+
runExternalCodeGraphLifecycle: () => runExternalCodeGraphLifecycle
|
|
195179
195346
|
});
|
|
195180
195347
|
import { spawn as spawn5 } from "child_process";
|
|
195181
195348
|
import { existsSync as existsSync16, readFileSync as readFileSync9 } from "fs";
|
|
@@ -195374,6 +195541,66 @@ async function inspectExternalCodeGraph(input) {
|
|
|
195374
195541
|
const health = healthFromStatus(status);
|
|
195375
195542
|
return { health, quality: providerQuality({ mode, health }) };
|
|
195376
195543
|
}
|
|
195544
|
+
async function runExternalCodeGraphLifecycle(input) {
|
|
195545
|
+
const mode = input.mode ?? "auto";
|
|
195546
|
+
if (mode === "off") {
|
|
195547
|
+
const health = { state: "disabled", reason: "External CodeGraph is disabled by configuration." };
|
|
195548
|
+
return {
|
|
195549
|
+
action: input.action,
|
|
195550
|
+
performed: false,
|
|
195551
|
+
message: "External CodeGraph is disabled by configuration.",
|
|
195552
|
+
health,
|
|
195553
|
+
quality: providerQuality({ mode, health })
|
|
195554
|
+
};
|
|
195555
|
+
}
|
|
195556
|
+
const indexPath = join23(input.projectRoot, ".codegraph");
|
|
195557
|
+
if (input.action === "sync" && !existsSync16(indexPath)) {
|
|
195558
|
+
const health = { state: "not-detected", reason: "No local .codegraph index is present for this project." };
|
|
195559
|
+
return {
|
|
195560
|
+
action: input.action,
|
|
195561
|
+
performed: false,
|
|
195562
|
+
message: 'Initialize CodeGraph first with "memorix codegraph init".',
|
|
195563
|
+
health,
|
|
195564
|
+
quality: providerQuality({ mode, health })
|
|
195565
|
+
};
|
|
195566
|
+
}
|
|
195567
|
+
if (input.action === "init" && existsSync16(indexPath)) {
|
|
195568
|
+
const inspected2 = await inspectExternalCodeGraph(input);
|
|
195569
|
+
return {
|
|
195570
|
+
action: input.action,
|
|
195571
|
+
performed: false,
|
|
195572
|
+
message: "A local CodeGraph directory already exists; no initialization was performed.",
|
|
195573
|
+
...inspected2
|
|
195574
|
+
};
|
|
195575
|
+
}
|
|
195576
|
+
const result = await runSafely(input.runner ?? defaultRunner, {
|
|
195577
|
+
command: input.command,
|
|
195578
|
+
args: input.action === "init" ? ["init", input.projectRoot] : ["sync", input.projectRoot, "--quiet"],
|
|
195579
|
+
cwd: input.projectRoot,
|
|
195580
|
+
// A context read must stay fast; an explicit user-requested index sync is
|
|
195581
|
+
// a different operation and gets its own bounded maintenance window.
|
|
195582
|
+
timeoutMs: EXTERNAL_CODEGRAPH_LIFECYCLE_TIMEOUT_MS,
|
|
195583
|
+
maxOutputBytes: MAX_EXTERNAL_CODEGRAPH_OUTPUT_BYTES
|
|
195584
|
+
});
|
|
195585
|
+
if (!result.ok) {
|
|
195586
|
+
const health = unavailableHealth(result);
|
|
195587
|
+
return {
|
|
195588
|
+
action: input.action,
|
|
195589
|
+
performed: false,
|
|
195590
|
+
message: "CodeGraph " + input.action + " did not complete: " + (health.reason ?? "unknown local error"),
|
|
195591
|
+
health,
|
|
195592
|
+
quality: providerQuality({ mode, health })
|
|
195593
|
+
};
|
|
195594
|
+
}
|
|
195595
|
+
const inspected = await inspectExternalCodeGraph(input);
|
|
195596
|
+
const remainsStale = inspected.health.state === "stale";
|
|
195597
|
+
return {
|
|
195598
|
+
action: input.action,
|
|
195599
|
+
performed: true,
|
|
195600
|
+
message: input.action === "init" ? 'Local CodeGraph initialization completed. Run "memorix codegraph sync" when source changes.' : remainsStale ? "Local CodeGraph synchronization completed, but the graph remains stale against the current worktree; this task will use Lite evidence." : "Local CodeGraph synchronization completed and is ready for task-scoped semantic context.",
|
|
195601
|
+
...inspected
|
|
195602
|
+
};
|
|
195603
|
+
}
|
|
195377
195604
|
function safeRelativePath(projectRoot, value, exclude) {
|
|
195378
195605
|
const path47 = safeText(value, 1024);
|
|
195379
195606
|
if (!path47 || isAbsolute2(path47)) return void 0;
|
|
@@ -195499,7 +195726,7 @@ async function getExternalCodeGraphContext(input) {
|
|
|
195499
195726
|
quality: providerQuality({ mode, health: inspected.health, ...contributes ? { selected: "external" } : {} })
|
|
195500
195727
|
};
|
|
195501
195728
|
}
|
|
195502
|
-
var DEFAULT_EXTERNAL_CODEGRAPH_TIMEOUT_MS, MAX_EXTERNAL_CODEGRAPH_TIMEOUT_MS, MAX_EXTERNAL_CODEGRAPH_OUTPUT_BYTES, MAX_EXTERNAL_NODE_COUNT, MAX_EXTERNAL_EDGE_COUNT, MAX_EXTERNAL_FILE_COUNT, MAX_EXTERNAL_TEXT_LENGTH, LITE_SUPPORTED_LANGUAGES, defaultRunner;
|
|
195729
|
+
var DEFAULT_EXTERNAL_CODEGRAPH_TIMEOUT_MS, MAX_EXTERNAL_CODEGRAPH_TIMEOUT_MS, EXTERNAL_CODEGRAPH_LIFECYCLE_TIMEOUT_MS, MAX_EXTERNAL_CODEGRAPH_OUTPUT_BYTES, MAX_EXTERNAL_NODE_COUNT, MAX_EXTERNAL_EDGE_COUNT, MAX_EXTERNAL_FILE_COUNT, MAX_EXTERNAL_TEXT_LENGTH, LITE_SUPPORTED_LANGUAGES, defaultRunner;
|
|
195503
195730
|
var init_external_provider = __esm({
|
|
195504
195731
|
"src/codegraph/external-provider.ts"() {
|
|
195505
195732
|
"use strict";
|
|
@@ -195509,6 +195736,7 @@ var init_external_provider = __esm({
|
|
|
195509
195736
|
init_ids();
|
|
195510
195737
|
DEFAULT_EXTERNAL_CODEGRAPH_TIMEOUT_MS = 1200;
|
|
195511
195738
|
MAX_EXTERNAL_CODEGRAPH_TIMEOUT_MS = 5e3;
|
|
195739
|
+
EXTERNAL_CODEGRAPH_LIFECYCLE_TIMEOUT_MS = 3e4;
|
|
195512
195740
|
MAX_EXTERNAL_CODEGRAPH_OUTPUT_BYTES = 256 * 1024;
|
|
195513
195741
|
MAX_EXTERNAL_NODE_COUNT = 16;
|
|
195514
195742
|
MAX_EXTERNAL_EDGE_COUNT = 24;
|
|
@@ -197231,6 +197459,7 @@ async function buildAutoProjectContext(input) {
|
|
|
197231
197459
|
projectId: input.project.id,
|
|
197232
197460
|
dataDir: input.dataDir,
|
|
197233
197461
|
...task ? { task } : {},
|
|
197462
|
+
...input.agent ? { agent: input.agent } : {},
|
|
197234
197463
|
lens: lens.id,
|
|
197235
197464
|
startHere,
|
|
197236
197465
|
...alwaysOn.profile.length > 0 || alwaysOn.state || alwaysOn.durable.length > 0 ? { alwaysOn } : {},
|
|
@@ -197567,6 +197796,34 @@ var init_auto_context = __esm({
|
|
|
197567
197796
|
}
|
|
197568
197797
|
});
|
|
197569
197798
|
|
|
197799
|
+
// src/knowledge/context-receipt.ts
|
|
197800
|
+
var context_receipt_exports = {};
|
|
197801
|
+
__export(context_receipt_exports, {
|
|
197802
|
+
buildBoundedContextReceipt: () => buildBoundedContextReceipt
|
|
197803
|
+
});
|
|
197804
|
+
function buildBoundedContextReceipt(input) {
|
|
197805
|
+
const provider2 = input.providerQuality ?? input.workset.provenance.codeProvider;
|
|
197806
|
+
return {
|
|
197807
|
+
schemaVersion: "1",
|
|
197808
|
+
task: input.workset.task,
|
|
197809
|
+
brief: input.workset.prompt,
|
|
197810
|
+
receipt: input.workset.receipt,
|
|
197811
|
+
code: {
|
|
197812
|
+
selected: provider2?.selected ?? "lite",
|
|
197813
|
+
quality: provider2?.selectedQuality ?? "heuristic",
|
|
197814
|
+
externalState: provider2?.external.state ?? "not-detected",
|
|
197815
|
+
...input.workset.provenance.snapshotId ? { snapshotId: input.workset.provenance.snapshotId } : {}
|
|
197816
|
+
},
|
|
197817
|
+
...input.workset.agentLoadout ? { loadout: input.workset.agentLoadout } : {}
|
|
197818
|
+
};
|
|
197819
|
+
}
|
|
197820
|
+
var init_context_receipt = __esm({
|
|
197821
|
+
"src/knowledge/context-receipt.ts"() {
|
|
197822
|
+
"use strict";
|
|
197823
|
+
init_esm_shims();
|
|
197824
|
+
}
|
|
197825
|
+
});
|
|
197826
|
+
|
|
197570
197827
|
// src/cli/commands/context.ts
|
|
197571
197828
|
var context_exports = {};
|
|
197572
197829
|
__export(context_exports, {
|
|
@@ -197577,6 +197834,12 @@ function coerceRefreshMode(input) {
|
|
|
197577
197834
|
if (value === "always" || value === "never" || value === "auto") return value;
|
|
197578
197835
|
throw new Error("refresh must be one of: auto, always, never");
|
|
197579
197836
|
}
|
|
197837
|
+
function coerceAgentTarget(input) {
|
|
197838
|
+
const value = input?.trim().toLowerCase();
|
|
197839
|
+
if (!value) return void 0;
|
|
197840
|
+
if (WORKFLOW_AGENT_TARGETS.includes(value)) return value;
|
|
197841
|
+
throw new Error("agent must be one of: " + WORKFLOW_AGENT_TARGETS.join(", "));
|
|
197842
|
+
}
|
|
197580
197843
|
var context_default;
|
|
197581
197844
|
var init_context2 = __esm({
|
|
197582
197845
|
"src/cli/commands/context.ts"() {
|
|
@@ -197586,6 +197849,8 @@ var init_context2 = __esm({
|
|
|
197586
197849
|
init_auto_context();
|
|
197587
197850
|
init_observations();
|
|
197588
197851
|
init_visibility();
|
|
197852
|
+
init_context_receipt();
|
|
197853
|
+
init_workflows2();
|
|
197589
197854
|
init_operator_shared();
|
|
197590
197855
|
context_default = defineCommand({
|
|
197591
197856
|
meta: {
|
|
@@ -197601,10 +197866,12 @@ var init_context2 = __esm({
|
|
|
197601
197866
|
},
|
|
197602
197867
|
resume: { type: "boolean", description: "Always include the bounded prior-work projection" },
|
|
197603
197868
|
refresh: { type: "string", description: "Project scan policy: auto, always, or never" },
|
|
197604
|
-
|
|
197869
|
+
agent: { type: "string", description: "Optional target agent for compatible workflow selection" },
|
|
197870
|
+
json: { type: "boolean", description: "Emit machine-readable JSON output" },
|
|
197871
|
+
briefJson: { type: "boolean", description: "Emit only the bounded agent brief and receipt JSON" }
|
|
197605
197872
|
},
|
|
197606
197873
|
run: async ({ args }) => {
|
|
197607
|
-
const asJson = !!args.json;
|
|
197874
|
+
const asJson = !!args.json || !!args.briefJson;
|
|
197608
197875
|
const task = args.task?.trim() || args.input?.trim() || void 0;
|
|
197609
197876
|
try {
|
|
197610
197877
|
const { project, dataDir, reader } = await getCliProjectContext();
|
|
@@ -197613,23 +197880,25 @@ var init_context2 = __esm({
|
|
|
197613
197880
|
dataDir,
|
|
197614
197881
|
observations: filterReadableObservations(getAllObservations(), reader),
|
|
197615
197882
|
task,
|
|
197883
|
+
agent: coerceAgentTarget(args.agent),
|
|
197616
197884
|
refresh: coerceRefreshMode(args.refresh),
|
|
197617
197885
|
reader,
|
|
197618
197886
|
...args.resume ? { continuation: "always" } : {}
|
|
197619
197887
|
});
|
|
197888
|
+
const detailed = {
|
|
197889
|
+
project,
|
|
197890
|
+
lens: context.lens,
|
|
197891
|
+
brief: buildAutoProjectBrief(context),
|
|
197892
|
+
currentFacts: context.currentFacts,
|
|
197893
|
+
overview: context.overview,
|
|
197894
|
+
refresh: context.refresh,
|
|
197895
|
+
providerQuality: context.providerQuality,
|
|
197896
|
+
workset: context.workset,
|
|
197897
|
+
...context.task ? { task: context.task } : {},
|
|
197898
|
+
...context.continuation ? { continuation: context.continuation } : {}
|
|
197899
|
+
};
|
|
197620
197900
|
emitResult(
|
|
197621
|
-
{
|
|
197622
|
-
project,
|
|
197623
|
-
lens: context.lens,
|
|
197624
|
-
brief: buildAutoProjectBrief(context),
|
|
197625
|
-
currentFacts: context.currentFacts,
|
|
197626
|
-
overview: context.overview,
|
|
197627
|
-
refresh: context.refresh,
|
|
197628
|
-
providerQuality: context.providerQuality,
|
|
197629
|
-
workset: context.workset,
|
|
197630
|
-
...context.task ? { task: context.task } : {},
|
|
197631
|
-
...context.continuation ? { continuation: context.continuation } : {}
|
|
197632
|
-
},
|
|
197901
|
+
args.briefJson ? buildBoundedContextReceipt({ workset: context.workset, providerQuality: context.providerQuality }) : detailed,
|
|
197633
197902
|
formatAutoProjectContextPrompt(context),
|
|
197634
197903
|
asJson
|
|
197635
197904
|
);
|
|
@@ -197661,7 +197930,9 @@ var init_resume = __esm({
|
|
|
197661
197930
|
args: {
|
|
197662
197931
|
task: { type: "positional", description: "Current continuation task", required: false },
|
|
197663
197932
|
refresh: { type: "string", description: "Project scan policy: auto, always, or never" },
|
|
197664
|
-
|
|
197933
|
+
agent: { type: "string", description: "Optional target agent for compatible workflow selection" },
|
|
197934
|
+
json: { type: "boolean", description: "Emit machine-readable JSON output" },
|
|
197935
|
+
briefJson: { type: "boolean", description: "Emit only the bounded agent brief and receipt JSON" }
|
|
197665
197936
|
},
|
|
197666
197937
|
async run({ args }) {
|
|
197667
197938
|
await context_default.run?.({
|
|
@@ -197669,7 +197940,9 @@ var init_resume = __esm({
|
|
|
197669
197940
|
_: [],
|
|
197670
197941
|
input: args.task,
|
|
197671
197942
|
refresh: args.refresh,
|
|
197943
|
+
agent: args.agent,
|
|
197672
197944
|
json: args.json,
|
|
197945
|
+
briefJson: args.briefJson,
|
|
197673
197946
|
resume: true
|
|
197674
197947
|
},
|
|
197675
197948
|
rawArgs: [],
|
|
@@ -197949,6 +198222,7 @@ async function attachTaskWorkset(input) {
|
|
|
197949
198222
|
projectId: input.projectId,
|
|
197950
198223
|
dataDir: input.dataDir,
|
|
197951
198224
|
task: input.pack.task,
|
|
198225
|
+
...input.agent ? { agent: input.agent } : {},
|
|
197952
198226
|
lens: input.lens,
|
|
197953
198227
|
currentFacts: input.currentFacts ?? [],
|
|
197954
198228
|
...input.codeState ? { codeState: input.codeState } : {},
|
|
@@ -198057,7 +198331,8 @@ function formatStatus(status, quality) {
|
|
|
198057
198331
|
status.indexedAt ? `- Indexed at: ${status.indexedAt}` : "- Indexed at: never",
|
|
198058
198332
|
...quality ? [
|
|
198059
198333
|
`- Persistent provider: ${status.provider} (heuristic local index)`,
|
|
198060
|
-
`- External semantic CodeGraph: ${quality.external.state}` + (quality.external.reason ? ` (${quality.external.reason})` : "")
|
|
198334
|
+
`- External semantic CodeGraph: ${quality.external.state}` + (quality.external.reason ? ` (${quality.external.reason})` : ""),
|
|
198335
|
+
`- Task-scoped provider: ${quality.selected} (${quality.selectedQuality})`
|
|
198061
198336
|
] : []
|
|
198062
198337
|
].join("\n");
|
|
198063
198338
|
}
|
|
@@ -198065,6 +198340,8 @@ function formatUsageHint() {
|
|
|
198065
198340
|
return [
|
|
198066
198341
|
"Usage:",
|
|
198067
198342
|
" memorix codegraph refresh",
|
|
198343
|
+
" memorix codegraph init # explicit local CodeGraph initialization",
|
|
198344
|
+
" memorix codegraph sync # explicit local CodeGraph synchronization",
|
|
198068
198345
|
" memorix codegraph status --json",
|
|
198069
198346
|
" memorix codegraph diff [--from <snapshot>] [--to <snapshot>]",
|
|
198070
198347
|
" memorix codegraph impact --path <relative-source-path>",
|
|
@@ -198119,6 +198396,12 @@ function compactFacts(project) {
|
|
|
198119
198396
|
facts.push(formatGitFact(current.git));
|
|
198120
198397
|
return { facts, dirty: current.git.dirty };
|
|
198121
198398
|
}
|
|
198399
|
+
function coerceAgentTarget2(input) {
|
|
198400
|
+
const value = input?.trim().toLowerCase();
|
|
198401
|
+
if (!value) return void 0;
|
|
198402
|
+
if (WORKFLOW_AGENT_TARGETS.includes(value)) return value;
|
|
198403
|
+
throw new Error("agent must be one of: " + WORKFLOW_AGENT_TARGETS.join(", "));
|
|
198404
|
+
}
|
|
198122
198405
|
var codegraph_default;
|
|
198123
198406
|
var init_codegraph = __esm({
|
|
198124
198407
|
"src/cli/commands/codegraph.ts"() {
|
|
@@ -198133,6 +198416,8 @@ var init_codegraph = __esm({
|
|
|
198133
198416
|
init_task_lens();
|
|
198134
198417
|
init_external_provider();
|
|
198135
198418
|
init_resolved_config();
|
|
198419
|
+
init_context_receipt();
|
|
198420
|
+
init_workflows2();
|
|
198136
198421
|
init_observations();
|
|
198137
198422
|
init_visibility();
|
|
198138
198423
|
init_operator_shared();
|
|
@@ -198142,19 +198427,21 @@ var init_codegraph = __esm({
|
|
|
198142
198427
|
description: "Inspect and refresh CodeGraph Memory for the current project"
|
|
198143
198428
|
},
|
|
198144
198429
|
args: {
|
|
198145
|
-
action: { type: "string", description: "Action: status, refresh, diff, impact, or context-pack" },
|
|
198430
|
+
action: { type: "string", description: "Action: status, refresh, diff, impact, init, sync, or context-pack" },
|
|
198146
198431
|
task: { type: "string", description: "Task text for context-pack" },
|
|
198147
198432
|
path: { type: "string", description: "Indexed relative source path for impact" },
|
|
198148
198433
|
limit: { type: "string", description: "Max active memories to inspect for context-pack" },
|
|
198149
198434
|
from: { type: "string", description: "Earlier CodeGraph snapshot id for diff" },
|
|
198150
198435
|
to: { type: "string", description: "Later CodeGraph snapshot id for diff" },
|
|
198151
198436
|
impactLimit: { type: "string", description: "Maximum graph relations to inspect for diff impact" },
|
|
198152
|
-
|
|
198437
|
+
agent: { type: "string", description: "Optional target agent for compatible workflow selection" },
|
|
198438
|
+
json: { type: "boolean", description: "Emit machine-readable JSON output" },
|
|
198439
|
+
briefJson: { type: "boolean", description: "Emit only the bounded agent brief and receipt JSON for context-pack" }
|
|
198153
198440
|
},
|
|
198154
198441
|
run: async ({ args }) => {
|
|
198155
198442
|
const positional = args._ ?? [];
|
|
198156
198443
|
const action = (positional[0] || args.action || "status").toLowerCase();
|
|
198157
|
-
const asJson = !!args.json;
|
|
198444
|
+
const asJson = !!args.json || !!args.briefJson;
|
|
198158
198445
|
try {
|
|
198159
198446
|
const { project, dataDir, reader } = await getCliProjectContext();
|
|
198160
198447
|
const store2 = new CodeGraphStore();
|
|
@@ -198221,6 +198508,26 @@ ${formatUsageHint()}`;
|
|
|
198221
198508
|
);
|
|
198222
198509
|
return;
|
|
198223
198510
|
}
|
|
198511
|
+
case "init":
|
|
198512
|
+
case "sync": {
|
|
198513
|
+
const lifecycle = await runExternalCodeGraphLifecycle({
|
|
198514
|
+
action,
|
|
198515
|
+
projectRoot: project.rootPath,
|
|
198516
|
+
mode: codegraphConfig.externalContext,
|
|
198517
|
+
command: codegraphConfig.externalCommand,
|
|
198518
|
+
timeoutMs: codegraphConfig.externalTimeoutMs
|
|
198519
|
+
});
|
|
198520
|
+
emitResult(
|
|
198521
|
+
{ project, lifecycle, providerQuality: lifecycle.quality },
|
|
198522
|
+
[
|
|
198523
|
+
lifecycle.message,
|
|
198524
|
+
`- External semantic CodeGraph: ${lifecycle.health.state}`,
|
|
198525
|
+
`- Task-scoped provider: ${lifecycle.quality.selected} (${lifecycle.quality.selectedQuality})`
|
|
198526
|
+
].join("\n"),
|
|
198527
|
+
asJson
|
|
198528
|
+
);
|
|
198529
|
+
return;
|
|
198530
|
+
}
|
|
198224
198531
|
case "diff": {
|
|
198225
198532
|
const snapshots = store2.listSnapshots(project.id, 2);
|
|
198226
198533
|
const fromSnapshotId = args.from?.trim() || snapshots[1]?.id;
|
|
@@ -198305,13 +198612,18 @@ ${formatUsageHint()}`;
|
|
|
198305
198612
|
...external.outline ? { semanticCode: external.outline } : {},
|
|
198306
198613
|
providerQuality: external.quality,
|
|
198307
198614
|
...external.caution ? { runtimeCautions: [{ kind: "external-codegraph-fallback", message: external.caution }] } : {},
|
|
198308
|
-
reader
|
|
198615
|
+
reader,
|
|
198616
|
+
agent: coerceAgentTarget2(args.agent)
|
|
198309
198617
|
});
|
|
198310
|
-
emitResult(
|
|
198618
|
+
emitResult(
|
|
198619
|
+
args.briefJson && pack.workset ? buildBoundedContextReceipt({ workset: pack.workset, providerQuality: external.quality }) : { project, pack, providerQuality: external.quality },
|
|
198620
|
+
buildContextPackPrompt(pack),
|
|
198621
|
+
asJson
|
|
198622
|
+
);
|
|
198311
198623
|
return;
|
|
198312
198624
|
}
|
|
198313
198625
|
default:
|
|
198314
|
-
emitError(`unknown codegraph action "${action}". Use "status", "refresh", "diff", "impact", or "context-pack".`, asJson);
|
|
198626
|
+
emitError(`unknown codegraph action "${action}". Use "status", "refresh", "init", "sync", "diff", "impact", or "context-pack".`, asJson);
|
|
198315
198627
|
}
|
|
198316
198628
|
} catch (error40) {
|
|
198317
198629
|
emitError(error40 instanceof Error ? error40.message : String(error40), asJson);
|
|
@@ -199205,13 +199517,13 @@ function verifyType(declaredType, narrative, title) {
|
|
|
199205
199517
|
}
|
|
199206
199518
|
return { type: declaredType, corrected: false };
|
|
199207
199519
|
}
|
|
199208
|
-
async function extractFactsWithLLM(narrative, title, existingFacts) {
|
|
199520
|
+
async function extractFactsWithLLM(narrative, title, existingFacts, signal) {
|
|
199209
199521
|
try {
|
|
199210
199522
|
const { callLLM: callLLM2 } = await Promise.resolve().then(() => (init_provider2(), provider_exports2));
|
|
199211
199523
|
const input = `Title: ${title}
|
|
199212
199524
|
Content: ${narrative}${existingFacts.length > 0 ? `
|
|
199213
199525
|
Already known facts (don't repeat): ${existingFacts.join("; ")}` : ""}`;
|
|
199214
|
-
const response = await callLLM2(LLM_EXTRACT_PROMPT, input);
|
|
199526
|
+
const response = await callLLM2(LLM_EXTRACT_PROMPT, input, signal);
|
|
199215
199527
|
const text2 = response.content.trim();
|
|
199216
199528
|
const jsonMatch = text2.match(/\{[\s\S]*\}/);
|
|
199217
199529
|
if (!jsonMatch) return [];
|
|
@@ -199220,15 +199532,16 @@ Already known facts (don't repeat): ${existingFacts.join("; ")}` : ""}`;
|
|
|
199220
199532
|
if (!Array.isArray(facts)) return [];
|
|
199221
199533
|
const existingLower = new Set(existingFacts.map((f7) => f7.toLowerCase().trim()));
|
|
199222
199534
|
return facts.filter((f7) => typeof f7 === "string" && f7.length >= 5).filter((f7) => !existingLower.has(f7.toLowerCase().trim())).slice(0, 10);
|
|
199223
|
-
} catch {
|
|
199535
|
+
} catch (error40) {
|
|
199536
|
+
if (signal?.aborted) throw error40;
|
|
199224
199537
|
return [];
|
|
199225
199538
|
}
|
|
199226
199539
|
}
|
|
199227
|
-
async function runExtract(input, existingEntities, useLLM = false) {
|
|
199540
|
+
async function runExtract(input, existingEntities, useLLM = false, signal) {
|
|
199228
199541
|
const callerFacts = input.facts ?? [];
|
|
199229
199542
|
let extractedFacts;
|
|
199230
199543
|
if (useLLM) {
|
|
199231
|
-
extractedFacts = await extractFactsWithLLM(input.narrative, input.title, callerFacts);
|
|
199544
|
+
extractedFacts = await extractFactsWithLLM(input.narrative, input.title, callerFacts, signal);
|
|
199232
199545
|
if (extractedFacts.length === 0) {
|
|
199233
199546
|
extractedFacts = extractFacts2(input.narrative, callerFacts);
|
|
199234
199547
|
}
|
|
@@ -199448,7 +199761,7 @@ function mergeFacts2(oldFacts, newFacts) {
|
|
|
199448
199761
|
}
|
|
199449
199762
|
return merged;
|
|
199450
199763
|
}
|
|
199451
|
-
async function resolveWithLLM(extracted, hits, getObservation2) {
|
|
199764
|
+
async function resolveWithLLM(extracted, hits, getObservation2, signal) {
|
|
199452
199765
|
try {
|
|
199453
199766
|
const { callLLM: callLLM2 } = await Promise.resolve().then(() => (init_provider2(), provider_exports2));
|
|
199454
199767
|
const existingMemories = hits.slice(0, 5).map((h5, i4) => ({
|
|
@@ -199465,7 +199778,7 @@ Facts: ${extracted.facts.join("; ")}
|
|
|
199465
199778
|
|
|
199466
199779
|
EXISTING MEMORIES:
|
|
199467
199780
|
${existingMemories.map((m6) => `[ID:${m6.id}] ${m6.title} | ${m6.content} | Facts: ${m6.facts}`).join("\n")}`;
|
|
199468
|
-
const response = await callLLM2(LLM_RESOLVE_PROMPT, input);
|
|
199781
|
+
const response = await callLLM2(LLM_RESOLVE_PROMPT, input, signal);
|
|
199469
199782
|
const text2 = response.content.trim();
|
|
199470
199783
|
const jsonMatch = text2.match(/\{[\s\S]*\}/);
|
|
199471
199784
|
if (!jsonMatch) return null;
|
|
@@ -199502,7 +199815,8 @@ ${existingMemories.map((m6) => `[ID:${m6.id}] ${m6.title} | ${m6.content} | Fact
|
|
|
199502
199815
|
};
|
|
199503
199816
|
}
|
|
199504
199817
|
return null;
|
|
199505
|
-
} catch {
|
|
199818
|
+
} catch (error40) {
|
|
199819
|
+
if (signal?.aborted) throw error40;
|
|
199506
199820
|
return null;
|
|
199507
199821
|
}
|
|
199508
199822
|
}
|
|
@@ -199520,19 +199834,20 @@ function scoreCandidate(extracted, candidate2) {
|
|
|
199520
199834
|
const contradiction = hasContradiction(candidate2.narrative, extracted.narrative);
|
|
199521
199835
|
return { score, searchSimilarity, entityMatch, richer, contradiction };
|
|
199522
199836
|
}
|
|
199523
|
-
async function runResolve(extracted, projectId, searchMemories3, getObservation2, useLLM = false) {
|
|
199837
|
+
async function runResolve(extracted, projectId, searchMemories3, getObservation2, useLLM = false, signal) {
|
|
199524
199838
|
const query = `${extracted.title} ${extracted.narrative.substring(0, 200)}`;
|
|
199525
199839
|
let hits;
|
|
199526
199840
|
try {
|
|
199527
|
-
hits = await searchMemories3(query, 5, projectId);
|
|
199528
|
-
} catch {
|
|
199841
|
+
hits = await searchMemories3(query, 5, projectId, signal);
|
|
199842
|
+
} catch (error40) {
|
|
199843
|
+
if (signal?.aborted) throw error40;
|
|
199529
199844
|
return { action: "new", reason: "Search unavailable, defaulting to new" };
|
|
199530
199845
|
}
|
|
199531
199846
|
if (hits.length === 0) {
|
|
199532
199847
|
return { action: "new", reason: "No similar existing memories found" };
|
|
199533
199848
|
}
|
|
199534
199849
|
if (useLLM) {
|
|
199535
|
-
const llmResult = await resolveWithLLM(extracted, hits, getObservation2);
|
|
199850
|
+
const llmResult = await resolveWithLLM(extracted, hits, getObservation2, signal);
|
|
199536
199851
|
if (llmResult) return llmResult;
|
|
199537
199852
|
}
|
|
199538
199853
|
const scored = hits.map((hit) => ({
|
|
@@ -199954,7 +200269,7 @@ async function runFormation(input, config2) {
|
|
|
199954
200269
|
const existingEntities = config2.getEntityNames();
|
|
199955
200270
|
const extractStartTime = Date.now();
|
|
199956
200271
|
emitStageEvent("extract", "start");
|
|
199957
|
-
const extraction = await runExtract(input, existingEntities, config2.useLLM);
|
|
200272
|
+
const extraction = await runExtract(input, existingEntities, config2.useLLM, config2.signal);
|
|
199958
200273
|
stageDurationsMs.extract = Date.now() - extractStartTime;
|
|
199959
200274
|
emitStageEvent("extract", "success", stageDurationsMs.extract);
|
|
199960
200275
|
stagesCompleted = 1;
|
|
@@ -199974,7 +200289,8 @@ async function runFormation(input, config2) {
|
|
|
199974
200289
|
input.projectId,
|
|
199975
200290
|
config2.searchMemories,
|
|
199976
200291
|
config2.getObservation,
|
|
199977
|
-
config2.useLLM
|
|
200292
|
+
config2.useLLM,
|
|
200293
|
+
config2.signal
|
|
199978
200294
|
);
|
|
199979
200295
|
stageDurationsMs.resolve = Date.now() - resolveStartTime;
|
|
199980
200296
|
emitStageEvent("resolve", "success", stageDurationsMs.resolve);
|
|
@@ -258708,7 +259024,7 @@ The path should point to a directory containing a .git folder.`
|
|
|
258708
259024
|
};
|
|
258709
259025
|
const server = existingServer ?? new McpServer({
|
|
258710
259026
|
name: "memorix",
|
|
258711
|
-
version: true ? "1.
|
|
259027
|
+
version: true ? "1.6.0" : "1.0.1"
|
|
258712
259028
|
});
|
|
258713
259029
|
const originalRegisterTool = server.registerTool.bind(server);
|
|
258714
259030
|
server.registerTool = ((name, ...args) => {
|
|
@@ -258897,8 +259213,8 @@ The path should point to a directory containing a .git folder.`
|
|
|
258897
259213
|
mode: "active",
|
|
258898
259214
|
useLLM: isLLMEnabled(),
|
|
258899
259215
|
minValueScore: 0.3,
|
|
258900
|
-
searchMemories: async (q4, limit2, pid) => {
|
|
258901
|
-
const result = await compactSearch({ query: q4, limit: limit2, projectId: pid, status: "active", reader });
|
|
259216
|
+
searchMemories: async (q4, limit2, pid, signal) => {
|
|
259217
|
+
const result = await compactSearch({ query: q4, limit: limit2, projectId: pid, status: "active", reader, signal });
|
|
258902
259218
|
if (result.entries.length === 0) return [];
|
|
258903
259219
|
const details = await compactDetail(result.entries.map((e5) => e5.id), { reader });
|
|
258904
259220
|
return details.documents.map((d4, i4) => ({
|
|
@@ -258928,16 +259244,19 @@ The path should point to a directory containing a .git folder.`
|
|
|
258928
259244
|
getEntityNames: () => graphManager.getEntityNames(),
|
|
258929
259245
|
onStageEvent: onFormationStageEvent
|
|
258930
259246
|
};
|
|
258931
|
-
formationResult = await
|
|
258932
|
-
|
|
258933
|
-
|
|
258934
|
-
|
|
258935
|
-
|
|
258936
|
-
|
|
258937
|
-
|
|
258938
|
-
|
|
258939
|
-
|
|
258940
|
-
|
|
259247
|
+
formationResult = await withTimeoutSignal(
|
|
259248
|
+
async (signal) => {
|
|
259249
|
+
formationConfig.signal = signal;
|
|
259250
|
+
return runFormation({
|
|
259251
|
+
entityName,
|
|
259252
|
+
type,
|
|
259253
|
+
title,
|
|
259254
|
+
narrative,
|
|
259255
|
+
facts: safeFacts,
|
|
259256
|
+
projectId: project.id,
|
|
259257
|
+
source: "explicit"
|
|
259258
|
+
}, formationConfig);
|
|
259259
|
+
},
|
|
258941
259260
|
FORMATION_TIMEOUT_MS,
|
|
258942
259261
|
"Formation pipeline"
|
|
258943
259262
|
);
|
|
@@ -259287,8 +259606,8 @@ Auto-enriched: ${enrichmentParts.join(", ")}` : "";
|
|
|
259287
259606
|
mode: formationMode,
|
|
259288
259607
|
useLLM: isLLMEnabled(),
|
|
259289
259608
|
minValueScore: 0.3,
|
|
259290
|
-
searchMemories: async (q4, limit2, pid) => {
|
|
259291
|
-
const result = await compactSearch({ query: q4, limit: limit2, projectId: pid, status: "active", reader });
|
|
259609
|
+
searchMemories: async (q4, limit2, pid, signal) => {
|
|
259610
|
+
const result = await compactSearch({ query: q4, limit: limit2, projectId: pid, status: "active", reader, signal });
|
|
259292
259611
|
if (result.entries.length === 0) return [];
|
|
259293
259612
|
const details = await compactDetail(result.entries.map((e5) => e5.id), { reader });
|
|
259294
259613
|
return details.documents.map((d4, i4) => ({
|
|
@@ -259309,8 +259628,11 @@ Auto-enriched: ${enrichmentParts.join(", ")}` : "";
|
|
|
259309
259628
|
},
|
|
259310
259629
|
getEntityNames: () => graphManager.getEntityNames()
|
|
259311
259630
|
};
|
|
259312
|
-
const formed = await
|
|
259313
|
-
|
|
259631
|
+
const formed = await withTimeoutSignal(
|
|
259632
|
+
async (signal) => {
|
|
259633
|
+
formationConfig.signal = signal;
|
|
259634
|
+
return runFormation({ entityName, type, title, narrative, facts: safeFacts, projectId: project.id, source: "explicit", topicKey }, formationConfig);
|
|
259635
|
+
},
|
|
259314
259636
|
FORMATION_TIMEOUT_MS,
|
|
259315
259637
|
"Shadow formation"
|
|
259316
259638
|
);
|
|
@@ -259536,13 +259858,28 @@ _Search mode: ${getLastSearchMode2(project.id)}_`;
|
|
|
259536
259858
|
refresh: external_exports2.enum(["auto", "always", "never"]).optional().default("auto").describe(
|
|
259537
259859
|
"Code Memory refresh policy. auto refreshes only when missing or stale."
|
|
259538
259860
|
),
|
|
259539
|
-
format: external_exports2.enum(["prompt", "summary", "json"]).optional().default("prompt").describe(
|
|
259540
|
-
'Output format. "prompt" is agent-ready; "summary" is human-readable; "json" is
|
|
259861
|
+
format: external_exports2.enum(["prompt", "summary", "json", "receipt"]).optional().default("prompt").describe(
|
|
259862
|
+
'Output format. "prompt" is agent-ready; "summary" is human-readable; "receipt" is bounded JSON; "json" is detailed diagnostics.'
|
|
259541
259863
|
),
|
|
259864
|
+
agent: external_exports2.enum([
|
|
259865
|
+
"windsurf",
|
|
259866
|
+
"cursor",
|
|
259867
|
+
"claude-code",
|
|
259868
|
+
"codex",
|
|
259869
|
+
"copilot",
|
|
259870
|
+
"antigravity",
|
|
259871
|
+
"gemini-cli",
|
|
259872
|
+
"openclaw",
|
|
259873
|
+
"hermes",
|
|
259874
|
+
"omp",
|
|
259875
|
+
"kiro",
|
|
259876
|
+
"opencode",
|
|
259877
|
+
"trae"
|
|
259878
|
+
]).optional().describe("Optional target agent for compatible workflow selection."),
|
|
259542
259879
|
limit: external_exports2.number().optional().describe("Reserved for future source limits; current prompt stays compact by default.")
|
|
259543
259880
|
}
|
|
259544
259881
|
},
|
|
259545
|
-
async ({ task, refresh, format }) => {
|
|
259882
|
+
async ({ task, refresh, format, agent }) => {
|
|
259546
259883
|
const unresolved = requireResolvedProject("build project context for the current project");
|
|
259547
259884
|
if (unresolved) return unresolved;
|
|
259548
259885
|
const [
|
|
@@ -259554,12 +259891,14 @@ _Search mode: ${getLastSearchMode2(project.id)}_`;
|
|
|
259554
259891
|
},
|
|
259555
259892
|
{ getObservationStore: getObservationStore2 },
|
|
259556
259893
|
{ MaintenanceJobStore: MaintenanceJobStore2 },
|
|
259557
|
-
{ enqueueCodegraphRefresh: enqueueCodegraphRefresh2 }
|
|
259894
|
+
{ enqueueCodegraphRefresh: enqueueCodegraphRefresh2 },
|
|
259895
|
+
{ buildBoundedContextReceipt: buildBoundedContextReceipt2 }
|
|
259558
259896
|
] = await Promise.all([
|
|
259559
259897
|
Promise.resolve().then(() => (init_auto_context(), auto_context_exports)),
|
|
259560
259898
|
Promise.resolve().then(() => (init_obs_store(), obs_store_exports)),
|
|
259561
259899
|
Promise.resolve().then(() => (init_maintenance_jobs(), maintenance_jobs_exports)),
|
|
259562
|
-
Promise.resolve().then(() => (init_lifecycle(), lifecycle_exports))
|
|
259900
|
+
Promise.resolve().then(() => (init_lifecycle(), lifecycle_exports)),
|
|
259901
|
+
Promise.resolve().then(() => (init_context_receipt(), context_receipt_exports))
|
|
259563
259902
|
]);
|
|
259564
259903
|
const observations2 = filterReadableObservations(
|
|
259565
259904
|
await getObservationStore2().loadByProject(project.id, { status: "active" }),
|
|
@@ -259570,6 +259909,7 @@ _Search mode: ${getLastSearchMode2(project.id)}_`;
|
|
|
259570
259909
|
dataDir: projectDir2,
|
|
259571
259910
|
observations: observations2,
|
|
259572
259911
|
task,
|
|
259912
|
+
agent,
|
|
259573
259913
|
refresh: refresh ?? "auto",
|
|
259574
259914
|
reader: getObservationReader(),
|
|
259575
259915
|
enqueueRefresh: () => {
|
|
@@ -259582,7 +259922,10 @@ _Search mode: ${getLastSearchMode2(project.id)}_`;
|
|
|
259582
259922
|
});
|
|
259583
259923
|
}
|
|
259584
259924
|
});
|
|
259585
|
-
const text2 = format === "json" ? JSON.stringify({ ...context, brief: buildAutoProjectBrief2(context) }, null, 2) : format === "
|
|
259925
|
+
const text2 = format === "json" ? JSON.stringify({ ...context, brief: buildAutoProjectBrief2(context) }, null, 2) : format === "receipt" ? JSON.stringify(buildBoundedContextReceipt2({
|
|
259926
|
+
workset: context.workset,
|
|
259927
|
+
providerQuality: context.providerQuality
|
|
259928
|
+
}), null, 2) : format === "summary" ? formatAutoProjectContextSummary2(context) : formatAutoProjectContextPrompt2(context);
|
|
259586
259929
|
autopilotRetrievalBoundary = {
|
|
259587
259930
|
projectId: project.id,
|
|
259588
259931
|
issuedAt: Date.now(),
|