agents-inc 0.173.0 → 0.175.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 (88) hide show
  1. package/CHANGELOG.md +102 -0
  2. package/dist/{chunk-LJQXQTFC.js → chunk-37QFHJUW.js} +142 -13
  3. package/dist/chunk-37QFHJUW.js.map +1 -0
  4. package/dist/chunk-6HJVH27C.js +114 -0
  5. package/dist/chunk-6HJVH27C.js.map +1 -0
  6. package/dist/{chunk-ITQF35UQ.js → chunk-DQB3E2SX.js} +3 -3
  7. package/dist/{chunk-AARQBW5L.js → chunk-EGC7PNDI.js} +46 -32
  8. package/dist/chunk-EGC7PNDI.js.map +1 -0
  9. package/dist/{chunk-3N4FSTVX.js → chunk-EHEBN4NB.js} +2 -2
  10. package/dist/{chunk-EHJIQDXR.js → chunk-GNMRXXRY.js} +39 -40
  11. package/dist/chunk-GNMRXXRY.js.map +1 -0
  12. package/dist/{chunk-G7NUK3BF.js → chunk-ICHWAFAC.js} +29 -19
  13. package/dist/chunk-ICHWAFAC.js.map +1 -0
  14. package/dist/{chunk-Q4UNHVPX.js → chunk-MFCZARV2.js} +9 -9
  15. package/dist/chunk-MFCZARV2.js.map +1 -0
  16. package/dist/{chunk-SPQSNZMM.js → chunk-P5XEK7HC.js} +2 -2
  17. package/dist/{chunk-VR6QTK5Z.js → chunk-Q4NWATGH.js} +31 -27
  18. package/dist/chunk-Q4NWATGH.js.map +1 -0
  19. package/dist/{chunk-BRZA7ZCX.js → chunk-SI2LLEIR.js} +5 -5
  20. package/dist/{chunk-VSPC74SS.js → chunk-SNXEYAFP.js} +45 -30
  21. package/dist/chunk-SNXEYAFP.js.map +1 -0
  22. package/dist/{chunk-A3ZAXL5T.js → chunk-SRII2GMF.js} +3 -3
  23. package/dist/{chunk-7OG635DK.js → chunk-TG3SPPZY.js} +6 -2
  24. package/dist/{chunk-7OG635DK.js.map → chunk-TG3SPPZY.js.map} +1 -1
  25. package/dist/{chunk-MHAQWMNJ.js → chunk-U46LYYRA.js} +3 -6
  26. package/dist/{chunk-MHAQWMNJ.js.map → chunk-U46LYYRA.js.map} +1 -1
  27. package/dist/{chunk-3R3LHA4Q.js → chunk-XYBHH3M5.js} +2 -2
  28. package/dist/{chunk-F437ICEG.js → chunk-YLFKFVQP.js} +11 -11
  29. package/dist/chunk-YLFKFVQP.js.map +1 -0
  30. package/dist/{chunk-WVFBBZEP.js → chunk-YM3VEDAP.js} +698 -325
  31. package/dist/chunk-YM3VEDAP.js.map +1 -0
  32. package/dist/commands/build/marketplace.js +4 -4
  33. package/dist/commands/build/plugins.js +6 -6
  34. package/dist/commands/compile.js +16 -16
  35. package/dist/commands/compile.js.map +1 -1
  36. package/dist/commands/doctor.js +73 -78
  37. package/dist/commands/doctor.js.map +1 -1
  38. package/dist/commands/edit.js +84 -80
  39. package/dist/commands/edit.js.map +1 -1
  40. package/dist/commands/eject.js +27 -18
  41. package/dist/commands/eject.js.map +1 -1
  42. package/dist/commands/init.js +16 -18
  43. package/dist/commands/list.js +42 -18
  44. package/dist/commands/list.js.map +1 -1
  45. package/dist/commands/new/marketplace.js +4 -4
  46. package/dist/commands/search.js +9 -9
  47. package/dist/commands/share.js +13 -13
  48. package/dist/commands/share.js.map +1 -1
  49. package/dist/commands/uninstall.js +29 -27
  50. package/dist/commands/uninstall.js.map +1 -1
  51. package/dist/commands/update.js +17 -18
  52. package/dist/commands/update.js.map +1 -1
  53. package/dist/components/common/select-list.js +2 -2
  54. package/dist/components/common/skill-agent-summary.js +3 -3
  55. package/dist/components/common/summary-panel.js +4 -7
  56. package/dist/hooks/init.js +39 -26
  57. package/dist/hooks/init.js.map +1 -1
  58. package/dist/load-agent-defs-BJ4KBKBA.js +14 -0
  59. package/dist/{recompile-project-agents-6G6M2RS6.js → recompile-project-agents-2QTFMYDC.js} +8 -8
  60. package/dist/{source-loader-W7XCNKNA.js → source-loader-I6SWWDUF.js} +4 -4
  61. package/package.json +1 -1
  62. package/dist/chunk-2RTBSLSR.js +0 -82
  63. package/dist/chunk-2RTBSLSR.js.map +0 -1
  64. package/dist/chunk-AARQBW5L.js.map +0 -1
  65. package/dist/chunk-EHJIQDXR.js.map +0 -1
  66. package/dist/chunk-F437ICEG.js.map +0 -1
  67. package/dist/chunk-G7NUK3BF.js.map +0 -1
  68. package/dist/chunk-LJQXQTFC.js.map +0 -1
  69. package/dist/chunk-N33AKFLR.js +0 -24
  70. package/dist/chunk-N33AKFLR.js.map +0 -1
  71. package/dist/chunk-Q4UNHVPX.js.map +0 -1
  72. package/dist/chunk-Q6WRR4BN.js +0 -195
  73. package/dist/chunk-Q6WRR4BN.js.map +0 -1
  74. package/dist/chunk-VR6QTK5Z.js.map +0 -1
  75. package/dist/chunk-VSPC74SS.js.map +0 -1
  76. package/dist/chunk-WVFBBZEP.js.map +0 -1
  77. package/dist/components/common/scroll-affordance.js +0 -9
  78. package/dist/load-agent-defs-E67DSYTN.js +0 -14
  79. package/dist/source-loader-W7XCNKNA.js.map +0 -1
  80. /package/dist/{chunk-ITQF35UQ.js.map → chunk-DQB3E2SX.js.map} +0 -0
  81. /package/dist/{chunk-3N4FSTVX.js.map → chunk-EHEBN4NB.js.map} +0 -0
  82. /package/dist/{chunk-SPQSNZMM.js.map → chunk-P5XEK7HC.js.map} +0 -0
  83. /package/dist/{chunk-BRZA7ZCX.js.map → chunk-SI2LLEIR.js.map} +0 -0
  84. /package/dist/{chunk-A3ZAXL5T.js.map → chunk-SRII2GMF.js.map} +0 -0
  85. /package/dist/{chunk-3R3LHA4Q.js.map → chunk-XYBHH3M5.js.map} +0 -0
  86. /package/dist/{components/common/scroll-affordance.js.map → load-agent-defs-BJ4KBKBA.js.map} +0 -0
  87. /package/dist/{recompile-project-agents-6G6M2RS6.js.map → recompile-project-agents-2QTFMYDC.js.map} +0 -0
  88. /package/dist/{load-agent-defs-E67DSYTN.js.map → source-loader-I6SWWDUF.js.map} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli/commands/init.tsx","../src/cli/lib/permission-checker.tsx"],"sourcesContent":["import os from \"os\";\nimport React from \"react\";\n\nimport { Flags, type Interfaces } from \"@oclif/core\";\nimport { Box, Text, useApp } from \"ink\";\nimport { partition } from \"remeda\";\nimport { render } from \"../components/render.js\";\n\nimport { BaseCommand } from \"../base-command.js\";\nimport type { InstallSelection } from \"@workspace/compile/seed-to-config\";\nimport { useTerminalDimensions } from \"../components/hooks/use-terminal-dimensions.js\";\nimport { stoppingOnARefusal, type SourceLoadResult } from \"../lib/loading/index.js\";\nimport {\n loadSource,\n sayCapturedWarnings,\n loadAgentDefs,\n copyLocalSkills,\n writeProjectConfig,\n compileAgentsAllScopes,\n compileProjectScope,\n type CompilationResult,\n type ConfigWriteResult,\n type SkillCopyResult,\n discoverInstalledSkills,\n} from \"../lib/operations/index.js\";\nimport { movedGlobalAgentInputs, type GateReport } from \"../lib/config-gate/index.js\";\nimport { fetchSeedConfig } from \"../lib/seed/fetch-seed.js\";\nimport {\n registerExternalSkills,\n writeExternalSkills,\n type ExternalSkillInstall,\n} from \"../lib/seed/external-skills.js\";\nimport { seedToInstallSelection, type SeedMapping } from \"../lib/seed/seed-to-selection.js\";\nimport {\n holdInstalledGlobal,\n installsAtHome,\n joinedStatement,\n notInstalledGlobally,\n panelRowEntries,\n readInstalledGlobal,\n type HeldGlobal,\n type InstalledGlobal,\n} from \"../lib/seed/seed-apply.js\";\nimport { agentChangesAmong, type AgentChange } from \"../lib/configuration/scope-diff.js\";\nimport { isActiveAt } from \"../lib/configuration/scope-predicates.js\";\nimport { summaryPanelBlock, type SummaryPanelProps } from \"../components/common/summary-panel.js\";\nimport {\n getInstallationsByProvider,\n type ProviderInstallation,\n} from \"../lib/plugins/plugin-info.js\";\nimport {\n assertNamedSourceUsable,\n isLocalSource,\n resolveBranding,\n} from \"../lib/configuration/config.js\";\nimport {\n type InstallMode,\n detectInstallation,\n detectProjectInstallation,\n deriveInstallMode,\n holdsItsOwnInstallation,\n resolveInstallPaths,\n buildAgentScopeMap,\n isHomeDirectory,\n INSTALL_MODE_LABELS,\n INSTALL_MODE_DESCRIPTIONS,\n} from \"../lib/installation/index.js\";\nimport { hostAt } from \"../lib/hosts/host-for.js\";\nimport {\n agentCodec,\n chooseProviderForThisRun,\n providerAtScope,\n providerInUse,\n relativeConfigPath,\n} from \"../lib/installation/install-layout.js\";\nimport { providerToNameAt } from \"../lib/installation/provider-to-name.js\";\nimport { hostCompileNotices } from \"../lib/hosts/host-compile-notices.js\";\nimport {\n installationToName,\n providerFlag,\n providerNamedBy,\n providerNeedsAConfigurationToInstall,\n} from \"../lib/installation/provider-flag.js\";\nimport { checkPermissions } from \"../lib/permission-checker.js\";\nimport {\n ASCII_LOGO,\n CLI_INVOKE_COMMAND,\n DEFAULT_BRANDING,\n EDITOR_ADDRESS,\n EDITOR_URL,\n EJECT_SOURCE,\n editorConfigUrl,\n type Provider,\n} from \"../consts.js\";\nimport { clearTerminalScreen } from \"../utils/terminal.js\";\nimport { SelectList, type SelectListItem } from \"../components/common/select-list.js\";\nimport { promptConfirm, promptValue } from \"../components/common/prompt-confirm.js\";\nimport { Confirm } from \"../components/common/confirm.js\";\nimport { getErrorMessage } from \"../utils/errors.js\";\nimport { EXIT_CODES } from \"../lib/exit-codes.js\";\nimport { openUrl } from \"../utils/open-url.js\";\nimport { plural } from \"../utils/string.js\";\nimport type {\n AgentName,\n AgentScopeConfig,\n MergedSkillsMatrix,\n SkillConfig,\n SkillId,\n SkillScope,\n} from \"../types/index.js\";\nimport { type StartupMessage } from \"../utils/logger.js\";\nimport {\n ERROR_MESSAGES,\n INCOMPLETE_WORK_RECOVERY,\n SHARED_CONFIG_ARRIVALS,\n STATUS_MESSAGES,\n addMarketplaceInTheEditor,\n agentsNotCompiled,\n applySharedConfigHere,\n carriedSkillsWritten,\n globalScopedAgentsHint,\n initSucceeded,\n keptAsInstalledGlobally,\n sharedConfigExistingInstall,\n subAgentChanged,\n} from \"../utils/messages.js\";\nimport type { SeedPayload } from \"@workspace/matrix/seed\";\n\nconst DASHBOARD_OPTIONS = [\n { label: \"Edit in the web editor\", value: \"edit\" },\n { label: \"Compile\", value: \"compile\" },\n { label: \"Doctor\", value: \"doctor\" },\n { label: \"List\", value: \"list\" },\n] as const satisfies readonly SelectListItem<string>[];\n\nconst DASHBOARD_OPTIONS_LINE = ` ${DASHBOARD_OPTIONS.map(({ label }) => `[${label}]`).join(\" \")}`;\n\ntype DashboardCommand = (typeof DASHBOARD_OPTIONS)[number][\"value\"];\n\n/** A white-labelled name replaces the logo, because the logo spells the shipped name. */\nconst DashboardTitle: React.FC<{ name: string }> = ({ name }) =>\n name === DEFAULT_BRANDING.NAME ? <Text>{ASCII_LOGO}</Text> : <Text bold>{name}</Text>;\n\ntype DashboardProps = {\n data: DashboardData;\n onSelect: (command: DashboardCommand) => void;\n onCancel: () => void;\n};\n\nexport const Dashboard: React.FC<DashboardProps> = ({ data, onSelect, onCancel }) => {\n const { exit } = useApp();\n const { rows: terminalHeight } = useTerminalDimensions();\n\n return (\n <Box flexDirection=\"column\" height={terminalHeight}>\n <Box marginBottom={1}>\n <DashboardTitle name={data.name} />\n </Box>\n <Box marginBottom={1}>\n <Text>{dashboardCountLines(data).join(\"\\n\")}</Text>\n </Box>\n <SelectList\n items={DASHBOARD_OPTIONS}\n onSelect={(command) => {\n onSelect(command);\n exit();\n }}\n onCancel={() => {\n onCancel();\n exit();\n }}\n />\n </Box>\n );\n};\n\n/**\n * Shared by the TTY and piped dashboards so the two cannot drift apart. A scope holding two\n * installations gets a named block for each, a blank line apart.\n */\nfunction dashboardCountLines({ installations }: DashboardData): string[] {\n const named = installations.length > 1;\n const blocks = installations.map((installation) => [\n ...(named ? [` Provider: ${installation.provider}`] : []),\n ...installationCountLines(installation),\n ]);\n return blankLineBetween(blocks);\n}\n\nfunction blankLineBetween(blocks: string[][]): string[] {\n return blocks.flatMap((block, index) => (index === 0 ? block : [\"\", ...block]));\n}\n\nfunction installationCountLines(installation: ProviderInstallation): string[] {\n return [\n ` Skills: ${installation.skillCount} installed`,\n ` Agents: ${installation.agentCount} compiled`,\n ` Mode: ${INSTALL_MODE_LABELS[installation.mode]}`,\n ...(installation.marketplace ? [` Marketplace: ${installation.marketplace}`] : []),\n ];\n}\n\nexport function formatDashboardText(data: DashboardData): string {\n return [data.name, \"\", ...dashboardCountLines(data), \"\", DASHBOARD_OPTIONS_LINE].join(\"\\n\");\n}\n\n/** Ctrl+C cancels the run; Escape (null) only leaves the dashboard. */\nconst DASHBOARD_INTERRUPTED = \"interrupted\";\n\ntype DashboardAnswer = DashboardCommand | typeof DASHBOARD_INTERRUPTED | null;\n\nasync function showDashboard(\n projectDir: string,\n log?: (message: string) => void,\n): Promise<DashboardAnswer> {\n const data = await getDashboardData(projectDir);\n\n if (!process.stdin.isTTY) {\n const output = log ?? console.log;\n output(formatDashboardText(data));\n return null;\n }\n\n // clearOnResolve repaints a clean terminal before unmount: the dashboard fills the height.\n const selectedCommand = await promptValue<DashboardAnswer>(\n (resolve) => (\n <Dashboard\n data={data}\n onSelect={(command) => resolve(command)}\n onCancel={() => resolve(null)}\n />\n ),\n { onExit: DASHBOARD_INTERRUPTED, clearOnResolve: true },\n );\n\n clearTerminalScreen();\n\n return selectedCommand;\n}\n\nfunction dashboardCommandArgv(command: DashboardCommand): string[] {\n return command === \"edit\" ? [\"--ui\"] : [];\n}\n\nexport type DashboardFlow = \"not-installed\" | \"shown\" | \"cancelled\";\n\n/** Never exits the process: callers decide from the {@link DashboardFlow} it answers. */\nexport async function runDashboardFlow(\n projectDir: string,\n config: Interfaces.Config,\n log?: (message: string) => void,\n): Promise<DashboardFlow> {\n const installation = await detectInstallation(projectDir);\n if (!installation) return \"not-installed\";\n\n const selectedCommand = await showDashboard(projectDir, log);\n if (selectedCommand === DASHBOARD_INTERRUPTED) return \"cancelled\";\n if (selectedCommand) {\n await config.runCommand(selectedCommand, dashboardCommandArgv(selectedCommand));\n }\n return \"shown\";\n}\n\n/** A required key, not `?`: oclif writes the key as `undefined` when the flag is not passed. */\ntype SourceFlags = { marketplace: string | undefined };\n\ntype Selection = {\n result: InstallSelection;\n sourceResult: SourceLoadResult;\n /** Where the selection was actually loaded from; a shared id may name a marketplace. */\n sourceFlags: SourceFlags;\n /** A global install's own skills, recorded as they are and never installed over. */\n installedAlready: ReadonlySet<SkillId>;\n};\n\n/** The payload names the marketplace because a skill id never says where its repository lives. */\nfunction sharedConfigSourceFlags(flags: SourceFlags, payload: SeedPayload): SourceFlags {\n return { marketplace: flags.marketplace ?? payload.marketplace };\n}\n\nexport default class Init extends BaseCommand {\n /** Resolved once in {@link install}; the closing line is printed several calls below. */\n private brandingName: string = DEFAULT_BRANDING.NAME;\n\n static summary = `Initialize ${DEFAULT_BRANDING.NAME} in this project`;\n static description = `Build a configuration in ${EDITOR_ADDRESS}, or install one by id with --from. Over an existing installation, shows its dashboard.`;\n\n static examples = [\n {\n description: \"Open the editor to build a configuration\",\n command: \"<%= config.bin %> <%= command.id %>\",\n },\n {\n description: \"Install a configuration built in the editor\",\n command: \"<%= config.bin %> <%= command.id %> --from <id>\",\n },\n {\n description: \"Test local marketplace changes against a configuration built in the editor\",\n command: \"<%= config.bin %> <%= command.id %> --from <id> --marketplace ./my-marketplace\",\n },\n ];\n\n static flags = {\n marketplace: Flags.string({\n char: \"m\",\n description:\n \"With --from, install from this marketplace instead of the one the configuration names. Without --from, open the editor and say how to add it there\",\n required: false,\n }),\n from: Flags.string({\n description: \"Install a configuration shared from agentsinc.sh by its id\",\n helpValue: \"<id>\",\n }),\n ui: Flags.boolean({\n description: `Open ${EDITOR_ADDRESS} on the id --from names, or on the catalogue — what a bare init does where nothing is installed`,\n default: false,\n }),\n provider: providerFlag(),\n };\n\n /** The exit code is decided once, after every path through {@link install} has ended. */\n async run(): Promise<void> {\n await this.install();\n this.exitIfWorkIncomplete();\n }\n\n /** The link is printed before it is opened, so it still works where no browser can open. */\n private async openEditor(\n projectDir: string,\n provider: Provider | undefined,\n id?: string,\n marketplace?: string,\n ): Promise<void> {\n const url = id === undefined ? EDITOR_URL : editorConfigUrl(id);\n // Above the first line, so a ref the install route would refuse is refused before any output.\n const marketplaceLine =\n marketplace === undefined ? undefined : this.addMarketplaceLineOrFail(marketplace);\n\n const installedHere = await holdsItsOwnInstallation(projectDir);\n const toName = installedHere ? await installationToName(projectDir, provider) : provider;\n\n this.log(id === undefined ? `Build it at ${url}` : `Open it at ${url}`);\n if (marketplaceLine !== undefined) this.log(marketplaceLine);\n this.log(applySharedConfigHere(id, installedHere, toName));\n\n if (!process.stdin.isTTY) return;\n\n const opened = await openUrl(url);\n if (!opened.ok) this.warn(opened.error);\n }\n\n private async install(): Promise<void> {\n const { flags } = await this.parse(Init);\n const projectDir = process.cwd();\n\n // First, so a refused `--provider` leaves the filesystem untouched at both scopes.\n this.settleTheProviderForThisRun(flags);\n\n // Before `ensureConfigReadable`: a broken config must not block the editor route.\n if (opensTheEditor(flags)) {\n return this.openEditor(\n projectDir,\n providerNamedBy(flags.provider),\n flags.from,\n flags.marketplace,\n );\n }\n\n // ABORT: an unreadable config is refused here, before any route reads it.\n await this.ensureConfigReadable(projectDir);\n\n if (flags.from === undefined) return this.showDashboardOrOpenEditor(projectDir);\n\n // Its degrade arm cannot fire: `ensureConfigReadable` already refused every unreadable config.\n this.brandingName = await this.resolveBrandingName(projectDir);\n\n const selection = await this.selectionFromSharedConfig(flags.from, flags, projectDir);\n if (!selection) this.exit(EXIT_CODES.CANCELLED);\n\n this.reportValidationErrors(selection.result.validation);\n\n await this.handleInstallation(selection, projectDir);\n }\n\n private async showDashboardOrOpenEditor(projectDir: string): Promise<void> {\n const dashboard = await runDashboardFlow(projectDir, this.config, (msg) => this.log(msg));\n switch (dashboard) {\n case \"cancelled\":\n return this.error(\"Cancelled\", { exit: EXIT_CODES.CANCELLED });\n case \"not-installed\":\n return this.openEditor(projectDir, undefined);\n case \"shown\":\n return;\n default: {\n const _exhaustive: never = dashboard;\n return _exhaustive;\n }\n }\n }\n\n /** Refused as the install route refuses it, since the line echoes the ref it was given. */\n private addMarketplaceLineOrFail(ref: string): string {\n try {\n assertNamedSourceUsable(ref);\n return addMarketplaceInTheEditor(ref, isLocalSource(ref));\n } catch (error) {\n this.handleError(error);\n }\n }\n\n /** `--provider` only picks which folder an install creates, so it needs `--from`. */\n private settleTheProviderForThisRun(flags: Interfaces.InferredFlags<typeof Init.flags>): void {\n const named = providerNamedBy(flags.provider);\n if (named === undefined) return;\n\n if (flags.from === undefined) {\n this.error(providerNeedsAConfigurationToInstall(), { exit: EXIT_CODES.INVALID_ARGS });\n }\n\n chooseProviderForThisRun(named);\n }\n\n /** Every refusal fires before anything is written. */\n private async selectionFromSharedConfig(\n id: string,\n flags: SourceFlags,\n projectDir: string,\n ): Promise<Selection | null> {\n await this.refuseInstalledProject(projectDir, id);\n\n const payload = await this.fetchSharedConfigOrFail(id);\n const sourceFlags = sharedConfigSourceFlags(flags, payload);\n const { sourceResult, startupMessages } = await this.loadSourceOrFail(sourceFlags, projectDir);\n // Before the decode, which would otherwise skip carried skills as unknown ids.\n const carriedSkills = this.registerExternalSkillsOrFail(\n payload,\n sourceResult.matrix,\n projectDir,\n );\n const mapping = this.decodeSeedOrFail(payload, sourceResult.matrix);\n const { result } = mapping;\n\n // Nothing is installed here: `refuseInstalledProject` has already refused a home that holds one.\n this.refuseProjectScopedContentAtHome(result, projectDir, false);\n\n const installedGlobal = await installedGlobalToHold(projectDir);\n const held = holdInstalledGlobal(result, installedGlobal);\n const arrivingCarried = notInstalledGlobally(carriedSkills, held);\n\n // Above the lists: a yes installs what was listed, so nothing listed may then be refused.\n await this.refuseSharedConfigBeforeAsking(\n held.result,\n arrivingCarried,\n projectDir,\n sourceResult,\n );\n\n // Above the skips: a skill that could not load is skipped under the warning saying why.\n sayCapturedWarnings(startupMessages);\n this.warnOfSkippedEntries(mapping, sourceResult.unloadedSkillIds);\n this.refuseAnEmptySelection(held.result, id);\n\n const stackName = await this.stackNameOf(result.selectedStackId, sourceResult);\n this.logWhatGoesWhere(held, installedGlobal, stackName, {\n id: installsAtHome(result) ? id : undefined,\n provider: providerToNameAt(os.homedir(), providerInUse(projectDir)),\n });\n if (process.stdin.isTTY && !(await this.confirmInstall())) {\n this.log(\"Setup cancelled\");\n return null;\n }\n\n // After the question, so a refusal or a no leaves nothing written.\n await this.writeCarriedSkills(arrivingCarried);\n this.announceArrivingSkills(held, result.selectedAgents.length);\n\n return {\n result: held.result,\n sourceResult,\n sourceFlags,\n installedAlready: new Set(held.installed.skillIds),\n };\n }\n\n /**\n * The panel where the question is asked, or where it would be: the project against the whole\n * global install it inherits. `runFromHome.id` is the id only where home would take it.\n */\n private logWhatGoesWhere(\n held: HeldGlobal,\n installedGlobal: InstalledGlobal | null,\n stackName: string | undefined,\n runFromHome: RunFromHome,\n ): void {\n const joined = joinedGlobalAgents(held, installedGlobal);\n const lines = summaryPanelBlock(\n installPanel(held, installedGlobal, joined, stackName),\n joined.map(subAgentChanged),\n [...joinedStatement(held), ...keptAsInstalledStatement(held, runFromHome)],\n );\n for (const line of lines) {\n this.log(line);\n }\n }\n\n private refuseAnEmptySelection(result: InstallSelection, id: string): void {\n if (!selectsNothing(result)) return;\n\n this.error(`Configuration '${id}' contains no skills this catalog can install.`, {\n exit: EXIT_CODES.ERROR,\n });\n }\n\n private announceArrivingSkills(held: HeldGlobal, agentCount: number): void {\n const arriving = notInstalledGlobally(held.result.skills, held);\n if (arriving.length === 0) return;\n\n this.log(`Installing ${arriving.length} skill(s) across ${agentCount} sub-agent(s)\\n`);\n }\n\n private async confirmInstall(): Promise<boolean> {\n const outcome = await promptConfirm(({ onConfirm, onCancel }) => (\n <Confirm\n message={SHARED_CONFIG_ARRIVALS.INSTALL_CONFIRM}\n onConfirm={onConfirm}\n onCancel={onCancel}\n />\n ));\n return outcome === \"confirmed\";\n }\n\n /** Project-scoped: `detectInstallation`'s global fallback would refuse every clean project. */\n private async refuseInstalledProject(projectDir: string, id: string): Promise<void> {\n const installation = await detectProjectInstallation(projectDir);\n if (!installation) return;\n\n const provider = providerToNameAt(projectDir, providerInUse(projectDir));\n this.error(sharedConfigExistingInstall(installation.configPath, id, provider), {\n exit: EXIT_CODES.ERROR,\n });\n }\n\n private async fetchSharedConfigOrFail(id: string): Promise<SeedPayload> {\n this.log(`Fetching configuration ${id}...`);\n const fetched = await fetchSeedConfig(id);\n if (!fetched.ok) {\n this.error(fetched.error, { exit: EXIT_CODES.ERROR });\n }\n return fetched.payload;\n }\n\n private decodeSeedOrFail(payload: SeedPayload, matrix: MergedSkillsMatrix): SeedMapping {\n try {\n return seedToInstallSelection(payload, matrix);\n } catch (error) {\n this.handleError(error);\n }\n }\n\n private registerExternalSkillsOrFail(\n payload: SeedPayload,\n matrix: MergedSkillsMatrix,\n projectDir: string,\n ): ExternalSkillInstall[] {\n try {\n return registerExternalSkills(payload, matrix, projectDir);\n } catch (error) {\n this.handleError(error);\n }\n }\n\n private async writeCarriedSkills(carried: ExternalSkillInstall[]): Promise<void> {\n if (carried.length === 0) return;\n\n await writeExternalSkills(carried);\n this.log(carriedSkillsWritten(carried.map((skill) => skill.id)));\n }\n\n private async loadSourceOrFail(\n flags: SourceFlags,\n projectDir: string,\n ): Promise<{ sourceResult: SourceLoadResult; startupMessages: StartupMessage[] }> {\n try {\n const loaded = await stoppingOnARefusal(() =>\n loadSource({\n // The one load that may choose a marketplace rather than read the stored one.\n caller: \"init\",\n ...(flags.marketplace !== undefined && { sourceFlag: flags.marketplace }),\n projectDir,\n captureStartupMessages: true,\n }),\n );\n return { sourceResult: loaded.sourceResult, startupMessages: loaded.startupMessages };\n } catch (error) {\n this.error(getErrorMessage(error), {\n exit: EXIT_CODES.ERROR,\n });\n }\n }\n\n private async handleInstallation(\n { result, sourceResult, sourceFlags, installedAlready }: Selection,\n projectDir: string,\n ): Promise<void> {\n const plan = planInstall(result, installedAlready);\n this.logInstallPlan(plan);\n\n // Before any copy, so a failed resolution cannot leave a half-install with no config.ts.\n const resolvedMarketplace = await this.marketplaceForPluginSkills(\n plan.pluginSkills,\n sourceResult,\n projectDir,\n );\n\n const copyResult = await this.copyEjectedSkills(plan, projectDir, sourceResult);\n\n if (resolvedMarketplace !== null) {\n await this.installPluginSkillsReported(\n plan.pluginSkills,\n resolvedMarketplace,\n projectDir,\n sourceResult.matrix,\n );\n }\n\n try {\n const written = await this.writeConfigAndCompile(\n result,\n sourceResult,\n sourceFlags,\n projectDir,\n );\n this.reportSuccess(written, copyResult, projectDir);\n\n await this.showPermissionNotice(projectDir);\n } catch (error) {\n this.handleError(error);\n }\n }\n\n private async marketplaceForPluginSkills(\n pluginSkills: InstallSelection[\"skills\"],\n sourceResult: SourceLoadResult,\n projectDir: string,\n ): Promise<string | null> {\n if (pluginSkills.length === 0) return null;\n\n return this.requireMarketplaceOrExit(\n sourceResult,\n \"install plugin skills\",\n hostAt(projectDir),\n (marketplace) => this.log(`Registering marketplace \"${marketplace}\"...`),\n );\n }\n\n /** One frame, then unmount: the notice has no exit of its own and `--from` must run headless. */\n private async showPermissionNotice(projectDir: string): Promise<void> {\n const permissionWarning = await checkPermissions(projectDir);\n if (!permissionWarning) return;\n\n const { unmount } = render(permissionWarning);\n unmount();\n }\n\n private logInstallPlan(plan: InstallPlan): void {\n this.log(\"\\n\");\n this.log(`Selected ${plural(plan.ejectedSkills.length + plan.pluginSkills.length, \"skill\")}`);\n this.log(`Install mode: ${installModeDescription(plan)}`);\n }\n\n private async copyEjectedSkills(\n { ejectedSkills, installMode }: InstallPlan,\n projectDir: string,\n sourceResult: SourceLoadResult,\n ): Promise<SkillCopyResult | null> {\n if (ejectedSkills.length === 0) return null;\n\n this.log(\"Copying skills to local directory...\");\n const copyResult = await copyLocalSkills(ejectedSkills, projectDir, sourceResult);\n this.log(skillsCopiedLine(copyResult, installMode, projectDir));\n return copyResult;\n }\n\n private async writeConfigAndCompile(\n result: InstallSelection,\n sourceResult: SourceLoadResult,\n flags: SourceFlags,\n projectDir: string,\n ): Promise<WrittenInstall> {\n const configResult = await this.writeConfigReported(result, sourceResult, flags, projectDir);\n const agentScopeMap = buildAgentScopeMap(configResult.config);\n const compileResult = await this.compileInstalledAgents(\n configResult.propagation,\n agentScopeMap,\n projectDir,\n );\n this.reportCompilation(compileResult);\n await this.reportWhatThisHostCannotCarry(projectDir);\n\n this.reportFanOut(configResult.propagation);\n\n return { configResult, compileResult, agentScopeMap };\n }\n\n private async writeConfigReported(\n result: InstallSelection,\n sourceResult: SourceLoadResult,\n flags: SourceFlags,\n projectDir: string,\n ): Promise<ConfigWriteResult> {\n this.log(\"Generating configuration...\");\n const configResult = await writeProjectConfig({\n selection: result,\n sourceResult,\n projectDir,\n ...(flags.marketplace !== undefined && { sourceFlag: flags.marketplace }),\n });\n\n if (configResult.wasMerged) {\n this.log(`Merged with existing config at ${configResult.existingConfigPath}`);\n }\n\n this.log(`Configuration saved (${plural(configResult.config.agents.length, \"agent\")})\\n`);\n this.reportUnassignedSkills(configResult.config, result.skills);\n return configResult;\n }\n\n private async compileInstalledAgents(\n written: GateReport,\n agentScopeMap: Map<AgentName, SkillScope>,\n projectDir: string,\n ): Promise<CompilationResult> {\n this.log(STATUS_MESSAGES.COMPILING_AGENTS);\n // Sequential: both can reject and discovery warns, so the order decides what the user reads.\n const agentDefs = await loadAgentDefs();\n const { allSkills } = await discoverInstalledSkills(projectDir);\n const compile = compilesGlobalScope(projectDir, written)\n ? compileAgentsAllScopes\n : compileProjectScope;\n return compile({\n projectDir,\n sourcePath: agentDefs.sourcePath,\n skills: allSkills,\n agentScopeMap,\n });\n }\n\n private async reportWhatThisHostCannotCarry(projectDir: string): Promise<void> {\n for (const notice of await hostCompileNotices(providerInUse(projectDir), projectDir)) {\n this.log(notice);\n }\n }\n\n /**\n * Failures are recorded rather than aborted on: the skills and config are already written, and\n * {@link BaseCommand.exitIfWorkIncomplete} answers for them.\n */\n private reportCompilation(compileResult: CompilationResult): void {\n const { compiled, failed, warnings } = compileResult;\n const summary = `Compiled ${plural(compiled.length, \"agent\")}`;\n\n if (failed.length === 0) {\n this.log(`${summary}\\n`);\n return;\n }\n\n this.log(`${summary} (${failed.length} failed)\\n`);\n for (const warning of warnings) {\n this.warn(warning);\n }\n // Off `failed`, not `warnings`: warnings also carry entries that are not failures.\n this.recordIncompleteWork(agentsNotCompiled(failed), INCOMPLETE_WORK_RECOVERY.RECOMPILE);\n }\n\n private reportSuccess(\n { configResult, compileResult, agentScopeMap }: WrittenInstall,\n copyResult: SkillCopyResult | null,\n projectDir: string,\n ): void {\n // A run with work owed ends on the failure account instead of claiming success.\n if (!this.hasIncompleteWork) this.log(`${initSucceeded(this.brandingName)}\\n`);\n\n if (copyResult !== null && copyResult.totalCopied > 0) {\n this.logDirectoryBlocks(\"Skills copied to:\", skillsCopiedBlocks(projectDir, copyResult));\n }\n this.logDirectoryBlocks(\n \"Agents compiled to:\",\n agentsCompiledBlocks(projectDir, compileResult.compiled, agentScopeMap),\n );\n this.reportConfiguration(configResult, agentScopeMap, projectDir);\n }\n\n private reportConfiguration(\n { configPath, propagation }: ConfigWriteResult,\n agentScopeMap: Map<AgentName, SkillScope>,\n projectDir: string,\n ): void {\n const paths = {\n global: resolveInstallPaths(projectDir, \"global\").configPath,\n project: configPath,\n };\n const split = splitAgentScopes(projectDir, agentScopeMap);\n\n this.log(\"Configuration:\");\n for (const written of configsWritten(projectDir, paths, propagation.globalWritten)) {\n this.log(` ${written}`);\n }\n this.log(\"\");\n\n this.log(\"To customize agent-skill assignments:\");\n for (const [index, step] of customizationSteps(split, paths.global, projectDir).entries()) {\n this.log(` ${index + 1}. ${step}`);\n }\n this.log(\"\");\n }\n\n private logDirectoryBlocks(heading: string, blocks: DirectoryBlock[]): void {\n for (const { dir, entries } of blocks) {\n this.log(heading);\n this.log(` ${dir}`);\n for (const entry of entries) {\n this.log(` ${entry}`);\n }\n this.log(\"\");\n }\n }\n}\n\n/** The editor is where a marketplace is added, so `--marketplace` without `--from` opens it. */\nfunction opensTheEditor(\n flags: Pick<Interfaces.InferredFlags<typeof Init.flags>, \"ui\" | \"from\" | \"marketplace\">,\n): boolean {\n return flags.ui || (flags.from === undefined && flags.marketplace !== undefined);\n}\n\n/** A sub-agent is installable without skills, so only a selection with neither is empty. */\nfunction selectsNothing(result: InstallSelection): boolean {\n return result.skills.length === 0 && result.selectedAgents.length === 0;\n}\n\n/** At the home root the global config is the project's own, so there is no global install apart. */\nasync function installedGlobalToHold(projectDir: string): Promise<InstalledGlobal | null> {\n if (isHomeDirectory(projectDir)) return null;\n return await readInstalledGlobal(projectDir);\n}\n\n/** The run from home that changes what a project run keeps, where home would take it. */\ntype RunFromHome = { id: string | undefined; provider: Provider | undefined };\n\nfunction keptAsInstalledStatement(held: HeldGlobal, runFromHome: RunFromHome): string[] {\n const { skillIds, agentNames } = held.keptAsInstalled;\n if (skillIds.length === 0 && agentNames.length === 0) return [];\n return [\n keptAsInstalledGlobally(\n skillIds,\n agentNames,\n runFromHome.id,\n runFromHome.provider,\n panelRowEntries(held),\n ),\n ];\n}\n\ntype GlobalEntries = { skills: SkillConfig[]; agents: AgentScopeConfig[] };\n\n/** What the project inherits that the configuration leaves unnamed: a project config copies it all. */\nfunction inheritedGlobal(held: HeldGlobal, installedGlobal: InstalledGlobal | null): GlobalEntries {\n if (installedGlobal === null) return { skills: [], agents: [] };\n\n const namedSkills = new Set(held.result.skills.filter(isGlobal).map(({ id }) => id));\n const namedAgents = new Set(held.result.agentConfigs.filter(isGlobal).map(({ name }) => name));\n return {\n skills: installedGlobal.skills.filter((skill) => isGlobal(skill) && !namedSkills.has(skill.id)),\n agents: installedGlobal.agents.filter(\n (agent) => isGlobal(agent) && !namedAgents.has(agent.name),\n ),\n };\n}\n\nfunction isGlobal(entry: SkillConfig | AgentScopeConfig): boolean {\n return isActiveAt(entry, \"global\");\n}\n\n/** Measured against the global install: the project changes nothing else of it. */\nfunction installPanel(\n held: HeldGlobal,\n installedGlobal: InstalledGlobal | null,\n joined: AgentChange[],\n stackName: string | undefined,\n): SummaryPanelProps {\n const inherited = inheritedGlobal(held, installedGlobal);\n return {\n skillConfigs: [...held.result.skills, ...inherited.skills],\n agentConfigs: [...held.result.agentConfigs, ...inherited.agents],\n installedSkillConfigs: installedGlobal?.skills ?? null,\n installedAgentConfigs: installedGlobal?.agents ?? null,\n isInitMode: true,\n changedAgentNames: new Set(joined.map(({ name }) => name)),\n stackName,\n };\n}\n\n/** The held global sub-agents an arriving skill's row joins, against their installed rows. */\nfunction joinedGlobalAgents(\n held: HeldGlobal,\n installedGlobal: InstalledGlobal | null,\n): AgentChange[] {\n if (installedGlobal === null) return [];\n\n return agentChangesAmong(\n held.joined.map(({ agentName }) => agentName),\n installedGlobal,\n {\n agents: held.result.agentConfigs,\n skills: held.result.skills,\n stack: held.result.assignedStack,\n },\n );\n}\n\ntype InstallPlan = {\n installMode: InstallMode;\n ejectedSkills: InstallSelection[\"skills\"];\n pluginSkills: InstallSelection[\"skills\"];\n};\n\nfunction planInstall(\n result: InstallSelection,\n installedAlready: ReadonlySet<SkillId>,\n): InstallPlan {\n const toInstall = result.skills.filter(\n (skill) => !skill.excluded && !installedAlready.has(skill.id),\n );\n const [ejectedSkills, pluginSkills] = partition(\n toInstall,\n (skill) => skill.origin === EJECT_SOURCE,\n );\n return { installMode: deriveInstallMode(toInstall), ejectedSkills, pluginSkills };\n}\n\nfunction installModeDescription({ installMode, ejectedSkills, pluginSkills }: InstallPlan): string {\n if (installMode !== \"mixed\") return INSTALL_MODE_DESCRIPTIONS[installMode];\n return `${INSTALL_MODE_LABELS.mixed} (${ejectedSkills.length} eject, ${pluginSkills.length} plugin)`;\n}\n\ntype WrittenInstall = {\n configResult: ConfigWriteResult;\n compileResult: CompilationResult;\n agentScopeMap: Map<AgentName, SkillScope>;\n};\n\n/**\n * From a project, global sub-agents recompile only when the write changed their inputs;\n * otherwise they would be rebuilt from this run's catalogue, not the one they were made from.\n */\nfunction compilesGlobalScope(cwd: string, written: GateReport): boolean {\n return isHomeDirectory(cwd) || movedGlobalAgentInputs(written);\n}\n\n/** Names the directory only when every skill landed at one scope; the block beneath lists both. */\nfunction skillsCopiedLine(\n copyResult: SkillCopyResult,\n installMode: InstallMode,\n projectDir: string,\n): string {\n const isMixed = installMode === \"mixed\";\n const copied = plural(copyResult.totalCopied, isMixed ? \"local skill\" : \"skill\");\n const lineEnd = isMixed ? \"\" : \"\\n\";\n const projectCount = copyResult.projectCopied.length;\n const globalCount = copyResult.globalCopied.length;\n const landedAtBothScopes = projectCount > 0 && globalCount > 0;\n\n if (landedAtBothScopes) {\n return `Copied ${copied} (${projectCount} project, ${globalCount} global)${lineEnd}`;\n }\n const landedAt: SkillScope = globalCount > 0 ? \"global\" : \"project\";\n return `Copied ${copied} to ${resolveInstallPaths(projectDir, landedAt).skillsDir}/${lineEnd}`;\n}\n\n/** Entries are on-disk names, so ids, never display names. */\ntype DirectoryBlock = { dir: string; entries: string[] };\n\nfunction hasEntries(block: DirectoryBlock): boolean {\n return block.entries.length > 0;\n}\n\n/** At home a Claude install's two scopes are one folder, which is named once. */\nfunction oneBlockPerDir(blocks: DirectoryBlock[]): DirectoryBlock[] {\n const dirs = [...new Set(blocks.map((block) => block.dir))];\n return dirs.map((dir) => ({\n dir,\n entries: blocks.filter((block) => block.dir === dir).flatMap((block) => block.entries),\n }));\n}\n\nfunction skillsCopiedBlocks(projectDir: string, copyResult: SkillCopyResult): DirectoryBlock[] {\n return oneBlockPerDir(\n [\n copiedSkillsBlock(projectDir, \"global\", copyResult.globalCopied),\n copiedSkillsBlock(projectDir, \"project\", copyResult.projectCopied),\n ].filter(hasEntries),\n );\n}\n\nfunction copiedSkillsBlock(\n projectDir: string,\n scope: SkillScope,\n copied: SkillCopyResult[\"projectCopied\"],\n): DirectoryBlock {\n return {\n dir: resolveInstallPaths(projectDir, scope).skillsDir,\n entries: copied.map(({ skillId }) => `${skillId}/`),\n };\n}\n\n/** Mirrors `writeCompiledAgentsByScope`' routing. */\nfunction agentsCompiledBlocks(\n projectDir: string,\n compiled: AgentName[],\n agentScopeMap: Map<AgentName, SkillScope>,\n): DirectoryBlock[] {\n const [globalAgents, projectAgents] = partition(\n compiled,\n (name) => agentScopeMap.get(name) === \"global\",\n );\n return oneBlockPerDir(\n [\n compiledAgentsBlock(projectDir, \"global\", globalAgents),\n compiledAgentsBlock(projectDir, \"project\", projectAgents),\n ].filter(hasEntries),\n );\n}\n\n/** Per scope, because the project and global installs can be on different hosts. */\nfunction compiledAgentsBlock(\n projectDir: string,\n scope: SkillScope,\n agents: AgentName[],\n): DirectoryBlock {\n const { extension } = agentCodec(providerAtScope(projectDir, scope));\n return {\n dir: resolveInstallPaths(projectDir, scope).agentsDir,\n entries: agents.map((name) => `${name}${extension}`),\n };\n}\n\ntype ConfigPaths = { global: string; project: string };\n\ntype AgentScopeSplit = { globalAgentCount: number; isGlobalOnly: boolean };\n\n/** At the home root both scopes are one config and one pass, so there is no split. */\nfunction splitAgentScopes(cwd: string, agentScopeMap: Map<AgentName, SkillScope>): AgentScopeSplit {\n if (isHomeDirectory(cwd)) return { globalAgentCount: 0, isGlobalOnly: false };\n\n const scopes = [...agentScopeMap.values()];\n const globalAgentCount = scopes.filter((scope) => scope === \"global\").length;\n return {\n globalAgentCount,\n isGlobalOnly: globalAgentCount > 0 && globalAgentCount === scopes.length,\n };\n}\n\n/**\n * From a project its own config is always written, and the global one whenever the run changed it,\n * if only to register the project. At home the two are one file.\n */\nfunction configsWritten(projectDir: string, paths: ConfigPaths, globalWritten: boolean): string[] {\n if (isHomeDirectory(projectDir)) return [paths.project];\n return globalWritten ? [paths.global, paths.project] : [paths.project];\n}\n\n/** `compile` in a project recompiles no global agent, hence the global hint. */\nfunction customizationSteps(\n split: AgentScopeSplit,\n globalConfigPath: string,\n projectDir: string,\n): string[] {\n if (split.isGlobalOnly) {\n return [`Edit ${globalConfigPath}`, globalScopedAgentsHint(split.globalAgentCount)];\n }\n\n return [\n `Edit ${relativeConfigPath(projectDir, providerInUse(projectDir))}`,\n `Run '${CLI_INVOKE_COMMAND} compile' to regenerate agents`,\n ...(split.globalAgentCount > 0 ? [globalScopedAgentsHint(split.globalAgentCount)] : []),\n ];\n}\n\nexport type DashboardData = {\n name: string;\n installations: ProviderInstallation[];\n};\n\n/** Each installation's counts come from its own scope-aware read, so project and global never mix. */\nasync function getDashboardData(projectDir: string): Promise<DashboardData> {\n // ABORT: an unloadable config throws here, as the installation check before it already would.\n const [installations, branding] = await Promise.all([\n getInstallationsByProvider(projectDir),\n resolveBranding(projectDir),\n ]);\n // Every caller found an installation before drawing the dashboard.\n if (installations.length === 0) throw new Error(ERROR_MESSAGES.NO_INSTALLATION);\n\n return { name: branding.name, installations };\n}\n","import React from \"react\";\nimport { z } from \"zod\";\n\nimport { Text, Box } from \"ink\";\nimport path from \"path\";\n\nimport { CLI_COLORS, MAX_CONFIG_FILE_SIZE } from \"../consts\";\nimport {\n advisesOnPermissions,\n permissionFiles,\n providerInUse,\n} from \"./installation/install-layout.js\";\nimport { fileExists, readFileSafe } from \"../utils/fs\";\nimport { warn } from \"../utils/logger\";\nimport { settingsFileSchema } from \"./schemas\";\n\ntype SettingsFile = z.infer<typeof settingsFileSchema>;\ntype PermissionConfig = NonNullable<SettingsFile[\"permissions\"]>;\n\n/** Undefined when absent, malformed or empty; silent about every other field (Claude Code's). */\nasync function readSettingsPermissions(filePath: string): Promise<PermissionConfig | undefined> {\n if (!(await fileExists(filePath))) return undefined;\n try {\n const content = await readFileSafe(filePath, MAX_CONFIG_FILE_SIZE);\n const raw: unknown = JSON.parse(content);\n const result = settingsFileSchema.safeParse(raw);\n const parsed: SettingsFile = result.success ? result.data : {};\n return parsed.permissions;\n } catch {\n warn(`Malformed settings file at '${filePath}' — skipping`);\n return undefined;\n }\n}\n\nfunction settingsFilesFor(projectRoot: string): string[] {\n return permissionFiles(providerInUse(projectRoot), \"project\", projectRoot);\n}\n\n/** Permissions from the highest-precedence settings file that defines them — the overlay wins. */\nasync function loadPermissions(files: readonly string[]): Promise<PermissionConfig | undefined> {\n for (const filePath of [...files].reverse()) {\n const permissions = await readSettingsPermissions(filePath);\n if (permissions) return permissions;\n }\n return undefined;\n}\n\n/** Relative to the project and POSIX-separated: a name shown to a person, not a path to open. */\nfunction asUserWritesIt(projectRoot: string, file: string): string {\n return path.relative(projectRoot, file).split(path.sep).join(\"/\");\n}\n\n/** `null` for a host whose permission model this release cannot advise on. */\nexport async function checkPermissions(projectRoot: string): Promise<React.ReactElement | null> {\n if (!advisesOnPermissions(providerInUse(projectRoot))) return null;\n\n const files = settingsFilesFor(projectRoot);\n // The base file: the one this CLI writes and a user with neither is asked to create.\n const [base] = files;\n if (base === undefined) return null;\n\n const permissions = await loadPermissions(files);\n const settingsFile = asUserWritesIt(projectRoot, base);\n\n if (!permissions) {\n return (\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor={CLI_COLORS.WARNING} padding={1}>\n <Text bold color={CLI_COLORS.WARNING}>\n Permission Notice\n </Text>\n <Text>No permissions configured in {settingsFile}</Text>\n <Text>Agents will prompt for approval on each tool use.</Text>\n <Text> </Text>\n <Text>For autonomous operation, add to {settingsFile}:</Text>\n <Text> </Text>\n <Text color={CLI_COLORS.DIM}>{\"{\"}</Text>\n <Text color={CLI_COLORS.DIM}>{' \"permissions\": {'}</Text>\n <Text color={CLI_COLORS.DIM}>{' \"allow\": ['}</Text>\n <Text color={CLI_COLORS.DIM}>{' \"Read(*)\",'}</Text>\n <Text color={CLI_COLORS.DIM}>{' \"Bash(git *)\",'}</Text>\n <Text color={CLI_COLORS.DIM}>{' \"Bash(bun *)\"'}</Text>\n <Text color={CLI_COLORS.DIM}>{\" ]\"}</Text>\n <Text color={CLI_COLORS.DIM}>{\" }\"}</Text>\n <Text color={CLI_COLORS.DIM}>{\"}\"}</Text>\n </Box>\n );\n }\n\n const hasRestrictiveBash = permissions.deny?.some(\n (rule) => rule === \"Bash(*)\" || rule === \"Bash\",\n );\n const hasNoAllows = !permissions.allow || permissions.allow.length === 0;\n\n if (hasRestrictiveBash || hasNoAllows) {\n return (\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor={CLI_COLORS.WARNING} padding={1}>\n <Text bold color={CLI_COLORS.WARNING}>\n Permission Warnings\n </Text>\n {hasRestrictiveBash && (\n <Text>\n ⚠ Bash is denied in permissions. Some agents require Bash for git, testing, and build\n commands.\n </Text>\n )}\n {hasNoAllows && (\n <Text>⚠ No allow rules configured. Agents will prompt for each tool use.</Text>\n )}\n </Box>\n );\n }\n\n return null;\n}\n"],"mappings":"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","names":["Box","Text","jsx","jsxs","Text","Box"]}
