{"version":3,"file":"platform-targets.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/plugins/formats/platform-targets.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEtD,0FAA0F;AAC1F,MAAM,MAAM,cAAc,GAAG,OAAO,CAAC,mBAAmB,EAAE,QAAQ,CAAC,CAAC;AAEpE,gEAAgE;AAChE,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,mBAAmB,GAAG,QAAQ,IAAI,cAAc,CAE1F;AAED;;;;;GAKG;AACH,eAAO,MAAM,wBAAwB,EAAE,SAAS,cAAc,EAAe,CAAC;AAE9E,wEAAwE;AACxE,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,mBAAmB,GAAG,SAAS,CAcrF;AAED,MAAM,WAAW,aAAa;IAC7B,kEAAkE;IAClE,SAAS,EAAE,mBAAmB,EAAE,CAAC;IACjC,oFAAoF;IACpF,OAAO,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,2EAA2E;AAC3E,wBAAgB,cAAc,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,aAAa,CAWvE;AAKD,oFAAoF;AACpF,wBAAgB,YAAY,CAAC,SAAS,EAAE,SAAS,mBAAmB,EAAE,GAAG,SAAS,GAAG,IAAI,CAExF;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,IAAI,mBAAmB,EAAE,GAAG,SAAS,CAEzE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,CAAC,EAAE,SAAS,mBAAmB,EAAE,GAAG,cAAc,EAAE,CAclG","sourcesContent":["/**\n * Session-wide artifact platform targeting (`--platform`).\n *\n * hoocode reads resources from every vendor convention, but when it *writes*\n * artifacts it needs a target layout. The two kinds of write have **different\n * rules**, which is why this module exposes two resolvers rather than one:\n *\n *   Plugins            distribution units. A plugin only means anything as a\n *                      member of a platform ecosystem (there is no `.agents`\n *                      marketplace), so production is platform-specific and\n *                      `agents` is never a valid target.\n *                      → {@link resolvePluginPlatforms}\n *   Workspace scaffolds  `/new-skill`, `/new-agent`, `/new-command`. These are\n *                      consumed in place, never shipped, and `.agents/` is a\n *                      real cross-vendor convention for them.\n *                      → {@link getWorkspacePlatforms}\n *\n *   token vocabulary   `agents` (alias `native`), `claude`,\n *                      `github` (aliases `copilot`, `gh`)\n *   session state      set once at startup from the `--platform` flag or the\n *                      `platform` setting (main.ts)\n *\n * See docs/plugin-system-architecture.md §1 for the reasoning.\n *\n * Kept beside the format registry (and importing only `types.ts`) so the\n * platform vocabulary and the adapters stay a one-directory concern: adding a\n * vendor means a new adapter file plus a token here, nothing else.\n */\n\nimport type { MarketplacePlatform } from \"./types.js\";\n\n/** The platforms a *plugin* can be produced for. `agents` is excluded by construction. */\nexport type PluginPlatform = Exclude<MarketplacePlatform, \"agents\">;\n\n/** True for the platform tokens that own a plugin ecosystem. */\nexport function isPluginPlatform(platform: MarketplacePlatform): platform is PluginPlatform {\n\treturn platform !== \"agents\";\n}\n\n/**\n * Default plugin production target when neither the call nor the session picked\n * one. Claude is the default because it is the only platform whose local loop\n * closes: an authored plugin lands in `~/.claude/skills/<id>/` and is live on the\n * next session, whereas Copilot has no in-place drop-in at all.\n */\nexport const DEFAULT_PLUGIN_PLATFORMS: readonly PluginPlatform[] = [\"claude\"];\n\n/** Canonicalize one platform token, folding the user-facing aliases. */\nexport function normalizePlatformToken(token: string): MarketplacePlatform | undefined {\n\tswitch (token.trim().toLowerCase()) {\n\t\tcase \"agents\":\n\t\tcase \"native\":\n\t\t\treturn \"agents\";\n\t\tcase \"claude\":\n\t\t\treturn \"claude\";\n\t\tcase \"github\":\n\t\tcase \"copilot\":\n\t\tcase \"gh\":\n\t\t\treturn \"github\";\n\t\tdefault:\n\t\t\treturn undefined;\n\t}\n}\n\nexport interface PlatformParse {\n\t/** Canonical platforms, deduped, in the order first mentioned. */\n\tplatforms: MarketplacePlatform[];\n\t/** Tokens that matched no known platform (surfaced as diagnostics, never fatal). */\n\tinvalid: string[];\n}\n\n/** Parse raw `--platform` / `platform` tokens into canonical platforms. */\nexport function parsePlatforms(tokens: readonly string[]): PlatformParse {\n\tconst platforms: MarketplacePlatform[] = [];\n\tconst invalid: string[] = [];\n\tfor (const token of tokens) {\n\t\tconst trimmed = token.trim();\n\t\tif (!trimmed) continue;\n\t\tconst canonical = normalizePlatformToken(trimmed);\n\t\tif (!canonical) invalid.push(trimmed);\n\t\telse if (!platforms.includes(canonical)) platforms.push(canonical);\n\t}\n\treturn { platforms, invalid };\n}\n\n/** Session-wide targets. Undefined = not configured (fall back to per-consumer defaults). */\nlet sessionPlatforms: MarketplacePlatform[] | undefined;\n\n/** Set (or clear, with undefined/empty) the session's artifact platform targets. */\nexport function setPlatforms(platforms: readonly MarketplacePlatform[] | undefined): void {\n\tsessionPlatforms = platforms && platforms.length > 0 ? [...platforms] : undefined;\n}\n\n/**\n * The session's configured targets for **workspace scaffolds**, or undefined when\n * `--platform` was not given — callers treat undefined as \"use the hoocode-native\n * location\" rather than substituting a default. `agents` is a legitimate value\n * here: a scaffolded skill or command is consumed in place, not distributed.\n */\nexport function getWorkspacePlatforms(): MarketplacePlatform[] | undefined {\n\treturn sessionPlatforms ? [...sessionPlatforms] : undefined;\n}\n\n/**\n * Resolve the platforms a **plugin** should be produced for: an explicit per-call\n * selection wins, then the session's `--platform` targets, then\n * {@link DEFAULT_PLUGIN_PLATFORMS}.\n *\n * `agents` can never be the answer. An explicit `agents` throws — a caller asking\n * for a plugin in a format no marketplace accepts has made a mistake and should\n * hear about it. A session-level `agents` is *filtered* instead, because\n * `--platform` also drives workspace scaffolds, where `agents` is a perfectly\n * good choice; a user who set it for that reason should not have plugin authoring\n * blow up in their face. If filtering leaves nothing, the default applies.\n */\nexport function resolvePluginPlatforms(explicit?: readonly MarketplacePlatform[]): PluginPlatform[] {\n\tif (explicit && explicit.length > 0) {\n\t\tconst rejected = explicit.filter((p) => !isPluginPlatform(p));\n\t\tif (rejected.length > 0) {\n\t\t\tthrow new Error(\n\t\t\t\t`Cannot author a plugin for platform \"${rejected.join(\", \")}\": plugins are distribution units and ` +\n\t\t\t\t\t\"the native `agents` layout belongs to no marketplace, so it can never be published or installed. \" +\n\t\t\t\t\t\"Target `claude` or `github`, or author a workspace skill instead.\",\n\t\t\t);\n\t\t}\n\t\treturn explicit.filter(isPluginPlatform);\n\t}\n\tconst fromSession = (sessionPlatforms ?? []).filter(isPluginPlatform);\n\treturn fromSession.length > 0 ? fromSession : [...DEFAULT_PLUGIN_PLATFORMS];\n}\n"]}