memorix 1.9.5 → 1.9.6
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 +42 -0
- package/README.md +6 -1
- package/README.zh-CN.md +6 -1
- package/dist/cli/index.js +1647 -264
- package/dist/index.d.ts +12 -7
- package/dist/index.js +952 -182
- package/dist/maintenance-runner.js +243 -103
- package/dist/media-audio-runner.js +243 -103
- package/dist/media-video-runner.js +243 -103
- package/dist/memcode-runtime/CHANGELOG.md +42 -0
- package/dist/sdk.js +871 -157
- package/dist/vector-backfill-runner.js +243 -103
- package/docs/API_REFERENCE.md +36 -0
- package/docs/CONFIGURATION.md +43 -0
- package/docs/DEVELOPMENT.md +1 -1
- package/docs/KNOWN_ISSUES_AND_ROADMAP.md +49 -14
- package/docs/PERFORMANCE.md +46 -2
- package/docs/README.md +2 -1
- package/docs/SETUP.md +1 -1
- package/package.json +2 -1
- package/plugins/antigravity/memorix/plugin.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/hermes/memorix/plugin.yaml +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/capability-map.ts +1 -0
- package/src/cli/command-guide.ts +13 -1
- package/src/cli/commands/context.ts +2 -0
- package/src/cli/commands/continuity.ts +155 -0
- package/src/cli/commands/init.ts +5 -2
- package/src/cli/commands/serve-http.ts +242 -42
- package/src/cli/index.ts +3 -1
- package/src/cli/tui/ConfigureView.tsx +2 -0
- package/src/codegraph/auto-context.ts +17 -0
- package/src/config/legacy-loader.ts +2 -2
- package/src/config/resolved-config.ts +8 -5
- package/src/config/yaml-loader.ts +20 -10
- package/src/embedding/api-provider.ts +4 -2
- package/src/embedding/fastembed-provider.ts +47 -14
- package/src/embedding/transformers-provider.ts +29 -7
- package/src/evaluation/memory-quality-gate.ts +90 -0
- package/src/hooks/official-skills.ts +2 -0
- package/src/knowledge/context-assembly.ts +1 -0
- package/src/knowledge/context-receipt.ts +15 -0
- package/src/knowledge/task-continuity.ts +413 -0
- package/src/knowledge/workset.ts +77 -0
- package/src/llm/provider.ts +2 -1
- package/src/orchestrate/coordinator.ts +60 -0
- package/src/orchestrate/effect-ledger.ts +160 -0
- package/src/orchestrate/pipeline-trace.ts +40 -6
- package/src/runtime/maintenance-jobs.ts +12 -6
- package/src/server/modern-mcp-bridge.ts +153 -27
- package/src/server/tool-profile.ts +3 -2
- package/src/server.ts +129 -5
- package/src/store/sqlite-db.ts +144 -4
- package/src/team/team-store.ts +62 -27
package/dist/sdk.js
CHANGED
|
@@ -420,9 +420,12 @@ END;
|
|
|
420
420
|
// src/store/sqlite-db.ts
|
|
421
421
|
var sqlite_db_exports = {};
|
|
422
422
|
__export(sqlite_db_exports, {
|
|
423
|
+
acquireDatabase: () => acquireDatabase,
|
|
423
424
|
closeAllDatabases: () => closeAllDatabases,
|
|
424
425
|
closeDatabase: () => closeDatabase,
|
|
426
|
+
evictIdleDatabases: () => evictIdleDatabases,
|
|
425
427
|
getDatabase: () => getDatabase,
|
|
428
|
+
getDatabaseStats: () => getDatabaseStats,
|
|
426
429
|
isSqliteAvailable: () => isSqliteAvailable,
|
|
427
430
|
loadBetterSqlite3: () => loadBetterSqlite3
|
|
428
431
|
});
|
|
@@ -460,11 +463,21 @@ function applySchemaMigrations(db2) {
|
|
|
460
463
|
apply();
|
|
461
464
|
}
|
|
462
465
|
}
|
|
466
|
+
function normalizeDataDir(dataDir) {
|
|
467
|
+
return path3.resolve(dataDir);
|
|
468
|
+
}
|
|
469
|
+
function touchDatabase(normalized, db2) {
|
|
470
|
+
_dbCache.delete(normalized);
|
|
471
|
+
_dbCache.set(normalized, db2);
|
|
472
|
+
}
|
|
463
473
|
function getDatabase(dataDir) {
|
|
464
|
-
const normalized =
|
|
474
|
+
const normalized = normalizeDataDir(dataDir);
|
|
465
475
|
assertNotHomeDataDir(normalized);
|
|
466
476
|
const existing = _dbCache.get(normalized);
|
|
467
|
-
if (existing)
|
|
477
|
+
if (existing) {
|
|
478
|
+
touchDatabase(normalized, existing);
|
|
479
|
+
return existing;
|
|
480
|
+
}
|
|
468
481
|
loadBetterSqlite3();
|
|
469
482
|
fs.mkdirSync(dataDir, { recursive: true });
|
|
470
483
|
const dbPath = path3.join(dataDir, "memorix.db");
|
|
@@ -494,6 +507,8 @@ function getDatabase(dataDir) {
|
|
|
494
507
|
db2.exec(CREATE_MAINTENANCE_JOBS_TABLE);
|
|
495
508
|
db2.exec(CREATE_MAINTENANCE_TARGETS_TABLE);
|
|
496
509
|
db2.exec(CREATE_COMPACTION_CHECKPOINTS_TABLE);
|
|
510
|
+
db2.exec(CREATE_TASK_CONTINUITY_EVENTS_TABLE);
|
|
511
|
+
db2.exec(CREATE_AGENT_EFFECTS_TABLE);
|
|
497
512
|
try {
|
|
498
513
|
db2.exec(`ALTER TABLE mini_skills ADD COLUMN sourceSnapshot TEXT NOT NULL DEFAULT ''`);
|
|
499
514
|
} catch {
|
|
@@ -532,7 +547,7 @@ function getDatabase(dataDir) {
|
|
|
532
547
|
db2.prepare(`INSERT OR IGNORE INTO meta (key, value) VALUES ('storage_generation', '0')`).run();
|
|
533
548
|
db2.prepare(`INSERT OR IGNORE INTO meta (key, value) VALUES ('next_id', '1')`).run();
|
|
534
549
|
db2.prepare(`INSERT OR IGNORE INTO meta (key, value) VALUES ('mini_skills_generation', '0')`).run();
|
|
535
|
-
|
|
550
|
+
touchDatabase(normalized, db2);
|
|
536
551
|
return db2;
|
|
537
552
|
} catch (error) {
|
|
538
553
|
try {
|
|
@@ -542,8 +557,46 @@ function getDatabase(dataDir) {
|
|
|
542
557
|
throw error;
|
|
543
558
|
}
|
|
544
559
|
}
|
|
560
|
+
function acquireDatabase(dataDir) {
|
|
561
|
+
const normalized = normalizeDataDir(dataDir);
|
|
562
|
+
const db2 = getDatabase(normalized);
|
|
563
|
+
_dbLeases.set(normalized, (_dbLeases.get(normalized) ?? 0) + 1);
|
|
564
|
+
let released = false;
|
|
565
|
+
return {
|
|
566
|
+
dataDir: normalized,
|
|
567
|
+
db: db2,
|
|
568
|
+
release: () => {
|
|
569
|
+
if (released) return;
|
|
570
|
+
released = true;
|
|
571
|
+
const count2 = (_dbLeases.get(normalized) ?? 0) - 1;
|
|
572
|
+
if (count2 > 0) _dbLeases.set(normalized, count2);
|
|
573
|
+
else _dbLeases.delete(normalized);
|
|
574
|
+
}
|
|
575
|
+
};
|
|
576
|
+
}
|
|
577
|
+
function getDatabaseStats() {
|
|
578
|
+
let leased = 0;
|
|
579
|
+
for (const count2 of _dbLeases.values()) leased += count2;
|
|
580
|
+
return { cached: _dbCache.size, leased, leasedDataDirs: _dbLeases.size };
|
|
581
|
+
}
|
|
582
|
+
function evictIdleDatabases(maxCached) {
|
|
583
|
+
const target = Math.max(0, Math.floor(maxCached));
|
|
584
|
+
let evicted = 0;
|
|
585
|
+
for (const [normalized, db2] of [..._dbCache]) {
|
|
586
|
+
if (_dbCache.size <= target) break;
|
|
587
|
+
if ((_dbLeases.get(normalized) ?? 0) > 0) continue;
|
|
588
|
+
try {
|
|
589
|
+
db2.close();
|
|
590
|
+
} catch {
|
|
591
|
+
}
|
|
592
|
+
_dbCache.delete(normalized);
|
|
593
|
+
evicted++;
|
|
594
|
+
}
|
|
595
|
+
return evicted;
|
|
596
|
+
}
|
|
545
597
|
function closeDatabase(dataDir) {
|
|
546
|
-
const normalized =
|
|
598
|
+
const normalized = normalizeDataDir(dataDir);
|
|
599
|
+
if ((_dbLeases.get(normalized) ?? 0) > 0) return;
|
|
547
600
|
const db2 = _dbCache.get(normalized);
|
|
548
601
|
if (db2) {
|
|
549
602
|
try {
|
|
@@ -561,6 +614,7 @@ function closeAllDatabases() {
|
|
|
561
614
|
}
|
|
562
615
|
_dbCache.delete(key);
|
|
563
616
|
}
|
|
617
|
+
_dbLeases.clear();
|
|
564
618
|
}
|
|
565
619
|
function isSqliteAvailable() {
|
|
566
620
|
try {
|
|
@@ -570,7 +624,7 @@ function isSqliteAvailable() {
|
|
|
570
624
|
return false;
|
|
571
625
|
}
|
|
572
626
|
}
|
|
573
|
-
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_EVIDENCE_CARDS_TABLE, CREATE_EVIDENCE_CARD_EVENTS_TABLE, CREATE_MEMORY_FEEDBACK_STATES_TABLE, CREATE_MEMORY_FEEDBACK_EVENTS_TABLE, CREATE_MCP_BINDINGS_TABLE, CREATE_INDEXES, SCHEMA_MIGRATIONS, _dbCache;
|
|
627
|
+
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_EVIDENCE_CARDS_TABLE, CREATE_EVIDENCE_CARD_EVENTS_TABLE, CREATE_MEMORY_FEEDBACK_STATES_TABLE, CREATE_MEMORY_FEEDBACK_EVENTS_TABLE, CREATE_TASK_CONTINUITY_EVENTS_TABLE, CREATE_AGENT_EFFECTS_TABLE, CREATE_MCP_BINDINGS_TABLE, CREATE_INDEXES, SCHEMA_MIGRATIONS, _dbCache, _dbLeases;
|
|
574
628
|
var init_sqlite_db = __esm({
|
|
575
629
|
"src/store/sqlite-db.ts"() {
|
|
576
630
|
"use strict";
|
|
@@ -1287,6 +1341,43 @@ CREATE TABLE IF NOT EXISTS memory_feedback_events (
|
|
|
1287
1341
|
delta REAL NOT NULL DEFAULT 0,
|
|
1288
1342
|
observed_at TEXT NOT NULL
|
|
1289
1343
|
);
|
|
1344
|
+
`;
|
|
1345
|
+
CREATE_TASK_CONTINUITY_EVENTS_TABLE = `
|
|
1346
|
+
CREATE TABLE IF NOT EXISTS task_continuity_events (
|
|
1347
|
+
id TEXT PRIMARY KEY,
|
|
1348
|
+
project_id TEXT NOT NULL,
|
|
1349
|
+
task_id TEXT NOT NULL,
|
|
1350
|
+
task TEXT NOT NULL,
|
|
1351
|
+
kind TEXT NOT NULL,
|
|
1352
|
+
content TEXT NOT NULL,
|
|
1353
|
+
item_status TEXT,
|
|
1354
|
+
source_ref TEXT,
|
|
1355
|
+
evidence_json TEXT NOT NULL DEFAULT '[]',
|
|
1356
|
+
actor TEXT,
|
|
1357
|
+
created_at TEXT NOT NULL,
|
|
1358
|
+
event_key TEXT,
|
|
1359
|
+
item_key TEXT,
|
|
1360
|
+
supersedes_id TEXT
|
|
1361
|
+
);
|
|
1362
|
+
`;
|
|
1363
|
+
CREATE_AGENT_EFFECTS_TABLE = `
|
|
1364
|
+
CREATE TABLE IF NOT EXISTS agent_effects (
|
|
1365
|
+
id TEXT PRIMARY KEY,
|
|
1366
|
+
pipeline_id TEXT NOT NULL,
|
|
1367
|
+
task_id TEXT NOT NULL,
|
|
1368
|
+
attempt INTEGER NOT NULL,
|
|
1369
|
+
effect_key TEXT NOT NULL,
|
|
1370
|
+
tool TEXT NOT NULL,
|
|
1371
|
+
risk_tier TEXT NOT NULL,
|
|
1372
|
+
replay_policy TEXT NOT NULL,
|
|
1373
|
+
status TEXT NOT NULL,
|
|
1374
|
+
call_id TEXT,
|
|
1375
|
+
idempotency_key TEXT NOT NULL,
|
|
1376
|
+
input_fingerprint TEXT,
|
|
1377
|
+
detail TEXT,
|
|
1378
|
+
started_at INTEGER NOT NULL,
|
|
1379
|
+
finished_at INTEGER
|
|
1380
|
+
);
|
|
1290
1381
|
`;
|
|
1291
1382
|
CREATE_MCP_BINDINGS_TABLE = `
|
|
1292
1383
|
CREATE TABLE IF NOT EXISTS mcp_bindings (
|
|
@@ -1365,7 +1456,18 @@ CREATE INDEX IF NOT EXISTS idx_evidence_cards_candidate ON evidence_cards(projec
|
|
|
1365
1456
|
CREATE INDEX IF NOT EXISTS idx_evidence_card_events_card ON evidence_card_events(card_id, created_at);
|
|
1366
1457
|
CREATE INDEX IF NOT EXISTS idx_memory_feedback_states_project ON memory_feedback_states(project_id, candidate_kind, updated_at DESC);
|
|
1367
1458
|
CREATE INDEX IF NOT EXISTS idx_memory_feedback_events_candidate ON memory_feedback_events(project_id, candidate_kind, candidate_id, observed_at DESC);
|
|
1459
|
+
CREATE INDEX IF NOT EXISTS idx_task_continuity_project_task ON task_continuity_events(project_id, task_id, created_at ASC);
|
|
1460
|
+
CREATE INDEX IF NOT EXISTS idx_task_continuity_project_recent ON task_continuity_events(project_id, created_at DESC);
|
|
1461
|
+
CREATE INDEX IF NOT EXISTS idx_task_continuity_item ON task_continuity_events(project_id, task_id, kind, item_key, created_at DESC);
|
|
1462
|
+
CREATE UNIQUE INDEX IF NOT EXISTS idx_task_continuity_event_key
|
|
1463
|
+
ON task_continuity_events(project_id, task_id, event_key)
|
|
1464
|
+
WHERE event_key IS NOT NULL;
|
|
1465
|
+
CREATE UNIQUE INDEX IF NOT EXISTS idx_agent_effect_identity
|
|
1466
|
+
ON agent_effects(pipeline_id, task_id, attempt, effect_key);
|
|
1467
|
+
CREATE INDEX IF NOT EXISTS idx_agent_effect_pipeline ON agent_effects(pipeline_id, started_at ASC);
|
|
1368
1468
|
CREATE INDEX IF NOT EXISTS idx_mcp_bindings_project ON mcp_bindings(project_id, last_used_at DESC);
|
|
1469
|
+
CREATE INDEX IF NOT EXISTS idx_mcp_bindings_root ON mcp_bindings(project_root, last_used_at DESC);
|
|
1470
|
+
CREATE INDEX IF NOT EXISTS idx_mcp_bindings_expiry ON mcp_bindings(expires_at);
|
|
1369
1471
|
CREATE UNIQUE INDEX IF NOT EXISTS idx_maintenance_jobs_active_dedupe
|
|
1370
1472
|
ON maintenance_jobs(project_id, kind, dedupe_key)
|
|
1371
1473
|
WHERE status IN ('pending', 'running', 'retry');
|
|
@@ -1536,6 +1638,8 @@ CREATE UNIQUE INDEX IF NOT EXISTS idx_maintenance_jobs_active_dedupe
|
|
|
1536
1638
|
db2.exec("CREATE INDEX IF NOT EXISTS idx_memory_feedback_states_project ON memory_feedback_states(project_id, candidate_kind, updated_at DESC)");
|
|
1537
1639
|
db2.exec("CREATE INDEX IF NOT EXISTS idx_memory_feedback_events_candidate ON memory_feedback_events(project_id, candidate_kind, candidate_id, observed_at DESC)");
|
|
1538
1640
|
db2.exec("CREATE INDEX IF NOT EXISTS idx_mcp_bindings_project ON mcp_bindings(project_id, last_used_at DESC)");
|
|
1641
|
+
db2.exec("CREATE INDEX IF NOT EXISTS idx_mcp_bindings_root ON mcp_bindings(project_root, last_used_at DESC)");
|
|
1642
|
+
db2.exec("CREATE INDEX IF NOT EXISTS idx_mcp_bindings_expiry ON mcp_bindings(expires_at)");
|
|
1539
1643
|
}
|
|
1540
1644
|
},
|
|
1541
1645
|
{
|
|
@@ -1546,9 +1650,22 @@ CREATE UNIQUE INDEX IF NOT EXISTS idx_maintenance_jobs_active_dedupe
|
|
|
1546
1650
|
addColumnIfMissing(db2, "code_symbols", "source", "source TEXT");
|
|
1547
1651
|
addColumnIfMissing(db2, "code_edges", "source", "source TEXT");
|
|
1548
1652
|
}
|
|
1653
|
+
},
|
|
1654
|
+
{
|
|
1655
|
+
id: "1.9-continuity-v2",
|
|
1656
|
+
apply: (db2) => {
|
|
1657
|
+
addColumnIfMissing(db2, "task_continuity_events", "event_key", "event_key TEXT");
|
|
1658
|
+
addColumnIfMissing(db2, "task_continuity_events", "item_key", "item_key TEXT");
|
|
1659
|
+
addColumnIfMissing(db2, "task_continuity_events", "supersedes_id", "supersedes_id TEXT");
|
|
1660
|
+
db2.exec("CREATE INDEX IF NOT EXISTS idx_task_continuity_item ON task_continuity_events(project_id, task_id, kind, item_key, created_at DESC)");
|
|
1661
|
+
db2.exec(`CREATE UNIQUE INDEX IF NOT EXISTS idx_task_continuity_event_key
|
|
1662
|
+
ON task_continuity_events(project_id, task_id, event_key)
|
|
1663
|
+
WHERE event_key IS NOT NULL`);
|
|
1664
|
+
}
|
|
1549
1665
|
}
|
|
1550
1666
|
];
|
|
1551
1667
|
_dbCache = /* @__PURE__ */ new Map();
|
|
1668
|
+
_dbLeases = /* @__PURE__ */ new Map();
|
|
1552
1669
|
}
|
|
1553
1670
|
});
|
|
1554
1671
|
|
|
@@ -3216,18 +3333,23 @@ __export(yaml_loader_exports, {
|
|
|
3216
3333
|
import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
|
|
3217
3334
|
import { homedir } from "os";
|
|
3218
3335
|
import { parse as parseYamlDocument } from "yaml";
|
|
3336
|
+
function cacheKey(homeDir, projectRoot) {
|
|
3337
|
+
return `${homeDir}\0${projectRoot ?? ""}`;
|
|
3338
|
+
}
|
|
3219
3339
|
function initProjectRoot(root) {
|
|
3220
3340
|
globalProjectRoot = root;
|
|
3221
|
-
configCache.delete(root);
|
|
3341
|
+
configCache.delete(cacheKey(homedir(), root));
|
|
3222
3342
|
}
|
|
3223
3343
|
function clearProjectRoot() {
|
|
3224
3344
|
globalProjectRoot = null;
|
|
3225
3345
|
}
|
|
3226
|
-
function loadYamlConfig(projectRoot) {
|
|
3346
|
+
function loadYamlConfig(projectRoot, options = {}) {
|
|
3347
|
+
const homeDir = options.homeDir ?? homedir();
|
|
3227
3348
|
const resolvedRoot = projectRoot === null ? null : projectRoot ?? globalProjectRoot ?? null;
|
|
3228
|
-
const
|
|
3349
|
+
const key = cacheKey(homeDir, resolvedRoot);
|
|
3350
|
+
const cached = configCache.get(key);
|
|
3229
3351
|
if (cached) return cached;
|
|
3230
|
-
const userYaml = getGlobalYamlPath(
|
|
3352
|
+
const userYaml = getGlobalYamlPath(homeDir);
|
|
3231
3353
|
const projectYaml = resolvedRoot ? getProjectYamlPath(resolvedRoot) : null;
|
|
3232
3354
|
let userConfig = {};
|
|
3233
3355
|
let projectConfig = {};
|
|
@@ -3259,12 +3381,12 @@ function loadYamlConfig(projectRoot) {
|
|
|
3259
3381
|
server: { ...userConfig.server, ...projectConfig.server },
|
|
3260
3382
|
team: { ...userConfig.team, ...projectConfig.team }
|
|
3261
3383
|
};
|
|
3262
|
-
configCache.set(
|
|
3384
|
+
configCache.set(key, merged);
|
|
3263
3385
|
return merged;
|
|
3264
3386
|
}
|
|
3265
|
-
function resetYamlConfigCache(projectRoot) {
|
|
3387
|
+
function resetYamlConfigCache(projectRoot, homeDir = homedir()) {
|
|
3266
3388
|
if (projectRoot !== void 0) {
|
|
3267
|
-
configCache.delete(projectRoot ?? null);
|
|
3389
|
+
configCache.delete(cacheKey(homeDir, projectRoot ?? null));
|
|
3268
3390
|
} else {
|
|
3269
3391
|
configCache.clear();
|
|
3270
3392
|
}
|
|
@@ -3474,9 +3596,9 @@ var init_detector = __esm({
|
|
|
3474
3596
|
// src/config/legacy-loader.ts
|
|
3475
3597
|
import { existsSync as existsSync4, readFileSync as readFileSync4 } from "fs";
|
|
3476
3598
|
import { homedir as homedir2 } from "os";
|
|
3477
|
-
function loadFileConfig() {
|
|
3599
|
+
function loadFileConfig(homeDir = homedir2()) {
|
|
3478
3600
|
if (cachedConfig !== null) return cachedConfig;
|
|
3479
|
-
const configPath = getLegacyConfigJsonPath(
|
|
3601
|
+
const configPath = getLegacyConfigJsonPath(homeDir);
|
|
3480
3602
|
try {
|
|
3481
3603
|
if (existsSync4(configPath)) {
|
|
3482
3604
|
cachedConfig = JSON.parse(readFileSync4(configPath, "utf-8"));
|
|
@@ -3506,15 +3628,15 @@ import { homedir as homedir3 } from "os";
|
|
|
3506
3628
|
function loadTomlConfig(options = {}) {
|
|
3507
3629
|
const homeDir = options.homeDir ?? homedir3();
|
|
3508
3630
|
const projectRoot = options.projectRoot ?? null;
|
|
3509
|
-
const
|
|
3510
|
-
const cached = configCache2.get(
|
|
3631
|
+
const cacheKey3 = `${homeDir}\0${projectRoot ?? ""}`;
|
|
3632
|
+
const cached = configCache2.get(cacheKey3);
|
|
3511
3633
|
if (cached) return cached;
|
|
3512
3634
|
const userToml = getGlobalConfigTomlPath(homeDir);
|
|
3513
3635
|
const projectToml = projectRoot ? getProjectConfigTomlPath(projectRoot) : null;
|
|
3514
3636
|
const userConfig = existsSync5(userToml) ? parseTomlConfig(readFileSync5(userToml, "utf8"), userToml) : {};
|
|
3515
3637
|
const projectConfig = projectToml && existsSync5(projectToml) ? parseTomlConfig(readFileSync5(projectToml, "utf8"), projectToml) : {};
|
|
3516
3638
|
const merged = mergeTomlConfig(userConfig, projectConfig);
|
|
3517
|
-
configCache2.set(
|
|
3639
|
+
configCache2.set(cacheKey3, merged);
|
|
3518
3640
|
return merged;
|
|
3519
3641
|
}
|
|
3520
3642
|
function mergeTomlConfig(base, override) {
|
|
@@ -3714,8 +3836,8 @@ function getResolvedConfig(options = {}) {
|
|
|
3714
3836
|
const projectRoot = options.projectRoot === void 0 ? detectProject()?.rootPath ?? null : options.projectRoot;
|
|
3715
3837
|
loadDotenv(projectRoot === null ? void 0 : projectRoot ?? void 0, { userHomeDir: homeDir });
|
|
3716
3838
|
const toml = loadTomlConfig({ projectRoot: projectRoot ?? null, homeDir });
|
|
3717
|
-
const yaml = loadYamlConfig(projectRoot ?? null);
|
|
3718
|
-
const legacy = loadFileConfig();
|
|
3839
|
+
const yaml = loadYamlConfig(projectRoot ?? null, { homeDir });
|
|
3840
|
+
const legacy = loadFileConfig(homeDir);
|
|
3719
3841
|
const embeddingBaseUrl = first(process.env.MEMORIX_EMBEDDING_BASE_URL, toml.embedding?.base_url, yaml.embedding?.baseUrl, legacy.embeddingApi?.baseUrl);
|
|
3720
3842
|
const openRouterEmbeddingApiKey = isOpenRouterUrl(embeddingBaseUrl) ? process.env.OPENROUTER_API_KEY : void 0;
|
|
3721
3843
|
const memoryLlmProvider = first(
|
|
@@ -3737,15 +3859,17 @@ function getResolvedConfig(options = {}) {
|
|
|
3737
3859
|
legacy.llm?.baseUrl
|
|
3738
3860
|
);
|
|
3739
3861
|
const openRouterMemoryLlmApiKey = isOpenRouterMemoryLane(memoryLlmProvider, memoryLlmBaseUrl) ? process.env.OPENROUTER_API_KEY : void 0;
|
|
3862
|
+
const isAtlasCloud = memoryLlmProvider === "atlascloud";
|
|
3740
3863
|
const memoryLlmApiKey = first(
|
|
3741
3864
|
process.env.MEMORIX_LLM_API_KEY,
|
|
3742
3865
|
process.env.MEMORIX_API_KEY,
|
|
3743
3866
|
toml.memory?.llm?.api_key,
|
|
3744
3867
|
yaml.llm?.apiKey,
|
|
3745
3868
|
legacy.llm?.apiKey,
|
|
3746
|
-
|
|
3747
|
-
process.env.
|
|
3748
|
-
|
|
3869
|
+
// Never borrow another provider's credentials for the Atlas Cloud preset.
|
|
3870
|
+
isAtlasCloud ? process.env.ATLASCLOUD_API_KEY : process.env.OPENAI_API_KEY,
|
|
3871
|
+
isAtlasCloud ? void 0 : process.env.ANTHROPIC_API_KEY,
|
|
3872
|
+
isAtlasCloud ? void 0 : openRouterMemoryLlmApiKey
|
|
3749
3873
|
);
|
|
3750
3874
|
const resolved = {
|
|
3751
3875
|
agent: {
|
|
@@ -3924,7 +4048,8 @@ function getEnvSourceNames() {
|
|
|
3924
4048
|
"MEMORIX_CODEGRAPH_EXTERNAL_CONTEXT",
|
|
3925
4049
|
"MEMORIX_CODEGRAPH_EXTERNAL_COMMAND",
|
|
3926
4050
|
"MEMORIX_CODEGRAPH_EXTERNAL_TIMEOUT_MS",
|
|
3927
|
-
"OPENROUTER_API_KEY"
|
|
4051
|
+
"OPENROUTER_API_KEY",
|
|
4052
|
+
"ATLASCLOUD_API_KEY"
|
|
3928
4053
|
].filter((name) => process.env[name]);
|
|
3929
4054
|
}
|
|
3930
4055
|
function isOpenRouterUrl(value) {
|
|
@@ -4143,12 +4268,45 @@ function textHash(text3) {
|
|
|
4143
4268
|
async function loadDiskCache() {
|
|
4144
4269
|
try {
|
|
4145
4270
|
const raw = await readFile(CACHE_FILE, "utf-8");
|
|
4271
|
+
if (Buffer.byteLength(raw, "utf8") > MAX_CACHE_FILE_BYTES) {
|
|
4272
|
+
console.error("[memorix] FastEmbed cache exceeds the disk load limit; starting with an empty cache");
|
|
4273
|
+
return;
|
|
4274
|
+
}
|
|
4146
4275
|
const entries = JSON.parse(raw);
|
|
4147
|
-
|
|
4148
|
-
|
|
4276
|
+
if (!Array.isArray(entries)) return;
|
|
4277
|
+
for (const entry of entries) {
|
|
4278
|
+
if (!Array.isArray(entry) || typeof entry[0] !== "string" || !isVector(entry[1])) continue;
|
|
4279
|
+
cacheSet(entry[0], entry[1], false);
|
|
4280
|
+
}
|
|
4281
|
+
console.error(`[memorix] Loaded ${cache.size} cached embeddings from disk`);
|
|
4149
4282
|
} catch {
|
|
4150
4283
|
}
|
|
4151
4284
|
}
|
|
4285
|
+
function isVector(value) {
|
|
4286
|
+
return Array.isArray(value) && value.every((entry) => typeof entry === "number");
|
|
4287
|
+
}
|
|
4288
|
+
function maxCachePayloadBytes() {
|
|
4289
|
+
const raw = Number.parseInt(process.env.MEMORIX_EMBEDDING_CACHE_MAX_BYTES ?? "", 10);
|
|
4290
|
+
return Number.isFinite(raw) && raw > 0 ? raw : DEFAULT_CACHE_PAYLOAD_BYTES;
|
|
4291
|
+
}
|
|
4292
|
+
function cacheSet(hash4, value, markDirty = true) {
|
|
4293
|
+
const incomingBytes = value.length * 8;
|
|
4294
|
+
if (incomingBytes > maxCachePayloadBytes()) return;
|
|
4295
|
+
const existing = cache.get(hash4);
|
|
4296
|
+
if (existing) cachePayloadBytes -= existing.length * 8;
|
|
4297
|
+
else {
|
|
4298
|
+
while (cache.size >= MAX_CACHE_SIZE || cachePayloadBytes + incomingBytes > maxCachePayloadBytes()) {
|
|
4299
|
+
const firstKey = cache.keys().next().value;
|
|
4300
|
+
if (firstKey === void 0) break;
|
|
4301
|
+
const old = cache.get(firstKey);
|
|
4302
|
+
cache.delete(firstKey);
|
|
4303
|
+
if (old) cachePayloadBytes -= old.length * 8;
|
|
4304
|
+
}
|
|
4305
|
+
}
|
|
4306
|
+
cache.set(hash4, value);
|
|
4307
|
+
cachePayloadBytes += incomingBytes;
|
|
4308
|
+
if (markDirty) diskCacheDirty = true;
|
|
4309
|
+
}
|
|
4152
4310
|
async function saveDiskCache() {
|
|
4153
4311
|
if (!diskCacheDirty) return;
|
|
4154
4312
|
try {
|
|
@@ -4159,7 +4317,7 @@ async function saveDiskCache() {
|
|
|
4159
4317
|
} catch {
|
|
4160
4318
|
}
|
|
4161
4319
|
}
|
|
4162
|
-
var CACHE_DIR, CACHE_FILE, cache, MAX_CACHE_SIZE, diskCacheDirty, FastEmbedProvider;
|
|
4320
|
+
var CACHE_DIR, CACHE_FILE, cache, MAX_CACHE_SIZE, DEFAULT_CACHE_PAYLOAD_BYTES, MAX_CACHE_FILE_BYTES, cachePayloadBytes, diskCacheDirty, FastEmbedProvider;
|
|
4163
4321
|
var init_fastembed_provider = __esm({
|
|
4164
4322
|
"src/embedding/fastembed-provider.ts"() {
|
|
4165
4323
|
"use strict";
|
|
@@ -4169,6 +4327,9 @@ var init_fastembed_provider = __esm({
|
|
|
4169
4327
|
CACHE_FILE = join2(CACHE_DIR, ".embedding-cache.json");
|
|
4170
4328
|
cache = /* @__PURE__ */ new Map();
|
|
4171
4329
|
MAX_CACHE_SIZE = 5e3;
|
|
4330
|
+
DEFAULT_CACHE_PAYLOAD_BYTES = 64 * 1024 * 1024;
|
|
4331
|
+
MAX_CACHE_FILE_BYTES = 128 * 1024 * 1024;
|
|
4332
|
+
cachePayloadBytes = 0;
|
|
4172
4333
|
diskCacheDirty = false;
|
|
4173
4334
|
FastEmbedProvider = class _FastEmbedProvider {
|
|
4174
4335
|
name = "fastembed-bge-small";
|
|
@@ -4210,7 +4371,7 @@ var init_fastembed_provider = __esm({
|
|
|
4210
4371
|
if (result.length !== this.dimensions) {
|
|
4211
4372
|
throw new Error(`Expected ${this.dimensions}d embedding, got ${result.length}d`);
|
|
4212
4373
|
}
|
|
4213
|
-
|
|
4374
|
+
cacheSet(hash4, result);
|
|
4214
4375
|
return result;
|
|
4215
4376
|
}
|
|
4216
4377
|
async embedBatch(texts) {
|
|
@@ -4235,7 +4396,7 @@ var init_fastembed_provider = __esm({
|
|
|
4235
4396
|
const originalIdx = uncachedIndices[batchIdx];
|
|
4236
4397
|
const plain = Array.from(vec);
|
|
4237
4398
|
results[originalIdx] = plain;
|
|
4238
|
-
|
|
4399
|
+
cacheSet(textHash(uncachedTexts[batchIdx]), plain);
|
|
4239
4400
|
batchIdx++;
|
|
4240
4401
|
}
|
|
4241
4402
|
}
|
|
@@ -4243,14 +4404,6 @@ var init_fastembed_provider = __esm({
|
|
|
4243
4404
|
}
|
|
4244
4405
|
return results;
|
|
4245
4406
|
}
|
|
4246
|
-
cacheSet(hash4, value) {
|
|
4247
|
-
if (cache.size >= MAX_CACHE_SIZE) {
|
|
4248
|
-
const firstKey = cache.keys().next().value;
|
|
4249
|
-
if (firstKey !== void 0) cache.delete(firstKey);
|
|
4250
|
-
}
|
|
4251
|
-
cache.set(hash4, value);
|
|
4252
|
-
diskCacheDirty = true;
|
|
4253
|
-
}
|
|
4254
4407
|
};
|
|
4255
4408
|
}
|
|
4256
4409
|
});
|
|
@@ -4260,7 +4413,15 @@ var transformers_provider_exports = {};
|
|
|
4260
4413
|
__export(transformers_provider_exports, {
|
|
4261
4414
|
TransformersProvider: () => TransformersProvider
|
|
4262
4415
|
});
|
|
4263
|
-
|
|
4416
|
+
import { createHash as createHash2 } from "crypto";
|
|
4417
|
+
function cacheKey2(text3) {
|
|
4418
|
+
return createHash2("sha256").update(text3).digest("hex");
|
|
4419
|
+
}
|
|
4420
|
+
function maxCachePayloadBytes2() {
|
|
4421
|
+
const raw = Number.parseInt(process.env.MEMORIX_EMBEDDING_CACHE_MAX_BYTES ?? "", 10);
|
|
4422
|
+
return Number.isFinite(raw) && raw > 0 ? raw : DEFAULT_CACHE_PAYLOAD_BYTES2;
|
|
4423
|
+
}
|
|
4424
|
+
var cache2, MAX_CACHE_SIZE2, DEFAULT_CACHE_PAYLOAD_BYTES2, cachePayloadBytes2, TransformersProvider;
|
|
4264
4425
|
var init_transformers_provider = __esm({
|
|
4265
4426
|
"src/embedding/transformers-provider.ts"() {
|
|
4266
4427
|
"use strict";
|
|
@@ -4268,6 +4429,8 @@ var init_transformers_provider = __esm({
|
|
|
4268
4429
|
init_provider();
|
|
4269
4430
|
cache2 = /* @__PURE__ */ new Map();
|
|
4270
4431
|
MAX_CACHE_SIZE2 = 5e3;
|
|
4432
|
+
DEFAULT_CACHE_PAYLOAD_BYTES2 = 64 * 1024 * 1024;
|
|
4433
|
+
cachePayloadBytes2 = 0;
|
|
4271
4434
|
TransformersProvider = class _TransformersProvider {
|
|
4272
4435
|
name = "transformers-minilm";
|
|
4273
4436
|
dimensions = 384;
|
|
@@ -4302,7 +4465,7 @@ var init_transformers_provider = __esm({
|
|
|
4302
4465
|
return Promise.all(inputs.map((input) => this.embedInput(input, options)));
|
|
4303
4466
|
}
|
|
4304
4467
|
async embed(text3) {
|
|
4305
|
-
const cached = cache2.get(text3);
|
|
4468
|
+
const cached = cache2.get(cacheKey2(text3));
|
|
4306
4469
|
if (cached) return cached;
|
|
4307
4470
|
const output = await this.extractor(text3, {
|
|
4308
4471
|
pooling: "mean",
|
|
@@ -4312,7 +4475,7 @@ var init_transformers_provider = __esm({
|
|
|
4312
4475
|
if (result.length !== this.dimensions) {
|
|
4313
4476
|
throw new Error(`Expected ${this.dimensions}d embedding, got ${result.length}d`);
|
|
4314
4477
|
}
|
|
4315
|
-
this.cacheSet(text3, result);
|
|
4478
|
+
this.cacheSet(cacheKey2(text3), result);
|
|
4316
4479
|
return result;
|
|
4317
4480
|
}
|
|
4318
4481
|
async embedBatch(texts) {
|
|
@@ -4320,7 +4483,7 @@ var init_transformers_provider = __esm({
|
|
|
4320
4483
|
const uncachedIndices = [];
|
|
4321
4484
|
const uncachedTexts = [];
|
|
4322
4485
|
for (let i2 = 0; i2 < texts.length; i2++) {
|
|
4323
|
-
const cached = cache2.get(texts[i2]);
|
|
4486
|
+
const cached = cache2.get(cacheKey2(texts[i2]));
|
|
4324
4487
|
if (cached) {
|
|
4325
4488
|
results[i2] = cached;
|
|
4326
4489
|
} else {
|
|
@@ -4338,17 +4501,27 @@ var init_transformers_provider = __esm({
|
|
|
4338
4501
|
const vec = Array.from(allVecs[i2]);
|
|
4339
4502
|
const originalIdx = uncachedIndices[i2];
|
|
4340
4503
|
results[originalIdx] = vec;
|
|
4341
|
-
this.cacheSet(uncachedTexts[i2], vec);
|
|
4504
|
+
this.cacheSet(cacheKey2(uncachedTexts[i2]), vec);
|
|
4342
4505
|
}
|
|
4343
4506
|
}
|
|
4344
4507
|
return results;
|
|
4345
4508
|
}
|
|
4346
4509
|
cacheSet(key, value) {
|
|
4347
|
-
|
|
4348
|
-
|
|
4349
|
-
|
|
4510
|
+
const incomingBytes = value.length * 8;
|
|
4511
|
+
if (incomingBytes > maxCachePayloadBytes2()) return;
|
|
4512
|
+
const existing = cache2.get(key);
|
|
4513
|
+
if (existing) cachePayloadBytes2 -= existing.length * 8;
|
|
4514
|
+
else {
|
|
4515
|
+
while (cache2.size >= MAX_CACHE_SIZE2 || cachePayloadBytes2 + incomingBytes > maxCachePayloadBytes2()) {
|
|
4516
|
+
const firstKey = cache2.keys().next().value;
|
|
4517
|
+
if (firstKey === void 0) break;
|
|
4518
|
+
const old = cache2.get(firstKey);
|
|
4519
|
+
cache2.delete(firstKey);
|
|
4520
|
+
if (old) cachePayloadBytes2 -= old.length * 8;
|
|
4521
|
+
}
|
|
4350
4522
|
}
|
|
4351
4523
|
cache2.set(key, value);
|
|
4524
|
+
cachePayloadBytes2 += incomingBytes;
|
|
4352
4525
|
}
|
|
4353
4526
|
};
|
|
4354
4527
|
}
|
|
@@ -4370,7 +4543,7 @@ __export(api_provider_exports, {
|
|
|
4370
4543
|
saveDiskCacheNow: () => saveDiskCacheNow,
|
|
4371
4544
|
seedApiEmbeddingCacheForTests: () => seedApiEmbeddingCacheForTests
|
|
4372
4545
|
});
|
|
4373
|
-
import { createHash as
|
|
4546
|
+
import { createHash as createHash3 } from "crypto";
|
|
4374
4547
|
import { createReadStream, createWriteStream, constants as fsConstants } from "fs";
|
|
4375
4548
|
import { access, readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2, rename, stat, unlink } from "fs/promises";
|
|
4376
4549
|
import { join as join3 } from "path";
|
|
@@ -4397,7 +4570,7 @@ function cacheStatFile() {
|
|
|
4397
4570
|
function payloadBytes(vector) {
|
|
4398
4571
|
return vector.length * BYTES_PER_DIM;
|
|
4399
4572
|
}
|
|
4400
|
-
function
|
|
4573
|
+
function maxCachePayloadBytes3() {
|
|
4401
4574
|
const raw = process.env.MEMORIX_EMBEDDING_CACHE_MAX_BYTES;
|
|
4402
4575
|
if (raw) {
|
|
4403
4576
|
const parsed = Number.parseInt(raw, 10);
|
|
@@ -4407,7 +4580,7 @@ function maxCachePayloadBytes() {
|
|
|
4407
4580
|
}
|
|
4408
4581
|
function maxEntriesForDimensions(dimensions) {
|
|
4409
4582
|
const dim = Math.max(1, Math.floor(dimensions));
|
|
4410
|
-
const byBytes = Math.floor(
|
|
4583
|
+
const byBytes = Math.floor(maxCachePayloadBytes3() / (dim * BYTES_PER_DIM));
|
|
4411
4584
|
return Math.max(1, Math.min(MAX_CACHE_ENTRIES, byBytes));
|
|
4412
4585
|
}
|
|
4413
4586
|
function rememberDimensions(vector) {
|
|
@@ -4420,13 +4593,15 @@ function evictOldest() {
|
|
|
4420
4593
|
if (firstKey === void 0) return;
|
|
4421
4594
|
const old = cache3.get(firstKey);
|
|
4422
4595
|
cache3.delete(firstKey);
|
|
4423
|
-
if (old)
|
|
4596
|
+
if (old) cachePayloadBytes3 -= payloadBytes(old);
|
|
4424
4597
|
}
|
|
4425
4598
|
function evictToFit(incomingBytes, incomingDims) {
|
|
4599
|
+
if (incomingBytes > maxCachePayloadBytes3()) return false;
|
|
4426
4600
|
const limit2 = maxEntriesForDimensions(incomingDims);
|
|
4427
|
-
while (cache3.size > 0 && (cache3.size >= limit2 ||
|
|
4601
|
+
while (cache3.size > 0 && (cache3.size >= limit2 || cachePayloadBytes3 + incomingBytes > maxCachePayloadBytes3())) {
|
|
4428
4602
|
evictOldest();
|
|
4429
4603
|
}
|
|
4604
|
+
return true;
|
|
4430
4605
|
}
|
|
4431
4606
|
function isNumberArray(value) {
|
|
4432
4607
|
return Array.isArray(value) && value.every((entry) => typeof entry === "number");
|
|
@@ -4453,12 +4628,12 @@ function cacheInsert(hash4, value, dirty) {
|
|
|
4453
4628
|
const incoming = payloadBytes(value);
|
|
4454
4629
|
const existing = cache3.get(hash4);
|
|
4455
4630
|
if (existing) {
|
|
4456
|
-
|
|
4631
|
+
cachePayloadBytes3 -= payloadBytes(existing);
|
|
4457
4632
|
cache3.delete(hash4);
|
|
4458
4633
|
}
|
|
4459
|
-
evictToFit(incoming, value.length || cacheDimensions || DEFAULT_ASSUMED_DIMENSIONS);
|
|
4634
|
+
if (!evictToFit(incoming, value.length || cacheDimensions || DEFAULT_ASSUMED_DIMENSIONS)) return;
|
|
4460
4635
|
cache3.set(hash4, value);
|
|
4461
|
-
|
|
4636
|
+
cachePayloadBytes3 += incoming;
|
|
4462
4637
|
if (dirty) diskCacheDirty2 = true;
|
|
4463
4638
|
}
|
|
4464
4639
|
async function readCacheStat() {
|
|
@@ -4494,7 +4669,7 @@ function cacheNamespace(config) {
|
|
|
4494
4669
|
].join("|");
|
|
4495
4670
|
}
|
|
4496
4671
|
function textHash2(text3, namespace) {
|
|
4497
|
-
return
|
|
4672
|
+
return createHash3("sha256").update(`${namespace}\0${text3}`).digest("hex").slice(0, 16);
|
|
4498
4673
|
}
|
|
4499
4674
|
function inputIdentity(input, options = {}) {
|
|
4500
4675
|
return JSON.stringify({
|
|
@@ -4836,7 +5011,7 @@ function getApiEmbeddingDiskCacheLoadCountForTests() {
|
|
|
4836
5011
|
}
|
|
4837
5012
|
function resetApiEmbeddingCacheForTests() {
|
|
4838
5013
|
cache3.clear();
|
|
4839
|
-
|
|
5014
|
+
cachePayloadBytes3 = 0;
|
|
4840
5015
|
cacheDimensions = null;
|
|
4841
5016
|
diskCacheEntryCount = 0;
|
|
4842
5017
|
diskCacheLoaded = false;
|
|
@@ -4847,14 +5022,14 @@ function resetApiEmbeddingCacheForTests() {
|
|
|
4847
5022
|
}
|
|
4848
5023
|
function seedApiEmbeddingCacheForTests(entries) {
|
|
4849
5024
|
cache3.clear();
|
|
4850
|
-
|
|
5025
|
+
cachePayloadBytes3 = 0;
|
|
4851
5026
|
cacheDimensions = null;
|
|
4852
5027
|
for (const [key, value] of entries) cacheInsert(key, value, true);
|
|
4853
5028
|
diskCacheLoaded = true;
|
|
4854
5029
|
diskCacheDirty2 = true;
|
|
4855
5030
|
}
|
|
4856
5031
|
function getApiEmbeddingCachePayloadBytesForTests() {
|
|
4857
|
-
return
|
|
5032
|
+
return cachePayloadBytes3;
|
|
4858
5033
|
}
|
|
4859
5034
|
function getApiEmbeddingJsonlLineCountCallsForTests() {
|
|
4860
5035
|
return jsonlLineCountCalls;
|
|
@@ -5028,7 +5203,7 @@ function scheduleDiskSave() {
|
|
|
5028
5203
|
diskSaveTimer = null;
|
|
5029
5204
|
}, DISK_SAVE_DEBOUNCE_MS);
|
|
5030
5205
|
}
|
|
5031
|
-
function
|
|
5206
|
+
function cacheSet2(hash4, value) {
|
|
5032
5207
|
cacheInsert(hash4, value, true);
|
|
5033
5208
|
}
|
|
5034
5209
|
function resolveEnvEmbeddingApiKey() {
|
|
@@ -5148,7 +5323,7 @@ async function waitForRetry(waitMs, signal) {
|
|
|
5148
5323
|
abortSignal.addEventListener("abort", onAbort, { once: true });
|
|
5149
5324
|
});
|
|
5150
5325
|
}
|
|
5151
|
-
var cache3, MAX_CACHE_ENTRIES, MAX_CACHE_PAYLOAD_BYTES, BYTES_PER_DIM, DEFAULT_ASSUMED_DIMENSIONS, MAX_MIGRATION_VALUE_BYTES,
|
|
5326
|
+
var cache3, MAX_CACHE_ENTRIES, MAX_CACHE_PAYLOAD_BYTES, BYTES_PER_DIM, DEFAULT_ASSUMED_DIMENSIONS, MAX_MIGRATION_VALUE_BYTES, cachePayloadBytes3, cacheDimensions, diskCacheEntryCount, diskCacheDirty2, diskSaveTimer, diskCacheLoaded, diskCacheLoadPromise, diskCacheLoadCount, jsonlLineCountCalls, MAX_INPUT_CHARS, MAX_CONCURRENCY, DISK_SAVE_DEBOUNCE_MS, DEFAULT_MAX_BATCH_SIZE, DASHSCOPE_MAX_BATCH_SIZE, MAX_RETRIES2, BASE_DELAY_MS, EmbeddingAPIError, APIEmbeddingProvider;
|
|
5152
5327
|
var init_api_provider = __esm({
|
|
5153
5328
|
"src/embedding/api-provider.ts"() {
|
|
5154
5329
|
"use strict";
|
|
@@ -5160,7 +5335,7 @@ var init_api_provider = __esm({
|
|
|
5160
5335
|
BYTES_PER_DIM = 8;
|
|
5161
5336
|
DEFAULT_ASSUMED_DIMENSIONS = 4096;
|
|
5162
5337
|
MAX_MIGRATION_VALUE_BYTES = 16 * 1024 * 1024;
|
|
5163
|
-
|
|
5338
|
+
cachePayloadBytes3 = 0;
|
|
5164
5339
|
cacheDimensions = null;
|
|
5165
5340
|
diskCacheEntryCount = 0;
|
|
5166
5341
|
diskCacheDirty2 = false;
|
|
@@ -5345,7 +5520,7 @@ var init_api_provider = __esm({
|
|
|
5345
5520
|
} else {
|
|
5346
5521
|
embedding = await apiCall();
|
|
5347
5522
|
}
|
|
5348
|
-
|
|
5523
|
+
cacheSet2(hash4, embedding);
|
|
5349
5524
|
scheduleDiskSave();
|
|
5350
5525
|
return embedding;
|
|
5351
5526
|
}
|
|
@@ -5393,7 +5568,7 @@ var init_api_provider = __esm({
|
|
|
5393
5568
|
for (const item of response.data) {
|
|
5394
5569
|
const originalIdx = chunkIndices[item.index];
|
|
5395
5570
|
results[originalIdx] = item.embedding;
|
|
5396
|
-
|
|
5571
|
+
cacheSet2(textHash2(normalizedTexts[originalIdx], this.cacheKeyNamespace), item.embedding);
|
|
5397
5572
|
}
|
|
5398
5573
|
} catch (error) {
|
|
5399
5574
|
const providerLimit = parseBatchLimit(error);
|
|
@@ -5471,7 +5646,7 @@ var init_api_provider = __esm({
|
|
|
5471
5646
|
throw new Error(`Expected ${this.dimensions}d, got ${embedding.length}d; dimension mismatch`);
|
|
5472
5647
|
}
|
|
5473
5648
|
this.trackUsage(response);
|
|
5474
|
-
|
|
5649
|
+
cacheSet2(hash4, embedding);
|
|
5475
5650
|
scheduleDiskSave();
|
|
5476
5651
|
return embedding;
|
|
5477
5652
|
}
|
|
@@ -6854,6 +7029,7 @@ var init_provider2 = __esm({
|
|
|
6854
7029
|
openai: { baseUrl: "https://api.openai.com/v1", model: "gpt-4.1-nano" },
|
|
6855
7030
|
anthropic: { baseUrl: "https://api.anthropic.com/v1", model: "claude-3-5-haiku-latest" },
|
|
6856
7031
|
openrouter: { baseUrl: "https://openrouter.ai/api/v1", model: "openai/gpt-4.1-nano" },
|
|
7032
|
+
atlascloud: { baseUrl: "https://api.atlascloud.ai/v1", model: "deepseek-ai/deepseek-v3.2" },
|
|
6857
7033
|
custom: { baseUrl: "http://localhost:11434/v1", model: "llama3" }
|
|
6858
7034
|
};
|
|
6859
7035
|
currentConfig = null;
|
|
@@ -7630,7 +7806,7 @@ __export(semantic_index_exports, {
|
|
|
7630
7806
|
upsertSemanticVector: () => upsertSemanticVector,
|
|
7631
7807
|
upsertSemanticVectors: () => upsertSemanticVectors
|
|
7632
7808
|
});
|
|
7633
|
-
import { createHash as
|
|
7809
|
+
import { createHash as createHash4 } from "crypto";
|
|
7634
7810
|
import { createRequire as createRequire3 } from "module";
|
|
7635
7811
|
import path11 from "path";
|
|
7636
7812
|
function createSemanticIndexProfile(provider2) {
|
|
@@ -7644,7 +7820,7 @@ function stateKey(dataDir, profile) {
|
|
|
7644
7820
|
return `${path11.resolve(dataDir)}::${profile.key}`;
|
|
7645
7821
|
}
|
|
7646
7822
|
function tableName(profile) {
|
|
7647
|
-
const digest2 =
|
|
7823
|
+
const digest2 = createHash4("sha256").update(profile.key).digest("hex").slice(0, 20);
|
|
7648
7824
|
return `${TABLE_PREFIX}${digest2}`;
|
|
7649
7825
|
}
|
|
7650
7826
|
function indexRoot(dataDir) {
|
|
@@ -9732,6 +9908,7 @@ var init_secret_filter = __esm({
|
|
|
9732
9908
|
// src/runtime/maintenance-jobs.ts
|
|
9733
9909
|
var maintenance_jobs_exports = {};
|
|
9734
9910
|
__export(maintenance_jobs_exports, {
|
|
9911
|
+
DEFAULT_FAILED_HISTORY_RETENTION_MS: () => DEFAULT_FAILED_HISTORY_RETENTION_MS,
|
|
9735
9912
|
MAINTENANCE_JOB_KINDS: () => MAINTENANCE_JOB_KINDS,
|
|
9736
9913
|
MaintenanceJobStore: () => MaintenanceJobStore,
|
|
9737
9914
|
MaintenanceJobWorker: () => MaintenanceJobWorker,
|
|
@@ -9781,7 +9958,7 @@ function normalizedKinds(kinds) {
|
|
|
9781
9958
|
function getMaintenanceRetryDelayMs(attempts) {
|
|
9782
9959
|
return Math.min(6e4, 1e3 * 2 ** Math.max(0, attempts - 1));
|
|
9783
9960
|
}
|
|
9784
|
-
var MAINTENANCE_JOB_KINDS, DEFAULT_MAX_ATTEMPTS, DEFAULT_LEASE_MS, DEFAULT_POLL_INTERVAL_MS, MAX_ERROR_LENGTH, DEFAULT_COMPLETED_HISTORY_RETENTION_MS, MaintenanceJobStore, MaintenanceJobWorker;
|
|
9961
|
+
var MAINTENANCE_JOB_KINDS, DEFAULT_MAX_ATTEMPTS, DEFAULT_LEASE_MS, DEFAULT_POLL_INTERVAL_MS, MAX_ERROR_LENGTH, DEFAULT_COMPLETED_HISTORY_RETENTION_MS, DEFAULT_FAILED_HISTORY_RETENTION_MS, MaintenanceJobStore, MaintenanceJobWorker;
|
|
9785
9962
|
var init_maintenance_jobs = __esm({
|
|
9786
9963
|
"src/runtime/maintenance-jobs.ts"() {
|
|
9787
9964
|
"use strict";
|
|
@@ -9808,6 +9985,7 @@ var init_maintenance_jobs = __esm({
|
|
|
9808
9985
|
DEFAULT_POLL_INTERVAL_MS = 2e3;
|
|
9809
9986
|
MAX_ERROR_LENGTH = 1e3;
|
|
9810
9987
|
DEFAULT_COMPLETED_HISTORY_RETENTION_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
9988
|
+
DEFAULT_FAILED_HISTORY_RETENTION_MS = 30 * 24 * 60 * 60 * 1e3;
|
|
9811
9989
|
MaintenanceJobStore = class {
|
|
9812
9990
|
db;
|
|
9813
9991
|
constructor(dataDir) {
|
|
@@ -9934,18 +10112,21 @@ var init_maintenance_jobs = __esm({
|
|
|
9934
10112
|
}
|
|
9935
10113
|
/**
|
|
9936
10114
|
* Completed jobs are useful recent operator history, not permanent data.
|
|
9937
|
-
* Failed
|
|
9938
|
-
*
|
|
10115
|
+
* Failed diagnostics are retained longer, but are still bounded so a
|
|
10116
|
+
* permanently failing job kind cannot grow the database forever.
|
|
9939
10117
|
*/
|
|
9940
10118
|
pruneCompletedHistory(options = {}) {
|
|
9941
10119
|
const now3 = options.now ?? Date.now();
|
|
9942
10120
|
const maxAgeMs = Number.isFinite(options.maxAgeMs) ? Math.max(0, Math.floor(options.maxAgeMs)) : DEFAULT_COMPLETED_HISTORY_RETENTION_MS;
|
|
10121
|
+
const failedMaxAgeMs = Number.isFinite(options.failedMaxAgeMs) ? Math.max(0, Math.floor(options.failedMaxAgeMs)) : DEFAULT_FAILED_HISTORY_RETENTION_MS;
|
|
9943
10122
|
const result = this.db.prepare(`
|
|
9944
10123
|
DELETE FROM maintenance_jobs
|
|
9945
|
-
WHERE status = 'completed'
|
|
10124
|
+
WHERE (status = 'completed'
|
|
9946
10125
|
AND completed_at IS NOT NULL
|
|
9947
|
-
AND completed_at < ?
|
|
9948
|
-
|
|
10126
|
+
AND completed_at < ?)
|
|
10127
|
+
OR (status = 'failed'
|
|
10128
|
+
AND updated_at < ?)
|
|
10129
|
+
`).run(now3 - maxAgeMs, now3 - failedMaxAgeMs);
|
|
9949
10130
|
return Number(result.changes ?? 0);
|
|
9950
10131
|
}
|
|
9951
10132
|
claimNext(options) {
|
|
@@ -10299,7 +10480,7 @@ var init_lifecycle = __esm({
|
|
|
10299
10480
|
});
|
|
10300
10481
|
|
|
10301
10482
|
// src/store/evidence-store.ts
|
|
10302
|
-
import { createHash as
|
|
10483
|
+
import { createHash as createHash5, randomUUID as randomUUID3 } from "crypto";
|
|
10303
10484
|
function safeJson(value, fallback) {
|
|
10304
10485
|
if (typeof value !== "string" || value.length === 0) return fallback;
|
|
10305
10486
|
try {
|
|
@@ -10333,7 +10514,7 @@ function rowToCard(row) {
|
|
|
10333
10514
|
};
|
|
10334
10515
|
}
|
|
10335
10516
|
function observationHash(observation) {
|
|
10336
|
-
return
|
|
10517
|
+
return createHash5("sha256").update(JSON.stringify({
|
|
10337
10518
|
projectId: observation.projectId,
|
|
10338
10519
|
id: observation.id,
|
|
10339
10520
|
title: observation.title,
|
|
@@ -10927,13 +11108,13 @@ __export(workspace_exports, {
|
|
|
10927
11108
|
loadKnowledgeWorkspace: () => loadKnowledgeWorkspace,
|
|
10928
11109
|
resolveKnowledgeWorkspaceFile: () => resolveKnowledgeWorkspaceFile
|
|
10929
11110
|
});
|
|
10930
|
-
import { createHash as
|
|
11111
|
+
import { createHash as createHash6 } from "crypto";
|
|
10931
11112
|
import { execFile } from "child_process";
|
|
10932
11113
|
import { promises as fs9 } from "fs";
|
|
10933
11114
|
import path14 from "path";
|
|
10934
11115
|
import { promisify } from "util";
|
|
10935
11116
|
function hash(value) {
|
|
10936
|
-
return
|
|
11117
|
+
return createHash6("sha256").update(value).digest("hex");
|
|
10937
11118
|
}
|
|
10938
11119
|
function workspaceId(projectId, mode) {
|
|
10939
11120
|
return "workspace:" + hash(projectId + ":" + mode).slice(0, 24);
|
|
@@ -12086,14 +12267,14 @@ __export(asset_store_exports, {
|
|
|
12086
12267
|
readMediaAsset: () => readMediaAsset,
|
|
12087
12268
|
removeMediaAsset: () => removeMediaAsset
|
|
12088
12269
|
});
|
|
12089
|
-
import { createHash as
|
|
12270
|
+
import { createHash as createHash7, randomUUID as randomUUID6 } from "crypto";
|
|
12090
12271
|
import { copyFile, lstat, mkdir as mkdir3, open, readFile as readFile3, readdir, rename as rename2, rm, stat as stat2, writeFile as writeFile3 } from "fs/promises";
|
|
12091
12272
|
import path15 from "path";
|
|
12092
12273
|
function mediaRoot(dataDir) {
|
|
12093
12274
|
return path15.resolve(dataDir, "media");
|
|
12094
12275
|
}
|
|
12095
12276
|
function projectStorageKey(projectId) {
|
|
12096
|
-
return
|
|
12277
|
+
return createHash7("sha256").update(projectId).digest("hex").slice(0, 16);
|
|
12097
12278
|
}
|
|
12098
12279
|
function validateUnderRoot(root, candidate) {
|
|
12099
12280
|
const resolved = path15.resolve(candidate);
|
|
@@ -12153,7 +12334,7 @@ async function readHeader(filePath, bytes = 32) {
|
|
|
12153
12334
|
}
|
|
12154
12335
|
async function sha256File(filePath) {
|
|
12155
12336
|
const bytes = await readFile3(filePath);
|
|
12156
|
-
return
|
|
12337
|
+
return createHash7("sha256").update(bytes).digest("hex");
|
|
12157
12338
|
}
|
|
12158
12339
|
function destinationFor(root, projectId, sha256, extension3) {
|
|
12159
12340
|
const relative5 = path15.join("assets", projectStorageKey(projectId), sha256.slice(0, 2), `${sha256}${extension3}`);
|
|
@@ -12259,7 +12440,7 @@ async function importMediaBuffer(input) {
|
|
|
12259
12440
|
if (input.bytes.length === 0) throw new Error("Media import rejects empty payloads");
|
|
12260
12441
|
if (input.bytes.length > maxBytes) throw new Error(`Media payload is too large (${input.bytes.length} bytes; limit ${maxBytes})`);
|
|
12261
12442
|
const detected = detectMedia(input.bytes.subarray(0, 32));
|
|
12262
|
-
const sha256 =
|
|
12443
|
+
const sha256 = createHash7("sha256").update(input.bytes).digest("hex");
|
|
12263
12444
|
return importKnownMedia({
|
|
12264
12445
|
dataDir: input.dataDir,
|
|
12265
12446
|
projectId: input.projectId,
|
|
@@ -12277,7 +12458,7 @@ async function readMediaAsset(dataDir, asset, maxBytes = DEFAULT_MAX_MEDIA_BYTES
|
|
|
12277
12458
|
if (asset.byteSize > maxBytes) throw new Error(`Media asset exceeds read limit (${asset.byteSize} bytes; limit ${maxBytes})`);
|
|
12278
12459
|
const bytes = await readFile3(getMediaAssetPath(dataDir, asset));
|
|
12279
12460
|
if (bytes.length !== asset.byteSize) throw new Error(`Media asset size no longer matches metadata: ${asset.id}`);
|
|
12280
|
-
const sha256 =
|
|
12461
|
+
const sha256 = createHash7("sha256").update(bytes).digest("hex");
|
|
12281
12462
|
if (sha256 !== asset.sha256) throw new Error(`Media asset hash no longer matches metadata: ${asset.id}`);
|
|
12282
12463
|
return bytes;
|
|
12283
12464
|
}
|
|
@@ -65147,7 +65328,7 @@ var require_gaxios = __commonJS({
|
|
|
65147
65328
|
var retry_js_1 = require_retry3();
|
|
65148
65329
|
var stream_1 = __require("stream");
|
|
65149
65330
|
var interceptor_js_1 = require_interceptor();
|
|
65150
|
-
var
|
|
65331
|
+
var randomUUID20 = async () => globalThis.crypto?.randomUUID() || (await import("crypto")).randomUUID();
|
|
65151
65332
|
var HTTP_STATUS_NO_CONTENT = 204;
|
|
65152
65333
|
var Gaxios = class {
|
|
65153
65334
|
agentCache = /* @__PURE__ */ new Map();
|
|
@@ -65420,7 +65601,7 @@ var require_gaxios = __commonJS({
|
|
|
65420
65601
|
*/
|
|
65421
65602
|
["Blob", "File", "FormData"].includes(opts.data?.constructor?.name || "");
|
|
65422
65603
|
if (opts.multipart?.length) {
|
|
65423
|
-
const boundary = await
|
|
65604
|
+
const boundary = await randomUUID20();
|
|
65424
65605
|
preparedHeaders.set("content-type", `multipart/related; boundary=${boundary}`);
|
|
65425
65606
|
opts.body = stream_1.Readable.from(this.getMultipartRequest(opts.multipart, boundary));
|
|
65426
65607
|
} else if (shouldDirectlyPassData) {
|
|
@@ -71092,16 +71273,16 @@ var require_jwtaccess = __commonJS({
|
|
|
71092
71273
|
* @returns A string that returns the cached key.
|
|
71093
71274
|
*/
|
|
71094
71275
|
getCachedKey(url, scopes) {
|
|
71095
|
-
let
|
|
71276
|
+
let cacheKey3 = url;
|
|
71096
71277
|
if (scopes && Array.isArray(scopes) && scopes.length) {
|
|
71097
|
-
|
|
71278
|
+
cacheKey3 = url ? `${url}_${scopes.join("_")}` : `${scopes.join("_")}`;
|
|
71098
71279
|
} else if (typeof scopes === "string") {
|
|
71099
|
-
|
|
71280
|
+
cacheKey3 = url ? `${url}_${scopes}` : scopes;
|
|
71100
71281
|
}
|
|
71101
|
-
if (!
|
|
71282
|
+
if (!cacheKey3) {
|
|
71102
71283
|
throw Error("Scopes or url must be provided");
|
|
71103
71284
|
}
|
|
71104
|
-
return
|
|
71285
|
+
return cacheKey3;
|
|
71105
71286
|
}
|
|
71106
71287
|
/**
|
|
71107
71288
|
* Get a non-expired access token, after refreshing if necessary.
|
|
@@ -77647,7 +77828,7 @@ var require_websocket = __commonJS({
|
|
|
77647
77828
|
var http3 = __require("http");
|
|
77648
77829
|
var net = __require("net");
|
|
77649
77830
|
var tls = __require("tls");
|
|
77650
|
-
var { randomBytes: randomBytes2, createHash:
|
|
77831
|
+
var { randomBytes: randomBytes2, createHash: createHash20 } = __require("crypto");
|
|
77651
77832
|
var { Duplex, Readable: Readable2 } = __require("stream");
|
|
77652
77833
|
var { URL: URL2 } = __require("url");
|
|
77653
77834
|
var PerMessageDeflate2 = require_permessage_deflate();
|
|
@@ -78315,7 +78496,7 @@ var require_websocket = __commonJS({
|
|
|
78315
78496
|
abortHandshake(websocket, socket, "Invalid Upgrade header");
|
|
78316
78497
|
return;
|
|
78317
78498
|
}
|
|
78318
|
-
const digest2 =
|
|
78499
|
+
const digest2 = createHash20("sha1").update(key + GUID).digest("base64");
|
|
78319
78500
|
if (res.headers["sec-websocket-accept"] !== digest2) {
|
|
78320
78501
|
abortHandshake(websocket, socket, "Invalid Sec-WebSocket-Accept header");
|
|
78321
78502
|
return;
|
|
@@ -78687,7 +78868,7 @@ var require_websocket_server = __commonJS({
|
|
|
78687
78868
|
var EventEmitter2 = __require("events");
|
|
78688
78869
|
var http3 = __require("http");
|
|
78689
78870
|
var { Duplex } = __require("stream");
|
|
78690
|
-
var { createHash:
|
|
78871
|
+
var { createHash: createHash20 } = __require("crypto");
|
|
78691
78872
|
var extension3 = require_extension();
|
|
78692
78873
|
var PerMessageDeflate2 = require_permessage_deflate();
|
|
78693
78874
|
var subprotocol2 = require_subprotocol();
|
|
@@ -78994,7 +79175,7 @@ var require_websocket_server = __commonJS({
|
|
|
78994
79175
|
);
|
|
78995
79176
|
}
|
|
78996
79177
|
if (this._state > RUNNING) return abortHandshake(socket, 503);
|
|
78997
|
-
const digest2 =
|
|
79178
|
+
const digest2 = createHash20("sha1").update(key + GUID).digest("base64");
|
|
78998
79179
|
const headers = [
|
|
78999
79180
|
"HTTP/1.1 101 Switching Protocols",
|
|
79000
79181
|
"Upgrade: websocket",
|
|
@@ -143053,9 +143234,9 @@ var init_union_priority_sort = __esm({
|
|
|
143053
143234
|
// node_modules/typebox/build/value/clean/from_union.mjs
|
|
143054
143235
|
function FromUnion9(context, type, value) {
|
|
143055
143236
|
for (const schema of UnionPrioritySort(type.anyOf)) {
|
|
143056
|
-
const
|
|
143057
|
-
if (Check2(context, schema,
|
|
143058
|
-
return
|
|
143237
|
+
const clean2 = FromType19(context, schema, Clone2(value));
|
|
143238
|
+
if (Check2(context, schema, clean2))
|
|
143239
|
+
return clean2;
|
|
143059
143240
|
}
|
|
143060
143241
|
return value;
|
|
143061
143242
|
}
|
|
@@ -147693,9 +147874,9 @@ var init_long_term = __esm({
|
|
|
147693
147874
|
});
|
|
147694
147875
|
|
|
147695
147876
|
// src/codegraph/ids.ts
|
|
147696
|
-
import { createHash as
|
|
147877
|
+
import { createHash as createHash8 } from "crypto";
|
|
147697
147878
|
function digest(input) {
|
|
147698
|
-
return
|
|
147879
|
+
return createHash8("sha256").update(input).digest("hex").slice(0, 16);
|
|
147699
147880
|
}
|
|
147700
147881
|
function normalizeCodePath(path37) {
|
|
147701
147882
|
return path37.replace(/\\/g, "/").replace(/^\.\//, "").replace(/\/+/g, "/");
|
|
@@ -148743,7 +148924,7 @@ var init_store = __esm({
|
|
|
148743
148924
|
|
|
148744
148925
|
// src/codegraph/code-state.ts
|
|
148745
148926
|
import { execFile as execFile2 } from "child_process";
|
|
148746
|
-
import { createHash as
|
|
148927
|
+
import { createHash as createHash9 } from "crypto";
|
|
148747
148928
|
import { promisify as promisify3 } from "util";
|
|
148748
148929
|
async function runGit(rootPath, args) {
|
|
148749
148930
|
try {
|
|
@@ -148772,7 +148953,7 @@ function changedPathCount(status) {
|
|
|
148772
148953
|
return count2;
|
|
148773
148954
|
}
|
|
148774
148955
|
function fingerprint(baseRevision, status) {
|
|
148775
|
-
return
|
|
148956
|
+
return createHash9("sha256").update(baseRevision ?? "").update("\0").update(status).digest("hex");
|
|
148776
148957
|
}
|
|
148777
148958
|
async function collectCodeStateSnapshot(input) {
|
|
148778
148959
|
const [revision, status] = await Promise.all([
|
|
@@ -148866,12 +149047,12 @@ var init_exclude3 = __esm({
|
|
|
148866
149047
|
});
|
|
148867
149048
|
|
|
148868
149049
|
// src/codegraph/semantic-provider.ts
|
|
148869
|
-
import { createHash as
|
|
149050
|
+
import { createHash as createHash10 } from "crypto";
|
|
148870
149051
|
import "fs";
|
|
148871
149052
|
import { resolve } from "path";
|
|
148872
149053
|
import ts from "typescript";
|
|
148873
149054
|
function hashText(value) {
|
|
148874
|
-
return
|
|
149055
|
+
return createHash10("sha256").update(value).digest("hex");
|
|
148875
149056
|
}
|
|
148876
149057
|
function canonicalPath(value) {
|
|
148877
149058
|
const normalized = resolve(value).replace(/\\/g, "/");
|
|
@@ -149216,11 +149397,11 @@ __export(lite_provider_exports, {
|
|
|
149216
149397
|
indexProjectLite: () => indexProjectLite,
|
|
149217
149398
|
refreshProjectLite: () => refreshProjectLite
|
|
149218
149399
|
});
|
|
149219
|
-
import { createHash as
|
|
149400
|
+
import { createHash as createHash11 } from "crypto";
|
|
149220
149401
|
import { existsSync as existsSync12, readdirSync as readdirSync2, readFileSync as readFileSync8, statSync as statSync3 } from "fs";
|
|
149221
149402
|
import { join as join4, relative as relative2 } from "path";
|
|
149222
149403
|
function hashText2(text3) {
|
|
149223
|
-
return
|
|
149404
|
+
return createHash11("sha256").update(text3).digest("hex");
|
|
149224
149405
|
}
|
|
149225
149406
|
function extension2(path37) {
|
|
149226
149407
|
const index = path37.lastIndexOf(".");
|
|
@@ -149853,7 +150034,7 @@ var claim_store_exports = {};
|
|
|
149853
150034
|
__export(claim_store_exports, {
|
|
149854
150035
|
ClaimStore: () => ClaimStore
|
|
149855
150036
|
});
|
|
149856
|
-
import { createHash as
|
|
150037
|
+
import { createHash as createHash12, randomUUID as randomUUID12 } from "crypto";
|
|
149857
150038
|
function optionalText3(value) {
|
|
149858
150039
|
return typeof value === "string" && value ? value : void 0;
|
|
149859
150040
|
}
|
|
@@ -149906,7 +150087,7 @@ function rowToEvent3(row) {
|
|
|
149906
150087
|
};
|
|
149907
150088
|
}
|
|
149908
150089
|
function evidenceKey(input) {
|
|
149909
|
-
return
|
|
150090
|
+
return createHash12("sha256").update(JSON.stringify([
|
|
149910
150091
|
input.evidenceKind,
|
|
149911
150092
|
input.evidenceId,
|
|
149912
150093
|
input.relation,
|
|
@@ -150104,7 +150285,7 @@ __export(claims_exports, {
|
|
|
150104
150285
|
supersedeClaim: () => supersedeClaim,
|
|
150105
150286
|
writeClaim: () => writeClaim
|
|
150106
150287
|
});
|
|
150107
|
-
import { createHash as
|
|
150288
|
+
import { createHash as createHash13, randomUUID as randomUUID13 } from "crypto";
|
|
150108
150289
|
function compactText2(value, field) {
|
|
150109
150290
|
if (typeof value !== "string") throw new Error("Claim " + field + " must be text");
|
|
150110
150291
|
const sanitized = sanitizeCredentials(value).trim().replace(/\s+/g, " ");
|
|
@@ -150116,7 +150297,7 @@ function normalizedTerm(value) {
|
|
|
150116
150297
|
return compactText2(value, "identity").toLocaleLowerCase("en-US");
|
|
150117
150298
|
}
|
|
150118
150299
|
function hashIdentity(parts) {
|
|
150119
|
-
return
|
|
150300
|
+
return createHash13("sha256").update(parts.join(String.fromCharCode(31))).digest("hex");
|
|
150120
150301
|
}
|
|
150121
150302
|
function buildClaimIdentity(input) {
|
|
150122
150303
|
const subject = normalizedTerm(input.subject);
|
|
@@ -150357,7 +150538,7 @@ function supersedeClaim(store, input) {
|
|
|
150357
150538
|
});
|
|
150358
150539
|
}
|
|
150359
150540
|
function hashObservation(observation) {
|
|
150360
|
-
return
|
|
150541
|
+
return createHash13("sha256").update(JSON.stringify([
|
|
150361
150542
|
observation.title,
|
|
150362
150543
|
observation.narrative,
|
|
150363
150544
|
observation.facts,
|
|
@@ -150601,11 +150782,11 @@ var init_frontmatter = __esm({
|
|
|
150601
150782
|
});
|
|
150602
150783
|
|
|
150603
150784
|
// src/knowledge/markdown.ts
|
|
150604
|
-
import { createHash as
|
|
150785
|
+
import { createHash as createHash14 } from "crypto";
|
|
150605
150786
|
import { promises as fs13 } from "fs";
|
|
150606
150787
|
import path22 from "path";
|
|
150607
150788
|
function hashContent(content) {
|
|
150608
|
-
return
|
|
150789
|
+
return createHash14("sha256").update(content).digest("hex");
|
|
150609
150790
|
}
|
|
150610
150791
|
function stringField(data, key) {
|
|
150611
150792
|
const value = data[key];
|
|
@@ -150731,11 +150912,11 @@ __export(wiki_exports, {
|
|
|
150731
150912
|
lintKnowledgeWorkspace: () => lintKnowledgeWorkspace,
|
|
150732
150913
|
readKnowledgePage: () => readKnowledgePage
|
|
150733
150914
|
});
|
|
150734
|
-
import { createHash as
|
|
150915
|
+
import { createHash as createHash15 } from "crypto";
|
|
150735
150916
|
import { promises as fs14 } from "fs";
|
|
150736
150917
|
import path23 from "path";
|
|
150737
150918
|
function hash2(value) {
|
|
150738
|
-
return
|
|
150919
|
+
return createHash15("sha256").update(value).digest("hex");
|
|
150739
150920
|
}
|
|
150740
150921
|
function now() {
|
|
150741
150922
|
return (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -151954,11 +152135,11 @@ __export(workflows_exports, {
|
|
|
151954
152135
|
syncCanonicalWorkflows: () => syncCanonicalWorkflows,
|
|
151955
152136
|
writeCanonicalWorkflow: () => writeCanonicalWorkflow
|
|
151956
152137
|
});
|
|
151957
|
-
import { createHash as
|
|
152138
|
+
import { createHash as createHash16 } from "crypto";
|
|
151958
152139
|
import { promises as fs15 } from "fs";
|
|
151959
152140
|
import path24 from "path";
|
|
151960
152141
|
function hash3(value) {
|
|
151961
|
-
return
|
|
152142
|
+
return createHash16("sha256").update(value).digest("hex");
|
|
151962
152143
|
}
|
|
151963
152144
|
function now2() {
|
|
151964
152145
|
return (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -155993,8 +156174,8 @@ function legacyBehavior(homeDir) {
|
|
|
155993
156174
|
function getBehaviorConfig(options = {}) {
|
|
155994
156175
|
const homeDir = options.homeDir ?? homedir22();
|
|
155995
156176
|
const projectRoot = options.projectRoot === void 0 ? detectProject()?.rootPath ?? null : options.projectRoot;
|
|
155996
|
-
const
|
|
155997
|
-
const cached = cache4.get(
|
|
156177
|
+
const cacheKey3 = `${homeDir}\0${projectRoot ?? ""}`;
|
|
156178
|
+
const cached = cache4.get(cacheKey3);
|
|
155998
156179
|
if (cached) return cached;
|
|
155999
156180
|
const legacy = legacyBehavior(homeDir);
|
|
156000
156181
|
let resolved = {};
|
|
@@ -156008,7 +156189,7 @@ function getBehaviorConfig(options = {}) {
|
|
|
156008
156189
|
autoCleanup: typeof resolved.autoCleanup === "boolean" ? resolved.autoCleanup : typeof legacy.autoCleanup === "boolean" ? legacy.autoCleanup : DEFAULTS.autoCleanup,
|
|
156009
156190
|
formationMode: isFormationMode(resolved.formation) ? resolved.formation : isFormationMode(legacy.formationMode) ? legacy.formationMode : DEFAULTS.formationMode
|
|
156010
156191
|
};
|
|
156011
|
-
cache4.set(
|
|
156192
|
+
cache4.set(cacheKey3, config);
|
|
156012
156193
|
return config;
|
|
156013
156194
|
}
|
|
156014
156195
|
function resetBehaviorConfigCache() {
|
|
@@ -156613,6 +156794,7 @@ function freshnessForMemory(status) {
|
|
|
156613
156794
|
return "unknown";
|
|
156614
156795
|
}
|
|
156615
156796
|
function receiptOmissionKind(raw) {
|
|
156797
|
+
if (raw.includes("continuity")) return "continuity";
|
|
156616
156798
|
if (raw.includes("continuation")) return "continuation";
|
|
156617
156799
|
if (raw.includes("task")) return "task";
|
|
156618
156800
|
if (raw.includes("fact")) return "current-fact";
|
|
@@ -156723,6 +156905,77 @@ function renderTaskWorksetPrompt(input) {
|
|
|
156723
156905
|
trust: "source-backed"
|
|
156724
156906
|
});
|
|
156725
156907
|
appendLine(lines, "Task lens: " + input.lens, maxTokens, omitted, "lens");
|
|
156908
|
+
if (input.continuity) {
|
|
156909
|
+
const continuity = input.continuity;
|
|
156910
|
+
appendLine(lines, "", maxTokens, omitted, "continuity-heading");
|
|
156911
|
+
appendLine(lines, "Task continuity", maxTokens, omitted, "continuity-heading", selected, {
|
|
156912
|
+
kind: "continuity",
|
|
156913
|
+
id: "continuity:" + continuity.taskId,
|
|
156914
|
+
reason: "explicit task continuity ledger",
|
|
156915
|
+
trust: "source-backed"
|
|
156916
|
+
});
|
|
156917
|
+
appendLine(
|
|
156918
|
+
lines,
|
|
156919
|
+
"- Status: " + continuity.status + " | " + short(continuity.task, 30),
|
|
156920
|
+
maxTokens,
|
|
156921
|
+
omitted,
|
|
156922
|
+
"continuity-task"
|
|
156923
|
+
);
|
|
156924
|
+
appendLine(
|
|
156925
|
+
lines,
|
|
156926
|
+
"- Outcome: " + continuity.outcome.state,
|
|
156927
|
+
maxTokens,
|
|
156928
|
+
omitted,
|
|
156929
|
+
"continuity-outcome",
|
|
156930
|
+
selected,
|
|
156931
|
+
{
|
|
156932
|
+
kind: "continuity",
|
|
156933
|
+
id: "continuity:" + continuity.taskId,
|
|
156934
|
+
reason: "deterministic task outcome projection",
|
|
156935
|
+
trust: "derived"
|
|
156936
|
+
}
|
|
156937
|
+
);
|
|
156938
|
+
for (const requirement of continuity.requirements.slice(0, 3)) {
|
|
156939
|
+
appendLine(lines, "- Requirement: " + short(requirement, 24), maxTokens, omitted, "continuity-requirement", selected, {
|
|
156940
|
+
kind: "continuity",
|
|
156941
|
+
id: "continuity:" + continuity.taskId,
|
|
156942
|
+
reason: "explicit task requirement",
|
|
156943
|
+
trust: "source-backed"
|
|
156944
|
+
});
|
|
156945
|
+
}
|
|
156946
|
+
for (const decision of continuity.decisions.slice(0, 2)) {
|
|
156947
|
+
appendLine(lines, "- Decision: " + short(decision, 24), maxTokens, omitted, "continuity-decision", selected, {
|
|
156948
|
+
kind: "continuity",
|
|
156949
|
+
id: "continuity:" + continuity.taskId,
|
|
156950
|
+
reason: "explicit task decision",
|
|
156951
|
+
trust: "source-backed"
|
|
156952
|
+
});
|
|
156953
|
+
}
|
|
156954
|
+
for (const verification of continuity.verification.slice(-3)) {
|
|
156955
|
+
appendLine(
|
|
156956
|
+
lines,
|
|
156957
|
+
"- Verify [" + verification.status + "]: " + short(verification.content, 22),
|
|
156958
|
+
maxTokens,
|
|
156959
|
+
omitted,
|
|
156960
|
+
"continuity-verification",
|
|
156961
|
+
selected,
|
|
156962
|
+
{
|
|
156963
|
+
kind: "continuity",
|
|
156964
|
+
id: "continuity:" + continuity.taskId,
|
|
156965
|
+
reason: "task verification state",
|
|
156966
|
+
trust: "source-backed"
|
|
156967
|
+
}
|
|
156968
|
+
);
|
|
156969
|
+
}
|
|
156970
|
+
for (const risk of continuity.risks.slice(0, 2)) {
|
|
156971
|
+
appendLine(lines, "- Risk: " + short(risk, 22), maxTokens, omitted, "continuity-risk", selected, {
|
|
156972
|
+
kind: "continuity",
|
|
156973
|
+
id: "continuity:" + continuity.taskId,
|
|
156974
|
+
reason: "open task risk",
|
|
156975
|
+
trust: "source-backed"
|
|
156976
|
+
});
|
|
156977
|
+
}
|
|
156978
|
+
}
|
|
156726
156979
|
if (input.alwaysOn) {
|
|
156727
156980
|
const hasAlwaysOn = input.alwaysOn.profile.length > 0 || Boolean(input.alwaysOn.state) || input.alwaysOn.durable.length > 0;
|
|
156728
156981
|
if (hasAlwaysOn) {
|
|
@@ -157246,6 +157499,7 @@ async function buildTaskWorkset(input) {
|
|
|
157246
157499
|
version: "1.3",
|
|
157247
157500
|
task,
|
|
157248
157501
|
lens: input.lens,
|
|
157502
|
+
...input.continuity ? { continuity: input.continuity } : {},
|
|
157249
157503
|
...input.alwaysOn && (input.alwaysOn.profile.length > 0 || input.alwaysOn.state || input.alwaysOn.durable.length > 0) ? { alwaysOn: input.alwaysOn } : {},
|
|
157250
157504
|
currentFacts: input.currentFacts?.map((fact) => fact.startsWith("Historical note:") ? short(fact, 48) : short(fact, 28)).slice(0, 4) ?? [],
|
|
157251
157505
|
...continuation ? { continuation } : {},
|
|
@@ -158630,7 +158884,7 @@ var compaction_checkpoint_store_exports = {};
|
|
|
158630
158884
|
__export(compaction_checkpoint_store_exports, {
|
|
158631
158885
|
CompactionCheckpointStore: () => CompactionCheckpointStore
|
|
158632
158886
|
});
|
|
158633
|
-
import { createHash as
|
|
158887
|
+
import { createHash as createHash18, randomUUID as randomUUID16 } from "crypto";
|
|
158634
158888
|
function optionalText7(value) {
|
|
158635
158889
|
return typeof value === "string" && value ? value : void 0;
|
|
158636
158890
|
}
|
|
@@ -158672,7 +158926,7 @@ function sourceKeyFor(input, summary) {
|
|
|
158672
158926
|
input.tokensBefore ?? "",
|
|
158673
158927
|
input.firstKeptEntryId ?? ""
|
|
158674
158928
|
].join("\0");
|
|
158675
|
-
return `derived:${
|
|
158929
|
+
return `derived:${createHash18("sha256").update(material).digest("hex").slice(0, 32)}`;
|
|
158676
158930
|
}
|
|
158677
158931
|
function rowToCheckpoint(row) {
|
|
158678
158932
|
return {
|
|
@@ -158930,6 +159184,305 @@ var init_compaction_checkpoint_store = __esm({
|
|
|
158930
159184
|
}
|
|
158931
159185
|
});
|
|
158932
159186
|
|
|
159187
|
+
// src/knowledge/task-continuity.ts
|
|
159188
|
+
var task_continuity_exports = {};
|
|
159189
|
+
__export(task_continuity_exports, {
|
|
159190
|
+
TASK_CONTINUITY_EVENT_KINDS: () => TASK_CONTINUITY_EVENT_KINDS,
|
|
159191
|
+
TaskContinuityStore: () => TaskContinuityStore,
|
|
159192
|
+
evaluateTaskContinuity: () => evaluateTaskContinuity
|
|
159193
|
+
});
|
|
159194
|
+
import { randomUUID as randomUUID17 } from "crypto";
|
|
159195
|
+
function clean(value, maxLength = MAX_TEXT_LENGTH2) {
|
|
159196
|
+
return sanitizeCredentials(value).replace(/\s+/g, " ").trim().slice(0, maxLength);
|
|
159197
|
+
}
|
|
159198
|
+
function cleanList(values, maxLength = MAX_TEXT_LENGTH2) {
|
|
159199
|
+
return [...new Set((values ?? []).map((value) => clean(value, maxLength)).filter(Boolean))].slice(0, MAX_LIST_ITEMS2);
|
|
159200
|
+
}
|
|
159201
|
+
function parseRefs(value) {
|
|
159202
|
+
if (typeof value !== "string") return [];
|
|
159203
|
+
try {
|
|
159204
|
+
const parsed = JSON.parse(value);
|
|
159205
|
+
return Array.isArray(parsed) ? cleanList(parsed.filter((item) => typeof item === "string"), 500).slice(0, MAX_EVIDENCE_REFS) : [];
|
|
159206
|
+
} catch {
|
|
159207
|
+
return [];
|
|
159208
|
+
}
|
|
159209
|
+
}
|
|
159210
|
+
function evaluateTaskContinuity(ledger) {
|
|
159211
|
+
const verification = {
|
|
159212
|
+
passed: ledger.verification.filter((item) => item.status === "passed").length,
|
|
159213
|
+
failed: ledger.verification.filter((item) => item.status === "failed").length,
|
|
159214
|
+
pending: ledger.verification.filter((item) => item.status === "pending").length,
|
|
159215
|
+
skipped: ledger.verification.filter((item) => item.status === "skipped").length
|
|
159216
|
+
};
|
|
159217
|
+
const reasons = [];
|
|
159218
|
+
if (verification.failed > 0) reasons.push("verification-failed");
|
|
159219
|
+
if (verification.pending > 0) reasons.push("verification-pending");
|
|
159220
|
+
if (ledger.risks.length > 0) reasons.push("open-risks");
|
|
159221
|
+
if (ledger.status === "blocked") reasons.push("task-blocked");
|
|
159222
|
+
if (ledger.status === "abandoned") reasons.push("task-abandoned");
|
|
159223
|
+
if (ledger.status === "blocked" || ledger.status === "abandoned" || verification.failed > 0) {
|
|
159224
|
+
return {
|
|
159225
|
+
state: "at-risk",
|
|
159226
|
+
score: verification.passed > verification.failed ? 0.55 : 0.2,
|
|
159227
|
+
verification,
|
|
159228
|
+
reasons
|
|
159229
|
+
};
|
|
159230
|
+
}
|
|
159231
|
+
if (ledger.status === "completed") {
|
|
159232
|
+
if (verification.passed > 0 && verification.pending === 0 && verification.skipped === 0) {
|
|
159233
|
+
return {
|
|
159234
|
+
state: ledger.risks.length > 0 ? "validated-with-risks" : "validated",
|
|
159235
|
+
score: ledger.risks.length > 0 ? 0.8 : 1,
|
|
159236
|
+
verification,
|
|
159237
|
+
reasons: reasons.length > 0 ? reasons : ["verification-passed"]
|
|
159238
|
+
};
|
|
159239
|
+
}
|
|
159240
|
+
return {
|
|
159241
|
+
state: "unverified",
|
|
159242
|
+
score: 0.4,
|
|
159243
|
+
verification,
|
|
159244
|
+
reasons: reasons.length > 0 ? reasons : ["no-passing-verification"]
|
|
159245
|
+
};
|
|
159246
|
+
}
|
|
159247
|
+
return {
|
|
159248
|
+
state: "in-progress",
|
|
159249
|
+
score: verification.passed > 0 && verification.pending === 0 ? 0.75 : 0.5,
|
|
159250
|
+
verification,
|
|
159251
|
+
reasons: reasons.length > 0 ? reasons : ["task-open"]
|
|
159252
|
+
};
|
|
159253
|
+
}
|
|
159254
|
+
function rowToEvent4(row) {
|
|
159255
|
+
const status = row.item_status ? String(row.item_status) : void 0;
|
|
159256
|
+
return {
|
|
159257
|
+
id: String(row.id),
|
|
159258
|
+
projectId: String(row.project_id),
|
|
159259
|
+
taskId: String(row.task_id),
|
|
159260
|
+
task: clean(String(row.task), MAX_TASK_LENGTH),
|
|
159261
|
+
kind: row.kind,
|
|
159262
|
+
content: clean(String(row.content)),
|
|
159263
|
+
...status ? { status } : {},
|
|
159264
|
+
...row.source_ref ? { sourceRef: clean(String(row.source_ref), 500) } : {},
|
|
159265
|
+
evidenceRefs: parseRefs(row.evidence_json),
|
|
159266
|
+
...row.actor ? { actor: clean(String(row.actor), 200) } : {},
|
|
159267
|
+
at: String(row.created_at),
|
|
159268
|
+
...row.event_key ? { eventKey: clean(String(row.event_key), 200) } : {},
|
|
159269
|
+
...row.item_key ? { itemKey: clean(String(row.item_key), 120) } : {},
|
|
159270
|
+
...row.supersedes_id ? { supersedesId: clean(String(row.supersedes_id), 120) } : {}
|
|
159271
|
+
};
|
|
159272
|
+
}
|
|
159273
|
+
function aggregate(events) {
|
|
159274
|
+
const first2 = events.find((event) => event.kind === "task") ?? events[0];
|
|
159275
|
+
const latestOutcome = [...events].reverse().find((event) => event.kind === "outcome");
|
|
159276
|
+
const verificationByKey = /* @__PURE__ */ new Map();
|
|
159277
|
+
for (const event of events.filter((event2) => event2.kind === "verification")) {
|
|
159278
|
+
verificationByKey.set(event.itemKey ?? `event:${event.id}`, event);
|
|
159279
|
+
}
|
|
159280
|
+
const ledger = {
|
|
159281
|
+
taskId: first2.taskId,
|
|
159282
|
+
projectId: first2.projectId,
|
|
159283
|
+
task: first2.task,
|
|
159284
|
+
status: latestOutcome?.status ?? "open",
|
|
159285
|
+
requirements: events.filter((event) => event.kind === "requirement").map((event) => event.content),
|
|
159286
|
+
decisions: events.filter((event) => event.kind === "decision").map((event) => event.content),
|
|
159287
|
+
verification: [...verificationByKey.values()].map((event) => ({
|
|
159288
|
+
id: event.itemKey ?? event.id,
|
|
159289
|
+
content: event.content,
|
|
159290
|
+
status: event.status ?? "pending",
|
|
159291
|
+
...event.sourceRef ? { sourceRef: event.sourceRef } : {},
|
|
159292
|
+
evidenceRefs: event.evidenceRefs
|
|
159293
|
+
})),
|
|
159294
|
+
risks: events.filter((event) => event.kind === "risk").map((event) => event.content),
|
|
159295
|
+
outcomes: events.filter((event) => event.kind === "outcome").map((event) => event.content),
|
|
159296
|
+
updatedAt: events[events.length - 1].at,
|
|
159297
|
+
events
|
|
159298
|
+
};
|
|
159299
|
+
return { ...ledger, outcome: evaluateTaskContinuity(ledger) };
|
|
159300
|
+
}
|
|
159301
|
+
var TASK_CONTINUITY_EVENT_KINDS, MAX_TEXT_LENGTH2, MAX_TASK_LENGTH, MAX_LIST_ITEMS2, MAX_EVIDENCE_REFS, MAX_EVENTS_PER_TASK, TaskContinuityStore;
|
|
159302
|
+
var init_task_continuity = __esm({
|
|
159303
|
+
"src/knowledge/task-continuity.ts"() {
|
|
159304
|
+
"use strict";
|
|
159305
|
+
init_esm_shims();
|
|
159306
|
+
init_secret_filter();
|
|
159307
|
+
init_sqlite_db();
|
|
159308
|
+
TASK_CONTINUITY_EVENT_KINDS = [
|
|
159309
|
+
"task",
|
|
159310
|
+
"requirement",
|
|
159311
|
+
"decision",
|
|
159312
|
+
"verification",
|
|
159313
|
+
"risk",
|
|
159314
|
+
"outcome"
|
|
159315
|
+
];
|
|
159316
|
+
MAX_TEXT_LENGTH2 = 2e3;
|
|
159317
|
+
MAX_TASK_LENGTH = 1e3;
|
|
159318
|
+
MAX_LIST_ITEMS2 = 8;
|
|
159319
|
+
MAX_EVIDENCE_REFS = 8;
|
|
159320
|
+
MAX_EVENTS_PER_TASK = 200;
|
|
159321
|
+
TaskContinuityStore = class {
|
|
159322
|
+
db = null;
|
|
159323
|
+
async init(dataDir) {
|
|
159324
|
+
this.db = getDatabase(dataDir);
|
|
159325
|
+
}
|
|
159326
|
+
requireDb() {
|
|
159327
|
+
if (!this.db) throw new Error("TaskContinuityStore is not initialized.");
|
|
159328
|
+
return this.db;
|
|
159329
|
+
}
|
|
159330
|
+
insert(input) {
|
|
159331
|
+
const db2 = this.requireDb();
|
|
159332
|
+
const projectId = clean(input.projectId, 500);
|
|
159333
|
+
const taskId = clean(input.taskId, 120);
|
|
159334
|
+
const eventKey = input.eventKey ? clean(input.eventKey, 200) : void 0;
|
|
159335
|
+
if (eventKey) {
|
|
159336
|
+
const existing = db2.prepare(
|
|
159337
|
+
"SELECT * FROM task_continuity_events WHERE project_id = ? AND task_id = ? AND event_key = ?"
|
|
159338
|
+
).get(projectId, taskId, eventKey);
|
|
159339
|
+
if (existing) return rowToEvent4(existing);
|
|
159340
|
+
}
|
|
159341
|
+
const existingCount = db2.prepare(
|
|
159342
|
+
"SELECT COUNT(*) AS count FROM task_continuity_events WHERE project_id = ? AND task_id = ?"
|
|
159343
|
+
).get(projectId, taskId);
|
|
159344
|
+
if (Number(existingCount?.count ?? 0) >= MAX_EVENTS_PER_TASK) {
|
|
159345
|
+
throw new Error("Task continuity ledger reached its 200-event limit.");
|
|
159346
|
+
}
|
|
159347
|
+
const event = {
|
|
159348
|
+
id: randomUUID17(),
|
|
159349
|
+
projectId,
|
|
159350
|
+
taskId,
|
|
159351
|
+
task: clean(input.task, MAX_TASK_LENGTH),
|
|
159352
|
+
kind: input.kind,
|
|
159353
|
+
content: clean(input.content),
|
|
159354
|
+
...input.status ? { status: input.status } : {},
|
|
159355
|
+
...input.sourceRef ? { sourceRef: clean(input.sourceRef, 500) } : {},
|
|
159356
|
+
evidenceRefs: cleanList(input.evidenceRefs, 500).slice(0, MAX_EVIDENCE_REFS),
|
|
159357
|
+
...input.actor ? { actor: clean(input.actor, 200) } : {},
|
|
159358
|
+
at: input.at ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
159359
|
+
...eventKey ? { eventKey } : {},
|
|
159360
|
+
...input.itemKey ? { itemKey: clean(input.itemKey, 120) } : {},
|
|
159361
|
+
...input.supersedesId ? { supersedesId: clean(input.supersedesId, 120) } : {}
|
|
159362
|
+
};
|
|
159363
|
+
db2.prepare(`
|
|
159364
|
+
INSERT INTO task_continuity_events (
|
|
159365
|
+
id, project_id, task_id, task, kind, content, item_status,
|
|
159366
|
+
source_ref, evidence_json, actor, created_at, event_key, item_key, supersedes_id
|
|
159367
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
159368
|
+
`).run(
|
|
159369
|
+
event.id,
|
|
159370
|
+
event.projectId,
|
|
159371
|
+
event.taskId,
|
|
159372
|
+
event.task,
|
|
159373
|
+
event.kind,
|
|
159374
|
+
event.content,
|
|
159375
|
+
event.status ?? null,
|
|
159376
|
+
event.sourceRef ?? null,
|
|
159377
|
+
JSON.stringify(event.evidenceRefs),
|
|
159378
|
+
event.actor ?? null,
|
|
159379
|
+
event.at,
|
|
159380
|
+
event.eventKey ?? null,
|
|
159381
|
+
event.itemKey ?? null,
|
|
159382
|
+
event.supersedesId ?? null
|
|
159383
|
+
);
|
|
159384
|
+
return event;
|
|
159385
|
+
}
|
|
159386
|
+
start(input) {
|
|
159387
|
+
const task = clean(input.task, MAX_TASK_LENGTH);
|
|
159388
|
+
if (!task) throw new Error("A non-empty task is required.");
|
|
159389
|
+
const idempotencyKey = input.idempotencyKey ? clean(input.idempotencyKey, 200) : void 0;
|
|
159390
|
+
const taskId = clean(input.taskId ?? idempotencyKey ?? "", 120) || randomUUID17();
|
|
159391
|
+
const requirements = cleanList(input.requirements);
|
|
159392
|
+
const transaction = this.requireDb().transaction(() => {
|
|
159393
|
+
this.insert({
|
|
159394
|
+
projectId: input.projectId,
|
|
159395
|
+
taskId,
|
|
159396
|
+
task,
|
|
159397
|
+
kind: "task",
|
|
159398
|
+
content: task,
|
|
159399
|
+
status: "open",
|
|
159400
|
+
actor: input.actor,
|
|
159401
|
+
...idempotencyKey ? { eventKey: `start:${idempotencyKey}` } : {}
|
|
159402
|
+
});
|
|
159403
|
+
for (const requirement of requirements) {
|
|
159404
|
+
this.insert({
|
|
159405
|
+
projectId: input.projectId,
|
|
159406
|
+
taskId,
|
|
159407
|
+
task,
|
|
159408
|
+
kind: "requirement",
|
|
159409
|
+
content: requirement,
|
|
159410
|
+
actor: input.actor
|
|
159411
|
+
});
|
|
159412
|
+
}
|
|
159413
|
+
});
|
|
159414
|
+
transaction.immediate();
|
|
159415
|
+
return { taskId, ledger: this.get(input.projectId, taskId) };
|
|
159416
|
+
}
|
|
159417
|
+
record(input) {
|
|
159418
|
+
const projectId = clean(input.projectId, 500);
|
|
159419
|
+
const taskId = clean(input.taskId, 120);
|
|
159420
|
+
const existing = this.get(projectId, taskId);
|
|
159421
|
+
if (!existing) throw new Error("Task continuity ledger not found: " + taskId);
|
|
159422
|
+
const transaction = this.requireDb().transaction(() => this.insert({
|
|
159423
|
+
projectId,
|
|
159424
|
+
taskId,
|
|
159425
|
+
task: existing.task,
|
|
159426
|
+
kind: input.kind,
|
|
159427
|
+
content: input.content,
|
|
159428
|
+
...input.kind === "verification" && input.verificationStatus ? { status: input.verificationStatus } : {},
|
|
159429
|
+
sourceRef: input.sourceRef,
|
|
159430
|
+
evidenceRefs: input.evidenceRefs,
|
|
159431
|
+
actor: input.actor,
|
|
159432
|
+
at: input.at,
|
|
159433
|
+
...input.idempotencyKey ? { eventKey: input.idempotencyKey } : {},
|
|
159434
|
+
...input.verificationId ? { itemKey: input.verificationId } : {}
|
|
159435
|
+
}));
|
|
159436
|
+
const event = transaction.immediate();
|
|
159437
|
+
return { event, ledger: this.get(projectId, taskId) };
|
|
159438
|
+
}
|
|
159439
|
+
close(input) {
|
|
159440
|
+
const projectId = clean(input.projectId, 500);
|
|
159441
|
+
const taskId = clean(input.taskId, 120);
|
|
159442
|
+
const existing = this.get(projectId, taskId);
|
|
159443
|
+
if (!existing) throw new Error("Task continuity ledger not found: " + taskId);
|
|
159444
|
+
const transaction = this.requireDb().transaction(() => this.insert({
|
|
159445
|
+
projectId,
|
|
159446
|
+
taskId,
|
|
159447
|
+
task: existing.task,
|
|
159448
|
+
kind: "outcome",
|
|
159449
|
+
content: input.content,
|
|
159450
|
+
status: input.status,
|
|
159451
|
+
sourceRef: input.sourceRef,
|
|
159452
|
+
evidenceRefs: input.evidenceRefs,
|
|
159453
|
+
actor: input.actor,
|
|
159454
|
+
at: input.at,
|
|
159455
|
+
...input.idempotencyKey ? { eventKey: input.idempotencyKey } : {}
|
|
159456
|
+
}));
|
|
159457
|
+
const event = transaction.immediate();
|
|
159458
|
+
return { event, ledger: this.get(projectId, taskId) };
|
|
159459
|
+
}
|
|
159460
|
+
get(projectId, taskId) {
|
|
159461
|
+
const normalizedProjectId = clean(projectId, 500);
|
|
159462
|
+
const normalizedTaskId = clean(taskId, 120);
|
|
159463
|
+
const rows = this.requireDb().prepare(`
|
|
159464
|
+
SELECT * FROM task_continuity_events
|
|
159465
|
+
WHERE project_id = ? AND task_id = ?
|
|
159466
|
+
ORDER BY created_at ASC, rowid ASC
|
|
159467
|
+
`).all(normalizedProjectId, normalizedTaskId);
|
|
159468
|
+
if (rows.length === 0) return void 0;
|
|
159469
|
+
return aggregate(rows.map(rowToEvent4));
|
|
159470
|
+
}
|
|
159471
|
+
list(projectId, limit2 = 20) {
|
|
159472
|
+
const rows = this.requireDb().prepare(`
|
|
159473
|
+
SELECT task_id
|
|
159474
|
+
FROM task_continuity_events
|
|
159475
|
+
WHERE project_id = ?
|
|
159476
|
+
GROUP BY task_id
|
|
159477
|
+
ORDER BY MAX(created_at) DESC
|
|
159478
|
+
LIMIT ?
|
|
159479
|
+
`).all(projectId, Math.min(100, Math.max(1, Math.floor(limit2))));
|
|
159480
|
+
return rows.map((row) => this.get(projectId, String(row.task_id))).filter((ledger) => Boolean(ledger));
|
|
159481
|
+
}
|
|
159482
|
+
};
|
|
159483
|
+
}
|
|
159484
|
+
});
|
|
159485
|
+
|
|
158933
159486
|
// src/codegraph/auto-context.ts
|
|
158934
159487
|
var auto_context_exports = {};
|
|
158935
159488
|
__export(auto_context_exports, {
|
|
@@ -159186,6 +159739,16 @@ async function buildAutoProjectContext(input) {
|
|
|
159186
159739
|
};
|
|
159187
159740
|
}
|
|
159188
159741
|
}
|
|
159742
|
+
let continuity = input.continuity;
|
|
159743
|
+
if (!continuity && input.taskId) {
|
|
159744
|
+
try {
|
|
159745
|
+
const { TaskContinuityStore: TaskContinuityStore2 } = await Promise.resolve().then(() => (init_task_continuity(), task_continuity_exports));
|
|
159746
|
+
const continuityStore = new TaskContinuityStore2();
|
|
159747
|
+
await continuityStore.init(input.dataDir);
|
|
159748
|
+
continuity = continuityStore.get(input.project.id, input.taskId);
|
|
159749
|
+
} catch {
|
|
159750
|
+
}
|
|
159751
|
+
}
|
|
159189
159752
|
const alwaysOn = await buildAlwaysOnBlock({
|
|
159190
159753
|
dataDir: input.dataDir,
|
|
159191
159754
|
projectId: input.project.id,
|
|
@@ -159204,6 +159767,7 @@ async function buildAutoProjectContext(input) {
|
|
|
159204
159767
|
providerQuality: providerQuality2,
|
|
159205
159768
|
currentFacts: worksetFactLines(currentFacts),
|
|
159206
159769
|
...continuation ? { continuation } : {},
|
|
159770
|
+
...continuity ? { continuity } : {},
|
|
159207
159771
|
codeState: codeStateLine(overview),
|
|
159208
159772
|
...codeEvolution ? { codeEvolution } : {},
|
|
159209
159773
|
reliableMemory: sourceSets.reliableSources.slice(0, lens.sourceLimit).map((source) => ({
|
|
@@ -159251,6 +159815,7 @@ async function buildAutoProjectContext(input) {
|
|
|
159251
159815
|
refresh,
|
|
159252
159816
|
providerQuality: providerQuality2,
|
|
159253
159817
|
...continuationRequested && workset.continuation ? { continuation: workset.continuation } : {},
|
|
159818
|
+
...workset.continuity ? { continuity: workset.continuity } : {},
|
|
159254
159819
|
workset
|
|
159255
159820
|
};
|
|
159256
159821
|
}
|
|
@@ -159552,7 +160117,14 @@ function buildBoundedContextReceipt(input) {
|
|
|
159552
160117
|
externalState: provider2?.external.state ?? "not-detected",
|
|
159553
160118
|
...input.workset.provenance.snapshotId ? { snapshotId: input.workset.provenance.snapshotId } : {}
|
|
159554
160119
|
},
|
|
159555
|
-
...input.workset.agentLoadout ? { loadout: input.workset.agentLoadout } : {}
|
|
160120
|
+
...input.workset.agentLoadout ? { loadout: input.workset.agentLoadout } : {},
|
|
160121
|
+
...input.workset.continuity ? {
|
|
160122
|
+
continuity: {
|
|
160123
|
+
taskId: input.workset.continuity.taskId,
|
|
160124
|
+
status: input.workset.continuity.status,
|
|
160125
|
+
outcome: input.workset.continuity.outcome
|
|
160126
|
+
}
|
|
160127
|
+
} : {}
|
|
159556
160128
|
};
|
|
159557
160129
|
}
|
|
159558
160130
|
var init_context_receipt = __esm({
|
|
@@ -160184,15 +160756,21 @@ var team_store_exports = {};
|
|
|
160184
160756
|
__export(team_store_exports, {
|
|
160185
160757
|
AGENT_TYPE_ROLE_MAP: () => AGENT_TYPE_ROLE_MAP,
|
|
160186
160758
|
DEFAULT_ROLES: () => DEFAULT_ROLES,
|
|
160759
|
+
DEFAULT_TEAM_QUERY_LIMIT: () => DEFAULT_TEAM_QUERY_LIMIT,
|
|
160760
|
+
MAX_TEAM_QUERY_LIMIT: () => MAX_TEAM_QUERY_LIMIT,
|
|
160187
160761
|
TeamStore: () => TeamStore,
|
|
160188
160762
|
getTeamStore: () => getTeamStore,
|
|
160189
160763
|
initTeamStore: () => initTeamStore,
|
|
160190
160764
|
isTeamStoreInitialized: () => isTeamStoreInitialized,
|
|
160191
160765
|
resetTeamStore: () => resetTeamStore
|
|
160192
160766
|
});
|
|
160193
|
-
import { randomUUID as
|
|
160767
|
+
import { randomUUID as randomUUID18 } from "crypto";
|
|
160194
160768
|
import path31 from "path";
|
|
160195
160769
|
import fs18 from "fs";
|
|
160770
|
+
function clampTeamQueryLimit(limit2) {
|
|
160771
|
+
if (!Number.isFinite(limit2) || limit2 == null) return DEFAULT_TEAM_QUERY_LIMIT;
|
|
160772
|
+
return Math.min(MAX_TEAM_QUERY_LIMIT, Math.max(1, Math.floor(limit2)));
|
|
160773
|
+
}
|
|
160196
160774
|
function getTeamStore() {
|
|
160197
160775
|
if (!_teamStore) {
|
|
160198
160776
|
throw new Error("[memorix] TeamStore not initialized \u2014 call initTeamStore() first");
|
|
@@ -160216,12 +160794,14 @@ function resetTeamStore() {
|
|
|
160216
160794
|
_teamStore = null;
|
|
160217
160795
|
_teamStoreDataDir = null;
|
|
160218
160796
|
}
|
|
160219
|
-
var DEFAULT_ROLES, AGENT_TYPE_ROLE_MAP, TeamStore, _teamStore, _teamStoreDataDir;
|
|
160797
|
+
var DEFAULT_TEAM_QUERY_LIMIT, MAX_TEAM_QUERY_LIMIT, DEFAULT_ROLES, AGENT_TYPE_ROLE_MAP, TeamStore, _teamStore, _teamStoreDataDir;
|
|
160220
160798
|
var init_team_store = __esm({
|
|
160221
160799
|
"src/team/team-store.ts"() {
|
|
160222
160800
|
"use strict";
|
|
160223
160801
|
init_esm_shims();
|
|
160224
160802
|
init_sqlite_db();
|
|
160803
|
+
DEFAULT_TEAM_QUERY_LIMIT = 100;
|
|
160804
|
+
MAX_TEAM_QUERY_LIMIT = 500;
|
|
160225
160805
|
DEFAULT_ROLES = [
|
|
160226
160806
|
{ roleId: "planner", label: "Planner", description: "Breaks down requirements, creates tasks, defines dependencies", preferredAgentTypes: ["claude-code", "cursor", "codex"], maxConcurrent: 2 },
|
|
160227
160807
|
{ roleId: "researcher", label: "Researcher", description: "Investigates codebase, gathers context, answers questions", preferredAgentTypes: ["claude-code", "cursor", "gemini-cli"], maxConcurrent: 2 },
|
|
@@ -160479,7 +161059,7 @@ var init_team_store = __esm({
|
|
|
160479
161059
|
* reactivate it (preserving agent_id). Otherwise create a new one.
|
|
160480
161060
|
*/
|
|
160481
161061
|
registerAgent(input) {
|
|
160482
|
-
const instanceId = input.instanceId ||
|
|
161062
|
+
const instanceId = input.instanceId || randomUUID18();
|
|
160483
161063
|
const now3 = Date.now();
|
|
160484
161064
|
const existing = this.stmtAgentFindByInstance.get(
|
|
160485
161065
|
input.projectId,
|
|
@@ -160505,7 +161085,7 @@ var init_team_store = __esm({
|
|
|
160505
161085
|
this.eventBus?.emit("agent:joined", { agentId: row2.agent_id, projectId: input.projectId, agentType: input.agentType });
|
|
160506
161086
|
return row2;
|
|
160507
161087
|
}
|
|
160508
|
-
const agentId =
|
|
161088
|
+
const agentId = randomUUID18();
|
|
160509
161089
|
this.stmtAgentUpsert.run({
|
|
160510
161090
|
agent_id: agentId,
|
|
160511
161091
|
project_id: input.projectId,
|
|
@@ -160531,32 +161111,37 @@ var init_team_store = __esm({
|
|
|
160531
161111
|
return this.stmtAgentFindByInstance.get(projectId, agentType, instanceId);
|
|
160532
161112
|
}
|
|
160533
161113
|
listAgents(projectId, filter) {
|
|
160534
|
-
const
|
|
161114
|
+
const limit2 = clampTeamQueryLimit(filter?.limit);
|
|
160535
161115
|
if (filter?.status) {
|
|
160536
|
-
return
|
|
161116
|
+
return this.db.prepare(
|
|
161117
|
+
`SELECT * FROM team_agents WHERE project_id = ? AND status = ? ORDER BY joined_at DESC LIMIT ?`
|
|
161118
|
+
).all(projectId, filter.status, limit2);
|
|
160537
161119
|
}
|
|
160538
|
-
return
|
|
161120
|
+
return this.db.prepare(
|
|
161121
|
+
`SELECT * FROM team_agents WHERE project_id = ? ORDER BY joined_at DESC LIMIT ?`
|
|
161122
|
+
).all(projectId, limit2);
|
|
160539
161123
|
}
|
|
160540
161124
|
/** List agents across all projects (for global scope) */
|
|
160541
|
-
listAllAgents() {
|
|
161125
|
+
listAllAgents(limit2) {
|
|
160542
161126
|
if (!this.db) return [];
|
|
160543
|
-
return this.db.prepare("SELECT * FROM team_agents ORDER BY last_heartbeat DESC").all();
|
|
161127
|
+
return this.db.prepare("SELECT * FROM team_agents ORDER BY last_heartbeat DESC LIMIT ?").all(clampTeamQueryLimit(limit2));
|
|
160544
161128
|
}
|
|
160545
161129
|
/** List locks across all projects (for global scope) */
|
|
160546
|
-
listAllLocks() {
|
|
161130
|
+
listAllLocks(limit2) {
|
|
160547
161131
|
if (!this.db) return [];
|
|
160548
161132
|
this.db.prepare("DELETE FROM team_locks WHERE expires_at <= ?").run(Date.now());
|
|
160549
|
-
return this.db.prepare("SELECT * FROM team_locks WHERE expires_at > ? ORDER BY locked_at DESC").all(Date.now());
|
|
161133
|
+
return this.db.prepare("SELECT * FROM team_locks WHERE expires_at > ? ORDER BY locked_at DESC LIMIT ?").all(Date.now(), clampTeamQueryLimit(limit2));
|
|
160550
161134
|
}
|
|
160551
161135
|
/** List tasks across all projects (for global scope) */
|
|
160552
161136
|
listAllTasks(filter) {
|
|
160553
161137
|
if (!this.db) return [];
|
|
161138
|
+
const limit2 = clampTeamQueryLimit(filter?.limit);
|
|
160554
161139
|
if (filter?.available) {
|
|
160555
161140
|
return this.db.prepare(
|
|
160556
|
-
`SELECT t.* FROM team_tasks t WHERE t.status = 'pending' AND t.assignee_agent_id IS NULL ORDER BY t.created_at DESC
|
|
160557
|
-
).all();
|
|
161141
|
+
`SELECT t.* FROM team_tasks t WHERE t.status = 'pending' AND t.assignee_agent_id IS NULL ORDER BY t.created_at DESC LIMIT ?`
|
|
161142
|
+
).all(limit2);
|
|
160558
161143
|
}
|
|
160559
|
-
return this.db.prepare("SELECT * FROM team_tasks ORDER BY created_at DESC").all();
|
|
161144
|
+
return this.db.prepare("SELECT * FROM team_tasks ORDER BY created_at DESC LIMIT ?").all(limit2);
|
|
160560
161145
|
}
|
|
160561
161146
|
heartbeat(agentId) {
|
|
160562
161147
|
const info = this.stmtAgentUpdateHeartbeat.run(Date.now(), agentId);
|
|
@@ -160591,7 +161176,10 @@ var init_team_store = __esm({
|
|
|
160591
161176
|
return staleIds;
|
|
160592
161177
|
}
|
|
160593
161178
|
getActiveCount(projectId) {
|
|
160594
|
-
|
|
161179
|
+
const row = this.db.prepare(
|
|
161180
|
+
`SELECT COUNT(*) AS count FROM team_agents WHERE project_id = ? AND status = 'active'`
|
|
161181
|
+
).get(projectId);
|
|
161182
|
+
return Number(row?.count ?? 0);
|
|
160595
161183
|
}
|
|
160596
161184
|
// ═══════════════════════════════════════════════════════════════════
|
|
160597
161185
|
// Message Operations
|
|
@@ -160607,7 +161195,7 @@ var init_team_store = __esm({
|
|
|
160607
161195
|
return { error: `Recipient agent '${input.recipientAgentId}' not found \u2014 cannot send to unknown agent` };
|
|
160608
161196
|
}
|
|
160609
161197
|
}
|
|
160610
|
-
const id =
|
|
161198
|
+
const id = randomUUID18();
|
|
160611
161199
|
const now3 = Date.now();
|
|
160612
161200
|
const row = {
|
|
160613
161201
|
id,
|
|
@@ -160626,8 +161214,14 @@ var init_team_store = __esm({
|
|
|
160626
161214
|
this.stmtMsgInsert.run(row);
|
|
160627
161215
|
return row;
|
|
160628
161216
|
}
|
|
160629
|
-
getInbox(projectId, agentId) {
|
|
160630
|
-
return this.
|
|
161217
|
+
getInbox(projectId, agentId, limit2) {
|
|
161218
|
+
return this.db.prepare(`
|
|
161219
|
+
SELECT * FROM team_messages
|
|
161220
|
+
WHERE project_id = ?
|
|
161221
|
+
AND (recipient_agent_id = ? OR recipient_agent_id IS NULL)
|
|
161222
|
+
ORDER BY created_at ASC
|
|
161223
|
+
LIMIT ?
|
|
161224
|
+
`).all(projectId, agentId, clampTeamQueryLimit(limit2));
|
|
160631
161225
|
}
|
|
160632
161226
|
getUnreadCount(projectId, agentId) {
|
|
160633
161227
|
const row = this.stmtMsgUnreadCount.get(projectId, agentId);
|
|
@@ -160657,7 +161251,7 @@ var init_team_store = __esm({
|
|
|
160657
161251
|
// Task Operations (with atomic claim semantics)
|
|
160658
161252
|
// ═══════════════════════════════════════════════════════════════════
|
|
160659
161253
|
createTask(input) {
|
|
160660
|
-
const taskId =
|
|
161254
|
+
const taskId = randomUUID18();
|
|
160661
161255
|
const now3 = Date.now();
|
|
160662
161256
|
const row = {
|
|
160663
161257
|
task_id: taskId,
|
|
@@ -160784,17 +161378,22 @@ var init_team_store = __esm({
|
|
|
160784
161378
|
return info.changes;
|
|
160785
161379
|
}
|
|
160786
161380
|
listTasks(projectId, filter) {
|
|
160787
|
-
|
|
160788
|
-
|
|
160789
|
-
|
|
160790
|
-
const all = this.stmtTaskListByProject.all(projectId);
|
|
161381
|
+
const clauses = ["project_id = ?"];
|
|
161382
|
+
const values = [projectId];
|
|
161383
|
+
if (filter?.available) clauses.push("status = 'pending'", "assignee_agent_id IS NULL");
|
|
160791
161384
|
if (filter?.status) {
|
|
160792
|
-
|
|
161385
|
+
clauses.push("status = ?");
|
|
161386
|
+
values.push(filter.status);
|
|
160793
161387
|
}
|
|
160794
161388
|
if (filter?.assignee) {
|
|
160795
|
-
|
|
161389
|
+
clauses.push("assignee_agent_id = ?");
|
|
161390
|
+
values.push(filter.assignee);
|
|
160796
161391
|
}
|
|
160797
|
-
|
|
161392
|
+
values.push(clampTeamQueryLimit(filter?.limit));
|
|
161393
|
+
const orderBy = filter?.available ? "created_at ASC, rowid ASC" : "created_at DESC, rowid DESC";
|
|
161394
|
+
return this.db.prepare(
|
|
161395
|
+
`SELECT * FROM team_tasks WHERE ${clauses.join(" AND ")} ORDER BY ${orderBy} LIMIT ?`
|
|
161396
|
+
).all(...values);
|
|
160798
161397
|
}
|
|
160799
161398
|
/**
|
|
160800
161399
|
* List available tasks for a specific agent, sorted by role affinity.
|
|
@@ -160806,7 +161405,7 @@ var init_team_store = __esm({
|
|
|
160806
161405
|
const agent = this.stmtAgentFindById.get(agentId);
|
|
160807
161406
|
if (!agent) return [];
|
|
160808
161407
|
const agentRole = agent.role;
|
|
160809
|
-
const available = this.
|
|
161408
|
+
const available = this.listTasks(projectId, { available: true, limit: MAX_TEAM_QUERY_LIMIT });
|
|
160810
161409
|
const eligible = available.filter((t2) => !t2.required_role || t2.required_role === agentRole);
|
|
160811
161410
|
const score = (t2) => {
|
|
160812
161411
|
if (t2.preferred_role === agentRole) return 0;
|
|
@@ -160860,12 +161459,16 @@ var init_team_store = __esm({
|
|
|
160860
161459
|
const row = this.stmtLockGet.get(file, projectId);
|
|
160861
161460
|
return row ?? null;
|
|
160862
161461
|
}
|
|
160863
|
-
listLocks(projectId, agentId) {
|
|
161462
|
+
listLocks(projectId, agentId, limit2) {
|
|
160864
161463
|
this.stmtLockDeleteExpired.run(projectId, Date.now());
|
|
160865
161464
|
if (agentId) {
|
|
160866
|
-
return this.
|
|
161465
|
+
return this.db.prepare(
|
|
161466
|
+
`SELECT * FROM team_locks WHERE project_id = ? AND locked_by = ? ORDER BY locked_at DESC LIMIT ?`
|
|
161467
|
+
).all(projectId, agentId, clampTeamQueryLimit(limit2));
|
|
160867
161468
|
}
|
|
160868
|
-
return this.
|
|
161469
|
+
return this.db.prepare(
|
|
161470
|
+
`SELECT * FROM team_locks WHERE project_id = ? ORDER BY locked_at DESC LIMIT ?`
|
|
161471
|
+
).all(projectId, clampTeamQueryLimit(limit2));
|
|
160869
161472
|
}
|
|
160870
161473
|
releaseAllLocks(agentId) {
|
|
160871
161474
|
const info = this.stmtLockDeleteByAgent.run(agentId);
|
|
@@ -160929,7 +161532,7 @@ var init_team_store = __esm({
|
|
|
160929
161532
|
for (const [agentId, msgs] of Object.entries(snap.messages.inboxes)) {
|
|
160930
161533
|
for (const msg of msgs) {
|
|
160931
161534
|
this.stmtMsgInsert.run({
|
|
160932
|
-
id: msg.id ??
|
|
161535
|
+
id: msg.id ?? randomUUID18(),
|
|
160933
161536
|
project_id: "migrated",
|
|
160934
161537
|
sender_agent_id: msg.from ?? "unknown",
|
|
160935
161538
|
recipient_agent_id: msg.to === "__broadcast__" ? null : msg.to ?? agentId,
|
|
@@ -163887,7 +164490,7 @@ __export(planner_exports, {
|
|
|
163887
164490
|
materializeTaskGraph: () => materializeTaskGraph,
|
|
163888
164491
|
seedAutonomousPipeline: () => seedAutonomousPipeline
|
|
163889
164492
|
});
|
|
163890
|
-
import { randomUUID as
|
|
164493
|
+
import { randomUUID as randomUUID19 } from "crypto";
|
|
163891
164494
|
function isPlannerTask(metadata) {
|
|
163892
164495
|
if (!metadata) return null;
|
|
163893
164496
|
try {
|
|
@@ -163945,7 +164548,7 @@ function seedAutonomousPipeline(teamStore, projectId, config, opts) {
|
|
|
163945
164548
|
const maxIterations = config.maxIterations ?? 3;
|
|
163946
164549
|
const taskBudget = config.taskBudget ?? 15;
|
|
163947
164550
|
const structuredPlan = opts?.structuredPlan ?? true;
|
|
163948
|
-
const pipelineId =
|
|
164551
|
+
const pipelineId = randomUUID19();
|
|
163949
164552
|
const meta = {
|
|
163950
164553
|
plannerType: "plan",
|
|
163951
164554
|
pipelineId,
|
|
@@ -164626,6 +165229,7 @@ var init_official_skills = __esm({
|
|
|
164626
165229
|
"| Need the sequence around one memory | `memorix_timeline` | `memorix memory timeline --id <id>` |",
|
|
164627
165230
|
"| Check source and freshness for a memory | `memorix_evidence` | `memorix evidence list|get|events` |",
|
|
164628
165231
|
"| Record whether a memory helped, conflicted, or was corrected | `memorix_feedback` | `memorix feedback record|show|audit` |",
|
|
165232
|
+
"| Track task requirements, decisions, verification, and outcome | `memorix_continuity` | `memorix continuity start|record|show|close` |",
|
|
164629
165233
|
"| Inspect or import controlled media | `memorix_media` | `memorix media import|attach|list|show|status` |",
|
|
164630
165234
|
'| Learned reusable project knowledge | `memorix_store` | `memorix memory store --type <type> --entity <name> --title "<title>" "<text>"` |',
|
|
164631
165235
|
"| Task or bug is complete/outdated | `memorix_resolve` | `memorix memory resolve --ids <ids>` |",
|
|
@@ -164649,6 +165253,7 @@ var init_official_skills = __esm({
|
|
|
164649
165253
|
"3. Use stale or unbound memory only as a warning or search lead.",
|
|
164650
165254
|
"4. Store durable decisions, fixes, and gotchas after the project state changes.",
|
|
164651
165255
|
"5. Resolve completed or obsolete memories so future briefs stay small.",
|
|
165256
|
+
"6. For multi-step work, start a continuity ledger and pass its taskId back to memorix_project_context.",
|
|
164652
165257
|
"",
|
|
164653
165258
|
"## Store Rules",
|
|
164654
165259
|
"",
|
|
@@ -166376,7 +166981,7 @@ init_freshness();
|
|
|
166376
166981
|
init_obs_store();
|
|
166377
166982
|
init_mini_skill_store();
|
|
166378
166983
|
init_session_store();
|
|
166379
|
-
import { createHash as
|
|
166984
|
+
import { createHash as createHash19 } from "crypto";
|
|
166380
166985
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
166381
166986
|
import { z as z627 } from "zod";
|
|
166382
166987
|
|
|
@@ -167768,9 +168373,9 @@ init_frontmatter();
|
|
|
167768
168373
|
|
|
167769
168374
|
// src/rules/utils.ts
|
|
167770
168375
|
init_esm_shims();
|
|
167771
|
-
import { createHash as
|
|
168376
|
+
import { createHash as createHash17 } from "crypto";
|
|
167772
168377
|
function hashContent2(content) {
|
|
167773
|
-
return
|
|
168378
|
+
return createHash17("sha256").update(content.trim()).digest("hex").substring(0, 16);
|
|
167774
168379
|
}
|
|
167775
168380
|
function generateRuleId(source, filePath) {
|
|
167776
168381
|
const sanitized = filePath.replace(/[\/\\]/g, "-").replace(/^\./, "");
|
|
@@ -169976,6 +170581,7 @@ var TOOL_PROFILES = Object.freeze({
|
|
|
169976
170581
|
// keep the default micro profile at its nine-tool token budget.
|
|
169977
170582
|
memorix_evidence: ["lite", "team", "full"],
|
|
169978
170583
|
memorix_feedback: ["lite", "team", "full"],
|
|
170584
|
+
memorix_continuity: ["lite", "team", "full"],
|
|
169979
170585
|
// ── lite: extended solo memory surface ────────────────────────────
|
|
169980
170586
|
memorix_graph_context: ["lite", "team", "full"],
|
|
169981
170587
|
memorix_timeline: ["lite", "team", "full"],
|
|
@@ -170198,7 +170804,7 @@ var MCP_SERVER_INFO_META_KEY = "io.modelcontextprotocol/serverInfo";
|
|
|
170198
170804
|
function getMcpServerInfo() {
|
|
170199
170805
|
return {
|
|
170200
170806
|
name: "memorix",
|
|
170201
|
-
version: true ? "1.9.
|
|
170807
|
+
version: true ? "1.9.6" : "1.0.1"
|
|
170202
170808
|
};
|
|
170203
170809
|
}
|
|
170204
170810
|
function createMcpDiscoverResult(capabilities, serverInfo) {
|
|
@@ -170333,7 +170939,7 @@ function coerceObjectArray(val) {
|
|
|
170333
170939
|
return [];
|
|
170334
170940
|
}
|
|
170335
170941
|
function createDeterministicInstanceId(projectId, agentType, agentName) {
|
|
170336
|
-
const digest2 =
|
|
170942
|
+
const digest2 = createHash19("sha256").update(projectId).update("\n").update(agentType).update("\n").update(agentName ?? "").digest("hex").slice(0, 24);
|
|
170337
170943
|
return `auto-${digest2}`;
|
|
170338
170944
|
}
|
|
170339
170945
|
var BOOTSTRAP_SAFE_TOOL_NAMES = /* @__PURE__ */ new Set([
|
|
@@ -170549,6 +171155,22 @@ async function createMemorixServer(cwd, existingServer, sharedTeam, options = {}
|
|
|
170549
171155
|
}
|
|
170550
171156
|
await projectRuntimeInitPromise;
|
|
170551
171157
|
};
|
|
171158
|
+
const activateProjectRuntime = async () => {
|
|
171159
|
+
if (!projectResolved) return;
|
|
171160
|
+
await initObservationStore(projectDir2);
|
|
171161
|
+
await initMiniSkillStore(projectDir2);
|
|
171162
|
+
await initSessionStore(projectDir2);
|
|
171163
|
+
await initObservations(projectDir2, { skipCorpusLoad: true });
|
|
171164
|
+
try {
|
|
171165
|
+
const { initProjectRoot: initProjectRoot2 } = await Promise.resolve().then(() => (init_yaml_loader(), yaml_loader_exports));
|
|
171166
|
+
const { resetDotenv: resetDotenv2, loadDotenv: loadDotenv2 } = await Promise.resolve().then(() => (init_dotenv_loader(), dotenv_loader_exports));
|
|
171167
|
+
initProjectRoot2(project.rootPath);
|
|
171168
|
+
resetDotenv2();
|
|
171169
|
+
loadDotenv2(project.rootPath);
|
|
171170
|
+
} catch {
|
|
171171
|
+
}
|
|
171172
|
+
initLLM({ projectRoot: project.rootPath });
|
|
171173
|
+
};
|
|
170552
171174
|
let maintenanceWorker = null;
|
|
170553
171175
|
const startProjectMaintenanceWorker = async (autoCleanup = false) => {
|
|
170554
171176
|
maintenanceWorker?.stop();
|
|
@@ -171464,6 +172086,7 @@ _Search mode: ${getLastSearchMode2(project.id)}_`;
|
|
|
171464
172086
|
description: "Build a compact Memory Autopilot brief for the current coding task. Schedules Code Memory refresh when needed, includes Start here files, reliable code-bound memories, stale/suspect cautions, and verification hints. Use this at the start of a new coding turn or after switching tasks.",
|
|
171465
172087
|
inputSchema: {
|
|
171466
172088
|
task: z627.string().optional().describe("Current coding task or question"),
|
|
172089
|
+
taskId: z627.string().max(120).optional().describe("Optional task continuity ledger id to include in the brief"),
|
|
171467
172090
|
refresh: z627.enum(["auto", "always", "never"]).optional().default("auto").describe(
|
|
171468
172091
|
"Code Memory refresh policy. auto refreshes only when missing or stale."
|
|
171469
172092
|
),
|
|
@@ -171488,7 +172111,7 @@ _Search mode: ${getLastSearchMode2(project.id)}_`;
|
|
|
171488
172111
|
limit: z627.number().optional().describe("Reserved for future source limits; current prompt stays compact by default.")
|
|
171489
172112
|
}
|
|
171490
172113
|
},
|
|
171491
|
-
async ({ task, refresh, format, agent }) => {
|
|
172114
|
+
async ({ task, taskId, refresh, format, agent }) => {
|
|
171492
172115
|
const unresolved = requireResolvedProject("build project context for the current project");
|
|
171493
172116
|
if (unresolved) return unresolved;
|
|
171494
172117
|
const [
|
|
@@ -171518,6 +172141,7 @@ _Search mode: ${getLastSearchMode2(project.id)}_`;
|
|
|
171518
172141
|
dataDir: projectDir2,
|
|
171519
172142
|
observations: observations2,
|
|
171520
172143
|
task,
|
|
172144
|
+
taskId,
|
|
171521
172145
|
agent,
|
|
171522
172146
|
refresh: refresh ?? "auto",
|
|
171523
172147
|
reader: getObservationReader(),
|
|
@@ -173943,6 +174567,94 @@ ${json2}
|
|
|
173943
174567
|
}
|
|
173944
174568
|
}
|
|
173945
174569
|
);
|
|
174570
|
+
server.registerTool(
|
|
174571
|
+
"memorix_continuity",
|
|
174572
|
+
{
|
|
174573
|
+
title: "Task Continuity Ledger",
|
|
174574
|
+
description: "Maintain a bounded, append-only continuity ledger for a coding task. Use start for requirements, record for decisions/verification/risks, show or list to inspect, and close for the final outcome. Pass the returned taskId to memorix_project_context so the current brief includes this ledger.",
|
|
174575
|
+
inputSchema: {
|
|
174576
|
+
action: z627.enum(["start", "record", "show", "list", "close"]).describe("Continuity operation"),
|
|
174577
|
+
taskId: z627.string().max(120).optional().describe("Continuity task id"),
|
|
174578
|
+
task: z627.string().max(1e3).optional().describe("Task description for start"),
|
|
174579
|
+
requirements: z627.array(z627.string().max(2e3)).max(8).optional().describe("Requirements for start"),
|
|
174580
|
+
kind: z627.enum(["requirement", "decision", "verification", "risk"]).optional().describe("Entry kind for record"),
|
|
174581
|
+
content: z627.string().max(2e3).optional().describe("Requirement, decision, verification, risk, or outcome text"),
|
|
174582
|
+
verificationStatus: z627.enum(["pending", "passed", "failed", "skipped"]).optional(),
|
|
174583
|
+
verificationId: z627.string().max(120).optional().describe("Stable verification obligation id; reuse it to move pending to passed/failed"),
|
|
174584
|
+
idempotencyKey: z627.string().max(200).optional().describe("Stable retry key; repeating the same operation returns the original event"),
|
|
174585
|
+
status: z627.enum(["completed", "blocked", "abandoned"]).optional().describe("Outcome status for close"),
|
|
174586
|
+
sourceRef: z627.string().max(500).optional().describe("Evidence or source reference"),
|
|
174587
|
+
evidenceRefs: z627.array(z627.string().max(500)).max(8).optional(),
|
|
174588
|
+
actor: z627.string().max(200).optional(),
|
|
174589
|
+
limit: z627.number().int().positive().max(100).optional().default(20)
|
|
174590
|
+
}
|
|
174591
|
+
},
|
|
174592
|
+
async ({ action, taskId, task, requirements, kind, content, verificationStatus, verificationId, idempotencyKey, status, sourceRef, evidenceRefs: evidenceRefs2, actor, limit: limit2 }) => {
|
|
174593
|
+
const unresolved = requireResolvedProject("manage task continuity for the current project");
|
|
174594
|
+
if (unresolved) return unresolved;
|
|
174595
|
+
const { TaskContinuityStore: TaskContinuityStore2 } = await Promise.resolve().then(() => (init_task_continuity(), task_continuity_exports));
|
|
174596
|
+
const continuity = new TaskContinuityStore2();
|
|
174597
|
+
await continuity.init(projectDir2);
|
|
174598
|
+
const effectiveActor = actor ?? currentAgentId;
|
|
174599
|
+
try {
|
|
174600
|
+
if (action === "start") {
|
|
174601
|
+
if (!task?.trim()) return { content: [{ type: "text", text: "task is required for continuity start." }], isError: true };
|
|
174602
|
+
const result2 = continuity.start({
|
|
174603
|
+
projectId: project.id,
|
|
174604
|
+
task,
|
|
174605
|
+
...taskId ? { taskId } : {},
|
|
174606
|
+
requirements,
|
|
174607
|
+
...effectiveActor ? { actor: effectiveActor } : {},
|
|
174608
|
+
...idempotencyKey ? { idempotencyKey } : {}
|
|
174609
|
+
});
|
|
174610
|
+
return { content: [{ type: "text", text: JSON.stringify({ projectId: project.id, ...result2 }, null, 2) }] };
|
|
174611
|
+
}
|
|
174612
|
+
if (action === "list") {
|
|
174613
|
+
return { content: [{ type: "text", text: JSON.stringify({ projectId: project.id, ledgers: continuity.list(project.id, limit2) }, null, 2) }] };
|
|
174614
|
+
}
|
|
174615
|
+
if (!taskId?.trim()) return { content: [{ type: "text", text: "taskId is required for this continuity action." }], isError: true };
|
|
174616
|
+
if (action === "show") {
|
|
174617
|
+
const ledger = continuity.get(project.id, taskId);
|
|
174618
|
+
if (!ledger) return { content: [{ type: "text", text: "Task continuity ledger not found." }], isError: true };
|
|
174619
|
+
return { content: [{ type: "text", text: JSON.stringify({ projectId: project.id, ledger }, null, 2) }] };
|
|
174620
|
+
}
|
|
174621
|
+
if (action === "record") {
|
|
174622
|
+
if (!kind || !content?.trim()) {
|
|
174623
|
+
return { content: [{ type: "text", text: "record requires kind and content." }], isError: true };
|
|
174624
|
+
}
|
|
174625
|
+
const result2 = continuity.record({
|
|
174626
|
+
projectId: project.id,
|
|
174627
|
+
taskId,
|
|
174628
|
+
kind,
|
|
174629
|
+
content,
|
|
174630
|
+
...verificationStatus ? { verificationStatus } : {},
|
|
174631
|
+
...sourceRef ? { sourceRef } : {},
|
|
174632
|
+
...evidenceRefs2 ? { evidenceRefs: evidenceRefs2 } : {},
|
|
174633
|
+
...effectiveActor ? { actor: effectiveActor } : {},
|
|
174634
|
+
...verificationId ? { verificationId } : {},
|
|
174635
|
+
...idempotencyKey ? { idempotencyKey } : {}
|
|
174636
|
+
});
|
|
174637
|
+
return { content: [{ type: "text", text: JSON.stringify({ projectId: project.id, ...result2 }, null, 2) }] };
|
|
174638
|
+
}
|
|
174639
|
+
if (!status || !content?.trim()) {
|
|
174640
|
+
return { content: [{ type: "text", text: "close requires status and content." }], isError: true };
|
|
174641
|
+
}
|
|
174642
|
+
const result = continuity.close({
|
|
174643
|
+
projectId: project.id,
|
|
174644
|
+
taskId,
|
|
174645
|
+
status,
|
|
174646
|
+
content,
|
|
174647
|
+
...sourceRef ? { sourceRef } : {},
|
|
174648
|
+
...evidenceRefs2 ? { evidenceRefs: evidenceRefs2 } : {},
|
|
174649
|
+
...effectiveActor ? { actor: effectiveActor } : {},
|
|
174650
|
+
...idempotencyKey ? { idempotencyKey } : {}
|
|
174651
|
+
});
|
|
174652
|
+
return { content: [{ type: "text", text: JSON.stringify({ projectId: project.id, ...result }, null, 2) }] };
|
|
174653
|
+
} catch (error) {
|
|
174654
|
+
return { content: [{ type: "text", text: error instanceof Error ? error.message : String(error) }], isError: true };
|
|
174655
|
+
}
|
|
174656
|
+
}
|
|
174657
|
+
);
|
|
173946
174658
|
if (teamFeaturesEnabled) {
|
|
173947
174659
|
const { initTeamStore: initTeamStore2 } = await Promise.resolve().then(() => (init_team_store(), team_store_exports));
|
|
173948
174660
|
initTeamStoreForProject = initTeamStore2;
|
|
@@ -174970,7 +175682,9 @@ fi
|
|
|
174970
175682
|
graphManager,
|
|
174971
175683
|
projectId: project.id,
|
|
174972
175684
|
deferredInit,
|
|
175685
|
+
activateProjectRuntime,
|
|
174973
175686
|
switchProject,
|
|
175687
|
+
getProjectDataDir: () => projectDir2,
|
|
174974
175688
|
isExplicitlyBound: () => projectBinding.isExplicit(),
|
|
174975
175689
|
getRequestContext,
|
|
174976
175690
|
handleTransportClose
|