@pasko70/pibo 1.0.5 → 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 -250
- 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 +42 -5
- 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 +47 -0
- 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 +3168 -1811
- 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-CI0Xj2Cp.js → dist-B4lw9z4F.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-aMr2VYOu.js → dist-BbTaHWON.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-u2OzzOTm.js → dist-BcT_c1EJ.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-Di1ScJ22.js → dist-CGINd7XU.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-wiRpAHIv.js → dist-CrBzZkUp.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-CaNOvqMY.js → dist-CyyISotB.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-zgYUl2B-.js → dist-DFbnFNpX.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-CNlhGq5i.js → dist-DGLWQLX8.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-BGxHKHPX.js → dist-DfcIkFSN.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-DrM-H3e1.js → dist-sKDHTwaT.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-DpmEro5R.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 +174 -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 +252 -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 +66 -2
- 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 +214 -0
- package/dist/user-skills/manager.js +35 -0
- package/dist/user-skills/store.js +267 -0
- package/dist/user-skills/types.js +1 -0
- 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/{.codex/skills → 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-B_E935fP.js +0 -151
- package/dist/apps/chat-ui/assets/index-Dk-opWl3.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
- /package/{.codex/skills → skills/builtin}/pi-agent-harness/agents/openai.yaml +0 -0
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { PythonRuntimeBackend } from "./python-backend.js";
|
|
3
|
+
import { NodeRuntimeBackend } from "./node-backend.js";
|
|
4
|
+
function nowIso() {
|
|
5
|
+
return new Date().toISOString();
|
|
6
|
+
}
|
|
7
|
+
function notFoundExec(sessionId = "auto") {
|
|
8
|
+
return {
|
|
9
|
+
status: "not_found",
|
|
10
|
+
sessionId,
|
|
11
|
+
durationMs: 0,
|
|
12
|
+
error: { name: "RuntimeNotFound", message: `Runtime session "${sessionId}" was not found.` },
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
function notFoundInspect(sessionId = "auto") {
|
|
16
|
+
return {
|
|
17
|
+
status: "not_found",
|
|
18
|
+
sessionId,
|
|
19
|
+
error: { name: "RuntimeNotFound", message: `Runtime session "${sessionId}" was not found.` },
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
function notFoundVars(sessionId = "auto") {
|
|
23
|
+
return {
|
|
24
|
+
status: "not_found",
|
|
25
|
+
sessionId,
|
|
26
|
+
variables: [],
|
|
27
|
+
error: { name: "RuntimeNotFound", message: `Runtime session "${sessionId}" was not found.` },
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
export class RuntimeSessionRegistry {
|
|
31
|
+
options;
|
|
32
|
+
sessions = new Map();
|
|
33
|
+
maxHistoryEntries;
|
|
34
|
+
constructor(options) {
|
|
35
|
+
this.options = options;
|
|
36
|
+
this.maxHistoryEntries = options.maxHistoryEntries ?? 100;
|
|
37
|
+
}
|
|
38
|
+
async start(controllerPiboSessionId, input) {
|
|
39
|
+
if (input.target?.type && input.target.type !== "local") {
|
|
40
|
+
return {
|
|
41
|
+
status: "error",
|
|
42
|
+
error: { name: "UnsupportedRuntimeTarget", message: `Runtime target "${input.target.type}" is not implemented yet.` },
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
const sessionId = `rt_${input.runtime}_${randomUUID().slice(0, 8)}`;
|
|
46
|
+
try {
|
|
47
|
+
const backend = input.runtime === "python"
|
|
48
|
+
? await PythonRuntimeBackend.start(this.options.cwd, input)
|
|
49
|
+
: await NodeRuntimeBackend.start(this.options.cwd, input);
|
|
50
|
+
const startedAt = nowIso();
|
|
51
|
+
const record = backend.getRecord();
|
|
52
|
+
const session = {
|
|
53
|
+
sessionId,
|
|
54
|
+
runtime: input.runtime,
|
|
55
|
+
name: input.name,
|
|
56
|
+
cwd: record.cwd,
|
|
57
|
+
status: "idle",
|
|
58
|
+
startedAt,
|
|
59
|
+
updatedAt: startedAt,
|
|
60
|
+
executionCount: 0,
|
|
61
|
+
pid: record.pid,
|
|
62
|
+
executable: record.executable,
|
|
63
|
+
controllerPiboSessionId,
|
|
64
|
+
backend,
|
|
65
|
+
history: [],
|
|
66
|
+
};
|
|
67
|
+
this.sessions.set(sessionId, session);
|
|
68
|
+
return { status: "ok", sessionId, runtime: input.runtime, name: input.name, ...record, startedAt };
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
return {
|
|
72
|
+
status: "failed",
|
|
73
|
+
sessionId,
|
|
74
|
+
runtime: input.runtime,
|
|
75
|
+
error: error instanceof Error
|
|
76
|
+
? { name: error.name, message: error.message, stack: error.stack }
|
|
77
|
+
: { name: "RuntimeStartError", message: String(error) },
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
async exec(controllerPiboSessionId, input) {
|
|
82
|
+
const session = input.sessionId
|
|
83
|
+
? this.getSessionForController(controllerPiboSessionId, input.sessionId)
|
|
84
|
+
: await this.getOrStartDefault(controllerPiboSessionId, input);
|
|
85
|
+
const sessionId = input.sessionId ?? session?.sessionId ?? "auto";
|
|
86
|
+
if (!session)
|
|
87
|
+
return notFoundExec(sessionId);
|
|
88
|
+
if (session.status === "closed" || session.status === "failed")
|
|
89
|
+
return notFoundExec(sessionId);
|
|
90
|
+
if (session.status === "busy") {
|
|
91
|
+
return {
|
|
92
|
+
status: "failed",
|
|
93
|
+
sessionId,
|
|
94
|
+
runtime: session.runtime,
|
|
95
|
+
durationMs: 0,
|
|
96
|
+
error: { name: "RuntimeBusy", message: `Runtime session "${sessionId}" is already busy.` },
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
const startedAt = nowIso();
|
|
100
|
+
session.status = "busy";
|
|
101
|
+
session.updatedAt = startedAt;
|
|
102
|
+
const result = await session.backend.exec(input);
|
|
103
|
+
result.sessionId = session.sessionId;
|
|
104
|
+
result.runtime = session.runtime;
|
|
105
|
+
session.executionCount += 1;
|
|
106
|
+
result.executionCount = session.executionCount;
|
|
107
|
+
session.lastExecAt = startedAt;
|
|
108
|
+
session.updatedAt = nowIso();
|
|
109
|
+
if (result.status === "failed" && !session.backend.isAlive()) {
|
|
110
|
+
session.status = "failed";
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
session.status = "idle";
|
|
114
|
+
}
|
|
115
|
+
this.appendHistory(session, {
|
|
116
|
+
id: randomUUID(),
|
|
117
|
+
startedAt,
|
|
118
|
+
durationMs: result.durationMs,
|
|
119
|
+
code: input.code,
|
|
120
|
+
status: result.status,
|
|
121
|
+
error: result.error,
|
|
122
|
+
});
|
|
123
|
+
if (input.closeOnSuccess === true && result.status === "ok") {
|
|
124
|
+
await this.close(controllerPiboSessionId, { sessionId: session.sessionId });
|
|
125
|
+
result.autoClosed = true;
|
|
126
|
+
}
|
|
127
|
+
return result;
|
|
128
|
+
}
|
|
129
|
+
async inspect(controllerPiboSessionId, input) {
|
|
130
|
+
const session = input.sessionId ? this.getSessionForController(controllerPiboSessionId, input.sessionId) : this.getDefault(controllerPiboSessionId, input.runtime ?? "python");
|
|
131
|
+
if (!session)
|
|
132
|
+
return notFoundInspect(input.sessionId);
|
|
133
|
+
const result = await session.backend.inspect(input);
|
|
134
|
+
return { ...result, sessionId: session.sessionId };
|
|
135
|
+
}
|
|
136
|
+
async vars(controllerPiboSessionId, input) {
|
|
137
|
+
const session = input.sessionId ? this.getSessionForController(controllerPiboSessionId, input.sessionId) : this.getDefault(controllerPiboSessionId, input.runtime ?? "python");
|
|
138
|
+
if (!session)
|
|
139
|
+
return notFoundVars(input.sessionId);
|
|
140
|
+
const result = await session.backend.vars(input);
|
|
141
|
+
return { ...result, sessionId: session.sessionId };
|
|
142
|
+
}
|
|
143
|
+
async interrupt(controllerPiboSessionId, input) {
|
|
144
|
+
const session = input.sessionId ? this.getSessionForController(controllerPiboSessionId, input.sessionId) : this.getDefault(controllerPiboSessionId, input.runtime ?? "python");
|
|
145
|
+
const sessionId = input.sessionId ?? session?.sessionId ?? "auto";
|
|
146
|
+
if (!session)
|
|
147
|
+
return { status: "not_found", sessionId, message: `Runtime session "${sessionId}" was not found.` };
|
|
148
|
+
const result = await session.backend.interrupt();
|
|
149
|
+
return { ...result, sessionId: session.sessionId };
|
|
150
|
+
}
|
|
151
|
+
async close(controllerPiboSessionId, input) {
|
|
152
|
+
const session = this.getSessionForController(controllerPiboSessionId, input.sessionId);
|
|
153
|
+
if (!session)
|
|
154
|
+
return { status: "not_found", sessionId: input.sessionId, closed: false, message: `Runtime session "${input.sessionId}" was not found.` };
|
|
155
|
+
try {
|
|
156
|
+
await session.backend.close(input.force);
|
|
157
|
+
session.status = "closed";
|
|
158
|
+
session.updatedAt = nowIso();
|
|
159
|
+
this.sessions.delete(session.sessionId);
|
|
160
|
+
return { status: "ok", sessionId: input.sessionId, closed: true };
|
|
161
|
+
}
|
|
162
|
+
catch (error) {
|
|
163
|
+
session.status = "failed";
|
|
164
|
+
return {
|
|
165
|
+
status: "failed",
|
|
166
|
+
sessionId: input.sessionId,
|
|
167
|
+
closed: false,
|
|
168
|
+
error: error instanceof Error
|
|
169
|
+
? { name: error.name, message: error.message, stack: error.stack }
|
|
170
|
+
: { name: "RuntimeCloseError", message: String(error) },
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
list(controllerPiboSessionId) {
|
|
175
|
+
return {
|
|
176
|
+
status: "ok",
|
|
177
|
+
sessions: [...this.sessions.values()]
|
|
178
|
+
.filter((session) => session.controllerPiboSessionId === controllerPiboSessionId)
|
|
179
|
+
.map(toRecord),
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
async closeControllerSessions(controllerPiboSessionId, options = {}) {
|
|
183
|
+
const sessions = [...this.sessions.values()].filter((session) => session.controllerPiboSessionId === controllerPiboSessionId);
|
|
184
|
+
await Promise.all(sessions.map((session) => this.close(controllerPiboSessionId, { sessionId: session.sessionId, force: options.force })));
|
|
185
|
+
}
|
|
186
|
+
async closeAll(options = {}) {
|
|
187
|
+
const sessions = [...this.sessions.values()];
|
|
188
|
+
await Promise.all(sessions.map((session) => this.close(session.controllerPiboSessionId, { sessionId: session.sessionId, force: options.force })));
|
|
189
|
+
}
|
|
190
|
+
pruneIdle(now = Date.now(), idleTimeoutMs = 30 * 60 * 1000) {
|
|
191
|
+
for (const session of this.sessions.values()) {
|
|
192
|
+
if (session.status !== "idle")
|
|
193
|
+
continue;
|
|
194
|
+
if (now - Date.parse(session.updatedAt) > idleTimeoutMs) {
|
|
195
|
+
void this.close(session.controllerPiboSessionId, { sessionId: session.sessionId, force: true });
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
createController(controllerPiboSessionId) {
|
|
200
|
+
return {
|
|
201
|
+
start: (input) => this.start(controllerPiboSessionId, input),
|
|
202
|
+
exec: (input) => this.exec(controllerPiboSessionId, input),
|
|
203
|
+
inspect: (input) => this.inspect(controllerPiboSessionId, input),
|
|
204
|
+
vars: (input) => this.vars(controllerPiboSessionId, input),
|
|
205
|
+
interrupt: (input) => this.interrupt(controllerPiboSessionId, input),
|
|
206
|
+
close: (input) => this.close(controllerPiboSessionId, input),
|
|
207
|
+
list: () => this.list(controllerPiboSessionId),
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
getDefault(controllerPiboSessionId, runtime) {
|
|
211
|
+
return [...this.sessions.values()].find((session) => session.controllerPiboSessionId === controllerPiboSessionId &&
|
|
212
|
+
session.runtime === runtime &&
|
|
213
|
+
session.status !== "closed" &&
|
|
214
|
+
session.status !== "failed");
|
|
215
|
+
}
|
|
216
|
+
async getOrStartDefault(controllerPiboSessionId, input) {
|
|
217
|
+
const runtime = input.runtime ?? "python";
|
|
218
|
+
const existing = this.getDefault(controllerPiboSessionId, runtime);
|
|
219
|
+
if (existing)
|
|
220
|
+
return existing;
|
|
221
|
+
const started = await this.start(controllerPiboSessionId, {
|
|
222
|
+
runtime,
|
|
223
|
+
name: input.name,
|
|
224
|
+
target: input.target,
|
|
225
|
+
timeoutMs: input.timeoutMs,
|
|
226
|
+
});
|
|
227
|
+
return started.sessionId ? this.getSessionForController(controllerPiboSessionId, started.sessionId) : undefined;
|
|
228
|
+
}
|
|
229
|
+
getSessionForController(controllerPiboSessionId, sessionId) {
|
|
230
|
+
const session = this.sessions.get(sessionId);
|
|
231
|
+
if (!session || session.controllerPiboSessionId !== controllerPiboSessionId)
|
|
232
|
+
return undefined;
|
|
233
|
+
return session;
|
|
234
|
+
}
|
|
235
|
+
appendHistory(session, entry) {
|
|
236
|
+
session.history.push(entry);
|
|
237
|
+
if (session.history.length > this.maxHistoryEntries)
|
|
238
|
+
session.history.splice(0, session.history.length - this.maxHistoryEntries);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
function toRecord(session) {
|
|
242
|
+
return {
|
|
243
|
+
sessionId: session.sessionId,
|
|
244
|
+
runtime: session.runtime,
|
|
245
|
+
name: session.name,
|
|
246
|
+
cwd: session.cwd,
|
|
247
|
+
status: session.status,
|
|
248
|
+
startedAt: session.startedAt,
|
|
249
|
+
updatedAt: session.updatedAt,
|
|
250
|
+
lastExecAt: session.lastExecAt,
|
|
251
|
+
executionCount: session.executionCount,
|
|
252
|
+
pid: session.pid,
|
|
253
|
+
executable: session.executable,
|
|
254
|
+
};
|
|
255
|
+
}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import { StringEnum, Type } from "@mariozechner/pi-ai";
|
|
2
|
+
import { defineTool } from "@mariozechner/pi-coding-agent";
|
|
3
|
+
export function createRuntimeToolProfile() {
|
|
4
|
+
return {
|
|
5
|
+
name: "runtime",
|
|
6
|
+
description: "Run Python/Node code in persistent runtime sessions; exec runs normal scripts.",
|
|
7
|
+
yieldable: true,
|
|
8
|
+
builtInPiboTool: "runtime",
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
function requireString(value, field) {
|
|
12
|
+
if (typeof value !== "string" || value.length === 0)
|
|
13
|
+
throw new Error(`runtime.${field} must be a non-empty string`);
|
|
14
|
+
return value;
|
|
15
|
+
}
|
|
16
|
+
function asObject(value) {
|
|
17
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : undefined;
|
|
18
|
+
}
|
|
19
|
+
function validateTarget(value) {
|
|
20
|
+
const object = asObject(value);
|
|
21
|
+
if (!object)
|
|
22
|
+
return undefined;
|
|
23
|
+
const target = {};
|
|
24
|
+
if (object.type !== undefined) {
|
|
25
|
+
if (object.type !== "local" && object.type !== "docker" && object.type !== "ssh")
|
|
26
|
+
throw new Error("runtime.target.type must be local, docker, or ssh");
|
|
27
|
+
target.type = object.type;
|
|
28
|
+
}
|
|
29
|
+
if (object.cwd !== undefined)
|
|
30
|
+
target.cwd = requireString(object.cwd, "target.cwd");
|
|
31
|
+
if (object.executable !== undefined)
|
|
32
|
+
target.executable = requireString(object.executable, "target.executable");
|
|
33
|
+
if (object.args !== undefined) {
|
|
34
|
+
if (!Array.isArray(object.args) || object.args.some((arg) => typeof arg !== "string"))
|
|
35
|
+
throw new Error("runtime.target.args must be an array of strings");
|
|
36
|
+
target.args = [...object.args];
|
|
37
|
+
}
|
|
38
|
+
if (object.env !== undefined) {
|
|
39
|
+
const env = asObject(object.env);
|
|
40
|
+
if (!env)
|
|
41
|
+
throw new Error("runtime.target.env must be an object");
|
|
42
|
+
target.env = Object.fromEntries(Object.entries(env).map(([key, value]) => [key, requireString(value, `target.env.${key}`)]));
|
|
43
|
+
}
|
|
44
|
+
return target;
|
|
45
|
+
}
|
|
46
|
+
function resultStatus(result) {
|
|
47
|
+
return asObject(result)?.status;
|
|
48
|
+
}
|
|
49
|
+
function isErrorStatus(status) {
|
|
50
|
+
return status !== undefined && status !== "ok";
|
|
51
|
+
}
|
|
52
|
+
function formatRuntimeResult(result) {
|
|
53
|
+
const object = asObject(result) ?? {};
|
|
54
|
+
const lines = [
|
|
55
|
+
`status: ${object.status ?? "unknown"}`,
|
|
56
|
+
];
|
|
57
|
+
if (object.sessionId)
|
|
58
|
+
lines.push(`sessionId: ${object.sessionId}`);
|
|
59
|
+
if (object.runtime)
|
|
60
|
+
lines.push(`runtime: ${object.runtime}`);
|
|
61
|
+
if (object.autoClosed !== undefined)
|
|
62
|
+
lines.push(`autoClosed: ${object.autoClosed}`);
|
|
63
|
+
if (object.executionCount !== undefined)
|
|
64
|
+
lines.push(`executionCount: ${object.executionCount}`);
|
|
65
|
+
if (object.durationMs !== undefined)
|
|
66
|
+
lines.push(`durationMs: ${object.durationMs}`);
|
|
67
|
+
if (typeof object.stdout === "string" && object.stdout.length > 0)
|
|
68
|
+
lines.push("", "stdout:", object.stdout);
|
|
69
|
+
if (typeof object.stderr === "string" && object.stderr.length > 0)
|
|
70
|
+
lines.push("", "stderr:", object.stderr);
|
|
71
|
+
if (object.result !== undefined && object.result !== null)
|
|
72
|
+
lines.push("", "result:", JSON.stringify(object.result, null, 2));
|
|
73
|
+
if (object.error !== undefined)
|
|
74
|
+
lines.push("", "error:", JSON.stringify(object.error, null, 2));
|
|
75
|
+
if (object.sessions !== undefined)
|
|
76
|
+
lines.push("", "sessions:", JSON.stringify(object.sessions, null, 2));
|
|
77
|
+
if (object.variables !== undefined)
|
|
78
|
+
lines.push("", "variables:", JSON.stringify(object.variables, null, 2));
|
|
79
|
+
if (object.summary !== undefined)
|
|
80
|
+
lines.push("", "summary:", JSON.stringify(object.summary, null, 2));
|
|
81
|
+
if (object.signature !== undefined)
|
|
82
|
+
lines.push("", "signature:", String(object.signature));
|
|
83
|
+
if (object.members !== undefined)
|
|
84
|
+
lines.push("", "members:", JSON.stringify(object.members, null, 2));
|
|
85
|
+
if (object.source !== undefined)
|
|
86
|
+
lines.push("", "source:", String(object.source));
|
|
87
|
+
if (object.doc !== undefined)
|
|
88
|
+
lines.push("", "doc:", String(object.doc));
|
|
89
|
+
if (object.closed !== undefined)
|
|
90
|
+
lines.push(`closed: ${object.closed}`);
|
|
91
|
+
if (object.message !== undefined)
|
|
92
|
+
lines.push(`message: ${object.message}`);
|
|
93
|
+
return lines.join("\n");
|
|
94
|
+
}
|
|
95
|
+
export function createRuntimeToolDefinition(controller) {
|
|
96
|
+
return defineTool({
|
|
97
|
+
name: "runtime",
|
|
98
|
+
label: "Runtime",
|
|
99
|
+
description: "Run Python/Node code in persistent sessions. Use this instead of bash for Python/Node execution except trivial one-line shell checks.",
|
|
100
|
+
promptSnippet: "Use runtime for Python/Node execution, especially longer snippets (~20+ lines), uncertain code, or objects/state to inspect. Prefer runtime over bash for Python/Node except trivial one-line shell checks. Auto-starts on exec; print values you need. Runtime keeps variables and processes alive between calls; reuse sessionId to inspect or continue from that state after partial failures. This saves output tokens and keeps your mental model tied to live state. Use read for file contents; use bash for shell commands and package installs.",
|
|
101
|
+
executionMode: "parallel",
|
|
102
|
+
parameters: Type.Object({
|
|
103
|
+
action: StringEnum(["exec", "inspect", "vars", "interrupt", "list"], { description: "Runtime action to perform." }),
|
|
104
|
+
runtime: Type.Optional(StringEnum(["python", "node"], { description: "Runtime kind; default python." })),
|
|
105
|
+
name: Type.Optional(Type.String({ description: "Optional human-readable runtime name." })),
|
|
106
|
+
target: Type.Optional(Type.Any({ description: "Auto-start target options such as { type: 'local', cwd, executable, args, env }." })),
|
|
107
|
+
sessionId: Type.Optional(Type.String({ description: "Existing runtime session id; omit to use auto runtime." })),
|
|
108
|
+
code: Type.Optional(Type.String({ description: "Code to execute for exec." })),
|
|
109
|
+
timeoutMs: Type.Optional(Type.Number({ description: "Action timeout in milliseconds." })),
|
|
110
|
+
mode: Type.Optional(StringEnum(["exec", "eval", "auto"], { description: "For exec: execution mode. Use eval when you need an expression result." })),
|
|
111
|
+
closeOnSuccess: Type.Optional(Type.Boolean({ description: "For exec: close the runtime only if execution succeeds." })),
|
|
112
|
+
expression: Type.Optional(Type.String({ description: "Expression to inspect." })),
|
|
113
|
+
what: Type.Optional(StringEnum(["summary", "signature", "members", "source", "doc", "all"], { description: "Inspection detail to return." })),
|
|
114
|
+
maxBytes: Type.Optional(Type.Number({ description: "Maximum bytes for summaries or inspect fields." })),
|
|
115
|
+
includePrivate: Type.Optional(Type.Boolean({ description: "For vars: include private names." })),
|
|
116
|
+
maxItems: Type.Optional(Type.Number({ description: "For vars: maximum variables to return." })),
|
|
117
|
+
}),
|
|
118
|
+
async execute(_toolCallId, params) {
|
|
119
|
+
let result;
|
|
120
|
+
try {
|
|
121
|
+
switch (params.action) {
|
|
122
|
+
case "exec":
|
|
123
|
+
result = await controller.exec({
|
|
124
|
+
sessionId: params.sessionId,
|
|
125
|
+
runtime: params.runtime,
|
|
126
|
+
name: params.name,
|
|
127
|
+
target: validateTarget(params.target),
|
|
128
|
+
code: requireString(params.code, "code"),
|
|
129
|
+
timeoutMs: params.timeoutMs,
|
|
130
|
+
mode: params.mode,
|
|
131
|
+
closeOnSuccess: params.closeOnSuccess,
|
|
132
|
+
});
|
|
133
|
+
break;
|
|
134
|
+
case "inspect":
|
|
135
|
+
result = await controller.inspect({
|
|
136
|
+
sessionId: params.sessionId,
|
|
137
|
+
runtime: params.runtime,
|
|
138
|
+
expression: requireString(params.expression, "expression"),
|
|
139
|
+
what: params.what,
|
|
140
|
+
maxBytes: params.maxBytes,
|
|
141
|
+
});
|
|
142
|
+
break;
|
|
143
|
+
case "vars":
|
|
144
|
+
result = await controller.vars({ sessionId: params.sessionId, runtime: params.runtime, includePrivate: params.includePrivate, maxItems: params.maxItems, maxBytes: params.maxBytes });
|
|
145
|
+
break;
|
|
146
|
+
case "interrupt":
|
|
147
|
+
result = await controller.interrupt({ sessionId: params.sessionId, runtime: params.runtime });
|
|
148
|
+
break;
|
|
149
|
+
case "list":
|
|
150
|
+
result = await controller.list({});
|
|
151
|
+
break;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
catch (error) {
|
|
155
|
+
result = {
|
|
156
|
+
status: "failed",
|
|
157
|
+
error: error instanceof Error ? { name: error.name, message: error.message, stack: error.stack } : { name: "RuntimeToolError", message: String(error) },
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
const status = resultStatus(result);
|
|
161
|
+
return {
|
|
162
|
+
content: [{ type: "text", text: formatRuntimeResult(result) }],
|
|
163
|
+
details: result,
|
|
164
|
+
isError: isErrorStatus(status),
|
|
165
|
+
};
|
|
166
|
+
},
|
|
167
|
+
});
|
|
168
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/tools/web-search.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export const WEB_SEARCH_PROMPT_CONTRIBUTION = "web_search is available as a Pibo native tool through the OpenAI provider adapter. Use it when current or externally sourced information is needed.";
|
|
1
2
|
const WEB_SEARCH_SOURCES_INCLUDE = "web_search_call.action.sources";
|
|
2
3
|
function hasProviderResponsesShape(payload) {
|
|
3
4
|
return Boolean(payload && typeof payload === "object" && "input" in payload);
|
|
@@ -100,7 +101,7 @@ const openAiWebSearchAdapter = {
|
|
|
100
101
|
systemPrompt: [
|
|
101
102
|
event.systemPrompt,
|
|
102
103
|
"# Native Web Search",
|
|
103
|
-
|
|
104
|
+
WEB_SEARCH_PROMPT_CONTRIBUTION,
|
|
104
105
|
].join("\n\n"),
|
|
105
106
|
}));
|
|
106
107
|
pi.on("before_provider_request", (event) => addOpenAiWebSearchProviderTool(event.payload, config));
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { dirname, join } from "node:path";
|
|
3
|
+
import { defaultUserSkillDir, parseSkillMd } from "./store.js";
|
|
4
|
+
export function parseSkillUrl(url) {
|
|
5
|
+
const trimmed = url.trim();
|
|
6
|
+
// skills.sh: https://skills.sh/{account}/skills/{skill-name}
|
|
7
|
+
// skills.sh: https://skills.sh/{account}/{repo}/{skill-name}
|
|
8
|
+
if (trimmed.startsWith("https://skills.sh/")) {
|
|
9
|
+
const rest = trimmed.slice("https://skills.sh/".length);
|
|
10
|
+
const parts = rest.split("/").filter(Boolean);
|
|
11
|
+
if (parts.length >= 3) {
|
|
12
|
+
// Format: {account}/{repo}/{skill-name} (e.g. softaworks/agent-toolkit/writing-clearly)
|
|
13
|
+
const account = parts[0];
|
|
14
|
+
const repo = parts[1];
|
|
15
|
+
const skillName = parts[2];
|
|
16
|
+
return { account, repo, path: `skills/${skillName}`, skillName };
|
|
17
|
+
}
|
|
18
|
+
if (parts.length >= 2 && parts[1] === "skills") {
|
|
19
|
+
const account = parts[0];
|
|
20
|
+
const skillName = parts[2] ?? parts[0];
|
|
21
|
+
return { account, repo: "skills", path: `skills/${skillName}`, skillName };
|
|
22
|
+
}
|
|
23
|
+
if (parts.length === 2) {
|
|
24
|
+
// Format: {account}/skills or {account}/{repo}
|
|
25
|
+
if (parts[1] === "skills") {
|
|
26
|
+
return { account: parts[0], repo: "skills" };
|
|
27
|
+
}
|
|
28
|
+
return { account: parts[0], repo: parts[1] };
|
|
29
|
+
}
|
|
30
|
+
if (parts.length === 1) {
|
|
31
|
+
return { account: parts[0], repo: "skills" };
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
// GitHub tree URL: https://github.com/{account}/{repo}/tree/{branch}/{path}
|
|
35
|
+
const githubTreeMatch = trimmed.match(/^https:\/\/github\.com\/([^\/]+)\/([^\/]+)\/tree\/[^\/]+\/(.+)$/);
|
|
36
|
+
if (githubTreeMatch) {
|
|
37
|
+
const account = githubTreeMatch[1];
|
|
38
|
+
const repo = githubTreeMatch[2];
|
|
39
|
+
const path = githubTreeMatch[3];
|
|
40
|
+
const skillName = path.split("/").pop() ?? repo;
|
|
41
|
+
return { account, repo, path, skillName };
|
|
42
|
+
}
|
|
43
|
+
// GitHub shorthand or repo URL: https://github.com/{account}/{repo}
|
|
44
|
+
const githubRepoMatch = trimmed.match(/^https:\/\/github\.com\/([^\/]+)\/([^\/]+)$/);
|
|
45
|
+
if (githubRepoMatch) {
|
|
46
|
+
return { account: githubRepoMatch[1], repo: githubRepoMatch[2] };
|
|
47
|
+
}
|
|
48
|
+
// Bare shorthand: {account}/{repo} or {account}/{repo}/{skill-path}
|
|
49
|
+
const shorthandMatch = trimmed.match(/^([^\/\s]+)\/([^\/\s]+)(?:\/(.+))?$/);
|
|
50
|
+
if (shorthandMatch && !trimmed.startsWith("http")) {
|
|
51
|
+
const account = shorthandMatch[1];
|
|
52
|
+
const repo = shorthandMatch[2];
|
|
53
|
+
const path = shorthandMatch[3];
|
|
54
|
+
const skillName = path?.split("/").pop() ?? repo;
|
|
55
|
+
return { account, repo, path, skillName };
|
|
56
|
+
}
|
|
57
|
+
return undefined;
|
|
58
|
+
}
|
|
59
|
+
async function fetchGitHubContents(account, repo, path) {
|
|
60
|
+
const apiUrl = `https://api.github.com/repos/${encodeURIComponent(account)}/${encodeURIComponent(repo)}/contents/${encodeURIComponent(path)}`;
|
|
61
|
+
const response = await fetch(apiUrl, {
|
|
62
|
+
headers: { Accept: "application/vnd.github.v3+json", "User-Agent": "pibo-skills-installer" },
|
|
63
|
+
});
|
|
64
|
+
if (!response.ok) {
|
|
65
|
+
const text = await response.text().catch(() => "");
|
|
66
|
+
throw new Error(`GitHub API error (${response.status}): ${text || response.statusText}`);
|
|
67
|
+
}
|
|
68
|
+
const data = (await response.json());
|
|
69
|
+
if (!Array.isArray(data)) {
|
|
70
|
+
throw new Error(`Expected directory listing from GitHub API, got: ${typeof data}`);
|
|
71
|
+
}
|
|
72
|
+
return data;
|
|
73
|
+
}
|
|
74
|
+
async function fetchGitHubFile(downloadUrl) {
|
|
75
|
+
const response = await fetch(downloadUrl, { headers: { "User-Agent": "pibo-skills-installer" } });
|
|
76
|
+
if (!response.ok) {
|
|
77
|
+
throw new Error(`Failed to download file (${response.status}): ${downloadUrl}`);
|
|
78
|
+
}
|
|
79
|
+
return new Uint8Array(await response.arrayBuffer());
|
|
80
|
+
}
|
|
81
|
+
async function downloadDirectory(account, repo, path, targetDir) {
|
|
82
|
+
const items = await fetchGitHubContents(account, repo, path);
|
|
83
|
+
for (const item of items) {
|
|
84
|
+
const targetPath = join(targetDir, item.name);
|
|
85
|
+
if (item.type === "file") {
|
|
86
|
+
if (!item.download_url)
|
|
87
|
+
continue;
|
|
88
|
+
const content = await fetchGitHubFile(item.download_url);
|
|
89
|
+
mkdirSync(dirname(targetPath), { recursive: true });
|
|
90
|
+
writeFileSync(targetPath, content);
|
|
91
|
+
}
|
|
92
|
+
else if (item.type === "dir") {
|
|
93
|
+
mkdirSync(targetPath, { recursive: true });
|
|
94
|
+
await downloadDirectory(account, repo, item.path, targetPath);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
async function findSkillMdPath(items) {
|
|
99
|
+
return items.find((item) => item.type === "file" && item.name.toLowerCase() === "skill.md");
|
|
100
|
+
}
|
|
101
|
+
async function findSkillDirectory(account, repo, path) {
|
|
102
|
+
if (path) {
|
|
103
|
+
const items = await fetchGitHubContents(account, repo, path);
|
|
104
|
+
const skillMd = await findSkillMdPath(items);
|
|
105
|
+
if (skillMd) {
|
|
106
|
+
return { path, skillName: path.split("/").pop() ?? repo };
|
|
107
|
+
}
|
|
108
|
+
// If no SKILL.md at this path, search subdirectories one level deep
|
|
109
|
+
for (const item of items) {
|
|
110
|
+
if (item.type === "dir") {
|
|
111
|
+
const subItems = await fetchGitHubContents(account, repo, item.path).catch(() => []);
|
|
112
|
+
const subSkillMd = await findSkillMdPath(subItems);
|
|
113
|
+
if (subSkillMd) {
|
|
114
|
+
return { path: item.path, skillName: item.name };
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
// Try common skill directories
|
|
120
|
+
const candidates = ["skills", "skill", "src/skills", "agents/skills"];
|
|
121
|
+
for (const candidate of candidates) {
|
|
122
|
+
const items = await fetchGitHubContents(account, repo, candidate).catch(() => []);
|
|
123
|
+
const skillMd = await findSkillMdPath(items);
|
|
124
|
+
if (skillMd) {
|
|
125
|
+
return { path: candidate, skillName: candidate };
|
|
126
|
+
}
|
|
127
|
+
// Search one level deep
|
|
128
|
+
for (const item of items) {
|
|
129
|
+
if (item.type === "dir") {
|
|
130
|
+
const subItems = await fetchGitHubContents(account, repo, item.path).catch(() => []);
|
|
131
|
+
const subSkillMd = await findSkillMdPath(subItems);
|
|
132
|
+
if (subSkillMd) {
|
|
133
|
+
return { path: item.path, skillName: item.name };
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
// Search repository root for SKILL.md
|
|
139
|
+
const rootItems = await fetchGitHubContents(account, repo, "").catch(() => []);
|
|
140
|
+
const rootSkillMd = await findSkillMdPath(rootItems);
|
|
141
|
+
if (rootSkillMd) {
|
|
142
|
+
return { path: "", skillName: repo };
|
|
143
|
+
}
|
|
144
|
+
throw new Error(`Could not find a SKILL.md in ${account}/${repo}${path ? `/${path}` : ""}`);
|
|
145
|
+
}
|
|
146
|
+
export async function installSkillFromUrl(url, cwd = process.cwd()) {
|
|
147
|
+
const source = parseSkillUrl(url);
|
|
148
|
+
if (!source) {
|
|
149
|
+
throw new Error(`Unsupported skill URL format: ${url}`);
|
|
150
|
+
}
|
|
151
|
+
const { account, repo, path, skillName } = source;
|
|
152
|
+
const resolved = path
|
|
153
|
+
? { path, skillName: skillName ?? path.split("/").pop() ?? repo }
|
|
154
|
+
: await findSkillDirectory(account, repo);
|
|
155
|
+
const targetName = resolved.skillName;
|
|
156
|
+
const targetDir = join(defaultUserSkillDir(cwd), targetName);
|
|
157
|
+
if (existsSync(targetDir)) {
|
|
158
|
+
throw new Error(`A skill named "${targetName}" already exists. Delete it first or choose a different name.`);
|
|
159
|
+
}
|
|
160
|
+
mkdirSync(targetDir, { recursive: true });
|
|
161
|
+
try {
|
|
162
|
+
await downloadDirectory(account, repo, resolved.path, targetDir);
|
|
163
|
+
}
|
|
164
|
+
catch (error) {
|
|
165
|
+
// Clean up on failure
|
|
166
|
+
try {
|
|
167
|
+
const { rmSync } = await import("node:fs");
|
|
168
|
+
rmSync(targetDir, { recursive: true, force: true });
|
|
169
|
+
}
|
|
170
|
+
catch {
|
|
171
|
+
// ignore cleanup errors
|
|
172
|
+
}
|
|
173
|
+
throw error;
|
|
174
|
+
}
|
|
175
|
+
// Read SKILL.md to extract name and description
|
|
176
|
+
const skillMdPath = join(targetDir, "SKILL.md");
|
|
177
|
+
if (!existsSync(skillMdPath)) {
|
|
178
|
+
throw new Error(`Download completed but no SKILL.md found in ${targetName}`);
|
|
179
|
+
}
|
|
180
|
+
const { readFileSync } = await import("node:fs");
|
|
181
|
+
const content = readFileSync(skillMdPath, "utf-8");
|
|
182
|
+
const parsed = parseSkillMd(content);
|
|
183
|
+
const name = parsed.name || targetName;
|
|
184
|
+
const description = parsed.description || "";
|
|
185
|
+
// Store the skill metadata (description lives in SKILL.md only, not JSON)
|
|
186
|
+
const { randomUUID } = await import("node:crypto");
|
|
187
|
+
const now = new Date().toISOString();
|
|
188
|
+
const skill = {
|
|
189
|
+
id: randomUUID(),
|
|
190
|
+
name,
|
|
191
|
+
description,
|
|
192
|
+
path: skillMdPath,
|
|
193
|
+
enabled: true,
|
|
194
|
+
source: url.includes("skills.sh") ? "skills.sh" : "github",
|
|
195
|
+
sourceUrl: url,
|
|
196
|
+
createdAt: now,
|
|
197
|
+
updatedAt: now,
|
|
198
|
+
};
|
|
199
|
+
const { loadUserSkillStore, saveUserSkillStore } = await import("./store.js");
|
|
200
|
+
const store = loadUserSkillStore(cwd);
|
|
201
|
+
const existing = store.skills.find((s) => s.name === name);
|
|
202
|
+
if (existing) {
|
|
203
|
+
const { rmSync } = await import("node:fs");
|
|
204
|
+
rmSync(targetDir, { recursive: true, force: true });
|
|
205
|
+
throw new Error(`A skill named "${name}" already exists. Delete it first or choose a different name.`);
|
|
206
|
+
}
|
|
207
|
+
// Strip description before persisting to JSON store.
|
|
208
|
+
const storedSkill = { ...skill };
|
|
209
|
+
delete storedSkill.description;
|
|
210
|
+
store.skills.push(storedSkill);
|
|
211
|
+
store.skills.sort((a, b) => a.name.localeCompare(b.name));
|
|
212
|
+
saveUserSkillStore(store, cwd);
|
|
213
|
+
return skill;
|
|
214
|
+
}
|