Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); const node_fs = require('node:fs'); const moduleShape = require('./moduleShape.js'); const AGENT_BASE_CLASSES = { agents: /* @__PURE__ */ new Set(["Agent"]), "agents/mcp": /* @__PURE__ */ new Set(["McpAgent"]), "@cloudflare/ai-chat": /* @__PURE__ */ new Set(["AIChatAgent"]), "@cloudflare/think": /* @__PURE__ */ new Set(["Think"]) }; const MAX_DEPTH = 8; async function detectAgentClasses(ast, entryId, candidates, resolver) { const ctx = { resolver, modules: /* @__PURE__ */ new Map([[entryId, moduleShape.shapeFromAst(ast)]]) }; const detected = /* @__PURE__ */ new Set(); for (const name of candidates) { if (await isAgentBinding(ctx, entryId, name, 0, /* @__PURE__ */ new Set())) { detected.add(name); } } return detected; } function collectAgentCandidates(ast, configuredNames) { const shape = moduleShape.shapeFromAst(ast); const candidates = /* @__PURE__ */ new Set(); const isResolvable = (name) => shape.classes.has(name) || shape.imports.has(name) || shape.reexports.has(name); for (const configured of configuredNames) { if (isResolvable(configured)) { candidates.add(configured); } const local = shape.localExports.get(configured); if (local && isResolvable(local)) { candidates.add(local); } } return candidates; } async function isAgentBinding(ctx, moduleId, name, depth, visited) { if (depth > MAX_DEPTH) return false; const key = `${moduleId} ${name}`; if (visited.has(key)) return false; visited.add(key); const shape = await getModuleShape(ctx, moduleId); if (!shape) return false; if (shape.classes.has(name)) { return extendsAgent(ctx, shape, moduleId, shape.classes.get(name), depth, visited); } const imported = shape.imports.get(name); if (imported) { return followImport(ctx, moduleId, imported.source, imported.imported, depth, visited); } if (name === moduleShape.DEFAULT_EXPORT) { if (shape.defaultExportIsClass) { return extendsAgent(ctx, shape, moduleId, shape.defaultExportSuper, depth, visited); } if (shape.defaultExportName) { return isAgentBinding(ctx, moduleId, shape.defaultExportName, depth + 1, visited); } } const localName = shape.localExports.get(name); if (localName) { return isAgentBinding(ctx, moduleId, localName, depth + 1, visited); } const reexport = shape.reexports.get(name); if (reexport) { return followImport(ctx, moduleId, reexport.source, reexport.imported, depth, visited); } for (const source of shape.starExports) { if (await followImport(ctx, moduleId, source, name, depth, visited)) { return true; } } return false; } async function extendsAgent(ctx, shape, moduleId, superClass, depth, visited) { if (!superClass) return false; if (superClass.kind === "identifier") { return isAgentBinding(ctx, moduleId, superClass.name, depth + 1, visited); } const source = shape.namespaces.get(superClass.object); if (source) { return followImport(ctx, moduleId, source, superClass.property, depth, visited); } return false; } async function followImport(ctx, importerId, source, importedName, depth, visited) { if (AGENT_BASE_CLASSES[source]?.has(importedName)) return true; if (!ctx.resolver.resolve) return false; let resolved; try { resolved = await ctx.resolver.resolve(source, importerId); } catch { return false; } if (!resolved?.id) return false; if (resolved.id.includes("/node_modules/") || resolved.id.includes("\\node_modules\\")) return false; return isAgentBinding(ctx, resolved.id, importedName, depth + 1, visited); } async function getModuleShape(ctx, moduleId) { if (ctx.modules.has(moduleId)) return ctx.modules.get(moduleId); let shape; try { const code = ctx.resolver.readFile ? ctx.resolver.readFile(moduleId) : node_fs.readFileSync(moduleId.replace(/[?#].*$/, ""), "utf8"); if (typeof code === "string") { shape = moduleShape.shapeFromSource(code); } } catch { } ctx.modules.set(moduleId, shape); return shape; } exports.collectAgentCandidates = collectAgentCandidates; exports.detectAgentClasses = detectAgentClasses; //# sourceMappingURL=agentClass.js.map