eve 0.27.13 → 0.29.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/CHANGELOG.md +38 -0
- package/dist/src/channel/adapter.d.ts +5 -5
- package/dist/src/channel/session.d.ts +2 -2
- package/dist/src/channel/types.d.ts +16 -6
- package/dist/src/chunks/{use-eve-agent-CWYe-vqE.js → use-eve-agent-CyDt3Lny.js} +92 -1
- package/dist/src/chunks/{use-eve-agent-CsSQOKnp.js → use-eve-agent-DaH3cf8K.js} +92 -1
- package/dist/src/cli/commands/agent-prompt/collect-intent.md +1 -1
- package/dist/src/cli/commands/channels.d.ts +0 -17
- package/dist/src/cli/commands/channels.js +1 -1
- package/dist/src/cli/commands/deploy.js +1 -1
- package/dist/src/cli/commands/extension-init.js +1 -1
- package/dist/src/cli/commands/init.js +1 -1
- package/dist/src/cli/commands/integration-connect.d.ts +29 -0
- package/dist/src/cli/commands/integration-connect.js +1 -0
- package/dist/src/cli/commands/integration-setup.d.ts +2 -3
- package/dist/src/cli/commands/integration-setup.js +1 -1
- package/dist/src/cli/commands/register-integration-commands.js +1 -1
- package/dist/src/cli/commands/registry-setup-command.d.ts +13 -3
- package/dist/src/cli/commands/registry-setup-command.js +2 -1
- package/dist/src/cli/commands/registry.d.ts +35 -1
- package/dist/src/cli/commands/registry.js +1 -1
- package/dist/src/cli/commands/trace.js +1 -1
- package/dist/src/cli/dev/tui/agent-header.js +1 -1
- package/dist/src/cli/dev/tui/prompt-command-handler.js +1 -1
- package/dist/src/cli/dev/tui/prompt-commands.d.ts +1 -1
- package/dist/src/cli/dev/tui/prompt-commands.js +1 -1
- package/dist/src/cli/dev/tui/remote-auth-command.js +1 -1
- package/dist/src/cli/dev/tui/runner.d.ts +8 -7
- package/dist/src/cli/dev/tui/runner.js +1 -1
- package/dist/src/cli/dev/tui/setup-commands.d.ts +8 -13
- package/dist/src/cli/dev/tui/setup-commands.js +3 -2
- package/dist/src/cli/dev/tui/setup-flow.d.ts +14 -5
- package/dist/src/cli/dev/tui/setup-panel.d.ts +5 -1
- package/dist/src/cli/dev/tui/setup-panel.js +2 -2
- package/dist/src/cli/dev/tui/status-line.d.ts +1 -1
- package/dist/src/cli/dev/tui/status-line.js +1 -1
- package/dist/src/cli/dev/tui/subagent-pump.d.ts +8 -2
- package/dist/src/cli/dev/tui/subagent-pump.js +1 -1
- package/dist/src/cli/dev/tui/terminal-renderer.d.ts +2 -5
- package/dist/src/cli/dev/tui/terminal-renderer.js +12 -12
- package/dist/src/cli/dev/tui/test/fake-setup-flow-renderer.js +1 -1
- package/dist/src/cli/dev/tui/tui-prompter.js +1 -1
- package/dist/src/cli/dev/tui/tui.d.ts +2 -0
- package/dist/src/cli/dev/tui/tui.js +1 -1
- package/dist/src/cli/dev/tui/vercel-status.d.ts +1 -6
- package/dist/src/cli/dev/tui/vercel-status.js +1 -1
- package/dist/src/cli/invoke/result.d.ts +15 -0
- package/dist/src/cli/invoke/result.js +1 -1
- package/dist/src/cli/option-parsers.d.ts +11 -0
- package/dist/src/cli/option-parsers.js +1 -0
- package/dist/src/cli/run.d.ts +1 -12
- package/dist/src/cli/run.js +3 -3
- package/dist/src/cli/shutdown.d.ts +2 -0
- package/dist/src/cli/shutdown.js +1 -1
- package/dist/src/client/eve-agent-store.d.ts +7 -4
- package/dist/src/client/eve-agent-store.js +1 -1
- package/dist/src/client/index.d.ts +3 -3
- package/dist/src/client/index.js +1 -1
- package/dist/src/client/message-action-parts.js +1 -1
- package/dist/src/client/message-reducer-types.d.ts +5 -3
- package/dist/src/client/message-response.d.ts +4 -4
- package/dist/src/client/ndjson.d.ts +3 -3
- package/dist/src/client/open-stream.d.ts +2 -2
- package/dist/src/client/output-schema.d.ts +2 -2
- package/dist/src/client/reducer.d.ts +2 -2
- package/dist/src/client/session-utils.d.ts +5 -5
- package/dist/src/client/session.d.ts +2 -2
- package/dist/src/client/types.d.ts +2 -2
- package/dist/src/compiled/.vendor-stamp.json +5 -5
- package/dist/src/compiled/@workflow/core/index.js +1 -1
- package/dist/src/compiled/@workflow/core/private.d.ts +21 -5
- package/dist/src/compiled/@workflow/core/private.js +1 -1
- package/dist/src/compiled/@workflow/core/runtime/world.d.ts +10 -5
- package/dist/src/compiled/@workflow/core/runtime.js +3 -3
- package/dist/src/compiled/@workflow/core/telemetry/semantic-conventions.d.ts +2 -2
- package/dist/src/compiled/@workflow/core/version.d.ts +1 -1
- package/dist/src/compiled/@workflow/core/workflow.js +1 -1
- package/dist/src/compiled/@workflow/world-local/index.js +3 -3
- package/dist/src/compiled/@workflow/world-vercel/index.js +13 -13
- package/dist/src/compiled/_chunks/workflow/{attribute-changes-DeZc2RZz.js → attribute-changes-1LmTKuTT.js} +1 -1
- package/dist/src/compiled/_chunks/workflow/{private-Cre8uYkA.js → private-BcwCGTV5.js} +1 -1
- package/dist/src/compiled/_chunks/workflow/{resume-hook-ip1hbn1b.js → resume-hook-D1_5NCZ6.js} +1 -1
- package/dist/src/compiled/_chunks/workflow/{run-CWytxfIp.js → run-C240Ctf4.js} +1 -1
- package/dist/src/compiled/_chunks/workflow/sleep-De802yfX.js +1 -0
- package/dist/src/compiled/_chunks/workflow/{wait-until-De9yESQN.js → wait-until-z48sPUjU.js} +2 -2
- package/dist/src/compiled/shadcn-registry/index.d.ts +1 -0
- package/dist/src/compiler/compile-from-memory.d.ts +1 -0
- package/dist/src/compiler/extension-compatibility.d.ts +8 -8
- package/dist/src/compiler/extension-compatibility.js +1 -1
- package/dist/src/compiler/manifest.d.ts +2 -2
- package/dist/src/compiler/manifest.js +1 -1
- package/dist/src/compiler/normalize-agent-config.js +1 -1
- package/dist/src/context/dynamic-instruction-lifecycle.d.ts +2 -2
- package/dist/src/context/dynamic-model-lifecycle.d.ts +2 -2
- package/dist/src/context/dynamic-skill-lifecycle.d.ts +2 -2
- package/dist/src/context/dynamic-tool-lifecycle.d.ts +2 -2
- package/dist/src/context/hook-lifecycle.d.ts +2 -2
- package/dist/src/evals/assertions/collector.d.ts +2 -10
- package/dist/src/evals/assertions/collector.js +1 -1
- package/dist/src/evals/assertions/run.d.ts +3 -3
- package/dist/src/evals/cli/eval.d.ts +6 -2
- package/dist/src/evals/cli/eval.js +2 -2
- package/dist/src/evals/cli/filter.d.ts +14 -0
- package/dist/src/evals/cli/filter.js +1 -0
- package/dist/src/evals/context.js +1 -1
- package/dist/src/evals/diagnostics.d.ts +8 -0
- package/dist/src/evals/diagnostics.js +1 -0
- package/dist/src/evals/expect/index.d.ts +1 -1
- package/dist/src/evals/expect/index.js +1 -1
- package/dist/src/evals/index.d.ts +1 -1
- package/dist/src/evals/judge.js +2 -1
- package/dist/src/evals/match.d.ts +4 -4
- package/dist/src/evals/runner/artifacts.js +1 -1
- package/dist/src/evals/runner/derive-run-facts.d.ts +2 -2
- package/dist/src/evals/runner/reporters/assertion-diagnostics.d.ts +3 -0
- package/dist/src/evals/runner/reporters/assertion-diagnostics.js +3 -0
- package/dist/src/evals/runner/reporters/braintrust.js +1 -1
- package/dist/src/evals/runner/reporters/console.js +1 -1
- package/dist/src/evals/runner/reporters/junit.js +2 -2
- package/dist/src/evals/session.d.ts +3 -3
- package/dist/src/evals/types.d.ts +33 -17
- package/dist/src/execution/cancel-descendant-turns-step.js +1 -1
- package/dist/src/execution/dispatch-runtime-actions-step.js +1 -1
- package/dist/src/execution/route-child-delivery.d.ts +4 -3
- package/dist/src/execution/route-child-delivery.js +1 -1
- package/dist/src/execution/session-delivery-hook.d.ts +1 -0
- package/dist/src/execution/session-delivery-hook.js +1 -1
- package/dist/src/execution/session-timeout-control.d.ts +9 -0
- package/dist/src/execution/session-timeout-control.js +1 -0
- package/dist/src/execution/session-timeout-steps.d.ts +13 -0
- package/dist/src/execution/session-timeout-steps.js +1 -0
- package/dist/src/execution/session-timeout-workflow.d.ts +6 -0
- package/dist/src/execution/session-timeout-workflow.js +1 -0
- package/dist/src/execution/session-timeout.d.ts +2 -0
- package/dist/src/execution/session-timeout.js +1 -0
- package/dist/src/execution/settle-cancelled-turn-step.js +1 -1
- package/dist/src/execution/subagent-event-proxy-step.js +1 -1
- package/dist/src/execution/subagent-hitl-proxy.d.ts +5 -1
- package/dist/src/execution/subagent-hitl-proxy.js +1 -1
- package/dist/src/execution/terminal-session-completion-step.d.ts +5 -0
- package/dist/src/execution/terminal-session-completion-step.js +1 -0
- package/dist/src/execution/terminal-session-failure-step.js +1 -1
- package/dist/src/execution/turn-cancellation-control.js +1 -1
- package/dist/src/execution/turn-workflow.js +1 -1
- package/dist/src/execution/workflow-entry.d.ts +1 -0
- package/dist/src/execution/workflow-entry.js +1 -1
- package/dist/src/execution/workflow-runtime.d.ts +4 -0
- package/dist/src/execution/workflow-runtime.js +1 -1
- package/dist/src/execution/workflow-steps.d.ts +12 -2
- package/dist/src/execution/workflow-steps.js +1 -1
- package/dist/src/harness/agent-otel-provider.js +1 -1
- package/dist/src/harness/ai-sdk-hook-bridge.js +1 -1
- package/dist/src/harness/input-extraction.js +1 -1
- package/dist/src/harness/input-request-class.d.ts +23 -0
- package/dist/src/harness/input-request-class.js +1 -0
- package/dist/src/harness/input-requests.d.ts +20 -9
- package/dist/src/harness/input-requests.js +1 -1
- package/dist/src/harness/instrumentation-lifecycle.d.ts +12 -1
- package/dist/src/harness/proxy-input-requests.d.ts +10 -4
- package/dist/src/harness/proxy-input-requests.js +1 -1
- package/dist/src/harness/session-limit-continuation.d.ts +0 -11
- package/dist/src/harness/session-limit-continuation.js +1 -1
- package/dist/src/harness/session-limit-enforcement.d.ts +3 -2
- package/dist/src/harness/session-limit-enforcement.js +1 -1
- package/dist/src/harness/session-token-limits.d.ts +41 -0
- package/dist/src/harness/session-token-limits.js +1 -0
- package/dist/src/harness/stale-input-responses.js +1 -1
- package/dist/src/harness/subagent-token-budget.d.ts +6 -4
- package/dist/src/harness/subagent-token-budget.js +1 -1
- package/dist/src/harness/tool-loop.js +1 -1
- package/dist/src/harness/turn-sleep.d.ts +12 -0
- package/dist/src/harness/turn-sleep.js +1 -0
- package/dist/src/harness/turn-tag-state.d.ts +26 -17
- package/dist/src/harness/turn-tag-state.js +1 -1
- package/dist/src/harness/types.d.ts +4 -4
- package/dist/src/harness/workflow-lifecycle.d.ts +2 -2
- package/dist/src/internal/application/compiled-artifacts.js +7 -7
- package/dist/src/internal/application/package.js +1 -1
- package/dist/src/internal/authored-definition/core.js +1 -1
- package/dist/src/internal/nitro/host/dev-authored-source-watcher.d.ts +4 -0
- package/dist/src/internal/nitro/host/dev-authored-source-watcher.js +1 -1
- package/dist/src/internal/nitro/host/start-development-server.js +2 -2
- package/dist/src/internal/workflow/development-world-protocol.js +1 -1
- package/dist/src/internal/workflow/world-target.d.ts +7 -0
- package/dist/src/internal/workflow/world-target.js +1 -0
- package/dist/src/internal/workflow-bundle/workflow-core-shim.d.ts +1 -1
- package/dist/src/internal/workflow-bundle/workflow-core-shim.js +1 -1
- package/dist/src/protocol/event-dedupe.d.ts +25 -0
- package/dist/src/protocol/event-dedupe.js +1 -0
- package/dist/src/protocol/event-id.d.ts +16 -0
- package/dist/src/protocol/event-id.js +1 -0
- package/dist/src/protocol/message.d.ts +39 -23
- package/dist/src/protocol/message.js +2 -2
- package/dist/src/protocol/routes.d.ts +4 -0
- package/dist/src/protocol/routes.js +1 -1
- package/dist/src/public/channels/discord/discordChannel.d.ts +3 -3
- package/dist/src/public/channels/github/githubChannel.d.ts +3 -3
- package/dist/src/public/channels/linear/linearChannel.d.ts +3 -3
- package/dist/src/public/channels/slack/hitl.js +1 -1
- package/dist/src/public/channels/slack/slackChannel.d.ts +3 -3
- package/dist/src/public/channels/teams/hitl.js +1 -1
- package/dist/src/public/channels/teams/teamsChannel.d.ts +3 -3
- package/dist/src/public/channels/telegram/telegramChannel.d.ts +3 -3
- package/dist/src/public/channels/twilio/twilioChannel.d.ts +3 -3
- package/dist/src/public/definitions/channel.d.ts +4 -4
- package/dist/src/public/definitions/hook.d.ts +2 -2
- package/dist/src/public/tools/sleep/index.d.ts +18 -0
- package/dist/src/public/tools/sleep/index.js +1 -0
- package/dist/src/react/use-eve-agent.d.ts +3 -2
- package/dist/src/runtime/framework-tools/ask-question.js +1 -1
- package/dist/src/runtime/framework-tools/sleep.d.ts +15 -0
- package/dist/src/runtime/framework-tools/sleep.js +1 -0
- package/dist/src/runtime/hooks/registry.d.ts +2 -2
- package/dist/src/runtime/input/types.d.ts +19 -4
- package/dist/src/runtime/input/types.js +1 -1
- package/dist/src/runtime/resolve-agent.js +1 -1
- package/dist/src/runtime/types.d.ts +2 -2
- package/dist/src/services/dev-client/runtime-artifacts.d.ts +7 -0
- package/dist/src/services/dev-client/runtime-artifacts.js +1 -1
- package/dist/src/setup/boxes/apply-ai-gateway-credential.js +1 -1
- package/dist/src/setup/boxes/deploy-project.d.ts +3 -3
- package/dist/src/setup/flows/deploy.js +1 -1
- package/dist/src/setup/flows/ensure-vercel-project.d.ts +17 -0
- package/dist/src/setup/flows/ensure-vercel-project.js +1 -0
- package/dist/src/setup/flows/in-project.d.ts +1 -1
- package/dist/src/setup/flows/link.js +1 -1
- package/dist/src/setup/flows/model.js +1 -1
- package/dist/src/setup/flows/provider.js +1 -1
- package/dist/src/setup/flows/registry.d.ts +20 -0
- package/dist/src/setup/flows/registry.js +1 -0
- package/dist/src/setup/index.d.ts +0 -1
- package/dist/src/setup/index.js +1 -1
- package/dist/src/setup/{channel-setup-environment.d.ts → integrations/channels/environment.d.ts} +2 -2
- package/dist/src/setup/integrations/channels/environment.js +1 -0
- package/dist/src/setup/{channel-setup-integrations.d.ts → integrations/channels/index.d.ts} +3 -3
- package/dist/src/setup/integrations/channels/index.js +1 -0
- package/dist/src/setup/{channel-setup-runner.d.ts → integrations/channels/runner.d.ts} +1 -1
- package/dist/src/setup/integrations/channels/runner.js +1 -0
- package/dist/src/setup/{boxes/add-channels.d.ts → integrations/channels/setup.d.ts} +32 -22
- package/dist/src/setup/integrations/channels/setup.js +2 -0
- package/dist/src/setup/{channel-setup-slack.d.ts → integrations/channels/slack.d.ts} +1 -1
- package/dist/src/setup/integrations/channels/slack.js +1 -0
- package/dist/src/setup/{channel-setup-integration.d.ts → integrations/channels/types.d.ts} +23 -7
- package/dist/src/setup/{channel-setup-ui.d.ts → integrations/channels/ui.d.ts} +2 -2
- package/dist/src/setup/integrations/channels/ui.js +2 -0
- package/dist/src/setup/{channel-setup-web.d.ts → integrations/channels/web.d.ts} +1 -1
- package/dist/src/setup/integrations/channels/web.js +1 -0
- package/dist/src/setup/primitives/run-vercel.d.ts +1 -0
- package/dist/src/setup/primitives/run-vercel.js +1 -1
- package/dist/src/setup/prompter.d.ts +16 -3
- package/dist/src/setup/prompter.js +1 -1
- package/dist/src/setup/registry-setup-client.d.ts +18 -0
- package/dist/src/setup/registry-setup-client.js +2 -0
- package/dist/src/setup/registry-setup-protocol.d.ts +93 -0
- package/dist/src/setup/registry-setup-protocol.js +1 -0
- package/dist/src/setup/scaffold/channels-catalog.d.ts +1 -1
- package/dist/src/setup/scaffold/create/extension.js +2 -2
- package/dist/src/setup/scaffold/create/project.js +2 -2
- package/dist/src/setup/scaffold/create/web-template.d.ts +1 -1
- package/dist/src/setup/scaffold/create/web-template.js +2 -2
- package/dist/src/setup/scaffold/create-in-place.d.ts +1 -0
- package/dist/src/setup/scaffold/create-in-place.js +1 -0
- package/dist/src/setup/scaffold/index.js +1 -1
- package/dist/src/setup/scaffold/update/connections.js +3 -3
- package/dist/src/setup/scaffold/update/update-connection-connector.js +1 -1
- package/dist/src/setup/vercel-project-framework.d.ts +1 -1
- package/dist/src/setup/vercel-project-framework.js +1 -1
- package/dist/src/setup/vercel-project.d.ts +17 -2
- package/dist/src/setup/vercel-project.js +0 -0
- package/dist/src/shared/agent-definition.d.ts +12 -0
- package/dist/src/shared/dynamic-tool-definition.d.ts +2 -2
- package/dist/src/shared/ulid.d.ts +39 -0
- package/dist/src/shared/ulid.js +1 -0
- package/dist/src/svelte/index.js +1 -1
- package/dist/src/svelte/use-eve-agent.d.ts +4 -4
- package/dist/src/svelte/use-eve-agent.js +1 -1
- package/dist/src/vue/index.js +1 -1
- package/dist/src/vue/use-eve-agent.d.ts +4 -4
- package/dist/src/vue/use-eve-agent.js +1 -1
- package/docs/agent-config.md +28 -16
- package/docs/channels/overview.mdx +1 -1
- package/docs/channels/slack.mdx +2 -2
- package/docs/concepts/default-harness.md +12 -0
- package/docs/concepts/execution-model-and-durability.mdx +1 -1
- package/docs/concepts/sessions-runs-and-streaming.md +61 -0
- package/docs/evals/assertions.mdx +8 -1
- package/docs/evals/judge.mdx +11 -1
- package/docs/evals/reporters.mdx +1 -1
- package/docs/evals/running.mdx +3 -0
- package/docs/guides/client/streaming.mdx +9 -3
- package/docs/guides/dev-tui.md +9 -14
- package/docs/guides/frontend/overview.mdx +4 -2
- package/docs/guides/frontend/use-eve-agent-svelte.mdx +1 -1
- package/docs/guides/frontend/use-eve-agent-vue.mdx +10 -10
- package/docs/guides/hooks.md +40 -2
- package/docs/guides/instrumentation.md +5 -1
- package/docs/reference/cli.md +25 -38
- package/docs/reference/typescript-api.md +2 -1
- package/docs/tools/human-in-the-loop.md +5 -0
- package/docs/tutorial/ship-it.mdx +2 -2
- package/package.json +11 -6
- package/dist/src/compiled/@workflow/core/runtime/world-target.d.ts +0 -11
- package/dist/src/compiled/_chunks/workflow/sleep-BjrUxUcs.js +0 -1
- package/dist/src/node_modules/.pnpm/@workflow_utils@5.0.0-beta.7/node_modules/@workflow/utils/dist/index.js +0 -1
- package/dist/src/node_modules/.pnpm/@workflow_utils@5.0.0-beta.7/node_modules/@workflow/utils/dist/parse-name.js +0 -1
- package/dist/src/node_modules/.pnpm/@workflow_utils@5.0.0-beta.7/node_modules/@workflow/utils/dist/promise.js +0 -1
- package/dist/src/node_modules/.pnpm/@workflow_utils@5.0.0-beta.7/node_modules/@workflow/utils/dist/time.js +0 -1
- package/dist/src/node_modules/.pnpm/@workflow_utils@5.0.0-beta.7/node_modules/@workflow/utils/dist/workflow-routes.js +0 -1
- package/dist/src/node_modules/.pnpm/@workflow_utils@5.0.0-beta.7/node_modules/@workflow/utils/dist/world-target.js +0 -1
- package/dist/src/node_modules/.pnpm/ms@2.1.3/node_modules/ms/index.js +0 -1
- package/dist/src/setup/boxes/add-channels.js +0 -2
- package/dist/src/setup/boxes/add-connections.d.ts +0 -26
- package/dist/src/setup/boxes/add-connections.js +0 -1
- package/dist/src/setup/boxes/install-channel-registry-items.d.ts +0 -8
- package/dist/src/setup/boxes/install-channel-registry-items.js +0 -1
- package/dist/src/setup/boxes/one-shot-next-steps.d.ts +0 -18
- package/dist/src/setup/boxes/one-shot-next-steps.js +0 -2
- package/dist/src/setup/boxes/preflight.d.ts +0 -37
- package/dist/src/setup/boxes/preflight.js +0 -1
- package/dist/src/setup/boxes/resolve-target.d.ts +0 -58
- package/dist/src/setup/boxes/resolve-target.js +0 -1
- package/dist/src/setup/boxes/scaffold.d.ts +0 -40
- package/dist/src/setup/boxes/scaffold.js +0 -1
- package/dist/src/setup/boxes/select-channels.d.ts +0 -49
- package/dist/src/setup/boxes/select-channels.js +0 -1
- package/dist/src/setup/boxes/select-chat.d.ts +0 -38
- package/dist/src/setup/boxes/select-chat.js +0 -1
- package/dist/src/setup/boxes/select-connections.d.ts +0 -30
- package/dist/src/setup/boxes/select-connections.js +0 -1
- package/dist/src/setup/boxes/select-setup-mode.d.ts +0 -32
- package/dist/src/setup/boxes/select-setup-mode.js +0 -1
- package/dist/src/setup/channel-setup-deployment.d.ts +0 -11
- package/dist/src/setup/channel-setup-deployment.js +0 -1
- package/dist/src/setup/channel-setup-environment.js +0 -1
- package/dist/src/setup/channel-setup-integration.js +0 -1
- package/dist/src/setup/channel-setup-integrations.js +0 -1
- package/dist/src/setup/channel-setup-runner.js +0 -1
- package/dist/src/setup/channel-setup-slack.js +0 -1
- package/dist/src/setup/channel-setup-ui.js +0 -2
- package/dist/src/setup/channel-setup-web.js +0 -1
- package/dist/src/setup/flows/channels.d.ts +0 -57
- package/dist/src/setup/flows/channels.js +0 -1
- package/dist/src/setup/flows/connections.d.ts +0 -37
- package/dist/src/setup/flows/connections.js +0 -3
- package/dist/src/setup/onboarding.d.ts +0 -60
- package/dist/src/setup/onboarding.js +0 -1
- /package/dist/src/{node_modules/.pnpm/@workflow_utils@5.0.0-beta.7/node_modules/@workflow/utils/dist/pluralize.js → setup/integrations/channels/types.js} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{WizardCancelledError}from"#setup/step.js";import{withSpinner}from"#setup/with-spinner.js";const ADDRESS_PREFIX=`address:`,BACK=`action:back`,DONE=`action:done`,ALL=`category:all`,REGISTRY_CATEGORIES=[{value:`category:channel`,prefix:`channel/`,label:`Chat channels`,hint:`Web, Slack, Discord, Teams`},{value:`category:connection`,prefix:`connection/`,label:`Tools & data`,hint:`Linear, Notion, GitHub, Vercel`},{value:`category:extension`,prefix:`extension/`,label:`Capabilities`,hint:`Browser automation, memory, developer tools`},{value:`category:instrumentation`,prefix:`instrumentation/`,label:`Observability`,hint:`Sentry, Braintrust, Honeycomb`}];function itemLabel(e){return(e.name.split(`/`).at(-1)??e.name).split(`-`).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(` `)}function itemRows(e){return e.map((e,t)=>({value:`item:${t}`,label:itemLabel(e),hint:e.description??e.type}))}function categoryRows(){return[...REGISTRY_CATEGORIES.map(e=>({value:e.value,label:e.label,hint:e.hint})),{value:ALL,label:`All integrations`,hint:`Search by name or enter an item address`},{value:DONE,label:`Back to chat`,trailingAction:!0}]}function itemsForCategory(e,t){if(t===ALL)return e;let n=REGISTRY_CATEGORIES.find(e=>e.value===t);return n===void 0?e:e.filter(e=>e.address.startsWith(n.prefix)||e.name.startsWith(n.prefix))}function stringArray(e){return Array.isArray(e)?e.filter(e=>typeof e==`string`):[]}function itemSource(e){if(e.startsWith(`@`))return e.split(`/`)[0]??e;if(/^https?:\/\//u.test(e))try{return new URL(e).host}catch{return e}return`Vercel`}function manifestRecord(e){return typeof e==`object`&&e&&!Array.isArray(e)?e:{}}function summarizeDetails(e,t=3){let n=e.slice(0,t),r=e.length-n.length;return r>0?`${n.join(`, `)} … (+${r} more)`:n.join(`, `)}function itemDetails(e,t){let n=[{label:`Source`,value:e.source}],r=[...stringArray(t.dependencies),...stringArray(t.devDependencies),...stringArray(t.registryDependencies)];r.length>0&&n.push({label:`Packages`,value:summarizeDetails(r)});let i=t.envVars;if(typeof i==`object`&&i&&!Array.isArray(i)){let e=Object.keys(i);e.length>0&&n.push({label:`Environment`,value:summarizeDetails(e)})}let a=(Array.isArray(t.files)?t.files:[]).flatMap(e=>{if(typeof e!=`object`||!e||Array.isArray(e))return[];let t=e.target;return typeof t==`string`?[t]:[]});return a.length>0&&n.push({label:`Files`,value:summarizeDetails(a)}),n}async function inspectItem(e,n,r,i,a,o){let s=a??manifestRecord(await withSpinner(e,`Loading registry item…`,()=>n.getRegistryItemManifest(r,i.address)));for(;;){let t={message:typeof s.title==`string`?s.title:i.name,metadata:itemDetails(i,s),options:[{value:`add`,label:`Add to project`},{value:`back`,label:`Back`}]},a=typeof s.description==`string`?s.description:i.description;if(a!==void 0&&(t.description=a),await e.select(t)===`back`)return{kind:`back`};let c=e.log.spinner?.(`Installing ${itemLabel(i)} and dependencies…`);try{c?.stop();let install=()=>n.installRegistryItem(r,i.address,{silent:!0,prompter:e,signal:o});return{kind:`added`,output:await(e.withExclusiveTerminal?.(install)??install())}}finally{c?.stop()}}}async function resolveAddressItem(e,n,r,i){let a=manifestRecord(await withSpinner(e,`Loading registry item…`,()=>n.getRegistryItemManifest(r,i))),o={address:i,name:typeof a.name==`string`?a.name:i,source:itemSource(i)};return typeof a.type==`string`&&(o.type=a.type),typeof a.description==`string`&&(o.description=a.description),{item:o,manifest:a}}async function runRegistryFlow(a){let o;(a.deps?.browseRegistryCatalog===void 0||a.deps.getRegistryItemManifest===void 0||a.deps.installRegistryItem===void 0)&&(o=await import(`#cli/commands/registry.js`));let s={browseRegistryCatalog:a.deps?.browseRegistryCatalog??o.browseRegistryCatalog,getRegistryItemManifest:a.deps?.getRegistryItemManifest??o.getRegistryItemManifest,installRegistryItem:a.deps?.installRegistryItem??o.installRegistryItem},c=[];try{for(;;){a.signal?.throwIfAborted();let e=await withSpinner(a.prompter,`Loading registry…`,()=>s.browseRegistryCatalog(a.appRoot));c=[...c,...e.errors.map(e=>({tone:`warning`,text:`${e.registry}: ${e.message}`}))];let o=await a.prompter.select({message:``,options:categoryRows(),hintLayout:`inline`,notices:c});if(c=[],o===DONE)return{kind:`done`,addedItems:[]};let l=itemsForCategory(e.items,o),u=itemRows(l);u.push({value:BACK,label:`Back`,trailingAction:!0});let d=await a.prompter.select({message:`Browse registry integrations`,options:u,search:!0,placeholder:`Search or enter an item address`,searchAction:{label:e=>`Add “${e}”`,value:e=>`${ADDRESS_PREFIX}${e.trim()}`},hintLayout:`inline`});if(d===BACK)continue;let f=d.startsWith(ADDRESS_PREFIX)?await resolveAddressItem(a.prompter,s,a.appRoot,d.slice(8)):{item:l[Number(d.slice(5))]};if(f.item===void 0)throw Error(`The selected registry item is no longer available.`);let p=await inspectItem(a.prompter,s,a.appRoot,f.item,`manifest`in f?f.manifest:void 0,a.signal);if(p.kind===`added`)return p.output.length===0?{kind:`done`,addedItems:[f.item.address]}:{kind:`done`,addedItems:[f.item.address],output:p.output}}}catch(t){if(t instanceof WizardCancelledError)return{kind:`cancelled`};throw t}}export{runRegistryFlow};
|
|
@@ -4,7 +4,6 @@ export { type AiGatewayEnvFile, type ArgsHeadlessAiGateway, type ArgsHeadlessPro
|
|
|
4
4
|
export { type AnySetupBox, runHeadless, runInteractive, type RunnerOptions, type RunResult, } from "./runner.js";
|
|
5
5
|
export { createPrompter, type MultiSelectOptions, type NoteTone, type Prompter, type PrompterValue, type SelectCommonOptions, type SelectOption, type SingleSelectOptions, } from "./prompter.js";
|
|
6
6
|
export { createHeadlessPrompter, formatHeadlessEvent, type HeadlessEvent, type HeadlessLogSink, type HeadlessNextStep, HeadlessPromptError, } from "./headless.js";
|
|
7
|
-
export { composeOnboardingBoxes, type OnboardingBoxesOptions } from "./onboarding.js";
|
|
8
7
|
export { createPromptCommandOutput, type PromptCommandLog } from "./cli/index.js";
|
|
9
8
|
export { getPackageManagerStrategy, runPackageManagerInstall, runPnpmInstall, runVercel, spawnPackageManager, spawnPnpm, type PackageManagerStrategy, type RunPackageManagerOptions, type RunPnpmOptions, type RunVercelOptions, } from "./primitives/index.js";
|
|
10
9
|
export { detectDeployment, detectProjectResolution, projectProductionUrlFromResolution, type DeploymentInfo, type DeploymentState, type ProjectResolution, } from "./project-resolution.js";
|
package/dist/src/setup/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{InteractionRequired}from"./ask.js";import{runVercel}from"./primitives/run-vercel.js";import{detectDeployment,detectProjectResolution,projectProductionUrlFromResolution}from"./project-resolution.js";import{
|
|
1
|
+
import{InteractionRequired}from"./ask.js";import{runVercel}from"./primitives/run-vercel.js";import{detectDeployment,detectProjectResolution,projectProductionUrlFromResolution}from"./project-resolution.js";import{runVercelEnvPull}from"./run-vercel-link.js";import{createDefaultSetupState,requireProjectPath,snapshotSetupState}from"./state.js";import{getPackageManagerStrategy}from"./primitives/pm/index.js";import{linkProject,requireAuth,resolveProjectByNameOrId,resolveTeam}from"./vercel-project.js";import{createPromptCommandOutput}from"./cli/command-output.js";import"./cli/index.js";import{setupConnectionConnector}from"./connection-connector.js";import{WizardCancelledError}from"./step.js";import{runHeadless,runInteractive}from"./runner.js";import{HeadlessPromptError,createHeadlessPrompter,formatHeadlessEvent}from"./headless.js";import{createPrompter}from"./prompter.js";import{runPackageManagerInstall,runPnpmInstall,spawnPackageManager,spawnPnpm}from"./primitives/pm/run.js";import"./primitives/index.js";import{provisionSlackbot,reconcileSlackUid}from"./slackbot.js";export{HeadlessPromptError,InteractionRequired,WizardCancelledError,createDefaultSetupState,createHeadlessPrompter,createPromptCommandOutput,createPrompter,detectDeployment,detectProjectResolution,formatHeadlessEvent,getPackageManagerStrategy,linkProject,projectProductionUrlFromResolution,provisionSlackbot,reconcileSlackUid,requireAuth,requireProjectPath,resolveProjectByNameOrId,resolveTeam,runHeadless,runInteractive,runPackageManagerInstall,runPnpmInstall,runVercel,runVercelEnvPull,setupConnectionConnector,snapshotSetupState,spawnPackageManager,spawnPnpm};
|
package/dist/src/setup/{channel-setup-environment.d.ts → integrations/channels/environment.d.ts}
RENAMED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { ProjectResolution } from "
|
|
2
|
-
import type { VercelAuthStatus } from "
|
|
1
|
+
import type { ProjectResolution } from "../../project-resolution.js";
|
|
2
|
+
import type { VercelAuthStatus } from "../../vercel-project.js";
|
|
3
3
|
/** Read-only hosting facts available to channel-owned setup hooks. */
|
|
4
4
|
export interface ChannelSetupEnvironment {
|
|
5
5
|
vercel: {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function describeChannelSetupEnvironment(e){if(e.vercel.kind===`available`)switch(e.vercel.project.kind){case`deployed`:return`Found an authenticated Vercel account and deployed project (${e.vercel.project.productionUrl}).`;case`linked`:return`Found an authenticated Vercel account and linked project.`;case`unresolved`:return`Found an authenticated Vercel account; this directory is not linked to a project.`}switch(e.vercel.reason){case`logged-out`:return`No authenticated Vercel account found; choose Vercel Connect or portable credentials.`;case`cli-missing`:return`Vercel CLI not found; choose Vercel Connect or portable credentials.`;case`unavailable`:return`Could not verify the Vercel account; choose Vercel Connect or portable credentials.`}}function channelSetupEnvironment(e,t){return e===`authenticated`?{vercel:{kind:`available`,project:t}}:{vercel:{kind:`unavailable`,reason:e}}}export{channelSetupEnvironment,describeChannelSetupEnvironment};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { ChannelSetupIntegration } from "./
|
|
2
|
-
import type { ChannelKind } from "
|
|
1
|
+
import type { ChannelSetupIntegration } from "./types.js";
|
|
2
|
+
import type { ChannelKind } from "../../scaffold/index.js";
|
|
3
3
|
/** Built-in channel integrations in canonical picker order. */
|
|
4
4
|
export declare const CHANNEL_SETUP_INTEGRATIONS: readonly ChannelSetupIntegration[];
|
|
5
5
|
/** Resolves a channel setup integration by its filesystem-facing kind. */
|
|
6
6
|
export declare function channelSetupIntegration(kind: ChannelKind): ChannelSetupIntegration;
|
|
7
|
-
export { createChannelSetupUi } from "./
|
|
7
|
+
export { createChannelSetupUi } from "./ui.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{SLACK_CHANNEL_SETUP}from"./slack.js";import{WEB_CHANNEL_SETUP}from"./web.js";import{createChannelSetupUi}from"./ui.js";const CHANNEL_SETUP_INTEGRATIONS=[WEB_CHANNEL_SETUP,SLACK_CHANNEL_SETUP];function channelSetupIntegration(e){let t=CHANNEL_SETUP_INTEGRATIONS.find(t=>t.kind===e);if(t===void 0)throw Error(`No channel setup integration for "${e}".`);return t}export{CHANNEL_SETUP_INTEGRATIONS,channelSetupIntegration,createChannelSetupUi};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ChannelSetupContext, ChannelSetupResult } from "./
|
|
1
|
+
import type { ChannelSetupContext, ChannelSetupResult } from "./types.js";
|
|
2
2
|
/** Runs the shared scaffold box with decisions supplied by a channel integration. */
|
|
3
3
|
export declare function runChannelSetup(context: ChannelSetupContext, options: {
|
|
4
4
|
configureVercelServices?: boolean;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{runInteractive}from"../../runner.js";import{addChannels}from"./setup.js";async function runChannelSetup(t,n){let r=await runInteractive([addChannels({asker:t.ui.asker,prompter:t.ui.prompter,headless:t.headless,presetCreateSlackbot:t.presetCreateSlackbot,force:t.force,configureVercelServices:n.configureVercelServices,slackCredentials:n.slackCredentials,ensureLinkedProject:n.ensureLinkedProject,skipDependencyMutation:t.skipDependencyMutation,deps:t.deps})],t.state,{write:e=>t.ui.prompter.log.message(e)},{signal:t.signal});return r.kind===`done`?{kind:`done`,state:r.state}:{kind:`cancelled`}}export{runChannelSetup};
|
|
@@ -1,13 +1,28 @@
|
|
|
1
1
|
import { deriveSlackConnectorSlug, ensureChannel, type ChannelKind, type EvePackageContract } from "#setup/scaffold/index.js";
|
|
2
2
|
import { detectPackageManager } from "#setup/package-manager.js";
|
|
3
3
|
import { runPackageManagerInstall } from "#setup/primitives/pm/run.js";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import type { Asker } from "
|
|
7
|
-
import type { Prompter } from "
|
|
8
|
-
import { provisionSlackbot, reconcileSlackUid } from "
|
|
9
|
-
import { type
|
|
10
|
-
|
|
4
|
+
import { ensureVercelProject } from "#setup/flows/ensure-vercel-project.js";
|
|
5
|
+
import { type ProjectResolution } from "../../project-resolution.js";
|
|
6
|
+
import type { Asker } from "../../ask.js";
|
|
7
|
+
import type { Prompter } from "../../prompter.js";
|
|
8
|
+
import { provisionSlackbot, reconcileSlackUid } from "../../slackbot.js";
|
|
9
|
+
import { type SetupBox } from "../../step.js";
|
|
10
|
+
/** State required by channel setup, kept narrow so the integration can move packages. */
|
|
11
|
+
export interface AddChannelsState {
|
|
12
|
+
projectPath: string | {
|
|
13
|
+
kind: "unresolved";
|
|
14
|
+
inPlace: boolean;
|
|
15
|
+
} | {
|
|
16
|
+
kind: "resolved";
|
|
17
|
+
inPlace: boolean;
|
|
18
|
+
path: string;
|
|
19
|
+
};
|
|
20
|
+
project: ProjectResolution;
|
|
21
|
+
channelSelection: ChannelKind[];
|
|
22
|
+
channels: ChannelKind[];
|
|
23
|
+
webScaffolded: boolean;
|
|
24
|
+
slackScaffolded: boolean;
|
|
25
|
+
}
|
|
11
26
|
/** Injected for tests; defaults to the real scaffold, Connect, and Vercel effects. */
|
|
12
27
|
export interface AddChannelsDeps {
|
|
13
28
|
ensureChannel: typeof ensureChannel;
|
|
@@ -16,8 +31,7 @@ export interface AddChannelsDeps {
|
|
|
16
31
|
reconcileSlackUid: typeof reconcileSlackUid;
|
|
17
32
|
detectPackageManager: typeof detectPackageManager;
|
|
18
33
|
runPackageManagerInstall: typeof runPackageManagerInstall;
|
|
19
|
-
|
|
20
|
-
detectDeployment: typeof detectDeployment;
|
|
34
|
+
ensureVercelProject: typeof ensureVercelProject;
|
|
21
35
|
}
|
|
22
36
|
export interface AddChannelsOptions {
|
|
23
37
|
/** Resolves the slackbot question; the composed stack decides how. */
|
|
@@ -41,7 +55,7 @@ export interface AddChannelsOptions {
|
|
|
41
55
|
evePackage?: EvePackageContract;
|
|
42
56
|
/** Reuse the preferred existing Slack connector without prompting. */
|
|
43
57
|
presetCreateSlackbot?: boolean;
|
|
44
|
-
/** Overwrite existing channel files (`eve
|
|
58
|
+
/** Overwrite existing channel files (`eve add --overwrite channel/slack`). */
|
|
45
59
|
force?: boolean;
|
|
46
60
|
/** Credential source for Slack. Defaults to Vercel Connect. */
|
|
47
61
|
slackCredentials?: "vercel-connect" | "environment";
|
|
@@ -53,17 +67,15 @@ export interface AddChannelsOptions {
|
|
|
53
67
|
configureVercelServices?: boolean;
|
|
54
68
|
/**
|
|
55
69
|
* Opt-in fallback when Slack is chosen interactively but `state.project` is
|
|
56
|
-
* unresolved:
|
|
57
|
-
*
|
|
58
|
-
* resolves the project up front via the link box and keeps the hard gate.
|
|
70
|
+
* unresolved: link the project before provisioning the slackbot. The Slack
|
|
71
|
+
* integration sets this so Vercel Connect setup can link an unlinked project.
|
|
59
72
|
*/
|
|
60
73
|
ensureLinkedProject?: "interactive-vercel-link";
|
|
61
74
|
/**
|
|
62
75
|
* What a failed slackbot provision (create or attach) does to the run. The
|
|
63
|
-
* default, "abort", fails the whole box — right for `eve
|
|
64
|
-
* where Slack is the point.
|
|
65
|
-
*
|
|
66
|
-
* a later `eve channels add slack` starts clean).
|
|
76
|
+
* default, "abort", fails the whole box — right for `eve add channel/slack`,
|
|
77
|
+
* where Slack is the point. "warn-and-continue" records nothing so a later
|
|
78
|
+
* `eve add channel/slack` starts clean.
|
|
67
79
|
*/
|
|
68
80
|
slackbotFailure?: "abort" | "warn-and-continue";
|
|
69
81
|
deps?: AddChannelsDeps;
|
|
@@ -98,8 +110,7 @@ export interface AddChannelsPayload {
|
|
|
98
110
|
slackScaffolded: boolean;
|
|
99
111
|
/**
|
|
100
112
|
* Whether the post-scaffold dependency install succeeded. False both when no
|
|
101
|
-
* channels were recorded
|
|
102
|
-
* success lets `apply` mark the deploy-time install as already done.
|
|
113
|
+
* channels were recorded and when the install failed.
|
|
103
114
|
*/
|
|
104
115
|
dependenciesChanged: boolean;
|
|
105
116
|
dependenciesInstalled: boolean;
|
|
@@ -107,8 +118,7 @@ export interface AddChannelsPayload {
|
|
|
107
118
|
slackbot?: AddChannelsSlackbotFacts;
|
|
108
119
|
}
|
|
109
120
|
/**
|
|
110
|
-
*
|
|
111
|
-
* select-channels box (`state.channelSelection`): writes the Web Chat files,
|
|
121
|
+
* Channel integration setup. Scaffolds the requested channel: writes the Web Chat files,
|
|
112
122
|
* provisions the Slackbot through Vercel Connect, writes the Slack channel
|
|
113
123
|
* definition, reconciles a Connect-assigned connector UID, and installs the
|
|
114
124
|
* dependencies the scaffold added to `package.json` so a running `eve dev`
|
|
@@ -117,4 +127,4 @@ export interface AddChannelsPayload {
|
|
|
117
127
|
* and reads `state.project` directly, resolved earlier by the link box or the
|
|
118
128
|
* in-project seed.
|
|
119
129
|
*/
|
|
120
|
-
export declare function addChannels(options: AddChannelsOptions): SetupBox<
|
|
130
|
+
export declare function addChannels<State extends AddChannelsState = AddChannelsState>(options: AddChannelsOptions): SetupBox<State, AddChannelsInput, AddChannelsPayload>;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{isProjectResolved,mergeProjectResolution}from"../../project-resolution.js";import{WizardCancelledError}from"../../step.js";import{provisionSlackbot,reconcileSlackUid}from"../../slackbot.js";import{deriveSlackConnectorSlug,ensureChannel}from"#setup/scaffold/index.js";import{formatNodeEngineOverrideWarning}from"#setup/node-engine.js";import{detectPackageManager}from"#setup/package-manager.js";import{HumanActionRequiredError}from"#setup/human-action.js";import{createPromptCommandOutput,withPhase}from"#setup/cli/index.js";import{runPackageManagerInstall}from"#setup/primitives/pm/run.js";import{ensureVercelProject}from"#setup/flows/ensure-vercel-project.js";function slackbotFailureCopy(e){switch(e.state){case`not-installed`:return{reason:`Slackbot is not connected to a Slack workspace. Slack channel was not added.`,followUp:"Continuing without Slack — the install timed out and was cleaned up; re-run `eve add channel/slack` to try again."};case`cleanup-failed`:return{reason:`The abandoned Slack connector could not be removed. Slack channel was not added.`,followUp:`Continuing without Slack — resolve the cleanup warning above before trying again.`};case`connector-lookup-failed`:return{reason:`Existing Slack connectors could not be inspected. Slack channel was not added.`,followUp:"Continuing without Slack — restore Vercel CLI access, then re-run `eve add channel/slack`."};case`installation-check-failed`:return{reason:`Slack workspace installation could not be verified. Slack channel was not added.`,followUp:"Continuing without Slack — verify Vercel Connect is reachable, then re-run `eve add channel/slack`."};case`existing-not-installed`:return{reason:`The existing Slack connector is not connected to a Slack workspace. Slack channel was not added.`,followUp:`Continuing without Slack — resolve the existing connector warning above before trying again.`};case`detach-failed`:return{reason:`Slackbot provisioning could not replace the existing trigger destination. Slack channel was not added.`,followUp:"Continuing without Slack — run the `vercel connect detach` and `vercel connect attach` commands above."};case`attach-failed`:return{reason:`Slackbot provisioning did not attach this project. Slack channel was not added.`,followUp:"Continuing without Slack — finish event delivery with the `vercel connect attach` command above."};case`create-failed`:return{reason:`Slackbot creation failed.`,followUp:"Continuing without Slack — add it later with `eve add channel/slack`."}}}function warnOverwrittenFiles(e,t){for(let n of t??[])e.warning(`Overwrote ${n}`)}function warnCompetingNextConfigFiles(e,t){for(let n of t??[])e.warning(`Found competing Next.js config at ${n}; merge any needed settings into next.config.ts and remove it before starting the preview, or Next.js may ignore the generated eve rewrite.`)}function addChannels(f){let p=f.deps??{ensureChannel,deriveSlackConnectorSlug,provisionSlackbot,reconcileSlackUid,detectPackageManager,runPackageManagerInstall,ensureVercelProject};async function scaffoldSlackChannel(e,t,n,r,i,a){let o=!1;if(!t.slackScaffolded){let t=await p.ensureChannel({projectRoot:n,kind:`slack`,slackConnectorUid:a,slackConnectorSlug:r,force:f.force,skipDependencyMutation:f.skipDependencyMutation});i.dependenciesChanged||=t.packageJsonUpdated.length>0,warnOverwrittenFiles(e,t.filesOverwritten),t.action===`created`||t.action===`overwritten`?e.success(`Scaffolded channel: slack`):e.info(`Channel "slack" already exists. Skipping file creation.`),o=t.action!==`skipped`,i.slackScaffolded=!0}return i.channelsAdded.push(`slack`),o}async function addWebChannelToPayload(t,n,r,i,a,o){if(!n.channelSelection.includes(`web`))return;if(n.webScaffolded){a.channelsAdded.push(`web`);return}t.message(`Scaffolding Web Chat channel files...`);let c={projectRoot:r,kind:`web`,packageManager:i,force:f.force,configureVercelServices:f.configureVercelServices??isProjectResolved(n.project),skipDependencyMutation:f.skipDependencyMutation};f.evePackage!==void 0&&(c.webPackageVersions={evePackage:f.evePackage});let l=await p.ensureChannel(c);if(a.dependenciesChanged||=l.packageJsonUpdated.length>0,o?.throwIfAborted(),warnOverwrittenFiles(t,l.filesOverwritten),l.kind===`web`&&l.action!==`skipped`&&l.nodeEngineOverride!==void 0&&t.warning(formatNodeEngineOverrideWarning(l.nodeEngineOverride)),warnCompetingNextConfigFiles(t,`competingNextConfigFiles`in l?l.competingNextConfigFiles:void 0),l.action===`created`||l.action===`overwritten`){t.success(`Scaffolded channel: web`),a.webScaffolded=!0,a.channelsAdded.push(`web`);return}t.info(`Next.js project detected. Skipping Web Chat scaffolding.`)}function assertSlackProjectReady(t){if(f.ensureLinkedProject===void 0){if(!isProjectResolved(t.project))throw Error(`Slack setup with Vercel Connect requires a linked Vercel project.`);if(!isProjectResolved(t.project))throw Error(`Expected a linked Vercel project for Slack, but none was resolved.`)}}async function provisionSlackbotWithControls(e,t,n,r){let i={selectConnector:async(e,t)=>{if(f.presetCreateSlackbot===!0)return t??e[0];let n={message:`Which Slack app would you like to use?`,options:[...e.map(e=>{let n={value:e.uid,label:`Use ${e.uid}`};return e.uid===t?.uid&&(n.hint=`Matches this agent`),n}),{value:`create`,label:`Create a new Slack app`}],initialValue:t?.uid},r=await f.prompter.select(n);return r===`create`?`create`:e.find(e=>e.uid===r)}};return r!==void 0&&(i.signal=r),f.prompter.awaitChoice!==void 0&&(i.awaitChoice=f.prompter.awaitChoice),p.provisionSlackbot(e,t,n,void 0,i)}async function scaffoldAttachedSlackChannel(e,t,n,r,i,a){if(!await scaffoldSlackChannel(e,t,n,r,i,a.connectorUid)&&!await p.reconcileSlackUid(e,n,a,`slack/${r}`))throw Error(`Slack connector UID update is required before deployment.`)}async function addSlackChannelToPayload(r,i,a,o,s,c){if(!i.channelSelection.includes(`slack`))return;let u=await p.deriveSlackConnectorSlug(o);if(f.slackCredentials===`environment`){if(!i.slackScaffolded){let e=await p.ensureChannel({projectRoot:o,kind:`slack`,slackConnectorSlug:u,slackCredentials:`environment`,force:f.force,skipDependencyMutation:f.skipDependencyMutation});s.dependenciesChanged||=e.packageJsonUpdated.length>0,warnOverwrittenFiles(r,e.filesOverwritten),e.action===`created`||e.action===`overwritten`?r.success(`Scaffolded channel: slack`):r.info(`Channel "slack" already exists. Skipping file creation.`),s.slackScaffolded=!0}s.channelsAdded.push(`slack`);return}if(assertSlackProjectReady(i),!isProjectResolved(s.project)){if(a.headless)throw new HumanActionRequiredError({kind:`vercel-link`,command:`vercel link`,reason:`Slackbot creation needs this directory linked to a Vercel project.`});let e=await p.ensureVercelProject({appRoot:o,prompter:f.prompter,signal:c});s.project=mergeProjectResolution(s.project,{kind:`linked`,projectId:e.projectId})}let d=await provisionSlackbotWithControls(r,o,u,c);if(c?.throwIfAborted(),d.state===`cancelled`)throw new WizardCancelledError;if(d.state!==`attached`){let e=slackbotFailureCopy(d);if(f.slackbotFailure!==`warn-and-continue`)throw Error(e.reason);r.warning(`${e.reason} ${e.followUp}`);return}s.slackbot={connectorUid:d.connectorUid,chatUrl:d.chatUrl,workspaceName:d.workspaceName},await scaffoldAttachedSlackChannel(r,i,o,u,s,d)}async function installChannelDependencies(e,t,n,r,i){if(!(f.skipDependencyMutation||!r.dependenciesChanged)){if(await withPhase(e,`Installing channel dependencies (${n} install)...`,()=>p.runPackageManagerInstall(n,t,{onOutput:createPromptCommandOutput(e),signal:i}))){r.dependenciesInstalled=!0;return}e.warning(`Dependency installation failed. The new channels stay unloadable until \`${n} install\` or a deploy succeeds.`)}}async function performAddChannels(e,t,n){n?.throwIfAborted();let r=f.prompter.log,i=typeof e.projectPath==`string`?e.projectPath:e.projectPath.kind===`resolved`?e.projectPath.path:void 0;if(i===void 0)throw Error(`Project path has not been resolved.`);let a={channelsAdded:[],webScaffolded:e.webScaffolded,slackScaffolded:e.slackScaffolded,dependenciesChanged:!1,dependenciesInstalled:!1,project:e.project},o=await p.detectPackageManager(i);return await addWebChannelToPayload(r,e,i,o.kind,a,n),await addSlackChannelToPayload(r,e,t,i,a,n),await installChannelDependencies(r,i,o.kind,a,n),a}return{id:`add-channels`,async gather({state:e}){let t=f.headless??!1;if(t&&e.channelSelection.includes(`slack`)&&f.slackCredentials!==`environment`)throw Error("Slack setup is interactive. Run `eve add channel/slack` from an interactive terminal.");return{headless:t,createSlackbot:f.presetCreateSlackbot}},async perform({state:e,input:t,signal:r}){try{return await performAddChannels(e,t,r)}catch(e){if(!(e instanceof WizardCancelledError)){let t=e instanceof Error?e.message:String(e),n=t.split(`
|
|
2
|
+
`)[0]?.trim()??t;f.prompter.log.error(n)}throw e}},apply(e,n){let r=[...e.channels];for(let e of n.channelsAdded)r.includes(e)||r.push(e);let i={...e,channels:r,webScaffolded:n.webScaffolded,slackScaffolded:n.slackScaffolded,project:mergeProjectResolution(e.project,n.project)};return n.slackbot,i}}}export{addChannels};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import type { ChannelSetupIntegration } from "./
|
|
1
|
+
import type { ChannelSetupIntegration } from "./types.js";
|
|
2
2
|
/** Slack's channel-owned credential choice, provisioning, and scaffold behavior. */
|
|
3
3
|
export declare const SLACK_CHANNEL_SETUP: ChannelSetupIntegration;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{WizardCancelledError}from"../../step.js";import{runChannelSetup}from"./runner.js";async function choosePortableCredentials(t){if(t.presetPortableCredentials!==void 0)return t.presetPortableCredentials?`environment`:`vercel-connect`;try{return await t.ui.prompter.select({message:`How would you like to configure Slack?`,options:[{value:`vercel`,label:`Set up Vercel Connect`,hint:`Sign in and link this project`},{value:`portable`,label:`Use portable credentials`,hint:`Read Slack tokens from environment variables`}]})===`portable`?`environment`:`vercel-connect`}catch(t){if(t instanceof WizardCancelledError)return`cancelled`;throw t}}const SLACK_CHANNEL_SETUP={kind:`slack`,label:`Slack`,hint:`Slack app mentions and DMs`,async setup(e){let n=await choosePortableCredentials(e);if(n===`cancelled`)return{kind:`cancelled`};if(n===`vercel-connect`&&e.environment.vercel.kind===`unavailable`)throw Error("Vercel Connect requires an authenticated Vercel CLI. Run `vercel login`, then retry Slack setup.");let r=await runChannelSetup(e,n===`environment`?{slackCredentials:`environment`}:{slackCredentials:`vercel-connect`,ensureLinkedProject:`interactive-vercel-link`});return r.kind===`done`&&n===`environment`&&r.state.channels.includes(`slack`)&&e.ui.nextSteps([`Set SLACK_BOT_TOKEN and SLACK_SIGNING_SECRET in .env.local (listed in .env.example).`,`Configure your Slack app to send events to /eve/v1/slack on your public agent URL.`]),r}};export{SLACK_CHANNEL_SETUP};
|
|
@@ -1,12 +1,28 @@
|
|
|
1
|
-
import type { AddChannelsDeps } from "./
|
|
2
|
-
import type { ChannelSetupEnvironment } from "./
|
|
3
|
-
import type { ChannelSetupUi } from "./
|
|
4
|
-
import type { ChannelKind } from "
|
|
5
|
-
import type {
|
|
1
|
+
import type { AddChannelsDeps } from "./setup.js";
|
|
2
|
+
import type { ChannelSetupEnvironment } from "./environment.js";
|
|
3
|
+
import type { ChannelSetupUi } from "./ui.js";
|
|
4
|
+
import type { ChannelKind } from "../../scaffold/index.js";
|
|
5
|
+
import type { ProjectResolution } from "../../project-resolution.js";
|
|
6
|
+
/** Narrow state owned by one channel setup invocation. */
|
|
7
|
+
export interface ChannelSetupState {
|
|
8
|
+
readonly projectPath: string | {
|
|
9
|
+
kind: "unresolved";
|
|
10
|
+
inPlace: boolean;
|
|
11
|
+
} | {
|
|
12
|
+
kind: "resolved";
|
|
13
|
+
inPlace: boolean;
|
|
14
|
+
path: string;
|
|
15
|
+
};
|
|
16
|
+
readonly project: ProjectResolution;
|
|
17
|
+
readonly channelSelection: ChannelKind[];
|
|
18
|
+
readonly channels: ChannelKind[];
|
|
19
|
+
readonly webScaffolded: boolean;
|
|
20
|
+
readonly slackScaffolded: boolean;
|
|
21
|
+
}
|
|
6
22
|
/** Shared inputs available to a channel-owned setup implementation. */
|
|
7
23
|
export interface ChannelSetupContext {
|
|
8
24
|
readonly environment: ChannelSetupEnvironment;
|
|
9
|
-
readonly state: Readonly<
|
|
25
|
+
readonly state: Readonly<ChannelSetupState>;
|
|
10
26
|
readonly ui: ChannelSetupUi;
|
|
11
27
|
readonly signal?: AbortSignal;
|
|
12
28
|
readonly force?: boolean;
|
|
@@ -20,7 +36,7 @@ export interface ChannelSetupContext {
|
|
|
20
36
|
/** Structured outcome from a channel-owned setup implementation. */
|
|
21
37
|
export type ChannelSetupResult = {
|
|
22
38
|
readonly kind: "done";
|
|
23
|
-
readonly state:
|
|
39
|
+
readonly state: ChannelSetupState;
|
|
24
40
|
} | {
|
|
25
41
|
readonly kind: "cancelled";
|
|
26
42
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { type Asker } from "
|
|
2
|
-
import type { Prompter } from "
|
|
1
|
+
import { type Asker } from "../../ask.js";
|
|
2
|
+
import type { Prompter } from "../../prompter.js";
|
|
3
3
|
/** UI capabilities available to a channel-owned setup hook. */
|
|
4
4
|
export interface ChannelSetupUi {
|
|
5
5
|
readonly asker: Asker;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{SkippedSignal,confirm}from"../../ask.js";function createChannelSetupUi(n){return{...n,async confirm(r){try{return await n.asker.ask(confirm(r))}catch(t){if(t instanceof SkippedSignal)return!1;throw t}},nextSteps(e){e.length!==0&&n.prompter.note(e.join(`
|
|
2
|
+
`),`Next steps`,{tone:`success`})}}}export{createChannelSetupUi};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{runChannelSetup}from"./runner.js";const WEB_CHANNEL_SETUP={kind:`web`,label:`Web Chat`,hint:`Browser-based chat interface`,setup(e){return runChannelSetup(e,{configureVercelServices:e.environment.vercel.kind===`available`})}};export{WEB_CHANNEL_SETUP};
|
|
@@ -35,6 +35,7 @@ export declare function runVercel(args: string[], options: RunVercelOptions): Pr
|
|
|
35
35
|
export interface RunVercelCaptureResult {
|
|
36
36
|
ok: boolean;
|
|
37
37
|
stdout: string;
|
|
38
|
+
stderr?: string;
|
|
38
39
|
}
|
|
39
40
|
/**
|
|
40
41
|
* Runs an interactive Vercel CLI command while capturing its stdout.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{withoutCodingAgentMarkers}from"./coding-agent-env.js";import{createProcessOutputBuffer}from"./process-output.js";import{armProcessAbort}from"./process-abort.js";import{accessSync,constants,existsSync,statSync}from"node:fs";import{dirname,join,resolve}from"node:path";import{spawn}from"node:child_process";const CONNECT_FEATURE_FLAG_ENV={FF_CONNECT_ENABLED:`1`},VERCEL_NOT_FOUND_MESSAGE=`Vercel CLI not found. Install with: npm i -g vercel@latest`;function buildSpawnEnv(t){return{...withoutCodingAgentMarkers(process.env),...CONNECT_FEATURE_FLAG_ENV,...t}}function commandArgs(e,t){return!t||e.includes(`--non-interactive`)?e:[...e,`--non-interactive`]}function existingDir(e){let t=resolve(e);for(;!existsSync(t);){let e=dirname(t);if(e===t)break;t=e}return t}function armDeadline(e,t,n){if(t===void 0)return()=>{};let r=setTimeout(()=>{n(),e.kill(`SIGTERM`);let t=setTimeout(()=>e.kill(`SIGKILL`),5e3);t.unref(),e.once(`close`,()=>clearTimeout(t))},t);return r.unref(),()=>clearTimeout(r)}function timeoutMessage(e,t){return`vercel ${e.join(` `)} timed out after ${Math.round(t/1e3)}s and was aborted.`}function abortMessage(e){return`vercel ${e.join(` `)} was aborted.`}function isAbortError(e,t){return t?.aborted===!0||e.name===`AbortError`||e.code===`ABORT_ERR`}function ancestorDirectories(e){let t=[],n=resolve(e);for(;;){t.push(n);let e=dirname(n);if(e===n)return t;n=e}}function findExecutable(e){try{if(accessSync(e,constants.F_OK|constants.X_OK),statSync(e).isFile())return e}catch{return}}function vercelExecutableNames(e){return e===`win32`?[`vercel.cmd`,`vercel.exe`]:[`vercel`]}function findLocalVercel(e,t){for(let n of ancestorDirectories(e))for(let e of vercelExecutableNames(t)){let t=findExecutable(join(n,`node_modules`,`.bin`,e));if(t!==void 0)return t}}function resolveVercelInvocation(e,t=[],n=process.platform){let r=findLocalVercel(e,n);return n===`win32`?{command:r??`vercel`,commandArgs:t,shell:!0}:r===void 0?{command:`vercel`,commandArgs:t}:{command:r,commandArgs:t}}function stdioForRun(e){return e.onOutput?[e.nonInteractive?`ignore`:`inherit`,`pipe`,`pipe`]:e.nonInteractive?[`ignore`,`pipe`,`pipe`]:`inherit`}async function runVercel(e,r){return r.signal?.aborted!==!0&&new Promise(i=>{let a=existingDir(r.cwd),o=resolveVercelInvocation(a,commandArgs(e,r.nonInteractive)),s=r.onOutput&&createProcessOutputBuffer(r.onOutput),c=spawn(o.command,o.commandArgs,{cwd:a,stdio:stdioForRun(r),env:buildSpawnEnv(r.extraEnv??{}),shell:o.shell,signal:r.signal}),l=armProcessAbort(c,r.signal);c.stdout?.on(`data`,e=>s?.write(`stdout`,e)),c.stderr?.on(`data`,e=>s?.write(`stderr`,e));let u=!1;function settle(e){u||(u=!0,s?.flush(),i(e))}function reportFailure(e){r.onOutput?r.onOutput({stream:`stderr`,text:e}):process.stderr.write(`\n${e}\n`)}let d=armDeadline(c,r.timeoutMs,()=>{reportFailure(timeoutMessage(e,r.timeoutMs??0)),settle(!1)});c.on(`error`,t=>{isAbortError(t,r.signal)||(t.code===`ENOENT`?(l(),d(),reportFailure(VERCEL_NOT_FOUND_MESSAGE),settle(!1)):(l(),d(),reportFailure(`vercel ${e.join(` `)} failed: ${t.message}`),settle(!1)))}),c.on(`close`,t=>{if(l(),d(),r.signal?.aborted===!0){settle(!1);return}!u&&t!==0&&t!==null&&(s?.flush(),reportFailure(`vercel ${e.join(` `)} exited with code ${t}.`)),settle(t===0)})})}async function runVercelCaptureStdout(e,r){return r.signal?.aborted===!0?{ok:!1,stdout:``}:new Promise(i=>{let a=existingDir(r.cwd),o=resolveVercelInvocation(a,commandArgs(e,r.nonInteractive)),s=r.onOutput&&createProcessOutputBuffer(r.onOutput),c=spawn(o.command,o.commandArgs,{cwd:a,stdio:[r.nonInteractive?`ignore`:`inherit`,`pipe`,r.onOutput?`pipe`:`inherit`],env:buildSpawnEnv(r.extraEnv??{}),shell:o.shell,signal:r.signal}),l=armProcessAbort(c,r.signal),u=[];c.stdout?.on(`data`,e=>u.push(e.toString(`utf8`))),c.stderr?.on(`data`,e=>s?.write(`stderr`,e));let
|
|
1
|
+
import{withoutCodingAgentMarkers}from"./coding-agent-env.js";import{createProcessOutputBuffer}from"./process-output.js";import{armProcessAbort}from"./process-abort.js";import{accessSync,constants,existsSync,statSync}from"node:fs";import{dirname,join,resolve}from"node:path";import{spawn}from"node:child_process";const CONNECT_FEATURE_FLAG_ENV={FF_CONNECT_ENABLED:`1`},VERCEL_NOT_FOUND_MESSAGE=`Vercel CLI not found. Install with: npm i -g vercel@latest`;function buildSpawnEnv(t){return{...withoutCodingAgentMarkers(process.env),...CONNECT_FEATURE_FLAG_ENV,...t}}function commandArgs(e,t){return!t||e.includes(`--non-interactive`)?e:[...e,`--non-interactive`]}function existingDir(e){let t=resolve(e);for(;!existsSync(t);){let e=dirname(t);if(e===t)break;t=e}return t}function armDeadline(e,t,n){if(t===void 0)return()=>{};let r=setTimeout(()=>{n(),e.kill(`SIGTERM`);let t=setTimeout(()=>e.kill(`SIGKILL`),5e3);t.unref(),e.once(`close`,()=>clearTimeout(t))},t);return r.unref(),()=>clearTimeout(r)}function timeoutMessage(e,t){return`vercel ${e.join(` `)} timed out after ${Math.round(t/1e3)}s and was aborted.`}function abortMessage(e){return`vercel ${e.join(` `)} was aborted.`}function isAbortError(e,t){return t?.aborted===!0||e.name===`AbortError`||e.code===`ABORT_ERR`}function ancestorDirectories(e){let t=[],n=resolve(e);for(;;){t.push(n);let e=dirname(n);if(e===n)return t;n=e}}function findExecutable(e){try{if(accessSync(e,constants.F_OK|constants.X_OK),statSync(e).isFile())return e}catch{return}}function vercelExecutableNames(e){return e===`win32`?[`vercel.cmd`,`vercel.exe`]:[`vercel`]}function findLocalVercel(e,t){for(let n of ancestorDirectories(e))for(let e of vercelExecutableNames(t)){let t=findExecutable(join(n,`node_modules`,`.bin`,e));if(t!==void 0)return t}}function resolveVercelInvocation(e,t=[],n=process.platform){let r=findLocalVercel(e,n);return n===`win32`?{command:r??`vercel`,commandArgs:t,shell:!0}:r===void 0?{command:`vercel`,commandArgs:t}:{command:r,commandArgs:t}}function stdioForRun(e){return e.onOutput?[e.nonInteractive?`ignore`:`inherit`,`pipe`,`pipe`]:e.nonInteractive?[`ignore`,`pipe`,`pipe`]:`inherit`}async function runVercel(e,r){return r.signal?.aborted!==!0&&new Promise(i=>{let a=existingDir(r.cwd),o=resolveVercelInvocation(a,commandArgs(e,r.nonInteractive)),s=r.onOutput&&createProcessOutputBuffer(r.onOutput),c=spawn(o.command,o.commandArgs,{cwd:a,stdio:stdioForRun(r),env:buildSpawnEnv(r.extraEnv??{}),shell:o.shell,signal:r.signal}),l=armProcessAbort(c,r.signal);c.stdout?.on(`data`,e=>s?.write(`stdout`,e)),c.stderr?.on(`data`,e=>s?.write(`stderr`,e));let u=!1;function settle(e){u||(u=!0,s?.flush(),i(e))}function reportFailure(e){r.onOutput?r.onOutput({stream:`stderr`,text:e}):process.stderr.write(`\n${e}\n`)}let d=armDeadline(c,r.timeoutMs,()=>{reportFailure(timeoutMessage(e,r.timeoutMs??0)),settle(!1)});c.on(`error`,t=>{isAbortError(t,r.signal)||(t.code===`ENOENT`?(l(),d(),reportFailure(VERCEL_NOT_FOUND_MESSAGE),settle(!1)):(l(),d(),reportFailure(`vercel ${e.join(` `)} failed: ${t.message}`),settle(!1)))}),c.on(`close`,t=>{if(l(),d(),r.signal?.aborted===!0){settle(!1);return}!u&&t!==0&&t!==null&&(s?.flush(),reportFailure(`vercel ${e.join(` `)} exited with code ${t}.`)),settle(t===0)})})}async function runVercelCaptureStdout(e,r){return r.signal?.aborted===!0?{ok:!1,stdout:``,stderr:``}:new Promise(i=>{let a=existingDir(r.cwd),o=resolveVercelInvocation(a,commandArgs(e,r.nonInteractive)),s=r.onOutput&&createProcessOutputBuffer(r.onOutput),c=spawn(o.command,o.commandArgs,{cwd:a,stdio:[r.nonInteractive?`ignore`:`inherit`,`pipe`,r.onOutput?`pipe`:`inherit`],env:buildSpawnEnv(r.extraEnv??{}),shell:o.shell,signal:r.signal}),l=armProcessAbort(c,r.signal),u=[],d=[];c.stdout?.on(`data`,e=>u.push(e.toString(`utf8`))),c.stderr?.on(`data`,e=>{d.push(e.toString(`utf8`)),s?.write(`stderr`,e)});let f=!1;function settle(e){if(f)return;f=!0,s?.flush();let t=u.join(``),n=d.join(``);i(n.length===0?{ok:e,stdout:t}:{ok:e,stdout:t,stderr:n})}function reportFailure(e){r.onOutput?r.onOutput({stream:`stderr`,text:e}):process.stderr.write(`\n${e}\n`)}let p=armDeadline(c,r.timeoutMs,()=>{reportFailure(timeoutMessage(e,r.timeoutMs??0)),settle(!1)});c.on(`error`,t=>{isAbortError(t,r.signal)||(l(),p(),reportFailure(t.code===`ENOENT`?VERCEL_NOT_FOUND_MESSAGE:`vercel ${e.join(` `)} failed: ${t.message}`),settle(!1))}),c.on(`close`,t=>{if(l(),p(),r.signal?.aborted===!0){settle(!1);return}!f&&t!==0&&t!==null&&reportFailure(`vercel ${e.join(` `)} exited with code ${t}.`),settle(t===0)})})}async function captureVercel(e,r){return r.signal?.aborted===!0?{ok:!1,failure:{errno:`ABORT_ERR`,stdout:``,stderr:``,message:abortMessage(e)}}:new Promise(i=>{let a=existingDir(r.cwd),o=resolveVercelInvocation(a,commandArgs(e,r.nonInteractive)),s=r.onOutput&&createProcessOutputBuffer(r.onOutput),c=spawn(o.command,o.commandArgs,{cwd:a,stdio:[`ignore`,`pipe`,`pipe`],env:buildSpawnEnv(r.extraEnv??{}),shell:o.shell,signal:r.signal}),l=armProcessAbort(c,r.signal),u=[],d=[];c.stdout?.on(`data`,e=>u.push(e.toString(`utf8`))),c.stderr?.on(`data`,e=>{d.push(e.toString(`utf8`)),s?.write(`stderr`,e)});let f=!1;function fail(e,t=!0){f||(f=!0,s?.flush(),t&&r.onOutput?.({stream:`stderr`,text:e.message}),i({ok:!1,failure:e}))}function succeed(){f||(f=!0,s?.flush(),i({ok:!0,stdout:u.join(``)}))}let p=armDeadline(c,r.timeoutMs,()=>{fail({code:null,stdout:u.join(``),stderr:d.join(``),message:timeoutMessage(e,r.timeoutMs??0)})});c.on(`error`,t=>{isAbortError(t,r.signal)||(l(),p(),fail({errno:t.code,stdout:u.join(``),stderr:d.join(``),message:t.code===`ENOENT`?VERCEL_NOT_FOUND_MESSAGE:`vercel ${e.join(` `)} failed: ${t.message}`}))}),c.on(`close`,t=>{if(l(),p(),r.signal?.aborted===!0){fail({errno:`ABORT_ERR`,stdout:u.join(``),stderr:d.join(``),message:abortMessage(e)},!1);return}if(t!==0&&t!==null){fail({code:t,stdout:u.join(``),stderr:d.join(``),message:`vercel ${e.join(` `)} exited with code ${t}.`});return}succeed()})})}export{captureVercel,resolveVercelInvocation,runVercel,runVercelCaptureStdout};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type ChannelSetupAwaitChoice } from "#setup/cli/index.js";
|
|
1
|
+
import { type ChannelSetupAwaitChoice, type SetupSpinnerIntent } from "#setup/cli/index.js";
|
|
2
2
|
import { type RailSpinner } from "#setup/cli/index.js";
|
|
3
3
|
/**
|
|
4
4
|
* Clack constrains option values to readonly primitives. Our scaffold flow
|
|
@@ -63,9 +63,18 @@ export interface SelectNotice {
|
|
|
63
63
|
tone: "success" | "info" | "warning" | "error";
|
|
64
64
|
text: string;
|
|
65
65
|
}
|
|
66
|
+
/** One labeled fact rendered between a select question's description and options. */
|
|
67
|
+
export interface SelectMetadata {
|
|
68
|
+
label: string;
|
|
69
|
+
value: string;
|
|
70
|
+
}
|
|
66
71
|
/** Options common to every {@link Prompter.select} call. */
|
|
67
72
|
export interface SelectCommonOptions<T extends PrompterValue> {
|
|
68
73
|
message: string;
|
|
74
|
+
/** Inert context rendered beneath the question heading and above its options. */
|
|
75
|
+
description?: string;
|
|
76
|
+
/** Labeled facts rendered beneath the description and above the options. */
|
|
77
|
+
metadata?: readonly SelectMetadata[];
|
|
69
78
|
options: SelectOption<T>[];
|
|
70
79
|
/**
|
|
71
80
|
* Add a type-ahead filter line. The filter is a case-insensitive substring
|
|
@@ -86,7 +95,7 @@ export interface SelectCommonOptions<T extends PrompterValue> {
|
|
|
86
95
|
* each hint on its own line below the label with a blank line between options —
|
|
87
96
|
* for small action menus whose hints carry current values. "inline" keeps hints
|
|
88
97
|
* on the label row, suppresses numeric shortcuts, and separates the trailing
|
|
89
|
-
* completion action (e.g. the `/
|
|
98
|
+
* completion action (e.g. the `/add` task list).
|
|
90
99
|
*/
|
|
91
100
|
hintLayout?: "stacked" | "inline";
|
|
92
101
|
/** Outcome lines from earlier laps of a looping menu. */
|
|
@@ -202,6 +211,10 @@ export interface Prompter {
|
|
|
202
211
|
intro(title: string, subtitle?: string): void;
|
|
203
212
|
/** Prints a final green ● end-cap with the message. */
|
|
204
213
|
outro(message: string): void;
|
|
214
|
+
/** Temporarily hands terminal ownership to a command that inherits stdio. */
|
|
215
|
+
withInheritedStdio?<T>(task: () => Promise<T>): Promise<T>;
|
|
216
|
+
/** Gives a setup subprocess exclusive terminal and development-host ownership. */
|
|
217
|
+
withExclusiveTerminal?<T>(task: () => Promise<T>): Promise<T>;
|
|
205
218
|
log: {
|
|
206
219
|
message(text: string): void;
|
|
207
220
|
info(text: string): void;
|
|
@@ -215,7 +228,7 @@ export interface Prompter {
|
|
|
215
228
|
* returning a handle whose `stop()` clears it. Present on the real prompter;
|
|
216
229
|
* optional so lightweight test fakes can omit it.
|
|
217
230
|
*/
|
|
218
|
-
spinner?(message: string): RailSpinner;
|
|
231
|
+
spinner?(message: string, intent?: SetupSpinnerIntent): RailSpinner;
|
|
219
232
|
};
|
|
220
233
|
}
|
|
221
234
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{__toESM}from"../_virtual/_rolldown/runtime.js";import{require_picocolors}from"../node_modules/.pnpm/picocolors@1.1.1/node_modules/picocolors/picocolors.js";import{
|
|
1
|
+
import{__toESM}from"../_virtual/_rolldown/runtime.js";import{require_picocolors}from"../node_modules/.pnpm/picocolors@1.1.1/node_modules/picocolors/picocolors.js";import{TextPrompt as ht,isCancel as q,settings as h}from"../node_modules/.pnpm/@clack_core@1.3.1/node_modules/@clack/core/dist/index.js";import{WizardCancelledError}from"./step.js";import{initialQuitGuardState,quitHintNote,reduceQuitGuard}from"./quit-guard.js";import{cornerFor,createRailLog,formatPromptCancellation,formatPromptHeader,formatPromptOpener,formatPromptOutro,formatPromptSubmission,formatRailLine,railFor,runSelectComponent}from"#setup/cli/index.js";var import_picocolors=__toESM(require_picocolors(),1);function guardCancel(e){if(q(e))throw process.stdout.write(formatPromptCancellation(`Setup cancelled.`,import_picocolors.default)),new WizardCancelledError;return e}let escapeCancelDisabled=!1;function disableEscapeCancel(){escapeCancelDisabled||=(h.aliases.delete(`escape`),!0)}function attachQuitGuard(e){let t=initialQuitGuardState;return e.on(`key`,(n,r)=>{let{state:i,action:a}=reduceQuitGuard(t,r?.name===`escape`?{type:`escape`}:{type:`other-key`});t=i,a===`quit`&&(e.state=`cancel`)}),{note:()=>quitHintNote(t,import_picocolors.default)}}function toPromptState(e){return e}function railForState(e){return railFor(toPromptState(e),import_picocolors.default)}function cornerForState(e){return cornerFor(toPromptState(e),import_picocolors.default)}function header(e,t,n){return formatPromptHeader(toPromptState(e),t,{colors:import_picocolors.default,leadingRail:n===0?`white`:`green`})}const REDACTED_DISPLAY=`••••••••`;function textPrompt(e,t){let r,i=new ht({validate:t.validate?e=>t.validate?.(e??``):void 0,placeholder:t.placeholder,defaultValue:t.defaultValue,render(){let n=header(this.state,t.message,e),i=t.placeholder?import_picocolors.default.inverse(t.placeholder[0])+import_picocolors.default.dim(t.placeholder.slice(1)):import_picocolors.default.inverse(import_picocolors.default.hidden(`_`)),a=this.value?`•`.repeat(this.value.length):i,o=i;switch(t.mask?o=a:this.value&&(o=this.userInputWithCursor),this.state){case`error`:return`${n.trim()}\n${railForState(this.state)} ${o}\n${cornerForState(this.state)} ${import_picocolors.default.red(this.error)}\n`;case`submit`:{let n=this.value||t.placeholder||``;return t.mask&&(n=this.value?REDACTED_DISPLAY:t.placeholder??``),formatPromptSubmission(this.state,t.message,n,{colors:import_picocolors.default,leadingRail:e===0?`white`:`green`})}case`cancel`:return`${n}${railForState(this.state)} ${import_picocolors.default.strikethrough(import_picocolors.default.dim(t.mask&&this.value?REDACTED_DISPLAY:this.value??``))}${this.value?.trim()?`\n${railForState(this.state)}`:``}`;default:return`${n}${railForState(this.state)} ${o}\n${cornerForState(this.state)}${cornerNote(r?.note())}\n`}}});return r=attachQuitGuard(i),i.prompt()}function cornerNote(e){return e?` ${e}`:``}function createPrompter(){disableEscapeCancel();let e=0,t=createRailLog({colors:import_picocolors.default,output:process.stdout});function printNotices(e){for(let n of e??[])n.tone===`success`?t.success(n.text):n.tone===`warning`?t.warning(n.text):n.tone===`error`?t.error(n.text):t.message(n.text)}return{async text(n){t.settle(),printNotices(n.notices);let r=guardCancel(await textPrompt(e,n));return e+=1,r??``},async password(n){t.settle();let r=guardCancel(await textPrompt(e,{message:n.message,mask:!0,validate:n.validate}));return e+=1,r??``},async select(n){t.settle(),printNotices(n.notices),n.description!==void 0&&process.stdout.write(formatRailLine(import_picocolors.default.dim(n.description),import_picocolors.default,process.stdout));for(let{label:e,value:t}of n.metadata??[])process.stdout.write(formatRailLine(`${import_picocolors.default.dim(`${e}:`)} ${t}`,import_picocolors.default,process.stdout));let r=guardCancel(await runSelectComponent({message:n.message,options:n.options,multiple:n.multiple===!0,search:n.search??!1,searchAction:n.multiple===!0?void 0:n.searchAction,required:n.required??!1,placeholder:n.placeholder,defaultValue:n.multiple===!0?void 0:n.initialValue,initialValues:n.multiple===!0?n.initialValues:void 0,leadingRail:e===0?`white`:`green`,attachGuard:e=>attachQuitGuard(e)}));return e+=1,r},async acknowledge(e){t.settle(),process.stdout.write(formatRailLine(import_picocolors.default.bold(e.message),import_picocolors.default,process.stdout));for(let t of e.lines??[])process.stdout.write(formatRailLine(import_picocolors.default.dim(t),import_picocolors.default,process.stdout))},note(e,n,r){t.settle();let i=r?.tone===`success`?import_picocolors.default.green:import_picocolors.default.red;n&&process.stdout.write(formatRailLine(i(import_picocolors.default.bold(n)),import_picocolors.default,process.stdout)),process.stdout.write(formatRailLine(i(e),import_picocolors.default,process.stdout))},intro(e,n=`Production-grade agent framework.`){t.settle(),process.stdout.write(formatPromptOpener(e,n,import_picocolors.default))},outro(e){t.settle(),process.stdout.write(formatPromptOutro(e,import_picocolors.default))},log:t}}export{createPrompter};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { Prompter } from "./prompter.js";
|
|
2
|
+
import { type RegistrySetupChildMessage, type RegistrySetupFact } from "./registry-setup-protocol.js";
|
|
3
|
+
interface SetupProcess extends NodeJS.Process {
|
|
4
|
+
send?: (message: RegistrySetupChildMessage) => boolean;
|
|
5
|
+
}
|
|
6
|
+
export interface RegistrySetupClient {
|
|
7
|
+
prompter: Prompter;
|
|
8
|
+
signal: AbortSignal;
|
|
9
|
+
complete(facts?: readonly RegistrySetupFact[]): void;
|
|
10
|
+
cancel(): void;
|
|
11
|
+
fail(error: unknown): void;
|
|
12
|
+
}
|
|
13
|
+
/** Creates a prompter whose questions and output are rendered by the parent eve process. */
|
|
14
|
+
export declare function createRegistrySetupClient(input?: {
|
|
15
|
+
process?: SetupProcess;
|
|
16
|
+
signal?: AbortSignal;
|
|
17
|
+
}): RegistrySetupClient | undefined;
|
|
18
|
+
export {};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{WizardCancelledError}from"./step.js";import"./registry-setup-protocol.js";function send(e,t){if(e.send===void 0||!e.connected)throw Error(`The registry setup host disconnected.`);e.send(t)}function registrySetupError(e){if(!(e instanceof Error))return{message:String(e)};let t=e.stack?.split(`
|
|
2
|
+
`).slice(1).map(e=>e.trim()).filter(Boolean);return t===void 0||t.length===0?{message:e.message}:{message:e.message,details:t}}function createRegistrySetupClient(t={}){let n=t.process??process;if(n.send===void 0||process.env.EVE_SETUP_PROTOCOL===void 0)return;let r=new AbortController;t.signal!==void 0&&t.signal.addEventListener(`abort`,()=>r.abort(t.signal?.reason),{once:!0});let i=1,a=new Map;n.on(`message`,t=>{if(t.type===`cancel`){r.abort(new WizardCancelledError);for(let e of a.values())e({type:`cancel`});a.clear();return}a.get(t.id)?.(t)}),send(n,{type:`ready`,version:1});async function prompt(t){r.signal.throwIfAborted();let o=i++,s=await new Promise(e=>{a.set(o,e),send(n,{type:`prompt`,id:o,prompt:t})});if(a.delete(o),s.type===`cancel`||s.cancelled===!0)throw new WizardCancelledError;return s.value}async function validatedText(e,t){let n=t.notices;for(;;){let r=await prompt({kind:e,message:t.message,placeholder:t.placeholder,defaultValue:t.defaultValue,notices:n}),i=t.validate?.(r);if(i===void 0)return r;n=[{tone:`error`,text:i}]}}function select(e){return prompt({kind:`select`,options:e})}let o={text:e=>validatedText(`text`,e),password:e=>validatedText(`password`,e),select,async selectEditable(e){let t=await prompt({kind:`editable-select`,options:{...e,editable:{value:e.editable.value,defaultValue:e.editable.defaultValue}}});if(t.kind===`selected`)return{kind:`selected`,value:t.value};let n=e.editable.validate?.(t.text);if(n!==void 0)throw Error(n);return{kind:`edited`,value:t.value,text:t.text}},acknowledge:e=>prompt({kind:`acknowledge`,options:e}),awaitChoice(t){let r=i++;return{choice:new Promise((i,o)=>{a.set(r,t=>{a.delete(r),t.type===`cancel`||t.cancelled===!0?o(new WizardCancelledError):i(t.value)}),send(n,{type:`prompt`,id:r,prompt:{kind:`choice`,options:t}})}),close:()=>{a.delete(r),send(n,{type:`close-prompt`,id:r})}}},note(e,t,r){send(n,{type:`note`,message:e,title:t,tone:r?.tone})},intro(e,t){send(n,{type:`intro`,text:e,subtitle:t})},outro(e){send(n,{type:`outro`,text:e})},log:{message:e=>send(n,{type:`log`,level:`message`,text:e}),info:e=>send(n,{type:`log`,level:`info`,text:e}),success:e=>send(n,{type:`log`,level:`success`,text:e}),warning:e=>send(n,{type:`log`,level:`warning`,text:e}),error:e=>send(n,{type:`log`,level:`error`,text:e}),commandOutput:e=>send(n,{type:`log`,level:`commandOutput`,text:e}),spinner(e,t){let r=i++;return send(n,{type:`status`,id:r,status:e,intent:t?.kind===`external-action`?t:void 0}),{stop:()=>send(n,{type:`status`,id:r})}}}},s=!1,finish=e=>{s||(s=!0,send(n,{type:`result`,outcome:e}))};return{prompter:o,signal:r.signal,complete:(e=[])=>finish({kind:`completed`,facts:e}),cancel:()=>finish({kind:`cancelled`}),fail:e=>finish({kind:`failed`,error:registrySetupError(e)})}}export{createRegistrySetupClient};
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import type { AcknowledgeOptions, MultiSelectOptions, PrompterValue, SelectCommonOptions, SelectNotice, SelectOption, SingleSelectOptions } from "./prompter.js";
|
|
2
|
+
export declare const REGISTRY_SETUP_PROTOCOL_VERSION = 1;
|
|
3
|
+
export type RegistrySetupFact = {
|
|
4
|
+
label: string;
|
|
5
|
+
value: string;
|
|
6
|
+
kind?: "text" | "url" | "phone";
|
|
7
|
+
};
|
|
8
|
+
export type RegistrySetupError = {
|
|
9
|
+
message: string;
|
|
10
|
+
details?: readonly string[];
|
|
11
|
+
};
|
|
12
|
+
export type RegistrySetupOutcome = {
|
|
13
|
+
kind: "completed";
|
|
14
|
+
facts: readonly RegistrySetupFact[];
|
|
15
|
+
} | {
|
|
16
|
+
kind: "cancelled";
|
|
17
|
+
} | {
|
|
18
|
+
kind: "failed";
|
|
19
|
+
error: RegistrySetupError;
|
|
20
|
+
};
|
|
21
|
+
export type RegistrySetupPrompt = {
|
|
22
|
+
kind: "text" | "password";
|
|
23
|
+
message: string;
|
|
24
|
+
placeholder?: string;
|
|
25
|
+
defaultValue?: string;
|
|
26
|
+
notices?: readonly SelectNotice[];
|
|
27
|
+
} | {
|
|
28
|
+
kind: "select";
|
|
29
|
+
options: SingleSelectOptions<PrompterValue> | MultiSelectOptions<PrompterValue>;
|
|
30
|
+
} | {
|
|
31
|
+
kind: "editable-select";
|
|
32
|
+
options: SelectCommonOptions<PrompterValue> & {
|
|
33
|
+
initialValue?: PrompterValue;
|
|
34
|
+
editable: {
|
|
35
|
+
value: PrompterValue;
|
|
36
|
+
defaultValue: string;
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
} | {
|
|
40
|
+
kind: "acknowledge";
|
|
41
|
+
options: AcknowledgeOptions;
|
|
42
|
+
} | {
|
|
43
|
+
kind: "choice";
|
|
44
|
+
options: {
|
|
45
|
+
status: string;
|
|
46
|
+
context: string;
|
|
47
|
+
actions: readonly SelectOption<string>[];
|
|
48
|
+
};
|
|
49
|
+
};
|
|
50
|
+
export type RegistrySetupChildMessage = {
|
|
51
|
+
type: "ready";
|
|
52
|
+
version: typeof REGISTRY_SETUP_PROTOCOL_VERSION;
|
|
53
|
+
} | {
|
|
54
|
+
type: "prompt";
|
|
55
|
+
id: number;
|
|
56
|
+
prompt: RegistrySetupPrompt;
|
|
57
|
+
} | {
|
|
58
|
+
type: "close-prompt";
|
|
59
|
+
id: number;
|
|
60
|
+
} | {
|
|
61
|
+
type: "log";
|
|
62
|
+
level: "message" | "info" | "success" | "warning" | "error" | "commandOutput";
|
|
63
|
+
text: string;
|
|
64
|
+
} | {
|
|
65
|
+
type: "note";
|
|
66
|
+
message: string;
|
|
67
|
+
title?: string;
|
|
68
|
+
tone?: "warning" | "success";
|
|
69
|
+
} | {
|
|
70
|
+
type: "intro" | "outro";
|
|
71
|
+
text: string;
|
|
72
|
+
subtitle?: string;
|
|
73
|
+
} | {
|
|
74
|
+
type: "result";
|
|
75
|
+
outcome: RegistrySetupOutcome;
|
|
76
|
+
} | {
|
|
77
|
+
type: "status";
|
|
78
|
+
id: number;
|
|
79
|
+
status?: string;
|
|
80
|
+
intent?: {
|
|
81
|
+
kind: "external-action";
|
|
82
|
+
emphasis: string;
|
|
83
|
+
};
|
|
84
|
+
};
|
|
85
|
+
export type RegistrySetupParentMessage = {
|
|
86
|
+
type: "prompt-result";
|
|
87
|
+
id: number;
|
|
88
|
+
value?: unknown;
|
|
89
|
+
cancelled?: true;
|
|
90
|
+
} | {
|
|
91
|
+
type: "cancel";
|
|
92
|
+
};
|
|
93
|
+
export declare function isRegistrySetupChildMessage(value: unknown): value is RegistrySetupChildMessage;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const REGISTRY_SETUP_PROTOCOL_VERSION=1;function isRegistrySetupChildMessage(e){if(typeof e!=`object`||!e)return!1;let t=e.type;return t===`ready`||t===`prompt`||t===`close-prompt`||t===`log`||t===`note`||t===`intro`||t===`outro`||t===`result`||t===`status`}export{REGISTRY_SETUP_PROTOCOL_VERSION,isRegistrySetupChildMessage};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Build-time catalog of channels used by programmatic setup and
|
|
3
|
-
* `eve
|
|
3
|
+
* `eve add channel/slack`.
|
|
4
4
|
*
|
|
5
5
|
* Channel *identity* (slug, name, and whether it is scaffoldable) is owned by
|
|
6
6
|
* `@vercel/eve-catalog`, the cross-surface source of truth shared with the docs
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{pinnedNodeEngineMajor}from"../../node-engine.js";import{pathExists,writeTextFile}from"../files.js";import{resolveVersionToken}from"../version-tokens.js";import{applyPackageManagerWorkspaceConfiguration,isPackageManagerWorkspaceMember,patchWorkspaceRootPackageJson}from"../workspace-root.js";import{DEFAULT_EVE_PACKAGE_CONTRACT,ROOT_ONLY_PACKAGE_JSON_TEMPLATE_SUFFIX,resolveEvePackageContract}from"./project.js";import{basename,resolve}from"node:path";import{mkdir,readdir}from"node:fs/promises";
|
|
1
|
+
import{pinnedNodeEngineMajor}from"../../node-engine.js";import{pathExists,writeTextFile}from"../files.js";import{blockingCreateInPlaceEntries}from"../create-in-place.js";import{resolveVersionToken}from"../version-tokens.js";import{applyPackageManagerWorkspaceConfiguration,isPackageManagerWorkspaceMember,patchWorkspaceRootPackageJson}from"../workspace-root.js";import{DEFAULT_EVE_PACKAGE_CONTRACT,ROOT_ONLY_PACKAGE_JSON_TEMPLATE_SUFFIX,resolveEvePackageContract}from"./project.js";import{basename,resolve}from"node:path";import{mkdir,readdir}from"node:fs/promises";function renderTemplate(e,t){return e.replaceAll(`__EVE_INIT_APP_NAME__`,t.appName).replaceAll(`__EVE_INIT_PACKAGE_VERSION__`,t.eveVersion).replaceAll(`__EVE_INIT_ZOD_VERSION__`,t.zodPackageVersion).replaceAll(`__EVE_INIT_TYPESCRIPT_VERSION__`,t.typescriptPackageVersion).replaceAll(`__EVE_INIT_TYPES_NODE_VERSION__`,t.nodeTypesVersion).replaceAll(`__EVE_INIT_NODE_ENGINE__`,t.nodeEngine)}function packageJsonTemplate(e){return`${JSON.stringify({name:`__EVE_INIT_APP_NAME__`,version:`0.0.0`,type:`module`,eve:{extension:{source:`./extension`,dist:`./dist/extension`}},files:[`dist`],exports:{".":{types:`./dist/index.d.ts`,default:`./dist/index.mjs`},"./tools":{types:`./dist/tools/index.d.ts`,default:`./dist/tools/index.mjs`}},scripts:{build:`eve extension build`,prepare:`eve extension build`,typecheck:`tsc`},dependencies:{zod:`__EVE_INIT_ZOD_VERSION__`},devDependencies:{"@types/node":`__EVE_INIT_TYPES_NODE_VERSION__`,eve:`__EVE_INIT_PACKAGE_VERSION__`,typescript:`__EVE_INIT_TYPESCRIPT_VERSION__`},peerDependencies:{eve:`*`}},null,2).slice(0,-1)}${e?ROOT_ONLY_PACKAGE_JSON_TEMPLATE_SUFFIX:``}}\n`}function templateFiles(e){return{"extension/extension.ts":`import { defineExtension } from "eve/extension";
|
|
2
2
|
import { z } from "zod";
|
|
3
3
|
|
|
4
4
|
export default defineExtension({
|
|
@@ -30,4 +30,4 @@ dist
|
|
|
30
30
|
.DS_Store
|
|
31
31
|
*.tsbuildinfo
|
|
32
32
|
`,"AGENTS.md":"# eve Extension Package\n\nThis package is an eve extension — a reusable package of tools, connections,\nskills, hooks, and instruction fragments that a consuming agent mounts under\n`agent/extensions/`.\n\nBefore writing code, read the Extensions guide from the installed eve package\ndocs. In most installs, those docs are at `node_modules/eve/docs/extensions.md`.\nIn workspaces or local package installs, resolve the installed `eve` package\nlocation first and read its `docs/extensions.md`. If package docs are\nunavailable, use https://eve.dev/docs/extensions as a fallback.\n\n## Authoring\n\n- Declare the extension in `extension/extension.ts` with `defineExtension` from\n `eve/extension`. Config is optional; read bound values via the handle's\n `.config` in tools and hooks.\n- Add contributions under `extension/` the same way as in an agent:\n `tools/`, `connections/`, `skills/`, `hooks/`, and optional instruction\n fragments. Names come from file paths; the mount supplies the namespace, so\n name tools for what they do (`search`, not `crm_search`).\n- An extension cannot declare `agent.ts`, `sandbox`, `schedules`, or nested\n `extensions/` — those belong to the consuming agent.\n\n## Build and publish\n\n`eve extension build` (wired to `build`/`prepare`) transforms the complete\nagent-shaped source tree into `dist/extension/`, emits type declarations and a\ncompatibility manifest, and fills the package `exports` map. Ship `dist/` only.\nKeep `eve` as a required wildcard peer so the consumer's eve is the one that runs;\neve validates extension compatibility from the generated manifest. Keep the eve\ndevelopment dependency pinned exactly so builds remain reproducible. Upgrade it\nwhen the extension intentionally adopts a newer eve authoring API.\n","CLAUDE.md":`@AGENTS.md
|
|
33
|
-
`,"package.json":packageJsonTemplate(e)}}async function assertCanCreateInPlace(e,n){if(!await pathExists(e))return;let
|
|
33
|
+
`,"package.json":packageJsonTemplate(e)}}async function assertCanCreateInPlace(e,n){if(!await pathExists(e))return;let i=blockingCreateInPlaceEntries(await readdir(e));if(i.length>0&&!n){let e=i.slice(0,5).join(`, `),t=i.length>5?`, and ${i.length-5} more`:``;throw Error(`Cannot create project in current directory because it is not empty. Found: ${e}${t}. Use an empty directory.`)}}async function scaffoldExtensionProject(r){let s=resolve(r.targetDirectory??process.cwd(),r.projectName),c=r.projectName===`.`,l=r.overwriteExisting??!1,u=r.packageManager??`pnpm`,d=resolveEvePackageContract(r.evePackage??DEFAULT_EVE_PACKAGE_CONTRACT),f=pinnedNodeEngineMajor(d.nodeEngine),p=resolve(r.workspaceProbeDirectory??s),m=isPackageManagerWorkspaceMember(u,p);if(c)await assertCanCreateInPlace(s,l);else if(await pathExists(s))throw Error(`Cannot create project because "${s}" already exists.`);let h={appName:basename(s),eveVersion:d.version,zodPackageVersion:resolveVersionToken(`zodPackageVersion`,r.zodPackageVersion??`4.4.3`),typescriptPackageVersion:resolveVersionToken(`typescriptPackageVersion`,r.typescriptPackageVersion??`7.0.2`),nodeTypesVersion:f,nodeEngine:f};await mkdir(s,{recursive:!0});for(let[e,i]of Object.entries(templateFiles(!m))){let a=`${s}/${e}`,o=await pathExists(a);await writeTextFile(a,renderTemplate(i,h),{force:c&&l}),o&&await r.onOverwriteFile?.(a)}return await applyPackageManagerWorkspaceConfiguration({packageManager:u,projectRoot:s,workspaceProbeRoot:p,onWorkspaceRootMutation:r.onWorkspaceRootMutation}),await patchWorkspaceRootPackageJson(u,p,{nodeEngineRequirement:d.nodeEngine,onWorkspaceRootMutation:r.onWorkspaceRootMutation}),s}export{scaffoldExtensionProject};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{pinnedNodeEngineMajor}from"../../node-engine.js";import{SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS}from"../update/module-files.js";import{pathExists,writeTextFile}from"../files.js";import{resolveVersionToken}from"../version-tokens.js";import{applyPackageManagerWorkspaceConfiguration,isPackageManagerWorkspaceMember,patchWorkspaceRootPackageJson}from"../workspace-root.js";import{WEB_APP_TEMPLATE_FILES}from"./web-template.js";import{basename,join,resolve}from"node:path";import{mkdir,readdir,stat}from"node:fs/promises";const CURRENT_DIRECTORY_PROJECT_NAME=`.`,
|
|
1
|
+
import{pinnedNodeEngineMajor}from"../../node-engine.js";import{SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS}from"../update/module-files.js";import{pathExists,writeTextFile}from"../files.js";import{blockingCreateInPlaceEntries}from"../create-in-place.js";import{resolveVersionToken}from"../version-tokens.js";import{applyPackageManagerWorkspaceConfiguration,isPackageManagerWorkspaceMember,patchWorkspaceRootPackageJson}from"../workspace-root.js";import{WEB_APP_TEMPLATE_FILES}from"./web-template.js";import{basename,join,resolve}from"node:path";import{mkdir,readdir,stat}from"node:fs/promises";const CURRENT_DIRECTORY_PROJECT_NAME=`.`,DEFAULT_AI_PACKAGE_VERSION=`^7.0.38`,DEFAULT_CONNECT_PACKAGE_VERSION=`0.4.2`,DEFAULT_ZOD_PACKAGE_VERSION=`4.4.3`,DEFAULT_EVE_PACKAGE_CONTRACT={version:`0.29.0`,nodeEngine:`>=24`};function resolveEvePackageContract(e=DEFAULT_EVE_PACKAGE_CONTRACT){return{version:resolveVersionToken(`evePackage.version`,e.version),nodeEngine:resolveVersionToken(`evePackage.nodeEngine`,e.nodeEngine)}}function modelProviderSlug(e){let t=(e.split(`/`)[0]??``).replaceAll(/[^A-Za-z0-9._-]/gu,``);return t.length>0?t:`anthropic`}function byokProviderEnvVar(e){let t=modelProviderSlug(e).toUpperCase().replaceAll(/[^A-Z0-9]/gu,`_`);return`${/^[0-9]/.test(t)?`_`:``}${t}_API_KEY`}function agentTemplateFiles(e){return{"agent/agent.ts":BASE_AGENT_TEMPLATE.replaceAll(`__EVE_INIT_MODEL__`,e),"agent/channels/eve.ts":WEB_APP_TEMPLATE_FILES[`agent/channels/eve.ts`],"agent/instructions.md":AGENT_INSTRUCTIONS_TEMPLATE}}function renderTemplate(e,t){return e.replaceAll(`__EVE_INIT_APP_NAME__`,t.appName).replaceAll(`__EVE_INIT_MODEL__`,t.model).replaceAll(`__EVE_INIT_BYOK_PROVIDER__`,modelProviderSlug(t.model)).replaceAll(`__EVE_INIT_BYOK_ENV_VAR__`,byokProviderEnvVar(t.model)).replaceAll(`__EVE_INIT_PACKAGE_VERSION__`,formatEveDependencySpecifier(t.eveVersion)).replaceAll(`__EVE_INIT_AI_SDK_VERSION__`,t.aiPackageVersion).replaceAll(`__EVE_INIT_CONNECT_VERSION__`,t.connectPackageVersion).replaceAll(`__EVE_INIT_ZOD_VERSION__`,t.zodPackageVersion).replaceAll(`__EVE_INIT_TYPESCRIPT_VERSION__`,t.typescriptPackageVersion).replaceAll(`__EVE_INIT_TYPES_NODE_VERSION__`,t.nodeTypesVersion).replaceAll(`__EVE_INIT_NODE_ENGINE__`,t.nodeEngine)}function formatEveDependencySpecifier(e){return/^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z-.]+)?$/.test(e)?`^${e}`:e}const BASE_AGENT_TEMPLATE=`import { defineAgent } from "eve";
|
|
2
2
|
|
|
3
3
|
export default defineAgent({
|
|
4
4
|
model: "__EVE_INIT_MODEL__",
|
|
@@ -93,4 +93,4 @@ export default defineAgent({
|
|
|
93
93
|
},
|
|
94
94
|
},
|
|
95
95
|
});
|
|
96
|
-
`:BASE_AGENT_TEMPLATE,...SHARED_TEMPLATE_FILES,"package.json":packageJsonTemplate({includeRootOnlyFields:e.includeRootOnlyPackageJsonFields,packageManager:e.packageManager})}}async function assertCanCreateInPlace(e,t){if(!await pathExists(e))return;let r=(await readdir(e))
|
|
96
|
+
`:BASE_AGENT_TEMPLATE,...SHARED_TEMPLATE_FILES,"package.json":packageJsonTemplate({includeRootOnlyFields:e.includeRootOnlyPackageJsonFields,packageManager:e.packageManager})}}async function assertCanCreateInPlace(e,t){if(!await pathExists(e))return;let r=blockingCreateInPlaceEntries(await readdir(e));if(r.length>0&&!t){let e=r.slice(0,5).join(`, `),t=r.length>5?`, and ${r.length-5} more`:``;throw Error(`Cannot create project in current directory because it is not empty. Found: ${e}${t}. Use an empty directory.`)}}async function scaffoldBaseProject(t){let i=resolve(t.targetDirectory??process.cwd(),t.projectName),c=t.projectName===`.`,l=t.overwriteExisting??!1,u=t.byokProvider??!1,d=t.packageManager??`pnpm`,f=resolveEvePackageContract(t.evePackage),p=pinnedNodeEngineMajor(f.nodeEngine),m=resolve(t.workspaceProbeDirectory??i),h=isPackageManagerWorkspaceMember(d,m);if(c)await assertCanCreateInPlace(i,l);else if(await pathExists(i))throw Error(`Cannot create project because "${i}" already exists.`);let g={appName:basename(i),model:t.model,eveVersion:f.version,aiPackageVersion:resolveVersionToken(`aiPackageVersion`,t.aiPackageVersion??`^7.0.38`),connectPackageVersion:resolveVersionToken(`connectPackageVersion`,t.connectPackageVersion??`0.4.2`),zodPackageVersion:resolveVersionToken(`zodPackageVersion`,t.zodPackageVersion??`4.4.3`),typescriptPackageVersion:resolveVersionToken(`typescriptPackageVersion`,t.typescriptPackageVersion??`7.0.2`),nodeTypesVersion:p,nodeEngine:p};await mkdir(i,{recursive:!0});for(let[e,a]of Object.entries(templateFiles({byokProvider:u,includeRootOnlyPackageJsonFields:!h,packageManager:d}))){let o=`${i}/${e}`,s=await pathExists(o);await writeTextFile(o,renderTemplate(a,g),{force:c&&l}),s&&await t.onOverwriteFile?.(o)}return await applyPackageManagerWorkspaceConfiguration({packageManager:d,projectRoot:i,workspaceProbeRoot:m,onWorkspaceRootMutation:t.onWorkspaceRootMutation}),await patchWorkspaceRootPackageJson(d,m,{aiPackageVersion:g.aiPackageVersion,nodeEngineRequirement:f.nodeEngine,onWorkspaceRootMutation:t.onWorkspaceRootMutation}),i}async function isEveProject(e){for(let n of SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS)try{return await stat(join(e,`agent`,`agent${n}`)),!0}catch{}return!1}export{CURRENT_DIRECTORY_PROJECT_NAME,DEFAULT_AI_PACKAGE_VERSION,DEFAULT_CONNECT_PACKAGE_VERSION,DEFAULT_EVE_PACKAGE_CONTRACT,DEFAULT_ZOD_PACKAGE_VERSION,ROOT_ONLY_PACKAGE_JSON_TEMPLATE_SUFFIX,agentTemplateFiles,byokProviderEnvVar,formatEveDependencySpecifier,isEveProject,modelProviderSlug,resolveEvePackageContract,scaffoldBaseProject};
|