eve 0.39.2 → 0.40.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. package/CHANGELOG.md +24 -1
  2. package/dist/src/channel/delivery-metadata.js +1 -1
  3. package/dist/src/cli/commands/registry.js +1 -1
  4. package/dist/src/cli/dev/tui/tool-presentation.js +1 -1
  5. package/dist/src/cli/run.js +1 -1
  6. package/dist/src/compiled/.vendor-stamp.json +6 -6
  7. package/dist/src/compiled/@workflow/core/create-hook.d.ts +9 -5
  8. package/dist/src/compiled/@workflow/core/index.js +2 -2
  9. package/dist/src/compiled/@workflow/core/private.d.ts +31 -12
  10. package/dist/src/compiled/@workflow/core/private.js +1 -1
  11. package/dist/src/compiled/@workflow/core/runtime/constants.d.ts +27 -0
  12. package/dist/src/compiled/@workflow/core/runtime/quickjs-entrypoint.d.ts +2 -0
  13. package/dist/src/compiled/@workflow/core/runtime/step-executor.d.ts +49 -1
  14. package/dist/src/compiled/@workflow/core/runtime/step-latency.d.ts +6 -0
  15. package/dist/src/compiled/@workflow/core/runtime/suspension-handler.d.ts +81 -1
  16. package/dist/src/compiled/@workflow/core/runtime.js +3 -3
  17. package/dist/src/compiled/@workflow/core/serialization.d.ts +10 -2
  18. package/dist/src/compiled/@workflow/core/telemetry.d.ts +6 -0
  19. package/dist/src/compiled/@workflow/core/version.d.ts +1 -1
  20. package/dist/src/compiled/@workflow/core/workflow.js +1 -1
  21. package/dist/src/compiled/@workflow/world/env-config.d.ts +10 -0
  22. package/dist/src/compiled/@workflow/world/events.d.ts +96 -0
  23. package/dist/src/compiled/@workflow/world/index.d.ts +2 -1
  24. package/dist/src/compiled/@workflow/world/interfaces.d.ts +38 -1
  25. package/dist/src/compiled/@workflow/world/node-http-flag.d.ts +41 -0
  26. package/dist/src/compiled/@workflow/world/node-http.d.ts +81 -0
  27. package/dist/src/compiled/@workflow/world-local/index.js +5 -5
  28. package/dist/src/compiled/@workflow/world-vercel/index.js +12 -12
  29. package/dist/src/compiled/_chunks/workflow/{attribute-changes-B8K0pwpH.js → attribute-changes-DXbpwBdw.js} +2 -2
  30. package/dist/src/compiled/_chunks/workflow/{dist-BRGbNjhD.js → dist-Dk0aQqFO.js} +1 -1
  31. package/dist/src/compiled/_chunks/workflow/{env-config-DxamfI7T.js → env-config-L94XftKz.js} +1 -1
  32. package/dist/src/compiled/_chunks/workflow/frames-Dl2Hcma4.js +3 -0
  33. package/dist/src/compiled/_chunks/workflow/{private-z_2Kcwee.js → private-CuQ4HTFC.js} +1 -1
  34. package/dist/src/compiled/_chunks/workflow/resume-hook-E-Nkx8q_.js +1 -0
  35. package/dist/src/compiled/_chunks/workflow/run-cIeex2KF.js +1 -0
  36. package/dist/src/compiled/_chunks/workflow/sleep-CxFsdxB_.js +1 -0
  37. package/dist/src/compiled/_chunks/workflow/undici-DznrXKcM.js +95 -0
  38. package/dist/src/compiled/_chunks/workflow/wait-until-BZHmJCAW.js +15 -0
  39. package/dist/src/compiled/_chunks/workflow/{ws-transport-TYZ9zwoZ.js → ws-transport-Ct6yyRWZ.js} +1 -1
  40. package/dist/src/compiled/shadcn-registry/index.d.ts +1 -0
  41. package/dist/src/compiled/shadcn-registry/index.js +285 -379
  42. package/dist/src/compiler/extension-compatibility.d.ts +2 -2
  43. package/dist/src/compiler/extension-compatibility.js +1 -1
  44. package/dist/src/execution/parked-delivery-wait.js +1 -1
  45. package/dist/src/execution/proxied-deliver-step.js +1 -1
  46. package/dist/src/execution/report-dropped-wire-payload-step.d.ts +13 -0
  47. package/dist/src/execution/report-dropped-wire-payload-step.js +1 -0
  48. package/dist/src/execution/sandbox/bindings/just-bash-runtime.js +1 -1
  49. package/dist/src/execution/sandbox/logging-session.js +1 -1
  50. package/dist/src/execution/session-command-inbox.d.ts +3 -5
  51. package/dist/src/execution/session-command-inbox.js +1 -1
  52. package/dist/src/execution/session-timeout-steps.js +1 -1
  53. package/dist/src/execution/tasks/child/steps.d.ts +1 -0
  54. package/dist/src/execution/tasks/child/steps.js +1 -1
  55. package/dist/src/execution/tasks/parent/control-shared.d.ts +1 -1
  56. package/dist/src/execution/tasks/parent/dispatch-task-step.d.ts +1 -1
  57. package/dist/src/execution/tasks/parent/dispatch.js +1 -1
  58. package/dist/src/execution/turn-control-receiver.js +1 -1
  59. package/dist/src/execution/wire/session-inbox-contract.d.ts +24 -0
  60. package/dist/src/execution/wire/session-inbox-contract.js +1 -0
  61. package/dist/src/execution/wire/session-inbox-encoder.d.ts +23 -0
  62. package/dist/src/execution/wire/session-inbox-encoder.js +1 -0
  63. package/dist/src/execution/wire/session-inbox-resume.d.ts +10 -0
  64. package/dist/src/execution/wire/session-inbox-resume.js +1 -0
  65. package/dist/src/execution/wire/session-inbox-wire.d.ts +29 -0
  66. package/dist/src/execution/wire/session-inbox-wire.js +1 -0
  67. package/dist/src/execution/wire/session-inbox-wire.v0.d.ts +5 -0
  68. package/dist/src/execution/wire/session-inbox-wire.v0.js +1 -0
  69. package/dist/src/execution/wire/session-inbox-wire.v1.d.ts +237 -0
  70. package/dist/src/execution/wire/session-inbox-wire.v1.js +1 -0
  71. package/dist/src/execution/workflow-runtime.js +1 -1
  72. package/dist/src/harness/execute-tool.d.ts +1 -1
  73. package/dist/src/internal/application/package.js +1 -1
  74. package/dist/src/internal/authored-module-loader.js +3 -3
  75. package/dist/src/internal/nitro/host/extension-external-dependency-plugin.js +1 -1
  76. package/dist/src/public/channels/eve.js +1 -1
  77. package/dist/src/public/channels/slack/slackChannel.d.ts +3 -1
  78. package/dist/src/public/channels/slack/slackChannel.js +1 -1
  79. package/dist/src/public/definitions/channel.d.ts +2 -0
  80. package/dist/src/public/definitions/channel.js +1 -1
  81. package/dist/src/public/sandbox/just-bash-sandbox.d.ts +2 -0
  82. package/dist/src/runtime/actions/types.js +1 -1
  83. package/dist/src/runtime/framework-tools/tasks.d.ts +1 -5
  84. package/dist/src/runtime/framework-tools/tasks.js +1 -1
  85. package/dist/src/runtime/prompt/compose.js +1 -1
  86. package/dist/src/runtime/session-callback-route.js +1 -1
  87. package/dist/src/runtime/task-input-response-route.js +1 -1
  88. package/dist/src/setup/scaffold/create/project.js +1 -1
  89. package/dist/src/shared/empty-delivery.d.ts +1 -1
  90. package/dist/src/shared/empty-delivery.js +1 -1
  91. package/docs/meta.json +2 -1
  92. package/package.json +7 -6
  93. package/dist/src/compiled/_chunks/workflow/frames-DoexhtxJ.js +0 -3
  94. package/dist/src/compiled/_chunks/workflow/resume-hook-DO_MuJlY.js +0 -1
  95. package/dist/src/compiled/_chunks/workflow/run-lq7-eG0l.js +0 -1
  96. package/dist/src/compiled/_chunks/workflow/sleep-7TgF3i-e.js +0 -1
  97. package/dist/src/compiled/_chunks/workflow/undici-BBG5cZTy.js +0 -95
  98. package/dist/src/compiled/_chunks/workflow/wait-until-BPSgt1Wg.js +0 -15
  99. package/dist/src/execution/session-command-wire.d.ts +0 -24
  100. package/dist/src/execution/session-command-wire.js +0 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,28 @@
1
1
  # eve
2
2
 
3
+ ## 0.40.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 2838bb3: Remove `task_peek` from experimental background tasks and include completed results and failures directly in task notifications. Conditionally delivered task wakes can remain silent when that result was already covered by an earlier response.
8
+
9
+ ### Patch Changes
10
+
11
+ - e843b4d: Registry browsing now uses titles returned by the catalog, avoiding a separate request for every displayed item.
12
+ - 899e079: Keep `eve info --json` output valid JSON by omitting the CLI banner.
13
+ - cda9539: Redact brokered credential transforms when sandbox network policies are written to bootstrap logs.
14
+ - 87c61a1: Update eve's bundled Workflow SDK packages to the latest 5.0.0 beta releases, picking up a replay-determinism fix for branch wake order under concurrent replays.
15
+
16
+ ## 0.39.3
17
+
18
+ ### Patch Changes
19
+
20
+ - c2bfee1: Keep top-level sessions in an independent `agent.session` trace while preserving shared trace context for local and remote subagents.
21
+ - 9a7964b: Add a configurable, development-only `@eve/self-modification` source-editing subagent that mounts authored agent source read-write, exposes its instructions through an extension, and uses structured file tools to inspect and safely update source.
22
+ - 542c380: Preserve the configured `turnPolicy` on built-in and custom channels, and restore the option for Slack channels.
23
+ - 75bd9c8: Allow extension-owned external dependencies to use ESM-only packages that do not expose a CommonJS entry.
24
+ - 6fc904d: Session inbox hook payloads are now a validated, versioned wire format following eve's existing durable-format idioms. Producers inspect the target hook's wire capability and encode the shape its pinned consumer understands, including sessions created by eve 0.30.8; readers migrate legacy shapes forward and reject unknown versions instead of reinterpreting them.
25
+
3
26
  ## 0.39.2
4
27
 
5
28
  ### Patch Changes
@@ -239,7 +262,7 @@
239
262
 
240
263
  ### Patch Changes
241
264
 
242
- - 2a141f0: Keep sessions resumable across eve deployment upgrades: sends now cross durable session hooks as the established `deliver` envelope (with a transitional single-payload mirror for sessions pinned to 0.30.3–0.30.8), and consumers keep accepting payloads persisted by those versions.
265
+ - 2a141f0: Keep sessions resumable across eve deployment upgrades: sends now cross durable session hooks as the established `deliver` envelope (with a transitional single-payload mirror for sessions pinned to 0.30.5–0.30.8), and consumers keep accepting payloads persisted by those versions.
243
266
  - 99982f7: Treat AI SDK `.devtools` like other generated directories: ignore it in `eve dev` watching, agent discovery, and source snapshots so generation writes do not recompile or warn.
244
267
  - a497e8d: Preserve each tool executor's concrete return type through `defineTool`, so non-streaming tools no longer appear to return an async iterable. Allow `ctx.to()` to infer closed receive-target interfaces such as Slack's without requiring an index signature.
245
268
  - fe9e7ef: Consume interactive authorization callback results once and keep targeted connection searches from replaying callbacks for unrelated connections.
