agents-inc 0.171.0 → 0.172.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/dist/{chunk-WM2N2D6Q.js → chunk-255DGUCH.js} +2 -2
  3. package/dist/chunk-33JICQD5.js +196 -0
  4. package/dist/chunk-33JICQD5.js.map +1 -0
  5. package/dist/{chunk-ZC6GC66J.js → chunk-3R3LHA4Q.js} +2 -2
  6. package/dist/{chunk-KMOCMVK5.js → chunk-5MGRHS2G.js} +94 -58
  7. package/dist/chunk-5MGRHS2G.js.map +1 -0
  8. package/dist/{chunk-JGPE4RRE.js → chunk-5PPB6HT6.js} +2 -2
  9. package/dist/{chunk-S2SKVJT2.js → chunk-6CRA46YO.js} +14 -14
  10. package/dist/{chunk-TNFYBKVD.js → chunk-6LUTY35Q.js} +25 -14
  11. package/dist/chunk-6LUTY35Q.js.map +1 -0
  12. package/dist/{chunk-24OD7IP4.js → chunk-7OG635DK.js} +26 -4
  13. package/dist/chunk-7OG635DK.js.map +1 -0
  14. package/dist/{chunk-QIR56IDM.js → chunk-7ZOWSCAO.js} +29 -102
  15. package/dist/chunk-7ZOWSCAO.js.map +1 -0
  16. package/dist/{chunk-WDH6HHA3.js → chunk-A3ZAXL5T.js} +4 -5
  17. package/dist/{chunk-WDH6HHA3.js.map → chunk-A3ZAXL5T.js.map} +1 -1
  18. package/dist/chunk-G7NUK3BF.js +253 -0
  19. package/dist/chunk-G7NUK3BF.js.map +1 -0
  20. package/dist/{chunk-7IVLVEHX.js → chunk-KCLBLK3F.js} +3 -3
  21. package/dist/{chunk-AWWCRL5A.js → chunk-LUKDDHSI.js} +8 -6
  22. package/dist/{chunk-AWWCRL5A.js.map → chunk-LUKDDHSI.js.map} +1 -1
  23. package/dist/{chunk-W4KAY26P.js → chunk-MBIOZ5LW.js} +12 -3
  24. package/dist/{chunk-W4KAY26P.js.map → chunk-MBIOZ5LW.js.map} +1 -1
  25. package/dist/{chunk-A6OWEJGC.js → chunk-MHAQWMNJ.js} +35 -5
  26. package/dist/{chunk-A6OWEJGC.js.map → chunk-MHAQWMNJ.js.map} +1 -1
  27. package/dist/{chunk-RDXY4GRO.js → chunk-MOL2J5HS.js} +2 -2
  28. package/dist/{chunk-YLUOGAW7.js → chunk-N33AKFLR.js} +2 -2
  29. package/dist/{chunk-WII6GOPM.js → chunk-NISWBQNS.js} +52 -31
  30. package/dist/chunk-NISWBQNS.js.map +1 -0
  31. package/dist/{chunk-3YYHL76L.js → chunk-VILFCMRN.js} +420 -316
  32. package/dist/chunk-VILFCMRN.js.map +1 -0
  33. package/dist/{chunk-EOKNEGRD.js → chunk-Y23MP2OC.js} +8 -8
  34. package/dist/commands/build/marketplace.js +16 -14
  35. package/dist/commands/build/marketplace.js.map +1 -1
  36. package/dist/commands/build/plugins.js +6 -6
  37. package/dist/commands/compile.js +12 -12
  38. package/dist/commands/doctor.js +64 -81
  39. package/dist/commands/doctor.js.map +1 -1
  40. package/dist/commands/edit.js +150 -152
  41. package/dist/commands/edit.js.map +1 -1
  42. package/dist/commands/eject.js +10 -10
  43. package/dist/commands/init.js +19 -16
  44. package/dist/commands/list.js +14 -17
  45. package/dist/commands/list.js.map +1 -1
  46. package/dist/commands/new/marketplace.js +4 -4
  47. package/dist/commands/search.js +15 -13
  48. package/dist/commands/search.js.map +1 -1
  49. package/dist/commands/share.js +11 -11
  50. package/dist/commands/uninstall.js +109 -98
  51. package/dist/commands/uninstall.js.map +1 -1
  52. package/dist/commands/update.js +6 -6
  53. package/dist/components/common/scroll-affordance.js +2 -2
  54. package/dist/components/common/select-list.js +2 -2
  55. package/dist/components/common/skill-agent-summary.js +3 -4
  56. package/dist/components/common/summary-panel.js +11 -146
  57. package/dist/components/common/summary-panel.js.map +1 -1
  58. package/dist/hooks/init.js +22 -19
  59. package/dist/hooks/init.js.map +1 -1
  60. package/dist/load-agent-defs-54VIKN4T.js +14 -0
  61. package/dist/{recompile-project-agents-IQANWGOP.js → recompile-project-agents-5A44NJRD.js} +8 -8
  62. package/dist/{source-loader-YGG7DY2W.js → source-loader-LQNRI5UZ.js} +4 -4
  63. package/dist/src/agents/tester/web-tester/playbook.md +1 -1
  64. package/package.json +1 -1
  65. package/src/agents/tester/web-tester/playbook.md +1 -1
  66. package/dist/chunk-24OD7IP4.js.map +0 -1
  67. package/dist/chunk-3YYHL76L.js.map +0 -1
  68. package/dist/chunk-4RQKCV6I.js +0 -103
  69. package/dist/chunk-4RQKCV6I.js.map +0 -1
  70. package/dist/chunk-5FM77WKW.js +0 -69
  71. package/dist/chunk-5FM77WKW.js.map +0 -1
  72. package/dist/chunk-KMOCMVK5.js.map +0 -1
  73. package/dist/chunk-QIR56IDM.js.map +0 -1
  74. package/dist/chunk-R572RLTI.js +0 -108
  75. package/dist/chunk-R572RLTI.js.map +0 -1
  76. package/dist/chunk-TNFYBKVD.js.map +0 -1
  77. package/dist/chunk-WII6GOPM.js.map +0 -1
  78. package/dist/components/common/removal-plan-confirm.js +0 -10
  79. package/dist/load-agent-defs-UBWITIEI.js +0 -14
  80. package/dist/source-loader-YGG7DY2W.js.map +0 -1
  81. /package/dist/{chunk-WM2N2D6Q.js.map → chunk-255DGUCH.js.map} +0 -0
  82. /package/dist/{chunk-ZC6GC66J.js.map → chunk-3R3LHA4Q.js.map} +0 -0
  83. /package/dist/{chunk-JGPE4RRE.js.map → chunk-5PPB6HT6.js.map} +0 -0
  84. /package/dist/{chunk-S2SKVJT2.js.map → chunk-6CRA46YO.js.map} +0 -0
  85. /package/dist/{chunk-7IVLVEHX.js.map → chunk-KCLBLK3F.js.map} +0 -0
  86. /package/dist/{chunk-RDXY4GRO.js.map → chunk-MOL2J5HS.js.map} +0 -0
  87. /package/dist/{chunk-YLUOGAW7.js.map → chunk-N33AKFLR.js.map} +0 -0
  88. /package/dist/{chunk-EOKNEGRD.js.map → chunk-Y23MP2OC.js.map} +0 -0
  89. /package/dist/{components/common/removal-plan-confirm.js.map → load-agent-defs-54VIKN4T.js.map} +0 -0
  90. /package/dist/{recompile-project-agents-IQANWGOP.js.map → recompile-project-agents-5A44NJRD.js.map} +0 -0
  91. /package/dist/{load-agent-defs-UBWITIEI.js.map → source-loader-LQNRI5UZ.js.map} +0 -0
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli/lib/agents/list-compiled-agents.ts","../src/cli/lib/agents/agent-recompiler.ts","../src/cli/lib/agents/write-compiled-agents.ts","../src/cli/lib/compiler.ts","../src/cli/lib/agents/agent-provenance.ts"],"sourcesContent":["import path from \"path\";\nimport { partition } from \"remeda\";\nimport { glob, readFileOptional, remove } from \"../../utils/fs\";\nimport { isAgentName } from \"../../utils/type-guards\";\nimport { type AgentCodec, agentCodec } from \"../installation/install-layout\";\nimport type { AgentName } from \"../../types\";\n\n/**\n * The default codec; a caller on another host passes that host's\n * (`agentCodec(providerInUse(dir))`).\n */\nconst CLAUDE_AGENTS = agentCodec(\"claude\");\n\ntype AgentProvenanceSplit = {\n marked: string[];\n unmarked: string[];\n};\n\nexport async function listAgentMdFiles(agentsDir: string): Promise<string[]> {\n return listAgentFilesOf(agentsDir, CLAUDE_AGENTS);\n}\n\nexport async function listAgentFilesOf(agentsDir: string, codec: AgentCodec): Promise<string[]> {\n return glob(codec.listGlob, agentsDir);\n}\n\n/** An unreadable file lands in `unmarked`: \"cannot prove it is ours\" means leave it alone. */\nexport async function splitAgentsByProvenance(\n agentsDir: string,\n codec: AgentCodec = CLAUDE_AGENTS,\n): Promise<AgentProvenanceSplit> {\n const files = await listAgentFilesOf(agentsDir, codec);\n const classified = await Promise.all(\n files.map((file) => readAgentProvenance(agentsDir, file, codec)),\n );\n const [marked, unmarked] = partition(classified, (agent) => agent.compiledHere);\n\n return {\n marked: marked.map((agent) => agent.name),\n unmarked: unmarked.map((agent) => agent.name),\n };\n}\n\ntype ClassifiedAgent = { name: string; compiledHere: boolean };\n\nasync function readAgentProvenance(\n agentsDir: string,\n file: string,\n codec: AgentCodec,\n): Promise<ClassifiedAgent> {\n const content = await readFileOptional(path.join(agentsDir, file));\n return { name: path.basename(file, codec.extension), compiledHere: codec.hasMarker(content) };\n}\n\nexport async function listCompiledAgentNames(agentsDir: string): Promise<AgentName[]> {\n const files = await listAgentMdFiles(agentsDir);\n // Boundary cast: custom marketplace agents may fall outside the AgentName union.\n return files.map((f) => path.basename(f, CLAUDE_AGENTS.extension) as AgentName);\n}\n\n/**\n * Deletes built-in-named agent files not in `keep`, which must be the complete set for `agentsDir`.\n */\nexport async function pruneStaleCompiledAgents(\n agentsDir: string,\n keep: ReadonlySet<AgentName>,\n codec: AgentCodec = CLAUDE_AGENTS,\n): Promise<void> {\n const isStaleCompiledAgent = (file: string): boolean => {\n const name = path.basename(file, codec.extension);\n return isAgentName(name) && !keep.has(name);\n };\n\n const files = await listAgentFilesOf(agentsDir, codec);\n await Promise.all(\n files.filter(isStaleCompiledAgent).map((file) => remove(path.join(agentsDir, file))),\n );\n}\n","import { partition } from \"remeda\";\nimport { writeCompiledAgentsByScope, type AgentWriteOutcome } from \"./write-compiled-agents\";\nimport { listCompiledAgentNames } from \"./list-compiled-agents\";\nimport path from \"path\";\n\nimport { getErrorMessage } from \"../../utils/errors\";\nimport type {\n AgentDefinition,\n AgentName,\n CompileAgentConfig,\n CompileConfig,\n ProjectConfig,\n SkillDefinitionMap,\n SkillId,\n SkillScope,\n} from \"../../types\";\n\nimport { buildCompileAgents } from \"../installation/local-installer\";\nimport { ensureDir } from \"../../utils/fs\";\nimport { verbose } from \"../../utils/logger\";\nimport { typedEntries, typedFromEntries, typedKeys } from \"../../utils/typed-object\";\nimport { createLiquidEngine } from \"../compiler\";\nimport { loadProjectConfig, effectivelyExcludedSkillIds } from \"../configuration\";\nimport { loadAllAgents, loadProjectAgents } from \"../loading\";\nimport { getPluginAgentsDir } from \"../plugins\";\nimport { discoverAllPluginSkills } from \"../plugins/plugin-discovery\";\nimport { resolveAgents } from \"../resolver\";\n\nexport type RecompileAgentsOptions = {\n pluginDir: string;\n sourcePath: string;\n agents?: AgentName[];\n skills?: SkillDefinitionMap;\n projectDir?: string;\n outputDir?: string;\n /** When provided, routes agents by scope: global agents to ~/.claude/agents/, project agents to outputDir */\n agentScopeMap?: Map<AgentName, SkillScope>;\n};\n\nexport type RecompileAgentsResult = {\n compiled: AgentName[];\n /** The subset of `compiled` whose file content moved; the rest count as unchanged. */\n rewritten: AgentName[];\n failed: AgentName[];\n warnings: string[];\n};\n\nasync function getExistingAgentNames(pluginDir: string): Promise<AgentName[]> {\n return listCompiledAgentNames(getPluginAgentsDir(pluginDir));\n}\n\ntype ResolveAgentNamesParams = {\n specifiedAgents?: AgentName[];\n projectConfig: ProjectConfig | null;\n allAgents: Partial<Record<AgentName, AgentDefinition>>;\n outputDir?: string;\n pluginDir: string;\n};\n\nasync function resolveAgentNames(params: ResolveAgentNamesParams): Promise<AgentName[]> {\n const { specifiedAgents, projectConfig, allAgents, outputDir, pluginDir } = params;\n\n if (specifiedAgents) {\n return specifiedAgents;\n }\n\n // A present config is authoritative even when its roster is empty.\n if (projectConfig) {\n const agentNames = projectConfig.agents.map((a) => a.name);\n verbose(`Using agents from config: ${agentNames.join(\", \")}`);\n return agentNames;\n }\n\n if (outputDir) {\n const names = typedKeys<AgentName>(allAgents);\n verbose(`Using all available agents from source: ${names.join(\", \")}`);\n return names;\n }\n\n return getExistingAgentNames(pluginDir);\n}\n\nfunction buildRecompileResult(\n outcomes: AgentWriteOutcome[],\n priorWarnings: string[],\n): RecompileAgentsResult {\n const [succeeded, failedOutcomes] = partition(\n outcomes,\n (outcome): outcome is Extract<AgentWriteOutcome, { ok: true }> => outcome.ok,\n );\n succeeded.forEach((outcome) =>\n verbose(\n ` ${outcome.rewritten ? \"Rewrote\" : \"Unchanged\"}: ${outcome.name} (${outcome.scope} -> ${outcome.targetDir})`,\n ),\n );\n return {\n compiled: succeeded.map((outcome) => outcome.name),\n rewritten: succeeded.filter((outcome) => outcome.rewritten).map((outcome) => outcome.name),\n failed: failedOutcomes.map((outcome) => outcome.name),\n warnings: [\n ...priorWarnings,\n ...failedOutcomes.map(\n (outcome) => `Failed to compile ${outcome.name}: ${getErrorMessage(outcome.error)}`,\n ),\n ],\n };\n}\n\nexport function filterExcludedEntries(config: ProjectConfig): ProjectConfig {\n const excludedIds = effectivelyExcludedSkillIds(config.skills);\n const activeSkills = config.skills.filter((s) => !s.excluded);\n const activeAgents = config.agents.filter((a) => !a.excluded);\n\n // No stack stays absent rather than an explicit `undefined`.\n const filteredStack =\n config.stack === undefined\n ? {}\n : { stack: withoutExcludedAssignments(config.stack, excludedIds) };\n\n return { ...config, skills: activeSkills, agents: activeAgents, ...filteredStack };\n}\n\n/** Each agent and category keeps its key, even when left with no assignments. */\nexport function withoutExcludedAssignments(\n stack: NonNullable<ProjectConfig[\"stack\"]>,\n excludedIds: ReadonlySet<SkillId>,\n): NonNullable<ProjectConfig[\"stack\"]> {\n return Object.fromEntries(\n typedEntries(stack).map(([agentName, agentStack]) => [\n agentName,\n Object.fromEntries(\n typedEntries(agentStack).map(([category, assignments]) => [\n category,\n assignments.filter((assignment) => !excludedIds.has(assignment.id)),\n ]),\n ),\n ]),\n );\n}\n\nexport async function recompileAgents(\n options: RecompileAgentsOptions,\n): Promise<RecompileAgentsResult> {\n const { pluginDir, sourcePath, skills: providedSkills, projectDir, outputDir } = options;\n\n const configDir = projectDir ?? pluginDir;\n const filteredConfig = await loadConfigWithoutExclusions(configDir);\n const allAgents = await loadAgentDefinitions(sourcePath, projectDir);\n\n const agentNames = await resolveAgentNames({\n ...(options.agents !== undefined && { specifiedAgents: options.agents }),\n projectConfig: filteredConfig,\n allAgents,\n ...(outputDir !== undefined && { outputDir }),\n pluginDir,\n });\n\n // An empty pass is not a warning: callers report it off `compiled`.\n if (agentNames.length === 0) {\n return { compiled: [], rewritten: [], failed: [], warnings: [] };\n }\n\n verbose(`Recompiling ${agentNames.length} agents in ${outputDir ?? pluginDir}`);\n\n const pluginSkills: SkillDefinitionMap =\n providedSkills ?? (await discoverAllPluginSkills(projectDir ?? pluginDir));\n\n const { configAgents, missingWarnings } = compileEntriesFor(\n agentNames,\n filteredConfig,\n allAgents,\n );\n const compileConfig = compileConfigFor(filteredConfig, configAgents, pluginDir);\n\n const engine = await createLiquidEngine(projectDir);\n const resolvedAgents = await resolveAgents(allAgents, pluginSkills, compileConfig);\n\n const agentsDir = outputDir ?? getPluginAgentsDir(pluginDir);\n await ensureDir(agentsDir);\n\n const outcomes = await writeCompiledAgentsByScope({\n resolvedAgents,\n sourcePath,\n engine,\n projectAgentsDir: agentsDir,\n // Same root as the config, so format and configuration come from one installation.\n projectDir: configDir,\n ...(options.agentScopeMap !== undefined && { agentScopeMap: options.agentScopeMap }),\n });\n return buildRecompileResult(outcomes, missingWarnings);\n}\n\nasync function loadConfigWithoutExclusions(configDir: string): Promise<ProjectConfig | null> {\n const loaded = await loadProjectConfig(configDir);\n return loaded ? filterExcludedEntries(loaded.config) : null;\n}\n\n/** A project agent wins over a built-in one of the same name. */\nasync function loadAgentDefinitions(\n sourcePath: string,\n projectDir: string | undefined,\n): Promise<Partial<Record<AgentName, AgentDefinition>>> {\n const builtinAgents = await loadAllAgents(sourcePath);\n const projectAgents = projectDir ? await loadProjectAgents(projectDir) : {};\n\n return { ...builtinAgents, ...projectAgents };\n}\n\nfunction compileConfigFor(\n config: ProjectConfig | null,\n agents: Partial<Record<AgentName, CompileAgentConfig>>,\n pluginDir: string,\n): CompileConfig {\n return {\n name: config?.name || path.basename(pluginDir),\n description: config?.description || \"Recompiled plugin\",\n agents,\n };\n}\n\n/** Only agents the scope filter matches: a project pass must not overwrite stackless globals. */\nfunction compileEntriesFor(\n agentNames: AgentName[],\n config: ProjectConfig | null,\n allAgents: Partial<Record<AgentName, AgentDefinition>>,\n): { configAgents: Partial<Record<AgentName, CompileAgentConfig>>; missingWarnings: string[] } {\n const allConfigAgents = config ? buildCompileAgents(config, allAgents) : {};\n\n const [knownAgents, missingAgents] = partition(agentNames, (name) =>\n Boolean(allConfigAgents[name] || allAgents[name]),\n );\n\n return {\n configAgents: typedFromEntries<AgentName, CompileAgentConfig>(\n knownAgents.map((name) => [name, allConfigAgents[name] ?? {}]),\n ),\n missingWarnings: missingAgents.map((name) => `Agent \"${name}\" not found in source definitions`),\n };\n}\n","import os from \"os\";\nimport path from \"path\";\nimport type { Liquid } from \"liquidjs\";\nimport { compileAgentForHost } from \"../compiler.js\";\nimport { resolveInstallPaths } from \"../installation/install-base-dir.js\";\nimport { agentCodec, hostCompilesAgent, providerInUse } from \"../installation/install-layout.js\";\nimport { writeFile, fileExists, readFile } from \"../../utils/fs.js\";\nimport { typedEntries } from \"../../utils/typed-object.js\";\nimport type { Provider } from \"../../consts.js\";\nimport type { AgentConfig, AgentName, SkillScope } from \"../../types/index.js\";\n\nexport type AgentWriteOutcome =\n | {\n name: AgentName;\n ok: true;\n scope: SkillScope;\n targetDir: string;\n /** False when the output matched the file on disk, so nothing was written. */\n rewritten: boolean;\n }\n | { name: AgentName; ok: false; error: unknown };\n\n/** Skipping an identical write keeps the mtime, the only trace telling unchanged from rewritten. */\nasync function holdsExactly(filePath: string, content: string): Promise<boolean> {\n return (await fileExists(filePath)) && (await readFile(filePath)) === content;\n}\n\n/**\n * Routing for an agent the scope map does not name: the caller's `projectAgentsDir`. Deliberately\n * not the selection default, which would move unrouted agents into `~/.claude/agents`.\n */\nconst UNROUTED_AGENT_SCOPE: SkillScope = \"project\";\n\n/**\n * Per-agent failures come back as outcomes; a directory appears only when an agent routes into it.\n */\nexport async function writeCompiledAgentsByScope(params: {\n resolvedAgents: Partial<Record<AgentName, AgentConfig>>;\n sourcePath: string;\n engine: Liquid;\n projectAgentsDir: string;\n /** The root whose folder says which host the PROJECT scope's sub-agents are written for. */\n projectDir: string;\n agentScopeMap?: Map<AgentName, SkillScope>;\n}): Promise<AgentWriteOutcome[]> {\n const hosts: Record<SkillScope, AgentHost> = {\n // Each scope reads its own root: a Codex project under a Claude global is allowed.\n global: {\n provider: providerInUse(os.homedir()),\n agentsDir: resolveInstallPaths(os.homedir(), \"global\").agentsDir,\n },\n project: { provider: providerInUse(params.projectDir), agentsDir: params.projectAgentsDir },\n };\n\n const outcomes: AgentWriteOutcome[] = [];\n for (const [name, agent] of typedEntries<AgentName, AgentConfig>(params.resolvedAgents)) {\n const scope = params.agentScopeMap?.get(name) ?? UNROUTED_AGENT_SCOPE;\n const host = hosts[scope];\n\n // No outcome for a sub-agent this host does not carry: it was neither compiled nor failed.\n if (!hostCompilesAgent(host.provider, name)) continue;\n\n outcomes.push(await writeOneAgent({ ...params, name, agent, scope, host }));\n }\n return outcomes;\n}\n\n/** Returns the failure rather than throwing: the policy is the caller's. */\nasync function writeOneAgent(params: {\n name: AgentName;\n agent: AgentConfig;\n scope: SkillScope;\n host: AgentHost;\n sourcePath: string;\n engine: Liquid;\n}): Promise<AgentWriteOutcome> {\n const { name, scope, host } = params;\n\n try {\n const output = await compileAgentForHost(\n host.provider,\n name,\n params.agent,\n params.sourcePath,\n params.engine,\n );\n const targetPath = path.join(host.agentsDir, fileNameFor(name, host.provider));\n const rewritten = !(await holdsExactly(targetPath, output));\n if (rewritten) await writeFile(targetPath, output);\n\n return { name, ok: true, scope, targetDir: host.agentsDir, rewritten };\n } catch (error) {\n return { name, ok: false, error };\n }\n}\n\ntype AgentHost = { provider: Provider; agentsDir: string };\n\n/** The extension comes from `agentCodec`, so a `.md` never lands where Codex reads `.toml`. */\nfunction fileNameFor(name: AgentName, provider: Provider): string {\n return `${name}${agentCodec(provider).extension}`;\n}\n","import { Liquid } from \"liquidjs\";\nimport path from \"path\";\nimport {\n buildAgentTemplateContext,\n pluginRefFor,\n renderAgent,\n renderAgentBody,\n renderAgentRoleToml,\n type AgentFiles,\n} from \"@workspace/compile/agent-source\";\nimport { readFile, readFileOptional, directoryExists } from \"../utils/fs\";\nimport { verbose } from \"../utils/logger\";\nimport {\n CLAUDE_DIR,\n DIRS,\n PROJECT_ROOT,\n STANDARD_FILES,\n STANDARD_DIRS,\n type Provider,\n} from \"../consts\";\nimport { providerInUse, sourceFolderInUse, sourceFolderName } from \"./installation/install-layout\";\nimport { cliVersion } from \"./agents/agent-provenance\";\nimport \"./compile-seat.js\";\nimport type { AgentConfig, AgentName } from \"../types\";\n\nexport {\n buildAgentTemplateContext,\n sanitizeCompiledAgentData,\n sanitizeLiquidSyntax,\n} from \"@workspace/compile/agent-source\";\n\nasync function readAgentFiles(\n name: AgentName,\n agent: AgentConfig,\n projectRoot: string,\n): Promise<AgentFiles> {\n const agentSourceRoot = agent.sourceRoot || projectRoot;\n const agentBaseDir = agent.agentBaseDir || DIRS.agents;\n const agentPath = agent.path || name;\n const agentDir = path.join(agentSourceRoot, agentBaseDir, agentPath);\n\n const identity = await readFile(path.join(agentDir, STANDARD_FILES.IDENTITY_MD));\n const playbook = await readFile(path.join(agentDir, STANDARD_FILES.PLAYBOOK_MD));\n const criticalRequirementsTop = await readFileOptional(\n path.join(agentDir, STANDARD_FILES.CRITICAL_REQUIREMENTS_MD),\n \"\",\n );\n const criticalReminders = await readFileOptional(\n path.join(agentDir, STANDARD_FILES.CRITICAL_REMINDERS_MD),\n \"\",\n );\n\n const category = agentPath.split(\"/\")[0] || name;\n const categoryDir = path.join(agentSourceRoot, agentBaseDir, category);\n const output = await readOutputPartial(agentDir, categoryDir);\n\n return { identity, playbook, output, criticalRequirementsTop, criticalReminders };\n}\n\n/** The agent's own `output.md`, or its category's where the agent's is absent or empty. */\nasync function readOutputPartial(agentDir: string, categoryDir: string): Promise<string> {\n const own = await readFileOptional(path.join(agentDir, STANDARD_FILES.OUTPUT_MD), \"\");\n if (own) return own;\n return readFileOptional(path.join(categoryDir, STANDARD_FILES.OUTPUT_MD), \"\");\n}\n\n/**\n * Template roots, first match wins: the project source folder's `agents/_templates/`, legacy\n * `.claude/templates/`, then the built-ins. The options mirror `createEngineFromTemplates` in\n * `@workspace/compile/engine`; keep the two in sync.\n */\nexport async function createLiquidEngine(projectDir?: string): Promise<Liquid> {\n const roots: string[] = [];\n // One read for both: template overrides and source folder must name one installation.\n const provider = providerInUse(projectDir);\n\n if (projectDir) {\n const srcTemplatesDir = path.join(\n sourceFolderInUse(projectDir, provider).dir,\n STANDARD_DIRS.AGENTS,\n path.basename(DIRS.templates),\n );\n if (await directoryExists(srcTemplatesDir)) {\n roots.push(srcTemplatesDir);\n verbose(`Using local templates from: ${srcTemplatesDir}`);\n }\n\n const legacyTemplatesDir = path.join(projectDir, CLAUDE_DIR, STANDARD_DIRS.TEMPLATES);\n if (await directoryExists(legacyTemplatesDir)) {\n roots.push(legacyTemplatesDir);\n verbose(`Using legacy templates from: ${legacyTemplatesDir}`);\n }\n }\n\n roots.push(path.join(PROJECT_ROOT, DIRS.templates));\n\n return new Liquid({\n root: roots,\n extname: \".liquid\",\n strictVariables: false,\n strictFilters: true,\n globals: { sourceFolder: sourceFolderName(projectDir, provider) },\n });\n}\n\n/** Both hosts render from one template context; only the wrapper differs (markdown or TOML). */\nexport async function compileAgentForHost(\n provider: Provider,\n name: AgentName,\n agent: AgentConfig,\n fallbackRoot: string,\n engine: Liquid,\n): Promise<string> {\n verbose(`Compiling agent: ${name} (${provider})`);\n\n const files = await readAgentFiles(name, agent, fallbackRoot);\n\n // Each skill's own `source` decides `${id}:${id}` versus a bare id; no `source` means bare.\n const data = buildAgentTemplateContext(name, agent, files, (skill) => ({\n ...skill,\n ...pluginRefFor(skill),\n }));\n const version = await cliVersion();\n\n switch (provider) {\n case \"claude\":\n return renderAgent(engine, data, version);\n case \"codex\":\n return renderAgentRoleToml(agent, await renderAgentBody(engine, data, version));\n default: {\n const _exhaustive: never = provider;\n return _exhaustive;\n }\n }\n}\n","import path from \"path\";\nimport { z } from \"zod\";\n\nimport { PROJECT_ROOT, STANDARD_FILES } from \"../../consts\";\nimport { readFile } from \"../../utils/fs\";\n\nconst ownPackageJsonSchema = z.object({ version: z.string().min(1) });\n\nexport {\n hasProvenanceMarker,\n provenanceMarker,\n stampProvenanceMarker,\n} from \"@workspace/compile/agent-source\";\n\nlet ownVersion: Promise<string> | undefined;\n\n/**\n * Rendered in the trailing `<system-reminder>`, not the provenance marker, so a version bump leaves\n * the first cacheable bytes of every compiled agent unchanged.\n */\nexport function cliVersion(): Promise<string> {\n ownVersion ??= readOwnVersion();\n return ownVersion;\n}\n\nasync function readOwnVersion(): Promise<string> {\n const manifestPath = path.join(PROJECT_ROOT, STANDARD_FILES.PACKAGE_JSON);\n const raw: unknown = JSON.parse(await readFile(manifestPath));\n\n const parsed = ownPackageJsonSchema.safeParse(raw);\n if (!parsed.success) {\n throw new Error(`Could not read this CLI's own version from ${manifestPath}`);\n }\n return parsed.data.version;\n}\n"],"mappings":"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","names":["partition","path","path","path","path","path","path","path","partition","path"]}
1
+ {"version":3,"sources":["../src/cli/lib/agents/list-compiled-agents.ts","../src/cli/lib/agents/agent-recompiler.ts","../src/cli/lib/agents/write-compiled-agents.ts","../src/cli/lib/compiler.ts","../src/cli/lib/agents/agent-provenance.ts"],"sourcesContent":["import path from \"path\";\nimport { partition } from \"remeda\";\nimport { glob, readFileOptional, remove } from \"../../utils/fs\";\nimport { isAgentName } from \"../../utils/type-guards\";\nimport { type AgentCodec, agentCodec } from \"../installation/install-layout\";\nimport type { AgentName } from \"../../types\";\n\n/**\n * The default codec; a caller on another host passes that host's\n * (`agentCodec(providerInUse(dir))`).\n */\nconst CLAUDE_AGENTS = agentCodec(\"claude\");\n\ntype AgentProvenanceSplit = {\n marked: string[];\n unmarked: string[];\n};\n\nexport async function listAgentMdFiles(agentsDir: string): Promise<string[]> {\n return listAgentFilesOf(agentsDir, CLAUDE_AGENTS);\n}\n\nexport async function listAgentFilesOf(agentsDir: string, codec: AgentCodec): Promise<string[]> {\n return glob(codec.listGlob, agentsDir);\n}\n\n/** An unreadable file lands in `unmarked`: \"cannot prove it is ours\" means leave it alone. */\nexport async function splitAgentsByProvenance(\n agentsDir: string,\n codec: AgentCodec = CLAUDE_AGENTS,\n): Promise<AgentProvenanceSplit> {\n const files = await listAgentFilesOf(agentsDir, codec);\n const classified = await Promise.all(\n files.map((file) => readAgentProvenance(agentsDir, file, codec)),\n );\n const [marked, unmarked] = partition(classified, (agent) => agent.compiledHere);\n\n return {\n marked: marked.map((agent) => agent.name),\n unmarked: unmarked.map((agent) => agent.name),\n };\n}\n\ntype ClassifiedAgent = { name: string; compiledHere: boolean };\n\nasync function readAgentProvenance(\n agentsDir: string,\n file: string,\n codec: AgentCodec,\n): Promise<ClassifiedAgent> {\n const content = await readFileOptional(path.join(agentsDir, file));\n return { name: path.basename(file, codec.extension), compiledHere: codec.hasMarker(content) };\n}\n\nexport async function listCompiledAgentNames(agentsDir: string): Promise<AgentName[]> {\n const files = await listAgentMdFiles(agentsDir);\n // Boundary cast: custom marketplace agents may fall outside the AgentName union.\n return files.map((f) => path.basename(f, CLAUDE_AGENTS.extension) as AgentName);\n}\n\n/**\n * Deletes built-in-named agent files not in `keep`, which must be the complete set for `agentsDir`.\n */\nexport async function pruneStaleCompiledAgents(\n agentsDir: string,\n keep: ReadonlySet<AgentName>,\n codec: AgentCodec = CLAUDE_AGENTS,\n): Promise<void> {\n const isStaleCompiledAgent = (file: string): boolean => {\n const name = path.basename(file, codec.extension);\n return isAgentName(name) && !keep.has(name);\n };\n\n const files = await listAgentFilesOf(agentsDir, codec);\n await Promise.all(\n files.filter(isStaleCompiledAgent).map((file) => remove(path.join(agentsDir, file))),\n );\n}\n","import { partition } from \"remeda\";\nimport { writeCompiledAgentsByScope, type AgentWriteOutcome } from \"./write-compiled-agents\";\nimport { listCompiledAgentNames } from \"./list-compiled-agents\";\nimport path from \"path\";\n\nimport { getErrorMessage } from \"../../utils/errors\";\nimport type {\n AgentDefinition,\n AgentName,\n CompileAgentConfig,\n CompileConfig,\n ProjectConfig,\n SkillDefinitionMap,\n SkillId,\n SkillScope,\n} from \"../../types\";\n\nimport { buildCompileAgents } from \"../installation/local-installer\";\nimport { ensureDir } from \"../../utils/fs\";\nimport { verbose } from \"../../utils/logger\";\nimport { typedEntries, typedFromEntries, typedKeys } from \"../../utils/typed-object\";\nimport { createLiquidEngine } from \"../compiler\";\nimport { loadProjectConfig, effectivelyExcludedSkillIds } from \"../configuration\";\nimport { loadAllAgents, loadProjectAgents } from \"../loading\";\nimport { getPluginAgentsDir } from \"../plugins\";\nimport { discoverAllPluginSkills } from \"../plugins/plugin-discovery\";\nimport { resolveAgents } from \"../resolver\";\n\nexport type RecompileAgentsOptions = {\n pluginDir: string;\n sourcePath: string;\n agents?: AgentName[];\n skills?: SkillDefinitionMap;\n projectDir?: string;\n outputDir?: string;\n /** When provided, routes agents by scope: global agents to ~/.claude/agents/, project agents to outputDir */\n agentScopeMap?: Map<AgentName, SkillScope>;\n};\n\nexport type RecompileAgentsResult = {\n compiled: AgentName[];\n /** The subset of `compiled` whose file content moved; the rest count as unchanged. */\n rewritten: AgentName[];\n failed: AgentName[];\n warnings: string[];\n};\n\nasync function getExistingAgentNames(pluginDir: string): Promise<AgentName[]> {\n return listCompiledAgentNames(getPluginAgentsDir(pluginDir));\n}\n\ntype ResolveAgentNamesParams = {\n specifiedAgents?: AgentName[];\n projectConfig: ProjectConfig | null;\n allAgents: Partial<Record<AgentName, AgentDefinition>>;\n outputDir?: string;\n pluginDir: string;\n};\n\nasync function resolveAgentNames(params: ResolveAgentNamesParams): Promise<AgentName[]> {\n const { specifiedAgents, projectConfig, allAgents, outputDir, pluginDir } = params;\n\n if (specifiedAgents) {\n return specifiedAgents;\n }\n\n // A present config is authoritative even when its roster is empty.\n if (projectConfig) {\n const agentNames = projectConfig.agents.map((a) => a.name);\n verbose(`Using agents from config: ${agentNames.join(\", \")}`);\n return agentNames;\n }\n\n if (outputDir) {\n const names = typedKeys<AgentName>(allAgents);\n verbose(`Using all available agents from source: ${names.join(\", \")}`);\n return names;\n }\n\n return getExistingAgentNames(pluginDir);\n}\n\nfunction buildRecompileResult(\n outcomes: AgentWriteOutcome[],\n priorWarnings: string[],\n): RecompileAgentsResult {\n const [succeeded, failedOutcomes] = partition(\n outcomes,\n (outcome): outcome is Extract<AgentWriteOutcome, { ok: true }> => outcome.ok,\n );\n succeeded.forEach((outcome) =>\n verbose(\n ` ${outcome.rewritten ? \"Rewrote\" : \"Unchanged\"}: ${outcome.name} (${outcome.scope} -> ${outcome.targetDir})`,\n ),\n );\n return {\n compiled: succeeded.map((outcome) => outcome.name),\n rewritten: succeeded.filter((outcome) => outcome.rewritten).map((outcome) => outcome.name),\n failed: failedOutcomes.map((outcome) => outcome.name),\n warnings: [\n ...priorWarnings,\n ...failedOutcomes.map(\n (outcome) => `Failed to compile ${outcome.name}: ${getErrorMessage(outcome.error)}`,\n ),\n ],\n };\n}\n\nexport function filterExcludedEntries(config: ProjectConfig): ProjectConfig {\n const excludedIds = effectivelyExcludedSkillIds(config.skills);\n const activeSkills = config.skills.filter((s) => !s.excluded);\n const activeAgents = config.agents.filter((a) => !a.excluded);\n\n // No stack stays absent rather than an explicit `undefined`.\n const filteredStack =\n config.stack === undefined\n ? {}\n : { stack: withoutExcludedAssignments(config.stack, excludedIds) };\n\n return { ...config, skills: activeSkills, agents: activeAgents, ...filteredStack };\n}\n\n/** Each agent and category keeps its key, even when left with no assignments. */\nexport function withoutExcludedAssignments(\n stack: NonNullable<ProjectConfig[\"stack\"]>,\n excludedIds: ReadonlySet<SkillId>,\n): NonNullable<ProjectConfig[\"stack\"]> {\n return Object.fromEntries(\n typedEntries(stack).map(([agentName, agentStack]) => [\n agentName,\n Object.fromEntries(\n typedEntries(agentStack).map(([category, assignments]) => [\n category,\n assignments.filter((assignment) => !excludedIds.has(assignment.id)),\n ]),\n ),\n ]),\n );\n}\n\nexport async function recompileAgents(\n options: RecompileAgentsOptions,\n): Promise<RecompileAgentsResult> {\n const { pluginDir, sourcePath, skills: providedSkills, projectDir, outputDir } = options;\n\n const configDir = projectDir ?? pluginDir;\n const filteredConfig = await loadConfigWithoutExclusions(configDir);\n const allAgents = await loadAgentDefinitions(sourcePath, projectDir);\n\n const agentNames = await resolveAgentNames({\n ...(options.agents !== undefined && { specifiedAgents: options.agents }),\n projectConfig: filteredConfig,\n allAgents,\n ...(outputDir !== undefined && { outputDir }),\n pluginDir,\n });\n\n // An empty pass is not a warning: callers report it off `compiled`.\n if (agentNames.length === 0) {\n return { compiled: [], rewritten: [], failed: [], warnings: [] };\n }\n\n verbose(`Recompiling ${agentNames.length} agents in ${outputDir ?? pluginDir}`);\n\n const pluginSkills: SkillDefinitionMap =\n providedSkills ?? (await discoverAllPluginSkills(projectDir ?? pluginDir));\n\n const { configAgents, missingWarnings } = compileEntriesFor(\n agentNames,\n filteredConfig,\n allAgents,\n );\n const compileConfig = compileConfigFor(filteredConfig, configAgents, pluginDir);\n\n const engine = await createLiquidEngine(projectDir);\n const resolvedAgents = await resolveAgents(allAgents, pluginSkills, compileConfig);\n\n const agentsDir = outputDir ?? getPluginAgentsDir(pluginDir);\n await ensureDir(agentsDir);\n\n const outcomes = await writeCompiledAgentsByScope({\n resolvedAgents,\n sourcePath,\n engine,\n projectAgentsDir: agentsDir,\n // Same root as the config, so format and configuration come from one installation.\n projectDir: configDir,\n ...(options.agentScopeMap !== undefined && { agentScopeMap: options.agentScopeMap }),\n });\n return buildRecompileResult(outcomes, missingWarnings);\n}\n\nasync function loadConfigWithoutExclusions(configDir: string): Promise<ProjectConfig | null> {\n const loaded = await loadProjectConfig(configDir);\n return loaded ? filterExcludedEntries(loaded.config) : null;\n}\n\n/** A project agent wins over a built-in one of the same name. */\nasync function loadAgentDefinitions(\n sourcePath: string,\n projectDir: string | undefined,\n): Promise<Partial<Record<AgentName, AgentDefinition>>> {\n const builtinAgents = await loadAllAgents(sourcePath);\n const projectAgents = projectDir ? await loadProjectAgents(projectDir) : {};\n\n return { ...builtinAgents, ...projectAgents };\n}\n\nfunction compileConfigFor(\n config: ProjectConfig | null,\n agents: Partial<Record<AgentName, CompileAgentConfig>>,\n pluginDir: string,\n): CompileConfig {\n return {\n name: config?.name || path.basename(pluginDir),\n description: config?.description || \"Recompiled plugin\",\n agents,\n };\n}\n\n/** Only agents the scope filter matches: a project pass must not overwrite stackless globals. */\nfunction compileEntriesFor(\n agentNames: AgentName[],\n config: ProjectConfig | null,\n allAgents: Partial<Record<AgentName, AgentDefinition>>,\n): { configAgents: Partial<Record<AgentName, CompileAgentConfig>>; missingWarnings: string[] } {\n const allConfigAgents = config ? buildCompileAgents(config, allAgents) : {};\n\n const [knownAgents, missingAgents] = partition(agentNames, (name) =>\n Boolean(allConfigAgents[name] || allAgents[name]),\n );\n\n return {\n configAgents: typedFromEntries<AgentName, CompileAgentConfig>(\n knownAgents.map((name) => [name, allConfigAgents[name] ?? {}]),\n ),\n missingWarnings: missingAgents.map((name) => `Agent \"${name}\" not found in source definitions`),\n };\n}\n","import os from \"os\";\nimport path from \"path\";\nimport type { Liquid } from \"liquidjs\";\nimport { compileAgentForHost } from \"../compiler.js\";\nimport { resolveInstallPaths } from \"../installation/install-base-dir.js\";\nimport { agentCodec, hostCompilesAgent, providerInUse } from \"../installation/install-layout.js\";\nimport { writeFile, fileExists, readFile } from \"../../utils/fs.js\";\nimport { typedEntries } from \"../../utils/typed-object.js\";\nimport type { Provider } from \"../../consts.js\";\nimport type { AgentConfig, AgentName, SkillScope } from \"../../types/index.js\";\n\nexport type AgentWriteOutcome =\n | {\n name: AgentName;\n ok: true;\n scope: SkillScope;\n targetDir: string;\n /** False when the output matched the file on disk, so nothing was written. */\n rewritten: boolean;\n }\n | { name: AgentName; ok: false; error: unknown };\n\n/** Skipping an identical write keeps the mtime, the only trace telling unchanged from rewritten. */\nasync function holdsExactly(filePath: string, content: string): Promise<boolean> {\n return (await fileExists(filePath)) && (await readFile(filePath)) === content;\n}\n\n/**\n * Routing for an agent the scope map does not name: the caller's `projectAgentsDir`. Deliberately\n * not the selection default, which would move unrouted agents into `~/.claude/agents`.\n */\nconst UNROUTED_AGENT_SCOPE: SkillScope = \"project\";\n\n/**\n * Per-agent failures come back as outcomes; a directory appears only when an agent routes into it.\n */\nexport async function writeCompiledAgentsByScope(params: {\n resolvedAgents: Partial<Record<AgentName, AgentConfig>>;\n sourcePath: string;\n engine: Liquid;\n projectAgentsDir: string;\n /** The root whose folder says which host the PROJECT scope's sub-agents are written for. */\n projectDir: string;\n agentScopeMap?: Map<AgentName, SkillScope>;\n}): Promise<AgentWriteOutcome[]> {\n const hosts: Record<SkillScope, AgentHost> = {\n // Each scope reads its own root: a Codex project under a Claude global is allowed.\n global: {\n provider: providerInUse(os.homedir()),\n agentsDir: resolveInstallPaths(os.homedir(), \"global\").agentsDir,\n },\n project: { provider: providerInUse(params.projectDir), agentsDir: params.projectAgentsDir },\n };\n\n const outcomes: AgentWriteOutcome[] = [];\n for (const [name, agent] of typedEntries<AgentName, AgentConfig>(params.resolvedAgents)) {\n const scope = params.agentScopeMap?.get(name) ?? UNROUTED_AGENT_SCOPE;\n const host = hosts[scope];\n\n // No outcome for a sub-agent this host does not carry: it was neither compiled nor failed.\n if (!hostCompilesAgent(host.provider, name)) continue;\n\n outcomes.push(await writeOneAgent({ ...params, name, agent, scope, host }));\n }\n return outcomes;\n}\n\n/** Returns the failure rather than throwing: the policy is the caller's. */\nasync function writeOneAgent(params: {\n name: AgentName;\n agent: AgentConfig;\n scope: SkillScope;\n host: AgentHost;\n sourcePath: string;\n engine: Liquid;\n}): Promise<AgentWriteOutcome> {\n const { name, scope, host } = params;\n\n try {\n const output = await compileAgentForHost(\n host.provider,\n name,\n params.agent,\n params.sourcePath,\n params.engine,\n );\n const targetPath = path.join(host.agentsDir, fileNameFor(name, host.provider));\n const rewritten = !(await holdsExactly(targetPath, output));\n if (rewritten) await writeFile(targetPath, output);\n\n return { name, ok: true, scope, targetDir: host.agentsDir, rewritten };\n } catch (error) {\n return { name, ok: false, error };\n }\n}\n\ntype AgentHost = { provider: Provider; agentsDir: string };\n\n/** The extension comes from `agentCodec`, so a `.md` never lands where Codex reads `.toml`. */\nfunction fileNameFor(name: AgentName, provider: Provider): string {\n return `${name}${agentCodec(provider).extension}`;\n}\n","import { Liquid } from \"liquidjs\";\nimport path from \"path\";\nimport {\n buildAgentTemplateContext,\n pluginRefFor,\n renderAgent,\n renderAgentBody,\n renderAgentRoleToml,\n type AgentFiles,\n} from \"@workspace/compile/agent-source\";\nimport { readFile, readFileOptional, directoryExists } from \"../utils/fs\";\nimport { verbose } from \"../utils/logger\";\nimport {\n CLAUDE_DIR,\n DIRS,\n PROJECT_ROOT,\n STANDARD_FILES,\n STANDARD_DIRS,\n type Provider,\n} from \"../consts\";\nimport { providerInUse, sourceFolderInUse, sourceFolderName } from \"./installation/install-layout\";\nimport { cliVersion } from \"./agents/agent-provenance\";\nimport \"./compile-seat.js\";\nimport type { AgentConfig, AgentName } from \"../types\";\n\nexport {\n buildAgentTemplateContext,\n sanitizeCompiledAgentData,\n sanitizeLiquidSyntax,\n} from \"@workspace/compile/agent-source\";\n\nasync function readAgentFiles(\n name: AgentName,\n agent: AgentConfig,\n projectRoot: string,\n): Promise<AgentFiles> {\n const agentSourceRoot = agent.sourceRoot || projectRoot;\n const agentBaseDir = agent.agentBaseDir || DIRS.agents;\n const agentPath = agent.path || name;\n const agentDir = path.join(agentSourceRoot, agentBaseDir, agentPath);\n\n const identity = await readFile(path.join(agentDir, STANDARD_FILES.IDENTITY_MD));\n const playbook = await readFile(path.join(agentDir, STANDARD_FILES.PLAYBOOK_MD));\n const criticalRequirementsTop = await readFileOptional(\n path.join(agentDir, STANDARD_FILES.CRITICAL_REQUIREMENTS_MD),\n \"\",\n );\n const criticalReminders = await readFileOptional(\n path.join(agentDir, STANDARD_FILES.CRITICAL_REMINDERS_MD),\n \"\",\n );\n\n const category = agentPath.split(\"/\")[0] || name;\n const categoryDir = path.join(agentSourceRoot, agentBaseDir, category);\n const output = await readOutputPartial(agentDir, categoryDir);\n\n return { identity, playbook, output, criticalRequirementsTop, criticalReminders };\n}\n\n/** The agent's own `output.md`, or its category's where the agent's is absent or empty. */\nasync function readOutputPartial(agentDir: string, categoryDir: string): Promise<string> {\n const own = await readFileOptional(path.join(agentDir, STANDARD_FILES.OUTPUT_MD), \"\");\n if (own) return own;\n return readFileOptional(path.join(categoryDir, STANDARD_FILES.OUTPUT_MD), \"\");\n}\n\n/**\n * Template roots, first match wins: the project source folder's `agents/_templates/`, legacy\n * `.claude/templates/`, then the built-ins. The options mirror `createEngineFromTemplates` in\n * `@workspace/compile/engine`; keep the two in sync.\n */\nexport async function createLiquidEngine(projectDir?: string): Promise<Liquid> {\n const roots: string[] = [];\n // One read for both: template overrides and source folder must name one installation.\n const provider = providerInUse(projectDir);\n\n if (projectDir) {\n const srcTemplatesDir = path.join(\n sourceFolderInUse(projectDir, provider).dir,\n STANDARD_DIRS.AGENTS,\n path.basename(DIRS.templates),\n );\n if (await directoryExists(srcTemplatesDir)) {\n roots.push(srcTemplatesDir);\n verbose(`Using local templates from: ${srcTemplatesDir}`);\n }\n\n const legacyTemplatesDir = path.join(projectDir, CLAUDE_DIR, STANDARD_DIRS.TEMPLATES);\n if (await directoryExists(legacyTemplatesDir)) {\n roots.push(legacyTemplatesDir);\n verbose(`Using legacy templates from: ${legacyTemplatesDir}`);\n }\n }\n\n roots.push(path.join(PROJECT_ROOT, DIRS.templates));\n\n return new Liquid({\n root: roots,\n extname: \".liquid\",\n strictVariables: false,\n strictFilters: true,\n globals: { sourceFolder: sourceFolderName(projectDir, provider) },\n });\n}\n\n/** Both hosts render from one template context; only the wrapper differs (markdown or TOML). */\nexport async function compileAgentForHost(\n provider: Provider,\n name: AgentName,\n agent: AgentConfig,\n fallbackRoot: string,\n engine: Liquid,\n): Promise<string> {\n verbose(`Compiling agent: ${name} (${provider})`);\n\n const files = await readAgentFiles(name, agent, fallbackRoot);\n\n // Each skill's own `source` decides `${id}:${id}` versus a bare id; no `source` means bare.\n const data = buildAgentTemplateContext(name, agent, files, (skill) => ({\n ...skill,\n ...pluginRefFor(skill),\n }));\n const version = await cliVersion();\n\n switch (provider) {\n case \"claude\":\n return renderAgent(engine, data, version);\n case \"codex\":\n return renderAgentRoleToml(agent, await renderAgentBody(engine, data, version));\n default: {\n const _exhaustive: never = provider;\n return _exhaustive;\n }\n }\n}\n","import path from \"path\";\nimport { z } from \"zod\";\n\nimport { PROJECT_ROOT, STANDARD_FILES } from \"../../consts\";\nimport { readFile } from \"../../utils/fs\";\n\nconst ownPackageJsonSchema = z.object({ version: z.string().min(1) });\n\nexport {\n hasProvenanceMarker,\n provenanceMarker,\n stampProvenanceMarker,\n} from \"@workspace/compile/agent-source\";\n\nlet ownVersion: Promise<string> | undefined;\n\n/**\n * Rendered in the trailing `<system-reminder>`, not the provenance marker, so a version bump leaves\n * the first cacheable bytes of every compiled agent unchanged.\n */\nexport function cliVersion(): Promise<string> {\n ownVersion ??= readOwnVersion();\n return ownVersion;\n}\n\nasync function readOwnVersion(): Promise<string> {\n const manifestPath = path.join(PROJECT_ROOT, STANDARD_FILES.PACKAGE_JSON);\n const raw: unknown = JSON.parse(await readFile(manifestPath));\n\n const parsed = ownPackageJsonSchema.safeParse(raw);\n if (!parsed.success) {\n throw new Error(`Could not read this CLI's own version from ${manifestPath}`);\n }\n return parsed.data.version;\n}\n"],"mappings":"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","names":["partition","path","path","path","path","path","path","path","partition","path"]}
@@ -2,12 +2,12 @@
2
2
  import {
3
3
  chooseProviderForThisRun,
4
4
  detectInstallations
5
- } from "./chunk-3YYHL76L.js";
5
+ } from "./chunk-VILFCMRN.js";
6
6
  import {
7
7
  CLI_INVOKE_COMMAND,
8
8
  EDITOR_URL,
9
9
  PROVIDERS
10
- } from "./chunk-A6OWEJGC.js";
10
+ } from "./chunk-MHAQWMNJ.js";
11
11
 
