@cortexkit/magic-context 0.21.4 → 0.21.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 +155 -11
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -27378,6 +27378,21 @@ import { dirname as dirname7, isAbsolute, resolve as resolve2 } from "node:path"
|
|
|
27378
27378
|
function substituteConfigVariables(input) {
|
|
27379
27379
|
const warnings = [];
|
|
27380
27380
|
let text2 = input.text;
|
|
27381
|
+
if (input.isProjectConfig) {
|
|
27382
|
+
const hasEnvTokens = ENV_PATTERN.test(text2);
|
|
27383
|
+
const hasFileTokens = FILE_PATTERN.test(text2);
|
|
27384
|
+
ENV_PATTERN.lastIndex = 0;
|
|
27385
|
+
FILE_PATTERN.lastIndex = 0;
|
|
27386
|
+
if (hasEnvTokens || hasFileTokens) {
|
|
27387
|
+
const tokenTypes = [
|
|
27388
|
+
hasEnvTokens ? "{env:}" : undefined,
|
|
27389
|
+
hasFileTokens ? "{file:}" : undefined
|
|
27390
|
+
].filter(Boolean).join(" and ");
|
|
27391
|
+
warnings.push(`Project-level config no longer supports ${tokenTypes} tokens for security reasons; leaving tokens literal. Move secret expansion to user-level config.`);
|
|
27392
|
+
}
|
|
27393
|
+
return { text: text2, warnings };
|
|
27394
|
+
}
|
|
27395
|
+
text2 = stripJsonComments(text2);
|
|
27381
27396
|
text2 = text2.replace(ENV_PATTERN, (_, rawName) => {
|
|
27382
27397
|
const varName = rawName.trim();
|
|
27383
27398
|
const value = varName ? process.env[varName] : undefined;
|
|
@@ -27385,7 +27400,7 @@ function substituteConfigVariables(input) {
|
|
|
27385
27400
|
warnings.push(`Environment variable ${varName} is not set (referenced via {env:${varName}}); using empty string`);
|
|
27386
27401
|
return "";
|
|
27387
27402
|
}
|
|
27388
|
-
return value;
|
|
27403
|
+
return JSON.stringify(value).slice(1, -1);
|
|
27389
27404
|
});
|
|
27390
27405
|
const fileMatches = Array.from(text2.matchAll(FILE_PATTERN));
|
|
27391
27406
|
if (fileMatches.length === 0) {
|
|
@@ -27432,6 +27447,7 @@ function substituteConfigVariables(input) {
|
|
|
27432
27447
|
}
|
|
27433
27448
|
var ENV_PATTERN, FILE_PATTERN;
|
|
27434
27449
|
var init_variable = __esm(() => {
|
|
27450
|
+
init_jsonc_parser();
|
|
27435
27451
|
ENV_PATTERN = /\{env:([^}]+)\}/g;
|
|
27436
27452
|
FILE_PATTERN = /\{file:([^}]+)\}/g;
|
|
27437
27453
|
});
|
|
@@ -27447,13 +27463,17 @@ function getUserConfigBasePath() {
|
|
|
27447
27463
|
function getProjectConfigBasePath(directory) {
|
|
27448
27464
|
return join11(directory, ".opencode", CONFIG_FILE_BASENAME);
|
|
27449
27465
|
}
|
|
27450
|
-
function loadConfigFile(configPath) {
|
|
27466
|
+
function loadConfigFile(configPath, isProjectConfig = false) {
|
|
27451
27467
|
try {
|
|
27452
27468
|
if (!existsSync13(configPath)) {
|
|
27453
27469
|
return null;
|
|
27454
27470
|
}
|
|
27455
27471
|
const rawText = readFileSync8(configPath, "utf-8");
|
|
27456
|
-
const substituted = substituteConfigVariables({
|
|
27472
|
+
const substituted = substituteConfigVariables({
|
|
27473
|
+
text: rawText,
|
|
27474
|
+
configPath,
|
|
27475
|
+
isProjectConfig
|
|
27476
|
+
});
|
|
27457
27477
|
return {
|
|
27458
27478
|
config: parseJsonc3(substituted.text),
|
|
27459
27479
|
warnings: substituted.warnings.map((w3) => `${configPath}: ${w3}`)
|
|
@@ -27617,7 +27637,7 @@ function loadPluginConfig(directory) {
|
|
|
27617
27637
|
const dotOpenCodeDetected = detectConfigFile(getProjectConfigBasePath(directory));
|
|
27618
27638
|
const projectDetected = rootDetected.format !== "none" ? rootDetected : dotOpenCodeDetected;
|
|
27619
27639
|
const userLoaded = userDetected.format === "none" ? null : loadConfigFile(userDetected.path);
|
|
27620
|
-
const projectLoaded = projectDetected.format === "none" ? null : loadConfigFile(projectDetected.path);
|
|
27640
|
+
const projectLoaded = projectDetected.format === "none" ? null : loadConfigFile(projectDetected.path, true);
|
|
27621
27641
|
const allWarnings = [];
|
|
27622
27642
|
let mergedRaw = {};
|
|
27623
27643
|
if (userLoaded) {
|
|
@@ -28543,6 +28563,91 @@ var init_diagnostics_opencode = __esm(() => {
|
|
|
28543
28563
|
PLUGIN_ENTRY_WITH_VERSION = `${PLUGIN_NAME5}@latest`;
|
|
28544
28564
|
});
|
|
28545
28565
|
|
|
28566
|
+
// src/lib/issue-body.ts
|
|
28567
|
+
function isErrorLogLine(line) {
|
|
28568
|
+
return ERROR_LOG_PATTERNS.some((rx) => rx.test(line));
|
|
28569
|
+
}
|
|
28570
|
+
function extractRecentErrors(sanitized, limit = 20) {
|
|
28571
|
+
const matches = [];
|
|
28572
|
+
const lines = sanitized.split(/\r?\n/);
|
|
28573
|
+
for (let i = lines.length - 1;i >= 0 && matches.length < limit; i -= 1) {
|
|
28574
|
+
if (isErrorLogLine(lines[i])) {
|
|
28575
|
+
matches.push(lines[i]);
|
|
28576
|
+
}
|
|
28577
|
+
}
|
|
28578
|
+
return matches.reverse();
|
|
28579
|
+
}
|
|
28580
|
+
function capBodyToGithubLimit(body, maxBytes = MAX_GITHUB_BODY_BYTES) {
|
|
28581
|
+
if (Buffer.byteLength(body, "utf8") <= maxBytes)
|
|
28582
|
+
return body;
|
|
28583
|
+
const heading = "## Log (last";
|
|
28584
|
+
const headingIdx = body.indexOf(heading);
|
|
28585
|
+
if (headingIdx === -1) {
|
|
28586
|
+
const marker = `
|
|
28587
|
+
|
|
28588
|
+
[truncated for GitHub 64KB limit]
|
|
28589
|
+
`;
|
|
28590
|
+
const markerBytes2 = Buffer.byteLength(marker, "utf8");
|
|
28591
|
+
return truncateToByteBudget(body, maxBytes - markerBytes2) + marker;
|
|
28592
|
+
}
|
|
28593
|
+
const fenceOpenIdx = body.indexOf("\n```", headingIdx);
|
|
28594
|
+
if (fenceOpenIdx === -1)
|
|
28595
|
+
return body;
|
|
28596
|
+
const logStart = fenceOpenIdx + "\n```\n".length;
|
|
28597
|
+
const fenceCloseIdx = body.indexOf("\n```", logStart);
|
|
28598
|
+
if (fenceCloseIdx === -1)
|
|
28599
|
+
return body;
|
|
28600
|
+
const head = body.slice(0, logStart);
|
|
28601
|
+
const log3 = body.slice(logStart, fenceCloseIdx);
|
|
28602
|
+
const tail = body.slice(fenceCloseIdx);
|
|
28603
|
+
const overheadBytes = Buffer.byteLength(head, "utf8") + Buffer.byteLength(tail, "utf8");
|
|
28604
|
+
const truncationMarker = `[truncated for GitHub 64KB limit — older log lines dropped]
|
|
28605
|
+
`;
|
|
28606
|
+
const markerBytes = Buffer.byteLength(truncationMarker, "utf8");
|
|
28607
|
+
const logBudget = maxBytes - overheadBytes - markerBytes;
|
|
28608
|
+
if (logBudget <= 0) {
|
|
28609
|
+
return `${head}${truncationMarker}${tail}`;
|
|
28610
|
+
}
|
|
28611
|
+
const lines = log3.split(`
|
|
28612
|
+
`);
|
|
28613
|
+
let keepLines = lines;
|
|
28614
|
+
let kept = keepLines.join(`
|
|
28615
|
+
`);
|
|
28616
|
+
while (Buffer.byteLength(kept, "utf8") > logBudget && keepLines.length > 1) {
|
|
28617
|
+
const dropCount = Math.max(1, Math.floor(keepLines.length * 0.05));
|
|
28618
|
+
keepLines = keepLines.slice(dropCount);
|
|
28619
|
+
kept = keepLines.join(`
|
|
28620
|
+
`);
|
|
28621
|
+
}
|
|
28622
|
+
if (Buffer.byteLength(kept, "utf8") > logBudget) {
|
|
28623
|
+
kept = truncateToByteBudget(kept, logBudget);
|
|
28624
|
+
}
|
|
28625
|
+
return `${head}${truncationMarker}${kept}${tail}`;
|
|
28626
|
+
}
|
|
28627
|
+
function truncateToByteBudget(input, maxBytes) {
|
|
28628
|
+
if (maxBytes <= 0)
|
|
28629
|
+
return "";
|
|
28630
|
+
const buf = Buffer.from(input, "utf8");
|
|
28631
|
+
if (buf.length <= maxBytes)
|
|
28632
|
+
return input;
|
|
28633
|
+
let end = maxBytes;
|
|
28634
|
+
while (end > 0 && (buf[end] & 192) === 128) {
|
|
28635
|
+
end -= 1;
|
|
28636
|
+
}
|
|
28637
|
+
return buf.subarray(0, end).toString("utf8");
|
|
28638
|
+
}
|
|
28639
|
+
var MAX_GITHUB_BODY_BYTES = 60000, ERROR_LOG_PATTERNS;
|
|
28640
|
+
var init_issue_body = __esm(() => {
|
|
28641
|
+
ERROR_LOG_PATTERNS = [
|
|
28642
|
+
/\bfailed:/i,
|
|
28643
|
+
/\b(?:[A-Z][a-zA-Z]*)?Error:\s/,
|
|
28644
|
+
/\bEMERGENCY\b/,
|
|
28645
|
+
/\bexception\b/i,
|
|
28646
|
+
/^\s+at\s+[\w.<>$]+\s+\(/,
|
|
28647
|
+
/^\s+at\s+(?:file:|node_modules\/|[^/\s]+:\d+)/
|
|
28648
|
+
];
|
|
28649
|
+
});
|
|
28650
|
+
|
|
28546
28651
|
// src/lib/logs-opencode.ts
|
|
28547
28652
|
import { readFileSync as readFileSync12, writeFileSync as writeFileSync9 } from "node:fs";
|
|
28548
28653
|
import { homedir as homedir12 } from "node:os";
|
|
@@ -28595,9 +28700,12 @@ async function bundleIssueReport(report, description, _title, sessionFilter = nu
|
|
|
28595
28700
|
const historianScanWindow = sanitizeLogContent(logLines.slice(-4000).join(`
|
|
28596
28701
|
`));
|
|
28597
28702
|
const historianFailureLines = extractHistorianFailureLines(historianScanWindow, 30);
|
|
28703
|
+
const errorScanWindow = sanitizeLogContent(logLines.slice(-4000).join(`
|
|
28704
|
+
`));
|
|
28705
|
+
const recentErrorLines = extractRecentErrors(errorScanWindow, 20);
|
|
28598
28706
|
const configBody = JSON.stringify(sanitizeConfigValue(report.magicContextConfig.flags), null, 2);
|
|
28599
28707
|
const sanitizedConfigPath = report.configPaths.magicContextConfig.replace(homedir12(), "~");
|
|
28600
|
-
const
|
|
28708
|
+
const rawBodyMarkdown = [
|
|
28601
28709
|
"## Description",
|
|
28602
28710
|
description,
|
|
28603
28711
|
"",
|
|
@@ -28619,6 +28727,11 @@ async function bundleIssueReport(report, description, _title, sessionFilter = nu
|
|
|
28619
28727
|
"## Historian failure signals (log, sanitized)",
|
|
28620
28728
|
historianFailureLines.length === 0 ? "_No historian failure log lines found in recent history._" : ["```", historianFailureLines.join(`
|
|
28621
28729
|
`), "```"].join(`
|
|
28730
|
+
`),
|
|
28731
|
+
"",
|
|
28732
|
+
"## Recent errors (last 20, sanitized)",
|
|
28733
|
+
recentErrorLines.length === 0 ? "_No error-shaped log lines found in recent history._" : ["```", recentErrorLines.join(`
|
|
28734
|
+
`), "```"].join(`
|
|
28622
28735
|
`),
|
|
28623
28736
|
"",
|
|
28624
28737
|
`## Log (last ${LOG_TAIL_LINES} lines, sanitized)`,
|
|
@@ -28627,6 +28740,7 @@ async function bundleIssueReport(report, description, _title, sessionFilter = nu
|
|
|
28627
28740
|
"```"
|
|
28628
28741
|
].join(`
|
|
28629
28742
|
`);
|
|
28743
|
+
const bodyMarkdown = capBodyToGithubLimit(rawBodyMarkdown);
|
|
28630
28744
|
const path4 = join15(process.cwd(), `magic-context-issue-${formatTimestamp(new Date)}.md`);
|
|
28631
28745
|
writeFileSync9(path4, `${bodyMarkdown}
|
|
28632
28746
|
`);
|
|
@@ -28635,6 +28749,7 @@ async function bundleIssueReport(report, description, _title, sessionFilter = nu
|
|
|
28635
28749
|
var HISTORIAN_LOG_PATTERNS;
|
|
28636
28750
|
var init_logs_opencode = __esm(() => {
|
|
28637
28751
|
init_diagnostics_opencode();
|
|
28752
|
+
init_issue_body();
|
|
28638
28753
|
init_redaction();
|
|
28639
28754
|
HISTORIAN_LOG_PATTERNS = [
|
|
28640
28755
|
/historian failure:/,
|
|
@@ -162015,8 +162130,10 @@ function deleteOrphanProjectKeyFiles(db, now = Date.now()) {
|
|
|
162015
162130
|
if (existsSync18(row.projectPath))
|
|
162016
162131
|
continue;
|
|
162017
162132
|
try {
|
|
162018
|
-
db.
|
|
162019
|
-
|
|
162133
|
+
db.transaction(() => {
|
|
162134
|
+
db.prepare("DELETE FROM project_key_files WHERE project_path = ?").run(row.projectPath);
|
|
162135
|
+
db.prepare("DELETE FROM project_key_files_version WHERE project_path = ?").run(row.projectPath);
|
|
162136
|
+
})();
|
|
162020
162137
|
deletedProjects++;
|
|
162021
162138
|
} catch (error51) {
|
|
162022
162139
|
log2(`[key-files] orphan GC failed for ${row.projectPath}:`, error51);
|
|
@@ -162044,7 +162161,7 @@ function getCurrentVersion(db) {
|
|
|
162044
162161
|
const row = db.prepare("SELECT MAX(version) as version FROM schema_migrations").get();
|
|
162045
162162
|
return row?.version ?? 0;
|
|
162046
162163
|
}
|
|
162047
|
-
function isSiblingMigrationConflict(error51, version2) {
|
|
162164
|
+
function isSiblingMigrationConflict(db, error51, version2) {
|
|
162048
162165
|
if (!(error51 instanceof Error))
|
|
162049
162166
|
return false;
|
|
162050
162167
|
const code = error51.code;
|
|
@@ -162056,7 +162173,8 @@ function isSiblingMigrationConflict(error51, version2) {
|
|
|
162056
162173
|
return false;
|
|
162057
162174
|
if (!msg.toLowerCase().includes("version"))
|
|
162058
162175
|
return false;
|
|
162059
|
-
|
|
162176
|
+
const confirmed = db.prepare("SELECT 1 FROM schema_migrations WHERE version = ?").get(version2);
|
|
162177
|
+
return confirmed != null;
|
|
162060
162178
|
}
|
|
162061
162179
|
function runMigrations(db) {
|
|
162062
162180
|
ensureMigrationsTable(db);
|
|
@@ -162077,7 +162195,7 @@ function runMigrations(db) {
|
|
|
162077
162195
|
log2(`[migrations] applied v${migration.version}: ${migration.description}`);
|
|
162078
162196
|
migrationIndex += 1;
|
|
162079
162197
|
} catch (error51) {
|
|
162080
|
-
if (isSiblingMigrationConflict(error51, migration.version)) {
|
|
162198
|
+
if (isSiblingMigrationConflict(db, error51, migration.version)) {
|
|
162081
162199
|
log2(`[migrations] v${migration.version} already applied by sibling instance — resuming with re-read version`);
|
|
162082
162200
|
const reReadVersion = getCurrentVersion(db);
|
|
162083
162201
|
if (reReadVersion <= currentVersion) {
|
|
@@ -162483,6 +162601,16 @@ var init_migrations = __esm(async () => {
|
|
|
162483
162601
|
WHERE auto_search_hint_decisions IS NULL
|
|
162484
162602
|
`);
|
|
162485
162603
|
}
|
|
162604
|
+
},
|
|
162605
|
+
{
|
|
162606
|
+
version: 18,
|
|
162607
|
+
description: "Add pending_pi_compaction_marker_state column for Pi deferred marker drain",
|
|
162608
|
+
up: (db) => {
|
|
162609
|
+
const cols = db.prepare("PRAGMA table_info(session_meta)").all();
|
|
162610
|
+
if (!cols.some((c2) => c2.name === "pending_pi_compaction_marker_state")) {
|
|
162611
|
+
db.exec("ALTER TABLE session_meta ADD COLUMN pending_pi_compaction_marker_state TEXT");
|
|
162612
|
+
}
|
|
162613
|
+
}
|
|
162486
162614
|
}
|
|
162487
162615
|
];
|
|
162488
162616
|
});
|
|
@@ -163046,6 +163174,11 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
163046
163174
|
-- Excluded from healNullTextColumns. Readers filter IS NOT NULL AND
|
|
163047
163175
|
-- != empty-string defensively. Plan v6 section 3.
|
|
163048
163176
|
pending_compaction_marker_state TEXT,
|
|
163177
|
+
-- pending_pi_compaction_marker_state: intentionally NULLABLE without a
|
|
163178
|
+
-- default. Absence of a deferred Pi-native marker is SQL NULL; presence
|
|
163179
|
+
-- is a valid JSON blob written via setPendingPiCompactionMarkerState.
|
|
163180
|
+
-- Excluded from healNullTextColumns.
|
|
163181
|
+
pending_pi_compaction_marker_state TEXT,
|
|
163049
163182
|
-- deferred_execute_state: intentionally NULLABLE without a default.
|
|
163050
163183
|
-- Absence is SQL NULL; presence is a JSON blob written via
|
|
163051
163184
|
-- setDeferredExecutePendingIfAbsent. Excluded from healNullTextColumns.
|
|
@@ -163142,6 +163275,7 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
163142
163275
|
ensureColumn(db, "session_meta", "detected_context_limit", "INTEGER DEFAULT 0");
|
|
163143
163276
|
ensureColumn(db, "session_meta", "needs_emergency_recovery", "INTEGER DEFAULT 0");
|
|
163144
163277
|
ensureColumn(db, "session_meta", "pending_compaction_marker_state", "TEXT");
|
|
163278
|
+
ensureColumn(db, "session_meta", "pending_pi_compaction_marker_state", "TEXT");
|
|
163145
163279
|
ensureColumn(db, "session_meta", "deferred_execute_state", "TEXT");
|
|
163146
163280
|
ensureColumn(db, "tags", "harness", "TEXT NOT NULL DEFAULT 'opencode'");
|
|
163147
163281
|
ensureColumn(db, "pending_ops", "harness", "TEXT NOT NULL DEFAULT 'opencode'");
|
|
@@ -163969,7 +164103,10 @@ async function bundleIssueReport2(report, description, title, options = {}) {
|
|
|
163969
164103
|
const logLines = filterLogLinesBySession2(allLogLines, options.sessionFilter ?? null);
|
|
163970
164104
|
const recentLog = sanitizeLogContent2(logLines.slice(-LOG_TAIL_LINES).join(`
|
|
163971
164105
|
`)).trim();
|
|
163972
|
-
const
|
|
164106
|
+
const errorScanWindow = sanitizeLogContent2(logLines.slice(-4000).join(`
|
|
164107
|
+
`));
|
|
164108
|
+
const recentErrorLines = extractRecentErrors(errorScanWindow, 20);
|
|
164109
|
+
const rawBodyMarkdown = [
|
|
163973
164110
|
"## Title",
|
|
163974
164111
|
`[pi] ${sanitizeString2(title)}`,
|
|
163975
164112
|
"",
|
|
@@ -163984,6 +164121,11 @@ async function bundleIssueReport2(report, description, title, options = {}) {
|
|
|
163984
164121
|
"",
|
|
163985
164122
|
"## Diagnostics",
|
|
163986
164123
|
renderDiagnosticsMarkdown2(report),
|
|
164124
|
+
"",
|
|
164125
|
+
"## Recent errors (last 20, sanitized)",
|
|
164126
|
+
recentErrorLines.length === 0 ? "_No error-shaped log lines found in recent history._" : ["```", recentErrorLines.join(`
|
|
164127
|
+
`), "```"].join(`
|
|
164128
|
+
`),
|
|
163987
164129
|
"",
|
|
163988
164130
|
`## Log (last ${LOG_TAIL_LINES} lines, sanitized)`,
|
|
163989
164131
|
"```",
|
|
@@ -163991,6 +164133,7 @@ async function bundleIssueReport2(report, description, title, options = {}) {
|
|
|
163991
164133
|
"```"
|
|
163992
164134
|
].join(`
|
|
163993
164135
|
`);
|
|
164136
|
+
const bodyMarkdown = capBodyToGithubLimit(rawBodyMarkdown);
|
|
163994
164137
|
const cwd = options.cwd ?? process.cwd();
|
|
163995
164138
|
const path4 = join21(cwd, `magic-context-pi-issue-${formatTimestamp2(options.now ?? new Date)}.md`);
|
|
163996
164139
|
writeFileSync11(path4, `${bodyMarkdown}
|
|
@@ -163999,6 +164142,7 @@ async function bundleIssueReport2(report, description, title, options = {}) {
|
|
|
163999
164142
|
}
|
|
164000
164143
|
var init_logs_pi = __esm(() => {
|
|
164001
164144
|
init_diagnostics_pi();
|
|
164145
|
+
init_issue_body();
|
|
164002
164146
|
});
|
|
164003
164147
|
|
|
164004
164148
|
// src/commands/doctor-pi.ts
|