@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
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Vuong Ngo
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# @agimon-ai/doompi-runner
|
|
2
|
+
|
|
3
|
+
Pi bash tool replacement with background process supervision.
|
|
4
|
+
|
|
5
|
+
Replaces the built-in bash tool with a supervised one. Long commands are backgrounded
|
|
6
|
+
instead of blocking, a process tool manages them, and detached runs reconcile themselves
|
|
7
|
+
after the context is rewritten.
|
|
8
|
+
|
|
9
|
+
Part of [Doompi](https://www.npmjs.com/package/@agimon-ai/doompi), a coding agent that loads
|
|
10
|
+
only the skills and tools you name. This package is composed by Doompi and is not usually
|
|
11
|
+
installed on its own.
|
|
12
|
+
|
|
13
|
+
## Install
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install @agimon-ai/doompi-runner
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## How it loads
|
|
20
|
+
|
|
21
|
+
Name it in a layer in `.doom/modes.yaml`, then add that layer to a major mode:
|
|
22
|
+
|
|
23
|
+
```yaml
|
|
24
|
+
layers:
|
|
25
|
+
runner:
|
|
26
|
+
packages: ['@agimon-ai/doompi-runner/extensions/pi']
|
|
27
|
+
|
|
28
|
+
majorMode:
|
|
29
|
+
dev: [runner]
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Leader
|
|
33
|
+
|
|
34
|
+
`SPC r r` opens background processes, once the extension is loaded.
|
|
35
|
+
|
|
36
|
+
## Notes
|
|
37
|
+
|
|
38
|
+
Ships a prebuilt `rmux` binary per platform through the `@agimon-ai/doompi-runner-rmux-*`
|
|
39
|
+
optional dependencies.
|
|
40
|
+
|
|
41
|
+
## Entry points
|
|
42
|
+
|
|
43
|
+
51 subpaths are declared in the `exports` field of `package.json`.
|
|
44
|
+
|
|
45
|
+
## License
|
|
46
|
+
|
|
47
|
+
MIT
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function e(e,t,n,r){var i=arguments.length,a=i<3?t:r===null?r=Object.getOwnPropertyDescriptor(t,n):r,o;if(typeof Reflect==`object`&&typeof Reflect.decorate==`function`)a=Reflect.decorate(e,t,n,r);else for(var s=e.length-1;s>=0;s--)(o=e[s])&&(a=(i<3?o(a):i>3?o(t,n,a):o(t,n))||a);return i>3&&a&&Object.defineProperty(t,n,a),a}exports.default=e;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function e(e,t,n,r){var i=arguments.length,a=i<3?t:r===null?r=Object.getOwnPropertyDescriptor(t,n):r,o;if(typeof Reflect==`object`&&typeof Reflect.decorate==`function`)a=Reflect.decorate(e,t,n,r);else for(var s=e.length-1;s>=0;s--)(o=e[s])&&(a=(i<3?o(a):i>3?o(t,n,a):o(t,n))||a);return i>3&&a&&Object.defineProperty(t,n,a),a}export{e as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function e(e,t){if(typeof Reflect==`object`&&typeof Reflect.metadata==`function`)return Reflect.metadata(e,t)}exports.default=e;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function e(e,t){if(typeof Reflect==`object`&&typeof Reflect.metadata==`function`)return Reflect.metadata(e,t)}export{e as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function e(e,t){return function(n,r){t(n,r,e)}}exports.default=e;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function e(e,t){return function(n,r){t(n,r,e)}}export{e as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},s=(n,r,s)=>(s=n==null?{}:e(i(n)),o(r||!n||!n.__esModule||!a.call(n,`default`)?t(s,`default`,{value:n,enumerable:!0}):s,n));exports.__toESM=s;
|
package/dist/bin/cli.cjs
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../types.cjs"),t=require("../container/index.cjs"),n=require("../cli/cliApp.cjs");let r=require("node:url"),i=require("@agimon-ai/doompi-telemetry");async function a(){let e=[];for await(let t of process.stdin)e.push(Buffer.isBuffer(t)?t:Buffer.from(t));return Buffer.concat(e).toString(`utf8`)}async function o(r=process.argv.slice(2)){let o=Date.now(),s=(0,i.createDoomTelemetry)({serviceName:`doom-runner-cli`,packageName:`@agimon-ai/doompi-runner`,env:process.env,enableLogs:!0,enableTraces:!0}),c=t.createRunnerContainer(),l=c.get(e.TYPES.RunnerRegistry),u=0,d=0;try{let t=await n.runCli(r,{registry:l,launcher:c.get(e.TYPES.Launcher),rmuxBackend:c.get(e.TYPES.RmuxBackend),logReader:c.get(e.TYPES.LogReader),env:process.env,stdout:e=>{let t=e.endsWith(`
|
|
3
|
+
`)?e:`${e}\n`;u+=Buffer.byteLength(t,`utf8`),process.stdout.write(t)},stderr:e=>{let t=e.endsWith(`
|
|
4
|
+
`)?e:`${e}\n`;d+=Buffer.byteLength(t,`utf8`),process.stderr.write(t)},readStdin:a});return await s.recordEvent(`doom_runner.cli_finished`,{outcome:t===0?`completed`:`failed`,"runner.exit_code":t,duration_ms:Date.now()-o,"runner.argument_count":r.length,"runner.stdout_bytes":u,"runner.stderr_bytes":d}),t}catch(e){throw await s.recordError(`doom_runner.cli_failed`,e,{duration_ms:Date.now()-o,"runner.argument_count":r.length,"runner.stdout_bytes":u,"runner.stderr_bytes":d}),e}finally{l.close(),await s.shutdown()}}process.argv[1]&&require("url").pathToFileURL(__filename).href===(0,r.pathToFileURL)(process.argv[1]).href&&o().then(e=>{process.exitCode=e},e=>{process.stderr.write(`${e instanceof Error?e.message:String(e)}\n`),process.exitCode=1}),exports.main=o;
|
|
5
|
+
//# sourceMappingURL=cli.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.cjs","names":["createDoomTelemetry","createRunnerContainer","TYPES","runCli","pathToFileURL"],"sources":["../../src/bin/cli.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { createDoomTelemetry } from '@agimon-ai/doompi-telemetry';\nimport { createRunnerContainer } from '../container/index.ts';\nimport { pathToFileURL } from 'node:url';\nimport type { ILauncher } from '../services/Launcher/index.ts';\nimport type { ILogReader } from '../services/LogReader/index.ts';\nimport type { IRunnerRegistry } from '../services/RunnerRegistry/index.ts';\nimport type { IRmuxBackend } from '../services/RmuxBackend/index.ts';\nimport { TYPES } from '../types.ts';\nimport { runCli } from '../cli/cliApp.ts';\n\nasync function readStdin(): Promise<string> {\n const chunks: Buffer[] = [];\n for await (const chunk of process.stdin) chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));\n return Buffer.concat(chunks).toString('utf8');\n}\n\nexport async function main(argv: readonly string[] = process.argv.slice(2)): Promise<number> {\n const startedAt = Date.now();\n const telemetry = createDoomTelemetry({\n serviceName: 'doom-runner-cli',\n packageName: '@agimon-ai/doompi-runner',\n env: process.env,\n enableLogs: true,\n enableTraces: true,\n });\n const container = createRunnerContainer();\n const registry = container.get<IRunnerRegistry>(TYPES.RunnerRegistry);\n let stdoutBytes = 0;\n let stderrBytes = 0;\n try {\n const exitCode = await runCli(argv, {\n registry,\n launcher: container.get<ILauncher>(TYPES.Launcher),\n rmuxBackend: container.get<IRmuxBackend>(TYPES.RmuxBackend),\n logReader: container.get<ILogReader>(TYPES.LogReader),\n env: process.env,\n stdout: (text) => {\n const output = text.endsWith('\\n') ? text : `${text}\\n`;\n stdoutBytes += Buffer.byteLength(output, 'utf8');\n process.stdout.write(output);\n },\n stderr: (text) => {\n const output = text.endsWith('\\n') ? text : `${text}\\n`;\n stderrBytes += Buffer.byteLength(output, 'utf8');\n process.stderr.write(output);\n },\n readStdin,\n });\n await telemetry.recordEvent('doom_runner.cli_finished', {\n outcome: exitCode === 0 ? 'completed' : 'failed',\n 'runner.exit_code': exitCode,\n duration_ms: Date.now() - startedAt,\n 'runner.argument_count': argv.length,\n 'runner.stdout_bytes': stdoutBytes,\n 'runner.stderr_bytes': stderrBytes,\n });\n return exitCode;\n } catch (error) {\n await telemetry.recordError('doom_runner.cli_failed', error, {\n duration_ms: Date.now() - startedAt,\n 'runner.argument_count': argv.length,\n 'runner.stdout_bytes': stdoutBytes,\n 'runner.stderr_bytes': stderrBytes,\n });\n throw error;\n } finally {\n registry.close();\n await telemetry.shutdown();\n }\n}\n\nif (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {\n main().then(\n (code) => {\n process.exitCode = code;\n },\n (error: unknown) => {\n process.stderr.write(`${error instanceof Error ? error.message : String(error)}\\n`);\n process.exitCode = 1;\n },\n );\n}\n"],"mappings":";yOAYA,eAAe,GAA6B,CAC1C,IAAM,EAAmB,CAAC,EAC1B,UAAW,IAAM,KAAS,QAAQ,MAAO,EAAO,KAAK,OAAO,SAAS,CAAK,EAAI,EAAQ,OAAO,KAAK,CAAK,CAAC,EACxG,OAAO,OAAO,OAAO,CAAM,CAAC,CAAC,SAAS,MAAM,CAC9C,CAEA,eAAsB,EAAK,EAA0B,QAAQ,KAAK,MAAM,CAAC,EAAoB,CAC3F,IAAM,EAAY,KAAK,IAAI,EACrB,GAAA,EAAYA,EAAAA,oBAAAA,CAAoB,CACpC,YAAa,kBACb,YAAa,2BACb,IAAK,QAAQ,IACb,WAAY,GACZ,aAAc,EAChB,CAAC,EACK,EAAYC,EAAAA,sBAAsB,EAClC,EAAW,EAAU,IAAqBC,EAAAA,MAAM,cAAc,EAChE,EAAc,EACd,EAAc,EAClB,GAAI,CACF,IAAM,EAAW,MAAMC,EAAAA,OAAO,EAAM,CAClC,WACA,SAAU,EAAU,IAAeD,EAAAA,MAAM,QAAQ,EACjD,YAAa,EAAU,IAAkBA,EAAAA,MAAM,WAAW,EAC1D,UAAW,EAAU,IAAgBA,EAAAA,MAAM,SAAS,EACpD,IAAK,QAAQ,IACb,OAAS,GAAS,CAChB,IAAM,EAAS,EAAK,SAAS;CAAI,EAAI,EAAO,GAAG,EAAK,IACpD,GAAe,OAAO,WAAW,EAAQ,MAAM,EAC/C,QAAQ,OAAO,MAAM,CAAM,CAC7B,EACA,OAAS,GAAS,CAChB,IAAM,EAAS,EAAK,SAAS;CAAI,EAAI,EAAO,GAAG,EAAK,IACpD,GAAe,OAAO,WAAW,EAAQ,MAAM,EAC/C,QAAQ,OAAO,MAAM,CAAM,CAC7B,EACA,WACF,CAAC,EASD,OARA,MAAM,EAAU,YAAY,2BAA4B,CACtD,QAAS,IAAa,EAAI,YAAc,SACxC,mBAAoB,EACpB,YAAa,KAAK,IAAI,EAAI,EAC1B,wBAAyB,EAAK,OAC9B,sBAAuB,EACvB,sBAAuB,CACzB,CAAC,EACM,CACT,OAAS,EAAO,CAOd,MANA,MAAM,EAAU,YAAY,yBAA0B,EAAO,CAC3D,YAAa,KAAK,IAAI,EAAI,EAC1B,wBAAyB,EAAK,OAC9B,sBAAuB,EACvB,sBAAuB,CACzB,CAAC,EACK,CACR,QAAU,CACR,EAAS,MAAM,EACf,MAAM,EAAU,SAAS,CAC3B,CACF,CAEI,QAAQ,KAAK,IAAA,QAAA,KAAA,CAAA,CAAA,cAAA,UAAA,CAAA,CAAA,QAAA,EAA0BE,EAAAA,cAAAA,CAAc,QAAQ,KAAK,EAAE,CAAC,CAAC,MACxE,EAAK,CAAC,CAAC,KACJ,GAAS,CACR,QAAQ,SAAW,CACrB,EACC,GAAmB,CAClB,QAAQ,OAAO,MAAM,GAAG,aAAiB,MAAQ,EAAM,QAAU,OAAO,CAAK,EAAE,GAAG,EAClF,QAAQ,SAAW,CACrB,CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.cts","names":[],"sources":["../../src/bin/cli.ts"],"mappings":";iBAkBsB,KAAK,2BAAkD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.mts","names":[],"sources":["../../src/bin/cli.ts"],"mappings":";iBAkBsB,KAAK,2BAAkD"}
|
package/dist/bin/cli.mjs
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import{TYPES as e}from"../types.mjs";import{createRunnerContainer as t}from"../container/index.mjs";import{runCli as n}from"../cli/cliApp.mjs";import{pathToFileURL as r}from"node:url";import{createDoomTelemetry as i}from"@agimon-ai/doompi-telemetry";async function a(){let e=[];for await(let t of process.stdin)e.push(Buffer.isBuffer(t)?t:Buffer.from(t));return Buffer.concat(e).toString(`utf8`)}async function o(r=process.argv.slice(2)){let o=Date.now(),s=i({serviceName:`doom-runner-cli`,packageName:`@agimon-ai/doompi-runner`,env:process.env,enableLogs:!0,enableTraces:!0}),c=t(),l=c.get(e.RunnerRegistry),u=0,d=0;try{let t=await n(r,{registry:l,launcher:c.get(e.Launcher),rmuxBackend:c.get(e.RmuxBackend),logReader:c.get(e.LogReader),env:process.env,stdout:e=>{let t=e.endsWith(`
|
|
3
|
+
`)?e:`${e}\n`;u+=Buffer.byteLength(t,`utf8`),process.stdout.write(t)},stderr:e=>{let t=e.endsWith(`
|
|
4
|
+
`)?e:`${e}\n`;d+=Buffer.byteLength(t,`utf8`),process.stderr.write(t)},readStdin:a});return await s.recordEvent(`doom_runner.cli_finished`,{outcome:t===0?`completed`:`failed`,"runner.exit_code":t,duration_ms:Date.now()-o,"runner.argument_count":r.length,"runner.stdout_bytes":u,"runner.stderr_bytes":d}),t}catch(e){throw await s.recordError(`doom_runner.cli_failed`,e,{duration_ms:Date.now()-o,"runner.argument_count":r.length,"runner.stdout_bytes":u,"runner.stderr_bytes":d}),e}finally{l.close(),await s.shutdown()}}process.argv[1]&&import.meta.url===r(process.argv[1]).href&&o().then(e=>{process.exitCode=e},e=>{process.stderr.write(`${e instanceof Error?e.message:String(e)}\n`),process.exitCode=1});export{o as main};
|
|
5
|
+
//# sourceMappingURL=cli.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.mjs","names":[],"sources":["../../src/bin/cli.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { createDoomTelemetry } from '@agimon-ai/doompi-telemetry';\nimport { createRunnerContainer } from '../container/index.ts';\nimport { pathToFileURL } from 'node:url';\nimport type { ILauncher } from '../services/Launcher/index.ts';\nimport type { ILogReader } from '../services/LogReader/index.ts';\nimport type { IRunnerRegistry } from '../services/RunnerRegistry/index.ts';\nimport type { IRmuxBackend } from '../services/RmuxBackend/index.ts';\nimport { TYPES } from '../types.ts';\nimport { runCli } from '../cli/cliApp.ts';\n\nasync function readStdin(): Promise<string> {\n const chunks: Buffer[] = [];\n for await (const chunk of process.stdin) chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));\n return Buffer.concat(chunks).toString('utf8');\n}\n\nexport async function main(argv: readonly string[] = process.argv.slice(2)): Promise<number> {\n const startedAt = Date.now();\n const telemetry = createDoomTelemetry({\n serviceName: 'doom-runner-cli',\n packageName: '@agimon-ai/doompi-runner',\n env: process.env,\n enableLogs: true,\n enableTraces: true,\n });\n const container = createRunnerContainer();\n const registry = container.get<IRunnerRegistry>(TYPES.RunnerRegistry);\n let stdoutBytes = 0;\n let stderrBytes = 0;\n try {\n const exitCode = await runCli(argv, {\n registry,\n launcher: container.get<ILauncher>(TYPES.Launcher),\n rmuxBackend: container.get<IRmuxBackend>(TYPES.RmuxBackend),\n logReader: container.get<ILogReader>(TYPES.LogReader),\n env: process.env,\n stdout: (text) => {\n const output = text.endsWith('\\n') ? text : `${text}\\n`;\n stdoutBytes += Buffer.byteLength(output, 'utf8');\n process.stdout.write(output);\n },\n stderr: (text) => {\n const output = text.endsWith('\\n') ? text : `${text}\\n`;\n stderrBytes += Buffer.byteLength(output, 'utf8');\n process.stderr.write(output);\n },\n readStdin,\n });\n await telemetry.recordEvent('doom_runner.cli_finished', {\n outcome: exitCode === 0 ? 'completed' : 'failed',\n 'runner.exit_code': exitCode,\n duration_ms: Date.now() - startedAt,\n 'runner.argument_count': argv.length,\n 'runner.stdout_bytes': stdoutBytes,\n 'runner.stderr_bytes': stderrBytes,\n });\n return exitCode;\n } catch (error) {\n await telemetry.recordError('doom_runner.cli_failed', error, {\n duration_ms: Date.now() - startedAt,\n 'runner.argument_count': argv.length,\n 'runner.stdout_bytes': stdoutBytes,\n 'runner.stderr_bytes': stderrBytes,\n });\n throw error;\n } finally {\n registry.close();\n await telemetry.shutdown();\n }\n}\n\nif (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {\n main().then(\n (code) => {\n process.exitCode = code;\n },\n (error: unknown) => {\n process.stderr.write(`${error instanceof Error ? error.message : String(error)}\\n`);\n process.exitCode = 1;\n },\n );\n}\n"],"mappings":";0PAYA,eAAe,GAA6B,CAC1C,IAAM,EAAmB,CAAC,EAC1B,UAAW,IAAM,KAAS,QAAQ,MAAO,EAAO,KAAK,OAAO,SAAS,CAAK,EAAI,EAAQ,OAAO,KAAK,CAAK,CAAC,EACxG,OAAO,OAAO,OAAO,CAAM,CAAC,CAAC,SAAS,MAAM,CAC9C,CAEA,eAAsB,EAAK,EAA0B,QAAQ,KAAK,MAAM,CAAC,EAAoB,CAC3F,IAAM,EAAY,KAAK,IAAI,EACrB,EAAY,EAAoB,CACpC,YAAa,kBACb,YAAa,2BACb,IAAK,QAAQ,IACb,WAAY,GACZ,aAAc,EAChB,CAAC,EACK,EAAY,EAAsB,EAClC,EAAW,EAAU,IAAqB,EAAM,cAAc,EAChE,EAAc,EACd,EAAc,EAClB,GAAI,CACF,IAAM,EAAW,MAAM,EAAO,EAAM,CAClC,WACA,SAAU,EAAU,IAAe,EAAM,QAAQ,EACjD,YAAa,EAAU,IAAkB,EAAM,WAAW,EAC1D,UAAW,EAAU,IAAgB,EAAM,SAAS,EACpD,IAAK,QAAQ,IACb,OAAS,GAAS,CAChB,IAAM,EAAS,EAAK,SAAS;CAAI,EAAI,EAAO,GAAG,EAAK,IACpD,GAAe,OAAO,WAAW,EAAQ,MAAM,EAC/C,QAAQ,OAAO,MAAM,CAAM,CAC7B,EACA,OAAS,GAAS,CAChB,IAAM,EAAS,EAAK,SAAS;CAAI,EAAI,EAAO,GAAG,EAAK,IACpD,GAAe,OAAO,WAAW,EAAQ,MAAM,EAC/C,QAAQ,OAAO,MAAM,CAAM,CAC7B,EACA,WACF,CAAC,EASD,OARA,MAAM,EAAU,YAAY,2BAA4B,CACtD,QAAS,IAAa,EAAI,YAAc,SACxC,mBAAoB,EACpB,YAAa,KAAK,IAAI,EAAI,EAC1B,wBAAyB,EAAK,OAC9B,sBAAuB,EACvB,sBAAuB,CACzB,CAAC,EACM,CACT,OAAS,EAAO,CAOd,MANA,MAAM,EAAU,YAAY,yBAA0B,EAAO,CAC3D,YAAa,KAAK,IAAI,EAAI,EAC1B,wBAAyB,EAAK,OAC9B,sBAAuB,EACvB,sBAAuB,CACzB,CAAC,EACK,CACR,QAAU,CACR,EAAS,MAAM,EACf,MAAM,EAAU,SAAS,CAC3B,CACF,CAEI,QAAQ,KAAK,IAAM,YAAY,MAAQ,EAAc,QAAQ,KAAK,EAAE,CAAC,CAAC,MACxE,EAAK,CAAC,CAAC,KACJ,GAAS,CACR,QAAQ,SAAW,CACrB,EACC,GAAmB,CAClB,QAAQ,OAAO,MAAM,GAAG,aAAiB,MAAQ,EAAM,QAAU,OAAO,CAAK,EAAE,GAAG,EAClF,QAAQ,SAAW,CACrB,CACF"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../_virtual/_rolldown/runtime.cjs"),t=require("../services/AnsiScrub/ansiScrub.cjs");require("../services/AnsiScrub/index.cjs");let n=require("node:fs");n=e.__toESM(n,1);let r=require("node:url"),i=require("@agimon-ai/doompi-telemetry");async function a(e=process.argv.slice(2)){let r=Date.now(),a=(0,i.createDoomTelemetry)({serviceName:`doom-runner-log-sink`,packageName:`@agimon-ai/doompi-runner`,env:process.env,enableLogs:!0,enableTraces:!0}),[s,c,l,u]=e,d;try{if(!s||!c||!l||!u)throw Error(`logSink requires log, rotated log, max bytes, and completion paths`);if(d=Number(l),!Number.isFinite(d)||d<=0)throw Error(`logSink max bytes must be positive`)}catch(e){throw await a.recordError(`doom_runner.file_sink_failed`,e,{duration_ms:Date.now()-r}),await a.shutdown(),e}let f,p;try{f=n.default.openSync(s,`a`),p=n.default.statSync(s).size}catch(e){throw await a.recordError(`doom_runner.file_sink_failed`,e,{duration_ms:Date.now()-r}),await a.shutdown(),e}let m=0,h=0;try{process.stdin.setEncoding(`utf8`);for await(let e of process.stdin){let r=t.scrubTerminalOutput(String(e));if(!r)continue;let i=Buffer.from(r,`utf8`);p+i.byteLength>d&&(n.default.closeSync(f),n.default.renameSync(s,c),f=n.default.openSync(s,`w`),p=0,h+=1),n.default.writeSync(f,i),p+=i.byteLength,m+=1}return n.default.closeSync(f),o(u),await a.recordEvent(`doom_runner.file_sink_finished`,{outcome:`completed`,"runner.chunk_count":m,"runner.bytes_written":p,"runner.rotation_count":h,duration_ms:Date.now()-r}),0}catch(e){throw await a.recordError(`doom_runner.file_sink_failed`,e,{duration_ms:Date.now()-r}),e}finally{await a.shutdown()}}function o(e){let t=`${e}.${process.pid}.tmp`;n.default.writeFileSync(t,``,{mode:384}),n.default.renameSync(t,e)}process.argv[1]&&require("url").pathToFileURL(__filename).href===(0,r.pathToFileURL)(process.argv[1]).href&&a().then(e=>{process.exitCode=e},e=>{process.stderr.write(`${e instanceof Error?e.message:String(e)}\n`),process.exitCode=1}),exports.main=a;
|
|
2
|
+
//# sourceMappingURL=logSink.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logSink.cjs","names":["createDoomTelemetry","fs","scrubTerminalOutput","pathToFileURL"],"sources":["../../src/bin/logSink.ts"],"sourcesContent":["import { createDoomTelemetry } from '@agimon-ai/doompi-telemetry';\nimport fs from 'node:fs';\nimport { pathToFileURL } from 'node:url';\nimport { scrubTerminalOutput } from '../services/AnsiScrub/index.ts';\n\nexport async function main(argv: readonly string[] = process.argv.slice(2)): Promise<number> {\n const startedAt = Date.now();\n const telemetry = createDoomTelemetry({\n serviceName: 'doom-runner-log-sink',\n packageName: '@agimon-ai/doompi-runner',\n env: process.env,\n enableLogs: true,\n enableTraces: true,\n });\n const [logPath, rotatedPath, maxBytesRaw, donePath] = argv;\n let maxBytes: number;\n try {\n if (!logPath || !rotatedPath || !maxBytesRaw || !donePath) {\n throw new Error('logSink requires log, rotated log, max bytes, and completion paths');\n }\n maxBytes = Number(maxBytesRaw);\n if (!Number.isFinite(maxBytes) || maxBytes <= 0) throw new Error('logSink max bytes must be positive');\n } catch (error) {\n await telemetry.recordError('doom_runner.file_sink_failed', error, { duration_ms: Date.now() - startedAt });\n await telemetry.shutdown();\n throw error;\n }\n\n let handle: number;\n let written: number;\n try {\n handle = fs.openSync(logPath, 'a');\n written = fs.statSync(logPath).size;\n } catch (error) {\n await telemetry.recordError('doom_runner.file_sink_failed', error, { duration_ms: Date.now() - startedAt });\n await telemetry.shutdown();\n throw error;\n }\n let chunks = 0;\n let rotations = 0;\n try {\n process.stdin.setEncoding('utf8');\n for await (const chunk of process.stdin) {\n const text = scrubTerminalOutput(String(chunk));\n if (!text) continue;\n const bytes = Buffer.from(text, 'utf8');\n if (written + bytes.byteLength > maxBytes) {\n fs.closeSync(handle);\n fs.renameSync(logPath, rotatedPath);\n handle = fs.openSync(logPath, 'w');\n written = 0;\n rotations += 1;\n }\n fs.writeSync(handle, bytes);\n written += bytes.byteLength;\n chunks += 1;\n }\n fs.closeSync(handle);\n writeDone(donePath);\n await telemetry.recordEvent('doom_runner.file_sink_finished', {\n outcome: 'completed',\n 'runner.chunk_count': chunks,\n 'runner.bytes_written': written,\n 'runner.rotation_count': rotations,\n duration_ms: Date.now() - startedAt,\n });\n return 0;\n } catch (error) {\n await telemetry.recordError('doom_runner.file_sink_failed', error, { duration_ms: Date.now() - startedAt });\n throw error;\n } finally {\n await telemetry.shutdown();\n }\n}\n\nfunction writeDone(target: string): void {\n const temporary = `${target}.${process.pid}.tmp`;\n fs.writeFileSync(temporary, '', { mode: 0o600 });\n fs.renameSync(temporary, target);\n}\n\nif (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {\n main().then(\n (code) => {\n process.exitCode = code;\n },\n (error: unknown) => {\n process.stderr.write(`${error instanceof Error ? error.message : String(error)}\\n`);\n process.exitCode = 1;\n },\n );\n}\n"],"mappings":"iUAKA,eAAsB,EAAK,EAA0B,QAAQ,KAAK,MAAM,CAAC,EAAoB,CAC3F,IAAM,EAAY,KAAK,IAAI,EACrB,GAAA,EAAYA,EAAAA,oBAAAA,CAAoB,CACpC,YAAa,uBACb,YAAa,2BACb,IAAK,QAAQ,IACb,WAAY,GACZ,aAAc,EAChB,CAAC,EACK,CAAC,EAAS,EAAa,EAAa,GAAY,EAClD,EACJ,GAAI,CACF,GAAI,CAAC,GAAW,CAAC,GAAe,CAAC,GAAe,CAAC,EAC/C,MAAU,MAAM,oEAAoE,EAGtF,GADA,EAAW,OAAO,CAAW,EACzB,CAAC,OAAO,SAAS,CAAQ,GAAK,GAAY,EAAG,MAAU,MAAM,oCAAoC,CACvG,OAAS,EAAO,CAGd,MAFA,MAAM,EAAU,YAAY,+BAAgC,EAAO,CAAE,YAAa,KAAK,IAAI,EAAI,CAAU,CAAC,EAC1G,MAAM,EAAU,SAAS,EACnB,CACR,CAEA,IAAI,EACA,EACJ,GAAI,CACF,EAASC,EAAAA,QAAG,SAAS,EAAS,GAAG,EACjC,EAAUA,EAAAA,QAAG,SAAS,CAAO,CAAC,CAAC,IACjC,OAAS,EAAO,CAGd,MAFA,MAAM,EAAU,YAAY,+BAAgC,EAAO,CAAE,YAAa,KAAK,IAAI,EAAI,CAAU,CAAC,EAC1G,MAAM,EAAU,SAAS,EACnB,CACR,CACA,IAAI,EAAS,EACT,EAAY,EAChB,GAAI,CACF,QAAQ,MAAM,YAAY,MAAM,EAChC,UAAW,IAAM,KAAS,QAAQ,MAAO,CACvC,IAAM,EAAOC,EAAAA,oBAAoB,OAAO,CAAK,CAAC,EAC9C,GAAI,CAAC,EAAM,SACX,IAAM,EAAQ,OAAO,KAAK,EAAM,MAAM,EAClC,EAAU,EAAM,WAAa,IAC/B,EAAA,QAAG,UAAU,CAAM,EACnB,EAAA,QAAG,WAAW,EAAS,CAAW,EAClC,EAASD,EAAAA,QAAG,SAAS,EAAS,GAAG,EACjC,EAAU,EACV,GAAa,GAEf,EAAA,QAAG,UAAU,EAAQ,CAAK,EAC1B,GAAW,EAAM,WACjB,GAAU,CACZ,CAUA,OATA,EAAA,QAAG,UAAU,CAAM,EACnB,EAAU,CAAQ,EAClB,MAAM,EAAU,YAAY,iCAAkC,CAC5D,QAAS,YACT,qBAAsB,EACtB,uBAAwB,EACxB,wBAAyB,EACzB,YAAa,KAAK,IAAI,EAAI,CAC5B,CAAC,EACM,CACT,OAAS,EAAO,CAEd,MADA,MAAM,EAAU,YAAY,+BAAgC,EAAO,CAAE,YAAa,KAAK,IAAI,EAAI,CAAU,CAAC,EACpG,CACR,QAAU,CACR,MAAM,EAAU,SAAS,CAC3B,CACF,CAEA,SAAS,EAAU,EAAsB,CACvC,IAAM,EAAY,GAAG,EAAO,GAAG,QAAQ,IAAI,MAC3C,EAAA,QAAG,cAAc,EAAW,GAAI,CAAE,KAAM,GAAM,CAAC,EAC/C,EAAA,QAAG,WAAW,EAAW,CAAM,CACjC,CAEI,QAAQ,KAAK,IAAA,QAAA,KAAA,CAAA,CAAA,cAAA,UAAA,CAAA,CAAA,QAAA,EAA0BE,EAAAA,cAAAA,CAAc,QAAQ,KAAK,EAAE,CAAC,CAAC,MACxE,EAAK,CAAC,CAAC,KACJ,GAAS,CACR,QAAQ,SAAW,CACrB,EACC,GAAmB,CAClB,QAAQ,OAAO,MAAM,GAAG,aAAiB,MAAQ,EAAM,QAAU,OAAO,CAAK,EAAE,GAAG,EAClF,QAAQ,SAAW,CACrB,CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logSink.d.cts","names":[],"sources":["../../src/bin/logSink.ts"],"mappings":";iBAKsB,KAAK,2BAAkD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logSink.d.mts","names":[],"sources":["../../src/bin/logSink.ts"],"mappings":";iBAKsB,KAAK,2BAAkD"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{scrubTerminalOutput as e}from"../services/AnsiScrub/ansiScrub.mjs";import"../services/AnsiScrub/index.mjs";import t from"node:fs";import{pathToFileURL as n}from"node:url";import{createDoomTelemetry as r}from"@agimon-ai/doompi-telemetry";async function i(n=process.argv.slice(2)){let i=Date.now(),o=r({serviceName:`doom-runner-log-sink`,packageName:`@agimon-ai/doompi-runner`,env:process.env,enableLogs:!0,enableTraces:!0}),[s,c,l,u]=n,d;try{if(!s||!c||!l||!u)throw Error(`logSink requires log, rotated log, max bytes, and completion paths`);if(d=Number(l),!Number.isFinite(d)||d<=0)throw Error(`logSink max bytes must be positive`)}catch(e){throw await o.recordError(`doom_runner.file_sink_failed`,e,{duration_ms:Date.now()-i}),await o.shutdown(),e}let f,p;try{f=t.openSync(s,`a`),p=t.statSync(s).size}catch(e){throw await o.recordError(`doom_runner.file_sink_failed`,e,{duration_ms:Date.now()-i}),await o.shutdown(),e}let m=0,h=0;try{process.stdin.setEncoding(`utf8`);for await(let n of process.stdin){let r=e(String(n));if(!r)continue;let i=Buffer.from(r,`utf8`);p+i.byteLength>d&&(t.closeSync(f),t.renameSync(s,c),f=t.openSync(s,`w`),p=0,h+=1),t.writeSync(f,i),p+=i.byteLength,m+=1}return t.closeSync(f),a(u),await o.recordEvent(`doom_runner.file_sink_finished`,{outcome:`completed`,"runner.chunk_count":m,"runner.bytes_written":p,"runner.rotation_count":h,duration_ms:Date.now()-i}),0}catch(e){throw await o.recordError(`doom_runner.file_sink_failed`,e,{duration_ms:Date.now()-i}),e}finally{await o.shutdown()}}function a(e){let n=`${e}.${process.pid}.tmp`;t.writeFileSync(n,``,{mode:384}),t.renameSync(n,e)}process.argv[1]&&import.meta.url===n(process.argv[1]).href&&i().then(e=>{process.exitCode=e},e=>{process.stderr.write(`${e instanceof Error?e.message:String(e)}\n`),process.exitCode=1});export{i as main};
|
|
2
|
+
//# sourceMappingURL=logSink.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logSink.mjs","names":[],"sources":["../../src/bin/logSink.ts"],"sourcesContent":["import { createDoomTelemetry } from '@agimon-ai/doompi-telemetry';\nimport fs from 'node:fs';\nimport { pathToFileURL } from 'node:url';\nimport { scrubTerminalOutput } from '../services/AnsiScrub/index.ts';\n\nexport async function main(argv: readonly string[] = process.argv.slice(2)): Promise<number> {\n const startedAt = Date.now();\n const telemetry = createDoomTelemetry({\n serviceName: 'doom-runner-log-sink',\n packageName: '@agimon-ai/doompi-runner',\n env: process.env,\n enableLogs: true,\n enableTraces: true,\n });\n const [logPath, rotatedPath, maxBytesRaw, donePath] = argv;\n let maxBytes: number;\n try {\n if (!logPath || !rotatedPath || !maxBytesRaw || !donePath) {\n throw new Error('logSink requires log, rotated log, max bytes, and completion paths');\n }\n maxBytes = Number(maxBytesRaw);\n if (!Number.isFinite(maxBytes) || maxBytes <= 0) throw new Error('logSink max bytes must be positive');\n } catch (error) {\n await telemetry.recordError('doom_runner.file_sink_failed', error, { duration_ms: Date.now() - startedAt });\n await telemetry.shutdown();\n throw error;\n }\n\n let handle: number;\n let written: number;\n try {\n handle = fs.openSync(logPath, 'a');\n written = fs.statSync(logPath).size;\n } catch (error) {\n await telemetry.recordError('doom_runner.file_sink_failed', error, { duration_ms: Date.now() - startedAt });\n await telemetry.shutdown();\n throw error;\n }\n let chunks = 0;\n let rotations = 0;\n try {\n process.stdin.setEncoding('utf8');\n for await (const chunk of process.stdin) {\n const text = scrubTerminalOutput(String(chunk));\n if (!text) continue;\n const bytes = Buffer.from(text, 'utf8');\n if (written + bytes.byteLength > maxBytes) {\n fs.closeSync(handle);\n fs.renameSync(logPath, rotatedPath);\n handle = fs.openSync(logPath, 'w');\n written = 0;\n rotations += 1;\n }\n fs.writeSync(handle, bytes);\n written += bytes.byteLength;\n chunks += 1;\n }\n fs.closeSync(handle);\n writeDone(donePath);\n await telemetry.recordEvent('doom_runner.file_sink_finished', {\n outcome: 'completed',\n 'runner.chunk_count': chunks,\n 'runner.bytes_written': written,\n 'runner.rotation_count': rotations,\n duration_ms: Date.now() - startedAt,\n });\n return 0;\n } catch (error) {\n await telemetry.recordError('doom_runner.file_sink_failed', error, { duration_ms: Date.now() - startedAt });\n throw error;\n } finally {\n await telemetry.shutdown();\n }\n}\n\nfunction writeDone(target: string): void {\n const temporary = `${target}.${process.pid}.tmp`;\n fs.writeFileSync(temporary, '', { mode: 0o600 });\n fs.renameSync(temporary, target);\n}\n\nif (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {\n main().then(\n (code) => {\n process.exitCode = code;\n },\n (error: unknown) => {\n process.stderr.write(`${error instanceof Error ? error.message : String(error)}\\n`);\n process.exitCode = 1;\n },\n );\n}\n"],"mappings":"oPAKA,eAAsB,EAAK,EAA0B,QAAQ,KAAK,MAAM,CAAC,EAAoB,CAC3F,IAAM,EAAY,KAAK,IAAI,EACrB,EAAY,EAAoB,CACpC,YAAa,uBACb,YAAa,2BACb,IAAK,QAAQ,IACb,WAAY,GACZ,aAAc,EAChB,CAAC,EACK,CAAC,EAAS,EAAa,EAAa,GAAY,EAClD,EACJ,GAAI,CACF,GAAI,CAAC,GAAW,CAAC,GAAe,CAAC,GAAe,CAAC,EAC/C,MAAU,MAAM,oEAAoE,EAGtF,GADA,EAAW,OAAO,CAAW,EACzB,CAAC,OAAO,SAAS,CAAQ,GAAK,GAAY,EAAG,MAAU,MAAM,oCAAoC,CACvG,OAAS,EAAO,CAGd,MAFA,MAAM,EAAU,YAAY,+BAAgC,EAAO,CAAE,YAAa,KAAK,IAAI,EAAI,CAAU,CAAC,EAC1G,MAAM,EAAU,SAAS,EACnB,CACR,CAEA,IAAI,EACA,EACJ,GAAI,CACF,EAAS,EAAG,SAAS,EAAS,GAAG,EACjC,EAAU,EAAG,SAAS,CAAO,CAAC,CAAC,IACjC,OAAS,EAAO,CAGd,MAFA,MAAM,EAAU,YAAY,+BAAgC,EAAO,CAAE,YAAa,KAAK,IAAI,EAAI,CAAU,CAAC,EAC1G,MAAM,EAAU,SAAS,EACnB,CACR,CACA,IAAI,EAAS,EACT,EAAY,EAChB,GAAI,CACF,QAAQ,MAAM,YAAY,MAAM,EAChC,UAAW,IAAM,KAAS,QAAQ,MAAO,CACvC,IAAM,EAAO,EAAoB,OAAO,CAAK,CAAC,EAC9C,GAAI,CAAC,EAAM,SACX,IAAM,EAAQ,OAAO,KAAK,EAAM,MAAM,EAClC,EAAU,EAAM,WAAa,IAC/B,EAAG,UAAU,CAAM,EACnB,EAAG,WAAW,EAAS,CAAW,EAClC,EAAS,EAAG,SAAS,EAAS,GAAG,EACjC,EAAU,EACV,GAAa,GAEf,EAAG,UAAU,EAAQ,CAAK,EAC1B,GAAW,EAAM,WACjB,GAAU,CACZ,CAUA,OATA,EAAG,UAAU,CAAM,EACnB,EAAU,CAAQ,EAClB,MAAM,EAAU,YAAY,iCAAkC,CAC5D,QAAS,YACT,qBAAsB,EACtB,uBAAwB,EACxB,wBAAyB,EACzB,YAAa,KAAK,IAAI,EAAI,CAC5B,CAAC,EACM,CACT,OAAS,EAAO,CAEd,MADA,MAAM,EAAU,YAAY,+BAAgC,EAAO,CAAE,YAAa,KAAK,IAAI,EAAI,CAAU,CAAC,EACpG,CACR,QAAU,CACR,MAAM,EAAU,SAAS,CAC3B,CACF,CAEA,SAAS,EAAU,EAAsB,CACvC,IAAM,EAAY,GAAG,EAAO,GAAG,QAAQ,IAAI,MAC3C,EAAG,cAAc,EAAW,GAAI,CAAE,KAAM,GAAM,CAAC,EAC/C,EAAG,WAAW,EAAW,CAAM,CACjC,CAEI,QAAQ,KAAK,IAAM,YAAY,MAAQ,EAAc,QAAQ,KAAK,EAAE,CAAC,CAAC,MACxE,EAAK,CAAC,CAAC,KACJ,GAAS,CACR,QAAQ,SAAW,CACrB,EACC,GAAmB,CAClB,QAAQ,OAAO,MAAM,GAAG,aAAiB,MAAQ,EAAM,QAAU,OAAO,CAAK,EAAE,GAAG,EAClF,QAAQ,SAAW,CACrB,CACF"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../_virtual/_rolldown/runtime.cjs"),t=require("../services/Lifeline/client.cjs");let n=require("node:fs");n=e.__toESM(n,1);let r=require("node:url"),i=require("node:os");i=e.__toESM(i,1);let a=require("node:child_process"),o=require("@agimon-ai/doompi-telemetry");const s=`doom_runner.host_failed`,c=`invalid runner command spec`;async function l(e=process.argv.slice(2)){let n=Date.now(),r=(0,o.createDoomTelemetry)({serviceName:`doom-runner-host`,packageName:`@agimon-ai/doompi-runner`,env:process.env,enableLogs:!0,enableTraces:!0}),[c,l,p]=e,m;try{if(!c||!l||!p)throw Error(`runnerHost requires spec, gate, and exit paths`);m=u(c),await d(l)}catch(e){throw await r.recordError(s,e,{duration_ms:Date.now()-n}),await r.shutdown(),e}let h,g=null,_,v=e=>{if(h?.pid)try{process.kill(-h.pid,e)}catch{h.kill(e)}},y=e=>{g=e,v(e),_??=setTimeout(()=>v(`SIGKILL`),2e3)};for(let e of[`SIGTERM`,`SIGINT`,`SIGHUP`])process.once(e,()=>y(e));h=(0,a.spawn)(m.command,{cwd:m.cwd,env:m.env,shell:`/bin/bash`,stdio:`inherit`,detached:!0}),g&&y(g);let b=t.watchOwner(()=>y(`SIGTERM`),m.env[t.LIFELINE_ENV]);try{let e=await new Promise((e,t)=>{h?.once(`error`,t),h?.once(`exit`,(t,n)=>e({code:t,signal:n??g}))});f(p,e);let t=e.code===null?e.signal?128+i.default.constants.signals[e.signal]:1:e.code;return await r.recordEvent(`doom_runner.host_finished`,{outcome:e.signal||g?`signaled`:t===0?`completed`:`failed`,"runner.exit_code":t,...e.signal||g?{"runner.signal":e.signal??g??``}:{},duration_ms:Date.now()-n}),t}catch(e){throw await r.recordError(s,e,{duration_ms:Date.now()-n}),e}finally{b(),_&&clearTimeout(_),await r.shutdown()}}function u(e){let t=JSON.parse(n.default.readFileSync(e,`utf8`));if(typeof t!=`object`||!t)throw Error(c);let r=t;if(typeof r.command!=`string`||typeof r.cwd!=`string`||!r.env)throw Error(c);return{command:r.command,cwd:r.cwd,env:r.env}}async function d(e){for(;!n.default.existsSync(e);)await new Promise(e=>setTimeout(e,10))}function f(e,t){let r=`${e}.${process.pid}.tmp`;n.default.writeFileSync(r,`${JSON.stringify(t)}\n`,{mode:384}),n.default.renameSync(r,e)}process.argv[1]&&require("url").pathToFileURL(__filename).href===(0,r.pathToFileURL)(process.argv[1]).href&&l().then(e=>{process.exitCode=e},e=>{process.stderr.write(`${e instanceof Error?e.message:String(e)}\n`),process.exitCode=1}),exports.main=l;
|
|
2
|
+
//# sourceMappingURL=runnerHost.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runnerHost.cjs","names":["createDoomTelemetry","spawn","watchOwner","LIFELINE_ENV","os","fs","pathToFileURL"],"sources":["../../src/bin/runnerHost.ts"],"sourcesContent":["import { createDoomTelemetry } from '@agimon-ai/doompi-telemetry';\nimport fs from 'node:fs';\nimport os from 'node:os';\nimport { spawn, type ChildProcess } from 'node:child_process';\nimport { pathToFileURL } from 'node:url';\nimport { LIFELINE_ENV, watchOwner } from '../services/Lifeline/client.ts';\n\ninterface CommandSpec {\n command: string;\n cwd: string;\n env: Record<string, string>;\n}\n\nconst POLL_MS = 10;\nconst FORWARDED_SIGNAL_GRACE_MS = 2_000;\nconst HOST_FAILED_EVENT = 'doom_runner.host_failed';\nconst INVALID_COMMAND_SPEC_ERROR = 'invalid runner command spec';\n\nexport async function main(argv: readonly string[] = process.argv.slice(2)): Promise<number> {\n const startedAt = Date.now();\n const telemetry = createDoomTelemetry({\n serviceName: 'doom-runner-host',\n packageName: '@agimon-ai/doompi-runner',\n env: process.env,\n enableLogs: true,\n enableTraces: true,\n });\n const [specPath, gatePath, exitPath] = argv;\n let spec: CommandSpec;\n try {\n if (!specPath || !gatePath || !exitPath) throw new Error('runnerHost requires spec, gate, and exit paths');\n spec = readSpec(specPath);\n await waitForGate(gatePath);\n } catch (error) {\n await telemetry.recordError(HOST_FAILED_EVENT, error, { duration_ms: Date.now() - startedAt });\n await telemetry.shutdown();\n throw error;\n }\n let child: ChildProcess | undefined;\n let forwardedSignal: NodeJS.Signals | null = null;\n let escalationTimer: NodeJS.Timeout | undefined;\n const signalChild = (signal: NodeJS.Signals): void => {\n if (!child?.pid) return;\n try {\n process.kill(-child.pid, signal);\n } catch {\n child.kill(signal);\n }\n };\n const forward = (signal: NodeJS.Signals): void => {\n forwardedSignal = signal;\n signalChild(signal);\n escalationTimer ??= setTimeout(() => signalChild('SIGKILL'), FORWARDED_SIGNAL_GRACE_MS);\n };\n const signals: NodeJS.Signals[] = ['SIGTERM', 'SIGINT', 'SIGHUP'];\n for (const signal of signals) process.once(signal, () => forward(signal));\n\n child = spawn(spec.command, {\n cwd: spec.cwd,\n env: spec.env,\n shell: '/bin/bash',\n stdio: 'inherit',\n detached: true,\n });\n if (forwardedSignal) forward(forwardedSignal);\n\n // This process supervises the command for its whole life, so it is also the\n // right place to notice an owner that died without stopping it.\n //\n // The lifeline comes from the spec rather than this process's environment: an\n // rmux server outlives the session that started it, so its own environment can\n // still name a previous session's socket.\n const detachLifeline = watchOwner(() => forward('SIGTERM'), spec.env[LIFELINE_ENV]);\n\n try {\n const result = await new Promise<{ code: number | null; signal: NodeJS.Signals | null }>((resolve, reject) => {\n child?.once('error', reject);\n child?.once('exit', (code, signal) => resolve({ code, signal: signal ?? forwardedSignal }));\n });\n writeAtomic(exitPath, result);\n const exitCode = result.code !== null ? result.code : result.signal ? 128 + os.constants.signals[result.signal] : 1;\n await telemetry.recordEvent('doom_runner.host_finished', {\n outcome: result.signal || forwardedSignal ? 'signaled' : exitCode === 0 ? 'completed' : 'failed',\n 'runner.exit_code': exitCode,\n ...(result.signal || forwardedSignal ? { 'runner.signal': result.signal ?? forwardedSignal ?? '' } : {}),\n duration_ms: Date.now() - startedAt,\n });\n return exitCode;\n } catch (error) {\n await telemetry.recordError(HOST_FAILED_EVENT, error, { duration_ms: Date.now() - startedAt });\n throw error;\n } finally {\n detachLifeline();\n if (escalationTimer) clearTimeout(escalationTimer);\n await telemetry.shutdown();\n }\n}\n\nfunction readSpec(target: string): CommandSpec {\n const value: unknown = JSON.parse(fs.readFileSync(target, 'utf8'));\n if (typeof value !== 'object' || value === null) throw new Error(INVALID_COMMAND_SPEC_ERROR);\n const spec = value as Partial<CommandSpec>;\n if (typeof spec.command !== 'string' || typeof spec.cwd !== 'string' || !spec.env) {\n throw new Error(INVALID_COMMAND_SPEC_ERROR);\n }\n return { command: spec.command, cwd: spec.cwd, env: spec.env };\n}\n\nasync function waitForGate(target: string): Promise<void> {\n while (!fs.existsSync(target)) await new Promise((resolve) => setTimeout(resolve, POLL_MS));\n}\n\nfunction writeAtomic(target: string, value: unknown): void {\n const temporary = `${target}.${process.pid}.tmp`;\n fs.writeFileSync(temporary, `${JSON.stringify(value)}\\n`, { mode: 0o600 });\n fs.renameSync(temporary, target);\n}\n\nif (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {\n main().then(\n (code) => {\n process.exitCode = code;\n },\n (error: unknown) => {\n process.stderr.write(`${error instanceof Error ? error.message : String(error)}\\n`);\n process.exitCode = 1;\n },\n );\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runnerHost.d.cts","names":[],"sources":["../../src/bin/runnerHost.ts"],"mappings":";iBAkBsB,KAAK,2BAAkD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runnerHost.d.mts","names":[],"sources":["../../src/bin/runnerHost.ts"],"mappings":";iBAkBsB,KAAK,2BAAkD"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{LIFELINE_ENV as e,watchOwner as t}from"../services/Lifeline/client.mjs";import n from"node:fs";import{pathToFileURL as r}from"node:url";import i from"node:os";import{spawn as a}from"node:child_process";import{createDoomTelemetry as o}from"@agimon-ai/doompi-telemetry";const s=`doom_runner.host_failed`,c=`invalid runner command spec`;async function l(n=process.argv.slice(2)){let r=Date.now(),c=o({serviceName:`doom-runner-host`,packageName:`@agimon-ai/doompi-runner`,env:process.env,enableLogs:!0,enableTraces:!0}),[l,p,m]=n,h;try{if(!l||!p||!m)throw Error(`runnerHost requires spec, gate, and exit paths`);h=u(l),await d(p)}catch(e){throw await c.recordError(s,e,{duration_ms:Date.now()-r}),await c.shutdown(),e}let g,_=null,v,y=e=>{if(g?.pid)try{process.kill(-g.pid,e)}catch{g.kill(e)}},b=e=>{_=e,y(e),v??=setTimeout(()=>y(`SIGKILL`),2e3)};for(let e of[`SIGTERM`,`SIGINT`,`SIGHUP`])process.once(e,()=>b(e));g=a(h.command,{cwd:h.cwd,env:h.env,shell:`/bin/bash`,stdio:`inherit`,detached:!0}),_&&b(_);let x=t(()=>b(`SIGTERM`),h.env[e]);try{let e=await new Promise((e,t)=>{g?.once(`error`,t),g?.once(`exit`,(t,n)=>e({code:t,signal:n??_}))});f(m,e);let t=e.code===null?e.signal?128+i.constants.signals[e.signal]:1:e.code;return await c.recordEvent(`doom_runner.host_finished`,{outcome:e.signal||_?`signaled`:t===0?`completed`:`failed`,"runner.exit_code":t,...e.signal||_?{"runner.signal":e.signal??_??``}:{},duration_ms:Date.now()-r}),t}catch(e){throw await c.recordError(s,e,{duration_ms:Date.now()-r}),e}finally{x(),v&&clearTimeout(v),await c.shutdown()}}function u(e){let t=JSON.parse(n.readFileSync(e,`utf8`));if(typeof t!=`object`||!t)throw Error(c);let r=t;if(typeof r.command!=`string`||typeof r.cwd!=`string`||!r.env)throw Error(c);return{command:r.command,cwd:r.cwd,env:r.env}}async function d(e){for(;!n.existsSync(e);)await new Promise(e=>setTimeout(e,10))}function f(e,t){let r=`${e}.${process.pid}.tmp`;n.writeFileSync(r,`${JSON.stringify(t)}\n`,{mode:384}),n.renameSync(r,e)}process.argv[1]&&import.meta.url===r(process.argv[1]).href&&l().then(e=>{process.exitCode=e},e=>{process.stderr.write(`${e instanceof Error?e.message:String(e)}\n`),process.exitCode=1});export{l as main};
|
|
2
|
+
//# sourceMappingURL=runnerHost.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runnerHost.mjs","names":[],"sources":["../../src/bin/runnerHost.ts"],"sourcesContent":["import { createDoomTelemetry } from '@agimon-ai/doompi-telemetry';\nimport fs from 'node:fs';\nimport os from 'node:os';\nimport { spawn, type ChildProcess } from 'node:child_process';\nimport { pathToFileURL } from 'node:url';\nimport { LIFELINE_ENV, watchOwner } from '../services/Lifeline/client.ts';\n\ninterface CommandSpec {\n command: string;\n cwd: string;\n env: Record<string, string>;\n}\n\nconst POLL_MS = 10;\nconst FORWARDED_SIGNAL_GRACE_MS = 2_000;\nconst HOST_FAILED_EVENT = 'doom_runner.host_failed';\nconst INVALID_COMMAND_SPEC_ERROR = 'invalid runner command spec';\n\nexport async function main(argv: readonly string[] = process.argv.slice(2)): Promise<number> {\n const startedAt = Date.now();\n const telemetry = createDoomTelemetry({\n serviceName: 'doom-runner-host',\n packageName: '@agimon-ai/doompi-runner',\n env: process.env,\n enableLogs: true,\n enableTraces: true,\n });\n const [specPath, gatePath, exitPath] = argv;\n let spec: CommandSpec;\n try {\n if (!specPath || !gatePath || !exitPath) throw new Error('runnerHost requires spec, gate, and exit paths');\n spec = readSpec(specPath);\n await waitForGate(gatePath);\n } catch (error) {\n await telemetry.recordError(HOST_FAILED_EVENT, error, { duration_ms: Date.now() - startedAt });\n await telemetry.shutdown();\n throw error;\n }\n let child: ChildProcess | undefined;\n let forwardedSignal: NodeJS.Signals | null = null;\n let escalationTimer: NodeJS.Timeout | undefined;\n const signalChild = (signal: NodeJS.Signals): void => {\n if (!child?.pid) return;\n try {\n process.kill(-child.pid, signal);\n } catch {\n child.kill(signal);\n }\n };\n const forward = (signal: NodeJS.Signals): void => {\n forwardedSignal = signal;\n signalChild(signal);\n escalationTimer ??= setTimeout(() => signalChild('SIGKILL'), FORWARDED_SIGNAL_GRACE_MS);\n };\n const signals: NodeJS.Signals[] = ['SIGTERM', 'SIGINT', 'SIGHUP'];\n for (const signal of signals) process.once(signal, () => forward(signal));\n\n child = spawn(spec.command, {\n cwd: spec.cwd,\n env: spec.env,\n shell: '/bin/bash',\n stdio: 'inherit',\n detached: true,\n });\n if (forwardedSignal) forward(forwardedSignal);\n\n // This process supervises the command for its whole life, so it is also the\n // right place to notice an owner that died without stopping it.\n //\n // The lifeline comes from the spec rather than this process's environment: an\n // rmux server outlives the session that started it, so its own environment can\n // still name a previous session's socket.\n const detachLifeline = watchOwner(() => forward('SIGTERM'), spec.env[LIFELINE_ENV]);\n\n try {\n const result = await new Promise<{ code: number | null; signal: NodeJS.Signals | null }>((resolve, reject) => {\n child?.once('error', reject);\n child?.once('exit', (code, signal) => resolve({ code, signal: signal ?? forwardedSignal }));\n });\n writeAtomic(exitPath, result);\n const exitCode = result.code !== null ? result.code : result.signal ? 128 + os.constants.signals[result.signal] : 1;\n await telemetry.recordEvent('doom_runner.host_finished', {\n outcome: result.signal || forwardedSignal ? 'signaled' : exitCode === 0 ? 'completed' : 'failed',\n 'runner.exit_code': exitCode,\n ...(result.signal || forwardedSignal ? { 'runner.signal': result.signal ?? forwardedSignal ?? '' } : {}),\n duration_ms: Date.now() - startedAt,\n });\n return exitCode;\n } catch (error) {\n await telemetry.recordError(HOST_FAILED_EVENT, error, { duration_ms: Date.now() - startedAt });\n throw error;\n } finally {\n detachLifeline();\n if (escalationTimer) clearTimeout(escalationTimer);\n await telemetry.shutdown();\n }\n}\n\nfunction readSpec(target: string): CommandSpec {\n const value: unknown = JSON.parse(fs.readFileSync(target, 'utf8'));\n if (typeof value !== 'object' || value === null) throw new Error(INVALID_COMMAND_SPEC_ERROR);\n const spec = value as Partial<CommandSpec>;\n if (typeof spec.command !== 'string' || typeof spec.cwd !== 'string' || !spec.env) {\n throw new Error(INVALID_COMMAND_SPEC_ERROR);\n }\n return { command: spec.command, cwd: spec.cwd, env: spec.env };\n}\n\nasync function waitForGate(target: string): Promise<void> {\n while (!fs.existsSync(target)) await new Promise((resolve) => setTimeout(resolve, POLL_MS));\n}\n\nfunction writeAtomic(target: string, value: unknown): void {\n const temporary = `${target}.${process.pid}.tmp`;\n fs.writeFileSync(temporary, `${JSON.stringify(value)}\\n`, { mode: 0o600 });\n fs.renameSync(temporary, target);\n}\n\nif (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {\n main().then(\n (code) => {\n process.exitCode = code;\n },\n (error: unknown) => {\n process.stderr.write(`${error instanceof Error ? error.message : String(error)}\\n`);\n process.exitCode = 1;\n },\n );\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../_virtual/_rolldown/runtime.cjs"),t=require("../session.cjs"),n=require("../tool/responseEnvelope.cjs");let r=require("node:fs");r=e.__toESM(r,1);const i=`completed`,a=`rmux`,o=`stopped`,s=`SIGTERM`;async function c(e,n){let[r,...i]=e;if(r!==void 0&&r!==`--help`&&r!==`-h`&&!t.inheritedSessionId(n.env))return n.stderr(`PI_SESSION_ID is required for doom-runner commands`),1;switch(r){case`list`:return l(i,n);case`status`:return u(i,n);case`logs`:return d(i,n);case`stop`:return f(i,n);case`stop-all`:return p(i,n);case`input`:return m(i,n);case`--help`:case`-h`:case void 0:return n.stdout(S()),0;default:return n.stderr(`Unknown command: ${r}\n\n${S()}`),1}}async function l(e,n){let r=t.requiredSessionId(n.env),i=e.includes(`--all`)?await n.registry.listAll(r):await n.registry.listBySession(r);return n.stdout(i.length>0?i.map(g).join(`
|
|
2
|
+
`):`No runners`),0}async function u(e,t){let n=await h(e[0],t);return n?(t.stdout([`ID: ${n.id}`,`Name: ${n.name}`,`State: ${n.state}`,`Backend: ${n.backend}`,...n.backendTarget?[`Backend target: ${n.backendTarget}`]:[],`PID: ${n.pid}`,`Command: ${n.command}`,`CWD: ${n.cwd}`,`Session: ${n.sessionId}`,`Log: ${n.logPath}`,...n.exit?[`Exit: ${_(n)}`]:[]].join(`
|
|
3
|
+
`)),0):1}async function d(e,t){let n=await h(e[0],t);if(!n)return 1;let r=y(v(e,`--lines`))??200,i=t.logReader.read(n.logPath,{lines:r});return i.exists?(i.text&&t.stdout(i.text),e.includes(`--follow`)?b(n,i.fileSize,t):0):(t.stderr(`Runner ${n.id} has not written a log yet`),1)}async function f(e,t){let n=await h(e[0],t);if(!n)return 1;if(n.state!==`running`)return t.stderr(`Runner ${n.id} is already ${n.state}`),1;await x(n,t);let r=v(e,`--reason`);return await t.registry.complete(n.id,{reason:o,code:null,signal:s,...r?{stopReason:r}:{}},n.sessionId),t.stdout(`Stopped ${n.id}\nLog: ${n.logPath}`),0}async function p(e,n){let r=t.requiredSessionId(n.env),i=await n.registry.listBySession(r),a=v(e,`--reason`);for(let e of i)await x(e,n),await n.registry.complete(e.id,{reason:o,code:null,signal:s,...a?{stopReason:a}:{}},e.sessionId);return n.stdout(i.length>0?`Stopped ${i.length} runner(s) for session ${r}: ${i.map(e=>e.id).join(`, `)}`:`No active runners for session ${r}`),0}async function m(e,t){let n=await h(e[0],t);if(!n)return 1;if(n.state===i)return t.stderr(`Runner ${n.id} is already completed; use doom-runner logs ${n.id}`),1;if(!n.interactive)return t.stderr(`Runner ${n.id} was not started with interactive: true`),1;let r=v(e,`--text`)??await t.readStdin(),o=e.includes(`--enter`)&&!r.endsWith(`
|
|
4
|
+
`)?`${r}\n`:r;return n.backend!==a||!n.backendTarget?(t.stderr(`Runner ${n.id} uses the ${n.backend} backend, which does not expose CLI input`),1):await t.rmuxBackend.input(n.backendTarget,o)?(t.stdout(`Sent input to ${n.id}`),0):(t.stderr(`Runner ${n.id} is no longer accepting RMUX input`),1)}async function h(e,n){if(!e){n.stderr(`A runner ID is required`);return}let r=t.requiredSessionId(n.env),i=await n.registry.get(e,r);if(!i){n.stderr(`No runner with id ${e}`);return}return i}function g(e){let t=n.formatRunnerLine(e);return`${e.id} ${e.state} ${e.backend} ${t}`}function _(e){let t=e.exit;if(!t)return`unknown`;let n=t.code===null?t.signal?` ${t.signal}`:``:` code ${t.code}`,r=t.stopReason?` (${t.stopReason})`:``;return`${t.reason}${n}${r}`}function v(e,t){let n=e.indexOf(t);return n>=0?e[n+1]:void 0}function y(e){if(e===void 0)return;let t=Number(e);return Number.isInteger(t)&&t>0?t:void 0}async function b(e,t,n){let a=t;return new Promise(t=>{let o=!1,s,c=t=>{if(t.size<a&&(a=0),t.size===a)return;let i=t.size-a,o=Buffer.alloc(i),s=r.default.openSync(e.logPath,`r`);try{let e=r.default.readSync(s,o,0,i,a);e>0&&n.stdout(o.subarray(0,e).toString(`utf8`))}finally{r.default.closeSync(s)}a=t.size},l=()=>{if(!o){o=!0;try{c(r.default.statSync(e.logPath))}catch(t){t.code!==`ENOENT`&&n.stderr(`Runner ${e.id} failed to flush its final log output: ${t.message}`)}r.default.unwatchFile(e.logPath,c),clearInterval(s),process.off(`SIGINT`,l),t(0)}};process.once(`SIGINT`,l),r.default.watchFile(e.logPath,{interval:250},c),s=setInterval(()=>{n.registry.get(e.id).then(e=>{e?.state===i&&l()})},250)})}async function x(e,t){return e.backend===a&&e.backendTarget?t.rmuxBackend.stop(e.backendTarget,e.pid):t.launcher.stop(e.pid)}function S(){return[`Usage: doom-runner <command>`,``,`Commands:`,` list [--all]`,` status <id>`,` logs <id> [--lines N] [--follow]`,` stop <id> [--reason <text>]`,` stop-all [--reason <text>]`,` input <id> [--text <text>] [--enter]`].join(`
|
|
5
|
+
`)}exports.runCli=c;
|
|
6
|
+
//# sourceMappingURL=cliApp.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cliApp.cjs","names":["inheritedSessionId","requiredSessionId","formatRunnerLine","fs"],"sources":["../../src/cli/cliApp.ts"],"sourcesContent":["import fs from 'node:fs';\nimport type { ILauncher } from '../services/Launcher/index.ts';\nimport type { ILogReader } from '../services/LogReader/index.ts';\nimport type { IRmuxBackend } from '../services/RmuxBackend/index.ts';\nimport type { IRunnerRegistry, RunnerRecord } from '../services/RunnerRegistry/index.ts';\nimport { inheritedSessionId, requiredSessionId } from '../session.ts';\nimport { formatRunnerLine } from '../tool/responseEnvelope.ts';\n\nconst DEFAULT_LOG_LINES = 200;\nconst FOLLOW_INTERVAL_MS = 250;\nconst COMPLETED_STATE = 'completed';\nconst RMUX_BACKEND = 'rmux';\nconst STOPPED_REASON = 'stopped';\nconst TERMINATION_SIGNAL = 'SIGTERM';\n\nexport interface CliDependencies {\n registry: IRunnerRegistry;\n launcher: ILauncher;\n rmuxBackend: IRmuxBackend;\n logReader: ILogReader;\n env?: NodeJS.ProcessEnv;\n stdout(text: string): void;\n stderr(text: string): void;\n readStdin(): Promise<string>;\n}\n\nexport async function runCli(argv: readonly string[], dependencies: CliDependencies): Promise<number> {\n const [command, ...args] = argv;\n if (command !== undefined && command !== '--help' && command !== '-h' && !inheritedSessionId(dependencies.env)) {\n dependencies.stderr('PI_SESSION_ID is required for doom-runner commands');\n return 1;\n }\n switch (command) {\n case 'list':\n return list(args, dependencies);\n case 'status':\n return status(args, dependencies);\n case 'logs':\n return logs(args, dependencies);\n case 'stop':\n return stop(args, dependencies);\n case 'stop-all':\n return stopAll(args, dependencies);\n case 'input':\n return input(args, dependencies);\n case '--help':\n case '-h':\n case undefined:\n dependencies.stdout(help());\n return 0;\n default:\n dependencies.stderr(`Unknown command: ${command}\\n\\n${help()}`);\n return 1;\n }\n}\n\nasync function list(args: readonly string[], dependencies: CliDependencies): Promise<number> {\n const sessionId = requiredSessionId(dependencies.env);\n const records = args.includes('--all')\n ? await dependencies.registry.listAll(sessionId)\n : await dependencies.registry.listBySession(sessionId);\n dependencies.stdout(records.length > 0 ? records.map(formatRecord).join('\\n') : 'No runners');\n return 0;\n}\n\nasync function status(args: readonly string[], dependencies: CliDependencies): Promise<number> {\n const record = await requiredRecord(args[0], dependencies);\n if (!record) return 1;\n dependencies.stdout(\n [\n `ID: ${record.id}`,\n `Name: ${record.name}`,\n `State: ${record.state}`,\n `Backend: ${record.backend}`,\n ...(record.backendTarget ? [`Backend target: ${record.backendTarget}`] : []),\n `PID: ${record.pid}`,\n `Command: ${record.command}`,\n `CWD: ${record.cwd}`,\n `Session: ${record.sessionId}`,\n `Log: ${record.logPath}`,\n ...(record.exit ? [`Exit: ${formatExit(record)}`] : []),\n ].join('\\n'),\n );\n return 0;\n}\n\nasync function logs(args: readonly string[], dependencies: CliDependencies): Promise<number> {\n const record = await requiredRecord(args[0], dependencies);\n if (!record) return 1;\n const lines = positiveInteger(option(args, '--lines')) ?? DEFAULT_LOG_LINES;\n const result = dependencies.logReader.read(record.logPath, { lines });\n if (!result.exists) {\n dependencies.stderr(`Runner ${record.id} has not written a log yet`);\n return 1;\n }\n if (result.text) dependencies.stdout(result.text);\n if (!args.includes('--follow')) return 0;\n return follow(record, result.fileSize, dependencies);\n}\n\nasync function stop(args: readonly string[], dependencies: CliDependencies): Promise<number> {\n const record = await requiredRecord(args[0], dependencies);\n if (!record) return 1;\n if (record.state !== 'running') {\n dependencies.stderr(`Runner ${record.id} is already ${record.state}`);\n return 1;\n }\n await stopRecord(record, dependencies);\n const reason = option(args, '--reason');\n await dependencies.registry.complete(\n record.id,\n {\n reason: STOPPED_REASON,\n code: null,\n signal: TERMINATION_SIGNAL,\n ...(reason ? { stopReason: reason } : {}),\n },\n record.sessionId,\n );\n dependencies.stdout(`Stopped ${record.id}\\nLog: ${record.logPath}`);\n return 0;\n}\n\nasync function stopAll(args: readonly string[], dependencies: CliDependencies): Promise<number> {\n const sessionId = requiredSessionId(dependencies.env);\n const records = await dependencies.registry.listBySession(sessionId);\n const reason = option(args, '--reason');\n for (const record of records) {\n await stopRecord(record, dependencies);\n await dependencies.registry.complete(\n record.id,\n {\n reason: STOPPED_REASON,\n code: null,\n signal: TERMINATION_SIGNAL,\n ...(reason ? { stopReason: reason } : {}),\n },\n record.sessionId,\n );\n }\n dependencies.stdout(\n records.length > 0\n ? `Stopped ${records.length} runner(s) for session ${sessionId}: ${records.map((record) => record.id).join(', ')}`\n : `No active runners for session ${sessionId}`,\n );\n return 0;\n}\n\nasync function input(args: readonly string[], dependencies: CliDependencies): Promise<number> {\n const record = await requiredRecord(args[0], dependencies);\n if (!record) return 1;\n if (record.state === COMPLETED_STATE) {\n dependencies.stderr(`Runner ${record.id} is already completed; use doom-runner logs ${record.id}`);\n return 1;\n }\n if (!record.interactive) {\n dependencies.stderr(`Runner ${record.id} was not started with interactive: true`);\n return 1;\n }\n const supplied = option(args, '--text');\n const text = supplied ?? (await dependencies.readStdin());\n const payload = args.includes('--enter') && !text.endsWith('\\n') ? `${text}\\n` : text;\n if (record.backend !== RMUX_BACKEND || !record.backendTarget) {\n dependencies.stderr(`Runner ${record.id} uses the ${record.backend} backend, which does not expose CLI input`);\n return 1;\n }\n if (!(await dependencies.rmuxBackend.input(record.backendTarget, payload))) {\n dependencies.stderr(`Runner ${record.id} is no longer accepting RMUX input`);\n return 1;\n }\n dependencies.stdout(`Sent input to ${record.id}`);\n return 0;\n}\n\nasync function requiredRecord(\n id: string | undefined,\n dependencies: CliDependencies,\n): Promise<RunnerRecord | undefined> {\n if (!id) {\n dependencies.stderr('A runner ID is required');\n return undefined;\n }\n const sessionId = requiredSessionId(dependencies.env);\n const scopedRecord = await dependencies.registry.get(id, sessionId);\n if (!scopedRecord) {\n dependencies.stderr(`No runner with id ${id}`);\n return undefined;\n }\n return scopedRecord;\n}\n\nfunction formatRecord(record: RunnerRecord): string {\n const active = formatRunnerLine(record);\n return `${record.id} ${record.state} ${record.backend} ${active}`;\n}\n\nfunction formatExit(record: RunnerRecord): string {\n const exit = record.exit;\n if (!exit) return 'unknown';\n const detail = exit.code !== null ? ` code ${exit.code}` : exit.signal ? ` ${exit.signal}` : '';\n const note = exit.stopReason ? ` (${exit.stopReason})` : '';\n return `${exit.reason}${detail}${note}`;\n}\n\nfunction option(args: readonly string[], name: string): string | undefined {\n const index = args.indexOf(name);\n return index >= 0 ? args[index + 1] : undefined;\n}\n\nfunction positiveInteger(value: string | undefined): number | undefined {\n if (value === undefined) return undefined;\n const parsed = Number(value);\n return Number.isInteger(parsed) && parsed > 0 ? parsed : undefined;\n}\n\nasync function follow(record: RunnerRecord, initialSize: number, dependencies: CliDependencies): Promise<number> {\n let offset = initialSize;\n return new Promise<number>((resolve) => {\n let stopped = false;\n let stateTimer: NodeJS.Timeout;\n const listener = (current: fs.Stats): void => {\n if (current.size < offset) offset = 0;\n if (current.size === offset) return;\n const length = current.size - offset;\n const buffer = Buffer.alloc(length);\n const descriptor = fs.openSync(record.logPath, 'r');\n try {\n const bytesRead = fs.readSync(descriptor, buffer, 0, length, offset);\n if (bytesRead > 0) dependencies.stdout(buffer.subarray(0, bytesRead).toString('utf8'));\n } finally {\n fs.closeSync(descriptor);\n }\n offset = current.size;\n };\n const stopFollowing = (): void => {\n if (stopped) return;\n stopped = true;\n try {\n listener(fs.statSync(record.logPath));\n } catch (error) {\n // A missing log file was already reported by the initial read.\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') {\n dependencies.stderr(`Runner ${record.id} failed to flush its final log output: ${(error as Error).message}`);\n }\n }\n fs.unwatchFile(record.logPath, listener);\n clearInterval(stateTimer);\n process.off('SIGINT', stopFollowing);\n resolve(0);\n };\n process.once('SIGINT', stopFollowing);\n fs.watchFile(record.logPath, { interval: FOLLOW_INTERVAL_MS }, listener);\n stateTimer = setInterval(() => {\n void dependencies.registry.get(record.id).then((current) => {\n if (current?.state === COMPLETED_STATE) stopFollowing();\n });\n }, FOLLOW_INTERVAL_MS);\n });\n}\n\nasync function stopRecord(record: RunnerRecord, dependencies: CliDependencies): Promise<boolean> {\n if (record.backend === RMUX_BACKEND && record.backendTarget) {\n return dependencies.rmuxBackend.stop(record.backendTarget, record.pid);\n }\n return dependencies.launcher.stop(record.pid);\n}\n\nfunction help(): string {\n return [\n 'Usage: doom-runner <command>',\n '',\n 'Commands:',\n ' list [--all]',\n ' status <id>',\n ' logs <id> [--lines N] [--follow]',\n ' stop <id> [--reason <text>]',\n ' stop-all [--reason <text>]',\n ' input <id> [--text <text>] [--enter]',\n ].join('\\n');\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { ILauncher } from "../services/Launcher/types.cjs";
|
|
2
|
+
import "../services/Launcher/index.cjs";
|
|
3
|
+
import { ILogReader } from "../services/LogReader/types.cjs";
|
|
4
|
+
import "../services/LogReader/index.cjs";
|
|
5
|
+
import { IRmuxBackend } from "../services/RmuxBackend/types.cjs";
|
|
6
|
+
import "../services/RmuxBackend/index.cjs";
|
|
7
|
+
import { IRunnerRegistry } from "../services/RunnerRegistry/types.cjs";
|
|
8
|
+
import "../services/RunnerRegistry/index.cjs";
|
|
9
|
+
//#region src/cli/cliApp.d.ts
|
|
10
|
+
interface CliDependencies {
|
|
11
|
+
registry: IRunnerRegistry;
|
|
12
|
+
launcher: ILauncher;
|
|
13
|
+
rmuxBackend: IRmuxBackend;
|
|
14
|
+
logReader: ILogReader;
|
|
15
|
+
env?: NodeJS.ProcessEnv;
|
|
16
|
+
stdout(text: string): void;
|
|
17
|
+
stderr(text: string): void;
|
|
18
|
+
readStdin(): Promise<string>;
|
|
19
|
+
}
|
|
20
|
+
declare function runCli(argv: readonly string[], dependencies: CliDependencies): Promise<number>;
|
|
21
|
+
//#endregion
|
|
22
|
+
export { CliDependencies, runCli };
|
|
23
|
+
//# sourceMappingURL=cliApp.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cliApp.d.cts","names":[],"sources":["../../src/cli/cliApp.ts"],"mappings":";;;;;;;;;UAeiB;EACf,UAAU;EACV,UAAU;EACV,aAAa;EACb,WAAW;EACX,MAAM,OAAO;EACb,OAAO;EACP,OAAO;EACP,aAAa;;iBAGO,OAAO,yBAAyB,cAAc,kBAAkB"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { ILauncher } from "../services/Launcher/types.mjs";
|
|
2
|
+
import "../services/Launcher/index.mjs";
|
|
3
|
+
import { ILogReader } from "../services/LogReader/types.mjs";
|
|
4
|
+
import "../services/LogReader/index.mjs";
|
|
5
|
+
import { IRmuxBackend } from "../services/RmuxBackend/types.mjs";
|
|
6
|
+
import "../services/RmuxBackend/index.mjs";
|
|
7
|
+
import { IRunnerRegistry } from "../services/RunnerRegistry/types.mjs";
|
|
8
|
+
import "../services/RunnerRegistry/index.mjs";
|
|
9
|
+
//#region src/cli/cliApp.d.ts
|
|
10
|
+
interface CliDependencies {
|
|
11
|
+
registry: IRunnerRegistry;
|
|
12
|
+
launcher: ILauncher;
|
|
13
|
+
rmuxBackend: IRmuxBackend;
|
|
14
|
+
logReader: ILogReader;
|
|
15
|
+
env?: NodeJS.ProcessEnv;
|
|
16
|
+
stdout(text: string): void;
|
|
17
|
+
stderr(text: string): void;
|
|
18
|
+
readStdin(): Promise<string>;
|
|
19
|
+
}
|
|
20
|
+
declare function runCli(argv: readonly string[], dependencies: CliDependencies): Promise<number>;
|
|
21
|
+
//#endregion
|
|
22
|
+
export { CliDependencies, runCli };
|
|
23
|
+
//# sourceMappingURL=cliApp.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cliApp.d.mts","names":[],"sources":["../../src/cli/cliApp.ts"],"mappings":";;;;;;;;;UAeiB;EACf,UAAU;EACV,UAAU;EACV,aAAa;EACb,WAAW;EACX,MAAM,OAAO;EACb,OAAO;EACP,OAAO;EACP,aAAa;;iBAGO,OAAO,yBAAyB,cAAc,kBAAkB"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import{inheritedSessionId as e,requiredSessionId as t}from"../session.mjs";import{formatRunnerLine as n}from"../tool/responseEnvelope.mjs";import r from"node:fs";const i=`completed`,a=`rmux`,o=`stopped`,s=`SIGTERM`;async function c(t,n){let[r,...i]=t;if(r!==void 0&&r!==`--help`&&r!==`-h`&&!e(n.env))return n.stderr(`PI_SESSION_ID is required for doom-runner commands`),1;switch(r){case`list`:return l(i,n);case`status`:return u(i,n);case`logs`:return d(i,n);case`stop`:return f(i,n);case`stop-all`:return p(i,n);case`input`:return m(i,n);case`--help`:case`-h`:case void 0:return n.stdout(S()),0;default:return n.stderr(`Unknown command: ${r}\n\n${S()}`),1}}async function l(e,n){let r=t(n.env),i=e.includes(`--all`)?await n.registry.listAll(r):await n.registry.listBySession(r);return n.stdout(i.length>0?i.map(g).join(`
|
|
2
|
+
`):`No runners`),0}async function u(e,t){let n=await h(e[0],t);return n?(t.stdout([`ID: ${n.id}`,`Name: ${n.name}`,`State: ${n.state}`,`Backend: ${n.backend}`,...n.backendTarget?[`Backend target: ${n.backendTarget}`]:[],`PID: ${n.pid}`,`Command: ${n.command}`,`CWD: ${n.cwd}`,`Session: ${n.sessionId}`,`Log: ${n.logPath}`,...n.exit?[`Exit: ${_(n)}`]:[]].join(`
|
|
3
|
+
`)),0):1}async function d(e,t){let n=await h(e[0],t);if(!n)return 1;let r=y(v(e,`--lines`))??200,i=t.logReader.read(n.logPath,{lines:r});return i.exists?(i.text&&t.stdout(i.text),e.includes(`--follow`)?b(n,i.fileSize,t):0):(t.stderr(`Runner ${n.id} has not written a log yet`),1)}async function f(e,t){let n=await h(e[0],t);if(!n)return 1;if(n.state!==`running`)return t.stderr(`Runner ${n.id} is already ${n.state}`),1;await x(n,t);let r=v(e,`--reason`);return await t.registry.complete(n.id,{reason:o,code:null,signal:s,...r?{stopReason:r}:{}},n.sessionId),t.stdout(`Stopped ${n.id}\nLog: ${n.logPath}`),0}async function p(e,n){let r=t(n.env),i=await n.registry.listBySession(r),a=v(e,`--reason`);for(let e of i)await x(e,n),await n.registry.complete(e.id,{reason:o,code:null,signal:s,...a?{stopReason:a}:{}},e.sessionId);return n.stdout(i.length>0?`Stopped ${i.length} runner(s) for session ${r}: ${i.map(e=>e.id).join(`, `)}`:`No active runners for session ${r}`),0}async function m(e,t){let n=await h(e[0],t);if(!n)return 1;if(n.state===i)return t.stderr(`Runner ${n.id} is already completed; use doom-runner logs ${n.id}`),1;if(!n.interactive)return t.stderr(`Runner ${n.id} was not started with interactive: true`),1;let r=v(e,`--text`)??await t.readStdin(),o=e.includes(`--enter`)&&!r.endsWith(`
|
|
4
|
+
`)?`${r}\n`:r;return n.backend!==a||!n.backendTarget?(t.stderr(`Runner ${n.id} uses the ${n.backend} backend, which does not expose CLI input`),1):await t.rmuxBackend.input(n.backendTarget,o)?(t.stdout(`Sent input to ${n.id}`),0):(t.stderr(`Runner ${n.id} is no longer accepting RMUX input`),1)}async function h(e,n){if(!e){n.stderr(`A runner ID is required`);return}let r=t(n.env),i=await n.registry.get(e,r);if(!i){n.stderr(`No runner with id ${e}`);return}return i}function g(e){let t=n(e);return`${e.id} ${e.state} ${e.backend} ${t}`}function _(e){let t=e.exit;if(!t)return`unknown`;let n=t.code===null?t.signal?` ${t.signal}`:``:` code ${t.code}`,r=t.stopReason?` (${t.stopReason})`:``;return`${t.reason}${n}${r}`}function v(e,t){let n=e.indexOf(t);return n>=0?e[n+1]:void 0}function y(e){if(e===void 0)return;let t=Number(e);return Number.isInteger(t)&&t>0?t:void 0}async function b(e,t,n){let a=t;return new Promise(t=>{let o=!1,s,c=t=>{if(t.size<a&&(a=0),t.size===a)return;let i=t.size-a,o=Buffer.alloc(i),s=r.openSync(e.logPath,`r`);try{let e=r.readSync(s,o,0,i,a);e>0&&n.stdout(o.subarray(0,e).toString(`utf8`))}finally{r.closeSync(s)}a=t.size},l=()=>{if(!o){o=!0;try{c(r.statSync(e.logPath))}catch(t){t.code!==`ENOENT`&&n.stderr(`Runner ${e.id} failed to flush its final log output: ${t.message}`)}r.unwatchFile(e.logPath,c),clearInterval(s),process.off(`SIGINT`,l),t(0)}};process.once(`SIGINT`,l),r.watchFile(e.logPath,{interval:250},c),s=setInterval(()=>{n.registry.get(e.id).then(e=>{e?.state===i&&l()})},250)})}async function x(e,t){return e.backend===a&&e.backendTarget?t.rmuxBackend.stop(e.backendTarget,e.pid):t.launcher.stop(e.pid)}function S(){return[`Usage: doom-runner <command>`,``,`Commands:`,` list [--all]`,` status <id>`,` logs <id> [--lines N] [--follow]`,` stop <id> [--reason <text>]`,` stop-all [--reason <text>]`,` input <id> [--text <text>] [--enter]`].join(`
|
|
5
|
+
`)}export{c as runCli};
|
|
6
|
+
//# sourceMappingURL=cliApp.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cliApp.mjs","names":[],"sources":["../../src/cli/cliApp.ts"],"sourcesContent":["import fs from 'node:fs';\nimport type { ILauncher } from '../services/Launcher/index.ts';\nimport type { ILogReader } from '../services/LogReader/index.ts';\nimport type { IRmuxBackend } from '../services/RmuxBackend/index.ts';\nimport type { IRunnerRegistry, RunnerRecord } from '../services/RunnerRegistry/index.ts';\nimport { inheritedSessionId, requiredSessionId } from '../session.ts';\nimport { formatRunnerLine } from '../tool/responseEnvelope.ts';\n\nconst DEFAULT_LOG_LINES = 200;\nconst FOLLOW_INTERVAL_MS = 250;\nconst COMPLETED_STATE = 'completed';\nconst RMUX_BACKEND = 'rmux';\nconst STOPPED_REASON = 'stopped';\nconst TERMINATION_SIGNAL = 'SIGTERM';\n\nexport interface CliDependencies {\n registry: IRunnerRegistry;\n launcher: ILauncher;\n rmuxBackend: IRmuxBackend;\n logReader: ILogReader;\n env?: NodeJS.ProcessEnv;\n stdout(text: string): void;\n stderr(text: string): void;\n readStdin(): Promise<string>;\n}\n\nexport async function runCli(argv: readonly string[], dependencies: CliDependencies): Promise<number> {\n const [command, ...args] = argv;\n if (command !== undefined && command !== '--help' && command !== '-h' && !inheritedSessionId(dependencies.env)) {\n dependencies.stderr('PI_SESSION_ID is required for doom-runner commands');\n return 1;\n }\n switch (command) {\n case 'list':\n return list(args, dependencies);\n case 'status':\n return status(args, dependencies);\n case 'logs':\n return logs(args, dependencies);\n case 'stop':\n return stop(args, dependencies);\n case 'stop-all':\n return stopAll(args, dependencies);\n case 'input':\n return input(args, dependencies);\n case '--help':\n case '-h':\n case undefined:\n dependencies.stdout(help());\n return 0;\n default:\n dependencies.stderr(`Unknown command: ${command}\\n\\n${help()}`);\n return 1;\n }\n}\n\nasync function list(args: readonly string[], dependencies: CliDependencies): Promise<number> {\n const sessionId = requiredSessionId(dependencies.env);\n const records = args.includes('--all')\n ? await dependencies.registry.listAll(sessionId)\n : await dependencies.registry.listBySession(sessionId);\n dependencies.stdout(records.length > 0 ? records.map(formatRecord).join('\\n') : 'No runners');\n return 0;\n}\n\nasync function status(args: readonly string[], dependencies: CliDependencies): Promise<number> {\n const record = await requiredRecord(args[0], dependencies);\n if (!record) return 1;\n dependencies.stdout(\n [\n `ID: ${record.id}`,\n `Name: ${record.name}`,\n `State: ${record.state}`,\n `Backend: ${record.backend}`,\n ...(record.backendTarget ? [`Backend target: ${record.backendTarget}`] : []),\n `PID: ${record.pid}`,\n `Command: ${record.command}`,\n `CWD: ${record.cwd}`,\n `Session: ${record.sessionId}`,\n `Log: ${record.logPath}`,\n ...(record.exit ? [`Exit: ${formatExit(record)}`] : []),\n ].join('\\n'),\n );\n return 0;\n}\n\nasync function logs(args: readonly string[], dependencies: CliDependencies): Promise<number> {\n const record = await requiredRecord(args[0], dependencies);\n if (!record) return 1;\n const lines = positiveInteger(option(args, '--lines')) ?? DEFAULT_LOG_LINES;\n const result = dependencies.logReader.read(record.logPath, { lines });\n if (!result.exists) {\n dependencies.stderr(`Runner ${record.id} has not written a log yet`);\n return 1;\n }\n if (result.text) dependencies.stdout(result.text);\n if (!args.includes('--follow')) return 0;\n return follow(record, result.fileSize, dependencies);\n}\n\nasync function stop(args: readonly string[], dependencies: CliDependencies): Promise<number> {\n const record = await requiredRecord(args[0], dependencies);\n if (!record) return 1;\n if (record.state !== 'running') {\n dependencies.stderr(`Runner ${record.id} is already ${record.state}`);\n return 1;\n }\n await stopRecord(record, dependencies);\n const reason = option(args, '--reason');\n await dependencies.registry.complete(\n record.id,\n {\n reason: STOPPED_REASON,\n code: null,\n signal: TERMINATION_SIGNAL,\n ...(reason ? { stopReason: reason } : {}),\n },\n record.sessionId,\n );\n dependencies.stdout(`Stopped ${record.id}\\nLog: ${record.logPath}`);\n return 0;\n}\n\nasync function stopAll(args: readonly string[], dependencies: CliDependencies): Promise<number> {\n const sessionId = requiredSessionId(dependencies.env);\n const records = await dependencies.registry.listBySession(sessionId);\n const reason = option(args, '--reason');\n for (const record of records) {\n await stopRecord(record, dependencies);\n await dependencies.registry.complete(\n record.id,\n {\n reason: STOPPED_REASON,\n code: null,\n signal: TERMINATION_SIGNAL,\n ...(reason ? { stopReason: reason } : {}),\n },\n record.sessionId,\n );\n }\n dependencies.stdout(\n records.length > 0\n ? `Stopped ${records.length} runner(s) for session ${sessionId}: ${records.map((record) => record.id).join(', ')}`\n : `No active runners for session ${sessionId}`,\n );\n return 0;\n}\n\nasync function input(args: readonly string[], dependencies: CliDependencies): Promise<number> {\n const record = await requiredRecord(args[0], dependencies);\n if (!record) return 1;\n if (record.state === COMPLETED_STATE) {\n dependencies.stderr(`Runner ${record.id} is already completed; use doom-runner logs ${record.id}`);\n return 1;\n }\n if (!record.interactive) {\n dependencies.stderr(`Runner ${record.id} was not started with interactive: true`);\n return 1;\n }\n const supplied = option(args, '--text');\n const text = supplied ?? (await dependencies.readStdin());\n const payload = args.includes('--enter') && !text.endsWith('\\n') ? `${text}\\n` : text;\n if (record.backend !== RMUX_BACKEND || !record.backendTarget) {\n dependencies.stderr(`Runner ${record.id} uses the ${record.backend} backend, which does not expose CLI input`);\n return 1;\n }\n if (!(await dependencies.rmuxBackend.input(record.backendTarget, payload))) {\n dependencies.stderr(`Runner ${record.id} is no longer accepting RMUX input`);\n return 1;\n }\n dependencies.stdout(`Sent input to ${record.id}`);\n return 0;\n}\n\nasync function requiredRecord(\n id: string | undefined,\n dependencies: CliDependencies,\n): Promise<RunnerRecord | undefined> {\n if (!id) {\n dependencies.stderr('A runner ID is required');\n return undefined;\n }\n const sessionId = requiredSessionId(dependencies.env);\n const scopedRecord = await dependencies.registry.get(id, sessionId);\n if (!scopedRecord) {\n dependencies.stderr(`No runner with id ${id}`);\n return undefined;\n }\n return scopedRecord;\n}\n\nfunction formatRecord(record: RunnerRecord): string {\n const active = formatRunnerLine(record);\n return `${record.id} ${record.state} ${record.backend} ${active}`;\n}\n\nfunction formatExit(record: RunnerRecord): string {\n const exit = record.exit;\n if (!exit) return 'unknown';\n const detail = exit.code !== null ? ` code ${exit.code}` : exit.signal ? ` ${exit.signal}` : '';\n const note = exit.stopReason ? ` (${exit.stopReason})` : '';\n return `${exit.reason}${detail}${note}`;\n}\n\nfunction option(args: readonly string[], name: string): string | undefined {\n const index = args.indexOf(name);\n return index >= 0 ? args[index + 1] : undefined;\n}\n\nfunction positiveInteger(value: string | undefined): number | undefined {\n if (value === undefined) return undefined;\n const parsed = Number(value);\n return Number.isInteger(parsed) && parsed > 0 ? parsed : undefined;\n}\n\nasync function follow(record: RunnerRecord, initialSize: number, dependencies: CliDependencies): Promise<number> {\n let offset = initialSize;\n return new Promise<number>((resolve) => {\n let stopped = false;\n let stateTimer: NodeJS.Timeout;\n const listener = (current: fs.Stats): void => {\n if (current.size < offset) offset = 0;\n if (current.size === offset) return;\n const length = current.size - offset;\n const buffer = Buffer.alloc(length);\n const descriptor = fs.openSync(record.logPath, 'r');\n try {\n const bytesRead = fs.readSync(descriptor, buffer, 0, length, offset);\n if (bytesRead > 0) dependencies.stdout(buffer.subarray(0, bytesRead).toString('utf8'));\n } finally {\n fs.closeSync(descriptor);\n }\n offset = current.size;\n };\n const stopFollowing = (): void => {\n if (stopped) return;\n stopped = true;\n try {\n listener(fs.statSync(record.logPath));\n } catch (error) {\n // A missing log file was already reported by the initial read.\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') {\n dependencies.stderr(`Runner ${record.id} failed to flush its final log output: ${(error as Error).message}`);\n }\n }\n fs.unwatchFile(record.logPath, listener);\n clearInterval(stateTimer);\n process.off('SIGINT', stopFollowing);\n resolve(0);\n };\n process.once('SIGINT', stopFollowing);\n fs.watchFile(record.logPath, { interval: FOLLOW_INTERVAL_MS }, listener);\n stateTimer = setInterval(() => {\n void dependencies.registry.get(record.id).then((current) => {\n if (current?.state === COMPLETED_STATE) stopFollowing();\n });\n }, FOLLOW_INTERVAL_MS);\n });\n}\n\nasync function stopRecord(record: RunnerRecord, dependencies: CliDependencies): Promise<boolean> {\n if (record.backend === RMUX_BACKEND && record.backendTarget) {\n return dependencies.rmuxBackend.stop(record.backendTarget, record.pid);\n }\n return dependencies.launcher.stop(record.pid);\n}\n\nfunction help(): string {\n return [\n 'Usage: doom-runner <command>',\n '',\n 'Commands:',\n ' list [--all]',\n ' status <id>',\n ' logs <id> [--lines N] [--follow]',\n ' stop <id> [--reason <text>]',\n ' stop-all [--reason <text>]',\n ' input <id> [--text <text>] [--enter]',\n ].join('\\n');\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=`Active background runners survived compaction:`;function t(t){if(t.length===0)return``;let n=t.flatMap(e=>[`- ${e.name} (${e.id}), log: ${e.logPath}`,` Check: doom-runner status ${e.id}`,` Stream: doom-runner logs ${e.id} --follow`]);return[e,...n,`Use these CLI commands to inspect existing runners before launching another command.`].join(`
|
|
2
|
+
`)}function n(n,r){return r.length===0||n.includes(e)?n:[n,``,t(r)].join(`
|
|
3
|
+
`)}function r(e,n){e.on(`session_compact`,async()=>{let r=n.getSessionId();if(!r)return;let i;try{i=await n.listBySession(r)}catch{return}let a=t(i);a&&e.sendMessage({customType:`doom-runner-compaction`,content:a,display:!1,details:{sessionId:r,runnerIds:i.map(e=>e.id)}},{triggerTurn:!1,deliverAs:`steer`})})}exports.activeRunnerRecovery=t,exports.appendActiveRunnersToSummary=n,exports.registerRunnerCompactionRecovery=r;
|
|
4
|
+
//# sourceMappingURL=compaction.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compaction.cjs","names":[],"sources":["../src/compaction.ts"],"sourcesContent":["import type { ExtensionAPI } from '@earendil-works/pi-coding-agent';\nimport type { RunnerRecord } from './services/RunnerRegistry/index.ts';\n\nconst COMPACTION_RUNNERS_MARKER = 'Active background runners survived compaction:';\nconst RUNNER_COMPACTION_MESSAGE = 'doom-runner-compaction';\n\nexport interface RunnerCompactionDependencies {\n getSessionId(): string | undefined;\n listBySession(sessionId: string): Promise<RunnerRecord[]>;\n}\n\nexport function activeRunnerRecovery(active: readonly RunnerRecord[]): string {\n if (active.length === 0) return '';\n const runners = active.flatMap((record) => [\n `- ${record.name} (${record.id}), log: ${record.logPath}`,\n ` Check: doom-runner status ${record.id}`,\n ` Stream: doom-runner logs ${record.id} --follow`,\n ]);\n return [\n COMPACTION_RUNNERS_MARKER,\n ...runners,\n 'Use these CLI commands to inspect existing runners before launching another command.',\n ].join('\\n');\n}\n\nexport function appendActiveRunnersToSummary(summary: string, active: readonly RunnerRecord[]): string {\n if (active.length === 0 || summary.includes(COMPACTION_RUNNERS_MARKER)) return summary;\n return [summary, '', activeRunnerRecovery(active)].join('\\n');\n}\n\nexport function registerRunnerCompactionRecovery(pi: ExtensionAPI, dependencies: RunnerCompactionDependencies): void {\n pi.on('session_compact', async () => {\n const sessionId = dependencies.getSessionId();\n if (!sessionId) return;\n let active: RunnerRecord[];\n try {\n active = await dependencies.listBySession(sessionId);\n } catch {\n // Recovery is advisory. Omit stale runner hints rather than failing a completed compaction.\n return;\n }\n const content = activeRunnerRecovery(active);\n if (!content) return;\n pi.sendMessage(\n {\n customType: RUNNER_COMPACTION_MESSAGE,\n content,\n display: false,\n details: { sessionId, runnerIds: active.map((record) => record.id) },\n },\n { triggerTurn: false, deliverAs: 'steer' },\n );\n });\n}\n"],"mappings":"mEAGA,MAAM,EAA4B,iDAQlC,SAAgB,EAAqB,EAAyC,CAC5E,GAAI,EAAO,SAAW,EAAG,MAAO,GAChC,IAAM,EAAU,EAAO,QAAS,GAAW,CACzC,KAAK,EAAO,KAAK,IAAI,EAAO,GAAG,UAAU,EAAO,UAChD,+BAA+B,EAAO,KACtC,8BAA8B,EAAO,GAAG,UAC1C,CAAC,EACD,MAAO,CACL,EACA,GAAG,EACH,sFACF,CAAC,CAAC,KAAK;CAAI,CACb,CAEA,SAAgB,EAA6B,EAAiB,EAAyC,CAErG,OADI,EAAO,SAAW,GAAK,EAAQ,SAAS,CAAyB,EAAU,EACxE,CAAC,EAAS,GAAI,EAAqB,CAAM,CAAC,CAAC,CAAC,KAAK;CAAI,CAC9D,CAEA,SAAgB,EAAiC,EAAkB,EAAkD,CACnH,EAAG,GAAG,kBAAmB,SAAY,CACnC,IAAM,EAAY,EAAa,aAAa,EAC5C,GAAI,CAAC,EAAW,OAChB,IAAI,EACJ,GAAI,CACF,EAAS,MAAM,EAAa,cAAc,CAAS,CACrD,MAAQ,CAEN,MACF,CACA,IAAM,EAAU,EAAqB,CAAM,EACtC,GACL,EAAG,YACD,CACE,WAAY,yBACZ,UACA,QAAS,GACT,QAAS,CAAE,YAAW,UAAW,EAAO,IAAK,GAAW,EAAO,EAAE,CAAE,CACrE,EACA,CAAE,YAAa,GAAO,UAAW,OAAQ,CAC3C,CACF,CAAC,CACH"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { RunnerRecord } from "./services/RunnerRegistry/types.cjs";
|
|
2
|
+
import "./services/RunnerRegistry/index.cjs";
|
|
3
|
+
import { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
4
|
+
//#region src/compaction.d.ts
|
|
5
|
+
interface RunnerCompactionDependencies {
|
|
6
|
+
getSessionId(): string | undefined;
|
|
7
|
+
listBySession(sessionId: string): Promise<RunnerRecord[]>;
|
|
8
|
+
}
|
|
9
|
+
declare function activeRunnerRecovery(active: readonly RunnerRecord[]): string;
|
|
10
|
+
declare function appendActiveRunnersToSummary(summary: string, active: readonly RunnerRecord[]): string;
|
|
11
|
+
declare function registerRunnerCompactionRecovery(pi: ExtensionAPI, dependencies: RunnerCompactionDependencies): void;
|
|
12
|
+
//#endregion
|
|
13
|
+
export { RunnerCompactionDependencies, activeRunnerRecovery, appendActiveRunnersToSummary, registerRunnerCompactionRecovery };
|
|
14
|
+
//# sourceMappingURL=compaction.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compaction.d.cts","names":[],"sources":["../src/compaction.ts"],"mappings":";;;;UAMiB;EACf;EACA,cAAc,oBAAoB,QAAQ;;iBAG5B,qBAAqB,iBAAiB;iBActC,6BAA6B,iBAAiB,iBAAiB;iBAK/D,iCAAiC,IAAI,cAAc,cAAc"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { RunnerRecord } from "./services/RunnerRegistry/types.mjs";
|
|
2
|
+
import "./services/RunnerRegistry/index.mjs";
|
|
3
|
+
import { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
4
|
+
//#region src/compaction.d.ts
|
|
5
|
+
interface RunnerCompactionDependencies {
|
|
6
|
+
getSessionId(): string | undefined;
|
|
7
|
+
listBySession(sessionId: string): Promise<RunnerRecord[]>;
|
|
8
|
+
}
|
|
9
|
+
declare function activeRunnerRecovery(active: readonly RunnerRecord[]): string;
|
|
10
|
+
declare function appendActiveRunnersToSummary(summary: string, active: readonly RunnerRecord[]): string;
|
|
11
|
+
declare function registerRunnerCompactionRecovery(pi: ExtensionAPI, dependencies: RunnerCompactionDependencies): void;
|
|
12
|
+
//#endregion
|
|
13
|
+
export { RunnerCompactionDependencies, activeRunnerRecovery, appendActiveRunnersToSummary, registerRunnerCompactionRecovery };
|
|
14
|
+
//# sourceMappingURL=compaction.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compaction.d.mts","names":[],"sources":["../src/compaction.ts"],"mappings":";;;;UAMiB;EACf;EACA,cAAc,oBAAoB,QAAQ;;iBAG5B,qBAAqB,iBAAiB;iBActC,6BAA6B,iBAAiB,iBAAiB;iBAK/D,iCAAiC,IAAI,cAAc,cAAc"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
const e=`Active background runners survived compaction:`;function t(t){if(t.length===0)return``;let n=t.flatMap(e=>[`- ${e.name} (${e.id}), log: ${e.logPath}`,` Check: doom-runner status ${e.id}`,` Stream: doom-runner logs ${e.id} --follow`]);return[e,...n,`Use these CLI commands to inspect existing runners before launching another command.`].join(`
|
|
2
|
+
`)}function n(n,r){return r.length===0||n.includes(e)?n:[n,``,t(r)].join(`
|
|
3
|
+
`)}function r(e,n){e.on(`session_compact`,async()=>{let r=n.getSessionId();if(!r)return;let i;try{i=await n.listBySession(r)}catch{return}let a=t(i);a&&e.sendMessage({customType:`doom-runner-compaction`,content:a,display:!1,details:{sessionId:r,runnerIds:i.map(e=>e.id)}},{triggerTurn:!1,deliverAs:`steer`})})}export{t as activeRunnerRecovery,n as appendActiveRunnersToSummary,r as registerRunnerCompactionRecovery};
|
|
4
|
+
//# sourceMappingURL=compaction.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compaction.mjs","names":[],"sources":["../src/compaction.ts"],"sourcesContent":["import type { ExtensionAPI } from '@earendil-works/pi-coding-agent';\nimport type { RunnerRecord } from './services/RunnerRegistry/index.ts';\n\nconst COMPACTION_RUNNERS_MARKER = 'Active background runners survived compaction:';\nconst RUNNER_COMPACTION_MESSAGE = 'doom-runner-compaction';\n\nexport interface RunnerCompactionDependencies {\n getSessionId(): string | undefined;\n listBySession(sessionId: string): Promise<RunnerRecord[]>;\n}\n\nexport function activeRunnerRecovery(active: readonly RunnerRecord[]): string {\n if (active.length === 0) return '';\n const runners = active.flatMap((record) => [\n `- ${record.name} (${record.id}), log: ${record.logPath}`,\n ` Check: doom-runner status ${record.id}`,\n ` Stream: doom-runner logs ${record.id} --follow`,\n ]);\n return [\n COMPACTION_RUNNERS_MARKER,\n ...runners,\n 'Use these CLI commands to inspect existing runners before launching another command.',\n ].join('\\n');\n}\n\nexport function appendActiveRunnersToSummary(summary: string, active: readonly RunnerRecord[]): string {\n if (active.length === 0 || summary.includes(COMPACTION_RUNNERS_MARKER)) return summary;\n return [summary, '', activeRunnerRecovery(active)].join('\\n');\n}\n\nexport function registerRunnerCompactionRecovery(pi: ExtensionAPI, dependencies: RunnerCompactionDependencies): void {\n pi.on('session_compact', async () => {\n const sessionId = dependencies.getSessionId();\n if (!sessionId) return;\n let active: RunnerRecord[];\n try {\n active = await dependencies.listBySession(sessionId);\n } catch {\n // Recovery is advisory. Omit stale runner hints rather than failing a completed compaction.\n return;\n }\n const content = activeRunnerRecovery(active);\n if (!content) return;\n pi.sendMessage(\n {\n customType: RUNNER_COMPACTION_MESSAGE,\n content,\n display: false,\n details: { sessionId, runnerIds: active.map((record) => record.id) },\n },\n { triggerTurn: false, deliverAs: 'steer' },\n );\n });\n}\n"],"mappings":"AAGA,MAAM,EAA4B,iDAQlC,SAAgB,EAAqB,EAAyC,CAC5E,GAAI,EAAO,SAAW,EAAG,MAAO,GAChC,IAAM,EAAU,EAAO,QAAS,GAAW,CACzC,KAAK,EAAO,KAAK,IAAI,EAAO,GAAG,UAAU,EAAO,UAChD,+BAA+B,EAAO,KACtC,8BAA8B,EAAO,GAAG,UAC1C,CAAC,EACD,MAAO,CACL,EACA,GAAG,EACH,sFACF,CAAC,CAAC,KAAK;CAAI,CACb,CAEA,SAAgB,EAA6B,EAAiB,EAAyC,CAErG,OADI,EAAO,SAAW,GAAK,EAAQ,SAAS,CAAyB,EAAU,EACxE,CAAC,EAAS,GAAI,EAAqB,CAAM,CAAC,CAAC,CAAC,KAAK;CAAI,CAC9D,CAEA,SAAgB,EAAiC,EAAkB,EAAkD,CACnH,EAAG,GAAG,kBAAmB,SAAY,CACnC,IAAM,EAAY,EAAa,aAAa,EAC5C,GAAI,CAAC,EAAW,OAChB,IAAI,EACJ,GAAI,CACF,EAAS,MAAM,EAAa,cAAc,CAAS,CACrD,MAAQ,CAEN,MACF,CACA,IAAM,EAAU,EAAqB,CAAM,EACtC,GACL,EAAG,YACD,CACE,WAAY,yBACZ,UACA,QAAS,GACT,QAAS,CAAE,YAAW,UAAW,EAAO,IAAK,GAAW,EAAO,EAAE,CAAE,CACrE,EACA,CAAE,YAAa,GAAO,UAAW,OAAQ,CAC3C,CACF,CAAC,CACH"}
|
package/dist/config.cjs
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=`DOOM_RUNNER_BG_THRESHOLD_MS`,t=`DOOM_RUNNER_RESULT_MAX_BYTES`,n=`DOOM_RUNNER_LOG_MAX_BYTES`,r=`DOOM_RUNNER_LOG_TTL_MS`,i=6e4,a=51200,o=5242880,s=6048e5;function c(e,t){let n=Number(e);return Number.isFinite(n)&&n>0?n:t}function l(t=process.env){return c(t[e],i)}function u(e=process.env){return c(e[t],a)}function d(e=process.env){return c(e[n],o)}function f(e=process.env){return c(e[r],s)}exports.BG_THRESHOLD_MS_ENV=e,exports.DEFAULT_BG_THRESHOLD_MS=i,exports.DEFAULT_LOG_MAX_BYTES=o,exports.DEFAULT_LOG_TTL_MS=s,exports.DEFAULT_RESULT_MAX_BYTES=a,exports.LOG_DIR_ENV=`DOOM_RUNNER_LOG_DIR`,exports.LOG_MAX_BYTES_ENV=n,exports.LOG_TTL_MS_ENV=r,exports.RESULT_MAX_BYTES_ENV=t,exports.getBackgroundThresholdMs=l,exports.getLogMaxBytes=d,exports.getLogTtlMs=f,exports.getResultMaxBytes=u;
|
|
2
|
+
//# sourceMappingURL=config.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.cjs","names":[],"sources":["../src/config.ts"],"sourcesContent":["/**\n * Extension configuration, read from the environment.\n *\n * Env rather than a config file, matching doom-task: doom-pi already carries\n * per-launch state to Pi through env vars.\n */\n\nexport const BG_THRESHOLD_MS_ENV = 'DOOM_RUNNER_BG_THRESHOLD_MS';\nexport const RESULT_MAX_BYTES_ENV = 'DOOM_RUNNER_RESULT_MAX_BYTES';\nexport const LOG_MAX_BYTES_ENV = 'DOOM_RUNNER_LOG_MAX_BYTES';\nexport const LOG_TTL_MS_ENV = 'DOOM_RUNNER_LOG_TTL_MS';\n/** Unscoped override for the runner log directory. */\nexport const LOG_DIR_ENV = 'DOOM_RUNNER_LOG_DIR';\n\n/** A bash call still running at this point is promoted to a named runner. */\nexport const DEFAULT_BG_THRESHOLD_MS = 60_000;\n/** Tool results past this size are tail-truncated and spilled to the log file. */\nexport const DEFAULT_RESULT_MAX_BYTES = 51_200;\n/** A runner log rotates once to `.log.1` at this size. */\nexport const DEFAULT_LOG_MAX_BYTES = 5 * 1024 * 1024;\n/** Retention window for logs with no live registry record. */\nexport const DEFAULT_LOG_TTL_MS = 7 * 24 * 60 * 60 * 1000;\n\nfunction positiveNumber(raw: string | undefined, fallback: number): number {\n const value = Number(raw);\n return Number.isFinite(value) && value > 0 ? value : fallback;\n}\n\n/** Age at which a bash call becomes a background runner. */\nexport function getBackgroundThresholdMs(env: NodeJS.ProcessEnv = process.env): number {\n return positiveNumber(env[BG_THRESHOLD_MS_ENV], DEFAULT_BG_THRESHOLD_MS);\n}\n\n/** Byte ceiling for a single tool result before tail truncation kicks in. */\nexport function getResultMaxBytes(env: NodeJS.ProcessEnv = process.env): number {\n return positiveNumber(env[RESULT_MAX_BYTES_ENV], DEFAULT_RESULT_MAX_BYTES);\n}\n\n/** Byte ceiling for a runner log before it rotates. */\nexport function getLogMaxBytes(env: NodeJS.ProcessEnv = process.env): number {\n return positiveNumber(env[LOG_MAX_BYTES_ENV], DEFAULT_LOG_MAX_BYTES);\n}\n\n/** Retention window for orphaned runner logs. */\nexport function getLogTtlMs(env: NodeJS.ProcessEnv = process.env): number {\n return positiveNumber(env[LOG_TTL_MS_ENV], DEFAULT_LOG_TTL_MS);\n}\n"],"mappings":"mEAOA,MAAa,EAAsB,8BACtB,EAAuB,+BACvB,EAAoB,4BACpB,EAAiB,yBAKjB,EAA0B,IAE1B,EAA2B,MAE3B,EAAwB,QAExB,EAAqB,OAElC,SAAS,EAAe,EAAyB,EAA0B,CACzE,IAAM,EAAQ,OAAO,CAAG,EACxB,OAAO,OAAO,SAAS,CAAK,GAAK,EAAQ,EAAI,EAAQ,CACvD,CAGA,SAAgB,EAAyB,EAAyB,QAAQ,IAAa,CACrF,OAAO,EAAe,EAAI,GAAsB,CAAuB,CACzE,CAGA,SAAgB,EAAkB,EAAyB,QAAQ,IAAa,CAC9E,OAAO,EAAe,EAAI,GAAuB,CAAwB,CAC3E,CAGA,SAAgB,EAAe,EAAyB,QAAQ,IAAa,CAC3E,OAAO,EAAe,EAAI,GAAoB,CAAqB,CACrE,CAGA,SAAgB,EAAY,EAAyB,QAAQ,IAAa,CACxE,OAAO,EAAe,EAAI,GAAiB,CAAkB,CAC/D"}
|