eve 0.52.1 → 0.52.3

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 (240) hide show
  1. package/CHANGELOG.md +40 -0
  2. package/dist/src/channel/types.d.ts +1 -0
  3. package/dist/src/chunks/{use-eve-agent-CxkGSusZ.js → use-eve-agent-BR8EpIOX.js} +46 -19
  4. package/dist/src/chunks/{use-eve-agent-Crmh_YB-.js → use-eve-agent-XnfjQt1Z.js} +46 -19
  5. package/dist/src/cli/commands/deploy.js +1 -1
  6. package/dist/src/cli/commands/extension-init.d.ts +2 -1
  7. package/dist/src/cli/commands/extension-init.js +1 -1
  8. package/dist/src/cli/commands/init.d.ts +2 -13
  9. package/dist/src/cli/commands/init.js +1 -1
  10. package/dist/src/cli/dev/run-interactive-ui.d.ts +3 -0
  11. package/dist/src/cli/dev/run-interactive-ui.js +1 -1
  12. package/dist/src/cli/dev/tui/prompt-command-handler.js +1 -1
  13. package/dist/src/cli/dev/tui/runner.d.ts +6 -0
  14. package/dist/src/cli/dev/tui/runner.js +1 -1
  15. package/dist/src/cli/dev/tui/setup-commands.d.ts +5 -3
  16. package/dist/src/cli/dev/tui/setup-commands.js +2 -2
  17. package/dist/src/cli/dev/tui/status-line.js +1 -1
  18. package/dist/src/cli/dev/tui/subagent-pump.js +1 -1
  19. package/dist/src/cli/dev/tui/tui.d.ts +4 -0
  20. package/dist/src/cli/dev/tui/tui.js +1 -1
  21. package/dist/src/cli/run.d.ts +1 -1
  22. package/dist/src/cli/run.js +2 -2
  23. package/dist/src/cli/telemetry/index.d.ts +15 -0
  24. package/dist/src/cli/telemetry/index.js +2 -2
  25. package/dist/src/client/eve-agent-store.js +1 -1
  26. package/dist/src/client/ndjson.js +1 -1
  27. package/dist/src/client/session.js +1 -1
  28. package/dist/src/compiled/.vendor-stamp.json +1 -1
  29. package/dist/src/compiler/compile-from-memory.d.ts +1 -0
  30. package/dist/src/compiler/compile-from-memory.js +1 -1
  31. package/dist/src/compiler/default-tool-policy.d.ts +6 -0
  32. package/dist/src/compiler/default-tool-policy.js +1 -0
  33. package/dist/src/compiler/extension-compatibility.d.ts +18 -18
  34. package/dist/src/compiler/extension-compatibility.js +1 -1
  35. package/dist/src/compiler/manifest.js +1 -1
  36. package/dist/src/compiler/normalize-agent-config.js +1 -1
  37. package/dist/src/compiler/normalize-manifest.js +1 -1
  38. package/dist/src/context/build-dynamic-tools.d.ts +2 -1
  39. package/dist/src/context/build-dynamic-tools.js +1 -1
  40. package/dist/src/context/dynamic-tool-lifecycle.d.ts +3 -3
  41. package/dist/src/context/dynamic-tool-lifecycle.js +1 -1
  42. package/dist/src/context/dynamic-tool-metadata.d.ts +1 -1
  43. package/dist/src/context/hook-lifecycle.js +1 -1
  44. package/dist/src/context/keys.d.ts +2 -0
  45. package/dist/src/context/keys.js +1 -1
  46. package/dist/src/evals/cli/eval.js +1 -1
  47. package/dist/src/eve-channel/index.js +1 -1
  48. package/dist/src/execution/activity-events.d.ts +1 -0
  49. package/dist/src/execution/activity-events.js +1 -1
  50. package/dist/src/execution/node-step.js +1 -1
  51. package/dist/src/execution/sandbox/prewarm.js +1 -1
  52. package/dist/src/execution/session-activity-projection.js +1 -1
  53. package/dist/src/execution/session-activity.js +1 -1
  54. package/dist/src/execution/settle-cancelled-turn-step.js +1 -1
  55. package/dist/src/execution/tasks/parent/dispatch.js +1 -1
  56. package/dist/src/execution/tasks/parent/task-cancel.d.ts +2 -2
  57. package/dist/src/execution/tasks/parent/task-cancel.js +1 -1
  58. package/dist/src/execution/tasks/parent/tool-execution.js +1 -1
  59. package/dist/src/execution/tools/sleep-workflow.js +1 -1
  60. package/dist/src/execution/workflow-runtime.js +1 -1
  61. package/dist/src/execution/workflow-steps.js +1 -1
  62. package/dist/src/execution/workflow-webhook-route.js +1 -1
  63. package/dist/src/framework/sources/registry.js +1 -1
  64. package/dist/src/harness/action-presentation.d.ts +13 -0
  65. package/dist/src/harness/action-presentation.js +1 -0
  66. package/dist/src/harness/approval-delivery-coordinator.js +1 -1
  67. package/dist/src/harness/compaction-prompt.d.ts +1 -0
  68. package/dist/src/harness/compaction-prompt.js +1 -1
  69. package/dist/src/harness/compaction.js +1 -1
  70. package/dist/src/harness/coordination.js +1 -1
  71. package/dist/src/harness/emission.d.ts +1 -6
  72. package/dist/src/harness/emission.js +1 -1
  73. package/dist/src/harness/execute-tool.d.ts +2 -1
  74. package/dist/src/harness/finish-reason.d.ts +3 -0
  75. package/dist/src/harness/finish-reason.js +1 -0
  76. package/dist/src/harness/provider-tool-schemas.d.ts +1 -0
  77. package/dist/src/harness/provider-tool-schemas.js +1 -1
  78. package/dist/src/harness/step-hooks.js +1 -1
  79. package/dist/src/harness/stream-actions.d.ts +2 -2
  80. package/dist/src/harness/stream-actions.js +1 -1
  81. package/dist/src/harness/tool-call-input-errors.d.ts +4 -3
  82. package/dist/src/harness/tool-call-input-errors.js +1 -1
  83. package/dist/src/harness/tool-loop.js +2 -2
  84. package/dist/src/harness/tool-presentation.d.ts +5 -0
  85. package/dist/src/harness/tool-presentation.js +1 -0
  86. package/dist/src/harness/turn-client-context.d.ts +1 -0
  87. package/dist/src/harness/workflow-lifecycle.d.ts +2 -3
  88. package/dist/src/harness/workflow-lifecycle.js +1 -1
  89. package/dist/src/internal/application/compiled-artifacts.d.ts +3 -0
  90. package/dist/src/internal/application/compiled-artifacts.js +1 -1
  91. package/dist/src/internal/application/package.js +1 -1
  92. package/dist/src/internal/authored-definition/core.js +1 -1
  93. package/dist/src/internal/authored-definition/schema-backed.js +1 -1
  94. package/dist/src/internal/authored-module-conditions.d.ts +2 -0
  95. package/dist/src/internal/authored-module-conditions.js +1 -0
  96. package/dist/src/internal/authored-module-loader.d.ts +3 -0
  97. package/dist/src/internal/authored-module-loader.js +3 -3
  98. package/dist/src/internal/authored-module-map-loader.d.ts +3 -1
  99. package/dist/src/internal/authored-module-map-loader.js +1 -1
  100. package/dist/src/internal/authored-runtime-modules.d.ts +2 -0
  101. package/dist/src/internal/authored-runtime-modules.js +1 -1
  102. package/dist/src/internal/bundler/nitro-rolldown.d.ts +1 -0
  103. package/dist/src/internal/bundler/nitro-rolldown.js +1 -1
  104. package/dist/src/internal/nitro/development-generation.d.ts +2 -0
  105. package/dist/src/internal/nitro/development-generation.js +1 -1
  106. package/dist/src/internal/nitro/host/configure-nitro-routes.js +1 -1
  107. package/dist/src/internal/nitro/host/create-application-nitro.js +1 -1
  108. package/dist/src/internal/nitro/host/prepare-application-host.js +1 -1
  109. package/dist/src/internal/nitro/routes/channel-request-instrumentation.js +1 -1
  110. package/dist/src/internal/node-esm-compat-banner.d.ts +19 -6
  111. package/dist/src/internal/node-esm-compat-banner.js +2 -2
  112. package/dist/src/internal/workflow-bundle/builder-support.d.ts +5 -0
  113. package/dist/src/internal/workflow-bundle/builder.js +2 -2
  114. package/dist/src/internal/workflow-bundle/dynamic-tool-transform.d.ts +1 -1
  115. package/dist/src/internal/workflow-bundle/dynamic-tool-transform.js +1 -1
  116. package/dist/src/internal/workflow-bundle/workflow-core-shim.js +1 -1
  117. package/dist/src/protocol/activity.d.ts +6 -0
  118. package/dist/src/protocol/activity.js +1 -1
  119. package/dist/src/protocol/message.d.ts +13 -1
  120. package/dist/src/protocol/message.js +1 -1
  121. package/dist/src/public/channels/slack/activity-plan.js +1 -1
  122. package/dist/src/public/channels/slack/activity.js +2 -2
  123. package/dist/src/public/channels/slack/connections.d.ts +2 -2
  124. package/dist/src/public/channels/slack/connections.js +1 -1
  125. package/dist/src/public/memory/file/backends/default.js +1 -1
  126. package/dist/src/public/models/openai/chatgpt/credential-store.d.ts +6 -0
  127. package/dist/src/public/models/openai/chatgpt/credential-store.js +1 -0
  128. package/dist/src/public/models/openai/chatgpt/model.d.ts +1 -1
  129. package/dist/src/public/models/openai/chatgpt/oauth.d.ts +20 -0
  130. package/dist/src/public/models/openai/chatgpt/oauth.js +1 -0
  131. package/dist/src/public/models/openai/chatgpt/token-broker.d.ts +4 -3
  132. package/dist/src/public/models/openai/chatgpt/token-broker.js +1 -1
  133. package/dist/src/public/models/openai/chatgpt/transport.d.ts +1 -2
  134. package/dist/src/public/models/openai/index.d.ts +3 -4
  135. package/dist/src/public/tools/agent.d.ts +1 -0
  136. package/dist/src/public/tools/agent.js +1 -0
  137. package/dist/src/public/tools/ask-question.d.ts +1 -0
  138. package/dist/src/public/tools/ask-question.js +1 -0
  139. package/dist/src/public/tools/connection-search.d.ts +1 -0
  140. package/dist/src/public/tools/connection-search.js +1 -0
  141. package/dist/src/public/tools/index.d.ts +1 -1
  142. package/dist/src/public/tools/task-cancel.d.ts +1 -0
  143. package/dist/src/public/tools/task-cancel.js +1 -0
  144. package/dist/src/public/tools/task-update.d.ts +1 -0
  145. package/dist/src/public/tools/task-update.js +1 -0
  146. package/dist/src/runtime/connections/openapi-schema.js +1 -1
  147. package/dist/src/runtime/prompt/compose.js +1 -1
  148. package/dist/src/runtime/resolve-agent.js +1 -1
  149. package/dist/src/runtime/resolve-tool.js +1 -1
  150. package/dist/src/runtime/subagents/dynamic-agent-config.js +1 -1
  151. package/dist/src/runtime/types.d.ts +2 -0
  152. package/dist/src/self-modification/agent.js +1 -1
  153. package/dist/src/self-modification/extension/instructions.d.ts +1 -3
  154. package/dist/src/self-modification/extension/instructions.js +4 -2
  155. package/dist/src/self-modification/filesystem.js +1 -1
  156. package/dist/src/setup/flows/chatgpt-auth.d.ts +14 -2
  157. package/dist/src/setup/flows/chatgpt-auth.js +1 -1
  158. package/dist/src/setup/flows/model.d.ts +3 -2
  159. package/dist/src/setup/flows/model.js +1 -1
  160. package/dist/src/setup/flows/provider.js +1 -1
  161. package/dist/src/setup/flows/registry.d.ts +4 -0
  162. package/dist/src/setup/flows/registry.js +1 -1
  163. package/dist/src/setup/integrations/file-memory/vercel.d.ts +2 -2
  164. package/dist/src/setup/integrations/file-memory/vercel.js +1 -1
  165. package/dist/src/setup/scaffold/create/project.js +1 -1
  166. package/dist/src/shared/agent-definition.d.ts +7 -0
  167. package/dist/src/shared/boundary-hook-error.d.ts +4 -0
  168. package/dist/src/shared/boundary-hook-error.js +1 -0
  169. package/dist/src/{execution/activity-text.d.ts → shared/presentation-text.d.ts} +1 -1
  170. package/dist/src/shared/presentation-text.js +1 -0
  171. package/dist/src/svelte/index.js +1 -1
  172. package/dist/src/svelte/use-eve-agent.js +1 -1
  173. package/dist/src/tools/definition.d.ts +29 -0
  174. package/dist/src/tools/definition.js +1 -1
  175. package/dist/src/tools/durable-callbacks.d.ts +40 -9
  176. package/dist/src/tools/durable-callbacks.js +1 -1
  177. package/dist/src/tools/dynamic.d.ts +4 -1
  178. package/dist/src/tools/framework/agent-contract.js +1 -1
  179. package/dist/src/tools/provided/bash.js +1 -1
  180. package/dist/src/tools/provided/glob.js +1 -1
  181. package/dist/src/tools/provided/grep.js +1 -1
  182. package/dist/src/tools/provided/load-skill.js +1 -1
  183. package/dist/src/tools/provided/read-file.js +1 -1
  184. package/dist/src/tools/provided/web-fetch.js +1 -1
  185. package/dist/src/tools/provided/write-file.js +1 -1
  186. package/dist/src/tools/tool-label.d.ts +1 -0
  187. package/dist/src/tools/tool-label.js +1 -0
  188. package/dist/src/tracing/agent-action-instrumentation.js +1 -1
  189. package/dist/src/tracing/agent-approval-instrumentation.js +1 -1
  190. package/dist/src/tracing/agent-channel-delivery-instrumentation.js +1 -1
  191. package/dist/src/tracing/agent-otel-provider.js +2 -2
  192. package/dist/src/tracing/agent-otel-session-context.js +1 -1
  193. package/dist/src/tracing/agent-otel-usage.d.ts +10 -0
  194. package/dist/src/tracing/agent-otel-usage.js +1 -1
  195. package/dist/src/tracing/agent-span-naming.d.ts +1 -0
  196. package/dist/src/tracing/agent-span-naming.js +1 -0
  197. package/dist/src/tracing/agent-tool-instrumentation.js +1 -1
  198. package/dist/src/vue/index.js +1 -1
  199. package/dist/src/vue/use-eve-agent.js +1 -1
  200. package/docs/channels/slack.mdx +2 -0
  201. package/docs/concepts/built-in-tools.md +397 -68
  202. package/docs/concepts/default-harness.md +6 -0
  203. package/docs/concepts/sessions-runs-and-streaming.md +4 -0
  204. package/docs/connections/openapi.mdx +4 -0
  205. package/docs/connections/overview.mdx +1 -1
  206. package/docs/evals/running.mdx +2 -0
  207. package/docs/guides/client/continuations.mdx +11 -0
  208. package/docs/guides/client/streaming.mdx +7 -1
  209. package/docs/guides/dynamic-capabilities.md +5 -5
  210. package/docs/guides/frontend/overview.mdx +1 -1
  211. package/docs/guides/hooks.md +1 -1
  212. package/docs/guides/instrumentation.md +40 -1
  213. package/docs/guides/remote-agents.md +2 -0
  214. package/docs/instructions.mdx +1 -1
  215. package/docs/memory/custom-provider.md +4 -1
  216. package/docs/memory/file.md +25 -12
  217. package/docs/memory/overview.mdx +45 -13
  218. package/docs/reference/cli.md +6 -0
  219. package/docs/reference/telemetry.md +2 -2
  220. package/docs/reference/typescript-api.md +13 -9
  221. package/docs/sandbox.mdx +14 -2
  222. package/docs/subagents/index.mdx +8 -4
  223. package/docs/tools/overview.mdx +44 -2
  224. package/docs/tools/workflows.mdx +9 -1
  225. package/docs/tutorial/connect-a-warehouse.mdx +49 -26
  226. package/docs/tutorial/first-agent.mdx +20 -19
  227. package/docs/tutorial/guard-the-spend.mdx +4 -4
  228. package/docs/tutorial/how-it-runs.mdx +2 -3
  229. package/docs/tutorial/meta.json +2 -2
  230. package/docs/tutorial/query-sample-data.mdx +30 -19
  231. package/docs/tutorial/remember-definitions.mdx +5 -5
  232. package/docs/tutorial/run-analysis.mdx +155 -18
  233. package/docs/tutorial/ship-it.mdx +71 -81
  234. package/docs/tutorial/team-playbooks.mdx +10 -10
  235. package/package.json +32 -7
  236. package/dist/src/execution/activity-text.js +0 -1
  237. package/dist/src/internal/workflow-bundle/authored-workflow-modules.d.ts +0 -9
  238. package/dist/src/internal/workflow-bundle/authored-workflow-modules.js +0 -1
  239. package/dist/src/public/models/openai/chatgpt/codex-app-server.d.ts +0 -40
  240. package/dist/src/public/models/openai/chatgpt/codex-app-server.js +0 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,45 @@
