memorix 1.7.3 → 1.8.1
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 +41 -0
- package/README.md +1 -1
- package/README.zh-CN.md +1 -1
- package/dist/cli/index.js +1488 -270
- package/dist/dashboard/static/app.js +125 -27
- package/dist/dashboard/static/index.html +11 -1
- package/dist/dashboard/static/style.css +86 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +927 -240
- package/dist/maintenance-runner.js +607 -68
- package/dist/media-audio-runner.js +602 -63
- package/dist/media-video-runner.js +607 -68
- package/dist/memcode-runtime/CHANGELOG.md +41 -0
- package/dist/sdk.js +926 -239
- package/dist/types.d.ts +8 -0
- package/dist/vector-backfill-runner.js +607 -68
- package/docs/1.2.4-PERSISTENT-MEMORY-DELIVERY.md +1 -1
- package/docs/1.8.0-RELEASE-CANDIDATE-SPEC.md +75 -0
- package/docs/API_REFERENCE.md +39 -1
- package/docs/ARCHITECTURE.md +3 -1
- package/docs/DASHBOARD.md +16 -0
- package/docs/DEVELOPMENT.md +3 -2
- package/docs/INTEGRATIONS.md +1 -1
- package/docs/README.md +15 -2
- package/package.json +1 -1
- package/plugins/antigravity/memorix/rules/memorix.md +1 -1
- package/plugins/claude/memorix/.claude-plugin/plugin.json +1 -1
- package/plugins/claude/memorix/SKILL.md +1 -1
- package/plugins/claude/memorix/skills/memorix-memory/SKILL.md +2 -2
- package/plugins/codebuddy/memorix/.codebuddy-plugin/plugin.json +1 -1
- package/plugins/codebuddy/memorix/skills/memorix-memory/SKILL.md +2 -2
- package/plugins/codex/memorix/.codex-plugin/plugin.json +1 -1
- package/plugins/codex/memorix/skills/memorix-memory/SKILL.md +2 -2
- package/plugins/copilot/memorix/plugin.json +1 -1
- package/plugins/copilot/memorix/skills/memorix-memory/SKILL.md +2 -2
- package/plugins/cursor/memorix/skills/memorix-memory/SKILL.md +2 -2
- package/plugins/gemini/memorix/GEMINI.md +1 -1
- package/plugins/gemini/memorix/gemini-extension.json +1 -1
- package/plugins/omp/memorix/package.json +1 -1
- package/plugins/openclaw/memorix/.codex-plugin/plugin.json +1 -1
- package/plugins/pi/memorix/package.json +1 -1
- package/plugins/pi/memorix/skills/memorix-memory/SKILL.md +2 -2
- package/server.json +2 -2
- package/src/cli/capability-map.ts +2 -0
- package/src/cli/commands/context.ts +11 -0
- package/src/cli/commands/dashboard.ts +1 -1
- package/src/cli/commands/evidence.ts +56 -0
- package/src/cli/commands/feedback.ts +58 -0
- package/src/cli/commands/resume.ts +2 -0
- package/src/cli/commands/serve-http.ts +229 -13
- package/src/cli/fallback-budget.ts +59 -0
- package/src/cli/index.ts +5 -1
- package/src/compact/engine.ts +26 -1
- package/src/config/dotenv-loader.ts +17 -0
- package/src/dashboard/config-provenance.ts +17 -0
- package/src/dashboard/evidence.ts +63 -0
- package/src/dashboard/server.ts +178 -154
- package/src/dashboard/static/index.html +11 -1
- package/src/dashboard/static/style.css +86 -0
- package/src/hooks/installers/index.ts +1 -1
- package/src/hooks/official-skills.ts +3 -3
- package/src/hooks/rules/memorix-agent-rules.md +1 -1
- package/src/memory/feedback-model.ts +4 -0
- package/src/memory/feedback.ts +220 -0
- package/src/memory/observations.ts +19 -0
- package/src/memory/retention.ts +38 -5
- package/src/server/mcp-binding-store.ts +79 -0
- package/src/server/mcp-diagnostics.ts +40 -0
- package/src/server/tool-profile.ts +4 -0
- package/src/server.ts +125 -5
- package/src/store/evidence-store.ts +261 -0
- package/src/store/sqlite-db.ts +104 -0
- package/src/types.ts +8 -0
|
@@ -95,6 +95,8 @@ function loadEnvFile(filePath) {
|
|
|
95
95
|
const parsed = parse(readFileSync(filePath, "utf-8"));
|
|
96
96
|
for (const [key, value] of Object.entries(parsed)) {
|
|
97
97
|
if (!(key in process.env)) {
|
|
98
|
+
loadedEnvKeys.add(key);
|
|
99
|
+
loadedEnvValues.set(key, value);
|
|
98
100
|
process.env[key] = value;
|
|
99
101
|
injectedKeys.add(key);
|
|
100
102
|
}
|
|
@@ -107,6 +109,8 @@ function loadDotenv(projectRoot, options = {}) {
|
|
|
107
109
|
resetDotenv();
|
|
108
110
|
}
|
|
109
111
|
loadedEnvFiles.length = 0;
|
|
112
|
+
loadedEnvKeys.clear();
|
|
113
|
+
loadedEnvValues.clear();
|
|
110
114
|
if (projectRoot) {
|
|
111
115
|
loadEnvFile(getProjectDotenvPath(projectRoot));
|
|
112
116
|
}
|
|
@@ -122,11 +126,12 @@ function resetDotenv() {
|
|
|
122
126
|
dotenvLoaded = false;
|
|
123
127
|
dotenvProjectRoot = null;
|
|
124
128
|
loadedEnvFiles.length = 0;
|
|
129
|
+
loadedEnvKeys.clear();
|
|
125
130
|
}
|
|
126
131
|
function getLoadedEnvFiles() {
|
|
127
132
|
return loadedEnvFiles;
|
|
128
133
|
}
|
|
129
|
-
var dotenvLoaded, dotenvProjectRoot, loadedEnvFiles, injectedKeys;
|
|
134
|
+
var dotenvLoaded, dotenvProjectRoot, loadedEnvFiles, loadedEnvKeys, loadedEnvValues, injectedKeys;
|
|
130
135
|
var init_dotenv_loader = __esm({
|
|
131
136
|
"src/config/dotenv-loader.ts"() {
|
|
132
137
|
"use strict";
|
|
@@ -135,6 +140,8 @@ var init_dotenv_loader = __esm({
|
|
|
135
140
|
dotenvLoaded = false;
|
|
136
141
|
dotenvProjectRoot = null;
|
|
137
142
|
loadedEnvFiles = [];
|
|
143
|
+
loadedEnvKeys = /* @__PURE__ */ new Set();
|
|
144
|
+
loadedEnvValues = /* @__PURE__ */ new Map();
|
|
138
145
|
injectedKeys = /* @__PURE__ */ new Set();
|
|
139
146
|
}
|
|
140
147
|
});
|
|
@@ -518,7 +525,7 @@ function closeAllDatabases() {
|
|
|
518
525
|
_dbCache.delete(key);
|
|
519
526
|
}
|
|
520
527
|
}
|
|
521
|
-
var BetterSqlite3, CREATE_OBSERVATIONS_TABLE, CREATE_MINI_SKILLS_TABLE, CREATE_SESSIONS_TABLE, CREATE_META_TABLE, CREATE_TEAM_AGENTS_TABLE, CREATE_TEAM_MESSAGES_TABLE, CREATE_TEAM_TASKS_TABLE, CREATE_TEAM_TASK_DEPS_TABLE, CREATE_TEAM_LOCKS_TABLE, CREATE_TEAM_ROLES_TABLE, CREATE_CHAT_TRANSCRIPT_TABLE, CREATE_GRAPH_ENTITIES_TABLE, CREATE_GRAPH_RELATIONS_TABLE, CREATE_CODE_FILES_TABLE, CREATE_CODE_SYMBOLS_TABLE, CREATE_CODE_EDGES_TABLE, CREATE_OBSERVATION_CODE_REFS_TABLE, CREATE_SCHEMA_MIGRATIONS_TABLE, CREATE_CODE_STATE_SNAPSHOTS_TABLE, CREATE_CODE_STATE_SNAPSHOT_FILES_TABLE, CREATE_KNOWLEDGE_CLAIMS_TABLE, CREATE_KNOWLEDGE_CLAIM_EVIDENCE_TABLE, CREATE_KNOWLEDGE_CLAIM_EVENTS_TABLE, CREATE_KNOWLEDGE_WORKSPACES_TABLE, CREATE_KNOWLEDGE_PAGES_TABLE, CREATE_KNOWLEDGE_PAGE_CLAIMS_TABLE, CREATE_KNOWLEDGE_PAGE_LINKS_TABLE, CREATE_KNOWLEDGE_PROPOSALS_TABLE, CREATE_KNOWLEDGE_WORKFLOWS_TABLE, CREATE_KNOWLEDGE_WORKFLOW_RUNS_TABLE, CREATE_LONG_TERM_MEMORIES_TABLE, CREATE_LONG_TERM_MEMORY_EVIDENCE_TABLE, CREATE_LONG_TERM_MEMORY_EVENTS_TABLE, CREATE_MEMORY_OUTCOME_SIGNALS_TABLE, CREATE_MEDIA_ASSETS_TABLE, CREATE_MEDIA_ASSET_LINKS_TABLE, CREATE_MEDIA_DERIVATIONS_TABLE, CREATE_MEDIA_EMBEDDING_PROFILES_TABLE, CREATE_MEDIA_EMBEDDINGS_TABLE, CREATE_MEDIA_JOBS_TABLE, CREATE_MAINTENANCE_JOBS_TABLE, CREATE_MAINTENANCE_TARGETS_TABLE, CREATE_COMPACTION_CHECKPOINTS_TABLE, CREATE_INDEXES, SCHEMA_MIGRATIONS, _dbCache;
|
|
528
|
+
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;
|
|
522
529
|
var init_sqlite_db = __esm({
|
|
523
530
|
"src/store/sqlite-db.ts"() {
|
|
524
531
|
"use strict";
|
|
@@ -1164,6 +1171,79 @@ CREATE TABLE IF NOT EXISTS compaction_checkpoints (
|
|
|
1164
1171
|
created_at TEXT NOT NULL,
|
|
1165
1172
|
updated_at TEXT NOT NULL
|
|
1166
1173
|
);
|
|
1174
|
+
`;
|
|
1175
|
+
CREATE_EVIDENCE_CARDS_TABLE = `
|
|
1176
|
+
CREATE TABLE IF NOT EXISTS evidence_cards (
|
|
1177
|
+
id TEXT PRIMARY KEY,
|
|
1178
|
+
project_id TEXT NOT NULL,
|
|
1179
|
+
candidate_kind TEXT NOT NULL,
|
|
1180
|
+
candidate_id TEXT NOT NULL,
|
|
1181
|
+
title TEXT NOT NULL,
|
|
1182
|
+
summary TEXT NOT NULL DEFAULT '',
|
|
1183
|
+
entity_name TEXT,
|
|
1184
|
+
source_kind TEXT NOT NULL,
|
|
1185
|
+
source_ref TEXT NOT NULL,
|
|
1186
|
+
locator TEXT,
|
|
1187
|
+
captured_hash TEXT,
|
|
1188
|
+
session_id TEXT,
|
|
1189
|
+
status TEXT NOT NULL DEFAULT 'active',
|
|
1190
|
+
verification TEXT NOT NULL DEFAULT 'unverified',
|
|
1191
|
+
freshness TEXT NOT NULL DEFAULT 'current',
|
|
1192
|
+
stale_reason TEXT,
|
|
1193
|
+
files_json TEXT NOT NULL DEFAULT '[]',
|
|
1194
|
+
related_entities_json TEXT NOT NULL DEFAULT '[]',
|
|
1195
|
+
created_at TEXT NOT NULL,
|
|
1196
|
+
updated_at TEXT NOT NULL,
|
|
1197
|
+
UNIQUE(project_id, candidate_kind, candidate_id)
|
|
1198
|
+
);
|
|
1199
|
+
`;
|
|
1200
|
+
CREATE_EVIDENCE_CARD_EVENTS_TABLE = `
|
|
1201
|
+
CREATE TABLE IF NOT EXISTS evidence_card_events (
|
|
1202
|
+
id TEXT PRIMARY KEY,
|
|
1203
|
+
project_id TEXT NOT NULL,
|
|
1204
|
+
card_id TEXT NOT NULL,
|
|
1205
|
+
kind TEXT NOT NULL,
|
|
1206
|
+
detail TEXT,
|
|
1207
|
+
created_at TEXT NOT NULL,
|
|
1208
|
+
FOREIGN KEY (card_id) REFERENCES evidence_cards(id) ON DELETE CASCADE
|
|
1209
|
+
);
|
|
1210
|
+
`;
|
|
1211
|
+
CREATE_MEMORY_FEEDBACK_STATES_TABLE = `
|
|
1212
|
+
CREATE TABLE IF NOT EXISTS memory_feedback_states (
|
|
1213
|
+
project_id TEXT NOT NULL,
|
|
1214
|
+
candidate_kind TEXT NOT NULL,
|
|
1215
|
+
candidate_id TEXT NOT NULL,
|
|
1216
|
+
weight REAL NOT NULL DEFAULT 1.0,
|
|
1217
|
+
lifecycle_status TEXT NOT NULL DEFAULT 'active',
|
|
1218
|
+
updated_at TEXT NOT NULL,
|
|
1219
|
+
PRIMARY KEY (project_id, candidate_kind, candidate_id)
|
|
1220
|
+
);
|
|
1221
|
+
`;
|
|
1222
|
+
CREATE_MEMORY_FEEDBACK_EVENTS_TABLE = `
|
|
1223
|
+
CREATE TABLE IF NOT EXISTS memory_feedback_events (
|
|
1224
|
+
id TEXT PRIMARY KEY,
|
|
1225
|
+
project_id TEXT NOT NULL,
|
|
1226
|
+
candidate_kind TEXT NOT NULL,
|
|
1227
|
+
candidate_id TEXT NOT NULL,
|
|
1228
|
+
signal TEXT NOT NULL,
|
|
1229
|
+
actor TEXT,
|
|
1230
|
+
note TEXT,
|
|
1231
|
+
source_ref TEXT NOT NULL,
|
|
1232
|
+
target_event_id TEXT,
|
|
1233
|
+
delta REAL NOT NULL DEFAULT 0,
|
|
1234
|
+
observed_at TEXT NOT NULL
|
|
1235
|
+
);
|
|
1236
|
+
`;
|
|
1237
|
+
CREATE_MCP_BINDINGS_TABLE = `
|
|
1238
|
+
CREATE TABLE IF NOT EXISTS mcp_bindings (
|
|
1239
|
+
handle_id TEXT PRIMARY KEY,
|
|
1240
|
+
project_id TEXT NOT NULL,
|
|
1241
|
+
project_root TEXT NOT NULL,
|
|
1242
|
+
data_dir TEXT NOT NULL,
|
|
1243
|
+
created_at TEXT NOT NULL,
|
|
1244
|
+
last_used_at TEXT NOT NULL,
|
|
1245
|
+
expires_at TEXT
|
|
1246
|
+
);
|
|
1167
1247
|
`;
|
|
1168
1248
|
CREATE_INDEXES = `
|
|
1169
1249
|
CREATE INDEX IF NOT EXISTS idx_observations_projectId ON observations(projectId);
|
|
@@ -1226,6 +1306,12 @@ CREATE INDEX IF NOT EXISTS idx_maintenance_targets_updated ON maintenance_target
|
|
|
1226
1306
|
CREATE INDEX IF NOT EXISTS idx_compaction_checkpoints_project_recent ON compaction_checkpoints(project_id, status, completed_at DESC, pre_captured_at DESC);
|
|
1227
1307
|
CREATE INDEX IF NOT EXISTS idx_compaction_checkpoints_session_pending ON compaction_checkpoints(project_id, session_id, agent, phase, status, pre_captured_at DESC);
|
|
1228
1308
|
CREATE INDEX IF NOT EXISTS idx_compaction_checkpoints_source ON compaction_checkpoints(project_id, source_key);
|
|
1309
|
+
CREATE INDEX IF NOT EXISTS idx_evidence_cards_project ON evidence_cards(project_id, status, updated_at DESC);
|
|
1310
|
+
CREATE INDEX IF NOT EXISTS idx_evidence_cards_candidate ON evidence_cards(project_id, candidate_kind, candidate_id);
|
|
1311
|
+
CREATE INDEX IF NOT EXISTS idx_evidence_card_events_card ON evidence_card_events(card_id, created_at);
|
|
1312
|
+
CREATE INDEX IF NOT EXISTS idx_memory_feedback_states_project ON memory_feedback_states(project_id, candidate_kind, updated_at DESC);
|
|
1313
|
+
CREATE INDEX IF NOT EXISTS idx_memory_feedback_events_candidate ON memory_feedback_events(project_id, candidate_kind, candidate_id, observed_at DESC);
|
|
1314
|
+
CREATE INDEX IF NOT EXISTS idx_mcp_bindings_project ON mcp_bindings(project_id, last_used_at DESC);
|
|
1229
1315
|
CREATE UNIQUE INDEX IF NOT EXISTS idx_maintenance_jobs_active_dedupe
|
|
1230
1316
|
ON maintenance_jobs(project_id, kind, dedupe_key)
|
|
1231
1317
|
WHERE status IN ('pending', 'running', 'retry');
|
|
@@ -1381,6 +1467,22 @@ CREATE UNIQUE INDEX IF NOT EXISTS idx_maintenance_jobs_active_dedupe
|
|
|
1381
1467
|
}
|
|
1382
1468
|
db2.exec("CREATE INDEX IF NOT EXISTS idx_media_jobs_source_asset ON media_jobs(project_id, source_asset_id, status)");
|
|
1383
1469
|
}
|
|
1470
|
+
},
|
|
1471
|
+
{
|
|
1472
|
+
id: "1.8-context-control-plane",
|
|
1473
|
+
apply: (db2) => {
|
|
1474
|
+
db2.exec(CREATE_EVIDENCE_CARDS_TABLE);
|
|
1475
|
+
db2.exec(CREATE_EVIDENCE_CARD_EVENTS_TABLE);
|
|
1476
|
+
db2.exec(CREATE_MEMORY_FEEDBACK_STATES_TABLE);
|
|
1477
|
+
db2.exec(CREATE_MEMORY_FEEDBACK_EVENTS_TABLE);
|
|
1478
|
+
db2.exec(CREATE_MCP_BINDINGS_TABLE);
|
|
1479
|
+
db2.exec("CREATE INDEX IF NOT EXISTS idx_evidence_cards_project ON evidence_cards(project_id, status, updated_at DESC)");
|
|
1480
|
+
db2.exec("CREATE INDEX IF NOT EXISTS idx_evidence_cards_candidate ON evidence_cards(project_id, candidate_kind, candidate_id)");
|
|
1481
|
+
db2.exec("CREATE INDEX IF NOT EXISTS idx_evidence_card_events_card ON evidence_card_events(card_id, created_at)");
|
|
1482
|
+
db2.exec("CREATE INDEX IF NOT EXISTS idx_memory_feedback_states_project ON memory_feedback_states(project_id, candidate_kind, updated_at DESC)");
|
|
1483
|
+
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)");
|
|
1484
|
+
db2.exec("CREATE INDEX IF NOT EXISTS idx_mcp_bindings_project ON mcp_bindings(project_id, last_used_at DESC)");
|
|
1485
|
+
}
|
|
1384
1486
|
}
|
|
1385
1487
|
];
|
|
1386
1488
|
_dbCache = /* @__PURE__ */ new Map();
|
|
@@ -7981,10 +8083,230 @@ var init_lifecycle = __esm({
|
|
|
7981
8083
|
}
|
|
7982
8084
|
});
|
|
7983
8085
|
|
|
8086
|
+
// src/store/evidence-store.ts
|
|
8087
|
+
import { createHash as createHash3, randomUUID as randomUUID3 } from "crypto";
|
|
8088
|
+
function safeJson(value, fallback) {
|
|
8089
|
+
if (typeof value !== "string" || value.length === 0) return fallback;
|
|
8090
|
+
try {
|
|
8091
|
+
return JSON.parse(value);
|
|
8092
|
+
} catch {
|
|
8093
|
+
return fallback;
|
|
8094
|
+
}
|
|
8095
|
+
}
|
|
8096
|
+
function rowToCard(row) {
|
|
8097
|
+
return {
|
|
8098
|
+
id: String(row.id),
|
|
8099
|
+
projectId: String(row.project_id),
|
|
8100
|
+
candidateKind: row.candidate_kind,
|
|
8101
|
+
candidateId: String(row.candidate_id),
|
|
8102
|
+
title: String(row.title),
|
|
8103
|
+
summary: String(row.summary ?? ""),
|
|
8104
|
+
...row.entity_name ? { entityName: String(row.entity_name) } : {},
|
|
8105
|
+
sourceKind: String(row.source_kind),
|
|
8106
|
+
sourceRef: String(row.source_ref),
|
|
8107
|
+
...row.locator ? { locator: String(row.locator) } : {},
|
|
8108
|
+
...row.captured_hash ? { capturedHash: String(row.captured_hash) } : {},
|
|
8109
|
+
...row.session_id ? { sessionId: String(row.session_id) } : {},
|
|
8110
|
+
status: String(row.status ?? "active"),
|
|
8111
|
+
verification: row.verification,
|
|
8112
|
+
freshness: row.freshness,
|
|
8113
|
+
...row.stale_reason ? { staleReason: String(row.stale_reason) } : {},
|
|
8114
|
+
files: safeJson(row.files_json, []),
|
|
8115
|
+
relatedEntities: safeJson(row.related_entities_json, []),
|
|
8116
|
+
createdAt: String(row.created_at),
|
|
8117
|
+
updatedAt: String(row.updated_at)
|
|
8118
|
+
};
|
|
8119
|
+
}
|
|
8120
|
+
function observationHash(observation) {
|
|
8121
|
+
return createHash3("sha256").update(JSON.stringify({
|
|
8122
|
+
projectId: observation.projectId,
|
|
8123
|
+
id: observation.id,
|
|
8124
|
+
title: observation.title,
|
|
8125
|
+
narrative: observation.narrative,
|
|
8126
|
+
facts: observation.facts,
|
|
8127
|
+
files: observation.filesModified,
|
|
8128
|
+
relatedEntities: observation.relatedEntities
|
|
8129
|
+
})).digest("hex");
|
|
8130
|
+
}
|
|
8131
|
+
function sourceKind(observation) {
|
|
8132
|
+
if (observation.source === "git" || observation.sourceDetail === "git-ingest") return "git";
|
|
8133
|
+
if (observation.sourceDetail === "hook") return "hook";
|
|
8134
|
+
return observation.source ?? "agent";
|
|
8135
|
+
}
|
|
8136
|
+
var EvidenceCardStore;
|
|
8137
|
+
var init_evidence_store = __esm({
|
|
8138
|
+
"src/store/evidence-store.ts"() {
|
|
8139
|
+
"use strict";
|
|
8140
|
+
init_esm_shims();
|
|
8141
|
+
init_sqlite_db();
|
|
8142
|
+
EvidenceCardStore = class {
|
|
8143
|
+
db = null;
|
|
8144
|
+
async init(dataDir) {
|
|
8145
|
+
this.db = getDatabase(dataDir);
|
|
8146
|
+
}
|
|
8147
|
+
requireDb() {
|
|
8148
|
+
if (!this.db) throw new Error("EvidenceCardStore is not initialized.");
|
|
8149
|
+
return this.db;
|
|
8150
|
+
}
|
|
8151
|
+
upsertObservation(observation) {
|
|
8152
|
+
const db2 = this.requireDb();
|
|
8153
|
+
const now3 = (/* @__PURE__ */ new Date()).toISOString();
|
|
8154
|
+
const card = {
|
|
8155
|
+
id: `evidence:observation:${observation.projectId}:${observation.id}`,
|
|
8156
|
+
projectId: observation.projectId,
|
|
8157
|
+
candidateKind: "observation",
|
|
8158
|
+
candidateId: String(observation.id),
|
|
8159
|
+
title: observation.title,
|
|
8160
|
+
summary: observation.narrative.slice(0, 500),
|
|
8161
|
+
entityName: observation.entityName,
|
|
8162
|
+
sourceKind: sourceKind(observation),
|
|
8163
|
+
sourceRef: `observation:${observation.id}`,
|
|
8164
|
+
locator: observation.filesModified?.join(", ") || `observation:${observation.id}`,
|
|
8165
|
+
capturedHash: observationHash(observation),
|
|
8166
|
+
...observation.sessionId ? { sessionId: observation.sessionId } : {},
|
|
8167
|
+
status: observation.status ?? "active",
|
|
8168
|
+
verification: observation.status === "resolved" ? "verified" : "unverified",
|
|
8169
|
+
freshness: "current",
|
|
8170
|
+
files: observation.filesModified ?? [],
|
|
8171
|
+
relatedEntities: observation.relatedEntities ?? [],
|
|
8172
|
+
createdAt: observation.createdAt,
|
|
8173
|
+
updatedAt: now3
|
|
8174
|
+
};
|
|
8175
|
+
db2.prepare(`
|
|
8176
|
+
INSERT INTO evidence_cards (
|
|
8177
|
+
id, project_id, candidate_kind, candidate_id, title, summary, entity_name,
|
|
8178
|
+
source_kind, source_ref, locator, captured_hash, session_id, status,
|
|
8179
|
+
verification, freshness, stale_reason, files_json, related_entities_json,
|
|
8180
|
+
created_at, updated_at
|
|
8181
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NULL, ?, ?, ?, ?)
|
|
8182
|
+
ON CONFLICT(project_id, candidate_kind, candidate_id) DO UPDATE SET
|
|
8183
|
+
title = excluded.title,
|
|
8184
|
+
summary = excluded.summary,
|
|
8185
|
+
entity_name = excluded.entity_name,
|
|
8186
|
+
source_kind = excluded.source_kind,
|
|
8187
|
+
source_ref = excluded.source_ref,
|
|
8188
|
+
locator = excluded.locator,
|
|
8189
|
+
captured_hash = excluded.captured_hash,
|
|
8190
|
+
session_id = excluded.session_id,
|
|
8191
|
+
status = excluded.status,
|
|
8192
|
+
freshness = 'current',
|
|
8193
|
+
stale_reason = NULL,
|
|
8194
|
+
files_json = excluded.files_json,
|
|
8195
|
+
related_entities_json = excluded.related_entities_json,
|
|
8196
|
+
updated_at = excluded.updated_at
|
|
8197
|
+
`).run(
|
|
8198
|
+
card.id,
|
|
8199
|
+
card.projectId,
|
|
8200
|
+
card.candidateKind,
|
|
8201
|
+
card.candidateId,
|
|
8202
|
+
card.title,
|
|
8203
|
+
card.summary,
|
|
8204
|
+
card.entityName ?? null,
|
|
8205
|
+
card.sourceKind,
|
|
8206
|
+
card.sourceRef,
|
|
8207
|
+
card.locator ?? null,
|
|
8208
|
+
card.capturedHash ?? null,
|
|
8209
|
+
card.sessionId ?? null,
|
|
8210
|
+
card.status,
|
|
8211
|
+
card.verification,
|
|
8212
|
+
card.freshness,
|
|
8213
|
+
JSON.stringify(card.files),
|
|
8214
|
+
JSON.stringify(card.relatedEntities),
|
|
8215
|
+
card.createdAt,
|
|
8216
|
+
card.updatedAt
|
|
8217
|
+
);
|
|
8218
|
+
return this.get(card.projectId, card.candidateKind, card.candidateId) ?? card;
|
|
8219
|
+
}
|
|
8220
|
+
get(projectId, candidateKind, candidateId) {
|
|
8221
|
+
const row = this.requireDb().prepare(`
|
|
8222
|
+
SELECT * FROM evidence_cards WHERE project_id = ? AND candidate_kind = ? AND candidate_id = ?
|
|
8223
|
+
`).get(projectId, candidateKind, candidateId);
|
|
8224
|
+
return row ? rowToCard(row) : void 0;
|
|
8225
|
+
}
|
|
8226
|
+
list(projectId, options = {}) {
|
|
8227
|
+
const limit2 = Math.min(100, Math.max(1, Math.floor(options.limit ?? 20)));
|
|
8228
|
+
const clauses = ["project_id = ?"];
|
|
8229
|
+
const args = [projectId];
|
|
8230
|
+
if (options.freshness) {
|
|
8231
|
+
clauses.push("freshness = ?");
|
|
8232
|
+
args.push(options.freshness);
|
|
8233
|
+
}
|
|
8234
|
+
if (options.status) {
|
|
8235
|
+
clauses.push("status = ?");
|
|
8236
|
+
args.push(options.status);
|
|
8237
|
+
}
|
|
8238
|
+
args.push(limit2);
|
|
8239
|
+
const rows = this.requireDb().prepare(`
|
|
8240
|
+
SELECT * FROM evidence_cards WHERE ${clauses.join(" AND ")} ORDER BY updated_at DESC, id DESC LIMIT ?
|
|
8241
|
+
`).all(...args);
|
|
8242
|
+
return rows.map(rowToCard);
|
|
8243
|
+
}
|
|
8244
|
+
syncObservations(observations2) {
|
|
8245
|
+
return observations2.map((observation) => this.upsertObservation(observation));
|
|
8246
|
+
}
|
|
8247
|
+
markStaleForPaths(projectId, paths, reason = "source file changed") {
|
|
8248
|
+
const normalized = new Set(paths.map((value) => value.replace(/\\/g, "/").toLowerCase()));
|
|
8249
|
+
if (normalized.size === 0) return 0;
|
|
8250
|
+
const db2 = this.requireDb();
|
|
8251
|
+
const rows = db2.prepare(`SELECT * FROM evidence_cards WHERE project_id = ? AND freshness != 'stale'`).all(projectId);
|
|
8252
|
+
const update2 = db2.prepare(`
|
|
8253
|
+
UPDATE evidence_cards SET freshness = 'stale', stale_reason = ?, updated_at = ?
|
|
8254
|
+
WHERE id = ?
|
|
8255
|
+
`);
|
|
8256
|
+
let changed = 0;
|
|
8257
|
+
const now3 = (/* @__PURE__ */ new Date()).toISOString();
|
|
8258
|
+
const run = db2.transaction(() => {
|
|
8259
|
+
for (const row of rows) {
|
|
8260
|
+
const files = safeJson(row.files_json, []);
|
|
8261
|
+
if (!files.some((file) => normalized.has(file.replace(/\\/g, "/").toLowerCase()))) continue;
|
|
8262
|
+
update2.run(reason, now3, row.id);
|
|
8263
|
+
changed++;
|
|
8264
|
+
}
|
|
8265
|
+
});
|
|
8266
|
+
run();
|
|
8267
|
+
return changed;
|
|
8268
|
+
}
|
|
8269
|
+
setVerification(projectId, cardId, verification) {
|
|
8270
|
+
this.requireDb().prepare(`
|
|
8271
|
+
UPDATE evidence_cards SET verification = ?, updated_at = ? WHERE project_id = ? AND id = ?
|
|
8272
|
+
`).run(verification, (/* @__PURE__ */ new Date()).toISOString(), projectId, cardId);
|
|
8273
|
+
}
|
|
8274
|
+
recordEvent(projectId, cardId, kind, detail) {
|
|
8275
|
+
const event = {
|
|
8276
|
+
id: randomUUID3(),
|
|
8277
|
+
projectId,
|
|
8278
|
+
cardId,
|
|
8279
|
+
kind,
|
|
8280
|
+
...detail ? { detail: detail.slice(0, 2e3) } : {},
|
|
8281
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
8282
|
+
};
|
|
8283
|
+
this.requireDb().prepare(`
|
|
8284
|
+
INSERT INTO evidence_card_events (id, project_id, card_id, kind, detail, created_at)
|
|
8285
|
+
VALUES (?, ?, ?, ?, ?, ?)
|
|
8286
|
+
`).run(event.id, event.projectId, event.cardId, event.kind, event.detail ?? null, event.createdAt);
|
|
8287
|
+
return event;
|
|
8288
|
+
}
|
|
8289
|
+
listEvents(cardId, limit2 = 50) {
|
|
8290
|
+
const rows = this.requireDb().prepare(`
|
|
8291
|
+
SELECT * FROM evidence_card_events WHERE card_id = ? ORDER BY created_at DESC LIMIT ?
|
|
8292
|
+
`).all(cardId, Math.min(200, Math.max(1, Math.floor(limit2))));
|
|
8293
|
+
return rows.map((row) => ({
|
|
8294
|
+
id: String(row.id),
|
|
8295
|
+
projectId: String(row.project_id),
|
|
8296
|
+
cardId: String(row.card_id),
|
|
8297
|
+
kind: String(row.kind),
|
|
8298
|
+
...row.detail ? { detail: String(row.detail) } : {},
|
|
8299
|
+
createdAt: String(row.created_at)
|
|
8300
|
+
}));
|
|
8301
|
+
}
|
|
8302
|
+
};
|
|
8303
|
+
}
|
|
8304
|
+
});
|
|
8305
|
+
|
|
7984
8306
|
// src/codegraph/ids.ts
|
|
7985
|
-
import { createHash as
|
|
8307
|
+
import { createHash as createHash4 } from "crypto";
|
|
7986
8308
|
function digest(input) {
|
|
7987
|
-
return
|
|
8309
|
+
return createHash4("sha256").update(input).digest("hex").slice(0, 16);
|
|
7988
8310
|
}
|
|
7989
8311
|
function normalizeCodePath(path21) {
|
|
7990
8312
|
return path21.replace(/\\/g, "/").replace(/^\.\//, "").replace(/\/+/g, "/");
|
|
@@ -8019,7 +8341,7 @@ var store_exports = {};
|
|
|
8019
8341
|
__export(store_exports, {
|
|
8020
8342
|
CodeGraphStore: () => CodeGraphStore
|
|
8021
8343
|
});
|
|
8022
|
-
import { randomUUID as
|
|
8344
|
+
import { randomUUID as randomUUID4 } from "crypto";
|
|
8023
8345
|
import { posix as pathPosix } from "path";
|
|
8024
8346
|
function rowToFile(row) {
|
|
8025
8347
|
return {
|
|
@@ -8736,7 +9058,7 @@ var init_store = __esm({
|
|
|
8736
9058
|
* so an interrupted scan cannot be advertised as complete.
|
|
8737
9059
|
*/
|
|
8738
9060
|
recordCodeStateSnapshot(input) {
|
|
8739
|
-
const id =
|
|
9061
|
+
const id = randomUUID4();
|
|
8740
9062
|
let snapshot;
|
|
8741
9063
|
const tx = this.db.transaction(() => {
|
|
8742
9064
|
const previous = this.db.prepare(
|
|
@@ -9068,6 +9390,16 @@ async function bindObservationCodeRefsBestEffort(observation) {
|
|
|
9068
9390
|
} catch {
|
|
9069
9391
|
}
|
|
9070
9392
|
}
|
|
9393
|
+
async function persistEvidenceCard(observation) {
|
|
9394
|
+
if (!projectDir) return;
|
|
9395
|
+
try {
|
|
9396
|
+
const evidence = new EvidenceCardStore();
|
|
9397
|
+
await evidence.init(projectDir);
|
|
9398
|
+
evidence.upsertObservation(observation);
|
|
9399
|
+
} catch (error) {
|
|
9400
|
+
console.error(`[memorix] Evidence card projection failed for obs-${observation.id}: ${error instanceof Error ? error.message : String(error)}`);
|
|
9401
|
+
}
|
|
9402
|
+
}
|
|
9071
9403
|
function queueClaimDerivation(observation) {
|
|
9072
9404
|
const dataDir = projectDir;
|
|
9073
9405
|
const isExplicit = observation.sourceDetail === "explicit";
|
|
@@ -9414,6 +9746,7 @@ async function storeObservation(input) {
|
|
|
9414
9746
|
}
|
|
9415
9747
|
if (!persistedCallbackInvoked) await input.onPersisted?.(observation);
|
|
9416
9748
|
await bindObservationCodeRefsBestEffort(observation);
|
|
9749
|
+
await persistEvidenceCard(observation);
|
|
9417
9750
|
queueObservationQualification(observation);
|
|
9418
9751
|
if (resolveObservationVisibility(observation) === "project") {
|
|
9419
9752
|
queueClaimDerivation(observation);
|
|
@@ -9506,6 +9839,7 @@ async function upsertObservation(existing, input, now3) {
|
|
|
9506
9839
|
await store.update(existing);
|
|
9507
9840
|
}
|
|
9508
9841
|
await bindObservationCodeRefsBestEffort(existing);
|
|
9842
|
+
await persistEvidenceCard(existing);
|
|
9509
9843
|
queueObservationQualification(existing);
|
|
9510
9844
|
if (resolveObservationVisibility(existing) === "project") {
|
|
9511
9845
|
queueClaimDerivation(existing);
|
|
@@ -9639,6 +9973,7 @@ async function resolveObservations(ids, status = "resolved") {
|
|
|
9639
9973
|
await Promise.all(changed.map((observation) => tx.update(observation)));
|
|
9640
9974
|
});
|
|
9641
9975
|
}
|
|
9976
|
+
for (const observation of changed) await persistEvidenceCard(observation);
|
|
9642
9977
|
return { resolved, notFound };
|
|
9643
9978
|
}
|
|
9644
9979
|
function getProjectObservations(projectId) {
|
|
@@ -9976,6 +10311,7 @@ var init_observations = __esm({
|
|
|
9976
10311
|
init_secret_filter();
|
|
9977
10312
|
init_lifecycle();
|
|
9978
10313
|
init_visibility();
|
|
10314
|
+
init_evidence_store();
|
|
9979
10315
|
observations = [];
|
|
9980
10316
|
nextId = 1;
|
|
9981
10317
|
projectDir = null;
|
|
@@ -9993,7 +10329,7 @@ var init_observations = __esm({
|
|
|
9993
10329
|
});
|
|
9994
10330
|
|
|
9995
10331
|
// src/knowledge/workspace-store.ts
|
|
9996
|
-
import { randomUUID as
|
|
10332
|
+
import { randomUUID as randomUUID5 } from "crypto";
|
|
9997
10333
|
function arrayValue(raw) {
|
|
9998
10334
|
if (typeof raw !== "string" || !raw) return [];
|
|
9999
10335
|
try {
|
|
@@ -10134,7 +10470,7 @@ var init_workspace_store = __esm({
|
|
|
10134
10470
|
}
|
|
10135
10471
|
createProposal(input) {
|
|
10136
10472
|
const proposal = {
|
|
10137
|
-
id: input.id ??
|
|
10473
|
+
id: input.id ?? randomUUID5(),
|
|
10138
10474
|
...input,
|
|
10139
10475
|
status: input.status ?? "pending",
|
|
10140
10476
|
createdAt: input.createdAt ?? (/* @__PURE__ */ new Date()).toISOString()
|
|
@@ -10187,13 +10523,13 @@ __export(workspace_exports, {
|
|
|
10187
10523
|
loadKnowledgeWorkspace: () => loadKnowledgeWorkspace,
|
|
10188
10524
|
resolveKnowledgeWorkspaceFile: () => resolveKnowledgeWorkspaceFile
|
|
10189
10525
|
});
|
|
10190
|
-
import { createHash as
|
|
10526
|
+
import { createHash as createHash5 } from "crypto";
|
|
10191
10527
|
import { execFile } from "child_process";
|
|
10192
10528
|
import { promises as fs6 } from "fs";
|
|
10193
10529
|
import path9 from "path";
|
|
10194
10530
|
import { promisify } from "util";
|
|
10195
10531
|
function hash(value) {
|
|
10196
|
-
return
|
|
10532
|
+
return createHash5("sha256").update(value).digest("hex");
|
|
10197
10533
|
}
|
|
10198
10534
|
function workspaceId(projectId, mode) {
|
|
10199
10535
|
return "workspace:" + hash(projectId + ":" + mode).slice(0, 24);
|
|
@@ -10789,7 +11125,7 @@ Respond in JSON only:
|
|
|
10789
11125
|
});
|
|
10790
11126
|
|
|
10791
11127
|
// src/media/media-store.ts
|
|
10792
|
-
import { randomUUID as
|
|
11128
|
+
import { randomUUID as randomUUID6 } from "crypto";
|
|
10793
11129
|
function asOptionalText(value) {
|
|
10794
11130
|
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
10795
11131
|
}
|
|
@@ -10959,7 +11295,7 @@ var init_media_store = __esm({
|
|
|
10959
11295
|
return { asset: this.getAsset(input.projectId, existing.id), deduplicated: true };
|
|
10960
11296
|
}
|
|
10961
11297
|
const asset = {
|
|
10962
|
-
id:
|
|
11298
|
+
id: randomUUID6(),
|
|
10963
11299
|
...input,
|
|
10964
11300
|
createdAt: now3,
|
|
10965
11301
|
updatedAt: now3
|
|
@@ -11039,7 +11375,7 @@ var init_media_store = __esm({
|
|
|
11039
11375
|
`).get(input.assetId, input.observationId ?? null, input.role);
|
|
11040
11376
|
if (existing) return rowToLink(existing);
|
|
11041
11377
|
const link = {
|
|
11042
|
-
id:
|
|
11378
|
+
id: randomUUID6(),
|
|
11043
11379
|
assetId: input.assetId,
|
|
11044
11380
|
projectId: input.projectId,
|
|
11045
11381
|
...input.observationId !== void 0 ? { observationId: input.observationId } : {},
|
|
@@ -11078,7 +11414,7 @@ var init_media_store = __esm({
|
|
|
11078
11414
|
return rowToDerivation(this.db.prepare("SELECT * FROM media_derivations WHERE id = ?").get(existing.id));
|
|
11079
11415
|
}
|
|
11080
11416
|
const derivation = {
|
|
11081
|
-
id:
|
|
11417
|
+
id: randomUUID6(),
|
|
11082
11418
|
...input,
|
|
11083
11419
|
content,
|
|
11084
11420
|
...error ? { error } : {},
|
|
@@ -11165,7 +11501,7 @@ var init_media_store = __esm({
|
|
|
11165
11501
|
createJob(input) {
|
|
11166
11502
|
const now3 = Date.now();
|
|
11167
11503
|
const job = {
|
|
11168
|
-
id:
|
|
11504
|
+
id: randomUUID6(),
|
|
11169
11505
|
projectId: input.projectId,
|
|
11170
11506
|
kind: input.kind,
|
|
11171
11507
|
status: "queued",
|
|
@@ -11327,14 +11663,14 @@ var init_types2 = __esm({
|
|
|
11327
11663
|
});
|
|
11328
11664
|
|
|
11329
11665
|
// src/media/asset-store.ts
|
|
11330
|
-
import { createHash as
|
|
11666
|
+
import { createHash as createHash6, randomUUID as randomUUID7 } from "crypto";
|
|
11331
11667
|
import { copyFile, lstat, mkdir as mkdir3, open, readFile as readFile3, readdir, rename as rename2, rm, stat as stat2, writeFile as writeFile3 } from "fs/promises";
|
|
11332
11668
|
import path10 from "path";
|
|
11333
11669
|
function mediaRoot(dataDir) {
|
|
11334
11670
|
return path10.resolve(dataDir, "media");
|
|
11335
11671
|
}
|
|
11336
11672
|
function projectStorageKey(projectId) {
|
|
11337
|
-
return
|
|
11673
|
+
return createHash6("sha256").update(projectId).digest("hex").slice(0, 16);
|
|
11338
11674
|
}
|
|
11339
11675
|
function validateUnderRoot(root, candidate) {
|
|
11340
11676
|
const resolved = path10.resolve(candidate);
|
|
@@ -11398,7 +11734,7 @@ async function destinationExists(destination) {
|
|
|
11398
11734
|
async function persistBuffer(bytes, destination) {
|
|
11399
11735
|
await mkdir3(path10.dirname(destination), { recursive: true });
|
|
11400
11736
|
if (await destinationExists(destination)) return false;
|
|
11401
|
-
const temporary = `${destination}.${
|
|
11737
|
+
const temporary = `${destination}.${randomUUID7()}.tmp`;
|
|
11402
11738
|
try {
|
|
11403
11739
|
await writeFile3(temporary, bytes, { flag: "wx" });
|
|
11404
11740
|
await rename2(temporary, destination);
|
|
@@ -11443,7 +11779,7 @@ async function importMediaBuffer(input) {
|
|
|
11443
11779
|
if (input.bytes.length === 0) throw new Error("Media import rejects empty payloads");
|
|
11444
11780
|
if (input.bytes.length > maxBytes) throw new Error(`Media payload is too large (${input.bytes.length} bytes; limit ${maxBytes})`);
|
|
11445
11781
|
const detected = detectMedia(input.bytes.subarray(0, 32));
|
|
11446
|
-
const sha256 =
|
|
11782
|
+
const sha256 = createHash6("sha256").update(input.bytes).digest("hex");
|
|
11447
11783
|
return importKnownMedia({
|
|
11448
11784
|
dataDir: input.dataDir,
|
|
11449
11785
|
projectId: input.projectId,
|
|
@@ -11461,7 +11797,7 @@ async function readMediaAsset(dataDir, asset, maxBytes = DEFAULT_MAX_MEDIA_BYTES
|
|
|
11461
11797
|
if (asset.byteSize > maxBytes) throw new Error(`Media asset exceeds read limit (${asset.byteSize} bytes; limit ${maxBytes})`);
|
|
11462
11798
|
const bytes = await readFile3(getMediaAssetPath(dataDir, asset));
|
|
11463
11799
|
if (bytes.length !== asset.byteSize) throw new Error(`Media asset size no longer matches metadata: ${asset.id}`);
|
|
11464
|
-
const sha256 =
|
|
11800
|
+
const sha256 = createHash6("sha256").update(bytes).digest("hex");
|
|
11465
11801
|
if (sha256 !== asset.sha256) throw new Error(`Media asset hash no longer matches metadata: ${asset.id}`);
|
|
11466
11802
|
return bytes;
|
|
11467
11803
|
}
|
|
@@ -64212,7 +64548,7 @@ var require_gaxios = __commonJS({
|
|
|
64212
64548
|
var retry_js_1 = require_retry3();
|
|
64213
64549
|
var stream_1 = __require("stream");
|
|
64214
64550
|
var interceptor_js_1 = require_interceptor();
|
|
64215
|
-
var
|
|
64551
|
+
var randomUUID16 = async () => globalThis.crypto?.randomUUID() || (await import("crypto")).randomUUID();
|
|
64216
64552
|
var HTTP_STATUS_NO_CONTENT = 204;
|
|
64217
64553
|
var Gaxios = class {
|
|
64218
64554
|
agentCache = /* @__PURE__ */ new Map();
|
|
@@ -64485,7 +64821,7 @@ var require_gaxios = __commonJS({
|
|
|
64485
64821
|
*/
|
|
64486
64822
|
["Blob", "File", "FormData"].includes(opts.data?.constructor?.name || "");
|
|
64487
64823
|
if (opts.multipart?.length) {
|
|
64488
|
-
const boundary = await
|
|
64824
|
+
const boundary = await randomUUID16();
|
|
64489
64825
|
preparedHeaders.set("content-type", `multipart/related; boundary=${boundary}`);
|
|
64490
64826
|
opts.body = stream_1.Readable.from(this.getMultipartRequest(opts.multipart, boundary));
|
|
64491
64827
|
} else if (shouldDirectlyPassData) {
|
|
@@ -76712,7 +77048,7 @@ var require_websocket = __commonJS({
|
|
|
76712
77048
|
var http3 = __require("http");
|
|
76713
77049
|
var net = __require("net");
|
|
76714
77050
|
var tls = __require("tls");
|
|
76715
|
-
var { randomBytes, createHash:
|
|
77051
|
+
var { randomBytes, createHash: createHash14 } = __require("crypto");
|
|
76716
77052
|
var { Duplex, Readable: Readable2 } = __require("stream");
|
|
76717
77053
|
var { URL: URL2 } = __require("url");
|
|
76718
77054
|
var PerMessageDeflate2 = require_permessage_deflate();
|
|
@@ -77380,7 +77716,7 @@ var require_websocket = __commonJS({
|
|
|
77380
77716
|
abortHandshake(websocket, socket, "Invalid Upgrade header");
|
|
77381
77717
|
return;
|
|
77382
77718
|
}
|
|
77383
|
-
const digest2 =
|
|
77719
|
+
const digest2 = createHash14("sha1").update(key + GUID).digest("base64");
|
|
77384
77720
|
if (res.headers["sec-websocket-accept"] !== digest2) {
|
|
77385
77721
|
abortHandshake(websocket, socket, "Invalid Sec-WebSocket-Accept header");
|
|
77386
77722
|
return;
|
|
@@ -77752,7 +78088,7 @@ var require_websocket_server = __commonJS({
|
|
|
77752
78088
|
var EventEmitter = __require("events");
|
|
77753
78089
|
var http3 = __require("http");
|
|
77754
78090
|
var { Duplex } = __require("stream");
|
|
77755
|
-
var { createHash:
|
|
78091
|
+
var { createHash: createHash14 } = __require("crypto");
|
|
77756
78092
|
var extension3 = require_extension();
|
|
77757
78093
|
var PerMessageDeflate2 = require_permessage_deflate();
|
|
77758
78094
|
var subprotocol2 = require_subprotocol();
|
|
@@ -78059,7 +78395,7 @@ var require_websocket_server = __commonJS({
|
|
|
78059
78395
|
);
|
|
78060
78396
|
}
|
|
78061
78397
|
if (this._state > RUNNING) return abortHandshake(socket, 503);
|
|
78062
|
-
const digest2 =
|
|
78398
|
+
const digest2 = createHash14("sha1").update(key + GUID).digest("base64");
|
|
78063
78399
|
const headers = [
|
|
78064
78400
|
"HTTP/1.1 101 Switching Protocols",
|
|
78065
78401
|
"Upgrade: websocket",
|
|
@@ -145197,6 +145533,186 @@ var init_audio_jobs = __esm({
|
|
|
145197
145533
|
}
|
|
145198
145534
|
});
|
|
145199
145535
|
|
|
145536
|
+
// src/memory/feedback-model.ts
|
|
145537
|
+
function feedbackWeightMultiplier(weight) {
|
|
145538
|
+
return Math.max(0.35, Math.min(1.4, 0.35 + Math.max(0, Math.min(2, weight)) * 0.525));
|
|
145539
|
+
}
|
|
145540
|
+
var init_feedback_model = __esm({
|
|
145541
|
+
"src/memory/feedback-model.ts"() {
|
|
145542
|
+
"use strict";
|
|
145543
|
+
init_esm_shims();
|
|
145544
|
+
}
|
|
145545
|
+
});
|
|
145546
|
+
|
|
145547
|
+
// src/memory/feedback.ts
|
|
145548
|
+
var feedback_exports = {};
|
|
145549
|
+
__export(feedback_exports, {
|
|
145550
|
+
FEEDBACK_DELTAS: () => FEEDBACK_DELTAS,
|
|
145551
|
+
MemoryFeedbackStore: () => MemoryFeedbackStore,
|
|
145552
|
+
applyMemoryFeedback: () => applyMemoryFeedback,
|
|
145553
|
+
feedbackWeightMultiplier: () => feedbackWeightMultiplier
|
|
145554
|
+
});
|
|
145555
|
+
import { randomUUID as randomUUID8 } from "crypto";
|
|
145556
|
+
function applyMemoryFeedback(current, event) {
|
|
145557
|
+
const delta = event.signal === "revoke" ? 0 : FEEDBACK_DELTAS[event.signal];
|
|
145558
|
+
const weight = Math.max(0, Math.min(2, current.weight + delta));
|
|
145559
|
+
const status = (event.signal === "code-conflict" || event.signal === "user-correction" || event.signal === "weaken") && weight < 0.5 ? "archived" : current.status;
|
|
145560
|
+
return { weight, status, audit: [...current.audit, { ...event }] };
|
|
145561
|
+
}
|
|
145562
|
+
function rowToEvent(row) {
|
|
145563
|
+
return {
|
|
145564
|
+
id: String(row.id),
|
|
145565
|
+
projectId: String(row.project_id),
|
|
145566
|
+
candidateKind: row.candidate_kind,
|
|
145567
|
+
candidateId: String(row.candidate_id),
|
|
145568
|
+
signal: row.signal,
|
|
145569
|
+
...row.observed_at ? { at: String(row.observed_at) } : { at: (/* @__PURE__ */ new Date()).toISOString() },
|
|
145570
|
+
...row.actor ? { actor: String(row.actor) } : {},
|
|
145571
|
+
...row.note ? { note: String(row.note) } : {},
|
|
145572
|
+
...row.source_ref ? { sourceRef: String(row.source_ref) } : {},
|
|
145573
|
+
...row.target_event_id ? { targetEventId: String(row.target_event_id) } : {},
|
|
145574
|
+
delta: Number(row.delta ?? 0)
|
|
145575
|
+
};
|
|
145576
|
+
}
|
|
145577
|
+
var FEEDBACK_DELTAS, MemoryFeedbackStore;
|
|
145578
|
+
var init_feedback = __esm({
|
|
145579
|
+
"src/memory/feedback.ts"() {
|
|
145580
|
+
"use strict";
|
|
145581
|
+
init_esm_shims();
|
|
145582
|
+
init_sqlite_db();
|
|
145583
|
+
init_feedback_model();
|
|
145584
|
+
FEEDBACK_DELTAS = {
|
|
145585
|
+
"user-correction": -0.35,
|
|
145586
|
+
"verification-success": 0.25,
|
|
145587
|
+
"verification-failure": -0.25,
|
|
145588
|
+
"code-change": -0.15,
|
|
145589
|
+
used: 0.1,
|
|
145590
|
+
"not-used": -0.05,
|
|
145591
|
+
"code-conflict": -0.4,
|
|
145592
|
+
strengthen: 0.2,
|
|
145593
|
+
weaken: -0.2
|
|
145594
|
+
};
|
|
145595
|
+
MemoryFeedbackStore = class {
|
|
145596
|
+
db = null;
|
|
145597
|
+
async init(dataDir) {
|
|
145598
|
+
this.db = getDatabase(dataDir);
|
|
145599
|
+
}
|
|
145600
|
+
requireDb() {
|
|
145601
|
+
if (!this.db) throw new Error("MemoryFeedbackStore is not initialized.");
|
|
145602
|
+
return this.db;
|
|
145603
|
+
}
|
|
145604
|
+
loadEvents(projectId, candidateKind, candidateId) {
|
|
145605
|
+
return this.requireDb().prepare(`
|
|
145606
|
+
SELECT * FROM memory_feedback_events
|
|
145607
|
+
WHERE project_id = ? AND candidate_kind = ? AND candidate_id = ?
|
|
145608
|
+
ORDER BY observed_at ASC, rowid ASC
|
|
145609
|
+
`).all(projectId, candidateKind, candidateId).map(rowToEvent);
|
|
145610
|
+
}
|
|
145611
|
+
rebuild(projectId, candidateKind, candidateId) {
|
|
145612
|
+
const events = this.loadEvents(projectId, candidateKind, candidateId);
|
|
145613
|
+
const revoked = new Set(events.filter((event) => event.signal === "revoke" && event.targetEventId).map((event) => event.targetEventId));
|
|
145614
|
+
let state = { weight: 1, status: "active", audit: [] };
|
|
145615
|
+
for (const event of events) {
|
|
145616
|
+
if (event.signal === "revoke" || revoked.has(event.id)) {
|
|
145617
|
+
state.audit.push(event);
|
|
145618
|
+
continue;
|
|
145619
|
+
}
|
|
145620
|
+
state = applyMemoryFeedback(state, event);
|
|
145621
|
+
}
|
|
145622
|
+
this.requireDb().prepare(`
|
|
145623
|
+
INSERT INTO memory_feedback_states (project_id, candidate_kind, candidate_id, weight, lifecycle_status, updated_at)
|
|
145624
|
+
VALUES (?, ?, ?, ?, ?, ?)
|
|
145625
|
+
ON CONFLICT(project_id, candidate_kind, candidate_id) DO UPDATE SET
|
|
145626
|
+
weight = excluded.weight, lifecycle_status = excluded.lifecycle_status, updated_at = excluded.updated_at
|
|
145627
|
+
`).run(projectId, candidateKind, candidateId, state.weight, state.status, (/* @__PURE__ */ new Date()).toISOString());
|
|
145628
|
+
return state;
|
|
145629
|
+
}
|
|
145630
|
+
getState(projectId, candidateKind, candidateId) {
|
|
145631
|
+
const row = this.requireDb().prepare(`
|
|
145632
|
+
SELECT weight, lifecycle_status FROM memory_feedback_states
|
|
145633
|
+
WHERE project_id = ? AND candidate_kind = ? AND candidate_id = ?
|
|
145634
|
+
`).get(projectId, candidateKind, candidateId);
|
|
145635
|
+
if (!row) return { weight: 1, status: "active", audit: [] };
|
|
145636
|
+
return {
|
|
145637
|
+
weight: Number(row.weight ?? 1),
|
|
145638
|
+
status: row.lifecycle_status ?? "active",
|
|
145639
|
+
audit: this.loadEvents(projectId, candidateKind, candidateId)
|
|
145640
|
+
};
|
|
145641
|
+
}
|
|
145642
|
+
listStates(projectId, candidateKind = "observation") {
|
|
145643
|
+
return this.requireDb().prepare(`
|
|
145644
|
+
SELECT candidate_id, weight, lifecycle_status, updated_at
|
|
145645
|
+
FROM memory_feedback_states WHERE project_id = ? AND candidate_kind = ?
|
|
145646
|
+
ORDER BY updated_at DESC
|
|
145647
|
+
`).all(projectId, candidateKind).map((row) => ({
|
|
145648
|
+
candidateId: String(row.candidate_id),
|
|
145649
|
+
weight: Number(row.weight),
|
|
145650
|
+
status: row.lifecycle_status,
|
|
145651
|
+
updatedAt: String(row.updated_at)
|
|
145652
|
+
}));
|
|
145653
|
+
}
|
|
145654
|
+
weights(projectId, candidateKind = "observation") {
|
|
145655
|
+
const states = /* @__PURE__ */ new Map();
|
|
145656
|
+
for (const row of this.listStates(projectId, candidateKind)) {
|
|
145657
|
+
states.set(row.candidateId, this.getState(projectId, candidateKind, row.candidateId));
|
|
145658
|
+
}
|
|
145659
|
+
return states;
|
|
145660
|
+
}
|
|
145661
|
+
record(input) {
|
|
145662
|
+
if (input.signal === "revoke" && !input.targetEventId) {
|
|
145663
|
+
throw new Error("A revoke feedback event requires targetEventId.");
|
|
145664
|
+
}
|
|
145665
|
+
if (input.signal === "revoke") {
|
|
145666
|
+
const target = this.requireDb().prepare(`
|
|
145667
|
+
SELECT 1 FROM memory_feedback_events
|
|
145668
|
+
WHERE id = ? AND project_id = ? AND candidate_kind = ? AND candidate_id = ?
|
|
145669
|
+
`).get(input.targetEventId, input.projectId, input.candidateKind, input.candidateId);
|
|
145670
|
+
if (!target) throw new Error("The feedback event to revoke was not found in the same candidate scope.");
|
|
145671
|
+
}
|
|
145672
|
+
const event = {
|
|
145673
|
+
id: randomUUID8(),
|
|
145674
|
+
projectId: input.projectId,
|
|
145675
|
+
candidateKind: input.candidateKind,
|
|
145676
|
+
candidateId: input.candidateId,
|
|
145677
|
+
signal: input.signal,
|
|
145678
|
+
sourceRef: input.sourceRef,
|
|
145679
|
+
...input.actor ? { actor: input.actor } : {},
|
|
145680
|
+
...input.note ? { note: input.note.slice(0, 2e3) } : {},
|
|
145681
|
+
...input.targetEventId ? { targetEventId: input.targetEventId } : {},
|
|
145682
|
+
at: input.at ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
145683
|
+
delta: input.signal === "revoke" ? 0 : FEEDBACK_DELTAS[input.signal]
|
|
145684
|
+
};
|
|
145685
|
+
this.requireDb().prepare(`
|
|
145686
|
+
INSERT INTO memory_feedback_events (
|
|
145687
|
+
id, project_id, candidate_kind, candidate_id, signal, actor, note,
|
|
145688
|
+
source_ref, target_event_id, delta, observed_at
|
|
145689
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
145690
|
+
`).run(
|
|
145691
|
+
event.id,
|
|
145692
|
+
event.projectId,
|
|
145693
|
+
event.candidateKind,
|
|
145694
|
+
event.candidateId,
|
|
145695
|
+
event.signal,
|
|
145696
|
+
event.actor ?? null,
|
|
145697
|
+
event.note ?? null,
|
|
145698
|
+
event.sourceRef,
|
|
145699
|
+
event.targetEventId ?? null,
|
|
145700
|
+
event.delta,
|
|
145701
|
+
event.at
|
|
145702
|
+
);
|
|
145703
|
+
return { event, state: this.rebuild(input.projectId, input.candidateKind, input.candidateId) };
|
|
145704
|
+
}
|
|
145705
|
+
audit(projectId, candidateKind, candidateId, limit2 = 100) {
|
|
145706
|
+
return this.requireDb().prepare(`
|
|
145707
|
+
SELECT * FROM memory_feedback_events
|
|
145708
|
+
WHERE project_id = ? AND candidate_kind = ? AND candidate_id = ?
|
|
145709
|
+
ORDER BY observed_at DESC, rowid DESC LIMIT ?
|
|
145710
|
+
`).all(projectId, candidateKind, candidateId, Math.min(200, Math.max(1, Math.floor(limit2)))).map(rowToEvent);
|
|
145711
|
+
}
|
|
145712
|
+
};
|
|
145713
|
+
}
|
|
145714
|
+
});
|
|
145715
|
+
|
|
145200
145716
|
// src/memory/retention.ts
|
|
145201
145717
|
var retention_exports = {};
|
|
145202
145718
|
__export(retention_exports, {
|
|
@@ -145238,6 +145754,7 @@ function getEffectiveRetentionDays(doc) {
|
|
|
145238
145754
|
}
|
|
145239
145755
|
function isImmune(doc) {
|
|
145240
145756
|
if (doc.type === "probe") return false;
|
|
145757
|
+
if (doc.feedbackStatus === "archived") return false;
|
|
145241
145758
|
if (doc.admissionState === "candidate" || doc.admissionState === "ephemeral") return false;
|
|
145242
145759
|
if (doc.valueCategory === "core") return true;
|
|
145243
145760
|
const importance = getImportanceLevel(doc);
|
|
@@ -145270,7 +145787,8 @@ function calculateRelevance(doc, referenceTime) {
|
|
|
145270
145787
|
const decayFactor = Math.exp(-ageDays / retention);
|
|
145271
145788
|
const accessCount = doc.accessCount ?? 0;
|
|
145272
145789
|
const accessBoost = Math.min(2, 1 + 0.1 * accessCount);
|
|
145273
|
-
|
|
145790
|
+
const feedbackMultiplier = doc.feedbackWeight === void 0 ? 1 : feedbackWeightMultiplier(doc.feedbackWeight);
|
|
145791
|
+
let totalScore = base * decayFactor * accessBoost * feedbackMultiplier;
|
|
145274
145792
|
const immune = isImmune(doc);
|
|
145275
145793
|
if (immune) {
|
|
145276
145794
|
totalScore = Math.max(totalScore, 0.5);
|
|
@@ -145282,7 +145800,8 @@ function calculateRelevance(doc, referenceTime) {
|
|
|
145282
145800
|
decayFactor,
|
|
145283
145801
|
accessBoost,
|
|
145284
145802
|
ageDays,
|
|
145285
|
-
isImmune: immune
|
|
145803
|
+
isImmune: immune,
|
|
145804
|
+
feedbackMultiplier
|
|
145286
145805
|
};
|
|
145287
145806
|
}
|
|
145288
145807
|
function rankByRelevance(docs, referenceTime) {
|
|
@@ -145290,6 +145809,7 @@ function rankByRelevance(docs, referenceTime) {
|
|
|
145290
145809
|
}
|
|
145291
145810
|
function getRetentionZone(doc, referenceTime) {
|
|
145292
145811
|
const now3 = referenceTime ?? /* @__PURE__ */ new Date();
|
|
145812
|
+
if (doc.feedbackStatus === "archived") return "archive-candidate";
|
|
145293
145813
|
const importance = getImportanceLevel(doc);
|
|
145294
145814
|
const retention = getEffectiveRetentionDays(doc);
|
|
145295
145815
|
const createdAt = new Date(doc.createdAt);
|
|
@@ -145361,7 +145881,7 @@ function explainRetention(doc, referenceTime) {
|
|
|
145361
145881
|
summary: parts.join(" ; ")
|
|
145362
145882
|
};
|
|
145363
145883
|
}
|
|
145364
|
-
function toRetentionDocument(obs, accessMap) {
|
|
145884
|
+
function toRetentionDocument(obs, accessMap, feedback) {
|
|
145365
145885
|
const access2 = accessMap?.get(obs.id);
|
|
145366
145886
|
return {
|
|
145367
145887
|
id: `obs-${obs.id}`,
|
|
@@ -145383,11 +145903,12 @@ function toRetentionDocument(obs, accessMap) {
|
|
|
145383
145903
|
sourceDetail: obs.sourceDetail ?? "",
|
|
145384
145904
|
valueCategory: obs.valueCategory ?? "",
|
|
145385
145905
|
admissionState: obs.admissionState ?? "",
|
|
145386
|
-
admissionReason: obs.admissionReason ?? ""
|
|
145906
|
+
admissionReason: obs.admissionReason ?? "",
|
|
145907
|
+
...feedback ? { feedbackWeight: feedback.weight, feedbackStatus: feedback.status } : {}
|
|
145387
145908
|
};
|
|
145388
145909
|
}
|
|
145389
145910
|
function projectObservationRetention(observation, options = {}) {
|
|
145390
|
-
const document2 = toRetentionDocument(observation, options.accessMap);
|
|
145911
|
+
const document2 = toRetentionDocument(observation, options.accessMap, options.feedback);
|
|
145391
145912
|
const relevance = calculateRelevance(document2, options.referenceTime);
|
|
145392
145913
|
const explanation = explainRetention(document2, options.referenceTime);
|
|
145393
145914
|
return {
|
|
@@ -145412,7 +145933,17 @@ function summarizeRetentionProjections(projections) {
|
|
|
145412
145933
|
}
|
|
145413
145934
|
return { active, stale, archiveCandidates, immune };
|
|
145414
145935
|
}
|
|
145415
|
-
async function
|
|
145936
|
+
async function loadFeedbackStore(dataDir) {
|
|
145937
|
+
try {
|
|
145938
|
+
const { MemoryFeedbackStore: MemoryFeedbackStore2 } = await Promise.resolve().then(() => (init_feedback(), feedback_exports));
|
|
145939
|
+
const store = new MemoryFeedbackStore2();
|
|
145940
|
+
await store.init(dataDir);
|
|
145941
|
+
return store;
|
|
145942
|
+
} catch {
|
|
145943
|
+
return void 0;
|
|
145944
|
+
}
|
|
145945
|
+
}
|
|
145946
|
+
async function archiveExpiredBatch(projectDir2, options) {
|
|
145416
145947
|
const store = getObservationStore();
|
|
145417
145948
|
const limit2 = Math.min(500, Math.max(1, Math.floor(options.limit ?? 100)));
|
|
145418
145949
|
const afterId = Math.max(0, Math.floor(options.afterId ?? 0));
|
|
@@ -145421,11 +145952,13 @@ async function archiveExpiredBatch(_projectDir, options) {
|
|
|
145421
145952
|
afterId,
|
|
145422
145953
|
limit: limit2 + 1
|
|
145423
145954
|
});
|
|
145955
|
+
const feedback = await loadFeedbackStore(projectDir2);
|
|
145424
145956
|
const hasMore = page.length > limit2;
|
|
145425
145957
|
const scanned = hasMore ? page.slice(0, limit2) : page;
|
|
145426
145958
|
const candidateIds = scanned.filter((observation) => !options.reader || canManageObservation(observation, options.reader)).filter((observation) => projectObservationRetention(observation, {
|
|
145427
145959
|
accessMap: options.accessMap,
|
|
145428
|
-
referenceTime: options.referenceTime
|
|
145960
|
+
referenceTime: options.referenceTime,
|
|
145961
|
+
...feedback ? { feedback: feedback.getState(options.projectId, "observation", String(observation.id)) } : {}
|
|
145429
145962
|
}).zone === "archive-candidate").map((observation) => observation.id);
|
|
145430
145963
|
const archived = candidateIds.length === 0 ? 0 : await store.atomic(async (tx) => {
|
|
145431
145964
|
const updates = await Promise.all(
|
|
@@ -145456,6 +145989,7 @@ async function archiveExpired(projectDir2, referenceTime, accessMap, projectId,
|
|
|
145456
145989
|
const remaining = reader ? remainingObservations.filter((observation) => canManageObservation(observation, reader)).length : remainingObservations.length;
|
|
145457
145990
|
return { archived, remaining };
|
|
145458
145991
|
}
|
|
145992
|
+
const feedback = await loadFeedbackStore(projectDir2);
|
|
145459
145993
|
return await store.atomic(async (tx) => {
|
|
145460
145994
|
const allObs = await tx.loadAll();
|
|
145461
145995
|
const activeObs = allObs.filter(
|
|
@@ -145463,7 +145997,11 @@ async function archiveExpired(projectDir2, referenceTime, accessMap, projectId,
|
|
|
145463
145997
|
);
|
|
145464
145998
|
const archivedIds = [];
|
|
145465
145999
|
for (const obs of activeObs) {
|
|
145466
|
-
const retention = projectObservationRetention(obs, {
|
|
146000
|
+
const retention = projectObservationRetention(obs, {
|
|
146001
|
+
accessMap,
|
|
146002
|
+
referenceTime,
|
|
146003
|
+
...feedback ? { feedback: feedback.getState(obs.projectId, "observation", String(obs.id)) } : {}
|
|
146004
|
+
});
|
|
145467
146005
|
if (retention.zone === "archive-candidate") {
|
|
145468
146006
|
archivedIds.push(obs.id);
|
|
145469
146007
|
}
|
|
@@ -145483,6 +146021,7 @@ var init_retention = __esm({
|
|
|
145483
146021
|
init_esm_shims();
|
|
145484
146022
|
init_obs_store();
|
|
145485
146023
|
init_visibility();
|
|
146024
|
+
init_feedback_model();
|
|
145486
146025
|
RETENTION_DAYS = {
|
|
145487
146026
|
critical: 365,
|
|
145488
146027
|
high: 180,
|
|
@@ -145519,7 +146058,7 @@ var init_retention = __esm({
|
|
|
145519
146058
|
});
|
|
145520
146059
|
|
|
145521
146060
|
// src/memory/owner.ts
|
|
145522
|
-
import { randomUUID as
|
|
146061
|
+
import { randomUUID as randomUUID9 } from "crypto";
|
|
145523
146062
|
import { promises as fs9 } from "fs";
|
|
145524
146063
|
import path16 from "path";
|
|
145525
146064
|
function ownerPath(dataDir) {
|
|
@@ -145549,7 +146088,7 @@ async function resolveLocalMemoryOwner(dataDir, options = {}) {
|
|
|
145549
146088
|
await fs9.mkdir(path16.dirname(filePath), { recursive: true });
|
|
145550
146089
|
const created = {
|
|
145551
146090
|
version: 1,
|
|
145552
|
-
id: "local-" +
|
|
146091
|
+
id: "local-" + randomUUID9(),
|
|
145553
146092
|
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
145554
146093
|
};
|
|
145555
146094
|
try {
|
|
@@ -145572,7 +146111,7 @@ var init_owner = __esm({
|
|
|
145572
146111
|
});
|
|
145573
146112
|
|
|
145574
146113
|
// src/memory/long-term-store.ts
|
|
145575
|
-
import { randomUUID as
|
|
146114
|
+
import { randomUUID as randomUUID10 } from "crypto";
|
|
145576
146115
|
function optionalText2(value) {
|
|
145577
146116
|
return typeof value === "string" && value.trim() ? value : void 0;
|
|
145578
146117
|
}
|
|
@@ -145623,7 +146162,7 @@ function rowToEvidence(row) {
|
|
|
145623
146162
|
createdAt: row.createdAt
|
|
145624
146163
|
};
|
|
145625
146164
|
}
|
|
145626
|
-
function
|
|
146165
|
+
function rowToEvent2(row) {
|
|
145627
146166
|
return {
|
|
145628
146167
|
id: row.id,
|
|
145629
146168
|
memoryId: row.memoryId,
|
|
@@ -145732,7 +146271,7 @@ var init_long_term_store = __esm({
|
|
|
145732
146271
|
}
|
|
145733
146272
|
insertEvidence(input) {
|
|
145734
146273
|
const evidence = {
|
|
145735
|
-
id:
|
|
146274
|
+
id: randomUUID10(),
|
|
145736
146275
|
...input,
|
|
145737
146276
|
createdAt: input.createdAt ?? (/* @__PURE__ */ new Date()).toISOString()
|
|
145738
146277
|
};
|
|
@@ -145759,7 +146298,7 @@ var init_long_term_store = __esm({
|
|
|
145759
146298
|
}
|
|
145760
146299
|
recordEvent(input) {
|
|
145761
146300
|
const event = {
|
|
145762
|
-
id:
|
|
146301
|
+
id: randomUUID10(),
|
|
145763
146302
|
...input,
|
|
145764
146303
|
createdAt: input.createdAt ?? (/* @__PURE__ */ new Date()).toISOString()
|
|
145765
146304
|
};
|
|
@@ -145780,7 +146319,7 @@ var init_long_term_store = __esm({
|
|
|
145780
146319
|
listEvents(memoryId) {
|
|
145781
146320
|
return this.db.prepare(`
|
|
145782
146321
|
SELECT * FROM long_term_memory_events WHERE memoryId = ? ORDER BY createdAt ASC, rowid ASC
|
|
145783
|
-
`).all(memoryId).map(
|
|
146322
|
+
`).all(memoryId).map(rowToEvent2);
|
|
145784
146323
|
}
|
|
145785
146324
|
markAccess(ids, at = (/* @__PURE__ */ new Date()).toISOString()) {
|
|
145786
146325
|
const unique = [...new Set(ids.filter(Boolean))];
|
|
@@ -145849,7 +146388,7 @@ __export(long_term_exports, {
|
|
|
145849
146388
|
selectLongTermMemoriesForTask: () => selectLongTermMemoriesForTask,
|
|
145850
146389
|
supersedeLongTermMemory: () => supersedeLongTermMemory
|
|
145851
146390
|
});
|
|
145852
|
-
import { randomUUID as
|
|
146391
|
+
import { randomUUID as randomUUID11 } from "crypto";
|
|
145853
146392
|
function isOneOf(value, values) {
|
|
145854
146393
|
return typeof value === "string" && values.includes(value);
|
|
145855
146394
|
}
|
|
@@ -146031,7 +146570,7 @@ async function createManualLongTermMemory(input) {
|
|
|
146031
146570
|
const owner = await resolveLocalMemoryOwner(input.dataDir, { create: true });
|
|
146032
146571
|
if (!owner) throw new Error("Memorix could not resolve a local memory owner.");
|
|
146033
146572
|
assertScope(input.scope);
|
|
146034
|
-
const evidence = input.scope === "user" ? [{ kind: "user", referenceId: owner.id, relation: "user-confirmed" }] : [{ kind: "manual", referenceId: "manual:" +
|
|
146573
|
+
const evidence = input.scope === "user" ? [{ kind: "user", referenceId: owner.id, relation: "user-confirmed" }] : [{ kind: "manual", referenceId: "manual:" + randomUUID11(), relation: "supports" }];
|
|
146035
146574
|
return createLongTermMemoryWithDataDir({
|
|
146036
146575
|
dataDir: input.dataDir,
|
|
146037
146576
|
originProjectId: input.projectId,
|
|
@@ -146086,7 +146625,7 @@ async function createLongTermMemoryWithDataDir(input) {
|
|
|
146086
146625
|
assertPortableEvidence(input.scope, portability, evidenceInputs);
|
|
146087
146626
|
const now3 = (/* @__PURE__ */ new Date()).toISOString();
|
|
146088
146627
|
const memory = {
|
|
146089
|
-
id:
|
|
146628
|
+
id: randomUUID11(),
|
|
146090
146629
|
originProjectId: compactText(input.originProjectId, "origin project id", 1e3),
|
|
146091
146630
|
ownerId: compactText(input.ownerId, "owner id", 160),
|
|
146092
146631
|
scope: input.scope,
|
|
@@ -146405,7 +146944,7 @@ var init_long_term = __esm({
|
|
|
146405
146944
|
|
|
146406
146945
|
// src/codegraph/code-state.ts
|
|
146407
146946
|
import { execFile as execFile2 } from "child_process";
|
|
146408
|
-
import { createHash as
|
|
146947
|
+
import { createHash as createHash7 } from "crypto";
|
|
146409
146948
|
import { promisify as promisify3 } from "util";
|
|
146410
146949
|
async function runGit(rootPath, args) {
|
|
146411
146950
|
try {
|
|
@@ -146434,7 +146973,7 @@ function changedPathCount(status) {
|
|
|
146434
146973
|
return count2;
|
|
146435
146974
|
}
|
|
146436
146975
|
function fingerprint(baseRevision, status) {
|
|
146437
|
-
return
|
|
146976
|
+
return createHash7("sha256").update(baseRevision ?? "").update("\0").update(status).digest("hex");
|
|
146438
146977
|
}
|
|
146439
146978
|
async function collectCodeStateSnapshot(input) {
|
|
146440
146979
|
const [revision, status] = await Promise.all([
|
|
@@ -146534,11 +147073,11 @@ __export(lite_provider_exports, {
|
|
|
146534
147073
|
indexProjectLite: () => indexProjectLite,
|
|
146535
147074
|
refreshProjectLite: () => refreshProjectLite
|
|
146536
147075
|
});
|
|
146537
|
-
import { createHash as
|
|
147076
|
+
import { createHash as createHash8 } from "crypto";
|
|
146538
147077
|
import { readdirSync as readdirSync2, readFileSync as readFileSync7, statSync as statSync3 } from "fs";
|
|
146539
147078
|
import { join as join4, relative } from "path";
|
|
146540
147079
|
function hashText(text2) {
|
|
146541
|
-
return
|
|
147080
|
+
return createHash8("sha256").update(text2).digest("hex");
|
|
146542
147081
|
}
|
|
146543
147082
|
function extension2(path21) {
|
|
146544
147083
|
const index = path21.lastIndexOf(".");
|
|
@@ -146948,7 +147487,7 @@ var claim_store_exports = {};
|
|
|
146948
147487
|
__export(claim_store_exports, {
|
|
146949
147488
|
ClaimStore: () => ClaimStore
|
|
146950
147489
|
});
|
|
146951
|
-
import { createHash as
|
|
147490
|
+
import { createHash as createHash9, randomUUID as randomUUID12 } from "crypto";
|
|
146952
147491
|
function optionalText3(value) {
|
|
146953
147492
|
return typeof value === "string" && value ? value : void 0;
|
|
146954
147493
|
}
|
|
@@ -146987,7 +147526,7 @@ function rowToEvidence2(row) {
|
|
|
146987
147526
|
createdAt: row.createdAt
|
|
146988
147527
|
};
|
|
146989
147528
|
}
|
|
146990
|
-
function
|
|
147529
|
+
function rowToEvent3(row) {
|
|
146991
147530
|
return {
|
|
146992
147531
|
id: row.id,
|
|
146993
147532
|
projectId: row.projectId,
|
|
@@ -147001,7 +147540,7 @@ function rowToEvent2(row) {
|
|
|
147001
147540
|
};
|
|
147002
147541
|
}
|
|
147003
147542
|
function evidenceKey(input) {
|
|
147004
|
-
return
|
|
147543
|
+
return createHash9("sha256").update(JSON.stringify([
|
|
147005
147544
|
input.evidenceKind,
|
|
147006
147545
|
input.evidenceId,
|
|
147007
147546
|
input.relation,
|
|
@@ -147132,7 +147671,7 @@ var init_claim_store = __esm({
|
|
|
147132
147671
|
locator, capturedHash, evidenceKey, createdAt
|
|
147133
147672
|
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
147134
147673
|
`).run(
|
|
147135
|
-
|
|
147674
|
+
randomUUID12(),
|
|
147136
147675
|
input.claimId,
|
|
147137
147676
|
input.evidenceKind,
|
|
147138
147677
|
input.evidenceId,
|
|
@@ -147154,7 +147693,7 @@ var init_claim_store = __esm({
|
|
|
147154
147693
|
}
|
|
147155
147694
|
recordEvent(input) {
|
|
147156
147695
|
const event = {
|
|
147157
|
-
id:
|
|
147696
|
+
id: randomUUID12(),
|
|
147158
147697
|
...input,
|
|
147159
147698
|
...input.detail ? { detail: sanitizeCredentials(input.detail) } : {},
|
|
147160
147699
|
createdAt: input.createdAt ?? (/* @__PURE__ */ new Date()).toISOString()
|
|
@@ -147182,7 +147721,7 @@ var init_claim_store = __esm({
|
|
|
147182
147721
|
SELECT * FROM knowledge_claim_events
|
|
147183
147722
|
WHERE claimId = ?
|
|
147184
147723
|
ORDER BY createdAt ASC, id
|
|
147185
|
-
`).all(claimId).map(
|
|
147724
|
+
`).all(claimId).map(rowToEvent3);
|
|
147186
147725
|
}
|
|
147187
147726
|
};
|
|
147188
147727
|
}
|
|
@@ -147199,7 +147738,7 @@ __export(claims_exports, {
|
|
|
147199
147738
|
supersedeClaim: () => supersedeClaim,
|
|
147200
147739
|
writeClaim: () => writeClaim
|
|
147201
147740
|
});
|
|
147202
|
-
import { createHash as
|
|
147741
|
+
import { createHash as createHash10, randomUUID as randomUUID13 } from "crypto";
|
|
147203
147742
|
function compactText2(value, field) {
|
|
147204
147743
|
if (typeof value !== "string") throw new Error("Claim " + field + " must be text");
|
|
147205
147744
|
const sanitized = sanitizeCredentials(value).trim().replace(/\s+/g, " ");
|
|
@@ -147211,7 +147750,7 @@ function normalizedTerm(value) {
|
|
|
147211
147750
|
return compactText2(value, "identity").toLocaleLowerCase("en-US");
|
|
147212
147751
|
}
|
|
147213
147752
|
function hashIdentity(parts) {
|
|
147214
|
-
return
|
|
147753
|
+
return createHash10("sha256").update(parts.join(String.fromCharCode(31))).digest("hex");
|
|
147215
147754
|
}
|
|
147216
147755
|
function buildClaimIdentity(input) {
|
|
147217
147756
|
const subject = normalizedTerm(input.subject);
|
|
@@ -147285,7 +147824,7 @@ function normalizeClaimInput(input) {
|
|
|
147285
147824
|
const now3 = (/* @__PURE__ */ new Date()).toISOString();
|
|
147286
147825
|
return {
|
|
147287
147826
|
claim: {
|
|
147288
|
-
id:
|
|
147827
|
+
id: randomUUID13(),
|
|
147289
147828
|
projectId,
|
|
147290
147829
|
subject,
|
|
147291
147830
|
predicate,
|
|
@@ -147452,7 +147991,7 @@ function supersedeClaim(store, input) {
|
|
|
147452
147991
|
});
|
|
147453
147992
|
}
|
|
147454
147993
|
function hashObservation(observation) {
|
|
147455
|
-
return
|
|
147994
|
+
return createHash10("sha256").update(JSON.stringify([
|
|
147456
147995
|
observation.title,
|
|
147457
147996
|
observation.narrative,
|
|
147458
147997
|
observation.facts,
|
|
@@ -147696,11 +148235,11 @@ var init_frontmatter = __esm({
|
|
|
147696
148235
|
});
|
|
147697
148236
|
|
|
147698
148237
|
// src/knowledge/markdown.ts
|
|
147699
|
-
import { createHash as
|
|
148238
|
+
import { createHash as createHash11 } from "crypto";
|
|
147700
148239
|
import { promises as fs10 } from "fs";
|
|
147701
148240
|
import path17 from "path";
|
|
147702
148241
|
function hashContent(content) {
|
|
147703
|
-
return
|
|
148242
|
+
return createHash11("sha256").update(content).digest("hex");
|
|
147704
148243
|
}
|
|
147705
148244
|
function stringField(data, key) {
|
|
147706
148245
|
const value = data[key];
|
|
@@ -147826,11 +148365,11 @@ __export(wiki_exports, {
|
|
|
147826
148365
|
lintKnowledgeWorkspace: () => lintKnowledgeWorkspace,
|
|
147827
148366
|
readKnowledgePage: () => readKnowledgePage
|
|
147828
148367
|
});
|
|
147829
|
-
import { createHash as
|
|
148368
|
+
import { createHash as createHash12 } from "crypto";
|
|
147830
148369
|
import { promises as fs11 } from "fs";
|
|
147831
148370
|
import path18 from "path";
|
|
147832
148371
|
function hash2(value) {
|
|
147833
|
-
return
|
|
148372
|
+
return createHash12("sha256").update(value).digest("hex");
|
|
147834
148373
|
}
|
|
147835
148374
|
function now() {
|
|
147836
148375
|
return (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -148370,7 +148909,7 @@ var init_workflow_sync = __esm({
|
|
|
148370
148909
|
});
|
|
148371
148910
|
|
|
148372
148911
|
// src/knowledge/workflow-store.ts
|
|
148373
|
-
import { randomUUID as
|
|
148912
|
+
import { randomUUID as randomUUID14 } from "crypto";
|
|
148374
148913
|
function parseJson(value, fallback) {
|
|
148375
148914
|
if (typeof value !== "string" || !value) return fallback;
|
|
148376
148915
|
try {
|
|
@@ -148470,7 +149009,7 @@ var init_workflow_store = __esm({
|
|
|
148470
149009
|
}
|
|
148471
149010
|
recordRun(input) {
|
|
148472
149011
|
const run = {
|
|
148473
|
-
id:
|
|
149012
|
+
id: randomUUID14(),
|
|
148474
149013
|
workflowId: input.workflowId,
|
|
148475
149014
|
projectId: input.projectId,
|
|
148476
149015
|
task: input.task.trim(),
|
|
@@ -148538,7 +149077,7 @@ var init_outcome_types = __esm({
|
|
|
148538
149077
|
});
|
|
148539
149078
|
|
|
148540
149079
|
// src/knowledge/outcome-store.ts
|
|
148541
|
-
import { randomUUID as
|
|
149080
|
+
import { randomUUID as randomUUID15 } from "crypto";
|
|
148542
149081
|
function optionalText5(value) {
|
|
148543
149082
|
return typeof value === "string" && value.trim() ? value : void 0;
|
|
148544
149083
|
}
|
|
@@ -148582,7 +149121,7 @@ var init_outcome_store = __esm({
|
|
|
148582
149121
|
}
|
|
148583
149122
|
record(input) {
|
|
148584
149123
|
const signal = {
|
|
148585
|
-
id:
|
|
149124
|
+
id: randomUUID15(),
|
|
148586
149125
|
projectId: text(input.projectId, "project id"),
|
|
148587
149126
|
candidateKind: oneOf(input.candidateKind, MEMORY_OUTCOME_CANDIDATE_KINDS, "candidate kind"),
|
|
148588
149127
|
candidateId: text(input.candidateId, "candidate id"),
|
|
@@ -148687,11 +149226,11 @@ __export(workflows_exports, {
|
|
|
148687
149226
|
syncCanonicalWorkflows: () => syncCanonicalWorkflows,
|
|
148688
149227
|
writeCanonicalWorkflow: () => writeCanonicalWorkflow
|
|
148689
149228
|
});
|
|
148690
|
-
import { createHash as
|
|
149229
|
+
import { createHash as createHash13 } from "crypto";
|
|
148691
149230
|
import { promises as fs12 } from "fs";
|
|
148692
149231
|
import path19 from "path";
|
|
148693
149232
|
function hash3(value) {
|
|
148694
|
-
return
|
|
149233
|
+
return createHash13("sha256").update(value).digest("hex");
|
|
148695
149234
|
}
|
|
148696
149235
|
function now2() {
|
|
148697
149236
|
return (/* @__PURE__ */ new Date()).toISOString();
|