@cortexkit/pi-magic-context 0.18.0 → 0.19.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.js +531 -241
- package/dist/subagent-entry.js +256 -114
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -11277,7 +11277,7 @@ function finalize(ctx, schema) {
|
|
|
11277
11277
|
result.$schema = "http://json-schema.org/draft-07/schema#";
|
|
11278
11278
|
} else if (ctx.target === "draft-04") {
|
|
11279
11279
|
result.$schema = "http://json-schema.org/draft-04/schema#";
|
|
11280
|
-
} else if (ctx.target === "openapi-3.0") {}
|
|
11280
|
+
} else if (ctx.target === "openapi-3.0") {}
|
|
11281
11281
|
if (ctx.external?.uri) {
|
|
11282
11282
|
const id = ctx.external.registry.get(schema)?.id;
|
|
11283
11283
|
if (!id)
|
|
@@ -11538,7 +11538,7 @@ var formatMap, stringProcessor = (schema, ctx, _json, _params) => {
|
|
|
11538
11538
|
if (val === undefined) {
|
|
11539
11539
|
if (ctx.unrepresentable === "throw") {
|
|
11540
11540
|
throw new Error("Literal `undefined` cannot be represented in JSON Schema");
|
|
11541
|
-
}
|
|
11541
|
+
}
|
|
11542
11542
|
} else if (typeof val === "bigint") {
|
|
11543
11543
|
if (ctx.unrepresentable === "throw") {
|
|
11544
11544
|
throw new Error("BigInt literals cannot be represented in JSON Schema");
|
|
@@ -14891,10 +14891,63 @@ var init_magic_context = __esm(() => {
|
|
|
14891
14891
|
});
|
|
14892
14892
|
});
|
|
14893
14893
|
|
|
14894
|
-
// ../plugin/src/shared/
|
|
14895
|
-
|
|
14894
|
+
// ../plugin/src/shared/harness.ts
|
|
14895
|
+
function setHarness(value) {
|
|
14896
|
+
if (harnessLocked && currentHarness !== value) {
|
|
14897
|
+
throw new Error(`Magic Context: harness already locked to "${currentHarness}"; cannot change to "${value}"`);
|
|
14898
|
+
}
|
|
14899
|
+
currentHarness = value;
|
|
14900
|
+
harnessLocked = true;
|
|
14901
|
+
}
|
|
14902
|
+
function getHarness() {
|
|
14903
|
+
return currentHarness;
|
|
14904
|
+
}
|
|
14905
|
+
var currentHarness = "opencode", harnessLocked = false;
|
|
14906
|
+
|
|
14907
|
+
// ../plugin/src/shared/data-path.ts
|
|
14896
14908
|
import * as os from "node:os";
|
|
14897
14909
|
import * as path from "node:path";
|
|
14910
|
+
function getDataDir() {
|
|
14911
|
+
return process.env.XDG_DATA_HOME ?? path.join(os.homedir(), ".local", "share");
|
|
14912
|
+
}
|
|
14913
|
+
function getMagicContextTempDir(harness = getHarness()) {
|
|
14914
|
+
return path.join(os.tmpdir(), harness, "magic-context");
|
|
14915
|
+
}
|
|
14916
|
+
function getMagicContextLogPath(harness = getHarness()) {
|
|
14917
|
+
return path.join(getMagicContextTempDir(harness), "magic-context.log");
|
|
14918
|
+
}
|
|
14919
|
+
function getProjectMagicContextDir(directory) {
|
|
14920
|
+
return path.join(directory, ".opencode", "magic-context");
|
|
14921
|
+
}
|
|
14922
|
+
function getProjectMagicContextHistorianDir(directory) {
|
|
14923
|
+
return path.join(getProjectMagicContextDir(directory), "historian");
|
|
14924
|
+
}
|
|
14925
|
+
function getOpenCodeStorageDir() {
|
|
14926
|
+
return path.join(getDataDir(), "opencode", "storage");
|
|
14927
|
+
}
|
|
14928
|
+
function getMagicContextStorageDir() {
|
|
14929
|
+
return path.join(getDataDir(), "cortexkit", "magic-context");
|
|
14930
|
+
}
|
|
14931
|
+
function getLegacyOpenCodeMagicContextStorageDir() {
|
|
14932
|
+
return path.join(getOpenCodeStorageDir(), "plugin", "magic-context");
|
|
14933
|
+
}
|
|
14934
|
+
function getCacheDir() {
|
|
14935
|
+
return process.env.XDG_CACHE_HOME ?? path.join(os.homedir(), ".cache");
|
|
14936
|
+
}
|
|
14937
|
+
var init_data_path = () => {};
|
|
14938
|
+
|
|
14939
|
+
// ../plugin/src/shared/logger.ts
|
|
14940
|
+
import * as fs from "node:fs";
|
|
14941
|
+
import * as path2 from "node:path";
|
|
14942
|
+
function ensureDir(filePath) {
|
|
14943
|
+
const dir = path2.dirname(filePath);
|
|
14944
|
+
if (dir === lastEnsuredDir)
|
|
14945
|
+
return;
|
|
14946
|
+
try {
|
|
14947
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
14948
|
+
lastEnsuredDir = dir;
|
|
14949
|
+
} catch {}
|
|
14950
|
+
}
|
|
14898
14951
|
function flush() {
|
|
14899
14952
|
if (flushTimer) {
|
|
14900
14953
|
clearTimeout(flushTimer);
|
|
@@ -14905,6 +14958,8 @@ function flush() {
|
|
|
14905
14958
|
const data = buffer.join("");
|
|
14906
14959
|
buffer = [];
|
|
14907
14960
|
try {
|
|
14961
|
+
const logFile = getMagicContextLogPath();
|
|
14962
|
+
ensureDir(logFile);
|
|
14908
14963
|
fs.appendFileSync(logFile, data);
|
|
14909
14964
|
} catch {}
|
|
14910
14965
|
}
|
|
@@ -14935,9 +14990,9 @@ ${data.stack}` : ""}` : ` ${JSON.stringify(data)}`;
|
|
|
14935
14990
|
function sessionLog(sessionId, message, data) {
|
|
14936
14991
|
log(`[magic-context][${sessionId}] ${message}`, data);
|
|
14937
14992
|
}
|
|
14938
|
-
var
|
|
14993
|
+
var isTestEnv = false, buffer, flushTimer = null, FLUSH_INTERVAL_MS = 500, BUFFER_SIZE_LIMIT = 50, lastEnsuredDir = null;
|
|
14939
14994
|
var init_logger = __esm(() => {
|
|
14940
|
-
|
|
14995
|
+
init_data_path();
|
|
14941
14996
|
buffer = [];
|
|
14942
14997
|
if (!isTestEnv) {
|
|
14943
14998
|
process.on("exit", flush);
|
|
@@ -14961,30 +15016,47 @@ function cosineSimilarity(a, b) {
|
|
|
14961
15016
|
return denominator === 0 ? 0 : dotProduct / denominator;
|
|
14962
15017
|
}
|
|
14963
15018
|
|
|
14964
|
-
// ../plugin/src/
|
|
14965
|
-
import
|
|
14966
|
-
|
|
14967
|
-
|
|
14968
|
-
return process.env.XDG_DATA_HOME ?? path2.join(os2.homedir(), ".local", "share");
|
|
14969
|
-
}
|
|
14970
|
-
function getOpenCodeStorageDir() {
|
|
14971
|
-
return path2.join(getDataDir(), "opencode", "storage");
|
|
15019
|
+
// ../plugin/src/features/magic-context/memory/normalize-hash.ts
|
|
15020
|
+
import { createHash } from "node:crypto";
|
|
15021
|
+
function normalizeMemoryContent(content) {
|
|
15022
|
+
return content.toLowerCase().replace(/\s+/g, " ").trim();
|
|
14972
15023
|
}
|
|
14973
|
-
function
|
|
14974
|
-
|
|
15024
|
+
function computeNormalizedHash(content) {
|
|
15025
|
+
const normalized = normalizeMemoryContent(content);
|
|
15026
|
+
return createHash("md5").update(normalized).digest("hex");
|
|
14975
15027
|
}
|
|
14976
|
-
|
|
14977
|
-
|
|
15028
|
+
var init_normalize_hash = () => {};
|
|
15029
|
+
|
|
15030
|
+
// ../plugin/src/features/magic-context/memory/embedding-identity.ts
|
|
15031
|
+
function normalizeEndpoint(endpoint) {
|
|
15032
|
+
return endpoint?.trim().replace(/\/+$/, "") ?? "";
|
|
14978
15033
|
}
|
|
14979
|
-
function
|
|
14980
|
-
|
|
15034
|
+
function getEmbeddingProviderIdentity(config2) {
|
|
15035
|
+
if (config2.provider === "off") {
|
|
15036
|
+
return "embedding-provider:off";
|
|
15037
|
+
}
|
|
15038
|
+
const identityInput = config2.provider === "openai-compatible" ? {
|
|
15039
|
+
provider: "openai-compatible",
|
|
15040
|
+
model: config2.model.trim(),
|
|
15041
|
+
endpoint: normalizeEndpoint(config2.endpoint),
|
|
15042
|
+
apiKeyPresent: Boolean(config2.api_key?.trim())
|
|
15043
|
+
} : {
|
|
15044
|
+
provider: "local",
|
|
15045
|
+
model: config2.model?.trim() || DEFAULT_LOCAL_EMBEDDING_MODEL,
|
|
15046
|
+
endpoint: "",
|
|
15047
|
+
apiKeyPresent: false
|
|
15048
|
+
};
|
|
15049
|
+
return `embedding-provider:${computeNormalizedHash(JSON.stringify(identityInput))}`;
|
|
14981
15050
|
}
|
|
14982
|
-
var
|
|
15051
|
+
var init_embedding_identity = __esm(() => {
|
|
15052
|
+
init_magic_context();
|
|
15053
|
+
init_normalize_hash();
|
|
15054
|
+
});
|
|
14983
15055
|
|
|
14984
15056
|
// ../plugin/src/features/magic-context/memory/embedding-local.ts
|
|
14985
|
-
import { mkdirSync } from "node:fs";
|
|
15057
|
+
import { mkdirSync as mkdirSync2 } from "node:fs";
|
|
14986
15058
|
import { open, stat, unlink, writeFile } from "node:fs/promises";
|
|
14987
|
-
import { join as
|
|
15059
|
+
import { join as join2 } from "node:path";
|
|
14988
15060
|
async function acquireModelLoadLock(lockPath) {
|
|
14989
15061
|
const waitStart = Date.now();
|
|
14990
15062
|
while (true) {
|
|
@@ -15099,7 +15171,7 @@ class LocalEmbeddingProvider {
|
|
|
15099
15171
|
initPromise = null;
|
|
15100
15172
|
constructor(model = DEFAULT_LOCAL_EMBEDDING_MODEL) {
|
|
15101
15173
|
this.model = model;
|
|
15102
|
-
this.modelId =
|
|
15174
|
+
this.modelId = getEmbeddingProviderIdentity({ provider: "local", model });
|
|
15103
15175
|
}
|
|
15104
15176
|
async initialize() {
|
|
15105
15177
|
if (this.pipeline) {
|
|
@@ -15118,15 +15190,15 @@ class LocalEmbeddingProvider {
|
|
|
15118
15190
|
if (LogLevel && "ERROR" in LogLevel) {
|
|
15119
15191
|
env.logLevel = LogLevel.ERROR;
|
|
15120
15192
|
}
|
|
15121
|
-
const modelCacheDir =
|
|
15193
|
+
const modelCacheDir = join2(getMagicContextStorageDir(), "models");
|
|
15122
15194
|
try {
|
|
15123
|
-
|
|
15195
|
+
mkdirSync2(modelCacheDir, { recursive: true });
|
|
15124
15196
|
env.cacheDir = modelCacheDir;
|
|
15125
15197
|
} catch {
|
|
15126
15198
|
log("[magic-context] could not create model cache dir, using library default");
|
|
15127
15199
|
}
|
|
15128
15200
|
const createPipeline = transformersModule.pipeline;
|
|
15129
|
-
const lockPath =
|
|
15201
|
+
const lockPath = join2(modelCacheDir, ".load.lock");
|
|
15130
15202
|
const releaseLock = await acquireModelLoadLock(lockPath);
|
|
15131
15203
|
const stopHeartbeat = startLockHeartbeat(lockPath);
|
|
15132
15204
|
try {
|
|
@@ -15241,12 +15313,13 @@ var init_embedding_local = __esm(() => {
|
|
|
15241
15313
|
init_magic_context();
|
|
15242
15314
|
init_data_path();
|
|
15243
15315
|
init_logger();
|
|
15316
|
+
init_embedding_identity();
|
|
15244
15317
|
STALE_LOCK_MS = 3 * 60000;
|
|
15245
15318
|
MAX_LOCK_WAIT_MS = 5 * 60000;
|
|
15246
15319
|
});
|
|
15247
15320
|
|
|
15248
15321
|
// ../plugin/src/features/magic-context/memory/embedding-openai.ts
|
|
15249
|
-
function
|
|
15322
|
+
function normalizeEndpoint2(endpoint) {
|
|
15250
15323
|
return endpoint?.trim().replace(/\/+$/, "") ?? "";
|
|
15251
15324
|
}
|
|
15252
15325
|
|
|
@@ -15261,10 +15334,15 @@ class OpenAICompatibleEmbeddingProvider {
|
|
|
15261
15334
|
openLogged = false;
|
|
15262
15335
|
halfOpenProbeInFlight = false;
|
|
15263
15336
|
constructor(options) {
|
|
15264
|
-
this.endpoint =
|
|
15337
|
+
this.endpoint = normalizeEndpoint2(options.endpoint);
|
|
15265
15338
|
this.model = options.model?.trim() ?? "";
|
|
15266
15339
|
this.apiKey = options.apiKey?.trim() ?? "";
|
|
15267
|
-
this.modelId =
|
|
15340
|
+
this.modelId = getEmbeddingProviderIdentity({
|
|
15341
|
+
provider: "openai-compatible",
|
|
15342
|
+
endpoint: this.endpoint,
|
|
15343
|
+
model: this.model,
|
|
15344
|
+
...this.apiKey ? { api_key: this.apiKey } : {}
|
|
15345
|
+
});
|
|
15268
15346
|
}
|
|
15269
15347
|
async initialize() {
|
|
15270
15348
|
if (this.initialized)
|
|
@@ -15446,20 +15524,10 @@ class OpenAICompatibleEmbeddingProvider {
|
|
|
15446
15524
|
var FAILURE_THRESHOLD = 3, FAILURE_WINDOW_MS = 60000, OPEN_DURATION_MS, FETCH_TIMEOUT_MS = 30000;
|
|
15447
15525
|
var init_embedding_openai = __esm(() => {
|
|
15448
15526
|
init_logger();
|
|
15527
|
+
init_embedding_identity();
|
|
15449
15528
|
OPEN_DURATION_MS = 5 * 60000;
|
|
15450
15529
|
});
|
|
15451
15530
|
|
|
15452
|
-
// ../plugin/src/features/magic-context/memory/normalize-hash.ts
|
|
15453
|
-
import { createHash } from "node:crypto";
|
|
15454
|
-
function normalizeMemoryContent(content) {
|
|
15455
|
-
return content.toLowerCase().replace(/\s+/g, " ").trim();
|
|
15456
|
-
}
|
|
15457
|
-
function computeNormalizedHash(content) {
|
|
15458
|
-
const normalized = normalizeMemoryContent(content);
|
|
15459
|
-
return createHash("md5").update(normalized).digest("hex");
|
|
15460
|
-
}
|
|
15461
|
-
var init_normalize_hash = () => {};
|
|
15462
|
-
|
|
15463
15531
|
// ../plugin/src/features/magic-context/memory/storage-memory-embeddings.ts
|
|
15464
15532
|
var exports_storage_memory_embeddings = {};
|
|
15465
15533
|
__export(exports_storage_memory_embeddings, {
|
|
@@ -15604,17 +15672,8 @@ function resolveEmbeddingConfig(config2) {
|
|
|
15604
15672
|
}
|
|
15605
15673
|
return { provider: "off" };
|
|
15606
15674
|
}
|
|
15607
|
-
function
|
|
15608
|
-
|
|
15609
|
-
return "off";
|
|
15610
|
-
}
|
|
15611
|
-
if (config2.provider === "openai-compatible") {
|
|
15612
|
-
const endpoint = config2.endpoint.trim();
|
|
15613
|
-
const model = config2.model.trim();
|
|
15614
|
-
const keyHash = config2.api_key ? computeNormalizedHash(config2.api_key) : "nokey";
|
|
15615
|
-
return `openai-compat:${endpoint}:${model}:${keyHash}`;
|
|
15616
|
-
}
|
|
15617
|
-
return config2.model.trim() || DEFAULT_LOCAL_EMBEDDING_MODEL;
|
|
15675
|
+
function resolveProviderIdentity(config2) {
|
|
15676
|
+
return getEmbeddingProviderIdentity(config2);
|
|
15618
15677
|
}
|
|
15619
15678
|
function createProvider(config2) {
|
|
15620
15679
|
if (config2.provider === "off") {
|
|
@@ -15638,10 +15697,10 @@ function getOrCreateProvider() {
|
|
|
15638
15697
|
}
|
|
15639
15698
|
function initializeEmbedding(config2) {
|
|
15640
15699
|
const nextConfig = resolveEmbeddingConfig(config2);
|
|
15641
|
-
const
|
|
15700
|
+
const nextProviderIdentity = resolveProviderIdentity(nextConfig);
|
|
15642
15701
|
const previousProvider = provider;
|
|
15643
|
-
const
|
|
15644
|
-
if (
|
|
15702
|
+
const previousProviderIdentity = previousProvider?.modelId ?? resolveProviderIdentity(embeddingConfig);
|
|
15703
|
+
if (previousProviderIdentity === nextProviderIdentity) {
|
|
15645
15704
|
embeddingConfig = nextConfig;
|
|
15646
15705
|
return;
|
|
15647
15706
|
}
|
|
@@ -15789,9 +15848,9 @@ var DEFAULT_EMBEDDING_CONFIG, embeddingConfig, provider = null, loadUnembeddedMe
|
|
|
15789
15848
|
var init_embedding = __esm(() => {
|
|
15790
15849
|
init_magic_context();
|
|
15791
15850
|
init_logger();
|
|
15851
|
+
init_embedding_identity();
|
|
15792
15852
|
init_embedding_local();
|
|
15793
15853
|
init_embedding_openai();
|
|
15794
|
-
init_normalize_hash();
|
|
15795
15854
|
init_storage_memory_embeddings();
|
|
15796
15855
|
DEFAULT_EMBEDDING_CONFIG = {
|
|
15797
15856
|
provider: "local",
|
|
@@ -15983,7 +16042,7 @@ var exports_native_binding = {};
|
|
|
15983
16042
|
__export(exports_native_binding, {
|
|
15984
16043
|
resolveBetterSqliteNativeBinding: () => resolveBetterSqliteNativeBinding
|
|
15985
16044
|
});
|
|
15986
|
-
import { existsSync, mkdirSync as
|
|
16045
|
+
import { existsSync, mkdirSync as mkdirSync3, writeFileSync } from "node:fs";
|
|
15987
16046
|
import { createRequire } from "node:module";
|
|
15988
16047
|
import * as path4 from "node:path";
|
|
15989
16048
|
function logInfo(message) {
|
|
@@ -16083,7 +16142,7 @@ async function resolveBetterSqliteNativeBinding() {
|
|
|
16083
16142
|
}
|
|
16084
16143
|
logWarn(`cached binary at ${cachedPath} has wrong ABI (${cachedProbe.actual ?? "unknown"} != ${expected}); refetching`);
|
|
16085
16144
|
}
|
|
16086
|
-
|
|
16145
|
+
mkdirSync3(path4.dirname(cachedPath), { recursive: true });
|
|
16087
16146
|
const nodeFileBytes = await downloadElectronPrebuild(pkgVersion, expected);
|
|
16088
16147
|
writeFileSync(cachedPath, nodeFileBytes);
|
|
16089
16148
|
logInfo(`cached Electron prebuild at ${cachedPath} (${(nodeFileBytes.length / 1024).toFixed(1)} KB)`);
|
|
@@ -16151,9 +16210,9 @@ __export(exports_read_session_db, {
|
|
|
16151
16210
|
findLastAssistantModelFromOpenCodeDb: () => findLastAssistantModelFromOpenCodeDb,
|
|
16152
16211
|
closeReadOnlySessionDb: () => closeReadOnlySessionDb
|
|
16153
16212
|
});
|
|
16154
|
-
import { join as
|
|
16213
|
+
import { join as join4 } from "node:path";
|
|
16155
16214
|
function getOpenCodeDbPath() {
|
|
16156
|
-
return
|
|
16215
|
+
return join4(getDataDir(), "opencode", "opencode.db");
|
|
16157
16216
|
}
|
|
16158
16217
|
function closeCachedReadOnlyDb() {
|
|
16159
16218
|
if (!cachedReadOnlyDb) {
|
|
@@ -16251,21 +16310,22 @@ __export(exports_rpc_notifications, {
|
|
|
16251
16310
|
drainNotifications: () => drainNotifications
|
|
16252
16311
|
});
|
|
16253
16312
|
function pushNotification(type, payload, sessionId) {
|
|
16254
|
-
queue2.push({ type, payload, sessionId });
|
|
16313
|
+
queue2.push({ id: nextNotificationId++, type, payload, sessionId });
|
|
16255
16314
|
if (queue2.length > 100) {
|
|
16256
16315
|
queue2 = queue2.slice(-50);
|
|
16257
16316
|
}
|
|
16258
16317
|
}
|
|
16259
|
-
function drainNotifications() {
|
|
16318
|
+
function drainNotifications(lastReceivedId = 0) {
|
|
16260
16319
|
lastDrainAt = Date.now();
|
|
16261
|
-
|
|
16262
|
-
|
|
16263
|
-
|
|
16320
|
+
if (lastReceivedId > 0) {
|
|
16321
|
+
queue2 = queue2.filter((notification) => notification.id > lastReceivedId);
|
|
16322
|
+
}
|
|
16323
|
+
return [...queue2];
|
|
16264
16324
|
}
|
|
16265
16325
|
function isTuiConnected() {
|
|
16266
16326
|
return lastDrainAt > 0 && Date.now() - lastDrainAt < TUI_CONNECTED_WINDOW_MS;
|
|
16267
16327
|
}
|
|
16268
|
-
var queue2, lastDrainAt = 0, TUI_CONNECTED_WINDOW_MS = 3000;
|
|
16328
|
+
var queue2, nextNotificationId = 1, lastDrainAt = 0, TUI_CONNECTED_WINDOW_MS = 3000;
|
|
16269
16329
|
var init_rpc_notifications = __esm(() => {
|
|
16270
16330
|
queue2 = [];
|
|
16271
16331
|
});
|
|
@@ -23877,10 +23937,10 @@ var require_stringify = __commonJS((exports, module) => {
|
|
|
23877
23937
|
replacer = null;
|
|
23878
23938
|
indent = EMPTY;
|
|
23879
23939
|
};
|
|
23880
|
-
var
|
|
23940
|
+
var join12 = (one, two, gap) => one ? two ? one + two.trim() + LF + gap : one.trimRight() + repeat_line_breaks(Math.max(1, count_trailing_line_breaks(one, gap)), gap) : two ? two.trimRight() + repeat_line_breaks(Math.max(1, count_trailing_line_breaks(two, gap)), gap) : EMPTY;
|
|
23881
23941
|
var join_content = (inside, value, gap) => {
|
|
23882
23942
|
const comment = process_comments(value, PREFIX_BEFORE, gap + indent, true);
|
|
23883
|
-
return
|
|
23943
|
+
return join12(comment, inside, gap);
|
|
23884
23944
|
};
|
|
23885
23945
|
var stringify_string = (holder, key, value) => {
|
|
23886
23946
|
const raw = get_raw_string_literal(holder, key);
|
|
@@ -23902,13 +23962,13 @@ var require_stringify = __commonJS((exports, module) => {
|
|
|
23902
23962
|
if (i !== 0) {
|
|
23903
23963
|
inside += COMMA;
|
|
23904
23964
|
}
|
|
23905
|
-
const before =
|
|
23965
|
+
const before = join12(after_comma, process_comments(value, BEFORE(i), deeper_gap), deeper_gap);
|
|
23906
23966
|
inside += before || LF + deeper_gap;
|
|
23907
23967
|
inside += stringify(i, value, deeper_gap) || STR_NULL;
|
|
23908
23968
|
inside += process_comments(value, AFTER_VALUE(i), deeper_gap);
|
|
23909
23969
|
after_comma = process_comments(value, AFTER(i), deeper_gap);
|
|
23910
23970
|
}
|
|
23911
|
-
inside +=
|
|
23971
|
+
inside += join12(after_comma, process_comments(value, PREFIX_AFTER, deeper_gap), deeper_gap);
|
|
23912
23972
|
return BRACKET_OPEN + join_content(inside, value, gap) + BRACKET_CLOSE;
|
|
23913
23973
|
};
|
|
23914
23974
|
var object_stringify = (value, gap) => {
|
|
@@ -23929,13 +23989,13 @@ var require_stringify = __commonJS((exports, module) => {
|
|
|
23929
23989
|
inside += COMMA;
|
|
23930
23990
|
}
|
|
23931
23991
|
first = false;
|
|
23932
|
-
const before =
|
|
23992
|
+
const before = join12(after_comma, process_comments(value, BEFORE(key), deeper_gap), deeper_gap);
|
|
23933
23993
|
inside += before || LF + deeper_gap;
|
|
23934
23994
|
inside += quote(key) + process_comments(value, AFTER_PROP(key), deeper_gap) + COLON + process_comments(value, AFTER_COLON(key), deeper_gap) + SPACE + sv + process_comments(value, AFTER_VALUE(key), deeper_gap);
|
|
23935
23995
|
after_comma = process_comments(value, AFTER(key), deeper_gap);
|
|
23936
23996
|
};
|
|
23937
23997
|
keys.forEach(iteratee);
|
|
23938
|
-
inside +=
|
|
23998
|
+
inside += join12(after_comma, process_comments(value, PREFIX_AFTER, deeper_gap), deeper_gap);
|
|
23939
23999
|
return CURLY_BRACKET_OPEN + join_content(inside, value, gap) + CURLY_BRACKET_CLOSE;
|
|
23940
24000
|
};
|
|
23941
24001
|
function stringify(key, holder, gap) {
|
|
@@ -24030,7 +24090,7 @@ var require_src2 = __commonJS((exports, module) => {
|
|
|
24030
24090
|
// src/index.ts
|
|
24031
24091
|
init_embedding();
|
|
24032
24092
|
import { createRequire as createRequire2 } from "node:module";
|
|
24033
|
-
import { join as
|
|
24093
|
+
import { join as join14 } from "node:path";
|
|
24034
24094
|
|
|
24035
24095
|
// ../plugin/src/features/magic-context/memory/project-identity.ts
|
|
24036
24096
|
import { execSync } from "node:child_process";
|
|
@@ -157083,21 +157143,6 @@ function readSessionChunk(sessionId, tokenBudget, offset = 1, eligibleEndOrdinal
|
|
|
157083
157143
|
toolOnlyRanges
|
|
157084
157144
|
};
|
|
157085
157145
|
}
|
|
157086
|
-
|
|
157087
|
-
// ../plugin/src/shared/harness.ts
|
|
157088
|
-
var currentHarness = "opencode";
|
|
157089
|
-
var harnessLocked = false;
|
|
157090
|
-
function setHarness(value) {
|
|
157091
|
-
if (harnessLocked && currentHarness !== value) {
|
|
157092
|
-
throw new Error(`Magic Context: harness already locked to "${currentHarness}"; cannot change to "${value}"`);
|
|
157093
|
-
}
|
|
157094
|
-
currentHarness = value;
|
|
157095
|
-
harnessLocked = true;
|
|
157096
|
-
}
|
|
157097
|
-
function getHarness() {
|
|
157098
|
-
return currentHarness;
|
|
157099
|
-
}
|
|
157100
|
-
|
|
157101
157146
|
// ../plugin/src/features/magic-context/compression-depth-storage.ts
|
|
157102
157147
|
var incrementDepthStatements = new WeakMap;
|
|
157103
157148
|
var totalDepthStatements = new WeakMap;
|
|
@@ -157773,8 +157818,8 @@ function escapeXmlContent(s) {
|
|
|
157773
157818
|
}
|
|
157774
157819
|
// ../plugin/src/features/magic-context/storage-db.ts
|
|
157775
157820
|
init_data_path();
|
|
157776
|
-
import { copyFileSync, cpSync, existsSync as existsSync3, mkdirSync as
|
|
157777
|
-
import { join as
|
|
157821
|
+
import { copyFileSync, cpSync, existsSync as existsSync3, mkdirSync as mkdirSync4 } from "node:fs";
|
|
157822
|
+
import { join as join6 } from "node:path";
|
|
157778
157823
|
|
|
157779
157824
|
// ../plugin/src/shared/error-message.ts
|
|
157780
157825
|
function getErrorMessage(error51) {
|
|
@@ -157991,6 +158036,9 @@ var MIGRATIONS = [
|
|
|
157991
158036
|
embedding BLOB NOT NULL,
|
|
157992
158037
|
model_id TEXT NOT NULL,
|
|
157993
158038
|
created_at INTEGER NOT NULL,
|
|
158039
|
+
-- FK-cascade audit (v12): git_commit_embeddings.sha -> git_commits.sha
|
|
158040
|
+
-- uses ON DELETE CASCADE, so SQLite PRAGMA foreign_keys must be ON on
|
|
158041
|
+
-- every connection and v12 cleans historical orphan rows.
|
|
157994
158042
|
FOREIGN KEY(sha) REFERENCES git_commits(sha) ON DELETE CASCADE
|
|
157995
158043
|
);
|
|
157996
158044
|
|
|
@@ -158130,6 +158178,29 @@ var MIGRATIONS = [
|
|
|
158130
158178
|
db.exec("ALTER TABLE session_meta ADD COLUMN todo_synthetic_state_json TEXT DEFAULT ''");
|
|
158131
158179
|
}
|
|
158132
158180
|
}
|
|
158181
|
+
},
|
|
158182
|
+
{
|
|
158183
|
+
version: 12,
|
|
158184
|
+
description: "Clean orphan rows from FK-cascade embedding tables",
|
|
158185
|
+
up: (db) => {
|
|
158186
|
+
const hasTable = (name2) => Boolean(db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name = ?").get(name2));
|
|
158187
|
+
const memoryEmbeddings = hasTable("memory_embeddings") ? db.prepare(`DELETE FROM memory_embeddings
|
|
158188
|
+
WHERE memory_id NOT IN (SELECT id FROM memories)`).run().changes : 0;
|
|
158189
|
+
log(`[migrations] v12 cleaned ${memoryEmbeddings} orphan memory_embeddings row(s)`);
|
|
158190
|
+
const gitCommitEmbeddings = hasTable("git_commit_embeddings") ? db.prepare(`DELETE FROM git_commit_embeddings
|
|
158191
|
+
WHERE sha NOT IN (SELECT sha FROM git_commits)`).run().changes : 0;
|
|
158192
|
+
log(`[migrations] v12 cleaned ${gitCommitEmbeddings} orphan git_commit_embeddings row(s)`);
|
|
158193
|
+
}
|
|
158194
|
+
},
|
|
158195
|
+
{
|
|
158196
|
+
version: 13,
|
|
158197
|
+
description: "Add pending_compaction_marker_state column for deferred marker drain",
|
|
158198
|
+
up: (db) => {
|
|
158199
|
+
const cols = db.prepare("PRAGMA table_info(session_meta)").all();
|
|
158200
|
+
if (!cols.some((c) => c.name === "pending_compaction_marker_state")) {
|
|
158201
|
+
db.exec("ALTER TABLE session_meta ADD COLUMN pending_compaction_marker_state TEXT");
|
|
158202
|
+
}
|
|
158203
|
+
}
|
|
158133
158204
|
}
|
|
158134
158205
|
];
|
|
158135
158206
|
function ensureMigrationsTable(db) {
|
|
@@ -158197,6 +158268,28 @@ function runMigrations(db) {
|
|
|
158197
158268
|
log(`[migrations] schema version now: ${MIGRATIONS[MIGRATIONS.length - 1].version}`);
|
|
158198
158269
|
}
|
|
158199
158270
|
|
|
158271
|
+
// ../plugin/src/shared/stable-json.ts
|
|
158272
|
+
function stableStringify(value, seen = new WeakSet) {
|
|
158273
|
+
if (value === undefined)
|
|
158274
|
+
return "undefined";
|
|
158275
|
+
if (value === null || typeof value !== "object")
|
|
158276
|
+
return JSON.stringify(value) ?? String(value);
|
|
158277
|
+
if (seen.has(value))
|
|
158278
|
+
return '"[Circular]"';
|
|
158279
|
+
seen.add(value);
|
|
158280
|
+
if (Array.isArray(value)) {
|
|
158281
|
+
return `[${value.map((item) => stableStringify(item, seen)).join(",")}]`;
|
|
158282
|
+
}
|
|
158283
|
+
const entries = Object.entries(value).sort(([a], [b]) => {
|
|
158284
|
+
if (a < b)
|
|
158285
|
+
return -1;
|
|
158286
|
+
if (a > b)
|
|
158287
|
+
return 1;
|
|
158288
|
+
return 0;
|
|
158289
|
+
});
|
|
158290
|
+
return `{${entries.map(([key, child]) => `${JSON.stringify(key)}:${stableStringify(child, seen)}`).join(",")}}`;
|
|
158291
|
+
}
|
|
158292
|
+
|
|
158200
158293
|
// ../plugin/src/features/magic-context/tool-definition-tokens.ts
|
|
158201
158294
|
var measurements = new Map;
|
|
158202
158295
|
var fingerprints = new Map;
|
|
@@ -158232,11 +158325,11 @@ function loadToolDefinitionMeasurements(db) {
|
|
|
158232
158325
|
init_data_path();
|
|
158233
158326
|
init_logger();
|
|
158234
158327
|
import { existsSync as existsSync2 } from "node:fs";
|
|
158235
|
-
import { join as
|
|
158328
|
+
import { join as join5 } from "node:path";
|
|
158236
158329
|
var LEASE_DURATION_MS = 5 * 60 * 1000;
|
|
158237
158330
|
var LEASE_RENEWAL_MS = 60 * 1000;
|
|
158238
158331
|
function resolveOpencodeDbPath() {
|
|
158239
|
-
return
|
|
158332
|
+
return join5(getDataDir(), "opencode", "opencode.db");
|
|
158240
158333
|
}
|
|
158241
158334
|
function ensureBackfillStateTable(db) {
|
|
158242
158335
|
db.exec(`
|
|
@@ -158479,20 +158572,20 @@ var persistenceByDatabase = new WeakMap;
|
|
|
158479
158572
|
var persistenceErrorByDatabase = new WeakMap;
|
|
158480
158573
|
function resolveDatabasePath() {
|
|
158481
158574
|
const dbDir = getMagicContextStorageDir();
|
|
158482
|
-
return { dbDir, dbPath:
|
|
158575
|
+
return { dbDir, dbPath: join6(dbDir, "context.db") };
|
|
158483
158576
|
}
|
|
158484
158577
|
function migrateLegacyStorageIfNeeded(targetDbPath, targetDbDir) {
|
|
158485
158578
|
if (existsSync3(targetDbPath))
|
|
158486
158579
|
return;
|
|
158487
158580
|
const legacyDir = getLegacyOpenCodeMagicContextStorageDir();
|
|
158488
|
-
const legacyDbPath =
|
|
158581
|
+
const legacyDbPath = join6(legacyDir, "context.db");
|
|
158489
158582
|
if (!existsSync3(legacyDbPath))
|
|
158490
158583
|
return;
|
|
158491
158584
|
log(`[magic-context] migrating legacy plugin storage: ${legacyDir} -> ${targetDbDir} (legacy left in place as backup)`);
|
|
158492
|
-
|
|
158585
|
+
mkdirSync4(targetDbDir, { recursive: true });
|
|
158493
158586
|
for (const suffix of ["", "-wal", "-shm"]) {
|
|
158494
158587
|
const src = `${legacyDbPath}${suffix}`;
|
|
158495
|
-
const dst =
|
|
158588
|
+
const dst = join6(targetDbDir, `context.db${suffix}`);
|
|
158496
158589
|
if (existsSync3(src)) {
|
|
158497
158590
|
try {
|
|
158498
158591
|
copyFileSync(src, dst);
|
|
@@ -158501,8 +158594,8 @@ function migrateLegacyStorageIfNeeded(targetDbPath, targetDbDir) {
|
|
|
158501
158594
|
}
|
|
158502
158595
|
}
|
|
158503
158596
|
}
|
|
158504
|
-
const legacyModelsDir =
|
|
158505
|
-
const targetModelsDir =
|
|
158597
|
+
const legacyModelsDir = join6(legacyDir, "models");
|
|
158598
|
+
const targetModelsDir = join6(targetDbDir, "models");
|
|
158506
158599
|
if (existsSync3(legacyModelsDir) && !existsSync3(targetModelsDir)) {
|
|
158507
158600
|
try {
|
|
158508
158601
|
cpSync(legacyModelsDir, targetModelsDir, { recursive: true });
|
|
@@ -158512,9 +158605,9 @@ function migrateLegacyStorageIfNeeded(targetDbPath, targetDbDir) {
|
|
|
158512
158605
|
}
|
|
158513
158606
|
}
|
|
158514
158607
|
function initializeDatabase(db) {
|
|
158608
|
+
db.exec("PRAGMA foreign_keys=ON");
|
|
158515
158609
|
db.exec("PRAGMA journal_mode=WAL");
|
|
158516
158610
|
db.exec("PRAGMA busy_timeout=5000");
|
|
158517
|
-
db.exec("PRAGMA foreign_keys=ON");
|
|
158518
158611
|
db.exec(`
|
|
158519
158612
|
CREATE TABLE IF NOT EXISTS tags (
|
|
158520
158613
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
@@ -158612,6 +158705,9 @@ function initializeDatabase(db) {
|
|
|
158612
158705
|
);
|
|
158613
158706
|
|
|
158614
158707
|
CREATE TABLE IF NOT EXISTS memory_embeddings (
|
|
158708
|
+
-- FK-cascade audit (v12): memory_embeddings.memory_id -> memories.id
|
|
158709
|
+
-- uses ON DELETE CASCADE, so SQLite PRAGMA foreign_keys must be ON on
|
|
158710
|
+
-- every connection and v12 cleans historical orphan rows.
|
|
158615
158711
|
memory_id INTEGER PRIMARY KEY REFERENCES memories(id) ON DELETE CASCADE,
|
|
158616
158712
|
embedding BLOB NOT NULL,
|
|
158617
158713
|
model_id TEXT
|
|
@@ -158719,7 +158815,13 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
158719
158815
|
system_prompt_hash TEXT DEFAULT '',
|
|
158720
158816
|
memory_block_cache TEXT DEFAULT '',
|
|
158721
158817
|
memory_block_count INTEGER DEFAULT 0,
|
|
158722
|
-
memory_block_ids TEXT DEFAULT ''
|
|
158818
|
+
memory_block_ids TEXT DEFAULT '',
|
|
158819
|
+
-- pending_compaction_marker_state: intentionally NULLABLE without a
|
|
158820
|
+
-- default. Absence of a deferred marker is SQL NULL; presence is a
|
|
158821
|
+
-- valid JSON blob written via setPendingCompactionMarkerState.
|
|
158822
|
+
-- Excluded from healNullTextColumns. Readers filter IS NOT NULL AND
|
|
158823
|
+
-- != empty-string defensively. Plan v6 section 3.
|
|
158824
|
+
pending_compaction_marker_state TEXT
|
|
158723
158825
|
);
|
|
158724
158826
|
|
|
158725
158827
|
CREATE INDEX IF NOT EXISTS idx_tags_session_tag_number ON tags(session_id, tag_number);
|
|
@@ -158807,6 +158909,7 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
158807
158909
|
ensureColumn(db, "session_meta", "recomp_partial_range_end", "INTEGER DEFAULT 0");
|
|
158808
158910
|
ensureColumn(db, "session_meta", "detected_context_limit", "INTEGER DEFAULT 0");
|
|
158809
158911
|
ensureColumn(db, "session_meta", "needs_emergency_recovery", "INTEGER DEFAULT 0");
|
|
158912
|
+
ensureColumn(db, "session_meta", "pending_compaction_marker_state", "TEXT");
|
|
158810
158913
|
ensureColumn(db, "tags", "harness", "TEXT NOT NULL DEFAULT 'opencode'");
|
|
158811
158914
|
ensureColumn(db, "pending_ops", "harness", "TEXT NOT NULL DEFAULT 'opencode'");
|
|
158812
158915
|
ensureColumn(db, "source_contents", "harness", "TEXT NOT NULL DEFAULT 'opencode'");
|
|
@@ -158896,7 +158999,7 @@ function openDatabase() {
|
|
|
158896
158999
|
}
|
|
158897
159000
|
try {
|
|
158898
159001
|
migrateLegacyStorageIfNeeded(dbPath, dbDir);
|
|
158899
|
-
|
|
159002
|
+
mkdirSync4(dbDir, { recursive: true });
|
|
158900
159003
|
const db = new Database(dbPath);
|
|
158901
159004
|
initializeDatabase(db);
|
|
158902
159005
|
runMigrations(db);
|
|
@@ -159201,6 +159304,28 @@ function setStrippedPlaceholderIds(db, sessionId, ids) {
|
|
|
159201
159304
|
const json2 = ids.size > 0 ? JSON.stringify([...ids]) : "";
|
|
159202
159305
|
db.prepare("UPDATE session_meta SET stripped_placeholder_ids = ? WHERE session_id = ?").run(json2, sessionId);
|
|
159203
159306
|
}
|
|
159307
|
+
function isPendingCompactionMarker(value) {
|
|
159308
|
+
return typeof value === "object" && value !== null && typeof value.ordinal === "number" && typeof value.endMessageId === "string" && typeof value.publishedAt === "number";
|
|
159309
|
+
}
|
|
159310
|
+
function getPendingCompactionMarkerState(db, sessionId) {
|
|
159311
|
+
const row = db.prepare("SELECT pending_compaction_marker_state FROM session_meta WHERE session_id = ?").get(sessionId);
|
|
159312
|
+
const raw = row?.pending_compaction_marker_state;
|
|
159313
|
+
if (raw === null || raw === undefined || raw === "")
|
|
159314
|
+
return null;
|
|
159315
|
+
try {
|
|
159316
|
+
const parsed = JSON.parse(raw);
|
|
159317
|
+
if (isPendingCompactionMarker(parsed)) {
|
|
159318
|
+
return parsed;
|
|
159319
|
+
}
|
|
159320
|
+
} catch {}
|
|
159321
|
+
return null;
|
|
159322
|
+
}
|
|
159323
|
+
function clearPendingCompactionMarkerStateIf(db, sessionId, expected) {
|
|
159324
|
+
const expectedBlob = stableStringify(expected);
|
|
159325
|
+
const result = db.prepare(`UPDATE session_meta SET pending_compaction_marker_state = NULL
|
|
159326
|
+
WHERE session_id = ? AND pending_compaction_marker_state = ?`).run(sessionId, expectedBlob);
|
|
159327
|
+
return result.changes > 0;
|
|
159328
|
+
}
|
|
159204
159329
|
// ../plugin/src/features/magic-context/resolve-subagent-fallback.ts
|
|
159205
159330
|
init_logger();
|
|
159206
159331
|
await init_read_session_db();
|
|
@@ -159798,7 +159923,7 @@ init_data_path();
|
|
|
159798
159923
|
import { createHash as createHash3 } from "node:crypto";
|
|
159799
159924
|
import { existsSync as existsSync4, readFileSync } from "node:fs";
|
|
159800
159925
|
import { homedir as homedir2, platform } from "node:os";
|
|
159801
|
-
import { join as
|
|
159926
|
+
import { join as join7 } from "node:path";
|
|
159802
159927
|
|
|
159803
159928
|
// ../plugin/src/shared/jsonc-parser.ts
|
|
159804
159929
|
function stripJsonComments(content) {
|
|
@@ -159913,15 +160038,15 @@ function getModelsJsonPath() {
|
|
|
159913
160038
|
const cacheBase = getCacheDir();
|
|
159914
160039
|
const source = process.env.OPENCODE_MODELS_URL?.trim();
|
|
159915
160040
|
const filename = source && source !== "https://models.dev" ? `models-${hashFast(source)}.json` : "models.json";
|
|
159916
|
-
return
|
|
160041
|
+
return join7(cacheBase, "opencode", filename);
|
|
159917
160042
|
}
|
|
159918
160043
|
function getOpencodeConfigPath() {
|
|
159919
160044
|
const envDir = process.env.OPENCODE_CONFIG_DIR?.trim();
|
|
159920
|
-
const configDir = envDir ? envDir : platform() === "win32" ?
|
|
159921
|
-
const jsonc =
|
|
160045
|
+
const configDir = envDir ? envDir : platform() === "win32" ? join7(homedir2(), ".config", "opencode") : join7(process.env.XDG_CONFIG_HOME || join7(homedir2(), ".config"), "opencode");
|
|
160046
|
+
const jsonc = join7(configDir, "opencode.jsonc");
|
|
159922
160047
|
if (existsSync4(jsonc))
|
|
159923
160048
|
return jsonc;
|
|
159924
|
-
const json2 =
|
|
160049
|
+
const json2 = join7(configDir, "opencode.json");
|
|
159925
160050
|
if (existsSync4(json2))
|
|
159926
160051
|
return json2;
|
|
159927
160052
|
return null;
|
|
@@ -160297,12 +160422,12 @@ init_logger();
|
|
|
160297
160422
|
// src/subagent-runner.ts
|
|
160298
160423
|
import * as childProcess from "node:child_process";
|
|
160299
160424
|
import { existsSync as existsSync5 } from "node:fs";
|
|
160300
|
-
import { dirname as
|
|
160425
|
+
import { dirname as dirname3, resolve as resolvePath } from "node:path";
|
|
160301
160426
|
import { createInterface } from "node:readline";
|
|
160302
160427
|
import { fileURLToPath } from "node:url";
|
|
160303
160428
|
function resolveSubagentEntryPath() {
|
|
160304
160429
|
try {
|
|
160305
|
-
const here =
|
|
160430
|
+
const here = dirname3(fileURLToPath(import.meta.url));
|
|
160306
160431
|
const candidate = resolvePath(here, "subagent-entry.js");
|
|
160307
160432
|
if (existsSync5(candidate))
|
|
160308
160433
|
return candidate;
|
|
@@ -160744,69 +160869,6 @@ ${sidekickText}
|
|
|
160744
160869
|
});
|
|
160745
160870
|
}
|
|
160746
160871
|
|
|
160747
|
-
// ../plugin/src/features/magic-context/dreamer/queue.ts
|
|
160748
|
-
function enqueueDream(db, projectIdentity, reason, force = false) {
|
|
160749
|
-
const now = Date.now();
|
|
160750
|
-
return db.transaction(() => {
|
|
160751
|
-
const staleThresholdMs = force ? 2 * 60 * 1000 : 120 * 60 * 1000;
|
|
160752
|
-
db.prepare("DELETE FROM dream_queue WHERE project_path = ? AND started_at IS NOT NULL AND started_at < ?").run([projectIdentity, now - staleThresholdMs]);
|
|
160753
|
-
const existing = db.prepare("SELECT id FROM dream_queue WHERE project_path = ?").get(projectIdentity);
|
|
160754
|
-
if (existing) {
|
|
160755
|
-
return null;
|
|
160756
|
-
}
|
|
160757
|
-
const result = db.prepare("INSERT INTO dream_queue (project_path, reason, enqueued_at) VALUES (?, ?, ?)").run(projectIdentity, reason, now);
|
|
160758
|
-
return {
|
|
160759
|
-
id: Number(result.lastInsertRowid),
|
|
160760
|
-
projectIdentity,
|
|
160761
|
-
reason,
|
|
160762
|
-
enqueuedAt: now,
|
|
160763
|
-
startedAt: null
|
|
160764
|
-
};
|
|
160765
|
-
})();
|
|
160766
|
-
}
|
|
160767
|
-
function peekQueue(db, projectIdentity) {
|
|
160768
|
-
const row = projectIdentity ? db.prepare("SELECT id, project_path, reason, enqueued_at FROM dream_queue WHERE started_at IS NULL AND project_path = ? ORDER BY enqueued_at ASC LIMIT 1").get(projectIdentity) : db.prepare("SELECT id, project_path, reason, enqueued_at FROM dream_queue WHERE started_at IS NULL ORDER BY enqueued_at ASC LIMIT 1").get();
|
|
160769
|
-
if (!row)
|
|
160770
|
-
return null;
|
|
160771
|
-
return {
|
|
160772
|
-
id: row.id,
|
|
160773
|
-
projectIdentity: row.project_path,
|
|
160774
|
-
reason: row.reason,
|
|
160775
|
-
enqueuedAt: row.enqueued_at,
|
|
160776
|
-
startedAt: null
|
|
160777
|
-
};
|
|
160778
|
-
}
|
|
160779
|
-
function dequeueNext(db, projectIdentity) {
|
|
160780
|
-
const now = Date.now();
|
|
160781
|
-
return db.transaction(() => {
|
|
160782
|
-
const entry = peekQueue(db, projectIdentity);
|
|
160783
|
-
if (!entry)
|
|
160784
|
-
return null;
|
|
160785
|
-
const result = db.prepare("UPDATE dream_queue SET started_at = ? WHERE id = ? AND started_at IS NULL").run(now, entry.id);
|
|
160786
|
-
if (result.changes === 0)
|
|
160787
|
-
return null;
|
|
160788
|
-
return { ...entry, startedAt: now };
|
|
160789
|
-
})();
|
|
160790
|
-
}
|
|
160791
|
-
function removeDreamEntry(db, id) {
|
|
160792
|
-
db.prepare("DELETE FROM dream_queue WHERE id = ?").run(id);
|
|
160793
|
-
}
|
|
160794
|
-
function resetDreamEntry(db, id) {
|
|
160795
|
-
db.prepare("UPDATE dream_queue SET started_at = NULL, retry_count = COALESCE(retry_count, 0) + 1 WHERE id = ?").run(id);
|
|
160796
|
-
}
|
|
160797
|
-
function getEntryRetryCount(db, id) {
|
|
160798
|
-
const row = db.prepare("SELECT retry_count FROM dream_queue WHERE id = ?").get(id);
|
|
160799
|
-
return row?.retry_count ?? 0;
|
|
160800
|
-
}
|
|
160801
|
-
function clearStaleEntries(db, maxAgeMs) {
|
|
160802
|
-
const cutoff = Date.now() - maxAgeMs;
|
|
160803
|
-
const result = db.prepare("DELETE FROM dream_queue WHERE started_at IS NOT NULL AND started_at < ?").run(cutoff);
|
|
160804
|
-
return result.changes;
|
|
160805
|
-
}
|
|
160806
|
-
|
|
160807
|
-
// src/commands/ctx-dream.ts
|
|
160808
|
-
init_logger();
|
|
160809
|
-
|
|
160810
160872
|
// ../plugin/src/features/magic-context/dreamer/storage-dream-state.ts
|
|
160811
160873
|
var getDreamStateStatements = new WeakMap;
|
|
160812
160874
|
var setDreamStateStatements = new WeakMap;
|
|
@@ -160902,9 +160964,84 @@ function releaseLease(db, holderId) {
|
|
|
160902
160964
|
deleteDreamState(db, LEASE_EXPIRY_KEY);
|
|
160903
160965
|
})();
|
|
160904
160966
|
}
|
|
160967
|
+
|
|
160968
|
+
// ../plugin/src/features/magic-context/dreamer/queue.ts
|
|
160969
|
+
function hasActiveDreamLease(db) {
|
|
160970
|
+
try {
|
|
160971
|
+
return isLeaseActive(db);
|
|
160972
|
+
} catch (error51) {
|
|
160973
|
+
if (String(error51).includes("no such table: dream_state")) {
|
|
160974
|
+
return false;
|
|
160975
|
+
}
|
|
160976
|
+
throw error51;
|
|
160977
|
+
}
|
|
160978
|
+
}
|
|
160979
|
+
function enqueueDream(db, projectIdentity, reason, force = false) {
|
|
160980
|
+
const now = Date.now();
|
|
160981
|
+
return db.transaction(() => {
|
|
160982
|
+
if (!hasActiveDreamLease(db)) {
|
|
160983
|
+
const staleThresholdMs = force ? 2 * 60 * 1000 : 120 * 60 * 1000;
|
|
160984
|
+
db.prepare("DELETE FROM dream_queue WHERE project_path = ? AND started_at IS NOT NULL AND started_at < ?").run([projectIdentity, now - staleThresholdMs]);
|
|
160985
|
+
}
|
|
160986
|
+
const existing = db.prepare("SELECT id FROM dream_queue WHERE project_path = ?").get(projectIdentity);
|
|
160987
|
+
if (existing) {
|
|
160988
|
+
return null;
|
|
160989
|
+
}
|
|
160990
|
+
const result = db.prepare("INSERT INTO dream_queue (project_path, reason, enqueued_at) VALUES (?, ?, ?)").run(projectIdentity, reason, now);
|
|
160991
|
+
return {
|
|
160992
|
+
id: Number(result.lastInsertRowid),
|
|
160993
|
+
projectIdentity,
|
|
160994
|
+
reason,
|
|
160995
|
+
enqueuedAt: now,
|
|
160996
|
+
startedAt: null
|
|
160997
|
+
};
|
|
160998
|
+
})();
|
|
160999
|
+
}
|
|
161000
|
+
function peekQueue(db, projectIdentity) {
|
|
161001
|
+
const row = projectIdentity ? db.prepare("SELECT id, project_path, reason, enqueued_at FROM dream_queue WHERE started_at IS NULL AND project_path = ? ORDER BY enqueued_at ASC LIMIT 1").get(projectIdentity) : db.prepare("SELECT id, project_path, reason, enqueued_at FROM dream_queue WHERE started_at IS NULL ORDER BY enqueued_at ASC LIMIT 1").get();
|
|
161002
|
+
if (!row)
|
|
161003
|
+
return null;
|
|
161004
|
+
return {
|
|
161005
|
+
id: row.id,
|
|
161006
|
+
projectIdentity: row.project_path,
|
|
161007
|
+
reason: row.reason,
|
|
161008
|
+
enqueuedAt: row.enqueued_at,
|
|
161009
|
+
startedAt: null
|
|
161010
|
+
};
|
|
161011
|
+
}
|
|
161012
|
+
function dequeueNext(db, projectIdentity) {
|
|
161013
|
+
const now = Date.now();
|
|
161014
|
+
return db.transaction(() => {
|
|
161015
|
+
const entry = peekQueue(db, projectIdentity);
|
|
161016
|
+
if (!entry)
|
|
161017
|
+
return null;
|
|
161018
|
+
const result = db.prepare("UPDATE dream_queue SET started_at = ? WHERE id = ? AND started_at IS NULL").run(now, entry.id);
|
|
161019
|
+
if (result.changes === 0)
|
|
161020
|
+
return null;
|
|
161021
|
+
return { ...entry, startedAt: now };
|
|
161022
|
+
})();
|
|
161023
|
+
}
|
|
161024
|
+
function removeDreamEntry(db, id) {
|
|
161025
|
+
db.prepare("DELETE FROM dream_queue WHERE id = ?").run(id);
|
|
161026
|
+
}
|
|
161027
|
+
function resetDreamEntry(db, id) {
|
|
161028
|
+
db.prepare("UPDATE dream_queue SET started_at = NULL, retry_count = COALESCE(retry_count, 0) + 1 WHERE id = ?").run(id);
|
|
161029
|
+
}
|
|
161030
|
+
function getEntryRetryCount(db, id) {
|
|
161031
|
+
const row = db.prepare("SELECT retry_count FROM dream_queue WHERE id = ?").get(id);
|
|
161032
|
+
return row?.retry_count ?? 0;
|
|
161033
|
+
}
|
|
161034
|
+
function clearStaleEntries(db, maxAgeMs) {
|
|
161035
|
+
const cutoff = Date.now() - maxAgeMs;
|
|
161036
|
+
const result = db.prepare("DELETE FROM dream_queue WHERE started_at IS NOT NULL AND started_at < ?").run(cutoff);
|
|
161037
|
+
return result.changes;
|
|
161038
|
+
}
|
|
161039
|
+
|
|
161040
|
+
// src/commands/ctx-dream.ts
|
|
161041
|
+
init_logger();
|
|
160905
161042
|
// ../plugin/src/features/magic-context/dreamer/runner.ts
|
|
160906
161043
|
import { existsSync as existsSync6 } from "node:fs";
|
|
160907
|
-
import { join as
|
|
161044
|
+
import { join as join8 } from "node:path";
|
|
160908
161045
|
|
|
160909
161046
|
// ../plugin/src/shared/index.ts
|
|
160910
161047
|
init_logger();
|
|
@@ -162442,7 +162579,7 @@ function logWithStackHead(message, stackHead) {
|
|
|
162442
162579
|
log(message, stackHead ? { stackHead } : undefined);
|
|
162443
162580
|
}
|
|
162444
162581
|
function getOpenCodeDbPath2() {
|
|
162445
|
-
return
|
|
162582
|
+
return join8(getDataDir(), "opencode", "opencode.db");
|
|
162446
162583
|
}
|
|
162447
162584
|
function openOpenCodeDb() {
|
|
162448
162585
|
const dbPath = getOpenCodeDbPath2();
|
|
@@ -162517,9 +162654,11 @@ async function identifyKeyFilesForSession(args) {
|
|
|
162517
162654
|
try {
|
|
162518
162655
|
if (!renewLease(args.db, args.holderId)) {
|
|
162519
162656
|
log(`[key-files][${args.sessionId}] lease renewal failed — aborting`);
|
|
162657
|
+
args.onLeaseLost?.(`key-files:${args.sessionId}`);
|
|
162520
162658
|
abortController.abort();
|
|
162521
162659
|
}
|
|
162522
|
-
} catch {
|
|
162660
|
+
} catch (error51) {
|
|
162661
|
+
args.onLeaseLost?.(`key-files:${args.sessionId}`, error51);
|
|
162523
162662
|
abortController.abort();
|
|
162524
162663
|
}
|
|
162525
162664
|
}, 60000);
|
|
@@ -162574,6 +162713,10 @@ async function identifyKeyFilesForSession(args) {
|
|
|
162574
162713
|
log(`[key-files][${args.sessionId}] could not parse agent output — using heuristic fallback`);
|
|
162575
162714
|
applyHeuristicFallback();
|
|
162576
162715
|
} catch (error51) {
|
|
162716
|
+
if (args.isLeaseLost?.() || abortController.signal.aborted) {
|
|
162717
|
+
log(`[key-files][${args.sessionId}] lease lost during identification — skipping heuristic fallback`);
|
|
162718
|
+
throw error51;
|
|
162719
|
+
}
|
|
162577
162720
|
log(`[key-files][${args.sessionId}] identification failed: ${getErrorMessage(error51)} — using heuristic fallback`);
|
|
162578
162721
|
try {
|
|
162579
162722
|
applyHeuristicFallback();
|
|
@@ -162614,6 +162757,10 @@ async function identifyKeyFiles(args) {
|
|
|
162614
162757
|
}
|
|
162615
162758
|
log(`[key-files] evaluating ${sessionIds.length} active session(s) for ${args.projectIdentity}`);
|
|
162616
162759
|
for (const sessionId of sessionIds) {
|
|
162760
|
+
if (args.isLeaseLost?.()) {
|
|
162761
|
+
log("[key-files] lease lost — stopping key-file identification");
|
|
162762
|
+
break;
|
|
162763
|
+
}
|
|
162617
162764
|
if (Date.now() > args.deadline) {
|
|
162618
162765
|
log("[key-files] deadline reached — stopping key-file identification");
|
|
162619
162766
|
break;
|
|
@@ -162625,6 +162772,8 @@ async function identifyKeyFiles(args) {
|
|
|
162625
162772
|
sessionDirectory: args.sessionDirectory,
|
|
162626
162773
|
holderId: args.holderId,
|
|
162627
162774
|
fallbackModels: args.fallbackModels,
|
|
162775
|
+
onLeaseLost: args.onLeaseLost,
|
|
162776
|
+
isLeaseLost: args.isLeaseLost,
|
|
162628
162777
|
deadline: args.deadline,
|
|
162629
162778
|
sessionId,
|
|
162630
162779
|
config: args.config
|
|
@@ -162681,8 +162830,50 @@ async function runDream(args) {
|
|
|
162681
162830
|
let lastErrorSignature = null;
|
|
162682
162831
|
let consecutiveSameErrorFailures = 0;
|
|
162683
162832
|
let circuitBreakerTripped = false;
|
|
162833
|
+
let lostLease = false;
|
|
162834
|
+
let lostLeaseReason = null;
|
|
162835
|
+
let lostLeaseRecorded = false;
|
|
162836
|
+
const markLeaseLost = (phase, error51) => {
|
|
162837
|
+
const detail = error51 ? `: ${getErrorMessage(error51)}` : "";
|
|
162838
|
+
lostLeaseReason = `Dream lease lost during ${phase}${detail}`;
|
|
162839
|
+
if (!lostLease) {
|
|
162840
|
+
log(`[dreamer] FATAL: ${lostLeaseReason}; aborting all remaining dream work`);
|
|
162841
|
+
} else {
|
|
162842
|
+
log(`[dreamer] FATAL: ${lostLeaseReason}; dream work is already aborting`);
|
|
162843
|
+
}
|
|
162844
|
+
lostLease = true;
|
|
162845
|
+
};
|
|
162846
|
+
const recordLeaseLostTask = (phase) => {
|
|
162847
|
+
if (lostLeaseRecorded)
|
|
162848
|
+
return;
|
|
162849
|
+
lostLeaseRecorded = true;
|
|
162850
|
+
result.tasks.push({
|
|
162851
|
+
name: "lease-lost",
|
|
162852
|
+
durationMs: 0,
|
|
162853
|
+
result: "",
|
|
162854
|
+
error: lostLeaseReason ?? `Dream lease lost during ${phase}; aborted remaining work`
|
|
162855
|
+
});
|
|
162856
|
+
};
|
|
162857
|
+
const verifyLeaseStillHeld = (phase) => {
|
|
162858
|
+
if (lostLease)
|
|
162859
|
+
return false;
|
|
162860
|
+
try {
|
|
162861
|
+
if (!renewLease(args.db, holderId)) {
|
|
162862
|
+
markLeaseLost(phase);
|
|
162863
|
+
return false;
|
|
162864
|
+
}
|
|
162865
|
+
return true;
|
|
162866
|
+
} catch (error51) {
|
|
162867
|
+
markLeaseLost(phase, error51);
|
|
162868
|
+
return false;
|
|
162869
|
+
}
|
|
162870
|
+
};
|
|
162684
162871
|
try {
|
|
162685
162872
|
for (const taskName of args.tasks) {
|
|
162873
|
+
if (!verifyLeaseStillHeld(`before task ${taskName}`)) {
|
|
162874
|
+
recordLeaseLostTask(`before task ${taskName}`);
|
|
162875
|
+
break;
|
|
162876
|
+
}
|
|
162686
162877
|
if (Date.now() > deadline) {
|
|
162687
162878
|
log(`[dreamer] deadline reached, stopping after ${result.tasks.length} tasks`);
|
|
162688
162879
|
break;
|
|
@@ -162695,18 +162886,20 @@ async function runDream(args) {
|
|
|
162695
162886
|
try {
|
|
162696
162887
|
if (!renewLease(args.db, holderId)) {
|
|
162697
162888
|
log(`[dreamer] task ${taskName}: lease renewal failed — aborting LLM call`);
|
|
162889
|
+
markLeaseLost(`task ${taskName} lease renewal`);
|
|
162698
162890
|
taskAbortController.abort();
|
|
162699
162891
|
}
|
|
162700
162892
|
} catch (err) {
|
|
162701
162893
|
log(`[dreamer] task ${taskName}: lease renewal threw — aborting LLM call: ${err}`);
|
|
162894
|
+
markLeaseLost(`task ${taskName} lease renewal`, err);
|
|
162702
162895
|
taskAbortController.abort();
|
|
162703
162896
|
}
|
|
162704
162897
|
}, 60000);
|
|
162705
162898
|
try {
|
|
162706
162899
|
const docsDir = args.sessionDirectory ?? args.projectIdentity;
|
|
162707
162900
|
const existingDocs = taskName === "maintain-docs" ? {
|
|
162708
|
-
architecture: existsSync6(
|
|
162709
|
-
structure: existsSync6(
|
|
162901
|
+
architecture: existsSync6(join8(docsDir, "ARCHITECTURE.md")),
|
|
162902
|
+
structure: existsSync6(join8(docsDir, "STRUCTURE.md"))
|
|
162710
162903
|
} : undefined;
|
|
162711
162904
|
const userMemories = taskName === "archive-stale" ? getActiveUserMemories(args.db).map((um) => ({
|
|
162712
162905
|
id: um.id,
|
|
@@ -162745,6 +162938,9 @@ async function runDream(args) {
|
|
|
162745
162938
|
fallbackModels: args.fallbackModels,
|
|
162746
162939
|
callContext: `dreamer:${taskName}`
|
|
162747
162940
|
});
|
|
162941
|
+
if (lostLease) {
|
|
162942
|
+
throw new Error(lostLeaseReason ?? `Dream lease lost during ${taskName}`);
|
|
162943
|
+
}
|
|
162748
162944
|
const messagesResponse = await args.client.session.messages({
|
|
162749
162945
|
path: { id: agentSessionId },
|
|
162750
162946
|
query: { directory: args.sessionDirectory ?? args.projectIdentity }
|
|
@@ -162775,7 +162971,10 @@ async function runDream(args) {
|
|
|
162775
162971
|
result: null,
|
|
162776
162972
|
error: errorDescription.brief
|
|
162777
162973
|
});
|
|
162778
|
-
if (
|
|
162974
|
+
if (lostLease) {
|
|
162975
|
+
lastErrorSignature = null;
|
|
162976
|
+
consecutiveSameErrorFailures = 0;
|
|
162977
|
+
} else if (shouldSkipCircuitBreaker(error51, errorDescription.brief)) {
|
|
162779
162978
|
lastErrorSignature = null;
|
|
162780
162979
|
consecutiveSameErrorFailures = 0;
|
|
162781
162980
|
} else {
|
|
@@ -162808,11 +163007,18 @@ async function runDream(args) {
|
|
|
162808
163007
|
});
|
|
162809
163008
|
}
|
|
162810
163009
|
}
|
|
163010
|
+
if (lostLease) {
|
|
163011
|
+
recordLeaseLostTask(`task ${taskName}`);
|
|
163012
|
+
break;
|
|
163013
|
+
}
|
|
162811
163014
|
if (circuitBreakerTripped) {
|
|
162812
163015
|
break;
|
|
162813
163016
|
}
|
|
162814
163017
|
}
|
|
162815
|
-
if (
|
|
163018
|
+
if (lostLease) {
|
|
163019
|
+
log("[dreamer] lease lost: skipping all post-task phases");
|
|
163020
|
+
recordLeaseLostTask("post-task phases");
|
|
163021
|
+
} else if (circuitBreakerTripped) {
|
|
162816
163022
|
log("[dreamer] circuit breaker: skipping post-task phases");
|
|
162817
163023
|
result.tasks.push({
|
|
162818
163024
|
name: "post-task-phases",
|
|
@@ -162821,9 +163027,12 @@ async function runDream(args) {
|
|
|
162821
163027
|
error: "Skipped post-task phases after circuit breaker tripped; configure dreamer model/fallback_models in magic-context.jsonc."
|
|
162822
163028
|
});
|
|
162823
163029
|
}
|
|
162824
|
-
if (!circuitBreakerTripped && args.experimentalUserMemories?.enabled && Date.now() <= deadline) {
|
|
163030
|
+
if (!circuitBreakerTripped && !lostLease && args.experimentalUserMemories?.enabled && Date.now() <= deadline) {
|
|
162825
163031
|
const umStart = Date.now();
|
|
162826
163032
|
try {
|
|
163033
|
+
if (!verifyLeaseStillHeld("before user-memory review")) {
|
|
163034
|
+
throw new Error(lostLeaseReason ?? "Dream lease lost before user-memory review");
|
|
163035
|
+
}
|
|
162827
163036
|
const reviewResult = await reviewUserMemories({
|
|
162828
163037
|
db: args.db,
|
|
162829
163038
|
client: args.client,
|
|
@@ -162834,6 +163043,9 @@ async function runDream(args) {
|
|
|
162834
163043
|
promotionThreshold: args.experimentalUserMemories.promotionThreshold,
|
|
162835
163044
|
fallbackModels: args.fallbackModels
|
|
162836
163045
|
});
|
|
163046
|
+
if (!verifyLeaseStillHeld("after user-memory review")) {
|
|
163047
|
+
throw new Error(lostLeaseReason ?? "Dream lease lost after user-memory review");
|
|
163048
|
+
}
|
|
162837
163049
|
const umOutput = `promoted=${reviewResult.promoted} merged=${reviewResult.merged} dismissed=${reviewResult.dismissed} consumed=${reviewResult.candidatesConsumed}`;
|
|
162838
163050
|
if (reviewResult.promoted > 0 || reviewResult.merged > 0 || reviewResult.dismissed > 0) {
|
|
162839
163051
|
log(`[dreamer] user-memories: ${umOutput}`);
|
|
@@ -162853,9 +163065,14 @@ async function runDream(args) {
|
|
|
162853
163065
|
error: errorDescription.brief
|
|
162854
163066
|
});
|
|
162855
163067
|
}
|
|
163068
|
+
if (lostLease)
|
|
163069
|
+
recordLeaseLostTask("user-memory review");
|
|
162856
163070
|
}
|
|
162857
|
-
if (!circuitBreakerTripped && Date.now() <= deadline) {
|
|
163071
|
+
if (!circuitBreakerTripped && !lostLease && Date.now() <= deadline) {
|
|
162858
163072
|
try {
|
|
163073
|
+
if (!verifyLeaseStillHeld("before smart-note evaluation")) {
|
|
163074
|
+
throw new Error(lostLeaseReason ?? "Dream lease lost before smart-note evaluation");
|
|
163075
|
+
}
|
|
162859
163076
|
await evaluateSmartNotes({
|
|
162860
163077
|
db: args.db,
|
|
162861
163078
|
client: args.client,
|
|
@@ -162865,16 +163082,26 @@ async function runDream(args) {
|
|
|
162865
163082
|
holderId,
|
|
162866
163083
|
deadline,
|
|
162867
163084
|
result,
|
|
162868
|
-
fallbackModels: args.fallbackModels
|
|
163085
|
+
fallbackModels: args.fallbackModels,
|
|
163086
|
+
onLeaseLost: markLeaseLost,
|
|
163087
|
+
isLeaseLost: () => lostLease
|
|
162869
163088
|
});
|
|
163089
|
+
if (!verifyLeaseStillHeld("after smart-note evaluation")) {
|
|
163090
|
+
throw new Error(lostLeaseReason ?? "Dream lease lost after smart-note evaluation");
|
|
163091
|
+
}
|
|
162870
163092
|
} catch (error51) {
|
|
162871
163093
|
const errorDescription = describeError(error51);
|
|
162872
163094
|
logWithStackHead(`[dreamer] smart note evaluation failed: ${errorDescription.brief}`, errorDescription.stackHead);
|
|
162873
163095
|
}
|
|
163096
|
+
if (lostLease)
|
|
163097
|
+
recordLeaseLostTask("smart-note evaluation");
|
|
162874
163098
|
}
|
|
162875
|
-
if (!circuitBreakerTripped && args.experimentalPinKeyFiles?.enabled && Date.now() <= deadline) {
|
|
163099
|
+
if (!circuitBreakerTripped && !lostLease && args.experimentalPinKeyFiles?.enabled && Date.now() <= deadline) {
|
|
162876
163100
|
const kfStart = Date.now();
|
|
162877
163101
|
try {
|
|
163102
|
+
if (!verifyLeaseStillHeld("before key-file identification")) {
|
|
163103
|
+
throw new Error(lostLeaseReason ?? "Dream lease lost before key-file identification");
|
|
163104
|
+
}
|
|
162878
163105
|
await identifyKeyFiles({
|
|
162879
163106
|
db: args.db,
|
|
162880
163107
|
client: args.client,
|
|
@@ -162884,8 +163111,13 @@ async function runDream(args) {
|
|
|
162884
163111
|
holderId,
|
|
162885
163112
|
deadline,
|
|
162886
163113
|
config: args.experimentalPinKeyFiles,
|
|
162887
|
-
fallbackModels: args.fallbackModels
|
|
163114
|
+
fallbackModels: args.fallbackModels,
|
|
163115
|
+
onLeaseLost: markLeaseLost,
|
|
163116
|
+
isLeaseLost: () => lostLease
|
|
162888
163117
|
});
|
|
163118
|
+
if (!verifyLeaseStillHeld("after key-file identification")) {
|
|
163119
|
+
throw new Error(lostLeaseReason ?? "Dream lease lost after key-file identification");
|
|
163120
|
+
}
|
|
162889
163121
|
result.tasks.push({
|
|
162890
163122
|
name: "key files",
|
|
162891
163123
|
durationMs: Date.now() - kfStart,
|
|
@@ -162901,6 +163133,8 @@ async function runDream(args) {
|
|
|
162901
163133
|
error: errorDescription.brief
|
|
162902
163134
|
});
|
|
162903
163135
|
}
|
|
163136
|
+
if (lostLease)
|
|
163137
|
+
recordLeaseLostTask("key-file identification");
|
|
162904
163138
|
}
|
|
162905
163139
|
} finally {
|
|
162906
163140
|
releaseLease(args.db, holderId);
|
|
@@ -162941,7 +163175,7 @@ async function runDream(args) {
|
|
|
162941
163175
|
"circuit-breaker"
|
|
162942
163176
|
]);
|
|
162943
163177
|
const hasSuccessfulTask = result.tasks.some((t) => !t.error && !POST_TASK_NAMES.has(t.name));
|
|
162944
|
-
if (hasSuccessfulTask) {
|
|
163178
|
+
if (hasSuccessfulTask && !lostLease) {
|
|
162945
163179
|
setDreamState(args.db, `last_dream_at:${args.projectIdentity}`, String(result.finishedAt));
|
|
162946
163180
|
setDreamState(args.db, "last_dream_at", String(result.finishedAt));
|
|
162947
163181
|
}
|
|
@@ -162990,9 +163224,11 @@ Only include notes whose conditions you could definitively evaluate. Skip notes
|
|
|
162990
163224
|
try {
|
|
162991
163225
|
if (!renewLease(args.db, args.holderId)) {
|
|
162992
163226
|
log("[dreamer] smart notes: lease renewal failed — aborting");
|
|
163227
|
+
args.onLeaseLost?.("smart notes");
|
|
162993
163228
|
abortController.abort();
|
|
162994
163229
|
}
|
|
162995
|
-
} catch {
|
|
163230
|
+
} catch (error51) {
|
|
163231
|
+
args.onLeaseLost?.("smart notes", error51);
|
|
162996
163232
|
abortController.abort();
|
|
162997
163233
|
}
|
|
162998
163234
|
}, 60000);
|
|
@@ -164271,7 +164507,6 @@ function createScheduler(config2) {
|
|
|
164271
164507
|
}
|
|
164272
164508
|
};
|
|
164273
164509
|
}
|
|
164274
|
-
|
|
164275
164510
|
// ../plugin/src/features/magic-context/tagger.ts
|
|
164276
164511
|
var TOOL_COMPOSITE_KEY_SEP = "\x00";
|
|
164277
164512
|
function makeToolCompositeKey(ownerMsgId, callId) {
|
|
@@ -165310,16 +165545,24 @@ function trimMemoriesToBudget(sessionId, memories, budgetTokens) {
|
|
|
165310
165545
|
function prepareCompartmentInjection(db, sessionId, messages, isCacheBusting, projectPath, injectionBudgetTokens, temporalAwareness) {
|
|
165311
165546
|
const cached2 = injectionCache.get(sessionId);
|
|
165312
165547
|
if (!isCacheBusting && cached2) {
|
|
165313
|
-
if (cached2.
|
|
165314
|
-
|
|
165315
|
-
|
|
165316
|
-
|
|
165317
|
-
|
|
165318
|
-
|
|
165319
|
-
|
|
165548
|
+
if (cached2.kind === "empty") {
|
|
165549
|
+
return null;
|
|
165550
|
+
}
|
|
165551
|
+
const prepared = cached2.injection;
|
|
165552
|
+
if (prepared.compartmentEndMessageId === null) {
|
|
165553
|
+
sessionLog(sessionId, "compartment injection cache in degraded mode (null boundary), forcing rebuild");
|
|
165554
|
+
} else {
|
|
165555
|
+
if (prepared.compartmentEndMessageId.length > 0) {
|
|
165556
|
+
const cutoffIndex2 = messages.findIndex((message) => message.info.id === prepared.compartmentEndMessageId);
|
|
165557
|
+
if (cutoffIndex2 >= 0) {
|
|
165558
|
+
const remaining = messages.slice(cutoffIndex2 + 1);
|
|
165559
|
+
messages.splice(0, messages.length, ...remaining);
|
|
165560
|
+
} else {
|
|
165561
|
+
sessionLog(sessionId, `compartment injection: cached boundary ${prepared.compartmentEndMessageId} not in messages (already trimmed), reusing cache`);
|
|
165562
|
+
}
|
|
165320
165563
|
}
|
|
165564
|
+
return { ...prepared, rebuiltFromDb: false };
|
|
165321
165565
|
}
|
|
165322
|
-
return cached2;
|
|
165323
165566
|
}
|
|
165324
165567
|
const compartments = getCompartments(db, sessionId);
|
|
165325
165568
|
const facts = getSessionFacts(db, sessionId);
|
|
@@ -165351,7 +165594,11 @@ function prepareCompartmentInjection(db, sessionId, messages, isCacheBusting, pr
|
|
|
165351
165594
|
}
|
|
165352
165595
|
}
|
|
165353
165596
|
if (compartments.length === 0 && facts.length === 0 && !memoryBlock) {
|
|
165354
|
-
injectionCache.
|
|
165597
|
+
injectionCache.set(sessionId, {
|
|
165598
|
+
kind: "empty",
|
|
165599
|
+
compartmentEndMessageId: "",
|
|
165600
|
+
renderedBytes: 0
|
|
165601
|
+
});
|
|
165355
165602
|
return null;
|
|
165356
165603
|
}
|
|
165357
165604
|
let dateRanges;
|
|
@@ -165384,9 +165631,10 @@ function prepareCompartmentInjection(db, sessionId, messages, isCacheBusting, pr
|
|
|
165384
165631
|
compartmentCount: 0,
|
|
165385
165632
|
skippedVisibleMessages: 0,
|
|
165386
165633
|
factCount: facts.length,
|
|
165387
|
-
memoryCount
|
|
165634
|
+
memoryCount,
|
|
165635
|
+
rebuiltFromDb: true
|
|
165388
165636
|
};
|
|
165389
|
-
injectionCache.set(sessionId, result2);
|
|
165637
|
+
injectionCache.set(sessionId, { kind: "populated", injection: result2 });
|
|
165390
165638
|
return result2;
|
|
165391
165639
|
}
|
|
165392
165640
|
const lastCompartment = compartments[compartments.length - 1];
|
|
@@ -165404,9 +165652,10 @@ function prepareCompartmentInjection(db, sessionId, messages, isCacheBusting, pr
|
|
|
165404
165652
|
compartmentCount: compartments.length,
|
|
165405
165653
|
skippedVisibleMessages: 0,
|
|
165406
165654
|
factCount: facts.length,
|
|
165407
|
-
memoryCount
|
|
165655
|
+
memoryCount,
|
|
165656
|
+
rebuiltFromDb: true
|
|
165408
165657
|
};
|
|
165409
|
-
injectionCache.set(sessionId, result2);
|
|
165658
|
+
injectionCache.set(sessionId, { kind: "populated", injection: result2 });
|
|
165410
165659
|
return result2;
|
|
165411
165660
|
}
|
|
165412
165661
|
let skippedVisibleMessages = 0;
|
|
@@ -165415,17 +165664,20 @@ function prepareCompartmentInjection(db, sessionId, messages, isCacheBusting, pr
|
|
|
165415
165664
|
skippedVisibleMessages = cutoffIndex + 1;
|
|
165416
165665
|
const remaining = messages.slice(cutoffIndex + 1);
|
|
165417
165666
|
messages.splice(0, messages.length, ...remaining);
|
|
165667
|
+
} else {
|
|
165668
|
+
sessionLog(sessionId, `compartment injection entering degraded mode: boundary ${lastEndMessageId} not in visible messages`);
|
|
165418
165669
|
}
|
|
165419
165670
|
const result = {
|
|
165420
165671
|
block,
|
|
165421
165672
|
compartmentEndMessage: lastEnd,
|
|
165422
|
-
compartmentEndMessageId: lastEndMessageId,
|
|
165673
|
+
compartmentEndMessageId: cutoffIndex >= 0 ? lastEndMessageId : null,
|
|
165423
165674
|
compartmentCount: compartments.length,
|
|
165424
165675
|
skippedVisibleMessages,
|
|
165425
165676
|
factCount: facts.length,
|
|
165426
|
-
memoryCount
|
|
165677
|
+
memoryCount,
|
|
165678
|
+
rebuiltFromDb: true
|
|
165427
165679
|
};
|
|
165428
|
-
injectionCache.set(sessionId, result);
|
|
165680
|
+
injectionCache.set(sessionId, { kind: "populated", injection: result });
|
|
165429
165681
|
return result;
|
|
165430
165682
|
}
|
|
165431
165683
|
|
|
@@ -166968,7 +167220,7 @@ function injectSessionHistoryIntoPi(db, sessionId, piMessages, isCacheBusting, p
|
|
|
166968
167220
|
};
|
|
166969
167221
|
}
|
|
166970
167222
|
const boundaryId = prepared.compartmentEndMessageId;
|
|
166971
|
-
const skippedVisible = boundaryId.length > 0 ? trimPiMessagesToBoundary(piMessages, entryIds, boundaryId) : prepared.skippedVisibleMessages;
|
|
167223
|
+
const skippedVisible = boundaryId != null && boundaryId.length > 0 ? trimPiMessagesToBoundary(piMessages, entryIds, boundaryId) : prepared.skippedVisibleMessages;
|
|
166972
167224
|
const historyBlock = `<session-history>
|
|
166973
167225
|
${prepared.block}
|
|
166974
167226
|
</session-history>`;
|
|
@@ -168018,17 +168270,17 @@ function getReducedRecompTokenBudget(currentBudget) {
|
|
|
168018
168270
|
}
|
|
168019
168271
|
|
|
168020
168272
|
// ../plugin/src/hooks/magic-context/historian-state-file.ts
|
|
168021
|
-
|
|
168022
|
-
import {
|
|
168023
|
-
import { join as
|
|
168273
|
+
init_data_path();
|
|
168274
|
+
import { mkdirSync as mkdirSync5, unlinkSync, writeFileSync as writeFileSync2 } from "node:fs";
|
|
168275
|
+
import { join as join9 } from "node:path";
|
|
168024
168276
|
var HISTORIAN_STATE_INLINE_THRESHOLD = 30000;
|
|
168025
|
-
|
|
168026
|
-
function maybeWriteHistorianStateFile(sessionId, existingState) {
|
|
168277
|
+
function maybeWriteHistorianStateFile(sessionId, existingState, directory) {
|
|
168027
168278
|
if (existingState.length <= HISTORIAN_STATE_INLINE_THRESHOLD)
|
|
168028
168279
|
return;
|
|
168029
168280
|
try {
|
|
168030
|
-
|
|
168031
|
-
|
|
168281
|
+
const dir = getProjectMagicContextHistorianDir(directory);
|
|
168282
|
+
mkdirSync5(dir, { recursive: true });
|
|
168283
|
+
const path5 = join9(dir, `state-${sessionId}-${Date.now()}.xml`);
|
|
168032
168284
|
writeFileSync2(path5, existingState, "utf8");
|
|
168033
168285
|
return path5;
|
|
168034
168286
|
} catch {
|
|
@@ -168128,7 +168380,7 @@ async function runPiHistorian(deps) {
|
|
|
168128
168380
|
const existingState = priorCompartments.length > 0 || priorFacts.length > 0 ? buildExistingStateXml(priorCompartments, priorFacts, memoryBlock) : memoryBlock ? `${memoryBlock}
|
|
168129
168381
|
|
|
168130
168382
|
This is your first run. No existing compartments or facts.` : "This is your first run. No existing state.";
|
|
168131
|
-
stateFilePath = maybeWriteHistorianStateFile(sessionId, existingState);
|
|
168383
|
+
stateFilePath = maybeWriteHistorianStateFile(sessionId, existingState, directory);
|
|
168132
168384
|
if (stateFilePath) {
|
|
168133
168385
|
sessionLog(sessionId, `pi-historian: existing state offloaded to file (${existingState.length} chars) → ${stateFilePath}`);
|
|
168134
168386
|
}
|
|
@@ -170236,7 +170488,7 @@ init_logger();
|
|
|
170236
170488
|
init_data_path();
|
|
170237
170489
|
init_logger();
|
|
170238
170490
|
await init_sqlite();
|
|
170239
|
-
import { join as
|
|
170491
|
+
import { join as join10 } from "node:path";
|
|
170240
170492
|
var BASE62_CHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
|
170241
170493
|
function randomBase62(length) {
|
|
170242
170494
|
const chars = [];
|
|
@@ -170257,7 +170509,7 @@ function generatePartId(timestampMs, counter = 0n) {
|
|
|
170257
170509
|
return generateId("prt", timestampMs, counter);
|
|
170258
170510
|
}
|
|
170259
170511
|
function getOpenCodeDbPath3() {
|
|
170260
|
-
return
|
|
170512
|
+
return join10(getDataDir(), "opencode", "opencode.db");
|
|
170261
170513
|
}
|
|
170262
170514
|
var cachedWriteDb = null;
|
|
170263
170515
|
var REQUIRED_MESSAGE_COLUMNS = ["id", "session_id", "time_created", "time_updated", "data"];
|
|
@@ -170815,11 +171067,13 @@ async function runCompressorPass2(args) {
|
|
|
170815
171067
|
}
|
|
170816
171068
|
|
|
170817
171069
|
// ../plugin/src/hooks/magic-context/compartment-runner-historian.ts
|
|
170818
|
-
import { mkdirSync as
|
|
170819
|
-
import {
|
|
170820
|
-
import { join as join12 } from "node:path";
|
|
171070
|
+
import { mkdirSync as mkdirSync6, unlinkSync as unlinkSync2, writeFileSync as writeFileSync3 } from "node:fs";
|
|
171071
|
+
import { join as join11 } from "node:path";
|
|
170821
171072
|
init_magic_context();
|
|
170822
|
-
|
|
171073
|
+
init_data_path();
|
|
171074
|
+
function historianResponseDumpDir(directory) {
|
|
171075
|
+
return getProjectMagicContextHistorianDir(directory);
|
|
171076
|
+
}
|
|
170823
171077
|
var MAX_HISTORIAN_RETRIES = 2;
|
|
170824
171078
|
async function runValidatedHistorianPass(args) {
|
|
170825
171079
|
const firstRun = await runHistorianPrompt({
|
|
@@ -170971,7 +171225,7 @@ async function runHistorianPrompt(args) {
|
|
|
170971
171225
|
if (!result) {
|
|
170972
171226
|
return { ok: false, error: "Historian returned no assistant output." };
|
|
170973
171227
|
}
|
|
170974
|
-
const dumpPath = dumpHistorianResponse(parentSessionId, dumpLabel ?? "historian-response", result);
|
|
171228
|
+
const dumpPath = dumpHistorianResponse(parentSessionId, sessionDirectory, dumpLabel ?? "historian-response", result);
|
|
170975
171229
|
return { ok: true, result, dumpPath };
|
|
170976
171230
|
} catch (modelError) {
|
|
170977
171231
|
const desc = describeError(modelError);
|
|
@@ -171063,12 +171317,13 @@ function cleanupHistorianDump(sessionId, dumpPath) {
|
|
|
171063
171317
|
});
|
|
171064
171318
|
}
|
|
171065
171319
|
}
|
|
171066
|
-
function dumpHistorianResponse(sessionId, label, text) {
|
|
171320
|
+
function dumpHistorianResponse(sessionId, directory, label, text) {
|
|
171067
171321
|
try {
|
|
171068
|
-
|
|
171322
|
+
const dumpDir = historianResponseDumpDir(directory);
|
|
171323
|
+
mkdirSync6(dumpDir, { recursive: true });
|
|
171069
171324
|
const safeSessionId = sanitizeDumpName(sessionId);
|
|
171070
171325
|
const safeLabel = sanitizeDumpName(label);
|
|
171071
|
-
const dumpPath =
|
|
171326
|
+
const dumpPath = join11(dumpDir, `${safeSessionId}-${safeLabel}-${Date.now()}.xml`);
|
|
171072
171327
|
writeFileSync3(dumpPath, text, "utf8");
|
|
171073
171328
|
sessionLog(sessionId, "compartment agent: historian response dumped", {
|
|
171074
171329
|
label,
|
|
@@ -171293,9 +171548,18 @@ async function executePartialRecompInternal(deps, range) {
|
|
|
171293
171548
|
}
|
|
171294
171549
|
setRecompPartialRange(db, sessionId, null);
|
|
171295
171550
|
clearCompressionDepthRange(db, sessionId, snapStart, snapEnd);
|
|
171296
|
-
|
|
171297
|
-
|
|
171551
|
+
if (deps.preserveInjectionCacheUntilConsumed !== true) {
|
|
171552
|
+
clearInjectionCache(sessionId);
|
|
171553
|
+
}
|
|
171554
|
+
deps.onCompartmentStatePublished?.(sessionId);
|
|
171298
171555
|
const lastEnd = merged[merged.length - 1]?.endMessage ?? snapEnd;
|
|
171556
|
+
if (deps.experimentalCompactionMarkers && lastEnd > 0) {
|
|
171557
|
+
updateCompactionMarkerAfterPublication(db, sessionId, lastEnd, deps.directory);
|
|
171558
|
+
const stalePending = getPendingCompactionMarkerState(db, sessionId);
|
|
171559
|
+
if (stalePending) {
|
|
171560
|
+
clearPendingCompactionMarkerStateIf(db, sessionId, stalePending);
|
|
171561
|
+
}
|
|
171562
|
+
}
|
|
171299
171563
|
return { compartmentCount: merged.length, lastEndMessage: lastEnd };
|
|
171300
171564
|
};
|
|
171301
171565
|
const protectedTailStart = getProtectedTailStartOrdinal(sessionId);
|
|
@@ -171510,8 +171774,10 @@ async function executeContextRecompInternal(deps) {
|
|
|
171510
171774
|
if (!promoted2)
|
|
171511
171775
|
return null;
|
|
171512
171776
|
clearCompressionDepth(db, sessionId);
|
|
171513
|
-
|
|
171514
|
-
|
|
171777
|
+
if (deps.preserveInjectionCacheUntilConsumed !== true) {
|
|
171778
|
+
clearInjectionCache(sessionId);
|
|
171779
|
+
}
|
|
171780
|
+
deps.onCompartmentStatePublished?.(sessionId);
|
|
171515
171781
|
if (deps.directory && deps.memoryEnabled !== false && deps.autoPromote !== false) {
|
|
171516
171782
|
promoteSessionFactsToMemory(db, sessionId, resolveProjectIdentity(deps.directory), promoted2.facts);
|
|
171517
171783
|
}
|
|
@@ -171521,6 +171787,10 @@ async function executeContextRecompInternal(deps) {
|
|
|
171521
171787
|
}
|
|
171522
171788
|
if (deps.experimentalCompactionMarkers && lastCompartmentEnd2 > 0) {
|
|
171523
171789
|
updateCompactionMarkerAfterPublication(db, sessionId, lastCompartmentEnd2, deps.directory);
|
|
171790
|
+
const stalePending = getPendingCompactionMarkerState(db, sessionId);
|
|
171791
|
+
if (stalePending) {
|
|
171792
|
+
clearPendingCompactionMarkerStateIf(db, sessionId, stalePending);
|
|
171793
|
+
}
|
|
171524
171794
|
}
|
|
171525
171795
|
return [
|
|
171526
171796
|
`Persisted ${promoted2.compartments.length} compartment${promoted2.compartments.length === 1 ? "" : "s"} from ${passCount} successful pass${passCount === 1 ? "" : "es"}.`,
|
|
@@ -171586,7 +171856,7 @@ Nothing was written.`;
|
|
|
171586
171856
|
|
|
171587
171857
|
This is your first run. No existing compartments or facts.` : "This is your first run. No existing state.";
|
|
171588
171858
|
cleanupHistorianStateFile(currentStateFilePath);
|
|
171589
|
-
currentStateFilePath = maybeWriteHistorianStateFile(sessionId, existingState);
|
|
171859
|
+
currentStateFilePath = maybeWriteHistorianStateFile(sessionId, existingState, sessionDirectory);
|
|
171590
171860
|
const prompt = buildCompartmentAgentPrompt(existingState, `Messages ${chunk.startIndex}-${chunk.endIndex}:
|
|
171591
171861
|
|
|
171592
171862
|
${chunk.text}`, { stateFilePath: currentStateFilePath });
|
|
@@ -171682,8 +171952,10 @@ Nothing was written.`;
|
|
|
171682
171952
|
clearRecompStaging(db, sessionId);
|
|
171683
171953
|
}
|
|
171684
171954
|
clearCompressionDepth(db, sessionId);
|
|
171685
|
-
|
|
171686
|
-
|
|
171955
|
+
if (deps.preserveInjectionCacheUntilConsumed !== true) {
|
|
171956
|
+
clearInjectionCache(sessionId);
|
|
171957
|
+
}
|
|
171958
|
+
deps.onCompartmentStatePublished?.(sessionId);
|
|
171687
171959
|
const finalCompartments = promoted?.compartments ?? candidateCompartments;
|
|
171688
171960
|
const finalFacts = promoted?.facts ?? candidateFacts;
|
|
171689
171961
|
if (deps.directory && deps.memoryEnabled !== false && deps.autoPromote !== false) {
|
|
@@ -171732,21 +172004,39 @@ Staging data preserved for resume on next attempt.`;
|
|
|
171732
172004
|
|
|
171733
172005
|
// ../plugin/src/hooks/magic-context/compartment-runner.ts
|
|
171734
172006
|
var activeRuns = new Map;
|
|
172007
|
+
function markActiveCompartmentRunPublished(sessionId) {
|
|
172008
|
+
const activeRun = activeRuns.get(sessionId);
|
|
172009
|
+
if (activeRun)
|
|
172010
|
+
activeRun.published = true;
|
|
172011
|
+
}
|
|
172012
|
+
function withPublishedCallback(deps) {
|
|
172013
|
+
return {
|
|
172014
|
+
...deps,
|
|
172015
|
+
onCompartmentStatePublished: (sid) => {
|
|
172016
|
+
markActiveCompartmentRunPublished(sid);
|
|
172017
|
+
deps.onCompartmentStatePublished?.(sid);
|
|
172018
|
+
}
|
|
172019
|
+
};
|
|
172020
|
+
}
|
|
171735
172021
|
async function executeContextRecomp(deps, options = {}) {
|
|
171736
172022
|
const { sessionId } = deps;
|
|
171737
172023
|
if (activeRuns.has(sessionId)) {
|
|
171738
172024
|
return "## Magic Recomp\n\nHistorian is already running for this session. Wait for it to finish, then try `/ctx-recomp` again.";
|
|
171739
172025
|
}
|
|
171740
|
-
const
|
|
171741
|
-
|
|
172026
|
+
const runnerDeps = withPublishedCallback(deps);
|
|
172027
|
+
const promise2 = options.range ? executePartialRecompInternal(runnerDeps, options.range) : executeContextRecompInternal(runnerDeps);
|
|
172028
|
+
const wrappedPromise = promise2.then(() => {
|
|
171742
172029
|
return;
|
|
171743
172030
|
}).catch((err) => {
|
|
171744
172031
|
sessionLog(sessionId, "compartment agent: recomp unhandled rejection:", err);
|
|
171745
|
-
})
|
|
172032
|
+
});
|
|
172033
|
+
activeRuns.set(sessionId, { promise: wrappedPromise, published: false });
|
|
171746
172034
|
try {
|
|
171747
172035
|
return await promise2;
|
|
171748
172036
|
} finally {
|
|
171749
|
-
activeRuns.
|
|
172037
|
+
if (activeRuns.get(sessionId)?.promise === wrappedPromise) {
|
|
172038
|
+
activeRuns.delete(sessionId);
|
|
172039
|
+
}
|
|
171750
172040
|
}
|
|
171751
172041
|
}
|
|
171752
172042
|
|
|
@@ -172239,7 +172529,7 @@ import {
|
|
|
172239
172529
|
// package.json
|
|
172240
172530
|
var package_default = {
|
|
172241
172531
|
name: "@cortexkit/pi-magic-context",
|
|
172242
|
-
version: "0.
|
|
172532
|
+
version: "0.19.0",
|
|
172243
172533
|
type: "module",
|
|
172244
172534
|
description: "Pi coding agent extension for Magic Context — cross-session memory and context management",
|
|
172245
172535
|
main: "dist/index.js",
|
|
@@ -172778,12 +173068,12 @@ function readHistorianState(db, sessionId, meta3) {
|
|
|
172778
173068
|
init_magic_context();
|
|
172779
173069
|
import { existsSync as existsSync8, readFileSync as readFileSync3 } from "node:fs";
|
|
172780
173070
|
import { homedir as homedir4 } from "node:os";
|
|
172781
|
-
import { join as
|
|
173071
|
+
import { join as join12 } from "node:path";
|
|
172782
173072
|
|
|
172783
173073
|
// ../plugin/src/config/variable.ts
|
|
172784
173074
|
import { existsSync as existsSync7, readFileSync as readFileSync2 } from "node:fs";
|
|
172785
173075
|
import { homedir as homedir3 } from "node:os";
|
|
172786
|
-
import { dirname as
|
|
173076
|
+
import { dirname as dirname4, isAbsolute, resolve } from "node:path";
|
|
172787
173077
|
var ENV_PATTERN = /\{env:([^}]+)\}/g;
|
|
172788
173078
|
var FILE_PATTERN = /\{file:([^}]+)\}/g;
|
|
172789
173079
|
function substituteConfigVariables(input) {
|
|
@@ -172802,7 +173092,7 @@ function substituteConfigVariables(input) {
|
|
|
172802
173092
|
if (fileMatches.length === 0) {
|
|
172803
173093
|
return { text, warnings };
|
|
172804
173094
|
}
|
|
172805
|
-
const configDir = input.configPath ?
|
|
173095
|
+
const configDir = input.configPath ? dirname4(input.configPath) : process.cwd();
|
|
172806
173096
|
let output = "";
|
|
172807
173097
|
let cursor = 0;
|
|
172808
173098
|
for (const match of fileMatches) {
|
|
@@ -172846,12 +173136,12 @@ function substituteConfigVariables(input) {
|
|
|
172846
173136
|
var import_comment_json = __toESM(require_src2(), 1);
|
|
172847
173137
|
var CONFIG_FILE_NAME = "magic-context";
|
|
172848
173138
|
function getProjectConfigPaths(cwd) {
|
|
172849
|
-
const basePath =
|
|
173139
|
+
const basePath = join12(cwd, ".pi", CONFIG_FILE_NAME);
|
|
172850
173140
|
return [`${basePath}.jsonc`, `${basePath}.json`];
|
|
172851
173141
|
}
|
|
172852
173142
|
function getUserConfigPaths() {
|
|
172853
173143
|
const home = process.env.HOME ?? homedir4();
|
|
172854
|
-
const basePath =
|
|
173144
|
+
const basePath = join12(home, ".pi", "agent", CONFIG_FILE_NAME);
|
|
172855
173145
|
return [`${basePath}.jsonc`, `${basePath}.json`];
|
|
172856
173146
|
}
|
|
172857
173147
|
function resolveFirstExisting(paths) {
|
|
@@ -173008,7 +173298,7 @@ function stripTagPrefixFromAssistantMessage(message) {
|
|
|
173008
173298
|
// src/system-prompt.ts
|
|
173009
173299
|
import { createHash as createHash4 } from "node:crypto";
|
|
173010
173300
|
import { existsSync as existsSync9, readFileSync as readFileSync4, realpathSync } from "node:fs";
|
|
173011
|
-
import { join as
|
|
173301
|
+
import { join as join13, resolve as resolve2, sep } from "node:path";
|
|
173012
173302
|
|
|
173013
173303
|
// ../plugin/src/agents/magic-context-prompt.ts
|
|
173014
173304
|
function getToolHistoryGuidance(dropToolStructure) {
|
|
@@ -173110,7 +173400,7 @@ var DOC_FILES = ["ARCHITECTURE.md", "STRUCTURE.md"];
|
|
|
173110
173400
|
function readProjectDocs(directory) {
|
|
173111
173401
|
const sections = [];
|
|
173112
173402
|
for (const filename of DOC_FILES) {
|
|
173113
|
-
const filePath =
|
|
173403
|
+
const filePath = join13(directory, filename);
|
|
173114
173404
|
try {
|
|
173115
173405
|
if (existsSync9(filePath)) {
|
|
173116
173406
|
const content = readFileSync4(filePath, "utf-8").trim();
|
|
@@ -178341,7 +178631,7 @@ function resolveDreamerFromConfig(config2) {
|
|
|
178341
178631
|
}
|
|
178342
178632
|
async function src_default2(pi) {
|
|
178343
178633
|
const storageDir = getMagicContextStorageDir();
|
|
178344
|
-
const dbPath =
|
|
178634
|
+
const dbPath = join14(storageDir, "context.db");
|
|
178345
178635
|
let db;
|
|
178346
178636
|
try {
|
|
178347
178637
|
db = openDatabase();
|