@@ -14,7 +14,7 @@ import {
14
14
  readFileOptional,
15
15
  unexpressibleOnCodexMessage,
16
16
  writeFile
17
- } from "./chunk-WVFBBZEP.js";
17
+ } from "./chunk-YM3VEDAP.js";
18
18
 
19
19
  // src/cli/lib/hosts/claude-project-trust.ts
20
20
  import path from "path";
@@ -241,4 +241,4 @@ async function hostCompileNotices(provider, projectDir) {
241
241
  export {
242
242
  hostCompileNotices
243
243
  };
244
- //# sourceMappingURL=chunk-3N4FSTVX.js.map
244
+ //# sourceMappingURL=chunk-EHEBN4NB.js.map
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  agentCodec,
4
+ agentsDir,
4
5
  buildAgentTemplateContext,
5
6
  buildCompileAgents,
6
7
  directoryExists,
@@ -11,6 +12,7 @@ import {
11
12
  getPluginAgentsDir,
12
13
  glob,
13
14
  hostCompilesAgent,
15
+ inheritedGlobalProvider,
14
16
  isAgentName,
15
17
  loadAllAgents,
16
18
  loadProjectAgents,
@@ -24,17 +26,16 @@ import {
24
26
  renderAgentBody,
25
27
  renderAgentRoleToml,
26
28
  resolveAgents,
27
- resolveInstallPaths,
28
29
  sourceFolderInUse,
29
30
  sourceFolderName,
30
31
  verbose,
31
32
  writeFile
32
- } from "./chunk-WVFBBZEP.js";
33
+ } from "./chunk-YM3VEDAP.js";
33
34
  import {
34
35
  typedEntries,
35
36
  typedFromEntries,
36
37
  typedKeys
37
- } from "./chunk-7OG635DK.js";
38
+ } from "./chunk-TG3SPPZY.js";
38
39
  import {
39
40
  CLAUDE_DIR,
40
41
  DIRS,
@@ -42,22 +43,22 @@ import {
42
43
  STANDARD_DIRS,
43
44
  STANDARD_FILES,
44
45
  effectivelyExcludedSkillIds
45
- } from "./chunk-MHAQWMNJ.js";
46
+ } from "./chunk-U46LYYRA.js";
46
47
 
