@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,36 @@
|
|
|
1
|
+
import { t as ILauncher } from "./launcher-BG5t9nvG.mjs";
|
|
2
|
+
import { t as IRmuxBackend } from "./rmuxBackend-CaEWooWn.mjs";
|
|
3
|
+
import { a as RunnerTerminationIntent, i as RunnerRecord, n as IRunnerRegistry } from "./runnerRegistry-CtJiD02R.mjs";
|
|
4
|
+
import { t as IProcessControl } from "./processControl-BAOa3oo_.mjs";
|
|
5
|
+
import { t as IRunnerPaths } from "./type-BXM03qSw.mjs";
|
|
6
|
+
//#region src/services/reconcile/index.d.ts
|
|
7
|
+
interface ReconcileDependencies {
|
|
8
|
+
registry: IRunnerRegistry;
|
|
9
|
+
launcher: ILauncher;
|
|
10
|
+
rmuxBackend: IRmuxBackend;
|
|
11
|
+
processControl: IProcessControl;
|
|
12
|
+
currentHostPid: number;
|
|
13
|
+
startup: boolean;
|
|
14
|
+
/** Same-host restart cleanup belongs only to this session. */
|
|
15
|
+
startupSessionId?: string;
|
|
16
|
+
active?: readonly RunnerRecord[];
|
|
17
|
+
}
|
|
18
|
+
export interface RunnerReconcileResult {
|
|
19
|
+
reclaimed: string[];
|
|
20
|
+
errors: string[];
|
|
21
|
+
}
|
|
22
|
+
export declare function stopRunnerProcess(record: RunnerRecord, launcher: ILauncher, rmuxBackend: IRmuxBackend, termination?: {
|
|
23
|
+
registry: IRunnerRegistry;
|
|
24
|
+
intent: RunnerTerminationIntent;
|
|
25
|
+
}): Promise<boolean>;
|
|
26
|
+
/** Repairs active registry entries that lost their original completion observer. */
|
|
27
|
+
export declare function reconcileActiveRunners(dependencies: ReconcileDependencies): Promise<RunnerReconcileResult>;
|
|
28
|
+
interface LegacyCleanupDependencies extends Omit<ReconcileDependencies, 'startup'> {
|
|
29
|
+
paths: IRunnerPaths;
|
|
30
|
+
}
|
|
31
|
+
/** Deletes the legacy Git store only after no live foreign runner uses it. */
|
|
32
|
+
export declare function cleanupLegacyRunnerStore(dependencies: LegacyCleanupDependencies): Promise<RunnerReconcileResult & {
|
|
33
|
+
removed?: string;
|
|
34
|
+
}>;
|
|
35
|
+
//#endregion
|
|
36
|
+
//# sourceMappingURL=reconcile.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reconcile.d.mts","names":[],"sources":["../src/services/reconcile/index.ts"],"mappings":";;;;;;UAWU;EACR,UAAU;EACV,UAAU;EACV,aAAa;EACb,gBAAgB;EAChB;EACA;;EAEA;EACA,kBAAkB;;iBAGH;EACf;EACA;;wBAGoB,kBACpB,QAAQ,cACR,UAAU,WACV,aAAa,cACb;EAAgB,UAAU;EAAiB,QAAQ;IAClD;;wBAWmB,uBAAuB,cAAc,wBAAwB,QAAQ;UAqFjF,kCAAkC,KAAK;EAC/C,OAAO;;;wBAIa,yBACpB,cAAc,4BACb,QAAQ;EAA0B"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_bashResult = require("./bashResult-DNgtahGR.cjs");
|
|
3
|
+
const require_logReader = require("./logReader-B6J7L7Ua.cjs");
|
|
4
|
+
exports.boundExcerpt = require_bashResult.boundExcerpt;
|
|
5
|
+
exports.boundResultText = require_bashResult.boundResultText;
|
|
6
|
+
exports.collectErrorLines = require_bashResult.collectErrorLines;
|
|
7
|
+
exports.composeExcerpt = require_bashResult.composeExcerpt;
|
|
8
|
+
exports.countLines = require_bashResult.countLines;
|
|
9
|
+
exports.createErrorScanner = require_bashResult.createErrorScanner;
|
|
10
|
+
exports.errorResult = require_bashResult.errorResult;
|
|
11
|
+
exports.formatRunResult = require_bashResult.formatRunResult;
|
|
12
|
+
exports.formatRunnerLine = require_bashResult.formatRunnerLine;
|
|
13
|
+
exports.formatSize = require_bashResult.formatSize;
|
|
14
|
+
exports.formatUptime = require_bashResult.formatUptime;
|
|
15
|
+
exports.parseResultPragma = require_bashResult.parseResultPragma;
|
|
16
|
+
exports.summarizeLog = require_logReader.summarizeLog;
|
|
17
|
+
exports.summarizeText = require_bashResult.summarizeText;
|
|
18
|
+
exports.textResult = require_bashResult.textResult;
|
|
19
|
+
exports.truncateForResult = require_logReader.truncateForResult;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { n as BashRunResult } from "./bashRunService-Ci0cGdYO.mjs";
|
|
2
|
+
import { i as RunnerRecord } from "./runnerRegistry-CtJiD02R.mjs";
|
|
3
|
+
import { a as ResultBudget, c as TruncatedOutput, i as LogSummary, n as Excerpt, o as SalvagedError, r as LogSummarizer, s as ToolResult, t as ErrorLineScanner } from "./bashResult-DcrRaBLv.mjs";
|
|
4
|
+
import { t as RunnerSettings } from "./runnerSettings-DiV1lvzx.mjs";
|
|
5
|
+
import { i as truncateForResult, r as summarizeLog } from "./index-DM7yJpMs.mjs";
|
|
6
|
+
//#region src/services/bashResult/index.d.ts
|
|
7
|
+
export declare function textResult(text: string, details?: Record<string, unknown>): ToolResult;
|
|
8
|
+
export declare function errorResult(message: string): ToolResult;
|
|
9
|
+
/** Human-readable byte count, matching how pi reports output sizes. */
|
|
10
|
+
export declare function formatSize(bytes: number): string;
|
|
11
|
+
export declare function countLines(text: string): number;
|
|
12
|
+
export declare function createErrorScanner(maxEntries?: number, settings?: RunnerSettings): ErrorLineScanner;
|
|
13
|
+
/**
|
|
14
|
+
* Reads `# @doom: {"maxResultBytes": 32768}` from the command's first line.
|
|
15
|
+
*
|
|
16
|
+
* The pragma is a shell comment, so it stays harmless if this parse is ever
|
|
17
|
+
* skipped, and it survives verbatim into the log where a wider result can be
|
|
18
|
+
* explained after the fact.
|
|
19
|
+
*/
|
|
20
|
+
export declare function parseResultPragma(command: string): ResultBudget;
|
|
21
|
+
/**
|
|
22
|
+
* Collapses repeats so one failure repeated two hundred times costs one slot.
|
|
23
|
+
* Counting continues past the entry cap so the tallies stay honest.
|
|
24
|
+
*/
|
|
25
|
+
export declare function collectErrorLines(lines: Iterable<string>, maxEntries?: number, settings?: RunnerSettings): SalvagedError[];
|
|
26
|
+
/**
|
|
27
|
+
* Bounds text to the budget, keeping a leading excerpt as well as the tail.
|
|
28
|
+
*
|
|
29
|
+
* Failures announce themselves at both ends: a command that could not start
|
|
30
|
+
* says so on line one, and a command that died says so on the last. Keeping
|
|
31
|
+
* only the tail loses the first kind entirely.
|
|
32
|
+
*/
|
|
33
|
+
export declare function boundExcerpt(text: string, maxLines?: number, maxBytes?: number, maxTokens?: number, settings?: RunnerSettings): Excerpt;
|
|
34
|
+
/**
|
|
35
|
+
* Same budget as `boundExcerpt`, for callers that streamed the two ends
|
|
36
|
+
* separately and never held the middle. `totalLines` counts the whole source,
|
|
37
|
+
* so the marker states what was dropped rather than what was captured.
|
|
38
|
+
*/
|
|
39
|
+
export declare function composeExcerpt(headSource: string, tailSource: string, totalLines: number, maxLines?: number, maxBytes?: number, errors?: readonly SalvagedError[], maxTokens?: number, settings?: RunnerSettings): Excerpt;
|
|
40
|
+
/** Applies Doom's line and byte ceilings to text already held in memory. */
|
|
41
|
+
export declare function summarizeText(text: string, maxLines?: number, maxBytes?: number): Pick<LogSummary, 'tail' | 'tailLines'>;
|
|
42
|
+
/** Bounds the complete model-facing result after status and recovery text are attached. */
|
|
43
|
+
export declare function boundResultText(text: string, maxBytes?: number, settings?: RunnerSettings, maxTokens?: number): string;
|
|
44
|
+
/** `name pid 1234 up 3m sleep 60` — one runner per line. */
|
|
45
|
+
export declare function formatRunnerLine(record: RunnerRecord, now?: number): string;
|
|
46
|
+
export declare function formatUptime(startedAt: string, now: number): string;
|
|
47
|
+
export declare function formatRunResult(result: BashRunResult, budget?: ResultBudget, summarizeLog?: LogSummarizer, settings?: RunnerSettings, environment?: NodeJS.ProcessEnv): ToolResult;
|
|
48
|
+
//#endregion
|
|
49
|
+
export { type ErrorLineScanner, type Excerpt, type LogSummarizer, type LogSummary, type ResultBudget, type SalvagedError, type ToolResult, type TruncatedOutput, summarizeLog, truncateForResult };
|
|
50
|
+
//# sourceMappingURL=responseEnvelope.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"responseEnvelope.d.mts","names":[],"sources":["../src/services/bashResult/index.ts"],"mappings":";;;;;;wBAiDgB,WAAW,cAAc,UAAS,0BAA+B;wBAIjE,YAAY,kBAAkB;;wBAK9B,WAAW;wBAUX,WAAW;wBAqCX,mBAAmB,qBAAmC,WAAW,iBAAiB;;;;;;;;wBAiBlF,kBAAkB,kBAAkB;;;;;wBA2DpC,kBACd,OAAO,kBACP,qBACA,WAAW,iBACV;;;;;;;;wBAyLa,aACd,cACA,mBACA,mBACA,oBACA,WAAW,iBACV;;;;;;wBAsCa,eACd,oBACA,oBACA,oBACA,mBACA,mBACA,kBAAiB,iBACjB,oBACA,WAAW,iBACV;;wBAsCa,cACd,cACA,mBACA,oBACC,KAAK;;wBAMQ,gBACd,cACA,mBACA,WAAW,gBACX;;wBAoBc,iBAAiB,QAAQ,cAAc;wBAKvC,aAAa,mBAAmB;wBA+BhC,gBACd,QAAQ,eACR,SAAQ,cACR,eAAc,eACd,WAAW,gBACX,cAAa,OAAO,aACnB"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { a as countLines, c as formatRunResult, d as formatUptime, f as parseResultPragma, i as composeExcerpt, l as formatRunnerLine, m as textResult, n as boundResultText, o as createErrorScanner, p as summarizeText, r as collectErrorLines, s as errorResult, t as boundExcerpt, u as formatSize } from "./bashResult-bIVSzoj-.mjs";
|
|
2
|
+
import { i as truncateForResult, r as summarizeLog } from "./logReader-UfbDbwQl.mjs";
|
|
3
|
+
export { boundExcerpt, boundResultText, collectErrorLines, composeExcerpt, countLines, createErrorScanner, errorResult, formatRunResult, formatRunnerLine, formatSize, formatUptime, parseResultPragma, summarizeLog, summarizeText, textResult, truncateForResult };
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { t as ExitResult } from "./spawner-CdrN_HNk.mjs";
|
|
2
|
+
import { r as RunHandle } from "./launcher-BG5t9nvG.mjs";
|
|
3
|
+
import { r as PtyRun } from "./ptyHost-DWWtRrGn.mjs";
|
|
4
|
+
//#region src/types/rmuxBackend.d.ts
|
|
5
|
+
interface RmuxLaunchRequest {
|
|
6
|
+
id: string;
|
|
7
|
+
name: string;
|
|
8
|
+
command: string;
|
|
9
|
+
cwd: string;
|
|
10
|
+
sessionId: string;
|
|
11
|
+
interactive: boolean;
|
|
12
|
+
}
|
|
13
|
+
interface IRmuxBackend {
|
|
14
|
+
/** Returns undefined when no compatible RMUX binary is available before launch. */
|
|
15
|
+
launch(request: RmuxLaunchRequest): Promise<RunHandle | undefined>;
|
|
16
|
+
/** Reconnects completion monitoring for a persisted RMUX session. */
|
|
17
|
+
watch(id: string, target: string, sessionId?: string): Promise<ExitResult | undefined>;
|
|
18
|
+
/** Reads persisted terminal evidence without contacting RMUX. */
|
|
19
|
+
readOutcome(id: string, sessionId: string): ExitResult | undefined;
|
|
20
|
+
stop(target: string, expectedPid: number): Promise<boolean>;
|
|
21
|
+
input(target: string, text: string): Promise<boolean>;
|
|
22
|
+
/**
|
|
23
|
+
* The pane's current screen as text, or undefined when it cannot be read.
|
|
24
|
+
*
|
|
25
|
+
* A screen, not a byte stream: the multiplexer holds the rendered state and
|
|
26
|
+
* hands back what is on it now. That is what makes an attached view possible
|
|
27
|
+
* from another process, where the live PTY handle is out of reach, and it is
|
|
28
|
+
* why the log file cannot stand in: it is scrubbed of cursor movement before
|
|
29
|
+
* it is ever written.
|
|
30
|
+
*/
|
|
31
|
+
capture(target: string): Promise<string | undefined>;
|
|
32
|
+
get(name: string): PtyRun | undefined;
|
|
33
|
+
}
|
|
34
|
+
//#endregion
|
|
35
|
+
export { RmuxLaunchRequest as n, IRmuxBackend as t };
|
|
36
|
+
//# sourceMappingURL=rmuxBackend-CaEWooWn.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rmuxBackend-CaEWooWn.d.mts","names":[],"sources":["../src/types/rmuxBackend.ts"],"mappings":";;;;UAIiB;EACf;EACA;EACA;EACA;EACA;EACA;;UAGe;;EAEf,OAAO,SAAS,oBAAoB,QAAQ;;EAE5C,MAAM,YAAY,gBAAgB,qBAAqB,QAAQ;;EAE/D,YAAY,YAAY,oBAAoB;EAC5C,KAAK,gBAAgB,sBAAsB;EAC3C,MAAM,gBAAgB,eAAe;;;;;;;;;;EAUrC,QAAQ,iBAAiB;EACzB,IAAI,eAAe"}
|
|
@@ -0,0 +1,509 @@
|
|
|
1
|
+
import { g as noninteractiveEnvironment, s as getLogMaxBytes, u as getResultMaxBytes } from "./runnerConfig-BQBlVAXn.mjs";
|
|
2
|
+
import { NO_TERMINAL_INPUT_ENV, cleanupSupervisorFiles, readExitMetadata, runtimeEntry, shellJoin, supervisorPaths, watchForFile, writeCommandSpec } from "./services/runnerSupervisor/index.mjs";
|
|
3
|
+
import { createRequire } from "node:module";
|
|
4
|
+
import { createHash } from "node:crypto";
|
|
5
|
+
import fs from "node:fs";
|
|
6
|
+
import path from "node:path";
|
|
7
|
+
import { RMUX } from "@rmux/sdk";
|
|
8
|
+
//#region src/constants/rmuxBackend.ts
|
|
9
|
+
const RMUX_BINARY_ENV = "PO_RMUX_BINARY";
|
|
10
|
+
const LOG_DRAIN_TIMEOUT_MS = 2e3;
|
|
11
|
+
const PANE_STATE_FORMAT = "#{pane_dead}:#{pane_dead_status}:#{session_name}";
|
|
12
|
+
const PANE_PID_FORMAT = "#{pane_pid}";
|
|
13
|
+
const STOP_CLOSE_TIMEOUT_MS = 1e3;
|
|
14
|
+
const VENDOR_DIRECTORY = "vendor";
|
|
15
|
+
const SESSION_PREFIX = "doom-runner-";
|
|
16
|
+
const OWNED_TARGET_PATTERN = /^doom-runner-[A-Za-z0-9_-]+$/;
|
|
17
|
+
const NON_INTERACTIVE_ENV = {
|
|
18
|
+
NO_COLOR: "1",
|
|
19
|
+
CI: "1"
|
|
20
|
+
};
|
|
21
|
+
//#endregion
|
|
22
|
+
//#region src/services/rmuxBackend/index.ts
|
|
23
|
+
/** Pane liveness, its exit status, and whether the session still exists, in one read. */
|
|
24
|
+
const PACKAGE_BY_PLATFORM = {
|
|
25
|
+
"darwin-arm64": "@agimon-ai/po-runner-rmux-darwin-arm64",
|
|
26
|
+
"darwin-x64": "@agimon-ai/po-runner-rmux-darwin-x64",
|
|
27
|
+
"linux-arm64": "@agimon-ai/po-runner-rmux-linux-arm64",
|
|
28
|
+
"linux-x64": "@agimon-ai/po-runner-rmux-linux-x64"
|
|
29
|
+
};
|
|
30
|
+
var RmuxBackend = class {
|
|
31
|
+
paths;
|
|
32
|
+
env;
|
|
33
|
+
settings;
|
|
34
|
+
clientPromise;
|
|
35
|
+
runs = /* @__PURE__ */ new Map();
|
|
36
|
+
completions = /* @__PURE__ */ new Map();
|
|
37
|
+
constructor(paths, env = process.env, settings) {
|
|
38
|
+
this.paths = paths;
|
|
39
|
+
this.env = env;
|
|
40
|
+
this.settings = settings;
|
|
41
|
+
}
|
|
42
|
+
async launch(request) {
|
|
43
|
+
const rmux = await this.client();
|
|
44
|
+
if (!rmux) return void 0;
|
|
45
|
+
this.paths.ensureDirectories();
|
|
46
|
+
const target = `${SESSION_PREFIX}${request.id}`;
|
|
47
|
+
const logPath = this.paths.logPathFor(request.id);
|
|
48
|
+
const aux = this.auxPaths(request.id, request.sessionId);
|
|
49
|
+
let created = false;
|
|
50
|
+
let released = false;
|
|
51
|
+
try {
|
|
52
|
+
this.prepareFiles(request, logPath, aux);
|
|
53
|
+
const opened = await rmux.cmd("new-session", "-d", "-P", "-F", PANE_PID_FORMAT, "-s", target, "-c", request.cwd, process.execPath, runtimeEntry("runnerHost"), aux.spec, aux.gate, aux.exit, { check: true });
|
|
54
|
+
created = true;
|
|
55
|
+
await rmux.cmd("set-option", "-t", target, "remain-on-exit", "on", { check: true });
|
|
56
|
+
await rmux.cmd("pipe-pane", "-t", target, this.logPipeCommand(logPath, aux.logDone, request), { check: true });
|
|
57
|
+
const pane = rmux.session(target).pane(0, 0);
|
|
58
|
+
const pid = reportedPid(String(opened.stdout ?? "")) ?? await panePid(rmux, target);
|
|
59
|
+
fs.writeFileSync(aux.gate, "", { mode: 384 });
|
|
60
|
+
released = true;
|
|
61
|
+
let buffering = true;
|
|
62
|
+
const completion = this.monitor(rmux, pane, target, aux);
|
|
63
|
+
this.trackCompletion(target, completion);
|
|
64
|
+
const stop = () => this.stop(target, pid);
|
|
65
|
+
const handle = {
|
|
66
|
+
id: request.id,
|
|
67
|
+
name: request.name,
|
|
68
|
+
pid,
|
|
69
|
+
logPath,
|
|
70
|
+
backend: "rmux",
|
|
71
|
+
backendTarget: target,
|
|
72
|
+
output: () => buffering ? readTail(logPath, getResultMaxBytes(this.env, this.settings) * 2) : "",
|
|
73
|
+
completion: () => completion,
|
|
74
|
+
detach: () => {
|
|
75
|
+
buffering = false;
|
|
76
|
+
},
|
|
77
|
+
stop
|
|
78
|
+
};
|
|
79
|
+
if (request.interactive) this.runs.set(request.name, this.interactiveRun(handle, pane, completion));
|
|
80
|
+
completion.finally(() => this.runs.delete(request.name)).catch((error) => process.emitWarning(`RMUX completion failed for ${target}: ${errorMessage(error)}`));
|
|
81
|
+
return handle;
|
|
82
|
+
} catch (error) {
|
|
83
|
+
if (released) throw error;
|
|
84
|
+
if (created) await rmux.session(target).kill().catch((cleanupError) => process.emitWarning(`Could not clean up failed RMUX launch ${target}: ${errorMessage(cleanupError)}`));
|
|
85
|
+
cleanupSupervisorFiles(aux);
|
|
86
|
+
process.emitWarning(request.interactive ? `RMUX launch unavailable for interactive runner: ${errorMessage(error)}` : `RMUX launch unavailable, using supervised subprocess: ${errorMessage(error)}`);
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
async stop(target, expectedPid) {
|
|
91
|
+
if (!OWNED_TARGET_PATTERN.test(target) || !Number.isInteger(expectedPid) || expectedPid <= 0) return false;
|
|
92
|
+
const rmux = await this.client();
|
|
93
|
+
if (!rmux) return false;
|
|
94
|
+
try {
|
|
95
|
+
if (await sessionMissing(rmux, target)) return true;
|
|
96
|
+
const pid = await panePid(rmux, target);
|
|
97
|
+
if (pid !== expectedPid) return false;
|
|
98
|
+
const signalled = signalPane(pid, target);
|
|
99
|
+
if (signalled === "gone") return true;
|
|
100
|
+
if (signalled === "failed") return false;
|
|
101
|
+
if (await waitForPaneStop(rmux, target, 3e3)) return true;
|
|
102
|
+
if (await sessionMissing(rmux, target)) return true;
|
|
103
|
+
if (await panePid(rmux, target) !== expectedPid) return false;
|
|
104
|
+
return closeOwnedSession(rmux, target);
|
|
105
|
+
} catch (error) {
|
|
106
|
+
process.emitWarning(`Could not stop RMUX target ${target}: ${errorMessage(error)}`);
|
|
107
|
+
return false;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
async watch(id, target, sessionId) {
|
|
111
|
+
const rmux = await this.client();
|
|
112
|
+
if (!rmux) return void 0;
|
|
113
|
+
const pane = rmux.session(target).pane(0, 0);
|
|
114
|
+
try {
|
|
115
|
+
await rmux.displayMessage("#{pane_id}", { target });
|
|
116
|
+
} catch (error) {
|
|
117
|
+
process.emitWarning(`Could not watch RMUX target ${target}: ${errorMessage(error)}`);
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
const completion = this.monitor(rmux, pane, target, this.auxPaths(id, sessionId));
|
|
121
|
+
this.trackCompletion(target, completion);
|
|
122
|
+
return completion;
|
|
123
|
+
}
|
|
124
|
+
async input(target, text) {
|
|
125
|
+
const rmux = await this.client();
|
|
126
|
+
if (!rmux) return false;
|
|
127
|
+
return await rmux.session(target).pane(0, 0).sendText(text).catch((error) => {
|
|
128
|
+
process.emitWarning(`Could not send input to RMUX target ${target}: ${errorMessage(error)}`);
|
|
129
|
+
}) !== void 0;
|
|
130
|
+
}
|
|
131
|
+
async capture(target) {
|
|
132
|
+
const rmux = await this.client();
|
|
133
|
+
if (!rmux) return void 0;
|
|
134
|
+
return rmux.session(target).pane(0, 0).captureText().catch((error) => {
|
|
135
|
+
process.emitWarning(`Could not capture RMUX target ${target}: ${errorMessage(error)}`);
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
get(name) {
|
|
139
|
+
return this.runs.get(name);
|
|
140
|
+
}
|
|
141
|
+
readOutcome(id, sessionId) {
|
|
142
|
+
return readExitMetadata(this.auxPaths(id, sessionId).exit);
|
|
143
|
+
}
|
|
144
|
+
trackCompletion(target, completion) {
|
|
145
|
+
this.completions.set(target, completion);
|
|
146
|
+
completion.finally(() => this.completions.delete(target)).catch((error) => process.emitWarning(`RMUX monitor failed for ${target}: ${errorMessage(error)}`));
|
|
147
|
+
}
|
|
148
|
+
client() {
|
|
149
|
+
this.clientPromise ??= this.resolveClient();
|
|
150
|
+
return this.clientPromise;
|
|
151
|
+
}
|
|
152
|
+
async resolveClient() {
|
|
153
|
+
const binaries = [resolveBundledRmuxBinary(import.meta.url, this.env), "rmux"].filter((value) => value !== void 0);
|
|
154
|
+
for (const binary of binaries) try {
|
|
155
|
+
if (binary !== "rmux") ensureExecutablePayload(binary);
|
|
156
|
+
const client = new RMUX({
|
|
157
|
+
binary,
|
|
158
|
+
socketName: socketName(this.paths.repositoryPath())
|
|
159
|
+
});
|
|
160
|
+
await client.capabilities();
|
|
161
|
+
return client;
|
|
162
|
+
} catch (error) {
|
|
163
|
+
process.emitWarning(`RMUX candidate ${binary} is unavailable: ${errorMessage(error)}`);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
prepareFiles(request, logPath, aux) {
|
|
167
|
+
cleanupSupervisorFiles(aux);
|
|
168
|
+
fs.writeFileSync(logPath, "", { mode: 384 });
|
|
169
|
+
const env = environment(request.sessionId, request.interactive, this.env);
|
|
170
|
+
const spec = {
|
|
171
|
+
command: request.command,
|
|
172
|
+
cwd: request.cwd,
|
|
173
|
+
env
|
|
174
|
+
};
|
|
175
|
+
writeCommandSpec(aux.spec, spec);
|
|
176
|
+
}
|
|
177
|
+
auxPaths(id, sessionId) {
|
|
178
|
+
return supervisorPaths(this.paths.stateDirectory(sessionId), id);
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* The sink the pane pipes into.
|
|
182
|
+
*
|
|
183
|
+
* An interactive run also asks for a raw copy: the scrubbed log it writes
|
|
184
|
+
* beside it has had cursor movement taken out, which is what a terminal
|
|
185
|
+
* needs most. Only interactive runs pay for it, because only they can be
|
|
186
|
+
* attached to.
|
|
187
|
+
*/
|
|
188
|
+
logPipeCommand(logPath, donePath, request) {
|
|
189
|
+
const id = path.basename(logPath, ".log");
|
|
190
|
+
return shellJoin([
|
|
191
|
+
process.execPath,
|
|
192
|
+
runtimeEntry("logSink"),
|
|
193
|
+
logPath,
|
|
194
|
+
this.paths.rotatedLogPathFor(id),
|
|
195
|
+
String(getLogMaxBytes(this.env)),
|
|
196
|
+
donePath,
|
|
197
|
+
...request.interactive ? [this.paths.rawLogPathFor(id)] : []
|
|
198
|
+
]);
|
|
199
|
+
}
|
|
200
|
+
async monitor(rmux, pane, target, aux) {
|
|
201
|
+
try {
|
|
202
|
+
const paneCode = await waitForRunEnd(rmux, target, aux.exit);
|
|
203
|
+
await waitForLogDrain(rmux, target, aux.logDone);
|
|
204
|
+
return readExitMetadata(aux.exit) ?? {
|
|
205
|
+
code: paneCode,
|
|
206
|
+
signal: null
|
|
207
|
+
};
|
|
208
|
+
} finally {
|
|
209
|
+
let timer;
|
|
210
|
+
const cleanup = async () => {
|
|
211
|
+
if (!await sessionMissing(rmux, target)) await pane.server.session(target).kill();
|
|
212
|
+
};
|
|
213
|
+
try {
|
|
214
|
+
await Promise.race([cleanup().catch((error) => process.emitWarning(`Could not clean up completed RMUX target ${target}: ${errorMessage(error)}`)), new Promise((resolve) => {
|
|
215
|
+
timer = setTimeout(() => {
|
|
216
|
+
process.emitWarning(`Timed out cleaning up RMUX target ${target} after ${STOP_CLOSE_TIMEOUT_MS}ms`);
|
|
217
|
+
resolve();
|
|
218
|
+
}, STOP_CLOSE_TIMEOUT_MS);
|
|
219
|
+
})]);
|
|
220
|
+
} finally {
|
|
221
|
+
if (timer) clearTimeout(timer);
|
|
222
|
+
cleanupSupervisorFiles(aux);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
interactiveRun(handle, pane, completion) {
|
|
227
|
+
let screen = "";
|
|
228
|
+
let active = true;
|
|
229
|
+
const handlers = /* @__PURE__ */ new Set();
|
|
230
|
+
const refresh = async () => {
|
|
231
|
+
while (active) {
|
|
232
|
+
const next = await pane.captureText().catch((error) => {
|
|
233
|
+
process.emitWarning(`Could not capture RMUX screen for ${handle.name}: ${errorMessage(error)}`);
|
|
234
|
+
return screen;
|
|
235
|
+
});
|
|
236
|
+
if (next !== screen) {
|
|
237
|
+
screen = next;
|
|
238
|
+
for (const handler of handlers) handler(next);
|
|
239
|
+
}
|
|
240
|
+
await delay(100);
|
|
241
|
+
}
|
|
242
|
+
};
|
|
243
|
+
refresh();
|
|
244
|
+
completion.finally(() => {
|
|
245
|
+
active = false;
|
|
246
|
+
}).catch((error) => process.emitWarning(`RMUX interactive completion failed for ${handle.name}: ${errorMessage(error)}`));
|
|
247
|
+
return {
|
|
248
|
+
...handle,
|
|
249
|
+
write: (text) => {
|
|
250
|
+
pane.sendText(text).catch((error) => process.emitWarning(errorMessage(error)));
|
|
251
|
+
},
|
|
252
|
+
screen: () => screen,
|
|
253
|
+
onData: (handler) => {
|
|
254
|
+
handlers.add(handler);
|
|
255
|
+
return () => handlers.delete(handler);
|
|
256
|
+
},
|
|
257
|
+
resize: (cols, rows) => {
|
|
258
|
+
pane.resize({
|
|
259
|
+
width: cols,
|
|
260
|
+
height: rows
|
|
261
|
+
}).catch((error) => process.emitWarning(errorMessage(error)));
|
|
262
|
+
}
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
};
|
|
266
|
+
function rmuxPackageForTarget(platform, architecture) {
|
|
267
|
+
const target = `${platform}-${architecture}`;
|
|
268
|
+
const packageName = PACKAGE_BY_PLATFORM[target];
|
|
269
|
+
if (!packageName) process.emitWarning(`Bundled RMUX binary is unavailable for unsupported target ${target}`);
|
|
270
|
+
return packageName;
|
|
271
|
+
}
|
|
272
|
+
function resolveBundledRmuxBinary(moduleUrl = import.meta.url, env = process.env) {
|
|
273
|
+
const configured = env[RMUX_BINARY_ENV];
|
|
274
|
+
if (configured !== void 0 && configured !== "") return configured;
|
|
275
|
+
const packageName = rmuxPackageForTarget(process.platform, process.arch);
|
|
276
|
+
if (!packageName) return void 0;
|
|
277
|
+
try {
|
|
278
|
+
const manifest = createRequire(moduleUrl).resolve(`${packageName}/package.json`);
|
|
279
|
+
return path.join(path.dirname(manifest), VENDOR_DIRECTORY, "bin", "rmux");
|
|
280
|
+
} catch (error) {
|
|
281
|
+
process.emitWarning(`Bundled RMUX binary is unavailable for ${packageName}: ${errorMessage(error)}`);
|
|
282
|
+
return;
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* Make the bundled payload runnable before the launcher is spawned.
|
|
287
|
+
*
|
|
288
|
+
* The prebuilt packages reach npm with plain 0644 files, so the executable bit
|
|
289
|
+
* the build set is not what lands on a user machine. Restoring it on the one
|
|
290
|
+
* binary we spawn is not enough: rmux execs two files of its own,
|
|
291
|
+
* `bin/rmux-daemon` and `libexec/rmux/rmux`, and the launcher fails on that
|
|
292
|
+
* first exec with a permission error. Every file the payload ships is restored
|
|
293
|
+
* here instead, which also covers a helper a later rmux release adds.
|
|
294
|
+
*
|
|
295
|
+
* A configured override (PO_RMUX_BINARY) usually points at a stand-alone
|
|
296
|
+
* binary, so only paths that really sit inside a package vendor tree get the
|
|
297
|
+
* walk. Files that are already executable are left untouched, since chmod on a
|
|
298
|
+
* binary owned by someone else would throw and drop an otherwise usable
|
|
299
|
+
* candidate.
|
|
300
|
+
*/
|
|
301
|
+
function ensureExecutablePayload(binary) {
|
|
302
|
+
const vendor = path.resolve(path.dirname(binary), "..");
|
|
303
|
+
const payload = path.basename(vendor) === "vendor" ? fs.readdirSync(vendor, {
|
|
304
|
+
recursive: true,
|
|
305
|
+
withFileTypes: true
|
|
306
|
+
}).filter((entry) => entry.isFile()).map((entry) => path.join(entry.parentPath, entry.name)) : [binary];
|
|
307
|
+
for (const file of payload) if ((fs.statSync(file).mode & 73) === 0) fs.chmodSync(file, 493);
|
|
308
|
+
}
|
|
309
|
+
function socketName(repositoryPath) {
|
|
310
|
+
const hash = createHash("sha256").update(repositoryPath).digest("hex").slice(0, 12);
|
|
311
|
+
return `${SESSION_PREFIX}${hash}`;
|
|
312
|
+
}
|
|
313
|
+
function environment(sessionId, interactive, env) {
|
|
314
|
+
const values = {
|
|
315
|
+
...env,
|
|
316
|
+
...interactive ? {} : {
|
|
317
|
+
...NON_INTERACTIVE_ENV,
|
|
318
|
+
...noninteractiveEnvironment(env)
|
|
319
|
+
},
|
|
320
|
+
...NO_TERMINAL_INPUT_ENV,
|
|
321
|
+
PI_SESSION_ID: sessionId
|
|
322
|
+
};
|
|
323
|
+
if (!interactive) delete values["FORCE_COLOR"];
|
|
324
|
+
return Object.fromEntries(Object.entries(values).filter((entry) => entry[1] !== void 0));
|
|
325
|
+
}
|
|
326
|
+
async function panePid(rmux, target) {
|
|
327
|
+
const response = await rmux.displayMessage(PANE_PID_FORMAT, { target });
|
|
328
|
+
const pid = reportedPid(typeof response["message"] === "string" ? response["message"] : "");
|
|
329
|
+
if (pid === void 0) throw new Error(`RMUX did not report a pane pid for ${target}`);
|
|
330
|
+
return pid;
|
|
331
|
+
}
|
|
332
|
+
/** A pane pid as rmux prints it, or nothing when the output holds no usable pid. */
|
|
333
|
+
function reportedPid(output) {
|
|
334
|
+
const pid = Number(output.trim());
|
|
335
|
+
return Number.isInteger(pid) && pid > 0 ? pid : void 0;
|
|
336
|
+
}
|
|
337
|
+
/**
|
|
338
|
+
* Waits for the run to end, preferring the supervisor's own record of it.
|
|
339
|
+
*
|
|
340
|
+
* The sidecar is written before the command's pane can end, and it outlives the
|
|
341
|
+
* server that the pane's exit takes down with it. Watching for it means a run
|
|
342
|
+
* that finishes inside a poll interval is observed when it finishes rather than
|
|
343
|
+
* on the next tick. Asking the server stays the fallback for a supervisor that
|
|
344
|
+
* died without recording anything.
|
|
345
|
+
*/
|
|
346
|
+
async function waitForRunEnd(rmux, target, exitPath) {
|
|
347
|
+
const landed = watchForFile(exitPath);
|
|
348
|
+
let active = true;
|
|
349
|
+
const readEvidence = async () => {
|
|
350
|
+
while (active) if (await landed.appeared(100)) return null;
|
|
351
|
+
return null;
|
|
352
|
+
};
|
|
353
|
+
const probePane = async () => {
|
|
354
|
+
while (active) {
|
|
355
|
+
await delay(100);
|
|
356
|
+
if (!active) return null;
|
|
357
|
+
const state = await readPaneExit(rmux, target);
|
|
358
|
+
if (state.exited) return state.code;
|
|
359
|
+
}
|
|
360
|
+
return null;
|
|
361
|
+
};
|
|
362
|
+
try {
|
|
363
|
+
return await Promise.race([readEvidence(), probePane()]);
|
|
364
|
+
} finally {
|
|
365
|
+
active = false;
|
|
366
|
+
landed.close();
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
/**
|
|
370
|
+
* Gives the log sink a moment to mark the log complete.
|
|
371
|
+
*
|
|
372
|
+
* Normal completion retains the session until the sink records its final
|
|
373
|
+
* writes. A lost session cannot guarantee a later marker, so it ends the wait.
|
|
374
|
+
*/
|
|
375
|
+
async function waitForLogDrain(rmux, target, donePath) {
|
|
376
|
+
const deadline = Date.now() + LOG_DRAIN_TIMEOUT_MS;
|
|
377
|
+
const landed = watchForFile(donePath);
|
|
378
|
+
let active = true;
|
|
379
|
+
const readEvidence = async () => {
|
|
380
|
+
while (active && Date.now() < deadline) if (await landed.appeared(25)) return;
|
|
381
|
+
};
|
|
382
|
+
const probeSession = async () => {
|
|
383
|
+
while (active && Date.now() < deadline) {
|
|
384
|
+
await delay(25);
|
|
385
|
+
if (!active) return;
|
|
386
|
+
if (await sessionMissing(rmux, target)) return;
|
|
387
|
+
}
|
|
388
|
+
};
|
|
389
|
+
try {
|
|
390
|
+
await Promise.race([readEvidence(), probeSession()]);
|
|
391
|
+
} finally {
|
|
392
|
+
active = false;
|
|
393
|
+
landed.close();
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
async function closeOwnedSession(rmux, target) {
|
|
397
|
+
return new Promise((resolve) => {
|
|
398
|
+
let settled = false;
|
|
399
|
+
const finish = (result) => {
|
|
400
|
+
if (settled) return;
|
|
401
|
+
settled = true;
|
|
402
|
+
clearTimeout(timer);
|
|
403
|
+
resolve(result);
|
|
404
|
+
};
|
|
405
|
+
const timer = setTimeout(() => {
|
|
406
|
+
process.emitWarning(`Timed out closing RMUX target ${target} after ${STOP_CLOSE_TIMEOUT_MS}ms`);
|
|
407
|
+
finish(false);
|
|
408
|
+
}, STOP_CLOSE_TIMEOUT_MS);
|
|
409
|
+
rmux.session(target).kill().then(() => finish(true), (error) => {
|
|
410
|
+
process.emitWarning(`Could not close RMUX target ${target}: ${errorMessage(error)}`);
|
|
411
|
+
finish(false);
|
|
412
|
+
});
|
|
413
|
+
});
|
|
414
|
+
}
|
|
415
|
+
async function waitForPaneStop(rmux, target, timeoutMs) {
|
|
416
|
+
const deadline = Date.now() + timeoutMs;
|
|
417
|
+
while (Date.now() < deadline) {
|
|
418
|
+
try {
|
|
419
|
+
if ((await readPaneExit(rmux, target)).exited) return true;
|
|
420
|
+
} catch (error) {
|
|
421
|
+
process.emitWarning(`Could not verify RMUX target ${target} stopped: ${errorMessage(error)}`);
|
|
422
|
+
return false;
|
|
423
|
+
}
|
|
424
|
+
await delay(100);
|
|
425
|
+
}
|
|
426
|
+
return false;
|
|
427
|
+
}
|
|
428
|
+
/**
|
|
429
|
+
* One formatted read answers both questions this poll asks, so watching a run
|
|
430
|
+
* costs the same single rmux call it always did.
|
|
431
|
+
*/
|
|
432
|
+
async function readPaneExit(rmux, target) {
|
|
433
|
+
let message;
|
|
434
|
+
try {
|
|
435
|
+
const response = await rmux.displayMessage(PANE_STATE_FORMAT, { target });
|
|
436
|
+
message = typeof response["message"] === "string" ? response["message"] : "";
|
|
437
|
+
} catch {
|
|
438
|
+
return {
|
|
439
|
+
exited: true,
|
|
440
|
+
code: null
|
|
441
|
+
};
|
|
442
|
+
}
|
|
443
|
+
const [dead, status, ...rest] = message.trim().split(":");
|
|
444
|
+
if (rest.join(":") === "") return {
|
|
445
|
+
exited: true,
|
|
446
|
+
code: null
|
|
447
|
+
};
|
|
448
|
+
if (dead === "1" || dead === "true") {
|
|
449
|
+
const code = Number(status);
|
|
450
|
+
return {
|
|
451
|
+
exited: true,
|
|
452
|
+
code: Number.isInteger(code) ? code : null
|
|
453
|
+
};
|
|
454
|
+
}
|
|
455
|
+
return {
|
|
456
|
+
exited: false,
|
|
457
|
+
code: null
|
|
458
|
+
};
|
|
459
|
+
}
|
|
460
|
+
/** A session that cannot be found, on a server that may itself be gone. */
|
|
461
|
+
async function sessionMissing(rmux, target) {
|
|
462
|
+
try {
|
|
463
|
+
return (await rmux.cmd("has-session", "-t", target)).returnCode !== 0;
|
|
464
|
+
} catch {
|
|
465
|
+
return true;
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
/**
|
|
469
|
+
* A pane that was already gone and a signal that could not be delivered are
|
|
470
|
+
* opposite answers to "is it stopped", so they are reported apart.
|
|
471
|
+
*/
|
|
472
|
+
function signalPane(pid, target) {
|
|
473
|
+
try {
|
|
474
|
+
process.kill(pid, "SIGTERM");
|
|
475
|
+
return "signalled";
|
|
476
|
+
} catch (error) {
|
|
477
|
+
if (error.code === "ESRCH") return "gone";
|
|
478
|
+
process.emitWarning(`Could not signal RMUX target ${target}: ${errorMessage(error)}`);
|
|
479
|
+
return "failed";
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
function readTail(target, maxBytes) {
|
|
483
|
+
let handle;
|
|
484
|
+
try {
|
|
485
|
+
const size = fs.statSync(target).size;
|
|
486
|
+
const bytes = Math.min(size, maxBytes);
|
|
487
|
+
const buffer = Buffer.alloc(bytes);
|
|
488
|
+
handle = fs.openSync(target, "r");
|
|
489
|
+
fs.readSync(handle, buffer, 0, bytes, size - bytes);
|
|
490
|
+
return buffer.toString("utf8");
|
|
491
|
+
} catch (error) {
|
|
492
|
+
if (error.code !== "ENOENT") process.emitWarning(`Could not read RMUX log ${target}: ${errorMessage(error)}`);
|
|
493
|
+
return "";
|
|
494
|
+
} finally {
|
|
495
|
+
if (handle !== void 0) fs.closeSync(handle);
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
function delay(ms) {
|
|
499
|
+
return new Promise((resolve) => {
|
|
500
|
+
setTimeout(resolve, ms).unref?.();
|
|
501
|
+
});
|
|
502
|
+
}
|
|
503
|
+
function errorMessage(error) {
|
|
504
|
+
return error instanceof Error ? error.message : String(error);
|
|
505
|
+
}
|
|
506
|
+
//#endregion
|
|
507
|
+
export { rmuxPackageForTarget as n, RmuxBackend as t };
|
|
508
|
+
|
|
509
|
+
//# sourceMappingURL=rmuxBackend-DfyQwJrc.mjs.map
|