eve 0.45.2 → 0.46.1

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 (116) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/dist/src/channel/types.d.ts +2 -0
  3. package/dist/src/chunks/{use-eve-agent-DI2j5XK8.js → use-eve-agent-CacMaX4P.js} +91 -43
  4. package/dist/src/chunks/{use-eve-agent-BH7Z6SDu.js → use-eve-agent-kmlFdOBB.js} +91 -43
  5. package/dist/src/cli/commands/info.d.ts +2 -0
  6. package/dist/src/cli/commands/info.js +2 -2
  7. package/dist/src/cli/dev/tui/agent-header.d.ts +5 -14
  8. package/dist/src/cli/dev/tui/agent-header.js +1 -1
  9. package/dist/src/cli/dev/tui/prompt-commands.d.ts +2 -0
  10. package/dist/src/cli/dev/tui/prompt-commands.js +1 -1
  11. package/dist/src/cli/dev/tui/runner.d.ts +7 -5
  12. package/dist/src/cli/dev/tui/runner.js +1 -1
  13. package/dist/src/cli/dev/tui/terminal-renderer.d.ts +3 -3
  14. package/dist/src/cli/run.js +3 -3
  15. package/dist/src/client/message-reducer-primitives.d.ts +8 -0
  16. package/dist/src/client/message-reducer-primitives.js +1 -0
  17. package/dist/src/client/message-reducer-types.d.ts +2 -0
  18. package/dist/src/client/message-reducer.js +1 -1
  19. package/dist/src/compiled/.vendor-stamp.json +1 -1
  20. package/dist/src/compiled/@linqapp/chat-sdk-adapter/index.d.ts +2 -1
  21. package/dist/src/compiled/@linqapp/chat-sdk-adapter/index.js +3 -3
  22. package/dist/src/compiler/channel-route-plan.d.ts +2 -2
  23. package/dist/src/compiler/extension-compatibility.d.ts +18 -18
  24. package/dist/src/compiler/extension-compatibility.js +1 -1
  25. package/dist/src/compiler/instrumentation-layout-config.d.ts +3 -0
  26. package/dist/src/compiler/instrumentation-layout-config.js +1 -0
  27. package/dist/src/compiler/load-binding-namespace.d.ts +5 -3
  28. package/dist/src/compiler/load-binding-namespace.js +1 -1
  29. package/dist/src/compiler/manifest.d.ts +2 -2
  30. package/dist/src/compiler/manifest.js +1 -1
  31. package/dist/src/compiler/module-lifecycle.d.ts +14 -0
  32. package/dist/src/compiler/module-lifecycle.js +1 -0
  33. package/dist/src/compiler/module-map.d.ts +2 -2
  34. package/dist/src/compiler/module-map.js +2 -2
  35. package/dist/src/compiler/node-source-state.d.ts +6 -3
  36. package/dist/src/compiler/node-source-state.js +1 -1
  37. package/dist/src/compiler/normalize-agent-config.d.ts +2 -2
  38. package/dist/src/compiler/normalize-helpers.d.ts +4 -4
  39. package/dist/src/compiler/normalize-manifest-helpers.js +1 -1
  40. package/dist/src/compiler/normalize-manifest.js +1 -1
  41. package/dist/src/compiler/remote-agent-node.js +1 -1
  42. package/dist/src/compiler/source-graph.d.ts +12 -2
  43. package/dist/src/compiler/source-graph.js +1 -1
  44. package/dist/src/compiler/validate-artifact.js +1 -1
  45. package/dist/src/context/keys.d.ts +2 -0
  46. package/dist/src/execution/tools/connection-search.js +1 -1
  47. package/dist/src/execution/workflow-runtime.js +1 -1
  48. package/dist/src/framework/sources/registry.js +1 -1
  49. package/dist/src/harness/channel-delivery-instrumentation.js +1 -1
  50. package/dist/src/harness/emission.d.ts +1 -8
  51. package/dist/src/harness/emission.js +1 -1
  52. package/dist/src/harness/instrumentation/content-policy.d.ts +3 -2
  53. package/dist/src/harness/instrumentation/content-policy.js +1 -1
  54. package/dist/src/harness/instrumentation/content.d.ts +11 -0
  55. package/dist/src/harness/instrumentation/content.js +1 -1
  56. package/dist/src/harness/ordered-stream-emitter.js +1 -1
  57. package/dist/src/harness/tool-loop.js +2 -2
  58. package/dist/src/internal/application/compiled-artifacts.d.ts +7 -7
  59. package/dist/src/internal/application/compiled-artifacts.js +2 -3
  60. package/dist/src/internal/application/package.js +1 -1
  61. package/dist/src/internal/authored-asset-import-plugin.d.ts +6 -2
  62. package/dist/src/internal/authored-asset-import-plugin.js +1 -1
  63. package/dist/src/internal/authored-module-loader.js +3 -3
  64. package/dist/src/internal/authored-module-map-loader.js +1 -1
  65. package/dist/src/internal/authored-runtime-modules.d.ts +15 -0
  66. package/dist/src/internal/authored-runtime-modules.js +1 -0
  67. package/dist/src/internal/materialized-authored-modules.d.ts +2 -18
  68. package/dist/src/internal/materialized-authored-modules.js +1 -1
  69. package/dist/src/internal/nitro/development-generation.js +1 -1
  70. package/dist/src/internal/nitro/routes/agent-info/build-agent-info-response.js +1 -1
  71. package/dist/src/packages/eve-catalog/src/index.js +1 -1
  72. package/dist/src/protocol/message.d.ts +29 -2
  73. package/dist/src/protocol/message.js +2 -2
  74. package/dist/src/public/channels/slack/inbound-content.js +2 -2
  75. package/dist/src/public/definitions/connections/tool-call.d.ts +2 -0
  76. package/dist/src/public/definitions/hook.d.ts +1 -0
  77. package/dist/src/public/instrumentation/otel.d.ts +1 -1
  78. package/dist/src/runtime/connections/mcp-client.d.ts +1 -1
  79. package/dist/src/runtime/connections/mcp-client.js +1 -1
  80. package/dist/src/runtime/connections/openapi-client.d.ts +1 -1
  81. package/dist/src/runtime/connections/openapi-client.js +1 -1
  82. package/dist/src/runtime/connections/provided-arguments.d.ts +1 -0
  83. package/dist/src/runtime/connections/provided-arguments.js +1 -1
  84. package/dist/src/setup/integrations/registry.js +1 -1
  85. package/dist/src/setup/integrations/shopify/setup.d.ts +20 -0
  86. package/dist/src/setup/integrations/shopify/setup.js +1 -0
  87. package/dist/src/setup/integrations/shopify/templates.d.ts +1 -0
  88. package/dist/src/setup/integrations/shopify/templates.js +88 -0
  89. package/dist/src/setup/scaffold/create/project.js +1 -1
  90. package/dist/src/shared/connection-types.d.ts +3 -1
  91. package/dist/src/shared/instrumentation-content.d.ts +6 -0
  92. package/dist/src/shared/instrumentation-content.js +1 -0
  93. package/dist/src/shared/instrumentation-decision.d.ts +8 -0
  94. package/dist/src/shared/instrumentation-decision.js +1 -0
  95. package/dist/src/svelte/index.js +1 -1
  96. package/dist/src/svelte/use-eve-agent.js +1 -1
  97. package/dist/src/tracing/agent-trace-context-store.d.ts +3 -3
  98. package/dist/src/tracing/agent-trace-context-store.js +1 -1
  99. package/dist/src/tracing/otel-declaration.d.ts +14 -3
  100. package/dist/src/tracing/sampled-trace.d.ts +8 -1
  101. package/dist/src/tracing/sampled-trace.js +1 -1
  102. package/dist/src/vue/index.js +1 -1
  103. package/dist/src/vue/use-eve-agent.js +1 -1
  104. package/docs/agent-config.md +2 -0
  105. package/docs/channels/slack.mdx +2 -0
  106. package/docs/concepts/sessions-runs-and-streaming.md +5 -2
  107. package/docs/connections/mcp.mdx +1 -1
  108. package/docs/connections/openapi.mdx +1 -1
  109. package/docs/guides/client/streaming.mdx +18 -15
  110. package/docs/guides/dev-tui.md +2 -1
  111. package/docs/guides/dynamic-capabilities.md +2 -0
  112. package/docs/instructions.mdx +3 -1
  113. package/docs/reference/typescript-api.md +25 -0
  114. package/docs/schedules.mdx +2 -0
  115. package/docs/skills.mdx +2 -0
  116. package/package.json +2 -2
