@cortexkit/magic-context 0.42.4 → 0.42.6
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 +550 -129
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -20477,7 +20477,7 @@ function expandConfigPath(value) {
|
|
|
20477
20477
|
return `${homedir8()}/${trimmed.slice(2)}`;
|
|
20478
20478
|
return trimmed;
|
|
20479
20479
|
}
|
|
20480
|
-
var DEFAULT_EXECUTE_THRESHOLD_PERCENTAGE = 65, EXECUTE_THRESHOLD_CAP_MESSAGE = "execute_threshold is capped at 90% for cache safety: output capacity is reserved from the usable context window, and the remaining 10% absorbs mid-turn growth before the absolute 95% emergency wall. Use a value between 20 and 90.", DEFAULT_HISTORIAN_TIMEOUT_MS = 600000, DEFAULT_HISTORY_BUDGET_PERCENTAGE = 0.15, DEFAULT_LOCAL_EMBEDDING_MODEL = "Xenova/all-MiniLM-L6-v2", PiThinkingLevelSchema, OmpThinkingLevelSchema, PiConfigSchema, PromptSurfacePresetSchema, PromptSurfaceModelKeySchema, PromptSurfaceToolKeySchema, PromptSurfaceConfigSchema, PER_HARNESS_MIGRATION_INVENTORY, PER_HARNESS_MODEL_KEYS, OcEntryObjectSchema, OcEntrySchema, PiEntryObjectSchema, PiEntrySchema, OmpEntryObjectSchema, OmpEntrySchema, OpenCodeHarnessBlockSchema, PiHarnessBlockSchema, OmpHarnessBlockSchema, OpenCodeTaskExecutionSchema, PiTaskExecutionSchema, OmpTaskExecutionSchema, DreamerOpenCodeHarnessBlockSchema, DreamerPiHarnessBlockSchema, DreamerOmpHarnessBlockSchema, ProfileOpenCodeModelBlockSchema, ProfilePiModelBlockSchema, ProfileOmpModelBlockSchema, ProfileHistorianSchema, ProfileDreamerSchema, ConfigProfileSchema, ConfigProfilesSchema, CronScheduleSchema, DreamTaskBaseConfigSchema, PromotionThresholdSchema, PrimerPromotionThresholdSchema, DreamTaskConfigSchema, ReviewUserMemoriesTaskConfigSchema, PromotePrimersTaskConfigSchema, DEFAULT_TASK_SCHEDULES2, DreamTasksSchema, AgentMetadataSchema, DreamerConfigSchema, HistorianConfigSchema, EmbeddingFallbackProviderSchema, BaseEmbeddingConfigSchema, EmbeddingConfigSchema, MagicContextConfigSchema;
|
|
20480
|
+
var DEFAULT_EXECUTE_THRESHOLD_PERCENTAGE = 65, EXECUTE_THRESHOLD_CAP_MESSAGE = "execute_threshold is capped at 90% for cache safety: output capacity is reserved from the usable context window, and the remaining 10% absorbs mid-turn growth before the absolute 95% emergency wall. Use a value between 20 and 90.", DEFAULT_HISTORIAN_TIMEOUT_MS = 600000, DEFAULT_HISTORY_BUDGET_PERCENTAGE = 0.15, PROTECTED_TOKENS_MIN = 4000, DEFAULT_LOCAL_EMBEDDING_MODEL = "Xenova/all-MiniLM-L6-v2", PiThinkingLevelSchema, OmpThinkingLevelSchema, PiConfigSchema, PromptSurfacePresetSchema, PromptSurfaceModelKeySchema, PromptSurfaceToolKeySchema, PromptSurfaceConfigSchema, PER_HARNESS_MIGRATION_INVENTORY, PER_HARNESS_MODEL_KEYS, OcEntryObjectSchema, OcEntrySchema, PiEntryObjectSchema, PiEntrySchema, OmpEntryObjectSchema, OmpEntrySchema, OpenCodeHarnessBlockSchema, PiHarnessBlockSchema, OmpHarnessBlockSchema, OpenCodeTaskExecutionSchema, PiTaskExecutionSchema, OmpTaskExecutionSchema, DreamerOpenCodeHarnessBlockSchema, DreamerPiHarnessBlockSchema, DreamerOmpHarnessBlockSchema, ProfileOpenCodeModelBlockSchema, ProfilePiModelBlockSchema, ProfileOmpModelBlockSchema, ProfileHistorianSchema, ProfileDreamerSchema, ConfigProfileSchema, ConfigProfilesSchema, CronScheduleSchema, DreamTaskBaseConfigSchema, PromotionThresholdSchema, PrimerPromotionThresholdSchema, DreamTaskConfigSchema, ReviewUserMemoriesTaskConfigSchema, PromotePrimersTaskConfigSchema, DEFAULT_TASK_SCHEDULES2, DreamTasksSchema, AgentMetadataSchema, DreamerConfigSchema, HistorianConfigSchema, EmbeddingFallbackProviderSchema, BaseEmbeddingConfigSchema, EmbeddingConfigSchema, MagicContextConfigSchema;
|
|
20481
20481
|
var init_magic_context = __esm(() => {
|
|
20482
20482
|
init_zod();
|
|
20483
20483
|
init_language_directive();
|
|
@@ -20836,8 +20836,8 @@ var init_magic_context = __esm(() => {
|
|
|
20836
20836
|
smart_notes: object({
|
|
20837
20837
|
retina_handoff: boolean2().default(false).describe("When true, dreamer skips smart notes whose surface conditions compiled to retina provider configs at authoring time. Default false keeps both paths active until the retina consumer is deployed.")
|
|
20838
20838
|
}).default({ retina_handoff: false }).describe("Smart-note ownership transition controls."),
|
|
20839
|
-
cache_ttl: union([string2(), object({ default: string2() }).catchall(string2())]).default("5m").describe(`How long Magic Context assumes the provider's cached prefix stays valid. This is MC's own deferral gate — it does not change the provider's actual cache lifetime. String (e.g. "5m", "1h", "30s") or per-model object ({ default: "5m", "model
|
|
20840
|
-
prompt_surface: PromptSurfaceConfigSchema.default({ default: "full" }).describe("Prompt-surface presets: default is full; models use bare model IDs, provider/model, or provider/* routing keys. Guidance and tool-description overrides are user-level only.
|
|
20839
|
+
cache_ttl: union([string2(), object({ default: string2() }).catchall(string2())]).default("5m").describe(`How long Magic Context assumes the provider's cached prefix stays valid. This is MC's own deferral gate — it does not change the provider's actual cache lifetime. String (e.g. "5m", "1h", "30s") or per-model object ({ default: "5m", "provider/model": "1h", "provider/*": "never" }); keys resolve most-specific first (exact provider/model, bare model ID, shorter dash-prefixes, then the provider/* wildcard, then default). Set to "never" to mean MC never assumes expiry (for lanes kept warm externally by a cache-keep tool) — disables the idle-TTL heuristic so MC never initiates a rebuild based on elapsed time. Provider-side extended TTL is a separate request-level concern (cache_control: { ttl } in the request body).`),
|
|
20840
|
+
prompt_surface: PromptSurfaceConfigSchema.default({ default: "full" }).describe("Prompt-surface presets: default is full; models use bare model IDs, provider/model, or provider/* routing keys. Guidance and tool-description overrides are user-level only. OpenCode 1.x, Pi, and OMP register tool descriptions once per process (they follow the default preset). OpenCode 2 rewrites the five ctx_* descriptions per request from the draft model."),
|
|
20841
20841
|
output_reserve: union([
|
|
20842
20842
|
number2().min(0),
|
|
20843
20843
|
object({ default: number2().min(0) }).catchall(number2().min(0))
|
|
@@ -20853,7 +20853,7 @@ var init_magic_context = __esm(() => {
|
|
|
20853
20853
|
execute_threshold_tokens: object({
|
|
20854
20854
|
default: number2().min(5000).max(2000000).optional()
|
|
20855
20855
|
}).catchall(number2().min(5000).max(2000000)).optional().describe("Absolute token thresholds per model. When matched, overrides execute_threshold_percentage for that model. Accepts `default` for all models or per-model keys. Values above 90% × context_limit are clamped with a warning log. Min 5_000, max 2_000_000."),
|
|
20856
|
-
protected_tokens: number2().int().min(
|
|
20856
|
+
protected_tokens: number2().int().min(PROTECTED_TOKENS_MIN).max(1e6).optional().describe("Positive integer token floor to protect from automatic reclaim (min: 4_000, max: 1_000_000). When omitted, the derived default is clamp(round(0.05 × usableSoft), min(16_000, round(0.08 × usableSoft)), 64_000)."),
|
|
20857
20857
|
protected_tags: unknown().optional().describe("Deprecated: number of recent tags to protect. Ignored for behaviour; use protected_tokens instead.").meta({ deprecated: true }),
|
|
20858
20858
|
clear_reasoning_age: number2().min(10).default(50).describe("Clear reasoning/thinking blocks older than N tags (default: 50)"),
|
|
20859
20859
|
history_budget_percentage: number2().min(0.05).max(0.5).default(DEFAULT_HISTORY_BUDGET_PERCENTAGE).describe("Fraction of usable context (context_limit × execute_threshold) reserved for the session history block (default: 0.15)"),
|
|
@@ -21786,6 +21786,9 @@ function redactConfigValue(value) {
|
|
|
21786
21786
|
}
|
|
21787
21787
|
return typeof value;
|
|
21788
21788
|
}
|
|
21789
|
+
function formatProtectedTokensBelowMinWarning(value) {
|
|
21790
|
+
return `protected_tokens is a token floor (minimum ${PROTECTED_TOKENS_MIN}, default derived from the context window); ${value} looks like the old protected_tags count. Remove the key to use the default, or set a token count such as 16000.`;
|
|
21791
|
+
}
|
|
21789
21792
|
function warnProtectedTagsDeprecationOnce() {
|
|
21790
21793
|
if (!warnedProtectedTagsDeprecation) {
|
|
21791
21794
|
warnedProtectedTagsDeprecation = true;
|
|
@@ -21876,6 +21879,11 @@ function parsePluginConfig(rawConfig, recoveredTopLevelKeys = []) {
|
|
|
21876
21879
|
delete patched[key];
|
|
21877
21880
|
const defaultVal = defaults[key];
|
|
21878
21881
|
const reason = customMessagesByKey.get(key);
|
|
21882
|
+
const invalidRawValue = rawConfig[key];
|
|
21883
|
+
if (key === "protected_tokens" && typeof invalidRawValue === "number" && invalidRawValue < PROTECTED_TOKENS_MIN) {
|
|
21884
|
+
warnings.push(formatProtectedTokensBelowMinWarning(invalidRawValue));
|
|
21885
|
+
continue;
|
|
21886
|
+
}
|
|
21879
21887
|
warnings.push(`"${key}": invalid value (${redactConfigValue(rawConfig[key])}), using default ${JSON.stringify(defaultVal)}.${reason ? ` ${reason}` : ""}`);
|
|
21880
21888
|
}
|
|
21881
21889
|
const retryMigrated = migrateLegacyAgentEnabledInMemory(migrateDreamerV2(migrateLegacyExperimental(patched, preMigrationWarnings), preMigrationWarnings), preMigrationWarnings);
|
|
@@ -22122,6 +22130,7 @@ import { homedir as homedir11 } from "node:os";
|
|
|
22122
22130
|
import { join as join13 } from "node:path";
|
|
22123
22131
|
function detectConflicts(directory, options) {
|
|
22124
22132
|
const compactionEnabled = options?.compactionEnabled ?? true;
|
|
22133
|
+
const hostGeneration = options?.hostGeneration ?? "v1";
|
|
22125
22134
|
const conflicts = {
|
|
22126
22135
|
compactionAuto: false,
|
|
22127
22136
|
compactionPrune: false,
|
|
@@ -22131,15 +22140,15 @@ function detectConflicts(directory, options) {
|
|
|
22131
22140
|
omoAnthropicRecovery: false
|
|
22132
22141
|
};
|
|
22133
22142
|
const reasons = [];
|
|
22134
|
-
let compactionResult = options?.resolvedCompaction ?? checkCompaction(directory);
|
|
22143
|
+
let compactionResult = options?.resolvedCompaction ?? checkCompaction(directory, hostGeneration);
|
|
22135
22144
|
if (process.env.OPENCODE_DISABLE_AUTOCOMPACT) {
|
|
22136
22145
|
compactionResult = { auto: false, prune: false };
|
|
22137
22146
|
}
|
|
22138
|
-
if (compactionEnabled && compactionResult.auto) {
|
|
22147
|
+
if (hostGeneration === "v1" && compactionEnabled && compactionResult.auto) {
|
|
22139
22148
|
conflicts.compactionAuto = true;
|
|
22140
22149
|
reasons.push(options?.resolvedCompaction ? "OpenCode auto-compaction is enabled (compaction.auto=true) (resolved config)" : "OpenCode auto-compaction is enabled (compaction.auto=true)");
|
|
22141
22150
|
}
|
|
22142
|
-
if (compactionEnabled && compactionResult.prune) {
|
|
22151
|
+
if (hostGeneration === "v1" && compactionEnabled && compactionResult.prune) {
|
|
22143
22152
|
conflicts.compactionPrune = true;
|
|
22144
22153
|
reasons.push(options?.resolvedCompaction ? "OpenCode prune is enabled (compaction.prune=true) (resolved config)" : "OpenCode prune is enabled (compaction.prune=true)");
|
|
22145
22154
|
}
|
|
@@ -22165,29 +22174,32 @@ function detectConflicts(directory, options) {
|
|
|
22165
22174
|
hasConflict: reasons.length > 0,
|
|
22166
22175
|
reasons,
|
|
22167
22176
|
conflicts,
|
|
22168
|
-
nativeCompaction: {
|
|
22177
|
+
nativeCompaction: {
|
|
22178
|
+
auto: compactionResult.auto,
|
|
22179
|
+
prune: hostGeneration === "v1" ? compactionResult.prune : false
|
|
22180
|
+
}
|
|
22169
22181
|
};
|
|
22170
22182
|
}
|
|
22171
|
-
function checkCompaction(directory) {
|
|
22183
|
+
function checkCompaction(directory, hostGeneration) {
|
|
22172
22184
|
if (process.env.OPENCODE_DISABLE_AUTOCOMPACT) {
|
|
22173
22185
|
return { auto: false, prune: false };
|
|
22174
22186
|
}
|
|
22175
|
-
const projectResult = readProjectCompaction(directory);
|
|
22187
|
+
const projectResult = readProjectCompaction(directory, hostGeneration);
|
|
22176
22188
|
if (projectResult.resolved)
|
|
22177
22189
|
return projectResult;
|
|
22178
|
-
const userResult = readUserCompaction();
|
|
22190
|
+
const userResult = readUserCompaction(hostGeneration);
|
|
22179
22191
|
if (userResult.resolved)
|
|
22180
22192
|
return userResult;
|
|
22181
22193
|
return { auto: true, prune: false };
|
|
22182
22194
|
}
|
|
22183
|
-
function readProjectCompaction(directory) {
|
|
22195
|
+
function readProjectCompaction(directory, hostGeneration) {
|
|
22184
22196
|
const dotOcJsonc = join13(directory, ".opencode", "opencode.jsonc");
|
|
22185
22197
|
const dotOcJson = join13(directory, ".opencode", "opencode.json");
|
|
22186
22198
|
const dotOcConfig = readJsoncFile(dotOcJsonc) ?? readJsoncFile(dotOcJson);
|
|
22187
22199
|
if (dotOcConfig?.compaction) {
|
|
22188
22200
|
const c = dotOcConfig.compaction;
|
|
22189
|
-
if (c.auto !== undefined || c.prune !== undefined) {
|
|
22190
|
-
return
|
|
22201
|
+
if (c.auto !== undefined || hostGeneration === "v1" && c.prune !== undefined || hostGeneration === "v2" && (c.keep?.tokens !== undefined || c.buffer !== undefined)) {
|
|
22202
|
+
return resolvedCompactionBlock(c, hostGeneration);
|
|
22191
22203
|
}
|
|
22192
22204
|
}
|
|
22193
22205
|
const rootJsonc = join13(directory, "opencode.jsonc");
|
|
@@ -22195,25 +22207,37 @@ function readProjectCompaction(directory) {
|
|
|
22195
22207
|
const rootConfig = readJsoncFile(rootJsonc) ?? readJsoncFile(rootJson);
|
|
22196
22208
|
if (rootConfig?.compaction) {
|
|
22197
22209
|
const c = rootConfig.compaction;
|
|
22198
|
-
if (c.auto !== undefined || c.prune !== undefined) {
|
|
22199
|
-
return
|
|
22210
|
+
if (c.auto !== undefined || hostGeneration === "v1" && c.prune !== undefined || hostGeneration === "v2" && (c.keep?.tokens !== undefined || c.buffer !== undefined)) {
|
|
22211
|
+
return resolvedCompactionBlock(c, hostGeneration);
|
|
22200
22212
|
}
|
|
22201
22213
|
}
|
|
22202
22214
|
return { auto: false, prune: false, resolved: false };
|
|
22203
22215
|
}
|
|
22204
|
-
function readUserCompaction() {
|
|
22216
|
+
function readUserCompaction(hostGeneration) {
|
|
22205
22217
|
try {
|
|
22206
22218
|
const paths = getOpenCodeConfigPaths({ binary: "opencode" });
|
|
22207
22219
|
const config = readJsoncFile(paths.configJsonc) ?? readJsoncFile(paths.configJson);
|
|
22208
22220
|
if (config?.compaction) {
|
|
22209
22221
|
const c = config.compaction;
|
|
22210
|
-
if (c.auto !== undefined || c.prune !== undefined) {
|
|
22211
|
-
return
|
|
22222
|
+
if (c.auto !== undefined || hostGeneration === "v1" && c.prune !== undefined || hostGeneration === "v2" && (c.keep?.tokens !== undefined || c.buffer !== undefined)) {
|
|
22223
|
+
return resolvedCompactionBlock(c, hostGeneration);
|
|
22212
22224
|
}
|
|
22213
22225
|
}
|
|
22214
22226
|
} catch {}
|
|
22215
22227
|
return { auto: false, prune: false, resolved: false };
|
|
22216
22228
|
}
|
|
22229
|
+
function resolvedCompactionBlock(block, hostGeneration) {
|
|
22230
|
+
if (hostGeneration === "v2") {
|
|
22231
|
+
return {
|
|
22232
|
+
auto: block.auto !== false,
|
|
22233
|
+
prune: false,
|
|
22234
|
+
resolved: true,
|
|
22235
|
+
...typeof block.keep?.tokens === "number" ? { keepTokens: block.keep.tokens } : {},
|
|
22236
|
+
...typeof block.buffer === "number" ? { buffer: block.buffer } : {}
|
|
22237
|
+
};
|
|
22238
|
+
}
|
|
22239
|
+
return { auto: block.auto === true, prune: block.prune === true, resolved: true };
|
|
22240
|
+
}
|
|
22217
22241
|
function checkDcpPlugin(directory) {
|
|
22218
22242
|
const plugins = collectPluginEntries(directory);
|
|
22219
22243
|
return plugins.some((p) => matchesPackageName(p, DCP_PACKAGE_NAMES));
|
|
@@ -26263,9 +26287,11 @@ class SubcModuleTransport {
|
|
|
26263
26287
|
this.wrapupSessions.delete(args.sessionId);
|
|
26264
26288
|
};
|
|
26265
26289
|
const laneDeadlineMs = Date.now() + attemptTimeoutMs;
|
|
26266
|
-
let releaseLane;
|
|
26290
|
+
let releaseLane = () => {};
|
|
26267
26291
|
try {
|
|
26268
|
-
|
|
26292
|
+
if (!args.bypassSessionLane) {
|
|
26293
|
+
releaseLane = await this.acquireCorrectnessLane(args.sessionId, args.signal, laneDeadlineMs);
|
|
26294
|
+
}
|
|
26269
26295
|
} catch (error) {
|
|
26270
26296
|
finishWrapupTracking();
|
|
26271
26297
|
if (args.method === "state_sync" && isDeadlineFailure(error)) {
|
|
@@ -26367,12 +26393,13 @@ class SubcModuleTransport {
|
|
|
26367
26393
|
args.onTimings?.(timings);
|
|
26368
26394
|
}
|
|
26369
26395
|
}
|
|
26370
|
-
async authorityRequest(sessionId, projectRoot, method, body) {
|
|
26396
|
+
async authorityRequest(sessionId, projectRoot, method, body, timeoutMs) {
|
|
26371
26397
|
const response = await this.call({
|
|
26372
26398
|
sessionId,
|
|
26373
26399
|
projectRoot,
|
|
26374
26400
|
method,
|
|
26375
|
-
body: { ...body, method, v: 1 }
|
|
26401
|
+
body: { ...body, method, v: 1 },
|
|
26402
|
+
timeoutMs
|
|
26376
26403
|
});
|
|
26377
26404
|
if (isRecord3(response) && isRecord3(response.result))
|
|
26378
26405
|
return response.result;
|
|
@@ -26432,6 +26459,20 @@ class SubcModuleTransport {
|
|
|
26432
26459
|
throw new Error("mirror.pull omitted page");
|
|
26433
26460
|
return { page: response.page };
|
|
26434
26461
|
}
|
|
26462
|
+
async mirrorMemory(args) {
|
|
26463
|
+
const { projectRoot, ...body } = args;
|
|
26464
|
+
const response = await this.authorityRequest(`mirror-memory:${args.module_row_id}`, projectRoot ?? this.bindRootForAuthority(), "mirror.memory", body, 1900);
|
|
26465
|
+
return {
|
|
26466
|
+
row: isRecord3(response.row) ? response.row : null
|
|
26467
|
+
};
|
|
26468
|
+
}
|
|
26469
|
+
async memoryIdentityAck(args) {
|
|
26470
|
+
const { projectRoot, ...body } = args;
|
|
26471
|
+
const response = await this.authorityRequest(`memory-identity:${args.project}`, projectRoot ?? this.bindRootForAuthority(), "memory.identity.ack", body);
|
|
26472
|
+
return {
|
|
26473
|
+
acknowledged: typeof response.acknowledged === "number" ? response.acknowledged : 0
|
|
26474
|
+
};
|
|
26475
|
+
}
|
|
26435
26476
|
async deleteSession(sessionId, projectRoot) {
|
|
26436
26477
|
await this.call({
|
|
26437
26478
|
sessionId,
|
|
@@ -27700,6 +27741,90 @@ function isSqliteLockError(error) {
|
|
|
27700
27741
|
function tableExists(db, name) {
|
|
27701
27742
|
return Boolean(db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name = ?").get(name));
|
|
27702
27743
|
}
|
|
27744
|
+
function tableHasHarnessColumn(db, name) {
|
|
27745
|
+
if (!tableExists(db, name))
|
|
27746
|
+
return false;
|
|
27747
|
+
return db.prepare(`PRAGMA table_info(${name})`).all().some((column) => column.name === "harness");
|
|
27748
|
+
}
|
|
27749
|
+
function deleteLosingOpenCode2Twin(db, table, joinColumns, newerPredicate) {
|
|
27750
|
+
if (!tableHasHarnessColumn(db, table))
|
|
27751
|
+
return;
|
|
27752
|
+
const naturalJoin = joinColumns.map((column) => `oc.${column} = o2.${column}`).join(" AND ");
|
|
27753
|
+
const o2On = naturalJoin ? `${naturalJoin} AND oc.harness = 'opencode'` : `oc.harness = 'opencode'`;
|
|
27754
|
+
const ocOn = naturalJoin ? `${naturalJoin} AND o2.harness = 'opencode2'` : `o2.harness = 'opencode2'`;
|
|
27755
|
+
db.exec(`
|
|
27756
|
+
DELETE FROM ${table}
|
|
27757
|
+
WHERE rowid IN (
|
|
27758
|
+
SELECT o2.rowid
|
|
27759
|
+
FROM ${table} AS o2
|
|
27760
|
+
JOIN ${table} AS oc
|
|
27761
|
+
ON ${o2On}
|
|
27762
|
+
WHERE o2.harness = 'opencode2'
|
|
27763
|
+
AND NOT (${newerPredicate})
|
|
27764
|
+
);
|
|
27765
|
+
DELETE FROM ${table}
|
|
27766
|
+
WHERE rowid IN (
|
|
27767
|
+
SELECT oc.rowid
|
|
27768
|
+
FROM ${table} AS oc
|
|
27769
|
+
JOIN ${table} AS o2
|
|
27770
|
+
ON ${ocOn}
|
|
27771
|
+
WHERE oc.harness = 'opencode'
|
|
27772
|
+
AND (${newerPredicate})
|
|
27773
|
+
);
|
|
27774
|
+
`);
|
|
27775
|
+
}
|
|
27776
|
+
function relabelOpenCode2HarnessRows(db) {
|
|
27777
|
+
deleteLosingOpenCode2Twin(db, "session_projects", ["session_id"], "o2.updated_at > oc.updated_at");
|
|
27778
|
+
deleteLosingOpenCode2Twin(db, "primer_candidates", ["project_path", "session_id", "source_start_message_id", "source_end_message_id"], "o2.created_at > oc.created_at");
|
|
27779
|
+
deleteLosingOpenCode2Twin(db, "transform_decisions", ["session_id", "message_id"], "o2.ts_ms > oc.ts_ms");
|
|
27780
|
+
deleteLosingOpenCode2Twin(db, "message_history_orphan_sweep", [], "COALESCE(o2.last_swept_at, -1) > COALESCE(oc.last_swept_at, -1)");
|
|
27781
|
+
if (tableHasHarnessColumn(db, "session_project_backfill_state")) {
|
|
27782
|
+
db.exec(`
|
|
27783
|
+
DELETE FROM session_project_backfill_state
|
|
27784
|
+
WHERE harness = 'opencode2'
|
|
27785
|
+
AND EXISTS (
|
|
27786
|
+
SELECT 1 FROM session_project_backfill_state WHERE harness = 'opencode'
|
|
27787
|
+
)
|
|
27788
|
+
AND NOT (
|
|
27789
|
+
(status = 'completed'
|
|
27790
|
+
AND (SELECT status FROM session_project_backfill_state WHERE harness = 'opencode')
|
|
27791
|
+
!= 'completed')
|
|
27792
|
+
OR (
|
|
27793
|
+
status = (SELECT status FROM session_project_backfill_state WHERE harness = 'opencode')
|
|
27794
|
+
AND COALESCE(started_at, -1) > COALESCE(
|
|
27795
|
+
(SELECT started_at FROM session_project_backfill_state WHERE harness = 'opencode'),
|
|
27796
|
+
-1
|
|
27797
|
+
)
|
|
27798
|
+
)
|
|
27799
|
+
);
|
|
27800
|
+
DELETE FROM session_project_backfill_state
|
|
27801
|
+
WHERE harness = 'opencode'
|
|
27802
|
+
AND EXISTS (
|
|
27803
|
+
SELECT 1 FROM session_project_backfill_state WHERE harness = 'opencode2'
|
|
27804
|
+
)
|
|
27805
|
+
AND (
|
|
27806
|
+
((SELECT status FROM session_project_backfill_state WHERE harness = 'opencode2') = 'completed'
|
|
27807
|
+
AND status != 'completed')
|
|
27808
|
+
OR (
|
|
27809
|
+
status = (SELECT status FROM session_project_backfill_state WHERE harness = 'opencode2')
|
|
27810
|
+
AND COALESCE(
|
|
27811
|
+
(SELECT started_at FROM session_project_backfill_state WHERE harness = 'opencode2'),
|
|
27812
|
+
-1
|
|
27813
|
+
) > COALESCE(started_at, -1)
|
|
27814
|
+
)
|
|
27815
|
+
);
|
|
27816
|
+
`);
|
|
27817
|
+
}
|
|
27818
|
+
const tables = new Set([
|
|
27819
|
+
...V85_OPENCODE2_RELABEL_TABLES,
|
|
27820
|
+
...V85_OPTIONAL_OPENCODE2_RELABEL_TABLES
|
|
27821
|
+
]);
|
|
27822
|
+
for (const table of tables) {
|
|
27823
|
+
if (!tableHasHarnessColumn(db, table))
|
|
27824
|
+
continue;
|
|
27825
|
+
db.exec(`UPDATE ${table} SET harness = 'opencode' WHERE harness = 'opencode2'`);
|
|
27826
|
+
}
|
|
27827
|
+
}
|
|
27703
27828
|
function healMismatchedTierClose(db, table, hasLegacy) {
|
|
27704
27829
|
if (!tableExists(db, table))
|
|
27705
27830
|
return;
|
|
@@ -27901,7 +28026,7 @@ function runMigrations(db) {
|
|
|
27901
28026
|
log3(`[migrations] upstream migration lane now: ${MIGRATIONS[MIGRATIONS.length - 1].version}`);
|
|
27902
28027
|
}
|
|
27903
28028
|
}
|
|
27904
|
-
var FORK_MIGRATION_VERSION_FLOOR = 1e4, MigrationLockBusyError, MIGRATIONS, LATEST_MIGRATION_VERSION;
|
|
28029
|
+
var FORK_MIGRATION_VERSION_FLOOR = 1e4, MigrationLockBusyError, V85_OPENCODE2_RELABEL_TABLES, V85_OPTIONAL_OPENCODE2_RELABEL_TABLES, MIGRATIONS, LATEST_MIGRATION_VERSION;
|
|
27905
28030
|
var init_migrations = __esm(() => {
|
|
27906
28031
|
init_compartment_parser();
|
|
27907
28032
|
init_logger();
|
|
@@ -27913,6 +28038,30 @@ var init_migrations = __esm(() => {
|
|
|
27913
28038
|
this.name = "MigrationLockBusyError";
|
|
27914
28039
|
}
|
|
27915
28040
|
};
|
|
28041
|
+
V85_OPENCODE2_RELABEL_TABLES = [
|
|
28042
|
+
"tags",
|
|
28043
|
+
"pending_ops",
|
|
28044
|
+
"source_contents",
|
|
28045
|
+
"compartments",
|
|
28046
|
+
"compartment_chunk_embeddings",
|
|
28047
|
+
"session_projects",
|
|
28048
|
+
"compartment_events",
|
|
28049
|
+
"compression_depth",
|
|
28050
|
+
"session_facts",
|
|
28051
|
+
"primer_candidates",
|
|
28052
|
+
"notes",
|
|
28053
|
+
"message_history_index",
|
|
28054
|
+
"message_history_source",
|
|
28055
|
+
"pending_session_cleanup",
|
|
28056
|
+
"message_history_orphan_sweep",
|
|
28057
|
+
"session_meta",
|
|
28058
|
+
"subagent_invocations",
|
|
28059
|
+
"historian_runs",
|
|
28060
|
+
"transform_decisions",
|
|
28061
|
+
"recomp_compartments",
|
|
28062
|
+
"recomp_facts"
|
|
28063
|
+
];
|
|
28064
|
+
V85_OPTIONAL_OPENCODE2_RELABEL_TABLES = ["session_project_backfill_state"];
|
|
27916
28065
|
MIGRATIONS = [
|
|
27917
28066
|
{
|
|
27918
28067
|
version: 1,
|
|
@@ -29975,6 +30124,13 @@ var init_migrations = __esm(() => {
|
|
|
29975
30124
|
ensureColumn(db, "session_meta", "protected_tokens_effective", "INTEGER");
|
|
29976
30125
|
ensureColumn(db, "session_meta", "protected_tokens_pre_snapshot", "TEXT");
|
|
29977
30126
|
}
|
|
30127
|
+
},
|
|
30128
|
+
{
|
|
30129
|
+
version: 85,
|
|
30130
|
+
description: "relabel OpenCode 1.x mis-tagged opencode2 session rows",
|
|
30131
|
+
up(db) {
|
|
30132
|
+
relabelOpenCode2HarnessRows(db);
|
|
30133
|
+
}
|
|
29978
30134
|
}
|
|
29979
30135
|
];
|
|
29980
30136
|
LATEST_MIGRATION_VERSION = MIGRATIONS.reduce((max, m) => Math.max(max, m.version), 0);
|
|
@@ -30054,15 +30210,20 @@ var init_tool_definition_tokens = __esm(() => {
|
|
|
30054
30210
|
import { existsSync as existsSync19, readdirSync as readdirSync2, statSync as statSync9 } from "node:fs";
|
|
30055
30211
|
import { homedir as homedir13 } from "node:os";
|
|
30056
30212
|
import { isAbsolute as isAbsolute6, join as join16 } from "node:path";
|
|
30057
|
-
function
|
|
30058
|
-
|
|
30213
|
+
function openCodeHostGenerationFromVersion(version) {
|
|
30214
|
+
const major = Number.parseInt(version?.match(/\d+/)?.[0] ?? "", 10);
|
|
30215
|
+
return Number.isFinite(major) && major >= 2 ? "v2" : "v1";
|
|
30216
|
+
}
|
|
30217
|
+
function openCodeDataDir(env = process.env, dataHome) {
|
|
30218
|
+
return join16(dataHome ?? env.XDG_DATA_HOME ?? join16(homedir13(), ".local", "share"), "opencode");
|
|
30059
30219
|
}
|
|
30060
|
-
function environmentKey(dataDir) {
|
|
30220
|
+
function environmentKey(dataDir, hostGeneration, channel, env) {
|
|
30061
30221
|
return [
|
|
30222
|
+
hostGeneration,
|
|
30062
30223
|
dataDir,
|
|
30063
|
-
|
|
30064
|
-
|
|
30065
|
-
|
|
30224
|
+
env.OPENCODE_DB ?? "",
|
|
30225
|
+
env.OPENCODE_DISABLE_CHANNEL_DB ?? "",
|
|
30226
|
+
channel ?? env.OPENCODE_CHANNEL ?? ""
|
|
30066
30227
|
].join("\x00");
|
|
30067
30228
|
}
|
|
30068
30229
|
function channelPath(dataDir, channel) {
|
|
@@ -30094,8 +30255,8 @@ function discoverOpenCodeDb(dataDir) {
|
|
|
30094
30255
|
const channel = name === "opencode.db" ? null : name.slice("opencode-".length, -".db".length) || null;
|
|
30095
30256
|
return { path: existing.path, source: "discovered", channel };
|
|
30096
30257
|
}
|
|
30097
|
-
function
|
|
30098
|
-
const explicit =
|
|
30258
|
+
function resolveV1Fresh(dataDir, env = process.env) {
|
|
30259
|
+
const explicit = env.OPENCODE_DB;
|
|
30099
30260
|
if (explicit !== undefined && explicit.length > 0) {
|
|
30100
30261
|
if (explicit === ":memory:") {
|
|
30101
30262
|
return { path: explicit, source: "OPENCODE_DB", channel: null };
|
|
@@ -30106,24 +30267,47 @@ function resolveFresh(dataDir) {
|
|
|
30106
30267
|
channel: null
|
|
30107
30268
|
};
|
|
30108
30269
|
}
|
|
30109
|
-
const disableChannelDb =
|
|
30270
|
+
const disableChannelDb = env.OPENCODE_DISABLE_CHANNEL_DB;
|
|
30110
30271
|
if (disableChannelDb === "1" || disableChannelDb === "true") {
|
|
30111
30272
|
return { path: join16(dataDir, "opencode.db"), source: "default", channel: null };
|
|
30112
30273
|
}
|
|
30113
|
-
const channel =
|
|
30274
|
+
const channel = env.OPENCODE_CHANNEL;
|
|
30114
30275
|
if (channel !== undefined && channel.length > 0) {
|
|
30115
30276
|
return { path: channelPath(dataDir, channel), source: "channel", channel };
|
|
30116
30277
|
}
|
|
30117
30278
|
return discoverOpenCodeDb(dataDir);
|
|
30118
30279
|
}
|
|
30119
|
-
function
|
|
30120
|
-
|
|
30121
|
-
|
|
30280
|
+
function sourceOpenCodeDatabaseFilename(hostGeneration, channel, env = process.env) {
|
|
30281
|
+
if (hostGeneration === "v1") {
|
|
30282
|
+
const explicit = env.OPENCODE_DB;
|
|
30283
|
+
if (explicit !== undefined && explicit.length > 0)
|
|
30284
|
+
return explicit;
|
|
30285
|
+
if (env.OPENCODE_DISABLE_CHANNEL_DB === "1" || env.OPENCODE_DISABLE_CHANNEL_DB === "true") {
|
|
30286
|
+
return "opencode.db";
|
|
30287
|
+
}
|
|
30288
|
+
return ["latest", "beta", "prod"].includes(channel) ? "opencode.db" : `opencode-${channel}.db`;
|
|
30289
|
+
}
|
|
30290
|
+
return env.OPENCODE_DB ?? (["latest", "dev", "beta", "next", "prod"].includes(channel) || env.OPENCODE_DISABLE_CHANNEL_DB === "1" || env.OPENCODE_DISABLE_CHANNEL_DB === "true" ? "opencode.db" : `opencode-${channel.replace(/[^a-zA-Z0-9._-]/g, "")}.db`);
|
|
30291
|
+
}
|
|
30292
|
+
function resolveV2Fresh(dataDir, channel, env) {
|
|
30293
|
+
const filename = sourceOpenCodeDatabaseFilename("v2", channel, env);
|
|
30294
|
+
const explicit = env.OPENCODE_DB !== undefined;
|
|
30295
|
+
return {
|
|
30296
|
+
path: filename === ":memory:" ? filename : join16(dataDir, filename),
|
|
30297
|
+
source: explicit ? "OPENCODE_DB" : env.OPENCODE_CHANNEL ? "channel" : "default",
|
|
30298
|
+
channel: explicit ? null : channel
|
|
30299
|
+
};
|
|
30300
|
+
}
|
|
30301
|
+
function resolveOpenCodeDbPath(hostGeneration = "v1", options = {}) {
|
|
30302
|
+
const env = options.env ?? process.env;
|
|
30303
|
+
const dataDir = openCodeDataDir(env, options.dataHome);
|
|
30304
|
+
const channel = options.channel ?? env.OPENCODE_CHANNEL;
|
|
30305
|
+
const key = environmentKey(dataDir, hostGeneration, channel, env);
|
|
30122
30306
|
if (cachedResolution?.key === key && (!cachedResolution.existed || existsSync19(cachedResolution.resolution.path))) {
|
|
30123
30307
|
if (cachedResolution.existed)
|
|
30124
30308
|
return cachedResolution.resolution;
|
|
30125
30309
|
}
|
|
30126
|
-
const resolution =
|
|
30310
|
+
const resolution = hostGeneration === "v2" ? resolveV2Fresh(dataDir, channel ?? "latest", env) : resolveV1Fresh(dataDir, env);
|
|
30127
30311
|
cachedResolution = {
|
|
30128
30312
|
key,
|
|
30129
30313
|
resolution,
|
|
@@ -30131,6 +30315,29 @@ function resolveOpenCodeDbPath() {
|
|
|
30131
30315
|
};
|
|
30132
30316
|
return resolution;
|
|
30133
30317
|
}
|
|
30318
|
+
function schemaTableNames(db, schema = "main") {
|
|
30319
|
+
const rows = db.prepare(`SELECT name FROM ${schema}.sqlite_master WHERE type = 'table' AND name IN ('message', 'part', 'session', 'project', 'session_message')`).all();
|
|
30320
|
+
return new Set(rows.flatMap((row) => typeof row.name === "string" ? [row.name] : []));
|
|
30321
|
+
}
|
|
30322
|
+
function detectOpenCodeStoreGeneration(db, schema = "main") {
|
|
30323
|
+
const tables = schemaTableNames(db, schema);
|
|
30324
|
+
const hasV1Messages = tables.has("message") && tables.has("part");
|
|
30325
|
+
if (hasV1Messages)
|
|
30326
|
+
return "v1";
|
|
30327
|
+
if (tables.has("session_message"))
|
|
30328
|
+
return "v2";
|
|
30329
|
+
if (tables.has("session") || tables.has("project"))
|
|
30330
|
+
return "v1";
|
|
30331
|
+
return "unknown";
|
|
30332
|
+
}
|
|
30333
|
+
function assertOpenCodeStoreGeneration(db, expected, path, schema = "main") {
|
|
30334
|
+
const actual = detectOpenCodeStoreGeneration(db, schema);
|
|
30335
|
+
if (actual === expected)
|
|
30336
|
+
return;
|
|
30337
|
+
if (actual === "unknown")
|
|
30338
|
+
return;
|
|
30339
|
+
throw new Error(`OpenCode store generation mismatch at ${path}: expected ${expected}, found ${actual}; refusing generation-specific database access`);
|
|
30340
|
+
}
|
|
30134
30341
|
function openCodeDbPathExists(resolution = resolveOpenCodeDbPath()) {
|
|
30135
30342
|
return resolution.path !== ":memory:" && existsSync19(resolution.path);
|
|
30136
30343
|
}
|
|
@@ -30415,7 +30622,7 @@ function initializeDatabase(db, busyTimeoutMs = BOOT_SQLITE_BUSY_TIMEOUT_MS) {
|
|
|
30415
30622
|
tag_id INTEGER,
|
|
30416
30623
|
session_id TEXT,
|
|
30417
30624
|
content TEXT,
|
|
30418
|
-
created_at INTEGER,
|
|
30625
|
+
created_at INTEGER, -- epoch ms; Date.now() on source writes, preserved on session clones
|
|
30419
30626
|
harness TEXT NOT NULL DEFAULT 'opencode',
|
|
30420
30627
|
PRIMARY KEY(session_id, tag_id)
|
|
30421
30628
|
);
|
|
@@ -30439,7 +30646,7 @@ function initializeDatabase(db, busyTimeoutMs = BOOT_SQLITE_BUSY_TIMEOUT_MS) {
|
|
|
30439
30646
|
p1_embedding BLOB,
|
|
30440
30647
|
p1_embedding_model_id TEXT,
|
|
30441
30648
|
legacy INTEGER NOT NULL DEFAULT 0,
|
|
30442
|
-
created_at INTEGER NOT NULL,
|
|
30649
|
+
created_at INTEGER NOT NULL, -- epoch ms (Date.now())
|
|
30443
30650
|
harness TEXT NOT NULL DEFAULT 'opencode',
|
|
30444
30651
|
UNIQUE(session_id, sequence)
|
|
30445
30652
|
);
|
|
@@ -30458,7 +30665,7 @@ function initializeDatabase(db, busyTimeoutMs = BOOT_SQLITE_BUSY_TIMEOUT_MS) {
|
|
|
30458
30665
|
model_id TEXT NOT NULL,
|
|
30459
30666
|
dims INTEGER NOT NULL,
|
|
30460
30667
|
vector BLOB NOT NULL,
|
|
30461
|
-
created_at INTEGER NOT NULL,
|
|
30668
|
+
created_at INTEGER NOT NULL, -- epoch ms (Date.now())
|
|
30462
30669
|
UNIQUE(compartment_id, model_id, window_index)
|
|
30463
30670
|
);
|
|
30464
30671
|
CREATE INDEX IF NOT EXISTS idx_cce_session ON compartment_chunk_embeddings(session_id);
|
|
@@ -30481,7 +30688,7 @@ function initializeDatabase(db, busyTimeoutMs = BOOT_SQLITE_BUSY_TIMEOUT_MS) {
|
|
|
30481
30688
|
kind TEXT NOT NULL,
|
|
30482
30689
|
at_compartment INTEGER,
|
|
30483
30690
|
fields_json TEXT NOT NULL DEFAULT '{}',
|
|
30484
|
-
created_at INTEGER NOT NULL,
|
|
30691
|
+
created_at INTEGER NOT NULL, -- epoch ms (Date.now())
|
|
30485
30692
|
harness TEXT NOT NULL DEFAULT 'opencode'
|
|
30486
30693
|
);
|
|
30487
30694
|
CREATE INDEX IF NOT EXISTS idx_compartment_events_session
|
|
@@ -30510,7 +30717,7 @@ function initializeDatabase(db, busyTimeoutMs = BOOT_SQLITE_BUSY_TIMEOUT_MS) {
|
|
|
30510
30717
|
session_id TEXT NOT NULL,
|
|
30511
30718
|
category TEXT NOT NULL,
|
|
30512
30719
|
content TEXT NOT NULL,
|
|
30513
|
-
created_at INTEGER NOT NULL,
|
|
30720
|
+
created_at INTEGER NOT NULL, -- epoch ms (Date.now())
|
|
30514
30721
|
updated_at INTEGER NOT NULL,
|
|
30515
30722
|
harness TEXT NOT NULL DEFAULT 'opencode'
|
|
30516
30723
|
);
|
|
@@ -30529,7 +30736,7 @@ function initializeDatabase(db, busyTimeoutMs = BOOT_SQLITE_BUSY_TIMEOUT_MS) {
|
|
|
30529
30736
|
source_message_time INTEGER NOT NULL,
|
|
30530
30737
|
question_embedding BLOB,
|
|
30531
30738
|
question_embedding_model_id TEXT,
|
|
30532
|
-
created_at INTEGER NOT NULL,
|
|
30739
|
+
created_at INTEGER NOT NULL, -- epoch ms (Date.now())
|
|
30533
30740
|
UNIQUE(project_path, harness, session_id, source_start_message_id, source_end_message_id)
|
|
30534
30741
|
);
|
|
30535
30742
|
CREATE INDEX IF NOT EXISTS idx_primer_candidates_project_time
|
|
@@ -30552,7 +30759,7 @@ function initializeDatabase(db, busyTimeoutMs = BOOT_SQLITE_BUSY_TIMEOUT_MS) {
|
|
|
30552
30759
|
answer_refreshed_at INTEGER,
|
|
30553
30760
|
source_candidate_ids TEXT NOT NULL DEFAULT '[]',
|
|
30554
30761
|
source_candidate_provenance TEXT,
|
|
30555
|
-
created_at INTEGER NOT NULL,
|
|
30762
|
+
created_at INTEGER NOT NULL, -- epoch ms (Date.now())
|
|
30556
30763
|
updated_at INTEGER NOT NULL
|
|
30557
30764
|
);
|
|
30558
30765
|
CREATE INDEX IF NOT EXISTS idx_primers_project_status_observed
|
|
@@ -30665,7 +30872,7 @@ function initializeDatabase(db, busyTimeoutMs = BOOT_SQLITE_BUSY_TIMEOUT_MS) {
|
|
|
30665
30872
|
job_id TEXT,
|
|
30666
30873
|
cursor TEXT,
|
|
30667
30874
|
status TEXT NOT NULL DEFAULT 'pending',
|
|
30668
|
-
created_at INTEGER NOT NULL DEFAULT 0,
|
|
30875
|
+
created_at INTEGER NOT NULL DEFAULT 0, -- epoch ms (Date.now())
|
|
30669
30876
|
updated_at INTEGER NOT NULL DEFAULT 0,
|
|
30670
30877
|
UNIQUE(session_id, request_key)
|
|
30671
30878
|
);
|
|
@@ -30706,7 +30913,7 @@ function initializeDatabase(db, busyTimeoutMs = BOOT_SQLITE_BUSY_TIMEOUT_MS) {
|
|
|
30706
30913
|
shadow_epoch INTEGER NOT NULL DEFAULT 0,
|
|
30707
30914
|
corpus_hash TEXT NOT NULL DEFAULT '',
|
|
30708
30915
|
coverage_json TEXT NOT NULL DEFAULT '{}',
|
|
30709
|
-
created_at INTEGER NOT NULL DEFAULT 0,
|
|
30916
|
+
created_at INTEGER NOT NULL DEFAULT 0, -- epoch ms (Date.now())
|
|
30710
30917
|
UNIQUE(dedup_key, cohort_key)
|
|
30711
30918
|
);
|
|
30712
30919
|
CREATE INDEX IF NOT EXISTS idx_embedding_measurement_session
|
|
@@ -31129,7 +31336,7 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
31129
31336
|
importance_avg REAL,
|
|
31130
31337
|
discarded_last INTEGER NOT NULL DEFAULT 0,
|
|
31131
31338
|
legacy INTEGER NOT NULL DEFAULT 0,
|
|
31132
|
-
created_at INTEGER NOT NULL
|
|
31339
|
+
created_at INTEGER NOT NULL -- epoch ms (Date.now())
|
|
31133
31340
|
);
|
|
31134
31341
|
CREATE INDEX IF NOT EXISTS idx_historian_runs_session
|
|
31135
31342
|
ON historian_runs(session_id, created_at DESC);
|
|
@@ -31182,7 +31389,7 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
31182
31389
|
importance INTEGER NOT NULL DEFAULT 50,
|
|
31183
31390
|
episode_type TEXT,
|
|
31184
31391
|
pass_number INTEGER NOT NULL,
|
|
31185
|
-
created_at INTEGER NOT NULL,
|
|
31392
|
+
created_at INTEGER NOT NULL, -- epoch ms (Date.now())
|
|
31186
31393
|
harness TEXT NOT NULL DEFAULT 'opencode',
|
|
31187
31394
|
UNIQUE(session_id, sequence)
|
|
31188
31395
|
);
|
|
@@ -31193,7 +31400,7 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
31193
31400
|
category TEXT NOT NULL,
|
|
31194
31401
|
content TEXT NOT NULL,
|
|
31195
31402
|
pass_number INTEGER NOT NULL,
|
|
31196
|
-
created_at INTEGER NOT NULL,
|
|
31403
|
+
created_at INTEGER NOT NULL, -- epoch ms (Date.now())
|
|
31197
31404
|
harness TEXT NOT NULL DEFAULT 'opencode'
|
|
31198
31405
|
);
|
|
31199
31406
|
|
|
@@ -31526,7 +31733,7 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
31526
31733
|
`);
|
|
31527
31734
|
ensureColumn(db, "workspaces", "share_categories", `TEXT NOT NULL DEFAULT '["CONSTRAINTS"]'`);
|
|
31528
31735
|
}
|
|
31529
|
-
var databases, pendingAsyncOpens, persistenceByDatabase, persistenceErrorByDatabase, pathByDatabase, LATEST_SUPPORTED_VERSION =
|
|
31736
|
+
var databases, pendingAsyncOpens, persistenceByDatabase, persistenceErrorByDatabase, pathByDatabase, LATEST_SUPPORTED_VERSION = 85, BOOT_SQLITE_BUSY_TIMEOUT_MS = 5000, PERMISSIONS_ENFORCEABLE, RPC_DISCOVERY_PARSE_GRACE_MS, defaultRpcDiscoveryFs, rpcDiscoveryFs, sqlitePragmaConfig, CHANNEL2_CLAIM_TTL_MS;
|
|
31530
31737
|
var init_storage_db = __esm(async () => {
|
|
31531
31738
|
init_data_path();
|
|
31532
31739
|
init_logger();
|
|
@@ -32683,6 +32890,81 @@ var init_doctor_repair_db = __esm(async () => {
|
|
|
32683
32890
|
];
|
|
32684
32891
|
});
|
|
32685
32892
|
|
|
32893
|
+
// src/commands/doctor-hidden-sessions.ts
|
|
32894
|
+
function parseMetadata(value) {
|
|
32895
|
+
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
32896
|
+
return value;
|
|
32897
|
+
}
|
|
32898
|
+
if (typeof value !== "string")
|
|
32899
|
+
return null;
|
|
32900
|
+
try {
|
|
32901
|
+
const parsed = JSON.parse(value);
|
|
32902
|
+
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
|
|
32903
|
+
} catch {
|
|
32904
|
+
return null;
|
|
32905
|
+
}
|
|
32906
|
+
}
|
|
32907
|
+
function listHiddenSessionsFromDatabase(database) {
|
|
32908
|
+
const columns = new Set(database.prepare("PRAGMA table_info(session)").all().flatMap((row) => row && typeof row === "object" && typeof row.name === "string" ? [row.name] : []));
|
|
32909
|
+
if (!columns.has("metadata"))
|
|
32910
|
+
return [];
|
|
32911
|
+
const title = columns.has("title") ? "title" : "'' AS title";
|
|
32912
|
+
const directory = columns.has("directory") ? "directory" : "'' AS directory";
|
|
32913
|
+
const updatedAt = columns.has("time_updated") ? "time_updated" : columns.has("updated_at") ? "updated_at AS time_updated" : "NULL AS time_updated";
|
|
32914
|
+
const rows = database.prepare(`SELECT id, ${title}, ${directory}, ${updatedAt}, metadata
|
|
32915
|
+
FROM session
|
|
32916
|
+
WHERE metadata IS NOT NULL
|
|
32917
|
+
ORDER BY time_updated DESC, id ASC`).all();
|
|
32918
|
+
return rows.flatMap((row) => {
|
|
32919
|
+
const metadata = parseMetadata(row.metadata);
|
|
32920
|
+
if (metadata?.magic_context !== "hidden-run" || typeof row.id !== "string")
|
|
32921
|
+
return [];
|
|
32922
|
+
const role = metadata.role;
|
|
32923
|
+
return [
|
|
32924
|
+
{
|
|
32925
|
+
id: row.id,
|
|
32926
|
+
title: typeof row.title === "string" ? row.title : "",
|
|
32927
|
+
directory: typeof row.directory === "string" ? row.directory : "",
|
|
32928
|
+
role: role === "historian" || role === "dreamer" ? role : "unknown",
|
|
32929
|
+
updatedAt: typeof row.time_updated === "number" ? row.time_updated : null
|
|
32930
|
+
}
|
|
32931
|
+
];
|
|
32932
|
+
});
|
|
32933
|
+
}
|
|
32934
|
+
async function runListHiddenSessions() {
|
|
32935
|
+
const resolution = resolveOpenCodeDbPath("v2");
|
|
32936
|
+
if (!openCodeDbPathExists(resolution)) {
|
|
32937
|
+
console.log(`No OpenCode 2 session database found at ${resolution.path}.`);
|
|
32938
|
+
return 0;
|
|
32939
|
+
}
|
|
32940
|
+
const db = openExistingDatabase(resolution.path, { readonly: true });
|
|
32941
|
+
if (!db) {
|
|
32942
|
+
console.log(`No OpenCode 2 session database found at ${resolution.path}.`);
|
|
32943
|
+
return 0;
|
|
32944
|
+
}
|
|
32945
|
+
try {
|
|
32946
|
+
assertOpenCodeStoreGeneration(db, "v2", resolution.path);
|
|
32947
|
+
const sessions = listHiddenSessionsFromDatabase(db);
|
|
32948
|
+
if (sessions.length === 0) {
|
|
32949
|
+
console.log("No Magic Context hidden-run sessions found.");
|
|
32950
|
+
return 0;
|
|
32951
|
+
}
|
|
32952
|
+
console.log(`Magic Context hidden-run sessions (${sessions.length}):`);
|
|
32953
|
+
for (const session of sessions) {
|
|
32954
|
+
const location = session.directory ? ` ${session.directory}` : "";
|
|
32955
|
+
console.log(`- ${session.id} ${session.role} ${session.title}${location}`);
|
|
32956
|
+
}
|
|
32957
|
+
console.log("These are visible OpenCode 2 root sessions and are never deleted by Magic Context. Remove unwanted sessions manually in OpenCode.");
|
|
32958
|
+
return 0;
|
|
32959
|
+
} finally {
|
|
32960
|
+
db.close();
|
|
32961
|
+
}
|
|
32962
|
+
}
|
|
32963
|
+
var init_doctor_hidden_sessions = __esm(async () => {
|
|
32964
|
+
init_opencode_db_path();
|
|
32965
|
+
await init_database_access();
|
|
32966
|
+
});
|
|
32967
|
+
|
|
32686
32968
|
// src/lib/migration-paths.ts
|
|
32687
32969
|
function getOpenCodeDatabasePath() {
|
|
32688
32970
|
return resolveOpenCodeDbPath().path;
|
|
@@ -33291,6 +33573,7 @@ function migrateOpenCodeSessionToPi(opts) {
|
|
|
33291
33573
|
if (db === null) {
|
|
33292
33574
|
throw new Error(`OpenCode database not found at ${opencodeDbPath}; nothing to migrate.`);
|
|
33293
33575
|
}
|
|
33576
|
+
assertOpenCodeStoreGeneration(db, "v1", opencodeDbPath);
|
|
33294
33577
|
let cortexkitDb;
|
|
33295
33578
|
let ownsCortexkitDb = false;
|
|
33296
33579
|
let cortexkitSchemaVersionBefore = null;
|
|
@@ -33560,6 +33843,7 @@ var DEFAULT_PROVIDER = "openai-codex", DEFAULT_MODEL = "gpt-5.5", MIGRATION_COMP
|
|
|
33560
33843
|
FROM migration_pending WHERE migration_key = ?`;
|
|
33561
33844
|
var init_migrate = __esm(async () => {
|
|
33562
33845
|
init_data_path();
|
|
33846
|
+
init_opencode_db_path();
|
|
33563
33847
|
init_atomic_write();
|
|
33564
33848
|
init_migration_paths();
|
|
33565
33849
|
init_paths();
|
|
@@ -33969,6 +34253,7 @@ async function runMigrateSessionCli(args) {
|
|
|
33969
34253
|
if (opencodeDb === null) {
|
|
33970
34254
|
throw new Error(`OpenCode database not found at ${opencodeDbPath}; nothing to migrate.`);
|
|
33971
34255
|
}
|
|
34256
|
+
assertOpenCodeStoreGeneration(opencodeDb, "v1", opencodeDbPath);
|
|
33972
34257
|
contextDb = dryRun ? openExistingContextDatabase(contextDbPath, { readonly: true }) : openExistingContextDatabaseForMutation(contextDbPath);
|
|
33973
34258
|
if (contextDb === null) {
|
|
33974
34259
|
throw new Error(`Magic Context database not found at ${contextDbPath}; nothing to migrate.`);
|
|
@@ -34089,6 +34374,7 @@ var init_migrate_session = __esm(async () => {
|
|
|
34089
34374
|
init_storage_project_state();
|
|
34090
34375
|
init_module_transport();
|
|
34091
34376
|
init_data_path();
|
|
34377
|
+
init_opencode_db_path();
|
|
34092
34378
|
init_migration_paths();
|
|
34093
34379
|
init_prompts();
|
|
34094
34380
|
await __promiseAll([
|
|
@@ -34561,6 +34847,11 @@ function parsePiConfig(rawConfig, recoveredTopLevelKeys = []) {
|
|
|
34561
34847
|
}
|
|
34562
34848
|
delete patched[key];
|
|
34563
34849
|
const defaultValue = defaults[key];
|
|
34850
|
+
const invalidRawValue = rawConfig[key];
|
|
34851
|
+
if (key === "protected_tokens" && typeof invalidRawValue === "number" && invalidRawValue < PROTECTED_TOKENS_MIN) {
|
|
34852
|
+
warnings.push(`protected_tokens is a token floor (minimum ${PROTECTED_TOKENS_MIN}, default derived from the context window); ${invalidRawValue} looks like the old protected_tags count. Remove the key to use the default, or set a token count such as 16000.`);
|
|
34853
|
+
continue;
|
|
34854
|
+
}
|
|
34564
34855
|
warnings.push(`"${key}": invalid value (${redactConfigValue2(rawConfig[key])}), using default ${JSON.stringify(defaultValue)}.`);
|
|
34565
34856
|
}
|
|
34566
34857
|
const retryParsed = MagicContextConfigSchema.safeParse(patched);
|
|
@@ -36384,12 +36675,43 @@ function listShadowBackfillStalls(db, projectIdentity) {
|
|
|
36384
36675
|
}
|
|
36385
36676
|
var SHADOW_BACKFILL_PROVENANCE_KEY = "_magicContextShadowBackfill";
|
|
36386
36677
|
|
|
36678
|
+
// ../plugin/src/shared/auto-update-provenance.ts
|
|
36679
|
+
import { existsSync as existsSync28, readFileSync as readFileSync17 } from "node:fs";
|
|
36680
|
+
function readAutoUpdateCheckState(path) {
|
|
36681
|
+
if (!existsSync28(path))
|
|
36682
|
+
return null;
|
|
36683
|
+
try {
|
|
36684
|
+
const value = JSON.parse(readFileSync17(path, "utf-8"));
|
|
36685
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
36686
|
+
return null;
|
|
36687
|
+
const raw = value;
|
|
36688
|
+
const state = {};
|
|
36689
|
+
if (typeof raw.lastCheckedMs === "number" && Number.isFinite(raw.lastCheckedMs)) {
|
|
36690
|
+
state.lastCheckedMs = raw.lastCheckedMs;
|
|
36691
|
+
}
|
|
36692
|
+
if (typeof raw.updaterPinnedSpec === "string" && raw.updaterPinnedSpec.length > 0) {
|
|
36693
|
+
state.updaterPinnedSpec = raw.updaterPinnedSpec;
|
|
36694
|
+
}
|
|
36695
|
+
if (typeof raw.updaterPinnedAt === "number" && Number.isFinite(raw.updaterPinnedAt)) {
|
|
36696
|
+
state.updaterPinnedAt = raw.updaterPinnedAt;
|
|
36697
|
+
}
|
|
36698
|
+
return state;
|
|
36699
|
+
} catch {
|
|
36700
|
+
return null;
|
|
36701
|
+
}
|
|
36702
|
+
}
|
|
36703
|
+
function isUpdaterPinnedSpec(state, configuredSpec) {
|
|
36704
|
+
return state?.updaterPinnedSpec === configuredSpec && typeof state.updaterPinnedAt === "number" && Number.isFinite(state.updaterPinnedAt);
|
|
36705
|
+
}
|
|
36706
|
+
var AUTO_UPDATE_CHECK_STATE_FILENAME = "last-update-check.json";
|
|
36707
|
+
var init_auto_update_provenance = () => {};
|
|
36708
|
+
|
|
36387
36709
|
// ../plugin/src/shared/tui-config.ts
|
|
36388
36710
|
import {
|
|
36389
36711
|
chmodSync as chmodSync5,
|
|
36390
|
-
existsSync as
|
|
36712
|
+
existsSync as existsSync29,
|
|
36391
36713
|
mkdirSync as mkdirSync9,
|
|
36392
|
-
readFileSync as
|
|
36714
|
+
readFileSync as readFileSync18,
|
|
36393
36715
|
renameSync as renameSync6,
|
|
36394
36716
|
statSync as statSync13,
|
|
36395
36717
|
writeFileSync as writeFileSync6
|
|
@@ -36437,9 +36759,9 @@ function resolveTuiConfigPath(configDirOverride) {
|
|
|
36437
36759
|
const configDir = configDirOverride ?? getOpenCodeConfigPaths({ binary: "opencode" }).configDir;
|
|
36438
36760
|
const jsoncPath = join24(configDir, "tui.jsonc");
|
|
36439
36761
|
const jsonPath = join24(configDir, "tui.json");
|
|
36440
|
-
if (
|
|
36762
|
+
if (existsSync29(jsoncPath))
|
|
36441
36763
|
return jsoncPath;
|
|
36442
|
-
if (
|
|
36764
|
+
if (existsSync29(jsonPath))
|
|
36443
36765
|
return jsonPath;
|
|
36444
36766
|
return jsoncPath;
|
|
36445
36767
|
}
|
|
@@ -36447,8 +36769,8 @@ function ensureTuiPluginEntry(options = {}) {
|
|
|
36447
36769
|
try {
|
|
36448
36770
|
const configPath = resolveTuiConfigPath(options.configDir);
|
|
36449
36771
|
let config = {};
|
|
36450
|
-
if (
|
|
36451
|
-
const raw =
|
|
36772
|
+
if (existsSync29(configPath)) {
|
|
36773
|
+
const raw = readFileSync18(configPath, "utf-8");
|
|
36452
36774
|
config = import_comment_json8.parse(raw) ?? {};
|
|
36453
36775
|
}
|
|
36454
36776
|
const plugins = Array.isArray(config.plugin) ? [...config.plugin] : [];
|
|
@@ -36500,7 +36822,7 @@ var init_tui_config = __esm(() => {
|
|
|
36500
36822
|
});
|
|
36501
36823
|
|
|
36502
36824
|
// src/lib/diagnostics-opencode.ts
|
|
36503
|
-
import { existsSync as
|
|
36825
|
+
import { existsSync as existsSync30, readdirSync as readdirSync4, readFileSync as readFileSync19, statSync as statSync14 } from "node:fs";
|
|
36504
36826
|
import { createRequire as createRequire4 } from "node:module";
|
|
36505
36827
|
import { join as join25 } from "node:path";
|
|
36506
36828
|
function getSelfVersion() {
|
|
@@ -36520,8 +36842,8 @@ function getPluginCacheInfo() {
|
|
|
36520
36842
|
let cached;
|
|
36521
36843
|
for (const installedPkgPath of getOpenCodePluginPackageJsonPaths()) {
|
|
36522
36844
|
try {
|
|
36523
|
-
if (
|
|
36524
|
-
const pkg = JSON.parse(
|
|
36845
|
+
if (existsSync30(installedPkgPath)) {
|
|
36846
|
+
const pkg = JSON.parse(readFileSync19(installedPkgPath, "utf-8"));
|
|
36525
36847
|
cached = typeof pkg.version === "string" ? pkg.version : undefined;
|
|
36526
36848
|
if (cached)
|
|
36527
36849
|
break;
|
|
@@ -36537,7 +36859,7 @@ function getStorageResolution() {
|
|
|
36537
36859
|
}
|
|
36538
36860
|
function fileSize(path) {
|
|
36539
36861
|
try {
|
|
36540
|
-
return
|
|
36862
|
+
return existsSync30(path) ? statSync14(path).size : 0;
|
|
36541
36863
|
} catch {
|
|
36542
36864
|
return 0;
|
|
36543
36865
|
}
|
|
@@ -36549,10 +36871,10 @@ function sanitizeValue(value) {
|
|
|
36549
36871
|
return sanitizeConfigValue(value);
|
|
36550
36872
|
}
|
|
36551
36873
|
function readConfig3(path) {
|
|
36552
|
-
if (!
|
|
36874
|
+
if (!existsSync30(path))
|
|
36553
36875
|
return { value: null };
|
|
36554
36876
|
try {
|
|
36555
|
-
const raw =
|
|
36877
|
+
const raw = readFileSync19(path, "utf-8");
|
|
36556
36878
|
const value = import_comment_json9.parse(raw);
|
|
36557
36879
|
return { value };
|
|
36558
36880
|
} catch (error) {
|
|
@@ -36577,7 +36899,7 @@ function configHasPluginEntry(config) {
|
|
|
36577
36899
|
}
|
|
36578
36900
|
function parseHistorianDumpMeta(path) {
|
|
36579
36901
|
try {
|
|
36580
|
-
const xml =
|
|
36902
|
+
const xml = readFileSync19(path, "utf-8");
|
|
36581
36903
|
const parsed = parseCompartmentOutput(xml);
|
|
36582
36904
|
const factCountByCategory = {};
|
|
36583
36905
|
for (const fact of parsed.facts) {
|
|
@@ -36610,7 +36932,7 @@ function parseHistorianDumpMeta(path) {
|
|
|
36610
36932
|
}
|
|
36611
36933
|
}
|
|
36612
36934
|
function listDumpsInDir(dir, limit) {
|
|
36613
|
-
if (!
|
|
36935
|
+
if (!existsSync30(dir))
|
|
36614
36936
|
return { count: 0, recent: [] };
|
|
36615
36937
|
try {
|
|
36616
36938
|
const entries = readdirSync4(dir).filter((name) => name.endsWith(".xml")).map((name) => {
|
|
@@ -36733,7 +37055,7 @@ function collectRecentSessionsFromDatabase(database) {
|
|
|
36733
37055
|
return [{ sessionId, title, directory, lastActiveAt, parentSessionId }];
|
|
36734
37056
|
});
|
|
36735
37057
|
}
|
|
36736
|
-
async function collectRecentSessions(resolution) {
|
|
37058
|
+
async function collectRecentSessions(resolution, hostGeneration) {
|
|
36737
37059
|
const opencodeDbPath = resolution.path;
|
|
36738
37060
|
if (!openCodeDbPathExists(resolution))
|
|
36739
37061
|
return [];
|
|
@@ -36750,6 +37072,7 @@ async function collectRecentSessions(resolution) {
|
|
|
36750
37072
|
let db = null;
|
|
36751
37073
|
try {
|
|
36752
37074
|
db = new DatabaseClass(opencodeDbPath, { readonly: true });
|
|
37075
|
+
assertOpenCodeStoreGeneration(db, hostGeneration, opencodeDbPath);
|
|
36753
37076
|
return collectRecentSessionsFromDatabase(db);
|
|
36754
37077
|
} catch {
|
|
36755
37078
|
return [];
|
|
@@ -36761,7 +37084,7 @@ async function collectRecentSessions(resolution) {
|
|
|
36761
37084
|
}
|
|
36762
37085
|
async function collectHistorianFailures(storageDirPath) {
|
|
36763
37086
|
const contextDbPath = join25(storageDirPath, "context.db");
|
|
36764
|
-
if (!
|
|
37087
|
+
if (!existsSync30(contextDbPath))
|
|
36765
37088
|
return [];
|
|
36766
37089
|
if (typeof globalThis.Bun === "undefined") {
|
|
36767
37090
|
return [];
|
|
@@ -36795,7 +37118,7 @@ async function collectHistorianFailures(storageDirPath) {
|
|
|
36795
37118
|
}
|
|
36796
37119
|
async function collectHistorianRuns(storageDirPath) {
|
|
36797
37120
|
const contextDbPath = join25(storageDirPath, "context.db");
|
|
36798
|
-
if (!
|
|
37121
|
+
if (!existsSync30(contextDbPath))
|
|
36799
37122
|
return [];
|
|
36800
37123
|
if (typeof globalThis.Bun === "undefined")
|
|
36801
37124
|
return [];
|
|
@@ -36874,11 +37197,12 @@ async function collectDiagnostics() {
|
|
|
36874
37197
|
} catch (error) {
|
|
36875
37198
|
console.warn(`[magic-context] Could not load Magic Context config to resolve compaction mode; ` + `preserving existing native compaction fields. ` + `(${error instanceof Error ? error.message : String(error)})`);
|
|
36876
37199
|
}
|
|
36877
|
-
const conflictResult = detectConflicts(process.cwd(), { compactionEnabled });
|
|
36878
|
-
const openCodeDatabaseResolution = resolveOpenCodeDbPath();
|
|
36879
|
-
const recentSessions = await collectRecentSessions(openCodeDatabaseResolution);
|
|
36880
37200
|
const opencodeInstallations = describeOpenCodeInstallations(detectOpenCodeInstallations());
|
|
36881
37201
|
const activeInstallation = opencodeInstallations[0];
|
|
37202
|
+
const hostGeneration = openCodeHostGenerationFromVersion(activeInstallation?.version);
|
|
37203
|
+
const conflictResult = detectConflicts(process.cwd(), { compactionEnabled, hostGeneration });
|
|
37204
|
+
const openCodeDatabaseResolution = resolveOpenCodeDbPath(hostGeneration);
|
|
37205
|
+
const recentSessions = await collectRecentSessions(openCodeDatabaseResolution, hostGeneration);
|
|
36882
37206
|
let openCodeInstallKind = "none";
|
|
36883
37207
|
if (activeInstallation)
|
|
36884
37208
|
openCodeInstallKind = activeInstallation.kind;
|
|
@@ -36896,7 +37220,7 @@ async function collectDiagnostics() {
|
|
|
36896
37220
|
opencodeConfigHasPlugin: configHasPluginEntry(opencodeConfig.value),
|
|
36897
37221
|
tuiConfigHasPlugin: configHasPluginEntry(tuiConfig.value),
|
|
36898
37222
|
magicContextConfig: {
|
|
36899
|
-
exists:
|
|
37223
|
+
exists: existsSync30(configPaths.magicContextConfig),
|
|
36900
37224
|
...magicContextConfig.error ? { parseError: magicContextConfig.error } : {},
|
|
36901
37225
|
flags: sanitizeValue(magicContextConfig.value ?? {}) ?? {}
|
|
36902
37226
|
},
|
|
@@ -36904,7 +37228,7 @@ async function collectDiagnostics() {
|
|
|
36904
37228
|
storageDir: {
|
|
36905
37229
|
path: storageDirPath,
|
|
36906
37230
|
source: storageResolution.source,
|
|
36907
|
-
exists:
|
|
37231
|
+
exists: existsSync30(storageDirPath),
|
|
36908
37232
|
contextDbSizeBytes: fileSize(contextDbPath)
|
|
36909
37233
|
},
|
|
36910
37234
|
openCodeDatabase: {
|
|
@@ -37131,7 +37455,7 @@ var init_embedding_local = __esm(() => {
|
|
|
37131
37455
|
|
|
37132
37456
|
// src/lib/embedding-runtime.ts
|
|
37133
37457
|
import { spawnSync as spawnSync6 } from "node:child_process";
|
|
37134
|
-
import { existsSync as
|
|
37458
|
+
import { existsSync as existsSync31, readFileSync as readFileSync20 } from "node:fs";
|
|
37135
37459
|
import { createRequire as createRequire5 } from "node:module";
|
|
37136
37460
|
import { dirname as dirname16, join as join26, sep } from "node:path";
|
|
37137
37461
|
function describeError(error) {
|
|
@@ -37278,7 +37602,7 @@ function expectedBinaryRelPath(platform, arch) {
|
|
|
37278
37602
|
}
|
|
37279
37603
|
function onnxRuntimeNodeVersion(packageDir) {
|
|
37280
37604
|
try {
|
|
37281
|
-
const parsed = JSON.parse(
|
|
37605
|
+
const parsed = JSON.parse(readFileSync20(join26(packageDir, "package.json"), "utf8"));
|
|
37282
37606
|
return typeof parsed.version === "string" ? parsed.version : undefined;
|
|
37283
37607
|
} catch {
|
|
37284
37608
|
return;
|
|
@@ -37327,7 +37651,7 @@ function formatLocalEmbeddingRuntimeWasmSelected(status) {
|
|
|
37327
37651
|
function requireNodeWasmBundle(probe, candidates) {
|
|
37328
37652
|
if (probe.state === "failed")
|
|
37329
37653
|
return probe;
|
|
37330
|
-
const bundlePath = candidates.find((candidate) =>
|
|
37654
|
+
const bundlePath = candidates.find((candidate) => existsSync31(candidate));
|
|
37331
37655
|
return bundlePath ? probe : {
|
|
37332
37656
|
state: "failed",
|
|
37333
37657
|
reason: `functional Node WASM Transformers bundle is missing (checked ${candidates.join(", ")})`
|
|
@@ -37352,7 +37676,7 @@ function checkLocalEmbeddingRuntimeAt(installRoot, platform = process.platform,
|
|
|
37352
37676
|
}
|
|
37353
37677
|
const packageDir = join26(installRoot, "node_modules", "onnxruntime-node");
|
|
37354
37678
|
let native;
|
|
37355
|
-
if (!
|
|
37679
|
+
if (!existsSync31(join26(packageDir, "package.json"))) {
|
|
37356
37680
|
native = { state: "package-missing", packageDir };
|
|
37357
37681
|
} else {
|
|
37358
37682
|
const rel = expectedBinaryRelPath(platform, arch);
|
|
@@ -37363,7 +37687,7 @@ function checkLocalEmbeddingRuntimeAt(installRoot, platform = process.platform,
|
|
|
37363
37687
|
};
|
|
37364
37688
|
} else {
|
|
37365
37689
|
const binaryPath = join26(packageDir, rel);
|
|
37366
|
-
native =
|
|
37690
|
+
native = existsSync31(binaryPath) ? probeOnnxRuntimeNodeLoad(packageDir) ?? { state: "ok", binaryPath } : {
|
|
37367
37691
|
state: "binary-missing",
|
|
37368
37692
|
packageDir,
|
|
37369
37693
|
expectedBinary: binaryPath,
|
|
@@ -37374,7 +37698,7 @@ function checkLocalEmbeddingRuntimeAt(installRoot, platform = process.platform,
|
|
|
37374
37698
|
return withWasmFallback(native, () => probeWasmRuntimeAt(installRoot));
|
|
37375
37699
|
}
|
|
37376
37700
|
function checkLocalEmbeddingRuntime(installRoots, platform = process.platform, arch = process.arch, runtimePreference = "auto", host) {
|
|
37377
|
-
const existing = installRoots.filter((root) =>
|
|
37701
|
+
const existing = installRoots.filter((root) => existsSync31(root));
|
|
37378
37702
|
if (existing.length === 0) {
|
|
37379
37703
|
return {
|
|
37380
37704
|
state: "unknown",
|
|
@@ -37421,7 +37745,7 @@ function probeWasmRuntimeByResolution(pluginDir) {
|
|
|
37421
37745
|
}
|
|
37422
37746
|
}
|
|
37423
37747
|
function checkLocalEmbeddingRuntimeByResolution(pluginDir, platform = process.platform, arch = process.arch, runtimePreference = "auto", host) {
|
|
37424
|
-
if (!
|
|
37748
|
+
if (!existsSync31(join26(pluginDir, "package.json"))) {
|
|
37425
37749
|
return { state: "unknown", reason: "plugin package dir not found" };
|
|
37426
37750
|
}
|
|
37427
37751
|
const selectedRuntime = resolveLocalEmbeddingRuntime(runtimePreference, host);
|
|
@@ -37463,7 +37787,7 @@ function checkLocalEmbeddingRuntimeByResolution(pluginDir, platform = process.pl
|
|
|
37463
37787
|
native = probeOnnxRuntimeNodeLoad(onnxDir) ?? { state: "ok", binaryPath: onnxDir };
|
|
37464
37788
|
} else {
|
|
37465
37789
|
const binaryPath = join26(onnxDir, rel);
|
|
37466
|
-
native =
|
|
37790
|
+
native = existsSync31(binaryPath) ? probeOnnxRuntimeNodeLoad(onnxDir) ?? { state: "ok", binaryPath } : {
|
|
37467
37791
|
state: "binary-missing",
|
|
37468
37792
|
packageDir: onnxDir,
|
|
37469
37793
|
expectedBinary: binaryPath,
|
|
@@ -38023,9 +38347,9 @@ var init_types = __esm(() => {
|
|
|
38023
38347
|
// ../plugin/src/hooks/auto-update-checker/checker.ts
|
|
38024
38348
|
import {
|
|
38025
38349
|
accessSync as accessSync2,
|
|
38026
|
-
existsSync as
|
|
38350
|
+
existsSync as existsSync32,
|
|
38027
38351
|
constants as fsConstants,
|
|
38028
|
-
readFileSync as
|
|
38352
|
+
readFileSync as readFileSync21,
|
|
38029
38353
|
renameSync as renameSync7,
|
|
38030
38354
|
statSync as statSync15,
|
|
38031
38355
|
writeFileSync as writeFileSync8
|
|
@@ -38077,9 +38401,9 @@ function getWinningConfig(directory, surface) {
|
|
|
38077
38401
|
let winner = null;
|
|
38078
38402
|
for (const path of getSurfaceConfigPaths(directory, surface)) {
|
|
38079
38403
|
try {
|
|
38080
|
-
if (!
|
|
38404
|
+
if (!existsSync32(path))
|
|
38081
38405
|
continue;
|
|
38082
|
-
const parsed = parseJsonConfig(
|
|
38406
|
+
const parsed = parseJsonConfig(readFileSync21(path, "utf-8"));
|
|
38083
38407
|
const entries = getPluginEntries(parsed);
|
|
38084
38408
|
if (entries.some((entry) => entry === PACKAGE_NAME || entry.startsWith(`${PACKAGE_NAME}@`))) {
|
|
38085
38409
|
if (winner) {
|
|
@@ -38115,14 +38439,14 @@ var init_checker = __esm(() => {
|
|
|
38115
38439
|
});
|
|
38116
38440
|
|
|
38117
38441
|
// src/lib/opencode-plugin-schema-fence.ts
|
|
38118
|
-
import { existsSync as
|
|
38442
|
+
import { existsSync as existsSync33, readdirSync as readdirSync5, readFileSync as readFileSync22 } from "node:fs";
|
|
38119
38443
|
import { join as join30 } from "node:path";
|
|
38120
38444
|
import { gunzipSync } from "node:zlib";
|
|
38121
38445
|
function readPackageVersion(packageJsonPath) {
|
|
38122
38446
|
try {
|
|
38123
|
-
if (!
|
|
38447
|
+
if (!existsSync33(packageJsonPath))
|
|
38124
38448
|
return null;
|
|
38125
|
-
const packageJson = JSON.parse(
|
|
38449
|
+
const packageJson = JSON.parse(readFileSync22(packageJsonPath, "utf-8"));
|
|
38126
38450
|
if (packageJson.name !== OPENCODE_PLUGIN_NAME || typeof packageJson.version !== "string") {
|
|
38127
38451
|
return null;
|
|
38128
38452
|
}
|
|
@@ -38142,7 +38466,7 @@ function readFenceValue(text) {
|
|
|
38142
38466
|
}
|
|
38143
38467
|
function readFenceFromDist(packageDirectory) {
|
|
38144
38468
|
const distDirectory = join30(packageDirectory, "dist");
|
|
38145
|
-
if (!
|
|
38469
|
+
if (!existsSync33(distDirectory))
|
|
38146
38470
|
return null;
|
|
38147
38471
|
const pending = [distDirectory];
|
|
38148
38472
|
const fenceValues = new Set;
|
|
@@ -38159,7 +38483,7 @@ function readFenceFromDist(packageDirectory) {
|
|
|
38159
38483
|
}
|
|
38160
38484
|
if (!entry.isFile() || !/\.(?:[cm]?js|ts)$/.test(entry.name))
|
|
38161
38485
|
continue;
|
|
38162
|
-
const fence = readFenceValue(
|
|
38486
|
+
const fence = readFenceValue(readFileSync22(path, "utf-8"));
|
|
38163
38487
|
if (fence !== null)
|
|
38164
38488
|
fenceValues.add(fence);
|
|
38165
38489
|
}
|
|
@@ -38376,14 +38700,53 @@ var init_storage_versions = __esm(async () => {
|
|
|
38376
38700
|
await init_storage_db();
|
|
38377
38701
|
});
|
|
38378
38702
|
|
|
38703
|
+
// src/commands/doctor-compartment-boundaries.ts
|
|
38704
|
+
function listDanglingCompartmentBoundaries(contextDb, openCodeDb) {
|
|
38705
|
+
const generation = detectOpenCodeStoreGeneration(openCodeDb);
|
|
38706
|
+
if (generation === "unknown") {
|
|
38707
|
+
throw new Error("OpenCode session database has an unrecognized schema");
|
|
38708
|
+
}
|
|
38709
|
+
const rows = contextDb.prepare(`SELECT c.session_id, c.sequence, c.start_message_id, c.end_message_id
|
|
38710
|
+
FROM compartments AS c
|
|
38711
|
+
LEFT JOIN session_meta AS sm ON sm.session_id = c.session_id
|
|
38712
|
+
WHERE sm.harness IS NULL OR sm.harness IN ('opencode', 'opencode2')
|
|
38713
|
+
ORDER BY c.session_id ASC, c.sequence ASC`).all();
|
|
38714
|
+
const statement = openCodeDb.prepare(generation === "v2" ? "SELECT 1 AS found FROM session_message WHERE session_id = ? AND id = ? LIMIT 1" : "SELECT 1 AS found FROM message WHERE session_id = ? AND id = ? LIMIT 1");
|
|
38715
|
+
const exists = (sessionId, messageId) => statement.get(sessionId, messageId) != null;
|
|
38716
|
+
return rows.flatMap((row) => {
|
|
38717
|
+
const missingStart = !exists(row.session_id, row.start_message_id);
|
|
38718
|
+
const missingEnd = !exists(row.session_id, row.end_message_id);
|
|
38719
|
+
if (!missingStart && !missingEnd)
|
|
38720
|
+
return [];
|
|
38721
|
+
return [
|
|
38722
|
+
{
|
|
38723
|
+
sessionId: row.session_id,
|
|
38724
|
+
sequence: row.sequence,
|
|
38725
|
+
missingStartMessageId: missingStart ? row.start_message_id : null,
|
|
38726
|
+
missingEndMessageId: missingEnd ? row.end_message_id : null
|
|
38727
|
+
}
|
|
38728
|
+
];
|
|
38729
|
+
});
|
|
38730
|
+
}
|
|
38731
|
+
function formatDanglingCompartmentBoundary(boundary) {
|
|
38732
|
+
const missing = [
|
|
38733
|
+
boundary.missingStartMessageId ? `start_message_id=${boundary.missingStartMessageId}` : null,
|
|
38734
|
+
boundary.missingEndMessageId ? `end_message_id=${boundary.missingEndMessageId}` : null
|
|
38735
|
+
].filter((value) => value !== null);
|
|
38736
|
+
return `session=${boundary.sessionId} sequence=${boundary.sequence} missing ${missing.join(" ")}`;
|
|
38737
|
+
}
|
|
38738
|
+
var init_doctor_compartment_boundaries = __esm(() => {
|
|
38739
|
+
init_opencode_db_path();
|
|
38740
|
+
});
|
|
38741
|
+
|
|
38379
38742
|
// src/commands/doctor-opencode-cache.ts
|
|
38380
|
-
import { existsSync as
|
|
38743
|
+
import { existsSync as existsSync34, readFileSync as readFileSync23, rmSync as rmSync3 } from "node:fs";
|
|
38381
38744
|
function readCachedPluginVersion(pluginCacheDir) {
|
|
38382
38745
|
try {
|
|
38383
38746
|
const installedPkgPath = getOpenCodePluginPackageJsonPath(pluginCacheDir);
|
|
38384
|
-
if (!
|
|
38747
|
+
if (!existsSync34(installedPkgPath))
|
|
38385
38748
|
return;
|
|
38386
|
-
const pkg = JSON.parse(
|
|
38749
|
+
const pkg = JSON.parse(readFileSync23(installedPkgPath, "utf-8"));
|
|
38387
38750
|
return typeof pkg.version === "string" ? pkg.version : undefined;
|
|
38388
38751
|
} catch {
|
|
38389
38752
|
return;
|
|
@@ -38392,7 +38755,7 @@ function readCachedPluginVersion(pluginCacheDir) {
|
|
|
38392
38755
|
async function clearPluginCache(options = {}, deps = {}) {
|
|
38393
38756
|
const remove = deps.remove ?? ((path) => rmSync3(path, { recursive: true, force: true }));
|
|
38394
38757
|
const pluginCacheRoots = getOpenCodePluginCacheRoots();
|
|
38395
|
-
const existingRoots = pluginCacheRoots.filter((root) =>
|
|
38758
|
+
const existingRoots = pluginCacheRoots.filter((root) => existsSync34(root));
|
|
38396
38759
|
if (existingRoots.length === 0) {
|
|
38397
38760
|
return { action: "not_found", path: pluginCacheRoots[0] ?? "" };
|
|
38398
38761
|
}
|
|
@@ -38460,7 +38823,7 @@ var init_doctor_opencode_cache = __esm(() => {
|
|
|
38460
38823
|
|
|
38461
38824
|
// src/commands/doctor-opencode.ts
|
|
38462
38825
|
import { spawnSync as spawnSync7 } from "node:child_process";
|
|
38463
|
-
import { existsSync as
|
|
38826
|
+
import { existsSync as existsSync35, readFileSync as readFileSync24 } from "node:fs";
|
|
38464
38827
|
import { createRequire as createRequire6 } from "node:module";
|
|
38465
38828
|
import { homedir as homedir16 } from "node:os";
|
|
38466
38829
|
import { join as join31 } from "node:path";
|
|
@@ -38566,6 +38929,13 @@ function isPinnedOpenCodePluginSpecifier(specifier) {
|
|
|
38566
38929
|
return false;
|
|
38567
38930
|
return specifier.startsWith(`${OPENCODE_PLUGIN_NAME}@`);
|
|
38568
38931
|
}
|
|
38932
|
+
function describeAutoUpdateStall(specifier, autoUpdateEnabled, storageDir = getMagicContextStorageDir()) {
|
|
38933
|
+
if (!autoUpdateEnabled || !isPinnedOpenCodePluginSpecifier(specifier))
|
|
38934
|
+
return null;
|
|
38935
|
+
const state = readAutoUpdateCheckState(join31(storageDir, AUTO_UPDATE_CHECK_STATE_FILENAME));
|
|
38936
|
+
const owner = isUpdaterPinnedSpec(state, specifier) ? "updater" : "you";
|
|
38937
|
+
return `auto-update: stalled — config pinned to ${specifier} (by ${owner})`;
|
|
38938
|
+
}
|
|
38569
38939
|
function getUserNpmrcPath() {
|
|
38570
38940
|
const custom = process.env.NPM_CONFIG_USERCONFIG?.trim();
|
|
38571
38941
|
if (custom)
|
|
@@ -38576,10 +38946,10 @@ function getUserNpmrcPath() {
|
|
|
38576
38946
|
function collectNpmReleaseAgeWarnings() {
|
|
38577
38947
|
const ageWarnings = [];
|
|
38578
38948
|
const npmrcPath = getUserNpmrcPath();
|
|
38579
|
-
if (!
|
|
38949
|
+
if (!existsSync35(npmrcPath))
|
|
38580
38950
|
return ageWarnings;
|
|
38581
38951
|
try {
|
|
38582
|
-
const npmrc =
|
|
38952
|
+
const npmrc = readFileSync24(npmrcPath, "utf-8");
|
|
38583
38953
|
for (const line of npmrc.split(`
|
|
38584
38954
|
`)) {
|
|
38585
38955
|
const trimmed = line.trim();
|
|
@@ -38713,7 +39083,7 @@ function checkLocalEmbeddingRuntimeForDoctor(runtimePreference = "auto") {
|
|
|
38713
39083
|
return { issues: 0 };
|
|
38714
39084
|
}
|
|
38715
39085
|
async function checkEmbeddingConfig(magicContextConfigPath) {
|
|
38716
|
-
if (!
|
|
39086
|
+
if (!existsSync35(magicContextConfigPath)) {
|
|
38717
39087
|
return checkLocalEmbeddingRuntimeForDoctor();
|
|
38718
39088
|
}
|
|
38719
39089
|
let rawText;
|
|
@@ -38935,11 +39305,42 @@ async function runDoctor2(options = {}) {
|
|
|
38935
39305
|
} else {
|
|
38936
39306
|
pass(installationReports.length > 1 ? `OpenCode ${activeInstallation.version} installed (active install marked above)` : `OpenCode ${activeInstallation.version} installed`);
|
|
38937
39307
|
}
|
|
38938
|
-
const
|
|
39308
|
+
const hostGeneration = openCodeHostGenerationFromVersion(activeInstallation.version);
|
|
39309
|
+
const openCodeDbResolution = resolveOpenCodeDbPath(hostGeneration);
|
|
39310
|
+
const openCodeDbCheck = describeOpenCodeDatabaseDoctorCheck(openCodeDbResolution);
|
|
38939
39311
|
if (openCodeDbCheck.ok)
|
|
38940
39312
|
pass(openCodeDbCheck.message);
|
|
38941
39313
|
else
|
|
38942
39314
|
fail(openCodeDbCheck.message);
|
|
39315
|
+
if (openCodeDbCheck.ok) {
|
|
39316
|
+
let contextDb = null;
|
|
39317
|
+
let sessionDb = null;
|
|
39318
|
+
try {
|
|
39319
|
+
contextDb = openExistingContextDatabase(authorityDbPath, { readonly: true });
|
|
39320
|
+
if (contextDb) {
|
|
39321
|
+
sessionDb = new Database(openCodeDbResolution.path, {
|
|
39322
|
+
readonly: true,
|
|
39323
|
+
fileMustExist: true
|
|
39324
|
+
});
|
|
39325
|
+
const dangling = listDanglingCompartmentBoundaries(contextDb, sessionDb);
|
|
39326
|
+
if (dangling.length === 0) {
|
|
39327
|
+
pass("Compartment boundary ids resolve in the OpenCode session store");
|
|
39328
|
+
} else {
|
|
39329
|
+
warn(`${dangling.length} compartment(s) have dangling OpenCode boundary ids`);
|
|
39330
|
+
for (const boundary of dangling) {
|
|
39331
|
+
log2.warn(` ${formatDanglingCompartmentBoundary(boundary)}`);
|
|
39332
|
+
}
|
|
39333
|
+
}
|
|
39334
|
+
} else {
|
|
39335
|
+
log2.info("Compartment boundary check: no context database found");
|
|
39336
|
+
}
|
|
39337
|
+
} catch (error) {
|
|
39338
|
+
warn(`Compartment boundary check unavailable: ${error instanceof Error ? error.message : String(error)}`);
|
|
39339
|
+
} finally {
|
|
39340
|
+
sessionDb?.close();
|
|
39341
|
+
contextDb?.close();
|
|
39342
|
+
}
|
|
39343
|
+
}
|
|
38943
39344
|
const selfVersion = getSelfVersion2();
|
|
38944
39345
|
const [npmLatest, pluginNpmLatest] = await Promise.all([
|
|
38945
39346
|
fetchNpmLatest(CLI_PACKAGE_NAME),
|
|
@@ -38958,7 +39359,8 @@ async function runDoctor2(options = {}) {
|
|
|
38958
39359
|
} else {
|
|
38959
39360
|
pass(`OpenCode config: ${paths.opencodeConfig}`);
|
|
38960
39361
|
}
|
|
38961
|
-
|
|
39362
|
+
let autoUpdateEnabled = true;
|
|
39363
|
+
if (existsSync35(paths.magicContextConfig)) {
|
|
38962
39364
|
pass(`Magic Context config: ${paths.magicContextConfig}`);
|
|
38963
39365
|
try {
|
|
38964
39366
|
const raw = loadRawConfigFile({ configPath: paths.magicContextConfig, tier: "user" });
|
|
@@ -38979,6 +39381,7 @@ async function runDoctor2(options = {}) {
|
|
|
38979
39381
|
}
|
|
38980
39382
|
try {
|
|
38981
39383
|
const result = loadPluginConfig(process.cwd());
|
|
39384
|
+
autoUpdateEnabled = result.auto_update !== false;
|
|
38982
39385
|
const warnings = result.configWarnings ?? [];
|
|
38983
39386
|
if (warnings.length > 0) {
|
|
38984
39387
|
warn(`Magic Context config has ${warnings.length} warning(s) — see 'magic-context doctor --issue' for details`);
|
|
@@ -38992,7 +39395,7 @@ async function runDoctor2(options = {}) {
|
|
|
38992
39395
|
warn(`No magic-context.jsonc found — using defaults`);
|
|
38993
39396
|
log2.info(" Run 'setup' to create one with model recommendations");
|
|
38994
39397
|
}
|
|
38995
|
-
if (
|
|
39398
|
+
if (existsSync35(paths.magicContextConfig)) {
|
|
38996
39399
|
try {
|
|
38997
39400
|
const raw = loadRawConfigFile({ configPath: paths.magicContextConfig, tier: "user" });
|
|
38998
39401
|
if (!raw)
|
|
@@ -39112,9 +39515,17 @@ async function runDoctor2(options = {}) {
|
|
|
39112
39515
|
log2.warn("Could not migrate deprecated config keys in magic-context.jsonc");
|
|
39113
39516
|
}
|
|
39114
39517
|
}
|
|
39518
|
+
const reportedAutoUpdateStalls = new Set;
|
|
39519
|
+
const reportAutoUpdateStall = (specifier) => {
|
|
39520
|
+
const message = describeAutoUpdateStall(specifier, autoUpdateEnabled);
|
|
39521
|
+
if (!message || reportedAutoUpdateStalls.has(message))
|
|
39522
|
+
return;
|
|
39523
|
+
reportedAutoUpdateStalls.add(message);
|
|
39524
|
+
warn(message);
|
|
39525
|
+
};
|
|
39115
39526
|
if (paths.opencodeConfigFormat !== "none") {
|
|
39116
39527
|
try {
|
|
39117
|
-
const raw =
|
|
39528
|
+
const raw = readFileSync24(paths.opencodeConfig, "utf-8");
|
|
39118
39529
|
const config = import_comment_json11.parse(raw);
|
|
39119
39530
|
const rawPlugins = Array.isArray(config?.plugin) ? config.plugin : [];
|
|
39120
39531
|
const existingIdx = rawPlugins.findIndex((entry) => matchesPluginEntry(entry, OPENCODE_PLUGIN_NAME) || isDevPathPluginEntry(entry));
|
|
@@ -39139,6 +39550,7 @@ async function runDoctor2(options = {}) {
|
|
|
39139
39550
|
} else {
|
|
39140
39551
|
const isPinned = isPinnedOpenCodePluginSpecifier(oldEntryStr);
|
|
39141
39552
|
if (isPinned && !options.force) {
|
|
39553
|
+
reportAutoUpdateStall(oldEntryStr);
|
|
39142
39554
|
warn(`Plugin pinned to ${oldEntryStr} in ${configName} — use 'doctor --force' to upgrade`);
|
|
39143
39555
|
} else {
|
|
39144
39556
|
if (Array.isArray(oldEntry) && oldEntry.length >= 1) {
|
|
@@ -39199,9 +39611,9 @@ async function runDoctor2(options = {}) {
|
|
|
39199
39611
|
pass("Added TUI sidebar plugin to tui.json");
|
|
39200
39612
|
warn("Restart OpenCode to see the sidebar");
|
|
39201
39613
|
fixed++;
|
|
39202
|
-
} else if (
|
|
39614
|
+
} else if (existsSync35(paths.tuiConfig)) {
|
|
39203
39615
|
try {
|
|
39204
|
-
const tuiRaw =
|
|
39616
|
+
const tuiRaw = readFileSync24(paths.tuiConfig, "utf-8");
|
|
39205
39617
|
const tuiConfig = import_comment_json11.parse(tuiRaw);
|
|
39206
39618
|
const tuiRawPlugins = Array.isArray(tuiConfig?.plugin) ? tuiConfig.plugin : [];
|
|
39207
39619
|
const tuiIdx = tuiRawPlugins.findIndex((entry) => matchesPluginEntry(entry, OPENCODE_PLUGIN_NAME) || isDevPathPluginEntry(entry));
|
|
@@ -39223,6 +39635,7 @@ async function runDoctor2(options = {}) {
|
|
|
39223
39635
|
} else {
|
|
39224
39636
|
const tuiPinned = isPinnedOpenCodePluginSpecifier(tuiEntryStr);
|
|
39225
39637
|
if (tuiPinned && !options.force) {
|
|
39638
|
+
reportAutoUpdateStall(tuiEntryStr);
|
|
39226
39639
|
warn(`TUI plugin pinned to ${tuiEntryStr} — use 'doctor --force' to upgrade`);
|
|
39227
39640
|
} else if (tuiPinned && options.force) {
|
|
39228
39641
|
if (Array.isArray(tuiEntry) && tuiEntry.length >= 1) {
|
|
@@ -39250,7 +39663,7 @@ async function runDoctor2(options = {}) {
|
|
|
39250
39663
|
} else {
|
|
39251
39664
|
fail("Could not create or verify the TUI sidebar config");
|
|
39252
39665
|
}
|
|
39253
|
-
if (
|
|
39666
|
+
if (existsSync35(paths.magicContextConfig)) {
|
|
39254
39667
|
try {
|
|
39255
39668
|
const raw = loadRawConfigFile({ configPath: paths.magicContextConfig, tier: "user" });
|
|
39256
39669
|
if (!raw)
|
|
@@ -39274,7 +39687,7 @@ async function runDoctor2(options = {}) {
|
|
|
39274
39687
|
const storage = getMagicContextStorageResolution();
|
|
39275
39688
|
const dbPath = join31(storage.path, "context.db");
|
|
39276
39689
|
log2.info(`Shared storage: ${storage.path} (source: ${storage.source})`);
|
|
39277
|
-
if (!
|
|
39690
|
+
if (!existsSync35(dbPath)) {
|
|
39278
39691
|
log2.info(`Shared context DB not yet created at ${dbPath} (will be created on first run)`);
|
|
39279
39692
|
} else {
|
|
39280
39693
|
log2.info(`Shared context DB exists at ${dbPath}`);
|
|
@@ -39454,6 +39867,7 @@ var init_doctor_opencode = __esm(async () => {
|
|
|
39454
39867
|
init_removed_agent_config();
|
|
39455
39868
|
init_variable();
|
|
39456
39869
|
init_embedding_synapse();
|
|
39870
|
+
init_auto_update_provenance();
|
|
39457
39871
|
init_conflict_detector();
|
|
39458
39872
|
init_conflict_fixer();
|
|
39459
39873
|
init_data_path();
|
|
@@ -39476,9 +39890,11 @@ var init_doctor_opencode = __esm(async () => {
|
|
|
39476
39890
|
init_paths();
|
|
39477
39891
|
init_prompts();
|
|
39478
39892
|
init_redaction2();
|
|
39893
|
+
init_doctor_compartment_boundaries();
|
|
39479
39894
|
init_doctor_opencode_cache();
|
|
39480
39895
|
await __promiseAll([
|
|
39481
39896
|
init_storage_db(),
|
|
39897
|
+
init_sqlite(),
|
|
39482
39898
|
init_database_access(),
|
|
39483
39899
|
init_storage_versions(),
|
|
39484
39900
|
init_v22_backfill_commands(),
|
|
@@ -39488,7 +39904,7 @@ var init_doctor_opencode = __esm(async () => {
|
|
|
39488
39904
|
});
|
|
39489
39905
|
|
|
39490
39906
|
// src/lib/diagnostics-pi.ts
|
|
39491
|
-
import { existsSync as
|
|
39907
|
+
import { existsSync as existsSync36, readdirSync as readdirSync6, readFileSync as readFileSync25, statSync as statSync16 } from "node:fs";
|
|
39492
39908
|
import { createRequire as createRequire7 } from "node:module";
|
|
39493
39909
|
import { join as join32 } from "node:path";
|
|
39494
39910
|
function getSelfVersion3() {
|
|
@@ -39505,7 +39921,7 @@ function getSelfVersion3() {
|
|
|
39505
39921
|
}
|
|
39506
39922
|
function fileSize2(path) {
|
|
39507
39923
|
try {
|
|
39508
|
-
return
|
|
39924
|
+
return existsSync36(path) ? statSync16(path).size : 0;
|
|
39509
39925
|
} catch {
|
|
39510
39926
|
return 0;
|
|
39511
39927
|
}
|
|
@@ -39517,11 +39933,11 @@ function sanitizeValue2(value) {
|
|
|
39517
39933
|
return sanitizeConfigValue(value);
|
|
39518
39934
|
}
|
|
39519
39935
|
function readJsonc(path) {
|
|
39520
|
-
if (!
|
|
39936
|
+
if (!existsSync36(path))
|
|
39521
39937
|
return { value: {} };
|
|
39522
39938
|
try {
|
|
39523
39939
|
return {
|
|
39524
|
-
value: import_comment_json12.parse(
|
|
39940
|
+
value: import_comment_json12.parse(readFileSync25(path, "utf-8"))
|
|
39525
39941
|
};
|
|
39526
39942
|
} catch (error) {
|
|
39527
39943
|
return {
|
|
@@ -39537,7 +39953,7 @@ function readConfigDiagnostic(path) {
|
|
|
39537
39953
|
const parsed = readJsonc(path);
|
|
39538
39954
|
return {
|
|
39539
39955
|
path,
|
|
39540
|
-
exists:
|
|
39956
|
+
exists: existsSync36(path),
|
|
39541
39957
|
...parsed.parseError ? { parseError: parsed.parseError } : {},
|
|
39542
39958
|
flags: sanitizeValue2(parsed.value)
|
|
39543
39959
|
};
|
|
@@ -39555,7 +39971,7 @@ function reverseSlugToDirectory(slug) {
|
|
|
39555
39971
|
}
|
|
39556
39972
|
function collectPiRecentSessions() {
|
|
39557
39973
|
const sessionsRoot = getPiSessionsRoot();
|
|
39558
|
-
if (!
|
|
39974
|
+
if (!existsSync36(sessionsRoot))
|
|
39559
39975
|
return [];
|
|
39560
39976
|
try {
|
|
39561
39977
|
const slugs = readdirSync6(sessionsRoot, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name);
|
|
@@ -39591,7 +40007,7 @@ function collectPiRecentSessions() {
|
|
|
39591
40007
|
}
|
|
39592
40008
|
function parseHistorianDumpMeta2(path) {
|
|
39593
40009
|
try {
|
|
39594
|
-
const xml =
|
|
40010
|
+
const xml = readFileSync25(path, "utf-8");
|
|
39595
40011
|
const parsed = parseCompartmentOutput(xml);
|
|
39596
40012
|
const factCountByCategory = {};
|
|
39597
40013
|
for (const fact of parsed.facts) {
|
|
@@ -39624,7 +40040,7 @@ function parseHistorianDumpMeta2(path) {
|
|
|
39624
40040
|
}
|
|
39625
40041
|
}
|
|
39626
40042
|
function listDumpsInDir2(dir, limit) {
|
|
39627
|
-
if (!
|
|
40043
|
+
if (!existsSync36(dir))
|
|
39628
40044
|
return { count: 0, recent: [] };
|
|
39629
40045
|
try {
|
|
39630
40046
|
const entries = readdirSync6(dir).filter((name) => name.endsWith(".xml")).map((name) => {
|
|
@@ -39718,7 +40134,7 @@ async function collectDiagnostics2(cwd = process.cwd()) {
|
|
|
39718
40134
|
piVersion: pi ? getPiVersion(pi.path) : null,
|
|
39719
40135
|
settings: {
|
|
39720
40136
|
path: settingsPath,
|
|
39721
|
-
exists:
|
|
40137
|
+
exists: existsSync36(settingsPath),
|
|
39722
40138
|
...settingsParsed.parseError ? { parseError: settingsParsed.parseError } : {},
|
|
39723
40139
|
hasMagicContextPackage: hasPiMagicContextPackage(packages),
|
|
39724
40140
|
packages: sanitizeValue2(packages)
|
|
@@ -39735,7 +40151,7 @@ async function collectDiagnostics2(cwd = process.cwd()) {
|
|
|
39735
40151
|
storageDir: {
|
|
39736
40152
|
path: storageDirPath,
|
|
39737
40153
|
source: storageResolution.source,
|
|
39738
|
-
exists:
|
|
40154
|
+
exists: existsSync36(storageDirPath),
|
|
39739
40155
|
contextDbSizeBytes: fileSize2(dbPath)
|
|
39740
40156
|
},
|
|
39741
40157
|
conflicts: {
|
|
@@ -39929,7 +40345,7 @@ var init_logs_pi = __esm(() => {
|
|
|
39929
40345
|
|
|
39930
40346
|
// src/commands/doctor-pi.ts
|
|
39931
40347
|
import { execFileSync as execFileSync6, spawnSync as spawnSync8 } from "node:child_process";
|
|
39932
|
-
import { existsSync as
|
|
40348
|
+
import { existsSync as existsSync37, mkdirSync as mkdirSync11, readdirSync as readdirSync7, readFileSync as readFileSync26, rmSync as rmSync4, statSync as statSync17 } from "node:fs";
|
|
39933
40349
|
import { createRequire as createRequire8 } from "node:module";
|
|
39934
40350
|
import { homedir as homedir17 } from "node:os";
|
|
39935
40351
|
import { dirname as dirname19, isAbsolute as isAbsolute8, join as join34 } from "node:path";
|
|
@@ -40023,7 +40439,7 @@ function summarize(results) {
|
|
|
40023
40439
|
function readJsonc2(path) {
|
|
40024
40440
|
try {
|
|
40025
40441
|
return {
|
|
40026
|
-
value: import_comment_json13.parse(
|
|
40442
|
+
value: import_comment_json13.parse(readFileSync26(path, "utf-8"))
|
|
40027
40443
|
};
|
|
40028
40444
|
} catch (error) {
|
|
40029
40445
|
return {
|
|
@@ -40075,13 +40491,13 @@ function piPluginDirCandidates(packages, cwd) {
|
|
|
40075
40491
|
}
|
|
40076
40492
|
dirs.push(join34(agentDir, "npm", "node_modules", PACKAGE_NAME2));
|
|
40077
40493
|
dirs.push(join34(cwd, ".pi", "npm", "node_modules", PACKAGE_NAME2));
|
|
40078
|
-
return dirs.filter((dir) =>
|
|
40494
|
+
return dirs.filter((dir) => existsSync37(join34(dir, "package.json")));
|
|
40079
40495
|
}
|
|
40080
40496
|
function projectConfigPath(cwd) {
|
|
40081
40497
|
return resolveCortexKitProjectConfigPath(cwd);
|
|
40082
40498
|
}
|
|
40083
40499
|
function readConfigForEmbedding(path, isProjectConfig) {
|
|
40084
|
-
if (!
|
|
40500
|
+
if (!existsSync37(path))
|
|
40085
40501
|
return null;
|
|
40086
40502
|
try {
|
|
40087
40503
|
const raw = loadRawConfigFile({
|
|
@@ -40182,7 +40598,7 @@ function cacheRoots(cwd) {
|
|
|
40182
40598
|
function findPiMagicContextCacheDirs(cwd, expectedVersion, force = false) {
|
|
40183
40599
|
const found = new Map;
|
|
40184
40600
|
const visit = (path, depth) => {
|
|
40185
|
-
if (depth < 0 || !
|
|
40601
|
+
if (depth < 0 || !existsSync37(path))
|
|
40186
40602
|
return;
|
|
40187
40603
|
let stat;
|
|
40188
40604
|
try {
|
|
@@ -40193,9 +40609,9 @@ function findPiMagicContextCacheDirs(cwd, expectedVersion, force = false) {
|
|
|
40193
40609
|
if (!stat.isDirectory())
|
|
40194
40610
|
return;
|
|
40195
40611
|
const packageJson = join34(path, "package.json");
|
|
40196
|
-
if (
|
|
40612
|
+
if (existsSync37(packageJson)) {
|
|
40197
40613
|
try {
|
|
40198
|
-
const pkg = JSON.parse(
|
|
40614
|
+
const pkg = JSON.parse(readFileSync26(packageJson, "utf-8"));
|
|
40199
40615
|
const name = typeof pkg.name === "string" ? pkg.name : "";
|
|
40200
40616
|
const version = typeof pkg.version === "string" ? pkg.version : undefined;
|
|
40201
40617
|
if (name === PACKAGE_NAME2) {
|
|
@@ -40260,7 +40676,7 @@ async function runHealthChecks2(options) {
|
|
|
40260
40676
|
}
|
|
40261
40677
|
const settingsPath = getPiUserExtensionsPath();
|
|
40262
40678
|
let packages = [];
|
|
40263
|
-
if (!
|
|
40679
|
+
if (!existsSync37(settingsPath)) {
|
|
40264
40680
|
add2(results, "fail", `Pi settings not found at ${settingsPath}`);
|
|
40265
40681
|
repairPlan.addPackageEntry = true;
|
|
40266
40682
|
} else {
|
|
@@ -40284,7 +40700,7 @@ async function runHealthChecks2(options) {
|
|
|
40284
40700
|
["user", userConfigPath, true],
|
|
40285
40701
|
["project", projectPath, false]
|
|
40286
40702
|
]) {
|
|
40287
|
-
if (!
|
|
40703
|
+
if (!existsSync37(path)) {
|
|
40288
40704
|
if (required) {
|
|
40289
40705
|
add2(results, "warn", `No ${label} magic-context.jsonc found at ${path}`);
|
|
40290
40706
|
if (userConfigMigrationRefused) {
|
|
@@ -40326,7 +40742,7 @@ async function runHealthChecks2(options) {
|
|
|
40326
40742
|
const storageDir = storage.path;
|
|
40327
40743
|
const dbPath = join34(storageDir, "context.db");
|
|
40328
40744
|
add2(results, "info", `Shared storage: ${storageDir} (source: ${storage.source})`);
|
|
40329
|
-
const existedBeforeOpen =
|
|
40745
|
+
const existedBeforeOpen = existsSync37(dbPath);
|
|
40330
40746
|
if (existedBeforeOpen)
|
|
40331
40747
|
add2(results, "pass", `Shared context DB exists at ${dbPath}`);
|
|
40332
40748
|
else
|
|
@@ -40561,7 +40977,7 @@ function repair2(plan, prompts) {
|
|
|
40561
40977
|
}
|
|
40562
40978
|
if (plan.writeUserConfig) {
|
|
40563
40979
|
const configPath = getPiUserConfigPath();
|
|
40564
|
-
if (!
|
|
40980
|
+
if (!existsSync37(configPath)) {
|
|
40565
40981
|
try {
|
|
40566
40982
|
writeDefaultMagicContextConfig(configPath);
|
|
40567
40983
|
prompts.log.success(`Wrote default Magic Context config to ${configPath}`);
|
|
@@ -40812,7 +41228,7 @@ var init_doctor_pi = __esm(async () => {
|
|
|
40812
41228
|
});
|
|
40813
41229
|
|
|
40814
41230
|
// src/commands/doctor.ts
|
|
40815
|
-
import { existsSync as
|
|
41231
|
+
import { existsSync as existsSync38, rmSync as rmSync5 } from "node:fs";
|
|
40816
41232
|
import { join as join35 } from "node:path";
|
|
40817
41233
|
async function runDoctor4(options) {
|
|
40818
41234
|
if (options.clear)
|
|
@@ -40943,7 +41359,7 @@ async function runClear() {
|
|
|
40943
41359
|
const s = spinner2();
|
|
40944
41360
|
s.start(`Clearing ${item.path}`);
|
|
40945
41361
|
try {
|
|
40946
|
-
if (
|
|
41362
|
+
if (existsSync38(item.path)) {
|
|
40947
41363
|
rmSync5(item.path, { recursive: true, force: true });
|
|
40948
41364
|
}
|
|
40949
41365
|
s.stop(`Cleared ${item.path}`);
|
|
@@ -41049,6 +41465,7 @@ function printUsage() {
|
|
|
41049
41465
|
console.log(" doctor migrate-session Re-home an OpenCode session to another directory");
|
|
41050
41466
|
console.log(" doctor merge-identity Merge project rows (--from ID --to ID [--dry-run] [--yes])");
|
|
41051
41467
|
console.log(" doctor repair-db Back up and salvage a corrupted shared database");
|
|
41468
|
+
console.log(" doctor list-hidden-sessions List Magic Context OpenCode 2 roots");
|
|
41052
41469
|
console.log("");
|
|
41053
41470
|
console.log(" Harness selection:");
|
|
41054
41471
|
console.log(" --harness opencode Target OpenCode only");
|
|
@@ -41105,6 +41522,10 @@ async function main(argv = process.argv.slice(2)) {
|
|
|
41105
41522
|
await init_doctor_repair_db();
|
|
41106
41523
|
return runRepairDbCli(rest.slice(1));
|
|
41107
41524
|
}
|
|
41525
|
+
if (rest[0] === "list-hidden-sessions") {
|
|
41526
|
+
await init_doctor_hidden_sessions();
|
|
41527
|
+
return runListHiddenSessions();
|
|
41528
|
+
}
|
|
41108
41529
|
if (rest[0] === "migrate") {
|
|
41109
41530
|
await init_migrate();
|
|
41110
41531
|
return runMigrateCli(rest.slice(1));
|