eve 0.29.3 → 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.
Files changed (216) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/dist/src/acp/adapter.d.ts +43 -0
  3. package/dist/src/acp/adapter.js +1 -0
  4. package/dist/src/acp/line-limit.d.ts +3 -0
  5. package/dist/src/acp/line-limit.js +1 -0
  6. package/dist/src/acp/server.d.ts +24 -0
  7. package/dist/src/acp/server.js +1 -0
  8. package/dist/src/chunks/{use-eve-agent-DaH3cf8K.js → use-eve-agent-8mofdZcO.js} +45 -10
  9. package/dist/src/chunks/{use-eve-agent-CyDt3Lny.js → use-eve-agent-bKJbH0k4.js} +45 -10
  10. package/dist/src/cli/acp/command.d.ts +22 -0
  11. package/dist/src/cli/acp/command.js +4 -0
  12. package/dist/src/cli/commands/agent-prompt/build-and-verify.md +4 -0
  13. package/dist/src/cli/commands/extension-init.js +1 -1
  14. package/dist/src/cli/commands/init-git.js +1 -1
  15. package/dist/src/cli/commands/init-repl.js +1 -1
  16. package/dist/src/cli/commands/init.js +1 -1
  17. package/dist/src/cli/commands/logs.js +2 -2
  18. package/dist/src/cli/commands/register-integration-commands.js +1 -1
  19. package/dist/src/cli/commands/register-registry-commands.js +1 -1
  20. package/dist/src/cli/commands/registry-project.js +1 -1
  21. package/dist/src/cli/commands/registry-setup-command.js +1 -1
  22. package/dist/src/cli/commands/registry.d.ts +14 -2
  23. package/dist/src/cli/commands/registry.js +1 -1
  24. package/dist/src/cli/commands/trace.d.ts +2 -2
  25. package/dist/src/cli/dev/command-options.d.ts +22 -0
  26. package/dist/src/cli/dev/command-options.js +1 -0
  27. package/dist/src/cli/dev/diagnostic-dump.js +1 -1
  28. package/dist/src/cli/dev/diagnostic-sink.js +1 -1
  29. package/dist/src/cli/dev/local-server-cleanup.js +1 -1
  30. package/dist/src/cli/dev/local-server-process.js +1 -1
  31. package/dist/src/cli/dev/tui/command-typeahead.js +1 -1
  32. package/dist/src/cli/dev/tui/remote-auth.d.ts +6 -3
  33. package/dist/src/cli/dev/tui/remote-connection-probe.js +1 -1
  34. package/dist/src/cli/dev/tui/runner.js +1 -1
  35. package/dist/src/cli/dev/tui/stream-format.d.ts +14 -0
  36. package/dist/src/cli/dev/tui/stream-format.js +2 -2
  37. package/dist/src/cli/dev/tui/terminal-background.d.ts +23 -0
  38. package/dist/src/cli/dev/tui/terminal-background.js +1 -0
  39. package/dist/src/cli/dev/tui/terminal-renderer.js +12 -12
  40. package/dist/src/cli/dev/tui/traces/trace-content.d.ts +7 -0
  41. package/dist/src/cli/dev/tui/traces/trace-content.js +2 -2
  42. package/dist/src/cli/dev/tui/traces/trace-conversation.d.ts +10 -5
  43. package/dist/src/cli/dev/tui/traces/trace-conversation.js +1 -1
  44. package/dist/src/cli/dev/tui/traces/trace-store.js +1 -1
  45. package/dist/src/cli/dev/tui/traces/trace-surfaces.d.ts +40 -0
  46. package/dist/src/cli/dev/tui/traces/trace-surfaces.js +1 -0
  47. package/dist/src/cli/dev/tui/traces/trace-view.d.ts +8 -1
  48. package/dist/src/cli/dev/tui/traces/trace-view.js +2 -2
  49. package/dist/src/cli/dev/tui/traces/trace-viewer-session.d.ts +13 -0
  50. package/dist/src/cli/dev/tui/traces/trace-viewer-session.js +1 -1
  51. package/dist/src/cli/dev/tui/traces/trace-viewer-state.js +1 -1
  52. package/dist/src/cli/dev/tui/tui.js +1 -1
  53. package/dist/src/cli/invoke/invoke.js +1 -1
  54. package/dist/src/cli/invoke/result.js +1 -1
  55. package/dist/src/cli/run.d.ts +3 -0
  56. package/dist/src/cli/run.js +3 -3
  57. package/dist/src/cli/ui/terminal-text.d.ts +0 -3
  58. package/dist/src/cli/ui/terminal-text.js +1 -1
  59. package/dist/src/client/index.d.ts +1 -1
  60. package/dist/src/client/open-stream.js +1 -1
  61. package/dist/src/client/session.d.ts +15 -1
  62. package/dist/src/client/session.js +1 -1
  63. package/dist/src/client/types.d.ts +9 -0
  64. package/dist/src/compiled/.vendor-stamp.json +2 -1
  65. package/dist/src/compiled/@agentclientprotocol/sdk/LICENSE +191 -0
  66. package/dist/src/compiled/@agentclientprotocol/sdk/index.d.ts +1835 -0
  67. package/dist/src/compiled/@agentclientprotocol/sdk/index.js +65 -0
  68. package/dist/src/compiled/@agentclientprotocol/sdk/jsonrpc.d.ts +603 -0
  69. package/dist/src/compiled/@agentclientprotocol/sdk/schema/guards.gen.d.ts +199 -0
  70. package/dist/src/compiled/@agentclientprotocol/sdk/schema/index.d.ts +51 -0
  71. package/dist/src/compiled/@agentclientprotocol/sdk/schema/types.gen.d.ts +6118 -0
  72. package/dist/src/compiled/@agentclientprotocol/sdk/stream.d.ts +35 -0
  73. package/dist/src/compiler/artifacts.js +1 -1
  74. package/dist/src/compiler/extension-compatibility.js +1 -1
  75. package/dist/src/compiler/model-catalog.js +1 -1
  76. package/dist/src/compiler/normalize-sandbox.js +1 -1
  77. package/dist/src/compiler/workspace-resources.js +1 -1
  78. package/dist/src/discover/project-source.js +1 -1
  79. package/dist/src/evals/cli/eval.js +2 -2
  80. package/dist/src/evals/loaders/json.js +1 -1
  81. package/dist/src/evals/loaders/yaml.js +1 -1
  82. package/dist/src/evals/runner/artifacts.js +1 -1
  83. package/dist/src/evals/runner/discover.js +1 -1
  84. package/dist/src/evals/runner/reporters/junit.js +1 -1
  85. package/dist/src/evals/session.js +1 -1
  86. package/dist/src/execution/sandbox/bindings/docker-cli.js +1 -1
  87. package/dist/src/execution/sandbox/bindings/docker-templates.js +1 -1
  88. package/dist/src/execution/sandbox/bindings/just-bash-runtime.js +1 -1
  89. package/dist/src/execution/sandbox/bindings/just-bash.js +1 -1
  90. package/dist/src/execution/sandbox/bindings/local-backend-utils.js +1 -1
  91. package/dist/src/execution/sandbox/bindings/microsandbox-lifecycle.js +1 -1
  92. package/dist/src/execution/sandbox/bindings/microsandbox-metadata.js +1 -1
  93. package/dist/src/execution/sandbox/bindings/microsandbox-platform.js +1 -1
  94. package/dist/src/execution/sandbox/bindings/microsandbox-runtime.js +1 -1
  95. package/dist/src/execution/sandbox/bindings/microsandbox-templates.js +1 -1
  96. package/dist/src/execution/sandbox/development-cleanup.js +1 -1
  97. package/dist/src/execution/sandbox/template-prewarm-lock.js +1 -1
  98. package/dist/src/harness/attachment-staging.js +1 -1
  99. package/dist/src/internal/application/build-profile.js +1 -1
  100. package/dist/src/internal/application/build-workspace.js +1 -1
  101. package/dist/src/internal/application/cache-metadata.js +1 -1
  102. package/dist/src/internal/application/compiled-artifacts.js +8 -8
  103. package/dist/src/internal/application/optional-package-install.js +2 -2
  104. package/dist/src/internal/application/output-publication-artifacts.js +1 -1
  105. package/dist/src/internal/application/output-publication-journal.js +1 -1
  106. package/dist/src/internal/application/output-publication-lock.js +1 -1
  107. package/dist/src/internal/application/output-publication.js +1 -1
  108. package/dist/src/internal/application/package.js +1 -1
  109. package/dist/src/internal/application/paths.js +1 -1
  110. package/dist/src/internal/application/production-compiler-artifacts.js +1 -1
  111. package/dist/src/internal/application/tsconfig-dependencies.js +1 -1
  112. package/dist/src/internal/authored-asset-import-plugin.js +1 -1
  113. package/dist/src/internal/authored-module-loader.js +3 -3
  114. package/dist/src/internal/authored-package-tsconfig-paths.js +1 -1
  115. package/dist/src/internal/materialized-authored-modules.js +1 -1
  116. package/dist/src/internal/nitro/dev-runtime-artifacts-retention.js +1 -1
  117. package/dist/src/internal/nitro/dev-runtime-artifacts.js +1 -1
  118. package/dist/src/internal/nitro/dev-runtime-source-snapshot-copy.js +1 -1
  119. package/dist/src/internal/nitro/dev-runtime-source-snapshot.js +1 -1
  120. package/dist/src/internal/nitro/host/build-application.js +1 -1
  121. package/dist/src/internal/nitro/host/build-extension.js +1 -1
  122. package/dist/src/internal/nitro/host/build-vercel-agent-summary.js +1 -1
  123. package/dist/src/internal/nitro/host/configure-nitro-routes.js +3 -3
  124. package/dist/src/internal/nitro/host/copy-host-middleware.js +1 -1
  125. package/dist/src/internal/nitro/host/create-application-nitro.js +1 -1
  126. package/dist/src/internal/nitro/host/cron-handler-route.js +1 -1
  127. package/dist/src/internal/nitro/host/dev-authored-rebuild-coordinator.js +1 -1
  128. package/dist/src/internal/nitro/host/dev-authored-source-watcher.js +1 -1
  129. package/dist/src/internal/nitro/host/dev-host-fingerprint.js +1 -1
  130. package/dist/src/internal/nitro/host/dev-host-workspace.js +1 -1
  131. package/dist/src/internal/nitro/host/dev-server-http.js +1 -1
  132. package/dist/src/internal/nitro/host/dev-server-state.js +1 -1
  133. package/dist/src/internal/nitro/host/dev-workspace-extensions.js +1 -1
  134. package/dist/src/internal/nitro/host/extension-build-config.js +1 -1
  135. package/dist/src/internal/nitro/host/extension-declarations.js +2 -2
  136. package/dist/src/internal/nitro/host/extension-distribution.js +3 -3
  137. package/dist/src/internal/nitro/host/extension-state-usage.js +1 -1
  138. package/dist/src/internal/nitro/host/normalize-vercel-service-crons.js +1 -1
  139. package/dist/src/internal/nitro/host/start-development-server.js +2 -2
  140. package/dist/src/internal/nitro/host/start-production-server.js +2 -2
  141. package/dist/src/internal/nitro/host/types.d.ts +2 -0
  142. package/dist/src/internal/vercel/project-link.js +1 -1
  143. package/dist/src/internal/workflow/development-world-client.js +1 -1
  144. package/dist/src/internal/workflow-bundle/builder-support.js +6 -6
  145. package/dist/src/internal/workflow-bundle/builder.js +3 -3
  146. package/dist/src/internal/workflow-bundle/nitro-step-entry.js +2 -2
  147. package/dist/src/internal/workflow-bundle/vercel-workflow-output.js +1 -1
  148. package/dist/src/internal/workflow-bundle/workflow-builders.js +1 -1
  149. package/dist/src/public/channels/discord/discordChannel.js +1 -1
  150. package/dist/src/public/channels/discord/verify.js +1 -1
  151. package/dist/src/public/channels/github/auth.js +2 -2
  152. package/dist/src/public/channels/github/githubChannel.js +1 -1
  153. package/dist/src/public/channels/github/verify.js +1 -1
  154. package/dist/src/public/channels/linear/inbound.js +2 -2
  155. package/dist/src/public/channels/linear/linearChannel.js +1 -1
  156. package/dist/src/public/channels/linear/verify.js +1 -1
  157. package/dist/src/public/channels/teams/teamsChannel.js +1 -1
  158. package/dist/src/public/channels/telegram/verify.js +1 -1
  159. package/dist/src/public/channels/twilio/twilioChannel.js +1 -1
  160. package/dist/src/public/models/openai/chatgpt/auth.js +1 -1
  161. package/dist/src/public/next/server.js +2 -2
  162. package/dist/src/public/next/vercel-output-config.js +1 -1
  163. package/dist/src/public/nuxt/dev-server.js +1 -1
  164. package/dist/src/public/nuxt/vercel-services.js +1 -1
  165. package/dist/src/public/sveltekit/dev-server.js +1 -1
  166. package/dist/src/public/sveltekit/vercel-json.js +1 -1
  167. package/dist/src/runtime/framework-tools/file-state.js +1 -1
  168. package/dist/src/runtime/sandbox/keys.js +1 -1
  169. package/dist/src/runtime/workspace/seed-files.js +1 -1
  170. package/dist/src/setup/boxes/detect-ai-gateway.js +1 -1
  171. package/dist/src/setup/index.d.ts +1 -0
  172. package/dist/src/setup/index.js +1 -1
  173. package/dist/src/setup/integrations/discord/api.d.ts +15 -0
  174. package/dist/src/setup/integrations/discord/api.js +1 -0
  175. package/dist/src/setup/integrations/discord/connect.d.ts +24 -0
  176. package/dist/src/setup/integrations/discord/connect.js +1 -0
  177. package/dist/src/setup/integrations/discord/setup.d.ts +19 -0
  178. package/dist/src/setup/integrations/discord/setup.js +8 -0
  179. package/dist/src/setup/integrations/registry.js +1 -1
  180. package/dist/src/setup/package-manager.js +1 -1
  181. package/dist/src/setup/primitives/pm/pnpm.js +3 -3
  182. package/dist/src/setup/project-resolution.js +1 -1
  183. package/dist/src/setup/prompter.js +1 -1
  184. package/dist/src/setup/registry-setup-client.d.ts +6 -2
  185. package/dist/src/setup/registry-setup-client.js +1 -1
  186. package/dist/src/setup/scaffold/create/add-to-project.js +1 -1
  187. package/dist/src/setup/scaffold/create/extension.js +1 -1
  188. package/dist/src/setup/scaffold/create/project.js +2 -9
  189. package/dist/src/setup/scaffold/files.js +1 -1
  190. package/dist/src/setup/scaffold/update/channels.js +2 -2
  191. package/dist/src/setup/scaffold/update/connections.js +1 -1
  192. package/dist/src/setup/scaffold/workspace-root.js +1 -1
  193. package/dist/src/setup/slack-connect-lifecycle.js +1 -1
  194. package/dist/src/setup/vercel-project-framework.js +1 -1
  195. package/dist/src/shared/guards.d.ts +2 -0
  196. package/dist/src/shared/guards.js +1 -1
  197. package/dist/src/shared/skill-package.js +1 -1
  198. package/dist/src/shared/skill-paths.d.ts +4 -4
  199. package/dist/src/shared/skill-paths.js +2 -2
  200. package/dist/src/shared/vercel-output-directory.js +1 -1
  201. package/dist/src/source-change/static-source-change.js +1 -1
  202. package/dist/src/svelte/index.js +1 -1
  203. package/dist/src/svelte/use-eve-agent.js +1 -1
  204. package/dist/src/tracing/local-instrumentation-runtime.js +1 -1
  205. package/dist/src/tracing/local-trace-reader.d.ts +22 -5
  206. package/dist/src/tracing/local-trace-reader.js +1 -1
  207. package/dist/src/tracing/local-trace-retention.js +1 -1
  208. package/dist/src/tracing/local-trace-span-processor.js +1 -1
  209. package/dist/src/vue/index.js +1 -1
  210. package/dist/src/vue/use-eve-agent.js +1 -1
  211. package/docs/channels/discord.mdx +30 -14
  212. package/docs/guides/acp.md +91 -0
  213. package/docs/guides/client/streaming.mdx +24 -0
  214. package/docs/guides/meta.json +1 -0
  215. package/docs/reference/cli.md +3 -0
  216. package/package.json +2 -1
