@wjarka/cezarion 0.10.0-pr30.54
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +838 -0
- package/dist/agent-config/account-identity.d.ts +44 -0
- package/dist/agent-config/account-identity.js +128 -0
- package/dist/agent-config/account-identity.js.map +1 -0
- package/dist/agent-config/catalog.d.ts +72 -0
- package/dist/agent-config/catalog.js +223 -0
- package/dist/agent-config/catalog.js.map +1 -0
- package/dist/agent-config/files.d.ts +46 -0
- package/dist/agent-config/files.js +119 -0
- package/dist/agent-config/files.js.map +1 -0
- package/dist/agent-config/model-settings/claude.d.ts +2 -0
- package/dist/agent-config/model-settings/claude.js +11 -0
- package/dist/agent-config/model-settings/claude.js.map +1 -0
- package/dist/agent-config/model-settings/codex.d.ts +2 -0
- package/dist/agent-config/model-settings/codex.js +16 -0
- package/dist/agent-config/model-settings/codex.js.map +1 -0
- package/dist/agent-config/model-settings/opencode.d.ts +2 -0
- package/dist/agent-config/model-settings/opencode.js +8 -0
- package/dist/agent-config/model-settings/opencode.js.map +1 -0
- package/dist/agent-config/model-settings/pi.d.ts +12 -0
- package/dist/agent-config/model-settings/pi.js +18 -0
- package/dist/agent-config/model-settings/pi.js.map +1 -0
- package/dist/agent-config/model-settings/shared.d.ts +9 -0
- package/dist/agent-config/model-settings/shared.js +93 -0
- package/dist/agent-config/model-settings/shared.js.map +1 -0
- package/dist/agent-config/model-settings/types.d.ts +9 -0
- package/dist/agent-config/model-settings/types.js +2 -0
- package/dist/agent-config/model-settings/types.js.map +1 -0
- package/dist/agent-config/models.d.ts +9 -0
- package/dist/agent-config/models.js +32 -0
- package/dist/agent-config/models.js.map +1 -0
- package/dist/agent-config/seed.d.ts +7 -0
- package/dist/agent-config/seed.js +90 -0
- package/dist/agent-config/seed.js.map +1 -0
- package/dist/agent-config/service.d.ts +44 -0
- package/dist/agent-config/service.js +71 -0
- package/dist/agent-config/service.js.map +1 -0
- package/dist/agent-config/validate.d.ts +21 -0
- package/dist/agent-config/validate.js +76 -0
- package/dist/agent-config/validate.js.map +1 -0
- package/dist/automations/coordinator.d.ts +26 -0
- package/dist/automations/coordinator.js +66 -0
- package/dist/automations/coordinator.js.map +1 -0
- package/dist/automations/github-poller.d.ts +74 -0
- package/dist/automations/github-poller.js +234 -0
- package/dist/automations/github-poller.js.map +1 -0
- package/dist/automations/scheduler.d.ts +42 -0
- package/dist/automations/scheduler.js +192 -0
- package/dist/automations/scheduler.js.map +1 -0
- package/dist/automations/store.d.ts +65 -0
- package/dist/automations/store.js +298 -0
- package/dist/automations/store.js.map +1 -0
- package/dist/automations/task-template.d.ts +18 -0
- package/dist/automations/task-template.js +95 -0
- package/dist/automations/task-template.js.map +1 -0
- package/dist/automations/types.d.ts +255 -0
- package/dist/automations/types.js +159 -0
- package/dist/automations/types.js.map +1 -0
- package/dist/config.d.ts +77 -0
- package/dist/config.js +242 -0
- package/dist/config.js.map +1 -0
- package/dist/contract/agent-config.d.ts +153 -0
- package/dist/contract/agent-profiles.d.ts +347 -0
- package/dist/contract/automations.d.ts +935 -0
- package/dist/contract/events.d.ts +104 -0
- package/dist/contract/github.d.ts +556 -0
- package/dist/contract/health.d.ts +102 -0
- package/dist/contract/index.d.ts +16 -0
- package/dist/contract/index.js +1895 -0
- package/dist/contract/projects.d.ts +210 -0
- package/dist/contract/repo.d.ts +234 -0
- package/dist/contract/runs.d.ts +1473 -0
- package/dist/contract/skills.d.ts +232 -0
- package/dist/contract/workflows.d.ts +218 -0
- package/dist/contract/workspace.d.ts +579 -0
- package/dist/core/agent-env.d.ts +31 -0
- package/dist/core/agent-env.js +371 -0
- package/dist/core/agent-env.js.map +1 -0
- package/dist/core/agent-model-policy.d.ts +10 -0
- package/dist/core/agent-model-policy.js +36 -0
- package/dist/core/agent-model-policy.js.map +1 -0
- package/dist/core/agent-profiles.d.ts +62 -0
- package/dist/core/agent-profiles.js +90 -0
- package/dist/core/agent-profiles.js.map +1 -0
- package/dist/core/agent-runner.d.ts +211 -0
- package/dist/core/agent-runner.js +68 -0
- package/dist/core/agent-runner.js.map +1 -0
- package/dist/core/ask.d.ts +105 -0
- package/dist/core/ask.js +187 -0
- package/dist/core/ask.js.map +1 -0
- package/dist/core/backend-detect.d.ts +16 -0
- package/dist/core/backend-detect.js +155 -0
- package/dist/core/backend-detect.js.map +1 -0
- package/dist/core/claude-cli-runner.d.ts +59 -0
- package/dist/core/claude-cli-runner.js +483 -0
- package/dist/core/claude-cli-runner.js.map +1 -0
- package/dist/core/claude-ui-mapper.d.ts +80 -0
- package/dist/core/claude-ui-mapper.js +598 -0
- package/dist/core/claude-ui-mapper.js.map +1 -0
- package/dist/core/codex-app-server-runner.d.ts +41 -0
- package/dist/core/codex-app-server-runner.js +584 -0
- package/dist/core/codex-app-server-runner.js.map +1 -0
- package/dist/core/codex-app-server-transport.d.ts +35 -0
- package/dist/core/codex-app-server-transport.js +150 -0
- package/dist/core/codex-app-server-transport.js.map +1 -0
- package/dist/core/codex-model-catalog.d.ts +10 -0
- package/dist/core/codex-model-catalog.js +110 -0
- package/dist/core/codex-model-catalog.js.map +1 -0
- package/dist/core/codex-ui-mapper.d.ts +112 -0
- package/dist/core/codex-ui-mapper.js +766 -0
- package/dist/core/codex-ui-mapper.js.map +1 -0
- package/dist/core/model-identity.d.ts +125 -0
- package/dist/core/model-identity.js +132 -0
- package/dist/core/model-identity.js.map +1 -0
- package/dist/core/model-presets.d.ts +21 -0
- package/dist/core/model-presets.js +81 -0
- package/dist/core/model-presets.js.map +1 -0
- package/dist/core/ndjson.d.ts +6 -0
- package/dist/core/ndjson.js +23 -0
- package/dist/core/ndjson.js.map +1 -0
- package/dist/core/opencode-model-catalog.d.ts +32 -0
- package/dist/core/opencode-model-catalog.js +153 -0
- package/dist/core/opencode-model-catalog.js.map +1 -0
- package/dist/core/opencode-server-runner.d.ts +32 -0
- package/dist/core/opencode-server-runner.js +882 -0
- package/dist/core/opencode-server-runner.js.map +1 -0
- package/dist/core/opencode-ui-mapper.d.ts +137 -0
- package/dist/core/opencode-ui-mapper.js +800 -0
- package/dist/core/opencode-ui-mapper.js.map +1 -0
- package/dist/core/pi-model-catalog.d.ts +31 -0
- package/dist/core/pi-model-catalog.js +152 -0
- package/dist/core/pi-model-catalog.js.map +1 -0
- package/dist/core/pi-runner.d.ts +24 -0
- package/dist/core/pi-runner.js +403 -0
- package/dist/core/pi-runner.js.map +1 -0
- package/dist/core/pi-ui-mapper.d.ts +36 -0
- package/dist/core/pi-ui-mapper.js +304 -0
- package/dist/core/pi-ui-mapper.js.map +1 -0
- package/dist/core/process-usage.d.ts +66 -0
- package/dist/core/process-usage.js +193 -0
- package/dist/core/process-usage.js.map +1 -0
- package/dist/core/provider-auth.d.ts +154 -0
- package/dist/core/provider-auth.js +509 -0
- package/dist/core/provider-auth.js.map +1 -0
- package/dist/core/provider-availability.d.ts +3 -0
- package/dist/core/provider-availability.js +14 -0
- package/dist/core/provider-availability.js.map +1 -0
- package/dist/core/runner-factory.d.ts +8 -0
- package/dist/core/runner-factory.js +25 -0
- package/dist/core/runner-factory.js.map +1 -0
- package/dist/core/runner-model-catalog.d.ts +29 -0
- package/dist/core/runner-model-catalog.js +78 -0
- package/dist/core/runner-model-catalog.js.map +1 -0
- package/dist/core/secret-redaction.d.ts +37 -0
- package/dist/core/secret-redaction.js +115 -0
- package/dist/core/secret-redaction.js.map +1 -0
- package/dist/core/shell-env.d.ts +28 -0
- package/dist/core/shell-env.js +56 -0
- package/dist/core/shell-env.js.map +1 -0
- package/dist/core/tool-display.d.ts +31 -0
- package/dist/core/tool-display.js +179 -0
- package/dist/core/tool-display.js.map +1 -0
- package/dist/core/ui-events.d.ts +335 -0
- package/dist/core/ui-events.js +25 -0
- package/dist/core/ui-events.js.map +1 -0
- package/dist/core/usage-limit.d.ts +42 -0
- package/dist/core/usage-limit.js +209 -0
- package/dist/core/usage-limit.js.map +1 -0
- package/dist/core/usage.d.ts +11 -0
- package/dist/core/usage.js +15 -0
- package/dist/core/usage.js.map +1 -0
- package/dist/core/v1-text-coalescer.d.ts +36 -0
- package/dist/core/v1-text-coalescer.js +72 -0
- package/dist/core/v1-text-coalescer.js.map +1 -0
- package/dist/git-diff-base.d.ts +85 -0
- package/dist/git-diff-base.js +180 -0
- package/dist/git-diff-base.js.map +1 -0
- package/dist/git-refs.d.ts +11 -0
- package/dist/git-refs.js +14 -0
- package/dist/git-refs.js.map +1 -0
- package/dist/git-worktree.d.ts +161 -0
- package/dist/git-worktree.js +508 -0
- package/dist/git-worktree.js.map +1 -0
- package/dist/handoff.d.ts +62 -0
- package/dist/handoff.js +154 -0
- package/dist/handoff.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +680 -0
- package/dist/index.js.map +1 -0
- package/dist/install-as-command.d.ts +40 -0
- package/dist/install-as-command.js +52 -0
- package/dist/install-as-command.js.map +1 -0
- package/dist/pack-check.d.ts +17 -0
- package/dist/pack-check.js +27 -0
- package/dist/pack-check.js.map +1 -0
- package/dist/paths.d.ts +140 -0
- package/dist/paths.js +192 -0
- package/dist/paths.js.map +1 -0
- package/dist/planner.d.ts +27 -0
- package/dist/planner.js +268 -0
- package/dist/planner.js.map +1 -0
- package/dist/release/manifests.d.ts +81 -0
- package/dist/release/manifests.js +74 -0
- package/dist/release/manifests.js.map +1 -0
- package/dist/release/snapshot.d.ts +67 -0
- package/dist/release/snapshot.js +97 -0
- package/dist/release/snapshot.js.map +1 -0
- package/dist/release/stable.d.ts +38 -0
- package/dist/release/stable.js +55 -0
- package/dist/release/stable.js.map +1 -0
- package/dist/runs/agent-tmpdir.d.ts +41 -0
- package/dist/runs/agent-tmpdir.js +183 -0
- package/dist/runs/agent-tmpdir.js.map +1 -0
- package/dist/runs/auto-name.d.ts +75 -0
- package/dist/runs/auto-name.js +179 -0
- package/dist/runs/auto-name.js.map +1 -0
- package/dist/runs/event-history.d.ts +50 -0
- package/dist/runs/event-history.js +613 -0
- package/dist/runs/event-history.js.map +1 -0
- package/dist/runs/retention.d.ts +60 -0
- package/dist/runs/retention.js +86 -0
- package/dist/runs/retention.js.map +1 -0
- package/dist/runs/review-gate.d.ts +18 -0
- package/dist/runs/review-gate.js +21 -0
- package/dist/runs/review-gate.js.map +1 -0
- package/dist/runs/run-index.d.ts +19 -0
- package/dist/runs/run-index.js +43 -0
- package/dist/runs/run-index.js.map +1 -0
- package/dist/runs/store.d.ts +446 -0
- package/dist/runs/store.js +1118 -0
- package/dist/runs/store.js.map +1 -0
- package/dist/runs/task-markers.d.ts +28 -0
- package/dist/runs/task-markers.js +74 -0
- package/dist/runs/task-markers.js.map +1 -0
- package/dist/runs/task-refs.d.ts +25 -0
- package/dist/runs/task-refs.js +74 -0
- package/dist/runs/task-refs.js.map +1 -0
- package/dist/runs/ui-event-sink.d.ts +81 -0
- package/dist/runs/ui-event-sink.js +210 -0
- package/dist/runs/ui-event-sink.js.map +1 -0
- package/dist/server/app-type.d.ts +21 -0
- package/dist/server/app-type.js +2 -0
- package/dist/server/app-type.js.map +1 -0
- package/dist/server/capabilities.d.ts +70 -0
- package/dist/server/capabilities.js +152 -0
- package/dist/server/capabilities.js.map +1 -0
- package/dist/server/checkout.d.ts +128 -0
- package/dist/server/checkout.js +296 -0
- package/dist/server/checkout.js.map +1 -0
- package/dist/server/forge/github.d.ts +513 -0
- package/dist/server/forge/github.js +2364 -0
- package/dist/server/forge/github.js.map +1 -0
- package/dist/server/forge/index.d.ts +40 -0
- package/dist/server/forge/index.js +72 -0
- package/dist/server/forge/index.js.map +1 -0
- package/dist/server/forge/types.d.ts +242 -0
- package/dist/server/forge/types.js +2 -0
- package/dist/server/forge/types.js.map +1 -0
- package/dist/server/fs-browse.d.ts +105 -0
- package/dist/server/fs-browse.js +182 -0
- package/dist/server/fs-browse.js.map +1 -0
- package/dist/server/git-changes.d.ts +213 -0
- package/dist/server/git-changes.js +555 -0
- package/dist/server/git-changes.js.map +1 -0
- package/dist/server/git.d.ts +28 -0
- package/dist/server/git.js +112 -0
- package/dist/server/git.js.map +1 -0
- package/dist/server/github.d.ts +9 -0
- package/dist/server/github.js +8 -0
- package/dist/server/github.js.map +1 -0
- package/dist/server/launch-key.d.ts +7 -0
- package/dist/server/launch-key.js +33 -0
- package/dist/server/launch-key.js.map +1 -0
- package/dist/server/open-in-app.d.ts +66 -0
- package/dist/server/open-in-app.js +211 -0
- package/dist/server/open-in-app.js.map +1 -0
- package/dist/server/open-in-terminal.d.ts +70 -0
- package/dist/server/open-in-terminal.js +179 -0
- package/dist/server/open-in-terminal.js.map +1 -0
- package/dist/server/pr.d.ts +7 -0
- package/dist/server/pr.js +7 -0
- package/dist/server/pr.js.map +1 -0
- package/dist/server/project-context.d.ts +120 -0
- package/dist/server/project-context.js +182 -0
- package/dist/server/project-context.js.map +1 -0
- package/dist/server/provider-action-gate.d.ts +8 -0
- package/dist/server/provider-action-gate.js +56 -0
- package/dist/server/provider-action-gate.js.map +1 -0
- package/dist/server/provider-auth-runtime.d.ts +21 -0
- package/dist/server/provider-auth-runtime.js +66 -0
- package/dist/server/provider-auth-runtime.js.map +1 -0
- package/dist/server/server.d.ts +13138 -0
- package/dist/server/server.js +5263 -0
- package/dist/server/server.js.map +1 -0
- package/dist/server/static-ui.d.ts +49 -0
- package/dist/server/static-ui.js +92 -0
- package/dist/server/static-ui.js.map +1 -0
- package/dist/server/validators.d.ts +97 -0
- package/dist/server/validators.js +86 -0
- package/dist/server/validators.js.map +1 -0
- package/dist/server/ws.d.ts +85 -0
- package/dist/server/ws.js +218 -0
- package/dist/server/ws.js.map +1 -0
- package/dist/server/wsl.d.ts +25 -0
- package/dist/server/wsl.js +92 -0
- package/dist/server/wsl.js.map +1 -0
- package/dist/server-install/engine.d.ts +50 -0
- package/dist/server-install/engine.js +324 -0
- package/dist/server-install/engine.js.map +1 -0
- package/dist/server-install/platforms/macosx-ngrok.d.ts +6 -0
- package/dist/server-install/platforms/macosx-ngrok.js +345 -0
- package/dist/server-install/platforms/macosx-ngrok.js.map +1 -0
- package/dist/server-install/platforms/ubuntu-vps.d.ts +78 -0
- package/dist/server-install/platforms/ubuntu-vps.js +1016 -0
- package/dist/server-install/platforms/ubuntu-vps.js.map +1 -0
- package/dist/server-install/state.d.ts +52 -0
- package/dist/server-install/state.js +182 -0
- package/dist/server-install/state.js.map +1 -0
- package/dist/server-install/steps.d.ts +109 -0
- package/dist/server-install/steps.js +334 -0
- package/dist/server-install/steps.js.map +1 -0
- package/dist/server-install/strategies.d.ts +4 -0
- package/dist/server-install/strategies.js +20 -0
- package/dist/server-install/strategies.js.map +1 -0
- package/dist/server-install/types.d.ts +287 -0
- package/dist/server-install/types.js +121 -0
- package/dist/server-install/types.js.map +1 -0
- package/dist/server-install/ui.d.ts +42 -0
- package/dist/server-install/ui.js +130 -0
- package/dist/server-install/ui.js.map +1 -0
- package/dist/skills-banner.d.ts +22 -0
- package/dist/skills-banner.js +41 -0
- package/dist/skills-banner.js.map +1 -0
- package/dist/skills-remote.d.ts +84 -0
- package/dist/skills-remote.js +468 -0
- package/dist/skills-remote.js.map +1 -0
- package/dist/skills-update.d.ts +88 -0
- package/dist/skills-update.js +392 -0
- package/dist/skills-update.js.map +1 -0
- package/dist/skills.d.ts +82 -0
- package/dist/skills.js +251 -0
- package/dist/skills.js.map +1 -0
- package/dist/todos.d.ts +48 -0
- package/dist/todos.js +201 -0
- package/dist/todos.js.map +1 -0
- package/dist/ui-state.d.ts +26 -0
- package/dist/ui-state.js +38 -0
- package/dist/ui-state.js.map +1 -0
- package/dist/update-check.d.ts +12 -0
- package/dist/update-check.js +41 -0
- package/dist/update-check.js.map +1 -0
- package/dist/workflows/load.d.ts +15 -0
- package/dist/workflows/load.js +56 -0
- package/dist/workflows/load.js.map +1 -0
- package/dist/workflows/run.d.ts +758 -0
- package/dist/workflows/run.js +3389 -0
- package/dist/workflows/run.js.map +1 -0
- package/dist/workflows/types.d.ts +153 -0
- package/dist/workflows/types.js +212 -0
- package/dist/workflows/types.js.map +1 -0
- package/dist/workspace/agent-accounts.d.ts +153 -0
- package/dist/workspace/agent-accounts.js +304 -0
- package/dist/workspace/agent-accounts.js.map +1 -0
- package/dist/workspace/agent-profiles.d.ts +78 -0
- package/dist/workspace/agent-profiles.js +115 -0
- package/dist/workspace/agent-profiles.js.map +1 -0
- package/dist/workspace/config.d.ts +169 -0
- package/dist/workspace/config.js +379 -0
- package/dist/workspace/config.js.map +1 -0
- package/dist/workspace/migrations.d.ts +45 -0
- package/dist/workspace/migrations.js +147 -0
- package/dist/workspace/migrations.js.map +1 -0
- package/dist/workspace/projects-cli.d.ts +25 -0
- package/dist/workspace/projects-cli.js +172 -0
- package/dist/workspace/projects-cli.js.map +1 -0
- package/dist/workspace/projects.d.ts +109 -0
- package/dist/workspace/projects.js +250 -0
- package/dist/workspace/projects.js.map +1 -0
- package/dist/workspace/semaphore.d.ts +179 -0
- package/dist/workspace/semaphore.js +195 -0
- package/dist/workspace/semaphore.js.map +1 -0
- package/dist/workspace/ui-state.d.ts +34 -0
- package/dist/workspace/ui-state.js +53 -0
- package/dist/workspace/ui-state.js.map +1 -0
- package/package.json +70 -0
- package/scripts/check-pack.mjs +46 -0
- package/scripts/inline-contract.mjs +112 -0
- package/scripts/install-as-command.mjs +120 -0
- package/scripts/mock-claude.mjs +520 -0
- package/scripts/mock-pi-rpc.mjs +83 -0
- package/scripts/sync-readme.mjs +20 -0
- package/scripts/test-process-usage.mjs +47 -0
- package/web/dist/assets/alert-dialog-B4Ofsgv7.js +1 -0
- package/web/dist/assets/arrow-down-Dy8dup7j.js +1 -0
- package/web/dist/assets/arrow-left-BJaucbhn.js +1 -0
- package/web/dist/assets/bundle-mjs-BT31bpU6.js +1 -0
- package/web/dist/assets/centered-state-duPW0phQ.js +43 -0
- package/web/dist/assets/chevron-right-Be4A5TCS.js +1 -0
- package/web/dist/assets/chunk-BO2N2NFS-DE6qKn3r.js +131 -0
- package/web/dist/assets/collapsible-DdcNBdSk.js +1 -0
- package/web/dist/assets/commit-list-CgvN9vec.js +1 -0
- package/web/dist/assets/compare-variants-CQA2nd65.js +1 -0
- package/web/dist/assets/core-BCsw8oQw.js +12 -0
- package/web/dist/assets/css-BsVw1vtW.js +1 -0
- package/web/dist/assets/diff-B6Agp5Hl.js +3 -0
- package/web/dist/assets/diff-stat-BoXuGkgq.js +1 -0
- package/web/dist/assets/diff-view-CD8XI-fj.js +6 -0
- package/web/dist/assets/diff-woXpYk--.js +1 -0
- package/web/dist/assets/dropdown-menu-B3SYw-k5.js +1 -0
- package/web/dist/assets/editable-title-B-hjp5wl.js +1 -0
- package/web/dist/assets/ellipsis-vertical-BYwzw0xl.js +1 -0
- package/web/dist/assets/engine-javascript-FQvzRocB.js +141 -0
- package/web/dist/assets/file-BRj5eISx.js +1 -0
- package/web/dist/assets/folder-z4oT5981.js +1 -0
- package/web/dist/assets/git-toolbar-owSEkYld.js +1 -0
- package/web/dist/assets/github-Bz2VgRX3.js +1 -0
- package/web/dist/assets/go-rLFTqkRN.js +1 -0
- package/web/dist/assets/highlighted-body-OFNGDK62-BL-MfFgl.js +1 -0
- package/web/dist/assets/highlighter-CdHqIwFr.js +3 -0
- package/web/dist/assets/html-BY76lXLH.js +1 -0
- package/web/dist/assets/image-preview-h3WFluuy.js +1 -0
- package/web/dist/assets/index-BbcQNT92.css +2 -0
- package/web/dist/assets/index-EtQQQ6Kj.js +7 -0
- package/web/dist/assets/inter-latin-ext-wght-normal-DO1Apj_S.woff2 +0 -0
- package/web/dist/assets/inter-latin-wght-normal-Dx4kXJAl.woff2 +0 -0
- package/web/dist/assets/javascript-BgS3c2Ky.js +1 -0
- package/web/dist/assets/jetbrains-mono-latin-ext-wght-normal-DBQx-q_a.woff2 +0 -0
- package/web/dist/assets/jetbrains-mono-latin-wght-normal-B9CIFXIH.woff2 +0 -0
- package/web/dist/assets/json-qhed-kSA.js +1 -0
- package/web/dist/assets/jsonc-CYpm1nAK.js +1 -0
- package/web/dist/assets/jsx-Bz0zcwM4.js +1 -0
- package/web/dist/assets/lib-BQXq3kEf.js +1 -0
- package/web/dist/assets/lib-BxQXEXDF.js +1 -0
- package/web/dist/assets/markdown-BYOwaDjH.js +1 -0
- package/web/dist/assets/markdown-DqBKYPiB.js +2 -0
- package/web/dist/assets/mermaid-GHXKKRXX-C4jxqUUb.js +1 -0
- package/web/dist/assets/new-task-form-BdJKRBJX.js +1 -0
- package/web/dist/assets/pill-BQfmfpYp.js +1 -0
- package/web/dist/assets/project-router-DxgFZY1l.js +1 -0
- package/web/dist/assets/prompt-templates-B6m16gq-.js +15 -0
- package/web/dist/assets/python-gzcpVVnB.js +1 -0
- package/web/dist/assets/react-runtime-CCIEwYL0.js +9 -0
- package/web/dist/assets/refresh-cw-mhSpxf2a.js +1 -0
- package/web/dist/assets/repo-git-CUNRxR3_.js +1 -0
- package/web/dist/assets/rolldown-runtime-QTnfLwEv.js +1 -0
- package/web/dist/assets/run-diff-DsmmDVfx.js +3 -0
- package/web/dist/assets/run-header-BkhrseLJ.js +1 -0
- package/web/dist/assets/rust-Cfkwpbl8.js +1 -0
- package/web/dist/assets/search-x-BqDMB2g8.js +1 -0
- package/web/dist/assets/shellscript-CLZ0U2zV.js +1 -0
- package/web/dist/assets/skill-empty-hint-BWEvTggc.js +1 -0
- package/web/dist/assets/skills-9oR_oHse.js +1 -0
- package/web/dist/assets/skills-DwIxnnWO.js +1 -0
- package/web/dist/assets/sparkles-DIoTQpyx.js +1 -0
- package/web/dist/assets/sql-BsFa4tDR.js +1 -0
- package/web/dist/assets/square-terminal-Cc7CuQxc.js +1 -0
- package/web/dist/assets/tab-link-D1fQgpmO.js +1 -0
- package/web/dist/assets/task-changes-BKeLlDpK.js +1 -0
- package/web/dist/assets/task-commits-gcEFZIa5.js +1 -0
- package/web/dist/assets/task-files-BGAqoXTW.js +2 -0
- package/web/dist/assets/task-thread-DT8aUYTS.js +9 -0
- package/web/dist/assets/textarea-BOVbfy5C.js +1 -0
- package/web/dist/assets/thread-loading-CypW73KD.js +1 -0
- package/web/dist/assets/toml-CcmNWLt0.js +1 -0
- package/web/dist/assets/trash-2-CJq6LHWn.js +1 -0
- package/web/dist/assets/triangle-alert-CjDFvU27.js +1 -0
- package/web/dist/assets/tsx-udAQXfEw.js +1 -0
- package/web/dist/assets/typescript-bsJCZSQ-.js +1 -0
- package/web/dist/assets/upload-CPDZlJeK.js +1 -0
- package/web/dist/assets/use-desktop-5JsLmi0a.js +1 -0
- package/web/dist/assets/use-submit-shortcut-CHVFevty.js +1 -0
- package/web/dist/assets/utils-DiO6zyJd.js +64 -0
- package/web/dist/assets/workflows-rQDFzWRt.js +11 -0
- package/web/dist/assets/yaml-rwi0_p6S.js +1 -0
- package/web/dist/assets/zoomable-image-COWqb11v.js +1 -0
- package/web/dist/index.html +80 -0
- package/web/dist/open-mercato.svg +11 -0
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
import { chmodSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs';
|
|
3
|
+
import { tmpdir } from 'node:os';
|
|
4
|
+
import { join } from 'node:path';
|
|
5
|
+
import { shellQuote, withEnvPrefix } from '../core/shell-env.js';
|
|
6
|
+
import { isWsl, wslDistroName } from './wsl.js';
|
|
7
|
+
/**
|
|
8
|
+
* Open a real terminal window at `cwd` running `command` — the "take over the
|
|
9
|
+
* agent session locally" handoff. Cross-platform strategy ported from
|
|
10
|
+
* github-janitor's `openInTerminal.ts`: macOS via osascript, Windows via
|
|
11
|
+
* cmd/start, Linux by probing common emulators with a temp launch script
|
|
12
|
+
* (which sidesteps per-emulator quoting rules). WSL (#361) reuses the Linux
|
|
13
|
+
* script but hands it to a Windows-side terminal through interop, re-entering
|
|
14
|
+
* the distro with `wsl.exe` — there is no Linux desktop of its own to open
|
|
15
|
+
* `x-terminal-emulator` etc. on.
|
|
16
|
+
*
|
|
17
|
+
* Returns true when a launcher was started without an immediate error; the
|
|
18
|
+
* caller shows a copy-the-command fallback otherwise.
|
|
19
|
+
*/
|
|
20
|
+
export async function openInTerminal(cwd, command,
|
|
21
|
+
/** Environment the opened shell must carry — today, the agent account's config dir (spec
|
|
22
|
+
* 2026-07-29-agent-profiles). Rendered per platform and made to PERSIST, because the window
|
|
23
|
+
* stays open and the user types the next `claude` in it themselves. An empty/absent env
|
|
24
|
+
* changes nothing about the command. Returns false without launching anything when the
|
|
25
|
+
* values cannot be embedded safely: a terminal silently aimed at the wrong account is worse
|
|
26
|
+
* than no terminal, since nothing in the window would say so. */
|
|
27
|
+
env = {}) {
|
|
28
|
+
const prefixed = withEnvPrefix(command, env, process.platform);
|
|
29
|
+
if (prefixed === null)
|
|
30
|
+
return false;
|
|
31
|
+
if (process.platform === 'darwin') {
|
|
32
|
+
const script = `cd ${shellQuote(cwd)} && ${prefixed}`;
|
|
33
|
+
return runDetached('osascript', [
|
|
34
|
+
'-e',
|
|
35
|
+
'tell application "Terminal" to activate',
|
|
36
|
+
'-e',
|
|
37
|
+
`tell application "Terminal" to do script ${appleScriptQuote(script)}`,
|
|
38
|
+
]);
|
|
39
|
+
}
|
|
40
|
+
if (process.platform === 'win32') {
|
|
41
|
+
const inner = `cd /d "${cwd}" && ${prefixed}`;
|
|
42
|
+
// Windows Terminal first, classic cmd window as fallback.
|
|
43
|
+
if (await runDetached('cmd', ['/c', 'start', '', 'wt', '-d', cwd, 'cmd', '/K', prefixed])) {
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
return runDetached('cmd', ['/c', 'start', '', 'cmd', '/K', inner]);
|
|
47
|
+
}
|
|
48
|
+
// Linux/other: a temp script avoids each emulator's own quoting rules. It reaps
|
|
49
|
+
// itself afterwards (#785) — see `createLaunchScript`.
|
|
50
|
+
const scriptPath = createLaunchScript(cwd, prefixed);
|
|
51
|
+
if (isWsl()) {
|
|
52
|
+
// No Linux GUI here — go through interop to a Windows terminal, which re-enters this same
|
|
53
|
+
// distro (`wsl.exe -d <distro>`) to run the script we just wrote. `scriptPath`/`cwd` stay
|
|
54
|
+
// POSIX: `wsl.exe` interprets its command line inside the distro, not on the Windows side.
|
|
55
|
+
for (const [bin, args] of wslTerminalLaunchers(scriptPath, wslDistroName())) {
|
|
56
|
+
if (await runDetached(bin, args))
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
const candidates = [
|
|
62
|
+
['x-terminal-emulator', ['-e', scriptPath]],
|
|
63
|
+
['gnome-terminal', ['--', scriptPath]],
|
|
64
|
+
['konsole', ['-e', scriptPath]],
|
|
65
|
+
['wezterm', ['start', '--', scriptPath]],
|
|
66
|
+
['kitty', [scriptPath]],
|
|
67
|
+
['alacritty', ['-e', scriptPath]],
|
|
68
|
+
['xterm', ['-e', scriptPath]],
|
|
69
|
+
];
|
|
70
|
+
for (const [bin, args] of candidates) {
|
|
71
|
+
if (await runDetached(bin, args))
|
|
72
|
+
return true;
|
|
73
|
+
}
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
/** The Windows-side (bin, args) candidates for launching `scriptPath` inside `distro` through
|
|
77
|
+
* WSL interop, in try-order — Windows Terminal first, a classic console window as fallback. Pure
|
|
78
|
+
* (no spawning) so the exact command line is unit-testable without a real WSL host.
|
|
79
|
+
*
|
|
80
|
+
* Every launcher here is shell-free by construction, and must stay that way: routing through
|
|
81
|
+
* `cmd.exe` (`/c start …`) would reintroduce BatBadBut (CVE-2024-27980, see #459). Passing an
|
|
82
|
+
* argument array is NOT protection when the binary is a shell — libuv only quotes arguments
|
|
83
|
+
* containing space, tab or quote, so a space-free `distro` like `a&calc&` would reach `cmd`
|
|
84
|
+
* live and be interpreted. `wt.exe` and `conhost.exe` parse no metacharacters, so the same
|
|
85
|
+
* input is inert. `distro` is additionally validated at the source (`wslDistroName`). */
|
|
86
|
+
export function wslTerminalLaunchers(scriptPath, distro) {
|
|
87
|
+
return [
|
|
88
|
+
['wt.exe', ['wsl.exe', '-d', distro, '--', scriptPath]],
|
|
89
|
+
['conhost.exe', ['wsl.exe', '-d', distro, '--', scriptPath]],
|
|
90
|
+
];
|
|
91
|
+
}
|
|
92
|
+
/** Grace period before a launch script's directory is removed. Generous next to the
|
|
93
|
+
* ~250 ms each emulator candidate is given, because the cost of being early is a
|
|
94
|
+
* window that never opens, and the cost of being late is a few hundred bytes. */
|
|
95
|
+
export const LAUNCH_SCRIPT_TTL_MS = 60_000;
|
|
96
|
+
/**
|
|
97
|
+
* Writes the temp launch script shared by the plain-Linux and WSL branches — `cd` into
|
|
98
|
+
* the worktree, run `command`, then drop into an interactive shell so the window stays
|
|
99
|
+
* open — and schedules its own removal (#785).
|
|
100
|
+
*
|
|
101
|
+
* Every "open in terminal" used to leave its `cez-term-*` directory behind forever. On a
|
|
102
|
+
* host whose `/tmp` is a tmpfs that never reboots, cezar's own litter is part of what
|
|
103
|
+
* exhausts the directory the agents' output capture depends on, so the opener cleans up
|
|
104
|
+
* after itself. Deleting the script mid-run is safe: the emulator has already `exec`'d
|
|
105
|
+
* bash on it, and POSIX keeps an unlinked file's inode alive for every open descriptor.
|
|
106
|
+
* The timer is `unref`'d — a pending cleanup must never be the reason `cezar serve`
|
|
107
|
+
* refuses to exit.
|
|
108
|
+
*
|
|
109
|
+
* Exported for the regression test, which must prove the directory does not survive
|
|
110
|
+
* without spawning a real terminal emulator.
|
|
111
|
+
*/
|
|
112
|
+
export function createLaunchScript(cwd, command, ttlMs = LAUNCH_SCRIPT_TTL_MS) {
|
|
113
|
+
const dir = mkdtempSync(join(tmpdir(), 'cez-term-'));
|
|
114
|
+
const scriptPath = join(dir, 'launch.sh');
|
|
115
|
+
writeFileSync(scriptPath, `#!/usr/bin/env bash\ncd ${shellQuote(cwd)}\n${command}\nexec bash\n`, 'utf8');
|
|
116
|
+
chmodSync(scriptPath, 0o755);
|
|
117
|
+
const timer = setTimeout(() => {
|
|
118
|
+
try {
|
|
119
|
+
rmSync(dir, { recursive: true, force: true });
|
|
120
|
+
}
|
|
121
|
+
catch {
|
|
122
|
+
// best-effort: a launch script we cannot remove is litter, not a failure.
|
|
123
|
+
}
|
|
124
|
+
}, ttlMs);
|
|
125
|
+
timer.unref?.();
|
|
126
|
+
return scriptPath;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* A test that reaches a real launcher opens a window on the developer's machine — a Terminal on
|
|
130
|
+
* macOS, a `cmd` window on Windows, an emulator on Linux — and #820 is what that looks like: a
|
|
131
|
+
* suite run left a Terminal sitting in a `cez-profiles-home-*` fixture directory the same run had
|
|
132
|
+
* already deleted. Throwing beats returning `false`: a silent refusal would let the omission
|
|
133
|
+
* survive as a passing test, and the fix is always the same one line — inject the launcher seam
|
|
134
|
+
* (`openTerminal` / `openFile` / `openApp` on `ServerDeps`) instead of reaching the real one.
|
|
135
|
+
*
|
|
136
|
+
* `CEZ_ALLOW_TEST_SPAWN=1` is the deliberate exception, for a file that has replaced
|
|
137
|
+
* `node:child_process` with a mock: nothing reaches a real process there, and asserting the argv a
|
|
138
|
+
* launcher WOULD pass is exactly how the Windows launcher-safety cases (#469, BatBadBut) are
|
|
139
|
+
* pinned. Set it around those tests, never process-wide.
|
|
140
|
+
*
|
|
141
|
+
* Exported so `open-in-app.ts` shares this one definition rather than keeping a second copy that
|
|
142
|
+
* could drift.
|
|
143
|
+
*/
|
|
144
|
+
export function refuseSpawnUnderTest(bin, args) {
|
|
145
|
+
if (!process.env.VITEST || process.env.CEZ_ALLOW_TEST_SPAWN === '1')
|
|
146
|
+
return;
|
|
147
|
+
throw new Error(`refusing to spawn a launcher from a test: ${[bin, ...args].join(' ')}\n` +
|
|
148
|
+
'Inject the launcher (ServerDeps.openTerminal / openFile / openApp) instead of calling the real one.');
|
|
149
|
+
}
|
|
150
|
+
/** Spawn detached; success = no error within a short settle window. */
|
|
151
|
+
function runDetached(bin, args) {
|
|
152
|
+
return new Promise((resolve) => {
|
|
153
|
+
refuseSpawnUnderTest(bin, args);
|
|
154
|
+
let child;
|
|
155
|
+
try {
|
|
156
|
+
child = spawn(bin, args, { stdio: 'ignore', detached: true });
|
|
157
|
+
}
|
|
158
|
+
catch {
|
|
159
|
+
resolve(false);
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
let settled = false;
|
|
163
|
+
const settle = (ok) => {
|
|
164
|
+
if (settled)
|
|
165
|
+
return;
|
|
166
|
+
settled = true;
|
|
167
|
+
resolve(ok);
|
|
168
|
+
};
|
|
169
|
+
child.once('error', () => settle(false));
|
|
170
|
+
setTimeout(() => {
|
|
171
|
+
child.unref();
|
|
172
|
+
settle(true);
|
|
173
|
+
}, 250);
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
function appleScriptQuote(s) {
|
|
177
|
+
return `"${s.replaceAll('\\', '\\\\').replaceAll('"', '\\"')}"`;
|
|
178
|
+
}
|
|
179
|
+
//# sourceMappingURL=open-in-terminal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"open-in-terminal.js","sourceRoot":"","sources":["../../src/server/open-in-terminal.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxE,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACjE,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEhD;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,GAAW,EACX,OAAe;AACf;;;;;kEAKkE;AAClE,GAAG,GAA2B,EAAE;IAEhC,MAAM,QAAQ,GAAG,aAAa,CAAC,OAAO,EAAE,GAAG,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC/D,IAAI,QAAQ,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IAEpC,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAClC,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,GAAG,CAAC,OAAO,QAAQ,EAAE,CAAC;QACtD,OAAO,WAAW,CAAC,WAAW,EAAE;YAC9B,IAAI;YACJ,yCAAyC;YACzC,IAAI;YACJ,4CAA4C,gBAAgB,CAAC,MAAM,CAAC,EAAE;SACvE,CAAC,CAAC;IACL,CAAC;IAED,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QACjC,MAAM,KAAK,GAAG,UAAU,GAAG,QAAQ,QAAQ,EAAE,CAAC;QAC9C,0DAA0D;QAC1D,IAAI,MAAM,WAAW,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC,EAAE,CAAC;YAC1F,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,WAAW,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC;IACrE,CAAC;IAED,gFAAgF;IAChF,uDAAuD;IACvD,MAAM,UAAU,GAAG,kBAAkB,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IAErD,IAAI,KAAK,EAAE,EAAE,CAAC;QACZ,0FAA0F;QAC1F,0FAA0F;QAC1F,2FAA2F;QAC3F,KAAK,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,oBAAoB,CAAC,UAAU,EAAE,aAAa,EAAE,CAAC,EAAE,CAAC;YAC5E,IAAI,MAAM,WAAW,CAAC,GAAG,EAAE,IAAI,CAAC;gBAAE,OAAO,IAAI,CAAC;QAChD,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,UAAU,GAA8B;QAC5C,CAAC,qBAAqB,EAAE,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;QAC3C,CAAC,gBAAgB,EAAE,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;QACtC,CAAC,SAAS,EAAE,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;QAC/B,CAAC,SAAS,EAAE,CAAC,OAAO,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC;QACxC,CAAC,OAAO,EAAE,CAAC,UAAU,CAAC,CAAC;QACvB,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;QACjC,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;KAC9B,CAAC;IACF,KAAK,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,UAAU,EAAE,CAAC;QACrC,IAAI,MAAM,WAAW,CAAC,GAAG,EAAE,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;IAChD,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;;;;0FAS0F;AAC1F,MAAM,UAAU,oBAAoB,CAAC,UAAkB,EAAE,MAAc;IACrE,OAAO;QACL,CAAC,QAAQ,EAAE,CAAC,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC;QACvD,CAAC,aAAa,EAAE,CAAC,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC;KAC7D,CAAC;AACJ,CAAC;AAED;;kFAEkF;AAClF,MAAM,CAAC,MAAM,oBAAoB,GAAG,MAAM,CAAC;AAE3C;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,kBAAkB,CAChC,GAAW,EACX,OAAe,EACf,KAAK,GAAW,oBAAoB;IAEpC,MAAM,GAAG,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,WAAW,CAAC,CAAC,CAAC;IACrD,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;IAC1C,aAAa,CAAC,UAAU,EAAE,2BAA2B,UAAU,CAAC,GAAG,CAAC,KAAK,OAAO,eAAe,EAAE,MAAM,CAAC,CAAC;IACzG,SAAS,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;IAC7B,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;QAC5B,IAAI,CAAC;YACH,MAAM,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAChD,CAAC;QAAC,MAAM,CAAC;YACP,0EAA0E;QAC5E,CAAC;IACH,CAAC,EAAE,KAAK,CAAC,CAAC;IACV,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC;IAChB,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,oBAAoB,CAAC,GAAW,EAAE,IAAuB;IACvE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,oBAAoB,KAAK,GAAG;QAAE,OAAO;IAC5E,MAAM,IAAI,KAAK,CACb,6CAA6C,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI;QACvE,qGAAqG,CACxG,CAAC;AACJ,CAAC;AAED,uEAAuE;AACvE,SAAS,WAAW,CAAC,GAAW,EAAE,IAAc;IAC9C,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,oBAAoB,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAChC,IAAI,KAAK,CAAC;QACV,IAAI,CAAC;YACH,KAAK,GAAG,KAAK,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;QAChE,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,CAAC,KAAK,CAAC,CAAC;YACf,OAAO;QACT,CAAC;QACD,IAAI,OAAO,GAAG,KAAK,CAAC;QACpB,MAAM,MAAM,GAAG,CAAC,EAAW,EAAE,EAAE;YAC7B,IAAI,OAAO;gBAAE,OAAO;YACpB,OAAO,GAAG,IAAI,CAAC;YACf,OAAO,CAAC,EAAE,CAAC,CAAC;QACd,CAAC,CAAC;QACF,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QACzC,UAAU,CAAC,GAAG,EAAE;YACd,KAAK,CAAC,KAAK,EAAE,CAAC;YACd,MAAM,CAAC,IAAI,CAAC,CAAC;QACf,CAAC,EAAE,GAAG,CAAC,CAAC;IACV,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,gBAAgB,CAAC,CAAS;IACjC,OAAO,IAAI,CAAC,CAAC,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,UAAU,CAAC,GAAG,EAAE,KAAK,CAAC,GAAG,CAAC;AAClE,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Thin delegate — draft-PR creation (review gate, spec 009) moved behind the
|
|
3
|
+
* forge-driver seam (`src/server/forge/github.ts`, cockpit-ui redesign spec
|
|
4
|
+
* §"Forge-driver seam"). Kept so existing imports keep working.
|
|
5
|
+
*/
|
|
6
|
+
export { buildPrBody, createDraftPr } from './forge/github.ts';
|
|
7
|
+
export type { DraftPrInput, DraftPrOutcome } from './forge/types.ts';
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Thin delegate — draft-PR creation (review gate, spec 009) moved behind the
|
|
3
|
+
* forge-driver seam (`src/server/forge/github.ts`, cockpit-ui redesign spec
|
|
4
|
+
* §"Forge-driver seam"). Kept so existing imports keep working.
|
|
5
|
+
*/
|
|
6
|
+
export { buildPrBody, createDraftPr } from './forge/github.js';
|
|
7
|
+
//# sourceMappingURL=pr.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pr.js","sourceRoot":"","sources":["../../src/server/pr.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { AutomationStore } from '../automations/store.ts';
|
|
2
|
+
import { RunStore } from '../runs/store.ts';
|
|
3
|
+
import { WorkspaceSemaphore } from '../workspace/semaphore.ts';
|
|
4
|
+
import { RunManager } from '../workflows/run.ts';
|
|
5
|
+
/**
|
|
6
|
+
* Per-project server context (spec 2026-07-20-multi-project-workspace,
|
|
7
|
+
* "Project contexts" + "Boot flow"): one `{store, manager, dataDir,
|
|
8
|
+
* launchKey}` bundle per registered project, built lazily on first access.
|
|
9
|
+
*
|
|
10
|
+
* Building a context mirrors what `serveCommand` does for the boot project
|
|
11
|
+
* today — `RunStore.open(dataDir, { keepLive: true })`, `new RunManager`,
|
|
12
|
+
* orphan-worktree prune + count-based retention when the root is a git repo,
|
|
13
|
+
* then `manager.recover()` — so a project opened from the sidebar gets the
|
|
14
|
+
* exact same crash recovery the boot project gets. A registry entry whose
|
|
15
|
+
* root is gone (`status: 'missing'`) is never instantiated; `context()`
|
|
16
|
+
* throws a typed `ProjectContextError` the route layer maps to 409 (and
|
|
17
|
+
* `unknown-project` to 404).
|
|
18
|
+
*/
|
|
19
|
+
/** The per-project bundle the routes operate on. */
|
|
20
|
+
export interface ProjectContext {
|
|
21
|
+
/** Registry project id (slug). */
|
|
22
|
+
id: string;
|
|
23
|
+
/** Realpath'd repo root the registry holds for this project. */
|
|
24
|
+
root: string;
|
|
25
|
+
/** `<root>/.ai/cezar` — all of this project's on-disk state. */
|
|
26
|
+
dataDir: string;
|
|
27
|
+
store: RunStore;
|
|
28
|
+
manager: RunManager;
|
|
29
|
+
automationStore: AutomationStore;
|
|
30
|
+
/** Bookmarklet auto-start secret (spec 011), ensured at context build. */
|
|
31
|
+
launchKey: string;
|
|
32
|
+
}
|
|
33
|
+
/** Minimal registry shape the context map needs — matches
|
|
34
|
+
* `workspace/projects.ts` `ProjectListEntry` structurally, but injected so
|
|
35
|
+
* tests stay hermetic (no `~/.cezar` reads). */
|
|
36
|
+
export interface ProjectContextSource {
|
|
37
|
+
id: string;
|
|
38
|
+
root: string;
|
|
39
|
+
/** `missing` roots are never instantiated; `ok`/`not-git` both build. */
|
|
40
|
+
status: 'ok' | 'missing' | 'not-git';
|
|
41
|
+
}
|
|
42
|
+
export interface ProjectContextDeps {
|
|
43
|
+
/** Registry lookup — the workspace `listProjects()` in production. */
|
|
44
|
+
listProjects: () => Promise<readonly ProjectContextSource[]>;
|
|
45
|
+
/** Resolve the one automation store owned by this project. Production
|
|
46
|
+
* injects the workspace automation coordinator's cached store so API
|
|
47
|
+
* mutations and scheduler reads share the same in-memory state. */
|
|
48
|
+
automationStore?: (projectId: string, root: string) => AutomationStore;
|
|
49
|
+
/** Workspace-wide parallel-cap semaphore (spec 2026-07-20, step 2.5). Boot
|
|
50
|
+
* passes the ONE instance it already gave the boot manager, so every
|
|
51
|
+
* project's RunManager counts against the same `resources.maxParallel`.
|
|
52
|
+
* When omitted, the map still shares one private instance across the
|
|
53
|
+
* managers it builds (workspace defaults, never refreshed). */
|
|
54
|
+
semaphore?: WorkspaceSemaphore;
|
|
55
|
+
}
|
|
56
|
+
export type ProjectContextFailure = 'unknown-project' | 'missing-root';
|
|
57
|
+
/** Typed failure so the route layer can map reasons to statuses (404/409)
|
|
58
|
+
* without string matching. */
|
|
59
|
+
export declare class ProjectContextError extends Error {
|
|
60
|
+
readonly reason: ProjectContextFailure;
|
|
61
|
+
readonly projectId: string;
|
|
62
|
+
constructor(reason: ProjectContextFailure, projectId: string);
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Lazy `Map<projectId, ProjectContext>`. Nothing is instantiated at
|
|
66
|
+
* construction — the boot project is built eagerly by the caller via
|
|
67
|
+
* `context(bootId)`; every other project on first API touch. Concurrent
|
|
68
|
+
* `context()` calls for the same id share one build (the in-flight promise is
|
|
69
|
+
* cached), so recovery never runs twice for a project.
|
|
70
|
+
*/
|
|
71
|
+
export declare class ProjectContexts {
|
|
72
|
+
private readonly deps;
|
|
73
|
+
private readonly contexts;
|
|
74
|
+
private readonly building;
|
|
75
|
+
/** Live store-created subscribers; invoked before RunManager recovery. */
|
|
76
|
+
private readonly storeListeners;
|
|
77
|
+
/** Live `onContextBuilt` subscribers (workspace SSE, step 2.8). */
|
|
78
|
+
private readonly builtListeners;
|
|
79
|
+
/** One semaphore for every manager this map builds — injected by boot,
|
|
80
|
+
* private-but-shared otherwise. */
|
|
81
|
+
private readonly semaphore;
|
|
82
|
+
constructor(deps: ProjectContextDeps);
|
|
83
|
+
/** The built context for `projectId`, building it on first access.
|
|
84
|
+
* Throws `ProjectContextError` for unknown ids and missing roots. */
|
|
85
|
+
context(projectId: string): Promise<ProjectContext>;
|
|
86
|
+
/**
|
|
87
|
+
* Subscribe to future context builds (multi-project spec, step 2.8): the
|
|
88
|
+
* workspace SSE stream attaches to every already-built context at connect
|
|
89
|
+
* and uses this hook to pick up contexts built LATER — so subscribing never
|
|
90
|
+
* force-instantiates a project, yet a project's first API touch makes its
|
|
91
|
+
* events flow to already-open workspace streams. Returns an unsubscribe.
|
|
92
|
+
*/
|
|
93
|
+
onContextBuilt(listener: (ctx: ProjectContext) => void): () => void;
|
|
94
|
+
/**
|
|
95
|
+
* Subscribe at the earliest RunStore lifecycle point: immediately after a
|
|
96
|
+
* lazy project's store opens and before its manager can recover runs. This
|
|
97
|
+
* stays generic so backend-specific observers do not leak into the context
|
|
98
|
+
* map. Returns an unsubscribe.
|
|
99
|
+
*/
|
|
100
|
+
onStoreCreated(listener: (store: RunStore) => void): () => void;
|
|
101
|
+
/** A listener throwing must never fail the build (its store is usable). */
|
|
102
|
+
private notifyStoreCreated;
|
|
103
|
+
/** A listener throwing must never fail the build (its context is fine). */
|
|
104
|
+
private notifyBuilt;
|
|
105
|
+
/** Already-built context, without triggering a build. */
|
|
106
|
+
peek(projectId: string): ProjectContext | undefined;
|
|
107
|
+
/** Ids of every built context (dispose bookkeeping, shutdown flush). */
|
|
108
|
+
ids(): string[];
|
|
109
|
+
/**
|
|
110
|
+
* Tear down one project's context (project removal): the manager stops
|
|
111
|
+
* making moves on its own (`RunManager.dispose()` — usage-sampler
|
|
112
|
+
* unsubscribe, timers, queued state) and the store is closed — index
|
|
113
|
+
* flushed to disk, every event-bus subscriber detached. Returns false when
|
|
114
|
+
* nothing was built for `projectId`.
|
|
115
|
+
*/
|
|
116
|
+
dispose(projectId: string): boolean;
|
|
117
|
+
/** Tear down every built context (process shutdown). */
|
|
118
|
+
disposeAll(): void;
|
|
119
|
+
private build;
|
|
120
|
+
}
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import { join } from 'node:path';
|
|
2
|
+
import { AutomationStore } from '../automations/store.js';
|
|
3
|
+
import { reconcileAutomationReceipts } from '../automations/task-template.js';
|
|
4
|
+
import { DEFAULT_WORKTREE_RETENTION, resolveWorktreeRetention } from '../config.js';
|
|
5
|
+
import { pruneOrphans } from '../git-worktree.js';
|
|
6
|
+
import { reclaimWorktrees } from '../runs/retention.js';
|
|
7
|
+
import { RunStore } from '../runs/store.js';
|
|
8
|
+
import { WorkspaceSemaphore } from '../workspace/semaphore.js';
|
|
9
|
+
import { RunManager } from '../workflows/run.js';
|
|
10
|
+
import { ensureLaunchKey } from './launch-key.js';
|
|
11
|
+
import { getRepoInfo } from './git.js';
|
|
12
|
+
/** Typed failure so the route layer can map reasons to statuses (404/409)
|
|
13
|
+
* without string matching. */
|
|
14
|
+
export class ProjectContextError extends Error {
|
|
15
|
+
reason;
|
|
16
|
+
projectId;
|
|
17
|
+
constructor(reason, projectId) {
|
|
18
|
+
super(reason === 'unknown-project'
|
|
19
|
+
? `unknown project: ${projectId}`
|
|
20
|
+
: `project root is missing: ${projectId}`);
|
|
21
|
+
this.reason = reason;
|
|
22
|
+
this.projectId = projectId;
|
|
23
|
+
this.name = 'ProjectContextError';
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Lazy `Map<projectId, ProjectContext>`. Nothing is instantiated at
|
|
28
|
+
* construction — the boot project is built eagerly by the caller via
|
|
29
|
+
* `context(bootId)`; every other project on first API touch. Concurrent
|
|
30
|
+
* `context()` calls for the same id share one build (the in-flight promise is
|
|
31
|
+
* cached), so recovery never runs twice for a project.
|
|
32
|
+
*/
|
|
33
|
+
export class ProjectContexts {
|
|
34
|
+
deps;
|
|
35
|
+
contexts = new Map();
|
|
36
|
+
building = new Map();
|
|
37
|
+
/** Live store-created subscribers; invoked before RunManager recovery. */
|
|
38
|
+
storeListeners = new Set();
|
|
39
|
+
/** Live `onContextBuilt` subscribers (workspace SSE, step 2.8). */
|
|
40
|
+
builtListeners = new Set();
|
|
41
|
+
/** One semaphore for every manager this map builds — injected by boot,
|
|
42
|
+
* private-but-shared otherwise. */
|
|
43
|
+
semaphore;
|
|
44
|
+
constructor(deps) {
|
|
45
|
+
this.deps = deps;
|
|
46
|
+
this.semaphore = deps.semaphore ?? new WorkspaceSemaphore();
|
|
47
|
+
}
|
|
48
|
+
/** The built context for `projectId`, building it on first access.
|
|
49
|
+
* Throws `ProjectContextError` for unknown ids and missing roots. */
|
|
50
|
+
async context(projectId) {
|
|
51
|
+
const existing = this.contexts.get(projectId);
|
|
52
|
+
if (existing)
|
|
53
|
+
return existing;
|
|
54
|
+
const inFlight = this.building.get(projectId);
|
|
55
|
+
if (inFlight)
|
|
56
|
+
return inFlight;
|
|
57
|
+
const build = this.build(projectId);
|
|
58
|
+
this.building.set(projectId, build);
|
|
59
|
+
try {
|
|
60
|
+
const ctx = await build;
|
|
61
|
+
this.contexts.set(projectId, ctx);
|
|
62
|
+
this.notifyBuilt(ctx);
|
|
63
|
+
return ctx;
|
|
64
|
+
}
|
|
65
|
+
finally {
|
|
66
|
+
this.building.delete(projectId);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Subscribe to future context builds (multi-project spec, step 2.8): the
|
|
71
|
+
* workspace SSE stream attaches to every already-built context at connect
|
|
72
|
+
* and uses this hook to pick up contexts built LATER — so subscribing never
|
|
73
|
+
* force-instantiates a project, yet a project's first API touch makes its
|
|
74
|
+
* events flow to already-open workspace streams. Returns an unsubscribe.
|
|
75
|
+
*/
|
|
76
|
+
onContextBuilt(listener) {
|
|
77
|
+
this.builtListeners.add(listener);
|
|
78
|
+
return () => this.builtListeners.delete(listener);
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Subscribe at the earliest RunStore lifecycle point: immediately after a
|
|
82
|
+
* lazy project's store opens and before its manager can recover runs. This
|
|
83
|
+
* stays generic so backend-specific observers do not leak into the context
|
|
84
|
+
* map. Returns an unsubscribe.
|
|
85
|
+
*/
|
|
86
|
+
onStoreCreated(listener) {
|
|
87
|
+
this.storeListeners.add(listener);
|
|
88
|
+
return () => this.storeListeners.delete(listener);
|
|
89
|
+
}
|
|
90
|
+
/** A listener throwing must never fail the build (its store is usable). */
|
|
91
|
+
notifyStoreCreated(store) {
|
|
92
|
+
for (const listener of [...this.storeListeners]) {
|
|
93
|
+
try {
|
|
94
|
+
listener(store);
|
|
95
|
+
}
|
|
96
|
+
catch {
|
|
97
|
+
// subscriber's problem — context construction can continue
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
/** A listener throwing must never fail the build (its context is fine). */
|
|
102
|
+
notifyBuilt(ctx) {
|
|
103
|
+
for (const listener of [...this.builtListeners]) {
|
|
104
|
+
try {
|
|
105
|
+
listener(ctx);
|
|
106
|
+
}
|
|
107
|
+
catch {
|
|
108
|
+
// subscriber's problem — the build succeeded
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
/** Already-built context, without triggering a build. */
|
|
113
|
+
peek(projectId) {
|
|
114
|
+
return this.contexts.get(projectId);
|
|
115
|
+
}
|
|
116
|
+
/** Ids of every built context (dispose bookkeeping, shutdown flush). */
|
|
117
|
+
ids() {
|
|
118
|
+
return [...this.contexts.keys()];
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Tear down one project's context (project removal): the manager stops
|
|
122
|
+
* making moves on its own (`RunManager.dispose()` — usage-sampler
|
|
123
|
+
* unsubscribe, timers, queued state) and the store is closed — index
|
|
124
|
+
* flushed to disk, every event-bus subscriber detached. Returns false when
|
|
125
|
+
* nothing was built for `projectId`.
|
|
126
|
+
*/
|
|
127
|
+
dispose(projectId) {
|
|
128
|
+
const ctx = this.contexts.get(projectId);
|
|
129
|
+
if (!ctx)
|
|
130
|
+
return false;
|
|
131
|
+
this.contexts.delete(projectId);
|
|
132
|
+
teardown(ctx);
|
|
133
|
+
return true;
|
|
134
|
+
}
|
|
135
|
+
/** Tear down every built context (process shutdown). */
|
|
136
|
+
disposeAll() {
|
|
137
|
+
for (const id of this.ids())
|
|
138
|
+
this.dispose(id);
|
|
139
|
+
}
|
|
140
|
+
async build(projectId) {
|
|
141
|
+
const projects = await this.deps.listProjects();
|
|
142
|
+
const project = projects.find((p) => p.id === projectId);
|
|
143
|
+
if (!project)
|
|
144
|
+
throw new ProjectContextError('unknown-project', projectId);
|
|
145
|
+
if (project.status === 'missing')
|
|
146
|
+
throw new ProjectContextError('missing-root', projectId);
|
|
147
|
+
const dataDir = join(project.root, '.ai/cezar');
|
|
148
|
+
// keepLive + recover() (#367), same as serveCommand: runs that were live
|
|
149
|
+
// when this project's context last existed are re-queued or resumed.
|
|
150
|
+
const store = RunStore.open(dataDir, { keepLive: true });
|
|
151
|
+
const automationStore = this.deps.automationStore?.(project.id, project.root)
|
|
152
|
+
?? AutomationStore.open(dataDir);
|
|
153
|
+
reconcileAutomationReceipts(automationStore, store);
|
|
154
|
+
this.notifyStoreCreated(store);
|
|
155
|
+
const manager = new RunManager(store, project.root, { semaphore: this.semaphore });
|
|
156
|
+
try {
|
|
157
|
+
const launchKey = ensureLaunchKey(dataDir);
|
|
158
|
+
// Startup reconcile (spec 006) + count-based retention (#483) — the same
|
|
159
|
+
// best-effort sweeps serveCommand runs for the boot project, gated on the
|
|
160
|
+
// root actually being a git repo.
|
|
161
|
+
if (await getRepoInfo(project.root)) {
|
|
162
|
+
await pruneOrphans(project.root, new Set(store.listRuns().map((r) => r.id))).catch(() => []);
|
|
163
|
+
const keep = await resolveWorktreeRetention(project.root).catch(() => DEFAULT_WORKTREE_RETENTION);
|
|
164
|
+
await reclaimWorktrees(project.root, store, keep).catch(() => []);
|
|
165
|
+
}
|
|
166
|
+
await manager.recover();
|
|
167
|
+
return { id: project.id, root: project.root, dataDir, store, manager, automationStore, launchKey };
|
|
168
|
+
}
|
|
169
|
+
catch (err) {
|
|
170
|
+
// A failed build must not leak the half-built context's subscriptions.
|
|
171
|
+
teardown({ store, manager });
|
|
172
|
+
throw err;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
/** Shared teardown for built and half-built contexts. */
|
|
177
|
+
function teardown(ctx) {
|
|
178
|
+
ctx.manager.dispose();
|
|
179
|
+
ctx.store.flush();
|
|
180
|
+
ctx.store.removeAllListeners();
|
|
181
|
+
}
|
|
182
|
+
//# sourceMappingURL=project-context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-context.js","sourceRoot":"","sources":["../../src/server/project-context.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ProviderId, ProviderStatusResponse } from '../core/provider-auth.ts';
|
|
2
|
+
import type { RunRecord } from '../runs/store.ts';
|
|
3
|
+
import { type WorkflowDef } from '../workflows/types.ts';
|
|
4
|
+
export declare function providersRequiredByWorkflow(workflow: WorkflowDef, fallback: ProviderId): ProviderId[];
|
|
5
|
+
export declare function providerForExistingRun(run: RunRecord, override?: ProviderId): ProviderId;
|
|
6
|
+
/** The provider that owns a currently live session, when the record is attributed. */
|
|
7
|
+
export declare function providerForActiveRun(run: RunRecord): ProviderId;
|
|
8
|
+
export declare function unavailableProviderMessage(required: readonly ProviderId[], response: ProviderStatusResponse): string | null;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { PROVIDER_IDS } from '../core/provider-auth.js';
|
|
2
|
+
import { stepKind } from '../workflows/types.js';
|
|
3
|
+
const ORDER = PROVIDER_IDS;
|
|
4
|
+
const LABEL = {
|
|
5
|
+
claude: 'Claude Code',
|
|
6
|
+
codex: 'Codex',
|
|
7
|
+
opencode: 'OpenCode',
|
|
8
|
+
pi: 'pi',
|
|
9
|
+
};
|
|
10
|
+
export function providersRequiredByWorkflow(workflow, fallback) {
|
|
11
|
+
const required = new Set();
|
|
12
|
+
for (const step of workflow.steps) {
|
|
13
|
+
if (stepKind(step) === 'agent')
|
|
14
|
+
required.add(step.runner ?? fallback);
|
|
15
|
+
}
|
|
16
|
+
return ORDER.filter((provider) => required.has(provider));
|
|
17
|
+
}
|
|
18
|
+
export function providerForExistingRun(run, override) {
|
|
19
|
+
if (override)
|
|
20
|
+
return override;
|
|
21
|
+
return run.runner ?? 'claude';
|
|
22
|
+
}
|
|
23
|
+
/** The provider that owns a currently live session, when the record is attributed. */
|
|
24
|
+
export function providerForActiveRun(run) {
|
|
25
|
+
const current = run.currentStepId
|
|
26
|
+
? run.steps.find((step) => step.id === run.currentStepId)
|
|
27
|
+
: undefined;
|
|
28
|
+
if (current?.backend)
|
|
29
|
+
return current.backend;
|
|
30
|
+
// `execute()` persists the task backend before it starts a step. This is the
|
|
31
|
+
// conservative fallback for older records whose current step lacks affinity.
|
|
32
|
+
if (run.runner)
|
|
33
|
+
return run.runner;
|
|
34
|
+
// Pre-affinity records can still carry a prior attributed session. It is a
|
|
35
|
+
// better fallback than guessing Claude, but never outranks the live step or
|
|
36
|
+
// the run's current runner.
|
|
37
|
+
for (let index = run.steps.length - 1; index >= 0; index -= 1) {
|
|
38
|
+
const backend = run.steps[index]?.backend;
|
|
39
|
+
if (backend)
|
|
40
|
+
return backend;
|
|
41
|
+
}
|
|
42
|
+
return 'claude';
|
|
43
|
+
}
|
|
44
|
+
export function unavailableProviderMessage(required, response) {
|
|
45
|
+
for (const provider of required) {
|
|
46
|
+
const row = response.providers.find(({ provider: id }) => id === provider);
|
|
47
|
+
if (row?.enabled === false) {
|
|
48
|
+
return `${LABEL[provider]} is disabled. Enable it in Settings → Agents → Providers.`;
|
|
49
|
+
}
|
|
50
|
+
if (row?.status !== 'connected') {
|
|
51
|
+
return `${LABEL[provider]} credentials are unavailable. Authorize it in Settings → Agents → Providers.`;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=provider-action-gate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider-action-gate.js","sourceRoot":"","sources":["../../src/server/provider-action-gate.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAExD,OAAO,EAAE,QAAQ,EAAoB,MAAM,uBAAuB,CAAC;AAEnE,MAAM,KAAK,GAA0B,YAAY,CAAC;AAClD,MAAM,KAAK,GAA+B;IACxC,MAAM,EAAE,aAAa;IACrB,KAAK,EAAE,OAAO;IACd,QAAQ,EAAE,UAAU;IACpB,EAAE,EAAE,IAAI;CACT,CAAC;AAEF,MAAM,UAAU,2BAA2B,CACzC,QAAqB,EACrB,QAAoB;IAEpB,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAc,CAAC;IACvC,KAAK,MAAM,IAAI,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;QAClC,IAAI,QAAQ,CAAC,IAAI,CAAC,KAAK,OAAO;YAAE,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,IAAI,QAAQ,CAAC,CAAC;IACxE,CAAC;IACD,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC;AAC5D,CAAC;AAED,MAAM,UAAU,sBAAsB,CACpC,GAAc,EACd,QAAqB;IAErB,IAAI,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAC9B,OAAO,GAAG,CAAC,MAAM,IAAI,QAAQ,CAAC;AAChC,CAAC;AAED,sFAAsF;AACtF,MAAM,UAAU,oBAAoB,CAAC,GAAc;IACjD,MAAM,OAAO,GAAG,GAAG,CAAC,aAAa;QAC/B,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,GAAG,CAAC,aAAa,CAAC;QACzD,CAAC,CAAC,SAAS,CAAC;IACd,IAAI,OAAO,EAAE,OAAO;QAAE,OAAO,OAAO,CAAC,OAAO,CAAC;IAE7C,6EAA6E;IAC7E,6EAA6E;IAC7E,IAAI,GAAG,CAAC,MAAM;QAAE,OAAO,GAAG,CAAC,MAAM,CAAC;IAElC,2EAA2E;IAC3E,4EAA4E;IAC5E,4BAA4B;IAC5B,KAAK,IAAI,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;QAC9D,MAAM,OAAO,GAAG,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;QAC1C,IAAI,OAAO;YAAE,OAAO,OAAO,CAAC;IAC9B,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,0BAA0B,CACxC,QAA+B,EAC/B,QAAgC;IAEhC,KAAK,MAAM,QAAQ,IAAI,QAAQ,EAAE,CAAC;QAChC,MAAM,GAAG,GAAG,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,KAAK,QAAQ,CAAC,CAAC;QAC3E,IAAI,GAAG,EAAE,OAAO,KAAK,KAAK,EAAE,CAAC;YAC3B,OAAO,GAAG,KAAK,CAAC,QAAQ,CAAC,2DAA2D,CAAC;QACvF,CAAC;QACD,IAAI,GAAG,EAAE,MAAM,KAAK,WAAW,EAAE,CAAC;YAChC,OAAO,GAAG,KAAK,CAAC,QAAQ,CAAC,8EAA8E,CAAC;QAC1G,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { type ProviderAuthService, type ProviderStatus } from '../core/provider-auth.ts';
|
|
2
|
+
import type { RunStore } from '../runs/store.ts';
|
|
3
|
+
export declare function watchProviderRuntimeAuthFailures(store: RunStore, providerAuth: ProviderAuthService, onInvalidated: (status: ProviderStatus) => void): () => void;
|
|
4
|
+
/**
|
|
5
|
+
* Process-wide dedupe for store observation. The same boot store is wired
|
|
6
|
+
* before recovery and again when the HTTP app is constructed; lazy stores are
|
|
7
|
+
* wired both at creation and at the existing context-built hook. One listener
|
|
8
|
+
* per RunStore keeps those lifecycle overlaps harmless.
|
|
9
|
+
*/
|
|
10
|
+
export declare class ProviderRuntimeAuthObserver {
|
|
11
|
+
private readonly providerAuth;
|
|
12
|
+
private readonly onInvalidated;
|
|
13
|
+
private readonly watched;
|
|
14
|
+
constructor(providerAuth: ProviderAuthService, onInvalidated: (status: ProviderStatus) => void);
|
|
15
|
+
watch(store: RunStore): void;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Boot ordering seam: observation must exist before recovery starts because a
|
|
19
|
+
* resumed runner can emit its first normalized error before recover() returns.
|
|
20
|
+
*/
|
|
21
|
+
export declare function recoverWithProviderRuntimeAuthObservation(store: RunStore, recover: () => Promise<void>, observer: ProviderRuntimeAuthObserver): Promise<void>;
|