@cortexkit/pi-magic-context 0.47.0 → 0.48.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/dist/auto-search-worker.js +27 -22
- package/dist/embedding-activity-ew6dshfd.js +10 -0
- package/dist/embedding-backfill-bnnytehy.js +20 -0
- package/dist/embedding-cache-7rp4gqzr.js +16 -0
- package/dist/embedding-worker.js +11 -8
- package/dist/harness-9872e0ym.js +10 -0
- package/dist/historian-calibration-extension.js +3 -2
- package/dist/index-0am8a7k1.js +152 -0
- package/dist/index-0h2mkab2.js +17 -0
- package/dist/index-135e8hvg.js +43 -0
- package/dist/{index-0qejsd7f.js → index-3cgbv47m.js} +289 -45
- package/dist/index-419bndtm.js +2309 -0
- package/dist/index-544c0e0x.js +3026 -0
- package/dist/index-5hd7h4rr.js +3098 -0
- package/dist/index-5jp1h0bz.js +750 -0
- package/dist/index-603mt6nm.js +171 -0
- package/dist/index-674f6qs2.js +16 -0
- package/dist/{index-vgcemg0n.js → index-6pgq5ns2.js} +151 -2452
- package/dist/{index-xpbh1ypk.js → index-72bdc1bd.js} +38 -741
- package/dist/index-8976mezv.js +209 -0
- package/dist/{index-td885aah.js → index-8y5knskr.js} +98 -231
- package/dist/{index-k3ezsjng.js → index-98z1c1r0.js} +14574 -13942
- package/dist/index-9p40dgkm.js +22 -0
- package/dist/index-9x1f96r8.js +11 -0
- package/dist/{index-266qrgss.js → index-9xb0axhc.js} +301 -27
- package/dist/{index-spk5vrhy.js → index-bgmv2kaf.js} +1 -16
- package/dist/index-dkx0b1kt.js +514 -0
- package/dist/{index-7n8gb6j3.js → index-f956htf3.js} +28 -31
- package/dist/index-fapenpch.js +13 -0
- package/dist/index-fm3ksh5e.js +1060 -0
- package/dist/{index-2p1e8706.js → index-fp37he9a.js} +3 -3
- package/dist/index-hrf13mn3.js +2388 -0
- package/dist/index-pvm4pd5d.js +3069 -0
- package/dist/{index-kztsbkqq.js → index-r7xg4hvw.js} +171 -168
- package/dist/index-rt5jgzp1.js +1127 -0
- package/dist/{index-n3g5mwa8.js → index-wrm4nbj7.js} +3 -3
- package/dist/index-xjqheg7a.js +931 -0
- package/dist/index-yhzhdp3m.js +143 -0
- package/dist/{index-w76x3af7.js → index-zrr5t5a7.js} +1 -3
- package/dist/index.js +4203 -2183
- package/dist/logger-v3dsxdnm.js +19 -0
- package/dist/message-index-bounded-t7vvty76.js +120 -0
- package/dist/{message-time-backfill-d3db2etr.js → message-time-backfill-4ndf7hrq.js} +7 -6
- package/dist/migration-worker.js +20 -14
- package/dist/project-embedding-registry-jy2hmq28.js +85 -0
- package/dist/raw-ordinal-warmup-worker.js +60 -0
- package/dist/{read-session-chunk-atxsyfqv.js → read-session-chunk-47pjn7fz.js} +12 -6
- package/dist/read-session-raw-yn8nawav.js +55 -0
- package/dist/{safe-notification-target-6cn3z99t.js → safe-notification-target-3c1ns931.js} +3 -2
- package/dist/search-42szfhwp.js +40 -0
- package/dist/sqlite-3yye76ht.js +44 -0
- package/dist/sqlite-context-pragmas-gcgch6qz.js +6 -0
- package/dist/storage-memory-1z20y55x.js +71 -0
- package/dist/storage-tags-jym5z6yk.js +127 -0
- package/dist/subagent-entry.js +34 -17
- package/dist/transformers-node-wasm.js +18415 -18415
- package/package.json +3 -3
- package/dist/index-7s8vw2y0.js +0 -5207
- package/dist/index-qaa5j277.js +0 -8544
- /package/dist/{index-en1k8h8m.js → index-5prbx026.js} +0 -0
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
// ../plugin/src/shared/opencode-db-path.ts
|
|
2
|
+
import { existsSync, readdirSync, statSync } from "node:fs";
|
|
3
|
+
import { homedir } from "node:os";
|
|
4
|
+
import { isAbsolute, join, resolve } from "node:path";
|
|
5
|
+
var cachedResolution = null;
|
|
6
|
+
var lastReadFailure = null;
|
|
7
|
+
var claimedDiagnostics = new Set;
|
|
8
|
+
function openCodeDataDir(env = process.env, dataHome) {
|
|
9
|
+
return join(dataHome ?? env.XDG_DATA_HOME ?? join(homedir(), ".local", "share"), "opencode");
|
|
10
|
+
}
|
|
11
|
+
function environmentKey(dataDir, hostGeneration, channel, env) {
|
|
12
|
+
return [
|
|
13
|
+
hostGeneration,
|
|
14
|
+
dataDir,
|
|
15
|
+
env.OPENCODE_DB ?? "",
|
|
16
|
+
env.OPENCODE_DISABLE_CHANNEL_DB ?? "",
|
|
17
|
+
channel ?? env.OPENCODE_CHANNEL ?? ""
|
|
18
|
+
].join("\x00");
|
|
19
|
+
}
|
|
20
|
+
function channelPath(dataDir, channel) {
|
|
21
|
+
return ["latest", "beta", "prod"].includes(channel) ? join(dataDir, "opencode.db") : join(dataDir, `opencode-${channel}.db`);
|
|
22
|
+
}
|
|
23
|
+
function discoveredCandidateNames(dataDir) {
|
|
24
|
+
const names = ["opencode.db", "opencode-local.db", "opencode-dev.db"];
|
|
25
|
+
try {
|
|
26
|
+
const discovered = readdirSync(dataDir, { withFileTypes: true }).filter((entry) => /^opencode-.+\.db$/.test(entry.name) && !names.includes(entry.name)).map((entry) => entry.name).sort();
|
|
27
|
+
names.push(...discovered);
|
|
28
|
+
} catch {}
|
|
29
|
+
return names;
|
|
30
|
+
}
|
|
31
|
+
function discoverOpenCodeDb(dataDir) {
|
|
32
|
+
const candidates = discoveredCandidateNames(dataDir).map((name, order) => {
|
|
33
|
+
const path = join(dataDir, name);
|
|
34
|
+
try {
|
|
35
|
+
const metadata = statSync(path);
|
|
36
|
+
return metadata.isFile() ? { path, order, mtimeMs: metadata.mtimeMs } : null;
|
|
37
|
+
} catch {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
const existing = candidates.filter((candidate) => candidate !== null).sort((left, right) => right.mtimeMs - left.mtimeMs || left.order - right.order)[0];
|
|
42
|
+
if (!existing) {
|
|
43
|
+
return { path: join(dataDir, "opencode.db"), source: "default", channel: null };
|
|
44
|
+
}
|
|
45
|
+
const name = existing.path.slice(dataDir.length + 1);
|
|
46
|
+
const channel = name === "opencode.db" ? null : name.slice("opencode-".length, -".db".length) || null;
|
|
47
|
+
return { path: existing.path, source: "discovered", channel };
|
|
48
|
+
}
|
|
49
|
+
function resolveV1Fresh(dataDir, env = process.env) {
|
|
50
|
+
const explicit = env.OPENCODE_DB;
|
|
51
|
+
if (explicit !== undefined && explicit.length > 0) {
|
|
52
|
+
if (explicit === ":memory:") {
|
|
53
|
+
return { path: explicit, source: "OPENCODE_DB", channel: null };
|
|
54
|
+
}
|
|
55
|
+
return {
|
|
56
|
+
path: isAbsolute(explicit) ? explicit : join(dataDir, explicit),
|
|
57
|
+
source: "OPENCODE_DB",
|
|
58
|
+
channel: null
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
const disableChannelDb = env.OPENCODE_DISABLE_CHANNEL_DB;
|
|
62
|
+
if (disableChannelDb === "1" || disableChannelDb === "true") {
|
|
63
|
+
return { path: join(dataDir, "opencode.db"), source: "default", channel: null };
|
|
64
|
+
}
|
|
65
|
+
const channel = env.OPENCODE_CHANNEL;
|
|
66
|
+
if (channel !== undefined && channel.length > 0) {
|
|
67
|
+
return { path: channelPath(dataDir, channel), source: "channel", channel };
|
|
68
|
+
}
|
|
69
|
+
return discoverOpenCodeDb(dataDir);
|
|
70
|
+
}
|
|
71
|
+
function sourceOpenCodeDatabaseFilename(hostGeneration, channel, env = process.env) {
|
|
72
|
+
if (hostGeneration === "v1") {
|
|
73
|
+
const explicit = env.OPENCODE_DB;
|
|
74
|
+
if (explicit !== undefined && explicit.length > 0)
|
|
75
|
+
return explicit;
|
|
76
|
+
if (env.OPENCODE_DISABLE_CHANNEL_DB === "1" || env.OPENCODE_DISABLE_CHANNEL_DB === "true") {
|
|
77
|
+
return "opencode.db";
|
|
78
|
+
}
|
|
79
|
+
return ["latest", "beta", "prod"].includes(channel) ? "opencode.db" : `opencode-${channel}.db`;
|
|
80
|
+
}
|
|
81
|
+
return env.OPENCODE_DB ?? (["latest", "dev", "beta", "next", "prod"].includes(channel) || env.OPENCODE_DISABLE_CHANNEL_DB === "1" || env.OPENCODE_DISABLE_CHANNEL_DB === "true" ? "opencode.db" : `opencode-${channel.replace(/[^a-zA-Z0-9._-]/g, "")}.db`);
|
|
82
|
+
}
|
|
83
|
+
function resolveV2Fresh(dataDir, channel, env) {
|
|
84
|
+
const filename = sourceOpenCodeDatabaseFilename("v2", channel, env);
|
|
85
|
+
const explicit = env.OPENCODE_DB !== undefined;
|
|
86
|
+
return {
|
|
87
|
+
path: filename === ":memory:" ? filename : resolve(dataDir, filename),
|
|
88
|
+
source: explicit ? "OPENCODE_DB" : env.OPENCODE_CHANNEL ? "channel" : "default",
|
|
89
|
+
channel: explicit ? null : channel
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
function resolveOpenCodeDbPath(hostGeneration = "v1", options = {}) {
|
|
93
|
+
const env = options.env ?? process.env;
|
|
94
|
+
const dataDir = openCodeDataDir(env, options.dataHome);
|
|
95
|
+
const channel = options.channel ?? env.OPENCODE_CHANNEL;
|
|
96
|
+
const key = environmentKey(dataDir, hostGeneration, channel, env);
|
|
97
|
+
if (cachedResolution?.key === key && (!cachedResolution.existed || existsSync(cachedResolution.resolution.path))) {
|
|
98
|
+
if (cachedResolution.existed)
|
|
99
|
+
return cachedResolution.resolution;
|
|
100
|
+
}
|
|
101
|
+
const resolution = hostGeneration === "v2" ? resolveV2Fresh(dataDir, channel ?? "latest", env) : resolveV1Fresh(dataDir, env);
|
|
102
|
+
cachedResolution = {
|
|
103
|
+
key,
|
|
104
|
+
resolution,
|
|
105
|
+
existed: resolution.path !== ":memory:" && existsSync(resolution.path)
|
|
106
|
+
};
|
|
107
|
+
return resolution;
|
|
108
|
+
}
|
|
109
|
+
function schemaTableNames(db, schema = "main") {
|
|
110
|
+
const rows = db.prepare(`SELECT name FROM ${schema}.sqlite_master WHERE type = 'table' AND name IN ('message', 'part', 'session', 'project', 'session_message', 'session_v2')`).all();
|
|
111
|
+
return new Set(rows.flatMap((row) => typeof row.name === "string" ? [row.name] : []));
|
|
112
|
+
}
|
|
113
|
+
function hasV1MessageTables(db, schema = "main") {
|
|
114
|
+
const tables = schemaTableNames(db, schema);
|
|
115
|
+
return tables.has("message") && tables.has("part");
|
|
116
|
+
}
|
|
117
|
+
function detectOpenCodeStoreGeneration(db, schema = "main") {
|
|
118
|
+
const tables = schemaTableNames(db, schema);
|
|
119
|
+
const hasV1Messages = tables.has("message") && tables.has("part");
|
|
120
|
+
if (hasV1Messages)
|
|
121
|
+
return "v1";
|
|
122
|
+
if (tables.has("session_message"))
|
|
123
|
+
return "v2";
|
|
124
|
+
if (tables.has("session") || tables.has("project"))
|
|
125
|
+
return "v1";
|
|
126
|
+
return "unknown";
|
|
127
|
+
}
|
|
128
|
+
function hasMigratedV2Schema(tables) {
|
|
129
|
+
return tables.has("session_message") && tables.has("session_v2");
|
|
130
|
+
}
|
|
131
|
+
function isOpenCodeV2Store(db, schema = "main") {
|
|
132
|
+
return detectOpenCodeStoreGeneration(db, schema) === "v2" || hasMigratedV2Schema(schemaTableNames(db, schema));
|
|
133
|
+
}
|
|
134
|
+
function assertOpenCodeStoreGeneration(db, expected, path, schema = "main") {
|
|
135
|
+
const actual = detectOpenCodeStoreGeneration(db, schema);
|
|
136
|
+
if (actual === expected)
|
|
137
|
+
return;
|
|
138
|
+
if (expected === "v2" && isOpenCodeV2Store(db, schema))
|
|
139
|
+
return;
|
|
140
|
+
if (actual === "unknown")
|
|
141
|
+
return;
|
|
142
|
+
throw new Error(`OpenCode store generation mismatch at ${path}: expected ${expected}, found ${actual}; refusing generation-specific database access`);
|
|
143
|
+
}
|
|
144
|
+
function openCodeDbPathExists(resolution = resolveOpenCodeDbPath()) {
|
|
145
|
+
return resolution.path !== ":memory:" && existsSync(resolution.path);
|
|
146
|
+
}
|
|
147
|
+
function getOpenCodeDbProbeDescriptions(resolution = resolveOpenCodeDbPath()) {
|
|
148
|
+
if (resolution.source === "OPENCODE_DB")
|
|
149
|
+
return [resolution.path];
|
|
150
|
+
if (resolution.source === "channel" || process.env.OPENCODE_DISABLE_CHANNEL_DB === "1" || process.env.OPENCODE_DISABLE_CHANNEL_DB === "true") {
|
|
151
|
+
return [resolution.path];
|
|
152
|
+
}
|
|
153
|
+
const dataDir = openCodeDataDir();
|
|
154
|
+
return [
|
|
155
|
+
join(dataDir, "opencode.db"),
|
|
156
|
+
join(dataDir, "opencode-local.db"),
|
|
157
|
+
join(dataDir, "opencode-dev.db"),
|
|
158
|
+
join(dataDir, "opencode-<channel>.db")
|
|
159
|
+
];
|
|
160
|
+
}
|
|
161
|
+
function recordOpenCodeDbReadFailure(resolution, error) {
|
|
162
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
163
|
+
lastReadFailure = { ...resolution, message };
|
|
164
|
+
return lastReadFailure;
|
|
165
|
+
}
|
|
166
|
+
function clearOpenCodeDbReadFailure(path) {
|
|
167
|
+
if (path === undefined || lastReadFailure?.path === path)
|
|
168
|
+
lastReadFailure = null;
|
|
169
|
+
}
|
|
170
|
+
function claimOpenCodeDbDiagnosticOnce(surface, resolution) {
|
|
171
|
+
const key = `${surface}\x00${resolution.path}\x00${resolution.source}`;
|
|
172
|
+
if (claimedDiagnostics.has(key))
|
|
173
|
+
return false;
|
|
174
|
+
claimedDiagnostics.add(key);
|
|
175
|
+
return true;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// ../plugin/src/features/magic-context/tool-definition-tokens.ts
|
|
179
|
+
var measurements = new Map;
|
|
180
|
+
var fingerprints = new Map;
|
|
181
|
+
var persistenceDb = null;
|
|
182
|
+
var cachedInsertStmt = null;
|
|
183
|
+
function keyFor(providerID, modelID, agentName) {
|
|
184
|
+
const agent = agentName && agentName.length > 0 ? agentName : "default";
|
|
185
|
+
return `${providerID}/${modelID}/${agent}`;
|
|
186
|
+
}
|
|
187
|
+
function setDatabase(db) {
|
|
188
|
+
persistenceDb = db;
|
|
189
|
+
cachedInsertStmt = null;
|
|
190
|
+
}
|
|
191
|
+
function loadToolDefinitionMeasurements(db) {
|
|
192
|
+
let rows = [];
|
|
193
|
+
try {
|
|
194
|
+
rows = db.prepare("SELECT provider_id, model_id, agent_name, tool_id, token_count FROM tool_definition_measurements").all();
|
|
195
|
+
} catch {
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
for (const row of rows) {
|
|
199
|
+
const key = keyFor(row.provider_id, row.model_id, row.agent_name);
|
|
200
|
+
let inner = measurements.get(key);
|
|
201
|
+
if (!inner) {
|
|
202
|
+
inner = new Map;
|
|
203
|
+
measurements.set(key, inner);
|
|
204
|
+
}
|
|
205
|
+
inner.set(row.tool_id, row.token_count);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
export { resolveOpenCodeDbPath, hasV1MessageTables, assertOpenCodeStoreGeneration, openCodeDbPathExists, getOpenCodeDbProbeDescriptions, recordOpenCodeDbReadFailure, clearOpenCodeDbReadFailure, claimOpenCodeDbDiagnosticOnce, setDatabase, loadToolDefinitionMeasurements };
|
|
@@ -1,6 +1,54 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
} from "./index-
|
|
2
|
+
sessionLog2
|
|
3
|
+
} from "./index-f956htf3.js";
|
|
4
|
+
|
|
5
|
+
// ../plugin/src/shared/stable-json.ts
|
|
6
|
+
function stableStringify(value, seen = new WeakSet) {
|
|
7
|
+
const pieces = [];
|
|
8
|
+
writeStable(value, seen, pieces);
|
|
9
|
+
return pieces.join("");
|
|
10
|
+
}
|
|
11
|
+
function writeStable(value, seen, pieces) {
|
|
12
|
+
if (value === undefined) {
|
|
13
|
+
pieces.push("undefined");
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
if (value === null || typeof value !== "object") {
|
|
17
|
+
pieces.push(JSON.stringify(value) ?? String(value));
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
if (seen.has(value)) {
|
|
21
|
+
pieces.push('"[Circular]"');
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
seen.add(value);
|
|
25
|
+
if (Array.isArray(value)) {
|
|
26
|
+
pieces.push("[");
|
|
27
|
+
for (let index = 0;index < value.length; index += 1) {
|
|
28
|
+
if (index > 0)
|
|
29
|
+
pieces.push(",");
|
|
30
|
+
if (index in value)
|
|
31
|
+
writeStable(value[index], seen, pieces);
|
|
32
|
+
}
|
|
33
|
+
pieces.push("]");
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
const entries = Object.entries(value).sort(([a], [b]) => {
|
|
37
|
+
if (a < b)
|
|
38
|
+
return -1;
|
|
39
|
+
if (a > b)
|
|
40
|
+
return 1;
|
|
41
|
+
return 0;
|
|
42
|
+
});
|
|
43
|
+
pieces.push("{");
|
|
44
|
+
entries.forEach(([key, child], index) => {
|
|
45
|
+
if (index > 0)
|
|
46
|
+
pieces.push(",");
|
|
47
|
+
pieces.push(JSON.stringify(key), ":");
|
|
48
|
+
writeStable(child, seen, pieces);
|
|
49
|
+
});
|
|
50
|
+
pieces.push("}");
|
|
51
|
+
}
|
|
4
52
|
|
|
5
53
|
// ../plugin/src/shared/sqlite-helpers.ts
|
|
6
54
|
function closeQuietly(db) {
|
|
@@ -19,28 +67,6 @@ function isKnownAutocommit(db) {
|
|
|
19
67
|
}
|
|
20
68
|
}
|
|
21
69
|
|
|
22
|
-
// ../plugin/src/shared/stable-json.ts
|
|
23
|
-
function stableStringify(value, seen = new WeakSet) {
|
|
24
|
-
if (value === undefined)
|
|
25
|
-
return "undefined";
|
|
26
|
-
if (value === null || typeof value !== "object")
|
|
27
|
-
return JSON.stringify(value) ?? String(value);
|
|
28
|
-
if (seen.has(value))
|
|
29
|
-
return '"[Circular]"';
|
|
30
|
-
seen.add(value);
|
|
31
|
-
if (Array.isArray(value)) {
|
|
32
|
-
return `[${value.map((item) => stableStringify(item, seen)).join(",")}]`;
|
|
33
|
-
}
|
|
34
|
-
const entries = Object.entries(value).sort(([a], [b]) => {
|
|
35
|
-
if (a < b)
|
|
36
|
-
return -1;
|
|
37
|
-
if (a > b)
|
|
38
|
-
return 1;
|
|
39
|
-
return 0;
|
|
40
|
-
});
|
|
41
|
-
return `{${entries.map(([key, child]) => `${JSON.stringify(key)}:${stableStringify(child, seen)}`).join(",")}}`;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
70
|
// ../plugin/src/features/magic-context/storage-schema-helpers.ts
|
|
45
71
|
var columnCaches = new WeakMap;
|
|
46
72
|
function readColumnNames(db, table) {
|
|
@@ -313,11 +339,11 @@ function installV95PerfSchema(db, verifyExistingMap = false, allowCreateMap = tr
|
|
|
313
339
|
try {
|
|
314
340
|
entries = JSON.parse(row.entries);
|
|
315
341
|
} catch {
|
|
316
|
-
|
|
342
|
+
sessionLog2(row.session_id, "v95 temporal metadata: malformed JSON skipped; original blob retained");
|
|
317
343
|
continue;
|
|
318
344
|
}
|
|
319
345
|
if (!Array.isArray(entries)) {
|
|
320
|
-
|
|
346
|
+
sessionLog2(row.session_id, "v95 temporal metadata: non-array JSON skipped; original blob retained");
|
|
321
347
|
continue;
|
|
322
348
|
}
|
|
323
349
|
const kept = [];
|
|
@@ -364,213 +390,54 @@ function installV95PerfSchema(db, verifyExistingMap = false, allowCreateMap = tr
|
|
|
364
390
|
}
|
|
365
391
|
}
|
|
366
392
|
var tagOrderIndexes = new WeakMap;
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
}
|
|
387
|
-
function channelPath(dataDir, channel) {
|
|
388
|
-
return ["latest", "beta", "prod"].includes(channel) ? join(dataDir, "opencode.db") : join(dataDir, `opencode-${channel}.db`);
|
|
389
|
-
}
|
|
390
|
-
function discoveredCandidateNames(dataDir) {
|
|
391
|
-
const names = ["opencode.db", "opencode-local.db", "opencode-dev.db"];
|
|
392
|
-
try {
|
|
393
|
-
const discovered = readdirSync(dataDir, { withFileTypes: true }).filter((entry) => /^opencode-.+\.db$/.test(entry.name) && !names.includes(entry.name)).map((entry) => entry.name).sort();
|
|
394
|
-
names.push(...discovered);
|
|
395
|
-
} catch {}
|
|
396
|
-
return names;
|
|
397
|
-
}
|
|
398
|
-
function discoverOpenCodeDb(dataDir) {
|
|
399
|
-
const candidates = discoveredCandidateNames(dataDir).map((name, order) => {
|
|
400
|
-
const path = join(dataDir, name);
|
|
401
|
-
try {
|
|
402
|
-
const metadata = statSync(path);
|
|
403
|
-
return metadata.isFile() ? { path, order, mtimeMs: metadata.mtimeMs } : null;
|
|
404
|
-
} catch {
|
|
405
|
-
return null;
|
|
406
|
-
}
|
|
407
|
-
});
|
|
408
|
-
const existing = candidates.filter((candidate) => candidate !== null).sort((left, right) => right.mtimeMs - left.mtimeMs || left.order - right.order)[0];
|
|
409
|
-
if (!existing) {
|
|
410
|
-
return { path: join(dataDir, "opencode.db"), source: "default", channel: null };
|
|
411
|
-
}
|
|
412
|
-
const name = existing.path.slice(dataDir.length + 1);
|
|
413
|
-
const channel = name === "opencode.db" ? null : name.slice("opencode-".length, -".db".length) || null;
|
|
414
|
-
return { path: existing.path, source: "discovered", channel };
|
|
415
|
-
}
|
|
416
|
-
function resolveV1Fresh(dataDir, env = process.env) {
|
|
417
|
-
const explicit = env.OPENCODE_DB;
|
|
418
|
-
if (explicit !== undefined && explicit.length > 0) {
|
|
419
|
-
if (explicit === ":memory:") {
|
|
420
|
-
return { path: explicit, source: "OPENCODE_DB", channel: null };
|
|
421
|
-
}
|
|
422
|
-
return {
|
|
423
|
-
path: isAbsolute(explicit) ? explicit : join(dataDir, explicit),
|
|
424
|
-
source: "OPENCODE_DB",
|
|
425
|
-
channel: null
|
|
426
|
-
};
|
|
427
|
-
}
|
|
428
|
-
const disableChannelDb = env.OPENCODE_DISABLE_CHANNEL_DB;
|
|
429
|
-
if (disableChannelDb === "1" || disableChannelDb === "true") {
|
|
430
|
-
return { path: join(dataDir, "opencode.db"), source: "default", channel: null };
|
|
431
|
-
}
|
|
432
|
-
const channel = env.OPENCODE_CHANNEL;
|
|
433
|
-
if (channel !== undefined && channel.length > 0) {
|
|
434
|
-
return { path: channelPath(dataDir, channel), source: "channel", channel };
|
|
435
|
-
}
|
|
436
|
-
return discoverOpenCodeDb(dataDir);
|
|
437
|
-
}
|
|
438
|
-
function sourceOpenCodeDatabaseFilename(hostGeneration, channel, env = process.env) {
|
|
439
|
-
if (hostGeneration === "v1") {
|
|
440
|
-
const explicit = env.OPENCODE_DB;
|
|
441
|
-
if (explicit !== undefined && explicit.length > 0)
|
|
442
|
-
return explicit;
|
|
443
|
-
if (env.OPENCODE_DISABLE_CHANNEL_DB === "1" || env.OPENCODE_DISABLE_CHANNEL_DB === "true") {
|
|
444
|
-
return "opencode.db";
|
|
445
|
-
}
|
|
446
|
-
return ["latest", "beta", "prod"].includes(channel) ? "opencode.db" : `opencode-${channel}.db`;
|
|
447
|
-
}
|
|
448
|
-
return env.OPENCODE_DB ?? (["latest", "dev", "beta", "next", "prod"].includes(channel) || env.OPENCODE_DISABLE_CHANNEL_DB === "1" || env.OPENCODE_DISABLE_CHANNEL_DB === "true" ? "opencode.db" : `opencode-${channel.replace(/[^a-zA-Z0-9._-]/g, "")}.db`);
|
|
449
|
-
}
|
|
450
|
-
function resolveV2Fresh(dataDir, channel, env) {
|
|
451
|
-
const filename = sourceOpenCodeDatabaseFilename("v2", channel, env);
|
|
452
|
-
const explicit = env.OPENCODE_DB !== undefined;
|
|
453
|
-
return {
|
|
454
|
-
path: filename === ":memory:" ? filename : resolve(dataDir, filename),
|
|
455
|
-
source: explicit ? "OPENCODE_DB" : env.OPENCODE_CHANNEL ? "channel" : "default",
|
|
456
|
-
channel: explicit ? null : channel
|
|
457
|
-
};
|
|
458
|
-
}
|
|
459
|
-
function resolveOpenCodeDbPath(hostGeneration = "v1", options = {}) {
|
|
460
|
-
const env = options.env ?? process.env;
|
|
461
|
-
const dataDir = openCodeDataDir(env, options.dataHome);
|
|
462
|
-
const channel = options.channel ?? env.OPENCODE_CHANNEL;
|
|
463
|
-
const key = environmentKey(dataDir, hostGeneration, channel, env);
|
|
464
|
-
if (cachedResolution?.key === key && (!cachedResolution.existed || existsSync(cachedResolution.resolution.path))) {
|
|
465
|
-
if (cachedResolution.existed)
|
|
466
|
-
return cachedResolution.resolution;
|
|
467
|
-
}
|
|
468
|
-
const resolution = hostGeneration === "v2" ? resolveV2Fresh(dataDir, channel ?? "latest", env) : resolveV1Fresh(dataDir, env);
|
|
469
|
-
cachedResolution = {
|
|
470
|
-
key,
|
|
471
|
-
resolution,
|
|
472
|
-
existed: resolution.path !== ":memory:" && existsSync(resolution.path)
|
|
473
|
-
};
|
|
474
|
-
return resolution;
|
|
475
|
-
}
|
|
476
|
-
function schemaTableNames(db, schema = "main") {
|
|
477
|
-
const rows = db.prepare(`SELECT name FROM ${schema}.sqlite_master WHERE type = 'table' AND name IN ('message', 'part', 'session', 'project', 'session_message', 'session_v2')`).all();
|
|
478
|
-
return new Set(rows.flatMap((row) => typeof row.name === "string" ? [row.name] : []));
|
|
479
|
-
}
|
|
480
|
-
function hasV1MessageTables(db, schema = "main") {
|
|
481
|
-
const tables = schemaTableNames(db, schema);
|
|
482
|
-
return tables.has("message") && tables.has("part");
|
|
483
|
-
}
|
|
484
|
-
function detectOpenCodeStoreGeneration(db, schema = "main") {
|
|
485
|
-
const tables = schemaTableNames(db, schema);
|
|
486
|
-
const hasV1Messages = tables.has("message") && tables.has("part");
|
|
487
|
-
if (hasV1Messages)
|
|
488
|
-
return "v1";
|
|
489
|
-
if (tables.has("session_message"))
|
|
490
|
-
return "v2";
|
|
491
|
-
if (tables.has("session") || tables.has("project"))
|
|
492
|
-
return "v1";
|
|
493
|
-
return "unknown";
|
|
494
|
-
}
|
|
495
|
-
function hasMigratedV2Schema(tables) {
|
|
496
|
-
return tables.has("session_message") && tables.has("session_v2");
|
|
497
|
-
}
|
|
498
|
-
function isOpenCodeV2Store(db, schema = "main") {
|
|
499
|
-
return detectOpenCodeStoreGeneration(db, schema) === "v2" || hasMigratedV2Schema(schemaTableNames(db, schema));
|
|
500
|
-
}
|
|
501
|
-
function assertOpenCodeStoreGeneration(db, expected, path, schema = "main") {
|
|
502
|
-
const actual = detectOpenCodeStoreGeneration(db, schema);
|
|
503
|
-
if (actual === expected)
|
|
504
|
-
return;
|
|
505
|
-
if (expected === "v2" && isOpenCodeV2Store(db, schema))
|
|
506
|
-
return;
|
|
507
|
-
if (actual === "unknown")
|
|
508
|
-
return;
|
|
509
|
-
throw new Error(`OpenCode store generation mismatch at ${path}: expected ${expected}, found ${actual}; refusing generation-specific database access`);
|
|
510
|
-
}
|
|
511
|
-
function openCodeDbPathExists(resolution = resolveOpenCodeDbPath()) {
|
|
512
|
-
return resolution.path !== ":memory:" && existsSync(resolution.path);
|
|
513
|
-
}
|
|
514
|
-
function getOpenCodeDbProbeDescriptions(resolution = resolveOpenCodeDbPath()) {
|
|
515
|
-
if (resolution.source === "OPENCODE_DB")
|
|
516
|
-
return [resolution.path];
|
|
517
|
-
if (resolution.source === "channel" || process.env.OPENCODE_DISABLE_CHANNEL_DB === "1" || process.env.OPENCODE_DISABLE_CHANNEL_DB === "true") {
|
|
518
|
-
return [resolution.path];
|
|
393
|
+
function tagOrderConstraintIndex(db) {
|
|
394
|
+
const version = db.prepare("PRAGMA schema_version").get().schema_version;
|
|
395
|
+
const cacheable = isKnownAutocommit(db);
|
|
396
|
+
if (!cacheable)
|
|
397
|
+
tagOrderIndexes.delete(db);
|
|
398
|
+
const cached = tagOrderIndexes.get(db);
|
|
399
|
+
if (cached?.schemaVersion === version)
|
|
400
|
+
return cached.name;
|
|
401
|
+
const candidates = db.prepare("PRAGMA index_list(tags)").all();
|
|
402
|
+
for (const candidate of candidates) {
|
|
403
|
+
if (!candidate.unique || candidate.origin !== "u")
|
|
404
|
+
continue;
|
|
405
|
+
const quoted = `"${candidate.name.replaceAll('"', '""')}"`;
|
|
406
|
+
const columns = db.prepare(`PRAGMA index_info(${quoted})`).all();
|
|
407
|
+
if (columns.length !== 2 || columns[0]?.name !== "session_id" || columns[1]?.name !== "tag_number")
|
|
408
|
+
continue;
|
|
409
|
+
if (cacheable)
|
|
410
|
+
tagOrderIndexes.set(db, { schemaVersion: version, name: quoted });
|
|
411
|
+
return quoted;
|
|
519
412
|
}
|
|
520
|
-
|
|
521
|
-
return [
|
|
522
|
-
join(dataDir, "opencode.db"),
|
|
523
|
-
join(dataDir, "opencode-local.db"),
|
|
524
|
-
join(dataDir, "opencode-dev.db"),
|
|
525
|
-
join(dataDir, "opencode-<channel>.db")
|
|
526
|
-
];
|
|
527
|
-
}
|
|
528
|
-
function recordOpenCodeDbReadFailure(resolution, error) {
|
|
529
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
530
|
-
lastReadFailure = { ...resolution, message };
|
|
531
|
-
return lastReadFailure;
|
|
532
|
-
}
|
|
533
|
-
function clearOpenCodeDbReadFailure(path) {
|
|
534
|
-
if (path === undefined || lastReadFailure?.path === path)
|
|
535
|
-
lastReadFailure = null;
|
|
536
|
-
}
|
|
537
|
-
function claimOpenCodeDbDiagnosticOnce(surface, resolution) {
|
|
538
|
-
const key = `${surface}\x00${resolution.path}\x00${resolution.source}`;
|
|
539
|
-
if (claimedDiagnostics.has(key))
|
|
540
|
-
return false;
|
|
541
|
-
claimedDiagnostics.add(key);
|
|
542
|
-
return true;
|
|
413
|
+
throw new Error("tags lacks its UNIQUE(session_id, tag_number) ordering constraint");
|
|
543
414
|
}
|
|
544
415
|
|
|
545
|
-
// ../plugin/src/features/magic-context/
|
|
546
|
-
var
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
}
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
measurements.set(key, inner);
|
|
571
|
-
}
|
|
572
|
-
inner.set(row.tool_id, row.token_count);
|
|
573
|
-
}
|
|
416
|
+
// ../plugin/src/features/magic-context/storage-tag-identity-revision.ts
|
|
417
|
+
var TAG_IDENTITY_REVISION_PREFIX = "tag_identity_revision:";
|
|
418
|
+
function tagIdentityRevisionKey(sessionId) {
|
|
419
|
+
return `${TAG_IDENTITY_REVISION_PREFIX}${sessionId}`;
|
|
420
|
+
}
|
|
421
|
+
var BUMP = (session) => `INSERT INTO schema_migrations_meta (key, value)
|
|
422
|
+
VALUES ('${TAG_IDENTITY_REVISION_PREFIX}' || ${session}, '1')
|
|
423
|
+
ON CONFLICT(key) DO UPDATE SET value = CAST(CAST(value AS INTEGER) + 1 AS TEXT)`;
|
|
424
|
+
var TRIGGER_SQL = `CREATE TEMP TRIGGER IF NOT EXISTS mc_tag_identity_revision_au
|
|
425
|
+
AFTER UPDATE OF id, session_id, message_id, tag_number, type, tool_owner_message_id, reasoning_token_count
|
|
426
|
+
ON main.tags
|
|
427
|
+
BEGIN
|
|
428
|
+
${BUMP("OLD.session_id")};
|
|
429
|
+
INSERT INTO schema_migrations_meta (key, value)
|
|
430
|
+
SELECT '${TAG_IDENTITY_REVISION_PREFIX}' || NEW.session_id, '1'
|
|
431
|
+
WHERE NEW.session_id IS NOT OLD.session_id
|
|
432
|
+
ON CONFLICT(key) DO UPDATE SET value = CAST(CAST(value AS INTEGER) + 1 AS TEXT);
|
|
433
|
+
END`;
|
|
434
|
+
function installTagIdentityRevisionTrigger(db) {
|
|
435
|
+
db.exec(TRIGGER_SQL);
|
|
436
|
+
}
|
|
437
|
+
function deleteTagIdentityRevisions(db, sessionIds) {
|
|
438
|
+
const statement = db.prepare("DELETE FROM schema_migrations_meta WHERE key = ? AND NOT EXISTS (SELECT 1 FROM tags WHERE session_id = ?)");
|
|
439
|
+
for (const sessionId of sessionIds)
|
|
440
|
+
statement.run(tagIdentityRevisionKey(sessionId), sessionId);
|
|
574
441
|
}
|
|
575
442
|
|
|
576
|
-
export { stableStringify, closeQuietly, isKnownAutocommit, getTableColumnNames, ensureColumn, healAllNullColumns, observeTemporalDecisions, freezeTemporalDecisions, installV95PerfSchema,
|
|
443
|
+
export { stableStringify, closeQuietly, isKnownAutocommit, getTableColumnNames, ensureColumn, healAllNullColumns, observeTemporalDecisions, freezeTemporalDecisions, installV95PerfSchema, tagOrderConstraintIndex, tagIdentityRevisionKey, installTagIdentityRevisionTrigger, deleteTagIdentityRevisions };
|