package/CHANGELOG.md CHANGED
@@ -1,5 +1,27 @@
1
1
  # eve
2
2
 
3
+ ## 0.46.1
4
+
5
+ ### Patch Changes
6
+
7
+ - 16c8b63: Expose a replay-stable `callId` to MCP and OpenAPI `providedArguments` callbacks so connection tools can derive per-call idempotency keys.
8
+ - e2d9162: Update the Linq channel adapter to preserve supported text decorations, including bold, italic, strikethrough, and underline, in outbound messages.
9
+ - fbc3080: Add Shopify registry setup for searching products and building UCP carts and checkouts. Setup now generates an anonymous UCP profile that the connection advertises in production.
10
+ - 2af4a4c: Tool inputs now stream through the durable event protocol as `action.input.appended` before the matching validated `actions.requested` event. Each event stores only its raw delta and UTF-16 offset, while the default message reducer exposes cumulative raw input on `dynamic-tool.inputText` in the `input-streaming` state. This advances the stream protocol to version 24; when assistant text precedes a tool call, `message.completed` now arrives before that call's streamed input events.
11
+ - 122f565: Add a local dev TUI `/info` command that shows the same application, artifact, diagnostic, and messaging details as `eve info`. The human-readable report now begins directly with its application details instead of repeating an `eve Info` heading.
12
+
13
+ ## 0.46.0
14
+
15
+ ### Minor Changes
16
+
17
+ - 1d79217: Emit traces for every audience by default while recording content only for public conversations. `tracePolicy` can explicitly disable emission or select directional content capture, and existing boolean policies retain their current behavior.
18
+
19
+ ### Patch Changes
20
+
21
+ - 47b3e48: Static authored definitions now remain build-only, while runtime entries and their assets use the same bundling semantics in development and production.
22
+ - 9c0a138: Replace the eve TUI's separate banner and text header with a startup card showing the installed version, active model, and the instructions, tools, skills, subagents, and schedules loaded by the agent.
23
+ - 7acb4ec: Include the original message body when Slack users share a message into an eve conversation. Agents now receive Slack crosspost content alongside distinct top-level comments without repeating content already present in the comment.
24
+
3
25
  ## 0.45.2
4
26
 
5
27
  ### Patch Changes
@@ -7,6 +7,7 @@ import type { InputRequest, InputResponse } from "#shared/input.js";
7
7
  import type { ChannelAdapter } from "#channel/adapter.js";
8
8
  import type { AgentLimitsDefinition } from "#shared/agent-definition.js";
9
9
  import type { JsonObject } from "#shared/json.js";
10
+ import type { InstrumentationDecision } from "#shared/instrumentation-decision.js";
10
11
  import type { TaskView } from "#tasks/types.js";
11
12
  export type { ContextAccessor } from "#context/key.js";
12
13
  export type { ChannelInstrumentationProjection } from "#channel/instrumentation.js";
@@ -71,6 +72,7 @@ export interface SessionParent {
71
72
  * free of tracing dependencies.
72
73
  */
73
74
  export interface SessionTraceContext {
75
+ readonly decision?: InstrumentationDecision;
74
76
  readonly spanId: string;
75
77
  readonly traceFlags: number;
76
78
  readonly traceId: string;
@@ -2215,6 +2215,62 @@ function stringifyUnknown(value) {
2215
2215
  }
2216
2216
  }
2217
2217
 
2218
+ //#endregion
2219
+ //#region src/client/message-reducer-primitives.ts
2220
+ function projectReceivedParts(parts, message) {
2221
+ return parts?.map((part) => part.type === "text" ? {
2222
+ state: "done",
2223
+ text: part.text,
2224
+ type: "text"
2225
+ } : {
2226
+ filename: part.filename,
2227
+ mediaType: part.mediaType,
2228
+ size: part.size,
2229
+ type: "file",
2230
+ url: part.url
2231
+ }) ?? [{
2232
+ state: "done",
2233
+ text: message,
2234
+ type: "text"
2235
+ }];
2236
+ }
2237
+ function partKey(part) {
2238
+ switch (part.type) {
2239
+ case "text": return `text:${part.stepIndex ?? 0}`;
2240
+ case "reasoning": return `reasoning:${part.stepIndex ?? 0}`;
2241
+ case "file": return `file:${part.stepIndex ?? 0}:${part.filename ?? part.url ?? part.mediaType}`;
2242
+ case "step-start": return "step-start";
2243
+ case "authorization": return `authorization:${part.turnId}:${part.stepIndex}:${part.name}`;
2244
+ case "dynamic-tool": return `dynamic-tool:${part.toolCallId}`;
2245
+ }
2246
+ }
2247
+ function upsertMessage(data, next) {
2248
+ const index = data.messages.findIndex((message) => message.id === next.id);
2249
+ if (index === -1) return { messages: [...data.messages, next] };
2250
+ return { messages: [
2251
+ ...data.messages.slice(0, index),
2252
+ next,
2253
+ ...data.messages.slice(index + 1)
2254
+ ] };
2255
+ }
2256
+ function removeStreamingToolPartsForTurn(data, turnId) {
2257
+ const index = data.messages.findIndex((message) => message.role === "assistant" && message.metadata?.turnId === turnId);
2258
+ const message = data.messages[index];
2259
+ if (message === void 0) return data;
2260
+ return upsertMessage(data, {
2261
+ ...message,
2262
+ parts: message.parts.filter((part) => part.type !== "dynamic-tool" || part.state !== "input-streaming")
2263
+ });
2264
+ }
2265
+ function optimisticUserMessageId(submissionId) {
2266
+ return `optimistic:${submissionId}:user`;
2267
+ }
2268
+ function appendToolInputDelta(inputText, offset, delta) {
2269
+ if (offset === 0) return delta;
2270
+ if (inputText?.length !== offset) return void 0;
2271
+ return inputText + delta;
2272
+ }
2273
+
2218
2274
  //#endregion
2219
2275
  //#region src/client/message-reducer.ts
2220
2276
  function defaultMessageReducer() {
@@ -2285,6 +2341,27 @@ function reduceMessageData(data, event) {
2285
2341
  text: event.data.reasoning,
2286
2342
  type: "reasoning"
2287
2343
  }));
