eve 0.29.2 → 0.29.4
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 +41 -0
- package/dist/src/acp/adapter.d.ts +43 -0
- package/dist/src/acp/adapter.js +1 -0
- package/dist/src/acp/line-limit.d.ts +3 -0
- package/dist/src/acp/line-limit.js +1 -0
- package/dist/src/acp/server.d.ts +24 -0
- package/dist/src/acp/server.js +1 -0
- package/dist/src/channel/types.d.ts +15 -0
- package/dist/src/chunks/{use-eve-agent-DaH3cf8K.js → use-eve-agent-8mofdZcO.js} +45 -10
- package/dist/src/chunks/{use-eve-agent-CyDt3Lny.js → use-eve-agent-bKJbH0k4.js} +45 -10
- package/dist/src/cli/acp/command.d.ts +22 -0
- package/dist/src/cli/acp/command.js +4 -0
- package/dist/src/cli/commands/agent-prompt/build-and-verify.md +4 -0
- package/dist/src/cli/commands/extension-init.js +1 -1
- package/dist/src/cli/commands/init-git.js +1 -1
- package/dist/src/cli/commands/init-repl.js +1 -1
- package/dist/src/cli/commands/init.js +1 -1
- package/dist/src/cli/commands/integration-setup.d.ts +3 -7
- package/dist/src/cli/commands/integration-setup.js +1 -1
- package/dist/src/cli/commands/logs.js +2 -2
- package/dist/src/cli/commands/register-integration-commands.js +1 -1
- package/dist/src/cli/commands/register-registry-commands.js +1 -1
- package/dist/src/cli/commands/registry-project.js +1 -1
- package/dist/src/cli/commands/registry-setup-command.js +1 -1
- package/dist/src/cli/commands/registry.d.ts +15 -2
- package/dist/src/cli/commands/registry.js +1 -1
- package/dist/src/cli/commands/trace.d.ts +6 -23
- package/dist/src/cli/commands/trace.js +7 -5
- package/dist/src/cli/dev/command-options.d.ts +22 -0
- package/dist/src/cli/dev/diagnostic-dump.js +1 -1
- package/dist/src/cli/dev/diagnostic-sink.js +1 -1
- package/dist/src/cli/dev/local-server-cleanup.js +1 -1
- package/dist/src/cli/dev/local-server-process.js +1 -1
- package/dist/src/cli/dev/tui/blocks.js +1 -1
- package/dist/src/cli/dev/tui/clipboard.d.ts +17 -0
- package/dist/src/cli/dev/tui/clipboard.js +1 -0
- package/dist/src/cli/dev/tui/command-typeahead.js +1 -1
- package/dist/src/cli/dev/tui/prompt-commands.d.ts +3 -0
- package/dist/src/cli/dev/tui/prompt-commands.js +1 -1
- package/dist/src/cli/dev/tui/remote-auth.d.ts +6 -3
- package/dist/src/cli/dev/tui/remote-auth.js +1 -1
- package/dist/src/cli/dev/tui/remote-connection-probe.js +1 -1
- package/dist/src/cli/dev/tui/runner.d.ts +6 -0
- package/dist/src/cli/dev/tui/runner.js +1 -1
- package/dist/src/cli/dev/tui/stream-format.d.ts +22 -0
- package/dist/src/cli/dev/tui/stream-format.js +2 -2
- package/dist/src/cli/dev/tui/terminal-background.d.ts +23 -0
- package/dist/src/cli/dev/tui/terminal-background.js +1 -0
- package/dist/src/cli/dev/tui/terminal-renderer.d.ts +3 -0
- package/dist/src/cli/dev/tui/terminal-renderer.js +12 -12
- package/dist/src/cli/dev/tui/test/mock-terminal.js +3 -3
- package/dist/src/cli/dev/tui/traces/trace-content.d.ts +35 -0
- package/dist/src/cli/dev/tui/traces/trace-content.js +2 -0
- package/dist/src/cli/dev/tui/traces/trace-conversation.d.ts +63 -0
- package/dist/src/cli/dev/tui/traces/trace-conversation.js +2 -0
- package/dist/src/cli/dev/tui/traces/trace-store.d.ts +27 -0
- package/dist/src/cli/dev/tui/traces/trace-store.js +1 -0
- package/dist/src/cli/dev/tui/traces/trace-surfaces.d.ts +40 -0
- package/dist/src/cli/dev/tui/traces/trace-surfaces.js +1 -0
- package/dist/src/cli/dev/tui/traces/trace-view.d.ts +55 -0
- package/dist/src/cli/dev/tui/traces/trace-view.js +2 -0
- package/dist/src/cli/dev/tui/traces/trace-viewer-session.d.ts +54 -0
- package/dist/src/cli/dev/tui/traces/trace-viewer-session.js +1 -0
- package/dist/src/cli/dev/tui/traces/trace-viewer-state.d.ts +110 -0
- package/dist/src/cli/dev/tui/traces/trace-viewer-state.js +1 -0
- package/dist/src/cli/dev/tui/tui.js +1 -1
- package/dist/src/cli/invoke/invoke.js +1 -1
- package/dist/src/cli/invoke/result.js +1 -1
- package/dist/src/cli/run.d.ts +3 -0
- package/dist/src/cli/run.js +3 -3
- package/dist/src/cli/ui/alt-screen.d.ts +42 -0
- package/dist/src/cli/ui/alt-screen.js +1 -0
- package/dist/src/cli/ui/terminal-text.d.ts +4 -3
- package/dist/src/cli/ui/terminal-text.js +1 -1
- package/dist/src/client/index.d.ts +1 -1
- package/dist/src/client/open-stream.js +1 -1
- package/dist/src/client/session.d.ts +15 -1
- package/dist/src/client/session.js +1 -1
- package/dist/src/client/types.d.ts +9 -0
- package/dist/src/compiled/.vendor-stamp.json +3 -1
- package/dist/src/compiled/@agentclientprotocol/sdk/LICENSE +191 -0
- package/dist/src/compiled/@agentclientprotocol/sdk/index.d.ts +1835 -0
- package/dist/src/compiled/@agentclientprotocol/sdk/index.js +65 -0
- package/dist/src/compiled/@agentclientprotocol/sdk/jsonrpc.d.ts +603 -0
- package/dist/src/compiled/@agentclientprotocol/sdk/schema/guards.gen.d.ts +199 -0
- package/dist/src/compiled/@agentclientprotocol/sdk/schema/index.d.ts +51 -0
- package/dist/src/compiled/@agentclientprotocol/sdk/schema/types.gen.d.ts +6118 -0
- package/dist/src/compiled/@agentclientprotocol/sdk/stream.d.ts +35 -0
- package/dist/src/compiled/@photon-ai/chat-adapter-imessage/LICENSE +21 -0
- package/dist/src/compiled/@photon-ai/chat-adapter-imessage/_spectrum-core.d.ts +3 -0
- package/dist/src/compiled/@photon-ai/chat-adapter-imessage/_spectrum-imessage.d.ts +2 -0
- package/dist/src/compiled/@photon-ai/chat-adapter-imessage/index.d.ts +496 -0
- package/dist/src/compiled/@photon-ai/chat-adapter-imessage/index.js +137 -0
- package/dist/src/compiled/@vercel/sandbox/index.js +13 -107
- package/dist/src/compiled/_chunks/node/auth-BS3UoyvT.js +2 -0
- package/dist/src/compiled/_chunks/node/compat-Dm2n85Mx.js +1 -0
- package/dist/src/compiled/_chunks/node/schemas-DtQwuPdM.js +65 -0
- package/dist/src/compiled/_chunks/node/undici-DWL_MYmT.js +95 -0
- package/dist/src/compiled/_chunks/node/version-Cztrk7z6.js +1 -0
- package/dist/src/compiled/shadcn-registry/index.js +461 -893
- package/dist/src/compiler/artifacts.js +1 -1
- package/dist/src/compiler/extension-compatibility.js +1 -1
- package/dist/src/compiler/model-catalog.js +1 -1
- package/dist/src/compiler/normalize-sandbox.js +1 -1
- package/dist/src/compiler/workspace-resources.js +1 -1
- package/dist/src/context/keys.d.ts +3 -1
- package/dist/src/context/keys.js +1 -1
- package/dist/src/discover/project-source.js +1 -1
- package/dist/src/evals/cli/eval.js +2 -2
- package/dist/src/evals/loaders/json.js +1 -1
- package/dist/src/evals/loaders/yaml.js +1 -1
- package/dist/src/evals/runner/artifacts.js +1 -1
- package/dist/src/evals/runner/discover.js +1 -1
- package/dist/src/evals/runner/reporters/junit.js +1 -1
- package/dist/src/evals/session.js +1 -1
- package/dist/src/execution/delegated-parent-notification.js +1 -1
- package/dist/src/execution/delegated-parent-result.js +1 -1
- package/dist/src/execution/dispatch-runtime-actions-step.js +1 -1
- package/dist/src/execution/runtime-context.js +1 -1
- package/dist/src/execution/sandbox/bindings/docker-cli.js +1 -1
- package/dist/src/execution/sandbox/bindings/docker-templates.js +1 -1
- package/dist/src/execution/sandbox/bindings/just-bash-runtime.js +1 -1
- package/dist/src/execution/sandbox/bindings/just-bash.js +1 -1
- package/dist/src/execution/sandbox/bindings/local-backend-utils.js +1 -1
- package/dist/src/execution/sandbox/bindings/microsandbox-lifecycle.js +1 -1
- package/dist/src/execution/sandbox/bindings/microsandbox-metadata.js +1 -1
- package/dist/src/execution/sandbox/bindings/microsandbox-platform.js +1 -1
- package/dist/src/execution/sandbox/bindings/microsandbox-runtime.js +1 -1
- package/dist/src/execution/sandbox/bindings/microsandbox-templates.js +1 -1
- package/dist/src/execution/sandbox/development-cleanup.js +1 -1
- package/dist/src/execution/sandbox/glob-tool.js +3 -3
- package/dist/src/execution/sandbox/grep-tool.js +1 -1
- package/dist/src/execution/sandbox/read-file-tool.js +3 -3
- package/dist/src/execution/sandbox/require-sandbox.d.ts +3 -3
- package/dist/src/execution/sandbox/require-sandbox.js +1 -1
- package/dist/src/execution/sandbox/template-prewarm-lock.js +1 -1
- package/dist/src/execution/sandbox/write-file-tool.js +1 -1
- package/dist/src/execution/subagent-adapter-state.d.ts +39 -0
- package/dist/src/execution/subagent-adapter-state.js +1 -0
- package/dist/src/execution/subagent-adapter.d.ts +0 -34
- package/dist/src/execution/subagent-adapter.js +1 -1
- package/dist/src/execution/subagent-tool.d.ts +2 -1
- package/dist/src/execution/subagent-tool.js +1 -1
- package/dist/src/execution/workflow-steps.js +1 -1
- package/dist/src/harness/attachment-staging.js +1 -1
- package/dist/src/harness/instrumentation-lifecycle.d.ts +18 -0
- package/dist/src/harness/instrumentation-native-events.d.ts +3 -1
- package/dist/src/harness/instrumentation-native-events.js +1 -1
- package/dist/src/harness/parent-lineage.d.ts +11 -0
- package/dist/src/harness/parent-lineage.js +1 -0
- package/dist/src/harness/tool-loop.js +2 -2
- package/dist/src/internal/application/build-profile.js +1 -1
- package/dist/src/internal/application/build-workspace.js +1 -1
- package/dist/src/internal/application/cache-metadata.js +1 -1
- package/dist/src/internal/application/compiled-artifacts.js +8 -8
- package/dist/src/internal/application/optional-package-install.js +2 -2
- package/dist/src/internal/application/output-publication-artifacts.js +1 -1
- package/dist/src/internal/application/output-publication-journal.js +1 -1
- package/dist/src/internal/application/output-publication-lock.js +1 -1
- package/dist/src/internal/application/output-publication.js +1 -1
- package/dist/src/internal/application/package.js +1 -1
- package/dist/src/internal/application/paths.js +1 -1
- package/dist/src/internal/application/production-compiler-artifacts.js +1 -1
- package/dist/src/internal/application/tsconfig-dependencies.js +1 -1
- package/dist/src/internal/authored-asset-import-plugin.js +1 -1
- package/dist/src/internal/authored-module-loader.js +3 -3
- package/dist/src/internal/authored-package-tsconfig-paths.js +1 -1
- package/dist/src/internal/materialized-authored-modules.js +1 -1
- package/dist/src/internal/nitro/dev-runtime-artifacts-retention.js +1 -1
- package/dist/src/internal/nitro/dev-runtime-artifacts.js +1 -1
- package/dist/src/internal/nitro/dev-runtime-source-snapshot-copy.js +1 -1
- package/dist/src/internal/nitro/dev-runtime-source-snapshot.js +1 -1
- package/dist/src/internal/nitro/host/build-application.js +1 -1
- package/dist/src/internal/nitro/host/build-extension.js +1 -1
- package/dist/src/internal/nitro/host/build-vercel-agent-summary.js +1 -1
- package/dist/src/internal/nitro/host/configure-nitro-routes.js +3 -3
- package/dist/src/internal/nitro/host/copy-host-middleware.js +1 -1
- package/dist/src/internal/nitro/host/create-application-nitro.js +1 -1
- package/dist/src/internal/nitro/host/cron-handler-route.js +1 -1
- package/dist/src/internal/nitro/host/dev-authored-rebuild-coordinator.js +1 -1
- package/dist/src/internal/nitro/host/dev-authored-source-watcher.js +1 -1
- package/dist/src/internal/nitro/host/dev-host-fingerprint.js +1 -1
- package/dist/src/internal/nitro/host/dev-host-workspace.js +1 -1
- package/dist/src/internal/nitro/host/dev-server-http.js +1 -1
- package/dist/src/internal/nitro/host/dev-server-state.js +1 -1
- package/dist/src/internal/nitro/host/dev-workspace-extensions.js +1 -1
- package/dist/src/internal/nitro/host/extension-build-config.js +1 -1
- package/dist/src/internal/nitro/host/extension-declarations.js +2 -2
- package/dist/src/internal/nitro/host/extension-distribution.js +3 -3
- package/dist/src/internal/nitro/host/extension-state-usage.js +1 -1
- package/dist/src/internal/nitro/host/local-tracing-runtime-plugin.js +1 -1
- package/dist/src/internal/nitro/host/normalize-vercel-service-crons.js +1 -1
- package/dist/src/internal/nitro/host/start-development-server.js +2 -2
- package/dist/src/internal/nitro/host/start-production-server.js +2 -2
- package/dist/src/internal/nitro/host/types.d.ts +2 -0
- package/dist/src/internal/vercel/project-link.js +1 -1
- package/dist/src/internal/workflow/development-world-client.js +1 -1
- package/dist/src/internal/workflow-bundle/builder-support.js +6 -6
- package/dist/src/internal/workflow-bundle/builder.js +3 -3
- package/dist/src/internal/workflow-bundle/nitro-step-entry.js +2 -2
- package/dist/src/internal/workflow-bundle/vercel-workflow-output.js +1 -1
- package/dist/src/internal/workflow-bundle/workflow-builders.js +1 -1
- package/dist/src/packages/eve-catalog/src/index.js +1 -1
- package/dist/src/public/channels/chat-sdk/chatSdkChannel.d.ts +7 -0
- package/dist/src/public/channels/chat-sdk/chatSdkChannel.js +2 -2
- package/dist/src/public/channels/discord/discordChannel.js +1 -1
- package/dist/src/public/channels/discord/verify.js +1 -1
- package/dist/src/public/channels/github/auth.js +2 -2
- package/dist/src/public/channels/github/githubChannel.js +1 -1
- package/dist/src/public/channels/github/verify.js +1 -1
- package/dist/src/public/channels/linear/inbound.js +2 -2
- package/dist/src/public/channels/linear/linearChannel.js +1 -1
- package/dist/src/public/channels/linear/verify.js +1 -1
- package/dist/src/public/channels/photon/inboundContent.d.ts +4 -0
- package/dist/src/public/channels/photon/inboundContent.js +1 -0
- package/dist/src/public/channels/photon/index.d.ts +1 -0
- package/dist/src/public/channels/photon/index.js +1 -0
- package/dist/src/public/channels/photon/photonIMessageChannel.d.ts +54 -0
- package/dist/src/public/channels/photon/photonIMessageChannel.js +1 -0
- package/dist/src/public/channels/teams/teamsChannel.js +1 -1
- package/dist/src/public/channels/telegram/verify.js +1 -1
- package/dist/src/public/channels/twilio/twilioChannel.js +1 -1
- package/dist/src/public/models/openai/chatgpt/auth.js +1 -1
- package/dist/src/public/next/server.js +2 -2
- package/dist/src/public/next/vercel-output-config.js +1 -1
- package/dist/src/public/nuxt/dev-server.js +1 -1
- package/dist/src/public/nuxt/vercel-services.js +1 -1
- package/dist/src/public/sveltekit/dev-server.js +1 -1
- package/dist/src/public/sveltekit/vercel-json.js +1 -1
- package/dist/src/runtime/channels/registry.js +1 -1
- package/dist/src/runtime/framework-tools/file-state.js +1 -1
- package/dist/src/runtime/framework-tools/glob.js +1 -1
- package/dist/src/runtime/framework-tools/grep.js +1 -1
- package/dist/src/runtime/framework-tools/read-file.js +1 -1
- package/dist/src/runtime/framework-tools/write-file.js +1 -1
- package/dist/src/runtime/sandbox/keys.js +1 -1
- package/dist/src/runtime/workspace/seed-files.js +1 -1
- package/dist/src/setup/boxes/detect-ai-gateway.js +1 -1
- package/dist/src/setup/boxes/resolve-provisioning.js +1 -1
- package/dist/src/setup/connect-provisioning.d.ts +32 -0
- package/dist/src/setup/connect-provisioning.js +1 -0
- package/dist/src/setup/flows/login.js +1 -1
- package/dist/src/setup/flows/registry.js +1 -1
- package/dist/src/setup/index.d.ts +1 -0
- package/dist/src/setup/index.js +1 -1
- package/dist/src/setup/integrations/discord/api.d.ts +15 -0
- package/dist/src/setup/integrations/discord/api.js +1 -0
- package/dist/src/setup/integrations/discord/connect.d.ts +24 -0
- package/dist/src/setup/integrations/discord/connect.js +1 -0
- package/dist/src/setup/integrations/discord/setup.d.ts +19 -0
- package/dist/src/setup/integrations/discord/setup.js +8 -0
- package/dist/src/setup/integrations/photon/connect.d.ts +40 -0
- package/dist/src/setup/integrations/photon/connect.js +1 -0
- package/dist/src/setup/integrations/photon/management.d.ts +34 -0
- package/dist/src/setup/integrations/photon/management.js +1 -0
- package/dist/src/setup/integrations/photon/setup-flow.d.ts +39 -0
- package/dist/src/setup/integrations/photon/setup-flow.js +20 -0
- package/dist/src/setup/integrations/photon/setup.d.ts +3 -0
- package/dist/src/setup/integrations/photon/setup.js +1 -0
- package/dist/src/setup/integrations/registry.d.ts +6 -0
- package/dist/src/setup/integrations/registry.js +1 -0
- package/dist/src/setup/integrations/runner.d.ts +25 -0
- package/dist/src/setup/integrations/runner.js +1 -0
- package/dist/src/setup/integrations/{channels → shared}/environment.d.ts +3 -3
- package/dist/src/setup/integrations/shared/environment.js +1 -0
- package/dist/src/setup/integrations/shared/scaffold.d.ts +19 -0
- package/dist/src/setup/integrations/shared/scaffold.js +1 -0
- package/dist/src/setup/integrations/{channels → shared}/ui.d.ts +3 -3
- package/dist/src/setup/integrations/shared/ui.js +2 -0
- package/dist/src/setup/integrations/slack/setup.d.ts +16 -0
- package/dist/src/setup/integrations/slack/setup.js +1 -0
- package/dist/src/setup/integrations/types.d.ts +26 -0
- package/dist/src/setup/integrations/types.js +1 -0
- package/dist/src/setup/integrations/web/setup.d.ts +3 -0
- package/dist/src/setup/integrations/web/setup.js +1 -0
- package/dist/src/setup/package-manager.js +1 -1
- package/dist/src/setup/primitives/pm/pnpm.js +3 -3
- package/dist/src/setup/primitives/run-vercel.d.ts +2 -7
- package/dist/src/setup/primitives/run-vercel.js +1 -1
- package/dist/src/setup/project-resolution.js +1 -1
- package/dist/src/setup/prompter.js +1 -1
- package/dist/src/setup/registry-setup-client.d.ts +6 -2
- package/dist/src/setup/registry-setup-client.js +1 -1
- package/dist/src/setup/scaffold/create/add-to-project.js +1 -1
- package/dist/src/setup/scaffold/create/extension.js +1 -1
- package/dist/src/setup/scaffold/create/project.js +3 -10
- package/dist/src/setup/scaffold/files.js +1 -1
- package/dist/src/setup/scaffold/update/channels.js +2 -2
- package/dist/src/setup/scaffold/update/connections.js +1 -1
- package/dist/src/setup/scaffold/workspace-root.js +1 -1
- package/dist/src/setup/slack-connect-lifecycle.d.ts +2 -8
- package/dist/src/setup/slack-connect-lifecycle.js +1 -1
- package/dist/src/setup/state.d.ts +0 -12
- package/dist/src/setup/state.js +1 -1
- package/dist/src/setup/vercel-project-framework.js +1 -1
- package/dist/src/shared/guards.d.ts +2 -0
- package/dist/src/shared/guards.js +1 -1
- package/dist/src/shared/skill-package.js +1 -1
- package/dist/src/shared/skill-paths.d.ts +14 -4
- package/dist/src/shared/skill-paths.js +2 -2
- package/dist/src/shared/vercel-output-directory.js +1 -1
- package/dist/src/source-change/static-source-change.js +1 -1
- package/dist/src/svelte/index.js +1 -1
- package/dist/src/svelte/use-eve-agent.js +1 -1
- package/dist/src/tracing/agent-otel-content.d.ts +32 -0
- package/dist/src/tracing/agent-otel-content.js +4 -0
- package/dist/src/{harness → tracing}/agent-otel-provider.d.ts +10 -1
- package/dist/src/tracing/agent-otel-provider.js +2 -0
- package/dist/src/{harness → tracing}/agent-trace-context-store.d.ts +8 -1
- package/dist/src/tracing/agent-trace-context-store.js +1 -0
- package/dist/src/{harness → tracing}/agent-trace-span-processor.d.ts +5 -1
- package/dist/src/tracing/agent-trace-span-processor.js +1 -0
- package/dist/src/tracing/local-instrumentation-runtime.js +1 -0
- package/dist/src/tracing/local-trace-reader.d.ts +74 -0
- package/dist/src/tracing/local-trace-reader.js +1 -0
- package/dist/src/{harness → tracing}/local-trace-retention.js +1 -1
- package/dist/src/{harness → tracing}/local-trace-span-processor.js +1 -1
- package/dist/src/vue/index.js +1 -1
- package/dist/src/vue/use-eve-agent.js +1 -1
- package/docs/channels/chat-sdk.mdx +18 -1
- package/docs/channels/discord.mdx +30 -14
- package/docs/channels/meta.json +1 -0
- package/docs/channels/overview.mdx +1 -1
- package/docs/channels/photon.mdx +78 -0
- package/docs/concepts/default-harness.md +2 -0
- package/docs/guides/acp.md +91 -0
- package/docs/guides/client/streaming.mdx +24 -0
- package/docs/guides/dev-tui.md +20 -1
- package/docs/guides/instrumentation.md +8 -7
- package/docs/guides/meta.json +1 -0
- package/docs/reference/cli.md +12 -1
- package/docs/sandbox.mdx +1 -1
- package/package.json +8 -1
- package/dist/src/compiled/_chunks/node/auth-DMsLOrh7.js +0 -2
- package/dist/src/compiled/_chunks/node/version-BQBAL95V.js +0 -64
- package/dist/src/harness/agent-otel-provider.js +0 -1
- package/dist/src/harness/agent-trace-context-store.js +0 -1
- package/dist/src/harness/agent-trace-span-processor.js +0 -1
- package/dist/src/harness/local-instrumentation-runtime.js +0 -1
- package/dist/src/setup/integrations/channels/environment.js +0 -1
- package/dist/src/setup/integrations/channels/index.d.ts +0 -7
- package/dist/src/setup/integrations/channels/index.js +0 -1
- package/dist/src/setup/integrations/channels/runner.d.ts +0 -7
- package/dist/src/setup/integrations/channels/runner.js +0 -1
- package/dist/src/setup/integrations/channels/setup.d.ts +0 -130
- package/dist/src/setup/integrations/channels/setup.js +0 -2
- package/dist/src/setup/integrations/channels/slack.d.ts +0 -3
- package/dist/src/setup/integrations/channels/slack.js +0 -1
- package/dist/src/setup/integrations/channels/types.d.ts +0 -49
- package/dist/src/setup/integrations/channels/ui.js +0 -2
- package/dist/src/setup/integrations/channels/web.d.ts +0 -3
- package/dist/src/setup/integrations/channels/web.js +0 -1
- /package/dist/src/{setup/integrations/channels/types.js → cli/dev/command-options.js} +0 -0
- /package/dist/src/{harness → tracing}/local-instrumentation-runtime.d.ts +0 -0
- /package/dist/src/{harness → tracing}/local-trace-retention.d.ts +0 -0
- /package/dist/src/{harness → tracing}/local-trace-span-processor.d.ts +0 -0
|
@@ -1 +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};
|
|
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.title===void 0?(e.name.split(`/`).at(-1)??e.name).split(`-`).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(` `):e.title}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};
|
|
@@ -9,5 +9,6 @@ export { getPackageManagerStrategy, runPackageManagerInstall, runPnpmInstall, ru
|
|
|
9
9
|
export { detectDeployment, detectProjectResolution, projectProductionUrlFromResolution, type DeploymentInfo, type DeploymentState, type ProjectResolution, } from "./project-resolution.js";
|
|
10
10
|
export { runVercelEnvPull } from "./run-vercel-link.js";
|
|
11
11
|
export { provisionSlackbot, reconcileSlackUid, type ProvisionSlackbotResult } from "./slackbot.js";
|
|
12
|
+
export { runRemoteAuthFlow } from "../cli/dev/tui/remote-auth.js";
|
|
12
13
|
export { setupConnectionConnector, type SetupConnectionConnectorOptions, type SetupConnectionConnectorResult, } from "./connection-connector.js";
|
|
13
14
|
export { linkProject, requireAuth, resolveProjectByNameOrId, resolveTeam, } from "./vercel-project.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{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};
|
|
1
|
+
import{runRemoteAuthFlow}from"../cli/dev/tui/remote-auth.js";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,runRemoteAuthFlow,runVercel,runVercelEnvPull,setupConnectionConnector,snapshotSetupState,spawnPackageManager,spawnPnpm};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/** Non-secret Discord application metadata resolved from a bot token. */
|
|
2
|
+
export interface DiscordApplication {
|
|
3
|
+
id: string;
|
|
4
|
+
name: string;
|
|
5
|
+
publicKey: string;
|
|
6
|
+
}
|
|
7
|
+
/** Validates a bot token and returns its Discord application. */
|
|
8
|
+
export declare function resolveDiscordApplication(botToken: string, fetchImpl?: typeof fetch): Promise<DiscordApplication>;
|
|
9
|
+
/** Registers the global command consumed by the default Discord channel. */
|
|
10
|
+
export declare function registerDiscordCommand(applicationId: string, botToken: string, command: {
|
|
11
|
+
name: string;
|
|
12
|
+
description: string;
|
|
13
|
+
}, fetchImpl?: typeof fetch): Promise<void>;
|
|
14
|
+
/** Points Discord HTTP Interactions at a persisted Connect connector. */
|
|
15
|
+
export declare function configureDiscordInteractionsEndpoint(botToken: string, connectorId: string, fetchImpl?: typeof fetch): Promise<void>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{object,string}from"../../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/classic/schemas.js";import"../../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/index.js";const DiscordApplicationSchema=object({id:string(),name:string(),verify_key:string()});async function discordRequest(e,t,n,r){return r(`https://discord.com/api/v10${t}`,{...n,headers:{authorization:`Bot ${e}`,"content-type":`application/json`,...n.headers}})}async function resolveDiscordApplication(e,t=fetch){let r=await discordRequest(e,`/oauth2/applications/@me`,{method:`GET`},t);if(!r.ok)throw Error(`Discord rejected the bot token (HTTP ${r.status}).`);let i=DiscordApplicationSchema.safeParse(await r.json());if(!i.success)throw Error(`Discord returned incomplete application details.`);return{id:i.data.id,name:i.data.name,publicKey:i.data.verify_key}}async function registerDiscordCommand(e,t,n,r=fetch){let i=await discordRequest(t,`/applications/${encodeURIComponent(e)}/commands`,{method:`POST`,body:JSON.stringify({name:n.name,description:n.description,type:1,options:[{name:`message`,description:`What should the agent do?`,type:3,required:!0}]})},r);if(!i.ok)throw Error(`Discord command registration failed (HTTP ${i.status}).`)}async function configureDiscordInteractionsEndpoint(e,t,n=fetch){let r=await discordRequest(e,`/applications/@me`,{method:`PATCH`,body:JSON.stringify({interactions_endpoint_url:`https://connect.vercel.com/trigger/${encodeURIComponent(t)}`})},n);if(!r.ok)throw Error(`Discord rejected the interactions endpoint (HTTP ${r.status}).`)}export{configureDiscordInteractionsEndpoint,registerDiscordCommand,resolveDiscordApplication};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { type ChannelSetupLog } from "#setup/cli/index.js";
|
|
2
|
+
import type { VercelProjectReference } from "#setup/project-resolution.js";
|
|
3
|
+
import { runVercel, runVercelCaptureStdout } from "#setup/primitives/run-vercel.js";
|
|
4
|
+
export declare const DISCORD_TRIGGER_PATH = "/eve/v1/discord";
|
|
5
|
+
export interface DiscordConnectorRef {
|
|
6
|
+
id: string;
|
|
7
|
+
uid: string;
|
|
8
|
+
}
|
|
9
|
+
export interface ProvisionDiscordConnectorDeps {
|
|
10
|
+
runVercel: typeof runVercel;
|
|
11
|
+
runVercelCaptureStdout: typeof runVercelCaptureStdout;
|
|
12
|
+
}
|
|
13
|
+
/** Parses `vercel connect create -F json` output for a Discord connector. */
|
|
14
|
+
export declare function parseCreatedDiscordConnector(stdout: string): DiscordConnectorRef | undefined;
|
|
15
|
+
/** Creates a Discord connector and attaches its trigger to eve's route. */
|
|
16
|
+
export declare function provisionDiscordConnector(input: {
|
|
17
|
+
botToken: string;
|
|
18
|
+
log: ChannelSetupLog;
|
|
19
|
+
project: VercelProjectReference;
|
|
20
|
+
projectRoot: string;
|
|
21
|
+
slug: string;
|
|
22
|
+
signal?: AbortSignal;
|
|
23
|
+
deps?: ProvisionDiscordConnectorDeps;
|
|
24
|
+
}): Promise<DiscordConnectorRef>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{array,object,string}from"../../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/classic/schemas.js";import"../../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/index.js";import{runVercel,runVercelCaptureStdout}from"#setup/primitives/run-vercel.js";import{createPromptCommandOutput,withPhase}from"#setup/cli/index.js";import{replaceConnectTrigger}from"#setup/connect-provisioning.js";const DISCORD_TRIGGER_PATH=`/eve/v1/discord`,DiscordConnectorRefSchema=object({id:string().min(1),uid:string().min(1),supportedSubjectTypes:array(string()).refine(e=>e.includes(`app`))});function parseCreatedDiscordConnector(e){try{let t=DiscordConnectorRefSchema.safeParse(JSON.parse(e));return t.success?{id:t.data.id,uid:t.data.uid}:void 0}catch{return}}async function provisionDiscordConnector(e){let t=e.deps??{runVercel,runVercelCaptureStdout},n=createPromptCommandOutput(e.log),r=await withPhase(e.log,`Creating Discord connector...`,()=>t.runVercelCaptureStdout([`connect`,`create`,`discord`,`--connector-type`,`discord`,`--data`,`@-`,`--name`,e.slug,`--triggers`,`-F`,`json`,`--scope`,e.project.orgId],{cwd:e.projectRoot,nonInteractive:!0,onOutput:n,signal:e.signal,stdin:JSON.stringify({botToken:e.botToken.trim()})}));if(e.signal?.throwIfAborted(),!r.ok){let e=[r.stderr,r.stdout].find(e=>e!==void 0&&e.trim().length>0);throw Error(e?`Discord connector creation failed:\n${e}`:`Discord connector creation failed.`)}let i=parseCreatedDiscordConnector(r.stdout);if(i===void 0)throw Error(`Vercel returned an invalid Discord connector.`);if((await withPhase(e.log,`Connecting Discord interactions...`,()=>replaceConnectTrigger({connectorUid:i.uid,projectRoot:e.projectRoot,projectId:e.project.projectId,orgId:e.project.orgId,environment:`production`,triggerPath:DISCORD_TRIGGER_PATH,onOutput:n,signal:e.signal,deps:t}))).state!==`attached`)throw Error(`Discord connector was created, but its trigger could not be attached. Run \`vercel connect attach ${i.uid} --project ${e.project.projectId} --environment production --triggers --trigger-path ${DISCORD_TRIGGER_PATH} --yes --scope ${e.project.orgId}\`.`);return i}export{DISCORD_TRIGGER_PATH,parseCreatedDiscordConnector,provisionDiscordConnector};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { ensureVercelProject } from "#setup/flows/ensure-vercel-project.js";
|
|
2
|
+
import { deriveSlackConnectorSlug } from "#setup/scaffold/index.js";
|
|
3
|
+
import { writeTextFile } from "#setup/scaffold/files.js";
|
|
4
|
+
import type { IntegrationSetupContext, IntegrationSetupResult, SetupIntegration } from "../types.js";
|
|
5
|
+
import { configureDiscordInteractionsEndpoint, registerDiscordCommand, resolveDiscordApplication } from "./api.js";
|
|
6
|
+
import { provisionDiscordConnector } from "./connect.js";
|
|
7
|
+
export interface DiscordSetupDeps {
|
|
8
|
+
configureEndpoint: typeof configureDiscordInteractionsEndpoint;
|
|
9
|
+
deriveConnectorSlug: typeof deriveSlackConnectorSlug;
|
|
10
|
+
ensureVercelProject: typeof ensureVercelProject;
|
|
11
|
+
provisionConnector: typeof provisionDiscordConnector;
|
|
12
|
+
registerCommand: typeof registerDiscordCommand;
|
|
13
|
+
resolveApplication: typeof resolveDiscordApplication;
|
|
14
|
+
writeTextFile: typeof writeTextFile;
|
|
15
|
+
}
|
|
16
|
+
/** Runs guided Discord connector, command, and channel setup. */
|
|
17
|
+
export declare function setupDiscord(context: IntegrationSetupContext, deps?: DiscordSetupDeps): Promise<IntegrationSetupResult>;
|
|
18
|
+
/** Discord setup registration. */
|
|
19
|
+
export declare const DISCORD_SETUP: SetupIntegration;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import{configureDiscordInteractionsEndpoint,registerDiscordCommand,resolveDiscordApplication}from"./api.js";import{provisionDiscordConnector}from"./connect.js";import{join}from"node:path";import{deriveSlackConnectorSlug}from"#setup/scaffold/index.js";import{WizardCancelledError}from"#setup/step.js";import{text}from"#setup/ask.js";import{ensureVercelProject}from"#setup/flows/ensure-vercel-project.js";import{writeTextFile}from"#setup/scaffold/files.js";const defaultDeps={configureEndpoint:configureDiscordInteractionsEndpoint,deriveConnectorSlug:deriveSlackConnectorSlug,ensureVercelProject,provisionConnector:provisionDiscordConnector,registerCommand:registerDiscordCommand,resolveApplication:resolveDiscordApplication,writeTextFile};function validateCommandName(e){let t=e.trim();return t?t.length>32?`Command name must be 32 characters or fewer.`:/^[a-z0-9_-]+$/.test(t)?null:`Use lowercase letters, numbers, hyphens, or underscores.`:`Command name is required.`}function connectTemplate(e){return`import { connectDiscordCredentials } from "@vercel/connect/eve";
|
|
2
|
+
import { discordChannel } from "eve/channels/discord";
|
|
3
|
+
|
|
4
|
+
export default discordChannel({
|
|
5
|
+
credentials: connectDiscordCredentials(${JSON.stringify(e)}),
|
|
6
|
+
});
|
|
7
|
+
`}async function setupDiscord(e,t=defaultDeps){if(e.environment.vercel.kind===`unavailable`)throw Error("Discord setup requires an authenticated Vercel CLI. Run `vercel login`, then retry.");try{let n=[`Create a Discord application or open an existing one, then go to Bot → Reset Token and copy the new bot token.`,`Create: https://discord.com/developers/applications?new_application=true`,`Existing applications: https://discord.com/developers/applications`];e.ui.prompter.acknowledge?await e.ui.prompter.acknowledge({message:`Discord application`,lines:n}):e.ui.prompter.log.info(`Discord application\n${n.join(`
|
|
8
|
+
`)}`);let r=(await e.ui.asker.ask(text({key:`discord-bot-token`,message:`Discord bot token`,required:!0,sensitive:!0}))).trim(),i=await e.ui.asker.ask(text({key:`discord-command-name`,message:`Discord command name`,detected:`ask`,required:!0,validate:validateCommandName})),a=await e.ui.asker.ask(text({key:`discord-command-description`,message:`Discord command description`,detected:`Ask the eve agent`,required:!0,validate:e=>e.trim().length===0?`Command description is required.`:e.trim().length>100?`Command description must be 100 characters or fewer.`:null})),o=await t.resolveApplication(r),s=await t.ensureVercelProject({appRoot:e.appRoot,prompter:e.ui.prompter,signal:e.signal}),c=await t.provisionConnector({botToken:r,log:e.ui.prompter.log,project:s,projectRoot:e.appRoot,slug:await t.deriveConnectorSlug(e.appRoot),signal:e.signal});await t.registerCommand(o.id,r,{name:i.trim(),description:a.trim()}),await t.configureEndpoint(r,c.id),await t.writeTextFile(join(e.appRoot,`agent/channels/discord.ts`),connectTemplate(c.uid),{force:e.force});let l=`https://discord.com/oauth2/authorize?client_id=${encodeURIComponent(o.id)}&scope=bot%20applications.commands&permissions=3072`;return e.ui.nextSteps([`Install the Discord application, then try /${i.trim()}: ${l}`]),{kind:`done`,facts:[{label:`Discord application`,value:`https://discord.com/developers/applications/${o.id}/information`,kind:`url`}]}}catch(e){if(e instanceof WizardCancelledError)return{kind:`cancelled`};throw e}}const DISCORD_SETUP={kind:`discord`,label:`Discord`,hint:`Slash commands and interactions`,setup:setupDiscord};export{DISCORD_SETUP,setupDiscord};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { ChannelSetupLog } from "#setup/cli/index.js";
|
|
2
|
+
import type { VercelProjectReference } from "#setup/project-resolution.js";
|
|
3
|
+
import { runVercel, runVercelCaptureStdout } from "#setup/primitives/run-vercel.js";
|
|
4
|
+
export declare const PHOTON_CONNECT_SERVICE = "photon";
|
|
5
|
+
export declare const PHOTON_CONNECTOR_TYPE = "photon";
|
|
6
|
+
export declare const PHOTON_TRIGGER_PATH = "/eve/v1/photon";
|
|
7
|
+
/** Photon project credentials collected separately from their Connect storage encoding. */
|
|
8
|
+
export interface PhotonProjectCredentials {
|
|
9
|
+
projectId: string;
|
|
10
|
+
projectSecret: string;
|
|
11
|
+
}
|
|
12
|
+
/** Identity of a native Photon connector created through Vercel Connect. */
|
|
13
|
+
export interface PhotonConnectorRef {
|
|
14
|
+
id: string;
|
|
15
|
+
uid: string;
|
|
16
|
+
/** Direct project URL used until Photon is available as a managed trigger connector. */
|
|
17
|
+
webhookUrl?: string;
|
|
18
|
+
}
|
|
19
|
+
/** Effects used to provision a Photon connector. */
|
|
20
|
+
export interface ProvisionPhotonConnectorDeps {
|
|
21
|
+
runVercel: typeof runVercel;
|
|
22
|
+
runVercelCaptureStdout: typeof runVercelCaptureStdout;
|
|
23
|
+
}
|
|
24
|
+
/** Input for provisioning one Photon connector and its eve webhook destination. */
|
|
25
|
+
export interface ProvisionPhotonConnectorOptions {
|
|
26
|
+
credentials: PhotonProjectCredentials;
|
|
27
|
+
log: ChannelSetupLog;
|
|
28
|
+
project: VercelProjectReference;
|
|
29
|
+
projectRoot: string;
|
|
30
|
+
slug: string;
|
|
31
|
+
signal?: AbortSignal;
|
|
32
|
+
deps?: ProvisionPhotonConnectorDeps;
|
|
33
|
+
}
|
|
34
|
+
/** Parses `vercel connect create -F json` output for a Photon connector. */
|
|
35
|
+
export declare function parseCreatedPhotonConnector(stdout: string): PhotonConnectorRef | undefined;
|
|
36
|
+
/**
|
|
37
|
+
* Creates a native Photon connector and attaches its verified webhook trigger
|
|
38
|
+
* to the linked project. Secrets travel over stdin, never argv.
|
|
39
|
+
*/
|
|
40
|
+
export declare function provisionPhotonConnector(options: ProvisionPhotonConnectorOptions): Promise<PhotonConnectorRef>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{array,object,string}from"../../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/classic/schemas.js";import"../../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/index.js";import{runVercel,runVercelCaptureStdout}from"#setup/primitives/run-vercel.js";import{createPromptCommandOutput,withPhase}from"#setup/cli/index.js";import{replaceConnectTrigger}from"#setup/connect-provisioning.js";const PHOTON_CONNECT_SERVICE=`photon`,PHOTON_CONNECTOR_TYPE=`photon`,PHOTON_TRIGGER_PATH=`/eve/v1/photon`,PhotonConnectorRefSchema=object({id:string().min(1),uid:string().min(1),supportedSubjectTypes:array(string()).refine(e=>e.includes(`app`))});function parseCreatedPhotonConnector(e){try{let t=PhotonConnectorRefSchema.safeParse(JSON.parse(e));return t.success?{id:t.data.id,uid:t.data.uid}:void 0}catch{return}}function createData(e){return JSON.stringify({projectId:e.projectId.trim(),projectSecret:e.projectSecret.trim()})}function requireCreatedConnector(e){if(!e.ok){let t=[e.stderr,e.stdout].map(e=>e?.trim()).find(e=>e!==void 0&&e.length>0);throw Error(t?`Photon connector creation failed:\n${t}`:`Photon connector creation failed.`)}let t=parseCreatedPhotonConnector(e.stdout);if(t===void 0)throw Error(`Vercel returned an invalid Photon connector after creation.`);return t}async function provisionPhotonConnector(e){let t=e.deps??{runVercel,runVercelCaptureStdout},n=createPromptCommandOutput(e.log),r=await withPhase(e.log,`Creating Photon connector...`,()=>t.runVercelCaptureStdout([`connect`,`create`,PHOTON_CONNECT_SERVICE,`--connector-type`,PHOTON_CONNECTOR_TYPE,`--data`,`@-`,`--name`,e.slug,`--triggers`,`-F`,`json`,`--scope`,e.project.orgId],{cwd:e.projectRoot,nonInteractive:!0,onOutput:n,signal:e.signal,stdin:createData(e.credentials)}));e.signal?.throwIfAborted();let i=requireCreatedConnector(r),a=await withPhase(e.log,`Connecting Photon credentials...`,()=>replaceConnectTrigger({connectorUid:i.uid,projectRoot:e.projectRoot,projectId:e.project.projectId,orgId:e.project.orgId,environment:`production`,triggerPath:PHOTON_TRIGGER_PATH,onOutput:n,signal:e.signal,deps:t}));if(e.signal?.throwIfAborted(),a.state!==`attached`){let t=`vercel connect attach ${i.uid} --project ${e.project.projectId} --environment production --triggers --trigger-path ${PHOTON_TRIGGER_PATH} --yes --scope ${e.project.orgId}`;throw Error(a.state===`detach-failed`?`Photon connector was created, but its default trigger destination could not be removed. Run \`vercel connect detach ${i.uid} --project ${e.project.projectId} --yes --scope ${e.project.orgId}\`, then \`${t}\`.`:`Photon connector was created, but its credentials could not be attached. Run \`${t}\`.`)}return i}export{PHOTON_CONNECTOR_TYPE,PHOTON_CONNECT_SERVICE,PHOTON_TRIGGER_PATH,parseCreatedPhotonConnector,provisionPhotonConnector};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/** Validates international syntax and the fixed-length North American numbering plan. */
|
|
2
|
+
export declare function validatePhotonPhoneNumber(value: string): string | null;
|
|
3
|
+
export interface PhotonManagedProject {
|
|
4
|
+
projectId: string;
|
|
5
|
+
projectSecret: string;
|
|
6
|
+
assignedPhoneNumber?: string;
|
|
7
|
+
/** Deletes the dedicated project when a later setup phase fails. */
|
|
8
|
+
cleanup(): Promise<void>;
|
|
9
|
+
}
|
|
10
|
+
export interface PhotonDeviceAuthorization {
|
|
11
|
+
userCode: string;
|
|
12
|
+
verificationUrl: string;
|
|
13
|
+
}
|
|
14
|
+
export interface ProvisionPhotonProjectOptions {
|
|
15
|
+
projectName: string;
|
|
16
|
+
phoneNumber: string;
|
|
17
|
+
onAuthorization(authorization: PhotonDeviceAuthorization): void;
|
|
18
|
+
signal?: AbortSignal;
|
|
19
|
+
deps?: PhotonManagementDeps;
|
|
20
|
+
}
|
|
21
|
+
export interface UsePhotonProjectOptions {
|
|
22
|
+
projectId: string;
|
|
23
|
+
projectSecret: string;
|
|
24
|
+
phoneNumber: string;
|
|
25
|
+
deps?: PhotonManagementDeps;
|
|
26
|
+
}
|
|
27
|
+
export interface PhotonManagementDeps {
|
|
28
|
+
fetch: typeof fetch;
|
|
29
|
+
delay(ms: number, signal?: AbortSignal): Promise<void>;
|
|
30
|
+
}
|
|
31
|
+
/** Authorizes Photon and creates an isolated iMessage project for one eve agent. */
|
|
32
|
+
export declare function provisionPhotonProject(options: ProvisionPhotonProjectOptions): Promise<PhotonManagedProject>;
|
|
33
|
+
/** Validates existing Photon credentials and registers the agent's iMessage user. */
|
|
34
|
+
export declare function usePhotonProject(options: UsePhotonProjectOptions): Promise<PhotonManagedProject>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{z}from"#compiled/zod/index.js";import{setTimeout}from"node:timers/promises";const PHOTON_DASHBOARD_HOST=`https://app.photon.codes`,PHOTON_DEVICE_CLIENT_ID=`photon-cli`,E164=/^\+[1-9]\d{6,14}$/;function validatePhotonPhoneNumber(e){let t=e.trim();return E164.test(t)?t.startsWith(`+1`)&&t.length!==12?`US and Canadian numbers must be +1 followed by exactly 10 digits`:null:`Use E.164 format: + followed by 7–15 digits, for example +15551234567`}const DeviceAuthorizationSchema=z.object({device_code:z.string().min(1),user_code:z.string().min(1),verification_uri_complete:z.string().url().optional(),verification_uri:z.string().url().optional(),expires_in:z.number().positive().optional(),interval:z.number().positive().optional()}),DeviceTokenSchema=z.object({access_token:z.string().min(1).optional(),accessToken:z.string().min(1).optional()}),ProjectSchema=z.object({id:z.string().min(1)}),ProjectSecretSchema=z.object({projectSecret:z.string().min(1)}),ErrorResponseSchema=z.object({error:z.unknown().optional(),message:z.unknown().optional()}),PhoneRegistrationSchema=z.object({assignedPhoneNumber:z.string().optional(),phoneNumber:z.string().optional(),data:z.object({assignedPhoneNumber:z.string().optional(),phoneNumber:z.string().optional(),user:z.object({assignedPhoneNumber:z.string().optional(),phoneNumber:z.string().optional()}).optional()}).optional(),user:z.object({assignedPhoneNumber:z.string().optional(),phoneNumber:z.string().optional()}).optional()}),defaultDeps={fetch,delay:(e,n)=>setTimeout(e,void 0,{signal:n})};function errorDetail(e,t){let n=ErrorResponseSchema.safeParse(e);return String(n.success?n.data.error??n.data.message??t:t)}function parsePhotonResponse(e,t,n){let r=e.safeParse(t);if(!r.success)throw Error(n);return r.data}async function json(e,t){let n=await e.json().catch(()=>void 0);if(!e.ok)throw Error(`Photon ${t} failed: ${errorDetail(n,e.statusText)}`);return n}function bearer(e){return{authorization:`Bearer ${e}`,"content-type":`application/json`}}function basic(e,t){return{authorization:`Basic ${Buffer.from(`${e}:${t}`).toString(`base64`)}`,"content-type":`application/json`}}async function requestDeviceCode(e){let t=await e.fetch(`${PHOTON_DASHBOARD_HOST}/api/auth/device/code`,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({client_id:PHOTON_DEVICE_CLIENT_ID,scope:`openid profile email`})}),i=parsePhotonResponse(DeviceAuthorizationSchema,await json(t,`device login`),`Photon returned an invalid device authorization response.`),o=i.verification_uri_complete??i.verification_uri;if(o===void 0)throw Error(`Photon returned an invalid device authorization response.`);return{deviceCode:i.device_code,userCode:i.user_code,verificationUrl:o,expiresIn:i.expires_in??1800,interval:i.interval??5}}async function pollForToken(e,t,i){let a=Date.now()+e.expiresIn*1e3,s=e.interval*1e3;for(;Date.now()<a;){await t.delay(s,i);let a=await t.fetch(`${PHOTON_DASHBOARD_HOST}/api/auth/device/token`,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({grant_type:`urn:ietf:params:oauth:grant-type:device_code`,device_code:e.deviceCode,client_id:PHOTON_DEVICE_CLIENT_ID}),signal:i}),c=await a.json().catch(()=>void 0);if(a.ok){let e=parsePhotonResponse(DeviceTokenSchema,c,`Photon approved device login without returning an access token.`);if(e.access_token!==void 0)return e.access_token;if(e.accessToken!==void 0)return e.accessToken;throw Error(`Photon approved device login without returning an access token.`)}let l=ErrorResponseSchema.safeParse(c),u=l.success?l.data.error??l.data.message:void 0;if(u!==`authorization_pending`){if(u===`slow_down`||a.status===429){s+=a.status===429?1e4:5e3;continue}throw Error(`Photon device login failed: ${String(u??a.statusText)}`)}}throw Error(`Photon device login timed out.`)}async function createProject(e,t,r){let i=await r.fetch(`${PHOTON_DASHBOARD_HOST}/api/projects`,{method:`POST`,headers:bearer(e),body:JSON.stringify({name:t,location:`United States`,platforms:[`imessage`],template:!1,observability:!1})});return parsePhotonResponse(ProjectSchema,await json(i,`project creation`),`Photon did not return a project ID.`).id}async function regenerateSecret(e,t,r){let i=await r.fetch(`${PHOTON_DASHBOARD_HOST}/api/projects/${encodeURIComponent(t)}/regenerate-secret`,{method:`POST`,headers:bearer(e),body:`{}`});return parsePhotonResponse(ProjectSecretSchema,await json(i,`project credential provisioning`),`Photon did not return the new project secret.`).projectSecret}async function registerUser(e,t,n,r){let i=await r.fetch(`https://spectrum.photon.codes/projects/${encodeURIComponent(e)}/users/`,{method:`POST`,headers:basic(e,t),body:JSON.stringify({type:`shared`,phoneNumber:n})}),a=parsePhotonResponse(PhoneRegistrationSchema,await json(i,`phone registration`),`Photon returned an invalid phone registration response.`);return a.data?.user?.assignedPhoneNumber??a.data?.user?.phoneNumber??a.data?.assignedPhoneNumber??a.data?.phoneNumber??a.user?.assignedPhoneNumber??a.user?.phoneNumber??a.assignedPhoneNumber??a.phoneNumber}async function deleteProject(e,t,r){let i=await r.fetch(`${PHOTON_DASHBOARD_HOST}/api/projects/${encodeURIComponent(t)}`,{method:`DELETE`,headers:bearer(e)});!i.ok&&i.status!==404&&await json(i,`project cleanup`)}async function provisionPhotonProject(e){let t=e.phoneNumber.trim(),n=validatePhotonPhoneNumber(t);if(n!==null)throw Error(`Photon phone number is invalid. ${n}.`);let r=e.deps??defaultDeps,i=await requestDeviceCode(r);e.onAuthorization({userCode:i.userCode,verificationUrl:i.verificationUrl});let a=await pollForToken(i,r,e.signal),o=await createProject(a,e.projectName,r),cleanup=()=>deleteProject(a,o,r);try{let e=await regenerateSecret(a,o,r),n=await registerUser(o,e,t,r);return n===void 0?{projectId:o,projectSecret:e,cleanup}:{projectId:o,projectSecret:e,assignedPhoneNumber:n,cleanup}}catch(e){throw await cleanup().catch(()=>{}),e}}async function usePhotonProject(e){let t=e.phoneNumber.trim(),n=validatePhotonPhoneNumber(t);if(n!==null)throw Error(`Photon phone number is invalid. ${n}.`);let r=e.projectId.trim(),i=e.projectSecret.trim();if(!r||!i)throw Error(`Photon project ID and project secret are required.`);let a=await registerUser(r,i,t,e.deps??defaultDeps),cleanup=async()=>{};return a===void 0?{projectId:r,projectSecret:i,cleanup}:{projectId:r,projectSecret:i,assignedPhoneNumber:a,cleanup}}export{provisionPhotonProject,usePhotonProject,validatePhotonPhoneNumber};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { appendEnv } from "../../append-env.js";
|
|
2
|
+
import { provisionPhotonConnector } from "./connect.js";
|
|
3
|
+
import { provisionPhotonProject, usePhotonProject } from "./management.js";
|
|
4
|
+
import { openUrl } from "../../primitives/open-url.js";
|
|
5
|
+
import { deriveSlackConnectorSlug } from "../../scaffold/index.js";
|
|
6
|
+
import { writeTextFile } from "../../scaffold/files.js";
|
|
7
|
+
import type { IntegrationSetupEnvironment } from "../shared/environment.js";
|
|
8
|
+
import type { IntegrationSetupUi } from "../shared/ui.js";
|
|
9
|
+
import { ensureVercelProject } from "../../flows/ensure-vercel-project.js";
|
|
10
|
+
/** Inputs for Photon project provisioning and channel scaffolding. */
|
|
11
|
+
export interface PhotonSetupOptions {
|
|
12
|
+
agentName: string;
|
|
13
|
+
projectPath: string;
|
|
14
|
+
environment: IntegrationSetupEnvironment;
|
|
15
|
+
ui: IntegrationSetupUi;
|
|
16
|
+
signal?: AbortSignal;
|
|
17
|
+
force?: boolean;
|
|
18
|
+
deps?: PhotonSetupDeps;
|
|
19
|
+
}
|
|
20
|
+
/** Outcome of Photon project provisioning and channel scaffolding. */
|
|
21
|
+
export type PhotonSetupResult = {
|
|
22
|
+
kind: "done";
|
|
23
|
+
assignedPhoneNumber?: string;
|
|
24
|
+
dashboardUrl: string;
|
|
25
|
+
} | {
|
|
26
|
+
kind: "cancelled";
|
|
27
|
+
};
|
|
28
|
+
export interface PhotonSetupDeps {
|
|
29
|
+
appendEnv: typeof appendEnv;
|
|
30
|
+
deriveConnectorSlug: typeof deriveSlackConnectorSlug;
|
|
31
|
+
ensureVercelProject: typeof ensureVercelProject;
|
|
32
|
+
openUrl: typeof openUrl;
|
|
33
|
+
provisionConnector: typeof provisionPhotonConnector;
|
|
34
|
+
provisionProject: typeof provisionPhotonProject;
|
|
35
|
+
useProject: typeof usePhotonProject;
|
|
36
|
+
writeTextFile: typeof writeTextFile;
|
|
37
|
+
}
|
|
38
|
+
/** Provisions a Photon project and scaffolds its iMessage channel. */
|
|
39
|
+
export declare function setupPhoton(options: PhotonSetupOptions): Promise<PhotonSetupResult>;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import{appendEnv}from"../../append-env.js";import{text}from"../../ask.js";import{writeTextFile}from"../../scaffold/files.js";import{deriveSlackConnectorSlug}from"../../scaffold/update/channels.js";import"../../scaffold/index.js";import{WizardCancelledError}from"../../step.js";import{ensureVercelProject}from"../../flows/ensure-vercel-project.js";import{provisionPhotonConnector}from"./connect.js";import{provisionPhotonProject,usePhotonProject,validatePhotonPhoneNumber}from"./management.js";import{openUrl}from"../../primitives/open-url.js";import{join}from"node:path";const defaultDeps={appendEnv,deriveConnectorSlug:deriveSlackConnectorSlug,ensureVercelProject,openUrl,provisionConnector:provisionPhotonConnector,provisionProject:provisionPhotonProject,useProject:usePhotonProject,writeTextFile};function connectTemplate(e){return`import { connectPhotonCredentials } from "@vercel/connect/eve";
|
|
2
|
+
import { photonIMessageChannel } from "eve/channels/photon";
|
|
3
|
+
|
|
4
|
+
export default photonIMessageChannel({
|
|
5
|
+
credentials: connectPhotonCredentials(${JSON.stringify(e)}),
|
|
6
|
+
});
|
|
7
|
+
`}async function choosePhotonProject(e){let n=`eve · ${e.agentName||`agent`}`,r=[{value:`create`,label:`Create a new Photon project`,hint:`Name: ${n}`},{value:`existing`,label:`Use an existing Photon project`,hint:`Enter its project credentials`}],i=e.ui.prompter.selectEditable?await e.ui.prompter.selectEditable({message:`Photon project`,options:r,initialValue:`create`,editable:{value:`create`,defaultValue:n,formatHint:e=>`Name: ${e}`,validate:e=>e.trim().length===0?`Project name cannot be empty.`:void 0}}):void 0;if((i?.value??await e.ui.prompter.select({message:`Photon project`,options:r,initialValue:`create`}))===`existing`){let n=await e.ui.asker.ask(text({key:`photon-project-id`,message:`Photon project ID`,required:!0})),r=await e.ui.asker.ask(text({key:`photon-project-secret`,message:`Photon project secret`,required:!0,sensitive:!0}));return{photonProject:{projectId:n.trim(),projectSecret:r.trim()}}}return{photonProject:`create`,photonProjectName:i?.kind===`edited`?i.text.trim():n}}async function chooseSetupPlan(e){try{let t=await e.ui.prompter.select({message:`How would you like to configure Photon?`,options:[{value:`vercel`,label:`Set up Vercel Connect`,hint:e.environment.vercel.kind===`available`?`Link this project and configure Photon automatically`:`Log in to Vercel and link this project`},{value:`portable`,label:`Use portable credentials`,hint:`Configure the Photon webhook manually after deployment`}],initialValue:e.environment.vercel.kind===`available`?`vercel`:`portable`});if(t===`vercel`&&e.environment.vercel.kind===`unavailable`)throw Error("Vercel Connect requires an authenticated Vercel CLI. Run `vercel login`, then retry Photon setup.");let n=await choosePhotonProject(e);return{credentials:t===`vercel`?`vercel-connect`:`environment`,...n}}catch(e){if(e instanceof WizardCancelledError)return`cancelled`;throw e}}async function resolvePhotonProject(e,t,n,r){if(t.photonProject!==`create`)return r.useProject({...t.photonProject,phoneNumber:n});let i=e.ui.prompter.log.spinner?.(`Waiting for Photon approval…`,{kind:`external-action`,emphasis:`browser`});try{return await r.provisionProject({projectName:t.photonProjectName??`eve · ${e.agentName||`agent`}`,phoneNumber:n,signal:e.signal,onAuthorization(t){e.ui.prompter.log.message(`Authorize Photon: ${t.verificationUrl}`),e.ui.prompter.log.message(`Photon code: ${t.userCode}`),r.openUrl(t.verificationUrl)}})}finally{i?.stop()}}async function scaffoldPhoton(e,n,r){let i=await e.ui.asker.ask(text({key:`photon-phone-number`,message:`Your iMessage phone number`,placeholder:`+15551234567`,required:!0,validate:validatePhotonPhoneNumber})),a=e.projectPath,o=await resolvePhotonProject(e,n,i,r);try{let t=join(a,`agent/channels/photon.ts`);if(n.credentials===`vercel-connect`){let n=await r.deriveConnectorSlug(a,e.agentName),i=await r.ensureVercelProject({appRoot:a,prompter:e.ui.prompter,signal:e.signal}),s=await r.provisionConnector({credentials:o,log:e.ui.prompter.log,project:i,projectRoot:a,slug:n,signal:e.signal});await r.writeTextFile(t,connectTemplate(s.uid),{force:e.force})}else await r.appendEnv(join(a,`.env.local`),{IMESSAGE_PROJECT_ID:o.projectId,IMESSAGE_PROJECT_SECRET:o.projectSecret}),await r.writeTextFile(t,`import { photonIMessageChannel } from "eve/channels/photon";
|
|
8
|
+
|
|
9
|
+
async function photonCredentials() {
|
|
10
|
+
const projectId = process.env.IMESSAGE_PROJECT_ID;
|
|
11
|
+
const projectSecret = process.env.IMESSAGE_PROJECT_SECRET;
|
|
12
|
+
if (!projectId || !projectSecret) throw new Error("Photon project credentials are required.");
|
|
13
|
+
return { projectId, projectSecret };
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export default photonIMessageChannel({
|
|
17
|
+
credentials: photonCredentials,
|
|
18
|
+
webhookSecret: process.env.IMESSAGE_WEBHOOK_SECRET,
|
|
19
|
+
});
|
|
20
|
+
`,{force:e.force}),e.ui.nextSteps([`Deploy the agent, then create a Photon webhook pointing to https://<your-host>/eve/v1/photon.`,`Copy the webhook signing secret into IMESSAGE_WEBHOOK_SECRET, alongside IMESSAGE_PROJECT_ID and IMESSAGE_PROJECT_SECRET, in your host's encrypted environment variables.`]);e.ui.prompter.log.success(`Scaffolded channel: photon`),o.assignedPhoneNumber!==void 0&&e.ui.prompter.note(o.assignedPhoneNumber,`Text your agent`,{tone:`success`});let i=`https://app.photon.codes/dashboard/${o.projectId}`;return e.ui.prompter.note(i,`Photon project`,{tone:`success`}),o.assignedPhoneNumber===void 0?{dashboardUrl:i}:{assignedPhoneNumber:o.assignedPhoneNumber,dashboardUrl:i}}catch(e){throw await o.cleanup().catch(()=>{}),e}}async function setupPhoton(e){try{let t=await chooseSetupPlan(e);return t===`cancelled`?{kind:`cancelled`}:{kind:`done`,...await scaffoldPhoton(e,t,e.deps??defaultDeps)}}catch(e){if(e instanceof WizardCancelledError)return{kind:`cancelled`};throw e}}export{setupPhoton};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{setupPhoton}from"./setup-flow.js";import{basename}from"node:path";const PHOTON_SETUP={kind:`photon`,label:`Photon`,hint:`Messages through Photon`,async setup(e){let t=await setupPhoton({agentName:basename(e.appRoot),projectPath:e.appRoot,environment:e.environment,ui:e.ui,signal:e.signal,force:e.force});return t.kind===`cancelled`?t:{kind:`done`,facts:[...t.assignedPhoneNumber===void 0?[]:[{label:`Text your agent`,value:t.assignedPhoneNumber,kind:`phone`}],{label:`Photon project`,value:t.dashboardUrl,kind:`url`}]}}};export{PHOTON_SETUP};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { SetupIntegration } from "./types.js";
|
|
2
|
+
/** Built-in registry setup integrations in canonical picker order. */
|
|
3
|
+
export declare const SETUP_INTEGRATIONS: readonly SetupIntegration[];
|
|
4
|
+
/** Resolves one built-in setup integration by its registry setup name. */
|
|
5
|
+
export declare function setupIntegration(kind: string): SetupIntegration;
|
|
6
|
+
export { createIntegrationSetupUi } from "./shared/ui.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{DISCORD_SETUP}from"./discord/setup.js";import{PHOTON_SETUP}from"./photon/setup.js";import{SLACK_SETUP}from"./slack/setup.js";import{WEB_SETUP}from"./web/setup.js";import{createIntegrationSetupUi}from"./shared/ui.js";const SETUP_INTEGRATIONS=[WEB_SETUP,SLACK_SETUP,DISCORD_SETUP,PHOTON_SETUP];function setupIntegration(e){let t=SETUP_INTEGRATIONS.find(t=>t.kind===e);if(t===void 0)throw Error(`Integration setup "${e}" is not available in this version of eve. Upgrade eve and try again.`);return t}export{SETUP_INTEGRATIONS,createIntegrationSetupUi,setupIntegration};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { RegistrySetupFact } from "#setup/registry-setup-protocol.js";
|
|
2
|
+
import { detectDeployment } from "#setup/project-resolution.js";
|
|
3
|
+
import type { Prompter } from "#setup/prompter.js";
|
|
4
|
+
import { getVercelAuthStatus } from "#setup/vercel-project.js";
|
|
5
|
+
/** Inputs shared by every registry-owned integration setup flow. */
|
|
6
|
+
export interface RunIntegrationSetupOptions {
|
|
7
|
+
appRoot: string;
|
|
8
|
+
prompter: Prompter;
|
|
9
|
+
signal?: AbortSignal;
|
|
10
|
+
yes?: boolean;
|
|
11
|
+
}
|
|
12
|
+
/** Effects shared by the built-in integration setup runner. */
|
|
13
|
+
export interface IntegrationSetupRunnerDeps {
|
|
14
|
+
detectDeployment: typeof detectDeployment;
|
|
15
|
+
getVercelAuthStatus: typeof getVercelAuthStatus;
|
|
16
|
+
}
|
|
17
|
+
/** Outcome returned by one registry-owned integration setup flow. */
|
|
18
|
+
export type IntegrationSetupOutcome = {
|
|
19
|
+
kind: "cancelled";
|
|
20
|
+
} | {
|
|
21
|
+
kind: "done";
|
|
22
|
+
facts?: readonly RegistrySetupFact[];
|
|
23
|
+
};
|
|
24
|
+
/** Runs one built-in integration setup flow selected by its registry setup name. */
|
|
25
|
+
export declare function runIntegrationSetup(kind: string, options: RunIntegrationSetupOptions, deps?: IntegrationSetupRunnerDeps): Promise<IntegrationSetupOutcome>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{createIntegrationSetupUi}from"./shared/ui.js";import{setupIntegration}from"./registry.js";import{describeIntegrationSetupEnvironment,integrationSetupEnvironment}from"./shared/environment.js";import{detectDeployment,projectResolutionFromDeployment}from"#setup/project-resolution.js";import{getVercelAuthStatus}from"#setup/vercel-project.js";import{interactiveAsker}from"#setup/ask.js";const defaultDeps={detectDeployment,getVercelAuthStatus};async function runIntegrationSetup(e,t,n=defaultDeps){let r=setupIntegration(e);t.prompter.intro(`Set up ${r.label}`),t.prompter.log.message(`Checking Vercel setup...`);let[i,a]=await Promise.all([n.detectDeployment(t.appRoot,{signal:t.signal}),n.getVercelAuthStatus(t.appRoot,{signal:t.signal})]),o=integrationSetupEnvironment(a,projectResolutionFromDeployment(i));return t.prompter.log.info(describeIntegrationSetupEnvironment(o)),await r.setup({environment:o,appRoot:t.appRoot,ui:createIntegrationSetupUi({asker:interactiveAsker(t.prompter),prompter:t.prompter}),yes:t.yes,signal:t.signal})}export{runIntegrationSetup};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ProjectResolution } from "../../project-resolution.js";
|
|
2
2
|
import type { VercelAuthStatus } from "../../vercel-project.js";
|
|
3
3
|
/** Read-only hosting facts available to channel-owned setup hooks. */
|
|
4
|
-
export interface
|
|
4
|
+
export interface IntegrationSetupEnvironment {
|
|
5
5
|
vercel: {
|
|
6
6
|
kind: "available";
|
|
7
7
|
project: ProjectResolution;
|
|
@@ -11,6 +11,6 @@ export interface ChannelSetupEnvironment {
|
|
|
11
11
|
};
|
|
12
12
|
}
|
|
13
13
|
/** Describes the result of the read-only Vercel capability probe. */
|
|
14
|
-
export declare function
|
|
14
|
+
export declare function describeIntegrationSetupEnvironment(environment: IntegrationSetupEnvironment): string;
|
|
15
15
|
/** Builds channel setup facts from the independent Vercel probes. */
|
|
16
|
-
export declare function
|
|
16
|
+
export declare function integrationSetupEnvironment(authStatus: VercelAuthStatus, project: ProjectResolution): IntegrationSetupEnvironment;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function describeIntegrationSetupEnvironment(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 integrationSetupEnvironment(e,t){return e===`authenticated`?{vercel:{kind:`available`,project:t}}:{vercel:{kind:`unavailable`,reason:e}}}export{describeIntegrationSetupEnvironment,integrationSetupEnvironment};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type ChannelSetupLog } from "#setup/cli/index.js";
|
|
2
|
+
import { detectPackageManager } from "#setup/package-manager.js";
|
|
3
|
+
import { runPackageManagerInstall } from "#setup/primitives/pm/run.js";
|
|
4
|
+
/** Effects used to install dependencies added by an integration scaffold. */
|
|
5
|
+
export interface IntegrationScaffoldDeps {
|
|
6
|
+
detectPackageManager: typeof detectPackageManager;
|
|
7
|
+
runPackageManagerInstall: typeof runPackageManagerInstall;
|
|
8
|
+
}
|
|
9
|
+
/** Installs dependencies added by an integration scaffold without failing setup if installation fails. */
|
|
10
|
+
export declare function installScaffoldDependencies(input: {
|
|
11
|
+
changed: boolean;
|
|
12
|
+
log: ChannelSetupLog;
|
|
13
|
+
projectPath: string;
|
|
14
|
+
signal?: AbortSignal;
|
|
15
|
+
skip?: boolean;
|
|
16
|
+
deps?: IntegrationScaffoldDeps;
|
|
17
|
+
}): Promise<void>;
|
|
18
|
+
/** Reports files overwritten by one integration scaffold. */
|
|
19
|
+
export declare function reportOverwrittenFiles(log: ChannelSetupLog, files: readonly string[] | undefined): void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{detectPackageManager}from"#setup/package-manager.js";import{createPromptCommandOutput,withPhase}from"#setup/cli/index.js";import{runPackageManagerInstall}from"#setup/primitives/pm/run.js";const defaultDeps={detectPackageManager,runPackageManagerInstall};async function installScaffoldDependencies(e){if(!e.changed||e.skip)return;let r=e.deps??defaultDeps,i=await r.detectPackageManager(e.projectPath);await withPhase(e.log,`Installing channel dependencies (${i.kind} install)...`,()=>r.runPackageManagerInstall(i.kind,e.projectPath,{onOutput:createPromptCommandOutput(e.log),signal:e.signal}))||e.log.warning(`Dependency installation failed. The new channel stays unloadable until \`${i.kind} install\` or a deploy succeeds.`)}function reportOverwrittenFiles(e,t){for(let n of t??[])e.warning(`Overwrote ${n}`)}export{installScaffoldDependencies,reportOverwrittenFiles};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type Asker } from "../../ask.js";
|
|
2
2
|
import type { Prompter } from "../../prompter.js";
|
|
3
3
|
/** UI capabilities available to a channel-owned setup hook. */
|
|
4
|
-
export interface
|
|
4
|
+
export interface IntegrationSetupUi {
|
|
5
5
|
readonly asker: Asker;
|
|
6
6
|
readonly prompter: Prompter;
|
|
7
7
|
confirm(input: {
|
|
@@ -12,7 +12,7 @@ export interface ChannelSetupUi {
|
|
|
12
12
|
nextSteps(lines: readonly string[]): void;
|
|
13
13
|
}
|
|
14
14
|
/** Adapts the shared setup asker and prompter to the channel hook UI. */
|
|
15
|
-
export declare function
|
|
15
|
+
export declare function createIntegrationSetupUi(input: {
|
|
16
16
|
asker: Asker;
|
|
17
17
|
prompter: Prompter;
|
|
18
|
-
}):
|
|
18
|
+
}): IntegrationSetupUi;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{SkippedSignal,confirm}from"../../ask.js";function createIntegrationSetupUi(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{createIntegrationSetupUi};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { deriveSlackConnectorSlug, ensureChannel } from "#setup/scaffold/index.js";
|
|
2
|
+
import { ensureVercelProject } from "#setup/flows/ensure-vercel-project.js";
|
|
3
|
+
import { provisionSlackbot, reconcileSlackUid } from "#setup/slackbot.js";
|
|
4
|
+
import type { IntegrationSetupContext, IntegrationSetupResult, SetupIntegration } from "../types.js";
|
|
5
|
+
/** Effects used by Slack setup. */
|
|
6
|
+
export interface SlackSetupDeps {
|
|
7
|
+
deriveSlackConnectorSlug: typeof deriveSlackConnectorSlug;
|
|
8
|
+
ensureChannel: typeof ensureChannel;
|
|
9
|
+
ensureVercelProject: typeof ensureVercelProject;
|
|
10
|
+
provisionSlackbot: typeof provisionSlackbot;
|
|
11
|
+
reconcileSlackUid: typeof reconcileSlackUid;
|
|
12
|
+
}
|
|
13
|
+
/** Runs the Slack setup flow. Exported for direct integration tests. */
|
|
14
|
+
export declare function setupSlack(context: IntegrationSetupContext, deps?: SlackSetupDeps): Promise<IntegrationSetupResult>;
|
|
15
|
+
/** Slack setup registration. */
|
|
16
|
+
export declare const SLACK_SETUP: SetupIntegration;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{installScaffoldDependencies,reportOverwrittenFiles}from"../shared/scaffold.js";import{deriveSlackConnectorSlug,ensureChannel}from"#setup/scaffold/index.js";import{WizardCancelledError}from"#setup/step.js";import{ensureVercelProject}from"#setup/flows/ensure-vercel-project.js";import{provisionSlackbot,reconcileSlackUid}from"#setup/slackbot.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:"Re-run `eve add channel/slack` after the workspace install is complete."};case`cleanup-failed`:return{reason:`The abandoned Slack connector could not be removed. Slack channel was not added.`,followUp:`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:"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:"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:`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:"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:"Finish event delivery with the `vercel connect attach` command above."};case`create-failed`:return{reason:`Slackbot creation failed.`,followUp:"Add it later with `eve add channel/slack`."}}}const defaultDeps={deriveSlackConnectorSlug,ensureChannel,ensureVercelProject,provisionSlackbot,reconcileSlackUid};async function chooseCredentials(e){if(e.yes)return`vercel-connect`;try{return await e.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(e){if(e instanceof WizardCancelledError)return`cancelled`;throw e}}async function provisionSlack(e,t,n){let r={selectConnector:async(t,n)=>{if(e.yes)return n??t[0];let r=await e.ui.prompter.select({message:`Which Slack app would you like to use?`,options:[...t.map(e=>{let t={value:e.uid,label:`Use ${e.uid}`};return e.uid===n?.uid&&(t.hint=`Matches this agent`),t}),{value:`create`,label:`Create a new Slack app`}],initialValue:n?.uid});return r===`create`?`create`:t.find(e=>e.uid===r)}};e.signal!==void 0&&(r.signal=e.signal),e.ui.prompter.awaitChoice!==void 0&&(r.awaitChoice=e.ui.prompter.awaitChoice);let a=await t.provisionSlackbot(e.ui.prompter.log,e.appRoot,n,void 0,r);if(e.signal?.throwIfAborted(),a.state===`cancelled`)throw new WizardCancelledError;if(a.state!==`attached`){let e=slackbotFailureCopy(a);throw Error(`${e.reason} ${e.followUp}`)}return a}async function setupSlack(n,r=defaultDeps){let i=await chooseCredentials(n);if(i===`cancelled`)return{kind:`cancelled`};if(i===`vercel-connect`&&n.environment.vercel.kind===`unavailable`)throw Error("Vercel Connect requires an authenticated Vercel CLI. Run `vercel login`, then retry Slack setup.");let a=await r.deriveSlackConnectorSlug(n.appRoot);if(i===`environment`){let e=await r.ensureChannel({projectRoot:n.appRoot,kind:`slack`,slackConnectorSlug:a,slackCredentials:`environment`,force:n.force,skipDependencyMutation:!0});return reportOverwrittenFiles(n.ui.prompter.log,e.filesOverwritten),n.ui.prompter.log.success(`Scaffolded channel: slack`),n.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.`]),{kind:`done`}}if((await r.ensureVercelProject({appRoot:n.appRoot,prompter:n.ui.prompter,signal:n.signal})).projectId.length===0)throw Error(`Slack setup with Vercel Connect requires a linked Vercel project.`);let o=await provisionSlack(n,r,a),s=await r.ensureChannel({projectRoot:n.appRoot,kind:`slack`,slackConnectorUid:o.connectorUid,slackConnectorSlug:a,force:n.force,skipDependencyMutation:!0});if(reportOverwrittenFiles(n.ui.prompter.log,s.filesOverwritten),s.action===`skipped`&&!await r.reconcileSlackUid(n.ui.prompter.log,n.appRoot,o,`slack/${a}`))throw Error(`Slack connector UID update is required before deployment.`);return n.ui.prompter.log.success(`Scaffolded channel: slack`),await installScaffoldDependencies({changed:s.packageJsonUpdated.length>0,log:n.ui.prompter.log,projectPath:n.appRoot,signal:n.signal}),{kind:`done`}}const SLACK_SETUP={kind:`slack`,label:`Slack`,hint:`Slack app mentions and DMs`,setup:setupSlack};export{SLACK_SETUP,setupSlack};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { RegistrySetupFact } from "#setup/registry-setup-protocol.js";
|
|
2
|
+
import type { IntegrationSetupEnvironment } from "./shared/environment.js";
|
|
3
|
+
import type { IntegrationSetupUi } from "./shared/ui.js";
|
|
4
|
+
/** Inputs available to one registry-owned integration setup flow. */
|
|
5
|
+
export interface IntegrationSetupContext {
|
|
6
|
+
readonly appRoot: string;
|
|
7
|
+
readonly environment: IntegrationSetupEnvironment;
|
|
8
|
+
readonly ui: IntegrationSetupUi;
|
|
9
|
+
readonly signal?: AbortSignal;
|
|
10
|
+
readonly force?: boolean;
|
|
11
|
+
readonly yes?: boolean;
|
|
12
|
+
}
|
|
13
|
+
/** Outcome from one registry-owned integration setup flow. */
|
|
14
|
+
export type IntegrationSetupResult = {
|
|
15
|
+
readonly kind: "done";
|
|
16
|
+
readonly facts?: readonly RegistrySetupFact[];
|
|
17
|
+
} | {
|
|
18
|
+
readonly kind: "cancelled";
|
|
19
|
+
};
|
|
20
|
+
/** One built-in registry-owned integration setup flow. */
|
|
21
|
+
export interface SetupIntegration {
|
|
22
|
+
readonly kind: string;
|
|
23
|
+
readonly label: string;
|
|
24
|
+
readonly hint?: string;
|
|
25
|
+
setup(context: IntegrationSetupContext): Promise<IntegrationSetupResult>;
|
|
26
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export{};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{installScaffoldDependencies,reportOverwrittenFiles}from"../shared/scaffold.js";import{ensureChannel}from"#setup/scaffold/index.js";import{formatNodeEngineOverrideWarning}from"#setup/node-engine.js";import{detectPackageManager}from"#setup/package-manager.js";function reportCompetingNextConfigFiles(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.`)}const WEB_SETUP={kind:`web`,label:`Web Chat`,hint:`Browser-based chat interface`,async setup(r){r.ui.prompter.log.message(`Scaffolding Web Chat channel files...`);let i=await ensureChannel({projectRoot:r.appRoot,kind:`web`,packageManager:(await detectPackageManager(r.appRoot)).kind,configureVercelServices:r.environment.vercel.kind===`available`,force:r.force,skipDependencyMutation:!0});return reportOverwrittenFiles(r.ui.prompter.log,i.filesOverwritten),i.kind===`web`&&i.action!==`skipped`&&i.nodeEngineOverride!==void 0&&r.ui.prompter.log.warning(formatNodeEngineOverrideWarning(i.nodeEngineOverride)),reportCompetingNextConfigFiles(r.ui.prompter.log,`competingNextConfigFiles`in i?i.competingNextConfigFiles:void 0),i.action===`skipped`?(r.ui.prompter.log.info(`Next.js project detected. Skipping Web Chat scaffolding.`),{kind:`done`}):(r.ui.prompter.log.success(`Scaffolded channel: web`),await installScaffoldDependencies({changed:i.packageJsonUpdated.length>0,log:r.ui.prompter.log,projectPath:r.appRoot,signal:r.signal}),{kind:`done`})}};export{WEB_SETUP};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{pathExists}from"./path-exists.js";import{
|
|
1
|
+
import{pathExists}from"./path-exists.js";import{readFile}from"node:fs/promises";import{dirname,join,resolve}from"node:path";const LOCKFILE_MANAGERS=[[`pnpm-lock.yaml`,`pnpm`],[`pnpm-workspace.yaml`,`pnpm`],[`package-lock.json`,`npm`],[`yarn.lock`,`yarn`],[`bun.lock`,`bun`],[`bun.lockb`,`bun`]];function isPackageManagerKind(e){return e===`bun`||e===`npm`||e===`pnpm`||e===`yarn`}function resolvePackageManager(e){let t=e.packageManagerField?.split(`@`,1)[0]?.trim();if(t!==void 0&&isPackageManagerKind(t))return{kind:t,source:`package-manager-field`};for(let[t,n]of LOCKFILE_MANAGERS)if(e.lockfiles.includes(t))return{kind:n,source:`lockfile`};return{kind:`pnpm`,source:`default`}}function packageManagerFromUserAgent(e){let t=e?.split(`/`,1)[0];return t!==void 0&&isPackageManagerKind(t)?t:void 0}function detectInvokingPackageManager(){return packageManagerFromUserAgent(process.env.npm_config_user_agent)}async function detectPackageManagerInDirectory(n){let i;try{let e=JSON.parse(await readFile(join(n,`package.json`),`utf8`));typeof e==`object`&&e&&`packageManager`in e&&typeof e.packageManager==`string`&&(i=e.packageManager)}catch{}let a=[];for(let[t]of LOCKFILE_MANAGERS)await pathExists(join(n,t))&&a.push(t);let o=resolvePackageManager({packageManagerField:i,lockfiles:a});return o.source==="default"?void 0:o}async function detectAncestorPackageManager(e){let t=dirname(resolve(e));for(;;){let e=await detectPackageManagerInDirectory(t);if(e!==void 0)return e;let r=dirname(t);if(r===t)return;t=r}}async function detectPackageManager(e){return await detectPackageManagerInDirectory(resolve(e))??await detectAncestorPackageManager(e)??{kind:`pnpm`,source:`default`}}export{detectInvokingPackageManager,detectPackageManager,packageManagerFromUserAgent,resolvePackageManager};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{pathExists}from"../../path-exists.js";import{workspacePatternForProject,workspacePatternsClaimProject}from"../../scaffold/workspace-glob.js";import{existsSync,readFileSync,realpathSync}from"node:fs";import{dirname,extname,join,resolve}from"node:path";
|
|
1
|
+
import{pathExists}from"../../path-exists.js";import{workspacePatternForProject,workspacePatternsClaimProject}from"../../scaffold/workspace-glob.js";import{readFile,writeFile}from"node:fs/promises";import{existsSync,readFileSync,realpathSync}from"node:fs";import{dirname,extname,join,resolve}from"node:path";const PNPM_WORKSPACE_PATH=`pnpm-workspace.yaml`,PNPM_WORKSPACE_MEMBERSHIP_ARGUMENTS=[`list`,`--depth`,`-1`,`--json`],RELEASE_AGE_EXCLUSIONS=[`@ai-sdk/*`,`@rolldown/*`,`@vercel/*`,`@workflow/*`,`ai`,`experimental-ai-sdk-code-mode`,`eve`,`nitro`,`rolldown`,`workflow`];function formatReleaseAgeExclusion(e){return` - ${e.includes(`*`)?JSON.stringify(e):e}`}const PNPM_WORKSPACE_CONTENT=[`minimumReleaseAgeExclude:`,...RELEASE_AGE_EXCLUSIONS.map(formatReleaseAgeExclusion),`allowBuilds:`,` sharp: false`,`# Compatibility for eve releases with an incomplete runtime manifest.`,`packageExtensions:`,` "eve@>=0.6.0-beta.13 <=0.7.0":`,` dependencies:`,` oxc-parser: 0.134.0`,``].join(`
|
|
2
2
|
`),SHARP_BUILD_POLICY=` sharp: false`;function releaseAgeExclusionName(e){return e.trim().replace(/^-\s+/u,``).replace(/^["']|["']$/gu,``)}function findYamlBlockEnd(e,t){let n=t+1;for(;n<e.length;){let t=e[n]??``;if(t.length>0&&!t.startsWith(` `)&&!t.startsWith(` `))break;n+=1}return n}function withSharpBuildPolicy(e){let t=e.endsWith(`
|
|
3
3
|
`)?e:`${e}\n`,n=t.split(`
|
|
4
4
|
`),r=n.findIndex(e=>e===`allowBuilds:`);if(r<0)return`${t.trim().length===0?``:`${t}\n`}allowBuilds:\n${SHARP_BUILD_POLICY}\n`;let i=findYamlBlockEnd(n,r);if(n.slice(r+1,i).some(e=>/^\s+sharp:/.test(e)))return e;let a=i;for(;a>r+1&&n[a-1]===``;)--a;return n.splice(a,0,SHARP_BUILD_POLICY),n.join(`
|
|
@@ -6,7 +6,7 @@ import{pathExists}from"../../path-exists.js";import{workspacePatternForProject,w
|
|
|
6
6
|
`)?e:`${e}\n`,n=t.split(`
|
|
7
7
|
`),r=n.findIndex(e=>e===`minimumReleaseAgeExclude:`);if(r<0)return`${t.trim().length===0?``:`${t}\n`}minimumReleaseAgeExclude:\n${RELEASE_AGE_EXCLUSIONS.map(formatReleaseAgeExclusion).join(`
|
|
8
8
|
`)}\n`;let i=findYamlBlockEnd(n,r),a=n.slice(r+1,i),o=new Set(a.map(releaseAgeExclusionName)),s=RELEASE_AGE_EXCLUSIONS.filter(e=>!o.has(e));if(s.length===0)return e;let c=i;for(;c>r+1&&n[c-1]===``;)--c;return n.splice(c,0,...s.map(formatReleaseAgeExclusion)),n.join(`
|
|
9
|
-
`)}async function ensurePnpmWorkspacePolicy(t){if(!await pathExists(t))return await writeFile(t,PNPM_WORKSPACE_CONTENT,`utf8`),`written`;let n=await readFile(t,`utf8`),
|
|
9
|
+
`)}async function ensurePnpmWorkspacePolicy(t){if(!await pathExists(t))return await writeFile(t,PNPM_WORKSPACE_CONTENT,`utf8`),`written`;let n=await readFile(t,`utf8`),a=withReleaseAgeExclusions(withSharpBuildPolicy(n));return a===n?`skipped`:(await writeFile(t,a,`utf8`),`written`)}function findAncestorPnpmWorkspaceRoot(e){let t=dirname(resolve(e));for(;;){if(existsSync(join(t,`pnpm-workspace.yaml`)))return t;let e=dirname(t);if(e===t)return;t=e}}function hasAncestorPnpmWorkspace(e){return findAncestorPnpmWorkspaceRoot(e)!==void 0}function parsePnpmWorkspacePackagePatterns(e){let t=e.split(/\r?\n/u),n=t.findIndex(e=>/^\s*packages:/u.test(e));if(n<0)return;let r=/^\s*packages:\s*\[(.*)\]\s*(?:#.*)?$/u.exec(t[n]??``);if(r!==null){let e=r[1].trim();return e.length===0?[]:e.split(`,`).map(e=>e.trim().replace(/^['"]|['"]$/gu,``)).filter(e=>e.length>0)}if(t[n]?.trim()!==`packages:`)return;let i=[];for(let e of t.slice(n+1)){if(/^\S/u.test(e))break;let t=/^\s*-\s*(.+?)\s*$/u.exec(e);t!==null&&i.push(t[1].replace(/^['"]|['"]$/gu,``))}return i}function findClaimingAncestorPnpmWorkspaceRoot(e){let t=findAncestorPnpmWorkspaceRoot(e);if(t===void 0)return;let r;try{r=parsePnpmWorkspacePackagePatterns(readFileSync(join(t,PNPM_WORKSPACE_PATH),`utf8`))}catch{return t}return r===void 0||workspacePatternsClaimProject(r,t,e)?t:void 0}function withPnpmWorkspacePackagePattern(e,t){let n=e.endsWith(`
|
|
10
10
|
`)?e:`${e}\n`,r=n.split(`
|
|
11
11
|
`),i=r.findIndex(e=>e.trim()===`packages:`);if(i<0)return`${n.trim().length===0?``:`${n}\n`}packages:\n - ${t}\n`;let a=findYamlBlockEnd(r,i);for(;a>i+1&&r[a-1]===``;)--a;return r.splice(a,0,` - ${t}`),r.join(`
|
|
12
|
-
`)}async function ensurePnpmWorkspaceIncludesProject(e){let n=findAncestorPnpmWorkspaceRoot(e);if(n===void 0||resolve(n)===resolve(e)||findClaimingAncestorPnpmWorkspaceRoot(e)===n)return`skipped`;let
|
|
12
|
+
`)}async function ensurePnpmWorkspaceIncludesProject(e){let n=findAncestorPnpmWorkspaceRoot(e);if(n===void 0||resolve(n)===resolve(e)||findClaimingAncestorPnpmWorkspaceRoot(e)===n)return`skipped`;let a=join(n,PNPM_WORKSPACE_PATH),o=await readFile(a,`utf8`),s=withPnpmWorkspacePackagePattern(o,workspacePatternForProject(n,e));return s===o?`skipped`:(await writeFile(a,s,`utf8`),`written`)}function pnpmWorkspaceClaimsProject(e,t){let n;try{n=JSON.parse(e)}catch{return}if(!Array.isArray(n)||n.length===0)return;let canonicalPath=e=>{let t=resolve(e);try{return realpathSync.native(t)}catch{return t}},r=canonicalPath(t),i=!1;for(let e of n){if(typeof e!=`object`||!e)continue;let t=e.path;if(typeof t==`string`&&(i=!0,canonicalPath(t)===r))return!0}return!i&&void 0}const pnpmPackageManager={kind:`pnpm`,scaffoldFiles:{[PNPM_WORKSPACE_PATH]:PNPM_WORKSPACE_CONTENT},async applyProjectConfiguration(e,t){let n=t?.workspaceProbeRoot??e,r=await ensurePnpmWorkspaceIncludesProject(n),i=join(findClaimingAncestorPnpmWorkspaceRoot(n)??e,PNPM_WORKSPACE_PATH),a=await ensurePnpmWorkspacePolicy(i);return(r===`written`||a===`written`?`written`:`skipped`)==`written`?{filesSkipped:[],filesWritten:[i]}:{filesSkipped:[i],filesWritten:[]}},devArguments:()=>[`exec`,`eve`,`dev`],installArguments:e=>[`install`,`--no-frozen-lockfile`,...e.bypassMinimumReleaseAge===!0?[`--config.minimum-release-age=0`]:[],...e.ignoreWorkspace===!0?[`--ignore-workspace`]:[]],prepareArguments:(e,t)=>[`--dir`,e,...t],resolveInvocation(e){let t=process.env.npm_execpath;if(t!==void 0&&t.toLowerCase().includes(`pnpm`)){let n=extname(t).toLowerCase();return n===`.cjs`||n===`.js`?{args:[t,...e],command:process.execPath}:{args:e,command:t,shell:process.platform===`win32`}}if(process.env.npm_config_user_agent?.toLowerCase().startsWith(`pnpm/`))return{args:e,command:`pnpm`,shell:process.platform===`win32`};let n=process.env.PNPM_HOME;if(n!==void 0){let t=join(n,process.platform===`win32`?`pnpm.CMD`:`pnpm`);if(existsSync(t))return{args:e,command:t,shell:process.platform===`win32`}}return{args:e,command:`pnpm`}}};export{PNPM_WORKSPACE_CONTENT,PNPM_WORKSPACE_MEMBERSHIP_ARGUMENTS,PNPM_WORKSPACE_PATH,ensurePnpmWorkspaceIncludesProject,findAncestorPnpmWorkspaceRoot,findClaimingAncestorPnpmWorkspaceRoot,hasAncestorPnpmWorkspace,pnpmPackageManager,pnpmWorkspaceClaimsProject};
|
|
@@ -5,6 +5,8 @@ export interface RunVercelOptions {
|
|
|
5
5
|
extraEnv?: Readonly<Record<string, string>>;
|
|
6
6
|
/** Pass `--non-interactive` and close stdin so automation cannot stop on a prompt. */
|
|
7
7
|
nonInteractive?: boolean;
|
|
8
|
+
/** UTF-8 data written to stdin, used to keep connector secrets out of argv. */
|
|
9
|
+
stdin?: string;
|
|
8
10
|
/** Streams command output to a parent-owned renderer instead of writing outside it. */
|
|
9
11
|
onOutput?: ProcessOutputHandler;
|
|
10
12
|
/** Aborts the Vercel CLI subprocess when its parent setup flow is interrupted. */
|
|
@@ -73,12 +75,5 @@ export type VercelCaptureResult = {
|
|
|
73
75
|
ok: false;
|
|
74
76
|
failure: VercelCaptureFailure;
|
|
75
77
|
};
|
|
76
|
-
/**
|
|
77
|
-
* Runs a Vercel CLI lookup and captures stdout.
|
|
78
|
-
*
|
|
79
|
-
* stderr is always captured so a failure's diagnostic survives, even with no
|
|
80
|
-
* live `onOutput` renderer attached; when `onOutput` is supplied, stderr is
|
|
81
|
-
* streamed to it and the failure summary is appended after a non-zero exit.
|
|
82
|
-
*/
|
|
83
78
|
export declare function captureVercel(args: string[], options: RunVercelOptions): Promise<VercelCaptureResult>;
|
|
84
79
|
export {};
|