@skaile/workspaces 0.40.1 → 0.41.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 +29 -0
- package/dist/{asset-feeds-NOHUJ4XZ.js → asset-feeds-B3YOVIX6.js} +11 -11
- package/dist/{asset-feeds-NOHUJ4XZ.js.map → asset-feeds-B3YOVIX6.js.map} +1 -1
- package/dist/asset-manager/index.js +9 -9
- package/dist/asset-manager/installer.js +8 -8
- package/dist/{chunk-HL66R2P2.js → chunk-2PXSZYKV.js} +17 -8
- package/dist/chunk-2PXSZYKV.js.map +1 -0
- package/dist/{chunk-XZNPKJXU.js → chunk-4ZDA6Q5A.js} +4 -4
- package/dist/{chunk-XZNPKJXU.js.map → chunk-4ZDA6Q5A.js.map} +1 -1
- package/dist/{chunk-HAXQAC6D.js → chunk-54PBADZO.js} +3 -3
- package/dist/{chunk-HAXQAC6D.js.map → chunk-54PBADZO.js.map} +1 -1
- package/dist/{chunk-O66LT7UI.js → chunk-5PGFAYN3.js} +5 -5
- package/dist/{chunk-O66LT7UI.js.map → chunk-5PGFAYN3.js.map} +1 -1
- package/dist/{chunk-MAPRKFBD.js → chunk-B5PEERRZ.js} +18 -3
- package/dist/chunk-B5PEERRZ.js.map +1 -0
- package/dist/{chunk-CFCSDZYF.js → chunk-DUAB2AFV.js} +4 -4
- package/dist/{chunk-CFCSDZYF.js.map → chunk-DUAB2AFV.js.map} +1 -1
- package/dist/{chunk-SAXDHVJZ.js → chunk-DZCK7GRW.js} +3 -3
- package/dist/{chunk-SAXDHVJZ.js.map → chunk-DZCK7GRW.js.map} +1 -1
- package/dist/{chunk-BM7XANVN.js → chunk-GEEW6SY2.js} +10 -3
- package/dist/chunk-GEEW6SY2.js.map +1 -0
- package/dist/{chunk-USEFGACS.js → chunk-HUSXT2BN.js} +7 -7
- package/dist/{chunk-USEFGACS.js.map → chunk-HUSXT2BN.js.map} +1 -1
- package/dist/{chunk-XNMABEHH.js → chunk-IGNSNZPG.js} +5 -5
- package/dist/{chunk-XNMABEHH.js.map → chunk-IGNSNZPG.js.map} +1 -1
- package/dist/{chunk-PBHLDLVU.js → chunk-LCJNBABB.js} +13 -9
- package/dist/chunk-LCJNBABB.js.map +1 -0
- package/dist/{chunk-23WP47VA.js → chunk-NXNBX56J.js} +2 -2
- package/dist/{chunk-23WP47VA.js.map → chunk-NXNBX56J.js.map} +1 -1
- package/dist/{chunk-WLWHOA3S.js → chunk-QGDCLTK2.js} +4 -4
- package/dist/{chunk-WLWHOA3S.js.map → chunk-QGDCLTK2.js.map} +1 -1
- package/dist/{chunk-CBXZB3G5.js → chunk-RVXP5KN5.js} +3 -3
- package/dist/{chunk-CBXZB3G5.js.map → chunk-RVXP5KN5.js.map} +1 -1
- package/dist/{chunk-EAWENE2K.js → chunk-SC3YNS4W.js} +4 -4
- package/dist/{chunk-EAWENE2K.js.map → chunk-SC3YNS4W.js.map} +1 -1
- package/dist/{chunk-C54IAYEU.js → chunk-TRVTY5AF.js} +3 -3
- package/dist/{chunk-C54IAYEU.js.map → chunk-TRVTY5AF.js.map} +1 -1
- package/dist/{chunk-KYC6JH75.js → chunk-UKJMQZV6.js} +3 -3
- package/dist/{chunk-KYC6JH75.js.map → chunk-UKJMQZV6.js.map} +1 -1
- package/dist/{chunk-DBL3X6V4.js → chunk-V2OSYOWR.js} +5 -5
- package/dist/{chunk-DBL3X6V4.js.map → chunk-V2OSYOWR.js.map} +1 -1
- package/dist/{chunk-FBIQ4QPF.js → chunk-VIA64TYP.js} +3 -3
- package/dist/{chunk-FBIQ4QPF.js.map → chunk-VIA64TYP.js.map} +1 -1
- package/dist/{chunk-4A2LAEX6.js → chunk-VMX4DA65.js} +4 -4
- package/dist/{chunk-4A2LAEX6.js.map → chunk-VMX4DA65.js.map} +1 -1
- package/dist/cli/index.js +36 -36
- package/dist/connectors/config.js +8 -8
- package/dist/connectors/index.js +9 -9
- package/dist/core/index.js +7 -7
- package/dist/core/manifest.js +2 -2
- package/dist/core/models.js +1 -1
- package/dist/core/publish-manifest.js +2 -2
- package/dist/core/ref.d.ts +2 -0
- package/dist/core/ref.js +29 -0
- package/dist/core/ref.js.map +1 -0
- package/dist/core/runtime-assets.js +5 -5
- package/dist/core/src/index.d.ts +1 -1
- package/dist/core/src/index.d.ts.map +1 -1
- package/dist/core/src/manifest.d.ts +0 -14
- package/dist/core/src/manifest.d.ts.map +1 -1
- package/dist/core/src/models.d.ts +20 -0
- package/dist/core/src/models.d.ts.map +1 -1
- package/dist/core/src/ref.d.ts +25 -0
- package/dist/core/src/ref.d.ts.map +1 -0
- package/dist/core/src/walker.d.ts.map +1 -1
- package/dist/core/workspace-config.js +4 -4
- package/dist/deploy/index.js +7 -7
- package/dist/discovery/index.js +4 -4
- package/dist/{ensure-sources-XITKRBLU.js → ensure-sources-EEH3DWH5.js} +13 -13
- package/dist/{ensure-sources-XITKRBLU.js.map → ensure-sources-EEH3DWH5.js.map} +1 -1
- package/dist/factory-assets/connectors/deploy.js +9 -9
- package/dist/factory-assets/connectors/devserver.js +9 -9
- package/dist/factory-assets/connectors/flow/adapter.js +9 -9
- package/dist/factory-assets/connectors/flow/engine.js +7 -7
- package/dist/factory-assets/connectors/flow/run-flow.js +10 -10
- package/dist/factory-assets/connectors/flow.js +9 -9
- package/dist/factory-assets/connectors/git.js +9 -9
- package/dist/factory-assets/connectors/gmail.js +9 -9
- package/dist/factory-assets/connectors/googledrive.js +9 -9
- package/dist/factory-assets/connectors/local.js +9 -9
- package/dist/factory-assets/connectors/mattermost.js +9 -9
- package/dist/factory-assets/connectors/memory.js +9 -9
- package/dist/factory-assets/connectors/minio.js +9 -9
- package/dist/factory-assets/connectors/postgres.js +9 -9
- package/dist/factory-assets/connectors/s3.js +9 -9
- package/dist/factory-assets/connectors/sharepoint.js +9 -9
- package/dist/factory-assets/connectors/sqlite.js +9 -9
- package/dist/factory-assets/connectors/static-server.js +9 -9
- package/dist/factory-assets/connectors/tunnel.js +9 -9
- package/dist/factory-assets/connectors/webdav.js +9 -9
- package/dist/factory-assets/connectors/xstate-store.js +9 -9
- package/dist/factory-assets/connectors/xstate.js +9 -9
- package/dist/{flows-BOJMGLRI.js → flows-ZYWYM5HR.js} +4 -4
- package/dist/{flows-BOJMGLRI.js.map → flows-ZYWYM5HR.js.map} +1 -1
- package/dist/library/index.js +11 -11
- package/dist/library/install.js +8 -8
- package/dist/open-library-5M67A7BN.js +23 -0
- package/dist/{open-library-5KJOZHG7.js.map → open-library-5M67A7BN.js.map} +1 -1
- package/dist/paths-RTD4IMYN.js +15 -0
- package/dist/{paths-66ZDGXK3.js.map → paths-RTD4IMYN.js.map} +1 -1
- package/dist/{plugin-store-BOQXW3XV.js → plugin-store-YEHJFGJS.js} +9 -9
- package/dist/{plugin-store-BOQXW3XV.js.map → plugin-store-YEHJFGJS.js.map} +1 -1
- package/dist/runner/index.js +11 -11
- package/dist/runner/src/mcp-runtime-handlers.d.ts +4 -0
- package/dist/runner/src/mcp-runtime-handlers.d.ts.map +1 -1
- package/dist/sdk/asset-manager.js +9 -9
- package/dist/sdk/core.js +7 -7
- package/dist/sdk/flow.js +7 -7
- package/dist/sdk/index.js +11 -11
- package/dist/sdk/runner.js +11 -11
- package/dist/{setup-JIGNL3O4.js → setup-VNS4I3OF.js} +9 -9
- package/dist/{setup-JIGNL3O4.js.map → setup-VNS4I3OF.js.map} +1 -1
- package/dist/store-client-GBWSRUZR.js +15 -0
- package/dist/{store-client-ODJJK5XS.js.map → store-client-GBWSRUZR.js.map} +1 -1
- package/dist/tui/index.js +11 -11
- package/dist/types/src/lifecycle.d.ts +1 -0
- package/dist/types/src/lifecycle.d.ts.map +1 -1
- package/dist/workspace-plugin/adapters/mcp.js +2 -2
- package/dist/workspace-plugin/adapters/omp.js +3 -3
- package/dist/workspace-plugin/index.js +1 -1
- package/package.json +7 -1
- package/dist/chunk-BM7XANVN.js.map +0 -1
- package/dist/chunk-HL66R2P2.js.map +0 -1
- package/dist/chunk-MAPRKFBD.js.map +0 -1
- package/dist/chunk-PBHLDLVU.js.map +0 -1
- package/dist/open-library-5KJOZHG7.js +0 -23
- package/dist/paths-66ZDGXK3.js +0 -15
- package/dist/store-client-ODJJK5XS.js +0 -15
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { globalSettingsPath, mapLegacyFields } from './chunk-
|
|
1
|
+
import { globalSettingsPath, mapLegacyFields } from './chunk-VIA64TYP.js';
|
|
2
2
|
import { existsSync, readFileSync, mkdirSync, writeFileSync } from 'fs';
|
|
3
3
|
import { homedir } from 'os';
|
|
4
4
|
import { join } from 'path';
|
|
@@ -89,5 +89,5 @@ function isStoreAuthenticated(config) {
|
|
|
89
89
|
}
|
|
90
90
|
|
|
91
91
|
export { clearStoreTokens, getStoreConfig, isStoreAuthenticated, saveStoreTokens, storeFetch };
|
|
92
|
-
//# sourceMappingURL=chunk-
|
|
93
|
-
//# sourceMappingURL=chunk-
|
|
92
|
+
//# sourceMappingURL=chunk-TRVTY5AF.js.map
|
|
93
|
+
//# sourceMappingURL=chunk-TRVTY5AF.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../cli/src/store-client.ts"],"names":[],"mappings":"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","file":"chunk-
|
|
1
|
+
{"version":3,"sources":["../cli/src/store-client.ts"],"names":[],"mappings":";;;;;AAuBO,SAAS,cAAA,GAA8B;AAC5C,EAAA,MAAM,eAAe,kBAAA,EAAmB;AACxC,EAAA,IAAI,WAAgC,EAAC;AACrC,EAAA,IAAI,UAAA,CAAW,YAAY,CAAA,EAAG;AAC5B,IAAA,IAAI;AACF,MAAA,QAAA,GAAW,gBAAgB,IAAA,CAAK,KAAA,CAAM,aAAa,YAAA,EAAc,OAAO,CAAC,CAAC,CAAA;AAAA,IAC5E,CAAA,CAAA,MAAQ;AACN,MAAA,QAAA,GAAW,EAAC;AAAA,IACd;AAAA,EACF;AACA,EAAA,OAAO;AAAA,IACL,GAAA,EAAK,QAAA,CAAS,QAAA,IAAY,OAAA,CAAQ,IAAI,gBAAA,IAAoB,yBAAA;AAAA,IAC1D,GAAA,EAAK,SAAS,QAAA,IAAY,IAAA;AAAA,IAC1B,YAAA,EAAc,SAAS,iBAAA,IAAqB;AAAA,GAC9C;AACF;AAGA,SAAS,gBAAA,GAA2B;AAClC,EAAA,OAAO,IAAA,CAAK,OAAA,EAAQ,EAAG,SAAA,EAAW,eAAe,CAAA;AACnD;AASO,SAAS,eAAA,CAAgB,KAAa,YAAA,EAA4B;AACvE,EAAA,MAAM,eAAe,gBAAA,EAAiB;AACtC,EAAA,MAAM,GAAA,GAAM,IAAA,CAAK,YAAA,EAAc,IAAI,CAAA;AACnC,EAAA,SAAA,CAAU,GAAA,EAAK,EAAE,SAAA,EAAW,IAAA,EAAM,CAAA;AAElC,EAAA,IAAI,UAA+B,EAAC;AACpC,EAAA,IAAI,UAAA,CAAW,YAAY,CAAA,EAAG;AAC5B,IAAA,IAAI;AACF,MAAA,OAAA,GAAU,IAAA,CAAK,KAAA,CAAM,YAAA,CAAa,YAAA,EAAc,OAAO,CAAC,CAAA;AAAA,IAC1D,CAAA,CAAA,MAAQ;AACN,MAAA,OAAA,GAAU,EAAC;AAAA,IACb;AAAA,EACF;AAEA,EAAA,OAAA,CAAQ,QAAA,GAAW,GAAA;AACnB,EAAA,OAAA,CAAQ,iBAAA,GAAoB,YAAA;AAC5B,EAAA,aAAA,CAAc,cAAc,IAAA,CAAK,SAAA,CAAU,SAAS,IAAA,EAAM,CAAC,GAAG,OAAO,CAAA;AACvE;AAOO,SAAS,gBAAA,GAAyB;AACvC,EAAA,MAAM,eAAe,gBAAA,EAAiB;AACtC,EAAA,IAAI,CAAC,UAAA,CAAW,YAAY,CAAA,EAAG;AAE/B,EAAA,IAAI;AACF,IAAA,MAAM,UAAU,IAAA,CAAK,KAAA,CAAM,YAAA,CAAa,YAAA,EAAc,OAAO,CAAC,CAAA;AAC9D,IAAA,OAAO,OAAA,CAAQ,QAAA;AACf,IAAA,OAAO,OAAA,CAAQ,iBAAA;AACf,IAAA,aAAA,CAAc,cAAc,IAAA,CAAK,SAAA,CAAU,SAAS,IAAA,EAAM,CAAC,GAAG,OAAO,CAAA;AAAA,EACvE,CAAA,CAAA,MAAQ;AAAA,EAER;AACF;AAWA,eAAsB,UAAA,CACpB,MAAA,EACA,IAAA,EACA,IAAA,EAMY;AACZ,EAAA,IAAI,GAAA,GAAM,CAAA,EAAG,MAAA,CAAO,GAAG,GAAG,IAAI,CAAA,CAAA;AAC9B,EAAA,IAAI,MAAM,MAAA,EAAQ;AAChB,IAAA,MAAM,EAAA,GAAK,IAAI,eAAA,CAAgB,IAAA,CAAK,MAAM,CAAA;AAC1C,IAAA,GAAA,IAAO,IAAI,EAAE,CAAA,CAAA;AAAA,EACf;AAEA,EAAA,MAAM,OAAA,GAAkC;AAAA,IACtC,cAAA,EAAgB,kBAAA;AAAA,IAChB,MAAA,EAAQ,kBAAA;AAAA,IACR,GAAI,IAAA,EAAM,OAAA,IAAW;AAAC,GACxB;AACA,EAAA,IAAI,OAAO,GAAA,EAAK;AACd,IAAA,OAAA,CAAQ,aAAA,GAAgB,CAAA,OAAA,EAAU,MAAA,CAAO,GAAG,CAAA,CAAA;AAAA,EAC9C;AAEA,EAAA,MAAM,SAAA,GAAyB;AAAA,IAC7B,MAAA,EAAQ,MAAM,MAAA,IAAU,KAAA;AAAA,IACxB;AAAA,GACF;AACA,EAAA,IAAI,MAAM,IAAA,EAAM;AACd,IAAA,SAAA,CAAU,IAAA,GAAO,IAAA,CAAK,SAAA,CAAU,IAAA,CAAK,IAAI,CAAA;AAAA,EAC3C;AAEA,EAAA,MAAM,UAAA,GAAa,IAAI,eAAA,EAAgB;AACvC,EAAA,MAAM,UAAU,UAAA,CAAW,MAAM,UAAA,CAAW,KAAA,IAAS,IAAK,CAAA;AAC1D,EAAA,IAAI;AACF,IAAA,MAAM,GAAA,GAAM,MAAM,KAAA,CAAM,GAAA,EAAK,EAAE,GAAG,SAAA,EAAW,MAAA,EAAQ,UAAA,CAAW,MAAA,EAAQ,CAAA;AACxE,IAAA,IAAI,CAAC,IAAI,EAAA,EAAI;AACX,MAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,IAAA,EAAK,CAAE,KAAA,CAAM,OAAO,EAAE,KAAA,EAAO,CAAA,KAAA,EAAQ,GAAA,CAAI,MAAM,IAAG,CAAE,CAAA;AAC3E,MAAA,MAAM,IAAI,KAAA,CAAO,IAAA,CAAa,SAAS,CAAA,iBAAA,EAAoB,GAAA,CAAI,MAAM,CAAA,CAAE,CAAA;AAAA,IACzE;AACA,IAAA,OAAO,IAAI,IAAA,EAAK;AAAA,EAClB,CAAA,SAAE;AACA,IAAA,YAAA,CAAa,OAAO,CAAA;AAAA,EACtB;AACF;AAQO,SAAS,qBAAqB,MAAA,EAA+B;AAClE,EAAA,MAAM,CAAA,GAAI,UAAU,cAAA,EAAe;AACnC,EAAA,OAAO,CAAC,CAAC,CAAA,CAAE,GAAA;AACb","file":"chunk-TRVTY5AF.js","sourcesContent":["import { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { globalSettingsPath, mapLegacyFields } from \"@skaile/workspaces/core\";\n\n/**\n * Connection configuration for the AI Asset Store API.\n *\n * @docLink cli/dev-guide#store-client\n */\nexport interface StoreConfig {\n url: string;\n jwt: string | null;\n refreshToken: string | null;\n}\n\n/**\n * Read store connection config from global user settings, falling back to\n * `SKAILE_STORE_URL` env var and the default store URL.\n *\n * @returns Populated {@link StoreConfig} with `url`, `jwt`, and `refreshToken`.\n * @docLink cli/dev-guide#store-client\n */\nexport function getStoreConfig(): StoreConfig {\n const settingsPath = globalSettingsPath();\n let settings: Record<string, any> = {};\n if (existsSync(settingsPath)) {\n try {\n settings = mapLegacyFields(JSON.parse(readFileSync(settingsPath, \"utf-8\")));\n } catch {\n settings = {};\n }\n }\n return {\n url: settings.storeUrl ?? process.env.SKAILE_STORE_URL ?? \"https://store.skaile.ai\",\n jwt: settings.storeJwt ?? null,\n refreshToken: settings.storeRefreshToken ?? null,\n };\n}\n\n/** Path to user-level settings */\nfunction userSettingsPath(): string {\n return join(homedir(), \".skaile\", \"settings.json\");\n}\n\n/**\n * Persist store authentication tokens to `~/.skaile/settings.json`.\n *\n * @param jwt - The JWT access token returned by the store login endpoint.\n * @param refreshToken - The refresh token for obtaining new JWTs.\n * @docLink cli/dev-guide#store-client\n */\nexport function saveStoreTokens(jwt: string, refreshToken: string): void {\n const settingsPath = userSettingsPath();\n const dir = join(settingsPath, \"..\");\n mkdirSync(dir, { recursive: true });\n\n let current: Record<string, any> = {};\n if (existsSync(settingsPath)) {\n try {\n current = JSON.parse(readFileSync(settingsPath, \"utf-8\"));\n } catch {\n current = {};\n }\n }\n\n current.storeJwt = jwt;\n current.storeRefreshToken = refreshToken;\n writeFileSync(settingsPath, JSON.stringify(current, null, 2), \"utf-8\");\n}\n\n/**\n * Remove store authentication tokens from `~/.skaile/settings.json`.\n *\n * @docLink cli/dev-guide#store-client\n */\nexport function clearStoreTokens(): void {\n const settingsPath = userSettingsPath();\n if (!existsSync(settingsPath)) return;\n\n try {\n const current = JSON.parse(readFileSync(settingsPath, \"utf-8\"));\n delete current.storeJwt;\n delete current.storeRefreshToken;\n writeFileSync(settingsPath, JSON.stringify(current, null, 2), \"utf-8\");\n } catch {\n // ignore\n }\n}\n\n/**\n * Make an authenticated HTTP request to the store REST API with a 1.5s timeout.\n *\n * @param config - Store connection config (URL + auth token).\n * @param path - API path (e.g. `/api/assets`).\n * @param opts - Optional method, body, query params, and extra headers.\n * @returns Parsed JSON response body.\n * @docLink cli/dev-guide#store-client\n */\nexport async function storeFetch<T = any>(\n config: StoreConfig,\n path: string,\n opts?: {\n method?: string;\n body?: unknown;\n params?: Record<string, string>;\n headers?: Record<string, string>;\n },\n): Promise<T> {\n let url = `${config.url}${path}`;\n if (opts?.params) {\n const sp = new URLSearchParams(opts.params);\n url += `?${sp}`;\n }\n\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n ...(opts?.headers ?? {}),\n };\n if (config.jwt) {\n headers.Authorization = `Bearer ${config.jwt}`;\n }\n\n const fetchOpts: RequestInit = {\n method: opts?.method ?? \"GET\",\n headers,\n };\n if (opts?.body) {\n fetchOpts.body = JSON.stringify(opts.body);\n }\n\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 1_500);\n try {\n const res = await fetch(url, { ...fetchOpts, signal: controller.signal });\n if (!res.ok) {\n const body = await res.json().catch(() => ({ error: `HTTP ${res.status}` }));\n throw new Error((body as any).error ?? `Store API error: ${res.status}`);\n }\n return res.json() as Promise<T>;\n } finally {\n clearTimeout(timeout);\n }\n}\n\n/**\n * Return `true` if a JWT token is present in the provided (or default) store config.\n *\n * @param config - Optional pre-loaded config; if omitted, calls {@link getStoreConfig}.\n * @docLink cli/dev-guide#store-client\n */\nexport function isStoreAuthenticated(config?: StoreConfig): boolean {\n const c = config ?? getStoreConfig();\n return !!c.jwt;\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { parseAssetRef } from './chunk-
|
|
1
|
+
import { parseAssetRef } from './chunk-GEEW6SY2.js';
|
|
2
2
|
import { createHash } from 'crypto';
|
|
3
3
|
import { rm, mkdir, writeFile } from 'fs/promises';
|
|
4
4
|
import { resolve, join, sep, dirname, isAbsolute } from 'path';
|
|
@@ -124,5 +124,5 @@ async function installFlat(manifest, targetDir, fetcher) {
|
|
|
124
124
|
}
|
|
125
125
|
|
|
126
126
|
export { installFromManifest, longestCommonDirPrefix };
|
|
127
|
-
//# sourceMappingURL=chunk-
|
|
128
|
-
//# sourceMappingURL=chunk-
|
|
127
|
+
//# sourceMappingURL=chunk-UKJMQZV6.js.map
|
|
128
|
+
//# sourceMappingURL=chunk-UKJMQZV6.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../library/src/install/install-from-manifest.ts"],"names":[],"mappings":"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","file":"chunk-KYC6JH75.js","sourcesContent":["/**\n * Pointer-only install path.\n *\n * Given an {@link InstallManifest} (the Pointer Triple the Catalog hands\n * clients), this:\n *\n * 1. fetches the asset bytes directly from the upstream repo at the pinned\n * commit (via an injectable fetcher, default {@link fetchAssetFilesFromGitHub});\n * 2. verifies EVERY per-file SHA256 against `manifest.files[].sha256`;\n * 3. verifies the composite SHA256 rollup over the sorted\n * `<path>:<sha256>\\n` lines against `manifest.sha256`;\n * 4. writes the verified bytes under `<libraryRoot>/@<publisher>/<name>/<version>`.\n *\n * Any hash mismatch is a hard failure — bytes are not written if per-file\n * verification fails, and the composite check is the second gate.\n *\n * @docLink packages/library/concepts#install\n */\n\nimport { createHash } from \"node:crypto\";\nimport { mkdir, rm, writeFile } from \"node:fs/promises\";\nimport { dirname, isAbsolute, join, resolve, sep } from \"node:path\";\nimport { parseAssetRef } from \"@skaile/workspaces/core\";\nimport type { InstallManifest } from \"@skaile/workspaces/types\";\n\n/**\n * Validate a single manifest-supplied file path against path traversal.\n *\n * `manifest.files[].path` comes off the network — the attacker controls the\n * entire manifest (and therefore every hash in it), so hash verification can\n * NEVER mitigate a malicious *destination*. A path like\n * `../../../../home/user/.bashrc` or an absolute path would escape\n * `installPath` and yield an arbitrary file write. Every path is checked\n * BEFORE any fetch or write happens; the first bad path aborts the entire\n * install with a hard throw.\n *\n * A path is rejected if ANY of:\n * - it is empty;\n * - it is absolute (`path.isAbsolute`) or has a leading slash;\n * - it contains a `..` segment;\n * - `path.resolve(installPath, p)` is not `installPath` itself and does not\n * start with `installPath + path.sep` (escapes the install dir).\n *\n * @throws An error matching `/unsafe path in manifest/` on the first bad path.\n */\nfunction assertSafeManifestPath(installPath: string, p: string): void {\n const bad = (): never => {\n throw new Error(`unsafe path in manifest: ${p}`);\n };\n if (!p || p.length === 0) bad();\n if (isAbsolute(p) || p.startsWith(\"/\") || p.startsWith(\"\\\\\")) bad();\n const segments = p.split(/[/\\\\]/);\n if (segments.some((s) => s === \"..\")) bad();\n const resolved = resolve(installPath, p);\n if (resolved !== installPath && !resolved.startsWith(installPath + sep)) bad();\n}\n\n/**\n * Validate one component (publisher / name / version) of the attacker-controlled\n * `manifest.ref`.\n *\n * `installPath` is built by joining these components onto `libraryRoot`. A\n * component containing a path separator or a `..` / leading-dot segment would\n * let `installPath` itself escape `libraryRoot` — yielding an arbitrary file\n * write AND, via the pre-write `rm(installPath, { recursive })`, an arbitrary\n * recursive delete. The per-file `assertSafeManifestPath` guard cannot catch\n * this: it only validates each `f.path` *relative to* `installPath`, never\n * `installPath` itself. Components must be plain identifier-like strings.\n *\n * @throws An error matching `/unsafe ref/` on a bad component.\n */\nfunction assertSafeRefComponent(kind: string, value: string): void {\n // Reject empty, leading-dot (covers `.` and `..`), path separators, and\n // ASCII control characters (NUL et al.) — fails a malformed segment fast\n // with a domain-specific error rather than a raw EINVAL deeper in.\n const hasControlChar = [...value].some((c) => c.charCodeAt(0) < 0x20);\n if (!value || value.startsWith(\".\") || /[/\\\\]/.test(value) || hasControlChar) {\n throw new Error(`unsafe ref ${kind} component in manifest: '${value}'`);\n }\n}\n\n/**\n * Longest common **directory** prefix across manifest paths, compared by whole\n * slash-delimited segments (never raw-string — so `app/` and `app-data/` never\n * collide). Each path's basename is excluded, so the result is always a\n * directory prefix and every path keeps a non-empty remainder after stripping.\n *\n * Used by flat mode to reproduce the platform pointer-installer's asset-rooting:\n * the store persists repo-root-relative paths (e.g. `skaile-platform/mcpo/xls/MCP.md`)\n * but the runner scans `.skaile/assets/<kind>/<name>/` for immediate-child files,\n * so this prefix is stripped from the WRITE path while the fetch keeps the full\n * repo path. Returns `''` when there is no common directory (a no-op strip).\n */\nexport function longestCommonDirPrefix(paths: readonly string[]): string {\n if (paths.length === 0) return \"\";\n const dirSegments = paths.map((p) => p.split(\"/\").slice(0, -1));\n let common = dirSegments[0]!;\n for (let i = 1; i < dirSegments.length && common.length > 0; i++) {\n const segs = dirSegments[i]!;\n let n = 0;\n while (n < common.length && n < segs.length && common[n] === segs[n]) n++;\n common = common.slice(0, n);\n }\n return common.join(\"/\");\n}\n\n/**\n * Fetcher signature — fetches `{ path → Buffer }` for the requested paths at\n * a pinned upstream commit. {@link fetchAssetFilesFromGitHub} is the default\n * production implementation; tests inject a mock.\n */\nexport type AssetFetcher = (opts: {\n url: string;\n commitSha: string;\n paths: string[];\n}) => Promise<Record<string, Buffer>>;\n\n/**\n * Options for {@link installFromManifest}.\n */\nexport interface InstallOpts {\n /** The pointer-only install manifest from the Catalog. */\n manifest: InstallManifest;\n /** Filesystem root the asset is installed under (ref-derived mode). */\n libraryRoot: string;\n /**\n * Pluggable fetcher so tests can inject mock data. Defaults to\n * {@link fetchAssetFilesFromGitHub} in production.\n */\n fetcher?: AssetFetcher;\n /**\n * Flat-layout mode. When set, install-core reproduces the platform\n * pointer-installer's behavior: it ignores `libraryRoot`/ref-derivation, does\n * NOT parse `manifest.ref` and does NOT verify the composite sha256, strips\n * the longest-common-dir prefix from each path, per-file sha256-verifies, and\n * writes the stripped paths as immediate children of `targetDir` (what the\n * runner's `.skaile/assets/<kind>/<name>/` scan requires). `installPath` is\n * `targetDir`. Absent → unchanged ref-derived `@<pub>/name/version/<path>`\n * layout with composite verify.\n */\n targetDir?: string;\n}\n\n/**\n * Result of a successful {@link installFromManifest} call.\n */\nexport interface InstallResult {\n /** Absolute path the asset files were written to. */\n installPath: string;\n}\n\n/**\n * Fetch, verify, and write an asset's files per its {@link InstallManifest}.\n *\n * @throws An error matching `/hash mismatch/i` if any per-file SHA256 differs.\n * @throws An error matching `/composite hash mismatch/i` if the rollup differs.\n * @throws An error if the ref is malformed or the fetcher omits a file.\n */\nexport async function installFromManifest(opts: InstallOpts): Promise<InstallResult> {\n const { manifest, libraryRoot } = opts;\n const fetcher =\n opts.fetcher ?? (await import(\"./source-fetch-github.js\")).fetchAssetFilesFromGitHub;\n\n // Flat mode: reproduce the platform pointer-installer's asset-rooted layout.\n // No ref parse, no composite verify — the platform store may not satisfy a\n // ref-grammar or composite, and the runner only needs immediate-child files.\n if (opts.targetDir !== undefined) {\n return installFlat(manifest, opts.targetDir, fetcher);\n }\n\n // 1. Parse ref into install path: `skill:@x/git#1.0.0` → `<root>/@x/git/1.0.0`.\n // Done first so the C1 path-traversal guard can resolve against installPath\n // BEFORE any network fetch happens. The ref is attacker-controlled, so each\n // segment is further validated as a safe path component (H1) after parsing.\n // `parseAssetRef` is the single canonical grammar (`kind:@publisher/name#version`);\n // the legacy trailing-`@version` shape was removed in core and is rejected here.\n let parsed: ReturnType<typeof parseAssetRef>;\n try {\n parsed = parseAssetRef(manifest.ref);\n } catch (e) {\n throw new Error(`invalid ref: ${manifest.ref}: ${e instanceof Error ? e.message : String(e)}`);\n }\n const publisher = parsed.publisher;\n const name = parsed.name;\n const version = parsed.pin;\n if (!publisher) throw new Error(`invalid ref: ${manifest.ref} (missing publisher)`);\n if (!version) throw new Error(`invalid ref: ${manifest.ref} (missing version pin)`);\n assertSafeRefComponent(\"publisher\", publisher);\n assertSafeRefComponent(\"name\", name);\n assertSafeRefComponent(\"version\", version);\n const root = resolve(libraryRoot);\n const installPath = resolve(join(root, `@${publisher}`, name, version));\n // Defense in depth: even with the segment guards above, assert the built\n // installPath stays strictly inside libraryRoot before any write or `rm`.\n if (installPath !== root && !installPath.startsWith(root + sep)) {\n throw new Error(`unsafe install path: ref '${manifest.ref}' resolves outside the library root`);\n }\n\n // 2. [C1] Validate EVERY manifest path against traversal BEFORE fetching.\n // The attacker controls the manifest (and thus all hashes) — hashes verify\n // content, never destination. Reject the whole install on the first bad path.\n for (const f of manifest.files) {\n assertSafeManifestPath(installPath, f.path);\n }\n\n // 3. Fetch all files at the pinned commit.\n const paths = manifest.files.map((f) => f.path);\n const bytes = await fetcher({\n url: manifest.source.url,\n commitSha: manifest.source.commitSha,\n paths,\n });\n\n // 4. Verify per-file SHA256 — hard fail before writing anything. The path\n // key used to read from the fetcher result is re-guarded as defense in depth.\n for (const f of manifest.files) {\n assertSafeManifestPath(installPath, f.path);\n const buf = bytes[f.path];\n if (!buf) throw new Error(`fetcher returned no bytes for ${f.path}`);\n const actual = createHash(\"sha256\").update(buf).digest(\"hex\");\n if (actual !== f.sha256) {\n throw new Error(`hash mismatch for ${f.path}: expected ${f.sha256}, got ${actual}`);\n }\n }\n\n // 5. Verify composite SHA256 over the sorted `<path>:<sha256>\\n` lines.\n const sortedLines = manifest.files\n .slice()\n .sort((a, b) => a.path.localeCompare(b.path))\n .map((e) => `${e.path}:${e.sha256}\\n`)\n .join(\"\");\n const actualComposite = createHash(\"sha256\").update(sortedLines, \"utf-8\").digest(\"hex\");\n if (actualComposite !== manifest.sha256) {\n throw new Error(`composite hash mismatch: expected ${manifest.sha256}, got ${actualComposite}`);\n }\n\n // 6. [M1] Write all verified files. A failed install must leave NO partial\n // directory: any prior `installPath` is removed first (clean overwrite), and\n // a mid-loop write failure removes the partially-written tree before\n // rethrowing.\n await rm(installPath, { recursive: true, force: true });\n try {\n for (const f of manifest.files) {\n const target = join(installPath, f.path);\n await mkdir(dirname(target), { recursive: true });\n await writeFile(target, bytes[f.path]!);\n }\n } catch (e) {\n await rm(installPath, { recursive: true, force: true }).catch(() => {});\n throw e;\n }\n\n return { installPath };\n}\n\n/**\n * Flat-layout install — the platform pointer-installer's behavior, made canonical\n * in install-core. Validates every path, fetches with the FULL repo paths, per-file\n * sha256-verifies, then strips the longest-common-dir prefix and writes each file\n * as `join(targetDir, path.slice(assetRoot.length + 1))` — immediate children of\n * `targetDir`. No ref parse, no composite check.\n */\nasync function installFlat(\n manifest: InstallManifest,\n targetDir: string,\n fetcher: AssetFetcher,\n): Promise<InstallResult> {\n const target = resolve(targetDir);\n\n // Gate every path before any fetch — the attacker controls the whole manifest.\n for (const f of manifest.files) {\n assertSafeManifestPath(target, f.path);\n }\n\n // Fetch keys off the FULL repo path (matches the upstream tree).\n const paths = manifest.files.map((f) => f.path);\n const bytes = await fetcher({\n url: manifest.source.url,\n commitSha: manifest.source.commitSha,\n paths,\n });\n\n // Strip the asset-root dir prefix from the WRITE path only — the fetch above\n // still keyed off the full repo path. Stripping removes leading whole segments\n // (never the basename), so a non-empty remainder always survives.\n const assetRoot = longestCommonDirPrefix(paths);\n\n for (const f of manifest.files) {\n const buf = bytes[f.path];\n if (!buf) throw new Error(`fetcher returned no bytes for ${f.path}`);\n const actual = createHash(\"sha256\").update(buf).digest(\"hex\");\n if (actual !== f.sha256) {\n throw new Error(`hash mismatch for ${f.path}: expected ${f.sha256}, got ${actual}`);\n }\n const relPath = assetRoot ? f.path.slice(assetRoot.length + 1) : f.path;\n // Re-guard the post-strip destination — it is what we actually write.\n assertSafeManifestPath(target, relPath);\n const dest = join(target, relPath);\n await mkdir(dirname(dest), { recursive: true });\n await writeFile(dest, buf);\n }\n\n return { installPath: target };\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../library/src/install/install-from-manifest.ts"],"names":[],"mappings":"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","file":"chunk-UKJMQZV6.js","sourcesContent":["/**\n * Pointer-only install path.\n *\n * Given an {@link InstallManifest} (the Pointer Triple the Catalog hands\n * clients), this:\n *\n * 1. fetches the asset bytes directly from the upstream repo at the pinned\n * commit (via an injectable fetcher, default {@link fetchAssetFilesFromGitHub});\n * 2. verifies EVERY per-file SHA256 against `manifest.files[].sha256`;\n * 3. verifies the composite SHA256 rollup over the sorted\n * `<path>:<sha256>\\n` lines against `manifest.sha256`;\n * 4. writes the verified bytes under `<libraryRoot>/@<publisher>/<name>/<version>`.\n *\n * Any hash mismatch is a hard failure — bytes are not written if per-file\n * verification fails, and the composite check is the second gate.\n *\n * @docLink packages/library/concepts#install\n */\n\nimport { createHash } from \"node:crypto\";\nimport { mkdir, rm, writeFile } from \"node:fs/promises\";\nimport { dirname, isAbsolute, join, resolve, sep } from \"node:path\";\nimport { parseAssetRef } from \"@skaile/workspaces/core\";\nimport type { InstallManifest } from \"@skaile/workspaces/types\";\n\n/**\n * Validate a single manifest-supplied file path against path traversal.\n *\n * `manifest.files[].path` comes off the network — the attacker controls the\n * entire manifest (and therefore every hash in it), so hash verification can\n * NEVER mitigate a malicious *destination*. A path like\n * `../../../../home/user/.bashrc` or an absolute path would escape\n * `installPath` and yield an arbitrary file write. Every path is checked\n * BEFORE any fetch or write happens; the first bad path aborts the entire\n * install with a hard throw.\n *\n * A path is rejected if ANY of:\n * - it is empty;\n * - it is absolute (`path.isAbsolute`) or has a leading slash;\n * - it contains a `..` segment;\n * - `path.resolve(installPath, p)` is not `installPath` itself and does not\n * start with `installPath + path.sep` (escapes the install dir).\n *\n * @throws An error matching `/unsafe path in manifest/` on the first bad path.\n */\nfunction assertSafeManifestPath(installPath: string, p: string): void {\n const bad = (): never => {\n throw new Error(`unsafe path in manifest: ${p}`);\n };\n if (!p || p.length === 0) bad();\n if (isAbsolute(p) || p.startsWith(\"/\") || p.startsWith(\"\\\\\")) bad();\n const segments = p.split(/[/\\\\]/);\n if (segments.some((s) => s === \"..\")) bad();\n const resolved = resolve(installPath, p);\n if (resolved !== installPath && !resolved.startsWith(installPath + sep)) bad();\n}\n\n/**\n * Validate one component (publisher / name / version) of the attacker-controlled\n * `manifest.ref`.\n *\n * `installPath` is built by joining these components onto `libraryRoot`. A\n * component containing a path separator or a `..` / leading-dot segment would\n * let `installPath` itself escape `libraryRoot` — yielding an arbitrary file\n * write AND, via the pre-write `rm(installPath, { recursive })`, an arbitrary\n * recursive delete. The per-file `assertSafeManifestPath` guard cannot catch\n * this: it only validates each `f.path` *relative to* `installPath`, never\n * `installPath` itself. Components must be plain identifier-like strings.\n *\n * @throws An error matching `/unsafe ref/` on a bad component.\n */\nfunction assertSafeRefComponent(kind: string, value: string): void {\n // Reject empty, leading-dot (covers `.` and `..`), path separators, and\n // ASCII control characters (NUL et al.) — fails a malformed segment fast\n // with a domain-specific error rather than a raw EINVAL deeper in.\n const hasControlChar = [...value].some((c) => c.charCodeAt(0) < 0x20);\n if (!value || value.startsWith(\".\") || /[/\\\\]/.test(value) || hasControlChar) {\n throw new Error(`unsafe ref ${kind} component in manifest: '${value}'`);\n }\n}\n\n/**\n * Longest common **directory** prefix across manifest paths, compared by whole\n * slash-delimited segments (never raw-string — so `app/` and `app-data/` never\n * collide). Each path's basename is excluded, so the result is always a\n * directory prefix and every path keeps a non-empty remainder after stripping.\n *\n * Used by flat mode to reproduce the platform pointer-installer's asset-rooting:\n * the store persists repo-root-relative paths (e.g. `skaile-platform/mcpo/xls/MCP.md`)\n * but the runner scans `.skaile/assets/<kind>/<name>/` for immediate-child files,\n * so this prefix is stripped from the WRITE path while the fetch keeps the full\n * repo path. Returns `''` when there is no common directory (a no-op strip).\n */\nexport function longestCommonDirPrefix(paths: readonly string[]): string {\n if (paths.length === 0) return \"\";\n const dirSegments = paths.map((p) => p.split(\"/\").slice(0, -1));\n let common = dirSegments[0]!;\n for (let i = 1; i < dirSegments.length && common.length > 0; i++) {\n const segs = dirSegments[i]!;\n let n = 0;\n while (n < common.length && n < segs.length && common[n] === segs[n]) n++;\n common = common.slice(0, n);\n }\n return common.join(\"/\");\n}\n\n/**\n * Fetcher signature — fetches `{ path → Buffer }` for the requested paths at\n * a pinned upstream commit. {@link fetchAssetFilesFromGitHub} is the default\n * production implementation; tests inject a mock.\n */\nexport type AssetFetcher = (opts: {\n url: string;\n commitSha: string;\n paths: string[];\n}) => Promise<Record<string, Buffer>>;\n\n/**\n * Options for {@link installFromManifest}.\n */\nexport interface InstallOpts {\n /** The pointer-only install manifest from the Catalog. */\n manifest: InstallManifest;\n /** Filesystem root the asset is installed under (ref-derived mode). */\n libraryRoot: string;\n /**\n * Pluggable fetcher so tests can inject mock data. Defaults to\n * {@link fetchAssetFilesFromGitHub} in production.\n */\n fetcher?: AssetFetcher;\n /**\n * Flat-layout mode. When set, install-core reproduces the platform\n * pointer-installer's behavior: it ignores `libraryRoot`/ref-derivation, does\n * NOT parse `manifest.ref` and does NOT verify the composite sha256, strips\n * the longest-common-dir prefix from each path, per-file sha256-verifies, and\n * writes the stripped paths as immediate children of `targetDir` (what the\n * runner's `.skaile/assets/<kind>/<name>/` scan requires). `installPath` is\n * `targetDir`. Absent → unchanged ref-derived `@<pub>/name/version/<path>`\n * layout with composite verify.\n */\n targetDir?: string;\n}\n\n/**\n * Result of a successful {@link installFromManifest} call.\n */\nexport interface InstallResult {\n /** Absolute path the asset files were written to. */\n installPath: string;\n}\n\n/**\n * Fetch, verify, and write an asset's files per its {@link InstallManifest}.\n *\n * @throws An error matching `/hash mismatch/i` if any per-file SHA256 differs.\n * @throws An error matching `/composite hash mismatch/i` if the rollup differs.\n * @throws An error if the ref is malformed or the fetcher omits a file.\n */\nexport async function installFromManifest(opts: InstallOpts): Promise<InstallResult> {\n const { manifest, libraryRoot } = opts;\n const fetcher =\n opts.fetcher ?? (await import(\"./source-fetch-github.js\")).fetchAssetFilesFromGitHub;\n\n // Flat mode: reproduce the platform pointer-installer's asset-rooted layout.\n // No ref parse, no composite verify — the platform store may not satisfy a\n // ref-grammar or composite, and the runner only needs immediate-child files.\n if (opts.targetDir !== undefined) {\n return installFlat(manifest, opts.targetDir, fetcher);\n }\n\n // 1. Parse ref into install path: `skill:@x/git#1.0.0` → `<root>/@x/git/1.0.0`.\n // Done first so the C1 path-traversal guard can resolve against installPath\n // BEFORE any network fetch happens. The ref is attacker-controlled, so each\n // segment is further validated as a safe path component (H1) after parsing.\n // `parseAssetRef` is the single canonical grammar (`kind:@publisher/name#version`);\n // the legacy trailing-`@version` shape was removed in core and is rejected here.\n let parsed: ReturnType<typeof parseAssetRef>;\n try {\n parsed = parseAssetRef(manifest.ref);\n } catch (e) {\n throw new Error(`invalid ref: ${manifest.ref}: ${e instanceof Error ? e.message : String(e)}`);\n }\n const publisher = parsed.publisher;\n const name = parsed.name;\n const version = parsed.pin;\n if (!publisher) throw new Error(`invalid ref: ${manifest.ref} (missing publisher)`);\n if (!version) throw new Error(`invalid ref: ${manifest.ref} (missing version pin)`);\n assertSafeRefComponent(\"publisher\", publisher);\n assertSafeRefComponent(\"name\", name);\n assertSafeRefComponent(\"version\", version);\n const root = resolve(libraryRoot);\n const installPath = resolve(join(root, `@${publisher}`, name, version));\n // Defense in depth: even with the segment guards above, assert the built\n // installPath stays strictly inside libraryRoot before any write or `rm`.\n if (installPath !== root && !installPath.startsWith(root + sep)) {\n throw new Error(`unsafe install path: ref '${manifest.ref}' resolves outside the library root`);\n }\n\n // 2. [C1] Validate EVERY manifest path against traversal BEFORE fetching.\n // The attacker controls the manifest (and thus all hashes) — hashes verify\n // content, never destination. Reject the whole install on the first bad path.\n for (const f of manifest.files) {\n assertSafeManifestPath(installPath, f.path);\n }\n\n // 3. Fetch all files at the pinned commit.\n const paths = manifest.files.map((f) => f.path);\n const bytes = await fetcher({\n url: manifest.source.url,\n commitSha: manifest.source.commitSha,\n paths,\n });\n\n // 4. Verify per-file SHA256 — hard fail before writing anything. The path\n // key used to read from the fetcher result is re-guarded as defense in depth.\n for (const f of manifest.files) {\n assertSafeManifestPath(installPath, f.path);\n const buf = bytes[f.path];\n if (!buf) throw new Error(`fetcher returned no bytes for ${f.path}`);\n const actual = createHash(\"sha256\").update(buf).digest(\"hex\");\n if (actual !== f.sha256) {\n throw new Error(`hash mismatch for ${f.path}: expected ${f.sha256}, got ${actual}`);\n }\n }\n\n // 5. Verify composite SHA256 over the sorted `<path>:<sha256>\\n` lines.\n const sortedLines = manifest.files\n .slice()\n .sort((a, b) => a.path.localeCompare(b.path))\n .map((e) => `${e.path}:${e.sha256}\\n`)\n .join(\"\");\n const actualComposite = createHash(\"sha256\").update(sortedLines, \"utf-8\").digest(\"hex\");\n if (actualComposite !== manifest.sha256) {\n throw new Error(`composite hash mismatch: expected ${manifest.sha256}, got ${actualComposite}`);\n }\n\n // 6. [M1] Write all verified files. A failed install must leave NO partial\n // directory: any prior `installPath` is removed first (clean overwrite), and\n // a mid-loop write failure removes the partially-written tree before\n // rethrowing.\n await rm(installPath, { recursive: true, force: true });\n try {\n for (const f of manifest.files) {\n const target = join(installPath, f.path);\n await mkdir(dirname(target), { recursive: true });\n await writeFile(target, bytes[f.path]!);\n }\n } catch (e) {\n await rm(installPath, { recursive: true, force: true }).catch(() => {});\n throw e;\n }\n\n return { installPath };\n}\n\n/**\n * Flat-layout install — the platform pointer-installer's behavior, made canonical\n * in install-core. Validates every path, fetches with the FULL repo paths, per-file\n * sha256-verifies, then strips the longest-common-dir prefix and writes each file\n * as `join(targetDir, path.slice(assetRoot.length + 1))` — immediate children of\n * `targetDir`. No ref parse, no composite check.\n */\nasync function installFlat(\n manifest: InstallManifest,\n targetDir: string,\n fetcher: AssetFetcher,\n): Promise<InstallResult> {\n const target = resolve(targetDir);\n\n // Gate every path before any fetch — the attacker controls the whole manifest.\n for (const f of manifest.files) {\n assertSafeManifestPath(target, f.path);\n }\n\n // Fetch keys off the FULL repo path (matches the upstream tree).\n const paths = manifest.files.map((f) => f.path);\n const bytes = await fetcher({\n url: manifest.source.url,\n commitSha: manifest.source.commitSha,\n paths,\n });\n\n // Strip the asset-root dir prefix from the WRITE path only — the fetch above\n // still keyed off the full repo path. Stripping removes leading whole segments\n // (never the basename), so a non-empty remainder always survives.\n const assetRoot = longestCommonDirPrefix(paths);\n\n for (const f of manifest.files) {\n const buf = bytes[f.path];\n if (!buf) throw new Error(`fetcher returned no bytes for ${f.path}`);\n const actual = createHash(\"sha256\").update(buf).digest(\"hex\");\n if (actual !== f.sha256) {\n throw new Error(`hash mismatch for ${f.path}: expected ${f.sha256}, got ${actual}`);\n }\n const relPath = assetRoot ? f.path.slice(assetRoot.length + 1) : f.path;\n // Re-guard the post-strip destination — it is what we actually write.\n assertSafeManifestPath(target, relPath);\n const dest = join(target, relPath);\n await mkdir(dirname(dest), { recursive: true });\n await writeFile(dest, buf);\n }\n\n return { installPath: target };\n}\n"]}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { initTelemetry } from './chunk-4R6DROGN.js';
|
|
2
2
|
import { parseSkillFrontmatter, validateFlowVersions } from './chunk-GXC3TYMQ.js';
|
|
3
|
-
import { FlowAdapter } from './chunk-
|
|
3
|
+
import { FlowAdapter } from './chunk-SC3YNS4W.js';
|
|
4
4
|
import { loadFlow } from './chunk-X46FY45B.js';
|
|
5
5
|
import { buildOrchestratorPrompt, renderStimulusPrompt } from './chunk-DEYYRFQU.js';
|
|
6
|
-
import { resolveSettings } from './chunk-
|
|
7
|
-
import { resolveAgentDir, resolveSkWorkspaceConfig } from './chunk-
|
|
6
|
+
import { resolveSettings } from './chunk-VIA64TYP.js';
|
|
7
|
+
import { resolveAgentDir, resolveSkWorkspaceConfig } from './chunk-2PXSZYKV.js';
|
|
8
8
|
import { createLogger } from './chunk-JB35MVBN.js';
|
|
9
9
|
import fs from 'fs';
|
|
10
10
|
import path from 'path';
|
|
@@ -389,5 +389,5 @@ function walkForSkill(dir, skillId) {
|
|
|
389
389
|
}
|
|
390
390
|
|
|
391
391
|
export { resumeFlow, runFlow };
|
|
392
|
-
//# sourceMappingURL=chunk-
|
|
393
|
-
//# sourceMappingURL=chunk-
|
|
392
|
+
//# sourceMappingURL=chunk-V2OSYOWR.js.map
|
|
393
|
+
//# sourceMappingURL=chunk-V2OSYOWR.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../factory-assets/connectors/flow/run-flow.ts"],"names":["c"],"mappings":"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","file":"chunk-DBL3X6V4.js","sourcesContent":["/**\n * runFlow / resumeFlow — CLI entry helpers for the flow connector.\n *\n * Moved from `runner/src/runner.ts` to `factory-assets/connectors/flow/run-flow.ts`\n * in Phase 3 of the flow-connector extraction (2026-05-08). Behaviour is\n * byte-identical to the previous runner-side implementation; only the log\n * source changes from `runner:flow:<runId>` to `flow-connector:run:<runId>`.\n *\n * The runner re-exports these symbols with a deprecation warning for one\n * release. CLI consumers should switch to\n * `import { runFlow, resumeFlow } from \"@skaile/workspaces/factory-assets/connectors/flow/run-flow\"`.\n *\n * Internal runner helpers (FlowOrchestrator, bootstrapRunnerLogStore,\n * createAgentSession, resolveDriverPaths, session helpers) are loaded lazily\n * via dynamic `await import(\"@skaile/workspaces/runner\")` inside\n * `loadRunnerModule()` below. The lazy load avoids a static package-level\n * cycle (runner → connectors → factory-assets → runner) — the cycle exists at\n * the workspace level but never resolves at module-load time because\n * factory-assets only ever calls `import` from inside an async function body.\n * The string-literal specifier preserves `bun --compile` and tsup static\n * analysis.\n */\n\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport type { AgentEvent } from \"@skaile/workspaces/bridge\";\nimport {\n resolveAgentDir,\n resolveSettings,\n resolveSkWorkspaceConfig,\n} from \"@skaile/workspaces/core\";\nimport { createLogger } from \"@skaile/workspaces/core/logging\";\nimport { parseSkillFrontmatter, validateFlowVersions } from \"@skaile/workspaces/resolver\";\nimport { initTelemetry } from \"@skaile/workspaces/telemetry\";\nimport type { FlowExecution } from \"@skaile/workspaces/types\";\nimport { FlowAdapter } from \"./adapter.js\";\nimport { loadFlow } from \"./engine/index.js\";\nimport {\n buildOrchestratorPrompt,\n renderStimulusPrompt,\n type TurnStimulus,\n} from \"./prompt-fragments.js\";\n\n/**\n * Lazy `import(\"@skaile/workspaces/runner\")` accessor. Cached on first call so\n * subsequent `runFlow` invocations don't re-evaluate the runner module.\n *\n * Dynamic ESM import is used (not `require`) so vitest and other ESM\n * bundlers honour their alias resolution — `require` would side-step the\n * configured aliases and pick up two distinct module instances when run\n * under vitest. The string-literal specifier ensures bun --compile keeps\n * the dependency (per the static-import-or-die rule in\n * connectors/CLAUDE.md).\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nlet _runnerModule: any | undefined;\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nasync function loadRunnerModule(): Promise<any> {\n if (_runnerModule) return _runnerModule;\n _runnerModule = await import(\"@skaile/workspaces/runner\");\n return _runnerModule;\n}\n\n/** Type-only re-export of SessionState so the runner tombstone shim still works. */\nexport type SessionState = import(\"@skaile/workspaces/runner\").SessionState;\n\n/** Maximum agent session duration (4 hours). Configurable via {@link RunOptions.sessionTimeoutMs}. */\nconst DEFAULT_SESSION_TIMEOUT_MS = 4 * 60 * 60 * 1000; // 4 hours\n\n/**\n * Options for {@link runFlow}.\n *\n * Wraps `FlowOrchestrator` with autonomous mode turned on by default so\n * interactive approval/input gates don't block a terminal run.\n *\n * @docLink packages/factory-assets/flow#run-flow\n */\nexport interface RunOptions {\n /** The working directory for the project being orchestrated. */\n projectDir: string;\n /** Absolute path to the `.flow.yaml` or `.flow.json` definition file. */\n flowPath: string;\n /**\n * Directory containing `agent.yaml`, `SOUL.md`, `RULES.md`, `knowledge/`.\n * Resolved from `skaile.yaml` via `resolveAgentDir` when absent.\n */\n agentDir?: string;\n /**\n * Agent driver backend. Defaults to `settings.driver` (`\"omp\"` or `\"claude-sdk\"`).\n */\n driver?: string;\n /**\n * LLM provider override (e.g. `\"anthropic\"`, `\"openrouter\"`).\n * Falls back to `settings.provider` when absent.\n */\n provider?: string;\n /**\n * Model name override. Falls back to `settings.model` when absent.\n */\n model?: string;\n /**\n * Path to a specific `settings.json` to load instead of the default\n * layered resolution chain (project → parent → global → built-in defaults).\n */\n settingsFile?: string;\n /**\n * When `true`, prints the initial flow state without starting the agent\n * and returns immediately.\n */\n dryRun?: boolean;\n /**\n * Per-session timeout in milliseconds. Defaults to\n * {@link DEFAULT_SESSION_TIMEOUT_MS} (4 hours).\n */\n sessionTimeoutMs?: number;\n /** Optional human-readable label shown in the session list. */\n sessionLabel?: string;\n /** Autonomous mode for CLI runs — defaults to true so interactive approval gates are skipped. */\n autonomousMode?: boolean;\n /**\n * Called for each {@link AgentEvent} emitted during the run\n * (e.g. `text`, `tool_call`, `state_changed`).\n */\n onEvent?: (event: AgentEvent) => void;\n /**\n * Called for each diagnostic log line. Defaults to `process.stdout`.\n */\n onLog?: (line: string) => void;\n}\n\n/**\n * Options for resuming an existing CLI session.\n *\n * Reconnects the driver's conversation thread (conversation history is\n * preserved via the stored `driverSessionId`) but restarts flow execution\n * from scratch — flow state is not persisted in CLI mode. For governed,\n * resumable flow runs use a host that persists flow state (e.g. the Skaile\n * platform).\n *\n * @docLink packages/factory-assets/flow#resume-flow\n */\nexport interface ResumeOptions {\n /** The working directory for the project being orchestrated. */\n projectDir: string;\n /**\n * Specific run ID to resume. When absent, the current session pointer\n * at `<projectDir>/.skaile/current` is used.\n */\n sessionId?: string;\n /**\n * Agent definition directory override. Defaults to the directory stored\n * in the session file.\n */\n agentDir?: string;\n /**\n * When `true`, prints the initial flow state without starting the agent\n * and returns immediately.\n */\n dryRun?: boolean;\n /**\n * Per-session timeout in milliseconds. Defaults to\n * {@link DEFAULT_SESSION_TIMEOUT_MS} (4 hours).\n */\n sessionTimeoutMs?: number;\n /**\n * Called for each {@link AgentEvent} emitted during the run.\n */\n onEvent?: RunOptions[\"onEvent\"];\n /**\n * Called for each diagnostic log line. Defaults to `process.stdout`.\n */\n onLog?: RunOptions[\"onLog\"];\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Start a new flow session from the CLI.\n *\n * Wraps `FlowOrchestrator` with autonomous mode turned on by default so\n * interactive approval/input gates don't block a terminal run. The\n * runner remains idle between turns — for the CLI use case, a single\n * turn should carry the flow to completion in autonomous mode. Non-CLI\n * hosts (Skaile platform, Pichi) use the orchestrator directly via the\n * serve command surface and drive gates through user actions.\n *\n * @docLink packages/factory-assets/flow#run-flow\n */\nexport async function runFlow(opts: RunOptions): Promise<void> {\n const runner = await loadRunnerModule();\n const {\n bootstrapRunnerLogStore,\n createAgentSession,\n createSessionStimulusBus,\n resolveDriverPaths,\n newSession,\n saveSession,\n touchSession,\n } = runner;\n\n const flow = loadFlow(opts.flowPath);\n const agentDir = opts.agentDir ?? resolveAgentDir(opts.projectDir);\n const settings = await resolveSettings(opts.projectDir, {\n driver: opts.driver,\n provider: opts.provider,\n model: opts.model,\n });\n\n const session = newSession({\n flowId: flow.id,\n projectDir: opts.projectDir,\n agentDir,\n driver: settings.driver ?? \"omp\",\n provider: settings.provider,\n model: settings.model,\n label: opts.sessionLabel,\n });\n\n await saveSession(opts.projectDir, session);\n\n // Bootstrap structured logging — registers a process-singleton LogStore.\n // OnLogBridgeSink mirrors entries to opts.onLog when caller provides one,\n // preserving back-compat with CLI hosts that consume plain text lines.\n const wsConfigEarly = resolveSkWorkspaceConfig(opts.projectDir);\n const { dispose: disposeLogStore } = bootstrapRunnerLogStore({\n sessionId: session.runId,\n projectDir: opts.projectDir,\n yamlBlock: (wsConfigEarly as { logging?: unknown }).logging,\n onLog: opts.onLog,\n });\n const flowLog = createLogger({\n kind: \"flow-connector\",\n subkind: \"run\",\n instance: session.runId,\n });\n const log = (line: string) => flowLog.info(line);\n\n try {\n // ── Dry run ────────────────────────────────────────────────────────────\n if (opts.dryRun) {\n const adapter = new FlowAdapter();\n const handle = await adapter.connect(\n {\n id: \"flow\",\n driver: \"flow\",\n access: \"read-only\" as const,\n options: { flow, seed: { runId: session.runId, startedBy: \"cli\" } },\n },\n {}, // flow needs no connect context\n );\n const state = adapter.getExecution(handle);\n const available = Object.values(state.nodes)\n .filter((n) => n.status === \"available\")\n .map((n) => n.id);\n log(`[dry-run] Flow: ${flow.name} (${flow.id})`);\n log(`[dry-run] Available: ${available.join(\", \") || \"(none)\"}`);\n await adapter.disconnect(handle);\n return;\n }\n\n await validatePinnedVersions(flow, opts.projectDir, log);\n\n // ── Telemetry initialization ────────────────────────────────────────────\n const wsConfig = wsConfigEarly;\n const telemetry = await initTelemetry(wsConfig.telemetry);\n const flowTrace = telemetry.startTrace({\n name: `flow:${flow.id}`,\n kind: \"flow_run\",\n attributes: {\n \"skaile.flow.id\": flow.id,\n \"skaile.flow.run_id\": session.runId,\n },\n });\n\n // ── Agent session setup ─────────────────────────────────────────────────\n const driverPaths = resolveDriverPaths(settings);\n const agentSession = await createAgentSession({\n projectDir: opts.projectDir,\n agentDir: session.agentDir,\n driver: session.driver,\n model: session.model,\n provider: session.provider,\n resumeSessionId: session.driverSessionId,\n projectClaudeMd: path.join(opts.projectDir, \"CLAUDE.md\"),\n promptsDir: path.join(opts.projectDir, driverPaths.promptsDir),\n sessionId: session.runId,\n onLog: log,\n telemetry,\n trace: flowTrace,\n wsConfig,\n });\n const { driver } = agentSession;\n const updatedSession = { ...session };\n\n // Track driver session ID so future resumes can reconnect the SDK thread.\n driver.on(\"agent-event\", () => {\n const runtimeSessionId = driver.runtimeSessionId;\n if (!runtimeSessionId || runtimeSessionId === updatedSession.driverSessionId) return;\n updatedSession.driverSessionId = runtimeSessionId;\n void saveSession(opts.projectDir, updatedSession).catch(() => {});\n });\n\n // ── FlowAdapter + stimulus bus ─────────────────────────────────────────\n //\n // Phase 4 of the flow-connector extraction: SessionStimulusBus is the sole\n // turn driver. The legacy FlowOrchestrator + onStateChange subscription\n // are gone — every turn is initiated either by the bus (after an adapter\n // mutation observed via `useBusForStimulus: true`) or by an explicit\n // `bus.signal()` call from this function (the initial flow_started turn).\n //\n // The bus's `driveTurn` callback receives the stimulus paragraph the\n // adapter rendered (not the full orchestrator prompt). It rebuilds the\n // five-section orchestrator prompt around that fragment using\n // `buildOrchestratorPrompt` so the agent sees the same flow context the\n // legacy orchestrator produced.\n const flowConnectorId = \"flow\";\n const turnTimeoutMs = opts.sessionTimeoutMs ?? DEFAULT_SESSION_TIMEOUT_MS;\n\n // Forward declaration so `driveTurn` can read the live execution\n // snapshot. Assigned just below, before the bus can fire.\n let flowAdapterRef: FlowAdapter | null = null;\n let flowHandleRef: import(\"@skaile/workspaces/connectors\").ConnectorHandle | null = null;\n\n const stimulusBus = createSessionStimulusBus({\n driveTurn: async (\n promptFragment: string,\n metas: Array<Record<string, unknown>>,\n ): Promise<void> => {\n // The adapter signal carries `meta.kind` per stimulus. Use that to\n // reconstruct the typed `TurnStimulus`; for compound batches, fall\n // back to `state_changed` (the union element that means \"look at\n // current state and continue\").\n const lastKind = metas[metas.length - 1]?.kind;\n let stimulus: TurnStimulus;\n if (lastKind === \"flow_started\") {\n stimulus = { kind: \"flow_started\" };\n } else if (\n lastKind === \"user_message\" &&\n typeof metas[metas.length - 1]?.text === \"string\"\n ) {\n const meta = metas[metas.length - 1] as Record<string, unknown>;\n stimulus = {\n kind: \"user_message\",\n text: String(meta.text ?? \"\"),\n senderId: String(meta.senderId ?? \"user\"),\n };\n } else {\n stimulus = { kind: \"state_changed\" };\n }\n // The fragment passed in by the bus is the adapter's\n // `renderStimulusPrompt(stim)` joined across coalesced signals.\n // For the initial / explicit-stimulus path, we build the full prompt\n // around the fragment via `buildOrchestratorPrompt`. The fragment is\n // discarded in favour of the structured stimulus to keep the prompt\n // shape stable; the structured form already contains everything the\n // fragment encoded.\n void promptFragment;\n if (!flowAdapterRef || !flowHandleRef) {\n throw new Error(\"driveTurn fired before FlowAdapter was wired\");\n }\n const fullPrompt = buildOrchestratorPrompt(\n flow,\n flowAdapterRef.getExecution(flowHandleRef),\n stimulus,\n );\n await awaitAgentEnd(driver, fullPrompt, opts.onEvent, turnTimeoutMs);\n },\n log: flowLog,\n });\n\n const flowAdapter = new FlowAdapter();\n const flowHandle = await flowAdapter.connect(\n {\n id: flowConnectorId,\n driver: \"flow\",\n access: \"read-write\" as const,\n options: {\n flow,\n seed: {\n runId: session.runId,\n startedBy: \"cli\",\n autonomousMode: opts.autonomousMode ?? true,\n },\n stimulusBus,\n useBusForStimulus: true,\n },\n },\n {}, // flow needs no connect context\n );\n flowAdapterRef = flowAdapter;\n flowHandleRef = flowHandle;\n\n // Forward state_changed events to the caller. The bus computes a\n // turn-kicking stimulus on each adapter mutation; the host-facing\n // event stream still observes the full snapshot via onChange.\n flowAdapter.onStateChange(flowHandle, (state: FlowExecution) => {\n opts.onEvent?.({\n type: \"state_changed\",\n store: `flow:${state.runId}`,\n state: state as unknown as Record<string, unknown>,\n } as unknown as AgentEvent);\n });\n\n // ── Execute ────────────────────────────────────────────────────────────\n flowLog.info(\"starting flow\", {\n flowId: flow.id,\n flowName: flow.name,\n runId: session.runId,\n });\n\n try {\n // Kick the initial flow_started turn explicitly. Subsequent turns are\n // driven by the bus signaling whenever the adapter mutates.\n const initialStimulus: TurnStimulus = { kind: \"flow_started\" };\n await stimulusBus.signal(flowConnectorId, {\n promptFragment: renderStimulusPrompt(initialStimulus),\n meta: { kind: initialStimulus.kind },\n });\n\n const finalState = flowAdapter.getExecution(flowHandle);\n if (finalState.done) {\n flowLog.info(\"flow complete\", { flowId: flow.id, flowName: flow.name });\n } else if (finalState.status === \"failed\") {\n flowLog.error(\"flow failed\", undefined, { flowId: flow.id, flowName: flow.name });\n } else {\n flowLog.warn(\"flow paused after one turn\", {\n flowId: flow.id,\n status: finalState.status,\n note: \"CLI mode does not interact with approval/input gates\",\n });\n }\n } finally {\n driver.kill();\n const lastState = flowAdapter.getExecution(flowHandle);\n await saveSession(\n opts.projectDir,\n touchSession({\n ...updatedSession,\n driverSessionId: driver.runtimeSessionId ?? updatedSession.driverSessionId,\n status: lastState.status === \"complete\" ? \"complete\" : \"paused\",\n }),\n ).catch(() => {});\n await flowAdapter.disconnect(flowHandle).catch(() => {});\n await agentSession.dispose();\n telemetry.endTrace(flowTrace, {\n status: flowAdapter.getExecution(flowHandle).status === \"complete\" ? \"ok\" : \"error\",\n });\n await telemetry.flush().catch(() => {});\n }\n } finally {\n disposeLogStore();\n }\n}\n\n/**\n * Resume an existing session from the CLI.\n *\n * With the Phase 2 turn-based model, flow state is NOT persisted to\n * local session files — only the driver session ID is kept. The CLI\n * can resume the agent's conversation thread, but the flow execution\n * itself starts from scratch because the runner has no durable store\n * for per-run state.\n *\n * For a governed, resumable flow run, use a host that persists flow\n * state (e.g. the Skaile platform). CLI resume is retained as a\n * driver-level convenience only: we load the session, restart the\n * flow, and the SDK will reconnect to the prior conversation thread.\n *\n * @docLink packages/factory-assets/flow#resume-flow\n */\nexport async function resumeFlow(opts: ResumeOptions): Promise<void> {\n const runner = await loadRunnerModule();\n const { loadSession, loadSessionById, bootstrapRunnerLogStore } = runner;\n\n const session = opts.sessionId\n ? await loadSessionById(opts.projectDir, opts.sessionId)\n : await loadSession(opts.projectDir);\n\n if (!session) {\n const hint = opts.sessionId\n ? `session ${opts.sessionId}`\n : `current session in ${opts.projectDir}/.skaile`;\n throw new Error(`No session found (${hint}) — run 'start' first`);\n }\n\n const flowPath = resolveFlowPath(session.flowId, opts.projectDir);\n\n // Bootstrap a transient logger for the resume diagnostics. The inner\n // runFlow() call will register its own LogStore for the new run. Keep\n // OnLogBridgeSink wiring so callers passing onLog still see this line.\n const wsConfigEarly = resolveSkWorkspaceConfig(opts.projectDir);\n const { dispose: disposeLogStore } = bootstrapRunnerLogStore({\n sessionId: session.runId,\n projectDir: opts.projectDir,\n yamlBlock: (wsConfigEarly as { logging?: unknown }).logging,\n onLog: opts.onLog,\n });\n const flowLog = createLogger({\n kind: \"flow-connector\",\n subkind: \"run\",\n instance: session.runId,\n });\n flowLog.info(\"resuming session\", {\n runId: session.runId,\n flowId: session.flowId,\n note: \"CLI mode does not persist flow state — flow restarts from scratch; driver thread resumes\",\n });\n\n try {\n await runFlow({\n projectDir: opts.projectDir,\n flowPath,\n agentDir: opts.agentDir ?? session.agentDir,\n driver: session.driver,\n model: session.model,\n provider: session.provider,\n sessionLabel: session.label,\n dryRun: opts.dryRun,\n sessionTimeoutMs: opts.sessionTimeoutMs,\n onEvent: opts.onEvent,\n onLog: opts.onLog,\n });\n } finally {\n disposeLogStore();\n }\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nasync function validatePinnedVersions(\n flow: Awaited<ReturnType<typeof loadFlow>>,\n projectDir: string,\n log: (line: string) => void,\n): Promise<void> {\n const pinnedNodes = flow.nodes.filter((n) => n.type === \"skill\" && n.data?.version);\n if (pinnedNodes.length === 0) return;\n\n const skillVersions = new Map<string, string>();\n const aiResourcesDir = findAiResourcesDir(projectDir);\n if (aiResourcesDir) {\n for (const node of pinnedNodes) {\n const skillId = node.data?.skill ?? node.id;\n if (skillVersions.has(skillId)) continue;\n const skillPath = findSkillMd(aiResourcesDir, skillId);\n if (skillPath) {\n const content = fs.readFileSync(skillPath, \"utf-8\");\n const fm = parseSkillFrontmatter(content);\n skillVersions.set(skillId, fm.metadata?.version ?? fm.version ?? \"\");\n }\n }\n }\n\n const versionNodes = pinnedNodes.map((n) => ({\n nodeId: n.id,\n skillId: n.data?.skill ?? n.id,\n requestedVersion: n.data?.version,\n }));\n\n const checks = validateFlowVersions(versionNodes, skillVersions);\n const failures = checks.filter((c) => !c.satisfied);\n if (failures.length > 0) {\n const lines = failures.map(\n (f) => ` ${f.nodeId}: wants ${f.requested}, found ${f.actual || \"(none)\"}`,\n );\n throw new Error(`Skill version mismatch:\\n${lines.join(\"\\n\")}`);\n }\n for (const c of checks.filter((c) => c.satisfied)) {\n log(` Version OK: ${c.skillId} ${c.actual} satisfies ${c.requested}`);\n }\n}\n\nfunction resolveFlowPath(flowId: string, projectDir: string): string {\n const armInstalled = path.join(projectDir, \".skaile\", \"flows\", flowId, `${flowId}.flow.yaml`);\n if (fs.existsSync(armInstalled)) return armInstalled;\n\n const manual = path.join(projectDir, \".skaile\", \"flows\", `${flowId}.flow.yaml`);\n if (fs.existsSync(manual)) return manual;\n\n let dir = projectDir;\n for (let i = 0; i < 6; i++) {\n const aiResources = path.join(dir, \"ai-assets\");\n if (fs.existsSync(aiResources)) {\n for (const domain of fs.readdirSync(aiResources)) {\n const flowsDir = path.join(aiResources, domain, \"flows\");\n const candidate = path.join(flowsDir, `${flowId}.flow.yaml`);\n if (fs.existsSync(candidate)) return candidate;\n const legacy = path.join(flowsDir, `${flowId}.json`);\n if (fs.existsSync(legacy)) return legacy;\n }\n throw new Error(`Flow not found: ${flowId} (searched .skaile/flows/ and ${aiResources})`);\n }\n dir = path.dirname(dir);\n }\n throw new Error(\n `Flow not found: ${flowId} (no .skaile/flows/ entry and could not locate ai-assets from ${projectDir})`,\n );\n}\n\n/** Walk up from projectDir to find ai-assets/ */\nfunction findAiResourcesDir(projectDir: string): string | null {\n let dir = projectDir;\n for (let i = 0; i < 6; i++) {\n const candidate = path.join(dir, \"ai-assets\");\n if (fs.existsSync(candidate)) return candidate;\n const parent = path.dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n return null;\n}\n\n/** Find SKILL.md for a given skill ID by walking ai-assets domains */\nfunction findSkillMd(aiResourcesDir: string, skillId: string): string | null {\n for (const domain of fs.readdirSync(aiResourcesDir, { withFileTypes: true })) {\n if (!domain.isDirectory()) continue;\n const skillsDir = path.join(aiResourcesDir, domain.name, \"skills\");\n if (!fs.existsSync(skillsDir)) continue;\n const found = walkForSkill(skillsDir, skillId);\n if (found) return found;\n }\n return null;\n}\n\n// ---------------------------------------------------------------------------\n// Turn-wait helper\n// ---------------------------------------------------------------------------\n\n/**\n * Minimal driver surface needed by the bus's `driveTurn` callback. Mirrors\n * the slice the legacy `FlowOrchestrator` consumed (`prompt` + `on` +\n * `removeAllListeners`) so we can keep the wait helper private to this\n * module without pulling in a runtime dep on `@skaile/workspaces/bridge`.\n */\ninterface TurnDriverSurface {\n prompt(message: string): Promise<void>;\n on(event: \"agent-event\", handler: (event: AgentEvent) => void): void;\n removeAllListeners(event: \"agent-event\"): void;\n}\n\n/**\n * Send a prompt to the driver and resolve when the agent emits\n * `agent_end` (or reject on `error`). Identical contract to the legacy\n * `awaitAgentEnd` helper from `flow-orchestrator.ts`. Phase 4 lifts the\n * helper into `run-flow.ts` because the bus now owns turn driving.\n */\nfunction awaitAgentEnd(\n driver: TurnDriverSurface,\n prompt: string,\n onEvent: ((event: AgentEvent) => void) | undefined,\n timeoutMs: number,\n): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n let settled = false;\n\n const done = (err?: Error) => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n driver.removeAllListeners(\"agent-event\");\n if (err) reject(err);\n else resolve();\n };\n\n const timer = setTimeout(\n () => done(new Error(`Flow turn timed out after ${timeoutMs / 1000}s`)),\n timeoutMs,\n );\n\n driver.on(\"agent-event\", (event: AgentEvent) => {\n onEvent?.(event);\n if (event.type === \"agent_end\") done();\n else if (event.type === \"error\") {\n const msg =\n (event as { error?: string; message?: string }).error ??\n (event as { message?: string }).message ??\n \"Agent error\";\n done(new Error(msg));\n }\n });\n\n driver.prompt(prompt).catch(done);\n });\n}\n\nfunction walkForSkill(dir: string, skillId: string): string | null {\n for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {\n if (!entry.isDirectory()) continue;\n const full = path.join(dir, entry.name);\n const skillMd = path.join(full, \"SKILL.md\");\n if (fs.existsSync(skillMd)) {\n if (entry.name === skillId) return skillMd;\n } else {\n const found = walkForSkill(full, skillId);\n if (found) return found;\n }\n }\n return null;\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../factory-assets/connectors/flow/run-flow.ts"],"names":["c"],"mappings":"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","file":"chunk-V2OSYOWR.js","sourcesContent":["/**\n * runFlow / resumeFlow — CLI entry helpers for the flow connector.\n *\n * Moved from `runner/src/runner.ts` to `factory-assets/connectors/flow/run-flow.ts`\n * in Phase 3 of the flow-connector extraction (2026-05-08). Behaviour is\n * byte-identical to the previous runner-side implementation; only the log\n * source changes from `runner:flow:<runId>` to `flow-connector:run:<runId>`.\n *\n * The runner re-exports these symbols with a deprecation warning for one\n * release. CLI consumers should switch to\n * `import { runFlow, resumeFlow } from \"@skaile/workspaces/factory-assets/connectors/flow/run-flow\"`.\n *\n * Internal runner helpers (FlowOrchestrator, bootstrapRunnerLogStore,\n * createAgentSession, resolveDriverPaths, session helpers) are loaded lazily\n * via dynamic `await import(\"@skaile/workspaces/runner\")` inside\n * `loadRunnerModule()` below. The lazy load avoids a static package-level\n * cycle (runner → connectors → factory-assets → runner) — the cycle exists at\n * the workspace level but never resolves at module-load time because\n * factory-assets only ever calls `import` from inside an async function body.\n * The string-literal specifier preserves `bun --compile` and tsup static\n * analysis.\n */\n\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport type { AgentEvent } from \"@skaile/workspaces/bridge\";\nimport {\n resolveAgentDir,\n resolveSettings,\n resolveSkWorkspaceConfig,\n} from \"@skaile/workspaces/core\";\nimport { createLogger } from \"@skaile/workspaces/core/logging\";\nimport { parseSkillFrontmatter, validateFlowVersions } from \"@skaile/workspaces/resolver\";\nimport { initTelemetry } from \"@skaile/workspaces/telemetry\";\nimport type { FlowExecution } from \"@skaile/workspaces/types\";\nimport { FlowAdapter } from \"./adapter.js\";\nimport { loadFlow } from \"./engine/index.js\";\nimport {\n buildOrchestratorPrompt,\n renderStimulusPrompt,\n type TurnStimulus,\n} from \"./prompt-fragments.js\";\n\n/**\n * Lazy `import(\"@skaile/workspaces/runner\")` accessor. Cached on first call so\n * subsequent `runFlow` invocations don't re-evaluate the runner module.\n *\n * Dynamic ESM import is used (not `require`) so vitest and other ESM\n * bundlers honour their alias resolution — `require` would side-step the\n * configured aliases and pick up two distinct module instances when run\n * under vitest. The string-literal specifier ensures bun --compile keeps\n * the dependency (per the static-import-or-die rule in\n * connectors/CLAUDE.md).\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nlet _runnerModule: any | undefined;\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nasync function loadRunnerModule(): Promise<any> {\n if (_runnerModule) return _runnerModule;\n _runnerModule = await import(\"@skaile/workspaces/runner\");\n return _runnerModule;\n}\n\n/** Type-only re-export of SessionState so the runner tombstone shim still works. */\nexport type SessionState = import(\"@skaile/workspaces/runner\").SessionState;\n\n/** Maximum agent session duration (4 hours). Configurable via {@link RunOptions.sessionTimeoutMs}. */\nconst DEFAULT_SESSION_TIMEOUT_MS = 4 * 60 * 60 * 1000; // 4 hours\n\n/**\n * Options for {@link runFlow}.\n *\n * Wraps `FlowOrchestrator` with autonomous mode turned on by default so\n * interactive approval/input gates don't block a terminal run.\n *\n * @docLink packages/factory-assets/flow#run-flow\n */\nexport interface RunOptions {\n /** The working directory for the project being orchestrated. */\n projectDir: string;\n /** Absolute path to the `.flow.yaml` or `.flow.json` definition file. */\n flowPath: string;\n /**\n * Directory containing `agent.yaml`, `SOUL.md`, `RULES.md`, `knowledge/`.\n * Resolved from `skaile.yaml` via `resolveAgentDir` when absent.\n */\n agentDir?: string;\n /**\n * Agent driver backend. Defaults to `settings.driver` (`\"omp\"` or `\"claude-sdk\"`).\n */\n driver?: string;\n /**\n * LLM provider override (e.g. `\"anthropic\"`, `\"openrouter\"`).\n * Falls back to `settings.provider` when absent.\n */\n provider?: string;\n /**\n * Model name override. Falls back to `settings.model` when absent.\n */\n model?: string;\n /**\n * Path to a specific `settings.json` to load instead of the default\n * layered resolution chain (project → parent → global → built-in defaults).\n */\n settingsFile?: string;\n /**\n * When `true`, prints the initial flow state without starting the agent\n * and returns immediately.\n */\n dryRun?: boolean;\n /**\n * Per-session timeout in milliseconds. Defaults to\n * {@link DEFAULT_SESSION_TIMEOUT_MS} (4 hours).\n */\n sessionTimeoutMs?: number;\n /** Optional human-readable label shown in the session list. */\n sessionLabel?: string;\n /** Autonomous mode for CLI runs — defaults to true so interactive approval gates are skipped. */\n autonomousMode?: boolean;\n /**\n * Called for each {@link AgentEvent} emitted during the run\n * (e.g. `text`, `tool_call`, `state_changed`).\n */\n onEvent?: (event: AgentEvent) => void;\n /**\n * Called for each diagnostic log line. Defaults to `process.stdout`.\n */\n onLog?: (line: string) => void;\n}\n\n/**\n * Options for resuming an existing CLI session.\n *\n * Reconnects the driver's conversation thread (conversation history is\n * preserved via the stored `driverSessionId`) but restarts flow execution\n * from scratch — flow state is not persisted in CLI mode. For governed,\n * resumable flow runs use a host that persists flow state (e.g. the Skaile\n * platform).\n *\n * @docLink packages/factory-assets/flow#resume-flow\n */\nexport interface ResumeOptions {\n /** The working directory for the project being orchestrated. */\n projectDir: string;\n /**\n * Specific run ID to resume. When absent, the current session pointer\n * at `<projectDir>/.skaile/current` is used.\n */\n sessionId?: string;\n /**\n * Agent definition directory override. Defaults to the directory stored\n * in the session file.\n */\n agentDir?: string;\n /**\n * When `true`, prints the initial flow state without starting the agent\n * and returns immediately.\n */\n dryRun?: boolean;\n /**\n * Per-session timeout in milliseconds. Defaults to\n * {@link DEFAULT_SESSION_TIMEOUT_MS} (4 hours).\n */\n sessionTimeoutMs?: number;\n /**\n * Called for each {@link AgentEvent} emitted during the run.\n */\n onEvent?: RunOptions[\"onEvent\"];\n /**\n * Called for each diagnostic log line. Defaults to `process.stdout`.\n */\n onLog?: RunOptions[\"onLog\"];\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Start a new flow session from the CLI.\n *\n * Wraps `FlowOrchestrator` with autonomous mode turned on by default so\n * interactive approval/input gates don't block a terminal run. The\n * runner remains idle between turns — for the CLI use case, a single\n * turn should carry the flow to completion in autonomous mode. Non-CLI\n * hosts (Skaile platform, Pichi) use the orchestrator directly via the\n * serve command surface and drive gates through user actions.\n *\n * @docLink packages/factory-assets/flow#run-flow\n */\nexport async function runFlow(opts: RunOptions): Promise<void> {\n const runner = await loadRunnerModule();\n const {\n bootstrapRunnerLogStore,\n createAgentSession,\n createSessionStimulusBus,\n resolveDriverPaths,\n newSession,\n saveSession,\n touchSession,\n } = runner;\n\n const flow = loadFlow(opts.flowPath);\n const agentDir = opts.agentDir ?? resolveAgentDir(opts.projectDir);\n const settings = await resolveSettings(opts.projectDir, {\n driver: opts.driver,\n provider: opts.provider,\n model: opts.model,\n });\n\n const session = newSession({\n flowId: flow.id,\n projectDir: opts.projectDir,\n agentDir,\n driver: settings.driver ?? \"omp\",\n provider: settings.provider,\n model: settings.model,\n label: opts.sessionLabel,\n });\n\n await saveSession(opts.projectDir, session);\n\n // Bootstrap structured logging — registers a process-singleton LogStore.\n // OnLogBridgeSink mirrors entries to opts.onLog when caller provides one,\n // preserving back-compat with CLI hosts that consume plain text lines.\n const wsConfigEarly = resolveSkWorkspaceConfig(opts.projectDir);\n const { dispose: disposeLogStore } = bootstrapRunnerLogStore({\n sessionId: session.runId,\n projectDir: opts.projectDir,\n yamlBlock: (wsConfigEarly as { logging?: unknown }).logging,\n onLog: opts.onLog,\n });\n const flowLog = createLogger({\n kind: \"flow-connector\",\n subkind: \"run\",\n instance: session.runId,\n });\n const log = (line: string) => flowLog.info(line);\n\n try {\n // ── Dry run ────────────────────────────────────────────────────────────\n if (opts.dryRun) {\n const adapter = new FlowAdapter();\n const handle = await adapter.connect(\n {\n id: \"flow\",\n driver: \"flow\",\n access: \"read-only\" as const,\n options: { flow, seed: { runId: session.runId, startedBy: \"cli\" } },\n },\n {}, // flow needs no connect context\n );\n const state = adapter.getExecution(handle);\n const available = Object.values(state.nodes)\n .filter((n) => n.status === \"available\")\n .map((n) => n.id);\n log(`[dry-run] Flow: ${flow.name} (${flow.id})`);\n log(`[dry-run] Available: ${available.join(\", \") || \"(none)\"}`);\n await adapter.disconnect(handle);\n return;\n }\n\n await validatePinnedVersions(flow, opts.projectDir, log);\n\n // ── Telemetry initialization ────────────────────────────────────────────\n const wsConfig = wsConfigEarly;\n const telemetry = await initTelemetry(wsConfig.telemetry);\n const flowTrace = telemetry.startTrace({\n name: `flow:${flow.id}`,\n kind: \"flow_run\",\n attributes: {\n \"skaile.flow.id\": flow.id,\n \"skaile.flow.run_id\": session.runId,\n },\n });\n\n // ── Agent session setup ─────────────────────────────────────────────────\n const driverPaths = resolveDriverPaths(settings);\n const agentSession = await createAgentSession({\n projectDir: opts.projectDir,\n agentDir: session.agentDir,\n driver: session.driver,\n model: session.model,\n provider: session.provider,\n resumeSessionId: session.driverSessionId,\n projectClaudeMd: path.join(opts.projectDir, \"CLAUDE.md\"),\n promptsDir: path.join(opts.projectDir, driverPaths.promptsDir),\n sessionId: session.runId,\n onLog: log,\n telemetry,\n trace: flowTrace,\n wsConfig,\n });\n const { driver } = agentSession;\n const updatedSession = { ...session };\n\n // Track driver session ID so future resumes can reconnect the SDK thread.\n driver.on(\"agent-event\", () => {\n const runtimeSessionId = driver.runtimeSessionId;\n if (!runtimeSessionId || runtimeSessionId === updatedSession.driverSessionId) return;\n updatedSession.driverSessionId = runtimeSessionId;\n void saveSession(opts.projectDir, updatedSession).catch(() => {});\n });\n\n // ── FlowAdapter + stimulus bus ─────────────────────────────────────────\n //\n // Phase 4 of the flow-connector extraction: SessionStimulusBus is the sole\n // turn driver. The legacy FlowOrchestrator + onStateChange subscription\n // are gone — every turn is initiated either by the bus (after an adapter\n // mutation observed via `useBusForStimulus: true`) or by an explicit\n // `bus.signal()` call from this function (the initial flow_started turn).\n //\n // The bus's `driveTurn` callback receives the stimulus paragraph the\n // adapter rendered (not the full orchestrator prompt). It rebuilds the\n // five-section orchestrator prompt around that fragment using\n // `buildOrchestratorPrompt` so the agent sees the same flow context the\n // legacy orchestrator produced.\n const flowConnectorId = \"flow\";\n const turnTimeoutMs = opts.sessionTimeoutMs ?? DEFAULT_SESSION_TIMEOUT_MS;\n\n // Forward declaration so `driveTurn` can read the live execution\n // snapshot. Assigned just below, before the bus can fire.\n let flowAdapterRef: FlowAdapter | null = null;\n let flowHandleRef: import(\"@skaile/workspaces/connectors\").ConnectorHandle | null = null;\n\n const stimulusBus = createSessionStimulusBus({\n driveTurn: async (\n promptFragment: string,\n metas: Array<Record<string, unknown>>,\n ): Promise<void> => {\n // The adapter signal carries `meta.kind` per stimulus. Use that to\n // reconstruct the typed `TurnStimulus`; for compound batches, fall\n // back to `state_changed` (the union element that means \"look at\n // current state and continue\").\n const lastKind = metas[metas.length - 1]?.kind;\n let stimulus: TurnStimulus;\n if (lastKind === \"flow_started\") {\n stimulus = { kind: \"flow_started\" };\n } else if (\n lastKind === \"user_message\" &&\n typeof metas[metas.length - 1]?.text === \"string\"\n ) {\n const meta = metas[metas.length - 1] as Record<string, unknown>;\n stimulus = {\n kind: \"user_message\",\n text: String(meta.text ?? \"\"),\n senderId: String(meta.senderId ?? \"user\"),\n };\n } else {\n stimulus = { kind: \"state_changed\" };\n }\n // The fragment passed in by the bus is the adapter's\n // `renderStimulusPrompt(stim)` joined across coalesced signals.\n // For the initial / explicit-stimulus path, we build the full prompt\n // around the fragment via `buildOrchestratorPrompt`. The fragment is\n // discarded in favour of the structured stimulus to keep the prompt\n // shape stable; the structured form already contains everything the\n // fragment encoded.\n void promptFragment;\n if (!flowAdapterRef || !flowHandleRef) {\n throw new Error(\"driveTurn fired before FlowAdapter was wired\");\n }\n const fullPrompt = buildOrchestratorPrompt(\n flow,\n flowAdapterRef.getExecution(flowHandleRef),\n stimulus,\n );\n await awaitAgentEnd(driver, fullPrompt, opts.onEvent, turnTimeoutMs);\n },\n log: flowLog,\n });\n\n const flowAdapter = new FlowAdapter();\n const flowHandle = await flowAdapter.connect(\n {\n id: flowConnectorId,\n driver: \"flow\",\n access: \"read-write\" as const,\n options: {\n flow,\n seed: {\n runId: session.runId,\n startedBy: \"cli\",\n autonomousMode: opts.autonomousMode ?? true,\n },\n stimulusBus,\n useBusForStimulus: true,\n },\n },\n {}, // flow needs no connect context\n );\n flowAdapterRef = flowAdapter;\n flowHandleRef = flowHandle;\n\n // Forward state_changed events to the caller. The bus computes a\n // turn-kicking stimulus on each adapter mutation; the host-facing\n // event stream still observes the full snapshot via onChange.\n flowAdapter.onStateChange(flowHandle, (state: FlowExecution) => {\n opts.onEvent?.({\n type: \"state_changed\",\n store: `flow:${state.runId}`,\n state: state as unknown as Record<string, unknown>,\n } as unknown as AgentEvent);\n });\n\n // ── Execute ────────────────────────────────────────────────────────────\n flowLog.info(\"starting flow\", {\n flowId: flow.id,\n flowName: flow.name,\n runId: session.runId,\n });\n\n try {\n // Kick the initial flow_started turn explicitly. Subsequent turns are\n // driven by the bus signaling whenever the adapter mutates.\n const initialStimulus: TurnStimulus = { kind: \"flow_started\" };\n await stimulusBus.signal(flowConnectorId, {\n promptFragment: renderStimulusPrompt(initialStimulus),\n meta: { kind: initialStimulus.kind },\n });\n\n const finalState = flowAdapter.getExecution(flowHandle);\n if (finalState.done) {\n flowLog.info(\"flow complete\", { flowId: flow.id, flowName: flow.name });\n } else if (finalState.status === \"failed\") {\n flowLog.error(\"flow failed\", undefined, { flowId: flow.id, flowName: flow.name });\n } else {\n flowLog.warn(\"flow paused after one turn\", {\n flowId: flow.id,\n status: finalState.status,\n note: \"CLI mode does not interact with approval/input gates\",\n });\n }\n } finally {\n driver.kill();\n const lastState = flowAdapter.getExecution(flowHandle);\n await saveSession(\n opts.projectDir,\n touchSession({\n ...updatedSession,\n driverSessionId: driver.runtimeSessionId ?? updatedSession.driverSessionId,\n status: lastState.status === \"complete\" ? \"complete\" : \"paused\",\n }),\n ).catch(() => {});\n await flowAdapter.disconnect(flowHandle).catch(() => {});\n await agentSession.dispose();\n telemetry.endTrace(flowTrace, {\n status: flowAdapter.getExecution(flowHandle).status === \"complete\" ? \"ok\" : \"error\",\n });\n await telemetry.flush().catch(() => {});\n }\n } finally {\n disposeLogStore();\n }\n}\n\n/**\n * Resume an existing session from the CLI.\n *\n * With the Phase 2 turn-based model, flow state is NOT persisted to\n * local session files — only the driver session ID is kept. The CLI\n * can resume the agent's conversation thread, but the flow execution\n * itself starts from scratch because the runner has no durable store\n * for per-run state.\n *\n * For a governed, resumable flow run, use a host that persists flow\n * state (e.g. the Skaile platform). CLI resume is retained as a\n * driver-level convenience only: we load the session, restart the\n * flow, and the SDK will reconnect to the prior conversation thread.\n *\n * @docLink packages/factory-assets/flow#resume-flow\n */\nexport async function resumeFlow(opts: ResumeOptions): Promise<void> {\n const runner = await loadRunnerModule();\n const { loadSession, loadSessionById, bootstrapRunnerLogStore } = runner;\n\n const session = opts.sessionId\n ? await loadSessionById(opts.projectDir, opts.sessionId)\n : await loadSession(opts.projectDir);\n\n if (!session) {\n const hint = opts.sessionId\n ? `session ${opts.sessionId}`\n : `current session in ${opts.projectDir}/.skaile`;\n throw new Error(`No session found (${hint}) — run 'start' first`);\n }\n\n const flowPath = resolveFlowPath(session.flowId, opts.projectDir);\n\n // Bootstrap a transient logger for the resume diagnostics. The inner\n // runFlow() call will register its own LogStore for the new run. Keep\n // OnLogBridgeSink wiring so callers passing onLog still see this line.\n const wsConfigEarly = resolveSkWorkspaceConfig(opts.projectDir);\n const { dispose: disposeLogStore } = bootstrapRunnerLogStore({\n sessionId: session.runId,\n projectDir: opts.projectDir,\n yamlBlock: (wsConfigEarly as { logging?: unknown }).logging,\n onLog: opts.onLog,\n });\n const flowLog = createLogger({\n kind: \"flow-connector\",\n subkind: \"run\",\n instance: session.runId,\n });\n flowLog.info(\"resuming session\", {\n runId: session.runId,\n flowId: session.flowId,\n note: \"CLI mode does not persist flow state — flow restarts from scratch; driver thread resumes\",\n });\n\n try {\n await runFlow({\n projectDir: opts.projectDir,\n flowPath,\n agentDir: opts.agentDir ?? session.agentDir,\n driver: session.driver,\n model: session.model,\n provider: session.provider,\n sessionLabel: session.label,\n dryRun: opts.dryRun,\n sessionTimeoutMs: opts.sessionTimeoutMs,\n onEvent: opts.onEvent,\n onLog: opts.onLog,\n });\n } finally {\n disposeLogStore();\n }\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nasync function validatePinnedVersions(\n flow: Awaited<ReturnType<typeof loadFlow>>,\n projectDir: string,\n log: (line: string) => void,\n): Promise<void> {\n const pinnedNodes = flow.nodes.filter((n) => n.type === \"skill\" && n.data?.version);\n if (pinnedNodes.length === 0) return;\n\n const skillVersions = new Map<string, string>();\n const aiResourcesDir = findAiResourcesDir(projectDir);\n if (aiResourcesDir) {\n for (const node of pinnedNodes) {\n const skillId = node.data?.skill ?? node.id;\n if (skillVersions.has(skillId)) continue;\n const skillPath = findSkillMd(aiResourcesDir, skillId);\n if (skillPath) {\n const content = fs.readFileSync(skillPath, \"utf-8\");\n const fm = parseSkillFrontmatter(content);\n skillVersions.set(skillId, fm.metadata?.version ?? fm.version ?? \"\");\n }\n }\n }\n\n const versionNodes = pinnedNodes.map((n) => ({\n nodeId: n.id,\n skillId: n.data?.skill ?? n.id,\n requestedVersion: n.data?.version,\n }));\n\n const checks = validateFlowVersions(versionNodes, skillVersions);\n const failures = checks.filter((c) => !c.satisfied);\n if (failures.length > 0) {\n const lines = failures.map(\n (f) => ` ${f.nodeId}: wants ${f.requested}, found ${f.actual || \"(none)\"}`,\n );\n throw new Error(`Skill version mismatch:\\n${lines.join(\"\\n\")}`);\n }\n for (const c of checks.filter((c) => c.satisfied)) {\n log(` Version OK: ${c.skillId} ${c.actual} satisfies ${c.requested}`);\n }\n}\n\nfunction resolveFlowPath(flowId: string, projectDir: string): string {\n const armInstalled = path.join(projectDir, \".skaile\", \"flows\", flowId, `${flowId}.flow.yaml`);\n if (fs.existsSync(armInstalled)) return armInstalled;\n\n const manual = path.join(projectDir, \".skaile\", \"flows\", `${flowId}.flow.yaml`);\n if (fs.existsSync(manual)) return manual;\n\n let dir = projectDir;\n for (let i = 0; i < 6; i++) {\n const aiResources = path.join(dir, \"ai-assets\");\n if (fs.existsSync(aiResources)) {\n for (const domain of fs.readdirSync(aiResources)) {\n const flowsDir = path.join(aiResources, domain, \"flows\");\n const candidate = path.join(flowsDir, `${flowId}.flow.yaml`);\n if (fs.existsSync(candidate)) return candidate;\n const legacy = path.join(flowsDir, `${flowId}.json`);\n if (fs.existsSync(legacy)) return legacy;\n }\n throw new Error(`Flow not found: ${flowId} (searched .skaile/flows/ and ${aiResources})`);\n }\n dir = path.dirname(dir);\n }\n throw new Error(\n `Flow not found: ${flowId} (no .skaile/flows/ entry and could not locate ai-assets from ${projectDir})`,\n );\n}\n\n/** Walk up from projectDir to find ai-assets/ */\nfunction findAiResourcesDir(projectDir: string): string | null {\n let dir = projectDir;\n for (let i = 0; i < 6; i++) {\n const candidate = path.join(dir, \"ai-assets\");\n if (fs.existsSync(candidate)) return candidate;\n const parent = path.dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n return null;\n}\n\n/** Find SKILL.md for a given skill ID by walking ai-assets domains */\nfunction findSkillMd(aiResourcesDir: string, skillId: string): string | null {\n for (const domain of fs.readdirSync(aiResourcesDir, { withFileTypes: true })) {\n if (!domain.isDirectory()) continue;\n const skillsDir = path.join(aiResourcesDir, domain.name, \"skills\");\n if (!fs.existsSync(skillsDir)) continue;\n const found = walkForSkill(skillsDir, skillId);\n if (found) return found;\n }\n return null;\n}\n\n// ---------------------------------------------------------------------------\n// Turn-wait helper\n// ---------------------------------------------------------------------------\n\n/**\n * Minimal driver surface needed by the bus's `driveTurn` callback. Mirrors\n * the slice the legacy `FlowOrchestrator` consumed (`prompt` + `on` +\n * `removeAllListeners`) so we can keep the wait helper private to this\n * module without pulling in a runtime dep on `@skaile/workspaces/bridge`.\n */\ninterface TurnDriverSurface {\n prompt(message: string): Promise<void>;\n on(event: \"agent-event\", handler: (event: AgentEvent) => void): void;\n removeAllListeners(event: \"agent-event\"): void;\n}\n\n/**\n * Send a prompt to the driver and resolve when the agent emits\n * `agent_end` (or reject on `error`). Identical contract to the legacy\n * `awaitAgentEnd` helper from `flow-orchestrator.ts`. Phase 4 lifts the\n * helper into `run-flow.ts` because the bus now owns turn driving.\n */\nfunction awaitAgentEnd(\n driver: TurnDriverSurface,\n prompt: string,\n onEvent: ((event: AgentEvent) => void) | undefined,\n timeoutMs: number,\n): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n let settled = false;\n\n const done = (err?: Error) => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n driver.removeAllListeners(\"agent-event\");\n if (err) reject(err);\n else resolve();\n };\n\n const timer = setTimeout(\n () => done(new Error(`Flow turn timed out after ${timeoutMs / 1000}s`)),\n timeoutMs,\n );\n\n driver.on(\"agent-event\", (event: AgentEvent) => {\n onEvent?.(event);\n if (event.type === \"agent_end\") done();\n else if (event.type === \"error\") {\n const msg =\n (event as { error?: string; message?: string }).error ??\n (event as { message?: string }).message ??\n \"Agent error\";\n done(new Error(msg));\n }\n });\n\n driver.prompt(prompt).catch(done);\n });\n}\n\nfunction walkForSkill(dir: string, skillId: string): string | null {\n for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {\n if (!entry.isDirectory()) continue;\n const full = path.join(dir, entry.name);\n const skillMd = path.join(full, \"SKILL.md\");\n if (fs.existsSync(skillMd)) {\n if (entry.name === skillId) return skillMd;\n } else {\n const found = walkForSkill(full, skillId);\n if (found) return found;\n }\n }\n return null;\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { resolveSkWorkspaceConfig } from './chunk-
|
|
1
|
+
import { resolveSkWorkspaceConfig } from './chunk-2PXSZYKV.js';
|
|
2
2
|
import { createHash } from 'crypto';
|
|
3
3
|
import fs, { writeFileSync, existsSync, readFileSync, mkdirSync, cpSync, readdirSync } from 'fs';
|
|
4
4
|
import path, { join, dirname, basename } from 'path';
|
|
@@ -818,5 +818,5 @@ var WorkspaceYamlEditor = class _WorkspaceYamlEditor {
|
|
|
818
818
|
};
|
|
819
819
|
|
|
820
820
|
export { ALL_PROVIDERS, ManifestYamlEditor, SETTINGS_DEFAULTS, WorkspaceYamlEditor, applyPatch, buildLockFile, computeHash, detectEnvApiKeys, extractForPatch, generatePatch, globalSettingsPath, listPatches, loadSettings, mapLegacyFields, maskApiKey, migrateSettings, portableSpawn, portableSpawnSync, projectSettingsPath, providerEnvKey, readLock, readPatch, readPluginsLockSlice, resolveAllKeys, resolveApiKey, resolveSettings, savePatch, saveSettings, verifyLock, walkForSettings, writeLock, writePluginsLockSlice };
|
|
821
|
-
//# sourceMappingURL=chunk-
|
|
822
|
-
//# sourceMappingURL=chunk-
|
|
821
|
+
//# sourceMappingURL=chunk-VIA64TYP.js.map
|
|
822
|
+
//# sourceMappingURL=chunk-VIA64TYP.js.map
|