1
1
  # eve
2
2
 
3
+ ## 0.52.3
4
+
5
+ ### Patch Changes
6
+
7
+ - 9cb899d: Add explicit Datadog operation and resource names to framework-owned agent spans while preserving their OpenTelemetry names and trace hierarchy. Agent invocation spans now include `agent.turn.outcome` so completion, failure, and cancellation remain queryable in backends that discard span events.
8
+ - 1a4f0b3: Allow tools to define an input-aware activity label for channel presentation. Framework tools now provide readable labels for shell, file, skill, fetch, and search actions.
9
+ - e5d8e7b: Match each client `send()` response to the message accepted by the server. Resuming a session with an old stream cursor now skips earlier turns instead of returning an old result.
10
+ - 14af96f: Preserve Node.js custom resolution conditions when bundling authored modules. Production builds with a channel importing `server-only` under `react-server` now produce a valid module map.
11
+ - 4cff7dc: Fix `eve start` failing when an app built on another machine is deployed to a different directory. Sandbox prewarming now resolves authored modules from the deployed app while preserving TypeScript aliases and workspace package resolution.
12
+ - 9034901: Resolve workflow path aliases from the application config and bundle only workflows reachable from the agent. Unresolved workflow imports now fail the build instead of producing a bundle that crashes every durable session.
13
+ - 8a50983: Keep dynamic tool callbacks isolated by session, lifecycle scope, and resolver. Replaying a tool now retains its own implementation when another session or scope registers the same tool name.
14
+ - 0d19fa3: Fix repeated ineffective compaction when provider-reported input tokens exceed the character estimate. Tool-result trimming now accounts for measured context pressure and falls back to summarization when it cannot free enough space.
15
+ - 67f3b8d: Sign in to a ChatGPT subscription directly from eve without installing the Codex CLI. eve now manages its own local login and token refresh, with browser sign-in, device codes over SSH, and actionable recovery messages; existing Codex users sign in once through `/model` after upgrading.
16
+ - 2ff8511: Preserve a cancelled task's notification to its parent when shutdown exceeds the cooperative grace period. Parents no longer wait for a notification from a task that was already cancelled.
17
+ - 3c3a0df: Allow async-generator tools to project typed preliminary and final results into bounded user-facing activity text with `activity.update` and `activity.result`.
18
+ - 2ff8511: Keep conversation sessions available after a `turn.started` or `step.started` handler throws. The failed turn reports the error, and a later message can resume the same session.
19
+ - 461b578: Keep framework context at a stable position throughout a turn so tool steps can reuse the existing prompt prefix instead of moving skill announcements behind new tool results.
20
+ - 4b5fad4: Steer a running background subagent by sending an updated message with its existing `agentId`. eve cancels its previous task and starts a new task in the same child session, preserving its conversation history.
21
+ - 59ec96c: Add CLI telemetry for setup and onboarding flows.
22
+
23
+ ## 0.52.2
24
+
25
+ ### Patch Changes
26
+
27
+ - 9cb98b9: Ignore OpenAPI `default` and `example` annotations whose values conflict with the declared schema type, so models are not prompted to submit invalid tool input.
28
+ - 1807ff9: Preserve conversation history when the compaction model returns an empty summary instead of replacing it with a blank checkpoint.
29
+ - 6dfd6d6: Point published `eve-source` export conditions at `dist` so Workflow bundle resolution works without the unpublished `src` tree.
30
+ - 9cb98b9: Resume settled sessions without waiting for the live stream idle timeout while preserving catch-up for turns accepted during replay.
31
+ - 4e0b345: Fix file-memory setup to connect private Vercel Blob storage with `EVE_MEMORY_BLOB_*` variables and OIDC authentication without provisioning a read-write token. Prefer OIDC for attached stores and let the Blob SDK resolve and refresh tokens instead of caching them in the memory backend.
32
+ - 9cb98b9: Prevent `eve dev` bundles that inline comma-separated CommonJS path globals from failing to load with duplicate declarations.
33
+ - 9cb98b9: Ensure `eve eval --json` writes the complete report when stdout is piped to another process.
34
+ - 9cb98b9: Keep Slack connection authorization buttons valid when a connection has a long display name.
35
+ - 9cb98b9: Workflow tools now create publicly resumable webhooks, fixing callbacks that returned 404. Webhook response options are preserved, and authored webhook tokens are rejected consistently with Workflow.
36
+ - 9cb98b9: Preserve steering replacements when cancelled turn work throws a generic `AbortError`, so the session returns to waiting instead of failing.
37
+ - 1807ff9: Fix client `result()` calls hanging after a turn finishes when fetch instrumentation clones the event stream, including eve-to-eve calls from authored tools. Client and TUI subagent stream cleanup now releases the HTTP connection without waiting for the tracing reader.
38
+ - 4446e0d: Allow agents to set `defaultTools: false` to skip eve's optional default tools while preserving connection discovery and tools explicitly authored under `agent/tools/`. Every optional default can be re-added from its public `eve/tools/*` subpath.
39
+ - 9cb98b9: Preserve complete Unicode characters when truncating compaction transcripts and tool results, preventing emoji at the cutoff from causing provider request failures.
40
+ - 9cb98b9: Preserve input-scoped approval keys on dynamic tools, including durable replay, so approvals record the intended key instead of the bare tool name.
41
+ - 9cb98b9: Reconnect session streams when browser response-body reads fail with vendor-specific `TypeError` messages, while keeping initial fetch retries limited to known transport errors.
42
+
3
43
  ## 0.52.1
4
44
 
5
45
  ### Patch Changes
@@ -198,6 +198,7 @@ export type SessionCommand = {
198
198
  export type SessionSendCommandResult = {
199
199
  readonly status: "accepted";
200
200
  readonly sessionId: string;
201
+ readonly deliveryId?: string;
201
202
  } | {
202
203
  readonly status: "session_not_active";
203
204
  };
@@ -915,7 +915,7 @@ async function* readNdjsonStream(body, options) {
915
915
  const trailing = buffer.trim();
916
916
  if (trailing.length > 0) yield parseMessageStreamEvent(trailing, options.streamVersion);
917
917
  } finally {
918
- if (!reachedEof) await reader.cancel().catch(() => {});
918
+ if (!reachedEof) reader.cancel().catch(() => {});
919
919
  reader.releaseLock();
920
920
  }
921
921
  }
@@ -924,12 +924,15 @@ function parseMessageStreamEvent(line, version) {
924
924
  return normalizeMessageStreamEvent(version, event);
925
925
  }