2344
+ case "action.input.appended": {
2345
+ const existing = findToolPart(data, event.data.callId);
2346
+ if (existing !== void 0 && existing.state !== "input-streaming") return data;
2347
+ const inputText = appendToolInputDelta(existing?.state === "input-streaming" ? existing.inputText : void 0, event.data.inputTextOffset, event.data.inputTextDelta);
2348
+ if (inputText === void 0) return data;
2349
+ const nextPart = {
2350
+ input: void 0,
2351
+ inputText,
2352
+ state: "input-streaming",
2353
+ stepIndex: event.data.stepIndex,
2354
+ toolCallId: event.data.callId,
2355
+ toolMetadata: existing?.toolMetadata ?? { eve: {
2356
+ kind: "unknown",
2357
+ name: event.data.toolName
2358
+ } },
2359
+ toolName: event.data.toolName,
2360
+ type: "dynamic-tool"
2361
+ };
2362
+ if (existing !== void 0) return updateToolPart(data, event.data.callId, nextPart);
2363
+ return updateAssistantMessage(data, event.data.turnId, (message) => upsertPart(ensureStepStartPart(message, event.data.stepIndex), nextPart));
2364
+ }
2288
2365
  case "actions.requested": {
2289
2366
  let next = data;
2290
2367
  for (const action of event.data.actions) {
@@ -2428,23 +2505,33 @@ function reduceMessageData(data, event) {
2428
2505
  });
2429
2506
  });
2430
2507
  case "result.completed": return updateAssistantMetadata(data, event.data.turnId, { result: event.data.result });
2431
- case "turn.completed": return updateAssistantMetadata(data, event.data.turnId, { status: "complete" });
2508
+ case "turn.completed": return updateAssistantMessage(data, event.data.turnId, (message) => ({
2509
+ ...message,
2510
+ metadata: {
2511
+ ...message.metadata,
2512
+ status: "complete"
2513
+ },
2514
+ parts: removeStreamingToolParts(message.parts)
2515
+ }));
2432
2516
  case "turn.cancelled": return updateAssistantMessage(data, event.data.turnId, (message) => ({
2433
2517
  ...message,
2434
2518
  metadata: {
2435
2519
  ...message.metadata,
2436
2520
  status: "complete"
2437
2521
  },
2438
- parts: message.parts.map((part) => (part.type === "text" || part.type === "reasoning") && part.state === "streaming" ? {
2522
+ parts: removeStreamingToolParts(message.parts.map((part) => (part.type === "text" || part.type === "reasoning") && part.state === "streaming" ? {
2439
2523
  ...part,
2440
2524
  state: "done"
2441
- } : part)
2525
+ } : part))
2442
2526
  }));
2443
- case "turn.failed":
2527
+ case "turn.failed": return removeStreamingToolPartsForTurn(data, event.data.turnId);
2444
2528
  case "session.failed": return data;
2445
2529
  default: return data;
2446
2530
  }
2447
2531
  }
2532
+ function removeStreamingToolParts(parts) {
2533
+ return parts.filter((part) => part.type !== "dynamic-tool" || part.state !== "input-streaming");
2534
+ }
2448
2535
  function respondToInputRequest(data, response) {
2449
2536
  const existing = findToolPartByApprovalId(data, response.requestId);
2450
2537
  if (!existing) return data;
@@ -2598,45 +2685,6 @@ function findLatestPendingAuthorizationPart(data, name) {
2598
2685
  function findToolPartByApprovalId(data, approvalId) {
2599
2686
  for (const message of data.messages) for (const part of message.parts) if (part.type === "dynamic-tool" && part.approval?.id === approvalId) return part;
2600
2687
  }
2601
- function projectReceivedParts(parts, message) {
2602
- return parts?.map((part) => part.type === "text" ? {
2603
- state: "done",
2604
- text: part.text,
2605
- type: "text"
2606
- } : {
2607
- filename: part.filename,
2608
- mediaType: part.mediaType,
2609
- size: part.size,
2610
- type: "file",
2611
- url: part.url
2612
- }) ?? [{
2613
- state: "done",
2614
- text: message,
2615
- type: "text"
2616
- }];
2617
- }
2618
- function partKey(part) {
2619
- switch (part.type) {
2620
- case "text": return `text:${part.stepIndex ?? 0}`;
2621
- case "reasoning": return `reasoning:${part.stepIndex ?? 0}`;
2622
- case "file": return `file:${part.stepIndex ?? 0}:${part.filename ?? part.url ?? part.mediaType}`;
2623
- case "step-start": return "step-start";
2624
- case "authorization": return `authorization:${part.turnId}:${part.stepIndex}:${part.name}`;
2625
- case "dynamic-tool": return `dynamic-tool:${part.toolCallId}`;
2626
- }
2627
- }
2628
- function upsertMessage(data, next) {
2629
- const index = data.messages.findIndex((message) => message.id === next.id);
2630
- if (index === -1) return { messages: [...data.messages, next] };
2631
- return { messages: [
2632
- ...data.messages.slice(0, index),
2633
- next,
2634
- ...data.messages.slice(index + 1)
2635
- ] };
2636
- }
2637
- function optimisticUserMessageId(submissionId) {
2638
- return `optimistic:${submissionId}:user`;
2639
- }
2640
2688
 
2641
2689
  //#endregion
2642
2690
  //#region src/vue/use-eve-agent.ts
@@ -2215,6 +2215,62 @@ function stringifyUnknown(value) {
2215
2215
  }
2216
2216
  }
2217
2217
 
2218
+ //#endregion
2219
+ //#region src/client/message-reducer-primitives.ts
2220
+ function projectReceivedParts(parts, message) {
2221
+ return parts?.map((part) => part.type === "text" ? {
2222
+ state: "done",
2223
+ text: part.text,
2224
+ type: "text"
2225
+ } : {
2226
+ filename: part.filename,
2227
+ mediaType: part.mediaType,
2228
+ size: part.size,
2229
+ type: "file",
2230
+ url: part.url
2231
+ }) ?? [{
2232
+ state: "done",
2233
+ text: message,
2234
+ type: "text"
2235
+ }];
2236
+ }
2237
+ function partKey(part) {
2238
+ switch (part.type) {
2239
+ case "text": return `text:${part.stepIndex ?? 0}`;
2240
+ case "reasoning": return `reasoning:${part.stepIndex ?? 0}`;
2241
+ case "file": return `file:${part.stepIndex ?? 0}:${part.filename ?? part.url ?? part.mediaType}`;
2242
+ case "step-start": return "step-start";
2243
+ case "authorization": return `authorization:${part.turnId}:${part.stepIndex}:${part.name}`;
2244
+ case "dynamic-tool": return `dynamic-tool:${part.toolCallId}`;
2245
+ }
2246
+ }
2247
+ function upsertMessage(data, next) {
2248
+ const index = data.messages.findIndex((message) => message.id === next.id);
2249
+ if (index === -1) return { messages: [...data.messages, next] };
2250
+ return { messages: [
2251
+ ...data.messages.slice(0, index),
2252
+ next,
2253
+ ...data.messages.slice(index + 1)
2254
+ ] };
2255
+ }
2256
+ function removeStreamingToolPartsForTurn(data, turnId) {
2257
+ const index = data.messages.findIndex((message) => message.role === "assistant" && message.metadata?.turnId === turnId);
2258
+ const message = data.messages[index];
2259
+ if (message === void 0) return data;
2260
+ return upsertMessage(data, {
2261
+ ...message,
2262
+ parts: message.parts.filter((part) => part.type !== "dynamic-tool" || part.state !== "input-streaming")
2263
+ });
2264
+ }
2265
+ function optimisticUserMessageId(submissionId) {
2266
+ return `optimistic:${submissionId}:user`;
2267
+ }
2268
+ function appendToolInputDelta(inputText, offset, delta) {
2269
+ if (offset === 0) return delta;
2270
+ if (inputText?.length !== offset) return void 0;
2271
+ return inputText + delta;
2272
+ }
2273
+
2218
2274
  //#endregion
2219
2275
  //#region src/client/message-reducer.ts
2220
2276
  function defaultMessageReducer() {
@@ -2285,6 +2341,27 @@ function reduceMessageData(data, event) {
2285
2341
  text: event.data.reasoning,
2286
2342
  type: "reasoning"
2287
2343
  }));
