@cortexkit/pi-magic-context 0.33.0 → 0.34.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/{index-f3jfb2ed.js → index-0k3j1tc3.js} +1394 -262
- package/dist/{rpc-notifications-td0amw6w.js → index-hw34xmzk.js} +2 -10
- package/dist/index.js +1240 -1091
- package/dist/rpc-notifications-s2rw51c6.js +17 -0
- package/dist/subagent-entry.js +8 -4
- package/package.json +69 -69
- /package/dist/{index-v7fmc1s2.js → index-3pnd4qh9.js} +0 -0
|
@@ -7852,9 +7852,13 @@ var require_src2 = __commonJS((exports, module) => {
|
|
|
7852
7852
|
});
|
|
7853
7853
|
|
|
7854
7854
|
// ../plugin/src/config/agent-disable.ts
|
|
7855
|
+
var COMPACTION_ENABLED_PATH = `compaction${"."}enabled`;
|
|
7855
7856
|
function isDreamerRunnable(config) {
|
|
7856
7857
|
return !!config.dreamer && config.dreamer.disable !== true;
|
|
7857
7858
|
}
|
|
7859
|
+
function isCompactionEnabled(config) {
|
|
7860
|
+
return config.compaction?.enabled !== false;
|
|
7861
|
+
}
|
|
7858
7862
|
function clonePlainObject(value) {
|
|
7859
7863
|
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
7860
7864
|
return;
|
|
@@ -8296,6 +8300,7 @@ var dubiousOwnershipLoggedDirectories = new Set;
|
|
|
8296
8300
|
var dubiousOwnershipWarnedDirectories = new Set;
|
|
8297
8301
|
var transientGitIdentityReuseLoggedDirectories = new Set;
|
|
8298
8302
|
var execFileSyncForIdentity = execFileSync;
|
|
8303
|
+
var userHomeDirectoryForIdentity = () => homedir2();
|
|
8299
8304
|
var nowMs = () => Date.now();
|
|
8300
8305
|
|
|
8301
8306
|
class ProjectIdentityError extends Error {
|
|
@@ -8491,9 +8496,12 @@ function recordDubiousOwnershipFallback(canonical) {
|
|
|
8491
8496
|
dubiousOwnershipLoggedDirectories.add(canonical);
|
|
8492
8497
|
log(`[magic-context] ${formatDubiousOwnershipWarning(canonical)}`);
|
|
8493
8498
|
}
|
|
8499
|
+
function canonicalUserHomeDirectory() {
|
|
8500
|
+
return realpathSync.native(userHomeDirectoryForIdentity());
|
|
8501
|
+
}
|
|
8494
8502
|
function isUserHomeDirectory(directory) {
|
|
8495
8503
|
try {
|
|
8496
|
-
return realpathSync.native(path.resolve(directory)) ===
|
|
8504
|
+
return realpathSync.native(path.resolve(directory)) === canonicalUserHomeDirectory();
|
|
8497
8505
|
} catch {
|
|
8498
8506
|
return false;
|
|
8499
8507
|
}
|
|
@@ -8562,22 +8570,52 @@ function hasGitDir(canonical) {
|
|
|
8562
8570
|
return false;
|
|
8563
8571
|
}
|
|
8564
8572
|
}
|
|
8565
|
-
function
|
|
8573
|
+
function gitRootInAncestorChain(startDirectory) {
|
|
8566
8574
|
let current = startDirectory;
|
|
8567
8575
|
while (true) {
|
|
8568
8576
|
if (existsSync2(path.join(current, ".git"))) {
|
|
8569
|
-
|
|
8577
|
+
try {
|
|
8578
|
+
return realpathSync.native(current);
|
|
8579
|
+
} catch {
|
|
8580
|
+
return path.resolve(current);
|
|
8581
|
+
}
|
|
8570
8582
|
}
|
|
8571
8583
|
const parent = path.dirname(current);
|
|
8572
8584
|
if (parent === current) {
|
|
8573
|
-
return
|
|
8585
|
+
return null;
|
|
8574
8586
|
}
|
|
8575
8587
|
current = parent;
|
|
8576
8588
|
}
|
|
8577
8589
|
}
|
|
8578
|
-
function
|
|
8579
|
-
|
|
8580
|
-
|
|
8590
|
+
function hasGitDirInAncestorChain(startDirectory) {
|
|
8591
|
+
return gitRootInAncestorChain(startDirectory) !== null;
|
|
8592
|
+
}
|
|
8593
|
+
function gitRootDirectory(canonical) {
|
|
8594
|
+
const direct = gitRootInAncestorChain(canonical);
|
|
8595
|
+
if (direct)
|
|
8596
|
+
return direct;
|
|
8597
|
+
try {
|
|
8598
|
+
const realCanonical = realpathSync.native(canonical);
|
|
8599
|
+
return realCanonical === canonical ? null : gitRootInAncestorChain(realCanonical);
|
|
8600
|
+
} catch {
|
|
8601
|
+
return null;
|
|
8602
|
+
}
|
|
8603
|
+
}
|
|
8604
|
+
function resolveProjectIdentityForSession(directory, allowHomeProject = false) {
|
|
8605
|
+
const canonicalHome = canonicalUserHomeDirectory();
|
|
8606
|
+
const canonicalDirectory = (() => {
|
|
8607
|
+
try {
|
|
8608
|
+
return realpathSync.native(path.resolve(directory));
|
|
8609
|
+
} catch {
|
|
8610
|
+
return path.resolve(directory);
|
|
8611
|
+
}
|
|
8612
|
+
})();
|
|
8613
|
+
const inheritsHomeRepository = gitRootDirectory(canonicalDirectory) === canonicalHome;
|
|
8614
|
+
if (canonicalDirectory === canonicalHome || inheritsHomeRepository) {
|
|
8615
|
+
if (!allowHomeProject)
|
|
8616
|
+
return;
|
|
8617
|
+
return directoryFallback(canonicalHome);
|
|
8618
|
+
}
|
|
8581
8619
|
return resolveProjectIdentityOrFallback(directory);
|
|
8582
8620
|
}
|
|
8583
8621
|
function normalizeStoredProjectPath(rawOrStored) {
|
|
@@ -8610,9 +8648,28 @@ function scheduleAfterBootQuiet(task, additionalDelayMs = 0) {
|
|
|
8610
8648
|
return timer;
|
|
8611
8649
|
}
|
|
8612
8650
|
|
|
8651
|
+
// ../plugin/src/shared/storage-permissions.ts
|
|
8652
|
+
var enforcePrivateStoragePermissions = true;
|
|
8653
|
+
function setStoragePrivatePermissionEnforcement(enforce) {
|
|
8654
|
+
enforcePrivateStoragePermissions = enforce;
|
|
8655
|
+
}
|
|
8656
|
+
function shouldEnforcePrivateStoragePermissions() {
|
|
8657
|
+
return enforcePrivateStoragePermissions;
|
|
8658
|
+
}
|
|
8659
|
+
|
|
8613
8660
|
// ../plugin/src/features/magic-context/storage-db.ts
|
|
8614
|
-
import {
|
|
8615
|
-
|
|
8661
|
+
import {
|
|
8662
|
+
chmodSync,
|
|
8663
|
+
copyFileSync,
|
|
8664
|
+
cpSync,
|
|
8665
|
+
existsSync as existsSync4,
|
|
8666
|
+
mkdirSync as mkdirSync2,
|
|
8667
|
+
mkdtempSync,
|
|
8668
|
+
readdirSync,
|
|
8669
|
+
readFileSync as readFileSync2,
|
|
8670
|
+
unlinkSync as unlinkSync2
|
|
8671
|
+
} from "node:fs";
|
|
8672
|
+
import { basename as basename2, dirname as dirname2, join as join3 } from "node:path";
|
|
8616
8673
|
|
|
8617
8674
|
// ../plugin/src/shared/error-message.ts
|
|
8618
8675
|
function getErrorMessage(error) {
|
|
@@ -8690,6 +8747,49 @@ function safeString(value) {
|
|
|
8690
8747
|
}
|
|
8691
8748
|
}
|
|
8692
8749
|
|
|
8750
|
+
// ../plugin/src/shared/rpc-utils.ts
|
|
8751
|
+
function isPidAlive(pid) {
|
|
8752
|
+
if (!Number.isInteger(pid) || pid <= 0)
|
|
8753
|
+
return false;
|
|
8754
|
+
try {
|
|
8755
|
+
process.kill(pid, 0);
|
|
8756
|
+
return true;
|
|
8757
|
+
} catch (err) {
|
|
8758
|
+
return err.code === "EPERM";
|
|
8759
|
+
}
|
|
8760
|
+
}
|
|
8761
|
+
function parseRpcPortFile(content, fallbackPid = 0) {
|
|
8762
|
+
const trimmed = content.trim();
|
|
8763
|
+
if (!trimmed)
|
|
8764
|
+
return null;
|
|
8765
|
+
if (trimmed.startsWith("{")) {
|
|
8766
|
+
try {
|
|
8767
|
+
const parsed = JSON.parse(trimmed);
|
|
8768
|
+
const port2 = Number(parsed.port);
|
|
8769
|
+
const pid = Number(parsed.pid);
|
|
8770
|
+
const startedAt = Number(parsed.started_at);
|
|
8771
|
+
if (!isValidPort(port2) || !Number.isInteger(pid) || pid <= 0)
|
|
8772
|
+
return null;
|
|
8773
|
+
return {
|
|
8774
|
+
port: port2,
|
|
8775
|
+
pid,
|
|
8776
|
+
started_at: Number.isFinite(startedAt) ? startedAt : 0,
|
|
8777
|
+
token: typeof parsed.token === "string" ? parsed.token : undefined,
|
|
8778
|
+
instance_id: typeof parsed.instance_id === "string" ? parsed.instance_id : undefined
|
|
8779
|
+
};
|
|
8780
|
+
} catch {
|
|
8781
|
+
return null;
|
|
8782
|
+
}
|
|
8783
|
+
}
|
|
8784
|
+
const port = Number.parseInt(trimmed, 10);
|
|
8785
|
+
if (!isValidPort(port))
|
|
8786
|
+
return null;
|
|
8787
|
+
return { port, pid: fallbackPid, started_at: 0 };
|
|
8788
|
+
}
|
|
8789
|
+
function isValidPort(port) {
|
|
8790
|
+
return Number.isInteger(port) && port > 0 && port <= 65535;
|
|
8791
|
+
}
|
|
8792
|
+
|
|
8693
8793
|
// ../plugin/src/shared/sqlite.ts
|
|
8694
8794
|
var isBun = typeof process !== "undefined" && typeof process.versions?.bun === "string";
|
|
8695
8795
|
var bunSpec = "bun:" + "sqlite";
|
|
@@ -8757,30 +8857,11 @@ function buildNodeSqliteDatabaseClass(DatabaseSync) {
|
|
|
8757
8857
|
}
|
|
8758
8858
|
var Database = DatabaseImpl;
|
|
8759
8859
|
var privilegeDepth = new WeakMap;
|
|
8760
|
-
var registeredPrivilegeFunctions = new WeakSet;
|
|
8761
|
-
var privilegeUdfAvailable = new WeakSet;
|
|
8762
|
-
function registerPrivilegedWriter(db) {
|
|
8763
|
-
if (registeredPrivilegeFunctions.has(db))
|
|
8764
|
-
return;
|
|
8765
|
-
const native = db;
|
|
8766
|
-
const implementation = () => (privilegeDepth.get(db) ?? 0) > 0 ? 1 : 0;
|
|
8767
|
-
if (typeof native.function === "function") {
|
|
8768
|
-
native.function("mc_privileged_writer", implementation);
|
|
8769
|
-
} else if (typeof native.createFunction === "function") {
|
|
8770
|
-
native.createFunction("mc_privileged_writer", implementation);
|
|
8771
|
-
} else {
|
|
8772
|
-
registeredPrivilegeFunctions.add(db);
|
|
8773
|
-
return;
|
|
8774
|
-
}
|
|
8775
|
-
privilegeUdfAvailable.add(db);
|
|
8776
|
-
registeredPrivilegeFunctions.add(db);
|
|
8777
|
-
}
|
|
8778
8860
|
function isInTransaction(db) {
|
|
8779
8861
|
const candidate = db;
|
|
8780
8862
|
return candidate.inTransaction === true || candidate.isTransaction === true;
|
|
8781
8863
|
}
|
|
8782
8864
|
function withPrivilegedWriter(db, operation) {
|
|
8783
|
-
registerPrivilegedWriter(db);
|
|
8784
8865
|
const previousDepth = privilegeDepth.get(db) ?? 0;
|
|
8785
8866
|
const nested = isInTransaction(db);
|
|
8786
8867
|
const savepoint = "mc_privilege_scope";
|
|
@@ -8791,11 +8872,9 @@ function withPrivilegedWriter(db, operation) {
|
|
|
8791
8872
|
}
|
|
8792
8873
|
privilegeDepth.set(db, previousDepth + 1);
|
|
8793
8874
|
try {
|
|
8794
|
-
|
|
8795
|
-
db.prepare("INSERT INTO context_privilege_state(id, enabled) VALUES (1, 1) ON CONFLICT(id) DO UPDATE SET enabled = 1").run();
|
|
8796
|
-
}
|
|
8875
|
+
db.prepare("INSERT INTO context_privilege_state(id, enabled) VALUES (1, 1) ON CONFLICT(id) DO UPDATE SET enabled = 1").run();
|
|
8797
8876
|
const result = operation();
|
|
8798
|
-
if (
|
|
8877
|
+
if (previousDepth === 0) {
|
|
8799
8878
|
db.prepare("UPDATE context_privilege_state SET enabled = 0 WHERE id = 1").run();
|
|
8800
8879
|
}
|
|
8801
8880
|
if (nested) {
|
|
@@ -8860,6 +8939,184 @@ function ensureContextStoreUuid(db) {
|
|
|
8860
8939
|
var MAX_AUTHORITY_SEED_FRAME_BYTES = 900 * 1024;
|
|
8861
8940
|
var mirrorFlights = new WeakMap;
|
|
8862
8941
|
|
|
8942
|
+
// ../plugin/src/hooks/magic-context/compartment-parser.ts
|
|
8943
|
+
var COMPARTMENT_REGEX = /<compartment\s+([^>]*?)\s*>(.*?)<\/compartment>/gs;
|
|
8944
|
+
var ATTR_START_REGEX = /\bstart="(\d+)"/;
|
|
8945
|
+
var ATTR_END_REGEX = /\bend="(\d+)"/;
|
|
8946
|
+
var ATTR_TITLE_REGEX = /\btitle="([^"]*)"/;
|
|
8947
|
+
var ATTR_EPISODE_REGEX = /\bepisode_type="([^"]*)"/;
|
|
8948
|
+
var ATTR_IMPORTANCE_REGEX = /\bimportance="(\d+)"/;
|
|
8949
|
+
function makeTierOpenRegex(n) {
|
|
8950
|
+
return new RegExp(`<p${n}\\s*(/?)>`);
|
|
8951
|
+
}
|
|
8952
|
+
var TIER_OPEN_REGEXES = [
|
|
8953
|
+
makeTierOpenRegex(1),
|
|
8954
|
+
makeTierOpenRegex(2),
|
|
8955
|
+
makeTierOpenRegex(3),
|
|
8956
|
+
makeTierOpenRegex(4)
|
|
8957
|
+
];
|
|
8958
|
+
var TIER_CLOSE_ANY_REGEX = /<\/p\d/;
|
|
8959
|
+
var TIER_OPEN_ANY_REGEX = /<p\d/;
|
|
8960
|
+
var CATEGORY_BLOCK_REGEX = /<(PROJECT_RULES|ARCHITECTURE|CONSTRAINTS|CONFIG_VALUES|NAMING)>(.*?)<\/\1>/gs;
|
|
8961
|
+
var FACT_ITEM_REGEX = /^\s*\*\s*(.+)$/gm;
|
|
8962
|
+
var UNPROCESSED_REGEX = /<unprocessed_from>(\d+)<\/unprocessed_from>/;
|
|
8963
|
+
var USER_OBSERVATIONS_REGEX = /<user_observations>(.*?)<\/user_observations>/s;
|
|
8964
|
+
var USER_OBS_ITEM_REGEX = /^\s*\*\s*(.+)$/gm;
|
|
8965
|
+
var PRIMER_CANDIDATES_REGEX = /<primer_candidates>(.*?)<\/primer_candidates>/s;
|
|
8966
|
+
var PRIMER_ELEMENT_REGEX = /<primer\s+at_compartment="(\d+)"\s*>(.*?)<\/primer>/gs;
|
|
8967
|
+
var PRIMER_ITEM_REGEX = /^\s*(?:\*|-|\d+\.)\s*(.+)$/gm;
|
|
8968
|
+
var FACTS_BLOCK_REGEX = /<facts>(.*?)<\/facts>/s;
|
|
8969
|
+
var EVENTS_BLOCK_REGEX = /<events>(.*?)<\/events>/s;
|
|
8970
|
+
var EVENT_ELEMENT_REGEX = /<([a-z_]+)\s+at_compartment="(\d+)"\s*>(.*?)<\/\1>/gs;
|
|
8971
|
+
var EVENT_FIELD_REGEX = /<([a-z_]+)\s*>(.*?)<\/\1>/gs;
|
|
8972
|
+
function extractTier(inner, index) {
|
|
8973
|
+
const openMatch = TIER_OPEN_REGEXES[index].exec(inner);
|
|
8974
|
+
if (!openMatch)
|
|
8975
|
+
return;
|
|
8976
|
+
if (openMatch[1] === "/")
|
|
8977
|
+
return "";
|
|
8978
|
+
const rest = inner.slice(openMatch.index + openMatch[0].length);
|
|
8979
|
+
const closeAt = rest.search(TIER_CLOSE_ANY_REGEX);
|
|
8980
|
+
let body = closeAt === -1 ? rest : rest.slice(0, closeAt);
|
|
8981
|
+
const openInside = body.search(TIER_OPEN_ANY_REGEX);
|
|
8982
|
+
if (openInside !== -1)
|
|
8983
|
+
body = body.slice(0, openInside);
|
|
8984
|
+
return unescapeXml(body.trim());
|
|
8985
|
+
}
|
|
8986
|
+
function extractTiersFromInner(inner) {
|
|
8987
|
+
return {
|
|
8988
|
+
p1: extractTier(inner, 0),
|
|
8989
|
+
p2: extractTier(inner, 1),
|
|
8990
|
+
p3: extractTier(inner, 2),
|
|
8991
|
+
p4: extractTier(inner, 3)
|
|
8992
|
+
};
|
|
8993
|
+
}
|
|
8994
|
+
function parseCompartmentOutput(text) {
|
|
8995
|
+
const compartments = [];
|
|
8996
|
+
const facts = [];
|
|
8997
|
+
for (const match of text.matchAll(COMPARTMENT_REGEX)) {
|
|
8998
|
+
const attrs = match[1];
|
|
8999
|
+
const inner = match[2];
|
|
9000
|
+
const startMatch = attrs.match(ATTR_START_REGEX);
|
|
9001
|
+
const endMatch = attrs.match(ATTR_END_REGEX);
|
|
9002
|
+
const titleMatch = attrs.match(ATTR_TITLE_REGEX);
|
|
9003
|
+
if (!startMatch || !endMatch || !titleMatch)
|
|
9004
|
+
continue;
|
|
9005
|
+
const startMessage = parseInt(startMatch[1], 10);
|
|
9006
|
+
const endMessage = parseInt(endMatch[1], 10);
|
|
9007
|
+
const title = unescapeXml(titleMatch[1]);
|
|
9008
|
+
if (Number.isNaN(startMessage) || Number.isNaN(endMessage) || !title)
|
|
9009
|
+
continue;
|
|
9010
|
+
const episodeMatch = attrs.match(ATTR_EPISODE_REGEX);
|
|
9011
|
+
const importanceMatch = attrs.match(ATTR_IMPORTANCE_REGEX);
|
|
9012
|
+
const episodeType = episodeMatch ? unescapeXml(episodeMatch[1]) : undefined;
|
|
9013
|
+
const importance = importanceMatch ? parseInt(importanceMatch[1], 10) : undefined;
|
|
9014
|
+
const p1 = extractTier(inner, 0);
|
|
9015
|
+
if (typeof p1 === "string" && p1.length > 0) {
|
|
9016
|
+
const p2 = extractTier(inner, 1);
|
|
9017
|
+
const p3 = extractTier(inner, 2);
|
|
9018
|
+
const p4 = extractTier(inner, 3);
|
|
9019
|
+
compartments.push({
|
|
9020
|
+
startMessage,
|
|
9021
|
+
endMessage,
|
|
9022
|
+
title,
|
|
9023
|
+
content: p1,
|
|
9024
|
+
p1,
|
|
9025
|
+
p2: typeof p2 === "string" ? p2 : p1,
|
|
9026
|
+
p3: typeof p3 === "string" ? p3 : typeof p2 === "string" ? p2 : p1,
|
|
9027
|
+
p4: typeof p4 === "string" ? p4 : "",
|
|
9028
|
+
importance,
|
|
9029
|
+
episodeType
|
|
9030
|
+
});
|
|
9031
|
+
continue;
|
|
9032
|
+
}
|
|
9033
|
+
const content = unescapeXml(inner.trim());
|
|
9034
|
+
if (content) {
|
|
9035
|
+
compartments.push({
|
|
9036
|
+
startMessage,
|
|
9037
|
+
endMessage,
|
|
9038
|
+
title,
|
|
9039
|
+
content,
|
|
9040
|
+
importance,
|
|
9041
|
+
episodeType
|
|
9042
|
+
});
|
|
9043
|
+
}
|
|
9044
|
+
}
|
|
9045
|
+
const factsBlockMatch = text.match(FACTS_BLOCK_REGEX);
|
|
9046
|
+
const factsScope = factsBlockMatch ? factsBlockMatch[1] : text.replace(EVENTS_BLOCK_REGEX, "").replace(/<compartment\s+[^>]*?\s*>.*?<\/compartment>/gs, "");
|
|
9047
|
+
for (const categoryMatch of factsScope.matchAll(CATEGORY_BLOCK_REGEX)) {
|
|
9048
|
+
const category = categoryMatch[1];
|
|
9049
|
+
const blockContent = categoryMatch[2];
|
|
9050
|
+
for (const itemMatch of blockContent.matchAll(FACT_ITEM_REGEX)) {
|
|
9051
|
+
const content = unescapeXml(itemMatch[1].trim());
|
|
9052
|
+
if (content) {
|
|
9053
|
+
facts.push({ category, content });
|
|
9054
|
+
}
|
|
9055
|
+
}
|
|
9056
|
+
}
|
|
9057
|
+
const unprocessedMatch = text.match(UNPROCESSED_REGEX);
|
|
9058
|
+
const unprocessedFrom = unprocessedMatch ? parseInt(unprocessedMatch[1], 10) : null;
|
|
9059
|
+
const userObservations = [];
|
|
9060
|
+
const userObsMatch = text.match(USER_OBSERVATIONS_REGEX);
|
|
9061
|
+
if (userObsMatch) {
|
|
9062
|
+
for (const itemMatch of userObsMatch[1].matchAll(USER_OBS_ITEM_REGEX)) {
|
|
9063
|
+
const obs = unescapeXml(itemMatch[1].trim());
|
|
9064
|
+
if (obs)
|
|
9065
|
+
userObservations.push(obs);
|
|
9066
|
+
}
|
|
9067
|
+
}
|
|
9068
|
+
const primerCandidates = [];
|
|
9069
|
+
const primerMatch = text.match(PRIMER_CANDIDATES_REGEX);
|
|
9070
|
+
if (primerMatch) {
|
|
9071
|
+
const block = primerMatch[1];
|
|
9072
|
+
let sawElement = false;
|
|
9073
|
+
for (const el of block.matchAll(PRIMER_ELEMENT_REGEX)) {
|
|
9074
|
+
sawElement = true;
|
|
9075
|
+
const question = unescapeXml(el[2].trim());
|
|
9076
|
+
if (question) {
|
|
9077
|
+
primerCandidates.push({
|
|
9078
|
+
question,
|
|
9079
|
+
originCompartmentIndex: Number.parseInt(el[1], 10)
|
|
9080
|
+
});
|
|
9081
|
+
}
|
|
9082
|
+
}
|
|
9083
|
+
if (!sawElement) {
|
|
9084
|
+
for (const itemMatch of block.matchAll(PRIMER_ITEM_REGEX)) {
|
|
9085
|
+
const question = unescapeXml(itemMatch[1].trim());
|
|
9086
|
+
if (question)
|
|
9087
|
+
primerCandidates.push({ question });
|
|
9088
|
+
}
|
|
9089
|
+
}
|
|
9090
|
+
}
|
|
9091
|
+
const events = parseEvents(text);
|
|
9092
|
+
compartments.sort((a, b) => a.startMessage - b.startMessage);
|
|
9093
|
+
return { compartments, facts, events, unprocessedFrom, userObservations, primerCandidates };
|
|
9094
|
+
}
|
|
9095
|
+
function parseEvents(text) {
|
|
9096
|
+
const blockMatch = text.match(EVENTS_BLOCK_REGEX);
|
|
9097
|
+
if (!blockMatch)
|
|
9098
|
+
return [];
|
|
9099
|
+
const block = blockMatch[1];
|
|
9100
|
+
const events = [];
|
|
9101
|
+
for (const elMatch of block.matchAll(EVENT_ELEMENT_REGEX)) {
|
|
9102
|
+
const kind = elMatch[1];
|
|
9103
|
+
const atRaw = parseInt(elMatch[2], 10);
|
|
9104
|
+
const atCompartment = Number.isNaN(atRaw) ? null : atRaw;
|
|
9105
|
+
const fields = {};
|
|
9106
|
+
for (const fieldMatch of elMatch[3].matchAll(EVENT_FIELD_REGEX)) {
|
|
9107
|
+
const name = fieldMatch[1];
|
|
9108
|
+
const value = unescapeXml(fieldMatch[2].trim());
|
|
9109
|
+
if (value)
|
|
9110
|
+
fields[name] = value;
|
|
9111
|
+
}
|
|
9112
|
+
events.push({ kind, atCompartment, fields });
|
|
9113
|
+
}
|
|
9114
|
+
return events;
|
|
9115
|
+
}
|
|
9116
|
+
function unescapeXml(s) {
|
|
9117
|
+
return s.replace(/&/g, "&").replace(/'/g, "'").replace(/"/g, '"').replace(/</g, "<").replace(/>/g, ">");
|
|
9118
|
+
}
|
|
9119
|
+
|
|
8863
9120
|
// ../plugin/src/features/magic-context/storage-schema-helpers.ts
|
|
8864
9121
|
function ensureColumn(db, table, column, definition) {
|
|
8865
9122
|
if (!/^[a-z][a-z0-9_]*$/.test(table) || !/^[a-z][a-z0-9_]*$/.test(column) || !/^[A-Z0-9_"'(),[\]\s]+$/i.test(definition)) {
|
|
@@ -9285,15 +9542,38 @@ function isSqliteLockError(error) {
|
|
|
9285
9542
|
function tableExists2(db, name) {
|
|
9286
9543
|
return Boolean(db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name = ?").get(name));
|
|
9287
9544
|
}
|
|
9545
|
+
function healMismatchedTierClose(db, table, hasLegacy) {
|
|
9546
|
+
if (!tableExists2(db, table))
|
|
9547
|
+
return;
|
|
9548
|
+
const columns = new Set(db.prepare(`PRAGMA table_info(${table})`).all().map((row) => row.name));
|
|
9549
|
+
for (const required of ["content", "p1", "p2", "p3", "p4"]) {
|
|
9550
|
+
if (!columns.has(required))
|
|
9551
|
+
return;
|
|
9552
|
+
}
|
|
9553
|
+
if (hasLegacy && !columns.has("legacy"))
|
|
9554
|
+
return;
|
|
9555
|
+
const predicate = hasLegacy ? "legacy = 1 AND p1 IS NULL AND content LIKE '%<p1%'" : "p1 IS NULL AND content LIKE '%<p1%'";
|
|
9556
|
+
const rows = db.prepare(`SELECT id, content FROM ${table} WHERE ${predicate}`).all();
|
|
9557
|
+
const update = db.prepare(`UPDATE ${table} SET p1 = ?, p2 = ?, p3 = ?, p4 = ?${hasLegacy ? ", legacy = 0" : ""} WHERE id = ?`);
|
|
9558
|
+
for (const row of rows) {
|
|
9559
|
+
const tiers = extractTiersFromInner(row.content);
|
|
9560
|
+
if (typeof tiers.p1 !== "string" || tiers.p1.length === 0)
|
|
9561
|
+
continue;
|
|
9562
|
+
const p1 = tiers.p1;
|
|
9563
|
+
const p2 = typeof tiers.p2 === "string" ? tiers.p2 : p1;
|
|
9564
|
+
const p3 = typeof tiers.p3 === "string" ? tiers.p3 : p2;
|
|
9565
|
+
const p4 = typeof tiers.p4 === "string" ? tiers.p4 : "";
|
|
9566
|
+
update.run(p1, p2, p3, p4, row.id);
|
|
9567
|
+
}
|
|
9568
|
+
}
|
|
9288
9569
|
function assertForeignKeyIntegrity(db, table) {
|
|
9289
9570
|
const rows = (table ? db.prepare(`PRAGMA foreign_key_check(${table})`) : db.prepare("PRAGMA foreign_key_check")).all();
|
|
9290
9571
|
if (rows.length > 0) {
|
|
9291
9572
|
throw new Error(`foreign_key_check failed after embedding table rebuild${table ? ` (${table})` : ""} (${rows.length} violation(s))`);
|
|
9292
9573
|
}
|
|
9293
9574
|
}
|
|
9294
|
-
function authorityPrivilegeCheck(
|
|
9295
|
-
|
|
9296
|
-
return typeof native.function === "function" || typeof native.createFunction === "function" ? "mc_privileged_writer() = 0" : "COALESCE((SELECT enabled FROM context_privilege_state WHERE id = 1), 0) = 0";
|
|
9575
|
+
function authorityPrivilegeCheck() {
|
|
9576
|
+
return "COALESCE((SELECT enabled FROM context_privilege_state WHERE id = 1), 0) = 0";
|
|
9297
9577
|
}
|
|
9298
9578
|
function managedAuthorityNoteRow(row) {
|
|
9299
9579
|
return `(
|
|
@@ -9312,7 +9592,7 @@ function managedAuthorityNoteRow(row) {
|
|
|
9312
9592
|
)`;
|
|
9313
9593
|
}
|
|
9314
9594
|
function installLatestAuthorityTriggers(db) {
|
|
9315
|
-
const privilegeCheck = authorityPrivilegeCheck(
|
|
9595
|
+
const privilegeCheck = authorityPrivilegeCheck();
|
|
9316
9596
|
if (tableExists2(db, "memories")) {
|
|
9317
9597
|
db.exec(`
|
|
9318
9598
|
DROP TRIGGER IF EXISTS memories_authority_guard_insert;
|
|
@@ -11238,6 +11518,48 @@ var MIGRATIONS = [
|
|
|
11238
11518
|
ON memory_mutation_log(project_path, target_memory_id, id);
|
|
11239
11519
|
`);
|
|
11240
11520
|
}
|
|
11521
|
+
},
|
|
11522
|
+
{
|
|
11523
|
+
version: 70,
|
|
11524
|
+
description: "heal legacy compartments stranded by mismatched tier closing tags (issue #246)",
|
|
11525
|
+
up(db) {
|
|
11526
|
+
healMismatchedTierClose(db, "compartments", true);
|
|
11527
|
+
healMismatchedTierClose(db, "recomp_compartments", false);
|
|
11528
|
+
}
|
|
11529
|
+
},
|
|
11530
|
+
{
|
|
11531
|
+
version: 71,
|
|
11532
|
+
description: "rebuild authority guard triggers to the durable state-table form (issue #253)",
|
|
11533
|
+
up(db) {
|
|
11534
|
+
installLatestAuthorityTriggers(db);
|
|
11535
|
+
}
|
|
11536
|
+
},
|
|
11537
|
+
{
|
|
11538
|
+
version: 72,
|
|
11539
|
+
description: "add per-session compaction mode record column (issue #266)",
|
|
11540
|
+
up(db) {
|
|
11541
|
+
if (tableExists2(db, "session_meta")) {
|
|
11542
|
+
ensureColumn(db, "session_meta", "compaction_mode_record", "TEXT");
|
|
11543
|
+
}
|
|
11544
|
+
}
|
|
11545
|
+
},
|
|
11546
|
+
{
|
|
11547
|
+
version: 73,
|
|
11548
|
+
description: "persist the last successful todowrite permission verdict",
|
|
11549
|
+
up(db) {
|
|
11550
|
+
if (tableExists2(db, "session_meta")) {
|
|
11551
|
+
ensureColumn(db, "session_meta", "todo_permission_denied", "INTEGER NOT NULL DEFAULT 2");
|
|
11552
|
+
}
|
|
11553
|
+
}
|
|
11554
|
+
},
|
|
11555
|
+
{
|
|
11556
|
+
version: 74,
|
|
11557
|
+
description: "persist detected context-limit provenance",
|
|
11558
|
+
up(db) {
|
|
11559
|
+
if (tableExists2(db, "session_meta")) {
|
|
11560
|
+
ensureColumn(db, "session_meta", "detected_context_limit_provenance", "TEXT NOT NULL DEFAULT 'unknown'");
|
|
11561
|
+
}
|
|
11562
|
+
}
|
|
11241
11563
|
}
|
|
11242
11564
|
];
|
|
11243
11565
|
var LATEST_MIGRATION_VERSION = MIGRATIONS.reduce((max, m) => Math.max(max, m.version), 0);
|
|
@@ -144263,30 +144585,40 @@ var persistenceByDatabase = new WeakMap;
|
|
|
144263
144585
|
var persistenceErrorByDatabase = new WeakMap;
|
|
144264
144586
|
var pathByDatabase = new WeakMap;
|
|
144265
144587
|
var lastSchemaFenceRejection = null;
|
|
144588
|
+
var lastMigrationOnOpenRefusal = null;
|
|
144266
144589
|
function getSchemaFenceRejection() {
|
|
144267
144590
|
return lastSchemaFenceRejection;
|
|
144268
144591
|
}
|
|
144269
|
-
|
|
144592
|
+
function getMigrationOnOpenRefusal() {
|
|
144593
|
+
return lastMigrationOnOpenRefusal;
|
|
144594
|
+
}
|
|
144595
|
+
var LATEST_SUPPORTED_VERSION = 74;
|
|
144270
144596
|
var PERMISSIONS_ENFORCEABLE = process.platform !== "win32";
|
|
144597
|
+
var defaultStoragePermissionFs = { chmodSync, mkdirSync: mkdirSync2 };
|
|
144598
|
+
var storagePermissionFs = defaultStoragePermissionFs;
|
|
144271
144599
|
function ensureSecureStorageDir(dir) {
|
|
144272
|
-
|
|
144600
|
+
if (!shouldEnforcePrivateStoragePermissions()) {
|
|
144601
|
+
storagePermissionFs.mkdirSync(dir, { recursive: true });
|
|
144602
|
+
return;
|
|
144603
|
+
}
|
|
144604
|
+
storagePermissionFs.mkdirSync(dir, { recursive: true, mode: 448 });
|
|
144273
144605
|
if (!PERMISSIONS_ENFORCEABLE)
|
|
144274
144606
|
return;
|
|
144275
144607
|
try {
|
|
144276
|
-
chmodSync(dir, 448);
|
|
144608
|
+
storagePermissionFs.chmodSync(dir, 448);
|
|
144277
144609
|
} catch (error) {
|
|
144278
144610
|
log(`[magic-context] could not restrict storage dir permissions on ${dir}: ${getErrorMessage(error)}`);
|
|
144279
144611
|
}
|
|
144280
144612
|
}
|
|
144281
144613
|
function restrictDatabaseFilePermissions(dbPath) {
|
|
144282
|
-
if (!PERMISSIONS_ENFORCEABLE)
|
|
144614
|
+
if (!PERMISSIONS_ENFORCEABLE || !shouldEnforcePrivateStoragePermissions())
|
|
144283
144615
|
return;
|
|
144284
144616
|
for (const suffix of ["", "-wal", "-shm"]) {
|
|
144285
144617
|
const file = `${dbPath}${suffix}`;
|
|
144286
144618
|
if (!existsSync4(file))
|
|
144287
144619
|
continue;
|
|
144288
144620
|
try {
|
|
144289
|
-
chmodSync(file, 384);
|
|
144621
|
+
storagePermissionFs.chmodSync(file, 384);
|
|
144290
144622
|
} catch (error) {
|
|
144291
144623
|
log(`[magic-context] could not restrict DB file permissions on ${file}: ${getErrorMessage(error)}`);
|
|
144292
144624
|
}
|
|
@@ -144356,6 +144688,9 @@ function getPersistedSchemaVersion(db) {
|
|
|
144356
144688
|
const row = db.prepare("SELECT MAX(version) AS version FROM schema_migrations").get();
|
|
144357
144689
|
return row?.version ?? 0;
|
|
144358
144690
|
}
|
|
144691
|
+
function formatSchemaFenceBootLog(persistedVersion, supportedVersion) {
|
|
144692
|
+
return `[magic-context] storage schema at boot: database=v${persistedVersion}, supported_fence=v${supportedVersion}`;
|
|
144693
|
+
}
|
|
144359
144694
|
function getRuntimeLatestSupportedVersion(options) {
|
|
144360
144695
|
if (options?.latestSupportedVersion !== undefined) {
|
|
144361
144696
|
return options.latestSupportedVersion;
|
|
@@ -144372,12 +144707,109 @@ function getRuntimeLatestSupportedVersion(options) {
|
|
|
144372
144707
|
function enforceSchemaFence(db, dbPath, latestSupportedVersion) {
|
|
144373
144708
|
const persistedVersion = getPersistedSchemaVersion(db);
|
|
144374
144709
|
if (persistedVersion <= latestSupportedVersion) {
|
|
144710
|
+
lastSchemaFenceRejection = null;
|
|
144375
144711
|
return true;
|
|
144376
144712
|
}
|
|
144377
144713
|
lastSchemaFenceRejection = { persistedVersion, supportedVersion: latestSupportedVersion };
|
|
144378
144714
|
log(`[magic-context] storage fatal: refusing to open ${dbPath}; database schema v${persistedVersion} is newer than this binary supports (max v${latestSupportedVersion}). A pinned or stale plugin is likely sharing this database with a newer instance; update or unpin Magic Context with 'npx @cortexkit/magic-context@latest doctor --force', then restart.`);
|
|
144379
144715
|
return false;
|
|
144380
144716
|
}
|
|
144717
|
+
function unreadableDiscovery(path2) {
|
|
144718
|
+
return {
|
|
144719
|
+
state: "unreadable",
|
|
144720
|
+
serverPids: [],
|
|
144721
|
+
staleFiles: [],
|
|
144722
|
+
unreadableFile: path2
|
|
144723
|
+
};
|
|
144724
|
+
}
|
|
144725
|
+
function inspectRpcServerDiscovery(storageDir) {
|
|
144726
|
+
const rpcRoot = join3(storageDir, "rpc");
|
|
144727
|
+
let projectEntries;
|
|
144728
|
+
try {
|
|
144729
|
+
projectEntries = readdirSync(rpcRoot, { withFileTypes: true });
|
|
144730
|
+
} catch (error) {
|
|
144731
|
+
if (error.code === "ENOENT") {
|
|
144732
|
+
return { state: "absent", serverPids: [], staleFiles: [] };
|
|
144733
|
+
}
|
|
144734
|
+
return unreadableDiscovery(rpcRoot);
|
|
144735
|
+
}
|
|
144736
|
+
const portFiles = [];
|
|
144737
|
+
for (const projectEntry of projectEntries) {
|
|
144738
|
+
if (!projectEntry.isDirectory())
|
|
144739
|
+
continue;
|
|
144740
|
+
const projectDir = join3(rpcRoot, projectEntry.name);
|
|
144741
|
+
let entries;
|
|
144742
|
+
try {
|
|
144743
|
+
entries = readdirSync(projectDir);
|
|
144744
|
+
} catch {
|
|
144745
|
+
return unreadableDiscovery(projectDir);
|
|
144746
|
+
}
|
|
144747
|
+
for (const entry of entries) {
|
|
144748
|
+
if (entry === "port" || entry.startsWith("port-") && entry.endsWith(".json")) {
|
|
144749
|
+
portFiles.push(join3(projectDir, entry));
|
|
144750
|
+
}
|
|
144751
|
+
}
|
|
144752
|
+
}
|
|
144753
|
+
if (portFiles.length === 0) {
|
|
144754
|
+
return { state: "absent", serverPids: [], staleFiles: [] };
|
|
144755
|
+
}
|
|
144756
|
+
const pids = new Set;
|
|
144757
|
+
const staleFiles = [];
|
|
144758
|
+
for (const portFile of portFiles) {
|
|
144759
|
+
let raw;
|
|
144760
|
+
try {
|
|
144761
|
+
raw = readFileSync2(portFile, "utf8");
|
|
144762
|
+
} catch {
|
|
144763
|
+
return unreadableDiscovery(portFile);
|
|
144764
|
+
}
|
|
144765
|
+
const filename = basename2(portFile);
|
|
144766
|
+
const pidFromName = /^port-(\d+)/.exec(filename)?.[1];
|
|
144767
|
+
const record = parseRpcPortFile(raw, pidFromName ? Number(pidFromName) : 0);
|
|
144768
|
+
if (!record || !Number.isInteger(record.pid) || record.pid <= 0) {
|
|
144769
|
+
return unreadableDiscovery(portFile);
|
|
144770
|
+
}
|
|
144771
|
+
if (isPidAlive(record.pid))
|
|
144772
|
+
pids.add(record.pid);
|
|
144773
|
+
else
|
|
144774
|
+
staleFiles.push(portFile);
|
|
144775
|
+
}
|
|
144776
|
+
const serverPids = [...pids].sort((a, b) => a - b);
|
|
144777
|
+
if (serverPids.length > 0) {
|
|
144778
|
+
return { state: "live", serverPids, staleFiles };
|
|
144779
|
+
}
|
|
144780
|
+
for (const staleFile of staleFiles) {
|
|
144781
|
+
try {
|
|
144782
|
+
unlinkSync2(staleFile);
|
|
144783
|
+
} catch {
|
|
144784
|
+
return unreadableDiscovery(staleFile);
|
|
144785
|
+
}
|
|
144786
|
+
}
|
|
144787
|
+
return { state: "stale", serverPids: [], staleFiles };
|
|
144788
|
+
}
|
|
144789
|
+
function enforceMigrationOnOpenGuard(db, dbPath, dbDir, latestSupportedVersion) {
|
|
144790
|
+
const persistedVersion = getPersistedSchemaVersion(db);
|
|
144791
|
+
if (persistedVersion >= latestSupportedVersion) {
|
|
144792
|
+
lastMigrationOnOpenRefusal = null;
|
|
144793
|
+
return true;
|
|
144794
|
+
}
|
|
144795
|
+
const discovery = inspectRpcServerDiscovery(dbDir);
|
|
144796
|
+
if (discovery.state === "absent" || discovery.state === "stale") {
|
|
144797
|
+
lastMigrationOnOpenRefusal = null;
|
|
144798
|
+
return true;
|
|
144799
|
+
}
|
|
144800
|
+
lastMigrationOnOpenRefusal = {
|
|
144801
|
+
persistedVersion,
|
|
144802
|
+
supportedVersion: latestSupportedVersion,
|
|
144803
|
+
serverPids: discovery.serverPids,
|
|
144804
|
+
...discovery.unreadableFile ? { unreadableFile: discovery.unreadableFile } : {}
|
|
144805
|
+
};
|
|
144806
|
+
if (discovery.state === "unreadable") {
|
|
144807
|
+
log(`[magic-context] storage fatal: refusing to migrate ${dbPath} from schema v${persistedVersion} to v${latestSupportedVersion} because RPC discovery file ${discovery.unreadableFile ?? "<unknown>"} is unreadable or invalid, so the absence of a live OpenCode server cannot be proven. Restart OpenCode, remove or repair the named discovery file, then retry this process.`);
|
|
144808
|
+
} else {
|
|
144809
|
+
log(`[magic-context] storage fatal: refusing to migrate ${dbPath} from schema v${persistedVersion} to v${latestSupportedVersion} while live OpenCode server PID(s) ${discovery.serverPids.join(", ")} may still use the old plugin build. Restart OpenCode, then retry this process.`);
|
|
144810
|
+
}
|
|
144811
|
+
return false;
|
|
144812
|
+
}
|
|
144381
144813
|
var sqlitePragmaConfig = {
|
|
144382
144814
|
cacheSizeMb: 64,
|
|
144383
144815
|
mmapSizeMb: 0
|
|
@@ -144422,6 +144854,9 @@ function finishDatabaseOpen(db, dbPath, explicitDbPath, latestSupportedVersion)
|
|
|
144422
144854
|
pathByDatabase.set(db, dbPath);
|
|
144423
144855
|
persistenceByDatabase.set(db, true);
|
|
144424
144856
|
persistenceErrorByDatabase.delete(db);
|
|
144857
|
+
if (!explicitDbPath) {
|
|
144858
|
+
log(formatSchemaFenceBootLog(getPersistedSchemaVersion(db), latestSupportedVersion));
|
|
144859
|
+
}
|
|
144425
144860
|
return db;
|
|
144426
144861
|
}
|
|
144427
144862
|
function initializeDatabase(db) {
|
|
@@ -145022,12 +145457,14 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
145022
145457
|
note_nudge_anchors TEXT NOT NULL DEFAULT '[]',
|
|
145023
145458
|
auto_search_hint_decisions TEXT NOT NULL DEFAULT '[]',
|
|
145024
145459
|
last_todo_state TEXT DEFAULT '',
|
|
145460
|
+
todo_permission_denied INTEGER NOT NULL DEFAULT 2,
|
|
145025
145461
|
todo_synthetic_call_id TEXT DEFAULT '',
|
|
145026
145462
|
todo_synthetic_anchor_message_id TEXT DEFAULT '',
|
|
145027
145463
|
todo_synthetic_state_json TEXT DEFAULT '',
|
|
145028
145464
|
is_subagent INTEGER DEFAULT 0,
|
|
145029
145465
|
last_context_percentage REAL DEFAULT 0,
|
|
145030
145466
|
last_input_tokens INTEGER DEFAULT 0,
|
|
145467
|
+
detected_context_limit_provenance TEXT NOT NULL DEFAULT 'unknown',
|
|
145031
145468
|
observed_safe_input_tokens INTEGER NOT NULL DEFAULT 0,
|
|
145032
145469
|
cache_alert_sent INTEGER NOT NULL DEFAULT 0,
|
|
145033
145470
|
times_execute_threshold_reached INTEGER DEFAULT 0,
|
|
@@ -145082,6 +145519,7 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
145082
145519
|
emergency_drain_active INTEGER NOT NULL DEFAULT 0,
|
|
145083
145520
|
historian_drain_failure_at INTEGER NOT NULL DEFAULT 0,
|
|
145084
145521
|
wrapup_in_progress_state TEXT,
|
|
145522
|
+
compaction_mode_record TEXT,
|
|
145085
145523
|
cached_m0_materialized_at INTEGER,
|
|
145086
145524
|
cached_m0_session_facts_version INTEGER,
|
|
145087
145525
|
cached_m0_upgrade_state TEXT,
|
|
@@ -145281,6 +145719,7 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
145281
145719
|
ensureColumn(db, "session_meta", "note_nudge_anchors", "TEXT NOT NULL DEFAULT '[]'");
|
|
145282
145720
|
ensureColumn(db, "session_meta", "auto_search_hint_decisions", "TEXT NOT NULL DEFAULT '[]'");
|
|
145283
145721
|
ensureColumn(db, "session_meta", "last_todo_state", "TEXT DEFAULT ''");
|
|
145722
|
+
ensureColumn(db, "session_meta", "todo_permission_denied", "INTEGER NOT NULL DEFAULT 2");
|
|
145284
145723
|
ensureColumn(db, "session_meta", "todo_synthetic_call_id", "TEXT DEFAULT ''");
|
|
145285
145724
|
ensureColumn(db, "session_meta", "todo_synthetic_anchor_message_id", "TEXT DEFAULT ''");
|
|
145286
145725
|
ensureColumn(db, "session_meta", "todo_synthetic_state_json", "TEXT DEFAULT ''");
|
|
@@ -145337,6 +145776,7 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
145337
145776
|
ensureColumn(db, "session_meta", "recomp_partial_range_end", "INTEGER DEFAULT 0");
|
|
145338
145777
|
ensureColumn(db, "session_meta", "detected_context_limit", "INTEGER DEFAULT 0");
|
|
145339
145778
|
ensureColumn(db, "session_meta", "detected_context_limit_model_key", "TEXT");
|
|
145779
|
+
ensureColumn(db, "session_meta", "detected_context_limit_provenance", "TEXT NOT NULL DEFAULT 'unknown'");
|
|
145340
145780
|
ensureColumn(db, "session_meta", "needs_emergency_recovery", "INTEGER DEFAULT 0");
|
|
145341
145781
|
ensureColumn(db, "session_meta", "emergency_recovery_origin", "TEXT DEFAULT ''");
|
|
145342
145782
|
ensureColumn(db, "session_meta", "pending_compaction_marker_state", "TEXT");
|
|
@@ -145387,6 +145827,7 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
145387
145827
|
ensureColumn(db, "session_meta", "emergency_drain_active", "INTEGER NOT NULL DEFAULT 0");
|
|
145388
145828
|
ensureColumn(db, "session_meta", "historian_drain_failure_at", "INTEGER NOT NULL DEFAULT 0");
|
|
145389
145829
|
ensureColumn(db, "session_meta", "wrapup_in_progress_state", "TEXT");
|
|
145830
|
+
ensureColumn(db, "session_meta", "compaction_mode_record", "TEXT");
|
|
145390
145831
|
ensureColumn(db, "session_meta", "cached_m0_materialized_at", "INTEGER");
|
|
145391
145832
|
ensureColumn(db, "session_meta", "cached_m0_session_facts_version", "INTEGER");
|
|
145392
145833
|
ensureColumn(db, "session_meta", "cached_m0_upgrade_state", "TEXT");
|
|
@@ -145526,12 +145967,13 @@ function openDatabase(dbPathOrOptions) {
|
|
|
145526
145967
|
const explicitDbPath = options?.dbPath !== undefined;
|
|
145527
145968
|
const { dbDir, dbPath } = resolveDatabasePath(options?.dbPath);
|
|
145528
145969
|
const latestSupportedVersion = getRuntimeLatestSupportedVersion(options);
|
|
145970
|
+
lastSchemaFenceRejection = null;
|
|
145971
|
+
lastMigrationOnOpenRefusal = null;
|
|
145529
145972
|
const existing = databases.get(dbPath);
|
|
145530
145973
|
if (existing) {
|
|
145531
145974
|
if (!enforceSchemaFence(existing, dbPath, latestSupportedVersion)) {
|
|
145532
145975
|
return null;
|
|
145533
145976
|
}
|
|
145534
|
-
registerPrivilegedWriter(existing);
|
|
145535
145977
|
if (!persistenceByDatabase.has(existing)) {
|
|
145536
145978
|
persistenceByDatabase.set(existing, true);
|
|
145537
145979
|
}
|
|
@@ -145544,11 +145986,14 @@ function openDatabase(dbPathOrOptions) {
|
|
|
145544
145986
|
}
|
|
145545
145987
|
ensureSecureStorageDir(dbDir);
|
|
145546
145988
|
const db = new Database(dbPath);
|
|
145547
|
-
registerPrivilegedWriter(db);
|
|
145548
145989
|
if (!enforceSchemaFence(db, dbPath, latestSupportedVersion)) {
|
|
145549
145990
|
closeQuietly(db);
|
|
145550
145991
|
return null;
|
|
145551
145992
|
}
|
|
145993
|
+
if (!enforceMigrationOnOpenGuard(db, dbPath, dbDir, latestSupportedVersion)) {
|
|
145994
|
+
closeQuietly(db);
|
|
145995
|
+
return null;
|
|
145996
|
+
}
|
|
145552
145997
|
initializeDatabase(db);
|
|
145553
145998
|
runMigrations(db);
|
|
145554
145999
|
ensureContextStoreUuid(db);
|
|
@@ -145564,6 +146009,8 @@ async function openDatabaseAsync(dbPathOrOptions) {
|
|
|
145564
146009
|
const explicitDbPath = options?.dbPath !== undefined;
|
|
145565
146010
|
const { dbDir, dbPath } = resolveDatabasePath(options?.dbPath);
|
|
145566
146011
|
const latestSupportedVersion = getRuntimeLatestSupportedVersion(options);
|
|
146012
|
+
lastSchemaFenceRejection = null;
|
|
146013
|
+
lastMigrationOnOpenRefusal = null;
|
|
145567
146014
|
const existing = databases.get(dbPath);
|
|
145568
146015
|
if (existing) {
|
|
145569
146016
|
if (!enforceSchemaFence(existing, dbPath, latestSupportedVersion))
|
|
@@ -145583,11 +146030,14 @@ async function openDatabaseAsync(dbPathOrOptions) {
|
|
|
145583
146030
|
migrateLegacyStorageIfNeeded(dbPath, dbDir);
|
|
145584
146031
|
ensureSecureStorageDir(dbDir);
|
|
145585
146032
|
db = new Database(dbPath);
|
|
145586
|
-
registerPrivilegedWriter(db);
|
|
145587
146033
|
if (!enforceSchemaFence(db, dbPath, latestSupportedVersion)) {
|
|
145588
146034
|
closeQuietly(db);
|
|
145589
146035
|
return null;
|
|
145590
146036
|
}
|
|
146037
|
+
if (!enforceMigrationOnOpenGuard(db, dbPath, dbDir, latestSupportedVersion)) {
|
|
146038
|
+
closeQuietly(db);
|
|
146039
|
+
return null;
|
|
146040
|
+
}
|
|
145591
146041
|
initializeDatabase(db);
|
|
145592
146042
|
await runMigrationsWithRetry(db);
|
|
145593
146043
|
ensureContextStoreUuid(db);
|
|
@@ -145609,6 +146059,24 @@ async function openDatabaseAsync(dbPathOrOptions) {
|
|
|
145609
146059
|
}
|
|
145610
146060
|
}
|
|
145611
146061
|
|
|
146062
|
+
// ../plugin/src/shared/context-limit-provenance.ts
|
|
146063
|
+
function normalizeContextLimitProvenance(value) {
|
|
146064
|
+
if (value === "prompt_only" || value === "combined")
|
|
146065
|
+
return value;
|
|
146066
|
+
return "unknown";
|
|
146067
|
+
}
|
|
146068
|
+
|
|
146069
|
+
// ../plugin/src/shared/escalation-bands.ts
|
|
146070
|
+
var MAX_EXECUTE_THRESHOLD = 90;
|
|
146071
|
+
var ABSOLUTE_EMERGENCY_PERCENTAGE = 95;
|
|
146072
|
+
function escalationBands(effectiveThresholdPercentage) {
|
|
146073
|
+
const threshold = Number.isFinite(effectiveThresholdPercentage) ? Math.min(effectiveThresholdPercentage, MAX_EXECUTE_THRESHOLD) : 65;
|
|
146074
|
+
return {
|
|
146075
|
+
forceMaterializationPercentage: Math.max(85, threshold + 2),
|
|
146076
|
+
emergencyPercentage: ABSOLUTE_EMERGENCY_PERCENTAGE
|
|
146077
|
+
};
|
|
146078
|
+
}
|
|
146079
|
+
|
|
145612
146080
|
// ../plugin/src/features/magic-context/storage-meta-shared.ts
|
|
145613
146081
|
import { Buffer as Buffer2 } from "node:buffer";
|
|
145614
146082
|
var SESSION_META_SELECT_COLUMNS = [
|
|
@@ -146248,6 +146716,45 @@ function releaseWrapupInProgress(db, sessionId, holderId) {
|
|
|
146248
146716
|
}
|
|
146249
146717
|
}
|
|
146250
146718
|
}
|
|
146719
|
+
var COMPACTION_MODE_RECORD_VALUES = new Set([
|
|
146720
|
+
"on",
|
|
146721
|
+
"off",
|
|
146722
|
+
"on_notice_pending",
|
|
146723
|
+
"off_notice_pending",
|
|
146724
|
+
"off_cleanup_pending"
|
|
146725
|
+
]);
|
|
146726
|
+
function normalizeCompactionModeRecord(value) {
|
|
146727
|
+
if (value === null || value === undefined)
|
|
146728
|
+
return null;
|
|
146729
|
+
if (typeof value === "string" && COMPACTION_MODE_RECORD_VALUES.has(value)) {
|
|
146730
|
+
return value;
|
|
146731
|
+
}
|
|
146732
|
+
return null;
|
|
146733
|
+
}
|
|
146734
|
+
function resolveCompactionModeRecord(record) {
|
|
146735
|
+
switch (record) {
|
|
146736
|
+
case "on":
|
|
146737
|
+
case "on_notice_pending":
|
|
146738
|
+
return "on";
|
|
146739
|
+
case "off":
|
|
146740
|
+
case "off_notice_pending":
|
|
146741
|
+
case "off_cleanup_pending":
|
|
146742
|
+
return "off";
|
|
146743
|
+
default:
|
|
146744
|
+
return null;
|
|
146745
|
+
}
|
|
146746
|
+
}
|
|
146747
|
+
function getCompactionModeRecord(db, sessionId) {
|
|
146748
|
+
const row = db.prepare("SELECT compaction_mode_record FROM session_meta WHERE session_id = ?").get(sessionId);
|
|
146749
|
+
return normalizeCompactionModeRecord(row?.compaction_mode_record);
|
|
146750
|
+
}
|
|
146751
|
+
function setCompactionModeRecord(db, sessionId, value) {
|
|
146752
|
+
if (value !== null && !COMPACTION_MODE_RECORD_VALUES.has(value)) {
|
|
146753
|
+
throw new Error(`Invalid compaction_mode_record value: ${String(value)} (expected a supported compaction mode record or null)`);
|
|
146754
|
+
}
|
|
146755
|
+
ensureSessionMetaRow(db, sessionId);
|
|
146756
|
+
db.prepare("UPDATE session_meta SET compaction_mode_record = ? WHERE session_id = ?").run(value, sessionId);
|
|
146757
|
+
}
|
|
146251
146758
|
function protectedTailWindowBudget(usagePercentage, usable, perRunCap) {
|
|
146252
146759
|
if (usagePercentage >= 95)
|
|
146253
146760
|
return Math.min(1e6, Math.max(4 * perRunCap, Math.round(0.5 * usable)));
|
|
@@ -146255,7 +146762,6 @@ function protectedTailWindowBudget(usagePercentage, usable, perRunCap) {
|
|
|
146255
146762
|
return Math.min(750000, Math.max(3 * perRunCap, Math.round(0.35 * usable)));
|
|
146256
146763
|
return Math.min(500000, Math.max(perRunCap, Math.round(0.2 * usable)));
|
|
146257
146764
|
}
|
|
146258
|
-
var EMERGENCY_DRAIN_ENTER_PERCENTAGE = 95;
|
|
146259
146765
|
var EMERGENCY_DRAIN_EXIT_MARGIN = 10;
|
|
146260
146766
|
var EMERGENCY_DRAIN_FALLBACK_EXIT_PERCENTAGE = 55;
|
|
146261
146767
|
var EMERGENCY_DRAIN_FAILURE_BACKOFF_MS = 60000;
|
|
@@ -146290,7 +146796,8 @@ function reserveProtectedTailDrainTokens(args) {
|
|
|
146290
146796
|
}
|
|
146291
146797
|
const exitThreshold = emergencyDrainExitThreshold(args.executeThresholdPercentage);
|
|
146292
146798
|
let latchActiveSince = meta.emergencyDrainActive;
|
|
146293
|
-
|
|
146799
|
+
const { forceMaterializationPercentage } = escalationBands(args.executeThresholdPercentage);
|
|
146800
|
+
if (args.usagePercentage >= forceMaterializationPercentage) {
|
|
146294
146801
|
if (latchActiveSince <= 0)
|
|
146295
146802
|
latchActiveSince = now;
|
|
146296
146803
|
} else if (latchActiveSince > 0) {
|
|
@@ -146659,17 +147166,19 @@ function normalizeEmergencyRecoveryOrigin(value) {
|
|
|
146659
147166
|
return value === "provider_overflow" || value === "proactive_model_shrink" ? value : null;
|
|
146660
147167
|
}
|
|
146661
147168
|
function getOverflowState(db, sessionId, modelKey) {
|
|
146662
|
-
const result = db.prepare("SELECT detected_context_limit, detected_context_limit_model_key, needs_emergency_recovery, emergency_recovery_origin FROM session_meta WHERE session_id = ?").get(sessionId);
|
|
147169
|
+
const result = db.prepare("SELECT detected_context_limit, detected_context_limit_model_key, detected_context_limit_provenance, needs_emergency_recovery, emergency_recovery_origin FROM session_meta WHERE session_id = ?").get(sessionId);
|
|
146663
147170
|
if (!result) {
|
|
146664
147171
|
return {
|
|
146665
147172
|
detectedContextLimit: 0,
|
|
146666
147173
|
detectedContextLimitModelKey: null,
|
|
147174
|
+
detectedContextLimitProvenance: "unknown",
|
|
146667
147175
|
needsEmergencyRecovery: false,
|
|
146668
147176
|
emergencyRecoveryOrigin: null
|
|
146669
147177
|
};
|
|
146670
147178
|
}
|
|
146671
147179
|
const storedModelKey = normalizeDetectedLimitModelKey(result.detected_context_limit_model_key);
|
|
146672
147180
|
const requestedModelKey = normalizeDetectedLimitModelKey(modelKey);
|
|
147181
|
+
const provenance = normalizeContextLimitProvenance(result.detected_context_limit_provenance);
|
|
146673
147182
|
const limit = typeof result.detected_context_limit === "number" && result.detected_context_limit > 0 ? result.detected_context_limit : 0;
|
|
146674
147183
|
const modelMatches = limit > 0 && requestedModelKey && storedModelKey ? requestedModelKey === storedModelKey : true;
|
|
146675
147184
|
const needs = typeof result.needs_emergency_recovery === "number" && result.needs_emergency_recovery > 0;
|
|
@@ -146678,11 +147187,12 @@ function getOverflowState(db, sessionId, modelKey) {
|
|
|
146678
147187
|
return {
|
|
146679
147188
|
detectedContextLimit: modelMatches ? limit : 0,
|
|
146680
147189
|
detectedContextLimitModelKey: storedModelKey,
|
|
147190
|
+
detectedContextLimitProvenance: provenance,
|
|
146681
147191
|
needsEmergencyRecovery: needs,
|
|
146682
147192
|
emergencyRecoveryOrigin: recoveryOrigin
|
|
146683
147193
|
};
|
|
146684
147194
|
}
|
|
146685
|
-
function recordOverflowDetected(db, sessionId, reportedLimit, modelKey, origin = "provider_overflow") {
|
|
147195
|
+
function recordOverflowDetected(db, sessionId, reportedLimit, modelKey, origin = "provider_overflow", provenance = "unknown") {
|
|
146686
147196
|
emergencyRecoveryArmedSessions.add(sessionId);
|
|
146687
147197
|
db.transaction(() => {
|
|
146688
147198
|
ensureSessionMetaRow(db, sessionId);
|
|
@@ -146691,7 +147201,7 @@ function recordOverflowDetected(db, sessionId, reportedLimit, modelKey, origin =
|
|
|
146691
147201
|
providerOverflowReconfirmedSessions.add(sessionId);
|
|
146692
147202
|
}
|
|
146693
147203
|
if (typeof reportedLimit === "number" && reportedLimit > 0) {
|
|
146694
|
-
db.prepare("UPDATE session_meta SET detected_context_limit = ?, detected_context_limit_model_key = ?, needs_emergency_recovery = 1, emergency_recovery_origin = ?, observed_safe_input_tokens = 0, cache_alert_sent = 0 WHERE session_id = ?").run(reportedLimit, normalizeDetectedLimitModelKey(modelKey), origin, sessionId);
|
|
147204
|
+
db.prepare("UPDATE session_meta SET detected_context_limit = ?, detected_context_limit_model_key = ?, detected_context_limit_provenance = ?, needs_emergency_recovery = 1, emergency_recovery_origin = ?, observed_safe_input_tokens = 0, cache_alert_sent = 0 WHERE session_id = ?").run(reportedLimit, normalizeDetectedLimitModelKey(modelKey), normalizeContextLimitProvenance(provenance), origin, sessionId);
|
|
146695
147205
|
} else {
|
|
146696
147206
|
db.prepare("UPDATE session_meta SET needs_emergency_recovery = 1, emergency_recovery_origin = ?, observed_safe_input_tokens = 0, cache_alert_sent = 0 WHERE session_id = ?").run(origin, sessionId);
|
|
146697
147207
|
}
|
|
@@ -146712,7 +147222,7 @@ function clearEmergencyRecovery(db, sessionId) {
|
|
|
146712
147222
|
function clearDetectedContextLimit(db, sessionId) {
|
|
146713
147223
|
db.transaction(() => {
|
|
146714
147224
|
ensureSessionMetaRow(db, sessionId);
|
|
146715
|
-
db.prepare("UPDATE session_meta SET detected_context_limit = 0, detected_context_limit_model_key = NULL WHERE session_id = ?").run(sessionId);
|
|
147225
|
+
db.prepare("UPDATE session_meta SET detected_context_limit = 0, detected_context_limit_model_key = NULL, detected_context_limit_provenance = 'unknown' WHERE session_id = ?").run(sessionId);
|
|
146716
147226
|
})();
|
|
146717
147227
|
}
|
|
146718
147228
|
function getPersistedCompactionMarkerState(db, sessionId) {
|
|
@@ -146977,6 +147487,62 @@ function getRawSessionMessageCountFromDb(db, sessionId) {
|
|
|
146977
147487
|
AND COALESCE(json_extract(data, '$.finish'), '') = 'stop')`).get(sessionId);
|
|
146978
147488
|
return typeof row?.count === "number" ? row.count : 0;
|
|
146979
147489
|
}
|
|
147490
|
+
function isMidTurn(_deps, sessionId) {
|
|
147491
|
+
try {
|
|
147492
|
+
return withReadOnlySessionDb((db) => isMidTurnFromOpenCodeDb(db, sessionId));
|
|
147493
|
+
} catch (error) {
|
|
147494
|
+
log("[magic-context] failed to inspect OpenCode mid-turn state:", error);
|
|
147495
|
+
return false;
|
|
147496
|
+
}
|
|
147497
|
+
}
|
|
147498
|
+
function isMidTurnFromOpenCodeDb(db, sessionId) {
|
|
147499
|
+
const latestAssistant = db.prepare(`SELECT id,
|
|
147500
|
+
json_extract(data, '$.finish') as finish,
|
|
147501
|
+
time_created as timeCreated
|
|
147502
|
+
FROM message
|
|
147503
|
+
WHERE session_id = ?
|
|
147504
|
+
AND json_extract(data, '$.role') = 'assistant'
|
|
147505
|
+
ORDER BY time_created DESC
|
|
147506
|
+
LIMIT 1`).get(sessionId);
|
|
147507
|
+
if (typeof latestAssistant?.id !== "string")
|
|
147508
|
+
return false;
|
|
147509
|
+
if (hasNewerRealUserMessage(db, sessionId, latestAssistant.timeCreated))
|
|
147510
|
+
return false;
|
|
147511
|
+
if (latestAssistant.finish === "tool-calls")
|
|
147512
|
+
return true;
|
|
147513
|
+
const partRows = db.prepare("SELECT data FROM part WHERE session_id = ? AND message_id = ?").all(sessionId, latestAssistant.id);
|
|
147514
|
+
return partRows.some((row) => {
|
|
147515
|
+
if (typeof row.data !== "string" || row.data.length === 0)
|
|
147516
|
+
return false;
|
|
147517
|
+
try {
|
|
147518
|
+
const part = JSON.parse(row.data);
|
|
147519
|
+
return part.type === "tool" && part.providerExecuted !== true;
|
|
147520
|
+
} catch {
|
|
147521
|
+
return false;
|
|
147522
|
+
}
|
|
147523
|
+
});
|
|
147524
|
+
}
|
|
147525
|
+
function hasNewerRealUserMessage(db, sessionId, latestAssistantTimeCreated) {
|
|
147526
|
+
if (typeof latestAssistantTimeCreated !== "number")
|
|
147527
|
+
return false;
|
|
147528
|
+
const row = db.prepare(`SELECT 1 as one
|
|
147529
|
+
FROM message m
|
|
147530
|
+
WHERE m.session_id = ?
|
|
147531
|
+
AND m.time_created > ?
|
|
147532
|
+
AND json_extract(m.data, '$.role') = 'user'
|
|
147533
|
+
AND NOT (
|
|
147534
|
+
EXISTS (SELECT 1 FROM part p WHERE p.message_id = m.id)
|
|
147535
|
+
AND NOT EXISTS (
|
|
147536
|
+
SELECT 1 FROM part p
|
|
147537
|
+
WHERE p.message_id = m.id
|
|
147538
|
+
AND COALESCE(json_extract(p.data, '$.synthetic'), 0) NOT IN (1, 'true')
|
|
147539
|
+
AND json_extract(p.data, '$.metadata.marker.kind') IS NULL
|
|
147540
|
+
AND COALESCE(json_extract(p.data, '$.ignored'), 0) NOT IN (1, 'true')
|
|
147541
|
+
)
|
|
147542
|
+
)
|
|
147543
|
+
LIMIT 1`).get(sessionId, latestAssistantTimeCreated);
|
|
147544
|
+
return row?.one === 1;
|
|
147545
|
+
}
|
|
146980
147546
|
|
|
146981
147547
|
// ../plugin/src/hooks/magic-context/read-session-raw.ts
|
|
146982
147548
|
function isRawMessageRow(row) {
|
|
@@ -148455,7 +149021,7 @@ function escapeXmlContent(s) {
|
|
|
148455
149021
|
}
|
|
148456
149022
|
// ../plugin/src/features/magic-context/project-docs-hash.ts
|
|
148457
149023
|
import { createHash as createHash5 } from "node:crypto";
|
|
148458
|
-
import { lstatSync, readFileSync as
|
|
149024
|
+
import { lstatSync, readFileSync as readFileSync3, statSync as statSync3 } from "node:fs";
|
|
148459
149025
|
import path2 from "node:path";
|
|
148460
149026
|
var PROJECT_DOC_FILES = ["ARCHITECTURE.md", "STRUCTURE.md"];
|
|
148461
149027
|
var PROJECT_DOCS_DELIMITER = `
|
|
@@ -148529,7 +149095,7 @@ function readCanonicalPieces(projectDirectory, files) {
|
|
|
148529
149095
|
if (!safeToRead) {
|
|
148530
149096
|
continue;
|
|
148531
149097
|
}
|
|
148532
|
-
const canonicalContent = canonicalizeDocContent(
|
|
149098
|
+
const canonicalContent = canonicalizeDocContent(readFileSync3(filePath, "utf8"));
|
|
148533
149099
|
hashPieces.push(`file:${filename}
|
|
148534
149100
|
${canonicalContent}`);
|
|
148535
149101
|
renderedSections.push(`<file name="${escapeXmlAttr(filename)}">
|
|
@@ -148976,7 +149542,7 @@ function getMemoryMutationsForRenderByIdentitySet(db, projectPaths, afterId, ren
|
|
|
148976
149542
|
}
|
|
148977
149543
|
visited.add(terminal);
|
|
148978
149544
|
const next = byTarget.get(terminal);
|
|
148979
|
-
if (
|
|
149545
|
+
if (next?.mutationType !== "superseded")
|
|
148980
149546
|
break;
|
|
148981
149547
|
if (depth >= MAX_MEMORY_REPLACEMENT_DEPTH - 1) {
|
|
148982
149548
|
terminal = null;
|
|
@@ -149236,6 +149802,14 @@ function getPendingOpsStatement(db) {
|
|
|
149236
149802
|
}
|
|
149237
149803
|
return stmt;
|
|
149238
149804
|
}
|
|
149805
|
+
function getClearPendingOpsStatement(db) {
|
|
149806
|
+
let stmt = clearPendingOpsStatements.get(db);
|
|
149807
|
+
if (!stmt) {
|
|
149808
|
+
stmt = db.prepare("DELETE FROM pending_ops WHERE session_id = ?");
|
|
149809
|
+
clearPendingOpsStatements.set(db, stmt);
|
|
149810
|
+
}
|
|
149811
|
+
return stmt;
|
|
149812
|
+
}
|
|
149239
149813
|
function getRemovePendingOpStatement(db) {
|
|
149240
149814
|
let stmt = removePendingOpStatements.get(db);
|
|
149241
149815
|
if (!stmt) {
|
|
@@ -149270,6 +149844,9 @@ function getPendingOps(db, sessionId) {
|
|
|
149270
149844
|
const rows = getPendingOpsStatement(db).all(sessionId).filter(isPendingOpRow);
|
|
149271
149845
|
return rows.map(toPendingOp).filter((op) => op !== null);
|
|
149272
149846
|
}
|
|
149847
|
+
function clearPendingOps(db, sessionId) {
|
|
149848
|
+
getClearPendingOpsStatement(db).run(sessionId);
|
|
149849
|
+
}
|
|
149273
149850
|
function removePendingOp(db, sessionId, tagId) {
|
|
149274
149851
|
getRemovePendingOpStatement(db).run(sessionId, tagId);
|
|
149275
149852
|
}
|
|
@@ -150229,76 +150806,6 @@ var ERROR_CLASSES = new Set([
|
|
|
150229
150806
|
"permission_denied",
|
|
150230
150807
|
"unknown"
|
|
150231
150808
|
]);
|
|
150232
|
-
// ../plugin/src/shared/models-dev-cache.ts
|
|
150233
|
-
import { mkdirSync as mkdirSync3, readFileSync as readFileSync3, renameSync as renameSync2, writeFileSync as writeFileSync2 } from "node:fs";
|
|
150234
|
-
import { join as join5 } from "node:path";
|
|
150235
|
-
var MIN_SANE_LIMIT = 20000;
|
|
150236
|
-
var MAX_SANE_LIMIT = 3000000;
|
|
150237
|
-
function isSaneLimit(limit) {
|
|
150238
|
-
return typeof limit === "number" && limit >= MIN_SANE_LIMIT && limit <= MAX_SANE_LIMIT;
|
|
150239
|
-
}
|
|
150240
|
-
var apiCache = null;
|
|
150241
|
-
var persistSeedLoaded = false;
|
|
150242
|
-
function persistFilePath() {
|
|
150243
|
-
return join5(getMagicContextStorageDir(), `model-context-limits-${getHarness()}.json`);
|
|
150244
|
-
}
|
|
150245
|
-
function loadPersistedApiCacheOnce() {
|
|
150246
|
-
if (persistSeedLoaded || apiCache !== null)
|
|
150247
|
-
return;
|
|
150248
|
-
persistSeedLoaded = true;
|
|
150249
|
-
try {
|
|
150250
|
-
const raw = readFileSync3(persistFilePath(), "utf-8");
|
|
150251
|
-
const obj = JSON.parse(raw);
|
|
150252
|
-
const map = new Map;
|
|
150253
|
-
for (const [key, persisted] of Object.entries(obj)) {
|
|
150254
|
-
const limit = typeof persisted === "number" ? persisted : persisted.limit;
|
|
150255
|
-
const inputLimit = typeof persisted === "number" ? undefined : persisted.inputLimit;
|
|
150256
|
-
const vision = typeof persisted === "number" ? false : persisted.vision === true;
|
|
150257
|
-
if (isSaneLimit(limit)) {
|
|
150258
|
-
map.set(key, {
|
|
150259
|
-
limit,
|
|
150260
|
-
inputLimit: isSaneLimit(inputLimit) ? inputLimit : undefined,
|
|
150261
|
-
vision
|
|
150262
|
-
});
|
|
150263
|
-
}
|
|
150264
|
-
}
|
|
150265
|
-
if (map.size > 0) {
|
|
150266
|
-
apiCache = map;
|
|
150267
|
-
sessionLog("global", `models-dev-cache: seeded ${map.size} entries from persisted cache (cold start)`);
|
|
150268
|
-
}
|
|
150269
|
-
} catch {}
|
|
150270
|
-
}
|
|
150271
|
-
function getSdkContextLimit(providerID, modelID) {
|
|
150272
|
-
loadPersistedApiCacheOnce();
|
|
150273
|
-
const fromApi = lookupLimitWithTagFallback(apiCache, providerID, modelID);
|
|
150274
|
-
return isSaneLimit(fromApi) ? fromApi : undefined;
|
|
150275
|
-
}
|
|
150276
|
-
function modelSupportsVision(providerID, modelID) {
|
|
150277
|
-
loadPersistedApiCacheOnce();
|
|
150278
|
-
if (!apiCache)
|
|
150279
|
-
return false;
|
|
150280
|
-
const exact = apiCache.get(`${providerID}/${modelID}`);
|
|
150281
|
-
if (exact?.vision === true)
|
|
150282
|
-
return true;
|
|
150283
|
-
const colon = modelID.lastIndexOf(":");
|
|
150284
|
-
return colon > 0 ? apiCache.get(`${providerID}/${modelID.slice(0, colon)}`)?.vision === true : false;
|
|
150285
|
-
}
|
|
150286
|
-
function lookupLimitWithTagFallback(cache, providerID, modelID) {
|
|
150287
|
-
if (!cache)
|
|
150288
|
-
return;
|
|
150289
|
-
const exact = cache.get(`${providerID}/${modelID}`)?.limit;
|
|
150290
|
-
if (typeof exact === "number")
|
|
150291
|
-
return exact;
|
|
150292
|
-
const colonIdx = modelID.lastIndexOf(":");
|
|
150293
|
-
if (colonIdx > 0) {
|
|
150294
|
-
const baseModel = modelID.slice(0, colonIdx);
|
|
150295
|
-
const fallback = cache.get(`${providerID}/${baseModel}`)?.limit;
|
|
150296
|
-
if (typeof fallback === "number")
|
|
150297
|
-
return fallback;
|
|
150298
|
-
}
|
|
150299
|
-
return;
|
|
150300
|
-
}
|
|
150301
|
-
|
|
150302
150809
|
// ../plugin/src/hooks/magic-context/todo-view.ts
|
|
150303
150810
|
import { createHash as createHash7 } from "node:crypto";
|
|
150304
150811
|
var TODO_STATUS_PENDING = "pending";
|
|
@@ -150756,7 +151263,7 @@ function pruneNestedConfigLeaf(block, relativePath) {
|
|
|
150756
151263
|
}
|
|
150757
151264
|
|
|
150758
151265
|
// src/config/index.ts
|
|
150759
|
-
import { existsSync as existsSync7, readFileSync as
|
|
151266
|
+
import { existsSync as existsSync7, readFileSync as readFileSync6 } from "node:fs";
|
|
150760
151267
|
|
|
150761
151268
|
// ../plugin/src/config/migrate-dreamer-v2.ts
|
|
150762
151269
|
var OLD_VERIFY_TASK = "verify";
|
|
@@ -165562,62 +166069,6 @@ function nextDueAtMs(expression, afterMs, consumedScheduledAtMs, maxSearchMs = M
|
|
|
165562
166069
|
return next ? next.getTime() : null;
|
|
165563
166070
|
}
|
|
165564
166071
|
|
|
165565
|
-
// ../plugin/src/features/magic-context/dreamer/task-registry.ts
|
|
165566
|
-
var CANONICAL_DREAM_TASKS = [
|
|
165567
|
-
"map-memories",
|
|
165568
|
-
"verify",
|
|
165569
|
-
"verify-broad",
|
|
165570
|
-
"curate",
|
|
165571
|
-
"compress-cues",
|
|
165572
|
-
"classify-memories",
|
|
165573
|
-
"retrospective",
|
|
165574
|
-
"maintain-docs",
|
|
165575
|
-
"evaluate-smart-notes",
|
|
165576
|
-
"review-user-memories",
|
|
165577
|
-
"promote-primers",
|
|
165578
|
-
"refresh-primers"
|
|
165579
|
-
];
|
|
165580
|
-
var AGENTIC_DREAM_TASKS = ["curate", "maintain-docs"];
|
|
165581
|
-
var MEMORY_DOMAIN_TASKS = [
|
|
165582
|
-
"map-memories",
|
|
165583
|
-
"verify",
|
|
165584
|
-
"verify-broad",
|
|
165585
|
-
"curate",
|
|
165586
|
-
"compress-cues",
|
|
165587
|
-
"classify-memories",
|
|
165588
|
-
"retrospective",
|
|
165589
|
-
"promote-primers",
|
|
165590
|
-
"refresh-primers"
|
|
165591
|
-
];
|
|
165592
|
-
var MEMORY_DOMAIN_SET = new Set(MEMORY_DOMAIN_TASKS);
|
|
165593
|
-
function leaseKindFor(task) {
|
|
165594
|
-
if (MEMORY_DOMAIN_SET.has(task))
|
|
165595
|
-
return "memory";
|
|
165596
|
-
switch (task) {
|
|
165597
|
-
case "review-user-memories":
|
|
165598
|
-
return "user-memories";
|
|
165599
|
-
case "promote-primers":
|
|
165600
|
-
case "refresh-primers":
|
|
165601
|
-
return "memory";
|
|
165602
|
-
case "maintain-docs":
|
|
165603
|
-
return "maintain-docs";
|
|
165604
|
-
case "evaluate-smart-notes":
|
|
165605
|
-
return "evaluate-smart-notes";
|
|
165606
|
-
default:
|
|
165607
|
-
return "memory";
|
|
165608
|
-
}
|
|
165609
|
-
}
|
|
165610
|
-
function leaseKeyFor(task, projectIdentity) {
|
|
165611
|
-
const kind = leaseKindFor(task);
|
|
165612
|
-
return kind === "user-memories" ? "user-memories" : `${kind}:${projectIdentity}`;
|
|
165613
|
-
}
|
|
165614
|
-
function isCanonicalDreamTask(value) {
|
|
165615
|
-
return CANONICAL_DREAM_TASKS.includes(value);
|
|
165616
|
-
}
|
|
165617
|
-
function compareTaskOrder(a, b) {
|
|
165618
|
-
return CANONICAL_DREAM_TASKS.indexOf(a) - CANONICAL_DREAM_TASKS.indexOf(b);
|
|
165619
|
-
}
|
|
165620
|
-
|
|
165621
166072
|
// ../plugin/src/config/schema/agent-overrides.ts
|
|
165622
166073
|
var PermissionValueSchema = exports_external.enum(["ask", "allow", "deny"]);
|
|
165623
166074
|
var PermissionSchema = exports_external.object({
|
|
@@ -165646,12 +166097,11 @@ var AgentOverrideConfigSchema = exports_external.object({
|
|
|
165646
166097
|
|
|
165647
166098
|
// ../plugin/src/config/schema/magic-context.ts
|
|
165648
166099
|
var DEFAULT_EXECUTE_THRESHOLD_PERCENTAGE = 65;
|
|
165649
|
-
var EXECUTE_THRESHOLD_CAP_MESSAGE = "execute_threshold is capped at
|
|
166100
|
+
var EXECUTE_THRESHOLD_CAP_MESSAGE = "execute_threshold is capped at 90% for cache safety: output capacity is reserved from the usable context window, and the remaining 10% absorbs mid-turn growth before the absolute 95% emergency wall. Use a value between 20 and 90.";
|
|
165650
166101
|
var DEFAULT_HISTORIAN_TIMEOUT_MS = 300000;
|
|
165651
166102
|
var DEFAULT_HISTORY_BUDGET_PERCENTAGE = 0.15;
|
|
165652
166103
|
var DEFAULT_LOCAL_EMBEDDING_MODEL = "Xenova/all-MiniLM-L6-v2";
|
|
165653
|
-
var
|
|
165654
|
-
var PiThinkingLevelSchema = exports_external.enum(["off", "minimal", "low", "medium", "high", "xhigh"]).optional();
|
|
166104
|
+
var PiThinkingLevelSchema = exports_external.enum(["off", "minimal", "low", "medium", "high", "xhigh", "max"]).optional();
|
|
165655
166105
|
var PiConfigSchema = exports_external.object({
|
|
165656
166106
|
subagent_extensions: exports_external.array(exports_external.string().trim().min(1)).optional().describe("User-only allowlist of Pi extensions for Magic Context subagent children. When set, children use --no-extensions and load only these entries (plus Magic Context's scoped child extension where applicable). Relative paths resolve from ~/.pi/agent, matching Pi's settings.json package location. Unset preserves normal Pi extension discovery.")
|
|
165657
166107
|
}).optional();
|
|
@@ -165724,7 +166174,7 @@ var SidekickConfigSchema = AgentOverrideConfigSchema.extend({
|
|
|
165724
166174
|
}).optional();
|
|
165725
166175
|
var HistorianConfigSchema = AgentOverrideConfigSchema.extend({
|
|
165726
166176
|
two_pass: exports_external.boolean().default(false).describe("Run a second editor pass over historian output to clean low-signal U: lines and cross-compartment duplicates. Adds ~1 extra API call and ~1.3x cost per historian run. Useful for models without extended thinking support. (default: false)"),
|
|
165727
|
-
thinking_level: PiThinkingLevelSchema.describe("Pi only: explicit thinking level passed as --thinking <level> to Pi historian subagent invocations. Required when using reasoning models (e.g. github-copilot/gpt-5.4) because Pi's default thinking-level resolution can pick a value the provider rejects. OpenCode users set variant instead. Valid: off | minimal | low | medium | high | xhigh"),
|
|
166177
|
+
thinking_level: PiThinkingLevelSchema.describe("Pi only: explicit thinking level passed as --thinking <level> to Pi historian subagent invocations. Required when using reasoning models (e.g. github-copilot/gpt-5.4) because Pi's default thinking-level resolution can pick a value the provider rejects. OpenCode users set variant instead. Valid: off | minimal | low | medium | high | xhigh | max"),
|
|
165728
166178
|
disallowed_tools: exports_external.array(exports_external.enum(["*", "read", "aft_outline", "aft_zoom", "aft_search"])).default([]).describe(`OpenCode only. Tools to REMOVE from the historian's default allow-list [read, aft_outline, aft_zoom, aft_search]. Applies to both historian and historian-editor agents. Use ["*"] to strip all tool definitions from the model request — this prevents weak instruction-following models (e.g. mistral-small-latest) from entering tool-calling loops. Individual tool names remove just that tool. Note: a user-supplied historian.permission override can re-allow a tool that disallowed_tools removed — disallowed_tools sets the baseline, permission overrides take precedence. (default: [])`)
|
|
165729
166179
|
}).optional();
|
|
165730
166180
|
var EmbeddingFallbackProviderSchema = exports_external.enum(["local", "openai-compatible", "off"]);
|
|
@@ -165745,7 +166195,22 @@ var BaseEmbeddingConfigSchema = exports_external.object({
|
|
|
165745
166195
|
input_type: exports_external.string().optional().describe("Default input_type for stored/indexed (passage) embeddings in the request body. Required by some openai-compatible providers (e.g. NVIDIA NIM). Omitted from the request when unset."),
|
|
165746
166196
|
query_input_type: exports_external.string().optional().describe("Optional input_type for query (search) embeddings on asymmetric models (e.g. NVIDIA NIM 'query'). When unset, query embeddings use embedding.input_type. Passage/stored content always uses embedding.input_type."),
|
|
165747
166197
|
truncate: exports_external.string().optional().describe("Optional truncate mode sent in the embedding request body (e.g. NVIDIA NIM accepts 'NONE' | 'START' | 'END'). Omitted from the request when unset."),
|
|
165748
|
-
max_input_tokens: exports_external.number().int().positive().optional().describe("Optional maximum input tokens for chunk embeddings. Defaults conservatively to 512 when omitted.")
|
|
166198
|
+
max_input_tokens: exports_external.number().int().positive().optional().describe("Optional maximum input tokens for chunk embeddings. Defaults conservatively to 512 when omitted."),
|
|
166199
|
+
local_dtype: exports_external.enum([
|
|
166200
|
+
"auto",
|
|
166201
|
+
"fp32",
|
|
166202
|
+
"fp16",
|
|
166203
|
+
"q8",
|
|
166204
|
+
"int8",
|
|
166205
|
+
"uint8",
|
|
166206
|
+
"q4",
|
|
166207
|
+
"bnb4",
|
|
166208
|
+
"q4f16",
|
|
166209
|
+
"q2",
|
|
166210
|
+
"q2f16",
|
|
166211
|
+
"q1",
|
|
166212
|
+
"q1f16"
|
|
166213
|
+
]).optional().describe("Local provider only: ONNX model dtype passed to the transformers.js feature-extraction pipeline. Accepts the @huggingface/transformers DataType strings (auto, fp32, fp16, q8, int8, uint8, q4, bnb4, q4f16, q2, q2f16, q1, q1f16). Omitted keeps today's behavior (fp32). A non-default value changes the produced vectors and folds into the embedding model identity, so switching dtype re-embeds rather than mixing vector spaces. Useful for selecting a quantized variant (e.g. q8) of a larger multilingual model to cut memory and CPU cost; see issue #259.")
|
|
165749
166214
|
}).superRefine((data, ctx) => {
|
|
165750
166215
|
const validationProvider = data.provider === "synapse" ? data.fallback_provider : data.provider;
|
|
165751
166216
|
if (validationProvider === "openai-compatible" && !data.endpoint?.trim()) {
|
|
@@ -165787,7 +166252,8 @@ var EmbeddingConfigSchema = BaseEmbeddingConfigSchema.transform((data) => {
|
|
|
165787
166252
|
return {
|
|
165788
166253
|
provider: "local",
|
|
165789
166254
|
model: data.model?.trim() || DEFAULT_LOCAL_EMBEDDING_MODEL,
|
|
165790
|
-
...data.max_input_tokens ? { max_input_tokens: data.max_input_tokens } : {}
|
|
166255
|
+
...data.max_input_tokens ? { max_input_tokens: data.max_input_tokens } : {},
|
|
166256
|
+
...data.local_dtype ? { local_dtype: data.local_dtype } : {}
|
|
165791
166257
|
};
|
|
165792
166258
|
}
|
|
165793
166259
|
if (data.provider === "openai-compatible") {
|
|
@@ -165810,6 +166276,7 @@ var EmbeddingConfigSchema = BaseEmbeddingConfigSchema.transform((data) => {
|
|
|
165810
166276
|
});
|
|
165811
166277
|
var MagicContextConfigSchema = exports_external.object({
|
|
165812
166278
|
enabled: exports_external.boolean().default(true).describe("Enable magic context (default: true)"),
|
|
166279
|
+
allow_home_project: exports_external.boolean().default(false).describe("Allow Magic Context sessions launched from the exact canonical home directory. The home session uses its deterministic dir: identity so pre-gate memories reconnect. USER-LEVEL ONLY: project config is ignored. The home identity is excluded from registry seed exports, never resolves descendants by containment, and cannot join a workspace."),
|
|
165813
166280
|
experimental: exports_external.object({
|
|
165814
166281
|
mural: exports_external.object({
|
|
165815
166282
|
enabled: exports_external.boolean().default(false),
|
|
@@ -165821,15 +166288,19 @@ var MagicContextConfigSchema = exports_external.object({
|
|
|
165821
166288
|
language: exports_external.string().trim().toLowerCase().refine((s) => isValidLanguageCode(s), 'language must be a 2-letter ISO 639-1 code (e.g. "tr", "es", "de")').optional().describe("Output language for Magic Context's generated content and guidance, as a " + '2-letter ISO 639-1 code (e.g. "tr", "es", "de", "ja", "pt"). When set, the ' + "historian, dreamer, sidekick, and the agent-guidance block instruct the model to " + "write its PROSE in this language while keeping all structural tokens (XML tags, " + "the five memory category names, code identifiers, file paths) in English. " + "USER-LEVEL ONLY (ignored in project config for security). Unset = today's " + "behavior (model mirrors the conversation; English scaffolding). Changing it " + "triggers one cache re-materialization; existing compartments/memories keep their " + "original language until naturally rewritten."),
|
|
165822
166289
|
historian: HistorianConfigSchema.describe("Historian agent configuration (model, fallback_models, variant, temperature, maxTokens, permission, two_pass, etc.)"),
|
|
165823
166290
|
dreamer: DreamerConfigSchema.optional().describe("Dreamer agent + scheduling configuration (model, fallback_models, disable, schedule, tasks, etc.)"),
|
|
165824
|
-
cache_ttl: exports_external.union([exports_external.string(), exports_external.object({ default: exports_external.string() }).catchall(exports_external.string())]).default("5m").describe('Cache TTL: string (e.g. "5m") or per-model object ({ default: "5m", "model-id": "10m" })'),
|
|
166291
|
+
cache_ttl: exports_external.union([exports_external.string(), exports_external.object({ default: exports_external.string() }).catchall(exports_external.string())]).default("5m").describe('Cache TTL: string (e.g. "5m", "1h", "30s") or per-model object ({ default: "5m", "model-id": "10m" }). Set to "never" for lanes kept warm by an external keepwarm proxy — disables the idle-TTL heuristic so MC never initiates a rebuild based on elapsed time.'),
|
|
166292
|
+
output_reserve: exports_external.union([
|
|
166293
|
+
exports_external.number().min(0),
|
|
166294
|
+
exports_external.object({ default: exports_external.number().min(0) }).catchall(exports_external.number().min(0))
|
|
166295
|
+
]).optional().describe('User-only output-token reservation override. Number or per-model object ({ default: 16384, "provider/model": 8192 }); 0 disables reservation. When unset, Magic Context reserves the catalog output limit (capped at 25% of context) for shared-window providers and keeps proven separate-quota Google/Gemini windows unchanged.'),
|
|
165825
166296
|
toast_duration_ms: exports_external.number().min(0).max(60000).default(5000).describe("TUI toast lifetime in milliseconds for Magic Context notifications. Set to 0 to disable Magic Context toasts entirely (min: 0, max: 60000, default: 5000)"),
|
|
165826
166297
|
execute_threshold_percentage: exports_external.union([
|
|
165827
|
-
exports_external.number().min(20).max(
|
|
165828
|
-
exports_external.object({ default: exports_external.number().min(20).max(
|
|
165829
|
-
]).default(DEFAULT_EXECUTE_THRESHOLD_PERCENTAGE).describe('Context percentage that forces queued operations to execute. Number or per-model object ({ default: 65, "provider/model": 45 }). Values above
|
|
166298
|
+
exports_external.number().min(20).max(90, EXECUTE_THRESHOLD_CAP_MESSAGE),
|
|
166299
|
+
exports_external.object({ default: exports_external.number().min(20).max(90, EXECUTE_THRESHOLD_CAP_MESSAGE) }).catchall(exports_external.number().min(20).max(90, EXECUTE_THRESHOLD_CAP_MESSAGE))
|
|
166300
|
+
]).default(DEFAULT_EXECUTE_THRESHOLD_PERCENTAGE).describe('Context percentage that forces queued operations to execute. Number or per-model object ({ default: 65, "provider/model": 45 }). Values above 90 are rejected because the runtime caps at 90% of the output-reserved safe window (MAX_EXECUTE_THRESHOLD). Default: DEFAULT_EXECUTE_THRESHOLD_PERCENTAGE'),
|
|
165830
166301
|
execute_threshold_tokens: exports_external.object({
|
|
165831
166302
|
default: exports_external.number().min(5000).max(2000000).optional()
|
|
165832
|
-
}).catchall(exports_external.number().min(5000).max(2000000)).optional().describe("Absolute token thresholds per model. When matched, overrides execute_threshold_percentage for that model. Accepts `default` for all models or per-model keys. Values above
|
|
166303
|
+
}).catchall(exports_external.number().min(5000).max(2000000)).optional().describe("Absolute token thresholds per model. When matched, overrides execute_threshold_percentage for that model. Accepts `default` for all models or per-model keys. Values above 90% × context_limit are clamped with a warning log. Min 5_000, max 2_000_000."),
|
|
165833
166304
|
protected_tags: exports_external.number().min(1).max(100).optional().describe("Number of recent tags to protect from dropping (min: 1, max: 100, default: 20)"),
|
|
165834
166305
|
clear_reasoning_age: exports_external.number().min(10).default(50).describe("Clear reasoning/thinking blocks older than N tags (default: 50)"),
|
|
165835
166306
|
history_budget_percentage: exports_external.number().min(0.05).max(0.5).default(DEFAULT_HISTORY_BUDGET_PERCENTAGE).describe("Fraction of usable context (context_limit × execute_threshold) reserved for the session history block (default: 0.15)"),
|
|
@@ -165849,6 +166320,9 @@ var MagicContextConfigSchema = exports_external.object({
|
|
|
165849
166320
|
cache_size_mb: exports_external.number().min(2).max(2048).default(64).describe("Page-cache size in MiB per connection (PRAGMA cache_size). Larger keeps more hot pages resident, cutting re-reads on repeated full-table scans. (min 2, max 2048, default 64)"),
|
|
165850
166321
|
mmap_size_mb: exports_external.number().min(0).max(8192).default(0).describe("Memory-mapped I/O size in MiB (PRAGMA mmap_size). 0 disables mmap (SQLite default). Raising it can cut read overhead on large DBs at the cost of address space. (min 0, max 8192, default 0)")
|
|
165851
166322
|
}).default({ cache_size_mb: 64, mmap_size_mb: 0 }).describe("SQLite connection tuning for Magic Context's own context.db. These are per-connection PRAGMAs applied at open; they do not change the schema or what is stored."),
|
|
166323
|
+
storage: exports_external.object({
|
|
166324
|
+
enforce_private_permissions: exports_external.boolean().default(true).describe("When true (default), Magic Context creates and re-tightens its storage directories to owner-only 0700 and storage files to owner-only 0600. Set false only for a deliberate trusted-group deployment whose operator manages directory, database, WAL/SHM, cache, and RPC file permissions externally; Magic Context then never chmods or supplies restrictive creation modes. USER-LEVEL ONLY — ignored in project config for security. On Windows, POSIX chmod modes are already meaningless, so this setting is a no-op.")
|
|
166325
|
+
}).default({ enforce_private_permissions: true }).describe("Storage permission policy. The default keeps session content and memories owner-private. Disabling enforcement is for trusted shared-group storage managed externally; every group member able to read the storage can read all stored session content and memories."),
|
|
165852
166326
|
embedding: EmbeddingConfigSchema.default({
|
|
165853
166327
|
provider: "local",
|
|
165854
166328
|
model: DEFAULT_LOCAL_EMBEDDING_MODEL
|
|
@@ -165862,6 +166336,9 @@ var MagicContextConfigSchema = exports_external.object({
|
|
|
165862
166336
|
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 compact date ranges to compartment headings. 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).'),
|
|
165863
166337
|
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."),
|
|
165864
166338
|
fail_closed_blocking: exports_external.boolean().default(true).describe("When Magic Context cannot operate (schema fence mismatch, storage open/migration failure), block the primary-session prompt with a loud recovery error instead of silently degrading to native compaction. Default true. Set false only to restore the old degrade-silently behavior (not recommended). USER-LEVEL ONLY — ignored in project config for security. Requires a restart."),
|
|
166339
|
+
compaction: exports_external.object({
|
|
166340
|
+
enabled: exports_external.boolean().default(true).describe("When false, Magic Context stops managing the context window and keeps its knowledge layer: memory and docs/user-profile/key-files injection through additive m[0]/m[1], raw-message FTS indexing, dreamer, notes, ctx_search, ctx_expand, ctx_memory, and /ctx-embed remain available. MC's historian/compartment preparation, tagging, markers, pruning, folding, drops, strips, splicing, synthetic context-management todos, temporal markers, nudges, and fail-closed blocking stop; ctx_expand remains a knowledge-surface tool. fail_closed_blocking is inert: a transform failure passes the input messages through without blocking or cancelling. This setting does not enable native compaction: OpenCode's compaction.auto / compaction.prune or Pi's equivalent owns the window, or nothing does. MC's compaction.enabled in magic-context.jsonc is distinct from OpenCode's compaction.auto / compaction.prune in opencode.jsonc; they are different files and different owners. On the first turn after disabling, a long session may trigger one native compaction cycle; MC removes only its own marker boundary, leaves native boundaries and stored compartments intact, and does no pre-trimming mitigation. Marker cleanup is lazy per session, so an unresumed session is cleaned when it is next resumed. If compaction is enabled again, run /ctx-wrapup when the historian is runnable to catch up. OpenCode peer verification against v1.18.4 confirms native compaction covers child sessions: subagents receive additive memory/docs injection and no MC reclaim in this mode, so keep subagent tasks small or leave compaction.enabled on for long subagent runs. If transform_mode is rust, compaction-off resolves to the TypeScript transform and emits one frozen boot warning because there is no Rust reduced-mode contract. This is boot-resolved and requires a process restart; project-tier compaction.enabled is stripped so a cloned repository cannot disable the user's setting. The sidebar reports raw usage as Context: <pct>% · native compaction or Context: <pct>% · no active compaction and does not show an MC execute-threshold fill. /ctx-wrapup, /ctx-recomp, /ctx-flush, and /ctx-session-upgrade refuse without context-management side effects; /ctx-embed remains functional. Raw content hidden by a native boundary before Magic Context's first pass is not retroactively indexed.")
|
|
166341
|
+
}).default({ enabled: true }).describe("Compaction-off mode gate. Default true (MC manages the context window as today). Set compaction.enabled=false to keep the knowledge layer while letting native compaction (or nothing) own the window. Boot-resolved; requires a restart to change."),
|
|
165865
166342
|
todowrite: exports_external.object({
|
|
165866
166343
|
enabled: exports_external.boolean().default(true).describe("Pi only: register Magic Context's todowrite task-list tool. Disable if you use your own todo extension. OpenCode ships its own built-in todowrite; this setting has no effect there."),
|
|
165867
166344
|
overlay: exports_external.boolean().default(true).describe("Pi only: show the persistent todo overlay above the editor while tasks are active.")
|
|
@@ -166015,6 +166492,19 @@ function stripUnsafeProjectConfigFields(projectRaw) {
|
|
|
166015
166492
|
delete projectRaw.fail_closed_blocking;
|
|
166016
166493
|
warnings.push("Ignoring fail_closed_blocking from project config (security: only user-level config may disable or force the loud inoperability gate).");
|
|
166017
166494
|
}
|
|
166495
|
+
if ("allow_home_project" in projectRaw) {
|
|
166496
|
+
delete projectRaw.allow_home_project;
|
|
166497
|
+
warnings.push("Ignoring allow_home_project from project config (security: only user-level config may opt the user's home directory into Magic Context).");
|
|
166498
|
+
}
|
|
166499
|
+
const compaction = projectRaw.compaction;
|
|
166500
|
+
if (isPlainObject3(compaction) && "enabled" in compaction) {
|
|
166501
|
+
delete compaction.enabled;
|
|
166502
|
+
warnings.push("Ignoring compaction.enabled from project config (security: only user-level config may disable Magic Context's context-window management; a cloned repo cannot change how the user's window is owned).");
|
|
166503
|
+
}
|
|
166504
|
+
if ("output_reserve" in projectRaw) {
|
|
166505
|
+
delete projectRaw.output_reserve;
|
|
166506
|
+
warnings.push("Ignoring output_reserve from project config (security: output-token reservation only honors user-level config).");
|
|
166507
|
+
}
|
|
166018
166508
|
if ("language" in projectRaw) {
|
|
166019
166509
|
delete projectRaw.language;
|
|
166020
166510
|
warnings.push("Ignoring language from project config (security: output language is a user-level setting).");
|
|
@@ -166023,6 +166513,11 @@ function stripUnsafeProjectConfigFields(projectRaw) {
|
|
|
166023
166513
|
delete projectRaw.sqlite;
|
|
166024
166514
|
warnings.push("Ignoring sqlite.* from project config (security: SQLite cache/mmap PRAGMAs apply to the " + "process-global shared database handle; only user-level config may set them).");
|
|
166025
166515
|
}
|
|
166516
|
+
const storage = projectRaw.storage;
|
|
166517
|
+
if (isPlainObject3(storage) && "enforce_private_permissions" in storage) {
|
|
166518
|
+
delete storage.enforce_private_permissions;
|
|
166519
|
+
warnings.push("Ignoring storage.enforce_private_permissions from project config (security: only user-level config may opt into externally managed shared storage permissions).");
|
|
166520
|
+
}
|
|
166026
166521
|
const pi = projectRaw.pi;
|
|
166027
166522
|
if (isPlainObject3(pi) && "subagent_extensions" in pi) {
|
|
166028
166523
|
delete pi.subagent_extensions;
|
|
@@ -166361,6 +166856,188 @@ function substituteConfigVariables(input) {
|
|
|
166361
166856
|
return { text: output, warnings };
|
|
166362
166857
|
}
|
|
166363
166858
|
|
|
166859
|
+
// ../plugin/src/shared/models-dev-cache.ts
|
|
166860
|
+
import { mkdirSync as mkdirSync3, readFileSync as readFileSync5, renameSync as renameSync2, writeFileSync as writeFileSync2 } from "node:fs";
|
|
166861
|
+
import { join as join5 } from "node:path";
|
|
166862
|
+
|
|
166863
|
+
// ../plugin/src/shared/harness-provider-map.ts
|
|
166864
|
+
var CANONICAL_TO_PI_PROVIDER = {
|
|
166865
|
+
openai: "openai-codex",
|
|
166866
|
+
google: "google-antigravity"
|
|
166867
|
+
};
|
|
166868
|
+
var PI_TO_CANONICAL_PROVIDER = {
|
|
166869
|
+
"openai-codex": "openai",
|
|
166870
|
+
"google-antigravity": "google"
|
|
166871
|
+
};
|
|
166872
|
+
function remapProviderPrefix(ref, map2) {
|
|
166873
|
+
if (typeof ref !== "string")
|
|
166874
|
+
return ref;
|
|
166875
|
+
const slash = ref.indexOf("/");
|
|
166876
|
+
if (slash <= 0)
|
|
166877
|
+
return ref;
|
|
166878
|
+
const provider = ref.slice(0, slash);
|
|
166879
|
+
const mapped = map2[provider];
|
|
166880
|
+
return mapped ? `${mapped}${ref.slice(slash)}` : ref;
|
|
166881
|
+
}
|
|
166882
|
+
function piModelRefToCanonical(ref) {
|
|
166883
|
+
return remapProviderPrefix(ref, PI_TO_CANONICAL_PROVIDER);
|
|
166884
|
+
}
|
|
166885
|
+
function resolveModelRefForPi(ref) {
|
|
166886
|
+
return remapProviderPrefix(piModelRefToCanonical(ref), CANONICAL_TO_PI_PROVIDER);
|
|
166887
|
+
}
|
|
166888
|
+
|
|
166889
|
+
// ../plugin/src/shared/models-dev-cache.ts
|
|
166890
|
+
var MIN_SANE_LIMIT = 20000;
|
|
166891
|
+
var MAX_SANE_LIMIT = 3000000;
|
|
166892
|
+
function isSaneLimit(limit) {
|
|
166893
|
+
return typeof limit === "number" && limit >= MIN_SANE_LIMIT && limit <= MAX_SANE_LIMIT;
|
|
166894
|
+
}
|
|
166895
|
+
var SEPARATE_OUTPUT_QUOTA_PROVIDERS = new Set(["google", "google-antigravity"]);
|
|
166896
|
+
var MIN_PLAUSIBLE_CONTEXT_LIMIT = 1024;
|
|
166897
|
+
var OUTPUT_RESERVE_CAP_RATIO = 0.25;
|
|
166898
|
+
var outputReserveConfig;
|
|
166899
|
+
var reserveClampLogSeen = new Set;
|
|
166900
|
+
var apiCache = null;
|
|
166901
|
+
var persistSeedLoaded = false;
|
|
166902
|
+
function persistFilePath() {
|
|
166903
|
+
return join5(getMagicContextStorageDir(), `model-context-limits-${getHarness()}.json`);
|
|
166904
|
+
}
|
|
166905
|
+
function loadPersistedApiCacheOnce() {
|
|
166906
|
+
if (persistSeedLoaded || apiCache !== null)
|
|
166907
|
+
return;
|
|
166908
|
+
persistSeedLoaded = true;
|
|
166909
|
+
try {
|
|
166910
|
+
const raw = readFileSync5(persistFilePath(), "utf-8");
|
|
166911
|
+
const obj = JSON.parse(raw);
|
|
166912
|
+
const map2 = new Map;
|
|
166913
|
+
for (const [key, persisted] of Object.entries(obj)) {
|
|
166914
|
+
const limit = typeof persisted === "number" ? persisted : persisted.limit;
|
|
166915
|
+
const contextLimit = typeof persisted === "number" ? undefined : persisted.contextLimit;
|
|
166916
|
+
const inputLimit = typeof persisted === "number" ? undefined : persisted.inputLimit;
|
|
166917
|
+
const outputLimit = typeof persisted === "number" ? undefined : persisted.outputLimit;
|
|
166918
|
+
const vision = typeof persisted === "number" ? false : persisted.vision === true;
|
|
166919
|
+
if (isSaneLimit(contextLimit) || isSaneLimit(limit)) {
|
|
166920
|
+
map2.set(key, {
|
|
166921
|
+
limit: isSaneLimit(limit) ? limit : undefined,
|
|
166922
|
+
contextLimit: isSaneLimit(contextLimit) ? contextLimit : undefined,
|
|
166923
|
+
inputLimit: isSaneLimit(inputLimit) ? inputLimit : undefined,
|
|
166924
|
+
outputLimit: isFinitePositive(outputLimit) ? outputLimit : undefined,
|
|
166925
|
+
vision
|
|
166926
|
+
});
|
|
166927
|
+
}
|
|
166928
|
+
}
|
|
166929
|
+
if (map2.size > 0) {
|
|
166930
|
+
apiCache = map2;
|
|
166931
|
+
sessionLog("global", `models-dev-cache: seeded ${map2.size} entries from persisted cache (cold start)`);
|
|
166932
|
+
}
|
|
166933
|
+
} catch {}
|
|
166934
|
+
}
|
|
166935
|
+
function isFinitePositive(value) {
|
|
166936
|
+
return typeof value === "number" && Number.isFinite(value) && value > 0;
|
|
166937
|
+
}
|
|
166938
|
+
function modelKeyLookupOrder(providerID, modelID) {
|
|
166939
|
+
const full = `${providerID}/${modelID}`;
|
|
166940
|
+
const canonicalFull = piModelRefToCanonical(full);
|
|
166941
|
+
const candidates = [full, canonicalFull, modelID];
|
|
166942
|
+
const colon = modelID.lastIndexOf(":");
|
|
166943
|
+
if (colon > 0) {
|
|
166944
|
+
const bareModel = modelID.slice(0, colon);
|
|
166945
|
+
const providerBare = `${providerID}/${bareModel}`;
|
|
166946
|
+
candidates.push(providerBare, piModelRefToCanonical(providerBare), bareModel);
|
|
166947
|
+
}
|
|
166948
|
+
return [...new Set(candidates)];
|
|
166949
|
+
}
|
|
166950
|
+
function configuredOutputReserve(config2, providerID, modelID) {
|
|
166951
|
+
if (typeof config2 === "number")
|
|
166952
|
+
return Number.isFinite(config2) && config2 >= 0 ? config2 : undefined;
|
|
166953
|
+
if (!config2)
|
|
166954
|
+
return;
|
|
166955
|
+
for (const candidate of modelKeyLookupOrder(providerID, modelID)) {
|
|
166956
|
+
const value = config2[candidate];
|
|
166957
|
+
if (typeof value === "number" && Number.isFinite(value) && value >= 0)
|
|
166958
|
+
return value;
|
|
166959
|
+
}
|
|
166960
|
+
return Number.isFinite(config2.default) && config2.default >= 0 ? config2.default : undefined;
|
|
166961
|
+
}
|
|
166962
|
+
function logReserveClampOnce(key, message) {
|
|
166963
|
+
if (reserveClampLogSeen.has(key))
|
|
166964
|
+
return;
|
|
166965
|
+
reserveClampLogSeen.add(key);
|
|
166966
|
+
sessionLog("global", `models-dev-cache: ${message}`);
|
|
166967
|
+
}
|
|
166968
|
+
function setOutputReserveConfig(config2) {
|
|
166969
|
+
outputReserveConfig = config2;
|
|
166970
|
+
}
|
|
166971
|
+
function resolveLimit(limit, providerID, modelID, reserveConfig = outputReserveConfig) {
|
|
166972
|
+
if (!limit)
|
|
166973
|
+
return;
|
|
166974
|
+
const context = isFinitePositive(limit.context) ? limit.context : undefined;
|
|
166975
|
+
const input = isFinitePositive(limit.input) ? limit.input : undefined;
|
|
166976
|
+
if (input !== undefined && (context === undefined || input < context))
|
|
166977
|
+
return input;
|
|
166978
|
+
if (context === undefined)
|
|
166979
|
+
return;
|
|
166980
|
+
const configuredReserve = configuredOutputReserve(reserveConfig, providerID, modelID);
|
|
166981
|
+
let reserve;
|
|
166982
|
+
if (configuredReserve !== undefined) {
|
|
166983
|
+
reserve = configuredReserve;
|
|
166984
|
+
} else if (SEPARATE_OUTPUT_QUOTA_PROVIDERS.has(providerID)) {
|
|
166985
|
+
reserve = 0;
|
|
166986
|
+
} else {
|
|
166987
|
+
const output = isFinitePositive(limit.output) ? limit.output : 0;
|
|
166988
|
+
const cap = context * OUTPUT_RESERVE_CAP_RATIO;
|
|
166989
|
+
reserve = Math.min(output, cap);
|
|
166990
|
+
if (output > cap) {
|
|
166991
|
+
logReserveClampOnce(`cap|${providerID}/${modelID}|${context}|${output}`, `output reserve capped at 25% for ${providerID}/${modelID}: ${output} → ${cap}`);
|
|
166992
|
+
}
|
|
166993
|
+
}
|
|
166994
|
+
const floor = Math.max(MIN_PLAUSIBLE_CONTEXT_LIMIT, context * 0.5);
|
|
166995
|
+
const maxReserve = Math.max(0, context - floor);
|
|
166996
|
+
if (reserve > maxReserve) {
|
|
166997
|
+
logReserveClampOnce(`floor|${providerID}/${modelID}|${context}|${reserve}`, `output reserve clamped for ${providerID}/${modelID}: ${reserve} → ${maxReserve} (usable floor ${floor})`);
|
|
166998
|
+
reserve = maxReserve;
|
|
166999
|
+
}
|
|
167000
|
+
return Math.floor(context - reserve);
|
|
167001
|
+
}
|
|
167002
|
+
function getSdkContextLimit(providerID, modelID, detectedContextLimit, options) {
|
|
167003
|
+
loadPersistedApiCacheOnce();
|
|
167004
|
+
const metadata = lookupMetadataWithTagFallback(apiCache, providerID, modelID);
|
|
167005
|
+
if (!metadata)
|
|
167006
|
+
return;
|
|
167007
|
+
const rawContext = metadata.contextLimit ?? metadata.limit;
|
|
167008
|
+
const promptOnlyDetected = options?.detectedLimitProvenance === "prompt_only" && isFinitePositive(detectedContextLimit) ? detectedContextLimit : undefined;
|
|
167009
|
+
const context = promptOnlyDetected === undefined && isFinitePositive(detectedContextLimit) && isFinitePositive(rawContext) ? Math.min(rawContext, detectedContextLimit) : promptOnlyDetected === undefined && isFinitePositive(detectedContextLimit) ? detectedContextLimit : rawContext;
|
|
167010
|
+
const inputCandidates = [metadata.inputLimit, promptOnlyDetected].filter(isFinitePositive);
|
|
167011
|
+
const input = inputCandidates.length > 0 ? Math.min(...inputCandidates) : undefined;
|
|
167012
|
+
return resolveLimit({
|
|
167013
|
+
context,
|
|
167014
|
+
input,
|
|
167015
|
+
output: metadata.outputLimit
|
|
167016
|
+
}, providerID, modelID, options?.reservation === "none" ? 0 : undefined);
|
|
167017
|
+
}
|
|
167018
|
+
function modelSupportsVision(providerID, modelID) {
|
|
167019
|
+
loadPersistedApiCacheOnce();
|
|
167020
|
+
if (!apiCache)
|
|
167021
|
+
return false;
|
|
167022
|
+
const exact = apiCache.get(`${providerID}/${modelID}`);
|
|
167023
|
+
if (exact?.vision === true)
|
|
167024
|
+
return true;
|
|
167025
|
+
const colon = modelID.lastIndexOf(":");
|
|
167026
|
+
return colon > 0 ? apiCache.get(`${providerID}/${modelID.slice(0, colon)}`)?.vision === true : false;
|
|
167027
|
+
}
|
|
167028
|
+
function lookupMetadataWithTagFallback(cache, providerID, modelID) {
|
|
167029
|
+
if (!cache)
|
|
167030
|
+
return;
|
|
167031
|
+
const exact = cache.get(`${providerID}/${modelID}`);
|
|
167032
|
+
if (exact)
|
|
167033
|
+
return exact;
|
|
167034
|
+
const colonIdx = modelID.lastIndexOf(":");
|
|
167035
|
+
if (colonIdx > 0) {
|
|
167036
|
+
return cache.get(`${providerID}/${modelID.slice(0, colonIdx)}`);
|
|
167037
|
+
}
|
|
167038
|
+
return;
|
|
167039
|
+
}
|
|
167040
|
+
|
|
166364
167041
|
// src/config/index.ts
|
|
166365
167042
|
var import_comment_json = __toESM(require_src2(), 1);
|
|
166366
167043
|
function getProjectConfigPaths(cwd) {
|
|
@@ -166379,7 +167056,7 @@ function resolvePiLegacyFallback(sources) {
|
|
|
166379
167056
|
}
|
|
166380
167057
|
function loadConfigFile(path3, scope) {
|
|
166381
167058
|
try {
|
|
166382
|
-
const rawText =
|
|
167059
|
+
const rawText = readFileSync6(path3, "utf-8");
|
|
166383
167060
|
const substituted = substituteConfigVariables({
|
|
166384
167061
|
text: rawText,
|
|
166385
167062
|
configPath: path3,
|
|
@@ -166564,6 +167241,7 @@ function loadPiConfig(opts = {}) {
|
|
|
166564
167241
|
}
|
|
166565
167242
|
}
|
|
166566
167243
|
const parsed = parsePiConfig(rawConfig);
|
|
167244
|
+
setOutputReserveConfig(parsed.config.output_reserve);
|
|
166567
167245
|
warnings.push(...parsed.warnings.map((warning) => `[merged config] ${warning}`));
|
|
166568
167246
|
return {
|
|
166569
167247
|
config: parsed.config,
|
|
@@ -166683,6 +167361,7 @@ function loadPiConfigDetailed(opts = {}) {
|
|
|
166683
167361
|
}
|
|
166684
167362
|
const recoveredTopLevelKeys = [];
|
|
166685
167363
|
const parsed = parsePiConfig(rawConfig, recoveredTopLevelKeys);
|
|
167364
|
+
setOutputReserveConfig(parsed.config.output_reserve);
|
|
166686
167365
|
warnings.push(...parsed.warnings.map((warning) => `[merged config] ${warning}`));
|
|
166687
167366
|
const substitutionFailures = loadedFiles.flatMap(bindSubstitutionFailures);
|
|
166688
167367
|
const userLoaded = loadedFiles.find((loaded) => loaded.scope === "user");
|
|
@@ -166805,9 +167484,6 @@ var existingHashStatements = new WeakMap;
|
|
|
166805
167484
|
var existingHashByProjectStatements = new WeakMap;
|
|
166806
167485
|
var deleteByCompartmentStatements = new WeakMap;
|
|
166807
167486
|
var insertEmbeddingStatements = new WeakMap;
|
|
166808
|
-
var distinctModelStatements = new WeakMap;
|
|
166809
|
-
var clearProjectStatements = new WeakMap;
|
|
166810
|
-
var clearProjectModelStatements = new WeakMap;
|
|
166811
167487
|
var searchRowsStatements = new WeakMap;
|
|
166812
167488
|
var searchRowsByModelStatements = new WeakMap;
|
|
166813
167489
|
var searchPoolProbeStatements = new WeakMap;
|
|
@@ -170074,6 +170750,7 @@ function getEmbeddingProviderIdentity(config2) {
|
|
|
170074
170750
|
throw new Error("Unknown embedding provider");
|
|
170075
170751
|
}
|
|
170076
170752
|
const truncate = config2.provider === "openai-compatible" ? config2.truncate?.trim() : undefined;
|
|
170753
|
+
const localDtype = config2.provider === "local" && config2.local_dtype && config2.local_dtype !== "fp32" ? config2.local_dtype : undefined;
|
|
170077
170754
|
const identityInput = config2.provider === "openai-compatible" ? {
|
|
170078
170755
|
provider: "openai-compatible",
|
|
170079
170756
|
model: config2.model.trim(),
|
|
@@ -170085,7 +170762,8 @@ function getEmbeddingProviderIdentity(config2) {
|
|
|
170085
170762
|
provider: "local",
|
|
170086
170763
|
model: config2.model?.trim() || DEFAULT_LOCAL_EMBEDDING_MODEL,
|
|
170087
170764
|
endpoint: "",
|
|
170088
|
-
apiKeyPresent: false
|
|
170765
|
+
apiKeyPresent: false,
|
|
170766
|
+
...localDtype ? { localDtype } : {}
|
|
170089
170767
|
};
|
|
170090
170768
|
return `embedding-provider:${computeNormalizedHash(JSON.stringify(identityInput))}`;
|
|
170091
170769
|
}
|
|
@@ -170173,6 +170851,7 @@ async function injectWasmOrtForElectron() {
|
|
|
170173
170851
|
return false;
|
|
170174
170852
|
}
|
|
170175
170853
|
}
|
|
170854
|
+
var DEFAULT_LOCAL_DTYPE = "fp32";
|
|
170176
170855
|
async function withQuietConsole(fn) {
|
|
170177
170856
|
const origWarn = console.warn;
|
|
170178
170857
|
const origError = console.error;
|
|
@@ -170249,16 +170928,22 @@ class LocalEmbeddingProvider {
|
|
|
170249
170928
|
modelId;
|
|
170250
170929
|
maxInputTokens;
|
|
170251
170930
|
model;
|
|
170931
|
+
dtype;
|
|
170252
170932
|
pipeline = null;
|
|
170253
170933
|
initPromise = null;
|
|
170254
170934
|
inFlight = 0;
|
|
170255
170935
|
disposing = false;
|
|
170256
170936
|
disposePromise = null;
|
|
170257
170937
|
inFlightWaiters = [];
|
|
170258
|
-
constructor(model = DEFAULT_LOCAL_EMBEDDING_MODEL, maxInputTokens = 512) {
|
|
170938
|
+
constructor(model = DEFAULT_LOCAL_EMBEDDING_MODEL, maxInputTokens = 512, dtype = DEFAULT_LOCAL_DTYPE) {
|
|
170259
170939
|
this.model = model;
|
|
170260
170940
|
this.maxInputTokens = maxInputTokens;
|
|
170261
|
-
this.
|
|
170941
|
+
this.dtype = dtype || DEFAULT_LOCAL_DTYPE;
|
|
170942
|
+
this.modelId = getEmbeddingProviderIdentity({
|
|
170943
|
+
provider: "local",
|
|
170944
|
+
model,
|
|
170945
|
+
...dtype && dtype !== DEFAULT_LOCAL_DTYPE ? { local_dtype: dtype } : {}
|
|
170946
|
+
});
|
|
170262
170947
|
}
|
|
170263
170948
|
async initialize() {
|
|
170264
170949
|
if (this.disposing) {
|
|
@@ -170289,11 +170974,15 @@ class LocalEmbeddingProvider {
|
|
|
170289
170974
|
}
|
|
170290
170975
|
const modelCacheDir = join6(getMagicContextStorageDir(), "models");
|
|
170291
170976
|
try {
|
|
170292
|
-
|
|
170293
|
-
|
|
170294
|
-
|
|
170295
|
-
|
|
170296
|
-
|
|
170977
|
+
if (shouldEnforcePrivateStoragePermissions()) {
|
|
170978
|
+
mkdirSync4(modelCacheDir, { recursive: true, mode: 448 });
|
|
170979
|
+
if (process.platform !== "win32") {
|
|
170980
|
+
try {
|
|
170981
|
+
chmodSync2(modelCacheDir, 448);
|
|
170982
|
+
} catch {}
|
|
170983
|
+
}
|
|
170984
|
+
} else {
|
|
170985
|
+
mkdirSync4(modelCacheDir, { recursive: true });
|
|
170297
170986
|
}
|
|
170298
170987
|
env.cacheDir = modelCacheDir;
|
|
170299
170988
|
} catch {
|
|
@@ -170309,7 +170998,7 @@ class LocalEmbeddingProvider {
|
|
|
170309
170998
|
for (let attempt = 1;attempt <= MAX_ATTEMPTS; attempt++) {
|
|
170310
170999
|
try {
|
|
170311
171000
|
const pipeline = await withQuietConsole(() => createPipeline("feature-extraction", this.model, {
|
|
170312
|
-
dtype:
|
|
171001
|
+
dtype: this.dtype,
|
|
170313
171002
|
...injectedWasmOrt ? { device: "auto" } : {}
|
|
170314
171003
|
}));
|
|
170315
171004
|
if (this.disposing) {
|
|
@@ -170781,9 +171470,6 @@ var saveStatements = new WeakMap;
|
|
|
170781
171470
|
var loadProjectStatements = new WeakMap;
|
|
170782
171471
|
var loadUnembeddedStatements = new WeakMap;
|
|
170783
171472
|
var countEmbeddedStatements = new WeakMap;
|
|
170784
|
-
var clearProjectStatements2 = new WeakMap;
|
|
170785
|
-
var clearProjectModelStatements2 = new WeakMap;
|
|
170786
|
-
var distinctModelIdStatements = new WeakMap;
|
|
170787
171473
|
function getSaveStatement(db) {
|
|
170788
171474
|
let stmt = saveStatements.get(db);
|
|
170789
171475
|
if (!stmt) {
|
|
@@ -170854,7 +171540,6 @@ function countEmbeddedCommits(db, projectPath, modelId) {
|
|
|
170854
171540
|
var insertStatements = new WeakMap;
|
|
170855
171541
|
var existingShasStatements = new WeakMap;
|
|
170856
171542
|
var projectCountStatements = new WeakMap;
|
|
170857
|
-
var evictStatements = new WeakMap;
|
|
170858
171543
|
var evictOverflowStatements = new WeakMap;
|
|
170859
171544
|
var latestCommitTimeStatements = new WeakMap;
|
|
170860
171545
|
function getInsertStatement(db) {
|
|
@@ -171103,7 +171788,6 @@ var deleteEmbeddingStatements = new WeakMap;
|
|
|
171103
171788
|
var getStoredModelIdStatements = new WeakMap;
|
|
171104
171789
|
var clearAllEmbeddingsStatements = new WeakMap;
|
|
171105
171790
|
var clearModelEmbeddingsStatements = new WeakMap;
|
|
171106
|
-
var getDistinctStoredModelIdsStatements = new WeakMap;
|
|
171107
171791
|
function isEmbeddingBlob(value) {
|
|
171108
171792
|
return value instanceof Uint8Array || value instanceof ArrayBuffer;
|
|
171109
171793
|
}
|
|
@@ -171331,6 +172015,9 @@ var shadowWorker = null;
|
|
|
171331
172015
|
var SHADOW_MAX_ITEMS_PER_TICK = 64;
|
|
171332
172016
|
var SHADOW_MAX_BYTES_PER_TICK = 512 * 1024;
|
|
171333
172017
|
var SHADOW_MAX_WALL_CLOCK_MS = 2000;
|
|
172018
|
+
var pendingShadowBackfills = new Map;
|
|
172019
|
+
var shadowBackfillLastIds = new Map;
|
|
172020
|
+
var shadowBackfillStopReasons = new Map;
|
|
171334
172021
|
var loadUnembeddedMemoriesStatements = new WeakMap;
|
|
171335
172022
|
var upsertActiveIdentityStatements = new WeakMap;
|
|
171336
172023
|
var backfillActiveIdentityStatements = new Map;
|
|
@@ -171378,7 +172065,8 @@ function resolveEmbeddingConfig(config2) {
|
|
|
171378
172065
|
model: config2?.model?.trim() || DEFAULT_LOCAL_EMBEDDING_MODEL,
|
|
171379
172066
|
...config2?.max_input_tokens ? {
|
|
171380
172067
|
max_input_tokens: normalizeCompartmentChunkMaxInputTokens(config2.max_input_tokens)
|
|
171381
|
-
} : {}
|
|
172068
|
+
} : {},
|
|
172069
|
+
...config2?.local_dtype ? { local_dtype: config2.local_dtype } : {}
|
|
171382
172070
|
};
|
|
171383
172071
|
}
|
|
171384
172072
|
if (config2.provider === "openai-compatible") {
|
|
@@ -171437,7 +172125,7 @@ function createProvider(config2, context) {
|
|
|
171437
172125
|
});
|
|
171438
172126
|
}
|
|
171439
172127
|
if (config2.provider === "local") {
|
|
171440
|
-
return new LocalEmbeddingProvider(config2.model, config2.max_input_tokens);
|
|
172128
|
+
return new LocalEmbeddingProvider(config2.model, config2.max_input_tokens, config2.local_dtype);
|
|
171441
172129
|
}
|
|
171442
172130
|
if (config2.provider === "synapse") {
|
|
171443
172131
|
const synapse = config2;
|
|
@@ -171777,7 +172465,7 @@ function startShadowWorker() {
|
|
|
171777
172465
|
return;
|
|
171778
172466
|
shadowWorker = runShadowWorker().finally(() => {
|
|
171779
172467
|
shadowWorker = null;
|
|
171780
|
-
if (shadowQueue.length > 0)
|
|
172468
|
+
if (shadowQueue.length > 0 || hasPendingShadowBackfill())
|
|
171781
172469
|
startShadowWorker();
|
|
171782
172470
|
});
|
|
171783
172471
|
}
|
|
@@ -171824,6 +172512,95 @@ function enqueueShadowEmbeddingItems(projectIdentity, scope, ids) {
|
|
|
171824
172512
|
shadowQueue.push({ projectIdentity, scope, ids: [...ids] });
|
|
171825
172513
|
startShadowWorker();
|
|
171826
172514
|
}
|
|
172515
|
+
function shadowBackfillMissingBase(scope, primaryModelId, shadowModelId, projectIdentity) {
|
|
172516
|
+
if (scope === "memory") {
|
|
172517
|
+
return {
|
|
172518
|
+
sql: `SELECT m.id AS id
|
|
172519
|
+
FROM memories m
|
|
172520
|
+
JOIN memory_embeddings mp ON mp.memory_id = m.id AND mp.model_id = ?
|
|
172521
|
+
LEFT JOIN memory_embeddings ms ON ms.memory_id = m.id AND ms.model_id = ?
|
|
172522
|
+
WHERE m.project_path = ? AND m.status = 'active' AND ms.memory_id IS NULL`,
|
|
172523
|
+
params: [primaryModelId, shadowModelId, projectIdentity],
|
|
172524
|
+
orderBy: " ORDER BY m.id"
|
|
172525
|
+
};
|
|
172526
|
+
}
|
|
172527
|
+
if (scope === "commit") {
|
|
172528
|
+
return {
|
|
172529
|
+
sql: `SELECT gc.sha AS id
|
|
172530
|
+
FROM git_commits gc
|
|
172531
|
+
JOIN git_commit_embeddings gp ON gp.sha = gc.sha AND gp.model_id = ?
|
|
172532
|
+
LEFT JOIN git_commit_embeddings gs ON gs.sha = gc.sha AND gs.model_id = ?
|
|
172533
|
+
WHERE gc.project_path = ? AND gs.sha IS NULL`,
|
|
172534
|
+
params: [primaryModelId, shadowModelId, projectIdentity],
|
|
172535
|
+
orderBy: " ORDER BY gc.committed_at DESC, gc.sha"
|
|
172536
|
+
};
|
|
172537
|
+
}
|
|
172538
|
+
return {
|
|
172539
|
+
sql: `SELECT DISTINCT cp.compartment_id AS id
|
|
172540
|
+
FROM compartment_chunk_embeddings cp
|
|
172541
|
+
WHERE cp.project_path = ? AND cp.model_id = ?
|
|
172542
|
+
AND NOT EXISTS (
|
|
172543
|
+
SELECT 1 FROM compartment_chunk_embeddings cs
|
|
172544
|
+
WHERE cs.compartment_id = cp.compartment_id AND cs.model_id = ?
|
|
172545
|
+
)`,
|
|
172546
|
+
params: [projectIdentity, primaryModelId, shadowModelId],
|
|
172547
|
+
orderBy: " ORDER BY cp.compartment_id"
|
|
172548
|
+
};
|
|
172549
|
+
}
|
|
172550
|
+
function shadowBackfillMissingIds(db, projectIdentity, scope, primaryModelId, shadowModelId, limit) {
|
|
172551
|
+
const { sql, params, orderBy } = shadowBackfillMissingBase(scope, primaryModelId, shadowModelId, projectIdentity);
|
|
172552
|
+
const rows = db.prepare(`${sql}${orderBy} LIMIT ?`).all(...params, limit);
|
|
172553
|
+
return rows.map((row) => String(row.id));
|
|
172554
|
+
}
|
|
172555
|
+
function shadowModelIdForScope(registration, scope) {
|
|
172556
|
+
return scope === "chunk" ? registration.chunkModelId : registration.modelId;
|
|
172557
|
+
}
|
|
172558
|
+
function hasPendingShadowBackfill(projectIdentity) {
|
|
172559
|
+
if (projectIdentity === undefined)
|
|
172560
|
+
return pendingShadowBackfills.size > 0;
|
|
172561
|
+
const scopes = pendingShadowBackfills.get(projectIdentity);
|
|
172562
|
+
return scopes !== undefined && scopes.size > 0;
|
|
172563
|
+
}
|
|
172564
|
+
function pumpShadowBackfill() {
|
|
172565
|
+
for (const [projectIdentity, scopes] of pendingShadowBackfills) {
|
|
172566
|
+
const db = dbForShadowQueue.get(projectIdentity);
|
|
172567
|
+
const shadow = shadowRegistrations.get(projectIdentity);
|
|
172568
|
+
const primary = projectRegistrations.get(projectIdentity);
|
|
172569
|
+
if (!db || !shadow || !primary) {
|
|
172570
|
+
pendingShadowBackfills.delete(projectIdentity);
|
|
172571
|
+
continue;
|
|
172572
|
+
}
|
|
172573
|
+
for (const scope of [...scopes]) {
|
|
172574
|
+
const primaryModelId = shadowModelIdForScope(primary, scope);
|
|
172575
|
+
const shadowModelId = shadowModelIdForScope(shadow, scope);
|
|
172576
|
+
const stallKey = `${projectIdentity}:${scope}`;
|
|
172577
|
+
if (primaryModelId === "off" || shadowModelId === "off") {
|
|
172578
|
+
scopes.delete(scope);
|
|
172579
|
+
shadowBackfillLastIds.delete(stallKey);
|
|
172580
|
+
continue;
|
|
172581
|
+
}
|
|
172582
|
+
const ids = shadowBackfillMissingIds(db, projectIdentity, scope, primaryModelId, shadowModelId, SHADOW_MAX_ITEMS_PER_TICK);
|
|
172583
|
+
if (ids.length === 0) {
|
|
172584
|
+
shadowBackfillStopReasons.set(stallKey, "drained");
|
|
172585
|
+
scopes.delete(scope);
|
|
172586
|
+
shadowBackfillLastIds.delete(stallKey);
|
|
172587
|
+
continue;
|
|
172588
|
+
}
|
|
172589
|
+
const signature = ids.join(",");
|
|
172590
|
+
if (shadowBackfillLastIds.get(stallKey) === signature) {
|
|
172591
|
+
shadowBackfillStopReasons.set(stallKey, "stalled_no_progress");
|
|
172592
|
+
log(`[shadow] backfill scope ${scope} for ${projectIdentity} retired without progress — ` + `the last batch produced no writes (provider failure or timeout is the usual cause); ` + `${ids.length}+ items remain and retry on the next registration or manual --shadow run`);
|
|
172593
|
+
scopes.delete(scope);
|
|
172594
|
+
shadowBackfillLastIds.delete(stallKey);
|
|
172595
|
+
continue;
|
|
172596
|
+
}
|
|
172597
|
+
shadowBackfillLastIds.set(stallKey, signature);
|
|
172598
|
+
shadowQueue.push({ projectIdentity, scope, ids });
|
|
172599
|
+
}
|
|
172600
|
+
if (scopes.size === 0)
|
|
172601
|
+
pendingShadowBackfills.delete(projectIdentity);
|
|
172602
|
+
}
|
|
172603
|
+
}
|
|
171827
172604
|
async function embedShadowItems(registration, items, db, scope) {
|
|
171828
172605
|
const raw = registration.config;
|
|
171829
172606
|
const fingerprint = typeof raw.synapse_fingerprint === "string" ? raw.synapse_fingerprint : "";
|
|
@@ -171947,7 +172724,15 @@ async function runShadowWorker() {
|
|
|
171947
172724
|
const startedAt = Date.now();
|
|
171948
172725
|
let processed = 0;
|
|
171949
172726
|
let processedBytes = 0;
|
|
171950
|
-
|
|
172727
|
+
for (;; ) {
|
|
172728
|
+
if (shadowQueue.length === 0) {
|
|
172729
|
+
pumpShadowBackfill();
|
|
172730
|
+
if (shadowQueue.length === 0)
|
|
172731
|
+
break;
|
|
172732
|
+
}
|
|
172733
|
+
if (processed >= SHADOW_MAX_ITEMS_PER_TICK || Date.now() - startedAt >= SHADOW_MAX_WALL_CLOCK_MS) {
|
|
172734
|
+
break;
|
|
172735
|
+
}
|
|
171951
172736
|
const item = shadowQueue.shift();
|
|
171952
172737
|
if (!item)
|
|
171953
172738
|
break;
|
|
@@ -172483,7 +173268,7 @@ function createProvider2(config2) {
|
|
|
172483
173268
|
});
|
|
172484
173269
|
}
|
|
172485
173270
|
if (config2.provider === "local") {
|
|
172486
|
-
return new LocalEmbeddingProvider(config2.model, config2.max_input_tokens);
|
|
173271
|
+
return new LocalEmbeddingProvider(config2.model, config2.max_input_tokens, config2.local_dtype);
|
|
172487
173272
|
}
|
|
172488
173273
|
if (config2.provider === "synapse") {
|
|
172489
173274
|
const synapse = config2;
|
|
@@ -172660,7 +173445,8 @@ function configFingerprint(paths) {
|
|
|
172660
173445
|
}).join("|");
|
|
172661
173446
|
}
|
|
172662
173447
|
async function ensureProjectRegisteredFromPiDirectory(directory, db) {
|
|
172663
|
-
const
|
|
173448
|
+
const detailed = loadPiConfigDetailed({ cwd: directory });
|
|
173449
|
+
const projectIdentity = resolveProjectIdentityForSession(directory, detailed.config.allow_home_project);
|
|
172664
173450
|
if (!projectIdentity)
|
|
172665
173451
|
return;
|
|
172666
173452
|
let registrationFingerprints = registrationFingerprintsByDatabase.get(db);
|
|
@@ -172671,7 +173457,6 @@ async function ensureProjectRegisteredFromPiDirectory(directory, db) {
|
|
|
172671
173457
|
const cached2 = registrationFingerprints.get(projectIdentity);
|
|
172672
173458
|
if (cached2 && configFingerprint(cached2.paths) === cached2.fingerprint)
|
|
172673
173459
|
return;
|
|
172674
|
-
const detailed = loadPiConfigDetailed({ cwd: directory });
|
|
172675
173460
|
if (isConfigLoadUntrusted(detailed)) {
|
|
172676
173461
|
handleUntrustedLoad(db, projectIdentity, directory, detailed);
|
|
172677
173462
|
return;
|
|
@@ -178182,7 +178967,6 @@ class ModuleMemoryAuthorityError extends Error {
|
|
|
178182
178967
|
}
|
|
178183
178968
|
}
|
|
178184
178969
|
function assertTsMemoryWriteAllowed(db, projectPath) {
|
|
178185
|
-
registerPrivilegedWriter(db);
|
|
178186
178970
|
try {
|
|
178187
178971
|
const managed = db.prepare("SELECT 1 FROM authority_managed WHERE project_path = ? UNION SELECT 1 FROM authority_repair_pending WHERE project_path = ? LIMIT 1").get(projectPath, projectPath);
|
|
178188
178972
|
if (managed)
|
|
@@ -179104,6 +179888,7 @@ function queueEmbedding(args) {
|
|
|
179104
179888
|
}
|
|
179105
179889
|
function createCtxMemoryTool(deps) {
|
|
179106
179890
|
const dreamerAllowed = deps.allowDreamerActions === true;
|
|
179891
|
+
const resolveProject = deps.resolveProjectIdentity ?? resolveProjectIdentityForSession;
|
|
179107
179892
|
const description = dreamerAllowed ? `${CTX_MEMORY_DESCRIPTION}
|
|
179108
179893
|
- list: enumerate stored memories (maintenance sessions).` : CTX_MEMORY_DESCRIPTION;
|
|
179109
179894
|
return {
|
|
@@ -179126,7 +179911,7 @@ function createCtxMemoryTool(deps) {
|
|
|
179126
179911
|
if (!dreamerAllowed && DREAMER_ONLY_ACTIONS.has(params.action)) {
|
|
179127
179912
|
return err2(`Error: Action '${params.action}' is not allowed in this context.`);
|
|
179128
179913
|
}
|
|
179129
|
-
const projectIdentity =
|
|
179914
|
+
const projectIdentity = resolveProject(ctx.cwd);
|
|
179130
179915
|
if (!projectIdentity) {
|
|
179131
179916
|
return err2("Error: Could not resolve project identity for memory action.");
|
|
179132
179917
|
}
|
|
@@ -179496,6 +180281,7 @@ function paginateNewestFirst(notes, limit, offset) {
|
|
|
179496
180281
|
return { page, total, footer };
|
|
179497
180282
|
}
|
|
179498
180283
|
function createCtxNoteTool(deps) {
|
|
180284
|
+
const resolveProject = deps.resolveProjectIdentity ?? resolveProjectIdentityForSession;
|
|
179499
180285
|
return {
|
|
179500
180286
|
name: "ctx_note",
|
|
179501
180287
|
label: "Magic Context: Notes",
|
|
@@ -179527,7 +180313,7 @@ function createCtxNoteTool(deps) {
|
|
|
179527
180313
|
if (dreamerEnabled !== true) {
|
|
179528
180314
|
return err3("Error: Smart notes require dreamer to be enabled. Enable dreamer in magic-context.jsonc to use surface_condition.");
|
|
179529
180315
|
}
|
|
179530
|
-
const projectIdentity =
|
|
180316
|
+
const projectIdentity = resolveProject(ctx.cwd);
|
|
179531
180317
|
if (!projectIdentity) {
|
|
179532
180318
|
return err3("Error: Could not resolve project identity for smart note.");
|
|
179533
180319
|
}
|
|
@@ -179553,7 +180339,7 @@ function createCtxNoteTool(deps) {
|
|
|
179553
180339
|
if (typeof params.note_id !== "number") {
|
|
179554
180340
|
return err3("Error: 'note_id' is required when action is 'dismiss'.");
|
|
179555
180341
|
}
|
|
179556
|
-
const projectIdentity =
|
|
180342
|
+
const projectIdentity = resolveProject(ctx.cwd);
|
|
179557
180343
|
if (!projectIdentity) {
|
|
179558
180344
|
return err3("Error: Could not resolve project identity for note dismiss.");
|
|
179559
180345
|
}
|
|
@@ -179575,7 +180361,7 @@ function createCtxNoteTool(deps) {
|
|
|
179575
180361
|
if (!updates.content && !updates.surfaceCondition) {
|
|
179576
180362
|
return err3("Error: Provide 'content' and/or 'surface_condition' to update.");
|
|
179577
180363
|
}
|
|
179578
|
-
const projectIdentity =
|
|
180364
|
+
const projectIdentity = resolveProject(ctx.cwd);
|
|
179579
180365
|
if (!projectIdentity) {
|
|
179580
180366
|
return err3("Error: Could not resolve project identity for note update.");
|
|
179581
180367
|
}
|
|
@@ -179601,6 +180387,7 @@ function createCtxNoteTool(deps) {
|
|
|
179601
180387
|
db: deps.db,
|
|
179602
180388
|
sessionId,
|
|
179603
180389
|
cwd: ctx.cwd,
|
|
180390
|
+
resolveProjectIdentity: resolveProject,
|
|
179604
180391
|
filter: params.filter,
|
|
179605
180392
|
limit,
|
|
179606
180393
|
offset
|
|
@@ -179624,7 +180411,7 @@ No session notes or smart notes.`);
|
|
|
179624
180411
|
};
|
|
179625
180412
|
}
|
|
179626
180413
|
function readNotes(args) {
|
|
179627
|
-
const projectIdentity =
|
|
180414
|
+
const projectIdentity = args.resolveProjectIdentity(args.cwd);
|
|
179628
180415
|
if (args.filter === undefined) {
|
|
179629
180416
|
const sessionNotes2 = getNotes(args.db, {
|
|
179630
180417
|
sessionId: args.sessionId,
|
|
@@ -181357,32 +182144,6 @@ async function unifiedSearch(db, sessionId, projectPath, query, options = {}) {
|
|
|
181357
182144
|
// ../plugin/src/features/magic-context/mural/render-trigger.ts
|
|
181358
182145
|
import { createHash as createHash15 } from "node:crypto";
|
|
181359
182146
|
|
|
181360
|
-
// ../plugin/src/shared/harness-provider-map.ts
|
|
181361
|
-
var CANONICAL_TO_PI_PROVIDER = {
|
|
181362
|
-
openai: "openai-codex",
|
|
181363
|
-
google: "google-antigravity"
|
|
181364
|
-
};
|
|
181365
|
-
var PI_TO_CANONICAL_PROVIDER = {
|
|
181366
|
-
"openai-codex": "openai",
|
|
181367
|
-
"google-antigravity": "google"
|
|
181368
|
-
};
|
|
181369
|
-
function remapProviderPrefix(ref3, map2) {
|
|
181370
|
-
if (typeof ref3 !== "string")
|
|
181371
|
-
return ref3;
|
|
181372
|
-
const slash = ref3.indexOf("/");
|
|
181373
|
-
if (slash <= 0)
|
|
181374
|
-
return ref3;
|
|
181375
|
-
const provider2 = ref3.slice(0, slash);
|
|
181376
|
-
const mapped3 = map2[provider2];
|
|
181377
|
-
return mapped3 ? `${mapped3}${ref3.slice(slash)}` : ref3;
|
|
181378
|
-
}
|
|
181379
|
-
function piModelRefToCanonical(ref3) {
|
|
181380
|
-
return remapProviderPrefix(ref3, PI_TO_CANONICAL_PROVIDER);
|
|
181381
|
-
}
|
|
181382
|
-
function resolveModelRefForPi(ref3) {
|
|
181383
|
-
return remapProviderPrefix(piModelRefToCanonical(ref3), CANONICAL_TO_PI_PROVIDER);
|
|
181384
|
-
}
|
|
181385
|
-
|
|
181386
182147
|
// ../plugin/src/features/magic-context/mural/mural-selection.ts
|
|
181387
182148
|
var DEFAULT_MURAL_MEMORY_BUDGET = 8000;
|
|
181388
182149
|
function muralOverflowMemories(memories, budgetTokens = DEFAULT_MURAL_MEMORY_BUDGET) {
|
|
@@ -181584,6 +182345,8 @@ function naturalLineLengths(entries, roomWidth) {
|
|
|
181584
182345
|
let currentCategory = null;
|
|
181585
182346
|
for (let index = 0;index < entries.length; index++) {
|
|
181586
182347
|
const entry = entries[index];
|
|
182348
|
+
if (!entry)
|
|
182349
|
+
continue;
|
|
181587
182350
|
if (entry.category !== currentCategory) {
|
|
181588
182351
|
currentCategory = entry.category;
|
|
181589
182352
|
lengths.push(codepoints(` <${entry.category}> `));
|
|
@@ -181616,6 +182379,8 @@ function planLines(entries, roomWidth) {
|
|
|
181616
182379
|
let currentCategory = null;
|
|
181617
182380
|
for (let index = 0;index < entries.length; index++) {
|
|
181618
182381
|
const entry = entries[index];
|
|
182382
|
+
if (!entry)
|
|
182383
|
+
continue;
|
|
181619
182384
|
if (entry.category !== currentCategory) {
|
|
181620
182385
|
currentCategory = entry.category;
|
|
181621
182386
|
lines.push({
|
|
@@ -181679,8 +182444,11 @@ function renderLayout(entries, plan, roomWidth, columnCount) {
|
|
|
181679
182444
|
const usage = {};
|
|
181680
182445
|
let filledLineCount = 0;
|
|
181681
182446
|
for (const [column, columnPlan] of splitPlan(plan, columnCount).entries()) {
|
|
182447
|
+
const columnGrid = grid[column];
|
|
182448
|
+
if (!columnGrid)
|
|
182449
|
+
continue;
|
|
181682
182450
|
for (const [row, line] of columnPlan.entries()) {
|
|
181683
|
-
|
|
182451
|
+
columnGrid[row] = line.text;
|
|
181684
182452
|
filledLineCount += 1;
|
|
181685
182453
|
usage[line.category] = (usage[line.category] ?? 0) + 1;
|
|
181686
182454
|
const placementLine = row + 1;
|
|
@@ -181791,6 +182559,7 @@ function glyph(character) {
|
|
|
181791
182559
|
}
|
|
181792
182560
|
function drawGlyph(pixels, width, height, x, y, character, color) {
|
|
181793
182561
|
const glyphData = glyph(character);
|
|
182562
|
+
const [red, green, blue] = color;
|
|
181794
182563
|
for (let row = 0;row < MURAL_CELL_HEIGHT; row++) {
|
|
181795
182564
|
const pattern2 = glyphData.rows[row] ?? 0;
|
|
181796
182565
|
for (let column = 0;column < glyphData.width; column++) {
|
|
@@ -181801,9 +182570,9 @@ function drawGlyph(pixels, width, height, x, y, character, color) {
|
|
|
181801
182570
|
if (px < 0 || py < 0 || px >= width || py >= height)
|
|
181802
182571
|
continue;
|
|
181803
182572
|
const offset = (py * width + px) * 3;
|
|
181804
|
-
pixels[offset] =
|
|
181805
|
-
pixels[offset + 1] =
|
|
181806
|
-
pixels[offset + 2] =
|
|
182573
|
+
pixels[offset] = red;
|
|
182574
|
+
pixels[offset + 1] = green;
|
|
182575
|
+
pixels[offset + 2] = blue;
|
|
181807
182576
|
}
|
|
181808
182577
|
}
|
|
181809
182578
|
}
|
|
@@ -181815,6 +182584,7 @@ function drawText(pixels, width, height, x, y, text, color) {
|
|
|
181815
182584
|
}
|
|
181816
182585
|
}
|
|
181817
182586
|
function fillRect(pixels, canvasWidth, canvasHeight, x, y, width, height, color) {
|
|
182587
|
+
const [red, green, blue] = color;
|
|
181818
182588
|
const left = Math.max(0, x);
|
|
181819
182589
|
const top = Math.max(0, y);
|
|
181820
182590
|
const right = Math.min(canvasWidth, x + width);
|
|
@@ -181822,9 +182592,9 @@ function fillRect(pixels, canvasWidth, canvasHeight, x, y, width, height, color)
|
|
|
181822
182592
|
for (let py = top;py < bottom; py++) {
|
|
181823
182593
|
for (let px = left;px < right; px++) {
|
|
181824
182594
|
const offset = (py * canvasWidth + px) * 3;
|
|
181825
|
-
pixels[offset] =
|
|
181826
|
-
pixels[offset + 1] =
|
|
181827
|
-
pixels[offset + 2] =
|
|
182595
|
+
pixels[offset] = red;
|
|
182596
|
+
pixels[offset + 1] = green;
|
|
182597
|
+
pixels[offset + 2] = blue;
|
|
181828
182598
|
}
|
|
181829
182599
|
}
|
|
181830
182600
|
}
|
|
@@ -181851,6 +182621,9 @@ function renderMural(entries) {
|
|
|
181851
182621
|
});
|
|
181852
182622
|
const fittingCandidates = candidates2.filter((candidate) => candidate.layout.droppedIds.length === 0);
|
|
181853
182623
|
const candidatesToCompare = fittingCandidates.length > 0 ? fittingCandidates : candidates2;
|
|
182624
|
+
const firstCandidate = candidatesToCompare[0];
|
|
182625
|
+
if (!firstCandidate)
|
|
182626
|
+
throw new Error("mural layout candidate list is empty");
|
|
181854
182627
|
const selected = candidatesToCompare.reduce((best, candidate) => {
|
|
181855
182628
|
if (!best)
|
|
181856
182629
|
return candidate;
|
|
@@ -181861,7 +182634,7 @@ function renderMural(entries) {
|
|
|
181861
182634
|
return candidate.tileArea < best.tileArea ? candidate : best;
|
|
181862
182635
|
}
|
|
181863
182636
|
return candidate.requestedColumnCount < best.requestedColumnCount ? candidate : best;
|
|
181864
|
-
},
|
|
182637
|
+
}, firstCandidate);
|
|
181865
182638
|
const { layout, width, height } = selected;
|
|
181866
182639
|
const pixels = new Uint8Array(width * height * 3).fill(255);
|
|
181867
182640
|
const contentWidth = layout.columnCount === 0 ? 0 : layout.columnCount * roomWidth * MURAL_CELL_WIDTH + MURAL_COLUMN_GAP * (layout.columnCount - 1) * MURAL_CELL_WIDTH;
|
|
@@ -182161,6 +182934,353 @@ class BoundedSessionMap {
|
|
|
182161
182934
|
}
|
|
182162
182935
|
}
|
|
182163
182936
|
|
|
182937
|
+
// ../plugin/src/features/magic-context/compaction-marker.ts
|
|
182938
|
+
import { createHash as createHash16 } from "node:crypto";
|
|
182939
|
+
import { existsSync as existsSync9 } from "node:fs";
|
|
182940
|
+
import { join as join7 } from "node:path";
|
|
182941
|
+
var BASE62_CHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
|
182942
|
+
var ID_PREFIX_HEX_LENGTH = 12;
|
|
182943
|
+
var ID_SUFFIX_LENGTH = 14;
|
|
182944
|
+
var ID_PREFIX_MASK = (1n << BigInt(ID_PREFIX_HEX_LENGTH * 4)) - 1n;
|
|
182945
|
+
function deterministicBase62(seed, length) {
|
|
182946
|
+
let value = BigInt(`0x${createHash16("sha256").update(seed).digest("hex")}`);
|
|
182947
|
+
const chars = Array(length);
|
|
182948
|
+
for (let index = length - 1;index >= 0; index -= 1) {
|
|
182949
|
+
chars[index] = BASE62_CHARS[Number(value % 62n)];
|
|
182950
|
+
value /= 62n;
|
|
182951
|
+
}
|
|
182952
|
+
return chars.join("");
|
|
182953
|
+
}
|
|
182954
|
+
function generateId(prefix, timestampMs, counter, identity) {
|
|
182955
|
+
const encoded = BigInt(Math.max(0, Math.floor(timestampMs))) * 0x1000n + counter & ID_PREFIX_MASK;
|
|
182956
|
+
const hex3 = encoded.toString(16).padStart(ID_PREFIX_HEX_LENGTH, "0");
|
|
182957
|
+
return `${prefix}_${hex3}${deterministicBase62(`${prefix}\x00${identity}`, ID_SUFFIX_LENGTH)}`;
|
|
182958
|
+
}
|
|
182959
|
+
function generateMessageId(timestampMs, counter = 0n, identity = "") {
|
|
182960
|
+
return generateId("msg", timestampMs, counter, identity);
|
|
182961
|
+
}
|
|
182962
|
+
function generatePartId(timestampMs, counter = 0n, identity = "") {
|
|
182963
|
+
return generateId("prt", timestampMs, counter, identity);
|
|
182964
|
+
}
|
|
182965
|
+
function getOpenCodeDbPath2() {
|
|
182966
|
+
return join7(getDataDir(), "opencode", "opencode.db");
|
|
182967
|
+
}
|
|
182968
|
+
var cachedWriteDb = null;
|
|
182969
|
+
var REQUIRED_MESSAGE_COLUMNS = ["id", "session_id", "time_created", "time_updated", "data"];
|
|
182970
|
+
var REQUIRED_PART_COLUMNS = [
|
|
182971
|
+
"id",
|
|
182972
|
+
"message_id",
|
|
182973
|
+
"session_id",
|
|
182974
|
+
"time_created",
|
|
182975
|
+
"time_updated",
|
|
182976
|
+
"data"
|
|
182977
|
+
];
|
|
182978
|
+
var cachedSchemaCompatible = null;
|
|
182979
|
+
function isOpenCodeSchemaCompatible(db, dbPath) {
|
|
182980
|
+
if (cachedSchemaCompatible?.path === dbPath) {
|
|
182981
|
+
return cachedSchemaCompatible.compatible;
|
|
182982
|
+
}
|
|
182983
|
+
try {
|
|
182984
|
+
const messageCols = new Set(db.prepare("PRAGMA table_info(message)").all().map((r) => r.name ?? "").filter((n) => n.length > 0));
|
|
182985
|
+
const partCols = new Set(db.prepare("PRAGMA table_info(part)").all().map((r) => r.name ?? "").filter((n) => n.length > 0));
|
|
182986
|
+
const missingMessage = REQUIRED_MESSAGE_COLUMNS.filter((c) => !messageCols.has(c));
|
|
182987
|
+
const missingPart = REQUIRED_PART_COLUMNS.filter((c) => !partCols.has(c));
|
|
182988
|
+
if (missingMessage.length > 0 || missingPart.length > 0) {
|
|
182989
|
+
log(`[magic-context] compaction-marker: OpenCode DB schema missing required columns ` + `(message: [${missingMessage.join(", ")}], part: [${missingPart.join(", ")}]). ` + `Marker injection disabled for this process. ` + `This usually means OpenCode was updated and magic-context is out of date.`);
|
|
182990
|
+
cachedSchemaCompatible = { path: dbPath, compatible: false };
|
|
182991
|
+
return false;
|
|
182992
|
+
}
|
|
182993
|
+
cachedSchemaCompatible = { path: dbPath, compatible: true };
|
|
182994
|
+
return true;
|
|
182995
|
+
} catch (error51) {
|
|
182996
|
+
log(`[magic-context] compaction-marker: schema probe failed: ${error51 instanceof Error ? error51.message : String(error51)}. ` + `Marker injection disabled until next process restart.`);
|
|
182997
|
+
cachedSchemaCompatible = { path: dbPath, compatible: false };
|
|
182998
|
+
return false;
|
|
182999
|
+
}
|
|
183000
|
+
}
|
|
183001
|
+
function getWritableOpenCodeDb() {
|
|
183002
|
+
const dbPath = getOpenCodeDbPath2();
|
|
183003
|
+
if (cachedWriteDb?.path === dbPath) {
|
|
183004
|
+
return cachedWriteDb.db;
|
|
183005
|
+
}
|
|
183006
|
+
if (cachedWriteDb) {
|
|
183007
|
+
try {
|
|
183008
|
+
closeQuietly(cachedWriteDb.db);
|
|
183009
|
+
} catch {}
|
|
183010
|
+
}
|
|
183011
|
+
if (!existsSync9(dbPath)) {
|
|
183012
|
+
throw new Error(`OpenCode database not found at ${dbPath} (is OpenCode installed?)`);
|
|
183013
|
+
}
|
|
183014
|
+
const db = new Database(dbPath);
|
|
183015
|
+
db.exec("PRAGMA busy_timeout=5000");
|
|
183016
|
+
db.exec("PRAGMA journal_mode=WAL");
|
|
183017
|
+
cachedWriteDb = { path: dbPath, db };
|
|
183018
|
+
return db;
|
|
183019
|
+
}
|
|
183020
|
+
function getNonSummaryMessageSortKey(sessionId, messageId) {
|
|
183021
|
+
const db = getWritableOpenCodeDb();
|
|
183022
|
+
const row = db.prepare(`SELECT time_created, id
|
|
183023
|
+
FROM message
|
|
183024
|
+
WHERE session_id = ?
|
|
183025
|
+
AND id = ?
|
|
183026
|
+
AND NOT (COALESCE(json_extract(data, '$.summary'), 0) = 1
|
|
183027
|
+
AND COALESCE(json_extract(data, '$.finish'), '') = 'stop')
|
|
183028
|
+
LIMIT 1`).get(sessionId, messageId);
|
|
183029
|
+
if (typeof row?.time_created !== "number" || typeof row.id !== "string") {
|
|
183030
|
+
return null;
|
|
183031
|
+
}
|
|
183032
|
+
return { id: row.id, timeCreated: row.time_created };
|
|
183033
|
+
}
|
|
183034
|
+
function findBoundaryUserMessage(sessionId, endMessageId) {
|
|
183035
|
+
const db = getWritableOpenCodeDb();
|
|
183036
|
+
const target2 = getNonSummaryMessageSortKey(sessionId, endMessageId);
|
|
183037
|
+
if (!target2)
|
|
183038
|
+
return null;
|
|
183039
|
+
const boundary = db.prepare(`SELECT id, time_created, data
|
|
183040
|
+
FROM message
|
|
183041
|
+
WHERE session_id = ?
|
|
183042
|
+
AND NOT (COALESCE(json_extract(data, '$.summary'), 0) = 1
|
|
183043
|
+
AND COALESCE(json_extract(data, '$.finish'), '') = 'stop')
|
|
183044
|
+
AND COALESCE(json_extract(data, '$.role'), '') = 'user'
|
|
183045
|
+
AND (time_created < ? OR (time_created = ? AND id <= ?))
|
|
183046
|
+
ORDER BY time_created DESC, id DESC
|
|
183047
|
+
LIMIT 1`).get(sessionId, target2.timeCreated, target2.timeCreated, target2.id);
|
|
183048
|
+
if (typeof boundary?.id !== "string" || typeof boundary.time_created !== "number") {
|
|
183049
|
+
return null;
|
|
183050
|
+
}
|
|
183051
|
+
return { id: boundary.id, timeCreated: boundary.time_created };
|
|
183052
|
+
}
|
|
183053
|
+
function compareOpenCodeMessagesByCanonicalOrder(sessionId, leftMessageId, rightMessageId) {
|
|
183054
|
+
const left = getNonSummaryMessageSortKey(sessionId, leftMessageId);
|
|
183055
|
+
const right = getNonSummaryMessageSortKey(sessionId, rightMessageId);
|
|
183056
|
+
if (!left || !right)
|
|
183057
|
+
return null;
|
|
183058
|
+
if (left.timeCreated < right.timeCreated)
|
|
183059
|
+
return -1;
|
|
183060
|
+
if (left.timeCreated > right.timeCreated)
|
|
183061
|
+
return 1;
|
|
183062
|
+
if (left.id < right.id)
|
|
183063
|
+
return -1;
|
|
183064
|
+
if (left.id > right.id)
|
|
183065
|
+
return 1;
|
|
183066
|
+
return 0;
|
|
183067
|
+
}
|
|
183068
|
+
function removeLegacyMarkerLineageRows(db, args) {
|
|
183069
|
+
const legacySummaries = db.prepare(`SELECT m.id
|
|
183070
|
+
FROM message m
|
|
183071
|
+
WHERE m.session_id = ?
|
|
183072
|
+
AND m.id <> ?
|
|
183073
|
+
AND COALESCE(json_extract(m.data, '$.summary'), 0) = 1
|
|
183074
|
+
AND COALESCE(json_extract(m.data, '$.finish'), '') = 'stop'
|
|
183075
|
+
AND COALESCE(json_extract(m.data, '$.parentID'), '') = ?
|
|
183076
|
+
AND EXISTS (
|
|
183077
|
+
SELECT 1
|
|
183078
|
+
FROM part p
|
|
183079
|
+
WHERE p.session_id = m.session_id
|
|
183080
|
+
AND p.message_id = m.id
|
|
183081
|
+
AND COALESCE(json_extract(p.data, '$.type'), '') = 'text'
|
|
183082
|
+
AND COALESCE(json_extract(p.data, '$.text'), '') = ?
|
|
183083
|
+
)`).all(args.sessionId, args.summaryMessageId, args.boundaryMessageId, args.summaryText);
|
|
183084
|
+
const legacySummaryIds = legacySummaries.flatMap((row) => typeof row.id === "string" ? [row.id] : []);
|
|
183085
|
+
if (legacySummaryIds.length === 0)
|
|
183086
|
+
return;
|
|
183087
|
+
const deleteSummaryParts = db.prepare("DELETE FROM part WHERE session_id = ? AND message_id = ?");
|
|
183088
|
+
const deleteSummary = db.prepare("DELETE FROM message WHERE session_id = ? AND id = ?");
|
|
183089
|
+
for (const summaryMessageId of legacySummaryIds) {
|
|
183090
|
+
deleteSummaryParts.run(args.sessionId, summaryMessageId);
|
|
183091
|
+
deleteSummary.run(args.sessionId, summaryMessageId);
|
|
183092
|
+
}
|
|
183093
|
+
db.prepare(`DELETE FROM part
|
|
183094
|
+
WHERE session_id = ?
|
|
183095
|
+
AND message_id = ?
|
|
183096
|
+
AND id <> ?
|
|
183097
|
+
AND COALESCE(json_extract(data, '$.type'), '') = 'compaction'
|
|
183098
|
+
AND COALESCE(json_extract(data, '$.auto'), 0) = 1`).run(args.sessionId, args.boundaryMessageId, args.compactionPartId);
|
|
183099
|
+
}
|
|
183100
|
+
function injectCompactionMarker(args) {
|
|
183101
|
+
const db = getWritableOpenCodeDb();
|
|
183102
|
+
if (!isOpenCodeSchemaCompatible(db, getOpenCodeDbPath2())) {
|
|
183103
|
+
return null;
|
|
183104
|
+
}
|
|
183105
|
+
const boundary = args.resolvedBoundary ?? findBoundaryUserMessage(args.sessionId, args.endMessageId);
|
|
183106
|
+
if (!boundary) {
|
|
183107
|
+
log(`[magic-context] compaction-marker: no user message found at or before endMessageId ${args.endMessageId} (ordinal ${args.endOrdinal})`);
|
|
183108
|
+
return null;
|
|
183109
|
+
}
|
|
183110
|
+
const boundaryTime = boundary.timeCreated;
|
|
183111
|
+
const markerIdentity = `${args.sessionId}\x00${args.endMessageId}`;
|
|
183112
|
+
const summaryMsgId = generateMessageId(boundaryTime + 1, 1n, `${markerIdentity}\x00summary-message`);
|
|
183113
|
+
const compactionPartId = generatePartId(boundaryTime, 1n, `${markerIdentity}\x00compaction-part`);
|
|
183114
|
+
const summaryPartId = generatePartId(boundaryTime + 1, 2n, `${markerIdentity}\x00summary-part`);
|
|
183115
|
+
const summaryMsgData = JSON.stringify({
|
|
183116
|
+
role: "assistant",
|
|
183117
|
+
parentID: boundary.id,
|
|
183118
|
+
summary: true,
|
|
183119
|
+
finish: "stop",
|
|
183120
|
+
mode: "compaction",
|
|
183121
|
+
agent: "compaction",
|
|
183122
|
+
path: { cwd: args.directory, root: args.directory },
|
|
183123
|
+
cost: 0,
|
|
183124
|
+
tokens: { input: 0, output: 0, reasoning: 0, cache: { read: 0, write: 0 } },
|
|
183125
|
+
modelID: "magic-context",
|
|
183126
|
+
providerID: "magic-context",
|
|
183127
|
+
time: { created: boundaryTime + 1 }
|
|
183128
|
+
});
|
|
183129
|
+
try {
|
|
183130
|
+
db.transaction(() => {
|
|
183131
|
+
removeLegacyMarkerLineageRows(db, {
|
|
183132
|
+
sessionId: args.sessionId,
|
|
183133
|
+
boundaryMessageId: boundary.id,
|
|
183134
|
+
summaryText: args.summaryText,
|
|
183135
|
+
summaryMessageId: summaryMsgId,
|
|
183136
|
+
compactionPartId
|
|
183137
|
+
});
|
|
183138
|
+
db.prepare(`INSERT INTO part (id, message_id, session_id, time_created, time_updated, data)
|
|
183139
|
+
VALUES (?, ?, ?, ?, ?, ?)
|
|
183140
|
+
ON CONFLICT(id) DO UPDATE SET
|
|
183141
|
+
message_id = excluded.message_id,
|
|
183142
|
+
session_id = excluded.session_id,
|
|
183143
|
+
time_created = excluded.time_created,
|
|
183144
|
+
time_updated = excluded.time_updated,
|
|
183145
|
+
data = excluded.data`).run(compactionPartId, boundary.id, args.sessionId, boundaryTime, boundaryTime, '{"type":"compaction","auto":true}');
|
|
183146
|
+
db.prepare(`INSERT INTO message (id, session_id, time_created, time_updated, data)
|
|
183147
|
+
VALUES (?, ?, ?, ?, ?)
|
|
183148
|
+
ON CONFLICT(id) DO UPDATE SET
|
|
183149
|
+
session_id = excluded.session_id,
|
|
183150
|
+
time_created = excluded.time_created,
|
|
183151
|
+
time_updated = excluded.time_updated,
|
|
183152
|
+
data = excluded.data`).run(summaryMsgId, args.sessionId, boundaryTime + 1, boundaryTime + 1, summaryMsgData);
|
|
183153
|
+
db.prepare(`INSERT INTO part (id, message_id, session_id, time_created, time_updated, data)
|
|
183154
|
+
VALUES (?, ?, ?, ?, ?, ?)
|
|
183155
|
+
ON CONFLICT(id) DO UPDATE SET
|
|
183156
|
+
message_id = excluded.message_id,
|
|
183157
|
+
session_id = excluded.session_id,
|
|
183158
|
+
time_created = excluded.time_created,
|
|
183159
|
+
time_updated = excluded.time_updated,
|
|
183160
|
+
data = excluded.data`).run(summaryPartId, summaryMsgId, args.sessionId, boundaryTime + 1, boundaryTime + 1, JSON.stringify({ type: "text", text: args.summaryText }));
|
|
183161
|
+
})();
|
|
183162
|
+
log(`[magic-context] compaction-marker: injected boundary at user msg ${boundary.id} (ordinal ~${args.endOrdinal}), summary msg ${summaryMsgId}`);
|
|
183163
|
+
return {
|
|
183164
|
+
boundaryMessageId: boundary.id,
|
|
183165
|
+
summaryMessageId: summaryMsgId,
|
|
183166
|
+
compactionPartId,
|
|
183167
|
+
summaryPartId
|
|
183168
|
+
};
|
|
183169
|
+
} catch (error51) {
|
|
183170
|
+
log(`[magic-context] compaction-marker: injection failed: ${error51 instanceof Error ? error51.message : String(error51)}`);
|
|
183171
|
+
return null;
|
|
183172
|
+
}
|
|
183173
|
+
}
|
|
183174
|
+
function removeCompactionMarker(state) {
|
|
183175
|
+
try {
|
|
183176
|
+
const db = getWritableOpenCodeDb();
|
|
183177
|
+
db.transaction(() => {
|
|
183178
|
+
db.prepare("DELETE FROM part WHERE id = ?").run(state.summaryPartId);
|
|
183179
|
+
db.prepare("DELETE FROM message WHERE id = ?").run(state.summaryMessageId);
|
|
183180
|
+
db.prepare("DELETE FROM part WHERE id = ?").run(state.compactionPartId);
|
|
183181
|
+
})();
|
|
183182
|
+
return true;
|
|
183183
|
+
} catch (error51) {
|
|
183184
|
+
log(`[magic-context] compaction-marker: removal failed: ${error51 instanceof Error ? error51.message : String(error51)}`);
|
|
183185
|
+
return false;
|
|
183186
|
+
}
|
|
183187
|
+
}
|
|
183188
|
+
|
|
183189
|
+
// ../plugin/src/hooks/magic-context/compaction-marker-manager.ts
|
|
183190
|
+
var MARKER_SUMMARY_TEXT = "[Compacted by magic-context — session history is managed by the plugin]";
|
|
183191
|
+
function dropMarkerSummaryTag(db, sessionId, summaryMessageId) {
|
|
183192
|
+
const tagNumber = getTagNumberByMessageId(db, sessionId, `${summaryMessageId}:p0`);
|
|
183193
|
+
if (tagNumber !== null)
|
|
183194
|
+
updateTagStatus(db, sessionId, tagNumber, "dropped");
|
|
183195
|
+
}
|
|
183196
|
+
function persistMarkerStateAndDropReplacedTag(db, sessionId, state, replacedSummaryMessageId) {
|
|
183197
|
+
db.transaction(() => {
|
|
183198
|
+
setPersistedCompactionMarkerState(db, sessionId, state);
|
|
183199
|
+
if (replacedSummaryMessageId !== null) {
|
|
183200
|
+
dropMarkerSummaryTag(db, sessionId, replacedSummaryMessageId);
|
|
183201
|
+
}
|
|
183202
|
+
})();
|
|
183203
|
+
}
|
|
183204
|
+
function getCompartmentEndMessageIdForOrdinal(db, sessionId, endOrdinal) {
|
|
183205
|
+
const row = db.prepare(`SELECT end_message_id
|
|
183206
|
+
FROM compartments
|
|
183207
|
+
WHERE session_id = ? AND end_message = ?
|
|
183208
|
+
ORDER BY sequence DESC
|
|
183209
|
+
LIMIT 1`).get(sessionId, endOrdinal);
|
|
183210
|
+
return typeof row?.end_message_id === "string" && row.end_message_id.length > 0 ? row.end_message_id : null;
|
|
183211
|
+
}
|
|
183212
|
+
function existingMarkerAlreadyCoversTarget(sessionId, existing, targetOrdinal, targetEndMessageId) {
|
|
183213
|
+
if (existing.boundaryOrdinal < targetOrdinal) {
|
|
183214
|
+
return false;
|
|
183215
|
+
}
|
|
183216
|
+
if (existing.boundaryOrdinal === targetOrdinal) {
|
|
183217
|
+
const boundaryCompare = compareOpenCodeMessagesByCanonicalOrder(sessionId, existing.boundaryMessageId, targetEndMessageId);
|
|
183218
|
+
if (boundaryCompare === null || boundaryCompare > 0) {
|
|
183219
|
+
return false;
|
|
183220
|
+
}
|
|
183221
|
+
if (existing.targetEndMessageId !== null && existing.targetEndMessageId !== targetEndMessageId) {
|
|
183222
|
+
return false;
|
|
183223
|
+
}
|
|
183224
|
+
return true;
|
|
183225
|
+
}
|
|
183226
|
+
if (existing.targetEndMessageId !== null) {
|
|
183227
|
+
const targetCompare = compareOpenCodeMessagesByCanonicalOrder(sessionId, existing.targetEndMessageId, targetEndMessageId);
|
|
183228
|
+
if (targetCompare !== null && targetCompare <= 0) {
|
|
183229
|
+
return false;
|
|
183230
|
+
}
|
|
183231
|
+
}
|
|
183232
|
+
return true;
|
|
183233
|
+
}
|
|
183234
|
+
function updateCompactionMarkerAfterPublication(db, sessionId, lastCompartmentEnd, directory) {
|
|
183235
|
+
if (getHarness() !== "opencode") {
|
|
183236
|
+
return true;
|
|
183237
|
+
}
|
|
183238
|
+
const targetEndMessageId = getCompartmentEndMessageIdForOrdinal(db, sessionId, lastCompartmentEnd);
|
|
183239
|
+
if (!targetEndMessageId) {
|
|
183240
|
+
sessionLog(sessionId, `compaction-marker: no compartment endMessageId for ordinal ${lastCompartmentEnd}; preserving existing marker`);
|
|
183241
|
+
return false;
|
|
183242
|
+
}
|
|
183243
|
+
const existing = getPersistedCompactionMarkerState(db, sessionId);
|
|
183244
|
+
const removedSummaryMessageId = existing?.summaryMessageId ?? null;
|
|
183245
|
+
if (existing) {
|
|
183246
|
+
if (existingMarkerAlreadyCoversTarget(sessionId, existing, lastCompartmentEnd, targetEndMessageId)) {
|
|
183247
|
+
return true;
|
|
183248
|
+
}
|
|
183249
|
+
}
|
|
183250
|
+
const boundary = findBoundaryUserMessage(sessionId, targetEndMessageId);
|
|
183251
|
+
if (!boundary) {
|
|
183252
|
+
sessionLog(sessionId, `compaction-marker: no user boundary found at or before endMessageId ${targetEndMessageId} (ordinal ${lastCompartmentEnd}); preserving existing marker`);
|
|
183253
|
+
return false;
|
|
183254
|
+
}
|
|
183255
|
+
if (existing) {
|
|
183256
|
+
const removed = removeCompactionMarker(existing);
|
|
183257
|
+
if (!removed) {
|
|
183258
|
+
sessionLog(sessionId, `compaction-marker: failed to remove old boundary at ordinal ${existing.boundaryOrdinal}; preserving persisted state for retry (not injecting new marker this pass)`);
|
|
183259
|
+
return false;
|
|
183260
|
+
}
|
|
183261
|
+
persistMarkerStateAndDropReplacedTag(db, sessionId, null, removedSummaryMessageId);
|
|
183262
|
+
sessionLog(sessionId, `compaction-marker: removed old boundary at ordinal ${existing.boundaryOrdinal}, moving to ${lastCompartmentEnd}`);
|
|
183263
|
+
}
|
|
183264
|
+
const result = injectCompactionMarker({
|
|
183265
|
+
sessionId,
|
|
183266
|
+
endOrdinal: lastCompartmentEnd,
|
|
183267
|
+
endMessageId: targetEndMessageId,
|
|
183268
|
+
summaryText: MARKER_SUMMARY_TEXT,
|
|
183269
|
+
directory: directory ?? process.cwd(),
|
|
183270
|
+
resolvedBoundary: boundary
|
|
183271
|
+
});
|
|
183272
|
+
if (result) {
|
|
183273
|
+
persistMarkerStateAndDropReplacedTag(db, sessionId, {
|
|
183274
|
+
...result,
|
|
183275
|
+
boundaryOrdinal: lastCompartmentEnd,
|
|
183276
|
+
targetEndMessageId
|
|
183277
|
+
}, removedSummaryMessageId);
|
|
183278
|
+
sessionLog(sessionId, `compaction-marker: injected at ordinal ${lastCompartmentEnd}, boundary user msg ${result.boundaryMessageId}`);
|
|
183279
|
+
return true;
|
|
183280
|
+
}
|
|
183281
|
+
return false;
|
|
183282
|
+
}
|
|
183283
|
+
|
|
182164
183284
|
// ../plugin/src/hooks/magic-context/compartment-render-epoch.ts
|
|
182165
183285
|
var COMPARTMENT_RENDER_EPOCH = "cre2";
|
|
182166
183286
|
var EPOCH_COMPONENT_PREFIX = "|compartment-render:";
|
|
@@ -182450,6 +183570,13 @@ var INJECTION_CACHE_MAX = 100;
|
|
|
182450
183570
|
var injectionCache = new BoundedSessionMap(INJECTION_CACHE_MAX);
|
|
182451
183571
|
function clearInjectionCache(sessionId) {
|
|
182452
183572
|
injectionCache.delete(sessionId);
|
|
183573
|
+
resetDegradedReanchorState(sessionId);
|
|
183574
|
+
}
|
|
183575
|
+
var degradedRebuildCountBySession = new BoundedSessionMap(INJECTION_CACHE_MAX);
|
|
183576
|
+
var reAnchorLoggedBySession = new BoundedSessionMap(INJECTION_CACHE_MAX);
|
|
183577
|
+
function resetDegradedReanchorState(sessionId) {
|
|
183578
|
+
degradedRebuildCountBySession.delete(sessionId);
|
|
183579
|
+
reAnchorLoggedBySession.delete(sessionId);
|
|
182453
183580
|
}
|
|
182454
183581
|
function getVisibleMemoryIds(db, sessionId) {
|
|
182455
183582
|
try {
|
|
@@ -182791,6 +183918,7 @@ function formatSearchResults(query, results, currentSessionId) {
|
|
|
182791
183918
|
${body}`;
|
|
182792
183919
|
}
|
|
182793
183920
|
function createCtxSearchTool(deps) {
|
|
183921
|
+
const resolveProject = deps.resolveProjectIdentity ?? resolveProjectIdentityForSession;
|
|
182794
183922
|
return {
|
|
182795
183923
|
name: "ctx_search",
|
|
182796
183924
|
label: "Magic Context: Search",
|
|
@@ -182816,7 +183944,7 @@ function createCtxSearchTool(deps) {
|
|
|
182816
183944
|
};
|
|
182817
183945
|
}
|
|
182818
183946
|
const sessionId = ctx.sessionManager.getSessionId();
|
|
182819
|
-
const projectIdentity =
|
|
183947
|
+
const projectIdentity = resolveProject(ctx.cwd);
|
|
182820
183948
|
if (!projectIdentity) {
|
|
182821
183949
|
return {
|
|
182822
183950
|
content: [
|
|
@@ -182941,12 +184069,14 @@ function createTodowriteTool() {
|
|
|
182941
184069
|
|
|
182942
184070
|
// src/tools/index.ts
|
|
182943
184071
|
function registerMagicContextTools(pi, opts) {
|
|
184072
|
+
const resolveProjectIdentity2 = opts.resolveProjectIdentity ? (directory) => opts.resolveProjectIdentity?.({ cwd: directory }) : undefined;
|
|
182944
184073
|
pi.registerTool(createCtxSearchTool({
|
|
182945
184074
|
db: opts.db,
|
|
182946
184075
|
ensureProjectRegistered: opts.ensureProjectRegistered,
|
|
182947
184076
|
memoryEnabled: opts.memoryEnabled,
|
|
182948
184077
|
embeddingEnabled: opts.embeddingEnabled,
|
|
182949
|
-
gitCommitsEnabled: opts.gitCommitsEnabled
|
|
184078
|
+
gitCommitsEnabled: opts.gitCommitsEnabled,
|
|
184079
|
+
resolveProjectIdentity: resolveProjectIdentity2
|
|
182950
184080
|
}));
|
|
182951
184081
|
if (opts.memoryToolEnabled !== false) {
|
|
182952
184082
|
pi.registerTool(createCtxMemoryTool({
|
|
@@ -182954,14 +184084,16 @@ function registerMagicContextTools(pi, opts) {
|
|
|
182954
184084
|
ensureProjectRegistered: opts.ensureProjectRegistered,
|
|
182955
184085
|
memoryEnabled: opts.memoryEnabled,
|
|
182956
184086
|
embeddingEnabled: opts.embeddingEnabled,
|
|
182957
|
-
allowDreamerActions: opts.allowDreamerActions ?? false
|
|
184087
|
+
allowDreamerActions: opts.allowDreamerActions ?? false,
|
|
184088
|
+
resolveProjectIdentity: resolveProjectIdentity2
|
|
182958
184089
|
}));
|
|
182959
184090
|
}
|
|
182960
184091
|
if (!opts.sessionScopedToolsDisabled) {
|
|
182961
184092
|
pi.registerTool(createCtxNoteTool({
|
|
182962
184093
|
db: opts.db,
|
|
182963
184094
|
dreamerEnabled: opts.dreamerEnabled ?? false,
|
|
182964
|
-
resolveDreamerEnabled: opts.resolveDreamerEnabled
|
|
184095
|
+
resolveDreamerEnabled: opts.resolveDreamerEnabled,
|
|
184096
|
+
resolveProjectIdentity: resolveProjectIdentity2
|
|
182965
184097
|
}));
|
|
182966
184098
|
pi.registerTool(createCtxExpandTool({ db: opts.db }));
|
|
182967
184099
|
}
|
|
@@ -182971,7 +184103,7 @@ function registerMagicContextTools(pi, opts) {
|
|
|
182971
184103
|
registerTodosCommand(pi);
|
|
182972
184104
|
}
|
|
182973
184105
|
}
|
|
182974
|
-
if (!opts.sessionScopedToolsDisabled) {
|
|
184106
|
+
if (!opts.sessionScopedToolsDisabled && !opts.compactionOff) {
|
|
182975
184107
|
pi.registerTool(createCtxReduceTool({
|
|
182976
184108
|
db: opts.db,
|
|
182977
184109
|
protectedTags: opts.protectedTags ?? 20,
|
|
@@ -182980,4 +184112,4 @@ function registerMagicContextTools(pi, opts) {
|
|
|
182980
184112
|
}
|
|
182981
184113
|
}
|
|
182982
184114
|
|
|
182983
|
-
export {
|
|
184115
|
+
export { COMPACTION_ENABLED_PATH, isDreamerRunnable, isCompactionEnabled, migrateMagicContextConfigLocations, ProjectIdentityError, resolveProjectIdentityStrict, resolveProjectIdentity, resolveProjectIdentityForSession, beginBootQuietPeriod, scheduleAfterBootQuiet, Database, closeQuietly, isMidTurn, textMentionsRecentCommit, hasMeaningfulUserText, extractTexts, extractToolCallSummaries, estimateTokens, normalizeText, stripPersistedAssistantText, byteSize, stripTagPrefix, peelLeadingMcTagNotation, prependTag, isRecord, isEditTool, applyEditMarkerToInput, setRawMessageProvider, withRawMessageProvider, cleanUserText, withRawSessionMessageCache, readRawSessionMessages, primeTailRawMessageCache, getCachedAbsoluteMessageCount, primeInMemoryTailRawMessageCache, getRawSessionMessageCount, getRawSessionTagKeysThrough, getLegacyProtectedTailStartOrdinal, readSessionChunk, clearCompressionDepth, clearCompressionDepthRange, getMessageIndexSourceIdentity, isMessageIndexSourceCurrent, getLastIndexedOrdinal, getMessageIndexReconciliationStartOrdinal, isMessageIndexReconciledThrough, indexSingleMessage, indexMessagesAfterOrdinal, sweepOrphanedOpenCodeMessageIndexes, recordSessionProjectIdentity, COMPARTMENT_LEASE_RENEWAL_MS, acquireCompartmentLease, renewCompartmentLease, releaseCompartmentLease, isCompartmentLeaseHeld, persistCachedM0, clearCachedM0M1, getCompartments, getLastCompartmentEndMessage, getLastCompartmentEndMessageId, getCompartmentsByEndMessageId, appendCompartments, saveRecompStagingPass, getRecompStaging, clearRecompStaging, getRecompPartialRange, setRecompPartialRange, escapeXmlAttr, escapeXmlContent, getModuleNoteEvaluationBridge, getContextStoreUuid, parseCompartmentOutput, resolveWorkspaceShareCategories, resolveWorkspaceIdentitySet, expandWorkspaceIdentitySetWithAliases, sourceNameForMemory, computeWorkspaceEpochFingerprint, bumpEpochsForWorkspaceMembers, readProjectDocsCanonical, copySessionStateForClone, getErrorMessage, describeError, setStoragePrivatePermissionEnforcement, stableStringify, getSchemaFenceRejection, getMigrationOnOpenRefusal, LATEST_SUPPORTED_VERSION, getDatabasePath, getPersistedSchemaVersion, setSqlitePragmaConfig, applySqliteTuningPragmas, runSqliteOptimize, openDatabase, openDatabaseAsync, queueM0Mutation, getMaxM0MutationId, queueMemoryMutation, getMemoryMutationsForRender, getMemoryMutationsForRenderByProjects, getMaxMemoryMutationId, getMaxMemoryMutationIdForProjects, MAX_EXECUTE_THRESHOLD, escalationBands, loadProtectedTailMeta, markProtectedTailPolicyV3Seeded, recordProtectedTailPublicationFloor, recordProtectedTailNoEligibleHead, getWrapupInProgressState, isWrapupInProgress, acquireWrapupInProgress, updateWrapupInProgress, releaseWrapupInProgress, resolveCompactionModeRecord, getCompactionModeRecord, setCompactionModeRecord, reserveProtectedTailDrainTokens, clearEmergencyDrainLatch, recordHistorianDrainFailure, clearHistorianDrainFailure, rollbackProtectedTailDrainReservation, clearPersistedReasoningWatermark, getEmergencyInputSample, setEmergencyDropSample, clearEmergencyDropSample, getLastNudgeUndropped, setLastNudgeUndropped, getLastNudgeLevel, setLastNudgeLevel, resetLastNudgeCycle, resetLastNudgeCycleIfTailShrank, getChannel2NudgeState, setChannel2NudgeState, casChannel2NudgeState, getPersistedNoteNudge, setPersistedNoteNudgeTrigger, setPersistedNoteNudgeTriggerMessageId, getNoteNudgeAnchors, getAutoSearchHintDecisions, deliverNoteNudgeAtomic, appendAutoSearchHintDecision, pruneNoteNudgeAnchors, pruneAutoSearchHintDecisions, getPersistedTodoSyntheticAnchor, setPersistedTodoSyntheticAnchor, clearPersistedTodoSyntheticAnchor, getNoteLastReadAt, getHistorianFailureState, incrementHistorianFailure, clearHistorianFailureState, getOverflowState, recordOverflowDetected, clearEmergencyRecovery, clearDetectedContextLimit, getStrippedPlaceholderIds, applyStrippedPlaceholderDelta, getProcessedImageStrippedIds, addProcessedImageStrippedIds, getPendingCompactionMarkerState, clearPendingCompactionMarkerStateIf, getPendingPiCompactionMarkerState, setPendingPiCompactionMarkerState, clearPendingPiCompactionMarkerStateIf, getSessionsWithPendingPiMarker, peekDeferredExecutePending, setDeferredExecutePendingIfAbsent, clearDeferredExecutePendingIfMatches, setSessionWorkMetrics, getSessionWorkMetrics, getOrCreateSessionMeta, updateSessionMeta, advanceToolReclaimWatermark, retryPendingSessionCleanups, getNotes, getSessionNotes, getPendingSmartNotes, getReadySmartNotes, markNoteReady, markNoteChecked, queuePendingOp, getPendingOps, clearPendingOps, removePendingOp, PRIMER_CANDIDATE_TTL_MS, PRIMER_CANDIDATE_MAX_AGE_MS, primerOccurrenceKey, primerOccurrenceUtcDay, insertPrimerCandidates, updatePrimerCandidateEmbedding, getPrimerCandidatesByIds, getPrimerCandidatesForPromotion, countPrimerCandidatesForProject, getActivePrimers, createPrimer, updatePrimerSupport, updatePrimerAnswer, GLOBAL_USER_PROFILE_PROJECT_PATH, getProjectState, bumpProjectUserProfileVersion, saveSourceContent, replaceSourceContent, getSourceContents, recordSubagentInvocation, getLatestHistorianInvocationId, updateTagByteSize, getActiveTagTokenAggregate, AGE_RECLAIM_MIN_TOKENS, getOldestActiveUnprotectedToolTags, getActiveToolTagsForAgeReclaim, getTriggerTagTokenUpperBound, updateTagInputByteSize, updateTagTokenCount, getPersistedToolTagAccounting, getAllStatusTagTokenTotalsFlat, updateTagInputTokenCount, tagTokenCountIsNull, backfillTagTokenCounts, insertTag, updateTagStatus, updateTagDropMode, updateCavemanDepth, hasPiFallbackMessageTags, findAdoptableFallbackTags, hasPiFallbackToolOwnerTags, findPiFallbackToolOwnerTags, adoptPiFallbackToolOwnerTag, adoptPiFallbackMessageTag, getMaxTagNumberBySession, getTagNumberByMessageId, deriveTagLoadFloor, getTagsBySession, getActiveTagsBySession, getTagsForPendingOperations, getTagsByNumbers, getMaxDroppedTagNumber, getToolTagNumberByOwner, getNullOwnerToolTag, adoptNullOwnerToolTag, BoundedSessionMap, piModelRefToCanonical, resolveModelRefForPi, isSaneLimit, resolveLimit, getSdkContextLimit, normalizeTodoStateJson, buildSyntheticTodoPart, SYNTH_USER_ID_PREFIX, resolvePiStableId, isMidTurnPi, readPiSessionMessages, findLastModelKeyFromBranch, convertEntriesToRawMessages, withContentLanguageDirective, withMigrationLanguageDirective, buildPrimaryLanguageDirective, getOpenCodeDbPath2 as getOpenCodeDbPath, parseCron, nextOccurrence, nextDueAtMs, DEFAULT_EXECUTE_THRESHOLD_PERCENTAGE, DEFAULT_HISTORIAN_TIMEOUT_MS, buildCanonicalChunkTextFromFts, buildCompartmentSummaryFallbackText, canonicalizeInMemoryChunkTextForEmbedding, chunkCanonicalText, chunkEmbeddingWindowsAreCurrent, replaceCompartmentChunkEmbeddings, cosineSimilarity, computeNormalizedHash, GIT_SWEEP_LEASE_RENEWAL_MS, acquireGitSweepLease, renewGitSweepLease, markGitSweepSuccessAndRelease, parkGitSweepNonIndexable, releaseGitSweepLease, invalidateMemory, contentSha256, sweepStaleEmbeddingIdentitiesForProject, enqueueShadowEmbeddingItems, getProjectEmbeddingSnapshot, getProjectChunkEmbeddingModelId, getProjectEmbeddingMaxInputTokens, embedTextForProject, embedBatchForProject, embedItemsForProject, embedUnembeddedMemoriesForProject, drainCommitBacklogForProject, embedSessionCompartmentChunks, getEmbeddingCoverageStatus, computeCueContentHash, getMuralCueState, memoryNeedsCue, setMuralCue, hasMemoryShareableColumn, hasMemoryClassifiedAtColumn, getUnclassifiedMemoryIds, insertMemory, getMemoryByHash, getMemoriesByProject, getMemoriesByProjects, getMaxMemoryIdForProjects, readNewMemoriesForM1Union, getAllActiveMemoriesForMigration, getMemoryById, setMemoryClassification, archiveMemory, deleteMemory, getMemoryCount, getMemoryCountsByStatus, promoteSessionFactsDurable, embedPromotedFacts, recordMemoryMapping, recordMemoryVerifications, getUnmappedMemoryIds, clearMemoryVerifications, getMemoryVerifications, resolveGitTopLevel, readGitHead, readGitChangedFilesSince, readGitFileChangeTimesSince, verificationFileExists, normalizeVerificationFiles, USER_MEMORY_CANDIDATE_TTL_MS, insertUserMemoryCandidates, getUserMemoryCandidates, deleteUserMemoryCandidates, pruneExpiredUserMemoryCandidates, insertUserMemory, getActiveUserMemories, updateUserMemoryContent, dismissUserMemory, indexCommitsForProject, embedUnembeddedCommits, loadPiConfig, ensureProjectRegisteredFromPiDirectory, resolveMuralWire, updateCompactionMarkerAfterPublication, COMPARTMENT_RENDER_EPOCH, encodeCachedM0UpgradeIdentity, decodeCachedM0UpgradeIdentity, DEFAULT_HISTORY_BUDGET_TOKENS, renderCompartmentAtTier, renderDecayedCompartments, extractM0Block, TEMPORAL_MARKER_PATTERN, temporalMarkerPrefix, clearInjectionCache, getVisibleMemoryIds, renderMemoryBlock, DEFAULT_MEMORY_BUDGET_TOKENS, DEFAULT_USER_PROFILE_BUDGET_TOKENS, trimMemoriesToBudgetV2, trimWorkspaceMemoriesToBudgetV2, trimUserMemoriesToBudget, renderMemoryBlockV2, stripMemoryMuralBlock, unifiedSearch, rememberTodowriteToolCallTodos, parseTodos, setTodoSnapshot, registerTodoOverlay, registerTodoStateLifecycle, registerMagicContextTools };
|