@skaile/workspaces 0.22.0-beta.1 → 0.22.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 (164) hide show
  1. package/CHANGELOG.md +380 -0
  2. package/dist/{asset-feeds-QXCSAJRN.js → asset-feeds-Y2CDCM3W.js} +13 -14
  3. package/dist/asset-feeds-Y2CDCM3W.js.map +1 -0
  4. package/dist/asset-manager/index.js +7 -7
  5. package/dist/asset-manager/installer.js +6 -6
  6. package/dist/asset-manager/src/index.d.ts.map +1 -1
  7. package/dist/base-assets/connectors/deploy.js +7 -7
  8. package/dist/base-assets/connectors/devserver.js +7 -7
  9. package/dist/base-assets/connectors/flow/adapter.js +7 -7
  10. package/dist/base-assets/connectors/flow/run-flow.js +8 -8
  11. package/dist/base-assets/connectors/flow.js +7 -7
  12. package/dist/base-assets/connectors/git/driver.d.ts.map +1 -1
  13. package/dist/base-assets/connectors/git.js +7 -7
  14. package/dist/base-assets/connectors/gmail.js +7 -7
  15. package/dist/base-assets/connectors/googledrive.js +7 -7
  16. package/dist/base-assets/connectors/local.js +7 -7
  17. package/dist/base-assets/connectors/mattermost.js +7 -7
  18. package/dist/base-assets/connectors/memory.js +7 -7
  19. package/dist/base-assets/connectors/minio.js +7 -7
  20. package/dist/base-assets/connectors/postgres.js +7 -7
  21. package/dist/base-assets/connectors/s3.js +7 -7
  22. package/dist/base-assets/connectors/sharepoint.js +7 -7
  23. package/dist/base-assets/connectors/sqlite.js +7 -7
  24. package/dist/base-assets/connectors/static-server.js +7 -7
  25. package/dist/base-assets/connectors/tunnel.js +7 -7
  26. package/dist/base-assets/connectors/webdav.js +7 -7
  27. package/dist/base-assets/connectors/xstate-store.js +7 -7
  28. package/dist/base-assets/connectors/xstate.js +7 -7
  29. package/dist/{chunk-PTIHB2TV.js → chunk-2RYQERIT.js} +4 -4
  30. package/dist/{chunk-PTIHB2TV.js.map → chunk-2RYQERIT.js.map} +1 -1
  31. package/dist/chunk-32NA4TVC.js +30 -0
  32. package/dist/chunk-32NA4TVC.js.map +1 -0
  33. package/dist/{chunk-DKGDOALM.js → chunk-53UNDY6K.js} +5 -5
  34. package/dist/{chunk-DKGDOALM.js.map → chunk-53UNDY6K.js.map} +1 -1
  35. package/dist/{chunk-VCYXVP2S.js → chunk-7HSXUKNB.js} +24 -13
  36. package/dist/chunk-7HSXUKNB.js.map +1 -0
  37. package/dist/chunk-7QBNJTTQ.js +3 -0
  38. package/dist/{chunk-W2O5LWYU.js.map → chunk-7QBNJTTQ.js.map} +1 -1
  39. package/dist/{chunk-UMOENHVH.js → chunk-ETMUGBHF.js} +3 -3
  40. package/dist/{chunk-UMOENHVH.js.map → chunk-ETMUGBHF.js.map} +1 -1
  41. package/dist/{chunk-7PTP3SQJ.js → chunk-GTS2FODO.js} +32 -7
  42. package/dist/chunk-GTS2FODO.js.map +1 -0
  43. package/dist/{chunk-D7K72XEY.js → chunk-JN2CUVSU.js} +3 -3
  44. package/dist/{chunk-D7K72XEY.js.map → chunk-JN2CUVSU.js.map} +1 -1
  45. package/dist/{chunk-3ECS5PFD.js → chunk-K2HDYSAM.js} +4 -4
  46. package/dist/{chunk-3ECS5PFD.js.map → chunk-K2HDYSAM.js.map} +1 -1
  47. package/dist/{chunk-4AZKT2BU.js → chunk-K7WPR77X.js} +33 -50
  48. package/dist/chunk-K7WPR77X.js.map +1 -0
  49. package/dist/{chunk-JHF66MCK.js → chunk-MNAHNDUI.js} +5 -3
  50. package/dist/chunk-MNAHNDUI.js.map +1 -0
  51. package/dist/{chunk-APAOQLPT.js → chunk-NBJ5TOEC.js} +3 -3
  52. package/dist/{chunk-APAOQLPT.js.map → chunk-NBJ5TOEC.js.map} +1 -1
  53. package/dist/{chunk-NJLHHZIW.js → chunk-NDD5VMN5.js} +2 -2
  54. package/dist/{chunk-NJLHHZIW.js.map → chunk-NDD5VMN5.js.map} +1 -1
  55. package/dist/{chunk-LT4DLEYE.js → chunk-OJN25VJO.js} +24 -8
  56. package/dist/chunk-OJN25VJO.js.map +1 -0
  57. package/dist/{chunk-GFNW72LW.js → chunk-PFOXL4SH.js} +4 -4
  58. package/dist/{chunk-GFNW72LW.js.map → chunk-PFOXL4SH.js.map} +1 -1
  59. package/dist/{chunk-V3QMSM5I.js → chunk-SKXCTV55.js} +13 -14
  60. package/dist/chunk-SKXCTV55.js.map +1 -0
  61. package/dist/{chunk-J3VKAEQP.js → chunk-V5TBKO5Q.js} +64 -14
  62. package/dist/chunk-V5TBKO5Q.js.map +1 -0
  63. package/dist/{chunk-I3UEM3FX.js → chunk-VUCPJBAG.js} +9 -4
  64. package/dist/chunk-VUCPJBAG.js.map +1 -0
  65. package/dist/{chunk-XIHFJVOD.js → chunk-WH2EB2SF.js} +3 -3
  66. package/dist/{chunk-XIHFJVOD.js.map → chunk-WH2EB2SF.js.map} +1 -1
  67. package/dist/{chunk-PBWMV5GM.js → chunk-WQ7DE5UC.js} +18 -4
  68. package/dist/chunk-WQ7DE5UC.js.map +1 -0
  69. package/dist/cli/index.js +199 -200
  70. package/dist/cli/index.js.map +1 -1
  71. package/dist/cli/src/commands/manage.d.ts +23 -32
  72. package/dist/cli/src/commands/manage.d.ts.map +1 -1
  73. package/dist/cli/src/commands/npx.d.ts +5 -3
  74. package/dist/cli/src/commands/npx.d.ts.map +1 -1
  75. package/dist/cli/src/commands/source.d.ts +7 -0
  76. package/dist/cli/src/commands/source.d.ts.map +1 -1
  77. package/dist/connectors/config.js +6 -6
  78. package/dist/connectors/index.js +7 -7
  79. package/dist/core/index.js +5 -5
  80. package/dist/core/manifest.js +2 -2
  81. package/dist/core/models.js +1 -1
  82. package/dist/core/runtime-assets.js +4 -4
  83. package/dist/core/src/index.d.ts +2 -2
  84. package/dist/core/src/index.d.ts.map +1 -1
  85. package/dist/core/src/manifest.d.ts +16 -0
  86. package/dist/core/src/manifest.d.ts.map +1 -1
  87. package/dist/core/src/models.d.ts +8 -2
  88. package/dist/core/src/models.d.ts.map +1 -1
  89. package/dist/core/src/repo-manager.d.ts +17 -2
  90. package/dist/core/src/repo-manager.d.ts.map +1 -1
  91. package/dist/core/src/walker.d.ts +4 -0
  92. package/dist/core/src/walker.d.ts.map +1 -1
  93. package/dist/core/src/workspace-config.d.ts +14 -0
  94. package/dist/core/src/workspace-config.d.ts.map +1 -1
  95. package/dist/core/workspace-config.js +3 -3
  96. package/dist/deploy/index.js +138 -42
  97. package/dist/deploy/index.js.map +1 -1
  98. package/dist/deploy/src/index.d.ts +4 -3
  99. package/dist/deploy/src/index.d.ts.map +1 -1
  100. package/dist/deploy/src/targets/container-runtime.d.ts.map +1 -1
  101. package/dist/deploy/src/targets/local.d.ts.map +1 -1
  102. package/dist/deploy/src/targets/nix.d.ts +36 -0
  103. package/dist/deploy/src/targets/nix.d.ts.map +1 -0
  104. package/dist/deploy/src/targets/process-handle.d.ts +34 -0
  105. package/dist/deploy/src/targets/process-handle.d.ts.map +1 -0
  106. package/dist/discovery/index.js +3 -3
  107. package/dist/{ensure-sources-SL2S4UEX.js → ensure-sources-REWWBH2K.js} +9 -9
  108. package/dist/{ensure-sources-SL2S4UEX.js.map → ensure-sources-REWWBH2K.js.map} +1 -1
  109. package/dist/library/index.js +4 -4
  110. package/dist/open-library-CT4VVESU.js +13 -0
  111. package/dist/{open-library-M4DB3D3J.js.map → open-library-CT4VVESU.js.map} +1 -1
  112. package/dist/plugin-registry/src/context.d.ts +30 -1
  113. package/dist/plugin-registry/src/context.d.ts.map +1 -1
  114. package/dist/plugin-registry/src/index.d.ts +1 -1
  115. package/dist/plugin-registry/src/index.d.ts.map +1 -1
  116. package/dist/{plugin-store-AJ3FGXIC.js → plugin-store-QS7TC5HY.js} +7 -7
  117. package/dist/{plugin-store-AJ3FGXIC.js.map → plugin-store-QS7TC5HY.js.map} +1 -1
  118. package/dist/plugins/src/catalog-source.d.ts +5 -0
  119. package/dist/plugins/src/catalog-source.d.ts.map +1 -1
  120. package/dist/runner/index.js +13 -12
  121. package/dist/runner/src/serve.d.ts +7 -0
  122. package/dist/runner/src/serve.d.ts.map +1 -1
  123. package/dist/sdk/asset-manager.js +7 -7
  124. package/dist/sdk/core.js +5 -5
  125. package/dist/sdk/index.js +13 -12
  126. package/dist/sdk/index.js.map +1 -1
  127. package/dist/sdk/runner.js +13 -12
  128. package/dist/sdk/transport/ws/client.js +2 -1
  129. package/dist/sdk/transport/ws/server.js +2 -1
  130. package/dist/sdk/transport/ws.js +4 -3
  131. package/dist/sdk/transport.js +4 -3
  132. package/dist/{setup-GBSQX7JF.js → setup-F6DGKL7J.js} +7 -7
  133. package/dist/{setup-GBSQX7JF.js.map → setup-F6DGKL7J.js.map} +1 -1
  134. package/dist/store-client-JP642EEI.js +14 -0
  135. package/dist/{store-client-5WBRUC5U.js.map → store-client-JP642EEI.js.map} +1 -1
  136. package/dist/transport/index.js +4 -3
  137. package/dist/transport/src/ws/auth.d.ts +34 -0
  138. package/dist/transport/src/ws/auth.d.ts.map +1 -0
  139. package/dist/transport/src/ws/client.d.ts +4 -0
  140. package/dist/transport/src/ws/client.d.ts.map +1 -1
  141. package/dist/transport/src/ws/index.d.ts +3 -2
  142. package/dist/transport/src/ws/index.d.ts.map +1 -1
  143. package/dist/transport/src/ws/server.d.ts +5 -0
  144. package/dist/transport/src/ws/server.d.ts.map +1 -1
  145. package/dist/transport/ws/client.js +2 -1
  146. package/dist/transport/ws/server.js +2 -1
  147. package/dist/transport/ws.js +4 -3
  148. package/dist/tui/index.js +13 -12
  149. package/dist/tui/index.js.map +1 -1
  150. package/dist/workspace-plugin/index.js +1 -1
  151. package/package.json +1 -1
  152. package/dist/asset-feeds-QXCSAJRN.js.map +0 -1
  153. package/dist/chunk-4AZKT2BU.js.map +0 -1
  154. package/dist/chunk-7PTP3SQJ.js.map +0 -1
  155. package/dist/chunk-I3UEM3FX.js.map +0 -1
  156. package/dist/chunk-J3VKAEQP.js.map +0 -1
  157. package/dist/chunk-JHF66MCK.js.map +0 -1
  158. package/dist/chunk-LT4DLEYE.js.map +0 -1
  159. package/dist/chunk-PBWMV5GM.js.map +0 -1
  160. package/dist/chunk-V3QMSM5I.js.map +0 -1
  161. package/dist/chunk-VCYXVP2S.js.map +0 -1
  162. package/dist/chunk-W2O5LWYU.js +0 -3
  163. package/dist/open-library-M4DB3D3J.js +0 -13
  164. package/dist/store-client-5WBRUC5U.js +0 -14
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../core/src/repo-manager.ts","../core/src/walker.ts","../core/src/workspace-config.ts"],"names":["readFileSync","join","existsSync","parseYaml","resolve","mkdirSync","writeFileSync","readdirSync","homedir","parsePath","parse","stringify"],"mappings":"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","file":"chunk-V5TBKO5Q.js","sourcesContent":["/**\n * Repository operations — clone, pull, scan, resolve, link.\n *\n * Remote repos are cloned to a shared global cache (~/.skaile/repos/<name>/).\n * Projects reference the cache via symlinks at .skaile/repos/<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 mkdirSync,\n readFileSync,\n rmSync,\n symlinkSync,\n lstatSync,\n writeFileSync,\n} from \"node:fs\";\nimport { resolve, join } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport { parse, stringify } from \"yaml\";\nimport semver from \"semver\";\nimport type { AssetRef, CatalogEntry } from \"./models.js\";\nimport { parseAssetRef } from \"./models.js\";\nimport type { OverrideEntry, SourceDeclaration, StoreEntry } from \"./workspace-config.js\";\nimport type { ProvenanceCandidate, ProvenanceIndex } from \"./walker.js\";\nimport { scanDirectory } from \"./manifest.js\";\n\n// ── Global cache ─────────────────────────────────────────────────────────────\n\n/**\n * Return the global shared repo cache directory (`~/.skaile/repos` by default).\n * Override with the `SKAILE_CACHE_DIR` environment variable.\n * @docLink packages/core/api-reference#get-global-cache-dir\n */\nexport function getGlobalCacheDir(): string {\n return process.env.SKAILE_CACHE_DIR ?? join(homedir(), \".skaile\", \"repos\");\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// ── 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/repos/`\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 repos directory (`.skaile/repos/`)\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 if (opts?.projectDir) {\n const links = readLinks(opts.projectDir);\n if (links[name]) {\n const linked = links[name];\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 // 2. Local path (or managed cache dir for a remote source)\n if (decl.path) {\n const projectDir = opts?.projectDir ?? resolve(reposDir, \"..\");\n const resolved = resolve(projectDir, decl.path);\n if (existsSync(resolved)) return resolved;\n // A bare local path must already exist; a url-backed managed cache dir is\n // ours to populate, so clone into it on first miss.\n if (!decl.url) {\n throw new Error(`Local repository path not found: ${decl.path} (resolved: ${resolved})`);\n }\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 // 3. Remote URL — clone to shared global cache\n if (decl.url) {\n const branch = decl.branch ?? \"main\";\n const globalCache = getGlobalCacheDir();\n const cacheDest = join(globalCache, name);\n\n // Clone or pull in global cache\n if (existsSync(join(cacheDest, \".git\"))) {\n if (!opts?.pin) pullRepo(cacheDest, branch);\n } else {\n if (!cloneRepo(decl.url, 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 // Create symlink in project-local .skaile/repos/ → global cache\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 return cacheDest;\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 return cacheDest;\n }\n\n throw new Error(`Repository \"${name}\" has neither url nor path`);\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 */\nexport function 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 * 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 * @param repoDir - Absolute path to the repository root\n * @param repoName - Repository name attached to each produced entry\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 entries = scanDirectory(repoDir, repoName);\n return repo ? entries.map((e) => ({ ...e, repo })) : entries;\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 repos directory (`.skaile/repos/`)\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\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\"))) return globalDest;\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\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.\n */\nfunction qualifyPublisher(ref: string, fallback: string): string {\n const hashIdx = ref.indexOf(\"#\");\n const head = hashIdx === -1 ? ref : ref.slice(0, hashIdx);\n if (head.includes(\"@\")) return ref;\n const pin = hashIdx === -1 ? \"\" : ref.slice(hashIdx);\n return `${head}@${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:name@<publisher>[#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: ProvenanceCandidate[] = [];\n if (opts.stores.length > 0 && opts.storeFetcher) {\n const candidateVersions = enumerateVersionsForPin(\n ref.pin,\n sourceCandidates.map((c) => c.version),\n );\n for (const store of opts.stores) {\n for (const v of candidateVersions) {\n if (!v) continue;\n const m = await opts.storeFetcher.getInstallManifest(\n store.url,\n `${ref.publisher}/${ref.kind}:${ref.name}@${v}`,\n );\n if (m) {\n storeCandidates.push({\n publisher: ref.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 }\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 const canonicalRef = `${ref.publisher}/${ref.kind}:${ref.name}@${best}`;\n\n // 5. Conflict detection.\n const uniqueShas = Array.from(new Set(finalists.map((c) => c.sha256)));\n let chosen: ProvenanceCandidate;\n if (uniqueShas.length > 1) {\n const override = overridesByRef.get(canonicalRef);\n if (!override) {\n throw new CanonicalRefConflictError(canonicalRef, finalists, [...depChain, refStr]);\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 chosen = pick;\n overridesApplied.add(canonicalRef);\n } else {\n // No conflict — deterministic pick by sourceUrl asc.\n chosen = [...finalists].sort((a, b) => a.sourceUrl.localeCompare(b.sourceUrl))[0]!;\n }\n\n // 6. Cheap cross-check when both source and store produced a candidate.\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 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 [...depChain, refStr],\n );\n }\n }\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/** 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\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 repos directory\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\n let dest = join(getGlobalCacheDir(), name);\n if (!existsSync(join(dest, \".git\"))) {\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 * Provenance-index walker.\n *\n * Given a list of cloned source paths plus their resolved commits, walk each\n * clone, read the publication-half `skaile.yaml` (or fall back to the\n * agentskills.io filename layout), compute per-file and composite sha256s, and\n * build a {@link ProvenanceIndex} keyed by `<publisher>/<kind>:<name>`.\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 { existsSync, readFileSync, statSync, readdirSync } from \"node:fs\";\nimport { createHash } from \"node:crypto\";\nimport { join, relative } from \"node:path\";\nimport { parse as parseYaml } from \"yaml\";\nimport fg from \"fast-glob\";\nimport { bundleDepRefs, parseFrontmatter } from \"./manifest.js\";\nimport type { AssetEntry } from \"./workspace-config.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 for bundles from the bundle manifest. `resolveAll` recurses into\n * these so a bundle pulls its members (and nested bundles). */\n deps?: 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\nfunction publisherFromGithubUrl(url: string): string | undefined {\n const m = url.match(/github\\.com[/:]([^/]+)\\/[^/]+/);\n return m?.[1];\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 yamlPath = join(clone.localPath, \"skaile.yaml\");\n if (existsSync(yamlPath)) {\n walkWithManifest(clone, yamlPath, index);\n } else {\n walkFilenameConvention(clone, index);\n }\n}\n\nfunction walkWithManifest(clone: SourceClone, yamlPath: string, index: ProvenanceIndex): void {\n const raw = (parseYaml(readFileSync(yamlPath, \"utf8\")) ?? {}) as Record<string, unknown>;\n const publisher =\n typeof raw.publisher === \"string\" && raw.publisher.length > 0\n ? raw.publisher\n : publisherFromGithubUrl(clone.sourceUrl);\n if (!publisher) {\n throw new Error(\n `${clone.sourceUrl}: publisher must be declared in skaile.yaml ` +\n \"(non-GitHub source URL — auto-derivation not available).\",\n );\n }\n const sourceVersion =\n (typeof raw.version === \"string\" ? raw.version : undefined) ??\n (clone.tag ? clone.tag.replace(/^v/, \"\") : undefined) ??\n syntheticVersion(clone.commit);\n\n const assets = Array.isArray(raw.assets) ? (raw.assets as AssetEntry[]) : [];\n if (assets.length === 0) {\n // skaile.yaml present but no assets[]: fall back to filename convention.\n walkFilenameConvention(clone, index, publisher, sourceVersion);\n return;\n }\n for (const a of assets) {\n const assetPublisher = a.publisher ?? publisher;\n const version = a.version ?? sourceVersion;\n const files = expandAssetFiles(clone.localPath, a);\n verifyNameMatch(clone.localPath, files, a.name, a.kind);\n const metadata = readMetadata(clone.localPath, files, a.kind);\n const candidate: ProvenanceCandidate = {\n publisher: assetPublisher,\n kind: a.kind,\n name: a.name,\n version,\n sourceUrl: clone.sourceUrl,\n commit: clone.commit,\n files,\n sha256: compositeSha256(files),\n metadata,\n deps: bundleDeps(clone.localPath, files, a.kind),\n };\n push(index, `${assetPublisher}/${a.kind}:${a.name}`, candidate);\n }\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 if (a.files) {\n const matches = fg.sync(a.files, { 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\nfunction walkFilenameConvention(\n clone: SourceClone,\n index: ProvenanceIndex,\n publisherOverride?: string,\n versionOverride?: string,\n): void {\n const publisher = publisherOverride ?? publisherFromGithubUrl(clone.sourceUrl);\n if (!publisher) {\n throw new Error(\n `${clone.sourceUrl}: publisher must be declared in skaile.yaml ` + \"(non-GitHub source URL).\",\n );\n }\n const version =\n versionOverride ??\n (clone.tag ? clone.tag.replace(/^v/, \"\") : undefined) ??\n syntheticVersion(clone.commit);\n\n for (const { dir, kind, mdName } of KIND_DIRS) {\n const base = join(clone.localPath, dir);\n if (!existsSync(base) || !statSync(base).isDirectory()) continue;\n for (const entry of readdirSync(base, { withFileTypes: true })) {\n if (!entry.isDirectory()) continue;\n const assetDir = join(base, entry.name);\n if (!existsSync(join(assetDir, mdName))) continue;\n const files: Array<{ path: string; sha256: string }> = [];\n walkDirRecursive(assetDir, clone.localPath, files);\n const metadata = readMetadata(clone.localPath, files, kind);\n const candidate: ProvenanceCandidate = {\n publisher,\n kind,\n name: entry.name,\n version,\n sourceUrl: clone.sourceUrl,\n commit: clone.commit,\n files,\n sha256: compositeSha256(files),\n metadata,\n deps: bundleDeps(clone.localPath, files, kind),\n };\n push(index, `${publisher}/${kind}:${entry.name}`, candidate);\n }\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 if (declared && declared !== expectedName) {\n throw new Error(\n `name mismatch: ${mdName} says \"${declared}\", skaile.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/** For a bundle, locate its manifest among `files` and read its transitive dep\n * refs. Returns undefined for non-bundles or when no bundle manifest is present. */\nfunction bundleDeps(\n repoRoot: string,\n files: Array<{ path: string; sha256: string }>,\n kind: string,\n): string[] | undefined {\n if (kind !== \"bundle\") return undefined;\n const bf = files.find((f) => f.path.endsWith(\".bundle.yaml\") || f.path.endsWith(\"BUNDLE.md\"));\n return bf ? bundleDepRefs(join(repoRoot, bf.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 * 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 { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join, parse as parsePath, resolve } from \"node:path\";\nimport { parse, stringify } from \"yaml\";\nimport { fromMcpServerMd } from \"./manifest.js\";\nimport { type CatalogEntry, parseAssetRef } from \"./models.js\";\nimport { getRepoCommit } 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\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 * `~/.skaile/sources/<slug>/` (machine-global clone cache) where the slug is\n * 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 a publication-half `assets:` list inside a source's\n * `skaile.yaml`. Either `root:` (recursive walk) or `files:` (explicit list,\n * supports globs) declares which paths constitute the asset. `version:`\n * overrides the source-level version.\n *\n * @docLink packages/core/workspace-config#asset-entry\n */\nexport interface AssetEntry {\n kind: string;\n name: string;\n root?: string;\n files?: string[];\n version?: string;\n /** Per-asset publisher override (e.g. for curator/mirror repos). */\n publisher?: 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 /** 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 /** 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 * 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}\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 * Publication-half: this repo IS a source. Defaults to GitHub URL org.\n *\n * YAML key: `publisher`\n */\n publisher?: string;\n\n /**\n * Publication-half: top-level version. See spec §Version semantics.\n *\n * YAML key: `version`\n */\n version?: string;\n\n /**\n * Publication-half: exhaustive list of publishable assets.\n *\n * YAML key: `assets`\n */\n assets?: AssetEntry[];\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 * 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 `@skaile/base-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 * 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 // publication half — scalars: overlay wins when defined; assets: by kind+name\n publisher: overlay.publisher ?? base.publisher,\n version: overlay.version ?? base.version,\n assets: dedupeByKey(\n [...(base.assets ?? []), ...(overlay.assets ?? [])],\n (a) => `${a.kind}:${a.name}`,\n ),\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: {\n definition: overlay.agent?.definition ?? base.agent?.definition,\n context: overlay.agent?.context ?? base.agent?.context,\n permissions: {\n ...base.agent?.permissions,\n ...stripUndefined(overlay.agent?.permissions),\n deny_write: dedupe([\n ...(base.agent?.permissions?.deny_write ?? []),\n ...(overlay.agent?.permissions?.deny_write ?? []),\n ]),\n deny_read: dedupe([\n ...(base.agent?.permissions?.deny_read ?? []),\n ...(overlay.agent?.permissions?.deny_read ?? []),\n ]),\n },\n subagents: {\n ...(base.agent?.subagents ?? {}),\n ...(overlay.agent?.subagents ?? {}),\n },\n hooks: {\n pre_flow: [\n ...(base.agent?.hooks?.pre_flow ?? []),\n ...(overlay.agent?.hooks?.pre_flow ?? []),\n ],\n post_flow: [\n ...(base.agent?.hooks?.post_flow ?? []),\n ...(overlay.agent?.hooks?.post_flow ?? []),\n ],\n pre_node: [\n ...(base.agent?.hooks?.pre_node ?? []),\n ...(overlay.agent?.hooks?.pre_node ?? []),\n ],\n post_node: [\n ...(base.agent?.hooks?.post_node ?? []),\n ...(overlay.agent?.hooks?.post_node ?? []),\n ],\n },\n },\n\n workspace: {\n directories: dedupe([\n ...(base.workspace?.directories ?? []),\n ...(overlay.workspace?.directories ?? []),\n ]),\n git: {\n init: overlay.workspace?.git?.init ?? base.workspace?.git?.init,\n ignore: dedupe([\n ...(base.workspace?.git?.ignore ?? []),\n ...(overlay.workspace?.git?.ignore ?? []),\n ]),\n },\n setup: overlay.workspace?.setup ?? base.workspace?.setup,\n container: overlay.workspace?.container ?? base.workspace?.container,\n },\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 // 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// ── 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// ── 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/** 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 // 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 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(\n agentConfigRaw as Record<string, unknown>,\n );\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 if (Array.isArray(raw.startup)) {\n config.startup = raw.startup as StartupDirective[];\n }\n\n // Legacy-key hard cut. `repositories:` and `ai_resources:` (any case) were\n // removed with the canonical-identity schema. Throw with the spec wording —\n // the migration is done by the `migrate-skaile-manifest` skill, not code.\n if (raw.repositories !== undefined) {\n throw new Error(\n \"skaile.yaml: unknown top-level key `repositories:`. The schema changed in \" +\n \"@skaile/workspaces 4.x — see docs/concepts/manifest-schema.md, or ask \" +\n \"your AI assistant to apply 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 in \" +\n \"@skaile/workspaces 4.x — see docs/concepts/manifest-schema.md, or ask \" +\n \"your AI assistant to apply the `migrate-skaile-manifest` skill.\",\n );\n }\n\n // Publication half: publisher / version / assets[].\n if (typeof raw.publisher === \"string\" && raw.publisher.length > 0) {\n config.publisher = raw.publisher;\n }\n if (typeof raw.version === \"string\" && raw.version.length > 0) {\n config.version = raw.version;\n }\n if (Array.isArray(raw.assets)) {\n const entries: AssetEntry[] = [];\n for (const item of raw.assets) {\n if (!item || typeof item !== \"object\" || Array.isArray(item)) continue;\n const a = item as Record<string, unknown>;\n const kind = typeof a.kind === \"string\" ? a.kind : \"\";\n const name = typeof a.name === \"string\" ? a.name : \"\";\n if (!kind || !name) continue;\n const entry: AssetEntry = { kind, name };\n if (typeof a.root === \"string\") entry.root = a.root;\n if (Array.isArray(a.files)) {\n entry.files = (a.files as unknown[]).filter((f): f is string => typeof f === \"string\");\n }\n if (typeof a.version === \"string\") entry.version = a.version;\n if (typeof a.publisher === \"string\") entry.publisher = a.publisher;\n entries.push(entry);\n }\n if (entries.length > 0) config.assets = entries;\n }\n\n // Consumption half: stores[] and overrides[].\n if (Array.isArray(raw.stores)) {\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 if (Array.isArray(raw.overrides)) {\n const entries: OverrideEntry[] = [];\n for (const item of raw.overrides) {\n if (!item || typeof item !== \"object\" || Array.isArray(item)) continue;\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) continue;\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 entries.push({ ref, source, reason: o.reason });\n }\n if (entries.length > 0) config.overrides = entries;\n }\n\n // Structural validation deferred — these sections are accepted as raw\n // arrays/objects and cast; the runtime tolerates unexpected shapes.\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 config.mcp_servers = raw.mcp_servers as McpServerDeclaration[];\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 if (Array.isArray(raw.dependencies)) {\n config.dependencies = raw.dependencies.filter((d): d is string => typeof d === \"string\");\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 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 \"publisher\",\n \"version\",\n \"assets\",\n \"agent_config\",\n \"dependencies\",\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) decl.transport = String(m.transport) as \"stdio\" | \"sse\" | \"http\";\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 r = m.recipe as Record<string, unknown>;\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\n if (effectiveAttr !== undefined) {\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 decl.recipe = { attr: effectiveAttr, flake: r.flake as string };\n if (typeof r.publisher === \"string\") decl.recipe.publisher = r.publisher;\n } else {\n decl.recipe = { attr: effectiveAttr };\n }\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 \"${entry.name}\": ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\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 * 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 fromMcpServerMd} 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 */\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 mdPath = join(subDir, \"MCP.md\");\n if (!existsSync(mdPath)) continue;\n\n try {\n const entry = fromMcpServerMd(mdPath, name);\n const decl = mcpDeclFromCatalogEntry(entry);\n if (!decl) continue;\n\n decl.id = entry.name || name;\n\n const instancePath = join(subDir, \".instance.json\");\n if (existsSync(instancePath)) {\n // A malformed transient .instance.json must not nuke a valid MCP server:\n // catch parse errors here so the decl survives with its MCP.md env.\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] loadMaterializedMcpDeclarations: ignoring malformed \".instance.json\" for \"${name}\": ${\n err instanceof Error ? err.message : String(err)\n }`,\n );\n }\n }\n\n result.push(decl);\n } catch (err) {\n // Never include secret values in the warning — only the failing path + message.\n console.warn(\n `[workspace-config] loadMaterializedMcpDeclarations: failed to load \"${mdPath}\": ${\n err instanceof Error ? err.message : String(err)\n }`,\n );\n }\n }\n\n return result;\n}\n\n/**\n * Derive a cache slug from a source git URL (`<host>/<owner>/<repo>` → `<repo>`).\n * Mirrors the CLI's `deriveSlug`; kept local to avoid a CLI import cycle.\n */\nfunction sourceSlug(url: string): string {\n return (\n url\n .replace(/\\.git$/, \"\")\n .split(/[/:]/)\n .pop() ?? \"source\"\n );\n}\n\n/**\n * Resolve each `sources[]` entry to an on-disk clone path under the machine\n * cache (`~/.skaile/sources/<slug>/`) and its resolved HEAD commit. Entries\n * with no on-disk clone are skipped — the install pipeline clones them first.\n */\nfunction buildSourceClones(sources: SourceEntry[]): SourceClone[] {\n const home = process.env.SKAILE_HOME ?? join(homedir(), \".skaile\");\n const sourcesDir = join(home, \"sources\");\n const clones: SourceClone[] = [];\n for (const s of sources) {\n const localPath = join(sourcesDir, sourceSlug(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 return {\n name: c.name,\n kind: c.kind as CatalogEntry[\"kind\"],\n 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: [],\n metadata: c.metadata,\n };\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 */\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 // Collect mcp-server dep refs from top-level dependencies only.\n // (ai_resources[].dependencies is no longer a thing.)\n const mcpRefStrings: string[] = [];\n for (const dep of config.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\n // Build the provenance index from cloned sources for catalog-default lookup.\n const sources = config.sources ?? [];\n const provenanceIndex =\n sources.length > 0\n ? buildProvenanceIndex(buildSourceClones(sources), { projectDir })\n : (new Map() as ProvenanceIndex);\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 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 // Prefer the publisher-keyed candidate; fall back to any matching name.\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 const candidate = candidates?.[0];\n if (!candidate) continue;\n\n const catalogDecl = mcpDeclFromCatalogEntry(catalogEntryFromCandidate(candidate));\n if (!catalogDecl) continue;\n\n upsert(catalogDecl);\n }\n\n // Source 2: materialized assets — overlay onto matching catalog base.\n for (const decl of materialized) {\n upsert(decl);\n }\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"]}
@@ -43,7 +43,10 @@ function entryFromRaw(d) {
43
43
  description: String(d.description ?? ""),
44
44
  source: String(d.source ?? ""),
45
45
  publisher: d.publisher != null ? String(d.publisher) : void 0,
46
- domain: d.domain != null ? String(d.domain) : void 0,
46
+ // Read `repo`, falling back to the legacy `domain` key so a stale
47
+ // catalog.yaml cache written before this release still groups sanely.
48
+ // The cache self-heals on next write (entryToRaw stops writing `domain`).
49
+ repo: d.repo != null ? String(d.repo) : d.domain != null ? String(d.domain) : void 0,
47
50
  version: String(d.version ?? ""),
48
51
  requires: Array.isArray(d.requires) ? d.requires.filter(Boolean).map(parseDep) : [],
49
52
  dependencies: deps
@@ -51,6 +54,7 @@ function entryFromRaw(d) {
51
54
  if (d.metadata != null && typeof d.metadata === "object" && !Array.isArray(d.metadata)) {
52
55
  entry.metadata = d.metadata;
53
56
  }
57
+ if (d.category != null) entry.category = String(d.category);
54
58
  return entry;
55
59
  }
56
60
  function entryToRaw(e) {
@@ -60,12 +64,13 @@ function entryToRaw(e) {
60
64
  description: e.description,
61
65
  source: e.source,
62
66
  publisher: e.publisher,
63
- domain: e.domain,
67
+ repo: e.repo,
64
68
  version: e.version,
65
69
  requires: e.requires.map(depToStr),
66
70
  dependencies: e.dependencies
67
71
  };
68
72
  if (e.metadata) raw.metadata = e.metadata;
73
+ if (e.category != null) raw.category = e.category;
69
74
  return raw;
70
75
  }
71
76
  var PUBLISHER_RE = /^[A-Za-z0-9](?:[A-Za-z0-9]|-(?!-)){0,37}[A-Za-z0-9]$|^[A-Za-z0-9]$/;
@@ -147,5 +152,5 @@ function repositoryToRaw(r) {
147
152
  }
148
153
 
149
154
  export { ASSET_KINDS, INDIVIDUAL_KINDS, assetRefToDep, assetRefToStr, depToStr, entryFromRaw, entryToRaw, parseAssetRef, parseDep, repositoryFromRaw, repositoryToRaw };
150
- //# sourceMappingURL=chunk-I3UEM3FX.js.map
151
- //# sourceMappingURL=chunk-I3UEM3FX.js.map
155
+ //# sourceMappingURL=chunk-VUCPJBAG.js.map
156
+ //# sourceMappingURL=chunk-VUCPJBAG.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../core/src/models.ts"],"names":[],"mappings":"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","file":"chunk-VUCPJBAG.js","sourcesContent":["/**\n * Pure data models — no I/O, no side effects.\n */\n\nimport semver from \"semver\";\n\n/**\n * Discriminator for catalog entries and asset references.\n * Used in asset ref strings (e.g. `'skill:my-skill'`, `'agent:my-agent'`).\n * @docLink packages/core/concepts#asset-kind\n */\nexport type AssetKind =\n | \"skill\"\n | \"agent\"\n | \"prompt\"\n | \"bundle\"\n | \"flow\"\n | \"contract\"\n | \"mcp-server\"\n | \"persona\" // identity fragment — replaces SOUL.md in composition\n | \"ruleset\" // behavioral constraints — replaces RULES.md in composition\n | \"knowledge\" // knowledge bundle directory\n | \"connector\"; // connector descriptor (CONNECTOR.md)\n\n/**\n * All valid AssetKind values as a readonly array.\n * @docLink packages/core/concepts#asset-kinds\n */\nexport const ASSET_KINDS: readonly AssetKind[] = [\n \"skill\",\n \"agent\",\n \"prompt\",\n \"bundle\",\n \"flow\",\n \"contract\",\n \"mcp-server\",\n \"persona\",\n \"ruleset\",\n \"knowledge\",\n \"connector\",\n];\n/**\n * Asset kinds that represent individually installable assets (excludes \"bundle\").\n * Note: persona, ruleset, and knowledge are valid AssetKind values but are not\n * individually installable — they are resolved at session creation time via the\n * mixin-resolver, not through the install/deploy pipeline.\n * @docLink packages/core/concepts#individual-kinds\n */\nexport const INDIVIDUAL_KINDS = [\n \"skill\",\n \"agent\",\n \"prompt\",\n \"flow\",\n \"contract\",\n \"mcp-server\",\n] as const satisfies AssetKind[];\n\n// ── Dependency ────────────────────────────────────────────────────────────────\n\n/**\n * Declared dependency on another catalog asset.\n * @docLink packages/core/concepts#dependency\n */\nexport interface Dependency {\n /** Asset kind (e.g. \"skill\", \"agent\", \"contract\"). */\n kind: string;\n /** Asset name within that kind. */\n name: string;\n /** Canonical publisher namespace (when known). */\n publisher?: string;\n}\n\n/**\n * Parse a `\"kind:name\"` dependency string, or a bare `\"name\"` (defaults kind to `\"skill\"`).\n *\n * @param s - Dependency string, e.g. `\"skill:use-exa\"` or `\"use-exa\"`\n * @returns Parsed `{ kind, name }` dependency object\n * @docLink packages/core/concepts#parse-dep\n */\nexport function parseDep(s: string): Dependency {\n const i = s.indexOf(\":\");\n if (i !== -1) {\n const kind = s.slice(0, i).trim();\n const name = s.slice(i + 1).trim();\n return { kind, name };\n }\n return { kind: \"skill\", name: s.trim() };\n}\n\n/**\n * Serialize a Dependency back to its `\"kind:name\"` string form.\n *\n * @param d - Dependency to serialize\n * @returns String in `\"kind:name\"` format\n * @docLink packages/core/concepts#dep-to-str\n */\nexport function depToStr(d: Dependency): string {\n return `${d.kind}:${d.name}`;\n}\n\n// ── CatalogEntry ──────────────────────────────────────────────────────────────\n\n/**\n * A resolved catalog entry describing an installable asset.\n * Produced by manifest parsers and stored in the catalog YAML.\n * @docLink packages/core/concepts#catalog-entry\n */\nexport interface CatalogEntry {\n /** Unique asset name within its kind. */\n name: string;\n /** Asset kind discriminator. */\n kind: AssetKind;\n /** Short description of what this asset does. */\n description: string;\n /** Absolute path to manifest file */\n source: string;\n /** Canonical publisher namespace this asset belongs to (formerly `repository`). */\n publisher?: string;\n /**\n * `\"<org>/<repo>\"` coordinate the asset came from. Absent → the asset groups\n * directly under its publisher (local library with no git remote, or a\n * non-GitHub source). Replaces the former derived `domain` axis.\n */\n repo?: string;\n /** Semantic version string (may be empty if not declared in the manifest). */\n version: string;\n /** Skills, agents, or other assets this entry depends on. */\n requires: Dependency[];\n /** Bundle dependencies — asset refs to install (bundles only). */\n dependencies: string[];\n /**\n * Kind-specific metadata extracted from the manifest frontmatter.\n * Used by MCP servers to carry default config (transport, command, args, env, url, headers)\n * so that `mcp:name` dependency refs resolve to a runnable declaration without\n * requiring verbose inline config in `skaile.yaml`.\n */\n metadata?: Record<string, unknown>;\n /** Curated facet, surfaced as a badge in the manage TUI (not a tree axis). */\n category?: string;\n}\n\n/**\n * Construct a CatalogEntry from a raw deserialized record (e.g. from catalog.yaml).\n *\n * @param d - Raw object with loosely typed fields\n * @returns Normalized CatalogEntry\n * @docLink packages/core/concepts#entry-from-raw\n */\nexport function entryFromRaw(d: Record<string, unknown>): CatalogEntry {\n const rawDeps = d.dependencies;\n const deps = Array.isArray(rawDeps) ? (rawDeps as string[]).filter(Boolean) : [];\n const entry: CatalogEntry = {\n name: String(d.name ?? \"\"),\n kind: String(d.kind ?? \"skill\") as AssetKind,\n description: String(d.description ?? \"\"),\n source: String(d.source ?? \"\"),\n publisher: d.publisher != null ? String(d.publisher) : undefined,\n // Read `repo`, falling back to the legacy `domain` key so a stale\n // catalog.yaml cache written before this release still groups sanely.\n // The cache self-heals on next write (entryToRaw stops writing `domain`).\n repo: d.repo != null ? String(d.repo) : d.domain != null ? String(d.domain) : undefined,\n version: String(d.version ?? \"\"),\n requires: Array.isArray(d.requires)\n ? (d.requires as string[]).filter(Boolean).map(parseDep)\n : [],\n dependencies: deps,\n };\n if (d.metadata != null && typeof d.metadata === \"object\" && !Array.isArray(d.metadata)) {\n entry.metadata = d.metadata as Record<string, unknown>;\n }\n if (d.category != null) entry.category = String(d.category);\n return entry;\n}\n\n/**\n * Serialize a CatalogEntry to a plain record suitable for YAML/JSON persistence.\n *\n * @param e - CatalogEntry to serialize\n * @returns Plain object with string-serialized requires and dependencies\n * @docLink packages/core/concepts#entry-to-raw\n */\nexport function entryToRaw(e: CatalogEntry): Record<string, unknown> {\n const raw: Record<string, unknown> = {\n name: e.name,\n kind: e.kind,\n description: e.description,\n source: e.source,\n publisher: e.publisher,\n repo: e.repo,\n version: e.version,\n requires: e.requires.map(depToStr),\n dependencies: e.dependencies,\n };\n if (e.metadata) raw.metadata = e.metadata;\n if (e.category != null) raw.category = e.category;\n return raw;\n}\n\n// ── AssetRef ─────────────────────────────────────────────────────────────────\n\n/**\n * A parsed asset reference: `kind:name@<publisher>[#pin]`.\n *\n * `publisher` is the canonical, GitHub-shaped publisher namespace (≤39 chars,\n * alphanumeric+hyphen). `pin` is a SemVer constraint, exact SHA, or absent.\n * Floating refs (`main`, `latest`, `HEAD`) are rejected at parse time.\n *\n * Produced by `parseAssetRef`; consumed by `resolveAsset` and `resolveAll`.\n * @docLink packages/core/concepts#asset-ref\n */\nexport interface AssetRef {\n kind: string;\n name: string;\n /** Canonical publisher namespace. Optional only for ambiguity-resolution\n * during migration; new manifests require it. */\n publisher?: string;\n /** SemVer constraint (^1.4.0, ~1.4, 1.x, exact 1.4.0), 40-char SHA, or undefined. */\n pin?: string;\n}\n\n// GitHub-shaped: 1-39 chars, alphanumeric + single hyphens, no leading/trailing\n// hyphen, no double hyphens.\nconst PUBLISHER_RE = /^[A-Za-z0-9](?:[A-Za-z0-9]|-(?!-)){0,37}[A-Za-z0-9]$|^[A-Za-z0-9]$/;\nconst SHA_RE = /^[0-9a-f]{40}$/i;\n\n/** True when `pin` is a SemVer constraint, exact SemVer, or 40-char SHA. */\nfunction isValidPin(pin: string): boolean {\n if (SHA_RE.test(pin)) return true;\n if (semver.valid(pin)) return true;\n if (semver.validRange(pin)) return true;\n return false;\n}\n\n/**\n * Parse a canonical asset reference string into an `AssetRef` object.\n *\n * Grammar: `kind:name@<publisher>[#pin]`\n * \"skill:audit@skaile-ai\" → { kind: \"skill\", name: \"audit\", publisher: \"skaile-ai\" }\n * \"skill:audit@skaile-ai#^1.4.0\" → { …, pin: \"^1.4.0\" }\n * \"skill:audit@skaile-ai#<40-sha>\" → { …, pin: \"<40-sha>\" }\n *\n * `<publisher>` is required and GitHub-shaped (≤39 chars, alphanumeric+hyphen,\n * no leading/trailing or double hyphen). `pin` accepts a SemVer constraint\n * (`^`, `~`, `x`, exact), a 40-char SHA, or is absent. Floating refs\n * (`main`/`latest`/`HEAD`/anything non-canonical) are parse-time errors.\n *\n * The shorthand `mcp:` is normalized to `mcp-server:`.\n *\n * @param s - Asset reference string\n * @returns Parsed `AssetRef`\n * @throws When the publisher is missing/malformed or the pin is a floating ref.\n * @docLink packages/core/concepts#parse-asset-ref\n */\nexport function parseAssetRef(s: string): AssetRef {\n let rest = s.trim();\n let kind = \"skill\";\n\n const colonIdx = rest.indexOf(\":\");\n if (colonIdx !== -1) {\n kind = rest.slice(0, colonIdx).trim();\n rest = rest.slice(colonIdx + 1).trim();\n }\n if (kind === \"mcp\") kind = \"mcp-server\";\n\n let pin: string | undefined;\n const hashIdx = rest.indexOf(\"#\");\n if (hashIdx !== -1) {\n pin = rest.slice(hashIdx + 1).trim() || undefined;\n rest = rest.slice(0, hashIdx).trim();\n }\n\n let publisher: string | undefined;\n const atIdx = rest.indexOf(\"@\");\n if (atIdx !== -1) {\n publisher = rest.slice(atIdx + 1).trim();\n rest = rest.slice(0, atIdx).trim();\n if (publisher.length === 0) {\n throw new Error(`empty publisher in asset ref: \"${s}\"`);\n }\n if (!PUBLISHER_RE.test(publisher)) {\n if (publisher.length > 39) {\n throw new Error(`publisher length exceeds 39 chars: \"${publisher}\"`);\n }\n throw new Error(`publisher is not GitHub-shaped: \"${publisher}\"`);\n }\n } else {\n throw new Error(\n `publisher required in asset ref \"${s}\" — use \\`kind:name@<publisher>\\`. ` +\n \"Run the `migrate-skaile-manifest` skill on legacy manifests.\",\n );\n }\n\n if (pin !== undefined && !isValidPin(pin)) {\n throw new Error(\n `non-canonical pin \"${pin}\" in \"${s}\" — pin must be a SemVer ` +\n \"constraint (1.4.0, ^1.4, ~1.4, 1.x), a 40-char SHA, or absent. \" +\n \"Floating refs (main/latest/HEAD) are not allowed.\",\n );\n }\n\n return { kind, name: rest, publisher, pin };\n}\n\n/**\n * Serialize an AssetRef back to its canonical string form.\n *\n * @param ref - AssetRef to serialize\n * @returns String in `\"kind:name[@repository][#pin]\"` format\n * @docLink packages/core/concepts#asset-ref-to-str\n */\nexport function assetRefToStr(ref: AssetRef): string {\n let s = `${ref.kind}:${ref.name}`;\n if (ref.publisher) s += `@${ref.publisher}`;\n if (ref.pin) s += `#${ref.pin}`;\n return s;\n}\n\n/**\n * Convert an AssetRef to a simple Dependency, dropping the repository and pin qualifiers.\n *\n * @param ref - Full asset reference (may include repository and pin)\n * @returns Dependency with only kind and name\n * @docLink packages/core/concepts#asset-ref-to-dep\n */\nexport function assetRefToDep(ref: AssetRef): Dependency {\n return { kind: ref.kind, name: ref.name };\n}\n\n// ── Lock File ────────────────────────────────────────────────────────────────\n\n/** A path/sha256 pair recorded for one file inside a locked asset. */\nexport interface LockFileEntry {\n path: string;\n sha256: string;\n}\n\n/**\n * Per-asset entry in the lock file (v2 schema).\n * Keyed in `LockFile.assets` by canonical ref (`<publisher>/<kind>:<name>@<version>`).\n * @docLink packages/core/api-reference#lock-entry\n */\nexport interface LockEntry {\n /** Composite sha256 over sorted `<path>:<sha256>\\n` rows. */\n sha256: string;\n /** Resolved upstream source + commit. */\n source: { url: string; commit: string };\n /** Files that constitute the asset. */\n files: LockFileEntry[];\n /** True when an `overrides[]` entry pinned this resolution. */\n override_applied: boolean;\n}\n\n/** Per-source-URL entry in `LockFile.sources`. */\nexport interface LockSourceEntry {\n url: string;\n commit: string;\n}\n\n/**\n * Full skaile.lock.yaml structure (v2 schema).\n * @docLink packages/core/api-reference#lock-file\n */\nexport interface LockFile {\n /** Lock file schema version. v2 is canonical. */\n schema_version: 2;\n /** ISO timestamp of when the lock was generated. */\n locked_at: string;\n /** Resolved assets keyed by canonical ref `<publisher>/<kind>:<name>@<version>`. */\n assets: Record<string, LockEntry>;\n /** Every source URL that contributed at least one resolved asset. */\n sources: LockSourceEntry[];\n /**\n * Resolved plugin packages (from `skaile.yaml` `plugins:`), keyed by package\n * name. The plugin-store reconciler reads this slice into its reconcile-hash\n * so a lock change reinstalls even when the manifest list is unchanged.\n */\n plugins?: Record<string, LockPluginEntry>;\n}\n\n/** One pinned plugin package in the lock file's `plugins` slice. */\nexport interface LockPluginEntry {\n /** Resolved exact version (e.g. \"0.1.3\"). */\n version: string;\n /** Package integrity hash (e.g. \"sha512-...\"); may be empty until populated from bun's output. */\n integrity: string;\n}\n\n// ── AgentManifest ────────────────────────────────────────────────────────────\n\n/**\n * Agent package manifest — parsed from `agent.yaml` in an agent directory.\n * Defines the agent's identity, model preferences, capability requirements, and composition mixins.\n * @docLink packages/core/concepts#agent-manifest\n */\nexport interface AgentManifest {\n spec_version?: string;\n name?: string;\n version?: string;\n description?: string;\n model?: {\n preferred?: string;\n fallback?: string[];\n constraints?: { temperature?: number; max_tokens?: number };\n };\n tools?: {\n allowed?: string[];\n denied?: string[];\n };\n delegation?: { mode?: string };\n requires?: Array<{ name: string; source: string; version?: string; mount: string }>;\n tags?: string[];\n author?: string;\n metadata?: Record<string, unknown>;\n /**\n * @deprecated Use `persona`, `rules`, and `knowledge` mixin arrays instead.\n * This field is declared but was never resolved at runtime.\n */\n extends?: string;\n abilities?: string[];\n /**\n * Identity fragments to compose into the agent persona.\n * Each entry is a catalog ref (`persona:name@repo#pin`), a bare name\n * (defaults to kind \"persona\"), or a local path (`./my.persona.md`).\n * Resolved in order — concatenated with \\n\\n---\\n\\n separator.\n */\n persona?: string[];\n /**\n * Behavioral rule sets to compose into the agent's constraints.\n * Each entry is a catalog ref (`ruleset:name@repo#pin`), bare name,\n * or local path. All rules apply (union).\n */\n rules?: string[];\n /**\n * Knowledge bundles to compose into the agent's domain knowledge.\n * Each entry is a catalog ref (`knowledge:name@repo#pin`), bare name,\n * or local path to a knowledge directory. Loaded in declaration order.\n */\n knowledge?: string[];\n contracts?: string[];\n /**\n * v2 composition items. Each entry references an asset (skill, connector,\n * soul, ruleset, etc.) with binding semantics (discoverable, inline-live,\n * inline-snapshot). Resolved at session start via the composition module.\n */\n composes?: Array<{\n kind: string;\n ref: string;\n instance?: string;\n binding?: \"discoverable\" | \"inline-live\" | \"inline-snapshot\";\n }>;\n runtime?: {\n max_turns?: number;\n timeout?: number;\n [key: string]: unknown;\n };\n}\n\n// ── Repository ───────────────────────────────────────────────────────────────\n\ntype RepositoryKind = \"local\" | \"github\";\n\n/**\n * A registered asset repository (local path or cloned GitHub repo).\n * Stored in the catalog; consumed by `repo-manager` for cloning and scanning.\n * @docLink packages/core/concepts#repository\n */\nexport interface Repository {\n /** Logical repository name. */\n name: string;\n /** Storage kind: \"local\" for paths, \"github\" for remote URLs. */\n kind: RepositoryKind;\n /** Absolute path (local) or remote URL (github). */\n path: string;\n /** Active branch. */\n branch: string;\n /** Upstream fork URL (for fork-based workflows). */\n upstream?: string;\n}\n\n/**\n * Construct a `Repository` from a raw deserialized record.\n *\n * @param d - Raw object from YAML/JSON\n * @returns Normalized `Repository`\n * @docLink packages/core/concepts#repository-from-raw\n */\nexport function repositoryFromRaw(d: Record<string, unknown>): Repository {\n return {\n name: String(d.name ?? \"\"),\n kind: String(d.kind ?? \"local\") as RepositoryKind,\n path: String(d.path ?? \"\"),\n branch: String(d.branch ?? \"main\"),\n upstream: d.upstream != null ? String(d.upstream) : undefined,\n };\n}\n\n/**\n * Serialize a `Repository` to a plain record for YAML/JSON persistence.\n * Omits the `branch` field when it equals `\"main\"` to keep serialized output clean.\n *\n * @param r - Repository to serialize\n * @returns Plain object suitable for YAML/JSON\n * @docLink packages/core/concepts#repository-to-raw\n */\nexport function repositoryToRaw(r: Repository): Record<string, unknown> {\n const d: Record<string, unknown> = {\n name: r.name,\n kind: r.kind,\n path: r.path,\n };\n if (r.branch !== \"main\") d.branch = r.branch;\n if (r.upstream != null) d.upstream = r.upstream;\n return d;\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { globalSettingsPath, mapLegacyFields } from './chunk-UMOENHVH.js';
1
+ import { globalSettingsPath, mapLegacyFields } from './chunk-ETMUGBHF.js';
2
2
  import { existsSync, readFileSync, mkdirSync, writeFileSync } from 'fs';
3
3
  import { homedir } from 'os';
4
4
  import { join } from 'path';
@@ -89,5 +89,5 @@ function isStoreAuthenticated(config) {
89
89
  }
90
90
 
91
91
  export { clearStoreTokens, getStoreConfig, isStoreAuthenticated, saveStoreTokens, storeFetch };
92
- //# sourceMappingURL=chunk-XIHFJVOD.js.map
93
- //# sourceMappingURL=chunk-XIHFJVOD.js.map
92
+ //# sourceMappingURL=chunk-WH2EB2SF.js.map
93
+ //# sourceMappingURL=chunk-WH2EB2SF.js.map