@cortexkit/pi-magic-context 0.22.3 → 0.22.5
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 +1 -3
- package/dist/index.js +985 -582
- package/dist/subagent-entry.js +636 -337
- package/package.json +1 -1
package/dist/subagent-entry.js
CHANGED
|
@@ -46,167 +46,6 @@ var __export = (target, all) => {
|
|
|
46
46
|
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
47
47
|
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
48
48
|
|
|
49
|
-
// ../plugin/src/shared/harness.ts
|
|
50
|
-
function setHarness(value) {
|
|
51
|
-
if (harnessLocked && currentHarness !== value) {
|
|
52
|
-
throw new Error(`Magic Context: harness already locked to "${currentHarness}"; cannot change to "${value}"`);
|
|
53
|
-
}
|
|
54
|
-
currentHarness = value;
|
|
55
|
-
harnessLocked = true;
|
|
56
|
-
}
|
|
57
|
-
function getHarness() {
|
|
58
|
-
return currentHarness;
|
|
59
|
-
}
|
|
60
|
-
var currentHarness = "opencode", harnessLocked = false;
|
|
61
|
-
|
|
62
|
-
// ../plugin/src/shared/data-path.ts
|
|
63
|
-
import * as os from "node:os";
|
|
64
|
-
import * as path from "node:path";
|
|
65
|
-
function getDataDir() {
|
|
66
|
-
return process.env.XDG_DATA_HOME ?? path.join(os.homedir(), ".local", "share");
|
|
67
|
-
}
|
|
68
|
-
function getMagicContextTempDir(harness = getHarness()) {
|
|
69
|
-
return path.join(os.tmpdir(), harness, "magic-context");
|
|
70
|
-
}
|
|
71
|
-
function getMagicContextLogPath(harness = getHarness()) {
|
|
72
|
-
return path.join(getMagicContextTempDir(harness), "magic-context.log");
|
|
73
|
-
}
|
|
74
|
-
function getProjectMagicContextDir(directory) {
|
|
75
|
-
return path.join(directory, ".opencode", "magic-context");
|
|
76
|
-
}
|
|
77
|
-
function getProjectMagicContextHistorianDir(directory) {
|
|
78
|
-
return path.join(getProjectMagicContextDir(directory), "historian");
|
|
79
|
-
}
|
|
80
|
-
function getOpenCodeStorageDir() {
|
|
81
|
-
return path.join(getDataDir(), "opencode", "storage");
|
|
82
|
-
}
|
|
83
|
-
function getMagicContextStorageDir() {
|
|
84
|
-
return path.join(getDataDir(), "cortexkit", "magic-context");
|
|
85
|
-
}
|
|
86
|
-
function getLegacyOpenCodeMagicContextStorageDir() {
|
|
87
|
-
return path.join(getOpenCodeStorageDir(), "plugin", "magic-context");
|
|
88
|
-
}
|
|
89
|
-
var init_data_path = () => {};
|
|
90
|
-
|
|
91
|
-
// ../plugin/src/shared/logger.ts
|
|
92
|
-
import * as fs from "node:fs";
|
|
93
|
-
import * as path2 from "node:path";
|
|
94
|
-
function ensureDir(filePath) {
|
|
95
|
-
const dir = path2.dirname(filePath);
|
|
96
|
-
if (dir === lastEnsuredDir)
|
|
97
|
-
return;
|
|
98
|
-
try {
|
|
99
|
-
fs.mkdirSync(dir, { recursive: true });
|
|
100
|
-
lastEnsuredDir = dir;
|
|
101
|
-
} catch {}
|
|
102
|
-
}
|
|
103
|
-
function flush() {
|
|
104
|
-
if (flushTimer) {
|
|
105
|
-
clearTimeout(flushTimer);
|
|
106
|
-
flushTimer = null;
|
|
107
|
-
}
|
|
108
|
-
if (buffer.length === 0)
|
|
109
|
-
return;
|
|
110
|
-
const data = buffer.join("");
|
|
111
|
-
buffer = [];
|
|
112
|
-
try {
|
|
113
|
-
const logFile = getMagicContextLogPath();
|
|
114
|
-
ensureDir(logFile);
|
|
115
|
-
fs.appendFileSync(logFile, data);
|
|
116
|
-
} catch {}
|
|
117
|
-
}
|
|
118
|
-
function scheduleFlush() {
|
|
119
|
-
if (flushTimer)
|
|
120
|
-
return;
|
|
121
|
-
flushTimer = setTimeout(() => {
|
|
122
|
-
flushTimer = null;
|
|
123
|
-
flush();
|
|
124
|
-
}, FLUSH_INTERVAL_MS);
|
|
125
|
-
}
|
|
126
|
-
function log(message, data) {
|
|
127
|
-
if (isTestEnv)
|
|
128
|
-
return;
|
|
129
|
-
try {
|
|
130
|
-
const timestamp = new Date().toISOString();
|
|
131
|
-
const serialized = data === undefined ? "" : data instanceof Error ? ` ${data.message}${data.stack ? `
|
|
132
|
-
${data.stack}` : ""}` : ` ${JSON.stringify(data)}`;
|
|
133
|
-
buffer.push(`[${timestamp}] ${message}${serialized}
|
|
134
|
-
`);
|
|
135
|
-
if (buffer.length >= BUFFER_SIZE_LIMIT) {
|
|
136
|
-
flush();
|
|
137
|
-
} else {
|
|
138
|
-
scheduleFlush();
|
|
139
|
-
}
|
|
140
|
-
} catch {}
|
|
141
|
-
}
|
|
142
|
-
function sessionLog(sessionId, message, data) {
|
|
143
|
-
log(`[magic-context][${sessionId}] ${message}`, data);
|
|
144
|
-
}
|
|
145
|
-
var isTestEnv = false, buffer, flushTimer = null, FLUSH_INTERVAL_MS = 500, BUFFER_SIZE_LIMIT = 50, lastEnsuredDir = null;
|
|
146
|
-
var init_logger = __esm(() => {
|
|
147
|
-
init_data_path();
|
|
148
|
-
buffer = [];
|
|
149
|
-
if (!isTestEnv) {
|
|
150
|
-
process.on("exit", flush);
|
|
151
|
-
}
|
|
152
|
-
});
|
|
153
|
-
|
|
154
|
-
// ../plugin/src/shared/sqlite.ts
|
|
155
|
-
function buildNodeSqliteDatabaseClass(DatabaseSync) {
|
|
156
|
-
const SAVEPOINT = "mc_tx_sp";
|
|
157
|
-
|
|
158
|
-
class NodeSqliteDatabase extends DatabaseSync {
|
|
159
|
-
constructor(filename, options) {
|
|
160
|
-
const translated = { ...options };
|
|
161
|
-
if (options && "readonly" in options) {
|
|
162
|
-
translated.readOnly = options.readonly;
|
|
163
|
-
delete translated.readonly;
|
|
164
|
-
}
|
|
165
|
-
super(typeof filename === "string" ? filename : ":memory:", translated);
|
|
166
|
-
}
|
|
167
|
-
transaction(fn) {
|
|
168
|
-
const self = this;
|
|
169
|
-
const wrapped = function(...args) {
|
|
170
|
-
const nested = self.isTransaction === true;
|
|
171
|
-
self.exec(nested ? `SAVEPOINT ${SAVEPOINT}` : "BEGIN");
|
|
172
|
-
try {
|
|
173
|
-
const result = fn.apply(this, args);
|
|
174
|
-
self.exec(nested ? `RELEASE ${SAVEPOINT}` : "COMMIT");
|
|
175
|
-
return result;
|
|
176
|
-
} catch (error) {
|
|
177
|
-
if (nested) {
|
|
178
|
-
self.exec(`ROLLBACK TO ${SAVEPOINT}`);
|
|
179
|
-
self.exec(`RELEASE ${SAVEPOINT}`);
|
|
180
|
-
} else {
|
|
181
|
-
self.exec("ROLLBACK");
|
|
182
|
-
}
|
|
183
|
-
throw error;
|
|
184
|
-
}
|
|
185
|
-
};
|
|
186
|
-
return wrapped;
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
return NodeSqliteDatabase;
|
|
190
|
-
}
|
|
191
|
-
var isBun, bunSpec, nodeSpec, sqliteModule, DatabaseImpl, Database;
|
|
192
|
-
var init_sqlite = __esm(async () => {
|
|
193
|
-
isBun = typeof process !== "undefined" && typeof process.versions?.bun === "string";
|
|
194
|
-
bunSpec = "bun:" + "sqlite";
|
|
195
|
-
nodeSpec = "node:" + "sqlite";
|
|
196
|
-
sqliteModule = isBun ? await import(bunSpec) : await import(nodeSpec);
|
|
197
|
-
DatabaseImpl = isBun ? sqliteModule.Database : buildNodeSqliteDatabaseClass(sqliteModule.DatabaseSync);
|
|
198
|
-
Database = DatabaseImpl;
|
|
199
|
-
});
|
|
200
|
-
|
|
201
|
-
// ../plugin/src/shared/sqlite-helpers.ts
|
|
202
|
-
function closeQuietly(db) {
|
|
203
|
-
if (!db)
|
|
204
|
-
return;
|
|
205
|
-
try {
|
|
206
|
-
db.close();
|
|
207
|
-
} catch {}
|
|
208
|
-
}
|
|
209
|
-
|
|
210
49
|
// ../../node_modules/.bun/esprima@4.0.1/node_modules/esprima/dist/esprima.js
|
|
211
50
|
var require_esprima = __commonJS((exports, module) => {
|
|
212
51
|
(function webpackUniversalModuleDefinition(root, factory) {
|
|
@@ -7964,57 +7803,53 @@ var require_src2 = __commonJS((exports, module) => {
|
|
|
7964
7803
|
};
|
|
7965
7804
|
});
|
|
7966
7805
|
|
|
7967
|
-
// ../plugin/src/
|
|
7968
|
-
import { existsSync as
|
|
7969
|
-
import { join as
|
|
7970
|
-
|
|
7971
|
-
|
|
7806
|
+
// ../plugin/src/features/magic-context/storage-db.ts
|
|
7807
|
+
import { copyFileSync, cpSync, existsSync as existsSync3, mkdirSync as mkdirSync2 } from "node:fs";
|
|
7808
|
+
import { dirname as dirname2, join as join4 } from "node:path";
|
|
7809
|
+
|
|
7810
|
+
// ../plugin/src/shared/data-path.ts
|
|
7811
|
+
import * as os from "node:os";
|
|
7812
|
+
import * as path from "node:path";
|
|
7813
|
+
|
|
7814
|
+
// ../plugin/src/shared/harness.ts
|
|
7815
|
+
var currentHarness = "opencode";
|
|
7816
|
+
var harnessLocked = false;
|
|
7817
|
+
function setHarness(value) {
|
|
7818
|
+
if (harnessLocked && currentHarness !== value) {
|
|
7819
|
+
throw new Error(`Magic Context: harness already locked to "${currentHarness}"; cannot change to "${value}"`);
|
|
7820
|
+
}
|
|
7821
|
+
currentHarness = value;
|
|
7822
|
+
harnessLocked = true;
|
|
7972
7823
|
}
|
|
7973
|
-
function
|
|
7974
|
-
return
|
|
7824
|
+
function getHarness() {
|
|
7825
|
+
return currentHarness;
|
|
7975
7826
|
}
|
|
7976
|
-
|
|
7977
|
-
|
|
7978
|
-
|
|
7979
|
-
|
|
7980
|
-
try {
|
|
7981
|
-
closeQuietly(cachedReadOnlyDb.db);
|
|
7982
|
-
} catch (error51) {
|
|
7983
|
-
log("[magic-context] failed to close cached OpenCode read-only DB:", error51);
|
|
7984
|
-
} finally {
|
|
7985
|
-
cachedReadOnlyDb = null;
|
|
7986
|
-
}
|
|
7827
|
+
|
|
7828
|
+
// ../plugin/src/shared/data-path.ts
|
|
7829
|
+
function getDataDir() {
|
|
7830
|
+
return process.env.XDG_DATA_HOME ?? path.join(os.homedir(), ".local", "share");
|
|
7987
7831
|
}
|
|
7988
|
-
function
|
|
7989
|
-
|
|
7990
|
-
if (cachedReadOnlyDb?.path === dbPath) {
|
|
7991
|
-
return cachedReadOnlyDb.db;
|
|
7992
|
-
}
|
|
7993
|
-
closeCachedReadOnlyDb();
|
|
7994
|
-
const db = new Database(dbPath, { readonly: true });
|
|
7995
|
-
cachedReadOnlyDb = { path: dbPath, db };
|
|
7996
|
-
return db;
|
|
7832
|
+
function getMagicContextTempDir(harness = getHarness()) {
|
|
7833
|
+
return path.join(os.tmpdir(), harness, "magic-context");
|
|
7997
7834
|
}
|
|
7998
|
-
function
|
|
7999
|
-
return
|
|
7835
|
+
function getMagicContextLogPath(harness = getHarness()) {
|
|
7836
|
+
return path.join(getMagicContextTempDir(harness), "magic-context.log");
|
|
8000
7837
|
}
|
|
8001
|
-
function
|
|
8002
|
-
|
|
8003
|
-
|
|
8004
|
-
|
|
8005
|
-
return
|
|
7838
|
+
function getProjectMagicContextDir(directory) {
|
|
7839
|
+
return path.join(directory, ".opencode", "magic-context");
|
|
7840
|
+
}
|
|
7841
|
+
function getProjectMagicContextHistorianDir(directory) {
|
|
7842
|
+
return path.join(getProjectMagicContextDir(directory), "historian");
|
|
7843
|
+
}
|
|
7844
|
+
function getOpenCodeStorageDir() {
|
|
7845
|
+
return path.join(getDataDir(), "opencode", "storage");
|
|
7846
|
+
}
|
|
7847
|
+
function getMagicContextStorageDir() {
|
|
7848
|
+
return path.join(getDataDir(), "cortexkit", "magic-context");
|
|
7849
|
+
}
|
|
7850
|
+
function getLegacyOpenCodeMagicContextStorageDir() {
|
|
7851
|
+
return path.join(getOpenCodeStorageDir(), "plugin", "magic-context");
|
|
8006
7852
|
}
|
|
8007
|
-
var cachedReadOnlyDb = null;
|
|
8008
|
-
var init_read_session_db = __esm(async () => {
|
|
8009
|
-
init_data_path();
|
|
8010
|
-
init_logger();
|
|
8011
|
-
await init_sqlite();
|
|
8012
|
-
});
|
|
8013
|
-
|
|
8014
|
-
// ../plugin/src/features/magic-context/storage-db.ts
|
|
8015
|
-
init_data_path();
|
|
8016
|
-
import { copyFileSync, cpSync, existsSync as existsSync3, mkdirSync as mkdirSync2 } from "node:fs";
|
|
8017
|
-
import { dirname as dirname2, join as join4 } from "node:path";
|
|
8018
7853
|
|
|
8019
7854
|
// ../plugin/src/shared/error-message.ts
|
|
8020
7855
|
function getErrorMessage(error) {
|
|
@@ -8092,12 +7927,124 @@ function safeString(value) {
|
|
|
8092
7927
|
}
|
|
8093
7928
|
}
|
|
8094
7929
|
|
|
8095
|
-
// ../plugin/src/
|
|
8096
|
-
|
|
8097
|
-
|
|
7930
|
+
// ../plugin/src/shared/logger.ts
|
|
7931
|
+
import * as fs from "node:fs";
|
|
7932
|
+
import * as path2 from "node:path";
|
|
7933
|
+
var isTestEnv = false;
|
|
7934
|
+
var buffer = [];
|
|
7935
|
+
var flushTimer = null;
|
|
7936
|
+
var FLUSH_INTERVAL_MS = 500;
|
|
7937
|
+
var BUFFER_SIZE_LIMIT = 50;
|
|
7938
|
+
var lastEnsuredDir = null;
|
|
7939
|
+
function ensureDir(filePath) {
|
|
7940
|
+
const dir = path2.dirname(filePath);
|
|
7941
|
+
if (dir === lastEnsuredDir)
|
|
7942
|
+
return;
|
|
7943
|
+
try {
|
|
7944
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
7945
|
+
lastEnsuredDir = dir;
|
|
7946
|
+
} catch {}
|
|
7947
|
+
}
|
|
7948
|
+
function flush() {
|
|
7949
|
+
if (flushTimer) {
|
|
7950
|
+
clearTimeout(flushTimer);
|
|
7951
|
+
flushTimer = null;
|
|
7952
|
+
}
|
|
7953
|
+
if (buffer.length === 0)
|
|
7954
|
+
return;
|
|
7955
|
+
const data = buffer.join("");
|
|
7956
|
+
buffer = [];
|
|
7957
|
+
try {
|
|
7958
|
+
const logFile = getMagicContextLogPath();
|
|
7959
|
+
ensureDir(logFile);
|
|
7960
|
+
fs.appendFileSync(logFile, data);
|
|
7961
|
+
} catch {}
|
|
7962
|
+
}
|
|
7963
|
+
function scheduleFlush() {
|
|
7964
|
+
if (flushTimer)
|
|
7965
|
+
return;
|
|
7966
|
+
flushTimer = setTimeout(() => {
|
|
7967
|
+
flushTimer = null;
|
|
7968
|
+
flush();
|
|
7969
|
+
}, FLUSH_INTERVAL_MS);
|
|
7970
|
+
}
|
|
7971
|
+
function log(message, data) {
|
|
7972
|
+
if (isTestEnv)
|
|
7973
|
+
return;
|
|
7974
|
+
try {
|
|
7975
|
+
const timestamp = new Date().toISOString();
|
|
7976
|
+
const serialized = data === undefined ? "" : data instanceof Error ? ` ${data.message}${data.stack ? `
|
|
7977
|
+
${data.stack}` : ""}` : ` ${JSON.stringify(data)}`;
|
|
7978
|
+
buffer.push(`[${timestamp}] ${message}${serialized}
|
|
7979
|
+
`);
|
|
7980
|
+
if (buffer.length >= BUFFER_SIZE_LIMIT) {
|
|
7981
|
+
flush();
|
|
7982
|
+
} else {
|
|
7983
|
+
scheduleFlush();
|
|
7984
|
+
}
|
|
7985
|
+
} catch {}
|
|
7986
|
+
}
|
|
7987
|
+
function sessionLog(sessionId, message, data) {
|
|
7988
|
+
log(`[magic-context][${sessionId}] ${message}`, data);
|
|
7989
|
+
}
|
|
7990
|
+
if (!isTestEnv) {
|
|
7991
|
+
process.on("exit", flush);
|
|
7992
|
+
}
|
|
7993
|
+
|
|
7994
|
+
// ../plugin/src/shared/sqlite.ts
|
|
7995
|
+
var isBun = typeof process !== "undefined" && typeof process.versions?.bun === "string";
|
|
7996
|
+
var bunSpec = "bun:" + "sqlite";
|
|
7997
|
+
var nodeSpec = "node:" + "sqlite";
|
|
7998
|
+
var sqliteModule = isBun ? await import(bunSpec) : await import(nodeSpec);
|
|
7999
|
+
var DatabaseImpl = isBun ? sqliteModule.Database : buildNodeSqliteDatabaseClass(sqliteModule.DatabaseSync);
|
|
8000
|
+
function buildNodeSqliteDatabaseClass(DatabaseSync) {
|
|
8001
|
+
const SAVEPOINT = "mc_tx_sp";
|
|
8002
|
+
|
|
8003
|
+
class NodeSqliteDatabase extends DatabaseSync {
|
|
8004
|
+
constructor(filename, options) {
|
|
8005
|
+
const translated = { ...options };
|
|
8006
|
+
if (options && "readonly" in options) {
|
|
8007
|
+
translated.readOnly = options.readonly;
|
|
8008
|
+
delete translated.readonly;
|
|
8009
|
+
}
|
|
8010
|
+
super(typeof filename === "string" ? filename : ":memory:", translated);
|
|
8011
|
+
}
|
|
8012
|
+
transaction(fn) {
|
|
8013
|
+
const self = this;
|
|
8014
|
+
const wrapped = function(...args) {
|
|
8015
|
+
const nested = self.isTransaction === true;
|
|
8016
|
+
self.exec(nested ? `SAVEPOINT ${SAVEPOINT}` : "BEGIN");
|
|
8017
|
+
try {
|
|
8018
|
+
const result = fn.apply(this, args);
|
|
8019
|
+
self.exec(nested ? `RELEASE ${SAVEPOINT}` : "COMMIT");
|
|
8020
|
+
return result;
|
|
8021
|
+
} catch (error) {
|
|
8022
|
+
if (nested) {
|
|
8023
|
+
self.exec(`ROLLBACK TO ${SAVEPOINT}`);
|
|
8024
|
+
self.exec(`RELEASE ${SAVEPOINT}`);
|
|
8025
|
+
} else {
|
|
8026
|
+
self.exec("ROLLBACK");
|
|
8027
|
+
}
|
|
8028
|
+
throw error;
|
|
8029
|
+
}
|
|
8030
|
+
};
|
|
8031
|
+
return wrapped;
|
|
8032
|
+
}
|
|
8033
|
+
}
|
|
8034
|
+
return NodeSqliteDatabase;
|
|
8035
|
+
}
|
|
8036
|
+
var Database = DatabaseImpl;
|
|
8037
|
+
|
|
8038
|
+
// ../plugin/src/shared/sqlite-helpers.ts
|
|
8039
|
+
function closeQuietly(db) {
|
|
8040
|
+
if (!db)
|
|
8041
|
+
return;
|
|
8042
|
+
try {
|
|
8043
|
+
db.close();
|
|
8044
|
+
} catch {}
|
|
8045
|
+
}
|
|
8098
8046
|
|
|
8099
8047
|
// ../plugin/src/features/magic-context/key-files/project-key-files.ts
|
|
8100
|
-
init_logger();
|
|
8101
8048
|
import { createHash } from "node:crypto";
|
|
8102
8049
|
import { existsSync, readFileSync, realpathSync } from "node:fs";
|
|
8103
8050
|
import { join as join2, resolve, sep } from "node:path";
|
|
@@ -8214,7 +8161,6 @@ function isRelativeProjectFile(projectPath, relativePath) {
|
|
|
8214
8161
|
}
|
|
8215
8162
|
|
|
8216
8163
|
// ../plugin/src/features/magic-context/migrations.ts
|
|
8217
|
-
init_logger();
|
|
8218
8164
|
function tableExists(db, name) {
|
|
8219
8165
|
return Boolean(db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name = ?").get(name));
|
|
8220
8166
|
}
|
|
@@ -8948,6 +8894,28 @@ var MIGRATIONS = [
|
|
|
8948
8894
|
db.exec("ALTER TABLE notes ADD COLUMN anchor_ordinal INTEGER");
|
|
8949
8895
|
}
|
|
8950
8896
|
}
|
|
8897
|
+
},
|
|
8898
|
+
{
|
|
8899
|
+
version: 30,
|
|
8900
|
+
description: "HARD-bust m[0] markers: cached system/tool-set/model identity",
|
|
8901
|
+
up: (db) => {
|
|
8902
|
+
const hasSessionMeta = db.prepare("SELECT 1 FROM sqlite_master WHERE type='table' AND name='session_meta' LIMIT 1").get();
|
|
8903
|
+
if (!hasSessionMeta)
|
|
8904
|
+
return;
|
|
8905
|
+
ensureColumn(db, "session_meta", "cached_m0_system_hash", "TEXT");
|
|
8906
|
+
ensureColumn(db, "session_meta", "cached_m0_tool_set_hash", "TEXT");
|
|
8907
|
+
ensureColumn(db, "session_meta", "cached_m0_model_key", "TEXT");
|
|
8908
|
+
const columns = new Set(db.prepare("PRAGMA table_info(session_meta)").all().map((column) => column.name));
|
|
8909
|
+
if (columns.has("cached_m0_bytes")) {
|
|
8910
|
+
db.prepare(`UPDATE session_meta SET
|
|
8911
|
+
cached_m0_bytes = NULL,
|
|
8912
|
+
cached_m1_bytes = NULL,
|
|
8913
|
+
cached_m0_materialized_at = NULL,
|
|
8914
|
+
cached_m0_system_hash = NULL,
|
|
8915
|
+
cached_m0_tool_set_hash = NULL,
|
|
8916
|
+
cached_m0_model_key = NULL`).run();
|
|
8917
|
+
}
|
|
8918
|
+
}
|
|
8951
8919
|
}
|
|
8952
8920
|
];
|
|
8953
8921
|
var LATEST_MIGRATION_VERSION = MIGRATIONS.reduce((max, m) => Math.max(max, m.version), 0);
|
|
@@ -141663,8 +141631,6 @@ function loadToolDefinitionMeasurements(db) {
|
|
|
141663
141631
|
}
|
|
141664
141632
|
|
|
141665
141633
|
// ../plugin/src/features/magic-context/tool-owner-backfill.ts
|
|
141666
|
-
init_data_path();
|
|
141667
|
-
init_logger();
|
|
141668
141634
|
import { existsSync as existsSync2 } from "node:fs";
|
|
141669
141635
|
import { join as join3 } from "node:path";
|
|
141670
141636
|
var LEASE_DURATION_MS = 5 * 60 * 1000;
|
|
@@ -141912,7 +141878,7 @@ var databases = new Map;
|
|
|
141912
141878
|
var persistenceByDatabase = new WeakMap;
|
|
141913
141879
|
var persistenceErrorByDatabase = new WeakMap;
|
|
141914
141880
|
var lastSchemaFenceRejection = null;
|
|
141915
|
-
var LATEST_SUPPORTED_VERSION =
|
|
141881
|
+
var LATEST_SUPPORTED_VERSION = 30;
|
|
141916
141882
|
function resolveDatabasePath(dbPathOverride) {
|
|
141917
141883
|
if (dbPathOverride) {
|
|
141918
141884
|
return { dbDir: dirname2(dbPathOverride), dbPath: dbPathOverride };
|
|
@@ -142377,6 +142343,9 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
142377
142343
|
cached_m0_materialized_at INTEGER,
|
|
142378
142344
|
cached_m0_session_facts_version INTEGER,
|
|
142379
142345
|
cached_m0_upgrade_state TEXT,
|
|
142346
|
+
cached_m0_system_hash TEXT,
|
|
142347
|
+
cached_m0_tool_set_hash TEXT,
|
|
142348
|
+
cached_m0_model_key TEXT,
|
|
142380
142349
|
cached_m0_last_baseline_end_message_id TEXT,
|
|
142381
142350
|
upgrade_reminded_at INTEGER,
|
|
142382
142351
|
pi_stable_id_scheme INTEGER
|
|
@@ -142507,6 +142476,7 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
142507
142476
|
ensureColumn(db, "session_meta", "system_prompt_hash", "TEXT DEFAULT ''");
|
|
142508
142477
|
ensureColumn(db, "session_meta", "cleared_reasoning_through_tag", "INTEGER DEFAULT 0");
|
|
142509
142478
|
ensureColumn(db, "session_meta", "stripped_placeholder_ids", "TEXT DEFAULT ''");
|
|
142479
|
+
ensureColumn(db, "session_meta", "stale_reduce_stripped_ids", "TEXT DEFAULT ''");
|
|
142510
142480
|
ensureColumn(db, "compartments", "start_message_id", "TEXT DEFAULT ''");
|
|
142511
142481
|
ensureColumn(db, "compartments", "end_message_id", "TEXT DEFAULT ''");
|
|
142512
142482
|
ensureColumn(db, "memory_embeddings", "model_id", "TEXT");
|
|
@@ -142568,6 +142538,9 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
142568
142538
|
ensureColumn(db, "session_meta", "cached_m0_materialized_at", "INTEGER");
|
|
142569
142539
|
ensureColumn(db, "session_meta", "cached_m0_session_facts_version", "INTEGER");
|
|
142570
142540
|
ensureColumn(db, "session_meta", "cached_m0_upgrade_state", "TEXT");
|
|
142541
|
+
ensureColumn(db, "session_meta", "cached_m0_system_hash", "TEXT");
|
|
142542
|
+
ensureColumn(db, "session_meta", "cached_m0_tool_set_hash", "TEXT");
|
|
142543
|
+
ensureColumn(db, "session_meta", "cached_m0_model_key", "TEXT");
|
|
142571
142544
|
ensureColumn(db, "session_meta", "cached_m0_last_baseline_end_message_id", "TEXT");
|
|
142572
142545
|
ensureColumn(db, "session_meta", "upgrade_reminded_at", "INTEGER");
|
|
142573
142546
|
db.exec(`
|
|
@@ -142654,6 +142627,7 @@ function healNullTextColumns(db) {
|
|
|
142654
142627
|
["todo_synthetic_state_json", ""],
|
|
142655
142628
|
["system_prompt_hash", ""],
|
|
142656
142629
|
["stripped_placeholder_ids", ""],
|
|
142630
|
+
["stale_reduce_stripped_ids", ""],
|
|
142657
142631
|
["memory_block_cache", ""],
|
|
142658
142632
|
["memory_block_ids", ""],
|
|
142659
142633
|
["compaction_marker_state", ""],
|
|
@@ -142763,8 +142737,30 @@ function openDatabase(dbPathOrOptions) {
|
|
|
142763
142737
|
}
|
|
142764
142738
|
}
|
|
142765
142739
|
|
|
142766
|
-
// src/
|
|
142767
|
-
|
|
142740
|
+
// ../plugin/src/config/prune-config-leaf.ts
|
|
142741
|
+
function isPlainObject(value) {
|
|
142742
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
142743
|
+
}
|
|
142744
|
+
function pruneNestedConfigLeaf(block, relativePath) {
|
|
142745
|
+
if (relativePath.length === 0)
|
|
142746
|
+
return null;
|
|
142747
|
+
const result = { ...block };
|
|
142748
|
+
let cursor = result;
|
|
142749
|
+
for (let i = 0;i < relativePath.length - 1; i++) {
|
|
142750
|
+
const seg = String(relativePath[i]);
|
|
142751
|
+
const child = cursor[seg];
|
|
142752
|
+
if (!isPlainObject(child))
|
|
142753
|
+
return null;
|
|
142754
|
+
const clonedChild = { ...child };
|
|
142755
|
+
cursor[seg] = clonedChild;
|
|
142756
|
+
cursor = clonedChild;
|
|
142757
|
+
}
|
|
142758
|
+
const leaf = String(relativePath[relativePath.length - 1]);
|
|
142759
|
+
if (!(leaf in cursor))
|
|
142760
|
+
return null;
|
|
142761
|
+
delete cursor[leaf];
|
|
142762
|
+
return { block: result, removed: relativePath.map(String).join(".") };
|
|
142763
|
+
}
|
|
142768
142764
|
|
|
142769
142765
|
// src/config/index.ts
|
|
142770
142766
|
import { existsSync as existsSync5, readFileSync as readFileSync3 } from "node:fs";
|
|
@@ -142907,6 +142903,70 @@ function migrateLegacyExperimental(rawConfig, warnings) {
|
|
|
142907
142903
|
return patched;
|
|
142908
142904
|
}
|
|
142909
142905
|
|
|
142906
|
+
// ../plugin/src/config/project-security.ts
|
|
142907
|
+
var HIDDEN_AGENT_KEYS = ["historian", "dreamer", "sidekick"];
|
|
142908
|
+
var AGENT_ESCALATION_FIELDS = ["prompt", "permission", "tools", "system_prompt"];
|
|
142909
|
+
function isPlainObject2(value) {
|
|
142910
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
142911
|
+
}
|
|
142912
|
+
function stripUnsafeProjectConfigFields(projectRaw) {
|
|
142913
|
+
const warnings = [];
|
|
142914
|
+
if ("auto_update" in projectRaw) {
|
|
142915
|
+
delete projectRaw.auto_update;
|
|
142916
|
+
warnings.push("Ignoring auto_update from project config (security: this setting only honors user-level config).");
|
|
142917
|
+
}
|
|
142918
|
+
for (const agentKey of HIDDEN_AGENT_KEYS) {
|
|
142919
|
+
const block = projectRaw[agentKey];
|
|
142920
|
+
if (!isPlainObject2(block))
|
|
142921
|
+
continue;
|
|
142922
|
+
const removed = [];
|
|
142923
|
+
for (const field of AGENT_ESCALATION_FIELDS) {
|
|
142924
|
+
if (field in block) {
|
|
142925
|
+
delete block[field];
|
|
142926
|
+
removed.push(field);
|
|
142927
|
+
}
|
|
142928
|
+
}
|
|
142929
|
+
if (removed.length > 0) {
|
|
142930
|
+
warnings.push(`Ignoring ${agentKey}.${removed.join("/")} from project config ` + "(security: a repository cannot reprogram or re-permission hidden agents).");
|
|
142931
|
+
}
|
|
142932
|
+
}
|
|
142933
|
+
return warnings;
|
|
142934
|
+
}
|
|
142935
|
+
function normalizeEndpoint(value) {
|
|
142936
|
+
if (typeof value !== "string")
|
|
142937
|
+
return;
|
|
142938
|
+
const trimmed = value.trim().replace(/\/+$/, "");
|
|
142939
|
+
return trimmed.length > 0 ? trimmed.toLowerCase() : undefined;
|
|
142940
|
+
}
|
|
142941
|
+
function dropInheritedEmbeddingKeyOnRedirect(projectRaw, mergedRaw, userRaw) {
|
|
142942
|
+
const projectEmbedding = projectRaw.embedding;
|
|
142943
|
+
if (!isPlainObject2(projectEmbedding))
|
|
142944
|
+
return [];
|
|
142945
|
+
const redirectsEndpoint = "endpoint" in projectEmbedding;
|
|
142946
|
+
if (!redirectsEndpoint)
|
|
142947
|
+
return [];
|
|
142948
|
+
const userEmbedding = userRaw?.embedding;
|
|
142949
|
+
if (isPlainObject2(userEmbedding)) {
|
|
142950
|
+
const projectEndpoint = normalizeEndpoint(projectEmbedding.endpoint);
|
|
142951
|
+
const userEndpoint = normalizeEndpoint(userEmbedding.endpoint);
|
|
142952
|
+
if (projectEndpoint !== undefined && projectEndpoint === userEndpoint) {
|
|
142953
|
+
return [];
|
|
142954
|
+
}
|
|
142955
|
+
}
|
|
142956
|
+
const providesOwnKey = typeof projectEmbedding.api_key === "string" && projectEmbedding.api_key.length > 0;
|
|
142957
|
+
if (providesOwnKey)
|
|
142958
|
+
return [];
|
|
142959
|
+
const mergedEmbedding = mergedRaw.embedding;
|
|
142960
|
+
if (!isPlainObject2(mergedEmbedding))
|
|
142961
|
+
return [];
|
|
142962
|
+
if (!("api_key" in mergedEmbedding))
|
|
142963
|
+
return [];
|
|
142964
|
+
delete mergedEmbedding.api_key;
|
|
142965
|
+
return [
|
|
142966
|
+
"Dropped inherited user embedding api_key because project config redirected " + "embedding.endpoint without supplying its own key (security: prevents key " + "exfiltration to a repository-chosen endpoint)."
|
|
142967
|
+
];
|
|
142968
|
+
}
|
|
142969
|
+
|
|
142910
142970
|
// ../../node_modules/.bun/zod@4.4.3/node_modules/zod/v4/classic/external.js
|
|
142911
142971
|
var exports_external = {};
|
|
142912
142972
|
__export(exports_external, {
|
|
@@ -143538,7 +143598,7 @@ __export(exports_util, {
|
|
|
143538
143598
|
jsonStringifyReplacer: () => jsonStringifyReplacer,
|
|
143539
143599
|
joinValues: () => joinValues,
|
|
143540
143600
|
issue: () => issue,
|
|
143541
|
-
isPlainObject: () =>
|
|
143601
|
+
isPlainObject: () => isPlainObject3,
|
|
143542
143602
|
isObject: () => isObject,
|
|
143543
143603
|
hexToUint8Array: () => hexToUint8Array,
|
|
143544
143604
|
getSizableOrigin: () => getSizableOrigin,
|
|
@@ -143720,7 +143780,7 @@ var allowsEval = /* @__PURE__ */ cached(() => {
|
|
|
143720
143780
|
return false;
|
|
143721
143781
|
}
|
|
143722
143782
|
});
|
|
143723
|
-
function
|
|
143783
|
+
function isPlainObject3(o) {
|
|
143724
143784
|
if (isObject(o) === false)
|
|
143725
143785
|
return false;
|
|
143726
143786
|
const ctor = o.constructor;
|
|
@@ -143737,7 +143797,7 @@ function isPlainObject(o) {
|
|
|
143737
143797
|
return true;
|
|
143738
143798
|
}
|
|
143739
143799
|
function shallowClone(o) {
|
|
143740
|
-
if (
|
|
143800
|
+
if (isPlainObject3(o))
|
|
143741
143801
|
return { ...o };
|
|
143742
143802
|
if (Array.isArray(o))
|
|
143743
143803
|
return [...o];
|
|
@@ -143941,7 +144001,7 @@ function omit(schema, mask) {
|
|
|
143941
144001
|
return clone(schema, def);
|
|
143942
144002
|
}
|
|
143943
144003
|
function extend(schema, shape) {
|
|
143944
|
-
if (!
|
|
144004
|
+
if (!isPlainObject3(shape)) {
|
|
143945
144005
|
throw new Error("Invalid input to extend: expected a plain object");
|
|
143946
144006
|
}
|
|
143947
144007
|
const checks = schema._zod.def.checks;
|
|
@@ -143964,7 +144024,7 @@ function extend(schema, shape) {
|
|
|
143964
144024
|
return clone(schema, def);
|
|
143965
144025
|
}
|
|
143966
144026
|
function safeExtend(schema, shape) {
|
|
143967
|
-
if (!
|
|
144027
|
+
if (!isPlainObject3(shape)) {
|
|
143968
144028
|
throw new Error("Invalid input to safeExtend: expected a plain object");
|
|
143969
144029
|
}
|
|
143970
144030
|
const def = mergeDefs(schema._zod.def, {
|
|
@@ -146307,7 +146367,7 @@ function mergeValues(a, b) {
|
|
|
146307
146367
|
if (a instanceof Date && b instanceof Date && +a === +b) {
|
|
146308
146368
|
return { valid: true, data: a };
|
|
146309
146369
|
}
|
|
146310
|
-
if (
|
|
146370
|
+
if (isPlainObject3(a) && isPlainObject3(b)) {
|
|
146311
146371
|
const bKeys = Object.keys(b);
|
|
146312
146372
|
const sharedKeys = Object.keys(a).filter((key) => bKeys.indexOf(key) !== -1);
|
|
146313
146373
|
const newObj = { ...a, ...b };
|
|
@@ -146493,7 +146553,7 @@ var $ZodRecord = /* @__PURE__ */ $constructor("$ZodRecord", (inst, def) => {
|
|
|
146493
146553
|
$ZodType.init(inst, def);
|
|
146494
146554
|
inst._zod.parse = (payload, ctx) => {
|
|
146495
146555
|
const input = payload.value;
|
|
146496
|
-
if (!
|
|
146556
|
+
if (!isPlainObject3(input)) {
|
|
146497
146557
|
payload.issues.push({
|
|
146498
146558
|
expected: "record",
|
|
146499
146559
|
code: "invalid_type",
|
|
@@ -157347,6 +157407,7 @@ var MagicContextConfigSchema = exports_external.object({
|
|
|
157347
157407
|
model: DEFAULT_LOCAL_EMBEDDING_MODEL
|
|
157348
157408
|
}).describe("Embedding provider configuration"),
|
|
157349
157409
|
temporal_awareness: exports_external.boolean().default(true).describe('Inject wall-clock gap markers (<!-- +Xm -->) between user messages where > 5 min elapsed since the previous message, and add start/end date attributes on compartments. Gives the agent a sense of session pacing and "how long ago" across multi-day sessions. Graduated from experimental.temporal_awareness; default: true (set false to opt out).'),
|
|
157410
|
+
keep_subagents: exports_external.boolean().default(false).describe("Debug: keep the child sessions Magic Context spawns for its own subagents (historian, dreamer, sidekick, memory-migration) instead of deleting them on success. Useful for short-term inspection/data collection — their full transcript (prompt, tool calls, token usage, output) stays in the host session store. Kept sessions accumulate until manually cleared; leave false for normal use. Requires a restart to take effect."),
|
|
157350
157411
|
caveman_text_compression: exports_external.object({
|
|
157351
157412
|
enabled: exports_external.boolean().default(false).describe("Apply deterministic caveman-style text compression to old conversation text. Only active when ctx_reduce_enabled=false. Compresses user/assistant text in oldest-first tiers: ultra (oldest 20%), full, lite, untouched (newest 40%)."),
|
|
157352
157413
|
min_chars: exports_external.number().min(100).max(1e4).default(500).describe("Text parts shorter than this (characters) stay untouched. Min 100, max 10000. Default: 500.")
|
|
@@ -157446,6 +157507,21 @@ function stripJsonComments(content) {
|
|
|
157446
157507
|
// ../plugin/src/config/variable.ts
|
|
157447
157508
|
var ENV_PATTERN = /\{env:([^}]+)\}/g;
|
|
157448
157509
|
var FILE_PATTERN = /\{file:([^}]+)\}/g;
|
|
157510
|
+
function sensitiveFilePathReason(resolvedPath) {
|
|
157511
|
+
const home = homedir2();
|
|
157512
|
+
const sensitiveDirs = [
|
|
157513
|
+
{ dir: resolve2(home, ".ssh"), label: "SSH keys" },
|
|
157514
|
+
{ dir: resolve2(home, ".aws"), label: "AWS credentials" },
|
|
157515
|
+
{ dir: resolve2(home, ".gnupg"), label: "GnuPG keyring" },
|
|
157516
|
+
{ dir: resolve2(home, ".config", "gh"), label: "GitHub CLI auth" }
|
|
157517
|
+
];
|
|
157518
|
+
for (const { dir, label } of sensitiveDirs) {
|
|
157519
|
+
if (resolvedPath === dir || resolvedPath.startsWith(`${dir}/`)) {
|
|
157520
|
+
return label;
|
|
157521
|
+
}
|
|
157522
|
+
}
|
|
157523
|
+
return null;
|
|
157524
|
+
}
|
|
157449
157525
|
function substituteConfigVariables(input) {
|
|
157450
157526
|
const warnings = [];
|
|
157451
157527
|
let text = input.text;
|
|
@@ -157499,6 +157575,10 @@ function substituteConfigVariables(input) {
|
|
|
157499
157575
|
} else if (!isAbsolute(filePath)) {
|
|
157500
157576
|
filePath = resolve2(configDir, filePath);
|
|
157501
157577
|
}
|
|
157578
|
+
const sensitiveReason = sensitiveFilePathReason(filePath);
|
|
157579
|
+
if (sensitiveReason) {
|
|
157580
|
+
warnings.push(`${token} resolves to a sensitive path (${sensitiveReason}: ${filePath}); ` + "inlining its contents into config — make sure this is intentional.");
|
|
157581
|
+
}
|
|
157502
157582
|
if (!existsSync4(filePath)) {
|
|
157503
157583
|
warnings.push(`File not found for ${token} (resolved to ${filePath}); using empty string`);
|
|
157504
157584
|
continue;
|
|
@@ -157537,7 +157617,8 @@ function loadConfigFile(path3, scope) {
|
|
|
157537
157617
|
const rawText = readFileSync3(path3, "utf-8");
|
|
157538
157618
|
const substituted = substituteConfigVariables({
|
|
157539
157619
|
text: rawText,
|
|
157540
|
-
configPath: path3
|
|
157620
|
+
configPath: path3,
|
|
157621
|
+
isProjectConfig: scope === "project"
|
|
157541
157622
|
});
|
|
157542
157623
|
return {
|
|
157543
157624
|
path: path3,
|
|
@@ -157579,14 +157660,14 @@ function redactConfigValue(value) {
|
|
|
157579
157660
|
}
|
|
157580
157661
|
return typeof value;
|
|
157581
157662
|
}
|
|
157582
|
-
function
|
|
157663
|
+
function isPlainObject4(value) {
|
|
157583
157664
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
157584
157665
|
}
|
|
157585
157666
|
function mergeRawConfigs(base, override) {
|
|
157586
157667
|
const merged = { ...base };
|
|
157587
157668
|
for (const [key, overrideValue] of Object.entries(override)) {
|
|
157588
157669
|
const baseValue = merged[key];
|
|
157589
|
-
merged[key] =
|
|
157670
|
+
merged[key] = isPlainObject4(baseValue) && isPlainObject4(overrideValue) ? mergeRawConfigs(baseValue, overrideValue) : overrideValue;
|
|
157590
157671
|
}
|
|
157591
157672
|
return merged;
|
|
157592
157673
|
}
|
|
@@ -157600,10 +157681,15 @@ function parsePiConfig(rawConfig, recoveredTopLevelKeys = []) {
|
|
|
157600
157681
|
}
|
|
157601
157682
|
const defaults = MagicContextConfigSchema.parse({});
|
|
157602
157683
|
const errorPaths = new Set;
|
|
157684
|
+
const issuePathsByKey = new Map;
|
|
157603
157685
|
for (const issue2 of parsed.error.issues) {
|
|
157604
157686
|
const topKey = issue2.path[0];
|
|
157605
157687
|
if (topKey !== undefined) {
|
|
157606
|
-
|
|
157688
|
+
const key = String(topKey);
|
|
157689
|
+
errorPaths.add(key);
|
|
157690
|
+
const paths = issuePathsByKey.get(key) ?? [];
|
|
157691
|
+
paths.push([...issue2.path]);
|
|
157692
|
+
issuePathsByKey.set(key, paths);
|
|
157607
157693
|
}
|
|
157608
157694
|
}
|
|
157609
157695
|
const patched = { ...migrated };
|
|
@@ -157611,11 +157697,32 @@ function parsePiConfig(rawConfig, recoveredTopLevelKeys = []) {
|
|
|
157611
157697
|
for (const key of errorPaths) {
|
|
157612
157698
|
recoveredTopLevelKeys.push(key);
|
|
157613
157699
|
const isAgentConfig = key === "historian" || key === "dreamer" || key === "sidekick";
|
|
157614
|
-
delete patched[key];
|
|
157615
157700
|
if (isAgentConfig) {
|
|
157701
|
+
delete patched[key];
|
|
157616
157702
|
warnings.push(`"${key}": invalid agent configuration, ignoring. Check your magic-context.jsonc.`);
|
|
157617
157703
|
continue;
|
|
157618
157704
|
}
|
|
157705
|
+
const issuePaths = issuePathsByKey.get(key) ?? [];
|
|
157706
|
+
const rawValue = migrated[key];
|
|
157707
|
+
const allNested = issuePaths.length > 0 && issuePaths.every((p) => p.length >= 2) && typeof rawValue === "object" && rawValue !== null && !Array.isArray(rawValue);
|
|
157708
|
+
if (allNested) {
|
|
157709
|
+
let prunedBlock = {
|
|
157710
|
+
...rawValue
|
|
157711
|
+
};
|
|
157712
|
+
const prunedLeaves = [];
|
|
157713
|
+
for (const p of issuePaths) {
|
|
157714
|
+
const relative = p.slice(1);
|
|
157715
|
+
const result = pruneNestedConfigLeaf(prunedBlock, relative);
|
|
157716
|
+
if (result) {
|
|
157717
|
+
prunedBlock = result.block;
|
|
157718
|
+
prunedLeaves.push(result.removed);
|
|
157719
|
+
}
|
|
157720
|
+
}
|
|
157721
|
+
patched[key] = prunedBlock;
|
|
157722
|
+
warnings.push(`"${key}": invalid nested field(s) ${prunedLeaves.map((l) => `"${l}"`).join(", ")}, using defaults for those.`);
|
|
157723
|
+
continue;
|
|
157724
|
+
}
|
|
157725
|
+
delete patched[key];
|
|
157619
157726
|
const defaultValue = defaults[key];
|
|
157620
157727
|
warnings.push(`"${key}": invalid value (${redactConfigValue(rawConfig[key])}), using default ${JSON.stringify(defaultValue)}.`);
|
|
157621
157728
|
}
|
|
@@ -157648,10 +157755,22 @@ function loadPiConfig(opts = {}) {
|
|
|
157648
157755
|
return 0;
|
|
157649
157756
|
return a.scope === "user" ? -1 : 1;
|
|
157650
157757
|
});
|
|
157758
|
+
const userRaw = mergeFiles.find((f) => f.scope === "user")?.config;
|
|
157651
157759
|
for (const loaded of mergeFiles) {
|
|
157652
157760
|
const prefix = loaded.scope === "user" ? "[user config]" : "[project config]";
|
|
157653
157761
|
warnings.push(...loaded.warnings.map((warning) => `${prefix} ${warning}`));
|
|
157654
|
-
|
|
157762
|
+
if (loaded.scope === "project") {
|
|
157763
|
+
const projectRaw = { ...loaded.config };
|
|
157764
|
+
for (const warning of stripUnsafeProjectConfigFields(projectRaw)) {
|
|
157765
|
+
warnings.push(`${prefix} ${warning}`);
|
|
157766
|
+
}
|
|
157767
|
+
rawConfig = mergeRawConfigs(rawConfig, projectRaw);
|
|
157768
|
+
for (const warning of dropInheritedEmbeddingKeyOnRedirect(projectRaw, rawConfig, userRaw)) {
|
|
157769
|
+
warnings.push(`${prefix} ${warning}`);
|
|
157770
|
+
}
|
|
157771
|
+
} else {
|
|
157772
|
+
rawConfig = mergeRawConfigs(rawConfig, loaded.config);
|
|
157773
|
+
}
|
|
157655
157774
|
}
|
|
157656
157775
|
const parsed = parsePiConfig(rawConfig);
|
|
157657
157776
|
warnings.push(...parsed.warnings.map((warning) => `[merged config] ${warning}`));
|
|
@@ -157726,10 +157845,22 @@ function loadPiConfigDetailed(opts = {}) {
|
|
|
157726
157845
|
return 0;
|
|
157727
157846
|
return a.scope === "user" ? -1 : 1;
|
|
157728
157847
|
});
|
|
157848
|
+
const userRaw = mergeFiles.find((f) => f.scope === "user")?.config;
|
|
157729
157849
|
for (const loaded of mergeFiles) {
|
|
157730
157850
|
const prefix = loaded.scope === "user" ? "[user config]" : "[project config]";
|
|
157731
157851
|
warnings.push(...loaded.warnings.map((warning) => `${prefix} ${warning}`));
|
|
157732
|
-
|
|
157852
|
+
if (loaded.scope === "project") {
|
|
157853
|
+
const projectRaw = { ...loaded.config };
|
|
157854
|
+
for (const warning of stripUnsafeProjectConfigFields(projectRaw)) {
|
|
157855
|
+
warnings.push(`${prefix} ${warning}`);
|
|
157856
|
+
}
|
|
157857
|
+
rawConfig = mergeRawConfigs(rawConfig, projectRaw);
|
|
157858
|
+
for (const warning of dropInheritedEmbeddingKeyOnRedirect(projectRaw, rawConfig, userRaw)) {
|
|
157859
|
+
warnings.push(`${prefix} ${warning}`);
|
|
157860
|
+
}
|
|
157861
|
+
} else {
|
|
157862
|
+
rawConfig = mergeRawConfigs(rawConfig, loaded.config);
|
|
157863
|
+
}
|
|
157733
157864
|
}
|
|
157734
157865
|
const recoveredTopLevelKeys = [];
|
|
157735
157866
|
const parsed = parsePiConfig(rawConfig, recoveredTopLevelKeys);
|
|
@@ -157756,9 +157887,6 @@ function loadPiConfigDetailed(opts = {}) {
|
|
|
157756
157887
|
};
|
|
157757
157888
|
}
|
|
157758
157889
|
|
|
157759
|
-
// ../plugin/src/features/magic-context/memory/embedding.ts
|
|
157760
|
-
init_logger();
|
|
157761
|
-
|
|
157762
157890
|
// ../plugin/src/features/magic-context/memory/cosine-similarity.ts
|
|
157763
157891
|
function cosineSimilarity(a, b) {
|
|
157764
157892
|
if (a.length !== b.length) {
|
|
@@ -157787,7 +157915,7 @@ function computeNormalizedHash(content) {
|
|
|
157787
157915
|
}
|
|
157788
157916
|
|
|
157789
157917
|
// ../plugin/src/features/magic-context/memory/embedding-identity.ts
|
|
157790
|
-
function
|
|
157918
|
+
function normalizeEndpoint2(endpoint) {
|
|
157791
157919
|
return endpoint?.trim().replace(/\/+$/, "") ?? "";
|
|
157792
157920
|
}
|
|
157793
157921
|
function getEmbeddingProviderIdentity(config2) {
|
|
@@ -157797,7 +157925,7 @@ function getEmbeddingProviderIdentity(config2) {
|
|
|
157797
157925
|
const identityInput = config2.provider === "openai-compatible" ? {
|
|
157798
157926
|
provider: "openai-compatible",
|
|
157799
157927
|
model: config2.model.trim(),
|
|
157800
|
-
endpoint:
|
|
157928
|
+
endpoint: normalizeEndpoint2(config2.endpoint),
|
|
157801
157929
|
apiKeyPresent: Boolean(config2.api_key?.trim()),
|
|
157802
157930
|
inputType: config2.input_type?.trim() || ""
|
|
157803
157931
|
} : {
|
|
@@ -157814,8 +157942,6 @@ import { mkdirSync as mkdirSync3 } from "node:fs";
|
|
|
157814
157942
|
import { open, stat, unlink, writeFile } from "node:fs/promises";
|
|
157815
157943
|
import { dirname as dirname4, join as join6 } from "node:path";
|
|
157816
157944
|
import { pathToFileURL } from "node:url";
|
|
157817
|
-
init_data_path();
|
|
157818
|
-
init_logger();
|
|
157819
157945
|
var LOCK_POLL_MS = 150;
|
|
157820
157946
|
var STALE_LOCK_MS = 3 * 60000;
|
|
157821
157947
|
var MAX_LOCK_WAIT_MS = 5 * 60000;
|
|
@@ -158150,9 +158276,61 @@ class LocalEmbeddingProvider {
|
|
|
158150
158276
|
}
|
|
158151
158277
|
}
|
|
158152
158278
|
|
|
158279
|
+
// ../plugin/src/features/magic-context/memory/embedding-ssrf.ts
|
|
158280
|
+
var METADATA_HOSTNAMES = new Set(["metadata.google.internal", "metadata.goog"]);
|
|
158281
|
+
var IPV6_METADATA_HOSTS = new Set(["fd00:ec2::254"]);
|
|
158282
|
+
function isLinkLocalIpv4(host) {
|
|
158283
|
+
return /^169\.254\.\d{1,3}\.\d{1,3}$/.test(host);
|
|
158284
|
+
}
|
|
158285
|
+
function ipv4FromMappedIpv6(host) {
|
|
158286
|
+
const m = /^::ffff:(.+)$/.exec(host);
|
|
158287
|
+
if (!m)
|
|
158288
|
+
return null;
|
|
158289
|
+
const tail = m[1];
|
|
158290
|
+
if (/^\d{1,3}(\.\d{1,3}){3}$/.test(tail))
|
|
158291
|
+
return tail;
|
|
158292
|
+
const hex3 = /^([0-9a-f]{1,4}):([0-9a-f]{1,4})$/.exec(tail);
|
|
158293
|
+
if (hex3) {
|
|
158294
|
+
const hi = Number.parseInt(hex3[1], 16);
|
|
158295
|
+
const lo = Number.parseInt(hex3[2], 16);
|
|
158296
|
+
if (Number.isNaN(hi) || Number.isNaN(lo))
|
|
158297
|
+
return null;
|
|
158298
|
+
return `${hi >> 8 & 255}.${hi & 255}.${lo >> 8 & 255}.${lo & 255}`;
|
|
158299
|
+
}
|
|
158300
|
+
return null;
|
|
158301
|
+
}
|
|
158302
|
+
function blockedEmbeddingEndpointReason(endpoint) {
|
|
158303
|
+
const trimmed = endpoint.trim();
|
|
158304
|
+
if (trimmed.length === 0)
|
|
158305
|
+
return null;
|
|
158306
|
+
let url2;
|
|
158307
|
+
try {
|
|
158308
|
+
url2 = new URL(trimmed);
|
|
158309
|
+
} catch {
|
|
158310
|
+
return `embedding endpoint is not a valid URL: ${trimmed}`;
|
|
158311
|
+
}
|
|
158312
|
+
const host = url2.hostname.toLowerCase().replace(/^\[/, "").replace(/\]$/, "");
|
|
158313
|
+
if (METADATA_HOSTNAMES.has(host)) {
|
|
158314
|
+
return `embedding endpoint host ${host} is a cloud metadata service (blocked)`;
|
|
158315
|
+
}
|
|
158316
|
+
if (IPV6_METADATA_HOSTS.has(host)) {
|
|
158317
|
+
return `embedding endpoint host ${host} is the AWS IPv6 metadata service (blocked)`;
|
|
158318
|
+
}
|
|
158319
|
+
if (isLinkLocalIpv4(host)) {
|
|
158320
|
+
return `embedding endpoint host ${host} is link-local / cloud metadata (blocked)`;
|
|
158321
|
+
}
|
|
158322
|
+
const mappedV4 = ipv4FromMappedIpv6(host);
|
|
158323
|
+
if (mappedV4 && isLinkLocalIpv4(mappedV4)) {
|
|
158324
|
+
return `embedding endpoint host ${host} (IPv4-mapped ${mappedV4}) is link-local / cloud metadata (blocked)`;
|
|
158325
|
+
}
|
|
158326
|
+
if (host.startsWith("fe80:")) {
|
|
158327
|
+
return `embedding endpoint host ${host} is link-local / cloud metadata (blocked)`;
|
|
158328
|
+
}
|
|
158329
|
+
return null;
|
|
158330
|
+
}
|
|
158331
|
+
|
|
158153
158332
|
// ../plugin/src/features/magic-context/memory/embedding-openai.ts
|
|
158154
|
-
|
|
158155
|
-
function normalizeEndpoint2(endpoint) {
|
|
158333
|
+
function normalizeEndpoint3(endpoint) {
|
|
158156
158334
|
return endpoint?.trim().replace(/\/+$/, "") ?? "";
|
|
158157
158335
|
}
|
|
158158
158336
|
var FAILURE_THRESHOLD = 3;
|
|
@@ -158173,7 +158351,7 @@ class OpenAICompatibleEmbeddingProvider {
|
|
|
158173
158351
|
openLogged = false;
|
|
158174
158352
|
halfOpenProbeInFlight = false;
|
|
158175
158353
|
constructor(options) {
|
|
158176
|
-
this.endpoint =
|
|
158354
|
+
this.endpoint = normalizeEndpoint3(options.endpoint);
|
|
158177
158355
|
this.model = options.model?.trim() ?? "";
|
|
158178
158356
|
this.apiKey = options.apiKey?.trim() ?? "";
|
|
158179
158357
|
this.inputType = options.inputType?.trim() ?? "";
|
|
@@ -158193,6 +158371,12 @@ class OpenAICompatibleEmbeddingProvider {
|
|
|
158193
158371
|
this.initialized = false;
|
|
158194
158372
|
return false;
|
|
158195
158373
|
}
|
|
158374
|
+
const blockedReason = blockedEmbeddingEndpointReason(this.endpoint);
|
|
158375
|
+
if (blockedReason) {
|
|
158376
|
+
log(`[magic-context] embedding endpoint blocked: ${blockedReason}`);
|
|
158377
|
+
this.initialized = false;
|
|
158378
|
+
return false;
|
|
158379
|
+
}
|
|
158196
158380
|
this.initialized = true;
|
|
158197
158381
|
return true;
|
|
158198
158382
|
}
|
|
@@ -158238,6 +158422,7 @@ class OpenAICompatibleEmbeddingProvider {
|
|
|
158238
158422
|
...this.inputType ? { input_type: this.inputType } : {},
|
|
158239
158423
|
...this.truncate ? { truncate: this.truncate } : {}
|
|
158240
158424
|
}),
|
|
158425
|
+
redirect: "error",
|
|
158241
158426
|
signal: internalController.signal
|
|
158242
158427
|
});
|
|
158243
158428
|
if (!response.ok) {
|
|
@@ -158442,7 +158627,6 @@ function getDistinctStoredModelIds(db, projectPath) {
|
|
|
158442
158627
|
|
|
158443
158628
|
// ../plugin/src/features/magic-context/project-embedding-registry.ts
|
|
158444
158629
|
import { createHash as createHash3, randomUUID } from "node:crypto";
|
|
158445
|
-
init_logger();
|
|
158446
158630
|
|
|
158447
158631
|
// ../plugin/src/features/magic-context/git-commits/storage-git-commit-embeddings.ts
|
|
158448
158632
|
var saveStatements = new WeakMap;
|
|
@@ -158718,11 +158902,15 @@ function resolveEmbeddingConfig(config2) {
|
|
|
158718
158902
|
}
|
|
158719
158903
|
if (config2.provider === "openai-compatible") {
|
|
158720
158904
|
const apiKey = config2.api_key?.trim();
|
|
158905
|
+
const inputType = config2.input_type?.trim();
|
|
158906
|
+
const truncate = config2.truncate?.trim();
|
|
158721
158907
|
return {
|
|
158722
158908
|
provider: "openai-compatible",
|
|
158723
158909
|
model: config2.model.trim(),
|
|
158724
158910
|
endpoint: config2.endpoint.trim(),
|
|
158725
|
-
...apiKey ? { api_key: apiKey } : {}
|
|
158911
|
+
...apiKey ? { api_key: apiKey } : {},
|
|
158912
|
+
...inputType ? { input_type: inputType } : {},
|
|
158913
|
+
...truncate ? { truncate } : {}
|
|
158726
158914
|
};
|
|
158727
158915
|
}
|
|
158728
158916
|
return { provider: "off" };
|
|
@@ -158738,7 +158926,9 @@ function createProvider(config2) {
|
|
|
158738
158926
|
return new OpenAICompatibleEmbeddingProvider({
|
|
158739
158927
|
endpoint: config2.endpoint,
|
|
158740
158928
|
model: config2.model,
|
|
158741
|
-
apiKey: config2.api_key
|
|
158929
|
+
apiKey: config2.api_key,
|
|
158930
|
+
inputType: config2.input_type,
|
|
158931
|
+
truncate: config2.truncate
|
|
158742
158932
|
});
|
|
158743
158933
|
}
|
|
158744
158934
|
return new LocalEmbeddingProvider(config2.model);
|
|
@@ -159177,18 +159367,40 @@ function hasGitDir(canonical) {
|
|
|
159177
159367
|
return false;
|
|
159178
159368
|
}
|
|
159179
159369
|
}
|
|
159370
|
+
function normalizeStoredProjectPath(rawOrStored) {
|
|
159371
|
+
if (rawOrStored.startsWith("git:") || rawOrStored.startsWith("dir:")) {
|
|
159372
|
+
return rawOrStored;
|
|
159373
|
+
}
|
|
159374
|
+
try {
|
|
159375
|
+
return resolveProjectIdentity(rawOrStored);
|
|
159376
|
+
} catch {
|
|
159377
|
+
return directoryFallback(rawOrStored);
|
|
159378
|
+
}
|
|
159379
|
+
}
|
|
159380
|
+
function storedPathBelongsToIdentity(storedProjectPath, projectIdentity) {
|
|
159381
|
+
return storedProjectPath === projectIdentity || normalizeStoredProjectPath(storedProjectPath) === projectIdentity;
|
|
159382
|
+
}
|
|
159180
159383
|
|
|
159181
159384
|
// ../plugin/src/plugin/embedding-bootstrap-helpers.ts
|
|
159182
159385
|
import { createHash as createHash5 } from "node:crypto";
|
|
159183
|
-
init_logger();
|
|
159184
159386
|
var EMBEDDING_AFFECTING_KEYS = new Set([
|
|
159185
159387
|
"embedding.api_key",
|
|
159186
159388
|
"embedding.endpoint",
|
|
159187
159389
|
"embedding.model",
|
|
159188
|
-
"embedding.provider"
|
|
159390
|
+
"embedding.provider",
|
|
159391
|
+
"embedding.input_type",
|
|
159392
|
+
"embedding.truncate"
|
|
159189
159393
|
]);
|
|
159190
159394
|
var EMBEDDING_AFFECTING_TOP_LEVEL_KEYS = new Set(["embedding", "memory", "experimental"]);
|
|
159191
|
-
var EMBEDDING_WARNING_TERMS = [
|
|
159395
|
+
var EMBEDDING_WARNING_TERMS = [
|
|
159396
|
+
"api_key",
|
|
159397
|
+
"endpoint",
|
|
159398
|
+
"model",
|
|
159399
|
+
"provider",
|
|
159400
|
+
"embedding",
|
|
159401
|
+
"input_type",
|
|
159402
|
+
"truncate"
|
|
159403
|
+
];
|
|
159192
159404
|
var loggedFailureSignatures = new Map;
|
|
159193
159405
|
function sha256Prefix2(value, length = 16) {
|
|
159194
159406
|
return createHash5("sha256").update(value).digest("hex").slice(0, length);
|
|
@@ -159268,6 +159480,7 @@ async function ensureProjectRegisteredFromPiDirectory(directory, db) {
|
|
|
159268
159480
|
};
|
|
159269
159481
|
registerProjectEmbeddingAndMaybeWipe(db, projectIdentity, detailed.config.embedding, features, directory);
|
|
159270
159482
|
}
|
|
159483
|
+
|
|
159271
159484
|
// ../plugin/src/features/magic-context/compartment-lease.ts
|
|
159272
159485
|
var COMPARTMENT_LEASE_TTL_MS = 5 * 60 * 1000;
|
|
159273
159486
|
var COMPARTMENT_LEASE_RENEWAL_MS = 60 * 1000;
|
|
@@ -159361,6 +159574,9 @@ var SESSION_META_SELECT_COLUMNS = [
|
|
|
159361
159574
|
"cached_m0_materialized_at",
|
|
159362
159575
|
"cached_m0_session_facts_version",
|
|
159363
159576
|
"cached_m0_upgrade_state",
|
|
159577
|
+
"cached_m0_system_hash",
|
|
159578
|
+
"cached_m0_tool_set_hash",
|
|
159579
|
+
"cached_m0_model_key",
|
|
159364
159580
|
"last_observed_model_key",
|
|
159365
159581
|
"upgrade_reminded_at",
|
|
159366
159582
|
"pi_stable_id_scheme"
|
|
@@ -159397,6 +159613,9 @@ var META_COLUMNS = {
|
|
|
159397
159613
|
cachedM0MaterializedAt: "cached_m0_materialized_at",
|
|
159398
159614
|
cachedM0SessionFactsVersion: "cached_m0_session_facts_version",
|
|
159399
159615
|
cachedM0UpgradeState: "cached_m0_upgrade_state",
|
|
159616
|
+
cachedM0SystemHash: "cached_m0_system_hash",
|
|
159617
|
+
cachedM0ToolSetHash: "cached_m0_tool_set_hash",
|
|
159618
|
+
cachedM0ModelKey: "cached_m0_model_key",
|
|
159400
159619
|
lastObservedModelKey: "last_observed_model_key",
|
|
159401
159620
|
upgradeRemindedAt: "upgrade_reminded_at",
|
|
159402
159621
|
piStableIdScheme: "pi_stable_id_scheme"
|
|
@@ -159439,7 +159658,7 @@ function isSessionMetaRow(row) {
|
|
|
159439
159658
|
if (row === null || typeof row !== "object")
|
|
159440
159659
|
return false;
|
|
159441
159660
|
const r = row;
|
|
159442
|
-
return typeof r.session_id === "string" && typeof r.last_response_time === "number" && isStringOrNull(r.cache_ttl) && typeof r.counter === "number" && typeof r.last_nudge_tokens === "number" && isStringOrNull(r.last_nudge_band) && isStringOrNull(r.last_transform_error) && typeof r.is_subagent === "number" && typeof r.last_context_percentage === "number" && typeof r.last_input_tokens === "number" && isNumberOrNull(r.observed_safe_input_tokens) && isNumberOrNull(r.cache_alert_sent) && isNumberOrNull(r.times_execute_threshold_reached) && isNumberOrNull(r.compartment_in_progress) && (r.system_prompt_hash === null || typeof r.system_prompt_hash === "string" || typeof r.system_prompt_hash === "number") && isNumberOrNull(r.system_prompt_tokens) && isNumberOrNull(r.conversation_tokens) && isNumberOrNull(r.tool_call_tokens) && isNumberOrNull(r.cleared_reasoning_through_tag) && isStringOrNull(r.last_todo_state) && isBlobOrNull(r.cached_m0_bytes) && isBlobOrNull(r.cached_m1_bytes) && isNumberOrNull(r.cached_m0_project_memory_epoch) && isNumberOrNull(r.cached_m0_project_user_profile_version) && isNumberOrNull(r.cached_m0_max_compartment_seq) && isNumberOrNull(r.cached_m0_max_memory_id) && isNumberOrNull(r.cached_m0_max_mutation_id) && isNumberOrNull(r.cached_m0_max_memory_mutation_id) && isStringOrNull(r.cached_m0_project_docs_hash) && isNumberOrNull(r.cached_m0_materialized_at) && isNumberOrNull(r.cached_m0_session_facts_version) && isStringOrNull(r.cached_m0_upgrade_state) && isStringOrNull(r.last_observed_model_key) && isNumberOrNull(r.upgrade_reminded_at) && isNumberOrNull(r.pi_stable_id_scheme);
|
|
159661
|
+
return typeof r.session_id === "string" && typeof r.last_response_time === "number" && isStringOrNull(r.cache_ttl) && typeof r.counter === "number" && typeof r.last_nudge_tokens === "number" && isStringOrNull(r.last_nudge_band) && isStringOrNull(r.last_transform_error) && typeof r.is_subagent === "number" && typeof r.last_context_percentage === "number" && typeof r.last_input_tokens === "number" && isNumberOrNull(r.observed_safe_input_tokens) && isNumberOrNull(r.cache_alert_sent) && isNumberOrNull(r.times_execute_threshold_reached) && isNumberOrNull(r.compartment_in_progress) && (r.system_prompt_hash === null || typeof r.system_prompt_hash === "string" || typeof r.system_prompt_hash === "number") && isNumberOrNull(r.system_prompt_tokens) && isNumberOrNull(r.conversation_tokens) && isNumberOrNull(r.tool_call_tokens) && isNumberOrNull(r.cleared_reasoning_through_tag) && isStringOrNull(r.last_todo_state) && isBlobOrNull(r.cached_m0_bytes) && isBlobOrNull(r.cached_m1_bytes) && isNumberOrNull(r.cached_m0_project_memory_epoch) && isNumberOrNull(r.cached_m0_project_user_profile_version) && isNumberOrNull(r.cached_m0_max_compartment_seq) && isNumberOrNull(r.cached_m0_max_memory_id) && isNumberOrNull(r.cached_m0_max_mutation_id) && isNumberOrNull(r.cached_m0_max_memory_mutation_id) && isStringOrNull(r.cached_m0_project_docs_hash) && isNumberOrNull(r.cached_m0_materialized_at) && isNumberOrNull(r.cached_m0_session_facts_version) && isStringOrNull(r.cached_m0_upgrade_state) && isStringOrNull(r.cached_m0_system_hash) && isStringOrNull(r.cached_m0_tool_set_hash) && isStringOrNull(r.cached_m0_model_key) && isStringOrNull(r.last_observed_model_key) && isNumberOrNull(r.upgrade_reminded_at) && isNumberOrNull(r.pi_stable_id_scheme);
|
|
159443
159662
|
}
|
|
159444
159663
|
function getDefaultSessionMeta(sessionId) {
|
|
159445
159664
|
return {
|
|
@@ -159475,6 +159694,9 @@ function getDefaultSessionMeta(sessionId) {
|
|
|
159475
159694
|
cachedM0MaterializedAt: null,
|
|
159476
159695
|
cachedM0SessionFactsVersion: null,
|
|
159477
159696
|
cachedM0UpgradeState: null,
|
|
159697
|
+
cachedM0SystemHash: null,
|
|
159698
|
+
cachedM0ToolSetHash: null,
|
|
159699
|
+
cachedM0ModelKey: null,
|
|
159478
159700
|
lastObservedModelKey: null,
|
|
159479
159701
|
upgradeRemindedAt: null,
|
|
159480
159702
|
piStableIdScheme: null
|
|
@@ -159526,6 +159748,9 @@ function toSessionMeta(row) {
|
|
|
159526
159748
|
cachedM0MaterializedAt: numOrNull(row.cached_m0_materialized_at),
|
|
159527
159749
|
cachedM0SessionFactsVersion: numOrNull(row.cached_m0_session_facts_version),
|
|
159528
159750
|
cachedM0UpgradeState: stringOrNull(row.cached_m0_upgrade_state),
|
|
159751
|
+
cachedM0SystemHash: stringOrNull(row.cached_m0_system_hash),
|
|
159752
|
+
cachedM0ToolSetHash: stringOrNull(row.cached_m0_tool_set_hash),
|
|
159753
|
+
cachedM0ModelKey: stringOrNull(row.cached_m0_model_key),
|
|
159529
159754
|
lastObservedModelKey: stringOrNull(row.last_observed_model_key),
|
|
159530
159755
|
upgradeRemindedAt: numOrNull(row.upgrade_reminded_at),
|
|
159531
159756
|
piStableIdScheme: numOrNull(row.pi_stable_id_scheme)
|
|
@@ -159545,8 +159770,11 @@ function persistCachedM0(db, sessionId, payload) {
|
|
|
159545
159770
|
cached_m0_project_docs_hash = ?,
|
|
159546
159771
|
cached_m0_materialized_at = ?,
|
|
159547
159772
|
cached_m0_session_facts_version = ?,
|
|
159548
|
-
cached_m0_upgrade_state =
|
|
159549
|
-
|
|
159773
|
+
cached_m0_upgrade_state = ?,
|
|
159774
|
+
cached_m0_system_hash = ?,
|
|
159775
|
+
cached_m0_tool_set_hash = ?,
|
|
159776
|
+
cached_m0_model_key = ?
|
|
159777
|
+
WHERE session_id = ?`).run(Buffer2.from(payload.m0Bytes), payload.projectMemoryEpoch, payload.projectUserProfileVersion, payload.maxCompartmentSeq, payload.maxMemoryId, payload.maxMutationId, payload.maxMemoryMutationId ?? null, payload.m1Bytes ? Buffer2.from(payload.m1Bytes) : null, payload.projectDocsHash, payload.materializedAt, payload.sessionFactsVersion, payload.upgradeState, payload.systemHash ?? "", payload.toolSetHash ?? "", payload.modelKey ?? "", sessionId);
|
|
159550
159778
|
}
|
|
159551
159779
|
function clearCachedM0M1(db, sessionId) {
|
|
159552
159780
|
ensureSessionMetaRow(db, sessionId);
|
|
@@ -159564,6 +159792,9 @@ function clearCachedM0M1(db, sessionId) {
|
|
|
159564
159792
|
["cached_m0_materialized_at", null],
|
|
159565
159793
|
["cached_m0_session_facts_version", null],
|
|
159566
159794
|
["cached_m0_upgrade_state", null],
|
|
159795
|
+
["cached_m0_system_hash", null],
|
|
159796
|
+
["cached_m0_tool_set_hash", null],
|
|
159797
|
+
["cached_m0_model_key", null],
|
|
159567
159798
|
["cached_m0_last_baseline_end_message_id", null],
|
|
159568
159799
|
["memory_block_cache", ""],
|
|
159569
159800
|
["memory_block_count", 0],
|
|
@@ -159605,12 +159836,6 @@ function isCompartmentRow(row) {
|
|
|
159605
159836
|
const candidate = row;
|
|
159606
159837
|
return typeof candidate.id === "number" && typeof candidate.session_id === "string" && typeof candidate.sequence === "number" && typeof candidate.start_message === "number" && typeof candidate.end_message === "number" && typeof candidate.start_message_id === "string" && typeof candidate.end_message_id === "string" && typeof candidate.title === "string" && typeof candidate.content === "string" && isStringOrNullish(candidate.p1) && isStringOrNullish(candidate.p2) && isStringOrNullish(candidate.p3) && isStringOrNullish(candidate.p4) && isNumberOrNullish(candidate.importance) && isStringOrNullish(candidate.episode_type) && isNumberOrNullish(candidate.legacy) && typeof candidate.created_at === "number";
|
|
159607
159838
|
}
|
|
159608
|
-
function isSessionFactRow(row) {
|
|
159609
|
-
if (row === null || typeof row !== "object")
|
|
159610
|
-
return false;
|
|
159611
|
-
const candidate = row;
|
|
159612
|
-
return typeof candidate.id === "number" && typeof candidate.session_id === "string" && typeof candidate.category === "string" && typeof candidate.content === "string" && typeof candidate.created_at === "number" && typeof candidate.updated_at === "number";
|
|
159613
|
-
}
|
|
159614
159839
|
function insertCompartmentRows(db, sessionId, compartments, now) {
|
|
159615
159840
|
const stmt = getInsertCompartmentStatement(db);
|
|
159616
159841
|
for (const compartment of compartments) {
|
|
@@ -159639,16 +159864,6 @@ function toCompartment(row) {
|
|
|
159639
159864
|
createdAt: row.created_at
|
|
159640
159865
|
};
|
|
159641
159866
|
}
|
|
159642
|
-
function toSessionFact(row) {
|
|
159643
|
-
return {
|
|
159644
|
-
id: row.id,
|
|
159645
|
-
sessionId: row.session_id,
|
|
159646
|
-
category: row.category,
|
|
159647
|
-
content: row.content,
|
|
159648
|
-
createdAt: row.created_at,
|
|
159649
|
-
updatedAt: row.updated_at
|
|
159650
|
-
};
|
|
159651
|
-
}
|
|
159652
159867
|
function getCompartments(db, sessionId) {
|
|
159653
159868
|
const rows = db.prepare("SELECT * FROM compartments WHERE session_id = ? ORDER BY sequence ASC").all(sessionId).filter(isCompartmentRow);
|
|
159654
159869
|
return rows.map(toCompartment);
|
|
@@ -159669,10 +159884,6 @@ function appendCompartments(db, sessionId, compartments) {
|
|
|
159669
159884
|
insertCompartmentRows(db, sessionId, compartments, now);
|
|
159670
159885
|
})();
|
|
159671
159886
|
}
|
|
159672
|
-
function getSessionFacts(db, sessionId) {
|
|
159673
|
-
const rows = db.prepare("SELECT * FROM session_facts WHERE session_id = ? ORDER BY category ASC, id ASC").all(sessionId).filter(isSessionFactRow);
|
|
159674
|
-
return rows.map(toSessionFact);
|
|
159675
|
-
}
|
|
159676
159887
|
function saveRecompStagingPass(db, sessionId, passNumber, compartments, facts) {
|
|
159677
159888
|
const now = Date.now();
|
|
159678
159889
|
db.transaction(() => {
|
|
@@ -159716,14 +159927,6 @@ function getRecompStaging(db, sessionId) {
|
|
|
159716
159927
|
lastEndMessage: lastEnd
|
|
159717
159928
|
};
|
|
159718
159929
|
}
|
|
159719
|
-
function invalidateAllMemoryBlockCaches(db) {
|
|
159720
|
-
try {
|
|
159721
|
-
const rows = db.prepare("SELECT session_id FROM session_meta").all();
|
|
159722
|
-
for (const row of rows) {
|
|
159723
|
-
clearCachedM0M1(db, row.session_id);
|
|
159724
|
-
}
|
|
159725
|
-
} catch {}
|
|
159726
|
-
}
|
|
159727
159930
|
function clearRecompStaging(db, sessionId) {
|
|
159728
159931
|
db.transaction(() => {
|
|
159729
159932
|
db.prepare("DELETE FROM recomp_compartments WHERE session_id = ?").run(sessionId);
|
|
@@ -159770,8 +159973,47 @@ function escapeXmlContent(s) {
|
|
|
159770
159973
|
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
159771
159974
|
}
|
|
159772
159975
|
|
|
159773
|
-
// ../plugin/src/hooks/magic-context/read-session-
|
|
159774
|
-
|
|
159976
|
+
// ../plugin/src/hooks/magic-context/read-session-db.ts
|
|
159977
|
+
import { existsSync as existsSync6 } from "node:fs";
|
|
159978
|
+
import { join as join7 } from "node:path";
|
|
159979
|
+
function getOpenCodeDbPath() {
|
|
159980
|
+
return join7(getDataDir(), "opencode", "opencode.db");
|
|
159981
|
+
}
|
|
159982
|
+
function openCodeDbExists() {
|
|
159983
|
+
return existsSync6(getOpenCodeDbPath());
|
|
159984
|
+
}
|
|
159985
|
+
var cachedReadOnlyDb = null;
|
|
159986
|
+
function closeCachedReadOnlyDb() {
|
|
159987
|
+
if (!cachedReadOnlyDb) {
|
|
159988
|
+
return;
|
|
159989
|
+
}
|
|
159990
|
+
try {
|
|
159991
|
+
closeQuietly(cachedReadOnlyDb.db);
|
|
159992
|
+
} catch (error51) {
|
|
159993
|
+
log("[magic-context] failed to close cached OpenCode read-only DB:", error51);
|
|
159994
|
+
} finally {
|
|
159995
|
+
cachedReadOnlyDb = null;
|
|
159996
|
+
}
|
|
159997
|
+
}
|
|
159998
|
+
function getReadOnlySessionDb() {
|
|
159999
|
+
const dbPath = getOpenCodeDbPath();
|
|
160000
|
+
if (cachedReadOnlyDb?.path === dbPath) {
|
|
160001
|
+
return cachedReadOnlyDb.db;
|
|
160002
|
+
}
|
|
160003
|
+
closeCachedReadOnlyDb();
|
|
160004
|
+
const db = new Database(dbPath, { readonly: true });
|
|
160005
|
+
cachedReadOnlyDb = { path: dbPath, db };
|
|
160006
|
+
return db;
|
|
160007
|
+
}
|
|
160008
|
+
function withReadOnlySessionDb(fn) {
|
|
160009
|
+
return fn(getReadOnlySessionDb());
|
|
160010
|
+
}
|
|
160011
|
+
function getRawSessionMessageCountFromDb(db, sessionId) {
|
|
160012
|
+
const row = db.prepare(`SELECT COUNT(*) as count FROM message WHERE session_id = ?
|
|
160013
|
+
AND NOT (COALESCE(json_extract(data, '$.summary'), 0) = 1
|
|
160014
|
+
AND COALESCE(json_extract(data, '$.finish'), '') = 'stop')`).get(sessionId);
|
|
160015
|
+
return typeof row?.count === "number" ? row.count : 0;
|
|
160016
|
+
}
|
|
159775
160017
|
|
|
159776
160018
|
// ../plugin/src/hooks/magic-context/read-session-raw.ts
|
|
159777
160019
|
function isRawMessageRow(row) {
|
|
@@ -164666,7 +164908,6 @@ var CATEGORY_DEFAULT_TTL = {
|
|
|
164666
164908
|
KNOWN_ISSUES: 30 * 24 * 60 * 60 * 1000
|
|
164667
164909
|
};
|
|
164668
164910
|
// ../plugin/src/features/magic-context/memory/embedding-backfill.ts
|
|
164669
|
-
init_logger();
|
|
164670
164911
|
async function ensureMemoryEmbeddings(args) {
|
|
164671
164912
|
const snapshot = getProjectEmbeddingSnapshot(args.projectIdentity);
|
|
164672
164913
|
if (!snapshot?.enabled) {
|
|
@@ -164704,9 +164945,6 @@ async function ensureMemoryEmbeddings(args) {
|
|
|
164704
164945
|
}
|
|
164705
164946
|
return args.existingEmbeddings;
|
|
164706
164947
|
}
|
|
164707
|
-
// ../plugin/src/features/magic-context/memory/promotion.ts
|
|
164708
|
-
init_logger();
|
|
164709
|
-
|
|
164710
164948
|
// ../plugin/src/features/magic-context/memory/storage-memory.ts
|
|
164711
164949
|
var COLUMN_MAP = {
|
|
164712
164950
|
id: "id",
|
|
@@ -165378,7 +165616,7 @@ function indexMessagesAfterOrdinal(db, sessionId, messages, lastIndexedOrdinal,
|
|
|
165378
165616
|
}
|
|
165379
165617
|
// ../plugin/src/features/magic-context/project-docs-hash.ts
|
|
165380
165618
|
import { createHash as createHash6 } from "node:crypto";
|
|
165381
|
-
import { readFileSync as readFileSync4, statSync as statSync2 } from "node:fs";
|
|
165619
|
+
import { lstatSync, readFileSync as readFileSync4, statSync as statSync2 } from "node:fs";
|
|
165382
165620
|
import path4 from "node:path";
|
|
165383
165621
|
var PROJECT_DOC_FILES = ["ARCHITECTURE.md", "STRUCTURE.md"];
|
|
165384
165622
|
var PROJECT_DOCS_DELIMITER = `
|
|
@@ -165386,6 +165624,7 @@ var PROJECT_DOCS_DELIMITER = `
|
|
|
165386
165624
|
---
|
|
165387
165625
|
|
|
165388
165626
|
`;
|
|
165627
|
+
var MAX_PROJECT_DOC_BYTES = 256 * 1024;
|
|
165389
165628
|
var docsCache = new Map;
|
|
165390
165629
|
function canonicalizeDocContent(raw) {
|
|
165391
165630
|
return raw.replace(/^\uFEFF/, "").replace(/\r\n/g, `
|
|
@@ -165395,9 +165634,10 @@ function canonicalizeDocContent(raw) {
|
|
|
165395
165634
|
}
|
|
165396
165635
|
function fingerprintFile(filePath) {
|
|
165397
165636
|
try {
|
|
165398
|
-
const stat2 =
|
|
165637
|
+
const stat2 = lstatSync(filePath);
|
|
165638
|
+
const isReadableDoc = stat2.isFile() && stat2.size <= MAX_PROJECT_DOC_BYTES;
|
|
165399
165639
|
return {
|
|
165400
|
-
exists:
|
|
165640
|
+
exists: isReadableDoc,
|
|
165401
165641
|
mtimeMs: stat2.mtimeMs,
|
|
165402
165642
|
size: stat2.size
|
|
165403
165643
|
};
|
|
@@ -165440,6 +165680,16 @@ function readCanonicalPieces(projectDirectory, files) {
|
|
|
165440
165680
|
if (!fingerprint?.exists) {
|
|
165441
165681
|
continue;
|
|
165442
165682
|
}
|
|
165683
|
+
let safeToRead = false;
|
|
165684
|
+
try {
|
|
165685
|
+
const st = lstatSync(filePath);
|
|
165686
|
+
safeToRead = st.isFile() && st.size <= MAX_PROJECT_DOC_BYTES;
|
|
165687
|
+
} catch {
|
|
165688
|
+
safeToRead = false;
|
|
165689
|
+
}
|
|
165690
|
+
if (!safeToRead) {
|
|
165691
|
+
continue;
|
|
165692
|
+
}
|
|
165443
165693
|
const canonicalContent = canonicalizeDocContent(readFileSync4(filePath, "utf8"));
|
|
165444
165694
|
hashPieces.push(`file:${filename}
|
|
165445
165695
|
${canonicalContent}`);
|
|
@@ -165606,7 +165856,6 @@ function getMaxMemoryMutationId(db, projectPath) {
|
|
|
165606
165856
|
return row?.max_id ?? null;
|
|
165607
165857
|
}
|
|
165608
165858
|
// ../plugin/src/features/magic-context/storage-meta-persisted.ts
|
|
165609
|
-
init_logger();
|
|
165610
165859
|
var CAS_RETRY_LIMIT = 5;
|
|
165611
165860
|
var AUTO_SEARCH_NO_HINT_REASONS = new Set([
|
|
165612
165861
|
"below-threshold",
|
|
@@ -165761,7 +166010,8 @@ function casUpdateJsonArrayColumn(db, sessionId, column, validator, mutate, opti
|
|
|
165761
166010
|
}
|
|
165762
166011
|
for (let attempt = 0;attempt < CAS_RETRY_LIMIT; attempt += 1) {
|
|
165763
166012
|
const row = db.prepare(`SELECT ${column} FROM session_meta WHERE session_id = ?`).get(sessionId);
|
|
165764
|
-
const
|
|
166013
|
+
const rawCurrent = row?.[column] ?? null;
|
|
166014
|
+
const currentBlob = rawCurrent ?? "[]";
|
|
165765
166015
|
const current = parseJsonArray(currentBlob, validator);
|
|
165766
166016
|
const next = mutate(current);
|
|
165767
166017
|
if (next === null)
|
|
@@ -165769,7 +166019,7 @@ function casUpdateJsonArrayColumn(db, sessionId, column, validator, mutate, opti
|
|
|
165769
166019
|
const nextBlob = stableStringify(next);
|
|
165770
166020
|
if (nextBlob === currentBlob)
|
|
165771
166021
|
return true;
|
|
165772
|
-
const result = db.prepare(`UPDATE session_meta SET ${column} = ? WHERE session_id = ? AND ${column}
|
|
166022
|
+
const result = db.prepare(`UPDATE session_meta SET ${column} = ? WHERE session_id = ? AND ${column} IS ?`).run(nextBlob, sessionId, rawCurrent);
|
|
165773
166023
|
if (result.changes > 0)
|
|
165774
166024
|
return true;
|
|
165775
166025
|
}
|
|
@@ -165898,14 +166148,16 @@ function getHistorianFailureState(db, sessionId) {
|
|
|
165898
166148
|
};
|
|
165899
166149
|
}
|
|
165900
166150
|
function incrementHistorianFailure(db, sessionId, error51) {
|
|
166151
|
+
let nextCount = 1;
|
|
165901
166152
|
db.transaction(() => {
|
|
165902
166153
|
ensureSessionMetaRow(db, sessionId);
|
|
165903
166154
|
const current = getHistorianFailureState(db, sessionId);
|
|
165904
|
-
|
|
166155
|
+
nextCount = current.failureCount + 1;
|
|
165905
166156
|
db.prepare("UPDATE session_meta SET historian_failure_count = ?, historian_last_error = ?, historian_last_failure_at = ? WHERE session_id = ?").run(nextCount, error51, Date.now(), sessionId);
|
|
165906
166157
|
const reason = error51.replace(/\s+/g, " ").trim().slice(0, 300);
|
|
165907
166158
|
sessionLog(sessionId, `historian failure recorded: count=${nextCount} reason="${reason}"`);
|
|
165908
166159
|
})();
|
|
166160
|
+
return nextCount;
|
|
165909
166161
|
}
|
|
165910
166162
|
function clearHistorianFailureState(db, sessionId) {
|
|
165911
166163
|
db.transaction(() => {
|
|
@@ -165974,10 +166226,39 @@ function getStrippedPlaceholderIds(db, sessionId) {
|
|
|
165974
166226
|
} catch {}
|
|
165975
166227
|
return new Set;
|
|
165976
166228
|
}
|
|
165977
|
-
function
|
|
166229
|
+
function applyStrippedPlaceholderDelta(db, sessionId, delta) {
|
|
166230
|
+
const add = delta.add ? [...delta.add] : [];
|
|
166231
|
+
const remove = delta.remove ? [...delta.remove] : [];
|
|
166232
|
+
if (add.length === 0 && remove.length === 0)
|
|
166233
|
+
return true;
|
|
165978
166234
|
ensureSessionMetaRow(db, sessionId);
|
|
165979
|
-
|
|
165980
|
-
|
|
166235
|
+
for (let attempt = 0;attempt < CAS_RETRY_LIMIT; attempt += 1) {
|
|
166236
|
+
const row = db.prepare("SELECT stripped_placeholder_ids FROM session_meta WHERE session_id = ?").get(sessionId);
|
|
166237
|
+
const rawStored = row ? row.stripped_placeholder_ids ?? null : null;
|
|
166238
|
+
const current = new Set(parseStrippedBlob(rawStored));
|
|
166239
|
+
for (const id of add)
|
|
166240
|
+
current.add(id);
|
|
166241
|
+
for (const id of remove)
|
|
166242
|
+
current.delete(id);
|
|
166243
|
+
const nextBlob = current.size > 0 ? JSON.stringify([...current]) : "";
|
|
166244
|
+
if (nextBlob === (rawStored ?? ""))
|
|
166245
|
+
return true;
|
|
166246
|
+
const result = db.prepare("UPDATE session_meta SET stripped_placeholder_ids = ? WHERE session_id = ? AND stripped_placeholder_ids IS ?").run(nextBlob, sessionId, rawStored);
|
|
166247
|
+
if (result.changes > 0)
|
|
166248
|
+
return true;
|
|
166249
|
+
}
|
|
166250
|
+
sessionLog(sessionId, `stripped_placeholder_ids CAS: ${CAS_RETRY_LIMIT} retries exhausted`);
|
|
166251
|
+
return false;
|
|
166252
|
+
}
|
|
166253
|
+
function parseStrippedBlob(raw) {
|
|
166254
|
+
if (!raw || raw.length === 0)
|
|
166255
|
+
return [];
|
|
166256
|
+
try {
|
|
166257
|
+
const parsed = JSON.parse(raw);
|
|
166258
|
+
if (Array.isArray(parsed))
|
|
166259
|
+
return parsed.filter((v) => typeof v === "string");
|
|
166260
|
+
} catch {}
|
|
166261
|
+
return [];
|
|
165981
166262
|
}
|
|
165982
166263
|
function isPendingCompactionMarker(value) {
|
|
165983
166264
|
return typeof value === "object" && value !== null && typeof value.ordinal === "number" && typeof value.endMessageId === "string" && typeof value.publishedAt === "number";
|
|
@@ -166069,8 +166350,6 @@ function setSessionWorkMetrics(db, sessionId, newWorkTokens, totalInputTokens) {
|
|
|
166069
166350
|
import { Buffer as Buffer3 } from "node:buffer";
|
|
166070
166351
|
|
|
166071
166352
|
// ../plugin/src/features/magic-context/resolve-subagent-fallback.ts
|
|
166072
|
-
init_logger();
|
|
166073
|
-
await init_read_session_db();
|
|
166074
166353
|
function resolveIsSubagentFromOpenCodeDb(sessionId) {
|
|
166075
166354
|
try {
|
|
166076
166355
|
return withReadOnlySessionDb((openCodeDb) => {
|
|
@@ -166104,6 +166383,9 @@ var SESSION_META_FALLBACK_SELECTS = {
|
|
|
166104
166383
|
cached_m0_materialized_at: "NULL AS cached_m0_materialized_at",
|
|
166105
166384
|
cached_m0_session_facts_version: "NULL AS cached_m0_session_facts_version",
|
|
166106
166385
|
cached_m0_upgrade_state: "NULL AS cached_m0_upgrade_state",
|
|
166386
|
+
cached_m0_system_hash: "NULL AS cached_m0_system_hash",
|
|
166387
|
+
cached_m0_tool_set_hash: "NULL AS cached_m0_tool_set_hash",
|
|
166388
|
+
cached_m0_model_key: "NULL AS cached_m0_model_key",
|
|
166107
166389
|
last_observed_model_key: "NULL AS last_observed_model_key",
|
|
166108
166390
|
upgrade_reminded_at: "NULL AS upgrade_reminded_at"
|
|
166109
166391
|
};
|
|
@@ -166336,7 +166618,6 @@ function markNoteChecked(db, noteId) {
|
|
|
166336
166618
|
db.prepare("UPDATE notes SET last_checked_at = ?, updated_at = ? WHERE id = ? AND type = 'smart'").run(now, now, noteId);
|
|
166337
166619
|
}
|
|
166338
166620
|
// ../plugin/src/features/magic-context/storage-ops.ts
|
|
166339
|
-
init_logger();
|
|
166340
166621
|
var queuePendingOpStatements = new WeakMap;
|
|
166341
166622
|
var getPendingOpsStatements = new WeakMap;
|
|
166342
166623
|
var clearPendingOpsStatements = new WeakMap;
|
|
@@ -166738,7 +167019,6 @@ var ERROR_CLASSES = new Set([
|
|
|
166738
167019
|
"unknown"
|
|
166739
167020
|
]);
|
|
166740
167021
|
// src/tools/ctx-memory.ts
|
|
166741
|
-
init_logger();
|
|
166742
167022
|
var DEFAULT_LIST_LIMIT = 10;
|
|
166743
167023
|
var VALID_CATEGORIES = new Set(CATEGORY_PRIORITY);
|
|
166744
167024
|
function isMemoryCategory2(value) {
|
|
@@ -166883,7 +167163,6 @@ function createCtxMemoryTool(deps) {
|
|
|
166883
167163
|
sourceType: dreamerAllowed ? "dreamer" : "agent"
|
|
166884
167164
|
});
|
|
166885
167165
|
queueEmbedding({ deps, projectIdentity, memoryId: memory2.id, content });
|
|
166886
|
-
invalidateAllMemoryBlockCaches(deps.db);
|
|
166887
167166
|
return ok2(`Saved memory [ID: ${memory2.id}] in ${rawCategory}.`);
|
|
166888
167167
|
}
|
|
166889
167168
|
if (params.action === "delete") {
|
|
@@ -166891,7 +167170,7 @@ function createCtxMemoryTool(deps) {
|
|
|
166891
167170
|
return err2("Error: 'id' is required when action is 'delete'.");
|
|
166892
167171
|
}
|
|
166893
167172
|
const memory2 = getMemoryById(deps.db, params.id);
|
|
166894
|
-
if (!memory2 || memory2.projectPath
|
|
167173
|
+
if (!memory2 || !storedPathBelongsToIdentity(memory2.projectPath, projectIdentity)) {
|
|
166895
167174
|
return err2(`Error: Memory with ID ${params.id} was not found.`);
|
|
166896
167175
|
}
|
|
166897
167176
|
deps.db.transaction(() => {
|
|
@@ -166920,7 +167199,7 @@ function createCtxMemoryTool(deps) {
|
|
|
166920
167199
|
return err2("Error: 'content' is required when action is 'update'.");
|
|
166921
167200
|
}
|
|
166922
167201
|
const memory2 = getMemoryById(deps.db, params.id);
|
|
166923
|
-
if (!memory2 || memory2.projectPath
|
|
167202
|
+
if (!memory2 || !storedPathBelongsToIdentity(memory2.projectPath, projectIdentity)) {
|
|
166924
167203
|
return err2(`Error: Memory with ID ${params.id} was not found.`);
|
|
166925
167204
|
}
|
|
166926
167205
|
const normalizedHash = computeNormalizedHash(content);
|
|
@@ -166954,9 +167233,6 @@ function createCtxMemoryTool(deps) {
|
|
|
166954
167233
|
if (sourceMemories.length !== ids.length) {
|
|
166955
167234
|
return err2("Error: One or more source memories were not found.");
|
|
166956
167235
|
}
|
|
166957
|
-
if (sourceMemories.some((memory2) => memory2.projectPath !== projectIdentity)) {
|
|
166958
|
-
return err2("Error: All memories to merge must belong to the current project.");
|
|
166959
|
-
}
|
|
166960
167236
|
const requestedCategory = params.category?.trim();
|
|
166961
167237
|
if (requestedCategory && !isMemoryCategory2(requestedCategory)) {
|
|
166962
167238
|
return err2(`Error: Unknown memory category '${requestedCategory}'. Valid: ${CATEGORY_PRIORITY.join(", ")}`);
|
|
@@ -167015,7 +167291,7 @@ function createCtxMemoryTool(deps) {
|
|
|
167015
167291
|
}
|
|
167016
167292
|
supersededMemory(deps.db, memory2.id, canonicalMemory.id);
|
|
167017
167293
|
queueMemoryMutation(deps.db, {
|
|
167018
|
-
projectPath: memory2.projectPath,
|
|
167294
|
+
projectPath: normalizeStoredProjectPath(memory2.projectPath),
|
|
167019
167295
|
mutationType: "superseded",
|
|
167020
167296
|
targetMemoryId: memory2.id,
|
|
167021
167297
|
supersededById: canonicalMemory.id
|
|
@@ -167023,7 +167299,7 @@ function createCtxMemoryTool(deps) {
|
|
|
167023
167299
|
}
|
|
167024
167300
|
if (canonicalExisting && canonicalContentChanged) {
|
|
167025
167301
|
queueMemoryMutation(deps.db, {
|
|
167026
|
-
projectPath: canonicalMemory.projectPath,
|
|
167302
|
+
projectPath: normalizeStoredProjectPath(canonicalMemory.projectPath),
|
|
167027
167303
|
mutationType: "update",
|
|
167028
167304
|
targetMemoryId: canonicalMemory.id,
|
|
167029
167305
|
category,
|
|
@@ -167045,7 +167321,7 @@ function createCtxMemoryTool(deps) {
|
|
|
167045
167321
|
return err2("Error: 'id' is required when action is 'archive'.");
|
|
167046
167322
|
}
|
|
167047
167323
|
const memory2 = getMemoryById(deps.db, params.id);
|
|
167048
|
-
if (!memory2 || memory2.projectPath
|
|
167324
|
+
if (!memory2 || !storedPathBelongsToIdentity(memory2.projectPath, projectIdentity)) {
|
|
167049
167325
|
return err2(`Error: Memory with ID ${params.id} was not found.`);
|
|
167050
167326
|
}
|
|
167051
167327
|
deps.db.transaction(() => {
|
|
@@ -167307,7 +167583,7 @@ ${smartNotes.map(formatNoteLine).join(`
|
|
|
167307
167583
|
// ../plugin/src/features/magic-context/range-parser.ts
|
|
167308
167584
|
function parseRangeString(input) {
|
|
167309
167585
|
const maxRangeElements = 1000;
|
|
167310
|
-
const trimmed = input.trim();
|
|
167586
|
+
const trimmed = input.replace(/§/g, "").trim();
|
|
167311
167587
|
if (trimmed === "") {
|
|
167312
167588
|
throw new Error("Range string must not be empty");
|
|
167313
167589
|
}
|
|
@@ -167455,11 +167731,7 @@ function createCtxReduceTool(deps) {
|
|
|
167455
167731
|
};
|
|
167456
167732
|
}
|
|
167457
167733
|
|
|
167458
|
-
// ../plugin/src/features/magic-context/search.ts
|
|
167459
|
-
init_logger();
|
|
167460
|
-
|
|
167461
167734
|
// ../plugin/src/features/magic-context/git-commits/git-log-reader.ts
|
|
167462
|
-
init_logger();
|
|
167463
167735
|
import { execFile } from "node:child_process";
|
|
167464
167736
|
import { promisify } from "node:util";
|
|
167465
167737
|
var execFileAsync = promisify(execFile);
|
|
@@ -167543,11 +167815,7 @@ ${body}` : subject;
|
|
|
167543
167815
|
}
|
|
167544
167816
|
return commits;
|
|
167545
167817
|
}
|
|
167546
|
-
// ../plugin/src/features/magic-context/git-commits/indexer.ts
|
|
167547
|
-
init_logger();
|
|
167548
|
-
|
|
167549
167818
|
// ../plugin/src/features/magic-context/git-commits/storage-git-commits.ts
|
|
167550
|
-
init_logger();
|
|
167551
167819
|
var insertStatements = new WeakMap;
|
|
167552
167820
|
var existingShasStatements = new WeakMap;
|
|
167553
167821
|
var projectCountStatements = new WeakMap;
|
|
@@ -167760,7 +168028,6 @@ async function embedUnembeddedCommits(db, projectPath) {
|
|
|
167760
168028
|
}
|
|
167761
168029
|
}
|
|
167762
168030
|
// ../plugin/src/features/magic-context/git-commits/search-git-commits.ts
|
|
167763
|
-
init_logger();
|
|
167764
168031
|
var ftsStatements = new WeakMap;
|
|
167765
168032
|
var ftsPlainStatements = new WeakMap;
|
|
167766
168033
|
var getBySHAStatements = new WeakMap;
|
|
@@ -168431,9 +168698,6 @@ class BoundedSessionMap {
|
|
|
168431
168698
|
}
|
|
168432
168699
|
}
|
|
168433
168700
|
|
|
168434
|
-
// ../plugin/src/hooks/magic-context/inject-compartments.ts
|
|
168435
|
-
init_logger();
|
|
168436
|
-
|
|
168437
168701
|
// ../plugin/src/hooks/magic-context/decay-curve.ts
|
|
168438
168702
|
var H50 = 24;
|
|
168439
168703
|
var D = 25;
|
|
@@ -168497,6 +168761,9 @@ function escapeXmlAttr2(s) {
|
|
|
168497
168761
|
function escapeXmlContent2(s) {
|
|
168498
168762
|
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
168499
168763
|
}
|
|
168764
|
+
function isTieredRow(c) {
|
|
168765
|
+
return typeof c.p1 === "string" && c.p1.length > 0;
|
|
168766
|
+
}
|
|
168500
168767
|
function tierBody(c, tier2) {
|
|
168501
168768
|
const tiers = [c.p1, c.p2, c.p3, c.p4];
|
|
168502
168769
|
const requested = tiers[tier2 - 1];
|
|
@@ -168526,12 +168793,13 @@ function renderOneCompartment(c, tier2) {
|
|
|
168526
168793
|
const baseAttrs = `start="${c.startMessage}" end="${c.endMessage}" title="${escapeXmlAttr2(c.title)}"`;
|
|
168527
168794
|
if (tier2 >= 5)
|
|
168528
168795
|
return "";
|
|
168529
|
-
if (c.legacy === 1) {
|
|
168530
|
-
|
|
168796
|
+
if (c.legacy === 1 || !isTieredRow(c)) {
|
|
168797
|
+
const flat = (c.content ?? "").trim();
|
|
168798
|
+
if (tier2 >= 4 || flat.length === 0)
|
|
168531
168799
|
return `<compartment ${baseAttrs} />`;
|
|
168532
168800
|
return [
|
|
168533
168801
|
`<compartment ${baseAttrs}>`,
|
|
168534
|
-
escapeXmlContent2(legacyBodyForTier(
|
|
168802
|
+
escapeXmlContent2(legacyBodyForTier(flat, tier2)),
|
|
168535
168803
|
"</compartment>"
|
|
168536
168804
|
].join(`
|
|
168537
168805
|
`);
|
|
@@ -168608,26 +168876,58 @@ import { join as join9, sep as sep2 } from "node:path";
|
|
|
168608
168876
|
var import_comment_json2 = __toESM(require_src2(), 1);
|
|
168609
168877
|
import { existsSync as existsSync7, readFileSync as readFileSync5 } from "node:fs";
|
|
168610
168878
|
import { homedir as homedir4 } from "node:os";
|
|
168611
|
-
import { join as join8 } from "node:path";
|
|
168879
|
+
import { isAbsolute as isAbsolute2, join as join8, resolve as resolve3 } from "node:path";
|
|
168880
|
+
import { fileURLToPath } from "node:url";
|
|
168612
168881
|
var overrideAvailability = null;
|
|
168613
168882
|
function parseConfig(path5) {
|
|
168614
168883
|
if (!existsSync7(path5))
|
|
168615
168884
|
return null;
|
|
168616
168885
|
return import_comment_json2.parse(readFileSync5(path5, "utf-8"));
|
|
168617
168886
|
}
|
|
168618
|
-
|
|
168887
|
+
var AFT_NAME_NEEDLES = ["@cortexkit/aft", "aft-opencode", "aft-pi"];
|
|
168888
|
+
function stringMentionsAft(value) {
|
|
168889
|
+
return AFT_NAME_NEEDLES.some((needle) => value.includes(needle));
|
|
168890
|
+
}
|
|
168891
|
+
function resolveLocalEntryPackageName(value, configDir) {
|
|
168892
|
+
let dir = null;
|
|
168893
|
+
if (value.startsWith("file://")) {
|
|
168894
|
+
try {
|
|
168895
|
+
dir = fileURLToPath(value);
|
|
168896
|
+
} catch {
|
|
168897
|
+
return null;
|
|
168898
|
+
}
|
|
168899
|
+
} else if (value.startsWith("~/")) {
|
|
168900
|
+
dir = join8(homedir4(), value.slice(2));
|
|
168901
|
+
} else if (value.startsWith("/") || value.startsWith("./") || value.startsWith("../")) {
|
|
168902
|
+
dir = isAbsolute2(value) ? value : resolve3(configDir, value);
|
|
168903
|
+
} else {
|
|
168904
|
+
return null;
|
|
168905
|
+
}
|
|
168906
|
+
try {
|
|
168907
|
+
const pkg = JSON.parse(readFileSync5(join8(dir, "package.json"), "utf-8"));
|
|
168908
|
+
return typeof pkg.name === "string" ? pkg.name : null;
|
|
168909
|
+
} catch {
|
|
168910
|
+
return null;
|
|
168911
|
+
}
|
|
168912
|
+
}
|
|
168913
|
+
function entryMatchesAft(entry, configDir) {
|
|
168619
168914
|
const value = Array.isArray(entry) ? entry[0] : entry;
|
|
168620
|
-
|
|
168915
|
+
if (typeof value !== "string")
|
|
168916
|
+
return false;
|
|
168917
|
+
if (stringMentionsAft(value))
|
|
168918
|
+
return true;
|
|
168919
|
+
const name2 = resolveLocalEntryPackageName(value, configDir);
|
|
168920
|
+
return name2 != null && stringMentionsAft(name2);
|
|
168621
168921
|
}
|
|
168622
|
-
function hasAftInArray(value) {
|
|
168623
|
-
return Array.isArray(value) && value.some(entryMatchesAft);
|
|
168922
|
+
function hasAftInArray(value, configDir) {
|
|
168923
|
+
return Array.isArray(value) && value.some((entry) => entryMatchesAft(entry, configDir));
|
|
168624
168924
|
}
|
|
168625
|
-
function hasAftAtKeys(value, keys2) {
|
|
168925
|
+
function hasAftAtKeys(value, keys2, configDir) {
|
|
168626
168926
|
if (!value || typeof value !== "object")
|
|
168627
168927
|
return false;
|
|
168628
168928
|
const record4 = value;
|
|
168629
168929
|
for (const key of keys2) {
|
|
168630
|
-
if (hasAftInArray(record4[key]))
|
|
168930
|
+
if (hasAftInArray(record4[key], configDir))
|
|
168631
168931
|
return true;
|
|
168632
168932
|
}
|
|
168633
168933
|
return false;
|
|
@@ -168644,7 +168944,8 @@ function getAftAvailability() {
|
|
|
168644
168944
|
for (const path5 of opencodePaths) {
|
|
168645
168945
|
try {
|
|
168646
168946
|
const config2 = parseConfig(path5);
|
|
168647
|
-
|
|
168947
|
+
const configDir = join8(path5, "..");
|
|
168948
|
+
if (hasAftAtKeys(config2, ["plugin", "plugins", "mcp", "mcp_servers"], configDir)) {
|
|
168648
168949
|
opencode = true;
|
|
168649
168950
|
break;
|
|
168650
168951
|
}
|
|
@@ -168654,12 +168955,13 @@ function getAftAvailability() {
|
|
|
168654
168955
|
for (const path5 of piPaths) {
|
|
168655
168956
|
try {
|
|
168656
168957
|
const config2 = parseConfig(path5);
|
|
168657
|
-
|
|
168958
|
+
const configDir = join8(path5, "..");
|
|
168959
|
+
if (hasAftAtKeys(config2, ["packages", "extensions"], configDir)) {
|
|
168658
168960
|
pi = true;
|
|
168659
168961
|
break;
|
|
168660
168962
|
}
|
|
168661
168963
|
const agent = config2?.agent;
|
|
168662
|
-
if (hasAftAtKeys(agent, ["packages", "extensions"])) {
|
|
168964
|
+
if (hasAftAtKeys(agent, ["packages", "extensions"], configDir)) {
|
|
168663
168965
|
pi = true;
|
|
168664
168966
|
break;
|
|
168665
168967
|
}
|
|
@@ -168678,7 +168980,6 @@ function isAftAvailable() {
|
|
|
168678
168980
|
}
|
|
168679
168981
|
|
|
168680
168982
|
// ../plugin/src/hooks/magic-context/key-files-block.ts
|
|
168681
|
-
init_logger();
|
|
168682
168983
|
var cachedKeyFilesBySession = new Map;
|
|
168683
168984
|
var staleUpdates = new Map;
|
|
168684
168985
|
function staleKey(update2) {
|
|
@@ -168776,9 +169077,6 @@ ${blocks.join(`
|
|
|
168776
169077
|
return rendered;
|
|
168777
169078
|
}
|
|
168778
169079
|
|
|
168779
|
-
// ../plugin/src/hooks/magic-context/inject-compartments.ts
|
|
168780
|
-
await init_read_session_db();
|
|
168781
|
-
|
|
168782
169080
|
// ../plugin/src/hooks/magic-context/temporal-awareness.ts
|
|
168783
169081
|
var TEMPORAL_AWARENESS_THRESHOLD_SECONDS = 300;
|
|
168784
169082
|
var SECONDS_PER_MINUTE = 60;
|
|
@@ -169048,6 +169346,7 @@ function createCtxSearchTool(deps) {
|
|
|
169048
169346
|
const embeddingEnabled = snapshot ? snapshot.enabled || snapshot.gitCommitEnabled : deps.embeddingEnabled;
|
|
169049
169347
|
const gitCommitsEnabled = snapshot?.gitCommitEnabled ?? deps.gitCommitsEnabled ?? false;
|
|
169050
169348
|
const lastCompartmentEnd = getLastCompartmentEndMessage(deps.db, sessionId);
|
|
169349
|
+
const messageOrdinalCutoff = lastCompartmentEnd >= 0 ? lastCompartmentEnd : 0;
|
|
169051
169350
|
const visibleMemoryIds = getVisibleMemoryIds(deps.db, sessionId);
|
|
169052
169351
|
const results = await unifiedSearch(deps.db, sessionId, projectIdentity, query, {
|
|
169053
169352
|
limit: normalizeLimit3(params.limit),
|
|
@@ -169058,7 +169357,7 @@ function createCtxSearchTool(deps) {
|
|
|
169058
169357
|
return result?.vector ?? null;
|
|
169059
169358
|
},
|
|
169060
169359
|
isEmbeddingRuntimeEnabled: () => embeddingEnabled === true,
|
|
169061
|
-
maxMessageOrdinal:
|
|
169360
|
+
maxMessageOrdinal: messageOrdinalCutoff,
|
|
169062
169361
|
gitCommitsEnabled,
|
|
169063
169362
|
sources: params.sources,
|
|
169064
169363
|
visibleMemoryIds,
|