memorix 1.4.1 → 1.4.2
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 +19 -0
- package/dist/cli/index.js +1165 -464
- package/dist/index.js +933 -316
- package/dist/maintenance-runner.js +514 -159
- package/dist/media-video-runner.js +514 -159
- package/dist/memcode-runtime/CHANGELOG.md +19 -0
- package/dist/sdk.js +932 -315
- package/dist/vector-backfill-runner.js +514 -159
- package/docs/1.4.2-EVIDENCE-GOVERNED-MEMORY-SPEC.md +434 -0
- package/package.json +1 -1
- package/plugins/claude/memorix/.claude-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 +83 -2
- package/src/codegraph/auto-context.ts +20 -0
- package/src/codegraph/external-provider.ts +1 -0
- package/src/codegraph/store.ts +216 -5
- package/src/codegraph/types.ts +42 -0
- package/src/knowledge/context-assembly.ts +25 -0
- package/src/knowledge/governor.ts +156 -0
- package/src/knowledge/outcome-store.ts +102 -0
- package/src/knowledge/outcome-types.ts +49 -0
- package/src/knowledge/workflows.ts +32 -1
- package/src/knowledge/workset.ts +203 -13
- package/src/store/sqlite-db.ts +42 -0
|
@@ -307,7 +307,7 @@ function closeAllDatabases() {
|
|
|
307
307
|
_dbCache.delete(key);
|
|
308
308
|
}
|
|
309
309
|
}
|
|
310
|
-
var BetterSqlite3, CREATE_OBSERVATIONS_TABLE, CREATE_MINI_SKILLS_TABLE, CREATE_SESSIONS_TABLE, CREATE_META_TABLE, CREATE_TEAM_AGENTS_TABLE, CREATE_TEAM_MESSAGES_TABLE, CREATE_TEAM_TASKS_TABLE, CREATE_TEAM_TASK_DEPS_TABLE, CREATE_TEAM_LOCKS_TABLE, CREATE_TEAM_ROLES_TABLE, CREATE_CHAT_TRANSCRIPT_TABLE, CREATE_GRAPH_ENTITIES_TABLE, CREATE_GRAPH_RELATIONS_TABLE, CREATE_CODE_FILES_TABLE, CREATE_CODE_SYMBOLS_TABLE, CREATE_CODE_EDGES_TABLE, CREATE_OBSERVATION_CODE_REFS_TABLE, CREATE_SCHEMA_MIGRATIONS_TABLE, CREATE_CODE_STATE_SNAPSHOTS_TABLE, CREATE_KNOWLEDGE_CLAIMS_TABLE, CREATE_KNOWLEDGE_CLAIM_EVIDENCE_TABLE, CREATE_KNOWLEDGE_CLAIM_EVENTS_TABLE, CREATE_KNOWLEDGE_WORKSPACES_TABLE, CREATE_KNOWLEDGE_PAGES_TABLE, CREATE_KNOWLEDGE_PAGE_CLAIMS_TABLE, CREATE_KNOWLEDGE_PAGE_LINKS_TABLE, CREATE_KNOWLEDGE_PROPOSALS_TABLE, CREATE_KNOWLEDGE_WORKFLOWS_TABLE, CREATE_KNOWLEDGE_WORKFLOW_RUNS_TABLE, CREATE_LONG_TERM_MEMORIES_TABLE, CREATE_LONG_TERM_MEMORY_EVIDENCE_TABLE, CREATE_LONG_TERM_MEMORY_EVENTS_TABLE, CREATE_MEDIA_ASSETS_TABLE, CREATE_MEDIA_ASSET_LINKS_TABLE, CREATE_MEDIA_DERIVATIONS_TABLE, CREATE_MEDIA_EMBEDDING_PROFILES_TABLE, CREATE_MEDIA_EMBEDDINGS_TABLE, CREATE_MEDIA_JOBS_TABLE, CREATE_MAINTENANCE_JOBS_TABLE, CREATE_MAINTENANCE_TARGETS_TABLE, CREATE_COMPACTION_CHECKPOINTS_TABLE, CREATE_INDEXES, SCHEMA_MIGRATIONS, _dbCache;
|
|
310
|
+
var BetterSqlite3, CREATE_OBSERVATIONS_TABLE, CREATE_MINI_SKILLS_TABLE, CREATE_SESSIONS_TABLE, CREATE_META_TABLE, CREATE_TEAM_AGENTS_TABLE, CREATE_TEAM_MESSAGES_TABLE, CREATE_TEAM_TASKS_TABLE, CREATE_TEAM_TASK_DEPS_TABLE, CREATE_TEAM_LOCKS_TABLE, CREATE_TEAM_ROLES_TABLE, CREATE_CHAT_TRANSCRIPT_TABLE, CREATE_GRAPH_ENTITIES_TABLE, CREATE_GRAPH_RELATIONS_TABLE, CREATE_CODE_FILES_TABLE, CREATE_CODE_SYMBOLS_TABLE, CREATE_CODE_EDGES_TABLE, CREATE_OBSERVATION_CODE_REFS_TABLE, CREATE_SCHEMA_MIGRATIONS_TABLE, CREATE_CODE_STATE_SNAPSHOTS_TABLE, CREATE_CODE_STATE_SNAPSHOT_FILES_TABLE, CREATE_KNOWLEDGE_CLAIMS_TABLE, CREATE_KNOWLEDGE_CLAIM_EVIDENCE_TABLE, CREATE_KNOWLEDGE_CLAIM_EVENTS_TABLE, CREATE_KNOWLEDGE_WORKSPACES_TABLE, CREATE_KNOWLEDGE_PAGES_TABLE, CREATE_KNOWLEDGE_PAGE_CLAIMS_TABLE, CREATE_KNOWLEDGE_PAGE_LINKS_TABLE, CREATE_KNOWLEDGE_PROPOSALS_TABLE, CREATE_KNOWLEDGE_WORKFLOWS_TABLE, CREATE_KNOWLEDGE_WORKFLOW_RUNS_TABLE, CREATE_LONG_TERM_MEMORIES_TABLE, CREATE_LONG_TERM_MEMORY_EVIDENCE_TABLE, CREATE_LONG_TERM_MEMORY_EVENTS_TABLE, CREATE_MEMORY_OUTCOME_SIGNALS_TABLE, CREATE_MEDIA_ASSETS_TABLE, CREATE_MEDIA_ASSET_LINKS_TABLE, CREATE_MEDIA_DERIVATIONS_TABLE, CREATE_MEDIA_EMBEDDING_PROFILES_TABLE, CREATE_MEDIA_EMBEDDINGS_TABLE, CREATE_MEDIA_JOBS_TABLE, CREATE_MAINTENANCE_JOBS_TABLE, CREATE_MAINTENANCE_TARGETS_TABLE, CREATE_COMPACTION_CHECKPOINTS_TABLE, CREATE_INDEXES, SCHEMA_MIGRATIONS, _dbCache;
|
|
311
311
|
var init_sqlite_db = __esm({
|
|
312
312
|
"src/store/sqlite-db.ts"() {
|
|
313
313
|
"use strict";
|
|
@@ -573,6 +573,17 @@ CREATE TABLE IF NOT EXISTS observation_code_refs (
|
|
|
573
573
|
" UNIQUE(projectId, sourceEpoch)",
|
|
574
574
|
");"
|
|
575
575
|
].join("\n");
|
|
576
|
+
CREATE_CODE_STATE_SNAPSHOT_FILES_TABLE = [
|
|
577
|
+
"CREATE TABLE IF NOT EXISTS code_state_snapshot_files (",
|
|
578
|
+
" snapshotId TEXT NOT NULL,",
|
|
579
|
+
" projectId TEXT NOT NULL,",
|
|
580
|
+
" fileId TEXT NOT NULL,",
|
|
581
|
+
" path TEXT NOT NULL,",
|
|
582
|
+
" contentHash TEXT NOT NULL,",
|
|
583
|
+
" PRIMARY KEY (snapshotId, path),",
|
|
584
|
+
" FOREIGN KEY (snapshotId) REFERENCES code_state_snapshots(id) ON DELETE CASCADE",
|
|
585
|
+
");"
|
|
586
|
+
].join("\n");
|
|
576
587
|
CREATE_KNOWLEDGE_CLAIMS_TABLE = `
|
|
577
588
|
CREATE TABLE IF NOT EXISTS knowledge_claims (
|
|
578
589
|
id TEXT PRIMARY KEY,
|
|
@@ -783,6 +794,19 @@ CREATE TABLE IF NOT EXISTS long_term_memory_events (
|
|
|
783
794
|
createdAt TEXT NOT NULL,
|
|
784
795
|
FOREIGN KEY (memoryId) REFERENCES long_term_memories(id) ON DELETE CASCADE
|
|
785
796
|
);
|
|
797
|
+
`;
|
|
798
|
+
CREATE_MEMORY_OUTCOME_SIGNALS_TABLE = `
|
|
799
|
+
CREATE TABLE IF NOT EXISTS memory_outcome_signals (
|
|
800
|
+
id TEXT PRIMARY KEY,
|
|
801
|
+
projectId TEXT NOT NULL,
|
|
802
|
+
candidateKind TEXT NOT NULL,
|
|
803
|
+
candidateId TEXT NOT NULL,
|
|
804
|
+
kind TEXT NOT NULL,
|
|
805
|
+
sourceRef TEXT NOT NULL,
|
|
806
|
+
snapshotId TEXT,
|
|
807
|
+
detail TEXT,
|
|
808
|
+
observedAt TEXT NOT NULL
|
|
809
|
+
);
|
|
786
810
|
`;
|
|
787
811
|
CREATE_MEDIA_ASSETS_TABLE = `
|
|
788
812
|
CREATE TABLE IF NOT EXISTS media_assets (
|
|
@@ -1025,6 +1049,20 @@ CREATE UNIQUE INDEX IF NOT EXISTS idx_maintenance_jobs_active_dedupe
|
|
|
1025
1049
|
db2.exec("CREATE INDEX IF NOT EXISTS idx_code_edges_snapshot ON code_edges(projectId, snapshotId)");
|
|
1026
1050
|
}
|
|
1027
1051
|
},
|
|
1052
|
+
{
|
|
1053
|
+
id: "1.4-codegraph-snapshot-manifest",
|
|
1054
|
+
apply: (db2) => {
|
|
1055
|
+
db2.exec(CREATE_CODE_STATE_SNAPSHOT_FILES_TABLE);
|
|
1056
|
+
db2.exec("CREATE INDEX IF NOT EXISTS idx_code_snapshot_files_project_path ON code_state_snapshot_files(projectId, path)");
|
|
1057
|
+
}
|
|
1058
|
+
},
|
|
1059
|
+
{
|
|
1060
|
+
id: "1.4-memory-outcome-signals",
|
|
1061
|
+
apply: (db2) => {
|
|
1062
|
+
db2.exec(CREATE_MEMORY_OUTCOME_SIGNALS_TABLE);
|
|
1063
|
+
db2.exec("CREATE INDEX IF NOT EXISTS idx_memory_outcomes_candidate ON memory_outcome_signals(projectId, candidateKind, candidateId, observedAt DESC)");
|
|
1064
|
+
}
|
|
1065
|
+
},
|
|
1028
1066
|
{
|
|
1029
1067
|
id: "1.2-knowledge-claim-ledger",
|
|
1030
1068
|
apply: (db2) => {
|
|
@@ -1985,8 +2023,8 @@ async function readResponseText(response, signal, maxBytes = MAX_LLM_RESPONSE_BY
|
|
|
1985
2023
|
}
|
|
1986
2024
|
}
|
|
1987
2025
|
async function readResponseJson(response, signal, maxBytes = MAX_LLM_RESPONSE_BYTES) {
|
|
1988
|
-
const
|
|
1989
|
-
return JSON.parse(
|
|
2026
|
+
const text2 = await readResponseText(response, signal, maxBytes);
|
|
2027
|
+
return JSON.parse(text2);
|
|
1990
2028
|
}
|
|
1991
2029
|
async function* callLLMWithToolsStream(messages, tools) {
|
|
1992
2030
|
if (!currentConfig) {
|
|
@@ -3158,8 +3196,8 @@ var init_mini_skill_store = __esm({
|
|
|
3158
3196
|
|
|
3159
3197
|
// src/compact/token-budget.ts
|
|
3160
3198
|
import { countTokens, isWithinTokenLimit } from "gpt-tokenizer";
|
|
3161
|
-
function countTextTokens(
|
|
3162
|
-
return countTokens(
|
|
3199
|
+
function countTextTokens(text2) {
|
|
3200
|
+
return countTokens(text2);
|
|
3163
3201
|
}
|
|
3164
3202
|
var init_token_budget = __esm({
|
|
3165
3203
|
"src/compact/token-budget.ts"() {
|
|
@@ -3265,8 +3303,8 @@ import { createHash } from "crypto";
|
|
|
3265
3303
|
import { readFile, writeFile, mkdir } from "fs/promises";
|
|
3266
3304
|
import { join as join2 } from "path";
|
|
3267
3305
|
import { homedir as homedir6 } from "os";
|
|
3268
|
-
function textHash(
|
|
3269
|
-
return createHash("sha256").update(
|
|
3306
|
+
function textHash(text2) {
|
|
3307
|
+
return createHash("sha256").update(text2).digest("hex").slice(0, 16);
|
|
3270
3308
|
}
|
|
3271
3309
|
async function loadDiskCache() {
|
|
3272
3310
|
try {
|
|
@@ -3329,11 +3367,11 @@ var init_fastembed_provider = __esm({
|
|
|
3329
3367
|
async embedInputs(inputs, options = {}) {
|
|
3330
3368
|
return Promise.all(inputs.map((input) => this.embedInput(input, options)));
|
|
3331
3369
|
}
|
|
3332
|
-
async embed(
|
|
3333
|
-
const hash4 = textHash(
|
|
3370
|
+
async embed(text2) {
|
|
3371
|
+
const hash4 = textHash(text2);
|
|
3334
3372
|
const cached = cache.get(hash4);
|
|
3335
3373
|
if (cached) return cached;
|
|
3336
|
-
const raw = await this.model.queryEmbed(
|
|
3374
|
+
const raw = await this.model.queryEmbed(text2);
|
|
3337
3375
|
const result = Array.from(raw);
|
|
3338
3376
|
if (result.length !== this.dimensions) {
|
|
3339
3377
|
throw new Error(`Expected ${this.dimensions}d embedding, got ${result.length}d`);
|
|
@@ -3429,10 +3467,10 @@ var init_transformers_provider = __esm({
|
|
|
3429
3467
|
async embedInputs(inputs, options = {}) {
|
|
3430
3468
|
return Promise.all(inputs.map((input) => this.embedInput(input, options)));
|
|
3431
3469
|
}
|
|
3432
|
-
async embed(
|
|
3433
|
-
const cached = cache2.get(
|
|
3470
|
+
async embed(text2) {
|
|
3471
|
+
const cached = cache2.get(text2);
|
|
3434
3472
|
if (cached) return cached;
|
|
3435
|
-
const output = await this.extractor(
|
|
3473
|
+
const output = await this.extractor(text2, {
|
|
3436
3474
|
pooling: "mean",
|
|
3437
3475
|
normalize: true
|
|
3438
3476
|
});
|
|
@@ -3440,7 +3478,7 @@ var init_transformers_provider = __esm({
|
|
|
3440
3478
|
if (result.length !== this.dimensions) {
|
|
3441
3479
|
throw new Error(`Expected ${this.dimensions}d embedding, got ${result.length}d`);
|
|
3442
3480
|
}
|
|
3443
|
-
this.cacheSet(
|
|
3481
|
+
this.cacheSet(text2, result);
|
|
3444
3482
|
return result;
|
|
3445
3483
|
}
|
|
3446
3484
|
async embedBatch(texts) {
|
|
@@ -3503,8 +3541,8 @@ function dimsCacheFile() {
|
|
|
3503
3541
|
function cacheMetaFile() {
|
|
3504
3542
|
return join3(cacheDir(), ".embedding-api-cache-meta.json");
|
|
3505
3543
|
}
|
|
3506
|
-
function normalizeText(
|
|
3507
|
-
return
|
|
3544
|
+
function normalizeText(text2) {
|
|
3545
|
+
return text2.replace(/\s+/g, " ").trim().slice(0, MAX_INPUT_CHARS);
|
|
3508
3546
|
}
|
|
3509
3547
|
function cacheNamespace(config) {
|
|
3510
3548
|
return [
|
|
@@ -3514,8 +3552,8 @@ function cacheNamespace(config) {
|
|
|
3514
3552
|
config.requestedDimensions ?? "native"
|
|
3515
3553
|
].join("|");
|
|
3516
3554
|
}
|
|
3517
|
-
function textHash2(
|
|
3518
|
-
return createHash2("sha256").update(`${namespace}\0${
|
|
3555
|
+
function textHash2(text2, namespace) {
|
|
3556
|
+
return createHash2("sha256").update(`${namespace}\0${text2}`).digest("hex").slice(0, 16);
|
|
3519
3557
|
}
|
|
3520
3558
|
function inputIdentity(input, options = {}) {
|
|
3521
3559
|
return JSON.stringify({
|
|
@@ -3927,8 +3965,8 @@ var init_api_provider = __esm({
|
|
|
3927
3965
|
if (!embedding) throw new Error("API probe returned no embeddings; check model name and API key");
|
|
3928
3966
|
return embedding.length;
|
|
3929
3967
|
}
|
|
3930
|
-
async embed(
|
|
3931
|
-
const normalized = normalizeText(
|
|
3968
|
+
async embed(text2, options) {
|
|
3969
|
+
const normalized = normalizeText(text2);
|
|
3932
3970
|
if (isNativeGeminiEndpoint(this.config.baseUrl)) {
|
|
3933
3971
|
return this.embedInput({ modality: "text", text: normalized }, { intent: "document", ...options });
|
|
3934
3972
|
}
|
|
@@ -3985,7 +4023,7 @@ var init_api_provider = __esm({
|
|
|
3985
4023
|
}
|
|
3986
4024
|
async embedBatch(texts, options) {
|
|
3987
4025
|
if (isNativeGeminiEndpoint(this.config.baseUrl)) {
|
|
3988
|
-
return Promise.all(texts.map((
|
|
4026
|
+
return Promise.all(texts.map((text2) => this.embedInput({ modality: "text", text: text2 }, { intent: "document", ...options })));
|
|
3989
4027
|
}
|
|
3990
4028
|
await ensureDiskCacheLoaded();
|
|
3991
4029
|
const normalizedTexts = texts.map(normalizeText);
|
|
@@ -4064,8 +4102,8 @@ var init_api_provider = __esm({
|
|
|
4064
4102
|
}
|
|
4065
4103
|
async getCachedEmbeddings(texts) {
|
|
4066
4104
|
await ensureDiskCacheLoaded();
|
|
4067
|
-
return texts.map((
|
|
4068
|
-
const hash4 = textHash2(normalizeText(
|
|
4105
|
+
return texts.map((text2) => {
|
|
4106
|
+
const hash4 = textHash2(normalizeText(text2), this.cacheKeyNamespace);
|
|
4069
4107
|
return cache3.get(hash4) ?? null;
|
|
4070
4108
|
});
|
|
4071
4109
|
}
|
|
@@ -4295,9 +4333,9 @@ function wrapProvider(candidate) {
|
|
|
4295
4333
|
return {
|
|
4296
4334
|
name: candidate.name,
|
|
4297
4335
|
dimensions: candidate.dimensions,
|
|
4298
|
-
async embed(
|
|
4336
|
+
async embed(text2, options) {
|
|
4299
4337
|
try {
|
|
4300
|
-
return await candidate.embed(
|
|
4338
|
+
return await candidate.embed(text2, options);
|
|
4301
4339
|
} catch (error) {
|
|
4302
4340
|
if (kind === "api" && getEmbeddingMode2() === "auto" && isTemporaryEmbeddingFailure(error)) {
|
|
4303
4341
|
warnOnce("[memorix] API embedding temporarily unavailable \u2014 switching to local fallback provider");
|
|
@@ -4305,7 +4343,7 @@ function wrapProvider(candidate) {
|
|
|
4305
4343
|
if (fallback) {
|
|
4306
4344
|
provider = wrapProvider(fallback);
|
|
4307
4345
|
warnOnce(`[memorix] Embedding fallback activated: ${provider.name} (${provider.dimensions}d)`);
|
|
4308
|
-
return provider.embed(
|
|
4346
|
+
return provider.embed(text2, options);
|
|
4309
4347
|
}
|
|
4310
4348
|
}
|
|
4311
4349
|
if (isTemporaryEmbeddingFailure(error)) {
|
|
@@ -4804,8 +4842,8 @@ function isCjkHeavy(query) {
|
|
|
4804
4842
|
const cjkCount = (query.match(CJK_PATTERN) || []).length;
|
|
4805
4843
|
return query.length > 0 && cjkCount / query.length > 0.3;
|
|
4806
4844
|
}
|
|
4807
|
-
function normalizeExpansion(
|
|
4808
|
-
return
|
|
4845
|
+
function normalizeExpansion(text2) {
|
|
4846
|
+
return text2.trim().replace(/^[-*]\s*/, "").replace(/^["'`]+|["'`]+$/g, "").split(/\r?\n/)[0].trim();
|
|
4809
4847
|
}
|
|
4810
4848
|
async function maybeExpandSearchQuery(query) {
|
|
4811
4849
|
if (!query || !isCjkHeavy(query) || COMMAND_LIKE_QUERY.test(query)) {
|
|
@@ -5168,9 +5206,9 @@ function shouldSkipCompression(narrative, type) {
|
|
|
5168
5206
|
if (specialChars / narrative.length > 0.35) return true;
|
|
5169
5207
|
return false;
|
|
5170
5208
|
}
|
|
5171
|
-
function estimateTokens(
|
|
5172
|
-
const cjkChars = (
|
|
5173
|
-
const otherChars =
|
|
5209
|
+
function estimateTokens(text2) {
|
|
5210
|
+
const cjkChars = (text2.match(/[\u4e00-\u9fff\u3040-\u309f\u30a0-\u30ff\uac00-\ud7af]/g) || []).length;
|
|
5211
|
+
const otherChars = text2.length - cjkChars;
|
|
5174
5212
|
return Math.ceil(cjkChars / 1.5 + otherChars / 4);
|
|
5175
5213
|
}
|
|
5176
5214
|
var COMPRESS_PROMPT, COMPRESS_PROMPT_GENTLE, RERANK_PROMPT, SKIP_PATTERNS, LOW_COMPRESSION_TYPES;
|
|
@@ -5473,10 +5511,10 @@ function isEmbeddingEnabled() {
|
|
|
5473
5511
|
function getVectorDimensions() {
|
|
5474
5512
|
return embeddingEnabled ? embeddingDimensions : null;
|
|
5475
5513
|
}
|
|
5476
|
-
async function generateEmbedding(
|
|
5514
|
+
async function generateEmbedding(text2) {
|
|
5477
5515
|
const provider2 = await getEmbeddingProvider();
|
|
5478
5516
|
if (!provider2) return null;
|
|
5479
|
-
return provider2.embedInput ? provider2.embedInput({ modality: "text", text }, { intent: "document" }) : provider2.embed(
|
|
5517
|
+
return provider2.embedInput ? provider2.embedInput({ modality: "text", text: text2 }, { intent: "document" }) : provider2.embed(text2);
|
|
5480
5518
|
}
|
|
5481
5519
|
async function generateEmbeddingInput(input, options = {}) {
|
|
5482
5520
|
const provider2 = await getEmbeddingProvider();
|
|
@@ -6322,9 +6360,9 @@ var init_entity_extractor = __esm({
|
|
|
6322
6360
|
});
|
|
6323
6361
|
|
|
6324
6362
|
// src/memory/secret-filter.ts
|
|
6325
|
-
function applyRedaction(
|
|
6326
|
-
if (!
|
|
6327
|
-
let out =
|
|
6363
|
+
function applyRedaction(text2) {
|
|
6364
|
+
if (!text2) return text2;
|
|
6365
|
+
let out = text2;
|
|
6328
6366
|
out = out.replace(
|
|
6329
6367
|
/((?:password|passwd|pwd|secret|token|api[_-]?key|auth[_-]?key|access[_-]?key|private[_-]?key|client[_-]?secret)\s*[:=]\s*["']?)([^\s"',;\n]{6,})/gi,
|
|
6330
6368
|
"$1[REDACTED]"
|
|
@@ -6338,8 +6376,8 @@ function applyRedaction(text) {
|
|
|
6338
6376
|
out = out.replace(/\beyJ[A-Za-z0-9._-]{40,}\b/g, "[REDACTED]");
|
|
6339
6377
|
return out;
|
|
6340
6378
|
}
|
|
6341
|
-
function sanitizeCredentials(
|
|
6342
|
-
return applyRedaction(
|
|
6379
|
+
function sanitizeCredentials(text2) {
|
|
6380
|
+
return applyRedaction(text2);
|
|
6343
6381
|
}
|
|
6344
6382
|
var init_secret_filter = __esm({
|
|
6345
6383
|
"src/memory/secret-filter.ts"() {
|
|
@@ -6390,8 +6428,8 @@ function clampPositiveInteger(value, fallback) {
|
|
|
6390
6428
|
return Math.max(1, Math.floor(value));
|
|
6391
6429
|
}
|
|
6392
6430
|
function errorText(error) {
|
|
6393
|
-
const
|
|
6394
|
-
return sanitizeCredentials(
|
|
6431
|
+
const text2 = error instanceof Error ? error.message : String(error);
|
|
6432
|
+
return sanitizeCredentials(text2).slice(0, MAX_ERROR_LENGTH);
|
|
6395
6433
|
}
|
|
6396
6434
|
function normalizedKinds(kinds) {
|
|
6397
6435
|
if (!kinds) return void 0;
|
|
@@ -7340,9 +7378,9 @@ __export(consolidation_exports, {
|
|
|
7340
7378
|
executeConsolidation: () => executeConsolidation,
|
|
7341
7379
|
findConsolidationCandidates: () => findConsolidationCandidates
|
|
7342
7380
|
});
|
|
7343
|
-
function tokenize(
|
|
7381
|
+
function tokenize(text2) {
|
|
7344
7382
|
return new Set(
|
|
7345
|
-
|
|
7383
|
+
text2.toLowerCase().replace(/[^a-z0-9\u4e00-\u9fff\s-]/g, " ").split(/\s+/).filter((t2) => t2.length > 1)
|
|
7346
7384
|
);
|
|
7347
7385
|
}
|
|
7348
7386
|
function jaccardSimilarity(a, b) {
|
|
@@ -16300,8 +16338,8 @@ var init_headers = __esm({
|
|
|
16300
16338
|
});
|
|
16301
16339
|
|
|
16302
16340
|
// packages/ai/dist/utils/sanitize-unicode.js
|
|
16303
|
-
function sanitizeSurrogates(
|
|
16304
|
-
return
|
|
16341
|
+
function sanitizeSurrogates(text2) {
|
|
16342
|
+
return text2.replace(/[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/g, "");
|
|
16305
16343
|
}
|
|
16306
16344
|
var init_sanitize_unicode = __esm({
|
|
16307
16345
|
"packages/ai/dist/utils/sanitize-unicode.js"() {
|
|
@@ -16783,9 +16821,9 @@ var init_values = __esm({
|
|
|
16783
16821
|
}
|
|
16784
16822
|
return n;
|
|
16785
16823
|
};
|
|
16786
|
-
safeJSON = (
|
|
16824
|
+
safeJSON = (text2) => {
|
|
16787
16825
|
try {
|
|
16788
|
-
return JSON.parse(
|
|
16826
|
+
return JSON.parse(text2);
|
|
16789
16827
|
} catch (err) {
|
|
16790
16828
|
return void 0;
|
|
16791
16829
|
}
|
|
@@ -17948,8 +17986,8 @@ async function defaultParseResponse(client, props) {
|
|
|
17948
17986
|
const json2 = await response.json();
|
|
17949
17987
|
return addRequestID(json2, response);
|
|
17950
17988
|
}
|
|
17951
|
-
const
|
|
17952
|
-
return
|
|
17989
|
+
const text2 = await response.text();
|
|
17990
|
+
return text2;
|
|
17953
17991
|
})();
|
|
17954
17992
|
loggerFor(client).debug(`[${requestLogID}] response parsed`, formatRequestDetails({
|
|
17955
17993
|
retryOfRequestLogID,
|
|
@@ -43556,9 +43594,9 @@ var init_values2 = __esm({
|
|
|
43556
43594
|
}
|
|
43557
43595
|
return n;
|
|
43558
43596
|
};
|
|
43559
|
-
safeJSON2 = (
|
|
43597
|
+
safeJSON2 = (text2) => {
|
|
43560
43598
|
try {
|
|
43561
|
-
return JSON.parse(
|
|
43599
|
+
return JSON.parse(text2);
|
|
43562
43600
|
} catch (err) {
|
|
43563
43601
|
return void 0;
|
|
43564
43602
|
}
|
|
@@ -44332,8 +44370,8 @@ async function defaultParseResponse2(client, props) {
|
|
|
44332
44370
|
const json2 = await response.json();
|
|
44333
44371
|
return addRequestID2(json2, response);
|
|
44334
44372
|
}
|
|
44335
|
-
const
|
|
44336
|
-
return
|
|
44373
|
+
const text2 = await response.text();
|
|
44374
|
+
return text2;
|
|
44337
44375
|
})();
|
|
44338
44376
|
loggerFor2(client).debug(`[${requestLogID}] response parsed`, formatRequestDetails2({
|
|
44339
44377
|
retryOfRequestLogID,
|
|
@@ -50926,9 +50964,9 @@ function decodeSseLine(line, state) {
|
|
|
50926
50964
|
}
|
|
50927
50965
|
return null;
|
|
50928
50966
|
}
|
|
50929
|
-
function nextLineBreakIndex(
|
|
50930
|
-
const carriageReturnIndex =
|
|
50931
|
-
const newlineIndex =
|
|
50967
|
+
function nextLineBreakIndex(text2) {
|
|
50968
|
+
const carriageReturnIndex = text2.indexOf("\r");
|
|
50969
|
+
const newlineIndex = text2.indexOf("\n");
|
|
50932
50970
|
if (carriageReturnIndex === -1) {
|
|
50933
50971
|
return newlineIndex;
|
|
50934
50972
|
}
|
|
@@ -50937,18 +50975,18 @@ function nextLineBreakIndex(text) {
|
|
|
50937
50975
|
}
|
|
50938
50976
|
return Math.min(carriageReturnIndex, newlineIndex);
|
|
50939
50977
|
}
|
|
50940
|
-
function consumeLine(
|
|
50941
|
-
const lineBreakIndex = nextLineBreakIndex(
|
|
50978
|
+
function consumeLine(text2) {
|
|
50979
|
+
const lineBreakIndex = nextLineBreakIndex(text2);
|
|
50942
50980
|
if (lineBreakIndex === -1) {
|
|
50943
50981
|
return null;
|
|
50944
50982
|
}
|
|
50945
50983
|
let nextIndex = lineBreakIndex + 1;
|
|
50946
|
-
if (
|
|
50984
|
+
if (text2[lineBreakIndex] === "\r" && text2[nextIndex] === "\n") {
|
|
50947
50985
|
nextIndex += 1;
|
|
50948
50986
|
}
|
|
50949
50987
|
return {
|
|
50950
|
-
line:
|
|
50951
|
-
rest:
|
|
50988
|
+
line: text2.slice(0, lineBreakIndex),
|
|
50989
|
+
rest: text2.slice(nextIndex)
|
|
50952
50990
|
};
|
|
50953
50991
|
}
|
|
50954
50992
|
async function* iterateSseMessages(body, signal) {
|
|
@@ -53115,8 +53153,8 @@ var require_common = __commonJS({
|
|
|
53115
53153
|
}
|
|
53116
53154
|
function redactString(obj, key) {
|
|
53117
53155
|
if (typeof obj === "object" && obj !== null && typeof obj[key] === "string") {
|
|
53118
|
-
const
|
|
53119
|
-
if (/grant_type=/i.test(
|
|
53156
|
+
const text2 = obj[key];
|
|
53157
|
+
if (/grant_type=/i.test(text2) || /assertion=/i.test(text2) || /secret/i.test(text2)) {
|
|
53120
53158
|
obj[key] = REDACT;
|
|
53121
53159
|
}
|
|
53122
53160
|
}
|
|
@@ -59944,8 +59982,8 @@ var init_body = __esm({
|
|
|
59944
59982
|
* @return Promise
|
|
59945
59983
|
*/
|
|
59946
59984
|
async json() {
|
|
59947
|
-
const
|
|
59948
|
-
return JSON.parse(
|
|
59985
|
+
const text2 = await this.text();
|
|
59986
|
+
return JSON.parse(text2);
|
|
59949
59987
|
}
|
|
59950
59988
|
/**
|
|
59951
59989
|
* Decode response as text
|
|
@@ -61097,7 +61135,7 @@ var require_gaxios = __commonJS({
|
|
|
61097
61135
|
var retry_js_1 = require_retry3();
|
|
61098
61136
|
var stream_1 = __require("stream");
|
|
61099
61137
|
var interceptor_js_1 = require_interceptor();
|
|
61100
|
-
var
|
|
61138
|
+
var randomUUID11 = async () => globalThis.crypto?.randomUUID() || (await import("crypto")).randomUUID();
|
|
61101
61139
|
var HTTP_STATUS_NO_CONTENT = 204;
|
|
61102
61140
|
var Gaxios = class {
|
|
61103
61141
|
agentCache = /* @__PURE__ */ new Map();
|
|
@@ -61370,7 +61408,7 @@ var require_gaxios = __commonJS({
|
|
|
61370
61408
|
*/
|
|
61371
61409
|
["Blob", "File", "FormData"].includes(opts.data?.constructor?.name || "");
|
|
61372
61410
|
if (opts.multipart?.length) {
|
|
61373
|
-
const boundary = await
|
|
61411
|
+
const boundary = await randomUUID11();
|
|
61374
61412
|
preparedHeaders.set("content-type", `multipart/related; boundary=${boundary}`);
|
|
61375
61413
|
opts.body = stream_1.Readable.from(this.getMultipartRequest(opts.multipart, boundary));
|
|
61376
61414
|
} else if (shouldDirectlyPassData) {
|
|
@@ -63121,18 +63159,18 @@ var require_parse = __commonJS({
|
|
|
63121
63159
|
n: "\n",
|
|
63122
63160
|
r: "\r",
|
|
63123
63161
|
t: " "
|
|
63124
|
-
},
|
|
63162
|
+
}, text2, error = function(m2) {
|
|
63125
63163
|
throw {
|
|
63126
63164
|
name: "SyntaxError",
|
|
63127
63165
|
message: m2,
|
|
63128
63166
|
at,
|
|
63129
|
-
text
|
|
63167
|
+
text: text2
|
|
63130
63168
|
};
|
|
63131
63169
|
}, next = function(c) {
|
|
63132
63170
|
if (c && c !== ch) {
|
|
63133
63171
|
error("Expected '" + c + "' instead of '" + ch + "'");
|
|
63134
63172
|
}
|
|
63135
|
-
ch =
|
|
63173
|
+
ch = text2.charAt(at);
|
|
63136
63174
|
at += 1;
|
|
63137
63175
|
return ch;
|
|
63138
63176
|
}, number44 = function() {
|
|
@@ -63179,12 +63217,12 @@ var require_parse = __commonJS({
|
|
|
63179
63217
|
var startAt = at;
|
|
63180
63218
|
while (next()) {
|
|
63181
63219
|
if (ch === '"') {
|
|
63182
|
-
if (at - 1 > startAt) string474 +=
|
|
63220
|
+
if (at - 1 > startAt) string474 += text2.substring(startAt, at - 1);
|
|
63183
63221
|
next();
|
|
63184
63222
|
return string474;
|
|
63185
63223
|
}
|
|
63186
63224
|
if (ch === "\\") {
|
|
63187
|
-
if (at - 1 > startAt) string474 +=
|
|
63225
|
+
if (at - 1 > startAt) string474 += text2.substring(startAt, at - 1);
|
|
63188
63226
|
next();
|
|
63189
63227
|
if (ch === "u") {
|
|
63190
63228
|
uffff = 0;
|
|
@@ -63317,7 +63355,7 @@ var require_parse = __commonJS({
|
|
|
63317
63355
|
};
|
|
63318
63356
|
return function(source, reviver) {
|
|
63319
63357
|
var result;
|
|
63320
|
-
|
|
63358
|
+
text2 = source + "";
|
|
63321
63359
|
at = 0;
|
|
63322
63360
|
ch = " ";
|
|
63323
63361
|
result = value();
|
|
@@ -64229,8 +64267,8 @@ var require_crypto = __commonJS({
|
|
|
64229
64267
|
const result = new TextDecoder().decode(uint8array);
|
|
64230
64268
|
return result;
|
|
64231
64269
|
}
|
|
64232
|
-
encodeBase64StringUtf8(
|
|
64233
|
-
const uint8array = new TextEncoder().encode(
|
|
64270
|
+
encodeBase64StringUtf8(text2) {
|
|
64271
|
+
const uint8array = new TextEncoder().encode(text2);
|
|
64234
64272
|
const result = base64js.fromByteArray(uint8array);
|
|
64235
64273
|
return result;
|
|
64236
64274
|
}
|
|
@@ -64299,8 +64337,8 @@ var require_crypto2 = __commonJS({
|
|
|
64299
64337
|
decodeBase64StringUtf8(base64) {
|
|
64300
64338
|
return Buffer.from(base64, "base64").toString("utf-8");
|
|
64301
64339
|
}
|
|
64302
|
-
encodeBase64StringUtf8(
|
|
64303
|
-
return Buffer.from(
|
|
64340
|
+
encodeBase64StringUtf8(text2) {
|
|
64341
|
+
return Buffer.from(text2, "utf-8").toString("base64");
|
|
64304
64342
|
}
|
|
64305
64343
|
/**
|
|
64306
64344
|
* Computes the SHA-256 hash of the provided string.
|
|
@@ -84745,8 +84783,8 @@ async function defaultParseResponse3(client, props) {
|
|
|
84745
84783
|
const json2 = await response.json();
|
|
84746
84784
|
return json2;
|
|
84747
84785
|
}
|
|
84748
|
-
const
|
|
84749
|
-
return
|
|
84786
|
+
const text2 = await response.text();
|
|
84787
|
+
return text2;
|
|
84750
84788
|
})();
|
|
84751
84789
|
loggerFor3(client).debug(`[${requestLogID}] response parsed`, formatRequestDetails3({
|
|
84752
84790
|
retryOfRequestLogID,
|
|
@@ -86323,7 +86361,7 @@ var init_node = __esm({
|
|
|
86323
86361
|
if (this.candidates && this.candidates.length > 1) {
|
|
86324
86362
|
console.warn("there are multiple candidates in the response, returning text from the first one.");
|
|
86325
86363
|
}
|
|
86326
|
-
let
|
|
86364
|
+
let text2 = "";
|
|
86327
86365
|
let anyTextPartText = false;
|
|
86328
86366
|
const nonTextParts = [];
|
|
86329
86367
|
for (const part of (_h = (_g = (_f = (_e = this.candidates) === null || _e === void 0 ? void 0 : _e[0]) === null || _f === void 0 ? void 0 : _f.content) === null || _g === void 0 ? void 0 : _g.parts) !== null && _h !== void 0 ? _h : []) {
|
|
@@ -86337,13 +86375,13 @@ var init_node = __esm({
|
|
|
86337
86375
|
continue;
|
|
86338
86376
|
}
|
|
86339
86377
|
anyTextPartText = true;
|
|
86340
|
-
|
|
86378
|
+
text2 += part.text;
|
|
86341
86379
|
}
|
|
86342
86380
|
}
|
|
86343
86381
|
if (nonTextParts.length > 0) {
|
|
86344
86382
|
console.warn(`there are non-text parts ${nonTextParts} in the response, returning concatenation of all text parts. Please refer to the non text parts for a full response from model.`);
|
|
86345
86383
|
}
|
|
86346
|
-
return anyTextPartText ?
|
|
86384
|
+
return anyTextPartText ? text2 : void 0;
|
|
86347
86385
|
}
|
|
86348
86386
|
/**
|
|
86349
86387
|
* Returns the concatenation of all inline data parts from the first candidate
|
|
@@ -86596,7 +86634,7 @@ var init_node = __esm({
|
|
|
86596
86634
|
*/
|
|
86597
86635
|
get text() {
|
|
86598
86636
|
var _a5, _b, _c;
|
|
86599
|
-
let
|
|
86637
|
+
let text2 = "";
|
|
86600
86638
|
let anyTextPartFound = false;
|
|
86601
86639
|
const nonTextParts = [];
|
|
86602
86640
|
for (const part of (_c = (_b = (_a5 = this.serverContent) === null || _a5 === void 0 ? void 0 : _a5.modelTurn) === null || _b === void 0 ? void 0 : _b.parts) !== null && _c !== void 0 ? _c : []) {
|
|
@@ -86610,13 +86648,13 @@ var init_node = __esm({
|
|
|
86610
86648
|
continue;
|
|
86611
86649
|
}
|
|
86612
86650
|
anyTextPartFound = true;
|
|
86613
|
-
|
|
86651
|
+
text2 += part.text;
|
|
86614
86652
|
}
|
|
86615
86653
|
}
|
|
86616
86654
|
if (nonTextParts.length > 0) {
|
|
86617
86655
|
console.warn(`there are non-text parts ${nonTextParts} in the response, returning concatenation of all text parts. Please refer to the non text parts for a full response from model.`);
|
|
86618
86656
|
}
|
|
86619
|
-
return anyTextPartFound ?
|
|
86657
|
+
return anyTextPartFound ? text2 : void 0;
|
|
86620
86658
|
}
|
|
86621
86659
|
/**
|
|
86622
86660
|
* Returns the concatenation of all inline data parts from the server content if present.
|
|
@@ -91288,9 +91326,9 @@ var init_node = __esm({
|
|
|
91288
91326
|
}
|
|
91289
91327
|
return n;
|
|
91290
91328
|
};
|
|
91291
|
-
safeJSON3 = (
|
|
91329
|
+
safeJSON3 = (text2) => {
|
|
91292
91330
|
try {
|
|
91293
|
-
return JSON.parse(
|
|
91331
|
+
return JSON.parse(text2);
|
|
91294
91332
|
} catch (err) {
|
|
91295
91333
|
return void 0;
|
|
91296
91334
|
}
|
|
@@ -109153,8 +109191,8 @@ function findBoundary(buf) {
|
|
|
109153
109191
|
return null;
|
|
109154
109192
|
}
|
|
109155
109193
|
function parseMessage2(chunk, parse2, state, dataRequired) {
|
|
109156
|
-
const
|
|
109157
|
-
const lines =
|
|
109194
|
+
const text2 = new TextDecoder().decode(chunk);
|
|
109195
|
+
const lines = text2.split(/\r\n|\r|\n/);
|
|
109158
109196
|
const dataLines = [];
|
|
109159
109197
|
const ret = {};
|
|
109160
109198
|
let ignore = true;
|
|
@@ -132028,10 +132066,10 @@ function formatMistralError(error) {
|
|
|
132028
132066
|
}
|
|
132029
132067
|
return safeJsonStringify(error);
|
|
132030
132068
|
}
|
|
132031
|
-
function truncateErrorText(
|
|
132032
|
-
if (
|
|
132033
|
-
return
|
|
132034
|
-
return `${
|
|
132069
|
+
function truncateErrorText(text2, maxChars) {
|
|
132070
|
+
if (text2.length <= maxChars)
|
|
132071
|
+
return text2;
|
|
132072
|
+
return `${text2.slice(0, maxChars)}... [truncated ${text2.length - maxChars} chars]`;
|
|
132035
132073
|
}
|
|
132036
132074
|
function safeJsonStringify(value) {
|
|
132037
132075
|
try {
|
|
@@ -132151,7 +132189,7 @@ async function consumeChatStream(model, output, stream2, mistralStream) {
|
|
|
132151
132189
|
continue;
|
|
132152
132190
|
}
|
|
132153
132191
|
if (item.type === "thinking") {
|
|
132154
|
-
const deltaText = item.thinking.map((part) => "text" in part ? part.text : "").filter((
|
|
132192
|
+
const deltaText = item.thinking.map((part) => "text" in part ? part.text : "").filter((text2) => text2.length > 0).join("");
|
|
132155
132193
|
const thinkingDelta = sanitizeSurrogates(deltaText);
|
|
132156
132194
|
if (!thinkingDelta)
|
|
132157
132195
|
continue;
|
|
@@ -132348,8 +132386,8 @@ function toChatMessages(messages, supportsImages) {
|
|
|
132348
132386
|
}
|
|
132349
132387
|
return result;
|
|
132350
132388
|
}
|
|
132351
|
-
function buildToolResultText(
|
|
132352
|
-
const trimmed =
|
|
132389
|
+
function buildToolResultText(text2, hasImages, supportsImages, isError) {
|
|
132390
|
+
const trimmed = text2.trim();
|
|
132353
132391
|
const errorPrefix = isError ? "[tool error] " : "";
|
|
132354
132392
|
if (trimmed.length > 0) {
|
|
132355
132393
|
const imageSuffix = hasImages && !supportsImages ? "\n[tool image omitted: model does not support images]" : "";
|
|
@@ -133150,14 +133188,14 @@ async function* parseWebSocket(socket, signal, idleTimeoutMs) {
|
|
|
133150
133188
|
};
|
|
133151
133189
|
const onMessage = (event) => {
|
|
133152
133190
|
void (async () => {
|
|
133153
|
-
let
|
|
133191
|
+
let text2 = null;
|
|
133154
133192
|
try {
|
|
133155
133193
|
if (!event || typeof event !== "object" || !("data" in event))
|
|
133156
133194
|
return;
|
|
133157
|
-
|
|
133158
|
-
if (!
|
|
133195
|
+
text2 = await decodeWebSocketData(event.data);
|
|
133196
|
+
if (!text2)
|
|
133159
133197
|
return;
|
|
133160
|
-
const parsed = JSON.parse(
|
|
133198
|
+
const parsed = JSON.parse(text2);
|
|
133161
133199
|
const type = typeof parsed.type === "string" ? parsed.type : "";
|
|
133162
133200
|
if (type === "response.completed" || type === "response.done" || type === "response.incomplete") {
|
|
133163
133201
|
sawCompletion = true;
|
|
@@ -133168,7 +133206,7 @@ async function* parseWebSocket(socket, signal, idleTimeoutMs) {
|
|
|
133168
133206
|
} catch (cause) {
|
|
133169
133207
|
failed = new CodexProtocolError(`Invalid Codex WebSocket JSON: ${formatThrownValue(cause)}`, {
|
|
133170
133208
|
cause,
|
|
133171
|
-
payload:
|
|
133209
|
+
payload: text2
|
|
133172
133210
|
});
|
|
133173
133211
|
done = true;
|
|
133174
133212
|
wake();
|
|
@@ -141332,11 +141370,11 @@ function videoRequestConfig(input) {
|
|
|
141332
141370
|
};
|
|
141333
141371
|
}
|
|
141334
141372
|
async function readMiniMaxJson(response) {
|
|
141335
|
-
const
|
|
141373
|
+
const text2 = await response.text();
|
|
141336
141374
|
let body = {};
|
|
141337
|
-
if (
|
|
141375
|
+
if (text2) {
|
|
141338
141376
|
try {
|
|
141339
|
-
const parsed = JSON.parse(
|
|
141377
|
+
const parsed = JSON.parse(text2);
|
|
141340
141378
|
if (isRecord(parsed)) body = parsed;
|
|
141341
141379
|
} catch {
|
|
141342
141380
|
throw new Error("MiniMax video API returned invalid JSON");
|
|
@@ -142157,6 +142195,7 @@ __export(store_exports, {
|
|
|
142157
142195
|
CodeGraphStore: () => CodeGraphStore
|
|
142158
142196
|
});
|
|
142159
142197
|
import { randomUUID as randomUUID6 } from "crypto";
|
|
142198
|
+
import { posix as pathPosix } from "path";
|
|
142160
142199
|
function rowToFile(row) {
|
|
142161
142200
|
return {
|
|
142162
142201
|
id: row.id,
|
|
@@ -142207,6 +142246,26 @@ function rowToEdge(row) {
|
|
|
142207
142246
|
...row.sourceEpoch != null ? { sourceEpoch: Number(row.sourceEpoch) } : {}
|
|
142208
142247
|
};
|
|
142209
142248
|
}
|
|
142249
|
+
function resolveRelativeImportTarget(sourcePath, evidence, fileByPath) {
|
|
142250
|
+
const target = evidence?.trim().replace(/\\/g, "/");
|
|
142251
|
+
if (!target?.startsWith(".")) return void 0;
|
|
142252
|
+
const base = normalizeCodePath(pathPosix.normalize(pathPosix.join(pathPosix.dirname(sourcePath), target)));
|
|
142253
|
+
if (!base || base === ".." || base.startsWith("../")) return void 0;
|
|
142254
|
+
const candidates = [base];
|
|
142255
|
+
const extensionMatch = base.match(/(\.[A-Za-z0-9]+)$/);
|
|
142256
|
+
const hasExtension = Boolean(extensionMatch);
|
|
142257
|
+
if (!hasExtension) {
|
|
142258
|
+
const extensions = [...new Set([...fileByPath.keys()].map((path19) => path19.match(/(\.[A-Za-z0-9]+)$/)?.[1]).filter((extension3) => Boolean(extension3)))];
|
|
142259
|
+
for (const extension3 of extensions) {
|
|
142260
|
+
candidates.push(`${base}${extension3}`, `${base}/index${extension3}`);
|
|
142261
|
+
}
|
|
142262
|
+
} else {
|
|
142263
|
+
const sourceStem = base.slice(0, -extensionMatch[1].length);
|
|
142264
|
+
const sourceExtensions = extensionMatch[1] === ".js" ? [".ts", ".tsx", ".js", ".jsx"] : extensionMatch[1] === ".mjs" ? [".mts", ".mjs"] : extensionMatch[1] === ".cjs" ? [".cts", ".cjs"] : [];
|
|
142265
|
+
for (const extension3 of sourceExtensions) candidates.push(`${sourceStem}${extension3}`);
|
|
142266
|
+
}
|
|
142267
|
+
return candidates.map((candidate) => fileByPath.get(candidate)).find((file) => Boolean(file));
|
|
142268
|
+
}
|
|
142210
142269
|
function rowToRef(row) {
|
|
142211
142270
|
return {
|
|
142212
142271
|
id: row.id,
|
|
@@ -142267,6 +142326,18 @@ function rowToSnapshot(row) {
|
|
|
142267
142326
|
...row.previousSnapshotId ? { previousSnapshotId: row.previousSnapshotId } : {}
|
|
142268
142327
|
};
|
|
142269
142328
|
}
|
|
142329
|
+
function rowToSnapshotFile(row) {
|
|
142330
|
+
return {
|
|
142331
|
+
snapshotId: row.snapshotId,
|
|
142332
|
+
projectId: row.projectId,
|
|
142333
|
+
fileId: row.fileId,
|
|
142334
|
+
path: row.path,
|
|
142335
|
+
contentHash: row.contentHash
|
|
142336
|
+
};
|
|
142337
|
+
}
|
|
142338
|
+
function snapshotIsIncomplete(snapshot) {
|
|
142339
|
+
return snapshot.completeness.skippedOversizedFiles > 0 || (snapshot.completeness.unreadableFiles ?? 0) > 0 || snapshot.completeness.removalScanDeferred;
|
|
142340
|
+
}
|
|
142270
142341
|
var CodeGraphStore;
|
|
142271
142342
|
var init_store = __esm({
|
|
142272
142343
|
"src/codegraph/store.ts"() {
|
|
@@ -142438,6 +142509,7 @@ var init_store = __esm({
|
|
|
142438
142509
|
}
|
|
142439
142510
|
});
|
|
142440
142511
|
tx();
|
|
142512
|
+
this.reconcileLocalImportTargets(projectId);
|
|
142441
142513
|
}
|
|
142442
142514
|
/**
|
|
142443
142515
|
* Reconcile only files whose source changed plus files that disappeared.
|
|
@@ -142447,7 +142519,10 @@ var init_store = __esm({
|
|
|
142447
142519
|
const changed = input.changed.filter((delta) => delta.file.projectId === projectId);
|
|
142448
142520
|
const metadataOnly = (input.metadataOnly ?? []).filter((file) => file.projectId === projectId);
|
|
142449
142521
|
const removedFileIds = input.removedFileIds ?? [];
|
|
142450
|
-
if (changed.length === 0 && metadataOnly.length === 0 && removedFileIds.length === 0)
|
|
142522
|
+
if (changed.length === 0 && metadataOnly.length === 0 && removedFileIds.length === 0) {
|
|
142523
|
+
this.reconcileLocalImportTargets(projectId);
|
|
142524
|
+
return;
|
|
142525
|
+
}
|
|
142451
142526
|
const staleRefsForFile = this.db.prepare(`
|
|
142452
142527
|
UPDATE observation_code_refs
|
|
142453
142528
|
SET status = 'stale', updatedAt = ?
|
|
@@ -142457,9 +142532,18 @@ var init_store = __esm({
|
|
|
142457
142532
|
)
|
|
142458
142533
|
)
|
|
142459
142534
|
`);
|
|
142460
|
-
const
|
|
142535
|
+
const deleteEdgesFromFile = this.db.prepare(`
|
|
142536
|
+
DELETE FROM code_edges
|
|
142537
|
+
WHERE projectId = ? AND fromFileId = ?
|
|
142538
|
+
`);
|
|
142539
|
+
const clearImportTargetsForFile = this.db.prepare(`
|
|
142540
|
+
UPDATE code_edges
|
|
142541
|
+
SET toFileId = NULL
|
|
142542
|
+
WHERE projectId = ? AND toFileId = ? AND type = 'imports'
|
|
142543
|
+
`);
|
|
142544
|
+
const deleteOtherIncomingEdgesForFile = this.db.prepare(`
|
|
142461
142545
|
DELETE FROM code_edges
|
|
142462
|
-
WHERE projectId = ? AND
|
|
142546
|
+
WHERE projectId = ? AND toFileId = ? AND type != 'imports'
|
|
142463
142547
|
`);
|
|
142464
142548
|
const deleteSymbolsForFile = this.db.prepare(`DELETE FROM code_symbols WHERE projectId = ? AND fileId = ?`);
|
|
142465
142549
|
const deleteFile = this.db.prepare(`DELETE FROM code_files WHERE projectId = ? AND id = ?`);
|
|
@@ -142496,14 +142580,18 @@ var init_store = __esm({
|
|
|
142496
142580
|
const staleAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
142497
142581
|
for (const fileId of removedFileIds) {
|
|
142498
142582
|
staleRefsForFile.run(staleAt, projectId, fileId, projectId, fileId);
|
|
142499
|
-
|
|
142583
|
+
deleteEdgesFromFile.run(projectId, fileId);
|
|
142584
|
+
clearImportTargetsForFile.run(projectId, fileId);
|
|
142585
|
+
deleteOtherIncomingEdgesForFile.run(projectId, fileId);
|
|
142500
142586
|
deleteSymbolsForFile.run(projectId, fileId);
|
|
142501
142587
|
deleteFile.run(projectId, fileId);
|
|
142502
142588
|
}
|
|
142503
142589
|
for (const delta of changed) {
|
|
142504
142590
|
const fileId = delta.file.id;
|
|
142505
142591
|
staleRefsForFile.run(staleAt, projectId, fileId, projectId, fileId);
|
|
142506
|
-
|
|
142592
|
+
deleteEdgesFromFile.run(projectId, fileId);
|
|
142593
|
+
clearImportTargetsForFile.run(projectId, fileId);
|
|
142594
|
+
deleteOtherIncomingEdgesForFile.run(projectId, fileId);
|
|
142507
142595
|
deleteSymbolsForFile.run(projectId, fileId);
|
|
142508
142596
|
writeFile5(delta.file);
|
|
142509
142597
|
for (const symbol of delta.symbols) {
|
|
@@ -142541,6 +142629,7 @@ var init_store = __esm({
|
|
|
142541
142629
|
for (const file of metadataOnly) writeFile5(file);
|
|
142542
142630
|
});
|
|
142543
142631
|
tx();
|
|
142632
|
+
this.reconcileLocalImportTargets(projectId);
|
|
142544
142633
|
}
|
|
142545
142634
|
upsertObservationRefs(refs) {
|
|
142546
142635
|
if (refs.length === 0) return;
|
|
@@ -142602,6 +142691,25 @@ var init_store = __esm({
|
|
|
142602
142691
|
});
|
|
142603
142692
|
tx();
|
|
142604
142693
|
}
|
|
142694
|
+
/**
|
|
142695
|
+
* Lite import extraction records the original import text first. Resolve only
|
|
142696
|
+
* local relative imports against the current index after each refresh, so an
|
|
142697
|
+
* added or removed target cannot leave a fabricated file-to-file relation.
|
|
142698
|
+
*/
|
|
142699
|
+
reconcileLocalImportTargets(projectId) {
|
|
142700
|
+
const fileById = new Map(this.listFiles(projectId).map((file) => [file.id, file]));
|
|
142701
|
+
const fileByPath = new Map([...fileById.values()].map((file) => [file.path, file]));
|
|
142702
|
+
const update2 = this.db.prepare("UPDATE code_edges SET toFileId = ? WHERE id = ?");
|
|
142703
|
+
const tx = this.db.transaction(() => {
|
|
142704
|
+
for (const edge of this.listEdges(projectId)) {
|
|
142705
|
+
if (edge.type !== "imports" || !edge.fromFileId) continue;
|
|
142706
|
+
const source = fileById.get(edge.fromFileId);
|
|
142707
|
+
const target = source ? resolveRelativeImportTarget(source.path, edge.evidence, fileByPath) : void 0;
|
|
142708
|
+
update2.run(target?.id ?? null, edge.id);
|
|
142709
|
+
}
|
|
142710
|
+
});
|
|
142711
|
+
tx();
|
|
142712
|
+
}
|
|
142605
142713
|
getFile(projectId, path19) {
|
|
142606
142714
|
const row = this.db.prepare(`SELECT * FROM code_files WHERE projectId = ? AND path = ?`).get(projectId, normalizeCodePath(path19));
|
|
142607
142715
|
return row ? rowToFile(row) : null;
|
|
@@ -142676,6 +142784,18 @@ var init_store = __esm({
|
|
|
142676
142784
|
ORDER BY observationId, status, id
|
|
142677
142785
|
`).all(projectId).map(rowToRef);
|
|
142678
142786
|
}
|
|
142787
|
+
/** Count distinct observations whose binding to these exact files is stale. */
|
|
142788
|
+
countStaleObservationRefsForFiles(projectId, fileIds) {
|
|
142789
|
+
const ids = [...new Set(fileIds.filter(Boolean))];
|
|
142790
|
+
if (ids.length === 0) return 0;
|
|
142791
|
+
const placeholders = ids.map(() => "?").join(", ");
|
|
142792
|
+
const row = this.db.prepare(`
|
|
142793
|
+
SELECT COUNT(DISTINCT observationId) AS count
|
|
142794
|
+
FROM observation_code_refs
|
|
142795
|
+
WHERE projectId = ? AND status = 'stale' AND fileId IN (${placeholders})
|
|
142796
|
+
`).get(projectId, ...ids);
|
|
142797
|
+
return Number(row?.count ?? 0);
|
|
142798
|
+
}
|
|
142679
142799
|
listReferencedSymbols(projectId) {
|
|
142680
142800
|
return this.db.prepare(`
|
|
142681
142801
|
SELECT DISTINCT symbols.*
|
|
@@ -142697,6 +142817,94 @@ var init_store = __esm({
|
|
|
142697
142817
|
"SELECT * FROM code_state_snapshots WHERE projectId = ? ORDER BY sourceEpoch DESC LIMIT ?"
|
|
142698
142818
|
).all(projectId, safeLimit).map(rowToSnapshot);
|
|
142699
142819
|
}
|
|
142820
|
+
listSnapshotFiles(snapshotId) {
|
|
142821
|
+
return this.db.prepare(`
|
|
142822
|
+
SELECT snapshotId, projectId, fileId, path, contentHash
|
|
142823
|
+
FROM code_state_snapshot_files
|
|
142824
|
+
WHERE snapshotId = ?
|
|
142825
|
+
ORDER BY path
|
|
142826
|
+
`).all(snapshotId).map(rowToSnapshotFile);
|
|
142827
|
+
}
|
|
142828
|
+
diffSnapshots(projectId, fromSnapshotId, toSnapshotId) {
|
|
142829
|
+
const snapshots = this.db.prepare(`
|
|
142830
|
+
SELECT * FROM code_state_snapshots WHERE id IN (?, ?)
|
|
142831
|
+
`).all(fromSnapshotId, toSnapshotId).map(rowToSnapshot);
|
|
142832
|
+
if (snapshots.length !== 2) {
|
|
142833
|
+
return { projectId, fromSnapshotId, toSnapshotId, available: false, reason: "missing-snapshot", changes: [] };
|
|
142834
|
+
}
|
|
142835
|
+
if (snapshots.some((snapshot) => snapshot.projectId !== projectId)) {
|
|
142836
|
+
return { projectId, fromSnapshotId, toSnapshotId, available: false, reason: "project-mismatch", changes: [] };
|
|
142837
|
+
}
|
|
142838
|
+
if (snapshots.some(snapshotIsIncomplete)) {
|
|
142839
|
+
return { projectId, fromSnapshotId, toSnapshotId, available: false, reason: "incomplete-snapshot", changes: [] };
|
|
142840
|
+
}
|
|
142841
|
+
const before = this.listSnapshotFiles(fromSnapshotId);
|
|
142842
|
+
const after = this.listSnapshotFiles(toSnapshotId);
|
|
142843
|
+
if (before.length === 0 || after.length === 0) {
|
|
142844
|
+
return {
|
|
142845
|
+
projectId,
|
|
142846
|
+
fromSnapshotId,
|
|
142847
|
+
toSnapshotId,
|
|
142848
|
+
available: false,
|
|
142849
|
+
reason: "legacy-snapshot-without-manifest",
|
|
142850
|
+
changes: []
|
|
142851
|
+
};
|
|
142852
|
+
}
|
|
142853
|
+
const beforeByPath = new Map(before.map((file) => [file.path, file]));
|
|
142854
|
+
const afterByPath = new Map(after.map((file) => [file.path, file]));
|
|
142855
|
+
const paths = [.../* @__PURE__ */ new Set([...beforeByPath.keys(), ...afterByPath.keys()])].sort();
|
|
142856
|
+
const changes = [];
|
|
142857
|
+
for (const path19 of paths) {
|
|
142858
|
+
const oldFile = beforeByPath.get(path19);
|
|
142859
|
+
const newFile = afterByPath.get(path19);
|
|
142860
|
+
if (!oldFile && newFile) {
|
|
142861
|
+
changes.push({ path: path19, kind: "added", afterHash: newFile.contentHash });
|
|
142862
|
+
} else if (oldFile && !newFile) {
|
|
142863
|
+
changes.push({ path: path19, kind: "removed", beforeHash: oldFile.contentHash });
|
|
142864
|
+
} else if (oldFile && newFile && oldFile.contentHash !== newFile.contentHash) {
|
|
142865
|
+
changes.push({ path: path19, kind: "modified", beforeHash: oldFile.contentHash, afterHash: newFile.contentHash });
|
|
142866
|
+
}
|
|
142867
|
+
}
|
|
142868
|
+
return { projectId, fromSnapshotId, toSnapshotId, available: true, changes };
|
|
142869
|
+
}
|
|
142870
|
+
impactSlice(projectId, changedPaths, maxRelations = 24) {
|
|
142871
|
+
const safeLimit = Number.isFinite(maxRelations) ? Math.max(1, Math.min(100, Math.floor(maxRelations))) : 24;
|
|
142872
|
+
const normalizedPaths = [...new Set(changedPaths.map(normalizeCodePath).filter(Boolean))].sort();
|
|
142873
|
+
const files = this.listFiles(projectId);
|
|
142874
|
+
const fileById = new Map(files.map((file) => [file.id, file.path]));
|
|
142875
|
+
const fileIdBySymbolId = new Map(this.listSymbols(projectId).map((symbol) => [symbol.id, symbol.fileId]));
|
|
142876
|
+
const changedIds = new Set(files.filter((file) => normalizedPaths.includes(file.path)).map((file) => file.id));
|
|
142877
|
+
const direct = /* @__PURE__ */ new Set();
|
|
142878
|
+
let relationCount = 0;
|
|
142879
|
+
let truncated = false;
|
|
142880
|
+
for (const edge of this.listEdges(projectId)) {
|
|
142881
|
+
const endpoints = [
|
|
142882
|
+
edge.fromFileId,
|
|
142883
|
+
edge.toFileId,
|
|
142884
|
+
edge.fromSymbolId ? fileIdBySymbolId.get(edge.fromSymbolId) : void 0,
|
|
142885
|
+
edge.toSymbolId ? fileIdBySymbolId.get(edge.toSymbolId) : void 0
|
|
142886
|
+
].filter((id) => Boolean(id));
|
|
142887
|
+
if (!endpoints.some((id) => changedIds.has(id))) continue;
|
|
142888
|
+
const relatedPaths = endpoints.filter((id) => !changedIds.has(id)).map((id) => fileById.get(id)).filter((path19) => Boolean(path19));
|
|
142889
|
+
if (relatedPaths.length === 0) continue;
|
|
142890
|
+
if (relationCount >= safeLimit) {
|
|
142891
|
+
truncated = true;
|
|
142892
|
+
break;
|
|
142893
|
+
}
|
|
142894
|
+
relationCount += 1;
|
|
142895
|
+
for (const path19 of relatedPaths) direct.add(path19);
|
|
142896
|
+
}
|
|
142897
|
+
const snapshot = this.latestSnapshot(projectId);
|
|
142898
|
+
return {
|
|
142899
|
+
projectId,
|
|
142900
|
+
...snapshot ? { snapshotId: snapshot.id } : {},
|
|
142901
|
+
changedPaths: normalizedPaths,
|
|
142902
|
+
directlyConnectedPaths: [...direct].sort(),
|
|
142903
|
+
relationCount,
|
|
142904
|
+
truncated,
|
|
142905
|
+
provider: snapshot?.provider ?? "lite"
|
|
142906
|
+
};
|
|
142907
|
+
}
|
|
142700
142908
|
/**
|
|
142701
142909
|
* Record a completed scan and mark all current structural facts with its
|
|
142702
142910
|
* epoch. The snapshot is written only after refresh reconciliation succeeds,
|
|
@@ -142738,6 +142946,16 @@ var init_store = __esm({
|
|
|
142738
142946
|
this.db.prepare(
|
|
142739
142947
|
"UPDATE observation_code_refs SET snapshotId = ? WHERE projectId = ? AND status = 'current'"
|
|
142740
142948
|
).run(id, input.projectId);
|
|
142949
|
+
const snapshotFileRows = this.db.prepare(`
|
|
142950
|
+
SELECT id, projectId, path, contentHash FROM code_files WHERE projectId = ? ORDER BY path
|
|
142951
|
+
`).all(input.projectId);
|
|
142952
|
+
const insertSnapshotFile = this.db.prepare(`
|
|
142953
|
+
INSERT INTO code_state_snapshot_files (snapshotId, projectId, fileId, path, contentHash)
|
|
142954
|
+
VALUES (?, ?, ?, ?, ?)
|
|
142955
|
+
`);
|
|
142956
|
+
for (const file of snapshotFileRows) {
|
|
142957
|
+
insertSnapshotFile.run(id, file.projectId, file.id, file.path, file.contentHash);
|
|
142958
|
+
}
|
|
142741
142959
|
snapshot = {
|
|
142742
142960
|
...input,
|
|
142743
142961
|
id,
|
|
@@ -142903,8 +143121,8 @@ __export(lite_provider_exports, {
|
|
|
142903
143121
|
import { createHash as createHash7 } from "crypto";
|
|
142904
143122
|
import { readdirSync as readdirSync2, readFileSync as readFileSync6, statSync as statSync3 } from "fs";
|
|
142905
143123
|
import { join as join4, relative } from "path";
|
|
142906
|
-
function hashText(
|
|
142907
|
-
return createHash7("sha256").update(
|
|
143124
|
+
function hashText(text2) {
|
|
143125
|
+
return createHash7("sha256").update(text2).digest("hex");
|
|
142908
143126
|
}
|
|
142909
143127
|
function extension2(path19) {
|
|
142910
143128
|
const index = path19.lastIndexOf(".");
|
|
@@ -142948,19 +143166,19 @@ function walk(root, exclude, maxFiles) {
|
|
|
142948
143166
|
visit(root);
|
|
142949
143167
|
return out;
|
|
142950
143168
|
}
|
|
142951
|
-
function lineOf(
|
|
142952
|
-
return
|
|
143169
|
+
function lineOf(text2, index) {
|
|
143170
|
+
return text2.slice(0, index).split(/\r?\n/).length;
|
|
142953
143171
|
}
|
|
142954
|
-
function extractSymbols(projectId, file,
|
|
143172
|
+
function extractSymbols(projectId, file, text2, indexedAt) {
|
|
142955
143173
|
const symbols = [];
|
|
142956
143174
|
const profile = file.language ? languageProfiles[file.language] : void 0;
|
|
142957
143175
|
const patterns = profile?.symbols ?? [];
|
|
142958
143176
|
for (const { kind, re } of patterns) {
|
|
142959
143177
|
re.lastIndex = 0;
|
|
142960
|
-
for (const match2 of
|
|
143178
|
+
for (const match2 of text2.matchAll(re)) {
|
|
142961
143179
|
const name = match2[1];
|
|
142962
143180
|
if (!name || name.includes("\n")) continue;
|
|
142963
|
-
const startLine = lineOf(
|
|
143181
|
+
const startLine = lineOf(text2, match2.index ?? 0);
|
|
142964
143182
|
const id = makeCodeSymbolId({ projectId, path: file.path, qualifiedName: name, kind });
|
|
142965
143183
|
symbols.push({
|
|
142966
143184
|
id,
|
|
@@ -142980,13 +143198,13 @@ function extractSymbols(projectId, file, text, indexedAt) {
|
|
|
142980
143198
|
}
|
|
142981
143199
|
return symbols;
|
|
142982
143200
|
}
|
|
142983
|
-
function extractImportEdges(projectId, file,
|
|
143201
|
+
function extractImportEdges(projectId, file, text2, indexedAt) {
|
|
142984
143202
|
const edges = [];
|
|
142985
143203
|
const profile = file.language ? languageProfiles[file.language] : void 0;
|
|
142986
143204
|
const imports = profile?.imports ?? [];
|
|
142987
143205
|
for (const re of imports) {
|
|
142988
143206
|
re.lastIndex = 0;
|
|
142989
|
-
for (const match2 of
|
|
143207
|
+
for (const match2 of text2.matchAll(re)) {
|
|
142990
143208
|
const target = (match2[1] ?? "").trim();
|
|
142991
143209
|
if (!target) continue;
|
|
142992
143210
|
if (target.includes("\n")) {
|
|
@@ -143021,14 +143239,14 @@ function extractImportEdges(projectId, file, text, indexedAt) {
|
|
|
143021
143239
|
function indexFileLite(projectId, projectRoot, abs, indexedAt, fileStat) {
|
|
143022
143240
|
const rel = normalizeCodePath(relative(projectRoot, abs));
|
|
143023
143241
|
try {
|
|
143024
|
-
const
|
|
143242
|
+
const text2 = readFileSync6(abs, "utf-8");
|
|
143025
143243
|
const stat4 = fileStat ?? statSync3(abs);
|
|
143026
143244
|
const file = {
|
|
143027
143245
|
id: makeCodeFileId(projectId, rel),
|
|
143028
143246
|
projectId,
|
|
143029
143247
|
path: rel,
|
|
143030
143248
|
language: languageForPath(rel),
|
|
143031
|
-
contentHash: hashText(
|
|
143249
|
+
contentHash: hashText(text2),
|
|
143032
143250
|
// Preserve filesystem precision. Rounding here made same-size edits in
|
|
143033
143251
|
// a short Windows timestamp window indistinguishable to refresh.
|
|
143034
143252
|
mtimeMs: Number(stat4.mtimeMs),
|
|
@@ -143038,8 +143256,8 @@ function indexFileLite(projectId, projectRoot, abs, indexedAt, fileStat) {
|
|
|
143038
143256
|
return {
|
|
143039
143257
|
delta: {
|
|
143040
143258
|
file,
|
|
143041
|
-
symbols: extractSymbols(projectId, file,
|
|
143042
|
-
edges: extractImportEdges(projectId, file,
|
|
143259
|
+
symbols: extractSymbols(projectId, file, text2, indexedAt),
|
|
143260
|
+
edges: extractImportEdges(projectId, file, text2, indexedAt)
|
|
143043
143261
|
},
|
|
143044
143262
|
unreadable: false
|
|
143045
143263
|
};
|
|
@@ -143318,18 +143536,18 @@ __export(binder_exports, {
|
|
|
143318
143536
|
function observationText(obs) {
|
|
143319
143537
|
return [obs.title, obs.narrative, ...obs.facts ?? []].join("\n");
|
|
143320
143538
|
}
|
|
143321
|
-
function mentionsSymbol(
|
|
143539
|
+
function mentionsSymbol(text2, symbol) {
|
|
143322
143540
|
const name = symbol.name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
143323
|
-
return new RegExp(`(^|[^\\w$])${name}([^\\w$]|$)`).test(
|
|
143541
|
+
return new RegExp(`(^|[^\\w$])${name}([^\\w$]|$)`).test(text2);
|
|
143324
143542
|
}
|
|
143325
|
-
function identifierCandidates(
|
|
143326
|
-
return [...new Set(
|
|
143543
|
+
function identifierCandidates(text2) {
|
|
143544
|
+
return [...new Set(text2.match(/[A-Za-z_$][\w$]*(?:::[A-Za-z_$][\w$]*)*[!?=]?/g) ?? [])];
|
|
143327
143545
|
}
|
|
143328
|
-
function codeIdentifierCandidates(
|
|
143546
|
+
function codeIdentifierCandidates(text2) {
|
|
143329
143547
|
const explicit = /* @__PURE__ */ new Set();
|
|
143330
|
-
for (const match2 of
|
|
143331
|
-
for (const match2 of
|
|
143332
|
-
return identifierCandidates(
|
|
143548
|
+
for (const match2 of text2.matchAll(/`([A-Za-z_$][\w$]*(?:::[A-Za-z_$][\w$]*)*[!?=]?)`/g)) explicit.add(match2[1]);
|
|
143549
|
+
for (const match2 of text2.matchAll(/\b([A-Za-z_$][\w$]*(?:::[A-Za-z_$][\w$]*)*[!?=]?)\s*\(/g)) explicit.add(match2[1]);
|
|
143550
|
+
return identifierCandidates(text2).filter((candidate) => explicit.has(candidate) || candidate.includes("::") || /[!?=]$/.test(candidate) || /^[A-Z]/.test(candidate) || /[_$]/.test(candidate) || /[a-z0-9][A-Z]/.test(candidate) || /[A-Z]{2}/.test(candidate));
|
|
143333
143551
|
}
|
|
143334
143552
|
function fileRef(projectId, obs, file) {
|
|
143335
143553
|
return {
|
|
@@ -143359,7 +143577,7 @@ function symbolRef(projectId, obs, file, symbol) {
|
|
|
143359
143577
|
}
|
|
143360
143578
|
function resolveObservationCodeRefs(obs, lookup2) {
|
|
143361
143579
|
const refs = /* @__PURE__ */ new Map();
|
|
143362
|
-
const
|
|
143580
|
+
const text2 = observationText(obs);
|
|
143363
143581
|
const candidateFiles = /* @__PURE__ */ new Map();
|
|
143364
143582
|
for (const rawPath of obs.filesModified ?? []) {
|
|
143365
143583
|
const file = lookup2.findFile(normalizeCodePath(rawPath));
|
|
@@ -143369,7 +143587,7 @@ function resolveObservationCodeRefs(obs, lookup2) {
|
|
|
143369
143587
|
refs.set(ref.id, ref);
|
|
143370
143588
|
}
|
|
143371
143589
|
const hintedFileIds = new Set(candidateFiles.keys());
|
|
143372
|
-
const symbolNames = hintedFileIds.size > 0 ? identifierCandidates(
|
|
143590
|
+
const symbolNames = hintedFileIds.size > 0 ? identifierCandidates(text2) : codeIdentifierCandidates(text2);
|
|
143373
143591
|
const symbols = lookup2.findSymbols(symbolNames, [...hintedFileIds]);
|
|
143374
143592
|
const symbolsByName = /* @__PURE__ */ new Map();
|
|
143375
143593
|
for (const symbol of symbols) {
|
|
@@ -143380,7 +143598,7 @@ function resolveObservationCodeRefs(obs, lookup2) {
|
|
|
143380
143598
|
for (const group of symbolsByName.values()) {
|
|
143381
143599
|
const candidates = group.length === 1 ? group : [];
|
|
143382
143600
|
for (const symbol of candidates) {
|
|
143383
|
-
if (!mentionsSymbol(
|
|
143601
|
+
if (!mentionsSymbol(text2, symbol)) continue;
|
|
143384
143602
|
const file = candidateFiles.get(symbol.fileId) ?? lookup2.findFile(symbol.path);
|
|
143385
143603
|
if (!file) continue;
|
|
143386
143604
|
candidateFiles.set(file.id, file);
|
|
@@ -144108,8 +144326,8 @@ function taskTokens(task) {
|
|
|
144108
144326
|
return normalizedTokens(task);
|
|
144109
144327
|
}
|
|
144110
144328
|
function scoreClaim(claim, tokens) {
|
|
144111
|
-
const
|
|
144112
|
-
const words = normalizedTokens(
|
|
144329
|
+
const text2 = [claim.subject, claim.predicate, claim.objectValue].join(" ").toLocaleLowerCase("en-US");
|
|
144330
|
+
const words = normalizedTokens(text2);
|
|
144113
144331
|
let matches = 0;
|
|
144114
144332
|
for (const token of tokens) {
|
|
144115
144333
|
if (words.has(token)) matches += 1;
|
|
@@ -145005,29 +145223,141 @@ var init_workflow_store = __esm({
|
|
|
145005
145223
|
}
|
|
145006
145224
|
});
|
|
145007
145225
|
|
|
145226
|
+
// src/knowledge/outcome-types.ts
|
|
145227
|
+
var MEMORY_OUTCOME_CANDIDATE_KINDS, MEMORY_OUTCOME_SIGNAL_KINDS;
|
|
145228
|
+
var init_outcome_types = __esm({
|
|
145229
|
+
"src/knowledge/outcome-types.ts"() {
|
|
145230
|
+
"use strict";
|
|
145231
|
+
init_esm_shims();
|
|
145232
|
+
MEMORY_OUTCOME_CANDIDATE_KINDS = ["claim", "durable-memory", "workflow"];
|
|
145233
|
+
MEMORY_OUTCOME_SIGNAL_KINDS = [
|
|
145234
|
+
"verification-passed",
|
|
145235
|
+
"verification-failed",
|
|
145236
|
+
"verified-reuse",
|
|
145237
|
+
"user-pin",
|
|
145238
|
+
"user-correction",
|
|
145239
|
+
"source-changed",
|
|
145240
|
+
"conflict-confirmed",
|
|
145241
|
+
"manual-review"
|
|
145242
|
+
];
|
|
145243
|
+
}
|
|
145244
|
+
});
|
|
145245
|
+
|
|
145246
|
+
// src/knowledge/outcome-store.ts
|
|
145247
|
+
import { randomUUID as randomUUID10 } from "crypto";
|
|
145248
|
+
function optionalText4(value) {
|
|
145249
|
+
return typeof value === "string" && value.trim() ? value : void 0;
|
|
145250
|
+
}
|
|
145251
|
+
function text(value, field, max = 1e3) {
|
|
145252
|
+
const safe = sanitizeCredentials(value).replace(/\s+/g, " ").trim();
|
|
145253
|
+
if (!safe) throw new Error("Outcome signal " + field + " is required.");
|
|
145254
|
+
if (safe.length > max) throw new Error("Outcome signal " + field + " is too long.");
|
|
145255
|
+
return safe;
|
|
145256
|
+
}
|
|
145257
|
+
function oneOf(value, values, field) {
|
|
145258
|
+
if (typeof value !== "string" || !values.includes(value)) {
|
|
145259
|
+
throw new Error("Outcome signal " + field + " is invalid.");
|
|
145260
|
+
}
|
|
145261
|
+
return value;
|
|
145262
|
+
}
|
|
145263
|
+
function rowToSignal(row) {
|
|
145264
|
+
return {
|
|
145265
|
+
id: row.id,
|
|
145266
|
+
projectId: row.projectId,
|
|
145267
|
+
candidateKind: row.candidateKind,
|
|
145268
|
+
candidateId: row.candidateId,
|
|
145269
|
+
kind: row.kind,
|
|
145270
|
+
sourceRef: row.sourceRef,
|
|
145271
|
+
...optionalText4(row.snapshotId) ? { snapshotId: row.snapshotId } : {},
|
|
145272
|
+
...optionalText4(row.detail) ? { detail: row.detail } : {},
|
|
145273
|
+
observedAt: row.observedAt
|
|
145274
|
+
};
|
|
145275
|
+
}
|
|
145276
|
+
var OutcomeStore;
|
|
145277
|
+
var init_outcome_store = __esm({
|
|
145278
|
+
"src/knowledge/outcome-store.ts"() {
|
|
145279
|
+
"use strict";
|
|
145280
|
+
init_esm_shims();
|
|
145281
|
+
init_secret_filter();
|
|
145282
|
+
init_sqlite_db();
|
|
145283
|
+
init_outcome_types();
|
|
145284
|
+
OutcomeStore = class {
|
|
145285
|
+
db = null;
|
|
145286
|
+
async init(dataDir) {
|
|
145287
|
+
this.db = getDatabase(dataDir);
|
|
145288
|
+
}
|
|
145289
|
+
record(input) {
|
|
145290
|
+
const signal = {
|
|
145291
|
+
id: randomUUID10(),
|
|
145292
|
+
projectId: text(input.projectId, "project id"),
|
|
145293
|
+
candidateKind: oneOf(input.candidateKind, MEMORY_OUTCOME_CANDIDATE_KINDS, "candidate kind"),
|
|
145294
|
+
candidateId: text(input.candidateId, "candidate id"),
|
|
145295
|
+
kind: oneOf(input.kind, MEMORY_OUTCOME_SIGNAL_KINDS, "kind"),
|
|
145296
|
+
sourceRef: text(input.sourceRef, "source reference"),
|
|
145297
|
+
...input.snapshotId ? { snapshotId: text(input.snapshotId, "snapshot id") } : {},
|
|
145298
|
+
...input.detail ? { detail: text(input.detail, "detail") } : {},
|
|
145299
|
+
observedAt: input.observedAt ?? (/* @__PURE__ */ new Date()).toISOString()
|
|
145300
|
+
};
|
|
145301
|
+
this.db.prepare(`
|
|
145302
|
+
INSERT INTO memory_outcome_signals (
|
|
145303
|
+
id, projectId, candidateKind, candidateId, kind, sourceRef, snapshotId, detail, observedAt
|
|
145304
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
145305
|
+
`).run(
|
|
145306
|
+
signal.id,
|
|
145307
|
+
signal.projectId,
|
|
145308
|
+
signal.candidateKind,
|
|
145309
|
+
signal.candidateId,
|
|
145310
|
+
signal.kind,
|
|
145311
|
+
signal.sourceRef,
|
|
145312
|
+
signal.snapshotId ?? null,
|
|
145313
|
+
signal.detail ?? null,
|
|
145314
|
+
signal.observedAt
|
|
145315
|
+
);
|
|
145316
|
+
return signal;
|
|
145317
|
+
}
|
|
145318
|
+
latestForCandidates(projectId, candidateKind, candidateIds) {
|
|
145319
|
+
const ids = [...new Set(candidateIds.filter(Boolean))];
|
|
145320
|
+
if (ids.length === 0) return /* @__PURE__ */ new Map();
|
|
145321
|
+
const placeholders = ids.map(() => "?").join(", ");
|
|
145322
|
+
const rows = this.db.prepare(`
|
|
145323
|
+
SELECT * FROM memory_outcome_signals
|
|
145324
|
+
WHERE projectId = ? AND candidateKind = ? AND candidateId IN (${placeholders})
|
|
145325
|
+
ORDER BY observedAt DESC, id DESC
|
|
145326
|
+
`).all(projectId, candidateKind, ...ids);
|
|
145327
|
+
const latest = /* @__PURE__ */ new Map();
|
|
145328
|
+
for (const row of rows) {
|
|
145329
|
+
const signal = rowToSignal(row);
|
|
145330
|
+
if (!latest.has(signal.candidateId)) latest.set(signal.candidateId, signal);
|
|
145331
|
+
}
|
|
145332
|
+
return latest;
|
|
145333
|
+
}
|
|
145334
|
+
};
|
|
145335
|
+
}
|
|
145336
|
+
});
|
|
145337
|
+
|
|
145008
145338
|
// src/codegraph/task-lens.ts
|
|
145009
|
-
function containsTaskKeyword(
|
|
145339
|
+
function containsTaskKeyword(text2, keyword) {
|
|
145010
145340
|
const matcher = /^[a-z0-9_-]+$/i.test(keyword) ? new RegExp(`(^|[^a-z0-9_-])${keyword.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}(?=[^a-z0-9_-]|$)`, "gi") : new RegExp(keyword.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), "gi");
|
|
145011
145341
|
let match2;
|
|
145012
|
-
while ((match2 = matcher.exec(
|
|
145342
|
+
while ((match2 = matcher.exec(text2)) !== null) {
|
|
145013
145343
|
const keywordIndex = match2.index + (match2[1]?.length ?? 0);
|
|
145014
|
-
if (!isNegatedTaskKeyword(
|
|
145344
|
+
if (!isNegatedTaskKeyword(text2, keywordIndex)) return true;
|
|
145015
145345
|
}
|
|
145016
145346
|
return false;
|
|
145017
145347
|
}
|
|
145018
|
-
function isNegatedTaskKeyword(
|
|
145348
|
+
function isNegatedTaskKeyword(text2, keywordIndex) {
|
|
145019
145349
|
const boundary = Math.max(
|
|
145020
|
-
|
|
145021
|
-
|
|
145022
|
-
|
|
145023
|
-
|
|
145024
|
-
|
|
145025
|
-
|
|
145026
|
-
|
|
145027
|
-
|
|
145028
|
-
|
|
145350
|
+
text2.lastIndexOf(".", keywordIndex - 1),
|
|
145351
|
+
text2.lastIndexOf("!", keywordIndex - 1),
|
|
145352
|
+
text2.lastIndexOf("?", keywordIndex - 1),
|
|
145353
|
+
text2.lastIndexOf(";", keywordIndex - 1),
|
|
145354
|
+
text2.lastIndexOf("\n", keywordIndex - 1),
|
|
145355
|
+
text2.lastIndexOf("\u3002", keywordIndex - 1),
|
|
145356
|
+
text2.lastIndexOf("\uFF01", keywordIndex - 1),
|
|
145357
|
+
text2.lastIndexOf("\uFF1F", keywordIndex - 1),
|
|
145358
|
+
text2.lastIndexOf("\uFF1B", keywordIndex - 1)
|
|
145029
145359
|
);
|
|
145030
|
-
let prefix =
|
|
145360
|
+
let prefix = text2.slice(boundary + 1, keywordIndex).toLowerCase();
|
|
145031
145361
|
const contrast = /(?:,|\uff0c)\s*(?:but|however|instead|yet|\u4f46\u662f|\u4f46|\u800c\u662f)\s*/gi;
|
|
145032
145362
|
let contrastMatch;
|
|
145033
145363
|
let contrastEnd = -1;
|
|
@@ -145086,7 +145416,7 @@ function requiredText(data, key) {
|
|
|
145086
145416
|
}
|
|
145087
145417
|
return value.trim();
|
|
145088
145418
|
}
|
|
145089
|
-
function
|
|
145419
|
+
function optionalText5(data, key) {
|
|
145090
145420
|
const value = data[key];
|
|
145091
145421
|
if (value === void 0 || value === null || value === "") return void 0;
|
|
145092
145422
|
if (typeof value !== "string") throw new Error("workflow frontmatter field " + key + " must be text");
|
|
@@ -145129,11 +145459,11 @@ function phaseFromValue(value, index) {
|
|
|
145129
145459
|
}
|
|
145130
145460
|
const data = value;
|
|
145131
145461
|
const title = requiredText(data, "title");
|
|
145132
|
-
const phaseId =
|
|
145462
|
+
const phaseId = optionalText5(data, "id") ?? slug(title) + "-" + (index + 1);
|
|
145133
145463
|
return {
|
|
145134
145464
|
id: phaseId,
|
|
145135
145465
|
title,
|
|
145136
|
-
instructions:
|
|
145466
|
+
instructions: optionalText5(data, "instructions") ?? "",
|
|
145137
145467
|
branches: optionalStringArray(data, "branches"),
|
|
145138
145468
|
expectedOutputs: optionalStringArray(data, "expectedOutputs"),
|
|
145139
145469
|
verificationGates: optionalStringArray(data, "verificationGates")
|
|
@@ -145242,7 +145572,7 @@ function parsedWorkflow(data, body, input) {
|
|
|
145242
145572
|
id: requiredText(data, "id"),
|
|
145243
145573
|
workspaceId: input.workspaceId,
|
|
145244
145574
|
title: requiredText(data, "title"),
|
|
145245
|
-
description:
|
|
145575
|
+
description: optionalText5(data, "description") ?? "",
|
|
145246
145576
|
status: optionalStatus(data),
|
|
145247
145577
|
version: optionalNumber(data, "version", 1),
|
|
145248
145578
|
taskLenses: optionalStringArray(data, "taskLenses"),
|
|
@@ -145261,9 +145591,9 @@ function parsedWorkflow(data, body, input) {
|
|
|
145261
145591
|
sourcePath: normalizeSourcePath(input.sourcePath),
|
|
145262
145592
|
sourceHash: "",
|
|
145263
145593
|
contentHash: input.contentHash,
|
|
145264
|
-
createdAt:
|
|
145265
|
-
updatedAt:
|
|
145266
|
-
...
|
|
145594
|
+
createdAt: optionalText5(data, "createdAt") ?? now2(),
|
|
145595
|
+
updatedAt: optionalText5(data, "updatedAt") ?? now2(),
|
|
145596
|
+
...optionalText5(data, "importedFrom") ? { importedFrom: optionalText5(data, "importedFrom") } : {}
|
|
145267
145597
|
};
|
|
145268
145598
|
if (candidate.phases.length === 0) {
|
|
145269
145599
|
throw new Error("workflow must contain at least one phase or a non-empty body");
|
|
@@ -145362,11 +145692,11 @@ async function syncCanonicalWorkflows(workspace) {
|
|
|
145362
145692
|
return { workflows, errors };
|
|
145363
145693
|
}
|
|
145364
145694
|
function inferTaskLenses(value) {
|
|
145365
|
-
const
|
|
145366
|
-
return Object.entries(LENS_TERMS).filter(([, terms]) => terms.some((term) =>
|
|
145695
|
+
const text2 = value.toLowerCase();
|
|
145696
|
+
return Object.entries(LENS_TERMS).filter(([, terms]) => terms.some((term) => text2.includes(term))).map(([lens]) => lens);
|
|
145367
145697
|
}
|
|
145368
145698
|
function taskScore(workflow, task) {
|
|
145369
|
-
const
|
|
145699
|
+
const text2 = task.toLowerCase();
|
|
145370
145700
|
let score = 0;
|
|
145371
145701
|
const reasons = [];
|
|
145372
145702
|
const matchedLenses = /* @__PURE__ */ new Set();
|
|
@@ -145633,7 +145963,31 @@ async function recordWorkflowRun(input) {
|
|
|
145633
145963
|
throw new Error("Workflow was not found for this workspace");
|
|
145634
145964
|
}
|
|
145635
145965
|
if (!input.run.task.trim()) throw new Error("Workflow run task is required");
|
|
145636
|
-
|
|
145966
|
+
const run = store.recordRun(input.run);
|
|
145967
|
+
const kind = run.outcome === "passed" && run.verificationVerdict === "passed" ? "verification-passed" : run.outcome === "failed" || run.verificationVerdict === "failed" ? "verification-failed" : void 0;
|
|
145968
|
+
if (!kind) return run;
|
|
145969
|
+
const evidence = /* @__PURE__ */ new Map();
|
|
145970
|
+
evidence.set(workflow.id, "workflow");
|
|
145971
|
+
for (const reference of run.selectedEvidence) {
|
|
145972
|
+
const match2 = /^(claim|durable):(.+)$/.exec(reference);
|
|
145973
|
+
if (!match2) continue;
|
|
145974
|
+
evidence.set(match2[2], match2[1] === "claim" ? "claim" : "durable-memory");
|
|
145975
|
+
}
|
|
145976
|
+
const outcomes = new OutcomeStore();
|
|
145977
|
+
await outcomes.init(workflowStoreDataDir(input.workspace));
|
|
145978
|
+
for (const [candidateId, candidateKind] of evidence) {
|
|
145979
|
+
outcomes.record({
|
|
145980
|
+
projectId: run.projectId,
|
|
145981
|
+
candidateKind,
|
|
145982
|
+
candidateId,
|
|
145983
|
+
kind,
|
|
145984
|
+
sourceRef: "workflow-run:" + run.id,
|
|
145985
|
+
...run.startingSnapshotId ? { snapshotId: run.startingSnapshotId } : {},
|
|
145986
|
+
...run.failureReason ? { detail: run.failureReason } : {},
|
|
145987
|
+
observedAt: run.completedAt ?? run.startedAt
|
|
145988
|
+
});
|
|
145989
|
+
}
|
|
145990
|
+
return run;
|
|
145637
145991
|
}
|
|
145638
145992
|
async function selectWorkspaceWorkflows(input) {
|
|
145639
145993
|
const synced = await syncCanonicalWorkflows(input.workspace);
|
|
@@ -145658,6 +146012,7 @@ var init_workflows2 = __esm({
|
|
|
145658
146012
|
init_workflow_sync();
|
|
145659
146013
|
init_workspace();
|
|
145660
146014
|
init_workflow_store();
|
|
146015
|
+
init_outcome_store();
|
|
145661
146016
|
init_task_lens();
|
|
145662
146017
|
KNOWN_AGENTS = [
|
|
145663
146018
|
"windsurf",
|