@@ -1 +1 @@
1
- function createChannelDeliveryMetadata(e){return{...e,deliveryId:crypto.randomUUID()}}export{createChannelDeliveryMetadata};
1
+ function createChannelDeliveryMetadata(e){let t={channelKind:e.channelKind,channelName:e.channelName,deliveryId:crypto.randomUUID()};return e.requestId!==void 0&&(t.requestId=e.requestId),e.requestTraceContext!==void 0&&(t.requestTraceContext=e.requestTraceContext),t}export{createChannelDeliveryMetadata};
@@ -1 +1 @@
1
- import{hasInteractiveTerminal}from"./preconditions.js";import{reportHeadlessSetupCompletion,serializeHeadlessSetupEvent}from"./setup-headless.js";import{runDeclaredSetups}from"./registry-declared-setups.js";import{runRegistryPackage}from"./registry-package.js";import{eveMetadataFromRegistryItem,parseOfficialRegistrySearchMetadata}from"./registry-metadata.js";import{printRegistrySearchResults,registryViewText}from"./registry-presentation.js";import{addRegistryMappings,readRegistryConfig}from"./registry-project.js";import{errorMessage,resolveRegistryItemForAdd,runRegistryAction,setupReminder,setupResumeCommand}from"./registry-recovery.js";import{resolveInstalledPackageInfo}from"#internal/application/package.js";import{createPrompter}from"#setup/prompter.js";import{WizardCancelledError}from"#setup/step.js";import{addRegistryItems,getRegistryItems,searchRegistries}from"#compiled/shadcn-registry/index.js";import semver from"#compiled/semver/index.js";const defaultAddCommandDependencies={createPrompter,hasInteractiveTerminal,loadSetupCommandRunner:async()=>(await import(`./registry-setup-command.js`)).runRegistrySetupCommand};function resolveOfficialRegistryUrl(e=process.env.EVE_DEV_OFFICIAL_REGISTRY_URL){if(e===void 0)return`https://eve.dev/r`;let t;try{t=new URL(e)}catch{throw Error(`EVE_DEV_OFFICIAL_REGISTRY_URL must be an HTTP(S) URL.`)}if(t.protocol!==`http:`&&t.protocol!==`https:`)throw Error(`EVE_DEV_OFFICIAL_REGISTRY_URL must be an HTTP(S) URL.`);if(t.username!==``||t.password!==``)throw Error(`EVE_DEV_OFFICIAL_REGISTRY_URL must not include credentials.`);if(t.search!==``||t.hash!==``)throw Error(`EVE_DEV_OFFICIAL_REGISTRY_URL must not include a query or fragment.`);return t.pathname=t.pathname.replace(/\/+$/,``),t.toString().replace(/\/$/,``)}const OFFICIAL_REGISTRY=resolveOfficialRegistryUrl(),OFFICIAL_CATALOG=`${OFFICIAL_REGISTRY}/registry.json`,SKILLS_REGISTRY=`@skills`;function isRegistryAddress(e){return e.startsWith(`@`)||/^https?:\/\//.test(e)}function itemAddress(e){return isRegistryAddress(e)?e:`${OFFICIAL_REGISTRY}/${e}.json`}async function installOfficialRegistryItem(e,t,n={}){let r=await readEveRegistryConfig(e);await addRegistryItems([itemAddress(t)],{config:r,cwd:e,overwrite:n.overwrite})}function assertCompatibleEveVersion(e){if(e===void 0)return;let t=resolveInstalledPackageInfo().version;if(semver.validRange(e)===null)throw Error(`Registry item has an invalid eve version requirement: ${e}.`);if(!semver.subset(t,e))throw Error(`This registry item requires eve ${e}, but this project is using eve ${t}. Upgrade eve and run the command again.`)}function isOfficialItemAddress(e){return e.startsWith(`${OFFICIAL_REGISTRY}/`)}function withBuiltInRegistries(e){return{...e,registries:{[SKILLS_REGISTRY]:`https://www.skills.sh/r/{name}?agent=eve`,...e.registries}}}async function readEveRegistryConfig(e){return withBuiltInRegistries(await readRegistryConfig(e))}function configuredRegistrySources(e){return Object.keys(e.registries??{})}function validateRegistrySource(e){if(e!==void 0&&!isRegistryAddress(e))throw Error(`Registry sources must be a namespace or URL: ${e}`)}async function loadOfficialSearchMetadata(){let e=await fetch(OFFICIAL_CATALOG);if(!e.ok)throw Error(`Could not read the eve registry (${e.status}).`);return parseOfficialRegistrySearchMetadata(await e.json())}function searchItemAddress(e){return e.registry===OFFICIAL_CATALOG?e.name:e.addCommandArgument}function enrichSearchItem(e,t){let n=searchItemAddress(e);return{item:e,address:n,...t.get(n)}}function registrySourceLabel(e){return e===OFFICIAL_CATALOG?`eve`:e===SKILLS_REGISTRY?`skills.sh`:e}function searchPresentationSections(e,t,n){return e.flatMap(e=>{let r=t.get(e);return r===void 0?[]:[{label:registrySourceLabel(e),items:r.items.map(e=>enrichSearchItem(e,n)),total:r.pagination.total}]})}async function printAddSuggestions(e,t,n){try{let r=n.split(`/`).at(-1)||n,{resultsBySource:i,sources:a,metadataByAddress:o}=await searchRegistryCatalog(t,{limit:5,query:r}),c=searchPresentationSections(a,i,o);if(c.every(e=>e.items.length===0))return;e.log(`Did you mean?`),printRegistrySearchResults(e,{query:r,sections:c})}catch{}}async function searchRegistryCatalog(e,t){validateRegistrySource(t.source);let n=await readEveRegistryConfig(e),r=t.source?[t.source]:[OFFICIAL_CATALOG,...configuredRegistrySources(n).filter(e=>t.query!==void 0||e!==SKILLS_REGISTRY)],i=await Promise.all(r.map(async e=>{try{return{result:await searchRegistries([e],{config:n,limit:t.limit??100,query:t.query}),source:e}}catch(t){return{error:t,source:e}}})),a=[],o=new Map;for(let e of i)if(`error`in e)a.push({message:errorMessage(e.error),registry:e.source});else{let t=e.result.errors??[];if(a.push(...t),t.length===0){let t=e.result.items.filter(t=>t.registry===e.source);o.set(e.source,{...e.result,items:t,pagination:{...e.result.pagination,total:e.result.items.length===t.length?e.result.pagination.total:0}})}}let s=new Map(a.map(e=>[`${e.registry}\0${e.message}`,e])),c=o.has(OFFICIAL_CATALOG)?await loadOfficialSearchMetadata():new Map,l=o.get(OFFICIAL_CATALOG);l!==void 0&&l.items.sort((e,t)=>{let rank=e=>c.get(searchItemAddress(e))?.implementation===`native`?0:1;return rank(e)-rank(t)});let u=[...o.values()];return{config:n,result:{items:u.flatMap(e=>e.items),pagination:{hasMore:u.some(e=>e.pagination.hasMore),limit:t.limit??100,offset:0,total:u.reduce((e,t)=>e+t.pagination.total,0)},...s.size>0?{errors:[...s.values()]}:{}},resultsBySource:o,sources:r,metadataByAddress:c}}function registryManifestTitle(e){if(typeof e!=`object`||!e||Array.isArray(e))return;let t=e.title;return typeof t==`string`?t:void 0}async function browseRegistryCatalog(e,t={}){let{config:n,result:r}=await searchRegistryCatalog(e,t),i=await Promise.all(r.items.map(async e=>{let[t]=await getRegistryItems([e.addCommandArgument],{config:n});return t}));return{items:r.items.map((e,t)=>{let n={address:e.registry===OFFICIAL_CATALOG?e.name:e.addCommandArgument,name:e.name,source:e.registry===OFFICIAL_CATALOG?`Vercel`:e.registry},r=registryManifestTitle(i[t]);return r!==void 0&&(n.title=r),e.type!==void 0&&(n.type=e.type),e.description!==void 0&&(n.description=e.description),n}),total:r.pagination.total,errors:r.errors??[]}}async function browseRegistryItems(e,t,n,r,i={}){let{result:a,resultsBySource:o,sources:c,metadataByAddress:l}=await searchRegistryCatalog(t,{limit:i.limit,query:n,source:r}),u=a.errors??[];if(i.json||o.size>0){let t=a.items.map(e=>({...e,...l.get(searchItemAddress(e))})),r={query:n,sections:searchPresentationSections(c,o,l)};i.json&&(r.json={...a,items:t}),printRegistrySearchResults(e,r)}for(let t of u)e.error(`${t.registry}: ${t.message}`);u.length>0&&(process.exitCode=1)}async function getRegistryItemManifest(e,t){let n=await readEveRegistryConfig(e),r=await getRegistryItems([itemAddress(t)],{config:n});return r.length===1?r[0]:r}async function installRegistryItem(e,t,n={},r=defaultAddCommandDependencies){let i,a=[],o={error:e=>{i=e},log:e=>a.push(e)},s=process.exitCode,c=await runAddCommand(o,e,t,{...n,yes:n.prompter===void 0||n.yes,setupAuthorized:n.prompter!==void 0},r);if(process.exitCode=s,i!==void 0)throw Error(i);let l={output:a};return c!==void 0&&(l.setup=c),l}async function runAddCommand(e,t,o,s,c=defaultAddCommandDependencies){return runRegistryAction(e,t,async()=>{let l=await readEveRegistryConfig(t),u=itemAddress(o);if(s.skipInstall===!0){if(s.overwrite===!0)throw Error(`--overwrite cannot be used with --skip-install.`);if(s.skipSetup===!0)throw Error(`--skip-install cannot be used with --skip-setup.`);if(!isOfficialItemAddress(u))throw Error(`Setup flows are currently supported only for official eve registry items.`)}let d=await resolveRegistryItemForAdd(e,async()=>(await getRegistryItems([u],{config:l}))[0],()=>printAddSuggestions(e,t,o));if(!d.found)return;let f=d.item,p=isOfficialItemAddress(u)?eveMetadataFromRegistryItem(f):void 0;if(assertCompatibleEveVersion(p?.requires),p?.components!==void 0){if(!isOfficialItemAddress(u))throw Error(`Registry packages require the official eve registry.`);return reportCompletion(e,o,await runRegistryPackage({logger:e,appRoot:t,item:o,components:p.components,config:l,options:s,dependencies:c,operations:{itemAddress,metadata:eveMetadataFromRegistryItem,assertCompatibleVersion:assertCompatibleEveVersion,runSetups:({item:n,setups:i,prompter:a})=>runDeclaredSetups({logger:e,appRoot:t,item:n,setups:i,options:{yes:s.yes,nonInteractive:s.nonInteractive,answers:s.answers,prompter:a,signal:s.signal},dependencies:c,cancelledReminder:setupReminder(n,`cancelled`),resumeCommand:setupResumeCommand(n)}),setupReminder:e=>setupReminder(e,`skipped`)}}),s)}if(s.skipInstall===!0){if(p?.setup===void 0)throw Error(`Registry item "${o}" does not declare a setup flow.`);return reportCompletion(e,o,await runDeclaredSetups({logger:e,appRoot:t,item:o,setups:p.setup,options:s,dependencies:c,cancelledReminder:setupReminder(o,`cancelled`),resumeCommand:setupResumeCommand(o)}),s)}if(await addRegistryItems([u],{config:l,cwd:t,overwrite:s.overwrite,silent:s.silent}),p?.setup===void 0)return reportCompletion(e,o,{facts:[]},s);let m=c.hasInteractiveTerminal?.()??defaultAddCommandDependencies.hasInteractiveTerminal();if(s.nonInteractive&&e.log(serializeHeadlessSetupEvent({version:1,type:`progress`,message:s.skipInstall?`Setup ${o}`:`Installed ${o}`})),s.skipSetup===!0){if(s.nonInteractive)return reportCompletion(e,o,{facts:[]},s);e.log(setupReminder(o,`skipped`));return}if(!s.nonInteractive&&!s.yes&&!m&&s.setupAuthorized!==!0){e.log(setupReminder(o,`skipped`));return}if(!s.nonInteractive&&!s.yes&&s.setupAuthorized!==!0)try{if(await(s.prompter??c.createPrompter?.()??defaultAddCommandDependencies.createPrompter()).select({message:`Set up ${o} now?`,initialValue:`yes`,options:[{value:`yes`,label:`Yes`},{value:`no`,label:`No`}]})===`no`){e.log(setupReminder(o,`skipped`));return}}catch(t){if(!(t instanceof WizardCancelledError))throw t;e.log(setupReminder(o,`cancelled`));return}return reportCompletion(e,o,await runDeclaredSetups({logger:e,appRoot:t,item:o,setups:p.setup,options:s,dependencies:c,cancelledReminder:setupReminder(o,`cancelled`),resumeCommand:setupResumeCommand(o)}),s)})}function reportCompletion(e,n,r,i){return reportHeadlessSetupCompletion({logger:e,item:n,completion:r,nonInteractive:i.nonInteractive})}async function runRegistryAddCommand(e,t,n){await runRegistryAction(e,t,async()=>{let r=await addRegistryMappings(t,n);for(let t of r.skippedBuiltIn)e.log(`Skipped ${t} because it is built in.`);for(let t of r.skippedExisting)e.log(`Skipped ${t} because it is already configured.`);r.added.length>0&&e.log(`Added ${r.added.join(`, `)} to package.json.`)})}async function runRegistryListCommand(e,t,n,r={}){await runRegistryAction(e,t,()=>browseRegistryItems(e,t,void 0,n,r))}async function runRegistrySearchCommand(e,t,n,r,i={}){await runRegistryAction(e,t,()=>browseRegistryItems(e,t,n,r,{...i,limit:i.limit??10}))}async function runRegistryViewCommand(e,t,n,r={}){await runRegistryAction(e,t,async()=>{let i=await readEveRegistryConfig(t),a=await getRegistryItems([itemAddress(n)],{config:i}),o=a.length===1?a[0]:a;e.log(r.json?JSON.stringify(o,null,2):registryViewText(n,o))})}export{browseRegistryCatalog,getRegistryItemManifest,installOfficialRegistryItem,installRegistryItem,resolveOfficialRegistryUrl,runAddCommand,runRegistryAddCommand,runRegistryListCommand,runRegistrySearchCommand,runRegistryViewCommand};
1
+ import{hasInteractiveTerminal}from"./preconditions.js";import{reportHeadlessSetupCompletion,serializeHeadlessSetupEvent}from"./setup-headless.js";import{runDeclaredSetups}from"./registry-declared-setups.js";import{runRegistryPackage}from"./registry-package.js";import{eveMetadataFromRegistryItem,parseOfficialRegistrySearchMetadata}from"./registry-metadata.js";import{printRegistrySearchResults,registryViewText}from"./registry-presentation.js";import{addRegistryMappings,readRegistryConfig}from"./registry-project.js";import{errorMessage,resolveRegistryItemForAdd,runRegistryAction,setupReminder,setupResumeCommand}from"./registry-recovery.js";import{resolveInstalledPackageInfo}from"#internal/application/package.js";import{createPrompter}from"#setup/prompter.js";import{WizardCancelledError}from"#setup/step.js";import{addRegistryItems,getRegistryItems,searchRegistries}from"#compiled/shadcn-registry/index.js";import semver from"#compiled/semver/index.js";const defaultAddCommandDependencies={createPrompter,hasInteractiveTerminal,loadSetupCommandRunner:async()=>(await import(`./registry-setup-command.js`)).runRegistrySetupCommand};function resolveOfficialRegistryUrl(e=process.env.EVE_DEV_OFFICIAL_REGISTRY_URL){if(e===void 0)return`https://eve.dev/r`;let t;try{t=new URL(e)}catch{throw Error(`EVE_DEV_OFFICIAL_REGISTRY_URL must be an HTTP(S) URL.`)}if(t.protocol!==`http:`&&t.protocol!==`https:`)throw Error(`EVE_DEV_OFFICIAL_REGISTRY_URL must be an HTTP(S) URL.`);if(t.username!==``||t.password!==``)throw Error(`EVE_DEV_OFFICIAL_REGISTRY_URL must not include credentials.`);if(t.search!==``||t.hash!==``)throw Error(`EVE_DEV_OFFICIAL_REGISTRY_URL must not include a query or fragment.`);return t.pathname=t.pathname.replace(/\/+$/,``),t.toString().replace(/\/$/,``)}const OFFICIAL_REGISTRY=resolveOfficialRegistryUrl(),OFFICIAL_CATALOG=`${OFFICIAL_REGISTRY}/registry.json`,SKILLS_REGISTRY=`@skills`;function isRegistryAddress(e){return e.startsWith(`@`)||/^https?:\/\//.test(e)}function itemAddress(e){return isRegistryAddress(e)?e:`${OFFICIAL_REGISTRY}/${e}.json`}async function installOfficialRegistryItem(e,t,n={}){let r=await readEveRegistryConfig(e);await addRegistryItems([itemAddress(t)],{config:r,cwd:e,overwrite:n.overwrite})}function assertCompatibleEveVersion(e){if(e===void 0)return;let t=resolveInstalledPackageInfo().version;if(semver.validRange(e)===null)throw Error(`Registry item has an invalid eve version requirement: ${e}.`);if(!semver.subset(t,e))throw Error(`This registry item requires eve ${e}, but this project is using eve ${t}. Upgrade eve and run the command again.`)}function isOfficialItemAddress(e){return e.startsWith(`${OFFICIAL_REGISTRY}/`)}function withBuiltInRegistries(e){return{...e,registries:{[SKILLS_REGISTRY]:`https://www.skills.sh/r/{name}?agent=eve`,...e.registries}}}async function readEveRegistryConfig(e){return withBuiltInRegistries(await readRegistryConfig(e))}function configuredRegistrySources(e){return Object.keys(e.registries??{})}function validateRegistrySource(e){if(e!==void 0&&!isRegistryAddress(e))throw Error(`Registry sources must be a namespace or URL: ${e}`)}async function loadOfficialSearchMetadata(){let e=await fetch(OFFICIAL_CATALOG);if(!e.ok)throw Error(`Could not read the eve registry (${e.status}).`);return parseOfficialRegistrySearchMetadata(await e.json())}function searchItemAddress(e){return e.registry===OFFICIAL_CATALOG?e.name:e.addCommandArgument}function enrichSearchItem(e,t){let n=searchItemAddress(e);return{item:e,address:n,...t.get(n)}}function registrySourceLabel(e){return e===OFFICIAL_CATALOG?`eve`:e===SKILLS_REGISTRY?`skills.sh`:e}function searchPresentationSections(e,t,n){return e.flatMap(e=>{let r=t.get(e);return r===void 0?[]:[{label:registrySourceLabel(e),items:r.items.map(e=>enrichSearchItem(e,n)),total:r.pagination.total}]})}async function printAddSuggestions(e,t,n){try{let r=n.split(`/`).at(-1)||n,{resultsBySource:i,sources:a,metadataByAddress:o}=await searchRegistryCatalog(t,{limit:5,query:r}),c=searchPresentationSections(a,i,o);if(c.every(e=>e.items.length===0))return;e.log(`Did you mean?`),printRegistrySearchResults(e,{query:r,sections:c})}catch{}}async function searchRegistryCatalog(e,t){validateRegistrySource(t.source);let n=await readEveRegistryConfig(e),r=t.source?[t.source]:[OFFICIAL_CATALOG,...configuredRegistrySources(n).filter(e=>t.query!==void 0||e!==SKILLS_REGISTRY)],i=await Promise.all(r.map(async e=>{try{return{result:await searchRegistries([e],{config:n,limit:t.limit??100,query:t.query}),source:e}}catch(t){return{error:t,source:e}}})),a=[],o=new Map;for(let e of i)if(`error`in e)a.push({message:errorMessage(e.error),registry:e.source});else{let t=e.result.errors??[];if(a.push(...t),t.length===0){let t=e.result.items.filter(t=>t.registry===e.source);o.set(e.source,{...e.result,items:t,pagination:{...e.result.pagination,total:e.result.items.length===t.length?e.result.pagination.total:0}})}}let s=new Map(a.map(e=>[`${e.registry}\0${e.message}`,e])),c=o.has(OFFICIAL_CATALOG)?await loadOfficialSearchMetadata():new Map,l=o.get(OFFICIAL_CATALOG);l!==void 0&&l.items.sort((e,t)=>{let rank=e=>c.get(searchItemAddress(e))?.implementation===`native`?0:1;return rank(e)-rank(t)});let u=[...o.values()];return{config:n,result:{items:u.flatMap(e=>e.items),pagination:{hasMore:u.some(e=>e.pagination.hasMore),limit:t.limit??100,offset:0,total:u.reduce((e,t)=>e+t.pagination.total,0)},...s.size>0?{errors:[...s.values()]}:{}},resultsBySource:o,sources:r,metadataByAddress:c}}async function browseRegistryCatalog(e,t={}){let{result:n}=await searchRegistryCatalog(e,t);return{items:n.items.map(e=>{let t={address:e.registry===OFFICIAL_CATALOG?e.name:e.addCommandArgument,name:e.name,source:e.registry===OFFICIAL_CATALOG?`Vercel`:e.registry};return e.title!==void 0&&(t.title=e.title),e.type!==void 0&&(t.type=e.type),e.description!==void 0&&(t.description=e.description),t}),total:n.pagination.total,errors:n.errors??[]}}async function browseRegistryItems(e,t,n,r,i={}){let{result:a,resultsBySource:o,sources:c,metadataByAddress:l}=await searchRegistryCatalog(t,{limit:i.limit,query:n,source:r}),u=a.errors??[];if(i.json||o.size>0){let t=a.items.map(e=>({...e,...l.get(searchItemAddress(e))})),r={query:n,sections:searchPresentationSections(c,o,l)};i.json&&(r.json={...a,items:t}),printRegistrySearchResults(e,r)}for(let t of u)e.error(`${t.registry}: ${t.message}`);u.length>0&&(process.exitCode=1)}async function getRegistryItemManifest(e,t){let n=await readEveRegistryConfig(e),r=await getRegistryItems([itemAddress(t)],{config:n});return r.length===1?r[0]:r}async function installRegistryItem(e,t,n={},r=defaultAddCommandDependencies){let i,a=[],o={error:e=>{i=e},log:e=>a.push(e)},s=process.exitCode,c=await runAddCommand(o,e,t,{...n,yes:n.prompter===void 0||n.yes,setupAuthorized:n.prompter!==void 0},r);if(process.exitCode=s,i!==void 0)throw Error(i);let l={output:a};return c!==void 0&&(l.setup=c),l}async function runAddCommand(e,t,o,s,c=defaultAddCommandDependencies){return runRegistryAction(e,t,async()=>{let l=await readEveRegistryConfig(t),u=itemAddress(o);if(s.skipInstall===!0){if(s.overwrite===!0)throw Error(`--overwrite cannot be used with --skip-install.`);if(s.skipSetup===!0)throw Error(`--skip-install cannot be used with --skip-setup.`);if(!isOfficialItemAddress(u))throw Error(`Setup flows are currently supported only for official eve registry items.`)}let d=await resolveRegistryItemForAdd(e,async()=>(await getRegistryItems([u],{config:l}))[0],()=>printAddSuggestions(e,t,o));if(!d.found)return;let f=d.item,p=isOfficialItemAddress(u)?eveMetadataFromRegistryItem(f):void 0;if(assertCompatibleEveVersion(p?.requires),p?.components!==void 0){if(!isOfficialItemAddress(u))throw Error(`Registry packages require the official eve registry.`);return reportCompletion(e,o,await runRegistryPackage({logger:e,appRoot:t,item:o,components:p.components,config:l,options:s,dependencies:c,operations:{itemAddress,metadata:eveMetadataFromRegistryItem,assertCompatibleVersion:assertCompatibleEveVersion,runSetups:({item:n,setups:i,prompter:a})=>runDeclaredSetups({logger:e,appRoot:t,item:n,setups:i,options:{yes:s.yes,nonInteractive:s.nonInteractive,answers:s.answers,prompter:a,signal:s.signal},dependencies:c,cancelledReminder:setupReminder(n,`cancelled`),resumeCommand:setupResumeCommand(n)}),setupReminder:e=>setupReminder(e,`skipped`)}}),s)}if(s.skipInstall===!0){if(p?.setup===void 0)throw Error(`Registry item "${o}" does not declare a setup flow.`);return reportCompletion(e,o,await runDeclaredSetups({logger:e,appRoot:t,item:o,setups:p.setup,options:s,dependencies:c,cancelledReminder:setupReminder(o,`cancelled`),resumeCommand:setupResumeCommand(o)}),s)}if(await addRegistryItems([u],{config:l,cwd:t,overwrite:s.overwrite,silent:s.silent}),p?.setup===void 0)return reportCompletion(e,o,{facts:[]},s);let m=c.hasInteractiveTerminal?.()??defaultAddCommandDependencies.hasInteractiveTerminal();if(s.nonInteractive&&e.log(serializeHeadlessSetupEvent({version:1,type:`progress`,message:s.skipInstall?`Setup ${o}`:`Installed ${o}`})),s.skipSetup===!0){if(s.nonInteractive)return reportCompletion(e,o,{facts:[]},s);e.log(setupReminder(o,`skipped`));return}if(!s.nonInteractive&&!s.yes&&!m&&s.setupAuthorized!==!0){e.log(setupReminder(o,`skipped`));return}if(!s.nonInteractive&&!s.yes&&s.setupAuthorized!==!0)try{if(await(s.prompter??c.createPrompter?.()??defaultAddCommandDependencies.createPrompter()).select({message:`Set up ${o} now?`,initialValue:`yes`,options:[{value:`yes`,label:`Yes`},{value:`no`,label:`No`}]})===`no`){e.log(setupReminder(o,`skipped`));return}}catch(t){if(!(t instanceof WizardCancelledError))throw t;e.log(setupReminder(o,`cancelled`));return}return reportCompletion(e,o,await runDeclaredSetups({logger:e,appRoot:t,item:o,setups:p.setup,options:s,dependencies:c,cancelledReminder:setupReminder(o,`cancelled`),resumeCommand:setupResumeCommand(o)}),s)})}function reportCompletion(e,n,r,i){return reportHeadlessSetupCompletion({logger:e,item:n,completion:r,nonInteractive:i.nonInteractive})}async function runRegistryAddCommand(e,t,n){await runRegistryAction(e,t,async()=>{let r=await addRegistryMappings(t,n);for(let t of r.skippedBuiltIn)e.log(`Skipped ${t} because it is built in.`);for(let t of r.skippedExisting)e.log(`Skipped ${t} because it is already configured.`);r.added.length>0&&e.log(`Added ${r.added.join(`, `)} to package.json.`)})}async function runRegistryListCommand(e,t,n,r={}){await runRegistryAction(e,t,()=>browseRegistryItems(e,t,void 0,n,r))}async function runRegistrySearchCommand(e,t,n,r,i={}){await runRegistryAction(e,t,()=>browseRegistryItems(e,t,n,r,{...i,limit:i.limit??10}))}async function runRegistryViewCommand(e,t,n,r={}){await runRegistryAction(e,t,async()=>{let i=await readEveRegistryConfig(t),a=await getRegistryItems([itemAddress(n)],{config:i}),o=a.length===1?a[0]:a;e.log(r.json?JSON.stringify(o,null,2):registryViewText(n,o))})}export{browseRegistryCatalog,getRegistryItemManifest,installOfficialRegistryItem,installRegistryItem,resolveOfficialRegistryUrl,runAddCommand,runRegistryAddCommand,runRegistryListCommand,runRegistrySearchCommand,runRegistryViewCommand};
@@ -1 +1 @@
1
- import{summarizeToolArgs,summarizeToolResult}from"./tool-format.js";import{diffWriteDetail}from"./line-diff.js";import{stripTerminalControls}from"#cli/ui/terminal-text.js";const WRITE_FILE_VERB=`Write`,DELEGATE_VERB=`Delegate`,FINAL_OUTPUT_TITLE=`Return final output`,BUILTIN_TOOL_COPY={agent:{verb:`Delegate`,pastVerb:`Delegated`,argKey:`message`,singularNoun:`task`,pluralNoun:`tasks`},ask_question:{verb:`Ask`,pastVerb:`Asked`,argKey:`prompt`,singularNoun:`question`,pluralNoun:`questions`},bash:{verb:`Run`,pastVerb:`Ran`,argKey:`command`,singularNoun:`command`,pluralNoun:`commands`},connection_search:{verb:`Discover`,pastVerb:`Discovered`,argKey:`keywords`,singularNoun:`tool search`,pluralNoun:`tool searches`},glob:{verb:`Glob`,pastVerb:`Globbed`,argKey:`pattern`,singularNoun:`pattern`,pluralNoun:`patterns`},grep:{verb:`Grep`,pastVerb:`Grepped`,argKey:`pattern`,singularNoun:`pattern`,pluralNoun:`patterns`},load_skill:{verb:`Load`,pastVerb:`Loaded`,argKey:`skill`,singularNoun:`skill`,pluralNoun:`skills`},read_file:{verb:`Read`,pastVerb:`Read`,argKey:`filePath`,singularNoun:`file`,pluralNoun:`files`},task_cancel:{verb:`Cancel`,pastVerb:`Cancelled`,argKey:`taskIds`,extractItem:taskIdsArg,singularNoun:`task`,pluralNoun:`tasks`},task_peek:{verb:`Check`,pastVerb:`Checked`,argKey:`taskIds`,extractItem:taskIdsArg,singularNoun:`task`,pluralNoun:`tasks`},task_sleep:{verb:`Pause`,pastVerb:`Paused`,argKey:`seconds`,extractItem:sleepSecondsArg,singularNoun:`pause`,pluralNoun:`pauses`},task_update:{verb:`Update`,pastVerb:`Updated`,argKey:`message`,singularNoun:`parent`,pluralNoun:`parents`},web_fetch:{verb:`Fetch`,pastVerb:`Fetched`,argKey:`url`,singularNoun:`URL`,pluralNoun:`URLs`},web_search:{verb:`Search`,pastVerb:`Searched`,argKey:`query`,extractItem:e=>salientArg(e,`objective`)??salientArg(e,`search_query`)??salientArg(e,`searchQuery`)??webSearchActionArg(e),singularNoun:`query`,pluralNoun:`queries`}};function presentWriteFileTool(a,o,s){let c=readWriteFileInput(a,o);if(c===void 0)return{title:a,subtitle:summarizeToolArgs(o),summarizeResult:summarizeToolResult};let l=diffWriteDetail(s?.previousContent,c.content,s?.existed).map(e=>e.kind===`gap`?e:{...e,text:stripTerminalControls(e.text)});return{title:`${WRITE_FILE_VERB} ${salientLine(c.path)??c.path}`,doneTitle:`Wrote ${salientLine(c.path)??c.path}`,subtitle:``,summarizeResult:()=>void 0,detail:l,keepDetailWhenDone:!0}}function readWriteFileInput(e,t){if(toolBaseName(e)!==`write_file`||typeof t!=`object`||!t||Array.isArray(t))return;let n=t,r=n.filePath,i=n.content;if(!(typeof r!=`string`||r.trim().length===0)&&typeof i==`string`)return{path:r,content:i}}function presentTool(n,r,i){let c=toolBaseName(n);if(c===`todo`)return presentTodoTool(r);if(c===`write_file`)return presentWriteFileTool(n,r,i);if(i?.isSubagent===!0)return{title:`${DELEGATE_VERB} ${c}`,doneTitle:`Delegated ${c}`,subtitle:salientArg(r,`message`)??``,summarizeResult:()=>void 0};if(c===`final_output`)return{title:FINAL_OUTPUT_TITLE,subtitle:``,summarizeResult:()=>void 0};let l=BUILTIN_TOOL_COPY[c];if(l!==void 0){let e=salientArg(r,l.argKey)??l.extractItem?.(r);if(e!==void 0)return{title:`${l.verb} ${e}`,doneTitle:`${l.pastVerb} ${e}`,subtitle:``,summarizeResult:()=>void 0,group:{verb:l.verb,pastVerb:l.pastVerb,singularNoun:l.singularNoun,pluralNoun:l.pluralNoun,item:e}}}return{title:n,subtitle:summarizeToolArgs(r),summarizeResult:summarizeToolResult}}function presentPreparingTool(e,t){let n=toolBaseName(e);if(n===`final_output`)return{title:FINAL_OUTPUT_TITLE,subtitle:``,summarizeResult:()=>void 0};if(t?.isSubagent===!0)return{title:`${DELEGATE_VERB} ${n} …`,subtitle:``,summarizeResult:()=>void 0};let r=n===`write_file`?WRITE_FILE_VERB:BUILTIN_TOOL_COPY[n]?.verb;return{title:r===void 0?e:`${r} …`,subtitle:r===void 0?`preparing…`:``,summarizeResult:()=>void 0}}function isPanelRoutedTool(e){let t=toolBaseName(e);return t===`todo`||t===`ask_question`}function toolBaseName(e){return e.split(/[.:/]/u).at(-1)??e}function presentTodoTool(e){let t=typeof e==`object`&&e&&!Array.isArray(e)?e.todos:void 0;return Array.isArray(t)?{title:`Update todo list`,subtitle:`${t.length} task${t.length===1?``:`s`}`,summarizeResult:()=>void 0}:{title:`Read todo list`,subtitle:``,summarizeResult:()=>void 0}}function webSearchActionArg(e){if(typeof e!=`object`||!e||Array.isArray(e))return;let t=e.action;if(typeof t!=`object`||!t||Array.isArray(t))return;let n=t,r=n.queries;if(Array.isArray(r)){let e=r.filter(e=>typeof e==`string`).map(salientLine).filter(e=>e!==void 0).join(`, `);if(e.length>0)return e}for(let e of[`query`,`url`,`pattern`]){let t=n[e];if(typeof t==`string`){let e=salientLine(t);if(e!==void 0)return e}}}function taskIdsArg(e){if(typeof e!=`object`||!e||Array.isArray(e))return;let t=e.taskIds;if(!Array.isArray(t))return;let n=t.filter(e=>typeof e==`string`);if(n.length!==0)return salientLine(n.join(`, `))}function sleepSecondsArg(e){if(typeof e!=`object`||!e||Array.isArray(e))return;let t=e.seconds;if(!(typeof t!=`number`||!Number.isFinite(t)))return`${String(t)}s`}function salientArg(e,t){if(typeof e!=`object`||!e||Array.isArray(e))return;let n=e[t];if(typeof n==`string`)return salientLine(n)}function salientLine(e){let t=stripTerminalControls(e).split(/\r?\n/u).find(e=>e.trim().length>0)?.trim()??``;return t.length>0?t:void 0}export{isPanelRoutedTool,presentPreparingTool,presentTool,readWriteFileInput,toolBaseName};
1
+ import{summarizeToolArgs,summarizeToolResult}from"./tool-format.js";import{diffWriteDetail}from"./line-diff.js";import{stripTerminalControls}from"#cli/ui/terminal-text.js";const WRITE_FILE_VERB=`Write`,DELEGATE_VERB=`Delegate`,FINAL_OUTPUT_TITLE=`Return final output`,BUILTIN_TOOL_COPY={agent:{verb:`Delegate`,pastVerb:`Delegated`,argKey:`message`,singularNoun:`task`,pluralNoun:`tasks`},ask_question:{verb:`Ask`,pastVerb:`Asked`,argKey:`prompt`,singularNoun:`question`,pluralNoun:`questions`},bash:{verb:`Run`,pastVerb:`Ran`,argKey:`command`,singularNoun:`command`,pluralNoun:`commands`},connection_search:{verb:`Discover`,pastVerb:`Discovered`,argKey:`keywords`,singularNoun:`tool search`,pluralNoun:`tool searches`},glob:{verb:`Glob`,pastVerb:`Globbed`,argKey:`pattern`,singularNoun:`pattern`,pluralNoun:`patterns`},grep:{verb:`Grep`,pastVerb:`Grepped`,argKey:`pattern`,singularNoun:`pattern`,pluralNoun:`patterns`},load_skill:{verb:`Load`,pastVerb:`Loaded`,argKey:`skill`,singularNoun:`skill`,pluralNoun:`skills`},read_file:{verb:`Read`,pastVerb:`Read`,argKey:`filePath`,singularNoun:`file`,pluralNoun:`files`},task_cancel:{verb:`Cancel`,pastVerb:`Cancelled`,argKey:`taskIds`,extractItem:taskIdsArg,singularNoun:`task`,pluralNoun:`tasks`},task_sleep:{verb:`Pause`,pastVerb:`Paused`,argKey:`seconds`,extractItem:sleepSecondsArg,singularNoun:`pause`,pluralNoun:`pauses`},task_update:{verb:`Update`,pastVerb:`Updated`,argKey:`message`,singularNoun:`parent`,pluralNoun:`parents`},web_fetch:{verb:`Fetch`,pastVerb:`Fetched`,argKey:`url`,singularNoun:`URL`,pluralNoun:`URLs`},web_search:{verb:`Search`,pastVerb:`Searched`,argKey:`query`,extractItem:e=>salientArg(e,`objective`)??salientArg(e,`search_query`)??salientArg(e,`searchQuery`)??webSearchActionArg(e),singularNoun:`query`,pluralNoun:`queries`}};function presentWriteFileTool(a,o,s){let c=readWriteFileInput(a,o);if(c===void 0)return{title:a,subtitle:summarizeToolArgs(o),summarizeResult:summarizeToolResult};let l=diffWriteDetail(s?.previousContent,c.content,s?.existed).map(e=>e.kind===`gap`?e:{...e,text:stripTerminalControls(e.text)});return{title:`${WRITE_FILE_VERB} ${salientLine(c.path)??c.path}`,doneTitle:`Wrote ${salientLine(c.path)??c.path}`,subtitle:``,summarizeResult:()=>void 0,detail:l,keepDetailWhenDone:!0}}function readWriteFileInput(e,t){if(toolBaseName(e)!==`write_file`||typeof t!=`object`||!t||Array.isArray(t))return;let n=t,r=n.filePath,i=n.content;if(!(typeof r!=`string`||r.trim().length===0)&&typeof i==`string`)return{path:r,content:i}}function presentTool(n,r,i){let c=toolBaseName(n);if(c===`todo`)return presentTodoTool(r);if(c===`write_file`)return presentWriteFileTool(n,r,i);if(i?.isSubagent===!0)return{title:`${DELEGATE_VERB} ${c}`,doneTitle:`Delegated ${c}`,subtitle:salientArg(r,`message`)??``,summarizeResult:()=>void 0};if(c===`final_output`)return{title:FINAL_OUTPUT_TITLE,subtitle:``,summarizeResult:()=>void 0};let l=BUILTIN_TOOL_COPY[c];if(l!==void 0){let e=salientArg(r,l.argKey)??l.extractItem?.(r);if(e!==void 0)return{title:`${l.verb} ${e}`,doneTitle:`${l.pastVerb} ${e}`,subtitle:``,summarizeResult:()=>void 0,group:{verb:l.verb,pastVerb:l.pastVerb,singularNoun:l.singularNoun,pluralNoun:l.pluralNoun,item:e}}}return{title:n,subtitle:summarizeToolArgs(r),summarizeResult:summarizeToolResult}}function presentPreparingTool(e,t){let n=toolBaseName(e);if(n===`final_output`)return{title:FINAL_OUTPUT_TITLE,subtitle:``,summarizeResult:()=>void 0};if(t?.isSubagent===!0)return{title:`${DELEGATE_VERB} ${n} …`,subtitle:``,summarizeResult:()=>void 0};let r=n===`write_file`?WRITE_FILE_VERB:BUILTIN_TOOL_COPY[n]?.verb;return{title:r===void 0?e:`${r} …`,subtitle:r===void 0?`preparing…`:``,summarizeResult:()=>void 0}}function isPanelRoutedTool(e){let t=toolBaseName(e);return t===`todo`||t===`ask_question`}function toolBaseName(e){return e.split(/[.:/]/u).at(-1)??e}function presentTodoTool(e){let t=typeof e==`object`&&e&&!Array.isArray(e)?e.todos:void 0;return Array.isArray(t)?{title:`Update todo list`,subtitle:`${t.length} task${t.length===1?``:`s`}`,summarizeResult:()=>void 0}:{title:`Read todo list`,subtitle:``,summarizeResult:()=>void 0}}function webSearchActionArg(e){if(typeof e!=`object`||!e||Array.isArray(e))return;let t=e.action;if(typeof t!=`object`||!t||Array.isArray(t))return;let n=t,r=n.queries;if(Array.isArray(r)){let e=r.filter(e=>typeof e==`string`).map(salientLine).filter(e=>e!==void 0).join(`, `);if(e.length>0)return e}for(let e of[`query`,`url`,`pattern`]){let t=n[e];if(typeof t==`string`){let e=salientLine(t);if(e!==void 0)return e}}}function taskIdsArg(e){if(typeof e!=`object`||!e||Array.isArray(e))return;let t=e.taskIds;if(!Array.isArray(t))return;let n=t.filter(e=>typeof e==`string`);if(n.length!==0)return salientLine(n.join(`, `))}function sleepSecondsArg(e){if(typeof e!=`object`||!e||Array.isArray(e))return;let t=e.seconds;if(!(typeof t!=`number`||!Number.isFinite(t)))return`${String(t)}s`}function salientArg(e,t){if(typeof e!=`object`||!e||Array.isArray(e))return;let n=e[t];if(typeof n==`string`)return salientLine(n)}function salientLine(e){let t=stripTerminalControls(e).split(/\r?\n/u).find(e=>e.trim().length>0)?.trim()??``;return t.length>0?t:void 0}export{isPanelRoutedTool,presentPreparingTool,presentTool,readWriteFileInput,toolBaseName};
@@ -1,4 +1,4 @@
1
- import{createLogger}from"#internal/logging.js";import{Command,CommanderError,InvalidArgumentError}from"#compiled/commander/index.js";import{applicationCommand}from"#cli/application-command.js";import{parseDevelopmentHeaderOption,resolveDevelopmentUrlTarget}from"#cli/dev/url-target.js";import{parseDevelopmentServerUrl}from"#cli/dev/url.js";import{FORCED_EXIT_BACKSTOP_MS,installShutdownSignal,waitForShutdownSignal}from"#cli/shutdown.js";import{resolveInstalledPackageInfo}from"#internal/application/package.js";import{createCliTheme,renderCliTaggedLine}from"#cli/ui/output.js";import{isCodingAgentLaunch}from"#cli/agent-detection.js";import{eveCliBanner}from"#cli/banner.js";import{startCliLiveRow}from"#cli/ui/live-row.js";import{devBootPhase}from"#internal/dev-boot-progress.js";import{registerBuildCommand}from"#cli/commands/build.js";import{resolveApplicationRoot}from"#internal/application/paths.js";import{findCliApplicationRoot,resolveCliApplicationProject}from"#cli/application-root.js";import{registerIntegrationCommands}from"#cli/commands/register-integration-commands.js";import{registerProjectCommands}from"#cli/commands/register-project-commands.js";import{registerRegistryCommands}from"#cli/commands/register-registry-commands.js";import{resolveDevUiMode,resolveTuiDisplayOptions}from"#cli/dev/ui-options.js";import{registerAcpCommand}from"#cli/acp/command.js";import{waitForServerOrStop,waitForUiOrServer}from"#cli/dev/wait-for-ui.js";import{registerRuntimeInvokeCommand}from"#cli/invoke/command.js";import{parseContextSizeOption,parseDisplayMode,parseLogsMode,parsePortOption,parseReasoningOption,parseStatsMode}from"#cli/option-parsers.js";import{resolveTuiTitle}from"#cli/dev/tui/target.js";import{resumeDevelopmentRuntimeArtifacts,suspendDevelopmentRuntimeArtifacts}from"#services/dev-client/runtime-artifacts.js";const devBootLog=createLogger(`dev.boot`);function createDevBootProgressReporter(e){return t=>{switch(t.type){case`phase-started`:e?.update(`Building your agent`,t.phase),devBootLog.debug(t.phase);return;case`phase-finished`:devBootLog.debug(`${t.phase} finished`,{ms:t.elapsedMs});return;case`before-first-paint`:e?.stop();return;default:return t}}}async function loadPrintApplicationInfo(){return(await import(`#cli/commands/info.js`)).printApplicationInfo}async function loadRunDevelopmentTui(){return(await import(`#cli/dev/tui/tui.js`)).runDevelopmentTui}async function loadRunEvalCommand(){return(await import(`#evals/cli/eval.js`)).runEvalCommand}async function loadStartHost(){return(await import(`#cli/dev/local-server-process.js`)).createDevelopmentServer}const loadIsActiveDevelopmentServerForApp=async()=>(await import(`#internal/nitro/host.js`)).isActiveDevelopmentServerForApp;async function loadStartProductionHost(){return(await import(`#internal/nitro/host.js`)).startProductionServer}function hasInteractiveTerminal(){return!!(process.stdin.isTTY&&process.stdout.isTTY)}function createCliProgram(e,n,p){let g=resolveInstalledPackageInfo().version,_=new Command,v=createCliTheme();_.name(`eve`).description(`Build and run an eve application.`).version(g).showHelpAfterError().exitOverride().hook(`preAction`,(t,n)=>{[`info`,`dev`,`init`].includes(n.name())&&e.log(eveCliBanner())}).configureOutput({writeErr:t=>{e.error(t.trimEnd())},writeOut:t=>{e.log(t.trimEnd())}}),applicationCommand(_.command(`channels`).description(`Manage user-authored channels in the current project.`).command(`list`),p).description(`List user-authored channels in the current project.`).option(`--json`,`Output as JSON`).action(async t=>{let{runChannelsListCommand:n}=await import(`#cli/commands/channels.js`);await n(e,p.project,t)}),registerIntegrationCommands({program:_,logger:e,applicationContext:p});let b=_.command(`extension`).description(`Create and build reusable eve extension packages.`);b.command(`init [target]`).description(`Create a new eve extension package.`).option(`-y, --yes`,`Accepted for compatibility; has no effect`).action(async(t,n)=>{n.yes&&e.error(`warning: --yes has no effect for eve extension init.`);let{runExtensionInitCommand:r}=await import(`#cli/commands/extension-init.js`);await r(e,p.root,t)}),b.command(`build`).description(`Build the current package as an eve extension.`).action(async()=>{let{loadDevelopmentEnvironmentFiles:t}=await import(`#cli/dev/environment.js`);t(p.root);let{runExtensionBuildCommand:n}=await import(`#cli/commands/extension-build.js`);await n(e,p.root)}),registerRegistryCommands({program:_,logger:e,applicationContext:p}),_.command(`init [target]`).description(`Create a new eve agent, or add one to an existing project directory.`).option(`--channel-web-nextjs`,`Add the Web Chat application (Next.js)`).option(`--model <model>`,`Set the agent model (provider/model-id)`).option(`--reasoning <effort>`,`Set reasoning (provider-default|none|minimal|low|medium|high|xhigh)`,parseReasoningOption).option(`-y, --yes`,`Accepted for compatibility; has no effect`).action(async(t,n)=>{n.yes&&e.error(`warning: --yes has no effect for eve init.`);let{runInitCommand:r}=await import(`#cli/commands/init.js`);await r(e,p.root,t,{channelWebNextjs:n.channelWebNextjs,model:n.model,reasoning:n.reasoning})}),applicationCommand(_.command(`set`),p).description(`Change root agent model settings.`).option(`--model <model>`,`Set the agent model (provider/model-id)`).option(`--reasoning <effort>`,`Set reasoning (provider-default|none|minimal|low|medium|high|xhigh)`,parseReasoningOption).action(async t=>{let{runSetCommand:n}=await import(`#cli/commands/set.js`);await n(e,p.root,t)}),registerProjectCommands({program:_,logger:e,applicationContext:p}),registerBuildCommand({applicationContext:p,buildHost:n.buildHost,logger:e,program:_}),applicationCommand(_.command(`start`),p).description(`Start a built eve application.`).option(`--host <host>`,`Host interface to bind`).option(`--port <port>`,`Port to listen on (defaults to $PORT, then 3000)`,parsePortOption).action(async t=>{let{loadDevelopmentEnvironmentFiles:r}=await import(`#cli/dev/environment.js`);r(p.root);let i=await(n.startProductionHost??await loadStartProductionHost())(p.root,{host:t.host,port:t.port});e.log(renderCliTaggedLine(v,{message:`server listening at ${i.url}`,tag:`start`,tone:`success`})),await waitForShutdownSignal({close:()=>i.close(),wait:()=>i.wait()})}),registerRuntimeInvokeCommand({applicationContext:p,logger:e,program:_,runtime:n}),registerAcpCommand({applicationContext:p,eveVersion:g,program:_,resolveVerifiedRemoteDevelopmentClient:n.resolveVerifiedRemoteDevelopmentClient,runAcpServer:n.runAcpServer,startHost:n.startHost}),applicationCommand(_.command(`dev`),p,e=>resolveDevelopmentUrlTarget(e.opts(),e.processedArgs[0])===void 0).description(`Start the eve development server or connect to an existing URL.`).argument(`[url]`,`Connect to an existing server URL`,parseDevelopmentServerUrl).option(`--host <host>`,`Host interface to bind`).option(`--port <port>`,`Port to listen on (defaults to $PORT, then 2000)`,parsePortOption).option(`-u, --url <url>`,`Connect to an existing server URL`,parseDevelopmentServerUrl).option(`-H, --header <header>`,`Request header for a URL target, in "Name: value" form (repeatable)`,parseDevelopmentHeaderOption).option(`--no-ui`,`Start the server without an interactive UI`).option(`--name <name>`,`Title shown in the terminal UI (defaults to the app folder name)`).option(`--input <text>`,`Pre-fill the prompt input, or start onboarding with /model`).option(`--tools <mode>`,`How tool calls render: full | collapsed | auto-collapsed | hidden`,parseDisplayMode).option(`--reasoning <mode>`,`How reasoning renders: full | collapsed | auto-collapsed | hidden`,parseDisplayMode).option(`--subagents <mode>`,`How subagent sections render: full | collapsed | auto-collapsed | hidden`,parseDisplayMode).option(`--connection-auth <mode>`,`How connection authorization renders: full | collapsed | auto-collapsed | hidden`,parseDisplayMode).option(`--assistant-response-stats <mode>`,`Assistant header statistic: tokens | tokensPerSecond`,parseStatsMode).option(`--context-size <tokens>`,`Model context window size, shown as a usage percentage`,parseContextSizeOption).option(`--logs <mode>`,`Which server/agent logs to show: all | stderr | sandbox | none`,parseLogsMode).addHelpText(`after`,`
1
+ import{createLogger}from"#internal/logging.js";import{Command,CommanderError,InvalidArgumentError}from"#compiled/commander/index.js";import{applicationCommand}from"#cli/application-command.js";import{parseDevelopmentHeaderOption,resolveDevelopmentUrlTarget}from"#cli/dev/url-target.js";import{parseDevelopmentServerUrl}from"#cli/dev/url.js";import{FORCED_EXIT_BACKSTOP_MS,installShutdownSignal,waitForShutdownSignal}from"#cli/shutdown.js";import{resolveInstalledPackageInfo}from"#internal/application/package.js";import{createCliTheme,renderCliTaggedLine}from"#cli/ui/output.js";import{isCodingAgentLaunch}from"#cli/agent-detection.js";import{eveCliBanner}from"#cli/banner.js";import{startCliLiveRow}from"#cli/ui/live-row.js";import{devBootPhase}from"#internal/dev-boot-progress.js";import{registerBuildCommand}from"#cli/commands/build.js";import{resolveApplicationRoot}from"#internal/application/paths.js";import{findCliApplicationRoot,resolveCliApplicationProject}from"#cli/application-root.js";import{registerIntegrationCommands}from"#cli/commands/register-integration-commands.js";import{registerProjectCommands}from"#cli/commands/register-project-commands.js";import{registerRegistryCommands}from"#cli/commands/register-registry-commands.js";import{resolveDevUiMode,resolveTuiDisplayOptions}from"#cli/dev/ui-options.js";import{registerAcpCommand}from"#cli/acp/command.js";import{waitForServerOrStop,waitForUiOrServer}from"#cli/dev/wait-for-ui.js";import{registerRuntimeInvokeCommand}from"#cli/invoke/command.js";import{parseContextSizeOption,parseDisplayMode,parseLogsMode,parsePortOption,parseReasoningOption,parseStatsMode}from"#cli/option-parsers.js";import{resolveTuiTitle}from"#cli/dev/tui/target.js";import{resumeDevelopmentRuntimeArtifacts,suspendDevelopmentRuntimeArtifacts}from"#services/dev-client/runtime-artifacts.js";const devBootLog=createLogger(`dev.boot`);function createDevBootProgressReporter(e){return t=>{switch(t.type){case`phase-started`:e?.update(`Building your agent`,t.phase),devBootLog.debug(t.phase);return;case`phase-finished`:devBootLog.debug(`${t.phase} finished`,{ms:t.elapsedMs});return;case`before-first-paint`:e?.stop();return;default:return t}}}async function loadPrintApplicationInfo(){return(await import(`#cli/commands/info.js`)).printApplicationInfo}async function loadRunDevelopmentTui(){return(await import(`#cli/dev/tui/tui.js`)).runDevelopmentTui}async function loadRunEvalCommand(){return(await import(`#evals/cli/eval.js`)).runEvalCommand}async function loadStartHost(){return(await import(`#cli/dev/local-server-process.js`)).createDevelopmentServer}const loadIsActiveDevelopmentServerForApp=async()=>(await import(`#internal/nitro/host.js`)).isActiveDevelopmentServerForApp;async function loadStartProductionHost(){return(await import(`#internal/nitro/host.js`)).startProductionServer}function hasInteractiveTerminal(){return!!(process.stdin.isTTY&&process.stdout.isTTY)}function createCliProgram(e,n,p){let g=resolveInstalledPackageInfo().version,_=new Command,v=createCliTheme();_.name(`eve`).description(`Build and run an eve application.`).version(g).showHelpAfterError().exitOverride().hook(`preAction`,(t,n)=>{let{json:r}=n.opts();[`info`,`dev`,`init`].includes(n.name())&&!r&&e.log(eveCliBanner())}).configureOutput({writeErr:t=>{e.error(t.trimEnd())},writeOut:t=>{e.log(t.trimEnd())}}),applicationCommand(_.command(`channels`).description(`Manage user-authored channels in the current project.`).command(`list`),p).description(`List user-authored channels in the current project.`).option(`--json`,`Output as JSON`).action(async t=>{let{runChannelsListCommand:n}=await import(`#cli/commands/channels.js`);await n(e,p.project,t)}),registerIntegrationCommands({program:_,logger:e,applicationContext:p});let b=_.command(`extension`).description(`Create and build reusable eve extension packages.`);b.command(`init [target]`).description(`Create a new eve extension package.`).option(`-y, --yes`,`Accepted for compatibility; has no effect`).action(async(t,n)=>{n.yes&&e.error(`warning: --yes has no effect for eve extension init.`);let{runExtensionInitCommand:r}=await import(`#cli/commands/extension-init.js`);await r(e,p.root,t)}),b.command(`build`).description(`Build the current package as an eve extension.`).action(async()=>{let{loadDevelopmentEnvironmentFiles:t}=await import(`#cli/dev/environment.js`);t(p.root);let{runExtensionBuildCommand:n}=await import(`#cli/commands/extension-build.js`);await n(e,p.root)}),registerRegistryCommands({program:_,logger:e,applicationContext:p}),_.command(`init [target]`).description(`Create a new eve agent, or add one to an existing project directory.`).option(`--channel-web-nextjs`,`Add the Web Chat application (Next.js)`).option(`--model <model>`,`Set the agent model (provider/model-id)`).option(`--reasoning <effort>`,`Set reasoning (provider-default|none|minimal|low|medium|high|xhigh)`,parseReasoningOption).option(`-y, --yes`,`Accepted for compatibility; has no effect`).action(async(t,n)=>{n.yes&&e.error(`warning: --yes has no effect for eve init.`);let{runInitCommand:r}=await import(`#cli/commands/init.js`);await r(e,p.root,t,{channelWebNextjs:n.channelWebNextjs,model:n.model,reasoning:n.reasoning})}),applicationCommand(_.command(`set`),p).description(`Change root agent model settings.`).option(`--model <model>`,`Set the agent model (provider/model-id)`).option(`--reasoning <effort>`,`Set reasoning (provider-default|none|minimal|low|medium|high|xhigh)`,parseReasoningOption).action(async t=>{let{runSetCommand:n}=await import(`#cli/commands/set.js`);await n(e,p.root,t)}),registerProjectCommands({program:_,logger:e,applicationContext:p}),registerBuildCommand({applicationContext:p,buildHost:n.buildHost,logger:e,program:_}),applicationCommand(_.command(`start`),p).description(`Start a built eve application.`).option(`--host <host>`,`Host interface to bind`).option(`--port <port>`,`Port to listen on (defaults to $PORT, then 3000)`,parsePortOption).action(async t=>{let{loadDevelopmentEnvironmentFiles:r}=await import(`#cli/dev/environment.js`);r(p.root);let i=await(n.startProductionHost??await loadStartProductionHost())(p.root,{host:t.host,port:t.port});e.log(renderCliTaggedLine(v,{message:`server listening at ${i.url}`,tag:`start`,tone:`success`})),await waitForShutdownSignal({close:()=>i.close(),wait:()=>i.wait()})}),registerRuntimeInvokeCommand({applicationContext:p,logger:e,program:_,runtime:n}),registerAcpCommand({applicationContext:p,eveVersion:g,program:_,resolveVerifiedRemoteDevelopmentClient:n.resolveVerifiedRemoteDevelopmentClient,runAcpServer:n.runAcpServer,startHost:n.startHost}),applicationCommand(_.command(`dev`),p,e=>resolveDevelopmentUrlTarget(e.opts(),e.processedArgs[0])===void 0).description(`Start the eve development server or connect to an existing URL.`).argument(`[url]`,`Connect to an existing server URL`,parseDevelopmentServerUrl).option(`--host <host>`,`Host interface to bind`).option(`--port <port>`,`Port to listen on (defaults to $PORT, then 2000)`,parsePortOption).option(`-u, --url <url>`,`Connect to an existing server URL`,parseDevelopmentServerUrl).option(`-H, --header <header>`,`Request header for a URL target, in "Name: value" form (repeatable)`,parseDevelopmentHeaderOption).option(`--no-ui`,`Start the server without an interactive UI`).option(`--name <name>`,`Title shown in the terminal UI (defaults to the app folder name)`).option(`--input <text>`,`Pre-fill the prompt input, or start onboarding with /model`).option(`--tools <mode>`,`How tool calls render: full | collapsed | auto-collapsed | hidden`,parseDisplayMode).option(`--reasoning <mode>`,`How reasoning renders: full | collapsed | auto-collapsed | hidden`,parseDisplayMode).option(`--subagents <mode>`,`How subagent sections render: full | collapsed | auto-collapsed | hidden`,parseDisplayMode).option(`--connection-auth <mode>`,`How connection authorization renders: full | collapsed | auto-collapsed | hidden`,parseDisplayMode).option(`--assistant-response-stats <mode>`,`Assistant header statistic: tokens | tokensPerSecond`,parseStatsMode).option(`--context-size <tokens>`,`Model context window size, shown as a usage percentage`,parseContextSizeOption).option(`--logs <mode>`,`Which server/agent logs to show: all | stderr | sandbox | none`,parseLogsMode).addHelpText(`after`,`
2
2
  You can also pass a bare URL, for example: eve dev https://example.com
3
3
  `).action(async(t,i)=>{let a=resolveDevelopmentUrlTarget(i,t),s=a?.serverUrl,u=hasInteractiveTerminal(),d=resolveDevUiMode({options:i,interactive:u});if(i.input!==void 0&&d===`headless`)throw new InvalidArgumentError(`--input requires the interactive UI.`);let f=!1;s!==void 0&&(f=await(n.isActiveDevelopmentServerForApp??await loadIsActiveDevelopmentServerForApp())({appRoot:p.root,serverUrl:s}));let runInteractiveUi=async(e,t,r)=>{let o=await devBootPhase(`loading interactive UI`,async()=>n.runDevelopmentTui??await loadRunDevelopmentTui(),t),c=resolveTuiDisplayOptions(i),l=s===void 0||f?{kind:`local`,serverUrl:e.serverUrl,workspaceRoot:e.appRoot??p.root}:{kind:`remote`,serverUrl:e.serverUrl,workspaceRoot:p.root},u=resolveTuiTitle({name:i.name,target:l});u!==void 0&&(c.name=u);let d={target:l,initialInput:i.input,onBootProgress:t,lifecycle:r,...c};l.kind===`local`&&(d.withExclusiveTerminal=async t=>await(async()=>{if(!await suspendDevelopmentRuntimeArtifacts({serverUrl:e.serverUrl}))throw Error(`Could not pause the development server for integration setup.`);try{return await t()}finally{await resumeDevelopmentRuntimeArtifacts({serverUrl:e.serverUrl,silent:!0})}})()),a?.headers===void 0?await o(d):await o({...d,headers:a.headers})};if(s){let{loadDevelopmentEnvironmentFiles:t}=await import(`#cli/dev/environment.js`);if(t(p.root),e.log(`↗ ${f?`local`:`remote`} mode targeting ${v.info(new URL(s).host)}`),d===`headless`){e.log(renderCliTaggedLine(v,{message:`Interactive UI disabled because the current terminal is not a TTY.`,tag:`dev`,tone:`warning`}));return}e.log(``);let n=installShutdownSignal({exitAfterMs:FORCED_EXIT_BACKSTOP_MS});try{await runInteractiveUi({serverUrl:s},void 0,n)}finally{n.dispose()}return}d===`tui`&&e.log(``);let m=d===`tui`?startCliLiveRow(e):void 0,h=createDevBootProgressReporter(m);m?.update(`Building your agent`);let g,_,closeServer=()=>g===void 0?Promise.resolve():(_??=g.close(),_.catch(()=>void 0),_),y=installShutdownSignal({exitAfterMs:FORCED_EXIT_BACKSTOP_MS,onStop:()=>{closeServer()}});try{g=(n.startHost??await loadStartHost())(p.root,{existing:d===`tui`?`attach-if-unconfigured`:`reject`,host:i.host,onBootProgress:h,port:i.port});let t=(await Promise.race([g.start().then(e=>({handle:e})),y.stopped.then(()=>({handle:void 0}))])).handle;if(t===void 0)return;if(d!==`tui`&&e.log(renderCliTaggedLine(v,{message:`server listening at ${t.url}`,tag:`dev`,tone:`success`})),d===`headless`){i.ui!==!1&&!u&&e.log(renderCliTaggedLine(v,{message:`Interactive UI disabled because the current terminal is not a TTY.`,tag:`dev`,tone:`warning`})),await waitForServerOrStop(g,y);return}await waitForUiOrServer({handle:t,lifecycle:y,server:g,runUi:async()=>await runInteractiveUi({appRoot:t.appRoot,serverUrl:t.url},h,y)})}finally{m?.stop(),await closeServer(),y.dispose()}});let x=_.command(`logs`).description("Inspect local `eve dev` diagnostic logs (.eve/logs).");return applicationCommand(x.command(`show [logid]`,{isDefault:!0}),p).description(`Print a diagnostic log (the most recent when logid is omitted).`).option(`--dump`,`Prepend the log's environment dump (.dump sibling)`).option(`--events`,`Interleave session events from the local workflow store`).action(async(t,n)=>{let{runLogsShowCommand:r}=await import(`#cli/commands/logs.js`);await r(e,p.root,t,n)}),applicationCommand(x.command(`ls`),p).description(`List diagnostic logs, most recent first.`).option(`--json`,`Output as JSON`).action(async t=>{let{runLogsListCommand:n}=await import(`#cli/commands/logs.js`);await n(e,p.root,t)}),applicationCommand(_.command(`traces [trace]`),p).usage(`[options] [trace]
4
4
  eve traces ls [options]`).description("Show a local `eve dev` trace (the most recent when trace is omitted).").option(`--verbose`,`Expand every span with all attributes and events`).option(`--json`,`Output as JSON`).action(async(t,n)=>{let{runTraceShowCommand:r}=await import(`#cli/commands/trace.js`);await r(e,p.root,t,n)}).command(`ls`).description(`List local traces, most recent first.`).option(`--json`,`Output as JSON`).action(async t=>{let{runTraceListCommand:n}=await import(`#cli/commands/trace.js`);await n(e,p.root,t)}),applicationCommand(_.command(`info`),p).description(`Print resolved application information.`).option(`--json`,`Output as JSON`).action(async t=>{await(n.printApplicationInfo??await loadPrintApplicationInfo())(e,p.root,t)}),applicationCommand(_.command(`eval`),p).description(`Run evals against an eve agent.`).argument(`[evalIds...]`,`Eval ids (or directory prefixes) to run (all discovered evals when omitted)`).option(`--url <url>`,`Remote agent URL (skip local host startup)`,parseDevelopmentServerUrl).option(`--tag <tag...>`,`Run only evals carrying a tag`).option(`--exclude-tag <tag...>`,`Skip evals carrying a tag`).option(`--strict`,`Fail the exit code when any score falls below its threshold`).option(`--list`,`Print discovered evals without running them`).option(`--timeout <ms>`,`Per-eval timeout in milliseconds`).option(`--max-concurrency <n>`,`Max concurrent eval executions`).option(`--json`,`Output results as JSON`).option(`--junit <path>`,`Write JUnit XML results to a file`).option(`--skip-report`,`Skip eval-defined reporters (e.g. Braintrust)`).option(`--verbose`,`Stream per-eval t.log lines to stdout`).action(async(t,r)=>{await(n.runEvalCommand??await loadRunEvalCommand())(t,r,e,p.root)}),_}async function runCli(e=process.argv.slice(2),t=console,r={}){let i={root:resolveApplicationRoot(),async resolve(){let e=await(r.resolveApplicationProject??resolveCliApplicationProject)(i.root);i.project=e,i.root=e.appRoot}},a=createCliProgram(t,r,i),o=e;if(o.length===0){let e=await(r.findApplicationRoot??findCliApplicationRoot)(i.root);e===void 0?o=[`init`]:(i.root=e,o=[`dev`])}try{await a.parseAsync(o,{from:`user`})}catch(e){if(e instanceof CommanderError){if(e.exitCode===0)return;let n=await(r.isCodingAgentLaunch??isCodingAgentLaunch)();if(o[0]===`init`&&n){let{initAgentInstructions:e}=await import(`#cli/commands/agent-instructions.js`);t.log(e())}throw Error(e.message)}throw e}}export{resolveDevUiMode,resolveTuiDisplayOptions,runCli};
@@ -28,7 +28,7 @@
28
28
  "@ai-sdk/provider": "4.0.7",
29
29
  "@ai-sdk/provider-utils": "5.0.25",
30
30
  "semver": "7.8.4",
31
- "shadcn": "4.16.1",
31
+ "shadcn": "4.18.0",
32
32
  "@standard-schema/spec": "1.1.0",
33
33
  "turndown": "7.2.4",
34
34
  "@vercel/detect-agent": "1.2.3",
@@ -36,16 +36,16 @@
36
36
  "@vercel/otel": "2.1.3",
37
37
  "@vercel/sandbox-drives": "2.10.0-beta.0",
38
38
  "@vercel/sandbox": "2.8.0",
39
- "@workflow/core": "5.0.0-beta.42",
39
+ "@workflow/core": "5.0.0-beta.43",
40
40
  "@workflow/errors": "5.0.0-beta.17",
41
41
  "@workflow/serde": "5.0.0-beta.2",
42
- "@workflow/world": "5.0.0-beta.27",
43
- "@workflow/world-local": "5.0.0-beta.36",
44
- "@workflow/world-vercel": "5.0.0-beta.38",
42
+ "@workflow/world": "5.0.0-beta.28",
43
+ "@workflow/world-local": "5.0.0-beta.37",
44
+ "@workflow/world-vercel": "5.0.0-beta.39",
45
45
  "zod": "4.4.3",
46
46
  "zod-validation-error": "5.0.0"
47
47
  },
48
- "scriptHash": "d6805a01fe53c75ceb5bc0815fcc6354b57746fda18ce55c168188cb9b6c2c57",
48
+ "scriptHash": "e66658986492437f65202c761d4df792eeb66bdfe9f2d3cf35b76a395ea0834f",
49
49
  "toolVersions": {
50
50
  "rolldown": "1.1.5"
51
51
  }
@@ -108,13 +108,17 @@ export interface HookOptions {
108
108
  * the token with the information it has available.
109
109
  *
110
110
  * Deterministic tokens are intended for use with `createHook()` and
111
- * server-side `resumeHook()` only. For webhooks (`createWebhook()`),
112
- * tokens are always randomly generated to prevent unauthorized access
113
- * to the public webhook endpoint.
111
+ * server-side `resumeHook()` only. For webhooks (`createWebhook()`), an
112
+ * explicit token is not accepted — one is always generated for you.
113
+ *
114
+ * A generated token is not trivial to guess but is not a security
115
+ * contract, so authenticate webhook requests themselves rather than
116
+ * relying on URL secrecy:
117
+ * https://workflow-sdk.dev/docs/foundations/hooks#token-design
114
118
  *
115
119
  * If provided, the token must be a non-empty string; passing an empty
116
- * string throws. If not provided (or `undefined`), a randomly generated
117
- * token will be assigned.
120
+ * string throws. If not provided (or `undefined`), a token is generated
121
+ * for you.
118
122
  *
119
123
  * @example
120
124
  *
@@ -1,2 +1,2 @@
1
- import{E as e,I as t,P as n,X as r,Z as i,ar as a,cr as o,fr as s,hr as c,lr as l,mr as u,nr as d,pr as f,qn as p,sr as m}from"../../_chunks/workflow/wait-until-BPSgt1Wg.js";import{i as h,u as g}from"../../_chunks/workflow/dist-CqvWKNQv.js";import{a as _,i as v,r as y,t as b}from"../../_chunks/workflow/attribute-changes-B8K0pwpH.js";import"../../_chunks/workflow/dist-BRGbNjhD.js";import{n as x}from"../../_chunks/workflow/resume-hook-DO_MuJlY.js";import{t as S}from"../../_chunks/workflow/sleep-7TgF3i-e.js";function C(e){v(`createHook()`,`https://workflow-sdk.dev/docs/api-reference/workflow/create-hook`,C)}function w(e){v(`createWebhook()`,`https://workflow-sdk.dev/docs/api-reference/workflow/create-webhook`,w)}function T({schema:e}={}){function t(e){v(`defineHook().create()`,`https://workflow-sdk.dev/docs/api-reference/workflow/define-hook`,t)}return{create:t,async resume(t,n){if(!e?.[`~standard`])return await x(t,n);let r=e[`~standard`].validate(n);if(r instanceof Promise&&(r=await r),r.issues){let e=r.issues.map(e=>{let t=e.path?.map(e=>String(typeof e==`object`&&e?e.key:e)).join(`.`);return t?` at "${t}": ${e.message}`:` ${e.message}`});throw Error(`Hook payload did not match the defined schema:\n${e.join(`
2
- `)}`)}return await x(t,r.value)}}}async function E(e,t={}){let n=i.getStore(),r=n?.workflowMetadata?.workflowRunId;if(!r)throw new h(`setAttributes() must be called from a 'use workflow' or 'use step' function. Calling it from plain host code is not supported.`);let o=b(e,t);if(o.length!==0){if(n.runReadyBarrier)try{await n.runReadyBarrier}catch{}await(await a()).events.create(r,{eventType:`attr_set`,specVersion:6,eventData:{changes:o,writer:{type:`step`,stepId:n.stepMetadata.stepId,attempt:n.stepMetadata.attempt},...t.allowReservedAttributes===!0?{allowReservedAttributes:!0}:{}}})}}function D(){let e=i.getStore();return e||y(`getStepMetadata()`,`https://workflow-sdk.dev/docs/api-reference/workflow/get-step-metadata`,D),e.stepMetadata}function O(){let e=i.getStore();return e||_(`getWorkflowMetadata()`,`https://workflow-sdk.dev/docs/api-reference/workflow/get-workflow-metadata`,O),e.workflowMetadata}function k(a={}){let h=i.getStore();h||_(`getWritable()`,`https://workflow-sdk.dev/docs/api-reference/workflow/get-writable`,k);let{namespace:g}=a,v=h.workflowMetadata.workflowRunId,y=r(v,g);h.writables??=new Map;let b=h.writables,x=b.get(y);if(x)return x.writable;let S=t(n(globalThis,h.ops,v,h.encryptionKey,!0,h.runReadyBarrier),h.encryptionKey),C=new e(v,y,h.runReadyBarrier),w=m();return h.ops.push(w.promise),o(S.readable,C,w).catch(()=>{}),l(S.writable,w),Object.defineProperty(S.writable,s,{value:y,writable:!1}),Object.defineProperty(S.writable,c,{value:v,writable:!1}),h.workflowDeploymentId&&Object.defineProperty(S.writable,f,{value:h.workflowDeploymentId,writable:!1}),p(h.encryptionKey)&&Object.defineProperty(S.writable,u,{value:d(h.encryptionKey.keyPair.publicKey),writable:!1}),b.set(y,{writable:S.writable,state:w}),S.writable}export{h as FatalError,g as RetryableError,C as createHook,w as createWebhook,T as defineHook,D as getStepMetadata,O as getWorkflowMetadata,k as getWritable,E as setAttributes,S as sleep};
1
+ import{E as e,I as t,Jn as n,P as r,X as i,Z as a,cr as o,gr as s,hr as c,lr as l,mr as u,or as d,pr as f,rr as p,ur as m}from"../../_chunks/workflow/wait-until-BZHmJCAW.js";import{i as h,u as g}from"../../_chunks/workflow/dist-CqvWKNQv.js";import{a as _,i as v,r as y,t as b}from"../../_chunks/workflow/attribute-changes-DXbpwBdw.js";import"../../_chunks/workflow/dist-Dk0aQqFO.js";import{n as x}from"../../_chunks/workflow/resume-hook-E-Nkx8q_.js";import{t as S}from"../../_chunks/workflow/sleep-CxFsdxB_.js";function C(e){v(`createHook()`,`https://workflow-sdk.dev/docs/api-reference/workflow/create-hook`,C)}function w(e){v(`createWebhook()`,`https://workflow-sdk.dev/docs/api-reference/workflow/create-webhook`,w)}function T({schema:e}={}){function t(e){v(`defineHook().create()`,`https://workflow-sdk.dev/docs/api-reference/workflow/define-hook`,t)}return{create:t,async resume(t,n){if(!e?.[`~standard`])return await x(t,n);let r=e[`~standard`].validate(n);if(r instanceof Promise&&(r=await r),r.issues){let e=r.issues.map(e=>{let t=e.path?.map(e=>String(typeof e==`object`&&e?e.key:e)).join(`.`);return t?` at "${t}": ${e.message}`:` ${e.message}`});throw Error(`Hook payload did not match the defined schema:\n${e.join(`
2
+ `)}`)}return await x(t,r.value)}}}async function E(e,t={}){let n=a.getStore(),r=n?.workflowMetadata?.workflowRunId;if(!r)throw new h(`setAttributes() must be called from a 'use workflow' or 'use step' function. Calling it from plain host code is not supported.`);let i=b(e,t);if(i.length!==0){if(n.runReadyBarrier)try{await n.runReadyBarrier}catch{}await(await d()).events.create(r,{eventType:`attr_set`,specVersion:6,eventData:{changes:i,writer:{type:`step`,stepId:n.stepMetadata.stepId,attempt:n.stepMetadata.attempt},...t.allowReservedAttributes===!0?{allowReservedAttributes:!0}:{}}})}}function D(){let e=a.getStore();return e||y(`getStepMetadata()`,`https://workflow-sdk.dev/docs/api-reference/workflow/get-step-metadata`,D),e.stepMetadata}function O(){let e=a.getStore();return e||_(`getWorkflowMetadata()`,`https://workflow-sdk.dev/docs/api-reference/workflow/get-workflow-metadata`,O),e.workflowMetadata}function k(d={}){let h=a.getStore();h||_(`getWritable()`,`https://workflow-sdk.dev/docs/api-reference/workflow/get-writable`,k);let{namespace:g}=d,v=h.workflowMetadata.workflowRunId,y=i(v,g);h.writables??=new Map;let b=h.writables,x=b.get(y);if(x)return x.writable;let S=t(r(globalThis,h.ops,v,h.encryptionKey,!0,h.runReadyBarrier),h.encryptionKey),C=new e(v,y,h.runReadyBarrier),w=o();return h.ops.push(w.promise),l(S.readable,C,w).catch(()=>{}),m(S.writable,w),Object.defineProperty(S.writable,f,{value:y,writable:!1}),Object.defineProperty(S.writable,s,{value:v,writable:!1}),h.workflowDeploymentId&&Object.defineProperty(S.writable,u,{value:h.workflowDeploymentId,writable:!1}),n(h.encryptionKey)&&Object.defineProperty(S.writable,c,{value:p(h.encryptionKey.keyPair.publicKey),writable:!1}),b.set(y,{writable:S.writable,state:w}),S.writable}export{h as FatalError,g as RetryableError,C as createHook,w as createWebhook,T as defineHook,D as getStepMetadata,O as getWorkflowMetadata,k as getWritable,E as setAttributes,S as sleep};
@@ -132,6 +132,13 @@ interface DeliveryBarrierEntry {
132
132
  * once a consumer takes the payload.
133
133
  */
134
134
  armed: boolean;
135
+ /**
136
+ * Retire this entry: resolve `delivered` and remove it from the registry,
137
+ * exactly as `markDelivered` would. Called only by the context's safety-net
138
+ * dispenser ({@link ensureBarrierSafetyNet}), and only on the lowest-index
139
+ * entry at delivery idle. Idempotent.
140
+ */
141
+ retire: () => void;
135
142
  }
136
143
  /**
137
144
  * Awaits, in strict event-log order, every still-registered delivery that is
@@ -172,18 +179,18 @@ interface DeliveryBarrierEntry {
172
179
  * in log order; {@link hasParkedCommittedDelivery} deliberately reports such a
173
180
  * step as not self-resolving so that idle stays reachable.
174
181
  *
175
- * "The whole chain then delivers in log order" rests on the PAYLOAD's safety
176
- * net observing idle before the net of the wait parked behind it. If the
177
- * wait's net fired first, the step's gate would open while the wait was still
178
- * parked on the payload barrier and the inversion above would reappear. Within
179
- * one drain window that order is structural, and carried by FIFO of the
180
- * safety-net polls: nets arm via `setTimeout` in log order during synchronous
181
- * consumption, each polling round re-arms through `promiseQueue.then(...)` in
182
- * the order the checks ran, and each net that fires flips
183
- * {@link hasParkedCommittedDelivery} back to true, re-blocking the rest until
184
- * the released delivery completes. Replay — where divergence manifests —
185
- * always consumes the log in one window. Do not "optimize" the net scheduling
186
- * in a way that breaks that per-window FIFO.
182
+ * "The whole chain then delivers in log order" rests on the PAYLOAD's barrier
183
+ * being retired before that of anything parked behind it. That order is
184
+ * structural: safety-net retirements go through one per-context dispenser that
185
+ * only ever retires the lowest-index entry at delivery idle, and every
186
+ * retirement that wakes a chain flips {@link hasParkedCommittedDelivery} back
187
+ * to true, re-blocking the dispenser until the chain has drained — see
188
+ * {@link ensureBarrierSafetyNet}. (This used to rest on the FIFO of one idle
189
+ * poll per barrier, which held for a single parked segment but decayed to
190
+ * timing noise with several — the release order, and therefore the ULIDs
191
+ * drawn by the woken branches, then depended on how much log the replay had
192
+ * loaded. storm-log-replay.test.ts replays a production log corrupted exactly
193
+ * that way.)
187
194
  */
188
195
  export declare function awaitEarlierDeliveries(ctx: WorkflowOrchestratorContext, eventIndex: number | undefined, kind: DeliveryKind): Promise<void>;
189
196
  /** Handle for a registered branch-deciding delivery barrier. */
@@ -273,6 +280,18 @@ export declare function hasParkedCommittedDelivery(ctx: WorkflowOrchestratorCont
273
280
  * what it has and has not done yet says nothing about the run. Two callers
274
281
  * read it, for the two such decisions: {@link scheduleWhenIdle} for the
275
282
  * suspension, and the events consumer's unconsumed-event check for divergence.
283
+ *
284
+ * A non-empty barrier registry counts as in flight, even when every remaining
285
+ * entry is parked behind an unclaimed buffered payload. Those entries only
286
+ * move when the safety-net dispenser retires them (lowest-first, see
287
+ * {@link ensureBarrierSafetyNet}), and the deliveries they release are real
288
+ * workflow reactions — a suspension raised before they run would be computed
289
+ * from a VM that has not seen them, scheduling none of their follow-up work
290
+ * and leaving the run dormant (the vercel/workflow#3183 shape). The dispenser
291
+ * itself is gated on {@link canRetireAbandonedBarriers}, the weaker predicate
292
+ * without the registry term, precisely so it can do the draining that this
293
+ * predicate waits for; registry size strictly decreases at each retirement,
294
+ * so idle is always reached.
276
295
  */
277
296
  export declare function isDeliveryIdle(ctx: WorkflowOrchestratorContext): boolean;
278
297
  /**
@@ -1 +1 @@
1
- import{a as e,i as t,n,o as r,r as i,s as a,t as o}from"../../_chunks/workflow/private-z_2Kcwee.js";export{o as awaitEarlierDeliveries,n as getStepFunction,i as hasParkedCommittedDelivery,t as isDeliveryIdle,e as registerDeliveryBarrier,r as registerStepFunction,a as scheduleWhenIdle};
1
+ import{a as e,i as t,n,o as r,r as i,s as a,t as o}from"../../_chunks/workflow/private-CuQ4HTFC.js";export{o as awaitEarlierDeliveries,n as getStepFunction,i as hasParkedCommittedDelivery,t as isDeliveryIdle,e as registerDeliveryBarrier,r as registerStepFunction,a as scheduleWhenIdle};
@@ -120,6 +120,33 @@ export declare const MAX_RESILIENT_STEP_INPUT_BYTES: number;
120
120
  * latency the parallel publish saves.
121
121
  */
122
122
  export declare function isResilientStepDispatchEnabled(): boolean;
123
+ /**
124
+ * Whether batched event transitions are enabled: the suspension handler folds
125
+ * a clean fan-out's `step_created` + `wait_created` writes into one
126
+ * `world.events.createBatch` call (one durable write, per-event outcomes)
127
+ * instead of one write per event. Only engages when the World implements the
128
+ * optional `events.createBatch` AND the run is on slot identity
129
+ * (specVersion >= 6) AND the suspension carries no attribute/hook writes and
130
+ * no resilient step dispatch — everything else keeps the single-event path
131
+ * byte-for-byte.
132
+ *
133
+ * Reads `process.env.WORKFLOW_BATCH_TRANSITIONS` lazily. Default **ON**;
134
+ * disabled only by an explicit `'0'` / `'false'` (case-insensitive) — the
135
+ * operator escape hatch that restores the exact prior one-write-per-event
136
+ * path, mirroring `WORKFLOW_TURBO`'s kill-switch shape.
137
+ */
138
+ export declare function isBatchTransitionsEnabled(): boolean;
139
+ /**
140
+ * Ceiling on events per `createBatch` call from the batched fan-out fold.
141
+ * Mirrors the server's transaction budgets with a comfortable margin: each
142
+ * fan-out event costs 2 transaction items server-side (entity + event row)
143
+ * against the 100-item DynamoDB cap, and inline payloads count against a
144
+ * 768 KB byte budget — 32 events stays well under both, and a fan-out larger
145
+ * than this simply commits in successive batches (split batches lose
146
+ * cross-batch atomicity, which is exactly today's per-event-write crash
147
+ * surface — every batch still converges on retry via per-event 409s).
148
+ */
149
+ export declare const MAX_BATCH_FANOUT_EVENTS = 32;
123
150
  /**
124
151
  * Optional client-side override for the server-supplied per-run event ceiling.
125
152
  * When set to a positive integer, the runtime clamps the server's limit *down*
@@ -101,6 +101,8 @@ export declare function runWorkflowWithQuickJS(params: {
101
101
  * the in-flight body instead of requeueing the step.
102
102
  */
103
103
  ownerMessageId?: string;
104
+ /** Request ID of the queue invocation, when the queue provides one. */
105
+ requestId?: string;
104
106
  /**
105
107
  * Queue namespace resolved at route registration (runtime.ts). Must be
106
108
  * threaded into every message publish: the builders bake the namespace
@@ -1,4 +1,4 @@
1
- import type { Event, SerializedData, World } from '#compiled/@workflow/world/index.js';
1
+ import type { Event, SerializedData, StartedStep, World } from '#compiled/@workflow/world/index.js';
2
2
  import type { PayloadKey } from '../serialization/encryption.js';
3
3
  import { type SlotSnapshotParams } from './helpers.js';
4
4
  import { ReplayRecoveryReporter } from './replay-recovery-reporter.js';
@@ -12,6 +12,8 @@ export interface StepExecutorParams {
12
12
  workflowDeploymentId?: string;
13
13
  workflowName: string;
14
14
  workflowStartedAt: number;
15
+ /** Request ID of the invocation executing this step, when provided by its queue. */
16
+ requestId?: string;
15
17
  /** Root run id of this run's lineage, carried into the step context. */
16
18
  rootRunId?: string;
17
19
  stepId: string;
@@ -35,6 +37,17 @@ export interface StepExecutorParams {
35
37
  * carries no payload (the legacy contract).
36
38
  */
37
39
  lazyStepInput?: SerializedData;
40
+ /**
41
+ * Pre-claimed inline start: the suspension handler committed (or lost) this
42
+ * step's `step_created` + `step_started` pair inside its batched fan-out
43
+ * write, so the start this executor would otherwise send has already been
44
+ * decided. `owned: false` returns `{ type: 'skipped' }` before any write —
45
+ * the same outcome as losing the lazy claim's atomic create. `owned: true`
46
+ * skips both start paths (no start write at all) and runs the body against
47
+ * the claimed step. Mutually exclusive with `lazyStepInput`: the input
48
+ * already rode the pair's `step_created`, and the claimed step carries it.
49
+ */
50
+ preclaimedStart?: PreclaimedInlineStart;
38
51
  /**
39
52
  * Inline step ownership: the queue message ID of the invocation this
40
53
  * executeStep call runs in (from the queue handler's meta). When set, the
@@ -140,6 +153,41 @@ export interface StepExecutorParams {
140
153
  /** One-shot recovery telemetry activated by the orchestrator replay. */
141
154
  replayRecoveryReporter?: ReplayRecoveryReporter;
142
155
  }
156
+ /**
157
+ * The settled outcome of a `step_created` + `step_started` pair the
158
+ * suspension handler folded into its batched fan-out write (see
159
+ * `SuspensionHandlerResult.inlineClaims`). Handed to executeStep as
160
+ * {@link StepExecutorParams.preclaimedStart} so the executor runs (or skips)
161
+ * the body off the batch's verdict instead of sending a start of its own.
162
+ */
163
+ export type PreclaimedInlineStart = {
164
+ /** The pair committed: this execution owns the step and runs the body. */
165
+ owned: true;
166
+ /**
167
+ * The started step entity from the batch result, with the locally
168
+ * dehydrated input attached by the suspension handler (batch responses
169
+ * return refs lazily; the body's hydration wants the same bytes the
170
+ * pair's `step_created` carried).
171
+ */
172
+ step: StartedStep;
173
+ /**
174
+ * `Date.now()` taken right before the batch POST that carried the pair
175
+ * — the claim's "start POST sent" instant, anchoring RSFS exactly like
176
+ * the lazy claim's own POST would.
177
+ */
178
+ batchPostSentAtMs?: number;
179
+ /**
180
+ * `Date.now()` taken right after that batch POST returned — the
181
+ * claim's completion instant (T6 of the hook-resume TTR window).
182
+ */
183
+ claimCompletedAtMs?: number;
184
+ } | {
185
+ /**
186
+ * The pair lost its atomic create-claim (per-event 409): a concurrent
187
+ * writer owns the step, so the body must not run here.
188
+ */
189
+ owned: false;
190
+ };
143
191
  /**
144
192
  * Inline-delta returned by a step-terminal write when the caller passed
145
193
  * {@link StepExecutorParams.inlineDeltaSinceCursor} and the World supports
@@ -193,5 +193,11 @@ export declare function computeStepLatencyEventData(params: {
193
193
  lazyStepStart: boolean;
194
194
  /** Whether the body ran optimistically, without awaiting step_started. */
195
195
  optimisticStart: boolean;
196
+ /**
197
+ * Whether the step's `step_created` + `step_started` pair was pre-claimed
198
+ * inside the suspension handler's batched fan-out write (no start POST of
199
+ * its own at all).
200
+ */
201
+ preclaimedStart?: boolean;
196
202
  }): StepLatencyEventData | undefined;
197
203
  //# sourceMappingURL=step-latency.d.ts.map
@@ -3,6 +3,7 @@ import { type SerializedData, type TraceCarrier, type ValidQueueName, type Workf
3
3
  import type { StepInvocationQueueItem, WorkflowSuspension } from '../global.js';
4
4
  import { type LoadedEventLog } from './helpers.js';
5
5
  import { ReplayRecoveryReporter } from './replay-recovery-reporter.js';
6
+ import type { PreclaimedInlineStart } from './step-executor.js';
6
7
  export interface SuspensionHandlerParams {
7
8
  suspension: WorkflowSuspension;
8
9
  world: World;
@@ -52,6 +53,31 @@ export interface SuspensionHandlerParams {
52
53
  */
53
54
  getTraceCarrier: () => Promise<TraceCarrier>;
54
55
  };
56
+ /**
57
+ * Inline step ownership: the queue message ID of the invocation this
58
+ * suspension runs in (the queue handler's meta). When present AND the
59
+ * batched fan-out engages, the lazy-inline steps' deferred writes are
60
+ * folded into the batch as `step_created` + `step_started` pairs — the
61
+ * started row stamped with this ID, exactly like the lazy claim it
62
+ * replaces — pre-claiming the steps the caller is about to run inline. See
63
+ * {@link SuspensionHandlerResult.inlineClaims}. Callers that never
64
+ * inline-execute (terminal drain) omit it, keeping their lazy steps on the
65
+ * plain deferred path.
66
+ */
67
+ ownerMessageId?: string;
68
+ /**
69
+ * Lets the batched fan-out return before every chunk has committed: only
70
+ * the chunk carrying the pre-claimed inline pairs gates the handler's
71
+ * return (its claims are what the caller starts bodies from), while the
72
+ * trailing chunks' commits — and every chunk's in-flush step-message
73
+ * publishes — ride {@link SuspensionHandlerResult.deferredBatchWork}. A
74
+ * caller that opts in MUST await that promise before acking its delivery:
75
+ * the durability contract ("every create durable before ack") moves from
76
+ * the handler's return to that join, and nothing else re-drives a lost
77
+ * trailing chunk. Callers that don't opt in (terminal drain, default)
78
+ * keep the everything-durable-at-return behavior.
79
+ */
80
+ allowDeferredBatchWork?: boolean;
55
81
  }
56
82
  /**
57
83
  * Result of handling a suspension. Returns pending step items so the caller
@@ -104,6 +130,60 @@ export interface SuspensionHandlerResult {
104
130
  stepName: string;
105
131
  dehydratedInput: SerializedData;
106
132
  }>;
133
+ /**
134
+ * Pre-claimed inline starts, by correlation id: the per-step verdicts of
135
+ * the `step_created` + `step_started` pairs the batched fan-out committed
136
+ * for the lazy-inline steps. A step with an entry here is passed to
137
+ * `executeStep` as `preclaimedStart` INSTEAD of `lazyStepInput` — its
138
+ * input already rode the pair, and the claim is settled: `owned: true`
139
+ * carries the started attempt-1 entity (input re-attached) so the body
140
+ * runs straight off the batch commit with no start write of its own;
141
+ * `owned: false` lost the pair's atomic create-claim to a concurrent
142
+ * writer, and executeStep returns `skipped` without running the body —
143
+ * the same outcome as losing the lazy claim. Empty whenever the fold did
144
+ * not engage (batching off, no `ownerMessageId`, or the lone-inline case,
145
+ * which keeps the optimistic lazy path and its claim/body overlap).
146
+ *
147
+ * Crash window: the pair commits before the caller runs the body, so a
148
+ * crash between them leaves a started step stamped with this message's
149
+ * ID. Redelivery of the same message re-executes it via the owned-recovery
150
+ * path — the exact machinery the lazy claim's crash window already uses.
151
+ */
152
+ inlineClaims: Map<string, PreclaimedInlineStart>;
153
+ /**
154
+ * The highest slot the batched fan-out committed, when it ran. The batch's
155
+ * own events are not in the caller's loaded log (the next reload picks
156
+ * them up), so the caller folds this ceiling into the slot snapshot it
157
+ * hands the inline executions — otherwise every inline terminal write
158
+ * would name a pre-batch position and be answered with a skipped-slot
159
+ * report echoing the events this suspension just wrote. Under
160
+ * {@link SuspensionHandlerParams.allowDeferredBatchWork} this covers the
161
+ * chunks that had committed by the handler's return (always the pair
162
+ * chunk); a trailing chunk that commits later is echoed back on the
163
+ * terminal writes like any foreign event — reports the executor reads for
164
+ * position and discards.
165
+ *
166
+ * So the echo is only fully suppressed for a SINGLE-chunk fold. On a
167
+ * multi-chunk fan-out the bodies start off the pair chunk while trailing
168
+ * chunks are still in flight, and an inline terminal write issued in that
169
+ * window still names a position below them and still draws a report for
170
+ * their events. Bounded (trailing chunks only, large fan-outs only) and
171
+ * self-correcting on the next reload — recorded so a report seen there
172
+ * reads as expected rather than as a bug.
173
+ */
174
+ batchCommittedSlotCeiling?: number;
175
+ /**
176
+ * The batched fan-out's deferred work, present only when the caller opted
177
+ * in via {@link SuspensionHandlerParams.allowDeferredBatchWork} and
178
+ * trailing work exists: the commits of every chunk except the pair chunk,
179
+ * plus every chunk's step-message publishes (each chained on ITS OWN
180
+ * chunk's commit, so publish-after-create holds per step). The caller
181
+ * MUST await it before acking — a rejection here is a failed suspension
182
+ * write and fails the delivery exactly as it would have at the handler's
183
+ * return. Steps whose messages this work publishes are already in
184
+ * {@link queuedStepCorrelationIds} at return time.
185
+ */
186
+ deferredBatchWork?: Promise<void>;
107
187
  /**
108
188
  * The soonest pending wait, if any: seconds until it elapses and the
109
189
  * correlationId of the wait that produced that timeout. The
@@ -153,5 +233,5 @@ export interface SuspensionHandlerResult {
153
233
  * 1. Hooks are processed first to prevent race conditions with webhook receivers
154
234
  * 2. Step events and wait events are created in parallel
155
235
  */
156
- export declare function handleSuspension({ suspension, world, run, span, requestId, eventLog, runReadyBarrier, replayRecoveryReporter, stepDispatch, }: SuspensionHandlerParams): Promise<SuspensionHandlerResult>;
236
+ export declare function handleSuspension({ suspension, world, run, span, requestId, eventLog, runReadyBarrier, replayRecoveryReporter, stepDispatch, ownerMessageId, allowDeferredBatchWork, }: SuspensionHandlerParams): Promise<SuspensionHandlerResult>;
157
237
  //# sourceMappingURL=suspension-handler.d.ts.map