@agimon-ai/po-runner 0.0.0-alpha.0
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/LICENSE +21 -0
- package/README.md +257 -0
- package/dist/ansiScrub-CsqTSaVT.mjs +71 -0
- package/dist/ansiScrub-CsqTSaVT.mjs.map +1 -0
- package/dist/ansiScrub-D5gpHDch.cjs +100 -0
- package/dist/ansiScrub-D5gpHDch.cjs.map +1 -0
- package/dist/ansiScrub.cjs +7 -0
- package/dist/ansiScrub.d.mts +26 -0
- package/dist/ansiScrub.d.mts.map +1 -0
- package/dist/ansiScrub.mjs +2 -0
- package/dist/apiContracts.cjs +162 -0
- package/dist/apiContracts.cjs.map +1 -0
- package/dist/apiContracts.d.mts +53 -0
- package/dist/apiContracts.d.mts.map +1 -0
- package/dist/apiContracts.mjs +157 -0
- package/dist/apiContracts.mjs.map +1 -0
- package/dist/bashResult-DNgtahGR.cjs +629 -0
- package/dist/bashResult-DNgtahGR.cjs.map +1 -0
- package/dist/bashResult-DcrRaBLv.d.mts +49 -0
- package/dist/bashResult-DcrRaBLv.d.mts.map +1 -0
- package/dist/bashResult-bIVSzoj-.mjs +546 -0
- package/dist/bashResult-bIVSzoj-.mjs.map +1 -0
- package/dist/bashRunService-CJ02XaAq.mjs +440 -0
- package/dist/bashRunService-CJ02XaAq.mjs.map +1 -0
- package/dist/bashRunService-Ci0cGdYO.d.mts +71 -0
- package/dist/bashRunService-Ci0cGdYO.d.mts.map +1 -0
- package/dist/bashRunService-DyqxOSlx.cjs +445 -0
- package/dist/bashRunService-DyqxOSlx.cjs.map +1 -0
- package/dist/bashRunService.cjs +3 -0
- package/dist/bashRunService.d.mts +36 -0
- package/dist/bashRunService.d.mts.map +1 -0
- package/dist/bashRunService.mjs +2 -0
- package/dist/bashSchema.cjs +5 -0
- package/dist/bashSchema.d.mts +7 -0
- package/dist/bashSchema.d.mts.map +1 -0
- package/dist/bashSchema.mjs +2 -0
- package/dist/bashTool-B1EwZLo_.d.mts +20 -0
- package/dist/bashTool-B1EwZLo_.d.mts.map +1 -0
- package/dist/bashTool-C-k7fmyh.mjs +24 -0
- package/dist/bashTool-C-k7fmyh.mjs.map +1 -0
- package/dist/bashTool-CdgtqVFD.cjs +41 -0
- package/dist/bashTool-CdgtqVFD.cjs.map +1 -0
- package/dist/bashTool.cjs +13 -0
- package/dist/bashTool.cjs.map +1 -0
- package/dist/bashTool.d.mts +8 -0
- package/dist/bashTool.d.mts.map +1 -0
- package/dist/bashTool.mjs +11 -0
- package/dist/bashTool.mjs.map +1 -0
- package/dist/bin/cli.cjs +78 -0
- package/dist/bin/cli.cjs.map +1 -0
- package/dist/bin/cli.d.mts +4 -0
- package/dist/bin/cli.d.mts.map +1 -0
- package/dist/bin/cli.mjs +77 -0
- package/dist/bin/cli.mjs.map +1 -0
- package/dist/bin/logSink.cjs +102 -0
- package/dist/bin/logSink.cjs.map +1 -0
- package/dist/bin/logSink.d.mts +4 -0
- package/dist/bin/logSink.d.mts.map +1 -0
- package/dist/bin/logSink.mjs +99 -0
- package/dist/bin/logSink.mjs.map +1 -0
- package/dist/bin/runnerHost.cjs +131 -0
- package/dist/bin/runnerHost.cjs.map +1 -0
- package/dist/bin/runnerHost.d.mts +4 -0
- package/dist/bin/runnerHost.d.mts.map +1 -0
- package/dist/bin/runnerHost.mjs +127 -0
- package/dist/bin/runnerHost.mjs.map +1 -0
- package/dist/cliApp-Dj9nwaOv.cjs +244 -0
- package/dist/cliApp-Dj9nwaOv.cjs.map +1 -0
- package/dist/cliApp-v8Z3rMCi.mjs +237 -0
- package/dist/cliApp-v8Z3rMCi.mjs.map +1 -0
- package/dist/cliApp.cjs +3 -0
- package/dist/cliApp.d.mts +18 -0
- package/dist/cliApp.d.mts.map +1 -0
- package/dist/cliApp.mjs +2 -0
- package/dist/clock-Cv2pddgo.mjs +16 -0
- package/dist/clock-Cv2pddgo.mjs.map +1 -0
- package/dist/clock-euJkweLq.d.mts +11 -0
- package/dist/clock-euJkweLq.d.mts.map +1 -0
- package/dist/clock-jqnLWziT.cjs +21 -0
- package/dist/clock-jqnLWziT.cjs.map +1 -0
- package/dist/clock.cjs +3 -0
- package/dist/clock.d.mts +10 -0
- package/dist/clock.d.mts.map +1 -0
- package/dist/clock.mjs +2 -0
- package/dist/compaction-4QSUsBxq.cjs +40 -0
- package/dist/compaction-4QSUsBxq.cjs.map +1 -0
- package/dist/compaction-DCw80VZj.mjs +29 -0
- package/dist/compaction-DCw80VZj.mjs.map +1 -0
- package/dist/compaction.cjs +4 -0
- package/dist/compaction.d.mts +10 -0
- package/dist/compaction.d.mts.map +1 -0
- package/dist/compaction.mjs +2 -0
- package/dist/config.cjs +41 -0
- package/dist/config.d.mts +2 -0
- package/dist/config.mjs +2 -0
- package/dist/extensions/mcp-ui.mjs +23 -0
- package/dist/extensions/mcp-ui.mjs.map +1 -0
- package/dist/extensions/mcp.cjs +142 -0
- package/dist/extensions/mcp.cjs.map +1 -0
- package/dist/extensions/mcp.d.mts +5 -0
- package/dist/extensions/mcp.d.mts.map +1 -0
- package/dist/extensions/mcp.mjs +114 -0
- package/dist/extensions/mcp.mjs.map +1 -0
- package/dist/extensions/server.cjs +1156 -0
- package/dist/extensions/server.cjs.map +1 -0
- package/dist/extensions/server.d.mts +5 -0
- package/dist/extensions/server.d.mts.map +1 -0
- package/dist/extensions/server.mjs +1146 -0
- package/dist/extensions/server.mjs.map +1 -0
- package/dist/extensions/web.mjs +1785 -0
- package/dist/extensions/web.mjs.map +1 -0
- package/dist/headless-BGYfIlNk.mjs +169 -0
- package/dist/headless-BGYfIlNk.mjs.map +1 -0
- package/dist/headless-CHUsBGhg.cjs +180 -0
- package/dist/headless-CHUsBGhg.cjs.map +1 -0
- package/dist/index-BZL7keVW.d.mts +31 -0
- package/dist/index-BZL7keVW.d.mts.map +1 -0
- package/dist/index-BwB_jTI9.d.mts +12 -0
- package/dist/index-BwB_jTI9.d.mts.map +1 -0
- package/dist/index-D9-IXax4.d.mts +43 -0
- package/dist/index-D9-IXax4.d.mts.map +1 -0
- package/dist/index-DBz0DxnL.d.mts +39 -0
- package/dist/index-DBz0DxnL.d.mts.map +1 -0
- package/dist/index-DM7yJpMs.d.mts +25 -0
- package/dist/index-DM7yJpMs.d.mts.map +1 -0
- package/dist/index-Dhi8asLH.d.mts +22 -0
- package/dist/index-Dhi8asLH.d.mts.map +1 -0
- package/dist/index.cjs +19 -0
- package/dist/index.d.mts +7 -0
- package/dist/index.mjs +6 -0
- package/dist/launcher-BDm6-DiQ.mjs +150 -0
- package/dist/launcher-BDm6-DiQ.mjs.map +1 -0
- package/dist/launcher-BG5t9nvG.d.mts +39 -0
- package/dist/launcher-BG5t9nvG.d.mts.map +1 -0
- package/dist/launcher-SlyE8R3b.cjs +157 -0
- package/dist/launcher-SlyE8R3b.cjs.map +1 -0
- package/dist/launcher.cjs +3 -0
- package/dist/launcher.d.mts +33 -0
- package/dist/launcher.d.mts.map +1 -0
- package/dist/launcher.mjs +2 -0
- package/dist/lifeline-BZaQA0rm.mjs +88 -0
- package/dist/lifeline-BZaQA0rm.mjs.map +1 -0
- package/dist/lifeline-BuV_erib.cjs +98 -0
- package/dist/lifeline-BuV_erib.cjs.map +1 -0
- package/dist/lifeline-eJdZV0nN.d.mts +19 -0
- package/dist/lifeline-eJdZV0nN.d.mts.map +1 -0
- package/dist/lifeline.cjs +6 -0
- package/dist/lifeline.d.mts +21 -0
- package/dist/lifeline.d.mts.map +1 -0
- package/dist/lifeline.mjs +3 -0
- package/dist/logFile-C7oQ_v-g.d.mts +16 -0
- package/dist/logFile-C7oQ_v-g.d.mts.map +1 -0
- package/dist/logFile-CNvepZh0.cjs +67 -0
- package/dist/logFile-CNvepZh0.cjs.map +1 -0
- package/dist/logFile-KKPbkC-a.mjs +60 -0
- package/dist/logFile-KKPbkC-a.mjs.map +1 -0
- package/dist/logFile.cjs +3 -0
- package/dist/logFile.d.mts +11 -0
- package/dist/logFile.d.mts.map +1 -0
- package/dist/logFile.mjs +2 -0
- package/dist/logReader-B6J7L7Ua.cjs +282 -0
- package/dist/logReader-B6J7L7Ua.cjs.map +1 -0
- package/dist/logReader-MdW9ffvV.d.mts +43 -0
- package/dist/logReader-MdW9ffvV.d.mts.map +1 -0
- package/dist/logReader-UfbDbwQl.mjs +257 -0
- package/dist/logReader-UfbDbwQl.mjs.map +1 -0
- package/dist/logReader.cjs +4 -0
- package/dist/logReader.d.mts +3 -0
- package/dist/logReader.mjs +2 -0
- package/dist/processControl-BAOa3oo_.d.mts +14 -0
- package/dist/processControl-BAOa3oo_.d.mts.map +1 -0
- package/dist/processControl-DApTpV16.mjs +26 -0
- package/dist/processControl-DApTpV16.mjs.map +1 -0
- package/dist/processControl-DNJ1WZ9N.cjs +31 -0
- package/dist/processControl-DNJ1WZ9N.cjs.map +1 -0
- package/dist/processControl.cjs +3 -0
- package/dist/processControl.d.mts +10 -0
- package/dist/processControl.d.mts.map +1 -0
- package/dist/processControl.mjs +2 -0
- package/dist/ptyHost-DWWtRrGn.d.mts +38 -0
- package/dist/ptyHost-DWWtRrGn.d.mts.map +1 -0
- package/dist/ptyHost-DlQtTB8F.mjs +150 -0
- package/dist/ptyHost-DlQtTB8F.mjs.map +1 -0
- package/dist/ptyHost-MI2Z6WTG.cjs +157 -0
- package/dist/ptyHost-MI2Z6WTG.cjs.map +1 -0
- package/dist/ptyHost.cjs +3 -0
- package/dist/ptyHost.d.mts +26 -0
- package/dist/ptyHost.d.mts.map +1 -0
- package/dist/ptyHost.mjs +2 -0
- package/dist/ptySpawner-B6GsueZd.d.mts +28 -0
- package/dist/ptySpawner-B6GsueZd.d.mts.map +1 -0
- package/dist/ptySpawner-DEi1KOnd.mjs +17 -0
- package/dist/ptySpawner-DEi1KOnd.mjs.map +1 -0
- package/dist/ptySpawner-ijw0g5_T.cjs +22 -0
- package/dist/ptySpawner-ijw0g5_T.cjs.map +1 -0
- package/dist/ptySpawner.cjs +3 -0
- package/dist/ptySpawner.d.mts +14 -0
- package/dist/ptySpawner.d.mts.map +1 -0
- package/dist/ptySpawner.mjs +2 -0
- package/dist/reconcile-BugwYFbV.cjs +133 -0
- package/dist/reconcile-BugwYFbV.cjs.map +1 -0
- package/dist/reconcile-DMeNSxwn.mjs +114 -0
- package/dist/reconcile-DMeNSxwn.mjs.map +1 -0
- package/dist/reconcile.cjs +5 -0
- package/dist/reconcile.d.mts +36 -0
- package/dist/reconcile.d.mts.map +1 -0
- package/dist/reconcile.mjs +2 -0
- package/dist/responseEnvelope.cjs +19 -0
- package/dist/responseEnvelope.d.mts +50 -0
- package/dist/responseEnvelope.d.mts.map +1 -0
- package/dist/responseEnvelope.mjs +3 -0
- package/dist/rmuxBackend-CaEWooWn.d.mts +36 -0
- package/dist/rmuxBackend-CaEWooWn.d.mts.map +1 -0
- package/dist/rmuxBackend-DfyQwJrc.mjs +509 -0
- package/dist/rmuxBackend-DfyQwJrc.mjs.map +1 -0
- package/dist/rmuxBackend-DlxgqRZ1.cjs +523 -0
- package/dist/rmuxBackend-DlxgqRZ1.cjs.map +1 -0
- package/dist/rmuxBackend.cjs +4 -0
- package/dist/rmuxBackend.d.mts +3 -0
- package/dist/rmuxBackend.mjs +2 -0
- package/dist/rolldown-runtime-VH7oDXx4.cjs +28 -0
- package/dist/rtkProcessor-B4_urXQr.mjs +10 -0
- package/dist/rtkProcessor-B4_urXQr.mjs.map +1 -0
- package/dist/rtkProcessor-B9KPdyzr.mjs +309 -0
- package/dist/rtkProcessor-B9KPdyzr.mjs.map +1 -0
- package/dist/rtkProcessor-Bc4L4o_8.cjs +335 -0
- package/dist/rtkProcessor-Bc4L4o_8.cjs.map +1 -0
- package/dist/rtkProcessor-CVZvNhkJ.d.mts +35 -0
- package/dist/rtkProcessor-CVZvNhkJ.d.mts.map +1 -0
- package/dist/rtkProcessor-CsrCPyTQ.cjs +33 -0
- package/dist/rtkProcessor-CsrCPyTQ.cjs.map +1 -0
- package/dist/rtkProcessor.cjs +11 -0
- package/dist/rtkProcessor.d.mts +7 -0
- package/dist/rtkProcessor.d.mts.map +1 -0
- package/dist/rtkProcessor.mjs +3 -0
- package/dist/runnerConfig-BQBlVAXn.mjs +134 -0
- package/dist/runnerConfig-BQBlVAXn.mjs.map +1 -0
- package/dist/runnerConfig-BjtulXBI.d.mts +57 -0
- package/dist/runnerConfig-BjtulXBI.d.mts.map +1 -0
- package/dist/runnerConfig-D2tGq5ZM.cjs +367 -0
- package/dist/runnerConfig-D2tGq5ZM.cjs.map +1 -0
- package/dist/runnerDependencies-DruByBGS.mjs +647 -0
- package/dist/runnerDependencies-DruByBGS.mjs.map +1 -0
- package/dist/runnerDependencies-KMZigIxB.cjs +667 -0
- package/dist/runnerDependencies-KMZigIxB.cjs.map +1 -0
- package/dist/runnerDependencies.cjs +3 -0
- package/dist/runnerDependencies.d.mts +2 -0
- package/dist/runnerDependencies.mjs +2 -0
- package/dist/runnerNamer-B8FH7n2v.mjs +44 -0
- package/dist/runnerNamer-B8FH7n2v.mjs.map +1 -0
- package/dist/runnerNamer-we1XVYfM.cjs +49 -0
- package/dist/runnerNamer-we1XVYfM.cjs.map +1 -0
- package/dist/runnerNamer.cjs +3 -0
- package/dist/runnerNamer.d.mts +11 -0
- package/dist/runnerNamer.d.mts.map +1 -0
- package/dist/runnerNamer.mjs +2 -0
- package/dist/runnerPaths-BTEuzxw0.cjs +471 -0
- package/dist/runnerPaths-BTEuzxw0.cjs.map +1 -0
- package/dist/runnerPaths-B_dAAeco.mjs +451 -0
- package/dist/runnerPaths-B_dAAeco.mjs.map +1 -0
- package/dist/runnerPaths.cjs +3 -0
- package/dist/runnerPaths.d.mts +50 -0
- package/dist/runnerPaths.d.mts.map +1 -0
- package/dist/runnerPaths.mjs +2 -0
- package/dist/runnerRegistry-BmkZTJHi.cjs +371 -0
- package/dist/runnerRegistry-BmkZTJHi.cjs.map +1 -0
- package/dist/runnerRegistry-CeOHEjBv.mjs +339 -0
- package/dist/runnerRegistry-CeOHEjBv.mjs.map +1 -0
- package/dist/runnerRegistry-CtJiD02R.d.mts +88 -0
- package/dist/runnerRegistry-CtJiD02R.d.mts.map +1 -0
- package/dist/runnerRegistry.cjs +4 -0
- package/dist/runnerRegistry.d.mts +3 -0
- package/dist/runnerRegistry.mjs +2 -0
- package/dist/runnerSettings-DiV1lvzx.d.mts +34 -0
- package/dist/runnerSettings-DiV1lvzx.d.mts.map +1 -0
- package/dist/services/lifeline/client.cjs +52 -0
- package/dist/services/lifeline/client.cjs.map +1 -0
- package/dist/services/lifeline/client.d.mts +22 -0
- package/dist/services/lifeline/client.d.mts.map +1 -0
- package/dist/services/lifeline/client.mjs +48 -0
- package/dist/services/lifeline/client.mjs.map +1 -0
- package/dist/services/runnerSupervisor/index.cjs +207 -0
- package/dist/services/runnerSupervisor/index.cjs.map +1 -0
- package/dist/services/runnerSupervisor/index.d.mts +71 -0
- package/dist/services/runnerSupervisor/index.d.mts.map +1 -0
- package/dist/services/runnerSupervisor/index.mjs +195 -0
- package/dist/services/runnerSupervisor/index.mjs.map +1 -0
- package/dist/session-BC43uEyG.cjs +29 -0
- package/dist/session-BC43uEyG.cjs.map +1 -0
- package/dist/session-Chsb_Nh2.mjs +18 -0
- package/dist/session-Chsb_Nh2.mjs.map +1 -0
- package/dist/session-DE2Acesp.mjs +6 -0
- package/dist/session-DE2Acesp.mjs.map +1 -0
- package/dist/session-SfIPtdZO.cjs +11 -0
- package/dist/session-SfIPtdZO.cjs.map +1 -0
- package/dist/session.cjs +6 -0
- package/dist/session.d.mts +11 -0
- package/dist/session.d.mts.map +1 -0
- package/dist/session.mjs +3 -0
- package/dist/spawner-BxFsINXP.cjs +68 -0
- package/dist/spawner-BxFsINXP.cjs.map +1 -0
- package/dist/spawner-CdrN_HNk.d.mts +35 -0
- package/dist/spawner-CdrN_HNk.d.mts.map +1 -0
- package/dist/spawner-LoVsn55-.mjs +63 -0
- package/dist/spawner-LoVsn55-.mjs.map +1 -0
- package/dist/spawner.cjs +3 -0
- package/dist/spawner.d.mts +9 -0
- package/dist/spawner.d.mts.map +1 -0
- package/dist/spawner.mjs +2 -0
- package/dist/type-BXM03qSw.d.mts +44 -0
- package/dist/type-BXM03qSw.d.mts.map +1 -0
- package/dist/type-C31e1gla.d.mts +43 -0
- package/dist/type-C31e1gla.d.mts.map +1 -0
- package/dist/type-vWQNTahw.d.mts +12 -0
- package/dist/type-vWQNTahw.d.mts.map +1 -0
- package/dist/types.cjs +0 -0
- package/dist/types.d.mts +3 -0
- package/dist/types.mjs +1 -0
- package/llms.txt +9 -0
- package/package.json +303 -0
- package/skills/doom-runner/SKILL.md +78 -0
- package/src/prompts/po-use-runner/SKILL.md +47 -0
|
@@ -0,0 +1,445 @@
|
|
|
1
|
+
const require_rtkProcessor = require("./rtkProcessor-CsrCPyTQ.cjs");
|
|
2
|
+
const require_runnerConfig = require("./runnerConfig-D2tGq5ZM.cjs");
|
|
3
|
+
let node_crypto = require("node:crypto");
|
|
4
|
+
//#region src/constants/bashRunService.ts
|
|
5
|
+
const COMPLETED = "completed";
|
|
6
|
+
const FAILED = "failed";
|
|
7
|
+
const LAUNCHER_ERROR = "launcher_error";
|
|
8
|
+
//#endregion
|
|
9
|
+
//#region src/services/bashRunService/resources.ts
|
|
10
|
+
/** Split shell words without mistaking quoted examples for executed commands. */
|
|
11
|
+
function commandInvocations(command) {
|
|
12
|
+
const invocations = [];
|
|
13
|
+
let words = [];
|
|
14
|
+
let word = "";
|
|
15
|
+
let quote = "";
|
|
16
|
+
let escaped = false;
|
|
17
|
+
const flushWord = () => {
|
|
18
|
+
if (word) words.push(word);
|
|
19
|
+
word = "";
|
|
20
|
+
};
|
|
21
|
+
for (const character of command) if (escaped) {
|
|
22
|
+
word += character;
|
|
23
|
+
escaped = false;
|
|
24
|
+
} else if (character === "\\" && quote !== "'") escaped = true;
|
|
25
|
+
else if (quote) {
|
|
26
|
+
if (character === quote) quote = "";
|
|
27
|
+
else word += character;
|
|
28
|
+
} else if (character === "\"" || character === "'") quote = character;
|
|
29
|
+
else if (";&|\n".includes(character)) {
|
|
30
|
+
flushWord();
|
|
31
|
+
if (words.length) invocations.push(words);
|
|
32
|
+
words = [];
|
|
33
|
+
} else if (/\s/.test(character)) flushWord();
|
|
34
|
+
else word += character;
|
|
35
|
+
flushWord();
|
|
36
|
+
if (words.length) invocations.push(words);
|
|
37
|
+
return invocations;
|
|
38
|
+
}
|
|
39
|
+
function executableName(word) {
|
|
40
|
+
return word.replace(/\\/g, "/").split("/").pop() ?? word;
|
|
41
|
+
}
|
|
42
|
+
/** Admission policy, not a shell security boundary. Opaque scripts still need explicit ownership. */
|
|
43
|
+
function isHeavyCommand(command) {
|
|
44
|
+
const heavyTarget = /(?:^|[\s:,=])(?:build(?:-[\w-]+)?|test(?:-[\w-]+)?|lint|fixcode|typecheck|check|bundle)(?:[\s:,=]|$)/;
|
|
45
|
+
const expensiveBinary = /^(?:vitest|jest|tsc|tsgo|tsdown|webpack|rollup|esbuild|oxlint|oxfmt|pytest|maestro|xcodebuild|gradle|gradlew)$/;
|
|
46
|
+
return commandInvocations(command).some((words) => {
|
|
47
|
+
while (words.length) {
|
|
48
|
+
const first = words[0];
|
|
49
|
+
if (/^[A-Za-z_][A-Za-z_0-9]*=/.test(first) || /^(?:env|command|exec|time)$/.test(executableName(first))) words.shift();
|
|
50
|
+
else break;
|
|
51
|
+
}
|
|
52
|
+
let executable = executableName(words.shift() ?? "");
|
|
53
|
+
if (words.includes("--help") || words.includes("--version")) return false;
|
|
54
|
+
if (/^(?:pnpm|npm|npx|yarn|bun)$/.test(executable)) {
|
|
55
|
+
while (words[0]?.startsWith("-")) {
|
|
56
|
+
const option = words.shift();
|
|
57
|
+
if (/^(?:--filter|--dir|-C|--cwd|--prefix)$/.test(option)) words.shift();
|
|
58
|
+
}
|
|
59
|
+
if (words[0] === "exec" || words[0] === "run") words.shift();
|
|
60
|
+
const invocation = words.shift() ?? "";
|
|
61
|
+
if (/^(?:build|test|lint|fixcode|typecheck|check)(?::[\w-]+)?$/.test(invocation)) return true;
|
|
62
|
+
executable = executableName(invocation);
|
|
63
|
+
}
|
|
64
|
+
if (expensiveBinary.test(executable)) return true;
|
|
65
|
+
if (executable === "nx") {
|
|
66
|
+
if (/^(?:show|graph|daemon|reset|report|list)$/.test(words[0] ?? "")) return false;
|
|
67
|
+
return heavyTarget.test(words.join(" "));
|
|
68
|
+
}
|
|
69
|
+
if (/^(?:playwright|vite|cargo|go)$/.test(executable)) return heavyTarget.test(words.join(" "));
|
|
70
|
+
if (/^(?:python|python3)$/.test(executable)) return words[0] === "-m" && words[1] === "pytest";
|
|
71
|
+
if (/^(?:node|bun|tsx)$/.test(executable)) executable = executableName(words.find((word) => !word.startsWith("-")) ?? "");
|
|
72
|
+
const script = executable.replace(/\.(?:[cm]?[jt]s)$/, "");
|
|
73
|
+
return script !== executable && (expensiveBinary.test(script) || /^(?:build|test|lint|fixcode|typecheck|dev)(?:[-:]|$)/.test(script));
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
//#endregion
|
|
77
|
+
//#region src/services/bashRunService/index.ts
|
|
78
|
+
/** The command outlived the background threshold and should be promoted. */
|
|
79
|
+
const TIMED_OUT = Symbol("threshold-reached");
|
|
80
|
+
/** The command outlived the caller's explicit timeout and should be stopped. */
|
|
81
|
+
const DEADLINE = Symbol("deadline-reached");
|
|
82
|
+
/** The caller cancelled the command and its owned runner should be stopped. */
|
|
83
|
+
const ABORTED = Symbol("aborted");
|
|
84
|
+
function runnerId() {
|
|
85
|
+
return `${Date.now().toString(36)}-${(0, node_crypto.randomBytes)(3).toString("base64url")}`;
|
|
86
|
+
}
|
|
87
|
+
var BashRunService = class {
|
|
88
|
+
launcher;
|
|
89
|
+
rmuxBackend;
|
|
90
|
+
namer;
|
|
91
|
+
registry;
|
|
92
|
+
clock;
|
|
93
|
+
rtkProcessor;
|
|
94
|
+
cwd;
|
|
95
|
+
env;
|
|
96
|
+
executionBudget;
|
|
97
|
+
constructor(launcher, rmuxBackend, namer, registry, clock, rtkProcessor, cwd = process.cwd(), env = process.env, executionBudget) {
|
|
98
|
+
this.launcher = launcher;
|
|
99
|
+
this.rmuxBackend = rmuxBackend;
|
|
100
|
+
this.namer = namer;
|
|
101
|
+
this.registry = registry;
|
|
102
|
+
this.clock = clock;
|
|
103
|
+
this.rtkProcessor = rtkProcessor;
|
|
104
|
+
this.cwd = cwd;
|
|
105
|
+
this.env = env;
|
|
106
|
+
this.executionBudget = executionBudget;
|
|
107
|
+
}
|
|
108
|
+
async run(request) {
|
|
109
|
+
const id = runnerId();
|
|
110
|
+
const name = await this.namer.allocate(request.command, request.sessionId, request.name);
|
|
111
|
+
const cwd = request.cwd ?? this.cwd;
|
|
112
|
+
const interactive = request.interactive === true;
|
|
113
|
+
if (request.signal?.aborted) return {
|
|
114
|
+
kind: FAILED,
|
|
115
|
+
id,
|
|
116
|
+
name,
|
|
117
|
+
error: "Operation aborted"
|
|
118
|
+
};
|
|
119
|
+
let handle;
|
|
120
|
+
let releaseSlot;
|
|
121
|
+
try {
|
|
122
|
+
if (this.executionBudget && isHeavyCommand(request.command)) releaseSlot = await this.executionBudget.acquire(request.signal);
|
|
123
|
+
request.signal?.throwIfAborted();
|
|
124
|
+
const rmuxHandle = await this.rmuxBackend.launch({
|
|
125
|
+
id,
|
|
126
|
+
name,
|
|
127
|
+
command: request.command,
|
|
128
|
+
cwd,
|
|
129
|
+
sessionId: request.sessionId,
|
|
130
|
+
interactive
|
|
131
|
+
});
|
|
132
|
+
if (interactive && !rmuxHandle) {
|
|
133
|
+
releaseSlot?.();
|
|
134
|
+
return {
|
|
135
|
+
kind: FAILED,
|
|
136
|
+
id,
|
|
137
|
+
name,
|
|
138
|
+
error: "RMUX is required for interactive commands but is unavailable"
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
handle = rmuxHandle ?? this.launcher.launch({
|
|
142
|
+
id,
|
|
143
|
+
name,
|
|
144
|
+
command: request.command,
|
|
145
|
+
cwd,
|
|
146
|
+
sessionId: request.sessionId
|
|
147
|
+
});
|
|
148
|
+
} catch (error) {
|
|
149
|
+
releaseSlot?.();
|
|
150
|
+
return {
|
|
151
|
+
kind: FAILED,
|
|
152
|
+
id,
|
|
153
|
+
name,
|
|
154
|
+
error: error instanceof Error ? error.message : String(error)
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
if (handle.pid === void 0) {
|
|
158
|
+
releaseSlot?.();
|
|
159
|
+
return {
|
|
160
|
+
kind: FAILED,
|
|
161
|
+
id,
|
|
162
|
+
name,
|
|
163
|
+
error: "The command did not start, so it cannot be supervised"
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
if (releaseSlot) handle.completion().then(releaseSlot, releaseSlot);
|
|
167
|
+
try {
|
|
168
|
+
await this.registry.register({
|
|
169
|
+
id,
|
|
170
|
+
name,
|
|
171
|
+
pid: handle.pid,
|
|
172
|
+
command: request.command,
|
|
173
|
+
cwd,
|
|
174
|
+
logPath: handle.logPath,
|
|
175
|
+
interactive,
|
|
176
|
+
sessionId: request.sessionId,
|
|
177
|
+
backend: handle.backend,
|
|
178
|
+
...handle.backendTarget ? { backendTarget: handle.backendTarget } : {}
|
|
179
|
+
});
|
|
180
|
+
} catch (error) {
|
|
181
|
+
await handle.stop();
|
|
182
|
+
return {
|
|
183
|
+
kind: FAILED,
|
|
184
|
+
id,
|
|
185
|
+
name,
|
|
186
|
+
error: error instanceof Error ? error.message : String(error)
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
if (releaseSlot) try {
|
|
190
|
+
await releaseSlot.attachProcess?.(handle.pid);
|
|
191
|
+
} catch (error) {
|
|
192
|
+
if (!await handle.stop()) return this.promote(handle, "requested", void 0);
|
|
193
|
+
await this.registry.complete(id, {
|
|
194
|
+
reason: "stopped",
|
|
195
|
+
code: null,
|
|
196
|
+
signal: "SIGTERM"
|
|
197
|
+
});
|
|
198
|
+
return {
|
|
199
|
+
kind: FAILED,
|
|
200
|
+
id,
|
|
201
|
+
name,
|
|
202
|
+
error: error instanceof Error ? error.message : String(error)
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
if (request.signal?.aborted) {
|
|
206
|
+
if (!await handle.stop()) return this.promote(handle, "requested", void 0);
|
|
207
|
+
await this.registry.complete(id, {
|
|
208
|
+
reason: "stopped",
|
|
209
|
+
code: null,
|
|
210
|
+
signal: "SIGTERM"
|
|
211
|
+
});
|
|
212
|
+
return {
|
|
213
|
+
kind: FAILED,
|
|
214
|
+
id,
|
|
215
|
+
name,
|
|
216
|
+
error: "Operation aborted"
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
if (request.background === true || interactive) return this.promote(handle, request.background === true ? "requested" : "interactive", request.signal);
|
|
220
|
+
const outputUpdates = request.onOutput ? this.followOutput(handle, request.onOutput) : void 0;
|
|
221
|
+
try {
|
|
222
|
+
const outcome = await this.race(handle, request.timeoutMs, request.signal);
|
|
223
|
+
outputUpdates?.flush();
|
|
224
|
+
if (outcome === TIMED_OUT) return this.promote(handle, "threshold", request.signal);
|
|
225
|
+
if (outcome === ABORTED) {
|
|
226
|
+
await this.registry.requestTermination(id, {
|
|
227
|
+
reason: "stopped",
|
|
228
|
+
terminationReason: "request_cancelled"
|
|
229
|
+
});
|
|
230
|
+
await handle.stop();
|
|
231
|
+
outputUpdates?.flush();
|
|
232
|
+
await this.registry.complete(id, {
|
|
233
|
+
reason: "stopped",
|
|
234
|
+
code: null,
|
|
235
|
+
signal: "SIGTERM"
|
|
236
|
+
});
|
|
237
|
+
return {
|
|
238
|
+
kind: COMPLETED,
|
|
239
|
+
id,
|
|
240
|
+
name,
|
|
241
|
+
output: handle.output(),
|
|
242
|
+
exitCode: null,
|
|
243
|
+
signal: "SIGTERM",
|
|
244
|
+
logPath: handle.logPath,
|
|
245
|
+
backend: handle.backend,
|
|
246
|
+
aborted: true
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
if (outcome === DEADLINE) {
|
|
250
|
+
await this.registry.requestTermination(id, {
|
|
251
|
+
reason: "timed_out",
|
|
252
|
+
terminationReason: "timeout"
|
|
253
|
+
});
|
|
254
|
+
await handle.stop();
|
|
255
|
+
outputUpdates?.flush();
|
|
256
|
+
await this.registry.complete(id, {
|
|
257
|
+
reason: "timed_out",
|
|
258
|
+
code: null,
|
|
259
|
+
signal: "SIGTERM"
|
|
260
|
+
});
|
|
261
|
+
return {
|
|
262
|
+
kind: COMPLETED,
|
|
263
|
+
id,
|
|
264
|
+
name,
|
|
265
|
+
output: handle.output(),
|
|
266
|
+
exitCode: null,
|
|
267
|
+
signal: "SIGTERM",
|
|
268
|
+
logPath: handle.logPath,
|
|
269
|
+
backend: handle.backend,
|
|
270
|
+
timedOut: true
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
if (outcome instanceof Error) {
|
|
274
|
+
await this.registry.complete(id, {
|
|
275
|
+
reason: LAUNCHER_ERROR,
|
|
276
|
+
code: null,
|
|
277
|
+
signal: null
|
|
278
|
+
});
|
|
279
|
+
return {
|
|
280
|
+
kind: FAILED,
|
|
281
|
+
id,
|
|
282
|
+
name,
|
|
283
|
+
error: outcome.message
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
await this.registry.complete(id, {
|
|
287
|
+
reason: outcome.reason ?? (outcome.signal ? "signaled" : outcome.code === 0 ? "completed" : "failed"),
|
|
288
|
+
code: outcome.code,
|
|
289
|
+
signal: outcome.signal,
|
|
290
|
+
...outcome.terminationReason ? { terminationReason: outcome.terminationReason } : {},
|
|
291
|
+
...outcome.stopReason ? { stopReason: outcome.stopReason } : {}
|
|
292
|
+
});
|
|
293
|
+
return {
|
|
294
|
+
kind: COMPLETED,
|
|
295
|
+
id,
|
|
296
|
+
name,
|
|
297
|
+
output: handle.output(),
|
|
298
|
+
exitCode: outcome.code,
|
|
299
|
+
signal: outcome.signal,
|
|
300
|
+
logPath: handle.logPath,
|
|
301
|
+
backend: handle.backend,
|
|
302
|
+
...await this.processLog(request.command, handle.logPath)
|
|
303
|
+
};
|
|
304
|
+
} finally {
|
|
305
|
+
outputUpdates?.dispose();
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
async processLog(command, logPath) {
|
|
309
|
+
try {
|
|
310
|
+
const result = await this.rtkProcessor.process({
|
|
311
|
+
command,
|
|
312
|
+
logPath
|
|
313
|
+
});
|
|
314
|
+
if (result.kind === "processed") return { rtkOutput: result.result };
|
|
315
|
+
if (result.kind === "fallback") return { rtkWarning: result.warning };
|
|
316
|
+
return {};
|
|
317
|
+
} catch {
|
|
318
|
+
return { rtkWarning: require_rtkProcessor.RTK_FAILED_WARNING };
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
followOutput(handle, onOutput) {
|
|
322
|
+
let active = true;
|
|
323
|
+
let previous = "";
|
|
324
|
+
let cancelPoll;
|
|
325
|
+
const flush = () => {
|
|
326
|
+
if (!active) return;
|
|
327
|
+
const output = handle.output();
|
|
328
|
+
if (output === previous) return;
|
|
329
|
+
previous = output;
|
|
330
|
+
onOutput(output);
|
|
331
|
+
};
|
|
332
|
+
const poll = () => {
|
|
333
|
+
if (!active) return;
|
|
334
|
+
flush();
|
|
335
|
+
if (active) cancelPoll = this.clock.after(100, poll);
|
|
336
|
+
};
|
|
337
|
+
cancelPoll = this.clock.after(100, poll);
|
|
338
|
+
return {
|
|
339
|
+
flush,
|
|
340
|
+
dispose: () => {
|
|
341
|
+
active = false;
|
|
342
|
+
cancelPoll?.();
|
|
343
|
+
cancelPoll = void 0;
|
|
344
|
+
}
|
|
345
|
+
};
|
|
346
|
+
}
|
|
347
|
+
/**
|
|
348
|
+
* Waits for the command, giving up at the background threshold or at the
|
|
349
|
+
* caller's timeout, whichever comes first.
|
|
350
|
+
*
|
|
351
|
+
* A rejected completion is returned rather than thrown so the caller can
|
|
352
|
+
* report a start failure as a tool result instead of an exception.
|
|
353
|
+
*/
|
|
354
|
+
async race(handle, timeoutMs, signal) {
|
|
355
|
+
const cancels = [];
|
|
356
|
+
const racers = [handle.completion().catch((error) => error)];
|
|
357
|
+
racers.push(new Promise((resolve) => {
|
|
358
|
+
cancels.push(this.clock.after(require_runnerConfig.getBackgroundThresholdMs(this.env), () => resolve(TIMED_OUT)));
|
|
359
|
+
}));
|
|
360
|
+
if (timeoutMs !== void 0 && timeoutMs > 0) racers.push(new Promise((resolve) => {
|
|
361
|
+
cancels.push(this.clock.after(timeoutMs, () => resolve(DEADLINE)));
|
|
362
|
+
}));
|
|
363
|
+
if (signal) racers.push(new Promise((resolve) => {
|
|
364
|
+
if (signal.aborted) {
|
|
365
|
+
resolve(ABORTED);
|
|
366
|
+
return;
|
|
367
|
+
}
|
|
368
|
+
const abort = () => resolve(ABORTED);
|
|
369
|
+
signal.addEventListener("abort", abort, { once: true });
|
|
370
|
+
cancels.push(() => signal.removeEventListener("abort", abort));
|
|
371
|
+
}));
|
|
372
|
+
try {
|
|
373
|
+
return await Promise.race(racers);
|
|
374
|
+
} finally {
|
|
375
|
+
for (const cancel of cancels) cancel();
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
async promote(handle, reason, signal) {
|
|
379
|
+
if (handle.pid === void 0) return {
|
|
380
|
+
kind: FAILED,
|
|
381
|
+
id: handle.id,
|
|
382
|
+
name: handle.name,
|
|
383
|
+
error: "The command did not start"
|
|
384
|
+
};
|
|
385
|
+
await this.registry.markPromoted(handle.id);
|
|
386
|
+
handle.detach();
|
|
387
|
+
let abortStop;
|
|
388
|
+
const abort = () => {
|
|
389
|
+
abortStop = this.registry.requestTermination(handle.id, {
|
|
390
|
+
reason: "stopped",
|
|
391
|
+
terminationReason: "request_cancelled"
|
|
392
|
+
}).then(() => handle.stop()).then(async () => {
|
|
393
|
+
await this.registry.complete(handle.id, {
|
|
394
|
+
reason: "stopped",
|
|
395
|
+
code: null,
|
|
396
|
+
signal: "SIGTERM"
|
|
397
|
+
});
|
|
398
|
+
return true;
|
|
399
|
+
}).catch((error) => {
|
|
400
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
401
|
+
process.emitWarning(`Failed to stop aborted runner ${handle.id}: ${message}`);
|
|
402
|
+
return false;
|
|
403
|
+
});
|
|
404
|
+
};
|
|
405
|
+
if (signal?.aborted) abort();
|
|
406
|
+
handle.completion().then(async (outcome) => {
|
|
407
|
+
if (await abortStop) return;
|
|
408
|
+
await this.registry.complete(handle.id, {
|
|
409
|
+
reason: outcome.reason ?? (outcome.signal ? "signaled" : outcome.code === 0 ? "completed" : "failed"),
|
|
410
|
+
code: outcome.code,
|
|
411
|
+
signal: outcome.signal,
|
|
412
|
+
...outcome.terminationReason ? { terminationReason: outcome.terminationReason } : {},
|
|
413
|
+
...outcome.stopReason ? { stopReason: outcome.stopReason } : {}
|
|
414
|
+
});
|
|
415
|
+
}, async () => {
|
|
416
|
+
if (await abortStop) return;
|
|
417
|
+
await this.registry.complete(handle.id, {
|
|
418
|
+
reason: LAUNCHER_ERROR,
|
|
419
|
+
code: null,
|
|
420
|
+
signal: null
|
|
421
|
+
});
|
|
422
|
+
}).catch((error) => {
|
|
423
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
424
|
+
process.emitWarning(`Failed to complete runner ${handle.id}: ${message}`);
|
|
425
|
+
});
|
|
426
|
+
return {
|
|
427
|
+
kind: "promoted",
|
|
428
|
+
id: handle.id,
|
|
429
|
+
name: handle.name,
|
|
430
|
+
pid: handle.pid,
|
|
431
|
+
logPath: handle.logPath,
|
|
432
|
+
backend: handle.backend,
|
|
433
|
+
reason
|
|
434
|
+
};
|
|
435
|
+
}
|
|
436
|
+
};
|
|
437
|
+
//#endregion
|
|
438
|
+
Object.defineProperty(exports, "BashRunService", {
|
|
439
|
+
enumerable: true,
|
|
440
|
+
get: function() {
|
|
441
|
+
return BashRunService;
|
|
442
|
+
}
|
|
443
|
+
});
|
|
444
|
+
|
|
445
|
+
//# sourceMappingURL=bashRunService-DyqxOSlx.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bashRunService-DyqxOSlx.cjs","names":["randomBytes","RTK_FAILED_WARNING","getBackgroundThresholdMs"],"sources":["../src/constants/bashRunService.ts","../src/services/bashRunService/resources.ts","../src/services/bashRunService/index.ts"],"sourcesContent":["export const RUNNER_ID_RANDOM_BYTES = 3;\nexport const OUTPUT_UPDATE_POLL_MS = 100;\nexport const COMPLETED = 'completed';\nexport const FAILED = 'failed';\nexport const LAUNCHER_ERROR = 'launcher_error';\nexport const SIGNALED = 'signaled';\n","/** Split shell words without mistaking quoted examples for executed commands. */\nfunction commandInvocations(command: string): string[][] {\n const invocations: string[][] = [];\n let words: string[] = [];\n let word = '';\n let quote = '';\n let escaped = false;\n const flushWord = (): void => {\n if (word) words.push(word);\n word = '';\n };\n for (const character of command) {\n if (escaped) {\n word += character;\n escaped = false;\n } else if (character === '\\\\' && quote !== \"'\") {\n escaped = true;\n } else if (quote) {\n if (character === quote) quote = '';\n else word += character;\n } else if (character === '\"' || character === \"'\") {\n quote = character;\n } else if (';&|\\n'.includes(character)) {\n flushWord();\n if (words.length) invocations.push(words);\n words = [];\n } else if (/\\s/.test(character)) {\n flushWord();\n } else {\n word += character;\n }\n }\n flushWord();\n if (words.length) invocations.push(words);\n return invocations;\n}\n\nfunction executableName(word: string): string {\n return word.replace(/\\\\/g, '/').split('/').pop() ?? word;\n}\n\n/** Admission policy, not a shell security boundary. Opaque scripts still need explicit ownership. */\nexport function isHeavyCommand(command: string): boolean {\n const heavyTarget =\n /(?:^|[\\s:,=])(?:build(?:-[\\w-]+)?|test(?:-[\\w-]+)?|lint|fixcode|typecheck|check|bundle)(?:[\\s:,=]|$)/;\n const expensiveBinary =\n /^(?:vitest|jest|tsc|tsgo|tsdown|webpack|rollup|esbuild|oxlint|oxfmt|pytest|maestro|xcodebuild|gradle|gradlew)$/;\n return commandInvocations(command).some((words) => {\n while (words.length) {\n const first = words[0]!;\n if (/^[A-Za-z_][A-Za-z_0-9]*=/.test(first) || /^(?:env|command|exec|time)$/.test(executableName(first))) {\n words.shift();\n } else break;\n }\n let executable = executableName(words.shift() ?? '');\n if (words.includes('--help') || words.includes('--version')) return false;\n if (/^(?:pnpm|npm|npx|yarn|bun)$/.test(executable)) {\n while (words[0]?.startsWith('-')) {\n const option = words.shift()!;\n if (/^(?:--filter|--dir|-C|--cwd|--prefix)$/.test(option)) words.shift();\n }\n if (words[0] === 'exec' || words[0] === 'run') words.shift();\n const invocation = words.shift() ?? '';\n if (/^(?:build|test|lint|fixcode|typecheck|check)(?::[\\w-]+)?$/.test(invocation)) return true;\n executable = executableName(invocation);\n }\n if (expensiveBinary.test(executable)) return true;\n if (executable === 'nx') {\n if (/^(?:show|graph|daemon|reset|report|list)$/.test(words[0] ?? '')) return false;\n return heavyTarget.test(words.join(' '));\n }\n if (/^(?:playwright|vite|cargo|go)$/.test(executable)) return heavyTarget.test(words.join(' '));\n if (/^(?:python|python3)$/.test(executable)) return words[0] === '-m' && words[1] === 'pytest';\n if (/^(?:node|bun|tsx)$/.test(executable)) {\n executable = executableName(words.find((word) => !word.startsWith('-')) ?? '');\n }\n const script = executable.replace(/\\.(?:[cm]?[jt]s)$/, '');\n return (\n script !== executable &&\n (expensiveBinary.test(script) || /^(?:build|test|lint|fixcode|typecheck|dev)(?:[-:]|$)/.test(script))\n );\n });\n}\n","import { randomBytes } from 'node:crypto';\n\nimport type { DoomHostExecutionBudget, DoomHostExecutionPermit } from '@agimon-ai/po-core/packageApi';\n\nimport {\n COMPLETED,\n FAILED,\n LAUNCHER_ERROR,\n OUTPUT_UPDATE_POLL_MS,\n RUNNER_ID_RANDOM_BYTES,\n SIGNALED,\n} from '../../constants/bashRunService';\nimport type {\n BashRunRequest,\n BashRunResult,\n CompletedRun,\n IBashRunService,\n PromotedRun,\n} from '../../types/bashRunService';\nimport type { IClock } from '../../types/clock';\nimport type { ILauncher, RunHandle } from '../../types/launcher';\nimport type { IRmuxBackend } from '../../types/rmuxBackend';\nimport { type IRtkProcessor, RTK_FAILED_WARNING } from '../../types/rtkProcessor';\nimport type { IRunnerRegistry } from '../../types/runnerRegistry';\nimport { getBackgroundThresholdMs } from '../runnerConfig';\nimport type { IRunnerNamer } from '../runnerNamer/type';\nimport { isHeavyCommand } from './resources';\n\n/** The command outlived the background threshold and should be promoted. */\nconst TIMED_OUT = Symbol('threshold-reached');\n/** The command outlived the caller's explicit timeout and should be stopped. */\nconst DEADLINE = Symbol('deadline-reached');\n/** The caller cancelled the command and its owned runner should be stopped. */\nconst ABORTED = Symbol('aborted');\n\nfunction runnerId(): string {\n const timestamp = Date.now().toString(36);\n const random = randomBytes(RUNNER_ID_RANDOM_BYTES).toString('base64url');\n return `${timestamp}-${random}`;\n}\n\nexport class BashRunService implements IBashRunService {\n constructor(\n private readonly launcher: ILauncher,\n private readonly rmuxBackend: IRmuxBackend,\n private readonly namer: IRunnerNamer,\n private readonly registry: IRunnerRegistry,\n private readonly clock: IClock,\n private readonly rtkProcessor: IRtkProcessor,\n private readonly cwd: string = process.cwd(),\n private readonly env: Readonly<Record<string, string | undefined>> = process.env,\n private readonly executionBudget?: DoomHostExecutionBudget,\n ) {}\n\n async run(request: BashRunRequest): Promise<BashRunResult> {\n const id = runnerId();\n const name = await this.namer.allocate(request.command, request.sessionId, request.name);\n const cwd = request.cwd ?? this.cwd;\n const interactive = request.interactive === true;\n if (request.signal?.aborted) return { kind: FAILED, id, name, error: 'Operation aborted' };\n\n let handle: RunHandle;\n let releaseSlot: DoomHostExecutionPermit | undefined;\n try {\n if (this.executionBudget && isHeavyCommand(request.command)) {\n releaseSlot = await this.executionBudget.acquire(request.signal);\n }\n request.signal?.throwIfAborted();\n const rmuxHandle = await this.rmuxBackend.launch({\n id,\n name,\n command: request.command,\n cwd,\n sessionId: request.sessionId,\n interactive,\n });\n if (interactive && !rmuxHandle) {\n releaseSlot?.();\n return { kind: FAILED, id, name, error: 'RMUX is required for interactive commands but is unavailable' };\n }\n handle =\n rmuxHandle ?? this.launcher.launch({ id, name, command: request.command, cwd, sessionId: request.sessionId });\n } catch (error) {\n releaseSlot?.();\n return { kind: FAILED, id, name, error: error instanceof Error ? error.message : String(error) };\n }\n\n if (handle.pid === undefined) {\n releaseSlot?.();\n return { kind: FAILED, id, name, error: 'The command did not start, so it cannot be supervised' };\n }\n // A background promotion is not process completion. Keep the slot until actual exit.\n if (releaseSlot) void handle.completion().then(releaseSlot, releaseSlot);\n // Register first so a process that survives PID attachment failure remains discoverable.\n try {\n await this.registry.register({\n id,\n name,\n pid: handle.pid,\n command: request.command,\n cwd,\n logPath: handle.logPath,\n interactive,\n sessionId: request.sessionId,\n backend: handle.backend,\n ...(handle.backendTarget ? { backendTarget: handle.backendTarget } : {}),\n });\n } catch (error) {\n await handle.stop();\n return { kind: FAILED, id, name, error: error instanceof Error ? error.message : String(error) };\n }\n\n if (releaseSlot) {\n try {\n await releaseSlot.attachProcess?.(handle.pid);\n } catch (error) {\n if (!(await handle.stop())) {\n return this.promote(handle, 'requested', undefined);\n }\n await this.registry.complete(id, { reason: 'stopped', code: null, signal: 'SIGTERM' });\n return { kind: FAILED, id, name, error: error instanceof Error ? error.message : String(error) };\n }\n }\n if (request.signal?.aborted) {\n if (!(await handle.stop())) return this.promote(handle, 'requested', undefined);\n await this.registry.complete(id, { reason: 'stopped', code: null, signal: 'SIGTERM' });\n return { kind: FAILED, id, name, error: 'Operation aborted' };\n }\n\n // An interactive run has nothing to wait for: it is going to prompt, so\n // the model needs the runner name before it can answer.\n if (request.background === true || interactive) {\n return this.promote(handle, request.background === true ? 'requested' : 'interactive', request.signal);\n }\n\n const outputUpdates = request.onOutput ? this.followOutput(handle, request.onOutput) : undefined;\n try {\n const outcome = await this.race(handle, request.timeoutMs, request.signal);\n outputUpdates?.flush();\n if (outcome === TIMED_OUT) {\n return this.promote(handle, 'threshold', request.signal);\n }\n if (outcome === ABORTED) {\n await this.registry.requestTermination(id, { reason: 'stopped', terminationReason: 'request_cancelled' });\n await handle.stop();\n outputUpdates?.flush();\n await this.registry.complete(id, { reason: 'stopped', code: null, signal: 'SIGTERM' });\n return {\n kind: COMPLETED,\n id,\n name,\n output: handle.output(),\n exitCode: null,\n signal: 'SIGTERM',\n logPath: handle.logPath,\n backend: handle.backend,\n aborted: true,\n };\n }\n if (outcome === DEADLINE) {\n // An explicit timeout means the caller wants the command dead, not\n // supervised, so it is stopped rather than promoted.\n await this.registry.requestTermination(id, { reason: 'timed_out', terminationReason: 'timeout' });\n await handle.stop();\n outputUpdates?.flush();\n await this.registry.complete(id, { reason: 'timed_out', code: null, signal: 'SIGTERM' });\n return {\n kind: COMPLETED,\n id,\n name,\n output: handle.output(),\n exitCode: null,\n signal: 'SIGTERM',\n logPath: handle.logPath,\n backend: handle.backend,\n timedOut: true,\n };\n }\n if (outcome instanceof Error) {\n await this.registry.complete(id, { reason: LAUNCHER_ERROR, code: null, signal: null });\n return { kind: FAILED, id, name, error: outcome.message };\n }\n\n await this.registry.complete(id, {\n reason: outcome.reason ?? (outcome.signal ? SIGNALED : outcome.code === 0 ? COMPLETED : FAILED),\n code: outcome.code,\n signal: outcome.signal,\n ...(outcome.terminationReason ? { terminationReason: outcome.terminationReason } : {}),\n ...(outcome.stopReason ? { stopReason: outcome.stopReason } : {}),\n });\n\n return {\n kind: COMPLETED,\n id,\n name,\n output: handle.output(),\n exitCode: outcome.code,\n signal: outcome.signal,\n logPath: handle.logPath,\n backend: handle.backend,\n ...(await this.processLog(request.command, handle.logPath)),\n };\n } finally {\n outputUpdates?.dispose();\n }\n }\n\n private async processLog(command: string, logPath: string): Promise<Pick<CompletedRun, 'rtkOutput' | 'rtkWarning'>> {\n try {\n const result = await this.rtkProcessor.process({ command, logPath });\n if (result.kind === 'processed') return { rtkOutput: result.result };\n if (result.kind === 'fallback') return { rtkWarning: result.warning };\n return {};\n } catch {\n return { rtkWarning: RTK_FAILED_WARNING };\n }\n }\n\n private followOutput(\n handle: RunHandle,\n onOutput: NonNullable<BashRunRequest['onOutput']>,\n ): { flush(): void; dispose(): void } {\n let active = true;\n let previous = '';\n let cancelPoll: (() => void) | undefined;\n const flush = (): void => {\n if (!active) return;\n const output = handle.output();\n if (output === previous) return;\n previous = output;\n onOutput(output);\n };\n const poll = (): void => {\n if (!active) return;\n flush();\n if (active) cancelPoll = this.clock.after(OUTPUT_UPDATE_POLL_MS, poll);\n };\n cancelPoll = this.clock.after(OUTPUT_UPDATE_POLL_MS, poll);\n return {\n flush,\n dispose: () => {\n active = false;\n cancelPoll?.();\n cancelPoll = undefined;\n },\n };\n }\n\n /**\n * Waits for the command, giving up at the background threshold or at the\n * caller's timeout, whichever comes first.\n *\n * A rejected completion is returned rather than thrown so the caller can\n * report a start failure as a tool result instead of an exception.\n */\n private async race(\n handle: RunHandle,\n timeoutMs: number | undefined,\n signal: AbortSignal | undefined,\n ): Promise<\n Awaited<ReturnType<RunHandle['completion']>> | Error | typeof TIMED_OUT | typeof DEADLINE | typeof ABORTED\n > {\n const cancels: Array<() => void> = [];\n const racers: Array<Promise<unknown>> = [handle.completion().catch((error: Error) => error)];\n\n racers.push(\n new Promise((resolve) => {\n cancels.push(this.clock.after(getBackgroundThresholdMs(this.env), () => resolve(TIMED_OUT)));\n }),\n );\n if (timeoutMs !== undefined && timeoutMs > 0) {\n racers.push(\n new Promise((resolve) => {\n cancels.push(this.clock.after(timeoutMs, () => resolve(DEADLINE)));\n }),\n );\n }\n if (signal) {\n racers.push(\n new Promise((resolve) => {\n if (signal.aborted) {\n resolve(ABORTED);\n return;\n }\n const abort = (): void => resolve(ABORTED);\n signal.addEventListener('abort', abort, { once: true });\n cancels.push(() => signal.removeEventListener('abort', abort));\n }),\n );\n }\n\n try {\n return (await Promise.race(racers)) as\n | Awaited<ReturnType<RunHandle['completion']>>\n | Error\n | typeof TIMED_OUT\n | typeof DEADLINE\n | typeof ABORTED;\n } finally {\n for (const cancel of cancels) cancel();\n }\n }\n\n private async promote(\n handle: RunHandle,\n reason: PromotedRun['reason'],\n signal: AbortSignal | undefined,\n ): Promise<BashRunResult> {\n if (handle.pid === undefined)\n return { kind: FAILED, id: handle.id, name: handle.name, error: 'The command did not start' };\n await this.registry.markPromoted(handle.id);\n // Registration first: an unregistered runner is invisible, and the handle\n // stops buffering the moment it is detached.\n handle.detach();\n let abortStop: Promise<boolean> | undefined;\n const abort = (): void => {\n abortStop = this.registry\n .requestTermination(handle.id, { reason: 'stopped', terminationReason: 'request_cancelled' })\n .then(() => handle.stop())\n .then(async () => {\n await this.registry.complete(handle.id, { reason: 'stopped', code: null, signal: 'SIGTERM' });\n return true;\n })\n .catch((error: unknown) => {\n const message = error instanceof Error ? error.message : String(error);\n process.emitWarning(`Failed to stop aborted runner ${handle.id}: ${message}`);\n return false;\n });\n };\n // The signal belongs to the tool call, which ends when this returns, and\n // Pi aborts it at that point. A promoted runner outlives the call, so only\n // an abort that landed before the handoff stops it.\n if (signal?.aborted) abort();\n void handle\n .completion()\n .then(\n async (outcome) => {\n if (await abortStop) return;\n await this.registry.complete(handle.id, {\n reason: outcome.reason ?? (outcome.signal ? SIGNALED : outcome.code === 0 ? COMPLETED : FAILED),\n code: outcome.code,\n signal: outcome.signal,\n ...(outcome.terminationReason ? { terminationReason: outcome.terminationReason } : {}),\n ...(outcome.stopReason ? { stopReason: outcome.stopReason } : {}),\n });\n },\n async () => {\n if (await abortStop) return;\n await this.registry.complete(handle.id, { reason: LAUNCHER_ERROR, code: null, signal: null });\n },\n )\n .catch((error: unknown) => {\n const message = error instanceof Error ? error.message : String(error);\n process.emitWarning(`Failed to complete runner ${handle.id}: ${message}`);\n });\n\n return {\n kind: 'promoted',\n id: handle.id,\n name: handle.name,\n pid: handle.pid,\n logPath: handle.logPath,\n backend: handle.backend,\n reason,\n };\n }\n}\n"],"mappings":";;;;AAEA,MAAa,YAAY;AACzB,MAAa,SAAS;AACtB,MAAa,iBAAiB;;;;ACH9B,SAAS,mBAAmB,SAA6B;CACvD,MAAM,cAA0B,CAAC;CACjC,IAAI,QAAkB,CAAC;CACvB,IAAI,OAAO;CACX,IAAI,QAAQ;CACZ,IAAI,UAAU;CACd,MAAM,kBAAwB;EAC5B,IAAI,MAAM,MAAM,KAAK,IAAI;EACzB,OAAO;CACT;CACA,KAAK,MAAM,aAAa,SACtB,IAAI,SAAS;EACX,QAAQ;EACR,UAAU;CACZ,OAAO,IAAI,cAAc,QAAQ,UAAU,KACzC,UAAU;MACL,IAAI,OAAO;EAChB,IAAI,cAAc,OAAO,QAAQ;OAC5B,QAAQ;CACf,OAAO,IAAI,cAAc,QAAO,cAAc,KAC5C,QAAQ;MACH,IAAI,QAAQ,SAAS,SAAS,GAAG;EACtC,UAAU;EACV,IAAI,MAAM,QAAQ,YAAY,KAAK,KAAK;EACxC,QAAQ,CAAC;CACX,OAAO,IAAI,KAAK,KAAK,SAAS,GAC5B,UAAU;MAEV,QAAQ;CAGZ,UAAU;CACV,IAAI,MAAM,QAAQ,YAAY,KAAK,KAAK;CACxC,OAAO;AACT;AAEA,SAAS,eAAe,MAAsB;CAC5C,OAAO,KAAK,QAAQ,OAAO,GAAG,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,KAAK;AACtD;;AAGA,SAAgB,eAAe,SAA0B;CACvD,MAAM,cACJ;CACF,MAAM,kBACJ;CACF,OAAO,mBAAmB,OAAO,CAAC,CAAC,MAAM,UAAU;EACjD,OAAO,MAAM,QAAQ;GACnB,MAAM,QAAQ,MAAM;GACpB,IAAI,2BAA2B,KAAK,KAAK,KAAK,8BAA8B,KAAK,eAAe,KAAK,CAAC,GACpG,MAAM,MAAM;QACP;EACT;EACA,IAAI,aAAa,eAAe,MAAM,MAAM,KAAK,EAAE;EACnD,IAAI,MAAM,SAAS,QAAQ,KAAK,MAAM,SAAS,WAAW,GAAG,OAAO;EACpE,IAAI,8BAA8B,KAAK,UAAU,GAAG;GAClD,OAAO,MAAM,EAAE,EAAE,WAAW,GAAG,GAAG;IAChC,MAAM,SAAS,MAAM,MAAM;IAC3B,IAAI,yCAAyC,KAAK,MAAM,GAAG,MAAM,MAAM;GACzE;GACA,IAAI,MAAM,OAAO,UAAU,MAAM,OAAO,OAAO,MAAM,MAAM;GAC3D,MAAM,aAAa,MAAM,MAAM,KAAK;GACpC,IAAI,4DAA4D,KAAK,UAAU,GAAG,OAAO;GACzF,aAAa,eAAe,UAAU;EACxC;EACA,IAAI,gBAAgB,KAAK,UAAU,GAAG,OAAO;EAC7C,IAAI,eAAe,MAAM;GACvB,IAAI,4CAA4C,KAAK,MAAM,MAAM,EAAE,GAAG,OAAO;GAC7E,OAAO,YAAY,KAAK,MAAM,KAAK,GAAG,CAAC;EACzC;EACA,IAAI,iCAAiC,KAAK,UAAU,GAAG,OAAO,YAAY,KAAK,MAAM,KAAK,GAAG,CAAC;EAC9F,IAAI,uBAAuB,KAAK,UAAU,GAAG,OAAO,MAAM,OAAO,QAAQ,MAAM,OAAO;EACtF,IAAI,qBAAqB,KAAK,UAAU,GACtC,aAAa,eAAe,MAAM,MAAM,SAAS,CAAC,KAAK,WAAW,GAAG,CAAC,KAAK,EAAE;EAE/E,MAAM,SAAS,WAAW,QAAQ,qBAAqB,EAAE;EACzD,OACE,WAAW,eACV,gBAAgB,KAAK,MAAM,KAAK,uDAAuD,KAAK,MAAM;CAEvG,CAAC;AACH;;;;ACrDA,MAAM,YAAY,OAAO,mBAAmB;;AAE5C,MAAM,WAAW,OAAO,kBAAkB;;AAE1C,MAAM,UAAU,OAAO,SAAS;AAEhC,SAAS,WAAmB;CAG1B,OAAO,GAFW,KAAK,IAAI,CAAC,CAAC,SAAS,EAEpB,EAAE,IAAA,GADLA,YAAAA,YAAAA,CAAAA,CAAkC,CAAC,CAAC,SAAS,WAChC;AAC9B;AAEA,IAAa,iBAAb,MAAuD;CAElC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CATnB,YACE,UACA,aACA,OACA,UACA,OACA,cACA,MAA+B,QAAQ,IAAI,GAC3C,MAAqE,QAAQ,KAC7E,iBACA;EATiB,KAAA,WAAA;EACA,KAAA,cAAA;EACA,KAAA,QAAA;EACA,KAAA,WAAA;EACA,KAAA,QAAA;EACA,KAAA,eAAA;EACA,KAAA,MAAA;EACA,KAAA,MAAA;EACA,KAAA,kBAAA;CAChB;CAEH,MAAM,IAAI,SAAiD;EACzD,MAAM,KAAK,SAAS;EACpB,MAAM,OAAO,MAAM,KAAK,MAAM,SAAS,QAAQ,SAAS,QAAQ,WAAW,QAAQ,IAAI;EACvF,MAAM,MAAM,QAAQ,OAAO,KAAK;EAChC,MAAM,cAAc,QAAQ,gBAAgB;EAC5C,IAAI,QAAQ,QAAQ,SAAS,OAAO;GAAE,MAAM;GAAQ;GAAI;GAAM,OAAO;EAAoB;EAEzF,IAAI;EACJ,IAAI;EACJ,IAAI;GACF,IAAI,KAAK,mBAAmB,eAAe,QAAQ,OAAO,GACxD,cAAc,MAAM,KAAK,gBAAgB,QAAQ,QAAQ,MAAM;GAEjE,QAAQ,QAAQ,eAAe;GAC/B,MAAM,aAAa,MAAM,KAAK,YAAY,OAAO;IAC/C;IACA;IACA,SAAS,QAAQ;IACjB;IACA,WAAW,QAAQ;IACnB;GACF,CAAC;GACD,IAAI,eAAe,CAAC,YAAY;IAC9B,cAAc;IACd,OAAO;KAAE,MAAM;KAAQ;KAAI;KAAM,OAAO;IAA+D;GACzG;GACA,SACE,cAAc,KAAK,SAAS,OAAO;IAAE;IAAI;IAAM,SAAS,QAAQ;IAAS;IAAK,WAAW,QAAQ;GAAU,CAAC;EAChH,SAAS,OAAO;GACd,cAAc;GACd,OAAO;IAAE,MAAM;IAAQ;IAAI;IAAM,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;GAAE;EACjG;EAEA,IAAI,OAAO,QAAQ,KAAA,GAAW;GAC5B,cAAc;GACd,OAAO;IAAE,MAAM;IAAQ;IAAI;IAAM,OAAO;GAAwD;EAClG;EAEA,IAAI,aAAa,OAAY,WAAW,CAAC,CAAC,KAAK,aAAa,WAAW;EAEvE,IAAI;GACF,MAAM,KAAK,SAAS,SAAS;IAC3B;IACA;IACA,KAAK,OAAO;IACZ,SAAS,QAAQ;IACjB;IACA,SAAS,OAAO;IAChB;IACA,WAAW,QAAQ;IACnB,SAAS,OAAO;IAChB,GAAI,OAAO,gBAAgB,EAAE,eAAe,OAAO,cAAc,IAAI,CAAC;GACxE,CAAC;EACH,SAAS,OAAO;GACd,MAAM,OAAO,KAAK;GAClB,OAAO;IAAE,MAAM;IAAQ;IAAI;IAAM,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;GAAE;EACjG;EAEA,IAAI,aACF,IAAI;GACF,MAAM,YAAY,gBAAgB,OAAO,GAAG;EAC9C,SAAS,OAAO;GACd,IAAI,CAAE,MAAM,OAAO,KAAK,GACtB,OAAO,KAAK,QAAQ,QAAQ,aAAa,KAAA,CAAS;GAEpD,MAAM,KAAK,SAAS,SAAS,IAAI;IAAE,QAAQ;IAAW,MAAM;IAAM,QAAQ;GAAU,CAAC;GACrF,OAAO;IAAE,MAAM;IAAQ;IAAI;IAAM,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;GAAE;EACjG;EAEF,IAAI,QAAQ,QAAQ,SAAS;GAC3B,IAAI,CAAE,MAAM,OAAO,KAAK,GAAI,OAAO,KAAK,QAAQ,QAAQ,aAAa,KAAA,CAAS;GAC9E,MAAM,KAAK,SAAS,SAAS,IAAI;IAAE,QAAQ;IAAW,MAAM;IAAM,QAAQ;GAAU,CAAC;GACrF,OAAO;IAAE,MAAM;IAAQ;IAAI;IAAM,OAAO;GAAoB;EAC9D;EAIA,IAAI,QAAQ,eAAe,QAAQ,aACjC,OAAO,KAAK,QAAQ,QAAQ,QAAQ,eAAe,OAAO,cAAc,eAAe,QAAQ,MAAM;EAGvG,MAAM,gBAAgB,QAAQ,WAAW,KAAK,aAAa,QAAQ,QAAQ,QAAQ,IAAI,KAAA;EACvF,IAAI;GACF,MAAM,UAAU,MAAM,KAAK,KAAK,QAAQ,QAAQ,WAAW,QAAQ,MAAM;GACzE,eAAe,MAAM;GACrB,IAAI,YAAY,WACd,OAAO,KAAK,QAAQ,QAAQ,aAAa,QAAQ,MAAM;GAEzD,IAAI,YAAY,SAAS;IACvB,MAAM,KAAK,SAAS,mBAAmB,IAAI;KAAE,QAAQ;KAAW,mBAAmB;IAAoB,CAAC;IACxG,MAAM,OAAO,KAAK;IAClB,eAAe,MAAM;IACrB,MAAM,KAAK,SAAS,SAAS,IAAI;KAAE,QAAQ;KAAW,MAAM;KAAM,QAAQ;IAAU,CAAC;IACrF,OAAO;KACL,MAAM;KACN;KACA;KACA,QAAQ,OAAO,OAAO;KACtB,UAAU;KACV,QAAQ;KACR,SAAS,OAAO;KAChB,SAAS,OAAO;KAChB,SAAS;IACX;GACF;GACA,IAAI,YAAY,UAAU;IAGxB,MAAM,KAAK,SAAS,mBAAmB,IAAI;KAAE,QAAQ;KAAa,mBAAmB;IAAU,CAAC;IAChG,MAAM,OAAO,KAAK;IAClB,eAAe,MAAM;IACrB,MAAM,KAAK,SAAS,SAAS,IAAI;KAAE,QAAQ;KAAa,MAAM;KAAM,QAAQ;IAAU,CAAC;IACvF,OAAO;KACL,MAAM;KACN;KACA;KACA,QAAQ,OAAO,OAAO;KACtB,UAAU;KACV,QAAQ;KACR,SAAS,OAAO;KAChB,SAAS,OAAO;KAChB,UAAU;IACZ;GACF;GACA,IAAI,mBAAmB,OAAO;IAC5B,MAAM,KAAK,SAAS,SAAS,IAAI;KAAE,QAAQ;KAAgB,MAAM;KAAM,QAAQ;IAAK,CAAC;IACrF,OAAO;KAAE,MAAM;KAAQ;KAAI;KAAM,OAAO,QAAQ;IAAQ;GAC1D;GAEA,MAAM,KAAK,SAAS,SAAS,IAAI;IAC/B,QAAQ,QAAQ,WAAW,QAAQ,SAAA,aAAoB,QAAQ,SAAS,IAAA,cAAA;IACxE,MAAM,QAAQ;IACd,QAAQ,QAAQ;IAChB,GAAI,QAAQ,oBAAoB,EAAE,mBAAmB,QAAQ,kBAAkB,IAAI,CAAC;IACpF,GAAI,QAAQ,aAAa,EAAE,YAAY,QAAQ,WAAW,IAAI,CAAC;GACjE,CAAC;GAED,OAAO;IACL,MAAM;IACN;IACA;IACA,QAAQ,OAAO,OAAO;IACtB,UAAU,QAAQ;IAClB,QAAQ,QAAQ;IAChB,SAAS,OAAO;IAChB,SAAS,OAAO;IAChB,GAAI,MAAM,KAAK,WAAW,QAAQ,SAAS,OAAO,OAAO;GAC3D;EACF,UAAU;GACR,eAAe,QAAQ;EACzB;CACF;CAEA,MAAc,WAAW,SAAiB,SAA0E;EAClH,IAAI;GACF,MAAM,SAAS,MAAM,KAAK,aAAa,QAAQ;IAAE;IAAS;GAAQ,CAAC;GACnE,IAAI,OAAO,SAAS,aAAa,OAAO,EAAE,WAAW,OAAO,OAAO;GACnE,IAAI,OAAO,SAAS,YAAY,OAAO,EAAE,YAAY,OAAO,QAAQ;GACpE,OAAO,CAAC;EACV,QAAQ;GACN,OAAO,EAAE,YAAYC,qBAAAA,mBAAmB;EAC1C;CACF;CAEA,aACE,QACA,UACoC;EACpC,IAAI,SAAS;EACb,IAAI,WAAW;EACf,IAAI;EACJ,MAAM,cAAoB;GACxB,IAAI,CAAC,QAAQ;GACb,MAAM,SAAS,OAAO,OAAO;GAC7B,IAAI,WAAW,UAAU;GACzB,WAAW;GACX,SAAS,MAAM;EACjB;EACA,MAAM,aAAmB;GACvB,IAAI,CAAC,QAAQ;GACb,MAAM;GACN,IAAI,QAAQ,aAAa,KAAK,MAAM,MAAA,KAA6B,IAAI;EACvE;EACA,aAAa,KAAK,MAAM,MAAA,KAA6B,IAAI;EACzD,OAAO;GACL;GACA,eAAe;IACb,SAAS;IACT,aAAa;IACb,aAAa,KAAA;GACf;EACF;CACF;;;;;;;;CASA,MAAc,KACZ,QACA,WACA,QAGA;EACA,MAAM,UAA6B,CAAC;EACpC,MAAM,SAAkC,CAAC,OAAO,WAAW,CAAC,CAAC,OAAO,UAAiB,KAAK,CAAC;EAE3F,OAAO,KACL,IAAI,SAAS,YAAY;GACvB,QAAQ,KAAK,KAAK,MAAM,MAAMC,qBAAAA,yBAAyB,KAAK,GAAG,SAAS,QAAQ,SAAS,CAAC,CAAC;EAC7F,CAAC,CACH;EACA,IAAI,cAAc,KAAA,KAAa,YAAY,GACzC,OAAO,KACL,IAAI,SAAS,YAAY;GACvB,QAAQ,KAAK,KAAK,MAAM,MAAM,iBAAiB,QAAQ,QAAQ,CAAC,CAAC;EACnE,CAAC,CACH;EAEF,IAAI,QACF,OAAO,KACL,IAAI,SAAS,YAAY;GACvB,IAAI,OAAO,SAAS;IAClB,QAAQ,OAAO;IACf;GACF;GACA,MAAM,cAAoB,QAAQ,OAAO;GACzC,OAAO,iBAAiB,SAAS,OAAO,EAAE,MAAM,KAAK,CAAC;GACtD,QAAQ,WAAW,OAAO,oBAAoB,SAAS,KAAK,CAAC;EAC/D,CAAC,CACH;EAGF,IAAI;GACF,OAAQ,MAAM,QAAQ,KAAK,MAAM;EAMnC,UAAU;GACR,KAAK,MAAM,UAAU,SAAS,OAAO;EACvC;CACF;CAEA,MAAc,QACZ,QACA,QACA,QACwB;EACxB,IAAI,OAAO,QAAQ,KAAA,GACjB,OAAO;GAAE,MAAM;GAAQ,IAAI,OAAO;GAAI,MAAM,OAAO;GAAM,OAAO;EAA4B;EAC9F,MAAM,KAAK,SAAS,aAAa,OAAO,EAAE;EAG1C,OAAO,OAAO;EACd,IAAI;EACJ,MAAM,cAAoB;GACxB,YAAY,KAAK,SACd,mBAAmB,OAAO,IAAI;IAAE,QAAQ;IAAW,mBAAmB;GAAoB,CAAC,CAAC,CAC5F,WAAW,OAAO,KAAK,CAAC,CAAC,CACzB,KAAK,YAAY;IAChB,MAAM,KAAK,SAAS,SAAS,OAAO,IAAI;KAAE,QAAQ;KAAW,MAAM;KAAM,QAAQ;IAAU,CAAC;IAC5F,OAAO;GACT,CAAC,CAAC,CACD,OAAO,UAAmB;IACzB,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;IACrE,QAAQ,YAAY,iCAAiC,OAAO,GAAG,IAAI,SAAS;IAC5E,OAAO;GACT,CAAC;EACL;EAIA,IAAI,QAAQ,SAAS,MAAM;EAC3B,OACG,WAAW,CAAC,CACZ,KACC,OAAO,YAAY;GACjB,IAAI,MAAM,WAAW;GACrB,MAAM,KAAK,SAAS,SAAS,OAAO,IAAI;IACtC,QAAQ,QAAQ,WAAW,QAAQ,SAAA,aAAoB,QAAQ,SAAS,IAAA,cAAA;IACxE,MAAM,QAAQ;IACd,QAAQ,QAAQ;IAChB,GAAI,QAAQ,oBAAoB,EAAE,mBAAmB,QAAQ,kBAAkB,IAAI,CAAC;IACpF,GAAI,QAAQ,aAAa,EAAE,YAAY,QAAQ,WAAW,IAAI,CAAC;GACjE,CAAC;EACH,GACA,YAAY;GACV,IAAI,MAAM,WAAW;GACrB,MAAM,KAAK,SAAS,SAAS,OAAO,IAAI;IAAE,QAAQ;IAAgB,MAAM;IAAM,QAAQ;GAAK,CAAC;EAC9F,CACF,CAAC,CACA,OAAO,UAAmB;GACzB,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;GACrE,QAAQ,YAAY,6BAA6B,OAAO,GAAG,IAAI,SAAS;EAC1E,CAAC;EAEH,OAAO;GACL,MAAM;GACN,IAAI,OAAO;GACX,MAAM,OAAO;GACb,KAAK,OAAO;GACZ,SAAS,OAAO;GAChB,SAAS,OAAO;GAChB;EACF;CACF;AACF"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { t as IRtkProcessor } from "./rtkProcessor-CVZvNhkJ.mjs";
|
|
2
|
+
import { a as IBashRunService, i as FailedRun, n as BashRunResult, o as PromotedRun, r as CompletedRun, t as BashRunRequest } from "./bashRunService-Ci0cGdYO.mjs";
|
|
3
|
+
import { t as IClock } from "./clock-euJkweLq.mjs";
|
|
4
|
+
import { t as ILauncher } from "./launcher-BG5t9nvG.mjs";
|
|
5
|
+
import { t as IRmuxBackend } from "./rmuxBackend-CaEWooWn.mjs";
|
|
6
|
+
import { n as IRunnerRegistry } from "./runnerRegistry-CtJiD02R.mjs";
|
|
7
|
+
import { t as IRunnerNamer } from "./type-vWQNTahw.mjs";
|
|
8
|
+
import { DoomHostExecutionBudget } from "@agimon-ai/po-core/packageApi";
|
|
9
|
+
//#region src/services/bashRunService/index.d.ts
|
|
10
|
+
export declare class BashRunService implements IBashRunService {
|
|
11
|
+
private readonly launcher;
|
|
12
|
+
private readonly rmuxBackend;
|
|
13
|
+
private readonly namer;
|
|
14
|
+
private readonly registry;
|
|
15
|
+
private readonly clock;
|
|
16
|
+
private readonly rtkProcessor;
|
|
17
|
+
private readonly cwd;
|
|
18
|
+
private readonly env;
|
|
19
|
+
private readonly executionBudget?;
|
|
20
|
+
constructor(launcher: ILauncher, rmuxBackend: IRmuxBackend, namer: IRunnerNamer, registry: IRunnerRegistry, clock: IClock, rtkProcessor: IRtkProcessor, cwd?: string, env?: Readonly<Record<string, string | undefined>>, executionBudget?: DoomHostExecutionBudget | undefined);
|
|
21
|
+
run(request: BashRunRequest): Promise<BashRunResult>;
|
|
22
|
+
private processLog;
|
|
23
|
+
private followOutput;
|
|
24
|
+
/**
|
|
25
|
+
* Waits for the command, giving up at the background threshold or at the
|
|
26
|
+
* caller's timeout, whichever comes first.
|
|
27
|
+
*
|
|
28
|
+
* A rejected completion is returned rather than thrown so the caller can
|
|
29
|
+
* report a start failure as a tool result instead of an exception.
|
|
30
|
+
*/
|
|
31
|
+
private race;
|
|
32
|
+
private promote;
|
|
33
|
+
}
|
|
34
|
+
//#endregion
|
|
35
|
+
export type { BashRunRequest, BashRunResult, CompletedRun, FailedRun, IBashRunService, PromotedRun };
|
|
36
|
+
//# sourceMappingURL=bashRunService.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bashRunService.d.mts","names":[],"sources":["../src/services/bashRunService/index.ts"],"mappings":";;;;;;;;;qBAyCa,0BAA0B;mBAElB;mBACA;mBACA;mBACA;mBACA;mBACA;mBACA;mBACA;mBACA;EATnB,YACmB,UAAU,WACV,aAAa,cACb,OAAO,cACP,UAAU,iBACV,OAAO,QACP,cAAc,eACd,cACA,MAAK,SAAS,qCACd,kBAAkB;EAG/B,IAAI,SAAS,iBAAiB,QAAQ;UAyJ9B;UAWN;;;;;;;;UAqCM;UAgDA"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_bashTool = require("./bashTool-CdgtqVFD.cjs");
|
|
3
|
+
exports.BASH_TOOL_LABEL = require_bashTool.BASH_TOOL_LABEL;
|
|
4
|
+
exports.BASH_TOOL_NAME = require_bashTool.BASH_TOOL_NAME;
|
|
5
|
+
exports.BashParamsSchema = require_bashTool.BashParamsSchema;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { n as BashParamsSchema, t as BashParams } from "./bashTool-B1EwZLo_.mjs";
|
|
2
|
+
//#region src/constants/bashTool.d.ts
|
|
3
|
+
export declare const BASH_TOOL_NAME = "bash";
|
|
4
|
+
export declare const BASH_TOOL_LABEL = "bash";
|
|
5
|
+
//#endregion
|
|
6
|
+
export { BashParams, BashParamsSchema };
|
|
7
|
+
//# sourceMappingURL=bashSchema.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bashSchema.d.mts","names":[],"sources":["../src/constants/bashTool.ts"],"mappings":";;qBAAa;qBACA"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Static, Type } from "typebox";
|
|
2
|
+
//#region src/schemas/bashTool.d.ts
|
|
3
|
+
/** Replaces pi's built-in tool of the same name, so hooks keyed on `bash` keep working. */
|
|
4
|
+
/**
|
|
5
|
+
* Built-in bash parameters plus the backgrounding controls.
|
|
6
|
+
*
|
|
7
|
+
* `command` and `timeout` keep their original names and wording so the tool is
|
|
8
|
+
* a drop-in replacement. Every `description` is prompt copy the model reads.
|
|
9
|
+
*/
|
|
10
|
+
declare const BashParamsSchema: Type.TObject<{
|
|
11
|
+
command: Type.TString;
|
|
12
|
+
timeout: Type.TOptional<Type.TNumber>;
|
|
13
|
+
background: Type.TOptional<Type.TBoolean>;
|
|
14
|
+
interactive: Type.TOptional<Type.TBoolean>;
|
|
15
|
+
name: Type.TOptional<Type.TString>;
|
|
16
|
+
}>;
|
|
17
|
+
type BashParams = Static<typeof BashParamsSchema>;
|
|
18
|
+
//#endregion
|
|
19
|
+
export { BashParamsSchema as n, BashParams as t };
|
|
20
|
+
//# sourceMappingURL=bashTool-B1EwZLo_.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bashTool-B1EwZLo_.d.mts","names":[],"sources":["../src/schemas/bashTool.ts"],"mappings":";;;;;;;;;cAUa,kBAAgB,KAAA;;;;;;;KAsBjB,aAAa,cAAc"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Type } from "typebox";
|
|
2
|
+
//#region src/schemas/bashTool.ts
|
|
3
|
+
/** Replaces pi's built-in tool of the same name, so hooks keyed on `bash` keep working. */
|
|
4
|
+
/**
|
|
5
|
+
* Built-in bash parameters plus the backgrounding controls.
|
|
6
|
+
*
|
|
7
|
+
* `command` and `timeout` keep their original names and wording so the tool is
|
|
8
|
+
* a drop-in replacement. Every `description` is prompt copy the model reads.
|
|
9
|
+
*/
|
|
10
|
+
const BashParamsSchema = Type.Object({
|
|
11
|
+
command: Type.String({ description: "Bash command to execute" }),
|
|
12
|
+
timeout: Type.Optional(Type.Number({ description: "Timeout in seconds (optional, no default timeout)" })),
|
|
13
|
+
background: Type.Optional(Type.Boolean({ description: "Start the command in the background immediately instead of waiting. Use for dev servers, watchers and other commands you already know will not finish." })),
|
|
14
|
+
interactive: Type.Optional(Type.Boolean({ description: "Run under a pseudo terminal so the command can prompt. Use only when the command asks for confirmation or input; answer it with doom-runner input. Logs from interactive runs are noisier." })),
|
|
15
|
+
name: Type.Optional(Type.String({ description: "Preferred runner name if the command ends up in the background. A name in use gets a suffix." }))
|
|
16
|
+
});
|
|
17
|
+
//#endregion
|
|
18
|
+
//#region src/constants/bashTool.ts
|
|
19
|
+
const BASH_TOOL_NAME = "bash";
|
|
20
|
+
const BASH_TOOL_LABEL = "bash";
|
|
21
|
+
//#endregion
|
|
22
|
+
export { BASH_TOOL_NAME as n, BashParamsSchema as r, BASH_TOOL_LABEL as t };
|
|
23
|
+
|
|
24
|
+
//# sourceMappingURL=bashTool-C-k7fmyh.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bashTool-C-k7fmyh.mjs","names":[],"sources":["../src/schemas/bashTool.ts","../src/constants/bashTool.ts"],"sourcesContent":["import { type Static, Type } from 'typebox';\n\n/** Replaces pi's built-in tool of the same name, so hooks keyed on `bash` keep working. */\n\n/**\n * Built-in bash parameters plus the backgrounding controls.\n *\n * `command` and `timeout` keep their original names and wording so the tool is\n * a drop-in replacement. Every `description` is prompt copy the model reads.\n */\nexport const BashParamsSchema = Type.Object({\n command: Type.String({ description: 'Bash command to execute' }),\n timeout: Type.Optional(Type.Number({ description: 'Timeout in seconds (optional, no default timeout)' })),\n background: Type.Optional(\n Type.Boolean({\n description:\n 'Start the command in the background immediately instead of waiting. Use for dev servers, watchers and other commands you already know will not finish.',\n }),\n ),\n interactive: Type.Optional(\n Type.Boolean({\n description:\n 'Run under a pseudo terminal so the command can prompt. Use only when the command asks for confirmation or input; answer it with doom-runner input. Logs from interactive runs are noisier.',\n }),\n ),\n name: Type.Optional(\n Type.String({\n description: 'Preferred runner name if the command ends up in the background. A name in use gets a suffix.',\n }),\n ),\n});\n\nexport type BashParams = Static<typeof BashParamsSchema>;\n","export const BASH_TOOL_NAME = 'bash';\nexport const BASH_TOOL_LABEL = 'bash';\n\nexport const MS_PER_SECOND = 1000;\n"],"mappings":";;;;;;;;;AAUA,MAAa,mBAAmB,KAAK,OAAO;CAC1C,SAAS,KAAK,OAAO,EAAE,aAAa,0BAA0B,CAAC;CAC/D,SAAS,KAAK,SAAS,KAAK,OAAO,EAAE,aAAa,oDAAoD,CAAC,CAAC;CACxG,YAAY,KAAK,SACf,KAAK,QAAQ,EACX,aACE,yJACJ,CAAC,CACH;CACA,aAAa,KAAK,SAChB,KAAK,QAAQ,EACX,aACE,6LACJ,CAAC,CACH;CACA,MAAM,KAAK,SACT,KAAK,OAAO,EACV,aAAa,+FACf,CAAC,CACH;AACF,CAAC;;;AC9BD,MAAa,iBAAiB;AAC9B,MAAa,kBAAkB"}
|