2344
+ case "action.input.appended": {
2345
+ const existing = findToolPart(data, event.data.callId);
2346
+ if (existing !== void 0 && existing.state !== "input-streaming") return data;
2347
+ const inputText = appendToolInputDelta(existing?.state === "input-streaming" ? existing.inputText : void 0, event.data.inputTextOffset, event.data.inputTextDelta);
2348
+ if (inputText === void 0) return data;
2349
+ const nextPart = {
2350
+ input: void 0,
2351
+ inputText,
2352
+ state: "input-streaming",
2353
+ stepIndex: event.data.stepIndex,
2354
+ toolCallId: event.data.callId,
2355
+ toolMetadata: existing?.toolMetadata ?? { eve: {
2356
+ kind: "unknown",
2357
+ name: event.data.toolName
2358
+ } },
2359
+ toolName: event.data.toolName,
2360
+ type: "dynamic-tool"
2361
+ };
2362
+ if (existing !== void 0) return updateToolPart(data, event.data.callId, nextPart);
2363
+ return updateAssistantMessage(data, event.data.turnId, (message) => upsertPart(ensureStepStartPart(message, event.data.stepIndex), nextPart));
2364
+ }
2288
2365
  case "actions.requested": {
2289
2366
  let next = data;
2290
2367
  for (const action of event.data.actions) {
@@ -2428,23 +2505,33 @@ function reduceMessageData(data, event) {
2428
2505
  });
2429
2506
  });
2430
2507
  case "result.completed": return updateAssistantMetadata(data, event.data.turnId, { result: event.data.result });
2431
- case "turn.completed": return updateAssistantMetadata(data, event.data.turnId, { status: "complete" });
2508
+ case "turn.completed": return updateAssistantMessage(data, event.data.turnId, (message) => ({
2509
+ ...message,
2510
+ metadata: {
2511
+ ...message.metadata,
2512
+ status: "complete"
2513
+ },
2514
+ parts: removeStreamingToolParts(message.parts)
2515
+ }));
2432
2516
  case "turn.cancelled": return updateAssistantMessage(data, event.data.turnId, (message) => ({
2433
2517
  ...message,
2434
2518
  metadata: {
2435
2519
  ...message.metadata,
2436
2520
  status: "complete"
2437
2521
  },
2438
- parts: message.parts.map((part) => (part.type === "text" || part.type === "reasoning") && part.state === "streaming" ? {
2522
+ parts: removeStreamingToolParts(message.parts.map((part) => (part.type === "text" || part.type === "reasoning") && part.state === "streaming" ? {
2439
2523
  ...part,
2440
2524
  state: "done"
2441
- } : part)
2525
+ } : part))
2442
2526
  }));
2443
- case "turn.failed":
2527
+ case "turn.failed": return removeStreamingToolPartsForTurn(data, event.data.turnId);
2444
2528
  case "session.failed": return data;
2445
2529
  default: return data;
2446
2530
  }
2447
2531
  }
