oh-my-opencode 5.1.32 → 5.1.34
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/README.ja.md +1 -1
- package/README.ko.md +1 -1
- package/README.md +1 -1
- package/README.ru.md +1 -1
- package/README.zh-cn.md +1 -1
- package/dist/cli/account-keys/commands.d.ts +9 -0
- package/dist/cli/account-keys/keyring.d.ts +16 -0
- package/dist/cli/account-keys/keystore.d.ts +34 -0
- package/dist/cli/index.js +91401 -90585
- package/dist/cli/service-auth/accounts-closed.fixture.d.ts +1 -0
- package/dist/cli/service-auth/commands.d.ts +4 -1
- package/dist/cli/worktree-sweep/types.d.ts +3 -1
- package/dist/cli-node/index.js +91521 -90705
- package/dist/features/background-agent/concurrency.d.ts +6 -0
- package/dist/features/background-agent/manager.d.ts +2 -0
- package/dist/features/background-agent/task-history.d.ts +1 -0
- package/dist/features/background-agent/types.d.ts +2 -0
- package/dist/index.js +362 -126
- package/dist/skills/browser/runtime/omowright/index.js +6 -5
- package/dist/skills/browser/runtime/omowright/manifest.json +3 -3
- package/dist/skills/ulw-execute/SKILL.md +9 -6
- package/dist/skills/ulw-research/AGENTS.md +3 -2
- package/dist/skills/ulw-research/SKILL.md +7 -5
- package/dist/skills/ulw-research/references/deliverable-phase.md +1 -1
- package/dist/skills/ulw-research/references/report-gates.md +2 -0
- package/dist/skills/ulw-research/references/report-visualization.md +126 -0
- package/dist/skills/ulw-research/scripts/contracts.mjs +3 -1
- package/dist/skills/ulw-research/scripts/contracts.test.ts +2 -0
- package/dist/skills/ulw-research/scripts/gates-figures.mjs +33 -1
- package/dist/skills/ulw-research/scripts/gates-static.mjs +2 -2
- package/dist/skills/ulw-research/scripts/gates-static.test.ts +56 -3
- package/dist/skills/ulw-research/scripts/tests/fixtures/bad-report.html +4 -0
- package/dist/startup-migration.d.ts +3 -0
- package/dist/tui.js +55 -24
- package/package.json +15 -15
- package/packages/omo-codex/plugin/.codex-plugin/plugin.json +1 -1
- package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +1 -0
- package/packages/omo-codex/plugin/components/bootstrap/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
- package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/comment-checker/package.json +1 -1
- package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
- package/packages/omo-codex/plugin/components/git-bash/package.json +1 -1
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +1 -1
- package/packages/omo-codex/plugin/components/lsp/dist/.omo-runtime-manifest.json +2 -2
- package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
- package/packages/omo-codex/plugin/components/lsp/package.json +1 -1
- package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
- package/packages/omo-codex/plugin/components/rules/package.json +1 -1
- package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/teammode/package.json +1 -1
- package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/telemetry/package.json +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/package.json +1 -1
- package/packages/omo-codex/plugin/components/ulw-execute-continuation/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/ulw-execute-continuation/package.json +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +5 -5
- package/packages/omo-codex/plugin/components/ulw-loop/package.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-recording-spawn-admission.json +1 -1
- package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +1 -1
- package/packages/omo-codex/plugin/hooks/pre-tool-use-guarding-ulw-loop-spawns.json +1 -1
- package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +1 -1
- package/packages/omo-codex/plugin/hooks/stop-checking-ulw-execute-continuation.json +1 -1
- package/packages/omo-codex/plugin/hooks/stop-checking-ulw-loop-resume.json +1 -1
- package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +1 -1
- package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +1 -1
- package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +1 -1
- package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +1 -1
- package/packages/omo-codex/plugin/package-lock.json +12 -12
- package/packages/omo-codex/plugin/package.json +1 -1
- package/packages/omo-codex/plugin/skills/browser/runtime/omowright/index.js +6 -5
- package/packages/omo-codex/plugin/skills/browser/runtime/omowright/manifest.json +3 -3
- package/packages/omo-codex/plugin/skills/ulw-execute/SKILL.md +9 -6
- package/packages/omo-codex/plugin/skills/ulw-research/AGENTS.md +3 -2
- package/packages/omo-codex/plugin/skills/ulw-research/SKILL.md +7 -5
- package/packages/omo-codex/plugin/skills/ulw-research/references/deliverable-phase.md +1 -1
- package/packages/omo-codex/plugin/skills/ulw-research/references/report-gates.md +2 -0
- package/packages/omo-codex/plugin/skills/ulw-research/references/report-visualization.md +126 -0
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/contracts.mjs +3 -1
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/gates-figures.mjs +33 -1
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/gates-static.mjs +2 -2
- package/packages/omo-codex/scripts/install-dist/install-local.mjs +3 -2
- package/packages/shared-skills/skills/browser/runtime/omowright/index.js +6 -5
- package/packages/shared-skills/skills/browser/runtime/omowright/manifest.json +3 -3
- package/packages/shared-skills/skills/ulw-execute/SKILL.md +9 -6
- package/packages/shared-skills/skills/ulw-research/AGENTS.md +3 -2
- package/packages/shared-skills/skills/ulw-research/SKILL.md +7 -5
- package/packages/shared-skills/skills/ulw-research/references/deliverable-phase.md +1 -1
- package/packages/shared-skills/skills/ulw-research/references/report-gates.md +2 -0
- package/packages/shared-skills/skills/ulw-research/references/report-visualization.md +126 -0
- package/packages/shared-skills/skills/ulw-research/scripts/contracts.mjs +3 -1
- package/packages/shared-skills/skills/ulw-research/scripts/contracts.test.ts +2 -0
- package/packages/shared-skills/skills/ulw-research/scripts/gates-figures.mjs +33 -1
- package/packages/shared-skills/skills/ulw-research/scripts/gates-static.mjs +2 -2
- package/packages/shared-skills/skills/ulw-research/scripts/gates-static.test.ts +56 -3
- package/packages/shared-skills/skills/ulw-research/scripts/tests/fixtures/bad-report.html +4 -0
package/dist/index.js
CHANGED
|
@@ -4713,11 +4713,6 @@ function formatDurationHuman(milliseconds) {
|
|
|
4713
4713
|
return `${seconds}s`;
|
|
4714
4714
|
}
|
|
4715
4715
|
|
|
4716
|
-
// packages/utils/src/shell-command-escape.ts
|
|
4717
|
-
function shellEscapeForDoubleQuotedCommand(value) {
|
|
4718
|
-
return value.replace(/\\/g, "\\\\").replace(/\$/g, "\\$").replace(/`/g, "\\`").replace(/"/g, "\\\"").replace(/;/g, "\\;").replace(/\|/g, "\\|").replace(/&/g, "\\&").replace(/#/g, "\\#").replace(/\(/g, "\\(").replace(/\)/g, "\\)");
|
|
4719
|
-
}
|
|
4720
|
-
|
|
4721
4716
|
// packages/utils/src/jsonc-parser.ts
|
|
4722
4717
|
function stripBom3(content) {
|
|
4723
4718
|
return content.charCodeAt(0) === 65279 ? content.slice(1) : content;
|
|
@@ -6187,58 +6182,52 @@ function toGitFileStatus(statusToken) {
|
|
|
6187
6182
|
return "deleted";
|
|
6188
6183
|
return "modified";
|
|
6189
6184
|
}
|
|
6190
|
-
function normalizeGitStatusPath(statusToken, filePath) {
|
|
6191
|
-
if (statusToken !== "R" && statusToken !== "C")
|
|
6192
|
-
return filePath;
|
|
6193
|
-
const arrowIndex = filePath.lastIndexOf(" -> ");
|
|
6194
|
-
return arrowIndex === -1 ? filePath : filePath.slice(arrowIndex + 4);
|
|
6195
|
-
}
|
|
6196
|
-
function parseGitStatusPorcelainLine(line) {
|
|
6197
|
-
if (!line)
|
|
6198
|
-
return null;
|
|
6199
|
-
const statusToken = line.substring(0, 2).trim();
|
|
6200
|
-
const filePath = normalizeGitStatusPath(statusToken, line.substring(3));
|
|
6201
|
-
if (!filePath)
|
|
6202
|
-
return null;
|
|
6203
|
-
return {
|
|
6204
|
-
filePath,
|
|
6205
|
-
status: toGitFileStatus(statusToken)
|
|
6206
|
-
};
|
|
6207
|
-
}
|
|
6208
6185
|
|
|
6209
|
-
// packages/utils/src/git-worktree/parse-status-porcelain.ts
|
|
6210
|
-
function
|
|
6186
|
+
// packages/utils/src/git-worktree/parse-status-porcelain-z.ts
|
|
6187
|
+
function parseGitStatusPorcelainZ(output) {
|
|
6211
6188
|
const map = new Map;
|
|
6212
6189
|
if (!output)
|
|
6213
6190
|
return map;
|
|
6214
|
-
|
|
6215
|
-
|
|
6216
|
-
const
|
|
6217
|
-
if (
|
|
6191
|
+
const fields = output.split("\x00");
|
|
6192
|
+
for (let index = 0;index < fields.length; index++) {
|
|
6193
|
+
const record = fields[index];
|
|
6194
|
+
if (record.length < 4)
|
|
6218
6195
|
continue;
|
|
6219
|
-
|
|
6196
|
+
const statusCode = record.substring(0, 2);
|
|
6197
|
+
map.set(record.substring(3), statusCode.includes("C") ? "added" : toGitFileStatus(statusCode.trim()));
|
|
6198
|
+
if (statusCode.includes("R") || statusCode.includes("C"))
|
|
6199
|
+
index++;
|
|
6220
6200
|
}
|
|
6221
6201
|
return map;
|
|
6222
6202
|
}
|
|
6223
|
-
var
|
|
6203
|
+
var init_parse_status_porcelain_z = () => {};
|
|
6224
6204
|
|
|
6225
|
-
// packages/utils/src/git-worktree/parse-diff-numstat.ts
|
|
6226
|
-
function
|
|
6205
|
+
// packages/utils/src/git-worktree/parse-diff-numstat-z.ts
|
|
6206
|
+
function toCount(value) {
|
|
6207
|
+
return value === "-" ? 0 : parseInt(value, 10);
|
|
6208
|
+
}
|
|
6209
|
+
function parseGitDiffNumstatZ(output, statusMap) {
|
|
6227
6210
|
if (!output)
|
|
6228
6211
|
return [];
|
|
6229
6212
|
const stats = [];
|
|
6230
|
-
|
|
6231
|
-
|
|
6232
|
-
const
|
|
6233
|
-
|
|
6213
|
+
const fields = output.split("\x00");
|
|
6214
|
+
for (let index = 0;index < fields.length; index++) {
|
|
6215
|
+
const field = fields[index];
|
|
6216
|
+
const firstTab = field.indexOf("\t");
|
|
6217
|
+
const secondTab = field.indexOf("\t", firstTab + 1);
|
|
6218
|
+
if (firstTab === -1 || secondTab === -1)
|
|
6219
|
+
continue;
|
|
6220
|
+
let path = field.slice(secondTab + 1);
|
|
6221
|
+
if (path === "") {
|
|
6222
|
+
index += 2;
|
|
6223
|
+
path = fields[index];
|
|
6224
|
+
}
|
|
6225
|
+
if (!path)
|
|
6234
6226
|
continue;
|
|
6235
|
-
const [addedStr, removedStr, path] = parts;
|
|
6236
|
-
const added = addedStr === "-" ? 0 : parseInt(addedStr, 10);
|
|
6237
|
-
const removed = removedStr === "-" ? 0 : parseInt(removedStr, 10);
|
|
6238
6227
|
stats.push({
|
|
6239
6228
|
path,
|
|
6240
|
-
added,
|
|
6241
|
-
removed,
|
|
6229
|
+
added: toCount(field.slice(0, firstTab)),
|
|
6230
|
+
removed: toCount(field.slice(firstTab + 1, secondTab)),
|
|
6242
6231
|
status: statusMap.get(path) ?? "modified"
|
|
6243
6232
|
});
|
|
6244
6233
|
}
|
|
@@ -6251,46 +6240,43 @@ import * as fs3 from "fs";
|
|
|
6251
6240
|
import { join as join12 } from "path";
|
|
6252
6241
|
function collectGitDiffStats(directory) {
|
|
6253
6242
|
try {
|
|
6254
|
-
const diffOutput = childProcess.execFileSync("git", ["diff", "--numstat", "HEAD"], {
|
|
6243
|
+
const diffOutput = childProcess.execFileSync("git", ["diff", "--numstat", "-z", "-M", "HEAD"], {
|
|
6255
6244
|
cwd: directory,
|
|
6256
6245
|
encoding: "utf-8",
|
|
6257
6246
|
timeout: 5000,
|
|
6258
6247
|
stdio: ["pipe", "pipe", "pipe"]
|
|
6259
|
-
})
|
|
6260
|
-
const statusOutput = childProcess.execFileSync("git", ["status", "--porcelain"], {
|
|
6248
|
+
});
|
|
6249
|
+
const statusOutput = childProcess.execFileSync("git", ["status", "--porcelain", "-z", "--find-renames", "--untracked-files=all"], {
|
|
6261
6250
|
cwd: directory,
|
|
6262
6251
|
encoding: "utf-8",
|
|
6263
6252
|
timeout: 5000,
|
|
6264
6253
|
stdio: ["pipe", "pipe", "pipe"]
|
|
6265
|
-
})
|
|
6266
|
-
const untrackedOutput = childProcess.execFileSync("git", ["ls-files", "--others", "--exclude-standard"], {
|
|
6254
|
+
});
|
|
6255
|
+
const untrackedOutput = childProcess.execFileSync("git", ["ls-files", "-z", "--others", "--exclude-standard"], {
|
|
6267
6256
|
cwd: directory,
|
|
6268
6257
|
encoding: "utf-8",
|
|
6269
6258
|
timeout: 5000,
|
|
6270
6259
|
stdio: ["pipe", "pipe", "pipe"]
|
|
6271
|
-
})
|
|
6272
|
-
const untrackedNumstat = untrackedOutput ? untrackedOutput.split(
|
|
6273
|
-
`).filter(Boolean).map((filePath) => {
|
|
6260
|
+
});
|
|
6261
|
+
const untrackedNumstat = untrackedOutput ? untrackedOutput.split("\x00").filter(Boolean).map((filePath) => {
|
|
6274
6262
|
try {
|
|
6275
6263
|
const content = fs3.readFileSync(join12(directory, filePath), "utf-8");
|
|
6276
6264
|
const lineCount = content.split(`
|
|
6277
6265
|
`).length - (content.endsWith(`
|
|
6278
6266
|
`) ? 1 : 0);
|
|
6279
|
-
return `${lineCount} 0 ${filePath}`;
|
|
6267
|
+
return `${lineCount} 0 ${filePath}\x00`;
|
|
6280
6268
|
} catch (error) {
|
|
6281
6269
|
if (!(error instanceof Error)) {
|
|
6282
6270
|
throw error;
|
|
6283
6271
|
}
|
|
6284
|
-
return `0 0 ${filePath}`;
|
|
6272
|
+
return `0 0 ${filePath}\x00`;
|
|
6285
6273
|
}
|
|
6286
|
-
}).join(
|
|
6287
|
-
|
|
6288
|
-
const combinedNumstat = [diffOutput, untrackedNumstat].filter(Boolean).join(`
|
|
6289
|
-
`).trim();
|
|
6274
|
+
}).join("") : "";
|
|
6275
|
+
const combinedNumstat = diffOutput + untrackedNumstat;
|
|
6290
6276
|
if (!combinedNumstat)
|
|
6291
6277
|
return [];
|
|
6292
|
-
const statusMap =
|
|
6293
|
-
return
|
|
6278
|
+
const statusMap = parseGitStatusPorcelainZ(statusOutput);
|
|
6279
|
+
return parseGitDiffNumstatZ(combinedNumstat, statusMap);
|
|
6294
6280
|
} catch (error) {
|
|
6295
6281
|
if (!(error instanceof Error)) {
|
|
6296
6282
|
throw error;
|
|
@@ -6299,13 +6285,18 @@ function collectGitDiffStats(directory) {
|
|
|
6299
6285
|
}
|
|
6300
6286
|
}
|
|
6301
6287
|
var init_collect_git_diff_stats = __esm(() => {
|
|
6302
|
-
|
|
6288
|
+
init_parse_status_porcelain_z();
|
|
6303
6289
|
});
|
|
6304
6290
|
|
|
6305
6291
|
// packages/utils/src/git-worktree/format-file-changes.ts
|
|
6306
6292
|
function normalizePath(path) {
|
|
6307
6293
|
return path.replaceAll("\\", "/");
|
|
6308
6294
|
}
|
|
6295
|
+
function displayPath2(path) {
|
|
6296
|
+
if (!UNSAFE_DISPLAY_CHARACTER.test(path))
|
|
6297
|
+
return path;
|
|
6298
|
+
return JSON.stringify(path).replace(UNSAFE_DISPLAY_CHARACTERS, (character) => `\\u${character.charCodeAt(0).toString(16).padStart(4, "0")}`);
|
|
6299
|
+
}
|
|
6309
6300
|
function formatFileChanges(stats, notepadPath) {
|
|
6310
6301
|
if (stats.length === 0)
|
|
6311
6302
|
return `[FILE CHANGES SUMMARY]
|
|
@@ -6318,21 +6309,21 @@ No file changes detected.
|
|
|
6318
6309
|
if (modified.length > 0) {
|
|
6319
6310
|
lines.push("Modified files:");
|
|
6320
6311
|
for (const f of modified) {
|
|
6321
|
-
lines.push(` ${f.path} (+${f.added}, -${f.removed})`);
|
|
6312
|
+
lines.push(` ${displayPath2(f.path)} (+${f.added}, -${f.removed})`);
|
|
6322
6313
|
}
|
|
6323
6314
|
lines.push("");
|
|
6324
6315
|
}
|
|
6325
6316
|
if (added.length > 0) {
|
|
6326
6317
|
lines.push("Created files:");
|
|
6327
6318
|
for (const f of added) {
|
|
6328
|
-
lines.push(` ${f.path} (+${f.added})`);
|
|
6319
|
+
lines.push(` ${displayPath2(f.path)} (+${f.added})`);
|
|
6329
6320
|
}
|
|
6330
6321
|
lines.push("");
|
|
6331
6322
|
}
|
|
6332
6323
|
if (deleted.length > 0) {
|
|
6333
6324
|
lines.push("Deleted files:");
|
|
6334
6325
|
for (const f of deleted) {
|
|
6335
|
-
lines.push(` ${f.path} (-${f.removed})`);
|
|
6326
|
+
lines.push(` ${displayPath2(f.path)} (-${f.removed})`);
|
|
6336
6327
|
}
|
|
6337
6328
|
lines.push("");
|
|
6338
6329
|
}
|
|
@@ -6344,17 +6335,23 @@ No file changes detected.
|
|
|
6344
6335
|
});
|
|
6345
6336
|
if (notepadStat) {
|
|
6346
6337
|
lines.push("[NOTEPAD UPDATED]");
|
|
6347
|
-
lines.push(` ${notepadStat.path} (+${notepadStat.added})`);
|
|
6338
|
+
lines.push(` ${displayPath2(notepadStat.path)} (+${notepadStat.added})`);
|
|
6348
6339
|
lines.push("");
|
|
6349
6340
|
}
|
|
6350
6341
|
}
|
|
6351
6342
|
return lines.join(`
|
|
6352
6343
|
`);
|
|
6353
6344
|
}
|
|
6345
|
+
var UNSAFE_DISPLAY_CHARACTER, UNSAFE_DISPLAY_CHARACTERS;
|
|
6346
|
+
var init_format_file_changes = __esm(() => {
|
|
6347
|
+
UNSAFE_DISPLAY_CHARACTER = /[\p{Cc}\u2028\u2029]/u;
|
|
6348
|
+
UNSAFE_DISPLAY_CHARACTERS = /[\p{Cc}\u2028\u2029]/gu;
|
|
6349
|
+
});
|
|
6354
6350
|
|
|
6355
6351
|
// packages/utils/src/git-worktree/index.ts
|
|
6356
6352
|
var init_git_worktree = __esm(() => {
|
|
6357
6353
|
init_collect_git_diff_stats();
|
|
6354
|
+
init_format_file_changes();
|
|
6358
6355
|
});
|
|
6359
6356
|
|
|
6360
6357
|
// packages/utils/src/internal-initiator-marker.ts
|
|
@@ -8331,9 +8328,22 @@ function buildTmuxAttachCommand(serverUrl, sessionId, directory = process.cwd())
|
|
|
8331
8328
|
const escapedDirectory = shellQuoteForNestedCommand(directory || process.cwd());
|
|
8332
8329
|
return `${TMUX_COMMAND_SHELL} -c "opencode attach ${escapedUrl} --session ${escapedSessionId} --dir ${escapedDirectory}"`;
|
|
8333
8330
|
}
|
|
8331
|
+
function withoutNul(value) {
|
|
8332
|
+
return value.replaceAll("\x00", "");
|
|
8333
|
+
}
|
|
8334
|
+
function escapeTmuxFormat(value) {
|
|
8335
|
+
return value.replaceAll("#", "##");
|
|
8336
|
+
}
|
|
8337
|
+
function buildSubagentPaneTitle(description) {
|
|
8338
|
+
const shown = withoutNul(description).slice(0, PANE_TITLE_DESCRIPTION_LIMIT);
|
|
8339
|
+
return `omo-subagent-${escapeTmuxFormat(shown)}`;
|
|
8340
|
+
}
|
|
8334
8341
|
function buildTmuxPlaceholderCommand(description) {
|
|
8335
|
-
const
|
|
8336
|
-
|
|
8342
|
+
const clean = withoutNul(description);
|
|
8343
|
+
const shown = clean.length > PLACEHOLDER_DESCRIPTION_LIMIT ? `${clean.slice(0, PLACEHOLDER_DESCRIPTION_LIMIT)}\u2026` : clean;
|
|
8344
|
+
const banner = shellQuoteForNestedCommand(`OMO subagent pane ready: ${shown}`);
|
|
8345
|
+
const hint = shellQuoteForNestedCommand("Focus this pane to attach.");
|
|
8346
|
+
return `${TMUX_COMMAND_SHELL} -c "printf '%s\\n%s\\n' ${banner} ${hint}; while :; do sleep 86400; done"`;
|
|
8337
8347
|
}
|
|
8338
8348
|
function buildPaneAuthEnvironmentArgs() {
|
|
8339
8349
|
const password = process.env.OPENCODE_SERVER_PASSWORD;
|
|
@@ -8347,10 +8357,7 @@ function buildPaneAuthEnvironmentArgs() {
|
|
|
8347
8357
|
}
|
|
8348
8358
|
return args;
|
|
8349
8359
|
}
|
|
8350
|
-
var TMUX_COMMAND_SHELL = "/bin/sh";
|
|
8351
|
-
var init_pane_command = __esm(() => {
|
|
8352
|
-
init_src();
|
|
8353
|
-
});
|
|
8360
|
+
var TMUX_COMMAND_SHELL = "/bin/sh", PLACEHOLDER_DESCRIPTION_LIMIT = 2000, PANE_TITLE_DESCRIPTION_LIMIT = 20;
|
|
8354
8361
|
|
|
8355
8362
|
// packages/tmux-core/src/tmux-utils/pane-spawn.ts
|
|
8356
8363
|
async function resolveSpawnTmuxPaneDeps(deps) {
|
|
@@ -8422,7 +8429,7 @@ async function spawnTmuxPane(sessionId, description, config, serverUrl, _directo
|
|
|
8422
8429
|
if (result.exitCode !== 0 || !paneId) {
|
|
8423
8430
|
return { success: false };
|
|
8424
8431
|
}
|
|
8425
|
-
const title =
|
|
8432
|
+
const title = buildSubagentPaneTitle(description);
|
|
8426
8433
|
const titleResult = await runTmuxCommand(tmux, ["select-pane", "-t", paneId, "-T", title]);
|
|
8427
8434
|
if (titleResult.exitCode !== 0) {
|
|
8428
8435
|
log("[spawnTmuxPane] WARNING: failed to set pane title", {
|
|
@@ -8437,7 +8444,6 @@ async function spawnTmuxPane(sessionId, description, config, serverUrl, _directo
|
|
|
8437
8444
|
var init_pane_spawn = __esm(() => {
|
|
8438
8445
|
init_environment();
|
|
8439
8446
|
init_server_health();
|
|
8440
|
-
init_pane_command();
|
|
8441
8447
|
});
|
|
8442
8448
|
|
|
8443
8449
|
// packages/tmux-core/src/tmux-utils/pane-close.ts
|
|
@@ -8510,7 +8516,7 @@ async function replaceTmuxPane(paneId, sessionId, description, config, _serverUr
|
|
|
8510
8516
|
log("[replaceTmuxPane] FAILED", { paneId, exitCode: result.exitCode, stderr: result.stderr.trim() });
|
|
8511
8517
|
return { success: false };
|
|
8512
8518
|
}
|
|
8513
|
-
const title =
|
|
8519
|
+
const title = buildSubagentPaneTitle(description);
|
|
8514
8520
|
const titleResult = await runTmuxCommand(tmux, ["select-pane", "-t", paneId, "-T", title]);
|
|
8515
8521
|
if (titleResult.exitCode !== 0) {
|
|
8516
8522
|
log("[replaceTmuxPane] WARNING: failed to set pane title", {
|
|
@@ -8525,7 +8531,6 @@ async function replaceTmuxPane(paneId, sessionId, description, config, _serverUr
|
|
|
8525
8531
|
}
|
|
8526
8532
|
var init_pane_replace = __esm(() => {
|
|
8527
8533
|
init_environment();
|
|
8528
|
-
init_pane_command();
|
|
8529
8534
|
});
|
|
8530
8535
|
|
|
8531
8536
|
// packages/tmux-core/src/tmux-utils/pane-activate.ts
|
|
@@ -8570,7 +8575,6 @@ async function activateTmuxPane(paneId, sessionId, serverUrl, directory, deps =
|
|
|
8570
8575
|
var init_pane_activate = __esm(() => {
|
|
8571
8576
|
init_runner();
|
|
8572
8577
|
init_environment();
|
|
8573
|
-
init_pane_command();
|
|
8574
8578
|
});
|
|
8575
8579
|
|
|
8576
8580
|
// packages/tmux-core/src/tmux-utils/window-spawn.ts
|
|
@@ -8638,7 +8642,7 @@ async function spawnTmuxWindow(sessionId, description, config, serverUrl, _direc
|
|
|
8638
8642
|
log("[spawnTmuxWindow] FAILED", { exitCode: result.exitCode, stderr: result.stderr.trim() });
|
|
8639
8643
|
return { success: false };
|
|
8640
8644
|
}
|
|
8641
|
-
const title =
|
|
8645
|
+
const title = buildSubagentPaneTitle(description);
|
|
8642
8646
|
const titleResult = await runTmuxCommand(tmux, ["select-pane", "-t", paneId, "-T", title]);
|
|
8643
8647
|
if (titleResult.exitCode !== 0) {
|
|
8644
8648
|
log("[spawnTmuxWindow] WARNING: failed to set pane title", {
|
|
@@ -8655,7 +8659,6 @@ var ISOLATED_WINDOW_NAME = "omo-agents";
|
|
|
8655
8659
|
var init_window_spawn = __esm(() => {
|
|
8656
8660
|
init_environment();
|
|
8657
8661
|
init_server_health();
|
|
8658
|
-
init_pane_command();
|
|
8659
8662
|
});
|
|
8660
8663
|
|
|
8661
8664
|
// packages/tmux-core/src/tmux-utils/session-spawn.ts
|
|
@@ -8762,7 +8765,7 @@ async function spawnTmuxSession(sessionId, description, config, serverUrl, _dire
|
|
|
8762
8765
|
log("[spawnTmuxSession] FAILED", { exitCode: result.exitCode, stderr: result.stderr.trim() });
|
|
8763
8766
|
return { success: false };
|
|
8764
8767
|
}
|
|
8765
|
-
const title =
|
|
8768
|
+
const title = buildSubagentPaneTitle(description);
|
|
8766
8769
|
const titleResult = await runTmuxCommand(tmux, ["select-pane", "-t", paneId, "-T", title]);
|
|
8767
8770
|
if (titleResult.exitCode !== 0) {
|
|
8768
8771
|
log("[spawnTmuxSession] WARNING: failed to set pane title", {
|
|
@@ -8779,7 +8782,6 @@ var ISOLATED_SESSION_NAME_PREFIX = "omo-agents";
|
|
|
8779
8782
|
var init_session_spawn = __esm(() => {
|
|
8780
8783
|
init_environment();
|
|
8781
8784
|
init_server_health();
|
|
8782
|
-
init_pane_command();
|
|
8783
8785
|
});
|
|
8784
8786
|
|
|
8785
8787
|
// packages/tmux-core/src/tmux-utils/session-kill.ts
|
|
@@ -8970,7 +8972,6 @@ var init_tmux_utils = __esm(() => {
|
|
|
8970
8972
|
init_session_spawn();
|
|
8971
8973
|
init_session_kill();
|
|
8972
8974
|
init_stale_session_sweep();
|
|
8973
|
-
init_pane_command();
|
|
8974
8975
|
init_layout();
|
|
8975
8976
|
init_spawn_process();
|
|
8976
8977
|
});
|
|
@@ -9469,7 +9470,7 @@ var init_stale_attach_pane_sweep = __esm(() => {
|
|
|
9469
9470
|
});
|
|
9470
9471
|
|
|
9471
9472
|
// packages/omo-opencode/src/shared/tmux/tmux-utils/pane-command.ts
|
|
9472
|
-
var
|
|
9473
|
+
var init_pane_command = () => {};
|
|
9473
9474
|
|
|
9474
9475
|
// packages/omo-opencode/src/shared/tmux/tmux-utils/layout.ts
|
|
9475
9476
|
async function enforceMainPaneWidth2(mainPaneId, windowWidth, mainPaneSizeOrOptions) {
|
|
@@ -9502,7 +9503,7 @@ var init_tmux_utils2 = __esm(() => {
|
|
|
9502
9503
|
init_session_kill2();
|
|
9503
9504
|
init_stale_session_sweep2();
|
|
9504
9505
|
init_stale_attach_pane_sweep();
|
|
9505
|
-
|
|
9506
|
+
init_pane_command();
|
|
9506
9507
|
init_layout2();
|
|
9507
9508
|
});
|
|
9508
9509
|
|
|
@@ -19641,7 +19642,7 @@ function selectExistingTeammatePane(teammatePanes, callerPaneId) {
|
|
|
19641
19642
|
function buildSplitArgs(callerPaneId, teammatePanes, member) {
|
|
19642
19643
|
const environmentArgs = buildPaneEnvironmentArgs();
|
|
19643
19644
|
if (teammatePanes.length === 0) {
|
|
19644
|
-
return ["split-window", ...environmentArgs, "-t", callerPaneId, "-h", "-d", "-l", "70%", "-P", "-F", "#{pane_id}", "-c", getPaneWorkingDirectory(member)];
|
|
19645
|
+
return ["split-window", ...environmentArgs, "-t", callerPaneId, "-h", "-d", "-l", "70%", "-P", "-F", "#{pane_id}", "-c", escapeTmuxFormat(getPaneWorkingDirectory(member))];
|
|
19645
19646
|
}
|
|
19646
19647
|
return [
|
|
19647
19648
|
"split-window",
|
|
@@ -19654,7 +19655,7 @@ function buildSplitArgs(callerPaneId, teammatePanes, member) {
|
|
|
19654
19655
|
"-F",
|
|
19655
19656
|
"#{pane_id}",
|
|
19656
19657
|
"-c",
|
|
19657
|
-
getPaneWorkingDirectory(member)
|
|
19658
|
+
escapeTmuxFormat(getPaneWorkingDirectory(member))
|
|
19658
19659
|
];
|
|
19659
19660
|
}
|
|
19660
19661
|
async function createTeamLayoutInCallerWindow(tmuxPath, callerPaneId, windowTarget, members, serverUrl, deps) {
|
|
@@ -20317,6 +20318,7 @@ var nonNegativeInteger = z5.number().int().nonnegative();
|
|
|
20317
20318
|
var OmoComputerSettingsLayerSchema = z5.object({
|
|
20318
20319
|
enabled: z5.boolean().describe("Experimental: register the computer tool in OmO Native sessions (default: on where the host is supported; false leaves it unregistered)"),
|
|
20319
20320
|
display: z5.string().min(1),
|
|
20321
|
+
showCursor: z5.boolean().describe("Show the display-only macOS cursor overlay (default: true; false hides it)"),
|
|
20320
20322
|
max_width: positiveInteger,
|
|
20321
20323
|
max_height: positiveInteger,
|
|
20322
20324
|
screenshot_max_bytes: positiveInteger,
|
|
@@ -22117,8 +22119,17 @@ function isFileExistsError(error) {
|
|
|
22117
22119
|
function backupCandidate(basePath, attempt) {
|
|
22118
22120
|
return attempt === 0 ? basePath : `${basePath}.${attempt}`;
|
|
22119
22121
|
}
|
|
22122
|
+
function writePlannedBackup(plannedPath, content, fileSystem) {
|
|
22123
|
+
try {
|
|
22124
|
+
if (fileSystem.existsSync(plannedPath) && fileSystem.readFileSync(plannedPath, "utf-8") === content)
|
|
22125
|
+
return plannedPath;
|
|
22126
|
+
} catch {}
|
|
22127
|
+
return writeBackupFrom(plannedPath, content, fileSystem);
|
|
22128
|
+
}
|
|
22120
22129
|
function writeBackup(path, content, fileSystem) {
|
|
22121
|
-
|
|
22130
|
+
return writeBackupFrom(`${path}.bak.${backupSuffix()}`, content, fileSystem);
|
|
22131
|
+
}
|
|
22132
|
+
function writeBackupFrom(basePath, content, fileSystem) {
|
|
22122
22133
|
let attempt = 0;
|
|
22123
22134
|
while (true) {
|
|
22124
22135
|
const candidate = backupCandidate(basePath, attempt);
|
|
@@ -22223,7 +22234,7 @@ function updateOmoConfig(options) {
|
|
|
22223
22234
|
if (existed) {
|
|
22224
22235
|
try {
|
|
22225
22236
|
assertConfigPathIsSafe(path, fileSystem);
|
|
22226
|
-
backupPath = writeBackup(path, content, fileSystem);
|
|
22237
|
+
backupPath = options.backupPath === undefined ? writeBackup(path, content, fileSystem) : writePlannedBackup(options.backupPath, content, fileSystem);
|
|
22227
22238
|
} catch (error) {
|
|
22228
22239
|
if (error instanceof OmoConfigWriteError)
|
|
22229
22240
|
throw error;
|
|
@@ -22540,6 +22551,7 @@ var writeOmoMigrationTarget = (input) => {
|
|
|
22540
22551
|
const options = writerInput(input.targetPath, input.env);
|
|
22541
22552
|
const result = updateOmoConfig({
|
|
22542
22553
|
...options,
|
|
22554
|
+
...input.backupPath === undefined ? {} : { backupPath: input.backupPath },
|
|
22543
22555
|
edits: input.edits,
|
|
22544
22556
|
env: input.env,
|
|
22545
22557
|
fileSystem: input.fileSystem,
|
|
@@ -22548,6 +22560,7 @@ var writeOmoMigrationTarget = (input) => {
|
|
|
22548
22560
|
if (!sameResolvedPath(result.path, input.targetPath)) {
|
|
22549
22561
|
throw new MigrationTransactionError(`Migration writer resolved ${result.path} instead of ${input.targetPath}`);
|
|
22550
22562
|
}
|
|
22563
|
+
return result.backupPath === undefined ? {} : { backupPath: result.backupPath };
|
|
22551
22564
|
};
|
|
22552
22565
|
function prepareTargetWrite(input) {
|
|
22553
22566
|
const targetCleanup = stripRetiredCodegraph(input.target);
|
|
@@ -22585,12 +22598,14 @@ function prepareTargetReplacement(input) {
|
|
|
22585
22598
|
};
|
|
22586
22599
|
}
|
|
22587
22600
|
function writePreparedTarget(input) {
|
|
22588
|
-
input.writeTarget({
|
|
22601
|
+
const written = input.writeTarget({
|
|
22602
|
+
...input.backupPath === undefined ? {} : { backupPath: input.backupPath },
|
|
22589
22603
|
edits: input.prepared.edits,
|
|
22590
22604
|
env: input.env,
|
|
22591
22605
|
fileSystem: input.fileSystem,
|
|
22592
22606
|
targetPath: input.targetPath
|
|
22593
22607
|
});
|
|
22608
|
+
return written?.backupPath;
|
|
22594
22609
|
}
|
|
22595
22610
|
|
|
22596
22611
|
// packages/omo-config-core/src/migration/journal.ts
|
|
@@ -22630,6 +22645,9 @@ function parseJournal(value) {
|
|
|
22630
22645
|
if (!value["completedMoves"].every((path) => typeof path === "string")) {
|
|
22631
22646
|
throw new Error("Migration journal completed moves are invalid");
|
|
22632
22647
|
}
|
|
22648
|
+
const targetBackupPath = value["targetBackupPath"];
|
|
22649
|
+
if (targetBackupPath !== undefined && typeof targetBackupPath !== "string")
|
|
22650
|
+
throw new Error("Migration journal target backup is invalid");
|
|
22633
22651
|
if (!Array.isArray(value["backupMoves"]))
|
|
22634
22652
|
throw new Error("Migration journal backup plan is invalid");
|
|
22635
22653
|
const backupMoves = [];
|
|
@@ -22644,6 +22662,7 @@ function parseJournal(value) {
|
|
|
22644
22662
|
completedMoves: [...value["completedMoves"]],
|
|
22645
22663
|
diagnostics: diagnostics === undefined ? [] : [...diagnostics],
|
|
22646
22664
|
migrationId: value["migrationId"],
|
|
22665
|
+
...targetBackupPath === undefined ? {} : { targetBackupPath },
|
|
22647
22666
|
targetPath: value["targetPath"],
|
|
22648
22667
|
targetWrite: {
|
|
22649
22668
|
additions: { ...value["targetWrite"]["additions"] },
|
|
@@ -22832,12 +22851,24 @@ function acquireMigrationLock(input) {
|
|
|
22832
22851
|
}
|
|
22833
22852
|
|
|
22834
22853
|
// packages/omo-config-core/src/migration/recovery.ts
|
|
22854
|
+
function backupPathForResume(planned, targetPath, fileSystem) {
|
|
22855
|
+
if (planned === undefined || !fileSystem.existsSync(planned) || !fileSystem.existsSync(targetPath))
|
|
22856
|
+
return planned;
|
|
22857
|
+
if (fileSystem.readFileSync(planned, "utf-8") === fileSystem.readFileSync(targetPath, "utf-8"))
|
|
22858
|
+
return planned;
|
|
22859
|
+
let attempt = 1;
|
|
22860
|
+
while (fileSystem.existsSync(`${planned}.${attempt}`))
|
|
22861
|
+
attempt += 1;
|
|
22862
|
+
return `${planned}.${attempt}`;
|
|
22863
|
+
}
|
|
22835
22864
|
function resumeMigrationJournal(input) {
|
|
22836
|
-
const
|
|
22837
|
-
if (
|
|
22838
|
-
return false;
|
|
22865
|
+
const read = readMigrationJournal(input.fileSystem, input.env);
|
|
22866
|
+
if (read === null)
|
|
22867
|
+
return { resumed: false };
|
|
22868
|
+
let journal = read;
|
|
22839
22869
|
input.renewLock();
|
|
22840
22870
|
const target = targetDocument(journal.targetPath, input.fileSystem);
|
|
22871
|
+
let writtenBackupPath;
|
|
22841
22872
|
if (!hasMigrationMarker(target, journal.migrationId)) {
|
|
22842
22873
|
const prepared = journal.targetWrite.mode === "replace-target" ? prepareTargetReplacement({
|
|
22843
22874
|
document: journal.targetWrite.additions,
|
|
@@ -22850,7 +22881,13 @@ function resumeMigrationJournal(input) {
|
|
|
22850
22881
|
target,
|
|
22851
22882
|
targetPath: journal.targetPath
|
|
22852
22883
|
});
|
|
22853
|
-
|
|
22884
|
+
const backupPath = backupPathForResume(journal.targetBackupPath, journal.targetPath, input.fileSystem);
|
|
22885
|
+
if (backupPath !== journal.targetBackupPath && backupPath !== undefined) {
|
|
22886
|
+
journal = { ...journal, targetBackupPath: backupPath };
|
|
22887
|
+
writeMigrationJournal(journal, input.fileSystem, input.env, input.process, input.clock);
|
|
22888
|
+
}
|
|
22889
|
+
writtenBackupPath = writePreparedTarget({
|
|
22890
|
+
...journal.targetBackupPath === undefined ? {} : { backupPath: journal.targetBackupPath },
|
|
22854
22891
|
env: input.env,
|
|
22855
22892
|
fileSystem: input.fileSystem,
|
|
22856
22893
|
prepared,
|
|
@@ -22876,7 +22913,8 @@ function resumeMigrationJournal(input) {
|
|
|
22876
22913
|
writeMigrationJournal(targetRecorded, input.fileSystem, input.env, input.process, input.clock);
|
|
22877
22914
|
}
|
|
22878
22915
|
removeMigrationJournal(input.fileSystem, input.env);
|
|
22879
|
-
|
|
22916
|
+
const targetBackupPath = writtenBackupPath ?? (journal.targetBackupPath !== undefined && input.fileSystem.existsSync(journal.targetBackupPath) ? journal.targetBackupPath : undefined);
|
|
22917
|
+
return targetBackupPath === undefined ? { resumed: true } : { resumed: true, targetBackupPath };
|
|
22880
22918
|
}
|
|
22881
22919
|
|
|
22882
22920
|
// packages/omo-config-core/src/migration/batch.ts
|
|
@@ -22930,6 +22968,15 @@ function assertSafeSourcePaths(sources, protectedPaths) {
|
|
|
22930
22968
|
function directoryPath2(path) {
|
|
22931
22969
|
return path.startsWith("/") ? posix3.dirname(path) : dirname4(path);
|
|
22932
22970
|
}
|
|
22971
|
+
function plannedTargetBackupPath(targetPath, clock, fileSystem) {
|
|
22972
|
+
if (!fileSystem.existsSync(targetPath))
|
|
22973
|
+
return;
|
|
22974
|
+
const base = `${targetPath}.bak.${new Date(clock.now()).toISOString().replace(/[:.]/g, "-")}`;
|
|
22975
|
+
let candidate = base;
|
|
22976
|
+
for (let attempt = 1;fileSystem.existsSync(candidate); attempt += 1)
|
|
22977
|
+
candidate = `${base}.${attempt}`;
|
|
22978
|
+
return candidate;
|
|
22979
|
+
}
|
|
22933
22980
|
function ensureBackupDirectories(moves, fileSystem) {
|
|
22934
22981
|
for (const move of moves)
|
|
22935
22982
|
fileSystem.mkdirSync(directoryPath2(move.to), { recursive: true });
|
|
@@ -22968,11 +23015,13 @@ function executePlan(input) {
|
|
|
22968
23015
|
if (input.dryRun)
|
|
22969
23016
|
return { diagnostics, journalResumed, preview, status: "planned" };
|
|
22970
23017
|
ensureBackupDirectories(moves, fileSystem);
|
|
23018
|
+
const targetBackupPath = plannedTargetBackupPath(plan.targetPath, input.clock, fileSystem);
|
|
22971
23019
|
const journal = {
|
|
22972
23020
|
backupMoves: moves,
|
|
22973
23021
|
completedMoves: [],
|
|
22974
23022
|
diagnostics,
|
|
22975
23023
|
migrationId: plan.id,
|
|
23024
|
+
...targetBackupPath === undefined ? {} : { targetBackupPath },
|
|
22976
23025
|
targetPath: plan.targetPath,
|
|
22977
23026
|
targetWrite: {
|
|
22978
23027
|
additions: transformed.document,
|
|
@@ -22984,7 +23033,7 @@ function executePlan(input) {
|
|
|
22984
23033
|
writeMigrationJournal(journal, fileSystem, env, input.process, input.clock);
|
|
22985
23034
|
input.onBoundary?.("journal-written");
|
|
22986
23035
|
input.renewLock();
|
|
22987
|
-
writePreparedTarget({ env, fileSystem, prepared, targetPath: plan.targetPath, writeTarget: input.writeTarget });
|
|
23036
|
+
writePreparedTarget({ ...targetBackupPath === undefined ? {} : { backupPath: targetBackupPath }, env, fileSystem, prepared, targetPath: plan.targetPath, writeTarget: input.writeTarget });
|
|
22988
23037
|
input.onBoundary?.("target-written");
|
|
22989
23038
|
const targetRecorded = { ...journal, targetWritten: true };
|
|
22990
23039
|
writeMigrationJournal(targetRecorded, fileSystem, env, input.process, input.clock);
|
|
@@ -23000,7 +23049,7 @@ function executePlan(input) {
|
|
|
23000
23049
|
input.onBoundary?.("source-recorded");
|
|
23001
23050
|
}
|
|
23002
23051
|
removeMigrationJournal(fileSystem, env);
|
|
23003
|
-
return { diagnostics, journalResumed, preview, status: "migrated" };
|
|
23052
|
+
return { diagnostics, journalResumed, preview, status: "migrated", ...targetBackupPath === undefined ? {} : { targetBackupPath } };
|
|
23004
23053
|
}
|
|
23005
23054
|
function runMigrations(options) {
|
|
23006
23055
|
const clock = options.clock ?? DEFAULT_MIGRATION_CLOCK;
|
|
@@ -23014,7 +23063,8 @@ function runMigrations(options) {
|
|
|
23014
23063
|
if (lock === null)
|
|
23015
23064
|
return { journalResumed: false, results: [], status: "locked" };
|
|
23016
23065
|
try {
|
|
23017
|
-
const
|
|
23066
|
+
const resumed = resumeMigrationJournal({ clock, env, fileSystem, process: process2, renewLock: lock.renew, writeTarget });
|
|
23067
|
+
const journalResumed = resumed.resumed;
|
|
23018
23068
|
lock.renew();
|
|
23019
23069
|
const results = options.discover().map((plan) => executePlan({
|
|
23020
23070
|
clock,
|
|
@@ -23030,7 +23080,7 @@ function runMigrations(options) {
|
|
|
23030
23080
|
}));
|
|
23031
23081
|
if (options.dryRun !== true)
|
|
23032
23082
|
options.afterMigrations?.(results);
|
|
23033
|
-
return { journalResumed, results, status: "completed" };
|
|
23083
|
+
return { journalResumed, ...resumed.targetBackupPath === undefined ? {} : { resumedTargetBackupPath: resumed.targetBackupPath }, results, status: "completed" };
|
|
23034
23084
|
} finally {
|
|
23035
23085
|
lock.release();
|
|
23036
23086
|
}
|
|
@@ -23094,6 +23144,11 @@ var AGENT_MODEL_REQUIREMENTS = {
|
|
|
23094
23144
|
fallbackChain: [
|
|
23095
23145
|
{ providers: ["openai", "chatgpt-subscription", "opencode"], model: "gpt-5.6-sol", variant: "xhigh" },
|
|
23096
23146
|
{ providers: ["github-copilot"], model: "gpt-5.6-sol", variant: "high" },
|
|
23147
|
+
{
|
|
23148
|
+
providers: ["google", "google-vertex", "opencode"],
|
|
23149
|
+
model: "gemini-4-argon",
|
|
23150
|
+
variant: "high"
|
|
23151
|
+
},
|
|
23097
23152
|
{
|
|
23098
23153
|
providers: ["google", "github-copilot", "opencode"],
|
|
23099
23154
|
model: "gemini-3.1-pro",
|
|
@@ -23183,6 +23238,11 @@ var AGENT_MODEL_REQUIREMENTS = {
|
|
|
23183
23238
|
model: "claude-opus-5-5",
|
|
23184
23239
|
variant: "max"
|
|
23185
23240
|
},
|
|
23241
|
+
{
|
|
23242
|
+
providers: ["google", "google-vertex", "opencode"],
|
|
23243
|
+
model: "gemini-4-argon",
|
|
23244
|
+
variant: "high"
|
|
23245
|
+
},
|
|
23186
23246
|
{
|
|
23187
23247
|
providers: ["google", "github-copilot", "opencode"],
|
|
23188
23248
|
model: "gemini-3.1-pro",
|
|
@@ -23225,6 +23285,7 @@ var AGENT_MODEL_REQUIREMENTS = {
|
|
|
23225
23285
|
var CATEGORY_MODEL_REQUIREMENTS = {
|
|
23226
23286
|
"visual-engineering": {
|
|
23227
23287
|
fallbackChain: [
|
|
23288
|
+
{ providers: ["google", "google-vertex", "opencode"], model: "gemini-4-argon", variant: "low" },
|
|
23228
23289
|
{
|
|
23229
23290
|
providers: ["anthropic", "anthropic-api", "github-copilot", "opencode"],
|
|
23230
23291
|
model: "claude-fable-5-1",
|
|
@@ -23360,6 +23421,7 @@ var CATEGORY_MODEL_REQUIREMENTS = {
|
|
|
23360
23421
|
writing: {
|
|
23361
23422
|
requiresAnyModel: true,
|
|
23362
23423
|
fallbackChain: [
|
|
23424
|
+
{ providers: ["google", "google-vertex", "opencode"], model: "gemini-4-argon", variant: "low" },
|
|
23363
23425
|
{
|
|
23364
23426
|
providers: ["anthropic", "anthropic-api", "github-copilot", "opencode"],
|
|
23365
23427
|
model: "claude-opus-5-5",
|
|
@@ -27880,7 +27942,7 @@ Approach:
|
|
|
27880
27942
|
var GOOGLE_CATEGORIES = [
|
|
27881
27943
|
{
|
|
27882
27944
|
name: "visual-engineering",
|
|
27883
|
-
config: { model: "
|
|
27945
|
+
config: { model: "google/gemini-4-argon", variant: "low" },
|
|
27884
27946
|
description: "Visual design, UI/UX, frontend, styling, animation, and design systems",
|
|
27885
27947
|
promptAppend: VISUAL_CATEGORY_PROMPT_APPEND
|
|
27886
27948
|
},
|
|
@@ -27921,7 +27983,7 @@ ANTI-AI-SLOP RULES (NON-NEGOTIABLE):
|
|
|
27921
27983
|
var KIMI_CATEGORIES = [
|
|
27922
27984
|
{
|
|
27923
27985
|
name: "writing",
|
|
27924
|
-
config: { model: "
|
|
27986
|
+
config: { model: "google/gemini-4-argon", variant: "low" },
|
|
27925
27987
|
description: "Documentation, prose, technical writing",
|
|
27926
27988
|
promptAppend: WRITING_CATEGORY_PROMPT_APPEND
|
|
27927
27989
|
}
|
|
@@ -29434,6 +29496,28 @@ var model_capabilities_generated_default = {
|
|
|
29434
29496
|
generatedAt: "2026-07-29T03:28:21.339Z",
|
|
29435
29497
|
sourceUrl: "https://models.dev/api.json",
|
|
29436
29498
|
models: {
|
|
29499
|
+
"gemini-4-argon": {
|
|
29500
|
+
id: "gemini-4-argon",
|
|
29501
|
+
family: "gemini",
|
|
29502
|
+
reasoning: true,
|
|
29503
|
+
temperature: false,
|
|
29504
|
+
toolCall: true,
|
|
29505
|
+
modalities: {
|
|
29506
|
+
input: [
|
|
29507
|
+
"text",
|
|
29508
|
+
"image",
|
|
29509
|
+
"audio",
|
|
29510
|
+
"pdf"
|
|
29511
|
+
],
|
|
29512
|
+
output: [
|
|
29513
|
+
"text"
|
|
29514
|
+
]
|
|
29515
|
+
},
|
|
29516
|
+
limit: {
|
|
29517
|
+
context: 1048576,
|
|
29518
|
+
output: 65535
|
|
29519
|
+
}
|
|
29520
|
+
},
|
|
29437
29521
|
"glm-5": {
|
|
29438
29522
|
id: "glm-5",
|
|
29439
29523
|
family: "glm",
|
|
@@ -88194,7 +88278,7 @@ function parseToolsConfig(toolsValue) {
|
|
|
88194
88278
|
var ANTHROPIC_PREFIX = "anthropic/";
|
|
88195
88279
|
var CLAUDE_CODE_ALIAS_MAP = new Map([
|
|
88196
88280
|
["sonnet", `${ANTHROPIC_PREFIX}claude-sonnet-4-6`],
|
|
88197
|
-
["opus", `${ANTHROPIC_PREFIX}claude-opus-
|
|
88281
|
+
["opus", `${ANTHROPIC_PREFIX}claude-opus-5-5`],
|
|
88198
88282
|
["haiku", `${ANTHROPIC_PREFIX}claude-haiku-5-5`]
|
|
88199
88283
|
]);
|
|
88200
88284
|
function mapClaudeModelString(model, anthropicProvider) {
|
|
@@ -99137,7 +99221,7 @@ function getCachedVersion(options = {}) {
|
|
|
99137
99221
|
// package.json
|
|
99138
99222
|
var package_default = {
|
|
99139
99223
|
name: "oh-my-opencode",
|
|
99140
|
-
version: "5.1.
|
|
99224
|
+
version: "5.1.34",
|
|
99141
99225
|
description: "The Best AI Agent Harness - Batteries-Included OpenCode Plugin with Multi-Model Orchestration, Parallel Background Agents, and Crafted LSP/AST Tools",
|
|
99142
99226
|
main: "./dist/index.js",
|
|
99143
99227
|
types: "dist/index.d.ts",
|
|
@@ -99314,7 +99398,7 @@ var package_default = {
|
|
|
99314
99398
|
},
|
|
99315
99399
|
devDependencies: {
|
|
99316
99400
|
"@clack/prompts": "^1.8.1",
|
|
99317
|
-
"@code-yeongyu/senpi": "2026.10.
|
|
99401
|
+
"@code-yeongyu/senpi": "2026.10.16",
|
|
99318
99402
|
"@modelcontextprotocol/sdk": "^1.30.0",
|
|
99319
99403
|
"@oh-my-opencode/agents-md-core": "workspace:*",
|
|
99320
99404
|
"@oh-my-opencode/ast-grep-mcp": "workspace:*",
|
|
@@ -99365,7 +99449,7 @@ var package_default = {
|
|
|
99365
99449
|
"js-yaml": "^5.4.2",
|
|
99366
99450
|
"jsonc-parser": "^3.3.1",
|
|
99367
99451
|
"node-pty": "^1.1.0",
|
|
99368
|
-
omowright: "github:code-yeongyu/omowright#
|
|
99452
|
+
omowright: "github:code-yeongyu/omowright#f87ef4d63fe7b56fe117dbab246c8ad88dd8a780",
|
|
99369
99453
|
picocolors: "^1.1.1",
|
|
99370
99454
|
picomatch: "^4.0.7",
|
|
99371
99455
|
"posthog-node": "^5.52.4",
|
|
@@ -99373,18 +99457,18 @@ var package_default = {
|
|
|
99373
99457
|
typescript: "^7.0.2"
|
|
99374
99458
|
},
|
|
99375
99459
|
optionalDependencies: {
|
|
99376
|
-
"oh-my-opencode-darwin-arm64": "5.1.
|
|
99377
|
-
"oh-my-opencode-darwin-x64": "5.1.
|
|
99378
|
-
"oh-my-opencode-darwin-x64-baseline": "5.1.
|
|
99379
|
-
"oh-my-opencode-linux-arm64": "5.1.
|
|
99380
|
-
"oh-my-opencode-linux-arm64-musl": "5.1.
|
|
99381
|
-
"oh-my-opencode-linux-x64": "5.1.
|
|
99382
|
-
"oh-my-opencode-linux-x64-baseline": "5.1.
|
|
99383
|
-
"oh-my-opencode-linux-x64-musl": "5.1.
|
|
99384
|
-
"oh-my-opencode-linux-x64-musl-baseline": "5.1.
|
|
99385
|
-
"oh-my-opencode-windows-arm64": "5.1.
|
|
99386
|
-
"oh-my-opencode-windows-x64": "5.1.
|
|
99387
|
-
"oh-my-opencode-windows-x64-baseline": "5.1.
|
|
99460
|
+
"oh-my-opencode-darwin-arm64": "5.1.34",
|
|
99461
|
+
"oh-my-opencode-darwin-x64": "5.1.34",
|
|
99462
|
+
"oh-my-opencode-darwin-x64-baseline": "5.1.34",
|
|
99463
|
+
"oh-my-opencode-linux-arm64": "5.1.34",
|
|
99464
|
+
"oh-my-opencode-linux-arm64-musl": "5.1.34",
|
|
99465
|
+
"oh-my-opencode-linux-x64": "5.1.34",
|
|
99466
|
+
"oh-my-opencode-linux-x64-baseline": "5.1.34",
|
|
99467
|
+
"oh-my-opencode-linux-x64-musl": "5.1.34",
|
|
99468
|
+
"oh-my-opencode-linux-x64-musl-baseline": "5.1.34",
|
|
99469
|
+
"oh-my-opencode-windows-arm64": "5.1.34",
|
|
99470
|
+
"oh-my-opencode-windows-x64": "5.1.34",
|
|
99471
|
+
"oh-my-opencode-windows-x64-baseline": "5.1.34"
|
|
99388
99472
|
},
|
|
99389
99473
|
overrides: {
|
|
99390
99474
|
hono: "^4.13.8",
|
|
@@ -100605,7 +100689,8 @@ function runOpenCodeStartupMigration(options) {
|
|
|
100605
100689
|
migratedFrom: [],
|
|
100606
100690
|
reloadRequired: false,
|
|
100607
100691
|
results: [],
|
|
100608
|
-
skippedConflictCount: 0
|
|
100692
|
+
skippedConflictCount: 0,
|
|
100693
|
+
targetBackupPaths: []
|
|
100609
100694
|
};
|
|
100610
100695
|
}
|
|
100611
100696
|
try {
|
|
@@ -100629,12 +100714,18 @@ function runOpenCodeStartupMigration(options) {
|
|
|
100629
100714
|
})
|
|
100630
100715
|
});
|
|
100631
100716
|
const migratedFrom = uniqueSources(batch.results);
|
|
100717
|
+
const targetBackupPaths = [
|
|
100718
|
+
...batch.resumedTargetBackupPath === undefined ? [] : [batch.resumedTargetBackupPath],
|
|
100719
|
+
...batch.results.flatMap((result) => result.targetBackupPath === undefined ? [] : [result.targetBackupPath])
|
|
100720
|
+
];
|
|
100632
100721
|
return {
|
|
100633
100722
|
journalResumed: batch.journalResumed,
|
|
100634
100723
|
migratedFrom,
|
|
100635
100724
|
reloadRequired: batch.journalResumed || migratedFrom.length > 0,
|
|
100636
100725
|
results: batch.results,
|
|
100637
100726
|
skippedConflictCount: skippedConflictCount(batch.results),
|
|
100727
|
+
targetBackupPaths,
|
|
100728
|
+
...batch.resumedTargetBackupPath === undefined ? {} : { resumedTargetBackupPath: batch.resumedTargetBackupPath },
|
|
100638
100729
|
...batch.status === "locked" ? { error: "Configuration migration is already running" } : {}
|
|
100639
100730
|
};
|
|
100640
100731
|
} catch (error) {
|
|
@@ -100644,7 +100735,8 @@ function runOpenCodeStartupMigration(options) {
|
|
|
100644
100735
|
migratedFrom: [],
|
|
100645
100736
|
reloadRequired: false,
|
|
100646
100737
|
results: [],
|
|
100647
|
-
skippedConflictCount: 0
|
|
100738
|
+
skippedConflictCount: 0,
|
|
100739
|
+
targetBackupPaths: []
|
|
100648
100740
|
};
|
|
100649
100741
|
}
|
|
100650
100742
|
}
|
|
@@ -142452,17 +142544,24 @@ class ConcurrencyManager {
|
|
|
142452
142544
|
}
|
|
142453
142545
|
return model;
|
|
142454
142546
|
}
|
|
142455
|
-
|
|
142547
|
+
tryAcquire(model) {
|
|
142456
142548
|
const key = this.getConcurrencyKey(model);
|
|
142457
142549
|
const limit = this.getConcurrencyLimit(model);
|
|
142458
142550
|
if (limit === Infinity) {
|
|
142459
|
-
return;
|
|
142551
|
+
return true;
|
|
142460
142552
|
}
|
|
142461
142553
|
const current = this.counts.get(key) ?? 0;
|
|
142462
142554
|
if (current < limit) {
|
|
142463
142555
|
this.counts.set(key, current + 1);
|
|
142556
|
+
return true;
|
|
142557
|
+
}
|
|
142558
|
+
return false;
|
|
142559
|
+
}
|
|
142560
|
+
async acquire(model, taskId) {
|
|
142561
|
+
if (this.tryAcquire(model)) {
|
|
142464
142562
|
return;
|
|
142465
142563
|
}
|
|
142564
|
+
const key = this.getConcurrencyKey(model);
|
|
142466
142565
|
return new Promise((resolve, reject) => {
|
|
142467
142566
|
const queue = this.queues.get(key) ?? [];
|
|
142468
142567
|
const entry = {
|
|
@@ -142765,9 +142864,17 @@ async function tryFallbackRetry(args) {
|
|
|
142765
142864
|
const rawKey = task.model ? `${task.model.providerID}/${task.model.modelID}` : task.agent;
|
|
142766
142865
|
const key = concurrencyManager.getConcurrencyKey(rawKey);
|
|
142767
142866
|
const queue = queuesByKey.get(key) ?? [];
|
|
142867
|
+
const hasContinuation = !!task.originalPrompt && task.originalPrompt !== task.prompt;
|
|
142868
|
+
const retryPrompt = hasContinuation ? `${task.originalPrompt}
|
|
142869
|
+
|
|
142870
|
+
[Latest continuation instruction]
|
|
142871
|
+
${task.prompt}` : task.prompt;
|
|
142872
|
+
const retryNote = hasContinuation ? `
|
|
142873
|
+
|
|
142874
|
+
[Note: this is a retry in a new session after the previous session failed; the earlier session's context is not available. Work from the original task and latest continuation instruction above.]` : "";
|
|
142768
142875
|
const retryInput = {
|
|
142769
142876
|
description: task.description,
|
|
142770
|
-
prompt:
|
|
142877
|
+
prompt: `${retryPrompt}${retryNote}`,
|
|
142771
142878
|
agent: task.agent,
|
|
142772
142879
|
parentSessionId: task.parentSessionId,
|
|
142773
142880
|
parentMessageId: task.parentMessageId,
|
|
@@ -144701,6 +144808,25 @@ class TaskHistory {
|
|
|
144701
144808
|
clearSession(parentSessionID) {
|
|
144702
144809
|
this.entries.delete(parentSessionID);
|
|
144703
144810
|
}
|
|
144811
|
+
restoreEntry(parentSessionID, taskID, entry) {
|
|
144812
|
+
const list = this.entries.get(parentSessionID);
|
|
144813
|
+
if (!list) {
|
|
144814
|
+
if (entry)
|
|
144815
|
+
this.record(parentSessionID, entry);
|
|
144816
|
+
return;
|
|
144817
|
+
}
|
|
144818
|
+
const index = list.findIndex((current) => current.id === taskID);
|
|
144819
|
+
if (index !== -1) {
|
|
144820
|
+
if (entry)
|
|
144821
|
+
list[index] = { ...entry };
|
|
144822
|
+
else
|
|
144823
|
+
list.splice(index, 1);
|
|
144824
|
+
} else if (entry) {
|
|
144825
|
+
this.record(parentSessionID, entry);
|
|
144826
|
+
}
|
|
144827
|
+
if (list.length === 0)
|
|
144828
|
+
this.entries.delete(parentSessionID);
|
|
144829
|
+
}
|
|
144704
144830
|
clearAll() {
|
|
144705
144831
|
this.entries.clear();
|
|
144706
144832
|
}
|
|
@@ -145300,6 +145426,7 @@ class BackgroundManager {
|
|
|
145300
145426
|
processingKeys = new Set;
|
|
145301
145427
|
completionTimers = new Map;
|
|
145302
145428
|
syncAttachedSessions = new Set;
|
|
145429
|
+
resumesAwaitingAdmission = new Set;
|
|
145303
145430
|
completedTaskArchive = new Map;
|
|
145304
145431
|
completedTaskSummaries = new Map;
|
|
145305
145432
|
idleDeferralTimers = new Map;
|
|
@@ -145506,8 +145633,12 @@ class BackgroundManager {
|
|
|
145506
145633
|
taskIDs.add(task.id);
|
|
145507
145634
|
this.tasksByParentSession.set(parentSessionID, taskIDs);
|
|
145508
145635
|
}
|
|
145509
|
-
captureResumeTaskSnapshot(task) {
|
|
145636
|
+
captureResumeTaskSnapshot(task, resumeParentSessionID) {
|
|
145510
145637
|
return {
|
|
145638
|
+
prompt: task.prompt,
|
|
145639
|
+
originalPrompt: task.originalPrompt,
|
|
145640
|
+
queuedAt: task.queuedAt,
|
|
145641
|
+
historyEntry: this.taskHistory.getByParentSession(resumeParentSessionID).find((entry) => entry.id === task.id),
|
|
145511
145642
|
status: task.status,
|
|
145512
145643
|
completedAt: task.completedAt,
|
|
145513
145644
|
error: task.error,
|
|
@@ -145523,16 +145654,23 @@ class BackgroundManager {
|
|
|
145523
145654
|
};
|
|
145524
145655
|
}
|
|
145525
145656
|
restoreTaskAfterSkippedResume(task, snapshot, skippedStatus) {
|
|
145657
|
+
if (this.shutdownTriggered)
|
|
145658
|
+
return;
|
|
145526
145659
|
log2("[background-agent] Restoring task after skipped resume prompt:", {
|
|
145527
145660
|
taskId: task.id,
|
|
145528
145661
|
sessionID: task.sessionId,
|
|
145529
145662
|
skippedStatus
|
|
145530
145663
|
});
|
|
145664
|
+
const resumeParentSessionID = task.parentSessionId;
|
|
145531
145665
|
this.cleanupPendingByParent(task);
|
|
145666
|
+
this.taskHistory.restoreEntry(resumeParentSessionID, task.id, snapshot.historyEntry);
|
|
145532
145667
|
if (task.concurrencyKey) {
|
|
145533
145668
|
this.concurrencyManager.release(task.concurrencyKey);
|
|
145534
145669
|
}
|
|
145535
145670
|
task.status = snapshot.status;
|
|
145671
|
+
task.prompt = snapshot.prompt;
|
|
145672
|
+
task.originalPrompt = snapshot.originalPrompt;
|
|
145673
|
+
task.queuedAt = snapshot.queuedAt;
|
|
145536
145674
|
task.completedAt = snapshot.completedAt;
|
|
145537
145675
|
task.error = snapshot.error;
|
|
145538
145676
|
task.startedAt = snapshot.startedAt;
|
|
@@ -145549,6 +145687,9 @@ class BackgroundManager {
|
|
|
145549
145687
|
this.scheduleTaskRemoval(task.id);
|
|
145550
145688
|
}
|
|
145551
145689
|
this.updateBackgroundTaskMarker(task.parentSessionId);
|
|
145690
|
+
if (resumeParentSessionID !== task.parentSessionId) {
|
|
145691
|
+
this.updateBackgroundTaskMarker(resumeParentSessionID);
|
|
145692
|
+
}
|
|
145552
145693
|
}
|
|
145553
145694
|
removeTaskFromParentIndex(taskID, parentSessionID) {
|
|
145554
145695
|
if (!parentSessionID) {
|
|
@@ -146145,14 +146286,74 @@ The fallback retry session is now created and can be inspected directly.
|
|
|
146145
146286
|
if (existingTask.status === "running") {
|
|
146146
146287
|
throw new Error(`Task ${existingTask.id} is currently running and cannot accept a continuation prompt. ` + "Wait for it to complete before resuming it with task_id.");
|
|
146147
146288
|
}
|
|
146148
|
-
|
|
146289
|
+
if (existingTask.status === "pending" && existingTask.pendingResume) {
|
|
146290
|
+
throw new Error(`Task ${existingTask.id} already has a continuation queued for admission and cannot accept another one. ` + "Wait for it to start and complete before resuming it with task_id.");
|
|
146291
|
+
}
|
|
146292
|
+
if (this.resumesAwaitingAdmission.has(existingTask.id)) {
|
|
146293
|
+
throw new Error(`Task ${existingTask.id} is already being resumed and cannot accept another continuation. ` + "Wait for it to complete before resuming it with task_id.");
|
|
146294
|
+
}
|
|
146295
|
+
const resumeSnapshot = this.captureResumeTaskSnapshot(existingTask, input.parentSessionId);
|
|
146149
146296
|
const completionTimer = this.completionTimers.get(existingTask.id);
|
|
146150
146297
|
if (completionTimer) {
|
|
146151
146298
|
clearTimeout(completionTimer);
|
|
146152
146299
|
this.completionTimers.delete(existingTask.id);
|
|
146153
146300
|
}
|
|
146154
146301
|
const concurrencyKey = this.concurrencyManager.getConcurrencyKey(existingTask.concurrencyGroup ?? existingTask.agent);
|
|
146155
|
-
|
|
146302
|
+
if (this.concurrencyManager.tryAcquire(concurrencyKey)) {
|
|
146303
|
+
this.resumesAwaitingAdmission.add(existingTask.id);
|
|
146304
|
+
try {
|
|
146305
|
+
await Promise.resolve();
|
|
146306
|
+
return await this.startResumedTask(existingTask, input, resumeSnapshot, concurrencyKey);
|
|
146307
|
+
} finally {
|
|
146308
|
+
this.resumesAwaitingAdmission.delete(existingTask.id);
|
|
146309
|
+
}
|
|
146310
|
+
}
|
|
146311
|
+
const admission = this.concurrencyManager.acquire(concurrencyKey, existingTask.id);
|
|
146312
|
+
const resumeToken = {};
|
|
146313
|
+
existingTask.pendingResume = resumeToken;
|
|
146314
|
+
existingTask.status = "pending";
|
|
146315
|
+
existingTask.queuedAt = new Date;
|
|
146316
|
+
existingTask.completedAt = undefined;
|
|
146317
|
+
existingTask.error = undefined;
|
|
146318
|
+
this.updateTaskParent(existingTask, input.parentSessionId);
|
|
146319
|
+
existingTask.parentMessageId = input.parentMessageId;
|
|
146320
|
+
existingTask.parentModel = input.parentModel;
|
|
146321
|
+
existingTask.parentAgent = input.parentAgent;
|
|
146322
|
+
if (input.parentTools)
|
|
146323
|
+
existingTask.parentTools = input.parentTools;
|
|
146324
|
+
if (input.parentSessionId) {
|
|
146325
|
+
const pending = this.pendingByParent.get(input.parentSessionId) ?? new Set;
|
|
146326
|
+
pending.add(existingTask.id);
|
|
146327
|
+
this.pendingByParent.set(input.parentSessionId, pending);
|
|
146328
|
+
}
|
|
146329
|
+
this.taskHistory.record(input.parentSessionId, { id: existingTask.id, sessionID: existingTask.sessionId, agent: existingTask.agent, description: existingTask.description, status: "pending", category: existingTask.category });
|
|
146330
|
+
getTaskToastManager()?.addTask({ id: existingTask.id, description: existingTask.description, agent: existingTask.agent, isBackground: true, status: "queued" });
|
|
146331
|
+
this.updateBackgroundTaskMarker(existingTask.parentSessionId);
|
|
146332
|
+
admission.then(async () => {
|
|
146333
|
+
if (this.shutdownTriggered || existingTask.status !== "pending" || existingTask.pendingResume !== resumeToken) {
|
|
146334
|
+
this.concurrencyManager.release(concurrencyKey);
|
|
146335
|
+
return;
|
|
146336
|
+
}
|
|
146337
|
+
await this.startResumedTask(existingTask, input, resumeSnapshot, concurrencyKey);
|
|
146338
|
+
}).catch((error) => {
|
|
146339
|
+
this.logger("[background-agent] Queued resume was not admitted:", { taskId: existingTask.id, error: error instanceof Error ? error.message : String(error) });
|
|
146340
|
+
if (this.shutdownTriggered || existingTask.status !== "pending" || existingTask.pendingResume !== resumeToken)
|
|
146341
|
+
return;
|
|
146342
|
+
existingTask.pendingResume = undefined;
|
|
146343
|
+
this.restoreTaskAfterSkippedResume(existingTask, resumeSnapshot, "unavailable");
|
|
146344
|
+
});
|
|
146345
|
+
return existingTask;
|
|
146346
|
+
}
|
|
146347
|
+
async startResumedTask(existingTask, input, resumeSnapshot, concurrencyKey) {
|
|
146348
|
+
if (this.shutdownTriggered) {
|
|
146349
|
+
this.concurrencyManager.release(concurrencyKey);
|
|
146350
|
+
return existingTask;
|
|
146351
|
+
}
|
|
146352
|
+
if (!existingTask.sessionId)
|
|
146353
|
+
throw new Error(`Task has no sessionID: ${existingTask.id}`);
|
|
146354
|
+
existingTask.pendingResume = undefined;
|
|
146355
|
+
existingTask.originalPrompt ??= existingTask.prompt;
|
|
146356
|
+
existingTask.prompt = input.prompt;
|
|
146156
146357
|
existingTask.concurrencyKey = concurrencyKey;
|
|
146157
146358
|
existingTask.concurrencyGroup = concurrencyKey;
|
|
146158
146359
|
existingTask.status = "running";
|
|
@@ -146166,6 +146367,15 @@ The fallback retry session is now created and can be inspected directly.
|
|
|
146166
146367
|
existingTask.parentTools = input.parentTools;
|
|
146167
146368
|
}
|
|
146168
146369
|
existingTask.startedAt = new Date;
|
|
146370
|
+
this.taskHistory.record(input.parentSessionId, {
|
|
146371
|
+
id: existingTask.id,
|
|
146372
|
+
sessionID: existingTask.sessionId,
|
|
146373
|
+
agent: existingTask.agent,
|
|
146374
|
+
description: existingTask.description,
|
|
146375
|
+
status: "running",
|
|
146376
|
+
category: existingTask.category,
|
|
146377
|
+
startedAt: existingTask.startedAt
|
|
146378
|
+
});
|
|
146169
146379
|
existingTask.progress = {
|
|
146170
146380
|
toolCalls: existingTask.progress?.toolCalls ?? 0,
|
|
146171
146381
|
toolCallWindow: existingTask.progress?.toolCallWindow,
|
|
@@ -146276,6 +146486,16 @@ The fallback retry session is now created and can be inspected directly.
|
|
|
146276
146486
|
const errorMessage = errorInfo.message ?? (error instanceof Error ? error.message : String(error));
|
|
146277
146487
|
existingTask.error = errorMessage;
|
|
146278
146488
|
existingTask.completedAt = new Date;
|
|
146489
|
+
this.taskHistory.record(existingTask.parentSessionId, {
|
|
146490
|
+
id: existingTask.id,
|
|
146491
|
+
sessionID: existingTask.sessionId,
|
|
146492
|
+
agent: existingTask.agent,
|
|
146493
|
+
description: existingTask.description,
|
|
146494
|
+
status: "interrupt",
|
|
146495
|
+
category: existingTask.category,
|
|
146496
|
+
startedAt: existingTask.startedAt,
|
|
146497
|
+
completedAt: existingTask.completedAt
|
|
146498
|
+
});
|
|
146279
146499
|
if (existingTask.rootSessionId) {
|
|
146280
146500
|
this.unregisterRootDescendant(existingTask.rootSessionId);
|
|
146281
146501
|
}
|
|
@@ -147596,7 +147816,17 @@ The task was re-queued on a fallback model after a retryable failure.
|
|
|
147596
147816
|
this.stopPolling();
|
|
147597
147817
|
const trackedSessionIDs = new Set;
|
|
147598
147818
|
const abortRequests = [];
|
|
147819
|
+
const queuedResumeParents = new Set;
|
|
147599
147820
|
for (const task of this.tasks.values()) {
|
|
147821
|
+
if (task.pendingResume) {
|
|
147822
|
+
queuedResumeParents.add(task.parentSessionId);
|
|
147823
|
+
task.pendingResume = undefined;
|
|
147824
|
+
task.status = "cancelled";
|
|
147825
|
+
task.completedAt = new Date;
|
|
147826
|
+
this.concurrencyManager.cancelWaiter(task.concurrencyGroup ?? task.agent, task.id);
|
|
147827
|
+
this.cleanupPendingByParent(task);
|
|
147828
|
+
removeTaskToastTracking(task.id);
|
|
147829
|
+
}
|
|
147600
147830
|
if (task.sessionId) {
|
|
147601
147831
|
trackedSessionIDs.add(task.sessionId);
|
|
147602
147832
|
}
|
|
@@ -147662,6 +147892,9 @@ The task was re-queued on a fallback model after a retryable failure.
|
|
|
147662
147892
|
this.queuesByKey.clear();
|
|
147663
147893
|
this.processingKeys.clear();
|
|
147664
147894
|
this.taskHistory.clearAll();
|
|
147895
|
+
for (const parentSessionID of queuedResumeParents) {
|
|
147896
|
+
this.updateBackgroundTaskMarker(parentSessionID);
|
|
147897
|
+
}
|
|
147665
147898
|
this.completedTaskSummaries.clear();
|
|
147666
147899
|
this.unregisterProcessCleanup();
|
|
147667
147900
|
log2("[background-agent] Shutdown complete");
|
|
@@ -187988,11 +188221,12 @@ function startupToastBody(input) {
|
|
|
187988
188221
|
const summary = input.migratedFrom.length === 0 ? "" : `Migrated ${input.migratedFrom.length} legacy source${input.migratedFrom.length === 1 ? "" : "s"}.`;
|
|
187989
188222
|
const conflicts = input.skippedConflictCount === 0 ? "" : ` Kept ${input.skippedConflictCount} existing value${input.skippedConflictCount === 1 ? "" : "s"}.`;
|
|
187990
188223
|
const diagnostics = input.diagnostics.length === 0 ? "" : ` ${input.diagnostics.join(" ")}`;
|
|
188224
|
+
const backups = input.targetBackupPaths.length === 0 ? "" : ` Previous config saved as ${input.targetBackupPaths.join(", ")}.`;
|
|
187991
188225
|
if (input.error !== undefined) {
|
|
187992
|
-
return { title: "Configuration migration failed", message: `${input.error}${diagnostics}`, variant: "error" };
|
|
188226
|
+
return { title: "Configuration migration failed", message: `${input.error}${backups}${diagnostics}`, variant: "error" };
|
|
187993
188227
|
}
|
|
187994
|
-
if (summary.length > 0)
|
|
187995
|
-
return { title: "Configuration migrated", message: `${summary}${conflicts}${diagnostics}
|
|
188228
|
+
if (summary.length > 0 || backups.length > 0)
|
|
188229
|
+
return { title: "Configuration migrated", message: `${summary}${conflicts}${backups}${diagnostics}`.trim(), variant: "success" };
|
|
187996
188230
|
if (diagnostics.length > 0)
|
|
187997
188231
|
return { title: "Configuration diagnostics", message: input.diagnostics.join(" "), variant: "warning" };
|
|
187998
188232
|
return;
|
|
@@ -188015,7 +188249,8 @@ function createPluginModule(overrides = {}) {
|
|
|
188015
188249
|
error: startupMigration.error,
|
|
188016
188250
|
journalResumed: startupMigration.journalResumed,
|
|
188017
188251
|
migratedFrom: startupMigration.migratedFrom,
|
|
188018
|
-
skippedConflictCount: startupMigration.skippedConflictCount
|
|
188252
|
+
skippedConflictCount: startupMigration.skippedConflictCount,
|
|
188253
|
+
targetBackupPaths: startupMigration.targetBackupPaths
|
|
188019
188254
|
});
|
|
188020
188255
|
if (startupMigration.error !== undefined) {
|
|
188021
188256
|
console.warn(`[config-migration] legacy configuration changes were not applied: ${startupMigration.error}`);
|
|
@@ -188024,7 +188259,8 @@ function createPluginModule(overrides = {}) {
|
|
|
188024
188259
|
diagnostics: startupDiagnostics,
|
|
188025
188260
|
...startupMigration.error === undefined ? {} : { error: startupMigration.error },
|
|
188026
188261
|
migratedFrom: startupMigration.migratedFrom,
|
|
188027
|
-
skippedConflictCount: startupMigration.skippedConflictCount
|
|
188262
|
+
skippedConflictCount: startupMigration.skippedConflictCount,
|
|
188263
|
+
targetBackupPaths: startupMigration.targetBackupPaths
|
|
188028
188264
|
});
|
|
188029
188265
|
if (toast !== undefined)
|
|
188030
188266
|
showStartupToast(input.client, toast, deps.log);
|