oh-my-opencode 3.17.13 → 3.17.15
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/cli/index.js +181 -46
- package/dist/cli/run/continuation-state.d.ts +1 -0
- package/dist/features/background-agent/manager.d.ts +1 -0
- package/dist/features/background-agent/process-cleanup.d.ts +4 -0
- package/dist/features/run-continuation-state/types.d.ts +1 -1
- package/dist/features/skill-mcp-manager/types.d.ts +1 -0
- package/dist/index.js +330 -143
- package/dist/shared/bun-spawn-shim.d.ts +39 -0
- package/dist/shared/tmux/tmux-utils/spawn-process.d.ts +1 -1
- package/package.json +14 -13
package/dist/index.js
CHANGED
|
@@ -44,7 +44,8 @@ var __export = (target, all) => {
|
|
|
44
44
|
});
|
|
45
45
|
};
|
|
46
46
|
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
47
|
-
|
|
47
|
+
import { createRequire as __omoCreateRequire } from "node:module";
|
|
48
|
+
var __require = typeof import.meta.require === "function" ? import.meta.require : __omoCreateRequire(import.meta.url);
|
|
48
49
|
|
|
49
50
|
// node_modules/js-yaml/dist/js-yaml.mjs
|
|
50
51
|
function isNothing(subject) {
|
|
@@ -2770,6 +2771,119 @@ var init_logger = __esm(() => {
|
|
|
2770
2771
|
buffer = [];
|
|
2771
2772
|
});
|
|
2772
2773
|
|
|
2774
|
+
// src/shared/bun-spawn-shim.ts
|
|
2775
|
+
import { spawn as nodeSpawn, spawnSync as nodeSpawnSync } from "child_process";
|
|
2776
|
+
import { Readable, Writable } from "stream";
|
|
2777
|
+
function emptyReadableStream() {
|
|
2778
|
+
return new ReadableStream({
|
|
2779
|
+
start(controller) {
|
|
2780
|
+
controller.close();
|
|
2781
|
+
}
|
|
2782
|
+
});
|
|
2783
|
+
}
|
|
2784
|
+
function toReadableStream(stream) {
|
|
2785
|
+
if (!stream)
|
|
2786
|
+
return emptyReadableStream();
|
|
2787
|
+
return Readable.toWeb(stream);
|
|
2788
|
+
}
|
|
2789
|
+
function emptyWritableStream() {
|
|
2790
|
+
return new Writable({
|
|
2791
|
+
write(_chunk, _encoding, callback) {
|
|
2792
|
+
callback();
|
|
2793
|
+
}
|
|
2794
|
+
});
|
|
2795
|
+
}
|
|
2796
|
+
function resolveCommand(cmdOrOpts, optsArg) {
|
|
2797
|
+
const isObj = !Array.isArray(cmdOrOpts);
|
|
2798
|
+
const opts = isObj ? cmdOrOpts : optsArg ?? {};
|
|
2799
|
+
return {
|
|
2800
|
+
cmd: isObj ? cmdOrOpts.cmd : cmdOrOpts,
|
|
2801
|
+
opts
|
|
2802
|
+
};
|
|
2803
|
+
}
|
|
2804
|
+
function resolveStdio(options) {
|
|
2805
|
+
if (options.stdio)
|
|
2806
|
+
return options.stdio;
|
|
2807
|
+
return [options.stdin ?? "ignore", options.stdout ?? "pipe", options.stderr ?? "inherit"];
|
|
2808
|
+
}
|
|
2809
|
+
function wrapNodeProcess(proc) {
|
|
2810
|
+
let exitCode = null;
|
|
2811
|
+
const exited = new Promise((resolve5, reject) => {
|
|
2812
|
+
proc.on("exit", (code) => {
|
|
2813
|
+
exitCode = code ?? 1;
|
|
2814
|
+
resolve5(exitCode);
|
|
2815
|
+
});
|
|
2816
|
+
proc.on("error", (error) => {
|
|
2817
|
+
if (exitCode === null) {
|
|
2818
|
+
exitCode = 1;
|
|
2819
|
+
reject(error);
|
|
2820
|
+
}
|
|
2821
|
+
});
|
|
2822
|
+
});
|
|
2823
|
+
return {
|
|
2824
|
+
get exitCode() {
|
|
2825
|
+
return exitCode;
|
|
2826
|
+
},
|
|
2827
|
+
exited,
|
|
2828
|
+
stdout: toReadableStream(proc.stdout),
|
|
2829
|
+
stderr: toReadableStream(proc.stderr),
|
|
2830
|
+
stdin: proc.stdin ?? emptyWritableStream(),
|
|
2831
|
+
kill(signal) {
|
|
2832
|
+
if (proc.killed || exitCode !== null)
|
|
2833
|
+
return;
|
|
2834
|
+
try {
|
|
2835
|
+
proc.kill(signal);
|
|
2836
|
+
} catch (error) {
|
|
2837
|
+
if (!String(error).includes("kill"))
|
|
2838
|
+
throw error;
|
|
2839
|
+
}
|
|
2840
|
+
},
|
|
2841
|
+
pid: proc.pid,
|
|
2842
|
+
ref() {
|
|
2843
|
+
proc.ref();
|
|
2844
|
+
},
|
|
2845
|
+
unref() {
|
|
2846
|
+
proc.unref();
|
|
2847
|
+
}
|
|
2848
|
+
};
|
|
2849
|
+
}
|
|
2850
|
+
function spawn2(cmdOrOpts, opts) {
|
|
2851
|
+
if (IS_BUN)
|
|
2852
|
+
return runtime.Bun.spawn(cmdOrOpts, opts);
|
|
2853
|
+
const { cmd, opts: options } = resolveCommand(cmdOrOpts, opts);
|
|
2854
|
+
const [bin, ...args] = cmd;
|
|
2855
|
+
const proc = nodeSpawn(bin, args, {
|
|
2856
|
+
cwd: options.cwd,
|
|
2857
|
+
env: options.env,
|
|
2858
|
+
stdio: resolveStdio(options),
|
|
2859
|
+
detached: options.detached
|
|
2860
|
+
});
|
|
2861
|
+
return wrapNodeProcess(proc);
|
|
2862
|
+
}
|
|
2863
|
+
function spawnSync(cmdOrOpts, opts) {
|
|
2864
|
+
if (IS_BUN)
|
|
2865
|
+
return runtime.Bun.spawnSync(cmdOrOpts, opts);
|
|
2866
|
+
const { cmd, opts: options } = resolveCommand(cmdOrOpts, opts);
|
|
2867
|
+
const [bin, ...args] = cmd;
|
|
2868
|
+
const result = nodeSpawnSync(bin, args, {
|
|
2869
|
+
cwd: options.cwd,
|
|
2870
|
+
env: options.env,
|
|
2871
|
+
stdio: resolveStdio(options)
|
|
2872
|
+
});
|
|
2873
|
+
return {
|
|
2874
|
+
exitCode: result.status ?? 1,
|
|
2875
|
+
stdout: result.stdout ?? undefined,
|
|
2876
|
+
stderr: result.stderr ?? undefined,
|
|
2877
|
+
success: (result.status ?? 1) === 0,
|
|
2878
|
+
pid: result.pid ?? -1
|
|
2879
|
+
};
|
|
2880
|
+
}
|
|
2881
|
+
var runtime, IS_BUN;
|
|
2882
|
+
var init_bun_spawn_shim = __esm(() => {
|
|
2883
|
+
runtime = globalThis;
|
|
2884
|
+
IS_BUN = typeof runtime.Bun !== "undefined";
|
|
2885
|
+
});
|
|
2886
|
+
|
|
2773
2887
|
// src/shared/agent-display-names.ts
|
|
2774
2888
|
function stripInvisibleAgentCharacters(agentName) {
|
|
2775
2889
|
return agentName.replace(INVISIBLE_AGENT_CHARACTERS_REGEX, "");
|
|
@@ -2873,12 +2987,11 @@ __export(exports_tmux_path_resolver, {
|
|
|
2873
2987
|
getTmuxPath: () => getTmuxPath,
|
|
2874
2988
|
getCachedTmuxPath: () => getCachedTmuxPath
|
|
2875
2989
|
});
|
|
2876
|
-
var {spawn: spawn9 } = globalThis.Bun;
|
|
2877
2990
|
async function findTmuxPath() {
|
|
2878
2991
|
const isWindows = process.platform === "win32";
|
|
2879
2992
|
const cmd = isWindows ? "where" : "which";
|
|
2880
2993
|
try {
|
|
2881
|
-
const proc =
|
|
2994
|
+
const proc = spawn2([cmd, "tmux"], {
|
|
2882
2995
|
stdout: "pipe",
|
|
2883
2996
|
stderr: "pipe"
|
|
2884
2997
|
});
|
|
@@ -2892,7 +3005,7 @@ async function findTmuxPath() {
|
|
|
2892
3005
|
if (!path6) {
|
|
2893
3006
|
return null;
|
|
2894
3007
|
}
|
|
2895
|
-
const verifyProc =
|
|
3008
|
+
const verifyProc = spawn2([path6, "-V"], {
|
|
2896
3009
|
stdout: "pipe",
|
|
2897
3010
|
stderr: "pipe"
|
|
2898
3011
|
});
|
|
@@ -2929,15 +3042,18 @@ function startBackgroundCheck() {
|
|
|
2929
3042
|
}
|
|
2930
3043
|
}
|
|
2931
3044
|
var tmuxPath = null, initPromise = null;
|
|
2932
|
-
var init_tmux_path_resolver = () => {
|
|
3045
|
+
var init_tmux_path_resolver = __esm(() => {
|
|
3046
|
+
init_bun_spawn_shim();
|
|
3047
|
+
});
|
|
2933
3048
|
|
|
2934
3049
|
// src/shared/tmux/tmux-utils/spawn-process.ts
|
|
2935
3050
|
var exports_spawn_process = {};
|
|
2936
3051
|
__export(exports_spawn_process, {
|
|
2937
|
-
spawn: () =>
|
|
3052
|
+
spawn: () => spawn2
|
|
3053
|
+
});
|
|
3054
|
+
var init_spawn_process = __esm(() => {
|
|
3055
|
+
init_bun_spawn_shim();
|
|
2938
3056
|
});
|
|
2939
|
-
var {spawn: spawn11 } = globalThis.Bun;
|
|
2940
|
-
var init_spawn_process = () => {};
|
|
2941
3057
|
|
|
2942
3058
|
// src/shared/tmux/tmux-utils/session-kill.ts
|
|
2943
3059
|
var exports_session_kill = {};
|
|
@@ -2948,7 +3064,7 @@ async function readStream2(stream) {
|
|
|
2948
3064
|
return stream ? new Response(stream).text() : "";
|
|
2949
3065
|
}
|
|
2950
3066
|
async function killTmuxSessionIfExists(sessionName) {
|
|
2951
|
-
const [{ log: log2 }, { isInsideTmux: isInsideTmux2 }, { getTmuxPath: getTmuxPath2 }, { spawn:
|
|
3067
|
+
const [{ log: log2 }, { isInsideTmux: isInsideTmux2 }, { getTmuxPath: getTmuxPath2 }, { spawn: spawn3 }] = await Promise.all([
|
|
2952
3068
|
Promise.resolve().then(() => (init_logger(), exports_logger)),
|
|
2953
3069
|
Promise.resolve().then(() => exports_environment),
|
|
2954
3070
|
Promise.resolve().then(() => (init_tmux_path_resolver(), exports_tmux_path_resolver)),
|
|
@@ -2963,7 +3079,7 @@ async function killTmuxSessionIfExists(sessionName) {
|
|
|
2963
3079
|
log2("[killTmuxSessionIfExists] SKIP: tmux not found", { sessionName });
|
|
2964
3080
|
return false;
|
|
2965
3081
|
}
|
|
2966
|
-
const hasSessionProcess =
|
|
3082
|
+
const hasSessionProcess = spawn3([tmux, "has-session", "-t", sessionName], {
|
|
2967
3083
|
stdout: "ignore",
|
|
2968
3084
|
stderr: "ignore"
|
|
2969
3085
|
});
|
|
@@ -2971,7 +3087,7 @@ async function killTmuxSessionIfExists(sessionName) {
|
|
|
2971
3087
|
log2("[killTmuxSessionIfExists] SKIP: session not found", { sessionName });
|
|
2972
3088
|
return false;
|
|
2973
3089
|
}
|
|
2974
|
-
const killSessionProcess =
|
|
3090
|
+
const killSessionProcess = spawn3([tmux, "kill-session", "-t", sessionName], {
|
|
2975
3091
|
stdout: "pipe",
|
|
2976
3092
|
stderr: "pipe"
|
|
2977
3093
|
});
|
|
@@ -15517,10 +15633,10 @@ var require_resolveCommand = __commonJS((exports, module) => {
|
|
|
15517
15633
|
}
|
|
15518
15634
|
return resolved;
|
|
15519
15635
|
}
|
|
15520
|
-
function
|
|
15636
|
+
function resolveCommand2(parsed) {
|
|
15521
15637
|
return resolveCommandAttempt(parsed) || resolveCommandAttempt(parsed, true);
|
|
15522
15638
|
}
|
|
15523
|
-
module.exports =
|
|
15639
|
+
module.exports = resolveCommand2;
|
|
15524
15640
|
});
|
|
15525
15641
|
|
|
15526
15642
|
// node_modules/cross-spawn/lib/util/escape.js
|
|
@@ -15588,19 +15704,19 @@ var require_readShebang = __commonJS((exports, module) => {
|
|
|
15588
15704
|
// node_modules/cross-spawn/lib/parse.js
|
|
15589
15705
|
var require_parse2 = __commonJS((exports, module) => {
|
|
15590
15706
|
var path15 = __require("path");
|
|
15591
|
-
var
|
|
15707
|
+
var resolveCommand2 = require_resolveCommand();
|
|
15592
15708
|
var escape2 = require_escape();
|
|
15593
15709
|
var readShebang = require_readShebang();
|
|
15594
15710
|
var isWin = process.platform === "win32";
|
|
15595
15711
|
var isExecutableRegExp = /\.(?:com|exe)$/i;
|
|
15596
15712
|
var isCmdShimRegExp = /node_modules[\\/].bin[\\/][^\\/]+\.cmd$/i;
|
|
15597
15713
|
function detectShebang(parsed) {
|
|
15598
|
-
parsed.file =
|
|
15714
|
+
parsed.file = resolveCommand2(parsed);
|
|
15599
15715
|
const shebang = parsed.file && readShebang(parsed.file);
|
|
15600
15716
|
if (shebang) {
|
|
15601
15717
|
parsed.args.unshift(parsed.file);
|
|
15602
15718
|
parsed.command = shebang;
|
|
15603
|
-
return
|
|
15719
|
+
return resolveCommand2(parsed);
|
|
15604
15720
|
}
|
|
15605
15721
|
return parsed.file;
|
|
15606
15722
|
}
|
|
@@ -15696,21 +15812,21 @@ var require_cross_spawn = __commonJS((exports, module) => {
|
|
|
15696
15812
|
var cp = __require("child_process");
|
|
15697
15813
|
var parse3 = require_parse2();
|
|
15698
15814
|
var enoent = require_enoent();
|
|
15699
|
-
function
|
|
15815
|
+
function spawn4(command, args, options) {
|
|
15700
15816
|
const parsed = parse3(command, args, options);
|
|
15701
15817
|
const spawned = cp.spawn(parsed.command, parsed.args, parsed.options);
|
|
15702
15818
|
enoent.hookChildProcess(spawned, parsed);
|
|
15703
15819
|
return spawned;
|
|
15704
15820
|
}
|
|
15705
|
-
function
|
|
15821
|
+
function spawnSync3(command, args, options) {
|
|
15706
15822
|
const parsed = parse3(command, args, options);
|
|
15707
15823
|
const result = cp.spawnSync(parsed.command, parsed.args, parsed.options);
|
|
15708
15824
|
result.error = result.error || enoent.verifyENOENTSync(result.status, parsed);
|
|
15709
15825
|
return result;
|
|
15710
15826
|
}
|
|
15711
|
-
module.exports =
|
|
15712
|
-
module.exports.spawn =
|
|
15713
|
-
module.exports.sync =
|
|
15827
|
+
module.exports = spawn4;
|
|
15828
|
+
module.exports.spawn = spawn4;
|
|
15829
|
+
module.exports.sync = spawnSync3;
|
|
15714
15830
|
module.exports._parse = parse3;
|
|
15715
15831
|
module.exports._enoent = enoent;
|
|
15716
15832
|
});
|
|
@@ -18576,7 +18692,7 @@ Both ${PLUGIN_NAME} and ${pluginName} scan ~/.config/opencode/skills/ and regist
|
|
|
18576
18692
|
3. Or uninstall ${PLUGIN_NAME} if you prefer ${pluginName}'s skill management`;
|
|
18577
18693
|
}
|
|
18578
18694
|
// src/shared/zip-extractor.ts
|
|
18579
|
-
|
|
18695
|
+
init_bun_spawn_shim();
|
|
18580
18696
|
import { release } from "os";
|
|
18581
18697
|
|
|
18582
18698
|
// src/shared/archive-entry-validator.ts
|
|
@@ -18635,7 +18751,7 @@ function validateArchiveEntries(entries, destDir) {
|
|
|
18635
18751
|
}
|
|
18636
18752
|
|
|
18637
18753
|
// src/shared/zip-entry-listing/python-zip-entry-listing.ts
|
|
18638
|
-
|
|
18754
|
+
init_bun_spawn_shim();
|
|
18639
18755
|
function isPythonZipListingAvailable() {
|
|
18640
18756
|
const proc = spawnSync(["python3", "--version"], {
|
|
18641
18757
|
stdout: "ignore",
|
|
@@ -18681,7 +18797,7 @@ async function listZipEntriesWithPython(archivePath) {
|
|
|
18681
18797
|
return JSON.parse(stdout);
|
|
18682
18798
|
}
|
|
18683
18799
|
// src/shared/zip-entry-listing/powershell-zip-entry-listing.ts
|
|
18684
|
-
|
|
18800
|
+
init_bun_spawn_shim();
|
|
18685
18801
|
function isPowerShellZipEntryRecord(value) {
|
|
18686
18802
|
if (!value || typeof value !== "object") {
|
|
18687
18803
|
return false;
|
|
@@ -18707,7 +18823,7 @@ function parsePowerShellZipEntryLine(line) {
|
|
|
18707
18823
|
};
|
|
18708
18824
|
}
|
|
18709
18825
|
async function listZipEntriesWithPowerShell(archivePath, escapePowerShellPath, extractor) {
|
|
18710
|
-
const proc =
|
|
18826
|
+
const proc = spawn2([
|
|
18711
18827
|
extractor,
|
|
18712
18828
|
"-Command",
|
|
18713
18829
|
[
|
|
@@ -18746,8 +18862,8 @@ async function listZipEntriesWithPowerShell(archivePath, escapePowerShellPath, e
|
|
|
18746
18862
|
return stdout.split(/\r?\n/).map((line) => line.trim()).filter(Boolean).map((line) => parsePowerShellZipEntryLine(line)).filter((entry) => entry !== null);
|
|
18747
18863
|
}
|
|
18748
18864
|
// src/shared/zip-entry-listing/tar-zip-entry-listing.ts
|
|
18865
|
+
init_bun_spawn_shim();
|
|
18749
18866
|
init_logger();
|
|
18750
|
-
var {spawn: spawn4 } = globalThis.Bun;
|
|
18751
18867
|
function parseTarListedZipEntry(line) {
|
|
18752
18868
|
const match = line.match(/^([^\s])\S*\s+\d+\s+\S+\s+\S+\s+\d+\s+\w+\s+\d+\s+(?:\d{2}:\d{2}|\d{4})\s+(.*)$/);
|
|
18753
18869
|
if (!match) {
|
|
@@ -18793,7 +18909,7 @@ function parseTarListingOutput(stdout) {
|
|
|
18793
18909
|
return parsedEntries;
|
|
18794
18910
|
}
|
|
18795
18911
|
async function listZipEntriesWithTar(archivePath) {
|
|
18796
|
-
const proc =
|
|
18912
|
+
const proc = spawn2(["tar", "-tvf", archivePath], {
|
|
18797
18913
|
stdout: "pipe",
|
|
18798
18914
|
stderr: "pipe"
|
|
18799
18915
|
});
|
|
@@ -18808,12 +18924,12 @@ async function listZipEntriesWithTar(archivePath) {
|
|
|
18808
18924
|
return parseTarListingOutput(stdout);
|
|
18809
18925
|
}
|
|
18810
18926
|
// src/shared/zip-entry-listing/zipinfo-zip-entry-listing.ts
|
|
18811
|
-
|
|
18927
|
+
init_bun_spawn_shim();
|
|
18812
18928
|
|
|
18813
18929
|
// src/shared/zip-entry-listing/read-zip-symlink-target.ts
|
|
18814
|
-
|
|
18930
|
+
init_bun_spawn_shim();
|
|
18815
18931
|
async function readZipSymlinkTarget(archivePath, entryPath) {
|
|
18816
|
-
const proc =
|
|
18932
|
+
const proc = spawn2(["unzip", "-p", archivePath, "--", entryPath], {
|
|
18817
18933
|
stdout: "pipe",
|
|
18818
18934
|
stderr: "pipe"
|
|
18819
18935
|
});
|
|
@@ -18841,7 +18957,7 @@ function parseZipInfoListedEntry(line) {
|
|
|
18841
18957
|
};
|
|
18842
18958
|
}
|
|
18843
18959
|
function isZipInfoZipListingAvailable() {
|
|
18844
|
-
const proc =
|
|
18960
|
+
const proc = spawnSync(["which", "zipinfo"], {
|
|
18845
18961
|
stdout: "ignore",
|
|
18846
18962
|
stderr: "ignore"
|
|
18847
18963
|
});
|
|
@@ -18854,7 +18970,7 @@ async function listZipEntriesWithZipInfo(archivePath) {
|
|
|
18854
18970
|
if (!isZipInfoZipListingAvailable()) {
|
|
18855
18971
|
throw new Error("zip entry listing requires zipinfo, but zipinfo is not installed");
|
|
18856
18972
|
}
|
|
18857
|
-
const proc =
|
|
18973
|
+
const proc = spawn2(["zipinfo", "-l", archivePath], {
|
|
18858
18974
|
stdout: "pipe",
|
|
18859
18975
|
stderr: "pipe"
|
|
18860
18976
|
});
|
|
@@ -18893,7 +19009,7 @@ function getWindowsBuildNumber() {
|
|
|
18893
19009
|
function isPwshAvailable() {
|
|
18894
19010
|
if (process.platform !== "win32")
|
|
18895
19011
|
return false;
|
|
18896
|
-
const result =
|
|
19012
|
+
const result = spawnSync(["where", "pwsh"], { stdout: "pipe", stderr: "pipe" });
|
|
18897
19013
|
return result.exitCode === 0;
|
|
18898
19014
|
}
|
|
18899
19015
|
function escapePowerShellPath(path5) {
|
|
@@ -18917,27 +19033,27 @@ async function extractZip(archivePath, destDir) {
|
|
|
18917
19033
|
const extractor = getWindowsZipExtractor();
|
|
18918
19034
|
switch (extractor) {
|
|
18919
19035
|
case "tar":
|
|
18920
|
-
proc =
|
|
19036
|
+
proc = spawn2(["tar", "-xf", archivePath, "-C", destDir], {
|
|
18921
19037
|
stdout: "ignore",
|
|
18922
19038
|
stderr: "pipe"
|
|
18923
19039
|
});
|
|
18924
19040
|
break;
|
|
18925
19041
|
case "pwsh":
|
|
18926
|
-
proc =
|
|
19042
|
+
proc = spawn2(["pwsh", "-Command", `Expand-Archive -Path '${escapePowerShellPath(archivePath)}' -DestinationPath '${escapePowerShellPath(destDir)}' -Force`], {
|
|
18927
19043
|
stdout: "ignore",
|
|
18928
19044
|
stderr: "pipe"
|
|
18929
19045
|
});
|
|
18930
19046
|
break;
|
|
18931
19047
|
case "powershell":
|
|
18932
19048
|
default:
|
|
18933
|
-
proc =
|
|
19049
|
+
proc = spawn2(["powershell", "-Command", `Expand-Archive -Path '${escapePowerShellPath(archivePath)}' -DestinationPath '${escapePowerShellPath(destDir)}' -Force`], {
|
|
18934
19050
|
stdout: "ignore",
|
|
18935
19051
|
stderr: "pipe"
|
|
18936
19052
|
});
|
|
18937
19053
|
break;
|
|
18938
19054
|
}
|
|
18939
19055
|
} else {
|
|
18940
|
-
proc =
|
|
19056
|
+
proc = spawn2(["unzip", "-o", archivePath, "-d", destDir], {
|
|
18941
19057
|
stdout: "ignore",
|
|
18942
19058
|
stderr: "pipe"
|
|
18943
19059
|
});
|
|
@@ -18965,9 +19081,9 @@ async function listZipEntries(archivePath) {
|
|
|
18965
19081
|
throw new Error("zip entry listing requires either python3 or zipinfo to inspect the archive safely");
|
|
18966
19082
|
}
|
|
18967
19083
|
// src/shared/binary-downloader.ts
|
|
19084
|
+
init_bun_spawn_shim();
|
|
18968
19085
|
import { chmodSync, existsSync as existsSync9, mkdirSync as mkdirSync3, unlinkSync as unlinkSync2 } from "fs";
|
|
18969
19086
|
import * as path5 from "path";
|
|
18970
|
-
var {spawn: spawn8 } = globalThis.Bun;
|
|
18971
19087
|
function isTarTraversalErrorOutput(output) {
|
|
18972
19088
|
return /path contains '\.\.'|member name contains '\.\.'|removing leading [`'\"]?\.\.\//i.test(output);
|
|
18973
19089
|
}
|
|
@@ -18992,7 +19108,7 @@ async function extractTarGz(archivePath, destDir, options) {
|
|
|
18992
19108
|
const entries = await listTarEntries(archivePath, options?.cwd);
|
|
18993
19109
|
validateArchiveEntries(entries, destDir);
|
|
18994
19110
|
const args = options?.args ?? ["tar", "-xzf", archivePath, "-C", destDir];
|
|
18995
|
-
const proc =
|
|
19111
|
+
const proc = spawn2(args, {
|
|
18996
19112
|
cwd: options?.cwd,
|
|
18997
19113
|
stdout: "pipe",
|
|
18998
19114
|
stderr: "pipe"
|
|
@@ -19042,7 +19158,7 @@ function parseTarEntry(line) {
|
|
|
19042
19158
|
};
|
|
19043
19159
|
}
|
|
19044
19160
|
async function listTarEntries(archivePath, cwd) {
|
|
19045
|
-
const proc =
|
|
19161
|
+
const proc = spawn2(["tar", "-tvzf", archivePath], {
|
|
19046
19162
|
cwd,
|
|
19047
19163
|
stdout: "pipe",
|
|
19048
19164
|
stderr: "pipe"
|
|
@@ -19612,6 +19728,7 @@ function toLogLabel(cacheLabel) {
|
|
|
19612
19728
|
}
|
|
19613
19729
|
function createJsonFileCacheStore(options) {
|
|
19614
19730
|
let memoryValue;
|
|
19731
|
+
let writtenInCurrentProcess = false;
|
|
19615
19732
|
function getCacheFilePath() {
|
|
19616
19733
|
return join10(options.getCacheDir(), options.filename);
|
|
19617
19734
|
}
|
|
@@ -19646,6 +19763,12 @@ function createJsonFileCacheStore(options) {
|
|
|
19646
19763
|
}
|
|
19647
19764
|
}
|
|
19648
19765
|
function has() {
|
|
19766
|
+
if (memoryValue !== undefined && memoryValue !== null) {
|
|
19767
|
+
return true;
|
|
19768
|
+
}
|
|
19769
|
+
if (writtenInCurrentProcess) {
|
|
19770
|
+
return true;
|
|
19771
|
+
}
|
|
19649
19772
|
return existsSync10(getCacheFilePath());
|
|
19650
19773
|
}
|
|
19651
19774
|
function write(value) {
|
|
@@ -19654,6 +19777,7 @@ function createJsonFileCacheStore(options) {
|
|
|
19654
19777
|
try {
|
|
19655
19778
|
writeFileSync2(cacheFile, options.serialize?.(value) ?? JSON.stringify(value, null, 2));
|
|
19656
19779
|
memoryValue = value;
|
|
19780
|
+
writtenInCurrentProcess = true;
|
|
19657
19781
|
log(`[${options.logPrefix}] ${options.cacheLabel} written`, options.describe(value));
|
|
19658
19782
|
} catch (error) {
|
|
19659
19783
|
log(`[${options.logPrefix}] Error writing ${toLogLabel(options.cacheLabel)}`, {
|
|
@@ -19663,6 +19787,7 @@ function createJsonFileCacheStore(options) {
|
|
|
19663
19787
|
}
|
|
19664
19788
|
function resetMemory() {
|
|
19665
19789
|
memoryValue = undefined;
|
|
19790
|
+
writtenInCurrentProcess = false;
|
|
19666
19791
|
}
|
|
19667
19792
|
return {
|
|
19668
19793
|
read,
|
|
@@ -19673,6 +19798,7 @@ function createJsonFileCacheStore(options) {
|
|
|
19673
19798
|
}
|
|
19674
19799
|
|
|
19675
19800
|
// src/shared/connected-providers-cache.ts
|
|
19801
|
+
var providerModelsCacheWrittenInCurrentProcess = false;
|
|
19676
19802
|
var CONNECTED_PROVIDERS_CACHE_FILE = "connected-providers.json";
|
|
19677
19803
|
var PROVIDER_MODELS_CACHE_FILE = "provider-models.json";
|
|
19678
19804
|
function isRecord(value) {
|
|
@@ -19712,6 +19838,9 @@ function createConnectedProvidersCacheStore(getCacheDir2 = getOmoOpenCodeCacheDi
|
|
|
19712
19838
|
return providerModelsCacheStore.read();
|
|
19713
19839
|
}
|
|
19714
19840
|
function hasProviderModelsCache() {
|
|
19841
|
+
if (providerModelsCacheWrittenInCurrentProcess) {
|
|
19842
|
+
return true;
|
|
19843
|
+
}
|
|
19715
19844
|
return providerModelsCacheStore.has();
|
|
19716
19845
|
}
|
|
19717
19846
|
function writeProviderModelsCache(data) {
|
|
@@ -19719,6 +19848,7 @@ function createConnectedProvidersCacheStore(getCacheDir2 = getOmoOpenCodeCacheDi
|
|
|
19719
19848
|
...data,
|
|
19720
19849
|
updatedAt: new Date().toISOString()
|
|
19721
19850
|
});
|
|
19851
|
+
providerModelsCacheWrittenInCurrentProcess = true;
|
|
19722
19852
|
}
|
|
19723
19853
|
async function updateConnectedProvidersCache(client) {
|
|
19724
19854
|
if (!client?.provider?.list) {
|
|
@@ -19767,6 +19897,7 @@ function createConnectedProvidersCacheStore(getCacheDir2 = getOmoOpenCodeCacheDi
|
|
|
19767
19897
|
function _resetMemCacheForTesting() {
|
|
19768
19898
|
connectedProvidersCacheStore.resetMemory();
|
|
19769
19899
|
providerModelsCacheStore.resetMemory();
|
|
19900
|
+
providerModelsCacheWrittenInCurrentProcess = false;
|
|
19770
19901
|
}
|
|
19771
19902
|
return {
|
|
19772
19903
|
readConnectedProvidersCache,
|
|
@@ -63825,10 +63956,11 @@ async function isServerRunning(serverUrl) {
|
|
|
63825
63956
|
return false;
|
|
63826
63957
|
}
|
|
63827
63958
|
// src/shared/tmux/tmux-utils/pane-dimensions.ts
|
|
63959
|
+
init_bun_spawn_shim();
|
|
63828
63960
|
init_tmux_path_resolver();
|
|
63829
63961
|
// src/shared/tmux/tmux-utils/pane-spawn.ts
|
|
63962
|
+
init_bun_spawn_shim();
|
|
63830
63963
|
init_tmux_path_resolver();
|
|
63831
|
-
var {spawn: spawn10 } = globalThis.Bun;
|
|
63832
63964
|
async function spawnTmuxPane(sessionId, description, config, serverUrl, targetPaneId, splitDirection = "-h") {
|
|
63833
63965
|
const { log: log2 } = await Promise.resolve().then(() => (init_logger(), exports_logger));
|
|
63834
63966
|
log2("[spawnTmuxPane] called", {
|
|
@@ -63871,7 +64003,7 @@ async function spawnTmuxPane(sessionId, description, config, serverUrl, targetPa
|
|
|
63871
64003
|
...targetPaneId ? ["-t", targetPaneId] : [],
|
|
63872
64004
|
opencodeCmd
|
|
63873
64005
|
];
|
|
63874
|
-
const proc =
|
|
64006
|
+
const proc = spawn2([tmux, ...args], { stdout: "pipe", stderr: "pipe" });
|
|
63875
64007
|
const exitCode = await proc.exited;
|
|
63876
64008
|
const stdout = await new Response(proc.stdout).text();
|
|
63877
64009
|
const paneId = stdout.trim();
|
|
@@ -63879,7 +64011,7 @@ async function spawnTmuxPane(sessionId, description, config, serverUrl, targetPa
|
|
|
63879
64011
|
return { success: false };
|
|
63880
64012
|
}
|
|
63881
64013
|
const title = `omo-subagent-${description.slice(0, 20)}`;
|
|
63882
|
-
const titleProc =
|
|
64014
|
+
const titleProc = spawn2([tmux, "select-pane", "-t", paneId, "-T", title], {
|
|
63883
64015
|
stdout: "ignore",
|
|
63884
64016
|
stderr: "pipe"
|
|
63885
64017
|
});
|
|
@@ -63904,7 +64036,7 @@ async function readStream(stream) {
|
|
|
63904
64036
|
return stream ? new Response(stream).text() : "";
|
|
63905
64037
|
}
|
|
63906
64038
|
async function closeTmuxPane(paneId) {
|
|
63907
|
-
const [{ log: log2 }, { isInsideTmux: isInsideTmux2 }, { getTmuxPath: getTmuxPath2 }, { spawn:
|
|
64039
|
+
const [{ log: log2 }, { isInsideTmux: isInsideTmux2 }, { getTmuxPath: getTmuxPath2 }, { spawn: spawn3 }] = await Promise.all([
|
|
63908
64040
|
Promise.resolve().then(() => (init_logger(), exports_logger)),
|
|
63909
64041
|
Promise.resolve().then(() => exports_environment),
|
|
63910
64042
|
Promise.resolve().then(() => (init_tmux_path_resolver(), exports_tmux_path_resolver)),
|
|
@@ -63920,14 +64052,14 @@ async function closeTmuxPane(paneId) {
|
|
|
63920
64052
|
return false;
|
|
63921
64053
|
}
|
|
63922
64054
|
log2("[closeTmuxPane] sending Ctrl+C for graceful shutdown", { paneId });
|
|
63923
|
-
const ctrlCProc =
|
|
64055
|
+
const ctrlCProc = spawn3([tmux, "send-keys", "-t", paneId, "C-c"], {
|
|
63924
64056
|
stdout: "ignore",
|
|
63925
64057
|
stderr: "ignore"
|
|
63926
64058
|
});
|
|
63927
64059
|
await ctrlCProc.exited;
|
|
63928
64060
|
await delay2(250);
|
|
63929
64061
|
log2("[closeTmuxPane] killing pane", { paneId });
|
|
63930
|
-
const killPaneProc =
|
|
64062
|
+
const killPaneProc = spawn3([tmux, "kill-pane", "-t", paneId], {
|
|
63931
64063
|
stdout: "pipe",
|
|
63932
64064
|
stderr: "pipe"
|
|
63933
64065
|
});
|
|
@@ -63950,8 +64082,8 @@ async function closeTmuxPane(paneId) {
|
|
|
63950
64082
|
return true;
|
|
63951
64083
|
}
|
|
63952
64084
|
// src/shared/tmux/tmux-utils/pane-replace.ts
|
|
64085
|
+
init_bun_spawn_shim();
|
|
63953
64086
|
init_tmux_path_resolver();
|
|
63954
|
-
var {spawn: spawn12 } = globalThis.Bun;
|
|
63955
64087
|
async function replaceTmuxPane(paneId, sessionId, description, config, serverUrl) {
|
|
63956
64088
|
const { log: log2 } = await Promise.resolve().then(() => (init_logger(), exports_logger));
|
|
63957
64089
|
log2("[replaceTmuxPane] called", { paneId, sessionId, description });
|
|
@@ -63966,7 +64098,7 @@ async function replaceTmuxPane(paneId, sessionId, description, config, serverUrl
|
|
|
63966
64098
|
return { success: false };
|
|
63967
64099
|
}
|
|
63968
64100
|
log2("[replaceTmuxPane] sending Ctrl+C for graceful shutdown", { paneId });
|
|
63969
|
-
const ctrlCProc =
|
|
64101
|
+
const ctrlCProc = spawn2([tmux, "send-keys", "-t", paneId, "C-c"], {
|
|
63970
64102
|
stdout: "pipe",
|
|
63971
64103
|
stderr: "pipe"
|
|
63972
64104
|
});
|
|
@@ -63974,7 +64106,7 @@ async function replaceTmuxPane(paneId, sessionId, description, config, serverUrl
|
|
|
63974
64106
|
const shell = process.env.SHELL || "/bin/sh";
|
|
63975
64107
|
const escapedUrl = shellEscapeForDoubleQuotedCommand(serverUrl);
|
|
63976
64108
|
const opencodeCmd = `${shell} -c "opencode attach ${escapedUrl} --session ${sessionId}"`;
|
|
63977
|
-
const proc =
|
|
64109
|
+
const proc = spawn2([tmux, "respawn-pane", "-k", "-t", paneId, opencodeCmd], {
|
|
63978
64110
|
stdout: "pipe",
|
|
63979
64111
|
stderr: "pipe"
|
|
63980
64112
|
});
|
|
@@ -63985,7 +64117,7 @@ async function replaceTmuxPane(paneId, sessionId, description, config, serverUrl
|
|
|
63985
64117
|
return { success: false };
|
|
63986
64118
|
}
|
|
63987
64119
|
const title = `omo-subagent-${description.slice(0, 20)}`;
|
|
63988
|
-
const titleProc =
|
|
64120
|
+
const titleProc = spawn2([tmux, "select-pane", "-t", paneId, "-T", title], {
|
|
63989
64121
|
stdout: "ignore",
|
|
63990
64122
|
stderr: "pipe"
|
|
63991
64123
|
});
|
|
@@ -64004,8 +64136,8 @@ async function replaceTmuxPane(paneId, sessionId, description, config, serverUrl
|
|
|
64004
64136
|
return { success: true, paneId };
|
|
64005
64137
|
}
|
|
64006
64138
|
// src/shared/tmux/tmux-utils/window-spawn.ts
|
|
64139
|
+
init_bun_spawn_shim();
|
|
64007
64140
|
init_tmux_path_resolver();
|
|
64008
|
-
var {spawn: spawn13 } = globalThis.Bun;
|
|
64009
64141
|
var ISOLATED_WINDOW_NAME = "omo-agents";
|
|
64010
64142
|
async function spawnTmuxWindow(sessionId, description, config, serverUrl) {
|
|
64011
64143
|
const { log: log2 } = await Promise.resolve().then(() => (init_logger(), exports_logger));
|
|
@@ -64048,7 +64180,7 @@ async function spawnTmuxWindow(sessionId, description, config, serverUrl) {
|
|
|
64048
64180
|
"#{pane_id}",
|
|
64049
64181
|
opencodeCmd
|
|
64050
64182
|
];
|
|
64051
|
-
const proc =
|
|
64183
|
+
const proc = spawn2([tmux, ...args], { stdout: "pipe", stderr: "pipe" });
|
|
64052
64184
|
const exitCode = await proc.exited;
|
|
64053
64185
|
const stdout = await new Response(proc.stdout).text();
|
|
64054
64186
|
const paneId = stdout.trim();
|
|
@@ -64058,7 +64190,7 @@ async function spawnTmuxWindow(sessionId, description, config, serverUrl) {
|
|
|
64058
64190
|
return { success: false };
|
|
64059
64191
|
}
|
|
64060
64192
|
const title = `omo-subagent-${description.slice(0, 20)}`;
|
|
64061
|
-
const titleProc =
|
|
64193
|
+
const titleProc = spawn2([tmux, "select-pane", "-t", paneId, "-T", title], {
|
|
64062
64194
|
stdout: "ignore",
|
|
64063
64195
|
stderr: "pipe"
|
|
64064
64196
|
});
|
|
@@ -64077,14 +64209,14 @@ async function spawnTmuxWindow(sessionId, description, config, serverUrl) {
|
|
|
64077
64209
|
return { success: true, paneId };
|
|
64078
64210
|
}
|
|
64079
64211
|
// src/shared/tmux/tmux-utils/session-spawn.ts
|
|
64212
|
+
init_bun_spawn_shim();
|
|
64080
64213
|
init_tmux_path_resolver();
|
|
64081
|
-
var {spawn: spawn14 } = globalThis.Bun;
|
|
64082
64214
|
var ISOLATED_SESSION_NAME_PREFIX = "omo-agents";
|
|
64083
64215
|
function getIsolatedSessionName(pid = process.pid) {
|
|
64084
64216
|
return `${ISOLATED_SESSION_NAME_PREFIX}-${pid}`;
|
|
64085
64217
|
}
|
|
64086
64218
|
async function getWindowDimensions(tmux, sourcePaneId) {
|
|
64087
|
-
const proc =
|
|
64219
|
+
const proc = spawn2([tmux, "display", "-p", "-t", sourcePaneId, "#{window_width},#{window_height}"], { stdout: "pipe", stderr: "pipe" });
|
|
64088
64220
|
const exitCode = await proc.exited;
|
|
64089
64221
|
const stdout = await new Response(proc.stdout).text();
|
|
64090
64222
|
if (exitCode !== 0)
|
|
@@ -64095,7 +64227,7 @@ async function getWindowDimensions(tmux, sourcePaneId) {
|
|
|
64095
64227
|
return { width, height };
|
|
64096
64228
|
}
|
|
64097
64229
|
async function sessionExists(tmux, sessionName) {
|
|
64098
|
-
const proc =
|
|
64230
|
+
const proc = spawn2([tmux, "has-session", "-t", sessionName], {
|
|
64099
64231
|
stdout: "ignore",
|
|
64100
64232
|
stderr: "ignore"
|
|
64101
64233
|
});
|
|
@@ -64164,7 +64296,7 @@ async function spawnTmuxSession(sessionId, description, config, serverUrl, sourc
|
|
|
64164
64296
|
mode: sessionAlreadyExists ? "new-window" : "new-session",
|
|
64165
64297
|
sessionName: isolatedSessionName
|
|
64166
64298
|
});
|
|
64167
|
-
const proc =
|
|
64299
|
+
const proc = spawn2([tmux, ...args], { stdout: "pipe", stderr: "pipe" });
|
|
64168
64300
|
const exitCode = await proc.exited;
|
|
64169
64301
|
const stdout = await new Response(proc.stdout).text();
|
|
64170
64302
|
const paneId = stdout.trim();
|
|
@@ -64174,7 +64306,7 @@ async function spawnTmuxSession(sessionId, description, config, serverUrl, sourc
|
|
|
64174
64306
|
return { success: false };
|
|
64175
64307
|
}
|
|
64176
64308
|
const title = `omo-subagent-${description.slice(0, 20)}`;
|
|
64177
|
-
const titleProc =
|
|
64309
|
+
const titleProc = spawn2([tmux, "select-pane", "-t", paneId, "-T", title], {
|
|
64178
64310
|
stdout: "ignore",
|
|
64179
64311
|
stderr: "pipe"
|
|
64180
64312
|
});
|
|
@@ -64204,8 +64336,8 @@ function isProcessAlive(pid) {
|
|
|
64204
64336
|
}
|
|
64205
64337
|
}
|
|
64206
64338
|
async function listOmoAgentSessionsViaTmux(tmux) {
|
|
64207
|
-
const { spawn:
|
|
64208
|
-
const proc =
|
|
64339
|
+
const { spawn: spawn3 } = await Promise.resolve().then(() => (init_spawn_process(), exports_spawn_process));
|
|
64340
|
+
const proc = spawn3([tmux, "list-sessions", "-F", "#{session_name}"], {
|
|
64209
64341
|
stdout: "pipe",
|
|
64210
64342
|
stderr: "pipe"
|
|
64211
64343
|
});
|
|
@@ -64271,8 +64403,8 @@ async function sweepStaleOmoAgentSessions() {
|
|
|
64271
64403
|
return sweepStaleOmoAgentSessionsWith(deps);
|
|
64272
64404
|
}
|
|
64273
64405
|
// src/shared/tmux/tmux-utils/layout.ts
|
|
64406
|
+
init_bun_spawn_shim();
|
|
64274
64407
|
init_tmux_path_resolver();
|
|
64275
|
-
var {spawn: spawn15 } = globalThis.Bun;
|
|
64276
64408
|
function clamp(value, min, max) {
|
|
64277
64409
|
return Math.max(min, Math.min(max, value));
|
|
64278
64410
|
}
|
|
@@ -64286,7 +64418,7 @@ function calculateMainPaneWidth(windowWidth, options) {
|
|
|
64286
64418
|
return clamp(Math.max(desiredMainPaneWidth, minMainPaneWidth), 0, maxMainPaneWidth);
|
|
64287
64419
|
}
|
|
64288
64420
|
async function applyLayout(tmux, layout, mainPaneSize, deps) {
|
|
64289
|
-
const spawnCommand = deps?.spawnCommand ??
|
|
64421
|
+
const spawnCommand = deps?.spawnCommand ?? spawn2;
|
|
64290
64422
|
const layoutProc = spawnCommand([tmux, "select-layout", layout], {
|
|
64291
64423
|
stdout: "ignore",
|
|
64292
64424
|
stderr: "ignore"
|
|
@@ -64305,7 +64437,7 @@ async function enforceMainPaneWidth(mainPaneId, windowWidth, mainPaneSizeOrOptio
|
|
|
64305
64437
|
return;
|
|
64306
64438
|
const options = typeof mainPaneSizeOrOptions === "number" ? { mainPaneSize: mainPaneSizeOrOptions } : mainPaneSizeOrOptions ?? {};
|
|
64307
64439
|
const mainWidth = calculateMainPaneWidth(windowWidth, options);
|
|
64308
|
-
const proc =
|
|
64440
|
+
const proc = spawn2([tmux, "resize-pane", "-t", mainPaneId, "-x", String(mainWidth)], {
|
|
64309
64441
|
stdout: "ignore",
|
|
64310
64442
|
stderr: "ignore"
|
|
64311
64443
|
});
|
|
@@ -66659,7 +66791,7 @@ async function injectContinuation(args) {
|
|
|
66659
66791
|
log(`[${HOOK_NAME}] Skipped injection: continuation stopped for session`, { sessionID });
|
|
66660
66792
|
return;
|
|
66661
66793
|
}
|
|
66662
|
-
const hasRunningBgTasks = backgroundManager ? backgroundManager.getTasksByParentSession(sessionID).some((task) => task.status === "running") : false;
|
|
66794
|
+
const hasRunningBgTasks = backgroundManager ? backgroundManager.getTasksByParentSession(sessionID).some((task) => task.status === "running" || task.status === "pending") : false;
|
|
66663
66795
|
if (hasRunningBgTasks) {
|
|
66664
66796
|
log(`[${HOOK_NAME}] Skipped injection: background tasks running`, { sessionID });
|
|
66665
66797
|
return;
|
|
@@ -66865,7 +66997,7 @@ async function handleSessionIdle(args) {
|
|
|
66865
66997
|
}
|
|
66866
66998
|
state2.abortDetectedAt = undefined;
|
|
66867
66999
|
}
|
|
66868
|
-
const hasRunningBgTasks = backgroundManager ? backgroundManager.getTasksByParentSession(sessionID).some((task) => task.status === "running") : false;
|
|
67000
|
+
const hasRunningBgTasks = backgroundManager ? backgroundManager.getTasksByParentSession(sessionID).some((task) => task.status === "running" || task.status === "pending") : false;
|
|
66869
67001
|
if (hasRunningBgTasks) {
|
|
66870
67002
|
log(`[${HOOK_NAME}] Skipped: background tasks running`, { sessionID });
|
|
66871
67003
|
return;
|
|
@@ -67655,6 +67787,14 @@ function getDefaultSoundPath(platform2) {
|
|
|
67655
67787
|
return "";
|
|
67656
67788
|
}
|
|
67657
67789
|
}
|
|
67790
|
+
async function runQuietNothrow(command) {
|
|
67791
|
+
const safeCommand = typeof command.nothrow === "function" ? command.nothrow() : command;
|
|
67792
|
+
if (typeof safeCommand.quiet === "function") {
|
|
67793
|
+
await safeCommand.quiet();
|
|
67794
|
+
return;
|
|
67795
|
+
}
|
|
67796
|
+
await safeCommand;
|
|
67797
|
+
}
|
|
67658
67798
|
async function sendSessionNotification(ctx, platform2, title, message) {
|
|
67659
67799
|
switch (platform2) {
|
|
67660
67800
|
case "darwin": {
|
|
@@ -67682,14 +67822,14 @@ async function sendSessionNotification(ctx, platform2, title, message) {
|
|
|
67682
67822
|
return;
|
|
67683
67823
|
const escapedTitle = escapeAppleScriptText(title);
|
|
67684
67824
|
const escapedMessage = escapeAppleScriptText(message);
|
|
67685
|
-
await ctx.$`${osascriptPath} -e ${'display notification "' + escapedMessage + '" with title "' + escapedTitle + '"'}
|
|
67825
|
+
await runQuietNothrow(ctx.$`${osascriptPath} -e ${'display notification "' + escapedMessage + '" with title "' + escapedTitle + '"'}`);
|
|
67686
67826
|
break;
|
|
67687
67827
|
}
|
|
67688
67828
|
case "linux": {
|
|
67689
67829
|
const notifySendPath = await getNotifySendPath();
|
|
67690
67830
|
if (!notifySendPath)
|
|
67691
67831
|
return;
|
|
67692
|
-
await ctx.$`${notifySendPath} ${title} ${message} 2>/dev/null
|
|
67832
|
+
await runQuietNothrow(ctx.$`${notifySendPath} ${title} ${message} 2>/dev/null`);
|
|
67693
67833
|
break;
|
|
67694
67834
|
}
|
|
67695
67835
|
case "win32": {
|
|
@@ -67697,7 +67837,7 @@ async function sendSessionNotification(ctx, platform2, title, message) {
|
|
|
67697
67837
|
if (!powershellPath)
|
|
67698
67838
|
return;
|
|
67699
67839
|
const toastScript = buildWindowsToastScript(title, message);
|
|
67700
|
-
await ctx.$`${powershellPath} -Command ${toastScript}
|
|
67840
|
+
await runQuietNothrow(ctx.$`${powershellPath} -Command ${toastScript}`);
|
|
67701
67841
|
break;
|
|
67702
67842
|
}
|
|
67703
67843
|
}
|
|
@@ -67708,17 +67848,17 @@ async function playSessionNotificationSound(ctx, platform2, soundPath) {
|
|
|
67708
67848
|
const afplayPath = await getAfplayPath();
|
|
67709
67849
|
if (!afplayPath)
|
|
67710
67850
|
return;
|
|
67711
|
-
ctx.$`${afplayPath} ${soundPath}
|
|
67851
|
+
await runQuietNothrow(ctx.$`${afplayPath} ${soundPath}`);
|
|
67712
67852
|
break;
|
|
67713
67853
|
}
|
|
67714
67854
|
case "linux": {
|
|
67715
67855
|
const paplayPath = await getPaplayPath();
|
|
67716
67856
|
if (paplayPath) {
|
|
67717
|
-
ctx.$`${paplayPath} ${soundPath} 2>/dev/null
|
|
67857
|
+
await runQuietNothrow(ctx.$`${paplayPath} ${soundPath} 2>/dev/null`);
|
|
67718
67858
|
} else {
|
|
67719
67859
|
const aplayPath = await getAplayPath();
|
|
67720
67860
|
if (aplayPath) {
|
|
67721
|
-
ctx.$`${aplayPath} ${soundPath} 2>/dev/null
|
|
67861
|
+
await runQuietNothrow(ctx.$`${aplayPath} ${soundPath} 2>/dev/null`);
|
|
67722
67862
|
}
|
|
67723
67863
|
}
|
|
67724
67864
|
break;
|
|
@@ -67728,7 +67868,7 @@ async function playSessionNotificationSound(ctx, platform2, soundPath) {
|
|
|
67728
67868
|
if (!powershellPath)
|
|
67729
67869
|
return;
|
|
67730
67870
|
const escaped = escapePowerShellSingleQuotedText(soundPath);
|
|
67731
|
-
ctx.$`${powershellPath} -Command ${"(New-Object Media.SoundPlayer '" + escaped + "').PlaySync()"}
|
|
67871
|
+
await runQuietNothrow(ctx.$`${powershellPath} -Command ${"(New-Object Media.SoundPlayer '" + escaped + "').PlaySync()"}`);
|
|
67732
67872
|
break;
|
|
67733
67873
|
}
|
|
67734
67874
|
}
|
|
@@ -69108,7 +69248,7 @@ import z from "zod";
|
|
|
69108
69248
|
import { existsSync as existsSync33 } from "fs";
|
|
69109
69249
|
|
|
69110
69250
|
// src/hooks/comment-checker/cli.ts
|
|
69111
|
-
|
|
69251
|
+
init_bun_spawn_shim();
|
|
69112
69252
|
import { createRequire as createRequire2 } from "module";
|
|
69113
69253
|
import { dirname as dirname6, join as join34 } from "path";
|
|
69114
69254
|
import { existsSync as existsSync32 } from "fs";
|
|
@@ -69314,7 +69454,7 @@ async function runCommentChecker(input, cliPath, customPrompt) {
|
|
|
69314
69454
|
if (customPrompt) {
|
|
69315
69455
|
args.push("--prompt", customPrompt);
|
|
69316
69456
|
}
|
|
69317
|
-
const proc =
|
|
69457
|
+
const proc = spawn2(args, {
|
|
69318
69458
|
stdin: "pipe",
|
|
69319
69459
|
stdout: "pipe",
|
|
69320
69460
|
stderr: "pipe"
|
|
@@ -74706,16 +74846,16 @@ function migrateLegacyConfigFile(legacyPath) {
|
|
|
74706
74846
|
// src/cli/config-manager/write-omo-config.ts
|
|
74707
74847
|
init_plugin_identity();
|
|
74708
74848
|
// src/shared/spawn-with-windows-hide.ts
|
|
74709
|
-
|
|
74710
|
-
import { spawn as
|
|
74711
|
-
import { Readable } from "stream";
|
|
74712
|
-
function
|
|
74849
|
+
init_bun_spawn_shim();
|
|
74850
|
+
import { spawn as nodeSpawn2 } from "child_process";
|
|
74851
|
+
import { Readable as Readable2 } from "stream";
|
|
74852
|
+
function toReadableStream2(stream) {
|
|
74713
74853
|
if (!stream) {
|
|
74714
74854
|
return;
|
|
74715
74855
|
}
|
|
74716
|
-
return
|
|
74856
|
+
return Readable2.toWeb(stream);
|
|
74717
74857
|
}
|
|
74718
|
-
function
|
|
74858
|
+
function wrapNodeProcess2(proc) {
|
|
74719
74859
|
let resolveExited;
|
|
74720
74860
|
let exitCode = null;
|
|
74721
74861
|
const exited = new Promise((resolve11) => {
|
|
@@ -74736,8 +74876,8 @@ function wrapNodeProcess(proc) {
|
|
|
74736
74876
|
return exitCode;
|
|
74737
74877
|
},
|
|
74738
74878
|
exited,
|
|
74739
|
-
stdout:
|
|
74740
|
-
stderr:
|
|
74879
|
+
stdout: toReadableStream2(proc.stdout),
|
|
74880
|
+
stderr: toReadableStream2(proc.stderr),
|
|
74741
74881
|
kill(signal) {
|
|
74742
74882
|
try {
|
|
74743
74883
|
if (!signal) {
|
|
@@ -74751,17 +74891,17 @@ function wrapNodeProcess(proc) {
|
|
|
74751
74891
|
}
|
|
74752
74892
|
function spawnWithWindowsHide(command, options) {
|
|
74753
74893
|
if (process.platform !== "win32") {
|
|
74754
|
-
return
|
|
74894
|
+
return spawn2(command, options);
|
|
74755
74895
|
}
|
|
74756
74896
|
const [cmd, ...args] = command;
|
|
74757
|
-
const proc =
|
|
74897
|
+
const proc = nodeSpawn2(cmd, args, {
|
|
74758
74898
|
cwd: options.cwd,
|
|
74759
74899
|
env: options.env,
|
|
74760
|
-
stdio: [options.stdin ?? "
|
|
74900
|
+
stdio: [options.stdin ?? "ignore", options.stdout ?? "pipe", options.stderr ?? "inherit"],
|
|
74761
74901
|
windowsHide: true,
|
|
74762
74902
|
shell: true
|
|
74763
74903
|
});
|
|
74764
|
-
return
|
|
74904
|
+
return wrapNodeProcess2(proc);
|
|
74765
74905
|
}
|
|
74766
74906
|
// src/cli/config-manager/bun-install.ts
|
|
74767
74907
|
import { existsSync as existsSync51 } from "fs";
|
|
@@ -86078,6 +86218,7 @@ async function resolveRecentPromptContextForSession(ctx, sessionID) {
|
|
|
86078
86218
|
}
|
|
86079
86219
|
|
|
86080
86220
|
// src/hooks/atlas/boulder-continuation-injector.ts
|
|
86221
|
+
var ACTIVE_BACKGROUND_TASK_STATUSES = new Set(["pending", "running"]);
|
|
86081
86222
|
async function injectBoulderContinuation(input) {
|
|
86082
86223
|
const {
|
|
86083
86224
|
ctx,
|
|
@@ -86092,7 +86233,7 @@ async function injectBoulderContinuation(input) {
|
|
|
86092
86233
|
backgroundManager,
|
|
86093
86234
|
sessionState
|
|
86094
86235
|
} = input;
|
|
86095
|
-
const hasRunningBgTasks = backgroundManager ? backgroundManager.getTasksByParentSession(sessionID).some((t) => t.status
|
|
86236
|
+
const hasRunningBgTasks = backgroundManager ? backgroundManager.getTasksByParentSession(sessionID).some((t) => ACTIVE_BACKGROUND_TASK_STATUSES.has(t.status)) : false;
|
|
86096
86237
|
if (hasRunningBgTasks) {
|
|
86097
86238
|
log(`[${HOOK_NAME7}] Skipped injection: background tasks running`, { sessionID });
|
|
86098
86239
|
return "skipped_background_tasks";
|
|
@@ -88743,6 +88884,10 @@ function isModelInCooldown(model, state3, cooldownSeconds) {
|
|
|
88743
88884
|
function findNextAvailableFallback(state3, fallbackModels, cooldownSeconds) {
|
|
88744
88885
|
for (let i2 = state3.fallbackIndex + 1;i2 < fallbackModels.length; i2++) {
|
|
88745
88886
|
const candidate = fallbackModels[i2];
|
|
88887
|
+
if (candidate === state3.currentModel) {
|
|
88888
|
+
log(`[${HOOK_NAME11}] Skipping fallback model (same as current)`, { model: candidate, index: i2 });
|
|
88889
|
+
continue;
|
|
88890
|
+
}
|
|
88746
88891
|
if (!isModelInCooldown(candidate, state3, cooldownSeconds)) {
|
|
88747
88892
|
return candidate;
|
|
88748
88893
|
}
|
|
@@ -91969,9 +92114,9 @@ function getLanguageId(ext) {
|
|
|
91969
92114
|
return EXT_TO_LANG[ext] || "plaintext";
|
|
91970
92115
|
}
|
|
91971
92116
|
// src/tools/lsp/lsp-process.ts
|
|
92117
|
+
init_bun_spawn_shim();
|
|
91972
92118
|
init_logger();
|
|
91973
|
-
|
|
91974
|
-
import { spawn as nodeSpawn2 } from "child_process";
|
|
92119
|
+
import { spawn as nodeSpawn3 } from "child_process";
|
|
91975
92120
|
import { existsSync as existsSync68, statSync as statSync9 } from "fs";
|
|
91976
92121
|
function shouldUseNodeSpawn() {
|
|
91977
92122
|
return process.platform === "win32";
|
|
@@ -91990,7 +92135,7 @@ function validateCwd(cwd) {
|
|
|
91990
92135
|
return { valid: false, error: `Cannot access working directory: ${cwd} (${err instanceof Error ? err.message : String(err)})` };
|
|
91991
92136
|
}
|
|
91992
92137
|
}
|
|
91993
|
-
function
|
|
92138
|
+
function wrapNodeProcess3(proc) {
|
|
91994
92139
|
let resolveExited;
|
|
91995
92140
|
let exitCode = null;
|
|
91996
92141
|
const exitedPromise = new Promise((resolve14) => {
|
|
@@ -92091,16 +92236,16 @@ function spawnProcess(command, options) {
|
|
|
92091
92236
|
if (shouldUseNodeSpawn()) {
|
|
92092
92237
|
const [cmd, ...args] = command;
|
|
92093
92238
|
log("[LSP] Using Node.js child_process on Windows to avoid Bun spawn segfault");
|
|
92094
|
-
const proc2 =
|
|
92239
|
+
const proc2 = nodeSpawn3(cmd, args, {
|
|
92095
92240
|
cwd: options.cwd,
|
|
92096
92241
|
env: options.env,
|
|
92097
92242
|
stdio: ["pipe", "pipe", "pipe"],
|
|
92098
92243
|
windowsHide: true,
|
|
92099
92244
|
shell: true
|
|
92100
92245
|
});
|
|
92101
|
-
return
|
|
92246
|
+
return wrapNodeProcess3(proc2);
|
|
92102
92247
|
}
|
|
92103
|
-
const proc =
|
|
92248
|
+
const proc = spawn2(command, {
|
|
92104
92249
|
stdin: "pipe",
|
|
92105
92250
|
stdout: "pipe",
|
|
92106
92251
|
stderr: "pipe",
|
|
@@ -92119,7 +92264,7 @@ import { pathToFileURL } from "url";
|
|
|
92119
92264
|
|
|
92120
92265
|
// src/tools/lsp/lsp-client-transport.ts
|
|
92121
92266
|
var import_node = __toESM(require_main(), 1);
|
|
92122
|
-
import { Readable as
|
|
92267
|
+
import { Readable as Readable3, Writable as Writable2 } from "stream";
|
|
92123
92268
|
import { delimiter as delimiter2 } from "path";
|
|
92124
92269
|
init_logger();
|
|
92125
92270
|
|
|
@@ -92163,7 +92308,7 @@ class LSPClientTransport {
|
|
|
92163
92308
|
stderr: ${stderr}` : ""));
|
|
92164
92309
|
}
|
|
92165
92310
|
const stdoutReader = this.proc.stdout.getReader();
|
|
92166
|
-
const nodeReadable = new
|
|
92311
|
+
const nodeReadable = new Readable3({
|
|
92167
92312
|
async read() {
|
|
92168
92313
|
try {
|
|
92169
92314
|
const { done, value } = await stdoutReader.read();
|
|
@@ -92178,7 +92323,7 @@ stderr: ${stderr}` : ""));
|
|
|
92178
92323
|
}
|
|
92179
92324
|
});
|
|
92180
92325
|
const stdin = this.proc.stdin;
|
|
92181
|
-
const nodeWritable = new
|
|
92326
|
+
const nodeWritable = new Writable2({
|
|
92182
92327
|
write(chunk, _encoding, callback) {
|
|
92183
92328
|
try {
|
|
92184
92329
|
stdin.write(chunk);
|
|
@@ -93638,7 +93783,7 @@ function setSgCliPath(path13) {
|
|
|
93638
93783
|
resolvedCliPath2 = path13;
|
|
93639
93784
|
}
|
|
93640
93785
|
// src/tools/ast-grep/cli.ts
|
|
93641
|
-
|
|
93786
|
+
init_bun_spawn_shim();
|
|
93642
93787
|
import { existsSync as existsSync74 } from "fs";
|
|
93643
93788
|
|
|
93644
93789
|
// src/tools/ast-grep/cli-binary-path-resolution.ts
|
|
@@ -93772,7 +93917,7 @@ async function runSg(options) {
|
|
|
93772
93917
|
}
|
|
93773
93918
|
}
|
|
93774
93919
|
const timeout = DEFAULT_TIMEOUT_MS2;
|
|
93775
|
-
const proc =
|
|
93920
|
+
const proc = spawn2([cliPath, ...args], {
|
|
93776
93921
|
stdout: "pipe",
|
|
93777
93922
|
stderr: "pipe"
|
|
93778
93923
|
});
|
|
@@ -93835,7 +93980,7 @@ async function runSg(options) {
|
|
|
93835
93980
|
if (shouldSeparateWritePass && jsonResult.matches.length > 0) {
|
|
93836
93981
|
const writeArgs = args.filter((a) => a !== "--json=compact");
|
|
93837
93982
|
writeArgs.push("--update-all");
|
|
93838
|
-
const writeProc =
|
|
93983
|
+
const writeProc = spawn2([cliPath, ...writeArgs], {
|
|
93839
93984
|
stdout: "pipe",
|
|
93840
93985
|
stderr: "pipe"
|
|
93841
93986
|
});
|
|
@@ -94004,7 +94149,7 @@ ${hint}`;
|
|
|
94004
94149
|
import { resolve as resolve18 } from "path";
|
|
94005
94150
|
|
|
94006
94151
|
// src/shared/ripgrep-cli.ts
|
|
94007
|
-
import { spawnSync as
|
|
94152
|
+
import { spawnSync as spawnSync2 } from "child_process";
|
|
94008
94153
|
import { existsSync as existsSync76 } from "fs";
|
|
94009
94154
|
import { dirname as dirname24, join as join83 } from "path";
|
|
94010
94155
|
|
|
@@ -94114,7 +94259,7 @@ function findExecutable(name) {
|
|
|
94114
94259
|
const isWindows2 = process.platform === "win32";
|
|
94115
94260
|
const cmd = isWindows2 ? "where" : "which";
|
|
94116
94261
|
try {
|
|
94117
|
-
const result =
|
|
94262
|
+
const result = spawnSync2(cmd, [name], { encoding: "utf-8", timeout: 5000 });
|
|
94118
94263
|
if (result.status === 0 && result.stdout.trim()) {
|
|
94119
94264
|
return result.stdout.trim().split(`
|
|
94120
94265
|
`)[0];
|
|
@@ -94190,7 +94335,7 @@ async function resolveGrepCliWithAutoInstall() {
|
|
|
94190
94335
|
}
|
|
94191
94336
|
|
|
94192
94337
|
// src/tools/grep/cli.ts
|
|
94193
|
-
|
|
94338
|
+
init_bun_spawn_shim();
|
|
94194
94339
|
|
|
94195
94340
|
// src/tools/grep/constants.ts
|
|
94196
94341
|
var DEFAULT_MAX_DEPTH = 20;
|
|
@@ -94379,7 +94524,7 @@ async function runRgInternal(options, resolvedCli) {
|
|
|
94379
94524
|
}
|
|
94380
94525
|
const paths = options.paths?.length ? options.paths : ["."];
|
|
94381
94526
|
args.push(...paths);
|
|
94382
|
-
const proc =
|
|
94527
|
+
const proc = spawn2([cli.path, ...args], {
|
|
94383
94528
|
stdout: "pipe",
|
|
94384
94529
|
stderr: "pipe"
|
|
94385
94530
|
});
|
|
@@ -94443,7 +94588,7 @@ async function runRgCountInternal(options, resolvedCli) {
|
|
|
94443
94588
|
const paths = options.paths?.length ? options.paths : ["."];
|
|
94444
94589
|
args.push(...paths);
|
|
94445
94590
|
const timeout = Math.min(options.timeout ?? DEFAULT_TIMEOUT_MS3, DEFAULT_TIMEOUT_MS3);
|
|
94446
|
-
const proc =
|
|
94591
|
+
const proc = spawn2([cli.path, ...args], {
|
|
94447
94592
|
stdout: "pipe",
|
|
94448
94593
|
stderr: "pipe"
|
|
94449
94594
|
});
|
|
@@ -94563,8 +94708,8 @@ function createGrepTools(ctx) {
|
|
|
94563
94708
|
import { resolve as resolve20 } from "path";
|
|
94564
94709
|
|
|
94565
94710
|
// src/tools/glob/cli.ts
|
|
94711
|
+
init_bun_spawn_shim();
|
|
94566
94712
|
import { resolve as resolve19 } from "path";
|
|
94567
|
-
var {spawn: spawn19 } = globalThis.Bun;
|
|
94568
94713
|
|
|
94569
94714
|
// src/tools/glob/constants.ts
|
|
94570
94715
|
var DEFAULT_TIMEOUT_MS4 = 60000;
|
|
@@ -94660,7 +94805,7 @@ async function runRgFilesInternal(options, resolvedCli) {
|
|
|
94660
94805
|
cwd = paths[0] || ".";
|
|
94661
94806
|
command = [cli.path, ...args];
|
|
94662
94807
|
}
|
|
94663
|
-
const proc =
|
|
94808
|
+
const proc = spawn2(command, {
|
|
94664
94809
|
stdout: "pipe",
|
|
94665
94810
|
stderr: "pipe",
|
|
94666
94811
|
cwd
|
|
@@ -96348,7 +96493,8 @@ function createSkillMcpTool(options) {
|
|
|
96348
96493
|
serverName: args.mcp_name,
|
|
96349
96494
|
skillName: found.skill.name,
|
|
96350
96495
|
sessionID,
|
|
96351
|
-
scope: found.skill.scope
|
|
96496
|
+
scope: found.skill.scope,
|
|
96497
|
+
directory: toolContext.directory
|
|
96352
96498
|
};
|
|
96353
96499
|
const context = {
|
|
96354
96500
|
config: found.config,
|
|
@@ -102873,6 +103019,7 @@ function normalizeHashlineEdits(rawEdits) {
|
|
|
102873
103019
|
|
|
102874
103020
|
// src/tools/hashline-edit/formatter-trigger.ts
|
|
102875
103021
|
import path14 from "path";
|
|
103022
|
+
init_bun_spawn_shim();
|
|
102876
103023
|
var cachedFormattersByDirectory = new Map;
|
|
102877
103024
|
function getFormatterCacheKey(directory) {
|
|
102878
103025
|
return path14.resolve(directory);
|
|
@@ -102937,7 +103084,7 @@ async function runFormattersForFile(client2, directory, filePath) {
|
|
|
102937
103084
|
const cmd = buildFormatterCommand(formatter.command, filePath);
|
|
102938
103085
|
try {
|
|
102939
103086
|
log("[formatter-trigger] Running formatter", { command: cmd, file: filePath });
|
|
102940
|
-
const proc =
|
|
103087
|
+
const proc = spawn2(cmd, {
|
|
102941
103088
|
cwd: directory,
|
|
102942
103089
|
env: { ...process.env, ...formatter.environment },
|
|
102943
103090
|
stdout: "ignore",
|
|
@@ -104362,11 +104509,17 @@ async function tryFallbackRetry(args) {
|
|
|
104362
104509
|
}
|
|
104363
104510
|
|
|
104364
104511
|
// src/features/background-agent/process-cleanup.ts
|
|
104365
|
-
|
|
104512
|
+
var _scheduleForcedExitEnabled = true;
|
|
104513
|
+
function scheduleForcedExit(cleanupResult, exitCode, exitAfterCleanup = false) {
|
|
104514
|
+
if (!_scheduleForcedExitEnabled)
|
|
104515
|
+
return;
|
|
104366
104516
|
process.exitCode = exitCode;
|
|
104367
104517
|
const exitTimeout = setTimeout(() => process.exit(), 6000);
|
|
104368
104518
|
Promise.resolve(cleanupResult).finally(() => {
|
|
104369
104519
|
clearTimeout(exitTimeout);
|
|
104520
|
+
if (exitAfterCleanup) {
|
|
104521
|
+
process.exit(exitCode);
|
|
104522
|
+
}
|
|
104370
104523
|
});
|
|
104371
104524
|
}
|
|
104372
104525
|
function registerProcessSignal(signal, handler, exitAfter) {
|
|
@@ -104381,8 +104534,9 @@ function registerProcessSignal(signal, handler, exitAfter) {
|
|
|
104381
104534
|
}
|
|
104382
104535
|
function registerErrorEvent(signal, handler) {
|
|
104383
104536
|
const listener = (error) => {
|
|
104537
|
+
process.off(signal, listener);
|
|
104384
104538
|
log(`[background-agent] ${signal} received during shutdown cleanup:`, error);
|
|
104385
|
-
scheduleForcedExit(handler(error), 1);
|
|
104539
|
+
scheduleForcedExit(handler(error), 1, true);
|
|
104386
104540
|
};
|
|
104387
104541
|
process.on(signal, listener);
|
|
104388
104542
|
return listener;
|
|
@@ -104773,7 +104927,7 @@ async function checkAndInterruptStaleTasks(args) {
|
|
|
104773
104927
|
const sessionStatus = sessionStatuses?.[sessionID]?.type;
|
|
104774
104928
|
const sessionIsRunning = sessionStatus !== undefined && isActiveSessionStatus(sessionStatus);
|
|
104775
104929
|
const sessionMissing = sessionStatuses !== undefined && sessionStatus === undefined;
|
|
104776
|
-
const
|
|
104930
|
+
const runtime2 = now - startedAt.getTime();
|
|
104777
104931
|
if (sessionMissing) {
|
|
104778
104932
|
task.consecutiveMissedPolls = (task.consecutiveMissedPolls ?? 0) + 1;
|
|
104779
104933
|
} else if (sessionStatuses !== undefined) {
|
|
@@ -104786,13 +104940,13 @@ async function checkAndInterruptStaleTasks(args) {
|
|
|
104786
104940
|
if (sessionMissing && !sessionGone)
|
|
104787
104941
|
continue;
|
|
104788
104942
|
const effectiveTimeout = sessionGone ? sessionGoneTimeoutMs : messageStalenessMs;
|
|
104789
|
-
if (
|
|
104943
|
+
if (runtime2 <= effectiveTimeout)
|
|
104790
104944
|
continue;
|
|
104791
104945
|
if (sessionGone && await verifySessionExists(client2, sessionID, directory)) {
|
|
104792
104946
|
task.consecutiveMissedPolls = 0;
|
|
104793
104947
|
continue;
|
|
104794
104948
|
}
|
|
104795
|
-
const staleMinutes2 = Math.round(
|
|
104949
|
+
const staleMinutes2 = Math.round(runtime2 / 60000);
|
|
104796
104950
|
const reason2 = sessionGone ? "session gone from status registry" : "no activity";
|
|
104797
104951
|
task.status = "cancelled";
|
|
104798
104952
|
task.error = `Stale timeout (${reason2} for ${staleMinutes2}min since start). This is a FINAL cancellation - do NOT create a replacement task. If the timeout is too short, increase 'background_task.${sessionGone ? "sessionGoneTimeoutMs" : "staleTimeoutMs"}' in .opencode/${CONFIG_BASENAME}.json.`;
|
|
@@ -104813,7 +104967,7 @@ async function checkAndInterruptStaleTasks(args) {
|
|
|
104813
104967
|
}
|
|
104814
104968
|
if (sessionIsRunning)
|
|
104815
104969
|
continue;
|
|
104816
|
-
if (
|
|
104970
|
+
if (runtime2 < MIN_RUNTIME_BEFORE_STALE_MS)
|
|
104817
104971
|
continue;
|
|
104818
104972
|
const timeSinceLastUpdate = now - task.progress.lastUpdate.getTime();
|
|
104819
104973
|
const effectiveStaleTimeout = sessionGone ? sessionGoneTimeoutMs : staleTimeoutMs;
|
|
@@ -105221,6 +105375,7 @@ class BackgroundManager {
|
|
|
105221
105375
|
}
|
|
105222
105376
|
spawnReservation.commit();
|
|
105223
105377
|
this.markPreStartDescendantReservation(task);
|
|
105378
|
+
this.updateBackgroundTaskMarker(input.parentSessionId);
|
|
105224
105379
|
this.processKey(key);
|
|
105225
105380
|
return { ...task };
|
|
105226
105381
|
} catch (error) {
|
|
@@ -105268,6 +105423,7 @@ class BackgroundManager {
|
|
|
105268
105423
|
if (item.task.sessionId) {
|
|
105269
105424
|
await this.abortSessionWithLogging(item.task.sessionId, "startTask error cleanup");
|
|
105270
105425
|
}
|
|
105426
|
+
this.updateBackgroundTaskMarker(item.task.parentSessionId);
|
|
105271
105427
|
this.markForNotification(item.task);
|
|
105272
105428
|
this.enqueueNotificationForParent(item.task.parentSessionId, () => this.notifyParentSession(item.task)).catch((err) => {
|
|
105273
105429
|
log("[background-agent] Failed to notify on startTask error:", err);
|
|
@@ -105522,6 +105678,15 @@ The fallback retry session is now created and can be inspected directly.
|
|
|
105522
105678
|
}
|
|
105523
105679
|
return tasks;
|
|
105524
105680
|
}
|
|
105681
|
+
updateBackgroundTaskMarker(parentSessionID) {
|
|
105682
|
+
const tasks = this.getTasksByParentSession(parentSessionID);
|
|
105683
|
+
const activeTasks = tasks.filter((t) => t.status === "running" || t.status === "pending");
|
|
105684
|
+
if (activeTasks.length > 0) {
|
|
105685
|
+
setContinuationMarkerSource(this.directory, parentSessionID, "background-task", "active", `${activeTasks.length} background task(s) active`);
|
|
105686
|
+
} else {
|
|
105687
|
+
setContinuationMarkerSource(this.directory, parentSessionID, "background-task", "idle");
|
|
105688
|
+
}
|
|
105689
|
+
}
|
|
105525
105690
|
getAllDescendantTasks(sessionID) {
|
|
105526
105691
|
const result = [];
|
|
105527
105692
|
const directChildren = this.getTasksByParentSession(sessionID);
|
|
@@ -106102,6 +106267,9 @@ The fallback retry session is now created and can be inspected directly.
|
|
|
106102
106267
|
if (task.sessionId) {
|
|
106103
106268
|
SessionCategoryRegistry.remove(task.sessionId);
|
|
106104
106269
|
}
|
|
106270
|
+
if (task.parentSessionId) {
|
|
106271
|
+
this.updateBackgroundTaskMarker(task.parentSessionId);
|
|
106272
|
+
}
|
|
106105
106273
|
this.markForNotification(task);
|
|
106106
106274
|
this.enqueueNotificationForParent(task.parentSessionId, () => this.notifyParentSession(task)).catch((err) => {
|
|
106107
106275
|
log("[background-agent] Error in notifyParentSession for errored task:", { taskId: task.id, error: err });
|
|
@@ -106336,6 +106504,9 @@ ${originalText}`;
|
|
|
106336
106504
|
SessionCategoryRegistry.remove(task.sessionId);
|
|
106337
106505
|
}
|
|
106338
106506
|
removeTaskToastTracking(task.id);
|
|
106507
|
+
if (task.parentSessionId) {
|
|
106508
|
+
this.updateBackgroundTaskMarker(task.parentSessionId);
|
|
106509
|
+
}
|
|
106339
106510
|
if (options?.skipNotification) {
|
|
106340
106511
|
this.cleanupPendingByParent(task);
|
|
106341
106512
|
this.scheduleTaskRemoval(task.id);
|
|
@@ -106415,6 +106586,9 @@ ${originalText}`;
|
|
|
106415
106586
|
await this.abortSessionWithLogging(task.sessionId, `task completion (${source})`);
|
|
106416
106587
|
SessionCategoryRegistry.remove(task.sessionId);
|
|
106417
106588
|
}
|
|
106589
|
+
if (task.parentSessionId) {
|
|
106590
|
+
this.updateBackgroundTaskMarker(task.parentSessionId);
|
|
106591
|
+
}
|
|
106418
106592
|
try {
|
|
106419
106593
|
await this.enqueueNotificationForParent(task.parentSessionId, () => this.notifyParentSession(task));
|
|
106420
106594
|
log(`[background-agent] Task completed via ${source}:`, task.id);
|
|
@@ -106598,6 +106772,9 @@ ${originalText}`;
|
|
|
106598
106772
|
}
|
|
106599
106773
|
}
|
|
106600
106774
|
this.cleanupPendingByParent(task);
|
|
106775
|
+
if (task.parentSessionId) {
|
|
106776
|
+
this.updateBackgroundTaskMarker(task.parentSessionId);
|
|
106777
|
+
}
|
|
106601
106778
|
this.markForNotification(task);
|
|
106602
106779
|
this.enqueueNotificationForParent(task.parentSessionId, () => this.notifyParentSession(task)).catch((err) => {
|
|
106603
106780
|
log("[background-agent] Error in notifyParentSession for stale-pruned task:", { taskId: task.id, error: err });
|
|
@@ -106652,6 +106829,9 @@ ${originalText}`;
|
|
|
106652
106829
|
if (task.sessionId) {
|
|
106653
106830
|
SessionCategoryRegistry.remove(task.sessionId);
|
|
106654
106831
|
}
|
|
106832
|
+
if (task.parentSessionId) {
|
|
106833
|
+
this.updateBackgroundTaskMarker(task.parentSessionId);
|
|
106834
|
+
}
|
|
106655
106835
|
this.markForNotification(task);
|
|
106656
106836
|
this.enqueueNotificationForParent(task.parentSessionId, () => this.notifyParentSession(task)).catch((err) => {
|
|
106657
106837
|
log("[background-agent] Error in notifyParentSession for crashed task:", { taskId: task.id, error: err });
|
|
@@ -107095,7 +107275,7 @@ async function findAvailablePort2(startPort = DEFAULT_PORT) {
|
|
|
107095
107275
|
}
|
|
107096
107276
|
|
|
107097
107277
|
// src/features/mcp-oauth/oauth-authorization-flow.ts
|
|
107098
|
-
import { spawn as
|
|
107278
|
+
import { spawn as spawn3 } from "child_process";
|
|
107099
107279
|
import { createHash as createHash2, randomBytes as randomBytes2 } from "crypto";
|
|
107100
107280
|
import { createServer } from "http";
|
|
107101
107281
|
function generateCodeVerifier() {
|
|
@@ -107176,7 +107356,7 @@ function openBrowser(url) {
|
|
|
107176
107356
|
args = [url];
|
|
107177
107357
|
}
|
|
107178
107358
|
try {
|
|
107179
|
-
const child =
|
|
107359
|
+
const child = spawn3(command, args, { stdio: "ignore", detached: true });
|
|
107180
107360
|
child.on("error", () => {});
|
|
107181
107361
|
child.unref();
|
|
107182
107362
|
} catch {}
|
|
@@ -111777,7 +111957,8 @@ async function createStdioClient(params) {
|
|
|
111777
111957
|
command,
|
|
111778
111958
|
args,
|
|
111779
111959
|
env: mergedEnv,
|
|
111780
|
-
stderr: "ignore"
|
|
111960
|
+
stderr: "ignore",
|
|
111961
|
+
...info.directory ? { cwd: info.directory } : {}
|
|
111781
111962
|
});
|
|
111782
111963
|
const client2 = stdioClientDependencies.createClient({ name: `skill-mcp-${info.skillName}-${info.serverName}`, version: "1.0.0" }, { capabilities: {} });
|
|
111783
111964
|
try {
|
|
@@ -112083,7 +112264,7 @@ function createModelFallbackControllerAccessor() {
|
|
|
112083
112264
|
};
|
|
112084
112265
|
}
|
|
112085
112266
|
// src/features/tmux-subagent/pane-state-querier.ts
|
|
112086
|
-
|
|
112267
|
+
init_bun_spawn_shim();
|
|
112087
112268
|
|
|
112088
112269
|
// src/features/tmux-subagent/pane-state-parser.ts
|
|
112089
112270
|
var MANDATORY_PANE_FIELD_COUNT = 8;
|
|
@@ -112172,7 +112353,7 @@ async function queryWindowState(sourcePaneId) {
|
|
|
112172
112353
|
const tmux3 = await getTmuxPath();
|
|
112173
112354
|
if (!tmux3)
|
|
112174
112355
|
return null;
|
|
112175
|
-
const proc =
|
|
112356
|
+
const proc = spawn2([
|
|
112176
112357
|
tmux3,
|
|
112177
112358
|
"list-panes",
|
|
112178
112359
|
"-t",
|
|
@@ -113708,7 +113889,7 @@ function resolveGateway(config2, event) {
|
|
|
113708
113889
|
}
|
|
113709
113890
|
|
|
113710
113891
|
// src/openclaw/dispatcher.ts
|
|
113711
|
-
|
|
113892
|
+
init_bun_spawn_shim();
|
|
113712
113893
|
var DEFAULT_HTTP_TIMEOUT_MS = 1e4;
|
|
113713
113894
|
var DEFAULT_COMMAND_TIMEOUT_MS = 5000;
|
|
113714
113895
|
var MIN_COMMAND_TIMEOUT_MS = 100;
|
|
@@ -113842,7 +114023,7 @@ async function wakeCommandGateway(gatewayName, gatewayConfig, variables) {
|
|
|
113842
114023
|
return _match;
|
|
113843
114024
|
return shellEscapeArg(value);
|
|
113844
114025
|
});
|
|
113845
|
-
const proc =
|
|
114026
|
+
const proc = spawn2(["sh", "-c", interpolated], {
|
|
113846
114027
|
env: { ...process.env },
|
|
113847
114028
|
stdout: "pipe",
|
|
113848
114029
|
stderr: "ignore",
|
|
@@ -113892,7 +114073,7 @@ function terminateCommandProcess(proc, signal) {
|
|
|
113892
114073
|
}
|
|
113893
114074
|
|
|
113894
114075
|
// src/openclaw/tmux.ts
|
|
113895
|
-
|
|
114076
|
+
init_bun_spawn_shim();
|
|
113896
114077
|
function getCurrentTmuxSession() {
|
|
113897
114078
|
const env = process.env.TMUX;
|
|
113898
114079
|
if (!env)
|
|
@@ -113902,7 +114083,7 @@ function getCurrentTmuxSession() {
|
|
|
113902
114083
|
}
|
|
113903
114084
|
async function captureTmuxPane(paneId, lines = 15) {
|
|
113904
114085
|
try {
|
|
113905
|
-
const proc =
|
|
114086
|
+
const proc = spawn2(["tmux", "capture-pane", "-p", "-t", paneId, "-S", `-${lines}`], {
|
|
113906
114087
|
stdout: "pipe",
|
|
113907
114088
|
stderr: "ignore"
|
|
113908
114089
|
});
|
|
@@ -113918,7 +114099,7 @@ async function captureTmuxPane(paneId, lines = 15) {
|
|
|
113918
114099
|
}
|
|
113919
114100
|
async function isTmuxAvailable() {
|
|
113920
114101
|
try {
|
|
113921
|
-
const proc =
|
|
114102
|
+
const proc = spawn2(["tmux", "-V"], {
|
|
113922
114103
|
stdout: "ignore",
|
|
113923
114104
|
stderr: "ignore"
|
|
113924
114105
|
});
|
|
@@ -114383,8 +114564,8 @@ function markReplyListenerStopped(state3, error) {
|
|
|
114383
114564
|
}
|
|
114384
114565
|
|
|
114385
114566
|
// src/openclaw/reply-listener-process.ts
|
|
114567
|
+
init_bun_spawn_shim();
|
|
114386
114568
|
import { readFileSync as readFileSync62 } from "fs";
|
|
114387
|
-
var {spawn: spawn25 } = globalThis.Bun;
|
|
114388
114569
|
var REPLY_LISTENER_DAEMON_IDENTITY_MARKER = "--openclaw-reply-listener-daemon";
|
|
114389
114570
|
var REPLY_LISTENER_DAEMON_ENV_ALLOWLIST = [
|
|
114390
114571
|
"PATH",
|
|
@@ -114442,7 +114623,7 @@ async function isReplyListenerDaemonProcess(pid) {
|
|
|
114442
114623
|
const cmdline = readFileSync62(`/proc/${pid}/cmdline`, "utf-8");
|
|
114443
114624
|
return cmdline.includes(REPLY_LISTENER_DAEMON_IDENTITY_MARKER);
|
|
114444
114625
|
}
|
|
114445
|
-
const processInfo =
|
|
114626
|
+
const processInfo = spawn2(["ps", "-p", String(pid), "-o", "args="], {
|
|
114446
114627
|
stdout: "pipe",
|
|
114447
114628
|
stderr: "ignore"
|
|
114448
114629
|
});
|
|
@@ -114456,9 +114637,9 @@ async function isReplyListenerDaemonProcess(pid) {
|
|
|
114456
114637
|
}
|
|
114457
114638
|
|
|
114458
114639
|
// src/openclaw/reply-listener-spawn.ts
|
|
114459
|
-
|
|
114640
|
+
init_bun_spawn_shim();
|
|
114460
114641
|
function spawnReplyListenerDaemon(daemonScript, startupToken) {
|
|
114461
|
-
return
|
|
114642
|
+
return spawn2(["bun", "run", daemonScript, REPLY_LISTENER_DAEMON_IDENTITY_MARKER], {
|
|
114462
114643
|
detached: true,
|
|
114463
114644
|
stdio: ["ignore", "ignore", "ignore"],
|
|
114464
114645
|
cwd: process.cwd(),
|
|
@@ -127608,7 +127789,6 @@ init_agent_display_names();
|
|
|
127608
127789
|
init_agent_display_names();
|
|
127609
127790
|
|
|
127610
127791
|
// src/plugin/ultrawork-db-model-override.ts
|
|
127611
|
-
import { Database } from "bun:sqlite";
|
|
127612
127792
|
import { join as join102 } from "path";
|
|
127613
127793
|
import { existsSync as existsSync92 } from "fs";
|
|
127614
127794
|
function getDbPath() {
|
|
@@ -127687,7 +127867,13 @@ function retryViaMicrotask(db, messageId, targetModel, variant, attempt) {
|
|
|
127687
127867
|
});
|
|
127688
127868
|
}
|
|
127689
127869
|
function scheduleDeferredModelOverride(messageId, targetModel, variant) {
|
|
127690
|
-
queueMicrotask(() => {
|
|
127870
|
+
queueMicrotask(async () => {
|
|
127871
|
+
const sqliteModule = await import("bun:sqlite").catch(() => null);
|
|
127872
|
+
const Database = sqliteModule?.Database;
|
|
127873
|
+
if (typeof Database !== "function") {
|
|
127874
|
+
log("[ultrawork-db-override] bun:sqlite unavailable, skipping deferred override", { messageId });
|
|
127875
|
+
return;
|
|
127876
|
+
}
|
|
127691
127877
|
const dbPath = getDbPath();
|
|
127692
127878
|
if (!existsSync92(dbPath)) {
|
|
127693
127879
|
log("[ultrawork-db-override] DB not found, skipping deferred override");
|
|
@@ -133787,7 +133973,7 @@ class PostHog extends PostHogBackendClient {
|
|
|
133787
133973
|
// package.json
|
|
133788
133974
|
var package_default = {
|
|
133789
133975
|
name: "oh-my-opencode",
|
|
133790
|
-
version: "3.17.
|
|
133976
|
+
version: "3.17.15",
|
|
133791
133977
|
description: "The Best AI Agent Harness - Batteries-Included OpenCode Plugin with Multi-Model Orchestration, Parallel Background Agents, and Crafted LSP/AST Tools",
|
|
133792
133978
|
main: "./dist/index.js",
|
|
133793
133979
|
types: "dist/index.d.ts",
|
|
@@ -133809,7 +133995,8 @@ var package_default = {
|
|
|
133809
133995
|
"./schema.json": "./dist/oh-my-opencode.schema.json"
|
|
133810
133996
|
},
|
|
133811
133997
|
scripts: {
|
|
133812
|
-
build: "bun build src/index.ts --outdir dist --target bun --format esm --external @ast-grep/napi --external zod && tsc --emitDeclarationOnly && bun build src/cli/index.ts --outdir dist/cli --target bun --format esm --external @ast-grep/napi && bun run build:schema",
|
|
133998
|
+
build: "bun build src/index.ts --outdir dist --target bun --format esm --external @ast-grep/napi --external zod && bun run build:node-require-shim && tsc --emitDeclarationOnly && bun build src/cli/index.ts --outdir dist/cli --target bun --format esm --external @ast-grep/napi && bun run build:schema",
|
|
133999
|
+
"build:node-require-shim": "bun run script/patch-node-require-shim.ts",
|
|
133813
134000
|
"build:all": "bun run build && bun run build:binaries",
|
|
133814
134001
|
"build:binaries": "bun run script/build-binaries.ts",
|
|
133815
134002
|
"build:schema": "bun run script/build-schema.ts",
|
|
@@ -133867,17 +134054,17 @@ var package_default = {
|
|
|
133867
134054
|
zod: "^4.3.0"
|
|
133868
134055
|
},
|
|
133869
134056
|
optionalDependencies: {
|
|
133870
|
-
"oh-my-opencode-darwin-arm64": "3.17.
|
|
133871
|
-
"oh-my-opencode-darwin-x64": "3.17.
|
|
133872
|
-
"oh-my-opencode-darwin-x64-baseline": "3.17.
|
|
133873
|
-
"oh-my-opencode-linux-arm64": "3.17.
|
|
133874
|
-
"oh-my-opencode-linux-arm64-musl": "3.17.
|
|
133875
|
-
"oh-my-opencode-linux-x64": "3.17.
|
|
133876
|
-
"oh-my-opencode-linux-x64-baseline": "3.17.
|
|
133877
|
-
"oh-my-opencode-linux-x64-musl": "3.17.
|
|
133878
|
-
"oh-my-opencode-linux-x64-musl-baseline": "3.17.
|
|
133879
|
-
"oh-my-opencode-windows-x64": "3.17.
|
|
133880
|
-
"oh-my-opencode-windows-x64-baseline": "3.17.
|
|
134057
|
+
"oh-my-opencode-darwin-arm64": "3.17.15",
|
|
134058
|
+
"oh-my-opencode-darwin-x64": "3.17.15",
|
|
134059
|
+
"oh-my-opencode-darwin-x64-baseline": "3.17.15",
|
|
134060
|
+
"oh-my-opencode-linux-arm64": "3.17.15",
|
|
134061
|
+
"oh-my-opencode-linux-arm64-musl": "3.17.15",
|
|
134062
|
+
"oh-my-opencode-linux-x64": "3.17.15",
|
|
134063
|
+
"oh-my-opencode-linux-x64-baseline": "3.17.15",
|
|
134064
|
+
"oh-my-opencode-linux-x64-musl": "3.17.15",
|
|
134065
|
+
"oh-my-opencode-linux-x64-musl-baseline": "3.17.15",
|
|
134066
|
+
"oh-my-opencode-windows-x64": "3.17.15",
|
|
134067
|
+
"oh-my-opencode-windows-x64-baseline": "3.17.15"
|
|
133881
134068
|
},
|
|
133882
134069
|
overrides: {},
|
|
133883
134070
|
trustedDependencies: [
|