2532
+ function removeStreamingToolParts(parts) {
2533
+ return parts.filter((part) => part.type !== "dynamic-tool" || part.state !== "input-streaming");
2534
+ }
2448
2535
  function respondToInputRequest(data, response) {
2449
2536
  const existing = findToolPartByApprovalId(data, response.requestId);
2450
2537
  if (!existing) return data;
@@ -2598,45 +2685,6 @@ function findLatestPendingAuthorizationPart(data, name) {
2598
2685
  function findToolPartByApprovalId(data, approvalId) {
2599
2686
  for (const message of data.messages) for (const part of message.parts) if (part.type === "dynamic-tool" && part.approval?.id === approvalId) return part;
2600
2687
  }
2601
- function projectReceivedParts(parts, message) {
2602
- return parts?.map((part) => part.type === "text" ? {
2603
- state: "done",
2604
- text: part.text,
2605
- type: "text"
2606
- } : {
2607
- filename: part.filename,
2608
- mediaType: part.mediaType,
2609
- size: part.size,
2610
- type: "file",
2611
- url: part.url
2612
- }) ?? [{
2613
- state: "done",
2614
- text: message,
2615
- type: "text"
2616
- }];
2617
- }
2618
- function partKey(part) {
2619
- switch (part.type) {
2620
- case "text": return `text:${part.stepIndex ?? 0}`;
2621
- case "reasoning": return `reasoning:${part.stepIndex ?? 0}`;
2622
- case "file": return `file:${part.stepIndex ?? 0}:${part.filename ?? part.url ?? part.mediaType}`;
2623
- case "step-start": return "step-start";
2624
- case "authorization": return `authorization:${part.turnId}:${part.stepIndex}:${part.name}`;
2625
- case "dynamic-tool": return `dynamic-tool:${part.toolCallId}`;
2626
- }
2627
- }
2628
- function upsertMessage(data, next) {
2629
- const index = data.messages.findIndex((message) => message.id === next.id);
2630
- if (index === -1) return { messages: [...data.messages, next] };
2631
- return { messages: [
2632
- ...data.messages.slice(0, index),
2633
- next,
2634
- ...data.messages.slice(index + 1)
2635
- ] };
2636
- }
2637
- function optimisticUserMessageId(submissionId) {
2638
- return `optimistic:${submissionId}:user`;
2639
- }
2640
2688
 
2641
2689
  //#endregion
2642
2690
  //#region src/svelte/use-eve-agent.ts
@@ -52,4 +52,6 @@ export declare function buildApplicationInfoJson(inspection: ApplicationInspecti
52
52
  * Writes resolved application details and the active message-route contract.
53
53
  */
54
54
  export declare function printApplicationInfo(logger: CliInfoLogger, appRoot: string, options?: PrintApplicationInfoOptions): Promise<void>;
55
+ /** Renders the human-readable `eve info` report for CLI and TUI surfaces. */
56
+ export declare function renderApplicationInfo(inspection: ApplicationInspection): string;
55
57
  export {};
@@ -1,2 +1,2 @@
1
- import{createCliTheme,renderCliBanner,renderCliSection}from"#cli/ui/output.js";import{inspectApplication}from"#services/inspect-application.js";function formatInstructions(e){return e.map(e=>`${e.logicalPath} (${e.role})`).join(`, `)}function buildApplicationInfoJson(e){let{application:t,compiledState:n,messaging:r}=e;return{appRoot:t.appRoot,agentRoot:n?.project.agentRoot??null,layout:n?.project.layout??null,status:n?.metadata.status??`unavailable`,diagnostics:n?{errors:n.metadata.discovery.summary.errors,warnings:n.metadata.discovery.summary.warnings}:null,model:n?.manifest.config.model?.id??null,instructions:n===null||n.manifest.instructions.length===0?null:formatInstructions(n.manifest.instructions),skills:(n?.manifest.skills??[]).map(e=>e.name),tools:(n?.manifest.tools??[]).map(e=>e.name),subagents:(n?.manifest.subagents??[]).map(e=>e.name),schedules:(n?.manifest.schedules??[]).map(e=>e.name),channels:(n?.manifest.channelRoutes.effective??[]).map(e=>({name:e.name,kind:e.adapterKind??null,method:e.method,urlPath:e.urlPath})),messaging:{create:r.createSessionRoutePath,messages:r.sessionMessagesRoutePattern,stream:r.streamRoutePattern},artifacts:n?{compiledManifest:n.paths.compiledManifestPath,discoveryManifest:n.paths.discoveryManifestPath,diagnostics:n.paths.diagnosticsPath,moduleMap:n.paths.moduleMapPath,metadata:n.paths.compileMetadataPath}:null}}function pluralize(e,t){return`${e} ${t}${e===1?``:`s`}`}function formatDiscoverySummary(e,t){return`${pluralize(e,`error`)}, ${pluralize(t,`warning`)}`}function resolveCompileTone(e){switch(e){case`ready`:return`success`;case`failed`:return`danger`;default:return`warning`}}async function printApplicationInfo(i,a,o={}){let s=await inspectApplication(a);if(o.json){i.log(JSON.stringify(buildApplicationInfoJson(s),null,2));return}let c=s.compiledState,l=s.application,u=createCliTheme(),d=[{label:`App Root`,value:l.appRoot}],f=[{label:`Workflow Build`,value:l.workflowBuildDir},{label:`Output`,value:l.outputDir}],p=[];c===null?d.push({label:`Compile`,tone:`warning`,value:`unavailable`}):(d.push({label:`Agent Root`,value:c.project.agentRoot},{label:`Layout`,value:c.project.layout},{label:`Compile`,tone:resolveCompileTone(c.metadata.status),value:c.metadata.status},{label:`Diagnostics`,tone:c.metadata.discovery.summary.errors>0?`danger`:c.metadata.discovery.summary.warnings>0?`warning`:`success`,value:formatDiscoverySummary(c.metadata.discovery.summary.errors,c.metadata.discovery.summary.warnings)},{label:`Instructions`,value:c.manifest.instructions.length===0?`none`:formatInstructions(c.manifest.instructions)},{label:`Skills`,value:pluralize(c.manifest.skills.length,`skill`)},{label:`Tools`,value:pluralize(c.manifest.tools.length,`tool`)},{label:`Subagents`,value:pluralize(c.manifest.subagents.length,`subagent`)},{label:`Schedules`,value:pluralize(c.manifest.schedules.length,`schedule`)}),f.unshift({label:`Compiled Manifest`,value:c.paths.compiledManifestPath},{label:`Discovery Manifest`,value:c.paths.discoveryManifestPath},{label:`Diagnostics`,value:c.paths.diagnosticsPath},{label:`Module Map`,value:c.paths.moduleMapPath},{label:`Metadata`,value:c.paths.compileMetadataPath}),p.push(c.manifest.instructions.length===0?{label:`Instructions`,value:`No instructions prompt discovered.`}:{label:`Instructions`,value:formatInstructions(c.manifest.instructions)})),i.log([renderCliBanner(u,{subtitle:`Resolved application paths and the active message contract.`,title:`eve Info`}),``,renderCliSection(u,{rows:d,title:`Application`}),``,renderCliSection(u,{rows:f,title:`Artifacts`}),...c===null?[]:[``,renderCliSection(u,{rows:p,title:`Instructions`})],``,renderCliSection(u,{rows:[{label:`Workflow ID`,value:l.workflowId},{label:`Source Dir`,value:l.workflowSourceDir},{label:`Create`,tone:`info`,value:`POST ${s.messaging.createSessionRoutePath}`},{label:`Messages`,tone:`info`,value:`POST ${s.messaging.sessionMessagesRoutePattern}`},{label:`Stream`,tone:`info`,value:`GET ${s.messaging.streamRoutePattern}`}],title:`Messaging`})].join(`
2
- `))}export{buildApplicationInfoJson,printApplicationInfo};
1
+ import{createCliTheme,renderCliSection}from"#cli/ui/output.js";import{inspectApplication}from"#services/inspect-application.js";function formatInstructions(e){return e.map(e=>`${e.logicalPath} (${e.role})`).join(`, `)}function buildApplicationInfoJson(e){let{application:t,compiledState:n,messaging:r}=e;return{appRoot:t.appRoot,agentRoot:n?.project.agentRoot??null,layout:n?.project.layout??null,status:n?.metadata.status??`unavailable`,diagnostics:n?{errors:n.metadata.discovery.summary.errors,warnings:n.metadata.discovery.summary.warnings}:null,model:n?.manifest.config.model?.id??null,instructions:n===null||n.manifest.instructions.length===0?null:formatInstructions(n.manifest.instructions),skills:(n?.manifest.skills??[]).map(e=>e.name),tools:(n?.manifest.tools??[]).map(e=>e.name),subagents:(n?.manifest.subagents??[]).map(e=>e.name),schedules:(n?.manifest.schedules??[]).map(e=>e.name),channels:(n?.manifest.channelRoutes.effective??[]).map(e=>({name:e.name,kind:e.adapterKind??null,method:e.method,urlPath:e.urlPath})),messaging:{create:r.createSessionRoutePath,messages:r.sessionMessagesRoutePattern,stream:r.streamRoutePattern},artifacts:n?{compiledManifest:n.paths.compiledManifestPath,discoveryManifest:n.paths.discoveryManifestPath,diagnostics:n.paths.diagnosticsPath,moduleMap:n.paths.moduleMapPath,metadata:n.paths.compileMetadataPath}:null}}function pluralize(e,t){return`${e} ${t}${e===1?``:`s`}`}function formatDiscoverySummary(e,t){return`${pluralize(e,`error`)}, ${pluralize(t,`warning`)}`}function resolveCompileTone(e){switch(e){case`ready`:return`success`;case`failed`:return`danger`;default:return`warning`}}async function printApplicationInfo(e,t,r={}){let i=await inspectApplication(t);if(r.json){e.log(JSON.stringify(buildApplicationInfoJson(i),null,2));return}e.log(renderApplicationInfo(i))}function renderApplicationInfo(n){let r=n.compiledState,i=n.application,a=createCliTheme(),o=[{label:`App Root`,value:i.appRoot}],s=[{label:`Workflow Build`,value:i.workflowBuildDir},{label:`Output`,value:i.outputDir}],c=[];return r===null?o.push({label:`Compile`,tone:`warning`,value:`unavailable`}):(o.push({label:`Agent Root`,value:r.project.agentRoot},{label:`Layout`,value:r.project.layout},{label:`Compile`,tone:resolveCompileTone(r.metadata.status),value:r.metadata.status},{label:`Diagnostics`,tone:r.metadata.discovery.summary.errors>0?`danger`:r.metadata.discovery.summary.warnings>0?`warning`:`success`,value:formatDiscoverySummary(r.metadata.discovery.summary.errors,r.metadata.discovery.summary.warnings)},{label:`Instructions`,value:r.manifest.instructions.length===0?`none`:formatInstructions(r.manifest.instructions)},{label:`Skills`,value:pluralize(r.manifest.skills.length,`skill`)},{label:`Tools`,value:pluralize(r.manifest.tools.length,`tool`)},{label:`Subagents`,value:pluralize(r.manifest.subagents.length,`subagent`)},{label:`Schedules`,value:pluralize(r.manifest.schedules.length,`schedule`)}),s.unshift({label:`Compiled Manifest`,value:r.paths.compiledManifestPath},{label:`Discovery Manifest`,value:r.paths.discoveryManifestPath},{label:`Diagnostics`,value:r.paths.diagnosticsPath},{label:`Module Map`,value:r.paths.moduleMapPath},{label:`Metadata`,value:r.paths.compileMetadataPath}),c.push(r.manifest.instructions.length===0?{label:`Instructions`,value:`No instructions prompt discovered.`}:{label:`Instructions`,value:formatInstructions(r.manifest.instructions)})),[renderCliSection(a,{rows:o,title:`Application`}),``,renderCliSection(a,{rows:s,title:`Artifacts`}),...r===null?[]:[``,renderCliSection(a,{rows:c,title:`Instructions`})],``,renderCliSection(a,{rows:[{label:`Workflow ID`,value:i.workflowId},{label:`Source Dir`,value:i.workflowSourceDir},{label:`Create`,tone:`info`,value:`POST ${n.messaging.createSessionRoutePath}`},{label:`Messages`,tone:`info`,value:`POST ${n.messaging.sessionMessagesRoutePattern}`},{label:`Stream`,tone:`info`,value:`GET ${n.messaging.streamRoutePattern}`}],title:`Messaging`})].join(`
2
+ `)}export{buildApplicationInfoJson,printApplicationInfo,renderApplicationInfo};
@@ -1,21 +1,15 @@
1
- /**
2
- * Builds the startup header the dev TUI commits to scrollback before the
3
- * first prompt: one `eve <agent name>` brand line, a discovery-diagnostics
4
- * line when the compiler reported problems, and a rotating tip for local
5
- * sessions. The resolved model is not repeated here — it lives on the
6
- * persistent status line at the bottom.
7
- */
1
+ /** Builds the startup card the dev TUI commits before the first prompt. */
8
2
  import type { AgentInfoResult } from "#client/index.js";
9
3
  import type { Theme } from "./theme.js";
10
4
  export interface AgentHeaderInput {
11
- /** Resolved display name (e.g. "weather-agent"). */
12
- name: string;
5
+ /** Resolved display name used when agent inspection is unavailable. */
6
+ name?: string;
13
7
  /** Agent inspection payload, or `undefined` when it could not be fetched. */
14
8
  info?: AgentInfoResult;
15
9
  theme: Theme;
16
10
  /** Available terminal width. */
17
11
  width: number;
18
- /** Message-of-the-day line rendered under the brand line, when present. */
12
+ /** Message-of-the-day line rendered below the startup card, when present. */
19
13
  tip?: string;
20
14
  }
21
15
  /**
@@ -25,8 +19,5 @@ export interface AgentHeaderInput {
25
19
  export declare const AGENT_HEADER_TIPS: readonly string[];
26
20
  /** Picks one tip; `random` is a test seam over Math.random. */
27
21
  export declare function pickAgentHeaderTip(random?: () => number): string;
28
- /**
29
- * Returns the styled rows of the startup header (no trailing blank line is
30
- * added by callers other than the one separating it from the transcript).
31
- */
22
+ /** Returns the styled rows of the startup card and optional tip. */
32
23
  export declare function buildAgentHeader(input: AgentHeaderInput): string[];
@@ -1 +1 @@
1
- import{isPromptControlCommand}from"./prompt-commands.js";import{truncate}from"./tool-format.js";const AGENT_HEADER_TIPS=[`Use /add to install integrations from the registry.`,`Use /deploy to see your agent go live.`,`Type /help to see every command.`];function pickAgentHeaderTip(e=Math.random){let t=Math.min(AGENT_HEADER_TIPS.length-1,Math.floor(e()*AGENT_HEADER_TIPS.length));return AGENT_HEADER_TIPS[t]}function buildAgentHeader(e){let{theme:n,info:r,name:i,width:a}=e,o=n.colors,s=[],c=o.bold(`eve`);if(s.push(` ${c} ${o.dim(truncate(i,Math.max(8,a-8)))}`),r&&(r.diagnostics.discoveryErrors>0||r.diagnostics.discoveryWarnings>0)){let e=[];r.diagnostics.discoveryErrors>0&&e.push(o.red(`${r.diagnostics.discoveryErrors} error${plural(r.diagnostics.discoveryErrors)}`)),r.diagnostics.discoveryWarnings>0&&e.push(o.yellow(`${r.diagnostics.discoveryWarnings} warning${plural(r.diagnostics.discoveryWarnings)}`)),s.push(` ${o.dim(n.glyph.warning)} ${e.join(o.dim(` · `))}`)}return e.tip!==void 0&&s.push(` ${renderTip(e.tip,Math.max(8,a-2),n)}`),s}function renderTip(n,r,i){return truncate(n,r).split(/(\/[a-z:-]+)/u).map(t=>isPromptControlCommand(t)?i.colors.blue(t):i.colors.dim(t)).join(``)}function plural(e){return e===1?``:`s`}export{AGENT_HEADER_TIPS,buildAgentHeader,pickAgentHeaderTip};
1
+ import{isPromptControlCommand}from"./prompt-commands.js";import{resolveInstalledPackageInfo}from"#internal/application/package.js";import{clipVisible,visibleLength}from"#cli/ui/terminal-text.js";const AGENT_HEADER_TIPS=[`Use the /add command to install an integration.`,`Use the /deploy command to deploy your agent.`,`Use the /help command to see every command.`],EVE_LOGO=[`⣿⣿⣿⣿⣿⣿⣿⣿⣿ ⠏⣿⣿⣿⣿⣿⣿⣿⣿⣿`,` ⠇⣿⠏`,`⣿⣿⣿⣿⣿⣿⠇ ⠇⣿⠏ ⠇⣿⣿⣿⣿⣿`,` ⠃⣿⠏`,`⣿⣿⣿⣿⣿⣿⠏ ⠃⣿⠏ ⠇⣿⣿⣿⣿⣿⣿⣿`];function pickAgentHeaderTip(e=Math.random){let t=Math.min(AGENT_HEADER_TIPS.length-1,Math.floor(e()*AGENT_HEADER_TIPS.length));return AGENT_HEADER_TIPS[t]}function buildAgentHeader(e){let{theme:i,info:o,width:s}=e,c=i.colors,l=resolveInstalledPackageInfo().version,u=Math.min(68,Math.max(0,s-1)),d=`${c.dim(`☰`)}${c.bold(`eve`)} ${c.dim(`(v${l})`)}`;if(u<4)return[clipVisible(d,s)];let f=i.unicode?`─`:`-`,p=i.unicode?`│`:`|`,m=i.unicode?`╭`:`+`,h=i.unicode?`╮`:`+`,g=i.unicode?`╰`:`+`,_=i.unicode?`╯`:`+`,v=u-2,y=f.repeat(v),row=(e=``,t=0)=>{let i=Math.max(0,v-2),a=clipVisible(e,i),o=Math.max(0,i-visibleLength(a)-t);return`${c.dim(p)} ${a}${` `.repeat(o)} ${c.dim(p)}`},b=o?.agent.name??e.name,x=b===void 0?d:spreadRow(d,c.bold(b),v-2,1),S=[c.dim(`${m}${y}${h}`)];S.push(row(x,1),row());let C=Math.max(...EVE_LOGO.map(e=>visibleLength(e)));i.unicode&&v-2>=C&&S.push(...EVE_LOGO.map(e=>row(centerLogoLine(e,C,v-2,i))),row());let detail=(e,t)=>row(`${c.dim(e.padEnd(14))}${t}`),w=formatHeaderModel(o?.agent.model,i);if(w!==void 0&&S.push(detail(`model`,w)),o!==void 0){S.push(detail(`instructions`,formatInstructions(o,v-18))),S.push(row());let e=groupTools(o);if(e.length===0)S.push(detail(`tools`,`none`));else{S.push(detail(`tools`,``));for(let t of e.slice(0,4))S.push(detail(` ${t.label}`,fitNames(t.names,v-18)));let t=e.length-4;t>0&&S.push(detail(` +${t} ${pluralize(t,`group`)}`,``))}S.push(detail(`skills`,fitNames(skillNames(o),v-18))),S.push(detail(`subagents`,fitNames(subagentNames(o),v-18))),S.push(detail(`schedules`,fitNames(o.schedules.map(e=>e.name),v-18)))}if(S.push(c.dim(`${g}${y}${_}`)),o&&(o.diagnostics.discoveryErrors>0||o.diagnostics.discoveryWarnings>0)){let e=[];o.diagnostics.discoveryErrors>0&&e.push(c.red(`${o.diagnostics.discoveryErrors} error${plural(o.diagnostics.discoveryErrors)}`)),o.diagnostics.discoveryWarnings>0&&e.push(c.yellow(`${o.diagnostics.discoveryWarnings} warning${plural(o.diagnostics.discoveryWarnings)}`)),S.push(``,` ${c.dim(i.glyph.warning)} ${e.join(c.dim(` · `))}`)}return e.tip!==void 0&&S.push(``,` ${c.bold(`Tip:`)} ${renderTip(e.tip,Math.max(8,s-7),i)}`),S}function centerLogoLine(e,t,n,r){let i=Math.max(0,Math.floor((n-t)/2));return`${` `.repeat(i)}${r.colors.cyan(e)}`}function spreadRow(e,t,i,a){let o=Math.max(1,i-a),s=clipVisible(e,Math.max(1,o-visibleLength(t)-1)),c=clipVisible(t,Math.max(1,o-visibleLength(s)-1)),l=Math.max(1,o-visibleLength(s)-visibleLength(c));return`${s}${` `.repeat(l)}${c}`}function groupTools(e){let t=new Map;for(let n of e.tools.static){let e=n.owner.kind===`application`?`agent`:n.owner.kind===`framework`?`eve`:n.owner.namespace,r=t.get(e)??[];r.push(n.name),t.set(e,r)}e.tools.dynamic.length>0&&t.set(`dynamic`,e.tools.dynamic.map(e=>e.slug));let priority=e=>e===`agent`?0:e===`dynamic`?2:e===`eve`?3:1;return[...t].map(([e,t])=>({label:e,names:t.sort()})).sort((e,t)=>priority(e.label)-priority(t.label)||e.label.localeCompare(t.label))}function skillNames(e){return[...e.skills.static.map(e=>e.name),...e.skills.dynamic.map(e=>`${e.slug} (dynamic)`)].sort()}function subagentNames(e){return[...e.subagents.local,...e.remoteAgents.entries].map(e=>e.name).sort()}function formatInstructions(e,t){return fitNames([...e.instructions.static.map(e=>`${e.logicalPath} (${e.role})`),...e.instructions.dynamic.map(e=>`${e.slug} (dynamic)`)],t)}function fitNames(e,t){if(e.length===0)return`none`;for(let n=e.length;n>0;--n){let i=e.length-n,a=`${e.slice(0,n).join(`, `)}${i>0?`, +${i} more`:``}`;if(visibleLength(a)<=t)return a}return clipVisible(e[0],t)}function formatHeaderModel(e,t){if(e?.id===void 0)return;let n=e.endpoint;if(n===void 0)return e.id;let r=t.colors.dim(`via `);switch(n.kind){case`external`:return`${e.id} ${r}${n.provider}`;case`chatgpt`:return`${e.id} ${r}chatgpt-sub`;case`gateway`:return n.connected?`${e.id} ${r}ai-gateway(${n.credential})`:`${e.id} ${r}ai-gateway(not connected)`}}function renderTip(t,r,i){return clipVisible(t.split(/(\/[a-z:-]+)/u).map(t=>isPromptControlCommand(t)?i.colors.blue(t):i.colors.dim(t)).join(``),r)}function plural(e){return e===1?``:`s`}function pluralize(e,t){return`${t}${plural(e)}`}export{AGENT_HEADER_TIPS,buildAgentHeader,pickAgentHeaderTip};
@@ -13,6 +13,8 @@ export type PromptCommand = {
13
13
  type: "exit";
14
14
  } | {
15
15
  type: "help";
16
+ } | {
17
+ type: "info";
16
18
  } | {
17
19
  type: "loglevel";
18
20
  argument: string;
@@ -1,2 +1,2 @@
1
- const PROMPT_COMMAND_DEFINITIONS=[{name:`help`,aliases:[],description:`Show available commands`,takesArgument:!1,build:()=>({type:`help`}),targets:[`local`,`remote`]},{name:`reset`,aliases:[],description:`Start a fresh session`,takesArgument:!1,build:()=>({type:`reset`}),targets:[`local`,`remote`]},{name:`cancel`,aliases:[],description:`Cancel the running turn`,takesArgument:!1,build:()=>({type:`cancel`}),targets:[`local`,`remote`]},{name:`clear`,aliases:[`new`],description:`Clear the current session context`,takesArgument:!1,build:()=>({type:`clear`}),targets:[`local`,`remote`]},{name:`compact`,aliases:[],description:`Compact the current session context`,takesArgument:!1,build:()=>({type:`compact`}),targets:[`local`,`remote`]},{name:`vc:install`,aliases:[],description:`Install the Vercel CLI`,takesArgument:!1,build:()=>({type:`extension`,name:`vc:install`,argument:``}),targets:[`local`,`remote`]},{name:`vc:login`,aliases:[],description:`Authenticate with Vercel`,takesArgument:!1,build:()=>({type:`extension`,name:`vc:login`,argument:``}),targets:[`local`,`remote`]},{name:`model`,aliases:[],description:`Configure the agent's model and provider`,argumentHint:`[provider/model]`,takesArgument:!0,build:e=>({type:`extension`,name:`model`,argument:e}),targets:[`local`]},{name:`loglevel`,aliases:[],description:`Show or hide captured stdout/stderr/sandbox logs`,argumentHint:`[all|stderr|sandbox|none]`,takesArgument:!0,build:e=>({type:`loglevel`,argument:e}),targets:[`local`,`remote`]},{name:`traces`,aliases:[],description:`Open the local trace viewer`,argumentHint:`[trace]`,takesArgument:!0,build:e=>({type:`traces`,argument:e}),targets:[`local`]},{name:`add`,aliases:[],description:`Add an integration from the registry`,takesArgument:!0,build:e=>({type:`extension`,name:`add`,argument:e}),targets:[`local`]},{name:`deploy`,aliases:[],description:`Deploy the agent to Vercel`,takesArgument:!1,build:()=>({type:`extension`,name:`deploy`,argument:``}),targets:[`local`]},{name:`exit`,aliases:[`quit`],description:`Quit the TUI`,takesArgument:!1,build:()=>({type:`exit`}),targets:[`local`,`remote`]}],PROMPT_COMMANDS=PROMPT_COMMAND_DEFINITIONS;function promptCommandsFor(t){return PROMPT_COMMAND_DEFINITIONS.filter(e=>e.targets.some(e=>e===t))}function isPromptCommandAvailableFor(t,n){return(PROMPT_COMMAND_DEFINITIONS.find(e=>e.name===t)?.targets)?.includes(n)??!1}function parsePromptCommand(e){let n=e.trim();if(!n.startsWith(`/`))return null;for(let e of PROMPT_COMMANDS)for(let t of[e.name,...e.aliases]){let r=`/${t}`;if(n===r)return e.build(``);if(e.takesArgument&&n.startsWith(`${r} `))return e.build(n.slice(r.length).trim())}return null}function isPromptControlCommand(e){return parsePromptCommand(e)!==null}function formatPromptCommandHelp(e=PROMPT_COMMANDS){let n=e.map(e=>{let t=e.argumentHint===void 0?``:` ${e.argumentHint}`,n=e.aliases.map(e=>` (/${e})`).join(``);return{invocation:`/${e.name}${t}${n}`,description:e.description}}),r=Math.max(...n.map(e=>e.invocation.length))+2;return n.map(e=>e.invocation.padEnd(r)+e.description).join(`
1
+ const PROMPT_COMMAND_DEFINITIONS=[{name:`help`,aliases:[],description:`Show available commands`,takesArgument:!1,build:()=>({type:`help`}),targets:[`local`,`remote`]},{name:`info`,aliases:[],description:`Show application and messaging information`,takesArgument:!1,build:()=>({type:`info`}),targets:[`local`]},{name:`reset`,aliases:[],description:`Start a fresh session`,takesArgument:!1,build:()=>({type:`reset`}),targets:[`local`,`remote`]},{name:`cancel`,aliases:[],description:`Cancel the running turn`,takesArgument:!1,build:()=>({type:`cancel`}),targets:[`local`,`remote`]},{name:`clear`,aliases:[`new`],description:`Clear the current session context`,takesArgument:!1,build:()=>({type:`clear`}),targets:[`local`,`remote`]},{name:`compact`,aliases:[],description:`Compact the current session context`,takesArgument:!1,build:()=>({type:`compact`}),targets:[`local`,`remote`]},{name:`vc:install`,aliases:[],description:`Install the Vercel CLI`,takesArgument:!1,build:()=>({type:`extension`,name:`vc:install`,argument:``}),targets:[`local`,`remote`]},{name:`vc:login`,aliases:[],description:`Authenticate with Vercel`,takesArgument:!1,build:()=>({type:`extension`,name:`vc:login`,argument:``}),targets:[`local`,`remote`]},{name:`model`,aliases:[],description:`Configure the agent's model and provider`,argumentHint:`[provider/model]`,takesArgument:!0,build:e=>({type:`extension`,name:`model`,argument:e}),targets:[`local`]},{name:`loglevel`,aliases:[],description:`Show or hide captured stdout/stderr/sandbox logs`,argumentHint:`[all|stderr|sandbox|none]`,takesArgument:!0,build:e=>({type:`loglevel`,argument:e}),targets:[`local`,`remote`]},{name:`traces`,aliases:[],description:`Open the local trace viewer`,argumentHint:`[trace]`,takesArgument:!0,build:e=>({type:`traces`,argument:e}),targets:[`local`]},{name:`add`,aliases:[],description:`Add an integration from the registry`,takesArgument:!0,build:e=>({type:`extension`,name:`add`,argument:e}),targets:[`local`]},{name:`deploy`,aliases:[],description:`Deploy the agent to Vercel`,takesArgument:!1,build:()=>({type:`extension`,name:`deploy`,argument:``}),targets:[`local`]},{name:`exit`,aliases:[`quit`],description:`Quit the TUI`,takesArgument:!1,build:()=>({type:`exit`}),targets:[`local`,`remote`]}],PROMPT_COMMANDS=PROMPT_COMMAND_DEFINITIONS;function promptCommandsFor(t){return PROMPT_COMMAND_DEFINITIONS.filter(e=>e.targets.some(e=>e===t))}function isPromptCommandAvailableFor(t,n){return(PROMPT_COMMAND_DEFINITIONS.find(e=>e.name===t)?.targets)?.includes(n)??!1}function parsePromptCommand(e){let n=e.trim();if(!n.startsWith(`/`))return null;for(let e of PROMPT_COMMANDS)for(let t of[e.name,...e.aliases]){let r=`/${t}`;if(n===r)return e.build(``);if(e.takesArgument&&n.startsWith(`${r} `))return e.build(n.slice(r.length).trim())}return null}function isPromptControlCommand(e){return parsePromptCommand(e)!==null}function formatPromptCommandHelp(e=PROMPT_COMMANDS){let n=e.map(e=>{let t=e.argumentHint===void 0?``:` ${e.argumentHint}`,n=e.aliases.map(e=>` (/${e})`).join(``);return{invocation:`/${e.name}${t}${n}`,description:e.description}}),r=Math.max(...n.map(e=>e.invocation.length))+2;return n.map(e=>e.invocation.padEnd(r)+e.description).join(`
2
2
  `)}export{PROMPT_COMMANDS,formatPromptCommandHelp,isPromptCommandAvailableFor,isPromptControlCommand,parsePromptCommand,promptCommandsFor};
@@ -1,4 +1,5 @@
1
1
  import { type AgentInfoResult, type ConnectionAuthorizationOutcome, type InputRequest, Client, ClientSession } from "#client/index.js";
2
+ import { inspectApplication } from "#services/inspect-application.js";
2
3
  import { type SubagentView } from "./subagent-pump.js";
3
4
  export type { SubagentRun, SubagentStepUpdate, SubagentToolUpdate, SubagentView, } from "./subagent-pump.js";
4
5
  import { type DevBootProgressReporter } from "#internal/dev-boot-progress.js";
@@ -151,15 +152,14 @@ export type AgentTUIAgentHeader = {
151
152
  name: string;
152
153
  serverUrl: string;
153
154
  info?: AgentInfoResult;
154
- /** Message-of-the-day line shown under the brand line (local sessions only). */
155
+ /** Message-of-the-day line shown below the startup card (local sessions only). */
155
156
  tip?: string;
156
157
  };
157
158
  export type AgentTUIRenderer = {
158
159
  /**
159
- * Commits a startup header describing the connected agent (brand mark,
160
- * model, instructions, tools, skills, subagents) to the transcript before
161
- * the first prompt, and refreshes it after local dev artifact changes.
162
- * Optional — renderers without a header simply skip it.
160
+ * Commits the startup card to the transcript before the first prompt and
161
+ * refreshes it after local dev artifact changes. Optional — renderers
162
+ * without a header simply skip it.
163
163
  */
164
164
  renderAgentHeader?(header: AgentTUIAgentHeader): void;
165
165
  /**
@@ -370,6 +370,8 @@ export type EveTUIRunnerOptions = TuiDisplayOptions & {
370
370
  bootDetections?: readonly BootDetection[];
371
371
  /** Test seam for the status line's Vercel link probe; defaults to the real one. */
372
372
  detectProjectIdentity?: typeof detectProjectIdentity;
373
+ /** Test seam for `/info`; defaults to the filesystem application inspector. */
374
+ inspectApplication?: typeof inspectApplication;
373
375
  /** Test seam for the off-critical-path boot login probe; defaults to the real one. */
374
376
  getVercelAuthStatus?: typeof getVercelAuthStatus;
375
377
  /** Reports phases from this runner's initial local-dev connection. */