@cortexkit/pi-magic-context 0.34.1 → 0.35.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-ekzg3w5y.js → index-xbk9epe8.js} +1029 -164
- package/dist/index.js +626 -701
- package/dist/subagent-entry.js +6 -3
- package/package.json +1 -1
|
@@ -8667,6 +8667,7 @@ import {
|
|
|
8667
8667
|
mkdtempSync,
|
|
8668
8668
|
readdirSync,
|
|
8669
8669
|
readFileSync as readFileSync3,
|
|
8670
|
+
statSync as statSync3,
|
|
8670
8671
|
unlinkSync as unlinkSync2
|
|
8671
8672
|
} from "node:fs";
|
|
8672
8673
|
import { basename as basename2, dirname as dirname2, join as join3 } from "node:path";
|
|
@@ -11641,6 +11642,15 @@ var MIGRATIONS = [
|
|
|
11641
11642
|
ensureColumn(db, "session_meta", "detected_context_limit_provenance", "TEXT NOT NULL DEFAULT 'unknown'");
|
|
11642
11643
|
}
|
|
11643
11644
|
}
|
|
11645
|
+
},
|
|
11646
|
+
{
|
|
11647
|
+
version: 75,
|
|
11648
|
+
description: "persist mural cue validation rejection latches",
|
|
11649
|
+
up(db) {
|
|
11650
|
+
if (!tableExists2(db, "memories"))
|
|
11651
|
+
return;
|
|
11652
|
+
ensureColumn(db, "memories", "mural_cue_rejection_count", "INTEGER NOT NULL DEFAULT 0");
|
|
11653
|
+
}
|
|
11644
11654
|
}
|
|
11645
11655
|
];
|
|
11646
11656
|
var LATEST_MIGRATION_VERSION = MIGRATIONS.reduce((max, m) => Math.max(max, m.version), 0);
|
|
@@ -144676,7 +144686,7 @@ function getSchemaFenceRejection() {
|
|
|
144676
144686
|
function getMigrationOnOpenRefusal() {
|
|
144677
144687
|
return lastMigrationOnOpenRefusal;
|
|
144678
144688
|
}
|
|
144679
|
-
var LATEST_SUPPORTED_VERSION =
|
|
144689
|
+
var LATEST_SUPPORTED_VERSION = 75;
|
|
144680
144690
|
var PERMISSIONS_ENFORCEABLE = process.platform !== "win32";
|
|
144681
144691
|
var defaultStoragePermissionFs = { chmodSync, mkdirSync: mkdirSync2 };
|
|
144682
144692
|
var storagePermissionFs = defaultStoragePermissionFs;
|
|
@@ -144798,24 +144808,65 @@ function enforceSchemaFence(db, dbPath, latestSupportedVersion) {
|
|
|
144798
144808
|
log(`[magic-context] storage fatal: refusing to open ${dbPath}; upstream migration lane 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.`);
|
|
144799
144809
|
return false;
|
|
144800
144810
|
}
|
|
144801
|
-
function unreadableDiscovery(path2) {
|
|
144811
|
+
function unreadableDiscovery(path2, arm) {
|
|
144802
144812
|
return {
|
|
144803
144813
|
state: "unreadable",
|
|
144804
144814
|
serverPids: [],
|
|
144805
144815
|
staleFiles: [],
|
|
144806
|
-
unreadableFile: path2
|
|
144816
|
+
unreadableFile: path2,
|
|
144817
|
+
unreadableArm: arm
|
|
144807
144818
|
};
|
|
144808
144819
|
}
|
|
144820
|
+
var RPC_DISCOVERY_PARSE_GRACE_MS = 10 * 60 * 1000;
|
|
144821
|
+
var defaultRpcDiscoveryFs = {
|
|
144822
|
+
readdirSync: (path2, options) => options?.withFileTypes ? readdirSync(path2, { withFileTypes: true }) : readdirSync(path2),
|
|
144823
|
+
readFileSync: (path2, encoding) => String(readFileSync3(path2, encoding)),
|
|
144824
|
+
statSync: (path2) => ({ mtimeMs: statSync3(path2).mtimeMs }),
|
|
144825
|
+
unlinkSync: (path2) => unlinkSync2(path2)
|
|
144826
|
+
};
|
|
144827
|
+
var rpcDiscoveryFs = defaultRpcDiscoveryFs;
|
|
144828
|
+
function invalidDiscoveryReason(raw) {
|
|
144829
|
+
const trimmed = raw.trim();
|
|
144830
|
+
if (trimmed.startsWith("{")) {
|
|
144831
|
+
try {
|
|
144832
|
+
const parsed = JSON.parse(trimmed);
|
|
144833
|
+
if ("pid" in parsed) {
|
|
144834
|
+
const pid = Number(parsed.pid);
|
|
144835
|
+
if (!Number.isInteger(pid) || pid <= 0)
|
|
144836
|
+
return "invalid-pid";
|
|
144837
|
+
}
|
|
144838
|
+
} catch {}
|
|
144839
|
+
}
|
|
144840
|
+
return "parse-invalid";
|
|
144841
|
+
}
|
|
144842
|
+
function classifyJunkDiscovery(portFile, raw, staleFiles) {
|
|
144843
|
+
let mtimeMs;
|
|
144844
|
+
try {
|
|
144845
|
+
mtimeMs = rpcDiscoveryFs.statSync(portFile).mtimeMs;
|
|
144846
|
+
} catch (error) {
|
|
144847
|
+
if (error.code === "ENOENT")
|
|
144848
|
+
return null;
|
|
144849
|
+
return unreadableDiscovery(portFile, "io");
|
|
144850
|
+
}
|
|
144851
|
+
const ageMs = Date.now() - mtimeMs;
|
|
144852
|
+
if (!Number.isFinite(ageMs) || ageMs < RPC_DISCOVERY_PARSE_GRACE_MS) {
|
|
144853
|
+
return unreadableDiscovery(portFile, "parse");
|
|
144854
|
+
}
|
|
144855
|
+
staleFiles.push(portFile);
|
|
144856
|
+
const reason = invalidDiscoveryReason(raw);
|
|
144857
|
+
log(`[magic-context] removing stale RPC discovery file ${portFile}: ${reason} record older than 10 minutes`);
|
|
144858
|
+
return null;
|
|
144859
|
+
}
|
|
144809
144860
|
function inspectRpcServerDiscovery(storageDir) {
|
|
144810
144861
|
const rpcRoot = join3(storageDir, "rpc");
|
|
144811
144862
|
let projectEntries;
|
|
144812
144863
|
try {
|
|
144813
|
-
projectEntries = readdirSync(rpcRoot, { withFileTypes: true });
|
|
144864
|
+
projectEntries = rpcDiscoveryFs.readdirSync(rpcRoot, { withFileTypes: true });
|
|
144814
144865
|
} catch (error) {
|
|
144815
144866
|
if (error.code === "ENOENT") {
|
|
144816
144867
|
return { state: "absent", serverPids: [], staleFiles: [] };
|
|
144817
144868
|
}
|
|
144818
|
-
return unreadableDiscovery(rpcRoot);
|
|
144869
|
+
return unreadableDiscovery(rpcRoot, "io");
|
|
144819
144870
|
}
|
|
144820
144871
|
const portFiles = [];
|
|
144821
144872
|
for (const projectEntry of projectEntries) {
|
|
@@ -144824,9 +144875,11 @@ function inspectRpcServerDiscovery(storageDir) {
|
|
|
144824
144875
|
const projectDir = join3(rpcRoot, projectEntry.name);
|
|
144825
144876
|
let entries;
|
|
144826
144877
|
try {
|
|
144827
|
-
entries = readdirSync(projectDir);
|
|
144828
|
-
} catch {
|
|
144829
|
-
|
|
144878
|
+
entries = rpcDiscoveryFs.readdirSync(projectDir);
|
|
144879
|
+
} catch (error) {
|
|
144880
|
+
if (error.code === "ENOENT")
|
|
144881
|
+
continue;
|
|
144882
|
+
return unreadableDiscovery(projectDir, "io");
|
|
144830
144883
|
}
|
|
144831
144884
|
for (const entry of entries) {
|
|
144832
144885
|
if (entry === "port" || entry.startsWith("port-") && entry.endsWith(".json")) {
|
|
@@ -144842,15 +144895,21 @@ function inspectRpcServerDiscovery(storageDir) {
|
|
|
144842
144895
|
for (const portFile of portFiles) {
|
|
144843
144896
|
let raw;
|
|
144844
144897
|
try {
|
|
144845
|
-
raw =
|
|
144846
|
-
} catch {
|
|
144847
|
-
|
|
144898
|
+
raw = rpcDiscoveryFs.readFileSync(portFile, "utf8");
|
|
144899
|
+
} catch (error) {
|
|
144900
|
+
if (error.code === "ENOENT")
|
|
144901
|
+
continue;
|
|
144902
|
+
return unreadableDiscovery(portFile, "io");
|
|
144848
144903
|
}
|
|
144849
144904
|
const filename = basename2(portFile);
|
|
144850
144905
|
const pidFromName = /^port-(\d+)/.exec(filename)?.[1];
|
|
144851
|
-
const
|
|
144906
|
+
const fallbackPid = pidFromName ? Number(pidFromName) : 0;
|
|
144907
|
+
const record = parseRpcPortFile(raw, fallbackPid);
|
|
144852
144908
|
if (!record || !Number.isInteger(record.pid) || record.pid <= 0) {
|
|
144853
|
-
|
|
144909
|
+
const junk = classifyJunkDiscovery(portFile, raw, staleFiles);
|
|
144910
|
+
if (junk)
|
|
144911
|
+
return junk;
|
|
144912
|
+
continue;
|
|
144854
144913
|
}
|
|
144855
144914
|
if (isPidAlive(record.pid) && isPidIdentityPlausible(record))
|
|
144856
144915
|
pids.add(record.pid);
|
|
@@ -144859,9 +144918,9 @@ function inspectRpcServerDiscovery(storageDir) {
|
|
|
144859
144918
|
}
|
|
144860
144919
|
for (const staleFile of staleFiles) {
|
|
144861
144920
|
try {
|
|
144862
|
-
|
|
144921
|
+
rpcDiscoveryFs.unlinkSync(staleFile);
|
|
144863
144922
|
} catch {
|
|
144864
|
-
return unreadableDiscovery(staleFile);
|
|
144923
|
+
return unreadableDiscovery(staleFile, "io");
|
|
144865
144924
|
}
|
|
144866
144925
|
}
|
|
144867
144926
|
const serverPids = [...pids].sort((a, b) => a - b);
|
|
@@ -144885,10 +144944,14 @@ function enforceMigrationOnOpenGuard(db, dbPath, dbDir, latestSupportedVersion)
|
|
|
144885
144944
|
persistedVersion,
|
|
144886
144945
|
supportedVersion: latestSupportedVersion,
|
|
144887
144946
|
serverPids: discovery.serverPids,
|
|
144888
|
-
...discovery.unreadableFile ? { unreadableFile: discovery.unreadableFile } : {}
|
|
144947
|
+
...discovery.unreadableFile ? { unreadableFile: discovery.unreadableFile } : {},
|
|
144948
|
+
...discovery.unreadableArm ? { unreadableArm: discovery.unreadableArm } : {}
|
|
144889
144949
|
};
|
|
144890
144950
|
if (discovery.state === "unreadable") {
|
|
144891
|
-
|
|
144951
|
+
const unreadableFile = discovery.unreadableFile ?? "<unknown>";
|
|
144952
|
+
const arm = discovery.unreadableArm ?? "io";
|
|
144953
|
+
const recovery = arm === "io" ? `If no OpenCode server is running, it is safe to delete ${unreadableFile} and retry.` : `Retry after the file is older than the ten-minute grace window, or stop OpenCode before deleting it.`;
|
|
144954
|
+
log(`[magic-context] storage fatal: refusing to migrate ${dbPath} from upstream migration v${persistedVersion} to v${latestSupportedVersion} because RPC discovery file ${unreadableFile} is uncertain (${arm} arm), so the absence of a live OpenCode server cannot be proven. ${recovery}`);
|
|
144892
144955
|
} else {
|
|
144893
144956
|
log(`[magic-context] storage fatal: refusing to migrate ${dbPath} from upstream migration 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.`);
|
|
144894
144957
|
}
|
|
@@ -145182,6 +145245,7 @@ function initializeDatabase(db) {
|
|
|
145182
145245
|
mural_cue TEXT,
|
|
145183
145246
|
mural_cue_hash TEXT,
|
|
145184
145247
|
mural_cue_at INTEGER,
|
|
145248
|
+
mural_cue_rejection_count INTEGER NOT NULL DEFAULT 0,
|
|
145185
145249
|
UNIQUE(project_path, category, normalized_hash)
|
|
145186
145250
|
);
|
|
145187
145251
|
|
|
@@ -146513,6 +146577,7 @@ function clearCachedM0M1(db, sessionId) {
|
|
|
146513
146577
|
|
|
146514
146578
|
// ../plugin/src/features/magic-context/storage-meta-persisted.ts
|
|
146515
146579
|
var emergencyRecoveryArmedSessions = new Set;
|
|
146580
|
+
var emergencyRecoveryArmedAtBySession = new Map;
|
|
146516
146581
|
var providerOverflowReconfirmedSessions = new Set;
|
|
146517
146582
|
var CAS_RETRY_LIMIT = 5;
|
|
146518
146583
|
var AUTO_SEARCH_NO_HINT_REASONS = new Set([
|
|
@@ -147278,6 +147343,7 @@ function getOverflowState(db, sessionId, modelKey) {
|
|
|
147278
147343
|
}
|
|
147279
147344
|
function recordOverflowDetected(db, sessionId, reportedLimit, modelKey, origin = "provider_overflow", provenance = "unknown") {
|
|
147280
147345
|
emergencyRecoveryArmedSessions.add(sessionId);
|
|
147346
|
+
emergencyRecoveryArmedAtBySession.set(sessionId, Date.now());
|
|
147281
147347
|
db.transaction(() => {
|
|
147282
147348
|
ensureSessionMetaRow(db, sessionId);
|
|
147283
147349
|
const prior = db.prepare("SELECT needs_emergency_recovery FROM session_meta WHERE session_id = ?").get(sessionId);
|
|
@@ -147301,6 +147367,7 @@ function clearEmergencyRecovery(db, sessionId) {
|
|
|
147301
147367
|
}
|
|
147302
147368
|
})();
|
|
147303
147369
|
emergencyRecoveryArmedSessions.delete(sessionId);
|
|
147370
|
+
emergencyRecoveryArmedAtBySession.delete(sessionId);
|
|
147304
147371
|
providerOverflowReconfirmedSessions.delete(sessionId);
|
|
147305
147372
|
}
|
|
147306
147373
|
function clearDetectedContextLimit(db, sessionId) {
|
|
@@ -147818,6 +147885,521 @@ function readRawSessionTailFromDb(db, sessionId, baseOrdinal, anchorMessageId) {
|
|
|
147818
147885
|
return { messages, absoluteMessageCount: Math.max(0, ord - 1) };
|
|
147819
147886
|
}
|
|
147820
147887
|
|
|
147888
|
+
// ../plugin/src/shared/record-type-guard.ts
|
|
147889
|
+
function isRecord(value) {
|
|
147890
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
147891
|
+
}
|
|
147892
|
+
|
|
147893
|
+
// ../plugin/src/hooks/magic-context/read-session-true-raw-tokens.ts
|
|
147894
|
+
function completedToolArcCrossesBoundary(invOrdinal, resOrdinal, boundary) {
|
|
147895
|
+
return invOrdinal < boundary && boundary <= resOrdinal;
|
|
147896
|
+
}
|
|
147897
|
+
var MAX_MESSAGE_CACHE_ENTRIES = 1e5;
|
|
147898
|
+
var MAX_MESSAGE_CACHE_KEY_BYTES = 64 * 1024 * 1024;
|
|
147899
|
+
var FNV1A_32_OFFSET = 2166136261;
|
|
147900
|
+
var FNV1A_32_PRIME = 16777619;
|
|
147901
|
+
var messageEstimateCache = new Map;
|
|
147902
|
+
var messageEstimateCacheBytes = 0;
|
|
147903
|
+
var EMPTY_BREAKDOWN = {
|
|
147904
|
+
text: 0,
|
|
147905
|
+
reasoning: 0,
|
|
147906
|
+
toolInput: 0,
|
|
147907
|
+
toolOutput: 0,
|
|
147908
|
+
image: 0,
|
|
147909
|
+
other: 0,
|
|
147910
|
+
total: 0
|
|
147911
|
+
};
|
|
147912
|
+
function addBreakdown(target, kind, value) {
|
|
147913
|
+
if (kind === "total")
|
|
147914
|
+
return;
|
|
147915
|
+
const safeValue = Number.isFinite(value) && value > 0 ? Math.round(value) : 0;
|
|
147916
|
+
target[kind] += safeValue;
|
|
147917
|
+
target.total += safeValue;
|
|
147918
|
+
}
|
|
147919
|
+
function estimateStructured(value) {
|
|
147920
|
+
if (typeof value === "string")
|
|
147921
|
+
return estimateTokens(value);
|
|
147922
|
+
if (value === undefined || value === null)
|
|
147923
|
+
return 0;
|
|
147924
|
+
return estimateTokens(stableStringify(value));
|
|
147925
|
+
}
|
|
147926
|
+
function firstStringField(record, fields) {
|
|
147927
|
+
for (const field of fields) {
|
|
147928
|
+
const value = record[field];
|
|
147929
|
+
if (typeof value === "string" && value.length > 0)
|
|
147930
|
+
return value;
|
|
147931
|
+
}
|
|
147932
|
+
return null;
|
|
147933
|
+
}
|
|
147934
|
+
function stringValue(value) {
|
|
147935
|
+
if (typeof value === "string")
|
|
147936
|
+
return value;
|
|
147937
|
+
if (value === undefined || value === null)
|
|
147938
|
+
return "";
|
|
147939
|
+
return stableStringify(value);
|
|
147940
|
+
}
|
|
147941
|
+
function textFromToolResultContent(content) {
|
|
147942
|
+
if (typeof content === "string")
|
|
147943
|
+
return content;
|
|
147944
|
+
if (Array.isArray(content)) {
|
|
147945
|
+
const pieces = [];
|
|
147946
|
+
for (const entry of content) {
|
|
147947
|
+
if (typeof entry === "string") {
|
|
147948
|
+
pieces.push(entry);
|
|
147949
|
+
} else if (isRecord(entry)) {
|
|
147950
|
+
const text = firstStringField(entry, ["text", "content", "value"]);
|
|
147951
|
+
pieces.push(text ?? stableStringify(entry));
|
|
147952
|
+
} else if (entry !== null && entry !== undefined) {
|
|
147953
|
+
pieces.push(String(entry));
|
|
147954
|
+
}
|
|
147955
|
+
}
|
|
147956
|
+
return pieces.join(`
|
|
147957
|
+
`);
|
|
147958
|
+
}
|
|
147959
|
+
return stringValue(content);
|
|
147960
|
+
}
|
|
147961
|
+
function looksImageLike(part) {
|
|
147962
|
+
const type = typeof part.type === "string" ? part.type.toLowerCase() : "";
|
|
147963
|
+
const mime = typeof part.mime === "string" ? part.mime.toLowerCase() : "";
|
|
147964
|
+
const mediaType = typeof part.mediaType === "string" ? part.mediaType.toLowerCase() : "";
|
|
147965
|
+
return type.includes("image") || mime.startsWith("image/") || mediaType.startsWith("image/") || part.image_url !== undefined || part.imageUrl !== undefined || part.image !== undefined;
|
|
147966
|
+
}
|
|
147967
|
+
function defaultImageTokenHeuristic(part) {
|
|
147968
|
+
if (isRecord(part)) {
|
|
147969
|
+
const width = part.width;
|
|
147970
|
+
const height = part.height;
|
|
147971
|
+
if (typeof width === "number" && typeof height === "number" && width > 0 && height > 0) {
|
|
147972
|
+
return Math.max(256, Math.min(4096, Math.ceil(width * height / 750)));
|
|
147973
|
+
}
|
|
147974
|
+
}
|
|
147975
|
+
return 1024;
|
|
147976
|
+
}
|
|
147977
|
+
function partType(part) {
|
|
147978
|
+
return typeof part.type === "string" ? part.type : "";
|
|
147979
|
+
}
|
|
147980
|
+
function hasOwn(record, key) {
|
|
147981
|
+
return Object.hasOwn(record, key);
|
|
147982
|
+
}
|
|
147983
|
+
function recursiveByteLength(value) {
|
|
147984
|
+
if (value === null || value === undefined)
|
|
147985
|
+
return 0;
|
|
147986
|
+
if (typeof value === "string")
|
|
147987
|
+
return value.length;
|
|
147988
|
+
if (typeof value === "number" || typeof value === "boolean" || typeof value === "bigint") {
|
|
147989
|
+
return String(value).length;
|
|
147990
|
+
}
|
|
147991
|
+
if (Array.isArray(value)) {
|
|
147992
|
+
return value.reduce((sum, item) => sum + recursiveByteLength(item), value.length);
|
|
147993
|
+
}
|
|
147994
|
+
if (isRecord(value)) {
|
|
147995
|
+
let total = Object.keys(value).length;
|
|
147996
|
+
for (const [key, child] of Object.entries(value)) {
|
|
147997
|
+
total += key.length + recursiveByteLength(child);
|
|
147998
|
+
}
|
|
147999
|
+
return total;
|
|
148000
|
+
}
|
|
148001
|
+
return String(value).length;
|
|
148002
|
+
}
|
|
148003
|
+
function updateFnv1a32(hash, text) {
|
|
148004
|
+
let next = hash;
|
|
148005
|
+
for (let index = 0;index < text.length; index += 1) {
|
|
148006
|
+
next ^= text.charCodeAt(index);
|
|
148007
|
+
next = Math.imul(next, FNV1A_32_PRIME) >>> 0;
|
|
148008
|
+
}
|
|
148009
|
+
return next;
|
|
148010
|
+
}
|
|
148011
|
+
function contentStringsHash(fields) {
|
|
148012
|
+
let hash = FNV1A_32_OFFSET;
|
|
148013
|
+
for (const field of fields) {
|
|
148014
|
+
hash = updateFnv1a32(hash, `${field.length}:`);
|
|
148015
|
+
hash = updateFnv1a32(hash, field);
|
|
148016
|
+
hash = updateFnv1a32(hash, "\x00");
|
|
148017
|
+
}
|
|
148018
|
+
return hash.toString(16).padStart(8, "0");
|
|
148019
|
+
}
|
|
148020
|
+
function rawPartVersion(part) {
|
|
148021
|
+
return part.__magicContextPartUpdatedAt ?? part.updated_at ?? part.updatedAt ?? part.version ?? part.revision ?? "";
|
|
148022
|
+
}
|
|
148023
|
+
function callIdFromPart(part) {
|
|
148024
|
+
const direct = firstStringField(part, ["callID", "callId", "toolCallId", "tool_call_id", "id"]);
|
|
148025
|
+
if (direct)
|
|
148026
|
+
return direct;
|
|
148027
|
+
const state = isRecord(part.state) ? part.state : null;
|
|
148028
|
+
return state ? firstStringField(state, ["callID", "callId", "toolCallId", "tool_call_id", "id"]) ?? "" : "";
|
|
148029
|
+
}
|
|
148030
|
+
function toolSignalFromPart(part) {
|
|
148031
|
+
if (!isRecord(part))
|
|
148032
|
+
return null;
|
|
148033
|
+
const type = partType(part);
|
|
148034
|
+
const state = isRecord(part.state) ? part.state : null;
|
|
148035
|
+
const callId = callIdFromPart(part);
|
|
148036
|
+
if (!callId && type !== "tool")
|
|
148037
|
+
return null;
|
|
148038
|
+
if (type === "tool") {
|
|
148039
|
+
const hasInput = state !== null && hasOwn(state, "input");
|
|
148040
|
+
const outputKey = state ? hasOwn(state, "output") ? "output" : hasOwn(state, "error") ? "error" : hasOwn(state, "result") ? "result" : null : null;
|
|
148041
|
+
const hasOutput = outputKey !== null;
|
|
148042
|
+
const outputValue = outputKey && state ? state[outputKey] : undefined;
|
|
148043
|
+
const providerExecuted = part.providerExecuted === true;
|
|
148044
|
+
const openInvocation = !providerExecuted && !hasOutput;
|
|
148045
|
+
return {
|
|
148046
|
+
callId,
|
|
148047
|
+
hasInput: hasInput || openInvocation,
|
|
148048
|
+
hasOutput,
|
|
148049
|
+
inputText: hasInput && state ? stringValue(state.input) : "",
|
|
148050
|
+
outputText: hasOutput ? stringValue(outputValue) : ""
|
|
148051
|
+
};
|
|
148052
|
+
}
|
|
148053
|
+
if (type === "tool-invocation") {
|
|
148054
|
+
const args = part.args ?? part.input;
|
|
148055
|
+
return {
|
|
148056
|
+
callId,
|
|
148057
|
+
hasInput: args !== undefined,
|
|
148058
|
+
hasOutput: false,
|
|
148059
|
+
inputText: args !== undefined ? stringValue(args) : "",
|
|
148060
|
+
outputText: ""
|
|
148061
|
+
};
|
|
148062
|
+
}
|
|
148063
|
+
if (type === "tool_use") {
|
|
148064
|
+
const input = part.input;
|
|
148065
|
+
return {
|
|
148066
|
+
callId,
|
|
148067
|
+
hasInput: input !== undefined,
|
|
148068
|
+
hasOutput: false,
|
|
148069
|
+
inputText: input !== undefined ? stringValue(input) : "",
|
|
148070
|
+
outputText: ""
|
|
148071
|
+
};
|
|
148072
|
+
}
|
|
148073
|
+
if (type === "tool_result") {
|
|
148074
|
+
const content = part.content ?? part.output ?? part.result;
|
|
148075
|
+
return {
|
|
148076
|
+
callId,
|
|
148077
|
+
hasInput: false,
|
|
148078
|
+
hasOutput: content !== undefined,
|
|
148079
|
+
inputText: "",
|
|
148080
|
+
outputText: content !== undefined ? textFromToolResultContent(content) : ""
|
|
148081
|
+
};
|
|
148082
|
+
}
|
|
148083
|
+
return null;
|
|
148084
|
+
}
|
|
148085
|
+
function partCheapFingerprint(part) {
|
|
148086
|
+
if (!isRecord(part))
|
|
148087
|
+
return `${typeof part}:${recursiveByteLength(part)}`;
|
|
148088
|
+
const version = rawPartVersion(part);
|
|
148089
|
+
const type = typeof part.type === "string" ? part.type : "";
|
|
148090
|
+
return `${type}:${String(version)}:${recursiveByteLength(part)}`;
|
|
148091
|
+
}
|
|
148092
|
+
function messageCacheKey(message, options) {
|
|
148093
|
+
const namespace = "cacheNamespace" in options ? options.cacheNamespace : "estimate";
|
|
148094
|
+
const cheapFingerprint = message.parts.map(partCheapFingerprint).join("|");
|
|
148095
|
+
return [
|
|
148096
|
+
namespace,
|
|
148097
|
+
options.providerShapeVersion,
|
|
148098
|
+
message.id || `ordinal:${message.ordinal}`,
|
|
148099
|
+
message.role,
|
|
148100
|
+
message.parts.length,
|
|
148101
|
+
cheapFingerprint
|
|
148102
|
+
].join("\x00");
|
|
148103
|
+
}
|
|
148104
|
+
function setCachedEstimate(key, breakdown) {
|
|
148105
|
+
const keyEstimateBytes = key.length * 2 + 64;
|
|
148106
|
+
const existing = messageEstimateCache.get(key);
|
|
148107
|
+
if (existing)
|
|
148108
|
+
messageEstimateCacheBytes -= existing.keyEstimateBytes;
|
|
148109
|
+
messageEstimateCache.set(key, { breakdown, keyEstimateBytes });
|
|
148110
|
+
messageEstimateCacheBytes += keyEstimateBytes;
|
|
148111
|
+
while (messageEstimateCache.size > MAX_MESSAGE_CACHE_ENTRIES || messageEstimateCacheBytes > MAX_MESSAGE_CACHE_KEY_BYTES) {
|
|
148112
|
+
const first = messageEstimateCache.keys().next().value;
|
|
148113
|
+
if (typeof first !== "string")
|
|
148114
|
+
break;
|
|
148115
|
+
const removed = messageEstimateCache.get(first);
|
|
148116
|
+
if (removed)
|
|
148117
|
+
messageEstimateCacheBytes -= removed.keyEstimateBytes;
|
|
148118
|
+
messageEstimateCache.delete(first);
|
|
148119
|
+
}
|
|
148120
|
+
}
|
|
148121
|
+
function cloneBreakdown(value) {
|
|
148122
|
+
return { ...value };
|
|
148123
|
+
}
|
|
148124
|
+
function estimateNonToolPart(part, options, breakdown) {
|
|
148125
|
+
if (!isRecord(part)) {
|
|
148126
|
+
if (part !== null && part !== undefined)
|
|
148127
|
+
addBreakdown(breakdown, "other", estimateStructured(part));
|
|
148128
|
+
return true;
|
|
148129
|
+
}
|
|
148130
|
+
const type = partType(part);
|
|
148131
|
+
if (type === "step-start" || type === "step-finish" || type === "meta" && Object.keys(part).length <= 1) {
|
|
148132
|
+
return true;
|
|
148133
|
+
}
|
|
148134
|
+
if (type === "text") {
|
|
148135
|
+
const text = firstStringField(part, ["text", "content"]);
|
|
148136
|
+
if (text)
|
|
148137
|
+
addBreakdown(breakdown, "text", estimateTokens(text));
|
|
148138
|
+
return true;
|
|
148139
|
+
}
|
|
148140
|
+
if (type === "reasoning" || type === "thinking" || type === "redacted_thinking") {
|
|
148141
|
+
const text = firstStringField(part, ["thinking", "text", "content", "reasoning"]);
|
|
148142
|
+
if (text) {
|
|
148143
|
+
addBreakdown(breakdown, "reasoning", estimateTokens(text));
|
|
148144
|
+
} else {
|
|
148145
|
+
addBreakdown(breakdown, "other", estimateStructured(part));
|
|
148146
|
+
}
|
|
148147
|
+
return true;
|
|
148148
|
+
}
|
|
148149
|
+
const reasoningText = firstStringField(part, ["thinking", "reasoning"]);
|
|
148150
|
+
if (reasoningText && type.length === 0) {
|
|
148151
|
+
addBreakdown(breakdown, "reasoning", estimateTokens(reasoningText));
|
|
148152
|
+
return true;
|
|
148153
|
+
}
|
|
148154
|
+
if (looksImageLike(part)) {
|
|
148155
|
+
addBreakdown(breakdown, "image", options.imageTokenHeuristic?.(part) ?? defaultImageTokenHeuristic(part));
|
|
148156
|
+
const altText = firstStringField(part, ["alt", "text", "description"]);
|
|
148157
|
+
if (altText)
|
|
148158
|
+
addBreakdown(breakdown, "text", estimateTokens(altText));
|
|
148159
|
+
return true;
|
|
148160
|
+
}
|
|
148161
|
+
if (type.includes("file") || type === "source") {
|
|
148162
|
+
const content = firstStringField(part, ["content", "text", "source"]);
|
|
148163
|
+
if (content)
|
|
148164
|
+
addBreakdown(breakdown, "text", estimateTokens(content));
|
|
148165
|
+
else
|
|
148166
|
+
addBreakdown(breakdown, "other", estimateStructured(part));
|
|
148167
|
+
return true;
|
|
148168
|
+
}
|
|
148169
|
+
return false;
|
|
148170
|
+
}
|
|
148171
|
+
function estimateTrueRawMessageTokens(message, options) {
|
|
148172
|
+
const breakdown = cloneBreakdown(EMPTY_BREAKDOWN);
|
|
148173
|
+
const countedInput = new Set;
|
|
148174
|
+
const countedOutput = new Set;
|
|
148175
|
+
let ordinalToolIndex = 0;
|
|
148176
|
+
for (const part of message.parts) {
|
|
148177
|
+
const signal = toolSignalFromPart(part);
|
|
148178
|
+
if (signal) {
|
|
148179
|
+
const localKey = `${signal.callId || "tool"}:${message.ordinal}:${ordinalToolIndex}`;
|
|
148180
|
+
ordinalToolIndex += 1;
|
|
148181
|
+
if (signal.hasInput) {
|
|
148182
|
+
const key = `${signal.callId}:input:${message.ordinal}`;
|
|
148183
|
+
if (!countedInput.has(key)) {
|
|
148184
|
+
countedInput.add(key);
|
|
148185
|
+
addBreakdown(breakdown, "toolInput", estimateTokens(signal.inputText));
|
|
148186
|
+
}
|
|
148187
|
+
}
|
|
148188
|
+
if (signal.hasOutput) {
|
|
148189
|
+
const key = `${signal.callId}:output:${message.ordinal}:${localKey}`;
|
|
148190
|
+
if (!countedOutput.has(key)) {
|
|
148191
|
+
countedOutput.add(key);
|
|
148192
|
+
addBreakdown(breakdown, "toolOutput", estimateTokens(signal.outputText));
|
|
148193
|
+
}
|
|
148194
|
+
}
|
|
148195
|
+
continue;
|
|
148196
|
+
}
|
|
148197
|
+
if (!estimateNonToolPart(part, options, breakdown)) {
|
|
148198
|
+
addBreakdown(breakdown, "other", estimateStructured(part));
|
|
148199
|
+
}
|
|
148200
|
+
}
|
|
148201
|
+
return breakdown;
|
|
148202
|
+
}
|
|
148203
|
+
function buildToolArcs(messages) {
|
|
148204
|
+
const openQueues = new Map;
|
|
148205
|
+
const arcs = [];
|
|
148206
|
+
for (const message of messages) {
|
|
148207
|
+
for (const part of message.parts) {
|
|
148208
|
+
const signal = toolSignalFromPart(part);
|
|
148209
|
+
if (!signal || signal.callId.length === 0)
|
|
148210
|
+
continue;
|
|
148211
|
+
if (signal.hasInput && signal.hasOutput) {
|
|
148212
|
+
arcs.push({
|
|
148213
|
+
callId: signal.callId,
|
|
148214
|
+
invOrdinal: message.ordinal,
|
|
148215
|
+
resOrdinal: message.ordinal
|
|
148216
|
+
});
|
|
148217
|
+
continue;
|
|
148218
|
+
}
|
|
148219
|
+
if (signal.hasInput) {
|
|
148220
|
+
const queue = openQueues.get(signal.callId) ?? [];
|
|
148221
|
+
queue.push(message.ordinal);
|
|
148222
|
+
openQueues.set(signal.callId, queue);
|
|
148223
|
+
continue;
|
|
148224
|
+
}
|
|
148225
|
+
if (signal.hasOutput) {
|
|
148226
|
+
const queue = openQueues.get(signal.callId) ?? [];
|
|
148227
|
+
const invOrdinal = queue.shift();
|
|
148228
|
+
if (queue.length === 0)
|
|
148229
|
+
openQueues.delete(signal.callId);
|
|
148230
|
+
else
|
|
148231
|
+
openQueues.set(signal.callId, queue);
|
|
148232
|
+
if (invOrdinal !== undefined) {
|
|
148233
|
+
arcs.push({ callId: signal.callId, invOrdinal, resOrdinal: message.ordinal });
|
|
148234
|
+
}
|
|
148235
|
+
}
|
|
148236
|
+
}
|
|
148237
|
+
}
|
|
148238
|
+
for (const [callId, queue] of openQueues) {
|
|
148239
|
+
for (const invOrdinal of queue) {
|
|
148240
|
+
arcs.push({ callId, invOrdinal, resOrdinal: null });
|
|
148241
|
+
}
|
|
148242
|
+
}
|
|
148243
|
+
return arcs.sort((a, b) => a.invOrdinal - b.invOrdinal || (a.resOrdinal ?? Number.MAX_SAFE_INTEGER) - (b.resOrdinal ?? Number.MAX_SAFE_INTEGER));
|
|
148244
|
+
}
|
|
148245
|
+
function fenceBoundaryForToolArcs(candidate, arcs, lastCompartmentEndOrdinal, recentOpenArcCutoff) {
|
|
148246
|
+
let boundary = candidate;
|
|
148247
|
+
for (const arc of arcs) {
|
|
148248
|
+
if (arc.resOrdinal !== null) {
|
|
148249
|
+
if (completedToolArcCrossesBoundary(arc.invOrdinal, arc.resOrdinal, boundary)) {
|
|
148250
|
+
boundary = arc.resOrdinal + 1;
|
|
148251
|
+
}
|
|
148252
|
+
continue;
|
|
148253
|
+
}
|
|
148254
|
+
if (arc.invOrdinal < recentOpenArcCutoff)
|
|
148255
|
+
continue;
|
|
148256
|
+
if (arc.invOrdinal >= lastCompartmentEndOrdinal + 1 && arc.invOrdinal < boundary) {
|
|
148257
|
+
return arc.invOrdinal;
|
|
148258
|
+
}
|
|
148259
|
+
if (arc.invOrdinal >= boundary) {
|
|
148260
|
+
return arc.invOrdinal;
|
|
148261
|
+
}
|
|
148262
|
+
}
|
|
148263
|
+
return boundary;
|
|
148264
|
+
}
|
|
148265
|
+
function tokenForMessage(message, options) {
|
|
148266
|
+
const key = messageCacheKey(message, options);
|
|
148267
|
+
const cached = messageEstimateCache.get(key);
|
|
148268
|
+
if (cached)
|
|
148269
|
+
return cloneBreakdown(cached.breakdown);
|
|
148270
|
+
const breakdown = estimateTrueRawMessageTokens(message, options);
|
|
148271
|
+
setCachedEstimate(key, breakdown);
|
|
148272
|
+
return cloneBreakdown(breakdown);
|
|
148273
|
+
}
|
|
148274
|
+
function buildTrueRawTokenIndex(sessionId, messages, options) {
|
|
148275
|
+
const ordered = [...messages].sort((a, b) => a.ordinal - b.ordinal);
|
|
148276
|
+
const sliceCount = ordered.length;
|
|
148277
|
+
const firstOrdinal = ordered.length > 0 ? ordered[0].ordinal : 1;
|
|
148278
|
+
const terminalOrdinal = ordered.length > 0 ? ordered[ordered.length - 1].ordinal : 0;
|
|
148279
|
+
const rawMessageCount = Math.max(sliceCount, terminalOrdinal, options.absoluteMessageCount ?? sliceCount);
|
|
148280
|
+
const ordinalSpan = terminalOrdinal >= firstOrdinal ? terminalOrdinal - firstOrdinal + 1 : 0;
|
|
148281
|
+
const tokensByOrdinal = new Map;
|
|
148282
|
+
const idsByOrdinal = new Map;
|
|
148283
|
+
const prefix = new Array(ordinalSpan + 1).fill(0);
|
|
148284
|
+
for (const message of ordered) {
|
|
148285
|
+
const stored = options.storedTotalForMessage?.(message);
|
|
148286
|
+
const total = stored !== undefined && stored !== null ? stored : tokenForMessage(message, options).total;
|
|
148287
|
+
tokensByOrdinal.set(message.ordinal, total);
|
|
148288
|
+
idsByOrdinal.set(message.ordinal, message.id);
|
|
148289
|
+
const relative = message.ordinal - firstOrdinal + 1;
|
|
148290
|
+
if (relative >= 1 && relative <= ordinalSpan) {
|
|
148291
|
+
prefix[relative] = total;
|
|
148292
|
+
}
|
|
148293
|
+
}
|
|
148294
|
+
for (let k = 1;k <= ordinalSpan; k += 1) {
|
|
148295
|
+
prefix[k] += prefix[k - 1];
|
|
148296
|
+
}
|
|
148297
|
+
const ordinalToIndex = (ordinal) => Math.max(0, Math.min(ordinalSpan, ordinal - firstOrdinal));
|
|
148298
|
+
return {
|
|
148299
|
+
sessionId,
|
|
148300
|
+
providerShapeVersion: options.providerShapeVersion,
|
|
148301
|
+
rawMessageCount,
|
|
148302
|
+
tokenForOrdinal(ordinal) {
|
|
148303
|
+
return tokensByOrdinal.get(ordinal) ?? 0;
|
|
148304
|
+
},
|
|
148305
|
+
messageIdAtOrdinal(ordinal) {
|
|
148306
|
+
return idsByOrdinal.get(ordinal) ?? null;
|
|
148307
|
+
},
|
|
148308
|
+
suffixTokensFromOrdinal(ordinal) {
|
|
148309
|
+
if (ordinal <= firstOrdinal)
|
|
148310
|
+
return prefix[ordinalSpan];
|
|
148311
|
+
if (ordinal > terminalOrdinal)
|
|
148312
|
+
return 0;
|
|
148313
|
+
return prefix[ordinalSpan] - prefix[ordinalToIndex(ordinal)];
|
|
148314
|
+
},
|
|
148315
|
+
rangeTokens(startInclusive, endExclusive) {
|
|
148316
|
+
const start = Math.max(firstOrdinal, startInclusive);
|
|
148317
|
+
const end = Math.max(start, Math.min(terminalOrdinal + 1, endExclusive));
|
|
148318
|
+
return prefix[end - firstOrdinal] - prefix[start - firstOrdinal];
|
|
148319
|
+
},
|
|
148320
|
+
findSuffixStartForTokens(tokens) {
|
|
148321
|
+
if (!Number.isFinite(tokens) || tokens <= 0)
|
|
148322
|
+
return terminalOrdinal + 1;
|
|
148323
|
+
const target = Math.max(0, Math.floor(tokens));
|
|
148324
|
+
const total = prefix[ordinalSpan];
|
|
148325
|
+
if (total < target)
|
|
148326
|
+
return firstOrdinal;
|
|
148327
|
+
const cut = total - target;
|
|
148328
|
+
let lo = 0;
|
|
148329
|
+
let hi = ordinalSpan;
|
|
148330
|
+
let best = 0;
|
|
148331
|
+
while (lo <= hi) {
|
|
148332
|
+
const mid = lo + hi >> 1;
|
|
148333
|
+
if (prefix[mid] <= cut) {
|
|
148334
|
+
best = mid;
|
|
148335
|
+
lo = mid + 1;
|
|
148336
|
+
} else {
|
|
148337
|
+
hi = mid - 1;
|
|
148338
|
+
}
|
|
148339
|
+
}
|
|
148340
|
+
return firstOrdinal + best;
|
|
148341
|
+
},
|
|
148342
|
+
findHeadEndForCap(startInclusive, endExclusive, capTokens) {
|
|
148343
|
+
const start = Math.max(firstOrdinal, Math.min(terminalOrdinal + 1, startInclusive));
|
|
148344
|
+
const end = Math.max(start, Math.min(terminalOrdinal + 1, endExclusive));
|
|
148345
|
+
if (!Number.isFinite(capTokens) || capTokens <= 0)
|
|
148346
|
+
return start;
|
|
148347
|
+
const startIndex = start - firstOrdinal;
|
|
148348
|
+
const endIndex = end - firstOrdinal;
|
|
148349
|
+
const cut = prefix[startIndex] + Math.floor(capTokens);
|
|
148350
|
+
let lo = startIndex + 1;
|
|
148351
|
+
let hi = endIndex;
|
|
148352
|
+
let bestEndIndex = startIndex;
|
|
148353
|
+
while (lo <= hi) {
|
|
148354
|
+
const mid = lo + hi >> 1;
|
|
148355
|
+
if (prefix[mid] <= cut) {
|
|
148356
|
+
bestEndIndex = mid;
|
|
148357
|
+
lo = mid + 1;
|
|
148358
|
+
} else {
|
|
148359
|
+
hi = mid - 1;
|
|
148360
|
+
}
|
|
148361
|
+
}
|
|
148362
|
+
let bestEnd = firstOrdinal + bestEndIndex;
|
|
148363
|
+
if (bestEnd === start && start < end)
|
|
148364
|
+
bestEnd = start + 1;
|
|
148365
|
+
return Math.min(bestEnd, end);
|
|
148366
|
+
}
|
|
148367
|
+
};
|
|
148368
|
+
}
|
|
148369
|
+
function partContentFingerprint(part) {
|
|
148370
|
+
if (!isRecord(part))
|
|
148371
|
+
return `${typeof part}:${recursiveByteLength(part)}`;
|
|
148372
|
+
const tool = toolSignalFromPart(part);
|
|
148373
|
+
if (tool) {
|
|
148374
|
+
return contentStringsHash([tool.inputText, tool.outputText]);
|
|
148375
|
+
}
|
|
148376
|
+
const text = firstStringField(part, ["text", "thinking", "reasoning", "content", "url"]) ?? "";
|
|
148377
|
+
return contentStringsHash([text]);
|
|
148378
|
+
}
|
|
148379
|
+
function computeRawRangeFingerprint(messages, startInclusive, endExclusive) {
|
|
148380
|
+
const pieces = [];
|
|
148381
|
+
for (const message of messages) {
|
|
148382
|
+
if (message.ordinal < startInclusive || message.ordinal >= endExclusive)
|
|
148383
|
+
continue;
|
|
148384
|
+
const partFingerprint = message.parts.map(partContentFingerprint).join(",");
|
|
148385
|
+
pieces.push(`${message.ordinal}:${message.id}:${message.parts.length}:${partFingerprint}`);
|
|
148386
|
+
}
|
|
148387
|
+
return pieces.join("|");
|
|
148388
|
+
}
|
|
148389
|
+
function invalidateTrueRawTokenCache(args) {
|
|
148390
|
+
const sessionNeedle = args.sessionId ? `${args.sessionId}` : null;
|
|
148391
|
+
const messageNeedle = args.messageId ? `\x00${args.messageId}\x00` : null;
|
|
148392
|
+
for (const [key, value] of messageEstimateCache) {
|
|
148393
|
+
const sessionMatches = sessionNeedle === null || key.includes(sessionNeedle);
|
|
148394
|
+
const messageMatches = messageNeedle === null || key.includes(messageNeedle);
|
|
148395
|
+
if (sessionMatches && messageMatches) {
|
|
148396
|
+
messageEstimateCache.delete(key);
|
|
148397
|
+
messageEstimateCacheBytes -= value.keyEstimateBytes;
|
|
148398
|
+
}
|
|
148399
|
+
}
|
|
148400
|
+
args.reason;
|
|
148401
|
+
}
|
|
148402
|
+
|
|
147821
148403
|
// ../plugin/src/hooks/magic-context/tag-content-primitives.ts
|
|
147822
148404
|
var encoder = new TextEncoder;
|
|
147823
148405
|
var TAG_PREFIX_REGEX = /^(?:§\d+§\s*)+/;
|
|
@@ -147890,11 +148472,6 @@ function isFilePart(part) {
|
|
|
147890
148472
|
return p.type === "file" && typeof p.url === "string";
|
|
147891
148473
|
}
|
|
147892
148474
|
|
|
147893
|
-
// ../plugin/src/shared/record-type-guard.ts
|
|
147894
|
-
function isRecord(value) {
|
|
147895
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
147896
|
-
}
|
|
147897
|
-
|
|
147898
148475
|
// ../plugin/src/hooks/magic-context/edit-marker.ts
|
|
147899
148476
|
var TRUNCATION_SENTINEL = "...[truncated]";
|
|
147900
148477
|
var EDIT_REGION_HINT_LEN = 40;
|
|
@@ -148335,6 +148912,7 @@ function readSessionChunk(sessionId, tokenBudget, offset = 1, eligibleEndOrdinal
|
|
|
148335
148912
|
toolOnlyRanges.push({ start: range.start, end: range.end });
|
|
148336
148913
|
}
|
|
148337
148914
|
}
|
|
148915
|
+
const completedToolArcs = buildToolArcs(messages).flatMap((arc) => arc.resOrdinal === null ? [] : [{ start: arc.invOrdinal, end: arc.resOrdinal }]);
|
|
148338
148916
|
return {
|
|
148339
148917
|
startIndex: startOrdinal,
|
|
148340
148918
|
endIndex: lastOrdinal,
|
|
@@ -148347,7 +148925,8 @@ function readSessionChunk(sessionId, tokenBudget, offset = 1, eligibleEndOrdinal
|
|
|
148347
148925
|
`),
|
|
148348
148926
|
lines: lineMeta,
|
|
148349
148927
|
commitClusterCount: commitClusters,
|
|
148350
|
-
toolOnlyRanges
|
|
148928
|
+
toolOnlyRanges,
|
|
148929
|
+
completedToolArcs
|
|
148351
148930
|
};
|
|
148352
148931
|
}
|
|
148353
148932
|
|
|
@@ -149105,7 +149684,7 @@ function escapeXmlContent(s) {
|
|
|
149105
149684
|
}
|
|
149106
149685
|
// ../plugin/src/features/magic-context/project-docs-hash.ts
|
|
149107
149686
|
import { createHash as createHash5 } from "node:crypto";
|
|
149108
|
-
import { lstatSync, readFileSync as readFileSync4, statSync as
|
|
149687
|
+
import { lstatSync, readFileSync as readFileSync4, statSync as statSync4 } from "node:fs";
|
|
149109
149688
|
import path2 from "node:path";
|
|
149110
149689
|
var PROJECT_DOC_FILES = ["ARCHITECTURE.md", "STRUCTURE.md"];
|
|
149111
149690
|
var PROJECT_DOCS_DELIMITER = `
|
|
@@ -149136,7 +149715,7 @@ function fingerprintFile(filePath) {
|
|
|
149136
149715
|
}
|
|
149137
149716
|
function readDirectoryMtimeMs(projectDirectory) {
|
|
149138
149717
|
try {
|
|
149139
|
-
return
|
|
149718
|
+
return statSync4(projectDirectory).mtimeMs;
|
|
149140
149719
|
} catch {
|
|
149141
149720
|
return 0;
|
|
149142
149721
|
}
|
|
@@ -150997,6 +151576,275 @@ function isTodoItem(value) {
|
|
|
150997
151576
|
return typeof todo.content === "string" && isTodoStatus(todo.status) && (todo.priority === undefined || isTodoPriority(todo.priority));
|
|
150998
151577
|
}
|
|
150999
151578
|
|
|
151579
|
+
// ../plugin/src/shared/prompt-surface-runtime.ts
|
|
151580
|
+
import { existsSync as existsSync7, readFileSync as readFileSync6, statSync as statSync5 } from "node:fs";
|
|
151581
|
+
import { dirname as dirname3, isAbsolute as isAbsolute2, resolve } from "node:path";
|
|
151582
|
+
|
|
151583
|
+
// ../plugin/src/tools/light-descriptions.ts
|
|
151584
|
+
var CTX_REDUCE_LIGHT_DESCRIPTION = `For ctx_reduce users, mark spent §N§ outputs discardable; release is QUEUED, not immediate, so content stays visible until space is needed. Newest tags stay protected until they age out. Released content becomes a placeholder; recover it only by rerunning the source or recovery tool, so mark only genuinely finished material. Mark analyzed, redundant, persisted, or merely confirmatory outputs; keep user messages, unresolved errors, unextracted evidence, and exact wording. NEVER blanket-mark a large range: review every tag first.`;
|
|
151585
|
+
var CTX_EXPAND_LIGHT_DESCRIPTION = `For ctx_expand users, recover compacted conversation by passing a session-history heading's inclusive start/end ordinals. Results are raw [N] U:/A: transcript capped near 15K tokens; oversized ranges return the head and a continuation. Use verbose=true to list each message ordinal, part previews, and tool-output sizes; use message=N for one complete stored message and its tool exchanges. NEVER expand ranges after the last compartment because that live tail is already visible.`;
|
|
151586
|
+
var CTX_NOTE_LIGHT_DESCRIPTION = `For ctx_note users, write saves, read lists, update changes, and dismiss retires future session notes; surface_condition creates a smart note. For smart notes, NEVER use a condition tied to this conversation or an unobservable future action because the background checker can inspect only external GitHub, disk, git, or web signals.`;
|
|
151587
|
+
var CTX_MEMORY_LIGHT_DESCRIPTION = `For ctx_memory users, write one standalone durable fact with category and content; update one ID, archive one or more IDs, merge two or more IDs, or get one to twenty numeric IDs. get reads memories in every status; list remains dreamer-only, so primary agents must NEVER assume bulk-list access.`;
|
|
151588
|
+
var CTX_SEARCH_LIGHT_DESCRIPTION = `For ctx_search users, retrieve only hidden recall: memories not already in <project-memory>, compacted messages outside the live tail, commits, and notes. Omit sources for broad search; select memory, message, git_commit, or note to target a source, or pass memory IDs to bypass text search. Message hits continue through ctx_expand.`;
|
|
151589
|
+
|
|
151590
|
+
// ../plugin/src/shared/jsonc-parser.ts
|
|
151591
|
+
import { existsSync as existsSync6, readFileSync as readFileSync5 } from "node:fs";
|
|
151592
|
+
function stripJsonComments(content) {
|
|
151593
|
+
let result = "";
|
|
151594
|
+
let inString = false;
|
|
151595
|
+
let escaped = false;
|
|
151596
|
+
let inLineComment = false;
|
|
151597
|
+
let inBlockComment = false;
|
|
151598
|
+
for (let index = 0;index < content.length; index += 1) {
|
|
151599
|
+
const char = content[index];
|
|
151600
|
+
const next = content[index + 1];
|
|
151601
|
+
if (inLineComment) {
|
|
151602
|
+
if (char === `
|
|
151603
|
+
`) {
|
|
151604
|
+
inLineComment = false;
|
|
151605
|
+
result += char;
|
|
151606
|
+
}
|
|
151607
|
+
continue;
|
|
151608
|
+
}
|
|
151609
|
+
if (inBlockComment) {
|
|
151610
|
+
if (char === "*" && next === "/") {
|
|
151611
|
+
inBlockComment = false;
|
|
151612
|
+
index += 1;
|
|
151613
|
+
}
|
|
151614
|
+
continue;
|
|
151615
|
+
}
|
|
151616
|
+
if (inString) {
|
|
151617
|
+
result += char;
|
|
151618
|
+
if (escaped) {
|
|
151619
|
+
escaped = false;
|
|
151620
|
+
} else if (char === "\\") {
|
|
151621
|
+
escaped = true;
|
|
151622
|
+
} else if (char === '"') {
|
|
151623
|
+
inString = false;
|
|
151624
|
+
}
|
|
151625
|
+
continue;
|
|
151626
|
+
}
|
|
151627
|
+
if (char === '"') {
|
|
151628
|
+
inString = true;
|
|
151629
|
+
result += char;
|
|
151630
|
+
continue;
|
|
151631
|
+
}
|
|
151632
|
+
if (char === "/" && next === "/") {
|
|
151633
|
+
inLineComment = true;
|
|
151634
|
+
index += 1;
|
|
151635
|
+
continue;
|
|
151636
|
+
}
|
|
151637
|
+
if (char === "/" && next === "*") {
|
|
151638
|
+
inBlockComment = true;
|
|
151639
|
+
index += 1;
|
|
151640
|
+
continue;
|
|
151641
|
+
}
|
|
151642
|
+
result += char;
|
|
151643
|
+
}
|
|
151644
|
+
return result;
|
|
151645
|
+
}
|
|
151646
|
+
function detectConfigFile(basePath) {
|
|
151647
|
+
const jsoncPath = `${basePath}.jsonc`;
|
|
151648
|
+
const jsonPath = `${basePath}.json`;
|
|
151649
|
+
if (existsSync6(jsoncPath)) {
|
|
151650
|
+
return { format: "jsonc", path: jsoncPath };
|
|
151651
|
+
}
|
|
151652
|
+
if (existsSync6(jsonPath)) {
|
|
151653
|
+
return { format: "json", path: jsonPath };
|
|
151654
|
+
}
|
|
151655
|
+
return { format: "none", path: jsoncPath };
|
|
151656
|
+
}
|
|
151657
|
+
|
|
151658
|
+
// ../plugin/src/shared/prompt-surface.ts
|
|
151659
|
+
function isValidPromptSurfaceModelKey(key) {
|
|
151660
|
+
if (key.length === 0 || key.trim() !== key)
|
|
151661
|
+
return false;
|
|
151662
|
+
const slash = key.indexOf("/");
|
|
151663
|
+
if (slash <= 0 || slash === key.length - 1)
|
|
151664
|
+
return false;
|
|
151665
|
+
const provider = key.slice(0, slash);
|
|
151666
|
+
const modelID = key.slice(slash + 1);
|
|
151667
|
+
if (provider.trim() !== provider || modelID.trim() !== modelID || provider.includes("*") || modelID.includes("*") && modelID !== "*") {
|
|
151668
|
+
return false;
|
|
151669
|
+
}
|
|
151670
|
+
if (modelID === "*")
|
|
151671
|
+
return true;
|
|
151672
|
+
return modelID.length > 0 && !modelID.startsWith("/") && !modelID.endsWith("/") && !modelID.includes("//");
|
|
151673
|
+
}
|
|
151674
|
+
function modelKeyLookupOrder(modelKey) {
|
|
151675
|
+
if (!modelKey)
|
|
151676
|
+
return [];
|
|
151677
|
+
const slash = modelKey.indexOf("/");
|
|
151678
|
+
if (slash <= 0 || slash === modelKey.length - 1)
|
|
151679
|
+
return [];
|
|
151680
|
+
const provider = modelKey.slice(0, slash);
|
|
151681
|
+
let modelID = modelKey.slice(slash + 1);
|
|
151682
|
+
const candidates = [];
|
|
151683
|
+
while (modelID.length > 0) {
|
|
151684
|
+
candidates.push({ key: `${provider}/${modelID}`, source: "exact" });
|
|
151685
|
+
candidates.push({ key: modelID, source: "bare" });
|
|
151686
|
+
const lastDash = modelID.lastIndexOf("-");
|
|
151687
|
+
if (lastDash <= 0)
|
|
151688
|
+
break;
|
|
151689
|
+
modelID = modelID.slice(0, lastDash);
|
|
151690
|
+
}
|
|
151691
|
+
candidates.push({ key: `${provider}/*`, source: "wildcard" });
|
|
151692
|
+
const seen = new Set;
|
|
151693
|
+
return candidates.filter((candidate) => {
|
|
151694
|
+
if (seen.has(candidate.key))
|
|
151695
|
+
return false;
|
|
151696
|
+
seen.add(candidate.key);
|
|
151697
|
+
return true;
|
|
151698
|
+
});
|
|
151699
|
+
}
|
|
151700
|
+
function resolveModelConfigValue(values, modelKey) {
|
|
151701
|
+
if (!values)
|
|
151702
|
+
return;
|
|
151703
|
+
for (const candidate of modelKeyLookupOrder(modelKey)) {
|
|
151704
|
+
const value = values[candidate.key];
|
|
151705
|
+
if (value !== undefined) {
|
|
151706
|
+
return { value, source: candidate.source };
|
|
151707
|
+
}
|
|
151708
|
+
}
|
|
151709
|
+
return;
|
|
151710
|
+
}
|
|
151711
|
+
function resolvePromptSurface(config, modelKey) {
|
|
151712
|
+
const fallback = config?.default ?? "full";
|
|
151713
|
+
const match = resolveModelConfigValue(config?.models, modelKey);
|
|
151714
|
+
if (match && match.source !== "bare") {
|
|
151715
|
+
return { preset: match.value, source: match.source };
|
|
151716
|
+
}
|
|
151717
|
+
return { preset: fallback, source: "default" };
|
|
151718
|
+
}
|
|
151719
|
+
function resolveModelConfigOrDefault(values, modelKey, fallback) {
|
|
151720
|
+
return resolveModelConfigValue(values, modelKey)?.value ?? fallback;
|
|
151721
|
+
}
|
|
151722
|
+
|
|
151723
|
+
// ../plugin/src/shared/prompt-surface-runtime.ts
|
|
151724
|
+
var GUIDANCE_MARKER = "## Magic Context";
|
|
151725
|
+
var GUIDANCE_MARKER_LINE = /^## Magic Context[\t ]*\r?$/gm;
|
|
151726
|
+
var PROMPT_SURFACE_TOOL_IDS = [
|
|
151727
|
+
"ctx_reduce",
|
|
151728
|
+
"ctx_expand",
|
|
151729
|
+
"ctx_note",
|
|
151730
|
+
"ctx_memory",
|
|
151731
|
+
"ctx_search"
|
|
151732
|
+
];
|
|
151733
|
+
var LIGHT_TOOL_DESCRIPTIONS = {
|
|
151734
|
+
ctx_reduce: CTX_REDUCE_LIGHT_DESCRIPTION,
|
|
151735
|
+
ctx_expand: CTX_EXPAND_LIGHT_DESCRIPTION,
|
|
151736
|
+
ctx_note: CTX_NOTE_LIGHT_DESCRIPTION,
|
|
151737
|
+
ctx_memory: CTX_MEMORY_LIGHT_DESCRIPTION,
|
|
151738
|
+
ctx_search: CTX_SEARCH_LIGHT_DESCRIPTION
|
|
151739
|
+
};
|
|
151740
|
+
function promptSurfaceHashMaterial(systemContent, preset = "full") {
|
|
151741
|
+
return preset === "full" ? systemContent : `${systemContent}
|
|
151742
|
+
\x00magic-context-prompt-surface:${preset}`;
|
|
151743
|
+
}
|
|
151744
|
+
var PROMPT_SURFACE_TOOL_ID_SET = new Set(PROMPT_SURFACE_TOOL_IDS);
|
|
151745
|
+
function resolveUserConfigDirectory(options) {
|
|
151746
|
+
if (options.userConfigDirectory)
|
|
151747
|
+
return resolve(options.userConfigDirectory);
|
|
151748
|
+
const sharedBase = cortexKitUserConfigBasePath();
|
|
151749
|
+
const shared = detectConfigFile(sharedBase);
|
|
151750
|
+
if (shared.format !== "none")
|
|
151751
|
+
return dirname3(shared.path);
|
|
151752
|
+
if (options.harness) {
|
|
151753
|
+
const legacy = resolveLegacyConfigSourcesForHarness(options.directory ?? process.cwd(), options.harness).user.find((source) => existsSync7(source.path));
|
|
151754
|
+
if (legacy)
|
|
151755
|
+
return dirname3(legacy.path);
|
|
151756
|
+
}
|
|
151757
|
+
return dirname3(sharedBase);
|
|
151758
|
+
}
|
|
151759
|
+
function markerCount(content) {
|
|
151760
|
+
return content.match(GUIDANCE_MARKER_LINE)?.length ?? 0;
|
|
151761
|
+
}
|
|
151762
|
+
function createPromptSurfaceRuntime(options) {
|
|
151763
|
+
const userConfigDirectory = resolveUserConfigDirectory(options);
|
|
151764
|
+
const warned = new Set;
|
|
151765
|
+
const warnOnce = (key, message) => {
|
|
151766
|
+
if (warned.has(key))
|
|
151767
|
+
return;
|
|
151768
|
+
warned.add(key);
|
|
151769
|
+
options.warn(message);
|
|
151770
|
+
};
|
|
151771
|
+
const readGuidanceOverride = (configuredPath) => {
|
|
151772
|
+
if (!configuredPath)
|
|
151773
|
+
return;
|
|
151774
|
+
const path3 = isAbsolute2(configuredPath) ? configuredPath : resolve(userConfigDirectory, configuredPath);
|
|
151775
|
+
let content;
|
|
151776
|
+
try {
|
|
151777
|
+
if (!statSync5(path3).isFile()) {
|
|
151778
|
+
warnOnce(`guidance-not-file:${path3}`, `prompt_surface.guidance_override_path (${path3}) is not a file; using built-in guidance.`);
|
|
151779
|
+
return;
|
|
151780
|
+
}
|
|
151781
|
+
content = readFileSync6(path3, "utf8");
|
|
151782
|
+
} catch (error) {
|
|
151783
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
151784
|
+
warnOnce(`guidance-unreadable:${path3}:${reason}`, `prompt_surface.guidance_override_path (${path3}) could not be read (${reason}); using built-in guidance.`);
|
|
151785
|
+
return;
|
|
151786
|
+
}
|
|
151787
|
+
if (content.trim().length === 0) {
|
|
151788
|
+
warnOnce(`guidance-empty:${path3}`, `prompt_surface.guidance_override_path (${path3}) is empty; using built-in guidance.`);
|
|
151789
|
+
return;
|
|
151790
|
+
}
|
|
151791
|
+
const markers = markerCount(content);
|
|
151792
|
+
if (markers !== 1) {
|
|
151793
|
+
warnOnce(`guidance-marker-count:${path3}:${markers}`, `prompt_surface.guidance_override_path (${path3}) must contain exactly one ${JSON.stringify(GUIDANCE_MARKER)} section marker; found ${markers}. Using built-in guidance.`);
|
|
151794
|
+
return;
|
|
151795
|
+
}
|
|
151796
|
+
return content;
|
|
151797
|
+
};
|
|
151798
|
+
return {
|
|
151799
|
+
resolveRegistration(config) {
|
|
151800
|
+
const { preset } = resolvePromptSurface(config, undefined);
|
|
151801
|
+
const overrides = config?.tool_descriptions ?? {};
|
|
151802
|
+
for (const [toolId, description] of Object.entries(overrides)) {
|
|
151803
|
+
if (!PROMPT_SURFACE_TOOL_ID_SET.has(toolId)) {
|
|
151804
|
+
warnOnce(`unknown-tool:${toolId}`, `prompt_surface.tool_descriptions.${toolId} is not a known ctx_* tool ID; the override was ignored.`);
|
|
151805
|
+
} else if (description.trim().length === 0) {
|
|
151806
|
+
warnOnce(`empty-tool:${toolId}`, `prompt_surface.tool_descriptions.${toolId} is empty; the override was ignored.`);
|
|
151807
|
+
}
|
|
151808
|
+
}
|
|
151809
|
+
return {
|
|
151810
|
+
preset,
|
|
151811
|
+
descriptionFor(toolId, fullDescription) {
|
|
151812
|
+
if (!PROMPT_SURFACE_TOOL_ID_SET.has(toolId))
|
|
151813
|
+
return fullDescription;
|
|
151814
|
+
const override = overrides[toolId];
|
|
151815
|
+
if (override !== undefined && override.trim().length > 0)
|
|
151816
|
+
return override;
|
|
151817
|
+
return preset === "light" ? LIGHT_TOOL_DESCRIPTIONS[toolId] : fullDescription;
|
|
151818
|
+
}
|
|
151819
|
+
};
|
|
151820
|
+
},
|
|
151821
|
+
resolveGuidance(config, modelKey) {
|
|
151822
|
+
const { preset } = resolvePromptSurface(config, modelKey);
|
|
151823
|
+
return {
|
|
151824
|
+
preset,
|
|
151825
|
+
primaryOverride: readGuidanceOverride(config?.guidance_override_path)
|
|
151826
|
+
};
|
|
151827
|
+
}
|
|
151828
|
+
};
|
|
151829
|
+
}
|
|
151830
|
+
function createPromptSurfaceGuidanceEpochCache(runtime) {
|
|
151831
|
+
const epochs = new Map;
|
|
151832
|
+
return {
|
|
151833
|
+
resolve(sessionId, config, modelKey) {
|
|
151834
|
+
const cached = epochs.get(sessionId);
|
|
151835
|
+
if (cached && cached.config === config && cached.modelKey === modelKey) {
|
|
151836
|
+
return cached.selection;
|
|
151837
|
+
}
|
|
151838
|
+
const selection = runtime.resolveGuidance(config, modelKey);
|
|
151839
|
+
epochs.set(sessionId, { config, modelKey, selection });
|
|
151840
|
+
return selection;
|
|
151841
|
+
},
|
|
151842
|
+
clear(sessionId) {
|
|
151843
|
+
epochs.delete(sessionId);
|
|
151844
|
+
}
|
|
151845
|
+
};
|
|
151846
|
+
}
|
|
151847
|
+
|
|
151000
151848
|
// src/read-session-pi.ts
|
|
151001
151849
|
var SYNTH_USER_ID_PREFIX = "synth-user-";
|
|
151002
151850
|
function resolvePiStableId(msg, index, entryIds, entryIdByRef) {
|
|
@@ -151347,7 +152195,7 @@ function pruneNestedConfigLeaf(block, relativePath) {
|
|
|
151347
152195
|
}
|
|
151348
152196
|
|
|
151349
152197
|
// src/config/index.ts
|
|
151350
|
-
import { existsSync as
|
|
152198
|
+
import { existsSync as existsSync9, readFileSync as readFileSync9 } from "node:fs";
|
|
151351
152199
|
|
|
151352
152200
|
// ../plugin/src/config/migrate-dreamer-v2.ts
|
|
151353
152201
|
var OLD_VERIFY_TASK = "verify";
|
|
@@ -166204,6 +167052,23 @@ var PiThinkingLevelSchema = exports_external.enum(["off", "minimal", "low", "med
|
|
|
166204
167052
|
var PiConfigSchema = exports_external.object({
|
|
166205
167053
|
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.")
|
|
166206
167054
|
}).optional();
|
|
167055
|
+
var PromptSurfacePresetSchema = exports_external.enum(["full", "light"]);
|
|
167056
|
+
var PromptSurfaceModelKeySchema = exports_external.string().refine(isValidPromptSurfaceModelKey, {
|
|
167057
|
+
message: "Use a non-empty provider/model key or the literal provider/* wildcard; model IDs may contain additional slashes and matching is case-sensitive."
|
|
167058
|
+
});
|
|
167059
|
+
var PromptSurfaceToolKeySchema = exports_external.string().refine((value) => value.trim().length > 0, {
|
|
167060
|
+
message: "tool description keys must not be empty or whitespace-only"
|
|
167061
|
+
});
|
|
167062
|
+
var PromptSurfaceConfigSchema = exports_external.object({
|
|
167063
|
+
default: PromptSurfacePresetSchema.default("full").describe('Fallback prompt-surface preset ("full" or "light").'),
|
|
167064
|
+
models: exports_external.record(PromptSurfaceModelKeySchema, PromptSurfacePresetSchema).optional().describe("Literal per-model routing. Keys are provider/model or provider/*; matching is case-sensitive and preserves additional slashes in model IDs."),
|
|
167065
|
+
guidance_override_path: exports_external.string().refine((value) => value.trim().length > 0, {
|
|
167066
|
+
message: "guidance_override_path must not be empty or whitespace-only"
|
|
167067
|
+
}).optional().describe("USER-LEVEL ONLY path to a complete primary guidance section. Relative paths resolve from the user config file."),
|
|
167068
|
+
tool_descriptions: exports_external.record(PromptSurfaceToolKeySchema, exports_external.string().refine((value) => value.trim().length > 0, {
|
|
167069
|
+
message: "tool description values must not be empty or whitespace-only"
|
|
167070
|
+
})).optional().describe("USER-LEVEL ONLY top-level description overrides keyed by ctx_* tool ID; parameter schemas and descriptions are unchanged.")
|
|
167071
|
+
}).describe("Prompt-surface preset routing. Project config may select default/models, while guidance_override_path and tool_descriptions are user-level only.");
|
|
166207
167072
|
var CronScheduleSchema = exports_external.string().refine((s) => s.trim() === "" || isValidCron(s), {
|
|
166208
167073
|
message: 'Invalid schedule: use a 5-field cron expression (e.g. "0 3 * * *" for 3am daily, "0 3 * * 0" for Sunday 3am, "0 */6 * * *" every 6h) or "" to disable.'
|
|
166209
167074
|
}).describe('5-field cron schedule (e.g. "0 3 * * *"), or "" to disable this task.');
|
|
@@ -166386,6 +167251,7 @@ var MagicContextConfigSchema = exports_external.object({
|
|
|
166386
167251
|
historian: HistorianConfigSchema.describe("Historian agent configuration (model, fallback_models, variant, temperature, maxTokens, permission, two_pass, etc.)"),
|
|
166387
167252
|
dreamer: DreamerConfigSchema.optional().describe("Dreamer agent + scheduling configuration (model, fallback_models, disable, schedule, tasks, etc.)"),
|
|
166388
167253
|
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.'),
|
|
167254
|
+
prompt_surface: PromptSurfaceConfigSchema.default({ default: "full" }).describe("Prompt-surface presets: default is full; models use the literal provider/model or provider/* routing grammar. Guidance and tool-description overrides are user-level only. On OpenCode and Pi, per-model routing applies to the guidance block only: tool descriptions are registered once per process, so they follow the default preset (a v1 plugin-surface limitation; per-model tool descriptions are planned for the OpenCode v2 plugin API once the SDK stabilizes)."),
|
|
166389
167255
|
output_reserve: exports_external.union([
|
|
166390
167256
|
exports_external.number().min(0),
|
|
166391
167257
|
exports_external.object({ default: exports_external.number().min(0) }).catchall(exports_external.number().min(0))
|
|
@@ -166434,7 +167300,7 @@ var MagicContextConfigSchema = exports_external.object({
|
|
|
166434
167300
|
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."),
|
|
166435
167301
|
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."),
|
|
166436
167302
|
compaction: exports_external.object({
|
|
166437
|
-
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.
|
|
167303
|
+
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. 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.")
|
|
166438
167304
|
}).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."),
|
|
166439
167305
|
todowrite: exports_external.object({
|
|
166440
167306
|
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."),
|
|
@@ -166480,6 +167346,7 @@ var MagicContextConfigSchema = exports_external.object({
|
|
|
166480
167346
|
// ../plugin/src/config/project-security.ts
|
|
166481
167347
|
var HIDDEN_AGENT_KEYS = ["historian", "dreamer", "sidekick"];
|
|
166482
167348
|
var HISTORIAN_USER_ONLY_FIELDS = ["model", "fallback_models"];
|
|
167349
|
+
var PROMPT_SURFACE_USER_ONLY_FIELDS = ["guidance_override_path", "tool_descriptions"];
|
|
166483
167350
|
var AGENT_ESCALATION_FIELDS = ["prompt", "permission", "tools", "system_prompt"];
|
|
166484
167351
|
var EMBEDDING_DESTINATION_FIELDS = ["endpoint", "provider", "fallback_provider"];
|
|
166485
167352
|
var PERCENTAGE_THRESHOLD_REASON = "security: a repository may only raise compaction thresholds above the user's effective value; it cannot force earlier historian work or cloned-repo cost escalation.";
|
|
@@ -166615,6 +167482,19 @@ function stripUnsafeProjectConfigFields(projectRaw) {
|
|
|
166615
167482
|
delete storage.enforce_private_permissions;
|
|
166616
167483
|
warnings.push("Ignoring storage.enforce_private_permissions from project config (security: only user-level config may opt into externally managed shared storage permissions).");
|
|
166617
167484
|
}
|
|
167485
|
+
const promptSurface = projectRaw.prompt_surface;
|
|
167486
|
+
if (isPlainObject3(promptSurface)) {
|
|
167487
|
+
const removed = [];
|
|
167488
|
+
for (const field of PROMPT_SURFACE_USER_ONLY_FIELDS) {
|
|
167489
|
+
if (field in promptSurface) {
|
|
167490
|
+
delete promptSurface[field];
|
|
167491
|
+
removed.push(field);
|
|
167492
|
+
}
|
|
167493
|
+
}
|
|
167494
|
+
if (removed.length > 0) {
|
|
167495
|
+
warnings.push(`Ignoring prompt_surface.${removed.join("/")} from project config (security: repositories may select prompt presets but only user config may provide guidance or tool-description text).`);
|
|
167496
|
+
}
|
|
167497
|
+
}
|
|
166618
167498
|
const pi = projectRaw.pi;
|
|
166619
167499
|
if (isPlainObject3(pi) && "subagent_extensions" in pi) {
|
|
166620
167500
|
delete pi.subagent_extensions;
|
|
@@ -166811,76 +167691,18 @@ function dropInheritedEmbeddingKeyOnRedirect(projectRaw, mergedRaw, userRaw) {
|
|
|
166811
167691
|
}
|
|
166812
167692
|
|
|
166813
167693
|
// ../plugin/src/config/variable.ts
|
|
166814
|
-
import { existsSync as
|
|
167694
|
+
import { existsSync as existsSync8, readFileSync as readFileSync7 } from "node:fs";
|
|
166815
167695
|
import { homedir as homedir4 } from "node:os";
|
|
166816
|
-
import { dirname as
|
|
166817
|
-
|
|
166818
|
-
// ../plugin/src/shared/jsonc-parser.ts
|
|
166819
|
-
function stripJsonComments(content) {
|
|
166820
|
-
let result = "";
|
|
166821
|
-
let inString = false;
|
|
166822
|
-
let escaped = false;
|
|
166823
|
-
let inLineComment = false;
|
|
166824
|
-
let inBlockComment = false;
|
|
166825
|
-
for (let index = 0;index < content.length; index += 1) {
|
|
166826
|
-
const char = content[index];
|
|
166827
|
-
const next = content[index + 1];
|
|
166828
|
-
if (inLineComment) {
|
|
166829
|
-
if (char === `
|
|
166830
|
-
`) {
|
|
166831
|
-
inLineComment = false;
|
|
166832
|
-
result += char;
|
|
166833
|
-
}
|
|
166834
|
-
continue;
|
|
166835
|
-
}
|
|
166836
|
-
if (inBlockComment) {
|
|
166837
|
-
if (char === "*" && next === "/") {
|
|
166838
|
-
inBlockComment = false;
|
|
166839
|
-
index += 1;
|
|
166840
|
-
}
|
|
166841
|
-
continue;
|
|
166842
|
-
}
|
|
166843
|
-
if (inString) {
|
|
166844
|
-
result += char;
|
|
166845
|
-
if (escaped) {
|
|
166846
|
-
escaped = false;
|
|
166847
|
-
} else if (char === "\\") {
|
|
166848
|
-
escaped = true;
|
|
166849
|
-
} else if (char === '"') {
|
|
166850
|
-
inString = false;
|
|
166851
|
-
}
|
|
166852
|
-
continue;
|
|
166853
|
-
}
|
|
166854
|
-
if (char === '"') {
|
|
166855
|
-
inString = true;
|
|
166856
|
-
result += char;
|
|
166857
|
-
continue;
|
|
166858
|
-
}
|
|
166859
|
-
if (char === "/" && next === "/") {
|
|
166860
|
-
inLineComment = true;
|
|
166861
|
-
index += 1;
|
|
166862
|
-
continue;
|
|
166863
|
-
}
|
|
166864
|
-
if (char === "/" && next === "*") {
|
|
166865
|
-
inBlockComment = true;
|
|
166866
|
-
index += 1;
|
|
166867
|
-
continue;
|
|
166868
|
-
}
|
|
166869
|
-
result += char;
|
|
166870
|
-
}
|
|
166871
|
-
return result;
|
|
166872
|
-
}
|
|
166873
|
-
|
|
166874
|
-
// ../plugin/src/config/variable.ts
|
|
167696
|
+
import { dirname as dirname4, isAbsolute as isAbsolute3, resolve as resolve2 } from "node:path";
|
|
166875
167697
|
var ENV_PATTERN = /\{env:([^}]+)\}/g;
|
|
166876
167698
|
var FILE_PATTERN = /\{file:([^}]+)\}/g;
|
|
166877
167699
|
function sensitiveFilePathReason(resolvedPath) {
|
|
166878
167700
|
const home = homedir4();
|
|
166879
167701
|
const sensitiveDirs = [
|
|
166880
|
-
{ dir:
|
|
166881
|
-
{ dir:
|
|
166882
|
-
{ dir:
|
|
166883
|
-
{ dir:
|
|
167702
|
+
{ dir: resolve2(home, ".ssh"), label: "SSH keys" },
|
|
167703
|
+
{ dir: resolve2(home, ".aws"), label: "AWS credentials" },
|
|
167704
|
+
{ dir: resolve2(home, ".gnupg"), label: "GnuPG keyring" },
|
|
167705
|
+
{ dir: resolve2(home, ".config", "gh"), label: "GitHub CLI auth" }
|
|
166884
167706
|
];
|
|
166885
167707
|
for (const { dir, label } of sensitiveDirs) {
|
|
166886
167708
|
if (resolvedPath === dir || resolvedPath.startsWith(`${dir}/`)) {
|
|
@@ -166920,7 +167742,7 @@ function substituteConfigVariables(input) {
|
|
|
166920
167742
|
if (fileMatches.length === 0) {
|
|
166921
167743
|
return { text, warnings };
|
|
166922
167744
|
}
|
|
166923
|
-
const configDir = input.configPath ?
|
|
167745
|
+
const configDir = input.configPath ? dirname4(input.configPath) : process.cwd();
|
|
166924
167746
|
let output = "";
|
|
166925
167747
|
let cursor = 0;
|
|
166926
167748
|
for (const match of fileMatches) {
|
|
@@ -166938,21 +167760,21 @@ function substituteConfigVariables(input) {
|
|
|
166938
167760
|
}
|
|
166939
167761
|
let filePath = rawPath.trim();
|
|
166940
167762
|
if (filePath.startsWith("~/")) {
|
|
166941
|
-
filePath =
|
|
166942
|
-
} else if (!
|
|
166943
|
-
filePath =
|
|
167763
|
+
filePath = resolve2(homedir4(), filePath.slice(2));
|
|
167764
|
+
} else if (!isAbsolute3(filePath)) {
|
|
167765
|
+
filePath = resolve2(configDir, filePath);
|
|
166944
167766
|
}
|
|
166945
167767
|
const sensitiveReason = sensitiveFilePathReason(filePath);
|
|
166946
167768
|
if (sensitiveReason) {
|
|
166947
167769
|
warnings.push(`${token} resolves to a sensitive path (${sensitiveReason}: ${filePath}); ` + "inlining its contents into config — make sure this is intentional.");
|
|
166948
167770
|
}
|
|
166949
|
-
if (!
|
|
167771
|
+
if (!existsSync8(filePath)) {
|
|
166950
167772
|
warnings.push(`File not found for ${token} (resolved to ${filePath}); using empty string`);
|
|
166951
167773
|
continue;
|
|
166952
167774
|
}
|
|
166953
167775
|
let contents;
|
|
166954
167776
|
try {
|
|
166955
|
-
contents =
|
|
167777
|
+
contents = readFileSync7(filePath, "utf-8").trim();
|
|
166956
167778
|
} catch (error51) {
|
|
166957
167779
|
const message = error51 instanceof Error ? error51.message : String(error51);
|
|
166958
167780
|
warnings.push(`Failed to read file for ${token} (${filePath}): ${message}; using empty string`);
|
|
@@ -166965,7 +167787,7 @@ function substituteConfigVariables(input) {
|
|
|
166965
167787
|
}
|
|
166966
167788
|
|
|
166967
167789
|
// ../plugin/src/shared/models-dev-cache.ts
|
|
166968
|
-
import { mkdirSync as mkdirSync3, readFileSync as
|
|
167790
|
+
import { mkdirSync as mkdirSync3, readFileSync as readFileSync8, renameSync as renameSync2, writeFileSync as writeFileSync2 } from "node:fs";
|
|
166969
167791
|
import { join as join5 } from "node:path";
|
|
166970
167792
|
|
|
166971
167793
|
// ../plugin/src/shared/harness-provider-map.ts
|
|
@@ -167015,7 +167837,7 @@ function loadPersistedApiCacheOnce() {
|
|
|
167015
167837
|
return;
|
|
167016
167838
|
persistSeedLoaded = true;
|
|
167017
167839
|
try {
|
|
167018
|
-
const raw =
|
|
167840
|
+
const raw = readFileSync8(persistFilePath(), "utf-8");
|
|
167019
167841
|
const obj = JSON.parse(raw);
|
|
167020
167842
|
const map2 = new Map;
|
|
167021
167843
|
for (const [key, persisted] of Object.entries(obj)) {
|
|
@@ -167043,7 +167865,7 @@ function loadPersistedApiCacheOnce() {
|
|
|
167043
167865
|
function isFinitePositive(value) {
|
|
167044
167866
|
return typeof value === "number" && Number.isFinite(value) && value > 0;
|
|
167045
167867
|
}
|
|
167046
|
-
function
|
|
167868
|
+
function modelKeyLookupOrder2(providerID, modelID) {
|
|
167047
167869
|
const full = `${providerID}/${modelID}`;
|
|
167048
167870
|
const canonicalFull = piModelRefToCanonical(full);
|
|
167049
167871
|
const candidates = [full, canonicalFull, modelID];
|
|
@@ -167060,7 +167882,7 @@ function configuredOutputReserve(config2, providerID, modelID) {
|
|
|
167060
167882
|
return Number.isFinite(config2) && config2 >= 0 ? config2 : undefined;
|
|
167061
167883
|
if (!config2)
|
|
167062
167884
|
return;
|
|
167063
|
-
for (const candidate of
|
|
167885
|
+
for (const candidate of modelKeyLookupOrder2(providerID, modelID)) {
|
|
167064
167886
|
const value = config2[candidate];
|
|
167065
167887
|
if (typeof value === "number" && Number.isFinite(value) && value >= 0)
|
|
167066
167888
|
return value;
|
|
@@ -167157,14 +167979,14 @@ function getUserConfigPaths() {
|
|
|
167157
167979
|
return [`${basePath}.jsonc`, `${basePath}.json`];
|
|
167158
167980
|
}
|
|
167159
167981
|
function resolveFirstExisting(paths) {
|
|
167160
|
-
return paths.find((path3) =>
|
|
167982
|
+
return paths.find((path3) => existsSync9(path3));
|
|
167161
167983
|
}
|
|
167162
167984
|
function resolvePiLegacyFallback(sources) {
|
|
167163
|
-
return sources.find((source) =>
|
|
167985
|
+
return sources.find((source) => existsSync9(source.path)) ?? null;
|
|
167164
167986
|
}
|
|
167165
167987
|
function loadConfigFile(path3, scope) {
|
|
167166
167988
|
try {
|
|
167167
|
-
const rawText =
|
|
167989
|
+
const rawText = readFileSync9(path3, "utf-8");
|
|
167168
167990
|
const substituted = substituteConfigVariables({
|
|
167169
167991
|
text: rawText,
|
|
167170
167992
|
configPath: path3,
|
|
@@ -167297,7 +168119,7 @@ function loadPiConfig(opts = {}) {
|
|
|
167297
168119
|
if (loaded)
|
|
167298
168120
|
loadedFiles.push(loaded);
|
|
167299
168121
|
}
|
|
167300
|
-
const legacyProjectUnmigrated = !projectPath && !projectLegacyFallback && legacySources.project.some((source) =>
|
|
168122
|
+
const legacyProjectUnmigrated = !projectPath && !projectLegacyFallback && legacySources.project.some((source) => existsSync9(source.path));
|
|
167301
168123
|
const userPath = resolveFirstExisting(getUserConfigPaths());
|
|
167302
168124
|
const userLegacyFallback = userPath ? null : resolvePiLegacyFallback(harnessLegacy.user);
|
|
167303
168125
|
const userReadPath = userPath ?? userLegacyFallback?.path;
|
|
@@ -167306,7 +168128,7 @@ function loadPiConfig(opts = {}) {
|
|
|
167306
168128
|
if (loaded)
|
|
167307
168129
|
loadedFiles.push(loaded);
|
|
167308
168130
|
}
|
|
167309
|
-
const legacyUserUnmigrated = !userPath && !userLegacyFallback && legacySources.user.some((source) =>
|
|
168131
|
+
const legacyUserUnmigrated = !userPath && !userLegacyFallback && legacySources.user.some((source) => existsSync9(source.path));
|
|
167310
168132
|
if (userLegacyFallback) {
|
|
167311
168133
|
warnings.push(`[user config] reading legacy config from ${userLegacyFallback.path} until migration completes; run \`npx @cortexkit/magic-context doctor\` to consolidate into the shared CortexKit location.`);
|
|
167312
168134
|
} else if (legacyUserUnmigrated) {
|
|
@@ -167353,6 +168175,7 @@ function loadPiConfig(opts = {}) {
|
|
|
167353
168175
|
warnings.push(...parsed.warnings.map((warning) => `[merged config] ${warning}`));
|
|
167354
168176
|
return {
|
|
167355
168177
|
config: parsed.config,
|
|
168178
|
+
registrationPromptSurface: trustedBaseConfig.prompt_surface,
|
|
167356
168179
|
warnings,
|
|
167357
168180
|
loadedFromPaths: loadedFiles.map((loaded) => loaded.path)
|
|
167358
168181
|
};
|
|
@@ -167416,7 +168239,7 @@ function loadPiConfigDetailed(opts = {}) {
|
|
|
167416
168239
|
if (loaded)
|
|
167417
168240
|
loadedFiles.push(loaded);
|
|
167418
168241
|
}
|
|
167419
|
-
const legacyProjectUnmigrated = !projectPath && !projectLegacyFallback && legacySources.project.some((source) =>
|
|
168242
|
+
const legacyProjectUnmigrated = !projectPath && !projectLegacyFallback && legacySources.project.some((source) => existsSync9(source.path));
|
|
167420
168243
|
const userPath = resolveFirstExisting(getUserConfigPaths());
|
|
167421
168244
|
const userLegacyFallback = userPath ? null : resolvePiLegacyFallback(harnessLegacy.user);
|
|
167422
168245
|
const userReadPath = userPath ?? userLegacyFallback?.path;
|
|
@@ -167425,7 +168248,7 @@ function loadPiConfigDetailed(opts = {}) {
|
|
|
167425
168248
|
if (loaded)
|
|
167426
168249
|
loadedFiles.push(loaded);
|
|
167427
168250
|
}
|
|
167428
|
-
const legacyUserUnmigrated = !userPath && !userLegacyFallback && legacySources.user.some((source) =>
|
|
168251
|
+
const legacyUserUnmigrated = !userPath && !userLegacyFallback && legacySources.user.some((source) => existsSync9(source.path));
|
|
167429
168252
|
if (userLegacyFallback) {
|
|
167430
168253
|
warnings.push(`[user config] reading legacy config from ${userLegacyFallback.path} until migration completes; run \`npx @cortexkit/magic-context doctor\` to consolidate into the shared CortexKit location.`);
|
|
167431
168254
|
} else if (legacyUserUnmigrated) {
|
|
@@ -167480,6 +168303,7 @@ function loadPiConfigDetailed(opts = {}) {
|
|
|
167480
168303
|
};
|
|
167481
168304
|
return {
|
|
167482
168305
|
config: parsed.config,
|
|
168306
|
+
registrationPromptSurface: trustedBaseConfig.prompt_surface,
|
|
167483
168307
|
warnings,
|
|
167484
168308
|
loadedFromPaths: loadedFiles.map((loaded) => loaded.path),
|
|
167485
168309
|
loadOutcome: combinedOutcome({
|
|
@@ -167494,7 +168318,7 @@ function loadPiConfigDetailed(opts = {}) {
|
|
|
167494
168318
|
}
|
|
167495
168319
|
|
|
167496
168320
|
// src/embedding-bootstrap.ts
|
|
167497
|
-
import { statSync as
|
|
168321
|
+
import { statSync as statSync6 } from "node:fs";
|
|
167498
168322
|
|
|
167499
168323
|
// ../plugin/src/features/magic-context/compartment-chunk-embedding.ts
|
|
167500
168324
|
import { createHash as createHash8 } from "node:crypto";
|
|
@@ -168564,7 +169388,7 @@ class SubcSocket {
|
|
|
168564
169388
|
return this.sock.localPort ?? null;
|
|
168565
169389
|
}
|
|
168566
169390
|
static connect(host, port, deadlineMs) {
|
|
168567
|
-
return new Promise((
|
|
169391
|
+
return new Promise((resolve3, reject) => {
|
|
168568
169392
|
const sock = net.connect({ host, port });
|
|
168569
169393
|
sock.setNoDelay(true);
|
|
168570
169394
|
const timer = setTimeout(() => {
|
|
@@ -168573,7 +169397,7 @@ class SubcSocket {
|
|
|
168573
169397
|
}, Math.max(0, deadlineMs - Date.now()));
|
|
168574
169398
|
sock.once("connect", () => {
|
|
168575
169399
|
clearTimeout(timer);
|
|
168576
|
-
|
|
169400
|
+
resolve3(new SubcSocket(sock));
|
|
168577
169401
|
});
|
|
168578
169402
|
sock.once("error", (err) => {
|
|
168579
169403
|
clearTimeout(timer);
|
|
@@ -168605,7 +169429,7 @@ class SubcSocket {
|
|
|
168605
169429
|
}
|
|
168606
169430
|
if (n === 0)
|
|
168607
169431
|
return Promise.resolve(new Uint8Array(0));
|
|
168608
|
-
return new Promise((
|
|
169432
|
+
return new Promise((resolve3, reject) => {
|
|
168609
169433
|
let timer = null;
|
|
168610
169434
|
if (Number.isFinite(deadlineMs)) {
|
|
168611
169435
|
const remaining = deadlineMs - Date.now();
|
|
@@ -168618,7 +169442,7 @@ class SubcSocket {
|
|
|
168618
169442
|
reject(new SocketTimeoutError(`timed out waiting for ${n} bytes`));
|
|
168619
169443
|
}, remaining);
|
|
168620
169444
|
}
|
|
168621
|
-
this.waiter = { need: n, resolve:
|
|
169445
|
+
this.waiter = { need: n, resolve: resolve3, reject, timer };
|
|
168622
169446
|
this.tryServe();
|
|
168623
169447
|
});
|
|
168624
169448
|
}
|
|
@@ -168642,7 +169466,7 @@ class SubcSocket {
|
|
|
168642
169466
|
let queued = false;
|
|
168643
169467
|
let settled = false;
|
|
168644
169468
|
let timer = null;
|
|
168645
|
-
const completed = new Promise((
|
|
169469
|
+
const completed = new Promise((resolve3, reject) => {
|
|
168646
169470
|
const settle = (run) => {
|
|
168647
169471
|
if (settled)
|
|
168648
169472
|
return;
|
|
@@ -168666,7 +169490,7 @@ class SubcSocket {
|
|
|
168666
169490
|
if (err) {
|
|
168667
169491
|
reject(new SocketWriteQueuedError("subc socket reported a write error after bytes were handed to the socket", err instanceof Error ? err : new Error(String(err))));
|
|
168668
169492
|
} else {
|
|
168669
|
-
|
|
169493
|
+
resolve3();
|
|
168670
169494
|
}
|
|
168671
169495
|
});
|
|
168672
169496
|
});
|
|
@@ -168882,14 +169706,14 @@ class SubcClient {
|
|
|
168882
169706
|
const admission = opts.admissionClass ?? AdmissionClass.Normal;
|
|
168883
169707
|
const corr = this.allocateCorr();
|
|
168884
169708
|
const key = pendingKey(handle, corr);
|
|
168885
|
-
const closed = new Promise((
|
|
169709
|
+
const closed = new Promise((resolve3, reject) => {
|
|
168886
169710
|
if (this.closedErr) {
|
|
168887
169711
|
reject(this.closedErr);
|
|
168888
169712
|
return;
|
|
168889
169713
|
}
|
|
168890
169714
|
this.pending.set(key, {
|
|
168891
169715
|
handle,
|
|
168892
|
-
resolve: () =>
|
|
169716
|
+
resolve: () => resolve3(),
|
|
168893
169717
|
reject,
|
|
168894
169718
|
onProgress: onEvent,
|
|
168895
169719
|
timer: null,
|
|
@@ -168974,11 +169798,11 @@ class SubcClient {
|
|
|
168974
169798
|
const waiters = [];
|
|
168975
169799
|
for (const pending of this.pending.values()) {
|
|
168976
169800
|
if (pending.handle === handle && !pending.subscription) {
|
|
168977
|
-
waiters.push(new Promise((
|
|
169801
|
+
waiters.push(new Promise((resolve3) => {
|
|
168978
169802
|
const previous = pending.onSettle;
|
|
168979
169803
|
pending.onSettle = () => {
|
|
168980
169804
|
previous?.();
|
|
168981
|
-
|
|
169805
|
+
resolve3();
|
|
168982
169806
|
};
|
|
168983
169807
|
}));
|
|
168984
169808
|
}
|
|
@@ -169034,11 +169858,11 @@ class SubcClient {
|
|
|
169034
169858
|
const channel = handle?.channel ?? 0;
|
|
169035
169859
|
const epoch = handle?.epoch ?? 0;
|
|
169036
169860
|
const frame = buildFrame(FrameType.Request, buildFlags(false, priority, false, admission), channel, epoch, corr, body);
|
|
169037
|
-
return new Promise((
|
|
169861
|
+
return new Promise((resolve3, reject) => {
|
|
169038
169862
|
const ms = timeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;
|
|
169039
169863
|
const pending = {
|
|
169040
169864
|
handle,
|
|
169041
|
-
resolve:
|
|
169865
|
+
resolve: resolve3,
|
|
169042
169866
|
reject,
|
|
169043
169867
|
onProgress,
|
|
169044
169868
|
timer: null,
|
|
@@ -169112,11 +169936,11 @@ class SubcClient {
|
|
|
169112
169936
|
}
|
|
169113
169937
|
return this.outcomeUnknownCallError("connection dropped before the managed call returned a response", error51);
|
|
169114
169938
|
};
|
|
169115
|
-
return new Promise((
|
|
169939
|
+
return new Promise((resolve3, reject) => {
|
|
169116
169940
|
const ms = timeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;
|
|
169117
169941
|
const pending = {
|
|
169118
169942
|
handle,
|
|
169119
|
-
resolve:
|
|
169943
|
+
resolve: resolve3,
|
|
169120
169944
|
reject,
|
|
169121
169945
|
onProgress,
|
|
169122
169946
|
timer: null,
|
|
@@ -169504,7 +170328,7 @@ function normalizeConnectOptions(opts) {
|
|
|
169504
170328
|
identity: opts.identity,
|
|
169505
170329
|
targetKind: opts.targetKind ?? DEFAULT_MANAGED_TARGET_KIND,
|
|
169506
170330
|
reconnectBackoff: opts.reconnectBackoff ?? DEFAULT_RECONNECT_BACKOFF,
|
|
169507
|
-
sleep: opts.sleep ?? ((ms) => new Promise((
|
|
170331
|
+
sleep: opts.sleep ?? ((ms) => new Promise((resolve3) => setTimeout(resolve3, ms))),
|
|
169508
170332
|
timeoutArbitrationGraceMs: opts.timeoutArbitrationGraceMs ?? TIMEOUT_ARBITRATION_GRACE_MS
|
|
169509
170333
|
};
|
|
169510
170334
|
}
|
|
@@ -169561,8 +170385,8 @@ class AsyncPermitPool {
|
|
|
169561
170385
|
this.available -= 1;
|
|
169562
170386
|
return this.releaseOnce();
|
|
169563
170387
|
}
|
|
169564
|
-
await new Promise((
|
|
169565
|
-
this.waiters.push(
|
|
170388
|
+
await new Promise((resolve3) => {
|
|
170389
|
+
this.waiters.push(resolve3);
|
|
169566
170390
|
});
|
|
169567
170391
|
return this.releaseOnce();
|
|
169568
170392
|
}
|
|
@@ -169618,8 +170442,8 @@ class SubcProvider {
|
|
|
169618
170442
|
this.currentConn = currentConn;
|
|
169619
170443
|
this.opts = opts;
|
|
169620
170444
|
this.storage = storage;
|
|
169621
|
-
this.closed = new Promise((
|
|
169622
|
-
this.resolveClosed =
|
|
170445
|
+
this.closed = new Promise((resolve3) => {
|
|
170446
|
+
this.resolveClosed = resolve3;
|
|
169623
170447
|
});
|
|
169624
170448
|
this.readLoop(sock, this.generation);
|
|
169625
170449
|
this.enqueueConnectionState({ state: "connected", epoch: this.connectionEpoch });
|
|
@@ -169639,13 +170463,13 @@ class SubcProvider {
|
|
|
169639
170463
|
const key = routeKey(handle, corr);
|
|
169640
170464
|
const timeoutMs = opts.timeoutMs ?? WRITE_TIMEOUT_MS;
|
|
169641
170465
|
const frame = buildFrame(FrameType.Request, buildFlags(false, opts.priority ?? Priority.Interactive, false, opts.admissionClass ?? AdmissionClass.Normal), handle.channel, handle.epoch, corr, body);
|
|
169642
|
-
return await new Promise((
|
|
170466
|
+
return await new Promise((resolve3, reject) => {
|
|
169643
170467
|
const timer = setTimeout(() => {
|
|
169644
170468
|
if (this.pending.delete(key))
|
|
169645
170469
|
reject(new SubcProviderError("reverse request timed out", "request_timeout"));
|
|
169646
170470
|
}, timeoutMs);
|
|
169647
170471
|
this.pending.set(key, {
|
|
169648
|
-
resolve: (response) =>
|
|
170472
|
+
resolve: (response) => resolve3(response.body),
|
|
169649
170473
|
reject,
|
|
169650
170474
|
timer
|
|
169651
170475
|
});
|
|
@@ -170117,7 +170941,7 @@ function normalizeProviderConnectOptions(opts) {
|
|
|
170117
170941
|
onBound: opts.onBound,
|
|
170118
170942
|
onRouteGone: opts.onRouteGone,
|
|
170119
170943
|
reconnectBackoff: opts.reconnectBackoff ?? DEFAULT_RECONNECT_BACKOFF,
|
|
170120
|
-
sleep: opts.sleep ?? ((ms) => new Promise((
|
|
170944
|
+
sleep: opts.sleep ?? ((ms) => new Promise((resolve3) => setTimeout(resolve3, ms))),
|
|
170121
170945
|
restoredDebounceMs: opts.restoredDebounceMs ?? DEFAULT_RESTORED_DEBOUNCE_MS,
|
|
170122
170946
|
onConnectionState: opts.onConnectionState,
|
|
170123
170947
|
launchNonce: opts.launchNonce
|
|
@@ -170162,7 +170986,7 @@ function errorCode2(err) {
|
|
|
170162
170986
|
return;
|
|
170163
170987
|
}
|
|
170164
170988
|
async function pauseBeforeStateRetry() {
|
|
170165
|
-
await new Promise((
|
|
170989
|
+
await new Promise((resolve3) => setTimeout(resolve3, 0));
|
|
170166
170990
|
}
|
|
170167
170991
|
function controlFlags() {
|
|
170168
170992
|
return buildFlags(false, Priority.Passive, false);
|
|
@@ -170400,7 +171224,7 @@ function classifyError(value) {
|
|
|
170400
171224
|
});
|
|
170401
171225
|
}
|
|
170402
171226
|
function wait(ms) {
|
|
170403
|
-
return new Promise((
|
|
171227
|
+
return new Promise((resolve3) => setTimeout(resolve3, ms));
|
|
170404
171228
|
}
|
|
170405
171229
|
function sha256(value) {
|
|
170406
171230
|
return createHash9("sha256").update(value).digest("hex");
|
|
@@ -170879,7 +171703,7 @@ function getEmbeddingProviderIdentity(config2) {
|
|
|
170879
171703
|
// ../plugin/src/features/magic-context/memory/embedding-local.ts
|
|
170880
171704
|
import { chmodSync as chmodSync2, mkdirSync as mkdirSync4 } from "node:fs";
|
|
170881
171705
|
import { open, stat, unlink, writeFile } from "node:fs/promises";
|
|
170882
|
-
import { dirname as
|
|
171706
|
+
import { dirname as dirname5, join as join6 } from "node:path";
|
|
170883
171707
|
import { pathToFileURL } from "node:url";
|
|
170884
171708
|
var LOCK_POLL_MS = 150;
|
|
170885
171709
|
var STALE_LOCK_MS = 3 * 60000;
|
|
@@ -170919,7 +171743,7 @@ async function acquireModelLoadLock(lockPath) {
|
|
|
170919
171743
|
if (Date.now() - waitStart > MAX_LOCK_WAIT_MS) {
|
|
170920
171744
|
throw new Error(`[magic-context] embedding-load lock wait exceeded ${MAX_LOCK_WAIT_MS}ms; another process is still loading the model. Skipping this init attempt to avoid an unsynchronized native load.`);
|
|
170921
171745
|
}
|
|
170922
|
-
await new Promise((
|
|
171746
|
+
await new Promise((resolve3) => setTimeout(resolve3, LOCK_POLL_MS));
|
|
170923
171747
|
}
|
|
170924
171748
|
}
|
|
170925
171749
|
}
|
|
@@ -170943,7 +171767,7 @@ async function injectWasmOrtForElectron() {
|
|
|
170943
171767
|
const { createRequire: createRequireFn } = await import("node:module");
|
|
170944
171768
|
const requireFn = createRequireFn(import.meta.url);
|
|
170945
171769
|
const mainEntry = requireFn.resolve("onnxruntime-web");
|
|
170946
|
-
const distDir =
|
|
171770
|
+
const distDir = dirname5(mainEntry);
|
|
170947
171771
|
const wasmPathsPrefix = `${pathToFileURL(distDir).href}/`;
|
|
170948
171772
|
if (ortWeb.env?.wasm) {
|
|
170949
171773
|
ortWeb.env.wasm.wasmPaths = wasmPathsPrefix;
|
|
@@ -171124,7 +171948,7 @@ class LocalEmbeddingProvider {
|
|
|
171124
171948
|
}
|
|
171125
171949
|
const delayMs = 300 * attempt + Math.floor(Math.random() * 200);
|
|
171126
171950
|
log(`[magic-context] embedding model load attempt ${attempt}/${MAX_ATTEMPTS} failed transiently, retrying in ${delayMs}ms`);
|
|
171127
|
-
await new Promise((
|
|
171951
|
+
await new Promise((resolve3) => setTimeout(resolve3, delayMs));
|
|
171128
171952
|
}
|
|
171129
171953
|
}
|
|
171130
171954
|
if (this.pipeline) {
|
|
@@ -171157,8 +171981,8 @@ class LocalEmbeddingProvider {
|
|
|
171157
171981
|
if (this.inFlight === 0) {
|
|
171158
171982
|
return Promise.resolve();
|
|
171159
171983
|
}
|
|
171160
|
-
return new Promise((
|
|
171161
|
-
this.inFlightWaiters.push(
|
|
171984
|
+
return new Promise((resolve3) => {
|
|
171985
|
+
this.inFlightWaiters.push(resolve3);
|
|
171162
171986
|
});
|
|
171163
171987
|
}
|
|
171164
171988
|
finishInFlight() {
|
|
@@ -172856,7 +173680,7 @@ async function runShadowWorker() {
|
|
|
172856
173680
|
}
|
|
172857
173681
|
processed += item.ids.length;
|
|
172858
173682
|
processedBytes += itemBytes;
|
|
172859
|
-
await new Promise((
|
|
173683
|
+
await new Promise((resolve3) => setTimeout(resolve3, 0));
|
|
172860
173684
|
}
|
|
172861
173685
|
}
|
|
172862
173686
|
function registerProjectInObservationMode(db, projectIdentity, sourceDirectory, failedConfig, failureSummary) {
|
|
@@ -173217,7 +174041,7 @@ async function embedCandidateChunkBatch(db, projectIdentity, modelId, candidates
|
|
|
173217
174041
|
if (Date.now() - attemptStart >= EMBED_SLOW_FAILURE_NO_RETRY_MS)
|
|
173218
174042
|
break;
|
|
173219
174043
|
if (attempt < EMBED_SLICE_RETRY_ATTEMPTS - 1) {
|
|
173220
|
-
await new Promise((
|
|
174044
|
+
await new Promise((resolve3) => setTimeout(resolve3, EMBED_SLICE_RETRY_BASE_MS * 2 ** attempt));
|
|
173221
174045
|
}
|
|
173222
174046
|
}
|
|
173223
174047
|
embedded += persistedIds.size;
|
|
@@ -173302,7 +174126,7 @@ async function embedSessionCompartmentChunks(db, projectIdentity, sessionId, opt
|
|
|
173302
174126
|
}
|
|
173303
174127
|
embedded += n;
|
|
173304
174128
|
options?.onProgress?.({ embedded: Math.min(embedded, total), total });
|
|
173305
|
-
await new Promise((
|
|
174129
|
+
await new Promise((resolve3) => setTimeout(resolve3, 0));
|
|
173306
174130
|
}
|
|
173307
174131
|
} finally {
|
|
173308
174132
|
clearInterval(renewal);
|
|
@@ -173545,7 +174369,7 @@ function configCandidatePaths(directory, loadedPaths) {
|
|
|
173545
174369
|
function configFingerprint(paths) {
|
|
173546
174370
|
return paths.map((path3) => {
|
|
173547
174371
|
try {
|
|
173548
|
-
const stat2 =
|
|
174372
|
+
const stat2 = statSync6(path3);
|
|
173549
174373
|
return `${path3}:${stat2.size}:${stat2.mtimeMs}`;
|
|
173550
174374
|
} catch {
|
|
173551
174375
|
return `${path3}:missing`;
|
|
@@ -178625,6 +179449,7 @@ function computeCueContentHash(content) {
|
|
|
178625
179449
|
return createHash13("sha256").update(content).digest("hex");
|
|
178626
179450
|
}
|
|
178627
179451
|
var muralCueColumnCache = new WeakMap;
|
|
179452
|
+
var muralCueRejectionColumnCache = new WeakMap;
|
|
178628
179453
|
function hasMuralCueColumns(db) {
|
|
178629
179454
|
const cached2 = muralCueColumnCache.get(db);
|
|
178630
179455
|
if (cached2 !== undefined)
|
|
@@ -178634,6 +179459,15 @@ function hasMuralCueColumns(db) {
|
|
|
178634
179459
|
muralCueColumnCache.set(db, present);
|
|
178635
179460
|
return present;
|
|
178636
179461
|
}
|
|
179462
|
+
function hasMuralCueRejectionCountColumn(db) {
|
|
179463
|
+
const cached2 = muralCueRejectionColumnCache.get(db);
|
|
179464
|
+
if (cached2 !== undefined)
|
|
179465
|
+
return cached2;
|
|
179466
|
+
const columns = db.prepare("PRAGMA table_info(memories)").all();
|
|
179467
|
+
const present = columns.some((column) => column.name === "mural_cue_rejection_count");
|
|
179468
|
+
muralCueRejectionColumnCache.set(db, present);
|
|
179469
|
+
return present;
|
|
179470
|
+
}
|
|
178637
179471
|
function getMuralCueState(db, memoryIds) {
|
|
178638
179472
|
const out = new Map;
|
|
178639
179473
|
if (!hasMuralCueColumns(db))
|
|
@@ -178642,9 +179476,14 @@ function getMuralCueState(db, memoryIds) {
|
|
|
178642
179476
|
if (ids.length === 0)
|
|
178643
179477
|
return out;
|
|
178644
179478
|
const placeholders3 = ids.map(() => "?").join(", ");
|
|
178645
|
-
const
|
|
179479
|
+
const rejectionCountColumn = hasMuralCueRejectionCountColumn(db) ? "COALESCE(mural_cue_rejection_count, 0) AS mural_cue_rejection_count" : "0 AS mural_cue_rejection_count";
|
|
179480
|
+
const rows = db.prepare(`SELECT id, mural_cue, mural_cue_hash, ${rejectionCountColumn} FROM memories WHERE id IN (${placeholders3})`).all(...ids);
|
|
178646
179481
|
for (const row of rows) {
|
|
178647
|
-
out.set(row.id, {
|
|
179482
|
+
out.set(row.id, {
|
|
179483
|
+
cue: row.mural_cue ?? null,
|
|
179484
|
+
hash: row.mural_cue_hash ?? null,
|
|
179485
|
+
...row.mural_cue_rejection_count > 0 ? { rejectionCount: row.mural_cue_rejection_count } : {}
|
|
179486
|
+
});
|
|
178648
179487
|
}
|
|
178649
179488
|
return out;
|
|
178650
179489
|
}
|
|
@@ -178661,9 +179500,25 @@ function setMuralCue(db, projectPath, id, cue, contentHash) {
|
|
|
178661
179500
|
if (!owned) {
|
|
178662
179501
|
throw new Error(`Memory ${id} does not belong to project ${projectPath}`);
|
|
178663
179502
|
}
|
|
178664
|
-
|
|
179503
|
+
const rejectionReset = hasMuralCueRejectionCountColumn(db) ? ", mural_cue_rejection_count = 0" : "";
|
|
179504
|
+
db.prepare(`UPDATE memories SET mural_cue = ?, mural_cue_hash = ?, mural_cue_at = ?${rejectionReset} WHERE id = ? AND project_path = ?`).run(cue, contentHash, Date.now(), id, projectPath);
|
|
178665
179505
|
});
|
|
178666
179506
|
}
|
|
179507
|
+
function recordMuralCueRejection(db, projectPath, id, contentHash) {
|
|
179508
|
+
if (!hasMuralCueColumns(db) || !hasMuralCueRejectionCountColumn(db))
|
|
179509
|
+
return 0;
|
|
179510
|
+
let count = 0;
|
|
179511
|
+
withPrivilegedWriter(db, () => {
|
|
179512
|
+
const owned = db.prepare("SELECT 1 FROM memories WHERE id = ? AND project_path = ?").get(id, projectPath);
|
|
179513
|
+
if (!owned) {
|
|
179514
|
+
throw new Error(`Memory ${id} does not belong to project ${projectPath}`);
|
|
179515
|
+
}
|
|
179516
|
+
const row = db.prepare("SELECT mural_cue_hash, mural_cue_rejection_count FROM memories WHERE id = ?").get(id);
|
|
179517
|
+
count = row?.mural_cue_hash === contentHash ? (row.mural_cue_rejection_count ?? 0) + 1 : 1;
|
|
179518
|
+
db.prepare("UPDATE memories SET mural_cue = NULL, mural_cue_hash = ?, mural_cue_at = ?, mural_cue_rejection_count = ? WHERE id = ? AND project_path = ?").run(contentHash, Date.now(), count, id, projectPath);
|
|
179519
|
+
});
|
|
179520
|
+
return count;
|
|
179521
|
+
}
|
|
178667
179522
|
|
|
178668
179523
|
// ../plugin/src/features/magic-context/memory/visibility.ts
|
|
178669
179524
|
var FOREIGN_VISIBLE_SQL = "status IN ('active','permanent') AND (expires_at IS NULL OR expires_at > :now_ms) AND shareable = 1 AND scope IN ('project','ecosystem','universe') AND category IN (SELECT value FROM json_each(:share_categories)) AND project_path IN (SELECT project_path FROM mc_workspace_members WHERE workspace_id = :workspace_id) AND project_path <> :reader_project";
|
|
@@ -179296,7 +180151,8 @@ function updateMemoryContent(db, id, content, normalizedHash) {
|
|
|
179296
180151
|
db.prepare("UPDATE memories SET classified_at = NULL WHERE id = ?").run(id);
|
|
179297
180152
|
}
|
|
179298
180153
|
if (hasMuralCueColumns(db)) {
|
|
179299
|
-
|
|
180154
|
+
const rejectionReset = hasMuralCueRejectionCountColumn(db) ? ", mural_cue_rejection_count = 0" : "";
|
|
180155
|
+
db.prepare(`UPDATE memories SET mural_cue = NULL, mural_cue_hash = NULL, mural_cue_at = NULL${rejectionReset} WHERE id = ?`).run(id);
|
|
179300
180156
|
}
|
|
179301
180157
|
let stmt = deleteEmbeddingOnContentUpdateStatements.get(db);
|
|
179302
180158
|
if (!stmt) {
|
|
@@ -179631,7 +180487,7 @@ function getMemoryVerifications(db, memoryIds) {
|
|
|
179631
180487
|
}
|
|
179632
180488
|
// ../plugin/src/features/magic-context/memory/verification-paths.ts
|
|
179633
180489
|
import { execFile } from "node:child_process";
|
|
179634
|
-
import { existsSync as
|
|
180490
|
+
import { existsSync as existsSync10, realpathSync as realpathSync2, statSync as statSync7 } from "node:fs";
|
|
179635
180491
|
import path3 from "node:path";
|
|
179636
180492
|
import { promisify } from "node:util";
|
|
179637
180493
|
var execFileAsync = promisify(execFile);
|
|
@@ -179738,7 +180594,7 @@ function verificationFileExists(baseRoot, filePath) {
|
|
|
179738
180594
|
return false;
|
|
179739
180595
|
const root = path3.resolve(baseRoot);
|
|
179740
180596
|
const candidate = path3.resolve(root, filePath);
|
|
179741
|
-
return isWithin(root, candidate) &&
|
|
180597
|
+
return isWithin(root, candidate) && existsSync10(candidate);
|
|
179742
180598
|
}
|
|
179743
180599
|
async function normalizeVerificationFiles(args) {
|
|
179744
180600
|
const cwd = path3.resolve(args.cwd);
|
|
@@ -179771,9 +180627,9 @@ async function normalizeVerificationFiles(args) {
|
|
|
179771
180627
|
warnings.push(`Skipped verification path "${value}" because it is the repo/project root.`);
|
|
179772
180628
|
continue;
|
|
179773
180629
|
}
|
|
179774
|
-
if (
|
|
180630
|
+
if (existsSync10(candidate)) {
|
|
179775
180631
|
try {
|
|
179776
|
-
if (
|
|
180632
|
+
if (statSync7(candidate).isDirectory()) {
|
|
179777
180633
|
warnings.push(`Skipped verification path "${value}" because it is a directory.`);
|
|
179778
180634
|
continue;
|
|
179779
180635
|
}
|
|
@@ -179802,7 +180658,7 @@ async function normalizeVerificationFiles(args) {
|
|
|
179802
180658
|
}
|
|
179803
180659
|
normalized.push(tracked);
|
|
179804
180660
|
} else {
|
|
179805
|
-
if (!
|
|
180661
|
+
if (!existsSync10(candidate)) {
|
|
179806
180662
|
warnings.push(`Skipped verification path "${value}" because it does not exist.`);
|
|
179807
180663
|
continue;
|
|
179808
180664
|
}
|
|
@@ -183044,7 +183900,7 @@ class BoundedSessionMap {
|
|
|
183044
183900
|
|
|
183045
183901
|
// ../plugin/src/features/magic-context/compaction-marker.ts
|
|
183046
183902
|
import { createHash as createHash16 } from "node:crypto";
|
|
183047
|
-
import { existsSync as
|
|
183903
|
+
import { existsSync as existsSync11 } from "node:fs";
|
|
183048
183904
|
import { join as join7 } from "node:path";
|
|
183049
183905
|
var BASE62_CHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
|
183050
183906
|
var ID_PREFIX_HEX_LENGTH = 12;
|
|
@@ -183116,7 +183972,7 @@ function getWritableOpenCodeDb() {
|
|
|
183116
183972
|
closeQuietly(cachedWriteDb.db);
|
|
183117
183973
|
} catch {}
|
|
183118
183974
|
}
|
|
183119
|
-
if (!
|
|
183975
|
+
if (!existsSync11(dbPath)) {
|
|
183120
183976
|
throw new Error(`OpenCode database not found at ${dbPath} (is OpenCode installed?)`);
|
|
183121
183977
|
}
|
|
183122
183978
|
const db = new Database(dbPath);
|
|
@@ -184178,32 +185034,41 @@ function createTodowriteTool() {
|
|
|
184178
185034
|
// src/tools/index.ts
|
|
184179
185035
|
function registerMagicContextTools(pi, opts) {
|
|
184180
185036
|
const resolveProjectIdentity2 = opts.resolveProjectIdentity ? (directory) => opts.resolveProjectIdentity?.({ cwd: directory }) : undefined;
|
|
184181
|
-
|
|
185037
|
+
const promptSurfaceRuntime = opts.promptSurfaceRuntime ?? createPromptSurfaceRuntime({
|
|
185038
|
+
userConfigDirectory: process.cwd(),
|
|
185039
|
+
warn: (message) => console.warn(`[magic-context][pi] config warning: ${message}`)
|
|
185040
|
+
});
|
|
185041
|
+
const registration = promptSurfaceRuntime.resolveRegistration(opts.promptSurface);
|
|
185042
|
+
const surfaceTool = (definition) => ({
|
|
185043
|
+
...definition,
|
|
185044
|
+
description: registration.descriptionFor(definition.name, definition.description)
|
|
185045
|
+
});
|
|
185046
|
+
pi.registerTool(surfaceTool(createCtxSearchTool({
|
|
184182
185047
|
db: opts.db,
|
|
184183
185048
|
ensureProjectRegistered: opts.ensureProjectRegistered,
|
|
184184
185049
|
memoryEnabled: opts.memoryEnabled,
|
|
184185
185050
|
embeddingEnabled: opts.embeddingEnabled,
|
|
184186
185051
|
gitCommitsEnabled: opts.gitCommitsEnabled,
|
|
184187
185052
|
resolveProjectIdentity: resolveProjectIdentity2
|
|
184188
|
-
}));
|
|
185053
|
+
})));
|
|
184189
185054
|
if (opts.memoryToolEnabled !== false) {
|
|
184190
|
-
pi.registerTool(createCtxMemoryTool({
|
|
185055
|
+
pi.registerTool(surfaceTool(createCtxMemoryTool({
|
|
184191
185056
|
db: opts.db,
|
|
184192
185057
|
ensureProjectRegistered: opts.ensureProjectRegistered,
|
|
184193
185058
|
memoryEnabled: opts.memoryEnabled,
|
|
184194
185059
|
embeddingEnabled: opts.embeddingEnabled,
|
|
184195
185060
|
allowDreamerActions: opts.allowDreamerActions ?? false,
|
|
184196
185061
|
resolveProjectIdentity: resolveProjectIdentity2
|
|
184197
|
-
}));
|
|
185062
|
+
})));
|
|
184198
185063
|
}
|
|
184199
185064
|
if (!opts.sessionScopedToolsDisabled) {
|
|
184200
|
-
pi.registerTool(createCtxNoteTool({
|
|
185065
|
+
pi.registerTool(surfaceTool(createCtxNoteTool({
|
|
184201
185066
|
db: opts.db,
|
|
184202
185067
|
dreamerEnabled: opts.dreamerEnabled ?? false,
|
|
184203
185068
|
resolveDreamerEnabled: opts.resolveDreamerEnabled,
|
|
184204
185069
|
resolveProjectIdentity: resolveProjectIdentity2
|
|
184205
|
-
}));
|
|
184206
|
-
pi.registerTool(createCtxExpandTool({ db: opts.db }));
|
|
185070
|
+
})));
|
|
185071
|
+
pi.registerTool(surfaceTool(createCtxExpandTool({ db: opts.db })));
|
|
184207
185072
|
}
|
|
184208
185073
|
if (opts.todowriteEnabled !== false) {
|
|
184209
185074
|
pi.registerTool(createTodowriteTool());
|
|
@@ -184212,12 +185077,12 @@ function registerMagicContextTools(pi, opts) {
|
|
|
184212
185077
|
}
|
|
184213
185078
|
}
|
|
184214
185079
|
if (!opts.sessionScopedToolsDisabled && !opts.compactionOff) {
|
|
184215
|
-
pi.registerTool(createCtxReduceTool({
|
|
185080
|
+
pi.registerTool(surfaceTool(createCtxReduceTool({
|
|
184216
185081
|
db: opts.db,
|
|
184217
185082
|
protectedTags: opts.protectedTags ?? 20,
|
|
184218
185083
|
resolveProtectedTags: opts.resolveProtectedTags
|
|
184219
|
-
}));
|
|
185084
|
+
})));
|
|
184220
185085
|
}
|
|
184221
185086
|
}
|
|
184222
185087
|
|
|
184223
|
-
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,
|
|
185088
|
+
export { COMPACTION_ENABLED_PATH, isDreamerRunnable, isCompactionEnabled, migrateMagicContextConfigLocations, ProjectIdentityError, resolveProjectIdentityStrict, resolveProjectIdentity, resolveProjectIdentityForSession, beginBootQuietPeriod, scheduleAfterBootQuiet, Database, closeQuietly, isMidTurn, textMentionsRecentCommit, hasMeaningfulUserText, extractTexts, extractToolCallSummaries, estimateTokens, normalizeText, isRecord, completedToolArcCrossesBoundary, estimateTrueRawMessageTokens, buildToolArcs, fenceBoundaryForToolArcs, buildTrueRawTokenIndex, computeRawRangeFingerprint, invalidateTrueRawTokenCache, stripPersistedAssistantText, byteSize, stripTagPrefix, peelLeadingMcTagNotation, prependTag, 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, 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, resolveModelConfigOrDefault, normalizeTodoStateJson, buildSyntheticTodoPart, promptSurfaceHashMaterial, createPromptSurfaceRuntime, createPromptSurfaceGuidanceEpochCache, SYNTH_USER_ID_PREFIX, resolvePiStableId, isMidTurnPi, readPiSessionMessages, findLastModelKeyFromBranch, convertEntriesToRawMessages, withContentLanguageDirective, withMigrationLanguageDirective, buildPrimaryLanguageDirective, computeCueContentHash, hasMuralCueColumns, getMuralCueState, memoryNeedsCue, setMuralCue, recordMuralCueRejection, invalidateMemory, computeNormalizedHash, hasMemoryShareableColumn, hasMemoryClassifiedAtColumn, getUnclassifiedMemoryIds, insertMemory, getMemoryByHash, getMemoriesByProject, getMemoriesByProjects, getMaxMemoryIdForProjects, readNewMemoriesForM1Union, getAllActiveMemoriesForMigration, getMemoryById, setMemoryClassification, archiveMemory, deleteMemory, getMemoryCount, getMemoryCountsByStatus, USER_MEMORY_CANDIDATE_TTL_MS, insertUserMemoryCandidates, getUserMemoryCandidates, deleteUserMemoryCandidates, pruneExpiredUserMemoryCandidates, insertUserMemory, getActiveUserMemories, updateUserMemoryContent, dismissUserMemory, getOpenCodeDbPath2 as getOpenCodeDbPath, parseCron, nextOccurrence, nextDueAtMs, DEFAULT_EXECUTE_THRESHOLD_PERCENTAGE, DEFAULT_HISTORIAN_TIMEOUT_MS, buildCanonicalChunkTextFromFts, buildCompartmentSummaryFallbackText, canonicalizeInMemoryChunkTextForEmbedding, chunkCanonicalText, chunkEmbeddingWindowsAreCurrent, replaceCompartmentChunkEmbeddings, cosineSimilarity, GIT_SWEEP_LEASE_RENEWAL_MS, acquireGitSweepLease, renewGitSweepLease, markGitSweepSuccessAndRelease, parkGitSweepNonIndexable, releaseGitSweepLease, contentSha256, sweepStaleEmbeddingIdentitiesForProject, enqueueShadowEmbeddingItems, getProjectEmbeddingSnapshot, getProjectChunkEmbeddingModelId, getProjectEmbeddingMaxInputTokens, embedTextForProject, embedBatchForProject, embedItemsForProject, embedUnembeddedMemoriesForProject, drainCommitBacklogForProject, embedSessionCompartmentChunks, getEmbeddingCoverageStatus, promoteSessionFactsDurable, embedPromotedFacts, recordMemoryMapping, recordMemoryVerifications, getUnmappedMemoryIds, clearMemoryVerifications, getMemoryVerifications, resolveGitTopLevel, readGitHead, readGitChangedFilesSince, readGitFileChangeTimesSince, verificationFileExists, normalizeVerificationFiles, 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 };
|