eve 0.22.2 → 0.22.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/dist/src/chunks/{use-eve-agent-CM24ZUEI.js → use-eve-agent-Cojyfr4X.js} +25 -13
  3. package/dist/src/chunks/{use-eve-agent-CxcKypLZ.js → use-eve-agent-D-S1TPCW.js} +25 -13
  4. package/dist/src/cli/dev/url.js +1 -1
  5. package/dist/src/client/client-error.d.ts +5 -1
  6. package/dist/src/client/client-error.js +1 -1
  7. package/dist/src/client/client.js +1 -1
  8. package/dist/src/client/open-stream.js +1 -1
  9. package/dist/src/client/session.js +1 -1
  10. package/dist/src/client/types.d.ts +2 -1
  11. package/dist/src/client/url.js +1 -1
  12. package/dist/src/compiler/manifest.d.ts +40 -2
  13. package/dist/src/compiler/manifest.js +1 -1
  14. package/dist/src/compiler/module-map.js +2 -2
  15. package/dist/src/compiler/normalize-extension.d.ts +68 -0
  16. package/dist/src/compiler/normalize-extension.js +1 -0
  17. package/dist/src/compiler/normalize-manifest.js +2 -2
  18. package/dist/src/compiler/workspace-resources.js +1 -1
  19. package/dist/src/context/dynamic-skill-lifecycle.js +1 -1
  20. package/dist/src/context/dynamic-tool-lifecycle.js +1 -1
  21. package/dist/src/discover/discover-agent.d.ts +14 -1
  22. package/dist/src/discover/discover-agent.js +1 -1
  23. package/dist/src/discover/extension-specifier.d.ts +15 -0
  24. package/dist/src/discover/extension-specifier.js +1 -0
  25. package/dist/src/discover/extensions.d.ts +109 -0
  26. package/dist/src/discover/extensions.js +1 -0
  27. package/dist/src/discover/filesystem.d.ts +1 -1
  28. package/dist/src/discover/filesystem.js +1 -1
  29. package/dist/src/discover/grammar.d.ts +27 -0
  30. package/dist/src/discover/grammar.js +1 -1
  31. package/dist/src/discover/manifest.d.ts +46 -0
  32. package/dist/src/discover/manifest.js +1 -1
  33. package/dist/src/evals/assertions/run.d.ts +3 -2
  34. package/dist/src/evals/assertions/run.js +2 -2
  35. package/dist/src/evals/index.d.ts +1 -1
  36. package/dist/src/evals/loaders/yaml.js +1 -1
  37. package/dist/src/evals/match.d.ts +11 -6
  38. package/dist/src/execution/sandbox/bindings/microsandbox-network.js +1 -1
  39. package/dist/src/internal/application/package.js +1 -1
  40. package/dist/src/internal/authored-module-loader.d.ts +14 -0
  41. package/dist/src/internal/authored-module-loader.js +2 -2
  42. package/dist/src/internal/authored-module-map-loader.js +1 -1
  43. package/dist/src/internal/bundler/extension-scope-plugin.d.ts +37 -0
  44. package/dist/src/internal/bundler/extension-scope-plugin.js +3 -0
  45. package/dist/src/internal/helpers/gray-matter.d.ts +25 -0
  46. package/dist/src/internal/helpers/gray-matter.js +1 -0
  47. package/dist/src/internal/helpers/markdown.js +1 -1
  48. package/dist/src/internal/nitro/dev-runtime-source-snapshot-copy.js +1 -1
  49. package/dist/src/internal/nitro/host/build-application.js +1 -1
  50. package/dist/src/internal/nitro/host/build-extension.d.ts +24 -0
  51. package/dist/src/internal/nitro/host/build-extension.js +4 -0
  52. package/dist/src/internal/nitro/host/create-application-nitro.js +1 -1
  53. package/dist/src/public/channels/discord/discordChannel.js +1 -1
  54. package/dist/src/public/channels/slack/api.js +1 -1
  55. package/dist/src/public/channels/slack/mrkdwn.d.ts +0 -2
  56. package/dist/src/public/channels/slack/mrkdwn.js +1 -1
  57. package/dist/src/public/definitions/extension.d.ts +68 -0
  58. package/dist/src/public/definitions/extension.js +1 -0
  59. package/dist/src/public/extension/index.d.ts +10 -0
  60. package/dist/src/public/extension/index.js +1 -0
  61. package/dist/src/runtime/connections/openapi-client.js +1 -1
  62. package/dist/src/runtime/connections/openapi-spec.js +1 -1
  63. package/dist/src/runtime/resolve-dynamic-skill.js +1 -1
  64. package/dist/src/runtime/resolve-dynamic-tool.js +1 -1
  65. package/dist/src/runtime/types.d.ts +10 -0
  66. package/dist/src/services/dev-client/vercel-auth-error.d.ts +2 -2
  67. package/dist/src/services/dev-client/vercel-auth-error.js +3 -3
  68. package/dist/src/setup/scaffold/create/project.js +3 -3
  69. package/dist/src/svelte/index.js +1 -1
  70. package/dist/src/svelte/use-eve-agent.js +1 -1
  71. package/dist/src/vue/index.js +1 -1
  72. package/dist/src/vue/use-eve-agent.js +1 -1
  73. package/docs/channels/custom.mdx +2 -2
  74. package/docs/channels/linear.mdx +1 -1
  75. package/docs/channels/slack.mdx +2 -0
  76. package/docs/concepts/context-control.md +1 -1
  77. package/docs/connections/openapi.mdx +3 -1
  78. package/docs/evals/assertions.mdx +4 -2
  79. package/docs/extensions.md +155 -0
  80. package/docs/guides/client/overview.mdx +1 -1
  81. package/docs/guides/dev-tui.md +4 -0
  82. package/docs/guides/dynamic-capabilities.md +3 -3
  83. package/docs/guides/instrumentation.md +1 -1
  84. package/docs/guides/state.md +3 -3
  85. package/docs/instructions.mdx +1 -1
  86. package/docs/meta.json +1 -0
  87. package/docs/patterns/dynamic-scheduling.md +11 -11
  88. package/docs/patterns/multi-tenant-approvals.md +6 -6
  89. package/docs/patterns/multi-tenant-auth.md +13 -13
  90. package/docs/patterns/multi-tenant-memory.md +9 -9
  91. package/docs/schedules.mdx +1 -1
  92. package/docs/tutorial/guard-the-spend.mdx +2 -2
  93. package/docs/tutorial/query-sample-data.mdx +1 -1
  94. package/docs/tutorial/remember-definitions.mdx +2 -2
  95. package/docs/tutorial/ship-it.mdx +1 -1
  96. package/package.json +6 -1