@@ -1,4 +1,4 @@
1
- import{pinnedNodeEngineMajor}from"../../node-engine.js";import{SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS}from"../update/module-files.js";import{pathExists,writeTextFile}from"../files.js";import{blockingCreateInPlaceEntries}from"../create-in-place.js";import{resolveVersionToken}from"../version-tokens.js";import{applyPackageManagerWorkspaceConfiguration,isPackageManagerWorkspaceMember,patchWorkspaceRootPackageJson}from"../workspace-root.js";import{WEB_APP_TEMPLATE_FILES}from"./web-template.js";import{basename,join,resolve}from"node:path";import{mkdir,readdir,stat}from"node:fs/promises";const CURRENT_DIRECTORY_PROJECT_NAME=`.`,DEFAULT_AI_PACKAGE_VERSION=`^7.0.38`,DEFAULT_CONNECT_PACKAGE_VERSION=`0.4.3`,DEFAULT_ZOD_PACKAGE_VERSION=`4.4.3`,DEFAULT_EVE_PACKAGE_CONTRACT={version:`0.29.3`,nodeEngine:`>=24`};function resolveEvePackageContract(e=DEFAULT_EVE_PACKAGE_CONTRACT){return{version:resolveVersionToken(`evePackage.version`,e.version),nodeEngine:resolveVersionToken(`evePackage.nodeEngine`,e.nodeEngine)}}function modelProviderSlug(e){let t=(e.split(`/`)[0]??``).replaceAll(/[^A-Za-z0-9._-]/gu,``);return t.length>0?t:`anthropic`}function byokProviderEnvVar(e){let t=modelProviderSlug(e).toUpperCase().replaceAll(/[^A-Z0-9]/gu,`_`);return`${/^[0-9]/.test(t)?`_`:``}${t}_API_KEY`}function agentTemplateFiles(e){return{"agent/agent.ts":BASE_AGENT_TEMPLATE.replaceAll(`__EVE_INIT_MODEL__`,e),"agent/channels/eve.ts":WEB_APP_TEMPLATE_FILES[`agent/channels/eve.ts`],"agent/instructions.md":AGENT_INSTRUCTIONS_TEMPLATE}}function renderTemplate(e,t){return e.replaceAll(`__EVE_INIT_APP_NAME__`,t.appName).replaceAll(`__EVE_INIT_MODEL__`,t.model).replaceAll(`__EVE_INIT_BYOK_PROVIDER__`,modelProviderSlug(t.model)).replaceAll(`__EVE_INIT_BYOK_ENV_VAR__`,byokProviderEnvVar(t.model)).replaceAll(`__EVE_INIT_PACKAGE_VERSION__`,formatEveDependencySpecifier(t.eveVersion)).replaceAll(`__EVE_INIT_AI_SDK_VERSION__`,t.aiPackageVersion).replaceAll(`__EVE_INIT_CONNECT_VERSION__`,t.connectPackageVersion).replaceAll(`__EVE_INIT_ZOD_VERSION__`,t.zodPackageVersion).replaceAll(`__EVE_INIT_TYPESCRIPT_VERSION__`,t.typescriptPackageVersion).replaceAll(`__EVE_INIT_TYPES_NODE_VERSION__`,t.nodeTypesVersion).replaceAll(`__EVE_INIT_NODE_ENGINE__`,t.nodeEngine)}function formatEveDependencySpecifier(e){return/^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z-.]+)?$/.test(e)?`^${e}`:e}const BASE_AGENT_TEMPLATE=`import { defineAgent } from "eve";
1
+ import{pinnedNodeEngineMajor}from"../../node-engine.js";import{SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS}from"../update/module-files.js";import{pathExists,writeTextFile}from"../files.js";import{blockingCreateInPlaceEntries}from"../create-in-place.js";import{resolveVersionToken}from"../version-tokens.js";import{applyPackageManagerWorkspaceConfiguration,isPackageManagerWorkspaceMember,patchWorkspaceRootPackageJson}from"../workspace-root.js";import{WEB_APP_TEMPLATE_FILES}from"./web-template.js";import{mkdir,readdir,stat}from"node:fs/promises";import{basename,join,resolve}from"node:path";const CURRENT_DIRECTORY_PROJECT_NAME=`.`,DEFAULT_AI_PACKAGE_VERSION=`^7.0.38`,DEFAULT_CONNECT_PACKAGE_VERSION=`0.4.3`,DEFAULT_ZOD_PACKAGE_VERSION=`4.4.3`,DEFAULT_EVE_PACKAGE_CONTRACT={version:`0.29.4`,nodeEngine:`>=24`};function resolveEvePackageContract(e=DEFAULT_EVE_PACKAGE_CONTRACT){return{version:resolveVersionToken(`evePackage.version`,e.version),nodeEngine:resolveVersionToken(`evePackage.nodeEngine`,e.nodeEngine)}}function modelProviderSlug(e){let t=(e.split(`/`)[0]??``).replaceAll(/[^A-Za-z0-9._-]/gu,``);return t.length>0?t:`anthropic`}function byokProviderEnvVar(e){let t=modelProviderSlug(e).toUpperCase().replaceAll(/[^A-Z0-9]/gu,`_`);return`${/^[0-9]/.test(t)?`_`:``}${t}_API_KEY`}function agentTemplateFiles(e){return{"agent/agent.ts":BASE_AGENT_TEMPLATE.replaceAll(`__EVE_INIT_MODEL__`,e),"agent/channels/eve.ts":WEB_APP_TEMPLATE_FILES[`agent/channels/eve.ts`],"agent/instructions.md":AGENT_INSTRUCTIONS_TEMPLATE}}function renderTemplate(e,t){return e.replaceAll(`__EVE_INIT_APP_NAME__`,t.appName).replaceAll(`__EVE_INIT_MODEL__`,t.model).replaceAll(`__EVE_INIT_BYOK_PROVIDER__`,modelProviderSlug(t.model)).replaceAll(`__EVE_INIT_BYOK_ENV_VAR__`,byokProviderEnvVar(t.model)).replaceAll(`__EVE_INIT_PACKAGE_VERSION__`,formatEveDependencySpecifier(t.eveVersion)).replaceAll(`__EVE_INIT_AI_SDK_VERSION__`,t.aiPackageVersion).replaceAll(`__EVE_INIT_CONNECT_VERSION__`,t.connectPackageVersion).replaceAll(`__EVE_INIT_ZOD_VERSION__`,t.zodPackageVersion).replaceAll(`__EVE_INIT_TYPESCRIPT_VERSION__`,t.typescriptPackageVersion).replaceAll(`__EVE_INIT_TYPES_NODE_VERSION__`,t.nodeTypesVersion).replaceAll(`__EVE_INIT_NODE_ENGINE__`,t.nodeEngine)}function formatEveDependencySpecifier(e){return/^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z-.]+)?$/.test(e)?`^${e}`:e}const BASE_AGENT_TEMPLATE=`import { defineAgent } from "eve";
2
2
 
