@skaile/workspaces 1.1.0 → 1.3.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 (183) hide show
  1. package/CHANGELOG.md +52 -0
  2. package/dist/{asset-feeds-NIAABO6U.js → asset-feeds-NEZKG6YS.js} +9 -9
  3. package/dist/{asset-feeds-NIAABO6U.js.map → asset-feeds-NEZKG6YS.js.map} +1 -1
  4. package/dist/asset-manager/index.js +7 -7
  5. package/dist/asset-manager/installer.js +6 -6
  6. package/dist/asset-manager/renderers.js +2 -2
  7. package/dist/bridge/drivers/claude-sdk.js +40 -5
  8. package/dist/bridge/drivers/claude-sdk.js.map +1 -1
  9. package/dist/bridge/drivers/codex.js +1 -1
  10. package/dist/bridge/drivers/continue.js +2 -2
  11. package/dist/bridge/drivers/echo.js +1 -1
  12. package/dist/bridge/drivers/gemini.js +3 -3
  13. package/dist/bridge/drivers/goose.js +2 -2
  14. package/dist/bridge/drivers/omp.js +1 -1
  15. package/dist/bridge/drivers/opencode.js +2 -2
  16. package/dist/bridge/drivers/qwen.js +3 -3
  17. package/dist/bridge/index.js +3 -2
  18. package/dist/bridge/src/cloud.d.ts +89 -0
  19. package/dist/bridge/src/cloud.d.ts.map +1 -0
  20. package/dist/bridge/src/drivers/claude-sdk.d.ts +12 -1
  21. package/dist/bridge/src/drivers/claude-sdk.d.ts.map +1 -1
  22. package/dist/bridge/src/index.d.ts +1 -0
  23. package/dist/bridge/src/index.d.ts.map +1 -1
  24. package/dist/bridge/src/types.d.ts +31 -0
  25. package/dist/bridge/src/types.d.ts.map +1 -1
  26. package/dist/{chunk-7X53KHQ4.js → chunk-4OVPB7SI.js} +4 -2
  27. package/dist/chunk-4OVPB7SI.js.map +1 -0
  28. package/dist/{chunk-SHOKXRL4.js → chunk-5XS3BFJS.js} +8 -4
  29. package/dist/chunk-5XS3BFJS.js.map +1 -0
  30. package/dist/{chunk-EE4NL25D.js → chunk-7CNIRF42.js} +111 -45
  31. package/dist/chunk-7CNIRF42.js.map +1 -0
  32. package/dist/{chunk-MG6UIS7G.js → chunk-AZAS3FKN.js} +6 -3
  33. package/dist/chunk-AZAS3FKN.js.map +1 -0
  34. package/dist/{chunk-BCJL2UNH.js → chunk-BDUANIAR.js} +3 -3
  35. package/dist/{chunk-BCJL2UNH.js.map → chunk-BDUANIAR.js.map} +1 -1
  36. package/dist/{chunk-KVZ6XKVN.js → chunk-BZMTR5WW.js} +3 -3
  37. package/dist/{chunk-KVZ6XKVN.js.map → chunk-BZMTR5WW.js.map} +1 -1
  38. package/dist/{chunk-INUQVXUE.js → chunk-ETYDLXI5.js} +2 -2
  39. package/dist/{chunk-INUQVXUE.js.map → chunk-ETYDLXI5.js.map} +1 -1
  40. package/dist/{chunk-CU5Z7GH3.js → chunk-GB4SEEK4.js} +13 -5
  41. package/dist/chunk-GB4SEEK4.js.map +1 -0
  42. package/dist/chunk-ISQWMBKD.js +74 -0
  43. package/dist/chunk-ISQWMBKD.js.map +1 -0
  44. package/dist/{chunk-ZUE2PIJ5.js → chunk-JQMIG7D3.js} +3 -3
  45. package/dist/{chunk-ZUE2PIJ5.js.map → chunk-JQMIG7D3.js.map} +1 -1
  46. package/dist/{chunk-UY5Q2NZH.js → chunk-K5SD7FSF.js} +3 -3
  47. package/dist/{chunk-UY5Q2NZH.js.map → chunk-K5SD7FSF.js.map} +1 -1
  48. package/dist/{chunk-L3SLC3S4.js → chunk-OBSSORCE.js} +6 -6
  49. package/dist/{chunk-L3SLC3S4.js.map → chunk-OBSSORCE.js.map} +1 -1
  50. package/dist/{chunk-5AGARSQT.js → chunk-OUWNTFDG.js} +31 -3
  51. package/dist/chunk-OUWNTFDG.js.map +1 -0
  52. package/dist/{chunk-VYIK5IE5.js → chunk-P3MJYPZE.js} +24 -5
  53. package/dist/chunk-P3MJYPZE.js.map +1 -0
  54. package/dist/{chunk-B4IOSXRZ.js → chunk-PSMW5HLX.js} +19 -8
  55. package/dist/chunk-PSMW5HLX.js.map +1 -0
  56. package/dist/{chunk-U5J77IIZ.js → chunk-QK5JDAFF.js} +4 -4
  57. package/dist/{chunk-U5J77IIZ.js.map → chunk-QK5JDAFF.js.map} +1 -1
  58. package/dist/{chunk-DMHVL5MC.js → chunk-RHMQPLIK.js} +5 -5
  59. package/dist/{chunk-DMHVL5MC.js.map → chunk-RHMQPLIK.js.map} +1 -1
  60. package/dist/{chunk-52XHXSBN.js → chunk-RJ3HUSBC.js} +3 -3
  61. package/dist/{chunk-52XHXSBN.js.map → chunk-RJ3HUSBC.js.map} +1 -1
  62. package/dist/{chunk-Z4EJOBEL.js → chunk-RYRJEVQ4.js} +7 -7
  63. package/dist/{chunk-Z4EJOBEL.js.map → chunk-RYRJEVQ4.js.map} +1 -1
  64. package/dist/{chunk-QVE3ILCY.js → chunk-SUOGVHGJ.js} +2 -2
  65. package/dist/chunk-SUOGVHGJ.js.map +1 -0
  66. package/dist/{chunk-BM37QD6U.js → chunk-TJRWGMD2.js} +3 -3
  67. package/dist/{chunk-BM37QD6U.js.map → chunk-TJRWGMD2.js.map} +1 -1
  68. package/dist/{chunk-35TLBMHX.js → chunk-WFEPI5LA.js} +5 -5
  69. package/dist/{chunk-35TLBMHX.js.map → chunk-WFEPI5LA.js.map} +1 -1
  70. package/dist/{chunk-OIGYDVCM.js → chunk-XBG2YDQQ.js} +3 -3
  71. package/dist/{chunk-OIGYDVCM.js.map → chunk-XBG2YDQQ.js.map} +1 -1
  72. package/dist/{chunk-WRBF34YE.js → chunk-XKARS6EE.js} +3 -3
  73. package/dist/{chunk-WRBF34YE.js.map → chunk-XKARS6EE.js.map} +1 -1
  74. package/dist/{chunk-YI5OZ7QO.js → chunk-YOPSHV7V.js} +2 -2
  75. package/dist/{chunk-YI5OZ7QO.js.map → chunk-YOPSHV7V.js.map} +1 -1
  76. package/dist/{chunk-G2X3THJV.js → chunk-YXEPZ7LP.js} +5 -5
  77. package/dist/{chunk-G2X3THJV.js.map → chunk-YXEPZ7LP.js.map} +1 -1
  78. package/dist/cli/index.js +104 -62
  79. package/dist/cli/index.js.map +1 -1
  80. package/dist/cli/src/commands/catalog.d.ts +20 -0
  81. package/dist/cli/src/commands/catalog.d.ts.map +1 -1
  82. package/dist/cli/src/commands/project.d.ts +9 -0
  83. package/dist/cli/src/commands/project.d.ts.map +1 -1
  84. package/dist/cli/src/helpers.d.ts +10 -0
  85. package/dist/cli/src/helpers.d.ts.map +1 -1
  86. package/dist/connectors/config.js +4 -4
  87. package/dist/connectors/index.js +5 -5
  88. package/dist/core/index.js +3 -3
  89. package/dist/core/runtime-assets.js +2 -2
  90. package/dist/core/src/index.d.ts +2 -2
  91. package/dist/core/src/index.d.ts.map +1 -1
  92. package/dist/core/src/settings.d.ts +18 -0
  93. package/dist/core/src/settings.d.ts.map +1 -1
  94. package/dist/core/src/workspace-config.d.ts +45 -0
  95. package/dist/core/src/workspace-config.d.ts.map +1 -1
  96. package/dist/core/workspace-config.js +1 -1
  97. package/dist/deploy/index.js +3 -3
  98. package/dist/discovery/index.js +2 -2
  99. package/dist/{ensure-sources-MJYHZ77Y.js → ensure-sources-4BAJGJRK.js} +10 -10
  100. package/dist/{ensure-sources-MJYHZ77Y.js.map → ensure-sources-4BAJGJRK.js.map} +1 -1
  101. package/dist/factory-assets/connectors/box.js +5 -5
  102. package/dist/factory-assets/connectors/deploy.js +5 -5
  103. package/dist/factory-assets/connectors/devserver.js +5 -5
  104. package/dist/factory-assets/connectors/flow/adapter.js +5 -5
  105. package/dist/factory-assets/connectors/flow/engine.js +3 -3
  106. package/dist/factory-assets/connectors/flow/run-flow.js +6 -6
  107. package/dist/factory-assets/connectors/flow.js +5 -5
  108. package/dist/factory-assets/connectors/git/driver.d.ts.map +1 -1
  109. package/dist/factory-assets/connectors/git.js +5 -5
  110. package/dist/factory-assets/connectors/gmail.js +5 -5
  111. package/dist/factory-assets/connectors/googledrive.js +5 -5
  112. package/dist/factory-assets/connectors/local.js +5 -5
  113. package/dist/factory-assets/connectors/mattermost.js +5 -5
  114. package/dist/factory-assets/connectors/memory.js +5 -5
  115. package/dist/factory-assets/connectors/minio.js +5 -5
  116. package/dist/factory-assets/connectors/postgres.js +5 -5
  117. package/dist/factory-assets/connectors/s3.js +5 -5
  118. package/dist/factory-assets/connectors/sharepoint.js +5 -5
  119. package/dist/factory-assets/connectors/sqlite.js +5 -5
  120. package/dist/factory-assets/connectors/static-server.js +5 -5
  121. package/dist/factory-assets/connectors/tunnel.js +5 -5
  122. package/dist/factory-assets/connectors/webdav.js +5 -5
  123. package/dist/factory-assets/connectors/xstate-store.js +5 -5
  124. package/dist/factory-assets/connectors/xstate.js +5 -5
  125. package/dist/{flows-4Z74KY2H.js → flows-UFCOGAAM.js} +3 -3
  126. package/dist/{flows-4Z74KY2H.js.map → flows-UFCOGAAM.js.map} +1 -1
  127. package/dist/helpers-2OL4FRFB.js +22 -0
  128. package/dist/{helpers-7KOVCMHW.js.map → helpers-2OL4FRFB.js.map} +1 -1
  129. package/dist/library/index.js +6 -6
  130. package/dist/library/install.js +3 -3
  131. package/dist/{open-library-PGTL332T.js → open-library-RPV2LIKL.js} +13 -13
  132. package/dist/{open-library-PGTL332T.js.map → open-library-RPV2LIKL.js.map} +1 -1
  133. package/dist/{paths-S7QNXYMB.js → paths-ML33B5SB.js} +6 -6
  134. package/dist/{paths-S7QNXYMB.js.map → paths-ML33B5SB.js.map} +1 -1
  135. package/dist/{plugin-store-3DAVGKHN.js → plugin-store-G4HKWCTU.js} +5 -5
  136. package/dist/{plugin-store-3DAVGKHN.js.map → plugin-store-G4HKWCTU.js.map} +1 -1
  137. package/dist/plugins/src/catalog-source.d.ts +7 -0
  138. package/dist/plugins/src/catalog-source.d.ts.map +1 -1
  139. package/dist/runner/index.js +10 -9
  140. package/dist/runner/src/cloud-bundle.d.ts +36 -0
  141. package/dist/runner/src/cloud-bundle.d.ts.map +1 -0
  142. package/dist/runner/src/resources.d.ts.map +1 -1
  143. package/dist/runner/src/serve.d.ts.map +1 -1
  144. package/dist/runner/src/session-builder.d.ts +32 -0
  145. package/dist/runner/src/session-builder.d.ts.map +1 -1
  146. package/dist/sdk/asset-manager.js +7 -7
  147. package/dist/sdk/bridge.js +3 -2
  148. package/dist/sdk/core.js +3 -3
  149. package/dist/sdk/flow.js +3 -3
  150. package/dist/sdk/index.js +10 -9
  151. package/dist/sdk/index.js.map +1 -1
  152. package/dist/sdk/runner.js +10 -9
  153. package/dist/sdk/store.js +1 -1
  154. package/dist/{setup-WBGDT2WY.js → setup-WS6PF6JQ.js} +8 -7
  155. package/dist/setup-WS6PF6JQ.js.map +1 -0
  156. package/dist/{source-FJXRQ2NU.js → source-22U5NOY4.js} +14 -14
  157. package/dist/{source-FJXRQ2NU.js.map → source-22U5NOY4.js.map} +1 -1
  158. package/dist/store/index.js +1 -1
  159. package/dist/store/src/store.d.ts.map +1 -1
  160. package/dist/{store-client-YGDN4L2G.js → store-client-YLMBH5MF.js} +6 -6
  161. package/dist/{store-client-YGDN4L2G.js.map → store-client-YLMBH5MF.js.map} +1 -1
  162. package/dist/tui/index.js +10 -9
  163. package/dist/tui/index.js.map +1 -1
  164. package/dist/types/manifests.js +1 -1
  165. package/dist/types/src/manifests/agent.d.ts +47 -8
  166. package/dist/types/src/manifests/agent.d.ts.map +1 -1
  167. package/dist/types/src/manifests/index.d.ts +1 -1
  168. package/dist/types/src/manifests/index.d.ts.map +1 -1
  169. package/dist/workspace-plugin/adapters/mcp.js +1 -1
  170. package/dist/workspace-plugin/adapters/omp.js +3 -3
  171. package/dist/workspace-plugin/index.js +1 -1
  172. package/package.json +1 -1
  173. package/dist/chunk-5AGARSQT.js.map +0 -1
  174. package/dist/chunk-7X53KHQ4.js.map +0 -1
  175. package/dist/chunk-B4IOSXRZ.js.map +0 -1
  176. package/dist/chunk-CU5Z7GH3.js.map +0 -1
  177. package/dist/chunk-EE4NL25D.js.map +0 -1
  178. package/dist/chunk-MG6UIS7G.js.map +0 -1
  179. package/dist/chunk-QVE3ILCY.js.map +0 -1
  180. package/dist/chunk-SHOKXRL4.js.map +0 -1
  181. package/dist/chunk-VYIK5IE5.js.map +0 -1
  182. package/dist/helpers-7KOVCMHW.js +0 -22
  183. package/dist/setup-WBGDT2WY.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../core/src/cache-paths.ts","../core/src/walker.ts","../core/src/repo-manager.ts","../core/src/workspace-config.ts"],"names":["existsSync","readdirSync","join","dirname","homedir","mkdirSync","readFileSync","resolve","writeFileSync","parsePath","parse","stringify"],"mappings":"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","file":"chunk-5AGARSQT.js","sourcesContent":["/**\n * Cache-root resolution + lazy legacy-dir migration primitives.\n *\n * `globalCacheRoot()` is the single root for all re-derivable global bytes\n * (`<root>/sources`, `<root>/catalog`). Sidecars are authored content and live\n * OUTSIDE this root (see `library/.../sidecar-paths.ts`).\n *\n * @docLink packages/core/api-reference#cache-paths\n */\nimport { existsSync, mkdirSync, readdirSync, renameSync, rmdirSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\n\n/**\n * The Skaile home dir — root for user-scope, machine-global state\n * (`skaile.yaml` SSOT, `skaile.lock.yaml`, `cache/`, `config.yaml`).\n * `$SKAILE_HOME` wins (tests point it at a temp dir); else `~/.skaile`.\n */\nexport function globalSkaileDir(): string {\n return process.env.SKAILE_HOME ?? join(homedir(), \".skaile\");\n}\n\n/**\n * The global cache root. `$SKAILE_CACHE_DIR` (now the cache *root*, not the\n * repos dir) wins; else `$SKAILE_HOME/cache`; else `~/.skaile/cache`.\n */\nexport function globalCacheRoot(): string {\n if (process.env.SKAILE_CACHE_DIR) return process.env.SKAILE_CACHE_DIR;\n return join(globalSkaileDir(), \"cache\");\n}\n\nconst migratedWholeTree = new Set<string>();\n\n/**\n * One-time whole-tree migration: if `newPath` is absent but `legacyPath` exists,\n * `rename()` legacy → new. Best-effort — a cross-device/raced rename is swallowed\n * (the caller's dir is re-derivable). Returns `newPath` always. Memoized per\n * `newPath` so hot resolvers don't stat on every call.\n */\nexport function migrateLegacyDir(newPath: string, legacyPath: string): string {\n if (migratedWholeTree.has(newPath)) return newPath;\n migratedWholeTree.add(newPath);\n try {\n if (!existsSync(newPath) && existsSync(legacyPath)) {\n mkdirSync(dirname(newPath), { recursive: true });\n renameSync(legacyPath, newPath);\n }\n } catch {\n // best-effort: re-derivable on miss\n }\n return newPath;\n}\n\nconst mergedEntries = new Set<string>();\n\n/**\n * Per-entry merge: move each immediate child of `legacyDir` that passes `filter`\n * into `targetDir/<name>`, skipping names already present in `targetDir`. Used\n * where two legacy roots feed one new root (so a whole-tree rename would clobber\n * or orphan). Removes `legacyDir` if it ends up empty. Idempotent; memoized per\n * `targetDir|legacyDir` pair.\n *\n * @param filter - receives the absolute child path; return true to move it.\n */\nexport function mergeLegacyEntriesInto(\n targetDir: string,\n legacyDir: string,\n filter: (childAbsPath: string) => boolean,\n): void {\n const key = `${targetDir}\\0${legacyDir}`;\n if (mergedEntries.has(key)) return;\n mergedEntries.add(key);\n if (!existsSync(legacyDir)) return;\n try {\n mkdirSync(targetDir, { recursive: true });\n for (const name of readdirSync(legacyDir)) {\n const from = join(legacyDir, name);\n if (!filter(from)) continue;\n const to = join(targetDir, name);\n if (existsSync(to)) continue; // don't clobber\n try {\n renameSync(from, to);\n } catch {\n // best-effort per entry\n }\n }\n if (readdirSync(legacyDir).length === 0) rmdirSync(legacyDir);\n } catch {\n // best-effort\n }\n}\n\n/** Test-only: reset migration memoization between cases. */\nexport function __resetCacheMigrationMemo(): void {\n migratedWholeTree.clear();\n mergedEntries.clear();\n}\n","/**\n * Provenance-index walker.\n *\n * Given a list of cloned source paths plus their resolved commits, walk each\n * clone, read its `skaile.manifest.yaml` (or fall back to the agentskills.io\n * filename layout), compute per-file and composite sha256s, and build a\n * {@link ProvenanceIndex} keyed by `<publisher>/<kind>:<name>`.\n *\n * Manifest discovery is recursive: a `skaile.manifest.yaml` at the repo root\n * *and* under any subdirectory contributes assets (a curator repo carries one\n * manifest per upstream). A manifest (or asset entry) with a `source:` pointer\n * is **curated** — its bytes live in the referenced upstream, so the candidate's\n * `sourceUrl`/`commit` stamp the upstream and the hashes come from the author-\n * pinned `sha256` / granular `files[].sha256` rather than from local bytes.\n *\n * This is the source-side half of the canonical-identity resolution model: the\n * resolver compares these candidates against store-side candidates and detects\n * divergent content hashes for the same `(publisher, kind, name, version)`.\n */\n\nimport { createHash } from \"node:crypto\";\nimport { existsSync, readdirSync, readFileSync } from \"node:fs\";\nimport { dirname, join, relative } from \"node:path\";\nimport fg from \"fast-glob\";\nimport { bundleDepRefs, parseFrontmatter, scanDirectory } from \"./manifest.js\";\nimport { isValidAssetName, slugifyAssetName } from \"./models.js\";\nimport {\n type AssetEntry,\n decodeSkaileManifest,\n type ManifestFileEntry,\n type ManifestSource,\n SKAILE_MANIFEST_FILENAME,\n} from \"./publish-manifest.js\";\n\n/** One cloned source repo, pinned at a resolved commit. */\nexport interface SourceClone {\n localPath: string;\n sourceUrl: string;\n /** 40-char SHA. */\n commit: string;\n /** Optional tag context for the version waterfall (step 3). */\n tag?: string;\n}\n\n/** One resolved candidate in the provenance index. */\nexport interface ProvenanceCandidate {\n publisher: string;\n kind: string;\n name: string;\n /** Canonical semver string (or `0.0.0-sha.<7char>`). */\n version: string;\n sourceUrl: string;\n commit: string;\n files: Array<{ path: string; sha256: string }>;\n /** Composite sha256 over sorted `<path>:<sha256>\\n` rows. */\n sha256: string;\n /** Parsed content frontmatter (mcp-server defaults etc.). */\n metadata?: Record<string, unknown>;\n /** Canonical transitive dependency refs (`kind:name@<publisher>[#pin]`).\n * Populated from the manifest's `assets[].dependencies` when present, else\n * for bundles from the bundle manifest. `resolveAll` recurses into these so a\n * bundle pulls its members (and nested bundles). */\n deps?: string[];\n\n // ── Store-listing metadata (manifest-wins-else-frontmatter; all optional) ──\n description?: string;\n keywords?: string[];\n category?: string;\n license?: string;\n homepage?: string;\n}\n\nexport type ProvenanceIndex = Map<string, ProvenanceCandidate[]>;\n\nfunction fileSha256(p: string): string {\n return createHash(\"sha256\").update(readFileSync(p)).digest(\"hex\");\n}\n\n/**\n * Composite hash: SHA-256 (bare 64-hex) over `localeCompare`-sorted\n * `<path>:<sha256>\\n` rows. Byte-for-byte identical to the store's\n * `computeCompositeSha256` (publish-shared.ts) and the `InstallManifest.sha256`\n * rollup, so source-side and store-side digests are directly comparable in the\n * resolver's cross-source divergence probe.\n */\nfunction compositeSha256(files: Array<{ path: string; sha256: string }>): string {\n const lines = files\n .slice()\n .sort((a, b) => a.path.localeCompare(b.path))\n .map((f) => `${f.path}:${f.sha256}\\n`)\n .join(\"\");\n return createHash(\"sha256\").update(lines).digest(\"hex\");\n}\n\n/**\n * Canonical GitHub-org → publisher slug. The single lowercasing rule shared by\n * the resolve side (`buildProvenanceIndex` here) and the index side\n * (`resolveSourcePublisher` in repo-manager). GitHub orgs are case-insensitive,\n * so a cased remote (`Acme`) and a lowercase index ref must not split.\n */\nexport function normalizeGithubOrg(org: string): string {\n return org.toLowerCase();\n}\n\nfunction publisherFromGithubUrl(url: string): string | undefined {\n const m = url.match(/github\\.com[/:]([^/]+)\\/[^/]+/);\n return m ? normalizeGithubOrg(m[1]) : undefined;\n}\n\nfunction syntheticVersion(commit: string): string {\n return `0.0.0-sha.${commit.slice(0, 7)}`;\n}\n\n/** Agentskills.io filename layout: `<repo-root>/<kind-plural>/<name>/<KIND>.md`. */\nconst KIND_DIRS: Array<{ dir: string; kind: string; mdName: string }> = [\n { dir: \"skills\", kind: \"skill\", mdName: \"SKILL.md\" },\n { dir: \"agents\", kind: \"agent\", mdName: \"AGENT.md\" },\n { dir: \"bundles\", kind: \"bundle\", mdName: \"BUNDLE.md\" },\n { dir: \"mcp-servers\", kind: \"mcp-server\", mdName: \"MCP.md\" },\n { dir: \"connectors\", kind: \"connector\", mdName: \"CONNECTOR.md\" },\n { dir: \"prompts\", kind: \"prompt\", mdName: \"PROMPT.md\" },\n { dir: \"contracts\", kind: \"contract\", mdName: \"CONTRACT.md\" },\n];\n\nconst MD_FILE_BY_KIND: Record<string, string> = Object.fromEntries(\n KIND_DIRS.map((k) => [k.kind, k.mdName]),\n);\n\n/**\n * Walk a list of source clones into a provenance index.\n *\n * @param clones - Cloned source repos pinned at resolved commits.\n * @returns Map of `<publisher>/<kind>:<name>` → candidates.\n * @throws On a SKILL.md name mismatch or a missing publisher for a non-GitHub source.\n * @docLink packages/core/workspace-config#build-provenance-index\n */\nexport function buildProvenanceIndex(\n clones: SourceClone[],\n _opts?: { projectDir?: string },\n): ProvenanceIndex {\n const index: ProvenanceIndex = new Map();\n for (const clone of clones) walkOne(clone, index);\n return index;\n}\n\nfunction walkOne(clone: SourceClone, index: ProvenanceIndex): void {\n const manifestPaths = findManifestFiles(clone.localPath);\n if (manifestPaths.length === 0) {\n walkFilenameConvention(clone, index);\n return;\n }\n let produced = false;\n for (const p of manifestPaths) {\n if (walkWithManifest(clone, p, index)) produced = true;\n }\n // Manifest(s) present but none declared assets[]: fall back to the\n // agentskills.io filename convention (matches the single-manifest behaviour).\n if (!produced) walkFilenameConvention(clone, index);\n}\n\n/** Recursively find every `skaile.manifest.yaml` under `root`, skipping\n * `.git`/`node_modules` (same skip list as the rest of the walker). */\nfunction findManifestFiles(root: string): string[] {\n const found: string[] = [];\n const walk = (dir: string): void => {\n if (!existsSync(dir)) return;\n for (const entry of readdirSync(dir, { withFileTypes: true })) {\n if (entry.name === \".git\" || entry.name === \"node_modules\") continue;\n const abs = join(dir, entry.name);\n if (entry.isDirectory()) walk(abs);\n else if (entry.isFile() && entry.name === SKAILE_MANIFEST_FILENAME) found.push(abs);\n }\n };\n walk(root);\n return found;\n}\n\n/**\n * Walk one `skaile.manifest.yaml` into the index. Returns `true` when it\n * produced at least one candidate.\n *\n * First-party assets (no `source:`) read bytes from the local clone. Curated\n * assets (manifest- or asset-level `source:`) are pointers: the candidate's\n * `sourceUrl`/`commit` stamp the upstream and the hashes come from the author-\n * pinned `sha256` / granular `files[].sha256`.\n */\nfunction walkWithManifest(\n clone: SourceClone,\n manifestPath: string,\n index: ProvenanceIndex,\n): boolean {\n const { manifest } = decodeSkaileManifest(readFileSync(manifestPath, \"utf8\"));\n const repoRoot = clone.localPath;\n const manifestPublisher = manifest.publisher ?? publisherFromGithubUrl(clone.sourceUrl);\n const manifestVersion =\n manifest.version ??\n (clone.tag ? clone.tag.replace(/^v/, \"\") : undefined) ??\n syntheticVersion(clone.commit);\n\n const assets = manifest.assets ?? [];\n if (assets.length === 0) return false;\n\n for (const a of assets) {\n const assetPublisher = a.publisher ?? manifestPublisher;\n if (!assetPublisher) {\n throw new Error(\n `${clone.sourceUrl}: publisher must be declared in skaile.manifest.yaml ` +\n \"(non-GitHub source URL — auto-derivation not available).\",\n );\n }\n const curatedSource = a.source ?? manifest.source;\n const version = a.version ?? manifestVersion;\n // A third-party manifest may declare a human-styled name; slugify it to a\n // canonical identity so the ref it produces parses (no-op when canonical).\n const name = canonicalAssetName(a.name);\n\n const resolved = resolveAssetBytes(clone, repoRoot, a, curatedSource);\n const { files } = resolved;\n\n const candidate: ProvenanceCandidate = {\n publisher: assetPublisher,\n kind: a.kind,\n name,\n version,\n sourceUrl: resolved.sourceUrl,\n commit: resolved.commit,\n files,\n sha256: a.sha256 ?? compositeSha256(files),\n metadata: resolved.metadata,\n deps: a.dependencies ?? manifestDeps(repoRoot, files, a.kind),\n };\n\n applyStoreListingMetadata(candidate, a, manifest, resolved.frontmatter);\n\n push(index, `${assetPublisher}/${a.kind}:${name}`, candidate);\n }\n return true;\n}\n\n/** Canonical asset name: returned as-is when already valid, slugified when a\n * third-party source declared a human-styled name, or left untouched when it\n * can't be slugified (downstream `parseAssetRef` then reports the full error). */\nfunction canonicalAssetName(raw: string): string {\n if (isValidAssetName(raw)) return raw;\n try {\n return slugifyAssetName(raw);\n } catch {\n return raw;\n }\n}\n\n/** Resolved bytes + provenance for one asset entry. */\ninterface ResolvedAssetBytes {\n files: Array<{ path: string; sha256: string }>;\n sourceUrl: string;\n commit: string;\n metadata?: Record<string, unknown>;\n frontmatter?: Record<string, unknown>;\n}\n\n/**\n * Resolve an asset's files + provenance stamp. Curated assets (a `source:`\n * pointer) read author-pinned granular `files[]`/sha256 and stamp the upstream;\n * first-party assets read bytes from the local clone and additionally surface\n * metadata + content frontmatter.\n */\nfunction resolveAssetBytes(\n clone: SourceClone,\n repoRoot: string,\n a: AssetEntry,\n curatedSource: ManifestSource | undefined,\n): ResolvedAssetBytes {\n if (curatedSource) {\n // Pointer — bytes live upstream (never vendored). Use the author-pinned\n // granular files[]/sha256; stamp provenance to the upstream.\n return {\n files: granularFiles(a) ?? [],\n sourceUrl: curatedSource.url,\n commit: curatedSource.commit ?? clone.commit,\n };\n }\n // First-party — bytes from the local clone.\n const files = expandAssetFiles(repoRoot, a);\n verifyNameMatch(repoRoot, files, a.name, a.kind);\n return {\n files,\n sourceUrl: clone.sourceUrl,\n commit: clone.commit,\n metadata: readMetadata(repoRoot, files, a.kind),\n frontmatter: readContentFrontmatter(repoRoot, files, a.kind),\n };\n}\n\n/**\n * Fold store-listing metadata onto a candidate in place: manifest field wins,\n * else content frontmatter, with repo-level license/homepage as the per-asset\n * default.\n */\nfunction applyStoreListingMetadata(\n candidate: ProvenanceCandidate,\n a: AssetEntry,\n manifest: { license?: string; homepage?: string },\n frontmatter: Record<string, unknown> | undefined,\n): void {\n const fmStr = (k: string): string | undefined =>\n typeof frontmatter?.[k] === \"string\" ? (frontmatter[k] as string) : undefined;\n const fmArr = (k: string): string[] | undefined =>\n Array.isArray(frontmatter?.[k])\n ? (frontmatter[k] as unknown[]).filter((x): x is string => typeof x === \"string\")\n : undefined;\n const description = a.description ?? fmStr(\"description\");\n const keywords = a.keywords ?? fmArr(\"keywords\");\n const category = a.category ?? fmStr(\"category\");\n const license = a.license ?? manifest.license;\n const homepage = a.homepage ?? manifest.homepage;\n if (description) candidate.description = description;\n if (keywords && keywords.length > 0) candidate.keywords = keywords;\n if (category) candidate.category = category;\n if (license) candidate.license = license;\n if (homepage) candidate.homepage = homepage;\n}\n\n/** The glob strings of an asset's `files:` (first-party form). */\nfunction globFiles(a: AssetEntry): string[] | undefined {\n if (!Array.isArray(a.files)) return undefined;\n const strings = a.files.filter((f): f is string => typeof f === \"string\");\n return strings.length > 0 ? strings : undefined;\n}\n\n/** The granular `{path, sha256}` entries of an asset's `files:` (curated form). */\nfunction granularFiles(a: AssetEntry): ManifestFileEntry[] | undefined {\n if (!Array.isArray(a.files)) return undefined;\n const granular = a.files.filter(\n (f): f is ManifestFileEntry => !!f && typeof f === \"object\" && \"path\" in f && \"sha256\" in f,\n );\n return granular.length > 0 ? granular : undefined;\n}\n\nfunction expandAssetFiles(\n repoRoot: string,\n a: AssetEntry,\n): Array<{ path: string; sha256: string }> {\n const out: Array<{ path: string; sha256: string }> = [];\n if (a.root) {\n walkDirRecursive(join(repoRoot, a.root), repoRoot, out);\n }\n const globs = globFiles(a);\n if (globs) {\n const matches = fg.sync(globs, { cwd: repoRoot, onlyFiles: true, dot: false });\n for (const rel of matches) {\n out.push({ path: rel, sha256: fileSha256(join(repoRoot, rel)) });\n }\n }\n // dedupe by path\n const seen = new Set<string>();\n return out.filter((f) => (seen.has(f.path) ? false : (seen.add(f.path), true)));\n}\n\nfunction walkDirRecursive(\n abs: string,\n root: string,\n out: Array<{ path: string; sha256: string }>,\n): void {\n if (!existsSync(abs)) return;\n for (const entry of readdirSync(abs, { withFileTypes: true })) {\n if (entry.name === \".git\" || entry.name === \"node_modules\") continue;\n const childAbs = join(abs, entry.name);\n if (entry.isDirectory()) {\n walkDirRecursive(childAbs, root, out);\n } else if (entry.isFile()) {\n out.push({ path: relative(root, childAbs), sha256: fileSha256(childAbs) });\n }\n }\n}\n\n/** Kinds whose asset spans the manifest file's whole containing directory\n * (SKILL.md + scripts, etc.). The rest are single-file assets (a `.bundle.yaml`,\n * `.flow.yaml`, or `.prompt.md` standing alone). */\nconst DIR_SCOPED_KINDS = new Set([\n \"skill\",\n \"agent\",\n \"contract\",\n \"mcp-server\",\n \"connector\",\n \"knowledge\",\n]);\n\nfunction walkFilenameConvention(clone: SourceClone, index: ProvenanceIndex): void {\n const publisher = publisherFromGithubUrl(clone.sourceUrl);\n if (!publisher) {\n throw new Error(\n `${clone.sourceUrl}: publisher must be declared in skaile.manifest.yaml ` +\n \"(non-GitHub source URL).\",\n );\n }\n const version =\n (clone.tag ? clone.tag.replace(/^v/, \"\") : undefined) ?? syntheticVersion(clone.commit);\n\n // Reuse the catalog scanner so the provenance fallback discovers exactly the\n // assets `manage` lists — recursively, by manifest filename, anywhere in the\n // tree. The old top-level `<kind-plural>/<name>/` scan missed nested assets\n // (e.g. `flows/x/x.bundle.yaml`): the TUI listed them but `add` couldn't\n // resolve them. See _devlog/notes/2026-06-02-provenance-fallback-recursion.md.\n for (const e of scanDirectory(clone.localPath, publisher)) {\n const manifestAbs = e.source;\n const files: Array<{ path: string; sha256: string }> = [];\n if (DIR_SCOPED_KINDS.has(e.kind)) {\n walkDirRecursive(dirname(manifestAbs), clone.localPath, files);\n } else {\n files.push({ path: relative(clone.localPath, manifestAbs), sha256: fileSha256(manifestAbs) });\n }\n const candidate: ProvenanceCandidate = {\n publisher,\n kind: e.kind,\n name: e.name,\n version,\n sourceUrl: clone.sourceUrl,\n commit: clone.commit,\n files,\n sha256: compositeSha256(files),\n metadata: readMetadata(clone.localPath, files, e.kind),\n deps: manifestDeps(clone.localPath, files, e.kind),\n };\n push(index, `${publisher}/${e.kind}:${e.name}`, candidate);\n }\n}\n\nfunction verifyNameMatch(\n repoRoot: string,\n files: Array<{ path: string; sha256: string }>,\n expectedName: string,\n kind: string,\n): void {\n const mdName = MD_FILE_BY_KIND[kind];\n if (!mdName) return;\n const md = files.find((f) => f.path.endsWith(mdName));\n if (!md) return;\n const { data } = parseFrontmatter(readFileSync(join(repoRoot, md.path), \"utf8\"));\n const declared = typeof data.name === \"string\" ? data.name : undefined;\n // Compare on the canonical (slugified) form so a manifest and its SKILL.md that\n // agree on a human-styled name (\"Complex App\" vs \"complex-app\") don't false-trip.\n if (declared && canonicalAssetName(declared) !== canonicalAssetName(expectedName)) {\n throw new Error(\n `name mismatch: ${mdName} says \"${declared}\", skaile.manifest.yaml says ` +\n `\"${expectedName}\" — index-time hard error.`,\n );\n }\n}\n\nfunction readMetadata(\n repoRoot: string,\n files: Array<{ path: string; sha256: string }>,\n kind: string,\n): Record<string, unknown> | undefined {\n // For MCP servers, return parsed frontmatter so loadMcpServerDeclarations\n // gets command/args/env defaults.\n if (kind !== \"mcp-server\") return undefined;\n const mcpMd = files.find((f) => f.path.endsWith(\"MCP.md\"));\n if (!mcpMd) return undefined;\n const { data } = parseFrontmatter(readFileSync(join(repoRoot, mcpMd.path), \"utf8\"));\n return data;\n}\n\n/** Read the asset's manifest-file frontmatter (SKILL.md, AGENT.md, …) so the\n * walker can fall back to content `description`/`keywords` when the manifest\n * omits the store-listing fields. Returns undefined when the kind has no\n * manifest file or it is absent among `files`. */\nfunction readContentFrontmatter(\n repoRoot: string,\n files: Array<{ path: string; sha256: string }>,\n kind: string,\n): Record<string, unknown> | undefined {\n const mdName = MD_FILE_BY_KIND[kind];\n if (!mdName) return undefined;\n const md = files.find((f) => f.path.endsWith(mdName));\n if (!md) return undefined;\n try {\n return parseFrontmatter(readFileSync(join(repoRoot, md.path), \"utf8\")).data;\n } catch {\n return undefined;\n }\n}\n\n/** For a bundle or flow, locate its manifest among `files` and read its\n * transitive dep refs (a flow's `requires:`, a bundle's `requires`/`dependencies`).\n * Without this, installing a flow deploys only the `.flow.yaml` and never the\n * contracts/skills/sub-flows it declares. Returns undefined for other kinds or\n * when no manifest is present. */\nfunction manifestDeps(\n repoRoot: string,\n files: Array<{ path: string; sha256: string }>,\n kind: string,\n): string[] | undefined {\n const ext =\n kind === \"bundle\"\n ? [\".bundle.yaml\", \"BUNDLE.md\"]\n : kind === \"flow\"\n ? [\".flow.yaml\", \".flow.json\"]\n : null;\n if (!ext) return undefined;\n const mf = files.find((f) => ext.some((e) => f.path.endsWith(e)));\n return mf ? bundleDepRefs(join(repoRoot, mf.path)) : undefined;\n}\n\nfunction push(index: ProvenanceIndex, key: string, candidate: ProvenanceCandidate): void {\n const arr = index.get(key) ?? [];\n arr.push(candidate);\n index.set(key, arr);\n}\n","/**\n * Repository operations — clone, pull, scan, resolve, link.\n *\n * Remote repos are cloned to a shared global cache (~/.skaile/cache/sources/<name>/).\n * Projects reference the cache via symlinks at .skaile/cache/sources/<name>/.\n * Local repos (path:) are used directly. Linked repos override remote URLs.\n *\n * Supports partial clone + sparse checkout for large repos.\n */\n\nimport { spawnSync } from \"node:child_process\";\nimport {\n existsSync,\n lstatSync,\n mkdirSync,\n readFileSync,\n rmSync,\n symlinkSync,\n writeFileSync,\n} from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join, resolve } from \"node:path\";\nimport semver from \"semver\";\nimport { parse, stringify } from \"yaml\";\nimport { globalCacheRoot, mergeLegacyEntriesInto } from \"./cache-paths.js\";\nimport { scanDirectory } from \"./manifest.js\";\nimport type { AssetRef, CatalogEntry } from \"./models.js\";\nimport { assetRefToStr, parseAssetRef } from \"./models.js\";\nimport { SKAILE_MANIFEST_FILENAME } from \"./publish-manifest.js\";\nimport { normalizeGithubOrg, type ProvenanceCandidate, type ProvenanceIndex } from \"./walker.js\";\nimport type { OverrideEntry, SourceDeclaration, StoreEntry } from \"./workspace-config.js\";\n\n// ── Global clone cache ───────────────────────────────────────────────────────\n\n/** True if `dir` is itself a git repo (has its own `.git`). */\nfunction hasOwnGit(dir: string): boolean {\n return existsSync(join(dir, \".git\"));\n}\n\n/**\n * The global source-clone cache: `<cacheRoot>/sources` (override the root with\n * `SKAILE_CACHE_DIR`). On first call it migrates both legacy clone roots into it:\n * the whole of `~/.skaile/repos/*`, and the own-`.git` (clone) entries of\n * `~/.skaile/sources/*`. The non-clone remainder of `~/.skaile/sources` is the\n * sidecar repo and is migrated separately by `getSidecarRoot()`.\n * @docLink packages/core/api-reference#get-global-cache-dir\n */\nexport function getGlobalCacheDir(): string {\n const dir = join(globalCacheRoot(), \"sources\");\n // Legacy roots are anchored at SKAILE_HOME, not the cache root — do not derive\n // them from globalCacheRoot() (SKAILE_CACHE_DIR may point elsewhere).\n const home = process.env.SKAILE_HOME ?? join(homedir(), \".skaile\");\n mergeLegacyEntriesInto(dir, join(home, \"repos\"), () => true);\n mergeLegacyEntriesInto(dir, join(home, \"sources\"), hasOwnGit);\n return dir;\n}\n\n// ── Clone-cache key ──────────────────────────────────────────────────────────\n\n/**\n * Canonical clone-cache key for a source git URL: `<host>/<owner>/<repo>`\n * (lowercased host; `.git` suffix, trailing slash, and protocol/scp prefix\n * stripped). This is the SSOT for the clone-cache path under\n * `getGlobalCacheDir()` — every writer and reader of that cache MUST derive its\n * key here.\n *\n * It exists because the old \"last path segment\" slug collided: both\n * `github.com/orgA/ai-assets` and `github.com/orgB/ai-assets` mapped to\n * `ai-assets`, so the wrong repo was served from cache silently. Keying by the\n * full `<host>/<owner>/<repo>` triple makes that collision impossible.\n *\n * Non-GitHub or unparseable URLs (local paths, `file://`, exotic hosts) fall\n * back to the last path segment so nothing throws.\n *\n * @docLink packages/core/api-reference#source-cache-key\n */\nexport function sourceCacheKey(url: string): string {\n const trimmed = url.trim();\n const normalized = trimmed\n .replace(/^git@([^:]+):/, \"$1/\") // git@host:owner/repo → host/owner/repo\n .replace(/^[a-z][a-z0-9+.-]*:\\/\\//i, \"\") // drop scheme (https://, ssh://, file://, …)\n .replace(/\\.git$/i, \"\")\n .replace(/\\/+$/, \"\");\n const m = /^([^/]+)\\/([^/]+)\\/([^/]+)$/.exec(normalized);\n if (m) {\n const [, host, owner, repo] = m;\n return `${host.toLowerCase()}/${owner}/${repo}`;\n }\n return lastSegment(trimmed);\n}\n\nfunction lastSegment(url: string): string {\n return (\n url\n .replace(/\\.git$/i, \"\")\n .replace(/\\/+$/, \"\")\n .split(/[/:]/)\n .pop() || \"source\"\n );\n}\n\n/**\n * Short repo name (`<repo>`) for a cache key produced by {@link sourceCacheKey}\n * (or a raw URL). Used where a single human-facing label or library name is\n * wanted instead of the full `<host>/<owner>/<repo>` triple.\n */\nexport function sourceShortName(cacheKeyOrUrl: string): string {\n return sourceCacheKey(cacheKeyOrUrl).replace(/\\/+$/, \"\").split(\"/\").pop() || \"source\";\n}\n\n// ── Git operations ───────────────────────────────────────────────────────────\n\n/**\n * Shared env for all git subprocess spawns.\n * GIT_TERMINAL_PROMPT=0 prevents git from opening /dev/tty to ask for\n * credentials when running inside a CLI spinner (which holds the terminal in\n * raw mode). Without this, git bypasses stdio: \"pipe\" and the process hangs\n * indefinitely waiting for input that can never arrive.\n */\nconst GIT_ENV = { ...process.env, GIT_TERMINAL_PROMPT: \"0\" };\n\n/**\n * Clone a remote git repository using partial clone (treeless) with sparse checkout.\n * Falls back to a regular shallow clone if the server does not support partial clones.\n *\n * @param url - Remote git URL\n * @param branch - Branch to clone\n * @param dest - Local destination directory\n * @returns `true` on success, `false` on failure\n * @docLink packages/core/api-reference#clone-repo\n */\nexport function cloneRepo(url: string, branch: string, dest: string): boolean {\n mkdirSync(dest, { recursive: true });\n // Try partial clone first (requires git 2.25+ and server support)\n const r = spawnSync(\n \"git\",\n [\"clone\", \"--depth=1\", \"--filter=blob:none\", \"--sparse\", \"--branch\", branch, url, dest],\n { stdio: \"pipe\", env: GIT_ENV },\n );\n if (r.status === 0) {\n // Enable cone mode for sparse checkout\n spawnSync(\"git\", [\"-C\", dest, \"sparse-checkout\", \"init\", \"--cone\"], {\n stdio: \"pipe\",\n env: GIT_ENV,\n });\n // Check out everything initially (for discovery)\n spawnSync(\"git\", [\"-C\", dest, \"sparse-checkout\", \"disable\"], { stdio: \"pipe\", env: GIT_ENV });\n return true;\n }\n // Fallback: regular shallow clone\n const fallback = spawnSync(\"git\", [\"clone\", \"--depth=1\", \"--branch\", branch, url, dest], {\n stdio: \"pipe\",\n env: GIT_ENV,\n });\n return fallback.status === 0;\n}\n\n/**\n * Pull the latest commits for a cloned repository.\n * On shallow clone divergence, falls back to `git fetch --depth=1` + `git reset --hard`.\n *\n * @param dest - Local repo directory\n * @param branch - Branch to pull\n * @returns `true` on success, `false` on failure\n * @docLink packages/core/api-reference#pull-repo\n */\nexport function pullRepo(dest: string, branch: string): boolean {\n const r = spawnSync(\"git\", [\"-C\", dest, \"pull\", \"--depth=1\", \"--ff-only\"], {\n stdio: \"pipe\",\n env: GIT_ENV,\n });\n if (r.status === 0) return true;\n // Shallow clones can diverge — force-sync via fetch + reset\n const fetch = spawnSync(\"git\", [\"-C\", dest, \"fetch\", \"--depth=1\", \"origin\", branch], {\n stdio: \"pipe\",\n env: GIT_ENV,\n });\n if (fetch.status !== 0) return false;\n const reset = spawnSync(\"git\", [\"-C\", dest, \"reset\", \"--hard\", `origin/${branch}`], {\n stdio: \"pipe\",\n env: GIT_ENV,\n });\n return reset.status === 0;\n}\n\n/**\n * Return the current HEAD commit SHA for a local repository.\n *\n * @param repoDir - Absolute path to the cloned repository\n * @returns Full commit SHA string, or `null` on failure\n * @docLink packages/core/api-reference#get-repo-commit\n */\nexport function getRepoCommit(repoDir: string): string | null {\n const r = spawnSync(\"git\", [\"-C\", repoDir, \"rev-parse\", \"HEAD\"], {\n encoding: \"utf8\",\n stdio: \"pipe\",\n });\n return r.status === 0 ? r.stdout.trim() : null;\n}\n\n/**\n * Check out a specific tag, branch, or commit SHA in a local repository.\n * Fetches the ref from `origin` first, then attempts `FETCH_HEAD` checkout.\n *\n * @param repoDir - Absolute path to the cloned repository\n * @param pin - Tag, branch name, or commit SHA\n * @returns `true` on success, `false` on failure\n * @docLink packages/core/api-reference#checkout-pin\n */\nexport function checkoutPin(repoDir: string, pin: string): boolean {\n // Fetch the ref first (works for tags, branches, and commits)\n spawnSync(\"git\", [\"-C\", repoDir, \"fetch\", \"--depth=1\", \"origin\", pin], {\n stdio: \"pipe\",\n env: GIT_ENV,\n });\n const r = spawnSync(\"git\", [\"-C\", repoDir, \"checkout\", \"FETCH_HEAD\"], {\n stdio: \"pipe\",\n env: GIT_ENV,\n });\n if (r.status === 0) return true;\n // Fallback: try direct checkout (for branches already fetched)\n const r2 = spawnSync(\"git\", [\"-C\", repoDir, \"checkout\", pin], { stdio: \"pipe\", env: GIT_ENV });\n return r2.status === 0;\n}\n\n/** Read a clone's `origin` remote URL, or `null` when it is absent / not a repo. */\nfunction getRepoRemoteUrl(repoDir: string): string | null {\n const r = spawnSync(\"git\", [\"-C\", repoDir, \"remote\", \"get-url\", \"origin\"], {\n encoding: \"utf8\",\n stdio: \"pipe\",\n env: GIT_ENV,\n });\n return r.status === 0 ? r.stdout.trim() : null;\n}\n\n/** True when the clone's origin maps to the same cache key as the declared URL. */\nfunction remoteUrlMatches(repoDir: string, expectedUrl: string): boolean {\n // Only a dir that is its OWN git root can be verified. A local source path that\n // is NOT a standalone clone (e.g. the in-repo factory-assets tree) would make\n // `git -C` report the ENCLOSING repo's remote, falsely \"mismatch\", and get\n // wiped. Treat \"not its own clone\" as a match so it is never destroyed.\n if (!hasOwnGit(repoDir)) return true;\n const actual = getRepoRemoteUrl(repoDir);\n if (!actual) return true; // no remote info → don't destroy; assume ok\n return sourceCacheKey(actual) === sourceCacheKey(expectedUrl);\n}\n\n// ── Link management ──────────────────────────────────────────────────────────\n\n/**\n * Map of repo name → local filesystem path for development overrides.\n * Stored in `.skaile/links.yaml`; used to redirect a named repo to a local clone.\n * @docLink packages/core/api-reference#link-config\n */\nexport interface LinkConfig {\n [repoName: string]: string; // repo name → local path\n}\n\n/** Path to the project-local links file. */\nfunction linksFile(projectDir: string): string {\n return join(projectDir, \".skaile\", \"links.yaml\");\n}\n\n/**\n * Read the dev-link map from `.skaile/links.yaml` in the project directory.\n * Returns an empty object when no links file exists.\n *\n * @param projectDir - Absolute path to the project root\n * @returns `LinkConfig` map (may be empty)\n * @docLink packages/core/api-reference#read-links\n */\nexport function readLinks(projectDir: string): LinkConfig {\n const file = linksFile(projectDir);\n if (!existsSync(file)) return {};\n try {\n return (parse(readFileSync(file, \"utf8\")) as LinkConfig) ?? {};\n } catch {\n return {};\n }\n}\n\n/**\n * Persist the dev-link map to `.skaile/links.yaml` in the project directory.\n *\n * @param projectDir - Absolute path to the project root\n * @param links - Updated `LinkConfig` to write\n * @docLink packages/core/api-reference#write-links\n */\nexport function writeLinks(projectDir: string, links: LinkConfig): void {\n const dir = join(projectDir, \".skaile\");\n mkdirSync(dir, { recursive: true });\n writeFileSync(linksFile(projectDir), stringify(links));\n}\n\n/**\n * Register a local filesystem path as a dev override for a named repository.\n * The path is stored in `.skaile/links.yaml` and takes priority over the remote URL at runtime.\n *\n * @param projectDir - Absolute path to the project root\n * @param repoName - Name of the repository to override\n * @param localPath - Local path (absolute or relative to `projectDir`) to use instead\n * @throws When the resolved path does not exist\n * @docLink packages/core/api-reference#link-repo\n */\nexport function linkRepo(projectDir: string, repoName: string, localPath: string): void {\n const resolved = resolve(projectDir, localPath);\n if (!existsSync(resolved)) {\n throw new Error(`Path not found: ${localPath} (resolved: ${resolved})`);\n }\n const links = readLinks(projectDir);\n links[repoName] = resolved;\n writeLinks(projectDir, links);\n}\n\n/**\n * Remove the dev-link override for a named repository, reverting it to the remote URL.\n *\n * @param projectDir - Absolute path to the project root\n * @param repoName - Name of the repository to unlink\n * @returns `true` if the link existed and was removed, `false` if no link was found\n * @docLink packages/core/api-reference#unlink-repo\n */\nexport function unlinkRepo(projectDir: string, repoName: string): boolean {\n const links = readLinks(projectDir);\n if (!links[repoName]) return false;\n delete links[repoName];\n writeLinks(projectDir, links);\n return true;\n}\n\n// ── Repo lifecycle ───────────────────────────────────────────────────────────\n\n/**\n * Ensure a repository is available locally, cloning or symlinking as needed.\n *\n * Resolution order:\n * 1. Linked override (`.skaile/links.yaml`) — highest priority\n * 2. Local path (`decl.path`) — direct filesystem reference; a bare path must\n * already exist, but a url-backed managed cache dir is cloned in-place on miss\n * 3. Remote URL (`decl.url`) — cloned to the shared global cache, symlinked into `.skaile/cache/sources/`\n *\n * Pin support: when `opts.pin` is provided, the tag/commit is checked out after clone.\n *\n * @param decl - Repository declaration from `skaile.yaml`\n * @param name - Logical repository name (cache key)\n * @param reposDir - Project-local source-clone directory (`.skaile/cache/sources/`)\n * @param opts - Optional: `pin` for a specific commit/tag, `projectDir` for link lookup\n * @returns Absolute path to the local repository directory\n * @throws When the repository cannot be resolved or cloned\n * @docLink packages/core/api-reference#ensure-repo\n */\nexport function ensureRepo(\n decl: SourceDeclaration,\n name: string,\n reposDir: string,\n opts?: { pin?: string; projectDir?: string },\n): string {\n // 1. Check for linked override\n const linked = resolveLinkedOverride(name, opts?.projectDir);\n if (linked) return linked;\n\n // 2. Local path (or managed cache dir for a remote source)\n if (decl.path) {\n return ensureLocalPathRepo(decl, reposDir, opts);\n }\n\n // 3. Remote URL — clone to shared global cache\n if (decl.url) {\n return ensureRemoteRepo(decl, name, reposDir, opts);\n }\n\n throw new Error(`Repository \"${name}\" has neither url nor path`);\n}\n\n/**\n * Step 1 of {@link ensureRepo}: resolve a dev-link override for `name`, if one\n * exists. Returns the linked path (validated to exist) or `null` when no link\n * is configured.\n */\nfunction resolveLinkedOverride(name: string, projectDir?: string): string | null {\n if (!projectDir) return null;\n const links = readLinks(projectDir);\n const linked = links[name];\n if (!linked) return null;\n if (!existsSync(linked)) {\n throw new Error(\n `Linked path not found: ${linked}. Remove the .skaile/links.yaml entry to clear it.`,\n );\n }\n return linked;\n}\n\n/**\n * Step 2 of {@link ensureRepo}: resolve a `decl.path` source. A bare local path\n * must already exist; a url-backed managed cache dir is ours to populate, so it\n * is cloned in-place on first miss.\n */\nfunction ensureLocalPathRepo(\n decl: SourceDeclaration,\n reposDir: string,\n opts?: { pin?: string; projectDir?: string },\n): string {\n const projectDir = opts?.projectDir ?? resolve(reposDir, \"..\");\n const resolved = resolve(projectDir, decl.path as string);\n // A managed cache dir whose origin maps to a different key than `decl.url` is a\n // stale flat-slug collision — wipe and re-clone so the wrong repo is never used.\n if (existsSync(resolved)) {\n if (!decl.url || remoteUrlMatches(resolved, decl.url)) return resolved;\n rmSync(resolved, { recursive: true, force: true });\n }\n if (!decl.url) {\n throw new Error(`Local repository path not found: ${decl.path} (resolved: ${resolved})`);\n }\n mkdirSync(dirname(resolved), { recursive: true });\n if (!cloneRepo(decl.url, decl.branch ?? \"main\", resolved)) {\n throw new Error(`Failed to clone ${decl.url} into ${resolved}`);\n }\n if (opts?.pin) checkoutPin(resolved, opts.pin);\n return resolved;\n}\n\n/**\n * Step 3 of {@link ensureRepo}: clone/pull a remote `decl.url` source into the\n * shared global cache, checkout any pin, then symlink it into the project-local\n * `.skaile/cache/sources/`. Returns the global cache path.\n */\nfunction ensureRemoteRepo(\n decl: SourceDeclaration,\n name: string,\n reposDir: string,\n opts?: { pin?: string; projectDir?: string },\n): string {\n const branch = decl.branch ?? \"main\";\n const globalCache = getGlobalCacheDir();\n const cacheDest = join(globalCache, name);\n\n // Clone or pull in global cache. A cache dir whose origin maps to a different\n // key than `decl.url` is a stale flat-slug collision — wipe and re-clone so\n // the wrong repo is never served.\n const cached = existsSync(join(cacheDest, \".git\"));\n if (cached && remoteUrlMatches(cacheDest, decl.url as string)) {\n if (!opts?.pin) pullRepo(cacheDest, branch);\n } else {\n if (cached) rmSync(cacheDest, { recursive: true, force: true });\n mkdirSync(dirname(cacheDest), { recursive: true });\n if (!cloneRepo(decl.url as string, branch, cacheDest)) {\n throw new Error(`Failed to clone ${decl.url} (branch: ${branch})`);\n }\n }\n\n // Checkout pin if specified\n if (opts?.pin) {\n checkoutPin(cacheDest, opts.pin);\n }\n\n linkCacheIntoProject(cacheDest, reposDir, name);\n return cacheDest;\n}\n\n/**\n * Create (or repair) the project-local `.skaile/cache/sources/<name>` symlink pointing\n * at the global cache. A stale real directory (legacy clone) is replaced. All\n * symlink failures are swallowed — callers fall back to the cache dir directly.\n */\nfunction linkCacheIntoProject(cacheDest: string, reposDir: string, name: string): void {\n const projectDest = join(reposDir, name);\n const projectExists = existsSync(projectDest);\n const isSymlink = projectExists && lstatSync(projectDest).isSymbolicLink();\n\n if (!projectExists) {\n mkdirSync(reposDir, { recursive: true });\n try {\n symlinkSync(cacheDest, projectDest);\n } catch {\n // Symlink failed (Windows?), just use cache dir directly\n }\n } else if (!isSymlink) {\n // Stale real directory (legacy clone) — replace with symlink to global cache\n rmSync(projectDest, { recursive: true });\n try {\n symlinkSync(cacheDest, projectDest);\n } catch {\n // Symlink failed, fall through to return cacheDest\n }\n }\n}\n\n// ── Scanning ─────────────────────────────────────────────────────────────────\n\n/**\n * Derive the `\"<org>/<repo>\"` slug from a directory's git `origin` remote.\n * Returns `undefined` when `rootDir` is not a git repo, has no `origin` remote,\n * or the URL is not a parseable GitHub repo. Mirrors the store's\n * `repoSlugFromSourceUrl` so local and remote feeds key the grouping tree\n * identically.\n *\n * @param rootDir - Absolute path to the scanned repository root\n * @returns `\"<org>/<repo>\"` or `undefined`\n * @docLink packages/core/api-reference#repo-slug-from-git-remote\n */\nfunction repoSlugFromGitRemote(rootDir: string): string | undefined {\n const r = spawnSync(\"git\", [\"-C\", rootDir, \"config\", \"--get\", \"remote.origin.url\"], {\n encoding: \"utf8\",\n stdio: \"pipe\",\n env: GIT_ENV,\n });\n if (r.status !== 0) return undefined;\n const m = /github\\.com[/:]([^/]+)\\/([^/]+?)(?:\\.git)?\\/?$/.exec(r.stdout.trim());\n return m ? `${m[1]}/${m[2]}` : undefined;\n}\n\n/**\n * Resolve a scanned source's canonical publisher: the declared `publisher` in\n * the root `skaile.manifest.yaml`, else the GitHub org from the `origin` remote.\n * Returns `undefined` when neither is available, so callers can fall back to the\n * repo config key.\n *\n * Single source of truth shared by the source/library scanner (`scanRepo`) and\n * the index/discovery side (`LocalCatalogSource.sync`) so both key an asset\n * identically. The org fallback is lowercased to its GitHub-shaped slug\n * (GitHub orgs are case-insensitive — a cased remote like `Acme` must not split\n * from the lowercase index ref). A declared manifest publisher is returned\n * verbatim (both paths read the same value, so they stay in parity).\n *\n * @param repoDir - Absolute path to the scanned repository root\n * @returns The publisher slug (no `@` sigil) or `undefined`\n * @docLink packages/core/api-reference#resolve-source-publisher\n */\nexport function resolveSourcePublisher(repoDir: string): string | undefined {\n const manifestPath = join(repoDir, SKAILE_MANIFEST_FILENAME);\n if (existsSync(manifestPath)) {\n try {\n const raw = parse(readFileSync(manifestPath, \"utf8\")) as Record<string, unknown> | null;\n if (raw && typeof raw.publisher === \"string\" && raw.publisher.length > 0)\n return raw.publisher;\n } catch {}\n }\n const org = repoSlugFromGitRemote(repoDir)?.split(\"/\")[0];\n return org ? normalizeGithubOrg(org) : undefined;\n}\n\n/**\n * Scan a repository directory and return all discovered asset catalog entries.\n * Delegates to `scanDirectory` from `manifest.ts`, then stamps the `repo` slug\n * derived once from the root's git remote onto every entry (the GitHub\n * coordinate is a property of the scanned root, not of individual assets).\n *\n * The `publisher` field is overridden with the source's declared canonical\n * publisher (`skaile.yaml` `publisher` / GitHub org) so refs emitted from\n * filename-convention scans match the provenance index `resolveAll` builds.\n * Without this, a source whose declared publisher differs from its config slug\n * yields refs (`name@<slug>`) that resolution can't find (`name@<publisher>`).\n *\n * @param repoDir - Absolute path to the repository root\n * @param repoName - Repository config key; fallback publisher and `repository` field\n * @returns Array of `CatalogEntry` objects found in the repository\n * @docLink packages/core/api-reference#scan-repo\n */\nexport function scanRepo(repoDir: string, repoName: string): CatalogEntry[] {\n const repo = repoSlugFromGitRemote(repoDir);\n const publisher = resolveSourcePublisher(repoDir) ?? repoName;\n return scanDirectory(repoDir, repoName).map((e) => ({\n ...e,\n publisher,\n ...(repo ? { repo } : {}),\n }));\n}\n\n// ── Resolution ───────────────────────────────────────────────────────────────\n\n/**\n * Resolve a single asset reference to its `CatalogEntry` by scanning declared repositories.\n *\n * Search order:\n * 1. Explicit `@repository` qualifier on the ref — only that repo is searched.\n * 2. `opts.preferRepo` — searched first when set (repo affinity for transitive deps).\n * 3. All declared repos in declaration order.\n *\n * @param ref - Parsed asset reference to resolve\n * @param repositories - Repository declarations from `skaile.yaml`\n * @param reposDir - Project-local source-clone directory (`.skaile/cache/sources/`)\n * @param opts - Optional: `projectDir` for link lookup, `preferRepo` for affinity\n * @returns Matching `CatalogEntry`, or `null` if not found in any repository\n * @docLink packages/core/api-reference#resolve-asset\n */\nexport function resolveAsset(\n ref: AssetRef,\n repositories: Record<string, SourceDeclaration>,\n reposDir: string,\n opts?: { projectDir?: string; preferRepo?: string },\n): CatalogEntry | null {\n let repoNames: string[];\n if (ref.publisher) {\n // Explicit @repo qualifier — only search that repo\n repoNames = [ref.publisher];\n } else if (opts?.preferRepo && opts.preferRepo in repositories) {\n // Repo affinity from parent — search preferred repo first, then others\n const rest = Object.keys(repositories).filter((n) => n !== opts.preferRepo);\n repoNames = [opts.preferRepo, ...rest];\n } else {\n repoNames = Object.keys(repositories);\n }\n\n for (const repoName of repoNames) {\n const decl = repositories[repoName];\n if (!decl) continue;\n\n const repoDir = resolveRepoDir(decl, repoName, reposDir, opts?.projectDir);\n if (!repoDir || !existsSync(repoDir)) continue;\n\n const entries = scanRepo(repoDir, repoName);\n const match = entries.find((e) => e.kind === ref.kind && e.name === ref.name);\n if (match) return match;\n }\n\n return null;\n}\n\n/** Resolve repo dir without cloning (for lookups). Checks links first. */\nfunction resolveRepoDir(\n decl: SourceDeclaration,\n name: string,\n reposDir: string,\n projectDir?: string,\n): string | null {\n // Check links\n if (projectDir) {\n const links = readLinks(projectDir);\n if (links[name]) {\n return existsSync(links[name]) ? links[name] : null;\n }\n }\n\n if (decl.path) {\n const base = projectDir ?? resolve(reposDir, \"..\");\n const resolved = resolve(base, decl.path);\n return existsSync(resolved) ? resolved : null;\n }\n\n // Check project-local symlink or global cache. A global cache dir whose origin\n // maps to a different key than `decl.url` is a stale collision — skip it rather\n // than scan the wrong repo (re-clone happens on the next ensureRepo).\n const projectDest = join(reposDir, name);\n if (existsSync(projectDest)) return projectDest;\n\n const globalDest = join(getGlobalCacheDir(), name);\n if (existsSync(join(globalDest, \".git\"))) {\n if (decl.url && !remoteUrlMatches(globalDest, decl.url)) return null;\n return globalDest;\n }\n\n return null;\n}\n\n/**\n * Hard error raised when two or more candidates for the same canonical ref\n * `<publisher>/<kind>:<name>@<version>` disagree on their content sha256 and no\n * `overrides[]` entry resolves the conflict. The message walks the dep chain\n * back to the user-declared root.\n * @docLink packages/core/api-reference#canonical-ref-conflict-error\n */\nexport class CanonicalRefConflictError extends Error {\n constructor(\n public ref: string,\n public candidates: ProvenanceCandidate[],\n public depChain: string[],\n ) {\n super(\n [\n `error: divergent sha256 for ${ref}`,\n \"\",\n \" pulled in via:\",\n ...depChain.map((s, i) => ` ${\" \".repeat(i * 2)}${s}`),\n \"\",\n \" candidates:\",\n ...candidates.map(\n (c) => ` ${c.sourceUrl} @ ${c.commit.slice(0, 8)}\\n sha256: ${c.sha256}`,\n ),\n \"\",\n \"resolve by:\",\n \" 1. removing one source from skaile.yaml,\",\n \" 2. configuring a store and using its canonical digest, or\",\n \" 3. adding to overrides: (with a non-empty reason:)\",\n ].join(\"\\n\"),\n );\n this.name = \"CanonicalRefConflictError\";\n }\n}\n\n/**\n * Result of a full transitive dependency resolution via `resolveAll`.\n * @docLink packages/core/api-reference#resolve-result\n */\nexport interface ResolveResult {\n /** Resolved candidates in leaf-first order. */\n resolved: ProvenanceCandidate[];\n /** Refs that no source / store could provide. */\n missing: string[];\n /** \"<publisher>/<kind>:<name>\" → parent ref (\"direct\" if user-declared). */\n resolvedBy: Map<string, string>;\n /** Overrides that were applied (lock-side bookkeeping); canonical refs. */\n overridesApplied: Set<string>;\n}\n\n/** Minimal store fetcher contract used by the resolver for the catalog branch. */\nexport interface StoreFetcher {\n getInstallManifest(\n storeUrl: string,\n ref: string,\n ): Promise<{\n sourceUrl: string;\n commit: string;\n sha256: string;\n files: Array<{ path: string; sha256: string }>;\n } | null>;\n getCanonicalDigest(storeUrl: string, ref: string): Promise<{ sha256: string } | null>;\n /**\n * Enumerate the versions a store can serve for a version-less ref\n * (`kind:@<publisher>/name`). Optional — when present, the resolver uses it to\n * discover candidate versions for a store-only asset whose dep ref is bare or\n * ranged (no source clone to derive a version hint from). Absent ⇒ the\n * resolver falls back to the source-derived hint only (legacy behaviour).\n */\n listVersions?(storeUrl: string, ref: string): Promise<string[]>;\n}\n\n/** Options for {@link resolveAll}. */\nexport interface ResolveOpts {\n /** Source-side candidate index built by the walker. */\n provenanceIndex: ProvenanceIndex;\n /** Conflict-resolution overrides (with required reason). */\n overrides: OverrideEntry[];\n /** Trusted store catalogs. */\n stores: StoreEntry[];\n /** Lazy store fetcher; only used when `stores[]` is non-empty. */\n storeFetcher?: StoreFetcher;\n projectDir?: string;\n}\n\nconst SHA_PIN_RE = /^[0-9a-f]{40}$/i;\n\n/**\n * Ensure a transitive dep ref carries a publisher, inheriting `fallback` (the\n * parent candidate's publisher) when absent. Keeps any `#pin` suffix in place.\n * A ref that already names a publisher is returned unchanged; a bare\n * `kind:name[#pin]` ref is re-emitted in the scope form `kind:@publisher/name[#pin]`.\n */\nfunction qualifyPublisher(ref: string, fallback: string): string {\n const hashIdx = ref.indexOf(\"#\");\n const head = hashIdx === -1 ? ref : ref.slice(0, hashIdx);\n // A scoped ref carries `@publisher/`; bare refs (`kind:name`) don't. `parseAssetRef`\n // throws on a bare ref, so detect the scope sigil by string before building one.\n if (head.includes(\"@\")) return ref;\n const pin = hashIdx === -1 ? undefined : ref.slice(hashIdx + 1) || undefined;\n const colonIdx = head.indexOf(\":\");\n const kind = colonIdx === -1 ? \"skill\" : head.slice(0, colonIdx);\n const name = colonIdx === -1 ? head : head.slice(colonIdx + 1);\n return assetRefToStr({ kind, name, publisher: fallback, pin });\n}\n\n/**\n * Resolve all dependencies against a content-hash-verified candidate set drawn\n * from every source clone and (optionally) every store.\n *\n * Per dep ref: gather source candidates, optionally extend with store\n * candidates, filter by the SemVer/SHA pin, pick the highest matching version,\n * then detect conflicts — divergent sha256 for the same\n * `(publisher, kind, name, version)` is a hard {@link CanonicalRefConflictError}\n * unless an `overrides[]` entry pins a source. A cheap `getCanonicalDigest`\n * cross-check runs when both a source and a store produced a candidate at the\n * chosen version.\n *\n * @param deps - Top-level canonical asset ref strings (`kind:@<publisher>/name[#pin]`).\n * @param opts - Provenance index, overrides, stores, and an optional store fetcher.\n * @returns `ResolveResult` with resolved candidates, missing refs, provenance map, applied overrides.\n * @docLink packages/core/api-reference#resolve-all\n */\nexport async function resolveAll(deps: string[], opts: ResolveOpts): Promise<ResolveResult> {\n const resolved: ProvenanceCandidate[] = [];\n const seen = new Set<string>(); // <publisher>/<kind>:<name>\n const missing: string[] = [];\n const resolvedBy = new Map<string, string>();\n const overridesApplied = new Set<string>();\n const overridesByRef = new Map(opts.overrides.map((o) => [o.ref, o]));\n\n async function visit(refStr: string, parent: string, depChain: string[]): Promise<void> {\n const ref = parseAssetRef(refStr); // throws on floating refs etc.\n if (!ref.publisher) throw new Error(`dep \"${refStr}\" missing publisher`);\n const key = `${ref.publisher}/${ref.kind}:${ref.name}`;\n if (seen.has(key)) return;\n seen.add(key);\n\n // 1. Source-side candidates.\n const sourceCandidates = opts.provenanceIndex.get(key) ?? [];\n\n // 2. Optional store-side candidates.\n const storeCandidates = await gatherStoreCandidates(ref, ref.publisher, sourceCandidates, opts);\n\n const all = [...sourceCandidates, ...storeCandidates];\n if (all.length === 0) {\n missing.push(refStr);\n return;\n }\n\n // 3. Filter by pin.\n const filtered = all.filter((c) => matchPin(ref.pin, c.version));\n if (filtered.length === 0) {\n missing.push(refStr);\n return;\n }\n\n // 4. Highest-version finalists.\n const versions = Array.from(new Set(filtered.map((c) => c.version)));\n const best = versions.sort((a, b) => semver.rcompare(coerceVersion(a), coerceVersion(b)))[0]!;\n const finalists = filtered.filter((c) => c.version === best);\n // Canonical ref == lock key == store wire ref: `kind:@publisher/name#version`.\n const canonicalRef = assetRefToStr({ ...ref, pin: best });\n\n // 5. Conflict detection.\n const chosen = selectChosenCandidate(\n finalists,\n canonicalRef,\n overridesByRef,\n overridesApplied,\n [...depChain, refStr],\n );\n\n // 6. Cheap cross-check when both source and store produced a candidate.\n await crossCheckStoreDigest(\n chosen,\n finalists,\n canonicalRef,\n best,\n sourceCandidates,\n storeCandidates,\n opts,\n [...depChain, refStr],\n );\n\n resolved.push(chosen);\n resolvedBy.set(key, parent);\n\n // Transitive expansion. Bundle candidates carry canonical dep refs; recurse\n // so a bundle pulls its members (and nested bundles, arbitrary depth). The\n // `seen` set above dedupes shared deps and breaks cycles. A bare ref inherits\n // the parent's publisher (same-source assumption).\n for (const depRef of chosen.deps ?? []) {\n await visit(qualifyPublisher(depRef, chosen.publisher), key, [...depChain, refStr]);\n }\n }\n\n for (const dep of deps) {\n await visit(dep, \"direct\", []);\n }\n return { resolved, missing, resolvedBy, overridesApplied };\n}\n\n/**\n * Step 2 of `resolveAll`'s `visit`: gather store-side candidates for `ref`.\n * For each store, derive a version hint (source-derived, or — for a bare/ranged\n * pin with no source hint and a `listVersions` capable fetcher — store-enumerated)\n * and fetch an install manifest per candidate version. Pure: reads `opts`, no\n * closure state. Returns `[]` when no store / fetcher is configured.\n */\nasync function gatherStoreCandidates(\n ref: AssetRef,\n publisher: string,\n sourceCandidates: ProvenanceCandidate[],\n opts: ResolveOpts,\n): Promise<ProvenanceCandidate[]> {\n const storeCandidates: ProvenanceCandidate[] = [];\n if (opts.stores.length === 0 || !opts.storeFetcher) return storeCandidates;\n\n const sourceVersions = sourceCandidates.map((c) => c.version);\n const fetcher = opts.storeFetcher;\n for (const store of opts.stores) {\n // Store-only fallback: with no source-derived version hint and a bare or\n // ranged pin, ask the store which versions it has so the dep can resolve\n // instead of landing in `missing` (exact pins/SHAs need no discovery).\n let versionsHint = sourceVersions;\n if (versionsHint.length === 0 && needsStoreVersionDiscovery(ref.pin) && fetcher.listVersions) {\n versionsHint = await fetcher.listVersions(\n store.url,\n assetRefToStr({ ...ref, pin: undefined }),\n );\n }\n const candidateVersions = enumerateVersionsForPin(ref.pin, versionsHint);\n for (const v of candidateVersions) {\n if (!v) continue;\n const m = await fetcher.getInstallManifest(store.url, assetRefToStr({ ...ref, pin: v }));\n if (m) {\n storeCandidates.push({\n publisher,\n kind: ref.kind,\n name: ref.name,\n version: v,\n sourceUrl: m.sourceUrl,\n commit: m.commit,\n files: m.files,\n sha256: m.sha256,\n });\n }\n }\n }\n return storeCandidates;\n}\n\n/**\n * Step 5 of `resolveAll`'s `visit`: pick the chosen candidate among the\n * highest-version finalists. Divergent sha256 is a hard conflict unless an\n * `overrides[]` entry pins a source (recorded in `overridesApplied`); otherwise\n * the pick is deterministic by `sourceUrl` ascending.\n */\nfunction selectChosenCandidate(\n finalists: ProvenanceCandidate[],\n canonicalRef: string,\n overridesByRef: Map<string, OverrideEntry>,\n overridesApplied: Set<string>,\n conflictChain: string[],\n): ProvenanceCandidate {\n const uniqueShas = Array.from(new Set(finalists.map((c) => c.sha256)));\n if (uniqueShas.length > 1) {\n const override = overridesByRef.get(canonicalRef);\n if (!override) {\n throw new CanonicalRefConflictError(canonicalRef, finalists, conflictChain);\n }\n const pick = finalists.find((c) => c.sourceUrl === override.source);\n if (!pick) {\n throw new Error(\n `override for ${canonicalRef} points at ${override.source}, ` +\n \"which is not among the resolved candidates\",\n );\n }\n overridesApplied.add(canonicalRef);\n return pick;\n }\n // No conflict — deterministic pick by sourceUrl asc.\n return [...finalists].sort((a, b) => a.sourceUrl.localeCompare(b.sourceUrl))[0]!;\n}\n\n/**\n * Step 6 of `resolveAll`'s `visit`: cheap cross-check that runs only when both a\n * source and a store produced a candidate at the chosen `best` version. A store\n * canonical digest that disagrees with `chosen.sha256` is a hard conflict.\n */\nasync function crossCheckStoreDigest(\n chosen: ProvenanceCandidate,\n finalists: ProvenanceCandidate[],\n canonicalRef: string,\n best: string,\n sourceCandidates: ProvenanceCandidate[],\n storeCandidates: ProvenanceCandidate[],\n opts: ResolveOpts,\n conflictChain: string[],\n): Promise<void> {\n if (\n !opts.storeFetcher ||\n opts.stores.length === 0 ||\n !sourceCandidates.some((c) => c.version === best) ||\n !storeCandidates.some((c) => c.version === best)\n ) {\n return;\n }\n for (const store of opts.stores) {\n const d = await opts.storeFetcher.getCanonicalDigest(store.url, canonicalRef);\n if (d && d.sha256 !== chosen.sha256) {\n throw new CanonicalRefConflictError(\n canonicalRef,\n [...finalists, { ...chosen, sourceUrl: store.url, sha256: d.sha256 }],\n conflictChain,\n );\n }\n }\n}\n\n/** Coerce a version string to a semver-comparable form (synthetic 0.0.0-sha.X is valid semver). */\nfunction coerceVersion(v: string): string {\n return semver.valid(v) ? v : (semver.coerce(v)?.version ?? \"0.0.0\");\n}\n\n/** Match a candidate version against a pin (SemVer range, exact, 40-char SHA, or absent). */\nfunction matchPin(pin: string | undefined, version: string): boolean {\n if (!pin) return true;\n if (SHA_PIN_RE.test(pin)) {\n // SHA pin matches only the synthetic version it produced.\n return version === `0.0.0-sha.${pin.slice(0, 7)}`;\n }\n if (version.startsWith(\"0.0.0-sha.\")) {\n // Synthetic versions satisfy ONLY their exact literal pin.\n return version === pin;\n }\n if (!semver.valid(version)) return version === pin;\n return semver.satisfies(version, pin, { includePrerelease: false });\n}\n\n/**\n * Whether the resolver should ask the store to enumerate versions. True for a\n * bare ref (no pin) or a SemVer range; false for an exact-version pin or a SHA\n * pin (those name a single version, so `getInstallManifest` can be queried\n * directly without discovery).\n */\nfunction needsStoreVersionDiscovery(pin: string | undefined): boolean {\n if (!pin) return true;\n if (SHA_PIN_RE.test(pin)) return false;\n return !semver.valid(pin);\n}\n\nfunction enumerateVersionsForPin(pin: string | undefined, sourceVersionsHint: string[]): string[] {\n if (!pin) return sourceVersionsHint.length > 0 ? sourceVersionsHint : [];\n if (semver.valid(pin)) return [pin];\n // For ranges / SHA pins the resolver re-filters against the source hint.\n return sourceVersionsHint;\n}\n\n// ── Status ───────────────────────────────────────────────────────────────────\n\n/**\n * Status summary for a repository — local HEAD, remote HEAD, and how far behind.\n * @docLink packages/core/api-reference#repo-status\n */\nexport interface RepoStatus {\n /** Logical name of the repository. */\n name: string;\n /** Whether the repo is local, remote (cloned), or linked (dev override). */\n kind: \"local\" | \"remote\" | \"linked\";\n /** Current local HEAD commit SHA. */\n localHead: string;\n /** Remote HEAD commit SHA (fetched during status check). */\n remoteHead: string;\n /** Number of commits the local clone is behind the remote. */\n behind: number;\n /** `true` when `behind === 0`. */\n upToDate: boolean;\n /** Absolute path the link points to (linked repos only). */\n linkedTo?: string;\n /** Human-readable error string when the status check failed. */\n error?: string;\n}\n\n/**\n * Check whether a repository clone is up to date with its remote.\n * Fetches the last 50 commits to compare local HEAD with `origin/<branch>`.\n *\n * @param decl - Repository declaration from `skaile.yaml`\n * @param name - Logical repository name\n * @param reposDir - Project-local source-clone directory (`.skaile/cache/sources/`)\n * @param projectDir - Optional project root for link lookup\n * @returns `RepoStatus` describing the current state\n * @docLink packages/core/api-reference#check-repo-status\n */\nexport function checkRepoStatus(\n decl: SourceDeclaration,\n name: string,\n reposDir: string,\n projectDir?: string,\n): RepoStatus {\n // Check for linked override\n if (projectDir) {\n const links = readLinks(projectDir);\n if (links[name]) {\n return {\n name,\n kind: \"linked\",\n localHead: \"\",\n remoteHead: \"\",\n behind: 0,\n upToDate: true,\n linkedTo: links[name],\n };\n }\n }\n\n const base: RepoStatus = {\n name,\n kind: decl.path ? \"local\" : \"remote\",\n localHead: \"\",\n remoteHead: \"\",\n behind: 0,\n upToDate: true,\n };\n\n if (decl.path) return base;\n\n // Check global cache first, then project-local. A global cache dir whose origin\n // maps to a different key than `decl.url` is a stale collision — fall through to\n // the project-local clone rather than reporting status for the wrong repo.\n let dest = join(getGlobalCacheDir(), name);\n const globalOk =\n existsSync(join(dest, \".git\")) && (!decl.url || remoteUrlMatches(dest, decl.url));\n if (!globalOk) {\n dest = join(reposDir, name);\n }\n if (!existsSync(join(dest, \".git\"))) {\n return { ...base, error: \"Not cloned yet\" };\n }\n\n const branch = decl.branch ?? \"main\";\n\n const localHead = getRepoCommit(dest);\n if (!localHead) return { ...base, error: \"Failed to read local HEAD\" };\n base.localHead = localHead;\n\n const fetchR = spawnSync(\"git\", [\"-C\", dest, \"fetch\", \"--depth=50\", \"origin\", branch], {\n encoding: \"utf8\",\n stdio: \"pipe\",\n env: GIT_ENV,\n });\n if (fetchR.status !== 0) return { ...base, error: \"Fetch failed\" };\n\n const remoteR = spawnSync(\"git\", [\"-C\", dest, \"rev-parse\", `origin/${branch}`], {\n encoding: \"utf8\",\n stdio: \"pipe\",\n });\n if (remoteR.status !== 0) return { ...base, error: \"Failed to read remote HEAD\" };\n base.remoteHead = remoteR.stdout.trim();\n\n const countR = spawnSync(\n \"git\",\n [\"-C\", dest, \"rev-list\", \"--left-right\", \"--count\", `HEAD...origin/${branch}`],\n { encoding: \"utf8\", stdio: \"pipe\" },\n );\n if (countR.status === 0) {\n const parts = countR.stdout.trim().split(/\\s+/);\n base.behind = parseInt(parts[1] ?? \"0\", 10);\n }\n\n base.upToDate = base.behind === 0;\n return base;\n}\n","/**\n * Unified workspace configuration — `skaile.yaml` / `<name>.skaile.yaml`\n *\n * Single file combining AI resources, data connectors, agent behavior,\n * runtime defaults, and workspace layout.\n *\n * ── File naming ──────────────────────────────────────────────────────────\n *\n * skaile.yaml → canonical default workspace config\n * staging.skaile.yaml → alternative workspace config\n * *.skaile.yaml → glob pattern for named configs\n *\n * ── Stacking ─────────────────────────────────────────────────────────────\n *\n * Files stack across scope levels (same name must match):\n * ~/.skaile/skaile.yaml priority 10 (user)\n * /app/skaile.yaml priority 20 (app)\n * /project/skaile.yaml priority 30 (project)\n *\n * ── Relationship to other files ──────────────────────────────────────────\n *\n * .skaile/settings.json User-specific overrides (API keys, personal\n * model preferences). Gitignored. Overrides\n * workspace config defaults at runtime.\n *\n * workspace.yaml Scaffold template. Generates skaile.yaml\n * at `skaile init` time. Never read at runtime.\n *\n * agent.yaml Agent definition (identity). Referenced from\n * skaile.yaml via `agent.definition`.\n */\n\nimport { cpSync, existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { basename, dirname, join, parse as parsePath, resolve } from \"node:path\";\nimport { parse, stringify } from \"yaml\";\nimport { globalSkaileDir } from \"./cache-paths.js\";\nimport {\n type DriverTarget,\n globalBackendRoot,\n SUPPORTED_DRIVER_TARGETS,\n} from \"./driver-targets.js\";\nimport { fromMcpServerMdContent, parseFrontmatter } from \"./manifest.js\";\nimport { type CatalogEntry, parseAssetRef } from \"./models.js\";\nimport { getGlobalCacheDir, getRepoCommit, sourceCacheKey } from \"./repo-manager.js\";\nimport {\n buildProvenanceIndex,\n type ProvenanceCandidate,\n type ProvenanceIndex,\n type SourceClone,\n} from \"./walker.js\";\n\n// ── Agent config ──────────────────────────────────────────────────────────────\n\n/**\n * Named agent configuration profile. The \"default\" profile is the active one.\n * Personal overrides (apiKeys, model preference) live in .skaile/settings.json.\n * @docLink packages/core/workspace-config#agent-config-profile\n */\nexport interface AgentConfigProfile {\n /** Bridge driver to use: \"claude-sdk\", \"codex\", or \"omp\". */\n driver?: string;\n /** Default LLM provider: \"anthropic\", \"openai\", \"google\", etc. */\n provider?: string;\n /** Default model identifier. */\n model?: string;\n /** Thinking mode for Claude models. */\n thinking?: \"adaptive\" | \"enabled\" | \"disabled\";\n /** Reasoning effort level. */\n effort?: \"low\" | \"medium\" | \"high\" | string;\n /** Override framework install paths (rarely needed). */\n skills_dir?: string;\n agents_dir?: string;\n prompts_dir?: string;\n}\n\n// ── Startup ───────────────────────────────────────────────────────────────────\n\n/**\n * A startup directive — run on workspace launch.\n *\n * String form: \"agent:research-assistant\" — start the named agent\n * Object form: { \"system-prompt-override\": \"...\" } — replace system prompt\n * { \"system-prompt-append\": \"...\" } — append to system prompt\n * @docLink packages/core/workspace-config#startup-directive\n */\nexport type StartupDirective = string | Record<string, string>;\n\n// ── AI Resources ──────────────────────────────────────────────────────────────\n\n/**\n * An AI resource source with its own dependency list.\n * All declared dependencies are installed from this source's catalog.\n * @docLink packages/core/workspace-config#ai-resource-entry\n */\nexport interface AiResourceEntry {\n /** Source name (used as cache key and in CLI output). */\n name: string;\n /** Path to local directory or GitHub repo URL. */\n path: string;\n /** Git branch (default: main). */\n branch?: string;\n /** Skill/agent/package/flow refs to install from this source. Syntax: \"kind:name\". */\n dependencies?: string[];\n /** Auto-deploy to framework dirs on install. */\n auto_deploy?: boolean;\n}\n\n// ── Repository Declaration ────────────────────────────────────────────────────\n\n/**\n * Internal-only data shape used by the asset install pipeline (`repo-manager`,\n * `lock`, `runtime-assets`). Carries the resolved URL or path for a `sources[]`\n * entry. Not surfaced directly via the workspace config schema.\n *\n * NOTE: this type was named `RepositoryDeclaration` before 2026-05-31 (the\n * canonical-identity rename). The shape is unchanged — only the name moved\n * from a project-local \"repository\" concept to the source carrier.\n *\n * @docLink packages/core/workspace-config#source-declaration\n */\nexport interface SourceDeclaration {\n /** GitHub or git URL (for remote repos). */\n url?: string;\n /** Local filesystem path (for local repos). */\n path?: string;\n /** Git branch (default: main). */\n branch?: string;\n /** Upstream URL for fork workflows. */\n upstream?: string;\n /**\n * Built-in source shipped inside the package (`dist/factory-assets/`). Deploys\n * are **copied**, not symlinked, even though `path` is set: the bundled dir\n * lives under `node_modules` and is replaced on every upgrade, so a symlink\n * into it would dangle. Injected at runtime by `AssetManager`, never persisted\n * to `skaile.yaml`.\n */\n factory?: boolean;\n}\n\n// ── Source Entry ──────────────────────────────────────────────────────────────\n\n/**\n * One entry in a project's `sources:` list. Names the upstream git URL plus\n * an optional pin (tag, branch HEAD, or 40-char SHA). The publisher identity\n * is NOT carried here — it is intrinsic to the asset bytes, declared in the\n * source's own `skaile.yaml`.\n *\n * Persisted under the `sources:` key in `skaile.yaml`. Bytes live under\n * `<cache>/sources/<slug>/` (unified machine-global clone cache, via\n * `getGlobalCacheDir()`) where the slug is derived from the URL.\n *\n * @docLink packages/core/workspace-config#source-entry\n */\nexport interface SourceEntry {\n /** Git URL (ssh or https). Cache key derives from this. */\n url: string;\n /** Optional pin: branch | tag | 40-char sha. Defaults to HEAD of default branch. */\n pin?: string;\n}\n\n/**\n * One entry in a project's `stores:` list. Catalog endpoint URL only.\n * The store backend authenticates publisher identity; no project-side\n * trust declaration applies.\n *\n * @docLink packages/core/workspace-config#store-entry\n */\nexport interface StoreEntry {\n /** Catalog base URL (e.g. `https://skaile.store`). */\n url: string;\n}\n\n/**\n * One entry in `overrides:`. Pins a specific canonical ref to one source\n * URL when two or more candidates diverge on sha256. The `reason:` field\n * is REQUIRED and non-empty; empty or missing is a parse-time error.\n *\n * @docLink packages/core/workspace-config#override-entry\n */\nexport interface OverrideEntry {\n /** Canonical ref form: `<publisher>/<kind>:<name>@<version>`. */\n ref: string;\n /** One of the candidate source URLs. */\n source: string;\n /** Non-empty justification. */\n reason: string;\n}\n\n// ── Mounts ──────────────────────────────────────────────────────────────────\n\n/**\n * A filesystem mount — projected storage backend.\n * @docLink packages/core/workspace-config#mount-declaration\n */\ninterface MountDeclaration {\n /** Unique identifier. Used as mount dir name. */\n id: string;\n /** Mount driver: \"local\", \"git\", \"s3\", \"webdav\", \"sharepoint\". */\n driver: string;\n /** What to mount: URL, bucket path, host filesystem path. */\n source: string;\n /** Workspace-relative mount point (default: .mounts/<id>). */\n target?: string;\n /** Access level enforced by the mount driver. */\n access?: \"read-only\" | \"read-write\";\n /** Credential reference: \"env:VAR_NAME\" or inline value. */\n auth?: string;\n /**\n * Whether to watch this mount for filesystem changes.\n * true = always watch, false = never watch, undefined = auto (watch if read-write).\n */\n watch?: boolean;\n /**\n * **Expert-only.** When `true`, the mount manager wires the resolved\n * credential into the workspace so the agent's interactive `git`/`curl`\n * tools can authenticate directly against the mount's host. Defaults to\n * `false` — agents have no credential exposure and rely on driver-managed\n * pulls/pushes. See `_devlog/specs/2026-05-05-git-credential-tiers.md`.\n */\n exposeAccessToken?: boolean;\n /**\n * Optional override for the access token TTL (seconds). When omitted, the\n * provider's natural TTL is used. Values above the provider's documented\n * maximum are silently capped.\n */\n accessTokenTTL?: number;\n /** Driver-specific configuration (branch, region, etc.). */\n options?: Record<string, unknown>;\n}\n\n// ── Connectors ────────────────────────────────────────────────────────────────\n\n/**\n * A data connector — tool-accessed backend the agent interacts with.\n * @docLink packages/core/workspace-config#connector-declaration\n */\nexport interface ConnectorDeclaration {\n /** Unique identifier. Used as tool namespace. */\n id: string;\n /** Connector adapter: \"postgres\", \"redis\", \"sqlite\", \"memory\", \"xstate\", \"xstate-store\", \"yjs\". */\n driver: string;\n /**\n * Access level enforced by ConnectorManager.\n * Optional in config — ConnectorManager defaults to \"read-only\" when absent.\n */\n access?: \"read-only\" | \"read-write\";\n /** Credential reference: \"env:VAR_NAME\" or inline value. */\n auth?: string;\n /**\n * Backend-mediated credential routing key. For backend-auth mounts the\n * platform serializes this top-level so the runner can mint/refresh the\n * connector token via `host.refresh_credential`. Must survive the\n * skaile.yaml → declaration mapping or live token refresh fails.\n */\n providerLinkId?: string;\n /**\n * Operating mode for connectors that manage a working copy. Orthogonal to\n * faces. `agent` = the agent drives the source natively (e.g. native git) and\n * the connector only provisions short-lived credentials. `sync` = the\n * connector owns the working copy (clone + watch + auto-commit/pull). Absent =\n * the driver's legacy `options.{session,sync,lifecycle}` blocks decide.\n */\n mode?: \"agent\" | \"sync\";\n /** Adapter-specific configuration (dsn, host, etc.). */\n options?: Record<string, unknown>;\n\n // ── Extended fields (Plan A: first-level asset support) ──────────────────\n /** Semver range for future catalog versioning, e.g. \"^1.0.0\". */\n version?: string;\n /**\n * Run a health check (ping) when the connector is first connected.\n * Default: false. Set to true to surface connection errors early.\n */\n health_check?: boolean;\n /**\n * Inject this connector's skill description into the agent's system prompt.\n * Default: false.\n */\n expose_as_skill?: boolean;\n /** Tags for catalog browsing and skill routing. */\n tags?: string[];\n\n /**\n * Optional filesystem face — makes the connector \"mountable\".\n * When present, ConnectorManager allocates a mount directory and passes it\n * to the connector via `ConnectContext.mountTarget`.\n *\n * YAML key: `mount` (sub-block under a `connectors:` entry).\n * Replaces the legacy top-level `mounts:` key (hard cut — see Task 11).\n */\n mount?: {\n /** Source URL or path (repo URL, bucket name, host path). */\n source: string;\n /** Override mount target directory (default: `.mounts/<id>/`). */\n target?: string;\n /** Watch flag: omitted → watch read-write, skip read-only. */\n watch?: boolean;\n /** Expert-only: expose the resolved credential to the agent CLI. */\n exposeAccessToken?: boolean;\n /** Optional access-token TTL override (seconds). */\n accessTokenTTL?: number;\n };\n}\n\n// ── MCP Servers ──────────────────────────────────────────────────────────────\n\n/**\n * Reference to a Nix-built asset recipe.\n *\n * Two source forms:\n * - **Platform-flake attr (legacy):** `{ attr }` selects an attribute path in\n * the platform flake (`/etc/skaile/flake/`), e.g. `mcps.excel`, `mcps.ppt`,\n * `stacks.baseline`. The leaf of `attr` doubles as the recipe-map lookup key.\n * - **Self-contained flake (BYO-flake):** `{ flake, attr? }` names a flake that\n * travels with the asset (`flake: \".\"`) or a remote URL for allowlisted\n * third-party publishers. The host-side builder resolves it to a store path.\n * Here `attr` is the in-flake BUILD target only (defaults to `\"default\"`);\n * the recipe **id** (the MCP declaration id) is the recipe-map / `${recipe:<id>}`\n * marker key, never `attr`.\n *\n * Resolution happens at session start (cold) and on `reconfigure_mcps` (hot-add)\n * via the prebuilt recipe map → `nix path-info --offline` fallback.\n *\n * @docLink packages/core/concepts#asset-recipe\n */\nexport interface AssetRecipe {\n /**\n * Flake attribute to resolve/build.\n * - Legacy `{ attr }` form: required, e.g. `mcps.excel`.\n * - BYO-flake `{ flake, attr? }` form: optional, defaults to `\"default\"`.\n */\n attr?: string;\n /**\n * Optional flake source. `\".\"` = the asset's own `flake.nix` (resolved\n * relative to the asset directory by the host-side builder). A flake URL\n * (`github:…`, `git+https://…`, `git+ssh://…`, `path:/…`) is permitted only\n * for publishers on the curated allowlist (enforced host-side). Absent = the\n * platform flake (legacy behaviour).\n */\n flake?: string;\n /**\n * Publisher id that authored this recipe's flake. Required (host-side) when\n * `flake` is a remote URL; the builder checks it against the allowlist.\n * Defaults to the owning asset's publisher when `flake` is `\".\"`.\n */\n publisher?: string;\n}\n\n/** Default in-flake build target for the BYO-flake form when `attr` is omitted. */\nexport const DEFAULT_RECIPE_ATTR = \"default\";\n\n/**\n * Validates an `AssetRecipe.flake` source string.\n *\n * Accepted forms:\n * - `\".\"` — the asset's own flake directory (always allowed).\n * - a flake URL with a recognised scheme: `github:`, `git+https://`,\n * `git+ssh://`, `path:/` (absolute-only).\n *\n * Rejected: empty strings, local relative/absolute paths other than `\".\"`\n * (including `..` traversal and bare `/abs/path` — those must go through an\n * explicit `path:` URL), and unknown schemes. This guards the value before the\n * host-side builder interpolates it into `nix build \"<flake>#<attr>\"`; the\n * allowlist gate is a *separate* trust check, not a substitute for this.\n *\n * NOTE: this validates *shape*, not allowlist membership — the publisher\n * allowlist is enforced host-side by the builder, which has the allowlist file.\n *\n * @throws Error when `flake` is malformed\n */\nexport function validateAssetRecipeFlake(flake: string): void {\n if (typeof flake !== \"string\" || flake.length === 0) {\n throw new Error(\"AssetRecipe.flake must be a non-empty string\");\n }\n if (flake.length > 500) {\n throw new Error(`AssetRecipe.flake too long (${flake.length} chars, max 500)`);\n }\n if (flake === \".\") return;\n // Recognised flake-URL schemes only. Everything else (relative paths, bare\n // absolute paths, `..`, `file:`, arbitrary schemes) is rejected — a local\n // path must be expressed as an explicit `path:` URL.\n // `path:` is absolute-only (`path:/…`): a remote catalog entry must not be\n // able to name a relative path or `..` escape via `path:relative/x`.\n const ALLOWED_SCHEME = /^(github:|git\\+https:\\/\\/|git\\+ssh:\\/\\/|path:\\/)/;\n if (!ALLOWED_SCHEME.test(flake)) {\n throw new Error(\n `AssetRecipe.flake \"${flake}\" has an unsupported source. ` +\n `Allowed: \".\" or a flake URL (github:, git+https://, git+ssh://, path:/).`,\n );\n }\n // Defense-in-depth: reject shell/nix metacharacters that have no place in a\n // flake ref even within an accepted scheme (the ref is also passed quoted by\n // the builder, but belt-and-braces). `#` is the nix attr separator — the\n // builder appends `#<attr>`, so a `#` in the flake ref would yield a\n // malformed `flake#x#attr` invocation.\n if (/[\\s`$;|&<>(){}#\\n\\r]/.test(flake)) {\n throw new Error(`AssetRecipe.flake \"${flake}\" contains forbidden characters.`);\n }\n}\n\n/**\n * Validates an `AssetRecipe.attr` value against nix attribute path syntax.\n *\n * Nix attribute paths are dot-separated segments. Each segment must start with\n * a letter and contain only letters, digits, underscores, hyphens, and dots.\n * Characters like `#`, spaces, and nix expression fragments are explicitly\n * rejected — even though `spawnSync` array args prevent shell injection, nix\n * parses the combined `flakeRef#attr` string and invalid chars trigger\n * unintended evaluation paths.\n *\n * Deliberate restriction: leading digits per segment are not allowed even\n * though some nix attrs permit them, because they are rare in practice and\n * the restriction makes the validation straightforward to audit.\n *\n * @throws Error when `attr` is invalid\n */\nexport function validateAssetRecipeAttr(attr: string): void {\n if (typeof attr !== \"string\" || attr.length === 0) {\n throw new Error(\"AssetRecipe.attr must be a non-empty string\");\n }\n if (attr.length > 200) {\n throw new Error(`AssetRecipe.attr too long (${attr.length} chars, max 200)`);\n }\n const VALID_ATTR = /^[a-z][a-z0-9._-]*(?:\\.[a-z][a-z0-9._-]*)*$/i;\n if (!VALID_ATTR.test(attr)) {\n throw new Error(\n `AssetRecipe.attr \"${attr}\" contains invalid characters. ` +\n `Allowed: letters, digits, underscore, hyphen, dot. ` +\n `Each dot-segment must start with a letter.`,\n );\n }\n}\n\n/**\n * A declarative external MCP server — spawned or connected at session startup\n * and injected into the Claude SDK driver as a named `mcpServers` entry.\n *\n * Maps directly to the Claude Agent SDK's `McpServerConfig` union:\n * - `transport: \"stdio\"` (default) → `McpStdioServerConfig` — subprocess spawn\n * - `transport: \"sse\"` → `McpSSEServerConfig` — HTTP Server-Sent Events\n * - `transport: \"http\"` → `McpHttpServerConfig` — HTTP streaming\n *\n * The `id` becomes the key in the SDK's `mcpServers` record and also the MCP\n * tool prefix (e.g., `mcp__my-server__<tool-name>`).\n * @docLink packages/core/workspace-config#mcp-server-declaration\n */\nexport interface McpServerDeclaration {\n /** Unique identifier — used as the `mcpServers` record key and tool prefix. */\n id: string;\n /**\n * Transport type.\n * Default: `\"stdio\"` (subprocess).\n */\n transport?: \"stdio\" | \"sse\" | \"http\";\n /** For `\"stdio\"`: the command to execute (e.g. `\"npx\"`, `\"node\"`, `\"python\"`). */\n command?: string;\n /** For `\"stdio\"`: arguments passed to the command. */\n args?: string[];\n /** For `\"stdio\"`: environment variables injected into the subprocess. */\n env?: Record<string, string>;\n /** For `\"sse\"` and `\"http\"`: the server URL. */\n url?: string;\n /** For `\"sse\"` and `\"http\"`: HTTP headers (e.g. `Authorization`). */\n headers?: Record<string, string>;\n /**\n * Credential resolution mode for a remote (sse/http) server. `\"backend\"` means\n * the platform mints + provisions the bearer (header `Authorization:\n * env:MCP__<id>__AUTH`) and the runner re-mints it on a 401. Written by the\n * platform; absent for local / static-token servers.\n */\n auth?: string;\n /**\n * For a remote `auth: \"backend\"` server: the org `ProviderLink` whose OAuth\n * credential backs this server's bearer. The runner passes it as the re-mint\n * `id` on a 401. Written by the platform alongside `auth`.\n */\n providerLinkId?: string;\n /** Short description of what this server provides (used in catalog). */\n description?: string;\n /** Tags for catalog browsing and discovery. */\n tags?: string[];\n /**\n * Named launcher strategy for a local (stdio) server. Selectable + explicit;\n * default is inferred (recipe present → \"recipe\"; else a pass-through\n * \"path\"/\"package-runner\" command-shape). Only \"recipe\" carries resolution\n * logic; \"package-runner\" (npx/uvx/pip) and \"path\" are documented command\n * shapes the stdio transport already spawns as-is. Ignored for remote (sse/http).\n */\n launcher?: \"recipe\" | \"package-runner\" | \"path\";\n /**\n * Optional Nix recipe binding. When present, the runner resolves the\n * recipe's `/nix/store` out-path before subprocess spawn and substitutes\n * `${recipe:<id>}` / `${recipe:<id>:<sub>}` / `${recipe:<id>:bin}` /\n * `${recipe:<id>:lib}` markers in `command`, `args`, and `env` values.\n * `<id>` matches this declaration's `id` field.\n */\n recipe?: AssetRecipe;\n /** Owner-authored instruction text from the materialized MCP.md body (preset custom instructions). */\n instructions?: string;\n}\n\n// ── Agent Configuration ──────────────────────────────────────────────────────\n\n/**\n * Platform-level context describing the environment the agent operates in.\n * Rendered by the runner into a \"## Platform\" section of the system prompt.\n */\nexport interface AgentContextConfig {\n /** Platform identifier (e.g. \"skaile\"). Controls the rendered header sentence. */\n platform?: string;\n /** Whether multiple users may interact in the same session. */\n multi_user?: boolean;\n /** Session persistence model. */\n session_model?: \"persistent\" | \"ephemeral\";\n}\n\nexport interface AgentConfig {\n /**\n * Agent definition reference. Resolved in order:\n * - Local path: \".skaile/agent\" or \"./my-agent\"\n * - Catalog reference: \"agent:<name>\" (resolved via asset manager catalog)\n * - Resource path: \"ai-assets://<domain>/agents/<name>\"\n */\n definition?: string;\n\n /**\n * Platform-level context (platform identifier, multi-user flag, session model).\n * Consumed by the runner to build the \"## Platform\" section of the system prompt.\n */\n context?: AgentContextConfig;\n\n /** Agent runtime constraints. */\n permissions?: AgentPermissions;\n\n /** Lifecycle hooks — shell commands run at specific points. */\n hooks?: AgentHooks;\n\n /** Named subagent definitions available for delegation. */\n subagents?: Record<string, SubagentConfig>;\n\n /**\n * Control which framework fragments are included in the rendered system prompt.\n * true (default) — include built-in fragment\n * false — omit this fragment\n * string — path to a custom markdown file (relative to project root)\n *\n * Fragment IDs: \"agent-mode\" | \"skill-discovery\" | \"connector-usage\" | \"handoff\"\n */\n fragments?: Record<string, boolean | string>;\n\n /**\n * Additional markdown files appended at the end of every rendered agent system\n * prompt in this workspace. Paths relative to the project root (skaile.yaml).\n *\n * YAML key: `prompt-extensions`\n */\n \"prompt-extensions\"?: string[];\n\n /**\n * Free-form user-authored agent prompt. Plain text or markdown — no length\n * cap, no template substitution. Prepended immediately after the platform\n * context section and before the environment section in the assembled\n * system prompt (see runner's {@link assembleSystemPrompt}).\n *\n * Written by the platform's wake-time yaml serializer from the combined\n * project-level + session-level prompts stored on `SkaileConfigData.agent.prompt`.\n * Standalone CLI / forge sessions may set this directly in `skaile.yaml`.\n *\n * Spec: `docs/superpowers/specs/2026-05-13-platform-agent-prompt-design.md`\n * @since 2026-05\n */\n prompt?: string;\n}\n\nexport interface AgentPermissions {\n /** Maximum agentic turns per query (default: 15). */\n max_turns?: number;\n /**\n * Permission mode for Claude SDK driver.\n * 'auto' = bypassPermissions (default for automated flows).\n * 'interactive' = prompt for each tool use.\n */\n permission_mode?: \"auto\" | \"interactive\";\n /** Glob patterns the agent may NOT write to. Stacking: union across scopes. */\n deny_write?: string[];\n /** Glob patterns the agent may NOT read. Stacking: union across scopes. */\n deny_read?: string[];\n /**\n * Network egress policy. Codec is permissive — the platform decides\n * enforcement.\n */\n network?: NetworkPolicy;\n}\n\n/**\n * Per-session egress policy: `open` allows everything, `off` allows only\n * platform-resolved LLM-provider endpoints, `allowlist` adds user-supplied\n * domains. `allowlist` field is ignored when `mode !== 'allowlist'`.\n */\nexport interface NetworkPolicy {\n mode: \"open\" | \"off\" | \"allowlist\";\n allowlist?: string[];\n}\n\nconst KNOWN_NETWORK_MODES = [\"open\", \"off\", \"allowlist\"] as const;\n\nexport interface AgentHooks {\n /** Run before a flow starts (after resources are connected). */\n pre_flow?: HookEntry[];\n /** Run after a flow completes (before resources disconnect). */\n post_flow?: HookEntry[];\n /** Run before each flow node executes. */\n pre_node?: HookEntry[];\n /** Run after each flow node completes successfully. */\n post_node?: HookEntry[];\n}\n\nexport interface HookEntry {\n /** Human-readable hook name. */\n name: string;\n /** Shell command to execute. */\n run: string;\n /** Working directory relative to workspace root (default: workspace root). */\n cwd?: string;\n /** Timeout in seconds (default: 60). */\n timeout?: number;\n /** Continue flow if hook fails (default: false). */\n continue_on_error?: boolean;\n}\n\nexport interface SubagentConfig {\n /** What this subagent does. */\n description: string;\n /** System prompt for the subagent. */\n prompt: string;\n /** Tools this subagent may use (default: all). */\n tools?: string[];\n /** Tools this subagent may NOT use. */\n disallowed_tools?: string[];\n /** Model override. */\n model?: string;\n}\n\n// ── Workspace Layout ─────────────────────────────────────────────────────────\n\nexport interface WorkspaceLayoutConfig {\n /** Directories to ensure exist (created at scaffold time, verified at run time). */\n directories?: string[];\n\n /** Git configuration. */\n git?: GitConfig;\n\n /** Post-scaffold setup commands (run once after `skaile init`). */\n setup?: SetupEntry[];\n\n /** Container configuration (Docker). */\n container?: ContainerConfig;\n}\n\nexport interface GitConfig {\n /** Initialize a git repo at scaffold time (default: true). */\n init?: boolean;\n /** .gitignore entries. Stacking: concatenate + deduplicate. */\n ignore?: string[];\n}\n\nexport interface SetupEntry {\n /** Human-readable name. */\n name: string;\n /** Shell command to execute. */\n run: string;\n /** Working directory relative to workspace root. */\n cwd?: string;\n /** Continue if command fails (default: false). */\n continue_on_error?: boolean;\n}\n\nexport interface NixContainerConfig {\n /**\n * Nixpkgs package attribute names to include in the environment.\n * Example: [\"nodejs_22\", \"bun\", \"git\", \"python3\"]\n */\n packages?: string[];\n /**\n * Nixpkgs registry name used as a package prefix for `nix shell`.\n * MUST be a bare registry name like \"nixpkgs\" — not a channel path like\n * \"nixpkgs/nixos-24.11\" (which is not valid as a flake ref prefix).\n * Defaults to \"nixpkgs\".\n */\n channel?: string;\n /**\n * Path to a Nix file (shell.nix / flake.nix) relative to the project root.\n * When set, `packages` and `channel` are ignored — the file is the source of truth.\n */\n flake?: string;\n /**\n * Predefined named stack to resolve from the system stack registry (SKAILE_NIX_STACK_REGISTRY).\n * Overridden by `packages` if present.\n * Takes precedence over the parent `ContainerConfig.stack` field when nix mode is active.\n */\n stack?: string;\n}\n\nexport interface ContainerConfig {\n /** Enable Docker container generation. */\n enabled?: boolean;\n /** Base Docker image. */\n image?: string;\n /** System packages to install. */\n packages?: string[];\n /** Agent CLIs to install globally in the container. */\n agent_clis?: string[];\n /** Ports to expose. */\n ports?: string[];\n /** Environment variables to pass through. */\n env?: string[];\n /** Docker volume/bind mounts. */\n mounts?: Array<{ type: \"bind\" | \"volume\"; source: string; target: string }>;\n /** WebSocket port for IPC. */\n ws_port?: number;\n /**\n * Named system stack.\n * - Docker mode: resolved to an image tag via `dockerImageMap` (SKAILE_DOCKER_IMAGE_MAP).\n * - Nix mode: resolved to a package list via `nixStackRegistry` (SKAILE_NIX_STACK_REGISTRY).\n * Overridden by `nix.stack` if both are present.\n */\n stack?: string;\n /** Nix-specific environment configuration (nix session mode only). */\n nix?: NixContainerConfig;\n}\n\n// ── Top-level config ──────────────────────────────────────────────────────────\n\nexport interface SkWorkspaceConfig {\n /** Project name (defaults to directory basename). */\n name?: string;\n /** Project description. */\n description?: string;\n\n /**\n * Agent configuration profiles. The \"default\" profile provides runtime\n * defaults (framework, model, provider). Personal overrides live in\n * .skaile/settings.json and always take priority.\n *\n * YAML key: `agent-config` or `agent_config`\n */\n agent_config?: Record<string, AgentConfigProfile>;\n\n /**\n * Startup directives — executed when the workspace is launched.\n * Each item is either a string (\"agent:name\") or a map\n * ({ \"system-prompt-override\": \"...\" }).\n */\n startup?: StartupDirective[];\n\n /**\n * Asset dependencies using `kind:name@<publisher>[#pin]` syntax.\n * Top-level flat list — sources and deps are separate concerns.\n *\n * YAML key: `dependencies`\n */\n dependencies?: string[];\n\n /**\n * Global cross-backend install set — the coding-agent backends a `skaile\n * install --global` fans `dependencies:` out to. Only meaningful in the\n * user-scope SSOT (`~/.skaile/skaile.yaml`). When absent, the backend set is\n * auto-detected from existing `~/.<backend>` dirs (see `resolveGlobalBackends`).\n * Each entry must be a `DriverTarget` (`claude-code` | `omp` | `codex`).\n *\n * YAML key: `global_backends`\n */\n global_backends?: DriverTarget[];\n\n /**\n * Github sources this project depends on. Each entry is `{url, pin?}`; the\n * cache slug is derived from the URL. `skaile install` clones any missing\n * entries; `skaile source add/remove/sync` are the CRUD surface.\n *\n * YAML key: `sources`\n */\n sources?: SourceEntry[];\n\n /**\n * Consumption-half: trusted store catalogs queried per dep.\n *\n * YAML key: `stores`\n */\n stores?: StoreEntry[];\n\n /**\n * Consumption-half: conflict-resolution overrides with required reason.\n *\n * YAML key: `overrides`\n */\n overrides?: OverrideEntry[];\n\n /**\n * Local patches applied during install (new format).\n * Maps \"kind:name\" → patch file path relative to project root.\n *\n * YAML key: `patches`\n */\n patches?: Record<string, string>;\n\n /**\n * @deprecated The top-level `mounts:` key is no longer supported as of Task 11.\n *\n * Move filesystem-projected storage backends under `connectors:` with a\n * `mount:` sub-block. See `docs/migration-mounts-to-connectors.md`.\n *\n * This field is kept on the type **only** so `config.ts` can detect a\n * present `mounts:` block and throw a migration error. It is never merged,\n * applied, or forwarded to any manager. `normalizeConfig` still populates it\n * when `mounts:` is present in the YAML so the detection check works.\n *\n * YAML key: `mounts` (rejected at runtime — do not use)\n */\n mounts?: MountDeclaration[];\n\n /**\n * Data connectors — tool-accessed backends.\n *\n * Each declaration's `driver` field is an *implicit* catalog ref\n * (`connector:<driver>`). The runtime resolves it through\n * `resolveRuntimeAssets()`, which scans every declared `repositories` entry\n * plus the implicit built-in `factory-assets` repo for matching `CONNECTOR.md`\n * manifests. Drivers that do not match any catalog entry produce a\n * `missing_driver` warning at session startup.\n *\n * YAML key: `connectors`\n */\n connectors?: ConnectorDeclaration[];\n\n /**\n * External MCP servers — injected into the Claude SDK driver at session startup.\n * Supports stdio subprocess, SSE, and HTTP transports.\n *\n * YAML key: `mcp_servers`\n */\n mcp_servers?: McpServerDeclaration[];\n\n /** Agent behavior — definition reference, permissions, hooks, subagents. */\n agent?: AgentConfig;\n\n /** Workspace layout — directories, git, setup scripts, container. */\n workspace?: WorkspaceLayoutConfig;\n\n /**\n * Secret provisioning configuration.\n * Controls how connector credentials are resolved at runtime.\n *\n * YAML key: `secrets`\n */\n secrets?: SecretsConfig;\n\n /**\n * Telemetry configuration — passed through raw to the telemetry package.\n * Parsed by `resolveTelemetryConfig` in `@skaile/workspaces/telemetry`.\n *\n * YAML key: `telemetry`\n */\n telemetry?: Record<string, unknown>;\n\n /**\n * Session compaction settings -- controls when and how conversation\n * snapshots are created.\n *\n * YAML key: `compaction`\n */\n compaction?: CompactionConfig;\n\n /**\n * Plugin specs to load into pluginRegistry — npm specifiers like\n * \"@skaile/provider-fly@^0.1.0\". Opt-in; no auto-discovery. YAML key: `plugins`.\n */\n plugins?: string[];\n /** Deploy target selection. YAML key: `deploy`. */\n deploy?: DeployBlock;\n}\n\n/** Deploy target selection for `skaile deploy`. YAML key: `deploy`. Resolved through pluginRegistry at deploy time. */\nexport interface DeployBlock {\n /** Deploy target id (e.g. \"local\", \"docker\", \"fly\") — resolved against pluginRegistry at deploy time, not validated here. */\n target: string;\n /** Target-specific config; validated by the target's configSchema at resolve time. */\n config?: unknown;\n}\n\nexport interface SecretsConfig {\n /**\n * How secrets are provided to the container.\n * \"env\" — read from process.env (default, for CLI/standalone)\n * \"provisioned\" — wait for secrets over transport bridge (platform containers)\n */\n provider?: \"env\" | \"provisioned\";\n /** Timeout in ms for waiting for provisioned secrets (default: 30000). */\n timeoutMs?: number;\n}\n\n// ── Compaction config ────────────────────────────────────────────────────────\n\nexport interface CompactionConfig {\n /** Enable managed compaction (default: true). */\n enabled?: boolean;\n /** Context fill percentage that triggers compaction (default: 80). */\n thresholdPercent?: number;\n /** Compact before hibernation for cheap restores (default: true). */\n compactOnHibernate?: boolean;\n /** Minimum ms between compactions to prevent thrashing (default: 120000). */\n minCooldownMs?: number;\n /** Enable manual compact command in expert mode (default: false). */\n manualCompactEnabled?: boolean;\n}\n\nexport const COMPACTION_DEFAULTS: Required<CompactionConfig> = {\n enabled: true,\n thresholdPercent: 80,\n compactOnHibernate: true,\n minCooldownMs: 120_000,\n manualCompactEnabled: false,\n};\n\n// ── Deprecated type aliases ───────────────────────────────────────────────────\n\n/** @deprecated Use AgentConfigProfile */\nexport interface RuntimeDefaults {\n framework?: string;\n driver?: string;\n provider?: string;\n model?: string;\n skills_dir?: string;\n agents_dir?: string;\n prompts_dir?: string;\n}\n\n/** @deprecated Use AiResourceEntry[] */\nexport interface AiResourcesConfig {\n sources?: AiResourceSource[];\n requires?: string[];\n auto_deploy?: boolean;\n}\n\n/** @deprecated Use AiResourceEntry */\nexport interface AiResourceSource {\n name: string;\n path: string;\n branch?: string;\n}\n\n// ── Config file info ──────────────────────────────────────────────────────────\n\nexport interface SkWorkspaceConfigFile {\n /** Absolute path to the config file. */\n path: string;\n /** Workspace name (extracted from filename). */\n name: string;\n /** Parsed config. */\n config: SkWorkspaceConfig;\n /**\n * Diagnostics from decoding this file — legacy-shape warnings (camelCase keys,\n * flat agent-config, the old ai_resources object) and unrecognized\n * driver/provider/access values. Absent on configs synthesized in-memory.\n */\n diagnostics?: Diagnostic[];\n}\n\n// ── Constants ─────────────────────────────────────────────────────────────────\n\n/** Suffix for named workspace configs: `<name>.skaile.yaml` */\nexport const SKAILE_YAML_SUFFIX = \".skaile.yaml\";\n/** Filename for the default workspace config when no name is given. */\nexport const SKAILE_YAML_DEFAULT = \"skaile.yaml\";\n\n/** @deprecated Use SKAILE_YAML_SUFFIX */\nexport const SK_WORKSPACE_SUFFIX = SKAILE_YAML_SUFFIX;\n/** @deprecated Use SKAILE_YAML_DEFAULT */\nexport const SK_WORKSPACE_DEFAULT_NAME = \"default\";\n\n// ── Config I/O ────────────────────────────────────────────────────────────────\n\n/**\n * Return the canonical filename for a workspace config.\n * The default workspace resolves to `\"skaile.yaml\"`; named workspaces resolve to\n * `\"<name>.skaile.yaml\"`.\n *\n * @param name - Optional workspace name (omit or pass `\"default\"` for the primary config)\n * @returns Filename string (not a full path)\n * @docLink packages/core/workspace-config#workspace-config-filename\n */\nexport function workspaceConfigFilename(name?: string): string {\n if (!name || name === \"default\") return SKAILE_YAML_DEFAULT;\n return `${name}${SKAILE_YAML_SUFFIX}`;\n}\n\n/**\n * Return `true` if `filename` matches the workspace config naming convention\n * (`\"skaile.yaml\"` or any `\"*.skaile.yaml\"`).\n *\n * @param filename - Bare filename (no directory component)\n * @docLink packages/core/workspace-config#is-workspace-config-filename\n */\nexport function isWorkspaceConfigFilename(filename: string): boolean {\n return filename === SKAILE_YAML_DEFAULT || filename.endsWith(SKAILE_YAML_SUFFIX);\n}\n\n/**\n * Extract the workspace name from a config filename.\n * `\"skaile.yaml\"` → `\"default\"`, `\"staging.skaile.yaml\"` → `\"staging\"`.\n *\n * @param filename - Bare filename produced by `workspaceConfigFilename`\n * @returns Workspace name string\n * @docLink packages/core/workspace-config#workspace-name-from-filename\n */\nexport function workspaceNameFromFilename(filename: string): string {\n if (filename === SKAILE_YAML_DEFAULT) return \"default\";\n return filename.slice(0, -SKAILE_YAML_SUFFIX.length);\n}\n\n/**\n * Load a single workspace config file from `dir`.\n * When `name` is omitted and no `skaile.yaml` exists, falls back to the sole\n * `*.skaile.yaml` file in the directory if exactly one is present.\n *\n * @param dir - Directory to search for the config file\n * @param name - Optional workspace name (omit for the default `skaile.yaml`)\n * @returns Parsed config file info, or `null` if no matching file was found\n * @docLink packages/core/workspace-config#load-sk-workspace-config\n */\nexport function loadSkWorkspaceConfig(dir: string, name?: string): SkWorkspaceConfigFile | null {\n const resolvedDir = resolve(dir);\n const canonicalName = name && name !== \"default\" ? name : undefined;\n\n const filename = workspaceConfigFilename(canonicalName);\n const filePath = join(resolvedDir, filename);\n if (existsSync(filePath)) {\n return parseConfigFile(filePath, canonicalName ?? \"default\");\n }\n\n if (!canonicalName) {\n const found = listSkWorkspaceConfigs(resolvedDir);\n if (found.length === 1) return found[0]!;\n }\n\n return null;\n}\n\n/**\n * Serialize and write a workspace config to `dir`, creating the directory if needed.\n *\n * @param dir - Target directory (created recursively if absent)\n * @param config - Config object to serialize as YAML\n * @param name - Optional workspace name (omit for the default `skaile.yaml`)\n * @returns Absolute path of the written file\n * @docLink packages/core/workspace-config#save-sk-workspace-config\n */\nexport function saveSkWorkspaceConfig(\n dir: string,\n config: SkWorkspaceConfig,\n name?: string,\n): string {\n const resolvedDir = resolve(dir);\n const filename = workspaceConfigFilename(name);\n const filePath = join(resolvedDir, filename);\n\n if (!existsSync(resolvedDir)) {\n mkdirSync(resolvedDir, { recursive: true });\n }\n\n writeFileSync(filePath, encodeSkaileYaml(config));\n return filePath;\n}\n\n/**\n * List all workspace config files present in `dir`, sorted alphabetically by name.\n * Returns an empty array when `dir` does not exist or is unreadable.\n *\n * @param dir - Directory to scan for `skaile.yaml` and `*.skaile.yaml` files\n * @returns Array of parsed config file descriptors\n * @docLink packages/core/workspace-config#list-sk-workspace-configs\n */\nexport function listSkWorkspaceConfigs(dir: string): SkWorkspaceConfigFile[] {\n const resolvedDir = resolve(dir);\n if (!existsSync(resolvedDir)) return [];\n\n const configs: SkWorkspaceConfigFile[] = [];\n try {\n for (const entry of readdirSync(resolvedDir)) {\n if (isWorkspaceConfigFilename(entry)) {\n const wsName = workspaceNameFromFilename(entry);\n const parsed = parseConfigFile(join(resolvedDir, entry), wsName);\n if (parsed) configs.push(parsed);\n }\n }\n } catch {\n /* unreadable dir */\n }\n\n return configs.sort((a, b) => a.name.localeCompare(b.name));\n}\n\n/**\n * Resolve the effective workspace config by stacking configs across three scope levels:\n * user (`~/.skaile/`) < app (`opts.appDir`) < project (`projectDir`).\n *\n * Each level's config is merged with `mergeSkWorkspaceConfigs`, with higher-priority\n * scopes winning for scalars and unions applied for arrays (deny lists, directories, etc.).\n * Returns an empty object `{}` when no config files are found.\n *\n * @param projectDir - Root directory of the current project\n * @param opts - Optional overrides: `name` selects a named workspace (default: `\"default\"`),\n * `appDir` inserts an app-level config between user and project scopes\n * @returns Merged effective `SkWorkspaceConfig`\n * @docLink packages/core/workspace-config#resolve-sk-workspace-config\n */\nexport function resolveSkWorkspaceConfig(\n projectDir: string,\n opts?: { name?: string; appDir?: string },\n): SkWorkspaceConfig {\n const name = opts?.name ?? SK_WORKSPACE_DEFAULT_NAME;\n const configs: SkWorkspaceConfig[] = [];\n\n // Surface the legacy-key hard error at the runtime boundary. decodeSkaileYaml\n // stays total (records a `legacy_key_rejected` diagnostic) so editor/preview\n // callers don't crash; the merged-runtime resolver re-throws it here so\n // install / serve fail loudly with the migration hint.\n const assertNoLegacyKey = (file: SkWorkspaceConfigFile | null) => {\n const d = file?.diagnostics?.find((x) => x.code === \"legacy_key_rejected\");\n if (d) throw new Error(d.message);\n };\n\n const userConfig = loadSkWorkspaceConfig(join(homedir(), \".skaile\"), name);\n assertNoLegacyKey(userConfig);\n if (userConfig) configs.push(userConfig.config);\n\n if (opts?.appDir) {\n const appConfig = loadSkWorkspaceConfig(opts.appDir, name);\n assertNoLegacyKey(appConfig);\n if (appConfig) configs.push(appConfig.config);\n }\n\n const projectConfig = loadSkWorkspaceConfig(projectDir, name);\n assertNoLegacyKey(projectConfig);\n if (projectConfig) configs.push(projectConfig.config);\n\n if (configs.length > 0) return configs.reduce(mergeSkWorkspaceConfigs);\n\n return {};\n}\n\n/**\n * Resolve **only** the user-scope global SSOT (`~/.skaile/skaile.yaml`), without\n * stacking any app/project config. This is the single source of truth for global\n * cross-backend installs (`skaile install --global`). Returns `{}` when the file\n * is absent (edge: no `~/.skaile/skaile.yaml` yet). Re-throws the legacy-key\n * error with the `migrate-skaile-manifest` hint, matching\n * {@link resolveSkWorkspaceConfig}.\n *\n * @returns The normalized user-scope config, or `{}` when absent.\n * @throws {Error} on legacy `repositories:` / `ai_resources:` keys.\n * @docLink packages/core/workspace-config#resolve-global-sk-workspace-config\n */\nexport function resolveGlobalSkWorkspaceConfig(): SkWorkspaceConfig {\n const file = loadSkWorkspaceConfig(globalSkaileDir(), SK_WORKSPACE_DEFAULT_NAME);\n const legacy = file?.diagnostics?.find((x) => x.code === \"legacy_key_rejected\");\n if (legacy) throw new Error(legacy.message);\n return file?.config ?? {};\n}\n\n/**\n * Resolve the set of coding-agent backends a global install fans out to:\n * the explicit `global_backends:` list from `~/.skaile/skaile.yaml` when set,\n * otherwise every {@link DriverTarget} whose global backend root dir already\n * exists under `~` (auto-detection). May return an empty array when no backend\n * is declared and none is present on disk.\n *\n * @returns Deduplicated, declaration-order list of global backends.\n * @throws {Error} on legacy keys in `~/.skaile/skaile.yaml`.\n * @docLink packages/core/workspace-config#resolve-global-backends\n */\nexport function resolveGlobalBackends(): DriverTarget[] {\n const explicit = resolveGlobalSkWorkspaceConfig().global_backends;\n if (explicit && explicit.length > 0) return [...new Set(explicit)];\n return SUPPORTED_DRIVER_TARGETS.filter((t) => existsSync(globalBackendRoot(t)));\n}\n\n/**\n * Walk upward from `startDir` looking for a `skaile.yaml` (or `*.skaile.yaml`).\n * Returns the directory containing the first match, or `undefined` if none found.\n *\n * Stops after 20 levels to avoid scanning all the way to `/`.\n *\n * @param startDir - Directory to start searching from (usually `process.cwd()`)\n * @returns Absolute path to the workspace root, or `undefined`\n * @docLink packages/core/workspace-config#find-workspace-root\n */\nexport function findWorkspaceRoot(startDir: string): string | undefined {\n let dir = resolve(startDir);\n const root = parsePath(dir).root; // filesystem root (e.g. \"/\" or \"C:\\\\\")\n let depth = 0;\n\n while (depth < 20) {\n if (existsSync(join(dir, SKAILE_YAML_DEFAULT))) return dir;\n // Check for named workspace configs (*.skaile.yaml)\n try {\n for (const entry of readdirSync(dir)) {\n if (entry.endsWith(SKAILE_YAML_SUFFIX)) return dir;\n }\n } catch {\n /* unreadable */\n }\n\n if (dir === root) break;\n const parent = dirname(dir);\n if (parent === dir) break;\n dir = parent;\n depth++;\n }\n return undefined;\n}\n\n// ── Merge logic ───────────────────────────────────────────────────────────────\n\n/**\n * Deep-merge two workspace configs according to stacking rules.\n * `overlay` takes priority over `base` for scalar fields.\n * Arrays use concatenation + deduplication; deny lists always union.\n * Mounts and connectors are merged by `id` (overlay entry wins for same id).\n * Hooks are concatenated in order (base first, overlay appended).\n *\n * @param base - Lower-priority config (e.g. user or app scope)\n * @param overlay - Higher-priority config (e.g. project scope)\n * @returns Merged `SkWorkspaceConfig`\n * @docLink packages/core/workspace-config#merge-sk-workspace-configs\n */\nexport function mergeSkWorkspaceConfigs(\n base: SkWorkspaceConfig,\n overlay: SkWorkspaceConfig,\n): SkWorkspaceConfig {\n return {\n name: overlay.name ?? base.name,\n description: overlay.description ?? base.description,\n\n // agent_config: per-profile key, overlay profile wins\n agent_config: {\n ...(base.agent_config ?? {}),\n ...(overlay.agent_config ?? {}),\n },\n\n // startup: overlay wins (project-level only)\n startup: overlay.startup ?? base.startup,\n\n // mounts: by id — overlay wins\n mounts: mergeById(base.mounts ?? [], overlay.mounts ?? []),\n\n // connectors: by id — overlay wins\n connectors: mergeById(base.connectors ?? [], overlay.connectors ?? []),\n\n // mcp_servers: by id — overlay wins\n mcp_servers: mergeById(base.mcp_servers ?? [], overlay.mcp_servers ?? []),\n\n agent: mergeAgentConfig(base.agent, overlay.agent),\n\n workspace: mergeWorkspaceConfig(base.workspace, overlay.workspace),\n\n // secrets: overlay wins entirely\n secrets: overlay.secrets ?? base.secrets,\n\n // telemetry: overlay wins entirely (raw pass-through)\n telemetry: overlay.telemetry ?? base.telemetry,\n\n // dependencies: concatenate and dedupe\n dependencies: dedupe([...(base.dependencies ?? []), ...(overlay.dependencies ?? [])]),\n\n // global_backends: user-scope SSOT key — overlay wins entirely\n global_backends: overlay.global_backends ?? base.global_backends,\n\n // sources: dedupe by url — overlay entry wins for the same url\n sources: dedupeByKey([...(base.sources ?? []), ...(overlay.sources ?? [])], \"url\"),\n\n // stores: dedupe by url — overlay wins\n stores: dedupeByKey([...(base.stores ?? []), ...(overlay.stores ?? [])], \"url\"),\n\n // overrides: dedupe by ref — overlay wins\n overrides: dedupeByKey([...(base.overrides ?? []), ...(overlay.overrides ?? [])], \"ref\"),\n\n // plugins: concatenate + dedupe (like dependencies)\n plugins: dedupe([...(base.plugins ?? []), ...(overlay.plugins ?? [])]),\n\n // deploy: overlay wins entirely (scalar-like selection)\n deploy: overlay.deploy ?? base.deploy,\n };\n}\n\n/** Merge the `agent:` block — scalars overlay-win, deny lists union, hooks concat. */\nfunction mergeAgentConfig(\n base: AgentConfig | undefined,\n overlay: AgentConfig | undefined,\n): AgentConfig {\n return {\n definition: overlay?.definition ?? base?.definition,\n context: overlay?.context ?? base?.context,\n permissions: {\n ...base?.permissions,\n ...stripUndefined(overlay?.permissions),\n deny_write: dedupe([\n ...(base?.permissions?.deny_write ?? []),\n ...(overlay?.permissions?.deny_write ?? []),\n ]),\n deny_read: dedupe([\n ...(base?.permissions?.deny_read ?? []),\n ...(overlay?.permissions?.deny_read ?? []),\n ]),\n },\n subagents: {\n ...(base?.subagents ?? {}),\n ...(overlay?.subagents ?? {}),\n },\n hooks: {\n pre_flow: [...(base?.hooks?.pre_flow ?? []), ...(overlay?.hooks?.pre_flow ?? [])],\n post_flow: [...(base?.hooks?.post_flow ?? []), ...(overlay?.hooks?.post_flow ?? [])],\n pre_node: [...(base?.hooks?.pre_node ?? []), ...(overlay?.hooks?.pre_node ?? [])],\n post_node: [...(base?.hooks?.post_node ?? []), ...(overlay?.hooks?.post_node ?? [])],\n },\n };\n}\n\n/** Merge the `workspace:` block — directories/ignore union, setup/container overlay-win. */\nfunction mergeWorkspaceConfig(\n base: WorkspaceLayoutConfig | undefined,\n overlay: WorkspaceLayoutConfig | undefined,\n): WorkspaceLayoutConfig {\n return {\n directories: dedupe([...(base?.directories ?? []), ...(overlay?.directories ?? [])]),\n git: {\n init: overlay?.git?.init ?? base?.git?.init,\n ignore: dedupe([...(base?.git?.ignore ?? []), ...(overlay?.git?.ignore ?? [])]),\n },\n setup: overlay?.setup ?? base?.setup,\n container: overlay?.container ?? base?.container,\n };\n}\n\n// ── Diagnostics ───────────────────────────────────────────────────────────────\n\n/** Severity of a {@link Diagnostic} produced by {@link decodeSkaileYaml}. */\nexport type DiagnosticSeverity = \"error\" | \"warning\" | \"info\";\n\n/**\n * A structured note about a decoded `skaile.yaml` — a syntax error, a tolerated\n * legacy/non-canonical shape that was normalized, or an unrecognized enum value.\n * {@link decodeSkaileYaml} never throws; it reports problems here so each caller\n * (platform editor, runner, CLI) decides how loud to be.\n */\nexport interface Diagnostic {\n /** Stable machine code, e.g. `\"legacy_key_camelcase\"` / `\"unknown_driver\"`. */\n code: string;\n severity: DiagnosticSeverity;\n /** Human-readable, actionable message. */\n message: string;\n /** Dotted path into the config the note refers to, when applicable. */\n path?: string;\n}\n\n/** Result of {@link decodeSkaileYaml}: the normalized config plus any notes. */\nexport interface DecodeResult {\n config: SkWorkspaceConfig;\n diagnostics: Diagnostic[];\n}\n\n/**\n * Known runtime drivers — mirrors the keys of `DRIVER_DEFAULTS` (framework.ts).\n * Kept local to avoid a settings/framework ↔ workspace-config import cycle; a\n * drift test asserts parity.\n */\nconst KNOWN_DRIVERS = [\"omp\", \"claude-sdk\", \"codex\"] as const;\n\n/**\n * Known LLM/voice providers — mirrors `ALL_PROVIDERS` (settings.ts). Local for\n * the same cycle reason; a drift test asserts parity.\n */\nconst KNOWN_PROVIDERS = [\n \"anthropic\",\n \"openai\",\n \"google\",\n \"mistral\",\n \"groq\",\n \"openrouter\",\n \"deepseek\",\n \"xai\",\n \"together\",\n \"fireworks\",\n \"deepgram\",\n \"elevenlabs\",\n] as const;\n\nconst KNOWN_ACCESS = [\"read-only\", \"read-write\"] as const;\n\n/** Valid launcher strategies for a local (stdio) MCP server. */\nconst KNOWN_LAUNCHERS = [\"recipe\", \"package-runner\", \"path\"] as const;\n// Runtime transport literals the runner's external-mcp switch branches on.\n// \"streamable-http\" is an MCP-spec alias normalized to \"http\" before this check.\nconst KNOWN_TRANSPORTS = [\"stdio\", \"sse\", \"http\"] as const;\n\n// ── Raw → canonical normalization ─────────────────────────────────────────────\n\n/** Scalar fields that identify a flat (un-profiled) agent-config block. */\nconst AGENT_PROFILE_FIELDS = [\n \"driver\",\n \"provider\",\n \"model\",\n \"thinking\",\n \"effort\",\n \"skills_dir\",\n \"agents_dir\",\n \"prompts_dir\",\n] as const;\n\n/**\n * Coerce a raw agent-config block into the canonical profile-map shape\n * (`{ default: {...}, … }`).\n *\n * Accepts two authoring shapes:\n * - **Profile map** (canonical): `{ default: { driver, model }, staging: {…} }`\n * - **Flat profile**: `{ driver, model, provider }` — emitted by clients that\n * serialize a runtime config object straight to YAML. Wrapped as the\n * `default` profile so `settingsFromWorkspaceConfig` finds it.\n *\n * `wrappedFlat` reports whether a flat block was wrapped, so the caller can emit\n * a diagnostic. A block is flat when any known profile field is present as a\n * scalar; a profile named e.g. `driver` carries an object value, so the scalar\n * check disambiguates.\n */\nfunction normalizeAgentConfig(raw: Record<string, unknown>): {\n profiles: Record<string, AgentConfigProfile>;\n wrappedFlat: boolean;\n} {\n const looksFlat = AGENT_PROFILE_FIELDS.some((f) => typeof raw[f] === \"string\");\n return looksFlat\n ? { profiles: { default: raw as AgentConfigProfile }, wrappedFlat: true }\n : { profiles: raw as Record<string, AgentConfigProfile>, wrappedFlat: false };\n}\n\n/**\n * Normalize a raw parsed YAML object into the canonical SkWorkspaceConfig shape.\n * Pure structural pass; see {@link decodeSkaileYaml} for the diagnostics-aware\n * entry point. Tolerates backward-compatible fields:\n * - `agent-config` (hyphen) / `agent_config` (underscore) / `agentConfig` (camelCase) → `agent_config`\n * - flat agent-config (`{ driver, model }`) → `{ default: { driver, model } }`\n *\n * Hard cut: legacy top-level keys `repositories:` and `ai_resources:` (any case)\n * now throw — the migration is performed by the `migrate-skaile-manifest` skill.\n * @docLink packages/core/workspace-config#normalize-config\n */\nexport function normalizeConfig(raw: Record<string, unknown>): SkWorkspaceConfig {\n return normalizeConfigInternal(raw).config;\n}\n\n/**\n * Normalize the `agent-config` block (hyphen/underscore/camelCase key + flat\n * single-profile shape) onto `config.agent_config`, recording warnings for\n * non-canonical shapes. No-op when no recognized key is present.\n */\nfunction normalizeAgentConfigSection(\n raw: Record<string, unknown>,\n config: SkWorkspaceConfig,\n diagnostics: Diagnostic[],\n): void {\n // agent_config: accept hyphen (canonical), underscore, or camelCase, plus a\n // flat single-profile block. Non-canonical shapes are normalized + flagged.\n let agentConfigRaw: unknown;\n let agentConfigKey: string | undefined;\n if (raw[\"agent-config\"] !== undefined) {\n agentConfigRaw = raw[\"agent-config\"];\n agentConfigKey = \"agent-config\";\n } else if (raw.agent_config !== undefined) {\n agentConfigRaw = raw.agent_config;\n agentConfigKey = \"agent_config\";\n } else if (raw.agentConfig !== undefined) {\n agentConfigRaw = raw.agentConfig;\n agentConfigKey = \"agentConfig\";\n }\n if (!agentConfigRaw || typeof agentConfigRaw !== \"object\" || Array.isArray(agentConfigRaw)) {\n return;\n }\n if (agentConfigKey === \"agentConfig\") {\n diagnostics.push({\n code: \"legacy_key_camelcase\",\n severity: \"warning\",\n message: 'Non-canonical key \"agentConfig\" — use \"agent-config\".',\n path: \"agentConfig\",\n });\n }\n const { profiles, wrappedFlat } = normalizeAgentConfig(agentConfigRaw as Record<string, unknown>);\n if (wrappedFlat) {\n diagnostics.push({\n code: \"legacy_agent_config_flat\",\n severity: \"warning\",\n message:\n 'Flat agent-config block wrapped as the \"default\" profile — nest fields under \"default:\".',\n path: agentConfigKey,\n });\n }\n config.agent_config = profiles;\n}\n\n/**\n * Hard-cut guard for legacy/migrated top-level keys. `repositories:` /\n * `ai_resources:` were removed with the canonical-identity schema; `publisher:` /\n * `version:` / `assets:` are publication keys that moved to `skaile.manifest.yaml`\n * (2026-06-03 split). All throw with the spec wording — the migration is done by\n * the `migrate-skaile-manifest` skill, not code. decodeSkaileYaml catches the\n * throw and records a single `legacy_key_rejected` diagnostic (the message\n * carries the specifics); resolveSkWorkspaceConfig re-throws it at the runtime\n * boundary.\n */\nfunction assertNoLegacyTopLevelKeys(raw: Record<string, unknown>): void {\n if (raw.repositories !== undefined) {\n throw new Error(\n \"skaile.yaml: unknown top-level key `repositories:`. The schema changed — \" +\n \"see docs/concepts/manifest-schema.md, or ask your AI assistant to apply \" +\n \"the `migrate-skaile-manifest` skill.\",\n );\n }\n if (raw.ai_resources !== undefined || raw.aiResources !== undefined) {\n throw new Error(\n \"skaile.yaml: unknown top-level key `ai_resources:`. The schema changed — \" +\n \"see docs/concepts/manifest-schema.md, or ask your AI assistant to apply \" +\n \"the `migrate-skaile-manifest` skill.\",\n );\n }\n for (const key of [\"publisher\", \"version\", \"assets\"] as const) {\n if (raw[key] !== undefined) {\n throw new Error(\n `skaile.yaml: \\`${key}:\\` is no longer valid here — publication keys ` +\n \"(publisher, version, assets) describe what a repo publishes and now live in \" +\n \"skaile.manifest.yaml. See docs/concepts/manifest-schema.md, or run the \" +\n \"`migrate-skaile-manifest` skill.\",\n );\n }\n }\n}\n\n/** Normalize a single raw `overrides[]` item into an OverrideEntry, or `null` to skip. */\nfunction normalizeOverrideEntry(item: unknown): OverrideEntry | null {\n if (!item || typeof item !== \"object\" || Array.isArray(item)) return null;\n const o = item as Record<string, unknown>;\n const ref = typeof o.ref === \"string\" ? o.ref : \"\";\n const source = typeof o.source === \"string\" ? o.source : \"\";\n if (!ref || !source) return null;\n if (typeof o.reason !== \"string\") {\n throw new Error(\n `skaile.yaml: overrides[] entry for ${ref}: reason is required ` +\n \"and must be a non-empty string.\",\n );\n }\n if (o.reason.trim().length === 0) {\n throw new Error(`skaile.yaml: overrides[] entry for ${ref}: reason must not be empty.`);\n }\n return { ref, source, reason: o.reason };\n}\n\n/** Normalize the consumption-half `stores[]` array onto `config`. */\nfunction normalizeStoresSection(raw: Record<string, unknown>, config: SkWorkspaceConfig): void {\n if (!Array.isArray(raw.stores)) return;\n const entries: StoreEntry[] = [];\n for (const item of raw.stores) {\n if (!item || typeof item !== \"object\" || Array.isArray(item)) continue;\n const s = item as Record<string, unknown>;\n const url = typeof s.url === \"string\" ? s.url : \"\";\n if (!url) continue;\n entries.push({ url });\n }\n if (entries.length > 0) config.stores = entries;\n}\n\n/** Normalize the consumption-half `overrides[]` array onto `config`. */\nfunction normalizeOverridesSection(raw: Record<string, unknown>, config: SkWorkspaceConfig): void {\n if (!Array.isArray(raw.overrides)) return;\n const entries: OverrideEntry[] = [];\n for (const item of raw.overrides) {\n const entry = normalizeOverrideEntry(item);\n if (entry) entries.push(entry);\n }\n if (entries.length > 0) config.overrides = entries;\n}\n\n/** Normalize the consumption-half `stores[]` and `overrides[]` arrays. */\nfunction normalizeConsumptionSection(\n raw: Record<string, unknown>,\n config: SkWorkspaceConfig,\n): void {\n normalizeStoresSection(raw, config);\n normalizeOverridesSection(raw, config);\n}\n\n/**\n * Normalize the tolerantly-cast sections (mounts, connectors, mcp_servers,\n * plugins, deploy, agent, workspace, secrets, compaction, patches). Structural\n * validation is deferred — the runtime tolerates unexpected shapes.\n */\nfunction normalizeStructuralSections(\n raw: Record<string, unknown>,\n config: SkWorkspaceConfig,\n diagnostics: Diagnostic[],\n): void {\n if (Array.isArray(raw.mounts)) {\n config.mounts = raw.mounts as MountDeclaration[];\n }\n // connectors: no data_resources fallback — clean break\n if (Array.isArray(raw.connectors)) {\n config.connectors = raw.connectors as ConnectorDeclaration[];\n }\n if (Array.isArray(raw.mcp_servers)) {\n // Strip unknown launcher values at parse time so they never reach the runner.\n // A warning diagnostic is emitted for each stripped entry (mirroring unknown_driver/access).\n config.mcp_servers = (raw.mcp_servers as McpServerDeclaration[]).map((entry) => {\n if (\n entry.launcher !== undefined &&\n !(KNOWN_LAUNCHERS as readonly string[]).includes(entry.launcher)\n ) {\n diagnostics.push({\n code: \"unknown_launcher\",\n severity: \"warning\",\n message: `Unknown launcher \"${entry.launcher}\" on mcp_servers entry \"${entry.id}\" — expected one of: ${KNOWN_LAUNCHERS.join(\", \")}.`,\n path: `mcp_servers.${entry.id}.launcher`,\n });\n const { launcher: _dropped, ...rest } = entry;\n return rest as McpServerDeclaration;\n }\n return entry;\n });\n }\n if (Array.isArray(raw.plugins)) {\n const specs = raw.plugins.filter((p): p is string => typeof p === \"string\" && p.length > 0);\n if (specs.length > 0) config.plugins = specs;\n }\n // deploy: structural only — the target id is resolved/validated against\n // pluginRegistry at deploy time, not here. A block missing a string target is\n // dropped silently (mirrors connectors' tolerant cast).\n if (raw.deploy && typeof raw.deploy === \"object\" && !Array.isArray(raw.deploy)) {\n const d = raw.deploy as Record<string, unknown>;\n if (typeof d.target === \"string\" && d.target.length > 0) {\n config.deploy = { target: d.target };\n if (d.config !== undefined) config.deploy.config = d.config;\n }\n }\n if (raw.agent) config.agent = raw.agent as AgentConfig;\n if (raw.workspace) config.workspace = raw.workspace as WorkspaceLayoutConfig;\n if (raw.secrets && typeof raw.secrets === \"object\") {\n config.secrets = raw.secrets as SecretsConfig;\n }\n if (raw.compaction && typeof raw.compaction === \"object\" && !Array.isArray(raw.compaction)) {\n config.compaction = raw.compaction as CompactionConfig;\n }\n if (raw.patches && typeof raw.patches === \"object\" && !Array.isArray(raw.patches)) {\n config.patches = raw.patches as Record<string, string>;\n }\n}\n\n/** Normalize `dependencies[]`, `sources[]`, and the raw `telemetry` pass-through. */\nfunction normalizeDependencySection(raw: Record<string, unknown>, config: SkWorkspaceConfig): void {\n if (Array.isArray(raw.dependencies)) {\n config.dependencies = raw.dependencies.filter((d): d is string => typeof d === \"string\");\n }\n\n // global_backends: accept hyphen (canonical) or underscore. Keep only known\n // DriverTargets — an unknown id is dropped here; `resolveGlobalBackends`\n // additionally falls back to auto-detection when the result is empty.\n const rawBackends = raw[\"global-backends\"] ?? raw.global_backends;\n if (Array.isArray(rawBackends)) {\n const valid = rawBackends.filter((b): b is DriverTarget =>\n (SUPPORTED_DRIVER_TARGETS as string[]).includes(b as string),\n );\n if (valid.length > 0) config.global_backends = [...new Set(valid)];\n }\n\n if (Array.isArray(raw.sources)) {\n const entries: SourceEntry[] = [];\n for (const item of raw.sources) {\n if (!item || typeof item !== \"object\" || Array.isArray(item)) continue;\n const s = item as Record<string, unknown>;\n const url = typeof s.url === \"string\" ? s.url : \"\";\n if (!url) continue;\n const entry: SourceEntry = { url };\n if (typeof s.pin === \"string\" && s.pin.length > 0) entry.pin = s.pin;\n entries.push(entry);\n }\n if (entries.length > 0) config.sources = entries;\n }\n\n // telemetry: pass through raw — parsed by @skaile/workspaces/telemetry\n if (raw.telemetry && typeof raw.telemetry === \"object\" && !Array.isArray(raw.telemetry)) {\n config.telemetry = raw.telemetry as Record<string, unknown>;\n }\n}\n\n/** Diagnostics-collecting core of {@link normalizeConfig}. */\nfunction normalizeConfigInternal(raw: Record<string, unknown>): DecodeResult {\n const config: SkWorkspaceConfig = {};\n const diagnostics: Diagnostic[] = [];\n\n if (raw.name) config.name = String(raw.name);\n if (raw.description) config.description = String(raw.description);\n\n normalizeAgentConfigSection(raw, config, diagnostics);\n\n if (Array.isArray(raw.startup)) {\n config.startup = raw.startup as StartupDirective[];\n }\n\n assertNoLegacyTopLevelKeys(raw);\n normalizeConsumptionSection(raw, config);\n normalizeStructuralSections(raw, config, diagnostics);\n normalizeDependencySection(raw, config);\n\n return { config, diagnostics };\n}\n\n// ── Codec (decode / encode) ────────────────────────────────────────────────────\n\n/**\n * Decode `skaile.yaml` text into a normalized {@link SkWorkspaceConfig} plus\n * {@link Diagnostic}s. Total — never throws: a YAML syntax error or a non-object\n * root is reported as an `error`-severity diagnostic with an empty config.\n * Legacy/non-canonical shapes (camelCase keys, flat agent-config, the old\n * ai_resources object) are normalized and reported as `warning`s; unrecognized\n * driver/provider/access values are reported as `warning`s too.\n *\n * Pair with {@link encodeSkaileYaml} for round-tripping. The round-trip is\n * canonical-lossless on the typed model (`decode(encode(config)).config` deep-\n * equals `config`) but does not preserve comments or key order — use\n * `WorkspaceYamlEditor` for comment-preserving in-place edits.\n * @docLink packages/core/workspace-config#decode-skaile-yaml\n */\nexport function decodeSkaileYaml(text: string): DecodeResult {\n let parsed: unknown;\n try {\n parsed = parse(text) ?? {};\n } catch (err) {\n return {\n config: {},\n diagnostics: [\n {\n code: \"yaml_syntax\",\n severity: \"error\",\n message: `Invalid YAML: ${err instanceof Error ? err.message : String(err)}`,\n },\n ],\n };\n }\n if (typeof parsed !== \"object\" || parsed === null || Array.isArray(parsed)) {\n return {\n config: {},\n diagnostics: [\n {\n code: \"non_object_root\",\n severity: \"error\",\n message: \"skaile.yaml must be a mapping at the top level.\",\n },\n ],\n };\n }\n // normalizeConfigInternal hard-throws on legacy keys (repositories:/ai_resources:).\n // decodeSkaileYaml is total by contract, so convert that throw into an\n // `error`-severity diagnostic for editor/preview callers.\n let result: DecodeResult;\n try {\n result = normalizeConfigInternal(parsed as Record<string, unknown>);\n } catch (err) {\n return {\n config: {},\n diagnostics: [\n {\n code: \"legacy_key_rejected\",\n severity: \"error\",\n message: err instanceof Error ? err.message : String(err),\n },\n ],\n };\n }\n validateConfigValues(result.config, result.diagnostics);\n return result;\n}\n\n/**\n * Encode a {@link SkWorkspaceConfig} to canonical `skaile.yaml` text:\n * deterministic key order, the hyphenated `agent-config` key, only defined\n * fields. This is the single sanctioned writer — clients should build a typed\n * config and encode it here rather than hand-serializing YAML.\n * @docLink packages/core/workspace-config#encode-skaile-yaml\n */\nexport function encodeSkaileYaml(config: SkWorkspaceConfig): string {\n return stringify(toCanonicalObject(config), { lineWidth: 120 });\n}\n\n/** Append `warning` diagnostics for unrecognized driver/provider/access values. */\nfunction validateConfigValues(config: SkWorkspaceConfig, diagnostics: Diagnostic[]): void {\n for (const [profile, p] of Object.entries(config.agent_config ?? {})) {\n if (p?.driver && !(KNOWN_DRIVERS as readonly string[]).includes(p.driver)) {\n diagnostics.push({\n code: \"unknown_driver\",\n severity: \"warning\",\n message: `Unknown driver \"${p.driver}\" — expected one of: ${KNOWN_DRIVERS.join(\", \")}.`,\n path: `agent-config.${profile}.driver`,\n });\n }\n if (p?.provider && !(KNOWN_PROVIDERS as readonly string[]).includes(p.provider)) {\n diagnostics.push({\n code: \"unknown_provider\",\n severity: \"warning\",\n message: `Unknown provider \"${p.provider}\" — expected one of: ${KNOWN_PROVIDERS.join(\", \")}.`,\n path: `agent-config.${profile}.provider`,\n });\n }\n }\n const checkAccess = (access: string | undefined, path: string) => {\n if (access && !(KNOWN_ACCESS as readonly string[]).includes(access)) {\n diagnostics.push({\n code: \"unknown_access\",\n severity: \"warning\",\n message: `Unknown access \"${access}\" — expected \"read-only\" or \"read-write\".`,\n path,\n });\n }\n };\n for (const c of config.connectors ?? []) checkAccess(c.access, `connectors.${c.id}.access`);\n for (const m of config.mounts ?? []) checkAccess(m.access, `mounts.${m.id}.access`);\n\n const network = config.agent?.permissions?.network;\n if (network) {\n if (network.mode && !(KNOWN_NETWORK_MODES as readonly string[]).includes(network.mode)) {\n diagnostics.push({\n code: \"unknown_network_mode\",\n severity: \"warning\",\n message: `Unknown network mode \"${network.mode}\" — expected one of: ${KNOWN_NETWORK_MODES.join(\", \")}.`,\n path: \"agent.permissions.network.mode\",\n });\n }\n if (network.allowlist && network.allowlist.length > 0 && network.mode !== \"allowlist\") {\n diagnostics.push({\n code: \"unexpected_network_allowlist\",\n severity: \"warning\",\n message: `network.allowlist is set but mode is \"${network.mode}\" — the allowlist is ignored unless mode is \"allowlist\".`,\n path: \"agent.permissions.network.allowlist\",\n });\n }\n }\n}\n\n/**\n * Canonical key order for encode. `agent_config` is emitted under the hyphenated\n * `agent-config` key (see {@link CONFIG_KEY_TO_YAML}); any field not listed here\n * is appended afterward so forward-compat keys survive a round-trip.\n */\nconst CANONICAL_KEY_ORDER: (keyof SkWorkspaceConfig)[] = [\n \"name\",\n \"description\",\n \"agent_config\",\n \"dependencies\",\n \"global_backends\",\n \"plugins\",\n \"sources\",\n \"stores\",\n \"overrides\",\n \"startup\",\n \"connectors\",\n \"mcp_servers\",\n \"deploy\",\n \"mounts\",\n \"agent\",\n \"workspace\",\n \"secrets\",\n \"telemetry\",\n \"compaction\",\n \"patches\",\n];\n\n/** Internal field name → canonical YAML key, where they differ. */\nconst CONFIG_KEY_TO_YAML: Partial<Record<keyof SkWorkspaceConfig, string>> = {\n agent_config: \"agent-config\",\n};\n\nfunction toCanonicalObject(config: SkWorkspaceConfig): Record<string, unknown> {\n const out: Record<string, unknown> = {};\n const emit = (key: keyof SkWorkspaceConfig) => {\n const value = config[key];\n if (value === undefined) return;\n out[CONFIG_KEY_TO_YAML[key] ?? key] = value;\n };\n for (const key of CANONICAL_KEY_ORDER) emit(key);\n // Preserve any field not in the canonical order (forward-compat).\n for (const key of Object.keys(config) as (keyof SkWorkspaceConfig)[]) {\n if (CANONICAL_KEY_ORDER.includes(key)) continue;\n emit(key);\n }\n return out;\n}\n\n// ── Helpers ───────────────────────────────────────────────────────────────────\n\nfunction parseConfigFile(filePath: string, name: string): SkWorkspaceConfigFile | null {\n let raw: string;\n try {\n raw = readFileSync(filePath, \"utf-8\");\n } catch {\n return null;\n }\n const { config, diagnostics } = decodeSkaileYaml(raw);\n // Preserve the legacy contract: an unparseable file reads as \"no config\".\n if (diagnostics.some((d) => d.code === \"yaml_syntax\")) return null;\n return { path: filePath, name, config, diagnostics };\n}\n\nfunction dedupe(arr: string[]): string[] {\n return [...new Set(arr)];\n}\n\nfunction dedupeByKey<T extends object>(arr: T[], key: string | ((item: T) => string)): T[] {\n const keyOf = typeof key === \"function\" ? key : (item: T) => String((item as any)[key] ?? \"\");\n const seen = new Set<string>();\n const result: T[] = [];\n for (let i = arr.length - 1; i >= 0; i--) {\n const val = keyOf(arr[i]!);\n if (!seen.has(val)) {\n seen.add(val);\n result.unshift(arr[i]!);\n }\n }\n return result;\n}\n\nfunction mergeById<T extends { id: string }>(base: T[], overlay: T[]): T[] {\n const map = new Map<string, T>();\n for (const r of base) map.set(r.id, r);\n for (const r of overlay) map.set(r.id, r);\n return [...map.values()];\n}\n\nfunction stripUndefined<T extends object>(obj?: T): Partial<T> {\n if (!obj) return {};\n const result: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(obj)) {\n if (v !== undefined) result[k] = v;\n }\n return result as Partial<T>;\n}\n\n// ── MCP server loader ─────────────────────────────────────────────────────────\n\n/**\n * Build a `McpServerDeclaration` from a resolved `CatalogEntry` with `kind: \"mcp-server\"`.\n * Maps `metadata` fields (transport, command, args, env, url, headers) to declaration fields.\n * Returns `null` when the entry has no usable metadata (no command and no url).\n */\nfunction mcpDeclFromCatalogEntry(entry: CatalogEntry): McpServerDeclaration | null {\n const m = entry.metadata;\n if (!m) return null;\n\n const decl: McpServerDeclaration = { id: entry.name };\n if (m.transport) {\n // Normalize the MCP-spec alias to the runtime literal the runner branches on,\n // then allow-list: an unrecognized value is warned-and-skipped rather than cast\n // through to the runner (mirrors the unknown_launcher diagnostic).\n const raw = String(m.transport);\n const t = raw === \"streamable-http\" ? \"http\" : raw;\n if ((KNOWN_TRANSPORTS as readonly string[]).includes(t)) {\n decl.transport = t as (typeof KNOWN_TRANSPORTS)[number];\n } else {\n console.warn(\n `[workspace-config] mcpDeclFromCatalogEntry: unknown transport \"${raw}\" on entry \"${entry.name}\" — expected one of: ${KNOWN_TRANSPORTS.join(\", \")}. Ignoring.`,\n );\n }\n }\n if (m.command) decl.command = String(m.command);\n if (Array.isArray(m.args)) decl.args = m.args.map(String);\n if (m.env && typeof m.env === \"object\") decl.env = m.env as Record<string, string>;\n if (m.url) decl.url = String(m.url);\n if (m.headers && typeof m.headers === \"object\") {\n decl.headers = m.headers as Record<string, string>;\n }\n if (entry.description) decl.description = entry.description;\n if (m.recipe && typeof m.recipe === \"object\" && !Array.isArray(m.recipe)) {\n const recipe = parseCatalogRecipe(m.recipe as Record<string, unknown>, entry.name);\n if (recipe) decl.recipe = recipe;\n }\n\n // Must have at least a command (stdio) or url (sse/http) to be useful\n if (!decl.command && !decl.url) return null;\n return decl;\n}\n\n/**\n * Parse a raw recipe object from `MCP.md` metadata into a validated\n * {@link AssetRecipe}. Returns `null` when there is no effective attr, or when\n * validation fails (the recipe is then treated as absent — the server may still\n * be usable via command/url without recipe substitution). `entryName` is used\n * only in the warning message.\n */\nfunction parseCatalogRecipe(r: Record<string, unknown>, entryName: string): AssetRecipe | null {\n const hasFlake = typeof r.flake === \"string\";\n // BYO-flake form: `attr` is optional and defaults to \"default\"; legacy form\n // requires `attr`. Compute the effective attr to validate.\n const rawAttr = typeof r.attr === \"string\" ? r.attr : undefined;\n const effectiveAttr = rawAttr ?? (hasFlake ? DEFAULT_RECIPE_ATTR : undefined);\n if (effectiveAttr === undefined) return null;\n\n try {\n validateAssetRecipeAttr(effectiveAttr);\n if (hasFlake) {\n // Validate the flake source too; invalid flake drops the WHOLE recipe\n // (do not silently fall back to a platform-flake attr — a publisher\n // that declared a flake intends to build it; building a same-named\n // platform attr would be a confusing security footgun).\n validateAssetRecipeFlake(r.flake as string);\n const recipe: AssetRecipe = { attr: effectiveAttr, flake: r.flake as string };\n if (typeof r.publisher === \"string\") recipe.publisher = r.publisher;\n return recipe;\n }\n return { attr: effectiveAttr };\n } catch (err) {\n // Invalid attr or flake — skip the recipe field entirely (treat as if\n // recipe was absent). The MCP server may still be usable via a\n // command/url without recipe substitution.\n console.warn(\n `[workspace-config] mcpDeclFromCatalogEntry: invalid recipe for entry \"${entryName}\": ${err instanceof Error ? err.message : String(err)}`,\n );\n return null;\n }\n}\n\n/**\n * Merge two `McpServerDeclaration` objects field-by-field.\n * `overlay` values win for every non-undefined field; `base` provides defaults.\n */\nfunction mergeMcpDeclarations(\n base: McpServerDeclaration,\n overlay: McpServerDeclaration,\n): McpServerDeclaration {\n return {\n id: overlay.id,\n transport: overlay.transport ?? base.transport,\n command: overlay.command ?? base.command,\n args: overlay.args ?? base.args,\n env: overlay.env ? (base.env ? { ...base.env, ...overlay.env } : overlay.env) : base.env,\n url: overlay.url ?? base.url,\n headers: overlay.headers\n ? base.headers\n ? { ...base.headers, ...overlay.headers }\n : overlay.headers\n : base.headers,\n description: overlay.description ?? base.description,\n tags: overlay.tags ?? base.tags,\n recipe: overlay.recipe ?? base.recipe,\n };\n}\n\n/**\n * Scan `<projectDir>/.skaile/assets/mcp-server/<name>/MCP.md` for MCP servers\n * that the platform materializer has written to disk for a subscribed asset.\n *\n * For each immediate subdirectory containing an `MCP.md`, the manifest is parsed\n * via {@link fromMcpServerMdContent} and mapped to a declaration via\n * {@link mcpDeclFromCatalogEntry}. A sibling `.instance.json` (written by the\n * platform materializer) is folded into `decl.env`.\n *\n * **Env-fold precedence (lowest → highest):**\n * 1. `MCP.md` `env` defaults\n * 2. string-valued entries of `.instance.json` `config` (non-string config\n * values — objects/arrays/numbers — are skipped so env never contains\n * `[object Object]`)\n * 3. `.instance.json` `resolvedSecrets` (always folded, all keys)\n *\n * Folded secret *values* are never logged. A malformed `MCP.md` for one asset\n * is caught per-directory and skipped (warned without secret values) so one bad\n * asset never aborts the whole scan.\n *\n * @param projectDir - Workspace root containing `.skaile/assets/mcp-server/`\n * @returns Declarations for every materialized MCP asset (empty if the dir is absent)\n */\n// Strip a publisher scope so a declared `@pub/name` matches a materialized dir\n// named `name` (and vice versa) without a false strict-mode exclusion.\nconst unscopedTail = (x: string): string => (x.includes(\"/\") ? x.split(\"/\").pop()! : x);\n\n/**\n * Fold a sibling `.instance.json` (written by the platform materializer) into\n * `decl.env`. Env-fold precedence (lowest → highest): existing `decl.env` <\n * string-valued `config` entries < `resolvedSecrets`. A malformed transient\n * `.instance.json` must not nuke a valid MCP server — parse errors are caught\n * here (warned without secret values) so the decl survives with its `MCP.md`\n * env. No-op when the file is absent. `name` is used only in the warning.\n */\nfunction foldInstanceEnv(decl: McpServerDeclaration, instancePath: string, name: string): void {\n if (!existsSync(instancePath)) return;\n try {\n const instance = JSON.parse(readFileSync(instancePath, \"utf8\")) as {\n config?: Record<string, unknown>;\n resolvedSecrets?: Record<string, unknown>;\n };\n\n const env: Record<string, string> = { ...(decl.env ?? {}) };\n\n // string-config < resolvedSecrets (folded after, so secrets win)\n if (instance.config && typeof instance.config === \"object\") {\n for (const [k, v] of Object.entries(instance.config)) {\n if (typeof v === \"string\") env[k] = v;\n }\n }\n if (instance.resolvedSecrets && typeof instance.resolvedSecrets === \"object\") {\n for (const [k, v] of Object.entries(instance.resolvedSecrets)) {\n // Guard like the config fold above — a non-string secret (serializer\n // bug) must not land in subprocess env as \"[object Object]\"/\"null\".\n if (typeof v === \"string\") env[k] = v;\n }\n }\n\n if (Object.keys(env).length > 0) decl.env = env;\n } catch (err) {\n // Never include secret values in the warning — only the failing path + message.\n console.warn(\n `[workspace-config] foldInstanceEnv: ignoring malformed \".instance.json\" for \"${name}\": ${\n err instanceof Error ? err.message : String(err)\n }`,\n );\n }\n}\n\n/**\n * Derive a single MCP declaration from a materialized on-disk subdir.\n * Returns `null` when the subdir has no `MCP.md` or when parsing fails\n * (warns without aborting the caller's scan).\n */\nexport function deriveSingleMaterializedMcpDeclaration(\n subDir: string,\n name: string,\n): McpServerDeclaration | null {\n const mdPath = join(subDir, \"MCP.md\");\n if (!existsSync(mdPath)) return null;\n\n try {\n const mdContent = readFileSync(mdPath, \"utf8\");\n const { body } = parseFrontmatter(mdContent);\n const entry = fromMcpServerMdContent(mdContent, name, mdPath);\n const decl = mcpDeclFromCatalogEntry(entry);\n if (!decl) return null;\n\n decl.id = entry.name || name;\n foldInstanceEnv(decl, join(subDir, \".instance.json\"), name);\n const trimmedBody = body.trim();\n if (trimmedBody.length > 0) decl.instructions = trimmedBody;\n return decl;\n } catch (err) {\n // Never include secret values — only the failing path + message.\n console.warn(\n `[workspace-config] deriveSingleMaterializedMcpDeclaration: failed to load \"${mdPath}\": ${\n err instanceof Error ? err.message : String(err)\n }`,\n );\n return null;\n }\n}\n\nfunction loadMaterializedMcpDeclarations(projectDir: string): McpServerDeclaration[] {\n const dir = join(projectDir, \".skaile/assets/mcp-server\");\n if (!existsSync(dir)) return [];\n\n const result: McpServerDeclaration[] = [];\n\n let subdirs: string[];\n try {\n subdirs = readdirSync(dir, { withFileTypes: true })\n .filter((e) => e.isDirectory())\n .map((e) => e.name);\n } catch {\n return [];\n }\n\n for (const name of subdirs) {\n const subDir = join(dir, name);\n const decl = deriveSingleMaterializedMcpDeclaration(subDir, name);\n if (decl) result.push(decl);\n }\n\n return result;\n}\n\n/**\n * Copy each materialized skill the platform materializer wrote to\n * `<projectDir>/.skaile/assets/skill/<name>/` into the active driver's native\n * skills dir (`<projectDir>/<skillsDir>/<name>/`) so native discovery surfaces\n * them to the LLM. Mirrors {@link loadMaterializedMcpDeclarations}: the scan\n * ALWAYS runs, independent of `dependencies:`.\n *\n * Only immediate subdirectories containing a `SKILL.md` are staged. The copy is\n * idempotent (`force: true` overwrites a previously staged copy on refresh).\n * `.instance.json` is NEVER copied — it can hold a materializer's\n * `resolvedSecrets`, which must not leak into `.claude/skills/`; Claude Code\n * skills do not consume it either.\n *\n * A failure staging one skill is caught per-directory, warned (path + message\n * only, never file contents), and skipped so one bad skill never aborts the scan.\n *\n * When `opts.declared` is provided, only skills whose dir name appears in it are\n * staged — undeclared on-disk dirs (\"ghosts\") are skipped so the effective set\n * equals `skaile.yaml` exactly (the canonical-contract invariant; the runner\n * always passes `declared`). Publisher-scope tolerance: `@pub/name` declared\n * matches a dir named `name`, and vice versa. When `opts.declared` is omitted the\n * scan stages every materialized skill (used by callers that do their own gating).\n *\n * @param projectDir - Workspace root containing `.skaile/assets/skill/`\n * @param skillsDir - Driver-relative skills dir, e.g. `.claude/skills`\n * @param opts - When `declared` is present, restrict staging to those names\n * @returns Names of the skills staged (empty if the source dir is absent)\n */\nexport function stageMaterializedSkills(\n projectDir: string,\n skillsDir: string,\n opts?: { declared?: string[] },\n): string[] {\n const dir = join(projectDir, \".skaile/assets/skill\");\n if (!existsSync(dir)) return [];\n\n const staged: string[] = [];\n\n let subdirs: string[];\n try {\n subdirs = readdirSync(dir, { withFileTypes: true })\n .filter((e) => e.isDirectory())\n .map((e) => e.name);\n } catch {\n return [];\n }\n\n // When a declared set is provided, build it once; each dir name is matched\n // against both its full form and its unscoped tail (publisher-scope tolerance).\n let declaredSet: Set<string> | undefined;\n if (opts?.declared !== undefined) {\n declaredSet = new Set<string>(opts.declared.flatMap((d) => [d, unscopedTail(d)]));\n }\n\n for (const name of subdirs) {\n const src = join(dir, name);\n if (!existsSync(join(src, \"SKILL.md\"))) continue;\n\n if (declaredSet && !declaredSet.has(name) && !declaredSet.has(unscopedTail(name))) continue;\n\n const dest = join(projectDir, skillsDir, name);\n try {\n // cpSync recursive creates dest; exclude `.instance.json` at any depth (resolvedSecrets).\n cpSync(src, dest, {\n recursive: true,\n force: true,\n filter: (source) => basename(source) !== \".instance.json\",\n });\n staged.push(name);\n } catch (err) {\n // Never include file contents in the warning — only the failing path + message.\n console.warn(\n `[workspace-config] stageMaterializedSkills: failed to stage \"${src}\": ${\n err instanceof Error ? err.message : String(err)\n }`,\n );\n }\n }\n\n return staged;\n}\n\n/**\n * Resolve each `sources[]` entry to an on-disk clone path under the unified\n * machine cache (`<cache>/sources/<host>/<owner>/<repo>/`) and its resolved HEAD\n * commit. Entries with no on-disk clone are skipped — the install pipeline\n * clones them first.\n */\nfunction buildSourceClones(sources: SourceEntry[]): SourceClone[] {\n const sourcesDir = getGlobalCacheDir();\n const clones: SourceClone[] = [];\n for (const s of sources) {\n const localPath = join(sourcesDir, sourceCacheKey(s.url));\n if (!existsSync(localPath)) continue;\n const commit = getRepoCommit(localPath) ?? \"0\".repeat(40);\n clones.push({ localPath, sourceUrl: s.url, commit, tag: s.pin });\n }\n return clones;\n}\n\n/** Build a synthetic CatalogEntry from a provenance candidate's MCP metadata. */\nfunction catalogEntryFromCandidate(c: ProvenanceCandidate): CatalogEntry {\n const md = c.metadata ?? {};\n const entry: CatalogEntry = {\n name: c.name,\n kind: c.kind as CatalogEntry[\"kind\"],\n description: c.description ?? (typeof md.description === \"string\" ? md.description : \"\"),\n source: c.files[0]?.path ?? \"\",\n publisher: c.publisher,\n version: c.version,\n requires: [],\n dependencies: c.deps ?? [],\n metadata: c.metadata,\n };\n if (c.category != null) entry.category = c.category;\n if (c.keywords && c.keywords.length > 0) entry.keywords = c.keywords;\n if (c.license != null) entry.license = c.license;\n if (c.homepage != null) entry.homepage = c.homepage;\n return entry;\n}\n\n/**\n * Load MCP server declarations by merging three sources:\n *\n * 1. **Catalog defaults** — `mcp-server:*` refs in the top-level `dependencies`\n * array, resolved against the provenance index built from the project's\n * cloned `sources[]`. The `MCP.md` frontmatter (captured on the walker's\n * `metadata` field) provides default config (transport, command, args, env,\n * url, headers).\n *\n * 2. **Materialized assets** — MCP servers the platform materializer has written\n * to `<projectDir>/.skaile/assets/mcp-server/<name>/MCP.md` for subscribed\n * assets (see {@link loadMaterializedMcpDeclarations}). This scan ALWAYS runs,\n * so a subscribed asset on disk with no `dependencies:` and no `mcp_servers:`\n * entry is still picked up.\n *\n * 3. **Explicit declarations** — entries in the `mcp_servers` section of\n * `skaile.yaml`. These override the other two sources field-by-field when the\n * `id` matches.\n *\n * **Precedence (lowest → highest):** catalog-dep refs < materialized assets <\n * explicit `mcp_servers:`. A catalog-dep and a materialized asset with the same\n * id merge (materialized overlay onto catalog base) rather than double-counting.\n *\n * @param projectDir - Workspace root where `skaile.yaml` lives\n * @returns Unified array of `McpServerDeclaration` objects ready for the runner\n * @docLink packages/core/workspace-config#load-mcp-server-declarations\n */\n/**\n * Resolve the first provenance candidate for an `mcp-server` ref. Prefers the\n * publisher-keyed candidate; falls back to any candidate whose key ends with\n * `/<kind>:<name>`. Returns `undefined` when nothing matches.\n */\nfunction lookupMcpCandidate(\n provenanceIndex: ProvenanceIndex,\n ref: ReturnType<typeof parseAssetRef>,\n): ProvenanceCandidate | undefined {\n let candidates: ProvenanceCandidate[] | undefined;\n if (ref.publisher) {\n candidates = provenanceIndex.get(`${ref.publisher}/${ref.kind}:${ref.name}`);\n }\n if (!candidates) {\n for (const [key, arr] of provenanceIndex) {\n if (key.endsWith(`/${ref.kind}:${ref.name}`)) {\n candidates = arr;\n break;\n }\n }\n }\n return candidates?.[0];\n}\n\n/**\n * Build the strict-mode declared-name set: explicit `mcp_servers` ids ∪ dep-ref\n * names (kind `mcp-server`), each contributing both its full and unscoped form\n * so a scoped declaration (e.g. id `@pub/excel`) still admits a materialized dir\n * named `excel`.\n */\nfunction buildDeclaredMcpNames(\n explicit: McpServerDeclaration[],\n mcpRefStrings: string[],\n): Set<string> {\n return new Set<string>([\n ...explicit.flatMap((e) => [e.id, unscopedTail(e.id)]),\n ...mcpRefStrings.flatMap((refStr) => {\n try {\n const r = parseAssetRef(refStr);\n return [r.name, unscopedTail(r.name)];\n } catch {\n return [];\n }\n }),\n ]);\n}\n\n/**\n * Collect `mcp-server` dep refs from the top-level `dependencies` array only.\n * (ai_resources[].dependencies is no longer a thing.) Parse failures surface\n * elsewhere (install pipeline) and are skipped here.\n */\nfunction collectMcpRefStrings(dependencies: string[] | undefined): string[] {\n const mcpRefStrings: string[] = [];\n for (const dep of dependencies ?? []) {\n try {\n const ref = parseAssetRef(dep);\n if (ref.kind === \"mcp-server\") mcpRefStrings.push(dep);\n } catch {\n // Parse failures surface elsewhere (install pipeline). Skip here.\n }\n }\n return mcpRefStrings;\n}\n\n/** Build the provenance index from cloned sources for catalog-default lookup. */\nfunction buildMcpProvenanceIndex(sources: SourceEntry[], projectDir: string): ProvenanceIndex {\n return sources.length > 0\n ? buildProvenanceIndex(buildSourceClones(sources), { projectDir })\n : (new Map() as ProvenanceIndex);\n}\n\n/**\n * Source 1 (lowest): upsert catalog-dep refs resolved via the provenance index.\n */\nfunction upsertCatalogMcpDecls(\n mcpRefStrings: string[],\n provenanceIndex: ProvenanceIndex,\n upsert: (decl: McpServerDeclaration) => void,\n): void {\n const seen = new Set<string>();\n for (const refStr of mcpRefStrings) {\n let ref: ReturnType<typeof parseAssetRef>;\n try {\n ref = parseAssetRef(refStr);\n } catch {\n continue;\n }\n if (seen.has(ref.name)) continue;\n seen.add(ref.name);\n\n const candidate = lookupMcpCandidate(provenanceIndex, ref);\n if (!candidate) continue;\n\n const catalogDecl = mcpDeclFromCatalogEntry(catalogEntryFromCandidate(candidate));\n if (!catalogDecl) continue;\n\n upsert(catalogDecl);\n }\n}\n\n/**\n * Source 2: upsert materialized assets, overlaying onto matching catalog base.\n * Only `skaile.yaml`-declared assets may load (the canonical-contract invariant);\n * undeclared on-disk entries (\"ghosts\") are silently skipped so the effective set\n * equals skaile.yaml exactly. The platform always writes the full effective set,\n * so nothing legitimately active is dropped.\n */\nfunction upsertMaterializedMcpDecls(\n materialized: McpServerDeclaration[],\n explicit: McpServerDeclaration[],\n mcpRefStrings: string[],\n upsert: (decl: McpServerDeclaration) => void,\n): void {\n const declaredNames = buildDeclaredMcpNames(explicit, mcpRefStrings);\n for (const decl of materialized) {\n if (declaredNames.has(decl.id) || declaredNames.has(unscopedTail(decl.id))) upsert(decl);\n }\n}\n\nexport function loadMcpServerDeclarations(projectDir: string): McpServerDeclaration[] {\n const config = resolveSkWorkspaceConfig(projectDir);\n const explicit = config.mcp_servers ?? [];\n\n // Materialized scan always runs — the primary use case is a subscribed asset\n // on disk with no dependencies: and no mcp_servers: entry.\n const materialized = loadMaterializedMcpDeclarations(projectDir);\n\n const mcpRefStrings = collectMcpRefStrings(config.dependencies);\n const provenanceIndex = buildMcpProvenanceIndex(config.sources ?? [], projectDir);\n\n // byId tracks the current merged decl per id so later, higher-precedence\n // sources overlay onto it instead of double-counting.\n const byId = new Map<string, McpServerDeclaration>();\n const order: string[] = [];\n\n const upsert = (decl: McpServerDeclaration) => {\n const existing = byId.get(decl.id);\n if (existing) {\n byId.set(decl.id, mergeMcpDeclarations(existing, decl));\n } else {\n byId.set(decl.id, decl);\n order.push(decl.id);\n }\n };\n\n // Source 1 (lowest): catalog-dep refs resolved via the provenance index.\n upsertCatalogMcpDecls(mcpRefStrings, provenanceIndex, upsert);\n\n // Source 2: materialized assets — overlay onto matching catalog base. Only\n // declared assets load (canonical-contract invariant); undeclared ghosts drop.\n upsertMaterializedMcpDecls(materialized, explicit, mcpRefStrings, upsert);\n\n // Source 3 (highest): explicit mcp_servers: — overlay field-by-field.\n for (const decl of explicit) {\n upsert(decl);\n }\n\n return order.map((id) => byId.get(id) as McpServerDeclaration);\n}\n\n// ── Agent definition resolver ──────────────────────────────────────────────────\n\n/**\n * Walk upward from `from` (max 8 levels) until a directory containing\n * `ai-assets/` is found. Returns the absolute path to that `ai-assets/`\n * directory, or undefined if none found.\n */\nfunction findAiAssetsDir(from: string): string | undefined {\n let dir = resolve(from);\n for (let i = 0; i < 8; i++) {\n const candidate = join(dir, \"ai-assets\");\n if (existsSync(candidate)) return candidate;\n const resolved = resolve(dir, \"..\");\n if (resolved === dir) break;\n dir = resolved;\n }\n return undefined;\n}\n\n/**\n * Resolve the `agent.definition` field from `skaile.yaml` in `projectDir`\n * to an absolute filesystem path.\n *\n * Resolution rules:\n * - Absent or empty → undefined\n * - Relative/absolute local path → resolve(projectDir, definition)\n * - `ai-assets://<rest>` → walk up for ai-assets/, join with <rest>\n * - `agent:<name>` catalog refs → unresolved here (returns undefined; the\n * install pipeline materializes catalog agents into the workspace)\n *\n * Used by the runner to determine agentDir without requiring --agent-dir.\n * @docLink packages/core/workspace-config#resolve-agent-dir\n */\nexport function resolveAgentDir(projectDir: string): string | undefined {\n const config = resolveSkWorkspaceConfig(projectDir);\n const definition = config.agent?.definition;\n if (!definition) return undefined;\n\n // ai-assets:// URI\n if (definition.startsWith(\"ai-assets://\")) {\n const relPath = definition.slice(\"ai-assets://\".length);\n const aiAssetsDir = findAiAssetsDir(projectDir);\n if (!aiAssetsDir) return undefined;\n return join(aiAssetsDir, relPath);\n }\n\n // Catalog reference (`agent:<name>@<publisher>`) — not resolved by directory\n // scanning anymore; the install pipeline materializes catalog agents.\n if (definition.startsWith(\"agent:\")) {\n return undefined;\n }\n\n // Local path (relative or absolute)\n return resolve(projectDir, definition);\n}\n"]}