@@ -0,0 +1 @@
1
+ import{join,relative}from"node:path";import{compileConnectionDefinition}from"#compiler/normalize-connection.js";import{compileHookEntry}from"#compiler/normalize-hook.js";import{compileInstructionsEntry}from"#compiler/normalize-instructions.js";import{compileSkillSource}from"#compiler/normalize-skill.js";import{compileToolEntry}from"#compiler/normalize-tool.js";async function compileExtensionContributions(e){let{mount:t,consumerAgentRoot:n}=e,r={externalDependencies:e.externalDependencies},i=await composeManifestContributions({manifest:t.manifest,namespace:t.namespace,consumerAgentRoot:n,options:r,sourceIdScope:`ext:${t.namespace}`,role:`extension`});if(t.overrides===void 0)return i.contributions;let a=await composeManifestContributions({manifest:t.overrides,namespace:t.namespace,consumerAgentRoot:n,options:r,sourceIdScope:`ext-override:${t.namespace}`,role:`override`});return applyOverrideDisables({merged:mergeContributions(a.contributions,i.contributions),disables:a.disabledToolTargets,extensionToolNames:new Set(i.contributions.tools.map(e=>e.name)),extensionDynamicToolSlugs:new Set(i.contributions.dynamicTools.map(e=>e.slug)),namespace:t.namespace})}function applyOverrideDisables(e){if(e.disables.length===0)return e.merged;let t=e.namespace.length+2,n=new Set;for(let r of e.disables){if(!e.extensionToolNames.has(r.name)&&!e.extensionDynamicToolSlugs.has(r.name)){let n=[...e.extensionToolNames,...e.extensionDynamicToolSlugs].map(e=>e.slice(t)).sort();throw Error(`The override "agent/extensions/${e.namespace}/${r.logicalPath}" calls disableTool(), but the "${e.namespace}" extension contributes no tool named "${r.name.slice(t)}". It contributes: ${n.length>0?n.join(`, `):`(no tools)`}.`)}n.add(r.name)}return{...e.merged,tools:e.merged.tools.filter(e=>!n.has(e.name)),dynamicTools:e.merged.dynamicTools.filter(e=>!n.has(e.slug))}}async function composeManifestContributions(o){let{manifest:s,namespace:c,consumerAgentRoot:l,options:u,sourceIdScope:d,role:f}=o,p=s.agentRoot,m=`${c}__`,scopeSourceId=e=>`${d}:${e}`,rebase=n=>relative(l,join(p,n)).replaceAll(`\\`,`/`),h=[],g=[],_=[];for(let e of s.tools){let t=await compileToolEntry(p,e,u);if(t.kind===`tool`)h.push({...t.definition,name:`${m}${t.definition.name}`,sourceId:scopeSourceId(t.definition.sourceId),logicalPath:rebase(t.definition.logicalPath)});else if(t.kind===`dynamic-tool`)g.push({...t.definition,slug:`${m}${t.definition.slug}`,extensionNamespace:c,sourceId:scopeSourceId(t.definition.sourceId),logicalPath:rebase(t.definition.logicalPath)});else if(t.kind===`enable-workflow`)throw Error(`${describeExtensionSource(f,c,e.logicalPath)} enables the Workflow tool, but the Workflow tool is the consuming agent's to enable, not an extension's. Remove it.`);else if(f===`extension`)throw Error(`${describeExtensionSource(f,c,e.logicalPath)} calls disableTool(), but an extension cannot disable framework tools — that is the consuming agent's to own. Remove it.`);else _.push({name:`${m}${t.name}`,logicalPath:e.logicalPath})}let v=s.hooks.map(e=>{let t=compileHookEntry(e);return{...t,slug:`${m}${t.slug}`,sourceId:scopeSourceId(t.sourceId),logicalPath:rebase(t.logicalPath)}}),y=[],b=[];for(let e of s.skills){let t=await compileSkillSource(p,e,u);t.kind===`skill`?y.push({...t.definition,name:`${m}${t.definition.name}`,sourceId:scopeSourceId(t.definition.sourceId),logicalPath:rebase(t.definition.logicalPath)}):b.push({...t.definition,slug:`${m}${t.definition.slug}`,extensionNamespace:c,sourceId:scopeSourceId(t.definition.sourceId),logicalPath:rebase(t.definition.logicalPath)})}let x=(await Promise.all(s.connections.map(e=>compileConnectionDefinition(p,e,u)))).map(e=>({...e,connectionName:`${m}${e.connectionName}`,sourceId:scopeSourceId(e.sourceId),logicalPath:rebase(e.logicalPath)})),S=[],C=[];for(let e of s.instructions){let t=await compileInstructionsEntry(p,e,u);t.kind===`instructions`?C.push(t.definition.markdown):S.push({...t.definition,slug:`${m}${t.definition.slug}`,sourceId:scopeSourceId(t.definition.sourceId),logicalPath:rebase(t.definition.logicalPath)})}return{contributions:{tools:h,dynamicTools:g,hooks:v,skills:y,dynamicSkills:b,dynamicInstructions:S,connections:x,instructionFragments:C},disabledToolTargets:_}}function describeExtensionSource(e,t,n){return e===`override`?`The override "agent/extensions/${t}/${n}"`:`The "${t}" extension's "${n}"`}function mergeContributions(e,t){return{tools:dedupeBy([...e.tools,...t.tools],e=>e.name),dynamicTools:dedupeBy([...e.dynamicTools,...t.dynamicTools],e=>e.slug),connections:dedupeBy([...e.connections,...t.connections],e=>e.connectionName),skills:dedupeBy([...e.skills,...t.skills],e=>e.name),hooks:[...e.hooks,...t.hooks],dynamicSkills:[...e.dynamicSkills,...t.dynamicSkills],dynamicInstructions:[...e.dynamicInstructions,...t.dynamicInstructions],instructionFragments:[...e.instructionFragments,...t.instructionFragments]}}function dedupeBy(e,t){let n=new Set,r=[];for(let i of e){let e=t(i);n.has(e)||(n.add(e),r.push(i))}return r}export{applyOverrideDisables,compileExtensionContributions,mergeContributions};
@@ -1,3 +1,3 @@
1
- import{compileChannelDefinition}from"#compiler/normalize-channel.js";import{ROOT_COMPILED_AGENT_NODE_ID,createCompiledAgentManifest,createCompiledAgentNodeManifest}from"#compiler/manifest.js";import{createCompiledRuntimeModelCatalogLoader}from"#compiler/model-catalog.js";import{compileAgentConfig}from"#compiler/normalize-agent-config.js";import{compileConnectionDefinition}from"#compiler/normalize-connection.js";import{compileHookEntry}from"#compiler/normalize-hook.js";import{compileSandboxDefinition}from"#compiler/normalize-sandbox.js";import{compileInstructionsEntry}from"#compiler/normalize-instructions.js";import{compileScheduleDefinition}from"#compiler/normalize-schedule.js";import{compileSkillSource}from"#compiler/normalize-skill.js";import{compileSubagentGraph}from"#compiler/normalize-subagent.js";import{compileToolEntry}from"#compiler/normalize-tool.js";async function compileAgentManifest(e){let r={modelCatalog:createCompiledRuntimeModelCatalogLoader(e.appRoot)},a=await compileAgentNodeManifest(e,r),o=await compileSubagentGraph({appRoot:e.appRoot,compileAgentNodeManifest,context:r,externalDependencies:a.config.build?.externalDependencies??[],parentNodeId:ROOT_COMPILED_AGENT_NODE_ID,subagents:e.subagents});return createCompiledAgentManifest({...a,remoteAgents:o.remoteAgents,subagentEdges:o.edges,subagents:o.nodes})}async function compileAgentNodeManifest(t,n,i={}){let s=await compileAgentConfig(t,n);if(i.allowWorkflowConfig===!1&&s.experimental?.workflow!==void 0)throw Error(`Workflow runtime configuration is only supported on the root agent config. Remove "experimental.workflow" from "${t.agentId}".`);let c=mergeExternalDependencies(i.externalDependencies,s.build?.externalDependencies),l=c.length===0?s:{...s,build:{...s.build,externalDependencies:c}},u=await Promise.all(t.tools.map(e=>compileToolEntry(t.agentRoot,e,{externalDependencies:c}))),d=[],f=[],p=[],m=!1;for(let e of u)e.kind===`tool`?d.push(e.definition):e.kind===`dynamic-tool`?f.push(e.definition):e.kind===`enable-workflow`?m=!0:p.push(e.name);let h=(await Promise.all(t.channels.map(n=>compileChannelDefinition(t.agentRoot,n,{externalDependencies:c})))).flat(),g=await Promise.all(t.skills.map(e=>compileSkillSource(t.agentRoot,e,{externalDependencies:c}))),_=[],v=[];for(let e of g)e.kind===`skill`?_.push(e.definition):v.push(e.definition);let y=await Promise.all(t.instructions.map(e=>compileInstructionsEntry(t.agentRoot,e,{externalDependencies:c}))),b=[],x=[];for(let e of y)e.kind===`instructions`?b.push(e.definition):x.push(e.definition);let S=b.length===0?void 0:b.length===1?b[0]:{name:`instructions`,logicalPath:`instructions`,markdown:b.map(e=>e.markdown).join(`
1
+ import{compileChannelDefinition}from"#compiler/normalize-channel.js";import{ROOT_COMPILED_AGENT_NODE_ID,createCompiledAgentManifest,createCompiledAgentNodeManifest}from"#compiler/manifest.js";import{compileConnectionDefinition}from"#compiler/normalize-connection.js";import{compileHookEntry}from"#compiler/normalize-hook.js";import{compileInstructionsEntry}from"#compiler/normalize-instructions.js";import{compileSkillSource}from"#compiler/normalize-skill.js";import{compileToolEntry}from"#compiler/normalize-tool.js";import{mountRefNamespace,packageStateNamespace}from"#discover/extensions.js";import{createCompiledRuntimeModelCatalogLoader}from"#compiler/model-catalog.js";import{compileAgentConfig}from"#compiler/normalize-agent-config.js";import{compileExtensionContributions}from"#compiler/normalize-extension.js";import{compileSandboxDefinition}from"#compiler/normalize-sandbox.js";import{compileScheduleDefinition}from"#compiler/normalize-schedule.js";import{compileSubagentGraph}from"#compiler/normalize-subagent.js";async function compileAgentManifest(e){let r={modelCatalog:createCompiledRuntimeModelCatalogLoader(e.appRoot)},i=await compileAgentNodeManifest(e,r),a=await compileSubagentGraph({appRoot:e.appRoot,compileAgentNodeManifest,context:r,externalDependencies:i.config.build?.externalDependencies??[],parentNodeId:ROOT_COMPILED_AGENT_NODE_ID,subagents:e.subagents}),o=e.resolvedExtensions.map(t=>{let n=e.extensions.find(e=>mountRefNamespace(e.logicalPath)===t.namespace);return{namespace:t.namespace,packageName:t.packageName,packageNamespace:packageStateNamespace(t.packageName),sourceRoot:t.sourceRoot,mountSourceId:n?.sourceId??`extensions/${t.namespace}`,mountLogicalPath:n?.logicalPath??`extensions/${t.namespace}`}});return createCompiledAgentManifest({...i,extensionMounts:o,remoteAgents:a.remoteAgents,subagentEdges:a.edges,subagents:a.nodes})}async function compileAgentNodeManifest(t,n,s={}){let c=await compileAgentConfig(t,n);if(s.allowWorkflowConfig===!1&&c.experimental?.workflow!==void 0)throw Error(`Workflow runtime configuration is only supported on the root agent config. Remove "experimental.workflow" from "${t.agentId}".`);let l=mergeExternalDependencies(s.externalDependencies,c.build?.externalDependencies),u=l.length===0?c:{...c,build:{...c.build,externalDependencies:l}},d=await Promise.all(t.tools.map(e=>compileToolEntry(t.agentRoot,e,{externalDependencies:l}))),f=[],p=[],m=[],h=!1;for(let e of d)e.kind===`tool`?f.push(e.definition):e.kind===`dynamic-tool`?p.push(e.definition):e.kind===`enable-workflow`?h=!0:m.push(e.name);let g=(await Promise.all(t.channels.map(n=>compileChannelDefinition(t.agentRoot,n,{externalDependencies:l})))).flat(),_=await Promise.all(t.skills.map(e=>compileSkillSource(t.agentRoot,e,{externalDependencies:l}))),v=[],y=[];for(let e of _)e.kind===`skill`?v.push(e.definition):y.push(e.definition);let b=await Promise.all(t.instructions.map(e=>compileInstructionsEntry(t.agentRoot,e,{externalDependencies:l}))),x=[],S=[];for(let e of b)e.kind===`instructions`?x.push(e.definition):S.push(e.definition);let C=await Promise.all(t.connections.map(e=>compileConnectionDefinition(t.agentRoot,e,{externalDependencies:l}))),w=t.hooks.map(e=>compileHookEntry(e)),T=await Promise.all(t.schedules.map(e=>compileScheduleDefinition(t.agentRoot,e,{externalDependencies:l}))),E=new Set(f.map(e=>e.name)),D=new Set(p.map(e=>e.slug)),O=new Set(C.map(e=>e.connectionName)),k=new Set(v.map(e=>e.name)),A=[];for(let e of[...t.resolvedExtensions].sort((e,t)=>e.namespace.localeCompare(t.namespace))){let r=await compileExtensionContributions({mount:e,context:n,consumerAgentRoot:t.agentRoot,externalDependencies:l});for(let e of r.tools)E.has(e.name)||(E.add(e.name),f.push(e));for(let e of r.dynamicTools)D.has(e.slug)||(D.add(e.slug),p.push(e));for(let e of r.connections)O.has(e.connectionName)||(O.add(e.connectionName),C.push(e));for(let e of r.skills)k.has(e.name)||(k.add(e.name),v.push(e));w.push(...r.hooks),y.push(...r.dynamicSkills),S.push(...r.dynamicInstructions),A.push(...r.instructionFragments)}let j=[...x.map(e=>e.markdown),...A],M=j.length===0?void 0:x.length===1&&A.length===0?x[0]:{name:`instructions`,logicalPath:`instructions`,markdown:j.join(`
2
2
 
3
- `),sourceId:b[0].sourceId,sourceKind:`module`};return createCompiledAgentNodeManifest({agentRoot:t.agentRoot,appRoot:t.appRoot,channels:h,config:l,connections:await Promise.all(t.connections.map(e=>compileConnectionDefinition(t.agentRoot,e,{externalDependencies:c}))),diagnosticsSummary:t.diagnosticsSummary,disabledFrameworkTools:p,workflowEnabled:m,dynamicSkills:v,dynamicTools:f,hooks:t.hooks.map(e=>compileHookEntry(e)),sandbox:t.sandbox===null?null:await compileSandboxDefinition(t.agentRoot,t.sandbox,{externalDependencies:c}),sandboxWorkspaces:t.sandboxWorkspaces.map(e=>({logicalPath:e.logicalPath,rootEntries:[...e.rootEntries],sourceId:e.sourceId,sourcePath:e.sourcePath})),schedules:await Promise.all(t.schedules.map(e=>compileScheduleDefinition(t.agentRoot,e,{externalDependencies:c}))),dynamicInstructions:x,skills:_,instructions:S,tools:d})}function mergeExternalDependencies(...e){let t=new Set;for(let n of e)for(let e of n??[])t.add(e);return[...t]}export{compileAgentManifest};
3
+ `),sourceId:x[0]?.sourceId??`instructions`,sourceKind:`module`};return createCompiledAgentNodeManifest({agentRoot:t.agentRoot,appRoot:t.appRoot,channels:g,config:u,connections:C,diagnosticsSummary:t.diagnosticsSummary,disabledFrameworkTools:m,workflowEnabled:h,dynamicSkills:y,dynamicTools:p,hooks:w,sandbox:t.sandbox===null?null:await compileSandboxDefinition(t.agentRoot,t.sandbox,{externalDependencies:l}),sandboxWorkspaces:t.sandboxWorkspaces.map(e=>({logicalPath:e.logicalPath,rootEntries:[...e.rootEntries],sourceId:e.sourceId,sourcePath:e.sourcePath})),schedules:T,dynamicInstructions:S,skills:v,instructions:M,tools:f})}function mergeExternalDependencies(...e){let t=new Set;for(let n of e)for(let e of n??[])t.add(e);return[...t]}export{compileAgentManifest};
@@ -1 +1 @@
1
- import{join,posix}from"node:path";import{cp,mkdir,readFile,readdir,rm}from"node:fs/promises";import{createHash}from"node:crypto";import{normalizeLogicalPath}from"#discover/filesystem.js";import{ROOT_COMPILED_AGENT_NODE_ID,deriveResourceRootEntries}from"#compiler/manifest.js";import{normalizeSkillPackage,writeSkillPackageDirectory}from"#shared/skill-package.js";const RESOURCES_DIRECTORY=`workspace-resources`;async function materializeWorkspaceResources(t){let n=join(t.compileDirectoryPath,RESOURCES_DIRECTORY);await rm(n,{force:!0,recursive:!0});let r=await materializeNode({nodeId:ROOT_COMPILED_AGENT_NODE_ID,resourcesRoot:n,manifest:t.manifest}),i=await Promise.all(t.manifest.subagents.map(async e=>({...e,agent:await materializeNode({nodeId:e.nodeId,resourcesRoot:n,manifest:e.agent})})));return{...r,kind:t.manifest.kind,subagentEdges:t.manifest.subagentEdges,subagents:i,version:t.manifest.version}}function createResourceRoot(t,n,r){return{contentHash:r,logicalPath:normalizeLogicalPath(join(RESOURCES_DIRECTORY,n)),rootEntries:deriveResourceRootEntries({sandboxWorkspaces:t.sandboxWorkspaces,skills:t.skills})}}async function materializeNode(t){let n=join(t.resourcesRoot,t.nodeId);await mkdir(n,{recursive:!0});let i=join(n,`workspace`);for(let e of t.manifest.sandboxWorkspaces)await copyDirectoryContents({sourcePath:e.sourcePath,targetPath:i});for(let e of t.manifest.skills)await materializeSkill({nodeRoot:n,skill:e});let a=await hashWorkspaceResourceRoot(n);return{...t.manifest,skills:t.manifest.skills.map(stripSkillPackageFiles),workspaceResourceRoot:createResourceRoot(t.manifest,t.nodeId,a)}}async function materializeSkill(t){let r=join(t.nodeRoot,`skills`,t.skill.name);if(t.skill.sourceKind===`skill-package`){await cp(t.skill.rootPath,r,{recursive:!0});return}await writeSkillPackageDirectory({rootPath:t.nodeRoot,skill:normalizeSkillPackage(t.skill)})}function stripSkillPackageFiles(e){let{files:t,...n}=e;return n}async function copyDirectoryContents(t){let i=await readdir(t.sourcePath,{withFileTypes:!0});await mkdir(t.targetPath,{recursive:!0});for(let r of i)!r.isDirectory()&&!r.isFile()||await cp(join(t.sourcePath,r.name),join(t.targetPath,r.name),{recursive:!0})}async function hashWorkspaceResourceRoot(e){let t=await listWorkspaceResourceFiles({logicalDirectoryPath:`.`,sourceDirectoryPath:e});if(t.sort((e,t)=>e.logicalPath.localeCompare(t.logicalPath)),t.length===0)return;let n=createHash(`sha256`);n.update(`eve-workspace-resource-root-v1\0`);for(let e of t){let t=await readFile(e.sourcePath);n.update(e.logicalPath),n.update(`\0`),n.update(String(t.byteLength)),n.update(`\0`),n.update(t),n.update(`\0`)}return n.digest(`hex`)}async function listWorkspaceResourceFiles(n){let r=[],i=await readdir(n.sourceDirectoryPath,{withFileTypes:!0});for(let a of i){if(!a.isDirectory()&&!a.isFile())continue;let i=join(n.sourceDirectoryPath,a.name),o=posix.join(n.logicalDirectoryPath,a.name);if(a.isDirectory()){r.push(...await listWorkspaceResourceFiles({logicalDirectoryPath:o,sourceDirectoryPath:i}));continue}r.push({logicalPath:o,sourcePath:i})}return r}export{materializeWorkspaceResources};
1
+ import{join,posix}from"node:path";import{cp,mkdir,readFile,readdir,rm}from"node:fs/promises";import{createHash}from"node:crypto";import{normalizeLogicalPath}from"#discover/filesystem.js";import{ROOT_COMPILED_AGENT_NODE_ID,deriveResourceRootEntries}from"#compiler/manifest.js";import{normalizeSkillPackage,writeSkillPackageDirectory}from"#shared/skill-package.js";const RESOURCES_DIRECTORY=`workspace-resources`;async function materializeWorkspaceResources(t){let n=join(t.compileDirectoryPath,RESOURCES_DIRECTORY);await rm(n,{force:!0,recursive:!0});let r=await materializeNode({nodeId:ROOT_COMPILED_AGENT_NODE_ID,resourcesRoot:n,manifest:t.manifest}),i=await Promise.all(t.manifest.subagents.map(async e=>({...e,agent:await materializeNode({nodeId:e.nodeId,resourcesRoot:n,manifest:e.agent})})));return{...r,kind:t.manifest.kind,extensionMounts:t.manifest.extensionMounts,subagentEdges:t.manifest.subagentEdges,subagents:i,version:t.manifest.version}}function createResourceRoot(t,n,r){return{contentHash:r,logicalPath:normalizeLogicalPath(join(RESOURCES_DIRECTORY,n)),rootEntries:deriveResourceRootEntries({sandboxWorkspaces:t.sandboxWorkspaces,skills:t.skills})}}async function materializeNode(t){let n=join(t.resourcesRoot,t.nodeId);await mkdir(n,{recursive:!0});let i=join(n,`workspace`);for(let e of t.manifest.sandboxWorkspaces)await copyDirectoryContents({sourcePath:e.sourcePath,targetPath:i});for(let e of t.manifest.skills)await materializeSkill({nodeRoot:n,skill:e});let a=await hashWorkspaceResourceRoot(n);return{...t.manifest,skills:t.manifest.skills.map(stripSkillPackageFiles),workspaceResourceRoot:createResourceRoot(t.manifest,t.nodeId,a)}}async function materializeSkill(t){let r=join(t.nodeRoot,`skills`,t.skill.name);if(t.skill.sourceKind===`skill-package`){await cp(t.skill.rootPath,r,{recursive:!0});return}await writeSkillPackageDirectory({rootPath:t.nodeRoot,skill:normalizeSkillPackage(t.skill)})}function stripSkillPackageFiles(e){let{files:t,...n}=e;return n}async function copyDirectoryContents(t){let i=await readdir(t.sourcePath,{withFileTypes:!0});await mkdir(t.targetPath,{recursive:!0});for(let r of i)!r.isDirectory()&&!r.isFile()||await cp(join(t.sourcePath,r.name),join(t.targetPath,r.name),{recursive:!0})}async function hashWorkspaceResourceRoot(e){let t=await listWorkspaceResourceFiles({logicalDirectoryPath:`.`,sourceDirectoryPath:e});if(t.sort((e,t)=>e.logicalPath.localeCompare(t.logicalPath)),t.length===0)return;let n=createHash(`sha256`);n.update(`eve-workspace-resource-root-v1\0`);for(let e of t){let t=await readFile(e.sourcePath);n.update(e.logicalPath),n.update(`\0`),n.update(String(t.byteLength)),n.update(`\0`),n.update(t),n.update(`\0`)}return n.digest(`hex`)}async function listWorkspaceResourceFiles(n){let r=[],i=await readdir(n.sourceDirectoryPath,{withFileTypes:!0});for(let a of i){if(!a.isDirectory()&&!a.isFile())continue;let i=join(n.sourceDirectoryPath,a.name),o=posix.join(n.logicalDirectoryPath,a.name);if(a.isDirectory()){r.push(...await listWorkspaceResourceFiles({logicalDirectoryPath:o,sourceDirectoryPath:i}));continue}r.push({logicalPath:o,sourcePath:i})}return r}export{materializeWorkspaceResources};
@@ -1 +1 @@
1
- import{createLogger}from"#internal/logging.js";import{DynamicSkillManifestKey,SandboxKey}from"#context/keys.js";import{toErrorMessage}from"#shared/errors.js";import{ALLOWED_DYNAMIC_SKILL_EVENTS,isBrandedSkillEntry}from"#shared/dynamic-tool-definition.js";import{normalizeSkillPackage,removeSkillPackageFromSandbox,writeSkillPackageToSandbox}from"#shared/skill-package.js";import{ContextKey}from"#context/key.js";import{buildResolveContext}from"#context/dynamic-resolve-context.js";import{formatAvailableSkillsSection}from"#execution/skills/instructions.js";import{resolveSandboxSkillRoot}from"#shared/skill-paths.js";const log=createLogger(`dynamic-skills`);function qualifyDynamicSkillNames(e,t,n){let r=Object.keys(n),i=[];if(r.length===0)return i;if(t)return i.push({name:e,entryKey:r[0],entry:n[r[0]]}),i;for(let e of r)i.push({name:e,entryKey:e,entry:n[e]});return i}async function formatDynamicSkillAnnouncement(e){let t=await e.ctx.require(SandboxKey).get(),r=t===null?void 0:await resolveSandboxSkillRoot({sandbox:t});return formatAvailableSkillsSection(Object.values(e.manifest).flat(),{skillRoot:r})??``}const PendingSkillAnnouncementKey=new ContextKey(`eve.pendingSkillAnnouncement`);async function dispatchDynamicSkillEvent(e){let{ctx:a,resolvers:o,event:s,messages:c}=e;if(a.get(PendingSkillAnnouncementKey)===void 0){let e=a.get(DynamicSkillManifestKey);e!==void 0&&Object.keys(e).length>0&&a.setVirtualContext(PendingSkillAnnouncementKey,await formatDynamicSkillAnnouncement({ctx:a,manifest:e}))}if(!ALLOWED_DYNAMIC_SKILL_EVENTS.has(s.type))return;let l=o.filter(e=>e.eventNames.includes(s.type));if(l.length===0)return;let u=buildResolveContext(a,c),d=a.get(DynamicSkillManifestKey)??{},f=[],p=await Promise.allSettled(l.map(async e=>{let t=e.events[s.type];if(t===void 0)return null;let n=await t(s,u);if(n==null)return{resolver:e,named:[]};let r,i;return isBrandedSkillEntry(n)?(r={_single:n},i=!0):(r=n,i=!1),{resolver:e,named:qualifyDynamicSkillNames(e.slug,i,r)}}));for(let e of p){if(e.status===`rejected`){log.error(`Dynamic skill resolver (${s.type}) threw — skipping.`,{error:toErrorMessage(e.reason)});continue}e.value!==null&&f.push({resolver:e.value.resolver,skills:e.value.named.map(({name:e,entry:t})=>normalizeSkillPackage({...t,name:e}))})}if(f.length===0)return;let m={...d};for(let{resolver:e,skills:t}of f)t.length===0?delete m[e.slug]:m[e.slug]=t.map(e=>({description:e.description,name:e.name}));let h=new Map;for(let[e,t]of Object.entries(m))for(let{name:n}of t){let t=h.get(n);if(t!==void 0)throw Error(`Dynamic skill "${n}" from resolver "${e}" collides with dynamic resolver "${t}". Namespace the map key manually, e.g. "${e}__${n}".`);h.set(n,e)}let g=await a.require(SandboxKey).get();if(g!==null){let e=new Set(Object.values(m).flat().map(e=>e.name)),t=new Set;for(let{resolver:n}of f)for(let r of d[n.slug]??[])e.has(r.name)||t.add(r.name);for(let e of t)await removeSkillPackageFromSandbox({name:e,sandbox:g});for(let{skills:e}of f)for(let t of e)await writeSkillPackageToSandbox({sandbox:g,skill:t})}a.set(DynamicSkillManifestKey,m),a.setVirtualContext(PendingSkillAnnouncementKey,await formatDynamicSkillAnnouncement({ctx:a,manifest:m}))}export{PendingSkillAnnouncementKey,dispatchDynamicSkillEvent};
1
+ import{createLogger}from"#internal/logging.js";import{DynamicSkillManifestKey,SandboxKey}from"#context/keys.js";import{toErrorMessage}from"#shared/errors.js";import{ALLOWED_DYNAMIC_SKILL_EVENTS,isBrandedSkillEntry}from"#shared/dynamic-tool-definition.js";import{normalizeSkillPackage,removeSkillPackageFromSandbox,writeSkillPackageToSandbox}from"#shared/skill-package.js";import{ContextKey}from"#context/key.js";import{buildResolveContext}from"#context/dynamic-resolve-context.js";import{formatAvailableSkillsSection}from"#execution/skills/instructions.js";import{resolveSandboxSkillRoot}from"#shared/skill-paths.js";const log=createLogger(`dynamic-skills`);function qualifyDynamicSkillNames(e,t,n){let r=Object.keys(n),i=[];if(r.length===0)return i;if(t)return i.push({name:e.slug,entryKey:r[0],entry:n[r[0]]}),i;let a=e.extensionNamespace===void 0?``:`${e.extensionNamespace}__`;for(let e of r)i.push({name:`${a}${e}`,entryKey:e,entry:n[e]});return i}async function formatDynamicSkillAnnouncement(e){let t=await e.ctx.require(SandboxKey).get(),r=t===null?void 0:await resolveSandboxSkillRoot({sandbox:t});return formatAvailableSkillsSection(Object.values(e.manifest).flat(),{skillRoot:r})??``}const PendingSkillAnnouncementKey=new ContextKey(`eve.pendingSkillAnnouncement`);async function dispatchDynamicSkillEvent(e){let{ctx:o,resolvers:s,event:c,messages:l}=e;if(o.get(PendingSkillAnnouncementKey)===void 0){let e=o.get(DynamicSkillManifestKey);e!==void 0&&Object.keys(e).length>0&&o.setVirtualContext(PendingSkillAnnouncementKey,await formatDynamicSkillAnnouncement({ctx:o,manifest:e}))}if(!ALLOWED_DYNAMIC_SKILL_EVENTS.has(c.type))return;let u=s.filter(e=>e.eventNames.includes(c.type));if(u.length===0)return;let d=buildResolveContext(o,l),f=o.get(DynamicSkillManifestKey)??{},p=[],m=await Promise.allSettled(u.map(async e=>{let t=e.events[c.type];if(t===void 0)return null;let n=await t(c,d);if(n==null)return{resolver:e,named:[]};let r,i;return isBrandedSkillEntry(n)?(r={_single:n},i=!0):(r=n,i=!1),{resolver:e,named:qualifyDynamicSkillNames(e,i,r)}}));for(let e of m){if(e.status===`rejected`){log.error(`Dynamic skill resolver (${c.type}) threw — skipping.`,{error:toErrorMessage(e.reason)});continue}e.value!==null&&p.push({resolver:e.value.resolver,skills:e.value.named.map(({name:e,entry:t})=>normalizeSkillPackage({...t,name:e}))})}if(p.length===0)return;let h={...f};for(let{resolver:e,skills:t}of p)t.length===0?delete h[e.slug]:h[e.slug]=t.map(e=>({description:e.description,name:e.name}));let g=new Map;for(let[e,t]of Object.entries(h))for(let{name:n}of t){let t=g.get(n);if(t!==void 0)throw Error(`Dynamic skill "${n}" from resolver "${e}" collides with dynamic resolver "${t}". Namespace the map key manually, e.g. "${e}__${n}".`);g.set(n,e)}let _=await o.require(SandboxKey).get();if(_!==null){let e=new Set(Object.values(h).flat().map(e=>e.name)),t=new Set;for(let{resolver:n}of p)for(let r of f[n.slug]??[])e.has(r.name)||t.add(r.name);for(let e of t)await removeSkillPackageFromSandbox({name:e,sandbox:_});for(let{skills:e}of p)for(let t of e)await writeSkillPackageToSandbox({sandbox:_,skill:t})}o.set(DynamicSkillManifestKey,h),o.setVirtualContext(PendingSkillAnnouncementKey,await formatDynamicSkillAnnouncement({ctx:o,manifest:h}))}export{PendingSkillAnnouncementKey,dispatchDynamicSkillEvent};
@@ -1 +1 @@
1
- import{createLogger}from"#internal/logging.js";import{LiveStepToolsKey,SessionDynamicToolMetadataKey,TurnDynamicToolMetadataKey}from"#context/keys.js";import{toErrorMessage}from"#shared/errors.js";import{ALLOWED_DYNAMIC_TOOL_EVENTS,isBrandedToolEntry}from"#shared/dynamic-tool-definition.js";import{jsonSchema,zodSchema}from"ai";import{buildBaseToolContext}from"#context/build-base-tool-context.js";import{buildResolveContext}from"#context/dynamic-resolve-context.js";import{normalizeJsonSchemaDefinition}from"#internal/json-schema.js";const log=createLogger(`dynamic-tools`);function toHarnessToolDefinition(e,t){return{description:t.description,execute:(e,n)=>t.execute(e,buildBaseToolContext(n)),inputSchema:convertInputSchema(t.inputSchema),name:e,approval:t.approval,outputSchema:convertOptionalOutputSchema(t.outputSchema),...t.toModelOutput===void 0?{}:{toModelOutput:t.toModelOutput}}}function convertInputSchema(e){return typeof e==`object`&&e&&`~standard`in e?zodSchema(e):jsonSchema(e)}function convertOptionalOutputSchema(e){if(e!==void 0)return typeof e==`object`&&e&&`~standard`in e?zodSchema(e):jsonSchema(e)}function qualifyDynamicToolNames(e,t,n){let r=Object.keys(n),i=[];if(r.length===0)return i;if(t)return i.push({name:e,entryKey:r[0],entry:n[r[0]]}),i;for(let e of r)i.push({name:e,entryKey:e,entry:n[e]});return i}function replayDynamicSessionTools(e,t){let n=[];for(let t of e){if(!t.executeStepFnName||!t.closureVars){log.warn(`Dynamic tool "${t.name}" has no registered step function — skipping on this step. The bundler transform may not have processed this tool file.`);continue}let e=lookupStepFunction(t.executeStepFnName);if(!e){log.warn(`Dynamic tool "${t.name}" references step function "${t.executeStepFnName}" which is not registered — skipping on this step.`);continue}n.push({description:t.description,execute:(n,r)=>e(t.closureVars,n,buildBaseToolContext(r)),inputSchema:jsonSchema(t.inputSchema),name:t.name,outputSchema:t.outputSchema===void 0?void 0:jsonSchema(t.outputSchema)})}return n}function getStepRegistry(){let e=Symbol.for(`@workflow/core//registeredSteps`),t=globalThis,n=t[e];return n===void 0&&(n=new Map,t[e]=n),n}function lookupStepFunction(e){try{return getStepRegistry().get(e)||null}catch{return null}}function registerStepFunction(e,t){getStepRegistry().set(e,t)}function safeSerialize(e){try{return JSON.parse(JSON.stringify(e))}catch{return{}}}function durableKeyForEvent(e){switch(e){case`session.started`:return SessionDynamicToolMetadataKey;case`turn.started`:return TurnDynamicToolMetadataKey;default:return}}async function resolveToolsFromEvent(e,t,n,r){let a=await Promise.allSettled(t.map(async t=>{let i=t.events[n.type];if(i===void 0)return null;let a=await i(n,buildResolveContext(e,r));if(a==null)return null;let s,c;return isBrandedToolEntry(a)?(s={_single:a},c=!0):(s=a,c=!1),{resolver:t,entries:s,isSingle:c}})),s=[],c=[],l=new Map;for(let e of a){if(e.status===`rejected`){log.error(`Dynamic tool resolver (${n.type}) threw — skipping.`,{error:toErrorMessage(e.reason)});continue}if(e.value===null)continue;let{resolver:t,entries:r,isSingle:a}=e.value,o=qualifyDynamicToolNames(t.slug,a,r);for(let{name:e,entryKey:r,entry:i}of o){let a=l.get(e);if(a!==void 0&&a!==t.slug)throw Error(`Dynamic tool "${e}" from resolver "${t.slug}" collides with dynamic resolver "${a}". Namespace the map key manually, e.g. "${t.slug}__${e}".`);if(l.set(e,t.slug),c.push(toHarnessToolDefinition(e,i)),n.type===`step.started`)continue;let o=`__executeStepFn`in i?i.__executeStepFn:void 0,u=`__closureVars`in i?i.__closureVars:void 0,f=o?.stepId,p=u===void 0?void 0:safeSerialize(u);if(f===void 0){let e=`eve:framework-dynamic:${t.slug}:${r}`,n=i.execute.bind(i);registerStepFunction(e,(e,t,r)=>n(t,r)),f=e,p={}}let m;if(i.approval!==void 0){m=`eve:dynamic-tool-approval:${t.slug}:${r}`;let e=i.approval.bind(i);registerStepFunction(m,(t,n)=>e(n))}s.push({name:e,description:i.description,inputSchema:normalizeJsonSchemaDefinition(i.inputSchema),outputSchema:i.outputSchema===void 0?void 0:normalizeJsonSchemaDefinition(i.outputSchema,`output`),resolverSlug:t.slug,entryKey:r,executeStepFnName:f,approvalStepFnName:m,closureVars:p})}}return{metadata:s,liveTools:c}}async function dispatchDynamicToolEvent(e){let{ctx:n,resolvers:r,event:i,messages:o}=e;if(!ALLOWED_DYNAMIC_TOOL_EVENTS.has(i.type))return;let s=r.filter(e=>e.eventNames.includes(i.type));if(s.length===0)return;let{metadata:c,liveTools:l}=await resolveToolsFromEvent(n,s,i,o);if(i.type===`step.started`){n.setVirtualContext(LiveStepToolsKey,l);return}let u=durableKeyForEvent(i.type);if(u===void 0)return;let d=new Set(s.map(e=>e.slug)),f=(n.get(u)??[]).filter(e=>!d.has(e.resolverSlug));n.set(u,[...f,...c])}export{dispatchDynamicToolEvent,replayDynamicSessionTools};
1
+ import{createLogger}from"#internal/logging.js";import{LiveStepToolsKey,SessionDynamicToolMetadataKey,TurnDynamicToolMetadataKey}from"#context/keys.js";import{toErrorMessage}from"#shared/errors.js";import{ALLOWED_DYNAMIC_TOOL_EVENTS,isBrandedToolEntry}from"#shared/dynamic-tool-definition.js";import{jsonSchema,zodSchema}from"ai";import{buildBaseToolContext}from"#context/build-base-tool-context.js";import{buildResolveContext}from"#context/dynamic-resolve-context.js";import{normalizeJsonSchemaDefinition}from"#internal/json-schema.js";const log=createLogger(`dynamic-tools`);function toHarnessToolDefinition(e,t){return{description:t.description,execute:(e,n)=>t.execute(e,buildBaseToolContext(n)),inputSchema:convertInputSchema(t.inputSchema),name:e,approval:t.approval,outputSchema:convertOptionalOutputSchema(t.outputSchema),...t.toModelOutput===void 0?{}:{toModelOutput:t.toModelOutput}}}function convertInputSchema(e){return typeof e==`object`&&e&&`~standard`in e?zodSchema(e):jsonSchema(e)}function convertOptionalOutputSchema(e){if(e!==void 0)return typeof e==`object`&&e&&`~standard`in e?zodSchema(e):jsonSchema(e)}function qualifyDynamicToolNames(e,t,n){let r=Object.keys(n),i=[];if(r.length===0)return i;if(t)return i.push({name:e.slug,entryKey:r[0],entry:n[r[0]]}),i;let a=e.extensionNamespace===void 0?``:`${e.extensionNamespace}__`;for(let e of r)i.push({name:`${a}${e}`,entryKey:e,entry:n[e]});return i}function replayDynamicSessionTools(e,t){let n=[];for(let t of e){if(!t.executeStepFnName||!t.closureVars){log.warn(`Dynamic tool "${t.name}" has no registered step function — skipping on this step. The bundler transform may not have processed this tool file.`);continue}let e=lookupStepFunction(t.executeStepFnName);if(!e){log.warn(`Dynamic tool "${t.name}" references step function "${t.executeStepFnName}" which is not registered — skipping on this step.`);continue}n.push({description:t.description,execute:(n,r)=>e(t.closureVars,n,buildBaseToolContext(r)),inputSchema:jsonSchema(t.inputSchema),name:t.name,outputSchema:t.outputSchema===void 0?void 0:jsonSchema(t.outputSchema)})}return n}function getStepRegistry(){let e=Symbol.for(`@workflow/core//registeredSteps`),t=globalThis,n=t[e];return n===void 0&&(n=new Map,t[e]=n),n}function lookupStepFunction(e){try{return getStepRegistry().get(e)||null}catch{return null}}function registerStepFunction(e,t){getStepRegistry().set(e,t)}function safeSerialize(e){try{return JSON.parse(JSON.stringify(e))}catch{return{}}}function durableKeyForEvent(e){switch(e){case`session.started`:return SessionDynamicToolMetadataKey;case`turn.started`:return TurnDynamicToolMetadataKey;default:return}}async function resolveToolsFromEvent(e,t,n,r){let a=await Promise.allSettled(t.map(async t=>{let i=t.events[n.type];if(i===void 0)return null;let a=await i(n,buildResolveContext(e,r));if(a==null)return null;let s,c;return isBrandedToolEntry(a)?(s={_single:a},c=!0):(s=a,c=!1),{resolver:t,entries:s,isSingle:c}})),s=[],c=[],l=new Map;for(let e of a){if(e.status===`rejected`){log.error(`Dynamic tool resolver (${n.type}) threw — skipping.`,{error:toErrorMessage(e.reason)});continue}if(e.value===null)continue;let{resolver:t,entries:r,isSingle:a}=e.value,o=qualifyDynamicToolNames(t,a,r);for(let{name:e,entryKey:r,entry:i}of o){let a=l.get(e);if(a!==void 0&&a!==t.slug)throw Error(`Dynamic tool "${e}" from resolver "${t.slug}" collides with dynamic resolver "${a}". Namespace the map key manually, e.g. "${t.slug}__${e}".`);if(l.set(e,t.slug),c.push(toHarnessToolDefinition(e,i)),n.type===`step.started`)continue;let o=`__executeStepFn`in i?i.__executeStepFn:void 0,u=`__closureVars`in i?i.__closureVars:void 0,f=o?.stepId,p=u===void 0?void 0:safeSerialize(u);if(f===void 0){let e=`eve:framework-dynamic:${t.slug}:${r}`,n=i.execute.bind(i);registerStepFunction(e,(e,t,r)=>n(t,r)),f=e,p={}}let m;if(i.approval!==void 0){m=`eve:dynamic-tool-approval:${t.slug}:${r}`;let e=i.approval.bind(i);registerStepFunction(m,(t,n)=>e(n))}s.push({name:e,description:i.description,inputSchema:normalizeJsonSchemaDefinition(i.inputSchema),outputSchema:i.outputSchema===void 0?void 0:normalizeJsonSchemaDefinition(i.outputSchema,`output`),resolverSlug:t.slug,entryKey:r,executeStepFnName:f,approvalStepFnName:m,closureVars:p})}}return{metadata:s,liveTools:c}}async function dispatchDynamicToolEvent(e){let{ctx:n,resolvers:r,event:i,messages:o}=e;if(!ALLOWED_DYNAMIC_TOOL_EVENTS.has(i.type))return;let s=r.filter(e=>e.eventNames.includes(i.type));if(s.length===0)return;let{metadata:c,liveTools:l}=await resolveToolsFromEvent(n,s,i,o);if(i.type===`step.started`){n.setVirtualContext(LiveStepToolsKey,l);return}let u=durableKeyForEvent(i.type);if(u===void 0)return;let d=new Set(s.map(e=>e.slug)),f=(n.get(u)??[]).filter(e=>!d.has(e.resolverSlug));n.set(u,[...f,...c])}export{dispatchDynamicToolEvent,replayDynamicSessionTools};
@@ -1,4 +1,4 @@
1
- import type { DiscoverDiagnostic } from "#discover/diagnostics.js";
1
+ import { type DiscoverDiagnostic } from "#discover/diagnostics.js";
2
2
  import { type AgentSourceManifest } from "#discover/manifest.js";
