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) {
|
|
@@ -542,11 +547,21 @@ function applySchemaMigrations(db2) {
|
|
|
542
547
|
apply();
|
|
543
548
|
}
|
|
544
549
|
}
|
|
550
|
+
function normalizeDataDir(dataDir) {
|
|
551
|
+
return path3.resolve(dataDir);
|
|
552
|
+
}
|
|
553
|
+
function touchDatabase(normalized, db2) {
|
|
554
|
+
_dbCache.delete(normalized);
|
|
555
|
+
_dbCache.set(normalized, db2);
|
|
556
|
+
}
|
|
545
557
|
function getDatabase(dataDir) {
|
|
546
|
-
const normalized =
|
|
558
|
+
const normalized = normalizeDataDir(dataDir);
|
|
547
559
|
assertNotHomeDataDir(normalized);
|
|
548
560
|
const existing = _dbCache.get(normalized);
|
|
549
|
-
if (existing)
|
|
561
|
+
if (existing) {
|
|
562
|
+
touchDatabase(normalized, existing);
|
|
563
|
+
return existing;
|
|
564
|
+
}
|
|
550
565
|
loadBetterSqlite3();
|
|
551
566
|
fs.mkdirSync(dataDir, { recursive: true });
|
|
552
567
|
const dbPath = path3.join(dataDir, "memorix.db");
|
|
@@ -576,6 +591,8 @@ function getDatabase(dataDir) {
|
|
|
576
591
|
db2.exec(CREATE_MAINTENANCE_JOBS_TABLE);
|
|
577
592
|
db2.exec(CREATE_MAINTENANCE_TARGETS_TABLE);
|
|
578
593
|
db2.exec(CREATE_COMPACTION_CHECKPOINTS_TABLE);
|
|
594
|
+
db2.exec(CREATE_TASK_CONTINUITY_EVENTS_TABLE);
|
|
595
|
+
db2.exec(CREATE_AGENT_EFFECTS_TABLE);
|
|
579
596
|
try {
|
|
580
597
|
db2.exec(`ALTER TABLE mini_skills ADD COLUMN sourceSnapshot TEXT NOT NULL DEFAULT ''`);
|
|
581
598
|
} catch {
|
|
@@ -614,7 +631,7 @@ function getDatabase(dataDir) {
|
|
|
614
631
|
db2.prepare(`INSERT OR IGNORE INTO meta (key, value) VALUES ('storage_generation', '0')`).run();
|
|
615
632
|
db2.prepare(`INSERT OR IGNORE INTO meta (key, value) VALUES ('next_id', '1')`).run();
|
|
616
633
|
db2.prepare(`INSERT OR IGNORE INTO meta (key, value) VALUES ('mini_skills_generation', '0')`).run();
|
|
617
|
-
|
|
634
|
+
touchDatabase(normalized, db2);
|
|
618
635
|
return db2;
|
|
619
636
|
} catch (error) {
|
|
620
637
|
try {
|
|
@@ -632,8 +649,9 @@ function closeAllDatabases() {
|
|
|
632
649
|
}
|
|
633
650
|
_dbCache.delete(key);
|
|
634
651
|
}
|
|
652
|
+
_dbLeases.clear();
|
|
635
653
|
}
|
|
636
|
-
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;
|
|
654
|
+
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;
|
|
637
655
|
var init_sqlite_db = __esm({
|
|
638
656
|
"src/store/sqlite-db.ts"() {
|
|
639
657
|
"use strict";
|
|
@@ -805,18 +823,21 @@ CREATE TABLE IF NOT EXISTS chat_transcript (
|
|
|
805
823
|
`;
|
|
806
824
|
CREATE_GRAPH_ENTITIES_TABLE = `
|
|
807
825
|
CREATE TABLE IF NOT EXISTS graph_entities (
|
|
808
|
-
|
|
826
|
+
projectId TEXT NOT NULL,
|
|
827
|
+
name TEXT NOT NULL,
|
|
809
828
|
entityType TEXT NOT NULL DEFAULT '',
|
|
810
|
-
observations TEXT NOT NULL DEFAULT '[]'
|
|
829
|
+
observations TEXT NOT NULL DEFAULT '[]',
|
|
830
|
+
PRIMARY KEY (projectId, name)
|
|
811
831
|
);
|
|
812
832
|
`;
|
|
813
833
|
CREATE_GRAPH_RELATIONS_TABLE = `
|
|
814
834
|
CREATE TABLE IF NOT EXISTS graph_relations (
|
|
815
835
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
836
|
+
projectId TEXT NOT NULL,
|
|
816
837
|
from_entity TEXT NOT NULL,
|
|
817
838
|
to_entity TEXT NOT NULL,
|
|
818
839
|
relationType TEXT NOT NULL DEFAULT '',
|
|
819
|
-
UNIQUE(from_entity, to_entity, relationType)
|
|
840
|
+
UNIQUE(projectId, from_entity, to_entity, relationType)
|
|
820
841
|
);
|
|
821
842
|
`;
|
|
822
843
|
CREATE_CODE_FILES_TABLE = `
|
|
@@ -1347,6 +1368,43 @@ CREATE TABLE IF NOT EXISTS memory_feedback_events (
|
|
|
1347
1368
|
delta REAL NOT NULL DEFAULT 0,
|
|
1348
1369
|
observed_at TEXT NOT NULL
|
|
1349
1370
|
);
|
|
1371
|
+
`;
|
|
1372
|
+
CREATE_TASK_CONTINUITY_EVENTS_TABLE = `
|
|
1373
|
+
CREATE TABLE IF NOT EXISTS task_continuity_events (
|
|
1374
|
+
id TEXT PRIMARY KEY,
|
|
1375
|
+
project_id TEXT NOT NULL,
|
|
1376
|
+
task_id TEXT NOT NULL,
|
|
1377
|
+
task TEXT NOT NULL,
|
|
1378
|
+
kind TEXT NOT NULL,
|
|
1379
|
+
content TEXT NOT NULL,
|
|
1380
|
+
item_status TEXT,
|
|
1381
|
+
source_ref TEXT,
|
|
1382
|
+
evidence_json TEXT NOT NULL DEFAULT '[]',
|
|
1383
|
+
actor TEXT,
|
|
1384
|
+
created_at TEXT NOT NULL,
|
|
1385
|
+
event_key TEXT,
|
|
1386
|
+
item_key TEXT,
|
|
1387
|
+
supersedes_id TEXT
|
|
1388
|
+
);
|
|
1389
|
+
`;
|
|
1390
|
+
CREATE_AGENT_EFFECTS_TABLE = `
|
|
1391
|
+
CREATE TABLE IF NOT EXISTS agent_effects (
|
|
1392
|
+
id TEXT PRIMARY KEY,
|
|
1393
|
+
pipeline_id TEXT NOT NULL,
|
|
1394
|
+
task_id TEXT NOT NULL,
|
|
1395
|
+
attempt INTEGER NOT NULL,
|
|
1396
|
+
effect_key TEXT NOT NULL,
|
|
1397
|
+
tool TEXT NOT NULL,
|
|
1398
|
+
risk_tier TEXT NOT NULL,
|
|
1399
|
+
replay_policy TEXT NOT NULL,
|
|
1400
|
+
status TEXT NOT NULL,
|
|
1401
|
+
call_id TEXT,
|
|
1402
|
+
idempotency_key TEXT NOT NULL,
|
|
1403
|
+
input_fingerprint TEXT,
|
|
1404
|
+
detail TEXT,
|
|
1405
|
+
started_at INTEGER NOT NULL,
|
|
1406
|
+
finished_at INTEGER
|
|
1407
|
+
);
|
|
1350
1408
|
`;
|
|
1351
1409
|
CREATE_MCP_BINDINGS_TABLE = `
|
|
1352
1410
|
CREATE TABLE IF NOT EXISTS mcp_bindings (
|
|
@@ -1425,7 +1483,18 @@ CREATE INDEX IF NOT EXISTS idx_evidence_cards_candidate ON evidence_cards(projec
|
|
|
1425
1483
|
CREATE INDEX IF NOT EXISTS idx_evidence_card_events_card ON evidence_card_events(card_id, created_at);
|
|
1426
1484
|
CREATE INDEX IF NOT EXISTS idx_memory_feedback_states_project ON memory_feedback_states(project_id, candidate_kind, updated_at DESC);
|
|
1427
1485
|
CREATE INDEX IF NOT EXISTS idx_memory_feedback_events_candidate ON memory_feedback_events(project_id, candidate_kind, candidate_id, observed_at DESC);
|
|
1486
|
+
CREATE INDEX IF NOT EXISTS idx_task_continuity_project_task ON task_continuity_events(project_id, task_id, created_at ASC);
|
|
1487
|
+
CREATE INDEX IF NOT EXISTS idx_task_continuity_project_recent ON task_continuity_events(project_id, created_at DESC);
|
|
1488
|
+
CREATE INDEX IF NOT EXISTS idx_task_continuity_item ON task_continuity_events(project_id, task_id, kind, item_key, created_at DESC);
|
|
1489
|
+
CREATE UNIQUE INDEX IF NOT EXISTS idx_task_continuity_event_key
|
|
1490
|
+
ON task_continuity_events(project_id, task_id, event_key)
|
|
1491
|
+
WHERE event_key IS NOT NULL;
|
|
1492
|
+
CREATE UNIQUE INDEX IF NOT EXISTS idx_agent_effect_identity
|
|
1493
|
+
ON agent_effects(pipeline_id, task_id, attempt, effect_key);
|
|
1494
|
+
CREATE INDEX IF NOT EXISTS idx_agent_effect_pipeline ON agent_effects(pipeline_id, started_at ASC);
|
|
1428
1495
|
CREATE INDEX IF NOT EXISTS idx_mcp_bindings_project ON mcp_bindings(project_id, last_used_at DESC);
|
|
1496
|
+
CREATE INDEX IF NOT EXISTS idx_mcp_bindings_root ON mcp_bindings(project_root, last_used_at DESC);
|
|
1497
|
+
CREATE INDEX IF NOT EXISTS idx_mcp_bindings_expiry ON mcp_bindings(expires_at);
|
|
1429
1498
|
CREATE UNIQUE INDEX IF NOT EXISTS idx_maintenance_jobs_active_dedupe
|
|
1430
1499
|
ON maintenance_jobs(project_id, kind, dedupe_key)
|
|
1431
1500
|
WHERE status IN ('pending', 'running', 'retry');
|
|
@@ -1596,6 +1665,8 @@ CREATE UNIQUE INDEX IF NOT EXISTS idx_maintenance_jobs_active_dedupe
|
|
|
1596
1665
|
db2.exec("CREATE INDEX IF NOT EXISTS idx_memory_feedback_states_project ON memory_feedback_states(project_id, candidate_kind, updated_at DESC)");
|
|
1597
1666
|
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)");
|
|
1598
1667
|
db2.exec("CREATE INDEX IF NOT EXISTS idx_mcp_bindings_project ON mcp_bindings(project_id, last_used_at DESC)");
|
|
1668
|
+
db2.exec("CREATE INDEX IF NOT EXISTS idx_mcp_bindings_root ON mcp_bindings(project_root, last_used_at DESC)");
|
|
1669
|
+
db2.exec("CREATE INDEX IF NOT EXISTS idx_mcp_bindings_expiry ON mcp_bindings(expires_at)");
|
|
1599
1670
|
}
|
|
1600
1671
|
},
|
|
1601
1672
|
{
|
|
@@ -1606,9 +1677,22 @@ CREATE UNIQUE INDEX IF NOT EXISTS idx_maintenance_jobs_active_dedupe
|
|
|
1606
1677
|
addColumnIfMissing(db2, "code_symbols", "source", "source TEXT");
|
|
1607
1678
|
addColumnIfMissing(db2, "code_edges", "source", "source TEXT");
|
|
1608
1679
|
}
|
|
1680
|
+
},
|
|
1681
|
+
{
|
|
1682
|
+
id: "1.9-continuity-v2",
|
|
1683
|
+
apply: (db2) => {
|
|
1684
|
+
addColumnIfMissing(db2, "task_continuity_events", "event_key", "event_key TEXT");
|
|
1685
|
+
addColumnIfMissing(db2, "task_continuity_events", "item_key", "item_key TEXT");
|
|
1686
|
+
addColumnIfMissing(db2, "task_continuity_events", "supersedes_id", "supersedes_id TEXT");
|
|
1687
|
+
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)");
|
|
1688
|
+
db2.exec(`CREATE UNIQUE INDEX IF NOT EXISTS idx_task_continuity_event_key
|
|
1689
|
+
ON task_continuity_events(project_id, task_id, event_key)
|
|
1690
|
+
WHERE event_key IS NOT NULL`);
|
|
1691
|
+
}
|
|
1609
1692
|
}
|
|
1610
1693
|
];
|
|
1611
1694
|
_dbCache = /* @__PURE__ */ new Map();
|
|
1695
|
+
_dbLeases = /* @__PURE__ */ new Map();
|
|
1612
1696
|
}
|
|
1613
1697
|
});
|
|
1614
1698
|
|
|
@@ -2124,6 +2208,7 @@ var init_media_store = __esm({
|
|
|
2124
2208
|
// src/runtime/maintenance-jobs.ts
|
|
2125
2209
|
var maintenance_jobs_exports = {};
|
|
2126
2210
|
__export(maintenance_jobs_exports, {
|
|
2211
|
+
DEFAULT_FAILED_HISTORY_RETENTION_MS: () => DEFAULT_FAILED_HISTORY_RETENTION_MS,
|
|
2127
2212
|
MAINTENANCE_JOB_KINDS: () => MAINTENANCE_JOB_KINDS,
|
|
2128
2213
|
MaintenanceJobStore: () => MaintenanceJobStore,
|
|
2129
2214
|
MaintenanceJobWorker: () => MaintenanceJobWorker,
|
|
@@ -2173,7 +2258,7 @@ function normalizedKinds(kinds) {
|
|
|
2173
2258
|
function getMaintenanceRetryDelayMs(attempts) {
|
|
2174
2259
|
return Math.min(6e4, 1e3 * 2 ** Math.max(0, attempts - 1));
|
|
2175
2260
|
}
|
|
2176
|
-
var MAINTENANCE_JOB_KINDS, DEFAULT_MAX_ATTEMPTS, DEFAULT_LEASE_MS, DEFAULT_POLL_INTERVAL_MS, MAX_ERROR_LENGTH, DEFAULT_COMPLETED_HISTORY_RETENTION_MS, MaintenanceJobStore, MaintenanceJobWorker;
|
|
2261
|
+
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;
|
|
2177
2262
|
var init_maintenance_jobs = __esm({
|
|
2178
2263
|
"src/runtime/maintenance-jobs.ts"() {
|
|
2179
2264
|
"use strict";
|
|
@@ -2200,6 +2285,7 @@ var init_maintenance_jobs = __esm({
|
|
|
2200
2285
|
DEFAULT_POLL_INTERVAL_MS = 2e3;
|
|
2201
2286
|
MAX_ERROR_LENGTH = 1e3;
|
|
2202
2287
|
DEFAULT_COMPLETED_HISTORY_RETENTION_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
2288
|
+
DEFAULT_FAILED_HISTORY_RETENTION_MS = 30 * 24 * 60 * 60 * 1e3;
|
|
2203
2289
|
MaintenanceJobStore = class {
|
|
2204
2290
|
db;
|
|
2205
2291
|
constructor(dataDir) {
|
|
@@ -2326,18 +2412,21 @@ var init_maintenance_jobs = __esm({
|
|
|
2326
2412
|
}
|
|
2327
2413
|
/**
|
|
2328
2414
|
* Completed jobs are useful recent operator history, not permanent data.
|
|
2329
|
-
* Failed
|
|
2330
|
-
*
|
|
2415
|
+
* Failed diagnostics are retained longer, but are still bounded so a
|
|
2416
|
+
* permanently failing job kind cannot grow the database forever.
|
|
2331
2417
|
*/
|
|
2332
2418
|
pruneCompletedHistory(options = {}) {
|
|
2333
2419
|
const now3 = options.now ?? Date.now();
|
|
2334
2420
|
const maxAgeMs = Number.isFinite(options.maxAgeMs) ? Math.max(0, Math.floor(options.maxAgeMs)) : DEFAULT_COMPLETED_HISTORY_RETENTION_MS;
|
|
2421
|
+
const failedMaxAgeMs = Number.isFinite(options.failedMaxAgeMs) ? Math.max(0, Math.floor(options.failedMaxAgeMs)) : DEFAULT_FAILED_HISTORY_RETENTION_MS;
|
|
2335
2422
|
const result = this.db.prepare(`
|
|
2336
2423
|
DELETE FROM maintenance_jobs
|
|
2337
|
-
WHERE status = 'completed'
|
|
2424
|
+
WHERE (status = 'completed'
|
|
2338
2425
|
AND completed_at IS NOT NULL
|
|
2339
|
-
AND completed_at < ?
|
|
2340
|
-
|
|
2426
|
+
AND completed_at < ?)
|
|
2427
|
+
OR (status = 'failed'
|
|
2428
|
+
AND updated_at < ?)
|
|
2429
|
+
`).run(now3 - maxAgeMs, now3 - failedMaxAgeMs);
|
|
2341
2430
|
return Number(result.changes ?? 0);
|
|
2342
2431
|
}
|
|
2343
2432
|
claimNext(options) {
|
|
@@ -2697,6 +2786,21 @@ var init_sqlite_reliability = __esm({
|
|
|
2697
2786
|
import { promises as fs2 } from "fs";
|
|
2698
2787
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
2699
2788
|
import path4 from "path";
|
|
2789
|
+
function canReclaimStaleLock(raw) {
|
|
2790
|
+
try {
|
|
2791
|
+
const parsed = JSON.parse(raw);
|
|
2792
|
+
const pid = Number(parsed.pid);
|
|
2793
|
+
if (!Number.isSafeInteger(pid) || pid < 1) return true;
|
|
2794
|
+
try {
|
|
2795
|
+
process.kill(pid, 0);
|
|
2796
|
+
return false;
|
|
2797
|
+
} catch (error) {
|
|
2798
|
+
return error.code !== "EPERM";
|
|
2799
|
+
}
|
|
2800
|
+
} catch {
|
|
2801
|
+
return true;
|
|
2802
|
+
}
|
|
2803
|
+
}
|
|
2700
2804
|
async function acquireLock(lockPath) {
|
|
2701
2805
|
for (let i2 = 0; i2 < MAX_RETRIES; i2++) {
|
|
2702
2806
|
try {
|
|
@@ -2710,9 +2814,12 @@ async function acquireLock(lockPath) {
|
|
|
2710
2814
|
try {
|
|
2711
2815
|
const stat5 = await fs2.stat(lockPath);
|
|
2712
2816
|
if (Date.now() - stat5.mtimeMs > LOCK_STALE_MS) {
|
|
2713
|
-
await fs2.
|
|
2714
|
-
|
|
2715
|
-
|
|
2817
|
+
const raw2 = await fs2.readFile(lockPath, "utf8").catch(() => "");
|
|
2818
|
+
if (canReclaimStaleLock(raw2)) {
|
|
2819
|
+
await fs2.unlink(lockPath).catch(() => {
|
|
2820
|
+
});
|
|
2821
|
+
continue;
|
|
2822
|
+
}
|
|
2716
2823
|
}
|
|
2717
2824
|
} catch {
|
|
2718
2825
|
continue;
|
|
@@ -2723,6 +2830,10 @@ async function acquireLock(lockPath) {
|
|
|
2723
2830
|
}
|
|
2724
2831
|
}
|
|
2725
2832
|
}
|
|
2833
|
+
const raw = await fs2.readFile(lockPath, "utf8").catch(() => "");
|
|
2834
|
+
if (!canReclaimStaleLock(raw)) {
|
|
2835
|
+
throw new Error(`Failed to acquire lock: ${lockPath} (owner is still running)`);
|
|
2836
|
+
}
|
|
2726
2837
|
await fs2.unlink(lockPath).catch(() => {
|
|
2727
2838
|
});
|
|
2728
2839
|
try {
|
|
@@ -3089,9 +3200,9 @@ var init_detector = __esm({
|
|
|
3089
3200
|
// src/config/legacy-loader.ts
|
|
3090
3201
|
import { existsSync as existsSync5, readFileSync as readFileSync5 } from "fs";
|
|
3091
3202
|
import { homedir as homedir3 } from "os";
|
|
3092
|
-
function loadFileConfig() {
|
|
3203
|
+
function loadFileConfig(homeDir = homedir3()) {
|
|
3093
3204
|
if (cachedConfig !== null) return cachedConfig;
|
|
3094
|
-
const configPath = getLegacyConfigJsonPath(
|
|
3205
|
+
const configPath = getLegacyConfigJsonPath(homeDir);
|
|
3095
3206
|
try {
|
|
3096
3207
|
if (existsSync5(configPath)) {
|
|
3097
3208
|
cachedConfig = JSON.parse(readFileSync5(configPath, "utf-8"));
|
|
@@ -3121,15 +3232,15 @@ import { homedir as homedir4 } from "os";
|
|
|
3121
3232
|
function loadTomlConfig(options = {}) {
|
|
3122
3233
|
const homeDir = options.homeDir ?? homedir4();
|
|
3123
3234
|
const projectRoot = options.projectRoot ?? null;
|
|
3124
|
-
const
|
|
3125
|
-
const cached = configCache2.get(
|
|
3235
|
+
const cacheKey3 = `${homeDir}\0${projectRoot ?? ""}`;
|
|
3236
|
+
const cached = configCache2.get(cacheKey3);
|
|
3126
3237
|
if (cached) return cached;
|
|
3127
3238
|
const userToml = getGlobalConfigTomlPath(homeDir);
|
|
3128
3239
|
const projectToml = projectRoot ? getProjectConfigTomlPath(projectRoot) : null;
|
|
3129
3240
|
const userConfig = existsSync6(userToml) ? parseTomlConfig(readFileSync6(userToml, "utf8"), userToml) : {};
|
|
3130
3241
|
const projectConfig = projectToml && existsSync6(projectToml) ? parseTomlConfig(readFileSync6(projectToml, "utf8"), projectToml) : {};
|
|
3131
3242
|
const merged = mergeTomlConfig(userConfig, projectConfig);
|
|
3132
|
-
configCache2.set(
|
|
3243
|
+
configCache2.set(cacheKey3, merged);
|
|
3133
3244
|
return merged;
|
|
3134
3245
|
}
|
|
3135
3246
|
function mergeTomlConfig(base, override) {
|
|
@@ -3250,8 +3361,8 @@ function getResolvedConfig(options = {}) {
|
|
|
3250
3361
|
const projectRoot = options.projectRoot === void 0 ? detectProject()?.rootPath ?? null : options.projectRoot;
|
|
3251
3362
|
loadDotenv(projectRoot === null ? void 0 : projectRoot ?? void 0, { userHomeDir: homeDir });
|
|
3252
3363
|
const toml = loadTomlConfig({ projectRoot: projectRoot ?? null, homeDir });
|
|
3253
|
-
const yaml = loadYamlConfig(projectRoot ?? null);
|
|
3254
|
-
const legacy = loadFileConfig();
|
|
3364
|
+
const yaml = loadYamlConfig(projectRoot ?? null, { homeDir });
|
|
3365
|
+
const legacy = loadFileConfig(homeDir);
|
|
3255
3366
|
const embeddingBaseUrl = first(process.env.MEMORIX_EMBEDDING_BASE_URL, toml.embedding?.base_url, yaml.embedding?.baseUrl, legacy.embeddingApi?.baseUrl);
|
|
3256
3367
|
const openRouterEmbeddingApiKey = isOpenRouterUrl(embeddingBaseUrl) ? process.env.OPENROUTER_API_KEY : void 0;
|
|
3257
3368
|
const memoryLlmProvider = first(
|
|
@@ -3273,15 +3384,17 @@ function getResolvedConfig(options = {}) {
|
|
|
3273
3384
|
legacy.llm?.baseUrl
|
|
3274
3385
|
);
|
|
3275
3386
|
const openRouterMemoryLlmApiKey = isOpenRouterMemoryLane(memoryLlmProvider, memoryLlmBaseUrl) ? process.env.OPENROUTER_API_KEY : void 0;
|
|
3387
|
+
const isAtlasCloud = memoryLlmProvider === "atlascloud";
|
|
3276
3388
|
const memoryLlmApiKey = first(
|
|
3277
3389
|
process.env.MEMORIX_LLM_API_KEY,
|
|
3278
3390
|
process.env.MEMORIX_API_KEY,
|
|
3279
3391
|
toml.memory?.llm?.api_key,
|
|
3280
3392
|
yaml.llm?.apiKey,
|
|
3281
3393
|
legacy.llm?.apiKey,
|
|
3282
|
-
|
|
3283
|
-
process.env.
|
|
3284
|
-
|
|
3394
|
+
// Never borrow another provider's credentials for the Atlas Cloud preset.
|
|
3395
|
+
isAtlasCloud ? process.env.ATLASCLOUD_API_KEY : process.env.OPENAI_API_KEY,
|
|
3396
|
+
isAtlasCloud ? void 0 : process.env.ANTHROPIC_API_KEY,
|
|
3397
|
+
isAtlasCloud ? void 0 : openRouterMemoryLlmApiKey
|
|
3285
3398
|
);
|
|
3286
3399
|
const resolved = {
|
|
3287
3400
|
agent: {
|
|
@@ -3460,7 +3573,8 @@ function getEnvSourceNames() {
|
|
|
3460
3573
|
"MEMORIX_CODEGRAPH_EXTERNAL_CONTEXT",
|
|
3461
3574
|
"MEMORIX_CODEGRAPH_EXTERNAL_COMMAND",
|
|
3462
3575
|
"MEMORIX_CODEGRAPH_EXTERNAL_TIMEOUT_MS",
|
|
3463
|
-
"OPENROUTER_API_KEY"
|
|
3576
|
+
"OPENROUTER_API_KEY",
|
|
3577
|
+
"ATLASCLOUD_API_KEY"
|
|
3464
3578
|
].filter((name) => process.env[name]);
|
|
3465
3579
|
}
|
|
3466
3580
|
function isOpenRouterUrl(value) {
|
|
@@ -3679,12 +3793,45 @@ function textHash(text2) {
|
|
|
3679
3793
|
async function loadDiskCache() {
|
|
3680
3794
|
try {
|
|
3681
3795
|
const raw = await readFile(CACHE_FILE, "utf-8");
|
|
3796
|
+
if (Buffer.byteLength(raw, "utf8") > MAX_CACHE_FILE_BYTES) {
|
|
3797
|
+
console.error("[memorix] FastEmbed cache exceeds the disk load limit; starting with an empty cache");
|
|
3798
|
+
return;
|
|
3799
|
+
}
|
|
3682
3800
|
const entries = JSON.parse(raw);
|
|
3683
|
-
|
|
3684
|
-
|
|
3801
|
+
if (!Array.isArray(entries)) return;
|
|
3802
|
+
for (const entry of entries) {
|
|
3803
|
+
if (!Array.isArray(entry) || typeof entry[0] !== "string" || !isVector(entry[1])) continue;
|
|
3804
|
+
cacheSet(entry[0], entry[1], false);
|
|
3805
|
+
}
|
|
3806
|
+
console.error(`[memorix] Loaded ${cache.size} cached embeddings from disk`);
|
|
3685
3807
|
} catch {
|
|
3686
3808
|
}
|
|
3687
3809
|
}
|
|
3810
|
+
function isVector(value) {
|
|
3811
|
+
return Array.isArray(value) && value.every((entry) => typeof entry === "number");
|
|
3812
|
+
}
|
|
3813
|
+
function maxCachePayloadBytes() {
|
|
3814
|
+
const raw = Number.parseInt(process.env.MEMORIX_EMBEDDING_CACHE_MAX_BYTES ?? "", 10);
|
|
3815
|
+
return Number.isFinite(raw) && raw > 0 ? raw : DEFAULT_CACHE_PAYLOAD_BYTES;
|
|
3816
|
+
}
|
|
3817
|
+
function cacheSet(hash4, value, markDirty = true) {
|
|
3818
|
+
const incomingBytes = value.length * 8;
|
|
3819
|
+
if (incomingBytes > maxCachePayloadBytes()) return;
|
|
3820
|
+
const existing = cache.get(hash4);
|
|
3821
|
+
if (existing) cachePayloadBytes -= existing.length * 8;
|
|
3822
|
+
else {
|
|
3823
|
+
while (cache.size >= MAX_CACHE_SIZE || cachePayloadBytes + incomingBytes > maxCachePayloadBytes()) {
|
|
3824
|
+
const firstKey = cache.keys().next().value;
|
|
3825
|
+
if (firstKey === void 0) break;
|
|
3826
|
+
const old = cache.get(firstKey);
|
|
3827
|
+
cache.delete(firstKey);
|
|
3828
|
+
if (old) cachePayloadBytes -= old.length * 8;
|
|
3829
|
+
}
|
|
3830
|
+
}
|
|
3831
|
+
cache.set(hash4, value);
|
|
3832
|
+
cachePayloadBytes += incomingBytes;
|
|
3833
|
+
if (markDirty) diskCacheDirty = true;
|
|
3834
|
+
}
|
|
3688
3835
|
async function saveDiskCache() {
|
|
3689
3836
|
if (!diskCacheDirty) return;
|
|
3690
3837
|
try {
|
|
@@ -3695,7 +3842,7 @@ async function saveDiskCache() {
|
|
|
3695
3842
|
} catch {
|
|
3696
3843
|
}
|
|
3697
3844
|
}
|
|
3698
|
-
var CACHE_DIR, CACHE_FILE, cache, MAX_CACHE_SIZE, diskCacheDirty, FastEmbedProvider;
|
|
3845
|
+
var CACHE_DIR, CACHE_FILE, cache, MAX_CACHE_SIZE, DEFAULT_CACHE_PAYLOAD_BYTES, MAX_CACHE_FILE_BYTES, cachePayloadBytes, diskCacheDirty, FastEmbedProvider;
|
|
3699
3846
|
var init_fastembed_provider = __esm({
|
|
3700
3847
|
"src/embedding/fastembed-provider.ts"() {
|
|
3701
3848
|
"use strict";
|
|
@@ -3705,6 +3852,9 @@ var init_fastembed_provider = __esm({
|
|
|
3705
3852
|
CACHE_FILE = join2(CACHE_DIR, ".embedding-cache.json");
|
|
3706
3853
|
cache = /* @__PURE__ */ new Map();
|
|
3707
3854
|
MAX_CACHE_SIZE = 5e3;
|
|
3855
|
+
DEFAULT_CACHE_PAYLOAD_BYTES = 64 * 1024 * 1024;
|
|
3856
|
+
MAX_CACHE_FILE_BYTES = 128 * 1024 * 1024;
|
|
3857
|
+
cachePayloadBytes = 0;
|
|
3708
3858
|
diskCacheDirty = false;
|
|
3709
3859
|
FastEmbedProvider = class _FastEmbedProvider {
|
|
3710
3860
|
name = "fastembed-bge-small";
|
|
@@ -3746,7 +3896,7 @@ var init_fastembed_provider = __esm({
|
|
|
3746
3896
|
if (result.length !== this.dimensions) {
|
|
3747
3897
|
throw new Error(`Expected ${this.dimensions}d embedding, got ${result.length}d`);
|
|
3748
3898
|
}
|
|
3749
|
-
|
|
3899
|
+
cacheSet(hash4, result);
|
|
3750
3900
|
return result;
|
|
3751
3901
|
}
|
|
3752
3902
|
async embedBatch(texts) {
|
|
@@ -3771,7 +3921,7 @@ var init_fastembed_provider = __esm({
|
|
|
3771
3921
|
const originalIdx = uncachedIndices[batchIdx];
|
|
3772
3922
|
const plain = Array.from(vec);
|
|
3773
3923
|
results[originalIdx] = plain;
|
|
3774
|
-
|
|
3924
|
+
cacheSet(textHash(uncachedTexts[batchIdx]), plain);
|
|
3775
3925
|
batchIdx++;
|
|
3776
3926
|
}
|
|
3777
3927
|
}
|
|
@@ -3779,14 +3929,6 @@ var init_fastembed_provider = __esm({
|
|
|
3779
3929
|
}
|
|
3780
3930
|
return results;
|
|
3781
3931
|
}
|
|
3782
|
-
cacheSet(hash4, value) {
|
|
3783
|
-
if (cache.size >= MAX_CACHE_SIZE) {
|
|
3784
|
-
const firstKey = cache.keys().next().value;
|
|
3785
|
-
if (firstKey !== void 0) cache.delete(firstKey);
|
|
3786
|
-
}
|
|
3787
|
-
cache.set(hash4, value);
|
|
3788
|
-
diskCacheDirty = true;
|
|
3789
|
-
}
|
|
3790
3932
|
};
|
|
3791
3933
|
}
|
|
3792
3934
|
});
|
|
@@ -3796,7 +3938,15 @@ var transformers_provider_exports = {};
|
|
|
3796
3938
|
__export(transformers_provider_exports, {
|
|
3797
3939
|
TransformersProvider: () => TransformersProvider
|
|
3798
3940
|
});
|
|
3799
|
-
|
|
3941
|
+
import { createHash as createHash2 } from "crypto";
|
|
3942
|
+
function cacheKey2(text2) {
|
|
3943
|
+
return createHash2("sha256").update(text2).digest("hex");
|
|
3944
|
+
}
|
|
3945
|
+
function maxCachePayloadBytes2() {
|
|
3946
|
+
const raw = Number.parseInt(process.env.MEMORIX_EMBEDDING_CACHE_MAX_BYTES ?? "", 10);
|
|
3947
|
+
return Number.isFinite(raw) && raw > 0 ? raw : DEFAULT_CACHE_PAYLOAD_BYTES2;
|
|
3948
|
+
}
|
|
3949
|
+
var cache2, MAX_CACHE_SIZE2, DEFAULT_CACHE_PAYLOAD_BYTES2, cachePayloadBytes2, TransformersProvider;
|
|
3800
3950
|
var init_transformers_provider = __esm({
|
|
3801
3951
|
"src/embedding/transformers-provider.ts"() {
|
|
3802
3952
|
"use strict";
|
|
@@ -3804,6 +3954,8 @@ var init_transformers_provider = __esm({
|
|
|
3804
3954
|
init_provider();
|
|
3805
3955
|
cache2 = /* @__PURE__ */ new Map();
|
|
3806
3956
|
MAX_CACHE_SIZE2 = 5e3;
|
|
3957
|
+
DEFAULT_CACHE_PAYLOAD_BYTES2 = 64 * 1024 * 1024;
|
|
3958
|
+
cachePayloadBytes2 = 0;
|
|
3807
3959
|
TransformersProvider = class _TransformersProvider {
|
|
3808
3960
|
name = "transformers-minilm";
|
|
3809
3961
|
dimensions = 384;
|
|
@@ -3838,7 +3990,7 @@ var init_transformers_provider = __esm({
|
|
|
3838
3990
|
return Promise.all(inputs.map((input) => this.embedInput(input, options)));
|
|
3839
3991
|
}
|
|
3840
3992
|
async embed(text2) {
|
|
3841
|
-
const cached = cache2.get(text2);
|
|
3993
|
+
const cached = cache2.get(cacheKey2(text2));
|
|
3842
3994
|
if (cached) return cached;
|
|
3843
3995
|
const output = await this.extractor(text2, {
|
|
3844
3996
|
pooling: "mean",
|
|
@@ -3848,7 +4000,7 @@ var init_transformers_provider = __esm({
|
|
|
3848
4000
|
if (result.length !== this.dimensions) {
|
|
3849
4001
|
throw new Error(`Expected ${this.dimensions}d embedding, got ${result.length}d`);
|
|
3850
4002
|
}
|
|
3851
|
-
this.cacheSet(text2, result);
|
|
4003
|
+
this.cacheSet(cacheKey2(text2), result);
|
|
3852
4004
|
return result;
|
|
3853
4005
|
}
|
|
3854
4006
|
async embedBatch(texts) {
|
|
@@ -3856,7 +4008,7 @@ var init_transformers_provider = __esm({
|
|
|
3856
4008
|
const uncachedIndices = [];
|
|
3857
4009
|
const uncachedTexts = [];
|
|
3858
4010
|
for (let i2 = 0; i2 < texts.length; i2++) {
|
|
3859
|
-
const cached = cache2.get(texts[i2]);
|
|
4011
|
+
const cached = cache2.get(cacheKey2(texts[i2]));
|
|
3860
4012
|
if (cached) {
|
|
3861
4013
|
results[i2] = cached;
|
|
3862
4014
|
} else {
|
|
@@ -3874,17 +4026,27 @@ var init_transformers_provider = __esm({
|
|
|
3874
4026
|
const vec = Array.from(allVecs[i2]);
|
|
3875
4027
|
const originalIdx = uncachedIndices[i2];
|
|
3876
4028
|
results[originalIdx] = vec;
|
|
3877
|
-
this.cacheSet(uncachedTexts[i2], vec);
|
|
4029
|
+
this.cacheSet(cacheKey2(uncachedTexts[i2]), vec);
|
|
3878
4030
|
}
|
|
3879
4031
|
}
|
|
3880
4032
|
return results;
|
|
3881
4033
|
}
|
|
3882
4034
|
cacheSet(key, value) {
|
|
3883
|
-
|
|
3884
|
-
|
|
3885
|
-
|
|
4035
|
+
const incomingBytes = value.length * 8;
|
|
4036
|
+
if (incomingBytes > maxCachePayloadBytes2()) return;
|
|
4037
|
+
const existing = cache2.get(key);
|
|
4038
|
+
if (existing) cachePayloadBytes2 -= existing.length * 8;
|
|
4039
|
+
else {
|
|
4040
|
+
while (cache2.size >= MAX_CACHE_SIZE2 || cachePayloadBytes2 + incomingBytes > maxCachePayloadBytes2()) {
|
|
4041
|
+
const firstKey = cache2.keys().next().value;
|
|
4042
|
+
if (firstKey === void 0) break;
|
|
4043
|
+
const old = cache2.get(firstKey);
|
|
4044
|
+
cache2.delete(firstKey);
|
|
4045
|
+
if (old) cachePayloadBytes2 -= old.length * 8;
|
|
4046
|
+
}
|
|
3886
4047
|
}
|
|
3887
4048
|
cache2.set(key, value);
|
|
4049
|
+
cachePayloadBytes2 += incomingBytes;
|
|
3888
4050
|
}
|
|
3889
4051
|
};
|
|
3890
4052
|
}
|
|
@@ -3906,7 +4068,7 @@ __export(api_provider_exports, {
|
|
|
3906
4068
|
saveDiskCacheNow: () => saveDiskCacheNow,
|
|
3907
4069
|
seedApiEmbeddingCacheForTests: () => seedApiEmbeddingCacheForTests
|
|
3908
4070
|
});
|
|
3909
|
-
import { createHash as
|
|
4071
|
+
import { createHash as createHash3 } from "crypto";
|
|
3910
4072
|
import { createReadStream, createWriteStream, constants as fsConstants } from "fs";
|
|
3911
4073
|
import { access, readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2, rename, stat, unlink } from "fs/promises";
|
|
3912
4074
|
import { join as join3 } from "path";
|
|
@@ -3933,7 +4095,7 @@ function cacheStatFile() {
|
|
|
3933
4095
|
function payloadBytes(vector) {
|
|
3934
4096
|
return vector.length * BYTES_PER_DIM;
|
|
3935
4097
|
}
|
|
3936
|
-
function
|
|
4098
|
+
function maxCachePayloadBytes3() {
|
|
3937
4099
|
const raw = process.env.MEMORIX_EMBEDDING_CACHE_MAX_BYTES;
|
|
3938
4100
|
if (raw) {
|
|
3939
4101
|
const parsed = Number.parseInt(raw, 10);
|
|
@@ -3943,7 +4105,7 @@ function maxCachePayloadBytes() {
|
|
|
3943
4105
|
}
|
|
3944
4106
|
function maxEntriesForDimensions(dimensions) {
|
|
3945
4107
|
const dim = Math.max(1, Math.floor(dimensions));
|
|
3946
|
-
const byBytes = Math.floor(
|
|
4108
|
+
const byBytes = Math.floor(maxCachePayloadBytes3() / (dim * BYTES_PER_DIM));
|
|
3947
4109
|
return Math.max(1, Math.min(MAX_CACHE_ENTRIES, byBytes));
|
|
3948
4110
|
}
|
|
3949
4111
|
function rememberDimensions(vector) {
|
|
@@ -3956,13 +4118,15 @@ function evictOldest() {
|
|
|
3956
4118
|
if (firstKey === void 0) return;
|
|
3957
4119
|
const old = cache3.get(firstKey);
|
|
3958
4120
|
cache3.delete(firstKey);
|
|
3959
|
-
if (old)
|
|
4121
|
+
if (old) cachePayloadBytes3 -= payloadBytes(old);
|
|
3960
4122
|
}
|
|
3961
4123
|
function evictToFit(incomingBytes, incomingDims) {
|
|
4124
|
+
if (incomingBytes > maxCachePayloadBytes3()) return false;
|
|
3962
4125
|
const limit2 = maxEntriesForDimensions(incomingDims);
|
|
3963
|
-
while (cache3.size > 0 && (cache3.size >= limit2 ||
|
|
4126
|
+
while (cache3.size > 0 && (cache3.size >= limit2 || cachePayloadBytes3 + incomingBytes > maxCachePayloadBytes3())) {
|
|
3964
4127
|
evictOldest();
|
|
3965
4128
|
}
|
|
4129
|
+
return true;
|
|
3966
4130
|
}
|
|
3967
4131
|
function isNumberArray(value) {
|
|
3968
4132
|
return Array.isArray(value) && value.every((entry) => typeof entry === "number");
|
|
@@ -3989,12 +4153,12 @@ function cacheInsert(hash4, value, dirty) {
|
|
|
3989
4153
|
const incoming = payloadBytes(value);
|
|
3990
4154
|
const existing = cache3.get(hash4);
|
|
3991
4155
|
if (existing) {
|
|
3992
|
-
|
|
4156
|
+
cachePayloadBytes3 -= payloadBytes(existing);
|
|
3993
4157
|
cache3.delete(hash4);
|
|
3994
4158
|
}
|
|
3995
|
-
evictToFit(incoming, value.length || cacheDimensions || DEFAULT_ASSUMED_DIMENSIONS);
|
|
4159
|
+
if (!evictToFit(incoming, value.length || cacheDimensions || DEFAULT_ASSUMED_DIMENSIONS)) return;
|
|
3996
4160
|
cache3.set(hash4, value);
|
|
3997
|
-
|
|
4161
|
+
cachePayloadBytes3 += incoming;
|
|
3998
4162
|
if (dirty) diskCacheDirty2 = true;
|
|
3999
4163
|
}
|
|
4000
4164
|
async function readCacheStat() {
|
|
@@ -4030,7 +4194,7 @@ function cacheNamespace(config) {
|
|
|
4030
4194
|
].join("|");
|
|
4031
4195
|
}
|
|
4032
4196
|
function textHash2(text2, namespace) {
|
|
4033
|
-
return
|
|
4197
|
+
return createHash3("sha256").update(`${namespace}\0${text2}`).digest("hex").slice(0, 16);
|
|
4034
4198
|
}
|
|
4035
4199
|
function inputIdentity(input, options = {}) {
|
|
4036
4200
|
return JSON.stringify({
|
|
@@ -4372,7 +4536,7 @@ function getApiEmbeddingDiskCacheLoadCountForTests() {
|
|
|
4372
4536
|
}
|
|
4373
4537
|
function resetApiEmbeddingCacheForTests() {
|
|
4374
4538
|
cache3.clear();
|
|
4375
|
-
|
|
4539
|
+
cachePayloadBytes3 = 0;
|
|
4376
4540
|
cacheDimensions = null;
|
|
4377
4541
|
diskCacheEntryCount = 0;
|
|
4378
4542
|
diskCacheLoaded = false;
|
|
@@ -4383,14 +4547,14 @@ function resetApiEmbeddingCacheForTests() {
|
|
|
4383
4547
|
}
|
|
4384
4548
|
function seedApiEmbeddingCacheForTests(entries) {
|
|
4385
4549
|
cache3.clear();
|
|
4386
|
-
|
|
4550
|
+
cachePayloadBytes3 = 0;
|
|
4387
4551
|
cacheDimensions = null;
|
|
4388
4552
|
for (const [key, value] of entries) cacheInsert(key, value, true);
|
|
4389
4553
|
diskCacheLoaded = true;
|
|
4390
4554
|
diskCacheDirty2 = true;
|
|
4391
4555
|
}
|
|
4392
4556
|
function getApiEmbeddingCachePayloadBytesForTests() {
|
|
4393
|
-
return
|
|
4557
|
+
return cachePayloadBytes3;
|
|
4394
4558
|
}
|
|
4395
4559
|
function getApiEmbeddingJsonlLineCountCallsForTests() {
|
|
4396
4560
|
return jsonlLineCountCalls;
|
|
@@ -4564,7 +4728,7 @@ function scheduleDiskSave() {
|
|
|
4564
4728
|
diskSaveTimer = null;
|
|
4565
4729
|
}, DISK_SAVE_DEBOUNCE_MS);
|
|
4566
4730
|
}
|
|
4567
|
-
function
|
|
4731
|
+
function cacheSet2(hash4, value) {
|
|
4568
4732
|
cacheInsert(hash4, value, true);
|
|
4569
4733
|
}
|
|
4570
4734
|
function resolveEnvEmbeddingApiKey() {
|
|
@@ -4684,7 +4848,7 @@ async function waitForRetry(waitMs, signal) {
|
|
|
4684
4848
|
abortSignal.addEventListener("abort", onAbort, { once: true });
|
|
4685
4849
|
});
|
|
4686
4850
|
}
|
|
4687
|
-
var cache3, MAX_CACHE_ENTRIES, MAX_CACHE_PAYLOAD_BYTES, BYTES_PER_DIM, DEFAULT_ASSUMED_DIMENSIONS, MAX_MIGRATION_VALUE_BYTES,
|
|
4851
|
+
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;
|
|
4688
4852
|
var init_api_provider = __esm({
|
|
4689
4853
|
"src/embedding/api-provider.ts"() {
|
|
4690
4854
|
"use strict";
|
|
@@ -4696,7 +4860,7 @@ var init_api_provider = __esm({
|
|
|
4696
4860
|
BYTES_PER_DIM = 8;
|
|
4697
4861
|
DEFAULT_ASSUMED_DIMENSIONS = 4096;
|
|
4698
4862
|
MAX_MIGRATION_VALUE_BYTES = 16 * 1024 * 1024;
|
|
4699
|
-
|
|
4863
|
+
cachePayloadBytes3 = 0;
|
|
4700
4864
|
cacheDimensions = null;
|
|
4701
4865
|
diskCacheEntryCount = 0;
|
|
4702
4866
|
diskCacheDirty2 = false;
|
|
@@ -4881,7 +5045,7 @@ var init_api_provider = __esm({
|
|
|
4881
5045
|
} else {
|
|
4882
5046
|
embedding = await apiCall();
|
|
4883
5047
|
}
|
|
4884
|
-
|
|
5048
|
+
cacheSet2(hash4, embedding);
|
|
4885
5049
|
scheduleDiskSave();
|
|
4886
5050
|
return embedding;
|
|
4887
5051
|
}
|
|
@@ -4929,7 +5093,7 @@ var init_api_provider = __esm({
|
|
|
4929
5093
|
for (const item of response.data) {
|
|
4930
5094
|
const originalIdx = chunkIndices[item.index];
|
|
4931
5095
|
results[originalIdx] = item.embedding;
|
|
4932
|
-
|
|
5096
|
+
cacheSet2(textHash2(normalizedTexts[originalIdx], this.cacheKeyNamespace), item.embedding);
|
|
4933
5097
|
}
|
|
4934
5098
|
} catch (error) {
|
|
4935
5099
|
const providerLimit = parseBatchLimit(error);
|
|
@@ -5007,7 +5171,7 @@ var init_api_provider = __esm({
|
|
|
5007
5171
|
throw new Error(`Expected ${this.dimensions}d, got ${embedding.length}d; dimension mismatch`);
|
|
5008
5172
|
}
|
|
5009
5173
|
this.trackUsage(response);
|
|
5010
|
-
|
|
5174
|
+
cacheSet2(hash4, embedding);
|
|
5011
5175
|
scheduleDiskSave();
|
|
5012
5176
|
return embedding;
|
|
5013
5177
|
}
|
|
@@ -6390,6 +6554,7 @@ var init_provider2 = __esm({
|
|
|
6390
6554
|
openai: { baseUrl: "https://api.openai.com/v1", model: "gpt-4.1-nano" },
|
|
6391
6555
|
anthropic: { baseUrl: "https://api.anthropic.com/v1", model: "claude-3-5-haiku-latest" },
|
|
6392
6556
|
openrouter: { baseUrl: "https://openrouter.ai/api/v1", model: "openai/gpt-4.1-nano" },
|
|
6557
|
+
atlascloud: { baseUrl: "https://api.atlascloud.ai/v1", model: "deepseek-ai/deepseek-v3.2" },
|
|
6393
6558
|
custom: { baseUrl: "http://localhost:11434/v1", model: "llama3" }
|
|
6394
6559
|
};
|
|
6395
6560
|
currentConfig = null;
|
|
@@ -6653,6 +6818,7 @@ var init_sqlite_store = __esm({
|
|
|
6653
6818
|
init_sqlite_db();
|
|
6654
6819
|
init_sqlite_reliability();
|
|
6655
6820
|
init_sqlite_fts();
|
|
6821
|
+
init_file_lock();
|
|
6656
6822
|
SqliteBackend = class {
|
|
6657
6823
|
db = null;
|
|
6658
6824
|
dataDir = "";
|
|
@@ -6816,38 +6982,43 @@ var init_sqlite_store = __esm({
|
|
|
6816
6982
|
}
|
|
6817
6983
|
// ── Migration ────────────────────────────────────────────────────
|
|
6818
6984
|
async migrateFromJsonIfNeeded() {
|
|
6819
|
-
const count2 = this.db.prepare(`SELECT COUNT(*) AS cnt FROM observations`).get();
|
|
6820
|
-
if (count2.cnt > 0) return;
|
|
6821
6985
|
const jsonPath = path7.join(this.dataDir, "observations.json");
|
|
6822
6986
|
if (!fs4.existsSync(jsonPath)) return;
|
|
6823
|
-
|
|
6987
|
+
await withFileLock(this.dataDir, async () => {
|
|
6988
|
+
const count2 = this.db.prepare(`SELECT COUNT(*) AS cnt FROM observations`).get();
|
|
6989
|
+
if (count2.cnt > 0) return;
|
|
6824
6990
|
const raw = fs4.readFileSync(jsonPath, "utf-8");
|
|
6825
|
-
const
|
|
6991
|
+
const parsed = JSON.parse(raw);
|
|
6992
|
+
if (!Array.isArray(parsed)) {
|
|
6993
|
+
throw new Error("[memorix] observations.json migration refused: expected a JSON array");
|
|
6994
|
+
}
|
|
6995
|
+
const observations2 = parsed;
|
|
6826
6996
|
if (observations2.length === 0) return;
|
|
6997
|
+
if (observations2.some((obs) => !obs || !Number.isSafeInteger(obs.id) || obs.id < 1 || typeof obs.projectId !== "string")) {
|
|
6998
|
+
throw new Error("[memorix] observations.json migration refused: invalid observation record");
|
|
6999
|
+
}
|
|
6827
7000
|
console.error(`[memorix] Migrating ${observations2.length} observations from JSON to SQLite...`);
|
|
6828
7001
|
const insertMany = this.db.transaction((obsList) => {
|
|
6829
7002
|
for (const obs of obsList) {
|
|
6830
7003
|
this.stmtInsert.run(obsToRow(obs));
|
|
6831
7004
|
}
|
|
6832
|
-
|
|
6833
|
-
|
|
6834
|
-
|
|
6835
|
-
if (fs4.existsSync(counterPath)) {
|
|
6836
|
-
try {
|
|
7005
|
+
const counterPath = path7.join(this.dataDir, "counter.json");
|
|
7006
|
+
let counterNextId;
|
|
7007
|
+
if (fs4.existsSync(counterPath)) {
|
|
6837
7008
|
const counterData = JSON.parse(fs4.readFileSync(counterPath, "utf-8"));
|
|
6838
|
-
const
|
|
6839
|
-
|
|
6840
|
-
|
|
6841
|
-
|
|
7009
|
+
const candidate = counterData.nextId ?? counterData.next_id;
|
|
7010
|
+
if (candidate !== void 0 && (!Number.isSafeInteger(candidate) || Number(candidate) < 1)) {
|
|
7011
|
+
throw new Error("[memorix] counter.json migration refused: nextId must be a positive integer");
|
|
7012
|
+
}
|
|
7013
|
+
counterNextId = candidate === void 0 ? void 0 : Number(candidate);
|
|
6842
7014
|
}
|
|
6843
|
-
|
|
6844
|
-
this.rawSaveIdCounter(Math.max(
|
|
6845
|
-
|
|
6846
|
-
|
|
7015
|
+
const maxId = Math.max(...obsList.map((obs) => obs.id));
|
|
7016
|
+
this.rawSaveIdCounter(Math.max(counterNextId ?? 1, maxId + 1));
|
|
7017
|
+
this.bumpGeneration();
|
|
7018
|
+
});
|
|
7019
|
+
insertMany(observations2);
|
|
6847
7020
|
console.error(`[memorix] Migration complete. ${observations2.length} observations now in SQLite.`);
|
|
6848
|
-
}
|
|
6849
|
-
console.error(`[memorix] JSON\u2192SQLite migration failed (non-fatal, data preserved in JSON): ${err}`);
|
|
6850
|
-
}
|
|
7021
|
+
});
|
|
6851
7022
|
}
|
|
6852
7023
|
// ── Public read ──────────────────────────────────────────────────
|
|
6853
7024
|
async loadAll() {
|
|
@@ -7147,7 +7318,7 @@ var init_obs_store = __esm({
|
|
|
7147
7318
|
});
|
|
7148
7319
|
|
|
7149
7320
|
// src/search/semantic-index.ts
|
|
7150
|
-
import { createHash as
|
|
7321
|
+
import { createHash as createHash4 } from "crypto";
|
|
7151
7322
|
import { createRequire as createRequire3 } from "module";
|
|
7152
7323
|
import path8 from "path";
|
|
7153
7324
|
function createSemanticIndexProfile(provider2) {
|
|
@@ -7161,7 +7332,7 @@ function stateKey(dataDir, profile) {
|
|
|
7161
7332
|
return `${path8.resolve(dataDir)}::${profile.key}`;
|
|
7162
7333
|
}
|
|
7163
7334
|
function tableName(profile) {
|
|
7164
|
-
const digest2 =
|
|
7335
|
+
const digest2 = createHash4("sha256").update(profile.key).digest("hex").slice(0, 20);
|
|
7165
7336
|
return `${TABLE_PREFIX}${digest2}`;
|
|
7166
7337
|
}
|
|
7167
7338
|
function indexRoot(dataDir) {
|
|
@@ -9239,7 +9410,7 @@ var init_lifecycle = __esm({
|
|
|
9239
9410
|
});
|
|
9240
9411
|
|
|
9241
9412
|
// src/store/evidence-store.ts
|
|
9242
|
-
import { createHash as
|
|
9413
|
+
import { createHash as createHash5, randomUUID as randomUUID4 } from "crypto";
|
|
9243
9414
|
function safeJson(value, fallback) {
|
|
9244
9415
|
if (typeof value !== "string" || value.length === 0) return fallback;
|
|
9245
9416
|
try {
|
|
@@ -9273,7 +9444,7 @@ function rowToCard(row) {
|
|
|
9273
9444
|
};
|
|
9274
9445
|
}
|
|
9275
9446
|
function observationHash(observation) {
|
|
9276
|
-
return
|
|
9447
|
+
return createHash5("sha256").update(JSON.stringify({
|
|
9277
9448
|
projectId: observation.projectId,
|
|
9278
9449
|
id: observation.id,
|
|
9279
9450
|
title: observation.title,
|
|
@@ -9703,13 +9874,13 @@ __export(workspace_exports, {
|
|
|
9703
9874
|
loadKnowledgeWorkspace: () => loadKnowledgeWorkspace,
|
|
9704
9875
|
resolveKnowledgeWorkspaceFile: () => resolveKnowledgeWorkspaceFile
|
|
9705
9876
|
});
|
|
9706
|
-
import { createHash as
|
|
9877
|
+
import { createHash as createHash6 } from "crypto";
|
|
9707
9878
|
import { execFile } from "child_process";
|
|
9708
9879
|
import { promises as fs6 } from "fs";
|
|
9709
9880
|
import path10 from "path";
|
|
9710
9881
|
import { promisify } from "util";
|
|
9711
9882
|
function hash(value) {
|
|
9712
|
-
return
|
|
9883
|
+
return createHash6("sha256").update(value).digest("hex");
|
|
9713
9884
|
}
|
|
9714
9885
|
function workspaceId(projectId, mode) {
|
|
9715
9886
|
return "workspace:" + hash(projectId + ":" + mode).slice(0, 24);
|
|
@@ -10317,14 +10488,14 @@ var init_types2 = __esm({
|
|
|
10317
10488
|
});
|
|
10318
10489
|
|
|
10319
10490
|
// src/media/asset-store.ts
|
|
10320
|
-
import { createHash as
|
|
10491
|
+
import { createHash as createHash7, randomUUID as randomUUID6 } from "crypto";
|
|
10321
10492
|
import { copyFile, lstat, mkdir as mkdir3, open, readFile as readFile3, readdir, rename as rename2, rm, stat as stat2, writeFile as writeFile3 } from "fs/promises";
|
|
10322
10493
|
import path11 from "path";
|
|
10323
10494
|
function mediaRoot(dataDir) {
|
|
10324
10495
|
return path11.resolve(dataDir, "media");
|
|
10325
10496
|
}
|
|
10326
10497
|
function projectStorageKey(projectId) {
|
|
10327
|
-
return
|
|
10498
|
+
return createHash7("sha256").update(projectId).digest("hex").slice(0, 16);
|
|
10328
10499
|
}
|
|
10329
10500
|
function validateUnderRoot(root, candidate) {
|
|
10330
10501
|
const resolved = path11.resolve(candidate);
|
|
@@ -10433,7 +10604,7 @@ async function importMediaBuffer(input) {
|
|
|
10433
10604
|
if (input.bytes.length === 0) throw new Error("Media import rejects empty payloads");
|
|
10434
10605
|
if (input.bytes.length > maxBytes) throw new Error(`Media payload is too large (${input.bytes.length} bytes; limit ${maxBytes})`);
|
|
10435
10606
|
const detected = detectMedia(input.bytes.subarray(0, 32));
|
|
10436
|
-
const sha256 =
|
|
10607
|
+
const sha256 = createHash7("sha256").update(input.bytes).digest("hex");
|
|
10437
10608
|
return importKnownMedia({
|
|
10438
10609
|
dataDir: input.dataDir,
|
|
10439
10610
|
projectId: input.projectId,
|
|
@@ -10451,7 +10622,7 @@ async function readMediaAsset(dataDir, asset, maxBytes = DEFAULT_MAX_MEDIA_BYTES
|
|
|
10451
10622
|
if (asset.byteSize > maxBytes) throw new Error(`Media asset exceeds read limit (${asset.byteSize} bytes; limit ${maxBytes})`);
|
|
10452
10623
|
const bytes = await readFile3(getMediaAssetPath(dataDir, asset));
|
|
10453
10624
|
if (bytes.length !== asset.byteSize) throw new Error(`Media asset size no longer matches metadata: ${asset.id}`);
|
|
10454
|
-
const sha256 =
|
|
10625
|
+
const sha256 = createHash7("sha256").update(bytes).digest("hex");
|
|
10455
10626
|
if (sha256 !== asset.sha256) throw new Error(`Media asset hash no longer matches metadata: ${asset.id}`);
|
|
10456
10627
|
return bytes;
|
|
10457
10628
|
}
|
|
@@ -69147,16 +69318,16 @@ var require_jwtaccess = __commonJS({
|
|
|
69147
69318
|
* @returns A string that returns the cached key.
|
|
69148
69319
|
*/
|
|
69149
69320
|
getCachedKey(url, scopes) {
|
|
69150
|
-
let
|
|
69321
|
+
let cacheKey3 = url;
|
|
69151
69322
|
if (scopes && Array.isArray(scopes) && scopes.length) {
|
|
69152
|
-
|
|
69323
|
+
cacheKey3 = url ? `${url}_${scopes.join("_")}` : `${scopes.join("_")}`;
|
|
69153
69324
|
} else if (typeof scopes === "string") {
|
|
69154
|
-
|
|
69325
|
+
cacheKey3 = url ? `${url}_${scopes}` : scopes;
|
|
69155
69326
|
}
|
|
69156
|
-
if (!
|
|
69327
|
+
if (!cacheKey3) {
|
|
69157
69328
|
throw Error("Scopes or url must be provided");
|
|
69158
69329
|
}
|
|
69159
|
-
return
|
|
69330
|
+
return cacheKey3;
|
|
69160
69331
|
}
|
|
69161
69332
|
/**
|
|
69162
69333
|
* Get a non-expired access token, after refreshing if necessary.
|
|
@@ -75702,7 +75873,7 @@ var require_websocket = __commonJS({
|
|
|
75702
75873
|
var http3 = __require("http");
|
|
75703
75874
|
var net = __require("net");
|
|
75704
75875
|
var tls = __require("tls");
|
|
75705
|
-
var { randomBytes, createHash:
|
|
75876
|
+
var { randomBytes, createHash: createHash17 } = __require("crypto");
|
|
75706
75877
|
var { Duplex, Readable: Readable2 } = __require("stream");
|
|
75707
75878
|
var { URL: URL2 } = __require("url");
|
|
75708
75879
|
var PerMessageDeflate2 = require_permessage_deflate();
|
|
@@ -76370,7 +76541,7 @@ var require_websocket = __commonJS({
|
|
|
76370
76541
|
abortHandshake(websocket, socket, "Invalid Upgrade header");
|
|
76371
76542
|
return;
|
|
76372
76543
|
}
|
|
76373
|
-
const digest2 =
|
|
76544
|
+
const digest2 = createHash17("sha1").update(key + GUID).digest("base64");
|
|
76374
76545
|
if (res.headers["sec-websocket-accept"] !== digest2) {
|
|
76375
76546
|
abortHandshake(websocket, socket, "Invalid Sec-WebSocket-Accept header");
|
|
76376
76547
|
return;
|
|
@@ -76742,7 +76913,7 @@ var require_websocket_server = __commonJS({
|
|
|
76742
76913
|
var EventEmitter = __require("events");
|
|
76743
76914
|
var http3 = __require("http");
|
|
76744
76915
|
var { Duplex } = __require("stream");
|
|
76745
|
-
var { createHash:
|
|
76916
|
+
var { createHash: createHash17 } = __require("crypto");
|
|
76746
76917
|
var extension3 = require_extension();
|
|
76747
76918
|
var PerMessageDeflate2 = require_permessage_deflate();
|
|
76748
76919
|
var subprotocol2 = require_subprotocol();
|
|
@@ -77049,7 +77220,7 @@ var require_websocket_server = __commonJS({
|
|
|
77049
77220
|
);
|
|
77050
77221
|
}
|
|
77051
77222
|
if (this._state > RUNNING) return abortHandshake(socket, 503);
|
|
77052
|
-
const digest2 =
|
|
77223
|
+
const digest2 = createHash17("sha1").update(key + GUID).digest("base64");
|
|
77053
77224
|
const headers = [
|
|
77054
77225
|
"HTTP/1.1 101 Switching Protocols",
|
|
77055
77226
|
"Upgrade: websocket",
|
|
@@ -145334,9 +145505,9 @@ var init_long_term = __esm({
|
|
|
145334
145505
|
});
|
|
145335
145506
|
|
|
145336
145507
|
// src/codegraph/ids.ts
|
|
145337
|
-
import { createHash as
|
|
145508
|
+
import { createHash as createHash8 } from "crypto";
|
|
145338
145509
|
function digest(input) {
|
|
145339
|
-
return
|
|
145510
|
+
return createHash8("sha256").update(input).digest("hex").slice(0, 16);
|
|
145340
145511
|
}
|
|
145341
145512
|
function normalizeCodePath(path23) {
|
|
145342
145513
|
return path23.replace(/\\/g, "/").replace(/^\.\//, "").replace(/\/+/g, "/");
|
|
@@ -146384,7 +146555,7 @@ var init_store = __esm({
|
|
|
146384
146555
|
|
|
146385
146556
|
// src/codegraph/code-state.ts
|
|
146386
146557
|
import { execFile as execFile2 } from "child_process";
|
|
146387
|
-
import { createHash as
|
|
146558
|
+
import { createHash as createHash9 } from "crypto";
|
|
146388
146559
|
import { promisify as promisify3 } from "util";
|
|
146389
146560
|
async function runGit(rootPath, args) {
|
|
146390
146561
|
try {
|
|
@@ -146413,7 +146584,7 @@ function changedPathCount(status) {
|
|
|
146413
146584
|
return count2;
|
|
146414
146585
|
}
|
|
146415
146586
|
function fingerprint(baseRevision, status) {
|
|
146416
|
-
return
|
|
146587
|
+
return createHash9("sha256").update(baseRevision ?? "").update("\0").update(status).digest("hex");
|
|
146417
146588
|
}
|
|
146418
146589
|
async function collectCodeStateSnapshot(input) {
|
|
146419
146590
|
const [revision, status] = await Promise.all([
|
|
@@ -146507,12 +146678,12 @@ var init_exclude3 = __esm({
|
|
|
146507
146678
|
});
|
|
146508
146679
|
|
|
146509
146680
|
// src/codegraph/semantic-provider.ts
|
|
146510
|
-
import { createHash as
|
|
146681
|
+
import { createHash as createHash10 } from "crypto";
|
|
146511
146682
|
import "fs";
|
|
146512
146683
|
import { resolve } from "path";
|
|
146513
146684
|
import ts from "typescript";
|
|
146514
146685
|
function hashText(value) {
|
|
146515
|
-
return
|
|
146686
|
+
return createHash10("sha256").update(value).digest("hex");
|
|
146516
146687
|
}
|
|
146517
146688
|
function canonicalPath(value) {
|
|
146518
146689
|
const normalized = resolve(value).replace(/\\/g, "/");
|
|
@@ -146857,11 +147028,11 @@ __export(lite_provider_exports, {
|
|
|
146857
147028
|
indexProjectLite: () => indexProjectLite,
|
|
146858
147029
|
refreshProjectLite: () => refreshProjectLite
|
|
146859
147030
|
});
|
|
146860
|
-
import { createHash as
|
|
147031
|
+
import { createHash as createHash11 } from "crypto";
|
|
146861
147032
|
import { existsSync as existsSync10, readdirSync as readdirSync2, readFileSync as readFileSync8, statSync as statSync3 } from "fs";
|
|
146862
147033
|
import { join as join4, relative as relative2 } from "path";
|
|
146863
147034
|
function hashText2(text2) {
|
|
146864
|
-
return
|
|
147035
|
+
return createHash11("sha256").update(text2).digest("hex");
|
|
146865
147036
|
}
|
|
146866
147037
|
function extension2(path23) {
|
|
146867
147038
|
const index = path23.lastIndexOf(".");
|
|
@@ -147494,7 +147665,7 @@ var claim_store_exports = {};
|
|
|
147494
147665
|
__export(claim_store_exports, {
|
|
147495
147666
|
ClaimStore: () => ClaimStore
|
|
147496
147667
|
});
|
|
147497
|
-
import { createHash as
|
|
147668
|
+
import { createHash as createHash12, randomUUID as randomUUID12 } from "crypto";
|
|
147498
147669
|
function optionalText3(value) {
|
|
147499
147670
|
return typeof value === "string" && value ? value : void 0;
|
|
147500
147671
|
}
|
|
@@ -147547,7 +147718,7 @@ function rowToEvent3(row) {
|
|
|
147547
147718
|
};
|
|
147548
147719
|
}
|
|
147549
147720
|
function evidenceKey(input) {
|
|
147550
|
-
return
|
|
147721
|
+
return createHash12("sha256").update(JSON.stringify([
|
|
147551
147722
|
input.evidenceKind,
|
|
147552
147723
|
input.evidenceId,
|
|
147553
147724
|
input.relation,
|
|
@@ -147745,7 +147916,7 @@ __export(claims_exports, {
|
|
|
147745
147916
|
supersedeClaim: () => supersedeClaim,
|
|
147746
147917
|
writeClaim: () => writeClaim
|
|
147747
147918
|
});
|
|
147748
|
-
import { createHash as
|
|
147919
|
+
import { createHash as createHash13, randomUUID as randomUUID13 } from "crypto";
|
|
147749
147920
|
function compactText2(value, field) {
|
|
147750
147921
|
if (typeof value !== "string") throw new Error("Claim " + field + " must be text");
|
|
147751
147922
|
const sanitized = sanitizeCredentials(value).trim().replace(/\s+/g, " ");
|
|
@@ -147757,7 +147928,7 @@ function normalizedTerm(value) {
|
|
|
147757
147928
|
return compactText2(value, "identity").toLocaleLowerCase("en-US");
|
|
147758
147929
|
}
|
|
147759
147930
|
function hashIdentity(parts) {
|
|
147760
|
-
return
|
|
147931
|
+
return createHash13("sha256").update(parts.join(String.fromCharCode(31))).digest("hex");
|
|
147761
147932
|
}
|
|
147762
147933
|
function buildClaimIdentity(input) {
|
|
147763
147934
|
const subject = normalizedTerm(input.subject);
|
|
@@ -147998,7 +148169,7 @@ function supersedeClaim(store, input) {
|
|
|
147998
148169
|
});
|
|
147999
148170
|
}
|
|
148000
148171
|
function hashObservation(observation) {
|
|
148001
|
-
return
|
|
148172
|
+
return createHash13("sha256").update(JSON.stringify([
|
|
148002
148173
|
observation.title,
|
|
148003
148174
|
observation.narrative,
|
|
148004
148175
|
observation.facts,
|
|
@@ -148242,11 +148413,11 @@ var init_frontmatter = __esm({
|
|
|
148242
148413
|
});
|
|
148243
148414
|
|
|
148244
148415
|
// src/knowledge/markdown.ts
|
|
148245
|
-
import { createHash as
|
|
148416
|
+
import { createHash as createHash14 } from "crypto";
|
|
148246
148417
|
import { promises as fs10 } from "fs";
|
|
148247
148418
|
import path17 from "path";
|
|
148248
148419
|
function hashContent(content) {
|
|
148249
|
-
return
|
|
148420
|
+
return createHash14("sha256").update(content).digest("hex");
|
|
148250
148421
|
}
|
|
148251
148422
|
function stringField(data, key) {
|
|
148252
148423
|
const value = data[key];
|
|
@@ -148372,11 +148543,11 @@ __export(wiki_exports, {
|
|
|
148372
148543
|
lintKnowledgeWorkspace: () => lintKnowledgeWorkspace,
|
|
148373
148544
|
readKnowledgePage: () => readKnowledgePage
|
|
148374
148545
|
});
|
|
148375
|
-
import { createHash as
|
|
148546
|
+
import { createHash as createHash15 } from "crypto";
|
|
148376
148547
|
import { promises as fs11 } from "fs";
|
|
148377
148548
|
import path18 from "path";
|
|
148378
148549
|
function hash2(value) {
|
|
148379
|
-
return
|
|
148550
|
+
return createHash15("sha256").update(value).digest("hex");
|
|
148380
148551
|
}
|
|
148381
148552
|
function now() {
|
|
148382
148553
|
return (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -149233,11 +149404,11 @@ __export(workflows_exports, {
|
|
|
149233
149404
|
syncCanonicalWorkflows: () => syncCanonicalWorkflows,
|
|
149234
149405
|
writeCanonicalWorkflow: () => writeCanonicalWorkflow
|
|
149235
149406
|
});
|
|
149236
|
-
import { createHash as
|
|
149407
|
+
import { createHash as createHash16 } from "crypto";
|
|
149237
149408
|
import { promises as fs12 } from "fs";
|
|
149238
149409
|
import path19 from "path";
|
|
149239
149410
|
function hash3(value) {
|
|
149240
|
-
return
|
|
149411
|
+
return createHash16("sha256").update(value).digest("hex");
|
|
149241
149412
|
}
|
|
149242
149413
|
function now2() {
|
|
149243
149414
|
return (/* @__PURE__ */ new Date()).toISOString();
|