@cortexkit/magic-context 0.36.1 → 0.37.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 +725 -169
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -12847,15 +12847,16 @@ Edit those files directly, then rerun setup.`);
|
|
|
12847
12847
|
// ../plugin/src/shared/logger.ts
|
|
12848
12848
|
import * as fs from "node:fs";
|
|
12849
12849
|
import * as path2 from "node:path";
|
|
12850
|
-
function
|
|
12851
|
-
const dir = path2.dirname(filePath);
|
|
12852
|
-
if (dir === lastEnsuredDir)
|
|
12853
|
-
return;
|
|
12850
|
+
function recordSwallowedWrite(error) {
|
|
12854
12851
|
try {
|
|
12855
|
-
|
|
12856
|
-
|
|
12852
|
+
swallowedWriteCount++;
|
|
12853
|
+
lastErrorMessage = error instanceof Error ? error.message : String(error);
|
|
12854
|
+
lastErrorTime = new Date().toISOString();
|
|
12857
12855
|
} catch {}
|
|
12858
12856
|
}
|
|
12857
|
+
function ensureDir4(filePath) {
|
|
12858
|
+
fs.mkdirSync(path2.dirname(filePath), { recursive: true });
|
|
12859
|
+
}
|
|
12859
12860
|
function flush() {
|
|
12860
12861
|
if (flushTimer) {
|
|
12861
12862
|
clearTimeout(flushTimer);
|
|
@@ -12869,7 +12870,9 @@ function flush() {
|
|
|
12869
12870
|
const logFile = getMagicContextLogPath();
|
|
12870
12871
|
ensureDir4(logFile);
|
|
12871
12872
|
fs.appendFileSync(logFile, data);
|
|
12872
|
-
} catch {
|
|
12873
|
+
} catch (error) {
|
|
12874
|
+
recordSwallowedWrite(error);
|
|
12875
|
+
}
|
|
12873
12876
|
}
|
|
12874
12877
|
function scheduleFlush() {
|
|
12875
12878
|
if (flushTimer)
|
|
@@ -12895,7 +12898,7 @@ ${data.stack}` : ""}` : ` ${JSON.stringify(data)}`;
|
|
|
12895
12898
|
}
|
|
12896
12899
|
} catch {}
|
|
12897
12900
|
}
|
|
12898
|
-
var isTestEnv = false, buffer, flushTimer = null, FLUSH_INTERVAL_MS = 500, BUFFER_SIZE_LIMIT = 50,
|
|
12901
|
+
var isTestEnv = false, buffer, flushTimer = null, FLUSH_INTERVAL_MS = 500, BUFFER_SIZE_LIMIT = 50, swallowedWriteCount = 0, lastErrorMessage = null, lastErrorTime = null;
|
|
12899
12902
|
var init_logger = __esm(() => {
|
|
12900
12903
|
init_data_path();
|
|
12901
12904
|
buffer = [];
|
|
@@ -12903,6 +12906,43 @@ var init_logger = __esm(() => {
|
|
|
12903
12906
|
process.on("exit", flush);
|
|
12904
12907
|
}
|
|
12905
12908
|
});
|
|
12909
|
+
// ../plugin/src/shared/window-geometry.ts
|
|
12910
|
+
function setWindowOverlayPath(path3) {
|
|
12911
|
+
configuredOverlayPath = path3;
|
|
12912
|
+
loadedOverlayPath = undefined;
|
|
12913
|
+
loadedOverlay = undefined;
|
|
12914
|
+
}
|
|
12915
|
+
var GRADES, UNITS, BOUNDARIES, UNKNOWN_REASONS, NUMERIC_FACT_KEYS, configuredOverlayPath, loadedOverlayPath, loadedOverlay, geometryClampLogSeen;
|
|
12916
|
+
var init_window_geometry = __esm(() => {
|
|
12917
|
+
init_data_path();
|
|
12918
|
+
init_harness_provider_map();
|
|
12919
|
+
init_logger();
|
|
12920
|
+
GRADES = new Set([
|
|
12921
|
+
"provider_asserted_runtime",
|
|
12922
|
+
"measured",
|
|
12923
|
+
"provider_asserted_doc",
|
|
12924
|
+
"catalog",
|
|
12925
|
+
"unknown"
|
|
12926
|
+
]);
|
|
12927
|
+
UNITS = new Set(["provider", "estimate"]);
|
|
12928
|
+
BOUNDARIES = new Set(["Observed", "Asserted", "Corrected"]);
|
|
12929
|
+
UNKNOWN_REASONS = new Set([
|
|
12930
|
+
"placeholder_output_equals_context",
|
|
12931
|
+
"placeholder_zero",
|
|
12932
|
+
"never_measured",
|
|
12933
|
+
"not_single_valued_at_key",
|
|
12934
|
+
"retracted"
|
|
12935
|
+
]);
|
|
12936
|
+
NUMERIC_FACT_KEYS = new Set([
|
|
12937
|
+
"window.advertised",
|
|
12938
|
+
"window.enforced",
|
|
12939
|
+
"output.advertised",
|
|
12940
|
+
"output.enforced",
|
|
12941
|
+
"output.default"
|
|
12942
|
+
]);
|
|
12943
|
+
geometryClampLogSeen = new Set;
|
|
12944
|
+
});
|
|
12945
|
+
|
|
12906
12946
|
// ../plugin/src/shared/models-dev-cache.ts
|
|
12907
12947
|
function setOutputReserveConfig(config) {
|
|
12908
12948
|
outputReserveConfig = config;
|
|
@@ -12912,6 +12952,7 @@ var init_models_dev_cache = __esm(() => {
|
|
|
12912
12952
|
init_data_path();
|
|
12913
12953
|
init_harness_provider_map();
|
|
12914
12954
|
init_logger();
|
|
12955
|
+
init_window_geometry();
|
|
12915
12956
|
SEPARATE_OUTPUT_QUOTA_PROVIDERS = new Set(["google", "google-antigravity"]);
|
|
12916
12957
|
reserveClampLogSeen = new Set;
|
|
12917
12958
|
});
|
|
@@ -27951,6 +27992,9 @@ function isValidPromptSurfaceModelKey(key) {
|
|
|
27951
27992
|
return true;
|
|
27952
27993
|
return modelID.length > 0 && !modelID.startsWith("/") && !modelID.endsWith("/") && !modelID.includes("//");
|
|
27953
27994
|
}
|
|
27995
|
+
var init_prompt_surface = __esm(() => {
|
|
27996
|
+
init_harness_provider_map();
|
|
27997
|
+
});
|
|
27954
27998
|
|
|
27955
27999
|
// ../plugin/src/config/schema/agent-overrides.ts
|
|
27956
28000
|
var PermissionValueSchema, PermissionSchema, AgentOverrideConfigSchema;
|
|
@@ -28005,6 +28049,7 @@ var init_magic_context = __esm(() => {
|
|
|
28005
28049
|
init_zod();
|
|
28006
28050
|
init_language_directive();
|
|
28007
28051
|
init_cron();
|
|
28052
|
+
init_prompt_surface();
|
|
28008
28053
|
init_agent_overrides();
|
|
28009
28054
|
PiThinkingLevelSchema = exports_external.enum(["off", "minimal", "low", "medium", "high", "xhigh", "max"]).optional();
|
|
28010
28055
|
PiConfigSchema = exports_external.object({
|
|
@@ -28201,6 +28246,9 @@ var init_magic_context = __esm(() => {
|
|
|
28201
28246
|
exports_external.number().min(0),
|
|
28202
28247
|
exports_external.object({ default: exports_external.number().min(0) }).catchall(exports_external.number().min(0))
|
|
28203
28248
|
]).optional().describe('User-only output-token reservation override. Number or per-model object ({ default: 16384, "provider/model": 8192 }); 0 disables reservation. When unset, Magic Context reserves the catalog output limit (capped at 25% of context) for shared-window providers and keeps proven separate-quota Google/Gemini windows unchanged.'),
|
|
28249
|
+
models: exports_external.object({
|
|
28250
|
+
window_overlay_path: exports_external.string().trim().min(1).optional()
|
|
28251
|
+
}).optional().describe("User-only Fusiform window-overlay settings. The path defaults to <dataDir>/fusiform/window-overlay.json."),
|
|
28204
28252
|
toast_duration_ms: exports_external.number().min(0).max(60000).default(5000).describe("TUI toast lifetime in milliseconds for Magic Context notifications. Set to 0 to disable Magic Context toasts entirely (min: 0, max: 60000, default: 5000)"),
|
|
28205
28253
|
execute_threshold_percentage: exports_external.union([
|
|
28206
28254
|
exports_external.number().min(20).max(90, EXECUTE_THRESHOLD_CAP_MESSAGE),
|
|
@@ -28407,6 +28455,11 @@ function stripUnsafeProjectConfigFields(projectRaw) {
|
|
|
28407
28455
|
delete projectRaw.output_reserve;
|
|
28408
28456
|
warnings.push("Ignoring output_reserve from project config (security: output-token reservation only honors user-level config).");
|
|
28409
28457
|
}
|
|
28458
|
+
const models = projectRaw.models;
|
|
28459
|
+
if (isPlainObject2(models) && "window_overlay_path" in models) {
|
|
28460
|
+
delete models.window_overlay_path;
|
|
28461
|
+
warnings.push("Ignoring models.window_overlay_path from project config (security: only user-level config may select model geometry metadata).");
|
|
28462
|
+
}
|
|
28410
28463
|
if ("language" in projectRaw) {
|
|
28411
28464
|
delete projectRaw.language;
|
|
28412
28465
|
warnings.push("Ignoring language from project config (security: output language is a user-level setting).");
|
|
@@ -29085,6 +29138,7 @@ function loadPluginConfigDetailed(directory) {
|
|
|
29085
29138
|
const recoveredTopLevelKeys = [];
|
|
29086
29139
|
const config2 = parsePluginConfig(mergedRaw, recoveredTopLevelKeys);
|
|
29087
29140
|
setOutputReserveConfig(config2.output_reserve);
|
|
29141
|
+
setWindowOverlayPath(config2.models?.window_overlay_path);
|
|
29088
29142
|
if (config2.configWarnings?.length) {
|
|
29089
29143
|
allWarnings.push(...config2.configWarnings.map((w) => {
|
|
29090
29144
|
if (userLoaded && projectLoaded)
|
|
@@ -29126,6 +29180,7 @@ function loadPluginConfigDetailed(directory) {
|
|
|
29126
29180
|
var init_config = __esm(() => {
|
|
29127
29181
|
init_jsonc_parser();
|
|
29128
29182
|
init_models_dev_cache();
|
|
29183
|
+
init_window_geometry();
|
|
29129
29184
|
init_agent_disable();
|
|
29130
29185
|
init_migrate_config_location();
|
|
29131
29186
|
init_migrate_dreamer_v2();
|
|
@@ -29176,14 +29231,17 @@ function detectConflicts(directory, options) {
|
|
|
29176
29231
|
omoAnthropicRecovery: false
|
|
29177
29232
|
};
|
|
29178
29233
|
const reasons = [];
|
|
29179
|
-
|
|
29234
|
+
let compactionResult = options?.resolvedCompaction ?? checkCompaction(directory);
|
|
29235
|
+
if (process.env.OPENCODE_DISABLE_AUTOCOMPACT) {
|
|
29236
|
+
compactionResult = { auto: false, prune: false };
|
|
29237
|
+
}
|
|
29180
29238
|
if (compactionEnabled && compactionResult.auto) {
|
|
29181
29239
|
conflicts.compactionAuto = true;
|
|
29182
|
-
reasons.push("OpenCode auto-compaction is enabled (compaction.auto=true)");
|
|
29240
|
+
reasons.push(options?.resolvedCompaction ? "OpenCode auto-compaction is enabled (compaction.auto=true) (resolved config)" : "OpenCode auto-compaction is enabled (compaction.auto=true)");
|
|
29183
29241
|
}
|
|
29184
29242
|
if (compactionEnabled && compactionResult.prune) {
|
|
29185
29243
|
conflicts.compactionPrune = true;
|
|
29186
|
-
reasons.push("OpenCode prune is enabled (compaction.prune=true)");
|
|
29244
|
+
reasons.push(options?.resolvedCompaction ? "OpenCode prune is enabled (compaction.prune=true) (resolved config)" : "OpenCode prune is enabled (compaction.prune=true)");
|
|
29187
29245
|
}
|
|
29188
29246
|
const dcpFound = checkDcpPlugin(directory);
|
|
29189
29247
|
if (dcpFound) {
|
|
@@ -29371,6 +29429,7 @@ function readOmoDisabledHooks(directory) {
|
|
|
29371
29429
|
var DCP_PACKAGE_NAMES, OMO_PACKAGE_NAMES;
|
|
29372
29430
|
var init_conflict_detector = __esm(() => {
|
|
29373
29431
|
init_jsonc_parser();
|
|
29432
|
+
init_logger();
|
|
29374
29433
|
init_opencode_config_dir();
|
|
29375
29434
|
DCP_PACKAGE_NAMES = new Set(["@tarquinen/opencode-dcp"]);
|
|
29376
29435
|
OMO_PACKAGE_NAMES = new Set(["oh-my-opencode", "oh-my-openagent"]);
|
|
@@ -30671,6 +30730,7 @@ function prepareMirrorPageStatements(db) {
|
|
|
30671
30730
|
return {
|
|
30672
30731
|
identityByModule: db.prepare("SELECT context_row_id FROM mirror_identity WHERE domain = ? AND module_project = ? AND module_row_id = ?"),
|
|
30673
30732
|
insertIdentity: db.prepare("INSERT OR IGNORE INTO mirror_identity(domain, module_project, module_row_id, context_row_id) VALUES (?, ?, ?, ?)"),
|
|
30733
|
+
deleteIdentityByContext: db.prepare("DELETE FROM mirror_identity WHERE domain = ? AND context_row_id = ?"),
|
|
30674
30734
|
deleteLiveMemory: db.prepare("DELETE FROM mirror_live_memory_rows WHERE module_project = ? AND module_row_id = ?"),
|
|
30675
30735
|
deletePendingReferencesForMemory: db.prepare("DELETE FROM mirror_pending_references WHERE domain = ? AND module_project = ? AND (module_row_id = ? OR target_module_row_id = ?)"),
|
|
30676
30736
|
deleteIdentity: db.prepare("DELETE FROM mirror_identity WHERE domain = ? AND module_project = ? AND module_row_id = ?"),
|
|
@@ -30722,7 +30782,7 @@ function prepareMirrorPageStatements(db) {
|
|
|
30722
30782
|
check_quarantined_until = ?, check_next_due_at = ?, check_compiled_at = ?, check_false_since_at = ?,
|
|
30723
30783
|
check_last_liveness_at = ?, last_checked_at = ?, check_status = ?, check_version = ?,
|
|
30724
30784
|
policy_version = ?, anchor_block_id = ?, anchor_ordinal = ?, created_at = ?, updated_at = ? WHERE id = ?`),
|
|
30725
|
-
upsertNoteRevision: db.prepare("INSERT INTO mirror_note_revisions(module_project, module_row_id, context_row_id, status_version) VALUES (?, ?, ?, ?)
|
|
30785
|
+
upsertNoteRevision: db.prepare("INSERT OR REPLACE INTO mirror_note_revisions(module_project, module_row_id, context_row_id, status_version) VALUES (?, ?, ?, ?)"),
|
|
30726
30786
|
translateMemoryReferences: db.prepare(`UPDATE memories
|
|
30727
30787
|
SET superseded_by_memory_id = (
|
|
30728
30788
|
SELECT target.context_row_id
|
|
@@ -30795,6 +30855,9 @@ function rememberIdentity(db, domain2, moduleProject, moduleRowId, contextRowId,
|
|
|
30795
30855
|
const existing = mirrorIdentity(db, domain2, moduleProject, moduleRowId, statements);
|
|
30796
30856
|
if (existing)
|
|
30797
30857
|
return;
|
|
30858
|
+
if (domain2 === "notes") {
|
|
30859
|
+
(statements?.deleteIdentityByContext ?? db.prepare("DELETE FROM mirror_identity WHERE domain = ? AND context_row_id = ?")).run(domain2, contextRowId);
|
|
30860
|
+
}
|
|
30798
30861
|
(statements?.insertIdentity ?? db.prepare("INSERT OR IGNORE INTO mirror_identity(domain, module_project, module_row_id, context_row_id) VALUES (?, ?, ?, ?)")).run(domain2, moduleProject, moduleRowId, contextRowId);
|
|
30799
30862
|
}
|
|
30800
30863
|
function contextMemoryId(db, domain2, moduleProject, row, moduleRowId, statements) {
|
|
@@ -31427,11 +31490,12 @@ function gitRootInAncestorChain(startDirectory) {
|
|
|
31427
31490
|
function hasGitDirInAncestorChain(startDirectory) {
|
|
31428
31491
|
return gitRootInAncestorChain(startDirectory) !== null;
|
|
31429
31492
|
}
|
|
31430
|
-
var GIT_TIMEOUT_MS = 5000, TRANSIENT_FAILURE_COOLDOWN_MS, identityCache, lastKnownGitIdentityCache, directoryFallbackCache, transientFailureCooldown, dubiousOwnershipFallbackDirectories, dubiousOwnershipLoggedDirectories, dubiousOwnershipWarnedDirectories, transientGitIdentityReuseLoggedDirectories, execFileSyncForIdentity, nowMs = () => Date.now(), ProjectIdentityError;
|
|
31493
|
+
var GIT_TIMEOUT_MS = 5000, TRANSIENT_FAILURE_COOLDOWN_MS, identityCache, linkedGitWorktreeCache, lastKnownGitIdentityCache, directoryFallbackCache, transientFailureCooldown, dubiousOwnershipFallbackDirectories, dubiousOwnershipLoggedDirectories, dubiousOwnershipWarnedDirectories, transientGitIdentityReuseLoggedDirectories, execFileSyncForIdentity, nowMs = () => Date.now(), ProjectIdentityError;
|
|
31431
31494
|
var init_project_identity = __esm(() => {
|
|
31432
31495
|
init_logger();
|
|
31433
31496
|
TRANSIENT_FAILURE_COOLDOWN_MS = 5 * 60 * 1000;
|
|
31434
31497
|
identityCache = new Map;
|
|
31498
|
+
linkedGitWorktreeCache = new Map;
|
|
31435
31499
|
lastKnownGitIdentityCache = new Map;
|
|
31436
31500
|
directoryFallbackCache = new Map;
|
|
31437
31501
|
transientFailureCooldown = new Map;
|
|
@@ -33731,6 +33795,7 @@ class SubcModuleTransport {
|
|
|
33731
33795
|
return error51;
|
|
33732
33796
|
}
|
|
33733
33797
|
async beforeDeadline(operation, deadlineMs, detail) {
|
|
33798
|
+
operation.catch(() => {});
|
|
33734
33799
|
const remainingMs = deadlineMs - Date.now();
|
|
33735
33800
|
if (remainingMs <= 0)
|
|
33736
33801
|
throw this.deadlineError(detail);
|
|
@@ -34145,12 +34210,14 @@ import { execFileSync as execFileSync4 } from "node:child_process";
|
|
|
34145
34210
|
import { readFileSync as readFileSync12 } from "node:fs";
|
|
34146
34211
|
function isPidAlive(pid) {
|
|
34147
34212
|
if (!Number.isInteger(pid) || pid <= 0)
|
|
34148
|
-
return
|
|
34213
|
+
return "dead";
|
|
34214
|
+
if (rpcIdentityPlatform === "win32")
|
|
34215
|
+
return readWindowsProcess(pid).state;
|
|
34149
34216
|
try {
|
|
34150
|
-
|
|
34151
|
-
return
|
|
34152
|
-
} catch (
|
|
34153
|
-
return
|
|
34217
|
+
rpcIdentityProcessKill(pid, 0);
|
|
34218
|
+
return "alive";
|
|
34219
|
+
} catch (error51) {
|
|
34220
|
+
return error51.code === "ESRCH" ? "dead" : "inconclusive";
|
|
34154
34221
|
}
|
|
34155
34222
|
}
|
|
34156
34223
|
function parseLinuxProcessStartTime(statContent, uptimeContent) {
|
|
@@ -34179,7 +34246,8 @@ function readPsProcessStartTime(pid) {
|
|
|
34179
34246
|
try {
|
|
34180
34247
|
const output = rpcIdentityExecFileSync("ps", ["-p", String(pid), "-o", "lstart="], {
|
|
34181
34248
|
encoding: "utf8",
|
|
34182
|
-
timeout: PS_PROBE_TIMEOUT_MS
|
|
34249
|
+
timeout: PS_PROBE_TIMEOUT_MS,
|
|
34250
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
34183
34251
|
});
|
|
34184
34252
|
const processStartTime = Date.parse(String(output).trim());
|
|
34185
34253
|
return Number.isFinite(processStartTime) ? processStartTime : null;
|
|
@@ -34187,6 +34255,70 @@ function readPsProcessStartTime(pid) {
|
|
|
34187
34255
|
return null;
|
|
34188
34256
|
}
|
|
34189
34257
|
}
|
|
34258
|
+
function parseCsvLine(line) {
|
|
34259
|
+
const fields = [];
|
|
34260
|
+
let field = "";
|
|
34261
|
+
let quoted = false;
|
|
34262
|
+
for (let index = 0;index < line.length; index += 1) {
|
|
34263
|
+
const character = line[index];
|
|
34264
|
+
if (character === '"') {
|
|
34265
|
+
if (quoted && line[index + 1] === '"') {
|
|
34266
|
+
field += '"';
|
|
34267
|
+
index += 1;
|
|
34268
|
+
} else {
|
|
34269
|
+
quoted = !quoted;
|
|
34270
|
+
}
|
|
34271
|
+
} else if (character === "," && !quoted) {
|
|
34272
|
+
fields.push(field);
|
|
34273
|
+
field = "";
|
|
34274
|
+
} else {
|
|
34275
|
+
field += character;
|
|
34276
|
+
}
|
|
34277
|
+
}
|
|
34278
|
+
if (quoted)
|
|
34279
|
+
return null;
|
|
34280
|
+
fields.push(field);
|
|
34281
|
+
return fields;
|
|
34282
|
+
}
|
|
34283
|
+
function parseTasklistOutput(output) {
|
|
34284
|
+
const entries = [];
|
|
34285
|
+
let sawHeader = false;
|
|
34286
|
+
for (const rawLine of output.split(/\r?\n/)) {
|
|
34287
|
+
const line = rawLine.trim();
|
|
34288
|
+
if (!line)
|
|
34289
|
+
continue;
|
|
34290
|
+
if (TASKLIST_NO_TASKS_PATTERN.test(line))
|
|
34291
|
+
return [];
|
|
34292
|
+
const fields = parseCsvLine(line);
|
|
34293
|
+
if (!fields)
|
|
34294
|
+
continue;
|
|
34295
|
+
if (fields[1]?.trim().toLowerCase() === "pid") {
|
|
34296
|
+
sawHeader = true;
|
|
34297
|
+
continue;
|
|
34298
|
+
}
|
|
34299
|
+
const pid = Number(fields[1]);
|
|
34300
|
+
if (!Number.isInteger(pid) || pid <= 0 || !fields[0])
|
|
34301
|
+
continue;
|
|
34302
|
+
entries.push({ pid, command: fields[0] });
|
|
34303
|
+
}
|
|
34304
|
+
return entries.length > 0 || sawHeader ? entries : null;
|
|
34305
|
+
}
|
|
34306
|
+
function readWindowsProcess(pid) {
|
|
34307
|
+
try {
|
|
34308
|
+
const output = rpcIdentityExecFileSync("tasklist", ["/FO", "CSV", "/FI", `PID eq ${pid}`], {
|
|
34309
|
+
encoding: "utf8",
|
|
34310
|
+
timeout: PS_PROBE_TIMEOUT_MS,
|
|
34311
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
34312
|
+
});
|
|
34313
|
+
const entries = parseTasklistOutput(String(output));
|
|
34314
|
+
if (entries === null)
|
|
34315
|
+
return { state: "inconclusive" };
|
|
34316
|
+
const process3 = entries.find((entry) => entry.pid === pid);
|
|
34317
|
+
return process3 ? { state: "alive", command: process3.command } : { state: "dead" };
|
|
34318
|
+
} catch {
|
|
34319
|
+
return { state: "inconclusive" };
|
|
34320
|
+
}
|
|
34321
|
+
}
|
|
34190
34322
|
function readLinuxProcessCommand(pid) {
|
|
34191
34323
|
try {
|
|
34192
34324
|
return String(rpcIdentityReadFileSync(`/proc/${pid}/cmdline`, "utf8"));
|
|
@@ -34198,7 +34330,8 @@ function readPsProcessCommand(pid) {
|
|
|
34198
34330
|
try {
|
|
34199
34331
|
const output = rpcIdentityExecFileSync("ps", ["-p", String(pid), "-o", "command="], {
|
|
34200
34332
|
encoding: "utf8",
|
|
34201
|
-
timeout: PS_PROBE_TIMEOUT_MS
|
|
34333
|
+
timeout: PS_PROBE_TIMEOUT_MS,
|
|
34334
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
34202
34335
|
});
|
|
34203
34336
|
return String(output);
|
|
34204
34337
|
} catch {
|
|
@@ -34211,17 +34344,17 @@ function commandLooksLikeOpenCode(command) {
|
|
|
34211
34344
|
}
|
|
34212
34345
|
function isPidIdentityPlausible(record2) {
|
|
34213
34346
|
if (!Number.isInteger(record2.pid) || record2.pid <= 0)
|
|
34214
|
-
return
|
|
34347
|
+
return "implausible";
|
|
34215
34348
|
if (Number.isFinite(record2.started_at) && record2.started_at > 0) {
|
|
34216
|
-
const processStartTime = rpcIdentityPlatform === "linux" ? readLinuxProcessStartTime(record2.pid) : readPsProcessStartTime(record2.pid);
|
|
34349
|
+
const processStartTime = rpcIdentityPlatform === "linux" ? readLinuxProcessStartTime(record2.pid) : rpcIdentityPlatform === "win32" ? null : readPsProcessStartTime(record2.pid);
|
|
34217
34350
|
if (processStartTime === null)
|
|
34218
|
-
return
|
|
34219
|
-
return processStartTime <= record2.started_at + RPC_IDENTITY_SKEW_TOLERANCE_MS;
|
|
34351
|
+
return "inconclusive";
|
|
34352
|
+
return processStartTime <= record2.started_at + RPC_IDENTITY_SKEW_TOLERANCE_MS ? "plausible" : "implausible";
|
|
34220
34353
|
}
|
|
34221
|
-
const command = rpcIdentityPlatform === "linux" ? readLinuxProcessCommand(record2.pid) : readPsProcessCommand(record2.pid);
|
|
34354
|
+
const command = rpcIdentityPlatform === "linux" ? readLinuxProcessCommand(record2.pid) : rpcIdentityPlatform === "win32" ? readWindowsProcess(record2.pid).command ?? null : readPsProcessCommand(record2.pid);
|
|
34222
34355
|
if (command === null)
|
|
34223
|
-
return
|
|
34224
|
-
return commandLooksLikeOpenCode(command);
|
|
34356
|
+
return "inconclusive";
|
|
34357
|
+
return commandLooksLikeOpenCode(command) ? "plausible" : "implausible";
|
|
34225
34358
|
}
|
|
34226
34359
|
function commandLooksLikePi(command) {
|
|
34227
34360
|
const normalized = command.trim().toLowerCase().replaceAll("\\", "/");
|
|
@@ -34239,20 +34372,39 @@ function commandLooksLikePi(command) {
|
|
|
34239
34372
|
function inspectLivePiProcesses() {
|
|
34240
34373
|
if (false) {}
|
|
34241
34374
|
try {
|
|
34242
|
-
const
|
|
34375
|
+
const isWindows = rpcIdentityPlatform === "win32";
|
|
34376
|
+
const output = String(rpcProcessListExecFileSync(isWindows ? "tasklist" : "ps", isWindows ? ["/FO", "CSV"] : ["-axo", "pid=,command="], {
|
|
34243
34377
|
encoding: "utf8",
|
|
34244
|
-
timeout: PS_PROBE_TIMEOUT_MS
|
|
34378
|
+
timeout: PS_PROBE_TIMEOUT_MS,
|
|
34379
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
34245
34380
|
}));
|
|
34246
34381
|
const pids = new Set;
|
|
34247
|
-
|
|
34248
|
-
const
|
|
34249
|
-
if (
|
|
34250
|
-
|
|
34251
|
-
|
|
34252
|
-
|
|
34253
|
-
|
|
34254
|
-
|
|
34255
|
-
|
|
34382
|
+
if (isWindows) {
|
|
34383
|
+
const entries = parseTasklistOutput(output);
|
|
34384
|
+
if (entries === null) {
|
|
34385
|
+
return {
|
|
34386
|
+
state: "unreadable",
|
|
34387
|
+
processIds: [],
|
|
34388
|
+
error: "tasklist output unavailable"
|
|
34389
|
+
};
|
|
34390
|
+
}
|
|
34391
|
+
for (const entry of entries) {
|
|
34392
|
+
if (entry.pid === process.pid)
|
|
34393
|
+
continue;
|
|
34394
|
+
if (commandLooksLikePi(entry.command))
|
|
34395
|
+
pids.add(entry.pid);
|
|
34396
|
+
}
|
|
34397
|
+
} else {
|
|
34398
|
+
for (const line of output.split(/\r?\n/)) {
|
|
34399
|
+
const match = /^\s*(\d+)\s+(.+)$/.exec(line);
|
|
34400
|
+
if (!match)
|
|
34401
|
+
continue;
|
|
34402
|
+
const pid = Number(match[1]);
|
|
34403
|
+
if (!Number.isInteger(pid) || pid <= 0 || pid === process.pid)
|
|
34404
|
+
continue;
|
|
34405
|
+
if (commandLooksLikePi(match[2]))
|
|
34406
|
+
pids.add(pid);
|
|
34407
|
+
}
|
|
34256
34408
|
}
|
|
34257
34409
|
return { state: "known", processIds: [...pids].sort((left, right) => left - right) };
|
|
34258
34410
|
} catch (error51) {
|
|
@@ -34297,11 +34449,13 @@ function parseRpcPortFile(content, fallbackPid = 0) {
|
|
|
34297
34449
|
function isValidPort(port) {
|
|
34298
34450
|
return Number.isInteger(port) && port > 0 && port <= 65535;
|
|
34299
34451
|
}
|
|
34300
|
-
var RPC_IDENTITY_SKEW_TOLERANCE_MS = 120000, LINUX_CLOCK_TICKS_PER_SECOND = 100, PS_PROBE_TIMEOUT_MS = 1000, OPEN_CODE_COMMAND_MARKERS, rpcIdentityReadFileSync, rpcIdentityExecFileSync, rpcProcessListExecFileSync, rpcIdentityPlatform, rpcIdentityNowMs = () => Date.now();
|
|
34452
|
+
var RPC_IDENTITY_SKEW_TOLERANCE_MS = 120000, LINUX_CLOCK_TICKS_PER_SECOND = 100, PS_PROBE_TIMEOUT_MS = 1000, OPEN_CODE_COMMAND_MARKERS, TASKLIST_NO_TASKS_PATTERN, rpcIdentityReadFileSync, rpcIdentityExecFileSync, rpcIdentityProcessKill, rpcProcessListExecFileSync, rpcIdentityPlatform, rpcIdentityNowMs = () => Date.now();
|
|
34301
34453
|
var init_rpc_utils = __esm(() => {
|
|
34302
34454
|
OPEN_CODE_COMMAND_MARKERS = ["opencode", "node", "bun", "electron"];
|
|
34455
|
+
TASKLIST_NO_TASKS_PATTERN = /^INFO:\s+No tasks are running which match the specified criteria\.?$/im;
|
|
34303
34456
|
rpcIdentityReadFileSync = readFileSync12;
|
|
34304
34457
|
rpcIdentityExecFileSync = execFileSync4;
|
|
34458
|
+
rpcIdentityProcessKill = process.kill;
|
|
34305
34459
|
rpcProcessListExecFileSync = execFileSync4;
|
|
34306
34460
|
rpcIdentityPlatform = process.platform;
|
|
34307
34461
|
});
|
|
@@ -34528,6 +34682,8 @@ function healAllNullColumns(db) {
|
|
|
34528
34682
|
["stripped_placeholder_ids", ""],
|
|
34529
34683
|
["stale_reduce_stripped_ids", ""],
|
|
34530
34684
|
["processed_image_stripped_ids", ""],
|
|
34685
|
+
["merged_reasoning_stripped_ids", ""],
|
|
34686
|
+
["trailing_blank_decisions", ""],
|
|
34531
34687
|
["memory_block_cache", ""],
|
|
34532
34688
|
["memory_block_ids", ""],
|
|
34533
34689
|
["compaction_marker_state", ""],
|
|
@@ -34981,6 +35137,7 @@ var init_migrations = __esm(() => {
|
|
|
34981
35137
|
status TEXT NOT NULL DEFAULT 'active',
|
|
34982
35138
|
promoted_at INTEGER NOT NULL,
|
|
34983
35139
|
source_candidate_ids TEXT DEFAULT '[]',
|
|
35140
|
+
source_candidate_provenance TEXT,
|
|
34984
35141
|
created_at INTEGER NOT NULL,
|
|
34985
35142
|
updated_at INTEGER NOT NULL
|
|
34986
35143
|
);
|
|
@@ -36007,6 +36164,7 @@ var init_migrations = __esm(() => {
|
|
|
36007
36164
|
last_observed_at INTEGER,
|
|
36008
36165
|
answer_refreshed_at INTEGER,
|
|
36009
36166
|
source_candidate_ids TEXT NOT NULL DEFAULT '[]',
|
|
36167
|
+
source_candidate_provenance TEXT,
|
|
36010
36168
|
created_at INTEGER NOT NULL,
|
|
36011
36169
|
updated_at INTEGER NOT NULL
|
|
36012
36170
|
);
|
|
@@ -36816,6 +36974,37 @@ var init_migrations = __esm(() => {
|
|
|
36816
36974
|
ensureColumn(db, "notes", "compiled_at", "INTEGER");
|
|
36817
36975
|
ensureColumn(db, "notes", "compile_status", "TEXT CHECK(compile_status IN ('compiled', 'plain', 'refused'))");
|
|
36818
36976
|
}
|
|
36977
|
+
},
|
|
36978
|
+
{
|
|
36979
|
+
version: 77,
|
|
36980
|
+
description: "persist scoped provenance for promoted user memories and primers",
|
|
36981
|
+
up(db) {
|
|
36982
|
+
if (tableExists(db, "user_memories")) {
|
|
36983
|
+
ensureColumn(db, "user_memories", "source_candidate_provenance", "TEXT");
|
|
36984
|
+
}
|
|
36985
|
+
if (tableExists(db, "primers")) {
|
|
36986
|
+
ensureColumn(db, "primers", "source_candidate_provenance", "TEXT");
|
|
36987
|
+
}
|
|
36988
|
+
}
|
|
36989
|
+
},
|
|
36990
|
+
{
|
|
36991
|
+
version: 78,
|
|
36992
|
+
description: "add migration_pending journal for crash-safe cross-harness session migration",
|
|
36993
|
+
up(db) {
|
|
36994
|
+
db.exec(`
|
|
36995
|
+
CREATE TABLE IF NOT EXISTS migration_pending (
|
|
36996
|
+
migration_key TEXT PRIMARY KEY,
|
|
36997
|
+
source_session_id TEXT NOT NULL,
|
|
36998
|
+
target_harness TEXT NOT NULL,
|
|
36999
|
+
pi_session_id TEXT NOT NULL,
|
|
37000
|
+
final_path TEXT NOT NULL,
|
|
37001
|
+
stage_path TEXT NOT NULL,
|
|
37002
|
+
content_sha256 TEXT NOT NULL,
|
|
37003
|
+
phase TEXT NOT NULL CHECK (phase IN ('staged', 'db_committed')),
|
|
37004
|
+
created_at INTEGER NOT NULL
|
|
37005
|
+
);
|
|
37006
|
+
`);
|
|
37007
|
+
}
|
|
36819
37008
|
}
|
|
36820
37009
|
];
|
|
36821
37010
|
LATEST_MIGRATION_VERSION = MIGRATIONS.reduce((max, m3) => Math.max(max, m3.version), 0);
|
|
@@ -36944,6 +37133,7 @@ function inspectRpcServerDiscovery(storageDir) {
|
|
|
36944
37133
|
}
|
|
36945
37134
|
const pids = new Set;
|
|
36946
37135
|
const staleFiles = [];
|
|
37136
|
+
const inconclusivePids = new Set;
|
|
36947
37137
|
for (const portFile of portFiles) {
|
|
36948
37138
|
let raw;
|
|
36949
37139
|
try {
|
|
@@ -36963,10 +37153,15 @@ function inspectRpcServerDiscovery(storageDir) {
|
|
|
36963
37153
|
return junk;
|
|
36964
37154
|
continue;
|
|
36965
37155
|
}
|
|
36966
|
-
|
|
37156
|
+
const liveness = isPidAlive(record2.pid);
|
|
37157
|
+
const identity = liveness === "dead" ? "implausible" : isPidIdentityPlausible(record2);
|
|
37158
|
+
if (liveness === "alive" && identity === "plausible") {
|
|
36967
37159
|
pids.add(record2.pid);
|
|
36968
|
-
else
|
|
37160
|
+
} else if (liveness === "dead" || identity === "implausible") {
|
|
36969
37161
|
staleFiles.push(portFile);
|
|
37162
|
+
} else {
|
|
37163
|
+
inconclusivePids.add(record2.pid);
|
|
37164
|
+
}
|
|
36970
37165
|
}
|
|
36971
37166
|
for (const staleFile of staleFiles) {
|
|
36972
37167
|
try {
|
|
@@ -36979,6 +37174,15 @@ function inspectRpcServerDiscovery(storageDir) {
|
|
|
36979
37174
|
if (serverPids.length > 0) {
|
|
36980
37175
|
return { state: "live", serverPids, staleFiles };
|
|
36981
37176
|
}
|
|
37177
|
+
const uncertainPids = [...inconclusivePids].sort((a3, b2) => a3 - b2);
|
|
37178
|
+
if (uncertainPids.length > 0) {
|
|
37179
|
+
return {
|
|
37180
|
+
state: "inconclusive",
|
|
37181
|
+
serverPids: [],
|
|
37182
|
+
staleFiles,
|
|
37183
|
+
inconclusivePids: uncertainPids
|
|
37184
|
+
};
|
|
37185
|
+
}
|
|
36982
37186
|
return { state: "stale", serverPids: [], staleFiles };
|
|
36983
37187
|
}
|
|
36984
37188
|
function getLiveMigrationBlockingProcesses(storageDir) {
|
|
@@ -37163,6 +37367,7 @@ function initializeDatabase(db) {
|
|
|
37163
37367
|
last_observed_at INTEGER,
|
|
37164
37368
|
answer_refreshed_at INTEGER,
|
|
37165
37369
|
source_candidate_ids TEXT NOT NULL DEFAULT '[]',
|
|
37370
|
+
source_candidate_provenance TEXT,
|
|
37166
37371
|
created_at INTEGER NOT NULL,
|
|
37167
37372
|
updated_at INTEGER NOT NULL
|
|
37168
37373
|
);
|
|
@@ -37798,6 +38003,11 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
37798
38003
|
ensureColumn(db, "primer_candidates", "question_embedding", "BLOB");
|
|
37799
38004
|
ensureColumn(db, "primer_candidates", "question_embedding_model_id", "TEXT");
|
|
37800
38005
|
ensureColumn(db, "primers", "question_embedding_model_id", "TEXT");
|
|
38006
|
+
ensureColumn(db, "primers", "source_candidate_provenance", "TEXT");
|
|
38007
|
+
const hasUserMemoriesTable = db.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'user_memories'").get();
|
|
38008
|
+
if (hasUserMemoriesTable) {
|
|
38009
|
+
ensureColumn(db, "user_memories", "source_candidate_provenance", "TEXT");
|
|
38010
|
+
}
|
|
37801
38011
|
db.exec(`
|
|
37802
38012
|
CREATE UNIQUE INDEX IF NOT EXISTS idx_primer_candidates_occurrence
|
|
37803
38013
|
ON primer_candidates(project_path, harness, session_id, source_start_message_id, source_end_message_id);
|
|
@@ -37871,6 +38081,8 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
37871
38081
|
ensureColumn(db, "session_meta", "stripped_placeholder_ids", "TEXT DEFAULT ''");
|
|
37872
38082
|
ensureColumn(db, "session_meta", "stale_reduce_stripped_ids", "TEXT DEFAULT ''");
|
|
37873
38083
|
ensureColumn(db, "session_meta", "processed_image_stripped_ids", "TEXT DEFAULT ''");
|
|
38084
|
+
ensureColumn(db, "session_meta", "merged_reasoning_stripped_ids", "TEXT DEFAULT ''");
|
|
38085
|
+
ensureColumn(db, "session_meta", "trailing_blank_decisions", "TEXT DEFAULT ''");
|
|
37874
38086
|
ensureColumn(db, "compartments", "start_message_id", "TEXT DEFAULT ''");
|
|
37875
38087
|
ensureColumn(db, "compartments", "end_message_id", "TEXT DEFAULT ''");
|
|
37876
38088
|
ensureColumn(db, "memory_embeddings", "model_id", "TEXT");
|
|
@@ -38089,7 +38301,7 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
38089
38301
|
ensureColumn(db, "message_history_index", "harness", "TEXT NOT NULL DEFAULT 'opencode'");
|
|
38090
38302
|
ensureColumn(db, "workspaces", "share_categories", `TEXT NOT NULL DEFAULT '["CONSTRAINTS"]'`);
|
|
38091
38303
|
}
|
|
38092
|
-
var databases, pendingAsyncOpens, persistenceByDatabase, persistenceErrorByDatabase, pathByDatabase, LATEST_SUPPORTED_VERSION =
|
|
38304
|
+
var databases, pendingAsyncOpens, persistenceByDatabase, persistenceErrorByDatabase, pathByDatabase, LATEST_SUPPORTED_VERSION = 78, PERMISSIONS_ENFORCEABLE, RPC_DISCOVERY_PARSE_GRACE_MS, defaultRpcDiscoveryFs, rpcDiscoveryFs, sqlitePragmaConfig;
|
|
38093
38305
|
var init_storage_db = __esm(async () => {
|
|
38094
38306
|
init_data_path();
|
|
38095
38307
|
init_logger();
|
|
@@ -38224,8 +38436,44 @@ var init_database_access = __esm(async () => {
|
|
|
38224
38436
|
var exports_doctor_authority = {};
|
|
38225
38437
|
__export(exports_doctor_authority, {
|
|
38226
38438
|
runDoctorDrainAuthority: () => runDoctorDrainAuthority,
|
|
38227
|
-
reportAuthorityMarkers: () => reportAuthorityMarkers
|
|
38439
|
+
reportAuthorityMarkers: () => reportAuthorityMarkers,
|
|
38440
|
+
authorityDrainCommand: () => authorityDrainCommand,
|
|
38441
|
+
assertProjectsUseTsAuthority: () => assertProjectsUseTsAuthority
|
|
38228
38442
|
});
|
|
38443
|
+
function authorityDrainCommand(project) {
|
|
38444
|
+
return `magic-context doctor drain-authority ${project.projectRoot ?? `<${project.role} project root>`}`;
|
|
38445
|
+
}
|
|
38446
|
+
async function assertProjectsUseTsAuthority(args) {
|
|
38447
|
+
const markers = listAuthorityManagedMarkers(args.db);
|
|
38448
|
+
const markerByProject = new Map(markers.map((marker) => [marker.project_path, marker]));
|
|
38449
|
+
for (const project of args.projects) {
|
|
38450
|
+
const marker = markerByProject.get(project.projectPath);
|
|
38451
|
+
if (!marker)
|
|
38452
|
+
continue;
|
|
38453
|
+
const projectRoot = project.projectRoot;
|
|
38454
|
+
if (!projectRoot) {
|
|
38455
|
+
throw new Error(`Migration refused: durable module authority for ${project.role} project ${project.projectPath} cannot be checked because its project directory is unavailable. ` + `Writes remain fenced. Drain it first: ${authorityDrainCommand(project)}`);
|
|
38456
|
+
}
|
|
38457
|
+
let statuses;
|
|
38458
|
+
try {
|
|
38459
|
+
statuses = await Promise.all(AUTHORITY_DOMAINS.map((domain2) => args.module.authorityStatus({
|
|
38460
|
+
context_store_uuid: marker.context_store_uuid,
|
|
38461
|
+
project: project.projectPath,
|
|
38462
|
+
projectRoot,
|
|
38463
|
+
domain: domain2
|
|
38464
|
+
})));
|
|
38465
|
+
} catch (error51) {
|
|
38466
|
+
throw new Error(`Migration refused: module unreachable while checking ${project.role} project ${project.projectPath}; writes remain fenced. ` + `Drain it first: ${authorityDrainCommand(project)}. ` + `Module error: ${error51 instanceof Error ? error51.message : String(error51)}`);
|
|
38467
|
+
}
|
|
38468
|
+
for (const [index, status] of statuses.entries()) {
|
|
38469
|
+
const state = status.authority?.state ?? "TS";
|
|
38470
|
+
if (state === "TS")
|
|
38471
|
+
continue;
|
|
38472
|
+
throw new Error(`Migration refused: ${project.role} project ${project.projectPath} has ${AUTHORITY_DOMAINS[index]} authority in ${state} mode; writes remain fenced. ` + `Drain it first: ${authorityDrainCommand(project)}`);
|
|
38473
|
+
}
|
|
38474
|
+
}
|
|
38475
|
+
return { markers };
|
|
38476
|
+
}
|
|
38229
38477
|
function authorityClient(transport, projectRoot) {
|
|
38230
38478
|
return {
|
|
38231
38479
|
authorityStatus: (request) => transport.authorityStatus({ ...request, projectRoot }),
|
|
@@ -38258,12 +38506,12 @@ async function reportAuthorityMarkers(args) {
|
|
|
38258
38506
|
}
|
|
38259
38507
|
try {
|
|
38260
38508
|
const module = authorityClient(transport, process.cwd());
|
|
38261
|
-
const statuses = await Promise.all(
|
|
38509
|
+
const statuses = await Promise.all(AUTHORITY_DOMAINS.map((domain2) => module.authorityStatus({
|
|
38262
38510
|
context_store_uuid: ensureContextStoreUuid(args.db),
|
|
38263
38511
|
project: marker.project_path,
|
|
38264
38512
|
domain: domain2
|
|
38265
38513
|
})));
|
|
38266
|
-
args.info(` ${marker.project_path}: ${statuses.map((status, index) => `${
|
|
38514
|
+
args.info(` ${marker.project_path}: ${statuses.map((status, index) => `${AUTHORITY_DOMAINS[index]}=${status.authority?.state ?? "TS"}`).join(", ")}`);
|
|
38267
38515
|
} catch {
|
|
38268
38516
|
args.warn(` ${marker.project_path}: module unreachable — writes fenced; run with rust mode or restore subc connectivity`);
|
|
38269
38517
|
}
|
|
@@ -38283,7 +38531,7 @@ async function runDoctorDrainAuthority(projectRoot, dbPath) {
|
|
|
38283
38531
|
}
|
|
38284
38532
|
const module = authorityClient(new SubcModuleTransport, projectRoot);
|
|
38285
38533
|
let drainedAny = false;
|
|
38286
|
-
for (const domain2 of
|
|
38534
|
+
for (const domain2 of AUTHORITY_DOMAINS) {
|
|
38287
38535
|
const status = await module.authorityStatus({
|
|
38288
38536
|
context_store_uuid: ensureContextStoreUuid(db),
|
|
38289
38537
|
project: projectPath,
|
|
@@ -38327,7 +38575,6 @@ async function runDoctorDrainAuthority(projectRoot, dbPath) {
|
|
|
38327
38575
|
db.close();
|
|
38328
38576
|
}
|
|
38329
38577
|
}
|
|
38330
|
-
var DOMAINS;
|
|
38331
38578
|
var init_doctor_authority = __esm(async () => {
|
|
38332
38579
|
init_project_identity();
|
|
38333
38580
|
init_storage_project_state();
|
|
@@ -38336,7 +38583,6 @@ var init_doctor_authority = __esm(async () => {
|
|
|
38336
38583
|
init_context_authority(),
|
|
38337
38584
|
init_database_access()
|
|
38338
38585
|
]);
|
|
38339
|
-
DOMAINS = ["memories", "notes"];
|
|
38340
38586
|
});
|
|
38341
38587
|
|
|
38342
38588
|
// ../plugin/src/features/magic-context/storage-identity-merge.ts
|
|
@@ -39225,17 +39471,20 @@ var init_migration_paths = () => {};
|
|
|
39225
39471
|
// src/commands/migrate.ts
|
|
39226
39472
|
var exports_migrate = {};
|
|
39227
39473
|
__export(exports_migrate, {
|
|
39474
|
+
sweepPendingMigrations: () => sweepPendingMigrations,
|
|
39228
39475
|
runMigrateCli: () => runMigrateCli,
|
|
39229
39476
|
projectPathToPiDirSlug: () => projectPathToPiDirSlug,
|
|
39230
39477
|
printMigrateHelp: () => printMigrateHelp,
|
|
39231
39478
|
parseMigrateArgs: () => parseMigrateArgs,
|
|
39479
|
+
migrationKeyFor: () => migrationKeyFor,
|
|
39232
39480
|
migrateOpenCodeSessionToPi: () => migrateOpenCodeSessionToPi,
|
|
39233
39481
|
generateUuidV7: () => generateUuidV7,
|
|
39234
|
-
formatPiFilenameTimestamp: () => formatPiFilenameTimestamp
|
|
39482
|
+
formatPiFilenameTimestamp: () => formatPiFilenameTimestamp,
|
|
39483
|
+
formatMigrationSweepLines: () => formatMigrationSweepLines
|
|
39235
39484
|
});
|
|
39236
|
-
import { randomBytes as randomBytes2 } from "node:crypto";
|
|
39237
|
-
import { unlinkSync as unlinkSync3 } from "node:fs";
|
|
39238
|
-
import { join as join18 } from "node:path";
|
|
39485
|
+
import { createHash as createHash3, randomBytes as randomBytes2 } from "node:crypto";
|
|
39486
|
+
import { existsSync as existsSync21, mkdirSync as mkdirSync8, renameSync as renameSync4, unlinkSync as unlinkSync3 } from "node:fs";
|
|
39487
|
+
import { dirname as dirname12, join as join18 } from "node:path";
|
|
39239
39488
|
function defaultOpenCodeDbPath() {
|
|
39240
39489
|
return getOpenCodeDatabasePath();
|
|
39241
39490
|
}
|
|
@@ -39246,7 +39495,7 @@ function defaultPiSessionsRoot() {
|
|
|
39246
39495
|
return getPiSessionsRoot();
|
|
39247
39496
|
}
|
|
39248
39497
|
function defaultFs() {
|
|
39249
|
-
return { writeFileAtomic, unlinkSync: unlinkSync3 };
|
|
39498
|
+
return { writeFileAtomic, unlinkSync: unlinkSync3, existsSync: existsSync21, renameSync: renameSync4, mkdirSync: mkdirSync8 };
|
|
39250
39499
|
}
|
|
39251
39500
|
function stmt(db, sql) {
|
|
39252
39501
|
return db.prepare(sql);
|
|
@@ -39272,6 +39521,74 @@ function generateUuidV7(date5 = new Date) {
|
|
|
39272
39521
|
function shortId() {
|
|
39273
39522
|
return randomBytes2(4).toString("hex");
|
|
39274
39523
|
}
|
|
39524
|
+
function migrationKeyFor(sourceSessionId, targetHarness) {
|
|
39525
|
+
return createHash3("sha256").update(`${sourceSessionId}
|
|
39526
|
+
${targetHarness}`).digest("hex");
|
|
39527
|
+
}
|
|
39528
|
+
function hasMigrationJournal(db) {
|
|
39529
|
+
return Boolean(stmt(db, "SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'migration_pending'").get());
|
|
39530
|
+
}
|
|
39531
|
+
function sweepPendingMigrations(db, fs3 = defaultFs()) {
|
|
39532
|
+
const report = {
|
|
39533
|
+
completed: 0,
|
|
39534
|
+
rolledForward: 0,
|
|
39535
|
+
rolledBack: 0,
|
|
39536
|
+
lost: []
|
|
39537
|
+
};
|
|
39538
|
+
if (!hasMigrationJournal(db))
|
|
39539
|
+
return report;
|
|
39540
|
+
const rows = stmt(db, `SELECT migration_key, source_session_id, target_harness, pi_session_id,
|
|
39541
|
+
final_path, stage_path, content_sha256, phase, created_at
|
|
39542
|
+
FROM migration_pending
|
|
39543
|
+
ORDER BY created_at ASC`).all();
|
|
39544
|
+
for (const row of rows) {
|
|
39545
|
+
if (fs3.existsSync(row.final_path)) {
|
|
39546
|
+
stmt(db, "DELETE FROM migration_pending WHERE migration_key = ?").run(row.migration_key);
|
|
39547
|
+
report.completed += 1;
|
|
39548
|
+
continue;
|
|
39549
|
+
}
|
|
39550
|
+
if (row.phase === "db_committed") {
|
|
39551
|
+
if (fs3.existsSync(row.stage_path)) {
|
|
39552
|
+
fs3.mkdirSync(dirname12(row.final_path), { recursive: true });
|
|
39553
|
+
fs3.renameSync(row.stage_path, row.final_path);
|
|
39554
|
+
stmt(db, "DELETE FROM migration_pending WHERE migration_key = ?").run(row.migration_key);
|
|
39555
|
+
report.rolledForward += 1;
|
|
39556
|
+
} else {
|
|
39557
|
+
report.lost.push(row);
|
|
39558
|
+
}
|
|
39559
|
+
continue;
|
|
39560
|
+
}
|
|
39561
|
+
try {
|
|
39562
|
+
fs3.unlinkSync(row.stage_path);
|
|
39563
|
+
} catch {}
|
|
39564
|
+
stmt(db, "DELETE FROM migration_pending WHERE migration_key = ?").run(row.migration_key);
|
|
39565
|
+
report.rolledBack += 1;
|
|
39566
|
+
}
|
|
39567
|
+
return report;
|
|
39568
|
+
}
|
|
39569
|
+
function readPendingMigration(db, migrationKey) {
|
|
39570
|
+
return stmt(db, JOURNAL_SELECT_SQL).get(migrationKey);
|
|
39571
|
+
}
|
|
39572
|
+
function claimJournalIdentity(args) {
|
|
39573
|
+
const existing = readPendingMigration(args.db, args.migrationKey);
|
|
39574
|
+
if (existing) {
|
|
39575
|
+
return { row: existing, resumed: true };
|
|
39576
|
+
}
|
|
39577
|
+
const piSessionId = generateUuidV7(new Date(args.now));
|
|
39578
|
+
stmt(args.db, `INSERT INTO migration_pending (
|
|
39579
|
+
migration_key, source_session_id, target_harness, pi_session_id,
|
|
39580
|
+
final_path, stage_path, content_sha256, phase, created_at
|
|
39581
|
+
) VALUES (?, ?, ?, ?, ?, ?, '', 'staged', ?)
|
|
39582
|
+
ON CONFLICT(migration_key) DO NOTHING`).run(args.migrationKey, args.sourceSessionId, args.targetHarness, piSessionId, args.finalPathFor(piSessionId), join18(args.stageDir, `${args.migrationKey}.jsonl`), args.now);
|
|
39583
|
+
const row = readPendingMigration(args.db, args.migrationKey);
|
|
39584
|
+
if (!row) {
|
|
39585
|
+
throw new Error("migration journal row disappeared during insert; aborting migration");
|
|
39586
|
+
}
|
|
39587
|
+
return { row, resumed: row.pi_session_id !== piSessionId };
|
|
39588
|
+
}
|
|
39589
|
+
function commitStagedChecksum(db, migrationKey, contentSha256) {
|
|
39590
|
+
stmt(db, "UPDATE migration_pending SET content_sha256 = ? WHERE migration_key = ?").run(contentSha256, migrationKey);
|
|
39591
|
+
}
|
|
39275
39592
|
function parseJsonObject(text3) {
|
|
39276
39593
|
const parsed = JSON.parse(text3);
|
|
39277
39594
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
@@ -39431,7 +39748,7 @@ function convertPartToEntries(ctx) {
|
|
|
39431
39748
|
}
|
|
39432
39749
|
}
|
|
39433
39750
|
function buildPiEntries(params) {
|
|
39434
|
-
const sessionUuid =
|
|
39751
|
+
const sessionUuid = params.piSessionId;
|
|
39435
39752
|
const nowIso = params.now.toISOString();
|
|
39436
39753
|
const entries = [
|
|
39437
39754
|
{
|
|
@@ -39467,6 +39784,7 @@ The following conversation was migrated from a different harness. Reasoning cont
|
|
|
39467
39784
|
list.push(part);
|
|
39468
39785
|
partsByMessage.set(part.message_id, list);
|
|
39469
39786
|
}
|
|
39787
|
+
const messageIdToFirstPiEntryId = new Map;
|
|
39470
39788
|
const messageIdToLastPiEntryId = new Map;
|
|
39471
39789
|
const orderedSourceMessageIds = [];
|
|
39472
39790
|
let parentId = boundary.id;
|
|
@@ -39477,6 +39795,7 @@ The following conversation was migrated from a different harness. Reasoning cont
|
|
|
39477
39795
|
const timestamp2 = isoFromMs(message.time_created, params.now);
|
|
39478
39796
|
const tokens = tokensFromMessage(message);
|
|
39479
39797
|
const usage = tokensToPiUsage(tokens);
|
|
39798
|
+
let firstEntryIdForMessage = null;
|
|
39480
39799
|
let lastEntryIdForMessage = null;
|
|
39481
39800
|
for (const part of partsByMessage.get(message.id) ?? []) {
|
|
39482
39801
|
const newEntries = convertPartToEntries({
|
|
@@ -39491,10 +39810,13 @@ The following conversation was migrated from a different harness. Reasoning cont
|
|
|
39491
39810
|
entry.parentId = parentId;
|
|
39492
39811
|
entries.push(entry);
|
|
39493
39812
|
parentId = entry.id;
|
|
39813
|
+
if (firstEntryIdForMessage === null)
|
|
39814
|
+
firstEntryIdForMessage = parentId;
|
|
39494
39815
|
lastEntryIdForMessage = parentId;
|
|
39495
39816
|
}
|
|
39496
39817
|
}
|
|
39497
|
-
if (lastEntryIdForMessage !== null) {
|
|
39818
|
+
if (lastEntryIdForMessage !== null && firstEntryIdForMessage !== null) {
|
|
39819
|
+
messageIdToFirstPiEntryId.set(message.id, firstEntryIdForMessage);
|
|
39498
39820
|
messageIdToLastPiEntryId.set(message.id, lastEntryIdForMessage);
|
|
39499
39821
|
orderedSourceMessageIds.push(message.id);
|
|
39500
39822
|
}
|
|
@@ -39502,6 +39824,7 @@ The following conversation was migrated from a different harness. Reasoning cont
|
|
|
39502
39824
|
return {
|
|
39503
39825
|
entries,
|
|
39504
39826
|
piSessionId: sessionUuid,
|
|
39827
|
+
messageIdToFirstPiEntryId,
|
|
39505
39828
|
messageIdToLastPiEntryId,
|
|
39506
39829
|
orderedSourceMessageIds
|
|
39507
39830
|
};
|
|
@@ -39539,8 +39862,9 @@ function fetchRows(db, sessionId, maxMessages) {
|
|
|
39539
39862
|
throw error51;
|
|
39540
39863
|
}
|
|
39541
39864
|
}
|
|
39542
|
-
function remapBoundaryId(openCodeMessageId, messageIdToLastPiEntryId, orderedSourceMessageIds) {
|
|
39543
|
-
const
|
|
39865
|
+
function remapBoundaryId(openCodeMessageId, edge, messageIdToFirstPiEntryId, messageIdToLastPiEntryId, orderedSourceMessageIds) {
|
|
39866
|
+
const directMap = edge === "start" ? messageIdToFirstPiEntryId : messageIdToLastPiEntryId;
|
|
39867
|
+
const direct = directMap.get(openCodeMessageId);
|
|
39544
39868
|
if (direct !== undefined)
|
|
39545
39869
|
return { piEntryId: direct, exact: true };
|
|
39546
39870
|
let nearestAtOrBefore;
|
|
@@ -39601,8 +39925,8 @@ function copyMagicContextState(args) {
|
|
|
39601
39925
|
let boundariesApproximated = 0;
|
|
39602
39926
|
const remappedCompartments = [];
|
|
39603
39927
|
for (const c3 of sourceCompartments) {
|
|
39604
|
-
const startRemap = remapBoundaryId(c3.start_message_id, args.messageIdToLastPiEntryId, args.orderedSourceMessageIds);
|
|
39605
|
-
const endRemap = remapBoundaryId(c3.end_message_id, args.messageIdToLastPiEntryId, args.orderedSourceMessageIds);
|
|
39928
|
+
const startRemap = remapBoundaryId(c3.start_message_id, "start", args.messageIdToFirstPiEntryId, args.messageIdToLastPiEntryId, args.orderedSourceMessageIds);
|
|
39929
|
+
const endRemap = remapBoundaryId(c3.end_message_id, "end", args.messageIdToFirstPiEntryId, args.messageIdToLastPiEntryId, args.orderedSourceMessageIds);
|
|
39606
39930
|
if (!startRemap || !endRemap)
|
|
39607
39931
|
continue;
|
|
39608
39932
|
if (!startRemap.exact || !endRemap.exact)
|
|
@@ -39631,9 +39955,9 @@ function copyMagicContextState(args) {
|
|
|
39631
39955
|
lastCompartmentEndPiEntryId: remappedCompartments.at(-1)?.end_message_id
|
|
39632
39956
|
};
|
|
39633
39957
|
if (args.dryRun) {
|
|
39634
|
-
return { ...result, commit: () => {} };
|
|
39958
|
+
return { ...result, remappedCompartments, commit: () => {} };
|
|
39635
39959
|
}
|
|
39636
|
-
const commit = () => {
|
|
39960
|
+
const commit = (journalKey) => {
|
|
39637
39961
|
const insertCompartment = stmt(args.cortexkitDb, `INSERT INTO compartments (
|
|
39638
39962
|
session_id, sequence, start_message, end_message,
|
|
39639
39963
|
start_message_id, end_message_id, title, content,
|
|
@@ -39645,19 +39969,72 @@ function copyMagicContextState(args) {
|
|
|
39645
39969
|
) VALUES (?, ?, ?, ?, ?, 'pi')`);
|
|
39646
39970
|
args.cortexkitDb.exec("BEGIN IMMEDIATE");
|
|
39647
39971
|
try {
|
|
39972
|
+
stmt(args.cortexkitDb, "DELETE FROM compartments WHERE session_id = ? AND harness = 'pi'").run(args.piSessionId);
|
|
39973
|
+
stmt(args.cortexkitDb, "DELETE FROM session_facts WHERE session_id = ? AND harness = 'pi'").run(args.piSessionId);
|
|
39648
39974
|
for (const c3 of remappedCompartments) {
|
|
39649
39975
|
insertCompartment.run(args.piSessionId, c3.sequence, c3.start_message, c3.end_message, c3.start_message_id, c3.end_message_id, c3.title, c3.content, c3.p1, c3.p2, c3.p3, c3.p4, typeof c3.importance === "number" ? c3.importance : 50, c3.episode_type, c3.legacy, args.now);
|
|
39650
39976
|
}
|
|
39651
39977
|
for (const f2 of sourceFacts) {
|
|
39652
39978
|
insertFact.run(args.piSessionId, f2.category, f2.content, f2.created_at, f2.updated_at);
|
|
39653
39979
|
}
|
|
39980
|
+
if (journalKey !== undefined) {
|
|
39981
|
+
stmt(args.cortexkitDb, "UPDATE migration_pending SET phase = 'db_committed' WHERE migration_key = ?").run(journalKey);
|
|
39982
|
+
}
|
|
39654
39983
|
args.cortexkitDb.exec("COMMIT");
|
|
39655
39984
|
} catch (error51) {
|
|
39656
39985
|
args.cortexkitDb.exec("ROLLBACK");
|
|
39657
39986
|
throw error51;
|
|
39658
39987
|
}
|
|
39659
39988
|
};
|
|
39660
|
-
return { ...result, commit };
|
|
39989
|
+
return { ...result, remappedCompartments, commit };
|
|
39990
|
+
}
|
|
39991
|
+
function derivePiRuntimeOrdinals(entries) {
|
|
39992
|
+
const ordinalByEntryId = new Map;
|
|
39993
|
+
let nextOrdinal = 1;
|
|
39994
|
+
const pendingToolResultIds = [];
|
|
39995
|
+
const foldPendingInto = (ordinal) => {
|
|
39996
|
+
for (const id of pendingToolResultIds)
|
|
39997
|
+
ordinalByEntryId.set(id, ordinal);
|
|
39998
|
+
pendingToolResultIds.length = 0;
|
|
39999
|
+
};
|
|
40000
|
+
for (const entry of entries) {
|
|
40001
|
+
const message = entry.message;
|
|
40002
|
+
if (entry.type !== "message" || typeof entry.id !== "string" || message === null || typeof message !== "object") {
|
|
40003
|
+
continue;
|
|
40004
|
+
}
|
|
40005
|
+
const role = message.role;
|
|
40006
|
+
if (role === "toolResult") {
|
|
40007
|
+
pendingToolResultIds.push(entry.id);
|
|
40008
|
+
continue;
|
|
40009
|
+
}
|
|
40010
|
+
if (role === "assistant" && pendingToolResultIds.length > 0) {
|
|
40011
|
+
foldPendingInto(nextOrdinal);
|
|
40012
|
+
nextOrdinal += 1;
|
|
40013
|
+
}
|
|
40014
|
+
const ordinal = nextOrdinal;
|
|
40015
|
+
nextOrdinal += 1;
|
|
40016
|
+
if (role === "user" && pendingToolResultIds.length > 0) {
|
|
40017
|
+
foldPendingInto(ordinal);
|
|
40018
|
+
}
|
|
40019
|
+
ordinalByEntryId.set(entry.id, ordinal);
|
|
40020
|
+
}
|
|
40021
|
+
if (pendingToolResultIds.length > 0) {
|
|
40022
|
+
foldPendingInto(nextOrdinal);
|
|
40023
|
+
}
|
|
40024
|
+
return ordinalByEntryId;
|
|
40025
|
+
}
|
|
40026
|
+
function applyRuntimeOrdinals(remappedCompartments, entries) {
|
|
40027
|
+
const ordinals = derivePiRuntimeOrdinals(entries);
|
|
40028
|
+
for (const compartment of remappedCompartments) {
|
|
40029
|
+
const startOrdinal = ordinals.get(compartment.start_message_id);
|
|
40030
|
+
const endOrdinal = ordinals.get(compartment.end_message_id);
|
|
40031
|
+
if (startOrdinal === undefined || endOrdinal === undefined) {
|
|
40032
|
+
const missing = startOrdinal === undefined ? compartment.start_message_id : compartment.end_message_id;
|
|
40033
|
+
throw new Error(`Migration boundary entry ${missing} has no runtime ordinal; migrator invariant violated`);
|
|
40034
|
+
}
|
|
40035
|
+
compartment.start_message = startOrdinal;
|
|
40036
|
+
compartment.end_message = endOrdinal;
|
|
40037
|
+
}
|
|
39661
40038
|
}
|
|
39662
40039
|
function ensureValidOptions(opts) {
|
|
39663
40040
|
if (!opts.from)
|
|
@@ -39707,52 +40084,88 @@ function migrateOpenCodeSessionToPi(opts) {
|
|
|
39707
40084
|
const modelId = opts.modelId ?? model.modelId;
|
|
39708
40085
|
const cwd = session.directory ?? session.path ?? process.cwd();
|
|
39709
40086
|
const outputDir = join18(piSessionsRoot, projectPathToPiDirSlug(cwd));
|
|
40087
|
+
const targetHarness = opts.targetHarness ?? "pi";
|
|
40088
|
+
const journalActive = cortexkitDb !== null && !opts.dryRun;
|
|
40089
|
+
let recovery;
|
|
40090
|
+
let migrationKey;
|
|
40091
|
+
let journalResumed = false;
|
|
40092
|
+
let piSessionId;
|
|
40093
|
+
let finalPath;
|
|
40094
|
+
let stagePath;
|
|
40095
|
+
if (journalActive && cortexkitDb !== null) {
|
|
40096
|
+
if (!hasMigrationJournal(cortexkitDb)) {
|
|
40097
|
+
throw new Error("context.db has no migration_pending journal (shared schema older than v78). Run a harness session once so the plugin can upgrade the schema, then retry doctor migrate.");
|
|
40098
|
+
}
|
|
40099
|
+
recovery = sweepPendingMigrations(cortexkitDb, fs3);
|
|
40100
|
+
migrationKey = migrationKeyFor(session.id, targetHarness);
|
|
40101
|
+
const claimed = claimJournalIdentity({
|
|
40102
|
+
db: cortexkitDb,
|
|
40103
|
+
migrationKey,
|
|
40104
|
+
sourceSessionId: session.id,
|
|
40105
|
+
targetHarness,
|
|
40106
|
+
finalPathFor: (id) => join18(outputDir, `${formatPiFilenameTimestamp(now)}_${id}.jsonl`),
|
|
40107
|
+
stageDir: join18(dirname12(piSessionsRoot), MIGRATION_STAGE_DIRNAME),
|
|
40108
|
+
now: now.getTime()
|
|
40109
|
+
});
|
|
40110
|
+
piSessionId = claimed.row.pi_session_id;
|
|
40111
|
+
finalPath = claimed.row.final_path;
|
|
40112
|
+
stagePath = claimed.row.stage_path;
|
|
40113
|
+
journalResumed = claimed.resumed;
|
|
40114
|
+
} else {
|
|
40115
|
+
piSessionId = generateUuidV7(now);
|
|
40116
|
+
finalPath = join18(outputDir, `${formatPiFilenameTimestamp(now)}_${piSessionId}.jsonl`);
|
|
40117
|
+
stagePath = "";
|
|
40118
|
+
}
|
|
39710
40119
|
const buildResult = buildPiEntries({
|
|
39711
40120
|
session,
|
|
39712
40121
|
messages,
|
|
39713
40122
|
parts,
|
|
39714
40123
|
now,
|
|
39715
40124
|
provider,
|
|
39716
|
-
modelId
|
|
40125
|
+
modelId,
|
|
40126
|
+
piSessionId
|
|
39717
40127
|
});
|
|
39718
40128
|
let copyResult = {
|
|
39719
40129
|
compartmentsCopied: 0,
|
|
39720
40130
|
factsCopied: 0,
|
|
39721
40131
|
boundariesApproximated: 0
|
|
39722
40132
|
};
|
|
39723
|
-
let
|
|
40133
|
+
let plan = null;
|
|
39724
40134
|
if (cortexkitDb !== null) {
|
|
39725
|
-
|
|
40135
|
+
plan = copyMagicContextState({
|
|
39726
40136
|
cortexkitDb,
|
|
39727
40137
|
sourceSessionId: session.id,
|
|
39728
|
-
piSessionId
|
|
40138
|
+
piSessionId,
|
|
40139
|
+
messageIdToFirstPiEntryId: buildResult.messageIdToFirstPiEntryId,
|
|
39729
40140
|
messageIdToLastPiEntryId: buildResult.messageIdToLastPiEntryId,
|
|
39730
40141
|
orderedSourceMessageIds: buildResult.orderedSourceMessageIds,
|
|
39731
40142
|
now: now.getTime(),
|
|
39732
40143
|
dryRun: Boolean(opts.dryRun)
|
|
39733
40144
|
});
|
|
39734
40145
|
copyResult = plan;
|
|
39735
|
-
commitMagicContextState = plan.commit;
|
|
39736
40146
|
}
|
|
39737
40147
|
const compactionMarker = insertCompactionMarker(buildResult.entries, copyResult.lastCompartmentEndPiEntryId);
|
|
39738
|
-
|
|
40148
|
+
if (plan)
|
|
40149
|
+
applyRuntimeOrdinals(plan.remappedCompartments, buildResult.entries);
|
|
39739
40150
|
const jsonl = `${buildResult.entries.map((entry) => JSON.stringify(entry)).join(`
|
|
39740
40151
|
`)}
|
|
39741
40152
|
`;
|
|
39742
40153
|
if (!opts.dryRun) {
|
|
39743
|
-
|
|
39744
|
-
|
|
39745
|
-
|
|
39746
|
-
|
|
39747
|
-
|
|
39748
|
-
|
|
39749
|
-
|
|
39750
|
-
|
|
40154
|
+
if (journalActive && cortexkitDb !== null && migrationKey !== undefined && plan) {
|
|
40155
|
+
const contentSha256 = createHash3("sha256").update(jsonl, "utf8").digest("hex");
|
|
40156
|
+
commitStagedChecksum(cortexkitDb, migrationKey, contentSha256);
|
|
40157
|
+
fs3.writeFileAtomic(stagePath, jsonl);
|
|
40158
|
+
plan.commit(migrationKey);
|
|
40159
|
+
fs3.mkdirSync(dirname12(finalPath), { recursive: true });
|
|
40160
|
+
fs3.renameSync(stagePath, finalPath);
|
|
40161
|
+
stmt(cortexkitDb, "DELETE FROM migration_pending WHERE migration_key = ?").run(migrationKey);
|
|
40162
|
+
} else {
|
|
40163
|
+
fs3.writeFileAtomic(finalPath, jsonl);
|
|
39751
40164
|
}
|
|
39752
40165
|
}
|
|
39753
40166
|
return {
|
|
39754
|
-
outputPath,
|
|
39755
|
-
piSessionId
|
|
40167
|
+
outputPath: finalPath,
|
|
40168
|
+
piSessionId,
|
|
39756
40169
|
messageCount: buildResult.entries.length - 2,
|
|
39757
40170
|
byteCount: Buffer.byteLength(jsonl, "utf8"),
|
|
39758
40171
|
sourceMessageCount,
|
|
@@ -39762,6 +40175,9 @@ function migrateOpenCodeSessionToPi(opts) {
|
|
|
39762
40175
|
compactionMarkerWritten: compactionMarker.written,
|
|
39763
40176
|
compactionBoundaryEntryId: compactionMarker.boundaryEntryId,
|
|
39764
40177
|
compactionFirstKeptEntryId: compactionMarker.firstKeptEntryId,
|
|
40178
|
+
...migrationKey !== undefined ? { migrationKey } : {},
|
|
40179
|
+
...journalActive ? { journalResumed } : {},
|
|
40180
|
+
...recovery !== undefined ? { recovery } : {},
|
|
39765
40181
|
...cortexkitSchemaVersionBefore !== null && cortexkitDb !== null ? {
|
|
39766
40182
|
cortexkitSchemaVersionBefore,
|
|
39767
40183
|
cortexkitSchemaVersionAfter: getPersistedSchemaVersion2(cortexkitDb)
|
|
@@ -39828,9 +40244,32 @@ function printMigrateHelp() {
|
|
|
39828
40244
|
- compartments + session_facts are copied to the new Pi session_id;
|
|
39829
40245
|
compartment boundary message IDs are remapped to the corresponding
|
|
39830
40246
|
Pi entry IDs (nearest-at-or-before for boundaries that don't have
|
|
39831
|
-
a direct message-level Pi entry)
|
|
40247
|
+
a direct message-level Pi entry), and compartment start/end ordinals
|
|
40248
|
+
are recomputed in the ordinal basis the Pi runtime reader produces
|
|
40249
|
+
|
|
40250
|
+
Crash safety:
|
|
40251
|
+
- each migration is tracked in the shared DB's migration_pending journal
|
|
40252
|
+
and staged outside the sessions tree; an interrupted run is reconciled
|
|
40253
|
+
by phase on the next 'doctor migrate' or plain 'doctor' run, reusing the
|
|
40254
|
+
original Pi session id instead of minting a second one
|
|
39832
40255
|
`);
|
|
39833
40256
|
}
|
|
40257
|
+
function formatMigrationSweepLines(report) {
|
|
40258
|
+
const lines = [];
|
|
40259
|
+
if (report.rolledForward > 0) {
|
|
40260
|
+
lines.push(`Recovered ${report.rolledForward} interrupted session migration(s) by completing the staged file rename.`);
|
|
40261
|
+
}
|
|
40262
|
+
if (report.rolledBack > 0) {
|
|
40263
|
+
lines.push(`Rolled back ${report.rolledBack} incomplete session migration(s) that never committed shared state.`);
|
|
40264
|
+
}
|
|
40265
|
+
if (report.completed > 0) {
|
|
40266
|
+
lines.push(`Cleared ${report.completed} finished session-migration journal row(s).`);
|
|
40267
|
+
}
|
|
40268
|
+
for (const row of report.lost) {
|
|
40269
|
+
lines.push(`LOST session migration content: source ${row.source_session_id} → ${row.target_harness} session ${row.pi_session_id}; expected file ${row.final_path} (sha256 ${row.content_sha256}). Re-run doctor migrate for this session to rebuild it.`);
|
|
40270
|
+
}
|
|
40271
|
+
return lines;
|
|
40272
|
+
}
|
|
39834
40273
|
async function runMigrateCli(args) {
|
|
39835
40274
|
try {
|
|
39836
40275
|
const parsed = parseMigrateArgs(args);
|
|
@@ -39840,8 +40279,14 @@ async function runMigrateCli(args) {
|
|
|
39840
40279
|
sessionId: parsed.session,
|
|
39841
40280
|
maxMessages: parsed.maxMessages,
|
|
39842
40281
|
dryRun: parsed.dryRun,
|
|
39843
|
-
piSessionsRoot: parsed.to === "omp" ? getOmpSessionsRoot() : undefined
|
|
40282
|
+
piSessionsRoot: parsed.to === "omp" ? getOmpSessionsRoot() : undefined,
|
|
40283
|
+
targetHarness: parsed.to === "omp" ? "omp" : "pi"
|
|
39844
40284
|
});
|
|
40285
|
+
if (result.recovery) {
|
|
40286
|
+
for (const line of formatMigrationSweepLines(result.recovery)) {
|
|
40287
|
+
console.log(line);
|
|
40288
|
+
}
|
|
40289
|
+
}
|
|
39845
40290
|
const action = result.dryRun ? "Would write" : "Wrote";
|
|
39846
40291
|
console.log(`${action} ${target} session JSONL:`);
|
|
39847
40292
|
console.log(` path: ${result.outputPath}`);
|
|
@@ -39858,6 +40303,9 @@ async function runMigrateCli(args) {
|
|
|
39858
40303
|
if (result.boundariesApproximated > 0) {
|
|
39859
40304
|
console.log(` boundaries approximated: ${result.boundariesApproximated} (nearest-at-or-before)`);
|
|
39860
40305
|
}
|
|
40306
|
+
if (result.migrationKey !== undefined) {
|
|
40307
|
+
console.log(` journal: ${result.migrationKey.slice(0, 12)}…${result.journalResumed ? " (resumed interrupted attempt)" : ""}`);
|
|
40308
|
+
}
|
|
39861
40309
|
if (!result.dryRun) {
|
|
39862
40310
|
console.log(`${target} may need to be restarted to pick up the new session file.`);
|
|
39863
40311
|
if (result.cortexkitSchemaVersionBefore !== undefined) {
|
|
@@ -39875,7 +40323,9 @@ async function runMigrateCli(args) {
|
|
|
39875
40323
|
return 1;
|
|
39876
40324
|
}
|
|
39877
40325
|
}
|
|
39878
|
-
var DEFAULT_PROVIDER = "openai-codex", DEFAULT_MODEL = "gpt-5.5", MIGRATION_COMPACTION_SUMMARY = "Magic Context compacted prior conversation. See <session-history> block for the structured summary.", PART_LOOKUP_CHUNK_SIZE = 900
|
|
40326
|
+
var DEFAULT_PROVIDER = "openai-codex", DEFAULT_MODEL = "gpt-5.5", MIGRATION_COMPACTION_SUMMARY = "Magic Context compacted prior conversation. See <session-history> block for the structured summary.", PART_LOOKUP_CHUNK_SIZE = 900, MIGRATION_STAGE_DIRNAME = ".mc-migrations", JOURNAL_SELECT_SQL = `SELECT migration_key, source_session_id, target_harness, pi_session_id,
|
|
40327
|
+
final_path, stage_path, content_sha256, phase, created_at
|
|
40328
|
+
FROM migration_pending WHERE migration_key = ?`;
|
|
39879
40329
|
var init_migrate = __esm(async () => {
|
|
39880
40330
|
init_data_path();
|
|
39881
40331
|
init_atomic_write();
|
|
@@ -39979,15 +40429,72 @@ var exports_migrate_session = {};
|
|
|
39979
40429
|
__export(exports_migrate_session, {
|
|
39980
40430
|
runMigrateSessionCli: () => runMigrateSessionCli,
|
|
39981
40431
|
planMigrateSession: () => planMigrateSession,
|
|
40432
|
+
assertMigrateSessionIsSafeToRehome: () => assertMigrateSessionIsSafeToRehome,
|
|
39982
40433
|
applyMigrateSession: () => applyMigrateSession
|
|
39983
40434
|
});
|
|
39984
|
-
import { existsSync as
|
|
40435
|
+
import { existsSync as existsSync22, realpathSync as realpathSync4 } from "node:fs";
|
|
39985
40436
|
import { homedir as homedir13 } from "node:os";
|
|
39986
40437
|
import path4, { join as join19 } from "node:path";
|
|
39987
40438
|
function existingSessionColumns(db) {
|
|
39988
40439
|
const rows = db.prepare("PRAGMA table_info(session)").all();
|
|
39989
40440
|
return new Set(rows.map((r2) => r2.name).filter((n2) => typeof n2 === "string"));
|
|
39990
40441
|
}
|
|
40442
|
+
function isModuleCacheStatePresent(status) {
|
|
40443
|
+
if (!status || typeof status !== "object")
|
|
40444
|
+
return false;
|
|
40445
|
+
const rowVersion = status.row_version;
|
|
40446
|
+
return typeof rowVersion === "number";
|
|
40447
|
+
}
|
|
40448
|
+
function drainCommandsForMarkers(markers, projects) {
|
|
40449
|
+
const byProject = new Map(projects.map((project) => [project.projectPath, project]));
|
|
40450
|
+
return [
|
|
40451
|
+
...new Set(markers.map((marker) => authorityDrainCommand(byProject.get(marker.project_path) ?? {
|
|
40452
|
+
role: "marked",
|
|
40453
|
+
projectPath: marker.project_path,
|
|
40454
|
+
projectRoot: null
|
|
40455
|
+
})))
|
|
40456
|
+
].join("; ");
|
|
40457
|
+
}
|
|
40458
|
+
async function assertMigrateSessionIsSafeToRehome(args) {
|
|
40459
|
+
const projects = [
|
|
40460
|
+
{
|
|
40461
|
+
role: "source",
|
|
40462
|
+
projectPath: args.plan.fromMcIdentity,
|
|
40463
|
+
projectRoot: args.plan.currentDirectory
|
|
40464
|
+
},
|
|
40465
|
+
{
|
|
40466
|
+
role: "target",
|
|
40467
|
+
projectPath: args.plan.toMcIdentity,
|
|
40468
|
+
projectRoot: args.plan.targetDirectory
|
|
40469
|
+
}
|
|
40470
|
+
];
|
|
40471
|
+
const authority = await assertProjectsUseTsAuthority({
|
|
40472
|
+
db: args.contextDb,
|
|
40473
|
+
projects,
|
|
40474
|
+
module: args.module
|
|
40475
|
+
});
|
|
40476
|
+
let sessionStatus;
|
|
40477
|
+
try {
|
|
40478
|
+
sessionStatus = await args.module.sessionStatus({
|
|
40479
|
+
sessionId: args.plan.sessionId,
|
|
40480
|
+
projectRoot: args.plan.currentDirectory ?? args.plan.targetDirectory
|
|
40481
|
+
});
|
|
40482
|
+
} catch (error51) {
|
|
40483
|
+
const message = error51 instanceof Error ? error51.message : String(error51);
|
|
40484
|
+
if (authority.markers.length === 0) {
|
|
40485
|
+
return {
|
|
40486
|
+
warnings: [
|
|
40487
|
+
`Module session-cache state was not checked because the module is unreachable: ${message}. No durable authority markers exist, so continuing for this pure-TypeScript installation.`
|
|
40488
|
+
]
|
|
40489
|
+
};
|
|
40490
|
+
}
|
|
40491
|
+
throw new Error("Migration refused: module session-cache state is unreachable while durable authority markers exist; writes remain fenced. " + `Drain marked projects first: ${drainCommandsForMarkers(authority.markers, projects)}. ` + `Module error: ${message}`);
|
|
40492
|
+
}
|
|
40493
|
+
if (isModuleCacheStatePresent(sessionStatus)) {
|
|
40494
|
+
throw new Error(`Migration refused: the module still holds transform cache state for session ${args.plan.sessionId}. ` + "Use TypeScript transform mode for the session's project, or run `ck session delete` after preserving any needed state, then re-run this migration.");
|
|
40495
|
+
}
|
|
40496
|
+
return { warnings: [] };
|
|
40497
|
+
}
|
|
39991
40498
|
function planMigrateSession(sessionId, rawTargetDirectory, deps) {
|
|
39992
40499
|
const sessionRow = deps.opencodeDb.prepare("SELECT id, directory FROM session WHERE id = ?").get(sessionId);
|
|
39993
40500
|
if (!sessionRow) {
|
|
@@ -40144,7 +40651,7 @@ function realDeps(opencodeDb, contextDb) {
|
|
|
40144
40651
|
opencodeDb,
|
|
40145
40652
|
contextDb,
|
|
40146
40653
|
resolveIdentity: resolveProjectIdentity,
|
|
40147
|
-
hasGitDir: (dir) =>
|
|
40654
|
+
hasGitDir: (dir) => existsSync22(join19(dir, ".git")),
|
|
40148
40655
|
realpath: (p2) => realpathSync4(p2)
|
|
40149
40656
|
};
|
|
40150
40657
|
}
|
|
@@ -40223,7 +40730,7 @@ async function runMigrateSessionCli(args) {
|
|
|
40223
40730
|
return 1;
|
|
40224
40731
|
}
|
|
40225
40732
|
const expandedTo = toDir.startsWith("~") ? join19(homedir13(), toDir.slice(1).replace(/^[/\\]/, "")) : toDir;
|
|
40226
|
-
if (!
|
|
40733
|
+
if (!existsSync22(expandedTo)) {
|
|
40227
40734
|
console.error(`Target directory does not exist: ${expandedTo}`);
|
|
40228
40735
|
return 1;
|
|
40229
40736
|
}
|
|
@@ -40249,6 +40756,27 @@ async function runMigrateSessionCli(args) {
|
|
|
40249
40756
|
} catch {}
|
|
40250
40757
|
const deps = realDeps(opencodeDb, contextDb);
|
|
40251
40758
|
const plan = planMigrateSession(sessionId, expandedTo, deps);
|
|
40759
|
+
const transport = new SubcModuleTransport;
|
|
40760
|
+
const safety = await assertMigrateSessionIsSafeToRehome({
|
|
40761
|
+
plan,
|
|
40762
|
+
contextDb,
|
|
40763
|
+
module: {
|
|
40764
|
+
authorityStatus: (request) => transport.authorityStatus(request),
|
|
40765
|
+
sessionStatus: ({ sessionId: statusSessionId, projectRoot }) => transport.call({
|
|
40766
|
+
sessionId: statusSessionId,
|
|
40767
|
+
projectRoot,
|
|
40768
|
+
method: "session.status",
|
|
40769
|
+
body: {
|
|
40770
|
+
method: "session.status",
|
|
40771
|
+
v: 1,
|
|
40772
|
+
session_id: statusSessionId
|
|
40773
|
+
}
|
|
40774
|
+
})
|
|
40775
|
+
}
|
|
40776
|
+
});
|
|
40777
|
+
for (const warning of safety.warnings) {
|
|
40778
|
+
promptIO.log.warn(warning);
|
|
40779
|
+
}
|
|
40252
40780
|
promptIO.note([
|
|
40253
40781
|
`session: ${plan.sessionId}`,
|
|
40254
40782
|
`from: ${plan.currentDirectory ?? "(unknown)"}`,
|
|
@@ -40332,10 +40860,14 @@ var init_migrate_session = __esm(async () => {
|
|
|
40332
40860
|
init_project_identity();
|
|
40333
40861
|
init_relocate_memory();
|
|
40334
40862
|
init_storage_project_state();
|
|
40863
|
+
init_module_transport();
|
|
40335
40864
|
init_data_path();
|
|
40336
40865
|
init_migration_paths();
|
|
40337
40866
|
init_prompts();
|
|
40338
|
-
await
|
|
40867
|
+
await __promiseAll([
|
|
40868
|
+
init_database_access(),
|
|
40869
|
+
init_doctor_authority()
|
|
40870
|
+
]);
|
|
40339
40871
|
VALID_MEMORY_ACTIONS = new Set([
|
|
40340
40872
|
"move-all",
|
|
40341
40873
|
"move-originated",
|
|
@@ -40346,7 +40878,7 @@ var init_migrate_session = __esm(async () => {
|
|
|
40346
40878
|
});
|
|
40347
40879
|
|
|
40348
40880
|
// ../plugin/src/features/magic-context/v22-deferred-backfill.ts
|
|
40349
|
-
import { createHash as
|
|
40881
|
+
import { createHash as createHash4 } from "node:crypto";
|
|
40350
40882
|
import { realpathSync as realpathSync5 } from "node:fs";
|
|
40351
40883
|
import path5 from "node:path";
|
|
40352
40884
|
function readMeta(db, key) {
|
|
@@ -40395,7 +40927,7 @@ function computeLegacyRustDirIdentity(rawProjectPath) {
|
|
|
40395
40927
|
} catch {
|
|
40396
40928
|
canonical = path5.isAbsolute(rawProjectPath) ? rawProjectPath : path5.join(process.cwd(), rawProjectPath);
|
|
40397
40929
|
}
|
|
40398
|
-
return `dir:${
|
|
40930
|
+
return `dir:${createHash4("sha256").update(canonical, "utf8").digest("hex")}`;
|
|
40399
40931
|
}
|
|
40400
40932
|
function upsertRekeyMap(db, oldProjectPath, newProjectPath, rekeyedAt) {
|
|
40401
40933
|
db.prepare(`INSERT INTO v22_identity_rekey_map (old_project_path, new_project_path, rekeyed_at)
|
|
@@ -40580,7 +41112,7 @@ var init_v22_backfill_commands = __esm(async () => {
|
|
|
40580
41112
|
});
|
|
40581
41113
|
|
|
40582
41114
|
// ../pi-plugin/src/config/index.ts
|
|
40583
|
-
import { existsSync as
|
|
41115
|
+
import { existsSync as existsSync23, readFileSync as readFileSync14 } from "node:fs";
|
|
40584
41116
|
function getProjectConfigPaths(cwd) {
|
|
40585
41117
|
const basePath = cortexKitProjectConfigBasePath(cwd);
|
|
40586
41118
|
return [`${basePath}.jsonc`, `${basePath}.json`];
|
|
@@ -40590,10 +41122,10 @@ function getUserConfigPaths() {
|
|
|
40590
41122
|
return [`${basePath}.jsonc`, `${basePath}.json`];
|
|
40591
41123
|
}
|
|
40592
41124
|
function resolveFirstExisting(paths) {
|
|
40593
|
-
return paths.find((path6) =>
|
|
41125
|
+
return paths.find((path6) => existsSync23(path6));
|
|
40594
41126
|
}
|
|
40595
41127
|
function resolvePiLegacyFallback(sources) {
|
|
40596
|
-
return sources.find((source) =>
|
|
41128
|
+
return sources.find((source) => existsSync23(source.path)) ?? null;
|
|
40597
41129
|
}
|
|
40598
41130
|
function loadConfigFile(path6, scope) {
|
|
40599
41131
|
try {
|
|
@@ -40750,7 +41282,7 @@ function loadPiConfig(opts = {}) {
|
|
|
40750
41282
|
if (loaded)
|
|
40751
41283
|
loadedFiles.push(loaded);
|
|
40752
41284
|
}
|
|
40753
|
-
const legacyProjectUnmigrated = !projectPath && !projectLegacyFallback && legacySources.project.some((source) =>
|
|
41285
|
+
const legacyProjectUnmigrated = !projectPath && !projectLegacyFallback && legacySources.project.some((source) => existsSync23(source.path));
|
|
40754
41286
|
const userPath = resolveFirstExisting(getUserConfigPaths());
|
|
40755
41287
|
const userLegacyFallback = userPath ? null : resolvePiLegacyFallback(harnessLegacy.user);
|
|
40756
41288
|
const userReadPath = userPath ?? userLegacyFallback?.path;
|
|
@@ -40759,7 +41291,7 @@ function loadPiConfig(opts = {}) {
|
|
|
40759
41291
|
if (loaded)
|
|
40760
41292
|
loadedFiles.push(loaded);
|
|
40761
41293
|
}
|
|
40762
|
-
const legacyUserUnmigrated = !userPath && !userLegacyFallback && legacySources.user.some((source) =>
|
|
41294
|
+
const legacyUserUnmigrated = !userPath && !userLegacyFallback && legacySources.user.some((source) => existsSync23(source.path));
|
|
40763
41295
|
if (userLegacyFallback) {
|
|
40764
41296
|
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.`);
|
|
40765
41297
|
} else if (legacyUserUnmigrated) {
|
|
@@ -40803,6 +41335,7 @@ function loadPiConfig(opts = {}) {
|
|
|
40803
41335
|
}
|
|
40804
41336
|
const parsed = parsePiConfig(rawConfig);
|
|
40805
41337
|
setOutputReserveConfig(parsed.config.output_reserve);
|
|
41338
|
+
setWindowOverlayPath(parsed.config.models?.window_overlay_path);
|
|
40806
41339
|
warnings.push(...parsed.warnings.map((warning) => `[merged config] ${warning}`));
|
|
40807
41340
|
return {
|
|
40808
41341
|
config: parsed.config,
|
|
@@ -40821,6 +41354,7 @@ var init_config2 = __esm(() => {
|
|
|
40821
41354
|
init_variable();
|
|
40822
41355
|
init_jsonc_parser();
|
|
40823
41356
|
init_models_dev_cache();
|
|
41357
|
+
init_window_geometry();
|
|
40824
41358
|
import_comment_json7 = __toESM(require_src3(), 1);
|
|
40825
41359
|
});
|
|
40826
41360
|
|
|
@@ -41040,9 +41574,9 @@ var init_redaction2 = __esm(() => {
|
|
|
41040
41574
|
|
|
41041
41575
|
// src/commands/doctor-omp.ts
|
|
41042
41576
|
import { execFileSync as execFileSync5, spawnSync as spawnSync4 } from "node:child_process";
|
|
41043
|
-
import { existsSync as
|
|
41577
|
+
import { existsSync as existsSync24, mkdirSync as mkdirSync9, readFileSync as readFileSync15 } from "node:fs";
|
|
41044
41578
|
import { createRequire as createRequire2 } from "node:module";
|
|
41045
|
-
import { dirname as
|
|
41579
|
+
import { dirname as dirname13, join as join20, resolve as resolve5 } from "node:path";
|
|
41046
41580
|
function parseSemver(value) {
|
|
41047
41581
|
const match = value?.match(/(\d+)\.(\d+)\.(\d+)/);
|
|
41048
41582
|
return match ? [Number(match[1]), Number(match[2]), Number(match[3])] : null;
|
|
@@ -41084,7 +41618,7 @@ function selfVersion() {
|
|
|
41084
41618
|
return "unknown";
|
|
41085
41619
|
}
|
|
41086
41620
|
function readConfig2(path6) {
|
|
41087
|
-
if (!
|
|
41621
|
+
if (!existsSync24(path6))
|
|
41088
41622
|
return {};
|
|
41089
41623
|
try {
|
|
41090
41624
|
const parsed = import_comment_json8.parse(readFileSync15(path6, "utf-8"));
|
|
@@ -41178,7 +41712,7 @@ async function runHealthChecks(options) {
|
|
|
41178
41712
|
}
|
|
41179
41713
|
}
|
|
41180
41714
|
const userConfigPath = getOmpUserConfigPath();
|
|
41181
|
-
if (!
|
|
41715
|
+
if (!existsSync24(userConfigPath)) {
|
|
41182
41716
|
add(results, "warn", `No Magic Context user config at ${userConfigPath}`);
|
|
41183
41717
|
repairPlan.writeUserConfig = true;
|
|
41184
41718
|
} else {
|
|
@@ -41195,7 +41729,7 @@ async function runHealthChecks(options) {
|
|
|
41195
41729
|
for (const warning of loaded.warnings.slice(0, 5))
|
|
41196
41730
|
add(results, "warn", warning);
|
|
41197
41731
|
const dbPath = join20(getMagicContextStorageDir(), "context.db");
|
|
41198
|
-
if (!
|
|
41732
|
+
if (!existsSync24(dbPath))
|
|
41199
41733
|
add(results, "info", `Shared context DB will be created at ${dbPath}`);
|
|
41200
41734
|
else {
|
|
41201
41735
|
let db = null;
|
|
@@ -41224,7 +41758,7 @@ ${formatDatabaseRepairGuidance(dbPath)}`);
|
|
|
41224
41758
|
add(results, "info", `OMP non-global config: ${source}`);
|
|
41225
41759
|
}
|
|
41226
41760
|
const logPath = getMagicContextLogPath2("pi");
|
|
41227
|
-
add(results, "info", `Pi-compatible runtime log: ${logPath}${
|
|
41761
|
+
add(results, "info", `Pi-compatible runtime log: ${logPath}${existsSync24(logPath) ? "" : " (not created yet)"}`);
|
|
41228
41762
|
if (!options.quiet)
|
|
41229
41763
|
for (const result of results)
|
|
41230
41764
|
printResult(options.prompts, result);
|
|
@@ -41237,7 +41771,7 @@ ${formatDatabaseRepairGuidance(dbPath)}`);
|
|
|
41237
41771
|
};
|
|
41238
41772
|
}
|
|
41239
41773
|
function writeDefaultConfig(path6) {
|
|
41240
|
-
|
|
41774
|
+
mkdirSync9(dirname13(path6), { recursive: true });
|
|
41241
41775
|
const config2 = {
|
|
41242
41776
|
$schema: "https://raw.githubusercontent.com/cortexkit/magic-context/master/assets/magic-context.schema.json",
|
|
41243
41777
|
...MagicContextConfigSchema.parse({})
|
|
@@ -41247,7 +41781,7 @@ function writeDefaultConfig(path6) {
|
|
|
41247
41781
|
}
|
|
41248
41782
|
async function repair(plan, deps, prompts, cwd) {
|
|
41249
41783
|
let fixed = 0;
|
|
41250
|
-
if (plan.writeUserConfig && !
|
|
41784
|
+
if (plan.writeUserConfig && !existsSync24(getOmpUserConfigPath())) {
|
|
41251
41785
|
writeDefaultConfig(getOmpUserConfigPath());
|
|
41252
41786
|
prompts.log.success(`Wrote default Magic Context config to ${getOmpUserConfigPath()}`);
|
|
41253
41787
|
fixed += 1;
|
|
@@ -41510,14 +42044,14 @@ var DEFAULT_TIMEOUT_MS = 1e4, MAX_PREVIEW_CHARS = 240;
|
|
|
41510
42044
|
// ../plugin/src/shared/tui-config.ts
|
|
41511
42045
|
import {
|
|
41512
42046
|
chmodSync as chmodSync4,
|
|
41513
|
-
existsSync as
|
|
41514
|
-
mkdirSync as
|
|
42047
|
+
existsSync as existsSync25,
|
|
42048
|
+
mkdirSync as mkdirSync10,
|
|
41515
42049
|
readFileSync as readFileSync16,
|
|
41516
|
-
renameSync as
|
|
42050
|
+
renameSync as renameSync5,
|
|
41517
42051
|
statSync as statSync9,
|
|
41518
42052
|
writeFileSync as writeFileSync6
|
|
41519
42053
|
} from "node:fs";
|
|
41520
|
-
import { dirname as
|
|
42054
|
+
import { dirname as dirname14, join as join21 } from "node:path";
|
|
41521
42055
|
function pluginEntryId(entry) {
|
|
41522
42056
|
if (typeof entry === "string")
|
|
41523
42057
|
return entry;
|
|
@@ -41554,15 +42088,15 @@ function writeTuiConfigAtomic(configPath, config2) {
|
|
|
41554
42088
|
chmodSync4(tmpPath, statSync9(configPath).mode & 511);
|
|
41555
42089
|
}
|
|
41556
42090
|
} catch {}
|
|
41557
|
-
|
|
42091
|
+
renameSync5(tmpPath, configPath);
|
|
41558
42092
|
}
|
|
41559
42093
|
function resolveTuiConfigPath(configDirOverride) {
|
|
41560
42094
|
const configDir = configDirOverride ?? getOpenCodeConfigPaths({ binary: "opencode" }).configDir;
|
|
41561
42095
|
const jsoncPath = join21(configDir, "tui.jsonc");
|
|
41562
42096
|
const jsonPath = join21(configDir, "tui.json");
|
|
41563
|
-
if (
|
|
42097
|
+
if (existsSync25(jsoncPath))
|
|
41564
42098
|
return jsoncPath;
|
|
41565
|
-
if (
|
|
42099
|
+
if (existsSync25(jsonPath))
|
|
41566
42100
|
return jsonPath;
|
|
41567
42101
|
return jsoncPath;
|
|
41568
42102
|
}
|
|
@@ -41570,7 +42104,7 @@ function ensureTuiPluginEntry(options = {}) {
|
|
|
41570
42104
|
try {
|
|
41571
42105
|
const configPath = resolveTuiConfigPath(options.configDir);
|
|
41572
42106
|
let config2 = {};
|
|
41573
|
-
if (
|
|
42107
|
+
if (existsSync25(configPath)) {
|
|
41574
42108
|
const raw = readFileSync16(configPath, "utf-8");
|
|
41575
42109
|
config2 = import_comment_json9.parse(raw) ?? {};
|
|
41576
42110
|
}
|
|
@@ -41605,7 +42139,7 @@ function ensureTuiPluginEntry(options = {}) {
|
|
|
41605
42139
|
}
|
|
41606
42140
|
}
|
|
41607
42141
|
config2.plugin = plugins;
|
|
41608
|
-
|
|
42142
|
+
mkdirSync10(dirname14(configPath), { recursive: true });
|
|
41609
42143
|
writeTuiConfigAtomic(configPath, config2);
|
|
41610
42144
|
log3(`[magic-context] updated TUI plugin entry in ${configPath}`);
|
|
41611
42145
|
return true;
|
|
@@ -41623,7 +42157,7 @@ var init_tui_config = __esm(() => {
|
|
|
41623
42157
|
});
|
|
41624
42158
|
|
|
41625
42159
|
// src/lib/diagnostics-opencode.ts
|
|
41626
|
-
import { existsSync as
|
|
42160
|
+
import { existsSync as existsSync26, readdirSync as readdirSync3, readFileSync as readFileSync17, statSync as statSync10 } from "node:fs";
|
|
41627
42161
|
import { createRequire as createRequire3 } from "node:module";
|
|
41628
42162
|
import { homedir as homedir15 } from "node:os";
|
|
41629
42163
|
import { join as join22 } from "node:path";
|
|
@@ -41644,7 +42178,7 @@ function getPluginCacheInfo() {
|
|
|
41644
42178
|
let cached2;
|
|
41645
42179
|
for (const installedPkgPath of getOpenCodePluginPackageJsonPaths()) {
|
|
41646
42180
|
try {
|
|
41647
|
-
if (
|
|
42181
|
+
if (existsSync26(installedPkgPath)) {
|
|
41648
42182
|
const pkg = JSON.parse(readFileSync17(installedPkgPath, "utf-8"));
|
|
41649
42183
|
cached2 = typeof pkg.version === "string" ? pkg.version : undefined;
|
|
41650
42184
|
if (cached2)
|
|
@@ -41662,7 +42196,7 @@ function getStorageDir() {
|
|
|
41662
42196
|
}
|
|
41663
42197
|
function fileSize(path6) {
|
|
41664
42198
|
try {
|
|
41665
|
-
return
|
|
42199
|
+
return existsSync26(path6) ? statSync10(path6).size : 0;
|
|
41666
42200
|
} catch {
|
|
41667
42201
|
return 0;
|
|
41668
42202
|
}
|
|
@@ -41674,7 +42208,7 @@ function sanitizeValue(value) {
|
|
|
41674
42208
|
return sanitizeConfigValue(value);
|
|
41675
42209
|
}
|
|
41676
42210
|
function readConfig3(path6) {
|
|
41677
|
-
if (!
|
|
42211
|
+
if (!existsSync26(path6))
|
|
41678
42212
|
return { value: null };
|
|
41679
42213
|
try {
|
|
41680
42214
|
const raw = readFileSync17(path6, "utf-8");
|
|
@@ -41735,7 +42269,7 @@ function parseHistorianDumpMeta(path6) {
|
|
|
41735
42269
|
}
|
|
41736
42270
|
}
|
|
41737
42271
|
function listDumpsInDir(dir, limit) {
|
|
41738
|
-
if (!
|
|
42272
|
+
if (!existsSync26(dir))
|
|
41739
42273
|
return { count: 0, recent: [] };
|
|
41740
42274
|
try {
|
|
41741
42275
|
const entries = readdirSync3(dir).filter((name) => name.endsWith(".xml")).map((name) => {
|
|
@@ -41805,7 +42339,7 @@ function collectHistorianDumps(recentSessions) {
|
|
|
41805
42339
|
async function collectRecentSessions() {
|
|
41806
42340
|
const dataHome = process.env.XDG_DATA_HOME || join22(process.env.HOME || homedir15(), ".local", "share");
|
|
41807
42341
|
const opencodeDbPath = join22(dataHome, "opencode", "opencode.db");
|
|
41808
|
-
if (!
|
|
42342
|
+
if (!existsSync26(opencodeDbPath))
|
|
41809
42343
|
return [];
|
|
41810
42344
|
if (typeof globalThis.Bun === "undefined") {
|
|
41811
42345
|
return [];
|
|
@@ -41840,7 +42374,7 @@ async function collectRecentSessions() {
|
|
|
41840
42374
|
}
|
|
41841
42375
|
async function collectHistorianFailures(storageDirPath) {
|
|
41842
42376
|
const contextDbPath = join22(storageDirPath, "context.db");
|
|
41843
|
-
if (!
|
|
42377
|
+
if (!existsSync26(contextDbPath))
|
|
41844
42378
|
return [];
|
|
41845
42379
|
if (typeof globalThis.Bun === "undefined") {
|
|
41846
42380
|
return [];
|
|
@@ -41874,7 +42408,7 @@ async function collectHistorianFailures(storageDirPath) {
|
|
|
41874
42408
|
}
|
|
41875
42409
|
async function collectHistorianRuns(storageDirPath) {
|
|
41876
42410
|
const contextDbPath = join22(storageDirPath, "context.db");
|
|
41877
|
-
if (!
|
|
42411
|
+
if (!existsSync26(contextDbPath))
|
|
41878
42412
|
return [];
|
|
41879
42413
|
if (typeof globalThis.Bun === "undefined")
|
|
41880
42414
|
return [];
|
|
@@ -41945,7 +42479,7 @@ async function collectDiagnostics() {
|
|
|
41945
42479
|
const storageDirPath = getStorageDir();
|
|
41946
42480
|
const contextDbPath = join22(storageDirPath, "context.db");
|
|
41947
42481
|
const logPath = getMagicContextLogPath2("opencode");
|
|
41948
|
-
const logFileSize =
|
|
42482
|
+
const logFileSize = existsSync26(logPath) ? statSync10(logPath).size : 0;
|
|
41949
42483
|
let compactionEnabled = false;
|
|
41950
42484
|
try {
|
|
41951
42485
|
compactionEnabled = isCompactionEnabled(loadPluginConfig(process.cwd()));
|
|
@@ -41973,14 +42507,14 @@ async function collectDiagnostics() {
|
|
|
41973
42507
|
opencodeConfigHasPlugin: configHasPluginEntry(opencodeConfig.value),
|
|
41974
42508
|
tuiConfigHasPlugin: configHasPluginEntry(tuiConfig.value),
|
|
41975
42509
|
magicContextConfig: {
|
|
41976
|
-
exists:
|
|
42510
|
+
exists: existsSync26(configPaths.magicContextConfig),
|
|
41977
42511
|
...magicContextConfig.error ? { parseError: magicContextConfig.error } : {},
|
|
41978
42512
|
flags: sanitizeValue(magicContextConfig.value ?? {}) ?? {}
|
|
41979
42513
|
},
|
|
41980
42514
|
pluginCache: getPluginCacheInfo(),
|
|
41981
42515
|
storageDir: {
|
|
41982
42516
|
path: storageDirPath,
|
|
41983
|
-
exists:
|
|
42517
|
+
exists: existsSync26(storageDirPath),
|
|
41984
42518
|
contextDbSizeBytes: fileSize(contextDbPath)
|
|
41985
42519
|
},
|
|
41986
42520
|
conflicts: {
|
|
@@ -41991,7 +42525,7 @@ async function collectDiagnostics() {
|
|
|
41991
42525
|
},
|
|
41992
42526
|
logFile: {
|
|
41993
42527
|
path: logPath,
|
|
41994
|
-
exists:
|
|
42528
|
+
exists: existsSync26(logPath),
|
|
41995
42529
|
sizeKb: Math.round(logFileSize / 1024)
|
|
41996
42530
|
},
|
|
41997
42531
|
recentSessions,
|
|
@@ -42144,9 +42678,9 @@ var init_diagnostics_opencode = __esm(() => {
|
|
|
42144
42678
|
|
|
42145
42679
|
// src/lib/embedding-runtime.ts
|
|
42146
42680
|
import { spawnSync as spawnSync5 } from "node:child_process";
|
|
42147
|
-
import { existsSync as
|
|
42681
|
+
import { existsSync as existsSync27 } from "node:fs";
|
|
42148
42682
|
import { createRequire as createRequire4 } from "node:module";
|
|
42149
|
-
import { dirname as
|
|
42683
|
+
import { dirname as dirname15, join as join23, sep } from "node:path";
|
|
42150
42684
|
function describeError(error51) {
|
|
42151
42685
|
const message = error51 instanceof Error ? error51.message : String(error51 ?? "unknown error");
|
|
42152
42686
|
const code = error51?.code;
|
|
@@ -42259,7 +42793,7 @@ function expectedBinaryRelPath(platform, arch) {
|
|
|
42259
42793
|
}
|
|
42260
42794
|
function checkLocalEmbeddingRuntimeAt(installRoot, platform = process.platform, arch = process.arch) {
|
|
42261
42795
|
const packageDir = join23(installRoot, "node_modules", "onnxruntime-node");
|
|
42262
|
-
if (!
|
|
42796
|
+
if (!existsSync27(join23(packageDir, "package.json"))) {
|
|
42263
42797
|
return { state: "package-missing", packageDir };
|
|
42264
42798
|
}
|
|
42265
42799
|
const rel = expectedBinaryRelPath(platform, arch);
|
|
@@ -42267,13 +42801,13 @@ function checkLocalEmbeddingRuntimeAt(installRoot, platform = process.platform,
|
|
|
42267
42801
|
return probeOnnxRuntimeNodeLoad(packageDir) ?? { state: "ok", binaryPath: packageDir };
|
|
42268
42802
|
}
|
|
42269
42803
|
const binaryPath = join23(packageDir, rel);
|
|
42270
|
-
if (!
|
|
42804
|
+
if (!existsSync27(binaryPath)) {
|
|
42271
42805
|
return { state: "binary-missing", packageDir, expectedBinary: binaryPath };
|
|
42272
42806
|
}
|
|
42273
42807
|
return probeOnnxRuntimeNodeLoad(packageDir) ?? { state: "ok", binaryPath };
|
|
42274
42808
|
}
|
|
42275
42809
|
function checkLocalEmbeddingRuntime(installRoots, platform = process.platform, arch = process.arch) {
|
|
42276
|
-
const existing = installRoots.filter((root) =>
|
|
42810
|
+
const existing = installRoots.filter((root) => existsSync27(root));
|
|
42277
42811
|
if (existing.length === 0) {
|
|
42278
42812
|
return {
|
|
42279
42813
|
state: "unknown",
|
|
@@ -42293,10 +42827,10 @@ function checkLocalEmbeddingRuntime(installRoots, platform = process.platform, a
|
|
|
42293
42827
|
function packageDirFromResolved(resolvedPath, packageName) {
|
|
42294
42828
|
const marker = `node_modules${sep}${packageName.split("/").join(sep)}`;
|
|
42295
42829
|
const idx = resolvedPath.indexOf(marker);
|
|
42296
|
-
return idx >= 0 ? resolvedPath.slice(0, idx + marker.length) :
|
|
42830
|
+
return idx >= 0 ? resolvedPath.slice(0, idx + marker.length) : dirname15(resolvedPath);
|
|
42297
42831
|
}
|
|
42298
42832
|
function checkLocalEmbeddingRuntimeByResolution(pluginDir, platform = process.platform, arch = process.arch) {
|
|
42299
|
-
if (!
|
|
42833
|
+
if (!existsSync27(join23(pluginDir, "package.json"))) {
|
|
42300
42834
|
return { state: "unknown", reason: "plugin package dir not found" };
|
|
42301
42835
|
}
|
|
42302
42836
|
let onnxDir = null;
|
|
@@ -42332,7 +42866,7 @@ function checkLocalEmbeddingRuntimeByResolution(pluginDir, platform = process.pl
|
|
|
42332
42866
|
return probeOnnxRuntimeNodeLoad(onnxDir) ?? { state: "ok", binaryPath: onnxDir };
|
|
42333
42867
|
}
|
|
42334
42868
|
const binaryPath = join23(onnxDir, rel);
|
|
42335
|
-
if (!
|
|
42869
|
+
if (!existsSync27(binaryPath)) {
|
|
42336
42870
|
return { state: "binary-missing", packageDir: onnxDir, expectedBinary: binaryPath };
|
|
42337
42871
|
}
|
|
42338
42872
|
return probeOnnxRuntimeNodeLoad(onnxDir) ?? { state: "ok", binaryPath };
|
|
@@ -42927,11 +43461,11 @@ var init_storage_versions = __esm(async () => {
|
|
|
42927
43461
|
});
|
|
42928
43462
|
|
|
42929
43463
|
// src/commands/doctor-opencode-cache.ts
|
|
42930
|
-
import { existsSync as
|
|
43464
|
+
import { existsSync as existsSync28, readFileSync as readFileSync19, rmSync as rmSync3 } from "node:fs";
|
|
42931
43465
|
function readCachedPluginVersion(pluginCacheDir) {
|
|
42932
43466
|
try {
|
|
42933
43467
|
const installedPkgPath = getOpenCodePluginPackageJsonPath(pluginCacheDir);
|
|
42934
|
-
if (!
|
|
43468
|
+
if (!existsSync28(installedPkgPath))
|
|
42935
43469
|
return;
|
|
42936
43470
|
const pkg = JSON.parse(readFileSync19(installedPkgPath, "utf-8"));
|
|
42937
43471
|
return typeof pkg.version === "string" ? pkg.version : undefined;
|
|
@@ -42942,7 +43476,7 @@ function readCachedPluginVersion(pluginCacheDir) {
|
|
|
42942
43476
|
async function clearPluginCache(options = {}, deps = {}) {
|
|
42943
43477
|
const remove = deps.remove ?? ((path6) => rmSync3(path6, { recursive: true, force: true }));
|
|
42944
43478
|
const pluginCacheRoots = getOpenCodePluginCacheRoots();
|
|
42945
|
-
const existingRoots = pluginCacheRoots.filter((root) =>
|
|
43479
|
+
const existingRoots = pluginCacheRoots.filter((root) => existsSync28(root));
|
|
42946
43480
|
if (existingRoots.length === 0) {
|
|
42947
43481
|
return { action: "not_found", path: pluginCacheRoots[0] ?? "" };
|
|
42948
43482
|
}
|
|
@@ -43010,7 +43544,7 @@ var init_doctor_opencode_cache = __esm(() => {
|
|
|
43010
43544
|
|
|
43011
43545
|
// src/commands/doctor-opencode.ts
|
|
43012
43546
|
import { execSync as execSync2, spawnSync as spawnSync6 } from "node:child_process";
|
|
43013
|
-
import { existsSync as
|
|
43547
|
+
import { existsSync as existsSync29, readFileSync as readFileSync20, statSync as statSync11 } from "node:fs";
|
|
43014
43548
|
import { createRequire as createRequire5 } from "node:module";
|
|
43015
43549
|
import { homedir as homedir16 } from "node:os";
|
|
43016
43550
|
import { join as join25 } from "node:path";
|
|
@@ -43117,7 +43651,7 @@ function getUserNpmrcPath() {
|
|
|
43117
43651
|
function collectNpmReleaseAgeWarnings() {
|
|
43118
43652
|
const ageWarnings = [];
|
|
43119
43653
|
const npmrcPath = getUserNpmrcPath();
|
|
43120
|
-
if (!
|
|
43654
|
+
if (!existsSync29(npmrcPath))
|
|
43121
43655
|
return ageWarnings;
|
|
43122
43656
|
try {
|
|
43123
43657
|
const npmrc = readFileSync20(npmrcPath, "utf-8");
|
|
@@ -43259,7 +43793,7 @@ function checkLocalEmbeddingRuntimeForDoctor() {
|
|
|
43259
43793
|
return { issues: 0 };
|
|
43260
43794
|
}
|
|
43261
43795
|
async function checkEmbeddingConfig(magicContextConfigPath) {
|
|
43262
|
-
if (!
|
|
43796
|
+
if (!existsSync29(magicContextConfigPath)) {
|
|
43263
43797
|
return checkLocalEmbeddingRuntimeForDoctor();
|
|
43264
43798
|
}
|
|
43265
43799
|
let rawText;
|
|
@@ -43470,7 +44004,7 @@ async function runDoctor2(options = {}) {
|
|
|
43470
44004
|
} else {
|
|
43471
44005
|
pass(`OpenCode config: ${paths.opencodeConfig}`);
|
|
43472
44006
|
}
|
|
43473
|
-
if (
|
|
44007
|
+
if (existsSync29(paths.magicContextConfig)) {
|
|
43474
44008
|
pass(`Magic Context config: ${paths.magicContextConfig}`);
|
|
43475
44009
|
try {
|
|
43476
44010
|
const raw = readFileSync20(paths.magicContextConfig, "utf-8");
|
|
@@ -43498,7 +44032,7 @@ async function runDoctor2(options = {}) {
|
|
|
43498
44032
|
warn(`No magic-context.jsonc found — using defaults`);
|
|
43499
44033
|
log2.info(" Run 'setup' to create one with model recommendations");
|
|
43500
44034
|
}
|
|
43501
|
-
if (
|
|
44035
|
+
if (existsSync29(paths.magicContextConfig)) {
|
|
43502
44036
|
try {
|
|
43503
44037
|
const mcRaw = readFileSync20(paths.magicContextConfig, "utf-8");
|
|
43504
44038
|
const mcConfig = import_comment_json11.parse(mcRaw);
|
|
@@ -43674,6 +44208,7 @@ async function runDoctor2(options = {}) {
|
|
|
43674
44208
|
const cwd = process.cwd();
|
|
43675
44209
|
const compactionEnabled = resolveCompactionEnabledForDoctor();
|
|
43676
44210
|
const conflictResult = detectConflicts(cwd, { compactionEnabled });
|
|
44211
|
+
log2.info("Compaction check: file-based; the running server's resolved config may differ — `opencode debug config` is authoritative");
|
|
43677
44212
|
if (conflictResult.hasConflict) {
|
|
43678
44213
|
for (const reason of conflictResult.reasons) {
|
|
43679
44214
|
fail(`Conflict: ${reason}`);
|
|
@@ -43702,7 +44237,7 @@ async function runDoctor2(options = {}) {
|
|
|
43702
44237
|
pass("Added TUI sidebar plugin to tui.json");
|
|
43703
44238
|
warn("Restart OpenCode to see the sidebar");
|
|
43704
44239
|
fixed++;
|
|
43705
|
-
} else if (
|
|
44240
|
+
} else if (existsSync29(paths.tuiConfig)) {
|
|
43706
44241
|
try {
|
|
43707
44242
|
const tuiRaw = readFileSync20(paths.tuiConfig, "utf-8");
|
|
43708
44243
|
const tuiConfig = import_comment_json11.parse(tuiRaw);
|
|
@@ -43753,7 +44288,7 @@ async function runDoctor2(options = {}) {
|
|
|
43753
44288
|
} else {
|
|
43754
44289
|
fail("Could not create or verify the TUI sidebar config");
|
|
43755
44290
|
}
|
|
43756
|
-
if (
|
|
44291
|
+
if (existsSync29(paths.magicContextConfig)) {
|
|
43757
44292
|
try {
|
|
43758
44293
|
const mcRaw = readFileSync20(paths.magicContextConfig, "utf-8");
|
|
43759
44294
|
const mcConfig = import_comment_json11.parse(mcRaw);
|
|
@@ -43773,7 +44308,7 @@ async function runDoctor2(options = {}) {
|
|
|
43773
44308
|
else
|
|
43774
44309
|
passCount++;
|
|
43775
44310
|
const dbPath = join25(getMagicContextStorageDir(), "context.db");
|
|
43776
|
-
if (!
|
|
44311
|
+
if (!existsSync29(dbPath)) {
|
|
43777
44312
|
log2.info(`Shared context DB not yet created at ${dbPath} (will be created on first run)`);
|
|
43778
44313
|
} else {
|
|
43779
44314
|
log2.info(`Shared context DB exists at ${dbPath}`);
|
|
@@ -43880,7 +44415,7 @@ ${formatDatabaseRepairGuidance(dbPath)}`);
|
|
|
43880
44415
|
}
|
|
43881
44416
|
}
|
|
43882
44417
|
const logPath = getMagicContextLogPath2("opencode");
|
|
43883
|
-
if (
|
|
44418
|
+
if (existsSync29(logPath)) {
|
|
43884
44419
|
const logStat = statSync11(logPath);
|
|
43885
44420
|
const sizeKb = (logStat.size / 1024).toFixed(0);
|
|
43886
44421
|
log2.info(`Log file: ${logPath} (${sizeKb} KB)`);
|
|
@@ -43960,8 +44495,8 @@ var init_doctor_opencode = __esm(async () => {
|
|
|
43960
44495
|
});
|
|
43961
44496
|
|
|
43962
44497
|
// src/lib/diagnostics-pi.ts
|
|
43963
|
-
import { createHash as
|
|
43964
|
-
import { existsSync as
|
|
44498
|
+
import { createHash as createHash5 } from "node:crypto";
|
|
44499
|
+
import { existsSync as existsSync30, readdirSync as readdirSync4, readFileSync as readFileSync21, statSync as statSync12 } from "node:fs";
|
|
43965
44500
|
import { createRequire as createRequire6 } from "node:module";
|
|
43966
44501
|
import { homedir as homedir17, userInfo as userInfo2 } from "node:os";
|
|
43967
44502
|
import { join as join26 } from "node:path";
|
|
@@ -43979,7 +44514,7 @@ function getSelfVersion3() {
|
|
|
43979
44514
|
}
|
|
43980
44515
|
function fileSize2(path6) {
|
|
43981
44516
|
try {
|
|
43982
|
-
return
|
|
44517
|
+
return existsSync30(path6) ? statSync12(path6).size : 0;
|
|
43983
44518
|
} catch {
|
|
43984
44519
|
return 0;
|
|
43985
44520
|
}
|
|
@@ -43989,7 +44524,7 @@ function escapeRegex3(value) {
|
|
|
43989
44524
|
}
|
|
43990
44525
|
function currentUserHash() {
|
|
43991
44526
|
const username = userInfo2().username || "unknown";
|
|
43992
|
-
return
|
|
44527
|
+
return createHash5("sha256").update(username).digest("hex").slice(0, 12);
|
|
43993
44528
|
}
|
|
43994
44529
|
function redactSecretString(value) {
|
|
43995
44530
|
return redactSecretText(value).replace(/Bearer\s+[A-Za-z0-9._~+\-/=]+/g, "Bearer <REDACTED>").replace(/sk-[A-Za-z0-9_-]{12,}/g, "sk-<REDACTED>").replace(/api[_-]?key=([^\s&]+)/gi, "api_key=<REDACTED>").replace(/token=([^\s&]+)/gi, "token=<REDACTED>");
|
|
@@ -44031,7 +44566,7 @@ function sanitizeValue2(value, key = "") {
|
|
|
44031
44566
|
return value;
|
|
44032
44567
|
}
|
|
44033
44568
|
function readJsonc(path6) {
|
|
44034
|
-
if (!
|
|
44569
|
+
if (!existsSync30(path6))
|
|
44035
44570
|
return { value: {} };
|
|
44036
44571
|
try {
|
|
44037
44572
|
return {
|
|
@@ -44051,7 +44586,7 @@ function readConfigDiagnostic(path6) {
|
|
|
44051
44586
|
const parsed = readJsonc(path6);
|
|
44052
44587
|
return {
|
|
44053
44588
|
path: path6,
|
|
44054
|
-
exists:
|
|
44589
|
+
exists: existsSync30(path6),
|
|
44055
44590
|
...parsed.parseError ? { parseError: parsed.parseError } : {},
|
|
44056
44591
|
flags: sanitizeValue2(parsed.value)
|
|
44057
44592
|
};
|
|
@@ -44069,7 +44604,7 @@ function reverseSlugToDirectory(slug) {
|
|
|
44069
44604
|
}
|
|
44070
44605
|
function collectPiRecentSessions() {
|
|
44071
44606
|
const sessionsRoot = getPiSessionsRoot();
|
|
44072
|
-
if (!
|
|
44607
|
+
if (!existsSync30(sessionsRoot))
|
|
44073
44608
|
return [];
|
|
44074
44609
|
try {
|
|
44075
44610
|
const slugs = readdirSync4(sessionsRoot, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name);
|
|
@@ -44138,7 +44673,7 @@ function parseHistorianDumpMeta2(path6) {
|
|
|
44138
44673
|
}
|
|
44139
44674
|
}
|
|
44140
44675
|
function listDumpsInDir2(dir, limit) {
|
|
44141
|
-
if (!
|
|
44676
|
+
if (!existsSync30(dir))
|
|
44142
44677
|
return { count: 0, recent: [] };
|
|
44143
44678
|
try {
|
|
44144
44679
|
const entries = readdirSync4(dir).filter((name) => name.endsWith(".xml")).map((name) => {
|
|
@@ -44216,7 +44751,7 @@ async function collectDiagnostics2(cwd = process.cwd()) {
|
|
|
44216
44751
|
const storageDirPath = getMagicContextStorageDir();
|
|
44217
44752
|
const dbPath = join26(storageDirPath, "context.db");
|
|
44218
44753
|
const logPath = getMagicContextLogPath2("pi");
|
|
44219
|
-
const logFileSize =
|
|
44754
|
+
const logFileSize = existsSync30(logPath) ? statSync12(logPath).size : 0;
|
|
44220
44755
|
const otherPiExtensions = packages.filter((entry) => !isPiMagicContextPackageEntry(entry)).map(describePiPackageEntry);
|
|
44221
44756
|
const recentSessions = collectPiRecentSessions();
|
|
44222
44757
|
const historianDumps = collectPiHistorianDumps(recentSessions);
|
|
@@ -44231,7 +44766,7 @@ async function collectDiagnostics2(cwd = process.cwd()) {
|
|
|
44231
44766
|
piVersion: pi ? getPiVersion(pi.path) : null,
|
|
44232
44767
|
settings: {
|
|
44233
44768
|
path: settingsPath,
|
|
44234
|
-
exists:
|
|
44769
|
+
exists: existsSync30(settingsPath),
|
|
44235
44770
|
...settingsParsed.parseError ? { parseError: settingsParsed.parseError } : {},
|
|
44236
44771
|
hasMagicContextPackage: hasPiMagicContextPackage(packages),
|
|
44237
44772
|
packages: sanitizeValue2(packages)
|
|
@@ -44247,7 +44782,7 @@ async function collectDiagnostics2(cwd = process.cwd()) {
|
|
|
44247
44782
|
loadWarnings: loaded.warnings.map(sanitizeString2),
|
|
44248
44783
|
storageDir: {
|
|
44249
44784
|
path: storageDirPath,
|
|
44250
|
-
exists:
|
|
44785
|
+
exists: existsSync30(storageDirPath),
|
|
44251
44786
|
contextDbSizeBytes: fileSize2(dbPath)
|
|
44252
44787
|
},
|
|
44253
44788
|
conflicts: {
|
|
@@ -44256,7 +44791,7 @@ async function collectDiagnostics2(cwd = process.cwd()) {
|
|
|
44256
44791
|
},
|
|
44257
44792
|
logFile: {
|
|
44258
44793
|
path: logPath,
|
|
44259
|
-
exists:
|
|
44794
|
+
exists: existsSync30(logPath),
|
|
44260
44795
|
sizeKb: Math.round(logFileSize / 1024)
|
|
44261
44796
|
},
|
|
44262
44797
|
recentSessions,
|
|
@@ -44428,10 +44963,10 @@ var init_logs_pi = __esm(() => {
|
|
|
44428
44963
|
|
|
44429
44964
|
// src/commands/doctor-pi.ts
|
|
44430
44965
|
import { execFileSync as execFileSync6, spawnSync as spawnSync7 } from "node:child_process";
|
|
44431
|
-
import { existsSync as
|
|
44966
|
+
import { existsSync as existsSync31, mkdirSync as mkdirSync11, readdirSync as readdirSync5, readFileSync as readFileSync23, rmSync as rmSync4, statSync as statSync13 } from "node:fs";
|
|
44432
44967
|
import { createRequire as createRequire7 } from "node:module";
|
|
44433
44968
|
import { homedir as homedir18 } from "node:os";
|
|
44434
|
-
import { dirname as
|
|
44969
|
+
import { dirname as dirname16, isAbsolute as isAbsolute4, join as join28 } from "node:path";
|
|
44435
44970
|
function depsFrom(options) {
|
|
44436
44971
|
return {
|
|
44437
44972
|
...DEFAULT_DEPS3,
|
|
@@ -44545,13 +45080,13 @@ function piPluginDirCandidates(packages, cwd) {
|
|
|
44545
45080
|
}
|
|
44546
45081
|
dirs.push(join28(agentDir, "npm", "node_modules", PACKAGE_NAME));
|
|
44547
45082
|
dirs.push(join28(cwd, ".pi", "npm", "node_modules", PACKAGE_NAME));
|
|
44548
|
-
return dirs.filter((dir) =>
|
|
45083
|
+
return dirs.filter((dir) => existsSync31(join28(dir, "package.json")));
|
|
44549
45084
|
}
|
|
44550
45085
|
function projectConfigPath(cwd) {
|
|
44551
45086
|
return resolveCortexKitProjectConfigPath(cwd);
|
|
44552
45087
|
}
|
|
44553
45088
|
function readConfigForEmbedding(path6, isProjectConfig) {
|
|
44554
|
-
if (!
|
|
45089
|
+
if (!existsSync31(path6))
|
|
44555
45090
|
return null;
|
|
44556
45091
|
try {
|
|
44557
45092
|
const rawText = readFileSync23(path6, "utf-8");
|
|
@@ -44647,7 +45182,7 @@ function cacheRoots(cwd) {
|
|
|
44647
45182
|
function findPiMagicContextCacheDirs(cwd, expectedVersion, force = false) {
|
|
44648
45183
|
const found = new Map;
|
|
44649
45184
|
const visit = (path6, depth) => {
|
|
44650
|
-
if (depth < 0 || !
|
|
45185
|
+
if (depth < 0 || !existsSync31(path6))
|
|
44651
45186
|
return;
|
|
44652
45187
|
let stat;
|
|
44653
45188
|
try {
|
|
@@ -44658,7 +45193,7 @@ function findPiMagicContextCacheDirs(cwd, expectedVersion, force = false) {
|
|
|
44658
45193
|
if (!stat.isDirectory())
|
|
44659
45194
|
return;
|
|
44660
45195
|
const packageJson = join28(path6, "package.json");
|
|
44661
|
-
if (
|
|
45196
|
+
if (existsSync31(packageJson)) {
|
|
44662
45197
|
try {
|
|
44663
45198
|
const pkg = JSON.parse(readFileSync23(packageJson, "utf-8"));
|
|
44664
45199
|
const name = typeof pkg.name === "string" ? pkg.name : "";
|
|
@@ -44725,7 +45260,7 @@ async function runHealthChecks2(options) {
|
|
|
44725
45260
|
}
|
|
44726
45261
|
const settingsPath = getPiUserExtensionsPath();
|
|
44727
45262
|
let packages = [];
|
|
44728
|
-
if (!
|
|
45263
|
+
if (!existsSync31(settingsPath)) {
|
|
44729
45264
|
add2(results, "fail", `Pi settings not found at ${settingsPath}`);
|
|
44730
45265
|
repairPlan.addPackageEntry = true;
|
|
44731
45266
|
} else {
|
|
@@ -44749,7 +45284,7 @@ async function runHealthChecks2(options) {
|
|
|
44749
45284
|
["user", userConfigPath, true],
|
|
44750
45285
|
["project", projectPath, false]
|
|
44751
45286
|
]) {
|
|
44752
|
-
if (!
|
|
45287
|
+
if (!existsSync31(path6)) {
|
|
44753
45288
|
if (required2) {
|
|
44754
45289
|
add2(results, "warn", `No ${label} magic-context.jsonc found at ${path6}`);
|
|
44755
45290
|
if (userConfigMigrationRefused) {
|
|
@@ -44787,7 +45322,7 @@ async function runHealthChecks2(options) {
|
|
|
44787
45322
|
}
|
|
44788
45323
|
const storageDir = getMagicContextStorageDir();
|
|
44789
45324
|
const dbPath = join28(storageDir, "context.db");
|
|
44790
|
-
const existedBeforeOpen =
|
|
45325
|
+
const existedBeforeOpen = existsSync31(dbPath);
|
|
44791
45326
|
if (existedBeforeOpen)
|
|
44792
45327
|
add2(results, "pass", `Shared context DB exists at ${dbPath}`);
|
|
44793
45328
|
else
|
|
@@ -44924,7 +45459,7 @@ ${formatDatabaseRepairGuidance(dbPath)}`);
|
|
|
44924
45459
|
add2(results, "pass", "Pi extension cache clean (no stale cached package found)");
|
|
44925
45460
|
}
|
|
44926
45461
|
const logPath = getMagicContextLogPath2("pi");
|
|
44927
|
-
if (
|
|
45462
|
+
if (existsSync31(logPath)) {
|
|
44928
45463
|
const stat = statSync13(logPath);
|
|
44929
45464
|
const sizeKb = (stat.size / 1024).toFixed(0);
|
|
44930
45465
|
const lines = readFileSync23(logPath, "utf-8").split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
|
|
@@ -44962,7 +45497,7 @@ ${formatDatabaseRepairGuidance(dbPath)}`);
|
|
|
44962
45497
|
return { results, repairPlan, ...summarize(results) };
|
|
44963
45498
|
}
|
|
44964
45499
|
function writeDefaultMagicContextConfig(path6) {
|
|
44965
|
-
|
|
45500
|
+
mkdirSync11(dirname16(path6), { recursive: true });
|
|
44966
45501
|
const config2 = {
|
|
44967
45502
|
$schema: "https://raw.githubusercontent.com/cortexkit/magic-context/master/assets/magic-context.schema.json",
|
|
44968
45503
|
...MagicContextConfigSchema.parse({})
|
|
@@ -44984,7 +45519,7 @@ function repair2(plan, prompts) {
|
|
|
44984
45519
|
}
|
|
44985
45520
|
if (plan.writeUserConfig) {
|
|
44986
45521
|
const configPath = getPiUserConfigPath();
|
|
44987
|
-
if (!
|
|
45522
|
+
if (!existsSync31(configPath)) {
|
|
44988
45523
|
try {
|
|
44989
45524
|
writeDefaultMagicContextConfig(configPath);
|
|
44990
45525
|
prompts.log.success(`Wrote default Magic Context config to ${configPath}`);
|
|
@@ -45216,7 +45751,7 @@ var exports_doctor = {};
|
|
|
45216
45751
|
__export(exports_doctor, {
|
|
45217
45752
|
runDoctor: () => runDoctor4
|
|
45218
45753
|
});
|
|
45219
|
-
import { existsSync as
|
|
45754
|
+
import { existsSync as existsSync32, rmSync as rmSync5 } from "node:fs";
|
|
45220
45755
|
import { join as join29 } from "node:path";
|
|
45221
45756
|
async function runDoctor4(options) {
|
|
45222
45757
|
if (options.clear)
|
|
@@ -45248,6 +45783,27 @@ async function runDoctor4(options) {
|
|
|
45248
45783
|
if (result.handled)
|
|
45249
45784
|
return result.exitCode;
|
|
45250
45785
|
}
|
|
45786
|
+
const { sweepPendingMigrations: sweepPendingMigrations2, formatMigrationSweepLines: formatMigrationSweepLines2 } = await init_migrate().then(() => exports_migrate);
|
|
45787
|
+
const sweepDbPath = join29(getMagicContextStorageDir(), "context.db");
|
|
45788
|
+
let sweepDb = null;
|
|
45789
|
+
try {
|
|
45790
|
+
sweepDb = openExistingContextDatabaseForMutation(sweepDbPath);
|
|
45791
|
+
} catch {}
|
|
45792
|
+
if (sweepDb !== null) {
|
|
45793
|
+
try {
|
|
45794
|
+
const report = sweepPendingMigrations2(sweepDb);
|
|
45795
|
+
for (const line of formatMigrationSweepLines2(report)) {
|
|
45796
|
+
if (line.startsWith("LOST"))
|
|
45797
|
+
log2.error(line);
|
|
45798
|
+
else
|
|
45799
|
+
log2.info(line);
|
|
45800
|
+
}
|
|
45801
|
+
} catch (error51) {
|
|
45802
|
+
log2.warn(`Session-migration recovery sweep failed: ${error51 instanceof Error ? error51.message : String(error51)}`);
|
|
45803
|
+
} finally {
|
|
45804
|
+
sweepDb.close();
|
|
45805
|
+
}
|
|
45806
|
+
}
|
|
45251
45807
|
let anyFailure = false;
|
|
45252
45808
|
for (const adapter of adapters) {
|
|
45253
45809
|
log2.step(`Running doctor for ${adapter.displayName}…`);
|
|
@@ -45324,7 +45880,7 @@ async function runClear() {
|
|
|
45324
45880
|
const s = spinner2();
|
|
45325
45881
|
s.start(`Clearing ${item.path}`);
|
|
45326
45882
|
try {
|
|
45327
|
-
if (
|
|
45883
|
+
if (existsSync32(item.path)) {
|
|
45328
45884
|
rmSync5(item.path, { recursive: true, force: true });
|
|
45329
45885
|
}
|
|
45330
45886
|
s.stop(`Cleared ${item.path}`);
|
|
@@ -45340,9 +45896,9 @@ async function runClear() {
|
|
|
45340
45896
|
function formatSize(bytes) {
|
|
45341
45897
|
if (bytes < 1024)
|
|
45342
45898
|
return `${bytes} B`;
|
|
45343
|
-
if (bytes <
|
|
45899
|
+
if (bytes < 1048576)
|
|
45344
45900
|
return `${(bytes / 1024).toFixed(1)} KB`;
|
|
45345
|
-
if (bytes <
|
|
45901
|
+
if (bytes < 1073741824)
|
|
45346
45902
|
return `${(bytes / 1024 / 1024).toFixed(1)} MB`;
|
|
45347
45903
|
return `${(bytes / 1024 / 1024 / 1024).toFixed(2)} GB`;
|
|
45348
45904
|
}
|