@skaile/workspaces 0.22.0 → 0.23.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 +92 -0
- package/dist/{asset-feeds-Y2CDCM3W.js → asset-feeds-WKIKSZ6Z.js} +9 -9
- package/dist/{asset-feeds-Y2CDCM3W.js.map → asset-feeds-WKIKSZ6Z.js.map} +1 -1
- package/dist/asset-manager/index.js +7 -7
- package/dist/asset-manager/installer.js +6 -6
- package/dist/asset-manager/src/index.d.ts +15 -0
- package/dist/asset-manager/src/index.d.ts.map +1 -1
- package/dist/base-assets/connectors/deploy.js +8 -8
- package/dist/base-assets/connectors/devserver.js +8 -8
- package/dist/base-assets/connectors/flow/adapter.js +8 -8
- package/dist/base-assets/connectors/flow/run-flow.js +9 -9
- package/dist/base-assets/connectors/flow.js +8 -8
- package/dist/base-assets/connectors/git.js +8 -8
- package/dist/base-assets/connectors/gmail.js +8 -8
- package/dist/base-assets/connectors/googledrive/driver.d.ts.map +1 -1
- package/dist/base-assets/connectors/googledrive.js +8 -8
- package/dist/base-assets/connectors/local.js +8 -8
- package/dist/base-assets/connectors/mattermost.js +8 -8
- package/dist/base-assets/connectors/memory.js +8 -8
- package/dist/base-assets/connectors/minio.js +8 -8
- package/dist/base-assets/connectors/postgres.js +8 -8
- package/dist/base-assets/connectors/s3.js +8 -8
- package/dist/base-assets/connectors/sharepoint/driver.d.ts.map +1 -1
- package/dist/base-assets/connectors/sharepoint.js +8 -8
- package/dist/base-assets/connectors/sqlite.js +8 -8
- package/dist/base-assets/connectors/static-server.js +8 -8
- package/dist/base-assets/connectors/tunnel.js +8 -8
- package/dist/base-assets/connectors/webdav/driver.d.ts.map +1 -1
- package/dist/base-assets/connectors/webdav.js +8 -8
- package/dist/base-assets/connectors/xstate-store.js +8 -8
- package/dist/base-assets/connectors/xstate.js +8 -8
- package/dist/{chunk-MNAHNDUI.js → chunk-2F3RUZXC.js} +3 -3
- package/dist/{chunk-MNAHNDUI.js.map → chunk-2F3RUZXC.js.map} +1 -1
- package/dist/{chunk-2RYQERIT.js → chunk-2RFOFHSM.js} +4 -4
- package/dist/{chunk-2RYQERIT.js.map → chunk-2RFOFHSM.js.map} +1 -1
- package/dist/{chunk-K2HDYSAM.js → chunk-46COM7M5.js} +5 -5
- package/dist/{chunk-K2HDYSAM.js.map → chunk-46COM7M5.js.map} +1 -1
- package/dist/{chunk-V5TBKO5Q.js → chunk-542K7SR6.js} +59 -35
- package/dist/chunk-542K7SR6.js.map +1 -0
- package/dist/{chunk-PFOXL4SH.js → chunk-5ESCS2OS.js} +4 -4
- package/dist/{chunk-PFOXL4SH.js.map → chunk-5ESCS2OS.js.map} +1 -1
- package/dist/{chunk-WH2EB2SF.js → chunk-AFLH7B64.js} +3 -3
- package/dist/{chunk-WH2EB2SF.js.map → chunk-AFLH7B64.js.map} +1 -1
- package/dist/{chunk-7HSXUKNB.js → chunk-BTAC2VYT.js} +19 -18
- package/dist/chunk-BTAC2VYT.js.map +1 -0
- package/dist/{chunk-K7WPR77X.js → chunk-DH4N5AW4.js} +14 -8
- package/dist/chunk-DH4N5AW4.js.map +1 -0
- package/dist/{chunk-SKXCTV55.js → chunk-DZCFFTAX.js} +9 -9
- package/dist/{chunk-SKXCTV55.js.map → chunk-DZCFFTAX.js.map} +1 -1
- package/dist/{chunk-OJN25VJO.js → chunk-E4UJ7CVK.js} +31 -126
- package/dist/chunk-E4UJ7CVK.js.map +1 -0
- package/dist/{chunk-JN2CUVSU.js → chunk-LJ52ZKIU.js} +3 -3
- package/dist/{chunk-JN2CUVSU.js.map → chunk-LJ52ZKIU.js.map} +1 -1
- package/dist/{chunk-NBJ5TOEC.js → chunk-ODPII24X.js} +3 -3
- package/dist/{chunk-NBJ5TOEC.js.map → chunk-ODPII24X.js.map} +1 -1
- package/dist/{chunk-NDD5VMN5.js → chunk-OVQZ5OKL.js} +2 -2
- package/dist/{chunk-NDD5VMN5.js.map → chunk-OVQZ5OKL.js.map} +1 -1
- package/dist/{chunk-6MB7CRME.js → chunk-QMONOHXT.js} +268 -37
- package/dist/chunk-QMONOHXT.js.map +1 -0
- package/dist/{chunk-53UNDY6K.js → chunk-QTWA6BZK.js} +5 -5
- package/dist/{chunk-53UNDY6K.js.map → chunk-QTWA6BZK.js.map} +1 -1
- package/dist/{chunk-4NDWKA64.js → chunk-WSZAFRQL.js} +8 -3
- package/dist/chunk-WSZAFRQL.js.map +1 -0
- package/dist/{chunk-VUCPJBAG.js → chunk-YX3UWPJ5.js} +53 -28
- package/dist/chunk-YX3UWPJ5.js.map +1 -0
- package/dist/{chunk-ETMUGBHF.js → chunk-Z3M5K67G.js} +8 -8
- package/dist/chunk-Z3M5K67G.js.map +1 -0
- package/dist/cli/index.js +38 -38
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/src/commands/manage.d.ts.map +1 -1
- package/dist/cli/src/helpers.d.ts +7 -0
- package/dist/cli/src/helpers.d.ts.map +1 -1
- package/dist/connectors/config.js +6 -6
- package/dist/connectors/index.js +8 -8
- package/dist/connectors/rclone.js +2 -1
- package/dist/connectors/src/rclone-process-manager.d.ts +91 -3
- package/dist/connectors/src/rclone-process-manager.d.ts.map +1 -1
- package/dist/connectors/src/watcher.d.ts +6 -0
- package/dist/connectors/src/watcher.d.ts.map +1 -1
- package/dist/core/index.js +5 -5
- package/dist/core/manifest.js +2 -2
- package/dist/core/models.js +1 -1
- package/dist/core/runtime-assets.js +4 -4
- package/dist/core/src/lock.d.ts +6 -6
- package/dist/core/src/manifest.d.ts.map +1 -1
- package/dist/core/src/models.d.ts +25 -18
- package/dist/core/src/models.d.ts.map +1 -1
- package/dist/core/src/repo-manager.d.ts +8 -2
- package/dist/core/src/repo-manager.d.ts.map +1 -1
- package/dist/core/workspace-config.js +3 -3
- package/dist/deploy/index.js +5 -5
- package/dist/discovery/index.js +3 -3
- package/dist/{ensure-sources-REWWBH2K.js → ensure-sources-OJUBGX6Z.js} +10 -10
- package/dist/{ensure-sources-REWWBH2K.js.map → ensure-sources-OJUBGX6Z.js.map} +1 -1
- package/dist/helpers-LTN3HMD3.js +4 -0
- package/dist/{helpers-I3SREIC3.js.map → helpers-LTN3HMD3.js.map} +1 -1
- package/dist/library/index.js +4 -4
- package/dist/open-library-67FSSQWE.js +13 -0
- package/dist/{open-library-CT4VVESU.js.map → open-library-67FSSQWE.js.map} +1 -1
- package/dist/{plugin-store-QS7TC5HY.js → plugin-store-IZ5SCRAV.js} +7 -7
- package/dist/{plugin-store-QS7TC5HY.js.map → plugin-store-IZ5SCRAV.js.map} +1 -1
- package/dist/runner/index.js +10 -10
- package/dist/sdk/asset-manager.js +7 -7
- package/dist/sdk/core.js +5 -5
- package/dist/sdk/index.js +10 -10
- package/dist/sdk/runner.js +10 -10
- package/dist/{setup-F6DGKL7J.js → setup-J7CYEQOF.js} +7 -7
- package/dist/{setup-F6DGKL7J.js.map → setup-J7CYEQOF.js.map} +1 -1
- package/dist/store-client-AEI6Y3KD.js +14 -0
- package/dist/{store-client-JP642EEI.js.map → store-client-AEI6Y3KD.js.map} +1 -1
- package/dist/tui/index.js +10 -10
- package/dist/workspace-plugin/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-4NDWKA64.js.map +0 -1
- package/dist/chunk-6MB7CRME.js.map +0 -1
- package/dist/chunk-7HSXUKNB.js.map +0 -1
- package/dist/chunk-ETMUGBHF.js.map +0 -1
- package/dist/chunk-K7WPR77X.js.map +0 -1
- package/dist/chunk-OJN25VJO.js.map +0 -1
- package/dist/chunk-V5TBKO5Q.js.map +0 -1
- package/dist/chunk-VUCPJBAG.js.map +0 -1
- package/dist/helpers-I3SREIC3.js +0 -4
- package/dist/open-library-CT4VVESU.js +0 -13
- package/dist/store-client-JP642EEI.js +0 -14
package/dist/tui/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { createAgentSession } from '../chunk-
|
|
2
|
-
import '../chunk-
|
|
1
|
+
import { createAgentSession } from '../chunk-DZCFFTAX.js';
|
|
2
|
+
import '../chunk-OVQZ5OKL.js';
|
|
3
3
|
import '../chunk-X5YPJV4N.js';
|
|
4
4
|
import '../chunk-O7SG5PC2.js';
|
|
5
5
|
import '../chunk-7QBNJTTQ.js';
|
|
@@ -14,21 +14,21 @@ import '../chunk-KOVLSBXK.js';
|
|
|
14
14
|
import '../chunk-RRVQAE5D.js';
|
|
15
15
|
import '../chunk-6VTG73UY.js';
|
|
16
16
|
import '../chunk-LV2HPH3C.js';
|
|
17
|
-
import '../chunk-
|
|
18
|
-
import { loadConnectorDeclarations } from '../chunk-
|
|
19
|
-
import '../chunk-
|
|
17
|
+
import '../chunk-E4UJ7CVK.js';
|
|
18
|
+
import { loadConnectorDeclarations } from '../chunk-ODPII24X.js';
|
|
19
|
+
import '../chunk-QMONOHXT.js';
|
|
20
20
|
import '../chunk-QAVZOJCV.js';
|
|
21
21
|
import '../chunk-6E6PKKAD.js';
|
|
22
22
|
import '../chunk-ICS76R4T.js';
|
|
23
23
|
import '../chunk-GZWJGNNN.js';
|
|
24
24
|
import '../chunk-FVTV7M76.js';
|
|
25
|
-
import { resolveSettings } from '../chunk-
|
|
25
|
+
import { resolveSettings } from '../chunk-Z3M5K67G.js';
|
|
26
26
|
import '../chunk-K5GBV4SA.js';
|
|
27
27
|
import '../chunk-KLNL7QHN.js';
|
|
28
|
-
import '../chunk-
|
|
29
|
-
import { resolveAgentDir } from '../chunk-
|
|
30
|
-
import '../chunk-
|
|
31
|
-
import '../chunk-
|
|
28
|
+
import '../chunk-5ESCS2OS.js';
|
|
29
|
+
import { resolveAgentDir } from '../chunk-542K7SR6.js';
|
|
30
|
+
import '../chunk-DH4N5AW4.js';
|
|
31
|
+
import '../chunk-YX3UWPJ5.js';
|
|
32
32
|
import '../chunk-JKNWJ64A.js';
|
|
33
33
|
import '../chunk-O4JH3KUE.js';
|
|
34
34
|
import '../chunk-24UIWON4.js';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { PluginStore, WorkspacePlugin, buildClaudePluginFiles, resolveProjectDir } from '../chunk-
|
|
1
|
+
export { PluginStore, WorkspacePlugin, buildClaudePluginFiles, resolveProjectDir } from '../chunk-OVQZ5OKL.js';
|
|
2
2
|
export { err, ok, okJson } from '../chunk-X5YPJV4N.js';
|
|
3
3
|
import '../chunk-24UIWON4.js';
|
|
4
4
|
import '../chunk-NSBPE2FW.js';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@skaile/workspaces",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.23.0",
|
|
4
4
|
"description": "Skaile workspaces runtime — types, core, bridge, runner, store, connectors, and supporting layers as one publishable package",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"packageManager": "bun@1.3.9",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../cli/src/helpers.ts"],"names":[],"mappings":"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","file":"chunk-4NDWKA64.js","sourcesContent":["import pc from \"picocolors\";\n\n/**\n * Terminal styling helpers used across all CLI commands.\n *\n * @docLink cli/dev-guide#helpers\n */\nexport const S = {\n brand: (s: string) => pc.cyan(pc.bold(s)),\n cmd: (s: string) => pc.cyan(s),\n heading: (s: string) => pc.bold(s),\n bold: (s: string) => pc.bold(s),\n dim: (s: string) => pc.dim(s),\n ok: (s: string) => pc.green(s),\n warn: (s: string) => pc.yellow(s),\n err: (s: string) => pc.red(s),\n label: (s: string) => pc.dim(s),\n rule: (w = 40) => pc.dim(\"─\".repeat(w)),\n};\n\nconst KIND_COLORS: Record<string, (s: string) => string> = {\n skill: pc.blue,\n agent: pc.magenta,\n prompt: pc.yellow,\n flow: pc.green,\n bundle: pc.cyan,\n contract: pc.red,\n connector: pc.green,\n mount: pc.green,\n knowledge: pc.cyan,\n persona: pc.cyan,\n ruleset: pc.cyan,\n \"mcp-server\": pc.magenta,\n};\n\n/** Color-code an asset kind string. */\nexport function kindColor(kind: string): string {\n const colorFn = KIND_COLORS[kind] ?? pc.dim;\n return colorFn(kind);\n}\n\n/** Color-code and pad an asset kind string. */\nexport function kindColorPad(kind: string, width = 8): string {\n const colorFn = KIND_COLORS[kind] ?? pc.dim;\n return colorFn(kind.padEnd(width));\n}\n\n/** Color-code a \"kind:name\" reference string. */\nexport function colorRef(ref: string): string {\n const colonIdx = ref.indexOf(\":\");\n if (colonIdx === -1) return ref;\n const kind = ref.slice(0, colonIdx);\n const rest = ref.slice(colonIdx);\n return `${kindColor(kind)}${rest}`;\n}\n\n/**\n * Print a success line prefixed with a green check mark.\n *\n * @param msg - Message to display.\n * @docLink cli/dev-guide#helpers\n */\nexport function logOk(msg: string) {\n console.log(` ${pc.green(\"✓\")} ${msg}`);\n}\n/**\n * Print an error line prefixed with a red cross to stderr.\n *\n * @param msg - Message to display.\n * @docLink cli/dev-guide#helpers\n */\nexport function logErr(msg: string) {\n console.error(` ${pc.red(\"✗\")} ${msg}`);\n}\n/**\n * Print a warning line prefixed with a yellow exclamation mark.\n *\n * @param msg - Message to display.\n * @docLink cli/dev-guide#helpers\n */\nexport function logWarn(msg: string) {\n console.log(` ${pc.yellow(\"!\")} ${msg}`);\n}\n/**\n * Print an info line prefixed with a dim dot.\n *\n * @param msg - Message to display.\n * @docLink cli/dev-guide#helpers\n */\nexport function logInfo(msg: string) {\n console.log(` ${pc.dim(\"·\")} ${msg}`);\n}\n\n/** Format a Date as a human-readable relative time string (e.g. \"5m ago\"). */\nexport function formatRelativeTime(date: Date): string {\n const diff = Date.now() - date.getTime();\n const seconds = Math.floor(diff / 1000);\n if (seconds < 60) return \"just now\";\n const minutes = Math.floor(seconds / 60);\n if (minutes < 60) return `${minutes}m ago`;\n const hours = Math.floor(minutes / 60);\n if (hours < 24) return `${hours}h ago`;\n const days = Math.floor(hours / 24);\n return `${days}d ago`;\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../connectors/src/fs-utils.ts","../connectors/src/port-pool.ts","../connectors/src/rclone-process-manager.ts"],"names":[],"mappings":"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","file":"chunk-6MB7CRME.js","sourcesContent":["/**\n * Shared filesystem helpers for connector infrastructure.\n *\n * @docLink packages/connectors/api-reference#fs-utils\n */\n\nimport { chmod, mkdir } from \"node:fs/promises\";\nimport type { Logger } from \"@skaile/workspaces/types\";\n\n/**\n * mkdir(recursive) + chmod 0o770 in one call. The post-mkdir `chmod` is the\n * load-bearing piece: `mkdir(mode:)` is ANDed with the process umask\n * (typically 022 → effective mode 0o750), which strips the group-write bit\n * that `fusermount3` requires on the rclone mountpoint and rclone needs on\n * its vfs cache directory. Explicit `chmod` is umask-immune.\n *\n * EPERM on `chmod` is swallowed: when a foreign uid pre-created the\n * directory (a stray uid-1000 process inside the container or a host-side\n * platform process writing through the project bind-mount), the runner\n * cannot chmod it. The platform's agent container entrypoint runs as root\n * and heals the subtree on the next restart — see\n * `platform/docker/agent/entrypoint.sh` `_skaile_heal_ownership`. A debug\n * line is emitted when a logger is supplied so the rare-but-real heal\n * trigger is observable in session logs without adding noise on the happy\n * path.\n *\n * The chmod is *idempotent* (the syscall always fires, but a no-op when\n * the mode is already 0o770), not a no-op — kernel behaviour for chmod is\n * \"set\", not \"set-if-different\".\n *\n * @param dir Absolute or relative path to ensure exists at mode 0o770.\n * @param log Optional logger. When provided, EPERM-on-chmod emits a\n * `debug`-level entry under whatever taxonomy the caller's logger uses.\n */\nexport async function ensureDirMode(dir: string, log?: Logger): Promise<void> {\n await mkdir(dir, { recursive: true });\n try {\n await chmod(dir, 0o770);\n } catch (err) {\n log?.debug(\"chmod 0770 skipped (EPERM — entrypoint heal expected)\", {\n path: dir,\n error: err instanceof Error ? err.message : String(err),\n });\n }\n}\n","/**\n * PortPool — allocates ports from a [min, max] range, checks OS for collisions.\n */\n\nimport { createConnection } from \"node:net\";\n\n/**\n * Allocates TCP ports from a `[min, max]` range with OS-level collision detection.\n * Used by service connector adapters (devserver, static-server) to assign local ports.\n * @docLink packages/connectors/api-reference#port-pool\n */\nexport class PortPool {\n private readonly min: number;\n private readonly max: number;\n private readonly inUse = new Set<number>();\n\n constructor(range: [number, number]) {\n this.min = range[0];\n this.max = range[1];\n }\n\n /** Allocate the next free port from the range. Checks OS for collisions. */\n async allocate(): Promise<number> {\n for (let port = this.min; port <= this.max; port++) {\n if (this.inUse.has(port)) continue;\n if (!(await PortPool.isPortFree(port))) {\n this.inUse.add(port);\n continue;\n }\n this.inUse.add(port);\n return port;\n }\n throw new Error(`No free port in range ${this.min}-${this.max}`);\n }\n\n /** Mark a port as in-use (for explicit port args or registered instances). */\n reserve(port: number): void {\n this.inUse.add(port);\n }\n\n /** Return a port to the pool. */\n release(port: number): void {\n this.inUse.delete(port);\n }\n\n /** Check if a port is currently tracked as in-use. */\n isInUse(port: number): boolean {\n return this.inUse.has(port);\n }\n\n /** Quick TCP connect test — returns true if nothing is listening. */\n static isPortFree(port: number, host = \"127.0.0.1\"): Promise<boolean> {\n return new Promise((resolve) => {\n const socket = createConnection({ port, host });\n socket.once(\"connect\", () => {\n socket.destroy();\n resolve(false);\n });\n socket.once(\"error\", () => {\n socket.destroy();\n resolve(true);\n });\n socket.setTimeout(500, () => {\n socket.destroy();\n resolve(true);\n });\n });\n }\n}\n","/**\n * RcloneProcessManager — supervises an rclone FUSE subprocess per mount.\n *\n * Responsibilities:\n * - Spawn rclone with a per-mount config + cache dir, wait for the FUSE\n * mountpoint to appear, then return a handle.\n * - Pipe rclone's JSON-formatted log lines into the parent driver's\n * {@link Logger} via a child source `${driverName}+rclone`.\n * - Coordinate graceful stop (flush → SIGTERM → fusermount fallback).\n * - Expose `flush` (POST /vfs/refresh + poll /vfs/stats) and `status`\n * (process liveness + cache-dir size).\n *\n * Cross-link: see `workspaces/core/CLAUDE.md` § Logging for the\n * `createLogger` / `LogStore` contract, and\n * `_devlog/specs/2026-05-01-debug-logging-design.md` for the source taxonomy.\n */\n\nimport { type ChildProcess, spawn } from \"node:child_process\";\nimport { randomBytes } from \"node:crypto\";\nimport { readdir, readFile, stat, unlink, writeFile } from \"node:fs/promises\";\nimport { tmpdir } from \"node:os\";\nimport path from \"node:path\";\nimport type { Readable } from \"node:stream\";\nimport type { Logger } from \"@skaile/workspaces/types\";\nimport { ensureDirMode } from \"./fs-utils.js\";\nimport { PortPool } from \"./port-pool.js\";\n\n/** Module-level pool for rclone remote-control (rc) ports. */\nconst RCLONE_RC_PORTS = new PortPool([55000, 56000]);\n\n/**\n * Spawn-time configuration for a single rclone FUSE mount.\n * @docLink packages/connectors/api-reference#rclone-spawn-config\n */\nexport interface RcloneSpawnConfig {\n /** Logical mount id; used as `instance` and as part of the rclone config filename. */\n mountId: string;\n /**\n * Driver name (e.g. \"sharepoint\", \"webdav\"); used to derive the rclone\n * subprocess child logger subkind: `${driverName}+rclone`.\n */\n driverName: string;\n /** Absolute path inside the container where rclone will FUSE-mount. Created if missing. */\n mountPoint: string;\n /** Absolute path inside the container for the vfs cache. Created if missing. */\n cacheDir: string;\n /** Full INI text for rclone.conf (one [remote] section, named `skaile-<mountId>`). */\n rcloneConfig: string;\n /** Remote spec, e.g. `skaile-foo:/Clients/KADK`. */\n remote: string;\n /** rclone --vfs-cache-mode value. */\n vfsCacheMode: \"minimal\" | \"writes\" | \"full\";\n /** Per-mount cache size cap. Default: '5G'. */\n cacheMaxSize?: string;\n /** Per-mount cache age cap. Default: '168h'. */\n cacheMaxAge?: string;\n /**\n * Parent driver Logger — already tagged\n * `{kind:\"mount\", subkind:<driver>, instance:<mountId>}` by ConnectorManager.\n * Used for manager-level events; rclone subprocess events go through the\n * derived `child({subkind: \\`${driverName}+rclone\\`})` logger.\n */\n log: Logger;\n}\n\n/**\n * Handle returned by `RcloneProcessManager.spawn()` once the FUSE mountpoint is confirmed.\n * @docLink packages/connectors/api-reference#rclone-handle\n */\nexport interface RcloneHandle {\n /** OS process id of the rclone subprocess. */\n pid: number;\n /** Confirmed FUSE mountpoint (echo of input). */\n mountPoint: string;\n /** Cache directory (echo of input). */\n cacheDir: string;\n /** The local rc API address rclone is bound to, e.g. '127.0.0.1:54321'. */\n rcAddr: string;\n}\n\ninterface InternalEntry {\n proc: ChildProcess;\n configPath: string;\n port: number;\n mountPoint: string;\n cacheDir: string;\n log: Logger;\n rcloneLog: Logger;\n /**\n * Last few stderr lines for diagnostic purposes (used in spawn-failure\n * messages).\n */\n recentStderr: string[];\n}\n\nconst HANDLES = new Map<number, InternalEntry>();\n\n/**\n * Manages rclone FUSE subprocesses for mount drivers. Stateless across instances —\n * the internal handle registry is module-scoped so a fresh `RcloneProcessManager`\n * can still find handles created by a previous instance.\n * @docLink packages/connectors/api-reference#rclone-process-manager\n */\nexport class RcloneProcessManager {\n /**\n * Spawn an rclone FUSE mount. Resolves once the mountpoint is confirmed\n * present in `/proc/self/mounts`. Throws on timeout, on early exit, or\n * if invariants are violated.\n */\n async spawn(config: RcloneSpawnConfig): Promise<RcloneHandle> {\n if (!path.isAbsolute(config.mountPoint)) {\n throw new Error(`mountPoint must be absolute: ${config.mountPoint}`);\n }\n if (!path.isAbsolute(config.cacheDir)) {\n throw new Error(`cacheDir must be absolute: ${config.cacheDir}`);\n }\n\n // Defence-in-depth: the per-connector driver already chmods these via\n // ensureDirMode, but direct callers that bypass the driver still need\n // mountPoint and cacheDir to be group-writable for fusermount3 / vfs.\n await ensureDirMode(config.mountPoint, config.log);\n await ensureDirMode(config.cacheDir, config.log);\n\n const configPath = path.join(\n tmpdir(),\n `rclone-${config.mountId}-${randomBytes(6).toString(\"hex\")}.conf`,\n );\n await writeFile(configPath, config.rcloneConfig, { mode: 0o600 });\n\n const port = await RCLONE_RC_PORTS.allocate();\n const rcAddr = `127.0.0.1:${port}`;\n const rcloneLog = config.log.child({ subkind: `${config.driverName}+rclone` });\n\n config.log.info(\"rclone spawn starting\", {\n mountPoint: config.mountPoint,\n remote: config.remote,\n vfsCacheMode: config.vfsCacheMode,\n });\n\n const args = [\n \"mount\",\n config.remote,\n config.mountPoint,\n \"--config\",\n configPath,\n \"--cache-dir\",\n config.cacheDir,\n \"--vfs-cache-mode\",\n config.vfsCacheMode,\n \"--vfs-cache-max-size\",\n config.cacheMaxSize ?? \"5G\",\n \"--vfs-cache-max-age\",\n config.cacheMaxAge ?? \"168h\",\n \"--vfs-write-back\",\n \"5s\",\n \"--vfs-cache-poll-interval\",\n \"60s\",\n \"--rc\",\n \"--rc-addr\",\n rcAddr,\n \"--log-level\",\n \"INFO\",\n \"--use-json-log\",\n \"--allow-other\",\n ];\n\n const proc = spawn(\"rclone\", args, { stdio: [\"ignore\", \"pipe\", \"pipe\"] });\n\n const recentStderr: string[] = [];\n const stderrTail = (line: string) => {\n recentStderr.push(line);\n if (recentStderr.length > 20) recentStderr.shift();\n };\n\n const stdoutHandler = (line: string) => {\n _routeRcloneLogLine(line, rcloneLog);\n };\n const stderrHandler = (line: string) => {\n stderrTail(line);\n _routeRcloneLogLine(line, rcloneLog);\n };\n\n if (proc.stdout) attachLineSplitter(proc.stdout, stdoutHandler);\n if (proc.stderr) attachLineSplitter(proc.stderr, stderrHandler);\n\n let earlyExitCode: number | null = null;\n let earlyExitSignal: NodeJS.Signals | null = null;\n const earlyExit = new Promise<void>((resolve) => {\n proc.once(\"exit\", (code, signal) => {\n earlyExitCode = code;\n earlyExitSignal = signal;\n resolve();\n });\n });\n\n const mountReady = waitFor(\n async () => {\n if (earlyExitCode !== null || earlyExitSignal !== null) return false;\n return await isMountpoint(config.mountPoint);\n },\n { timeoutMs: 15_000, intervalMs: 100 },\n );\n\n const ready = await Promise.race([mountReady, earlyExit.then(() => false)]);\n\n if (!ready) {\n try {\n if (proc.exitCode === null && proc.signalCode === null) {\n proc.kill(\"SIGKILL\");\n }\n } catch {\n // ignore\n }\n await unlink(configPath).catch(() => {});\n RCLONE_RC_PORTS.release(port);\n const tail =\n recentStderr.length > 0 ? `\\nstderr tail:\\n${recentStderr.slice(-5).join(\"\\n\")}` : \"\";\n throw new Error(`rclone failed to mount ${config.remote} at ${config.mountPoint}${tail}`);\n }\n\n const pid = proc.pid;\n if (pid === undefined) {\n // Should never happen if mountReady resolved true, but defend anyway.\n proc.kill(\"SIGKILL\");\n await unlink(configPath).catch(() => {});\n RCLONE_RC_PORTS.release(port);\n throw new Error(\"rclone process has no pid after successful mount\");\n }\n\n const entry: InternalEntry = {\n proc,\n configPath,\n port,\n mountPoint: config.mountPoint,\n cacheDir: config.cacheDir,\n log: config.log,\n rcloneLog,\n recentStderr,\n };\n HANDLES.set(pid, entry);\n\n proc.on(\"exit\", (code) => {\n // If the entry is still in the registry, this was unplanned.\n if (HANDLES.has(pid)) {\n config.log.warn(\"rclone exited unexpectedly\", { code, pid });\n }\n });\n\n config.log.info(\"rclone mountpoint confirmed\", { pid });\n\n return { pid, mountPoint: config.mountPoint, cacheDir: config.cacheDir, rcAddr };\n }\n\n /**\n * Stop an rclone subprocess. Attempts a flush first, then SIGTERM, then\n * SIGKILL + fusermount3 if `graceMs` elapses without the mountpoint\n * disappearing.\n */\n async stop(handle: RcloneHandle, opts?: { graceMs?: number }): Promise<void> {\n const graceMs = opts?.graceMs ?? 30_000;\n const entry = HANDLES.get(handle.pid);\n if (!entry) {\n return;\n }\n\n try {\n await this.flush(handle);\n } catch (err) {\n entry.log.warn(\"rclone flush before stop failed\", {\n pid: handle.pid,\n error: err instanceof Error ? err.message : String(err),\n });\n }\n\n entry.log.info(\"rclone stop initiated\", { pid: handle.pid });\n\n // Remove FIRST so the exit handler doesn't fire the unplanned-exit warning.\n HANDLES.delete(handle.pid);\n\n try {\n entry.proc.kill(\"SIGTERM\");\n } catch {\n // ignore — process may already be gone\n }\n\n const unmounted = await waitFor(async () => !(await isMountpoint(entry.mountPoint)), {\n timeoutMs: graceMs,\n intervalMs: 200,\n });\n\n if (!unmounted) {\n try {\n entry.proc.kill(\"SIGKILL\");\n } catch {\n // ignore\n }\n await new Promise<void>((resolve) => {\n const fuse = spawn(\"fusermount3\", [\"-u\", entry.mountPoint], { stdio: \"ignore\" });\n fuse.once(\"exit\", () => resolve());\n fuse.once(\"error\", () => resolve());\n });\n entry.log.warn(\"rclone hard-killed\", { pid: handle.pid });\n }\n\n RCLONE_RC_PORTS.release(entry.port);\n await unlink(entry.configPath).catch(() => {});\n }\n\n /**\n * Force rclone to upload pending writes, then wait until the in-use\n * counter reaches zero.\n */\n async flush(handle: RcloneHandle): Promise<void> {\n const entry = HANDLES.get(handle.pid);\n if (!entry) {\n throw new Error(`rclone handle not found (pid=${handle.pid})`);\n }\n\n const refreshRes = await fetch(`http://${handle.rcAddr}/vfs/refresh?recursive=true`, {\n method: \"POST\",\n });\n if (!refreshRes.ok) {\n const body = await refreshRes.text().catch(() => \"\");\n throw new Error(`rclone /vfs/refresh failed: ${refreshRes.status} ${body}`);\n }\n\n const ok = await waitFor(\n async () => {\n const r = await fetch(`http://${handle.rcAddr}/vfs/stats`, { method: \"GET\" });\n if (!r.ok) return false;\n const body = (await r.json()) as { inUse?: number; [k: string]: unknown };\n return body.inUse === 0;\n },\n { timeoutMs: 60_000, intervalMs: 500 },\n );\n if (!ok) {\n throw new Error(`rclone flush did not drain within 60s (pid=${handle.pid})`);\n }\n }\n\n /** Liveness + cache-dir size. */\n async status(handle: RcloneHandle): Promise<{ alive: boolean; cacheBytes: number }> {\n const entry = HANDLES.get(handle.pid);\n if (!entry) {\n return { alive: false, cacheBytes: 0 };\n }\n const alive = entry.proc.exitCode === null && entry.proc.signalCode === null;\n const cacheBytes = await dirSize(entry.cacheDir);\n return { alive, cacheBytes };\n }\n}\n\n// ── helpers ────────────────────────────────────────────────────────────────\n\ninterface RcloneJsonLine {\n level?: string;\n msg?: string;\n source?: string;\n time?: string;\n object?: string;\n error?: unknown;\n}\n\n/**\n * @internal\n * Route a single rclone log line (JSON or raw) to the appropriate Logger\n * call. Exported for tests; not part of the public API.\n */\nexport function _routeRcloneLogLine(line: string, log: Logger): void {\n const trimmed = line.trim();\n if (trimmed.length === 0) return;\n\n let parsed: RcloneJsonLine | null = null;\n try {\n const candidate = JSON.parse(trimmed);\n if (candidate && typeof candidate === \"object\") parsed = candidate as RcloneJsonLine;\n } catch {\n parsed = null;\n }\n\n if (!parsed) {\n log.info(trimmed);\n return;\n }\n\n const level = (parsed.level ?? \"INFO\").toUpperCase();\n const msg = parsed.msg ?? \"\";\n const data: Record<string, unknown> = {};\n if (parsed.object !== undefined) data.object = parsed.object;\n if (parsed.source !== undefined) data.source = parsed.source;\n\n switch (level) {\n case \"DEBUG\":\n log.debug(msg, data);\n break;\n case \"INFO\":\n case \"NOTICE\":\n log.info(msg, data);\n break;\n case \"WARNING\":\n log.warn(msg, data);\n break;\n case \"ERROR\":\n case \"CRITICAL\":\n case \"EMERGENCY\":\n case \"ALERT\":\n log.error(msg, parsed.error, data);\n break;\n default:\n log.info(msg, data);\n break;\n }\n}\n\n/** Returns true if `mountPoint` appears as a mount in /proc/self/mounts. */\nasync function isMountpoint(mountPoint: string): Promise<boolean> {\n try {\n const resolved = path.resolve(mountPoint);\n const text = await readFile(\"/proc/self/mounts\", \"utf8\");\n for (const raw of text.split(\"\\n\")) {\n if (raw.length === 0) continue;\n const fields = raw.split(/\\s+/);\n const mp = fields[1];\n if (!mp) continue;\n // /proc/self/mounts encodes spaces as \\040; cheap decode.\n const decoded = mp.replace(/\\\\040/g, \" \");\n if (decoded === resolved) return true;\n }\n return false;\n } catch {\n return false;\n }\n}\n\n/**\n * Poll `check` every `intervalMs` until it returns true or `timeoutMs`\n * elapses. Returns true on success, false on timeout.\n */\nasync function waitFor(\n check: () => Promise<boolean>,\n opts: { timeoutMs: number; intervalMs: number },\n): Promise<boolean> {\n const deadline = Date.now() + opts.timeoutMs;\n while (Date.now() < deadline) {\n if (await check()) return true;\n await sleep(opts.intervalMs);\n }\n return await check();\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => {\n setTimeout(resolve, ms);\n });\n}\n\n/** Wire a Readable to a per-line callback, buffering partial chunks. */\nfunction attachLineSplitter(stream: Readable, onLine: (line: string) => void): void {\n let buffer = \"\";\n stream.setEncoding(\"utf8\");\n stream.on(\"data\", (chunk: string) => {\n buffer += chunk;\n let idx = buffer.indexOf(\"\\n\");\n while (idx >= 0) {\n const line = buffer.slice(0, idx);\n buffer = buffer.slice(idx + 1);\n if (line.length > 0) onLine(line);\n idx = buffer.indexOf(\"\\n\");\n }\n });\n stream.on(\"end\", () => {\n if (buffer.length > 0) {\n onLine(buffer);\n buffer = \"\";\n }\n });\n}\n\n/** Recursively sum file sizes under `dir`. Returns 0 if dir does not exist. */\nasync function dirSize(dir: string): Promise<number> {\n let total = 0;\n try {\n const entries = await readdir(dir, { withFileTypes: true });\n for (const e of entries) {\n const full = path.join(dir, String(e.name));\n if (e.isDirectory()) {\n total += await dirSize(full);\n } else if (e.isFile()) {\n try {\n const s = await stat(full);\n total += s.size;\n } catch {\n // ignore\n }\n }\n }\n } catch {\n return 0;\n }\n return total;\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../asset-manager/src/index.ts"],"names":["parseYaml","stringifyYaml"],"mappings":"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","file":"chunk-7HSXUKNB.js","sourcesContent":["/**\n * @skaile/asset-manager — programmatic AI asset management API.\n *\n * Manages project-local repositories, dependency resolution, deployment,\n * lock files, patches, and contribution workflows.\n *\n * Usage:\n * import { AssetManager } from \"@skaile/workspaces/asset-manager\"\n * const am = new AssetManager({ projectDir: \"/path/to/project\" })\n * await am.install()\n */\n\nimport { spawnSync } from \"node:child_process\";\nimport {\n existsSync,\n lstatSync,\n readFileSync,\n readdirSync,\n rmSync,\n unlinkSync,\n writeFileSync,\n} from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join, resolve } from \"node:path\";\nimport { parse as parseYaml, stringify as stringifyYaml } from \"yaml\";\nimport type {\n AiComponent,\n CatalogEntry,\n LockFile,\n OverrideEntry,\n ProvenanceCandidate,\n SkWorkspaceConfig,\n SourceClone,\n SourceDeclaration,\n SourceEntry,\n StoreEntry,\n StoreFetcher,\n} from \"@skaile/workspaces/core\";\nimport type { DriverTarget } from \"@skaile/workspaces/core\";\nimport {\n buildProvenanceIndex,\n deployedBase,\n deployedDir,\n getRepoCommit,\n isDeployed,\n parseAssetRef,\n resolveRuntimeAssets,\n resolveSkWorkspaceConfig,\n} from \"@skaile/workspaces/core\";\nimport { buildLockFile, readLock, verifyLock, writeLock } from \"@skaile/workspaces/core\";\nimport {\n checkRepoStatus,\n ensureRepo,\n getGlobalCacheDir,\n readLinks,\n resolveAll,\n resolveAsset,\n scanRepo,\n} from \"@skaile/workspaces/core\";\nimport {\n extractForPatch,\n generatePatch,\n savePatch,\n applyPatch as coreApplyPatch,\n} from \"@skaile/workspaces/core\";\nimport type { DeployOptions } from \"./installer.js\";\nimport { createScaffold, deployAll, removeAsset } from \"./installer.js\";\nimport type { HistoryEntry } from \"./history.js\";\nimport { appendHistory, clearHistory, getRecentHistory } from \"./history.js\";\nimport { commitChanges } from \"./contrib.js\";\n\n/** Derive a cache slug from a source git URL (`<host>/<owner>/<repo>` → `<repo>`). */\nfunction sourceSlug(url: string): string {\n return (\n url\n .replace(/\\.git$/, \"\")\n .split(/[/:]/)\n .pop() ?? \"source\"\n );\n}\n\n/**\n * Parse a v2 canonical lock key (`<publisher>/<kind>:<name>@<version>`) into its\n * parts. Returns empty fields when the key is malformed.\n */\nfunction parseCanonicalLockKey(key: string): {\n publisher?: string;\n kind?: string;\n name?: string;\n version?: string;\n} {\n // <publisher>/<kind>:<name>@<version>\n const slash = key.indexOf(\"/\");\n const colon = key.indexOf(\":\", slash + 1);\n const at = key.lastIndexOf(\"@\");\n if (slash === -1 || colon === -1 || at === -1 || at < colon) return {};\n return {\n publisher: key.slice(0, slash),\n kind: key.slice(slash + 1, colon),\n name: key.slice(colon + 1, at),\n version: key.slice(at + 1),\n };\n}\n\n// Re-export sub-modules\nexport type { DeployOptions } from \"./installer.js\";\nexport type { Log } from \"./renderers.js\";\nexport type { HistoryEntry } from \"./history.js\";\nexport { createScaffold, deployAll, removeAsset } from \"./installer.js\";\nexport { renderAgentToFramework } from \"./renderers.js\";\nexport {\n appendHistory,\n clearHistory,\n getRecentHistory,\n loadHistory,\n} from \"./history.js\";\n// Contrib helpers (commitChanges et al.) are still used internally by the\n// patch-submit flow but are no longer part of the public API surface — the\n// `skaile repo contrib *` command tree was removed on 2026-05-12.\n\n// ── Types ────────────────────────────────────────────────────────────────────\n\n/**\n * Metadata about a repository declared in `skaile.yaml`.\n *\n * @docLink packages/asset-manager/concepts#asset-manager\n */\nexport interface RepoInfo {\n /** Repository name as declared in `skaile.yaml`. */\n name: string;\n /** How the repo is sourced: cloned from a URL, mounted from a local path, or symlinked via `skaile repo link`. */\n kind: \"local\" | \"remote\" | \"linked\";\n /** Remote URL (present when `kind === \"remote\"`). */\n url?: string;\n /** Filesystem path (present when `kind === \"local\"` or `kind === \"linked\"`). */\n path?: string;\n /** Git branch configured for this repository. */\n branch: string;\n /** Whether the repository has been cloned/resolved locally. */\n cloned: boolean;\n}\n\n/**\n * Live sync status for a repository.\n *\n * @docLink packages/asset-manager/concepts#asset-manager\n */\nexport interface RepoStatusInfo {\n /** Repository name as declared in `skaile.yaml`. */\n name: string;\n /** How the repo is sourced. */\n kind: \"local\" | \"remote\" | \"linked\";\n /** Number of commits the local clone is behind the remote. */\n behind: number;\n /** `true` when the local clone matches the remote HEAD. */\n upToDate: boolean;\n /** Error message when status check failed. */\n error?: string;\n}\n\n/**\n * Result of a full `skaile install` or `skaile add` run.\n *\n * @docLink packages/asset-manager/concepts#asset-manager\n */\nexport interface InstallResult {\n /** Asset refs (`kind:name`) successfully deployed in this run. */\n deployed: string[];\n /** Asset refs (`kind:name`) removed because they are no longer in the resolved set. */\n removed: string[];\n /** Asset refs that could not be resolved in any configured repository. */\n missing: string[];\n /** Whether `skaile.lock.yaml` was written or updated. */\n lockWritten: boolean;\n /**\n * npm packages installed as a side effect of resolving runtime asset peer\n * deps (connectors / mounts declared in skaile.yaml). Empty when nothing\n * needed installing or when the runtime-deps step was skipped.\n */\n npmInstalled?: string[];\n /**\n * npm packages that the runtime-deps step tried but failed to install.\n * Non-fatal — listed for telemetry and CLI reporting.\n */\n npmFailed?: string[];\n}\n\n/**\n * An installed asset whose source repository is behind the remote.\n *\n * @docLink packages/asset-manager/concepts#asset-manager\n */\nexport interface OutdatedEntry {\n /** Asset kind (`skill`, `agent`, `prompt`, `flow`, `contract`). */\n kind: string;\n /** Asset name as registered in the catalog. */\n name: string;\n /** Repository that provides this asset. */\n publisher: string;\n /** Version string recorded in the lock file at install time. */\n currentVersion: string;\n /** Number of commits the local repository is behind the remote. */\n behind: number;\n}\n\n/**\n * A node in the resolved dependency tree (returned by `AssetManager.tree()`).\n *\n * @docLink packages/asset-manager/concepts#asset-manager\n */\nexport interface DependencyNode {\n /** Asset ref (`kind:name`) or `\"project\"` for the root node. */\n ref: string;\n /** Transitive dependencies resolved by this node. */\n children: DependencyNode[];\n}\n\n/**\n * A missing dependency detected by `AssetManager.doctor()`.\n *\n * @docLink packages/asset-manager/concepts#asset-manager\n */\nexport interface DepIssue {\n /** Kind of the asset that has the unsatisfied requirement. */\n assetKind: string;\n /** Name of the asset that has the unsatisfied requirement. */\n assetName: string;\n /** Kind of the missing dependency. */\n depKind: string;\n /** Name of the missing dependency. */\n depName: string;\n /** `true` when the missing dependency exists in a configured repository but has not been installed. */\n inRepos: boolean;\n}\n\n/**\n * A single deployed asset shown in the workspace overview.\n *\n * @docLink packages/asset-manager/concepts#asset-manager\n */\nexport interface OverviewEntry {\n /** Asset kind (`skill`, `agent`, `prompt`, `flow`, `contract`). */\n kind: string;\n /** Asset name. */\n name: string;\n /** Domain the asset belongs to (from the lock file; `\"unknown\"` when unresolvable). */\n domain: string;\n /** Repository that provides this asset. */\n publisher: string;\n /** Version string from the lock file. */\n version: string;\n /**\n * Sync status relative to the source repository.\n * - `\"synced\"` — local clone matches remote HEAD\n * - `\"outdated\"` — local clone is behind the remote\n * - `\"local\"` — sourced from a local path, no remote to compare\n * - `\"error\"` — status check failed\n * - `\"unknown\"` — repository not found or lock entry missing\n */\n syncStatus: string;\n}\n\n/**\n * Aggregated workspace overview returned by `AssetManager.overview()`.\n *\n * @docLink packages/asset-manager/concepts#asset-manager\n */\nexport interface OverviewResult {\n /** Entries grouped by domain, sorted alphabetically. Each group is sorted by kind then name. */\n byDomain: Map<string, OverviewEntry[]>;\n /** Total number of deployed assets. */\n total: number;\n /** Sync status for each configured repository. */\n repos: RepoStatusInfo[];\n}\n\n// ── AssetManager ─────────────────────────────────────────────────────────────\n\n/**\n * Options for constructing an {@link AssetManager}.\n *\n * @docLink packages/asset-manager/concepts#asset-manager\n */\nexport interface AssetManagerOptions {\n /** Absolute or relative path to the workspace root (must contain `skaile.yaml`). */\n projectDir: string;\n /**\n * Agent framework to target for asset deployment.\n * Determines which framework directories (``.claude/``, ``.omp/``, etc.) are used.\n * Defaults to `\"claude-code\"`.\n */\n driverTarget?: DriverTarget;\n /**\n * When `true`, assets are installed into the global Skaile cache rather than the\n * project workspace. Skips `skaile.yaml` dependency updates.\n */\n global?: boolean;\n}\n\n/**\n * Programmatic API for managing AI assets in a Skaile workspace.\n *\n * `AssetManager` wraps repository management, catalog search, asset installation,\n * lock-file tracking, patch workflows, and workspace diagnostics. The CLI delegates\n * all `skaile catalog`, `skaile repo`, `skaile install`, `skaile add`, and\n * `skaile init` commands to this class.\n *\n * @example\n * ```typescript\n * import { AssetManager } from \"@skaile/workspaces/asset-manager\";\n *\n * const am = new AssetManager({ projectDir: \"/my-project\" });\n *\n * // Install all dependencies declared in skaile.yaml\n * const result = await am.install();\n * console.log(`Deployed: ${result.deployed.join(\", \")}`);\n *\n * // Add a single skill (resolves transitive deps, updates skaile.yaml)\n * const deployed = am.add(\"skill:my-skill\");\n *\n * // Search the catalog\n * const skills = am.search(\"code review\", \"skill\");\n * ```\n *\n * @docLink packages/asset-manager/concepts#asset-manager\n */\nexport class AssetManager {\n /** Resolved absolute path to the workspace root. */\n readonly projectDir: string;\n /** Agent framework driver target used for all deploy operations. */\n readonly driverTarget: DriverTarget;\n /** Whether this instance operates in global-install mode. */\n readonly global: boolean;\n\n constructor(opts: AssetManagerOptions) {\n this.projectDir = resolve(opts.projectDir);\n this.driverTarget = opts.driverTarget ?? (\"claude-code\" as DriverTarget);\n this.global = opts.global ?? false;\n }\n\n private get reposDir(): string {\n return join(this.projectDir, \".skaile\", \"repos\");\n }\n\n private get lockPath(): string {\n return join(this.projectDir, \"skaile.lock.yaml\");\n }\n\n private get patchDir(): string {\n return join(this.projectDir, \".skaile\", \"patches\");\n }\n\n private get deployOpts(): DeployOptions {\n return { driverTarget: this.driverTarget, global: this.global, cwd: this.projectDir };\n }\n\n private loadConfig(): {\n repositories: Record<string, SourceDeclaration>;\n sources: SourceEntry[];\n stores: StoreEntry[];\n dependencies: string[];\n overrides: OverrideEntry[];\n patches: Record<string, string>;\n config: SkWorkspaceConfig;\n } {\n // resolveSkWorkspaceConfig runs the canonical normalizer and throws on\n // legacy keys (`repositories:` / `ai_resources:`) — propagate to the caller.\n const config = resolveSkWorkspaceConfig(this.projectDir);\n\n const sources = config.sources ?? [];\n const stores = config.stores ?? [];\n const dependencies = config.dependencies ?? [];\n const overrides = config.overrides ?? [];\n const patches = config.patches ?? {};\n\n // Internal install-pipeline map: slug (derived from the source URL) →\n // SourceDeclaration pointing at the machine-cache clone under\n // ~/.skaile/sources/<slug>/. The slug is also the cache key for ensureRepo.\n const skaileHome = process.env.SKAILE_HOME ?? join(homedir(), \".skaile\");\n const sourcesDir = join(skaileHome, \"sources\");\n const repositories: Record<string, SourceDeclaration> = {};\n for (const s of sources) {\n const slug = sourceSlug(s.url);\n if (repositories[slug]) continue;\n repositories[slug] = { path: join(sourcesDir, slug), url: s.url };\n }\n\n return { repositories, sources, stores, dependencies, overrides, patches, config };\n }\n\n /** Build provenance-index clones from the resolved source declarations. */\n private buildClones(repositories: Record<string, SourceDeclaration>): SourceClone[] {\n const clones: SourceClone[] = [];\n for (const [slug, decl] of Object.entries(repositories)) {\n const localPath = this.resolveRepoDir(decl, slug);\n if (!localPath || !existsSync(localPath)) continue;\n const commit = getRepoCommit(localPath) ?? \"0\".repeat(40);\n clones.push({\n localPath,\n sourceUrl: decl.url ?? localPath,\n commit,\n tag: decl.branch,\n });\n }\n return clones;\n }\n\n /**\n * Bridge a resolved {@link ProvenanceCandidate} to a {@link CatalogEntry} for\n * the deploy pipeline. `source` is the absolute path to the asset's primary\n * manifest (or its directory) inside the clone; `publisher` is set to the\n * clone slug so `deployAll`'s repositories lookup resolves local-vs-remote.\n */\n private candidateToCatalogEntry(\n c: ProvenanceCandidate,\n repositories: Record<string, SourceDeclaration>,\n ): CatalogEntry | null {\n // Find the clone slug whose declaration URL matches the candidate's source.\n let slug: string | undefined;\n let cloneDir: string | undefined;\n for (const [s, decl] of Object.entries(repositories)) {\n if (decl.url === c.sourceUrl) {\n slug = s;\n cloneDir = this.resolveRepoDir(decl, s) ?? undefined;\n break;\n }\n }\n if (!cloneDir) {\n // Store-resolved or unknown source — fall back to the first source clone.\n const first = Object.entries(repositories)[0];\n if (first) {\n slug = first[0];\n cloneDir = this.resolveRepoDir(first[1], first[0]) ?? undefined;\n }\n }\n if (!cloneDir || !slug) return null;\n\n const MD_BY_KIND: Record<string, string> = {\n skill: \"SKILL.md\",\n agent: \"AGENT.md\",\n bundle: \"BUNDLE.md\",\n \"mcp-server\": \"MCP.md\",\n connector: \"CONNECTOR.md\",\n prompt: \"PROMPT.md\",\n contract: \"CONTRACT.md\",\n };\n const mdName = MD_BY_KIND[c.kind];\n const mdRel = c.files.find((f) => (mdName ? f.path.endsWith(mdName) : false))?.path;\n const source = mdRel ? join(cloneDir, mdRel) : cloneDir;\n\n return {\n name: c.name,\n kind: c.kind as CatalogEntry[\"kind\"],\n description: \"\",\n source,\n publisher: slug,\n version: c.version,\n requires: [],\n dependencies: [],\n metadata: c.metadata,\n };\n }\n\n // ── Install / resolve ──────────────────────────────────────────────────\n\n /**\n * Install all dependencies declared in `skaile.yaml`.\n *\n * Steps: clone/pull repositories → resolve transitive dependencies → reconcile\n * (remove stale assets) → deploy new assets → write `skaile.lock.yaml` → record history.\n *\n * @param opts - Optional installation options.\n * @param opts.locked - When `true`, restore the exact versions recorded in the existing\n * lock file instead of resolving from source. Throws if no lock file is found.\n * @returns {@link InstallResult} summarising what was deployed, what was missing, and any collisions.\n */\n async install(opts?: { locked?: boolean }): Promise<InstallResult> {\n const { repositories, sources, stores, dependencies, overrides, patches } = this.loadConfig();\n\n if (opts?.locked) {\n return this.installLocked(repositories, patches);\n }\n\n // 1. Ensure all source clones are present/up to date.\n const pinBySlug = new Map(sources.map((s) => [sourceSlug(s.url), s.pin]));\n for (const [name, decl] of Object.entries(repositories)) {\n try {\n ensureRepo(decl, name, this.reposDir, {\n projectDir: this.projectDir,\n pin: pinBySlug.get(name),\n });\n } catch (err) {\n return {\n deployed: [],\n removed: [],\n missing: [`source:${name} (${err instanceof Error ? err.message : String(err)})`],\n lockWritten: false,\n };\n }\n }\n\n // 2. Build the provenance index from the clones and resolve.\n const provenanceIndex = buildProvenanceIndex(this.buildClones(repositories), {\n projectDir: this.projectDir,\n });\n const { resolved, missing, overridesApplied } = await resolveAll(dependencies, {\n provenanceIndex,\n overrides,\n stores,\n storeFetcher: this.buildStoreFetcher(stores),\n projectDir: this.projectDir,\n });\n\n // 3. Reconcile: remove stale assets (in old lock but not in new resolved set).\n const oldLock = this.tryReadLock();\n const resolvedRefs = new Set(\n resolved.map((c) => `${c.publisher}/${c.kind}:${c.name}@${c.version}`),\n );\n const removed: string[] = [];\n if (oldLock) {\n for (const ref of Object.keys(oldLock.assets)) {\n if (!resolvedRefs.has(ref)) {\n const { kind, name } = parseCanonicalLockKey(ref);\n if (kind && name) {\n removeAsset(kind, name, this.deployOpts);\n removed.push(ref);\n }\n }\n }\n }\n\n // 4. Map candidates to catalog entries and deploy.\n const entries = resolved\n .map((c) => this.candidateToCatalogEntry(c, repositories))\n .filter((e): e is CatalogEntry => e !== null);\n const deployed = deployAll(entries, repositories, patches, this.deployOpts);\n\n // 5. Write the v2 lock file.\n writeLock(this.lockPath, buildLockFile(resolved, overridesApplied));\n\n // 6. Record history.\n for (const ref of deployed) {\n appendHistory(this.projectDir, {\n ref,\n action: \"add\",\n timestamp: new Date().toISOString(),\n context: this.global ? \"global\" : \"project\",\n });\n }\n for (const ref of removed) {\n appendHistory(this.projectDir, {\n ref,\n action: \"remove\",\n timestamp: new Date().toISOString(),\n context: this.global ? \"global\" : \"project\",\n });\n }\n\n // 7. Install npm peer deps for any mount/connector declared in skaile.yaml.\n const { npmInstalled, npmFailed } = await this.installRuntimeAssetDeps();\n\n return { deployed, removed, missing, lockWritten: true, npmInstalled, npmFailed };\n }\n\n /** Read the lock, returning null on a legacy v1 lock instead of throwing. */\n private tryReadLock(): LockFile | null {\n try {\n return readLock(this.lockPath);\n } catch {\n return null;\n }\n }\n\n /** Build a store fetcher from the configured stores, or undefined when none. */\n private buildStoreFetcher(stores: StoreEntry[]): StoreFetcher | undefined {\n if (stores.length === 0) return undefined;\n return {\n getInstallManifest: async (storeUrl, ref) => {\n const { RemoteCatalogSource, CatalogHttpError } = await import(\n \"@skaile/workspaces/library\"\n );\n const src = new RemoteCatalogSource({ baseUrl: storeUrl });\n try {\n const m = await src.getInstallManifest(ref);\n return {\n sourceUrl: m.source.url,\n commit: m.source.commitSha,\n sha256: m.sha256,\n files: m.files,\n };\n } catch (err) {\n if (err instanceof CatalogHttpError && err.status === 404) return null;\n throw err;\n }\n },\n getCanonicalDigest: async (storeUrl, ref) => {\n const { RemoteCatalogSource } = await import(\"@skaile/workspaces/library\");\n const src = new RemoteCatalogSource({ baseUrl: storeUrl });\n return src.getCanonicalDigest(ref);\n },\n };\n }\n\n /**\n * Resolve runtime assets and install any missing npm peer deps.\n *\n * - Required deps: installed via `bun add --optional`. Failure is recorded\n * in `npmFailed` but does not throw — install() proceeds so users get a\n * useful error message rather than a hung command.\n * - Optional deps: not installed automatically (would force every consumer\n * to pull every connector's deps). Future: add a flag to opt in.\n */\n private async installRuntimeAssetDeps(): Promise<{\n npmInstalled: string[];\n npmFailed: string[];\n }> {\n const npmInstalled: string[] = [];\n const npmFailed: string[] = [];\n let runtimeAssets: Awaited<ReturnType<typeof resolveRuntimeAssets>> | null = null;\n try {\n runtimeAssets = await resolveRuntimeAssets(this.projectDir);\n } catch {\n // Non-fatal — projects with no skaile.yaml or unresolvable base-assets\n // simply have no runtime deps to install.\n return { npmInstalled, npmFailed };\n }\n\n const required = runtimeAssets.requiredNpmDeps.required;\n if (required.length === 0) return { npmInstalled, npmFailed };\n\n const { findMissingPackages, installNpmPackages } = await import(\n \"@skaile/workspaces/connectors\"\n );\n const missing = findMissingPackages(required, this.projectDir);\n if (missing.length === 0) return { npmInstalled, npmFailed };\n\n const result = await installNpmPackages(missing, this.projectDir);\n if (result.success) {\n npmInstalled.push(...missing);\n } else {\n npmFailed.push(...missing);\n }\n return { npmInstalled, npmFailed };\n }\n\n private installLocked(\n repositories: Record<string, SourceDeclaration>,\n patches: Record<string, string>,\n ): InstallResult {\n const lock = this.tryReadLock();\n if (!lock) {\n throw new Error(\"No lock file found. Run `skaile install` first.\");\n }\n\n // Ensure every contributing source clone exists at its pinned commit. Sources\n // are keyed by URL slug; the lock's `sources[]` carries the URL + commit.\n const declBySlug = new Map(Object.entries(repositories));\n for (const src of lock.sources) {\n const slug = sourceSlug(src.url);\n const decl = declBySlug.get(slug) ?? { url: src.url };\n ensureRepo(decl, slug, this.reposDir, { projectDir: this.projectDir, pin: src.commit });\n }\n\n // Resolve a source URL to its on-disk clone for verification.\n const resolveCloneDir = (sourceUrl: string): string | null => {\n const slug = sourceSlug(sourceUrl);\n const decl = declBySlug.get(slug) ?? { url: sourceUrl };\n return this.resolveRepoDir(decl, slug);\n };\n\n // Verify integrity against the v2 lock.\n const verification = verifyLock(lock, resolveCloneDir);\n if (!verification.ok) {\n const issues = [\n ...verification.drifted.map((r) => `drifted: ${r}`),\n ...verification.missing.map((r) => `missing: ${r}`),\n ];\n throw new Error(`Lock file verification failed:\\n ${issues.join(\"\\n \")}`);\n }\n\n // Rebuild catalog entries from the lock and deploy.\n const resolved: CatalogEntry[] = [];\n for (const [ref, entry] of Object.entries(lock.assets)) {\n const { publisher, kind, name } = parseCanonicalLockKey(ref);\n if (!publisher || !kind || !name) continue;\n const slug = sourceSlug(entry.source.url);\n const cloneDir = resolveCloneDir(entry.source.url) ?? join(this.reposDir, slug);\n const mdRel =\n entry.files.find((f) => /\\.(md|yaml)$/i.test(f.path))?.path ?? entry.files[0]?.path ?? \"\";\n resolved.push({\n name,\n kind: kind as CatalogEntry[\"kind\"],\n description: \"\",\n source: mdRel ? join(cloneDir, mdRel) : cloneDir,\n publisher: slug,\n version: entry.source.commit,\n requires: [],\n dependencies: [],\n });\n // Ensure the repositories map has an entry for deployAll's local/remote check.\n if (!repositories[slug]) repositories[slug] = { url: entry.source.url, path: cloneDir };\n }\n\n const deployed = deployAll(resolved, repositories, patches, this.deployOpts);\n return { deployed, removed: [], missing: [], lockWritten: false };\n }\n\n /**\n * Add a single asset (and its transitive dependencies) to the workspace.\n *\n * Resolves `ref`, deploys the asset and all requirements, then records the ref\n * in `skaile.yaml` `dependencies` so subsequent `skaile install` runs re-deploy it.\n *\n * @param ref - Asset ref in `kind:name` or `repo/kind:name` form (e.g. `skill:my-skill`).\n * @returns Array of asset refs that were deployed in this call.\n * @throws When the asset cannot be found in any configured repository.\n */\n async add(ref: string): Promise<string[]> {\n const { repositories, stores, overrides, patches } = this.loadConfig();\n const parsed = parseAssetRef(ref);\n\n // Ensure clones.\n for (const [name, decl] of Object.entries(repositories)) {\n try {\n ensureRepo(decl, name, this.reposDir, { projectDir: this.projectDir });\n } catch {}\n }\n\n const provenanceIndex = buildProvenanceIndex(this.buildClones(repositories), {\n projectDir: this.projectDir,\n });\n const { resolved, missing } = await resolveAll([ref], {\n provenanceIndex,\n overrides,\n stores,\n storeFetcher: this.buildStoreFetcher(stores),\n projectDir: this.projectDir,\n });\n if (resolved.length === 0) {\n throw new Error(\n `Asset not found: ${ref}${missing.length ? ` (missing: ${missing.join(\", \")})` : \"\"}`,\n );\n }\n\n const entries = resolved\n .map((c) => this.candidateToCatalogEntry(c, repositories))\n .filter((e): e is CatalogEntry => e !== null);\n const deployed = deployAll(entries, repositories, patches, this.deployOpts);\n\n // Add to skaile.yaml dependencies (canonical ref string).\n this.addDependencyToConfig(ref);\n\n for (const d of deployed) {\n appendHistory(this.projectDir, {\n ref: d,\n action: \"add\",\n timestamp: new Date().toISOString(),\n context: this.global ? \"global\" : \"project\",\n });\n }\n\n return deployed;\n }\n\n /**\n * Remove a deployed asset and unregister it from `skaile.yaml`.\n *\n * @param ref - Asset ref in `kind:name` form (e.g. `skill:my-skill`).\n * @returns `true` if the asset was found and removed, `false` if it was not deployed.\n */\n remove(ref: string): boolean {\n const parsed = parseAssetRef(ref);\n const ok = removeAsset(parsed.kind, parsed.name, this.deployOpts);\n if (ok) {\n const depRef = `${parsed.kind}:${parsed.name}`;\n this.removeDependencyFromConfig(depRef);\n\n appendHistory(this.projectDir, {\n ref: depRef,\n action: \"remove\",\n timestamp: new Date().toISOString(),\n context: this.global ? \"global\" : \"project\",\n });\n }\n return ok;\n }\n\n // ── Query ──────────────────────────────────────────────────────────────\n\n /**\n * Search the catalog across all configured repositories.\n *\n * @param query - Substring to match against entry names and descriptions (case-insensitive).\n * Omit to return all entries.\n * @param kind - Filter by asset kind (`\"skill\"`, `\"agent\"`, `\"prompt\"`, `\"flow\"`, `\"contract\"`).\n * Omit to return all kinds.\n * @returns Array of matching {@link CatalogEntry} objects from all accessible repositories.\n */\n search(query?: string, kind?: string): CatalogEntry[] {\n const { repositories } = this.loadConfig();\n let all: CatalogEntry[] = [];\n\n for (const [name, decl] of Object.entries(repositories)) {\n const repoDir = this.resolveRepoDir(decl, name);\n if (!repoDir) continue;\n all = [...all, ...scanRepo(repoDir, name)];\n }\n\n if (kind) all = all.filter((e) => e.kind === kind);\n if (query) {\n const q = query.toLowerCase();\n all = all.filter(\n (e) => e.name.toLowerCase().includes(q) || e.description.toLowerCase().includes(q),\n );\n }\n return all;\n }\n\n /**\n * Look up a single asset's full catalog entry.\n *\n * @param ref - Asset ref in `kind:name` or `repo/kind:name` form.\n * @returns The matching {@link CatalogEntry}, or `null` when not found.\n */\n info(ref: string): CatalogEntry | null {\n const { repositories } = this.loadConfig();\n const parsed = parseAssetRef(ref);\n\n for (const [name, decl] of Object.entries(repositories)) {\n const repoDir = this.resolveRepoDir(decl, name);\n if (!repoDir) continue;\n if (parsed.publisher && parsed.publisher !== name) continue;\n const entries = scanRepo(repoDir, name);\n const match = entries.find((e) => e.kind === parsed.kind && e.name === parsed.name);\n if (match) return match;\n }\n return null;\n }\n\n /**\n * List all assets currently deployed in the workspace (or global cache).\n *\n * Scans the framework deploy directories rather than the lock file, so it\n * also returns assets that were installed manually or outside of `skaile install`.\n *\n * @param kind - Filter by asset kind. Omit to return all kinds.\n * @returns Shallow {@link CatalogEntry} objects (description and version will be empty).\n */\n listDeployed(kind?: string): CatalogEntry[] {\n // Bundles are dependency groups, not deployed as files — exclude from scan\n const kinds = (\n kind ? [kind] : [\"skill\", \"agent\", \"prompt\", \"flow\", \"contract\"]\n ) as AiComponent[];\n const result: CatalogEntry[] = [];\n const seen = new Set<string>();\n for (const k of kinds) {\n try {\n const base = deployedBase(k, this.driverTarget, this.global, this.projectDir);\n if (!existsSync(base)) continue;\n for (const item of readdirSync(base, { withFileTypes: true })) {\n // Directories and symlinks use the directory name directly (skills, omp agents, etc.)\n // Files use the stem without extension (claude-code agents → .md, codex agents → .toml,\n // prompts → .prompt.md, flows → .flow.yaml/.flow.json)\n let name: string;\n if (item.isDirectory() || item.isSymbolicLink()) {\n name = item.name;\n } else if (item.isFile()) {\n name = item.name\n .replace(/\\.prompt\\.md$/, \"\")\n .replace(/\\.flow\\.(yaml|json)$/, \"\")\n .replace(/\\.bundle\\.yaml$/, \"\")\n .replace(/\\.(md|toml|yaml|json)$/, \"\");\n } else {\n continue;\n }\n const key = `${k}:${name}`;\n if (seen.has(key)) continue;\n seen.add(key);\n result.push({\n name,\n kind: k as any,\n description: \"\",\n source: join(base, item.name),\n version: \"\",\n requires: [],\n dependencies: [],\n });\n }\n } catch {}\n }\n return result;\n }\n\n /**\n * Build an aggregated workspace overview with domain grouping and sync status.\n *\n * Combines deployed assets, lock file metadata, and live repository status\n * into a single structured result. Used by `skaile status`.\n *\n * @returns {@link OverviewResult} with entries grouped by domain and per-repo sync status.\n */\n overview(): OverviewResult {\n const { repositories } = this.loadConfig();\n const lock = this.tryReadLock();\n const deployed = this.listDeployed();\n\n // Get repo sync status\n const repoStatuses = new Map<string, RepoStatusInfo>();\n for (const [name, decl] of Object.entries(repositories)) {\n const status = checkRepoStatus(decl, name, this.reposDir);\n repoStatuses.set(name, {\n name,\n kind: status.kind,\n behind: status.behind,\n upToDate: status.upToDate,\n error: status.error,\n });\n }\n\n // Index lock entries by their <kind>:<name> suffix for deployed-asset lookup.\n const lockByKindName = new Map<string, { publisher: string; version: string; url: string }>();\n for (const [key] of Object.entries(lock?.assets ?? {})) {\n const parsed = parseCanonicalLockKey(key);\n if (parsed.kind && parsed.name && parsed.publisher && parsed.version) {\n lockByKindName.set(`${parsed.kind}:${parsed.name}`, {\n publisher: parsed.publisher,\n version: parsed.version,\n url: lock!.assets[key]!.source.url,\n });\n }\n }\n\n // Build entries with publisher + sync info. Domain grouping is by publisher\n // now that the lock no longer records a project-local domain.\n const entries: OverviewEntry[] = [];\n for (const d of deployed) {\n const lockEntry = lockByKindName.get(`${d.kind}:${d.name}`);\n const publisher = lockEntry?.publisher ?? \"\";\n const version = lockEntry?.version ?? \"\";\n const slug = lockEntry ? sourceSlug(lockEntry.url) : \"\";\n let syncStatus = \"unknown\";\n if (slug) {\n const repoStatus = repoStatuses.get(slug);\n if (!repoStatus) syncStatus = \"unknown\";\n else if (repoStatus.kind === \"local\") syncStatus = \"local\";\n else if (repoStatus.error) syncStatus = \"error\";\n else if (repoStatus.upToDate) syncStatus = \"synced\";\n else syncStatus = \"outdated\";\n }\n const domain = publisher || \"unknown\";\n entries.push({ kind: d.kind, name: d.name, domain, publisher, version, syncStatus });\n }\n\n // Group by domain (= publisher)\n const byDomain = new Map<string, OverviewEntry[]>();\n for (const e of entries) {\n if (!byDomain.has(e.domain)) byDomain.set(e.domain, []);\n byDomain.get(e.domain)!.push(e);\n }\n\n // Sort domains alphabetically, entries within domain by kind then name\n const sorted = new Map<string, OverviewEntry[]>();\n for (const key of [...byDomain.keys()].sort()) {\n sorted.set(\n key,\n byDomain\n .get(key)!\n .sort((a, b) =>\n a.kind !== b.kind ? a.kind.localeCompare(b.kind) : a.name.localeCompare(b.name),\n ),\n );\n }\n\n return {\n byDomain: sorted,\n total: entries.length,\n repos: [...repoStatuses.values()],\n };\n }\n\n /**\n * Build the resolved dependency tree from the lock file.\n *\n * @returns Root {@link DependencyNode} with `ref === \"project\"` whose children\n * are the directly-declared dependencies, each with their own transitive subtrees.\n * Returns a single node with `ref === \"(no lock file)\"` when no lock exists.\n */\n tree(): DependencyNode {\n const lock = this.tryReadLock();\n if (!lock) return { ref: \"(no lock file)\", children: [] };\n\n // v2 lock no longer records per-asset parent provenance — every locked asset\n // is shown as a direct child of the project (flat tree).\n return {\n ref: \"project\",\n children: Object.keys(lock.assets).map((ref) => ({ ref, children: [] })),\n };\n }\n\n /**\n * Explain why an asset is installed by tracing its dependency chain in the lock file.\n *\n * @param ref - Asset ref in `kind:name` form.\n * @returns Chain of refs from the asset back to `\"direct (skaile.yaml)\"`, or `[]` when\n * the asset is not in the lock file.\n */\n why(ref: string): string[] {\n const lock = this.tryReadLock();\n if (!lock) return [];\n if (!lock.assets[ref]) return []; // not in lock file\n // v2 lock no longer records a dep chain — every locked asset is reported as\n // directly declared. (Transitive provenance reconstruction is out of scope.)\n return [ref, \"direct (skaile.yaml)\"];\n }\n\n /**\n * List installed assets whose source repository is behind the remote.\n *\n * Only remote repositories (not local paths) are checked for staleness.\n *\n * @returns Array of {@link OutdatedEntry} objects, one per asset in a repository\n * that has commits not yet pulled locally.\n */\n outdated(): OutdatedEntry[] {\n const { repositories } = this.loadConfig();\n const lock = this.tryReadLock();\n if (!lock) return [];\n\n const result: OutdatedEntry[] = [];\n for (const src of lock.sources) {\n const slug = sourceSlug(src.url);\n const decl = repositories[slug];\n if (!decl || decl.path) continue; // skip unknown / local sources\n const status = checkRepoStatus(decl, slug, this.reposDir);\n if (status.behind <= 0) continue;\n for (const [ref, entry] of Object.entries(lock.assets)) {\n if (entry.source.url !== src.url) continue;\n const { publisher, kind, name, version } = parseCanonicalLockKey(ref);\n if (!kind || !name) continue;\n result.push({\n kind,\n name,\n publisher: publisher ?? slug,\n currentVersion: version ?? \"\",\n behind: status.behind,\n });\n }\n }\n return result;\n }\n\n /**\n * Produce a unified diff between the deployed asset and its catalog source.\n *\n * Useful for detecting manual edits to deployed files or verifying that a patch\n * was applied correctly.\n *\n * @param ref - Asset ref in `kind:name` form.\n * @returns Unified diff string, or `null` when there are no differences or the\n * asset is not deployed/resolvable.\n */\n diff(ref: string): string | null {\n const parsed = parseAssetRef(ref);\n const entry = this.info(ref);\n if (!entry) return null;\n\n const deployedPath = join(\n deployedBase(parsed.kind as AiComponent, this.driverTarget, this.global, this.projectDir),\n parsed.name,\n );\n if (!existsSync(deployedPath) || !existsSync(entry.source)) return null;\n\n const r = spawnSync(\"diff\", [\"-ruN\", entry.source, deployedPath], { encoding: \"utf8\" });\n return r.status === 1 ? r.stdout : null;\n }\n\n // ── Lock ───────────────────────────────────────────────────────────────\n\n /**\n * Resolve all declared dependencies and write (or overwrite) `skaile.lock.yaml`.\n *\n * Performs repository sync and full dependency resolution without deploying assets.\n * Use this to regenerate the lock file after manually editing `skaile.yaml`.\n *\n * @returns The written {@link LockFile} data.\n */\n async lock(): Promise<LockFile> {\n const { repositories, stores, dependencies, overrides } = this.loadConfig();\n\n for (const [name, decl] of Object.entries(repositories)) {\n try {\n ensureRepo(decl, name, this.reposDir, { projectDir: this.projectDir });\n } catch {}\n }\n\n const provenanceIndex = buildProvenanceIndex(this.buildClones(repositories), {\n projectDir: this.projectDir,\n });\n const { resolved, overridesApplied } = await resolveAll(dependencies, {\n provenanceIndex,\n overrides,\n stores,\n storeFetcher: this.buildStoreFetcher(stores),\n projectDir: this.projectDir,\n });\n const lockData = buildLockFile(resolved, overridesApplied);\n writeLock(this.lockPath, lockData);\n return lockData;\n }\n\n // ── Patch workflow ─────────────────────────────────────────────────────\n\n /**\n * Extract a deployed asset into a patch working directory for editing.\n *\n * Copies the deployed asset to `.skaile/patches/<kind>-<name>/` so changes\n * can be made there and then committed as a patch file via `patchCommit`.\n *\n * @param ref - Asset ref in `kind:name` form.\n * @returns Absolute path to the patch working directory.\n * @throws When the asset cannot be found in the catalog.\n */\n patch(ref: string): string {\n const entry = this.info(ref);\n if (!entry) throw new Error(`Asset not found: ${ref}`);\n return extractForPatch(entry, this.patchDir);\n }\n\n /**\n * Generate a `.patch` file from changes made in the patch working directory.\n *\n * Diffs the patch working directory against the original catalog source and\n * writes the result to `.skaile/patches/<kind>-<name>.patch`.\n *\n * @param ref - Asset ref in `kind:name` form.\n * @returns Absolute path to the generated `.patch` file.\n * @throws When the patch working directory does not exist or no differences are found.\n */\n patchCommit(ref: string): string {\n const parsed = parseAssetRef(ref);\n const entry = this.info(ref);\n if (!entry) throw new Error(`Asset not found: ${ref}`);\n\n const patchedDir = join(this.patchDir, `${parsed.kind}-${parsed.name}`);\n if (!existsSync(patchedDir)) {\n throw new Error(`No patch working dir found. Run \\`skaile patch ${ref}\\` first.`);\n }\n\n const originalDir = dirname(entry.source);\n const content = generatePatch(originalDir, patchedDir);\n if (!content) throw new Error(\"No differences found.\");\n\n const patchFile = join(this.patchDir, `${parsed.kind}-${parsed.name}.patch`);\n savePatch(patchFile, content);\n return patchFile;\n }\n\n /**\n * Apply the committed patch file to the repository clone and open a contribution branch.\n *\n * Applies `.skaile/patches/<kind>-<name>.patch` to the repository clone, creates a\n * `patch/<kind>-<name>` branch, and stages a commit — ready to push via `contribPush`.\n *\n * @param ref - Asset ref in `kind:name` form.\n * @throws When the asset is not found, has no repository, or the patch file is missing.\n */\n patchSubmit(ref: string): void {\n const parsed = parseAssetRef(ref);\n const entry = this.info(ref);\n if (!entry?.publisher) throw new Error(`Asset not found or no publisher: ${ref}`);\n\n const { repositories } = this.loadConfig();\n const decl = repositories[entry.publisher];\n if (!decl?.url) throw new Error(\"Can only submit patches for remote sources.\");\n\n const repoDir = join(this.reposDir, entry.publisher);\n const branchName = `patch/${parsed.kind}-${parsed.name}`;\n\n // Apply patch to repo clone\n const patchFile = join(this.patchDir, `${parsed.kind}-${parsed.name}.patch`);\n if (!existsSync(patchFile)) throw new Error(\"No patch file. Run `skaile patch-commit` first.\");\n\n coreApplyPatch(repoDir, patchFile);\n commitChanges(repoDir, `fix: improve ${parsed.kind} ${parsed.name}`, branchName);\n }\n\n /**\n * Delete the patch working directory and patch file for an asset.\n *\n * @param ref - Asset ref in `kind:name` form.\n */\n patchRemove(ref: string): void {\n const parsed = parseAssetRef(ref);\n const patchFile = join(this.patchDir, `${parsed.kind}-${parsed.name}.patch`);\n const patchedDir = join(this.patchDir, `${parsed.kind}-${parsed.name}`);\n try {\n rmSync(patchFile);\n } catch {}\n try {\n rmSync(patchedDir, { recursive: true });\n } catch {}\n }\n\n // ── Doctor ─────────────────────────────────────────────────────────────\n\n /**\n * Scan deployed assets for unsatisfied transitive dependencies.\n *\n * For each deployed asset, checks that all entries in its `requires` list are\n * also deployed. Returns a list of issues with a flag indicating whether the\n * missing dependency can be resolved from a configured repository.\n *\n * @returns Array of {@link DepIssue} objects. An empty array means the workspace is healthy.\n */\n doctor(): DepIssue[] {\n const { repositories } = this.loadConfig();\n const deployed = this.listDeployed();\n const issues: DepIssue[] = [];\n\n for (const entry of deployed) {\n const full = this.info(`${entry.kind}:${entry.name}`);\n if (!full) continue;\n for (const req of full.requires) {\n if (\n !isDeployed(\n req.kind as AiComponent,\n req.name,\n this.driverTarget,\n this.global,\n this.projectDir,\n )\n ) {\n const inRepos =\n resolveAsset({ kind: req.kind, name: req.name }, repositories, this.reposDir) !== null;\n issues.push({\n assetKind: entry.kind,\n assetName: entry.name,\n depKind: req.kind,\n depName: req.name,\n inRepos,\n });\n }\n }\n }\n return issues;\n }\n\n // ── Scaffold ───────────────────────────────────────────────────────────\n\n /**\n * Create a minimal asset scaffold directory (delegates to {@link createScaffold}).\n *\n * @param name - Asset name (also used as the directory name).\n * @param kind - Asset kind: `skill` | `agent` | `bundle` | `flow` | `prompt` | `contract`.\n * @param destDir - Parent directory to create the asset in.\n * @returns `{ ok: true, path }` on success, `{ ok: false, path: errorMessage }` if the\n * directory already exists.\n */\n create(name: string, kind: string, destDir: string): { ok: boolean; path: string } {\n return createScaffold(name, kind, destDir);\n }\n\n // ── Contrib (REMOVED 2026-05-12) ───────────────────────────────────────\n //\n // The `contribChanges / contribDiff / contribCommit / contribPush /\n // contribCompare` methods were retired alongside `skaile repo contrib *`.\n // The refinement push-back workflow is being re-introduced in Phase 4 as\n // `skaile publish` + `skaile preset push` against the Library Source model.\n\n // ── History ────────────────────────────────────────────────────────────\n\n /**\n * Return recent asset action history entries, newest first.\n *\n * @param limit - Maximum number of entries to return. Defaults to `20`.\n * @returns Array of {@link HistoryEntry} objects in reverse-chronological order.\n */\n history(limit = 20): HistoryEntry[] {\n return getRecentHistory(this.projectDir, limit);\n }\n\n /**\n * Erase all asset action history for this workspace.\n */\n clearHistory(): void {\n clearHistory(this.projectDir);\n }\n\n // ── Clean ───────────────────────────────────────────────────────────────\n\n /**\n * Remove deployed assets tracked by the lock file and report unmanaged ones.\n *\n * With `opts.all`, also deletes `.skaile/history.yaml`, `.skaile/patches/`,\n * `.skaile/repos/`, and `skaile.lock.yaml` — effectively resetting the workspace\n * to a pre-install state.\n *\n * @param opts - Optional cleanup options.\n * @param opts.all - When `true`, remove all Skaile-managed state in addition to deployed assets.\n * @returns Object with `removed` (successfully cleaned refs), `skipped` (with reasons),\n * and `unmanaged` (deployed assets not in the lock file).\n */\n clean(opts?: { all?: boolean }): {\n removed: string[];\n skipped: Array<{ ref: string; reason: string }>;\n unmanaged: string[];\n } {\n const lock = this.tryReadLock();\n const removed: string[] = [];\n const skipped: Array<{ ref: string; reason: string }> = [];\n\n if (lock) {\n for (const ref of Object.keys(lock.assets)) {\n const { kind, name } = parseCanonicalLockKey(ref);\n if (!kind || !name) continue;\n const dest = deployedDir(\n kind as AiComponent,\n name,\n this.driverTarget,\n this.global,\n this.projectDir,\n );\n\n try {\n const stat = lstatSync(dest);\n if (stat.isSymbolicLink()) unlinkSync(dest);\n else rmSync(dest, { recursive: true, force: true });\n removed.push(ref);\n } catch {\n // Already gone — count as removed\n removed.push(ref);\n }\n }\n }\n\n // Collect unmanaged assets for reporting. Deployed assets are keyed by\n // <kind>:<name>; map lock canonical refs to that shape for comparison.\n const lockRefs = lock\n ? new Set(\n Object.keys(lock.assets).map((r) => {\n const p = parseCanonicalLockKey(r);\n return p.kind && p.name ? `${p.kind}:${p.name}` : r;\n }),\n )\n : new Set<string>();\n const unmanaged: string[] = [];\n const allDeployed = this.listDeployed();\n for (const d of allDeployed) {\n const ref = `${d.kind}:${d.name}`;\n if (!lockRefs.has(ref)) {\n unmanaged.push(ref);\n }\n }\n\n if (opts?.all) {\n // Delete history file\n const historyFile = join(this.projectDir, \".skaile\", \"history.yaml\");\n try {\n unlinkSync(historyFile);\n } catch {}\n\n // Remove patches dir\n try {\n rmSync(this.patchDir, { recursive: true, force: true });\n } catch {}\n\n // Remove repos dir\n try {\n rmSync(this.reposDir, { recursive: true, force: true });\n } catch {}\n\n // Remove lock file\n try {\n unlinkSync(this.lockPath);\n } catch {}\n }\n\n return { removed, skipped, unmanaged };\n }\n\n // ── Helpers ────────────────────────────────────────────────────────────\n\n /** Add a dependency ref to skaile.yaml if not already present. */\n private addDependencyToConfig(ref: string): void {\n if (this.global) return; // global installs don't modify skaile.yaml\n const configPath = join(this.projectDir, \"skaile.yaml\");\n if (!existsSync(configPath)) return;\n const raw = parseYaml(readFileSync(configPath, \"utf8\")) ?? {};\n if (!raw.dependencies) raw.dependencies = [];\n if (!raw.dependencies.includes(ref)) {\n raw.dependencies.push(ref);\n writeFileSync(configPath, stringifyYaml(raw, { lineWidth: 120 }));\n }\n }\n\n /** Remove a dependency ref from skaile.yaml. */\n private removeDependencyFromConfig(ref: string): void {\n if (this.global) return;\n const configPath = join(this.projectDir, \"skaile.yaml\");\n if (!existsSync(configPath)) return;\n const raw = parseYaml(readFileSync(configPath, \"utf8\")) ?? {};\n if (!raw.dependencies) return;\n const idx = raw.dependencies.indexOf(ref);\n if (idx !== -1) {\n raw.dependencies.splice(idx, 1);\n writeFileSync(configPath, stringifyYaml(raw, { lineWidth: 120 }));\n }\n }\n\n private resolveRepoDir(decl: SourceDeclaration, name: string): string | null {\n // Check links first\n const links = readLinks(this.projectDir);\n if (links[name]) {\n return existsSync(links[name]) ? links[name] : null;\n }\n\n if (decl.path) {\n const resolved = resolve(this.projectDir, decl.path);\n return existsSync(resolved) ? resolved : null;\n }\n\n // Check project-local symlink, then global cache\n const dest = join(this.reposDir, name);\n if (existsSync(dest)) return dest;\n\n const globalDest = join(getGlobalCacheDir(), name);\n if (existsSync(join(globalDest, \".git\"))) return globalDest;\n\n return null;\n }\n}\n\n// ── Agent install (renders GitAgent packages to framework-native files) ──\n\nexport { installAgent } from \"./install-agent.js\";\n\n// ── Renderers ─────────────────────────────────────────────────────────────\n\nexport {\n AGENT_RENDERERS,\n claudeCodeRenderer,\n codexRenderer,\n driverTargetSupportsAgents,\n ompRenderer,\n} from \"./renderers.js\";\nexport type { AgentRenderer, AgentRenderInput, AgentRenderResult } from \"./renderers.js\";\n\n// ── Fragments ─────────────────────────────────────────────────────────────\n\nexport type {\n AbilityRef,\n ConnectorRef,\n ContractRef,\n FragmentContext,\n FragmentId,\n} from \"./fragments.js\";\nexport { BUILT_IN_FRAGMENTS, resolveFragments, loadPromptExtensions } from \"./fragments.js\";\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../core/src/lock.ts","../core/src/patch.ts","../core/src/settings.ts","../core/src/subprocess.ts","../core/src/workspace-yaml-editor.ts"],"names":["join","existsSync","writeFileSync","readFileSync","spawnSync","path"],"mappings":"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","file":"chunk-ETMUGBHF.js","sourcesContent":["/**\n * Lock file I/O and integrity verification (schema v2).\n *\n * The lock file (skaile.lock.yaml) captures the complete resolved state: every\n * asset keyed by its canonical ref `<publisher>/<kind>:<name>@<version>`, the\n * upstream source + commit it resolved from, a per-file + composite content\n * hash for drift detection, and whether an `overrides[]` entry pinned it. A\n * top-level `sources:` block records every contributing source URL at its\n * resolved commit.\n *\n * Old v1 lockfiles (`lockfile_version: 1`, `repositories:`) are rejected with a\n * clear regenerate-from-scratch error.\n */\n\nimport { createHash } from \"node:crypto\";\nimport { existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { parse, stringify } from \"yaml\";\nimport type {\n LockEntry,\n LockFile,\n LockPluginEntry,\n LockSourceEntry,\n} from \"./models.js\";\nimport type { ProvenanceCandidate } from \"./walker.js\";\n\n// ── Lock file I/O ────────────────────────────────────────────────────────────\n\n/**\n * Serialize a `LockFile` to YAML and write it to disk.\n *\n * @param lockPath - Absolute path to write the lock file (e.g. `skaile.lock.yaml`)\n * @param data - Lock file data to serialize\n * @docLink packages/core/api-reference#write-lock\n */\nexport function writeLock(lockPath: string, data: LockFile): void {\n writeFileSync(lockPath, stringify(data, { lineWidth: 120 }));\n}\n\n/**\n * Read and parse a lock file from disk.\n *\n * @param lockPath - Absolute path to the lock file\n * @returns Parsed `LockFile`, or `null` if the file is missing or unparseable\n * @throws When the file is a legacy v1 lock — the shape changed and it must be regenerated.\n * @docLink packages/core/api-reference#read-lock\n */\nexport function readLock(lockPath: string): LockFile | null {\n if (!existsSync(lockPath)) return null;\n let raw: unknown;\n try {\n raw = parse(readFileSync(lockPath, \"utf8\"));\n } catch {\n return null;\n }\n if (!raw || typeof raw !== \"object\") return null;\n const r = raw as Record<string, unknown>;\n if (r.schema_version !== 2) {\n throw new Error(\n \"lockfile schema v1 detected. The lockfile shape changed in \" +\n \"@skaile/workspaces 4.x. Regenerate: `rm skaile.lock.yaml && skaile install`.\",\n );\n }\n return r as unknown as LockFile;\n}\n\n// ── Hashing ──────────────────────────────────────────────────────────────────\n\n/**\n * Compute the SHA-256 hash of a file's content (hex digest, no prefix).\n *\n * @param filePath - Absolute path to the file\n * @returns Hex-encoded SHA-256 hash string\n * @docLink packages/core/api-reference#compute-hash\n */\nexport function computeHash(filePath: string): string {\n const content = readFileSync(filePath);\n return createHash(\"sha256\").update(content).digest(\"hex\");\n}\n\n/**\n * Composite hash: SHA-256 (bare 64-hex) over `localeCompare`-sorted\n * `<path>:<sha256>\\n` rows. Matches the walker's `compositeSha256`, the store's\n * `computeCompositeSha256`, and the `InstallManifest.sha256` rollup.\n */\nexport function compositeHash(files: Array<{ path: string; sha256: string }>): string {\n const lines = files\n .slice()\n .sort((a, b) => a.path.localeCompare(b.path))\n .map((f) => `${f.path}:${f.sha256}\\n`)\n .join(\"\");\n return createHash(\"sha256\").update(lines).digest(\"hex\");\n}\n\n// ── Lock file construction ───────────────────────────────────────────────────\n\n/**\n * Build a v2 `LockFile` from the resolver's output.\n *\n * Assets are keyed by canonical ref `<publisher>/<kind>:<name>@<version>`; the\n * top-level `sources:` block lists every contributing source URL pinned to its\n * resolved commit.\n *\n * @param resolved - Resolved provenance candidates (the resolver's `resolved` array).\n * @param overridesApplied - Canonical refs that an `overrides[]` entry pinned.\n * @returns Complete v2 `LockFile` ready for serialization.\n * @docLink packages/core/api-reference#build-lock-file\n */\nexport function buildLockFile(\n resolved: ProvenanceCandidate[],\n overridesApplied: Set<string>,\n): LockFile {\n const assets: Record<string, LockEntry> = {};\n const sourceMap = new Map<string, LockSourceEntry>();\n\n for (const c of resolved) {\n const canonicalRef = `${c.publisher}/${c.kind}:${c.name}@${c.version}`;\n assets[canonicalRef] = {\n sha256: c.sha256,\n source: { url: c.sourceUrl, commit: c.commit },\n files: c.files,\n override_applied: overridesApplied.has(canonicalRef),\n };\n if (!sourceMap.has(c.sourceUrl)) {\n sourceMap.set(c.sourceUrl, { url: c.sourceUrl, commit: c.commit });\n }\n }\n\n return {\n schema_version: 2,\n locked_at: new Date().toISOString(),\n assets,\n sources: Array.from(sourceMap.values()).sort((a, b) => a.url.localeCompare(b.url)),\n };\n}\n\n// ── Plugins slice ────────────────────────────────────────────────────────────\n\n/** Absolute path to a project's lock file. */\nfunction lockPathFor(projectDir: string): string {\n return join(projectDir, \"skaile.lock.yaml\");\n}\n\n/**\n * Read the `plugins` slice from a project's `skaile.lock.yaml`.\n *\n * Total — never throws on a missing/unparseable/legacy lock file (returns\n * `undefined`). The plugin-store reconciler folds this into its reconcile-hash\n * so a lock edit invalidates the hash even without a manifest change.\n *\n * @param projectDir - Project root containing `skaile.lock.yaml`\n * @returns The `plugins` record, or `undefined` when absent\n */\nexport function readPluginsLockSlice(\n projectDir: string,\n): Record<string, LockPluginEntry> | undefined {\n try {\n return readLock(lockPathFor(projectDir))?.plugins;\n } catch {\n // Legacy v1 lock — no usable plugins slice.\n return undefined;\n }\n}\n\n/**\n * Merge a `plugins` slice into a project's `skaile.lock.yaml`, preserving all\n * other fields. Creates a minimal v2 lock file when none exists (or the\n * existing one is a legacy v1 that can't be read).\n *\n * @param projectDir - Project root containing `skaile.lock.yaml`\n * @param slice - The `plugins` record to persist\n */\nexport function writePluginsLockSlice(\n projectDir: string,\n slice: Record<string, LockPluginEntry>,\n): void {\n const lockPath = lockPathFor(projectDir);\n let existing: LockFile | null = null;\n try {\n existing = readLock(lockPath);\n } catch {\n existing = null; // legacy v1 — overwrite with a fresh v2 shell\n }\n const next: LockFile = existing ?? {\n schema_version: 2,\n locked_at: new Date().toISOString(),\n assets: {},\n sources: [],\n };\n next.plugins = slice;\n writeLock(lockPath, next);\n}\n\n// ── Verification ─────────────────────────────────────────────────────────────\n\n/**\n * Result of verifying a lock file against the current repository state.\n * @docLink packages/core/api-reference#verify-result\n */\nexport interface VerifyResult {\n /** `true` when no drift or missing assets were found. */\n ok: boolean;\n /** Canonical refs whose content hash no longer matches. */\n drifted: string[];\n /** Canonical refs whose files cannot be found on disk. */\n missing: string[];\n}\n\n/**\n * Verify a v2 lock file against the current on-disk source clones.\n *\n * For each locked asset, resolve its source clone directory via `resolveCloneDir`\n * (URL → on-disk path), re-hash the recorded files, and compare the recomputed\n * composite against the locked `sha256`. Reports assets whose hash changed\n * (`drifted`) and assets whose files are missing (`missing`).\n *\n * @param lock - Previously generated v2 `LockFile`.\n * @param resolveCloneDir - Maps a source URL to its on-disk clone root (or null).\n * @returns `VerifyResult` indicating drift and missing assets.\n * @docLink packages/core/api-reference#verify-lock\n */\nexport function verifyLock(\n lock: LockFile,\n resolveCloneDir: (sourceUrl: string) => string | null,\n): VerifyResult {\n const drifted: string[] = [];\n const missing: string[] = [];\n\n for (const [ref, entry] of Object.entries(lock.assets)) {\n const cloneDir = resolveCloneDir(entry.source.url);\n if (!cloneDir) {\n missing.push(ref);\n continue;\n }\n let allPresent = true;\n const recomputed: Array<{ path: string; sha256: string }> = [];\n for (const f of entry.files) {\n const abs = join(cloneDir, f.path);\n if (!existsSync(abs)) {\n allPresent = false;\n break;\n }\n recomputed.push({ path: f.path, sha256: computeHash(abs) });\n }\n if (!allPresent) {\n missing.push(ref);\n continue;\n }\n if (compositeHash(recomputed) !== entry.sha256) {\n drifted.push(ref);\n }\n }\n\n return { ok: drifted.length === 0 && missing.length === 0, drifted, missing };\n}\n","/**\n * Patch operations — extract, generate, apply patches for skill improvement.\n *\n * Patches allow editing deployed assets from remote repos and contributing\n * changes back upstream via PR.\n */\n\nimport { spawnSync } from \"node:child_process\";\nimport { cpSync, existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { basename, dirname, join } from \"node:path\";\nimport type { CatalogEntry } from \"./models.js\";\n\n/**\n * Copy an asset's source directory into a patch working directory for editing.\n *\n * @param entry - The catalog entry to extract\n * @param patchDir - Base directory where extracted copies are placed\n * @returns Absolute path to the extracted copy (`<patchDir>/<kind>-<name>`)\n * @docLink packages/core/api-reference#extract-for-patch\n */\nexport function extractForPatch(entry: CatalogEntry, patchDir: string): string {\n const ref = `${entry.kind}-${entry.name}`;\n const dest = join(patchDir, ref);\n mkdirSync(dest, { recursive: true });\n\n // Copy the asset's source directory (or file) to the patch dir\n const sourceDir = dirname(entry.source);\n const sourceName = basename(entry.source);\n\n // If source is a file in a directory (e.g., skills/overview/SKILL.md), copy the whole dir\n if (existsSync(sourceDir)) {\n cpSync(sourceDir, dest, { recursive: true });\n }\n\n return dest;\n}\n\n/**\n * Generate a unified diff between an original and patched directory using `diff -ruN`.\n *\n * @param originalDir - Unmodified copy of the asset directory\n * @param patchedDir - Modified copy of the asset directory\n * @returns Patch content string, or `null` if there are no differences (or on error)\n * @docLink packages/core/api-reference#generate-patch\n */\nexport function generatePatch(originalDir: string, patchedDir: string): string | null {\n const r = spawnSync(\"diff\", [\"-ruN\", originalDir, patchedDir], {\n encoding: \"utf8\",\n stdio: \"pipe\",\n });\n\n // diff returns 0 if no differences, 1 if differences, 2 on error\n if (r.status === 0) return null; // no differences\n if (r.status === 1) return r.stdout;\n return null; // error\n}\n\n/**\n * Apply a unified diff patch file to a directory using `patch -p1`.\n *\n * @param targetDir - Directory to apply the patch to\n * @param patchFile - Path to the `.patch` file\n * @returns `true` on success, `false` if the patch file is missing or the command fails\n * @docLink packages/core/api-reference#apply-patch\n */\nexport function applyPatch(targetDir: string, patchFile: string): boolean {\n if (!existsSync(patchFile)) return false;\n const r = spawnSync(\"patch\", [\"-p1\", \"-d\", targetDir, \"-i\", patchFile], {\n stdio: \"pipe\",\n });\n return r.status === 0;\n}\n\n/**\n * Return the paths of all `.patch` files in a directory.\n *\n * @param patchDir - Directory to scan for `.patch` files\n * @returns Array of absolute paths; empty array when `patchDir` does not exist\n * @docLink packages/core/api-reference#list-patches\n */\nexport function listPatches(patchDir: string): string[] {\n if (!existsSync(patchDir)) return [];\n return readdirSync(patchDir)\n .filter((f) => f.endsWith(\".patch\"))\n .map((f) => join(patchDir, f));\n}\n\n/**\n * Write patch content to a file, creating parent directories as needed.\n *\n * @param patchPath - Destination file path (including `.patch` extension)\n * @param content - Unified diff content to write\n * @docLink packages/core/api-reference#save-patch\n */\nexport function savePatch(patchPath: string, content: string): void {\n mkdirSync(dirname(patchPath), { recursive: true });\n writeFileSync(patchPath, content, \"utf8\");\n}\n\n/**\n * Read the content of a patch file.\n *\n * @param patchPath - Path to the `.patch` file\n * @returns File content as a string, or `null` if the file does not exist\n * @docLink packages/core/api-reference#read-patch\n */\nexport function readPatch(patchPath: string): string | null {\n if (!existsSync(patchPath)) return null;\n return readFileSync(patchPath, \"utf8\");\n}\n","/**\n * User-layer runtime settings.\n *\n * SkaileSettings represents the personal, machine-specific overrides stored in\n * .skaile/settings.json (gitignored). Project-level defaults (framework, agent\n * definition, resource connections, hooks) belong in skaile.yaml via SkWorkspaceConfig.\n *\n * Resolution order (highest priority first):\n * 1. CLI flags / API overrides\n * 2. Environment variables (API keys only)\n * 3. .skaile/settings.json (project-local, walking upward)\n * 4. ~/.skaile/settings.json (user global)\n * 5. skaile.yaml defaults: (via resolveSkWorkspaceConfig — no duplicate YAML parser)\n * 6. Built-in SETTINGS_DEFAULTS\n */\n\nimport fs from \"node:fs\";\nimport fsp from \"node:fs/promises\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { resolveSkWorkspaceConfig } from \"./workspace-config.js\";\n\n// ── Types ──────────────────────────────────────────────────────────────────\n\n/**\n * All supported LLM and voice provider identifiers.\n * @docLink packages/core/settings#all-providers\n */\nexport const ALL_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\n/**\n * Union of supported LLM and voice provider identifiers.\n * @docLink packages/core/settings#provider\n */\nexport type Provider = (typeof ALL_PROVIDERS)[number];\n\n/**\n * Personal runtime settings — stored in .skaile/settings.json (gitignored).\n * Contains only user-specific overrides: credentials, preferred model/driver.\n *\n * Project-level config (framework, resources, hooks, agent definition) lives\n * in skaile.yaml as SkWorkspaceConfig. App-specific fields (voice, domains)\n * are added by forge-common-backend via AppSettings.\n * @docLink packages/core/settings#skaile-settings\n */\nexport interface SkaileSettings {\n /** Active LLM provider identifier (e.g. \"anthropic\", \"openai\"). */\n provider?: string;\n /** Active model identifier (e.g. \"claude-sonnet-4-6\"). */\n model?: string;\n /** Bridge driver to use: \"omp\", \"claude-sdk\", or \"codex\". */\n driver?: string;\n /** API keys keyed by provider identifier. Merged with env-var keys at resolution time. */\n apiKeys?: Record<string, string>;\n /** Framework install path overrides. Normally derived from skaile.yaml defaults. */\n skillsDir?: string;\n /** Override for the agents directory. Normally derived from skaile.yaml defaults. */\n agentsDir?: string;\n /** Override for the prompts directory. Normally derived from skaile.yaml defaults. */\n promptsDir?: string;\n /** AI Asset Store API URL (default: https://store.skaile.ai) */\n storeUrl?: string;\n /** JWT access token for the AI Asset Store */\n storeJwt?: string;\n /** Refresh token for JWT renewal */\n storeRefreshToken?: string;\n}\n\n/**\n * Built-in default settings. Lowest-priority layer in resolveSettings().\n * Override via .skaile/settings.json, ~/.skaile/settings.json, or env vars.\n * @docLink packages/core/settings#settings-defaults\n */\nexport const SETTINGS_DEFAULTS: SkaileSettings = {\n apiKeys: {},\n driver: \"omp\",\n provider: \"anthropic\",\n model: \"claude-sonnet-4-6\",\n};\n\n// ── Legacy field mapping ───────────────────────────────────────────────────\n\nconst LEGACY_FIELD_MAP: Record<string, keyof SkaileSettings> = {\n defaultProvider: \"provider\",\n defaultModel: \"model\",\n defaultAgentType: \"driver\",\n};\n\n/**\n * Rename legacy field names in a raw parsed settings object to their current equivalents.\n * Maps `defaultProvider` → `provider`, `defaultModel` → `model`, `defaultAgentType` → `driver`.\n *\n * @param raw - Raw object from JSON.parse of a settings file\n * @returns Settings with legacy keys renamed to current ones\n * @docLink packages/core/settings#map-legacy-fields\n */\nexport function mapLegacyFields(raw: Record<string, unknown>): SkaileSettings {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(raw)) {\n const mapped = LEGACY_FIELD_MAP[key];\n if (mapped) {\n if (!(mapped in result) || result[mapped] == null) result[mapped] = value;\n } else {\n result[key] = value;\n }\n }\n return result as SkaileSettings;\n}\n\n// ── Paths ──────────────────────────────────────────────────────────────────\n\nconst SKAILE_DIR = \".skaile\";\nconst SETTINGS_FILE = \"settings.json\";\n\n/**\n * Return the path to the user-global settings file: `~/.skaile/settings.json`.\n * @docLink packages/core/settings#global-settings-path\n */\nexport function globalSettingsPath(): string {\n return path.join(os.homedir(), SKAILE_DIR, SETTINGS_FILE);\n}\n\n/**\n * Return the path to the project-local settings file: `<projectDir>/.skaile/settings.json`.\n *\n * @param projectDir - Absolute path to the project root\n * @returns Absolute path to the project settings file\n * @docLink packages/core/settings#project-settings-path\n */\nexport function projectSettingsPath(projectDir: string): string {\n return path.join(projectDir, SKAILE_DIR, SETTINGS_FILE);\n}\n\n// ── I/O ────────────────────────────────────────────────────────────────────\n\n/**\n * Load and parse a settings JSON file, merging over SETTINGS_DEFAULTS.\n * Returns defaults if the file does not exist or cannot be parsed.\n *\n * @param filePath - Absolute path to a settings.json file\n * @returns Parsed settings merged with built-in defaults\n * @docLink packages/core/settings#load-settings\n */\nexport async function loadSettings(filePath: string): Promise<SkaileSettings> {\n try {\n const raw = await fsp.readFile(filePath, \"utf-8\");\n return { ...SETTINGS_DEFAULTS, ...mapLegacyFields(JSON.parse(raw)) };\n } catch {\n return { ...SETTINGS_DEFAULTS };\n }\n}\n\n/**\n * Persist settings to a JSON file, creating parent directories as needed.\n *\n * @param settings - Settings object to serialize\n * @param filePath - Absolute path to write the settings.json file\n * @docLink packages/core/settings#save-settings\n */\nexport async function saveSettings(settings: SkaileSettings, filePath: string): Promise<void> {\n await fsp.mkdir(path.dirname(filePath), { recursive: true });\n await fsp.writeFile(filePath, JSON.stringify(settings, null, 2), \"utf-8\");\n}\n\n/**\n * Walk upward from `projectDir` (max 10 levels) and collect all\n * `.skaile/settings.json` paths found along the way.\n * Results are ordered nearest-to-root first.\n *\n * @param projectDir - Starting directory for the upward walk\n * @returns Array of absolute paths to settings files found\n * @docLink packages/core/settings#walk-for-settings\n */\nexport function walkForSettings(projectDir: string): string[] {\n const found: string[] = [];\n let dir = path.resolve(projectDir);\n const root = path.parse(dir).root;\n for (let i = 0; i < 10; i++) {\n const candidate = path.join(dir, SKAILE_DIR, SETTINGS_FILE);\n if (fs.existsSync(candidate)) found.push(candidate);\n const parent = path.dirname(dir);\n if (parent === dir || parent === root) break;\n dir = parent;\n }\n return found;\n}\n\n// ── Resolution ─────────────────────────────────────────────────────────────\n\nfunction mergeSettings(base: SkaileSettings, source: Partial<SkaileSettings>): SkaileSettings {\n const result = { ...base };\n for (const [key, value] of Object.entries(source)) {\n if (value !== undefined && value !== null && value !== \"\") {\n if (key === \"apiKeys\" && typeof value === \"object\") {\n result.apiKeys = { ...result.apiKeys, ...(value as Record<string, string>) };\n } else {\n (result as any)[key] = value;\n }\n }\n }\n return result;\n}\n\n/** Derive a SkaileSettings-compatible layer from SkWorkspaceConfig agent_config.default. */\nfunction settingsFromWorkspaceConfig(projectDir: string): SkaileSettings {\n try {\n const ws = resolveSkWorkspaceConfig(projectDir);\n // Read agent_config.default\n const p = ws.agent_config?.default;\n if (!p) return {};\n const result: SkaileSettings = {};\n if (p.driver) result.driver = p.driver;\n if (p.provider) result.provider = p.provider;\n if (p.model) result.model = p.model;\n if (p.skills_dir) result.skillsDir = p.skills_dir;\n if (p.agents_dir) result.agentsDir = p.agents_dir;\n if (p.prompts_dir) result.promptsDir = p.prompts_dir;\n return result;\n } catch {\n return {};\n }\n}\n\n// ── Migration ──────────────────────────────────────────────────────────────\n\nconst _migrated = new Set<string>();\n\n/**\n * One-time migration from old config locations to .skaile/settings.json.\n * Does not delete old files — user can do that manually.\n * @docLink packages/core/settings#migrate-settings\n */\nexport async function migrateSettings(projectDir: string): Promise<void> {\n const resolved = path.resolve(projectDir);\n if (_migrated.has(resolved)) return;\n\n const targetPath = projectSettingsPath(resolved);\n if (fs.existsSync(targetPath)) {\n _migrated.add(resolved);\n return;\n }\n\n const sources: Record<string, unknown>[] = [];\n\n // Old location 1: data/settings.json (forge-project)\n const dataSettings = path.join(resolved, \"data\", \"settings.json\");\n if (fs.existsSync(dataSettings)) {\n try {\n sources.push(JSON.parse(fs.readFileSync(dataSettings, \"utf-8\")));\n } catch {}\n }\n\n // Old location 2: .cf/settings.json (forge-concept)\n const cfSettings = path.join(resolved, \".cf\", \"settings.json\");\n if (fs.existsSync(cfSettings)) {\n try {\n sources.push(JSON.parse(fs.readFileSync(cfSettings, \"utf-8\")));\n } catch {}\n }\n\n // Old location 3: .skaile/config.json (old SkailConfig)\n const oldConfig = path.join(resolved, \".skaile\", \"config.json\");\n if (fs.existsSync(oldConfig)) {\n try {\n sources.push(JSON.parse(fs.readFileSync(oldConfig, \"utf-8\")));\n } catch {}\n }\n\n if (sources.length > 0) {\n let merged: SkaileSettings = {};\n for (const source of sources) {\n merged = mergeSettings(merged, mapLegacyFields(source as Record<string, unknown>));\n }\n await saveSettings(merged, targetPath);\n }\n\n _migrated.add(resolved);\n}\n\n/**\n * Resolve effective settings through the 6-layer priority chain:\n * overrides > env vars (PREFERRED_PROVIDER, PREFERRED_MODEL, *_API_KEY) >\n * .skaile/settings.json (walks upward) > ~/.skaile/settings.json >\n * skaile.yaml agent_config defaults > SETTINGS_DEFAULTS.\n *\n * @param projectDir - Root directory of the project being operated on\n * @param overrides - Optional top-priority overrides (CLI flags, API body)\n * @returns Merged effective settings\n * @docLink packages/core/settings#resolve-settings\n */\nexport async function resolveSettings(\n projectDir: string,\n overrides?: Partial<SkaileSettings>,\n): Promise<SkaileSettings> {\n await migrateSettings(projectDir);\n\n // Base: built-in defaults\n let merged: SkaileSettings = { ...SETTINGS_DEFAULTS };\n\n // Layer: workspace config defaults (skaile.yaml via resolveSkWorkspaceConfig)\n merged = mergeSettings(merged, settingsFromWorkspaceConfig(projectDir));\n\n // Layer: user global settings\n const globalPath = globalSettingsPath();\n if (fs.existsSync(globalPath)) {\n try {\n const raw = JSON.parse(fs.readFileSync(globalPath, \"utf-8\"));\n merged = mergeSettings(merged, mapLegacyFields(raw));\n } catch {}\n }\n\n // Layer: project-local .skaile/settings.json (walking upward, farthest first)\n const settingsFiles = walkForSettings(projectDir);\n for (const filePath of settingsFiles.reverse()) {\n if (path.resolve(filePath) === path.resolve(globalPath)) continue;\n try {\n const raw = JSON.parse(fs.readFileSync(filePath, \"utf-8\"));\n merged = mergeSettings(merged, mapLegacyFields(raw));\n } catch {}\n }\n\n // Layer: environment variables (API keys + preferred provider/model)\n const envKeys = detectEnvApiKeys();\n if (Object.keys(envKeys).length > 0) {\n merged.apiKeys = { ...merged.apiKeys, ...envKeys };\n }\n if (process.env.PREFERRED_PROVIDER) merged.provider = process.env.PREFERRED_PROVIDER;\n if (process.env.PREFERRED_MODEL) merged.model = process.env.PREFERRED_MODEL;\n\n // Layer: explicit overrides\n if (overrides) merged = mergeSettings(merged, overrides);\n\n return merged;\n}\n\n// ── Provider / API key helpers ─────────────────────────────────────────────\n\n/**\n * Return the environment variable name for a provider's API key.\n * e.g. `providerEnvKey('anthropic')` → `'ANTHROPIC_API_KEY'`\n *\n * @param provider - Provider identifier (e.g. \"anthropic\", \"openai\")\n * @returns Environment variable name for that provider's API key\n * @docLink packages/core/settings#provider-env-key\n */\nexport function providerEnvKey(provider: string): string {\n return `${provider.toUpperCase().replace(/[^A-Z0-9]/g, \"_\")}_API_KEY`;\n}\n\n/**\n * Return the active API key for the given provider.\n * The matching environment variable (`*_API_KEY`) takes priority over\n * the value stored in `settings.apiKeys`.\n *\n * @param provider - Provider identifier (e.g. \"anthropic\")\n * @param settings - Current effective settings\n * @returns API key string, or undefined if not configured\n * @docLink packages/core/settings#resolve-api-key\n */\nexport function resolveApiKey(provider: string, settings: SkaileSettings): string | undefined {\n return process.env[providerEnvKey(provider)] || settings.apiKeys?.[provider];\n}\n\n/**\n * Return a masked version of an API key for safe logging.\n * Shows only the last four characters (e.g. `'****abc1'`).\n *\n * @param key - Raw API key to mask\n * @returns Masked key string, or empty string if key is falsy\n * @docLink packages/core/settings#mask-api-key\n */\nexport function maskApiKey(key: string): string {\n return key ? `****${key.slice(-4)}` : \"\";\n}\n\n/**\n * An API key resolved with information about where it came from.\n * @docLink packages/core/settings#resolved-key\n */\nexport interface ResolvedKey {\n /** Masked API key value (last 4 chars visible). */\n key: string;\n /** Whether the key came from an environment variable or stored settings. */\n source: \"env\" | \"stored\";\n}\n\n/**\n * Scan process.env (plus any `extraEnv` overrides) for recognized API key\n * variables and return them as a partial `apiKeys` record keyed by provider id.\n *\n * @param extraEnv - Additional environment entries to merge over process.env\n * @returns Partial apiKeys record containing only providers whose key was found\n * @docLink packages/core/settings#detect-env-api-keys\n */\nexport function detectEnvApiKeys(extraEnv?: Record<string, string>): Record<string, string> {\n const env = { ...process.env, ...extraEnv };\n const detected: Record<string, string> = {};\n for (const provider of ALL_PROVIDERS) {\n const val = env[providerEnvKey(provider)];\n if (val) detected[provider] = val;\n }\n return detected;\n}\n\n/**\n * Build a resolved key map for all known providers with source info and masked values.\n * Env-var keys take priority over stored keys when both exist.\n *\n * @param settings - Current effective settings (provides stored apiKeys)\n * @param envKeys - Keys detected from environment (e.g. from detectEnvApiKeys())\n * @returns Map from provider id to resolved key info; omits providers with no key\n * @docLink packages/core/settings#resolve-all-keys\n */\nexport function resolveAllKeys(\n settings: SkaileSettings,\n envKeys: Record<string, string>,\n): Record<string, ResolvedKey> {\n const result: Record<string, ResolvedKey> = {};\n for (const provider of ALL_PROVIDERS) {\n const envVal = envKeys[provider];\n const storedVal = settings.apiKeys?.[provider];\n if (envVal) {\n result[provider] = { key: maskApiKey(envVal), source: \"env\" };\n } else if (storedVal) {\n result[provider] = { key: maskApiKey(storedVal), source: \"stored\" };\n }\n }\n return result;\n}\n","/**\n * Runtime-portable subprocess spawning.\n *\n * `node:child_process` is implemented by both Node and Bun, so it is the\n * portable choice — no runtime detection needed (unlike embedded SQLite,\n * which has no shared API; see `logging/sinks/sqlite-runtime.ts`).\n *\n * These helpers wrap `node:child_process` to present a `Bun.Subprocess`-shaped\n * result — web `ReadableStream` stdio plus an `exited` promise — so call sites\n * migrated off `Bun.spawn` keep their stream-reading code unchanged.\n */\nimport { spawn, spawnSync } from \"node:child_process\";\nimport { Readable } from \"node:stream\";\n\nexport interface PortableSpawnOptions {\n cwd?: string;\n env?: Record<string, string | undefined>;\n detached?: boolean;\n}\n\n/** A spawned process with stdout/stderr piped. Mirrors the shape of `Bun.Subprocess`. */\nexport interface PortableSubprocess {\n /** OS process id, or -1 if the process failed to spawn. */\n readonly pid: number;\n readonly stdout: ReadableStream<Uint8Array>;\n readonly stderr: ReadableStream<Uint8Array>;\n /** Resolves with the exit code once the process closes (-1 on spawn error). */\n readonly exited: Promise<number>;\n kill(signal?: number | NodeJS.Signals): void;\n}\n\nexport interface PortableSpawnSyncResult {\n /** Exit code; -1 when the process did not exit cleanly. */\n exitCode: number;\n stdout: string;\n stderr: string;\n}\n\n/**\n * Spawn a subprocess with stdout/stderr piped. Works under Node and Bun.\n *\n * @param cmd - Command and arguments, e.g. `[\"docker\", \"ps\"]`.\n */\nexport function portableSpawn(cmd: string[], opts: PortableSpawnOptions = {}): PortableSubprocess {\n const [bin, ...args] = cmd;\n if (!bin) throw new Error(\"portableSpawn: empty command\");\n const child = spawn(bin, args, {\n cwd: opts.cwd,\n env: opts.env ?? process.env,\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n detached: opts.detached,\n });\n const exited = new Promise<number>((resolve) => {\n child.on(\"close\", (code) => resolve(code ?? 0));\n child.on(\"error\", () => resolve(-1));\n });\n return {\n pid: child.pid ?? -1,\n stdout: Readable.toWeb(child.stdout as Readable) as unknown as ReadableStream<Uint8Array>,\n stderr: Readable.toWeb(child.stderr as Readable) as unknown as ReadableStream<Uint8Array>,\n exited,\n kill: (signal) => {\n if (opts.detached && child.pid) {\n try {\n process.kill(-child.pid, signal);\n return;\n } catch {\n /* fall back to killing the direct child */\n }\n }\n child.kill(signal);\n },\n };\n}\n\n/**\n * Run a subprocess to completion synchronously, capturing stdout/stderr as\n * UTF-8 strings. Works under Node and Bun.\n *\n * @param cmd - Command and arguments, e.g. `[\"docker\", \"info\"]`.\n */\nexport function portableSpawnSync(\n cmd: string[],\n opts: PortableSpawnOptions = {},\n): PortableSpawnSyncResult {\n const [bin, ...args] = cmd;\n if (!bin) throw new Error(\"portableSpawnSync: empty command\");\n const result = spawnSync(bin, args, {\n cwd: opts.cwd,\n env: opts.env ?? process.env,\n encoding: \"utf8\",\n });\n return {\n exitCode: result.status ?? -1,\n stdout: result.stdout ?? \"\",\n stderr: result.stderr ?? \"\",\n };\n}\n","/**\n * Comment-preserving editor for skaile.yaml files.\n *\n * Uses the `yaml` library's Document API to parse into an AST that retains\n * comments, blank lines, and formatting. Mutations are applied to the AST\n * and serialized back — untouched sections remain byte-identical.\n *\n * Usage:\n *\n * import { WorkspaceYamlEditor } from '@skaile/workspaces/core'\n *\n * const editor = WorkspaceYamlEditor.load('/project/skaile.yaml')\n * editor.setAgentConfig('default', { driver: 'claude-sdk', model: 'claude-sonnet-4-6' })\n * editor.setSource({ url: 'https://github.com/skaile-ai/ai-assets' })\n * editor.save()\n */\n\nimport { existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { Document, isMap, isSeq, parseDocument, type YAMLMap } from \"yaml\";\nimport type {\n AgentConfigProfile,\n AssetEntry,\n ConnectorDeclaration,\n OverrideEntry,\n SourceEntry,\n StoreEntry,\n} from \"./workspace-config.js\";\n\n/**\n * Comment-preserving editor for `skaile.yaml` files.\n * Uses the `yaml` library's Document AST so untouched sections remain byte-identical.\n * Create with `WorkspaceYamlEditor.load(filePath)` or `WorkspaceYamlEditor.create(filePath)`.\n * @docLink packages/core/workspace-config#workspace-yaml-editor\n */\nexport class WorkspaceYamlEditor {\n readonly path: string;\n private doc: Document;\n\n private constructor(path: string, doc: Document) {\n this.path = path;\n this.doc = doc;\n }\n\n /** Load an existing skaile.yaml file. */\n static load(filePath: string): WorkspaceYamlEditor {\n if (!existsSync(filePath)) {\n throw new Error(`File not found: ${filePath}`);\n }\n const raw = readFileSync(filePath, \"utf-8\");\n const doc = parseDocument(raw);\n return new WorkspaceYamlEditor(filePath, doc);\n }\n\n /** Create a new empty document (for use when no file exists yet). */\n static create(filePath: string): WorkspaceYamlEditor {\n const doc = new Document({});\n return new WorkspaceYamlEditor(filePath, doc);\n }\n\n /** Write the document back to disk, preserving comments and formatting. */\n save(): void {\n writeFileSync(this.path, this.doc.toString());\n }\n\n /** Return the serialized YAML string without writing to disk. */\n toString(): string {\n return this.doc.toString();\n }\n\n // ── Scalar fields ──────────────────────────────────────────────────────────\n\n /** Get a top-level scalar field (name, description). */\n get(key: \"name\" | \"description\"): string | undefined {\n const val = this.doc.get(key);\n return val != null ? String(val) : undefined;\n }\n\n /** Set a top-level scalar field. */\n set(key: \"name\" | \"description\", value: string): void {\n this.doc.set(key, value);\n }\n\n // ── Agent config ──────────────────────────────────────────────────────────\n\n /**\n * Get an agent config profile by name (usually \"default\").\n * Reads from `agent-config` (canonical YAML key).\n */\n getAgentConfig(profile = \"default\"): AgentConfigProfile | undefined {\n const section = this._getAgentConfigSection();\n if (!section) return undefined;\n const val = section.get(profile);\n return val && typeof val === \"object\" ? (val as unknown as AgentConfigProfile) : undefined;\n }\n\n /**\n * Set fields on an agent config profile. Merges with existing values —\n * only the provided fields are overwritten.\n */\n setAgentConfig(profile: string, values: Partial<AgentConfigProfile>): void {\n let section = this._getAgentConfigSection();\n if (!section) {\n // Create the section. Use 'agent-config' as the canonical YAML key.\n this.doc.set(\"agent-config\", { [profile]: {} });\n section = this._getAgentConfigSection()!;\n }\n\n const existing = section.get(profile, true);\n if (!existing || !isMap(existing)) {\n section.set(profile, { ...values });\n return;\n }\n\n for (const [k, v] of Object.entries(values)) {\n if (v === undefined) continue;\n existing.set(k, v);\n }\n }\n\n /**\n * Delete a field from an agent config profile.\n */\n deleteAgentConfigField(profile: string, field: string): void {\n const section = this._getAgentConfigSection();\n if (!section) return;\n const profileNode = section.get(profile, true);\n if (isMap(profileNode)) {\n profileNode.delete(field);\n }\n }\n\n private _getAgentConfigSection(): YAMLMap | undefined {\n // Try canonical 'agent-config' first, then 'agent_config'\n const node = this.doc.get(\"agent-config\", true) ?? this.doc.get(\"agent_config\", true);\n return isMap(node) ? (node as YAMLMap) : undefined;\n }\n\n // ── Publisher / version (publication half) ──────────────────────────────────\n\n /** Get the publication-half `publisher:` field. */\n getPublisher(): string | undefined {\n const v = this.doc.get(\"publisher\");\n return v != null ? String(v) : undefined;\n }\n\n /** Set the publication-half `publisher:` field. */\n setPublisher(p: string): void {\n this.doc.set(\"publisher\", p);\n }\n\n /** Get the publication-half `version:` field. */\n getVersion(): string | undefined {\n const v = this.doc.get(\"version\");\n return v != null ? String(v) : undefined;\n }\n\n /** Set the publication-half `version:` field. */\n setVersion(v: string): void {\n this.doc.set(\"version\", v);\n }\n\n // ── Connectors ─────────────────────────────────────────────────────────────\n\n /** Get all connectors. */\n getConnectors(): ConnectorDeclaration[] {\n const val = this.doc.get(\"connectors\") ?? this.doc.get(\"data_resources\");\n if (!Array.isArray(val)) return [];\n return val as ConnectorDeclaration[];\n }\n\n /** Add or update a connector by id. */\n setConnector(connector: ConnectorDeclaration): void {\n const key = \"connectors\";\n const node = this.doc.get(key, true);\n\n if (!node || !isSeq(node)) {\n this.doc.set(key, this.doc.createNode([connector]));\n return;\n }\n\n let found = false;\n for (let i = 0; i < node.items.length; i++) {\n const item = node.items[i];\n if (isMap(item) && (item as YAMLMap).get(\"id\") === connector.id) {\n node.set(i, this.doc.createNode(connector));\n found = true;\n break;\n }\n }\n\n if (!found) {\n node.add(this.doc.createNode(connector));\n }\n }\n\n /** Remove a connector by id. */\n removeConnector(id: string): boolean {\n const key = this.doc.has(\"connectors\") ? \"connectors\" : \"data_resources\";\n const node = this.doc.get(key, true);\n if (!node || !isSeq(node)) return false;\n\n for (let i = 0; i < node.items.length; i++) {\n const item = node.items[i];\n if (isMap(item) && (item as YAMLMap).get(\"id\") === id) {\n node.delete(i);\n return true;\n }\n }\n return false;\n }\n\n // ── Plugins ────────────────────────────────────────────────────────────────\n\n /** Get all `plugins:` specifiers. */\n getPlugins(): string[] {\n const node = this.doc.get(\"plugins\", true);\n if (!isSeq(node)) return [];\n const out: string[] = [];\n for (const item of node.items) {\n const cur = item != null && typeof item === \"object\" && \"value\" in item ? item.value : item;\n if (typeof cur === \"string\") out.push(cur);\n }\n return out;\n }\n\n /**\n * Add a plugin specifier to `plugins:`, deduped by package name.\n * If an entry with the same package name exists it is replaced (so a version\n * bump re-pins in place); otherwise the spec is appended.\n *\n * @param spec - npm specifier, e.g. `\"@skaile/provider-fly@^0.1.0\"`.\n * @param nameOf - Extracts the package name from a spec (caller passes `parseSpec`-derived names).\n * @returns `true` when an existing entry was replaced, `false` when appended.\n */\n addPlugin(spec: string, nameOf: (s: string) => string): boolean {\n const node = this.doc.get(\"plugins\", true);\n if (!node || !isSeq(node)) {\n this.doc.set(\"plugins\", this.doc.createNode([spec]));\n return false;\n }\n\n const wantName = nameOf(spec);\n for (let i = 0; i < node.items.length; i++) {\n const item = node.items[i];\n const cur = item != null && typeof item === \"object\" && \"value\" in item ? item.value : item;\n if (typeof cur === \"string\" && nameOf(cur) === wantName) {\n node.set(i, this.doc.createNode(spec));\n return true;\n }\n }\n node.add(this.doc.createNode(spec));\n return false;\n }\n\n /**\n * Remove the `plugins:` entry whose package name matches `name`.\n *\n * @param name - Package name to remove (e.g. `\"@skaile/provider-fly\"`).\n * @param nameOf - Extracts the package name from a spec.\n * @returns `true` when an entry was removed.\n */\n removePlugin(name: string, nameOf: (s: string) => string): boolean {\n const node = this.doc.get(\"plugins\", true);\n if (!node || !isSeq(node)) return false;\n\n for (let i = 0; i < node.items.length; i++) {\n const item = node.items[i];\n const cur = item != null && typeof item === \"object\" && \"value\" in item ? item.value : item;\n if (typeof cur === \"string\" && nameOf(cur) === name) {\n node.delete(i);\n return true;\n }\n }\n return false;\n }\n\n // ── Sources ────────────────────────────────────────────────────────────────\n\n /** Get all source entries (`{url, pin?}`). */\n getSources(): SourceEntry[] {\n const val = this.doc.get(\"sources\");\n if (!Array.isArray(val)) return [];\n return val as SourceEntry[];\n }\n\n /**\n * Add or update a source entry, matched by `url`.\n * If an entry with the same url exists, it is replaced.\n */\n setSource(entry: SourceEntry): void {\n const node = this.doc.get(\"sources\", true);\n if (!node || !isSeq(node)) {\n this.doc.set(\"sources\", this.doc.createNode([entry]));\n return;\n }\n let found = false;\n for (let i = 0; i < node.items.length; i++) {\n const item = node.items[i];\n if (isMap(item) && (item as YAMLMap).get(\"url\") === entry.url) {\n node.set(i, this.doc.createNode(entry));\n found = true;\n break;\n }\n }\n if (!found) node.add(this.doc.createNode(entry));\n }\n\n /** Remove a source entry by url. Returns true when an entry was removed. */\n removeSource(url: string): boolean {\n const node = this.doc.get(\"sources\", true);\n if (!node || !isSeq(node)) return false;\n for (let i = 0; i < node.items.length; i++) {\n const item = node.items[i];\n if (isMap(item) && (item as YAMLMap).get(\"url\") === url) {\n node.delete(i);\n return true;\n }\n }\n return false;\n }\n\n // ── Stores ─────────────────────────────────────────────────────────────────\n\n /** Get all store entries (`{url}`). */\n getStores(): StoreEntry[] {\n const val = this.doc.get(\"stores\");\n if (!Array.isArray(val)) return [];\n return val as StoreEntry[];\n }\n\n /** Add or update a store entry, matched by `url`. */\n setStore(entry: StoreEntry): void {\n const node = this.doc.get(\"stores\", true);\n if (!node || !isSeq(node)) {\n this.doc.set(\"stores\", this.doc.createNode([entry]));\n return;\n }\n let found = false;\n for (let i = 0; i < node.items.length; i++) {\n const item = node.items[i];\n if (isMap(item) && (item as YAMLMap).get(\"url\") === entry.url) {\n node.set(i, this.doc.createNode(entry));\n found = true;\n break;\n }\n }\n if (!found) node.add(this.doc.createNode(entry));\n }\n\n /** Remove a store entry by url. Returns true when an entry was removed. */\n removeStore(url: string): boolean {\n const node = this.doc.get(\"stores\", true);\n if (!node || !isSeq(node)) return false;\n for (let i = 0; i < node.items.length; i++) {\n const item = node.items[i];\n if (isMap(item) && (item as YAMLMap).get(\"url\") === url) {\n node.delete(i);\n return true;\n }\n }\n return false;\n }\n\n // ── Overrides ────────────────────────────────────────────────────────────────\n\n /** Get all override entries (`{ref, source, reason}`). */\n getOverrides(): OverrideEntry[] {\n const val = this.doc.get(\"overrides\");\n if (!Array.isArray(val)) return [];\n return val as OverrideEntry[];\n }\n\n /** Add or update an override entry, matched by `ref`. */\n setOverride(entry: OverrideEntry): void {\n const node = this.doc.get(\"overrides\", true);\n if (!node || !isSeq(node)) {\n this.doc.set(\"overrides\", this.doc.createNode([entry]));\n return;\n }\n let found = false;\n for (let i = 0; i < node.items.length; i++) {\n const item = node.items[i];\n if (isMap(item) && (item as YAMLMap).get(\"ref\") === entry.ref) {\n node.set(i, this.doc.createNode(entry));\n found = true;\n break;\n }\n }\n if (!found) node.add(this.doc.createNode(entry));\n }\n\n /** Remove an override entry by ref. Returns true when an entry was removed. */\n removeOverride(ref: string): boolean {\n const node = this.doc.get(\"overrides\", true);\n if (!node || !isSeq(node)) return false;\n for (let i = 0; i < node.items.length; i++) {\n const item = node.items[i];\n if (isMap(item) && (item as YAMLMap).get(\"ref\") === ref) {\n node.delete(i);\n return true;\n }\n }\n return false;\n }\n\n // ── Publication assets ───────────────────────────────────────────────────────\n\n /** Get all publication-half `assets:` entries. */\n getPublicationAssets(): AssetEntry[] {\n const val = this.doc.get(\"assets\");\n if (!Array.isArray(val)) return [];\n return val as AssetEntry[];\n }\n\n /** Add or update a publication asset entry, matched by `kind` + `name`. */\n setPublicationAsset(entry: AssetEntry): void {\n const node = this.doc.get(\"assets\", true);\n if (!node || !isSeq(node)) {\n this.doc.set(\"assets\", this.doc.createNode([entry]));\n return;\n }\n let found = false;\n for (let i = 0; i < node.items.length; i++) {\n const item = node.items[i];\n if (\n isMap(item) &&\n (item as YAMLMap).get(\"kind\") === entry.kind &&\n (item as YAMLMap).get(\"name\") === entry.name\n ) {\n node.set(i, this.doc.createNode(entry));\n found = true;\n break;\n }\n }\n if (!found) node.add(this.doc.createNode(entry));\n }\n\n /** Remove a publication asset entry by kind + name. Returns true when removed. */\n removePublicationAsset(kind: string, name: string): boolean {\n const node = this.doc.get(\"assets\", true);\n if (!node || !isSeq(node)) return false;\n for (let i = 0; i < node.items.length; i++) {\n const item = node.items[i];\n if (\n isMap(item) &&\n (item as YAMLMap).get(\"kind\") === kind &&\n (item as YAMLMap).get(\"name\") === name\n ) {\n node.delete(i);\n return true;\n }\n }\n return false;\n }\n\n // ── Raw access (escape hatch) ─────────────────────────────────────────────\n\n /** Get the underlying yaml Document for advanced manipulation. */\n get document(): Document {\n return this.doc;\n }\n}\n"]}
|