926
926
  async function readWithIdleTimeout(reader, idleTimeoutMs) {
927
- if (idleTimeoutMs === void 0) return await reader.read();
928
927
  let timeout;
929
928
  try {
929
+ if (idleTimeoutMs === void 0) return await reader.read();
930
930
  return await Promise.race([reader.read(), new Promise((_resolve, reject) => {
931
931
  timeout = setTimeout(() => reject(new DOMException("Session stream was idle.", "AbortError")), idleTimeoutMs);
932
932
  })]);
933
+ } catch (error) {
934
+ if (error instanceof TypeError) throw new Error("Session stream disconnected.", { cause: error });
935
+ throw error;
933
936
  } finally {
934
937
  if (timeout !== void 0) clearTimeout(timeout);
935
938
  }
@@ -1404,7 +1407,7 @@ var ClientSession = class ClientSession {
1404
1407
  }
1405
1408
  static async create(context, input) {
1406
1409
  const response = await postTurn(context, EVE_SESSION_ROUTE_PATH, input, true);
1407
- const sessionId = await readSessionId(response);
1410
+ const { sessionId } = await readAcceptedMessage(response);
1408
1411
  const session = new ClientSession(context, {
1409
1412
  sessionId,
1410
1413
  streamIndex: 0
@@ -1451,8 +1454,10 @@ var ClientSession = class ClientSession {
1451
1454
  const initialStreamIndex = this.#state.streamIndex;
1452
1455
  const path = createEveSessionRoutePath(this.#state.sessionId);
1453
1456
  const response = retrySessionNotActive ? await postSessionSend(this.#context, path, input) : await postTurn(this.#context, path, input, false);
1454
- if (await readSessionId(response, this.#state.sessionId) !== this.#state.sessionId) throw new Error("Message route returned a different session id.");
1455
- return this.#messageResponse(response, input, initialStreamIndex);
1457
+ const { sessionId: responseSessionId, deliveryId } = await readAcceptedMessage(response, this.#state.sessionId);
1458
+ if (responseSessionId !== this.#state.sessionId) throw new Error("Message route returned a different session id.");
1459
+ if (input.message !== void 0 && deliveryId === void 0) throw new Error("Message route did not return a delivery id. Update the server before sending with this client.");
1460
+ return this.#messageResponse(response, input, initialStreamIndex, input.message === void 0 ? void 0 : deliveryId);
1456
1461
  }
1457
1462
  async cancel(options) {
1458
1463
  return await cancelClientSession({
@@ -1484,16 +1489,18 @@ var ClientSession = class ClientSession {
1484
1489
  if (options?.follow === false && (options.startIndex ?? this.#state.streamIndex) < 0) throw new Error("stream({ follow: false }) requires a nonnegative startIndex; a tail-relative cursor cannot be bounded.");
1485
1490
  return this.#streamAndAdvance(options);
1486
1491
  }
1487
- #messageResponse(response, input, initialStreamIndex) {
1492
+ #messageResponse(response, input, initialStreamIndex, deliveryId) {
1488
1493
  response.body?.cancel().catch(() => {});
1489
1494
  return new MessageResponse({
1490
1495
  cancelTurn: async (turnId) => await this.cancel({ turnId }),
1491
- createStream: () => this.#createEventStream(initialStreamIndex, input),
1496
+ createStream: () => this.#createEventStream(initialStreamIndex, input, deliveryId),
1492
1497
  sessionId: this.#state.sessionId
1493
1498
  });
1494
1499
  }
1495
- async *#createEventStream(initialStreamIndex, input) {
1500
+ async *#createEventStream(initialStreamIndex, input, deliveryId) {
1496
1501
  let eventCount = 0;
1502
+ let started = deliveryId === void 0;
1503
+ let reachedBoundary = false;
1497
1504
  const pendingAuthorizations = /* @__PURE__ */ new Set();
1498
1505
  try {
1499
1506
  for await (const event of this.#readStream({
@@ -1504,15 +1511,25 @@ var ClientSession = class ClientSession {
1504
1511
  streamReconnectPolicy: input.streamReconnectPolicy
1505
1512
  })) {
1506
1513
  eventCount += 1;
1514
+ if (deliveryId !== void 0) {
1515
+ const matches = event.meta?.deliveryIds?.includes(deliveryId) === true;
1516
+ const terminal = event.type === "session.failed" || event.type === "session.completed";
1517
+ if (!matches && terminal && (!started || event.type === "session.completed")) throw new Error("The session ended before the accepted message reached its turn boundary.");
1518
+ if (!started && !matches) continue;
1519
+ if (!terminal && event.meta?.deliveryIds !== void 0 && !matches) continue;
1520
+ started = true;
1521
+ }
1507
1522
  if (event.type === "authorization.required" && event.data.webhookUrl !== void 0) pendingAuthorizations.add(event.data.name);
1508
1523
  else if (event.type === "authorization.completed") pendingAuthorizations.delete(event.data.name);
1524
+ reachedBoundary = isCurrentTurnBoundaryEvent(event) && (event.type !== "session.waiting" || pendingAuthorizations.size === 0);
1509
1525
  yield event;
1510
- if (isCurrentTurnBoundaryEvent(event) && (event.type !== "session.waiting" || pendingAuthorizations.size === 0)) break;
1526
+ if (reachedBoundary) break;
1511
1527
  }
1528
+ if (deliveryId !== void 0 && !reachedBoundary && !input.signal?.aborted) throw new Error("The response stream ended before the accepted message reached its turn boundary.");
1512
1529
  } finally {
1513
1530
  this.#state = {
1514
1531
  sessionId: this.#state.sessionId,
1515
- streamIndex: initialStreamIndex + eventCount
1532
+ streamIndex: Math.max(this.#state.streamIndex, initialStreamIndex + eventCount)
1516
1533
  };
1517
1534
  }
1518
1535
  }
@@ -1588,11 +1605,14 @@ async function postTurn(context, path, input, requireMessage) {
1588
1605
  }
1589
1606
  return response;
1590
1607
  }
1591
- async function readSessionId(response, expected) {
1608
+ async function readAcceptedMessage(response, expected) {
1592
1609
  const payload = await response.json();
1593
1610
  const sessionId = (typeof payload.sessionId === "string" ? payload.sessionId : void 0) ?? response.headers.get("x-eve-session-id")?.trim() ?? expected;
1594
1611
  if (!sessionId) throw new Error("Message route did not return a session id.");
1595
- return sessionId;
1612
+ return {
1613
+ sessionId,
1614
+ deliveryId: typeof payload.deliveryId === "string" && payload.deliveryId.length > 0 ? payload.deliveryId : void 0
1615
+ };
1596
1616
  }
1597
1617
  function createMessageBody(input, requireMessage) {
1598
1618
  const body = {};
@@ -1979,14 +1999,21 @@ var EveAgentStore = class {
1979
1999
  const pendingAuthorizations = collectPendingAuthorizations(replayed);
1980
2000
  if (!replaySettled) this.#status = "streaming";
1981
2001
  this.#publish();
1982
- for await (const event of session.stream({
1983
- signal: turn.abortController.signal,
1984
- streamReconnectPolicy: replaySettled ? { reconnect: false } : void 0
1985
- })) {
2002
+ let followLive = !replaySettled;
2003
+ for (;;) {
2004
+ for await (const event of session.stream({
2005
+ follow: followLive ? void 0 : false,
2006
+ signal: turn.abortController.signal
2007
+ })) {
2008
+ if (!this.#isActiveTurn(turn)) return;
2009
+ replayed.push(event);
2010
+ this.#acceptServerEvent(event);
2011
+ updatePendingAuthorizations(pendingAuthorizations, event);
2012
+ if (followLive && isCurrentTurnBoundaryEvent(event) && (event.type !== "session.waiting" || pendingAuthorizations.size === 0)) break;
2013
+ }
1986
2014
  if (!this.#isActiveTurn(turn)) return;
1987
- this.#acceptServerEvent(event);
1988
- updatePendingAuthorizations(pendingAuthorizations, event);
1989
- if (isCurrentTurnBoundaryEvent(event) && (event.type !== "session.waiting" || pendingAuthorizations.size === 0)) break;
2015
+ if (followLive || isSettledSessionTail(replayed)) break;
2016
+ followLive = true;
1990
2017
  }
1991
2018
  } else {
1992
2019
  this.#status = this.#error === void 0 ? "ready" : "error";
@@ -915,7 +915,7 @@ async function* readNdjsonStream(body, options) {
915
915
  const trailing = buffer.trim();
916
916
  if (trailing.length > 0) yield parseMessageStreamEvent(trailing, options.streamVersion);
917
917
  } finally {
918
- if (!reachedEof) await reader.cancel().catch(() => {});
918
+ if (!reachedEof) reader.cancel().catch(() => {});
919
919
  reader.releaseLock();
920
920
  }
921
921
  }
@@ -924,12 +924,15 @@ function parseMessageStreamEvent(line, version) {
924
924
  return normalizeMessageStreamEvent(version, event);
925
925
  }
926
926
  async function readWithIdleTimeout(reader, idleTimeoutMs) {
927
- if (idleTimeoutMs === void 0) return await reader.read();
928
927
  let timeout;
929
928
  try {
929
+ if (idleTimeoutMs === void 0) return await reader.read();
930
930
  return await Promise.race([reader.read(), new Promise((_resolve, reject) => {
931
931
  timeout = setTimeout(() => reject(new DOMException("Session stream was idle.", "AbortError")), idleTimeoutMs);
932
932
  })]);
933
+ } catch (error) {
934
+ if (error instanceof TypeError) throw new Error("Session stream disconnected.", { cause: error });
935
+ throw error;
933
936
  } finally {
934
937
  if (timeout !== void 0) clearTimeout(timeout);
935
938
  }
@@ -1404,7 +1407,7 @@ var ClientSession = class ClientSession {
1404
1407
  }
1405
1408
  static async create(context, input) {
1406
1409
  const response = await postTurn(context, EVE_SESSION_ROUTE_PATH, input, true);
1407
- const sessionId = await readSessionId(response);
1410
+ const { sessionId } = await readAcceptedMessage(response);
1408
1411
  const session = new ClientSession(context, {
1409
1412
  sessionId,
1410
1413
  streamIndex: 0
@@ -1451,8 +1454,10 @@ var ClientSession = class ClientSession {
1451
1454
  const initialStreamIndex = this.#state.streamIndex;
1452
1455
  const path = createEveSessionRoutePath(this.#state.sessionId);
1453
1456
  const response = retrySessionNotActive ? await postSessionSend(this.#context, path, input) : await postTurn(this.#context, path, input, false);
1454
- if (await readSessionId(response, this.#state.sessionId) !== this.#state.sessionId) throw new Error("Message route returned a different session id.");
1455
- return this.#messageResponse(response, input, initialStreamIndex);
1457
+ const { sessionId: responseSessionId, deliveryId } = await readAcceptedMessage(response, this.#state.sessionId);
1458
+ if (responseSessionId !== this.#state.sessionId) throw new Error("Message route returned a different session id.");
1459
+ if (input.message !== void 0 && deliveryId === void 0) throw new Error("Message route did not return a delivery id. Update the server before sending with this client.");
1460
+ return this.#messageResponse(response, input, initialStreamIndex, input.message === void 0 ? void 0 : deliveryId);
1456
1461
  }
1457
1462
  async cancel(options) {
1458
1463
  return await cancelClientSession({
@@ -1484,16 +1489,18 @@ var ClientSession = class ClientSession {
1484
1489
  if (options?.follow === false && (options.startIndex ?? this.#state.streamIndex) < 0) throw new Error("stream({ follow: false }) requires a nonnegative startIndex; a tail-relative cursor cannot be bounded.");
1485
1490
  return this.#streamAndAdvance(options);
1486
1491
  }
1487
- #messageResponse(response, input, initialStreamIndex) {
1492
+ #messageResponse(response, input, initialStreamIndex, deliveryId) {
1488
1493
  response.body?.cancel().catch(() => {});
1489
1494
  return new MessageResponse({
1490
1495
  cancelTurn: async (turnId) => await this.cancel({ turnId }),
1491
- createStream: () => this.#createEventStream(initialStreamIndex, input),
1496
+ createStream: () => this.#createEventStream(initialStreamIndex, input, deliveryId),
1492
1497
  sessionId: this.#state.sessionId
1493
1498
  });
1494
1499
  }
1495
- async *#createEventStream(initialStreamIndex, input) {
1500
+ async *#createEventStream(initialStreamIndex, input, deliveryId) {
1496
1501
  let eventCount = 0;
1502
+ let started = deliveryId === void 0;
1503
+ let reachedBoundary = false;
1497
1504
  const pendingAuthorizations = /* @__PURE__ */ new Set();
1498
1505
  try {
1499
1506
  for await (const event of this.#readStream({
@@ -1504,15 +1511,25 @@ var ClientSession = class ClientSession {
1504
1511
  streamReconnectPolicy: input.streamReconnectPolicy
1505
1512
  })) {
1506
1513
  eventCount += 1;
1514
+ if (deliveryId !== void 0) {
1515
+ const matches = event.meta?.deliveryIds?.includes(deliveryId) === true;
1516
+ const terminal = event.type === "session.failed" || event.type === "session.completed";
1517
+ if (!matches && terminal && (!started || event.type === "session.completed")) throw new Error("The session ended before the accepted message reached its turn boundary.");
1518
+ if (!started && !matches) continue;
1519
+ if (!terminal && event.meta?.deliveryIds !== void 0 && !matches) continue;
1520
+ started = true;
1521
+ }
1507
1522
  if (event.type === "authorization.required" && event.data.webhookUrl !== void 0) pendingAuthorizations.add(event.data.name);
1508
1523
  else if (event.type === "authorization.completed") pendingAuthorizations.delete(event.data.name);
1524
+ reachedBoundary = isCurrentTurnBoundaryEvent(event) && (event.type !== "session.waiting" || pendingAuthorizations.size === 0);
1509
1525
  yield event;
1510
- if (isCurrentTurnBoundaryEvent(event) && (event.type !== "session.waiting" || pendingAuthorizations.size === 0)) break;
1526
+ if (reachedBoundary) break;
1511
1527
  }
1528
+ if (deliveryId !== void 0 && !reachedBoundary && !input.signal?.aborted) throw new Error("The response stream ended before the accepted message reached its turn boundary.");
1512
1529
  } finally {
1513
1530
  this.#state = {
1514
1531
  sessionId: this.#state.sessionId,
1515
- streamIndex: initialStreamIndex + eventCount
1532
+ streamIndex: Math.max(this.#state.streamIndex, initialStreamIndex + eventCount)
1516
1533
  };
1517
1534
  }
1518
1535
  }
@@ -1588,11 +1605,14 @@ async function postTurn(context, path, input, requireMessage) {
1588
1605
  }
1589
1606
  return response;
1590
1607
  }
1591
- async function readSessionId(response, expected) {
1608
+ async function readAcceptedMessage(response, expected) {
1592
1609
  const payload = await response.json();
1593
1610
  const sessionId = (typeof payload.sessionId === "string" ? payload.sessionId : void 0) ?? response.headers.get("x-eve-session-id")?.trim() ?? expected;
1594
1611
  if (!sessionId) throw new Error("Message route did not return a session id.");
1595
- return sessionId;
1612
+ return {
1613
+ sessionId,
1614
+ deliveryId: typeof payload.deliveryId === "string" && payload.deliveryId.length > 0 ? payload.deliveryId : void 0
1615
+ };
1596
1616
  }
1597
1617
  function createMessageBody(input, requireMessage) {
1598
1618
  const body = {};
@@ -1979,14 +1999,21 @@ var EveAgentStore = class {
1979
1999
  const pendingAuthorizations = collectPendingAuthorizations(replayed);
1980
2000
  if (!replaySettled) this.#status = "streaming";
1981
2001
  this.#publish();
1982
- for await (const event of session.stream({
1983
- signal: turn.abortController.signal,
1984
- streamReconnectPolicy: replaySettled ? { reconnect: false } : void 0
1985
- })) {
2002
+ let followLive = !replaySettled;
2003
+ for (;;) {
2004
+ for await (const event of session.stream({
2005
+ follow: followLive ? void 0 : false,
2006
+ signal: turn.abortController.signal
2007
+ })) {
2008
+ if (!this.#isActiveTurn(turn)) return;
2009
+ replayed.push(event);
2010
+ this.#acceptServerEvent(event);
2011
+ updatePendingAuthorizations(pendingAuthorizations, event);
2012
+ if (followLive && isCurrentTurnBoundaryEvent(event) && (event.type !== "session.waiting" || pendingAuthorizations.size === 0)) break;
2013
+ }
1986
2014
  if (!this.#isActiveTurn(turn)) return;
1987
- this.#acceptServerEvent(event);
1988
- updatePendingAuthorizations(pendingAuthorizations, event);
1989
- if (isCurrentTurnBoundaryEvent(event) && (event.type !== "session.waiting" || pendingAuthorizations.size === 0)) break;
2015
+ if (followLive || isSettledSessionTail(replayed)) break;
2016
+ followLive = true;
1990
2017
  }
1991
2018
  } else {
1992
2019
  this.#status = this.#error === void 0 ? "ready" : "error";
@@ -1 +1 @@
1
- import{hasInteractiveTerminal,validateWorkspaceProjectCommand}from"./preconditions.js";import{isNonInteractiveProjectCommand,runNonInteractiveLink}from"./vercel-non-interactive.js";import{isEveProject}from"#setup/scaffold/index.js";import{runDeployFlow}from"#setup/flows/deploy.js";import{createPrompter}from"#setup/prompter.js";const defaultDependencies={hasInteractiveTerminal,isEveProject};async function runDeployCommand(e,t,n=defaultDependencies,r={}){if(!await validateWorkspaceProjectCommand({appRoot:t,isEveProject:n.isEveProject,logger:e,workspaceMemberMessage:e=>`This agent belongs to the workspace at ${e.root}. Run \`eve deploy\` from the workspace root to deploy every peer agent together.`}))return;if(isNonInteractiveProjectCommand(r)){if(r.yes!==!0){e.error("`eve deploy --non-interactive` requires `--yes` to confirm production deployment."),process.exitCode=1;return}if(r.project!==void 0&&!await runNonInteractiveLink({logger:e,appRoot:t,options:r}))return}let i=n.createPrompter?.()??createPrompter();i.intro(`Deploy your eve agent to Vercel`);try{let a=await runDeployFlow({appRoot:t,prompter:i,interactive:!isNonInteractiveProjectCommand(r)&&n.hasInteractiveTerminal(),deps:n.flowDeps});if(a.kind===`needs-link`){e.error("This directory is not linked to a Vercel project. Run `eve link` first, or name the project on the deploy itself: `eve deploy --project <name-or-id> --non-interactive --yes`."),process.exitCode=1;return}if(a.kind===`local-model`){e.error("ChatGPT subscription models use local Codex credentials and cannot be deployed. Switch to an AI Gateway or server-authenticated model before running `eve deploy`."),process.exitCode=1;return}i.outro(a.kind===`cancelled`?`Cancelled.`:a.productionUrl===void 0?`Deployed.`:`Deployed: ${a.productionUrl}`)}catch(t){e.error(t instanceof Error?t.message:String(t)),process.exitCode=1}}export{runDeployCommand};
1
+ import{hasInteractiveTerminal,validateWorkspaceProjectCommand}from"./preconditions.js";import{isNonInteractiveProjectCommand,runNonInteractiveLink}from"./vercel-non-interactive.js";import{isEveProject}from"#setup/scaffold/index.js";import{runDeployFlow}from"#setup/flows/deploy.js";import{createPrompter}from"#setup/prompter.js";const defaultDependencies={hasInteractiveTerminal,isEveProject};async function runDeployCommand(e,t,n=defaultDependencies,r={}){if(!await validateWorkspaceProjectCommand({appRoot:t,isEveProject:n.isEveProject,logger:e,workspaceMemberMessage:e=>`This agent belongs to the workspace at ${e.root}. Run \`eve deploy\` from the workspace root to deploy every peer agent together.`}))return;if(isNonInteractiveProjectCommand(r)){if(r.yes!==!0){e.error("`eve deploy --non-interactive` requires `--yes` to confirm production deployment."),process.exitCode=1;return}if(r.project!==void 0&&!await runNonInteractiveLink({logger:e,appRoot:t,options:r}))return}let i=n.createPrompter?.()??createPrompter();i.intro(`Deploy your eve agent to Vercel`);try{let a=await runDeployFlow({appRoot:t,prompter:i,interactive:!isNonInteractiveProjectCommand(r)&&n.hasInteractiveTerminal(),deps:n.flowDeps});if(a.kind===`needs-link`){e.error("This directory is not linked to a Vercel project. Run `eve link` first, or name the project on the deploy itself: `eve deploy --project <name-or-id> --non-interactive --yes`."),process.exitCode=1;return}if(a.kind===`local-model`){e.error("ChatGPT subscription models use local ChatGPT credentials and cannot be deployed. Switch to an AI Gateway or server-authenticated model before running `eve deploy`."),process.exitCode=1;return}i.outro(a.kind===`cancelled`?`Cancelled.`:a.productionUrl===void 0?`Deployed.`:`Deployed: ${a.productionUrl}`)}catch(t){e.error(t instanceof Error?t.message:String(t)),process.exitCode=1}}export{runDeployCommand};
@@ -7,6 +7,7 @@ export interface ExtensionInitCliLogger {
7
7
  error(message: string): void;
8
8
  log(message: string): void;
9
9
  }
10
+ export type ExtensionInitSetupStep = "resolve_target" | "scaffold" | "install_dependencies" | "initialize_git" | "handoff";
10
11
  export interface ExtensionInitCommandDependencies {
11
12
  detectInvokingPackageManager: typeof detectInvokingPackageManager;
12
13
  detectPackageManager: typeof detectPackageManager;
@@ -22,4 +23,4 @@ export declare const EVE_INIT_PACKAGE_SPEC_ENV = "EVE_INIT_PACKAGE_SPEC";
22
23
  * Creates a new eve extension package. Same install/git flow as agent `eve init`,
23
24
  * but always create-only and prints next steps instead of starting `eve dev`.
24
25
  */
25
- export declare function runExtensionInitCommand(logger: ExtensionInitCliLogger, parentDirectory: string, target: string | undefined, dependencies?: ExtensionInitCommandDependencies): Promise<void>;
26
+ export declare function runExtensionInitCommand(logger: ExtensionInitCliLogger, parentDirectory: string, target: string | undefined, dependencies?: ExtensionInitCommandDependencies, trackStep?: (step: ExtensionInitSetupStep) => void): Promise<void>;
@@ -1 +1 @@
1
- import{initExtensionHandoff,initExtensionInstructions}from"./agent-instructions.js";import{tryInitializeGit}from"./init-git.js";import{mkdtemp,readdir,rename,rm,stat}from"node:fs/promises";import{createLogger,isLogLevelEnabled}from"#internal/logging.js";import{basename,join,resolve}from"node:path";import pc from"#compiled/picocolors/index.js";import{scaffoldExtensionProject}from"#setup/scaffold/index.js";import{packageManagerInstallFailureMessage,packageManagerInstallSucceeded,runPackageManagerInstall}from"#setup/primitives/index.js";import{performance}from"node:perf_hooks";import{isCodingAgentLaunch}from"#cli/agent-detection.js";import{EVE_WORDMARK}from"#cli/banner.js";import{formatElapsed}from"#cli/format-elapsed.js";import{startCliLiveRow}from"#cli/ui/live-row.js";import{formatNodeEngineOverrideWarning}from"#setup/node-engine.js";import{detectInvokingPackageManager,detectPackageManager}from"#setup/package-manager.js";import{pathExists}from"#setup/path-exists.js";import{parseProjectName}from"#setup/project-name.js";import{blockingCreateInPlaceEntries}from"#setup/scaffold/create-in-place.js";import{DEFAULT_EVE_PACKAGE_CONTRACT}from"#setup/scaffold/create/project.js";const defaultDependencies={detectInvokingPackageManager,detectPackageManager,isCodingAgentLaunch,now:()=>performance.now(),runPackageManagerInstall,scaffoldExtensionProject,tryInitializeGit},EVE_INIT_PACKAGE_SPEC_ENV=`EVE_INIT_PACKAGE_SPEC`,initLog=createLogger(`extension-init`);function isCurrentDirectoryTarget(e){return/^\.(?:[/\\]+\.?)*$/u.test(e.trim())}async function resolveTargetDirectory(e,t){let n=resolve(e,t);return(await stat(n).catch(()=>void 0))?.isDirectory()?n:void 0}async function assertCanScaffoldInPlace(e){let t=await readdir(e),n=blockingCreateInPlaceEntries(t);if(n.length===0)return;let r=n.slice(0,5).join(`, `),i=n.length>5?`, and ${n.length-5} more`:``;throw Error(`Cannot create project in current directory because it is not empty. Found: ${r}${i}. Use an empty directory.`)}async function moveDirectoryContents(e,t){for(let n of await readdir(e))await rename(join(e,n),join(t,n))}function uniqueWorkspaceRootMutations(e){let t=new Map;for(let n of e){let e=`${n.kind}:${n.path}`,r=t.get(e);t.set(e,{...n,nodeEngineOverride:n.nodeEngineOverride??r?.nodeEngineOverride})}return[...t.values()]}function formatWorkspaceRootMutationWarning(e){let t=e.kind===`package-json`?`package.json`:`configuration`,n=e.nodeEngineOverride===void 0?``:` (${formatNodeEngineOverrideWarning(e.nodeEngineOverride)})`;return`Updated workspace root ${t} at ${e.path}${n}`}async function resolveScaffoldPackageManager(e,t){let n=await t.detectPackageManager(e);return n.source==="default"?t.detectInvokingPackageManager()??`pnpm`:n.kind}async function scaffoldExtension(e,t,n,r,i){let a=resolve(e),o=t===`.`,s=o?a:join(a,t);if(o)await assertCanScaffoldInPlace(s);else if(await pathExists(s))throw Error(`Cannot create project because "${s}" already exists.`);let c=await mkdtemp(join(a,`.eve-extension-init-`)),l=[];try{let e=o?basename(s):t,a=await r.scaffoldExtensionProject({projectName:e,evePackage:i,targetDirectory:c,workspaceProbeDirectory:s,packageManager:n,onWorkspaceRootMutation:e=>{l.push(e)}});return o?await moveDirectoryContents(a,s):await rename(a,s),{projectPath:s,workspaceRootMutations:uniqueWorkspaceRootMutations(l)}}finally{await rm(c,{recursive:!0,force:!0})}}function installProgressDetail(e,t){let n=t.text.trim();if(n===``||e!==`npm`)return n||void 0;let r=/^npm silly fetch manifest (.+)$/u.exec(n);if(r!==null)return`Resolving ${r[1]}`;let i=/^npm http fetch \S+ \S+ attempt (\d+) failed with (\S+)$/u.exec(n);if(i!==null)return`npm registry · attempt ${i[1]} failed: ${i[2]}`;if(t.stream===`stdout`||/^npm (?:error|warn)\b/u.test(n))return n}const NPM_NOISE_LINE=/^\s*npm (?:silly|verbose|http|timing)\b/u;function resolveInitEvePackageOverride(){let e=process.env[EVE_INIT_PACKAGE_SPEC_ENV]?.trim();if(e!==void 0&&e.length!==0)return{nodeEngine:DEFAULT_EVE_PACKAGE_CONTRACT.nodeEngine,version:e}}async function runExtensionInitCommand(e,t,n,r=defaultDependencies){if(n===void 0&&await r.isCodingAgentLaunch()){e.log(initExtensionInstructions());return}let i=isLogLevelEnabled(`debug`),a=startCliLiveRow(e);a.update(`Preparing project`);let o,s,c=[],l,u,d;try{let f=n??`.`,p=isCurrentDirectoryTarget(f),m=p?await pathExists(join(resolve(t),`package.json`))?resolve(t):void 0:await resolveTargetDirectory(t,f),h=resolveInitEvePackageOverride();if(m!==void 0)throw Error("`eve extension init` creates a new extension package and cannot add to an existing project. Pass a new directory name, or run from an empty directory with `eve extension init .`.");a.update(`Creating extension`),initLog.debug(`creating extension`);let g=r.now(),_=p?`.`:parseProjectName(f),v=resolve(t);s=await resolveScaffoldPackageManager(_===`.`?v:join(v,_),r);let y=await scaffoldExtension(t,_,s,r,h);o=y.projectPath,c=y.workspaceRootMutations,l=r.now()-g,initLog.debug(`creating extension done`,{ms:l}),a.update(`Installing dependencies`,`${s} install`),initLog.debug(`installing dependencies with ${s}`);let b=r.now(),x=[],S=[],C=await r.runPackageManagerInstall(s,o,{progressDetails:process.stdout.isTTY===!0&&!i,onOutput:e=>{e.text.trim()!==``&&(S.push(e.text),S.length>20&&S.shift(),NPM_NOISE_LINE.test(e.text)||x.push(e.text)),i&&initLog.debug(e.text);let t=installProgressDetail(s,e);t!==void 0&&a.update(`Installing dependencies`,t)}});if(u=r.now()-b,!packageManagerInstallSucceeded(C)){initLog.debug(`dependency installation failed`,{ms:u}),a.stop();let t=x.length>0?x:S;for(let n of t)e.error(n);if(t.length===0){let t=packageManagerInstallFailureMessage(C);t!==void 0&&e.error(t)}throw Error(`Failed to install dependencies in "${o}".`)}initLog.debug(`dependencies installed`,{ms:u}),a.update(`Initializing Git repository`),initLog.debug(`initializing git repository`),d=await r.tryInitializeGit(o)}finally{a.stop()}e.log(`${pc.green(`✓`)} Created an ${EVE_WORDMARK} extension in ${pc.bold(o)} ${pc.dim(`in ${formatElapsed(l)}`)}`);for(let t of c)e.log(pc.yellow(`⚠ ${formatWorkspaceRootMutationWarning(t)}`));e.log(`${pc.green(`✓`)} Installed dependencies ${pc.dim(`in ${formatElapsed(u)}`)}`),d.kind===`failed`?e.error(pc.yellow(`Git initialization failed: ${d.reason}`)):d.kind===`initialized`&&e.log(`${pc.green(`✓`)} Initialized Git repository`),e.log(initExtensionHandoff({packageManager:s,packageName:basename(o),projectPath:o}))}export{EVE_INIT_PACKAGE_SPEC_ENV,runExtensionInitCommand};
1
+ import{initExtensionHandoff,initExtensionInstructions}from"./agent-instructions.js";import{tryInitializeGit}from"./init-git.js";import{mkdtemp,readdir,rename,rm,stat}from"node:fs/promises";import{createLogger,isLogLevelEnabled}from"#internal/logging.js";import{basename,join,resolve}from"node:path";import pc from"#compiled/picocolors/index.js";import{scaffoldExtensionProject}from"#setup/scaffold/index.js";import{packageManagerInstallFailureMessage,packageManagerInstallSucceeded,runPackageManagerInstall}from"#setup/primitives/index.js";import{performance}from"node:perf_hooks";import{isCodingAgentLaunch}from"#cli/agent-detection.js";import{EVE_WORDMARK}from"#cli/banner.js";import{formatElapsed}from"#cli/format-elapsed.js";import{startCliLiveRow}from"#cli/ui/live-row.js";import{formatNodeEngineOverrideWarning}from"#setup/node-engine.js";import{detectInvokingPackageManager,detectPackageManager}from"#setup/package-manager.js";import{pathExists}from"#setup/path-exists.js";import{parseProjectName}from"#setup/project-name.js";import{blockingCreateInPlaceEntries}from"#setup/scaffold/create-in-place.js";import{DEFAULT_EVE_PACKAGE_CONTRACT}from"#setup/scaffold/create/project.js";const defaultDependencies={detectInvokingPackageManager,detectPackageManager,isCodingAgentLaunch,now:()=>performance.now(),runPackageManagerInstall,scaffoldExtensionProject,tryInitializeGit},EVE_INIT_PACKAGE_SPEC_ENV=`EVE_INIT_PACKAGE_SPEC`,initLog=createLogger(`extension-init`);function isCurrentDirectoryTarget(e){return/^\.(?:[/\\]+\.?)*$/u.test(e.trim())}async function resolveTargetDirectory(e,t){let n=resolve(e,t);return(await stat(n).catch(()=>void 0))?.isDirectory()?n:void 0}async function assertCanScaffoldInPlace(e){let t=await readdir(e),n=blockingCreateInPlaceEntries(t);if(n.length===0)return;let r=n.slice(0,5).join(`, `),i=n.length>5?`, and ${n.length-5} more`:``;throw Error(`Cannot create project in current directory because it is not empty. Found: ${r}${i}. Use an empty directory.`)}async function moveDirectoryContents(e,t){for(let n of await readdir(e))await rename(join(e,n),join(t,n))}function uniqueWorkspaceRootMutations(e){let t=new Map;for(let n of e){let e=`${n.kind}:${n.path}`,r=t.get(e);t.set(e,{...n,nodeEngineOverride:n.nodeEngineOverride??r?.nodeEngineOverride})}return[...t.values()]}function formatWorkspaceRootMutationWarning(e){let t=e.kind===`package-json`?`package.json`:`configuration`,n=e.nodeEngineOverride===void 0?``:` (${formatNodeEngineOverrideWarning(e.nodeEngineOverride)})`;return`Updated workspace root ${t} at ${e.path}${n}`}async function resolveScaffoldPackageManager(e,t){let n=await t.detectPackageManager(e);return n.source==="default"?t.detectInvokingPackageManager()??`pnpm`:n.kind}async function scaffoldExtension(e,t,n,r,i){let a=resolve(e),o=t===`.`,s=o?a:join(a,t);if(o)await assertCanScaffoldInPlace(s);else if(await pathExists(s))throw Error(`Cannot create project because "${s}" already exists.`);let c=await mkdtemp(join(a,`.eve-extension-init-`)),l=[];try{let e=o?basename(s):t,a=await r.scaffoldExtensionProject({projectName:e,evePackage:i,targetDirectory:c,workspaceProbeDirectory:s,packageManager:n,onWorkspaceRootMutation:e=>{l.push(e)}});return o?await moveDirectoryContents(a,s):await rename(a,s),{projectPath:s,workspaceRootMutations:uniqueWorkspaceRootMutations(l)}}finally{await rm(c,{recursive:!0,force:!0})}}function installProgressDetail(e,t){let n=t.text.trim();if(n===``||e!==`npm`)return n||void 0;let r=/^npm silly fetch manifest (.+)$/u.exec(n);if(r!==null)return`Resolving ${r[1]}`;let i=/^npm http fetch \S+ \S+ attempt (\d+) failed with (\S+)$/u.exec(n);if(i!==null)return`npm registry · attempt ${i[1]} failed: ${i[2]}`;if(t.stream===`stdout`||/^npm (?:error|warn)\b/u.test(n))return n}const NPM_NOISE_LINE=/^\s*npm (?:silly|verbose|http|timing)\b/u;function resolveInitEvePackageOverride(){let e=process.env[EVE_INIT_PACKAGE_SPEC_ENV]?.trim();if(e!==void 0&&e.length!==0)return{nodeEngine:DEFAULT_EVE_PACKAGE_CONTRACT.nodeEngine,version:e}}async function runExtensionInitCommand(e,t,n,r=defaultDependencies,i){if(i?.(`resolve_target`),n===void 0&&await r.isCodingAgentLaunch()){e.log(initExtensionInstructions());return}let a=isLogLevelEnabled(`debug`),o=startCliLiveRow(e);o.update(`Preparing project`);let s,c,l=[],u,d,f;try{let p=n??`.`,m=isCurrentDirectoryTarget(p),h=m?await pathExists(join(resolve(t),`package.json`))?resolve(t):void 0:await resolveTargetDirectory(t,p),g=resolveInitEvePackageOverride();if(h!==void 0)throw Error("`eve extension init` creates a new extension package and cannot add to an existing project. Pass a new directory name, or run from an empty directory with `eve extension init .`.");i?.(`scaffold`),o.update(`Creating extension`),initLog.debug(`creating extension`);let _=r.now(),v=m?`.`:parseProjectName(p),y=resolve(t);c=await resolveScaffoldPackageManager(v===`.`?y:join(y,v),r);let b=await scaffoldExtension(t,v,c,r,g);s=b.projectPath,l=b.workspaceRootMutations,u=r.now()-_,initLog.debug(`creating extension done`,{ms:u}),i?.(`install_dependencies`),o.update(`Installing dependencies`,`${c} install`),initLog.debug(`installing dependencies with ${c}`);let x=r.now(),S=[],C=[],w=await r.runPackageManagerInstall(c,s,{progressDetails:process.stdout.isTTY===!0&&!a,onOutput:e=>{e.text.trim()!==``&&(C.push(e.text),C.length>20&&C.shift(),NPM_NOISE_LINE.test(e.text)||S.push(e.text)),a&&initLog.debug(e.text);let t=installProgressDetail(c,e);t!==void 0&&o.update(`Installing dependencies`,t)}});if(d=r.now()-x,!packageManagerInstallSucceeded(w)){initLog.debug(`dependency installation failed`,{ms:d}),o.stop();let t=S.length>0?S:C;for(let n of t)e.error(n);if(t.length===0){let t=packageManagerInstallFailureMessage(w);t!==void 0&&e.error(t)}throw Error(`Failed to install dependencies in "${s}".`)}initLog.debug(`dependencies installed`,{ms:d}),i?.(`initialize_git`),o.update(`Initializing Git repository`),initLog.debug(`initializing git repository`),f=await r.tryInitializeGit(s)}finally{o.stop()}i?.(`handoff`),e.log(`${pc.green(`✓`)} Created an ${EVE_WORDMARK} extension in ${pc.bold(s)} ${pc.dim(`in ${formatElapsed(u)}`)}`);for(let t of l)e.log(pc.yellow(`⚠ ${formatWorkspaceRootMutationWarning(t)}`));e.log(`${pc.green(`✓`)} Installed dependencies ${pc.dim(`in ${formatElapsed(d)}`)}`),f.kind===`failed`?e.error(pc.yellow(`Git initialization failed: ${f.reason}`)):f.kind===`initialized`&&e.log(`${pc.green(`✓`)} Initialized Git repository`),e.log(initExtensionHandoff({packageManager:c,packageName:basename(s),projectPath:s}))}export{EVE_INIT_PACKAGE_SPEC_ENV,runExtensionInitCommand};
@@ -1,4 +1,5 @@
1
1
  import { isCodingAgentLaunch } from "#cli/agent-detection.js";
2
+ import type { EveCliSetupStep, EveCliSetupTerminalResult } from "#cli/telemetry/index.js";
2
3
  import { detectInvokingPackageManager, detectPackageManager } from "#setup/package-manager.js";
3
4
  import { runPackageManagerInstall, spawnPackageManager } from "#setup/primitives/index.js";
4
5
  import { addAgentToProject } from "#setup/scaffold/create/add-to-project.js";
@@ -26,16 +27,4 @@ export interface InitCommandDependencies {
26
27
  validateModelSlug: typeof validateModelSlug;
27
28
  }
28
29
  export declare const EVE_INIT_PACKAGE_SPEC_ENV = "EVE_INIT_PACKAGE_SPEC";
29
- /**
30
- * Creates a new eve agent (`target` is a project name), or adds one to an
31
- * existing project (`target` is a directory), without external provisioning.
32
- * A fresh in-place scaffold asks whether to use the current directory or a new
33
- * subdirectory when the current directory is not empty. Coding-agent launches
34
- * must pass an explicit subdirectory instead.
35
- *
36
- * Runs launched by a coding agent get the dev command printed instead of
37
- * spawned after scaffolding, since the dev TUI would wedge the launching agent.
38
- *
39
- * For extension packages, use `eve extension init` instead.
40
- */
41
- export declare function runInitCommand(logger: InitCliLogger, parentDirectory: string, target: string | undefined, options: InitCommandOptions, dependencies?: InitCommandDependencies): Promise<void>;
30
+ export declare function runInitCommand(logger: InitCliLogger, parentDirectory: string, target: string | undefined, options: InitCommandOptions, dependencies?: InitCommandDependencies, trackStep?: (step: EveCliSetupStep) => void, trackTerminal?: (step: EveCliSetupStep, result: EveCliSetupTerminalResult) => void): Promise<void>;
@@ -1 +1 @@
1
- import{initAgentDevHandoff,initAgentReadySummary,initAgentReplPrompt}from"./agent-instructions.js";import{tryInitializeGit}from"./init-git.js";import{addAgentsToWorkspace,convertScaffoldToAgentWorkspace}from"./init-agent-workspace.js";import{confirmInitInNonEmptyDirectory}from"./init-confirm.js";import{cleanupFreshInitTarget,workspaceFailureNote}from"./init-recovery.js";import{selectInitHandoff,spawnCodingAgentRepl}from"./init-repl.js";import{resolveInitTarget}from"./init-target.js";import{mkdtemp,readdir,rename,rm}from"node:fs/promises";import{createLogger,isLogLevelEnabled}from"#internal/logging.js";import{basename,join,relative,resolve}from"node:path";import pc from"#compiled/picocolors/index.js";import{DEFAULT_AGENT_MODEL_ID}from"#shared/default-agent-model.js";import{ensureChannel,scaffoldBaseProject}from"#setup/scaffold/index.js";import{eveDevArguments,packageManagerInstallFailureMessage,packageManagerInstallSucceeded,resultSucceeded,runPackageManagerInstall,spawnPackageManager}from"#setup/primitives/index.js";import{performance}from"node:perf_hooks";import{isCodingAgentLaunch}from"#cli/agent-detection.js";import{EVE_WORDMARK}from"#cli/banner.js";import{formatElapsed}from"#cli/format-elapsed.js";import{startCliLiveRow}from"#cli/ui/live-row.js";import{formatNodeEngineOverrideWarning}from"#setup/node-engine.js";import{detectInvokingPackageManager,detectPackageManager}from"#setup/package-manager.js";import{pathExists}from"#setup/path-exists.js";import{DEFAULT_EVE_PACKAGE_CONTRACT}from"#setup/scaffold/create/project.js";import{validateModelSlug}from"#setup/flows/model-source-change.js";import{addAgentToProject}from"#setup/scaffold/create/add-to-project.js";import{WizardCancelledError}from"#setup/step.js";import{isPackageManagerWorkspaceMember}from"#setup/scaffold/workspace-root.js";const defaultDependencies={addAgentToProject,confirmInitInNonEmptyDirectory,detectInvokingPackageManager,detectPackageManager,ensureChannel,isCodingAgentLaunch,now:()=>performance.now(),runPackageManagerInstall,scaffoldBaseProject,selectInitHandoff,spawnCodingAgentRepl,spawnPackageManager,tryInitializeGit,validateModelSlug},EVE_INIT_PACKAGE_SPEC_ENV=`EVE_INIT_PACKAGE_SPEC`,initLog=createLogger(`init`);async function moveDirectoryContents(e,t){for(let n of await readdir(e))await rename(join(e,n),join(t,n))}function uniqueWorkspaceRootMutations(e){let t=new Map;for(let n of e){let e=`${n.kind}:${n.path}`,r=t.get(e);t.set(e,{...n,nodeEngineOverride:n.nodeEngineOverride??r?.nodeEngineOverride})}return[...t.values()]}function formatWorkspaceRootMutationWarning(e){let t=e.kind===`package-json`?`package.json`:`configuration`,n=e.nodeEngineOverride===void 0?``:` (${formatNodeEngineOverrideWarning(e.nodeEngineOverride)})`;return`Updated workspace root ${t} at ${e.path}${n}`}async function addToExistingProject(e,t,n,r){if(t.channelWebNextjs===!0)throw Error("`--channel-web-nextjs` is not supported when adding an agent to an existing project. Run `eve add channel/web` from the project afterwards instead.");if(t.model!==void 0){let r=await n.validateModelSlug(e,t.model);if(r!==null)throw Error(r)}let i=await n.detectPackageManager(e),a=await n.addAgentToProject({projectRoot:e,model:t.model??DEFAULT_AGENT_MODEL_ID,reasoning:t.reasoning,packageManager:i.kind,evePackage:r});return{configurationFilesChanged:a.configurationFilesChanged,dependenciesAdded:a.dependenciesAdded,filesWritten:a.filesWritten,packageManager:i.kind,nodeEngineOverride:a.nodeEngineOverride}}async function resolveScaffoldPackageManager(e,t){let n=await t.detectPackageManager(e);return n.source==="default"?t.detectInvokingPackageManager()??`pnpm`:n.kind}async function scaffoldProject(e,t,n,r,i,a,o,s){let c=resolve(e,`..`),l=!n&&await pathExists(e)&&(await readdir(e)).length===0;if(!n&&await pathExists(e)&&!l)throw Error(`Cannot create project because "${e}" already exists.`);let u=n&&s?void 0:await mkdtemp(join(c,`.eve-init-`)),d=[];try{let c=u??e;if(i.model!==void 0){let e=await a.validateModelSlug(c,i.model);if(e!==null)throw Error(e)}let f={projectName:u===void 0?`.`:n?basename(e):t,model:i.model??DEFAULT_AGENT_MODEL_ID,reasoning:i.reasoning,evePackage:o,targetDirectory:c,overwriteExisting:s,workspaceProbeDirectory:e,packageManager:r,onWorkspaceRootMutation:e=>{d.push(e)}},p=await a.scaffoldBaseProject(f);return i.agents!==void 0&&await convertScaffoldToAgentWorkspace(p,i.agents,i),i.channelWebNextjs===!0&&await a.ensureChannel({projectRoot:p,kind:`web`,packageManager:r,force:s,workspaceProbeDirectory:e,configureVercelServices:!1,onWorkspaceRootMutation:e=>{d.push(e)}}),u!==void 0&&(n||l?await moveDirectoryContents(p,e):await rename(p,e)),{projectPath:e,workspaceRootMutations:uniqueWorkspaceRootMutations(d)}}finally{u!==void 0&&await rm(u,{recursive:!0,force:!0})}}function installProgressDetail(e,t){let n=t.text.trim();if(n===``||e!==`npm`)return n||void 0;let r=/^npm silly fetch manifest (.+)$/u.exec(n);if(r!==null)return`Resolving ${r[1]}`;let i=/^npm http fetch \S+ \S+ attempt (\d+) failed with (\S+)$/u.exec(n);if(i!==null)return`npm registry · attempt ${i[1]} failed: ${i[2]}`;if(t.stream===`stdout`||/^npm (?:error|warn)\b/u.test(n))return n}const NPM_NOISE_LINE=/^\s*npm (?:silly|verbose|http|timing)\b/u;function reportExistingProjectChanges(e,t){e.log(`Updated existing project:`);for(let n of t.filesWritten)e.log(` Created ${relative(t.projectPath,n).replaceAll(`\\`,`/`)}`);t.dependenciesAdded.length>0&&e.log(` Added dependencies: ${t.dependenciesAdded.join(`, `)}`);for(let n of t.configurationFilesChanged)e.log(` Updated ${n}`);t.nodeEngineOverride!==void 0&&e.log(pc.yellow(` ⚠ ${formatNodeEngineOverrideWarning(t.nodeEngineOverride)}`))}async function runInitSteps(e){let{dependencies:t,logger:n,options:r,parentDirectory:i,target:a}=e,o=isLogLevelEnabled(`debug`),s=await t.isCodingAgentLaunch(),c=await resolveInitTarget({parentDirectory:i,target:a}),l=resolveInitEvePackageOverride(),u=startCliLiveRow(n);u.update(`Preparing project`);try{let e=c.kind===`fresh`?`creating agent`:`adding agent`;u.update(c.kind===`fresh`?`Creating agent`:`Adding agent`),initLog.debug(e);let i=t.now(),a;if(c.kind===`fresh`){let e=await resolveScaffoldPackageManager(c.projectPath,t),n=isPackageManagerWorkspaceMember(e,c.projectPath),i;try{i=await scaffoldProject(c.projectPath,c.projectName,c.createInPlace,e,r,t,l,c.overwriteExisting)}catch(e){if(c.failurePolicy===`clear`){let t=await cleanupFreshInitTarget(c.projectPath,c.failurePolicy,c.preservedEntries),r=e instanceof Error?e.message:String(e),i=t?`eve restored "${c.projectPath}" to its original state.`:`eve could not completely clean "${c.projectPath}".`;throw Error(`${r}\n\n${i}${workspaceFailureNote(n)}`)}if(c.failurePolicy===`remove`&&n){let t=e instanceof Error?e.message:String(e);throw Error(`${t}${workspaceFailureNote(!0)}`)}throw e}a={failurePolicy:c.failurePolicy,kind:`created`,packageManager:e,preservedTargetEntries:c.preservedEntries,projectPath:i.projectPath,retryCommand:`eve init ${c.projectPath}`,workspaceMember:n,workspaceRootMutations:i.workspaceRootMutations}}else{let e=await addToExistingProject(c.projectPath,r,t,l);a=e.nodeEngineOverride===void 0?{configurationFilesChanged:e.configurationFilesChanged,dependenciesAdded:e.dependenciesAdded,failurePolicy:`preserve`,filesWritten:e.filesWritten,kind:`added`,packageManager:e.packageManager,projectPath:c.projectPath}:{configurationFilesChanged:e.configurationFilesChanged,dependenciesAdded:e.dependenciesAdded,failurePolicy:`preserve`,filesWritten:e.filesWritten,kind:`added`,nodeEngineOverride:e.nodeEngineOverride,packageManager:e.packageManager,projectPath:c.projectPath}}let d=t.now()-i;initLog.debug(`${e} done`,{ms:d}),a.kind===`added`&&(u.stop(),reportExistingProjectChanges(n,a),u=startCliLiveRow(n)),u.update(`Installing dependencies`,`${a.packageManager} install`),initLog.debug(`installing dependencies with ${a.packageManager}`);let f=t.now(),p=[],m=[],h=await t.runPackageManagerInstall(a.packageManager,a.projectPath,{progressDetails:process.stdout.isTTY===!0&&!o,onOutput:e=>{e.text.trim()!==``&&(m.push(e.text),m.length>20&&m.shift(),NPM_NOISE_LINE.test(e.text)||p.push(e.text)),o&&initLog.debug(e.text);let t=installProgressDetail(a.packageManager,e);t!==void 0&&u.update(`Installing dependencies`,t)}}),g=t.now()-f;if(!packageManagerInstallSucceeded(h)){initLog.debug(`dependency installation failed`,{ms:g}),u.stop();let e=p.length>0?p:m;for(let t of e)n.error(t);if(e.length===0){let e=packageManagerInstallFailureMessage(h);e!==void 0&&n.error(e)}if(a.failurePolicy!==`preserve`){if(await cleanupFreshInitTarget(a.projectPath,a.failurePolicy,a.preservedTargetEntries)){let e=a.failurePolicy===`remove`?`eve removed the incomplete project at "${a.projectPath}".`:`eve restored "${a.projectPath}" to its original state.`,t=a.workspaceMember||a.workspaceRootMutations.length>0;throw Error(`Failed to install dependencies.\n\n${e}\n\nResolve the package-manager error above, then retry:\n ${a.retryCommand}${workspaceFailureNote(t)}`)}let e=a.workspaceMember||a.workspaceRootMutations.length>0;throw Error(`Failed to install dependencies, and eve could not completely clean "${a.projectPath}".\n\nResolve the package-manager error above, then install dependencies with ${a.packageManager} in that directory. Or clean the target manually before rerunning eve init.${workspaceFailureNote(e)}`)}throw Error(`The eve agent was added, but dependency installation failed.\n\nResolve the package-manager error above, then install dependencies with ${a.packageManager} in "${a.projectPath}".\n\nDo not rerun eve init; the agent is already configured.`)}return initLog.debug(`dependencies installed`,{ms:g}),a.kind===`created`?(u.update(`Initializing Git repository`),initLog.debug(`initializing git repository`),{...a,agentElapsedMs:d,agentLaunched:s,gitResult:await t.tryInitializeGit(a.projectPath),installElapsedMs:g}):{...a,agentElapsedMs:d,agentLaunched:s,installElapsedMs:g}}finally{u.stop()}}async function runInitCommand(e,t,n,r,i=defaultDependencies){if(await addAgentsToWorkspace(e,t,n,r,i.validateModelSlug))return;let a;try{a=await runInitSteps({dependencies:i,logger:e,options:r,parentDirectory:t,target:n})}catch(e){if(e instanceof WizardCancelledError)return;throw e}if(a.kind===`created`){e.log(`${pc.green(`✓`)} Created an ${EVE_WORDMARK} agent in ${pc.bold(a.projectPath)} ${pc.dim(`in ${formatElapsed(a.agentElapsedMs)}`)}`);for(let t of a.workspaceRootMutations)e.log(pc.yellow(`⚠ ${formatWorkspaceRootMutationWarning(t)}`))}else e.log(`${pc.green(`✓`)} Added an ${EVE_WORDMARK} agent to ${pc.bold(a.projectPath)} ${pc.dim(`in ${formatElapsed(a.agentElapsedMs)}`)}`);e.log(`${pc.green(`✓`)} Installed dependencies ${pc.dim(`in ${formatElapsed(a.installElapsedMs)}`)}`),a.kind===`created`&&a.gitResult.kind===`failed`&&(e.error(pc.yellow(`Git initialization failed during ${a.gitResult.stage}: ${a.gitResult.reason}`)),a.gitResult.stage===`commit`&&e.error(pc.yellow(`The eve agent was created successfully. Git repository metadata and staged files were preserved at "${a.projectPath}"; the initial commit is optional.\n\nTo create it later, configure Git identity and run:\n git -C ${JSON.stringify(a.projectPath)} commit -m "Initial commit from eve"`)));let o=eveDevArguments(a.packageManager),s=[a.packageManager,...o].join(` `),c=initAgentDevHandoff({projectPath:a.projectPath,devCommand:s});if(a.agentLaunched){e.log(initAgentReadySummary(r.model,a.projectPath,{workspace:r.agents!==void 0})),e.log(c);return}let l;try{l=await i.selectInitHandoff({agentName:basename(a.projectPath)})}catch(e){if(e instanceof WizardCancelledError)return;throw e}if(l===`exit`)return;if(l!==`eve-dev`){if(e.log(pc.dim(`$ ${l}`)),!await i.spawnCodingAgentRepl({command:l,cwd:a.projectPath,prompt:initAgentReplPrompt({devCommand:s}),onPromptUnseeded:t=>{e.log(pc.yellow(`Could not seed ${l} automatically. Paste this prompt into it:`)),e.log(t)}}))throw Error(`Coding-agent REPL exited unsuccessfully in "${a.projectPath}".`);return}let u=a.kind===`created`?[...o,`--onboard`]:o;if(e.log(pc.dim(`$ eve dev`)),!resultSucceeded(await i.spawnPackageManager(a.packageManager,a.projectPath,u)))throw Error(`Development server exited unsuccessfully in "${a.projectPath}".`)}function resolveInitEvePackageOverride(){let e=process.env[EVE_INIT_PACKAGE_SPEC_ENV]?.trim();if(e!==void 0&&e.length!==0)return{nodeEngine:DEFAULT_EVE_PACKAGE_CONTRACT.nodeEngine,version:e}}export{EVE_INIT_PACKAGE_SPEC_ENV,runInitCommand};
1
+ import{initAgentDevHandoff,initAgentReadySummary,initAgentReplPrompt}from"./agent-instructions.js";import{tryInitializeGit}from"./init-git.js";import{addAgentsToWorkspace,convertScaffoldToAgentWorkspace}from"./init-agent-workspace.js";import{confirmInitInNonEmptyDirectory}from"./init-confirm.js";import{cleanupFreshInitTarget,workspaceFailureNote}from"./init-recovery.js";import{selectInitHandoff,spawnCodingAgentRepl}from"./init-repl.js";import{resolveInitTarget}from"./init-target.js";import{mkdtemp,readdir,rename,rm}from"node:fs/promises";import{createLogger,isLogLevelEnabled}from"#internal/logging.js";import{basename,join,relative,resolve}from"node:path";import pc from"#compiled/picocolors/index.js";import{DEFAULT_AGENT_MODEL_ID}from"#shared/default-agent-model.js";import{ensureChannel,scaffoldBaseProject}from"#setup/scaffold/index.js";import{eveDevArguments,packageManagerInstallFailureMessage,packageManagerInstallSucceeded,resultSucceeded,runPackageManagerInstall,spawnPackageManager}from"#setup/primitives/index.js";import{performance}from"node:perf_hooks";import{isCodingAgentLaunch}from"#cli/agent-detection.js";import{EVE_WORDMARK}from"#cli/banner.js";import{formatElapsed}from"#cli/format-elapsed.js";import{startCliLiveRow}from"#cli/ui/live-row.js";import{formatNodeEngineOverrideWarning}from"#setup/node-engine.js";import{detectInvokingPackageManager,detectPackageManager}from"#setup/package-manager.js";import{pathExists}from"#setup/path-exists.js";import{DEFAULT_EVE_PACKAGE_CONTRACT}from"#setup/scaffold/create/project.js";import{validateModelSlug}from"#setup/flows/model-source-change.js";import{addAgentToProject}from"#setup/scaffold/create/add-to-project.js";import{WizardCancelledError}from"#setup/step.js";import{isPackageManagerWorkspaceMember}from"#setup/scaffold/workspace-root.js";const defaultDependencies={addAgentToProject,confirmInitInNonEmptyDirectory,detectInvokingPackageManager,detectPackageManager,ensureChannel,isCodingAgentLaunch,now:()=>performance.now(),runPackageManagerInstall,scaffoldBaseProject,selectInitHandoff,spawnCodingAgentRepl,spawnPackageManager,tryInitializeGit,validateModelSlug},EVE_INIT_PACKAGE_SPEC_ENV=`EVE_INIT_PACKAGE_SPEC`,initLog=createLogger(`init`);async function moveDirectoryContents(e,t){for(let n of await readdir(e))await rename(join(e,n),join(t,n))}function uniqueWorkspaceRootMutations(e){let t=new Map;for(let n of e){let e=`${n.kind}:${n.path}`,r=t.get(e);t.set(e,{...n,nodeEngineOverride:n.nodeEngineOverride??r?.nodeEngineOverride})}return[...t.values()]}function formatWorkspaceRootMutationWarning(e){let t=e.kind===`package-json`?`package.json`:`configuration`,n=e.nodeEngineOverride===void 0?``:` (${formatNodeEngineOverrideWarning(e.nodeEngineOverride)})`;return`Updated workspace root ${t} at ${e.path}${n}`}async function addToExistingProject(e,t,n,r){if(t.channelWebNextjs===!0)throw Error("`--channel-web-nextjs` is not supported when adding an agent to an existing project. Run `eve add channel/web` from the project afterwards instead.");if(t.model!==void 0){let r=await n.validateModelSlug(e,t.model);if(r!==null)throw Error(r)}let i=await n.detectPackageManager(e),a=await n.addAgentToProject({projectRoot:e,model:t.model??DEFAULT_AGENT_MODEL_ID,reasoning:t.reasoning,packageManager:i.kind,evePackage:r});return{configurationFilesChanged:a.configurationFilesChanged,dependenciesAdded:a.dependenciesAdded,filesWritten:a.filesWritten,packageManager:i.kind,nodeEngineOverride:a.nodeEngineOverride}}async function resolveScaffoldPackageManager(e,t){let n=await t.detectPackageManager(e);return n.source==="default"?t.detectInvokingPackageManager()??`pnpm`:n.kind}async function scaffoldProject(e,t,n,r,i,a,o,s){let c=resolve(e,`..`),l=!n&&await pathExists(e)&&(await readdir(e)).length===0;if(!n&&await pathExists(e)&&!l)throw Error(`Cannot create project because "${e}" already exists.`);let u=n&&s?void 0:await mkdtemp(join(c,`.eve-init-`)),d=[];try{let c=u??e;if(i.model!==void 0){let e=await a.validateModelSlug(c,i.model);if(e!==null)throw Error(e)}let f={projectName:u===void 0?`.`:n?basename(e):t,model:i.model??DEFAULT_AGENT_MODEL_ID,reasoning:i.reasoning,evePackage:o,targetDirectory:c,overwriteExisting:s,workspaceProbeDirectory:e,packageManager:r,onWorkspaceRootMutation:e=>{d.push(e)}},p=await a.scaffoldBaseProject(f);return i.agents!==void 0&&await convertScaffoldToAgentWorkspace(p,i.agents,i),i.channelWebNextjs===!0&&await a.ensureChannel({projectRoot:p,kind:`web`,packageManager:r,force:s,workspaceProbeDirectory:e,configureVercelServices:!1,onWorkspaceRootMutation:e=>{d.push(e)}}),u!==void 0&&(n||l?await moveDirectoryContents(p,e):await rename(p,e)),{projectPath:e,workspaceRootMutations:uniqueWorkspaceRootMutations(d)}}finally{u!==void 0&&await rm(u,{recursive:!0,force:!0})}}function installProgressDetail(e,t){let n=t.text.trim();if(n===``||e!==`npm`)return n||void 0;let r=/^npm silly fetch manifest (.+)$/u.exec(n);if(r!==null)return`Resolving ${r[1]}`;let i=/^npm http fetch \S+ \S+ attempt (\d+) failed with (\S+)$/u.exec(n);if(i!==null)return`npm registry · attempt ${i[1]} failed: ${i[2]}`;if(t.stream===`stdout`||/^npm (?:error|warn)\b/u.test(n))return n}const NPM_NOISE_LINE=/^\s*npm (?:silly|verbose|http|timing)\b/u;function reportExistingProjectChanges(e,t){e.log(`Updated existing project:`);for(let n of t.filesWritten)e.log(` Created ${relative(t.projectPath,n).replaceAll(`\\`,`/`)}`);t.dependenciesAdded.length>0&&e.log(` Added dependencies: ${t.dependenciesAdded.join(`, `)}`);for(let n of t.configurationFilesChanged)e.log(` Updated ${n}`);t.nodeEngineOverride!==void 0&&e.log(pc.yellow(` ⚠ ${formatNodeEngineOverrideWarning(t.nodeEngineOverride)}`))}async function runInitSteps(e){let{dependencies:t,logger:n,options:r,parentDirectory:i,target:a,trackStep:o}=e,s=isLogLevelEnabled(`debug`),c=await t.isCodingAgentLaunch(),l=await resolveInitTarget({parentDirectory:i,target:a}),u=resolveInitEvePackageOverride(),d=startCliLiveRow(n);d.update(`Preparing project`);try{let e=l.kind===`fresh`?`creating agent`:`adding agent`;o?.(`scaffold`),d.update(l.kind===`fresh`?`Creating agent`:`Adding agent`),initLog.debug(e);let i=t.now(),a;if(l.kind===`fresh`){let e=await resolveScaffoldPackageManager(l.projectPath,t),n=isPackageManagerWorkspaceMember(e,l.projectPath),i;try{i=await scaffoldProject(l.projectPath,l.projectName,l.createInPlace,e,r,t,u,l.overwriteExisting)}catch(e){if(l.failurePolicy===`clear`){let t=await cleanupFreshInitTarget(l.projectPath,l.failurePolicy,l.preservedEntries),r=e instanceof Error?e.message:String(e),i=t?`eve restored "${l.projectPath}" to its original state.`:`eve could not completely clean "${l.projectPath}".`;throw Error(`${r}\n\n${i}${workspaceFailureNote(n)}`)}if(l.failurePolicy===`remove`&&n){let t=e instanceof Error?e.message:String(e);throw Error(`${t}${workspaceFailureNote(!0)}`)}throw e}a={failurePolicy:l.failurePolicy,kind:`created`,packageManager:e,preservedTargetEntries:l.preservedEntries,projectPath:i.projectPath,retryCommand:`eve init ${l.projectPath}`,workspaceMember:n,workspaceRootMutations:i.workspaceRootMutations}}else{let e=await addToExistingProject(l.projectPath,r,t,u);a=e.nodeEngineOverride===void 0?{configurationFilesChanged:e.configurationFilesChanged,dependenciesAdded:e.dependenciesAdded,failurePolicy:`preserve`,filesWritten:e.filesWritten,kind:`added`,packageManager:e.packageManager,projectPath:l.projectPath}:{configurationFilesChanged:e.configurationFilesChanged,dependenciesAdded:e.dependenciesAdded,failurePolicy:`preserve`,filesWritten:e.filesWritten,kind:`added`,nodeEngineOverride:e.nodeEngineOverride,packageManager:e.packageManager,projectPath:l.projectPath}}let f=t.now()-i;initLog.debug(`${e} done`,{ms:f}),a.kind===`added`&&(d.stop(),reportExistingProjectChanges(n,a),d=startCliLiveRow(n)),o?.(`install_dependencies`),d.update(`Installing dependencies`,`${a.packageManager} install`),initLog.debug(`installing dependencies with ${a.packageManager}`);let p=t.now(),m=[],h=[],g=await t.runPackageManagerInstall(a.packageManager,a.projectPath,{progressDetails:process.stdout.isTTY===!0&&!s,onOutput:e=>{e.text.trim()!==``&&(h.push(e.text),h.length>20&&h.shift(),NPM_NOISE_LINE.test(e.text)||m.push(e.text)),s&&initLog.debug(e.text);let t=installProgressDetail(a.packageManager,e);t!==void 0&&d.update(`Installing dependencies`,t)}}),_=t.now()-p;if(!packageManagerInstallSucceeded(g)){initLog.debug(`dependency installation failed`,{ms:_}),d.stop();let e=m.length>0?m:h;for(let t of e)n.error(t);if(e.length===0){let e=packageManagerInstallFailureMessage(g);e!==void 0&&n.error(e)}if(a.failurePolicy!==`preserve`){if(await cleanupFreshInitTarget(a.projectPath,a.failurePolicy,a.preservedTargetEntries)){let e=a.failurePolicy===`remove`?`eve removed the incomplete project at "${a.projectPath}".`:`eve restored "${a.projectPath}" to its original state.`,t=a.workspaceMember||a.workspaceRootMutations.length>0;throw Error(`Failed to install dependencies.\n\n${e}\n\nResolve the package-manager error above, then retry:\n ${a.retryCommand}${workspaceFailureNote(t)}`)}let e=a.workspaceMember||a.workspaceRootMutations.length>0;throw Error(`Failed to install dependencies, and eve could not completely clean "${a.projectPath}".\n\nResolve the package-manager error above, then install dependencies with ${a.packageManager} in that directory. Or clean the target manually before rerunning eve init.${workspaceFailureNote(e)}`)}throw Error(`The eve agent was added, but dependency installation failed.\n\nResolve the package-manager error above, then install dependencies with ${a.packageManager} in "${a.projectPath}".\n\nDo not rerun eve init; the agent is already configured.`)}return initLog.debug(`dependencies installed`,{ms:_}),a.kind===`created`?(o?.(`initialize_git`),d.update(`Initializing Git repository`),initLog.debug(`initializing git repository`),{...a,agentElapsedMs:f,agentLaunched:c,gitResult:await t.tryInitializeGit(a.projectPath),installElapsedMs:_}):{...a,agentElapsedMs:f,agentLaunched:c,installElapsedMs:_}}finally{d.stop()}}async function runInitCommand(e,t,n,r,i=defaultDependencies,a,o){if(a?.(`resolve_target`),await addAgentsToWorkspace(e,t,n,r,i.validateModelSlug)){a?.(`handoff`),o?.(`handoff`,`completed`);return}let s;try{s=await runInitSteps({dependencies:i,logger:e,options:r,parentDirectory:t,target:n,trackStep:a})}catch(e){if(e instanceof WizardCancelledError){o?.(`resolve_target`,`cancelled`);return}throw e}if(a?.(`handoff`),s.kind===`created`){e.log(`${pc.green(`✓`)} Created an ${EVE_WORDMARK} agent in ${pc.bold(s.projectPath)} ${pc.dim(`in ${formatElapsed(s.agentElapsedMs)}`)}`);for(let t of s.workspaceRootMutations)e.log(pc.yellow(`⚠ ${formatWorkspaceRootMutationWarning(t)}`))}else e.log(`${pc.green(`✓`)} Added an ${EVE_WORDMARK} agent to ${pc.bold(s.projectPath)} ${pc.dim(`in ${formatElapsed(s.agentElapsedMs)}`)}`);e.log(`${pc.green(`✓`)} Installed dependencies ${pc.dim(`in ${formatElapsed(s.installElapsedMs)}`)}`),s.kind===`created`&&s.gitResult.kind===`failed`&&(e.error(pc.yellow(`Git initialization failed during ${s.gitResult.stage}: ${s.gitResult.reason}`)),s.gitResult.stage===`commit`&&e.error(pc.yellow(`The eve agent was created successfully. Git repository metadata and staged files were preserved at "${s.projectPath}"; the initial commit is optional.\n\nTo create it later, configure Git identity and run:\n git -C ${JSON.stringify(s.projectPath)} commit -m "Initial commit from eve"`)));let c=eveDevArguments(s.packageManager),l=[s.packageManager,...c].join(` `),u=initAgentDevHandoff({projectPath:s.projectPath,devCommand:l});if(s.agentLaunched){e.log(initAgentReadySummary(r.model,s.projectPath,{workspace:r.agents!==void 0})),e.log(u);return}let d;try{d=await i.selectInitHandoff({agentName:basename(s.projectPath)})}catch(e){if(e instanceof WizardCancelledError)return;throw e}if(d===`exit`)return;if(d!==`eve-dev`){if(e.log(pc.dim(`$ ${d}`)),!await i.spawnCodingAgentRepl({command:d,cwd:s.projectPath,prompt:initAgentReplPrompt({devCommand:l}),onPromptUnseeded:t=>{e.log(pc.yellow(`Could not seed ${d} automatically. Paste this prompt into it:`)),e.log(t)}}))throw Error(`Coding-agent REPL exited unsuccessfully in "${s.projectPath}".`);return}let f=s.kind===`created`?[...c,`--onboard`]:c;if(e.log(pc.dim(`$ eve dev`)),!resultSucceeded(await i.spawnPackageManager(s.packageManager,s.projectPath,f)))throw Error(`Development server exited unsuccessfully in "${s.projectPath}".`)}function resolveInitEvePackageOverride(){let e=process.env[EVE_INIT_PACKAGE_SPEC_ENV]?.trim();if(e!==void 0&&e.length!==0)return{nodeEngine:DEFAULT_EVE_PACKAGE_CONTRACT.nodeEngine,version:e}}export{EVE_INIT_PACKAGE_SPEC_ENV,runInitCommand};
@@ -1,4 +1,5 @@
1
1
  import { type DevBootProgressReporter } from "#internal/dev-boot-progress.js";
2
+ import type { EveCliSetupStepEvent, EveCliSetupTerminalEvent } from "#cli/telemetry/index.js";
2
3
  import type { DevelopmentCliOptions } from "./command-options.js";
3
4
  import type { DevelopmentTuiStartup, RunDevelopmentTuiInput } from "./tui/tui.js";
4
5
  import type { DevelopmentUrlTarget } from "./url-target.js";
@@ -11,6 +12,8 @@ export declare function runInteractiveDevelopmentUi(input: {
11
12
  readonly remoteTarget?: DevelopmentUrlTarget;
12
13
  readonly report?: DevBootProgressReporter;
13
14
  readonly runDevelopmentTui?: (input: RunDevelopmentTuiInput) => Promise<void>;
15
+ readonly onOnboardingStep?: (input: EveCliSetupStepEvent) => void;
16
+ readonly onOnboardingTerminal?: (input: EveCliSetupTerminalEvent) => void;
14
17
  readonly server: {
15
18
  readonly appRoot?: string;
16
19
  readonly serverUrl: string;
@@ -1 +1 @@
1
- import{resolveTuiDisplayOptions}from"./ui-options.js";import{resolveTuiTitle}from"./tui/target.js";import{randomUUID}from"node:crypto";import{findEveProjectContext}from"#internal/project-context.js";import{devBootPhase}from"#internal/dev-boot-progress.js";import{resumeDevelopmentRuntimeArtifacts,suspendDevelopmentRuntimeArtifacts}from"#services/dev-client/runtime-artifacts.js";async function runInteractiveDevelopmentUi(e){let t=await devBootPhase(`loading interactive UI`,async()=>e.runDevelopmentTui??(await import(`#cli/dev/tui/tui.js`)).runDevelopmentTui,e.report),n=e.server.appRoot??e.applicationRoot,r=await findEveProjectContext(n),i=r?.environmentRoot??n,a=r?.kind===`workspace-member`?r.member.appRoot:void 0,o=e.remoteTarget===void 0||e.existingLocalServer?{kind:`local`,serverUrl:e.server.serverUrl,workspaceRoot:i,agentRoot:a}:{kind:`remote`,serverUrl:e.server.serverUrl,workspaceRoot:i,agentRoot:a},s=resolveTuiDisplayOptions(e.options),c=resolveTuiTitle({name:e.options.name,target:o});c!==void 0&&(s.name=c);let l={target:o,initialInput:e.options.input,onboard:e.options.onboard,onBootProgress:e.report,lifecycle:e.lifecycle,...s};e.startup!==void 0&&(l.startup=e.startup),o.kind===`local`&&(l.withExclusiveTerminal=async t=>{let n=randomUUID();if(!await suspendDevelopmentRuntimeArtifacts({leaseId:n,serverUrl:e.server.serverUrl}))throw Error(`Could not pause the development server for integration setup.`);let r;try{r={ok:!0,value:await t()}}catch(e){r={error:e,ok:!1}}let i={leaseId:n,serverUrl:e.server.serverUrl,silent:!0};if(await resumeDevelopmentRuntimeArtifacts(i)===void 0&&await resumeDevelopmentRuntimeArtifacts(i)===void 0)throw Error(`Could not resume the eve development server after integration setup. Restart eve dev before making further source changes.`,r.ok?void 0:{cause:r.error});if(!r.ok)throw r.error;return r.value}),e.remoteTarget?.headers===void 0?await t(l):await t({...l,headers:e.remoteTarget.headers})}export{runInteractiveDevelopmentUi};
1
+ import{resolveTuiDisplayOptions}from"./ui-options.js";import{resolveTuiTitle}from"./tui/target.js";import{randomUUID}from"node:crypto";import{findEveProjectContext}from"#internal/project-context.js";import{devBootPhase}from"#internal/dev-boot-progress.js";import{resumeDevelopmentRuntimeArtifacts,suspendDevelopmentRuntimeArtifacts}from"#services/dev-client/runtime-artifacts.js";async function runInteractiveDevelopmentUi(e){let t=await devBootPhase(`loading interactive UI`,async()=>e.runDevelopmentTui??(await import(`#cli/dev/tui/tui.js`)).runDevelopmentTui,e.report),n=e.server.appRoot??e.applicationRoot,r=await findEveProjectContext(n),i=r?.environmentRoot??n,a=r?.kind===`workspace-member`?r.member.appRoot:void 0,o=e.remoteTarget===void 0||e.existingLocalServer?{kind:`local`,serverUrl:e.server.serverUrl,workspaceRoot:i,agentRoot:a}:{kind:`remote`,serverUrl:e.server.serverUrl,workspaceRoot:i,agentRoot:a},s=resolveTuiDisplayOptions(e.options),c=resolveTuiTitle({name:e.options.name,target:o});c!==void 0&&(s.name=c);let l={target:o,initialInput:e.options.input,onboard:e.options.onboard,onBootProgress:e.report,onOnboardingStep:e.onOnboardingStep,onOnboardingTerminal:e.onOnboardingTerminal,lifecycle:e.lifecycle,...s};e.startup!==void 0&&(l.startup=e.startup),o.kind===`local`&&(l.withExclusiveTerminal=async t=>{let n=randomUUID();if(!await suspendDevelopmentRuntimeArtifacts({leaseId:n,serverUrl:e.server.serverUrl}))throw Error(`Could not pause the development server for integration setup.`);let r;try{r={ok:!0,value:await t()}}catch(e){r={error:e,ok:!1}}let i={leaseId:n,serverUrl:e.server.serverUrl,silent:!0};if(await resumeDevelopmentRuntimeArtifacts(i)===void 0&&await resumeDevelopmentRuntimeArtifacts(i)===void 0)throw Error(`Could not resume the eve development server after integration setup. Restart eve dev before making further source changes.`,r.ok?void 0:{cause:r.error});if(!r.ok)throw r.error;return r.value}),e.remoteTarget?.headers===void 0?await t(l):await t({...l,headers:e.remoteTarget.headers})}export{runInteractiveDevelopmentUi};
@@ -1 +1 @@
1
- import{isPromptCommandAvailableFor}from"./prompt-commands.js";import{toErrorMessage}from"#shared/errors.js";function createPromptCommandHandler(e){return{async handle(t,n){let{target:r}=e;if(r.kind===`remote`&&!isPromptCommandAvailableFor(t.name,`remote`))return{message:`/${t.name} needs eve dev running the local server (it is not available with --url).`};if(t.name===`model`&&t.argument.length>0){if(r.kind!==`local`)return{message:`/model needs eve dev running the local server (it is not available with --url).`};let n=r.agentRoot??r.workspaceRoot;try{let{modelChangeRefusalForUneditableModel:r}=await import(`#setup/flows/model.js`),{changeAgentModel:i,formatApplyModelOutcome:a}=await import(`#setup/flows/model-source-change.js`),o=await(e.modelChangeRefusal??r)(n);return o===null?{message:a(await(e.applyModel??i)({appRoot:n,slug:t.argument}))}:{message:o}}catch(e){return{message:`Couldn't change the model: ${toErrorMessage(e)}`}}}let i=n.renderer.setupFlow;if(i===void 0)return{message:`/${t.name} is not supported by this renderer.`};if(t.name===`vc:login`&&r.kind===`remote`){if(n.remoteConnection===void 0)return{message:`/vc:login is not available in this session.`};let t;try{({runRemoteAuthCommand:t}=await import(`./remote-auth-command.js`))}catch(e){return{message:`/vc:login failed: ${toErrorMessage(e)}`}}return{message:await t({connection:n.remoteConnection,flow:e.remoteAuthFlow,renderer:i})}}let a;try{a=await import(`./setup-commands.js`)}catch(e){return{message:`/${t.name} failed: ${toErrorMessage(e)}`}}let{runTuiSetupCommand:o,SETUP_FLOW_CONFIG:s}=a,c=s[t.name];i.begin(n.setupFlowTitle??c.title,c.indicator),i.setNavigation?.(n.setupFlowNavigation);let l=!0;try{let a={command:t.name,appRoot:r.workspaceRoot,renderer:i,withExclusiveTerminal:n.withExclusiveTerminal,chatGptAccountLabel:n.chatGptAccountLabel};r.agentRoot!==void 0&&(a.agentRoot=r.agentRoot),n.initialModelStep!==void 0&&(a.initialModelStep=n.initialModelStep),n.registryPlannerContext!==void 0&&(a.registryPlannerContext=n.registryPlannerContext),t.name===`add`&&t.argument.length>0&&(a.initialRegistryAddress=t.argument),e.flows!==void 0&&(a.flows=e.flows);let s=await o(a);l=s.preserveFlowDiagnostics;let{preserveFlowDiagnostics:c,partial:u,...d}=s;return d}finally{n.keepSetupFlowOpen!==!0&&i.end({preserveDiagnostics:l})}}}}export{createPromptCommandHandler};
1
+ import{isPromptCommandAvailableFor}from"./prompt-commands.js";import{toErrorMessage}from"#shared/errors.js";function createPromptCommandHandler(e){return{async handle(t,n){let{target:r}=e;if(r.kind===`remote`&&!isPromptCommandAvailableFor(t.name,`remote`))return{message:`/${t.name} needs eve dev running the local server (it is not available with --url).`};if(t.name===`model`&&t.argument.length>0){if(r.kind!==`local`)return{message:`/model needs eve dev running the local server (it is not available with --url).`};let n=r.agentRoot??r.workspaceRoot;try{let{modelChangeRefusalForUneditableModel:r}=await import(`#setup/flows/model.js`),{changeAgentModel:i,formatApplyModelOutcome:a}=await import(`#setup/flows/model-source-change.js`),o=await(e.modelChangeRefusal??r)(n);return o===null?{message:a(await(e.applyModel??i)({appRoot:n,slug:t.argument}))}:{message:o}}catch(e){return{message:`Couldn't change the model: ${toErrorMessage(e)}`}}}let i=n.renderer.setupFlow;if(i===void 0)return{message:`/${t.name} is not supported by this renderer.`};if(t.name===`vc:login`&&r.kind===`remote`){if(n.remoteConnection===void 0)return{message:`/vc:login is not available in this session.`};let t;try{({runRemoteAuthCommand:t}=await import(`./remote-auth-command.js`))}catch(e){return{message:`/vc:login failed: ${toErrorMessage(e)}`}}return{message:await t({connection:n.remoteConnection,flow:e.remoteAuthFlow,renderer:i})}}let a;try{a=await import(`./setup-commands.js`)}catch(e){return{message:`/${t.name} failed: ${toErrorMessage(e)}`}}let{runTuiSetupCommand:o,SETUP_FLOW_CONFIG:s}=a,c=s[t.name];i.begin(n.setupFlowTitle??c.title,c.indicator),i.setNavigation?.(n.setupFlowNavigation);let l=!0;try{let a={command:t.name,appRoot:r.workspaceRoot,renderer:i,withExclusiveTerminal:n.withExclusiveTerminal,chatGptAccountLabel:n.chatGptAccountLabel};r.agentRoot!==void 0&&(a.agentRoot=r.agentRoot),n.initialModelStep!==void 0&&(a.initialModelStep=n.initialModelStep),n.registryPlannerContext!==void 0&&(a.registryPlannerContext=n.registryPlannerContext),n.onOnboardingScreen!==void 0&&(a.onOnboardingScreen=n.onOnboardingScreen),t.name===`add`&&t.argument.length>0&&(a.initialRegistryAddress=t.argument),e.flows!==void 0&&(a.flows=e.flows);let s=await o(a);l=s.preserveFlowDiagnostics;let{preserveFlowDiagnostics:c,partial:u,...d}=s;return d}finally{n.keepSetupFlowOpen!==!0&&i.end({preserveDiagnostics:l})}}}}export{createPromptCommandHandler};
@@ -1,4 +1,6 @@
1
1
  import { type AgentInfoResult, type ConnectionAuthorizationOutcome, type InputRequest, Client, ClientSession } from "#client/index.js";
2
+ import type { EveCliSetupStepEvent, EveCliSetupTerminalEvent } from "#cli/telemetry/index.js";
3
+ import type { OnboardingScreenEvent } from "./setup-commands.js";
2
4
  import { inspectApplication } from "#services/inspect-application.js";
3
5
  import { type SubagentView } from "./subagent-pump.js";
4
6
  export type { SubagentRun, SubagentStepUpdate, SubagentToolUpdate, SubagentView, } from "./subagent-pump.js";
@@ -292,6 +294,7 @@ export interface PromptCommandHandlerContext {
292
294
  /** Provider entry authorized by confirmed boot-time model-access evidence. */
293
295
  readonly initialModelStep?: "provider";
294
296
  readonly registryPlannerContext?: RegistryPlannerContext;
297
+ readonly onOnboardingScreen?: (input: OnboardingScreenEvent) => void;
295
298
  /** Overrides the standalone command title inside a composed setup journey. */
296
299
  readonly setupFlowTitle?: string;
297
300
  /** Progress owned by an enclosing journey while this command runs. */
@@ -364,6 +367,9 @@ export type EveTUIRunnerOptions = TuiDisplayOptions & {
364
367
  initialInput?: string;
365
368
  /** Explicit fresh-agent onboarding handoff from `eve init`. */
366
369
  onboard?: boolean;
370
+ /** Reports timestamped steps and terminal result for fresh-agent onboarding. */
371
+ onOnboardingStep?: (input: EveCliSetupStepEvent) => void;
372
+ onOnboardingTerminal?: (input: EveCliSetupTerminalEvent) => void;
367
373
  /** Handles non-core slash commands without adding feature branches to the runner. */
368
374
  promptCommandHandler?: PromptCommandHandler;
369
375
  /** Commands shown in discovery for this local or remote session. */