@cortexkit/magic-context 0.49.1 → 0.49.2
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 +211 -148
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -45104,6 +45104,151 @@ var init_log_lines = __esm(() => {
|
|
|
45104
45104
|
LEVEL_DEFAULT = LEVEL_ORDER.INFO;
|
|
45105
45105
|
});
|
|
45106
45106
|
|
|
45107
|
+
// src/lib/issue-body.ts
|
|
45108
|
+
function isErrorLogLine(line) {
|
|
45109
|
+
const parsed = parseLogLine(line);
|
|
45110
|
+
if (parsed?.level !== null && parsed?.level !== undefined) {
|
|
45111
|
+
return parsed.level === "ERROR" || parsed.level === "WARN";
|
|
45112
|
+
}
|
|
45113
|
+
if (/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/.test(line))
|
|
45114
|
+
return false;
|
|
45115
|
+
const message = parsed?.message ?? line;
|
|
45116
|
+
return ERROR_LOG_PATTERNS.some((rx) => rx.test(message));
|
|
45117
|
+
}
|
|
45118
|
+
function extractRecentErrors(sanitized, limit = 20) {
|
|
45119
|
+
const matches = [];
|
|
45120
|
+
const lines = sanitized.split(/\r?\n/);
|
|
45121
|
+
for (let i = lines.length - 1;i >= 0 && matches.length < limit; i -= 1) {
|
|
45122
|
+
if (isErrorLogLine(lines[i])) {
|
|
45123
|
+
matches.push(lines[i]);
|
|
45124
|
+
}
|
|
45125
|
+
}
|
|
45126
|
+
return matches.reverse();
|
|
45127
|
+
}
|
|
45128
|
+
function filterLogLinesBySession(lines, sessionId) {
|
|
45129
|
+
if (!sessionId)
|
|
45130
|
+
return lines;
|
|
45131
|
+
const otherSessionPattern = /\bses_[A-Za-z0-9]{3,64}\b/g;
|
|
45132
|
+
return lines.filter((line) => {
|
|
45133
|
+
const parsed = parseLogLine(line);
|
|
45134
|
+
if (parsed?.session && parsed.session !== sessionId)
|
|
45135
|
+
return false;
|
|
45136
|
+
const matches = parsed?.message.match(otherSessionPattern) ?? line.match(otherSessionPattern);
|
|
45137
|
+
if (!matches)
|
|
45138
|
+
return true;
|
|
45139
|
+
return matches.every((id) => id === sessionId);
|
|
45140
|
+
});
|
|
45141
|
+
}
|
|
45142
|
+
function getLogSessionIds(lines) {
|
|
45143
|
+
const otherSessionPattern = /\bses_[A-Za-z0-9]{3,64}\b/g;
|
|
45144
|
+
const seen = new Set;
|
|
45145
|
+
const sessions = [];
|
|
45146
|
+
for (let index = lines.length - 1;index >= 0; index -= 1) {
|
|
45147
|
+
const line = lines[index];
|
|
45148
|
+
const parsed = parseLogLine(line);
|
|
45149
|
+
if (parsed?.session && !seen.has(parsed.session)) {
|
|
45150
|
+
seen.add(parsed.session);
|
|
45151
|
+
sessions.push(parsed.session);
|
|
45152
|
+
}
|
|
45153
|
+
const matches = parsed?.message.match(otherSessionPattern) ?? line.match(otherSessionPattern);
|
|
45154
|
+
for (const session of matches ?? []) {
|
|
45155
|
+
if (!seen.has(session)) {
|
|
45156
|
+
seen.add(session);
|
|
45157
|
+
sessions.push(session);
|
|
45158
|
+
}
|
|
45159
|
+
}
|
|
45160
|
+
}
|
|
45161
|
+
return sessions;
|
|
45162
|
+
}
|
|
45163
|
+
function capBodyToGithubLimit(body, maxBytes = MAX_GITHUB_BODY_BYTES) {
|
|
45164
|
+
if (Buffer.byteLength(body, "utf8") <= maxBytes)
|
|
45165
|
+
return body;
|
|
45166
|
+
let capped = body;
|
|
45167
|
+
const heading = "## Log (last";
|
|
45168
|
+
const headingIdx = body.indexOf(heading);
|
|
45169
|
+
if (headingIdx === -1) {
|
|
45170
|
+
const markerBytes = Buffer.byteLength(FALLBACK_TRUNCATION_MARKER, "utf8");
|
|
45171
|
+
capped = truncateToByteBudget(body, maxBytes - markerBytes) + FALLBACK_TRUNCATION_MARKER;
|
|
45172
|
+
return enforceFinalBodyLimit(capped, maxBytes);
|
|
45173
|
+
}
|
|
45174
|
+
const fenceOpenIdx = body.indexOf("\n```", headingIdx);
|
|
45175
|
+
if (fenceOpenIdx === -1)
|
|
45176
|
+
return enforceFinalBodyLimit(body, maxBytes);
|
|
45177
|
+
const logStart = fenceOpenIdx + "\n```\n".length;
|
|
45178
|
+
const fenceCloseIdx = body.indexOf("\n```", logStart);
|
|
45179
|
+
if (fenceCloseIdx === -1)
|
|
45180
|
+
return enforceFinalBodyLimit(body, maxBytes);
|
|
45181
|
+
const head = body.slice(0, logStart);
|
|
45182
|
+
const log = body.slice(logStart, fenceCloseIdx);
|
|
45183
|
+
const tail = body.slice(fenceCloseIdx);
|
|
45184
|
+
const overheadBytes = Buffer.byteLength(head, "utf8") + Buffer.byteLength(tail, "utf8");
|
|
45185
|
+
const markerBytes = Buffer.byteLength(LOG_TRUNCATION_MARKER, "utf8");
|
|
45186
|
+
const logBudget = maxBytes - overheadBytes - markerBytes;
|
|
45187
|
+
if (logBudget <= 0) {
|
|
45188
|
+
capped = `${head}${LOG_TRUNCATION_MARKER}${tail}`;
|
|
45189
|
+
return enforceFinalBodyLimit(capped, maxBytes);
|
|
45190
|
+
}
|
|
45191
|
+
const lines = log.split(`
|
|
45192
|
+
`);
|
|
45193
|
+
let keepLines = lines;
|
|
45194
|
+
let kept = keepLines.join(`
|
|
45195
|
+
`);
|
|
45196
|
+
while (Buffer.byteLength(kept, "utf8") > logBudget && keepLines.length > 1) {
|
|
45197
|
+
const dropCount = Math.max(1, Math.floor(keepLines.length * 0.05));
|
|
45198
|
+
keepLines = keepLines.slice(dropCount);
|
|
45199
|
+
kept = keepLines.join(`
|
|
45200
|
+
`);
|
|
45201
|
+
}
|
|
45202
|
+
if (Buffer.byteLength(kept, "utf8") > logBudget) {
|
|
45203
|
+
kept = truncateToByteBudget(kept, logBudget);
|
|
45204
|
+
}
|
|
45205
|
+
capped = `${head}${LOG_TRUNCATION_MARKER}${kept}${tail}`;
|
|
45206
|
+
return enforceFinalBodyLimit(capped, maxBytes);
|
|
45207
|
+
}
|
|
45208
|
+
function enforceFinalBodyLimit(body, maxBytes) {
|
|
45209
|
+
if (Buffer.byteLength(body, "utf8") <= maxBytes)
|
|
45210
|
+
return body;
|
|
45211
|
+
const markerBytes = Buffer.byteLength(FINAL_TRUNCATION_MARKER, "utf8");
|
|
45212
|
+
if (markerBytes >= maxBytes) {
|
|
45213
|
+
return truncateToByteBudget(FINAL_TRUNCATION_MARKER, maxBytes);
|
|
45214
|
+
}
|
|
45215
|
+
return truncateToByteBudget(body, maxBytes - markerBytes) + FINAL_TRUNCATION_MARKER;
|
|
45216
|
+
}
|
|
45217
|
+
function truncateToByteBudget(input, maxBytes) {
|
|
45218
|
+
if (maxBytes <= 0)
|
|
45219
|
+
return "";
|
|
45220
|
+
const buf = Buffer.from(input, "utf8");
|
|
45221
|
+
if (buf.length <= maxBytes)
|
|
45222
|
+
return input;
|
|
45223
|
+
let end = maxBytes;
|
|
45224
|
+
while (end > 0 && (buf[end] & 192) === 128) {
|
|
45225
|
+
end -= 1;
|
|
45226
|
+
}
|
|
45227
|
+
return buf.subarray(0, end).toString("utf8");
|
|
45228
|
+
}
|
|
45229
|
+
var MAX_GITHUB_BODY_BYTES = 60000, LOG_TRUNCATION_MARKER = `[truncated for GitHub 64KB limit — older log lines dropped]
|
|
45230
|
+
`, FINAL_TRUNCATION_MARKER = `
|
|
45231
|
+
|
|
45232
|
+
[truncated further to fit GitHub body limit]
|
|
45233
|
+
`, FALLBACK_TRUNCATION_MARKER = `
|
|
45234
|
+
|
|
45235
|
+
[truncated for GitHub 64KB limit]
|
|
45236
|
+
`, ERROR_LOG_PATTERNS;
|
|
45237
|
+
var init_issue_body = __esm(() => {
|
|
45238
|
+
init_log_lines();
|
|
45239
|
+
ERROR_LOG_PATTERNS = [
|
|
45240
|
+
/\bfailed:/i,
|
|
45241
|
+
/\b(?:[A-Z][a-zA-Z]*)?Error:\s/,
|
|
45242
|
+
/\bEMERGENCY\b/,
|
|
45243
|
+
/could not safely prepare this turn/i,
|
|
45244
|
+
/\bMC-H[A-Z0-9-]+\b/i,
|
|
45245
|
+
/\brefused\s*\(/i,
|
|
45246
|
+
/\bexception\b/i,
|
|
45247
|
+
/^\s+at\s+[\w.<>$]+\s+\(/,
|
|
45248
|
+
/^\s+at\s+(?:file:|node_modules\/|[^/\s]+:\d+)/
|
|
45249
|
+
];
|
|
45250
|
+
});
|
|
45251
|
+
|
|
45107
45252
|
// src/lib/redaction.ts
|
|
45108
45253
|
function sanitizeDiagnosticEndpoint(value) {
|
|
45109
45254
|
const trimmed = value.trim();
|
|
@@ -45193,6 +45338,8 @@ function pluginDeclaresOmp(path) {
|
|
|
45193
45338
|
}
|
|
45194
45339
|
async function runHealthChecks(options) {
|
|
45195
45340
|
const results = [];
|
|
45341
|
+
let pluginVersion = null;
|
|
45342
|
+
let ompVersion = null;
|
|
45196
45343
|
const repairPlan = {
|
|
45197
45344
|
installPlugin: false,
|
|
45198
45345
|
disableCompaction: false,
|
|
@@ -45204,11 +45351,13 @@ async function runHealthChecks(options) {
|
|
|
45204
45351
|
add(results, "fail", "OMP binary not found on PATH or in standard user bin directories");
|
|
45205
45352
|
} else {
|
|
45206
45353
|
const version = options.deps.getOmpVersion(omp.path);
|
|
45354
|
+
ompVersion = version;
|
|
45207
45355
|
const plugins = options.deps.listOmpPlugins(omp.path);
|
|
45208
45356
|
if (!plugins) {
|
|
45209
45357
|
add(results, "fail", "`omp plugin list --json` failed or returned invalid JSON");
|
|
45210
45358
|
} else {
|
|
45211
45359
|
const plugin = plugins.find((entry) => entry.name === OMP_PLUGIN_PACKAGE);
|
|
45360
|
+
pluginVersion = plugin?.version ?? null;
|
|
45212
45361
|
if (!plugin) {
|
|
45213
45362
|
add(results, "info", `${version ? `Oh My Pi ${version}` : "Oh My Pi"} found; Magic Context is not installed there (run setup to add it)`);
|
|
45214
45363
|
repairPlan.installPlugin = true;
|
|
@@ -45335,6 +45484,9 @@ ${formatDatabaseRepairGuidance(dbPath)}`);
|
|
|
45335
45484
|
return {
|
|
45336
45485
|
results,
|
|
45337
45486
|
repairPlan,
|
|
45487
|
+
pluginVersion,
|
|
45488
|
+
ompVersion,
|
|
45489
|
+
logFiles,
|
|
45338
45490
|
pass: results.filter((result) => result.status === "pass").length,
|
|
45339
45491
|
warn: results.filter((result) => result.status === "warn").length,
|
|
45340
45492
|
fail: results.filter((result) => result.status === "fail").length
|
|
@@ -45388,17 +45540,51 @@ async function repair(plan, deps, prompts, cwd) {
|
|
|
45388
45540
|
function timestamp2(date) {
|
|
45389
45541
|
return date.toISOString().replace(/[-:]/g, "").replace(/\.\d{3}Z$/, "Z");
|
|
45390
45542
|
}
|
|
45391
|
-
function ompIssueBody(description, report) {
|
|
45543
|
+
function ompIssueBody(description, report, logLines, sessionFilter) {
|
|
45544
|
+
const LOG_TAIL_LINES = 400;
|
|
45545
|
+
const filteredLogLines = filterLogLinesBySession(logLines, sessionFilter);
|
|
45546
|
+
const recentLog = sanitizeDiagnosticText(filteredLogLines.slice(-LOG_TAIL_LINES).join(`
|
|
45547
|
+
`)).trim();
|
|
45548
|
+
const errorScanWindow = sanitizeDiagnosticText(filteredLogLines.slice(-4000).join(`
|
|
45549
|
+
`));
|
|
45550
|
+
const recentErrorLines = extractRecentErrors(errorScanWindow, 20);
|
|
45392
45551
|
return [
|
|
45393
45552
|
"## Description",
|
|
45394
45553
|
sanitizeDiagnosticText(description),
|
|
45395
45554
|
"",
|
|
45555
|
+
"## Environment",
|
|
45556
|
+
`- Magic Context plugin: ${report.pluginVersion ? `v${sanitizeDiagnosticText(report.pluginVersion)}` : "not installed"}`,
|
|
45557
|
+
`- Oh My Pi: ${report.ompVersion ? sanitizeDiagnosticText(report.ompVersion) : "not detected"}`,
|
|
45558
|
+
`- OS: ${process.platform} ${process.arch}`,
|
|
45559
|
+
`- Runtime: Node.js ${process.version}`,
|
|
45560
|
+
"",
|
|
45396
45561
|
"## OMP diagnostics",
|
|
45397
|
-
`- Magic Context CLI: ${selfVersion()}`,
|
|
45398
|
-
...report.results.map((result) => `- ${result.status.toUpperCase()}: ${sanitizeDiagnosticText(result.message)}`)
|
|
45562
|
+
`- Magic Context CLI: v${selfVersion()}`,
|
|
45563
|
+
...report.results.map((result) => `- ${result.status.toUpperCase()}: ${sanitizeDiagnosticText(result.message)}`),
|
|
45564
|
+
"",
|
|
45565
|
+
"## Recent errors (last 20, sanitized)",
|
|
45566
|
+
recentErrorLines.length === 0 ? "_No error-shaped log lines found in recent history._" : ["```", recentErrorLines.join(`
|
|
45567
|
+
`), "```"].join(`
|
|
45568
|
+
`),
|
|
45569
|
+
"",
|
|
45570
|
+
`## Log (last ${LOG_TAIL_LINES} lines, sanitized)`,
|
|
45571
|
+
"```",
|
|
45572
|
+
recentLog || "<no log output>",
|
|
45573
|
+
"```"
|
|
45399
45574
|
].join(`
|
|
45400
45575
|
`);
|
|
45401
45576
|
}
|
|
45577
|
+
function writeOmpIssueReport(path, fullBodyMarkdown) {
|
|
45578
|
+
const bodyMarkdown = capBodyToGithubLimit(fullBodyMarkdown);
|
|
45579
|
+
const truncated = bodyMarkdown !== fullBodyMarkdown;
|
|
45580
|
+
writeFileAtomic(path, `${bodyMarkdown}
|
|
45581
|
+
`);
|
|
45582
|
+
const fullPath = truncated ? `${path}.full.md` : undefined;
|
|
45583
|
+
if (fullPath)
|
|
45584
|
+
writeFileAtomic(fullPath, `${fullBodyMarkdown}
|
|
45585
|
+
`);
|
|
45586
|
+
return { path, bodyMarkdown, ...fullPath ? { fullPath } : {}, truncated };
|
|
45587
|
+
}
|
|
45402
45588
|
function runGhCommandWithDeps(deps, args) {
|
|
45403
45589
|
if (args[0] === "issue") {
|
|
45404
45590
|
const result = deps.spawnSync("gh", args, {
|
|
@@ -45432,9 +45618,8 @@ async function runIssueFlow(options) {
|
|
|
45432
45618
|
if (options.reportPath) {
|
|
45433
45619
|
const report = await runHealthChecks({ ...options, quiet: true });
|
|
45434
45620
|
const path = isAbsolute8(options.reportPath) ? options.reportPath : join33(options.cwd, options.reportPath);
|
|
45435
|
-
|
|
45436
|
-
`);
|
|
45437
|
-
options.prompts.log.success(`Sanitized report written to ${path}`);
|
|
45621
|
+
const bundle = writeOmpIssueReport(path, ompIssueBody("Generated non-interactively by `doctor --issue --report`.", report, readLogLines(report.logFiles), null));
|
|
45622
|
+
options.prompts.log.success(bundle.fullPath ? `Sanitized report written to ${bundle.path}; full report at ${bundle.fullPath}` : `Sanitized report written to ${bundle.path}`);
|
|
45438
45623
|
return 0;
|
|
45439
45624
|
}
|
|
45440
45625
|
const title = await options.prompts.text("Issue title", {
|
|
@@ -45446,19 +45631,31 @@ async function runIssueFlow(options) {
|
|
|
45446
45631
|
validate: (value) => value.trim() ? undefined : "Description is required"
|
|
45447
45632
|
});
|
|
45448
45633
|
const report = await runHealthChecks({ ...options, quiet: true });
|
|
45634
|
+
const logLines = readLogLines(report.logFiles);
|
|
45635
|
+
const sessionIds = getLogSessionIds(logLines);
|
|
45636
|
+
let sessionFilter = null;
|
|
45637
|
+
if (sessionIds.length > 1) {
|
|
45638
|
+
const choice = await options.prompts.selectOne("Which OMP session is this issue about? (filters log lines from other sessions)", [
|
|
45639
|
+
...sessionIds.map((sessionId, index) => ({
|
|
45640
|
+
label: `${sessionId}${index === 0 ? " (most recent)" : ""}`,
|
|
45641
|
+
value: sessionId
|
|
45642
|
+
})),
|
|
45643
|
+
{ label: "All sessions (no filtering)", value: "__all__" }
|
|
45644
|
+
]);
|
|
45645
|
+
sessionFilter = choice === "__all__" ? null : choice;
|
|
45646
|
+
}
|
|
45449
45647
|
const path = join33(options.cwd, `magic-context-omp-issue-${timestamp2(options.deps.now())}.md`);
|
|
45450
|
-
|
|
45451
|
-
`);
|
|
45452
|
-
options.prompts.log.success(`Sanitized report written to ${path}`);
|
|
45648
|
+
const bundle = writeOmpIssueReport(path, ompIssueBody(description, report, logLines, sessionFilter));
|
|
45649
|
+
options.prompts.log.success(bundle.fullPath ? `Sanitized report written to ${bundle.path}; full report at ${bundle.fullPath}` : `Sanitized report written to ${bundle.path}`);
|
|
45453
45650
|
if (await options.prompts.confirm("Submit this issue on GitHub now?", false)) {
|
|
45454
|
-
const result = submitGithubIssue(`[omp] ${title}`, path, (args) => runGhCommandWithDeps(options.deps, args));
|
|
45651
|
+
const result = submitGithubIssue(`[omp] ${title}`, bundle.path, (args) => runGhCommandWithDeps(options.deps, args));
|
|
45455
45652
|
if (result.ok) {
|
|
45456
45653
|
options.prompts.log.success(result.output);
|
|
45457
45654
|
} else {
|
|
45458
|
-
options.prompts.log.warn(formatGithubIssueFallback(result, path));
|
|
45655
|
+
options.prompts.log.warn(formatGithubIssueFallback(result, bundle.fullPath ?? bundle.path));
|
|
45459
45656
|
}
|
|
45460
45657
|
}
|
|
45461
|
-
options.prompts.log.info(`Open https://github.com/cortexkit/magic-context/issues/new and drag ${path} into the issue`);
|
|
45658
|
+
options.prompts.log.info(`Open https://github.com/cortexkit/magic-context/issues/new and drag ${bundle.fullPath ?? bundle.path} into the issue`);
|
|
45462
45659
|
return 0;
|
|
45463
45660
|
}
|
|
45464
45661
|
async function runDoctor(options = {}) {
|
|
@@ -45499,6 +45696,7 @@ var init_doctor_omp = __esm(async () => {
|
|
|
45499
45696
|
init_atomic_write();
|
|
45500
45697
|
init_config_location_migration();
|
|
45501
45698
|
init_github_issue();
|
|
45699
|
+
init_issue_body();
|
|
45502
45700
|
init_log_lines();
|
|
45503
45701
|
init_omp_helpers();
|
|
45504
45702
|
init_paths();
|
|
@@ -47576,113 +47774,6 @@ var init_embedding_runtime = __esm(() => {
|
|
|
47576
47774
|
runOnnxRuntimeNodeLoadProbeChildForRuntime = runOnnxRuntimeNodeLoadProbeChild;
|
|
47577
47775
|
});
|
|
47578
47776
|
|
|
47579
|
-
// src/lib/issue-body.ts
|
|
47580
|
-
function isErrorLogLine(line) {
|
|
47581
|
-
const parsed = parseLogLine(line);
|
|
47582
|
-
if (parsed?.level !== null && parsed?.level !== undefined) {
|
|
47583
|
-
return parsed.level === "ERROR" || parsed.level === "WARN";
|
|
47584
|
-
}
|
|
47585
|
-
if (/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/.test(line))
|
|
47586
|
-
return false;
|
|
47587
|
-
const message = parsed?.message ?? line;
|
|
47588
|
-
return ERROR_LOG_PATTERNS.some((rx) => rx.test(message));
|
|
47589
|
-
}
|
|
47590
|
-
function extractRecentErrors(sanitized, limit = 20) {
|
|
47591
|
-
const matches = [];
|
|
47592
|
-
const lines = sanitized.split(/\r?\n/);
|
|
47593
|
-
for (let i = lines.length - 1;i >= 0 && matches.length < limit; i -= 1) {
|
|
47594
|
-
if (isErrorLogLine(lines[i])) {
|
|
47595
|
-
matches.push(lines[i]);
|
|
47596
|
-
}
|
|
47597
|
-
}
|
|
47598
|
-
return matches.reverse();
|
|
47599
|
-
}
|
|
47600
|
-
function capBodyToGithubLimit(body, maxBytes = MAX_GITHUB_BODY_BYTES) {
|
|
47601
|
-
if (Buffer.byteLength(body, "utf8") <= maxBytes)
|
|
47602
|
-
return body;
|
|
47603
|
-
let capped = body;
|
|
47604
|
-
const heading = "## Log (last";
|
|
47605
|
-
const headingIdx = body.indexOf(heading);
|
|
47606
|
-
if (headingIdx === -1) {
|
|
47607
|
-
const markerBytes = Buffer.byteLength(FALLBACK_TRUNCATION_MARKER, "utf8");
|
|
47608
|
-
capped = truncateToByteBudget(body, maxBytes - markerBytes) + FALLBACK_TRUNCATION_MARKER;
|
|
47609
|
-
return enforceFinalBodyLimit(capped, maxBytes);
|
|
47610
|
-
}
|
|
47611
|
-
const fenceOpenIdx = body.indexOf("\n```", headingIdx);
|
|
47612
|
-
if (fenceOpenIdx === -1)
|
|
47613
|
-
return enforceFinalBodyLimit(body, maxBytes);
|
|
47614
|
-
const logStart = fenceOpenIdx + "\n```\n".length;
|
|
47615
|
-
const fenceCloseIdx = body.indexOf("\n```", logStart);
|
|
47616
|
-
if (fenceCloseIdx === -1)
|
|
47617
|
-
return enforceFinalBodyLimit(body, maxBytes);
|
|
47618
|
-
const head = body.slice(0, logStart);
|
|
47619
|
-
const log = body.slice(logStart, fenceCloseIdx);
|
|
47620
|
-
const tail = body.slice(fenceCloseIdx);
|
|
47621
|
-
const overheadBytes = Buffer.byteLength(head, "utf8") + Buffer.byteLength(tail, "utf8");
|
|
47622
|
-
const markerBytes = Buffer.byteLength(LOG_TRUNCATION_MARKER, "utf8");
|
|
47623
|
-
const logBudget = maxBytes - overheadBytes - markerBytes;
|
|
47624
|
-
if (logBudget <= 0) {
|
|
47625
|
-
capped = `${head}${LOG_TRUNCATION_MARKER}${tail}`;
|
|
47626
|
-
return enforceFinalBodyLimit(capped, maxBytes);
|
|
47627
|
-
}
|
|
47628
|
-
const lines = log.split(`
|
|
47629
|
-
`);
|
|
47630
|
-
let keepLines = lines;
|
|
47631
|
-
let kept = keepLines.join(`
|
|
47632
|
-
`);
|
|
47633
|
-
while (Buffer.byteLength(kept, "utf8") > logBudget && keepLines.length > 1) {
|
|
47634
|
-
const dropCount = Math.max(1, Math.floor(keepLines.length * 0.05));
|
|
47635
|
-
keepLines = keepLines.slice(dropCount);
|
|
47636
|
-
kept = keepLines.join(`
|
|
47637
|
-
`);
|
|
47638
|
-
}
|
|
47639
|
-
if (Buffer.byteLength(kept, "utf8") > logBudget) {
|
|
47640
|
-
kept = truncateToByteBudget(kept, logBudget);
|
|
47641
|
-
}
|
|
47642
|
-
capped = `${head}${LOG_TRUNCATION_MARKER}${kept}${tail}`;
|
|
47643
|
-
return enforceFinalBodyLimit(capped, maxBytes);
|
|
47644
|
-
}
|
|
47645
|
-
function enforceFinalBodyLimit(body, maxBytes) {
|
|
47646
|
-
if (Buffer.byteLength(body, "utf8") <= maxBytes)
|
|
47647
|
-
return body;
|
|
47648
|
-
const markerBytes = Buffer.byteLength(FINAL_TRUNCATION_MARKER, "utf8");
|
|
47649
|
-
if (markerBytes >= maxBytes) {
|
|
47650
|
-
return truncateToByteBudget(FINAL_TRUNCATION_MARKER, maxBytes);
|
|
47651
|
-
}
|
|
47652
|
-
return truncateToByteBudget(body, maxBytes - markerBytes) + FINAL_TRUNCATION_MARKER;
|
|
47653
|
-
}
|
|
47654
|
-
function truncateToByteBudget(input, maxBytes) {
|
|
47655
|
-
if (maxBytes <= 0)
|
|
47656
|
-
return "";
|
|
47657
|
-
const buf = Buffer.from(input, "utf8");
|
|
47658
|
-
if (buf.length <= maxBytes)
|
|
47659
|
-
return input;
|
|
47660
|
-
let end = maxBytes;
|
|
47661
|
-
while (end > 0 && (buf[end] & 192) === 128) {
|
|
47662
|
-
end -= 1;
|
|
47663
|
-
}
|
|
47664
|
-
return buf.subarray(0, end).toString("utf8");
|
|
47665
|
-
}
|
|
47666
|
-
var MAX_GITHUB_BODY_BYTES = 60000, LOG_TRUNCATION_MARKER = `[truncated for GitHub 64KB limit — older log lines dropped]
|
|
47667
|
-
`, FINAL_TRUNCATION_MARKER = `
|
|
47668
|
-
|
|
47669
|
-
[truncated further to fit GitHub body limit]
|
|
47670
|
-
`, FALLBACK_TRUNCATION_MARKER = `
|
|
47671
|
-
|
|
47672
|
-
[truncated for GitHub 64KB limit]
|
|
47673
|
-
`, ERROR_LOG_PATTERNS;
|
|
47674
|
-
var init_issue_body = __esm(() => {
|
|
47675
|
-
init_log_lines();
|
|
47676
|
-
ERROR_LOG_PATTERNS = [
|
|
47677
|
-
/\bfailed:/i,
|
|
47678
|
-
/\b(?:[A-Z][a-zA-Z]*)?Error:\s/,
|
|
47679
|
-
/\bEMERGENCY\b/,
|
|
47680
|
-
/\bexception\b/i,
|
|
47681
|
-
/^\s+at\s+[\w.<>$]+\s+\(/,
|
|
47682
|
-
/^\s+at\s+(?:file:|node_modules\/|[^/\s]+:\d+)/
|
|
47683
|
-
];
|
|
47684
|
-
});
|
|
47685
|
-
|
|
47686
47777
|
// src/lib/logs-opencode.ts
|
|
47687
47778
|
import { mkdirSync as mkdirSync7, writeFileSync as writeFileSync7 } from "node:fs";
|
|
47688
47779
|
import { dirname as dirname24, join as join37 } from "node:path";
|
|
@@ -47715,20 +47806,6 @@ function extractHistorianFailureLines(sanitized, limit = 30) {
|
|
|
47715
47806
|
}
|
|
47716
47807
|
return matches.reverse();
|
|
47717
47808
|
}
|
|
47718
|
-
function filterLogLinesBySession(lines, sessionId) {
|
|
47719
|
-
if (!sessionId)
|
|
47720
|
-
return lines;
|
|
47721
|
-
const otherSessionPattern = /\bses_[A-Za-z0-9]{3,64}\b/g;
|
|
47722
|
-
return lines.filter((line) => {
|
|
47723
|
-
const parsed = parseLogLine(line);
|
|
47724
|
-
if (parsed?.session && parsed.session !== sessionId)
|
|
47725
|
-
return false;
|
|
47726
|
-
const matches = parsed?.message.match(otherSessionPattern) ?? line.match(otherSessionPattern);
|
|
47727
|
-
if (!matches)
|
|
47728
|
-
return true;
|
|
47729
|
-
return matches.every((id) => id === sessionId);
|
|
47730
|
-
});
|
|
47731
|
-
}
|
|
47732
47809
|
async function bundleIssueReport(report, description, title, sessionFilter = null, options = {}) {
|
|
47733
47810
|
const LOG_TAIL_LINES = 400;
|
|
47734
47811
|
const allLogLines = readLogLines(report.logFiles ?? [report.logFile]);
|
|
@@ -50610,24 +50687,10 @@ function formatTimestamp2(date) {
|
|
|
50610
50687
|
pad(date.getSeconds())
|
|
50611
50688
|
].join("");
|
|
50612
50689
|
}
|
|
50613
|
-
function filterLogLinesBySession2(lines, sessionId) {
|
|
50614
|
-
if (!sessionId)
|
|
50615
|
-
return lines;
|
|
50616
|
-
const otherSessionPattern = /\bses_[A-Za-z0-9]{3,64}\b/g;
|
|
50617
|
-
return lines.filter((line) => {
|
|
50618
|
-
const parsed = parseLogLine(line);
|
|
50619
|
-
if (parsed?.session && parsed.session !== sessionId)
|
|
50620
|
-
return false;
|
|
50621
|
-
const matches = parsed?.message.match(otherSessionPattern) ?? line.match(otherSessionPattern);
|
|
50622
|
-
if (!matches)
|
|
50623
|
-
return true;
|
|
50624
|
-
return matches.every((id) => id === sessionId);
|
|
50625
|
-
});
|
|
50626
|
-
}
|
|
50627
50690
|
async function bundleIssueReport2(report, description, title, options = {}) {
|
|
50628
50691
|
const LOG_TAIL_LINES = 400;
|
|
50629
50692
|
const allLogLines = readLogLines(report.logFiles ?? [report.logFile]);
|
|
50630
|
-
const logLines =
|
|
50693
|
+
const logLines = filterLogLinesBySession(allLogLines, options.sessionFilter ?? null);
|
|
50631
50694
|
const recentLog = sanitizeLogContent2(logLines.slice(-LOG_TAIL_LINES).join(`
|
|
50632
50695
|
`)).trim();
|
|
50633
50696
|
const errorScanWindow = sanitizeLogContent2(logLines.slice(-4000).join(`
|