memorix 1.9.4 → 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 +75 -1
- package/README.md +12 -6
- package/README.zh-CN.md +12 -6
- package/dist/cli/index.js +2533 -585
- package/dist/index.d.ts +15 -8
- package/dist/index.js +1201 -284
- package/dist/maintenance-runner.js +387 -216
- package/dist/media-audio-runner.js +300 -129
- package/dist/media-video-runner.js +300 -129
- package/dist/memcode-runtime/CHANGELOG.md +75 -1
- package/dist/sdk.d.ts +1 -0
- package/dist/sdk.js +1882 -998
- package/dist/types.d.ts +1 -1
- package/dist/vector-backfill-runner.js +300 -129
- package/docs/AGENT_OPERATOR_PLAYBOOK.md +47 -3
- package/docs/API_REFERENCE.md +39 -1
- package/docs/CONFIGURATION.md +58 -1
- package/docs/DEVELOPMENT.md +1 -1
- package/docs/DOCKER.md +23 -3
- package/docs/INTEGRATIONS.md +1 -1
- package/docs/KNOWN_ISSUES_AND_ROADMAP.md +61 -1
- package/docs/MULTI-DEVICE-SYNC-RESEARCH.md +4 -0
- package/docs/PERFORMANCE.md +46 -2
- package/docs/README.md +2 -1
- package/docs/SETUP.md +56 -1
- package/package.json +3 -2
- 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 +15 -3
- package/src/cli/commands/agent-integrations.ts +57 -0
- package/src/cli/commands/background.ts +11 -2
- 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 +435 -84
- package/src/cli/commands/setup.ts +77 -10
- package/src/cli/commands/sync-store.ts +47 -12
- package/src/cli/commands/sync.ts +26 -0
- 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/dashboard/server.ts +10 -12
- 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/integrations/registry.ts +1 -1
- 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/memory/graph.ts +10 -8
- package/src/memory/session.ts +1 -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/sdk.ts +24 -0
- package/src/server/mcp-binding-store.ts +14 -3
- package/src/server/modern-mcp-bridge.ts +153 -27
- package/src/server/tool-profile.ts +3 -2
- package/src/server.ts +131 -7
- package/src/store/file-lock.ts +28 -3
- package/src/store/graph-store.ts +178 -46
- package/src/store/persistence.ts +14 -9
- package/src/store/sqlite-db.ts +150 -7
- package/src/store/sqlite-store.ts +32 -27
- package/src/sync/engine.ts +9 -7
- package/src/sync/namespace.ts +23 -0
- package/src/sync/policy.ts +19 -4
- package/src/sync/store-port.ts +43 -13
- package/src/sync/types.ts +2 -0
- package/src/team/team-store.ts +62 -27
- package/src/types.ts +1 -1
- package/src/workspace/mcp-adapters/grok.ts +32 -0
|
@@ -155,15 +155,20 @@ var init_dotenv_loader = __esm({
|
|
|
155
155
|
import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
|
|
156
156
|
import { homedir as homedir2 } from "os";
|
|
157
157
|
import { parse as parseYamlDocument } from "yaml";
|
|
158
|
+
function cacheKey(homeDir, projectRoot) {
|
|
159
|
+
return `${homeDir}\0${projectRoot ?? ""}`;
|
|
160
|
+
}
|
|
158
161
|
function initProjectRoot(root) {
|
|
159
162
|
globalProjectRoot = root;
|
|
160
|
-
configCache.delete(root);
|
|
163
|
+
configCache.delete(cacheKey(homedir2(), root));
|
|
161
164
|
}
|
|
162
|
-
function loadYamlConfig(projectRoot) {
|
|
165
|
+
function loadYamlConfig(projectRoot, options = {}) {
|
|
166
|
+
const homeDir = options.homeDir ?? homedir2();
|
|
163
167
|
const resolvedRoot = projectRoot === null ? null : projectRoot ?? globalProjectRoot ?? null;
|
|
164
|
-
const
|
|
168
|
+
const key = cacheKey(homeDir, resolvedRoot);
|
|
169
|
+
const cached = configCache.get(key);
|
|
165
170
|
if (cached) return cached;
|
|
166
|
-
const userYaml = getGlobalYamlPath(
|
|
171
|
+
const userYaml = getGlobalYamlPath(homeDir);
|
|
167
172
|
const projectYaml = resolvedRoot ? getProjectYamlPath(resolvedRoot) : null;
|
|
168
173
|
let userConfig = {};
|
|
169
174
|
let projectConfig = {};
|
|
@@ -195,7 +200,7 @@ function loadYamlConfig(projectRoot) {
|
|
|
195
200
|
server: { ...userConfig.server, ...projectConfig.server },
|
|
196
201
|
team: { ...userConfig.team, ...projectConfig.team }
|
|
197
202
|
};
|
|
198
|
-
configCache.set(
|
|
203
|
+
configCache.set(key, merged);
|
|
199
204
|
return merged;
|
|
200
205
|
}
|
|
201
206
|
function parseYaml(content) {
|
|
@@ -572,11 +577,21 @@ function applySchemaMigrations(db2) {
|
|
|
572
577
|
apply();
|
|
573
578
|
}
|
|
574
579
|
}
|
|
580
|
+
function normalizeDataDir(dataDir) {
|
|
581
|
+
return path3.resolve(dataDir);
|
|
582
|
+
}
|
|
583
|
+
function touchDatabase(normalized, db2) {
|
|
584
|
+
_dbCache.delete(normalized);
|
|
585
|
+
_dbCache.set(normalized, db2);
|
|
586
|
+
}
|
|
575
587
|
function getDatabase(dataDir) {
|
|
576
|
-
const normalized =
|
|
588
|
+
const normalized = normalizeDataDir(dataDir);
|
|
577
589
|
assertNotHomeDataDir(normalized);
|
|
578
590
|
const existing = _dbCache.get(normalized);
|
|
579
|
-
if (existing)
|
|
591
|
+
if (existing) {
|
|
592
|
+
touchDatabase(normalized, existing);
|
|
593
|
+
return existing;
|
|
594
|
+
}
|
|
580
595
|
loadBetterSqlite3();
|
|
581
596
|
fs.mkdirSync(dataDir, { recursive: true });
|
|
582
597
|
const dbPath = path3.join(dataDir, "memorix.db");
|
|
@@ -606,6 +621,8 @@ function getDatabase(dataDir) {
|
|
|
606
621
|
db2.exec(CREATE_MAINTENANCE_JOBS_TABLE);
|
|
607
622
|
db2.exec(CREATE_MAINTENANCE_TARGETS_TABLE);
|
|
608
623
|
db2.exec(CREATE_COMPACTION_CHECKPOINTS_TABLE);
|
|
624
|
+
db2.exec(CREATE_TASK_CONTINUITY_EVENTS_TABLE);
|
|
625
|
+
db2.exec(CREATE_AGENT_EFFECTS_TABLE);
|
|
609
626
|
try {
|
|
610
627
|
db2.exec(`ALTER TABLE mini_skills ADD COLUMN sourceSnapshot TEXT NOT NULL DEFAULT ''`);
|
|
611
628
|
} catch {
|
|
@@ -644,7 +661,7 @@ function getDatabase(dataDir) {
|
|
|
644
661
|
db2.prepare(`INSERT OR IGNORE INTO meta (key, value) VALUES ('storage_generation', '0')`).run();
|
|
645
662
|
db2.prepare(`INSERT OR IGNORE INTO meta (key, value) VALUES ('next_id', '1')`).run();
|
|
646
663
|
db2.prepare(`INSERT OR IGNORE INTO meta (key, value) VALUES ('mini_skills_generation', '0')`).run();
|
|
647
|
-
|
|
664
|
+
touchDatabase(normalized, db2);
|
|
648
665
|
return db2;
|
|
649
666
|
} catch (error) {
|
|
650
667
|
try {
|
|
@@ -662,8 +679,9 @@ function closeAllDatabases() {
|
|
|
662
679
|
}
|
|
663
680
|
_dbCache.delete(key);
|
|
664
681
|
}
|
|
682
|
+
_dbLeases.clear();
|
|
665
683
|
}
|
|
666
|
-
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;
|
|
684
|
+
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;
|
|
667
685
|
var init_sqlite_db = __esm({
|
|
668
686
|
"src/store/sqlite-db.ts"() {
|
|
669
687
|
"use strict";
|
|
@@ -835,18 +853,21 @@ CREATE TABLE IF NOT EXISTS chat_transcript (
|
|
|
835
853
|
`;
|
|
836
854
|
CREATE_GRAPH_ENTITIES_TABLE = `
|
|
837
855
|
CREATE TABLE IF NOT EXISTS graph_entities (
|
|
838
|
-
|
|
856
|
+
projectId TEXT NOT NULL,
|
|
857
|
+
name TEXT NOT NULL,
|
|
839
858
|
entityType TEXT NOT NULL DEFAULT '',
|
|
840
|
-
observations TEXT NOT NULL DEFAULT '[]'
|
|
859
|
+
observations TEXT NOT NULL DEFAULT '[]',
|
|
860
|
+
PRIMARY KEY (projectId, name)
|
|
841
861
|
);
|
|
842
862
|
`;
|
|
843
863
|
CREATE_GRAPH_RELATIONS_TABLE = `
|
|
844
864
|
CREATE TABLE IF NOT EXISTS graph_relations (
|
|
845
865
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
866
|
+
projectId TEXT NOT NULL,
|
|
846
867
|
from_entity TEXT NOT NULL,
|
|
847
868
|
to_entity TEXT NOT NULL,
|
|
848
869
|
relationType TEXT NOT NULL DEFAULT '',
|
|
849
|
-
UNIQUE(from_entity, to_entity, relationType)
|
|
870
|
+
UNIQUE(projectId, from_entity, to_entity, relationType)
|
|
850
871
|
);
|
|
851
872
|
`;
|
|
852
873
|
CREATE_CODE_FILES_TABLE = `
|
|
@@ -1377,6 +1398,43 @@ CREATE TABLE IF NOT EXISTS memory_feedback_events (
|
|
|
1377
1398
|
delta REAL NOT NULL DEFAULT 0,
|
|
1378
1399
|
observed_at TEXT NOT NULL
|
|
1379
1400
|
);
|
|
1401
|
+
`;
|
|
1402
|
+
CREATE_TASK_CONTINUITY_EVENTS_TABLE = `
|
|
1403
|
+
CREATE TABLE IF NOT EXISTS task_continuity_events (
|
|
1404
|
+
id TEXT PRIMARY KEY,
|
|
1405
|
+
project_id TEXT NOT NULL,
|
|
1406
|
+
task_id TEXT NOT NULL,
|
|
1407
|
+
task TEXT NOT NULL,
|
|
1408
|
+
kind TEXT NOT NULL,
|
|
1409
|
+
content TEXT NOT NULL,
|
|
1410
|
+
item_status TEXT,
|
|
1411
|
+
source_ref TEXT,
|
|
1412
|
+
evidence_json TEXT NOT NULL DEFAULT '[]',
|
|
1413
|
+
actor TEXT,
|
|
1414
|
+
created_at TEXT NOT NULL,
|
|
1415
|
+
event_key TEXT,
|
|
1416
|
+
item_key TEXT,
|
|
1417
|
+
supersedes_id TEXT
|
|
1418
|
+
);
|
|
1419
|
+
`;
|
|
1420
|
+
CREATE_AGENT_EFFECTS_TABLE = `
|
|
1421
|
+
CREATE TABLE IF NOT EXISTS agent_effects (
|
|
1422
|
+
id TEXT PRIMARY KEY,
|
|
1423
|
+
pipeline_id TEXT NOT NULL,
|
|
1424
|
+
task_id TEXT NOT NULL,
|
|
1425
|
+
attempt INTEGER NOT NULL,
|
|
1426
|
+
effect_key TEXT NOT NULL,
|
|
1427
|
+
tool TEXT NOT NULL,
|
|
1428
|
+
risk_tier TEXT NOT NULL,
|
|
1429
|
+
replay_policy TEXT NOT NULL,
|
|
1430
|
+
status TEXT NOT NULL,
|
|
1431
|
+
call_id TEXT,
|
|
1432
|
+
idempotency_key TEXT NOT NULL,
|
|
1433
|
+
input_fingerprint TEXT,
|
|
1434
|
+
detail TEXT,
|
|
1435
|
+
started_at INTEGER NOT NULL,
|
|
1436
|
+
finished_at INTEGER
|
|
1437
|
+
);
|
|
1380
1438
|
`;
|
|
1381
1439
|
CREATE_MCP_BINDINGS_TABLE = `
|
|
1382
1440
|
CREATE TABLE IF NOT EXISTS mcp_bindings (
|
|
@@ -1455,7 +1513,18 @@ CREATE INDEX IF NOT EXISTS idx_evidence_cards_candidate ON evidence_cards(projec
|
|
|
1455
1513
|
CREATE INDEX IF NOT EXISTS idx_evidence_card_events_card ON evidence_card_events(card_id, created_at);
|
|
1456
1514
|
CREATE INDEX IF NOT EXISTS idx_memory_feedback_states_project ON memory_feedback_states(project_id, candidate_kind, updated_at DESC);
|
|
1457
1515
|
CREATE INDEX IF NOT EXISTS idx_memory_feedback_events_candidate ON memory_feedback_events(project_id, candidate_kind, candidate_id, observed_at DESC);
|
|
1516
|
+
CREATE INDEX IF NOT EXISTS idx_task_continuity_project_task ON task_continuity_events(project_id, task_id, created_at ASC);
|
|
1517
|
+
CREATE INDEX IF NOT EXISTS idx_task_continuity_project_recent ON task_continuity_events(project_id, created_at DESC);
|
|
1518
|
+
CREATE INDEX IF NOT EXISTS idx_task_continuity_item ON task_continuity_events(project_id, task_id, kind, item_key, created_at DESC);
|
|
1519
|
+
CREATE UNIQUE INDEX IF NOT EXISTS idx_task_continuity_event_key
|
|
1520
|
+
ON task_continuity_events(project_id, task_id, event_key)
|
|
1521
|
+
WHERE event_key IS NOT NULL;
|
|
1522
|
+
CREATE UNIQUE INDEX IF NOT EXISTS idx_agent_effect_identity
|
|
1523
|
+
ON agent_effects(pipeline_id, task_id, attempt, effect_key);
|
|
1524
|
+
CREATE INDEX IF NOT EXISTS idx_agent_effect_pipeline ON agent_effects(pipeline_id, started_at ASC);
|
|
1458
1525
|
CREATE INDEX IF NOT EXISTS idx_mcp_bindings_project ON mcp_bindings(project_id, last_used_at DESC);
|
|
1526
|
+
CREATE INDEX IF NOT EXISTS idx_mcp_bindings_root ON mcp_bindings(project_root, last_used_at DESC);
|
|
1527
|
+
CREATE INDEX IF NOT EXISTS idx_mcp_bindings_expiry ON mcp_bindings(expires_at);
|
|
1459
1528
|
CREATE UNIQUE INDEX IF NOT EXISTS idx_maintenance_jobs_active_dedupe
|
|
1460
1529
|
ON maintenance_jobs(project_id, kind, dedupe_key)
|
|
1461
1530
|
WHERE status IN ('pending', 'running', 'retry');
|
|
@@ -1626,6 +1695,8 @@ CREATE UNIQUE INDEX IF NOT EXISTS idx_maintenance_jobs_active_dedupe
|
|
|
1626
1695
|
db2.exec("CREATE INDEX IF NOT EXISTS idx_memory_feedback_states_project ON memory_feedback_states(project_id, candidate_kind, updated_at DESC)");
|
|
1627
1696
|
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)");
|
|
1628
1697
|
db2.exec("CREATE INDEX IF NOT EXISTS idx_mcp_bindings_project ON mcp_bindings(project_id, last_used_at DESC)");
|
|
1698
|
+
db2.exec("CREATE INDEX IF NOT EXISTS idx_mcp_bindings_root ON mcp_bindings(project_root, last_used_at DESC)");
|
|
1699
|
+
db2.exec("CREATE INDEX IF NOT EXISTS idx_mcp_bindings_expiry ON mcp_bindings(expires_at)");
|
|
1629
1700
|
}
|
|
1630
1701
|
},
|
|
1631
1702
|
{
|
|
@@ -1636,9 +1707,22 @@ CREATE UNIQUE INDEX IF NOT EXISTS idx_maintenance_jobs_active_dedupe
|
|
|
1636
1707
|
addColumnIfMissing(db2, "code_symbols", "source", "source TEXT");
|
|
1637
1708
|
addColumnIfMissing(db2, "code_edges", "source", "source TEXT");
|
|
1638
1709
|
}
|
|
1710
|
+
},
|
|
1711
|
+
{
|
|
1712
|
+
id: "1.9-continuity-v2",
|
|
1713
|
+
apply: (db2) => {
|
|
1714
|
+
addColumnIfMissing(db2, "task_continuity_events", "event_key", "event_key TEXT");
|
|
1715
|
+
addColumnIfMissing(db2, "task_continuity_events", "item_key", "item_key TEXT");
|
|
1716
|
+
addColumnIfMissing(db2, "task_continuity_events", "supersedes_id", "supersedes_id TEXT");
|
|
1717
|
+
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)");
|
|
1718
|
+
db2.exec(`CREATE UNIQUE INDEX IF NOT EXISTS idx_task_continuity_event_key
|
|
1719
|
+
ON task_continuity_events(project_id, task_id, event_key)
|
|
1720
|
+
WHERE event_key IS NOT NULL`);
|
|
1721
|
+
}
|
|
1639
1722
|
}
|
|
1640
1723
|
];
|
|
1641
1724
|
_dbCache = /* @__PURE__ */ new Map();
|
|
1725
|
+
_dbLeases = /* @__PURE__ */ new Map();
|
|
1642
1726
|
}
|
|
1643
1727
|
});
|
|
1644
1728
|
|
|
@@ -1714,6 +1798,21 @@ var init_sqlite_reliability = __esm({
|
|
|
1714
1798
|
import { promises as fs2 } from "fs";
|
|
1715
1799
|
import { randomUUID } from "crypto";
|
|
1716
1800
|
import path4 from "path";
|
|
1801
|
+
function canReclaimStaleLock(raw) {
|
|
1802
|
+
try {
|
|
1803
|
+
const parsed = JSON.parse(raw);
|
|
1804
|
+
const pid = Number(parsed.pid);
|
|
1805
|
+
if (!Number.isSafeInteger(pid) || pid < 1) return true;
|
|
1806
|
+
try {
|
|
1807
|
+
process.kill(pid, 0);
|
|
1808
|
+
return false;
|
|
1809
|
+
} catch (error) {
|
|
1810
|
+
return error.code !== "EPERM";
|
|
1811
|
+
}
|
|
1812
|
+
} catch {
|
|
1813
|
+
return true;
|
|
1814
|
+
}
|
|
1815
|
+
}
|
|
1717
1816
|
async function acquireLock(lockPath) {
|
|
1718
1817
|
for (let i2 = 0; i2 < MAX_RETRIES; i2++) {
|
|
1719
1818
|
try {
|
|
@@ -1727,9 +1826,12 @@ async function acquireLock(lockPath) {
|
|
|
1727
1826
|
try {
|
|
1728
1827
|
const stat5 = await fs2.stat(lockPath);
|
|
1729
1828
|
if (Date.now() - stat5.mtimeMs > LOCK_STALE_MS) {
|
|
1730
|
-
await fs2.
|
|
1731
|
-
|
|
1732
|
-
|
|
1829
|
+
const raw2 = await fs2.readFile(lockPath, "utf8").catch(() => "");
|
|
1830
|
+
if (canReclaimStaleLock(raw2)) {
|
|
1831
|
+
await fs2.unlink(lockPath).catch(() => {
|
|
1832
|
+
});
|
|
1833
|
+
continue;
|
|
1834
|
+
}
|
|
1733
1835
|
}
|
|
1734
1836
|
} catch {
|
|
1735
1837
|
continue;
|
|
@@ -1740,6 +1842,10 @@ async function acquireLock(lockPath) {
|
|
|
1740
1842
|
}
|
|
1741
1843
|
}
|
|
1742
1844
|
}
|
|
1845
|
+
const raw = await fs2.readFile(lockPath, "utf8").catch(() => "");
|
|
1846
|
+
if (!canReclaimStaleLock(raw)) {
|
|
1847
|
+
throw new Error(`Failed to acquire lock: ${lockPath} (owner is still running)`);
|
|
1848
|
+
}
|
|
1743
1849
|
await fs2.unlink(lockPath).catch(() => {
|
|
1744
1850
|
});
|
|
1745
1851
|
try {
|
|
@@ -2106,9 +2212,9 @@ var init_detector = __esm({
|
|
|
2106
2212
|
// src/config/legacy-loader.ts
|
|
2107
2213
|
import { existsSync as existsSync5, readFileSync as readFileSync5 } from "fs";
|
|
2108
2214
|
import { homedir as homedir3 } from "os";
|
|
2109
|
-
function loadFileConfig() {
|
|
2215
|
+
function loadFileConfig(homeDir = homedir3()) {
|
|
2110
2216
|
if (cachedConfig !== null) return cachedConfig;
|
|
2111
|
-
const configPath = getLegacyConfigJsonPath(
|
|
2217
|
+
const configPath = getLegacyConfigJsonPath(homeDir);
|
|
2112
2218
|
try {
|
|
2113
2219
|
if (existsSync5(configPath)) {
|
|
2114
2220
|
cachedConfig = JSON.parse(readFileSync5(configPath, "utf-8"));
|
|
@@ -2138,15 +2244,15 @@ import { homedir as homedir4 } from "os";
|
|
|
2138
2244
|
function loadTomlConfig(options = {}) {
|
|
2139
2245
|
const homeDir = options.homeDir ?? homedir4();
|
|
2140
2246
|
const projectRoot = options.projectRoot ?? null;
|
|
2141
|
-
const
|
|
2142
|
-
const cached = configCache2.get(
|
|
2247
|
+
const cacheKey3 = `${homeDir}\0${projectRoot ?? ""}`;
|
|
2248
|
+
const cached = configCache2.get(cacheKey3);
|
|
2143
2249
|
if (cached) return cached;
|
|
2144
2250
|
const userToml = getGlobalConfigTomlPath(homeDir);
|
|
2145
2251
|
const projectToml = projectRoot ? getProjectConfigTomlPath(projectRoot) : null;
|
|
2146
2252
|
const userConfig = existsSync6(userToml) ? parseTomlConfig(readFileSync6(userToml, "utf8"), userToml) : {};
|
|
2147
2253
|
const projectConfig = projectToml && existsSync6(projectToml) ? parseTomlConfig(readFileSync6(projectToml, "utf8"), projectToml) : {};
|
|
2148
2254
|
const merged = mergeTomlConfig(userConfig, projectConfig);
|
|
2149
|
-
configCache2.set(
|
|
2255
|
+
configCache2.set(cacheKey3, merged);
|
|
2150
2256
|
return merged;
|
|
2151
2257
|
}
|
|
2152
2258
|
function mergeTomlConfig(base, override) {
|
|
@@ -2267,8 +2373,8 @@ function getResolvedConfig(options = {}) {
|
|
|
2267
2373
|
const projectRoot = options.projectRoot === void 0 ? detectProject()?.rootPath ?? null : options.projectRoot;
|
|
2268
2374
|
loadDotenv(projectRoot === null ? void 0 : projectRoot ?? void 0, { userHomeDir: homeDir });
|
|
2269
2375
|
const toml = loadTomlConfig({ projectRoot: projectRoot ?? null, homeDir });
|
|
2270
|
-
const yaml = loadYamlConfig(projectRoot ?? null);
|
|
2271
|
-
const legacy = loadFileConfig();
|
|
2376
|
+
const yaml = loadYamlConfig(projectRoot ?? null, { homeDir });
|
|
2377
|
+
const legacy = loadFileConfig(homeDir);
|
|
2272
2378
|
const embeddingBaseUrl = first(process.env.MEMORIX_EMBEDDING_BASE_URL, toml.embedding?.base_url, yaml.embedding?.baseUrl, legacy.embeddingApi?.baseUrl);
|
|
2273
2379
|
const openRouterEmbeddingApiKey = isOpenRouterUrl(embeddingBaseUrl) ? process.env.OPENROUTER_API_KEY : void 0;
|
|
2274
2380
|
const memoryLlmProvider = first(
|
|
@@ -2290,15 +2396,17 @@ function getResolvedConfig(options = {}) {
|
|
|
2290
2396
|
legacy.llm?.baseUrl
|
|
2291
2397
|
);
|
|
2292
2398
|
const openRouterMemoryLlmApiKey = isOpenRouterMemoryLane(memoryLlmProvider, memoryLlmBaseUrl) ? process.env.OPENROUTER_API_KEY : void 0;
|
|
2399
|
+
const isAtlasCloud = memoryLlmProvider === "atlascloud";
|
|
2293
2400
|
const memoryLlmApiKey = first(
|
|
2294
2401
|
process.env.MEMORIX_LLM_API_KEY,
|
|
2295
2402
|
process.env.MEMORIX_API_KEY,
|
|
2296
2403
|
toml.memory?.llm?.api_key,
|
|
2297
2404
|
yaml.llm?.apiKey,
|
|
2298
2405
|
legacy.llm?.apiKey,
|
|
2299
|
-
|
|
2300
|
-
process.env.
|
|
2301
|
-
|
|
2406
|
+
// Never borrow another provider's credentials for the Atlas Cloud preset.
|
|
2407
|
+
isAtlasCloud ? process.env.ATLASCLOUD_API_KEY : process.env.OPENAI_API_KEY,
|
|
2408
|
+
isAtlasCloud ? void 0 : process.env.ANTHROPIC_API_KEY,
|
|
2409
|
+
isAtlasCloud ? void 0 : openRouterMemoryLlmApiKey
|
|
2302
2410
|
);
|
|
2303
2411
|
const resolved = {
|
|
2304
2412
|
agent: {
|
|
@@ -2477,7 +2585,8 @@ function getEnvSourceNames() {
|
|
|
2477
2585
|
"MEMORIX_CODEGRAPH_EXTERNAL_CONTEXT",
|
|
2478
2586
|
"MEMORIX_CODEGRAPH_EXTERNAL_COMMAND",
|
|
2479
2587
|
"MEMORIX_CODEGRAPH_EXTERNAL_TIMEOUT_MS",
|
|
2480
|
-
"OPENROUTER_API_KEY"
|
|
2588
|
+
"OPENROUTER_API_KEY",
|
|
2589
|
+
"ATLASCLOUD_API_KEY"
|
|
2481
2590
|
].filter((name) => process.env[name]);
|
|
2482
2591
|
}
|
|
2483
2592
|
function isOpenRouterUrl(value) {
|
|
@@ -2696,12 +2805,45 @@ function textHash(text2) {
|
|
|
2696
2805
|
async function loadDiskCache() {
|
|
2697
2806
|
try {
|
|
2698
2807
|
const raw = await readFile(CACHE_FILE, "utf-8");
|
|
2808
|
+
if (Buffer.byteLength(raw, "utf8") > MAX_CACHE_FILE_BYTES) {
|
|
2809
|
+
console.error("[memorix] FastEmbed cache exceeds the disk load limit; starting with an empty cache");
|
|
2810
|
+
return;
|
|
2811
|
+
}
|
|
2699
2812
|
const entries = JSON.parse(raw);
|
|
2700
|
-
|
|
2701
|
-
|
|
2813
|
+
if (!Array.isArray(entries)) return;
|
|
2814
|
+
for (const entry of entries) {
|
|
2815
|
+
if (!Array.isArray(entry) || typeof entry[0] !== "string" || !isVector(entry[1])) continue;
|
|
2816
|
+
cacheSet(entry[0], entry[1], false);
|
|
2817
|
+
}
|
|
2818
|
+
console.error(`[memorix] Loaded ${cache.size} cached embeddings from disk`);
|
|
2702
2819
|
} catch {
|
|
2703
2820
|
}
|
|
2704
2821
|
}
|
|
2822
|
+
function isVector(value) {
|
|
2823
|
+
return Array.isArray(value) && value.every((entry) => typeof entry === "number");
|
|
2824
|
+
}
|
|
2825
|
+
function maxCachePayloadBytes() {
|
|
2826
|
+
const raw = Number.parseInt(process.env.MEMORIX_EMBEDDING_CACHE_MAX_BYTES ?? "", 10);
|
|
2827
|
+
return Number.isFinite(raw) && raw > 0 ? raw : DEFAULT_CACHE_PAYLOAD_BYTES;
|
|
2828
|
+
}
|
|
2829
|
+
function cacheSet(hash4, value, markDirty = true) {
|
|
2830
|
+
const incomingBytes = value.length * 8;
|
|
2831
|
+
if (incomingBytes > maxCachePayloadBytes()) return;
|
|
2832
|
+
const existing = cache.get(hash4);
|
|
2833
|
+
if (existing) cachePayloadBytes -= existing.length * 8;
|
|
2834
|
+
else {
|
|
2835
|
+
while (cache.size >= MAX_CACHE_SIZE || cachePayloadBytes + incomingBytes > maxCachePayloadBytes()) {
|
|
2836
|
+
const firstKey = cache.keys().next().value;
|
|
2837
|
+
if (firstKey === void 0) break;
|
|
2838
|
+
const old = cache.get(firstKey);
|
|
2839
|
+
cache.delete(firstKey);
|
|
2840
|
+
if (old) cachePayloadBytes -= old.length * 8;
|
|
2841
|
+
}
|
|
2842
|
+
}
|
|
2843
|
+
cache.set(hash4, value);
|
|
2844
|
+
cachePayloadBytes += incomingBytes;
|
|
2845
|
+
if (markDirty) diskCacheDirty = true;
|
|
2846
|
+
}
|
|
2705
2847
|
async function saveDiskCache() {
|
|
2706
2848
|
if (!diskCacheDirty) return;
|
|
2707
2849
|
try {
|
|
@@ -2712,7 +2854,7 @@ async function saveDiskCache() {
|
|
|
2712
2854
|
} catch {
|
|
2713
2855
|
}
|
|
2714
2856
|
}
|
|
2715
|
-
var CACHE_DIR, CACHE_FILE, cache, MAX_CACHE_SIZE, diskCacheDirty, FastEmbedProvider;
|
|
2857
|
+
var CACHE_DIR, CACHE_FILE, cache, MAX_CACHE_SIZE, DEFAULT_CACHE_PAYLOAD_BYTES, MAX_CACHE_FILE_BYTES, cachePayloadBytes, diskCacheDirty, FastEmbedProvider;
|
|
2716
2858
|
var init_fastembed_provider = __esm({
|
|
2717
2859
|
"src/embedding/fastembed-provider.ts"() {
|
|
2718
2860
|
"use strict";
|
|
@@ -2722,6 +2864,9 @@ var init_fastembed_provider = __esm({
|
|
|
2722
2864
|
CACHE_FILE = join2(CACHE_DIR, ".embedding-cache.json");
|
|
2723
2865
|
cache = /* @__PURE__ */ new Map();
|
|
2724
2866
|
MAX_CACHE_SIZE = 5e3;
|
|
2867
|
+
DEFAULT_CACHE_PAYLOAD_BYTES = 64 * 1024 * 1024;
|
|
2868
|
+
MAX_CACHE_FILE_BYTES = 128 * 1024 * 1024;
|
|
2869
|
+
cachePayloadBytes = 0;
|
|
2725
2870
|
diskCacheDirty = false;
|
|
2726
2871
|
FastEmbedProvider = class _FastEmbedProvider {
|
|
2727
2872
|
name = "fastembed-bge-small";
|
|
@@ -2763,7 +2908,7 @@ var init_fastembed_provider = __esm({
|
|
|
2763
2908
|
if (result.length !== this.dimensions) {
|
|
2764
2909
|
throw new Error(`Expected ${this.dimensions}d embedding, got ${result.length}d`);
|
|
2765
2910
|
}
|
|
2766
|
-
|
|
2911
|
+
cacheSet(hash4, result);
|
|
2767
2912
|
return result;
|
|
2768
2913
|
}
|
|
2769
2914
|
async embedBatch(texts) {
|
|
@@ -2788,7 +2933,7 @@ var init_fastembed_provider = __esm({
|
|
|
2788
2933
|
const originalIdx = uncachedIndices[batchIdx];
|
|
2789
2934
|
const plain = Array.from(vec);
|
|
2790
2935
|
results[originalIdx] = plain;
|
|
2791
|
-
|
|
2936
|
+
cacheSet(textHash(uncachedTexts[batchIdx]), plain);
|
|
2792
2937
|
batchIdx++;
|
|
2793
2938
|
}
|
|
2794
2939
|
}
|
|
@@ -2796,14 +2941,6 @@ var init_fastembed_provider = __esm({
|
|
|
2796
2941
|
}
|
|
2797
2942
|
return results;
|
|
2798
2943
|
}
|
|
2799
|
-
cacheSet(hash4, value) {
|
|
2800
|
-
if (cache.size >= MAX_CACHE_SIZE) {
|
|
2801
|
-
const firstKey = cache.keys().next().value;
|
|
2802
|
-
if (firstKey !== void 0) cache.delete(firstKey);
|
|
2803
|
-
}
|
|
2804
|
-
cache.set(hash4, value);
|
|
2805
|
-
diskCacheDirty = true;
|
|
2806
|
-
}
|
|
2807
2944
|
};
|
|
2808
2945
|
}
|
|
2809
2946
|
});
|
|
@@ -2813,7 +2950,15 @@ var transformers_provider_exports = {};
|
|
|
2813
2950
|
__export(transformers_provider_exports, {
|
|
2814
2951
|
TransformersProvider: () => TransformersProvider
|
|
2815
2952
|
});
|
|
2816
|
-
|
|
2953
|
+
import { createHash as createHash2 } from "crypto";
|
|
2954
|
+
function cacheKey2(text2) {
|
|
2955
|
+
return createHash2("sha256").update(text2).digest("hex");
|
|
2956
|
+
}
|
|
2957
|
+
function maxCachePayloadBytes2() {
|
|
2958
|
+
const raw = Number.parseInt(process.env.MEMORIX_EMBEDDING_CACHE_MAX_BYTES ?? "", 10);
|
|
2959
|
+
return Number.isFinite(raw) && raw > 0 ? raw : DEFAULT_CACHE_PAYLOAD_BYTES2;
|
|
2960
|
+
}
|
|
2961
|
+
var cache2, MAX_CACHE_SIZE2, DEFAULT_CACHE_PAYLOAD_BYTES2, cachePayloadBytes2, TransformersProvider;
|
|
2817
2962
|
var init_transformers_provider = __esm({
|
|
2818
2963
|
"src/embedding/transformers-provider.ts"() {
|
|
2819
2964
|
"use strict";
|
|
@@ -2821,6 +2966,8 @@ var init_transformers_provider = __esm({
|
|
|
2821
2966
|
init_provider();
|
|
2822
2967
|
cache2 = /* @__PURE__ */ new Map();
|
|
2823
2968
|
MAX_CACHE_SIZE2 = 5e3;
|
|
2969
|
+
DEFAULT_CACHE_PAYLOAD_BYTES2 = 64 * 1024 * 1024;
|
|
2970
|
+
cachePayloadBytes2 = 0;
|
|
2824
2971
|
TransformersProvider = class _TransformersProvider {
|
|
2825
2972
|
name = "transformers-minilm";
|
|
2826
2973
|
dimensions = 384;
|
|
@@ -2855,7 +3002,7 @@ var init_transformers_provider = __esm({
|
|
|
2855
3002
|
return Promise.all(inputs.map((input) => this.embedInput(input, options)));
|
|
2856
3003
|
}
|
|
2857
3004
|
async embed(text2) {
|
|
2858
|
-
const cached = cache2.get(text2);
|
|
3005
|
+
const cached = cache2.get(cacheKey2(text2));
|
|
2859
3006
|
if (cached) return cached;
|
|
2860
3007
|
const output = await this.extractor(text2, {
|
|
2861
3008
|
pooling: "mean",
|
|
@@ -2865,7 +3012,7 @@ var init_transformers_provider = __esm({
|
|
|
2865
3012
|
if (result.length !== this.dimensions) {
|
|
2866
3013
|
throw new Error(`Expected ${this.dimensions}d embedding, got ${result.length}d`);
|
|
2867
3014
|
}
|
|
2868
|
-
this.cacheSet(text2, result);
|
|
3015
|
+
this.cacheSet(cacheKey2(text2), result);
|
|
2869
3016
|
return result;
|
|
2870
3017
|
}
|
|
2871
3018
|
async embedBatch(texts) {
|
|
@@ -2873,7 +3020,7 @@ var init_transformers_provider = __esm({
|
|
|
2873
3020
|
const uncachedIndices = [];
|
|
2874
3021
|
const uncachedTexts = [];
|
|
2875
3022
|
for (let i2 = 0; i2 < texts.length; i2++) {
|
|
2876
|
-
const cached = cache2.get(texts[i2]);
|
|
3023
|
+
const cached = cache2.get(cacheKey2(texts[i2]));
|
|
2877
3024
|
if (cached) {
|
|
2878
3025
|
results[i2] = cached;
|
|
2879
3026
|
} else {
|
|
@@ -2891,17 +3038,27 @@ var init_transformers_provider = __esm({
|
|
|
2891
3038
|
const vec = Array.from(allVecs[i2]);
|
|
2892
3039
|
const originalIdx = uncachedIndices[i2];
|
|
2893
3040
|
results[originalIdx] = vec;
|
|
2894
|
-
this.cacheSet(uncachedTexts[i2], vec);
|
|
3041
|
+
this.cacheSet(cacheKey2(uncachedTexts[i2]), vec);
|
|
2895
3042
|
}
|
|
2896
3043
|
}
|
|
2897
3044
|
return results;
|
|
2898
3045
|
}
|
|
2899
3046
|
cacheSet(key, value) {
|
|
2900
|
-
|
|
2901
|
-
|
|
2902
|
-
|
|
3047
|
+
const incomingBytes = value.length * 8;
|
|
3048
|
+
if (incomingBytes > maxCachePayloadBytes2()) return;
|
|
3049
|
+
const existing = cache2.get(key);
|
|
3050
|
+
if (existing) cachePayloadBytes2 -= existing.length * 8;
|
|
3051
|
+
else {
|
|
3052
|
+
while (cache2.size >= MAX_CACHE_SIZE2 || cachePayloadBytes2 + incomingBytes > maxCachePayloadBytes2()) {
|
|
3053
|
+
const firstKey = cache2.keys().next().value;
|
|
3054
|
+
if (firstKey === void 0) break;
|
|
3055
|
+
const old = cache2.get(firstKey);
|
|
3056
|
+
cache2.delete(firstKey);
|
|
3057
|
+
if (old) cachePayloadBytes2 -= old.length * 8;
|
|
3058
|
+
}
|
|
2903
3059
|
}
|
|
2904
3060
|
cache2.set(key, value);
|
|
3061
|
+
cachePayloadBytes2 += incomingBytes;
|
|
2905
3062
|
}
|
|
2906
3063
|
};
|
|
2907
3064
|
}
|
|
@@ -2923,7 +3080,7 @@ __export(api_provider_exports, {
|
|
|
2923
3080
|
saveDiskCacheNow: () => saveDiskCacheNow,
|
|
2924
3081
|
seedApiEmbeddingCacheForTests: () => seedApiEmbeddingCacheForTests
|
|
2925
3082
|
});
|
|
2926
|
-
import { createHash as
|
|
3083
|
+
import { createHash as createHash3 } from "crypto";
|
|
2927
3084
|
import { createReadStream, createWriteStream, constants as fsConstants } from "fs";
|
|
2928
3085
|
import { access, readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2, rename, stat, unlink } from "fs/promises";
|
|
2929
3086
|
import { join as join3 } from "path";
|
|
@@ -2950,7 +3107,7 @@ function cacheStatFile() {
|
|
|
2950
3107
|
function payloadBytes(vector) {
|
|
2951
3108
|
return vector.length * BYTES_PER_DIM;
|
|
2952
3109
|
}
|
|
2953
|
-
function
|
|
3110
|
+
function maxCachePayloadBytes3() {
|
|
2954
3111
|
const raw = process.env.MEMORIX_EMBEDDING_CACHE_MAX_BYTES;
|
|
2955
3112
|
if (raw) {
|
|
2956
3113
|
const parsed = Number.parseInt(raw, 10);
|
|
@@ -2960,7 +3117,7 @@ function maxCachePayloadBytes() {
|
|
|
2960
3117
|
}
|
|
2961
3118
|
function maxEntriesForDimensions(dimensions) {
|
|
2962
3119
|
const dim = Math.max(1, Math.floor(dimensions));
|
|
2963
|
-
const byBytes = Math.floor(
|
|
3120
|
+
const byBytes = Math.floor(maxCachePayloadBytes3() / (dim * BYTES_PER_DIM));
|
|
2964
3121
|
return Math.max(1, Math.min(MAX_CACHE_ENTRIES, byBytes));
|
|
2965
3122
|
}
|
|
2966
3123
|
function rememberDimensions(vector) {
|
|
@@ -2973,13 +3130,15 @@ function evictOldest() {
|
|
|
2973
3130
|
if (firstKey === void 0) return;
|
|
2974
3131
|
const old = cache3.get(firstKey);
|
|
2975
3132
|
cache3.delete(firstKey);
|
|
2976
|
-
if (old)
|
|
3133
|
+
if (old) cachePayloadBytes3 -= payloadBytes(old);
|
|
2977
3134
|
}
|
|
2978
3135
|
function evictToFit(incomingBytes, incomingDims) {
|
|
3136
|
+
if (incomingBytes > maxCachePayloadBytes3()) return false;
|
|
2979
3137
|
const limit2 = maxEntriesForDimensions(incomingDims);
|
|
2980
|
-
while (cache3.size > 0 && (cache3.size >= limit2 ||
|
|
3138
|
+
while (cache3.size > 0 && (cache3.size >= limit2 || cachePayloadBytes3 + incomingBytes > maxCachePayloadBytes3())) {
|
|
2981
3139
|
evictOldest();
|
|
2982
3140
|
}
|
|
3141
|
+
return true;
|
|
2983
3142
|
}
|
|
2984
3143
|
function isNumberArray(value) {
|
|
2985
3144
|
return Array.isArray(value) && value.every((entry) => typeof entry === "number");
|
|
@@ -3006,12 +3165,12 @@ function cacheInsert(hash4, value, dirty) {
|
|
|
3006
3165
|
const incoming = payloadBytes(value);
|
|
3007
3166
|
const existing = cache3.get(hash4);
|
|
3008
3167
|
if (existing) {
|
|
3009
|
-
|
|
3168
|
+
cachePayloadBytes3 -= payloadBytes(existing);
|
|
3010
3169
|
cache3.delete(hash4);
|
|
3011
3170
|
}
|
|
3012
|
-
evictToFit(incoming, value.length || cacheDimensions || DEFAULT_ASSUMED_DIMENSIONS);
|
|
3171
|
+
if (!evictToFit(incoming, value.length || cacheDimensions || DEFAULT_ASSUMED_DIMENSIONS)) return;
|
|
3013
3172
|
cache3.set(hash4, value);
|
|
3014
|
-
|
|
3173
|
+
cachePayloadBytes3 += incoming;
|
|
3015
3174
|
if (dirty) diskCacheDirty2 = true;
|
|
3016
3175
|
}
|
|
3017
3176
|
async function readCacheStat() {
|
|
@@ -3047,7 +3206,7 @@ function cacheNamespace(config) {
|
|
|
3047
3206
|
].join("|");
|
|
3048
3207
|
}
|
|
3049
3208
|
function textHash2(text2, namespace) {
|
|
3050
|
-
return
|
|
3209
|
+
return createHash3("sha256").update(`${namespace}\0${text2}`).digest("hex").slice(0, 16);
|
|
3051
3210
|
}
|
|
3052
3211
|
function inputIdentity(input, options = {}) {
|
|
3053
3212
|
return JSON.stringify({
|
|
@@ -3389,7 +3548,7 @@ function getApiEmbeddingDiskCacheLoadCountForTests() {
|
|
|
3389
3548
|
}
|
|
3390
3549
|
function resetApiEmbeddingCacheForTests() {
|
|
3391
3550
|
cache3.clear();
|
|
3392
|
-
|
|
3551
|
+
cachePayloadBytes3 = 0;
|
|
3393
3552
|
cacheDimensions = null;
|
|
3394
3553
|
diskCacheEntryCount = 0;
|
|
3395
3554
|
diskCacheLoaded = false;
|
|
@@ -3400,14 +3559,14 @@ function resetApiEmbeddingCacheForTests() {
|
|
|
3400
3559
|
}
|
|
3401
3560
|
function seedApiEmbeddingCacheForTests(entries) {
|
|
3402
3561
|
cache3.clear();
|
|
3403
|
-
|
|
3562
|
+
cachePayloadBytes3 = 0;
|
|
3404
3563
|
cacheDimensions = null;
|
|
3405
3564
|
for (const [key, value] of entries) cacheInsert(key, value, true);
|
|
3406
3565
|
diskCacheLoaded = true;
|
|
3407
3566
|
diskCacheDirty2 = true;
|
|
3408
3567
|
}
|
|
3409
3568
|
function getApiEmbeddingCachePayloadBytesForTests() {
|
|
3410
|
-
return
|
|
3569
|
+
return cachePayloadBytes3;
|
|
3411
3570
|
}
|
|
3412
3571
|
function getApiEmbeddingJsonlLineCountCallsForTests() {
|
|
3413
3572
|
return jsonlLineCountCalls;
|
|
@@ -3581,7 +3740,7 @@ function scheduleDiskSave() {
|
|
|
3581
3740
|
diskSaveTimer = null;
|
|
3582
3741
|
}, DISK_SAVE_DEBOUNCE_MS);
|
|
3583
3742
|
}
|
|
3584
|
-
function
|
|
3743
|
+
function cacheSet2(hash4, value) {
|
|
3585
3744
|
cacheInsert(hash4, value, true);
|
|
3586
3745
|
}
|
|
3587
3746
|
function resolveEnvEmbeddingApiKey() {
|
|
@@ -3701,7 +3860,7 @@ async function waitForRetry(waitMs, signal) {
|
|
|
3701
3860
|
abortSignal.addEventListener("abort", onAbort, { once: true });
|
|
3702
3861
|
});
|
|
3703
3862
|
}
|
|
3704
|
-
var cache3, MAX_CACHE_ENTRIES, MAX_CACHE_PAYLOAD_BYTES, BYTES_PER_DIM, DEFAULT_ASSUMED_DIMENSIONS, MAX_MIGRATION_VALUE_BYTES,
|
|
3863
|
+
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;
|
|
3705
3864
|
var init_api_provider = __esm({
|
|
3706
3865
|
"src/embedding/api-provider.ts"() {
|
|
3707
3866
|
"use strict";
|
|
@@ -3713,7 +3872,7 @@ var init_api_provider = __esm({
|
|
|
3713
3872
|
BYTES_PER_DIM = 8;
|
|
3714
3873
|
DEFAULT_ASSUMED_DIMENSIONS = 4096;
|
|
3715
3874
|
MAX_MIGRATION_VALUE_BYTES = 16 * 1024 * 1024;
|
|
3716
|
-
|
|
3875
|
+
cachePayloadBytes3 = 0;
|
|
3717
3876
|
cacheDimensions = null;
|
|
3718
3877
|
diskCacheEntryCount = 0;
|
|
3719
3878
|
diskCacheDirty2 = false;
|
|
@@ -3898,7 +4057,7 @@ var init_api_provider = __esm({
|
|
|
3898
4057
|
} else {
|
|
3899
4058
|
embedding = await apiCall();
|
|
3900
4059
|
}
|
|
3901
|
-
|
|
4060
|
+
cacheSet2(hash4, embedding);
|
|
3902
4061
|
scheduleDiskSave();
|
|
3903
4062
|
return embedding;
|
|
3904
4063
|
}
|
|
@@ -3946,7 +4105,7 @@ var init_api_provider = __esm({
|
|
|
3946
4105
|
for (const item of response.data) {
|
|
3947
4106
|
const originalIdx = chunkIndices[item.index];
|
|
3948
4107
|
results[originalIdx] = item.embedding;
|
|
3949
|
-
|
|
4108
|
+
cacheSet2(textHash2(normalizedTexts[originalIdx], this.cacheKeyNamespace), item.embedding);
|
|
3950
4109
|
}
|
|
3951
4110
|
} catch (error) {
|
|
3952
4111
|
const providerLimit = parseBatchLimit(error);
|
|
@@ -4024,7 +4183,7 @@ var init_api_provider = __esm({
|
|
|
4024
4183
|
throw new Error(`Expected ${this.dimensions}d, got ${embedding.length}d; dimension mismatch`);
|
|
4025
4184
|
}
|
|
4026
4185
|
this.trackUsage(response);
|
|
4027
|
-
|
|
4186
|
+
cacheSet2(hash4, embedding);
|
|
4028
4187
|
scheduleDiskSave();
|
|
4029
4188
|
return embedding;
|
|
4030
4189
|
}
|
|
@@ -5407,6 +5566,7 @@ var init_provider2 = __esm({
|
|
|
5407
5566
|
openai: { baseUrl: "https://api.openai.com/v1", model: "gpt-4.1-nano" },
|
|
5408
5567
|
anthropic: { baseUrl: "https://api.anthropic.com/v1", model: "claude-3-5-haiku-latest" },
|
|
5409
5568
|
openrouter: { baseUrl: "https://openrouter.ai/api/v1", model: "openai/gpt-4.1-nano" },
|
|
5569
|
+
atlascloud: { baseUrl: "https://api.atlascloud.ai/v1", model: "deepseek-ai/deepseek-v3.2" },
|
|
5410
5570
|
custom: { baseUrl: "http://localhost:11434/v1", model: "llama3" }
|
|
5411
5571
|
};
|
|
5412
5572
|
currentConfig = null;
|
|
@@ -5670,6 +5830,7 @@ var init_sqlite_store = __esm({
|
|
|
5670
5830
|
init_sqlite_db();
|
|
5671
5831
|
init_sqlite_reliability();
|
|
5672
5832
|
init_sqlite_fts();
|
|
5833
|
+
init_file_lock();
|
|
5673
5834
|
SqliteBackend = class {
|
|
5674
5835
|
db = null;
|
|
5675
5836
|
dataDir = "";
|
|
@@ -5833,38 +5994,43 @@ var init_sqlite_store = __esm({
|
|
|
5833
5994
|
}
|
|
5834
5995
|
// ── Migration ────────────────────────────────────────────────────
|
|
5835
5996
|
async migrateFromJsonIfNeeded() {
|
|
5836
|
-
const count2 = this.db.prepare(`SELECT COUNT(*) AS cnt FROM observations`).get();
|
|
5837
|
-
if (count2.cnt > 0) return;
|
|
5838
5997
|
const jsonPath = path7.join(this.dataDir, "observations.json");
|
|
5839
5998
|
if (!fs4.existsSync(jsonPath)) return;
|
|
5840
|
-
|
|
5999
|
+
await withFileLock(this.dataDir, async () => {
|
|
6000
|
+
const count2 = this.db.prepare(`SELECT COUNT(*) AS cnt FROM observations`).get();
|
|
6001
|
+
if (count2.cnt > 0) return;
|
|
5841
6002
|
const raw = fs4.readFileSync(jsonPath, "utf-8");
|
|
5842
|
-
const
|
|
6003
|
+
const parsed = JSON.parse(raw);
|
|
6004
|
+
if (!Array.isArray(parsed)) {
|
|
6005
|
+
throw new Error("[memorix] observations.json migration refused: expected a JSON array");
|
|
6006
|
+
}
|
|
6007
|
+
const observations2 = parsed;
|
|
5843
6008
|
if (observations2.length === 0) return;
|
|
6009
|
+
if (observations2.some((obs) => !obs || !Number.isSafeInteger(obs.id) || obs.id < 1 || typeof obs.projectId !== "string")) {
|
|
6010
|
+
throw new Error("[memorix] observations.json migration refused: invalid observation record");
|
|
6011
|
+
}
|
|
5844
6012
|
console.error(`[memorix] Migrating ${observations2.length} observations from JSON to SQLite...`);
|
|
5845
6013
|
const insertMany = this.db.transaction((obsList) => {
|
|
5846
6014
|
for (const obs of obsList) {
|
|
5847
6015
|
this.stmtInsert.run(obsToRow(obs));
|
|
5848
6016
|
}
|
|
5849
|
-
|
|
5850
|
-
|
|
5851
|
-
|
|
5852
|
-
if (fs4.existsSync(counterPath)) {
|
|
5853
|
-
try {
|
|
6017
|
+
const counterPath = path7.join(this.dataDir, "counter.json");
|
|
6018
|
+
let counterNextId;
|
|
6019
|
+
if (fs4.existsSync(counterPath)) {
|
|
5854
6020
|
const counterData = JSON.parse(fs4.readFileSync(counterPath, "utf-8"));
|
|
5855
|
-
const
|
|
5856
|
-
|
|
5857
|
-
|
|
5858
|
-
|
|
6021
|
+
const candidate = counterData.nextId ?? counterData.next_id;
|
|
6022
|
+
if (candidate !== void 0 && (!Number.isSafeInteger(candidate) || Number(candidate) < 1)) {
|
|
6023
|
+
throw new Error("[memorix] counter.json migration refused: nextId must be a positive integer");
|
|
6024
|
+
}
|
|
6025
|
+
counterNextId = candidate === void 0 ? void 0 : Number(candidate);
|
|
5859
6026
|
}
|
|
5860
|
-
|
|
5861
|
-
this.rawSaveIdCounter(Math.max(
|
|
5862
|
-
|
|
5863
|
-
|
|
6027
|
+
const maxId = Math.max(...obsList.map((obs) => obs.id));
|
|
6028
|
+
this.rawSaveIdCounter(Math.max(counterNextId ?? 1, maxId + 1));
|
|
6029
|
+
this.bumpGeneration();
|
|
6030
|
+
});
|
|
6031
|
+
insertMany(observations2);
|
|
5864
6032
|
console.error(`[memorix] Migration complete. ${observations2.length} observations now in SQLite.`);
|
|
5865
|
-
}
|
|
5866
|
-
console.error(`[memorix] JSON\u2192SQLite migration failed (non-fatal, data preserved in JSON): ${err}`);
|
|
5867
|
-
}
|
|
6033
|
+
});
|
|
5868
6034
|
}
|
|
5869
6035
|
// ── Public read ──────────────────────────────────────────────────
|
|
5870
6036
|
async loadAll() {
|
|
@@ -6164,7 +6330,7 @@ var init_obs_store = __esm({
|
|
|
6164
6330
|
});
|
|
6165
6331
|
|
|
6166
6332
|
// src/search/semantic-index.ts
|
|
6167
|
-
import { createHash as
|
|
6333
|
+
import { createHash as createHash4 } from "crypto";
|
|
6168
6334
|
import { createRequire as createRequire3 } from "module";
|
|
6169
6335
|
import path8 from "path";
|
|
6170
6336
|
function createSemanticIndexProfile(provider2) {
|
|
@@ -6178,7 +6344,7 @@ function stateKey(dataDir, profile) {
|
|
|
6178
6344
|
return `${path8.resolve(dataDir)}::${profile.key}`;
|
|
6179
6345
|
}
|
|
6180
6346
|
function tableName(profile) {
|
|
6181
|
-
const digest2 =
|
|
6347
|
+
const digest2 = createHash4("sha256").update(profile.key).digest("hex").slice(0, 20);
|
|
6182
6348
|
return `${TABLE_PREFIX}${digest2}`;
|
|
6183
6349
|
}
|
|
6184
6350
|
function indexRoot(dataDir) {
|
|
@@ -8218,6 +8384,7 @@ var init_secret_filter = __esm({
|
|
|
8218
8384
|
// src/runtime/maintenance-jobs.ts
|
|
8219
8385
|
var maintenance_jobs_exports = {};
|
|
8220
8386
|
__export(maintenance_jobs_exports, {
|
|
8387
|
+
DEFAULT_FAILED_HISTORY_RETENTION_MS: () => DEFAULT_FAILED_HISTORY_RETENTION_MS,
|
|
8221
8388
|
MAINTENANCE_JOB_KINDS: () => MAINTENANCE_JOB_KINDS,
|
|
8222
8389
|
MaintenanceJobStore: () => MaintenanceJobStore,
|
|
8223
8390
|
MaintenanceJobWorker: () => MaintenanceJobWorker,
|
|
@@ -8267,7 +8434,7 @@ function normalizedKinds(kinds) {
|
|
|
8267
8434
|
function getMaintenanceRetryDelayMs(attempts) {
|
|
8268
8435
|
return Math.min(6e4, 1e3 * 2 ** Math.max(0, attempts - 1));
|
|
8269
8436
|
}
|
|
8270
|
-
var MAINTENANCE_JOB_KINDS, DEFAULT_MAX_ATTEMPTS, DEFAULT_LEASE_MS, DEFAULT_POLL_INTERVAL_MS, MAX_ERROR_LENGTH, DEFAULT_COMPLETED_HISTORY_RETENTION_MS, MaintenanceJobStore, MaintenanceJobWorker;
|
|
8437
|
+
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;
|
|
8271
8438
|
var init_maintenance_jobs = __esm({
|
|
8272
8439
|
"src/runtime/maintenance-jobs.ts"() {
|
|
8273
8440
|
"use strict";
|
|
@@ -8294,6 +8461,7 @@ var init_maintenance_jobs = __esm({
|
|
|
8294
8461
|
DEFAULT_POLL_INTERVAL_MS = 2e3;
|
|
8295
8462
|
MAX_ERROR_LENGTH = 1e3;
|
|
8296
8463
|
DEFAULT_COMPLETED_HISTORY_RETENTION_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
8464
|
+
DEFAULT_FAILED_HISTORY_RETENTION_MS = 30 * 24 * 60 * 60 * 1e3;
|
|
8297
8465
|
MaintenanceJobStore = class {
|
|
8298
8466
|
db;
|
|
8299
8467
|
constructor(dataDir) {
|
|
@@ -8420,18 +8588,21 @@ var init_maintenance_jobs = __esm({
|
|
|
8420
8588
|
}
|
|
8421
8589
|
/**
|
|
8422
8590
|
* Completed jobs are useful recent operator history, not permanent data.
|
|
8423
|
-
* Failed
|
|
8424
|
-
*
|
|
8591
|
+
* Failed diagnostics are retained longer, but are still bounded so a
|
|
8592
|
+
* permanently failing job kind cannot grow the database forever.
|
|
8425
8593
|
*/
|
|
8426
8594
|
pruneCompletedHistory(options = {}) {
|
|
8427
8595
|
const now3 = options.now ?? Date.now();
|
|
8428
8596
|
const maxAgeMs = Number.isFinite(options.maxAgeMs) ? Math.max(0, Math.floor(options.maxAgeMs)) : DEFAULT_COMPLETED_HISTORY_RETENTION_MS;
|
|
8597
|
+
const failedMaxAgeMs = Number.isFinite(options.failedMaxAgeMs) ? Math.max(0, Math.floor(options.failedMaxAgeMs)) : DEFAULT_FAILED_HISTORY_RETENTION_MS;
|
|
8429
8598
|
const result = this.db.prepare(`
|
|
8430
8599
|
DELETE FROM maintenance_jobs
|
|
8431
|
-
WHERE status = 'completed'
|
|
8600
|
+
WHERE (status = 'completed'
|
|
8432
8601
|
AND completed_at IS NOT NULL
|
|
8433
|
-
AND completed_at < ?
|
|
8434
|
-
|
|
8602
|
+
AND completed_at < ?)
|
|
8603
|
+
OR (status = 'failed'
|
|
8604
|
+
AND updated_at < ?)
|
|
8605
|
+
`).run(now3 - maxAgeMs, now3 - failedMaxAgeMs);
|
|
8435
8606
|
return Number(result.changes ?? 0);
|
|
8436
8607
|
}
|
|
8437
8608
|
claimNext(options) {
|
|
@@ -8757,7 +8928,7 @@ var init_lifecycle = __esm({
|
|
|
8757
8928
|
});
|
|
8758
8929
|
|
|
8759
8930
|
// src/store/evidence-store.ts
|
|
8760
|
-
import { createHash as
|
|
8931
|
+
import { createHash as createHash5, randomUUID as randomUUID3 } from "crypto";
|
|
8761
8932
|
function safeJson(value, fallback) {
|
|
8762
8933
|
if (typeof value !== "string" || value.length === 0) return fallback;
|
|
8763
8934
|
try {
|
|
@@ -8791,7 +8962,7 @@ function rowToCard(row) {
|
|
|
8791
8962
|
};
|
|
8792
8963
|
}
|
|
8793
8964
|
function observationHash(observation) {
|
|
8794
|
-
return
|
|
8965
|
+
return createHash5("sha256").update(JSON.stringify({
|
|
8795
8966
|
projectId: observation.projectId,
|
|
8796
8967
|
id: observation.id,
|
|
8797
8968
|
title: observation.title,
|
|
@@ -8977,9 +9148,9 @@ var init_evidence_store = __esm({
|
|
|
8977
9148
|
});
|
|
8978
9149
|
|
|
8979
9150
|
// src/codegraph/ids.ts
|
|
8980
|
-
import { createHash as
|
|
9151
|
+
import { createHash as createHash6 } from "crypto";
|
|
8981
9152
|
function digest(input) {
|
|
8982
|
-
return
|
|
9153
|
+
return createHash6("sha256").update(input).digest("hex").slice(0, 16);
|
|
8983
9154
|
}
|
|
8984
9155
|
function normalizeCodePath(path22) {
|
|
8985
9156
|
return path22.replace(/\\/g, "/").replace(/^\.\//, "").replace(/\/+/g, "/");
|
|
@@ -11549,13 +11720,13 @@ __export(workspace_exports, {
|
|
|
11549
11720
|
loadKnowledgeWorkspace: () => loadKnowledgeWorkspace,
|
|
11550
11721
|
resolveKnowledgeWorkspaceFile: () => resolveKnowledgeWorkspaceFile
|
|
11551
11722
|
});
|
|
11552
|
-
import { createHash as
|
|
11723
|
+
import { createHash as createHash7 } from "crypto";
|
|
11553
11724
|
import { execFile } from "child_process";
|
|
11554
11725
|
import { promises as fs6 } from "fs";
|
|
11555
11726
|
import path10 from "path";
|
|
11556
11727
|
import { promisify } from "util";
|
|
11557
11728
|
function hash(value) {
|
|
11558
|
-
return
|
|
11729
|
+
return createHash7("sha256").update(value).digest("hex");
|
|
11559
11730
|
}
|
|
11560
11731
|
function workspaceId(projectId, mode) {
|
|
11561
11732
|
return "workspace:" + hash(projectId + ":" + mode).slice(0, 24);
|
|
@@ -12690,14 +12861,14 @@ var init_types2 = __esm({
|
|
|
12690
12861
|
});
|
|
12691
12862
|
|
|
12692
12863
|
// src/media/asset-store.ts
|
|
12693
|
-
import { createHash as
|
|
12864
|
+
import { createHash as createHash8, randomUUID as randomUUID7 } from "crypto";
|
|
12694
12865
|
import { copyFile, lstat, mkdir as mkdir3, open, readFile as readFile3, readdir, rename as rename2, rm, stat as stat2, writeFile as writeFile3 } from "fs/promises";
|
|
12695
12866
|
import path11 from "path";
|
|
12696
12867
|
function mediaRoot(dataDir) {
|
|
12697
12868
|
return path11.resolve(dataDir, "media");
|
|
12698
12869
|
}
|
|
12699
12870
|
function projectStorageKey(projectId) {
|
|
12700
|
-
return
|
|
12871
|
+
return createHash8("sha256").update(projectId).digest("hex").slice(0, 16);
|
|
12701
12872
|
}
|
|
12702
12873
|
function validateUnderRoot(root, candidate) {
|
|
12703
12874
|
const resolved = path11.resolve(candidate);
|
|
@@ -12806,7 +12977,7 @@ async function importMediaBuffer(input) {
|
|
|
12806
12977
|
if (input.bytes.length === 0) throw new Error("Media import rejects empty payloads");
|
|
12807
12978
|
if (input.bytes.length > maxBytes) throw new Error(`Media payload is too large (${input.bytes.length} bytes; limit ${maxBytes})`);
|
|
12808
12979
|
const detected = detectMedia(input.bytes.subarray(0, 32));
|
|
12809
|
-
const sha256 =
|
|
12980
|
+
const sha256 = createHash8("sha256").update(input.bytes).digest("hex");
|
|
12810
12981
|
return importKnownMedia({
|
|
12811
12982
|
dataDir: input.dataDir,
|
|
12812
12983
|
projectId: input.projectId,
|
|
@@ -12824,7 +12995,7 @@ async function readMediaAsset(dataDir, asset, maxBytes = DEFAULT_MAX_MEDIA_BYTES
|
|
|
12824
12995
|
if (asset.byteSize > maxBytes) throw new Error(`Media asset exceeds read limit (${asset.byteSize} bytes; limit ${maxBytes})`);
|
|
12825
12996
|
const bytes = await readFile3(getMediaAssetPath(dataDir, asset));
|
|
12826
12997
|
if (bytes.length !== asset.byteSize) throw new Error(`Media asset size no longer matches metadata: ${asset.id}`);
|
|
12827
|
-
const sha256 =
|
|
12998
|
+
const sha256 = createHash8("sha256").update(bytes).digest("hex");
|
|
12828
12999
|
if (sha256 !== asset.sha256) throw new Error(`Media asset hash no longer matches metadata: ${asset.id}`);
|
|
12829
13000
|
return bytes;
|
|
12830
13001
|
}
|
|
@@ -71520,16 +71691,16 @@ var require_jwtaccess = __commonJS({
|
|
|
71520
71691
|
* @returns A string that returns the cached key.
|
|
71521
71692
|
*/
|
|
71522
71693
|
getCachedKey(url, scopes) {
|
|
71523
|
-
let
|
|
71694
|
+
let cacheKey3 = url;
|
|
71524
71695
|
if (scopes && Array.isArray(scopes) && scopes.length) {
|
|
71525
|
-
|
|
71696
|
+
cacheKey3 = url ? `${url}_${scopes.join("_")}` : `${scopes.join("_")}`;
|
|
71526
71697
|
} else if (typeof scopes === "string") {
|
|
71527
|
-
|
|
71698
|
+
cacheKey3 = url ? `${url}_${scopes}` : scopes;
|
|
71528
71699
|
}
|
|
71529
|
-
if (!
|
|
71700
|
+
if (!cacheKey3) {
|
|
71530
71701
|
throw Error("Scopes or url must be provided");
|
|
71531
71702
|
}
|
|
71532
|
-
return
|
|
71703
|
+
return cacheKey3;
|
|
71533
71704
|
}
|
|
71534
71705
|
/**
|
|
71535
71706
|
* Get a non-expired access token, after refreshing if necessary.
|
|
@@ -78075,7 +78246,7 @@ var require_websocket = __commonJS({
|
|
|
78075
78246
|
var http3 = __require("http");
|
|
78076
78247
|
var net = __require("net");
|
|
78077
78248
|
var tls = __require("tls");
|
|
78078
|
-
var { randomBytes, createHash:
|
|
78249
|
+
var { randomBytes, createHash: createHash17 } = __require("crypto");
|
|
78079
78250
|
var { Duplex, Readable: Readable2 } = __require("stream");
|
|
78080
78251
|
var { URL: URL2 } = __require("url");
|
|
78081
78252
|
var PerMessageDeflate2 = require_permessage_deflate();
|
|
@@ -78743,7 +78914,7 @@ var require_websocket = __commonJS({
|
|
|
78743
78914
|
abortHandshake(websocket, socket, "Invalid Upgrade header");
|
|
78744
78915
|
return;
|
|
78745
78916
|
}
|
|
78746
|
-
const digest2 =
|
|
78917
|
+
const digest2 = createHash17("sha1").update(key + GUID).digest("base64");
|
|
78747
78918
|
if (res.headers["sec-websocket-accept"] !== digest2) {
|
|
78748
78919
|
abortHandshake(websocket, socket, "Invalid Sec-WebSocket-Accept header");
|
|
78749
78920
|
return;
|
|
@@ -79115,7 +79286,7 @@ var require_websocket_server = __commonJS({
|
|
|
79115
79286
|
var EventEmitter = __require("events");
|
|
79116
79287
|
var http3 = __require("http");
|
|
79117
79288
|
var { Duplex } = __require("stream");
|
|
79118
|
-
var { createHash:
|
|
79289
|
+
var { createHash: createHash17 } = __require("crypto");
|
|
79119
79290
|
var extension3 = require_extension();
|
|
79120
79291
|
var PerMessageDeflate2 = require_permessage_deflate();
|
|
79121
79292
|
var subprotocol2 = require_subprotocol();
|
|
@@ -79422,7 +79593,7 @@ var require_websocket_server = __commonJS({
|
|
|
79422
79593
|
);
|
|
79423
79594
|
}
|
|
79424
79595
|
if (this._state > RUNNING) return abortHandshake(socket, 503);
|
|
79425
|
-
const digest2 =
|
|
79596
|
+
const digest2 = createHash17("sha1").update(key + GUID).digest("base64");
|
|
79426
79597
|
const headers = [
|
|
79427
79598
|
"HTTP/1.1 101 Switching Protocols",
|
|
79428
79599
|
"Upgrade: websocket",
|
|
@@ -148002,7 +148173,7 @@ var init_long_term = __esm({
|
|
|
148002
148173
|
|
|
148003
148174
|
// src/codegraph/code-state.ts
|
|
148004
148175
|
import { execFile as execFile2 } from "child_process";
|
|
148005
|
-
import { createHash as
|
|
148176
|
+
import { createHash as createHash9 } from "crypto";
|
|
148006
148177
|
import { promisify as promisify3 } from "util";
|
|
148007
148178
|
async function runGit(rootPath, args) {
|
|
148008
148179
|
try {
|
|
@@ -148031,7 +148202,7 @@ function changedPathCount(status) {
|
|
|
148031
148202
|
return count2;
|
|
148032
148203
|
}
|
|
148033
148204
|
function fingerprint(baseRevision, status) {
|
|
148034
|
-
return
|
|
148205
|
+
return createHash9("sha256").update(baseRevision ?? "").update("\0").update(status).digest("hex");
|
|
148035
148206
|
}
|
|
148036
148207
|
async function collectCodeStateSnapshot(input) {
|
|
148037
148208
|
const [revision, status] = await Promise.all([
|
|
@@ -148125,12 +148296,12 @@ var init_exclude3 = __esm({
|
|
|
148125
148296
|
});
|
|
148126
148297
|
|
|
148127
148298
|
// src/codegraph/semantic-provider.ts
|
|
148128
|
-
import { createHash as
|
|
148299
|
+
import { createHash as createHash10 } from "crypto";
|
|
148129
148300
|
import "fs";
|
|
148130
148301
|
import { resolve } from "path";
|
|
148131
148302
|
import ts from "typescript";
|
|
148132
148303
|
function hashText(value) {
|
|
148133
|
-
return
|
|
148304
|
+
return createHash10("sha256").update(value).digest("hex");
|
|
148134
148305
|
}
|
|
148135
148306
|
function canonicalPath(value) {
|
|
148136
148307
|
const normalized = resolve(value).replace(/\\/g, "/");
|
|
@@ -148475,11 +148646,11 @@ __export(lite_provider_exports, {
|
|
|
148475
148646
|
indexProjectLite: () => indexProjectLite,
|
|
148476
148647
|
refreshProjectLite: () => refreshProjectLite
|
|
148477
148648
|
});
|
|
148478
|
-
import { createHash as
|
|
148649
|
+
import { createHash as createHash11 } from "crypto";
|
|
148479
148650
|
import { existsSync as existsSync11, readdirSync as readdirSync2, readFileSync as readFileSync8, statSync as statSync3 } from "fs";
|
|
148480
148651
|
import { join as join4, relative as relative2 } from "path";
|
|
148481
148652
|
function hashText2(text2) {
|
|
148482
|
-
return
|
|
148653
|
+
return createHash11("sha256").update(text2).digest("hex");
|
|
148483
148654
|
}
|
|
148484
148655
|
function extension2(path22) {
|
|
148485
148656
|
const index = path22.lastIndexOf(".");
|
|
@@ -148955,7 +149126,7 @@ var claim_store_exports = {};
|
|
|
148955
149126
|
__export(claim_store_exports, {
|
|
148956
149127
|
ClaimStore: () => ClaimStore
|
|
148957
149128
|
});
|
|
148958
|
-
import { createHash as
|
|
149129
|
+
import { createHash as createHash12, randomUUID as randomUUID12 } from "crypto";
|
|
148959
149130
|
function optionalText3(value) {
|
|
148960
149131
|
return typeof value === "string" && value ? value : void 0;
|
|
148961
149132
|
}
|
|
@@ -149008,7 +149179,7 @@ function rowToEvent3(row) {
|
|
|
149008
149179
|
};
|
|
149009
149180
|
}
|
|
149010
149181
|
function evidenceKey(input) {
|
|
149011
|
-
return
|
|
149182
|
+
return createHash12("sha256").update(JSON.stringify([
|
|
149012
149183
|
input.evidenceKind,
|
|
149013
149184
|
input.evidenceId,
|
|
149014
149185
|
input.relation,
|
|
@@ -149206,7 +149377,7 @@ __export(claims_exports, {
|
|
|
149206
149377
|
supersedeClaim: () => supersedeClaim,
|
|
149207
149378
|
writeClaim: () => writeClaim
|
|
149208
149379
|
});
|
|
149209
|
-
import { createHash as
|
|
149380
|
+
import { createHash as createHash13, randomUUID as randomUUID13 } from "crypto";
|
|
149210
149381
|
function compactText2(value, field) {
|
|
149211
149382
|
if (typeof value !== "string") throw new Error("Claim " + field + " must be text");
|
|
149212
149383
|
const sanitized = sanitizeCredentials(value).trim().replace(/\s+/g, " ");
|
|
@@ -149218,7 +149389,7 @@ function normalizedTerm(value) {
|
|
|
149218
149389
|
return compactText2(value, "identity").toLocaleLowerCase("en-US");
|
|
149219
149390
|
}
|
|
149220
149391
|
function hashIdentity(parts) {
|
|
149221
|
-
return
|
|
149392
|
+
return createHash13("sha256").update(parts.join(String.fromCharCode(31))).digest("hex");
|
|
149222
149393
|
}
|
|
149223
149394
|
function buildClaimIdentity(input) {
|
|
149224
149395
|
const subject = normalizedTerm(input.subject);
|
|
@@ -149459,7 +149630,7 @@ function supersedeClaim(store, input) {
|
|
|
149459
149630
|
});
|
|
149460
149631
|
}
|
|
149461
149632
|
function hashObservation(observation) {
|
|
149462
|
-
return
|
|
149633
|
+
return createHash13("sha256").update(JSON.stringify([
|
|
149463
149634
|
observation.title,
|
|
149464
149635
|
observation.narrative,
|
|
149465
149636
|
observation.facts,
|
|
@@ -149703,11 +149874,11 @@ var init_frontmatter = __esm({
|
|
|
149703
149874
|
});
|
|
149704
149875
|
|
|
149705
149876
|
// src/knowledge/markdown.ts
|
|
149706
|
-
import { createHash as
|
|
149877
|
+
import { createHash as createHash14 } from "crypto";
|
|
149707
149878
|
import { promises as fs10 } from "fs";
|
|
149708
149879
|
import path18 from "path";
|
|
149709
149880
|
function hashContent(content) {
|
|
149710
|
-
return
|
|
149881
|
+
return createHash14("sha256").update(content).digest("hex");
|
|
149711
149882
|
}
|
|
149712
149883
|
function stringField(data, key) {
|
|
149713
149884
|
const value = data[key];
|
|
@@ -149833,11 +150004,11 @@ __export(wiki_exports, {
|
|
|
149833
150004
|
lintKnowledgeWorkspace: () => lintKnowledgeWorkspace,
|
|
149834
150005
|
readKnowledgePage: () => readKnowledgePage
|
|
149835
150006
|
});
|
|
149836
|
-
import { createHash as
|
|
150007
|
+
import { createHash as createHash15 } from "crypto";
|
|
149837
150008
|
import { promises as fs11 } from "fs";
|
|
149838
150009
|
import path19 from "path";
|
|
149839
150010
|
function hash2(value) {
|
|
149840
|
-
return
|
|
150011
|
+
return createHash15("sha256").update(value).digest("hex");
|
|
149841
150012
|
}
|
|
149842
150013
|
function now() {
|
|
149843
150014
|
return (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -150694,11 +150865,11 @@ __export(workflows_exports, {
|
|
|
150694
150865
|
syncCanonicalWorkflows: () => syncCanonicalWorkflows,
|
|
150695
150866
|
writeCanonicalWorkflow: () => writeCanonicalWorkflow
|
|
150696
150867
|
});
|
|
150697
|
-
import { createHash as
|
|
150868
|
+
import { createHash as createHash16 } from "crypto";
|
|
150698
150869
|
import { promises as fs12 } from "fs";
|
|
150699
150870
|
import path20 from "path";
|
|
150700
150871
|
function hash3(value) {
|
|
150701
|
-
return
|
|
150872
|
+
return createHash16("sha256").update(value).digest("hex");
|
|
150702
150873
|
}
|
|
150703
150874
|
function now2() {
|
|
150704
150875
|
return (/* @__PURE__ */ new Date()).toISOString();
|