11interface ParsedAgentId {
22 publisher : string
33 agentId : string
4- version : string | null
4+ version : string
55}
66
77export interface AgentTreeNode {
@@ -12,7 +12,7 @@ export interface AgentTreeNode {
1212 /** Publisher ID */
1313 publisher : string
1414 /** Version string */
15- version : string | null
15+ version : string
1616 /** Human-readable display name */
1717 displayName : string
1818 /** Description of when/why to spawn this agent */
@@ -48,50 +48,30 @@ function sanitizeIdForMermaid(id: string): string {
4848}
4949
5050/** Parse agent ID string (e.g. "publisher/agentId@version") */
51- function parseAgentId (
52- agentIdString : string ,
53- defaultPublisher ?: string ,
54- ) : ParsedAgentId {
55- // Fully qualified: publisher/agentId@version
51+ function parseAgentId ( agentIdString : string ) : ParsedAgentId {
5652 const fqMatch = agentIdString . match ( / ^ ( [ ^ / ] + ) \/ ( .+ ) @ ( .+ ) $ / )
57- if ( fqMatch ) {
58- return {
59- publisher : fqMatch [ 1 ] ! ,
60- agentId : fqMatch [ 2 ] ! ,
61- version : fqMatch [ 3 ] ! ,
62- }
63- }
64-
65- // With publisher but no version: publisher/agentId
66- const publisherMatch = agentIdString . match ( / ^ ( [ ^ / ] + ) \/ ( .+ ) $ / )
67- if ( publisherMatch ) {
68- return {
69- publisher : publisherMatch [ 1 ] ! ,
70- agentId : publisherMatch [ 2 ] ! ,
71- version : null ,
72- }
53+ if ( ! fqMatch ) {
54+ throw new Error (
55+ `Invalid agent reference '${ agentIdString } '. Expected 'publisher/agentId@version'.` ,
56+ )
7357 }
7458
75- // Simple ID: agentId
7659 return {
77- publisher : defaultPublisher ?? 'unknown' ,
78- agentId : agentIdString ,
79- version : null ,
60+ publisher : fqMatch [ 1 ] ! ,
61+ agentId : fqMatch [ 2 ] ! ,
62+ version : fqMatch [ 3 ] ! ,
8063 }
8164}
8265
8366function formatAgentId ( parsed : ParsedAgentId ) : string {
84- if ( parsed . version ) {
85- return `${ parsed . publisher } /${ parsed . agentId } @${ parsed . version } `
86- }
87- return `${ parsed . publisher } /${ parsed . agentId } `
67+ return `${ parsed . publisher } /${ parsed . agentId } @${ parsed . version } `
8868}
8969
9070interface BuildTreeContext {
9171 lookupAgent : (
9272 publisher : string ,
9373 agentId : string ,
94- version : string | null ,
74+ version : string ,
9575 ) => Promise < AgentLookupResult | null >
9676 visitedIds : Set < string >
9777 currentDepth : number
@@ -100,10 +80,9 @@ interface BuildTreeContext {
10080
10181async function buildTreeNodeRecursive (
10282 agentIdString : string ,
103- defaultPublisher : string ,
10483 ctx : BuildTreeContext ,
10584) : Promise < AgentTreeNode > {
106- const parsed = parseAgentId ( agentIdString , defaultPublisher )
85+ const parsed = parseAgentId ( agentIdString )
10786 const fullId = formatAgentId ( parsed )
10887
10988 // Check for cycles
@@ -146,7 +125,7 @@ async function buildTreeNodeRecursive(
146125 // Recursively build children if we haven't hit max depth
147126 if ( agentData && ctx . currentDepth < ctx . maxDepth ) {
148127 const childPromises = agentData . spawnableAgents . map ( ( childId ) =>
149- buildTreeNodeRecursive ( childId , parsed . publisher , {
128+ buildTreeNodeRecursive ( childId , {
150129 ...ctx ,
151130 currentDepth : ctx . currentDepth + 1 ,
152131 visitedIds : new Set ( ctx . visitedIds ) , // Clone for each branch
@@ -168,7 +147,7 @@ export async function buildAgentTree(params: {
168147 lookupAgent : (
169148 publisher : string ,
170149 agentId : string ,
171- version : string | null ,
150+ version : string ,
172151 ) => Promise < AgentLookupResult | null >
173152 maxDepth ?: number
174153} ) : Promise < AgentTreeData > {
@@ -188,7 +167,7 @@ export async function buildAgentTree(params: {
188167
189168 // Build children
190169 const childPromises = rootSpawnableAgents . map ( ( childId ) =>
191- buildTreeNodeRecursive ( childId , rootPublisher , {
170+ buildTreeNodeRecursive ( childId , {
192171 lookupAgent,
193172 visitedIds : new Set ( visitedIds ) ,
194173 currentDepth : 1 ,
@@ -256,15 +235,15 @@ export function generateMermaidDiagram(tree: AgentTreeData): string {
256235
257236 function getNodeLabel ( node : AgentTreeNode ) : string {
258237 const name = node . displayName
259- const version = node . version ? `v${ node . version } ` : ''
238+ const version = `v${ node . version } `
260239 // Escape special characters for Mermaid to prevent XSS
261240 const escapedName = name
262241 . replace ( / " / g, "'" )
263242 . replace ( / < / g, '<' )
264243 . replace ( / > / g, '>' )
265244 . replace ( / & (? ! l t ; | g t ; | a m p ; ) / g, '&' )
266245 const escapedVersion = version . replace ( / < / g, '<' ) . replace ( / > / g, '>' )
267- return escapedVersion ? `"${ escapedName } <br/>${ escapedVersion } "` : `" ${ escapedName } "`
246+ return `"${ escapedName } <br/>${ escapedVersion } "`
268247 }
269248
270249 function traverse ( node : AgentTreeNode , parentSanitizedId : string | null ) {
@@ -315,7 +294,7 @@ export interface NodeData {
315294 fullId : string
316295 agentId : string
317296 publisher : string
318- version : string | null
297+ version : string
319298 displayName : string
320299 spawnerPrompt : string | null
321300 isAvailable : boolean
0 commit comments