@agimon-ai/doompi-runner 0.0.1-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 +47 -0
- package/dist/_virtual/_@oxc-project_runtime@0.143.0/helpers/esm/decorate.cjs +1 -0
- package/dist/_virtual/_@oxc-project_runtime@0.143.0/helpers/esm/decorate.mjs +1 -0
- package/dist/_virtual/_@oxc-project_runtime@0.143.0/helpers/esm/decorateMetadata.cjs +1 -0
- package/dist/_virtual/_@oxc-project_runtime@0.143.0/helpers/esm/decorateMetadata.mjs +1 -0
- package/dist/_virtual/_@oxc-project_runtime@0.143.0/helpers/esm/decorateParam.cjs +1 -0
- package/dist/_virtual/_@oxc-project_runtime@0.143.0/helpers/esm/decorateParam.mjs +1 -0
- package/dist/_virtual/_rolldown/runtime.cjs +1 -0
- package/dist/bin/cli.cjs +5 -0
- package/dist/bin/cli.cjs.map +1 -0
- package/dist/bin/cli.d.cts +5 -0
- package/dist/bin/cli.d.cts.map +1 -0
- package/dist/bin/cli.d.mts +5 -0
- package/dist/bin/cli.d.mts.map +1 -0
- package/dist/bin/cli.mjs +5 -0
- package/dist/bin/cli.mjs.map +1 -0
- package/dist/bin/logSink.cjs +2 -0
- package/dist/bin/logSink.cjs.map +1 -0
- package/dist/bin/logSink.d.cts +5 -0
- package/dist/bin/logSink.d.cts.map +1 -0
- package/dist/bin/logSink.d.mts +5 -0
- package/dist/bin/logSink.d.mts.map +1 -0
- package/dist/bin/logSink.mjs +2 -0
- package/dist/bin/logSink.mjs.map +1 -0
- package/dist/bin/runnerHost.cjs +2 -0
- package/dist/bin/runnerHost.cjs.map +1 -0
- package/dist/bin/runnerHost.d.cts +5 -0
- package/dist/bin/runnerHost.d.cts.map +1 -0
- package/dist/bin/runnerHost.d.mts +5 -0
- package/dist/bin/runnerHost.d.mts.map +1 -0
- package/dist/bin/runnerHost.mjs +2 -0
- package/dist/bin/runnerHost.mjs.map +1 -0
- package/dist/cli/cliApp.cjs +6 -0
- package/dist/cli/cliApp.cjs.map +1 -0
- package/dist/cli/cliApp.d.cts +23 -0
- package/dist/cli/cliApp.d.cts.map +1 -0
- package/dist/cli/cliApp.d.mts +23 -0
- package/dist/cli/cliApp.d.mts.map +1 -0
- package/dist/cli/cliApp.mjs +6 -0
- package/dist/cli/cliApp.mjs.map +1 -0
- package/dist/compaction.cjs +4 -0
- package/dist/compaction.cjs.map +1 -0
- package/dist/compaction.d.cts +14 -0
- package/dist/compaction.d.cts.map +1 -0
- package/dist/compaction.d.mts +14 -0
- package/dist/compaction.d.mts.map +1 -0
- package/dist/compaction.mjs +4 -0
- package/dist/compaction.mjs.map +1 -0
- package/dist/config.cjs +2 -0
- package/dist/config.cjs.map +1 -0
- package/dist/config.d.cts +32 -0
- package/dist/config.d.cts.map +1 -0
- package/dist/config.d.mts +32 -0
- package/dist/config.d.mts.map +1 -0
- package/dist/config.mjs +2 -0
- package/dist/config.mjs.map +1 -0
- package/dist/container/index.cjs +2 -0
- package/dist/container/index.cjs.map +1 -0
- package/dist/container/index.d.cts +14 -0
- package/dist/container/index.d.cts.map +1 -0
- package/dist/container/index.d.mts +14 -0
- package/dist/container/index.d.mts.map +1 -0
- package/dist/container/index.mjs +2 -0
- package/dist/container/index.mjs.map +1 -0
- package/dist/extension.cjs +3 -0
- package/dist/extension.cjs.map +1 -0
- package/dist/extension.d.cts +10 -0
- package/dist/extension.d.cts.map +1 -0
- package/dist/extension.d.mts +10 -0
- package/dist/extension.d.mts.map +1 -0
- package/dist/extension.mjs +3 -0
- package/dist/extension.mjs.map +1 -0
- package/dist/extensions/pi.cjs +2 -0
- package/dist/extensions/pi.cjs.map +1 -0
- package/dist/extensions/pi.d.cts +2 -0
- package/dist/extensions/pi.d.mts +2 -0
- package/dist/extensions/pi.mjs +2 -0
- package/dist/extensions/pi.mjs.map +1 -0
- package/dist/index.cjs +1 -0
- package/dist/index.d.cts +7 -0
- package/dist/index.d.mts +7 -0
- package/dist/index.mjs +1 -0
- package/dist/ptyProvider.cjs +2 -0
- package/dist/ptyProvider.cjs.map +1 -0
- package/dist/ptyProvider.d.cts +13 -0
- package/dist/ptyProvider.d.cts.map +1 -0
- package/dist/ptyProvider.d.mts +13 -0
- package/dist/ptyProvider.d.mts.map +1 -0
- package/dist/ptyProvider.mjs +2 -0
- package/dist/ptyProvider.mjs.map +1 -0
- package/dist/reconcile.cjs +2 -0
- package/dist/reconcile.cjs.map +1 -0
- package/dist/reconcile.d.cts +37 -0
- package/dist/reconcile.d.cts.map +1 -0
- package/dist/reconcile.d.mts +37 -0
- package/dist/reconcile.d.mts.map +1 -0
- package/dist/reconcile.mjs +2 -0
- package/dist/reconcile.mjs.map +1 -0
- package/dist/runnerSpec.cjs +2 -0
- package/dist/runnerSpec.cjs.map +1 -0
- package/dist/runnerSpec.d.cts +50 -0
- package/dist/runnerSpec.d.cts.map +1 -0
- package/dist/runnerSpec.d.mts +50 -0
- package/dist/runnerSpec.d.mts.map +1 -0
- package/dist/runnerSpec.mjs +2 -0
- package/dist/runnerSpec.mjs.map +1 -0
- package/dist/services/AnsiScrub/ansiScrub.cjs +5 -0
- package/dist/services/AnsiScrub/ansiScrub.cjs.map +1 -0
- package/dist/services/AnsiScrub/ansiScrub.d.cts +34 -0
- package/dist/services/AnsiScrub/ansiScrub.d.cts.map +1 -0
- package/dist/services/AnsiScrub/ansiScrub.d.mts +34 -0
- package/dist/services/AnsiScrub/ansiScrub.d.mts.map +1 -0
- package/dist/services/AnsiScrub/ansiScrub.mjs +5 -0
- package/dist/services/AnsiScrub/ansiScrub.mjs.map +1 -0
- package/dist/services/AnsiScrub/index.cjs +1 -0
- package/dist/services/AnsiScrub/index.d.cts +2 -0
- package/dist/services/AnsiScrub/index.d.mts +2 -0
- package/dist/services/AnsiScrub/index.mjs +1 -0
- package/dist/services/BashRunService/BashRunService.cjs +2 -0
- package/dist/services/BashRunService/BashRunService.cjs.map +1 -0
- package/dist/services/BashRunService/BashRunService.d.cts +38 -0
- package/dist/services/BashRunService/BashRunService.d.cts.map +1 -0
- package/dist/services/BashRunService/BashRunService.d.mts +38 -0
- package/dist/services/BashRunService/BashRunService.d.mts.map +1 -0
- package/dist/services/BashRunService/BashRunService.mjs +2 -0
- package/dist/services/BashRunService/BashRunService.mjs.map +1 -0
- package/dist/services/BashRunService/index.cjs +1 -0
- package/dist/services/BashRunService/index.d.cts +3 -0
- package/dist/services/BashRunService/index.d.mts +3 -0
- package/dist/services/BashRunService/index.mjs +1 -0
- package/dist/services/BashRunService/types.d.cts +62 -0
- package/dist/services/BashRunService/types.d.cts.map +1 -0
- package/dist/services/BashRunService/types.d.mts +62 -0
- package/dist/services/BashRunService/types.d.mts.map +1 -0
- package/dist/services/Clock/SystemClock.cjs +2 -0
- package/dist/services/Clock/SystemClock.cjs.map +1 -0
- package/dist/services/Clock/SystemClock.d.cts +11 -0
- package/dist/services/Clock/SystemClock.d.cts.map +1 -0
- package/dist/services/Clock/SystemClock.d.mts +11 -0
- package/dist/services/Clock/SystemClock.d.mts.map +1 -0
- package/dist/services/Clock/SystemClock.mjs +2 -0
- package/dist/services/Clock/SystemClock.mjs.map +1 -0
- package/dist/services/Clock/index.cjs +1 -0
- package/dist/services/Clock/index.d.cts +3 -0
- package/dist/services/Clock/index.d.mts +3 -0
- package/dist/services/Clock/index.mjs +1 -0
- package/dist/services/Clock/types.d.cts +11 -0
- package/dist/services/Clock/types.d.cts.map +1 -0
- package/dist/services/Clock/types.d.mts +11 -0
- package/dist/services/Clock/types.d.mts.map +1 -0
- package/dist/services/Launcher/Launcher.cjs +2 -0
- package/dist/services/Launcher/Launcher.cjs.map +1 -0
- package/dist/services/Launcher/Launcher.d.cts +27 -0
- package/dist/services/Launcher/Launcher.d.cts.map +1 -0
- package/dist/services/Launcher/Launcher.d.mts +27 -0
- package/dist/services/Launcher/Launcher.d.mts.map +1 -0
- package/dist/services/Launcher/Launcher.mjs +2 -0
- package/dist/services/Launcher/Launcher.mjs.map +1 -0
- package/dist/services/Launcher/index.cjs +1 -0
- package/dist/services/Launcher/index.d.cts +3 -0
- package/dist/services/Launcher/index.d.mts +3 -0
- package/dist/services/Launcher/index.mjs +1 -0
- package/dist/services/Launcher/types.d.cts +40 -0
- package/dist/services/Launcher/types.d.cts.map +1 -0
- package/dist/services/Launcher/types.d.mts +40 -0
- package/dist/services/Launcher/types.d.mts.map +1 -0
- package/dist/services/Lifeline/NodeLifeline.cjs +2 -0
- package/dist/services/Lifeline/NodeLifeline.cjs.map +1 -0
- package/dist/services/Lifeline/NodeLifeline.d.cts +21 -0
- package/dist/services/Lifeline/NodeLifeline.d.cts.map +1 -0
- package/dist/services/Lifeline/NodeLifeline.d.mts +21 -0
- package/dist/services/Lifeline/NodeLifeline.d.mts.map +1 -0
- package/dist/services/Lifeline/NodeLifeline.mjs +2 -0
- package/dist/services/Lifeline/NodeLifeline.mjs.map +1 -0
- package/dist/services/Lifeline/client.cjs +2 -0
- package/dist/services/Lifeline/client.cjs.map +1 -0
- package/dist/services/Lifeline/client.d.cts +23 -0
- package/dist/services/Lifeline/client.d.cts.map +1 -0
- package/dist/services/Lifeline/client.d.mts +23 -0
- package/dist/services/Lifeline/client.d.mts.map +1 -0
- package/dist/services/Lifeline/client.mjs +2 -0
- package/dist/services/Lifeline/client.mjs.map +1 -0
- package/dist/services/Lifeline/index.cjs +1 -0
- package/dist/services/Lifeline/index.d.cts +4 -0
- package/dist/services/Lifeline/index.d.mts +4 -0
- package/dist/services/Lifeline/index.mjs +1 -0
- package/dist/services/Lifeline/types.d.cts +19 -0
- package/dist/services/Lifeline/types.d.cts.map +1 -0
- package/dist/services/Lifeline/types.d.mts +19 -0
- package/dist/services/Lifeline/types.d.mts.map +1 -0
- package/dist/services/LogFile/LogFile.cjs +2 -0
- package/dist/services/LogFile/LogFile.cjs.map +1 -0
- package/dist/services/LogFile/LogFile.d.cts +13 -0
- package/dist/services/LogFile/LogFile.d.cts.map +1 -0
- package/dist/services/LogFile/LogFile.d.mts +13 -0
- package/dist/services/LogFile/LogFile.d.mts.map +1 -0
- package/dist/services/LogFile/LogFile.mjs +2 -0
- package/dist/services/LogFile/LogFile.mjs.map +1 -0
- package/dist/services/LogFile/index.cjs +1 -0
- package/dist/services/LogFile/index.d.cts +3 -0
- package/dist/services/LogFile/index.d.mts +3 -0
- package/dist/services/LogFile/index.mjs +1 -0
- package/dist/services/LogFile/types.d.cts +16 -0
- package/dist/services/LogFile/types.d.cts.map +1 -0
- package/dist/services/LogFile/types.d.mts +16 -0
- package/dist/services/LogFile/types.d.mts.map +1 -0
- package/dist/services/LogReader/LogReader.cjs +10 -0
- package/dist/services/LogReader/LogReader.cjs.map +1 -0
- package/dist/services/LogReader/LogReader.d.cts +14 -0
- package/dist/services/LogReader/LogReader.d.cts.map +1 -0
- package/dist/services/LogReader/LogReader.d.mts +14 -0
- package/dist/services/LogReader/LogReader.d.mts.map +1 -0
- package/dist/services/LogReader/LogReader.mjs +10 -0
- package/dist/services/LogReader/LogReader.mjs.map +1 -0
- package/dist/services/LogReader/index.cjs +1 -0
- package/dist/services/LogReader/index.d.cts +3 -0
- package/dist/services/LogReader/index.d.mts +3 -0
- package/dist/services/LogReader/index.mjs +1 -0
- package/dist/services/LogReader/types.d.cts +27 -0
- package/dist/services/LogReader/types.d.cts.map +1 -0
- package/dist/services/LogReader/types.d.mts +27 -0
- package/dist/services/LogReader/types.d.mts.map +1 -0
- package/dist/services/ProcessControl/NodeProcessControl.cjs +2 -0
- package/dist/services/ProcessControl/NodeProcessControl.cjs.map +1 -0
- package/dist/services/ProcessControl/NodeProcessControl.d.cts +11 -0
- package/dist/services/ProcessControl/NodeProcessControl.d.cts.map +1 -0
- package/dist/services/ProcessControl/NodeProcessControl.d.mts +11 -0
- package/dist/services/ProcessControl/NodeProcessControl.d.mts.map +1 -0
- package/dist/services/ProcessControl/NodeProcessControl.mjs +2 -0
- package/dist/services/ProcessControl/NodeProcessControl.mjs.map +1 -0
- package/dist/services/ProcessControl/index.cjs +1 -0
- package/dist/services/ProcessControl/index.d.cts +3 -0
- package/dist/services/ProcessControl/index.d.mts +3 -0
- package/dist/services/ProcessControl/index.mjs +1 -0
- package/dist/services/ProcessControl/types.d.cts +14 -0
- package/dist/services/ProcessControl/types.d.cts.map +1 -0
- package/dist/services/ProcessControl/types.d.mts +14 -0
- package/dist/services/ProcessControl/types.d.mts.map +1 -0
- package/dist/services/PtyHost/PtyHost.cjs +5 -0
- package/dist/services/PtyHost/PtyHost.cjs.map +1 -0
- package/dist/services/PtyHost/PtyHost.d.cts +28 -0
- package/dist/services/PtyHost/PtyHost.d.cts.map +1 -0
- package/dist/services/PtyHost/PtyHost.d.mts +28 -0
- package/dist/services/PtyHost/PtyHost.d.mts.map +1 -0
- package/dist/services/PtyHost/PtyHost.mjs +5 -0
- package/dist/services/PtyHost/PtyHost.mjs.map +1 -0
- package/dist/services/PtyHost/index.cjs +1 -0
- package/dist/services/PtyHost/index.d.cts +3 -0
- package/dist/services/PtyHost/index.d.mts +3 -0
- package/dist/services/PtyHost/index.mjs +1 -0
- package/dist/services/PtyHost/types.d.cts +39 -0
- package/dist/services/PtyHost/types.d.cts.map +1 -0
- package/dist/services/PtyHost/types.d.mts +39 -0
- package/dist/services/PtyHost/types.d.mts.map +1 -0
- package/dist/services/PtySpawner/NodePtySpawner.cjs +2 -0
- package/dist/services/PtySpawner/NodePtySpawner.cjs.map +1 -0
- package/dist/services/PtySpawner/NodePtySpawner.d.cts +18 -0
- package/dist/services/PtySpawner/NodePtySpawner.d.cts.map +1 -0
- package/dist/services/PtySpawner/NodePtySpawner.d.mts +18 -0
- package/dist/services/PtySpawner/NodePtySpawner.d.mts.map +1 -0
- package/dist/services/PtySpawner/NodePtySpawner.mjs +2 -0
- package/dist/services/PtySpawner/NodePtySpawner.mjs.map +1 -0
- package/dist/services/PtySpawner/index.cjs +1 -0
- package/dist/services/PtySpawner/index.d.cts +3 -0
- package/dist/services/PtySpawner/index.d.mts +3 -0
- package/dist/services/PtySpawner/index.mjs +1 -0
- package/dist/services/PtySpawner/types.d.cts +28 -0
- package/dist/services/PtySpawner/types.d.cts.map +1 -0
- package/dist/services/PtySpawner/types.d.mts +28 -0
- package/dist/services/PtySpawner/types.d.mts.map +1 -0
- package/dist/services/RmuxBackend/RmuxBackend.cjs +2 -0
- package/dist/services/RmuxBackend/RmuxBackend.cjs.map +1 -0
- package/dist/services/RmuxBackend/RmuxBackend.d.cts +36 -0
- package/dist/services/RmuxBackend/RmuxBackend.d.cts.map +1 -0
- package/dist/services/RmuxBackend/RmuxBackend.d.mts +36 -0
- package/dist/services/RmuxBackend/RmuxBackend.d.mts.map +1 -0
- package/dist/services/RmuxBackend/RmuxBackend.mjs +2 -0
- package/dist/services/RmuxBackend/RmuxBackend.mjs.map +1 -0
- package/dist/services/RmuxBackend/index.cjs +1 -0
- package/dist/services/RmuxBackend/index.d.cts +3 -0
- package/dist/services/RmuxBackend/index.d.mts +3 -0
- package/dist/services/RmuxBackend/index.mjs +1 -0
- package/dist/services/RmuxBackend/types.d.cts +29 -0
- package/dist/services/RmuxBackend/types.d.cts.map +1 -0
- package/dist/services/RmuxBackend/types.d.mts +29 -0
- package/dist/services/RmuxBackend/types.d.mts.map +1 -0
- package/dist/services/RunnerNamer/RunnerNamer.cjs +2 -0
- package/dist/services/RunnerNamer/RunnerNamer.cjs.map +1 -0
- package/dist/services/RunnerNamer/RunnerNamer.d.cts +13 -0
- package/dist/services/RunnerNamer/RunnerNamer.d.cts.map +1 -0
- package/dist/services/RunnerNamer/RunnerNamer.d.mts +13 -0
- package/dist/services/RunnerNamer/RunnerNamer.d.mts.map +1 -0
- package/dist/services/RunnerNamer/RunnerNamer.mjs +2 -0
- package/dist/services/RunnerNamer/RunnerNamer.mjs.map +1 -0
- package/dist/services/RunnerNamer/index.cjs +1 -0
- package/dist/services/RunnerNamer/index.d.cts +3 -0
- package/dist/services/RunnerNamer/index.d.mts +3 -0
- package/dist/services/RunnerNamer/index.mjs +1 -0
- package/dist/services/RunnerNamer/types.d.cts +12 -0
- package/dist/services/RunnerNamer/types.d.cts.map +1 -0
- package/dist/services/RunnerNamer/types.d.mts +12 -0
- package/dist/services/RunnerNamer/types.d.mts.map +1 -0
- package/dist/services/RunnerPaths/RunnerPaths.cjs +2 -0
- package/dist/services/RunnerPaths/RunnerPaths.cjs.map +1 -0
- package/dist/services/RunnerPaths/RunnerPaths.d.cts +31 -0
- package/dist/services/RunnerPaths/RunnerPaths.d.cts.map +1 -0
- package/dist/services/RunnerPaths/RunnerPaths.d.mts +31 -0
- package/dist/services/RunnerPaths/RunnerPaths.d.mts.map +1 -0
- package/dist/services/RunnerPaths/RunnerPaths.mjs +2 -0
- package/dist/services/RunnerPaths/RunnerPaths.mjs.map +1 -0
- package/dist/services/RunnerPaths/index.cjs +1 -0
- package/dist/services/RunnerPaths/index.d.cts +3 -0
- package/dist/services/RunnerPaths/index.d.mts +3 -0
- package/dist/services/RunnerPaths/index.mjs +1 -0
- package/dist/services/RunnerPaths/types.d.cts +33 -0
- package/dist/services/RunnerPaths/types.d.cts.map +1 -0
- package/dist/services/RunnerPaths/types.d.mts +33 -0
- package/dist/services/RunnerPaths/types.d.mts.map +1 -0
- package/dist/services/RunnerRegistry/RunnerRegistry.cjs +2 -0
- package/dist/services/RunnerRegistry/RunnerRegistry.cjs.map +1 -0
- package/dist/services/RunnerRegistry/RunnerRegistry.d.cts +40 -0
- package/dist/services/RunnerRegistry/RunnerRegistry.d.cts.map +1 -0
- package/dist/services/RunnerRegistry/RunnerRegistry.d.mts +40 -0
- package/dist/services/RunnerRegistry/RunnerRegistry.d.mts.map +1 -0
- package/dist/services/RunnerRegistry/RunnerRegistry.mjs +2 -0
- package/dist/services/RunnerRegistry/RunnerRegistry.mjs.map +1 -0
- package/dist/services/RunnerRegistry/index.cjs +1 -0
- package/dist/services/RunnerRegistry/index.d.cts +3 -0
- package/dist/services/RunnerRegistry/index.d.mts +3 -0
- package/dist/services/RunnerRegistry/index.mjs +1 -0
- package/dist/services/RunnerRegistry/types.d.cts +98 -0
- package/dist/services/RunnerRegistry/types.d.cts.map +1 -0
- package/dist/services/RunnerRegistry/types.d.mts +98 -0
- package/dist/services/RunnerRegistry/types.d.mts.map +1 -0
- package/dist/services/Spawner/NodeSpawner.cjs +2 -0
- package/dist/services/Spawner/NodeSpawner.cjs.map +1 -0
- package/dist/services/Spawner/NodeSpawner.d.cts +10 -0
- package/dist/services/Spawner/NodeSpawner.d.cts.map +1 -0
- package/dist/services/Spawner/NodeSpawner.d.mts +10 -0
- package/dist/services/Spawner/NodeSpawner.d.mts.map +1 -0
- package/dist/services/Spawner/NodeSpawner.mjs +2 -0
- package/dist/services/Spawner/NodeSpawner.mjs.map +1 -0
- package/dist/services/Spawner/index.cjs +1 -0
- package/dist/services/Spawner/index.d.cts +3 -0
- package/dist/services/Spawner/index.d.mts +3 -0
- package/dist/services/Spawner/index.mjs +1 -0
- package/dist/services/Spawner/types.d.cts +31 -0
- package/dist/services/Spawner/types.d.cts.map +1 -0
- package/dist/services/Spawner/types.d.mts +31 -0
- package/dist/services/Spawner/types.d.mts.map +1 -0
- package/dist/session.cjs +2 -0
- package/dist/session.cjs.map +1 -0
- package/dist/session.d.cts +10 -0
- package/dist/session.d.cts.map +1 -0
- package/dist/session.d.mts +10 -0
- package/dist/session.d.mts.map +1 -0
- package/dist/session.mjs +2 -0
- package/dist/session.mjs.map +1 -0
- package/dist/tool/bashTool.cjs +7 -0
- package/dist/tool/bashTool.cjs.map +1 -0
- package/dist/tool/bashTool.d.cts +25 -0
- package/dist/tool/bashTool.d.cts.map +1 -0
- package/dist/tool/bashTool.d.mts +25 -0
- package/dist/tool/bashTool.d.mts.map +1 -0
- package/dist/tool/bashTool.mjs +7 -0
- package/dist/tool/bashTool.mjs.map +1 -0
- package/dist/tool/responseEnvelope.cjs +10 -0
- package/dist/tool/responseEnvelope.cjs.map +1 -0
- package/dist/tool/responseEnvelope.d.cts +45 -0
- package/dist/tool/responseEnvelope.d.cts.map +1 -0
- package/dist/tool/responseEnvelope.d.mts +45 -0
- package/dist/tool/responseEnvelope.d.mts.map +1 -0
- package/dist/tool/responseEnvelope.mjs +10 -0
- package/dist/tool/responseEnvelope.mjs.map +1 -0
- package/dist/tool/schema.cjs +2 -0
- package/dist/tool/schema.cjs.map +1 -0
- package/dist/tool/schema.d.cts +25 -0
- package/dist/tool/schema.d.cts.map +1 -0
- package/dist/tool/schema.d.mts +25 -0
- package/dist/tool/schema.d.mts.map +1 -0
- package/dist/tool/schema.mjs +2 -0
- package/dist/tool/schema.mjs.map +1 -0
- package/dist/tui/bashRender.cjs +8 -0
- package/dist/tui/bashRender.cjs.map +1 -0
- package/dist/tui/bashRender.d.cts +51 -0
- package/dist/tui/bashRender.d.cts.map +1 -0
- package/dist/tui/bashRender.d.mts +51 -0
- package/dist/tui/bashRender.d.mts.map +1 -0
- package/dist/tui/bashRender.mjs +8 -0
- package/dist/tui/bashRender.mjs.map +1 -0
- package/dist/tui/format.cjs +2 -0
- package/dist/tui/format.cjs.map +1 -0
- package/dist/tui/format.d.cts +25 -0
- package/dist/tui/format.d.cts.map +1 -0
- package/dist/tui/format.d.mts +25 -0
- package/dist/tui/format.d.mts.map +1 -0
- package/dist/tui/format.mjs +2 -0
- package/dist/tui/format.mjs.map +1 -0
- package/dist/tui/runnerSpace.cjs +6 -0
- package/dist/tui/runnerSpace.cjs.map +1 -0
- package/dist/tui/runnerSpace.d.cts +52 -0
- package/dist/tui/runnerSpace.d.cts.map +1 -0
- package/dist/tui/runnerSpace.d.mts +52 -0
- package/dist/tui/runnerSpace.d.mts.map +1 -0
- package/dist/tui/runnerSpace.mjs +6 -0
- package/dist/tui/runnerSpace.mjs.map +1 -0
- package/dist/types.cjs +2 -0
- package/dist/types.cjs.map +1 -0
- package/dist/types.d.cts +28 -0
- package/dist/types.d.cts.map +1 -0
- package/dist/types.d.mts +28 -0
- package/dist/types.d.mts.map +1 -0
- package/dist/types.mjs +2 -0
- package/dist/types.mjs.map +1 -0
- package/package.json +335 -0
- package/skills/doom-runner/SKILL.md +69 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { IClock } from "../Clock/types.mjs";
|
|
2
|
+
import "../Clock/index.mjs";
|
|
3
|
+
import { ILogFile } from "../LogFile/types.mjs";
|
|
4
|
+
import "../LogFile/index.mjs";
|
|
5
|
+
import { IProcessControl } from "../ProcessControl/types.mjs";
|
|
6
|
+
import "../ProcessControl/index.mjs";
|
|
7
|
+
import { IPtySpawner } from "../PtySpawner/types.mjs";
|
|
8
|
+
import "../PtySpawner/index.mjs";
|
|
9
|
+
import { IPtyHost, PtyLaunchRequest, PtyRun } from "./types.mjs";
|
|
10
|
+
import "reflect-metadata/lite";
|
|
11
|
+
//#region src/services/PtyHost/PtyHost.d.ts
|
|
12
|
+
declare class PtyHost implements IPtyHost {
|
|
13
|
+
private readonly spawner;
|
|
14
|
+
private readonly logFile;
|
|
15
|
+
private readonly processControl;
|
|
16
|
+
private readonly clock;
|
|
17
|
+
private readonly runs;
|
|
18
|
+
constructor(spawner: IPtySpawner, logFile: ILogFile, processControl: IProcessControl, clock: IClock);
|
|
19
|
+
launch(request: PtyLaunchRequest): Promise<PtyRun>;
|
|
20
|
+
get(name: string): PtyRun | undefined;
|
|
21
|
+
write(name: string, text: string): boolean;
|
|
22
|
+
list(): PtyRun[];
|
|
23
|
+
disposeAll(): Promise<void>;
|
|
24
|
+
private stopChild;
|
|
25
|
+
}
|
|
26
|
+
//#endregion
|
|
27
|
+
export { PtyHost };
|
|
28
|
+
//# sourceMappingURL=PtyHost.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PtyHost.d.mts","names":[],"sources":["../../../src/services/PtyHost/PtyHost.ts"],"mappings":";;;;;;;;;;;cAkCa,mBAAmB;mBAIe;mBACH;mBACO;mBACT;mBANvB;EAG4B,YAAA,SAAS,aACZ,SAAS,UACF,gBAAgB,iBACzB,OAAO;EAGzC,OAAO,SAAS,mBAAmB,QAAQ;EAyEjD,IAAI,eAAe;EAInB,MAAM,cAAc;EAOpB,QAAQ;EAIF,cAAc;UAMN"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import{getResultMaxBytes as e}from"../../config.mjs";import{TYPES as t}from"../../types.mjs";import n from"../../_virtual/_@oxc-project_runtime@0.143.0/helpers/esm/decorateMetadata.mjs";import r from"../../_virtual/_@oxc-project_runtime@0.143.0/helpers/esm/decorateParam.mjs";import i from"../../_virtual/_@oxc-project_runtime@0.143.0/helpers/esm/decorate.mjs";import{NO_TERMINAL_INPUT_ENV as a}from"../../runnerSpec.mjs";import{PI_SESSION_ID_ENV as o}from"../../session.mjs";import{scrubTerminalOutput as s}from"../AnsiScrub/ansiScrub.mjs";import"../AnsiScrub/index.mjs";import{createRequire as c}from"node:module";import{inject as l,injectable as u}from"inversify";import"reflect-metadata/lite";const{Terminal:d}=c(import.meta.url)(`@xterm/headless`);let f=class{spawner;logFile;processControl;clock;runs=new Map;constructor(e,t,n,r){this.spawner=e,this.logFile=t,this.processControl=n,this.clock=r}async launch(t){let n=t.cols??120,r=t.rows??30,i=this.logFile.open(t.id),c=new d({cols:n,rows:r,scrollback:2e3,allowProposedApi:!0}),l=e()*2,u=await this.spawner.spawn({command:t.command,cwd:t.cwd,env:{...process.env,...a,[o]:t.sessionId},cols:n,rows:r}),f=``,m=!0,h=!1,g=()=>void 0,_=new Promise(e=>{g=e}),v=new Set;u.onData(e=>{c.write(e);let t=s(e);i.append(t),m&&(f+=t,f.length>l&&(f=f.slice(-l)));for(let t of v)t(e)}),u.onExit(e=>{h||(h=!0,this.runs.delete(t.name),i.close(),g({code:e.exitCode,signal:null}))});let y={id:t.id,name:t.name,pid:u.pid,logPath:i.path,backend:`native`,output:()=>f,completion:()=>_,detach:()=>{m=!1,f=``},stop:()=>this.stopChild(u,t.name),write:e=>u.write(e),screen:()=>p(c),onData:e=>(v.add(e),()=>v.delete(e)),resize:(e,t)=>{u.resize(e,t),c.resize(e,t)}};return this.runs.set(t.name,y),y}get(e){return this.runs.get(e)}write(e,t){let n=this.runs.get(e);return n?(n.write(t.endsWith(`
|
|
2
|
+
`)?t:`${t}
|
|
3
|
+
`),!0):!1}list(){return[...this.runs.values()]}async disposeAll(){let e=[...this.runs.values()];this.runs.clear();for(let t of e)await t.stop()}async stopChild(e,t){if(this.runs.delete(t),!this.processControl.isAlive(e.pid))return!1;e.kill(`SIGTERM`);let n=this.clock.now()+2e3;for(;this.clock.now()<n;){if(!this.processControl.isAlive(e.pid))return!0;await new Promise(e=>{this.clock.after(100,e)})}return e.kill(`SIGKILL`),!0}};f=i([u(),r(0,l(t.PtySpawner)),r(1,l(t.LogFile)),r(2,l(t.ProcessControl)),r(3,l(t.Clock)),n(`design:paramtypes`,[Object,Object,Object,Object])],f);function p(e){let t=e.buffer.active,n=[];for(let r=t.baseY;r<t.baseY+e.rows;r+=1)n.push(t.getLine(r)?.translateToString(!0)??``);for(;n.length>0&&n.at(-1)===``;)n.pop();return n.join(`
|
|
4
|
+
`)}export{f as PtyHost};
|
|
5
|
+
//# sourceMappingURL=PtyHost.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PtyHost.mjs","names":[],"sources":["../../../src/services/PtyHost/PtyHost.ts"],"sourcesContent":["import { createRequire } from 'node:module';\nimport type { Terminal } from '@xterm/headless';\nimport { inject, injectable } from 'inversify';\nimport 'reflect-metadata/lite';\nimport { getResultMaxBytes } from '../../config.ts';\nimport { NO_TERMINAL_INPUT_ENV } from '../../runnerSpec.ts';\nimport { TYPES } from '../../types.ts';\nimport { scrubTerminalOutput } from '../AnsiScrub/index.ts';\nimport type { IClock } from '../Clock/index.ts';\nimport type { ILogFile } from '../LogFile/index.ts';\nimport type { IProcessControl } from '../ProcessControl/index.ts';\nimport type { IPtySpawner, PtyProcess } from '../PtySpawner/index.ts';\nimport type { ExitResult } from '../Spawner/index.ts';\nimport type { IPtyHost, PtyLaunchRequest, PtyRun } from './types.ts';\nimport { PI_SESSION_ID_ENV } from '../../session.ts';\n\nconst DEFAULT_COLS = 120;\nconst DEFAULT_ROWS = 30;\n/** Enough history for the overlay to scroll without holding a whole build. */\nconst SCROLLBACK = 2_000;\nconst MEMORY_BUFFER_FACTOR = 2;\nconst TERM_GRACE_MS = 2_000;\nconst LIVENESS_POLL_MS = 100;\nconst NEWLINE = '\\n';\n\n/**\n * `@xterm/headless` publishes CommonJS, and Node's ESM loader cannot detect its\n * named exports, so it is required rather than imported.\n */\nconst { Terminal: HeadlessTerminal } = createRequire(import.meta.url)(\n '@xterm/headless',\n) as typeof import('@xterm/headless');\n\n@injectable()\nexport class PtyHost implements IPtyHost {\n private readonly runs = new Map<string, PtyRun>();\n\n constructor(\n @inject(TYPES.PtySpawner) private readonly spawner: IPtySpawner,\n @inject(TYPES.LogFile) private readonly logFile: ILogFile,\n @inject(TYPES.ProcessControl) private readonly processControl: IProcessControl,\n @inject(TYPES.Clock) private readonly clock: IClock,\n ) {}\n\n async launch(request: PtyLaunchRequest): Promise<PtyRun> {\n const cols = request.cols ?? DEFAULT_COLS;\n const rows = request.rows ?? DEFAULT_ROWS;\n const writer = this.logFile.open(request.id);\n const terminal = new HeadlessTerminal({ cols, rows, scrollback: SCROLLBACK, allowProposedApi: true });\n const memoryLimit = getResultMaxBytes() * MEMORY_BUFFER_FACTOR;\n\n const child = await this.spawner.spawn({\n command: request.command,\n cwd: request.cwd,\n env: { ...process.env, ...NO_TERMINAL_INPUT_ENV, [PI_SESSION_ID_ENV]: request.sessionId },\n cols,\n rows,\n });\n\n let buffer = '';\n let buffering = true;\n let settled = false;\n let resolveCompletion: (result: ExitResult) => void = () => undefined;\n const completion = new Promise<ExitResult>((resolve) => {\n resolveCompletion = resolve;\n });\n const dataHandlers = new Set<(data: string) => void>();\n\n child.onData((data) => {\n // The terminal keeps the screen; the log keeps text worth grepping.\n terminal.write(data);\n const scrubbed = scrubTerminalOutput(data);\n writer.append(scrubbed);\n if (buffering) {\n buffer += scrubbed;\n if (buffer.length > memoryLimit) buffer = buffer.slice(-memoryLimit);\n }\n for (const handler of dataHandlers) handler(data);\n });\n\n child.onExit((result) => {\n if (settled) return;\n settled = true;\n this.runs.delete(request.name);\n writer.close();\n resolveCompletion({ code: result.exitCode, signal: null });\n });\n\n const run: PtyRun = {\n id: request.id,\n name: request.name,\n pid: child.pid,\n logPath: writer.path,\n backend: 'native',\n output: () => buffer,\n completion: () => completion,\n detach: () => {\n buffering = false;\n buffer = '';\n },\n stop: () => this.stopChild(child, request.name),\n write: (text) => child.write(text),\n screen: () => renderScreen(terminal),\n onData: (handler) => {\n dataHandlers.add(handler);\n return () => dataHandlers.delete(handler);\n },\n resize: (nextCols, nextRows) => {\n child.resize(nextCols, nextRows);\n terminal.resize(nextCols, nextRows);\n },\n };\n\n this.runs.set(request.name, run);\n return run;\n }\n\n get(name: string): PtyRun | undefined {\n return this.runs.get(name);\n }\n\n write(name: string, text: string): boolean {\n const run = this.runs.get(name);\n if (!run) return false;\n run.write(text.endsWith(NEWLINE) ? text : `${text}${NEWLINE}`);\n return true;\n }\n\n list(): PtyRun[] {\n return [...this.runs.values()];\n }\n\n async disposeAll(): Promise<void> {\n const runs = [...this.runs.values()];\n this.runs.clear();\n for (const run of runs) await run.stop();\n }\n\n private async stopChild(child: PtyProcess, name: string): Promise<boolean> {\n this.runs.delete(name);\n if (!this.processControl.isAlive(child.pid)) return false;\n\n child.kill('SIGTERM');\n const deadline = this.clock.now() + TERM_GRACE_MS;\n while (this.clock.now() < deadline) {\n if (!this.processControl.isAlive(child.pid)) return true;\n await new Promise<void>((resolve) => {\n this.clock.after(LIVENESS_POLL_MS, resolve);\n });\n }\n child.kill('SIGKILL');\n return true;\n }\n}\n\n/** The visible rows, trimmed of trailing blanks, as plain text. */\nfunction renderScreen(terminal: Terminal): string {\n const buffer = terminal.buffer.active;\n const lines: string[] = [];\n for (let row = buffer.baseY; row < buffer.baseY + terminal.rows; row += 1) {\n lines.push(buffer.getLine(row)?.translateToString(true) ?? '');\n }\n while (lines.length > 0 && lines.at(-1) === '') lines.pop();\n return lines.join(NEWLINE);\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./PtyHost.cjs");Object.defineProperty(exports,"PtyHost",{enumerable:!0,get:function(){return e.PtyHost}});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{PtyHost as e}from"./PtyHost.mjs";export{e as PtyHost};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { RunHandle } from "../Launcher/types.cjs";
|
|
2
|
+
import "../Launcher/index.cjs";
|
|
3
|
+
//#region src/services/PtyHost/types.d.ts
|
|
4
|
+
/** A background run hosted on a pseudo terminal, so it can be typed at. */
|
|
5
|
+
interface PtyRun extends RunHandle {
|
|
6
|
+
/** Sends text to the terminal. A newline is appended by the caller. */
|
|
7
|
+
write(text: string): void;
|
|
8
|
+
/** The visible screen, as plain text, for the overlay. */
|
|
9
|
+
screen(): string;
|
|
10
|
+
/** Subscribes to raw terminal output. Returns an unsubscribe function. */
|
|
11
|
+
onData(handler: (data: string) => void): () => void;
|
|
12
|
+
resize(cols: number, rows: number): void;
|
|
13
|
+
}
|
|
14
|
+
interface PtyLaunchRequest {
|
|
15
|
+
id: string;
|
|
16
|
+
name: string;
|
|
17
|
+
command: string;
|
|
18
|
+
cwd: string;
|
|
19
|
+
sessionId: string;
|
|
20
|
+
cols?: number;
|
|
21
|
+
rows?: number;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Owns every pseudo terminal this session started.
|
|
25
|
+
*
|
|
26
|
+
* A PTY cannot outlive its host process, so unlike detached subprocesses these
|
|
27
|
+
* runs are only reachable from the session that launched them.
|
|
28
|
+
*/
|
|
29
|
+
interface IPtyHost {
|
|
30
|
+
launch(request: PtyLaunchRequest): Promise<PtyRun>;
|
|
31
|
+
get(name: string): PtyRun | undefined;
|
|
32
|
+
/** Writes a line to a runner. False when this session does not host it. */
|
|
33
|
+
write(name: string, text: string): boolean;
|
|
34
|
+
list(): PtyRun[];
|
|
35
|
+
disposeAll(): Promise<void>;
|
|
36
|
+
}
|
|
37
|
+
//#endregion
|
|
38
|
+
export { IPtyHost, PtyLaunchRequest, PtyRun };
|
|
39
|
+
//# sourceMappingURL=types.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.cts","names":[],"sources":["../../../src/services/PtyHost/types.ts"],"mappings":";;;;UAGiB,eAAe;;EAE9B,MAAM;;EAEN;;EAEA,OAAO,UAAU;EACjB,OAAO,cAAc;;UAGN;EACf;EACA;EACA;EACA;EACA;EACA;EACA;;;;;;;;UASe;EACf,OAAO,SAAS,mBAAmB,QAAQ;EAC3C,IAAI,eAAe;;EAEnB,MAAM,cAAc;EACpB,QAAQ;EACR,cAAc"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { RunHandle } from "../Launcher/types.mjs";
|
|
2
|
+
import "../Launcher/index.mjs";
|
|
3
|
+
//#region src/services/PtyHost/types.d.ts
|
|
4
|
+
/** A background run hosted on a pseudo terminal, so it can be typed at. */
|
|
5
|
+
interface PtyRun extends RunHandle {
|
|
6
|
+
/** Sends text to the terminal. A newline is appended by the caller. */
|
|
7
|
+
write(text: string): void;
|
|
8
|
+
/** The visible screen, as plain text, for the overlay. */
|
|
9
|
+
screen(): string;
|
|
10
|
+
/** Subscribes to raw terminal output. Returns an unsubscribe function. */
|
|
11
|
+
onData(handler: (data: string) => void): () => void;
|
|
12
|
+
resize(cols: number, rows: number): void;
|
|
13
|
+
}
|
|
14
|
+
interface PtyLaunchRequest {
|
|
15
|
+
id: string;
|
|
16
|
+
name: string;
|
|
17
|
+
command: string;
|
|
18
|
+
cwd: string;
|
|
19
|
+
sessionId: string;
|
|
20
|
+
cols?: number;
|
|
21
|
+
rows?: number;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Owns every pseudo terminal this session started.
|
|
25
|
+
*
|
|
26
|
+
* A PTY cannot outlive its host process, so unlike detached subprocesses these
|
|
27
|
+
* runs are only reachable from the session that launched them.
|
|
28
|
+
*/
|
|
29
|
+
interface IPtyHost {
|
|
30
|
+
launch(request: PtyLaunchRequest): Promise<PtyRun>;
|
|
31
|
+
get(name: string): PtyRun | undefined;
|
|
32
|
+
/** Writes a line to a runner. False when this session does not host it. */
|
|
33
|
+
write(name: string, text: string): boolean;
|
|
34
|
+
list(): PtyRun[];
|
|
35
|
+
disposeAll(): Promise<void>;
|
|
36
|
+
}
|
|
37
|
+
//#endregion
|
|
38
|
+
export { IPtyHost, PtyLaunchRequest, PtyRun };
|
|
39
|
+
//# sourceMappingURL=types.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.mts","names":[],"sources":["../../../src/services/PtyHost/types.ts"],"mappings":";;;;UAGiB,eAAe;;EAE9B,MAAM;;EAEN;;EAEA,OAAO,UAAU;EACjB,OAAO,cAAc;;UAGN;EACf;EACA;EACA;EACA;EACA;EACA;EACA;;;;;;;;UASe;EACf,OAAO,SAAS,mBAAmB,QAAQ;EAC3C,IAAI,eAAe;;EAEnB,MAAM,cAAc;EACpB,QAAQ;EACR,cAAc"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../_virtual/_@oxc-project_runtime@0.143.0/helpers/esm/decorate.cjs");let t=require("inversify");require("reflect-metadata/lite");let n=require("node:path"),r=require("node:module"),i=require("node:fs/promises");const a=[`-lc`];let o=class{module;async spawn(e){let t=(await this.load()).spawn(`/bin/bash`,[...a,e.command],{cwd:e.cwd,env:e.env,cols:e.cols,rows:e.rows,name:`xterm-256color`});return{pid:t.pid,write:e=>t.write(e),resize:(e,n)=>t.resize(e,n),onData:e=>{t.onData(e)},onExit:e=>{t.onExit(e)},kill:e=>t.kill(e)}}load(){return this.module??=s().then(()=>import(`node-pty`)),this.module}};o=e.default([(0,t.injectable)()],o);async function s(){if(process.platform!==`win32`)try{let e=(0,r.createRequire)(e("url").pathToFileURL(__filename).href),t=(0,n.dirname)(e.resolve(`node-pty/package.json`)),a=(0,n.join)(t,`prebuilds`,`${process.platform}-${process.arch}`,`spawn-helper`);(await(0,i.stat)(a)).mode&73||await(0,i.chmod)(a,493)}catch{}}Object.defineProperty(exports,"NodePtySpawner",{enumerable:!0,get:function(){return o}});
|
|
2
|
+
//# sourceMappingURL=NodePtySpawner.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NodePtySpawner.cjs","names":["injectable","createRequire","dirname","join","stat","chmod"],"sources":["../../../src/services/PtySpawner/NodePtySpawner.ts"],"sourcesContent":["import { chmod, stat } from 'node:fs/promises';\nimport { createRequire } from 'node:module';\nimport { dirname, join } from 'node:path';\nimport { injectable } from 'inversify';\nimport 'reflect-metadata/lite';\nimport type { IPtySpawner, PtyProcess, PtySpawnRequest } from './types.ts';\n\nconst SHELL = '/bin/bash';\nconst SHELL_ARGS = ['-lc'];\nconst EXECUTABLE_MODE = 0o755;\nconst ANY_EXECUTE_BIT = 0o111;\n\n/**\n * Wraps `node-pty`, imported on first use only.\n *\n * The native module is a hard dependency of the interactive path and an\n * irrelevance to the default one, so a fresh checkout that cannot build it\n * still gets a working extension.\n */\n@injectable()\nexport class NodePtySpawner implements IPtySpawner {\n private module: Promise<typeof import('node-pty')> | undefined;\n\n async spawn(request: PtySpawnRequest): Promise<PtyProcess> {\n const pty = await this.load();\n const child = pty.spawn(SHELL, [...SHELL_ARGS, request.command], {\n cwd: request.cwd,\n env: request.env as Record<string, string>,\n cols: request.cols,\n rows: request.rows,\n name: 'xterm-256color',\n });\n\n return {\n pid: child.pid,\n write: (data) => child.write(data),\n resize: (cols, rows) => child.resize(cols, rows),\n onData: (handler) => {\n child.onData(handler);\n },\n onExit: (handler) => {\n child.onExit(handler);\n },\n kill: (signal) => child.kill(signal),\n };\n }\n\n private load(): Promise<typeof import('node-pty')> {\n this.module ??= ensureSpawnHelperExecutable().then(() => import('node-pty'));\n return this.module;\n }\n}\n\n/**\n * node-pty ships `spawn-helper` inside its POSIX prebuilds, and package\n * managers that rebuild the file from a content-addressable store can drop its\n * execute bit. Without it every spawn fails with `posix_spawnp failed`, so the\n * bit is restored on first load. Failures here are left to surface as the\n * original spawn error.\n */\nasync function ensureSpawnHelperExecutable(): Promise<void> {\n if (process.platform === 'win32') return;\n try {\n const require = createRequire(import.meta.url);\n const root = dirname(require.resolve('node-pty/package.json'));\n const helper = join(root, 'prebuilds', `${process.platform}-${process.arch}`, 'spawn-helper');\n const info = await stat(helper);\n if ((info.mode & ANY_EXECUTE_BIT) === 0) await chmod(helper, EXECUTABLE_MODE);\n } catch {\n // No prebuild for this platform means node-pty built from source, which\n // produces an already executable helper.\n }\n}\n"],"mappings":"0SAOA,MACM,EAAa,CAAC,KAAK,EAYlB,IAAM,EAAN,KAA4C,CACjD,OAEA,MAAM,MAAM,EAA+C,CAEzD,IAAM,GAAQ,MADI,KAAK,KAAK,EAAA,CACV,MAAM,YAAO,CAAC,GAAG,EAAY,EAAQ,OAAO,EAAG,CAC/D,IAAK,EAAQ,IACb,IAAK,EAAQ,IACb,KAAM,EAAQ,KACd,KAAM,EAAQ,KACd,KAAM,gBACR,CAAC,EAED,MAAO,CACL,IAAK,EAAM,IACX,MAAQ,GAAS,EAAM,MAAM,CAAI,EACjC,QAAS,EAAM,IAAS,EAAM,OAAO,EAAM,CAAI,EAC/C,OAAS,GAAY,CACnB,EAAM,OAAO,CAAO,CACtB,EACA,OAAS,GAAY,CACnB,EAAM,OAAO,CAAO,CACtB,EACA,KAAO,GAAW,EAAM,KAAK,CAAM,CACrC,CACF,CAEA,MAAmD,CAEjD,MADA,MAAK,SAAW,EAA4B,CAAC,CAAC,SAAW,OAAO,WAAW,EACpE,KAAK,MACd,CACF,EAhCCA,EAAAA,EAAAA,QAAAA,EAAAA,EAAAA,EAAAA,WAAAA,CAAW,CAAA,EAAA,CAAA,EAyCZ,eAAe,GAA6C,CACtD,WAAQ,WAAa,QACzB,GAAI,CACF,IAAM,GAAA,EAAUC,EAAAA,cAAAA,CAAAA,EAAAA,KAAAA,CAAAA,CAAAA,cAAAA,UAAAA,CAAAA,CAAAA,IAA6B,EACvC,GAAA,EAAOC,EAAAA,QAAAA,CAAQ,EAAQ,QAAQ,uBAAuB,CAAC,EACvD,GAAA,EAASC,EAAAA,KAAAA,CAAK,EAAM,YAAa,GAAG,QAAQ,SAAS,GAAG,QAAQ,OAAQ,cAAc,GAEvF,MAAA,EADcC,EAAAA,KAAAA,CAAK,CAAM,EAAA,CACpB,KAAO,IAAwB,MAAA,EAAMC,EAAAA,MAAAA,CAAM,EAAQ,GAAe,CAC9E,MAAQ,CAGR,CACF"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { IPtySpawner, PtyProcess, PtySpawnRequest } from "./types.cjs";
|
|
2
|
+
import "reflect-metadata/lite";
|
|
3
|
+
//#region src/services/PtySpawner/NodePtySpawner.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Wraps `node-pty`, imported on first use only.
|
|
6
|
+
*
|
|
7
|
+
* The native module is a hard dependency of the interactive path and an
|
|
8
|
+
* irrelevance to the default one, so a fresh checkout that cannot build it
|
|
9
|
+
* still gets a working extension.
|
|
10
|
+
*/
|
|
11
|
+
declare class NodePtySpawner implements IPtySpawner {
|
|
12
|
+
private module;
|
|
13
|
+
spawn(request: PtySpawnRequest): Promise<PtyProcess>;
|
|
14
|
+
private load;
|
|
15
|
+
}
|
|
16
|
+
//#endregion
|
|
17
|
+
export { NodePtySpawner };
|
|
18
|
+
//# sourceMappingURL=NodePtySpawner.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NodePtySpawner.d.cts","names":[],"sources":["../../../src/services/PtySpawner/NodePtySpawner.ts"],"mappings":";;;;;;;;;;cAoBa,0BAA0B;UAC7B;EAEF,MAAM,SAAS,kBAAkB,QAAQ;UAwBvC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { IPtySpawner, PtyProcess, PtySpawnRequest } from "./types.mjs";
|
|
2
|
+
import "reflect-metadata/lite";
|
|
3
|
+
//#region src/services/PtySpawner/NodePtySpawner.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Wraps `node-pty`, imported on first use only.
|
|
6
|
+
*
|
|
7
|
+
* The native module is a hard dependency of the interactive path and an
|
|
8
|
+
* irrelevance to the default one, so a fresh checkout that cannot build it
|
|
9
|
+
* still gets a working extension.
|
|
10
|
+
*/
|
|
11
|
+
declare class NodePtySpawner implements IPtySpawner {
|
|
12
|
+
private module;
|
|
13
|
+
spawn(request: PtySpawnRequest): Promise<PtyProcess>;
|
|
14
|
+
private load;
|
|
15
|
+
}
|
|
16
|
+
//#endregion
|
|
17
|
+
export { NodePtySpawner };
|
|
18
|
+
//# sourceMappingURL=NodePtySpawner.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NodePtySpawner.d.mts","names":[],"sources":["../../../src/services/PtySpawner/NodePtySpawner.ts"],"mappings":";;;;;;;;;;cAoBa,0BAA0B;UAC7B;EAEF,MAAM,SAAS,kBAAkB,QAAQ;UAwBvC"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import e from"../../_virtual/_@oxc-project_runtime@0.143.0/helpers/esm/decorate.mjs";import{createRequire as t}from"node:module";import{injectable as n}from"inversify";import"reflect-metadata/lite";import{dirname as r,join as i}from"node:path";import{chmod as a,stat as o}from"node:fs/promises";const s=[`-lc`];let c=class{module;async spawn(e){let t=(await this.load()).spawn(`/bin/bash`,[...s,e.command],{cwd:e.cwd,env:e.env,cols:e.cols,rows:e.rows,name:`xterm-256color`});return{pid:t.pid,write:e=>t.write(e),resize:(e,n)=>t.resize(e,n),onData:e=>{t.onData(e)},onExit:e=>{t.onExit(e)},kill:e=>t.kill(e)}}load(){return this.module??=l().then(()=>import(`node-pty`)),this.module}};c=e([n()],c);async function l(){if(process.platform!==`win32`)try{let e=t(import.meta.url),n=r(e.resolve(`node-pty/package.json`)),s=i(n,`prebuilds`,`${process.platform}-${process.arch}`,`spawn-helper`);(await o(s)).mode&73||await a(s,493)}catch{}}export{c as NodePtySpawner};
|
|
2
|
+
//# sourceMappingURL=NodePtySpawner.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NodePtySpawner.mjs","names":[],"sources":["../../../src/services/PtySpawner/NodePtySpawner.ts"],"sourcesContent":["import { chmod, stat } from 'node:fs/promises';\nimport { createRequire } from 'node:module';\nimport { dirname, join } from 'node:path';\nimport { injectable } from 'inversify';\nimport 'reflect-metadata/lite';\nimport type { IPtySpawner, PtyProcess, PtySpawnRequest } from './types.ts';\n\nconst SHELL = '/bin/bash';\nconst SHELL_ARGS = ['-lc'];\nconst EXECUTABLE_MODE = 0o755;\nconst ANY_EXECUTE_BIT = 0o111;\n\n/**\n * Wraps `node-pty`, imported on first use only.\n *\n * The native module is a hard dependency of the interactive path and an\n * irrelevance to the default one, so a fresh checkout that cannot build it\n * still gets a working extension.\n */\n@injectable()\nexport class NodePtySpawner implements IPtySpawner {\n private module: Promise<typeof import('node-pty')> | undefined;\n\n async spawn(request: PtySpawnRequest): Promise<PtyProcess> {\n const pty = await this.load();\n const child = pty.spawn(SHELL, [...SHELL_ARGS, request.command], {\n cwd: request.cwd,\n env: request.env as Record<string, string>,\n cols: request.cols,\n rows: request.rows,\n name: 'xterm-256color',\n });\n\n return {\n pid: child.pid,\n write: (data) => child.write(data),\n resize: (cols, rows) => child.resize(cols, rows),\n onData: (handler) => {\n child.onData(handler);\n },\n onExit: (handler) => {\n child.onExit(handler);\n },\n kill: (signal) => child.kill(signal),\n };\n }\n\n private load(): Promise<typeof import('node-pty')> {\n this.module ??= ensureSpawnHelperExecutable().then(() => import('node-pty'));\n return this.module;\n }\n}\n\n/**\n * node-pty ships `spawn-helper` inside its POSIX prebuilds, and package\n * managers that rebuild the file from a content-addressable store can drop its\n * execute bit. Without it every spawn fails with `posix_spawnp failed`, so the\n * bit is restored on first load. Failures here are left to surface as the\n * original spawn error.\n */\nasync function ensureSpawnHelperExecutable(): Promise<void> {\n if (process.platform === 'win32') return;\n try {\n const require = createRequire(import.meta.url);\n const root = dirname(require.resolve('node-pty/package.json'));\n const helper = join(root, 'prebuilds', `${process.platform}-${process.arch}`, 'spawn-helper');\n const info = await stat(helper);\n if ((info.mode & ANY_EXECUTE_BIT) === 0) await chmod(helper, EXECUTABLE_MODE);\n } catch {\n // No prebuild for this platform means node-pty built from source, which\n // produces an already executable helper.\n }\n}\n"],"mappings":"uSAOA,MACM,EAAa,CAAC,KAAK,EAYlB,IAAM,EAAN,KAA4C,CACjD,OAEA,MAAM,MAAM,EAA+C,CAEzD,IAAM,GAAQ,MADI,KAAK,KAAK,EAAA,CACV,MAAM,YAAO,CAAC,GAAG,EAAY,EAAQ,OAAO,EAAG,CAC/D,IAAK,EAAQ,IACb,IAAK,EAAQ,IACb,KAAM,EAAQ,KACd,KAAM,EAAQ,KACd,KAAM,gBACR,CAAC,EAED,MAAO,CACL,IAAK,EAAM,IACX,MAAQ,GAAS,EAAM,MAAM,CAAI,EACjC,QAAS,EAAM,IAAS,EAAM,OAAO,EAAM,CAAI,EAC/C,OAAS,GAAY,CACnB,EAAM,OAAO,CAAO,CACtB,EACA,OAAS,GAAY,CACnB,EAAM,OAAO,CAAO,CACtB,EACA,KAAO,GAAW,EAAM,KAAK,CAAM,CACrC,CACF,CAEA,MAAmD,CAEjD,MADA,MAAK,SAAW,EAA4B,CAAC,CAAC,SAAW,OAAO,WAAW,EACpE,KAAK,MACd,CACF,EAhCC,EAAA,EAAA,CAAA,EAAW,CAAA,EAAA,CAAA,EAyCZ,eAAe,GAA6C,CACtD,WAAQ,WAAa,QACzB,GAAI,CACF,IAAM,EAAU,EAAc,YAAY,GAAG,EACvC,EAAO,EAAQ,EAAQ,QAAQ,uBAAuB,CAAC,EACvD,EAAS,EAAK,EAAM,YAAa,GAAG,QAAQ,SAAS,GAAG,QAAQ,OAAQ,cAAc,GAEvF,MADc,EAAK,CAAM,EAAA,CACpB,KAAO,IAAwB,MAAM,EAAM,EAAQ,GAAe,CAC9E,MAAQ,CAGR,CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./NodePtySpawner.cjs");Object.defineProperty(exports,"NodePtySpawner",{enumerable:!0,get:function(){return e.NodePtySpawner}});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{NodePtySpawner as e}from"./NodePtySpawner.mjs";export{e as NodePtySpawner};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
//#region src/services/PtySpawner/types.d.ts
|
|
2
|
+
interface PtyExitResult {
|
|
3
|
+
exitCode: number;
|
|
4
|
+
signal?: number;
|
|
5
|
+
}
|
|
6
|
+
interface PtySpawnRequest {
|
|
7
|
+
/** Shell command line, run under a pseudo terminal so it can prompt. */
|
|
8
|
+
command: string;
|
|
9
|
+
cwd: string;
|
|
10
|
+
env: NodeJS.ProcessEnv;
|
|
11
|
+
cols: number;
|
|
12
|
+
rows: number;
|
|
13
|
+
}
|
|
14
|
+
interface PtyProcess {
|
|
15
|
+
readonly pid: number;
|
|
16
|
+
write(data: string): void;
|
|
17
|
+
resize(cols: number, rows: number): void;
|
|
18
|
+
onData(handler: (data: string) => void): void;
|
|
19
|
+
onExit(handler: (result: PtyExitResult) => void): void;
|
|
20
|
+
kill(signal?: string): void;
|
|
21
|
+
}
|
|
22
|
+
/** Pseudo terminal creation as a port. The native module is loaded lazily. */
|
|
23
|
+
interface IPtySpawner {
|
|
24
|
+
spawn(request: PtySpawnRequest): Promise<PtyProcess>;
|
|
25
|
+
}
|
|
26
|
+
//#endregion
|
|
27
|
+
export { IPtySpawner, PtyExitResult, PtyProcess, PtySpawnRequest };
|
|
28
|
+
//# sourceMappingURL=types.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.cts","names":[],"sources":["../../../src/services/PtySpawner/types.ts"],"mappings":";UAAiB;EACf;EACA;;UAGe;;EAEf;EACA;EACA,KAAK,OAAO;EACZ;EACA;;UAGe;WACN;EACT,MAAM;EACN,OAAO,cAAc;EACrB,OAAO,UAAU;EACjB,OAAO,UAAU,QAAQ;EACzB,KAAK;;;UAIU;EACf,MAAM,SAAS,kBAAkB,QAAQ"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
//#region src/services/PtySpawner/types.d.ts
|
|
2
|
+
interface PtyExitResult {
|
|
3
|
+
exitCode: number;
|
|
4
|
+
signal?: number;
|
|
5
|
+
}
|
|
6
|
+
interface PtySpawnRequest {
|
|
7
|
+
/** Shell command line, run under a pseudo terminal so it can prompt. */
|
|
8
|
+
command: string;
|
|
9
|
+
cwd: string;
|
|
10
|
+
env: NodeJS.ProcessEnv;
|
|
11
|
+
cols: number;
|
|
12
|
+
rows: number;
|
|
13
|
+
}
|
|
14
|
+
interface PtyProcess {
|
|
15
|
+
readonly pid: number;
|
|
16
|
+
write(data: string): void;
|
|
17
|
+
resize(cols: number, rows: number): void;
|
|
18
|
+
onData(handler: (data: string) => void): void;
|
|
19
|
+
onExit(handler: (result: PtyExitResult) => void): void;
|
|
20
|
+
kill(signal?: string): void;
|
|
21
|
+
}
|
|
22
|
+
/** Pseudo terminal creation as a port. The native module is loaded lazily. */
|
|
23
|
+
interface IPtySpawner {
|
|
24
|
+
spawn(request: PtySpawnRequest): Promise<PtyProcess>;
|
|
25
|
+
}
|
|
26
|
+
//#endregion
|
|
27
|
+
export { IPtySpawner, PtyExitResult, PtyProcess, PtySpawnRequest };
|
|
28
|
+
//# sourceMappingURL=types.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.mts","names":[],"sources":["../../../src/services/PtySpawner/types.ts"],"mappings":";UAAiB;EACf;EACA;;UAGe;;EAEf;EACA;EACA,KAAK,OAAO;EACZ;EACA;;UAGe;WACN;EACT,MAAM;EACN,OAAO,cAAc;EACrB,OAAO,UAAU;EACjB,OAAO,UAAU,QAAQ;EACzB,KAAK;;;UAIU;EACf,MAAM,SAAS,kBAAkB,QAAQ"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../_virtual/_rolldown/runtime.cjs"),t=require("../../config.cjs"),n=require("../../types.cjs"),r=require("../../_virtual/_@oxc-project_runtime@0.143.0/helpers/esm/decorateMetadata.cjs"),i=require("../../_virtual/_@oxc-project_runtime@0.143.0/helpers/esm/decorateParam.cjs"),a=require("../../_virtual/_@oxc-project_runtime@0.143.0/helpers/esm/decorate.cjs"),o=require("../../runnerSpec.cjs");let s=require("inversify");require("reflect-metadata/lite");let c=require("node:crypto"),l=require("node:fs");l=e.__toESM(l,1);let u=require("node:path");u=e.__toESM(u,1);let d=require("node:module"),f=require("@rmux/sdk");const p=1e3,m=`doom-runner-`,h=/^doom-runner-[A-Za-z0-9_-]+$/,g={NO_COLOR:`1`,CI:`1`},_={"darwin-arm64":`@agimon-ai/doompi-runner-rmux-darwin-arm64`,"darwin-x64":`@agimon-ai/doompi-runner-rmux-darwin-x64`,"linux-arm64":`@agimon-ai/doompi-runner-rmux-linux-arm64`,"linux-x64":`@agimon-ai/doompi-runner-rmux-linux-x64`};let v=class{paths;clientPromise;runs=new Map;completions=new Map;constructor(e){this.paths=e}async launch(e){let n=await this.client();if(!n)return;this.paths.ensureDirectories();let r=`${m}${e.id}`,i=this.paths.logPathFor(e.id),a=this.auxPaths(e.id,e.sessionId),s=!1,c=!1;try{this.prepareFiles(e,i,a),await n.cmd(`new-session`,`-d`,`-s`,r,`-c`,e.cwd,process.execPath,o.runtimeEntry(`runnerHost`),a.spec,a.gate,a.exit,{check:!0}),s=!0,await n.cmd(`pipe-pane`,`-t`,r,this.logPipeCommand(i,a.logDone),{check:!0});let u=n.session(r).pane(0,0),d=await C(n,r);l.default.writeFileSync(a.gate,``,{mode:384}),c=!0;let f=!0,p=this.monitor(n,u,r,a);this.trackCompletion(r,p);let m={id:e.id,name:e.name,pid:d,logPath:i,backend:`rmux`,backendTarget:r,output:()=>f?j(i,t.getResultMaxBytes()*2):``,completion:()=>p,detach:()=>{f=!1},stop:()=>this.stop(r,d)};return e.interactive&&this.runs.set(e.name,this.interactiveRun(m,u,p)),p.finally(()=>this.runs.delete(e.name)).catch(e=>process.emitWarning(`RMUX completion failed for ${r}: ${N(e)}`)),m}catch(e){if(c)throw e;s&&await n.session(r).kill().catch(e=>process.emitWarning(`Could not clean up failed RMUX launch ${r}: ${N(e)}`)),o.cleanupSupervisorFiles(a),process.emitWarning(`RMUX launch unavailable, using native runner: ${N(e)}`);return}}async stop(e,t){if(!h.test(e)||!Number.isInteger(t)||t<=0)return!1;let n=await this.client();if(!n)return!1;try{if(await k(n,e))return!0;let r=await C(n,e);if(r!==t)return!1;let i=A(r,e);return i===`gone`?!0:i===`failed`?!1:await D(n,e,3e3)||await k(n,e)?!0:await C(n,e)===t&&E(n,e)}catch(t){return process.emitWarning(`Could not stop RMUX target ${e}: ${N(t)}`),!1}}async watch(e,t,n){let r=await this.client();if(!r)return;let i=r.session(t).pane(0,0);try{await r.displayMessage(`#{pane_id}`,{target:t})}catch(e){process.emitWarning(`Could not watch RMUX target ${t}: ${N(e)}`);return}let a=this.monitor(r,i,t,this.auxPaths(e,n));return this.trackCompletion(t,a),a}async input(e,t){let n=await this.client();return n?await n.session(e).pane(0,0).sendText(t).catch(t=>{process.emitWarning(`Could not send input to RMUX target ${e}: ${N(t)}`)})!==void 0:!1}get(e){return this.runs.get(e)}readOutcome(e,t){return o.readExitMetadata(this.auxPaths(e,t).exit)}trackCompletion(e,t){this.completions.set(e,t),t.finally(()=>this.completions.delete(e)).catch(t=>process.emitWarning(`RMUX monitor failed for ${e}: ${N(t)}`))}client(){return this.clientPromise??=this.resolveClient(),this.clientPromise}async resolveClient(){let e=[b(),`rmux`].filter(e=>e!==void 0);for(let t of e)try{t!==`rmux`&&l.default.chmodSync(t,493);let e=new f.RMUX({binary:t,socketName:x(this.paths.repositoryPath())});return await e.capabilities(),e}catch(e){process.emitWarning(`RMUX candidate ${t} is unavailable: ${N(e)}`)}}prepareFiles(e,t,n){o.cleanupSupervisorFiles(n),l.default.writeFileSync(t,``,{mode:384});let r=S(e.sessionId,e.interactive),i={command:e.command,cwd:e.cwd,env:r};o.writeCommandSpec(n.spec,i)}auxPaths(e,t){return o.supervisorPaths(this.paths.stateDirectory(t),e)}logPipeCommand(e,n){return o.shellJoin([process.execPath,o.runtimeEntry(`logSink`),e,this.paths.rotatedLogPathFor(u.default.basename(e,`.log`)),String(t.getLogMaxBytes()),n])}async monitor(e,t,n,r){try{let t=await w(e,n,r.exit);return await T(e,n,r.logDone),o.readExitMetadata(r.exit)??{code:t,signal:null}}finally{await k(e,n).catch(()=>!1)||await t.server.session(n).kill().catch(e=>process.emitWarning(`Could not clean up completed RMUX target ${n}: ${N(e)}`)),o.cleanupSupervisorFiles(r)}}interactiveRun(e,t,n){let r=``,i=!0,a=new Set;return(async()=>{for(;i;){let n=await t.captureText().catch(t=>(process.emitWarning(`Could not capture RMUX screen for ${e.name}: ${N(t)}`),r));if(n!==r){r=n;for(let e of a)e(n)}await M(100)}})(),n.finally(()=>{i=!1}).catch(t=>process.emitWarning(`RMUX interactive completion failed for ${e.name}: ${N(t)}`)),{...e,write:e=>{t.sendText(e).catch(e=>process.emitWarning(N(e)))},screen:()=>r,onData:e=>(a.add(e),()=>a.delete(e)),resize:(e,n)=>{t.resize({width:e,height:n}).catch(e=>process.emitWarning(N(e)))}}}};v=a.default([(0,s.injectable)(),i.default(0,(0,s.inject)(n.TYPES.RunnerPaths)),r.default(`design:paramtypes`,[Object])],v);function y(e,t){let n=`${e}-${t}`,r=_[n];return r||process.emitWarning(`Bundled RMUX binary is unavailable for unsupported target ${n}`),r}function b(){let e=y(process.platform,process.arch);if(e)try{let t=(0,d.createRequire)(require("url").pathToFileURL(__filename).href).resolve(`${e}/package.json`);return u.default.join(u.default.dirname(t),`vendor`,`bin`,`rmux`)}catch(t){process.emitWarning(`Bundled RMUX binary is unavailable for ${e}: ${N(t)}`);return}}function x(e){let t=(0,c.createHash)(`sha256`).update(e).digest(`hex`).slice(0,12);return`${m}${t}`}function S(e,t){let n={...process.env,...t?{}:g,...o.NO_TERMINAL_INPUT_ENV,PI_SESSION_ID:e};return t||delete n.FORCE_COLOR,Object.fromEntries(Object.entries(n).filter(e=>e[1]!==void 0))}async function C(e,t){let n=await e.displayMessage(`#{pane_pid}`,{target:t}),r=Number(n.message);if(!Number.isInteger(r)||r<=0)throw Error(`RMUX did not report a pane pid for ${t}`);return r}async function w(e,t,n){for(;;){if(l.default.existsSync(n))return null;let r=await O(e,t);if(r.exited)return r.code;await M(100)}}async function T(e,t,n){let r=Date.now()+2e3;for(;Date.now()<r;){if(l.default.existsSync(n)||await k(e,t))return;await M(25)}}async function E(e,t){return new Promise(n=>{let r=!1,i=e=>{r||(r=!0,clearTimeout(a),n(e))},a=setTimeout(()=>{process.emitWarning(`Timed out closing RMUX target ${t} after ${p}ms`),i(!1)},p);e.session(t).kill().then(()=>i(!0),e=>{process.emitWarning(`Could not close RMUX target ${t}: ${N(e)}`),i(!1)})})}async function D(e,t,n){let r=Date.now()+n;for(;Date.now()<r;){try{if((await O(e,t)).exited)return!0}catch(e){return process.emitWarning(`Could not verify RMUX target ${t} stopped: ${N(e)}`),!1}await M(100)}return!1}async function O(e,t){let n;try{let r=await e.displayMessage(`#{pane_dead}:#{pane_dead_status}:#{session_name}`,{target:t});n=typeof r.message==`string`?r.message:``}catch{return{exited:!0,code:null}}let[r,i,...a]=n.trim().split(`:`);if(a.join(`:`)===``)return{exited:!0,code:null};if(r===`1`||r===`true`){let e=Number(i);return{exited:!0,code:Number.isInteger(e)?e:null}}return{exited:!1,code:null}}async function k(e,t){try{return(await e.cmd(`has-session`,`-t`,t)).returnCode!==0}catch{return!0}}function A(e,t){try{return process.kill(e,`SIGTERM`),`signalled`}catch(e){return e.code===`ESRCH`?`gone`:(process.emitWarning(`Could not signal RMUX target ${t}: ${N(e)}`),`failed`)}}function j(e,t){try{let n=l.default.readFileSync(e,`utf8`);return n.length>t?n.slice(-t):n}catch(t){return t.code!==`ENOENT`&&process.emitWarning(`Could not read RMUX log ${e}: ${N(t)}`),``}}function M(e){return new Promise(t=>{setTimeout(t,e).unref?.()})}function N(e){return e instanceof Error?e.message:String(e)}Object.defineProperty(exports,"RmuxBackend",{enumerable:!0,get:function(){return v}}),exports.rmuxPackageForTarget=y;
|
|
2
|
+
//# sourceMappingURL=RmuxBackend.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RmuxBackend.cjs","names":["runtimeEntry","getResultMaxBytes","readExitMetadata","RMUX","supervisorPaths","shellJoin","path","getLogMaxBytes","injectable","inject","TYPES","createRequire","createHash","NO_TERMINAL_INPUT_ENV","fs"],"sources":["../../../src/services/RmuxBackend/RmuxBackend.ts"],"sourcesContent":["import { createHash } from 'node:crypto';\nimport fs from 'node:fs';\nimport { createRequire } from 'node:module';\nimport path from 'node:path';\nimport { inject, injectable } from 'inversify';\nimport { RMUX, type Pane, type Rmux } from '@rmux/sdk';\nimport 'reflect-metadata/lite';\nimport { getLogMaxBytes, getResultMaxBytes } from '../../config.ts';\nimport {\n type CommandSpec,\n NO_TERMINAL_INPUT_ENV,\n type SupervisorPaths,\n cleanupSupervisorFiles,\n readExitMetadata,\n runtimeEntry,\n shellJoin,\n supervisorPaths,\n writeCommandSpec,\n} from '../../runnerSpec.ts';\nimport { TYPES } from '../../types.ts';\nimport type { ExitResult } from '../Spawner/index.ts';\nimport type { RunHandle } from '../Launcher/index.ts';\nimport type { PtyRun } from '../PtyHost/index.ts';\nimport type { IRunnerPaths } from '../RunnerPaths/index.ts';\nimport type { IRmuxBackend, RmuxLaunchRequest } from './types.ts';\n\nconst POLL_MS = 100;\nconst LOG_DRAIN_TIMEOUT_MS = 2_000;\nconst LOG_DRAIN_POLL_MS = 25;\n/** Pane liveness, its exit status, and whether the session still exists, in one read. */\nconst PANE_STATE_FORMAT = '#{pane_dead}:#{pane_dead_status}:#{session_name}';\nconst STOP_GRACE_MS = 3_000;\nconst STOP_CLOSE_TIMEOUT_MS = 1_000;\nconst EXECUTABLE_MODE = 0o755;\nconst SESSION_PREFIX = 'doom-runner-';\nconst OWNED_TARGET_PATTERN = /^doom-runner-[A-Za-z0-9_-]+$/;\nconst SOCKET_HASH_LENGTH = 12;\nconst NON_INTERACTIVE_ENV = { NO_COLOR: '1', CI: '1' };\nconst PACKAGE_BY_PLATFORM: Readonly<Record<string, string>> = {\n 'darwin-arm64': '@agimon-ai/doompi-runner-rmux-darwin-arm64',\n 'darwin-x64': '@agimon-ai/doompi-runner-rmux-darwin-x64',\n 'linux-arm64': '@agimon-ai/doompi-runner-rmux-linux-arm64',\n 'linux-x64': '@agimon-ai/doompi-runner-rmux-linux-x64',\n};\n\n@injectable()\nexport class RmuxBackend implements IRmuxBackend {\n private clientPromise: Promise<Rmux | undefined> | undefined;\n private readonly runs = new Map<string, PtyRun>();\n private readonly completions = new Map<string, Promise<ExitResult>>();\n\n constructor(@inject(TYPES.RunnerPaths) private readonly paths: IRunnerPaths) {}\n\n async launch(request: RmuxLaunchRequest): Promise<RunHandle | undefined> {\n const rmux = await this.client();\n if (!rmux) return undefined;\n\n this.paths.ensureDirectories();\n const target = `${SESSION_PREFIX}${request.id}`;\n const logPath = this.paths.logPathFor(request.id);\n const aux = this.auxPaths(request.id, request.sessionId);\n let created = false;\n let released = false;\n\n try {\n this.prepareFiles(request, logPath, aux);\n await rmux.cmd(\n 'new-session',\n '-d',\n '-s',\n target,\n '-c',\n request.cwd,\n process.execPath,\n runtimeEntry('runnerHost'),\n aux.spec,\n aux.gate,\n aux.exit,\n { check: true },\n );\n created = true;\n // No remain-on-exit: a finished pane ends its session, and the last session\n // ending stops the server, so a completed run leaves no process behind.\n await rmux.cmd('pipe-pane', '-t', target, this.logPipeCommand(logPath, aux.logDone), { check: true });\n\n const pane = rmux.session(target).pane(0, 0);\n const pid = await panePid(rmux, target);\n fs.writeFileSync(aux.gate, '', { mode: 0o600 });\n released = true;\n\n let buffering = true;\n const completion = this.monitor(rmux, pane, target, aux);\n this.trackCompletion(target, completion);\n const stop = (): Promise<boolean> => this.stop(target, pid);\n const handle: RunHandle = {\n id: request.id,\n name: request.name,\n pid,\n logPath,\n backend: 'rmux',\n backendTarget: target,\n output: () => (buffering ? readTail(logPath, getResultMaxBytes() * 2) : ''),\n completion: () => completion,\n detach: () => {\n buffering = false;\n },\n stop,\n };\n\n if (request.interactive) this.runs.set(request.name, this.interactiveRun(handle, pane, completion));\n void completion\n .finally(() => this.runs.delete(request.name))\n .catch((error: unknown) => process.emitWarning(`RMUX completion failed for ${target}: ${errorMessage(error)}`));\n return handle;\n } catch (error) {\n if (released) throw error;\n if (created) {\n await rmux\n .session(target)\n .kill()\n .catch((cleanupError: unknown) =>\n process.emitWarning(`Could not clean up failed RMUX launch ${target}: ${errorMessage(cleanupError)}`),\n );\n }\n cleanupSupervisorFiles(aux);\n process.emitWarning(`RMUX launch unavailable, using native runner: ${errorMessage(error)}`);\n return undefined;\n }\n }\n\n async stop(target: string, expectedPid: number): Promise<boolean> {\n if (!OWNED_TARGET_PATTERN.test(target) || !Number.isInteger(expectedPid) || expectedPid <= 0) return false;\n\n const rmux = await this.client();\n if (!rmux) return false;\n try {\n // A session that already ended took its process group with it.\n if (await sessionMissing(rmux, target)) return true;\n\n const pid = await panePid(rmux, target);\n if (pid !== expectedPid) return false;\n const signalled = signalPane(pid, target);\n if (signalled === 'gone') return true;\n if (signalled === 'failed') return false;\n\n if (await waitForPaneStop(rmux, target, STOP_GRACE_MS)) return true;\n if (await sessionMissing(rmux, target)) return true;\n\n // Revalidate after the grace period so a replacement pane is never closed.\n const currentPid = await panePid(rmux, target);\n if (currentPid !== expectedPid) return false;\n\n return closeOwnedSession(rmux, target);\n } catch (error) {\n process.emitWarning(`Could not stop RMUX target ${target}: ${errorMessage(error)}`);\n return false;\n }\n }\n\n async watch(id: string, target: string, sessionId?: string): Promise<ExitResult | undefined> {\n const rmux = await this.client();\n if (!rmux) return undefined;\n const pane = rmux.session(target).pane(0, 0);\n try {\n await rmux.displayMessage('#{pane_id}', { target });\n } catch (error) {\n process.emitWarning(`Could not watch RMUX target ${target}: ${errorMessage(error)}`);\n return undefined;\n }\n const completion = this.monitor(rmux, pane, target, this.auxPaths(id, sessionId));\n this.trackCompletion(target, completion);\n return completion;\n }\n\n async input(target: string, text: string): Promise<boolean> {\n const rmux = await this.client();\n if (!rmux) return false;\n const result = await rmux\n .session(target)\n .pane(0, 0)\n .sendText(text)\n .catch((error: unknown) => {\n process.emitWarning(`Could not send input to RMUX target ${target}: ${errorMessage(error)}`);\n return undefined;\n });\n return result !== undefined;\n }\n\n get(name: string): PtyRun | undefined {\n return this.runs.get(name);\n }\n\n readOutcome(id: string, sessionId: string): ExitResult | undefined {\n return readExitMetadata(this.auxPaths(id, sessionId).exit);\n }\n\n private trackCompletion(target: string, completion: Promise<ExitResult>): void {\n this.completions.set(target, completion);\n void completion\n .finally(() => this.completions.delete(target))\n .catch((error: unknown) => process.emitWarning(`RMUX monitor failed for ${target}: ${errorMessage(error)}`));\n }\n\n private client(): Promise<Rmux | undefined> {\n this.clientPromise ??= this.resolveClient();\n return this.clientPromise;\n }\n\n private async resolveClient(): Promise<Rmux | undefined> {\n const binaries = [bundledBinary(), 'rmux'].filter((value): value is string => value !== undefined);\n for (const binary of binaries) {\n try {\n if (binary !== 'rmux') fs.chmodSync(binary, EXECUTABLE_MODE);\n const client = new RMUX({ binary, socketName: socketName(this.paths.repositoryPath()) });\n await client.capabilities();\n return client;\n } catch (error) {\n process.emitWarning(`RMUX candidate ${binary} is unavailable: ${errorMessage(error)}`);\n // Try the next compatible candidate, then let the native launcher take over.\n }\n }\n return undefined;\n }\n\n private prepareFiles(request: RmuxLaunchRequest, logPath: string, aux: SupervisorPaths): void {\n cleanupSupervisorFiles(aux);\n fs.writeFileSync(logPath, '', { mode: 0o600 });\n const env = environment(request.sessionId, request.interactive);\n // runnerHost supervises the command and watches the lifeline itself, so an\n // owner that dies mid-run is handled inside the pane rather than around it.\n const spec: CommandSpec = { command: request.command, cwd: request.cwd, env };\n writeCommandSpec(aux.spec, spec);\n }\n\n private auxPaths(id: string, sessionId?: string): SupervisorPaths {\n return supervisorPaths(this.paths.stateDirectory(sessionId), id);\n }\n\n private logPipeCommand(logPath: string, donePath: string): string {\n return shellJoin([\n process.execPath,\n runtimeEntry('logSink'),\n logPath,\n this.paths.rotatedLogPathFor(path.basename(logPath, '.log')),\n String(getLogMaxBytes()),\n donePath,\n ]);\n }\n\n private async monitor(rmux: Rmux, pane: Pane, target: string, aux: SupervisorPaths): Promise<ExitResult> {\n try {\n const paneCode = await waitForRunEnd(rmux, target, aux.exit);\n await waitForLogDrain(rmux, target, aux.logDone);\n return readExitMetadata(aux.exit) ?? { code: paneCode, signal: null };\n } finally {\n // The pane ends its own session, so this only covers a session that somehow\n // outlived its pane. Killing unconditionally would warn on every clean run.\n if (!(await sessionMissing(rmux, target).catch(() => false))) {\n await pane.server\n .session(target)\n .kill()\n .catch((error: unknown) =>\n process.emitWarning(`Could not clean up completed RMUX target ${target}: ${errorMessage(error)}`),\n );\n }\n cleanupSupervisorFiles(aux);\n }\n }\n\n private interactiveRun(handle: RunHandle, pane: Pane, completion: Promise<ExitResult>): PtyRun {\n let screen = '';\n let active = true;\n const handlers = new Set<(data: string) => void>();\n const refresh = async (): Promise<void> => {\n while (active) {\n const next = await pane.captureText().catch((error: unknown) => {\n process.emitWarning(`Could not capture RMUX screen for ${handle.name}: ${errorMessage(error)}`);\n return screen;\n });\n if (next !== screen) {\n screen = next;\n for (const handler of handlers) handler(next);\n }\n await delay(POLL_MS);\n }\n };\n void refresh();\n void completion\n .finally(() => {\n active = false;\n })\n .catch((error: unknown) =>\n process.emitWarning(`RMUX interactive completion failed for ${handle.name}: ${errorMessage(error)}`),\n );\n return {\n ...handle,\n write: (text) => {\n void pane.sendText(text).catch((error: unknown) => process.emitWarning(errorMessage(error)));\n },\n screen: () => screen,\n onData: (handler) => {\n handlers.add(handler);\n return () => handlers.delete(handler);\n },\n resize: (cols, rows) => {\n void pane\n .resize({ width: cols, height: rows })\n .catch((error: unknown) => process.emitWarning(errorMessage(error)));\n },\n };\n }\n}\n\nexport function rmuxPackageForTarget(platform: string, architecture: string): string | undefined {\n const target = `${platform}-${architecture}`;\n const packageName = PACKAGE_BY_PLATFORM[target];\n if (!packageName) process.emitWarning(`Bundled RMUX binary is unavailable for unsupported target ${target}`);\n return packageName;\n}\n\nfunction bundledBinary(): string | undefined {\n const packageName = rmuxPackageForTarget(process.platform, process.arch);\n if (!packageName) return undefined;\n try {\n const require = createRequire(import.meta.url);\n const manifest = require.resolve(`${packageName}/package.json`);\n return path.join(path.dirname(manifest), 'vendor', 'bin', 'rmux');\n } catch (error) {\n process.emitWarning(`Bundled RMUX binary is unavailable for ${packageName}: ${errorMessage(error)}`);\n return undefined;\n }\n}\n\nfunction socketName(repositoryPath: string): string {\n const hash = createHash('sha256').update(repositoryPath).digest('hex').slice(0, SOCKET_HASH_LENGTH);\n return `${SESSION_PREFIX}${hash}`;\n}\n\nfunction environment(sessionId: string, interactive: boolean): Record<string, string> {\n const values: NodeJS.ProcessEnv = {\n ...process.env,\n ...(interactive ? {} : NON_INTERACTIVE_ENV),\n // Applied to interactive runs as well: a pane is a tty either way, and an\n // agent sending input to a prompt still has no way past a pager.\n ...NO_TERMINAL_INPUT_ENV,\n PI_SESSION_ID: sessionId,\n };\n if (!interactive) delete values['FORCE_COLOR'];\n return Object.fromEntries(\n Object.entries(values).filter((entry): entry is [string, string] => entry[1] !== undefined),\n );\n}\n\nasync function panePid(rmux: Rmux, target: string): Promise<number> {\n const response = await rmux.displayMessage('#{pane_pid}', { target });\n const pid = Number(response['message']);\n if (!Number.isInteger(pid) || pid <= 0) throw new Error(`RMUX did not report a pane pid for ${target}`);\n return pid;\n}\n\n/**\n * Waits for the run to end, preferring the supervisor's own record of it.\n *\n * The sidecar is written before the command's pane can end, and it outlives the\n * server that the pane's exit takes down with it. Asking the server is the\n * fallback for a supervisor that died without recording anything.\n */\nasync function waitForRunEnd(rmux: Rmux, target: string, exitPath: string): Promise<number | null> {\n for (;;) {\n if (fs.existsSync(exitPath)) return null;\n const state = await readPaneExit(rmux, target);\n if (state.exited) return state.code;\n await delay(POLL_MS);\n }\n}\n\n/**\n * Gives the log sink a moment to mark the log complete.\n *\n * The sink dies with the session it was piped from, so once the session is gone\n * the marker is never coming and there is nothing left to wait for. Its writes\n * are synchronous, so the log itself is already on disk either way.\n */\nasync function waitForLogDrain(rmux: Rmux, target: string, donePath: string): Promise<void> {\n const deadline = Date.now() + LOG_DRAIN_TIMEOUT_MS;\n while (Date.now() < deadline) {\n if (fs.existsSync(donePath)) return;\n if (await sessionMissing(rmux, target)) return;\n await delay(LOG_DRAIN_POLL_MS);\n }\n}\n\nasync function closeOwnedSession(rmux: Rmux, target: string): Promise<boolean> {\n return new Promise((resolve) => {\n let settled = false;\n const finish = (result: boolean): void => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n resolve(result);\n };\n const timer = setTimeout(() => {\n process.emitWarning(`Timed out closing RMUX target ${target} after ${STOP_CLOSE_TIMEOUT_MS}ms`);\n finish(false);\n }, STOP_CLOSE_TIMEOUT_MS);\n void rmux\n .session(target)\n .kill()\n .then(\n () => finish(true),\n (error: unknown) => {\n process.emitWarning(`Could not close RMUX target ${target}: ${errorMessage(error)}`);\n finish(false);\n },\n );\n });\n}\n\nasync function waitForPaneStop(rmux: Rmux, target: string, timeoutMs: number): Promise<boolean> {\n const deadline = Date.now() + timeoutMs;\n while (Date.now() < deadline) {\n try {\n if ((await readPaneExit(rmux, target)).exited) return true;\n } catch (error) {\n process.emitWarning(`Could not verify RMUX target ${target} stopped: ${errorMessage(error)}`);\n return false;\n }\n await delay(POLL_MS);\n }\n return false;\n}\n\n/**\n * One formatted read answers both questions this poll asks, so watching a run\n * costs the same single rmux call it always did.\n */\nasync function readPaneExit(rmux: Rmux, target: string): Promise<{ exited: boolean; code: number | null }> {\n let message: string;\n try {\n const response = await rmux.displayMessage(PANE_STATE_FORMAT, { target });\n message = typeof response['message'] === 'string' ? response['message'] : '';\n } catch {\n // The last session ending stops the server, so a server that cannot be\n // reached is the ordinary end of the last run rather than a fault.\n return { exited: true, code: null };\n }\n const [dead, status, ...rest] = message.trim().split(':');\n // A missing session formats as a live pane with no name rather than failing,\n // so the name is what says whether there is still anything to watch.\n if (rest.join(':') === '') return { exited: true, code: null };\n if (dead === '1' || dead === 'true') {\n const code = Number(status);\n return { exited: true, code: Number.isInteger(code) ? code : null };\n }\n return { exited: false, code: null };\n}\n\n/** A session that cannot be found, on a server that may itself be gone. */\nasync function sessionMissing(rmux: Rmux, target: string): Promise<boolean> {\n try {\n const probe = await rmux.cmd('has-session', '-t', target);\n return probe.returnCode !== 0;\n } catch {\n // No server to ask means no session to find.\n return true;\n }\n}\n\n/**\n * A pane that was already gone and a signal that could not be delivered are\n * opposite answers to \"is it stopped\", so they are reported apart.\n */\nfunction signalPane(pid: number, target: string): 'signalled' | 'gone' | 'failed' {\n try {\n process.kill(pid, 'SIGTERM');\n return 'signalled';\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ESRCH') return 'gone';\n process.emitWarning(`Could not signal RMUX target ${target}: ${errorMessage(error)}`);\n return 'failed';\n }\n}\n\nfunction readTail(target: string, maxBytes: number): string {\n try {\n const text = fs.readFileSync(target, 'utf8');\n return text.length > maxBytes ? text.slice(-maxBytes) : text;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') {\n process.emitWarning(`Could not read RMUX log ${target}: ${errorMessage(error)}`);\n }\n return '';\n }\n}\n\nfunction delay(ms: number): Promise<void> {\n return new Promise((resolve) => {\n const timer = setTimeout(resolve, ms);\n timer.unref?.();\n });\n}\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { IRunnerPaths } from "../RunnerPaths/types.cjs";
|
|
2
|
+
import "../RunnerPaths/index.cjs";
|
|
3
|
+
import { ExitResult } from "../Spawner/types.cjs";
|
|
4
|
+
import "../Spawner/index.cjs";
|
|
5
|
+
import { RunHandle } from "../Launcher/types.cjs";
|
|
6
|
+
import "../Launcher/index.cjs";
|
|
7
|
+
import { PtyRun } from "../PtyHost/types.cjs";
|
|
8
|
+
import "../PtyHost/index.cjs";
|
|
9
|
+
import { IRmuxBackend, RmuxLaunchRequest } from "./types.cjs";
|
|
10
|
+
import "reflect-metadata/lite";
|
|
11
|
+
//#region src/services/RmuxBackend/RmuxBackend.d.ts
|
|
12
|
+
declare class RmuxBackend implements IRmuxBackend {
|
|
13
|
+
private readonly paths;
|
|
14
|
+
private clientPromise;
|
|
15
|
+
private readonly runs;
|
|
16
|
+
private readonly completions;
|
|
17
|
+
constructor(paths: IRunnerPaths);
|
|
18
|
+
launch(request: RmuxLaunchRequest): Promise<RunHandle | undefined>;
|
|
19
|
+
stop(target: string, expectedPid: number): Promise<boolean>;
|
|
20
|
+
watch(id: string, target: string, sessionId?: string): Promise<ExitResult | undefined>;
|
|
21
|
+
input(target: string, text: string): Promise<boolean>;
|
|
22
|
+
get(name: string): PtyRun | undefined;
|
|
23
|
+
readOutcome(id: string, sessionId: string): ExitResult | undefined;
|
|
24
|
+
private trackCompletion;
|
|
25
|
+
private client;
|
|
26
|
+
private resolveClient;
|
|
27
|
+
private prepareFiles;
|
|
28
|
+
private auxPaths;
|
|
29
|
+
private logPipeCommand;
|
|
30
|
+
private monitor;
|
|
31
|
+
private interactiveRun;
|
|
32
|
+
}
|
|
33
|
+
declare function rmuxPackageForTarget(platform: string, architecture: string): string | undefined;
|
|
34
|
+
//#endregion
|
|
35
|
+
export { RmuxBackend, rmuxPackageForTarget };
|
|
36
|
+
//# sourceMappingURL=RmuxBackend.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RmuxBackend.d.cts","names":[],"sources":["../../../src/services/RmuxBackend/RmuxBackend.ts"],"mappings":";;;;;;;;;;;cA8Ca,uBAAuB;mBAKsB;UAJhD;mBACS;mBACA;EAEuC,YAAA,OAAO;EAEzD,OAAO,SAAS,oBAAoB,QAAQ;EA6E5C,KAAK,gBAAgB,sBAAsB;EA6B3C,MAAM,YAAY,gBAAgB,qBAAqB,QAAQ;EAe/D,MAAM,gBAAgB,eAAe;EAc3C,IAAI,eAAe;EAInB,YAAY,YAAY,oBAAoB;UAIpC;UAOA;UAKM;UAgBN;UAUA;UAIA;UAWM;UAoBN;;iBA4CM,qBAAqB,kBAAkB"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { IRunnerPaths } from "../RunnerPaths/types.mjs";
|
|
2
|
+
import "../RunnerPaths/index.mjs";
|
|
3
|
+
import { ExitResult } from "../Spawner/types.mjs";
|
|
4
|
+
import "../Spawner/index.mjs";
|
|
5
|
+
import { RunHandle } from "../Launcher/types.mjs";
|
|
6
|
+
import "../Launcher/index.mjs";
|
|
7
|
+
import { PtyRun } from "../PtyHost/types.mjs";
|
|
8
|
+
import "../PtyHost/index.mjs";
|
|
9
|
+
import { IRmuxBackend, RmuxLaunchRequest } from "./types.mjs";
|
|
10
|
+
import "reflect-metadata/lite";
|
|
11
|
+
//#region src/services/RmuxBackend/RmuxBackend.d.ts
|
|
12
|
+
declare class RmuxBackend implements IRmuxBackend {
|
|
13
|
+
private readonly paths;
|
|
14
|
+
private clientPromise;
|
|
15
|
+
private readonly runs;
|
|
16
|
+
private readonly completions;
|
|
17
|
+
constructor(paths: IRunnerPaths);
|
|
18
|
+
launch(request: RmuxLaunchRequest): Promise<RunHandle | undefined>;
|
|
19
|
+
stop(target: string, expectedPid: number): Promise<boolean>;
|
|
20
|
+
watch(id: string, target: string, sessionId?: string): Promise<ExitResult | undefined>;
|
|
21
|
+
input(target: string, text: string): Promise<boolean>;
|
|
22
|
+
get(name: string): PtyRun | undefined;
|
|
23
|
+
readOutcome(id: string, sessionId: string): ExitResult | undefined;
|
|
24
|
+
private trackCompletion;
|
|
25
|
+
private client;
|
|
26
|
+
private resolveClient;
|
|
27
|
+
private prepareFiles;
|
|
28
|
+
private auxPaths;
|
|
29
|
+
private logPipeCommand;
|
|
30
|
+
private monitor;
|
|
31
|
+
private interactiveRun;
|
|
32
|
+
}
|
|
33
|
+
declare function rmuxPackageForTarget(platform: string, architecture: string): string | undefined;
|
|
34
|
+
//#endregion
|
|
35
|
+
export { RmuxBackend, rmuxPackageForTarget };
|
|
36
|
+
//# sourceMappingURL=RmuxBackend.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RmuxBackend.d.mts","names":[],"sources":["../../../src/services/RmuxBackend/RmuxBackend.ts"],"mappings":";;;;;;;;;;;cA8Ca,uBAAuB;mBAKsB;UAJhD;mBACS;mBACA;EAEuC,YAAA,OAAO;EAEzD,OAAO,SAAS,oBAAoB,QAAQ;EA6E5C,KAAK,gBAAgB,sBAAsB;EA6B3C,MAAM,YAAY,gBAAgB,qBAAqB,QAAQ;EAe/D,MAAM,gBAAgB,eAAe;EAc3C,IAAI,eAAe;EAInB,YAAY,YAAY,oBAAoB;UAIpC;UAOA;UAKM;UAgBN;UAUA;UAIA;UAWM;UAoBN;;iBA4CM,qBAAqB,kBAAkB"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{getLogMaxBytes as e,getResultMaxBytes as t}from"../../config.mjs";import{TYPES as n}from"../../types.mjs";import r from"../../_virtual/_@oxc-project_runtime@0.143.0/helpers/esm/decorateMetadata.mjs";import i from"../../_virtual/_@oxc-project_runtime@0.143.0/helpers/esm/decorateParam.mjs";import a from"../../_virtual/_@oxc-project_runtime@0.143.0/helpers/esm/decorate.mjs";import{NO_TERMINAL_INPUT_ENV as o,cleanupSupervisorFiles as s,readExitMetadata as c,runtimeEntry as l,shellJoin as u,supervisorPaths as d,writeCommandSpec as f}from"../../runnerSpec.mjs";import{createRequire as p}from"node:module";import{inject as m,injectable as h}from"inversify";import"reflect-metadata/lite";import{createHash as g}from"node:crypto";import _ from"node:fs";import v from"node:path";import{RMUX as y}from"@rmux/sdk";const b=1e3,x=`doom-runner-`,S=/^doom-runner-[A-Za-z0-9_-]+$/,C={NO_COLOR:`1`,CI:`1`},w={"darwin-arm64":`@agimon-ai/doompi-runner-rmux-darwin-arm64`,"darwin-x64":`@agimon-ai/doompi-runner-rmux-darwin-x64`,"linux-arm64":`@agimon-ai/doompi-runner-rmux-linux-arm64`,"linux-x64":`@agimon-ai/doompi-runner-rmux-linux-x64`};let T=class{paths;clientPromise;runs=new Map;completions=new Map;constructor(e){this.paths=e}async launch(e){let n=await this.client();if(!n)return;this.paths.ensureDirectories();let r=`${x}${e.id}`,i=this.paths.logPathFor(e.id),a=this.auxPaths(e.id,e.sessionId),o=!1,c=!1;try{this.prepareFiles(e,i,a),await n.cmd(`new-session`,`-d`,`-s`,r,`-c`,e.cwd,process.execPath,l(`runnerHost`),a.spec,a.gate,a.exit,{check:!0}),o=!0,await n.cmd(`pipe-pane`,`-t`,r,this.logPipeCommand(i,a.logDone),{check:!0});let s=n.session(r).pane(0,0),u=await A(n,r);_.writeFileSync(a.gate,``,{mode:384}),c=!0;let d=!0,f=this.monitor(n,s,r,a);this.trackCompletion(r,f);let p={id:e.id,name:e.name,pid:u,logPath:i,backend:`rmux`,backendTarget:r,output:()=>d?R(i,t()*2):``,completion:()=>f,detach:()=>{d=!1},stop:()=>this.stop(r,u)};return e.interactive&&this.runs.set(e.name,this.interactiveRun(p,s,f)),f.finally(()=>this.runs.delete(e.name)).catch(e=>process.emitWarning(`RMUX completion failed for ${r}: ${B(e)}`)),p}catch(e){if(c)throw e;o&&await n.session(r).kill().catch(e=>process.emitWarning(`Could not clean up failed RMUX launch ${r}: ${B(e)}`)),s(a),process.emitWarning(`RMUX launch unavailable, using native runner: ${B(e)}`);return}}async stop(e,t){if(!S.test(e)||!Number.isInteger(t)||t<=0)return!1;let n=await this.client();if(!n)return!1;try{if(await I(n,e))return!0;let r=await A(n,e);if(r!==t)return!1;let i=L(r,e);return i===`gone`?!0:i===`failed`?!1:await P(n,e,3e3)||await I(n,e)?!0:await A(n,e)===t&&N(n,e)}catch(t){return process.emitWarning(`Could not stop RMUX target ${e}: ${B(t)}`),!1}}async watch(e,t,n){let r=await this.client();if(!r)return;let i=r.session(t).pane(0,0);try{await r.displayMessage(`#{pane_id}`,{target:t})}catch(e){process.emitWarning(`Could not watch RMUX target ${t}: ${B(e)}`);return}let a=this.monitor(r,i,t,this.auxPaths(e,n));return this.trackCompletion(t,a),a}async input(e,t){let n=await this.client();return n?await n.session(e).pane(0,0).sendText(t).catch(t=>{process.emitWarning(`Could not send input to RMUX target ${e}: ${B(t)}`)})!==void 0:!1}get(e){return this.runs.get(e)}readOutcome(e,t){return c(this.auxPaths(e,t).exit)}trackCompletion(e,t){this.completions.set(e,t),t.finally(()=>this.completions.delete(e)).catch(t=>process.emitWarning(`RMUX monitor failed for ${e}: ${B(t)}`))}client(){return this.clientPromise??=this.resolveClient(),this.clientPromise}async resolveClient(){let e=[D(),`rmux`].filter(e=>e!==void 0);for(let t of e)try{t!==`rmux`&&_.chmodSync(t,493);let e=new y({binary:t,socketName:O(this.paths.repositoryPath())});return await e.capabilities(),e}catch(e){process.emitWarning(`RMUX candidate ${t} is unavailable: ${B(e)}`)}}prepareFiles(e,t,n){s(n),_.writeFileSync(t,``,{mode:384});let r=k(e.sessionId,e.interactive),i={command:e.command,cwd:e.cwd,env:r};f(n.spec,i)}auxPaths(e,t){return d(this.paths.stateDirectory(t),e)}logPipeCommand(t,n){return u([process.execPath,l(`logSink`),t,this.paths.rotatedLogPathFor(v.basename(t,`.log`)),String(e()),n])}async monitor(e,t,n,r){try{let t=await j(e,n,r.exit);return await M(e,n,r.logDone),c(r.exit)??{code:t,signal:null}}finally{await I(e,n).catch(()=>!1)||await t.server.session(n).kill().catch(e=>process.emitWarning(`Could not clean up completed RMUX target ${n}: ${B(e)}`)),s(r)}}interactiveRun(e,t,n){let r=``,i=!0,a=new Set;return(async()=>{for(;i;){let n=await t.captureText().catch(t=>(process.emitWarning(`Could not capture RMUX screen for ${e.name}: ${B(t)}`),r));if(n!==r){r=n;for(let e of a)e(n)}await z(100)}})(),n.finally(()=>{i=!1}).catch(t=>process.emitWarning(`RMUX interactive completion failed for ${e.name}: ${B(t)}`)),{...e,write:e=>{t.sendText(e).catch(e=>process.emitWarning(B(e)))},screen:()=>r,onData:e=>(a.add(e),()=>a.delete(e)),resize:(e,n)=>{t.resize({width:e,height:n}).catch(e=>process.emitWarning(B(e)))}}}};T=a([h(),i(0,m(n.RunnerPaths)),r(`design:paramtypes`,[Object])],T);function E(e,t){let n=`${e}-${t}`,r=w[n];return r||process.emitWarning(`Bundled RMUX binary is unavailable for unsupported target ${n}`),r}function D(){let e=E(process.platform,process.arch);if(e)try{let t=p(import.meta.url).resolve(`${e}/package.json`);return v.join(v.dirname(t),`vendor`,`bin`,`rmux`)}catch(t){process.emitWarning(`Bundled RMUX binary is unavailable for ${e}: ${B(t)}`);return}}function O(e){let t=g(`sha256`).update(e).digest(`hex`).slice(0,12);return`${x}${t}`}function k(e,t){let n={...process.env,...t?{}:C,...o,PI_SESSION_ID:e};return t||delete n.FORCE_COLOR,Object.fromEntries(Object.entries(n).filter(e=>e[1]!==void 0))}async function A(e,t){let n=await e.displayMessage(`#{pane_pid}`,{target:t}),r=Number(n.message);if(!Number.isInteger(r)||r<=0)throw Error(`RMUX did not report a pane pid for ${t}`);return r}async function j(e,t,n){for(;;){if(_.existsSync(n))return null;let r=await F(e,t);if(r.exited)return r.code;await z(100)}}async function M(e,t,n){let r=Date.now()+2e3;for(;Date.now()<r;){if(_.existsSync(n)||await I(e,t))return;await z(25)}}async function N(e,t){return new Promise(n=>{let r=!1,i=e=>{r||(r=!0,clearTimeout(a),n(e))},a=setTimeout(()=>{process.emitWarning(`Timed out closing RMUX target ${t} after ${b}ms`),i(!1)},b);e.session(t).kill().then(()=>i(!0),e=>{process.emitWarning(`Could not close RMUX target ${t}: ${B(e)}`),i(!1)})})}async function P(e,t,n){let r=Date.now()+n;for(;Date.now()<r;){try{if((await F(e,t)).exited)return!0}catch(e){return process.emitWarning(`Could not verify RMUX target ${t} stopped: ${B(e)}`),!1}await z(100)}return!1}async function F(e,t){let n;try{let r=await e.displayMessage(`#{pane_dead}:#{pane_dead_status}:#{session_name}`,{target:t});n=typeof r.message==`string`?r.message:``}catch{return{exited:!0,code:null}}let[r,i,...a]=n.trim().split(`:`);if(a.join(`:`)===``)return{exited:!0,code:null};if(r===`1`||r===`true`){let e=Number(i);return{exited:!0,code:Number.isInteger(e)?e:null}}return{exited:!1,code:null}}async function I(e,t){try{return(await e.cmd(`has-session`,`-t`,t)).returnCode!==0}catch{return!0}}function L(e,t){try{return process.kill(e,`SIGTERM`),`signalled`}catch(e){return e.code===`ESRCH`?`gone`:(process.emitWarning(`Could not signal RMUX target ${t}: ${B(e)}`),`failed`)}}function R(e,t){try{let n=_.readFileSync(e,`utf8`);return n.length>t?n.slice(-t):n}catch(t){return t.code!==`ENOENT`&&process.emitWarning(`Could not read RMUX log ${e}: ${B(t)}`),``}}function z(e){return new Promise(t=>{setTimeout(t,e).unref?.()})}function B(e){return e instanceof Error?e.message:String(e)}export{T as RmuxBackend,E as rmuxPackageForTarget};
|
|
2
|
+
//# sourceMappingURL=RmuxBackend.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RmuxBackend.mjs","names":[],"sources":["../../../src/services/RmuxBackend/RmuxBackend.ts"],"sourcesContent":["import { createHash } from 'node:crypto';\nimport fs from 'node:fs';\nimport { createRequire } from 'node:module';\nimport path from 'node:path';\nimport { inject, injectable } from 'inversify';\nimport { RMUX, type Pane, type Rmux } from '@rmux/sdk';\nimport 'reflect-metadata/lite';\nimport { getLogMaxBytes, getResultMaxBytes } from '../../config.ts';\nimport {\n type CommandSpec,\n NO_TERMINAL_INPUT_ENV,\n type SupervisorPaths,\n cleanupSupervisorFiles,\n readExitMetadata,\n runtimeEntry,\n shellJoin,\n supervisorPaths,\n writeCommandSpec,\n} from '../../runnerSpec.ts';\nimport { TYPES } from '../../types.ts';\nimport type { ExitResult } from '../Spawner/index.ts';\nimport type { RunHandle } from '../Launcher/index.ts';\nimport type { PtyRun } from '../PtyHost/index.ts';\nimport type { IRunnerPaths } from '../RunnerPaths/index.ts';\nimport type { IRmuxBackend, RmuxLaunchRequest } from './types.ts';\n\nconst POLL_MS = 100;\nconst LOG_DRAIN_TIMEOUT_MS = 2_000;\nconst LOG_DRAIN_POLL_MS = 25;\n/** Pane liveness, its exit status, and whether the session still exists, in one read. */\nconst PANE_STATE_FORMAT = '#{pane_dead}:#{pane_dead_status}:#{session_name}';\nconst STOP_GRACE_MS = 3_000;\nconst STOP_CLOSE_TIMEOUT_MS = 1_000;\nconst EXECUTABLE_MODE = 0o755;\nconst SESSION_PREFIX = 'doom-runner-';\nconst OWNED_TARGET_PATTERN = /^doom-runner-[A-Za-z0-9_-]+$/;\nconst SOCKET_HASH_LENGTH = 12;\nconst NON_INTERACTIVE_ENV = { NO_COLOR: '1', CI: '1' };\nconst PACKAGE_BY_PLATFORM: Readonly<Record<string, string>> = {\n 'darwin-arm64': '@agimon-ai/doompi-runner-rmux-darwin-arm64',\n 'darwin-x64': '@agimon-ai/doompi-runner-rmux-darwin-x64',\n 'linux-arm64': '@agimon-ai/doompi-runner-rmux-linux-arm64',\n 'linux-x64': '@agimon-ai/doompi-runner-rmux-linux-x64',\n};\n\n@injectable()\nexport class RmuxBackend implements IRmuxBackend {\n private clientPromise: Promise<Rmux | undefined> | undefined;\n private readonly runs = new Map<string, PtyRun>();\n private readonly completions = new Map<string, Promise<ExitResult>>();\n\n constructor(@inject(TYPES.RunnerPaths) private readonly paths: IRunnerPaths) {}\n\n async launch(request: RmuxLaunchRequest): Promise<RunHandle | undefined> {\n const rmux = await this.client();\n if (!rmux) return undefined;\n\n this.paths.ensureDirectories();\n const target = `${SESSION_PREFIX}${request.id}`;\n const logPath = this.paths.logPathFor(request.id);\n const aux = this.auxPaths(request.id, request.sessionId);\n let created = false;\n let released = false;\n\n try {\n this.prepareFiles(request, logPath, aux);\n await rmux.cmd(\n 'new-session',\n '-d',\n '-s',\n target,\n '-c',\n request.cwd,\n process.execPath,\n runtimeEntry('runnerHost'),\n aux.spec,\n aux.gate,\n aux.exit,\n { check: true },\n );\n created = true;\n // No remain-on-exit: a finished pane ends its session, and the last session\n // ending stops the server, so a completed run leaves no process behind.\n await rmux.cmd('pipe-pane', '-t', target, this.logPipeCommand(logPath, aux.logDone), { check: true });\n\n const pane = rmux.session(target).pane(0, 0);\n const pid = await panePid(rmux, target);\n fs.writeFileSync(aux.gate, '', { mode: 0o600 });\n released = true;\n\n let buffering = true;\n const completion = this.monitor(rmux, pane, target, aux);\n this.trackCompletion(target, completion);\n const stop = (): Promise<boolean> => this.stop(target, pid);\n const handle: RunHandle = {\n id: request.id,\n name: request.name,\n pid,\n logPath,\n backend: 'rmux',\n backendTarget: target,\n output: () => (buffering ? readTail(logPath, getResultMaxBytes() * 2) : ''),\n completion: () => completion,\n detach: () => {\n buffering = false;\n },\n stop,\n };\n\n if (request.interactive) this.runs.set(request.name, this.interactiveRun(handle, pane, completion));\n void completion\n .finally(() => this.runs.delete(request.name))\n .catch((error: unknown) => process.emitWarning(`RMUX completion failed for ${target}: ${errorMessage(error)}`));\n return handle;\n } catch (error) {\n if (released) throw error;\n if (created) {\n await rmux\n .session(target)\n .kill()\n .catch((cleanupError: unknown) =>\n process.emitWarning(`Could not clean up failed RMUX launch ${target}: ${errorMessage(cleanupError)}`),\n );\n }\n cleanupSupervisorFiles(aux);\n process.emitWarning(`RMUX launch unavailable, using native runner: ${errorMessage(error)}`);\n return undefined;\n }\n }\n\n async stop(target: string, expectedPid: number): Promise<boolean> {\n if (!OWNED_TARGET_PATTERN.test(target) || !Number.isInteger(expectedPid) || expectedPid <= 0) return false;\n\n const rmux = await this.client();\n if (!rmux) return false;\n try {\n // A session that already ended took its process group with it.\n if (await sessionMissing(rmux, target)) return true;\n\n const pid = await panePid(rmux, target);\n if (pid !== expectedPid) return false;\n const signalled = signalPane(pid, target);\n if (signalled === 'gone') return true;\n if (signalled === 'failed') return false;\n\n if (await waitForPaneStop(rmux, target, STOP_GRACE_MS)) return true;\n if (await sessionMissing(rmux, target)) return true;\n\n // Revalidate after the grace period so a replacement pane is never closed.\n const currentPid = await panePid(rmux, target);\n if (currentPid !== expectedPid) return false;\n\n return closeOwnedSession(rmux, target);\n } catch (error) {\n process.emitWarning(`Could not stop RMUX target ${target}: ${errorMessage(error)}`);\n return false;\n }\n }\n\n async watch(id: string, target: string, sessionId?: string): Promise<ExitResult | undefined> {\n const rmux = await this.client();\n if (!rmux) return undefined;\n const pane = rmux.session(target).pane(0, 0);\n try {\n await rmux.displayMessage('#{pane_id}', { target });\n } catch (error) {\n process.emitWarning(`Could not watch RMUX target ${target}: ${errorMessage(error)}`);\n return undefined;\n }\n const completion = this.monitor(rmux, pane, target, this.auxPaths(id, sessionId));\n this.trackCompletion(target, completion);\n return completion;\n }\n\n async input(target: string, text: string): Promise<boolean> {\n const rmux = await this.client();\n if (!rmux) return false;\n const result = await rmux\n .session(target)\n .pane(0, 0)\n .sendText(text)\n .catch((error: unknown) => {\n process.emitWarning(`Could not send input to RMUX target ${target}: ${errorMessage(error)}`);\n return undefined;\n });\n return result !== undefined;\n }\n\n get(name: string): PtyRun | undefined {\n return this.runs.get(name);\n }\n\n readOutcome(id: string, sessionId: string): ExitResult | undefined {\n return readExitMetadata(this.auxPaths(id, sessionId).exit);\n }\n\n private trackCompletion(target: string, completion: Promise<ExitResult>): void {\n this.completions.set(target, completion);\n void completion\n .finally(() => this.completions.delete(target))\n .catch((error: unknown) => process.emitWarning(`RMUX monitor failed for ${target}: ${errorMessage(error)}`));\n }\n\n private client(): Promise<Rmux | undefined> {\n this.clientPromise ??= this.resolveClient();\n return this.clientPromise;\n }\n\n private async resolveClient(): Promise<Rmux | undefined> {\n const binaries = [bundledBinary(), 'rmux'].filter((value): value is string => value !== undefined);\n for (const binary of binaries) {\n try {\n if (binary !== 'rmux') fs.chmodSync(binary, EXECUTABLE_MODE);\n const client = new RMUX({ binary, socketName: socketName(this.paths.repositoryPath()) });\n await client.capabilities();\n return client;\n } catch (error) {\n process.emitWarning(`RMUX candidate ${binary} is unavailable: ${errorMessage(error)}`);\n // Try the next compatible candidate, then let the native launcher take over.\n }\n }\n return undefined;\n }\n\n private prepareFiles(request: RmuxLaunchRequest, logPath: string, aux: SupervisorPaths): void {\n cleanupSupervisorFiles(aux);\n fs.writeFileSync(logPath, '', { mode: 0o600 });\n const env = environment(request.sessionId, request.interactive);\n // runnerHost supervises the command and watches the lifeline itself, so an\n // owner that dies mid-run is handled inside the pane rather than around it.\n const spec: CommandSpec = { command: request.command, cwd: request.cwd, env };\n writeCommandSpec(aux.spec, spec);\n }\n\n private auxPaths(id: string, sessionId?: string): SupervisorPaths {\n return supervisorPaths(this.paths.stateDirectory(sessionId), id);\n }\n\n private logPipeCommand(logPath: string, donePath: string): string {\n return shellJoin([\n process.execPath,\n runtimeEntry('logSink'),\n logPath,\n this.paths.rotatedLogPathFor(path.basename(logPath, '.log')),\n String(getLogMaxBytes()),\n donePath,\n ]);\n }\n\n private async monitor(rmux: Rmux, pane: Pane, target: string, aux: SupervisorPaths): Promise<ExitResult> {\n try {\n const paneCode = await waitForRunEnd(rmux, target, aux.exit);\n await waitForLogDrain(rmux, target, aux.logDone);\n return readExitMetadata(aux.exit) ?? { code: paneCode, signal: null };\n } finally {\n // The pane ends its own session, so this only covers a session that somehow\n // outlived its pane. Killing unconditionally would warn on every clean run.\n if (!(await sessionMissing(rmux, target).catch(() => false))) {\n await pane.server\n .session(target)\n .kill()\n .catch((error: unknown) =>\n process.emitWarning(`Could not clean up completed RMUX target ${target}: ${errorMessage(error)}`),\n );\n }\n cleanupSupervisorFiles(aux);\n }\n }\n\n private interactiveRun(handle: RunHandle, pane: Pane, completion: Promise<ExitResult>): PtyRun {\n let screen = '';\n let active = true;\n const handlers = new Set<(data: string) => void>();\n const refresh = async (): Promise<void> => {\n while (active) {\n const next = await pane.captureText().catch((error: unknown) => {\n process.emitWarning(`Could not capture RMUX screen for ${handle.name}: ${errorMessage(error)}`);\n return screen;\n });\n if (next !== screen) {\n screen = next;\n for (const handler of handlers) handler(next);\n }\n await delay(POLL_MS);\n }\n };\n void refresh();\n void completion\n .finally(() => {\n active = false;\n })\n .catch((error: unknown) =>\n process.emitWarning(`RMUX interactive completion failed for ${handle.name}: ${errorMessage(error)}`),\n );\n return {\n ...handle,\n write: (text) => {\n void pane.sendText(text).catch((error: unknown) => process.emitWarning(errorMessage(error)));\n },\n screen: () => screen,\n onData: (handler) => {\n handlers.add(handler);\n return () => handlers.delete(handler);\n },\n resize: (cols, rows) => {\n void pane\n .resize({ width: cols, height: rows })\n .catch((error: unknown) => process.emitWarning(errorMessage(error)));\n },\n };\n }\n}\n\nexport function rmuxPackageForTarget(platform: string, architecture: string): string | undefined {\n const target = `${platform}-${architecture}`;\n const packageName = PACKAGE_BY_PLATFORM[target];\n if (!packageName) process.emitWarning(`Bundled RMUX binary is unavailable for unsupported target ${target}`);\n return packageName;\n}\n\nfunction bundledBinary(): string | undefined {\n const packageName = rmuxPackageForTarget(process.platform, process.arch);\n if (!packageName) return undefined;\n try {\n const require = createRequire(import.meta.url);\n const manifest = require.resolve(`${packageName}/package.json`);\n return path.join(path.dirname(manifest), 'vendor', 'bin', 'rmux');\n } catch (error) {\n process.emitWarning(`Bundled RMUX binary is unavailable for ${packageName}: ${errorMessage(error)}`);\n return undefined;\n }\n}\n\nfunction socketName(repositoryPath: string): string {\n const hash = createHash('sha256').update(repositoryPath).digest('hex').slice(0, SOCKET_HASH_LENGTH);\n return `${SESSION_PREFIX}${hash}`;\n}\n\nfunction environment(sessionId: string, interactive: boolean): Record<string, string> {\n const values: NodeJS.ProcessEnv = {\n ...process.env,\n ...(interactive ? {} : NON_INTERACTIVE_ENV),\n // Applied to interactive runs as well: a pane is a tty either way, and an\n // agent sending input to a prompt still has no way past a pager.\n ...NO_TERMINAL_INPUT_ENV,\n PI_SESSION_ID: sessionId,\n };\n if (!interactive) delete values['FORCE_COLOR'];\n return Object.fromEntries(\n Object.entries(values).filter((entry): entry is [string, string] => entry[1] !== undefined),\n );\n}\n\nasync function panePid(rmux: Rmux, target: string): Promise<number> {\n const response = await rmux.displayMessage('#{pane_pid}', { target });\n const pid = Number(response['message']);\n if (!Number.isInteger(pid) || pid <= 0) throw new Error(`RMUX did not report a pane pid for ${target}`);\n return pid;\n}\n\n/**\n * Waits for the run to end, preferring the supervisor's own record of it.\n *\n * The sidecar is written before the command's pane can end, and it outlives the\n * server that the pane's exit takes down with it. Asking the server is the\n * fallback for a supervisor that died without recording anything.\n */\nasync function waitForRunEnd(rmux: Rmux, target: string, exitPath: string): Promise<number | null> {\n for (;;) {\n if (fs.existsSync(exitPath)) return null;\n const state = await readPaneExit(rmux, target);\n if (state.exited) return state.code;\n await delay(POLL_MS);\n }\n}\n\n/**\n * Gives the log sink a moment to mark the log complete.\n *\n * The sink dies with the session it was piped from, so once the session is gone\n * the marker is never coming and there is nothing left to wait for. Its writes\n * are synchronous, so the log itself is already on disk either way.\n */\nasync function waitForLogDrain(rmux: Rmux, target: string, donePath: string): Promise<void> {\n const deadline = Date.now() + LOG_DRAIN_TIMEOUT_MS;\n while (Date.now() < deadline) {\n if (fs.existsSync(donePath)) return;\n if (await sessionMissing(rmux, target)) return;\n await delay(LOG_DRAIN_POLL_MS);\n }\n}\n\nasync function closeOwnedSession(rmux: Rmux, target: string): Promise<boolean> {\n return new Promise((resolve) => {\n let settled = false;\n const finish = (result: boolean): void => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n resolve(result);\n };\n const timer = setTimeout(() => {\n process.emitWarning(`Timed out closing RMUX target ${target} after ${STOP_CLOSE_TIMEOUT_MS}ms`);\n finish(false);\n }, STOP_CLOSE_TIMEOUT_MS);\n void rmux\n .session(target)\n .kill()\n .then(\n () => finish(true),\n (error: unknown) => {\n process.emitWarning(`Could not close RMUX target ${target}: ${errorMessage(error)}`);\n finish(false);\n },\n );\n });\n}\n\nasync function waitForPaneStop(rmux: Rmux, target: string, timeoutMs: number): Promise<boolean> {\n const deadline = Date.now() + timeoutMs;\n while (Date.now() < deadline) {\n try {\n if ((await readPaneExit(rmux, target)).exited) return true;\n } catch (error) {\n process.emitWarning(`Could not verify RMUX target ${target} stopped: ${errorMessage(error)}`);\n return false;\n }\n await delay(POLL_MS);\n }\n return false;\n}\n\n/**\n * One formatted read answers both questions this poll asks, so watching a run\n * costs the same single rmux call it always did.\n */\nasync function readPaneExit(rmux: Rmux, target: string): Promise<{ exited: boolean; code: number | null }> {\n let message: string;\n try {\n const response = await rmux.displayMessage(PANE_STATE_FORMAT, { target });\n message = typeof response['message'] === 'string' ? response['message'] : '';\n } catch {\n // The last session ending stops the server, so a server that cannot be\n // reached is the ordinary end of the last run rather than a fault.\n return { exited: true, code: null };\n }\n const [dead, status, ...rest] = message.trim().split(':');\n // A missing session formats as a live pane with no name rather than failing,\n // so the name is what says whether there is still anything to watch.\n if (rest.join(':') === '') return { exited: true, code: null };\n if (dead === '1' || dead === 'true') {\n const code = Number(status);\n return { exited: true, code: Number.isInteger(code) ? code : null };\n }\n return { exited: false, code: null };\n}\n\n/** A session that cannot be found, on a server that may itself be gone. */\nasync function sessionMissing(rmux: Rmux, target: string): Promise<boolean> {\n try {\n const probe = await rmux.cmd('has-session', '-t', target);\n return probe.returnCode !== 0;\n } catch {\n // No server to ask means no session to find.\n return true;\n }\n}\n\n/**\n * A pane that was already gone and a signal that could not be delivered are\n * opposite answers to \"is it stopped\", so they are reported apart.\n */\nfunction signalPane(pid: number, target: string): 'signalled' | 'gone' | 'failed' {\n try {\n process.kill(pid, 'SIGTERM');\n return 'signalled';\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ESRCH') return 'gone';\n process.emitWarning(`Could not signal RMUX target ${target}: ${errorMessage(error)}`);\n return 'failed';\n }\n}\n\nfunction readTail(target: string, maxBytes: number): string {\n try {\n const text = fs.readFileSync(target, 'utf8');\n return text.length > maxBytes ? text.slice(-maxBytes) : text;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') {\n process.emitWarning(`Could not read RMUX log ${target}: ${errorMessage(error)}`);\n }\n return '';\n }\n}\n\nfunction delay(ms: number): Promise<void> {\n return new Promise((resolve) => {\n const timer = setTimeout(resolve, ms);\n timer.unref?.();\n });\n}\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./RmuxBackend.cjs");Object.defineProperty(exports,"RmuxBackend",{enumerable:!0,get:function(){return e.RmuxBackend}}),exports.rmuxPackageForTarget=e.rmuxPackageForTarget;
|