3
3
  import { type ProjectSource } from "#discover/project-source.js";
4
4
  /**
@@ -14,6 +14,19 @@ interface DiscoverAgentInput {
14
14
  * memory-backed source.
15
15
  */
16
16
  source?: ProjectSource;
17
+ /**
18
+ * Discovery role. `"agent"` (default) resolves mounted extensions and
19
+ * accepts agent-level config. `"extension"` discovers an extension's own
20
+ * source tree: it rejects `agent.ts`/`sandbox` (consumer-owned) and does
21
+ * not resolve further extensions (transitive mounting is a non-goal).
22
+ */
23
+ role?: "agent" | "extension";
24
+ /**
25
+ * The app's eve version, checked against each mounted extension's
26
+ * `peerDependencies.eve`. Defaults to the running eve's version; injectable
27
+ * for tests.
28
+ */
29
+ eveVersion?: string;
17
30
  }
18
31
  /**
19
32
  * Result of discovering one authored agent source graph.
@@ -1 +1 @@
1
- import{join,resolve}from"node:path";import{classifyAgentRootEntry}from"#discover/filesystem.js";import{createDiskProjectSource}from"#discover/project-source.js";import{createAgentSourceManifest}from"#discover/manifest.js";import{DISCOVER_CHANNELS_DIRECTORY_INVALID,DISCOVER_HOOKS_DIRECTORY_INVALID,DISCOVER_TOOLS_DIRECTORY_INVALID,createChannelNameDiagnostic,createHookNameDiagnostic,createToolNameDiagnostic,createUnsupportedRootDirectoryDiagnostics,discoverFlatModuleSource,discoverInstructionsSource,discoverNamedSourceDirectory,readSortedDirectoryEntries}from"#discover/grammar.js";import{discoverConnectionSources}from"#discover/connections.js";import{discoverSubagents}from"#discover/discover-subagent.js";import{discoverLibSources}from"#discover/lib.js";import{discoverSandboxSource}from"#discover/sandbox.js";import{discoverScheduleSources}from"#discover/schedules.js";import{discoverSkills}from"#discover/skills.js";import{stripNpmPackageScope}from"#shared/package-name.js";async function discoverAgent(a){let o=a.source??createDiskProjectSource(),s=resolve(a.appRoot),c=resolve(a.agentRoot),l=[],u=await tryReadPackageJsonName(o,s),d=await readSortedDirectoryEntries(o,c);l.push(...createUnsupportedRootDirectoryDiagnostics({classifyEntry:classifyAgentRootEntry,createUnsupportedDirectoryMessage(e){return`Ignoring unsupported directory "${e}/" in the agent root.`},rootEntries:d,rootPath:c}));let f=await discoverInstructionsSource({rootEntries:d,rootPath:c,source:o});l.push(...f.diagnostics);let p=discoverFlatModuleSource({rootEntries:d,rootPath:c,slotName:`agent`});l.push(...p.diagnostics);let m=await discoverNamedSourceDirectory({directoryName:`channels`,invalidDirectoryCode:DISCOVER_CHANNELS_DIRECTORY_INVALID,invalidDirectoryMessage:`Expected "${join(c,`channels`)}" to be a directory of authored channels.`,recursive:!0,rootEntries:d,rootPath:c,source:o,validateSegment:createChannelNameDiagnostic});l.push(...m.diagnostics);let h=await discoverLibSources({agentRoot:c,rootEntries:d,source:o});l.push(...h.diagnostics);let g=await discoverScheduleSources({agentRoot:c,rootEntries:d,source:o});l.push(...g.diagnostics);let _=await discoverConnectionSources({rootEntries:d,rootPath:c,source:o});l.push(..._.diagnostics);let v=await discoverSandboxSource({rootEntries:d,rootPath:c,source:o});l.push(...v.diagnostics);let y=await discoverNamedSourceDirectory({directoryName:`tools`,invalidDirectoryCode:DISCOVER_TOOLS_DIRECTORY_INVALID,invalidDirectoryMessage:`Expected "${join(c,`tools`)}" to be a directory of authored tools.`,recursive:!0,rootEntries:d,rootPath:c,source:o,validateSegment:createToolNameDiagnostic});l.push(...y.diagnostics);let b=await discoverNamedSourceDirectory({directoryName:`hooks`,invalidDirectoryCode:DISCOVER_HOOKS_DIRECTORY_INVALID,invalidDirectoryMessage:`Expected "${join(c,`hooks`)}" to be a directory of authored hooks.`,recursive:!0,rootEntries:d,rootPath:c,source:o,validateSegment:createHookNameDiagnostic});l.push(...b.diagnostics);let x=await discoverSkills({agentRoot:c,source:o});l.push(...x.diagnostics);let S=await discoverSubagents({agentRoot:c,appRoot:s,source:o});l.push(...S.diagnostics);let C={agentRoot:c,appRoot:s,channels:m.sources,connections:_.connections,packageName:u,diagnostics:l,hooks:b.sources,lib:h.lib,instructions:f.instructions,sandbox:v.sandbox,sandboxWorkspaces:v.sandboxWorkspace===null?[]:[v.sandboxWorkspace],schedules:g.schedules,skills:x.skills,tools:y.sources,subagents:S.subagents};return p.module!==void 0&&(C.configModule=p.module),{diagnostics:l,manifest:createAgentSourceManifest(C)}}async function tryReadPackageJsonName(t,n){try{let r=join(n,`package.json`),i=JSON.parse(await t.readTextFile(r)).name;return typeof i!=`string`||i.length===0?void 0:stripNpmPackageScope(i)}catch{return}}export{discoverAgent};
1
+ import{resolveInstalledPackageInfo}from"#internal/application/package.js";import{join,resolve}from"node:path";import{createDiscoverErrorDiagnostic}from"#discover/diagnostics.js";import{SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS,classifyAgentRootEntry,normalizeLogicalPath}from"#discover/filesystem.js";import{createDiskProjectSource}from"#discover/project-source.js";import{DISCOVER_EXTENSION_AGENT_CONFIG_UNSUPPORTED,DISCOVER_EXTENSION_MOUNT_AMBIGUOUS,DISCOVER_EXTENSION_MOUNT_MISSING_DECLARATION,DISCOVER_EXTENSION_NESTED_MOUNT_UNSUPPORTED,DISCOVER_EXTENSION_OVERRIDE_OUTSIDE_MOUNT,DISCOVER_EXTENSION_SANDBOX_UNSUPPORTED,DISCOVER_EXTENSION_SCHEDULE_UNSUPPORTED,locateExtensionMount,mountNamespace}from"#discover/extensions.js";import{createAgentSourceManifest,createModuleSourceRef}from"#discover/manifest.js";import{DISCOVER_CHANNELS_DIRECTORY_INVALID,DISCOVER_EXTENSIONS_DIRECTORY_INVALID,DISCOVER_HOOKS_DIRECTORY_INVALID,DISCOVER_TOOLS_DIRECTORY_INVALID,createChannelNameDiagnostic,createExtensionNameDiagnostic,createHookNameDiagnostic,createToolNameDiagnostic,createUnsupportedRootDirectoryDiagnostics,discoverFlatModuleSource,discoverInstructionsSource,discoverNamedSourceDirectory,readSortedDirectoryEntries}from"#discover/grammar.js";import{discoverConnectionSources}from"#discover/connections.js";import{discoverSubagents}from"#discover/discover-subagent.js";import{discoverLibSources}from"#discover/lib.js";import{discoverSandboxSource}from"#discover/sandbox.js";import{discoverScheduleSources}from"#discover/schedules.js";import{discoverSkills}from"#discover/skills.js";import{stripNpmPackageScope}from"#shared/package-name.js";async function discoverAgent(i){let o=i.source??createDiskProjectSource(),l=resolve(i.appRoot),u=resolve(i.agentRoot),f=i.role??`agent`,h=i.eveVersion??resolveInstalledPackageInfo().version,g=[],_=await tryReadPackageJsonName(o,l),v=await readSortedDirectoryEntries(o,u);g.push(...createUnsupportedRootDirectoryDiagnostics({classifyEntry:classifyAgentRootEntry,createUnsupportedDirectoryMessage(e){return`Ignoring unsupported directory "${e}/" in the agent root.`},rootEntries:v,rootPath:u}));let y=await discoverInstructionsSource({rootEntries:v,rootPath:u,source:o,required:f!==`extension`});g.push(...y.diagnostics);let b=discoverFlatModuleSource({rootEntries:v,rootPath:u,slotName:`agent`});g.push(...b.diagnostics);let x=await discoverNamedSourceDirectory({directoryName:`channels`,invalidDirectoryCode:DISCOVER_CHANNELS_DIRECTORY_INVALID,invalidDirectoryMessage:`Expected "${join(u,`channels`)}" to be a directory of authored channels.`,recursive:!0,rootEntries:v,rootPath:u,source:o,validateSegment:createChannelNameDiagnostic});g.push(...x.diagnostics);let S=await discoverLibSources({agentRoot:u,rootEntries:v,source:o});g.push(...S.diagnostics);let C=await discoverScheduleSources({agentRoot:u,rootEntries:v,source:o});g.push(...C.diagnostics);let w=await discoverConnectionSources({rootEntries:v,rootPath:u,source:o});g.push(...w.diagnostics);let T=await discoverSandboxSource({rootEntries:v,rootPath:u,source:o});if(g.push(...T.diagnostics),f===`extension`){b.module!==void 0&&g.push(createDiscoverErrorDiagnostic({code:DISCOVER_EXTENSION_AGENT_CONFIG_UNSUPPORTED,message:`An extension may not declare agent config (agent.ts) — model, limits, and sandbox are the consuming agent's to own.`,sourcePath:join(u,b.module.logicalPath)})),T.sandbox!==null&&g.push(createDiscoverErrorDiagnostic({code:DISCOVER_EXTENSION_SANDBOX_UNSUPPORTED,message:`An extension may not declare a sandbox — it is the consuming agent's to own.`,sourcePath:join(u,T.sandbox.logicalPath)}));let[e]=C.schedules;e!==void 0&&g.push(createDiscoverErrorDiagnostic({code:DISCOVER_EXTENSION_SCHEDULE_UNSUPPORTED,message:`An extension may not declare schedules — background scheduling runs on the consuming agent's deployment under its limits, so it is the consuming agent's to own.`,sourcePath:join(u,e.logicalPath)}))}let E=await discoverNamedSourceDirectory({directoryName:`tools`,invalidDirectoryCode:DISCOVER_TOOLS_DIRECTORY_INVALID,invalidDirectoryMessage:`Expected "${join(u,`tools`)}" to be a directory of authored tools.`,recursive:!0,rootEntries:v,rootPath:u,source:o,validateSegment:createToolNameDiagnostic});g.push(...E.diagnostics);let D=await discoverNamedSourceDirectory({directoryName:`hooks`,invalidDirectoryCode:DISCOVER_HOOKS_DIRECTORY_INVALID,invalidDirectoryMessage:`Expected "${join(u,`hooks`)}" to be a directory of authored hooks.`,recursive:!0,rootEntries:v,rootPath:u,source:o,validateSegment:createHookNameDiagnostic});g.push(...D.diagnostics);let O=await discoverNamedSourceDirectory({directoryName:`extensions`,invalidDirectoryCode:DISCOVER_EXTENSIONS_DIRECTORY_INVALID,invalidDirectoryMessage:`Expected "${join(u,`extensions`)}" to be a directory of extension mounts.`,recursive:!1,rootEntries:v,rootPath:u,source:o,validateSegment:createExtensionNameDiagnostic});g.push(...O.diagnostics);let k=await discoverSkills({agentRoot:u,source:o});g.push(...k.diagnostics);let A=await discoverSubagents({agentRoot:u,appRoot:l,source:o});g.push(...A.diagnostics);let j=await collectExtensionMounts({agentRoot:u,fileMounts:O.sources,rootEntries:v,source:o});g.push(...j.diagnostics),g.push(...detectRootNamespaceCollisions({agentRoot:u,namespaces:j.mounts.map(e=>e.namespace),sources:[...E.sources,...w.connections,...k.skills,...C.schedules]}));let M=[];if(f!==`agent`)for(let e of j.mounts)g.push(createDiscoverErrorDiagnostic({code:DISCOVER_EXTENSION_NESTED_MOUNT_UNSUPPORTED,message:`"${e.mountRef.logicalPath}" mounts an extension from inside an extension, which is not supported yet. Extensions cannot mount other extensions; remove the "extensions/" slot.`,sourcePath:join(u,e.mountRef.logicalPath)}));else for(let e of j.mounts){let t=await locateExtensionMount({source:o,agentRoot:u,appRoot:l,mount:e.mountRef,namespace:e.namespace,eveVersion:h});if(g.push(...t.diagnostics),t.location===void 0)continue;let n=await discoverAgent({agentRoot:t.location.sourceRoot,appRoot:t.location.packageRoot,source:o,role:`extension`});g.push(...n.diagnostics);let r;if(e.overridesRoot!==void 0){let t=await discoverAgent({agentRoot:e.overridesRoot,appRoot:l,source:o,role:`extension`});g.push(...t.diagnostics),r=t.manifest}let i={namespace:t.location.namespace,specifier:t.location.specifier,packageName:t.location.packageName,packageRoot:t.location.packageRoot,sourceRoot:t.location.sourceRoot,manifest:n.manifest};r!==void 0&&(i.overrides=r),M.push(i)}let N={agentRoot:u,appRoot:l,channels:x.sources,connections:w.connections,packageName:_,diagnostics:g,extensions:j.mounts.map(e=>e.mountRef),resolvedExtensions:M,hooks:D.sources,lib:S.lib,instructions:y.instructions,sandbox:T.sandbox,sandboxWorkspaces:T.sandboxWorkspace===null?[]:[T.sandboxWorkspace],schedules:C.schedules,skills:k.skills,tools:E.sources,subagents:A.subagents};return b.module!==void 0&&(N.configModule=b.module),{diagnostics:g,manifest:createAgentSourceManifest(N)}}async function collectExtensionMounts(e){let n=[],i=join(e.agentRoot,`extensions`),a=e.fileMounts.map(e=>({namespace:mountNamespace(e.logicalPath),mountRef:e})),s=new Set(a.map(e=>e.namespace)),c=e.rootEntries.find(e=>e.name===`extensions`),d=[],f=new Set;if(c?.isDirectory()===!0){let a=await readSortedDirectoryEntries(e.source,i);for(let c of a){if(!c.isDirectory())continue;let a=c.name,l=join(i,a),p=createExtensionNameDiagnostic(a,l);if(p!==null){n.push(p);continue}let m=discoverFlatModuleSource({rootEntries:await readSortedDirectoryEntries(e.source,l),rootPath:l,slotName:`extension`});if(n.push(...m.diagnostics),m.module===void 0){n.push(createDiscoverErrorDiagnostic({code:DISCOVER_EXTENSION_MOUNT_MISSING_DECLARATION,message:`Extension mount directory "extensions/${a}/" must declare its mount in "extension.ts" (or another supported module extension).`,sourcePath:l}));continue}s.has(a)&&f.add(a),d.push({namespace:a,mountRef:createModuleSourceRef({logicalPath:normalizeLogicalPath(join(`extensions`,a,m.module.logicalPath))}),overridesRoot:l})}}for(let e of f)n.push(createDiscoverErrorDiagnostic({code:DISCOVER_EXTENSION_MOUNT_AMBIGUOUS,message:`Extension namespace "${e}" is claimed by both a file mount ("extensions/${e}.ts") and a directory mount ("extensions/${e}/"). Keep only one.`,sourcePath:i}));return{diagnostics:n,mounts:[...a,...d].filter(e=>!f.has(e.namespace))}}function detectRootNamespaceCollisions(e){if(e.namespaces.length===0)return[];let n=[];for(let i of e.sources){let a=rootContributionName(i.logicalPath),o=e.namespaces.find(e=>a.startsWith(`${e}__`));o!==void 0&&n.push(createDiscoverErrorDiagnostic({code:DISCOVER_EXTENSION_OVERRIDE_OUTSIDE_MOUNT,message:`"${i.logicalPath}" uses the "${o}__" prefix reserved for the mounted extension "${o}". Override an extension's contributions inside its mount directory ("extensions/${o}/…"), not at the agent root.`,sourcePath:join(e.agentRoot,i.logicalPath)}))}return n}function rootContributionName(e){let t=e.slice(e.indexOf(`/`)+1),n=t.split(`/`)[0]??t;for(let e of SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS)if(n.toLowerCase().endsWith(e))return n.slice(0,n.length-e.length);return n}async function tryReadPackageJsonName(e,n){try{let r=join(n,`package.json`),i=JSON.parse(await e.readTextFile(r)).name;return typeof i!=`string`||i.length===0?void 0:stripNpmPackageScope(i)}catch{return}}export{discoverAgent};
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Statically extracts the extension package specifier a mount file resolves to,
3
+ * without importing the module. Discovery reads only the import that binds the
4
+ * value the mount re-exports, so it can locate the package while honoring the
5
+ * "never import authored modules" invariant.
6
+ *
7
+ * Supported mount forms:
8
+ * - `export { default } from "@acme/crm";`
9
+ * - `import { crm } from "@acme/crm"; export default crm({ ... });`
10
+ * - `import crm from "@acme/crm"; export default crm();`
11
+ *
12
+ * Returns the specifier string, or `null` when the file does not match a
13
+ * recognized mount shape.
14
+ */
15
+ export declare function parseExtensionMountSpecifier(source: string): string | null;
@@ -0,0 +1 @@
1
+ function escapeRegExp(e){return e.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`)}function parseExtensionMountSpecifier(e){let t=e.match(/export\s*\{[^}]*\bdefault\b[^}]*\}\s*from\s*['"]([^'"]+)['"]/);if(t!==null)return t[1]??null;let n=e.match(/export\s+default\s+([A-Za-z_$][\w$]*)\s*[(;\n]/)?.[1];if(n===void 0)return null;let r=e.match(RegExp(`import\\s+${escapeRegExp(n)}\\s*(?:,\\s*\\{[^}]*\\})?\\s*from\\s*['"]([^'"]+)['"]`));if(r!==null)return r[1]??null;let i=/import\s*(?:[A-Za-z_$][\w$]*\s*,\s*)?\{([^}]*)\}\s*from\s*['"]([^'"]+)['"]/g;for(let t=i.exec(e);t!==null;t=i.exec(e)){let e=t[1]??``;for(let r of e.split(`,`)){let e=r.trim().split(/\s+as\s+/);if((e[1]??e[0]??``).trim()===n)return t[2]??null}}return null}export{parseExtensionMountSpecifier};
@@ -0,0 +1,109 @@
1
+ import { type DiscoverDiagnostic } from "#discover/diagnostics.js";
2
+ import type { ExtensionSourceRef } from "#discover/manifest.js";
3
+ import type { ProjectSource } from "#discover/project-source.js";
4
+ /**
5
+ * Emitted when a mount file cannot be resolved to an extension package.
6
+ */
7
+ export declare const DISCOVER_EXTENSION_MOUNT_UNRESOLVED = "discover/extension-mount-unresolved";
8
+ /**
9
+ * Emitted when one namespace is claimed by both a file mount
10
+ * (`extensions/<ns>.ts`) and a directory mount (`extensions/<ns>/`).
11
+ */
12
+ export declare const DISCOVER_EXTENSION_MOUNT_AMBIGUOUS = "discover/extension-mount-ambiguous";
13
+ /**
14
+ * Emitted when a directory mount (`extensions/<ns>/`) is missing its required
15
+ * `extension.<ext>` mount declaration.
16
+ */
17
+ export declare const DISCOVER_EXTENSION_MOUNT_MISSING_DECLARATION = "discover/extension-mount-missing-declaration";
18
+ /**
19
+ * Emitted when an extension declares its own `extensions/` mount slot. Extensions
20
+ * cannot mount other extensions yet; the slot is reserved so enabling nesting
21
+ * later is additive rather than a surprise.
22
+ */
23
+ export declare const DISCOVER_EXTENSION_NESTED_MOUNT_UNSUPPORTED = "discover/extension-nested-mount-unsupported";
24
+ /**
25
+ * Emitted when a consumer's agent-root contribution (e.g. `agent/tools/crm__x.ts`)
26
+ * uses a mounted extension's `<ns>__` prefix. That prefix is reserved for the
27
+ * extension and its co-located overrides, not the agent root.
28
+ */
29
+ export declare const DISCOVER_EXTENSION_OVERRIDE_OUTSIDE_MOUNT = "discover/extension-override-outside-mount";
30
+ /**
31
+ * Emitted when a resolved package is not a valid eve extension.
32
+ */
33
+ export declare const DISCOVER_EXTENSION_PACKAGE_INVALID = "discover/extension-package-invalid";
34
+ /**
35
+ * Emitted when the app's eve version does not satisfy an extension's declared
36
+ * `peerDependencies.eve` range — the tie between an extension and the eve it was
37
+ * built for.
38
+ */
39
+ export declare const DISCOVER_EXTENSION_EVE_INCOMPATIBLE = "discover/extension-eve-incompatible";
40
+ /**
41
+ * Emitted when an extension source tree declares agent-level config (`agent.ts`),
42
+ * which is the consuming agent's to own.
43
+ */
44
+ export declare const DISCOVER_EXTENSION_AGENT_CONFIG_UNSUPPORTED = "discover/extension-agent-config-unsupported";
45
+ /**
46
+ * Emitted when an extension source tree declares a `sandbox`, which is the
47
+ * consuming agent's to own.
48
+ */
49
+ export declare const DISCOVER_EXTENSION_SANDBOX_UNSUPPORTED = "discover/extension-sandbox-unsupported";
50
+ /**
51
+ * Emitted when an extension source tree declares `schedules`. Background
52
+ * scheduling runs sessions on the consuming agent's deployment under its limits,
53
+ * so it is the consuming agent's to own, not an extension's.
54
+ */
55
+ export declare const DISCOVER_EXTENSION_SCHEDULE_UNSUPPORTED = "discover/extension-schedule-unsupported";
56
+ /**
57
+ * Resolved on-disk location of one mounted extension package.
58
+ */
59
+ export interface ExtensionMountLocation {
60
+ /** Mount namespace derived from the mount filename (e.g. `crm`). */
61
+ readonly namespace: string;
62
+ /** Package specifier the mount imports (e.g. `@acme/crm`). */
63
+ readonly specifier: string;
64
+ /** Package name from the resolved `package.json`, used to scope state. */
65
+ readonly packageName: string;
66
+ /** Absolute path to the resolved package root. */
67
+ readonly packageRoot: string;
68
+ /** Absolute path to the extension's agent-shaped source root. */
69
+ readonly sourceRoot: string;
70
+ }
71
+ /**
72
+ * Derives the mount namespace from an `extensions/<name>.<ext>` logical path.
73
+ */
74
+ export declare function mountNamespace(logicalPath: string): string;
75
+ /**
76
+ * Derives the mount namespace from a mount ref's `extensions/…` logical path
77
+ * for either mount form: the file form (`extensions/crm.ts` → `crm`) or the
78
+ * directory form (`extensions/crm/extension.ts` → `crm`).
79
+ */
80
+ export declare function mountRefNamespace(logicalPath: string): string;
81
+ /**
82
+ * Derives the namespace that scopes an extension's durable state keys and config
83
+ * binding from its package name. Unlike the mount namespace, this stays keyed to
84
+ * the package (e.g. `@acme/crm` → `acme-crm`) so renaming the consumer's mount
85
+ * file never orphans persisted state.
86
+ */
87
+ export declare function packageStateNamespace(packageName: string): string;
88
+ /**
89
+ * Resolves one extension mount to its package and agent-shaped source root
90
+ * without importing the mount module. Reads the mount source text to extract
91
+ * the package specifier, resolves the package, and reads
92
+ * `package.json#eve.extension` for the source root.
93
+ */
94
+ export declare function locateExtensionMount(input: {
95
+ readonly source: ProjectSource;
96
+ readonly agentRoot: string;
97
+ readonly appRoot: string;
98
+ readonly mount: ExtensionSourceRef;
99
+ /**
100
+ * Mount namespace the caller derived from the mount path — passed in because
101
+ * the file and directory mount forms name it at different path positions.
102
+ */
103
+ readonly namespace: string;
104
+ /** The app's eve version, checked against the extension's `peerDependencies.eve`. */
105
+ readonly eveVersion: string;
106
+ }): Promise<{
107
+ location?: ExtensionMountLocation;
108
+ diagnostics: DiscoverDiagnostic[];
109
+ }>;
@@ -0,0 +1 @@
1
+ import{dirname,isAbsolute,join,resolve}from"node:path";import{createDiscoverErrorDiagnostic}from"#discover/diagnostics.js";import{SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS}from"#discover/filesystem.js";import semver from"#compiled/semver/index.js";import{parseExtensionMountSpecifier}from"#discover/extension-specifier.js";const DISCOVER_EXTENSION_MOUNT_UNRESOLVED=`discover/extension-mount-unresolved`,DISCOVER_EXTENSION_MOUNT_AMBIGUOUS=`discover/extension-mount-ambiguous`,DISCOVER_EXTENSION_MOUNT_MISSING_DECLARATION=`discover/extension-mount-missing-declaration`,DISCOVER_EXTENSION_NESTED_MOUNT_UNSUPPORTED=`discover/extension-nested-mount-unsupported`,DISCOVER_EXTENSION_OVERRIDE_OUTSIDE_MOUNT=`discover/extension-override-outside-mount`,DISCOVER_EXTENSION_PACKAGE_INVALID=`discover/extension-package-invalid`,DISCOVER_EXTENSION_EVE_INCOMPATIBLE=`discover/extension-eve-incompatible`,DISCOVER_EXTENSION_AGENT_CONFIG_UNSUPPORTED=`discover/extension-agent-config-unsupported`,DISCOVER_EXTENSION_SANDBOX_UNSUPPORTED=`discover/extension-sandbox-unsupported`,DISCOVER_EXTENSION_SCHEDULE_UNSUPPORTED=`discover/extension-schedule-unsupported`;function mountNamespace(e){let t=e.slice(e.lastIndexOf(`/`)+1);for(let e of SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS)if(t.toLowerCase().endsWith(e))return t.slice(0,t.length-e.length);return t}function mountRefNamespace(e){let t=e.replace(/^extensions\//,``),n=t.indexOf(`/`);return n===-1?mountNamespace(e):t.slice(0,n)}function packageStateNamespace(e){return e.replace(/^@/,``).replace(/[^a-zA-Z0-9._-]+/g,`-`).replace(/^-+|-+$/g,``)||`extension`}async function locateExtensionMount(t){let a=join(t.agentRoot,t.mount.logicalPath),{namespace:s}=t,c;try{c=await t.source.readTextFile(a)}catch{return{diagnostics:[createDiscoverErrorDiagnostic({code:DISCOVER_EXTENSION_MOUNT_UNRESOLVED,message:`Could not read extension mount "${t.mount.logicalPath}".`,sourcePath:a})]}}let l=parseExtensionMountSpecifier(c);if(l===null)return{diagnostics:[createDiscoverErrorDiagnostic({code:DISCOVER_EXTENSION_MOUNT_UNRESOLVED,message:`Extension mount "${t.mount.logicalPath}" must default-export a mounted extension, e.g. \`export default crm({ ... })\` or \`export { default } from "@acme/crm"\`.`,sourcePath:a})]};let u=await resolvePackageRoot({source:t.source,appRoot:t.appRoot,mountDirectory:dirname(a),specifier:l});if(u===null)return{diagnostics:[createDiscoverErrorDiagnostic({code:DISCOVER_EXTENSION_MOUNT_UNRESOLVED,message:`Could not resolve extension package "${l}" mounted by "${t.mount.logicalPath}".`,sourcePath:a})]};let d=join(u,`package.json`),f;try{f=JSON.parse(await t.source.readTextFile(d))}catch{return{diagnostics:[createDiscoverErrorDiagnostic({code:DISCOVER_EXTENSION_PACKAGE_INVALID,message:`Extension package "${l}" has no readable package.json at "${d}".`,sourcePath:d})]}}let p=f.eve?.extension;if(typeof p!=`string`||p.length===0)return{diagnostics:[createDiscoverErrorDiagnostic({code:DISCOVER_EXTENSION_PACKAGE_INVALID,message:`Package "${l}" is not an eve extension: its package.json is missing the \`eve.extension\` source-root field.`,sourcePath:d})]};let m=typeof f.name==`string`&&f.name.length>0?f.name:l,h=f.peerDependencies?.eve;return typeof h==`string`&&semver.validRange(h)!==null&&!semver.intersects(t.eveVersion,h)?{diagnostics:[createDiscoverErrorDiagnostic({code:DISCOVER_EXTENSION_EVE_INCOMPATIBLE,message:`Extension "${m}" requires eve "${h}", but this app uses eve ${t.eveVersion}. Upgrade the extension to a version that supports this eve, or align your eve version.`,sourcePath:d})]}:{location:{namespace:s,specifier:l,packageName:m,packageRoot:u,sourceRoot:resolve(u,p)},diagnostics:[]}}async function resolvePackageRoot(i){if(i.specifier.startsWith(`.`)){let e=resolve(i.mountDirectory,i.specifier);return await hasPackageJson(i.source,e)?e:null}if(isAbsolute(i.specifier))return await hasPackageJson(i.source,i.specifier)?i.specifier:null;let a=bareSpecifierPackagePath(i.specifier),o=resolve(i.appRoot);for(;;){let t=join(o,`node_modules`,a);if(await hasPackageJson(i.source,t))return t;let r=dirname(o);if(r===o)return null;o=r}}function bareSpecifierPackagePath(e){let t=e.split(`/`);return e.startsWith(`@`)?t.slice(0,2).join(`/`):t[0]??e}async function hasPackageJson(e,t){return await e.stat(join(t,`package.json`))===`file`}export{DISCOVER_EXTENSION_AGENT_CONFIG_UNSUPPORTED,DISCOVER_EXTENSION_EVE_INCOMPATIBLE,DISCOVER_EXTENSION_MOUNT_AMBIGUOUS,DISCOVER_EXTENSION_MOUNT_MISSING_DECLARATION,DISCOVER_EXTENSION_MOUNT_UNRESOLVED,DISCOVER_EXTENSION_NESTED_MOUNT_UNSUPPORTED,DISCOVER_EXTENSION_OVERRIDE_OUTSIDE_MOUNT,DISCOVER_EXTENSION_PACKAGE_INVALID,DISCOVER_EXTENSION_SANDBOX_UNSUPPORTED,DISCOVER_EXTENSION_SCHEDULE_UNSUPPORTED,locateExtensionMount,mountNamespace,mountRefNamespace,packageStateNamespace};
@@ -15,7 +15,7 @@ export type DirectoryEntryType = "directory" | "file" | "other";
15
15
  /**
16
16
  * Classified root-level agent entry.
17
17
  */
18
- export type AgentRootEntryKind = "agent-config-module" | "channels-directory" | "connections-directory" | "hooks-directory" | "instructions-directory" | "instructions-markdown" | "instructions-module" | "lib-directory" | "sandbox-directory" | "schedules-directory" | "skills-directory" | "system-markdown" | "system-module" | "tools-directory" | "unknown" | "subagents-directory";
18
+ export type AgentRootEntryKind = "agent-config-module" | "channels-directory" | "connections-directory" | "extensions-directory" | "hooks-directory" | "instructions-directory" | "instructions-markdown" | "instructions-module" | "lib-directory" | "sandbox-directory" | "schedules-directory" | "skills-directory" | "system-markdown" | "system-module" | "tools-directory" | "unknown" | "subagents-directory";
19
19
  /**
20
20
  * Classified local-subagent root entry.
21
21
  */
@@ -1 +1 @@
1
- import{sep}from"node:path";const SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS=[`.cts`,`.mts`,`.cjs`,`.mjs`,`.ts`,`.js`],PROJECT_MARKER_FILE_NAMES=[`package.json`,`vercel.json`],PROJECT_MARKER_FILE_NAME_SET=new Set(PROJECT_MARKER_FILE_NAMES);function getDirectoryEntryType(e){return e.isDirectory()?`directory`:e.isFile()?`file`:`other`}function isProjectMarkerEntry(e,t){return t===`file`&&PROJECT_MARKER_FILE_NAME_SET.has(e)}function classifyAgentRootEntry(e,t){if(t===`file`)return matchesSupportedModuleBaseName(e,`agent`)?`agent-config-module`:e.toLowerCase()===`instructions.md`?`instructions-markdown`:matchesSupportedModuleBaseName(e,`instructions`)?`instructions-module`:e.toLowerCase()===`system.md`?`system-markdown`:matchesSupportedModuleBaseName(e,`system`)?`system-module`:`unknown`;if(t===`directory`){if(e===`channels`)return`channels-directory`;if(e===`connections`)return`connections-directory`;if(e===`hooks`)return`hooks-directory`;if(e===`instructions`)return`instructions-directory`;if(e===`lib`)return`lib-directory`;if(e===`skills`)return`skills-directory`;if(e===`sandbox`)return`sandbox-directory`;if(e===`tools`)return`tools-directory`;if(e===`schedules`)return`schedules-directory`;if(e===`subagents`)return`subagents-directory`}return`unknown`}function classifyLocalSubagentEntry(e,t){if(t===`file`)return matchesSupportedModuleBaseName(e,`agent`)?`agent-config-module`:e.toLowerCase()===`instructions.md`?`instructions-markdown`:matchesSupportedModuleBaseName(e,`instructions`)?`instructions-module`:e.toLowerCase()===`system.md`?`system-markdown`:matchesSupportedModuleBaseName(e,`system`)?`system-module`:`unknown`;if(t===`directory`){if(e===`connections`)return`connections-directory`;if(e===`hooks`)return`hooks-directory`;if(e===`instructions`)return`instructions-directory`;if(e===`lib`)return`lib-directory`;if(e===`sandbox`)return`sandbox-directory`;if(e===`skills`)return`skills-directory`;if(e===`tools`)return`tools-directory`;if(e===`subagents`)return`subagents-directory`;if(e===`schedules`)return`invalid-schedules-directory`}return`unknown`}function classifySkillPackageEntry(e,t){if(t===`file`)return e.toLowerCase()===`skill.md`?`skill-markdown`:`skill-resource`;if(t===`directory`){if(e===`scripts`)return`skill-scripts-directory`;if(e===`references`)return`skill-references-directory`;if(e===`assets`)return`skill-assets-directory`}return`skill-resource`}function classifySkillsDirectoryEntry(e,t){if(t===`directory`)return`skill-package-directory`;if(t===`file`){if(e.toLowerCase().endsWith(`.md`))return`flat-skill-markdown`;if(getSupportedModuleBaseName(e)!==null)return`flat-skill-module`}return`unknown`}function normalizeLogicalPath(t){return t.replaceAll(sep,`/`).replace(/^\.\//,``).replace(/^\/+/,``)}function getSupportedModuleBaseName(e){for(let n of SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS)if(e.endsWith(n)&&e.length>n.length)return e.slice(0,-n.length);return null}function matchesSupportedModuleBaseName(e,t){return getSupportedModuleBaseName(e)===t}function stripLogicalPathExtension(e){let t=normalizeLogicalPath(e),n=t.lastIndexOf(`/`),r=t.lastIndexOf(`.`);return r===-1||r<n?t:t.slice(0,r)}export{PROJECT_MARKER_FILE_NAMES,SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS,classifyAgentRootEntry,classifyLocalSubagentEntry,classifySkillPackageEntry,classifySkillsDirectoryEntry,getDirectoryEntryType,getSupportedModuleBaseName,isProjectMarkerEntry,matchesSupportedModuleBaseName,normalizeLogicalPath,stripLogicalPathExtension};
1
+ import{sep}from"node:path";const SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS=[`.cts`,`.mts`,`.cjs`,`.mjs`,`.ts`,`.js`],PROJECT_MARKER_FILE_NAMES=[`package.json`,`vercel.json`],PROJECT_MARKER_FILE_NAME_SET=new Set(PROJECT_MARKER_FILE_NAMES);function getDirectoryEntryType(e){return e.isDirectory()?`directory`:e.isFile()?`file`:`other`}function isProjectMarkerEntry(e,t){return t===`file`&&PROJECT_MARKER_FILE_NAME_SET.has(e)}function classifyAgentRootEntry(e,t){if(t===`file`)return matchesSupportedModuleBaseName(e,`agent`)?`agent-config-module`:e.toLowerCase()===`instructions.md`?`instructions-markdown`:matchesSupportedModuleBaseName(e,`instructions`)?`instructions-module`:e.toLowerCase()===`system.md`?`system-markdown`:matchesSupportedModuleBaseName(e,`system`)?`system-module`:`unknown`;if(t===`directory`){if(e===`channels`)return`channels-directory`;if(e===`connections`)return`connections-directory`;if(e===`extensions`)return`extensions-directory`;if(e===`hooks`)return`hooks-directory`;if(e===`instructions`)return`instructions-directory`;if(e===`lib`)return`lib-directory`;if(e===`skills`)return`skills-directory`;if(e===`sandbox`)return`sandbox-directory`;if(e===`tools`)return`tools-directory`;if(e===`schedules`)return`schedules-directory`;if(e===`subagents`)return`subagents-directory`}return`unknown`}function classifyLocalSubagentEntry(e,t){if(t===`file`)return matchesSupportedModuleBaseName(e,`agent`)?`agent-config-module`:e.toLowerCase()===`instructions.md`?`instructions-markdown`:matchesSupportedModuleBaseName(e,`instructions`)?`instructions-module`:e.toLowerCase()===`system.md`?`system-markdown`:matchesSupportedModuleBaseName(e,`system`)?`system-module`:`unknown`;if(t===`directory`){if(e===`connections`)return`connections-directory`;if(e===`hooks`)return`hooks-directory`;if(e===`instructions`)return`instructions-directory`;if(e===`lib`)return`lib-directory`;if(e===`sandbox`)return`sandbox-directory`;if(e===`skills`)return`skills-directory`;if(e===`tools`)return`tools-directory`;if(e===`subagents`)return`subagents-directory`;if(e===`schedules`)return`invalid-schedules-directory`}return`unknown`}function classifySkillPackageEntry(e,t){if(t===`file`)return e.toLowerCase()===`skill.md`?`skill-markdown`:`skill-resource`;if(t===`directory`){if(e===`scripts`)return`skill-scripts-directory`;if(e===`references`)return`skill-references-directory`;if(e===`assets`)return`skill-assets-directory`}return`skill-resource`}function classifySkillsDirectoryEntry(e,t){if(t===`directory`)return`skill-package-directory`;if(t===`file`){if(e.toLowerCase().endsWith(`.md`))return`flat-skill-markdown`;if(getSupportedModuleBaseName(e)!==null)return`flat-skill-module`}return`unknown`}function normalizeLogicalPath(t){return t.replaceAll(sep,`/`).replace(/^\.\//,``).replace(/^\/+/,``)}function getSupportedModuleBaseName(e){for(let n of SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS)if(e.endsWith(n)&&e.length>n.length)return e.slice(0,-n.length);return null}function matchesSupportedModuleBaseName(e,t){return getSupportedModuleBaseName(e)===t}function stripLogicalPathExtension(e){let t=normalizeLogicalPath(e),n=t.lastIndexOf(`/`),r=t.lastIndexOf(`.`);return r===-1||r<n?t:t.slice(0,r)}export{PROJECT_MARKER_FILE_NAMES,SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS,classifyAgentRootEntry,classifyLocalSubagentEntry,classifySkillPackageEntry,classifySkillsDirectoryEntry,getDirectoryEntryType,getSupportedModuleBaseName,isProjectMarkerEntry,matchesSupportedModuleBaseName,normalizeLogicalPath,stripLogicalPathExtension};
@@ -39,6 +39,11 @@ export declare const DISCOVER_HOOKS_DIRECTORY_INVALID = "discover/hooks-director
39
39
  * directory.
40
40
  */
41
41
  export declare const DISCOVER_CHANNELS_DIRECTORY_INVALID = "discover/channels-directory-invalid";
42
+ /**
43
+ * Shared diagnostic emitted when the authored `extensions/` root is not a
44
+ * directory.
45
+ */
46
+ export declare const DISCOVER_EXTENSIONS_DIRECTORY_INVALID = "discover/extensions-directory-invalid";
42
47
  /**
43
48
  * Shared diagnostic emitted when an authored `tools/*.{ts,…}` filename does
44
49
  * not satisfy the model tool-name charset rule.
@@ -70,6 +75,11 @@ export declare const DISCOVER_CHANNEL_NAME_INVALID = "discover/channel-name-inva
70
75
  * directory segment does not satisfy the hook slug charset rule.
71
76
  */
72
77
  export declare const DISCOVER_HOOK_NAME_INVALID = "discover/hook-name-invalid";
78
+ /**
79
+ * Shared diagnostic emitted when an authored `extensions/*.{ts,…}` mount
80
+ * filename does not satisfy the extension namespace charset rule.
81
+ */
82
+ export declare const DISCOVER_EXTENSION_NAME_INVALID = "discover/extension-name-invalid";
73
83
  /**
74
84
  * Tool filename charset. The slug must start with an ASCII letter and may
75
85
  * contain ASCII letters, digits, underscores, and dashes. The 64-character
@@ -98,6 +108,14 @@ export declare const CHANNEL_SLUG_PATTERN: RegExp;
98
108
  * are not allowed — hooks have no URL semantics.
99
109
  */
100
110
  export declare const HOOK_SLUG_PATTERN: RegExp;
111
+ /**
112
+ * Extension mount filename charset. The basename becomes the namespace the
113
+ * consumer's build prefixes onto every contribution (`crm` → `crm__search`),
114
+ * so it uses the same restrictive charset as tool slugs: ASCII letters,
115
+ * digits, underscores, and dashes, starting with a letter, up to 64
116
+ * characters.
117
+ */
118
+ export declare const EXTENSION_SLUG_PATTERN: RegExp;
101
119
  /**
102
120
  * Shared diagnostic emitted when discovery ignores one unsupported directory.
103
121
  */
@@ -182,6 +200,15 @@ export declare function createChannelNameDiagnostic(segment: string, sourcePath:
182
200
  * the runtime never sees a malformed slug.
183
201
  */
184
202
  export declare function createHookNameDiagnostic(segment: string, sourcePath: string): DiscoverDiagnostic | null;
203
+ /**
204
+ * Returns a discovery diagnostic when an extension mount filename violates
205
+ * {@link EXTENSION_SLUG_PATTERN}, or `null` when it satisfies the rule.
206
+ *
207
+ * The mount basename becomes the namespace prefixed onto every contribution
208
+ * the extension composes into the consuming agent, so it must be a legal
209
+ * identifier segment.
210
+ */
211
+ export declare function createExtensionNameDiagnostic(slotName: string, sourcePath: string): DiscoverDiagnostic | null;
185
212
  export { discoverNamedSourceDirectory, type DiscoverNamedSourceDirectoryModuleInput, type DiscoverNamedSourceDirectoryWithMarkdownInput, } from "#discover/named-source-directory.js";
186
213
  /**
187
214
  * Emits shared diagnostics for unsupported root-level directories.
@@ -1 +1 @@
1
- import{join}from"node:path";import{createDiscoverErrorDiagnostic,createDiscoverWarningDiagnostic}from"#discover/diagnostics.js";import{getDirectoryEntryType}from"#discover/filesystem.js";import{createModuleSourceRef}from"#discover/manifest.js";import{collectFlatSlotCandidates}from"#discover/slots.js";import{lowerInstructionsMarkdown}from"#internal/helpers/markdown.js";import{discoverMarkdownSource}from"#discover/markdown.js";import{discoverNamedSourceDirectory,discoverNamedSourceDirectory as discoverNamedSourceDirectory$1}from"#discover/named-source-directory.js";const DISCOVER_MODULE_SLOT_COLLISION=`discover/module-slot-collision`,DISCOVER_REQUIRED_INSTRUCTIONS_MISSING=`discover/required-instructions-missing`,DISCOVER_DEPRECATED_SYSTEM_SLOT=`discover/deprecated-system-slot`,DISCOVER_SLOT_COLLISION=`discover/slot-collision`,DISCOVER_TOOLS_DIRECTORY_INVALID=`discover/tools-directory-invalid`,DISCOVER_HOOKS_DIRECTORY_INVALID=`discover/hooks-directory-invalid`,DISCOVER_CHANNELS_DIRECTORY_INVALID=`discover/channels-directory-invalid`,DISCOVER_TOOL_NAME_INVALID=`discover/tool-name-invalid`,DISCOVER_CONNECTION_NAME_INVALID=`discover/connection-name-invalid`,DISCOVER_SANDBOX_DIRECTORY_INVALID=`discover/sandbox-directory-invalid`,DISCOVER_INSTRUCTIONS_DIRECTORY_INVALID=`discover/instructions-directory-invalid`,DISCOVER_CHANNEL_NAME_INVALID=`discover/channel-name-invalid`,DISCOVER_HOOK_NAME_INVALID=`discover/hook-name-invalid`,TOOL_SLUG_PATTERN=/^[a-zA-Z][a-zA-Z0-9_-]{0,63}$/,CONNECTION_SLUG_PATTERN=/^[a-z][a-z0-9-]{0,63}$/,CHANNEL_SLUG_PATTERN=/^(\.?[a-z][a-z0-9-]{0,63}|\[[a-zA-Z][a-zA-Z0-9_]{0,63}\])$/,HOOK_SLUG_PATTERN=/^[a-zA-Z][a-zA-Z0-9_-]{0,63}$/,DISCOVER_UNSUPPORTED_DIRECTORY=`discover/unsupported-directory`;async function readSortedDirectoryEntries(e,t){let n=[...await e.readDirectory(t)];return n.sort((e,t)=>e.name.localeCompare(t.name)),n}async function discoverInstructionsSource(r){let i=r.rootEntries.some(e=>e.name===`instructions`&&e.isDirectory()),a=await discoverSlotSource({markdownFileName:`instructions.md`,moduleBaseName:`instructions`,rootEntries:r.rootEntries,rootPath:r.rootPath,slotLabel:`instructions`,source:r.source});if(i){let t=await discoverNamedSourceDirectory$1({allowMarkdown:!0,directoryName:`instructions`,invalidDirectoryCode:DISCOVER_INSTRUCTIONS_DIRECTORY_INVALID,invalidDirectoryMessage:`Expected "${join(r.rootPath,`instructions`)}" to be a directory of authored instructions.`,markdownLowerer:e=>lowerInstructionsMarkdown(e),recursive:!1,rootEntries:r.rootEntries,rootPath:r.rootPath,source:r.source}),n=[...t.sources];return a.source!==void 0&&n.unshift(a.source),{diagnostics:[...a.diagnostics,...t.diagnostics],instructions:n}}if(a.diagnostics.length>0||a.source!==void 0)return{diagnostics:a.diagnostics,instructions:a.source===void 0?[]:[a.source]};let o=await discoverSlotSource({markdownFileName:`system.md`,moduleBaseName:`system`,rootEntries:r.rootEntries,rootPath:r.rootPath,slotLabel:`system`,source:r.source});if(o.source!==void 0){let t=o.source.sourceKind===`markdown`?`system.md`:o.source.logicalPath;return{diagnostics:[createDiscoverWarningDiagnostic({code:DISCOVER_DEPRECATED_SYSTEM_SLOT,message:`The "${t}" slot is deprecated. Rename it to "${t.replace(/^system/,`instructions`)}" — the runtime still loads the legacy slot for now, but support will be removed in a future release.`,sourcePath:join(r.rootPath,t)}),...o.diagnostics],instructions:[o.source]}}return o.diagnostics.length>0?{diagnostics:o.diagnostics,instructions:[]}:r.required===!1?{diagnostics:[],instructions:[]}:{diagnostics:[createDiscoverErrorDiagnostic({code:DISCOVER_REQUIRED_INSTRUCTIONS_MISSING,message:`Expected authored instructions at "instructions.md", "instructions.ts", "instructions.cts", "instructions.mts", "instructions.js", "instructions.cjs", "instructions.mjs", or "instructions/" directory.`,sourcePath:r.rootPath})],instructions:[]}}async function discoverSlotSource(t){let n=collectFlatSlotCandidates(t.rootEntries,{markdownFileName:t.markdownFileName,moduleBaseName:t.moduleBaseName});if(n.markdownFileName!==void 0&&n.moduleFileNames.length>0)return{diagnostics:[createSlotCollisionDiagnostic(t.rootPath,t.slotLabel,[n.markdownFileName,...n.moduleFileNames])]};if(n.moduleFileNames.length>1)return{diagnostics:[createModuleSlotCollisionDiagnostic(t.rootPath,t.slotLabel,n.moduleFileNames)]};if(n.markdownFileName!==void 0)return{diagnostics:[],source:await discoverMarkdownSource({logicalPath:t.markdownFileName,lower:lowerInstructionsMarkdown,source:t.source,sourcePath:join(t.rootPath,n.markdownFileName)})};let[r]=n.moduleFileNames;return r===void 0?{diagnostics:[]}:{diagnostics:[],source:createModuleSourceRef({logicalPath:r})}}function discoverFlatModuleSource(e){let n=collectFlatSlotCandidates(e.rootEntries,{moduleBaseName:e.slotName});if(n.moduleFileNames.length>1)return{diagnostics:[createModuleSlotCollisionDiagnostic(e.rootPath,e.slotName,n.moduleFileNames)]};let[r]=n.moduleFileNames;return r===void 0?e.missingDiagnostic===void 0?{diagnostics:[]}:{diagnostics:[createDiscoverErrorDiagnostic({code:e.missingDiagnostic.code,message:e.missingDiagnostic.message,sourcePath:e.rootPath})]}:{diagnostics:[],module:createModuleSourceRef({logicalPath:r})}}function createToolNameDiagnostic(e,n){return TOOL_SLUG_PATTERN.test(e)?null:createDiscoverErrorDiagnostic({code:DISCOVER_TOOL_NAME_INVALID,message:`Tool filename "${e}" is not a legal tool name. Expected ASCII letters, digits, underscores, and dashes only, starting with a letter, up to 64 characters.`,sourcePath:n})}function createConnectionNameDiagnostic(e,n){return CONNECTION_SLUG_PATTERN.test(e)?null:createDiscoverErrorDiagnostic({code:DISCOVER_CONNECTION_NAME_INVALID,message:`Connection filename "${e}" is not a legal connection name. Expected lowercase ASCII letters, digits, and dashes only, starting with a letter, up to 64 characters.`,sourcePath:n})}function createChannelNameDiagnostic(e,n){return CHANNEL_SLUG_PATTERN.test(e)?null:createDiscoverErrorDiagnostic({code:DISCOVER_CHANNEL_NAME_INVALID,message:`Channel path segment "${e}" is not a legal channel name. Expected lowercase kebab-case (\`my-channel\`), optionally with a leading dot (\`.well-known\`), or a path parameter form (\`[sessionId]\`).`,sourcePath:n})}function createHookNameDiagnostic(e,n){return HOOK_SLUG_PATTERN.test(e)?null:createDiscoverErrorDiagnostic({code:DISCOVER_HOOK_NAME_INVALID,message:`Hook path segment "${e}" is not a legal hook name. Expected ASCII letters, digits, underscores, and dashes only, starting with a letter, up to 64 characters.`,sourcePath:n})}function createUnsupportedRootDirectoryDiagnostics(t){return t.rootEntries.flatMap(i=>!i.isDirectory()||t.classifyEntry(i.name,getDirectoryEntryType(i))!==`unknown`?[]:[createDiscoverWarningDiagnostic({code:DISCOVER_UNSUPPORTED_DIRECTORY,message:t.createUnsupportedDirectoryMessage(i.name),sourcePath:join(t.rootPath,i.name)})])}function createSlotCollisionDiagnostic(e,n,r){return createDiscoverErrorDiagnostic({code:DISCOVER_SLOT_COLLISION,message:`Found conflicting authored sources for "${n}": ${formatQuotedFileList(r)}.`,sourcePath:e})}function createModuleSlotCollisionDiagnostic(e,n,r){return createDiscoverErrorDiagnostic({code:DISCOVER_MODULE_SLOT_COLLISION,message:`Found multiple authored module sources for "${n}": ${formatQuotedFileList(r)}.`,sourcePath:e})}function formatQuotedFileList(e){return e.map(e=>`"${e}"`).join(`, `)}export{CHANNEL_SLUG_PATTERN,CONNECTION_SLUG_PATTERN,DISCOVER_CHANNELS_DIRECTORY_INVALID,DISCOVER_CHANNEL_NAME_INVALID,DISCOVER_CONNECTION_NAME_INVALID,DISCOVER_DEPRECATED_SYSTEM_SLOT,DISCOVER_HOOKS_DIRECTORY_INVALID,DISCOVER_HOOK_NAME_INVALID,DISCOVER_INSTRUCTIONS_DIRECTORY_INVALID,DISCOVER_MODULE_SLOT_COLLISION,DISCOVER_REQUIRED_INSTRUCTIONS_MISSING,DISCOVER_SANDBOX_DIRECTORY_INVALID,DISCOVER_SLOT_COLLISION,DISCOVER_TOOLS_DIRECTORY_INVALID,DISCOVER_TOOL_NAME_INVALID,DISCOVER_UNSUPPORTED_DIRECTORY,HOOK_SLUG_PATTERN,TOOL_SLUG_PATTERN,createChannelNameDiagnostic,createConnectionNameDiagnostic,createHookNameDiagnostic,createModuleSlotCollisionDiagnostic,createSlotCollisionDiagnostic,createToolNameDiagnostic,createUnsupportedRootDirectoryDiagnostics,discoverFlatModuleSource,discoverInstructionsSource,discoverNamedSourceDirectory,readSortedDirectoryEntries};
1
+ import{join}from"node:path";import{createDiscoverErrorDiagnostic,createDiscoverWarningDiagnostic}from"#discover/diagnostics.js";import{getDirectoryEntryType}from"#discover/filesystem.js";import{createModuleSourceRef}from"#discover/manifest.js";import{collectFlatSlotCandidates}from"#discover/slots.js";import{lowerInstructionsMarkdown}from"#internal/helpers/markdown.js";import{discoverMarkdownSource}from"#discover/markdown.js";import{discoverNamedSourceDirectory,discoverNamedSourceDirectory as discoverNamedSourceDirectory$1}from"#discover/named-source-directory.js";const DISCOVER_MODULE_SLOT_COLLISION=`discover/module-slot-collision`,DISCOVER_REQUIRED_INSTRUCTIONS_MISSING=`discover/required-instructions-missing`,DISCOVER_DEPRECATED_SYSTEM_SLOT=`discover/deprecated-system-slot`,DISCOVER_SLOT_COLLISION=`discover/slot-collision`,DISCOVER_TOOLS_DIRECTORY_INVALID=`discover/tools-directory-invalid`,DISCOVER_HOOKS_DIRECTORY_INVALID=`discover/hooks-directory-invalid`,DISCOVER_CHANNELS_DIRECTORY_INVALID=`discover/channels-directory-invalid`,DISCOVER_EXTENSIONS_DIRECTORY_INVALID=`discover/extensions-directory-invalid`,DISCOVER_TOOL_NAME_INVALID=`discover/tool-name-invalid`,DISCOVER_CONNECTION_NAME_INVALID=`discover/connection-name-invalid`,DISCOVER_SANDBOX_DIRECTORY_INVALID=`discover/sandbox-directory-invalid`,DISCOVER_INSTRUCTIONS_DIRECTORY_INVALID=`discover/instructions-directory-invalid`,DISCOVER_CHANNEL_NAME_INVALID=`discover/channel-name-invalid`,DISCOVER_HOOK_NAME_INVALID=`discover/hook-name-invalid`,DISCOVER_EXTENSION_NAME_INVALID=`discover/extension-name-invalid`,TOOL_SLUG_PATTERN=/^[a-zA-Z][a-zA-Z0-9_-]{0,63}$/,CONNECTION_SLUG_PATTERN=/^[a-z][a-z0-9-]{0,63}$/,CHANNEL_SLUG_PATTERN=/^(\.?[a-z][a-z0-9-]{0,63}|\[[a-zA-Z][a-zA-Z0-9_]{0,63}\])$/,HOOK_SLUG_PATTERN=/^[a-zA-Z][a-zA-Z0-9_-]{0,63}$/,EXTENSION_SLUG_PATTERN=/^[a-zA-Z][a-zA-Z0-9_-]{0,63}$/,DISCOVER_UNSUPPORTED_DIRECTORY=`discover/unsupported-directory`;async function readSortedDirectoryEntries(e,t){let n=[...await e.readDirectory(t)];return n.sort((e,t)=>e.name.localeCompare(t.name)),n}async function discoverInstructionsSource(r){let i=r.rootEntries.some(e=>e.name===`instructions`&&e.isDirectory()),a=await discoverSlotSource({markdownFileName:`instructions.md`,moduleBaseName:`instructions`,rootEntries:r.rootEntries,rootPath:r.rootPath,slotLabel:`instructions`,source:r.source});if(i){let t=await discoverNamedSourceDirectory$1({allowMarkdown:!0,directoryName:`instructions`,invalidDirectoryCode:DISCOVER_INSTRUCTIONS_DIRECTORY_INVALID,invalidDirectoryMessage:`Expected "${join(r.rootPath,`instructions`)}" to be a directory of authored instructions.`,markdownLowerer:e=>lowerInstructionsMarkdown(e),recursive:!1,rootEntries:r.rootEntries,rootPath:r.rootPath,source:r.source}),n=[...t.sources];return a.source!==void 0&&n.unshift(a.source),{diagnostics:[...a.diagnostics,...t.diagnostics],instructions:n}}if(a.diagnostics.length>0||a.source!==void 0)return{diagnostics:a.diagnostics,instructions:a.source===void 0?[]:[a.source]};let o=await discoverSlotSource({markdownFileName:`system.md`,moduleBaseName:`system`,rootEntries:r.rootEntries,rootPath:r.rootPath,slotLabel:`system`,source:r.source});if(o.source!==void 0){let t=o.source.sourceKind===`markdown`?`system.md`:o.source.logicalPath;return{diagnostics:[createDiscoverWarningDiagnostic({code:DISCOVER_DEPRECATED_SYSTEM_SLOT,message:`The "${t}" slot is deprecated. Rename it to "${t.replace(/^system/,`instructions`)}" — the runtime still loads the legacy slot for now, but support will be removed in a future release.`,sourcePath:join(r.rootPath,t)}),...o.diagnostics],instructions:[o.source]}}return o.diagnostics.length>0?{diagnostics:o.diagnostics,instructions:[]}:r.required===!1?{diagnostics:[],instructions:[]}:{diagnostics:[createDiscoverErrorDiagnostic({code:DISCOVER_REQUIRED_INSTRUCTIONS_MISSING,message:`Expected authored instructions at "instructions.md", "instructions.ts", "instructions.cts", "instructions.mts", "instructions.js", "instructions.cjs", "instructions.mjs", or "instructions/" directory.`,sourcePath:r.rootPath})],instructions:[]}}async function discoverSlotSource(t){let n=collectFlatSlotCandidates(t.rootEntries,{markdownFileName:t.markdownFileName,moduleBaseName:t.moduleBaseName});if(n.markdownFileName!==void 0&&n.moduleFileNames.length>0)return{diagnostics:[createSlotCollisionDiagnostic(t.rootPath,t.slotLabel,[n.markdownFileName,...n.moduleFileNames])]};if(n.moduleFileNames.length>1)return{diagnostics:[createModuleSlotCollisionDiagnostic(t.rootPath,t.slotLabel,n.moduleFileNames)]};if(n.markdownFileName!==void 0)return{diagnostics:[],source:await discoverMarkdownSource({logicalPath:t.markdownFileName,lower:lowerInstructionsMarkdown,source:t.source,sourcePath:join(t.rootPath,n.markdownFileName)})};let[r]=n.moduleFileNames;return r===void 0?{diagnostics:[]}:{diagnostics:[],source:createModuleSourceRef({logicalPath:r})}}function discoverFlatModuleSource(e){let n=collectFlatSlotCandidates(e.rootEntries,{moduleBaseName:e.slotName});if(n.moduleFileNames.length>1)return{diagnostics:[createModuleSlotCollisionDiagnostic(e.rootPath,e.slotName,n.moduleFileNames)]};let[r]=n.moduleFileNames;return r===void 0?e.missingDiagnostic===void 0?{diagnostics:[]}:{diagnostics:[createDiscoverErrorDiagnostic({code:e.missingDiagnostic.code,message:e.missingDiagnostic.message,sourcePath:e.rootPath})]}:{diagnostics:[],module:createModuleSourceRef({logicalPath:r})}}function createToolNameDiagnostic(e,n){return TOOL_SLUG_PATTERN.test(e)?null:createDiscoverErrorDiagnostic({code:DISCOVER_TOOL_NAME_INVALID,message:`Tool filename "${e}" is not a legal tool name. Expected ASCII letters, digits, underscores, and dashes only, starting with a letter, up to 64 characters.`,sourcePath:n})}function createConnectionNameDiagnostic(e,n){return CONNECTION_SLUG_PATTERN.test(e)?null:createDiscoverErrorDiagnostic({code:DISCOVER_CONNECTION_NAME_INVALID,message:`Connection filename "${e}" is not a legal connection name. Expected lowercase ASCII letters, digits, and dashes only, starting with a letter, up to 64 characters.`,sourcePath:n})}function createChannelNameDiagnostic(e,n){return CHANNEL_SLUG_PATTERN.test(e)?null:createDiscoverErrorDiagnostic({code:DISCOVER_CHANNEL_NAME_INVALID,message:`Channel path segment "${e}" is not a legal channel name. Expected lowercase kebab-case (\`my-channel\`), optionally with a leading dot (\`.well-known\`), or a path parameter form (\`[sessionId]\`).`,sourcePath:n})}function createHookNameDiagnostic(e,n){return HOOK_SLUG_PATTERN.test(e)?null:createDiscoverErrorDiagnostic({code:DISCOVER_HOOK_NAME_INVALID,message:`Hook path segment "${e}" is not a legal hook name. Expected ASCII letters, digits, underscores, and dashes only, starting with a letter, up to 64 characters.`,sourcePath:n})}function createExtensionNameDiagnostic(e,n){return EXTENSION_SLUG_PATTERN.test(e)?null:createDiscoverErrorDiagnostic({code:DISCOVER_EXTENSION_NAME_INVALID,message:`Extension mount filename "${e}" is not a legal extension namespace. Expected ASCII letters, digits, underscores, and dashes only, starting with a letter, up to 64 characters.`,sourcePath:n})}function createUnsupportedRootDirectoryDiagnostics(t){return t.rootEntries.flatMap(i=>!i.isDirectory()||t.classifyEntry(i.name,getDirectoryEntryType(i))!==`unknown`?[]:[createDiscoverWarningDiagnostic({code:DISCOVER_UNSUPPORTED_DIRECTORY,message:t.createUnsupportedDirectoryMessage(i.name),sourcePath:join(t.rootPath,i.name)})])}function createSlotCollisionDiagnostic(e,n,r){return createDiscoverErrorDiagnostic({code:DISCOVER_SLOT_COLLISION,message:`Found conflicting authored sources for "${n}": ${formatQuotedFileList(r)}.`,sourcePath:e})}function createModuleSlotCollisionDiagnostic(e,n,r){return createDiscoverErrorDiagnostic({code:DISCOVER_MODULE_SLOT_COLLISION,message:`Found multiple authored module sources for "${n}": ${formatQuotedFileList(r)}.`,sourcePath:e})}function formatQuotedFileList(e){return e.map(e=>`"${e}"`).join(`, `)}export{CHANNEL_SLUG_PATTERN,CONNECTION_SLUG_PATTERN,DISCOVER_CHANNELS_DIRECTORY_INVALID,DISCOVER_CHANNEL_NAME_INVALID,DISCOVER_CONNECTION_NAME_INVALID,DISCOVER_DEPRECATED_SYSTEM_SLOT,DISCOVER_EXTENSIONS_DIRECTORY_INVALID,DISCOVER_EXTENSION_NAME_INVALID,DISCOVER_HOOKS_DIRECTORY_INVALID,DISCOVER_HOOK_NAME_INVALID,DISCOVER_INSTRUCTIONS_DIRECTORY_INVALID,DISCOVER_MODULE_SLOT_COLLISION,DISCOVER_REQUIRED_INSTRUCTIONS_MISSING,DISCOVER_SANDBOX_DIRECTORY_INVALID,DISCOVER_SLOT_COLLISION,DISCOVER_TOOLS_DIRECTORY_INVALID,DISCOVER_TOOL_NAME_INVALID,DISCOVER_UNSUPPORTED_DIRECTORY,EXTENSION_SLUG_PATTERN,HOOK_SLUG_PATTERN,TOOL_SLUG_PATTERN,createChannelNameDiagnostic,createConnectionNameDiagnostic,createExtensionNameDiagnostic,createHookNameDiagnostic,createModuleSlotCollisionDiagnostic,createSlotCollisionDiagnostic,createToolNameDiagnostic,createUnsupportedRootDirectoryDiagnostics,discoverFlatModuleSource,discoverInstructionsSource,discoverNamedSourceDirectory,readSortedDirectoryEntries};
@@ -106,6 +106,38 @@ export interface SandboxWorkspaceFolderSourceRef {
106
106
  * Package-local helper module preserved by the discovery manifest.
107
107
  */
108
108
  export type LibSourceRef = ModuleSourceRef;
109
+ /**
110
+ * Extension mount source reference preserved by the discovery manifest. Each
111
+ * `agent/extensions/*.ts` file re-exports (and configures) an extension
112
+ * package; the file basename is the mount namespace.
113
+ */
114
+ export type ExtensionSourceRef = ModuleSourceRef;
115
+ /**
116
+ * A mounted extension resolved to its package and discovered agent-shaped
117
+ * source tree. The compiler composes each mount's {@link manifest} into the
118
+ * consuming agent, prefixing contributions with {@link namespace}.
119
+ */
120
+ export interface ResolvedExtensionMount {
121
+ /** Mount namespace derived from the mount filename (e.g. `crm`). */
122
+ readonly namespace: string;
123
+ /** Package specifier the mount imports (e.g. `@acme/crm`). */
124
+ readonly specifier: string;
125
+ /** Package name from the resolved package.json, used to scope state. */
126
+ readonly packageName: string;
127
+ /** Absolute path to the resolved package root. */
128
+ readonly packageRoot: string;
129
+ /** Absolute path to the extension's agent-shaped source root. */
130
+ readonly sourceRoot: string;
131
+ /** Discovered agent-shaped source manifest for the extension. */
132
+ readonly manifest: AgentSourceManifest;
133
+ /**
134
+ * Consumer-authored overrides discovered in the mount directory form
135
+ * (`extensions/<ns>/{tools,connections,…}/`). Composed under the same
136
+ * `<ns>__` namespace as the extension's own contributions but winning on
137
+ * name collision. Absent for the flat file mount form.
138
+ */
139
+ readonly overrides?: AgentSourceManifest;
140
+ }
109
141
  /**
110
142
  * Subagent source reference preserved by the discovery manifest.
111
143
  */
@@ -127,6 +159,18 @@ export interface AgentSourceManifest {
127
159
  connections: ConnectionSourceRef[];
128
160
  configModule?: ModuleSourceRef;
129
161
  diagnosticsSummary: DiscoverDiagnosticsSummary;
162
+ /**
163
+ * Mounted extension source references discovered under `agent/extensions/`.
164
+ * Each entry's logical-path basename is the mount namespace the compiler
165
+ * prefixes onto the extension's composed contributions.
166
+ */
167
+ extensions: ExtensionSourceRef[];
168
+ /**
169
+ * Mounted extensions resolved to their packages and discovered source trees.
170
+ * Populated only for the agent root; extension trees do not mount further
171
+ * extensions (transitive mounting is a non-goal).
172
+ */
173
+ resolvedExtensions: ResolvedExtensionMount[];
130
174
  hooks: ModuleSourceRef[];
131
175
  lib: LibSourceRef[];
132
176
  kind: typeof AGENT_SOURCE_MANIFEST_KIND;
@@ -170,6 +214,8 @@ export interface CreateAgentSourceManifestInput {
170
214
  connections?: readonly ConnectionSourceRef[];
171
215
  configModule?: ModuleSourceRef;
172
216
  diagnostics?: readonly DiscoverDiagnostic[];
217
+ extensions?: readonly ExtensionSourceRef[];
218
+ resolvedExtensions?: readonly ResolvedExtensionMount[];
173
219
  hooks?: readonly ModuleSourceRef[];
174
220
  lib?: readonly LibSourceRef[];
175
221
  /**
@@ -1 +1 @@
1
- import{basename,relative,resolve}from"node:path";import{summarizeDiscoverDiagnostics}from"#discover/diagnostics.js";import{normalizeLogicalPath}from"#discover/filesystem.js";const AGENT_SOURCE_MANIFEST_KIND=`eve-agent-discovery-manifest`,AGENT_SOURCE_MANIFEST_VERSION=12;function createAgentSourceManifest(e){let t=resolve(e.appRoot),i=resolve(e.agentRoot),o={agentId:e.agentId??deriveAgentIdFromRoots(t,i,e.packageName),agentRoot:i,appRoot:t,channels:[...e.channels??[]],connections:[...e.connections??[]],diagnosticsSummary:summarizeDiscoverDiagnostics(e.diagnostics??[]),hooks:[...e.hooks??[]],instructions:[...e.instructions??[]],lib:[...e.lib??[]],kind:AGENT_SOURCE_MANIFEST_KIND,sandbox:e.sandbox??null,sandboxWorkspaces:[...e.sandboxWorkspaces??[]],schedules:[...e.schedules??[]],skills:[...e.skills??[]],tools:[...e.tools??[]],version:12,subagents:[...e.subagents??[]]};return e.configModule!==void 0&&(o.configModule=e.configModule),o}function deriveAgentIdFromRoots(n,r,a){let o=normalizeLogicalPath(relative(n,r));return o===``||o===`.`||o===`agent`?a??basename(n):basename(r)}function createPathDerivedSourceId(e){return normalizeLogicalPath(e)}function createModuleSourceRef(e){let t=normalizeLogicalPath(e.logicalPath),n={sourceKind:`module`,logicalPath:t,sourceId:e.sourceId??createPathDerivedSourceId(t)};return e.exportName!==void 0&&(n.exportName=e.exportName),n}function createConnectionSourceRef(e){return{...createModuleSourceRef(e),connectionName:e.connectionName}}function createLocalSubagentSourceRef(e){let t=normalizeLogicalPath(e.logicalPath);return{entryPath:e.entryPath,logicalPath:t,manifest:e.manifest,rootPath:e.rootPath,sourceId:e.sourceId??createPathDerivedSourceId(t),subagentId:e.subagentId}}function createSkillPackageSourceRef(e){return{assetsPath:e.assetsPath,description:e.description,license:e.license,logicalPath:normalizeLogicalPath(e.logicalPath),markdown:e.markdown,metadata:e.metadata===void 0?void 0:{...e.metadata},name:e.name,referencesPath:e.referencesPath,rootPath:e.rootPath,scriptsPath:e.scriptsPath,skillFilePath:e.skillFilePath,skillId:e.skillId,sourceId:e.sourceId,sourceKind:`skill-package`}}export{AGENT_SOURCE_MANIFEST_KIND,AGENT_SOURCE_MANIFEST_VERSION,createAgentSourceManifest,createConnectionSourceRef,createLocalSubagentSourceRef,createModuleSourceRef,createPathDerivedSourceId,createSkillPackageSourceRef,deriveAgentIdFromRoots};
1
+ import{basename,relative,resolve}from"node:path";import{summarizeDiscoverDiagnostics}from"#discover/diagnostics.js";import{normalizeLogicalPath}from"#discover/filesystem.js";const AGENT_SOURCE_MANIFEST_KIND=`eve-agent-discovery-manifest`,AGENT_SOURCE_MANIFEST_VERSION=12;function createAgentSourceManifest(e){let t=resolve(e.appRoot),i=resolve(e.agentRoot),o={agentId:e.agentId??deriveAgentIdFromRoots(t,i,e.packageName),agentRoot:i,appRoot:t,channels:[...e.channels??[]],connections:[...e.connections??[]],diagnosticsSummary:summarizeDiscoverDiagnostics(e.diagnostics??[]),extensions:[...e.extensions??[]],resolvedExtensions:[...e.resolvedExtensions??[]],hooks:[...e.hooks??[]],instructions:[...e.instructions??[]],lib:[...e.lib??[]],kind:AGENT_SOURCE_MANIFEST_KIND,sandbox:e.sandbox??null,sandboxWorkspaces:[...e.sandboxWorkspaces??[]],schedules:[...e.schedules??[]],skills:[...e.skills??[]],tools:[...e.tools??[]],version:12,subagents:[...e.subagents??[]]};return e.configModule!==void 0&&(o.configModule=e.configModule),o}function deriveAgentIdFromRoots(n,r,a){let o=normalizeLogicalPath(relative(n,r));return o===``||o===`.`||o===`agent`?a??basename(n):basename(r)}function createPathDerivedSourceId(e){return normalizeLogicalPath(e)}function createModuleSourceRef(e){let t=normalizeLogicalPath(e.logicalPath),n={sourceKind:`module`,logicalPath:t,sourceId:e.sourceId??createPathDerivedSourceId(t)};return e.exportName!==void 0&&(n.exportName=e.exportName),n}function createConnectionSourceRef(e){return{...createModuleSourceRef(e),connectionName:e.connectionName}}function createLocalSubagentSourceRef(e){let t=normalizeLogicalPath(e.logicalPath);return{entryPath:e.entryPath,logicalPath:t,manifest:e.manifest,rootPath:e.rootPath,sourceId:e.sourceId??createPathDerivedSourceId(t),subagentId:e.subagentId}}function createSkillPackageSourceRef(e){return{assetsPath:e.assetsPath,description:e.description,license:e.license,logicalPath:normalizeLogicalPath(e.logicalPath),markdown:e.markdown,metadata:e.metadata===void 0?void 0:{...e.metadata},name:e.name,referencesPath:e.referencesPath,rootPath:e.rootPath,scriptsPath:e.scriptsPath,skillFilePath:e.skillFilePath,skillId:e.skillId,sourceId:e.sourceId,sourceKind:`skill-package`}}export{AGENT_SOURCE_MANIFEST_KIND,AGENT_SOURCE_MANIFEST_VERSION,createAgentSourceManifest,createConnectionSourceRef,createLocalSubagentSourceRef,createModuleSourceRef,createPathDerivedSourceId,createSkillPackageSourceRef,deriveAgentIdFromRoots};
@@ -27,7 +27,8 @@ export declare function messageIncludes(token: string | RegExp): RunAssertion;
27
27
  /**
28
28
  * Asserts a completed tool call with `name` happened. Options constrain the
29
29
  * call further: `input` partial-deep-matches, `output` matches the result,
30
- * `status` overrides the lifecycle state, and `count` requires an exact count.
30
+ * `status` overrides the lifecycle state, and `count` constrains the number of
31
+ * matches with either an exact number or a predicate.
31
32
  */
32
33
  export declare function calledTool(name: string, options?: EveEvalToolCallMatchOptions): RunAssertion;
33
34
  /**
@@ -68,7 +69,7 @@ export declare function calledSubagent(name: string, options?: EveEvalSubagentCa
68
69
  * stream. `label` names the assertion in reports.
69
70
  */
70
71
  export declare function eventsSatisfy(label: string, predicate: (events: readonly HandleMessageStreamEvent[]) => boolean): RunAssertion;
71
- /** Asserts a typed stream event exists, optionally with an exact count. */
72
+ /** Asserts a typed stream event exists, optionally constraining its count. */
72
73
  export declare function typedEvent(matcher: EveEvalEventMatch): RunAssertion;
73
74
  /** Asserts no typed stream event matches. */
74
75
  export declare function notEvent(matcher: EveEvalEventMatch): RunAssertion;
@@ -1,2 +1,2 @@
1
- import{deepEquals,eventMatches,subagentCallMatches,testRegExp,toolCallMatches}from"#evals/match.js";import{LOAD_SKILL_TOOL_NAME}from"#runtime/skills/fragment-context.js";const PASS={score:1},fail=(e,t)=>({score:0,message:e,metadata:t});function succeeded(){return{name:`succeeded`,evaluate(e){let t=runFailure(e);return t===void 0?e.derived.parked?fail(`run parked on ${e.derived.inputRequests.length} unanswered input request(s)`):PASS:t}}}function parked(){return{name:`parked`,evaluate(e){let t=runFailure(e);return t===void 0?e.derived.parked?PASS:fail(`expected the run to park on HITL input; it ended "${e.status}" with no pending requests`):t}}}function messageIncludes(e){return{name:`messageIncludes(${String(e)})`,evaluate(t){let n=joinCompletedMessages(t.events);return(typeof e==`string`?n.includes(e):testRegExp(e,n))?PASS:fail(`assistant messages did not include ${String(e)}; got: ${truncate(n)}`)}}}function calledTool(e,t={}){return validateCount(t.count),{name:`calledTool(${e})`,evaluate(n){let r=n.derived.toolCalls.filter(t=>t.name===e),a=r.filter(e=>toolCallMatches(e,t));if(t.count===void 0?a.length>0:a.length===t.count)return{score:1,metadata:{matchingCalls:a.length}};let o=r.length>0?`observed ${e} calls: ${r.map(e=>truncate(JSON.stringify(e.input))).join(`, `)}`:`observed tools: [${n.derived.toolCalls.map(e=>e.name).join(`, `)}]`;return fail(`${t.count===void 0?`expected a matching call to "${e}"`:`expected exactly ${t.count} matching call(s), found ${a.length}`}; ${o}`)}}}function loadedSkill(e,t={}){return{...calledTool(LOAD_SKILL_TOOL_NAME,{...t,input:{skill:e}}),name:`loadedSkill(${e})`}}function notCalledTool(e){return{name:`notCalledTool(${e})`,evaluate(t){let n=t.derived.toolCalls.filter(t=>t.name===e).length;return n===0?PASS:fail(`"${e}" was called ${n} time(s)`)}}}function toolOrder(e){return{name:`toolOrder(${e.join(` → `)})`,evaluate(t){let n=requestedTools(t.events).map(e=>e.name),r=missingOrderedName(e,n);return r===void 0?PASS:fail(`missing "${r.name}" after [${e.slice(0,r.cursor).join(`, `)}]; observed request order: [${n.join(`, `)}]`)}}}function usedNoTools(){return{name:`usedNoTools`,evaluate(e){let t=e.derived.toolCallCount;return t===0?PASS:fail(`expected no tool calls, got ${t}`,{toolCallCount:t})}}}function maxToolCalls(e){return validateCount(e),{name:`maxToolCalls(${e})`,evaluate(t){let n=t.derived.toolCallCount;return n<=e?PASS:fail(`expected at most ${e} tool calls, got ${n}`,{maxAllowed:e,toolCallCount:n})}}}function noFailedActions(){return{name:`noFailedActions`,evaluate(e){let t=e.events.filter(e=>e.type===`action.result`&&(e.data.status===`failed`||e.data.result.isError===!0));if(t.length===0)return PASS;let n=t.map(formatFailedActionResult);return fail(`${t.length} failed action(s): ${n.join(`; `)}`,{failedActions:t.map(e=>({callId:e.data.result.callId,error:e.data.error,kind:e.data.result.kind,output:e.data.result.output,status:e.data.status}))})}}}function calledSubagent(e,t={}){return validateCount(t.count),{name:`calledSubagent(${e})`,evaluate(r){let i=r.derived.subagentCalls.filter(t=>t.name===e),a=i.filter(e=>subagentCallMatches(e,t));return(t.count===void 0?a.length>0:a.length===t.count)?{score:1,metadata:{matchingCalls:a.length}}:i.length===0?fail(`subagent "${e}" was never called; observed: [${r.derived.subagentCalls.map(e=>e.name).join(`, `)}]`,{observedSubagentCalls:r.derived.subagentCalls}):fail(`subagent "${e}" was called but ${a.length} call(s) matched the constraints`,{observedSubagentCalls:i})}}}function eventsSatisfy(e,t){return{name:`eventsSatisfy(${e})`,evaluate(n){return t(n.events)?PASS:fail(`event predicate "${e}" did not hold`)}}}function typedEvent(e){return validateCount(e.count),{name:`event(${e.type})`,evaluate(n){let r=n.events.filter(n=>eventMatches(n,e));return(e.count===void 0?r.length>0:r.length===e.count)?{score:1,metadata:{matchingEvents:r.length}}:fail(`expected ${e.count===void 0?`at least one`:`exactly ${e.count}`} matching ${e.type} event(s), found ${r.length}; observed: [${n.events.map(e=>e.type).join(`, `)}]`)}}}function notEvent(e){return{name:`notEvent(${e.type})`,evaluate(n){let r=n.events.filter(n=>eventMatches(n,e));return r.length===0?PASS:fail(`expected no matching ${e.type} events, found ${r.length}`)}}}function eventOrder(e){for(let t of e)validateCount(t.count);return{name:`eventOrder(${e.map(e=>e.type).join(` → `)})`,evaluate(n){let r=-1;for(let i of e){let e=n.events.flatMap((e,n)=>eventMatches(e,i)?[n]:[]);if(!(i.count===void 0?e.length>0:e.length===i.count))return fail(`expected ${i.count===void 0?`at least one`:`exactly ${i.count}`} matching ${i.type} event(s), found ${e.length}`);let a=e[0];if(a===void 0||a<=r)return fail(`event group ${i.type} did not occur after the previous group`);r=e[e.length-1]??r}return PASS}}}function outputEquals(t){return{name:`outputEquals`,evaluate(n){return deepEquals(n.output,t)?PASS:fail(`output ${truncate(JSON.stringify(n.output))} does not equal expected ${truncate(JSON.stringify(t))}`)}}}function outputMatches(e){return{name:`outputMatches`,async evaluate(t){let n=await e[`~standard`].validate(t.output);return!(`issues`in n)||n.issues===void 0?PASS:fail(`output failed schema validation: ${n.issues.map(e=>e.message).join(`; `)}`)}}}function joinCompletedMessages(e){let t=[];for(let n of e)n.type===`message.completed`&&n.data.message!==null&&t.push(n.data.message);return t.join(`
2
- `)}function failureDetail(e,t){return t===void 0?e:`${e} (code: ${t})`}function formatFailedActionResult(e){let{result:t,status:n}=e.data;return[actionResultLabel(t),`callId=${t.callId}`,`status=${n}`,t.isError===!0?`isError=true`:void 0,e.data.error?.message===void 0?void 0:`error=${e.data.error.message}`,`output=${truncate(formatUnknown(t.output))}`].filter(e=>e!==void 0).join(` `)}function actionResultLabel(e){switch(e.kind){case`tool-result`:return`tool-result:${e.toolName}`;case`subagent-result`:return`subagent-result:${e.subagentName}`;case`load-skill-result`:return e.name===void 0?`load-skill-result`:`load-skill-result:${e.name}`}}function runFailure(e){if(e.status===`failed`)return fail(failureDetail(`run failed`,e.derived.failureCode));let t=e.events.find(e=>e.type===`turn.failed`||e.type===`step.failed`);return t===void 0?void 0:fail(`${t.type} (${t.data.code}): ${t.data.message}`)}function truncate(e,t=200){return e===void 0?`undefined`:e.length<=t?e:`${e.slice(0,t)}…`}function formatUnknown(e){if(e!==void 0){if(typeof e==`string`)return e;try{return JSON.stringify(e)}catch{return String(e)}}}function validateCount(e){if(e!==void 0&&(!Number.isInteger(e)||e<0))throw TypeError(`Assertion count must be a non-negative integer; received ${e}.`)}function missingOrderedName(e,t){let n=0;for(let r of t)if(r===e[n]&&(n+=1),n===e.length)return;let r=e[n];return r===void 0?void 0:{cursor:n,name:r}}function requestedTools(e){let t=[],n=new Set,append=(e,r)=>{n.has(e)||(n.add(e),t.push({callId:e,name:r}))};for(let t of e)if(t.type===`actions.requested`)for(let e of t.data.actions)e.kind===`tool-call`&&append(e.callId,e.toolName);else if(t.type===`input.requested`)for(let e of t.data.requests){let{action:t}=e;t.kind===`tool-call`&&append(t.callId,t.toolName)}return t}export{calledSubagent,calledTool,eventOrder,eventsSatisfy,loadedSkill,maxToolCalls,messageIncludes,noFailedActions,notCalledTool,notEvent,outputEquals,outputMatches,parked,succeeded,toolOrder,typedEvent,usedNoTools};
1
+ import{deepEquals,eventMatches,subagentCallMatches,testRegExp,toolCallMatches}from"#evals/match.js";import{LOAD_SKILL_TOOL_NAME}from"#runtime/skills/fragment-context.js";const PASS={score:1},fail=(e,t)=>({score:0,message:e,metadata:t});function succeeded(){return{name:`succeeded`,evaluate(e){let t=runFailure(e);return t===void 0?e.derived.parked?fail(`run parked on ${e.derived.inputRequests.length} unanswered input request(s)`):PASS:t}}}function parked(){return{name:`parked`,evaluate(e){let t=runFailure(e);return t===void 0?e.derived.parked?PASS:fail(`expected the run to park on HITL input; it ended "${e.status}" with no pending requests`):t}}}function messageIncludes(e){return{name:`messageIncludes(${String(e)})`,evaluate(t){let n=joinCompletedMessages(t.events);return(typeof e==`string`?n.includes(e):testRegExp(e,n))?PASS:fail(`assistant messages did not include ${String(e)}; got: ${truncate(n)}`)}}}function calledTool(e,t={}){return validateCount(t.count),{name:`calledTool(${e})`,evaluate(n){let r=n.derived.toolCalls.filter(t=>t.name===e),a=r.filter(e=>toolCallMatches(e,t));if(matchesCount(t.count,a.length))return{score:1,metadata:{matchingCalls:a.length}};let o=r.length>0?`observed ${e} calls: ${r.map(e=>truncate(JSON.stringify(e.input))).join(`, `)}`:`observed tools: [${n.derived.toolCalls.map(e=>e.name).join(`, `)}]`,s;return s=t.count===void 0?`expected a matching call to "${e}"`:typeof t.count==`number`?`expected exactly ${t.count} matching call(s), found ${a.length}`:`expected matching call count to satisfy the count predicate, found ${a.length}`,fail(`${s}; ${o}`)}}}function loadedSkill(e,t={}){return{...calledTool(LOAD_SKILL_TOOL_NAME,{...t,input:{skill:e}}),name:`loadedSkill(${e})`}}function notCalledTool(e){return{name:`notCalledTool(${e})`,evaluate(t){let n=t.derived.toolCalls.filter(t=>t.name===e).length;return n===0?PASS:fail(`"${e}" was called ${n} time(s)`)}}}function toolOrder(e){return{name:`toolOrder(${e.join(` → `)})`,evaluate(t){let n=requestedTools(t.events).map(e=>e.name),r=missingOrderedName(e,n);return r===void 0?PASS:fail(`missing "${r.name}" after [${e.slice(0,r.cursor).join(`, `)}]; observed request order: [${n.join(`, `)}]`)}}}function usedNoTools(){return{name:`usedNoTools`,evaluate(e){let t=e.derived.toolCallCount;return t===0?PASS:fail(`expected no tool calls, got ${t}`,{toolCallCount:t})}}}function maxToolCalls(e){return validateCount(e),{name:`maxToolCalls(${e})`,evaluate(t){let n=t.derived.toolCallCount;return n<=e?PASS:fail(`expected at most ${e} tool calls, got ${n}`,{maxAllowed:e,toolCallCount:n})}}}function noFailedActions(){return{name:`noFailedActions`,evaluate(e){let t=e.events.filter(e=>e.type===`action.result`&&(e.data.status===`failed`||e.data.result.isError===!0));if(t.length===0)return PASS;let n=t.map(formatFailedActionResult);return fail(`${t.length} failed action(s): ${n.join(`; `)}`,{failedActions:t.map(e=>({callId:e.data.result.callId,error:e.data.error,kind:e.data.result.kind,output:e.data.result.output,status:e.data.status}))})}}}function calledSubagent(e,t={}){return validateCount(t.count),{name:`calledSubagent(${e})`,evaluate(r){let i=r.derived.subagentCalls.filter(t=>t.name===e),a=i.filter(e=>subagentCallMatches(e,t));return matchesCount(t.count,a.length)?{score:1,metadata:{matchingCalls:a.length}}:i.length===0?fail(`subagent "${e}" was never called; observed: [${r.derived.subagentCalls.map(e=>e.name).join(`, `)}]`,{observedSubagentCalls:r.derived.subagentCalls}):fail(`subagent "${e}" was called but ${a.length} call(s) matched the constraints`,{observedSubagentCalls:i})}}}function eventsSatisfy(e,t){return{name:`eventsSatisfy(${e})`,evaluate(n){return t(n.events)?PASS:fail(`event predicate "${e}" did not hold`)}}}function typedEvent(e){return validateCount(e.count),{name:`event(${e.type})`,evaluate(n){let r=n.events.filter(n=>eventMatches(n,e));return matchesCount(e.count,r.length)?{score:1,metadata:{matchingEvents:r.length}}:fail(`expected ${describeCount(e.count)} matching ${e.type} event(s), found ${r.length}; observed: [${n.events.map(e=>e.type).join(`, `)}]`)}}}function notEvent(e){return{name:`notEvent(${e.type})`,evaluate(n){let r=n.events.filter(n=>eventMatches(n,e));return r.length===0?PASS:fail(`expected no matching ${e.type} events, found ${r.length}`)}}}function eventOrder(e){for(let t of e)validateCount(t.count);return{name:`eventOrder(${e.map(e=>e.type).join(` → `)})`,evaluate(n){let r=-1;for(let i of e){let e=n.events.flatMap((e,n)=>eventMatches(e,i)?[n]:[]);if(!matchesCount(i.count,e.length))return fail(`expected ${describeCount(i.count)} matching ${i.type} event(s), found ${e.length}`);let a=e[0];if(a===void 0||a<=r)return fail(`event group ${i.type} did not occur after the previous group`);r=e[e.length-1]??r}return PASS}}}function outputEquals(t){return{name:`outputEquals`,evaluate(n){return deepEquals(n.output,t)?PASS:fail(`output ${truncate(JSON.stringify(n.output))} does not equal expected ${truncate(JSON.stringify(t))}`)}}}function outputMatches(e){return{name:`outputMatches`,async evaluate(t){let n=await e[`~standard`].validate(t.output);return!(`issues`in n)||n.issues===void 0?PASS:fail(`output failed schema validation: ${n.issues.map(e=>e.message).join(`; `)}`)}}}function joinCompletedMessages(e){let t=[];for(let n of e)n.type===`message.completed`&&n.data.message!==null&&t.push(n.data.message);return t.join(`
2
+ `)}function failureDetail(e,t){return t===void 0?e:`${e} (code: ${t})`}function formatFailedActionResult(e){let{result:t,status:n}=e.data;return[actionResultLabel(t),`callId=${t.callId}`,`status=${n}`,t.isError===!0?`isError=true`:void 0,e.data.error?.message===void 0?void 0:`error=${e.data.error.message}`,`output=${truncate(formatUnknown(t.output))}`].filter(e=>e!==void 0).join(` `)}function actionResultLabel(e){switch(e.kind){case`tool-result`:return`tool-result:${e.toolName}`;case`subagent-result`:return`subagent-result:${e.subagentName}`;case`load-skill-result`:return e.name===void 0?`load-skill-result`:`load-skill-result:${e.name}`}}function runFailure(e){if(e.status===`failed`)return fail(failureDetail(`run failed`,e.derived.failureCode));let t=e.events.find(e=>e.type===`turn.failed`||e.type===`step.failed`);return t===void 0?void 0:fail(`${t.type} (${t.data.code}): ${t.data.message}`)}function truncate(e,t=200){return e===void 0?`undefined`:e.length<=t?e:`${e.slice(0,t)}…`}function formatUnknown(e){if(e!==void 0){if(typeof e==`string`)return e;try{return JSON.stringify(e)}catch{return String(e)}}}function matchesCount(e,t){return e===void 0?t>0:typeof e==`function`?e(t):t===e}function describeCount(e){return e===void 0?`at least one`:typeof e==`function`?`a count satisfying the predicate`:`exactly ${e}`}function validateCount(e){if(!(e===void 0||typeof e==`function`)&&(typeof e!=`number`||!Number.isInteger(e)||e<0))throw TypeError(`Assertion count must be a non-negative integer or predicate; received ${String(e)}.`)}function missingOrderedName(e,t){let n=0;for(let r of t)if(r===e[n]&&(n+=1),n===e.length)return;let r=e[n];return r===void 0?void 0:{cursor:n,name:r}}function requestedTools(e){let t=[],n=new Set,append=(e,r)=>{n.has(e)||(n.add(e),t.push({callId:e,name:r}))};for(let t of e)if(t.type===`actions.requested`)for(let e of t.data.actions)e.kind===`tool-call`&&append(e.callId,e.toolName);else if(t.type===`input.requested`)for(let e of t.data.requests){let{action:t}=e;t.kind===`tool-call`&&append(t.callId,t.toolName)}return t}export{calledSubagent,calledTool,eventOrder,eventsSatisfy,loadedSkill,maxToolCalls,messageIncludes,noFailedActions,notCalledTool,notEvent,outputEquals,outputMatches,parked,succeeded,toolOrder,typedEvent,usedNoTools};
@@ -4,6 +4,6 @@ export { EveEvalTurnFailedError } from "#evals/session.js";
4
4
  export { mockModel } from "#evals/mock-model.js";
5
5
  export type { RuntimeIdentity } from "#protocol/message.js";
6
6
  export type { InputRequest } from "#runtime/input/types.js";
7
- export type { EveEvalEventMatch, EveEvalInputRequestMatchOptions, EveEvalValueMatcher, EveEvalToolCallMatchOptions, EveEvalSkillLoadMatchOptions, EveEvalSubagentCallMatchOptions, } from "#evals/match.js";
7
+ export type { EveEvalCountMatcher, EveEvalEventMatch, EveEvalInputRequestMatchOptions, EveEvalValueMatcher, EveEvalToolCallMatchOptions, EveEvalSkillLoadMatchOptions, EveEvalSubagentCallMatchOptions, } from "#evals/match.js";
8
8
  export type { Assertion, AssertionHandle, AssertionResult, AssertionSeverity, AutoevalsJudges, EveEvalActionStatus, EveEvalAssertions, EveEvalContext, EveEvalDerivedFacts, EveEvalJudgeConfig, EveEvalRunSummary, EveEvalSession, EveEvalSessionResult, EveEvalScheduleDispatchResult, EveEvalSubagentCall, EveEval, EveEvalConfig, EveEvalConfigInput, EveEvalDefinition, EveEvalInput, EveEvalResult, EveEvalTarget, EveEvalTargetCapabilities, EveEvalTargetHandle, EveEvalTaskResult, EveEvalToolCall, EveEvalTurn, EveEvalVerdict, JudgeContext, JudgeOpts, } from "#evals/types.js";
9
9
  export type { MockModelMessage, MockModelOptions, MockModelRequest, MockModelResponder, MockModelResponse, MockModelTool, MockModelToolCall, MockModelToolResult, MockModelUsage, } from "#evals/mock-model.js";
@@ -1 +1 @@
1
- import{isAbsolute,resolve}from"node:path";import{readFile}from"node:fs/promises";import matter from"#compiled/gray-matter/index.js";async function loadYaml(e){let t=await readFile(isAbsolute(e)?e:resolve(process.cwd(),e),`utf-8`);return matter(t.trimStart().startsWith(`---`)?t:`---\n${t}\n---`).data??{}}export{loadYaml};
1
+ import{isAbsolute,resolve}from"node:path";import{readFile}from"node:fs/promises";import{parseFrontmatter}from"#internal/helpers/gray-matter.js";async function loadYaml(e){let t=await readFile(isAbsolute(e)?e:resolve(process.cwd(),e),`utf-8`);return parseFrontmatter(t.trimStart().startsWith(`---`)?t:`---\n${t}\n---`).data}export{loadYaml};