47
48
  // src/cli/lib/agents/list-compiled-agents.ts
48
49
  import path from "path";
49
50
  import { partition } from "remeda";
50
51
  var CLAUDE_AGENTS = agentCodec("claude");
51
- async function listAgentMdFiles(agentsDir) {
52
- return listAgentFilesOf(agentsDir, CLAUDE_AGENTS);
52
+ async function listAgentMdFiles(agentsDir2) {
53
+ return listAgentFilesOf(agentsDir2, CLAUDE_AGENTS);
53
54
  }
54
- async function listAgentFilesOf(agentsDir, codec) {
55
- return glob(codec.listGlob, agentsDir);
55
+ async function listAgentFilesOf(agentsDir2, codec) {
56
+ return glob(codec.listGlob, agentsDir2);
56
57
  }
57
- async function splitAgentsByProvenance(agentsDir, codec = CLAUDE_AGENTS) {
58
- const files = await listAgentFilesOf(agentsDir, codec);
58
+ async function splitAgentsByProvenance(agentsDir2, codec = CLAUDE_AGENTS) {
59
+ const files = await listAgentFilesOf(agentsDir2, codec);
59
60
  const classified = await Promise.all(
60
- files.map((file) => readAgentProvenance(agentsDir, file, codec))
61
+ files.map((file) => readAgentProvenance(agentsDir2, file, codec))
61
62
  );
62
63
  const [marked, unmarked] = partition(classified, (agent) => agent.compiledHere);
63
64
  return {
@@ -65,22 +66,22 @@ async function splitAgentsByProvenance(agentsDir, codec = CLAUDE_AGENTS) {
65
66
  unmarked: unmarked.map((agent) => agent.name)
66
67
  };
67
68
  }
68
- async function readAgentProvenance(agentsDir, file, codec) {
69
- const content = await readFileOptional(path.join(agentsDir, file));
69
+ async function readAgentProvenance(agentsDir2, file, codec) {
70
+ const content = await readFileOptional(path.join(agentsDir2, file));
70
71
  return { name: path.basename(file, codec.extension), compiledHere: codec.hasMarker(content) };
71
72
  }
72
- async function listCompiledAgentNames(agentsDir) {
73
- const files = await listAgentMdFiles(agentsDir);
73
+ async function listCompiledAgentNames(agentsDir2) {
74
+ const files = await listAgentMdFiles(agentsDir2);
74
75
  return files.map((f) => path.basename(f, CLAUDE_AGENTS.extension));
75
76
  }
76
- async function pruneStaleCompiledAgents(agentsDir, keep, codec = CLAUDE_AGENTS) {
77
+ async function pruneStaleCompiledAgents(agentsDir2, keep, codec = CLAUDE_AGENTS) {
77
78
  const isStaleCompiledAgent = (file) => {
78
79
  const name = path.basename(file, codec.extension);
79
80
  return isAgentName(name) && !keep.has(name);
80
81
  };
81
- const files = await listAgentFilesOf(agentsDir, codec);
82
+ const files = await listAgentFilesOf(agentsDir2, codec);
82
83
  await Promise.all(
83
- files.filter(isStaleCompiledAgent).map((file) => remove(path.join(agentsDir, file)))
84
+ files.filter(isStaleCompiledAgent).map((file) => remove(path.join(agentsDir2, file)))
84
85
  );
85
86
  }
86
87
 
@@ -88,7 +89,6 @@ async function pruneStaleCompiledAgents(agentsDir, keep, codec = CLAUDE_AGENTS)
88
89
  import { partition as partition2 } from "remeda";
89
90
 
90
91
  // src/cli/lib/agents/write-compiled-agents.ts
91
- import os from "os";
92
92
  import path4 from "path";
93
93
 
94
94
  // src/cli/lib/compiler.ts
@@ -140,9 +140,8 @@ async function readOutputPartial(agentDir, categoryDir) {
140
140
  if (own) return own;
141
141
  return readFileOptional(path3.join(categoryDir, STANDARD_FILES.OUTPUT_MD), "");
142
142
  }
143
- async function createLiquidEngine(projectDir) {
143
+ async function createLiquidEngine(projectDir, provider = providerInUse(projectDir)) {
144
144
  const roots = [];
145
- const provider = providerInUse(projectDir);
146
145
  if (projectDir) {
147
146
  const srcTemplatesDir = path3.join(
148
147
  sourceFolderInUse(projectDir, provider).dir,
@@ -194,13 +193,11 @@ async function holdsExactly(filePath, content) {
194
193
  }
195
194
  var UNROUTED_AGENT_SCOPE = "project";
196
195
  async function writeCompiledAgentsByScope(params) {
196
+ const own = params.provider ?? providerInUse(params.projectDir);
197
+ const inherited = inheritedGlobalProvider(params.projectDir, own);
197
198
  const hosts = {
198
- // Each scope reads its own root: a Codex project under a Claude global is allowed.
199
- global: {
200
- provider: providerInUse(os.homedir()),
201
- agentsDir: resolveInstallPaths(os.homedir(), "global").agentsDir
202
- },
203
- project: { provider: providerInUse(params.projectDir), agentsDir: params.projectAgentsDir }
199
+ global: { provider: inherited, agentsDir: agentsDir(inherited, "global", params.projectDir) },
200
+ project: { provider: own, agentsDir: params.projectAgentsDir }
204
201
  };
205
202
  const outcomes = [];
206
203
  for (const [name, agent] of typedEntries(params.resolvedAgents)) {
@@ -300,8 +297,9 @@ function withoutExcludedAssignments(stack, excludedIds) {
300
297
  async function recompileAgents(options) {
301
298
  const { pluginDir, sourcePath, skills: providedSkills, projectDir, outputDir } = options;
302
299
  const configDir = projectDir ?? pluginDir;
303
- const filteredConfig = await loadConfigWithoutExclusions(configDir);
304
- const allAgents = await loadAgentDefinitions(sourcePath, projectDir);
300
+ const provider = options.provider ?? providerInUse(configDir);
301
+ const filteredConfig = await loadConfigWithoutExclusions(configDir, provider);
302
+ const allAgents = await loadAgentDefinitions(sourcePath, projectDir, provider);
305
303
  const agentNames = await resolveAgentNames({
306
304
  ...options.agents !== void 0 && { specifiedAgents: options.agents },
307
305
  projectConfig: filteredConfig,
@@ -313,35 +311,36 @@ async function recompileAgents(options) {
313
311
  return { compiled: [], rewritten: [], failed: [], warnings: [] };
314
312
  }
315
313
  verbose(`Recompiling ${agentNames.length} agents in ${outputDir ?? pluginDir}`);
316
- const pluginSkills = providedSkills ?? await discoverAllPluginSkills(projectDir ?? pluginDir);
314
+ const pluginSkills = providedSkills ?? await discoverAllPluginSkills(configDir, provider);
317
315
  const { configAgents, missingWarnings } = compileEntriesFor(
318
316
  agentNames,
319
317
  filteredConfig,
320
318
  allAgents
321
319
  );
322
320
  const compileConfig = compileConfigFor(filteredConfig, configAgents, pluginDir);
323
- const engine = await createLiquidEngine(projectDir);
321
+ const engine = await createLiquidEngine(projectDir, provider);
324
322
  const resolvedAgents = await resolveAgents(allAgents, pluginSkills, compileConfig);
325
- const agentsDir = outputDir ?? getPluginAgentsDir(pluginDir);
326
- await ensureDir(agentsDir);
323
+ const agentsDir2 = outputDir ?? getPluginAgentsDir(pluginDir);
324
+ await ensureDir(agentsDir2);
327
325
  const outcomes = await writeCompiledAgentsByScope({
328
326
  resolvedAgents,
329
327
  sourcePath,
330
328
  engine,
331
- projectAgentsDir: agentsDir,
332
- // Same root as the config, so format and configuration come from one installation.
329
+ projectAgentsDir: agentsDir2,
330
+ // The config's own installation, so format and configuration agree.
333
331
  projectDir: configDir,
332
+ provider,
334
333
  ...options.agentScopeMap !== void 0 && { agentScopeMap: options.agentScopeMap }
335
334
  });
336
335
  return buildRecompileResult(outcomes, missingWarnings);
337
336
  }
338
- async function loadConfigWithoutExclusions(configDir) {
339
- const loaded = await loadProjectConfig(configDir);
337
+ async function loadConfigWithoutExclusions(configDir, provider) {
338
+ const loaded = await loadProjectConfig(configDir, provider);
340
339
  return loaded ? filterExcludedEntries(loaded.config) : null;
341
340
  }
342
- async function loadAgentDefinitions(sourcePath, projectDir) {
341
+ async function loadAgentDefinitions(sourcePath, projectDir, provider) {
343
342
  const builtinAgents = await loadAllAgents(sourcePath);
344
- const projectAgents = projectDir ? await loadProjectAgents(projectDir) : {};
343
+ const projectAgents = projectDir ? await loadProjectAgents(projectDir, provider) : {};
345
344
  return { ...builtinAgents, ...projectAgents };
346
345
  }
347
346
  function compileConfigFor(config, agents, pluginDir) {
@@ -374,4 +373,4 @@ export {
374
373
  withoutExcludedAssignments,
375
374
  recompileAgents
376
375
  };
377
- //# sourceMappingURL=chunk-EHJIQDXR.js.map
376
+ //# sourceMappingURL=chunk-GNMRXXRY.js.map
@@ -0,0 +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\";\nimport { providerInUse } from \"../installation/install-layout\";\nimport type { Provider } from \"../../consts\";\n\nexport type RecompileAgentsOptions = {\n pluginDir: string;\n sourcePath: string;\n agents?: AgentName[];\n skills?: SkillDefinitionMap;\n projectDir?: string;\n /** The installation recompiled, where its directory holds two; the default is the one in use. */\n provider?: Provider;\n outputDir?: string;\n /**\n * When provided, routes agents by scope: global ones to the agents folder of the global\n * installation inherited, project ones to `outputDir`.\n */\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 provider = options.provider ?? providerInUse(configDir);\n const filteredConfig = await loadConfigWithoutExclusions(configDir, provider);\n const allAgents = await loadAgentDefinitions(sourcePath, projectDir, provider);\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(configDir, provider));\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, provider);\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 // The config's own installation, so format and configuration agree.\n projectDir: configDir,\n provider,\n ...(options.agentScopeMap !== undefined && { agentScopeMap: options.agentScopeMap }),\n });\n return buildRecompileResult(outcomes, missingWarnings);\n}\n\nasync function loadConfigWithoutExclusions(\n configDir: string,\n provider: Provider,\n): Promise<ProjectConfig | null> {\n const loaded = await loadProjectConfig(configDir, provider);\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 provider: Provider,\n): Promise<Partial<Record<AgentName, AgentDefinition>>> {\n const builtinAgents = await loadAllAgents(sourcePath);\n const projectAgents = projectDir ? await loadProjectAgents(projectDir, provider) : {};\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 path from \"path\";\nimport type { Liquid } from \"liquidjs\";\nimport { compileAgentForHost } from \"../compiler.js\";\nimport {\n agentCodec,\n agentsDir,\n hostCompilesAgent,\n inheritedGlobalProvider,\n providerInUse,\n} 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 /** The installation at `projectDir`, where it holds two; the default is the one in use. */\n provider?: Provider;\n agentScopeMap?: Map<AgentName, SkillScope>;\n}): Promise<AgentWriteOutcome[]> {\n const own = params.provider ?? providerInUse(params.projectDir);\n // Each scope its own: a Codex project under a Claude global is allowed, and inherits only that.\n const inherited = inheritedGlobalProvider(params.projectDir, own);\n const hosts: Record<SkillScope, AgentHost> = {\n global: { provider: inherited, agentsDir: agentsDir(inherited, \"global\", params.projectDir) },\n project: { provider: own, 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(\n projectDir?: string,\n // One read for both: template overrides and source folder must name one installation.\n provider: Provider = providerInUse(projectDir),\n): Promise<Liquid> {\n const roots: string[] = [];\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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,OAAO,UAAU;AACjB,SAAS,iBAAiB;AAU1B,IAAM,gBAAgB,WAAW,QAAQ;AAOzC,eAAsB,iBAAiBA,YAAsC;AAC3E,SAAO,iBAAiBA,YAAW,aAAa;AAClD;AAEA,eAAsB,iBAAiBA,YAAmB,OAAsC;AAC9F,SAAO,KAAK,MAAM,UAAUA,UAAS;AACvC;AAGA,eAAsB,wBACpBA,YACA,QAAoB,eACW;AAC/B,QAAM,QAAQ,MAAM,iBAAiBA,YAAW,KAAK;AACrD,QAAM,aAAa,MAAM,QAAQ;AAAA,IAC/B,MAAM,IAAI,CAAC,SAAS,oBAAoBA,YAAW,MAAM,KAAK,CAAC;AAAA,EACjE;AACA,QAAM,CAAC,QAAQ,QAAQ,IAAI,UAAU,YAAY,CAAC,UAAU,MAAM,YAAY;AAE9E,SAAO;AAAA,IACL,QAAQ,OAAO,IAAI,CAAC,UAAU,MAAM,IAAI;AAAA,IACxC,UAAU,SAAS,IAAI,CAAC,UAAU,MAAM,IAAI;AAAA,EAC9C;AACF;AAIA,eAAe,oBACbA,YACA,MACA,OAC0B;AAC1B,QAAM,UAAU,MAAM,iBAAiB,KAAK,KAAKA,YAAW,IAAI,CAAC;AACjE,SAAO,EAAE,MAAM,KAAK,SAAS,MAAM,MAAM,SAAS,GAAG,cAAc,MAAM,UAAU,OAAO,EAAE;AAC9F;AAEA,eAAsB,uBAAuBA,YAAyC;AACpF,QAAM,QAAQ,MAAM,iBAAiBA,UAAS;AAE9C,SAAO,MAAM,IAAI,CAAC,MAAM,KAAK,SAAS,GAAG,cAAc,SAAS,CAAc;AAChF;AAKA,eAAsB,yBACpBA,YACA,MACA,QAAoB,eACL;AACf,QAAM,uBAAuB,CAAC,SAA0B;AACtD,UAAM,OAAO,KAAK,SAAS,MAAM,MAAM,SAAS;AAChD,WAAO,YAAY,IAAI,KAAK,CAAC,KAAK,IAAI,IAAI;AAAA,EAC5C;AAEA,QAAM,QAAQ,MAAM,iBAAiBA,YAAW,KAAK;AACrD,QAAM,QAAQ;AAAA,IACZ,MAAM,OAAO,oBAAoB,EAAE,IAAI,CAAC,SAAS,OAAO,KAAK,KAAKA,YAAW,IAAI,CAAC,CAAC;AAAA,EACrF;AACF;;;AC7EA,SAAS,aAAAC,kBAAiB;;;ACA1B,OAAOC,WAAU;;;ACAjB,SAAS,cAAc;AACvB,OAAOC,WAAU;;;ACDjB,OAAOC,WAAU;AACjB,SAAS,SAAS;AAKlB,IAAM,uBAAuB,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,CAAC;AAQpE,IAAI;AAMG,SAAS,aAA8B;AAC5C,iBAAe,eAAe;AAC9B,SAAO;AACT;AAEA,eAAe,iBAAkC;AAC/C,QAAM,eAAeC,MAAK,KAAK,cAAc,eAAe,YAAY;AACxE,QAAM,MAAe,KAAK,MAAM,MAAM,SAAS,YAAY,CAAC;AAE5D,QAAM,SAAS,qBAAqB,UAAU,GAAG;AACjD,MAAI,CAAC,OAAO,SAAS;AACnB,UAAM,IAAI,MAAM,8CAA8C,YAAY,EAAE;AAAA,EAC9E;AACA,SAAO,OAAO,KAAK;AACrB;;;ADHA,eAAe,eACb,MACA,OACA,aACqB;AACrB,QAAM,kBAAkB,MAAM,cAAc;AAC5C,QAAM,eAAe,MAAM,gBAAgB,KAAK;AAChD,QAAM,YAAY,MAAM,QAAQ;AAChC,QAAM,WAAWC,MAAK,KAAK,iBAAiB,cAAc,SAAS;AAEnE,QAAM,WAAW,MAAM,SAASA,MAAK,KAAK,UAAU,eAAe,WAAW,CAAC;AAC/E,QAAM,WAAW,MAAM,SAASA,MAAK,KAAK,UAAU,eAAe,WAAW,CAAC;AAC/E,QAAM,0BAA0B,MAAM;AAAA,IACpCA,MAAK,KAAK,UAAU,eAAe,wBAAwB;AAAA,IAC3D;AAAA,EACF;AACA,QAAM,oBAAoB,MAAM;AAAA,IAC9BA,MAAK,KAAK,UAAU,eAAe,qBAAqB;AAAA,IACxD;AAAA,EACF;AAEA,QAAM,WAAW,UAAU,MAAM,GAAG,EAAE,CAAC,KAAK;AAC5C,QAAM,cAAcA,MAAK,KAAK,iBAAiB,cAAc,QAAQ;AACrE,QAAM,SAAS,MAAM,kBAAkB,UAAU,WAAW;AAE5D,SAAO,EAAE,UAAU,UAAU,QAAQ,yBAAyB,kBAAkB;AAClF;AAGA,eAAe,kBAAkB,UAAkB,aAAsC;AACvF,QAAM,MAAM,MAAM,iBAAiBA,MAAK,KAAK,UAAU,eAAe,SAAS,GAAG,EAAE;AACpF,MAAI,IAAK,QAAO;AAChB,SAAO,iBAAiBA,MAAK,KAAK,aAAa,eAAe,SAAS,GAAG,EAAE;AAC9E;AAOA,eAAsB,mBACpB,YAEA,WAAqB,cAAc,UAAU,GAC5B;AACjB,QAAM,QAAkB,CAAC;AAEzB,MAAI,YAAY;AACd,UAAM,kBAAkBA,MAAK;AAAA,MAC3B,kBAAkB,YAAY,QAAQ,EAAE;AAAA,MACxC,cAAc;AAAA,MACdA,MAAK,SAAS,KAAK,SAAS;AAAA,IAC9B;AACA,QAAI,MAAM,gBAAgB,eAAe,GAAG;AAC1C,YAAM,KAAK,eAAe;AAC1B,cAAQ,+BAA+B,eAAe,EAAE;AAAA,IAC1D;AAEA,UAAM,qBAAqBA,MAAK,KAAK,YAAY,YAAY,cAAc,SAAS;AACpF,QAAI,MAAM,gBAAgB,kBAAkB,GAAG;AAC7C,YAAM,KAAK,kBAAkB;AAC7B,cAAQ,gCAAgC,kBAAkB,EAAE;AAAA,IAC9D;AAAA,EACF;AAEA,QAAM,KAAKA,MAAK,KAAK,cAAc,KAAK,SAAS,CAAC;AAElD,SAAO,IAAI,OAAO;AAAA,IAChB,MAAM;AAAA,IACN,SAAS;AAAA,IACT,iBAAiB;AAAA,IACjB,eAAe;AAAA,IACf,SAAS,EAAE,cAAc,iBAAiB,YAAY,QAAQ,EAAE;AAAA,EAClE,CAAC;AACH;AAGA,eAAsB,oBACpB,UACA,MACA,OACA,cACA,QACiB;AACjB,UAAQ,oBAAoB,IAAI,KAAK,QAAQ,GAAG;AAEhD,QAAM,QAAQ,MAAM,eAAe,MAAM,OAAO,YAAY;AAG5D,QAAM,OAAO,0BAA0B,MAAM,OAAO,OAAO,CAAC,WAAW;AAAA,IACrE,GAAG;AAAA,IACH,GAAG,aAAa,KAAK;AAAA,EACvB,EAAE;AACF,QAAM,UAAU,MAAM,WAAW;AAEjC,UAAQ,UAAU;AAAA,IAChB,KAAK;AACH,aAAO,YAAY,QAAQ,MAAM,OAAO;AAAA,IAC1C,KAAK;AACH,aAAO,oBAAoB,OAAO,MAAM,gBAAgB,QAAQ,MAAM,OAAO,CAAC;AAAA,IAChF,SAAS;AACP,YAAM,cAAqB;AAC3B,aAAO;AAAA,IACT;AAAA,EACF;AACF;;;AD7GA,eAAe,aAAa,UAAkB,SAAmC;AAC/E,SAAQ,MAAM,WAAW,QAAQ,KAAO,MAAM,SAAS,QAAQ,MAAO;AACxE;AAMA,IAAM,uBAAmC;AAKzC,eAAsB,2BAA2B,QAUhB;AAC/B,QAAM,MAAM,OAAO,YAAY,cAAc,OAAO,UAAU;AAE9D,QAAM,YAAY,wBAAwB,OAAO,YAAY,GAAG;AAChE,QAAM,QAAuC;AAAA,IAC3C,QAAQ,EAAE,UAAU,WAAW,WAAW,UAAU,WAAW,UAAU,OAAO,UAAU,EAAE;AAAA,IAC5F,SAAS,EAAE,UAAU,KAAK,WAAW,OAAO,iBAAiB;AAAA,EAC/D;AAEA,QAAM,WAAgC,CAAC;AACvC,aAAW,CAAC,MAAM,KAAK,KAAK,aAAqC,OAAO,cAAc,GAAG;AACvF,UAAM,QAAQ,OAAO,eAAe,IAAI,IAAI,KAAK;AACjD,UAAM,OAAO,MAAM,KAAK;AAGxB,QAAI,CAAC,kBAAkB,KAAK,UAAU,IAAI,EAAG;AAE7C,aAAS,KAAK,MAAM,cAAc,EAAE,GAAG,QAAQ,MAAM,OAAO,OAAO,KAAK,CAAC,CAAC;AAAA,EAC5E;AACA,SAAO;AACT;AAGA,eAAe,cAAc,QAOE;AAC7B,QAAM,EAAE,MAAM,OAAO,KAAK,IAAI;AAE9B,MAAI;AACF,UAAM,SAAS,MAAM;AAAA,MACnB,KAAK;AAAA,MACL;AAAA,MACA,OAAO;AAAA,MACP,OAAO;AAAA,MACP,OAAO;AAAA,IACT;AACA,UAAM,aAAaC,MAAK,KAAK,KAAK,WAAW,YAAY,MAAM,KAAK,QAAQ,CAAC;AAC7E,UAAM,YAAY,CAAE,MAAM,aAAa,YAAY,MAAM;AACzD,QAAI,UAAW,OAAM,UAAU,YAAY,MAAM;AAEjD,WAAO,EAAE,MAAM,IAAI,MAAM,OAAO,WAAW,KAAK,WAAW,UAAU;AAAA,EACvE,SAAS,OAAO;AACd,WAAO,EAAE,MAAM,IAAI,OAAO,MAAM;AAAA,EAClC;AACF;AAKA,SAAS,YAAY,MAAiB,UAA4B;AAChE,SAAO,GAAG,IAAI,GAAG,WAAW,QAAQ,EAAE,SAAS;AACjD;;;ADvGA,OAAOC,WAAU;AAmDjB,eAAe,sBAAsB,WAAyC;AAC5E,SAAO,uBAAuB,mBAAmB,SAAS,CAAC;AAC7D;AAUA,eAAe,kBAAkB,QAAuD;AACtF,QAAM,EAAE,iBAAiB,eAAe,WAAW,WAAW,UAAU,IAAI;AAE5E,MAAI,iBAAiB;AACnB,WAAO;AAAA,EACT;AAGA,MAAI,eAAe;AACjB,UAAM,aAAa,cAAc,OAAO,IAAI,CAAC,MAAM,EAAE,IAAI;AACzD,YAAQ,6BAA6B,WAAW,KAAK,IAAI,CAAC,EAAE;AAC5D,WAAO;AAAA,EACT;AAEA,MAAI,WAAW;AACb,UAAM,QAAQ,UAAqB,SAAS;AAC5C,YAAQ,2CAA2C,MAAM,KAAK,IAAI,CAAC,EAAE;AACrE,WAAO;AAAA,EACT;AAEA,SAAO,sBAAsB,SAAS;AACxC;AAEA,SAAS,qBACP,UACA,eACuB;AACvB,QAAM,CAAC,WAAW,cAAc,IAAIC;AAAA,IAClC;AAAA,IACA,CAAC,YAAiE,QAAQ;AAAA,EAC5E;AACA,YAAU;AAAA,IAAQ,CAAC,YACjB;AAAA,MACE,KAAK,QAAQ,YAAY,YAAY,WAAW,KAAK,QAAQ,IAAI,KAAK,QAAQ,KAAK,OAAO,QAAQ,SAAS;AAAA,IAC7G;AAAA,EACF;AACA,SAAO;AAAA,IACL,UAAU,UAAU,IAAI,CAAC,YAAY,QAAQ,IAAI;AAAA,IACjD,WAAW,UAAU,OAAO,CAAC,YAAY,QAAQ,SAAS,EAAE,IAAI,CAAC,YAAY,QAAQ,IAAI;AAAA,IACzF,QAAQ,eAAe,IAAI,CAAC,YAAY,QAAQ,IAAI;AAAA,IACpD,UAAU;AAAA,MACR,GAAG;AAAA,MACH,GAAG,eAAe;AAAA,QAChB,CAAC,YAAY,qBAAqB,QAAQ,IAAI,KAAK,gBAAgB,QAAQ,KAAK,CAAC;AAAA,MACnF;AAAA,IACF;AAAA,EACF;AACF;AAEO,SAAS,sBAAsB,QAAsC;AAC1E,QAAM,cAAc,4BAA4B,OAAO,MAAM;AAC7D,QAAM,eAAe,OAAO,OAAO,OAAO,CAAC,MAAM,CAAC,EAAE,QAAQ;AAC5D,QAAM,eAAe,OAAO,OAAO,OAAO,CAAC,MAAM,CAAC,EAAE,QAAQ;AAG5D,QAAM,gBACJ,OAAO,UAAU,SACb,CAAC,IACD,EAAE,OAAO,2BAA2B,OAAO,OAAO,WAAW,EAAE;AAErE,SAAO,EAAE,GAAG,QAAQ,QAAQ,cAAc,QAAQ,cAAc,GAAG,cAAc;AACnF;AAGO,SAAS,2BACd,OACA,aACqC;AACrC,SAAO,OAAO;AAAA,IACZ,aAAa,KAAK,EAAE,IAAI,CAAC,CAAC,WAAW,UAAU,MAAM;AAAA,MACnD;AAAA,MACA,OAAO;AAAA,QACL,aAAa,UAAU,EAAE,IAAI,CAAC,CAAC,UAAU,WAAW,MAAM;AAAA,UACxD;AAAA,UACA,YAAY,OAAO,CAAC,eAAe,CAAC,YAAY,IAAI,WAAW,EAAE,CAAC;AAAA,QACpE,CAAC;AAAA,MACH;AAAA,IACF,CAAC;AAAA,EACH;AACF;AAEA,eAAsB,gBACpB,SACgC;AAChC,QAAM,EAAE,WAAW,YAAY,QAAQ,gBAAgB,YAAY,UAAU,IAAI;AAEjF,QAAM,YAAY,cAAc;AAChC,QAAM,WAAW,QAAQ,YAAY,cAAc,SAAS;AAC5D,QAAM,iBAAiB,MAAM,4BAA4B,WAAW,QAAQ;AAC5E,QAAM,YAAY,MAAM,qBAAqB,YAAY,YAAY,QAAQ;AAE7E,QAAM,aAAa,MAAM,kBAAkB;AAAA,IACzC,GAAI,QAAQ,WAAW,UAAa,EAAE,iBAAiB,QAAQ,OAAO;AAAA,IACtE,eAAe;AAAA,IACf;AAAA,IACA,GAAI,cAAc,UAAa,EAAE,UAAU;AAAA,IAC3C;AAAA,EACF,CAAC;AAGD,MAAI,WAAW,WAAW,GAAG;AAC3B,WAAO,EAAE,UAAU,CAAC,GAAG,WAAW,CAAC,GAAG,QAAQ,CAAC,GAAG,UAAU,CAAC,EAAE;AAAA,EACjE;AAEA,UAAQ,eAAe,WAAW,MAAM,cAAc,aAAa,SAAS,EAAE;AAE9E,QAAM,eACJ,kBAAmB,MAAM,wBAAwB,WAAW,QAAQ;AAEtE,QAAM,EAAE,cAAc,gBAAgB,IAAI;AAAA,IACxC;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,QAAM,gBAAgB,iBAAiB,gBAAgB,cAAc,SAAS;AAE9E,QAAM,SAAS,MAAM,mBAAmB,YAAY,QAAQ;AAC5D,QAAM,iBAAiB,MAAM,cAAc,WAAW,cAAc,aAAa;AAEjF,QAAMC,aAAY,aAAa,mBAAmB,SAAS;AAC3D,QAAM,UAAUA,UAAS;AAEzB,QAAM,WAAW,MAAM,2BAA2B;AAAA,IAChD;AAAA,IACA;AAAA,IACA;AAAA,IACA,kBAAkBA;AAAA;AAAA,IAElB,YAAY;AAAA,IACZ;AAAA,IACA,GAAI,QAAQ,kBAAkB,UAAa,EAAE,eAAe,QAAQ,cAAc;AAAA,EACpF,CAAC;AACD,SAAO,qBAAqB,UAAU,eAAe;AACvD;AAEA,eAAe,4BACb,WACA,UAC+B;AAC/B,QAAM,SAAS,MAAM,kBAAkB,WAAW,QAAQ;AAC1D,SAAO,SAAS,sBAAsB,OAAO,MAAM,IAAI;AACzD;AAGA,eAAe,qBACb,YACA,YACA,UACsD;AACtD,QAAM,gBAAgB,MAAM,cAAc,UAAU;AACpD,QAAM,gBAAgB,aAAa,MAAM,kBAAkB,YAAY,QAAQ,IAAI,CAAC;AAEpF,SAAO,EAAE,GAAG,eAAe,GAAG,cAAc;AAC9C;AAEA,SAAS,iBACP,QACA,QACA,WACe;AACf,SAAO;AAAA,IACL,MAAM,QAAQ,QAAQC,MAAK,SAAS,SAAS;AAAA,IAC7C,aAAa,QAAQ,eAAe;AAAA,IACpC;AAAA,EACF;AACF;AAGA,SAAS,kBACP,YACA,QACA,WAC6F;AAC7F,QAAM,kBAAkB,SAAS,mBAAmB,QAAQ,SAAS,IAAI,CAAC;AAE1E,QAAM,CAAC,aAAa,aAAa,IAAIF;AAAA,IAAU;AAAA,IAAY,CAAC,SAC1D,QAAQ,gBAAgB,IAAI,KAAK,UAAU,IAAI,CAAC;AAAA,EAClD;AAEA,SAAO;AAAA,IACL,cAAc;AAAA,MACZ,YAAY,IAAI,CAAC,SAAS,CAAC,MAAM,gBAAgB,IAAI,KAAK,CAAC,CAAC,CAAC;AAAA,IAC/D;AAAA,IACA,iBAAiB,cAAc,IAAI,CAAC,SAAS,UAAU,IAAI,mCAAmC;AAAA,EAChG;AACF;","names":["agentsDir","partition","path","path","path","path","path","path","path","partition","agentsDir","path"]}
@@ -1,23 +1,22 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
- getSkillDisplayName,
4
- inertLine,
3
+ getSkillEntryDisplayName,
5
4
  typedValues
6
- } from "./chunk-7OG635DK.js";
5
+ } from "./chunk-TG3SPPZY.js";
7
6
  import {
8
7
  CLI_COLORS,
9
8
  EJECT_SOURCE,
10
9
  UI_SYMBOLS,
11
10
  isActiveAt,
12
11
  isGlobalTombstone
13
- } from "./chunk-MHAQWMNJ.js";
12
+ } from "./chunk-U46LYYRA.js";
14
13
 
15
14
  // src/cli/components/common/skill-agent-summary.tsx
16
15
  import { Box, Text } from "ink";
17
16
  import "react";
18
17
 
19
18
  // src/cli/lib/configuration/scope-diff.ts
20
- import { difference, partition, unique } from "remeda";
19
+ import { difference, indexBy, partition, unique } from "remeda";
21
20
  var NOTHING = /* @__PURE__ */ new Set();
22
21
  function computeScopeDiff(input) {
23
22
  const { currentSkills, currentAgents, installedSkillConfigs, installedAgentConfigs, isInitMode } = input;
@@ -87,9 +86,13 @@ function skillRowClassifier(installed, overwritten) {
87
86
  return (skill) => ({
88
87
  id: skill.id,
89
88
  source: skill.origin,
90
- status: skillStatus(skill, installedSlots, installedOriginBySlot, overwritten)
89
+ status: skillStatus(skill, installedSlots, installedOriginBySlot, overwritten),
90
+ ...recordedNameOf(skill)
91
91
  });
92
92
  }
93
+ function recordedNameOf(skill) {
94
+ return skill.displayName === void 0 ? {} : { displayName: skill.displayName };
95
+ }
93
96
  function agentRowClassifier(installed, changed) {
94
97
  const installedSlots = installed ? new Set(installed.map((agent) => slotKey(agent.name, agent.scope))) : null;
95
98
  return (agent) => ({ name: agent.name, status: agentStatus(agent, installedSlots, changed) });
@@ -108,7 +111,7 @@ function agentStatus(agent, installedSlots, changed) {
108
111
  return !agent.excluded && changed.has(agent.name) ? "changed" : "unchanged";
109
112
  }
110
113
  function toRemovedSkillRow(skill) {
111
- return { id: skill.id, source: skill.origin, status: "removed" };
114
+ return { id: skill.id, source: skill.origin, status: "removed", ...recordedNameOf(skill) };
112
115
  }
113
116
  function toRemovedAgentRow(agent) {
114
117
  return { name: agent.name, status: "removed" };
@@ -122,9 +125,21 @@ function agentChangesAmong(names, before, after) {
122
125
  return names.flatMap((name) => {
123
126
  const was = agentStateIn(before, name);
124
127
  const is = agentStateIn(after, name);
125
- return was === void 0 || is === void 0 ? [] : [agentChange(was, is)];
128
+ if (was === void 0 || is === void 0) return [];
129
+ return [namedByEntries(agentChange(was, is), before.skills, after.skills)];
126
130
  });
127
131
  }
132
+ function namedByEntries(change, before, after) {
133
+ const namedBy = {
134
+ ...activeEntriesOf(change.loses, before),
135
+ ...activeEntriesOf(change.gains, after)
136
+ };
137
+ return { ...change, namedBy };
138
+ }
139
+ function activeEntriesOf(skillIds, skills) {
140
+ const active = skills.filter((entry) => !entry.excluded && skillIds.includes(entry.id));
141
+ return indexBy(active, ({ id }) => id);
142
+ }
128
143
  function agentStateIn(config, name) {
129
144
  const agent = config.agents.find((entry) => entry.name === name && !entry.excluded);
130
145
  return agent === void 0 ? void 0 : { agent, rows: config.stack?.[name] };
@@ -151,11 +166,6 @@ function assignedSkillIds(rows) {
151
166
 
152
167
  // src/cli/components/common/skill-agent-summary.tsx
153
168
  import { jsx, jsxs } from "react/jsx-runtime";
154
- var NO_NAMES = /* @__PURE__ */ new Map();
155
- function skillNameOf(id, names) {
156
- const recorded = names.get(id);
157
- return recorded === void 0 ? getSkillDisplayName(id) : inertLine(recorded);
158
- }
159
169
  var TableHeader = ({ children }) => /* @__PURE__ */ jsx(Text, { bold: true, color: CLI_COLORS.WARNING, children });
160
170
  var ScopeLabel = ({ children }) => /* @__PURE__ */ jsx(Text, { color: CLI_COLORS.WHITE, backgroundColor: CLI_COLORS.LABEL_BG, children: ` ${children} ` });
161
171
  var EjectIcon = () => /* @__PURE__ */ jsxs(Text, { color: CLI_COLORS.WARNING, children: [
@@ -179,10 +189,10 @@ var DIFF_COLOR = {
179
189
  unchanged: CLI_COLORS.NEUTRAL
180
190
  };
181
191
  var NAME_GUTTER_COLUMNS = 3;
182
- var SkillRow = ({ row, name }) => /* @__PURE__ */ jsxs(Box, { width: "50%", paddingRight: NAME_GUTTER_COLUMNS, children: [
192
+ var SkillRow = ({ row }) => /* @__PURE__ */ jsxs(Box, { width: "50%", paddingRight: NAME_GUTTER_COLUMNS, children: [
183
193
  /* @__PURE__ */ jsx(Box, { flexShrink: 0, children: /* @__PURE__ */ jsx(Text, { color: DIFF_COLOR[row.status], children: DIFF_PREFIX[row.status] }) }),
184
194
  /* @__PURE__ */ jsxs(Text, { color: DIFF_COLOR[row.status], children: [
185
- name,
195
+ getSkillEntryDisplayName(row),
186
196
  row.source === EJECT_SOURCE && /* @__PURE__ */ jsx(EjectIcon, {})
187
197
  ] })
188
198
  ] });
@@ -195,7 +205,6 @@ var agentRowKey = (row) => row.status === "removed" ? `removed-${row.name}` : ro
195
205
  var SkillAgentSummary = ({
196
206
  skillConfigs,
197
207
  agentConfigs,
198
- skillNames = NO_NAMES,
199
208
  ...baseline
200
209
  }) => {
201
210
  const diff = computeScopeDiff({
@@ -222,11 +231,11 @@ var SkillAgentSummary = ({
222
231
  /* @__PURE__ */ jsx(TableHeader, { children: "Skills" }),
223
232
  diff.projectSkillRows.length > 0 && /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginTop: 1, children: [
224
233
  /* @__PURE__ */ jsx(ScopeLabel, { children: "Project" }),
225
- /* @__PURE__ */ jsx(Box, { flexWrap: "wrap", children: diff.projectSkillRows.map((row) => /* @__PURE__ */ jsx(SkillRow, { row, name: skillNameOf(row.id, skillNames) }, skillRowKey(row))) })
234
+ /* @__PURE__ */ jsx(Box, { flexWrap: "wrap", children: diff.projectSkillRows.map((row) => /* @__PURE__ */ jsx(SkillRow, { row }, skillRowKey(row))) })
226
235
  ] }),
227
236
  diff.globalSkillRows.length > 0 && /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginTop: 1, children: [
228
237
  /* @__PURE__ */ jsx(ScopeLabel, { children: "Global" }),
229
- /* @__PURE__ */ jsx(Box, { flexWrap: "wrap", children: diff.globalSkillRows.map((row) => /* @__PURE__ */ jsx(SkillRow, { row, name: skillNameOf(row.id, skillNames) }, skillRowKey(row))) })
238
+ /* @__PURE__ */ jsx(Box, { flexWrap: "wrap", children: diff.globalSkillRows.map((row) => /* @__PURE__ */ jsx(SkillRow, { row }, skillRowKey(row))) })
230
239
  ] })
231
240
  ]
232
241
  }
@@ -246,8 +255,9 @@ var SkillAgentSummary = ({
246
255
  };
247
256
 
248
257
  export {
258
+ computeScopeDiff,
249
259
  formatScopeTag,
250
260
  agentChangesAmong,
251
261
  SkillAgentSummary
252
262
  };
253
- //# sourceMappingURL=chunk-G7NUK3BF.js.map
263
+ //# sourceMappingURL=chunk-ICHWAFAC.js.map