@vibesdotdev/pm 0.0.0-stage → 1.0.0-rc.3
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 +18 -0
- package/README.md +227 -2
- package/dist/admission-store.d.ts +43 -0
- package/dist/admission-store.d.ts.map +1 -0
- package/dist/admission-store.js +108 -0
- package/dist/admission-store.js.map +1 -0
- package/dist/admission.d.ts +46 -0
- package/dist/admission.d.ts.map +1 -0
- package/dist/admission.js +81 -0
- package/dist/admission.js.map +1 -0
- package/dist/admitted-workspace.context.descriptor.d.ts +39 -0
- package/dist/admitted-workspace.context.descriptor.d.ts.map +1 -0
- package/dist/admitted-workspace.context.descriptor.js +18 -0
- package/dist/admitted-workspace.context.descriptor.js.map +1 -0
- package/dist/admitted-workspace.context.impl.consumer.d.ts +16 -0
- package/dist/admitted-workspace.context.impl.consumer.d.ts.map +1 -0
- package/dist/admitted-workspace.context.impl.consumer.js +7 -0
- package/dist/admitted-workspace.context.impl.consumer.js.map +1 -0
- package/dist/cli/admission-read.d.ts +12 -0
- package/dist/cli/admission-read.d.ts.map +1 -0
- package/dist/cli/admission-read.js +42 -0
- package/dist/cli/admission-read.js.map +1 -0
- package/dist/cli/command-input.d.ts +37 -0
- package/dist/cli/command-input.d.ts.map +1 -0
- package/dist/cli/command-input.js +34 -0
- package/dist/cli/command-input.js.map +1 -0
- package/dist/cli/consumer-components/startup-progress.d.ts +107 -0
- package/dist/cli/consumer-components/startup-progress.d.ts.map +1 -0
- package/dist/cli/consumer-components/startup-progress.js +392 -0
- package/dist/cli/consumer-components/startup-progress.js.map +1 -0
- package/dist/cli/consumer-services/control.d.ts +147 -0
- package/dist/cli/consumer-services/control.d.ts.map +1 -0
- package/dist/cli/consumer-services/control.js +209 -0
- package/dist/cli/consumer-services/control.js.map +1 -0
- package/dist/cli/daemon-launch-child.d.ts +35 -0
- package/dist/cli/daemon-launch-child.d.ts.map +1 -0
- package/dist/cli/daemon-launch-child.js +25 -0
- package/dist/cli/daemon-launch-child.js.map +1 -0
- package/dist/cli/docs/pm.cli.docs.descriptor.d.ts +4 -0
- package/dist/cli/docs/pm.cli.docs.descriptor.d.ts.map +1 -0
- package/dist/cli/docs/pm.cli.docs.descriptor.js +93 -0
- package/dist/cli/docs/pm.cli.docs.descriptor.js.map +1 -0
- package/dist/cli/filter-process-states.d.ts +12 -0
- package/dist/cli/filter-process-states.d.ts.map +1 -0
- package/dist/cli/filter-process-states.js +12 -0
- package/dist/cli/filter-process-states.js.map +1 -0
- package/dist/cli/output.d.ts +21 -0
- package/dist/cli/output.d.ts.map +1 -0
- package/dist/cli/output.js +19 -0
- package/dist/cli/output.js.map +1 -0
- package/dist/cli/plugin.d.ts +3 -0
- package/dist/cli/plugin.d.ts.map +1 -0
- package/dist/cli/plugin.js +12 -0
- package/dist/cli/plugin.js.map +1 -0
- package/dist/cli/pm.cli-group.descriptor.d.ts +10 -0
- package/dist/cli/pm.cli-group.descriptor.d.ts.map +1 -0
- package/dist/cli/pm.cli-group.descriptor.js +18 -0
- package/dist/cli/pm.cli-group.descriptor.js.map +1 -0
- package/dist/cli/pm.completion.cli-group.descriptor.d.ts +9 -0
- package/dist/cli/pm.completion.cli-group.descriptor.d.ts.map +1 -0
- package/dist/cli/pm.completion.cli-group.descriptor.js +17 -0
- package/dist/cli/pm.completion.cli-group.descriptor.js.map +1 -0
- package/dist/cli/pm.completion.install.descriptor.d.ts +9 -0
- package/dist/cli/pm.completion.install.descriptor.d.ts.map +1 -0
- package/dist/cli/pm.completion.install.descriptor.js +24 -0
- package/dist/cli/pm.completion.install.descriptor.js.map +1 -0
- package/dist/cli/pm.completion.install.impl.d.ts +11 -0
- package/dist/cli/pm.completion.install.impl.d.ts.map +1 -0
- package/dist/cli/pm.completion.install.impl.js +207 -0
- package/dist/cli/pm.completion.install.impl.js.map +1 -0
- package/dist/cli/pm.config.cli.descriptor.d.ts +10 -0
- package/dist/cli/pm.config.cli.descriptor.d.ts.map +1 -0
- package/dist/cli/pm.config.cli.descriptor.js +25 -0
- package/dist/cli/pm.config.cli.descriptor.js.map +1 -0
- package/dist/cli/pm.config.impl.d.ts +12 -0
- package/dist/cli/pm.config.impl.d.ts.map +1 -0
- package/dist/cli/pm.config.impl.js +117 -0
- package/dist/cli/pm.config.impl.js.map +1 -0
- package/dist/cli/pm.daemon.cli-group.descriptor.d.ts +9 -0
- package/dist/cli/pm.daemon.cli-group.descriptor.d.ts.map +1 -0
- package/dist/cli/pm.daemon.cli-group.descriptor.js +17 -0
- package/dist/cli/pm.daemon.cli-group.descriptor.js.map +1 -0
- package/dist/cli/pm.daemon.logs.descriptor.d.ts +9 -0
- package/dist/cli/pm.daemon.logs.descriptor.d.ts.map +1 -0
- package/dist/cli/pm.daemon.logs.descriptor.js +29 -0
- package/dist/cli/pm.daemon.logs.descriptor.js.map +1 -0
- package/dist/cli/pm.daemon.logs.impl.d.ts +11 -0
- package/dist/cli/pm.daemon.logs.impl.d.ts.map +1 -0
- package/dist/cli/pm.daemon.logs.impl.js +53 -0
- package/dist/cli/pm.daemon.logs.impl.js.map +1 -0
- package/dist/cli/pm.daemon.reconcile.descriptor.d.ts +9 -0
- package/dist/cli/pm.daemon.reconcile.descriptor.d.ts.map +1 -0
- package/dist/cli/pm.daemon.reconcile.descriptor.js +24 -0
- package/dist/cli/pm.daemon.reconcile.descriptor.js.map +1 -0
- package/dist/cli/pm.daemon.reconcile.impl.d.ts +16 -0
- package/dist/cli/pm.daemon.reconcile.impl.d.ts.map +1 -0
- package/dist/cli/pm.daemon.reconcile.impl.js +51 -0
- package/dist/cli/pm.daemon.reconcile.impl.js.map +1 -0
- package/dist/cli/pm.daemon.recover.descriptor.d.ts +9 -0
- package/dist/cli/pm.daemon.recover.descriptor.d.ts.map +1 -0
- package/dist/cli/pm.daemon.recover.descriptor.js +24 -0
- package/dist/cli/pm.daemon.recover.descriptor.js.map +1 -0
- package/dist/cli/pm.daemon.recover.impl.d.ts +16 -0
- package/dist/cli/pm.daemon.recover.impl.d.ts.map +1 -0
- package/dist/cli/pm.daemon.recover.impl.js +66 -0
- package/dist/cli/pm.daemon.recover.impl.js.map +1 -0
- package/dist/cli/pm.daemon.restart.descriptor.d.ts +9 -0
- package/dist/cli/pm.daemon.restart.descriptor.d.ts.map +1 -0
- package/dist/cli/pm.daemon.restart.descriptor.js +25 -0
- package/dist/cli/pm.daemon.restart.descriptor.js.map +1 -0
- package/dist/cli/pm.daemon.restart.impl.d.ts +28 -0
- package/dist/cli/pm.daemon.restart.impl.d.ts.map +1 -0
- package/dist/cli/pm.daemon.restart.impl.js +174 -0
- package/dist/cli/pm.daemon.restart.impl.js.map +1 -0
- package/dist/cli/pm.daemon.serve.descriptor.d.ts +10 -0
- package/dist/cli/pm.daemon.serve.descriptor.d.ts.map +1 -0
- package/dist/cli/pm.daemon.serve.descriptor.js +28 -0
- package/dist/cli/pm.daemon.serve.descriptor.js.map +1 -0
- package/dist/cli/pm.daemon.serve.impl.d.ts +37 -0
- package/dist/cli/pm.daemon.serve.impl.d.ts.map +1 -0
- package/dist/cli/pm.daemon.serve.impl.js +257 -0
- package/dist/cli/pm.daemon.serve.impl.js.map +1 -0
- package/dist/cli/pm.daemon.start.descriptor.d.ts +9 -0
- package/dist/cli/pm.daemon.start.descriptor.d.ts.map +1 -0
- package/dist/cli/pm.daemon.start.descriptor.js +28 -0
- package/dist/cli/pm.daemon.start.descriptor.js.map +1 -0
- package/dist/cli/pm.daemon.start.impl.d.ts +40 -0
- package/dist/cli/pm.daemon.start.impl.d.ts.map +1 -0
- package/dist/cli/pm.daemon.start.impl.js +341 -0
- package/dist/cli/pm.daemon.start.impl.js.map +1 -0
- package/dist/cli/pm.daemon.status.descriptor.d.ts +9 -0
- package/dist/cli/pm.daemon.status.descriptor.d.ts.map +1 -0
- package/dist/cli/pm.daemon.status.descriptor.js +24 -0
- package/dist/cli/pm.daemon.status.descriptor.js.map +1 -0
- package/dist/cli/pm.daemon.status.impl.d.ts +11 -0
- package/dist/cli/pm.daemon.status.impl.d.ts.map +1 -0
- package/dist/cli/pm.daemon.status.impl.js +123 -0
- package/dist/cli/pm.daemon.status.impl.js.map +1 -0
- package/dist/cli/pm.daemon.stop.descriptor.d.ts +9 -0
- package/dist/cli/pm.daemon.stop.descriptor.d.ts.map +1 -0
- package/dist/cli/pm.daemon.stop.descriptor.js +24 -0
- package/dist/cli/pm.daemon.stop.descriptor.js.map +1 -0
- package/dist/cli/pm.daemon.stop.impl.d.ts +21 -0
- package/dist/cli/pm.daemon.stop.impl.d.ts.map +1 -0
- package/dist/cli/pm.daemon.stop.impl.js +108 -0
- package/dist/cli/pm.daemon.stop.impl.js.map +1 -0
- package/dist/cli/pm.dashboard.descriptor.d.ts +10 -0
- package/dist/cli/pm.dashboard.descriptor.d.ts.map +1 -0
- package/dist/cli/pm.dashboard.descriptor.js +30 -0
- package/dist/cli/pm.dashboard.descriptor.js.map +1 -0
- package/dist/cli/pm.dashboard.impl.d.ts +16 -0
- package/dist/cli/pm.dashboard.impl.d.ts.map +1 -0
- package/dist/cli/pm.dashboard.impl.js +134 -0
- package/dist/cli/pm.dashboard.impl.js.map +1 -0
- package/dist/cli/pm.init.descriptor.d.ts +9 -0
- package/dist/cli/pm.init.descriptor.d.ts.map +1 -0
- package/dist/cli/pm.init.descriptor.js +28 -0
- package/dist/cli/pm.init.descriptor.js.map +1 -0
- package/dist/cli/pm.init.impl.d.ts +11 -0
- package/dist/cli/pm.init.impl.d.ts.map +1 -0
- package/dist/cli/pm.init.impl.js +112 -0
- package/dist/cli/pm.init.impl.js.map +1 -0
- package/dist/cli/pm.list.descriptor.d.ts +9 -0
- package/dist/cli/pm.list.descriptor.d.ts.map +1 -0
- package/dist/cli/pm.list.descriptor.js +44 -0
- package/dist/cli/pm.list.descriptor.js.map +1 -0
- package/dist/cli/pm.list.impl.d.ts +24 -0
- package/dist/cli/pm.list.impl.d.ts.map +1 -0
- package/dist/cli/pm.list.impl.js +204 -0
- package/dist/cli/pm.list.impl.js.map +1 -0
- package/dist/cli/pm.liveness.cli-group.descriptor.d.ts +25 -0
- package/dist/cli/pm.liveness.cli-group.descriptor.d.ts.map +1 -0
- package/dist/cli/pm.liveness.cli-group.descriptor.js +33 -0
- package/dist/cli/pm.liveness.cli-group.descriptor.js.map +1 -0
- package/dist/cli/pm.liveness.set.descriptor.d.ts +18 -0
- package/dist/cli/pm.liveness.set.descriptor.d.ts.map +1 -0
- package/dist/cli/pm.liveness.set.descriptor.js +65 -0
- package/dist/cli/pm.liveness.set.descriptor.js.map +1 -0
- package/dist/cli/pm.liveness.set.impl.d.ts +6 -0
- package/dist/cli/pm.liveness.set.impl.d.ts.map +1 -0
- package/dist/cli/pm.liveness.set.impl.js +61 -0
- package/dist/cli/pm.liveness.set.impl.js.map +1 -0
- package/dist/cli/pm.logs.descriptor.d.ts +9 -0
- package/dist/cli/pm.logs.descriptor.d.ts.map +1 -0
- package/dist/cli/pm.logs.descriptor.js +39 -0
- package/dist/cli/pm.logs.descriptor.js.map +1 -0
- package/dist/cli/pm.logs.impl.d.ts +11 -0
- package/dist/cli/pm.logs.impl.d.ts.map +1 -0
- package/dist/cli/pm.logs.impl.js +208 -0
- package/dist/cli/pm.logs.impl.js.map +1 -0
- package/dist/cli/pm.preset.cli-group.descriptor.d.ts +9 -0
- package/dist/cli/pm.preset.cli-group.descriptor.d.ts.map +1 -0
- package/dist/cli/pm.preset.cli-group.descriptor.js +17 -0
- package/dist/cli/pm.preset.cli-group.descriptor.js.map +1 -0
- package/dist/cli/pm.preset.list.descriptor.d.ts +9 -0
- package/dist/cli/pm.preset.list.descriptor.d.ts.map +1 -0
- package/dist/cli/pm.preset.list.descriptor.js +24 -0
- package/dist/cli/pm.preset.list.descriptor.js.map +1 -0
- package/dist/cli/pm.preset.list.impl.d.ts +6 -0
- package/dist/cli/pm.preset.list.impl.d.ts.map +1 -0
- package/dist/cli/pm.preset.list.impl.js +67 -0
- package/dist/cli/pm.preset.list.impl.js.map +1 -0
- package/dist/cli/pm.preset.restart.descriptor.d.ts +9 -0
- package/dist/cli/pm.preset.restart.descriptor.d.ts.map +1 -0
- package/dist/cli/pm.preset.restart.descriptor.js +39 -0
- package/dist/cli/pm.preset.restart.descriptor.js.map +1 -0
- package/dist/cli/pm.preset.restart.impl.d.ts +11 -0
- package/dist/cli/pm.preset.restart.impl.d.ts.map +1 -0
- package/dist/cli/pm.preset.restart.impl.js +85 -0
- package/dist/cli/pm.preset.restart.impl.js.map +1 -0
- package/dist/cli/pm.preset.show.descriptor.d.ts +9 -0
- package/dist/cli/pm.preset.show.descriptor.d.ts.map +1 -0
- package/dist/cli/pm.preset.show.descriptor.js +30 -0
- package/dist/cli/pm.preset.show.descriptor.js.map +1 -0
- package/dist/cli/pm.preset.show.impl.d.ts +6 -0
- package/dist/cli/pm.preset.show.impl.d.ts.map +1 -0
- package/dist/cli/pm.preset.show.impl.js +92 -0
- package/dist/cli/pm.preset.show.impl.js.map +1 -0
- package/dist/cli/pm.preset.start.descriptor.d.ts +9 -0
- package/dist/cli/pm.preset.start.descriptor.d.ts.map +1 -0
- package/dist/cli/pm.preset.start.descriptor.js +39 -0
- package/dist/cli/pm.preset.start.descriptor.js.map +1 -0
- package/dist/cli/pm.preset.start.impl.d.ts +11 -0
- package/dist/cli/pm.preset.start.impl.d.ts.map +1 -0
- package/dist/cli/pm.preset.start.impl.js +88 -0
- package/dist/cli/pm.preset.start.impl.js.map +1 -0
- package/dist/cli/pm.preset.status.descriptor.d.ts +9 -0
- package/dist/cli/pm.preset.status.descriptor.d.ts.map +1 -0
- package/dist/cli/pm.preset.status.descriptor.js +30 -0
- package/dist/cli/pm.preset.status.descriptor.js.map +1 -0
- package/dist/cli/pm.preset.status.impl.d.ts +11 -0
- package/dist/cli/pm.preset.status.impl.d.ts.map +1 -0
- package/dist/cli/pm.preset.status.impl.js +166 -0
- package/dist/cli/pm.preset.status.impl.js.map +1 -0
- package/dist/cli/pm.preset.stop.descriptor.d.ts +9 -0
- package/dist/cli/pm.preset.stop.descriptor.d.ts.map +1 -0
- package/dist/cli/pm.preset.stop.descriptor.js +39 -0
- package/dist/cli/pm.preset.stop.descriptor.js.map +1 -0
- package/dist/cli/pm.preset.stop.impl.d.ts +11 -0
- package/dist/cli/pm.preset.stop.impl.d.ts.map +1 -0
- package/dist/cli/pm.preset.stop.impl.js +68 -0
- package/dist/cli/pm.preset.stop.impl.js.map +1 -0
- package/dist/cli/pm.preset.teardown.descriptor.d.ts +9 -0
- package/dist/cli/pm.preset.teardown.descriptor.d.ts.map +1 -0
- package/dist/cli/pm.preset.teardown.descriptor.js +43 -0
- package/dist/cli/pm.preset.teardown.descriptor.js.map +1 -0
- package/dist/cli/pm.preset.teardown.impl.d.ts +12 -0
- package/dist/cli/pm.preset.teardown.impl.d.ts.map +1 -0
- package/dist/cli/pm.preset.teardown.impl.js +91 -0
- package/dist/cli/pm.preset.teardown.impl.js.map +1 -0
- package/dist/cli/pm.presets.descriptor.d.ts +9 -0
- package/dist/cli/pm.presets.descriptor.d.ts.map +1 -0
- package/dist/cli/pm.presets.descriptor.js +24 -0
- package/dist/cli/pm.presets.descriptor.js.map +1 -0
- package/dist/cli/pm.presets.impl.d.ts +11 -0
- package/dist/cli/pm.presets.impl.d.ts.map +1 -0
- package/dist/cli/pm.presets.impl.js +13 -0
- package/dist/cli/pm.presets.impl.js.map +1 -0
- package/dist/cli/pm.register.descriptor.d.ts +11 -0
- package/dist/cli/pm.register.descriptor.d.ts.map +1 -0
- package/dist/cli/pm.register.descriptor.js +32 -0
- package/dist/cli/pm.register.descriptor.js.map +1 -0
- package/dist/cli/pm.register.impl.d.ts +15 -0
- package/dist/cli/pm.register.impl.d.ts.map +1 -0
- package/dist/cli/pm.register.impl.js +81 -0
- package/dist/cli/pm.register.impl.js.map +1 -0
- package/dist/cli/pm.resource.apply.descriptor.d.ts +15 -0
- package/dist/cli/pm.resource.apply.descriptor.d.ts.map +1 -0
- package/dist/cli/pm.resource.apply.descriptor.js +41 -0
- package/dist/cli/pm.resource.apply.descriptor.js.map +1 -0
- package/dist/cli/pm.resource.apply.impl.d.ts +14 -0
- package/dist/cli/pm.resource.apply.impl.d.ts.map +1 -0
- package/dist/cli/pm.resource.apply.impl.js +91 -0
- package/dist/cli/pm.resource.apply.impl.js.map +1 -0
- package/dist/cli/pm.resource.cli-group.descriptor.d.ts +9 -0
- package/dist/cli/pm.resource.cli-group.descriptor.d.ts.map +1 -0
- package/dist/cli/pm.resource.cli-group.descriptor.js +17 -0
- package/dist/cli/pm.resource.cli-group.descriptor.js.map +1 -0
- package/dist/cli/pm.resource.list.descriptor.d.ts +9 -0
- package/dist/cli/pm.resource.list.descriptor.d.ts.map +1 -0
- package/dist/cli/pm.resource.list.descriptor.js +25 -0
- package/dist/cli/pm.resource.list.descriptor.js.map +1 -0
- package/dist/cli/pm.resource.list.impl.d.ts +11 -0
- package/dist/cli/pm.resource.list.impl.d.ts.map +1 -0
- package/dist/cli/pm.resource.list.impl.js +141 -0
- package/dist/cli/pm.resource.list.impl.js.map +1 -0
- package/dist/cli/pm.resource.recreate.descriptor.d.ts +4 -0
- package/dist/cli/pm.resource.recreate.descriptor.d.ts.map +1 -0
- package/dist/cli/pm.resource.recreate.descriptor.js +29 -0
- package/dist/cli/pm.resource.recreate.descriptor.js.map +1 -0
- package/dist/cli/pm.resource.recreate.impl.d.ts +6 -0
- package/dist/cli/pm.resource.recreate.impl.d.ts.map +1 -0
- package/dist/cli/pm.resource.recreate.impl.js +123 -0
- package/dist/cli/pm.resource.recreate.impl.js.map +1 -0
- package/dist/cli/pm.resource.status.descriptor.d.ts +9 -0
- package/dist/cli/pm.resource.status.descriptor.d.ts.map +1 -0
- package/dist/cli/pm.resource.status.descriptor.js +31 -0
- package/dist/cli/pm.resource.status.descriptor.js.map +1 -0
- package/dist/cli/pm.resource.status.impl.d.ts +11 -0
- package/dist/cli/pm.resource.status.impl.d.ts.map +1 -0
- package/dist/cli/pm.resource.status.impl.js +230 -0
- package/dist/cli/pm.resource.status.impl.js.map +1 -0
- package/dist/cli/pm.restart.descriptor.d.ts +9 -0
- package/dist/cli/pm.restart.descriptor.d.ts.map +1 -0
- package/dist/cli/pm.restart.descriptor.js +40 -0
- package/dist/cli/pm.restart.descriptor.js.map +1 -0
- package/dist/cli/pm.restart.impl.d.ts +12 -0
- package/dist/cli/pm.restart.impl.d.ts.map +1 -0
- package/dist/cli/pm.restart.impl.js +109 -0
- package/dist/cli/pm.restart.impl.js.map +1 -0
- package/dist/cli/pm.show.descriptor.d.ts +9 -0
- package/dist/cli/pm.show.descriptor.d.ts.map +1 -0
- package/dist/cli/pm.show.descriptor.js +30 -0
- package/dist/cli/pm.show.descriptor.js.map +1 -0
- package/dist/cli/pm.show.impl.d.ts +25 -0
- package/dist/cli/pm.show.impl.d.ts.map +1 -0
- package/dist/cli/pm.show.impl.js +175 -0
- package/dist/cli/pm.show.impl.js.map +1 -0
- package/dist/cli/pm.start-all.descriptor.d.ts +9 -0
- package/dist/cli/pm.start-all.descriptor.d.ts.map +1 -0
- package/dist/cli/pm.start-all.descriptor.js +34 -0
- package/dist/cli/pm.start-all.descriptor.js.map +1 -0
- package/dist/cli/pm.start-all.impl.d.ts +12 -0
- package/dist/cli/pm.start-all.impl.d.ts.map +1 -0
- package/dist/cli/pm.start-all.impl.js +91 -0
- package/dist/cli/pm.start-all.impl.js.map +1 -0
- package/dist/cli/pm.start.descriptor.d.ts +9 -0
- package/dist/cli/pm.start.descriptor.d.ts.map +1 -0
- package/dist/cli/pm.start.descriptor.js +40 -0
- package/dist/cli/pm.start.descriptor.js.map +1 -0
- package/dist/cli/pm.start.impl.d.ts +19 -0
- package/dist/cli/pm.start.impl.d.ts.map +1 -0
- package/dist/cli/pm.start.impl.js +170 -0
- package/dist/cli/pm.start.impl.js.map +1 -0
- package/dist/cli/pm.status.descriptor.d.ts +10 -0
- package/dist/cli/pm.status.descriptor.d.ts.map +1 -0
- package/dist/cli/pm.status.descriptor.js +31 -0
- package/dist/cli/pm.status.descriptor.js.map +1 -0
- package/dist/cli/pm.status.impl.d.ts +96 -0
- package/dist/cli/pm.status.impl.d.ts.map +1 -0
- package/dist/cli/pm.status.impl.js +425 -0
- package/dist/cli/pm.status.impl.js.map +1 -0
- package/dist/cli/pm.stop-all.descriptor.d.ts +9 -0
- package/dist/cli/pm.stop-all.descriptor.d.ts.map +1 -0
- package/dist/cli/pm.stop-all.descriptor.js +41 -0
- package/dist/cli/pm.stop-all.descriptor.js.map +1 -0
- package/dist/cli/pm.stop-all.impl.d.ts +14 -0
- package/dist/cli/pm.stop-all.impl.d.ts.map +1 -0
- package/dist/cli/pm.stop-all.impl.js +138 -0
- package/dist/cli/pm.stop-all.impl.js.map +1 -0
- package/dist/cli/pm.stop.descriptor.d.ts +9 -0
- package/dist/cli/pm.stop.descriptor.d.ts.map +1 -0
- package/dist/cli/pm.stop.descriptor.js +40 -0
- package/dist/cli/pm.stop.descriptor.js.map +1 -0
- package/dist/cli/pm.stop.impl.d.ts +13 -0
- package/dist/cli/pm.stop.impl.d.ts.map +1 -0
- package/dist/cli/pm.stop.impl.js +120 -0
- package/dist/cli/pm.stop.impl.js.map +1 -0
- package/dist/cli/pm.unregister-all.descriptor.d.ts +9 -0
- package/dist/cli/pm.unregister-all.descriptor.d.ts.map +1 -0
- package/dist/cli/pm.unregister-all.descriptor.js +28 -0
- package/dist/cli/pm.unregister-all.descriptor.js.map +1 -0
- package/dist/cli/pm.unregister-all.impl.d.ts +11 -0
- package/dist/cli/pm.unregister-all.impl.d.ts.map +1 -0
- package/dist/cli/pm.unregister-all.impl.js +106 -0
- package/dist/cli/pm.unregister-all.impl.js.map +1 -0
- package/dist/cli/pm.unregister.descriptor.d.ts +9 -0
- package/dist/cli/pm.unregister.descriptor.d.ts.map +1 -0
- package/dist/cli/pm.unregister.descriptor.js +34 -0
- package/dist/cli/pm.unregister.descriptor.js.map +1 -0
- package/dist/cli/pm.unregister.impl.d.ts +11 -0
- package/dist/cli/pm.unregister.impl.d.ts.map +1 -0
- package/dist/cli/pm.unregister.impl.js +77 -0
- package/dist/cli/pm.unregister.impl.js.map +1 -0
- package/dist/cli/pm.validate.descriptor.d.ts +9 -0
- package/dist/cli/pm.validate.descriptor.d.ts.map +1 -0
- package/dist/cli/pm.validate.descriptor.js +24 -0
- package/dist/cli/pm.validate.descriptor.js.map +1 -0
- package/dist/cli/pm.validate.impl.d.ts +6 -0
- package/dist/cli/pm.validate.impl.d.ts.map +1 -0
- package/dist/cli/pm.validate.impl.js +235 -0
- package/dist/cli/pm.validate.impl.js.map +1 -0
- package/dist/cli/preset-execution-options.d.ts +8 -0
- package/dist/cli/preset-execution-options.d.ts.map +1 -0
- package/dist/cli/preset-execution-options.js +22 -0
- package/dist/cli/preset-execution-options.js.map +1 -0
- package/dist/cli/register-manifest.d.ts +23 -0
- package/dist/cli/register-manifest.d.ts.map +1 -0
- package/dist/cli/register-manifest.js +80 -0
- package/dist/cli/register-manifest.js.map +1 -0
- package/dist/cli/runtime.d.ts +3 -0
- package/dist/cli/runtime.d.ts.map +1 -0
- package/dist/cli/runtime.js +134 -0
- package/dist/cli/runtime.js.map +1 -0
- package/dist/cli/table-columns.d.ts +22 -0
- package/dist/cli/table-columns.d.ts.map +1 -0
- package/dist/cli/table-columns.js +61 -0
- package/dist/cli/table-columns.js.map +1 -0
- package/dist/client-replies.d.ts +1188 -0
- package/dist/client-replies.d.ts.map +1 -0
- package/dist/client-replies.js +145 -0
- package/dist/client-replies.js.map +1 -0
- package/dist/client.d.ts +345 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +1005 -0
- package/dist/client.js.map +1 -0
- package/dist/config/pm.config.config.descriptor.d.ts +10 -0
- package/dist/config/pm.config.config.descriptor.d.ts.map +1 -0
- package/dist/config/pm.config.config.descriptor.js +37 -0
- package/dist/config/pm.config.config.descriptor.js.map +1 -0
- package/dist/context.d.ts +121 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +6 -0
- package/dist/context.js.map +1 -0
- package/dist/daemon/command-handler.d.ts +74 -0
- package/dist/daemon/command-handler.d.ts.map +1 -0
- package/dist/daemon/command-handler.js +220 -0
- package/dist/daemon/command-handler.js.map +1 -0
- package/dist/daemon/command-ids.d.ts +10 -0
- package/dist/daemon/command-ids.d.ts.map +1 -0
- package/dist/daemon/command-ids.js +51 -0
- package/dist/daemon/command-ids.js.map +1 -0
- package/dist/daemon/command-implementations.d.ts +30 -0
- package/dist/daemon/command-implementations.d.ts.map +1 -0
- package/dist/daemon/command-implementations.js +340 -0
- package/dist/daemon/command-implementations.js.map +1 -0
- package/dist/daemon/command-payload.d.ts +803 -0
- package/dist/daemon/command-payload.d.ts.map +1 -0
- package/dist/daemon/command-payload.js +128 -0
- package/dist/daemon/command-payload.js.map +1 -0
- package/dist/daemon/commands.plugin.d.ts +6 -0
- package/dist/daemon/commands.plugin.d.ts.map +1 -0
- package/dist/daemon/commands.plugin.js +22 -0
- package/dist/daemon/commands.plugin.js.map +1 -0
- package/dist/daemon/config-watcher.d.ts +125 -0
- package/dist/daemon/config-watcher.d.ts.map +1 -0
- package/dist/daemon/config-watcher.js +541 -0
- package/dist/daemon/config-watcher.js.map +1 -0
- package/dist/daemon/daemon-module-context.d.ts +16 -0
- package/dist/daemon/daemon-module-context.d.ts.map +1 -0
- package/dist/daemon/daemon-module-context.js +25 -0
- package/dist/daemon/daemon-module-context.js.map +1 -0
- package/dist/daemon/declared-commands.d.ts +39 -0
- package/dist/daemon/declared-commands.d.ts.map +1 -0
- package/dist/daemon/declared-commands.js +200 -0
- package/dist/daemon/declared-commands.js.map +1 -0
- package/dist/daemon/executable-freshness-reconciler.d.ts +99 -0
- package/dist/daemon/executable-freshness-reconciler.d.ts.map +1 -0
- package/dist/daemon/executable-freshness-reconciler.js +396 -0
- package/dist/daemon/executable-freshness-reconciler.js.map +1 -0
- package/dist/daemon/fleet-attach-state.d.ts +22 -0
- package/dist/daemon/fleet-attach-state.d.ts.map +1 -0
- package/dist/daemon/fleet-attach-state.js +39 -0
- package/dist/daemon/fleet-attach-state.js.map +1 -0
- package/dist/daemon/health-monitor.d.ts +105 -0
- package/dist/daemon/health-monitor.d.ts.map +1 -0
- package/dist/daemon/health-monitor.js +453 -0
- package/dist/daemon/health-monitor.js.map +1 -0
- package/dist/daemon/liveness-checker.d.ts +49 -0
- package/dist/daemon/liveness-checker.d.ts.map +1 -0
- package/dist/daemon/liveness-checker.js +330 -0
- package/dist/daemon/liveness-checker.js.map +1 -0
- package/dist/daemon/orphan-scanner.d.ts +114 -0
- package/dist/daemon/orphan-scanner.d.ts.map +1 -0
- package/dist/daemon/orphan-scanner.js +684 -0
- package/dist/daemon/orphan-scanner.js.map +1 -0
- package/dist/daemon/resource-health-monitor.d.ts +65 -0
- package/dist/daemon/resource-health-monitor.d.ts.map +1 -0
- package/dist/daemon/resource-health-monitor.js +247 -0
- package/dist/daemon/resource-health-monitor.js.map +1 -0
- package/dist/daemon/role.context.impl.d.ts +13 -0
- package/dist/daemon/role.context.impl.d.ts.map +1 -0
- package/dist/daemon/role.context.impl.js +7 -0
- package/dist/daemon/role.context.impl.js.map +1 -0
- package/dist/daemon/role.d.ts +56 -0
- package/dist/daemon/role.d.ts.map +1 -0
- package/dist/daemon/role.js +18 -0
- package/dist/daemon/role.js.map +1 -0
- package/dist/daemon/rpc-result.d.ts +9 -0
- package/dist/daemon/rpc-result.d.ts.map +1 -0
- package/dist/daemon/rpc-result.js +28 -0
- package/dist/daemon/rpc-result.js.map +1 -0
- package/dist/daemon/stray-daemons.d.ts +52 -0
- package/dist/daemon/stray-daemons.d.ts.map +1 -0
- package/dist/daemon/stray-daemons.js +101 -0
- package/dist/daemon/stray-daemons.js.map +1 -0
- package/dist/daemon/supervised-commands.d.ts +3 -0
- package/dist/daemon/supervised-commands.d.ts.map +1 -0
- package/dist/daemon/supervised-commands.js +51 -0
- package/dist/daemon/supervised-commands.js.map +1 -0
- package/dist/daemon.d.ts +329 -0
- package/dist/daemon.d.ts.map +1 -0
- package/dist/daemon.js +1654 -0
- package/dist/daemon.js.map +1 -0
- package/dist/definitions.d.ts +2 -0
- package/dist/definitions.d.ts.map +1 -0
- package/dist/definitions.js +2 -0
- package/dist/definitions.js.map +1 -0
- package/dist/dev/command.d.ts +39 -0
- package/dist/dev/command.d.ts.map +1 -0
- package/dist/dev/command.js +79 -0
- package/dist/dev/command.js.map +1 -0
- package/dist/dev/defaults.d.ts +34 -0
- package/dist/dev/defaults.d.ts.map +1 -0
- package/dist/dev/defaults.js +58 -0
- package/dist/dev/defaults.js.map +1 -0
- package/dist/dev/env.d.ts +31 -0
- package/dist/dev/env.d.ts.map +1 -0
- package/dist/dev/env.js +56 -0
- package/dist/dev/env.js.map +1 -0
- package/dist/dev/index.d.ts +26 -0
- package/dist/dev/index.d.ts.map +1 -0
- package/dist/dev/index.js +28 -0
- package/dist/dev/index.js.map +1 -0
- package/dist/dev/sveltekit.d.ts +41 -0
- package/dist/dev/sveltekit.d.ts.map +1 -0
- package/dist/dev/sveltekit.js +93 -0
- package/dist/dev/sveltekit.js.map +1 -0
- package/dist/dev/workspace-shape.d.ts +64 -0
- package/dist/dev/workspace-shape.d.ts.map +1 -0
- package/dist/dev/workspace-shape.js +19 -0
- package/dist/dev/workspace-shape.js.map +1 -0
- package/dist/docs/pm.daemon.docs.descriptor.d.ts +4 -0
- package/dist/docs/pm.daemon.docs.descriptor.d.ts.map +1 -0
- package/dist/docs/pm.daemon.docs.descriptor.js +48 -0
- package/dist/docs/pm.daemon.docs.descriptor.js.map +1 -0
- package/dist/docs/pm.docs.descriptor.d.ts +4 -0
- package/dist/docs/pm.docs.descriptor.d.ts.map +1 -0
- package/dist/docs/pm.docs.descriptor.js +45 -0
- package/dist/docs/pm.docs.descriptor.js.map +1 -0
- package/dist/docs/pm.preset.docs.descriptor.d.ts +4 -0
- package/dist/docs/pm.preset.docs.descriptor.d.ts.map +1 -0
- package/dist/docs/pm.preset.docs.descriptor.js +37 -0
- package/dist/docs/pm.preset.docs.descriptor.js.map +1 -0
- package/dist/docs/pm.queues.docs.descriptor.d.ts +4 -0
- package/dist/docs/pm.queues.docs.descriptor.d.ts.map +1 -0
- package/dist/docs/pm.queues.docs.descriptor.js +157 -0
- package/dist/docs/pm.queues.docs.descriptor.js.map +1 -0
- package/dist/docs/pm.resource.docs.descriptor.d.ts +4 -0
- package/dist/docs/pm.resource.docs.descriptor.d.ts.map +1 -0
- package/dist/docs/pm.resource.docs.descriptor.js +38 -0
- package/dist/docs/pm.resource.docs.descriptor.js.map +1 -0
- package/dist/docs/pm.tasks.docs.descriptor.d.ts +4 -0
- package/dist/docs/pm.tasks.docs.descriptor.d.ts.map +1 -0
- package/dist/docs/pm.tasks.docs.descriptor.js +242 -0
- package/dist/docs/pm.tasks.docs.descriptor.js.map +1 -0
- package/dist/docs/pm.workers.docs.descriptor.d.ts +4 -0
- package/dist/docs/pm.workers.docs.descriptor.d.ts.map +1 -0
- package/dist/docs/pm.workers.docs.descriptor.js +427 -0
- package/dist/docs/pm.workers.docs.descriptor.js.map +1 -0
- package/dist/errors.d.ts +262 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +479 -0
- package/dist/errors.js.map +1 -0
- package/dist/graph.d.ts +82 -0
- package/dist/graph.d.ts.map +1 -0
- package/dist/graph.js +247 -0
- package/dist/graph.js.map +1 -0
- package/dist/helpers/failure.d.ts +10 -0
- package/dist/helpers/failure.d.ts.map +1 -0
- package/dist/helpers/failure.js +10 -0
- package/dist/helpers/failure.js.map +1 -0
- package/dist/helpers/launch-custody.d.ts +16 -0
- package/dist/helpers/launch-custody.d.ts.map +1 -0
- package/dist/helpers/launch-custody.js +117 -0
- package/dist/helpers/launch-custody.js.map +1 -0
- package/dist/helpers/launch-identity.d.ts +20 -0
- package/dist/helpers/launch-identity.d.ts.map +1 -0
- package/dist/helpers/launch-identity.js +70 -0
- package/dist/helpers/launch-identity.js.map +1 -0
- package/dist/helpers/managed-http-origin.d.ts +4 -0
- package/dist/helpers/managed-http-origin.d.ts.map +1 -0
- package/dist/helpers/managed-http-origin.js +9 -0
- package/dist/helpers/managed-http-origin.js.map +1 -0
- package/dist/helpers/managed-process-admission.d.ts +55 -0
- package/dist/helpers/managed-process-admission.d.ts.map +1 -0
- package/dist/helpers/managed-process-admission.js +102 -0
- package/dist/helpers/managed-process-admission.js.map +1 -0
- package/dist/helpers/managed-process-id.d.ts +13 -0
- package/dist/helpers/managed-process-id.d.ts.map +1 -0
- package/dist/helpers/managed-process-id.js +16 -0
- package/dist/helpers/managed-process-id.js.map +1 -0
- package/dist/helpers/node-path.d.ts +16 -0
- package/dist/helpers/node-path.d.ts.map +1 -0
- package/dist/helpers/node-path.js +67 -0
- package/dist/helpers/node-path.js.map +1 -0
- package/dist/helpers/output-redaction.d.ts +36 -0
- package/dist/helpers/output-redaction.d.ts.map +1 -0
- package/dist/helpers/output-redaction.js +120 -0
- package/dist/helpers/output-redaction.js.map +1 -0
- package/dist/helpers/process-credentials.d.ts +62 -0
- package/dist/helpers/process-credentials.d.ts.map +1 -0
- package/dist/helpers/process-credentials.js +107 -0
- package/dist/helpers/process-credentials.js.map +1 -0
- package/dist/helpers/process-env.d.ts +72 -0
- package/dist/helpers/process-env.d.ts.map +1 -0
- package/dist/helpers/process-env.js +265 -0
- package/dist/helpers/process-env.js.map +1 -0
- package/dist/helpers/process-watch.d.ts +7 -0
- package/dist/helpers/process-watch.d.ts.map +1 -0
- package/dist/helpers/process-watch.js +27 -0
- package/dist/helpers/process-watch.js.map +1 -0
- package/dist/helpers/rlimits.d.ts +10 -0
- package/dist/helpers/rlimits.d.ts.map +1 -0
- package/dist/helpers/rlimits.js +14 -0
- package/dist/helpers/rlimits.js.map +1 -0
- package/dist/helpers/runtime-files.d.ts +42 -0
- package/dist/helpers/runtime-files.d.ts.map +1 -0
- package/dist/helpers/runtime-files.js +155 -0
- package/dist/helpers/runtime-files.js.map +1 -0
- package/dist/helpers/worker-routing.d.ts +35 -0
- package/dist/helpers/worker-routing.d.ts.map +1 -0
- package/dist/helpers/worker-routing.js +70 -0
- package/dist/helpers/worker-routing.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -0
- package/dist/interface.d.ts +150 -0
- package/dist/interface.d.ts.map +1 -0
- package/dist/interface.js +6 -0
- package/dist/interface.js.map +1 -0
- package/dist/kinds/daemon-module.kind.d.ts +103 -0
- package/dist/kinds/daemon-module.kind.d.ts.map +1 -0
- package/dist/kinds/daemon-module.kind.js +38 -0
- package/dist/kinds/daemon-module.kind.js.map +1 -0
- package/dist/kinds/launch-preparation.kind.d.ts +24 -0
- package/dist/kinds/launch-preparation.kind.d.ts.map +1 -0
- package/dist/kinds/launch-preparation.kind.js +7 -0
- package/dist/kinds/launch-preparation.kind.js.map +1 -0
- package/dist/kinds/liveness-profile.kind.d.ts +33 -0
- package/dist/kinds/liveness-profile.kind.d.ts.map +1 -0
- package/dist/kinds/liveness-profile.kind.js +27 -0
- package/dist/kinds/liveness-profile.kind.js.map +1 -0
- package/dist/kinds/preset.kind.d.ts +59 -0
- package/dist/kinds/preset.kind.d.ts.map +1 -0
- package/dist/kinds/preset.kind.js +35 -0
- package/dist/kinds/preset.kind.js.map +1 -0
- package/dist/kinds/process-source.kind.d.ts +6 -0
- package/dist/kinds/process-source.kind.d.ts.map +1 -0
- package/dist/kinds/process-source.kind.js +24 -0
- package/dist/kinds/process-source.kind.js.map +1 -0
- package/dist/kinds/process.kind.d.ts +237 -0
- package/dist/kinds/process.kind.d.ts.map +1 -0
- package/dist/kinds/process.kind.js +36 -0
- package/dist/kinds/process.kind.js.map +1 -0
- package/dist/kinds/resource-provider.kind.d.ts +41 -0
- package/dist/kinds/resource-provider.kind.d.ts.map +1 -0
- package/dist/kinds/resource-provider.kind.js +56 -0
- package/dist/kinds/resource-provider.kind.js.map +1 -0
- package/dist/kinds/resource.kind.d.ts +73 -0
- package/dist/kinds/resource.kind.d.ts.map +1 -0
- package/dist/kinds/resource.kind.js +35 -0
- package/dist/kinds/resource.kind.js.map +1 -0
- package/dist/kinds/runtime-daemon-endpoint.d.ts +34 -0
- package/dist/kinds/runtime-daemon-endpoint.d.ts.map +1 -0
- package/dist/kinds/runtime-daemon-endpoint.js +83 -0
- package/dist/kinds/runtime-daemon-endpoint.js.map +1 -0
- package/dist/kinds/runtime-daemon-endpoint.kind.d.ts +144 -0
- package/dist/kinds/runtime-daemon-endpoint.kind.d.ts.map +1 -0
- package/dist/kinds/runtime-daemon-endpoint.kind.js +104 -0
- package/dist/kinds/runtime-daemon-endpoint.kind.js.map +1 -0
- package/dist/launch-preparation.d.ts +12 -0
- package/dist/launch-preparation.d.ts.map +1 -0
- package/dist/launch-preparation.js +42 -0
- package/dist/launch-preparation.js.map +1 -0
- package/dist/logging/pm-daemon.logger.descriptor.d.ts +7 -0
- package/dist/logging/pm-daemon.logger.descriptor.d.ts.map +1 -0
- package/dist/logging/pm-daemon.logger.descriptor.js +16 -0
- package/dist/logging/pm-daemon.logger.descriptor.js.map +1 -0
- package/dist/logging/pm-daemon.output.descriptor.d.ts +9 -0
- package/dist/logging/pm-daemon.output.descriptor.d.ts.map +1 -0
- package/dist/logging/pm-daemon.output.descriptor.js +22 -0
- package/dist/logging/pm-daemon.output.descriptor.js.map +1 -0
- package/dist/manager.d.ts +206 -0
- package/dist/manager.d.ts.map +1 -0
- package/dist/manager.js +682 -0
- package/dist/manager.js.map +1 -0
- package/dist/managers/dependency-resolver.d.ts +85 -0
- package/dist/managers/dependency-resolver.d.ts.map +1 -0
- package/dist/managers/dependency-resolver.js +237 -0
- package/dist/managers/dependency-resolver.js.map +1 -0
- package/dist/managers/preset-executor.d.ts +138 -0
- package/dist/managers/preset-executor.d.ts.map +1 -0
- package/dist/managers/preset-executor.js +763 -0
- package/dist/managers/preset-executor.js.map +1 -0
- package/dist/managers/resource-manager.d.ts +142 -0
- package/dist/managers/resource-manager.d.ts.map +1 -0
- package/dist/managers/resource-manager.js +767 -0
- package/dist/managers/resource-manager.js.map +1 -0
- package/dist/migrations.generated.d.ts +14 -0
- package/dist/migrations.generated.d.ts.map +1 -0
- package/dist/migrations.generated.js +27 -0
- package/dist/migrations.generated.js.map +1 -0
- package/dist/pm.assets.runtime.d.ts +151 -0
- package/dist/pm.assets.runtime.d.ts.map +1 -0
- package/dist/pm.assets.runtime.js +30 -0
- package/dist/pm.assets.runtime.js.map +1 -0
- package/dist/pm.client.descriptor.d.ts +4 -0
- package/dist/pm.client.descriptor.d.ts.map +1 -0
- package/dist/pm.client.descriptor.js +8 -0
- package/dist/pm.client.descriptor.js.map +1 -0
- package/dist/pm.client.impl.consumer.d.ts +9 -0
- package/dist/pm.client.impl.consumer.d.ts.map +1 -0
- package/dist/pm.client.impl.consumer.js +13 -0
- package/dist/pm.client.impl.consumer.js.map +1 -0
- package/dist/pm.cloud.plugin.d.ts +29 -0
- package/dist/pm.cloud.plugin.d.ts.map +1 -0
- package/dist/pm.cloud.plugin.js +57 -0
- package/dist/pm.cloud.plugin.js.map +1 -0
- package/dist/pm.consumer.plugin.d.ts +3 -0
- package/dist/pm.consumer.plugin.d.ts.map +1 -0
- package/dist/pm.consumer.plugin.js +70 -0
- package/dist/pm.consumer.plugin.js.map +1 -0
- package/dist/pm.context.descriptor.d.ts +35 -0
- package/dist/pm.context.descriptor.d.ts.map +1 -0
- package/dist/pm.context.descriptor.js +12 -0
- package/dist/pm.context.descriptor.js.map +1 -0
- package/dist/pm.context.impl.consumer.d.ts +8 -0
- package/dist/pm.context.impl.consumer.d.ts.map +1 -0
- package/dist/pm.context.impl.consumer.js +6 -0
- package/dist/pm.context.impl.consumer.js.map +1 -0
- package/dist/pm.plugin.d.ts +6 -0
- package/dist/pm.plugin.d.ts.map +1 -0
- package/dist/pm.plugin.js +6 -0
- package/dist/pm.plugin.js.map +1 -0
- package/dist/presets/index.d.ts +5 -0
- package/dist/presets/index.d.ts.map +1 -0
- package/dist/presets/index.js +5 -0
- package/dist/presets/index.js.map +1 -0
- package/dist/presets/preset/index.d.ts +2 -0
- package/dist/presets/preset/index.d.ts.map +1 -0
- package/dist/presets/preset/index.js +2 -0
- package/dist/presets/preset/index.js.map +1 -0
- package/dist/presets/preset/web-dev.d.ts +39 -0
- package/dist/presets/preset/web-dev.d.ts.map +1 -0
- package/dist/presets/preset/web-dev.js +69 -0
- package/dist/presets/preset/web-dev.js.map +1 -0
- package/dist/presets/process/index.d.ts +3 -0
- package/dist/presets/process/index.d.ts.map +1 -0
- package/dist/presets/process/index.js +3 -0
- package/dist/presets/process/index.js.map +1 -0
- package/dist/presets/process/sveltekit.d.ts +125 -0
- package/dist/presets/process/sveltekit.d.ts.map +1 -0
- package/dist/presets/process/sveltekit.js +52 -0
- package/dist/presets/process/sveltekit.js.map +1 -0
- package/dist/presets/process/web.d.ts +34 -0
- package/dist/presets/process/web.d.ts.map +1 -0
- package/dist/presets/process/web.js +52 -0
- package/dist/presets/process/web.js.map +1 -0
- package/dist/presets/resource/database.d.ts +39 -0
- package/dist/presets/resource/database.d.ts.map +1 -0
- package/dist/presets/resource/database.js +60 -0
- package/dist/presets/resource/database.js.map +1 -0
- package/dist/presets/resource/index.d.ts +2 -0
- package/dist/presets/resource/index.d.ts.map +1 -0
- package/dist/presets/resource/index.js +2 -0
- package/dist/presets/resource/index.js.map +1 -0
- package/dist/presets/types.d.ts +101 -0
- package/dist/presets/types.d.ts.map +1 -0
- package/dist/presets/types.js +53 -0
- package/dist/presets/types.js.map +1 -0
- package/dist/register-migrations.impl.consumer.d.ts +8 -0
- package/dist/register-migrations.impl.consumer.d.ts.map +1 -0
- package/dist/register-migrations.impl.consumer.js +145 -0
- package/dist/register-migrations.impl.consumer.js.map +1 -0
- package/dist/resources/index.d.ts +7 -0
- package/dist/resources/index.d.ts.map +1 -0
- package/dist/resources/index.js +7 -0
- package/dist/resources/index.js.map +1 -0
- package/dist/resources/provider.d.ts +216 -0
- package/dist/resources/provider.d.ts.map +1 -0
- package/dist/resources/provider.js +54 -0
- package/dist/resources/provider.js.map +1 -0
- package/dist/resources/providers/builtin.assets.d.ts +8 -0
- package/dist/resources/providers/builtin.assets.d.ts.map +1 -0
- package/dist/resources/providers/builtin.assets.js +26 -0
- package/dist/resources/providers/builtin.assets.js.map +1 -0
- package/dist/resources/providers/index.d.ts +14 -0
- package/dist/resources/providers/index.d.ts.map +1 -0
- package/dist/resources/providers/index.js +14 -0
- package/dist/resources/providers/index.js.map +1 -0
- package/dist/resources/providers/local-mkcert.d.ts +31 -0
- package/dist/resources/providers/local-mkcert.d.ts.map +1 -0
- package/dist/resources/providers/local-mkcert.js +169 -0
- package/dist/resources/providers/local-mkcert.js.map +1 -0
- package/dist/resources/providers/shell-setup.d.ts +17 -0
- package/dist/resources/providers/shell-setup.d.ts.map +1 -0
- package/dist/resources/providers/shell-setup.js +41 -0
- package/dist/resources/providers/shell-setup.js.map +1 -0
- package/dist/resources/providers/tool-env.d.ts +63 -0
- package/dist/resources/providers/tool-env.d.ts.map +1 -0
- package/dist/resources/providers/tool-env.js +99 -0
- package/dist/resources/providers/tool-env.js.map +1 -0
- package/dist/resources/resource-state-summary.d.ts +3 -0
- package/dist/resources/resource-state-summary.d.ts.map +1 -0
- package/dist/resources/resource-state-summary.js +82 -0
- package/dist/resources/resource-state-summary.js.map +1 -0
- package/dist/resources/status-options.d.ts +4 -0
- package/dist/resources/status-options.d.ts.map +1 -0
- package/dist/resources/status-options.js +6 -0
- package/dist/resources/status-options.js.map +1 -0
- package/dist/runnable/executor.d.ts +11 -0
- package/dist/runnable/executor.d.ts.map +1 -0
- package/dist/runnable/executor.js +41 -0
- package/dist/runnable/executor.js.map +1 -0
- package/dist/runnable/plugin.d.ts +3 -0
- package/dist/runnable/plugin.d.ts.map +1 -0
- package/dist/runnable/plugin.js +12 -0
- package/dist/runnable/plugin.js.map +1 -0
- package/dist/runnable/schemas.d.ts +28 -0
- package/dist/runnable/schemas.d.ts.map +1 -0
- package/dist/runnable/schemas.js +10 -0
- package/dist/runnable/schemas.js.map +1 -0
- package/dist/runtime-daemon-supervisor.descriptor.d.ts +16 -0
- package/dist/runtime-daemon-supervisor.descriptor.d.ts.map +1 -0
- package/dist/runtime-daemon-supervisor.descriptor.js +17 -0
- package/dist/runtime-daemon-supervisor.descriptor.js.map +1 -0
- package/dist/runtime-daemon-supervisor.impl.consumer.d.ts +22 -0
- package/dist/runtime-daemon-supervisor.impl.consumer.d.ts.map +1 -0
- package/dist/runtime-daemon-supervisor.impl.consumer.js +66 -0
- package/dist/runtime-daemon-supervisor.impl.consumer.js.map +1 -0
- package/dist/schemas/action-error.d.ts +8 -0
- package/dist/schemas/action-error.d.ts.map +1 -0
- package/dist/schemas/action-error.js +8 -0
- package/dist/schemas/action-error.js.map +1 -0
- package/dist/schemas/admission.d.ts +36 -0
- package/dist/schemas/admission.d.ts.map +1 -0
- package/dist/schemas/admission.js +22 -0
- package/dist/schemas/admission.js.map +1 -0
- package/dist/schemas/builder.d.ts +402 -0
- package/dist/schemas/builder.d.ts.map +1 -0
- package/dist/schemas/builder.js +410 -0
- package/dist/schemas/builder.js.map +1 -0
- package/dist/schemas/client.d.ts +18 -0
- package/dist/schemas/client.d.ts.map +1 -0
- package/dist/schemas/client.js +2 -0
- package/dist/schemas/client.js.map +1 -0
- package/dist/schemas/commands.d.ts +315 -0
- package/dist/schemas/commands.d.ts.map +1 -0
- package/dist/schemas/commands.js +268 -0
- package/dist/schemas/commands.js.map +1 -0
- package/dist/schemas/common.d.ts +35 -0
- package/dist/schemas/common.d.ts.map +1 -0
- package/dist/schemas/common.js +43 -0
- package/dist/schemas/common.js.map +1 -0
- package/dist/schemas/daemon-command.d.ts +61 -0
- package/dist/schemas/daemon-command.d.ts.map +1 -0
- package/dist/schemas/daemon-command.js +2 -0
- package/dist/schemas/daemon-command.js.map +1 -0
- package/dist/schemas/daemon-host.d.ts +70 -0
- package/dist/schemas/daemon-host.d.ts.map +1 -0
- package/dist/schemas/daemon-host.js +2 -0
- package/dist/schemas/daemon-host.js.map +1 -0
- package/dist/schemas/daemon-launch.d.ts +43 -0
- package/dist/schemas/daemon-launch.d.ts.map +1 -0
- package/dist/schemas/daemon-launch.js +3 -0
- package/dist/schemas/daemon-launch.js.map +1 -0
- package/dist/schemas/daemon.d.ts +98 -0
- package/dist/schemas/daemon.d.ts.map +1 -0
- package/dist/schemas/daemon.js +88 -0
- package/dist/schemas/daemon.js.map +1 -0
- package/dist/schemas/dev.d.ts +169 -0
- package/dist/schemas/dev.d.ts.map +1 -0
- package/dist/schemas/dev.js +8 -0
- package/dist/schemas/dev.js.map +1 -0
- package/dist/schemas/executable-freshness.d.ts +88 -0
- package/dist/schemas/executable-freshness.d.ts.map +1 -0
- package/dist/schemas/executable-freshness.js +2 -0
- package/dist/schemas/executable-freshness.js.map +1 -0
- package/dist/schemas/forward-config.d.ts +11 -0
- package/dist/schemas/forward-config.d.ts.map +1 -0
- package/dist/schemas/forward-config.js +15 -0
- package/dist/schemas/forward-config.js.map +1 -0
- package/dist/schemas/graph.d.ts +444 -0
- package/dist/schemas/graph.d.ts.map +1 -0
- package/dist/schemas/graph.js +59 -0
- package/dist/schemas/graph.js.map +1 -0
- package/dist/schemas/health.d.ts +43 -0
- package/dist/schemas/health.d.ts.map +1 -0
- package/dist/schemas/health.js +6 -0
- package/dist/schemas/health.js.map +1 -0
- package/dist/schemas/launch-preparation.d.ts +106 -0
- package/dist/schemas/launch-preparation.d.ts.map +1 -0
- package/dist/schemas/launch-preparation.js +50 -0
- package/dist/schemas/launch-preparation.js.map +1 -0
- package/dist/schemas/liveness-profile.d.ts +108 -0
- package/dist/schemas/liveness-profile.d.ts.map +1 -0
- package/dist/schemas/liveness-profile.js +33 -0
- package/dist/schemas/liveness-profile.js.map +1 -0
- package/dist/schemas/liveness.d.ts +37 -0
- package/dist/schemas/liveness.d.ts.map +1 -0
- package/dist/schemas/liveness.js +41 -0
- package/dist/schemas/liveness.js.map +1 -0
- package/dist/schemas/manager.d.ts +46 -0
- package/dist/schemas/manager.d.ts.map +1 -0
- package/dist/schemas/manager.js +5 -0
- package/dist/schemas/manager.js.map +1 -0
- package/dist/schemas/port-forward.d.ts +47 -0
- package/dist/schemas/port-forward.d.ts.map +1 -0
- package/dist/schemas/port-forward.js +27 -0
- package/dist/schemas/port-forward.js.map +1 -0
- package/dist/schemas/process-source.d.ts +354 -0
- package/dist/schemas/process-source.d.ts.map +1 -0
- package/dist/schemas/process-source.js +19 -0
- package/dist/schemas/process-source.js.map +1 -0
- package/dist/schemas/process-tree.d.ts +12 -0
- package/dist/schemas/process-tree.d.ts.map +1 -0
- package/dist/schemas/process-tree.js +2 -0
- package/dist/schemas/process-tree.js.map +1 -0
- package/dist/schemas/process.d.ts +944 -0
- package/dist/schemas/process.d.ts.map +1 -0
- package/dist/schemas/process.js +429 -0
- package/dist/schemas/process.js.map +1 -0
- package/dist/schemas/resource.d.ts +223 -0
- package/dist/schemas/resource.d.ts.map +1 -0
- package/dist/schemas/resource.js +92 -0
- package/dist/schemas/resource.js.map +1 -0
- package/dist/schemas/store.d.ts +97 -0
- package/dist/schemas/store.d.ts.map +1 -0
- package/dist/schemas/store.js +2 -0
- package/dist/schemas/store.js.map +1 -0
- package/dist/schemas/task-supervision.d.ts +16 -0
- package/dist/schemas/task-supervision.d.ts.map +1 -0
- package/dist/schemas/task-supervision.js +10 -0
- package/dist/schemas/task-supervision.js.map +1 -0
- package/dist/schemas/tui-state.d.ts +777 -0
- package/dist/schemas/tui-state.d.ts.map +1 -0
- package/dist/schemas/tui-state.js +119 -0
- package/dist/schemas/tui-state.js.map +1 -0
- package/dist/schemas/worker-manager.d.ts +19 -0
- package/dist/schemas/worker-manager.d.ts.map +1 -0
- package/dist/schemas/worker-manager.js +2 -0
- package/dist/schemas/worker-manager.js.map +1 -0
- package/dist/services/cleanup.d.ts +78 -0
- package/dist/services/cleanup.d.ts.map +1 -0
- package/dist/services/cleanup.js +329 -0
- package/dist/services/cleanup.js.map +1 -0
- package/dist/services/health.d.ts +81 -0
- package/dist/services/health.d.ts.map +1 -0
- package/dist/services/health.js +435 -0
- package/dist/services/health.js.map +1 -0
- package/dist/services/index.d.ts +11 -0
- package/dist/services/index.d.ts.map +1 -0
- package/dist/services/index.js +10 -0
- package/dist/services/index.js.map +1 -0
- package/dist/services/lifecycle.d.ts +238 -0
- package/dist/services/lifecycle.d.ts.map +1 -0
- package/dist/services/lifecycle.js +1391 -0
- package/dist/services/lifecycle.js.map +1 -0
- package/dist/services/liveness-state.d.ts +95 -0
- package/dist/services/liveness-state.d.ts.map +1 -0
- package/dist/services/liveness-state.js +239 -0
- package/dist/services/liveness-state.js.map +1 -0
- package/dist/services/orphans.d.ts +72 -0
- package/dist/services/orphans.d.ts.map +1 -0
- package/dist/services/orphans.js +185 -0
- package/dist/services/orphans.js.map +1 -0
- package/dist/services/process-command.d.ts +25 -0
- package/dist/services/process-command.d.ts.map +1 -0
- package/dist/services/process-command.js +36 -0
- package/dist/services/process-command.js.map +1 -0
- package/dist/services/process-log-archive.d.ts +62 -0
- package/dist/services/process-log-archive.d.ts.map +1 -0
- package/dist/services/process-log-archive.js +150 -0
- package/dist/services/process-log-archive.js.map +1 -0
- package/dist/services/run-log-frames.d.ts +26 -0
- package/dist/services/run-log-frames.d.ts.map +1 -0
- package/dist/services/run-log-frames.js +45 -0
- package/dist/services/run-log-frames.js.map +1 -0
- package/dist/services/startup-warmup.d.ts +23 -0
- package/dist/services/startup-warmup.d.ts.map +1 -0
- package/dist/services/startup-warmup.js +21 -0
- package/dist/services/startup-warmup.js.map +1 -0
- package/dist/services/state-wait.d.ts +28 -0
- package/dist/services/state-wait.d.ts.map +1 -0
- package/dist/services/state-wait.js +57 -0
- package/dist/services/state-wait.js.map +1 -0
- package/dist/services/supervision-policy.d.ts +40 -0
- package/dist/services/supervision-policy.d.ts.map +1 -0
- package/dist/services/supervision-policy.js +48 -0
- package/dist/services/supervision-policy.js.map +1 -0
- package/dist/services/task-supervision.d.ts +14 -0
- package/dist/services/task-supervision.d.ts.map +1 -0
- package/dist/services/task-supervision.js +112 -0
- package/dist/services/task-supervision.js.map +1 -0
- package/dist/services/types/index.d.ts +74 -0
- package/dist/services/types/index.d.ts.map +1 -0
- package/dist/services/types/index.js +11 -0
- package/dist/services/types/index.js.map +1 -0
- package/dist/services/workers.d.ts +75 -0
- package/dist/services/workers.d.ts.map +1 -0
- package/dist/services/workers.js +212 -0
- package/dist/services/workers.js.map +1 -0
- package/dist/storage/workspaces.descriptor.d.ts +12 -0
- package/dist/storage/workspaces.descriptor.d.ts.map +1 -0
- package/dist/storage/workspaces.descriptor.js +33 -0
- package/dist/storage/workspaces.descriptor.js.map +1 -0
- package/dist/store/process-admission.d.ts +11 -0
- package/dist/store/process-admission.d.ts.map +1 -0
- package/dist/store/process-admission.js +46 -0
- package/dist/store/process-admission.js.map +1 -0
- package/dist/store/process-config.impl.consumer.d.ts +22 -0
- package/dist/store/process-config.impl.consumer.d.ts.map +1 -0
- package/dist/store/process-config.impl.consumer.js +84 -0
- package/dist/store/process-config.impl.consumer.js.map +1 -0
- package/dist/store/process-state.impl.consumer.d.ts +25 -0
- package/dist/store/process-state.impl.consumer.d.ts.map +1 -0
- package/dist/store/process-state.impl.consumer.js +140 -0
- package/dist/store/process-state.impl.consumer.js.map +1 -0
- package/dist/store/resource-state.impl.consumer.d.ts +9 -0
- package/dist/store/resource-state.impl.consumer.d.ts.map +1 -0
- package/dist/store/resource-state.impl.consumer.js +48 -0
- package/dist/store/resource-state.impl.consumer.js.map +1 -0
- package/dist/store.impl.consumer.d.ts +121 -0
- package/dist/store.impl.consumer.d.ts.map +1 -0
- package/dist/store.impl.consumer.js +436 -0
- package/dist/store.impl.consumer.js.map +1 -0
- package/dist/surface.d.ts +93 -0
- package/dist/surface.d.ts.map +1 -0
- package/dist/surface.js +153 -0
- package/dist/surface.js.map +1 -0
- package/dist/svelte/components/PMOverview.svelte +527 -0
- package/dist/svelte/components/PMOverview.svelte.d.ts +12 -0
- package/dist/svelte/components/PMOverview.svelte.d.ts.map +1 -0
- package/dist/svelte/index.d.ts +4 -0
- package/dist/svelte/index.d.ts.map +1 -0
- package/dist/svelte/index.js +2 -0
- package/dist/svelte/runtime.d.ts +33 -0
- package/dist/svelte/runtime.d.ts.map +1 -0
- package/dist/svelte/runtime.js +148 -0
- package/dist/svelte/styles.css +2 -0
- package/dist/tasks/completion.d.ts +6 -0
- package/dist/tasks/completion.d.ts.map +1 -0
- package/dist/tasks/completion.js +105 -0
- package/dist/tasks/completion.js.map +1 -0
- package/dist/tasks/index.d.ts +11 -0
- package/dist/tasks/index.d.ts.map +1 -0
- package/dist/tasks/index.js +11 -0
- package/dist/tasks/index.js.map +1 -0
- package/dist/tasks/launch.d.ts +196 -0
- package/dist/tasks/launch.d.ts.map +1 -0
- package/dist/tasks/launch.js +10 -0
- package/dist/tasks/launch.js.map +1 -0
- package/dist/tasks/run-task.d.ts +11 -0
- package/dist/tasks/run-task.d.ts.map +1 -0
- package/dist/tasks/run-task.js +144 -0
- package/dist/tasks/run-task.js.map +1 -0
- package/dist/tasks/schemas.d.ts +83 -0
- package/dist/tasks/schemas.d.ts.map +1 -0
- package/dist/tasks/schemas.js +67 -0
- package/dist/tasks/schemas.js.map +1 -0
- package/dist/testing/daemon.d.ts +64 -0
- package/dist/testing/daemon.d.ts.map +1 -0
- package/dist/testing/daemon.js +125 -0
- package/dist/testing/daemon.js.map +1 -0
- package/dist/tui/components/DaemonHealthCard.d.ts +22 -0
- package/dist/tui/components/DaemonHealthCard.d.ts.map +1 -0
- package/dist/tui/components/DaemonHealthCard.js +30 -0
- package/dist/tui/components/DaemonHealthCard.js.map +1 -0
- package/dist/tui/components/ErrorDetailsPanel.d.ts +16 -0
- package/dist/tui/components/ErrorDetailsPanel.d.ts.map +1 -0
- package/dist/tui/components/ErrorDetailsPanel.js +22 -0
- package/dist/tui/components/ErrorDetailsPanel.js.map +1 -0
- package/dist/tui/components/FilterBar.d.ts +21 -0
- package/dist/tui/components/FilterBar.d.ts.map +1 -0
- package/dist/tui/components/FilterBar.js +31 -0
- package/dist/tui/components/FilterBar.js.map +1 -0
- package/dist/tui/components/StatsBar.d.ts +17 -0
- package/dist/tui/components/StatsBar.d.ts.map +1 -0
- package/dist/tui/components/StatsBar.js +28 -0
- package/dist/tui/components/StatsBar.js.map +1 -0
- package/dist/tui/components/index.d.ts +5 -0
- package/dist/tui/components/index.d.ts.map +1 -0
- package/dist/tui/components/index.js +5 -0
- package/dist/tui/components/index.js.map +1 -0
- package/dist/tui/index.d.ts +7 -0
- package/dist/tui/index.d.ts.map +1 -0
- package/dist/tui/index.js +7 -0
- package/dist/tui/index.js.map +1 -0
- package/dist/tui/pm-dashboard.descriptor.d.ts +11 -0
- package/dist/tui/pm-dashboard.descriptor.d.ts.map +1 -0
- package/dist/tui/pm-dashboard.descriptor.js +26 -0
- package/dist/tui/pm-dashboard.descriptor.js.map +1 -0
- package/dist/tui/pm-dashboard.impl.consumer.d.ts +19 -0
- package/dist/tui/pm-dashboard.impl.consumer.d.ts.map +1 -0
- package/dist/tui/pm-dashboard.impl.consumer.js +839 -0
- package/dist/tui/pm-dashboard.impl.consumer.js.map +1 -0
- package/dist/tui/pm-open.descriptor.d.ts +10 -0
- package/dist/tui/pm-open.descriptor.d.ts.map +1 -0
- package/dist/tui/pm-open.descriptor.js +21 -0
- package/dist/tui/pm-open.descriptor.js.map +1 -0
- package/dist/tui/pm-open.impl.consumer.d.ts +9 -0
- package/dist/tui/pm-open.impl.consumer.d.ts.map +1 -0
- package/dist/tui/pm-open.impl.consumer.js +13 -0
- package/dist/tui/pm-open.impl.consumer.js.map +1 -0
- package/dist/tui/pm-processes.descriptor.d.ts +12 -0
- package/dist/tui/pm-processes.descriptor.d.ts.map +1 -0
- package/dist/tui/pm-processes.descriptor.js +30 -0
- package/dist/tui/pm-processes.descriptor.js.map +1 -0
- package/dist/tui/pm-processes.impl.consumer.d.ts +14 -0
- package/dist/tui/pm-processes.impl.consumer.d.ts.map +1 -0
- package/dist/tui/pm-processes.impl.consumer.js +214 -0
- package/dist/tui/pm-processes.impl.consumer.js.map +1 -0
- package/dist/tui/pm-state-keys.d.ts +316 -0
- package/dist/tui/pm-state-keys.d.ts.map +1 -0
- package/dist/tui/pm-state-keys.js +10 -0
- package/dist/tui/pm-state-keys.js.map +1 -0
- package/dist/tui/pm-status.descriptor.d.ts +11 -0
- package/dist/tui/pm-status.descriptor.d.ts.map +1 -0
- package/dist/tui/pm-status.descriptor.js +29 -0
- package/dist/tui/pm-status.descriptor.js.map +1 -0
- package/dist/tui/pm-status.impl.consumer.d.ts +11 -0
- package/dist/tui/pm-status.impl.consumer.d.ts.map +1 -0
- package/dist/tui/pm-status.impl.consumer.js +75 -0
- package/dist/tui/pm-status.impl.consumer.js.map +1 -0
- package/dist/tui/pm-tui.plugin.d.ts +13 -0
- package/dist/tui/pm-tui.plugin.d.ts.map +1 -0
- package/dist/tui/pm-tui.plugin.js +34 -0
- package/dist/tui/pm-tui.plugin.js.map +1 -0
- package/dist/utils/attempt.d.ts +31 -0
- package/dist/utils/attempt.d.ts.map +1 -0
- package/dist/utils/attempt.js +43 -0
- package/dist/utils/attempt.js.map +1 -0
- package/dist/utils/bounded-wait.d.ts +31 -0
- package/dist/utils/bounded-wait.d.ts.map +1 -0
- package/dist/utils/bounded-wait.js +35 -0
- package/dist/utils/bounded-wait.js.map +1 -0
- package/dist/utils/command-exists.d.ts +5 -0
- package/dist/utils/command-exists.d.ts.map +1 -0
- package/dist/utils/command-exists.js +8 -0
- package/dist/utils/command-exists.js.map +1 -0
- package/dist/utils/daemon-launch-lock.d.ts +143 -0
- package/dist/utils/daemon-launch-lock.d.ts.map +1 -0
- package/dist/utils/daemon-launch-lock.js +420 -0
- package/dist/utils/daemon-launch-lock.js.map +1 -0
- package/dist/utils/daemon-launch-recovery.d.ts +82 -0
- package/dist/utils/daemon-launch-recovery.d.ts.map +1 -0
- package/dist/utils/daemon-launch-recovery.js +173 -0
- package/dist/utils/daemon-launch-recovery.js.map +1 -0
- package/dist/utils/daemon-log-follower.d.ts +41 -0
- package/dist/utils/daemon-log-follower.d.ts.map +1 -0
- package/dist/utils/daemon-log-follower.js +124 -0
- package/dist/utils/daemon-log-follower.js.map +1 -0
- package/dist/utils/daemon-pid.d.ts +42 -0
- package/dist/utils/daemon-pid.d.ts.map +1 -0
- package/dist/utils/daemon-pid.js +80 -0
- package/dist/utils/daemon-pid.js.map +1 -0
- package/dist/utils/daemon-reachability.d.ts +87 -0
- package/dist/utils/daemon-reachability.d.ts.map +1 -0
- package/dist/utils/daemon-reachability.js +131 -0
- package/dist/utils/daemon-reachability.js.map +1 -0
- package/dist/utils/daemon-stdio-timestamps.d.ts +24 -0
- package/dist/utils/daemon-stdio-timestamps.d.ts.map +1 -0
- package/dist/utils/daemon-stdio-timestamps.js +59 -0
- package/dist/utils/daemon-stdio-timestamps.js.map +1 -0
- package/dist/utils/daemon-stop.d.ts +66 -0
- package/dist/utils/daemon-stop.d.ts.map +1 -0
- package/dist/utils/daemon-stop.js +100 -0
- package/dist/utils/daemon-stop.js.map +1 -0
- package/dist/utils/errno-failure.d.ts +16 -0
- package/dist/utils/errno-failure.d.ts.map +1 -0
- package/dist/utils/errno-failure.js +15 -0
- package/dist/utils/errno-failure.js.map +1 -0
- package/dist/utils/exec.d.ts +27 -0
- package/dist/utils/exec.d.ts.map +1 -0
- package/dist/utils/exec.js +36 -0
- package/dist/utils/exec.js.map +1 -0
- package/dist/utils/index.d.ts +5 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +5 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/liveness.d.ts +100 -0
- package/dist/utils/liveness.d.ts.map +1 -0
- package/dist/utils/liveness.js +225 -0
- package/dist/utils/liveness.js.map +1 -0
- package/dist/utils/logging.d.ts +60 -0
- package/dist/utils/logging.d.ts.map +1 -0
- package/dist/utils/logging.js +169 -0
- package/dist/utils/logging.js.map +1 -0
- package/dist/utils/path-under.d.ts +15 -0
- package/dist/utils/path-under.d.ts.map +1 -0
- package/dist/utils/path-under.js +16 -0
- package/dist/utils/path-under.js.map +1 -0
- package/dist/utils/port-ownership.d.ts +160 -0
- package/dist/utils/port-ownership.d.ts.map +1 -0
- package/dist/utils/port-ownership.js +176 -0
- package/dist/utils/port-ownership.js.map +1 -0
- package/dist/utils/ports.d.ts +43 -0
- package/dist/utils/ports.d.ts.map +1 -0
- package/dist/utils/ports.js +200 -0
- package/dist/utils/ports.js.map +1 -0
- package/dist/utils/process-tree.d.ts +33 -0
- package/dist/utils/process-tree.d.ts.map +1 -0
- package/dist/utils/process-tree.js +197 -0
- package/dist/utils/process-tree.js.map +1 -0
- package/dist/utils/semaphore.d.ts +16 -0
- package/dist/utils/semaphore.d.ts.map +1 -0
- package/dist/utils/semaphore.js +30 -0
- package/dist/utils/semaphore.js.map +1 -0
- package/dist/utils/socket-inode.impl.consumer.d.ts +26 -0
- package/dist/utils/socket-inode.impl.consumer.d.ts.map +1 -0
- package/dist/utils/socket-inode.impl.consumer.js +30 -0
- package/dist/utils/socket-inode.impl.consumer.js.map +1 -0
- package/dist/utils/socket-paths.d.ts +121 -0
- package/dist/utils/socket-paths.d.ts.map +1 -0
- package/dist/utils/socket-paths.js +167 -0
- package/dist/utils/socket-paths.js.map +1 -0
- package/dist/utils/socket.d.ts +65 -0
- package/dist/utils/socket.d.ts.map +1 -0
- package/dist/utils/socket.js +87 -0
- package/dist/utils/socket.js.map +1 -0
- package/dist/utils/version.d.ts +40 -0
- package/dist/utils/version.d.ts.map +1 -0
- package/dist/utils/version.js +65 -0
- package/dist/utils/version.js.map +1 -0
- package/dist/utils/vibes-home.d.ts +34 -0
- package/dist/utils/vibes-home.d.ts.map +1 -0
- package/dist/utils/vibes-home.js +27 -0
- package/dist/utils/vibes-home.js.map +1 -0
- package/dist/workspace-runtime.d.ts +38 -0
- package/dist/workspace-runtime.d.ts.map +1 -0
- package/dist/workspace-runtime.js +176 -0
- package/dist/workspace-runtime.js.map +1 -0
- package/package.json +465 -4
|
@@ -0,0 +1,1391 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Process Lifecycle Service
|
|
3
|
+
* Handles start, stop, restart, and monitoring of processes
|
|
4
|
+
*/
|
|
5
|
+
import * as z from 'zod/v4';
|
|
6
|
+
import { processLaunchDeclaration } from "../helpers/launch-identity.js";
|
|
7
|
+
import { prepareProcessLaunch } from "../launch-preparation.js";
|
|
8
|
+
import { redactCredentials, redactedExcerpt } from '@vibesdotdev/shared/utils';
|
|
9
|
+
import { CapabilityError, getRuntimeHostCommands, isCapabilityError, requireRuntimeCwd, valueFreeFailure } from '@vibesdotdev/kernel';
|
|
10
|
+
import { getRuntimePath } from '@vibesdotdev/paths';
|
|
11
|
+
import { resolveFileSystemAdapter } from '@vibesdotdev/filesystem/client/resolve-adapter';
|
|
12
|
+
import { readByteRange } from "../helpers/runtime-files.js";
|
|
13
|
+
import { getRuntimeExecution } from '@vibesdotdev/kernel/execution';
|
|
14
|
+
import { attempt, failureText } from "../utils/attempt.js";
|
|
15
|
+
import { hasErrnoCode } from "../utils/errno-failure.js";
|
|
16
|
+
import { runCapture, whichCommand } from "../utils/exec.js";
|
|
17
|
+
import { toolFailure } from "../resources/providers/tool-env.js";
|
|
18
|
+
import { ProcessConfigSchema, ProcessLaunchInputsSchema, ProcessRunSchema, isSameRun, isProcessExited } from "../schemas/process.js";
|
|
19
|
+
import { getLogger } from '@vibesdotdev/logging';
|
|
20
|
+
import { killProcessTree, gracefulKillProcessTree, isProcessRunning, verifyProcessOwnership, getDescendantPids, waitForProcessExit } from "../utils/process-tree.js";
|
|
21
|
+
import { isWaitTimeout, pollUntil } from "../utils/bounded-wait.js";
|
|
22
|
+
import { scanAndKillOrphans, checkOrphanedByState } from "./orphans.js";
|
|
23
|
+
import { removeSocket, testSocketConnectivity } from "../utils/socket.js";
|
|
24
|
+
import { extractMonitoredPorts, findPortConflicts, findProcessOnPort } from "../utils/ports.js";
|
|
25
|
+
import { composePMChildEnv } from "../helpers/process-env.js";
|
|
26
|
+
import { mayRestart, processRestartPolicy, readSupervision, restartDelayMs } from "./supervision-policy.js";
|
|
27
|
+
import { processLogRedactions, resolveProcessCredentials } from "../helpers/process-credentials.js";
|
|
28
|
+
import { PM_CAPTURE_ROTATION_POLICY } from "../utils/logging.js";
|
|
29
|
+
import { applyLivenessOverrides } from "./liveness-state.js";
|
|
30
|
+
import { resolveProcessCommand } from "./process-command.js";
|
|
31
|
+
import { isWithinStartupWarmup } from "./startup-warmup.js";
|
|
32
|
+
import { launchCustodyNeedsPersist } from "../helpers/launch-custody.js";
|
|
33
|
+
import { formatRunStartMarker } from "./process-log-archive.js";
|
|
34
|
+
/** The runaway guard's window; its limit is the declared `supervision.maxSpawnsPerMinute`. */
|
|
35
|
+
const SPAWN_WINDOW_MS = 60 * 1000;
|
|
36
|
+
// Log rotation: the logging owner's `rotateAppendedFile` under the declared
|
|
37
|
+
// `pm.process-capture` policy, at start and in the daemon's steady-state sweep.
|
|
38
|
+
/**
|
|
39
|
+
* Cap on bytes read from a stderr log for crash details: only the last few
|
|
40
|
+
* lines are kept, so reading more than this from a file that may sit at the
|
|
41
|
+
* 100MB rotation threshold is pure memory churn.
|
|
42
|
+
*/
|
|
43
|
+
const CRASH_DETAIL_TAIL_BYTES = 64 * 1024;
|
|
44
|
+
const PidFileTextSchema = z.string();
|
|
45
|
+
/**
|
|
46
|
+
* The last `maxBytes` of a file. Crash-detail extraction needs the last few
|
|
47
|
+
* lines only, so only that range is read, through the filesystem kind's ranged
|
|
48
|
+
* read.
|
|
49
|
+
*/
|
|
50
|
+
async function readTail(files, path, maxBytes) {
|
|
51
|
+
const { size } = await files.stat(path);
|
|
52
|
+
return new TextDecoder().decode(await readByteRange(files, path, Math.max(0, size - maxBytes), size));
|
|
53
|
+
}
|
|
54
|
+
/** The most of a hook's output a failure message or log carries. */
|
|
55
|
+
const HOOK_OUTPUT_MAX_CHARS = 4_000;
|
|
56
|
+
/** The reason of the typed error a hook that overran its deadline raises. */
|
|
57
|
+
const HOOK_TIMEOUT_REASON = 'pm-hook-timeout';
|
|
58
|
+
/**
|
|
59
|
+
* EX_TEMPFAIL (sysexits.h): the child says the machine failed, not the
|
|
60
|
+
* program, for example a full descriptor or memory table. Kiln exits 75 when
|
|
61
|
+
* ENFILE stops it opening its weights. On the crash schedule those exits spent
|
|
62
|
+
* `maxRestarts: 2` in seconds and left Kiln down after the machine recovered
|
|
63
|
+
* (2026-09-25). They back off on their own schedule instead, from
|
|
64
|
+
* max(restartDelay, 5s) doubling to 5 minutes, and never count toward
|
|
65
|
+
* `maxRestarts`.
|
|
66
|
+
*/
|
|
67
|
+
export const EX_TEMPFAIL = 75;
|
|
68
|
+
export const TEMPFAIL_MIN_DELAY_MS = 5_000;
|
|
69
|
+
export const TEMPFAIL_MAX_DELAY_MS = 5 * 60_000;
|
|
70
|
+
/** How long a restart waits for the stopped run's pid to exit before it refuses `pm-process-stop-failed`. */
|
|
71
|
+
export const RESTART_EXIT_TIMEOUT_MS = 5_000;
|
|
72
|
+
function exitOf(exit) {
|
|
73
|
+
return { code: exit.code ?? -1, signal: exit.signal ?? undefined };
|
|
74
|
+
}
|
|
75
|
+
/** The delay before EX_TEMPFAIL retry `attempt` (1-based): max(restartDelay, floor) doubling, capped at five minutes. */
|
|
76
|
+
export function tempfailRestartDelay(attempt, restartDelay, minDelayMs = TEMPFAIL_MIN_DELAY_MS) {
|
|
77
|
+
const base = Math.max(restartDelay || 0, minDelayMs);
|
|
78
|
+
return Math.min(base * Math.pow(2, Math.max(0, attempt - 1)), TEMPFAIL_MAX_DELAY_MS);
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Process Lifecycle Service manages process start/stop/restart
|
|
82
|
+
*/
|
|
83
|
+
export class LifecycleService {
|
|
84
|
+
store;
|
|
85
|
+
getRuntime;
|
|
86
|
+
logDir;
|
|
87
|
+
resourceManager;
|
|
88
|
+
graphIdentity;
|
|
89
|
+
daemonScope;
|
|
90
|
+
livenessProfile;
|
|
91
|
+
processes = new Map();
|
|
92
|
+
spawnTimes = new Map();
|
|
93
|
+
configuredIds = null;
|
|
94
|
+
/**
|
|
95
|
+
* Timers that reset a process's `consecutiveCrashRestarts` to 0 once
|
|
96
|
+
* it's been running stably for `config.restartSettleMs`. Cleared
|
|
97
|
+
* whenever the process exits, is stopped, or is re-started. See the
|
|
98
|
+
* `restartSettleMs` field in process.ts for the semantics.
|
|
99
|
+
*/
|
|
100
|
+
settleTimers = new Map();
|
|
101
|
+
healthSettleRuns = new Map();
|
|
102
|
+
healthSettleUnsubscribe;
|
|
103
|
+
/** The credential values injected at each process's last spawn by this daemon (RC05), for log redaction. */
|
|
104
|
+
credentialRedactions = new Map();
|
|
105
|
+
/** Consecutive EX_TEMPFAIL exits per process; cleared by any other exit or an operator start. */
|
|
106
|
+
tempfailAttempts = new Map();
|
|
107
|
+
tempfailMinDelayMs;
|
|
108
|
+
restartExitTimeoutMs;
|
|
109
|
+
/** The exit handling of each child PM holds a handle for, by process id: `stop()` awaits it. */
|
|
110
|
+
exits = new Map();
|
|
111
|
+
/** The handed runtime's Logging, read per entry so it follows hot-reload generations (C083a). */
|
|
112
|
+
get log() {
|
|
113
|
+
return getLogger('pm:lifecycle', this.getRuntime());
|
|
114
|
+
}
|
|
115
|
+
/** `store` holds both state and each process's registered/launched config (pm.md K8). */
|
|
116
|
+
constructor(store, config) {
|
|
117
|
+
this.tempfailMinDelayMs = config.tempfailMinDelayMs ?? TEMPFAIL_MIN_DELAY_MS;
|
|
118
|
+
this.restartExitTimeoutMs = config.restartExitTimeoutMs ?? RESTART_EXIT_TIMEOUT_MS;
|
|
119
|
+
this.store = store;
|
|
120
|
+
this.logDir = config.logDir;
|
|
121
|
+
this.resourceManager = config.resourceManager;
|
|
122
|
+
this.graphIdentity = config.graphIdentity;
|
|
123
|
+
this.daemonScope = config.daemonScope;
|
|
124
|
+
this.livenessProfile = config.livenessProfile;
|
|
125
|
+
this.getRuntime = config.getRuntime;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* The values `processId`'s log read surfaces redact: those this daemon
|
|
129
|
+
* injected at its last spawn, else its declared credentials resolved now
|
|
130
|
+
* (an adopted process). A reference that does not resolve fails the read.
|
|
131
|
+
*/
|
|
132
|
+
async logRedactions(processId) {
|
|
133
|
+
const injected = this.credentialRedactions.get(processId);
|
|
134
|
+
if (injected)
|
|
135
|
+
return injected;
|
|
136
|
+
return processLogRedactions(this.getRuntime(), await this.store.getConfig(processId), undefined);
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Get subprocess reference
|
|
140
|
+
*/
|
|
141
|
+
getProcess(processId) {
|
|
142
|
+
return this.processes.get(processId);
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Remove subprocess reference
|
|
146
|
+
*/
|
|
147
|
+
removeProcess(processId) {
|
|
148
|
+
this.processes.delete(processId);
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Clear any pending settle timer for a process. Called whenever
|
|
152
|
+
* the process exits, is stopped, or is about to be (re)started.
|
|
153
|
+
*/
|
|
154
|
+
clearSettleTimer(processId) {
|
|
155
|
+
const cancel = this.settleTimers.get(processId);
|
|
156
|
+
if (cancel) {
|
|
157
|
+
cancel();
|
|
158
|
+
this.settleTimers.delete(processId);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
/** Committed health transitions start or cancel the same-PID settlement window. */
|
|
162
|
+
observeSettleHealth() {
|
|
163
|
+
if (this.healthSettleUnsubscribe)
|
|
164
|
+
return;
|
|
165
|
+
this.healthSettleUnsubscribe = this.store.onStateChange((state) => {
|
|
166
|
+
const run = this.healthSettleRuns.get(state.id);
|
|
167
|
+
if (!run)
|
|
168
|
+
return;
|
|
169
|
+
if (state.status !== 'running' || state.pid !== run.pid) {
|
|
170
|
+
this.healthSettleRuns.delete(state.id);
|
|
171
|
+
this.clearSettleTimer(state.id);
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
const healthy = state.healthStatus === 'healthy';
|
|
175
|
+
if (healthy === run.healthy)
|
|
176
|
+
return;
|
|
177
|
+
run.healthy = healthy;
|
|
178
|
+
this.clearSettleTimer(state.id);
|
|
179
|
+
if (healthy)
|
|
180
|
+
this.armSettleReset(run.config, run.pid);
|
|
181
|
+
});
|
|
182
|
+
this.getRuntime().lifecycle.signal.addEventListener('abort', () => {
|
|
183
|
+
this.healthSettleUnsubscribe?.();
|
|
184
|
+
this.healthSettleUnsubscribe = undefined;
|
|
185
|
+
this.healthSettleRuns.clear();
|
|
186
|
+
for (const id of this.settleTimers.keys())
|
|
187
|
+
this.clearSettleTimer(id);
|
|
188
|
+
}, { once: true });
|
|
189
|
+
}
|
|
190
|
+
/** Health-configured runs wait for their first healthy state; others settle on uptime. */
|
|
191
|
+
scheduleSettleReset(config, pid) {
|
|
192
|
+
this.clearSettleTimer(config.id);
|
|
193
|
+
this.healthSettleRuns.delete(config.id);
|
|
194
|
+
if (config.restartSettleMs <= 0)
|
|
195
|
+
return;
|
|
196
|
+
if (config.healthCheck) {
|
|
197
|
+
this.observeSettleHealth();
|
|
198
|
+
this.healthSettleRuns.set(config.id, { config, pid, healthy: false });
|
|
199
|
+
}
|
|
200
|
+
else {
|
|
201
|
+
this.armSettleReset(config, pid);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
/** A lifecycle-owned deadline; cancellation also invalidates any in-flight state read. */
|
|
205
|
+
armSettleReset(config, pid) {
|
|
206
|
+
const settleMs = config.restartSettleMs;
|
|
207
|
+
let active = true;
|
|
208
|
+
const settle = async () => {
|
|
209
|
+
const settled = await attempt(async () => {
|
|
210
|
+
const state = await this.store.get(config.id);
|
|
211
|
+
if (!active || !state || state.status !== 'running' || state.pid !== pid)
|
|
212
|
+
return;
|
|
213
|
+
if (config.healthCheck && state.healthStatus !== 'healthy')
|
|
214
|
+
return;
|
|
215
|
+
if (state.consecutiveCrashRestarts > 0) {
|
|
216
|
+
await this.store.update(config.id, { consecutiveCrashRestarts: 0 });
|
|
217
|
+
this.log.debug('consecutive crash restart counter reset after settle window', { processId: config.id, settleMs });
|
|
218
|
+
}
|
|
219
|
+
});
|
|
220
|
+
if (this.settleTimers.get(config.id) === cancel)
|
|
221
|
+
this.settleTimers.delete(config.id);
|
|
222
|
+
if (!settled.ok) {
|
|
223
|
+
this.log.warn('settle timer store update failed', { processId: config.id, failure: valueFreeFailure(settled.failure) });
|
|
224
|
+
}
|
|
225
|
+
};
|
|
226
|
+
const deadline = this.getRuntime().lifecycle.timeout(() => void settle(), settleMs);
|
|
227
|
+
const cancel = () => { active = false; deadline(); };
|
|
228
|
+
this.settleTimers.set(config.id, cancel);
|
|
229
|
+
}
|
|
230
|
+
/** This process's captured log files, joined with the handed runtime's path mechanics. */
|
|
231
|
+
async getLogPaths(processId) {
|
|
232
|
+
const path = await getRuntimePath(this.getRuntime());
|
|
233
|
+
return {
|
|
234
|
+
stdout: path.join(this.logDir, `${processId}.stdout`),
|
|
235
|
+
stderr: path.join(this.logDir, `${processId}.stderr`)
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
/** The host filesystem the handed runtime resolves (PM's files are host facts at absolute paths). */
|
|
239
|
+
hostFiles() {
|
|
240
|
+
return resolveFileSystemAdapter(this.getRuntime(), { binding: false });
|
|
241
|
+
}
|
|
242
|
+
async ensureLogDir() {
|
|
243
|
+
await (await this.hostFiles()).mkdir(this.logDir, { recursive: true });
|
|
244
|
+
}
|
|
245
|
+
/** Rotate one of this process's logs through the logging owner under the declared policy. */
|
|
246
|
+
async rotateLogIfNeeded(logPath) {
|
|
247
|
+
// The logging owner's Node file rotation, loaded where a spawn first rotates.
|
|
248
|
+
const { readRotationPolicy, rotateAppendedFile } = await import('@vibesdotdev/logging');
|
|
249
|
+
const policy = await readRotationPolicy(this.getRuntime(), PM_CAPTURE_ROTATION_POLICY);
|
|
250
|
+
const result = await rotateAppendedFile(this.getRuntime(), logPath, policy);
|
|
251
|
+
if (result.rotated)
|
|
252
|
+
this.log.info('Rotated log file', { logPath, previousSize: result.previousSize });
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Record a terminal 'fail' state for a process that never spawned (build
|
|
256
|
+
* failure, missing cwd, missing command). Shared by the pre-spawn
|
|
257
|
+
* preflight failure paths so they cannot drift apart.
|
|
258
|
+
*/
|
|
259
|
+
async markSpawnFailure(processId, lastError) {
|
|
260
|
+
await this.store.set({
|
|
261
|
+
id: processId,
|
|
262
|
+
status: 'fail',
|
|
263
|
+
restartCount: 0,
|
|
264
|
+
consecutiveCrashRestarts: 0,
|
|
265
|
+
retryCount: 0,
|
|
266
|
+
stoppedAt: new Date(),
|
|
267
|
+
lastActivity: new Date(),
|
|
268
|
+
lastError
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
/** Idempotent start still records launch cwd/workspace when the stored config omitted them. */
|
|
272
|
+
async persistLaunchCustody(config) {
|
|
273
|
+
if (!config.cwd && !config.env?.VIBES_WORKSPACE_PATH)
|
|
274
|
+
return;
|
|
275
|
+
const registered = await this.store.getConfig(config.id);
|
|
276
|
+
if (!launchCustodyNeedsPersist(registered, config))
|
|
277
|
+
return;
|
|
278
|
+
const persisted = { ...(registered ?? config) };
|
|
279
|
+
if (config.cwd)
|
|
280
|
+
persisted.cwd = config.cwd;
|
|
281
|
+
persisted.env = { ...registered?.env, ...config.env };
|
|
282
|
+
await this.store.setConfig(persisted);
|
|
283
|
+
}
|
|
284
|
+
async truncateLogs(processId) {
|
|
285
|
+
const logPaths = await this.getLogPaths(processId);
|
|
286
|
+
const timestamp = new Date().toISOString();
|
|
287
|
+
const marker = formatRunStartMarker(timestamp);
|
|
288
|
+
// Rotate logs past the declared size first (logging owner, L1). A
|
|
289
|
+
// rotation failure is reported and never costs the new run its logs.
|
|
290
|
+
const rotated = await attempt(async () => {
|
|
291
|
+
await this.rotateLogIfNeeded(logPaths.stdout);
|
|
292
|
+
await this.rotateLogIfNeeded(logPaths.stderr);
|
|
293
|
+
});
|
|
294
|
+
if (!rotated.ok) {
|
|
295
|
+
this.log.warn('Failed to rotate process logs before start', {
|
|
296
|
+
processId,
|
|
297
|
+
failure: valueFreeFailure(rotated.failure)
|
|
298
|
+
});
|
|
299
|
+
}
|
|
300
|
+
const files = await this.hostFiles();
|
|
301
|
+
const truncated = await attempt(async () => {
|
|
302
|
+
await files.writeFile(logPaths.stdout, marker);
|
|
303
|
+
await files.writeFile(logPaths.stderr, marker);
|
|
304
|
+
});
|
|
305
|
+
if (!truncated.ok) {
|
|
306
|
+
// A full disk (or any fs failure) silently yielding NO logs is
|
|
307
|
+
// worse than a failed start: every crash then debugs blind. Match
|
|
308
|
+
// the rest of this file and surface it.
|
|
309
|
+
this.log.warn('Failed to truncate/rotate process logs', {
|
|
310
|
+
processId,
|
|
311
|
+
failure: valueFreeFailure(truncated.failure)
|
|
312
|
+
});
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
checkRunawaySpawns(config, maxSpawnsPerMinute) {
|
|
316
|
+
if (config.dangerouslyDisableRunawayChecks) {
|
|
317
|
+
this.log.warn('Runaway checks disabled', { processId: config.id });
|
|
318
|
+
return;
|
|
319
|
+
}
|
|
320
|
+
const now = Date.now();
|
|
321
|
+
let times = this.spawnTimes.get(config.id) || [];
|
|
322
|
+
times = times.filter((t) => t > now - SPAWN_WINDOW_MS);
|
|
323
|
+
if (times.length >= maxSpawnsPerMinute) {
|
|
324
|
+
const msg = `RUNAWAY PROCESS: ${times.length + 1} spawns of "${config.id}" in 1 minute (limit: ${maxSpawnsPerMinute})`;
|
|
325
|
+
this.log.error(msg, { processId: config.id, spawnsInWindow: times.length });
|
|
326
|
+
throw new CapabilityError(msg, 'RATE_LIMITED', {
|
|
327
|
+
reason: 'pm-runaway-spawns',
|
|
328
|
+
retryable: false,
|
|
329
|
+
details: { processId: config.id, spawnsInWindow: times.length + 1, limit: maxSpawnsPerMinute }
|
|
330
|
+
});
|
|
331
|
+
}
|
|
332
|
+
times.push(now);
|
|
333
|
+
this.spawnTimes.set(config.id, times);
|
|
334
|
+
}
|
|
335
|
+
async waitForSocketReady(socketPath, timeoutMs, processId) {
|
|
336
|
+
// Poll, bounded by the runtime lifecycle (RC07): the child (owner of the
|
|
337
|
+
// socket) publishes no cross-process "listening" event.
|
|
338
|
+
const runtime = this.getRuntime();
|
|
339
|
+
const ready = await pollUntil(runtime, () => testSocketConnectivity(runtime, socketPath, 500), {
|
|
340
|
+
timeoutMs,
|
|
341
|
+
intervalMs: 50,
|
|
342
|
+
reason: 'pm-process-socket-ready'
|
|
343
|
+
});
|
|
344
|
+
if (ready)
|
|
345
|
+
return;
|
|
346
|
+
const processInfo = processId ? ` for '${processId}'` : '';
|
|
347
|
+
throw new CapabilityError(`Socket${processInfo} not ready within ${timeoutMs}ms: endpoint is not accepting connections`, 'TIMEOUT', { reason: 'pm-socket-not-ready', details: { socketPath, timeoutMs } });
|
|
348
|
+
}
|
|
349
|
+
decodeHookOutput(output) {
|
|
350
|
+
return new TextDecoder().decode(output).trim();
|
|
351
|
+
}
|
|
352
|
+
formatHookFailureOutput(stdout, stderr) {
|
|
353
|
+
const stderrTail = this.decodeHookOutput(stderr)
|
|
354
|
+
.split('\n')
|
|
355
|
+
.filter(Boolean)
|
|
356
|
+
.slice(-8)
|
|
357
|
+
.join('\n');
|
|
358
|
+
const stdoutTail = this.decodeHookOutput(stdout)
|
|
359
|
+
.split('\n')
|
|
360
|
+
.filter(Boolean)
|
|
361
|
+
.slice(-8)
|
|
362
|
+
.join('\n');
|
|
363
|
+
const sections = [
|
|
364
|
+
stderrTail ? `stderr:\n${stderrTail}` : '',
|
|
365
|
+
stdoutTail ? `stdout:\n${stdoutTail}` : ''
|
|
366
|
+
].filter(Boolean);
|
|
367
|
+
// Hook output reaches messages, logs and stored state: credentials out, bounded.
|
|
368
|
+
return redactCredentials(sections.join('\n')).slice(0, HOOK_OUTPUT_MAX_CHARS);
|
|
369
|
+
}
|
|
370
|
+
async runPreBuildHook(config) {
|
|
371
|
+
if (!config.preBuild)
|
|
372
|
+
return null;
|
|
373
|
+
const { preBuild } = config;
|
|
374
|
+
const preBuildCwd = preBuild.cwd || config.cwd || requireRuntimeCwd(this.getRuntime());
|
|
375
|
+
// A hook is a PM child (C15): the process's declarations and its own.
|
|
376
|
+
const preBuildEnv = await composePMChildEnv(this.getRuntime(), {
|
|
377
|
+
env: { ...config.env, ...preBuild.env },
|
|
378
|
+
inheritEnv: [...(config.inheritEnv ?? []), ...(preBuild.inheritEnv ?? [])],
|
|
379
|
+
cwd: preBuildCwd
|
|
380
|
+
});
|
|
381
|
+
this.log.info('Running pre-build', { processId: config.id, cwd: preBuildCwd });
|
|
382
|
+
// Async spawn — a sync spawn here blocks the daemon's whole event loop
|
|
383
|
+
// (RPCs, health checks) for the duration of the hook, and a hung hook
|
|
384
|
+
// wedges the daemon permanently. The config's timeout is honored
|
|
385
|
+
// (BuildHookSchema defaults it to 600_000 during parse in start()).
|
|
386
|
+
const ran = await attempt(() => this.runHookProcess([preBuild.command, ...(preBuild.args || [])], { cwd: preBuildCwd, env: preBuildEnv }, preBuild.timeout, `pre-build for '${config.id}'`));
|
|
387
|
+
if (!ran.ok) {
|
|
388
|
+
this.log.error('Pre-build error', { processId: config.id, failure: valueFreeFailure(ran.failure) });
|
|
389
|
+
throw ran.failure;
|
|
390
|
+
}
|
|
391
|
+
const result = ran.value;
|
|
392
|
+
if (result.exitCode !== 0) {
|
|
393
|
+
const output = this.formatHookFailureOutput(result.stdout, result.stderr);
|
|
394
|
+
const cmdStr = [preBuild.command, ...(preBuild.args || [])].join(' ');
|
|
395
|
+
const detail = output || `command: ${cmdStr}`;
|
|
396
|
+
this.log.error('Pre-build failed', {
|
|
397
|
+
processId: config.id,
|
|
398
|
+
exitCode: result.exitCode,
|
|
399
|
+
command: cmdStr,
|
|
400
|
+
output,
|
|
401
|
+
detail
|
|
402
|
+
});
|
|
403
|
+
return result;
|
|
404
|
+
}
|
|
405
|
+
this.log.info('Pre-build complete', { processId: config.id });
|
|
406
|
+
return null;
|
|
407
|
+
}
|
|
408
|
+
/**
|
|
409
|
+
* Run a lifecycle hook command asynchronously with a hard timeout.
|
|
410
|
+
* On timeout the process gets SIGTERM, then SIGKILL after 2s grace.
|
|
411
|
+
*/
|
|
412
|
+
async runHookProcess(cmd, opts, timeoutMs, label) {
|
|
413
|
+
const [command, ...args] = cmd;
|
|
414
|
+
if (command === undefined) {
|
|
415
|
+
throw new CapabilityError(`${label} has no command`, 'INVALID_INPUT', { reason: 'pm-hook-command-missing' });
|
|
416
|
+
}
|
|
417
|
+
const execution = await getRuntimeExecution(this.getRuntime());
|
|
418
|
+
const executed = await attempt(() => execution.execute({ command, args, cwd: opts.cwd, env: opts.env, envMode: 'replace', timeout: timeoutMs, killTree: true }));
|
|
419
|
+
if (!executed.ok) {
|
|
420
|
+
// The owner refuses a command it cannot start (a missing binary) as a
|
|
421
|
+
// typed failure; the hook names itself in that rejection.
|
|
422
|
+
throw new CapabilityError(`${label} failed to start: ${failureText(executed.failure)}`, 'UNAVAILABLE', {
|
|
423
|
+
reason: 'pm-hook-start-failed',
|
|
424
|
+
cause: executed.failure
|
|
425
|
+
});
|
|
426
|
+
}
|
|
427
|
+
const result = executed.value;
|
|
428
|
+
if (result.timedOut) {
|
|
429
|
+
throw new CapabilityError(`${label} timed out after ${timeoutMs}ms`, 'TIMEOUT', {
|
|
430
|
+
reason: HOOK_TIMEOUT_REASON,
|
|
431
|
+
details: { timeoutMs }
|
|
432
|
+
});
|
|
433
|
+
}
|
|
434
|
+
if (result.exitCode === 127) {
|
|
435
|
+
throw new CapabilityError(`${label} failed to start or could not find its command (exit 127)`, 'UNAVAILABLE', {
|
|
436
|
+
reason: 'pm-hook-command-not-found'
|
|
437
|
+
});
|
|
438
|
+
}
|
|
439
|
+
return {
|
|
440
|
+
exitCode: result.exitCode ?? -1,
|
|
441
|
+
stdout: new TextEncoder().encode(result.stdout),
|
|
442
|
+
stderr: new TextEncoder().encode(result.stderr)
|
|
443
|
+
};
|
|
444
|
+
}
|
|
445
|
+
async runBuildHook(config) {
|
|
446
|
+
if (!config.build)
|
|
447
|
+
return;
|
|
448
|
+
const { build } = config;
|
|
449
|
+
const buildCwd = build.cwd || config.cwd || requireRuntimeCwd(this.getRuntime());
|
|
450
|
+
const buildEnv = await composePMChildEnv(this.getRuntime(), {
|
|
451
|
+
env: build.env,
|
|
452
|
+
inheritEnv: [...(config.inheritEnv ?? []), ...(build.inheritEnv ?? [])],
|
|
453
|
+
cwd: buildCwd
|
|
454
|
+
});
|
|
455
|
+
this.log.info('Running build', { processId: config.id, cwd: buildCwd });
|
|
456
|
+
const ran = await attempt(() => this.runHookProcess([build.command, ...(build.args || [])], { cwd: buildCwd, env: buildEnv }, build.timeout, `build for '${config.id}'`));
|
|
457
|
+
if (!ran.ok) {
|
|
458
|
+
this.log.error('Build error', { processId: config.id, failure: valueFreeFailure(ran.failure) });
|
|
459
|
+
throw ran.failure;
|
|
460
|
+
}
|
|
461
|
+
const result = ran.value;
|
|
462
|
+
if (result.exitCode !== 0) {
|
|
463
|
+
const output = this.formatHookFailureOutput(result.stdout, result.stderr);
|
|
464
|
+
const message = `Build failed for '${config.id}' (exit code ${result.exitCode})${output ? `\n${output}` : ''}`;
|
|
465
|
+
this.log.error('Build failed', { processId: config.id, exitCode: result.exitCode, output });
|
|
466
|
+
throw new CapabilityError(message, 'UNAVAILABLE', {
|
|
467
|
+
reason: 'pm-build-failed',
|
|
468
|
+
details: { processId: config.id, exitCode: result.exitCode }
|
|
469
|
+
});
|
|
470
|
+
}
|
|
471
|
+
this.log.info('Build complete', { processId: config.id });
|
|
472
|
+
}
|
|
473
|
+
async ensureLaunchReady(plan, config) {
|
|
474
|
+
if (!plan.readiness)
|
|
475
|
+
return;
|
|
476
|
+
const result = await runCapture(this.getRuntime(), plan.readiness.command, plan.readiness.args, {
|
|
477
|
+
inheritEnv: plan.readiness.inheritEnv ?? config.inheritEnv,
|
|
478
|
+
env: config.env, cwd: config.cwd, signal: this.getRuntime().lifecycle.signal
|
|
479
|
+
});
|
|
480
|
+
if (result.exitCode !== 0) {
|
|
481
|
+
throw toolFailure({ tool: plan.readiness.command, action: 'launch readiness', outcome: result });
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
async loadConfiguredProcessIds() {
|
|
485
|
+
if (this.configuredIds)
|
|
486
|
+
return this.configuredIds;
|
|
487
|
+
// An unreadable config is an error for the caller, never "nothing is configured".
|
|
488
|
+
const { readPMGraph } = await import("../graph.js");
|
|
489
|
+
const graph = await readPMGraph(this.getRuntime());
|
|
490
|
+
this.configuredIds = new Set(graph.configs.map((c) => c.id));
|
|
491
|
+
return this.configuredIds;
|
|
492
|
+
}
|
|
493
|
+
invalidateConfigCache() {
|
|
494
|
+
this.configuredIds = null;
|
|
495
|
+
}
|
|
496
|
+
/**
|
|
497
|
+
* The pre-build hook of one start: a failing exit records the failure (and,
|
|
498
|
+
* under `autoRestart` with attempts left, schedules the retry like a crash)
|
|
499
|
+
* and refuses the start `pm-prebuild-failed`; `ignoreFailure` only warns.
|
|
500
|
+
*/
|
|
501
|
+
async runPreBuildStep(config, preBuild) {
|
|
502
|
+
const preBuildResult = await this.runPreBuildHook(config);
|
|
503
|
+
if (!preBuildResult || preBuildResult.exitCode === 0)
|
|
504
|
+
return;
|
|
505
|
+
const output = this.formatHookFailureOutput(preBuildResult.stdout, preBuildResult.stderr);
|
|
506
|
+
const cmdStr = [preBuild.command, ...(preBuild.args || [])].join(' ');
|
|
507
|
+
const detail = output || `command: ${cmdStr}`;
|
|
508
|
+
const message = `Pre-build failed for '${config.id}' (exit code ${preBuildResult.exitCode})\n${detail}`;
|
|
509
|
+
const refusal = () => new CapabilityError(message, 'UNAVAILABLE', {
|
|
510
|
+
reason: 'pm-prebuild-failed',
|
|
511
|
+
details: { processId: config.id, exitCode: preBuildResult.exitCode }
|
|
512
|
+
});
|
|
513
|
+
if (preBuild.ignoreFailure) {
|
|
514
|
+
this.log.warn(`Pre-build failed but ignoreFailure=true for ${config.id}`, { message });
|
|
515
|
+
return;
|
|
516
|
+
}
|
|
517
|
+
// If autoRestart is enabled, schedule a retry with backoff like a crash
|
|
518
|
+
if (config.autoRestart) {
|
|
519
|
+
const existing = await this.store.get(config.id);
|
|
520
|
+
const policy = processRestartPolicy(await readSupervision(this.getRuntime()), config);
|
|
521
|
+
const nextAttempt = (existing?.consecutiveCrashRestarts ?? 0) + 1;
|
|
522
|
+
if (existing && mayRestart(policy, nextAttempt)) {
|
|
523
|
+
const delay = restartDelayMs(policy, nextAttempt);
|
|
524
|
+
this.log.info(`preBuild failed, scheduling restart for ${config.id}`, {
|
|
525
|
+
attempt: nextAttempt,
|
|
526
|
+
maxRestarts: policy.maxConsecutive,
|
|
527
|
+
delayMs: delay,
|
|
528
|
+
exitCode: preBuildResult.exitCode
|
|
529
|
+
});
|
|
530
|
+
await this.store.update(config.id, {
|
|
531
|
+
status: 'fail',
|
|
532
|
+
consecutiveCrashRestarts: nextAttempt,
|
|
533
|
+
lastActivity: new Date(),
|
|
534
|
+
lastError: message,
|
|
535
|
+
exitCode: preBuildResult.exitCode,
|
|
536
|
+
signal: preBuildResult.signal
|
|
537
|
+
});
|
|
538
|
+
// Supervision (RC11 class: the daemon restarting its own child),
|
|
539
|
+
// on the declared policy and a lifecycle one-shot (RC07).
|
|
540
|
+
this.getRuntime().lifecycle.timeout(() => {
|
|
541
|
+
void this.retryAfterPreBuildFailure(config);
|
|
542
|
+
}, delay);
|
|
543
|
+
throw refusal();
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
// No autoRestart or maxRestarts exceeded. A first start has no row yet.
|
|
547
|
+
await this.store.upsert(config.id, {
|
|
548
|
+
status: 'fail',
|
|
549
|
+
stoppedAt: new Date(),
|
|
550
|
+
lastActivity: new Date(),
|
|
551
|
+
lastError: message,
|
|
552
|
+
exitCode: preBuildResult.exitCode,
|
|
553
|
+
signal: preBuildResult.signal
|
|
554
|
+
});
|
|
555
|
+
throw refusal();
|
|
556
|
+
}
|
|
557
|
+
/** The scheduled start after a failed pre-build: its own failure is reported and recorded, nothing awaits it. */
|
|
558
|
+
async retryAfterPreBuildFailure(config) {
|
|
559
|
+
const retried = await attempt(() => this.start(config, { resetRestartCount: false }));
|
|
560
|
+
if (retried.ok)
|
|
561
|
+
return;
|
|
562
|
+
this.log.error(`preBuild retry failed for ${config.id}`, { failure: valueFreeFailure(retried.failure) });
|
|
563
|
+
await this.store.update(config.id, { lastError: `preBuild retry failed: ${failureText(retried.failure)}` });
|
|
564
|
+
}
|
|
565
|
+
/**
|
|
566
|
+
* Start a process
|
|
567
|
+
*/
|
|
568
|
+
async start(input, options) {
|
|
569
|
+
const parsed = ProcessConfigSchema.safeParse(input);
|
|
570
|
+
if (!parsed.success) {
|
|
571
|
+
throw new CapabilityError('Process configuration is invalid', 'INVALID_INPUT', {
|
|
572
|
+
reason: 'pm-process-config-invalid',
|
|
573
|
+
details: { issueCount: parsed.error.issues.length }
|
|
574
|
+
});
|
|
575
|
+
}
|
|
576
|
+
const config = parsed.data;
|
|
577
|
+
return this.store.withProcessAdmission(config.id, () => this.startAdmitted(config, options));
|
|
578
|
+
}
|
|
579
|
+
async startAdmitted(input, options) {
|
|
580
|
+
// Liveness profile overrides (pm-infra-liveness-fleet): the single choke
|
|
581
|
+
// point — start, restart, and watch-triggered rebuilds all funnel here.
|
|
582
|
+
// Only descriptors that declare the active local profile in
|
|
583
|
+
// livenessProfiles AND ship livenessConfig[profile] overrides change;
|
|
584
|
+
// everything else spawns exactly as before. The stored config keeps the
|
|
585
|
+
// canonical (un-overridden) config.
|
|
586
|
+
const config = applyLivenessOverrides(this.getRuntime(), processLaunchDeclaration(input), this.livenessProfile?.('local'));
|
|
587
|
+
this.checkRunawaySpawns(config, (await readSupervision(this.getRuntime())).maxSpawnsPerMinute);
|
|
588
|
+
const existing = await this.store.get(config.id);
|
|
589
|
+
// CRITICAL: Check if process is already properly running BEFORE orphan scan
|
|
590
|
+
// This prevents killing our own running process when start is called idempotently
|
|
591
|
+
if (existing?.pid && (await isProcessRunning(this.getRuntime(), existing.pid))) {
|
|
592
|
+
if (existing.status === 'running') {
|
|
593
|
+
// Verify the process is actually on the expected ports (not a recycled PID)
|
|
594
|
+
const monitoredPorts = await extractMonitoredPorts(this.getRuntime(), config);
|
|
595
|
+
let processOnExpectedPort = monitoredPorts.length === 0; // No ports = assume OK
|
|
596
|
+
// Launcher commands (bun, node, npm) never bind the port directly —
|
|
597
|
+
// their child does (e.g. `bun run vite` → node → vite listens on 8423).
|
|
598
|
+
// Treat any descendant of the recorded PID as "on expected port" so
|
|
599
|
+
// healthy launcher-style processes aren't misidentified as PID reuse.
|
|
600
|
+
const descendants = new Set(await getDescendantPids(this.getRuntime(), existing.pid));
|
|
601
|
+
for (const port of monitoredPorts) {
|
|
602
|
+
const pidOnPort = await findProcessOnPort(this.getRuntime(), port);
|
|
603
|
+
if (pidOnPort && (pidOnPort === existing.pid || descendants.has(pidOnPort))) {
|
|
604
|
+
processOnExpectedPort = true;
|
|
605
|
+
break;
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
if (processOnExpectedPort) {
|
|
609
|
+
// Process is healthy - idempotent start, return existing state
|
|
610
|
+
this.log.debug('Process already running, returning existing state', {
|
|
611
|
+
processId: config.id,
|
|
612
|
+
pid: existing.pid
|
|
613
|
+
});
|
|
614
|
+
await this.persistLaunchCustody(config);
|
|
615
|
+
return existing;
|
|
616
|
+
}
|
|
617
|
+
// A live pid that has not bound yet is BOOTING while it is inside the
|
|
618
|
+
// health warmup the config itself declares. Restarting it here made
|
|
619
|
+
// the orphan scan kill the daemon's own child the moment it bound
|
|
620
|
+
// (2026-09-05: 48 such kills of mcp-server-dev, boot 32-43 s).
|
|
621
|
+
if (isWithinStartupWarmup({
|
|
622
|
+
startedAt: existing.startedAt,
|
|
623
|
+
warmupMs: config.healthCheck?.warmupMs,
|
|
624
|
+
now: Date.now()
|
|
625
|
+
})) {
|
|
626
|
+
this.log.info('Process alive and still inside its health warmup; not on its port yet', {
|
|
627
|
+
processId: config.id,
|
|
628
|
+
pid: existing.pid,
|
|
629
|
+
monitoredPorts,
|
|
630
|
+
warmupMs: config.healthCheck?.warmupMs ?? null
|
|
631
|
+
});
|
|
632
|
+
return existing;
|
|
633
|
+
}
|
|
634
|
+
// PID is alive but not on expected port - likely PID reuse, continue to orphan scan
|
|
635
|
+
this.log.warn('Process PID alive but not on expected port, will restart', {
|
|
636
|
+
processId: config.id,
|
|
637
|
+
pid: existing.pid,
|
|
638
|
+
monitoredPorts
|
|
639
|
+
});
|
|
640
|
+
}
|
|
641
|
+
else {
|
|
642
|
+
// Process has PID but status is not 'running' - it's orphaned in state, kill it
|
|
643
|
+
await this.store.assertTaskLaunchAvailable(config.id);
|
|
644
|
+
const orphan = await checkOrphanedByState(this.getRuntime(), config, existing);
|
|
645
|
+
if (orphan.shouldKill && orphan.pid) {
|
|
646
|
+
this.log.warn('Killing orphaned process (state mismatch)', {
|
|
647
|
+
processId: config.id,
|
|
648
|
+
pid: orphan.pid,
|
|
649
|
+
status: existing.status
|
|
650
|
+
});
|
|
651
|
+
await killProcessTree(this.getRuntime(), orphan.pid, config.id);
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
await this.store.assertTaskLaunchAvailable(config.id);
|
|
656
|
+
// Reconciliation and persisted custody use the provider's executable identity,
|
|
657
|
+
// while the declaration retains its request for preparation on every start.
|
|
658
|
+
const launchPlan = await prepareProcessLaunch(this.getRuntime(), config);
|
|
659
|
+
const launchConfig = launchPlan ? { ...config, ...launchPlan.process } : config;
|
|
660
|
+
// NOW it's safe to scan for orphaned processes on ports
|
|
661
|
+
// This will only kill processes that are NOT our currently running process
|
|
662
|
+
const orphanResult = await scanAndKillOrphans(this.getRuntime(), launchConfig, existing, this.daemonScope);
|
|
663
|
+
if (orphanResult.foundOrphans) {
|
|
664
|
+
this.log.info('Killed orphaned processes on ports', { processId: config.id });
|
|
665
|
+
// Wait (bounded, RC07) for the ports to report free instead of a fixed
|
|
666
|
+
// sleep. Poll: the OS offers no port-release event to this process.
|
|
667
|
+
const runtime = this.getRuntime();
|
|
668
|
+
const freed = await pollUntil(runtime, async () => (await findPortConflicts(runtime, launchConfig, existing?.pid ?? null)).length === 0, { timeoutMs: 2_000, intervalMs: 50, reason: 'pm-port-release' });
|
|
669
|
+
if (!freed)
|
|
670
|
+
this.log.warn('Ports still held after orphan kill; starting anyway', { processId: config.id });
|
|
671
|
+
}
|
|
672
|
+
// Check resource dependencies
|
|
673
|
+
if (this.resourceManager && config.dependencies) {
|
|
674
|
+
for (const depId of config.dependencies) {
|
|
675
|
+
const resourceState = await this.resourceManager.getState(depId);
|
|
676
|
+
if (resourceState && resourceState.status !== 'ready') {
|
|
677
|
+
throw new CapabilityError(`Resource '${depId}' not ready (status: ${resourceState.status})`, 'UNAVAILABLE', {
|
|
678
|
+
reason: 'pm-resource-not-ready',
|
|
679
|
+
details: { resourceId: depId, status: resourceState.status }
|
|
680
|
+
});
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
}
|
|
684
|
+
// Check requiresPass dependencies
|
|
685
|
+
if (config.requiresPass) {
|
|
686
|
+
for (const depId of config.requiresPass) {
|
|
687
|
+
const depState = await this.store.get(depId);
|
|
688
|
+
if (!depState || depState.status !== 'pass') {
|
|
689
|
+
const lastError = depState?.lastError;
|
|
690
|
+
await this.store.set({
|
|
691
|
+
id: config.id,
|
|
692
|
+
status: 'waiting',
|
|
693
|
+
restartCount: 0,
|
|
694
|
+
consecutiveCrashRestarts: 0,
|
|
695
|
+
retryCount: 0,
|
|
696
|
+
lastError: `Dependency '${depId}' not in pass state${lastError ? `: ${lastError}` : ''}`,
|
|
697
|
+
stoppedAt: new Date(),
|
|
698
|
+
lastActivity: new Date()
|
|
699
|
+
});
|
|
700
|
+
throw new CapabilityError(`Dependency '${depId}' not in pass state`, 'CONFLICT', {
|
|
701
|
+
reason: 'pm-dependency-not-passed',
|
|
702
|
+
details: { processId: config.id, dependency: depId }
|
|
703
|
+
});
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
}
|
|
707
|
+
if (!config.socket && existing?.socketPath) {
|
|
708
|
+
await this.store.update(config.id, { socketPath: undefined });
|
|
709
|
+
}
|
|
710
|
+
await this.ensureLogDir();
|
|
711
|
+
await this.truncateLogs(config.id);
|
|
712
|
+
// The native owner refuses to remove a live endpoint. A listening process
|
|
713
|
+
// must be reconciled by identity, never killed just for using this path:
|
|
714
|
+
// when the socket's serve-lock holder is alive and is this process's own
|
|
715
|
+
// command, PM adopts it instead of spawning a duplicate the holder refuses.
|
|
716
|
+
if (config.socket) {
|
|
717
|
+
const adopted = await this.adoptServeHolder(config);
|
|
718
|
+
if (adopted)
|
|
719
|
+
return adopted;
|
|
720
|
+
}
|
|
721
|
+
const previousSocket = config.socket || existing?.socketPath;
|
|
722
|
+
if (previousSocket)
|
|
723
|
+
await removeSocket(this.getRuntime(), previousSocket);
|
|
724
|
+
if (launchPlan)
|
|
725
|
+
await this.ensureLaunchReady(launchPlan, config);
|
|
726
|
+
// Run pre-build hook if configured
|
|
727
|
+
const { preBuild } = config;
|
|
728
|
+
if (preBuild) {
|
|
729
|
+
const prebuilt = await attempt(() => this.runPreBuildStep(config, preBuild));
|
|
730
|
+
if (!prebuilt.ok) {
|
|
731
|
+
// A hook that overran its deadline (typed, never read from message text) is a recorded failure.
|
|
732
|
+
if (isCapabilityError(prebuilt.failure) && prebuilt.failure.reason === HOOK_TIMEOUT_REASON) {
|
|
733
|
+
await this.store.upsert(config.id, {
|
|
734
|
+
status: 'fail',
|
|
735
|
+
stoppedAt: new Date(),
|
|
736
|
+
lastActivity: new Date(),
|
|
737
|
+
lastError: failureText(prebuilt.failure),
|
|
738
|
+
signal: 'SIGTERM'
|
|
739
|
+
});
|
|
740
|
+
}
|
|
741
|
+
throw prebuilt.failure;
|
|
742
|
+
}
|
|
743
|
+
}
|
|
744
|
+
if (config.build) {
|
|
745
|
+
const built = await attempt(() => this.runBuildHook(config));
|
|
746
|
+
if (!built.ok) {
|
|
747
|
+
const message = failureText(built.failure);
|
|
748
|
+
if (!config.build.ignoreFailure) {
|
|
749
|
+
await this.markSpawnFailure(config.id, message);
|
|
750
|
+
throw built.failure;
|
|
751
|
+
}
|
|
752
|
+
this.log.warn(`Build failed but ignoreFailure=true for ${config.id}`, { message });
|
|
753
|
+
}
|
|
754
|
+
}
|
|
755
|
+
const logPaths = await this.getLogPaths(config.id);
|
|
756
|
+
const runtime = this.getRuntime();
|
|
757
|
+
const processCwd = config.cwd || requireRuntimeCwd(runtime);
|
|
758
|
+
// Preflight: verify cwd exists. Without this, posix_spawn fails with
|
|
759
|
+
// ENOENT and Bun attributes the error to the binary name, which is
|
|
760
|
+
// misleading ("posix_spawn 'bun'" when the real problem is the cwd).
|
|
761
|
+
const cwdPresent = await attempt(async () => (await this.hostFiles()).exists(processCwd));
|
|
762
|
+
if (!cwdPresent.ok || !cwdPresent.value) {
|
|
763
|
+
const code = cwdPresent.ok ? 'ENOENT' : hasErrnoCode(cwdPresent.failure) ? cwdPresent.failure.code : undefined;
|
|
764
|
+
const message = code === 'ENOENT'
|
|
765
|
+
? `cwd does not exist: '${processCwd}' for '${config.id}'`
|
|
766
|
+
: `cwd is not accessible (${code ?? 'unknown'}): '${processCwd}' for '${config.id}'`;
|
|
767
|
+
this.log.error(message, { processId: config.id });
|
|
768
|
+
await this.markSpawnFailure(config.id, message);
|
|
769
|
+
throw new CapabilityError(message, code === 'ENOENT' ? 'NOT_FOUND' : 'UNAVAILABLE', {
|
|
770
|
+
reason: code === 'ENOENT' ? 'pm-cwd-missing' : 'pm-cwd-inaccessible',
|
|
771
|
+
details: { processId: config.id, cwd: processCwd }
|
|
772
|
+
});
|
|
773
|
+
}
|
|
774
|
+
// C15: PM's base set, the host's re-entry facts and roots, the names the
|
|
775
|
+
// process inherits, its cwd's `.env`, and its declared env; nothing else.
|
|
776
|
+
const processEnv = await composePMChildEnv(runtime, {
|
|
777
|
+
env: config.env,
|
|
778
|
+
inheritEnv: config.inheritEnv,
|
|
779
|
+
cwd: processCwd
|
|
780
|
+
});
|
|
781
|
+
processEnv.VIBES_PM_MANAGED = config.id;
|
|
782
|
+
// Stamp the MODULE GRAPH this child is about to import, so the
|
|
783
|
+
// executable-freshness reconciler's second predicate compares against
|
|
784
|
+
// what this child actually loaded rather than a wall-clock guess: a
|
|
785
|
+
// `bun install` that rewrites an identical lock must not roll the fleet,
|
|
786
|
+
// and a genuine `vibes update` must roll every body spawned before it.
|
|
787
|
+
// `VIBES_HOST_ROOT` may already be in `processEnv` (inherited, or set by
|
|
788
|
+
// the process config) — the child's own root wins over the daemon's.
|
|
789
|
+
{
|
|
790
|
+
const childHostRoot = processEnv.VIBES_HOST_ROOT?.trim() || this.graphIdentity?.()?.root || undefined;
|
|
791
|
+
if (childHostRoot) {
|
|
792
|
+
processEnv.VIBES_HOST_ROOT = childHostRoot;
|
|
793
|
+
const digest = this.graphIdentity?.(childHostRoot)?.digest;
|
|
794
|
+
if (digest)
|
|
795
|
+
processEnv.VIBES_HOST_GRAPH_LOCK = digest;
|
|
796
|
+
}
|
|
797
|
+
}
|
|
798
|
+
const processCommand = launchPlan?.process ?? resolveProcessCommand(config, config.selfSpawn ? await getRuntimeHostCommands(runtime) : undefined);
|
|
799
|
+
// Preflight: verify command exists before spawning to prevent crash-loops.
|
|
800
|
+
// Async capture (sync spawn blocks the daemon's event loop); resolves the
|
|
801
|
+
// absolute path so spawn cannot disagree with the preflight.
|
|
802
|
+
const resolvedCommand = await whichCommand(runtime, processCommand.command, {
|
|
803
|
+
env: processEnv,
|
|
804
|
+
cwd: processCwd
|
|
805
|
+
});
|
|
806
|
+
if (!resolvedCommand) {
|
|
807
|
+
const message = `Command '${processCommand.command}' not found in PATH for '${config.id}'`;
|
|
808
|
+
this.log.error(message, { processId: config.id });
|
|
809
|
+
await this.markSpawnFailure(config.id, message);
|
|
810
|
+
throw new CapabilityError(message, 'NOT_FOUND', {
|
|
811
|
+
reason: 'pm-command-not-found',
|
|
812
|
+
details: { processId: config.id, command: processCommand.command }
|
|
813
|
+
});
|
|
814
|
+
}
|
|
815
|
+
// RC05: the declared credentials resolve through `resolveCredentialEnv`
|
|
816
|
+
// before anything spawns; a reference that does not resolve fails the
|
|
817
|
+
// start typed. Only the credential variables layer onto the C15 env
|
|
818
|
+
// (they win over a same-named declared or inherited value). Values stay
|
|
819
|
+
// out of argv and out of the stored config (stamped from `config.env`).
|
|
820
|
+
const resolvedCredentials = await attempt(() => resolveProcessCredentials(runtime, config));
|
|
821
|
+
if (!resolvedCredentials.ok) {
|
|
822
|
+
await this.markSpawnFailure(config.id, failureText(resolvedCredentials.failure));
|
|
823
|
+
throw resolvedCredentials.failure;
|
|
824
|
+
}
|
|
825
|
+
const credentials = resolvedCredentials.value;
|
|
826
|
+
const childEnv = credentials ? { ...processEnv, ...credentials.values } : processEnv;
|
|
827
|
+
// Pass the preflight-resolved absolute path so spawn cannot disagree
|
|
828
|
+
// with the preflight about which binary (or whether any) is on PATH.
|
|
829
|
+
const spawned = await attempt(async () => (await getRuntimeExecution(runtime)).spawn({
|
|
830
|
+
command: resolvedCommand, args: processCommand.args,
|
|
831
|
+
cwd: processCwd, env: childEnv, envMode: 'replace',
|
|
832
|
+
stdoutFile: logPaths.stdout, stderrFile: logPaths.stderr
|
|
833
|
+
}));
|
|
834
|
+
if (!spawned.ok) {
|
|
835
|
+
credentials?.audit('failure');
|
|
836
|
+
throw spawned.failure;
|
|
837
|
+
}
|
|
838
|
+
const proc = spawned.value;
|
|
839
|
+
if (proc.pid <= 0) {
|
|
840
|
+
credentials?.audit('failure');
|
|
841
|
+
const message = `Failed to spawn '${config.id}'`;
|
|
842
|
+
await this.markSpawnFailure(config.id, message);
|
|
843
|
+
throw new CapabilityError(message, 'UNAVAILABLE', {
|
|
844
|
+
reason: 'pm-spawn-failed',
|
|
845
|
+
details: { processId: config.id }
|
|
846
|
+
});
|
|
847
|
+
}
|
|
848
|
+
if (credentials) {
|
|
849
|
+
credentials.audit('success');
|
|
850
|
+
this.credentialRedactions.set(config.id, credentials.redact);
|
|
851
|
+
}
|
|
852
|
+
else {
|
|
853
|
+
this.credentialRedactions.delete(config.id);
|
|
854
|
+
}
|
|
855
|
+
proc.unref?.();
|
|
856
|
+
const exitPromise = proc.exited.then(exitOf);
|
|
857
|
+
// Persist config only after successful spawn to avoid config write storms
|
|
858
|
+
// during repeated failed starts (e.g. dependency preflight failures).
|
|
859
|
+
// Stamp the config with VIBES_HOST_ROOT and VIBES_HOST_GRAPH_LOCK so the
|
|
860
|
+
// executable-freshness reconciler can detect when the graph has changed.
|
|
861
|
+
// Merge onto the DECLARED config.env (never the resolved processEnv,
|
|
862
|
+
// which may hold resolved secret values) so other env keys the config
|
|
863
|
+
// declared survive registration.
|
|
864
|
+
const stampedEnv = { ...config.env };
|
|
865
|
+
if (processEnv.VIBES_HOST_ROOT)
|
|
866
|
+
stampedEnv.VIBES_HOST_ROOT = processEnv.VIBES_HOST_ROOT;
|
|
867
|
+
if (processEnv.VIBES_HOST_GRAPH_LOCK)
|
|
868
|
+
stampedEnv.VIBES_HOST_GRAPH_LOCK = processEnv.VIBES_HOST_GRAPH_LOCK;
|
|
869
|
+
// The child's workspace is its launch custody (the admitted root PM bound
|
|
870
|
+
// as its cwd), never a value this daemon inherited.
|
|
871
|
+
if (!stampedEnv.VIBES_WORKSPACE_PATH)
|
|
872
|
+
stampedEnv.VIBES_WORKSPACE_PATH = processCwd;
|
|
873
|
+
const stampedConfig = { ...launchConfig, cwd: config.cwd ?? processCwd, env: stampedEnv };
|
|
874
|
+
await this.store.setConfig({
|
|
875
|
+
...stampedConfig,
|
|
876
|
+
launchProvenance: {
|
|
877
|
+
declaration: ProcessLaunchInputsSchema.parse(config),
|
|
878
|
+
prepared: ProcessLaunchInputsSchema.parse(stampedConfig)
|
|
879
|
+
}
|
|
880
|
+
});
|
|
881
|
+
const configured = await this.loadConfiguredProcessIds();
|
|
882
|
+
const isEphemeral = !configured.has(config.id);
|
|
883
|
+
const now = new Date();
|
|
884
|
+
const shouldResetCount = options?.resetRestartCount ?? true;
|
|
885
|
+
if (shouldResetCount)
|
|
886
|
+
this.tempfailAttempts.delete(config.id);
|
|
887
|
+
const state = {
|
|
888
|
+
id: config.id,
|
|
889
|
+
pid: proc.pid,
|
|
890
|
+
status: 'running',
|
|
891
|
+
startedAt: now,
|
|
892
|
+
lastActivity: now,
|
|
893
|
+
restartCount: (existing?.restartCount ?? 0) + 1,
|
|
894
|
+
consecutiveCrashRestarts: shouldResetCount ? 0 : (existing?.consecutiveCrashRestarts ?? 0),
|
|
895
|
+
retryCount: existing?.retryCount || 0,
|
|
896
|
+
healthStatus: 'unknown',
|
|
897
|
+
socketPath: config.socket || undefined,
|
|
898
|
+
idleTimeoutMs: config.idleTimeoutMs,
|
|
899
|
+
ephemeral: isEphemeral || undefined
|
|
900
|
+
};
|
|
901
|
+
await this.store.set(state);
|
|
902
|
+
this.processes.set(config.id, proc);
|
|
903
|
+
this.monitorProcess(config, proc, exitPromise);
|
|
904
|
+
// Schedule the settle timer so the restart counter resets after
|
|
905
|
+
// the process has been running stably. If the process exits
|
|
906
|
+
// before the timer fires, monitorProcess() clears the timer.
|
|
907
|
+
this.scheduleSettleReset(config, proc.pid);
|
|
908
|
+
if (options?.wait && config.socket) {
|
|
909
|
+
await this.waitForSocketReady(config.socket, options.timeout || 30000, config.id);
|
|
910
|
+
}
|
|
911
|
+
return state;
|
|
912
|
+
}
|
|
913
|
+
/**
|
|
914
|
+
* Monitor process for exit and handle auto-restart
|
|
915
|
+
*/
|
|
916
|
+
monitorProcess(config, proc, exitPromise = proc.exited.then(exitOf)) {
|
|
917
|
+
const settled = this.settleExit(config, proc, exitPromise);
|
|
918
|
+
const exit = { pid: proc.pid, settled };
|
|
919
|
+
this.exits.set(config.id, exit);
|
|
920
|
+
void settled.then(() => {
|
|
921
|
+
if (this.exits.get(config.id) === exit)
|
|
922
|
+
this.exits.delete(config.id);
|
|
923
|
+
});
|
|
924
|
+
}
|
|
925
|
+
/**
|
|
926
|
+
* Wait for the process to exit and handle it. The exit handler's own
|
|
927
|
+
* failures must never surface as an unhandledRejection: daemon.ts treats
|
|
928
|
+
* those as fatal (handleFatalError → process.exit(1)), so a transient SQLite
|
|
929
|
+
* error during exit handling would take down every managed process, the
|
|
930
|
+
* exact single-failure shape the 2026-09-02 incident hardening exists to
|
|
931
|
+
* prevent. They are reported, and a best-effort state marker is left.
|
|
932
|
+
*/
|
|
933
|
+
async settleExit(config, proc, exitPromise) {
|
|
934
|
+
const handled = await attempt(async () => this.handleExit(config, proc, await exitPromise));
|
|
935
|
+
if (handled.ok)
|
|
936
|
+
return;
|
|
937
|
+
const facts = valueFreeFailure(handled.failure);
|
|
938
|
+
// The report and the marker are the last channels this failure has: the
|
|
939
|
+
// runtime's logging or store may be gone (disposal), and nothing further
|
|
940
|
+
// may reject, so a failure of either is dropped here and nowhere else.
|
|
941
|
+
await attempt(async () => this.log.error('exit handler failed', { processId: config.id, exitedPid: proc.pid, failure: facts }));
|
|
942
|
+
// Guarded like every terminal write: a record another writer already
|
|
943
|
+
// committed for this run (stop(), or the handler before it threw) stands.
|
|
944
|
+
const marked = await attempt(() => this.store.updateWhen(config.id, {
|
|
945
|
+
status: 'crashed',
|
|
946
|
+
stoppedAt: new Date(),
|
|
947
|
+
lastActivity: new Date(),
|
|
948
|
+
pid: undefined,
|
|
949
|
+
lastError: `Exit handler error: ${failureText(handled.failure)}`
|
|
950
|
+
}, (current) => !isProcessExited(current) && current.pid === proc.pid));
|
|
951
|
+
if (!marked.ok) {
|
|
952
|
+
await attempt(async () => this.log.error('exit handler best-effort state write also failed', {
|
|
953
|
+
processId: config.id,
|
|
954
|
+
failure: valueFreeFailure(marked.failure)
|
|
955
|
+
}));
|
|
956
|
+
}
|
|
957
|
+
}
|
|
958
|
+
/**
|
|
959
|
+
* Commit this exit's terminal record, deciding its branch from the row as
|
|
960
|
+
* read. The row can change between that read and the write (`stop()` writes
|
|
961
|
+
* `stopping`, or commits `stopped` itself when its bounded wait for this
|
|
962
|
+
* handler expired), so every terminal write is guarded on the row it was
|
|
963
|
+
* decided from: same status, same pid. A refused write wrote nothing; the
|
|
964
|
+
* handler re-reads and decides again, so the run gets exactly one truthful
|
|
965
|
+
* record and a run an operator stopped is never recorded `crashed`.
|
|
966
|
+
*
|
|
967
|
+
* Returns the row a service's own record landed over, with the error it
|
|
968
|
+
* recorded, for restart supervision; `undefined` when nothing is left to
|
|
969
|
+
* supervise (stale handle, a stop's record, a task's record, or a record
|
|
970
|
+
* another writer already committed).
|
|
971
|
+
*/
|
|
972
|
+
async commitExitRecord(config, proc, exit) {
|
|
973
|
+
const { code: exitCode, signal } = exit;
|
|
974
|
+
const crashed = exitCode !== 0;
|
|
975
|
+
let errorMessage;
|
|
976
|
+
let crashDetailRead = false;
|
|
977
|
+
let refused = false;
|
|
978
|
+
for (let state = await this.store.get(config.id); state; state = await this.store.get(config.id)) {
|
|
979
|
+
// Ignore exits from stale subprocess handles after a restart.
|
|
980
|
+
// Without this guard, an older PID exiting can overwrite state for a newer running PID
|
|
981
|
+
// and trigger unintended auto-restart loops.
|
|
982
|
+
if (state.pid && proc.pid && state.pid !== proc.pid) {
|
|
983
|
+
this.log.debug('Ignoring stale subprocess exit', {
|
|
984
|
+
processId: config.id,
|
|
985
|
+
exitedPid: proc.pid,
|
|
986
|
+
activePid: state.pid,
|
|
987
|
+
exitCode
|
|
988
|
+
});
|
|
989
|
+
return undefined;
|
|
990
|
+
}
|
|
991
|
+
if ((state.status === 'stopped' && state.pid === undefined) || (refused && isProcessExited(state))) {
|
|
992
|
+
// Another writer already committed this run's terminal record:
|
|
993
|
+
// stop(), when this exit was not observed within its bound. The
|
|
994
|
+
// record stays the only one; the late exit only clears a socket
|
|
995
|
+
// the child left behind.
|
|
996
|
+
this.log.debug('Late exit of a run whose stop is already committed', { processId: config.id, exitCode });
|
|
997
|
+
if (exitCode !== 0 && state.socketPath) {
|
|
998
|
+
await removeSocket(this.getRuntime(), state.socketPath);
|
|
999
|
+
await this.store.update(config.id, { staleSocket: true });
|
|
1000
|
+
}
|
|
1001
|
+
this.processes.delete(config.id);
|
|
1002
|
+
return undefined;
|
|
1003
|
+
}
|
|
1004
|
+
const read = state;
|
|
1005
|
+
const unchanged = (current) => current.status === read.status && current.pid === read.pid;
|
|
1006
|
+
if (read.status === 'stopping') {
|
|
1007
|
+
// An operator stop is ending this run: it awaits this record. A
|
|
1008
|
+
// child that did not exit cleanly left its socket behind; clear it
|
|
1009
|
+
// before the record commits, so an awaiter never sees a stale path.
|
|
1010
|
+
const staleSocket = exitCode !== 0 && read.socketPath ? read.socketPath : undefined;
|
|
1011
|
+
if (staleSocket)
|
|
1012
|
+
await removeSocket(this.getRuntime(), staleSocket);
|
|
1013
|
+
const landed = await this.store.updateWhen(config.id, {
|
|
1014
|
+
status: 'stopped',
|
|
1015
|
+
stoppedAt: new Date(),
|
|
1016
|
+
lastActivity: new Date(),
|
|
1017
|
+
exitCode,
|
|
1018
|
+
signal,
|
|
1019
|
+
pid: undefined,
|
|
1020
|
+
staleSocket: staleSocket ? true : undefined
|
|
1021
|
+
}, unchanged);
|
|
1022
|
+
if (landed) {
|
|
1023
|
+
this.processes.delete(config.id);
|
|
1024
|
+
return undefined;
|
|
1025
|
+
}
|
|
1026
|
+
}
|
|
1027
|
+
else if (config.task) {
|
|
1028
|
+
const landed = await this.store.updateWhen(config.id, {
|
|
1029
|
+
status: exitCode === 0 ? 'pass' : 'fail',
|
|
1030
|
+
stoppedAt: new Date(),
|
|
1031
|
+
lastActivity: new Date(),
|
|
1032
|
+
exitCode,
|
|
1033
|
+
signal,
|
|
1034
|
+
lastError: exitCode !== 0 ? `Exit code ${exitCode}` : undefined
|
|
1035
|
+
}, unchanged);
|
|
1036
|
+
if (landed) {
|
|
1037
|
+
this.processes.delete(config.id);
|
|
1038
|
+
return undefined;
|
|
1039
|
+
}
|
|
1040
|
+
}
|
|
1041
|
+
else {
|
|
1042
|
+
if (crashed && !crashDetailRead) {
|
|
1043
|
+
crashDetailRead = true;
|
|
1044
|
+
errorMessage = await this.crashDetail(config.id, exitCode);
|
|
1045
|
+
}
|
|
1046
|
+
const landed = await this.store.updateWhen(config.id, {
|
|
1047
|
+
status: config.runOnce && !crashed ? 'completed' : crashed ? 'crashed' : 'stopped',
|
|
1048
|
+
stoppedAt: new Date(),
|
|
1049
|
+
lastActivity: new Date(),
|
|
1050
|
+
exitCode,
|
|
1051
|
+
signal,
|
|
1052
|
+
pid: undefined,
|
|
1053
|
+
lastError: errorMessage
|
|
1054
|
+
}, unchanged);
|
|
1055
|
+
if (landed)
|
|
1056
|
+
return { state: read, errorMessage };
|
|
1057
|
+
}
|
|
1058
|
+
// The row changed after this handler read it: decide again from the row as it stands.
|
|
1059
|
+
refused = true;
|
|
1060
|
+
}
|
|
1061
|
+
return undefined;
|
|
1062
|
+
}
|
|
1063
|
+
/** `Exit code N`, with a bounded, redacted excerpt of the child's last stderr lines when readable. */
|
|
1064
|
+
async crashDetail(processId, exitCode) {
|
|
1065
|
+
const tail = await attempt(async () => {
|
|
1066
|
+
const logPaths = await this.getLogPaths(processId);
|
|
1067
|
+
return readTail(await this.hostFiles(), logPaths.stderr, CRASH_DETAIL_TAIL_BYTES);
|
|
1068
|
+
});
|
|
1069
|
+
if (!tail.ok) {
|
|
1070
|
+
this.log.debug('Failed to read stderr log for crash details', {
|
|
1071
|
+
processId,
|
|
1072
|
+
failure: valueFreeFailure(tail.failure)
|
|
1073
|
+
});
|
|
1074
|
+
return `Exit code ${exitCode}`;
|
|
1075
|
+
}
|
|
1076
|
+
const lastLines = tail.value
|
|
1077
|
+
.trim()
|
|
1078
|
+
.split('\n')
|
|
1079
|
+
.slice(-5)
|
|
1080
|
+
.filter((l) => l.trim());
|
|
1081
|
+
if (lastLines.length === 0)
|
|
1082
|
+
return `Exit code ${exitCode}`;
|
|
1083
|
+
// Persisted and printed by `pm list`: a bounded excerpt with the
|
|
1084
|
+
// credentials this daemon injected (and credential shapes) removed.
|
|
1085
|
+
const excerpt = redactedExcerpt(lastLines.join(' | '), {
|
|
1086
|
+
maxChars: 400,
|
|
1087
|
+
secrets: this.credentialRedactions.get(processId) ?? []
|
|
1088
|
+
});
|
|
1089
|
+
return `Exit code ${exitCode}: ${excerpt}`;
|
|
1090
|
+
}
|
|
1091
|
+
/**
|
|
1092
|
+
* One process exit: stale-handle guard, state write, socket cleanup, and
|
|
1093
|
+
* the restart supervision. While PM holds the child's handle this is the
|
|
1094
|
+
* single writer of the run's terminal record: a run `stop()` put in
|
|
1095
|
+
* `stopping` commits exactly one record here, `stopped` with the real exit.
|
|
1096
|
+
*/
|
|
1097
|
+
async handleExit(config, proc, exit) {
|
|
1098
|
+
// Always clear the settle timer for this process id on exit —
|
|
1099
|
+
// a stale timer from a previous incarnation could otherwise
|
|
1100
|
+
// reset the restart counter of the new one mid-crash-loop.
|
|
1101
|
+
this.clearSettleTimer(config.id);
|
|
1102
|
+
const committed = await this.commitExitRecord(config, proc, exit);
|
|
1103
|
+
if (!committed)
|
|
1104
|
+
return;
|
|
1105
|
+
const { state, errorMessage } = committed;
|
|
1106
|
+
const { code: exitCode } = exit;
|
|
1107
|
+
const crashed = exitCode !== 0;
|
|
1108
|
+
// CRITICAL FIX (Issue 4.4): Port-forward processes now use same restart logic as others
|
|
1109
|
+
// Previously they had special 2s sleep here that didn't participate in auto-restart backoff
|
|
1110
|
+
// Now they rely on the auto-restart loop below which applies proper exponential backoff
|
|
1111
|
+
this.processes.delete(config.id);
|
|
1112
|
+
if (crashed && state.socketPath) {
|
|
1113
|
+
await removeSocket(this.getRuntime(), state.socketPath);
|
|
1114
|
+
await this.store.update(config.id, { staleSocket: true });
|
|
1115
|
+
}
|
|
1116
|
+
const tempfail = exitCode === EX_TEMPFAIL;
|
|
1117
|
+
if (!tempfail)
|
|
1118
|
+
this.tempfailAttempts.delete(config.id);
|
|
1119
|
+
if (config.autoRestart && tempfail) {
|
|
1120
|
+
if (state.status === 'stopped')
|
|
1121
|
+
return;
|
|
1122
|
+
const retryAttempt = (this.tempfailAttempts.get(config.id) ?? 0) + 1;
|
|
1123
|
+
this.tempfailAttempts.set(config.id, retryAttempt);
|
|
1124
|
+
const delay = tempfailRestartDelay(retryAttempt, config.restartDelay, this.tempfailMinDelayMs);
|
|
1125
|
+
this.log.warn(`${config.id} exited EX_TEMPFAIL; retrying without counting toward maxRestarts`, {
|
|
1126
|
+
attempt: retryAttempt,
|
|
1127
|
+
delayMs: delay
|
|
1128
|
+
});
|
|
1129
|
+
await this.store.update(config.id, {
|
|
1130
|
+
lastError: `${errorMessage} (EX_TEMPFAIL: retry ${retryAttempt} in ${Math.round(delay / 1000)}s)`
|
|
1131
|
+
});
|
|
1132
|
+
await this.restartAfterBackoff(config, proc.pid, delay);
|
|
1133
|
+
return;
|
|
1134
|
+
}
|
|
1135
|
+
if (config.autoRestart && crashed) {
|
|
1136
|
+
if (state.status === 'stopped') {
|
|
1137
|
+
this.log.debug('Process intentionally stopped, skipping auto-restart', {
|
|
1138
|
+
processId: config.id
|
|
1139
|
+
});
|
|
1140
|
+
return;
|
|
1141
|
+
}
|
|
1142
|
+
// Supervision (RC11 class: the daemon restarting a child it owns):
|
|
1143
|
+
// the declared policy (`config.plugins.pm.supervision`, the
|
|
1144
|
+
// process's own `restartDelay`/`maxRestarts` winning), paused on
|
|
1145
|
+
// a tracked, disposal-aborted lifecycle delay (RC07).
|
|
1146
|
+
const policy = processRestartPolicy(await readSupervision(this.getRuntime()), config);
|
|
1147
|
+
const nextAttempt = state.consecutiveCrashRestarts + 1;
|
|
1148
|
+
const maxRestarts = policy.maxConsecutive;
|
|
1149
|
+
if (mayRestart(policy, nextAttempt)) {
|
|
1150
|
+
const delay = restartDelayMs(policy, nextAttempt);
|
|
1151
|
+
this.log.info(`Auto-restarting ${config.id}`, {
|
|
1152
|
+
attempt: nextAttempt,
|
|
1153
|
+
maxRestarts,
|
|
1154
|
+
delayMs: delay
|
|
1155
|
+
});
|
|
1156
|
+
await this.restartAfterBackoff(config, proc.pid, delay, async () => {
|
|
1157
|
+
await this.store.update(config.id, { consecutiveCrashRestarts: nextAttempt });
|
|
1158
|
+
});
|
|
1159
|
+
}
|
|
1160
|
+
else {
|
|
1161
|
+
this.log.warn(`${config.id} exceeded max restarts`, { maxRestarts });
|
|
1162
|
+
await this.store.update(config.id, {
|
|
1163
|
+
lastError: `${errorMessage} (max restarts exceeded)`
|
|
1164
|
+
});
|
|
1165
|
+
}
|
|
1166
|
+
}
|
|
1167
|
+
}
|
|
1168
|
+
/**
|
|
1169
|
+
* Stop a process
|
|
1170
|
+
*/
|
|
1171
|
+
/**
|
|
1172
|
+
* Adopt a live process already serving `config.socket`: the serve singleton
|
|
1173
|
+
* records its holder in `<socket>.pid`. Only a live holder whose command line
|
|
1174
|
+
* is this config's own (PM's ownership check) is adopted; anything else is
|
|
1175
|
+
* left for the socket owner to refuse.
|
|
1176
|
+
*/
|
|
1177
|
+
async adoptServeHolder(config) {
|
|
1178
|
+
const socket = config.socket;
|
|
1179
|
+
if (!socket)
|
|
1180
|
+
return null;
|
|
1181
|
+
const holderFile = await attempt(async () => PidFileTextSchema.parse(await (await this.hostFiles()).readFile(`${socket}.pid`, 'utf-8')));
|
|
1182
|
+
if (!holderFile.ok) {
|
|
1183
|
+
if (hasErrnoCode(holderFile.failure) && holderFile.failure.code === 'ENOENT')
|
|
1184
|
+
return null;
|
|
1185
|
+
throw holderFile.failure;
|
|
1186
|
+
}
|
|
1187
|
+
const pid = Number.parseInt(holderFile.value.trim(), 10);
|
|
1188
|
+
if (!Number.isFinite(pid) || pid <= 0)
|
|
1189
|
+
return null;
|
|
1190
|
+
if (!(await isProcessRunning(this.getRuntime(), pid)))
|
|
1191
|
+
return null;
|
|
1192
|
+
const tokens = [config.command, ...(config.args || [])].filter(Boolean);
|
|
1193
|
+
const ownership = await verifyProcessOwnership(this.getRuntime(), pid, config.id, tokens);
|
|
1194
|
+
if (!ownership.owned)
|
|
1195
|
+
return null;
|
|
1196
|
+
this.log.warn('Adopting the live serve holder instead of spawning a duplicate', {
|
|
1197
|
+
processId: config.id,
|
|
1198
|
+
pid,
|
|
1199
|
+
socket
|
|
1200
|
+
});
|
|
1201
|
+
// The holder may have no state row (stale cleanup removes a terminal row
|
|
1202
|
+
// and its config; config reload re-registers only the config): upsert.
|
|
1203
|
+
await this.store.upsert(config.id, {
|
|
1204
|
+
status: 'running',
|
|
1205
|
+
pid,
|
|
1206
|
+
socketPath: socket,
|
|
1207
|
+
startedAt: new Date(),
|
|
1208
|
+
lastActivity: new Date()
|
|
1209
|
+
});
|
|
1210
|
+
return (await this.store.get(config.id)) ?? null;
|
|
1211
|
+
}
|
|
1212
|
+
async stop(processId, options) {
|
|
1213
|
+
const requested = options?.run ? ProcessRunSchema.parse(options.run) : undefined;
|
|
1214
|
+
const assertRequestedRun = (current) => {
|
|
1215
|
+
if (requested && (!current || !isSameRun(current, requested)))
|
|
1216
|
+
throw new CapabilityError('The requested process run was superseded.', 'CONFLICT', {
|
|
1217
|
+
reason: 'pm-stop-run-superseded', details: { processId }
|
|
1218
|
+
});
|
|
1219
|
+
};
|
|
1220
|
+
const state = await this.store.get(processId);
|
|
1221
|
+
assertRequestedRun(state);
|
|
1222
|
+
// Only the admitted run may lose its settle timer.
|
|
1223
|
+
this.clearSettleTimer(processId);
|
|
1224
|
+
if (!state?.pid) {
|
|
1225
|
+
throw new CapabilityError(`Process ${processId} is not running`, 'CONFLICT', {
|
|
1226
|
+
reason: 'process-not-running',
|
|
1227
|
+
details: { processId }
|
|
1228
|
+
});
|
|
1229
|
+
}
|
|
1230
|
+
// Every write below is guarded against the row as it stands at the write:
|
|
1231
|
+
// the child may exit on its own while stop() awaits (the liveness probe,
|
|
1232
|
+
// the ownership check, the kill), and its exit handler's terminal record
|
|
1233
|
+
// is then the run's one record. stop() never writes over it.
|
|
1234
|
+
const sameRun = (current) => current.pid === state.pid && (!state.startedAt || isSameRun(current, { startedAt: state.startedAt }));
|
|
1235
|
+
const live = (current) => sameRun(current) && !isProcessExited(current);
|
|
1236
|
+
const handle = this.processes.get(processId);
|
|
1237
|
+
const forget = () => { if (this.processes.get(processId) === handle)
|
|
1238
|
+
this.processes.delete(processId); };
|
|
1239
|
+
// PM's handle on this run's child, captured before any await: the entry
|
|
1240
|
+
// leaves the map once its exit handling settles. While it is held, that
|
|
1241
|
+
// handler is the single writer of the run's terminal record, so every
|
|
1242
|
+
// branch below awaits it before its own guarded write.
|
|
1243
|
+
const held = this.exits.get(processId);
|
|
1244
|
+
const exit = held && held.pid === state.pid ? held : undefined;
|
|
1245
|
+
const running = await isProcessRunning(this.getRuntime(), state.pid);
|
|
1246
|
+
if (requested)
|
|
1247
|
+
assertRequestedRun(await this.store.get(processId));
|
|
1248
|
+
if (!running) {
|
|
1249
|
+
// A dead pid PM holds a handle for: its exit handler may be in flight
|
|
1250
|
+
// (its read or write not yet landed). It commits the real record.
|
|
1251
|
+
if (exit)
|
|
1252
|
+
await this.awaitExitHandled(processId, exit.settled);
|
|
1253
|
+
await this.store.updateWhen(processId, { status: 'stopped', stoppedAt: new Date(), lastActivity: new Date(), pid: undefined }, live);
|
|
1254
|
+
forget();
|
|
1255
|
+
return;
|
|
1256
|
+
}
|
|
1257
|
+
const config = await this.store.getConfig(processId);
|
|
1258
|
+
if (requested)
|
|
1259
|
+
assertRequestedRun(await this.store.get(processId));
|
|
1260
|
+
const tokens = config ? [config.command, ...(config.args || [])].filter(Boolean) : [processId];
|
|
1261
|
+
const ownership = await verifyProcessOwnership(this.getRuntime(), state.pid, processId, tokens);
|
|
1262
|
+
if (!ownership.owned) {
|
|
1263
|
+
this.log.warn('PID no longer belongs to process', { processId, pid: state.pid });
|
|
1264
|
+
// A dead pid fails the ownership check too: an in-flight exit handler
|
|
1265
|
+
// still commits this run's record first.
|
|
1266
|
+
if (exit)
|
|
1267
|
+
await this.awaitExitHandled(processId, exit.settled);
|
|
1268
|
+
await this.store.updateWhen(processId, {
|
|
1269
|
+
status: 'stopped',
|
|
1270
|
+
stoppedAt: new Date(),
|
|
1271
|
+
lastActivity: new Date(),
|
|
1272
|
+
pid: undefined,
|
|
1273
|
+
lastError: `PID ${state.pid} reused`
|
|
1274
|
+
}, live);
|
|
1275
|
+
forget();
|
|
1276
|
+
return;
|
|
1277
|
+
}
|
|
1278
|
+
// A run whose terminal record landed while stop() awaited stays ended.
|
|
1279
|
+
const stopping = await this.store.updateWhen(processId, { status: 'stopping' }, live);
|
|
1280
|
+
if (!stopping) {
|
|
1281
|
+
const current = await this.store.get(processId);
|
|
1282
|
+
if (current && !sameRun(current) && !isProcessExited(current)) {
|
|
1283
|
+
throw new CapabilityError('The requested process run was superseded.', 'CONFLICT', {
|
|
1284
|
+
reason: 'pm-stop-run-superseded', details: { processId }
|
|
1285
|
+
});
|
|
1286
|
+
}
|
|
1287
|
+
forget();
|
|
1288
|
+
return;
|
|
1289
|
+
}
|
|
1290
|
+
const timeout = options?.timeout || 5000;
|
|
1291
|
+
if (options?.force) {
|
|
1292
|
+
await killProcessTree(this.getRuntime(), state.pid, processId);
|
|
1293
|
+
}
|
|
1294
|
+
else {
|
|
1295
|
+
// Graceful path must reap the whole tree — spawn'd grandchildren
|
|
1296
|
+
// (e.g. typescript-language-server, tsserver.js under the LSP runtime)
|
|
1297
|
+
// don't die when the parent gets SIGTERM and are reparented to init.
|
|
1298
|
+
await gracefulKillProcessTree(this.getRuntime(), state.pid, processId, timeout);
|
|
1299
|
+
}
|
|
1300
|
+
// PM holds this child's handle: its exit handler is the single writer of
|
|
1301
|
+
// the run's terminal record (`stopped` with the real exit code). When it
|
|
1302
|
+
// settled without committing one (it ignored the exit as stale), or there
|
|
1303
|
+
// is no handle (an adopted process), or its exit was not observed within
|
|
1304
|
+
// the bound, stop() commits `stopped` itself, still only over a live row.
|
|
1305
|
+
if (exit)
|
|
1306
|
+
await this.awaitExitHandled(processId, exit.settled);
|
|
1307
|
+
await this.store.updateWhen(processId, { status: 'stopped', stoppedAt: new Date(), lastActivity: new Date(), pid: undefined }, live);
|
|
1308
|
+
forget();
|
|
1309
|
+
}
|
|
1310
|
+
/**
|
|
1311
|
+
* Await the killed child's exit handling, at most the restart exit bound:
|
|
1312
|
+
* a kill the child survived must not hang its stop forever.
|
|
1313
|
+
*/
|
|
1314
|
+
async awaitExitHandled(processId, settled) {
|
|
1315
|
+
const waited = await attempt(() => this.getRuntime().lifecycle.wait(() => settled, {
|
|
1316
|
+
timeoutMs: this.restartExitTimeoutMs,
|
|
1317
|
+
reason: 'pm-stop-exit-handled'
|
|
1318
|
+
}));
|
|
1319
|
+
if (waited.ok)
|
|
1320
|
+
return;
|
|
1321
|
+
if (!isWaitTimeout(waited.failure))
|
|
1322
|
+
throw waited.failure;
|
|
1323
|
+
this.log.warn('Stopped child exit was not observed within the bound; recording the stop', {
|
|
1324
|
+
processId,
|
|
1325
|
+
timeoutMs: this.restartExitTimeoutMs
|
|
1326
|
+
});
|
|
1327
|
+
}
|
|
1328
|
+
/**
|
|
1329
|
+
* Pause `delay` on the handed runtime's lifecycle (RC07: tracked, aborted
|
|
1330
|
+
* at disposal), then start `config` again unless a newer instance already
|
|
1331
|
+
* runs. `beforeStart` records the attempt only when the restart proceeds.
|
|
1332
|
+
*
|
|
1333
|
+
* Another starter (an operator's `pm start`, a preset, the health
|
|
1334
|
+
* monitor's kill of the previous incarnation) may have brought a NEW
|
|
1335
|
+
* instance up while this waited. Starting again would kill it as a port
|
|
1336
|
+
* orphan, and its exit would schedule yet another restart, so two loops
|
|
1337
|
+
* ping-pong (pm log 2026-08-28: mcp-server-dev attempts 1,2,3 interleaved
|
|
1338
|
+
* with 1,4,2,3,5,4,6,5,7,6, each killing the other's child on port 3000).
|
|
1339
|
+
* The exited pid is ours; a different live pid is someone else's success.
|
|
1340
|
+
*/
|
|
1341
|
+
async restartAfterBackoff(config, exitedPid, delay, beforeStart) {
|
|
1342
|
+
await this.getRuntime().lifecycle.delay(delay);
|
|
1343
|
+
const latest = await this.store.get(config.id);
|
|
1344
|
+
if (latest?.status === 'running' &&
|
|
1345
|
+
latest.pid !== undefined &&
|
|
1346
|
+
latest.pid !== exitedPid &&
|
|
1347
|
+
(await isProcessRunning(this.getRuntime(), latest.pid))) {
|
|
1348
|
+
this.log.info(`Skipping auto-restart of ${config.id}: a newer instance is already running`, {
|
|
1349
|
+
pid: latest.pid,
|
|
1350
|
+
exitedPid
|
|
1351
|
+
});
|
|
1352
|
+
return;
|
|
1353
|
+
}
|
|
1354
|
+
await beforeStart?.();
|
|
1355
|
+
const restarted = await attempt(() => this.start(config, { resetRestartCount: false }));
|
|
1356
|
+
if (!restarted.ok) {
|
|
1357
|
+
this.log.error(`Auto-restart failed for ${config.id}`, { failure: valueFreeFailure(restarted.failure) });
|
|
1358
|
+
await this.store.update(config.id, { lastError: `Restart failed: ${failureText(restarted.failure)}` });
|
|
1359
|
+
}
|
|
1360
|
+
}
|
|
1361
|
+
/**
|
|
1362
|
+
* Restart a process
|
|
1363
|
+
*/
|
|
1364
|
+
async restart(processId, options) {
|
|
1365
|
+
return this.store.withProcessAdmission(processId, async () => {
|
|
1366
|
+
await this.store.assertTaskReleaseAvailable(processId);
|
|
1367
|
+
return this.restartAdmitted(processId, options);
|
|
1368
|
+
});
|
|
1369
|
+
}
|
|
1370
|
+
async restartAdmitted(processId, options) {
|
|
1371
|
+
const config = await this.store.getConfig(processId);
|
|
1372
|
+
if (!config) {
|
|
1373
|
+
throw new CapabilityError(`Process config not found: ${processId}`, 'NOT_FOUND', {
|
|
1374
|
+
reason: 'pm-process-not-registered',
|
|
1375
|
+
details: { processId }
|
|
1376
|
+
});
|
|
1377
|
+
}
|
|
1378
|
+
const state = await this.store.get(processId);
|
|
1379
|
+
if (state?.pid && (await isProcessRunning(this.getRuntime(), state.pid))) {
|
|
1380
|
+
await this.stop(processId);
|
|
1381
|
+
if (!(await waitForProcessExit(this.getRuntime(), state.pid, this.restartExitTimeoutMs))) {
|
|
1382
|
+
throw new CapabilityError(`Failed to stop ${processId} (PID ${state.pid}) before restart`, 'UNAVAILABLE', {
|
|
1383
|
+
reason: 'pm-process-stop-failed',
|
|
1384
|
+
details: { processId, pid: state.pid }
|
|
1385
|
+
});
|
|
1386
|
+
}
|
|
1387
|
+
}
|
|
1388
|
+
return this.start(config, options);
|
|
1389
|
+
}
|
|
1390
|
+
}
|
|
1391
|
+
//# sourceMappingURL=lifecycle.js.map
|