@skaile/workspaces 0.22.0-beta.2 → 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.
- package/CHANGELOG.md +295 -0
- package/dist/{asset-feeds-2M6UKEJ7.js → asset-feeds-Y2CDCM3W.js} +8 -8
- package/dist/{asset-feeds-2M6UKEJ7.js.map → asset-feeds-Y2CDCM3W.js.map} +1 -1
- package/dist/asset-manager/index.js +6 -6
- package/dist/asset-manager/installer.js +5 -5
- package/dist/base-assets/connectors/deploy.js +6 -6
- package/dist/base-assets/connectors/devserver.js +6 -6
- package/dist/base-assets/connectors/flow/adapter.js +6 -6
- package/dist/base-assets/connectors/flow/run-flow.js +7 -7
- package/dist/base-assets/connectors/flow.js +6 -6
- package/dist/base-assets/connectors/git.js +6 -6
- package/dist/base-assets/connectors/gmail.js +6 -6
- package/dist/base-assets/connectors/googledrive.js +6 -6
- package/dist/base-assets/connectors/local.js +6 -6
- package/dist/base-assets/connectors/mattermost.js +6 -6
- package/dist/base-assets/connectors/memory.js +6 -6
- package/dist/base-assets/connectors/minio.js +6 -6
- package/dist/base-assets/connectors/postgres.js +6 -6
- package/dist/base-assets/connectors/s3.js +6 -6
- package/dist/base-assets/connectors/sharepoint.js +6 -6
- package/dist/base-assets/connectors/sqlite.js +6 -6
- package/dist/base-assets/connectors/static-server.js +6 -6
- package/dist/base-assets/connectors/tunnel.js +6 -6
- package/dist/base-assets/connectors/webdav.js +6 -6
- package/dist/base-assets/connectors/xstate-store.js +6 -6
- package/dist/base-assets/connectors/xstate.js +6 -6
- package/dist/{chunk-LDLZFYLR.js → chunk-2RYQERIT.js} +4 -4
- package/dist/{chunk-LDLZFYLR.js.map → chunk-2RYQERIT.js.map} +1 -1
- package/dist/{chunk-3KLWGHDE.js → chunk-53UNDY6K.js} +5 -5
- package/dist/{chunk-3KLWGHDE.js.map → chunk-53UNDY6K.js.map} +1 -1
- package/dist/{chunk-TWQPDBHB.js → chunk-7HSXUKNB.js} +6 -6
- package/dist/{chunk-TWQPDBHB.js.map → chunk-7HSXUKNB.js.map} +1 -1
- package/dist/{chunk-P4FYHEHW.js → chunk-ETMUGBHF.js} +3 -3
- package/dist/{chunk-P4FYHEHW.js.map → chunk-ETMUGBHF.js.map} +1 -1
- package/dist/{chunk-CEUHU3C4.js → chunk-JN2CUVSU.js} +3 -3
- package/dist/{chunk-CEUHU3C4.js.map → chunk-JN2CUVSU.js.map} +1 -1
- package/dist/{chunk-UBLTUFFI.js → chunk-K2HDYSAM.js} +4 -4
- package/dist/{chunk-UBLTUFFI.js.map → chunk-K2HDYSAM.js.map} +1 -1
- package/dist/{chunk-NQL3T75I.js → chunk-K7WPR77X.js} +21 -3
- package/dist/chunk-K7WPR77X.js.map +1 -0
- package/dist/{chunk-I5SGBFMM.js → chunk-MNAHNDUI.js} +3 -3
- package/dist/{chunk-I5SGBFMM.js.map → chunk-MNAHNDUI.js.map} +1 -1
- package/dist/{chunk-M5JDVO6D.js → chunk-NBJ5TOEC.js} +3 -3
- package/dist/{chunk-M5JDVO6D.js.map → chunk-NBJ5TOEC.js.map} +1 -1
- package/dist/{chunk-FIHVQFXB.js → chunk-NDD5VMN5.js} +2 -2
- package/dist/{chunk-FIHVQFXB.js.map → chunk-NDD5VMN5.js.map} +1 -1
- package/dist/{chunk-6SA2SIOU.js → chunk-OJN25VJO.js} +4 -4
- package/dist/{chunk-6SA2SIOU.js.map → chunk-OJN25VJO.js.map} +1 -1
- package/dist/{chunk-74GTZ4TJ.js → chunk-PFOXL4SH.js} +4 -4
- package/dist/{chunk-74GTZ4TJ.js.map → chunk-PFOXL4SH.js.map} +1 -1
- package/dist/{chunk-NICAMYPV.js → chunk-SKXCTV55.js} +8 -8
- package/dist/{chunk-NICAMYPV.js.map → chunk-SKXCTV55.js.map} +1 -1
- package/dist/{chunk-LDYPQVRU.js → chunk-V5TBKO5Q.js} +44 -11
- package/dist/chunk-V5TBKO5Q.js.map +1 -0
- package/dist/{chunk-FVZLCBSX.js → chunk-WH2EB2SF.js} +3 -3
- package/dist/{chunk-FVZLCBSX.js.map → chunk-WH2EB2SF.js.map} +1 -1
- package/dist/cli/index.js +41 -36
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/src/commands/manage.d.ts +1 -1
- package/dist/cli/src/commands/manage.d.ts.map +1 -1
- package/dist/connectors/config.js +5 -5
- package/dist/connectors/index.js +6 -6
- package/dist/core/index.js +4 -4
- package/dist/core/manifest.js +1 -1
- package/dist/core/runtime-assets.js +3 -3
- package/dist/core/src/index.d.ts +2 -2
- package/dist/core/src/index.d.ts.map +1 -1
- package/dist/core/src/manifest.d.ts +16 -0
- package/dist/core/src/manifest.d.ts.map +1 -1
- package/dist/core/src/repo-manager.d.ts.map +1 -1
- package/dist/core/src/walker.d.ts +4 -0
- package/dist/core/src/walker.d.ts.map +1 -1
- package/dist/core/src/workspace-config.d.ts +14 -0
- package/dist/core/src/workspace-config.d.ts.map +1 -1
- package/dist/core/workspace-config.js +2 -2
- package/dist/deploy/index.js +4 -4
- package/dist/discovery/index.js +2 -2
- package/dist/{ensure-sources-ALTI5PXR.js → ensure-sources-REWWBH2K.js} +8 -8
- package/dist/{ensure-sources-ALTI5PXR.js.map → ensure-sources-REWWBH2K.js.map} +1 -1
- package/dist/library/index.js +3 -3
- package/dist/{open-library-EEGG6RDN.js → open-library-CT4VVESU.js} +6 -6
- package/dist/{open-library-EEGG6RDN.js.map → open-library-CT4VVESU.js.map} +1 -1
- package/dist/{plugin-store-G277ZX3B.js → plugin-store-QS7TC5HY.js} +6 -6
- package/dist/{plugin-store-G277ZX3B.js.map → plugin-store-QS7TC5HY.js.map} +1 -1
- package/dist/runner/index.js +8 -8
- package/dist/sdk/asset-manager.js +6 -6
- package/dist/sdk/core.js +4 -4
- package/dist/sdk/index.js +8 -8
- package/dist/sdk/runner.js +8 -8
- package/dist/{setup-REX4I5NE.js → setup-F6DGKL7J.js} +6 -6
- package/dist/{setup-REX4I5NE.js.map → setup-F6DGKL7J.js.map} +1 -1
- package/dist/store-client-JP642EEI.js +14 -0
- package/dist/{store-client-IX3Y67NK.js.map → store-client-JP642EEI.js.map} +1 -1
- package/dist/tui/index.js +8 -8
- package/dist/workspace-plugin/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-LDYPQVRU.js.map +0 -1
- package/dist/chunk-NQL3T75I.js.map +0 -1
- package/dist/store-client-IX3Y67NK.js +0 -14
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { scanDirectory, parseFrontmatter, fromMcpServerMd } from './chunk-
|
|
1
|
+
import { scanDirectory, parseFrontmatter, bundleDepRefs, fromMcpServerMd } from './chunk-K7WPR77X.js';
|
|
2
2
|
import { parseAssetRef } from './chunk-VUCPJBAG.js';
|
|
3
3
|
import { mkdirSync, existsSync, readFileSync, writeFileSync, lstatSync, symlinkSync, rmSync, readdirSync, statSync } from 'fs';
|
|
4
4
|
import { homedir } from 'os';
|
|
@@ -250,6 +250,13 @@ var CanonicalRefConflictError = class extends Error {
|
|
|
250
250
|
depChain;
|
|
251
251
|
};
|
|
252
252
|
var SHA_PIN_RE = /^[0-9a-f]{40}$/i;
|
|
253
|
+
function qualifyPublisher(ref, fallback) {
|
|
254
|
+
const hashIdx = ref.indexOf("#");
|
|
255
|
+
const head = hashIdx === -1 ? ref : ref.slice(0, hashIdx);
|
|
256
|
+
if (head.includes("@")) return ref;
|
|
257
|
+
const pin = hashIdx === -1 ? "" : ref.slice(hashIdx);
|
|
258
|
+
return `${head}@${fallback}${pin}`;
|
|
259
|
+
}
|
|
253
260
|
async function resolveAll(deps, opts) {
|
|
254
261
|
const resolved = [];
|
|
255
262
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -338,6 +345,9 @@ async function resolveAll(deps, opts) {
|
|
|
338
345
|
}
|
|
339
346
|
resolved.push(chosen);
|
|
340
347
|
resolvedBy.set(key, parent);
|
|
348
|
+
for (const depRef of chosen.deps ?? []) {
|
|
349
|
+
await visit(qualifyPublisher(depRef, chosen.publisher), key, [...depChain, refStr]);
|
|
350
|
+
}
|
|
341
351
|
}
|
|
342
352
|
for (const dep of deps) {
|
|
343
353
|
await visit(dep, "direct", []);
|
|
@@ -491,7 +501,8 @@ function walkWithManifest(clone, yamlPath, index) {
|
|
|
491
501
|
commit: clone.commit,
|
|
492
502
|
files,
|
|
493
503
|
sha256: compositeSha256(files),
|
|
494
|
-
metadata
|
|
504
|
+
metadata,
|
|
505
|
+
deps: bundleDeps(clone.localPath, files, a.kind)
|
|
495
506
|
};
|
|
496
507
|
push(index, `${assetPublisher}/${a.kind}:${a.name}`, candidate);
|
|
497
508
|
}
|
|
@@ -549,7 +560,8 @@ function walkFilenameConvention(clone, index, publisherOverride, versionOverride
|
|
|
549
560
|
commit: clone.commit,
|
|
550
561
|
files,
|
|
551
562
|
sha256: compositeSha256(files),
|
|
552
|
-
metadata
|
|
563
|
+
metadata,
|
|
564
|
+
deps: bundleDeps(clone.localPath, files, kind)
|
|
553
565
|
};
|
|
554
566
|
push(index, `${publisher}/${kind}:${entry.name}`, candidate);
|
|
555
567
|
}
|
|
@@ -575,6 +587,11 @@ function readMetadata(repoRoot, files, kind) {
|
|
|
575
587
|
const { data } = parseFrontmatter(readFileSync(join(repoRoot, mcpMd.path), "utf8"));
|
|
576
588
|
return data;
|
|
577
589
|
}
|
|
590
|
+
function bundleDeps(repoRoot, files, kind) {
|
|
591
|
+
if (kind !== "bundle") return void 0;
|
|
592
|
+
const bf = files.find((f) => f.path.endsWith(".bundle.yaml") || f.path.endsWith("BUNDLE.md"));
|
|
593
|
+
return bf ? bundleDepRefs(join(repoRoot, bf.path)) : void 0;
|
|
594
|
+
}
|
|
578
595
|
function push(index, key, candidate) {
|
|
579
596
|
const arr = index.get(key) ?? [];
|
|
580
597
|
arr.push(candidate);
|
|
@@ -615,6 +632,7 @@ function validateAssetRecipeAttr(attr) {
|
|
|
615
632
|
);
|
|
616
633
|
}
|
|
617
634
|
}
|
|
635
|
+
var KNOWN_NETWORK_MODES = ["open", "off", "allowlist"];
|
|
618
636
|
var COMPACTION_DEFAULTS = {
|
|
619
637
|
enabled: true,
|
|
620
638
|
thresholdPercent: 80,
|
|
@@ -915,9 +933,7 @@ function normalizeConfigInternal(raw) {
|
|
|
915
933
|
const entry = { kind, name };
|
|
916
934
|
if (typeof a.root === "string") entry.root = a.root;
|
|
917
935
|
if (Array.isArray(a.files)) {
|
|
918
|
-
entry.files = a.files.filter(
|
|
919
|
-
(f) => typeof f === "string"
|
|
920
|
-
);
|
|
936
|
+
entry.files = a.files.filter((f) => typeof f === "string");
|
|
921
937
|
}
|
|
922
938
|
if (typeof a.version === "string") entry.version = a.version;
|
|
923
939
|
if (typeof a.publisher === "string") entry.publisher = a.publisher;
|
|
@@ -950,9 +966,7 @@ function normalizeConfigInternal(raw) {
|
|
|
950
966
|
);
|
|
951
967
|
}
|
|
952
968
|
if (o.reason.trim().length === 0) {
|
|
953
|
-
throw new Error(
|
|
954
|
-
`skaile.yaml: overrides[] entry for ${ref}: reason must not be empty.`
|
|
955
|
-
);
|
|
969
|
+
throw new Error(`skaile.yaml: overrides[] entry for ${ref}: reason must not be empty.`);
|
|
956
970
|
}
|
|
957
971
|
entries.push({ ref, source, reason: o.reason });
|
|
958
972
|
}
|
|
@@ -1090,6 +1104,25 @@ function validateConfigValues(config, diagnostics) {
|
|
|
1090
1104
|
};
|
|
1091
1105
|
for (const c of config.connectors ?? []) checkAccess(c.access, `connectors.${c.id}.access`);
|
|
1092
1106
|
for (const m of config.mounts ?? []) checkAccess(m.access, `mounts.${m.id}.access`);
|
|
1107
|
+
const network = config.agent?.permissions?.network;
|
|
1108
|
+
if (network) {
|
|
1109
|
+
if (network.mode && !KNOWN_NETWORK_MODES.includes(network.mode)) {
|
|
1110
|
+
diagnostics.push({
|
|
1111
|
+
code: "unknown_network_mode",
|
|
1112
|
+
severity: "warning",
|
|
1113
|
+
message: `Unknown network mode "${network.mode}" \u2014 expected one of: ${KNOWN_NETWORK_MODES.join(", ")}.`,
|
|
1114
|
+
path: "agent.permissions.network.mode"
|
|
1115
|
+
});
|
|
1116
|
+
}
|
|
1117
|
+
if (network.allowlist && network.allowlist.length > 0 && network.mode !== "allowlist") {
|
|
1118
|
+
diagnostics.push({
|
|
1119
|
+
code: "unexpected_network_allowlist",
|
|
1120
|
+
severity: "warning",
|
|
1121
|
+
message: `network.allowlist is set but mode is "${network.mode}" \u2014 the allowlist is ignored unless mode is "allowlist".`,
|
|
1122
|
+
path: "agent.permissions.network.allowlist"
|
|
1123
|
+
});
|
|
1124
|
+
}
|
|
1125
|
+
}
|
|
1093
1126
|
}
|
|
1094
1127
|
var CANONICAL_KEY_ORDER = [
|
|
1095
1128
|
"name",
|
|
@@ -1393,5 +1426,5 @@ function resolveAgentDir(projectDir) {
|
|
|
1393
1426
|
}
|
|
1394
1427
|
|
|
1395
1428
|
export { COMPACTION_DEFAULTS, CanonicalRefConflictError, DEFAULT_RECIPE_ATTR, SKAILE_YAML_DEFAULT, SKAILE_YAML_SUFFIX, SK_WORKSPACE_DEFAULT_NAME, SK_WORKSPACE_SUFFIX, buildProvenanceIndex, checkRepoStatus, checkoutPin, cloneRepo, decodeSkaileYaml, encodeSkaileYaml, ensureRepo, findWorkspaceRoot, getGlobalCacheDir, getRepoCommit, isWorkspaceConfigFilename, linkRepo, listSkWorkspaceConfigs, loadMcpServerDeclarations, loadSkWorkspaceConfig, mergeSkWorkspaceConfigs, normalizeConfig, pullRepo, readLinks, resolveAgentDir, resolveAll, resolveAsset, resolveSkWorkspaceConfig, saveSkWorkspaceConfig, scanRepo, unlinkRepo, validateAssetRecipeAttr, validateAssetRecipeFlake, workspaceConfigFilename, workspaceNameFromFilename, writeLinks };
|
|
1396
|
-
//# sourceMappingURL=chunk-
|
|
1397
|
-
//# sourceMappingURL=chunk-
|
|
1429
|
+
//# sourceMappingURL=chunk-V5TBKO5Q.js.map
|
|
1430
|
+
//# sourceMappingURL=chunk-V5TBKO5Q.js.map
|
|
@@ -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"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { globalSettingsPath, mapLegacyFields } from './chunk-
|
|
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-
|
|
93
|
-
//# sourceMappingURL=chunk-
|
|
92
|
+
//# sourceMappingURL=chunk-WH2EB2SF.js.map
|
|
93
|
+
//# sourceMappingURL=chunk-WH2EB2SF.js.map
|