(
selectedAgents: LocalAgentInfo[],
allAgents: LocalAgentInfo[],
agentDefinitions: Map<string, { spawnableAgents?: string[] }>,
includeDependents: boolean = false,
)
| 418 | |
| 419 | // Export helper to get all agent IDs for publishing (recursive) |
| 420 | export function getAllPublishAgentIds( |
| 421 | selectedAgents: LocalAgentInfo[], |
| 422 | allAgents: LocalAgentInfo[], |
| 423 | agentDefinitions: Map<string, { spawnableAgents?: string[] }>, |
| 424 | includeDependents: boolean = false, |
| 425 | ): string[] { |
| 426 | // Defensively filter out bundled agents to ensure they're never published |
| 427 | const publishableAgents = allAgents.filter((a) => !a.isBundled) |
| 428 | const publishableSelectedAgents = selectedAgents.filter((a) => !a.isBundled) |
| 429 | const localAgentIds = new Set(publishableAgents.map((a) => a.id)) |
| 430 | |
| 431 | const selectedIds = new Set(publishableSelectedAgents.map((a) => a.id)) |
| 432 | const result = new Set<string>(selectedIds) |
| 433 | |
| 434 | // Collect dependencies (agents the selected agents spawn) |
| 435 | function collectDependencies(agentId: string) { |
| 436 | if (!localAgentIds.has(agentId)) return |
| 437 | |
| 438 | const definition = agentDefinitions.get(agentId) |
| 439 | const spawnableAgents = definition?.spawnableAgents ?? [] |
| 440 | |
| 441 | for (const spawnableId of spawnableAgents) { |
| 442 | const simpleId = getSimpleAgentId(spawnableId) |
| 443 | if (localAgentIds.has(simpleId) && !result.has(simpleId)) { |
| 444 | result.add(simpleId) |
| 445 | collectDependencies(simpleId) |
| 446 | } |
| 447 | } |
| 448 | } |
| 449 | |
| 450 | for (const agent of publishableSelectedAgents) { |
| 451 | collectDependencies(agent.id) |
| 452 | } |
| 453 | |
| 454 | // Optionally collect dependents (agents that spawn the selected/dependency agents) |
| 455 | if (includeDependents) { |
| 456 | // Build a reverse lookup of child -> parent agents for publishable agents |
| 457 | const parentMap = new Map<string, string[]>() |
| 458 | |
| 459 | for (const [agentId, definition] of agentDefinitions) { |
| 460 | if (!localAgentIds.has(agentId)) continue |
| 461 | |
| 462 | const spawnableAgents = definition.spawnableAgents ?? [] |
| 463 | for (const spawnableId of spawnableAgents) { |
| 464 | const simpleId = getSimpleAgentId(spawnableId) |
| 465 | if (!localAgentIds.has(simpleId)) continue |
| 466 | |
| 467 | const parents = parentMap.get(simpleId) |
| 468 | if (parents) { |
| 469 | parents.push(agentId) |
| 470 | } else { |
| 471 | parentMap.set(simpleId, [agentId]) |
| 472 | } |
| 473 | } |
| 474 | } |
| 475 | |
| 476 | // Walk upward from the currently included agents to gather all ancestors |
| 477 | const stack = Array.from(result) |
no test coverage detected