@pasko70/pibo 1.1.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +106 -254
- package/context/codex-base-prompt.md +4 -0
- package/context/compute-worker.md +23 -0
- package/context/pibo-native-tooling.md +18 -0
- package/context/pibo-system-prompt.md +69 -8
- package/dist/api/simple-agent-api.js +136 -0
- package/dist/app-context.js +4 -0
- package/dist/apps/chat/agent-profiles.js +18 -3
- package/dist/apps/chat/agent-store.js +113 -16
- package/dist/apps/chat/chat-api-routes.js +311 -0
- package/dist/apps/chat/chat-capability-routes.js +90 -0
- package/dist/apps/chat/chat-files.js +178 -0
- package/dist/apps/chat/chat-request-normalizers.js +681 -0
- package/dist/apps/chat/chat-settings-routes.js +75 -0
- package/dist/apps/chat/chat-trace-helpers.js +94 -0
- package/dist/apps/chat/chat-user-skill-routes.js +149 -0
- package/dist/apps/chat/cron-api.js +213 -0
- package/dist/apps/chat/data/chat-data-mappers.js +74 -0
- package/dist/apps/chat/data/event-command-service.js +75 -0
- package/dist/apps/chat/data/navigation-query-service.js +11 -0
- package/dist/apps/chat/data/project-service.js +844 -0
- package/dist/apps/chat/data/read-state-service.js +42 -0
- package/dist/apps/chat/data/room-service.js +52 -0
- package/dist/apps/chat/data/session-query-service.js +63 -0
- package/dist/apps/chat/data/timeline-query-service.js +96 -0
- package/dist/apps/chat/event-log.js +1 -307
- package/dist/apps/chat/model-catalog.js +7 -2
- package/dist/apps/chat/output-compactor.js +126 -0
- package/dist/apps/chat/output-event-policy.js +17 -0
- package/dist/apps/chat/project-workflow-human-actions.js +347 -0
- package/dist/apps/chat/project-workflow-sessions.js +260 -0
- package/dist/apps/chat/provider-auth-actions.js +43 -0
- package/dist/apps/chat/ralph-api.js +156 -0
- package/dist/apps/chat/read-model.js +1 -218
- package/dist/apps/chat/rooms.js +1 -321
- package/dist/apps/chat/static-assets.js +996 -0
- package/dist/apps/chat/stream.js +29 -6
- package/dist/apps/chat/trace.js +179 -1003
- package/dist/apps/chat/types/event-store.js +1 -0
- package/dist/apps/chat/types/read-model.js +1 -0
- package/dist/apps/chat/types/rooms.js +36 -0
- package/dist/apps/chat/web-app.js +3131 -1959
- package/dist/apps/chat/workflow-catalog.js +572 -0
- package/dist/apps/chat/workflow-edge-compatibility.js +51 -0
- package/dist/apps/chat/workflow-json-schema-validation.js +335 -0
- package/dist/apps/chat/workflow-persistence-model.js +140 -0
- package/dist/apps/chat/workflow-persistence.js +633 -0
- package/dist/apps/chat/workflow-registered-ref-params.js +130 -0
- package/dist/apps/chat/workflow-registered-ref-pickers.js +179 -0
- package/dist/apps/chat/workflow-registered-ref-validation.js +210 -0
- package/dist/apps/chat/workflow-v2-security-validation.js +93 -0
- package/dist/apps/chat/workflow-validation-helpers.js +114 -0
- package/dist/apps/chat-ui/assets/{dist-CNLWH2qh.js → dist-B4lw9z4F.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-8e4L8ciw.js → dist-BbTaHWON.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-CMZOa5ik.js → dist-BcT_c1EJ.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-DNcnQRPF.js → dist-CGINd7XU.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-CqqUC8Ce.js → dist-CrBzZkUp.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-D2N4-LIc.js → dist-CyyISotB.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-CUqpST5w.js → dist-DFbnFNpX.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-CspjOeBj.js → dist-DGLWQLX8.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-B7bbI3Qz.js → dist-DfcIkFSN.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-v4pjHlB7.js → dist-sKDHTwaT.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-D9L4MSRF.js → dist-y9D6la48.js} +1 -1
- package/dist/apps/chat-ui/assets/index-C25VYnyb.css +1 -0
- package/dist/apps/chat-ui/assets/index-CUkuvI3v.js +165 -0
- package/dist/apps/chat-ui/assets/pwa-images/android/launchericon-144x144.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/android/launchericon-192x192.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/android/launchericon-48x48.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/android/launchericon-512x512.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/android/launchericon-72x72.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/android/launchericon-96x96.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/ios/100.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/ios/1024.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/ios/114.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/ios/120.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/ios/128.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/ios/144.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/ios/152.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/ios/16.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/ios/167.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/ios/180.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/ios/192.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/ios/20.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/ios/256.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/ios/29.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/ios/32.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/ios/40.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/ios/50.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/ios/512.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/ios/57.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/ios/58.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/ios/60.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/ios/64.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/ios/72.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/ios/76.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/ios/80.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/ios/87.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/windows/LargeTile.scale-100.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/windows/LargeTile.scale-125.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/windows/LargeTile.scale-150.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/windows/LargeTile.scale-200.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/windows/LargeTile.scale-400.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/windows/SmallTile.scale-100.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/windows/SmallTile.scale-125.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/windows/SmallTile.scale-150.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/windows/SmallTile.scale-200.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/windows/SmallTile.scale-400.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/windows/SplashScreen.scale-100.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/windows/SplashScreen.scale-125.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/windows/SplashScreen.scale-150.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/windows/SplashScreen.scale-200.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/windows/SplashScreen.scale-400.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/windows/Square150x150Logo.scale-100.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/windows/Square150x150Logo.scale-125.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/windows/Square150x150Logo.scale-150.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/windows/Square150x150Logo.scale-200.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/windows/Square150x150Logo.scale-400.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.altform-lightunplated_targetsize-16.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.altform-lightunplated_targetsize-20.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.altform-lightunplated_targetsize-24.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.altform-lightunplated_targetsize-256.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.altform-lightunplated_targetsize-30.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.altform-lightunplated_targetsize-32.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.altform-lightunplated_targetsize-36.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.altform-lightunplated_targetsize-40.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.altform-lightunplated_targetsize-44.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.altform-lightunplated_targetsize-48.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.altform-lightunplated_targetsize-60.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.altform-lightunplated_targetsize-64.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.altform-lightunplated_targetsize-72.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.altform-lightunplated_targetsize-80.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.altform-lightunplated_targetsize-96.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.altform-unplated_targetsize-16.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.altform-unplated_targetsize-20.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.altform-unplated_targetsize-24.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.altform-unplated_targetsize-256.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.altform-unplated_targetsize-30.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.altform-unplated_targetsize-32.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.altform-unplated_targetsize-36.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.altform-unplated_targetsize-40.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.altform-unplated_targetsize-44.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.altform-unplated_targetsize-48.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.altform-unplated_targetsize-60.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.altform-unplated_targetsize-64.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.altform-unplated_targetsize-72.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.altform-unplated_targetsize-80.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.altform-unplated_targetsize-96.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.scale-100.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.scale-125.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.scale-150.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.scale-200.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.scale-400.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.targetsize-16.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.targetsize-20.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.targetsize-24.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.targetsize-256.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.targetsize-30.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.targetsize-32.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.targetsize-36.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.targetsize-40.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.targetsize-44.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.targetsize-48.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.targetsize-60.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.targetsize-64.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.targetsize-72.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.targetsize-80.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.targetsize-96.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/windows/StoreLogo.scale-100.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/windows/StoreLogo.scale-125.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/windows/StoreLogo.scale-150.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/windows/StoreLogo.scale-200.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/windows/StoreLogo.scale-400.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/windows/Wide310x150Logo.scale-100.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/windows/Wide310x150Logo.scale-125.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/windows/Wide310x150Logo.scale-150.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/windows/Wide310x150Logo.scale-200.png +0 -0
- package/dist/apps/chat-ui/assets/pwa-images/windows/Wide310x150Logo.scale-400.png +0 -0
- package/dist/apps/chat-ui/index.html +8 -3
- package/dist/apps/chat-ui/manifest.webmanifest +25 -0
- package/dist/apps/chat-ui/sw.js +41 -0
- package/dist/apps/cli-ui/InkSessionApp.js +1218 -0
- package/dist/apps/cli-ui/InkTerminalLine.js +53 -0
- package/dist/apps/cli-ui/InkTerminalRow.js +304 -0
- package/dist/apps/cli-ui/InkTerminalView.js +25 -0
- package/dist/apps/cli-ui/cliSessionsCommand.js +232 -0
- package/dist/apps/cli-ui/index.js +8 -0
- package/dist/apps/cli-ui/inkColors.js +67 -0
- package/dist/apps/cli-ui/inkJson.js +244 -0
- package/dist/apps/cli-ui/inkMarkdown.js +122 -0
- package/dist/apps/context-files-ui/assets/{dist-DFi2YGux.js → dist-BOiGdrG-.js} +1 -1
- package/dist/apps/context-files-ui/assets/{dist-DyfSeBMu.js → dist-DK01b7x4.js} +1 -1
- package/dist/apps/context-files-ui/assets/{dist-CwbH_3RN.js → dist-DPG9jOQ-.js} +1 -1
- package/dist/apps/context-files-ui/assets/{dist-dTBsFYAl.js → dist-Dp5AH00p.js} +1 -1
- package/dist/apps/context-files-ui/assets/{dist-CxRLRmMx.js → dist-DqYw0LH7.js} +1 -1
- package/dist/apps/context-files-ui/assets/{dist-MyZgX9K2.js → dist-TF5iO5ML.js} +1 -1
- package/dist/apps/context-files-ui/assets/{dist-DQXzt2Ng.js → dist-TbjAhles.js} +1 -1
- package/dist/apps/context-files-ui/assets/{dist-YwR9dpb-.js → dist-ZsBbt0uY.js} +1 -1
- package/dist/apps/context-files-ui/assets/{dist-CKQF1zEu.js → dist-kmsvtHkH.js} +1 -1
- package/dist/apps/context-files-ui/assets/{dist-BJW3917N.js → dist-vnd7PMu3.js} +1 -1
- package/dist/apps/context-files-ui/assets/{index-BwRDoHMC.css → index-B92tL3Pp.css} +1 -1
- package/dist/apps/context-files-ui/assets/{index-GwvjXytt.js → index-BhAWD3dv.js} +2 -2
- package/dist/apps/context-files-ui/index.html +2 -2
- package/dist/auth/better-auth.js +2 -1
- package/dist/auth/login-actions.js +251 -0
- package/dist/auth/openai-codex-usage.js +147 -0
- package/dist/bin/pibo.js +0 -0
- package/dist/bin/rg.js +15 -0
- package/dist/cli-session/fakeSessionSource.js +804 -0
- package/dist/cli-session/index.js +3 -0
- package/dist/cli-session/localSessionSource.js +1144 -0
- package/dist/cli-session/sessionSource.js +13 -0
- package/dist/cli.js +142 -14
- package/dist/compute/cli.js +415 -0
- package/dist/compute/docker.js +827 -0
- package/dist/compute/resource-health.js +333 -0
- package/dist/compute/resource-policy.js +98 -0
- package/dist/config/config.js +9 -5
- package/dist/core/context-build.js +677 -0
- package/dist/core/model-defaults.js +51 -9
- package/dist/core/pibo-home.js +8 -0
- package/dist/core/profiles.js +48 -0
- package/dist/core/provider-telemetry.js +222 -0
- package/dist/core/routed-session.js +441 -47
- package/dist/core/runtime-telemetry.js +853 -0
- package/dist/core/runtime.js +103 -15
- package/dist/core/session-errors.js +47 -0
- package/dist/core/session-model.js +39 -0
- package/dist/core/session-router.js +292 -62
- package/dist/core/shared-app.js +17 -0
- package/dist/core/skill-expansion.js +43 -0
- package/dist/core/system-prompt-template.js +9 -9
- package/dist/core/telemetry-staleness.js +128 -0
- package/dist/core/test-output-compaction.js +145 -0
- package/dist/core/user-settings.js +73 -0
- package/dist/cron/channel.js +28 -0
- package/dist/cron/cli.js +230 -0
- package/dist/cron/plugin.js +11 -0
- package/dist/cron/schedule.js +214 -0
- package/dist/cron/service.js +177 -0
- package/dist/cron/store.js +349 -0
- package/dist/cron/types.js +1 -0
- package/dist/data/cli.js +184 -0
- package/dist/data/event-log.js +106 -0
- package/dist/data/final-app-space-cutover-migration.js +728 -0
- package/dist/data/ingest-service.js +389 -0
- package/dist/data/message-store.js +62 -0
- package/dist/data/navigation-store.js +75 -0
- package/dist/data/observation-store.js +46 -0
- package/dist/data/payload-store.js +144 -0
- package/dist/data/pibo-store.js +59 -0
- package/dist/data/schema.js +434 -0
- package/dist/data/session-store.js +63 -0
- package/dist/data/shared-app-migration.js +757 -0
- package/dist/data/sqlite-schema.js +12 -0
- package/dist/data/telemetry-preview.js +65 -0
- package/dist/data/telemetry-queries.js +212 -0
- package/dist/data/telemetry-retention.js +50 -0
- package/dist/data/telemetry-rows.js +158 -0
- package/dist/data/telemetry.js +357 -0
- package/dist/debug/delta-compaction.js +99 -0
- package/dist/debug/detail-format.js +86 -0
- package/dist/debug/events.js +149 -29
- package/dist/debug/failures.js +162 -0
- package/dist/debug/index.js +655 -30
- package/dist/debug/messages.js +185 -0
- package/dist/debug/next-commands.js +6 -0
- package/dist/debug/payloads.js +123 -0
- package/dist/debug/pty.js +924 -0
- package/dist/debug/session.js +45 -15
- package/dist/debug/sql.js +1 -1
- package/dist/debug/stores.js +18 -13
- package/dist/debug/summary.js +72 -0
- package/dist/debug/telemetry.js +649 -0
- package/dist/debug/tools.js +168 -0
- package/dist/debug/trace-render-check.js +151 -0
- package/dist/debug/trace.js +152 -27
- package/dist/debug/web-artifacts.js +63 -0
- package/dist/debug/web-options.js +313 -0
- package/dist/debug/web-render-analysis.js +310 -0
- package/dist/debug/web-snapshot-browser-scripts.js +303 -0
- package/dist/debug/web-streaming-benchmark-analysis.js +605 -0
- package/dist/debug/web-streaming-browser-library.js +928 -0
- package/dist/debug/web-streaming-browser-scripts.js +242 -0
- package/dist/debug/web-streaming-provider-telemetry.js +194 -0
- package/dist/debug/web-streaming-report.js +493 -0
- package/dist/debug/web-streaming-types.js +1 -0
- package/dist/debug/web.js +574 -0
- package/dist/gateway/backup.js +83 -0
- package/dist/gateway/cli.js +511 -0
- package/dist/gateway/fallback.js +155 -0
- package/dist/gateway/pidfile.js +84 -0
- package/dist/gateway/protocol.js +16 -0
- package/dist/gateway/server.js +172 -17
- package/dist/gateway/tool.js +54 -51
- package/dist/gateway/web.js +74 -2
- package/dist/index.js +3 -1
- package/dist/local/client.js +3 -3
- package/dist/local/extension.js +8 -5
- package/dist/plugins/builtin.js +251 -49
- package/dist/plugins/chat-vscode-web.js +28 -0
- package/dist/plugins/codex-compat.js +0 -41
- package/dist/plugins/context-files.js +98 -18
- package/dist/plugins/dev-auth.js +124 -0
- package/dist/plugins/native-tooling.js +15 -0
- package/dist/plugins/registry.js +49 -1
- package/dist/plugins/web-annotations.js +27 -0
- package/dist/providers/minimax.js +70 -0
- package/dist/providers/openai-compat.js +48 -0
- package/dist/ralph/channel.js +8 -0
- package/dist/ralph/cli.js +152 -0
- package/dist/ralph/plugin.js +14 -0
- package/dist/ralph/service.js +271 -0
- package/dist/ralph/stopping.js +151 -0
- package/dist/ralph/store.js +450 -0
- package/dist/ralph/templates.js +200 -0
- package/dist/ralph/types.js +1 -0
- package/dist/reliability/store.js +42 -26
- package/dist/runs/registry.js +72 -35
- package/dist/session-ui/commandCatalog.js +193 -0
- package/dist/session-ui/commandResults.js +95 -0
- package/dist/session-ui/index.js +7 -0
- package/dist/session-ui/ownerViewModel.js +27 -0
- package/dist/session-ui/roomSessionViewModel.js +69 -0
- package/dist/session-ui/statusViewModel.js +127 -0
- package/dist/session-ui/terminalCards.js +210 -0
- package/dist/session-ui/terminalRows.js +937 -0
- package/dist/session-ui/terminalValue.js +45 -0
- package/dist/sessions/pibo-data-store.js +178 -0
- package/dist/sessions/sqlite-store.js +78 -12
- package/dist/sessions/store.js +11 -4
- package/dist/sessions/workflow-session-kind.js +20 -0
- package/dist/setup/cli.js +567 -0
- package/dist/shared/trace-async-agent-runs.js +127 -0
- package/dist/shared/trace-engine.js +96 -0
- package/dist/shared/trace-event-projection.js +679 -0
- package/dist/shared/trace-live-reducer.js +191 -0
- package/dist/shared/trace-nodes.js +76 -0
- package/dist/shared/trace-order.js +11 -10
- package/dist/shared/trace-patch-nodes.js +83 -0
- package/dist/shared/trace-run-notifications.js +69 -0
- package/dist/shared/trace-subagent-links.js +46 -0
- package/dist/shared/trace-transcript.js +303 -0
- package/dist/shared/trace-types.js +1 -0
- package/dist/shared-app.js +4 -0
- package/dist/signals/aggregate.js +65 -0
- package/dist/signals/events.js +1 -0
- package/dist/signals/projector.js +158 -0
- package/dist/signals/registry.js +513 -0
- package/dist/signals/store.js +1 -0
- package/dist/signals/types.js +1 -0
- package/dist/skills/cli.js +117 -0
- package/dist/tools/agent-browser-leases.js +219 -0
- package/dist/tools/agent-browser-wrapper.js +99 -0
- package/dist/tools/browser-pool.js +623 -0
- package/dist/tools/browser-use-cdp.js +56 -4
- package/dist/tools/browser-use-leases.js +215 -37
- package/dist/tools/browser-use-wrapper.js +508 -65
- package/dist/tools/cdp-client.js +189 -0
- package/dist/tools/guides.js +203 -4
- package/dist/tools/index.js +666 -16
- package/dist/tools/npm-runtime.js +136 -0
- package/dist/tools/registry.js +107 -8
- package/dist/tools/runtime/index.js +3 -0
- package/dist/tools/runtime/node-backend.js +225 -0
- package/dist/tools/runtime/node-worker-source.js +206 -0
- package/dist/tools/runtime/python-backend.js +227 -0
- package/dist/tools/runtime/python-worker-source.js +178 -0
- package/dist/tools/runtime/registry.js +255 -0
- package/dist/tools/runtime/tool.js +168 -0
- package/dist/tools/runtime/types.js +1 -0
- package/dist/tools/web-search.js +2 -1
- package/dist/user-skills/installer.js +39 -36
- package/dist/user-skills/store.js +50 -11
- package/dist/web/auth.js +5 -1
- package/dist/web/channel.js +86 -0
- package/dist/web/http.js +79 -14
- package/dist/web-annotations/api.js +348 -0
- package/dist/web-annotations/attachments.js +201 -0
- package/dist/web-annotations/cdp.js +1107 -0
- package/dist/web-annotations/index.js +7 -0
- package/dist/web-annotations/store.js +407 -0
- package/dist/web-annotations/tools.js +350 -0
- package/dist/web-annotations/types.js +34 -0
- package/dist/web-annotations/validation.js +288 -0
- package/docs/README.md +23 -0
- package/docs/ops/install-developer-host.md +112 -0
- package/docs/ops/install-user-host.md +76 -0
- package/docs/ops/upgrade-user-to-developer-host.md +69 -0
- package/package.json +24 -10
- package/skills/builtin/pi-agent-harness/SKILL.md +24 -24
- package/skills/builtin/pibo-docker-system/SKILL.md +170 -0
- package/skills/builtin/pibo-spec-writing/SKILL.md +330 -0
- package/skills/builtin/prd/SKILL.md +143 -0
- package/skills/builtin/ralph-loop/SKILL.md +359 -0
- package/skills/builtin/ralph-prd-json/SKILL.md +123 -0
- package/skills/builtin/skill-creator/LICENSE.txt +202 -0
- package/skills/builtin/skill-creator/SKILL.md +513 -0
- package/skills/builtin/skill-creator/agents/analyzer.md +274 -0
- package/skills/builtin/skill-creator/agents/comparator.md +202 -0
- package/skills/builtin/skill-creator/agents/grader.md +223 -0
- package/skills/builtin/skill-creator/assets/eval_review.html +146 -0
- package/skills/builtin/skill-creator/eval-viewer/generate_review.py +471 -0
- package/skills/builtin/skill-creator/eval-viewer/viewer.html +1325 -0
- package/skills/builtin/skill-creator/references/schemas.md +430 -0
- package/skills/builtin/skill-creator/scripts/__init__.py +0 -0
- package/skills/builtin/skill-creator/scripts/aggregate_benchmark.py +401 -0
- package/skills/builtin/skill-creator/scripts/generate_report.py +326 -0
- package/skills/builtin/skill-creator/scripts/improve_description.py +247 -0
- package/skills/builtin/skill-creator/scripts/package_skill.py +136 -0
- package/skills/builtin/skill-creator/scripts/quick_validate.py +103 -0
- package/skills/builtin/skill-creator/scripts/run_eval.py +310 -0
- package/skills/builtin/skill-creator/scripts/run_loop.py +328 -0
- package/skills/builtin/skill-creator/scripts/utils.py +47 -0
- package/skills/builtin/web-annotations/SKILL.md +93 -0
- package/dist/apps/chat-ui/assets/index-D2Qxambd.js +0 -151
- package/dist/apps/chat-ui/assets/index-DXx368XK.css +0 -1
- package/dist/env.js +0 -32
- package/dist/plugins/core-tools.js +0 -94
- package/dist/plugins/example.js +0 -67
- package/dist/plugins/remote-agent.js +0 -9
- package/dist/remote/channel.js +0 -176
- package/dist/remote/client.js +0 -92
- package/dist/remote/examples/tui-controller.js +0 -263
- package/dist/remote/protocol.js +0 -55
- package/dist/remote/session-client.js +0 -189
- package/dist/sessions/bindings.js +0 -41
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export class CliSourceError extends Error {
|
|
2
|
+
code;
|
|
3
|
+
cause;
|
|
4
|
+
constructor(code, message, options = {}) {
|
|
5
|
+
super(message);
|
|
6
|
+
this.name = "CliSourceError";
|
|
7
|
+
this.code = code;
|
|
8
|
+
this.cause = options.cause;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
export function isCliSourceError(error) {
|
|
12
|
+
return error instanceof CliSourceError;
|
|
13
|
+
}
|
package/dist/cli.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { Command } from "commander";
|
|
2
|
-
import {
|
|
2
|
+
import { PIBO_CONFIG_KEYS, getDefaultPiboConfigPath, deletePiboConfigValue, getDisplayPiboConfigValue, loadPiboConfig, redactPiboConfig, savePiboConfig, setPiboConfigValue, } from "./config/config.js";
|
|
3
3
|
import { parsePiboThinkingLevel } from "./core/thinking.js";
|
|
4
4
|
async function createCliProfile(profileName) {
|
|
5
|
-
const { createDefaultPiboPluginRegistry, createGatewayProducerPiboProfile } = await import("./plugins/builtin.js");
|
|
5
|
+
const { createDefaultPiboPluginRegistry, createGatewayProducerPiboProfile, createPiboProfileFromRegistryOrDefault } = await import("./plugins/builtin.js");
|
|
6
6
|
if (profileName === "gateway-producer" || profileName === "pibo-gateway-producer") {
|
|
7
7
|
return createGatewayProducerPiboProfile();
|
|
8
8
|
}
|
|
9
|
-
return createDefaultPiboPluginRegistry()
|
|
9
|
+
return createPiboProfileFromRegistryOrDefault(createDefaultPiboPluginRegistry(), profileName);
|
|
10
10
|
}
|
|
11
11
|
function printJson(value) {
|
|
12
12
|
console.log(JSON.stringify(value, null, 2));
|
|
@@ -30,6 +30,13 @@ function parsePort(value) {
|
|
|
30
30
|
}
|
|
31
31
|
return port;
|
|
32
32
|
}
|
|
33
|
+
function parsePositiveInteger(value) {
|
|
34
|
+
const parsed = Number(value);
|
|
35
|
+
if (!Number.isInteger(parsed) || parsed < 1) {
|
|
36
|
+
throw new Error("Value must be a positive integer");
|
|
37
|
+
}
|
|
38
|
+
return parsed;
|
|
39
|
+
}
|
|
33
40
|
export async function runPiboCli(argv = process.argv) {
|
|
34
41
|
if (argv[2] === "--help" || argv[2] === "-h") {
|
|
35
42
|
printRootDiscovery();
|
|
@@ -55,10 +62,50 @@ export async function runPiboCli(argv = process.argv) {
|
|
|
55
62
|
await runDebugCli([argv[0] ?? "node", "pibo debug", ...argv.slice(3)]);
|
|
56
63
|
return;
|
|
57
64
|
}
|
|
65
|
+
if (argv[2] === "data") {
|
|
66
|
+
const { runDataCli } = await import("./data/cli.js");
|
|
67
|
+
await runDataCli([argv[0] ?? "node", "pibo data", ...argv.slice(3)]);
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
if (argv[2] === "gateway") {
|
|
71
|
+
const { runGatewayCli } = await import("./gateway/cli.js");
|
|
72
|
+
await runGatewayCli(argv);
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
if (argv[2] === "compute") {
|
|
76
|
+
const { runComputeCli } = await import("./compute/cli.js");
|
|
77
|
+
await runComputeCli([argv[0] ?? "node", "pibo compute", ...argv.slice(3)]);
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
if (argv[2] === "setup") {
|
|
81
|
+
const { runSetupCli } = await import("./setup/cli.js");
|
|
82
|
+
await runSetupCli([argv[0] ?? "node", "pibo setup", ...argv.slice(3)]);
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
if (argv[2] === "skills") {
|
|
86
|
+
const { runSkillsCli } = await import("./skills/cli.js");
|
|
87
|
+
await runSkillsCli([argv[0] ?? "node", "pibo skills", ...argv.slice(3)]);
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
if (argv[2] === "cron") {
|
|
91
|
+
const { runCronCli } = await import("./cron/cli.js");
|
|
92
|
+
await runCronCli([argv[0] ?? "node", "pibo cron", ...argv.slice(3)]);
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
if (argv[2] === "ralph") {
|
|
96
|
+
const { runRalphCli } = await import("./ralph/cli.js");
|
|
97
|
+
await runRalphCli([argv[0] ?? "node", "pibo ralph", ...argv.slice(3)]);
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
58
100
|
if (argv[2] === "config" && (argv[3] === "--help" || argv[3] === "-h" || argv.length === 3)) {
|
|
59
101
|
printConfigDiscovery();
|
|
60
102
|
return;
|
|
61
103
|
}
|
|
104
|
+
if (argv[2] === "tui:sessions" && (argv[3] === "--help" || argv[3] === "-h")) {
|
|
105
|
+
const { cliSessionsHelpText } = await import("./apps/cli-ui/index.js");
|
|
106
|
+
console.log(cliSessionsHelpText());
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
62
109
|
const program = new Command();
|
|
63
110
|
program.name("pibo").description("Agent-oriented CLI for Pibo").helpOption(false).showHelpAfterError();
|
|
64
111
|
program
|
|
@@ -105,7 +152,73 @@ export async function runPiboCli(argv = process.argv) {
|
|
|
105
152
|
const { runDebugCli } = await import("./debug/index.js");
|
|
106
153
|
await runDebugCli([argv[0] ?? "node", "pibo debug", ...args]);
|
|
107
154
|
});
|
|
108
|
-
|
|
155
|
+
program
|
|
156
|
+
.command("data")
|
|
157
|
+
.description("Inspect and maintain Pibo data stores")
|
|
158
|
+
.helpOption(false)
|
|
159
|
+
.allowUnknownOption(true)
|
|
160
|
+
.allowExcessArguments(true)
|
|
161
|
+
.argument("[args...]")
|
|
162
|
+
.action(async (args) => {
|
|
163
|
+
const { runDataCli } = await import("./data/cli.js");
|
|
164
|
+
await runDataCli([argv[0] ?? "node", "pibo data", ...args]);
|
|
165
|
+
});
|
|
166
|
+
program
|
|
167
|
+
.command("compute")
|
|
168
|
+
.description("Manage Pibo Docker compute workers")
|
|
169
|
+
.helpOption(false)
|
|
170
|
+
.allowUnknownOption(true)
|
|
171
|
+
.allowExcessArguments(true)
|
|
172
|
+
.argument("[args...]")
|
|
173
|
+
.action(async (args) => {
|
|
174
|
+
const { runComputeCli } = await import("./compute/cli.js");
|
|
175
|
+
await runComputeCli([argv[0] ?? "node", "pibo compute", ...args]);
|
|
176
|
+
});
|
|
177
|
+
program
|
|
178
|
+
.command("setup")
|
|
179
|
+
.description("Plan user-host installs and developer-host upgrades")
|
|
180
|
+
.helpOption(false)
|
|
181
|
+
.allowUnknownOption(true)
|
|
182
|
+
.allowExcessArguments(true)
|
|
183
|
+
.argument("[args...]")
|
|
184
|
+
.action(async (args) => {
|
|
185
|
+
const { runSetupCli } = await import("./setup/cli.js");
|
|
186
|
+
await runSetupCli([argv[0] ?? "node", "pibo setup", ...args]);
|
|
187
|
+
});
|
|
188
|
+
program
|
|
189
|
+
.command("skills")
|
|
190
|
+
.description("Manage Pibo user skills")
|
|
191
|
+
.helpOption(false)
|
|
192
|
+
.allowUnknownOption(true)
|
|
193
|
+
.allowExcessArguments(true)
|
|
194
|
+
.argument("[args...]")
|
|
195
|
+
.action(async (args) => {
|
|
196
|
+
const { runSkillsCli } = await import("./skills/cli.js");
|
|
197
|
+
await runSkillsCli([argv[0] ?? "node", "pibo skills", ...args]);
|
|
198
|
+
});
|
|
199
|
+
program
|
|
200
|
+
.command("cron")
|
|
201
|
+
.description("Manage scheduled Pibo jobs")
|
|
202
|
+
.helpOption(false)
|
|
203
|
+
.allowUnknownOption(true)
|
|
204
|
+
.allowExcessArguments(true)
|
|
205
|
+
.argument("[args...]")
|
|
206
|
+
.action(async (args) => {
|
|
207
|
+
const { runCronCli } = await import("./cron/cli.js");
|
|
208
|
+
await runCronCli([argv[0] ?? "node", "pibo cron", ...args]);
|
|
209
|
+
});
|
|
210
|
+
program
|
|
211
|
+
.command("ralph")
|
|
212
|
+
.description("Manage continuous Ralph jobs")
|
|
213
|
+
.helpOption(false)
|
|
214
|
+
.allowUnknownOption(true)
|
|
215
|
+
.allowExcessArguments(true)
|
|
216
|
+
.argument("[args...]")
|
|
217
|
+
.action(async (args) => {
|
|
218
|
+
const { runRalphCli } = await import("./ralph/cli.js");
|
|
219
|
+
await runRalphCli([argv[0] ?? "node", "pibo ralph", ...args]);
|
|
220
|
+
});
|
|
221
|
+
const config = program.command("config").description(`Manage pibo config at ${getDefaultPiboConfigPath()}`).helpOption(false);
|
|
109
222
|
config.action(() => {
|
|
110
223
|
printConfigDiscovery();
|
|
111
224
|
});
|
|
@@ -167,6 +280,7 @@ export async function runPiboCli(argv = process.argv) {
|
|
|
167
280
|
});
|
|
168
281
|
program
|
|
169
282
|
.command("tui:routed")
|
|
283
|
+
.helpOption("-h, --help", "Display help for command")
|
|
170
284
|
.option("--show-thinking", "Show routed thinking deltas in the local TUI")
|
|
171
285
|
.option("--thinking <level>", "Set routed thinking level: off, minimal, low, medium, high, xhigh", parsePiboThinkingLevel)
|
|
172
286
|
.argument("[profile]")
|
|
@@ -179,6 +293,20 @@ export async function runPiboCli(argv = process.argv) {
|
|
|
179
293
|
thinkingLevel: options.thinking,
|
|
180
294
|
});
|
|
181
295
|
});
|
|
296
|
+
program
|
|
297
|
+
.command("tui:sessions")
|
|
298
|
+
.description("Start the reduced Web Chat-derived session UI")
|
|
299
|
+
.option("--session <id>", "Open a specific Pibo session id")
|
|
300
|
+
.option("--max-rows <count>", "Limit rendered transcript rows", parsePositiveInteger)
|
|
301
|
+
.option("--demo", "Use deterministic fake session data for smoke testing")
|
|
302
|
+
.action(async (options) => {
|
|
303
|
+
const { runCliSessionsUi } = await import("./apps/cli-ui/index.js");
|
|
304
|
+
await runCliSessionsUi({
|
|
305
|
+
initialSessionId: options.session,
|
|
306
|
+
maxRows: options.maxRows,
|
|
307
|
+
useFakeSource: options.demo === true,
|
|
308
|
+
});
|
|
309
|
+
});
|
|
182
310
|
program
|
|
183
311
|
.command("router")
|
|
184
312
|
.argument("[piboSessionId]", "Pibo session id", "demo")
|
|
@@ -194,13 +322,6 @@ export async function runPiboCli(argv = process.argv) {
|
|
|
194
322
|
printJson(event);
|
|
195
323
|
await router.disposeAll();
|
|
196
324
|
});
|
|
197
|
-
program
|
|
198
|
-
.command("gateway")
|
|
199
|
-
.description("Start the local pibo gateway daemon")
|
|
200
|
-
.action(async () => {
|
|
201
|
-
const { runGatewayServer } = await import("./gateway/server.js");
|
|
202
|
-
await runGatewayServer();
|
|
203
|
-
});
|
|
204
325
|
program
|
|
205
326
|
.command("gateway:web")
|
|
206
327
|
.description("Start the authenticated web gateway")
|
|
@@ -238,18 +359,25 @@ Commands:
|
|
|
238
359
|
tools Install and inspect curated external CLI tools
|
|
239
360
|
pi-packages Register Pi Coding Agent packages
|
|
240
361
|
debug Inspect local Pibo data
|
|
362
|
+
data Inspect and maintain Pibo data stores
|
|
363
|
+
compute Manage Pibo Docker compute workers
|
|
364
|
+
setup Plan user-host installs and developer-host upgrades
|
|
365
|
+
skills Manage Pibo user skills
|
|
366
|
+
cron Manage scheduled Pibo jobs
|
|
367
|
+
ralph Manage continuous Ralph jobs
|
|
241
368
|
profile Inspect a pibo profile
|
|
242
369
|
tui Start the direct Pi TUI
|
|
243
370
|
tui:routed Start the local routed Pibo TUI
|
|
244
|
-
|
|
245
|
-
gateway
|
|
371
|
+
tui:sessions Start the reduced Web Chat-derived session UI
|
|
372
|
+
gateway Inspect and restart host gateways through safe CLI commands
|
|
373
|
+
gateway:web Start a web gateway runtime
|
|
246
374
|
|
|
247
375
|
Next:
|
|
248
376
|
pibo <command> --help
|
|
249
377
|
`;
|
|
250
378
|
}
|
|
251
379
|
function printConfigDiscoveryText() {
|
|
252
|
-
return `pibo config - local config at ${
|
|
380
|
+
return `pibo config - local config at ${getDefaultPiboConfigPath()}
|
|
253
381
|
|
|
254
382
|
Commands:
|
|
255
383
|
keys List supported config keys
|
|
@@ -0,0 +1,415 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { IMAGE_NAME, imageExists, shouldRebuild, shouldRebuildDeps, dockerBuild, saveHash, saveDepHash, spawnWorker, spawnDevWorker, listWorkers, releaseWorker, planReapWorkers, applyComputeWorkerReapPlan, getComputeDiskDiagnostics, } from "./docker.js";
|
|
3
|
+
import { getComputeResourceHealth } from "./resource-health.js";
|
|
4
|
+
import { mkdir } from "node:fs/promises";
|
|
5
|
+
import path from "node:path";
|
|
6
|
+
import os from "node:os";
|
|
7
|
+
const WORKSPACE_DIR = process.env.PIBO_COMPUTE_WORKSPACE || process.cwd();
|
|
8
|
+
const HASH_FILE = path.join(os.homedir(), ".pibo", "compute-image-hash");
|
|
9
|
+
const DEP_HASH_FILE = path.join(os.homedir(), ".pibo", "compute-dep-hash");
|
|
10
|
+
function printJson(value) {
|
|
11
|
+
console.log(JSON.stringify(value, null, 2));
|
|
12
|
+
}
|
|
13
|
+
function parsePositiveIntegerOption(value) {
|
|
14
|
+
if (value === undefined || value.trim() === "")
|
|
15
|
+
return undefined;
|
|
16
|
+
const parsed = Number(value);
|
|
17
|
+
return Number.isInteger(parsed) && parsed > 0 ? parsed : undefined;
|
|
18
|
+
}
|
|
19
|
+
function hostPort(value) {
|
|
20
|
+
if (!value || value === "-")
|
|
21
|
+
return undefined;
|
|
22
|
+
const first = value.split(",")[0] ?? value;
|
|
23
|
+
return first.includes(":") ? first.split(":").pop() : first;
|
|
24
|
+
}
|
|
25
|
+
function formatPorts(worker, verbose = false) {
|
|
26
|
+
if (verbose)
|
|
27
|
+
return worker.ports || "-";
|
|
28
|
+
const preferred = [
|
|
29
|
+
["gw", worker.portMap["4789/tcp"] ?? worker.portMap.gateway],
|
|
30
|
+
["cdp", worker.portMap["56663/tcp"] ?? worker.portMap.cdp],
|
|
31
|
+
["web", worker.portMap["4788/tcp"] ?? worker.portMap.web],
|
|
32
|
+
["chat", worker.portMap["4790/tcp"] ?? worker.portMap.chatUi],
|
|
33
|
+
["ctx", worker.portMap["4791/tcp"] ?? worker.portMap.contextFiles],
|
|
34
|
+
];
|
|
35
|
+
const compact = preferred
|
|
36
|
+
.map(([label, value]) => {
|
|
37
|
+
const port = hostPort(value);
|
|
38
|
+
return port ? `${label}=${port}` : undefined;
|
|
39
|
+
})
|
|
40
|
+
.filter(Boolean);
|
|
41
|
+
if (compact.length > 0)
|
|
42
|
+
return compact.join(",");
|
|
43
|
+
const fallback = Object.entries(worker.portMap)
|
|
44
|
+
.slice(0, 4)
|
|
45
|
+
.map(([container, value]) => `${container.replace(/\/tcp$/, "")}=${hostPort(value) ?? value}`);
|
|
46
|
+
return fallback.length > 0 ? fallback.join(",") : worker.ports || "-";
|
|
47
|
+
}
|
|
48
|
+
function formatResourcePolicy(worker) {
|
|
49
|
+
const policy = worker.resourcePolicy;
|
|
50
|
+
if (!policy)
|
|
51
|
+
return "-";
|
|
52
|
+
const parts = [
|
|
53
|
+
policy.memory ? `mem=${policy.memory}` : undefined,
|
|
54
|
+
policy.pidsLimit !== undefined ? `pids=${policy.pidsLimit}` : undefined,
|
|
55
|
+
policy.shmSize ? `shm=${policy.shmSize}` : undefined,
|
|
56
|
+
].filter(Boolean);
|
|
57
|
+
return parts.length ? parts.join(",") : "-";
|
|
58
|
+
}
|
|
59
|
+
function formatCleanup(worker) {
|
|
60
|
+
const prefix = worker.cleanupEligibility.eligible ? "eligible" : "skip";
|
|
61
|
+
return `${prefix}:${worker.cleanupEligibility.reasons.join("+") || "none"}`;
|
|
62
|
+
}
|
|
63
|
+
function formatComputeReapCommand(plan, apply) {
|
|
64
|
+
const args = ["pibo", "compute", "reap", apply ? "--apply" : "--dry-run", "--max-age-minutes", String(plan.options.maxAgeMinutes)];
|
|
65
|
+
if (plan.options.includeDev)
|
|
66
|
+
args.push("--include-dev");
|
|
67
|
+
if (!plan.options.includeStopped)
|
|
68
|
+
args.push("--no-stopped");
|
|
69
|
+
if (!plan.options.includeDirty)
|
|
70
|
+
args.push("--no-dirty");
|
|
71
|
+
return args.join(" ");
|
|
72
|
+
}
|
|
73
|
+
export function renderComputeWorkerListText(workers, options = {}) {
|
|
74
|
+
if (workers.length === 0) {
|
|
75
|
+
return [
|
|
76
|
+
options.all ? "No Pibo worker containers found." : "No worker containers running.",
|
|
77
|
+
"Next: pibo compute list --all --json",
|
|
78
|
+
"Next: pibo compute reap --help",
|
|
79
|
+
].join("\n");
|
|
80
|
+
}
|
|
81
|
+
const lines = ["NAME\tROLE\tSTATE\tSTATUS\tOOM\tPORTS\tCREATED\tLAST_USED\tHOLDER\tWORKTREE\tRALPH_JOB\tRALPH_RUN\tRESOURCE\tCLEANUP"];
|
|
82
|
+
for (const w of workers) {
|
|
83
|
+
lines.push(`${w.name}\t${w.role}\t${w.state}\t${w.status}\t${w.oomKilled ? "yes" : "no"}\t${formatPorts(w, options.verbose === true)}\t${w.createdAt}\t${w.lastUsedAt ?? "-"}\t${w.holder ?? "-"}\t${w.worktree ?? "-"}\t${w.ralphJobId ?? "-"}\t${w.ralphRunId ?? "-"}\t${formatResourcePolicy(w)}\t${formatCleanup(w)}`);
|
|
84
|
+
}
|
|
85
|
+
lines.push(options.verbose ? "Next: pibo compute list --all --json" : "Next: pibo compute list --all --verbose for full Docker port bindings");
|
|
86
|
+
lines.push("Next: pibo compute list --all --json");
|
|
87
|
+
return lines.join("\n");
|
|
88
|
+
}
|
|
89
|
+
export function renderComputeReapPlanText(plan, options = {}) {
|
|
90
|
+
const mode = options.applied ? "apply" : "dry-run";
|
|
91
|
+
const lines = [`Compute reap ${mode}: ${plan.summary.selected} selected, ${plan.summary.skipped} skipped, ${plan.summary.worktreesPreserved} worktree(s) preserved`];
|
|
92
|
+
if (plan.items.length === 0) {
|
|
93
|
+
lines.push("No Pibo worker containers found.");
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
lines.push("ACTION\tNAME\tROLE\tSTATE\tAGE_MIN\tREASONS\tSKIP_REASONS\tWORKTREE");
|
|
97
|
+
for (const item of plan.items) {
|
|
98
|
+
lines.push(`${item.action}\t${item.worker.name}\t${item.worker.role}\t${item.worker.state}\t${item.ageMinutes === undefined ? "-" : Math.floor(item.ageMinutes)}\t${item.reasons.join("+") || "-"}\t${item.skipReasons.join("+") || "-"}\t${item.preservesWorktree ? "preserve" : "-"}`);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
if (plan.options.includeDev && plan.summary.selected > 0)
|
|
102
|
+
lines.push("WARNING: --include-dev selected dev workers. Review ports/worktrees and active Ralph jobs before applying.");
|
|
103
|
+
if (options.applied)
|
|
104
|
+
lines.push(`Removed: ${options.removed?.join(", ") || "none"}`);
|
|
105
|
+
else
|
|
106
|
+
lines.push(`Dry-run only. Apply equivalent plan with: ${formatComputeReapCommand(plan, true)}`);
|
|
107
|
+
lines.push(`Review equivalent dry-run with: ${formatComputeReapCommand(plan, false)}`);
|
|
108
|
+
lines.push("Worktrees are preserved; remove Git worktrees only with an explicit worktree cleanup command.");
|
|
109
|
+
lines.push(...plan.nextCommands.map((command) => `Next: ${command}`));
|
|
110
|
+
return lines.join("\n");
|
|
111
|
+
}
|
|
112
|
+
function formatMaybeBytes(bytes) {
|
|
113
|
+
return bytes === undefined ? "-" : String(bytes);
|
|
114
|
+
}
|
|
115
|
+
function severityRank(severity) {
|
|
116
|
+
if (severity === "critical")
|
|
117
|
+
return 2;
|
|
118
|
+
if (severity === "warning")
|
|
119
|
+
return 1;
|
|
120
|
+
return 0;
|
|
121
|
+
}
|
|
122
|
+
export function renderComputeResourceHealthText(health) {
|
|
123
|
+
const lines = [`Compute resource health: ${health.severity} (read-only)`];
|
|
124
|
+
lines.push(`Generated at: ${health.generatedAt}`);
|
|
125
|
+
lines.push(`Browser processes: ${health.browserProcesses.totalChromiumMainProcesses} main / ${health.browserProcesses.totalChromiumProcesses} total Chromium processes`);
|
|
126
|
+
if (health.browserProcesses.unassignedMainProcessDetails.length > 0) {
|
|
127
|
+
lines.push(`Unmanaged browser main processes: ${health.browserProcesses.unassignedMainProcessDetails.length}`);
|
|
128
|
+
lines.push("PID\tWORKER\tUSER_DATA_DIR\tCOMMAND");
|
|
129
|
+
for (const process of health.browserProcesses.unassignedMainProcessDetails.slice(0, 5)) {
|
|
130
|
+
lines.push(`${process.pid}\t${process.workerName ?? "-"}\t${process.userDataDir ?? "-"}\t${process.commandName}`);
|
|
131
|
+
}
|
|
132
|
+
lines.push("Inspect unmanaged browsers with: pibo compute health --json");
|
|
133
|
+
}
|
|
134
|
+
lines.push(`Active browser leases: ${health.browserLeases.active}`);
|
|
135
|
+
lines.push(`Stale CDP files: ${health.browserLeases.staleCdpFiles.pidFiles} pid, ${health.browserLeases.staleCdpFiles.portFiles} port`);
|
|
136
|
+
lines.push(`Compute workers: ${health.computeWorkers.total} total, ${health.computeWorkers.dirty} dirty, ${health.computeWorkers.oomKilled} OOM-killed, ${health.computeWorkers.cleanupEligible} cleanup-eligible`);
|
|
137
|
+
lines.push(`Docker disk: reclaimable=${formatMaybeBytes(health.dockerDisk.reclaimableBytes)} buildCache=${formatMaybeBytes(health.dockerDisk.buildCacheBytes)} pressure=${health.dockerDisk.pressure ? "yes" : "no"}`);
|
|
138
|
+
lines.push(`Reaper/timer: ${health.reaperTimers.status}${health.reaperTimers.details ? ` - ${health.reaperTimers.details}` : ""}`);
|
|
139
|
+
if (health.browserProcesses.perWorker.length > 0) {
|
|
140
|
+
lines.push("Browser pools:");
|
|
141
|
+
lines.push("WORKER POOL STATE PID ACTIVE_LEASES MAIN_PROCESSES SEVERITY");
|
|
142
|
+
for (const pool of health.browserProcesses.perWorker) {
|
|
143
|
+
lines.push(`${pool.workerId}\t${pool.poolId}\t${pool.state}\t${pool.pid ?? "-"}\t${pool.activeLeaseCount}\t${pool.browserMainProcessCount}\t${pool.severity}`);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
lines.push("Checks:");
|
|
147
|
+
for (const check of [...health.checks].sort((a, b) => severityRank(b.severity) - severityRank(a.severity))) {
|
|
148
|
+
lines.push(`- [${check.severity}] ${check.id}: ${check.message}`);
|
|
149
|
+
for (const command of check.nextCommands)
|
|
150
|
+
lines.push(` Next: ${command}`);
|
|
151
|
+
}
|
|
152
|
+
lines.push("Next commands:");
|
|
153
|
+
for (const command of health.nextCommands.slice(0, 8))
|
|
154
|
+
lines.push(`- ${command}`);
|
|
155
|
+
return lines.join("\n");
|
|
156
|
+
}
|
|
157
|
+
export function renderComputeDiskDiagnosticsText(diagnostics) {
|
|
158
|
+
const lines = ["Compute disk diagnostics (read-only)"];
|
|
159
|
+
if (!diagnostics.dockerAvailable) {
|
|
160
|
+
lines.push(`Docker unavailable: ${diagnostics.dockerError ?? "unknown error"}`);
|
|
161
|
+
lines.push("Next: ensure Docker is installed and the daemon is reachable, then run pibo compute diagnostics --json");
|
|
162
|
+
return lines.join("\n");
|
|
163
|
+
}
|
|
164
|
+
if (diagnostics.rows.length === 0) {
|
|
165
|
+
lines.push("Docker reported no disk usage rows.");
|
|
166
|
+
}
|
|
167
|
+
else {
|
|
168
|
+
lines.push("TYPE\tCOUNT\tACTIVE\tSIZE\tSIZE_BYTES\tRECLAIMABLE\tRECLAIMABLE_BYTES");
|
|
169
|
+
for (const row of diagnostics.rows) {
|
|
170
|
+
lines.push(`${row.label}\t${row.totalCount ?? "-"}\t${row.active ?? "-"}\t${row.size || "-"}\t${formatMaybeBytes(row.sizeBytes)}\t${row.reclaimable || "-"}\t${formatMaybeBytes(row.reclaimableBytes)}`);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
lines.push(`Total bytes: ${formatMaybeBytes(diagnostics.totals.sizeBytes)}`);
|
|
174
|
+
lines.push(`Reclaimable bytes: ${formatMaybeBytes(diagnostics.totals.reclaimableBytes)}`);
|
|
175
|
+
lines.push("Cleanup suggestions:");
|
|
176
|
+
for (const suggestion of diagnostics.suggestions) {
|
|
177
|
+
lines.push(`- ${suggestion.kind}: ${suggestion.reason}`);
|
|
178
|
+
for (const command of suggestion.nextCommands)
|
|
179
|
+
lines.push(` Next: ${command}`);
|
|
180
|
+
}
|
|
181
|
+
return lines.join("\n");
|
|
182
|
+
}
|
|
183
|
+
export async function runComputeCli(argv) {
|
|
184
|
+
const program = new Command();
|
|
185
|
+
program
|
|
186
|
+
.name("pibo compute")
|
|
187
|
+
.description("Manage isolated Docker workers for Pibo development and testing")
|
|
188
|
+
.helpOption("-h, --help", "Show help")
|
|
189
|
+
.showHelpAfterError()
|
|
190
|
+
.helpCommand("help [command]", "Show help for command")
|
|
191
|
+
.addHelpText("after", `
|
|
192
|
+
Examples:
|
|
193
|
+
$ pibo compute spawn
|
|
194
|
+
$ pibo compute dev spawn --worktree my-fix
|
|
195
|
+
$ pibo compute list
|
|
196
|
+
$ pibo compute release pibo-worker-abc123
|
|
197
|
+
|
|
198
|
+
Next:
|
|
199
|
+
$ pibo compute spawn --help
|
|
200
|
+
$ pibo compute dev --help
|
|
201
|
+
`);
|
|
202
|
+
program
|
|
203
|
+
.command("spawn")
|
|
204
|
+
.description("Create a one-time worker from the current Docker image")
|
|
205
|
+
.option("--name <name>", "Set the container name")
|
|
206
|
+
.option("--holder <holder>", "Tag the container holder")
|
|
207
|
+
.option("--ttl-seconds <n>", "Tag the worker TTL in seconds")
|
|
208
|
+
.option("--idle-seconds <n>", "Tag the worker idle retention in seconds")
|
|
209
|
+
.option("--ralph-job-id <id>", "Tag the Ralph job id when this worker is Ralph-owned")
|
|
210
|
+
.option("--ralph-run-id <id>", "Tag the Ralph run id when this worker is Ralph-owned")
|
|
211
|
+
.addHelpText("after", `
|
|
212
|
+
Creates a worker container and starts the gateway. Prints JSON with the container id and mapped ports.
|
|
213
|
+
|
|
214
|
+
Use this for quick isolated checks. For code changes, prefer:
|
|
215
|
+
$ pibo compute dev spawn --worktree my-fix
|
|
216
|
+
`)
|
|
217
|
+
.action(async (options) => {
|
|
218
|
+
await mkdir(path.dirname(HASH_FILE), { recursive: true });
|
|
219
|
+
const needsBuild = !(await imageExists(IMAGE_NAME)) || (await shouldRebuild(WORKSPACE_DIR, HASH_FILE));
|
|
220
|
+
if (needsBuild) {
|
|
221
|
+
console.error(`Building ${IMAGE_NAME} from ${WORKSPACE_DIR}...`);
|
|
222
|
+
await dockerBuild(WORKSPACE_DIR);
|
|
223
|
+
await saveHash(WORKSPACE_DIR, HASH_FILE);
|
|
224
|
+
console.error("Build complete.");
|
|
225
|
+
}
|
|
226
|
+
const worker = await spawnWorker({
|
|
227
|
+
workspaceDir: WORKSPACE_DIR,
|
|
228
|
+
name: options.name,
|
|
229
|
+
holder: options.holder,
|
|
230
|
+
ttlSeconds: parsePositiveIntegerOption(options.ttlSeconds),
|
|
231
|
+
idleSeconds: parsePositiveIntegerOption(options.idleSeconds),
|
|
232
|
+
ralphJobId: options.ralphJobId,
|
|
233
|
+
ralphRunId: options.ralphRunId,
|
|
234
|
+
});
|
|
235
|
+
printJson(worker);
|
|
236
|
+
});
|
|
237
|
+
const devCmd = program
|
|
238
|
+
.command("dev")
|
|
239
|
+
.description("Manage development workers with Git worktrees")
|
|
240
|
+
.helpCommand("help [command]", "Show help for command")
|
|
241
|
+
.addHelpText("after", `
|
|
242
|
+
Use dev workers for Pibo code changes. Each worker gets its own Git worktree and port block.
|
|
243
|
+
|
|
244
|
+
Next:
|
|
245
|
+
$ pibo compute dev spawn --help
|
|
246
|
+
`);
|
|
247
|
+
devCmd
|
|
248
|
+
.command("spawn")
|
|
249
|
+
.description("Create a development worker with a Git worktree")
|
|
250
|
+
.requiredOption("--worktree <name>", "Name the Git worktree and branch")
|
|
251
|
+
.option("--repo <path>", "Use this repository", WORKSPACE_DIR)
|
|
252
|
+
.option("--holder <holder>", "Tag the container holder")
|
|
253
|
+
.option("--ttl-seconds <n>", "Tag the worker TTL in seconds")
|
|
254
|
+
.option("--idle-seconds <n>", "Tag the worker idle retention in seconds")
|
|
255
|
+
.option("--ralph-job-id <id>", "Tag the Ralph job id when this worker is Ralph-owned")
|
|
256
|
+
.option("--ralph-run-id <id>", "Tag the Ralph run id when this worker is Ralph-owned")
|
|
257
|
+
.addHelpText("after", `
|
|
258
|
+
Creates .worktrees/<name>, starts a worker, and prints JSON with ports and the worktree path.
|
|
259
|
+
|
|
260
|
+
Example:
|
|
261
|
+
$ pibo compute dev spawn --worktree my-fix
|
|
262
|
+
`)
|
|
263
|
+
.action(async (options) => {
|
|
264
|
+
await mkdir(path.dirname(DEP_HASH_FILE), { recursive: true });
|
|
265
|
+
console.error("[pibo compute] Checking Docker image status...");
|
|
266
|
+
const needsBuild = !(await imageExists(IMAGE_NAME)) || (await shouldRebuildDeps(options.repo, DEP_HASH_FILE));
|
|
267
|
+
if (needsBuild) {
|
|
268
|
+
console.error(`[pibo compute] Dependencies changed (package.json, package-lock.json, or Dockerfile).`);
|
|
269
|
+
console.error(`[pibo compute] Rebuilding Docker image ${IMAGE_NAME} — this takes 1-2 minutes...`);
|
|
270
|
+
await dockerBuild(options.repo);
|
|
271
|
+
await saveDepHash(options.repo, DEP_HASH_FILE);
|
|
272
|
+
console.error("[pibo compute] Docker image build complete.");
|
|
273
|
+
}
|
|
274
|
+
else {
|
|
275
|
+
console.error("[pibo compute] Using cached Docker image (dependencies unchanged).");
|
|
276
|
+
}
|
|
277
|
+
console.error(`[pibo compute] Creating git worktree '${options.worktree}'...`);
|
|
278
|
+
const worker = await spawnDevWorker({
|
|
279
|
+
repoDir: options.repo,
|
|
280
|
+
worktreeName: options.worktree,
|
|
281
|
+
holder: options.holder,
|
|
282
|
+
ttlSeconds: parsePositiveIntegerOption(options.ttlSeconds),
|
|
283
|
+
idleSeconds: parsePositiveIntegerOption(options.idleSeconds),
|
|
284
|
+
ralphJobId: options.ralphJobId,
|
|
285
|
+
ralphRunId: options.ralphRunId,
|
|
286
|
+
});
|
|
287
|
+
console.error(`[pibo compute] Dev container '${worker.id}' started.`);
|
|
288
|
+
console.error(`[pibo compute] Ports: gateway=${worker.gatewayPort}, cdp=${worker.cdpPort}, web=${worker.webPort}, chat-ui=${worker.webUIPortChat}, context-files=${worker.webUIPortContext}`);
|
|
289
|
+
console.error(`[pibo compute] Worktree: ${worker.worktree}`);
|
|
290
|
+
console.error(`[pibo compute] Connect: ${worker.connect}`);
|
|
291
|
+
printJson(worker);
|
|
292
|
+
});
|
|
293
|
+
program
|
|
294
|
+
.command("rebuild")
|
|
295
|
+
.description("Rebuild the pibo:latest Docker image")
|
|
296
|
+
.addHelpText("after", `
|
|
297
|
+
Rebuilds from the current workspace and refreshes compute image hashes.
|
|
298
|
+
`)
|
|
299
|
+
.action(async () => {
|
|
300
|
+
console.error(`Rebuilding ${IMAGE_NAME} from ${WORKSPACE_DIR}...`);
|
|
301
|
+
await dockerBuild(WORKSPACE_DIR);
|
|
302
|
+
await saveHash(WORKSPACE_DIR, HASH_FILE);
|
|
303
|
+
await saveDepHash(WORKSPACE_DIR, DEP_HASH_FILE);
|
|
304
|
+
console.error("Build complete.");
|
|
305
|
+
});
|
|
306
|
+
program
|
|
307
|
+
.command("list")
|
|
308
|
+
.description("List Pibo worker and dev-worker containers")
|
|
309
|
+
.option("--all", "Include stopped, exited, dead, and restarting Pibo workers")
|
|
310
|
+
.option("--json", "Print machine-readable worker metadata")
|
|
311
|
+
.option("--verbose", "Show full Docker port bindings in text output")
|
|
312
|
+
.addHelpText("after", `
|
|
313
|
+
Shows each worker's name, role, status, mapped ports, creation time, holder, and Ralph labels when present.
|
|
314
|
+
|
|
315
|
+
Next:
|
|
316
|
+
$ pibo compute list --all --json
|
|
317
|
+
`)
|
|
318
|
+
.action(async (options) => {
|
|
319
|
+
const workers = await listWorkers({ all: options.all === true });
|
|
320
|
+
if (options.json) {
|
|
321
|
+
printJson({ workers });
|
|
322
|
+
return;
|
|
323
|
+
}
|
|
324
|
+
console.log(renderComputeWorkerListText(workers, { all: options.all === true, verbose: options.verbose === true }));
|
|
325
|
+
});
|
|
326
|
+
program
|
|
327
|
+
.command("health")
|
|
328
|
+
.alias("doctor")
|
|
329
|
+
.description("Show read-only compute, browser, Docker, and reaper resource health")
|
|
330
|
+
.option("--json", "Print machine-readable resource health")
|
|
331
|
+
.option("--browser-pool-root <path>", "Browser pool root directory to scan")
|
|
332
|
+
.option("--browser-use-home <path>", "Browser-use home directory to scan for stale CDP files")
|
|
333
|
+
.addHelpText("after", `
|
|
334
|
+
Reports browser main-process counts, active browser-pool leases, stale CDP files, dirty/OOM workers, Docker disk pressure, and reaper/timer status.
|
|
335
|
+
The command is read-only and never reaps, prunes, stops, or removes resources.
|
|
336
|
+
|
|
337
|
+
Next:
|
|
338
|
+
$ pibo compute health --json
|
|
339
|
+
$ pibo tools browser-use pool reap --json
|
|
340
|
+
$ pibo compute reap --dry-run --json
|
|
341
|
+
`)
|
|
342
|
+
.action(async (options) => {
|
|
343
|
+
const health = await getComputeResourceHealth({ browserPoolRoot: options.browserPoolRoot, browserUseHome: options.browserUseHome });
|
|
344
|
+
if (options.json) {
|
|
345
|
+
printJson(health);
|
|
346
|
+
return;
|
|
347
|
+
}
|
|
348
|
+
console.log(renderComputeResourceHealthText(health));
|
|
349
|
+
});
|
|
350
|
+
program
|
|
351
|
+
.command("diagnostics")
|
|
352
|
+
.alias("disk")
|
|
353
|
+
.description("Show read-only Docker disk and build-cache diagnostics")
|
|
354
|
+
.option("--json", "Print machine-readable disk diagnostics")
|
|
355
|
+
.addHelpText("after", `
|
|
356
|
+
Reports Docker image, container, local volume, and build-cache usage without pruning anything.
|
|
357
|
+
Cleanup suggestions distinguish compute containers, images, build cache, and Git worktrees.
|
|
358
|
+
|
|
359
|
+
Next:
|
|
360
|
+
$ pibo compute diagnostics --json
|
|
361
|
+
$ pibo compute reap --dry-run --json
|
|
362
|
+
`)
|
|
363
|
+
.action(async (options) => {
|
|
364
|
+
const diagnostics = await getComputeDiskDiagnostics();
|
|
365
|
+
if (options.json) {
|
|
366
|
+
printJson(diagnostics);
|
|
367
|
+
return;
|
|
368
|
+
}
|
|
369
|
+
console.log(renderComputeDiskDiagnosticsText(diagnostics));
|
|
370
|
+
});
|
|
371
|
+
program
|
|
372
|
+
.command("release")
|
|
373
|
+
.description("Stop and remove a worker container")
|
|
374
|
+
.argument("<id>", "Container name or ID")
|
|
375
|
+
.addHelpText("after", `
|
|
376
|
+
Use the name or id shown by:
|
|
377
|
+
$ pibo compute list
|
|
378
|
+
`)
|
|
379
|
+
.action(async (id) => {
|
|
380
|
+
await releaseWorker(id);
|
|
381
|
+
console.log(`Released ${id}`);
|
|
382
|
+
});
|
|
383
|
+
program
|
|
384
|
+
.command("reap")
|
|
385
|
+
.description("Preview or apply compute worker container cleanup")
|
|
386
|
+
.option("--max-age-minutes <n>", "Select workers older than this many minutes", "60")
|
|
387
|
+
.option("--include-dev", "Also select dev-worker containers; dev workers are skipped by default")
|
|
388
|
+
.option("--no-stopped", "Do not select stopped, dead, created, or restarting containers")
|
|
389
|
+
.option("--no-dirty", "Do not select dirty or OOM-killed containers")
|
|
390
|
+
.option("--dry-run", "Preview the cleanup plan without removing containers")
|
|
391
|
+
.option("--apply", "Apply the cleanup plan and remove selected containers")
|
|
392
|
+
.option("--json", "Print machine-readable cleanup plan/result")
|
|
393
|
+
.addHelpText("after", `
|
|
394
|
+
Defaults to a dry-run plan for one-time workers. Dev workers require --include-dev.
|
|
395
|
+
Stopped, dirty/OOM, and old workers are selected unless disabled by selector flags.
|
|
396
|
+
Worktrees are preserved; container cleanup never deletes Git worktrees.
|
|
397
|
+
`)
|
|
398
|
+
.action(async (options) => {
|
|
399
|
+
const maxAge = Number(options.maxAgeMinutes);
|
|
400
|
+
const plan = await planReapWorkers({
|
|
401
|
+
includeDev: options.includeDev === true,
|
|
402
|
+
includeStopped: options.stopped !== false,
|
|
403
|
+
includeDirty: options.dirty !== false,
|
|
404
|
+
maxAgeMinutes: Number.isFinite(maxAge) ? maxAge : 60,
|
|
405
|
+
});
|
|
406
|
+
const shouldApply = options.apply === true;
|
|
407
|
+
const removed = shouldApply ? await applyComputeWorkerReapPlan(plan) : [];
|
|
408
|
+
if (options.json) {
|
|
409
|
+
printJson({ dryRun: !shouldApply, applied: shouldApply, removed, plan });
|
|
410
|
+
return;
|
|
411
|
+
}
|
|
412
|
+
console.log(renderComputeReapPlanText(plan, { applied: shouldApply, removed }));
|
|
413
|
+
});
|
|
414
|
+
await program.parseAsync(argv);
|
|
415
|
+
}
|