@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
|
@@ -1,5 +1,52 @@
|
|
|
1
1
|
const DEFAULT_CDP_URL = 'http://127.0.0.1:56663';
|
|
2
2
|
const DEFAULT_TIMEOUT_MS = 2500;
|
|
3
|
+
async function isCdpPortReachable(port) {
|
|
4
|
+
try {
|
|
5
|
+
const response = await fetchWithTimeout(`http://127.0.0.1:${port}/json/version`, 800);
|
|
6
|
+
return response.ok;
|
|
7
|
+
}
|
|
8
|
+
catch {
|
|
9
|
+
return false;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
async function discoverCdpUrl() {
|
|
13
|
+
const candidates = [];
|
|
14
|
+
if (process.env.BROWSER_USE_HOME) {
|
|
15
|
+
candidates.push(join(process.env.BROWSER_USE_HOME, 'pibo-cdp'));
|
|
16
|
+
}
|
|
17
|
+
if (process.env.HOME) {
|
|
18
|
+
candidates.push(join(process.env.HOME, '.pibo', 'tools', 'browser-use', 'home', 'pibo-cdp'));
|
|
19
|
+
candidates.push(join(process.env.HOME, '.browser-use', 'pibo-cdp'));
|
|
20
|
+
}
|
|
21
|
+
for (const stateDir of candidates) {
|
|
22
|
+
try {
|
|
23
|
+
if (!existsSync(stateDir))
|
|
24
|
+
continue;
|
|
25
|
+
const entries = readdirSync(stateDir)
|
|
26
|
+
.filter((f) => f.endsWith('.port'))
|
|
27
|
+
.map((f) => {
|
|
28
|
+
const path = join(stateDir, f);
|
|
29
|
+
const portText = readFileSync(path, 'utf-8').trim();
|
|
30
|
+
const port = Number.parseInt(portText, 10);
|
|
31
|
+
const mtime = statSync(path).mtimeMs;
|
|
32
|
+
return { port, mtime, valid: Number.isFinite(port) && port > 0 };
|
|
33
|
+
})
|
|
34
|
+
.filter((e) => e.valid)
|
|
35
|
+
.sort((a, b) => b.mtime - a.mtime);
|
|
36
|
+
for (const entry of entries) {
|
|
37
|
+
if (await isCdpPortReachable(entry.port)) {
|
|
38
|
+
return `http://127.0.0.1:${entry.port}`;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
// ignore discovery errors for this candidate
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return DEFAULT_CDP_URL;
|
|
47
|
+
}
|
|
48
|
+
import { existsSync, readdirSync, readFileSync, statSync } from 'node:fs';
|
|
49
|
+
import { join } from 'node:path';
|
|
3
50
|
const CHAT_TARGET_PROBE = `(() => {
|
|
4
51
|
const text = String(document.body?.innerText || "");
|
|
5
52
|
const textareas = [...document.querySelectorAll("textarea")].map((textarea) => ({
|
|
@@ -14,7 +61,7 @@ const CHAT_TARGET_PROBE = `(() => {
|
|
|
14
61
|
};
|
|
15
62
|
})()`;
|
|
16
63
|
export async function listBrowserUseCdpTargets(options = {}) {
|
|
17
|
-
const cdpUrl = normalizeCdpUrl(options.cdpUrl);
|
|
64
|
+
const cdpUrl = await normalizeCdpUrl(options.cdpUrl);
|
|
18
65
|
const probe = options.probe !== false;
|
|
19
66
|
const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
20
67
|
const targets = await fetchChromeTargets(cdpUrl, timeoutMs);
|
|
@@ -48,13 +95,18 @@ export function formatBrowserUseTargets(targets) {
|
|
|
48
95
|
return lines.join('\n');
|
|
49
96
|
}
|
|
50
97
|
export function printAttachChatExports(target, cdpUrl = DEFAULT_CDP_URL) {
|
|
51
|
-
console.log(`export PIBO_CDP_URL=${shellQuote(
|
|
98
|
+
console.log(`export PIBO_CDP_URL=${shellQuote(cdpUrl)}`);
|
|
52
99
|
console.log(`export PIBO_CDP_TARGET_ID=${shellQuote(target.id)}`);
|
|
53
100
|
console.log(`export PIBO_CDP_TARGET_WS=${shellQuote(target.webSocketDebuggerUrl ?? '')}`);
|
|
54
101
|
console.log(`export PIBO_CHAT_URL=${shellQuote(target.url)}`);
|
|
55
102
|
}
|
|
56
|
-
function
|
|
57
|
-
return
|
|
103
|
+
export function normalizeCdpUrlSync(value) {
|
|
104
|
+
return value.replace(/\/+$/, '');
|
|
105
|
+
}
|
|
106
|
+
async function normalizeCdpUrl(value) {
|
|
107
|
+
if (value)
|
|
108
|
+
return normalizeCdpUrlSync(value);
|
|
109
|
+
return (await discoverCdpUrl()).replace(/\/+$/, '');
|
|
58
110
|
}
|
|
59
111
|
async function fetchChromeTargets(cdpUrl, timeoutMs) {
|
|
60
112
|
const response = await fetchWithTimeout(`${cdpUrl}/json/list`, timeoutMs);
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
1
2
|
import { existsSync, readFileSync } from 'node:fs';
|
|
2
3
|
import { cp, mkdir, rm, writeFile } from 'node:fs/promises';
|
|
3
|
-
import { join } from 'node:path';
|
|
4
|
+
import { join, resolve } from 'node:path';
|
|
4
5
|
import { ErrorCode, formatCliError } from '../cli-errors.js';
|
|
5
6
|
import { BROWSER_USE_DEFAULT_PROFILE } from './browser-use-wrapper.js';
|
|
7
|
+
import { browserPoolPaths, loadBrowserPoolState, releaseBrowserPoolLease, saveBrowserPoolState, withBrowserPoolLock, } from './browser-pool.js';
|
|
6
8
|
const REGISTRY_VERSION = 1;
|
|
7
9
|
const DEFAULT_APP = 'pibo-chat';
|
|
8
10
|
const DEFAULT_TTL_MINUTES = 8 * 60;
|
|
@@ -36,6 +38,27 @@ function appPoolDir(status, app) {
|
|
|
36
38
|
function browserUseHome(status) {
|
|
37
39
|
return status.homeDir;
|
|
38
40
|
}
|
|
41
|
+
function browserPoolWorkerId() {
|
|
42
|
+
return process.env.PIBO_BROWSER_POOL_WORKER_ID || process.env.PIBO_COMPUTE_WORKER_ID || process.env.HOSTNAME || 'local';
|
|
43
|
+
}
|
|
44
|
+
function browserPoolId() {
|
|
45
|
+
return process.env.PIBO_BROWSER_POOL_ID || 'default';
|
|
46
|
+
}
|
|
47
|
+
function browserPoolRootDir(status) {
|
|
48
|
+
return process.env.PIBO_BROWSER_POOL_ROOT || join(browserUseHome(status), 'pibo-browser-pool');
|
|
49
|
+
}
|
|
50
|
+
function browserPoolLeaseIdForSession(sessionName) {
|
|
51
|
+
return `browser-use:${safeSessionName(sessionName)}`;
|
|
52
|
+
}
|
|
53
|
+
function browserPoolIdentityForLease(status, lease) {
|
|
54
|
+
return {
|
|
55
|
+
workerId: lease.browserPoolWorkerId || browserPoolWorkerId(),
|
|
56
|
+
poolId: lease.browserPoolId || browserPoolId(),
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
function browserPoolRootForLease(status, lease) {
|
|
60
|
+
return lease.browserPoolRootDir || browserPoolRootDir(status);
|
|
61
|
+
}
|
|
39
62
|
function authTemplateDir(status) {
|
|
40
63
|
if (process.env.PIBO_BROWSER_USE_AUTH_TEMPLATE_DIR) {
|
|
41
64
|
return process.env.PIBO_BROWSER_USE_AUTH_TEMPLATE_DIR;
|
|
@@ -46,9 +69,11 @@ function defaultTemplateDir(status) {
|
|
|
46
69
|
const preferred = authTemplateDir(status);
|
|
47
70
|
if (existsSync(preferred))
|
|
48
71
|
return preferred;
|
|
49
|
-
|
|
72
|
+
// Never fall back to the active default profile (it may be running).
|
|
73
|
+
// Create an empty template directory so leases get clean profiles.
|
|
74
|
+
return preferred;
|
|
50
75
|
}
|
|
51
|
-
function readRegistry(status) {
|
|
76
|
+
export function readRegistry(status) {
|
|
52
77
|
const path = registryPath(status);
|
|
53
78
|
if (!existsSync(path))
|
|
54
79
|
return { version: REGISTRY_VERSION, leases: [] };
|
|
@@ -92,7 +117,7 @@ async function withRegistryLock(status, action) {
|
|
|
92
117
|
await rm(lock, { recursive: true, force: true });
|
|
93
118
|
}
|
|
94
119
|
}
|
|
95
|
-
function isExpired(lease, now = new Date()) {
|
|
120
|
+
export function isExpired(lease, now = new Date()) {
|
|
96
121
|
return new Date(lease.expiresAt).getTime() <= now.getTime();
|
|
97
122
|
}
|
|
98
123
|
function safeSessionName(sessionName) {
|
|
@@ -134,25 +159,92 @@ function killLeaseProcess(status, lease) {
|
|
|
134
159
|
// Process already exited.
|
|
135
160
|
}
|
|
136
161
|
}
|
|
162
|
+
async function releaseAssociatedBrowserPoolLease(status, lease) {
|
|
163
|
+
if (!lease.browserPoolLeaseId)
|
|
164
|
+
return;
|
|
165
|
+
const identity = browserPoolIdentityForLease(status, lease);
|
|
166
|
+
const paths = browserPoolPaths(browserPoolRootForLease(status, lease), identity);
|
|
167
|
+
await releaseBrowserPoolLease(paths, identity, { leaseId: lease.browserPoolLeaseId });
|
|
168
|
+
}
|
|
169
|
+
async function reapAssociatedBrowserPoolLeaseProcess(status, lease) {
|
|
170
|
+
if (!lease.browserPoolLeaseId)
|
|
171
|
+
return false;
|
|
172
|
+
const identity = browserPoolIdentityForLease(status, lease);
|
|
173
|
+
const paths = browserPoolPaths(browserPoolRootForLease(status, lease), identity);
|
|
174
|
+
return withBrowserPoolLock(paths.lockPath, { holder: `auth-lease-reap:${lease.id}` }, async () => {
|
|
175
|
+
const state = await loadBrowserPoolState(paths.statePath, { ...identity, onMissing: 'empty', onMalformed: 'empty' });
|
|
176
|
+
if (!browserPoolStateMatchesAuthLease(state, lease))
|
|
177
|
+
return false;
|
|
178
|
+
const terminated = await terminateManagedBrowserProcess(state);
|
|
179
|
+
const reapedAt = nowIso();
|
|
180
|
+
await saveBrowserPoolState(paths.statePath, {
|
|
181
|
+
...state,
|
|
182
|
+
state: terminated ? 'stale' : state.state,
|
|
183
|
+
activeLeaseId: undefined,
|
|
184
|
+
activeLeaseCount: 0,
|
|
185
|
+
holder: undefined,
|
|
186
|
+
lastUsedAt: reapedAt,
|
|
187
|
+
idleExpiresAt: undefined,
|
|
188
|
+
cleanupStatus: terminated ? 'success' : 'skipped',
|
|
189
|
+
lastError: terminated ? 'Expired auth lease reaped managed browser process' : 'No live managed browser process to reap',
|
|
190
|
+
});
|
|
191
|
+
return terminated;
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
function browserPoolStateMatchesAuthLease(state, lease) {
|
|
195
|
+
return state.state === 'leased'
|
|
196
|
+
&& state.activeLeaseId === lease.browserPoolLeaseId
|
|
197
|
+
&& Boolean(state.userDataDir)
|
|
198
|
+
&& resolve(state.userDataDir) === resolve(lease.userDataDir);
|
|
199
|
+
}
|
|
200
|
+
async function terminateManagedBrowserProcess(state) {
|
|
201
|
+
if (!state.pid || !processIsAlive(state.pid))
|
|
202
|
+
return false;
|
|
203
|
+
const target = state.processGroupId && state.processGroupId === state.pid ? -state.processGroupId : state.pid;
|
|
204
|
+
try {
|
|
205
|
+
process.kill(target, 'SIGTERM');
|
|
206
|
+
}
|
|
207
|
+
catch {
|
|
208
|
+
return false;
|
|
209
|
+
}
|
|
210
|
+
if (!(await waitForProcessExit(state.pid, 1000))) {
|
|
211
|
+
try {
|
|
212
|
+
process.kill(target, 'SIGKILL');
|
|
213
|
+
}
|
|
214
|
+
catch {
|
|
215
|
+
// Process may have exited after TERM.
|
|
216
|
+
}
|
|
217
|
+
await waitForProcessExit(state.pid, 1000);
|
|
218
|
+
}
|
|
219
|
+
return !processIsAlive(state.pid);
|
|
220
|
+
}
|
|
221
|
+
async function waitForProcessExit(pid, timeoutMs) {
|
|
222
|
+
const startedAt = Date.now();
|
|
223
|
+
while (Date.now() - startedAt < timeoutMs) {
|
|
224
|
+
if (!processIsAlive(pid))
|
|
225
|
+
return true;
|
|
226
|
+
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
227
|
+
}
|
|
228
|
+
return !processIsAlive(pid);
|
|
229
|
+
}
|
|
137
230
|
async function copyTemplateProfile(templateDir, userDataDir) {
|
|
138
|
-
if (
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
231
|
+
if (existsSync(templateDir)) {
|
|
232
|
+
assertTemplateIsNotRunning(templateDir);
|
|
233
|
+
await rm(userDataDir, { recursive: true, force: true });
|
|
234
|
+
await mkdir(userDataDir, { recursive: true });
|
|
235
|
+
await cp(templateDir, userDataDir, {
|
|
236
|
+
recursive: true,
|
|
237
|
+
filter: (source) => {
|
|
238
|
+
const base = source.split(/[\\/]/).pop() ?? '';
|
|
239
|
+
return !base.startsWith('Singleton') && base !== 'DevToolsActivePort';
|
|
240
|
+
},
|
|
241
|
+
});
|
|
242
|
+
return;
|
|
145
243
|
}
|
|
146
|
-
|
|
244
|
+
// Template does not exist yet: create a clean empty profile directory.
|
|
245
|
+
// Chrome will initialise a fresh profile on first start.
|
|
147
246
|
await rm(userDataDir, { recursive: true, force: true });
|
|
148
247
|
await mkdir(userDataDir, { recursive: true });
|
|
149
|
-
await cp(templateDir, userDataDir, {
|
|
150
|
-
recursive: true,
|
|
151
|
-
filter: (source) => {
|
|
152
|
-
const base = source.split(/[\\/]/).pop() ?? '';
|
|
153
|
-
return !base.startsWith('Singleton') && base !== 'DevToolsActivePort';
|
|
154
|
-
},
|
|
155
|
-
});
|
|
156
248
|
}
|
|
157
249
|
function assertTemplateIsNotRunning(templateDir) {
|
|
158
250
|
for (const fileName of ['SingletonLock', 'SingletonCookie', 'SingletonSocket']) {
|
|
@@ -179,20 +271,25 @@ function nextSlotNumber(leases, app) {
|
|
|
179
271
|
}
|
|
180
272
|
throw new Error(`No browser-use slots available for ${app}`);
|
|
181
273
|
}
|
|
182
|
-
function createLease(status, app,
|
|
274
|
+
function createLease(status, app, holder, ttlMinutes, profileName, leases) {
|
|
183
275
|
const slot = nextSlotNumber(leases, app);
|
|
184
276
|
const slotName = `slot-${String(slot).padStart(3, '0')}`;
|
|
185
277
|
const appId = sanitizeIdPart(app);
|
|
186
278
|
const id = `${appId}-${slotName}`;
|
|
187
279
|
const createdAt = nowIso();
|
|
280
|
+
const sessionName = `pibo-auth-${id}`;
|
|
188
281
|
return {
|
|
189
282
|
id,
|
|
190
283
|
app,
|
|
191
|
-
|
|
192
|
-
sessionName
|
|
284
|
+
holder,
|
|
285
|
+
sessionName,
|
|
193
286
|
userDataDir: join(appPoolDir(status, app), slotName),
|
|
194
287
|
profileName,
|
|
195
288
|
status: 'active',
|
|
289
|
+
browserPoolLeaseId: browserPoolLeaseIdForSession(sessionName),
|
|
290
|
+
browserPoolWorkerId: browserPoolWorkerId(),
|
|
291
|
+
browserPoolId: browserPoolId(),
|
|
292
|
+
browserPoolRootDir: browserPoolRootDir(status),
|
|
196
293
|
createdAt,
|
|
197
294
|
updatedAt: createdAt,
|
|
198
295
|
expiresAt: addMinutes(new Date(createdAt), ttlMinutes).toISOString(),
|
|
@@ -209,6 +306,8 @@ function printLeaseEnv(status, lease) {
|
|
|
209
306
|
console.log(`export PIBO_BROWSER_USE_SESSION=${shellQuote(lease.sessionName)}`);
|
|
210
307
|
console.log(`export PIBO_BROWSER_USE_CHROME_USER_DATA_DIR=${shellQuote(lease.userDataDir)}`);
|
|
211
308
|
console.log(`export PIBO_BROWSER_USE_DEFAULT_PROFILE=${shellQuote(lease.profileName)}`);
|
|
309
|
+
if (lease.browserPoolLeaseId)
|
|
310
|
+
console.log(`export PIBO_BROWSER_POOL_LEASE_ID=${shellQuote(lease.browserPoolLeaseId)}`);
|
|
212
311
|
console.log(`# browser-use --session "$PIBO_BROWSER_USE_SESSION" state`);
|
|
213
312
|
}
|
|
214
313
|
function printLeaseJson(status, lease) {
|
|
@@ -221,23 +320,29 @@ function printLeaseJson(status, lease) {
|
|
|
221
320
|
PIBO_BROWSER_USE_SESSION: lease.sessionName,
|
|
222
321
|
PIBO_BROWSER_USE_CHROME_USER_DATA_DIR: lease.userDataDir,
|
|
223
322
|
PIBO_BROWSER_USE_DEFAULT_PROFILE: lease.profileName,
|
|
323
|
+
...(lease.browserPoolLeaseId ? { PIBO_BROWSER_POOL_LEASE_ID: lease.browserPoolLeaseId } : {}),
|
|
224
324
|
},
|
|
225
325
|
}, null, 2));
|
|
226
326
|
}
|
|
227
327
|
export async function acquireBrowserUseLease(context, options = {}) {
|
|
228
328
|
const app = options.app?.trim() || DEFAULT_APP;
|
|
229
|
-
const
|
|
329
|
+
const holder = options.holder?.trim() || process.env.PIBO_BROWSER_USE_LEASE_HOLDER || process.env.USER || 'unknown';
|
|
230
330
|
const ttlMinutes = options.ttlMinutes ?? DEFAULT_TTL_MINUTES;
|
|
231
331
|
const profileName = options.profileName?.trim() || BROWSER_USE_DEFAULT_PROFILE;
|
|
232
332
|
const templateDir = options.templateDir?.trim() || defaultTemplateDir(context.status);
|
|
233
333
|
await withRegistryLock(context.status, async () => {
|
|
234
334
|
const registry = readRegistry(context.status);
|
|
335
|
+
const reapedCount = await reapStaleLeasesInRegistry(context.status, registry);
|
|
235
336
|
let lease = selectReusableLease(context.status, registry.leases, app);
|
|
236
337
|
if (lease) {
|
|
237
338
|
await copyTemplateProfile(templateDir, lease.userDataDir);
|
|
238
|
-
lease.
|
|
339
|
+
lease.holder = holder;
|
|
239
340
|
lease.status = 'active';
|
|
240
341
|
lease.profileName = profileName;
|
|
342
|
+
lease.browserPoolLeaseId = browserPoolLeaseIdForSession(lease.sessionName);
|
|
343
|
+
lease.browserPoolWorkerId = browserPoolWorkerId();
|
|
344
|
+
lease.browserPoolId = browserPoolId();
|
|
345
|
+
lease.browserPoolRootDir = browserPoolRootDir(context.status);
|
|
241
346
|
lease.updatedAt = nowIso();
|
|
242
347
|
lease.expiresAt = addMinutes(new Date(), ttlMinutes).toISOString();
|
|
243
348
|
}
|
|
@@ -254,18 +359,95 @@ export async function acquireBrowserUseLease(context, options = {}) {
|
|
|
254
359
|
suggestion: 'Release a lease or rerun with a higher --max-slots value.',
|
|
255
360
|
}));
|
|
256
361
|
}
|
|
257
|
-
lease = createLease(context.status, app,
|
|
362
|
+
lease = createLease(context.status, app, holder, ttlMinutes, profileName, registry.leases);
|
|
258
363
|
await copyTemplateProfile(templateDir, lease.userDataDir);
|
|
259
364
|
registry.leases.push(lease);
|
|
260
365
|
}
|
|
261
366
|
await writeRegistry(context.status, registry);
|
|
367
|
+
if (reapedCount > 0 && !options.json) {
|
|
368
|
+
console.log(`Reaped ${reapedCount} stale lease${reapedCount === 1 ? '' : 's'}`);
|
|
369
|
+
}
|
|
262
370
|
if (options.json)
|
|
263
371
|
printLeaseJson(context.status, lease);
|
|
264
372
|
else
|
|
265
373
|
printLeaseEnv(context.status, lease);
|
|
374
|
+
if (!options.noWarmup) {
|
|
375
|
+
const warmup = await warmupBrowserUseLease(context, lease);
|
|
376
|
+
if (!warmup.success && !options.json) {
|
|
377
|
+
console.log(`Warning: Browser warm-up failed: ${warmup.error}`);
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
});
|
|
381
|
+
}
|
|
382
|
+
async function warmupBrowserUseLease(context, lease, timeoutMs = 15000) {
|
|
383
|
+
const wrapperPath = join(context.status.homeDir, 'bin', 'browser-use');
|
|
384
|
+
if (!existsSync(wrapperPath)) {
|
|
385
|
+
return { success: false, error: 'browser-use wrapper not found' };
|
|
386
|
+
}
|
|
387
|
+
const env = {
|
|
388
|
+
...process.env,
|
|
389
|
+
BROWSER_USE_HOME: browserUseHome(context.status),
|
|
390
|
+
PIBO_BROWSER_USE_SESSION: lease.sessionName,
|
|
391
|
+
PIBO_BROWSER_USE_CHROME_USER_DATA_DIR: lease.userDataDir,
|
|
392
|
+
PIBO_BROWSER_USE_DEFAULT_PROFILE: lease.profileName,
|
|
393
|
+
...(lease.browserPoolLeaseId ? { PIBO_BROWSER_POOL_LEASE_ID: lease.browserPoolLeaseId } : {}),
|
|
394
|
+
};
|
|
395
|
+
return new Promise((resolve) => {
|
|
396
|
+
const child = spawn(wrapperPath, ['--session', lease.sessionName, '--pibo-ensure-chrome'], {
|
|
397
|
+
env,
|
|
398
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
399
|
+
});
|
|
400
|
+
let stdout = '';
|
|
401
|
+
let stderr = '';
|
|
402
|
+
child.stdout.on('data', (chunk) => { stdout += chunk; });
|
|
403
|
+
child.stderr.on('data', (chunk) => { stderr += chunk; });
|
|
404
|
+
const timer = setTimeout(() => {
|
|
405
|
+
child.kill('SIGTERM');
|
|
406
|
+
resolve({ success: false, error: `Warm-up timed out after ${timeoutMs}ms` });
|
|
407
|
+
}, timeoutMs);
|
|
408
|
+
child.on('error', (error) => {
|
|
409
|
+
clearTimeout(timer);
|
|
410
|
+
resolve({ success: false, error: error.message });
|
|
411
|
+
});
|
|
412
|
+
child.on('close', (code) => {
|
|
413
|
+
clearTimeout(timer);
|
|
414
|
+
if (code === 0) {
|
|
415
|
+
const cdpUrl = stdout.trim();
|
|
416
|
+
resolve({ success: true, cdpUrl: cdpUrl || undefined });
|
|
417
|
+
}
|
|
418
|
+
else {
|
|
419
|
+
resolve({ success: false, error: stderr || `Chrome start exited with code ${code}` });
|
|
420
|
+
}
|
|
421
|
+
});
|
|
266
422
|
});
|
|
267
423
|
}
|
|
424
|
+
async function reapStaleLeasesInRegistry(status, registry) {
|
|
425
|
+
let count = 0;
|
|
426
|
+
for (const lease of registry.leases) {
|
|
427
|
+
if (lease.status !== 'active' || !isExpired(lease))
|
|
428
|
+
continue;
|
|
429
|
+
if (lease.browserPoolLeaseId) {
|
|
430
|
+
await reapAssociatedBrowserPoolLeaseProcess(status, lease);
|
|
431
|
+
}
|
|
432
|
+
else if (leaseProcessIsAlive(status, lease)) {
|
|
433
|
+
killLeaseProcess(status, lease);
|
|
434
|
+
}
|
|
435
|
+
lease.status = 'released';
|
|
436
|
+
lease.updatedAt = nowIso();
|
|
437
|
+
count += 1;
|
|
438
|
+
}
|
|
439
|
+
return count;
|
|
440
|
+
}
|
|
268
441
|
export async function listBrowserUseLeases(context, json = false) {
|
|
442
|
+
let reapedCount = 0;
|
|
443
|
+
// Auto-reap stale leases before listing
|
|
444
|
+
await withRegistryLock(context.status, async () => {
|
|
445
|
+
const registry = readRegistry(context.status);
|
|
446
|
+
reapedCount = await reapStaleLeasesInRegistry(context.status, registry);
|
|
447
|
+
if (reapedCount > 0) {
|
|
448
|
+
await writeRegistry(context.status, registry);
|
|
449
|
+
}
|
|
450
|
+
});
|
|
269
451
|
const registry = readRegistry(context.status);
|
|
270
452
|
const rows = registry.leases.map((lease) => ({
|
|
271
453
|
...lease,
|
|
@@ -282,7 +464,7 @@ export async function listBrowserUseLeases(context, json = false) {
|
|
|
282
464
|
}
|
|
283
465
|
for (const row of rows) {
|
|
284
466
|
const state = row.status === 'active' && !row.expired ? 'active' : row.expired ? 'expired' : row.status;
|
|
285
|
-
console.log(`${row.id}\t${state}\t${row.
|
|
467
|
+
console.log(`${row.id}\t${state}\t${row.holder}\t${row.sessionName}\t${row.userDataDir}`);
|
|
286
468
|
}
|
|
287
469
|
}
|
|
288
470
|
export async function releaseBrowserUseLease(context, id, options = {}) {
|
|
@@ -297,7 +479,12 @@ export async function releaseBrowserUseLease(context, id, options = {}) {
|
|
|
297
479
|
suggestion: 'Run `pibo tools browser-use lease list`.',
|
|
298
480
|
}));
|
|
299
481
|
}
|
|
300
|
-
|
|
482
|
+
if (lease.browserPoolLeaseId) {
|
|
483
|
+
await releaseAssociatedBrowserPoolLease(context.status, lease);
|
|
484
|
+
}
|
|
485
|
+
else {
|
|
486
|
+
killLeaseProcess(context.status, lease);
|
|
487
|
+
}
|
|
301
488
|
lease.status = 'released';
|
|
302
489
|
lease.updatedAt = nowIso();
|
|
303
490
|
if (options.deleteProfile) {
|
|
@@ -310,16 +497,7 @@ export async function releaseBrowserUseLease(context, id, options = {}) {
|
|
|
310
497
|
export async function reapStaleBrowserUseLeases(context) {
|
|
311
498
|
await withRegistryLock(context.status, async () => {
|
|
312
499
|
const registry = readRegistry(context.status);
|
|
313
|
-
|
|
314
|
-
for (const lease of registry.leases) {
|
|
315
|
-
if (lease.status !== 'active' || !isExpired(lease))
|
|
316
|
-
continue;
|
|
317
|
-
if (leaseProcessIsAlive(context.status, lease))
|
|
318
|
-
killLeaseProcess(context.status, lease);
|
|
319
|
-
lease.status = 'released';
|
|
320
|
-
lease.updatedAt = nowIso();
|
|
321
|
-
count += 1;
|
|
322
|
-
}
|
|
500
|
+
const count = await reapStaleLeasesInRegistry(context.status, registry);
|
|
323
501
|
await writeRegistry(context.status, registry);
|
|
324
502
|
console.log(`Reaped ${count} stale browser-use auth lease${count === 1 ? '' : 's'}`);
|
|
325
503
|
});
|