12
12
  // src/cli/lib/installation/provider-flag.ts
13
13
  import os from "os";
@@ -50,6 +50,14 @@ async function refuseAnAmbiguousInstallation(cwd, subject, named, onAmbiguous) {
50
50
  if (providers.length <= 1) return;
51
51
  onAmbiguous(ambiguousInstallation(subject, providers, scopeRoot));
52
52
  }
53
+ async function providersInPlay(cwd) {
54
+ return (await installationsInPlay(cwd)).providers;
55
+ }
56
+ async function installationToName(cwd, named) {
57
+ if (named !== void 0) return named;
58
+ const providers = await providersInPlay(cwd);
59
+ return providers.length > 1 ? providers : void 0;
60
+ }
53
61
  async function ambiguityFinding(cwd) {
54
62
  const { scopeRoot, providers } = await installationsInPlay(cwd);
55
63
  if (providers.length <= 1) return null;
@@ -67,7 +75,8 @@ export {
67
75
  providerNamedBy,
68
76
  providerNeedsAConfigurationToInstall,
69
77
  refuseAnAmbiguousInstallation,
78
+ installationToName,
70
79
  ambiguityFinding,
71
80
  otherInstallationsInThisScope
72
81
  };
73
- //# sourceMappingURL=chunk-W4KAY26P.js.map
82
+ //# sourceMappingURL=chunk-MBIOZ5LW.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli/lib/installation/provider-flag.ts"],"sourcesContent":["/**\n * `--provider`: names the installation where the folder cannot — a greenfield `init --from`, or a\n * scope holding both providers, where acting commands refuse until it is given.\n */\n\nimport os from \"os\";\n\nimport { Flags } from \"@oclif/core\";\n\nimport { PROVIDERS, EDITOR_URL, CLI_INVOKE_COMMAND, type Provider } from \"../../consts.js\";\nimport { detectInstallations, type DetectedInstallation } from \"./detect-installations.js\";\nimport { chooseProviderForThisRun } from \"./install-layout.js\";\n\n/** A factory because oclif mutates flag definitions, so commands must not share one. */\nexport function providerFlag() {\n return Flags.string({\n description: \"Which provider's installation this run is about\",\n helpValue: `<${PROVIDERS.join(\"|\")}>`,\n options: [...PROVIDERS],\n });\n}\n\n/** oclif has already rejected unlisted values; this only narrows. */\nexport function providerNamedBy(flagValue: string | undefined): Provider | undefined {\n if (flagValue === undefined) return undefined;\n return PROVIDERS.find((provider) => provider === flagValue);\n}\n\nexport function providerNeedsAConfigurationToInstall(): string {\n return (\n `--provider names which installation to create and needs the configuration to create it ` +\n `from, so it is only meaningful beside --from. Build one at ${EDITOR_URL}, then run ` +\n `'${CLI_INVOKE_COMMAND} init --from <id> --provider <provider>'.`\n );\n}\n\nfunction ambiguousInstallation(\n subject: string,\n providers: readonly Provider[],\n scopeRoot: string,\n): string {\n return (\n `${scopeRoot} holds ${providers.length} installations — ${providers.join(\" and \")} — so ` +\n `${subject} cannot tell which one you mean. Name it with --provider <${providers.join(\"|\")}>. ` +\n `Nothing has been changed.`\n );\n}\n\ntype InstallationsInPlay = {\n scopeRoot: string;\n providers: Provider[];\n};\n\n/** The project's installations, or the global ones only when the project has none. */\nasync function installationsInPlay(cwd: string): Promise<InstallationsInPlay> {\n const found = await detectInstallations(cwd);\n const inTheProject = atScope(found, \"project\");\n\n if (inTheProject.length > 0) return { scopeRoot: cwd, providers: providersOf(inTheProject) };\n return { scopeRoot: os.homedir(), providers: providersOf(atScope(found, \"global\")) };\n}\n\nfunction atScope(\n found: readonly DetectedInstallation[],\n scope: DetectedInstallation[\"scope\"],\n): DetectedInstallation[] {\n return found.filter((installation) => installation.scope === scope);\n}\n\nfunction providersOf(installations: readonly DetectedInstallation[]): Provider[] {\n return installations.map((installation) => installation.provider);\n}\n\n/**\n * A named provider is committed for the run; two installations and no flag call `onAmbiguous`\n * (the command's `this.error`); otherwise nothing happens.\n */\nexport async function refuseAnAmbiguousInstallation(\n cwd: string,\n subject: string,\n named: Provider | undefined,\n onAmbiguous: (message: string) => never,\n): Promise<void> {\n if (named !== undefined) {\n chooseProviderForThisRun(named);\n return;\n }\n\n const { scopeRoot, providers } = await installationsInPlay(cwd);\n if (providers.length <= 1) return;\n\n onAmbiguous(ambiguousInstallation(subject, providers, scopeRoot));\n}\n\n/** The non-refusing form, for `doctor`. */\nexport async function ambiguityFinding(cwd: string): Promise<string | null> {\n const { scopeRoot, providers } = await installationsInPlay(cwd);\n if (providers.length <= 1) return null;\n\n return ambiguousInstallation(\"every command that acts on one\", providers, scopeRoot);\n}\n\n/** For `list`: names the other installation in the scope, or `null` when there is none. */\nexport async function otherInstallationsInThisScope(\n cwd: string,\n showing: Provider,\n): Promise<string | null> {\n const { scopeRoot, providers } = await installationsInPlay(cwd);\n const others = providers.filter((provider) => provider !== showing);\n if (others.length === 0) return null;\n\n return (\n `${scopeRoot} holds ${providers.length} installations — ${providers.join(\" and \")} — and this ` +\n `is the ${showing} one. Show another with --provider <${providers.join(\"|\")}>.`\n );\n}\n"],"mappings":";;;;;;;;;;;;AAKA,OAAO,QAAQ;AAEf,SAAS,aAAa;AAOf,SAAS,eAAe;AAC7B,SAAO,MAAM,OAAO;AAAA,IAClB,aAAa;AAAA,IACb,WAAW,IAAI,UAAU,KAAK,GAAG,CAAC;AAAA,IAClC,SAAS,CAAC,GAAG,SAAS;AAAA,EACxB,CAAC;AACH;AAGO,SAAS,gBAAgB,WAAqD;AACnF,MAAI,cAAc,OAAW,QAAO;AACpC,SAAO,UAAU,KAAK,CAAC,aAAa,aAAa,SAAS;AAC5D;AAEO,SAAS,uCAA+C;AAC7D,SACE,qJAC8D,UAAU,eACpE,kBAAkB;AAE1B;AAEA,SAAS,sBACP,SACA,WACA,WACQ;AACR,SACE,GAAG,SAAS,UAAU,UAAU,MAAM,yBAAoB,UAAU,KAAK,OAAO,CAAC,cAC9E,OAAO,6DAA6D,UAAU,KAAK,GAAG,CAAC;AAG9F;AAQA,eAAe,oBAAoB,KAA2C;AAC5E,QAAM,QAAQ,MAAM,oBAAoB,GAAG;AAC3C,QAAM,eAAe,QAAQ,OAAO,SAAS;AAE7C,MAAI,aAAa,SAAS,EAAG,QAAO,EAAE,WAAW,KAAK,WAAW,YAAY,YAAY,EAAE;AAC3F,SAAO,EAAE,WAAW,GAAG,QAAQ,GAAG,WAAW,YAAY,QAAQ,OAAO,QAAQ,CAAC,EAAE;AACrF;AAEA,SAAS,QACP,OACA,OACwB;AACxB,SAAO,MAAM,OAAO,CAAC,iBAAiB,aAAa,UAAU,KAAK;AACpE;AAEA,SAAS,YAAY,eAA4D;AAC/E,SAAO,cAAc,IAAI,CAAC,iBAAiB,aAAa,QAAQ;AAClE;AAMA,eAAsB,8BACpB,KACA,SACA,OACA,aACe;AACf,MAAI,UAAU,QAAW;AACvB,6BAAyB,KAAK;AAC9B;AAAA,EACF;AAEA,QAAM,EAAE,WAAW,UAAU,IAAI,MAAM,oBAAoB,GAAG;AAC9D,MAAI,UAAU,UAAU,EAAG;AAE3B,cAAY,sBAAsB,SAAS,WAAW,SAAS,CAAC;AAClE;AAGA,eAAsB,iBAAiB,KAAqC;AAC1E,QAAM,EAAE,WAAW,UAAU,IAAI,MAAM,oBAAoB,GAAG;AAC9D,MAAI,UAAU,UAAU,EAAG,QAAO;AAElC,SAAO,sBAAsB,kCAAkC,WAAW,SAAS;AACrF;AAGA,eAAsB,8BACpB,KACA,SACwB;AACxB,QAAM,EAAE,WAAW,UAAU,IAAI,MAAM,oBAAoB,GAAG;AAC9D,QAAM,SAAS,UAAU,OAAO,CAAC,aAAa,aAAa,OAAO;AAClE,MAAI,OAAO,WAAW,EAAG,QAAO;AAEhC,SACE,GAAG,SAAS,UAAU,UAAU,MAAM,yBAAoB,UAAU,KAAK,OAAO,CAAC,2BACvE,OAAO,uCAAuC,UAAU,KAAK,GAAG,CAAC;AAE/E;","names":[]}
1
+ {"version":3,"sources":["../src/cli/lib/installation/provider-flag.ts"],"sourcesContent":["/**\n * `--provider`: names the installation where the folder cannot — a greenfield `init --from`, or a\n * scope holding both providers, where acting commands refuse until it is given.\n */\n\nimport os from \"os\";\n\nimport { Flags } from \"@oclif/core\";\n\nimport { PROVIDERS, EDITOR_URL, CLI_INVOKE_COMMAND, type Provider } from \"../../consts.js\";\nimport { detectInstallations, type DetectedInstallation } from \"./detect-installations.js\";\nimport { chooseProviderForThisRun } from \"./install-layout.js\";\n\n/** A factory because oclif mutates flag definitions, so commands must not share one. */\nexport function providerFlag() {\n return Flags.string({\n description: \"Which provider's installation this run is about\",\n helpValue: `<${PROVIDERS.join(\"|\")}>`,\n options: [...PROVIDERS],\n });\n}\n\n/** oclif has already rejected unlisted values; this only narrows. */\nexport function providerNamedBy(flagValue: string | undefined): Provider | undefined {\n if (flagValue === undefined) return undefined;\n return PROVIDERS.find((provider) => provider === flagValue);\n}\n\nexport function providerNeedsAConfigurationToInstall(): string {\n return (\n `--provider names which installation to create and needs the configuration to create it ` +\n `from, so it is only meaningful beside --from. Build one at ${EDITOR_URL}, then run ` +\n `'${CLI_INVOKE_COMMAND} init --from <id> --provider <provider>'.`\n );\n}\n\nfunction ambiguousInstallation(\n subject: string,\n providers: readonly Provider[],\n scopeRoot: string,\n): string {\n return (\n `${scopeRoot} holds ${providers.length} installations — ${providers.join(\" and \")} — so ` +\n `${subject} cannot tell which one you mean. Name it with --provider <${providers.join(\"|\")}>. ` +\n `Nothing has been changed.`\n );\n}\n\ntype InstallationsInPlay = {\n scopeRoot: string;\n providers: Provider[];\n};\n\n/** The project's installations, or the global ones only when the project has none. */\nasync function installationsInPlay(cwd: string): Promise<InstallationsInPlay> {\n const found = await detectInstallations(cwd);\n const inTheProject = atScope(found, \"project\");\n\n if (inTheProject.length > 0) return { scopeRoot: cwd, providers: providersOf(inTheProject) };\n return { scopeRoot: os.homedir(), providers: providersOf(atScope(found, \"global\")) };\n}\n\nfunction atScope(\n found: readonly DetectedInstallation[],\n scope: DetectedInstallation[\"scope\"],\n): DetectedInstallation[] {\n return found.filter((installation) => installation.scope === scope);\n}\n\nfunction providersOf(installations: readonly DetectedInstallation[]): Provider[] {\n return installations.map((installation) => installation.provider);\n}\n\n/**\n * A named provider is committed for the run; two installations and no flag call `onAmbiguous`\n * (the command's `this.error`); otherwise nothing happens.\n */\nexport async function refuseAnAmbiguousInstallation(\n cwd: string,\n subject: string,\n named: Provider | undefined,\n onAmbiguous: (message: string) => never,\n): Promise<void> {\n if (named !== undefined) {\n chooseProviderForThisRun(named);\n return;\n }\n\n const { scopeRoot, providers } = await installationsInPlay(cwd);\n if (providers.length <= 1) return;\n\n onAmbiguous(ambiguousInstallation(subject, providers, scopeRoot));\n}\n\n/** The non-refusing read the remedies hand a command out from, so they and the refusal agree. */\nexport async function providersInPlay(cwd: string): Promise<Provider[]> {\n return (await installationsInPlay(cwd)).providers;\n}\n\n/**\n * Which installation a handed-out acting command must name: the one the run named, else the choice\n * where two are in play, since a bare one refuses there.\n */\nexport async function installationToName(\n cwd: string,\n named: Provider | undefined,\n): Promise<Provider | Provider[] | undefined> {\n if (named !== undefined) return named;\n\n const providers = await providersInPlay(cwd);\n return providers.length > 1 ? providers : undefined;\n}\n\n/** The non-refusing form, for `doctor`. */\nexport async function ambiguityFinding(cwd: string): Promise<string | null> {\n const { scopeRoot, providers } = await installationsInPlay(cwd);\n if (providers.length <= 1) return null;\n\n return ambiguousInstallation(\"every command that acts on one\", providers, scopeRoot);\n}\n\n/** For `list`: names the other installation in the scope, or `null` when there is none. */\nexport async function otherInstallationsInThisScope(\n cwd: string,\n showing: Provider,\n): Promise<string | null> {\n const { scopeRoot, providers } = await installationsInPlay(cwd);\n const others = providers.filter((provider) => provider !== showing);\n if (others.length === 0) return null;\n\n return (\n `${scopeRoot} holds ${providers.length} installations — ${providers.join(\" and \")} — and this ` +\n `is the ${showing} one. Show another with --provider <${providers.join(\"|\")}>.`\n );\n}\n"],"mappings":";;;;;;;;;;;;AAKA,OAAO,QAAQ;AAEf,SAAS,aAAa;AAOf,SAAS,eAAe;AAC7B,SAAO,MAAM,OAAO;AAAA,IAClB,aAAa;AAAA,IACb,WAAW,IAAI,UAAU,KAAK,GAAG,CAAC;AAAA,IAClC,SAAS,CAAC,GAAG,SAAS;AAAA,EACxB,CAAC;AACH;AAGO,SAAS,gBAAgB,WAAqD;AACnF,MAAI,cAAc,OAAW,QAAO;AACpC,SAAO,UAAU,KAAK,CAAC,aAAa,aAAa,SAAS;AAC5D;AAEO,SAAS,uCAA+C;AAC7D,SACE,qJAC8D,UAAU,eACpE,kBAAkB;AAE1B;AAEA,SAAS,sBACP,SACA,WACA,WACQ;AACR,SACE,GAAG,SAAS,UAAU,UAAU,MAAM,yBAAoB,UAAU,KAAK,OAAO,CAAC,cAC9E,OAAO,6DAA6D,UAAU,KAAK,GAAG,CAAC;AAG9F;AAQA,eAAe,oBAAoB,KAA2C;AAC5E,QAAM,QAAQ,MAAM,oBAAoB,GAAG;AAC3C,QAAM,eAAe,QAAQ,OAAO,SAAS;AAE7C,MAAI,aAAa,SAAS,EAAG,QAAO,EAAE,WAAW,KAAK,WAAW,YAAY,YAAY,EAAE;AAC3F,SAAO,EAAE,WAAW,GAAG,QAAQ,GAAG,WAAW,YAAY,QAAQ,OAAO,QAAQ,CAAC,EAAE;AACrF;AAEA,SAAS,QACP,OACA,OACwB;AACxB,SAAO,MAAM,OAAO,CAAC,iBAAiB,aAAa,UAAU,KAAK;AACpE;AAEA,SAAS,YAAY,eAA4D;AAC/E,SAAO,cAAc,IAAI,CAAC,iBAAiB,aAAa,QAAQ;AAClE;AAMA,eAAsB,8BACpB,KACA,SACA,OACA,aACe;AACf,MAAI,UAAU,QAAW;AACvB,6BAAyB,KAAK;AAC9B;AAAA,EACF;AAEA,QAAM,EAAE,WAAW,UAAU,IAAI,MAAM,oBAAoB,GAAG;AAC9D,MAAI,UAAU,UAAU,EAAG;AAE3B,cAAY,sBAAsB,SAAS,WAAW,SAAS,CAAC;AAClE;AAGA,eAAsB,gBAAgB,KAAkC;AACtE,UAAQ,MAAM,oBAAoB,GAAG,GAAG;AAC1C;AAMA,eAAsB,mBACpB,KACA,OAC4C;AAC5C,MAAI,UAAU,OAAW,QAAO;AAEhC,QAAM,YAAY,MAAM,gBAAgB,GAAG;AAC3C,SAAO,UAAU,SAAS,IAAI,YAAY;AAC5C;AAGA,eAAsB,iBAAiB,KAAqC;AAC1E,QAAM,EAAE,WAAW,UAAU,IAAI,MAAM,oBAAoB,GAAG;AAC9D,MAAI,UAAU,UAAU,EAAG,QAAO;AAElC,SAAO,sBAAsB,kCAAkC,WAAW,SAAS;AACrF;AAGA,eAAsB,8BACpB,KACA,SACwB;AACxB,QAAM,EAAE,WAAW,UAAU,IAAI,MAAM,oBAAoB,GAAG;AAC9D,QAAM,SAAS,UAAU,OAAO,CAAC,aAAa,aAAa,OAAO;AAClE,MAAI,OAAO,WAAW,EAAG,QAAO;AAEhC,SACE,GAAG,SAAS,UAAU,UAAU,MAAM,yBAAoB,UAAU,KAAK,OAAO,CAAC,2BACvE,OAAO,uCAAuC,UAAU,KAAK,GAAG,CAAC;AAE/E;","names":[]}
@@ -10664,7 +10664,7 @@ var DISCOURAGED_PAIRS = Object.values(CATALOG.skillsById).flatMap(
10664
10664
 
10665
10665
  // ../matrix/src/seed.ts
10666
10666
  import { z as z3 } from "zod";
10667
- var SEED_VERSION = 6;
10667
+ var SEED_VERSION = 7;
10668
10668
  var seedModelSchema = z3.enum(["opus", "fable", "sonnet", "haiku"]);
10669
10669
  var seedEffortSchema = z3.enum([
10670
10670
  "low",
@@ -10692,6 +10692,8 @@ var seedAgentSchema = z3.object({
10692
10692
  });
10693
10693
  var MAX_EXTERNAL_SKILL_BYTES = 262144;
10694
10694
  var SKILL_MANIFEST = "SKILL.md";
10695
+ var PATH_SEPARATOR = /[/\\]/;
10696
+ var PARENT_DIRECTORY = "..";
10695
10697
  var treeBytes = (files) => {
10696
10698
  const encoder = new TextEncoder();
10697
10699
  return Object.values(files).reduce(
@@ -10699,10 +10701,19 @@ var treeBytes = (files) => {
10699
10701
  0
10700
10702
  );
10701
10703
  };
10704
+ var leavesItsDirectory = (key) => key.includes("\0") || key.split(PATH_SEPARATOR).includes(PARENT_DIRECTORY);
10702
10705
  var seedSkillTreeSchema = z3.record(z3.string().min(1), z3.string()).refine((files) => SKILL_MANIFEST in files, {
10703
10706
  message: `a skill directory must hold ${SKILL_MANIFEST}`
10704
10707
  }).refine((files) => treeBytes(files) <= MAX_EXTERNAL_SKILL_BYTES, {
10705
10708
  message: `a skill directory may not exceed ${String(MAX_EXTERNAL_SKILL_BYTES)} bytes`
10709
+ }).superRefine((files, ctx) => {
10710
+ for (const key of Object.keys(files).filter(leavesItsDirectory)) {
10711
+ ctx.addIssue({
10712
+ code: "custom",
10713
+ path: [key],
10714
+ message: "a skill directory's files must stay inside it, so no path may step through '..' or hold a null byte"
10715
+ });
10716
+ }
10706
10717
  });
10707
10718
  var seedExternalSkillSchema = z3.object({
10708
10719
  displayName: z3.string().min(1),
@@ -10724,6 +10735,8 @@ var seedPayloadSchema = z3.object({
10724
10735
  description: z3.string().exactOptional(),
10725
10736
  // As `--marketplace` takes it; absent is the public catalogue.
10726
10737
  marketplace: z3.string().exactOptional(),
10738
+ // Minted inside a project, whose run adds to the global install but changes nothing it holds.
10739
+ fromProject: z3.literal(true).exactOptional(),
10727
10740
  // Presence is selection.
10728
10741
  skills: z3.record(z3.string(), seedSkillSchema),
10729
10742
  // For ids no catalogue can resolve.
@@ -10741,7 +10754,6 @@ var isUnwritablePair = (agents, skillScope, agent) => {
10741
10754
  var unwritableSeedAssignments = (payload) => Object.entries(payload.skills).flatMap(
10742
10755
  ([skillId, skill]) => Object.keys(skill.assignments).filter((agent) => isUnwritablePair(payload.agents, skill.scope, agent)).map((agent) => ({ skillId, agent }))
10743
10756
  );
10744
- var PATH_SEPARATOR = /[/\\]/;
10745
10757
  var isControlCode = (code) => code <= 31 || code >= 127 && code <= 159;
10746
10758
  var holdsAControl = (id) => Array.from(id, (character) => character.charCodeAt(0)).some(isControlCode);
10747
10759
  var namesOneDirectory = (id) => id !== "" && id !== "." && id !== ".." && !PATH_SEPARATOR.test(id) && !holdsAControl(id);
@@ -10981,6 +10993,7 @@ function sourceDirName(provider) {
10981
10993
  }
10982
10994
 
10983
10995
  // src/cli/consts.ts
10996
+ import { isIPv4 } from "net";
10984
10997
  import os from "os";
10985
10998
  import path from "path";
10986
10999
  import { fileURLToPath } from "url";
@@ -11003,8 +11016,21 @@ function globalInstallRoot() {
11003
11016
  function cacheRoot() {
11004
11017
  return path.join(os.homedir(), ".cache", DEFAULT_PLUGIN_NAME);
11005
11018
  }
11019
+ var SEED_API_URL = process.env.AGENTS_INC_API_URL ?? "https://api.agentsinc.sh";
11006
11020
  var DEFAULT_EDITOR_URL = "https://agentsinc.sh/editor";
11007
- var EDITOR_URL = process.env.AGENTS_INC_EDITOR_URL ?? DEFAULT_EDITOR_URL;
11021
+ var LOCAL_EDITOR_URL = "http://localhost:5173/editor";
11022
+ var LOOPBACK_HOSTNAMES = ["localhost", "[::1]"];
11023
+ function isLoopbackIPv4(hostname) {
11024
+ return isIPv4(hostname) && hostname.startsWith("127.");
11025
+ }
11026
+ function runsOnThisMachine(address) {
11027
+ if (!URL.canParse(address)) return false;
11028
+ const { hostname } = new URL(address);
11029
+ return LOOPBACK_HOSTNAMES.includes(hostname) || isLoopbackIPv4(hostname);
11030
+ }
11031
+ var EDITOR_URL = runsOnThisMachine(SEED_API_URL) ? LOCAL_EDITOR_URL : DEFAULT_EDITOR_URL;
11032
+ var URL_SCHEME = /^https?:\/\//;
11033
+ var EDITOR_ADDRESS = EDITOR_URL.replace(URL_SCHEME, "");
11008
11034
  function editorConfigUrl(id) {
11009
11035
  return `${EDITOR_URL}/?fromId=${encodeURIComponent(id)}`;
11010
11036
  }
@@ -11047,7 +11073,9 @@ var UI_SYMBOLS = {
11047
11073
  CHECK: CHECK_GLYPH,
11048
11074
  CROSS: "\u2717",
11049
11075
  REMOVED: "-",
11050
- ADDED: "+"
11076
+ ADDED: "+",
11077
+ CHANGED: "~",
11078
+ OVERWRITTEN: "\u21BB"
11051
11079
  };
11052
11080
  var GITHUB_SOURCE = {
11053
11081
  HTTPS_PREFIX: "https://github.com/",
@@ -11170,7 +11198,9 @@ export {
11170
11198
  marketplaceManifestPath,
11171
11199
  globalInstallRoot,
11172
11200
  cacheRoot,
11201
+ SEED_API_URL,
11173
11202
  EDITOR_URL,
11203
+ EDITOR_ADDRESS,
11174
11204
  editorConfigUrl,
11175
11205
  SKILL_CATEGORIES_PATH,
11176
11206
  SKILL_RULES_PATH,
@@ -11199,4 +11229,4 @@ export {
11199
11229
  CLI_COLORS,
11200
11230
  ASCII_LOGO
11201
11231
  };
11202
- //# sourceMappingURL=chunk-A6OWEJGC.js.map
11232
+ //# sourceMappingURL=chunk-MHAQWMNJ.js.map