3
3
  export default defineAgent({
4
4
  model: "__EVE_INIT_MODEL__",
@@ -71,14 +71,7 @@ dist
71
71
  .output
72
72
  .nitro
73
73
  dist
74
- `,"AGENTS.md":`# eve Agent App
75
-
76
- This project uses the eve framework. Before writing code, read the relevant guide
77
- from the installed eve package docs. In most installs, those docs are at
78
- \`node_modules/eve/docs/\`. In workspaces or local package installs, resolve the
79
- installed \`eve\` package location first and read its \`docs/\` directory. If
80
- package docs are unavailable, use https://eve.dev/docs as a fallback.
81
- `,"CLAUDE.md":`@AGENTS.md
74
+ `,"AGENTS.md":"# eve Agent App\n\nThis project uses the eve framework. Before writing code, read the relevant guide\nfrom the installed eve package docs. In most installs, those docs are at\n`node_modules/eve/docs/`. In workspaces or local package installs, resolve the\ninstalled `eve` package location first and read its `docs/` directory. If\npackage docs are unavailable, use https://eve.dev/docs as a fallback.\n\nBefore implementing an integration yourself, use\n`eve registry search <query>` or `eve registry list` to discover available\nintegrations. Inspect one with `eve registry view <item>`, then install it with\n`eve add <item>`.\n","CLAUDE.md":`@AGENTS.md
82
75
  `};function templateFiles(e){return{"agent/agent.ts":e.byokProvider?`import { defineAgent } from "eve";
83
76
 
84
77
  export default defineAgent({
@@ -1 +1 @@
1
- import{dirname}from"node:path";import{mkdir,stat,writeFile}from"node:fs/promises";async function pathExists(e){try{return await stat(e),!0}catch{return!1}}var WriteFileExistsError=class extends Error{path;constructor(e){super(`Refusing to overwrite ${e} (pass --force to override).`),this.name=`WriteFileExistsError`,this.path=e}};async function writeTextFile(t,n,r={}){if(!r.force&&await pathExists(t))throw new WriteFileExistsError(t);await mkdir(dirname(t),{recursive:!0}),await writeFile(t,n,`utf8`)}export{WriteFileExistsError,pathExists,writeTextFile};
1
+ import{mkdir,stat,writeFile}from"node:fs/promises";import{dirname}from"node:path";async function pathExists(e){try{return await stat(e),!0}catch{return!1}}var WriteFileExistsError=class extends Error{path;constructor(e){super(`Refusing to overwrite ${e} (pass --force to override).`),this.name=`WriteFileExistsError`,this.path=e}};async function writeTextFile(t,n,r={}){if(!r.force&&await pathExists(t))throw new WriteFileExistsError(t);await mkdir(dirname(t),{recursive:!0}),await writeFile(t,n,`utf8`)}export{WriteFileExistsError,pathExists,writeTextFile};
@@ -1,10 +1,10 @@
1
- import{appendEnv}from"../../append-env.js";import{pinnedNodeEngineMajor}from"../../node-engine.js";import{getSupportedModuleBaseName,matchesSupportedModuleBaseName}from"./module-files.js";import{pathExists,writeTextFile}from"../files.js";import{resolveVersionToken}from"../version-tokens.js";import{patchPackageJson}from"./package-json.js";import{applyPackageManagerWorkspaceConfiguration,isPackageManagerWorkspaceMember,patchWorkspaceRootPackageJson}from"../workspace-root.js";import{WEB_APP_TEMPLATE_FILES,WEB_APP_TEMPLATE_PACKAGE_JSON}from"../create/web-template.js";import{DEFAULT_EVE_PACKAGE_CONTRACT,resolveEvePackageContract}from"../create/project.js";import{basename,join,resolve}from"node:path";import{readFile,readdir,unlink,writeFile}from"node:fs/promises";const SLACK_CHANNEL_DEFAULT_ROUTE=`/eve/v1/slack`,DEFAULT_SLACK_CONNECTOR_SLUG=`my-agent`,NEXT_PACKAGE_NAME=`next`,PACKAGE_DEPENDENCY_FIELDS=[`dependencies`,`devDependencies`],WEB_NEXT_CONFIG_PATH=`next.config.ts`,WEB_COMPETING_NEXT_CONFIG_PATHS=[`next.config.js`,`next.config.mjs`,WEB_NEXT_CONFIG_PATH,`next.config.mts`].filter(e=>e!==WEB_NEXT_CONFIG_PATH);function toSlackConnectorSlug(e){return e}function isJsonObject(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}async function readPackageJsonObject(e){if(!await pathExists(e))return;let t=JSON.parse(await readFile(e,`utf8`));return isJsonObject(t)?t:void 0}async function readDependencyVersion(e,t){let n=await readPackageJsonObject(e);if(n===void 0||!isJsonObject(n.dependencies))return;let r=n.dependencies[t];return typeof r==`string`?r:void 0}function packageJsonHasDependency(e,t){for(let n of PACKAGE_DEPENDENCY_FIELDS){let r=e[n];if(isJsonObject(r)&&typeof r[t]==`string`)return!0}return!1}async function hasPackageDependency(e,t){let n=await readPackageJsonObject(e);return n!==void 0&&packageJsonHasDependency(n,t)}async function isNextJsProject(e){return hasPackageDependency(join(e,`package.json`),NEXT_PACKAGE_NAME)}const VERCEL_HOST_FRAMEWORK_PRESETS={"@sveltejs/kit":`sveltekit`,[NEXT_PACKAGE_NAME]:`nextjs`,nuxt:`nuxtjs`,nuxt3:`nuxtjs`,"nuxt-edge":`nuxtjs`,"nuxt-nightly":`nuxtjs`};async function resolveVercelHostFrameworkPreset(e){let t=await readPackageJsonObject(join(e,`package.json`));if(t!==void 0){for(let[e,n]of Object.entries(VERCEL_HOST_FRAMEWORK_PRESETS))if(packageJsonHasDependency(t,e))return n}}async function hasVercelHostFramework(e){return await resolveVercelHostFrameworkPreset(e)!==void 0}async function ensurePackageDependency(e,t,n){return!await pathExists(e)||await readDependencyVersion(e,t)===n?[]:(await patchPackageJson(e,{dependencies:{[t]:n}}),[{path:e,dependencies:[t],devDependencies:[],scripts:[]}])}function resolveWebPackageVersions(e){return{evePackage:e?.evePackage??DEFAULT_EVE_PACKAGE_CONTRACT,aiPackageVersion:e?.aiPackageVersion??`^7.0.38`,nextPackageVersion:e?.nextPackageVersion??`16.3.0-preview.6`,reactPackageVersion:e?.reactPackageVersion??`19.2.6`,reactDomPackageVersion:e?.reactDomPackageVersion??`19.2.6`,streamdownPackageVersion:e?.streamdownPackageVersion??`2.5.0`,zodPackageVersion:e?.zodPackageVersion??`4.4.3`,typesReactPackageVersion:e?.typesReactPackageVersion??`19.2.15`,typesReactDomPackageVersion:e?.typesReactDomPackageVersion??`19.2.3`}}function formatEveDependencySpecifier(e){return/^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z-.]+)?$/.test(e)?`^${e}`:e}async function patchWebPackageJson(e,n,r,a,c,d=!0){let p=join(e,`package.json`);if(!await pathExists(p))return{mutations:[]};let h=resolveEvePackageContract(a.evePackage),g=pinnedNodeEngineMajor(h.nodeEngine),_={...WEB_APP_TEMPLATE_PACKAGE_JSON.dependencies,ai:resolveVersionToken(`aiPackageVersion`,a.aiPackageVersion),eve:formatEveDependencySpecifier(h.version),next:resolveVersionToken(`nextPackageVersion`,a.nextPackageVersion),react:resolveVersionToken(`reactPackageVersion`,a.reactPackageVersion),"react-dom":resolveVersionToken(`reactDomPackageVersion`,a.reactDomPackageVersion),streamdown:resolveVersionToken(`streamdownPackageVersion`,a.streamdownPackageVersion),zod:resolveVersionToken(`zodPackageVersion`,a.zodPackageVersion)},v={...WEB_APP_TEMPLATE_PACKAGE_JSON.devDependencies,"@types/node":g,"@types/react":resolveVersionToken(`typesReactPackageVersion`,a.typesReactPackageVersion),"@types/react-dom":resolveVersionToken(`typesReactDomPackageVersion`,a.typesReactDomPackageVersion),typescript:`6.0.3`},y=WEB_APP_TEMPLATE_PACKAGE_JSON.scripts,b=isPackageManagerWorkspaceMember(n,r),x={scripts:y};d&&(x.dependencies=_,x.devDependencies=v),b||(x.nodeEngineRequirement=h.nodeEngine);let S=await patchPackageJson(p,x),C=(await patchWorkspaceRootPackageJson(n,r,{aiPackageVersion:_.ai,nodeEngineRequirement:h.nodeEngine,onWorkspaceRootMutation:c})).nodeEngineOverride??S.nodeEngineOverride;return{mutations:[{path:p,dependencies:d?Object.keys(_):[],devDependencies:d?Object.keys(v):[],scripts:Object.keys(y)}],nodeEngineOverride:C}}function normalizeSlackConnectorSlug(e){return toSlackConnectorSlug((e.trim().replace(/^@/,``).split(`/`).at(-1)??``).toLowerCase().replace(/[^a-z0-9_-]+/g,`-`).replace(/^[^a-z0-9]+/,``).replace(/[^a-z0-9]+$/,``).slice(0,100).replace(/[^a-z0-9]+$/,``)||`my-agent`)}async function deriveSlackConnectorSlug(e,t){if(t!==void 0&&t.length>0&&t!==`.`)return normalizeSlackConnectorSlug(t);try{let t=await readFile(join(e,`package.json`),`utf8`),n=JSON.parse(t);if(typeof n.name==`string`&&n.name.length>0)return normalizeSlackConnectorSlug(n.name)}catch{}return normalizeSlackConnectorSlug(basename(resolve(e))||`my-agent`)}function buildSlackConnectTemplate(e){if(!e.startsWith(`slack/`)||e.length===6)throw Error(`Invalid Slack connector UID "${e}".`);return`import { connectSlackCredentials } from "@vercel/connect/eve";
1
+ import{appendEnv}from"../../append-env.js";import{pinnedNodeEngineMajor}from"../../node-engine.js";import{getSupportedModuleBaseName,matchesSupportedModuleBaseName}from"./module-files.js";import{pathExists,writeTextFile}from"../files.js";import{resolveVersionToken}from"../version-tokens.js";import{patchPackageJson}from"./package-json.js";import{applyPackageManagerWorkspaceConfiguration,isPackageManagerWorkspaceMember,patchWorkspaceRootPackageJson}from"../workspace-root.js";import{WEB_APP_TEMPLATE_FILES,WEB_APP_TEMPLATE_PACKAGE_JSON}from"../create/web-template.js";import{DEFAULT_EVE_PACKAGE_CONTRACT,resolveEvePackageContract}from"../create/project.js";import{readFile,readdir,unlink,writeFile}from"node:fs/promises";import{basename,join,resolve}from"node:path";const SLACK_CHANNEL_DEFAULT_ROUTE=`/eve/v1/slack`,DEFAULT_SLACK_CONNECTOR_SLUG=`my-agent`,NEXT_PACKAGE_NAME=`next`,PACKAGE_DEPENDENCY_FIELDS=[`dependencies`,`devDependencies`],WEB_NEXT_CONFIG_PATH=`next.config.ts`,WEB_COMPETING_NEXT_CONFIG_PATHS=[`next.config.js`,`next.config.mjs`,WEB_NEXT_CONFIG_PATH,`next.config.mts`].filter(e=>e!==WEB_NEXT_CONFIG_PATH);function toSlackConnectorSlug(e){return e}function isJsonObject(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}async function readPackageJsonObject(e){if(!await pathExists(e))return;let t=JSON.parse(await readFile(e,`utf8`));return isJsonObject(t)?t:void 0}async function readDependencyVersion(e,t){let n=await readPackageJsonObject(e);if(n===void 0||!isJsonObject(n.dependencies))return;let r=n.dependencies[t];return typeof r==`string`?r:void 0}function packageJsonHasDependency(e,t){for(let n of PACKAGE_DEPENDENCY_FIELDS){let r=e[n];if(isJsonObject(r)&&typeof r[t]==`string`)return!0}return!1}async function hasPackageDependency(e,t){let n=await readPackageJsonObject(e);return n!==void 0&&packageJsonHasDependency(n,t)}async function isNextJsProject(e){return hasPackageDependency(join(e,`package.json`),NEXT_PACKAGE_NAME)}const VERCEL_HOST_FRAMEWORK_PRESETS={"@sveltejs/kit":`sveltekit`,[NEXT_PACKAGE_NAME]:`nextjs`,nuxt:`nuxtjs`,nuxt3:`nuxtjs`,"nuxt-edge":`nuxtjs`,"nuxt-nightly":`nuxtjs`};async function resolveVercelHostFrameworkPreset(e){let t=await readPackageJsonObject(join(e,`package.json`));if(t!==void 0){for(let[e,n]of Object.entries(VERCEL_HOST_FRAMEWORK_PRESETS))if(packageJsonHasDependency(t,e))return n}}async function hasVercelHostFramework(e){return await resolveVercelHostFrameworkPreset(e)!==void 0}async function ensurePackageDependency(e,t,n){return!await pathExists(e)||await readDependencyVersion(e,t)===n?[]:(await patchPackageJson(e,{dependencies:{[t]:n}}),[{path:e,dependencies:[t],devDependencies:[],scripts:[]}])}function resolveWebPackageVersions(e){return{evePackage:e?.evePackage??DEFAULT_EVE_PACKAGE_CONTRACT,aiPackageVersion:e?.aiPackageVersion??`^7.0.38`,nextPackageVersion:e?.nextPackageVersion??`16.3.0-preview.6`,reactPackageVersion:e?.reactPackageVersion??`19.2.6`,reactDomPackageVersion:e?.reactDomPackageVersion??`19.2.6`,streamdownPackageVersion:e?.streamdownPackageVersion??`2.5.0`,zodPackageVersion:e?.zodPackageVersion??`4.4.3`,typesReactPackageVersion:e?.typesReactPackageVersion??`19.2.15`,typesReactDomPackageVersion:e?.typesReactDomPackageVersion??`19.2.3`}}function formatEveDependencySpecifier(e){return/^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z-.]+)?$/.test(e)?`^${e}`:e}async function patchWebPackageJson(e,n,r,a,c,d=!0){let p=join(e,`package.json`);if(!await pathExists(p))return{mutations:[]};let h=resolveEvePackageContract(a.evePackage),g=pinnedNodeEngineMajor(h.nodeEngine),_={...WEB_APP_TEMPLATE_PACKAGE_JSON.dependencies,ai:resolveVersionToken(`aiPackageVersion`,a.aiPackageVersion),eve:formatEveDependencySpecifier(h.version),next:resolveVersionToken(`nextPackageVersion`,a.nextPackageVersion),react:resolveVersionToken(`reactPackageVersion`,a.reactPackageVersion),"react-dom":resolveVersionToken(`reactDomPackageVersion`,a.reactDomPackageVersion),streamdown:resolveVersionToken(`streamdownPackageVersion`,a.streamdownPackageVersion),zod:resolveVersionToken(`zodPackageVersion`,a.zodPackageVersion)},v={...WEB_APP_TEMPLATE_PACKAGE_JSON.devDependencies,"@types/node":g,"@types/react":resolveVersionToken(`typesReactPackageVersion`,a.typesReactPackageVersion),"@types/react-dom":resolveVersionToken(`typesReactDomPackageVersion`,a.typesReactDomPackageVersion),typescript:`6.0.3`},y=WEB_APP_TEMPLATE_PACKAGE_JSON.scripts,b=isPackageManagerWorkspaceMember(n,r),x={scripts:y};d&&(x.dependencies=_,x.devDependencies=v),b||(x.nodeEngineRequirement=h.nodeEngine);let S=await patchPackageJson(p,x),C=(await patchWorkspaceRootPackageJson(n,r,{aiPackageVersion:_.ai,nodeEngineRequirement:h.nodeEngine,onWorkspaceRootMutation:c})).nodeEngineOverride??S.nodeEngineOverride;return{mutations:[{path:p,dependencies:d?Object.keys(_):[],devDependencies:d?Object.keys(v):[],scripts:Object.keys(y)}],nodeEngineOverride:C}}function normalizeSlackConnectorSlug(e){return toSlackConnectorSlug((e.trim().replace(/^@/,``).split(`/`).at(-1)??``).toLowerCase().replace(/[^a-z0-9_-]+/g,`-`).replace(/^[^a-z0-9]+/,``).replace(/[^a-z0-9]+$/,``).slice(0,100).replace(/[^a-z0-9]+$/,``)||`my-agent`)}async function deriveSlackConnectorSlug(e,t){if(t!==void 0&&t.length>0&&t!==`.`)return normalizeSlackConnectorSlug(t);try{let t=await readFile(join(e,`package.json`),`utf8`),n=JSON.parse(t);if(typeof n.name==`string`&&n.name.length>0)return normalizeSlackConnectorSlug(n.name)}catch{}return normalizeSlackConnectorSlug(basename(resolve(e))||`my-agent`)}function buildSlackConnectTemplate(e){if(!e.startsWith(`slack/`)||e.length===6)throw Error(`Invalid Slack connector UID "${e}".`);return`import { connectSlackCredentials } from "@vercel/connect/eve";
2
2
  import { slackChannel } from "eve/channels/slack";
3
3
 
4
4
  export default slackChannel({
5
5
  credentials: connectSlackCredentials(${JSON.stringify(e)}),
6
6
  });
7
- `}const SLACK_ENV_EXAMPLE_VALUES={SLACK_BOT_TOKEN:``,SLACK_SIGNING_SECRET:``};function renderWebAppTemplate(e,t){return e.replaceAll(`__EVE_INIT_APP_NAME__`,t).replaceAll(`__EVE_INIT_WITH_EVE_OPTIONS__`,``)}async function ensureWebVercelJson(e){return await pathExists(e)?`skipped`:(await writeTextFile(e,`${JSON.stringify({$schema:`https://openapi.vercel.sh/vercel.json`},null,2)}\n`,{force:!0}),`written`)}async function findCompetingNextConfigFiles(e){let t=[];for(let n of WEB_COMPETING_NEXT_CONFIG_PATHS){let r=join(e,n);await pathExists(r)&&t.push(r)}return t}async function ensureChannel(e){switch(e.kind){case`slack`:return ensureSlackChannel({...e,kind:`slack`});case`web`:return ensureWebChannel({...e,kind:`web`})}}async function ensureWebChannel(e){let t=join(e.projectRoot,`package.json`),n=await pathExists(join(e.projectRoot,`app/page.tsx`));if(!e.force&&await isNextJsProject(e.projectRoot))return{kind:`web`,action:`skipped`,skipReason:`nextjs-project`,filesWritten:[],filesSkipped:[t],packageJsonUpdated:[]};let r=resolveWebPackageVersions(e.webPackageVersions),o=e.packageManager??`pnpm`,s=resolve(e.workspaceProbeDirectory??e.projectRoot),l=await patchWebPackageJson(e.projectRoot,o,s,r,e.onWorkspaceRootMutation,!e.skipDependencyMutation),u=[],f=[],p=[],m=[],_=basename(resolve(e.projectRoot));if(e.configureVercelServices??!0){let t=join(e.projectRoot,`vercel.json`);await ensureWebVercelJson(t)===`written`?u.push(t):m.push(t)}let v=await applyPackageManagerWorkspaceConfiguration({packageManager:o,projectRoot:e.projectRoot,workspaceProbeRoot:s,onWorkspaceRootMutation:e.onWorkspaceRootMutation});if(u.push(...v.filesWritten),m.push(...v.filesSkipped),!e.skipDependencyMutation)for(let[t,n]of Object.entries(WEB_APP_TEMPLATE_FILES)){let r=join(e.projectRoot,t);if(t===`agent/channels/eve.ts`&&!e.force&&await pathExists(r)){m.push(r);continue}let o=await pathExists(r);await writeTextFile(r,renderWebAppTemplate(n,_),{force:!0}),u.push(r),o&&f.push(r)}p.push(...await findCompetingNextConfigFiles(e.projectRoot));let y=[...new Set(u)],b=[...new Set(m)].filter(e=>!y.includes(e)),x={kind:`web`,action:n?`overwritten`:`created`,filesWritten:y,filesSkipped:b,packageJsonUpdated:l.mutations};return f.length>0&&(x.filesOverwritten=f),p.length>0&&(x.competingNextConfigFiles=p),l.nodeEngineOverride!==void 0&&(x.nodeEngineOverride=l.nodeEngineOverride),x}async function ensureSlackChannel(t){let n=join(t.projectRoot,`agent/channels/slack.ts`),r=await pathExists(n);if(!t.force&&r)return{kind:`slack`,action:`skipped`,filesWritten:[],filesSkipped:[n],packageJsonUpdated:[]};let s=t.slackCredentials??`vercel-connect`,c=t.slackConnectorSlug??await deriveSlackConnectorSlug(t.projectRoot),l,u=[],d=[n],f=[],p;if(s===`vercel-connect`){if(!t.skipDependencyMutation){let e=resolveVersionToken(`connectPackageVersion`,t.connectPackageVersion??`0.4.3`);u=await ensurePackageDependency(join(t.projectRoot,`package.json`),`@vercel/connect`,e)}l=buildSlackConnectTemplate(t.slackConnectorUid??`slack/${c}`)}else{l=`import { slackChannel } from "eve/channels/slack";
7
+ `}const SLACK_ENV_EXAMPLE_VALUES={SLACK_BOT_TOKEN:``,SLACK_SIGNING_SECRET:``};function renderWebAppTemplate(e,t){return e.replaceAll(`__EVE_INIT_APP_NAME__`,t).replaceAll(`__EVE_INIT_WITH_EVE_OPTIONS__`,``)}async function ensureWebVercelJson(e){return await pathExists(e)?`skipped`:(await writeTextFile(e,`${JSON.stringify({$schema:`https://openapi.vercel.sh/vercel.json`},null,2)}\n`,{force:!0}),`written`)}async function findCompetingNextConfigFiles(e){let t=[];for(let n of WEB_COMPETING_NEXT_CONFIG_PATHS){let r=join(e,n);await pathExists(r)&&t.push(r)}return t}async function ensureChannel(e){switch(e.kind){case`slack`:return ensureSlackChannel({...e,kind:`slack`});case`web`:return ensureWebChannel({...e,kind:`web`})}}async function ensureWebChannel(e){let t=join(e.projectRoot,`package.json`),n=await pathExists(join(e.projectRoot,`app/page.tsx`));if(!e.force&&await isNextJsProject(e.projectRoot))return{kind:`web`,action:`skipped`,skipReason:`nextjs-project`,filesWritten:[],filesSkipped:[t],packageJsonUpdated:[]};let r=resolveWebPackageVersions(e.webPackageVersions),o=e.packageManager??`pnpm`,s=resolve(e.workspaceProbeDirectory??e.projectRoot),l=await patchWebPackageJson(e.projectRoot,o,s,r,e.onWorkspaceRootMutation,!e.skipDependencyMutation),u=[],f=[],p=[],m=[],h=basename(resolve(e.projectRoot));if(e.configureVercelServices??!0){let t=join(e.projectRoot,`vercel.json`);await ensureWebVercelJson(t)===`written`?u.push(t):m.push(t)}let g=await applyPackageManagerWorkspaceConfiguration({packageManager:o,projectRoot:e.projectRoot,workspaceProbeRoot:s,onWorkspaceRootMutation:e.onWorkspaceRootMutation});if(u.push(...g.filesWritten),m.push(...g.filesSkipped),!e.skipDependencyMutation)for(let[t,n]of Object.entries(WEB_APP_TEMPLATE_FILES)){let r=join(e.projectRoot,t);if(t===`agent/channels/eve.ts`&&!e.force&&await pathExists(r)){m.push(r);continue}let o=await pathExists(r);await writeTextFile(r,renderWebAppTemplate(n,h),{force:!0}),u.push(r),o&&f.push(r)}p.push(...await findCompetingNextConfigFiles(e.projectRoot));let _=[...new Set(u)],v=[...new Set(m)].filter(e=>!_.includes(e)),x={kind:`web`,action:n?`overwritten`:`created`,filesWritten:_,filesSkipped:v,packageJsonUpdated:l.mutations};return f.length>0&&(x.filesOverwritten=f),p.length>0&&(x.competingNextConfigFiles=p),l.nodeEngineOverride!==void 0&&(x.nodeEngineOverride=l.nodeEngineOverride),x}async function ensureSlackChannel(t){let n=join(t.projectRoot,`agent/channels/slack.ts`),r=await pathExists(n);if(!t.force&&r)return{kind:`slack`,action:`skipped`,filesWritten:[],filesSkipped:[n],packageJsonUpdated:[]};let s=t.slackCredentials??`vercel-connect`,c=t.slackConnectorSlug??await deriveSlackConnectorSlug(t.projectRoot),l,u=[],d=[n],f=[],p;if(s===`vercel-connect`){if(!t.skipDependencyMutation){let e=resolveVersionToken(`connectPackageVersion`,t.connectPackageVersion??`0.4.3`);u=await ensurePackageDependency(join(t.projectRoot,`package.json`),`@vercel/connect`,e)}l=buildSlackConnectTemplate(t.slackConnectorUid??`slack/${c}`)}else{l=`import { slackChannel } from "eve/channels/slack";
8
8
 
9
9
  export default slackChannel();
10
10
  `;let n=join(t.projectRoot,`.env.example`);p={path:n,...await pathExists(n)?{content:await readFile(n,`utf8`)}:{}},(await appendEnv(n,SLACK_ENV_EXAMPLE_VALUES)).written.length>0?d.push(n):f.push(n)}try{await writeTextFile(n,l,{force:t.force})}catch(e){throw p!==void 0&&(p.content===void 0?await unlink(p.path):await writeFile(p.path,p.content,`utf8`)),e}let m={kind:`slack`,action:r?`overwritten`:`created`,filesWritten:d,filesSkipped:f,packageJsonUpdated:u,slackConnectorSlug:c};return r&&(m.filesOverwritten=[n]),m}async function listAuthoredChannels(e){let t=join(e,`agent/channels`),i;try{i=await readdir(t,{withFileTypes:!0})}catch(e){if(e.code===`ENOENT`)return[];throw e}let a=[];for(let e of i){if(e.isFile()){let t=getSupportedModuleBaseName(e.name);t!==null&&a.push(t);continue}if(e.isDirectory())try{(await readdir(join(t,e.name))).some(e=>matchesSupportedModuleBaseName(e,`connection`))&&a.push(e.name)}catch{}}return a.sort()}export{DEFAULT_SLACK_CONNECTOR_SLUG,SLACK_CHANNEL_DEFAULT_ROUTE,deriveSlackConnectorSlug,ensureChannel,hasVercelHostFramework,isNextJsProject,listAuthoredChannels,normalizeSlackConnectorSlug,resolveVercelHostFrameworkPreset};
@@ -1,4 +1,4 @@
1
- import{getSupportedModuleBaseName,matchesSupportedModuleBaseName}from"./module-files.js";import{pathExists,writeTextFile}from"../files.js";import{resolveVersionToken}from"../version-tokens.js";import{patchPackageJson}from"./package-json.js";import{endpointForProtocol}from"../connections/catalog.js";import{join}from"node:path";import{readFile,readdir,writeFile}from"node:fs/promises";const DEFAULT_CONNECT_PACKAGE_VERSION=`0.4.3`,CONNECT_PACKAGE_NAME=`@vercel/connect`,USER_AUTHORED_CONNECTION_DIR=`agent/connections`;function resolveAuth(e){return e.auth??{kind:`none`}}function envKeysForAuth(e){switch(e.kind){case`bearer-env`:return[e.envVar];case`header`:return e.headers.map(e=>e.envVar);case`connect`:case`none`:return[]}}function authBlock(e){switch(e.kind){case`connect`:return` auth: connect("${e.connector}"),\n`;case`bearer-env`:return` auth: { getToken: async () => ({ token: process.env.${e.envVar}! }) },\n`;case`header`:return` headers: () => ({\n${e.headers.map(e=>` "${e.header}": process.env.${e.envVar}!,`).join(`
1
+ import{getSupportedModuleBaseName,matchesSupportedModuleBaseName}from"./module-files.js";import{pathExists,writeTextFile}from"../files.js";import{resolveVersionToken}from"../version-tokens.js";import{patchPackageJson}from"./package-json.js";import{endpointForProtocol}from"../connections/catalog.js";import{readFile,readdir,writeFile}from"node:fs/promises";import{join}from"node:path";const DEFAULT_CONNECT_PACKAGE_VERSION=`0.4.3`,CONNECT_PACKAGE_NAME=`@vercel/connect`,USER_AUTHORED_CONNECTION_DIR=`agent/connections`;function resolveAuth(e){return e.auth??{kind:`none`}}function envKeysForAuth(e){switch(e.kind){case`bearer-env`:return[e.envVar];case`header`:return e.headers.map(e=>e.envVar);case`connect`:case`none`:return[]}}function authBlock(e){switch(e.kind){case`connect`:return` auth: connect("${e.connector}"),\n`;case`bearer-env`:return` auth: { getToken: async () => ({ token: process.env.${e.envVar}! }) },\n`;case`header`:return` headers: () => ({\n${e.headers.map(e=>` "${e.header}": process.env.${e.envVar}!,`).join(`
2
2
  `)}\n }),\n`;case`none`:return``}}function renderMcpTemplate(e,t,n){return`${n.kind===`connect`?`import { connect } from "@vercel/connect/eve";
3
3
  import { defineMcpClientConnection } from "eve/connections";
4
4
  `:`import { defineMcpClientConnection } from "eve/connections";
@@ -1 +1 @@
1
- import{isPathInside,workspacePatternForProject,workspacePatternsClaimProject}from"./workspace-glob.js";import{ensurePnpmWorkspaceIncludesProject,findAncestorPnpmWorkspaceRoot}from"../primitives/pm/pnpm.js";import{getPackageManagerStrategy}from"../primitives/pm/index.js";import{patchPackageJson}from"./update/package-json.js";import{existsSync,readFileSync}from"node:fs";import{dirname,join,resolve}from"node:path";import{readFile,writeFile}from"node:fs/promises";function isJsonObject(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function packageJsonWorkspacePatterns(e){let t=e.workspaces;return Array.isArray(t)?t.filter(e=>typeof e==`string`):!isJsonObject(t)||!Array.isArray(t.packages)?[]:t.packages.filter(e=>typeof e==`string`)}function readPackageJsonWorkspacePatterns(e){let t=JSON.parse(readFileSync(e,`utf8`));if(!isJsonObject(t))return;let n=packageJsonWorkspacePatterns(t);return n.length===0?void 0:n}function findAncestorPackageJsonWorkspaceRoot(e){let t=dirname(resolve(e));for(;;){let e=join(t,`package.json`);if(existsSync(e))try{if(readPackageJsonWorkspacePatterns(e)!==void 0)return t}catch{}let n=dirname(t);if(n===t)return;t=n}}function findClaimingPackageJsonWorkspaceRoot(e){let t=findAncestorPackageJsonWorkspaceRoot(e);if(t===void 0)return;let r;try{r=readPackageJsonWorkspacePatterns(join(t,`package.json`))}catch{return}return r!==void 0&&workspacePatternsClaimProject(r,t,e)?t:void 0}function findPackageManagerWorkspaceRoot(e,t){switch(e){case`pnpm`:return findAncestorPnpmWorkspaceRoot(t);case`bun`:case`npm`:case`yarn`:return findAncestorPackageJsonWorkspaceRoot(t)}}function isPackageManagerWorkspaceMember(e,t){let n=findPackageManagerWorkspaceRoot(e,t);return n!==void 0&&resolve(n)!==resolve(t)}function workspaceRootPackageJsonPath(e,t){let n=findPackageManagerWorkspaceRoot(e,t);return n===void 0?void 0:join(n,`package.json`)}async function ensurePackageJsonWorkspaceIncludesProject(e){let n=findAncestorPackageJsonWorkspaceRoot(e);if(n===void 0||resolve(n)===resolve(e)||findClaimingPackageJsonWorkspaceRoot(e)===n)return;let r=join(n,`package.json`),i=JSON.parse(await readFile(r,`utf8`)),a=workspacePatternForProject(n,e);if(Array.isArray(i.workspaces))i.workspaces=[...i.workspaces,a];else if(isJsonObject(i.workspaces)&&Array.isArray(i.workspaces.packages))i.workspaces={...i.workspaces,packages:[...i.workspaces.packages,a]};else return;return await writeFile(r,`${JSON.stringify(i,null,2)}\n`,`utf8`),r}async function ensurePackageManagerWorkspaceIncludesProject(e,t){switch(e){case`pnpm`:{let e=findAncestorPnpmWorkspaceRoot(t);return e===void 0?void 0:await ensurePnpmWorkspaceIncludesProject(t)===`written`?join(e,`pnpm-workspace.yaml`):void 0}case`bun`:case`npm`:case`yarn`:return ensurePackageJsonWorkspaceIncludesProject(t)}}function packageManagerRootOnlyPackageJsonPatch(e,t){let n={};if(t.nodeEngineRequirement!==void 0&&(n.nodeEngineRequirement=t.nodeEngineRequirement),t.aiPackageVersion!==void 0)switch(e){case`bun`:case`npm`:n.overrides={ai:t.aiPackageVersion};break;case`yarn`:n.resolutions={ai:t.aiPackageVersion};break;case`pnpm`:break}return n}async function patchWorkspaceRootPackageJson(e,t,n){if(!isPackageManagerWorkspaceMember(e,t))return{changed:!1};let r=workspaceRootPackageJsonPath(e,t);if(r===void 0||!existsSync(r))return{changed:!1};let i=await patchPackageJson(r,packageManagerRootOnlyPackageJsonPatch(e,n));return i.changed&&await n.onWorkspaceRootMutation?.({kind:`package-json`,nodeEngineOverride:i.nodeEngineOverride,path:r}),{...i,path:r}}async function applyPackageManagerWorkspaceConfiguration(t){let n=resolve(t.workspaceProbeRoot??t.projectRoot),r=t.packageManager===`pnpm`?void 0:await ensurePackageManagerWorkspaceIncludesProject(t.packageManager,n),i=await getPackageManagerStrategy(t.packageManager).applyProjectConfiguration(t.projectRoot,{workspaceProbeRoot:n}),o=[...r===void 0?[]:[r],...i.filesWritten],s=[...i.filesSkipped];for(let n of o)isPathInside(t.projectRoot,n)||await t.onWorkspaceRootMutation?.({kind:`workspace-config`,path:n});return{filesSkipped:s,filesWritten:o}}export{applyPackageManagerWorkspaceConfiguration,isPackageManagerWorkspaceMember,patchWorkspaceRootPackageJson};
1
+ import{isPathInside,workspacePatternForProject,workspacePatternsClaimProject}from"./workspace-glob.js";import{ensurePnpmWorkspaceIncludesProject,findAncestorPnpmWorkspaceRoot}from"../primitives/pm/pnpm.js";import{getPackageManagerStrategy}from"../primitives/pm/index.js";import{patchPackageJson}from"./update/package-json.js";import{readFile,writeFile}from"node:fs/promises";import{existsSync,readFileSync}from"node:fs";import{dirname,join,resolve}from"node:path";function isJsonObject(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function packageJsonWorkspacePatterns(e){let t=e.workspaces;return Array.isArray(t)?t.filter(e=>typeof e==`string`):!isJsonObject(t)||!Array.isArray(t.packages)?[]:t.packages.filter(e=>typeof e==`string`)}function readPackageJsonWorkspacePatterns(e){let t=JSON.parse(readFileSync(e,`utf8`));if(!isJsonObject(t))return;let n=packageJsonWorkspacePatterns(t);return n.length===0?void 0:n}function findAncestorPackageJsonWorkspaceRoot(e){let t=dirname(resolve(e));for(;;){let e=join(t,`package.json`);if(existsSync(e))try{if(readPackageJsonWorkspacePatterns(e)!==void 0)return t}catch{}let n=dirname(t);if(n===t)return;t=n}}function findClaimingPackageJsonWorkspaceRoot(e){let t=findAncestorPackageJsonWorkspaceRoot(e);if(t===void 0)return;let r;try{r=readPackageJsonWorkspacePatterns(join(t,`package.json`))}catch{return}return r!==void 0&&workspacePatternsClaimProject(r,t,e)?t:void 0}function findPackageManagerWorkspaceRoot(e,t){switch(e){case`pnpm`:return findAncestorPnpmWorkspaceRoot(t);case`bun`:case`npm`:case`yarn`:return findAncestorPackageJsonWorkspaceRoot(t)}}function isPackageManagerWorkspaceMember(e,t){let n=findPackageManagerWorkspaceRoot(e,t);return n!==void 0&&resolve(n)!==resolve(t)}function workspaceRootPackageJsonPath(e,t){let n=findPackageManagerWorkspaceRoot(e,t);return n===void 0?void 0:join(n,`package.json`)}async function ensurePackageJsonWorkspaceIncludesProject(e){let n=findAncestorPackageJsonWorkspaceRoot(e);if(n===void 0||resolve(n)===resolve(e)||findClaimingPackageJsonWorkspaceRoot(e)===n)return;let r=join(n,`package.json`),i=JSON.parse(await readFile(r,`utf8`)),a=workspacePatternForProject(n,e);if(Array.isArray(i.workspaces))i.workspaces=[...i.workspaces,a];else if(isJsonObject(i.workspaces)&&Array.isArray(i.workspaces.packages))i.workspaces={...i.workspaces,packages:[...i.workspaces.packages,a]};else return;return await writeFile(r,`${JSON.stringify(i,null,2)}\n`,`utf8`),r}async function ensurePackageManagerWorkspaceIncludesProject(e,t){switch(e){case`pnpm`:{let e=findAncestorPnpmWorkspaceRoot(t);return e===void 0?void 0:await ensurePnpmWorkspaceIncludesProject(t)===`written`?join(e,`pnpm-workspace.yaml`):void 0}case`bun`:case`npm`:case`yarn`:return ensurePackageJsonWorkspaceIncludesProject(t)}}function packageManagerRootOnlyPackageJsonPatch(e,t){let n={};if(t.nodeEngineRequirement!==void 0&&(n.nodeEngineRequirement=t.nodeEngineRequirement),t.aiPackageVersion!==void 0)switch(e){case`bun`:case`npm`:n.overrides={ai:t.aiPackageVersion};break;case`yarn`:n.resolutions={ai:t.aiPackageVersion};break;case`pnpm`:break}return n}async function patchWorkspaceRootPackageJson(e,t,n){if(!isPackageManagerWorkspaceMember(e,t))return{changed:!1};let r=workspaceRootPackageJsonPath(e,t);if(r===void 0||!existsSync(r))return{changed:!1};let i=await patchPackageJson(r,packageManagerRootOnlyPackageJsonPatch(e,n));return i.changed&&await n.onWorkspaceRootMutation?.({kind:`package-json`,nodeEngineOverride:i.nodeEngineOverride,path:r}),{...i,path:r}}async function applyPackageManagerWorkspaceConfiguration(t){let n=resolve(t.workspaceProbeRoot??t.projectRoot),r=t.packageManager===`pnpm`?void 0:await ensurePackageManagerWorkspaceIncludesProject(t.packageManager,n),i=await getPackageManagerStrategy(t.packageManager).applyProjectConfiguration(t.projectRoot,{workspaceProbeRoot:n}),o=[...r===void 0?[]:[r],...i.filesWritten],s=[...i.filesSkipped];for(let n of o)isPathInside(t.projectRoot,n)||await t.onWorkspaceRootMutation?.({kind:`workspace-config`,path:n});return{filesSkipped:s,filesWritten:o}}export{applyPackageManagerWorkspaceConfiguration,isPackageManagerWorkspaceMember,patchWorkspaceRootPackageJson};
@@ -1 +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";import{parseSlackConnectorDetails,parseSlackConnectors}from"./slack-connect.js";import{join}from"node:path";import{SLACK_CHANNEL_DEFAULT_ROUTE}from"#setup/scaffold/index.js";import{readFile}from"node:fs/promises";import"#setup/primitives/run-vercel.js";import"#setup/cli/index.js";import{CONNECT_MUTATION_TIMEOUT_MS,replaceConnectTrigger}from"#setup/connect-provisioning.js";const CONNECT_LOOKUP_TIMEOUT_MS=6e4,VercelProjectLinkSchema=object({projectId:string().min(1),orgId:string().min(1)});async function listSlackConnectors(e,t,n,i){let a=await e.captureVercel([`connect`,`list`,`-F`,`json`,`--all-projects`],{cwd:t,onOutput:n,timeoutMs:CONNECT_LOOKUP_TIMEOUT_MS,signal:i});if(!a.ok)return{state:`failed`,message:a.failure.message};try{let e=JSON.parse(a.stdout);if(typeof e!=`object`||!e)return{state:`failed`,message:`Vercel returned a malformed connector list.`};let t=e;return Array.isArray(t.connectors??t.clients)?{state:`ok`,body:e,connectors:parseSlackConnectors(e)}:{state:`failed`,message:`Vercel returned a malformed connector list.`}}catch{return{state:`failed`,message:`Vercel returned invalid JSON for the connector list.`}}}async function readProjectLink(e){try{let t=await readFile(join(e,`.vercel`,`project.json`),`utf8`),n=VercelProjectLinkSchema.safeParse(JSON.parse(t));return n.success?n.data:void 0}catch{return}}async function findSlackConnector(e,t,n,r,i,a){let o=await listSlackConnectors(e,t,i,a);if(o.state===`failed`)return o;let s=new Set(o.connectors.map(e=>e.uid));if(n===void 0)return{state:`not-found`,connectorUids:s};let c=o.connectors.filter(e=>e.id!==void 0&&e.projectIds.includes(n)).sort((e,t)=>t.createdAt-e.createdAt).map(({uid:e,id:t})=>({uid:e,id:t}));if(c.length===0)return{state:`not-found`,connectorUids:s};let l=c.find(e=>e.uid===r);return l===void 0?{state:`found`,connectors:c,connectorUids:s}:{state:`found`,connectors:c,preferred:l,connectorUids:s}}async function attachSlackConnector(e,t,n,r,i){return replaceConnectTrigger({connectorUid:n.uid,projectRoot:t,triggerPath:SLACK_CHANNEL_DEFAULT_ROUTE,onOutput:r,signal:i,deps:e})}async function fetchSlackConnectorDetails(e){let t=e.orgId===void 0?``:`?teamId=${encodeURIComponent(e.orgId)}`,r=[`api`,`/v1/connect/connectors/${encodeURIComponent(e.connectorId)}${t}`];e.orgId!==void 0&&r.push(`--scope`,e.orgId);let i=await e.deps.captureVercel(r,{cwd:e.projectRoot,onOutput:e.onOutput,timeoutMs:e.timeoutMs,signal:e.signal});if(!i.ok)return{state:`failed`,message:i.failure.message};try{let t=parseSlackConnectorDetails(JSON.parse(i.stdout));return t?.ref.id===e.connectorId?{state:`found`,details:t}:{state:`failed`,message:`Vercel returned an invalid Slack connector.`}}catch{return{state:`failed`,message:`Vercel returned invalid JSON for the Slack connector.`}}}async function fetchSlackWorkspace(e){let t=await fetchSlackConnectorDetails(e);return t.state===`failed`?t:t.details.workspace===void 0?{state:`pending`}:{state:`connected`,workspace:t.details.workspace}}async function cleanupConnectorUid(e,t){let{log:n,deps:r,projectRoot:i,onOutput:a}=e;return await r.runVercel([`connect`,`remove`,t,`--disconnect-all`,`--yes`],{cwd:i,onOutput:a,timeoutMs:CONNECT_MUTATION_TIMEOUT_MS})?!0:(n.warning(`Could not remove the abandoned Slack connector. Run \`vercel connect remove ${t} --disconnect-all --yes\` to clean it up.`),!1)}async function cleanupConnectorUids(e,t){let n=[];for(let r of new Set(t))await cleanupConnectorUid(e,r)||n.push(r);return n.length===0?{state:`clean`}:{state:`failed`,connectorUids:n}}async function cleanupCreatedAttempt(e,t){if(t.createdRef)return cleanupConnectorUids(e,[t.createdRef.uid]);e.log.warning(`Vercel returned no connector UID for the abandoned Slack Connect request, so eve cannot prove that request was cancelled. No connector was removed; do not retry until the browser request is no longer usable.`);let n=await listSlackConnectors(e.deps,e.projectRoot,e.onOutput);return n.state===`failed`?{state:`failed`,connectorUids:[]}:{state:`failed`,connectorUids:n.connectors.map(e=>e.uid).filter(e=>(e===t.expectedUid||e.startsWith(`${t.expectedUid}-`))&&!t.baselineConnectorUids.has(e))}}export{CONNECT_LOOKUP_TIMEOUT_MS,attachSlackConnector,cleanupCreatedAttempt,fetchSlackConnectorDetails,fetchSlackWorkspace,findSlackConnector,listSlackConnectors,readProjectLink};
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";import{parseSlackConnectorDetails,parseSlackConnectors}from"./slack-connect.js";import{readFile}from"node:fs/promises";import{join}from"node:path";import{SLACK_CHANNEL_DEFAULT_ROUTE}from"#setup/scaffold/index.js";import"#setup/primitives/run-vercel.js";import"#setup/cli/index.js";import{CONNECT_MUTATION_TIMEOUT_MS,replaceConnectTrigger}from"#setup/connect-provisioning.js";const CONNECT_LOOKUP_TIMEOUT_MS=6e4,VercelProjectLinkSchema=object({projectId:string().min(1),orgId:string().min(1)});async function listSlackConnectors(e,t,n,i){let a=await e.captureVercel([`connect`,`list`,`-F`,`json`,`--all-projects`],{cwd:t,onOutput:n,timeoutMs:CONNECT_LOOKUP_TIMEOUT_MS,signal:i});if(!a.ok)return{state:`failed`,message:a.failure.message};try{let e=JSON.parse(a.stdout);if(typeof e!=`object`||!e)return{state:`failed`,message:`Vercel returned a malformed connector list.`};let t=e;return Array.isArray(t.connectors??t.clients)?{state:`ok`,body:e,connectors:parseSlackConnectors(e)}:{state:`failed`,message:`Vercel returned a malformed connector list.`}}catch{return{state:`failed`,message:`Vercel returned invalid JSON for the connector list.`}}}async function readProjectLink(e){try{let t=await readFile(join(e,`.vercel`,`project.json`),`utf8`),n=VercelProjectLinkSchema.safeParse(JSON.parse(t));return n.success?n.data:void 0}catch{return}}async function findSlackConnector(e,t,n,r,i,a){let o=await listSlackConnectors(e,t,i,a);if(o.state===`failed`)return o;let s=new Set(o.connectors.map(e=>e.uid));if(n===void 0)return{state:`not-found`,connectorUids:s};let c=o.connectors.filter(e=>e.id!==void 0&&e.projectIds.includes(n)).sort((e,t)=>t.createdAt-e.createdAt).map(({uid:e,id:t})=>({uid:e,id:t}));if(c.length===0)return{state:`not-found`,connectorUids:s};let l=c.find(e=>e.uid===r);return l===void 0?{state:`found`,connectors:c,connectorUids:s}:{state:`found`,connectors:c,preferred:l,connectorUids:s}}async function attachSlackConnector(e,t,n,r,i){return replaceConnectTrigger({connectorUid:n.uid,projectRoot:t,triggerPath:SLACK_CHANNEL_DEFAULT_ROUTE,onOutput:r,signal:i,deps:e})}async function fetchSlackConnectorDetails(e){let t=e.orgId===void 0?``:`?teamId=${encodeURIComponent(e.orgId)}`,r=[`api`,`/v1/connect/connectors/${encodeURIComponent(e.connectorId)}${t}`];e.orgId!==void 0&&r.push(`--scope`,e.orgId);let i=await e.deps.captureVercel(r,{cwd:e.projectRoot,onOutput:e.onOutput,timeoutMs:e.timeoutMs,signal:e.signal});if(!i.ok)return{state:`failed`,message:i.failure.message};try{let t=parseSlackConnectorDetails(JSON.parse(i.stdout));return t?.ref.id===e.connectorId?{state:`found`,details:t}:{state:`failed`,message:`Vercel returned an invalid Slack connector.`}}catch{return{state:`failed`,message:`Vercel returned invalid JSON for the Slack connector.`}}}async function fetchSlackWorkspace(e){let t=await fetchSlackConnectorDetails(e);return t.state===`failed`?t:t.details.workspace===void 0?{state:`pending`}:{state:`connected`,workspace:t.details.workspace}}async function cleanupConnectorUid(e,t){let{log:n,deps:r,projectRoot:i,onOutput:a}=e;return await r.runVercel([`connect`,`remove`,t,`--disconnect-all`,`--yes`],{cwd:i,onOutput:a,timeoutMs:CONNECT_MUTATION_TIMEOUT_MS})?!0:(n.warning(`Could not remove the abandoned Slack connector. Run \`vercel connect remove ${t} --disconnect-all --yes\` to clean it up.`),!1)}async function cleanupConnectorUids(e,t){let n=[];for(let r of new Set(t))await cleanupConnectorUid(e,r)||n.push(r);return n.length===0?{state:`clean`}:{state:`failed`,connectorUids:n}}async function cleanupCreatedAttempt(e,t){if(t.createdRef)return cleanupConnectorUids(e,[t.createdRef.uid]);e.log.warning(`Vercel returned no connector UID for the abandoned Slack Connect request, so eve cannot prove that request was cancelled. No connector was removed; do not retry until the browser request is no longer usable.`);let n=await listSlackConnectors(e.deps,e.projectRoot,e.onOutput);return n.state===`failed`?{state:`failed`,connectorUids:[]}:{state:`failed`,connectorUids:n.connectors.map(e=>e.uid).filter(e=>(e===t.expectedUid||e.startsWith(`${t.expectedUid}-`))&&!t.baselineConnectorUids.has(e))}}export{CONNECT_LOOKUP_TIMEOUT_MS,attachSlackConnector,cleanupCreatedAttempt,fetchSlackConnectorDetails,fetchSlackWorkspace,findSlackConnector,listSlackConnectors,readProjectLink};
@@ -1 +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";import{readProjectLink}from"./project-resolution.js";import{resolveVercelHostFrameworkPreset}from"./scaffold/update/channels.js";import"./scaffold/index.js";import{isForbiddenApiFailure,normalizeVercelApiResult}from"./vercel-api-failure.js";import{VERCEL_PROJECT_REQUEST_TIMEOUT_MS,parseVercelJson,requireVercelTeamAccess}from"./vercel-project-api.js";import{extname,join}from"node:path";import*as fs from"node:fs/promises";import{captureVercel}from"#setup/primitives/index.js";import"#setup/cli/index.js";const VercelProjectFrameworkSchema=object({framework:string().min(1).nullish()}),EVE_FRAMEWORK_INTEGRATIONS={nextjs:{label:`Next.js`,importSpecifier:`eve/next`},nuxt:{label:`Nuxt`,importSpecifier:`eve/nuxt`},nuxtjs:{label:`Nuxt`,importSpecifier:`eve/nuxt`},sveltekit:{label:`SvelteKit`,importSpecifier:`eve/sveltekit`}},FRAMEWORK_INTEGRATION_SOURCE_EXTENSIONS=new Set([`.cjs`,`.cts`,`.js`,`.json`,`.jsx`,`.mjs`,`.mts`,`.svelte`,`.ts`,`.tsx`,`.vue`]),FRAMEWORK_INTEGRATION_IGNORED_DIRECTORIES=new Set([`.eve`,`.git`,`.next`,`.nuxt`,`.output`,`.svelte-kit`,`.turbo`,`.vercel`,`build`,`coverage`,`dist`,`node_modules`]);function parseProjectFramework(e,t){let n=VercelProjectFrameworkSchema.safeParse(parseVercelJson(e,t));if(!n.success)throw Error(`Could not read Vercel project framework from ${t}.`);return n.data.framework??void 0}async function fetchProjectFramework(e,t,n,r){let s=normalizeVercelApiResult(await captureVercel([`api`,`/v9/projects/${n}`,`--scope`,t,`--raw`],{cwd:e,signal:r.signal,timeoutMs:VERCEL_PROJECT_REQUEST_TIMEOUT_MS}));if(s.ok)return parseProjectFramework(s.stdout,`project ${n}`);throw isForbiddenApiFailure(s.failure)&&requireVercelTeamAccess(s.failure),Error(`Could not inspect Vercel project "${n}". ${s.failure.message}`)}async function setProjectFramework(e,t,n,r,s,l){let u=normalizeVercelApiResult(await captureVercel([`api`,`/v9/projects/${n}`,`--scope`,t,`--method`,`PATCH`,`--raw-field`,`framework=${r}`,`--raw`],{cwd:e,onOutput:s,signal:l.signal,timeoutMs:VERCEL_PROJECT_REQUEST_TIMEOUT_MS}));if(!u.ok)throw isForbiddenApiFailure(u.failure)&&requireVercelTeamAccess(u.failure),Error(`Could not set Vercel project "${n}" framework to ${r}. ${u.failure.message}`)}async function confirmDetectedFramework(e,t,n){return await e.select({message:`Vercel detected ${n.label}. Is this project using ${n.importSpecifier}?`,options:[{value:!0,label:`Yes, keep ${t}`,hint:`Use this for a host app that integrates eve through ${n.importSpecifier}.`},{value:!1,label:`No, switch to eve`,hint:`Use this for a standalone eve agent.`}]})?`keep`:`switch-to-eve`}function sourceMentionsPackageSpecifier(e,t){return e.includes(`"${t}"`)||e.includes(`'${t}'`)||e.includes(`\`${t}\``)}async function directoryContainsPackageSpecifier(e,t){let n;try{n=await fs.readdir(e,{encoding:`utf8`,withFileTypes:!0})}catch{return!1}for(let r of n){let n=join(e,r.name);if(r.isDirectory()){if(FRAMEWORK_INTEGRATION_IGNORED_DIRECTORIES.has(r.name))continue;if(await directoryContainsPackageSpecifier(n,t))return!0;continue}if(!(!r.isFile()||!FRAMEWORK_INTEGRATION_SOURCE_EXTENSIONS.has(extname(r.name))))try{if(sourceMentionsPackageSpecifier(await fs.readFile(n,`utf8`),t))return!0}catch{continue}}return!1}async function detectFrameworkIntegrationImport(e,t){return directoryContainsPackageSpecifier(e,t)}async function resolveDetectedFrameworkAction(e,t,n,r){let i=EVE_FRAMEWORK_INTEGRATIONS[n];return i===void 0?`switch-to-eve`:await(r.detectFrameworkIntegrationImport??detectFrameworkIntegrationImport)(t,i.importSpecifier)?`keep`:r.headless?`switch-to-eve`:confirmDetectedFramework(e,n,i)}function frameworkPresetLabel(e){return EVE_FRAMEWORK_INTEGRATIONS[e]?.label??e}function describeError(e){return e instanceof Error?e.message:String(e)}async function syncHostFrameworkPreset(e,t,i,a){let o=await resolveVercelHostFrameworkPreset(t);if(o===void 0)return;let s=await readProjectLink(t);if(s===void 0)return;let c=frameworkPresetLabel(o),l;try{l=await fetchProjectFramework(t,s.orgId,s.projectId,a)}catch(t){if(a.signal?.aborted)throw t;e.log.warning(`Could not check this Vercel project's Framework Preset (${describeError(t)}). If it is not already ${c}, set it under Project Settings → Build and Deployment → Framework Settings before deploying.`);return}if(l===o)return;let u=l===void 0?void 0:frameworkPresetLabel(l),d=u===void 0?`had no Framework Preset set`:`was set to "${u}"`;try{await setProjectFramework(t,s.orgId,s.projectId,o,i,a)}catch(t){if(a.signal?.aborted)throw t;e.log.warning(`${describeError(t)} Set this Vercel project's Framework Preset to ${c} (Project Settings → Build and Deployment → Framework Settings) before deploying, or the deployment will not build your ${c} app.`);return}e.log.info(`This project uses ${c}, but its Vercel Framework Preset ${d}; switched it to ${c} so the deployment builds your app.`)}async function ensureCreatedProjectFramework(e,t,n,r,i,a){let o=await fetchProjectFramework(t,n,r,a);o!==`eve`&&(o===void 0?`switch-to-eve`:await resolveDetectedFrameworkAction(e,t,o,a))===`switch-to-eve`&&await setProjectFramework(t,n,r,`eve`,i,a)}export{ensureCreatedProjectFramework,syncHostFrameworkPreset};
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";import{readProjectLink}from"./project-resolution.js";import{resolveVercelHostFrameworkPreset}from"./scaffold/update/channels.js";import"./scaffold/index.js";import{isForbiddenApiFailure,normalizeVercelApiResult}from"./vercel-api-failure.js";import{VERCEL_PROJECT_REQUEST_TIMEOUT_MS,parseVercelJson,requireVercelTeamAccess}from"./vercel-project-api.js";import*as fs from"node:fs/promises";import{extname,join}from"node:path";import{captureVercel}from"#setup/primitives/index.js";import"#setup/cli/index.js";const VercelProjectFrameworkSchema=object({framework:string().min(1).nullish()}),EVE_FRAMEWORK_INTEGRATIONS={nextjs:{label:`Next.js`,importSpecifier:`eve/next`},nuxt:{label:`Nuxt`,importSpecifier:`eve/nuxt`},nuxtjs:{label:`Nuxt`,importSpecifier:`eve/nuxt`},sveltekit:{label:`SvelteKit`,importSpecifier:`eve/sveltekit`}},FRAMEWORK_INTEGRATION_SOURCE_EXTENSIONS=new Set([`.cjs`,`.cts`,`.js`,`.json`,`.jsx`,`.mjs`,`.mts`,`.svelte`,`.ts`,`.tsx`,`.vue`]),FRAMEWORK_INTEGRATION_IGNORED_DIRECTORIES=new Set([`.eve`,`.git`,`.next`,`.nuxt`,`.output`,`.svelte-kit`,`.turbo`,`.vercel`,`build`,`coverage`,`dist`,`node_modules`]);function parseProjectFramework(e,t){let n=VercelProjectFrameworkSchema.safeParse(parseVercelJson(e,t));if(!n.success)throw Error(`Could not read Vercel project framework from ${t}.`);return n.data.framework??void 0}async function fetchProjectFramework(e,t,n,r){let s=normalizeVercelApiResult(await captureVercel([`api`,`/v9/projects/${n}`,`--scope`,t,`--raw`],{cwd:e,signal:r.signal,timeoutMs:VERCEL_PROJECT_REQUEST_TIMEOUT_MS}));if(s.ok)return parseProjectFramework(s.stdout,`project ${n}`);throw isForbiddenApiFailure(s.failure)&&requireVercelTeamAccess(s.failure),Error(`Could not inspect Vercel project "${n}". ${s.failure.message}`)}async function setProjectFramework(e,t,n,r,s,l){let u=normalizeVercelApiResult(await captureVercel([`api`,`/v9/projects/${n}`,`--scope`,t,`--method`,`PATCH`,`--raw-field`,`framework=${r}`,`--raw`],{cwd:e,onOutput:s,signal:l.signal,timeoutMs:VERCEL_PROJECT_REQUEST_TIMEOUT_MS}));if(!u.ok)throw isForbiddenApiFailure(u.failure)&&requireVercelTeamAccess(u.failure),Error(`Could not set Vercel project "${n}" framework to ${r}. ${u.failure.message}`)}async function confirmDetectedFramework(e,t,n){return await e.select({message:`Vercel detected ${n.label}. Is this project using ${n.importSpecifier}?`,options:[{value:!0,label:`Yes, keep ${t}`,hint:`Use this for a host app that integrates eve through ${n.importSpecifier}.`},{value:!1,label:`No, switch to eve`,hint:`Use this for a standalone eve agent.`}]})?`keep`:`switch-to-eve`}function sourceMentionsPackageSpecifier(e,t){return e.includes(`"${t}"`)||e.includes(`'${t}'`)||e.includes(`\`${t}\``)}async function directoryContainsPackageSpecifier(e,t){let n;try{n=await fs.readdir(e,{encoding:`utf8`,withFileTypes:!0})}catch{return!1}for(let r of n){let n=join(e,r.name);if(r.isDirectory()){if(FRAMEWORK_INTEGRATION_IGNORED_DIRECTORIES.has(r.name))continue;if(await directoryContainsPackageSpecifier(n,t))return!0;continue}if(!(!r.isFile()||!FRAMEWORK_INTEGRATION_SOURCE_EXTENSIONS.has(extname(r.name))))try{if(sourceMentionsPackageSpecifier(await fs.readFile(n,`utf8`),t))return!0}catch{continue}}return!1}async function detectFrameworkIntegrationImport(e,t){return directoryContainsPackageSpecifier(e,t)}async function resolveDetectedFrameworkAction(e,t,n,r){let i=EVE_FRAMEWORK_INTEGRATIONS[n];return i===void 0?`switch-to-eve`:await(r.detectFrameworkIntegrationImport??detectFrameworkIntegrationImport)(t,i.importSpecifier)?`keep`:r.headless?`switch-to-eve`:confirmDetectedFramework(e,n,i)}function frameworkPresetLabel(e){return EVE_FRAMEWORK_INTEGRATIONS[e]?.label??e}function describeError(e){return e instanceof Error?e.message:String(e)}async function syncHostFrameworkPreset(e,t,i,a){let o=await resolveVercelHostFrameworkPreset(t);if(o===void 0)return;let s=await readProjectLink(t);if(s===void 0)return;let c=frameworkPresetLabel(o),l;try{l=await fetchProjectFramework(t,s.orgId,s.projectId,a)}catch(t){if(a.signal?.aborted)throw t;e.log.warning(`Could not check this Vercel project's Framework Preset (${describeError(t)}). If it is not already ${c}, set it under Project Settings → Build and Deployment → Framework Settings before deploying.`);return}if(l===o)return;let u=l===void 0?void 0:frameworkPresetLabel(l),d=u===void 0?`had no Framework Preset set`:`was set to "${u}"`;try{await setProjectFramework(t,s.orgId,s.projectId,o,i,a)}catch(t){if(a.signal?.aborted)throw t;e.log.warning(`${describeError(t)} Set this Vercel project's Framework Preset to ${c} (Project Settings → Build and Deployment → Framework Settings) before deploying, or the deployment will not build your ${c} app.`);return}e.log.info(`This project uses ${c}, but its Vercel Framework Preset ${d}; switched it to ${c} so the deployment builds your app.`)}async function ensureCreatedProjectFramework(e,t,n,r,i,a){let o=await fetchProjectFramework(t,n,r,a);o!==`eve`&&(o===void 0?`switch-to-eve`:await resolveDetectedFrameworkAction(e,t,o,a))===`switch-to-eve`&&await setProjectFramework(t,n,r,`eve`,i,a)}export{ensureCreatedProjectFramework,syncHostFrameworkPreset};
@@ -29,6 +29,8 @@ export declare function isObject(value: unknown): value is Record<string, unknow
29
29
  * meaningful value by display or correlation logic.
30
30
  */
31
31
  export declare function isNonEmptyString(value: unknown): value is string;
32
+ /** Returns a non-empty string or `undefined` for any other value. */
33
+ export declare function readNonEmptyString(value: unknown): string | undefined;
32
34
  /**
33
35
  * Returns `true` when `value` is a thenable — an object with a `then`
34
36
  * function. Used to reject async instrumentation metadata projectors
@@ -1 +1 @@
1
- function isObject(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function isNonEmptyString(e){return typeof e==`string`&&e.length>0}function isThenable(e){return isObject(e)&&typeof e.then==`function`}function isErrnoCode(e,t){return e instanceof Error&&`code`in e&&e.code===t}function isPlainRecord(e){if(!isObject(e))return!1;let t=Object.getPrototypeOf(e);return t===Object.prototype||t===null}export{isErrnoCode,isNonEmptyString,isObject,isPlainRecord,isThenable};
1
+ function isObject(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function isNonEmptyString(e){return typeof e==`string`&&e.length>0}function readNonEmptyString(e){return isNonEmptyString(e)?e:void 0}function isThenable(e){return isObject(e)&&typeof e.then==`function`}function isErrnoCode(e,t){return e instanceof Error&&`code`in e&&e.code===t}function isPlainRecord(e){if(!isObject(e))return!1;let t=Object.getPrototypeOf(e);return t===Object.prototype||t===null}export{isErrnoCode,isNonEmptyString,isObject,isPlainRecord,isThenable,readNonEmptyString};
@@ -1 +1 @@
1
- import{dirname,join}from"node:path";import{mkdir,writeFile}from"node:fs/promises";import{resolveSandboxSkillRoot,resolveSandboxSkillWritePath}from"#shared/skill-paths.js";import{Buffer}from"node:buffer";function normalizeSkillPackage(e){assertSafeSkillPackageName(e.name);let t=[{content:Buffer.from(e.markdown,`utf8`),relativePath:`SKILL.md`}];for(let[n,r]of Object.entries(e.files??{}))assertSafeSkillPackageFilePath(n),t.push({content:contentToBuffer(r),relativePath:n});return t.sort((e,t)=>comparePaths(e.relativePath,t.relativePath)),{description:e.description,files:t,license:e.license,markdown:e.markdown,metadata:e.metadata===void 0?void 0:{...e.metadata},name:e.name}}async function writeSkillPackageDirectory(i){for(let a of i.skill.files){let o=join(i.rootPath,`skills`,i.skill.name,a.relativePath);await mkdir(dirname(o),{recursive:!0}),await writeFile(o,a.content)}}async function writeSkillPackageToSandbox(e){for(let t of e.skill.files)await e.sandbox.writeBinaryFile({content:t.content,path:await resolveSandboxSkillWritePath({name:e.skill.name,relativePath:t.relativePath,sandbox:e.sandbox})})}async function removeSkillPackageFromSandbox(e){assertSafeSkillPackageName(e.name);let t=await resolveSandboxSkillRoot({sandbox:e.sandbox});await e.sandbox.removePath({force:!0,path:`${t}/${e.name}`,recursive:!0})}function assertSafeSkillPackageName(e){if(e.length===0||e.startsWith(`.`)||e.includes(`/`)||e.includes(`\\`)||e.includes(`..`)||!/^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(e)||/^[A-Za-z]:/.test(e))throw Error(`Expected skill name to be a non-empty shell-safe path segment starting with an alphanumeric character and containing only alphanumerics, ".", "_", or "-".`)}function assertSafeSkillPackageFilePath(e){if(e===`SKILL.md`)throw Error(`Skill package files must not include "SKILL.md"; eve generates it.`);if(e.length===0||e.startsWith(`/`)||e.includes(`\\`)||/^[A-Za-z]:/.test(e)||e.split(`/`).some(e=>e.length===0||e===`.`||e===`..`))throw Error(`Expected skill package file paths to be relative POSIX paths.`)}function contentToBuffer(e){return typeof e==`string`?Buffer.from(e,`utf8`):Buffer.from(e)}function comparePaths(e,t){return e<t?-1:+(e>t)}export{assertSafeSkillPackageName,normalizeSkillPackage,removeSkillPackageFromSandbox,writeSkillPackageDirectory,writeSkillPackageToSandbox};
1
+ import{mkdir,writeFile}from"node:fs/promises";import{dirname,join}from"node:path";import{resolveSandboxSkillRoot,resolveSandboxSkillWritePath}from"#shared/skill-paths.js";import{Buffer}from"node:buffer";function normalizeSkillPackage(e){assertSafeSkillPackageName(e.name);let t=[{content:Buffer.from(e.markdown,`utf8`),relativePath:`SKILL.md`}];for(let[n,r]of Object.entries(e.files??{}))assertSafeSkillPackageFilePath(n),t.push({content:contentToBuffer(r),relativePath:n});return t.sort((e,t)=>comparePaths(e.relativePath,t.relativePath)),{description:e.description,files:t,license:e.license,markdown:e.markdown,metadata:e.metadata===void 0?void 0:{...e.metadata},name:e.name}}async function writeSkillPackageDirectory(i){for(let a of i.skill.files){let o=join(i.rootPath,`skills`,i.skill.name,a.relativePath);await mkdir(dirname(o),{recursive:!0}),await writeFile(o,a.content)}}async function writeSkillPackageToSandbox(e){for(let t of e.skill.files)await e.sandbox.writeBinaryFile({content:t.content,path:await resolveSandboxSkillWritePath({name:e.skill.name,relativePath:t.relativePath,sandbox:e.sandbox})})}async function removeSkillPackageFromSandbox(e){assertSafeSkillPackageName(e.name);let t=await resolveSandboxSkillRoot({sandbox:e.sandbox});await e.sandbox.removePath({force:!0,path:`${t}/${e.name}`,recursive:!0})}function assertSafeSkillPackageName(e){if(e.length===0||e.startsWith(`.`)||e.includes(`/`)||e.includes(`\\`)||e.includes(`..`)||!/^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(e)||/^[A-Za-z]:/.test(e))throw Error(`Expected skill name to be a non-empty shell-safe path segment starting with an alphanumeric character and containing only alphanumerics, ".", "_", or "-".`)}function assertSafeSkillPackageFilePath(e){if(e===`SKILL.md`)throw Error(`Skill package files must not include "SKILL.md"; eve generates it.`);if(e.length===0||e.startsWith(`/`)||e.includes(`\\`)||/^[A-Za-z]:/.test(e)||e.split(`/`).some(e=>e.length===0||e===`.`||e===`..`))throw Error(`Expected skill package file paths to be relative POSIX paths.`)}function contentToBuffer(e){return typeof e==`string`?Buffer.from(e,`utf8`):Buffer.from(e)}function comparePaths(e,t){return e<t?-1:+(e>t)}export{assertSafeSkillPackageName,normalizeSkillPackage,removeSkillPackageFromSandbox,writeSkillPackageDirectory,writeSkillPackageToSandbox};
@@ -9,6 +9,10 @@ export declare function formatFallbackSkillPath(input: {
9
9
  readonly name: string;
10
10
  readonly relativePath: string;
11
11
  }): string;
12
+ /**
13
+ * Resolves where skills live in the sandbox: under the probed home when it has
14
+ * one, and under {@link FALLBACK_SKILL_ROOT} when it does not.
15
+ */
12
16
  export declare function resolveSandboxSkillRoot(input: {
13
17
  readonly sandbox: SandboxSession;
14
18
  }): Promise<string>;
@@ -32,7 +36,3 @@ export declare function resolveSandboxSkillWritePath(input: {
32
36
  readonly relativePath: string;
33
37
  readonly sandbox: SandboxSession;
34
38
  }): Promise<string>;
35
- export declare function resolveSandboxSeedFilePath(input: {
36
- readonly path: string;
37
- readonly sandbox: SandboxSession;
38
- }): Promise<string>;
@@ -1,2 +1,2 @@
1
- const MODEL_SKILL_ROOT=`$HOME/.agents/skills`,FALLBACK_SKILL_ROOT=`/workspace/skills`,MODEL_HOME_ROOT=`$HOME`,sandboxHomeCache=new WeakMap;function formatSkillModelPath(t){return formatSkillPath({name:t.name,relativePath:t.relativePath,root:MODEL_SKILL_ROOT})}function formatFallbackSkillPath(e){return formatSkillPath({name:e.name,relativePath:e.relativePath,root:FALLBACK_SKILL_ROOT})}async function resolveSandboxSkillRoot(e){let n=await resolveSandboxHome(e.sandbox);return n===null?FALLBACK_SKILL_ROOT:joinHomeSkillRoot(n)}async function resolveSandboxModelPath(e){if(!isModelHomePath(e.path))return e.path;let n=await resolveSandboxHome(e.sandbox);if(n!==null){let t=e.path.slice(5);return t.length===0?n:`${n===`/`?``:n}${t}`}return isModelSkillPath(e.path)?`${FALLBACK_SKILL_ROOT}${e.path.slice(20)}`:e.path}async function resolveSandboxSkillReadPaths(e){return[formatSkillPath({name:e.name,relativePath:e.relativePath,root:await resolveSandboxSkillRoot({sandbox:e.sandbox})})]}async function resolveSandboxSkillWritePath(e){return formatSkillPath({name:e.name,relativePath:e.relativePath,root:await resolveSandboxSkillRoot({sandbox:e.sandbox})})}async function resolveSandboxSeedFilePath(e){return isModelSkillPath(e.path)?await resolveSandboxModelPath(e):e.path}function formatSkillPath(e){return`${e.root}/${e.name}/${e.relativePath}`}async function resolveSandboxHome(e){let t=sandboxHomeCache.get(e);if(t!==void 0)return await t;let n=probeSandboxHome(e);return sandboxHomeCache.set(e,n),await n}async function probeSandboxHome(e){try{let t=await e.run({command:`printf '%s\\n' "$HOME"`});if(t.exitCode!==0)return null;let n=t.stdout.trim();return isUsableSandboxHome(n)?normalizeSandboxHome(n):null}catch{return null}}function isModelHomePath(e){return e===MODEL_HOME_ROOT||e.startsWith(`${MODEL_HOME_ROOT}/`)}function isModelSkillPath(e){return e===`$HOME/.agents/skills`||e.startsWith(`$HOME/.agents/skills/`)}function isUsableSandboxHome(e){return e.length>0&&e.startsWith(`/`)&&!e.includes(`\0`)&&!e.includes(`
2
- `)&&!e.includes(`\r`)}function joinHomeSkillRoot(e){return`${e===`/`?``:e}/.agents/skills`}function normalizeSandboxHome(e){return e===`/`?e:e.replace(/\/+$/,``)}export{FALLBACK_SKILL_ROOT,MODEL_SKILL_ROOT,formatFallbackSkillPath,formatSkillModelPath,resolveSandboxModelPath,resolveSandboxSeedFilePath,resolveSandboxSkillReadPaths,resolveSandboxSkillRoot,resolveSandboxSkillWritePath};
1
+ const MODEL_HOME_ROOT=`$HOME`,MODEL_SKILL_ROOT=`${MODEL_HOME_ROOT}/.agents/skills`,FALLBACK_SKILL_ROOT=`/workspace/skills`,sandboxHomeCache=new WeakMap;function formatSkillModelPath(e){return formatSkillPath({name:e.name,relativePath:e.relativePath,root:MODEL_SKILL_ROOT})}function formatFallbackSkillPath(e){return formatSkillPath({name:e.name,relativePath:e.relativePath,root:FALLBACK_SKILL_ROOT})}async function resolveSandboxSkillRoot(e){return await resolveSandboxModelPath({path:MODEL_SKILL_ROOT,sandbox:e.sandbox})}async function resolveSandboxModelPath(e){if(!isModelHomePath(e.path))return e.path;let r=await resolveSandboxHome(e.sandbox);if(r!==null){let t=e.path.slice(5);return t.length===0?r:`${r===`/`?``:r}${t}`}return isModelSkillPath(e.path)?`${FALLBACK_SKILL_ROOT}${e.path.slice(MODEL_SKILL_ROOT.length)}`:e.path}async function resolveSandboxSkillReadPaths(e){return[formatSkillPath({name:e.name,relativePath:e.relativePath,root:await resolveSandboxSkillRoot({sandbox:e.sandbox})})]}async function resolveSandboxSkillWritePath(e){return formatSkillPath({name:e.name,relativePath:e.relativePath,root:await resolveSandboxSkillRoot({sandbox:e.sandbox})})}function formatSkillPath(e){return`${e.root}/${e.name}/${e.relativePath}`}async function resolveSandboxHome(e){let t=sandboxHomeCache.get(e);if(t!==void 0)return await t;let n=probeSandboxHome(e);return sandboxHomeCache.set(e,n),await n}async function probeSandboxHome(e){try{let t=await e.run({command:`printf '%s\\n' "$HOME"`});if(t.exitCode!==0)return null;let n=t.stdout.trim();return isUsableSandboxHome(n)?normalizeSandboxHome(n):null}catch{return null}}function isModelHomePath(t){return t===MODEL_HOME_ROOT||t.startsWith(`${MODEL_HOME_ROOT}/`)}function isModelSkillPath(e){return e===MODEL_SKILL_ROOT||e.startsWith(`${MODEL_SKILL_ROOT}/`)}function isUsableSandboxHome(e){return e.length>0&&e.startsWith(`/`)&&!e.includes(`\0`)&&!e.includes(`
2
+ `)&&!e.includes(`\r`)}function normalizeSandboxHome(e){return e===`/`?e:e.replace(/\/+$/,``)}export{FALLBACK_SKILL_ROOT,MODEL_SKILL_ROOT,formatFallbackSkillPath,formatSkillModelPath,resolveSandboxModelPath,resolveSandboxSkillReadPaths,resolveSandboxSkillRoot,resolveSandboxSkillWritePath};
@@ -1 +1 @@
1
- import{dirname,join}from"node:path";import{stat}from"node:fs/promises";async function fileExists(e){try{return(await stat(e)).isFile()}catch(e){if(e instanceof Error&&`code`in e&&e.code===`ENOENT`)return!1;throw e}}async function findClosestDirectoryWithFile(t){let n=t.start;for(;;){let r=join(n,t.directoryName);if(await fileExists(join(r,t.fileName)))return r;let i=dirname(n);if(i===n)return;n=i}}async function findClosestLinkedVercelDirectory(e){return findClosestDirectoryWithFile({start:e,directoryName:`.vercel`,fileName:`project.json`})}async function findClosestVercelOutputDirectory(e){return findClosestDirectoryWithFile({start:e,directoryName:`output`,fileName:`builds.json`})}export{findClosestLinkedVercelDirectory,findClosestVercelOutputDirectory};
1
+ import{stat}from"node:fs/promises";import{dirname,join}from"node:path";async function fileExists(t){try{return(await stat(t)).isFile()}catch(e){if(e instanceof Error&&`code`in e&&e.code===`ENOENT`)return!1;throw e}}async function findClosestDirectoryWithFile(e){let n=e.start;for(;;){let r=join(n,e.directoryName);if(await fileExists(join(r,e.fileName)))return r;let i=dirname(n);if(i===n)return;n=i}}async function findClosestLinkedVercelDirectory(e){return findClosestDirectoryWithFile({start:e,directoryName:`.vercel`,fileName:`project.json`})}async function findClosestVercelOutputDirectory(e){return findClosestDirectoryWithFile({start:e,directoryName:`output`,fileName:`builds.json`})}export{findClosestLinkedVercelDirectory,findClosestVercelOutputDirectory};
@@ -1 +1 @@
1
- import{join}from"node:path";import{readFile,rename,writeFile}from"node:fs/promises";import{checkAgentConfigSource}from"#source-change/agent-config-string-path.js";import{applyAgentModelSettingsToSource}from"#source-change/apply-agent-model-settings.js";import{applyModelNameToSource}from"#source-change/apply-model-name.js";function createStaticSourceChange(e){return{updateModelName:t=>updateAgentModelName(e,t),updateModelSettings:t=>updateAgentModelSettings(e,t)}}async function updateAgentModelSettings(n,r){let i=n.configModule;if(i===void 0)return{kind:`bail`,reason:`agent has no agent.ts config module to edit`,at:{logicalPath:`agent.ts`,line:1}};let o=join(n.agentRoot,i.logicalPath),s=await readFile(o,`utf8`),c=await applyAgentModelSettingsToSource(s,r);if(c.kind===`bail`)return{kind:`bail`,reason:c.reason,at:{logicalPath:i.logicalPath,line:c.line}};let l=await editedSourceBail(s,c.nextSource,i.logicalPath);return l===void 0?(await writeSourceIfChanged(o,s,c.nextSource),{kind:`applied`,changed:c.changed}):l}async function updateAgentModelName(n,r){let i=n.configModule;if(i===void 0)return{kind:`bail`,reason:`agent has no agent.ts config module to edit`,at:{logicalPath:`agent.ts`,line:1}};let a=join(n.agentRoot,i.logicalPath),s=await readFile(a,`utf8`),c=await applyModelNameToSource(s,r);if(c.kind===`bail`)return{kind:`bail`,reason:c.reason,at:{logicalPath:i.logicalPath,line:c.line}};let l=await editedSourceBail(s,c.nextSource,i.logicalPath);return l===void 0?(await writeSourceIfChanged(a,s,c.nextSource),{kind:`applied`,from:c.from,to:c.to}):l}async function writeSourceIfChanged(e,t,i){if(i===t)return;let a=`${e}.${process.pid}.eve-tmp`;await writeFile(a,i,`utf8`),await rename(a,e)}async function editedSourceBail(e,t,n){if(t===e)return;let r=await checkAgentConfigSource(t);if(r!==void 0)return{kind:`bail`,reason:`the edit produced source eve refuses to write (${r})`,at:{logicalPath:n,line:1}}}export{createStaticSourceChange};
1
+ import{readFile,rename,writeFile}from"node:fs/promises";import{join}from"node:path";import{checkAgentConfigSource}from"#source-change/agent-config-string-path.js";import{applyAgentModelSettingsToSource}from"#source-change/apply-agent-model-settings.js";import{applyModelNameToSource}from"#source-change/apply-model-name.js";function createStaticSourceChange(e){return{updateModelName:t=>updateAgentModelName(e,t),updateModelSettings:t=>updateAgentModelSettings(e,t)}}async function updateAgentModelSettings(t,n){let i=t.configModule;if(i===void 0)return{kind:`bail`,reason:`agent has no agent.ts config module to edit`,at:{logicalPath:`agent.ts`,line:1}};let o=join(t.agentRoot,i.logicalPath),s=await readFile(o,`utf8`),c=await applyAgentModelSettingsToSource(s,n);if(c.kind===`bail`)return{kind:`bail`,reason:c.reason,at:{logicalPath:i.logicalPath,line:c.line}};let l=await editedSourceBail(s,c.nextSource,i.logicalPath);return l===void 0?(await writeSourceIfChanged(o,s,c.nextSource),{kind:`applied`,changed:c.changed}):l}async function updateAgentModelName(t,n){let i=t.configModule;if(i===void 0)return{kind:`bail`,reason:`agent has no agent.ts config module to edit`,at:{logicalPath:`agent.ts`,line:1}};let a=join(t.agentRoot,i.logicalPath),s=await readFile(a,`utf8`),c=await applyModelNameToSource(s,n);if(c.kind===`bail`)return{kind:`bail`,reason:c.reason,at:{logicalPath:i.logicalPath,line:c.line}};let l=await editedSourceBail(s,c.nextSource,i.logicalPath);return l===void 0?(await writeSourceIfChanged(a,s,c.nextSource),{kind:`applied`,from:c.from,to:c.to}):l}async function writeSourceIfChanged(e,r,i){if(i===r)return;let a=`${e}.${process.pid}.eve-tmp`;await writeFile(a,i,`utf8`),await rename(a,e)}async function editedSourceBail(e,t,n){if(t===e)return;let r=await checkAgentConfigSource(t);if(r!==void 0)return{kind:`bail`,reason:`the edit produced source eve refuses to write (${r})`,at:{logicalPath:n,line:1}}}export{createStaticSourceChange};
@@ -1,3 +1,3 @@
1
- import { n as defaultMessageReducer, t as useEveAgent } from "../chunks/use-eve-agent-DaH3cf8K.js";
1
+ import { n as defaultMessageReducer, t as useEveAgent } from "../chunks/use-eve-agent-8mofdZcO.js";
2
2
 
3
3
  export { defaultMessageReducer, useEveAgent };
@@ -1,3 +1,3 @@
1
- import { t as useEveAgent } from "../chunks/use-eve-agent-DaH3cf8K.js";
1
+ import { t as useEveAgent } from "../chunks/use-eve-agent-8mofdZcO.js";
2
2
 
3
3
  export { useEveAgent };
@@ -1 +1 @@
1
- import{LocalTraceSpanProcessor}from"#tracing/local-trace-span-processor.js";import{ContextAgentTraceStateStore}from"#tracing/agent-trace-context-store.js";import{getInstrumentationRuntime,registerInstrumentationRuntime}from"#harness/instrumentation-runtime.js";import{context,trace}from"#compiled/@opentelemetry/api/index.js";import{registerOTel}from"#compiled/@vercel/otel/index.js";import{createAgentOtelInstrumentation}from"#tracing/agent-otel-provider.js";import{AgentTraceSpanProcessor}from"#tracing/agent-trace-span-processor.js";import{createInstrumentationHooks}from"#harness/instrumentation-lifecycle.js";import{requestLocalTraceStorePrune,resolveLocalTraceRetentionSettings}from"#tracing/local-trace-retention.js";function installLocalInstrumentationRuntime(t){let n=getInstrumentationRuntime();if(n!==void 0)return n;let r=resolveLocalTraceRetentionSettings(),i=new AgentTraceSpanProcessor(r.enabled?[new LocalTraceSpanProcessor(t.appRoot)]:[]);registerOTel({autoDetectResources:!1,instrumentations:[],propagators:[`none`],serviceName:t.serviceName,spanProcessors:[i]});let a=trace.getTracer(`eve.registration`).startSpan(`eve.otel.registration`),o=trace.setSpan(context.active(),a),s=context.with(o,()=>trace.getActiveSpan()===a);if(a.end(),!i.isAttached()||!s)throw Error(`eve could not register OpenTelemetry because another runtime already exists.`);let c=createAgentOtelInstrumentation({captureContent:process.env.EVE_TRACES_CONTENT!==`off`,frameworkVersion:t.frameworkVersion,stateStore:new ContextAgentTraceStateStore,tracer:trace.getTracer(`eve.agent`,t.frameworkVersion)}),l={events:{"session.completed":releaseSessionTrace,"session.failed":releaseSessionTrace}};return requestPrune(),registerInstrumentationRuntime({forceFlush:()=>i.forceFlush(),hooks:createInstrumentationHooks([c.hook,l]),runInContext:c.runInContext});async function releaseSessionTrace(e){await i.forceFlush(),i.releaseSession(e.sessionId)&&requestPrune()}function requestPrune(){r.enabled&&requestLocalTraceStorePrune({activeTraceIds:i.activeTraceIds(),appRoot:t.appRoot,maxAgeMs:r.maxAgeMs,maxTotalBytes:r.maxTotalBytes,retainCount:r.retainCount})}}export{installLocalInstrumentationRuntime};
1
+ import{ContextAgentTraceStateStore}from"#tracing/agent-trace-context-store.js";import{getInstrumentationRuntime,registerInstrumentationRuntime}from"#harness/instrumentation-runtime.js";import{context,trace}from"#compiled/@opentelemetry/api/index.js";import{registerOTel}from"#compiled/@vercel/otel/index.js";import{createAgentOtelInstrumentation}from"#tracing/agent-otel-provider.js";import{AgentTraceSpanProcessor}from"#tracing/agent-trace-span-processor.js";import{createInstrumentationHooks}from"#harness/instrumentation-lifecycle.js";import{requestLocalTraceStorePrune,resolveLocalTraceRetentionSettings}from"#tracing/local-trace-retention.js";import{LocalTraceSpanProcessor}from"#tracing/local-trace-span-processor.js";function installLocalInstrumentationRuntime(t){let n=getInstrumentationRuntime();if(n!==void 0)return n;let r=resolveLocalTraceRetentionSettings(),i=new AgentTraceSpanProcessor(r.enabled?[new LocalTraceSpanProcessor(t.appRoot)]:[]);registerOTel({autoDetectResources:!1,instrumentations:[],propagators:[`none`],serviceName:t.serviceName,spanProcessors:[i]});let a=trace.getTracer(`eve.registration`).startSpan(`eve.otel.registration`),o=trace.setSpan(context.active(),a),s=context.with(o,()=>trace.getActiveSpan()===a);if(a.end(),!i.isAttached()||!s)throw Error(`eve could not register OpenTelemetry because another runtime already exists.`);let c=createAgentOtelInstrumentation({captureContent:process.env.EVE_TRACES_CONTENT!==`off`,frameworkVersion:t.frameworkVersion,stateStore:new ContextAgentTraceStateStore,tracer:trace.getTracer(`eve.agent`,t.frameworkVersion)}),l={events:{"session.completed":releaseSessionTrace,"session.failed":releaseSessionTrace}};return requestPrune(),registerInstrumentationRuntime({forceFlush:()=>i.forceFlush(),hooks:createInstrumentationHooks([c.hook,l]),runInContext:c.runInContext});async function releaseSessionTrace(e){await i.forceFlush(),i.releaseSession(e.sessionId)&&requestPrune()}function requestPrune(){r.enabled&&requestLocalTraceStorePrune({activeTraceIds:i.activeTraceIds(),appRoot:t.appRoot,maxAgeMs:r.maxAgeMs,maxTotalBytes:r.maxTotalBytes,retainCount:r.retainCount})}}export{installLocalInstrumentationRuntime};
@@ -36,13 +36,30 @@ export interface LocalTrace {
36
36
  /** Zero-based session window this trace holds, when the spans record one. */
37
37
  readonly window?: number;
38
38
  }
39
- /** Reads valid local traces, newest first, while ignoring malformed segments. */
40
- export declare function listLocalTraces(appRoot: string): Promise<LocalTrace[]>;
41
39
  /**
42
- * Reads one trace from its segments directory, or `undefined` when the trace
43
- * has no valid spans. Spans come back ordered by start time.
40
+ * Trace ids held by the spool, unordered. Empty when nothing has been written
41
+ * yet; any other read fault propagates.
42
+ */
43
+ export declare function listLocalTraceIds(appRoot: string): Promise<string[]>;
44
+ /**
45
+ * Instant one trace last received a span, or `undefined` once retention has
46
+ * pruned it. Reads the segments directory's mtime, so it stays cheap enough to
47
+ * poll a large spool without parsing any span.
48
+ */
49
+ export declare function readLocalTraceActivityMs(appRoot: string, traceId: string): Promise<number | undefined>;
50
+ /**
51
+ * Segment file names of one trace in read order, or `undefined` when the trace
52
+ * is gone. Segments are immutable and named for their span, so the order is
53
+ * stable across reads and a caller can treat names it has seen as parsed.
54
+ */
55
+ export declare function listLocalTraceSegments(appRoot: string, traceId: string): Promise<string[] | undefined>;
56
+ /**
57
+ * Spans held by one segment file. An oversized, unreadable, or malformed
58
+ * segment yields none, so a partial write never breaks a view.
44
59
  */
45
- export declare function readLocalTrace(root: string, traceId: string): Promise<LocalTrace | undefined>;
60
+ export declare function readLocalTraceSegment(appRoot: string, traceId: string, fileName: string): Promise<LocalTraceSpan[]>;
61
+ /** Reads valid local traces, newest first, while ignoring malformed segments. */
62
+ export declare function listLocalTraces(appRoot: string): Promise<LocalTrace[]>;
46
63
  /** Sorts spans into timeline order: start, then end, then a stable tiebreak. */
47
64
  export declare function compareLocalTraceSpans(left: LocalTraceSpan, right: LocalTraceSpan): number;
48
65
  /** Builds a trace from already-parsed spans, deriving summary fields. */
@@ -1 +1 @@
1
- import{join}from"node:path";import{readFile,readdir,stat}from"node:fs/promises";import{resolveLocalTraceSchemaDirectory}from"#tracing/local-trace-span-processor.js";const TRACE_ID_PATTERN=/^[0-9a-f]{32}$/u,SPAN_FILE_PATTERN=/^([0-9a-f]{16})\.otlp\.json$/u;async function listLocalTraces(e){let t=resolveLocalTraceSchemaDirectory(e),r;try{r=await readdir(t,{withFileTypes:!0})}catch(e){if(isMissing(e))return[];throw e}let o=[];for(let e of r){if(!e.isDirectory()||!TRACE_ID_PATTERN.test(e.name))continue;let n=await readLocalTrace(t,e.name).catch(()=>void 0);n!==void 0&&o.push(n)}return o.sort((e,t)=>e.startTimeNs===t.startTimeNs?e.traceId.localeCompare(t.traceId):e.startTimeNs>t.startTimeNs?-1:1)}async function readLocalTrace(i,a){let s=join(i,a,`segments`),c;try{c=await readdir(s,{withFileTypes:!0})}catch(e){if(isMissing(e))return;throw e}let l=new Map;for(let n of c.sort((e,t)=>e.name.localeCompare(t.name))){if(!n.isFile()||!SPAN_FILE_PATTERN.test(n.name))continue;let i;try{let a=join(s,n.name);if((await stat(a)).size>8388608)continue;i=await readFile(a,`utf8`)}catch{continue}for(let e of parseLocalTraceSegment(i,a))l.has(e.spanId)||l.set(e.spanId,e)}if(l.size!==0)return assembleLocalTrace(a,[...l.values()])}function compareLocalTraceSpans(e,t){return e.startTimeNs===t.startTimeNs?e.endTimeNs===t.endTimeNs?e.name.localeCompare(t.name)||e.spanId.localeCompare(t.spanId):e.endTimeNs<t.endTimeNs?-1:1:e.startTimeNs<t.startTimeNs?-1:1}function assembleLocalTrace(e,t){let n=[...t].sort(compareLocalTraceSpans),r=n.map(e=>e.attributes),i=distinctAttributes(r,`agent.session.id`);return{agentName:firstAttribute(r,`agent.name`),endTimeNs:n.reduce((e,t)=>t.endTimeNs>e?t.endTimeNs:e,0n),sessionId:i[0],sessionIds:i,spans:n,startTimeNs:n.reduce((e,t)=>t.startTimeNs<e?t.startTimeNs:e,n[0].startTimeNs),traceId:e,window:firstNumberAttribute(r,`agent.session.window`)}}function describeLocalTraceSpan(e){let t=[],n=stringSpanAttribute(e,`agent.turn.id`),r=valueSpanAttribute(e,`agent.step.index`),i=valueSpanAttribute(e,`agent.step.attempt`),a=stringSpanAttribute(e,`agent.action.kind`),o=stringSpanAttribute(e,`agent.action.name`),s=stringSpanAttribute(e,`agent.model.id`)??stringSpanAttribute(e,`gen_ai.request.model`);return e.name===`agent.turn`&&n!==void 0&&t.push(n),e.name===`agent.step`&&r!==void 0&&t.push(`step ${String(r)}${i===void 0?``:`, attempt ${String(i)}`}`),e.name===`agent.action`&&o!==void 0&&t.push(`${a??`action`}: ${o}`),s!==void 0&&e.name.includes(`do`)&&t.push(`model ${s}`),t}function parseLocalTraceSegment(e,t){try{let n=JSON.parse(e);if(!isRecord(n)||!Array.isArray(n.resourceSpans))return[];let r=[];for(let e of n.resourceSpans)if(!(!isRecord(e)||!Array.isArray(e.scopeSpans)))for(let n of e.scopeSpans){if(!isRecord(n)||!Array.isArray(n.spans))continue;let e=isRecord(n.scope)&&typeof n.scope.name==`string`?n.scope.name:void 0;for(let i of n.spans){let n=parseLocalTraceSpan(i,t,e);n!==void 0&&r.push(n)}}return r}catch{return[]}}function parseLocalTraceSpan(e,t,n){if(!isRecord(e)||e.traceId!==t||typeof e.spanId!=`string`||!/^[0-9a-f]{16}$/u.test(e.spanId)||typeof e.name!=`string`)return;let r=parseNanos(e.startTimeUnixNano),i=parseNanos(e.endTimeUnixNano);if(!(r===void 0||i===void 0||i<r))return{attributes:parseAttributes(e.attributes),endTimeNs:i,name:e.name,parentSpanId:typeof e.parentSpanId==`string`&&/^[0-9a-f]{16}$/u.test(e.parentSpanId)?e.parentSpanId:void 0,scope:n,spanId:e.spanId,startTimeNs:r,statusCode:parseStatusCode(e.status),traceId:t}}function parseAttributes(e){if(!Array.isArray(e))return{};let t={};for(let n of e){if(!isRecord(n)||typeof n.key!=`string`||!isRecord(n.value))continue;let e=parseAnyValue(n.value);e!==void 0&&(t[n.key]=e)}return t}function parseAnyValue(e){for(let t of[`stringValue`,`boolValue`,`intValue`,`doubleValue`])if(t in e)return e[t];if(isRecord(e.arrayValue)&&Array.isArray(e.arrayValue.values))return e.arrayValue.values.filter(isRecord).map(e=>parseAnyValue(e))}function parseNanos(e){if(!(typeof e!=`string`&&typeof e!=`number`))try{let t=BigInt(e);return t>=0n&&t<=18446744073709551615n?t:void 0}catch{return}}function parseStatusCode(e){return isRecord(e)?typeof e.code==`number`?e.code:e.code===`STATUS_CODE_ERROR`?2:0:0}function firstAttribute(e,t){for(let n of e){let e=n[t];if(typeof e==`string`&&e.length>0)return e}}function firstNumberAttribute(e,t){for(let n of e){let e=n[t];if(typeof e==`number`)return e;if(typeof e==`bigint`)return Number(e)}}function distinctAttributes(e,t){let n=new Set;for(let r of e){let e=r[t];typeof e==`string`&&e.length>0&&n.add(e)}return[...n]}function stringSpanAttribute(e,t){let n=e.attributes[t];return typeof n==`string`?n:void 0}function valueSpanAttribute(e,t){let n=e.attributes[t];return typeof n==`string`||typeof n==`number`?n:void 0}function isMissing(e){return e.code===`ENOENT`}function isRecord(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}export{assembleLocalTrace,compareLocalTraceSpans,describeLocalTraceSpan,listLocalTraces,parseLocalTraceSegment,readLocalTrace};
1
+ import{readFile,readdir,stat}from"node:fs/promises";import{join}from"node:path";import{resolveLocalTraceSchemaDirectory,resolveLocalTraceSegmentsDirectory}from"#tracing/local-trace-span-processor.js";const TRACE_ID_PATTERN=/^[0-9a-f]{32}$/u,SPAN_FILE_PATTERN=/^[0-9a-f]{16}\.otlp\.json$/u;async function listLocalTraceIds(e){let n;try{n=await readdir(resolveLocalTraceSchemaDirectory(e),{withFileTypes:!0})}catch(e){if(isMissing(e))return[];throw e}return n.filter(e=>e.isDirectory()&&TRACE_ID_PATTERN.test(e.name)).map(e=>e.name)}async function readLocalTraceActivityMs(e,t){try{return(await stat(resolveLocalTraceSegmentsDirectory(e,t))).mtimeMs}catch(e){if(isMissing(e))return;throw e}}async function listLocalTraceSegments(e,n){let r;try{r=await readdir(resolveLocalTraceSegmentsDirectory(e,n),{withFileTypes:!0})}catch(e){if(isMissing(e))return;throw e}return r.filter(e=>e.isFile()&&SPAN_FILE_PATTERN.test(e.name)).map(e=>e.name).sort((e,t)=>e.localeCompare(t))}async function readLocalTraceSegment(t,i,o){let s=join(resolveLocalTraceSegmentsDirectory(t,i),o),c;try{if((await stat(s)).size>8388608)return[];c=await readFile(s,`utf8`)}catch{return[]}return parseLocalTraceSegment(c,i)}async function listLocalTraces(e){let t=[];for(let n of await listLocalTraceIds(e)){let r=await readLocalTrace(e,n).catch(()=>void 0);r!==void 0&&t.push(r)}return t.sort((e,t)=>e.startTimeNs===t.startTimeNs?e.traceId.localeCompare(t.traceId):e.startTimeNs>t.startTimeNs?-1:1)}async function readLocalTrace(e,t){let n=await listLocalTraceSegments(e,t);if(n===void 0)return;let r=new Map;for(let i of n)for(let n of await readLocalTraceSegment(e,t,i))r.has(n.spanId)||r.set(n.spanId,n);if(r.size!==0)return assembleLocalTrace(t,[...r.values()])}function compareLocalTraceSpans(e,t){return e.startTimeNs===t.startTimeNs?e.endTimeNs===t.endTimeNs?e.name.localeCompare(t.name)||e.spanId.localeCompare(t.spanId):e.endTimeNs<t.endTimeNs?-1:1:e.startTimeNs<t.startTimeNs?-1:1}function assembleLocalTrace(e,t){let n=[...t].sort(compareLocalTraceSpans),r=n.map(e=>e.attributes),i=distinctAttributes(r,`agent.session.id`);return{agentName:firstAttribute(r,`agent.name`),endTimeNs:n.reduce((e,t)=>t.endTimeNs>e?t.endTimeNs:e,0n),sessionId:i[0],sessionIds:i,spans:n,startTimeNs:n.reduce((e,t)=>t.startTimeNs<e?t.startTimeNs:e,n[0].startTimeNs),traceId:e,window:firstNumberAttribute(r,`agent.session.window`)}}function describeLocalTraceSpan(e){let t=[],n=stringSpanAttribute(e,`agent.turn.id`),r=valueSpanAttribute(e,`agent.step.index`),i=valueSpanAttribute(e,`agent.step.attempt`),a=stringSpanAttribute(e,`agent.action.kind`),o=stringSpanAttribute(e,`agent.action.name`),s=stringSpanAttribute(e,`agent.model.id`)??stringSpanAttribute(e,`gen_ai.request.model`);return e.name===`agent.turn`&&n!==void 0&&t.push(n),e.name===`agent.step`&&r!==void 0&&t.push(`step ${String(r)}${i===void 0?``:`, attempt ${String(i)}`}`),e.name===`agent.action`&&o!==void 0&&t.push(`${a??`action`}: ${o}`),s!==void 0&&e.name.includes(`do`)&&t.push(`model ${s}`),t}function parseLocalTraceSegment(e,t){try{let n=JSON.parse(e);if(!isRecord(n)||!Array.isArray(n.resourceSpans))return[];let r=[];for(let e of n.resourceSpans)if(!(!isRecord(e)||!Array.isArray(e.scopeSpans)))for(let n of e.scopeSpans){if(!isRecord(n)||!Array.isArray(n.spans))continue;let e=isRecord(n.scope)&&typeof n.scope.name==`string`?n.scope.name:void 0;for(let i of n.spans){let n=parseLocalTraceSpan(i,t,e);n!==void 0&&r.push(n)}}return r}catch{return[]}}function parseLocalTraceSpan(e,t,n){if(!isRecord(e)||e.traceId!==t||typeof e.spanId!=`string`||!/^[0-9a-f]{16}$/u.test(e.spanId)||typeof e.name!=`string`)return;let r=parseNanos(e.startTimeUnixNano),i=parseNanos(e.endTimeUnixNano);if(!(r===void 0||i===void 0||i<r))return{attributes:parseAttributes(e.attributes),endTimeNs:i,name:e.name,parentSpanId:typeof e.parentSpanId==`string`&&/^[0-9a-f]{16}$/u.test(e.parentSpanId)?e.parentSpanId:void 0,scope:n,spanId:e.spanId,startTimeNs:r,statusCode:parseStatusCode(e.status),traceId:t}}function parseAttributes(e){if(!Array.isArray(e))return{};let t={};for(let n of e){if(!isRecord(n)||typeof n.key!=`string`||!isRecord(n.value))continue;let e=parseAnyValue(n.value);e!==void 0&&(t[n.key]=e)}return t}function parseAnyValue(e){for(let t of[`stringValue`,`boolValue`,`intValue`,`doubleValue`])if(t in e)return e[t];if(isRecord(e.arrayValue)&&Array.isArray(e.arrayValue.values))return e.arrayValue.values.filter(isRecord).map(e=>parseAnyValue(e))}function parseNanos(e){if(!(typeof e!=`string`&&typeof e!=`number`))try{let t=BigInt(e);return t>=0n&&t<=18446744073709551615n?t:void 0}catch{return}}function parseStatusCode(e){return isRecord(e)?typeof e.code==`number`?e.code:e.code===`STATUS_CODE_ERROR`?2:0:0}function firstAttribute(e,t){for(let n of e){let e=n[t];if(typeof e==`string`&&e.length>0)return e}}function firstNumberAttribute(e,t){for(let n of e){let e=n[t];if(typeof e==`number`)return e;if(typeof e==`bigint`)return Number(e)}}function distinctAttributes(e,t){let n=new Set;for(let r of e){let e=r[t];typeof e==`string`&&e.length>0&&n.add(e)}return[...n]}function stringSpanAttribute(e,t){let n=e.attributes[t];return typeof n==`string`?n:void 0}function valueSpanAttribute(e,t){let n=e.attributes[t];return typeof n==`string`||typeof n==`number`?n:void 0}function isMissing(e){return e.code===`ENOENT`}function isRecord(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}export{assembleLocalTrace,compareLocalTraceSpans,describeLocalTraceSpan,listLocalTraceIds,listLocalTraceSegments,listLocalTraces,parseLocalTraceSegment,readLocalTraceActivityMs,readLocalTraceSegment};
@@ -1 +1 @@
1
- import{createLogger,formatError}from"#internal/logging.js";import{join}from"node:path";import{readdir,rm,stat}from"node:fs/promises";import{resolveLocalTraceSchemaDirectory,resolveLocalTraceSegmentsDirectory}from"#tracing/local-trace-span-processor.js";const log=createLogger(`harness.local-trace-retention`),LOCAL_TRACE_QUIESCENCE_MS=300*1e3,LOCAL_TRACE_MAX_AGE_MS=10080*60*1e3,LOCAL_TRACE_MAX_TOTAL_BYTES=512*1024*1024;function resolveLocalTraceRetentionSettings(e=process.env){return{enabled:!isDisabled(e.EVE_TRACES),maxAgeMs:readBound(e,`EVE_TRACES_MAX_AGE_MS`,LOCAL_TRACE_MAX_AGE_MS),maxTotalBytes:readBound(e,`EVE_TRACES_MAX_TOTAL_BYTES`,LOCAL_TRACE_MAX_TOTAL_BYTES),retainCount:readBound(e,`EVE_TRACES_RETAIN_COUNT`,20)}}async function pruneLocalTraceStore(e){let t=e.now??Date.now(),n=clampBound(e.maxAgeMs??LOCAL_TRACE_MAX_AGE_MS),r=clampBound(e.maxTotalBytes??LOCAL_TRACE_MAX_TOTAL_BYTES),a=clampCount(e.retainCount??20),o=await readStoredTraces(e.appRoot,t),s=[...o].sort((e,t)=>t.modifiedAtMs-e.modifiedAtMs),c=new Set(s.slice(0,a===!1?0:a)),l=new Set,u=o.reduce((e,t)=>e+t.byteSize,0),d=0,f=0,p=0;for(let a of s.toReversed()){let o=t-a.modifiedAtMs,s=e.activeTraceIds.has(a.traceId)||c.has(a)||o<=LOCAL_TRACE_QUIESCENCE_MS?void 0:n!==!1&&o>n?`maxAgeMs`:r!==!1&&u>r?`maxTotalBytes`:void 0;if(s===void 0){p+=1;continue}await rm(a.path,{force:!0,recursive:!0}),u-=a.byteSize,d+=a.byteSize,f+=1,l.add(s)}return{reasons:[...l],reclaimedBytes:d,removedTraces:f,retainedTraces:p}}const pruneRequest={input:{activeTraceIds:new Set,appRoot:``},requested:!1,running:void 0};function requestLocalTraceStorePrune(e){pruneRequest.input=e,pruneRequest.requested=!0,pruneRequest.running===void 0&&startPruning()}function startPruning(){pruneRequest.running=(async()=>{for(;pruneRequest.requested;)pruneRequest.requested=!1,report(await pruneLocalTraceStore(pruneRequest.input))})().catch(e=>{log.warn(`local trace retention failed`,{error:formatError(e)})}).finally(()=>{pruneRequest.running=void 0,pruneRequest.requested&&startPruning()})}function report(e){e.removedTraces!==0&&log.info(`pruned local traces`,{reasons:e.reasons.join(`,`),reclaimedBytes:e.reclaimedBytes,removedTraces:e.removedTraces,retainedTraces:e.retainedTraces})}async function readStoredTraces(e,t){let r=resolveLocalTraceSchemaDirectory(e),i=await readDirectoryEntries(r);return i===void 0?[]:(await Promise.all(i.filter(e=>e.isDirectory()).map(async i=>{let a=join(r,i.name),o=resolveLocalTraceSegmentsDirectory(e,i.name);await reapAbandonedTemporaryFiles(o,t);let c=await directoryMtime(o)??await directoryMtime(a);if(c!==void 0)return{byteSize:await directorySize(a),modifiedAtMs:c,path:a,traceId:i.name}}))).filter(e=>e!==void 0)}async function reapAbandonedTemporaryFiles(e,t){let r=await readDirectoryEntries(e);if(r!==void 0)for(let o of r){if(!o.isFile()||!o.name.includes(`.tmp-`))continue;let r=join(e,o.name);try{if(t-(await stat(r)).mtimeMs<=LOCAL_TRACE_QUIESCENCE_MS)continue;await rm(r,{force:!0})}catch{}}}async function directoryMtime(e){try{return(await stat(e)).mtimeMs}catch{return}}async function directorySize(e){let t=await readDirectoryEntries(e);if(t===void 0)return 0;let r=0;for(let i of t){let t=join(e,i.name);if(i.isDirectory()){r+=await directorySize(t);continue}try{r+=(await stat(t)).size}catch{}}return r}async function readDirectoryEntries(e){try{return await readdir(e,{withFileTypes:!0})}catch(e){if(e instanceof Error&&`code`in e&&(e.code===`ENOENT`||e.code===`ENOTDIR`))return;throw e}}function isDisabled(e){if(e===void 0)return!1;let t=e.trim().toLowerCase();return t===`off`||t===`false`||t===`0`}function readBound(e,t,n){let r=e[t];if(r===void 0)return n;let i=r.trim().toLowerCase();if(i===`off`||i===`false`)return!1;let a=Number(i);return!Number.isFinite(a)||a<0?(log.warn(`ignoring invalid local trace retention value`,{fallback:n,name:t,value:r}),n):a}function clampBound(e){return e!==!1&&Math.max(0,e)}function clampCount(e){return e!==!1&&Math.max(0,Math.trunc(e))}export{pruneLocalTraceStore,requestLocalTraceStorePrune,resolveLocalTraceRetentionSettings};
1
+ import{readdir,rm,stat}from"node:fs/promises";import{createLogger,formatError}from"#internal/logging.js";import{join}from"node:path";import{resolveLocalTraceSchemaDirectory,resolveLocalTraceSegmentsDirectory}from"#tracing/local-trace-span-processor.js";const log=createLogger(`harness.local-trace-retention`),LOCAL_TRACE_QUIESCENCE_MS=300*1e3,LOCAL_TRACE_MAX_AGE_MS=10080*60*1e3,LOCAL_TRACE_MAX_TOTAL_BYTES=512*1024*1024;function resolveLocalTraceRetentionSettings(e=process.env){return{enabled:!isDisabled(e.EVE_TRACES),maxAgeMs:readBound(e,`EVE_TRACES_MAX_AGE_MS`,LOCAL_TRACE_MAX_AGE_MS),maxTotalBytes:readBound(e,`EVE_TRACES_MAX_TOTAL_BYTES`,LOCAL_TRACE_MAX_TOTAL_BYTES),retainCount:readBound(e,`EVE_TRACES_RETAIN_COUNT`,20)}}async function pruneLocalTraceStore(e){let n=e.now??Date.now(),r=clampBound(e.maxAgeMs??LOCAL_TRACE_MAX_AGE_MS),i=clampBound(e.maxTotalBytes??LOCAL_TRACE_MAX_TOTAL_BYTES),a=clampCount(e.retainCount??20),o=await readStoredTraces(e.appRoot,n),s=[...o].sort((e,t)=>t.modifiedAtMs-e.modifiedAtMs),c=new Set(s.slice(0,a===!1?0:a)),l=new Set,u=o.reduce((e,t)=>e+t.byteSize,0),d=0,f=0,p=0;for(let a of s.toReversed()){let o=n-a.modifiedAtMs,s=e.activeTraceIds.has(a.traceId)||c.has(a)||o<=LOCAL_TRACE_QUIESCENCE_MS?void 0:r!==!1&&o>r?`maxAgeMs`:i!==!1&&u>i?`maxTotalBytes`:void 0;if(s===void 0){p+=1;continue}await rm(a.path,{force:!0,recursive:!0}),u-=a.byteSize,d+=a.byteSize,f+=1,l.add(s)}return{reasons:[...l],reclaimedBytes:d,removedTraces:f,retainedTraces:p}}const pruneRequest={input:{activeTraceIds:new Set,appRoot:``},requested:!1,running:void 0};function requestLocalTraceStorePrune(e){pruneRequest.input=e,pruneRequest.requested=!0,pruneRequest.running===void 0&&startPruning()}function startPruning(){pruneRequest.running=(async()=>{for(;pruneRequest.requested;)pruneRequest.requested=!1,report(await pruneLocalTraceStore(pruneRequest.input))})().catch(e=>{log.warn(`local trace retention failed`,{error:formatError(e)})}).finally(()=>{pruneRequest.running=void 0,pruneRequest.requested&&startPruning()})}function report(e){e.removedTraces!==0&&log.info(`pruned local traces`,{reasons:e.reasons.join(`,`),reclaimedBytes:e.reclaimedBytes,removedTraces:e.removedTraces,retainedTraces:e.retainedTraces})}async function readStoredTraces(e,t){let n=resolveLocalTraceSchemaDirectory(e),r=await readDirectoryEntries(n);return r===void 0?[]:(await Promise.all(r.filter(e=>e.isDirectory()).map(async r=>{let i=join(n,r.name),o=resolveLocalTraceSegmentsDirectory(e,r.name);await reapAbandonedTemporaryFiles(o,t);let c=await directoryMtime(o)??await directoryMtime(i);if(c!==void 0)return{byteSize:await directorySize(i),modifiedAtMs:c,path:i,traceId:r.name}}))).filter(e=>e!==void 0)}async function reapAbandonedTemporaryFiles(e,r){let i=await readDirectoryEntries(e);if(i!==void 0)for(let o of i){if(!o.isFile()||!o.name.includes(`.tmp-`))continue;let i=join(e,o.name);try{if(r-(await stat(i)).mtimeMs<=LOCAL_TRACE_QUIESCENCE_MS)continue;await rm(i,{force:!0})}catch{}}}async function directoryMtime(e){try{return(await stat(e)).mtimeMs}catch{return}}async function directorySize(e){let t=await readDirectoryEntries(e);if(t===void 0)return 0;let r=0;for(let i of t){let t=join(e,i.name);if(i.isDirectory()){r+=await directorySize(t);continue}try{r+=(await stat(t)).size}catch{}}return r}async function readDirectoryEntries(t){try{return await readdir(t,{withFileTypes:!0})}catch(e){if(e instanceof Error&&`code`in e&&(e.code===`ENOENT`||e.code===`ENOTDIR`))return;throw e}}function isDisabled(e){if(e===void 0)return!1;let t=e.trim().toLowerCase();return t===`off`||t===`false`||t===`0`}function readBound(e,t,n){let r=e[t];if(r===void 0)return n;let i=r.trim().toLowerCase();if(i===`off`||i===`false`)return!1;let a=Number(i);return!Number.isFinite(a)||a<0?(log.warn(`ignoring invalid local trace retention value`,{fallback:n,name:t,value:r}),n):a}function clampBound(e){return e!==!1&&Math.max(0,e)}function clampCount(e){return e!==!1&&Math.max(0,Math.trunc(e))}export{pruneLocalTraceStore,requestLocalTraceStorePrune,resolveLocalTraceRetentionSettings};
@@ -1 +1 @@
1
- import{createLogger,formatError}from"#internal/logging.js";import{join}from"node:path";import{mkdir}from"node:fs/promises";import{atomicWriteFile}from"#shared/atomic-write-file.js";import{JsonTraceSerializer}from"#compiled/@opentelemetry/otlp-transformer/index.js";const log=createLogger(`harness.local-trace-span-processor`);function resolveLocalTraceStoreDirectory(e){return join(e,`.eve`,`traces`)}function resolveLocalTraceSchemaDirectory(e){return join(resolveLocalTraceStoreDirectory(e),`v1`)}function resolveLocalTraceSegmentsDirectory(e,t){return join(resolveLocalTraceSchemaDirectory(e),t,`segments`)}var LocalTraceSpanProcessor=class{#e;#t=Promise.resolve();#n=!1;constructor(e){this.#e=e}forceFlush(){return this.#t}onStart(){}onEnd(e){if(!isReadableSpan(e))return;let{spanId:n,traceId:r}=e.spanContext();if(!isHexId(r,32)||!isHexId(n,16))return;let i=JsonTraceSerializer.serializeRequest([e]);i!==void 0&&(this.#t=this.#t.then(async()=>{let e=resolveLocalTraceSegmentsDirectory(this.#e,r);await mkdir(e,{recursive:!0}),await atomicWriteFile(join(e,`${n}.otlp.json`),i)}).catch(e=>{this.#n||(this.#n=!0,log.warn(`local trace persistence failed`,{error:formatError(e)}))}))}shutdown(){return this.forceFlush()}};function isReadableSpan(e){return typeof e==`object`&&!!e&&`attributes`in e&&`spanContext`in e&&typeof e.spanContext==`function`}function isHexId(e,t){return e.length===t&&/^[0-9a-f]+$/u.test(e)}export{LocalTraceSpanProcessor,resolveLocalTraceSchemaDirectory,resolveLocalTraceSegmentsDirectory};
1
+ import{mkdir}from"node:fs/promises";import{createLogger,formatError}from"#internal/logging.js";import{join}from"node:path";import{atomicWriteFile}from"#shared/atomic-write-file.js";import{JsonTraceSerializer}from"#compiled/@opentelemetry/otlp-transformer/index.js";const log=createLogger(`harness.local-trace-span-processor`);function resolveLocalTraceStoreDirectory(e){return join(e,`.eve`,`traces`)}function resolveLocalTraceSchemaDirectory(e){return join(resolveLocalTraceStoreDirectory(e),`v1`)}function resolveLocalTraceSegmentsDirectory(e,t){return join(resolveLocalTraceSchemaDirectory(e),t,`segments`)}var LocalTraceSpanProcessor=class{#e;#t=Promise.resolve();#n=!1;constructor(e){this.#e=e}forceFlush(){return this.#t}onStart(){}onEnd(t){if(!isReadableSpan(t))return;let{spanId:n,traceId:r}=t.spanContext();if(!isHexId(r,32)||!isHexId(n,16))return;let i=JsonTraceSerializer.serializeRequest([t]);i!==void 0&&(this.#t=this.#t.then(async()=>{let t=resolveLocalTraceSegmentsDirectory(this.#e,r);await mkdir(t,{recursive:!0}),await atomicWriteFile(join(t,`${n}.otlp.json`),i)}).catch(e=>{this.#n||(this.#n=!0,log.warn(`local trace persistence failed`,{error:formatError(e)}))}))}shutdown(){return this.forceFlush()}};function isReadableSpan(e){return typeof e==`object`&&!!e&&`attributes`in e&&`spanContext`in e&&typeof e.spanContext==`function`}function isHexId(e,t){return e.length===t&&/^[0-9a-f]+$/u.test(e)}export{LocalTraceSpanProcessor,resolveLocalTraceSchemaDirectory,resolveLocalTraceSegmentsDirectory};
@@ -1,3 +1,3 @@
1
- import { n as defaultMessageReducer, t as useEveAgent } from "../chunks/use-eve-agent-CyDt3Lny.js";
1
+ import { n as defaultMessageReducer, t as useEveAgent } from "../chunks/use-eve-agent-bKJbH0k4.js";
2
2
 
3
3
  export { defaultMessageReducer, useEveAgent };
@@ -1,3 +1,3 @@
1
- import { t as useEveAgent } from "../chunks/use-eve-agent-CyDt3Lny.js";
1
+ import { t as useEveAgent } from "../chunks/use-eve-agent-bKJbH0k4.js";
2
2
 
3
3
  export { useEveAgent };
@@ -4,27 +4,43 @@ description: "Reach your agent from Discord HTTP Interactions, including slash c
4
4
  type: integration
5
5
  ---
6
6
 
7
- The Discord channel wires your agent into Discord's HTTP Interactions, including slash and application commands, message components, and modal submissions. Discord enforces a three-second ACK deadline, so the channel verifies the Ed25519 signature headers, acknowledges the command right away, and runs the eve work in the background. See [Channels](./overview) for the contract this builds on.
7
+ The Discord channel wires your agent into Discord's HTTP Interactions, including slash and application commands, message components, and modal submissions. Discord enforces a three-second ACK deadline, so the channel acknowledges the command right away and runs the eve work in the background. Credentials and inbound request verification run through [Vercel Connect](../guides/auth-and-route-protection), so Discord's bot token stays out of your environment and Connect verifies Discord's signature before forwarding an interaction to eve. See [Channels](./overview) for the contract this builds on.
8
8
 
9
- ## Add the channel
9
+ ## Set up Discord
10
10
 
11
- ```ts title="agent/channels/discord.ts"
12
- import { discordChannel } from "eve/channels/discord";
11
+ Run the guided setup from your eve project:
13
12
 
14
- export default discordChannel();
13
+ ```bash
14
+ pnpm eve add channel/discord
15
15
  ```
16
16
 
17
- ```bash
18
- DISCORD_PUBLIC_KEY=... # verifies X-Signature-Ed25519 + X-Signature-Timestamp
19
- DISCORD_APPLICATION_ID=... # edits the deferred response and sends followups
20
- DISCORD_BOT_TOKEN=... # proactive messages + fallback + typing indicators
17
+ The setup guides you through creating a Discord application and bot, then:
18
+
19
+ - validates the bot token;
20
+ - creates a Vercel Connect client and attaches `/eve/v1/discord` as its trigger destination;
21
+ - registers an application command with a required `message` option;
22
+ - configures the Discord application's Interactions Endpoint URL;
23
+ - scaffolds the channel with Connect-managed credentials; and
24
+ - prints the bot installation URL.
25
+
26
+ The command defaults to `/ask` with the description **Ask the eve agent**. You can edit both during setup. Discord global commands can take up to an hour to appear after registration.
27
+
28
+ The generated channel looks like this:
29
+
30
+ ```ts title="agent/channels/discord.ts"
31
+ import { connectDiscordCredentials } from "@vercel/connect/eve";
32
+ import { discordChannel } from "eve/channels/discord";
33
+
34
+ export default discordChannel({
35
+ credentials: connectDiscordCredentials("discord/my-agent"),
36
+ });
21
37
  ```
22
38
 
23
- To skip env vars, pass the same values through `credentials: { applicationId, botToken, publicKey }`. The route is `POST /eve/v1/discord` by default. Paste that public URL into your Discord application's Interactions Endpoint URL.
39
+ The route is `POST /eve/v1/discord` by default. Connect resolves the application ID and bot token lazily and verifies forwarded interactions with same-project Vercel OIDC.
24
40
 
25
- ## Register a command
41
+ ### Configure Discord manually
26
42
 
27
- Registering commands is on you, not the channel. Use Discord's API or the Developer Portal. A string option named `message` lines up with eve's default prompt extraction:
43
+ If you do not use the guided Connect setup, register a command with Discord's API or the Developer Portal. A string option named `message` lines up with eve's default prompt extraction:
28
44
 
29
45
  ```bash
30
46
  curl -X PUT "https://discord.com/api/v10/applications/$DISCORD_APPLICATION_ID/commands" \
@@ -33,7 +49,7 @@ curl -X PUT "https://discord.com/api/v10/applications/$DISCORD_APPLICATION_ID/co
33
49
  "options":[{"name":"message","description":"What should the agent do?","type":3,"required":true}]}]'
34
50
  ```
35
51
 
36
- Use guild commands during development for faster propagation.
52
+ Then configure the public `https://…/eve/v1/discord` route as the application's Interactions Endpoint URL. Pass `credentials: { applicationId, botToken, publicKey }` to `discordChannel`, or set the corresponding `DISCORD_APPLICATION_ID`, `DISCORD_BOT_TOKEN`, and `DISCORD_PUBLIC_KEY` environment variables.
37
53
 
38
54
  ## How the channel handles messages
39
55
 
@@ -74,7 +90,7 @@ HITL renders as Discord components. Confirmations and options become buttons, `d
74
90
 
75
91
  ### Proactive sessions
76
92
 
77
- Start a session without an inbound interaction through `receive(discord, { message, target, auth })` from a schedule `run` handler, or `args.receive(discord, ...)` from another channel. The proactive target shape is `{ channelId, conversationId?, initialMessage? }`. Either path needs `DISCORD_BOT_TOKEN`.
93
+ Start a session without an inbound interaction through `receive(discord, { message, target, auth })` from a schedule `run` handler, or `args.receive(discord, ...)` from another channel. The proactive target shape is `{ channelId, conversationId?, initialMessage? }`. Either path needs a bot token, supplied by Connect or `DISCORD_BOT_TOKEN`.
78
94
 
79
95
  ### Attachments
80
96
 
@@ -0,0 +1,91 @@
1
+ ---
2
+ title: "Use eve through ACP"
3
+ description: "Use local or deployed eve agents from Agent Client Protocol clients."
4
+ ---
5
+
6
+ Agent Client Protocol (ACP) clients can launch an authored eve application as a local subprocess. eve serves stable ACP v1 over stdio while its normal development server remains the execution runtime.
7
+
8
+ ```sh
9
+ eve acp
10
+ ```
11
+
12
+ Without a URL, the client starts one process from the eve application root. It supervises a local development server, and closing the ACP connection stops that owned server. To bridge ACP to a deployed eve agent, pass its URL:
13
+
14
+ ```sh
15
+ eve acp https://agent.example.com
16
+ ```
17
+
18
+ For a recognized Vercel deployment, eve verifies the exact origin and resolves a short-lived project-scoped OIDC token from the local Vercel session. If login or a Trusted Sources change is required, run `eve dev <url>` and complete `/vc:login` before launching ACP. `VERCEL_AUTOMATION_BYPASS_SECRET` remains available for deployments configured with a Protection Bypass for Automation token.
19
+
20
+ ## Configure Zed
21
+
22
+ Open the eve application root as the Zed workspace. In **Agent Settings → External Agents**, add a custom agent:
23
+
24
+ ```json
25
+ {
26
+ "agent_servers": {
27
+ "eve-local": {
28
+ "type": "custom",
29
+ "command": "pnpm",
30
+ "args": ["exec", "eve", "acp"],
31
+ "env": {}
32
+ }
33
+ }
34
+ }
35
+ ```
36
+
37
+ Use an absolute command path if Zed cannot find `pnpm` in its environment. The workspace must be the same directory as the eve application root; eve rejects a different `session/new.cwd` instead of running the wrong application.
38
+
39
+ Disable Zed project MCP servers for this agent. The initial eve adapter does not accept client-provided MCP servers.
40
+
41
+ ## Supported behavior
42
+
43
+ ACP clients receive:
44
+
45
+ - streamed assistant text and reasoning;
46
+ - tool-call requests and results;
47
+ - one-time tool approval and denial requests;
48
+ - fixed-choice and freeform questions when the client supports ACP form elicitation;
49
+ - cooperative turn cancellation;
50
+ - independent concurrent ACP sessions;
51
+ - session closure and process cleanup.
52
+
53
+ Development rebuilds retain normal eve semantics. In-flight work stays pinned to its generation, and the next turn uses the newest successful generation.
54
+
55
+ ## Security and capability limits
56
+
57
+ ACP mode does not give the agent access to the editor's host filesystem or terminal. `session/new.cwd` identifies the eve application being launched; it is not mounted into the agent sandbox.
58
+
59
+ The initial adapter does not support:
60
+
61
+ - a deployed ACP HTTP or WebSocket endpoint;
62
+ - ACP authentication (remote bridges use the deployed eve agent's existing HTTP authentication);
63
+ - ACP v2;
64
+ - client filesystem or terminal methods;
65
+ - client-provided MCP servers;
66
+ - images, audio, files, or embedded resources in prompts;
67
+ - session loading, listing, resumption, or durable ACP IDs across process restarts;
68
+ - ACP model or mode configuration.
69
+
70
+ The agent continues to use the connections, tools, credentials, and sandbox policy authored in the eve application. Prompt text and ACP metadata never establish an authenticated end-user principal.
71
+
72
+ ## Diagnose a connection
73
+
74
+ ACP reserves stdout for newline-delimited JSON-RPC. eve sends compilation output, server logs, and diagnostics to stderr so they cannot corrupt the protocol stream.
75
+
76
+ For a quick headless smoke test, run an ACP client such as `acpx` from the application root. `acpx` launches the ACP process itself; do not start `eve acp` separately.
77
+
78
+ ```sh
79
+ npx acpx@latest \
80
+ --agent 'pnpm exec eve acp' \
81
+ exec 'Reply with exactly: ACP works'
82
+ ```
83
+
84
+ When testing from the eve source checkout, use an authored fixture rather than the monorepo root, which does not provide an `eve` executable:
85
+
86
+ ```sh
87
+ cd apps/fixtures/weather-agent
88
+ npx acpx@latest --agent 'pnpm exec eve acp' exec 'Reply with exactly: ACP works'
89
+ ```
90
+
91
+ If startup fails, inspect the ACP client's logs together with eve's stderr. A non-empty client MCP configuration, a mismatched working directory, and unsupported prompt content produce explicit protocol errors before model work begins.