@0xmaxma/claude-gateway 1.6.8 → 1.7.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/README.md +149 -20
- package/config.template.json +59 -1
- package/dist/agent/dreaming/accept.d.ts +43 -0
- package/dist/agent/dreaming/accept.d.ts.map +1 -0
- package/dist/agent/dreaming/accept.js +230 -0
- package/dist/agent/dreaming/accept.js.map +1 -0
- package/dist/agent/dreaming/applier.d.ts +77 -0
- package/dist/agent/dreaming/applier.d.ts.map +1 -0
- package/dist/agent/dreaming/applier.js +406 -0
- package/dist/agent/dreaming/applier.js.map +1 -0
- package/dist/agent/dreaming/audit.d.ts +27 -0
- package/dist/agent/dreaming/audit.d.ts.map +1 -0
- package/dist/agent/dreaming/audit.js +100 -0
- package/dist/agent/dreaming/audit.js.map +1 -0
- package/dist/agent/dreaming/compactor.d.ts +66 -0
- package/dist/agent/dreaming/compactor.d.ts.map +1 -0
- package/dist/agent/dreaming/compactor.js +306 -0
- package/dist/agent/dreaming/compactor.js.map +1 -0
- package/dist/agent/dreaming/config.d.ts +19 -0
- package/dist/agent/dreaming/config.d.ts.map +1 -0
- package/dist/agent/dreaming/config.js +107 -0
- package/dist/agent/dreaming/config.js.map +1 -0
- package/dist/agent/dreaming/episodic.d.ts +42 -0
- package/dist/agent/dreaming/episodic.d.ts.map +1 -0
- package/dist/agent/dreaming/episodic.js +116 -0
- package/dist/agent/dreaming/episodic.js.map +1 -0
- package/dist/agent/dreaming/gather.d.ts +31 -0
- package/dist/agent/dreaming/gather.d.ts.map +1 -0
- package/dist/agent/dreaming/gather.js +55 -0
- package/dist/agent/dreaming/gather.js.map +1 -0
- package/dist/agent/dreaming/index.d.ts +87 -0
- package/dist/agent/dreaming/index.d.ts.map +1 -0
- package/dist/agent/dreaming/index.js +377 -0
- package/dist/agent/dreaming/index.js.map +1 -0
- package/dist/agent/dreaming/migrate-cli.d.ts +17 -0
- package/dist/agent/dreaming/migrate-cli.d.ts.map +1 -0
- package/dist/agent/dreaming/migrate-cli.js +42 -0
- package/dist/agent/dreaming/migrate-cli.js.map +1 -0
- package/dist/agent/dreaming/migrate.d.ts +72 -0
- package/dist/agent/dreaming/migrate.d.ts.map +1 -0
- package/dist/agent/dreaming/migrate.js +374 -0
- package/dist/agent/dreaming/migrate.js.map +1 -0
- package/dist/agent/dreaming/report.d.ts +39 -0
- package/dist/agent/dreaming/report.d.ts.map +1 -0
- package/dist/agent/dreaming/report.js +121 -0
- package/dist/agent/dreaming/report.js.map +1 -0
- package/dist/agent/dreaming/reviewer.d.ts +43 -0
- package/dist/agent/dreaming/reviewer.d.ts.map +1 -0
- package/dist/agent/dreaming/reviewer.js +249 -0
- package/dist/agent/dreaming/reviewer.js.map +1 -0
- package/dist/agent/dreaming/staleness.d.ts +68 -0
- package/dist/agent/dreaming/staleness.d.ts.map +1 -0
- package/dist/agent/dreaming/staleness.js +281 -0
- package/dist/agent/dreaming/staleness.js.map +1 -0
- package/dist/agent/dreaming/types.d.ts +130 -0
- package/dist/agent/dreaming/types.d.ts.map +1 -0
- package/dist/agent/dreaming/types.js +10 -0
- package/dist/agent/dreaming/types.js.map +1 -0
- package/dist/agent/knowledge/archive-db.d.ts +114 -0
- package/dist/agent/knowledge/archive-db.d.ts.map +1 -0
- package/dist/agent/knowledge/archive-db.js +474 -0
- package/dist/agent/knowledge/archive-db.js.map +1 -0
- package/dist/agent/knowledge/chunk.d.ts +21 -0
- package/dist/agent/knowledge/chunk.d.ts.map +1 -0
- package/dist/agent/knowledge/chunk.js +67 -0
- package/dist/agent/knowledge/chunk.js.map +1 -0
- package/dist/agent/knowledge/config.d.ts +20 -0
- package/dist/agent/knowledge/config.d.ts.map +1 -0
- package/dist/agent/knowledge/config.js +143 -0
- package/dist/agent/knowledge/config.js.map +1 -0
- package/dist/agent/knowledge/graph-demo.d.ts +25 -0
- package/dist/agent/knowledge/graph-demo.d.ts.map +1 -0
- package/dist/agent/knowledge/graph-demo.js +132 -0
- package/dist/agent/knowledge/graph-demo.js.map +1 -0
- package/dist/agent/knowledge/index.d.ts +24 -0
- package/dist/agent/knowledge/index.d.ts.map +1 -0
- package/dist/agent/knowledge/index.js +50 -0
- package/dist/agent/knowledge/index.js.map +1 -0
- package/dist/agent/knowledge/indexer.d.ts +34 -0
- package/dist/agent/knowledge/indexer.d.ts.map +1 -0
- package/dist/agent/knowledge/indexer.js +271 -0
- package/dist/agent/knowledge/indexer.js.map +1 -0
- package/dist/agent/knowledge/lifecycle.d.ts +91 -0
- package/dist/agent/knowledge/lifecycle.d.ts.map +1 -0
- package/dist/agent/knowledge/lifecycle.js +205 -0
- package/dist/agent/knowledge/lifecycle.js.map +1 -0
- package/dist/agent/knowledge/provenance.d.ts +15 -0
- package/dist/agent/knowledge/provenance.d.ts.map +1 -0
- package/dist/agent/knowledge/provenance.js +37 -0
- package/dist/agent/knowledge/provenance.js.map +1 -0
- package/dist/agent/knowledge/reindex-cli.d.ts +13 -0
- package/dist/agent/knowledge/reindex-cli.d.ts.map +1 -0
- package/dist/agent/knowledge/reindex-cli.js +53 -0
- package/dist/agent/knowledge/reindex-cli.js.map +1 -0
- package/dist/agent/knowledge/reindex-spawn.d.ts +30 -0
- package/dist/agent/knowledge/reindex-spawn.d.ts.map +1 -0
- package/dist/agent/knowledge/reindex-spawn.js +97 -0
- package/dist/agent/knowledge/reindex-spawn.js.map +1 -0
- package/dist/agent/knowledge/shared-promote.d.ts +18 -0
- package/dist/agent/knowledge/shared-promote.d.ts.map +1 -0
- package/dist/agent/knowledge/shared-promote.js +29 -0
- package/dist/agent/knowledge/shared-promote.js.map +1 -0
- package/dist/agent/knowledge/shared-writer.d.ts +24 -0
- package/dist/agent/knowledge/shared-writer.d.ts.map +1 -0
- package/dist/agent/knowledge/shared-writer.js +97 -0
- package/dist/agent/knowledge/shared-writer.js.map +1 -0
- package/dist/agent/knowledge/types.d.ts +83 -0
- package/dist/agent/knowledge/types.d.ts.map +1 -0
- package/dist/agent/knowledge/types.js +12 -0
- package/dist/agent/knowledge/types.js.map +1 -0
- package/dist/agent/knowledge/wiki.d.ts +107 -0
- package/dist/agent/knowledge/wiki.d.ts.map +1 -0
- package/dist/agent/knowledge/wiki.js +415 -0
- package/dist/agent/knowledge/wiki.js.map +1 -0
- package/dist/agent/memory-metrics.d.ts +48 -0
- package/dist/agent/memory-metrics.d.ts.map +1 -0
- package/dist/agent/memory-metrics.js +156 -0
- package/dist/agent/memory-metrics.js.map +1 -0
- package/dist/agent/runner.d.ts +24 -1
- package/dist/agent/runner.d.ts.map +1 -1
- package/dist/agent/runner.js +82 -6
- package/dist/agent/runner.js.map +1 -1
- package/dist/agent/skill-learning/config.d.ts +18 -0
- package/dist/agent/skill-learning/config.d.ts.map +1 -0
- package/dist/agent/skill-learning/config.js +71 -0
- package/dist/agent/skill-learning/config.js.map +1 -0
- package/dist/agent/skill-learning/curator.d.ts +45 -0
- package/dist/agent/skill-learning/curator.d.ts.map +1 -0
- package/dist/agent/skill-learning/curator.js +171 -0
- package/dist/agent/skill-learning/curator.js.map +1 -0
- package/dist/agent/skill-learning/index.d.ts +79 -0
- package/dist/agent/skill-learning/index.d.ts.map +1 -0
- package/dist/agent/skill-learning/index.js +308 -0
- package/dist/agent/skill-learning/index.js.map +1 -0
- package/dist/agent/skill-learning/metrics.d.ts +13 -0
- package/dist/agent/skill-learning/metrics.d.ts.map +1 -0
- package/dist/agent/skill-learning/metrics.js +109 -0
- package/dist/agent/skill-learning/metrics.js.map +1 -0
- package/dist/agent/skill-learning/notifier.d.ts +111 -0
- package/dist/agent/skill-learning/notifier.d.ts.map +1 -0
- package/dist/agent/skill-learning/notifier.js +398 -0
- package/dist/agent/skill-learning/notifier.js.map +1 -0
- package/dist/agent/skill-learning/reviewer.d.ts +61 -0
- package/dist/agent/skill-learning/reviewer.d.ts.map +1 -0
- package/dist/agent/skill-learning/reviewer.js +271 -0
- package/dist/agent/skill-learning/reviewer.js.map +1 -0
- package/dist/agent/skill-learning/telemetry.d.ts +22 -0
- package/dist/agent/skill-learning/telemetry.d.ts.map +1 -0
- package/dist/agent/skill-learning/telemetry.js +90 -0
- package/dist/agent/skill-learning/telemetry.js.map +1 -0
- package/dist/agent/skill-learning/trigger.d.ts +23 -0
- package/dist/agent/skill-learning/trigger.d.ts.map +1 -0
- package/dist/agent/skill-learning/trigger.js +44 -0
- package/dist/agent/skill-learning/trigger.js.map +1 -0
- package/dist/agent/skill-learning/types.d.ts +165 -0
- package/dist/agent/skill-learning/types.d.ts.map +1 -0
- package/dist/agent/skill-learning/types.js +11 -0
- package/dist/agent/skill-learning/types.js.map +1 -0
- package/dist/agent/skill-learning/writer.d.ts +37 -0
- package/dist/agent/skill-learning/writer.d.ts.map +1 -0
- package/dist/agent/skill-learning/writer.js +223 -0
- package/dist/agent/skill-learning/writer.js.map +1 -0
- package/dist/agent/workspace-loader.d.ts +83 -6
- package/dist/agent/workspace-loader.d.ts.map +1 -1
- package/dist/agent/workspace-loader.js +207 -14
- package/dist/agent/workspace-loader.js.map +1 -1
- package/dist/api/gateway-router.d.ts +2 -0
- package/dist/api/gateway-router.d.ts.map +1 -1
- package/dist/api/gateway-router.js +293 -6
- package/dist/api/gateway-router.js.map +1 -1
- package/dist/api/share-router.d.ts.map +1 -1
- package/dist/api/share-router.js +27 -1
- package/dist/api/share-router.js.map +1 -1
- package/dist/api/skills-router.d.ts +2 -2
- package/dist/api/skills-router.d.ts.map +1 -1
- package/dist/api/skills-router.js +61 -1
- package/dist/api/skills-router.js.map +1 -1
- package/dist/apps/agent-manager.d.ts +7 -0
- package/dist/apps/agent-manager.d.ts.map +1 -1
- package/dist/apps/agent-manager.js +13 -1
- package/dist/apps/agent-manager.js.map +1 -1
- package/dist/config/migrator.d.ts +2 -0
- package/dist/config/migrator.d.ts.map +1 -1
- package/dist/config/migrator.js +72 -1
- package/dist/config/migrator.js.map +1 -1
- package/dist/history/cleanup.d.ts +7 -0
- package/dist/history/cleanup.d.ts.map +1 -1
- package/dist/history/cleanup.js +27 -0
- package/dist/history/cleanup.js.map +1 -1
- package/dist/history/db.d.ts +65 -0
- package/dist/history/db.d.ts.map +1 -1
- package/dist/history/db.js +261 -0
- package/dist/history/db.js.map +1 -1
- package/dist/index.js +122 -20
- package/dist/index.js.map +1 -1
- package/dist/session/process.d.ts +10 -0
- package/dist/session/process.d.ts.map +1 -1
- package/dist/session/process.js +86 -1
- package/dist/session/process.js.map +1 -1
- package/dist/share/share-store.d.ts +11 -0
- package/dist/share/share-store.d.ts.map +1 -1
- package/dist/share/share-store.js +3 -1
- package/dist/share/share-store.js.map +1 -1
- package/dist/skills/loader.d.ts +8 -0
- package/dist/skills/loader.d.ts.map +1 -1
- package/dist/skills/loader.js +29 -1
- package/dist/skills/loader.js.map +1 -1
- package/dist/types.d.ts +116 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/ui/web-ui.d.ts.map +1 -1
- package/dist/ui/web-ui.js +1126 -3
- package/dist/ui/web-ui.js.map +1 -1
- package/mcp/package.json +2 -1
- package/mcp/server.ts +2 -0
- package/mcp/tools/image/module.ts +114 -9
- package/mcp/tools/memory/archive-reader.test.ts +212 -0
- package/mcp/tools/memory/archive-reader.ts +253 -0
- package/mcp/tools/memory/module.ts +152 -0
- package/mcp/tools/memory/retrieval-recorder.ts +66 -0
- package/mcp/tools/shared/share-client.ts +20 -1
- package/mcp/tools/skills/module.ts +28 -0
- package/package.json +1 -1
- package/resource/claude_gateway.svg +1038 -112
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Archive indexer (planning-64 K0).
|
|
4
|
+
*
|
|
5
|
+
* Walks an agent's memory files, chunks each, tags provenance, and writes them
|
|
6
|
+
* into the per-agent `kb.sqlite`. Hash-guarded: an unchanged file is skipped;
|
|
7
|
+
* a changed file is re-chunked and its stale chunks replaced; a file that
|
|
8
|
+
* disappeared is pruned. Deterministic (timestamps come from file mtime, not the
|
|
9
|
+
* wall clock) so a reindex of unchanged files is a true no-op.
|
|
10
|
+
*
|
|
11
|
+
* Synchronous by construction (node:sqlite + fs). Callers MUST invoke this OFF
|
|
12
|
+
* the gateway event loop (nightly dreaming spawn / out-of-process). K0 does not
|
|
13
|
+
* wire it into any gateway runtime path — it is dormant until K1.
|
|
14
|
+
*/
|
|
15
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
16
|
+
if (k2 === undefined) k2 = k;
|
|
17
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
18
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
19
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
20
|
+
}
|
|
21
|
+
Object.defineProperty(o, k2, desc);
|
|
22
|
+
}) : (function(o, m, k, k2) {
|
|
23
|
+
if (k2 === undefined) k2 = k;
|
|
24
|
+
o[k2] = m[k];
|
|
25
|
+
}));
|
|
26
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
27
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
28
|
+
}) : function(o, v) {
|
|
29
|
+
o["default"] = v;
|
|
30
|
+
});
|
|
31
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
32
|
+
var ownKeys = function(o) {
|
|
33
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
34
|
+
var ar = [];
|
|
35
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
36
|
+
return ar;
|
|
37
|
+
};
|
|
38
|
+
return ownKeys(o);
|
|
39
|
+
};
|
|
40
|
+
return function (mod) {
|
|
41
|
+
if (mod && mod.__esModule) return mod;
|
|
42
|
+
var result = {};
|
|
43
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
44
|
+
__setModuleDefault(result, mod);
|
|
45
|
+
return result;
|
|
46
|
+
};
|
|
47
|
+
})();
|
|
48
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
49
|
+
exports.archiveDbPath = archiveDbPath;
|
|
50
|
+
exports.indexAgentArchive = indexAgentArchive;
|
|
51
|
+
exports.indexSharedArchive = indexSharedArchive;
|
|
52
|
+
const path = __importStar(require("path"));
|
|
53
|
+
const fs = __importStar(require("fs"));
|
|
54
|
+
const crypto = __importStar(require("crypto"));
|
|
55
|
+
const archive_db_1 = require("./archive-db");
|
|
56
|
+
const chunk_1 = require("./chunk");
|
|
57
|
+
const provenance_1 = require("./provenance");
|
|
58
|
+
const lifecycle_1 = require("./lifecycle");
|
|
59
|
+
const config_1 = require("./config");
|
|
60
|
+
const wiki_1 = require("./wiki");
|
|
61
|
+
/** Evergreen core files (indexed even though they live at the workspace root). */
|
|
62
|
+
const EVERGREEN_FILES = ['MEMORY.md', 'USER.md'];
|
|
63
|
+
/** Default location of an agent's archive DB (sibling to history.db). */
|
|
64
|
+
function archiveDbPath(workspaceDir) {
|
|
65
|
+
// workspaceDir = agents/<id>/workspace ; the DB lives at agents/<id>/kb.sqlite
|
|
66
|
+
return path.join(path.dirname(workspaceDir), 'kb.sqlite');
|
|
67
|
+
}
|
|
68
|
+
/** Recursively collect `*.md` files under a directory, as absolute paths. */
|
|
69
|
+
function walkMarkdown(dir) {
|
|
70
|
+
const out = [];
|
|
71
|
+
let entries;
|
|
72
|
+
try {
|
|
73
|
+
entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
return out;
|
|
77
|
+
}
|
|
78
|
+
// Sort for deterministic index order across runs/platforms.
|
|
79
|
+
entries.sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0));
|
|
80
|
+
for (const e of entries) {
|
|
81
|
+
// Skip dotfiles — in particular a `.tmp-*` file left by a crashed shared-note
|
|
82
|
+
// write must never be indexed as a real note.
|
|
83
|
+
if (e.name.startsWith('.'))
|
|
84
|
+
continue;
|
|
85
|
+
const full = path.join(dir, e.name);
|
|
86
|
+
if (e.isDirectory())
|
|
87
|
+
out.push(...walkMarkdown(full));
|
|
88
|
+
else if (e.isFile() && e.name.toLowerCase().endsWith('.md'))
|
|
89
|
+
out.push(full);
|
|
90
|
+
}
|
|
91
|
+
return out;
|
|
92
|
+
}
|
|
93
|
+
/** The set of memory files to index for an agent (absolute paths). */
|
|
94
|
+
function collectSourceFiles(workspaceDir) {
|
|
95
|
+
const files = [];
|
|
96
|
+
for (const name of EVERGREEN_FILES) {
|
|
97
|
+
const p = path.join(workspaceDir, name);
|
|
98
|
+
if (fs.existsSync(p) && fs.statSync(p).isFile())
|
|
99
|
+
files.push(p);
|
|
100
|
+
}
|
|
101
|
+
files.push(...walkMarkdown(path.join(workspaceDir, 'memory')));
|
|
102
|
+
return files;
|
|
103
|
+
}
|
|
104
|
+
function sha256(content) {
|
|
105
|
+
return crypto.createHash('sha256').update(content).digest('hex');
|
|
106
|
+
}
|
|
107
|
+
/** Workspace-relative POSIX path (for storage + provenance classification). */
|
|
108
|
+
function relPosix(workspaceDir, absFile) {
|
|
109
|
+
return path.relative(workspaceDir, absFile).split(path.sep).join('/');
|
|
110
|
+
}
|
|
111
|
+
/** The entry_hash of the block a chunk starts in, or null if it starts outside any. */
|
|
112
|
+
function blockHashForLine(blocks, line) {
|
|
113
|
+
for (const b of blocks) {
|
|
114
|
+
if (line >= b.startLine && line <= b.endLine)
|
|
115
|
+
return b.entryHash;
|
|
116
|
+
}
|
|
117
|
+
return null;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Index one agent's archive. Returns per-run counts. A no-op (returns zeroed
|
|
121
|
+
* counts) when the archive is disabled.
|
|
122
|
+
*
|
|
123
|
+
* @param workspaceDir the agent's workspace dir (agents/<id>/workspace)
|
|
124
|
+
* @param agentCfg per-agent `gateway.knowledge.archive` override
|
|
125
|
+
* @param globalCfg global `gateway.knowledge.archive`
|
|
126
|
+
*/
|
|
127
|
+
function indexAgentArchive(workspaceDir, agentCfg, globalCfg) {
|
|
128
|
+
const cfg = (0, config_1.resolveArchiveConfig)(agentCfg, globalCfg);
|
|
129
|
+
const empty = {
|
|
130
|
+
filesSeen: 0,
|
|
131
|
+
filesIndexed: 0,
|
|
132
|
+
filesSkipped: 0,
|
|
133
|
+
filesRemoved: 0,
|
|
134
|
+
chunksWritten: 0,
|
|
135
|
+
};
|
|
136
|
+
if (!cfg.enabled)
|
|
137
|
+
return empty;
|
|
138
|
+
const db = archive_db_1.ArchiveDB.forPath(archiveDbPath(workspaceDir), cfg.tokenizer);
|
|
139
|
+
return reindexInto(db, {
|
|
140
|
+
baseDir: workspaceDir,
|
|
141
|
+
files: collectSourceFiles(workspaceDir),
|
|
142
|
+
chunkTokens: cfg.chunkTokens,
|
|
143
|
+
chunkOverlap: cfg.chunkOverlap,
|
|
144
|
+
originFn: provenance_1.classifyOrigin,
|
|
145
|
+
source: 'memory',
|
|
146
|
+
projectKey: null,
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Shared indexing core (used by both the per-agent and shared archives):
|
|
151
|
+
* hash-guarded chunk+provenance write of each file, then prune only files that
|
|
152
|
+
* genuinely disappeared. Deterministic (mtime-based) so unchanged input is a
|
|
153
|
+
* true no-op.
|
|
154
|
+
*/
|
|
155
|
+
function reindexInto(db, opts) {
|
|
156
|
+
const result = {
|
|
157
|
+
filesSeen: 0,
|
|
158
|
+
filesIndexed: 0,
|
|
159
|
+
filesSkipped: 0,
|
|
160
|
+
filesRemoved: 0,
|
|
161
|
+
chunksWritten: 0,
|
|
162
|
+
};
|
|
163
|
+
const seenRel = new Set();
|
|
164
|
+
for (const abs of opts.files) {
|
|
165
|
+
let content;
|
|
166
|
+
let stat;
|
|
167
|
+
try {
|
|
168
|
+
stat = fs.statSync(abs);
|
|
169
|
+
content = fs.readFileSync(abs, 'utf8');
|
|
170
|
+
}
|
|
171
|
+
catch {
|
|
172
|
+
continue; // race: file vanished mid-walk — treat as not present
|
|
173
|
+
}
|
|
174
|
+
const rel = relPosix(opts.baseDir, abs);
|
|
175
|
+
seenRel.add(rel);
|
|
176
|
+
result.filesSeen++;
|
|
177
|
+
const hash = sha256(content);
|
|
178
|
+
const existing = db.getSource(rel);
|
|
179
|
+
if (existing && existing.hash === hash) {
|
|
180
|
+
result.filesSkipped++; // hash-guarded: unchanged, no re-chunk
|
|
181
|
+
continue;
|
|
182
|
+
}
|
|
183
|
+
const mtime = Math.floor(stat.mtimeMs);
|
|
184
|
+
const origin = opts.originFn(rel);
|
|
185
|
+
const chunks = (0, chunk_1.chunkMarkdown)(content, opts.chunkTokens, opts.chunkOverlap);
|
|
186
|
+
// Entry-lifecycle identity (planning-66): only archive-tier files get an
|
|
187
|
+
// entry_hash (evergreen Lane-1, pinned files and the shared vault are exempt,
|
|
188
|
+
// so the GC can never consider them). Each FTS chunk inherits the entry_hash of
|
|
189
|
+
// the markdown block it starts in; blocks are the clean, movable unit the GC
|
|
190
|
+
// operates on (chunks are overlapping token windows and must never be moved).
|
|
191
|
+
const blocks = opts.source === 'memory' && (0, lifecycle_1.isArchiveTierPath)(rel) ? (0, lifecycle_1.parseEntryBlocks)(content) : [];
|
|
192
|
+
const rows = chunks.map((c) => ({
|
|
193
|
+
chunk: {
|
|
194
|
+
id: `${rel}#${c.startLine}-${c.endLine}`,
|
|
195
|
+
path: rel,
|
|
196
|
+
startLine: c.startLine,
|
|
197
|
+
endLine: c.endLine,
|
|
198
|
+
text: c.text,
|
|
199
|
+
updatedAt: mtime,
|
|
200
|
+
},
|
|
201
|
+
recall: { importance: null, triggers: null, projectKey: opts.projectKey },
|
|
202
|
+
provenance: {
|
|
203
|
+
originClass: origin,
|
|
204
|
+
sessionKind: 'unknown', // file-indexed content carries no session context
|
|
205
|
+
observedAt: mtime,
|
|
206
|
+
supersedesKey: null,
|
|
207
|
+
},
|
|
208
|
+
entryHash: blocks.length ? blockHashForLine(blocks, c.startLine) : null,
|
|
209
|
+
}));
|
|
210
|
+
db.replaceSource({ path: rel, hash, mtime, size: stat.size, source: opts.source }, rows, blocks.map((b) => ({ entryHash: b.entryHash, firstSeen: mtime })));
|
|
211
|
+
result.filesIndexed++;
|
|
212
|
+
result.chunksWritten += rows.length;
|
|
213
|
+
}
|
|
214
|
+
// Prune sources whose file genuinely disappeared. A file that still exists but
|
|
215
|
+
// whose stat/read threw a TRANSIENT error this run (EMFILE/EACCES/EINTR) is not
|
|
216
|
+
// in `seenRel` either — but it must NOT be pruned, or a live note silently loses
|
|
217
|
+
// its index between runs. Confirm real absence on disk before deleting.
|
|
218
|
+
for (const rel of db.listSourcePaths()) {
|
|
219
|
+
if (seenRel.has(rel))
|
|
220
|
+
continue;
|
|
221
|
+
if (fs.existsSync(path.join(opts.baseDir, rel)))
|
|
222
|
+
continue; // present but unreadable this run — keep
|
|
223
|
+
db.deleteSource(rel);
|
|
224
|
+
result.filesRemoved++;
|
|
225
|
+
}
|
|
226
|
+
return result;
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Index the SHARED, cross-agent vault (planning-64 K3): every `*.md` under the
|
|
230
|
+
* project's `notes/` dir is chunked into the shared `kb.sqlite`. Shared notes are
|
|
231
|
+
* authored by the owner's own agents (same trust domain) → provenance `agent`.
|
|
232
|
+
* No-op when shared KB is disabled. Runs OFF the gateway event loop, same as the
|
|
233
|
+
* per-agent indexer.
|
|
234
|
+
*/
|
|
235
|
+
function indexSharedArchive(agentCfg, globalCfg) {
|
|
236
|
+
const empty = {
|
|
237
|
+
filesSeen: 0,
|
|
238
|
+
filesIndexed: 0,
|
|
239
|
+
filesSkipped: 0,
|
|
240
|
+
filesRemoved: 0,
|
|
241
|
+
chunksWritten: 0,
|
|
242
|
+
};
|
|
243
|
+
const cfg = (0, config_1.resolveSharedConfig)(agentCfg, globalCfg);
|
|
244
|
+
if (!cfg.enabled)
|
|
245
|
+
return empty;
|
|
246
|
+
const notesDir = (0, config_1.sharedNotesDir)(cfg);
|
|
247
|
+
const db = archive_db_1.ArchiveDB.forPath((0, config_1.sharedDbPath)(cfg), config_1.ARCHIVE_DEFAULTS.tokenizer);
|
|
248
|
+
const result = reindexInto(db, {
|
|
249
|
+
baseDir: notesDir,
|
|
250
|
+
files: walkMarkdown(notesDir),
|
|
251
|
+
chunkTokens: config_1.ARCHIVE_DEFAULTS.chunkTokens,
|
|
252
|
+
chunkOverlap: config_1.ARCHIVE_DEFAULTS.chunkOverlap,
|
|
253
|
+
originFn: () => 'agent',
|
|
254
|
+
source: 'shared',
|
|
255
|
+
projectKey: cfg.project,
|
|
256
|
+
});
|
|
257
|
+
// K5 (opt-in): compile the memory-wiki graph + dashboards over the whole vault.
|
|
258
|
+
// Best-effort — a compile failure never affects indexing. mtime-free determinism
|
|
259
|
+
// is not required here (reports are regenerated each run), so wall-clock `now` is
|
|
260
|
+
// used for the staleness dashboard.
|
|
261
|
+
if (cfg.graph) {
|
|
262
|
+
try {
|
|
263
|
+
(0, wiki_1.compileWiki)((0, config_1.sharedVaultDir)(cfg), Date.now());
|
|
264
|
+
}
|
|
265
|
+
catch {
|
|
266
|
+
/* best-effort */
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
return result;
|
|
270
|
+
}
|
|
271
|
+
//# sourceMappingURL=indexer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"indexer.js","sourceRoot":"","sources":["../../../src/agent/knowledge/indexer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Archive entry lifecycle helpers (planning-66).
|
|
3
|
+
*
|
|
4
|
+
* The Lane-2 archive (`memory/*.md` → `kb.sqlite` → `memory_search`) accumulates
|
|
5
|
+
* stale / superseded entries with no stable per-entry identity to decide staleness
|
|
6
|
+
* from: the FTS chunk id is line-based (`${rel}#${start}-${end}`) and dies on every
|
|
7
|
+
* re-chunk, and `updated_at`/`observed_at` are file mtime (re-stamped on any edit).
|
|
8
|
+
*
|
|
9
|
+
* This module gives every archive ENTRY a reindex-surviving identity — a content
|
|
10
|
+
* hash of its normalized text (`entryHash`) — plus the two pure primitives the GC
|
|
11
|
+
* needs: a markdown-block parser (an "entry" = a top-level bullet or an h3–h6 entry
|
|
12
|
+
* header + its body, the same archivable unit the compactor moves) and deterministic
|
|
13
|
+
* supersession detection (a replacement verb + `#N` marks the older `#N` entry
|
|
14
|
+
* superseded). Everything here is pure — no I/O, no clock — so it is exhaustively
|
|
15
|
+
* testable and safe to call from the indexer and the nightly GC alike.
|
|
16
|
+
*
|
|
17
|
+
* Identity is block-level (not chunk-level) on purpose: FTS chunks are token-window
|
|
18
|
+
* slices with overlap (`chunk.ts`), so moving a chunk's raw lines would corrupt an
|
|
19
|
+
* overlapping neighbour. Blocks are clean markdown units, so the GC moves whole
|
|
20
|
+
* blocks. Each FTS chunk simply inherits the `entryHash` of the block it starts in,
|
|
21
|
+
* which is what the read-path recall counter is keyed to.
|
|
22
|
+
*/
|
|
23
|
+
/** Pinned archive files are searchable but structurally exempt from GC. */
|
|
24
|
+
export declare const PINNED_PREFIX = "memory/pinned/";
|
|
25
|
+
/**
|
|
26
|
+
* True when a workspace-relative path is a GC-eligible archive-tier entry source
|
|
27
|
+
* (planning-66). The archive tier is `memory/**.md`, EXCEPT:
|
|
28
|
+
* - evergreen Lane-1 (`MEMORY.md`/`USER.md` at the root) — never touched,
|
|
29
|
+
* - pinned files (`memory/pinned/**`) — searchable but never aged out.
|
|
30
|
+
* Only these files get an `entry_hash` + lifecycle row; everything else (evergreen,
|
|
31
|
+
* pinned, the shared vault) has no lifecycle, so the GC can never consider it.
|
|
32
|
+
*/
|
|
33
|
+
export declare function isArchiveTierPath(rel: string): boolean;
|
|
34
|
+
/** A parsed archive entry block with its 1-indexed inclusive line range. */
|
|
35
|
+
export interface EntryBlock {
|
|
36
|
+
text: string;
|
|
37
|
+
startLine: number;
|
|
38
|
+
endLine: number;
|
|
39
|
+
entryHash: string;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Normalize entry text for hashing: collapse every run of whitespace (including
|
|
43
|
+
* newlines) to a single space and trim. A block re-chunked, re-indented, or
|
|
44
|
+
* reflowed keeps the SAME hash — so its lifecycle (age, recall, invalidation)
|
|
45
|
+
* survives cosmetic edits. A genuine content change yields a new hash, which is
|
|
46
|
+
* correct: it is a new fact, so it starts a fresh age.
|
|
47
|
+
*/
|
|
48
|
+
export declare function normalizeEntryText(s: string): string;
|
|
49
|
+
/** Stable content identity for an archive entry: sha256 of its normalized text. */
|
|
50
|
+
export declare function entryHash(s: string): string;
|
|
51
|
+
/**
|
|
52
|
+
* Parse an archive markdown file into its entry blocks. An entry is either:
|
|
53
|
+
* - a top-level bullet (`- `/`* ` at column 0) plus its contiguous non-blank,
|
|
54
|
+
* non-header, non-bullet continuation lines, or
|
|
55
|
+
* - an h3–h6 entry header plus its body up to the next header or blank line.
|
|
56
|
+
* h1/h2 section titles, blank lines and free prose are NOT entries (they are
|
|
57
|
+
* structure, never moved). Mirrors the compactor's block model so the GC and the
|
|
58
|
+
* compactor agree on what a movable unit is. Line ranges are 1-indexed inclusive.
|
|
59
|
+
*/
|
|
60
|
+
export declare function parseEntryBlocks(content: string): EntryBlock[];
|
|
61
|
+
/**
|
|
62
|
+
* A replacement marker: an explicit supersession verb immediately followed by an
|
|
63
|
+
* issue/PR reference `#N`. Case-INSENSITIVE on the verb but the `#N` is required,
|
|
64
|
+
* so prose like "Closes #12", "merged into develop", or a bare "#12" never
|
|
65
|
+
* matches — only "supersedes #316" / "replaces #12" / "obsoletes #7". Mirrors the
|
|
66
|
+
* compactor's precision-over-recall stance: a false supersession only soft-
|
|
67
|
+
* invalidates (still searchable), never deletes, but we keep it tight anyway.
|
|
68
|
+
*/
|
|
69
|
+
export declare const SUPERSEDE_RE: RegExp;
|
|
70
|
+
/** All distinct `#N` numbers a block references (its candidate identities/targets). */
|
|
71
|
+
export declare function referencedIds(text: string): Set<number>;
|
|
72
|
+
/** The `#N` numbers a block declares it supersedes (verb + `#N`). */
|
|
73
|
+
export declare function supersededIds(text: string): Set<number>;
|
|
74
|
+
/** One resolved supersession: `targetHash` is superseded by `bySpec`. */
|
|
75
|
+
export interface Supersession {
|
|
76
|
+
targetHash: string;
|
|
77
|
+
bySpec: string;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Deterministically resolve which entries are superseded, over a set of blocks
|
|
81
|
+
* (the whole archive tier). For every block B that declares "supersedes #N", any
|
|
82
|
+
* OTHER block A that references `#N` is marked superseded-by-B. Precision guards:
|
|
83
|
+
* - the trigger requires the verb+`#N` form (referencing `#N` alone is not a
|
|
84
|
+
* trigger — only a target),
|
|
85
|
+
* - a block never supersedes itself,
|
|
86
|
+
* - a block that itself supersedes something is not eligible to be a target of
|
|
87
|
+
* the same `#N` (the newer, superseding entry stays live).
|
|
88
|
+
* Returns one entry per superseded target hash (last writer wins on conflict).
|
|
89
|
+
*/
|
|
90
|
+
export declare function detectSupersessions(blocks: EntryBlock[]): Supersession[];
|
|
91
|
+
//# sourceMappingURL=lifecycle.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lifecycle.d.ts","sourceRoot":"","sources":["../../../src/agent/knowledge/lifecycle.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAIH,2EAA2E;AAC3E,eAAO,MAAM,aAAa,mBAAmB,CAAC;AAE9C;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAKtD;AAED,4EAA4E;AAC5E,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED,mFAAmF;AACnF,wBAAgB,SAAS,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAE3C;AAQD;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,EAAE,CAqC9D;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,YAAY,QAA8D,CAAC;AAExF,uFAAuF;AACvF,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAIvD;AAED,qEAAqE;AACrE,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAIvD;AAED,yEAAyE;AACzE,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,UAAU,EAAE,GAAG,YAAY,EAAE,CAkBxE"}
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Archive entry lifecycle helpers (planning-66).
|
|
4
|
+
*
|
|
5
|
+
* The Lane-2 archive (`memory/*.md` → `kb.sqlite` → `memory_search`) accumulates
|
|
6
|
+
* stale / superseded entries with no stable per-entry identity to decide staleness
|
|
7
|
+
* from: the FTS chunk id is line-based (`${rel}#${start}-${end}`) and dies on every
|
|
8
|
+
* re-chunk, and `updated_at`/`observed_at` are file mtime (re-stamped on any edit).
|
|
9
|
+
*
|
|
10
|
+
* This module gives every archive ENTRY a reindex-surviving identity — a content
|
|
11
|
+
* hash of its normalized text (`entryHash`) — plus the two pure primitives the GC
|
|
12
|
+
* needs: a markdown-block parser (an "entry" = a top-level bullet or an h3–h6 entry
|
|
13
|
+
* header + its body, the same archivable unit the compactor moves) and deterministic
|
|
14
|
+
* supersession detection (a replacement verb + `#N` marks the older `#N` entry
|
|
15
|
+
* superseded). Everything here is pure — no I/O, no clock — so it is exhaustively
|
|
16
|
+
* testable and safe to call from the indexer and the nightly GC alike.
|
|
17
|
+
*
|
|
18
|
+
* Identity is block-level (not chunk-level) on purpose: FTS chunks are token-window
|
|
19
|
+
* slices with overlap (`chunk.ts`), so moving a chunk's raw lines would corrupt an
|
|
20
|
+
* overlapping neighbour. Blocks are clean markdown units, so the GC moves whole
|
|
21
|
+
* blocks. Each FTS chunk simply inherits the `entryHash` of the block it starts in,
|
|
22
|
+
* which is what the read-path recall counter is keyed to.
|
|
23
|
+
*/
|
|
24
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
25
|
+
if (k2 === undefined) k2 = k;
|
|
26
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
27
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
28
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
29
|
+
}
|
|
30
|
+
Object.defineProperty(o, k2, desc);
|
|
31
|
+
}) : (function(o, m, k, k2) {
|
|
32
|
+
if (k2 === undefined) k2 = k;
|
|
33
|
+
o[k2] = m[k];
|
|
34
|
+
}));
|
|
35
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
36
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
37
|
+
}) : function(o, v) {
|
|
38
|
+
o["default"] = v;
|
|
39
|
+
});
|
|
40
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
41
|
+
var ownKeys = function(o) {
|
|
42
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
43
|
+
var ar = [];
|
|
44
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
45
|
+
return ar;
|
|
46
|
+
};
|
|
47
|
+
return ownKeys(o);
|
|
48
|
+
};
|
|
49
|
+
return function (mod) {
|
|
50
|
+
if (mod && mod.__esModule) return mod;
|
|
51
|
+
var result = {};
|
|
52
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
53
|
+
__setModuleDefault(result, mod);
|
|
54
|
+
return result;
|
|
55
|
+
};
|
|
56
|
+
})();
|
|
57
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
58
|
+
exports.SUPERSEDE_RE = exports.PINNED_PREFIX = void 0;
|
|
59
|
+
exports.isArchiveTierPath = isArchiveTierPath;
|
|
60
|
+
exports.normalizeEntryText = normalizeEntryText;
|
|
61
|
+
exports.entryHash = entryHash;
|
|
62
|
+
exports.parseEntryBlocks = parseEntryBlocks;
|
|
63
|
+
exports.referencedIds = referencedIds;
|
|
64
|
+
exports.supersededIds = supersededIds;
|
|
65
|
+
exports.detectSupersessions = detectSupersessions;
|
|
66
|
+
const crypto = __importStar(require("crypto"));
|
|
67
|
+
/** Pinned archive files are searchable but structurally exempt from GC. */
|
|
68
|
+
exports.PINNED_PREFIX = 'memory/pinned/';
|
|
69
|
+
/**
|
|
70
|
+
* True when a workspace-relative path is a GC-eligible archive-tier entry source
|
|
71
|
+
* (planning-66). The archive tier is `memory/**.md`, EXCEPT:
|
|
72
|
+
* - evergreen Lane-1 (`MEMORY.md`/`USER.md` at the root) — never touched,
|
|
73
|
+
* - pinned files (`memory/pinned/**`) — searchable but never aged out.
|
|
74
|
+
* Only these files get an `entry_hash` + lifecycle row; everything else (evergreen,
|
|
75
|
+
* pinned, the shared vault) has no lifecycle, so the GC can never consider it.
|
|
76
|
+
*/
|
|
77
|
+
function isArchiveTierPath(rel) {
|
|
78
|
+
const p = rel.replace(/\\/g, '/');
|
|
79
|
+
if (p === 'MEMORY.md' || p === 'USER.md')
|
|
80
|
+
return false;
|
|
81
|
+
if (p.startsWith(exports.PINNED_PREFIX))
|
|
82
|
+
return false;
|
|
83
|
+
return p.startsWith('memory/') && p.endsWith('.md');
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Normalize entry text for hashing: collapse every run of whitespace (including
|
|
87
|
+
* newlines) to a single space and trim. A block re-chunked, re-indented, or
|
|
88
|
+
* reflowed keeps the SAME hash — so its lifecycle (age, recall, invalidation)
|
|
89
|
+
* survives cosmetic edits. A genuine content change yields a new hash, which is
|
|
90
|
+
* correct: it is a new fact, so it starts a fresh age.
|
|
91
|
+
*/
|
|
92
|
+
function normalizeEntryText(s) {
|
|
93
|
+
return s.replace(/\s+/g, ' ').trim();
|
|
94
|
+
}
|
|
95
|
+
/** Stable content identity for an archive entry: sha256 of its normalized text. */
|
|
96
|
+
function entryHash(s) {
|
|
97
|
+
return crypto.createHash('sha256').update(normalizeEntryText(s)).digest('hex');
|
|
98
|
+
}
|
|
99
|
+
const TOP_BULLET_RE = /^[-*] /;
|
|
100
|
+
const HEADER_RE = /^#{1,6} /;
|
|
101
|
+
/** h3–h6 can be a completed-entry header; h1/h2 are structural sections. */
|
|
102
|
+
const ENTRY_HEADER_RE = /^#{3,6} /;
|
|
103
|
+
const BLANK_RE = /^\s*$/;
|
|
104
|
+
/**
|
|
105
|
+
* Parse an archive markdown file into its entry blocks. An entry is either:
|
|
106
|
+
* - a top-level bullet (`- `/`* ` at column 0) plus its contiguous non-blank,
|
|
107
|
+
* non-header, non-bullet continuation lines, or
|
|
108
|
+
* - an h3–h6 entry header plus its body up to the next header or blank line.
|
|
109
|
+
* h1/h2 section titles, blank lines and free prose are NOT entries (they are
|
|
110
|
+
* structure, never moved). Mirrors the compactor's block model so the GC and the
|
|
111
|
+
* compactor agree on what a movable unit is. Line ranges are 1-indexed inclusive.
|
|
112
|
+
*/
|
|
113
|
+
function parseEntryBlocks(content) {
|
|
114
|
+
const lines = content.split('\n');
|
|
115
|
+
const blocks = [];
|
|
116
|
+
for (let i = 0; i < lines.length; i++) {
|
|
117
|
+
const line = lines[i];
|
|
118
|
+
if (ENTRY_HEADER_RE.test(line)) {
|
|
119
|
+
const blockLines = [line];
|
|
120
|
+
let j = i + 1;
|
|
121
|
+
while (j < lines.length && !BLANK_RE.test(lines[j]) && !HEADER_RE.test(lines[j])) {
|
|
122
|
+
blockLines.push(lines[j]);
|
|
123
|
+
j++;
|
|
124
|
+
}
|
|
125
|
+
const text = blockLines.join('\n');
|
|
126
|
+
blocks.push({ text, startLine: i + 1, endLine: j, entryHash: entryHash(text) });
|
|
127
|
+
i = j - 1;
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
130
|
+
if (TOP_BULLET_RE.test(line)) {
|
|
131
|
+
const blockLines = [line];
|
|
132
|
+
let j = i + 1;
|
|
133
|
+
while (j < lines.length &&
|
|
134
|
+
!BLANK_RE.test(lines[j]) &&
|
|
135
|
+
!HEADER_RE.test(lines[j]) &&
|
|
136
|
+
!TOP_BULLET_RE.test(lines[j])) {
|
|
137
|
+
blockLines.push(lines[j]);
|
|
138
|
+
j++;
|
|
139
|
+
}
|
|
140
|
+
const text = blockLines.join('\n');
|
|
141
|
+
blocks.push({ text, startLine: i + 1, endLine: j, entryHash: entryHash(text) });
|
|
142
|
+
i = j - 1;
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
// h1/h2 section titles, blanks, prose → not an entry.
|
|
146
|
+
}
|
|
147
|
+
return blocks;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* A replacement marker: an explicit supersession verb immediately followed by an
|
|
151
|
+
* issue/PR reference `#N`. Case-INSENSITIVE on the verb but the `#N` is required,
|
|
152
|
+
* so prose like "Closes #12", "merged into develop", or a bare "#12" never
|
|
153
|
+
* matches — only "supersedes #316" / "replaces #12" / "obsoletes #7". Mirrors the
|
|
154
|
+
* compactor's precision-over-recall stance: a false supersession only soft-
|
|
155
|
+
* invalidates (still searchable), never deletes, but we keep it tight anyway.
|
|
156
|
+
*/
|
|
157
|
+
exports.SUPERSEDE_RE = /\b(?:supersed(?:e|es|ed)|replaces?|obsoletes?)\s+#(\d+)/gi;
|
|
158
|
+
/** All distinct `#N` numbers a block references (its candidate identities/targets). */
|
|
159
|
+
function referencedIds(text) {
|
|
160
|
+
const ids = new Set();
|
|
161
|
+
for (const m of text.matchAll(/#(\d+)\b/g))
|
|
162
|
+
ids.add(Number(m[1]));
|
|
163
|
+
return ids;
|
|
164
|
+
}
|
|
165
|
+
/** The `#N` numbers a block declares it supersedes (verb + `#N`). */
|
|
166
|
+
function supersededIds(text) {
|
|
167
|
+
const ids = new Set();
|
|
168
|
+
for (const m of text.matchAll(exports.SUPERSEDE_RE))
|
|
169
|
+
ids.add(Number(m[1]));
|
|
170
|
+
return ids;
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Deterministically resolve which entries are superseded, over a set of blocks
|
|
174
|
+
* (the whole archive tier). For every block B that declares "supersedes #N", any
|
|
175
|
+
* OTHER block A that references `#N` is marked superseded-by-B. Precision guards:
|
|
176
|
+
* - the trigger requires the verb+`#N` form (referencing `#N` alone is not a
|
|
177
|
+
* trigger — only a target),
|
|
178
|
+
* - a block never supersedes itself,
|
|
179
|
+
* - a block that itself supersedes something is not eligible to be a target of
|
|
180
|
+
* the same `#N` (the newer, superseding entry stays live).
|
|
181
|
+
* Returns one entry per superseded target hash (last writer wins on conflict).
|
|
182
|
+
*/
|
|
183
|
+
function detectSupersessions(blocks) {
|
|
184
|
+
const out = new Map();
|
|
185
|
+
for (const b of blocks) {
|
|
186
|
+
const supersedes = supersededIds(b.text);
|
|
187
|
+
if (supersedes.size === 0)
|
|
188
|
+
continue;
|
|
189
|
+
for (const a of blocks) {
|
|
190
|
+
if (a.entryHash === b.entryHash)
|
|
191
|
+
continue; // never supersede self
|
|
192
|
+
if (supersededIds(a.text).size > 0)
|
|
193
|
+
continue; // the newer superseding entry stays live
|
|
194
|
+
const aIds = referencedIds(a.text);
|
|
195
|
+
for (const n of supersedes) {
|
|
196
|
+
if (aIds.has(n)) {
|
|
197
|
+
out.set(a.entryHash, b.entryHash);
|
|
198
|
+
break;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
return Array.from(out, ([targetHash, bySpec]) => ({ targetHash, bySpec }));
|
|
204
|
+
}
|
|
205
|
+
//# sourceMappingURL=lifecycle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lifecycle.js","sourceRoot":"","sources":["../../../src/agent/knowledge/lifecycle.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Classify the trust/origin of an indexed file by its workspace-relative path.
|
|
3
|
+
*
|
|
4
|
+
* Mirrors openclaw memory-core `resolveMemoryPathClassification`, adapted to our
|
|
5
|
+
* layout. FAIL-CLOSED: anything not explicitly recognized as agent-authored or
|
|
6
|
+
* system-generated is `untrusted` — so later phases (promotion, shared KB) can
|
|
7
|
+
* never auto-promote content whose provenance we could not vouch for.
|
|
8
|
+
*
|
|
9
|
+
* - `DREAMS.md`, `memory/dreaming/*`, `.dreaming/*` → system (machine-generated)
|
|
10
|
+
* - `MEMORY.md`, `USER.md`, `memory/*.md` → agent (self-authored)
|
|
11
|
+
* - everything else (imports, unknown) → untrusted
|
|
12
|
+
*/
|
|
13
|
+
import type { OriginClass } from './types';
|
|
14
|
+
export declare function classifyOrigin(relPath: string): OriginClass;
|
|
15
|
+
//# sourceMappingURL=provenance.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provenance.d.ts","sourceRoot":"","sources":["../../../src/agent/knowledge/provenance.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAO3C,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,CAmB3D"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Classify the trust/origin of an indexed file by its workspace-relative path.
|
|
4
|
+
*
|
|
5
|
+
* Mirrors openclaw memory-core `resolveMemoryPathClassification`, adapted to our
|
|
6
|
+
* layout. FAIL-CLOSED: anything not explicitly recognized as agent-authored or
|
|
7
|
+
* system-generated is `untrusted` — so later phases (promotion, shared KB) can
|
|
8
|
+
* never auto-promote content whose provenance we could not vouch for.
|
|
9
|
+
*
|
|
10
|
+
* - `DREAMS.md`, `memory/dreaming/*`, `.dreaming/*` → system (machine-generated)
|
|
11
|
+
* - `MEMORY.md`, `USER.md`, `memory/*.md` → agent (self-authored)
|
|
12
|
+
* - everything else (imports, unknown) → untrusted
|
|
13
|
+
*/
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.classifyOrigin = classifyOrigin;
|
|
16
|
+
/** Normalize a path to forward-slash, no leading "./". */
|
|
17
|
+
function toPosix(relPath) {
|
|
18
|
+
return relPath.replace(/\\/g, '/').replace(/^\.\//, '');
|
|
19
|
+
}
|
|
20
|
+
function classifyOrigin(relPath) {
|
|
21
|
+
const p = toPosix(relPath).toLowerCase();
|
|
22
|
+
// System: dreaming outputs and the dream diary are machine-generated.
|
|
23
|
+
if (p === 'dreams.md' ||
|
|
24
|
+
p.startsWith('memory/dreaming/') ||
|
|
25
|
+
p.startsWith('.dreaming/') ||
|
|
26
|
+
p.startsWith('memory/.dreams/')) {
|
|
27
|
+
return 'system';
|
|
28
|
+
}
|
|
29
|
+
// Agent: the self-authored memory core + atomic notes under memory/.
|
|
30
|
+
if (p === 'memory.md' || p === 'user.md')
|
|
31
|
+
return 'agent';
|
|
32
|
+
if (p.startsWith('memory/') && p.endsWith('.md'))
|
|
33
|
+
return 'agent';
|
|
34
|
+
// Fail-closed for anything else.
|
|
35
|
+
return 'untrusted';
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=provenance.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provenance.js","sourceRoot":"","sources":["../../../src/agent/knowledge/provenance.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;GAWG;;AASH,wCAmBC;AAxBD,0DAA0D;AAC1D,SAAS,OAAO,CAAC,OAAe;IAC9B,OAAO,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;AAC1D,CAAC;AAED,SAAgB,cAAc,CAAC,OAAe;IAC5C,MAAM,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,CAAC;IAEzC,sEAAsE;IACtE,IACE,CAAC,KAAK,WAAW;QACjB,CAAC,CAAC,UAAU,CAAC,kBAAkB,CAAC;QAChC,CAAC,CAAC,UAAU,CAAC,YAAY,CAAC;QAC1B,CAAC,CAAC,UAAU,CAAC,iBAAiB,CAAC,EAC/B,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,qEAAqE;IACrE,IAAI,CAAC,KAAK,WAAW,IAAI,CAAC,KAAK,SAAS;QAAE,OAAO,OAAO,CAAC;IACzD,IAAI,CAAC,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,OAAO,CAAC;IAEjE,iCAAiC;IACjC,OAAO,WAAW,CAAC;AACrB,CAAC"}
|