memorix 1.7.3 → 1.8.0
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 +32 -0
- package/README.md +1 -1
- package/README.zh-CN.md +1 -1
- package/dist/cli/index.js +1407 -192
- package/dist/dashboard/static/app.js +88 -4
- package/dist/dashboard/static/index.html +10 -0
- package/dist/dashboard/static/style.css +86 -0
- package/dist/index.js +875 -164
- 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 +32 -0
- package/dist/sdk.js +874 -163
- 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 +37 -1
- package/docs/DASHBOARD.md +10 -0
- package/docs/DEVELOPMENT.md +3 -2
- package/docs/INTEGRATIONS.md +1 -1
- package/docs/README.md +11 -1
- 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/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 +201 -12
- 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 +93 -68
- package/src/dashboard/static/index.html +10 -0
- 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 +121 -1
- 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
|
});
|
|
@@ -488,7 +495,7 @@ function closeAllDatabases() {
|
|
|
488
495
|
_dbCache.delete(key);
|
|
489
496
|
}
|
|
490
497
|
}
|
|
491
|
-
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;
|
|
498
|
+
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;
|
|
492
499
|
var init_sqlite_db = __esm({
|
|
493
500
|
"src/store/sqlite-db.ts"() {
|
|
494
501
|
"use strict";
|
|
@@ -1134,6 +1141,79 @@ CREATE TABLE IF NOT EXISTS compaction_checkpoints (
|
|
|
1134
1141
|
created_at TEXT NOT NULL,
|
|
1135
1142
|
updated_at TEXT NOT NULL
|
|
1136
1143
|
);
|
|
1144
|
+
`;
|
|
1145
|
+
CREATE_EVIDENCE_CARDS_TABLE = `
|
|
1146
|
+
CREATE TABLE IF NOT EXISTS evidence_cards (
|
|
1147
|
+
id TEXT PRIMARY KEY,
|
|
1148
|
+
project_id TEXT NOT NULL,
|
|
1149
|
+
candidate_kind TEXT NOT NULL,
|
|
1150
|
+
candidate_id TEXT NOT NULL,
|
|
1151
|
+
title TEXT NOT NULL,
|
|
1152
|
+
summary TEXT NOT NULL DEFAULT '',
|
|
1153
|
+
entity_name TEXT,
|
|
1154
|
+
source_kind TEXT NOT NULL,
|
|
1155
|
+
source_ref TEXT NOT NULL,
|
|
1156
|
+
locator TEXT,
|
|
1157
|
+
captured_hash TEXT,
|
|
1158
|
+
session_id TEXT,
|
|
1159
|
+
status TEXT NOT NULL DEFAULT 'active',
|
|
1160
|
+
verification TEXT NOT NULL DEFAULT 'unverified',
|
|
1161
|
+
freshness TEXT NOT NULL DEFAULT 'current',
|
|
1162
|
+
stale_reason TEXT,
|
|
1163
|
+
files_json TEXT NOT NULL DEFAULT '[]',
|
|
1164
|
+
related_entities_json TEXT NOT NULL DEFAULT '[]',
|
|
1165
|
+
created_at TEXT NOT NULL,
|
|
1166
|
+
updated_at TEXT NOT NULL,
|
|
1167
|
+
UNIQUE(project_id, candidate_kind, candidate_id)
|
|
1168
|
+
);
|
|
1169
|
+
`;
|
|
1170
|
+
CREATE_EVIDENCE_CARD_EVENTS_TABLE = `
|
|
1171
|
+
CREATE TABLE IF NOT EXISTS evidence_card_events (
|
|
1172
|
+
id TEXT PRIMARY KEY,
|
|
1173
|
+
project_id TEXT NOT NULL,
|
|
1174
|
+
card_id TEXT NOT NULL,
|
|
1175
|
+
kind TEXT NOT NULL,
|
|
1176
|
+
detail TEXT,
|
|
1177
|
+
created_at TEXT NOT NULL,
|
|
1178
|
+
FOREIGN KEY (card_id) REFERENCES evidence_cards(id) ON DELETE CASCADE
|
|
1179
|
+
);
|
|
1180
|
+
`;
|
|
1181
|
+
CREATE_MEMORY_FEEDBACK_STATES_TABLE = `
|
|
1182
|
+
CREATE TABLE IF NOT EXISTS memory_feedback_states (
|
|
1183
|
+
project_id TEXT NOT NULL,
|
|
1184
|
+
candidate_kind TEXT NOT NULL,
|
|
1185
|
+
candidate_id TEXT NOT NULL,
|
|
1186
|
+
weight REAL NOT NULL DEFAULT 1.0,
|
|
1187
|
+
lifecycle_status TEXT NOT NULL DEFAULT 'active',
|
|
1188
|
+
updated_at TEXT NOT NULL,
|
|
1189
|
+
PRIMARY KEY (project_id, candidate_kind, candidate_id)
|
|
1190
|
+
);
|
|
1191
|
+
`;
|
|
1192
|
+
CREATE_MEMORY_FEEDBACK_EVENTS_TABLE = `
|
|
1193
|
+
CREATE TABLE IF NOT EXISTS memory_feedback_events (
|
|
1194
|
+
id TEXT PRIMARY KEY,
|
|
1195
|
+
project_id TEXT NOT NULL,
|
|
1196
|
+
candidate_kind TEXT NOT NULL,
|
|
1197
|
+
candidate_id TEXT NOT NULL,
|
|
1198
|
+
signal TEXT NOT NULL,
|
|
1199
|
+
actor TEXT,
|
|
1200
|
+
note TEXT,
|
|
1201
|
+
source_ref TEXT NOT NULL,
|
|
1202
|
+
target_event_id TEXT,
|
|
1203
|
+
delta REAL NOT NULL DEFAULT 0,
|
|
1204
|
+
observed_at TEXT NOT NULL
|
|
1205
|
+
);
|
|
1206
|
+
`;
|
|
1207
|
+
CREATE_MCP_BINDINGS_TABLE = `
|
|
1208
|
+
CREATE TABLE IF NOT EXISTS mcp_bindings (
|
|
1209
|
+
handle_id TEXT PRIMARY KEY,
|
|
1210
|
+
project_id TEXT NOT NULL,
|
|
1211
|
+
project_root TEXT NOT NULL,
|
|
1212
|
+
data_dir TEXT NOT NULL,
|
|
1213
|
+
created_at TEXT NOT NULL,
|
|
1214
|
+
last_used_at TEXT NOT NULL,
|
|
1215
|
+
expires_at TEXT
|
|
1216
|
+
);
|
|
1137
1217
|
`;
|
|
1138
1218
|
CREATE_INDEXES = `
|
|
1139
1219
|
CREATE INDEX IF NOT EXISTS idx_observations_projectId ON observations(projectId);
|
|
@@ -1196,6 +1276,12 @@ CREATE INDEX IF NOT EXISTS idx_maintenance_targets_updated ON maintenance_target
|
|
|
1196
1276
|
CREATE INDEX IF NOT EXISTS idx_compaction_checkpoints_project_recent ON compaction_checkpoints(project_id, status, completed_at DESC, pre_captured_at DESC);
|
|
1197
1277
|
CREATE INDEX IF NOT EXISTS idx_compaction_checkpoints_session_pending ON compaction_checkpoints(project_id, session_id, agent, phase, status, pre_captured_at DESC);
|
|
1198
1278
|
CREATE INDEX IF NOT EXISTS idx_compaction_checkpoints_source ON compaction_checkpoints(project_id, source_key);
|
|
1279
|
+
CREATE INDEX IF NOT EXISTS idx_evidence_cards_project ON evidence_cards(project_id, status, updated_at DESC);
|
|
1280
|
+
CREATE INDEX IF NOT EXISTS idx_evidence_cards_candidate ON evidence_cards(project_id, candidate_kind, candidate_id);
|
|
1281
|
+
CREATE INDEX IF NOT EXISTS idx_evidence_card_events_card ON evidence_card_events(card_id, created_at);
|
|
1282
|
+
CREATE INDEX IF NOT EXISTS idx_memory_feedback_states_project ON memory_feedback_states(project_id, candidate_kind, updated_at DESC);
|
|
1283
|
+
CREATE INDEX IF NOT EXISTS idx_memory_feedback_events_candidate ON memory_feedback_events(project_id, candidate_kind, candidate_id, observed_at DESC);
|
|
1284
|
+
CREATE INDEX IF NOT EXISTS idx_mcp_bindings_project ON mcp_bindings(project_id, last_used_at DESC);
|
|
1199
1285
|
CREATE UNIQUE INDEX IF NOT EXISTS idx_maintenance_jobs_active_dedupe
|
|
1200
1286
|
ON maintenance_jobs(project_id, kind, dedupe_key)
|
|
1201
1287
|
WHERE status IN ('pending', 'running', 'retry');
|
|
@@ -1351,6 +1437,22 @@ CREATE UNIQUE INDEX IF NOT EXISTS idx_maintenance_jobs_active_dedupe
|
|
|
1351
1437
|
}
|
|
1352
1438
|
db2.exec("CREATE INDEX IF NOT EXISTS idx_media_jobs_source_asset ON media_jobs(project_id, source_asset_id, status)");
|
|
1353
1439
|
}
|
|
1440
|
+
},
|
|
1441
|
+
{
|
|
1442
|
+
id: "1.8-context-control-plane",
|
|
1443
|
+
apply: (db2) => {
|
|
1444
|
+
db2.exec(CREATE_EVIDENCE_CARDS_TABLE);
|
|
1445
|
+
db2.exec(CREATE_EVIDENCE_CARD_EVENTS_TABLE);
|
|
1446
|
+
db2.exec(CREATE_MEMORY_FEEDBACK_STATES_TABLE);
|
|
1447
|
+
db2.exec(CREATE_MEMORY_FEEDBACK_EVENTS_TABLE);
|
|
1448
|
+
db2.exec(CREATE_MCP_BINDINGS_TABLE);
|
|
1449
|
+
db2.exec("CREATE INDEX IF NOT EXISTS idx_evidence_cards_project ON evidence_cards(project_id, status, updated_at DESC)");
|
|
1450
|
+
db2.exec("CREATE INDEX IF NOT EXISTS idx_evidence_cards_candidate ON evidence_cards(project_id, candidate_kind, candidate_id)");
|
|
1451
|
+
db2.exec("CREATE INDEX IF NOT EXISTS idx_evidence_card_events_card ON evidence_card_events(card_id, created_at)");
|
|
1452
|
+
db2.exec("CREATE INDEX IF NOT EXISTS idx_memory_feedback_states_project ON memory_feedback_states(project_id, candidate_kind, updated_at DESC)");
|
|
1453
|
+
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)");
|
|
1454
|
+
db2.exec("CREATE INDEX IF NOT EXISTS idx_mcp_bindings_project ON mcp_bindings(project_id, last_used_at DESC)");
|
|
1455
|
+
}
|
|
1354
1456
|
}
|
|
1355
1457
|
];
|
|
1356
1458
|
_dbCache = /* @__PURE__ */ new Map();
|
|
@@ -8463,8 +8565,228 @@ var init_lifecycle = __esm({
|
|
|
8463
8565
|
}
|
|
8464
8566
|
});
|
|
8465
8567
|
|
|
8568
|
+
// src/store/evidence-store.ts
|
|
8569
|
+
import { createHash as createHash3, randomUUID as randomUUID4 } from "crypto";
|
|
8570
|
+
function safeJson(value, fallback) {
|
|
8571
|
+
if (typeof value !== "string" || value.length === 0) return fallback;
|
|
8572
|
+
try {
|
|
8573
|
+
return JSON.parse(value);
|
|
8574
|
+
} catch {
|
|
8575
|
+
return fallback;
|
|
8576
|
+
}
|
|
8577
|
+
}
|
|
8578
|
+
function rowToCard(row) {
|
|
8579
|
+
return {
|
|
8580
|
+
id: String(row.id),
|
|
8581
|
+
projectId: String(row.project_id),
|
|
8582
|
+
candidateKind: row.candidate_kind,
|
|
8583
|
+
candidateId: String(row.candidate_id),
|
|
8584
|
+
title: String(row.title),
|
|
8585
|
+
summary: String(row.summary ?? ""),
|
|
8586
|
+
...row.entity_name ? { entityName: String(row.entity_name) } : {},
|
|
8587
|
+
sourceKind: String(row.source_kind),
|
|
8588
|
+
sourceRef: String(row.source_ref),
|
|
8589
|
+
...row.locator ? { locator: String(row.locator) } : {},
|
|
8590
|
+
...row.captured_hash ? { capturedHash: String(row.captured_hash) } : {},
|
|
8591
|
+
...row.session_id ? { sessionId: String(row.session_id) } : {},
|
|
8592
|
+
status: String(row.status ?? "active"),
|
|
8593
|
+
verification: row.verification,
|
|
8594
|
+
freshness: row.freshness,
|
|
8595
|
+
...row.stale_reason ? { staleReason: String(row.stale_reason) } : {},
|
|
8596
|
+
files: safeJson(row.files_json, []),
|
|
8597
|
+
relatedEntities: safeJson(row.related_entities_json, []),
|
|
8598
|
+
createdAt: String(row.created_at),
|
|
8599
|
+
updatedAt: String(row.updated_at)
|
|
8600
|
+
};
|
|
8601
|
+
}
|
|
8602
|
+
function observationHash(observation) {
|
|
8603
|
+
return createHash3("sha256").update(JSON.stringify({
|
|
8604
|
+
projectId: observation.projectId,
|
|
8605
|
+
id: observation.id,
|
|
8606
|
+
title: observation.title,
|
|
8607
|
+
narrative: observation.narrative,
|
|
8608
|
+
facts: observation.facts,
|
|
8609
|
+
files: observation.filesModified,
|
|
8610
|
+
relatedEntities: observation.relatedEntities
|
|
8611
|
+
})).digest("hex");
|
|
8612
|
+
}
|
|
8613
|
+
function sourceKind(observation) {
|
|
8614
|
+
if (observation.source === "git" || observation.sourceDetail === "git-ingest") return "git";
|
|
8615
|
+
if (observation.sourceDetail === "hook") return "hook";
|
|
8616
|
+
return observation.source ?? "agent";
|
|
8617
|
+
}
|
|
8618
|
+
var EvidenceCardStore;
|
|
8619
|
+
var init_evidence_store = __esm({
|
|
8620
|
+
"src/store/evidence-store.ts"() {
|
|
8621
|
+
"use strict";
|
|
8622
|
+
init_esm_shims();
|
|
8623
|
+
init_sqlite_db();
|
|
8624
|
+
EvidenceCardStore = class {
|
|
8625
|
+
db = null;
|
|
8626
|
+
async init(dataDir) {
|
|
8627
|
+
this.db = getDatabase(dataDir);
|
|
8628
|
+
}
|
|
8629
|
+
requireDb() {
|
|
8630
|
+
if (!this.db) throw new Error("EvidenceCardStore is not initialized.");
|
|
8631
|
+
return this.db;
|
|
8632
|
+
}
|
|
8633
|
+
upsertObservation(observation) {
|
|
8634
|
+
const db2 = this.requireDb();
|
|
8635
|
+
const now3 = (/* @__PURE__ */ new Date()).toISOString();
|
|
8636
|
+
const card = {
|
|
8637
|
+
id: `evidence:observation:${observation.projectId}:${observation.id}`,
|
|
8638
|
+
projectId: observation.projectId,
|
|
8639
|
+
candidateKind: "observation",
|
|
8640
|
+
candidateId: String(observation.id),
|
|
8641
|
+
title: observation.title,
|
|
8642
|
+
summary: observation.narrative.slice(0, 500),
|
|
8643
|
+
entityName: observation.entityName,
|
|
8644
|
+
sourceKind: sourceKind(observation),
|
|
8645
|
+
sourceRef: `observation:${observation.id}`,
|
|
8646
|
+
locator: observation.filesModified?.join(", ") || `observation:${observation.id}`,
|
|
8647
|
+
capturedHash: observationHash(observation),
|
|
8648
|
+
...observation.sessionId ? { sessionId: observation.sessionId } : {},
|
|
8649
|
+
status: observation.status ?? "active",
|
|
8650
|
+
verification: observation.status === "resolved" ? "verified" : "unverified",
|
|
8651
|
+
freshness: "current",
|
|
8652
|
+
files: observation.filesModified ?? [],
|
|
8653
|
+
relatedEntities: observation.relatedEntities ?? [],
|
|
8654
|
+
createdAt: observation.createdAt,
|
|
8655
|
+
updatedAt: now3
|
|
8656
|
+
};
|
|
8657
|
+
db2.prepare(`
|
|
8658
|
+
INSERT INTO evidence_cards (
|
|
8659
|
+
id, project_id, candidate_kind, candidate_id, title, summary, entity_name,
|
|
8660
|
+
source_kind, source_ref, locator, captured_hash, session_id, status,
|
|
8661
|
+
verification, freshness, stale_reason, files_json, related_entities_json,
|
|
8662
|
+
created_at, updated_at
|
|
8663
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NULL, ?, ?, ?, ?)
|
|
8664
|
+
ON CONFLICT(project_id, candidate_kind, candidate_id) DO UPDATE SET
|
|
8665
|
+
title = excluded.title,
|
|
8666
|
+
summary = excluded.summary,
|
|
8667
|
+
entity_name = excluded.entity_name,
|
|
8668
|
+
source_kind = excluded.source_kind,
|
|
8669
|
+
source_ref = excluded.source_ref,
|
|
8670
|
+
locator = excluded.locator,
|
|
8671
|
+
captured_hash = excluded.captured_hash,
|
|
8672
|
+
session_id = excluded.session_id,
|
|
8673
|
+
status = excluded.status,
|
|
8674
|
+
freshness = 'current',
|
|
8675
|
+
stale_reason = NULL,
|
|
8676
|
+
files_json = excluded.files_json,
|
|
8677
|
+
related_entities_json = excluded.related_entities_json,
|
|
8678
|
+
updated_at = excluded.updated_at
|
|
8679
|
+
`).run(
|
|
8680
|
+
card.id,
|
|
8681
|
+
card.projectId,
|
|
8682
|
+
card.candidateKind,
|
|
8683
|
+
card.candidateId,
|
|
8684
|
+
card.title,
|
|
8685
|
+
card.summary,
|
|
8686
|
+
card.entityName ?? null,
|
|
8687
|
+
card.sourceKind,
|
|
8688
|
+
card.sourceRef,
|
|
8689
|
+
card.locator ?? null,
|
|
8690
|
+
card.capturedHash ?? null,
|
|
8691
|
+
card.sessionId ?? null,
|
|
8692
|
+
card.status,
|
|
8693
|
+
card.verification,
|
|
8694
|
+
card.freshness,
|
|
8695
|
+
JSON.stringify(card.files),
|
|
8696
|
+
JSON.stringify(card.relatedEntities),
|
|
8697
|
+
card.createdAt,
|
|
8698
|
+
card.updatedAt
|
|
8699
|
+
);
|
|
8700
|
+
return this.get(card.projectId, card.candidateKind, card.candidateId) ?? card;
|
|
8701
|
+
}
|
|
8702
|
+
get(projectId, candidateKind, candidateId) {
|
|
8703
|
+
const row = this.requireDb().prepare(`
|
|
8704
|
+
SELECT * FROM evidence_cards WHERE project_id = ? AND candidate_kind = ? AND candidate_id = ?
|
|
8705
|
+
`).get(projectId, candidateKind, candidateId);
|
|
8706
|
+
return row ? rowToCard(row) : void 0;
|
|
8707
|
+
}
|
|
8708
|
+
list(projectId, options = {}) {
|
|
8709
|
+
const limit2 = Math.min(100, Math.max(1, Math.floor(options.limit ?? 20)));
|
|
8710
|
+
const clauses = ["project_id = ?"];
|
|
8711
|
+
const args = [projectId];
|
|
8712
|
+
if (options.freshness) {
|
|
8713
|
+
clauses.push("freshness = ?");
|
|
8714
|
+
args.push(options.freshness);
|
|
8715
|
+
}
|
|
8716
|
+
if (options.status) {
|
|
8717
|
+
clauses.push("status = ?");
|
|
8718
|
+
args.push(options.status);
|
|
8719
|
+
}
|
|
8720
|
+
args.push(limit2);
|
|
8721
|
+
const rows = this.requireDb().prepare(`
|
|
8722
|
+
SELECT * FROM evidence_cards WHERE ${clauses.join(" AND ")} ORDER BY updated_at DESC, id DESC LIMIT ?
|
|
8723
|
+
`).all(...args);
|
|
8724
|
+
return rows.map(rowToCard);
|
|
8725
|
+
}
|
|
8726
|
+
syncObservations(observations2) {
|
|
8727
|
+
return observations2.map((observation) => this.upsertObservation(observation));
|
|
8728
|
+
}
|
|
8729
|
+
markStaleForPaths(projectId, paths, reason = "source file changed") {
|
|
8730
|
+
const normalized = new Set(paths.map((value) => value.replace(/\\/g, "/").toLowerCase()));
|
|
8731
|
+
if (normalized.size === 0) return 0;
|
|
8732
|
+
const db2 = this.requireDb();
|
|
8733
|
+
const rows = db2.prepare(`SELECT * FROM evidence_cards WHERE project_id = ? AND freshness != 'stale'`).all(projectId);
|
|
8734
|
+
const update2 = db2.prepare(`
|
|
8735
|
+
UPDATE evidence_cards SET freshness = 'stale', stale_reason = ?, updated_at = ?
|
|
8736
|
+
WHERE id = ?
|
|
8737
|
+
`);
|
|
8738
|
+
let changed = 0;
|
|
8739
|
+
const now3 = (/* @__PURE__ */ new Date()).toISOString();
|
|
8740
|
+
const run = db2.transaction(() => {
|
|
8741
|
+
for (const row of rows) {
|
|
8742
|
+
const files = safeJson(row.files_json, []);
|
|
8743
|
+
if (!files.some((file) => normalized.has(file.replace(/\\/g, "/").toLowerCase()))) continue;
|
|
8744
|
+
update2.run(reason, now3, row.id);
|
|
8745
|
+
changed++;
|
|
8746
|
+
}
|
|
8747
|
+
});
|
|
8748
|
+
run();
|
|
8749
|
+
return changed;
|
|
8750
|
+
}
|
|
8751
|
+
setVerification(projectId, cardId, verification) {
|
|
8752
|
+
this.requireDb().prepare(`
|
|
8753
|
+
UPDATE evidence_cards SET verification = ?, updated_at = ? WHERE project_id = ? AND id = ?
|
|
8754
|
+
`).run(verification, (/* @__PURE__ */ new Date()).toISOString(), projectId, cardId);
|
|
8755
|
+
}
|
|
8756
|
+
recordEvent(projectId, cardId, kind, detail) {
|
|
8757
|
+
const event = {
|
|
8758
|
+
id: randomUUID4(),
|
|
8759
|
+
projectId,
|
|
8760
|
+
cardId,
|
|
8761
|
+
kind,
|
|
8762
|
+
...detail ? { detail: detail.slice(0, 2e3) } : {},
|
|
8763
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
8764
|
+
};
|
|
8765
|
+
this.requireDb().prepare(`
|
|
8766
|
+
INSERT INTO evidence_card_events (id, project_id, card_id, kind, detail, created_at)
|
|
8767
|
+
VALUES (?, ?, ?, ?, ?, ?)
|
|
8768
|
+
`).run(event.id, event.projectId, event.cardId, event.kind, event.detail ?? null, event.createdAt);
|
|
8769
|
+
return event;
|
|
8770
|
+
}
|
|
8771
|
+
listEvents(cardId, limit2 = 50) {
|
|
8772
|
+
const rows = this.requireDb().prepare(`
|
|
8773
|
+
SELECT * FROM evidence_card_events WHERE card_id = ? ORDER BY created_at DESC LIMIT ?
|
|
8774
|
+
`).all(cardId, Math.min(200, Math.max(1, Math.floor(limit2))));
|
|
8775
|
+
return rows.map((row) => ({
|
|
8776
|
+
id: String(row.id),
|
|
8777
|
+
projectId: String(row.project_id),
|
|
8778
|
+
cardId: String(row.card_id),
|
|
8779
|
+
kind: String(row.kind),
|
|
8780
|
+
...row.detail ? { detail: String(row.detail) } : {},
|
|
8781
|
+
createdAt: String(row.created_at)
|
|
8782
|
+
}));
|
|
8783
|
+
}
|
|
8784
|
+
};
|
|
8785
|
+
}
|
|
8786
|
+
});
|
|
8787
|
+
|
|
8466
8788
|
// src/knowledge/workspace-store.ts
|
|
8467
|
-
import { randomUUID as
|
|
8789
|
+
import { randomUUID as randomUUID5 } from "crypto";
|
|
8468
8790
|
function arrayValue(raw) {
|
|
8469
8791
|
if (typeof raw !== "string" || !raw) return [];
|
|
8470
8792
|
try {
|
|
@@ -8605,7 +8927,7 @@ var init_workspace_store = __esm({
|
|
|
8605
8927
|
}
|
|
8606
8928
|
createProposal(input) {
|
|
8607
8929
|
const proposal = {
|
|
8608
|
-
id: input.id ??
|
|
8930
|
+
id: input.id ?? randomUUID5(),
|
|
8609
8931
|
...input,
|
|
8610
8932
|
status: input.status ?? "pending",
|
|
8611
8933
|
createdAt: input.createdAt ?? (/* @__PURE__ */ new Date()).toISOString()
|
|
@@ -8658,13 +8980,13 @@ __export(workspace_exports, {
|
|
|
8658
8980
|
loadKnowledgeWorkspace: () => loadKnowledgeWorkspace,
|
|
8659
8981
|
resolveKnowledgeWorkspaceFile: () => resolveKnowledgeWorkspaceFile
|
|
8660
8982
|
});
|
|
8661
|
-
import { createHash as
|
|
8983
|
+
import { createHash as createHash4 } from "crypto";
|
|
8662
8984
|
import { execFile } from "child_process";
|
|
8663
8985
|
import { promises as fs6 } from "fs";
|
|
8664
8986
|
import path9 from "path";
|
|
8665
8987
|
import { promisify } from "util";
|
|
8666
8988
|
function hash(value) {
|
|
8667
|
-
return
|
|
8989
|
+
return createHash4("sha256").update(value).digest("hex");
|
|
8668
8990
|
}
|
|
8669
8991
|
function workspaceId(projectId, mode) {
|
|
8670
8992
|
return "workspace:" + hash(projectId + ":" + mode).slice(0, 24);
|
|
@@ -9271,14 +9593,14 @@ var init_types2 = __esm({
|
|
|
9271
9593
|
});
|
|
9272
9594
|
|
|
9273
9595
|
// src/media/asset-store.ts
|
|
9274
|
-
import { createHash as
|
|
9596
|
+
import { createHash as createHash5, randomUUID as randomUUID6 } from "crypto";
|
|
9275
9597
|
import { copyFile, lstat, mkdir as mkdir3, open, readFile as readFile3, readdir, rename as rename2, rm, stat as stat2, writeFile as writeFile3 } from "fs/promises";
|
|
9276
9598
|
import path10 from "path";
|
|
9277
9599
|
function mediaRoot(dataDir) {
|
|
9278
9600
|
return path10.resolve(dataDir, "media");
|
|
9279
9601
|
}
|
|
9280
9602
|
function projectStorageKey(projectId) {
|
|
9281
|
-
return
|
|
9603
|
+
return createHash5("sha256").update(projectId).digest("hex").slice(0, 16);
|
|
9282
9604
|
}
|
|
9283
9605
|
function validateUnderRoot(root, candidate) {
|
|
9284
9606
|
const resolved = path10.resolve(candidate);
|
|
@@ -9342,7 +9664,7 @@ async function destinationExists(destination) {
|
|
|
9342
9664
|
async function persistBuffer(bytes, destination) {
|
|
9343
9665
|
await mkdir3(path10.dirname(destination), { recursive: true });
|
|
9344
9666
|
if (await destinationExists(destination)) return false;
|
|
9345
|
-
const temporary = `${destination}.${
|
|
9667
|
+
const temporary = `${destination}.${randomUUID6()}.tmp`;
|
|
9346
9668
|
try {
|
|
9347
9669
|
await writeFile3(temporary, bytes, { flag: "wx" });
|
|
9348
9670
|
await rename2(temporary, destination);
|
|
@@ -9387,7 +9709,7 @@ async function importMediaBuffer(input) {
|
|
|
9387
9709
|
if (input.bytes.length === 0) throw new Error("Media import rejects empty payloads");
|
|
9388
9710
|
if (input.bytes.length > maxBytes) throw new Error(`Media payload is too large (${input.bytes.length} bytes; limit ${maxBytes})`);
|
|
9389
9711
|
const detected = detectMedia(input.bytes.subarray(0, 32));
|
|
9390
|
-
const sha256 =
|
|
9712
|
+
const sha256 = createHash5("sha256").update(input.bytes).digest("hex");
|
|
9391
9713
|
return importKnownMedia({
|
|
9392
9714
|
dataDir: input.dataDir,
|
|
9393
9715
|
projectId: input.projectId,
|
|
@@ -9405,7 +9727,7 @@ async function readMediaAsset(dataDir, asset, maxBytes = DEFAULT_MAX_MEDIA_BYTES
|
|
|
9405
9727
|
if (asset.byteSize > maxBytes) throw new Error(`Media asset exceeds read limit (${asset.byteSize} bytes; limit ${maxBytes})`);
|
|
9406
9728
|
const bytes = await readFile3(getMediaAssetPath(dataDir, asset));
|
|
9407
9729
|
if (bytes.length !== asset.byteSize) throw new Error(`Media asset size no longer matches metadata: ${asset.id}`);
|
|
9408
|
-
const sha256 =
|
|
9730
|
+
const sha256 = createHash5("sha256").update(bytes).digest("hex");
|
|
9409
9731
|
if (sha256 !== asset.sha256) throw new Error(`Media asset hash no longer matches metadata: ${asset.id}`);
|
|
9410
9732
|
return bytes;
|
|
9411
9733
|
}
|
|
@@ -62156,7 +62478,7 @@ var require_gaxios = __commonJS({
|
|
|
62156
62478
|
var retry_js_1 = require_retry3();
|
|
62157
62479
|
var stream_1 = __require("stream");
|
|
62158
62480
|
var interceptor_js_1 = require_interceptor();
|
|
62159
|
-
var
|
|
62481
|
+
var randomUUID16 = async () => globalThis.crypto?.randomUUID() || (await import("crypto")).randomUUID();
|
|
62160
62482
|
var HTTP_STATUS_NO_CONTENT = 204;
|
|
62161
62483
|
var Gaxios = class {
|
|
62162
62484
|
agentCache = /* @__PURE__ */ new Map();
|
|
@@ -62429,7 +62751,7 @@ var require_gaxios = __commonJS({
|
|
|
62429
62751
|
*/
|
|
62430
62752
|
["Blob", "File", "FormData"].includes(opts.data?.constructor?.name || "");
|
|
62431
62753
|
if (opts.multipart?.length) {
|
|
62432
|
-
const boundary = await
|
|
62754
|
+
const boundary = await randomUUID16();
|
|
62433
62755
|
preparedHeaders.set("content-type", `multipart/related; boundary=${boundary}`);
|
|
62434
62756
|
opts.body = stream_1.Readable.from(this.getMultipartRequest(opts.multipart, boundary));
|
|
62435
62757
|
} else if (shouldDirectlyPassData) {
|
|
@@ -74656,7 +74978,7 @@ var require_websocket = __commonJS({
|
|
|
74656
74978
|
var http3 = __require("http");
|
|
74657
74979
|
var net = __require("net");
|
|
74658
74980
|
var tls = __require("tls");
|
|
74659
|
-
var { randomBytes, createHash:
|
|
74981
|
+
var { randomBytes, createHash: createHash14 } = __require("crypto");
|
|
74660
74982
|
var { Duplex, Readable: Readable2 } = __require("stream");
|
|
74661
74983
|
var { URL: URL2 } = __require("url");
|
|
74662
74984
|
var PerMessageDeflate2 = require_permessage_deflate();
|
|
@@ -75324,7 +75646,7 @@ var require_websocket = __commonJS({
|
|
|
75324
75646
|
abortHandshake(websocket, socket, "Invalid Upgrade header");
|
|
75325
75647
|
return;
|
|
75326
75648
|
}
|
|
75327
|
-
const digest2 =
|
|
75649
|
+
const digest2 = createHash14("sha1").update(key + GUID).digest("base64");
|
|
75328
75650
|
if (res.headers["sec-websocket-accept"] !== digest2) {
|
|
75329
75651
|
abortHandshake(websocket, socket, "Invalid Sec-WebSocket-Accept header");
|
|
75330
75652
|
return;
|
|
@@ -75696,7 +76018,7 @@ var require_websocket_server = __commonJS({
|
|
|
75696
76018
|
var EventEmitter = __require("events");
|
|
75697
76019
|
var http3 = __require("http");
|
|
75698
76020
|
var { Duplex } = __require("stream");
|
|
75699
|
-
var { createHash:
|
|
76021
|
+
var { createHash: createHash14 } = __require("crypto");
|
|
75700
76022
|
var extension3 = require_extension();
|
|
75701
76023
|
var PerMessageDeflate2 = require_permessage_deflate();
|
|
75702
76024
|
var subprotocol2 = require_subprotocol();
|
|
@@ -76003,7 +76325,7 @@ var require_websocket_server = __commonJS({
|
|
|
76003
76325
|
);
|
|
76004
76326
|
}
|
|
76005
76327
|
if (this._state > RUNNING) return abortHandshake(socket, 503);
|
|
76006
|
-
const digest2 =
|
|
76328
|
+
const digest2 = createHash14("sha1").update(key + GUID).digest("base64");
|
|
76007
76329
|
const headers = [
|
|
76008
76330
|
"HTTP/1.1 101 Switching Protocols",
|
|
76009
76331
|
"Upgrade: websocket",
|
|
@@ -142847,6 +143169,186 @@ var init_video_jobs = __esm({
|
|
|
142847
143169
|
}
|
|
142848
143170
|
});
|
|
142849
143171
|
|
|
143172
|
+
// src/memory/feedback-model.ts
|
|
143173
|
+
function feedbackWeightMultiplier(weight) {
|
|
143174
|
+
return Math.max(0.35, Math.min(1.4, 0.35 + Math.max(0, Math.min(2, weight)) * 0.525));
|
|
143175
|
+
}
|
|
143176
|
+
var init_feedback_model = __esm({
|
|
143177
|
+
"src/memory/feedback-model.ts"() {
|
|
143178
|
+
"use strict";
|
|
143179
|
+
init_esm_shims();
|
|
143180
|
+
}
|
|
143181
|
+
});
|
|
143182
|
+
|
|
143183
|
+
// src/memory/feedback.ts
|
|
143184
|
+
var feedback_exports = {};
|
|
143185
|
+
__export(feedback_exports, {
|
|
143186
|
+
FEEDBACK_DELTAS: () => FEEDBACK_DELTAS,
|
|
143187
|
+
MemoryFeedbackStore: () => MemoryFeedbackStore,
|
|
143188
|
+
applyMemoryFeedback: () => applyMemoryFeedback,
|
|
143189
|
+
feedbackWeightMultiplier: () => feedbackWeightMultiplier
|
|
143190
|
+
});
|
|
143191
|
+
import { randomUUID as randomUUID7 } from "crypto";
|
|
143192
|
+
function applyMemoryFeedback(current, event) {
|
|
143193
|
+
const delta = event.signal === "revoke" ? 0 : FEEDBACK_DELTAS[event.signal];
|
|
143194
|
+
const weight = Math.max(0, Math.min(2, current.weight + delta));
|
|
143195
|
+
const status = (event.signal === "code-conflict" || event.signal === "user-correction" || event.signal === "weaken") && weight < 0.5 ? "archived" : current.status;
|
|
143196
|
+
return { weight, status, audit: [...current.audit, { ...event }] };
|
|
143197
|
+
}
|
|
143198
|
+
function rowToEvent(row) {
|
|
143199
|
+
return {
|
|
143200
|
+
id: String(row.id),
|
|
143201
|
+
projectId: String(row.project_id),
|
|
143202
|
+
candidateKind: row.candidate_kind,
|
|
143203
|
+
candidateId: String(row.candidate_id),
|
|
143204
|
+
signal: row.signal,
|
|
143205
|
+
...row.observed_at ? { at: String(row.observed_at) } : { at: (/* @__PURE__ */ new Date()).toISOString() },
|
|
143206
|
+
...row.actor ? { actor: String(row.actor) } : {},
|
|
143207
|
+
...row.note ? { note: String(row.note) } : {},
|
|
143208
|
+
...row.source_ref ? { sourceRef: String(row.source_ref) } : {},
|
|
143209
|
+
...row.target_event_id ? { targetEventId: String(row.target_event_id) } : {},
|
|
143210
|
+
delta: Number(row.delta ?? 0)
|
|
143211
|
+
};
|
|
143212
|
+
}
|
|
143213
|
+
var FEEDBACK_DELTAS, MemoryFeedbackStore;
|
|
143214
|
+
var init_feedback = __esm({
|
|
143215
|
+
"src/memory/feedback.ts"() {
|
|
143216
|
+
"use strict";
|
|
143217
|
+
init_esm_shims();
|
|
143218
|
+
init_sqlite_db();
|
|
143219
|
+
init_feedback_model();
|
|
143220
|
+
FEEDBACK_DELTAS = {
|
|
143221
|
+
"user-correction": -0.35,
|
|
143222
|
+
"verification-success": 0.25,
|
|
143223
|
+
"verification-failure": -0.25,
|
|
143224
|
+
"code-change": -0.15,
|
|
143225
|
+
used: 0.1,
|
|
143226
|
+
"not-used": -0.05,
|
|
143227
|
+
"code-conflict": -0.4,
|
|
143228
|
+
strengthen: 0.2,
|
|
143229
|
+
weaken: -0.2
|
|
143230
|
+
};
|
|
143231
|
+
MemoryFeedbackStore = class {
|
|
143232
|
+
db = null;
|
|
143233
|
+
async init(dataDir) {
|
|
143234
|
+
this.db = getDatabase(dataDir);
|
|
143235
|
+
}
|
|
143236
|
+
requireDb() {
|
|
143237
|
+
if (!this.db) throw new Error("MemoryFeedbackStore is not initialized.");
|
|
143238
|
+
return this.db;
|
|
143239
|
+
}
|
|
143240
|
+
loadEvents(projectId, candidateKind, candidateId) {
|
|
143241
|
+
return this.requireDb().prepare(`
|
|
143242
|
+
SELECT * FROM memory_feedback_events
|
|
143243
|
+
WHERE project_id = ? AND candidate_kind = ? AND candidate_id = ?
|
|
143244
|
+
ORDER BY observed_at ASC, rowid ASC
|
|
143245
|
+
`).all(projectId, candidateKind, candidateId).map(rowToEvent);
|
|
143246
|
+
}
|
|
143247
|
+
rebuild(projectId, candidateKind, candidateId) {
|
|
143248
|
+
const events = this.loadEvents(projectId, candidateKind, candidateId);
|
|
143249
|
+
const revoked = new Set(events.filter((event) => event.signal === "revoke" && event.targetEventId).map((event) => event.targetEventId));
|
|
143250
|
+
let state = { weight: 1, status: "active", audit: [] };
|
|
143251
|
+
for (const event of events) {
|
|
143252
|
+
if (event.signal === "revoke" || revoked.has(event.id)) {
|
|
143253
|
+
state.audit.push(event);
|
|
143254
|
+
continue;
|
|
143255
|
+
}
|
|
143256
|
+
state = applyMemoryFeedback(state, event);
|
|
143257
|
+
}
|
|
143258
|
+
this.requireDb().prepare(`
|
|
143259
|
+
INSERT INTO memory_feedback_states (project_id, candidate_kind, candidate_id, weight, lifecycle_status, updated_at)
|
|
143260
|
+
VALUES (?, ?, ?, ?, ?, ?)
|
|
143261
|
+
ON CONFLICT(project_id, candidate_kind, candidate_id) DO UPDATE SET
|
|
143262
|
+
weight = excluded.weight, lifecycle_status = excluded.lifecycle_status, updated_at = excluded.updated_at
|
|
143263
|
+
`).run(projectId, candidateKind, candidateId, state.weight, state.status, (/* @__PURE__ */ new Date()).toISOString());
|
|
143264
|
+
return state;
|
|
143265
|
+
}
|
|
143266
|
+
getState(projectId, candidateKind, candidateId) {
|
|
143267
|
+
const row = this.requireDb().prepare(`
|
|
143268
|
+
SELECT weight, lifecycle_status FROM memory_feedback_states
|
|
143269
|
+
WHERE project_id = ? AND candidate_kind = ? AND candidate_id = ?
|
|
143270
|
+
`).get(projectId, candidateKind, candidateId);
|
|
143271
|
+
if (!row) return { weight: 1, status: "active", audit: [] };
|
|
143272
|
+
return {
|
|
143273
|
+
weight: Number(row.weight ?? 1),
|
|
143274
|
+
status: row.lifecycle_status ?? "active",
|
|
143275
|
+
audit: this.loadEvents(projectId, candidateKind, candidateId)
|
|
143276
|
+
};
|
|
143277
|
+
}
|
|
143278
|
+
listStates(projectId, candidateKind = "observation") {
|
|
143279
|
+
return this.requireDb().prepare(`
|
|
143280
|
+
SELECT candidate_id, weight, lifecycle_status, updated_at
|
|
143281
|
+
FROM memory_feedback_states WHERE project_id = ? AND candidate_kind = ?
|
|
143282
|
+
ORDER BY updated_at DESC
|
|
143283
|
+
`).all(projectId, candidateKind).map((row) => ({
|
|
143284
|
+
candidateId: String(row.candidate_id),
|
|
143285
|
+
weight: Number(row.weight),
|
|
143286
|
+
status: row.lifecycle_status,
|
|
143287
|
+
updatedAt: String(row.updated_at)
|
|
143288
|
+
}));
|
|
143289
|
+
}
|
|
143290
|
+
weights(projectId, candidateKind = "observation") {
|
|
143291
|
+
const states = /* @__PURE__ */ new Map();
|
|
143292
|
+
for (const row of this.listStates(projectId, candidateKind)) {
|
|
143293
|
+
states.set(row.candidateId, this.getState(projectId, candidateKind, row.candidateId));
|
|
143294
|
+
}
|
|
143295
|
+
return states;
|
|
143296
|
+
}
|
|
143297
|
+
record(input) {
|
|
143298
|
+
if (input.signal === "revoke" && !input.targetEventId) {
|
|
143299
|
+
throw new Error("A revoke feedback event requires targetEventId.");
|
|
143300
|
+
}
|
|
143301
|
+
if (input.signal === "revoke") {
|
|
143302
|
+
const target = this.requireDb().prepare(`
|
|
143303
|
+
SELECT 1 FROM memory_feedback_events
|
|
143304
|
+
WHERE id = ? AND project_id = ? AND candidate_kind = ? AND candidate_id = ?
|
|
143305
|
+
`).get(input.targetEventId, input.projectId, input.candidateKind, input.candidateId);
|
|
143306
|
+
if (!target) throw new Error("The feedback event to revoke was not found in the same candidate scope.");
|
|
143307
|
+
}
|
|
143308
|
+
const event = {
|
|
143309
|
+
id: randomUUID7(),
|
|
143310
|
+
projectId: input.projectId,
|
|
143311
|
+
candidateKind: input.candidateKind,
|
|
143312
|
+
candidateId: input.candidateId,
|
|
143313
|
+
signal: input.signal,
|
|
143314
|
+
sourceRef: input.sourceRef,
|
|
143315
|
+
...input.actor ? { actor: input.actor } : {},
|
|
143316
|
+
...input.note ? { note: input.note.slice(0, 2e3) } : {},
|
|
143317
|
+
...input.targetEventId ? { targetEventId: input.targetEventId } : {},
|
|
143318
|
+
at: input.at ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
143319
|
+
delta: input.signal === "revoke" ? 0 : FEEDBACK_DELTAS[input.signal]
|
|
143320
|
+
};
|
|
143321
|
+
this.requireDb().prepare(`
|
|
143322
|
+
INSERT INTO memory_feedback_events (
|
|
143323
|
+
id, project_id, candidate_kind, candidate_id, signal, actor, note,
|
|
143324
|
+
source_ref, target_event_id, delta, observed_at
|
|
143325
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
143326
|
+
`).run(
|
|
143327
|
+
event.id,
|
|
143328
|
+
event.projectId,
|
|
143329
|
+
event.candidateKind,
|
|
143330
|
+
event.candidateId,
|
|
143331
|
+
event.signal,
|
|
143332
|
+
event.actor ?? null,
|
|
143333
|
+
event.note ?? null,
|
|
143334
|
+
event.sourceRef,
|
|
143335
|
+
event.targetEventId ?? null,
|
|
143336
|
+
event.delta,
|
|
143337
|
+
event.at
|
|
143338
|
+
);
|
|
143339
|
+
return { event, state: this.rebuild(input.projectId, input.candidateKind, input.candidateId) };
|
|
143340
|
+
}
|
|
143341
|
+
audit(projectId, candidateKind, candidateId, limit2 = 100) {
|
|
143342
|
+
return this.requireDb().prepare(`
|
|
143343
|
+
SELECT * FROM memory_feedback_events
|
|
143344
|
+
WHERE project_id = ? AND candidate_kind = ? AND candidate_id = ?
|
|
143345
|
+
ORDER BY observed_at DESC, rowid DESC LIMIT ?
|
|
143346
|
+
`).all(projectId, candidateKind, candidateId, Math.min(200, Math.max(1, Math.floor(limit2)))).map(rowToEvent);
|
|
143347
|
+
}
|
|
143348
|
+
};
|
|
143349
|
+
}
|
|
143350
|
+
});
|
|
143351
|
+
|
|
142850
143352
|
// src/memory/retention.ts
|
|
142851
143353
|
var retention_exports = {};
|
|
142852
143354
|
__export(retention_exports, {
|
|
@@ -142888,6 +143390,7 @@ function getEffectiveRetentionDays(doc) {
|
|
|
142888
143390
|
}
|
|
142889
143391
|
function isImmune(doc) {
|
|
142890
143392
|
if (doc.type === "probe") return false;
|
|
143393
|
+
if (doc.feedbackStatus === "archived") return false;
|
|
142891
143394
|
if (doc.admissionState === "candidate" || doc.admissionState === "ephemeral") return false;
|
|
142892
143395
|
if (doc.valueCategory === "core") return true;
|
|
142893
143396
|
const importance = getImportanceLevel(doc);
|
|
@@ -142920,7 +143423,8 @@ function calculateRelevance(doc, referenceTime) {
|
|
|
142920
143423
|
const decayFactor = Math.exp(-ageDays / retention);
|
|
142921
143424
|
const accessCount = doc.accessCount ?? 0;
|
|
142922
143425
|
const accessBoost = Math.min(2, 1 + 0.1 * accessCount);
|
|
142923
|
-
|
|
143426
|
+
const feedbackMultiplier = doc.feedbackWeight === void 0 ? 1 : feedbackWeightMultiplier(doc.feedbackWeight);
|
|
143427
|
+
let totalScore = base * decayFactor * accessBoost * feedbackMultiplier;
|
|
142924
143428
|
const immune = isImmune(doc);
|
|
142925
143429
|
if (immune) {
|
|
142926
143430
|
totalScore = Math.max(totalScore, 0.5);
|
|
@@ -142932,7 +143436,8 @@ function calculateRelevance(doc, referenceTime) {
|
|
|
142932
143436
|
decayFactor,
|
|
142933
143437
|
accessBoost,
|
|
142934
143438
|
ageDays,
|
|
142935
|
-
isImmune: immune
|
|
143439
|
+
isImmune: immune,
|
|
143440
|
+
feedbackMultiplier
|
|
142936
143441
|
};
|
|
142937
143442
|
}
|
|
142938
143443
|
function rankByRelevance(docs, referenceTime) {
|
|
@@ -142940,6 +143445,7 @@ function rankByRelevance(docs, referenceTime) {
|
|
|
142940
143445
|
}
|
|
142941
143446
|
function getRetentionZone(doc, referenceTime) {
|
|
142942
143447
|
const now3 = referenceTime ?? /* @__PURE__ */ new Date();
|
|
143448
|
+
if (doc.feedbackStatus === "archived") return "archive-candidate";
|
|
142943
143449
|
const importance = getImportanceLevel(doc);
|
|
142944
143450
|
const retention = getEffectiveRetentionDays(doc);
|
|
142945
143451
|
const createdAt = new Date(doc.createdAt);
|
|
@@ -143011,7 +143517,7 @@ function explainRetention(doc, referenceTime) {
|
|
|
143011
143517
|
summary: parts.join(" ; ")
|
|
143012
143518
|
};
|
|
143013
143519
|
}
|
|
143014
|
-
function toRetentionDocument(obs, accessMap) {
|
|
143520
|
+
function toRetentionDocument(obs, accessMap, feedback) {
|
|
143015
143521
|
const access2 = accessMap?.get(obs.id);
|
|
143016
143522
|
return {
|
|
143017
143523
|
id: `obs-${obs.id}`,
|
|
@@ -143033,11 +143539,12 @@ function toRetentionDocument(obs, accessMap) {
|
|
|
143033
143539
|
sourceDetail: obs.sourceDetail ?? "",
|
|
143034
143540
|
valueCategory: obs.valueCategory ?? "",
|
|
143035
143541
|
admissionState: obs.admissionState ?? "",
|
|
143036
|
-
admissionReason: obs.admissionReason ?? ""
|
|
143542
|
+
admissionReason: obs.admissionReason ?? "",
|
|
143543
|
+
...feedback ? { feedbackWeight: feedback.weight, feedbackStatus: feedback.status } : {}
|
|
143037
143544
|
};
|
|
143038
143545
|
}
|
|
143039
143546
|
function projectObservationRetention(observation, options = {}) {
|
|
143040
|
-
const document2 = toRetentionDocument(observation, options.accessMap);
|
|
143547
|
+
const document2 = toRetentionDocument(observation, options.accessMap, options.feedback);
|
|
143041
143548
|
const relevance = calculateRelevance(document2, options.referenceTime);
|
|
143042
143549
|
const explanation = explainRetention(document2, options.referenceTime);
|
|
143043
143550
|
return {
|
|
@@ -143062,7 +143569,17 @@ function summarizeRetentionProjections(projections) {
|
|
|
143062
143569
|
}
|
|
143063
143570
|
return { active, stale, archiveCandidates, immune };
|
|
143064
143571
|
}
|
|
143065
|
-
async function
|
|
143572
|
+
async function loadFeedbackStore(dataDir) {
|
|
143573
|
+
try {
|
|
143574
|
+
const { MemoryFeedbackStore: MemoryFeedbackStore2 } = await Promise.resolve().then(() => (init_feedback(), feedback_exports));
|
|
143575
|
+
const store = new MemoryFeedbackStore2();
|
|
143576
|
+
await store.init(dataDir);
|
|
143577
|
+
return store;
|
|
143578
|
+
} catch {
|
|
143579
|
+
return void 0;
|
|
143580
|
+
}
|
|
143581
|
+
}
|
|
143582
|
+
async function archiveExpiredBatch(projectDir2, options) {
|
|
143066
143583
|
const store = getObservationStore();
|
|
143067
143584
|
const limit2 = Math.min(500, Math.max(1, Math.floor(options.limit ?? 100)));
|
|
143068
143585
|
const afterId = Math.max(0, Math.floor(options.afterId ?? 0));
|
|
@@ -143071,11 +143588,13 @@ async function archiveExpiredBatch(_projectDir, options) {
|
|
|
143071
143588
|
afterId,
|
|
143072
143589
|
limit: limit2 + 1
|
|
143073
143590
|
});
|
|
143591
|
+
const feedback = await loadFeedbackStore(projectDir2);
|
|
143074
143592
|
const hasMore = page.length > limit2;
|
|
143075
143593
|
const scanned = hasMore ? page.slice(0, limit2) : page;
|
|
143076
143594
|
const candidateIds = scanned.filter((observation) => !options.reader || canManageObservation(observation, options.reader)).filter((observation) => projectObservationRetention(observation, {
|
|
143077
143595
|
accessMap: options.accessMap,
|
|
143078
|
-
referenceTime: options.referenceTime
|
|
143596
|
+
referenceTime: options.referenceTime,
|
|
143597
|
+
...feedback ? { feedback: feedback.getState(options.projectId, "observation", String(observation.id)) } : {}
|
|
143079
143598
|
}).zone === "archive-candidate").map((observation) => observation.id);
|
|
143080
143599
|
const archived = candidateIds.length === 0 ? 0 : await store.atomic(async (tx) => {
|
|
143081
143600
|
const updates = await Promise.all(
|
|
@@ -143106,6 +143625,7 @@ async function archiveExpired(projectDir2, referenceTime, accessMap, projectId,
|
|
|
143106
143625
|
const remaining = reader ? remainingObservations.filter((observation) => canManageObservation(observation, reader)).length : remainingObservations.length;
|
|
143107
143626
|
return { archived, remaining };
|
|
143108
143627
|
}
|
|
143628
|
+
const feedback = await loadFeedbackStore(projectDir2);
|
|
143109
143629
|
return await store.atomic(async (tx) => {
|
|
143110
143630
|
const allObs = await tx.loadAll();
|
|
143111
143631
|
const activeObs = allObs.filter(
|
|
@@ -143113,7 +143633,11 @@ async function archiveExpired(projectDir2, referenceTime, accessMap, projectId,
|
|
|
143113
143633
|
);
|
|
143114
143634
|
const archivedIds = [];
|
|
143115
143635
|
for (const obs of activeObs) {
|
|
143116
|
-
const retention = projectObservationRetention(obs, {
|
|
143636
|
+
const retention = projectObservationRetention(obs, {
|
|
143637
|
+
accessMap,
|
|
143638
|
+
referenceTime,
|
|
143639
|
+
...feedback ? { feedback: feedback.getState(obs.projectId, "observation", String(obs.id)) } : {}
|
|
143640
|
+
});
|
|
143117
143641
|
if (retention.zone === "archive-candidate") {
|
|
143118
143642
|
archivedIds.push(obs.id);
|
|
143119
143643
|
}
|
|
@@ -143133,6 +143657,7 @@ var init_retention = __esm({
|
|
|
143133
143657
|
init_esm_shims();
|
|
143134
143658
|
init_obs_store();
|
|
143135
143659
|
init_visibility();
|
|
143660
|
+
init_feedback_model();
|
|
143136
143661
|
RETENTION_DAYS = {
|
|
143137
143662
|
critical: 365,
|
|
143138
143663
|
high: 180,
|
|
@@ -143169,7 +143694,7 @@ var init_retention = __esm({
|
|
|
143169
143694
|
});
|
|
143170
143695
|
|
|
143171
143696
|
// src/memory/owner.ts
|
|
143172
|
-
import { randomUUID as
|
|
143697
|
+
import { randomUUID as randomUUID8 } from "crypto";
|
|
143173
143698
|
import { promises as fs9 } from "fs";
|
|
143174
143699
|
import path15 from "path";
|
|
143175
143700
|
function ownerPath(dataDir) {
|
|
@@ -143199,7 +143724,7 @@ async function resolveLocalMemoryOwner(dataDir, options = {}) {
|
|
|
143199
143724
|
await fs9.mkdir(path15.dirname(filePath), { recursive: true });
|
|
143200
143725
|
const created = {
|
|
143201
143726
|
version: 1,
|
|
143202
|
-
id: "local-" +
|
|
143727
|
+
id: "local-" + randomUUID8(),
|
|
143203
143728
|
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
143204
143729
|
};
|
|
143205
143730
|
try {
|
|
@@ -143222,7 +143747,7 @@ var init_owner = __esm({
|
|
|
143222
143747
|
});
|
|
143223
143748
|
|
|
143224
143749
|
// src/memory/long-term-store.ts
|
|
143225
|
-
import { randomUUID as
|
|
143750
|
+
import { randomUUID as randomUUID9 } from "crypto";
|
|
143226
143751
|
function optionalText2(value) {
|
|
143227
143752
|
return typeof value === "string" && value.trim() ? value : void 0;
|
|
143228
143753
|
}
|
|
@@ -143273,7 +143798,7 @@ function rowToEvidence(row) {
|
|
|
143273
143798
|
createdAt: row.createdAt
|
|
143274
143799
|
};
|
|
143275
143800
|
}
|
|
143276
|
-
function
|
|
143801
|
+
function rowToEvent2(row) {
|
|
143277
143802
|
return {
|
|
143278
143803
|
id: row.id,
|
|
143279
143804
|
memoryId: row.memoryId,
|
|
@@ -143382,7 +143907,7 @@ var init_long_term_store = __esm({
|
|
|
143382
143907
|
}
|
|
143383
143908
|
insertEvidence(input) {
|
|
143384
143909
|
const evidence = {
|
|
143385
|
-
id:
|
|
143910
|
+
id: randomUUID9(),
|
|
143386
143911
|
...input,
|
|
143387
143912
|
createdAt: input.createdAt ?? (/* @__PURE__ */ new Date()).toISOString()
|
|
143388
143913
|
};
|
|
@@ -143409,7 +143934,7 @@ var init_long_term_store = __esm({
|
|
|
143409
143934
|
}
|
|
143410
143935
|
recordEvent(input) {
|
|
143411
143936
|
const event = {
|
|
143412
|
-
id:
|
|
143937
|
+
id: randomUUID9(),
|
|
143413
143938
|
...input,
|
|
143414
143939
|
createdAt: input.createdAt ?? (/* @__PURE__ */ new Date()).toISOString()
|
|
143415
143940
|
};
|
|
@@ -143430,7 +143955,7 @@ var init_long_term_store = __esm({
|
|
|
143430
143955
|
listEvents(memoryId) {
|
|
143431
143956
|
return this.db.prepare(`
|
|
143432
143957
|
SELECT * FROM long_term_memory_events WHERE memoryId = ? ORDER BY createdAt ASC, rowid ASC
|
|
143433
|
-
`).all(memoryId).map(
|
|
143958
|
+
`).all(memoryId).map(rowToEvent2);
|
|
143434
143959
|
}
|
|
143435
143960
|
markAccess(ids, at = (/* @__PURE__ */ new Date()).toISOString()) {
|
|
143436
143961
|
const unique = [...new Set(ids.filter(Boolean))];
|
|
@@ -143499,7 +144024,7 @@ __export(long_term_exports, {
|
|
|
143499
144024
|
selectLongTermMemoriesForTask: () => selectLongTermMemoriesForTask,
|
|
143500
144025
|
supersedeLongTermMemory: () => supersedeLongTermMemory
|
|
143501
144026
|
});
|
|
143502
|
-
import { randomUUID as
|
|
144027
|
+
import { randomUUID as randomUUID10 } from "crypto";
|
|
143503
144028
|
function isOneOf(value, values) {
|
|
143504
144029
|
return typeof value === "string" && values.includes(value);
|
|
143505
144030
|
}
|
|
@@ -143681,7 +144206,7 @@ async function createManualLongTermMemory(input) {
|
|
|
143681
144206
|
const owner = await resolveLocalMemoryOwner(input.dataDir, { create: true });
|
|
143682
144207
|
if (!owner) throw new Error("Memorix could not resolve a local memory owner.");
|
|
143683
144208
|
assertScope(input.scope);
|
|
143684
|
-
const evidence = input.scope === "user" ? [{ kind: "user", referenceId: owner.id, relation: "user-confirmed" }] : [{ kind: "manual", referenceId: "manual:" +
|
|
144209
|
+
const evidence = input.scope === "user" ? [{ kind: "user", referenceId: owner.id, relation: "user-confirmed" }] : [{ kind: "manual", referenceId: "manual:" + randomUUID10(), relation: "supports" }];
|
|
143685
144210
|
return createLongTermMemoryWithDataDir({
|
|
143686
144211
|
dataDir: input.dataDir,
|
|
143687
144212
|
originProjectId: input.projectId,
|
|
@@ -143736,7 +144261,7 @@ async function createLongTermMemoryWithDataDir(input) {
|
|
|
143736
144261
|
assertPortableEvidence(input.scope, portability, evidenceInputs);
|
|
143737
144262
|
const now3 = (/* @__PURE__ */ new Date()).toISOString();
|
|
143738
144263
|
const memory = {
|
|
143739
|
-
id:
|
|
144264
|
+
id: randomUUID10(),
|
|
143740
144265
|
originProjectId: compactText(input.originProjectId, "origin project id", 1e3),
|
|
143741
144266
|
ownerId: compactText(input.ownerId, "owner id", 160),
|
|
143742
144267
|
scope: input.scope,
|
|
@@ -144054,9 +144579,9 @@ var init_long_term = __esm({
|
|
|
144054
144579
|
});
|
|
144055
144580
|
|
|
144056
144581
|
// src/codegraph/ids.ts
|
|
144057
|
-
import { createHash as
|
|
144582
|
+
import { createHash as createHash6 } from "crypto";
|
|
144058
144583
|
function digest(input) {
|
|
144059
|
-
return
|
|
144584
|
+
return createHash6("sha256").update(input).digest("hex").slice(0, 16);
|
|
144060
144585
|
}
|
|
144061
144586
|
function normalizeCodePath(path22) {
|
|
144062
144587
|
return path22.replace(/\\/g, "/").replace(/^\.\//, "").replace(/\/+/g, "/");
|
|
@@ -144091,7 +144616,7 @@ var store_exports = {};
|
|
|
144091
144616
|
__export(store_exports, {
|
|
144092
144617
|
CodeGraphStore: () => CodeGraphStore
|
|
144093
144618
|
});
|
|
144094
|
-
import { randomUUID as
|
|
144619
|
+
import { randomUUID as randomUUID11 } from "crypto";
|
|
144095
144620
|
import { posix as pathPosix } from "path";
|
|
144096
144621
|
function rowToFile(row) {
|
|
144097
144622
|
return {
|
|
@@ -144808,7 +145333,7 @@ var init_store = __esm({
|
|
|
144808
145333
|
* so an interrupted scan cannot be advertised as complete.
|
|
144809
145334
|
*/
|
|
144810
145335
|
recordCodeStateSnapshot(input) {
|
|
144811
|
-
const id =
|
|
145336
|
+
const id = randomUUID11();
|
|
144812
145337
|
let snapshot;
|
|
144813
145338
|
const tx = this.db.transaction(() => {
|
|
144814
145339
|
const previous = this.db.prepare(
|
|
@@ -144886,7 +145411,7 @@ var init_store = __esm({
|
|
|
144886
145411
|
|
|
144887
145412
|
// src/codegraph/code-state.ts
|
|
144888
145413
|
import { execFile as execFile2 } from "child_process";
|
|
144889
|
-
import { createHash as
|
|
145414
|
+
import { createHash as createHash7 } from "crypto";
|
|
144890
145415
|
import { promisify as promisify3 } from "util";
|
|
144891
145416
|
async function runGit(rootPath, args) {
|
|
144892
145417
|
try {
|
|
@@ -144915,7 +145440,7 @@ function changedPathCount(status) {
|
|
|
144915
145440
|
return count2;
|
|
144916
145441
|
}
|
|
144917
145442
|
function fingerprint(baseRevision, status) {
|
|
144918
|
-
return
|
|
145443
|
+
return createHash7("sha256").update(baseRevision ?? "").update("\0").update(status).digest("hex");
|
|
144919
145444
|
}
|
|
144920
145445
|
async function collectCodeStateSnapshot(input) {
|
|
144921
145446
|
const [revision, status] = await Promise.all([
|
|
@@ -145015,11 +145540,11 @@ __export(lite_provider_exports, {
|
|
|
145015
145540
|
indexProjectLite: () => indexProjectLite,
|
|
145016
145541
|
refreshProjectLite: () => refreshProjectLite
|
|
145017
145542
|
});
|
|
145018
|
-
import { createHash as
|
|
145543
|
+
import { createHash as createHash8 } from "crypto";
|
|
145019
145544
|
import { readdirSync as readdirSync2, readFileSync as readFileSync7, statSync as statSync3 } from "fs";
|
|
145020
145545
|
import { join as join4, relative } from "path";
|
|
145021
145546
|
function hashText(text2) {
|
|
145022
|
-
return
|
|
145547
|
+
return createHash8("sha256").update(text2).digest("hex");
|
|
145023
145548
|
}
|
|
145024
145549
|
function extension2(path22) {
|
|
145025
145550
|
const index = path22.lastIndexOf(".");
|
|
@@ -145586,7 +146111,7 @@ var claim_store_exports = {};
|
|
|
145586
146111
|
__export(claim_store_exports, {
|
|
145587
146112
|
ClaimStore: () => ClaimStore
|
|
145588
146113
|
});
|
|
145589
|
-
import { createHash as
|
|
146114
|
+
import { createHash as createHash9, randomUUID as randomUUID12 } from "crypto";
|
|
145590
146115
|
function optionalText3(value) {
|
|
145591
146116
|
return typeof value === "string" && value ? value : void 0;
|
|
145592
146117
|
}
|
|
@@ -145625,7 +146150,7 @@ function rowToEvidence2(row) {
|
|
|
145625
146150
|
createdAt: row.createdAt
|
|
145626
146151
|
};
|
|
145627
146152
|
}
|
|
145628
|
-
function
|
|
146153
|
+
function rowToEvent3(row) {
|
|
145629
146154
|
return {
|
|
145630
146155
|
id: row.id,
|
|
145631
146156
|
projectId: row.projectId,
|
|
@@ -145639,7 +146164,7 @@ function rowToEvent2(row) {
|
|
|
145639
146164
|
};
|
|
145640
146165
|
}
|
|
145641
146166
|
function evidenceKey(input) {
|
|
145642
|
-
return
|
|
146167
|
+
return createHash9("sha256").update(JSON.stringify([
|
|
145643
146168
|
input.evidenceKind,
|
|
145644
146169
|
input.evidenceId,
|
|
145645
146170
|
input.relation,
|
|
@@ -145770,7 +146295,7 @@ var init_claim_store = __esm({
|
|
|
145770
146295
|
locator, capturedHash, evidenceKey, createdAt
|
|
145771
146296
|
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
145772
146297
|
`).run(
|
|
145773
|
-
|
|
146298
|
+
randomUUID12(),
|
|
145774
146299
|
input.claimId,
|
|
145775
146300
|
input.evidenceKind,
|
|
145776
146301
|
input.evidenceId,
|
|
@@ -145792,7 +146317,7 @@ var init_claim_store = __esm({
|
|
|
145792
146317
|
}
|
|
145793
146318
|
recordEvent(input) {
|
|
145794
146319
|
const event = {
|
|
145795
|
-
id:
|
|
146320
|
+
id: randomUUID12(),
|
|
145796
146321
|
...input,
|
|
145797
146322
|
...input.detail ? { detail: sanitizeCredentials(input.detail) } : {},
|
|
145798
146323
|
createdAt: input.createdAt ?? (/* @__PURE__ */ new Date()).toISOString()
|
|
@@ -145820,7 +146345,7 @@ var init_claim_store = __esm({
|
|
|
145820
146345
|
SELECT * FROM knowledge_claim_events
|
|
145821
146346
|
WHERE claimId = ?
|
|
145822
146347
|
ORDER BY createdAt ASC, id
|
|
145823
|
-
`).all(claimId).map(
|
|
146348
|
+
`).all(claimId).map(rowToEvent3);
|
|
145824
146349
|
}
|
|
145825
146350
|
};
|
|
145826
146351
|
}
|
|
@@ -145837,7 +146362,7 @@ __export(claims_exports, {
|
|
|
145837
146362
|
supersedeClaim: () => supersedeClaim,
|
|
145838
146363
|
writeClaim: () => writeClaim
|
|
145839
146364
|
});
|
|
145840
|
-
import { createHash as
|
|
146365
|
+
import { createHash as createHash10, randomUUID as randomUUID13 } from "crypto";
|
|
145841
146366
|
function compactText2(value, field) {
|
|
145842
146367
|
if (typeof value !== "string") throw new Error("Claim " + field + " must be text");
|
|
145843
146368
|
const sanitized = sanitizeCredentials(value).trim().replace(/\s+/g, " ");
|
|
@@ -145849,7 +146374,7 @@ function normalizedTerm(value) {
|
|
|
145849
146374
|
return compactText2(value, "identity").toLocaleLowerCase("en-US");
|
|
145850
146375
|
}
|
|
145851
146376
|
function hashIdentity(parts) {
|
|
145852
|
-
return
|
|
146377
|
+
return createHash10("sha256").update(parts.join(String.fromCharCode(31))).digest("hex");
|
|
145853
146378
|
}
|
|
145854
146379
|
function buildClaimIdentity(input) {
|
|
145855
146380
|
const subject = normalizedTerm(input.subject);
|
|
@@ -145923,7 +146448,7 @@ function normalizeClaimInput(input) {
|
|
|
145923
146448
|
const now3 = (/* @__PURE__ */ new Date()).toISOString();
|
|
145924
146449
|
return {
|
|
145925
146450
|
claim: {
|
|
145926
|
-
id:
|
|
146451
|
+
id: randomUUID13(),
|
|
145927
146452
|
projectId,
|
|
145928
146453
|
subject,
|
|
145929
146454
|
predicate,
|
|
@@ -146090,7 +146615,7 @@ function supersedeClaim(store, input) {
|
|
|
146090
146615
|
});
|
|
146091
146616
|
}
|
|
146092
146617
|
function hashObservation(observation) {
|
|
146093
|
-
return
|
|
146618
|
+
return createHash10("sha256").update(JSON.stringify([
|
|
146094
146619
|
observation.title,
|
|
146095
146620
|
observation.narrative,
|
|
146096
146621
|
observation.facts,
|
|
@@ -146334,11 +146859,11 @@ var init_frontmatter = __esm({
|
|
|
146334
146859
|
});
|
|
146335
146860
|
|
|
146336
146861
|
// src/knowledge/markdown.ts
|
|
146337
|
-
import { createHash as
|
|
146862
|
+
import { createHash as createHash11 } from "crypto";
|
|
146338
146863
|
import { promises as fs10 } from "fs";
|
|
146339
146864
|
import path16 from "path";
|
|
146340
146865
|
function hashContent(content) {
|
|
146341
|
-
return
|
|
146866
|
+
return createHash11("sha256").update(content).digest("hex");
|
|
146342
146867
|
}
|
|
146343
146868
|
function stringField(data, key) {
|
|
146344
146869
|
const value = data[key];
|
|
@@ -146464,11 +146989,11 @@ __export(wiki_exports, {
|
|
|
146464
146989
|
lintKnowledgeWorkspace: () => lintKnowledgeWorkspace,
|
|
146465
146990
|
readKnowledgePage: () => readKnowledgePage
|
|
146466
146991
|
});
|
|
146467
|
-
import { createHash as
|
|
146992
|
+
import { createHash as createHash12 } from "crypto";
|
|
146468
146993
|
import { promises as fs11 } from "fs";
|
|
146469
146994
|
import path17 from "path";
|
|
146470
146995
|
function hash2(value) {
|
|
146471
|
-
return
|
|
146996
|
+
return createHash12("sha256").update(value).digest("hex");
|
|
146472
146997
|
}
|
|
146473
146998
|
function now() {
|
|
146474
146999
|
return (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -147008,7 +147533,7 @@ var init_workflow_sync = __esm({
|
|
|
147008
147533
|
});
|
|
147009
147534
|
|
|
147010
147535
|
// src/knowledge/workflow-store.ts
|
|
147011
|
-
import { randomUUID as
|
|
147536
|
+
import { randomUUID as randomUUID14 } from "crypto";
|
|
147012
147537
|
function parseJson(value, fallback) {
|
|
147013
147538
|
if (typeof value !== "string" || !value) return fallback;
|
|
147014
147539
|
try {
|
|
@@ -147108,7 +147633,7 @@ var init_workflow_store = __esm({
|
|
|
147108
147633
|
}
|
|
147109
147634
|
recordRun(input) {
|
|
147110
147635
|
const run = {
|
|
147111
|
-
id:
|
|
147636
|
+
id: randomUUID14(),
|
|
147112
147637
|
workflowId: input.workflowId,
|
|
147113
147638
|
projectId: input.projectId,
|
|
147114
147639
|
task: input.task.trim(),
|
|
@@ -147176,7 +147701,7 @@ var init_outcome_types = __esm({
|
|
|
147176
147701
|
});
|
|
147177
147702
|
|
|
147178
147703
|
// src/knowledge/outcome-store.ts
|
|
147179
|
-
import { randomUUID as
|
|
147704
|
+
import { randomUUID as randomUUID15 } from "crypto";
|
|
147180
147705
|
function optionalText5(value) {
|
|
147181
147706
|
return typeof value === "string" && value.trim() ? value : void 0;
|
|
147182
147707
|
}
|
|
@@ -147220,7 +147745,7 @@ var init_outcome_store = __esm({
|
|
|
147220
147745
|
}
|
|
147221
147746
|
record(input) {
|
|
147222
147747
|
const signal = {
|
|
147223
|
-
id:
|
|
147748
|
+
id: randomUUID15(),
|
|
147224
147749
|
projectId: text(input.projectId, "project id"),
|
|
147225
147750
|
candidateKind: oneOf(input.candidateKind, MEMORY_OUTCOME_CANDIDATE_KINDS, "candidate kind"),
|
|
147226
147751
|
candidateId: text(input.candidateId, "candidate id"),
|
|
@@ -147325,11 +147850,11 @@ __export(workflows_exports, {
|
|
|
147325
147850
|
syncCanonicalWorkflows: () => syncCanonicalWorkflows,
|
|
147326
147851
|
writeCanonicalWorkflow: () => writeCanonicalWorkflow
|
|
147327
147852
|
});
|
|
147328
|
-
import { createHash as
|
|
147853
|
+
import { createHash as createHash13 } from "crypto";
|
|
147329
147854
|
import { promises as fs12 } from "fs";
|
|
147330
147855
|
import path18 from "path";
|
|
147331
147856
|
function hash3(value) {
|
|
147332
|
-
return
|
|
147857
|
+
return createHash13("sha256").update(value).digest("hex");
|
|
147333
147858
|
}
|
|
147334
147859
|
function now2() {
|
|
147335
147860
|
return (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -148711,6 +149236,16 @@ async function bindObservationCodeRefsBestEffort(observation) {
|
|
|
148711
149236
|
} catch {
|
|
148712
149237
|
}
|
|
148713
149238
|
}
|
|
149239
|
+
async function persistEvidenceCard(observation) {
|
|
149240
|
+
if (!projectDir) return;
|
|
149241
|
+
try {
|
|
149242
|
+
const evidence = new EvidenceCardStore();
|
|
149243
|
+
await evidence.init(projectDir);
|
|
149244
|
+
evidence.upsertObservation(observation);
|
|
149245
|
+
} catch (error) {
|
|
149246
|
+
console.error(`[memorix] Evidence card projection failed for obs-${observation.id}: ${error instanceof Error ? error.message : String(error)}`);
|
|
149247
|
+
}
|
|
149248
|
+
}
|
|
148714
149249
|
function queueClaimDerivation(observation) {
|
|
148715
149250
|
const dataDir = projectDir;
|
|
148716
149251
|
const isExplicit = observation.sourceDetail === "explicit";
|
|
@@ -149057,6 +149592,7 @@ async function storeObservation(input) {
|
|
|
149057
149592
|
}
|
|
149058
149593
|
if (!persistedCallbackInvoked) await input.onPersisted?.(observation);
|
|
149059
149594
|
await bindObservationCodeRefsBestEffort(observation);
|
|
149595
|
+
await persistEvidenceCard(observation);
|
|
149060
149596
|
queueObservationQualification(observation);
|
|
149061
149597
|
if (resolveObservationVisibility(observation) === "project") {
|
|
149062
149598
|
queueClaimDerivation(observation);
|
|
@@ -149149,6 +149685,7 @@ async function upsertObservation(existing, input, now3) {
|
|
|
149149
149685
|
await store.update(existing);
|
|
149150
149686
|
}
|
|
149151
149687
|
await bindObservationCodeRefsBestEffort(existing);
|
|
149688
|
+
await persistEvidenceCard(existing);
|
|
149152
149689
|
queueObservationQualification(existing);
|
|
149153
149690
|
if (resolveObservationVisibility(existing) === "project") {
|
|
149154
149691
|
queueClaimDerivation(existing);
|
|
@@ -149282,6 +149819,7 @@ async function resolveObservations(ids, status = "resolved") {
|
|
|
149282
149819
|
await Promise.all(changed.map((observation) => tx.update(observation)));
|
|
149283
149820
|
});
|
|
149284
149821
|
}
|
|
149822
|
+
for (const observation of changed) await persistEvidenceCard(observation);
|
|
149285
149823
|
return { resolved, notFound };
|
|
149286
149824
|
}
|
|
149287
149825
|
function getProjectObservations(projectId) {
|
|
@@ -149619,6 +150157,7 @@ var init_observations = __esm({
|
|
|
149619
150157
|
init_secret_filter();
|
|
149620
150158
|
init_lifecycle();
|
|
149621
150159
|
init_visibility();
|
|
150160
|
+
init_evidence_store();
|
|
149622
150161
|
observations = [];
|
|
149623
150162
|
nextId = 1;
|
|
149624
150163
|
projectDir = null;
|