@skaile/workspaces 0.41.6 → 0.42.1
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 +83 -0
- package/dist/{asset-feeds-FKD5AB2R.js → asset-feeds-UPJJGR3O.js} +8 -8
- package/dist/{asset-feeds-FKD5AB2R.js.map → asset-feeds-UPJJGR3O.js.map} +1 -1
- package/dist/asset-manager/index.js +6 -6
- package/dist/asset-manager/installer.js +5 -5
- package/dist/bridge/drivers/claude-sdk.js +112 -7
- package/dist/bridge/drivers/claude-sdk.js.map +1 -1
- package/dist/bridge/drivers/codex.js +1 -1
- package/dist/bridge/drivers/continue.js +2 -2
- package/dist/bridge/drivers/echo.js +1 -1
- package/dist/bridge/drivers/gemini.js +3 -3
- package/dist/bridge/drivers/goose.js +2 -2
- package/dist/bridge/drivers/omp.js +1 -1
- package/dist/bridge/drivers/opencode.js +2 -2
- package/dist/bridge/drivers/qwen.js +3 -3
- package/dist/bridge/index.js +2 -2
- package/dist/bridge/src/drivers/claude-sdk.d.ts +6 -0
- package/dist/bridge/src/drivers/claude-sdk.d.ts.map +1 -1
- package/dist/bridge/src/drivers/sanitize-assistant-text.d.ts +53 -0
- package/dist/bridge/src/drivers/sanitize-assistant-text.d.ts.map +1 -0
- package/dist/{chunk-J4RF5ABK.js → chunk-2BEDUMTA.js} +3 -3
- package/dist/{chunk-J4RF5ABK.js.map → chunk-2BEDUMTA.js.map} +1 -1
- package/dist/{chunk-5VJVSYXX.js → chunk-3HUUP3JC.js} +41 -3
- package/dist/chunk-3HUUP3JC.js.map +1 -0
- package/dist/{chunk-SBGHNXJD.js → chunk-3K2CYDBT.js} +17 -7
- package/dist/chunk-3K2CYDBT.js.map +1 -0
- package/dist/{chunk-2XFTGANB.js → chunk-4HKLAUHJ.js} +5 -5
- package/dist/{chunk-2XFTGANB.js.map → chunk-4HKLAUHJ.js.map} +1 -1
- package/dist/{chunk-5IXCNMMU.js → chunk-5C3QJSOD.js} +3 -3
- package/dist/{chunk-5IXCNMMU.js.map → chunk-5C3QJSOD.js.map} +1 -1
- package/dist/{chunk-TNYWP6EQ.js → chunk-5VMVNQGB.js} +6 -6
- package/dist/{chunk-TNYWP6EQ.js.map → chunk-5VMVNQGB.js.map} +1 -1
- package/dist/{chunk-B5PEERRZ.js → chunk-6IDBWPK2.js} +7 -4
- package/dist/chunk-6IDBWPK2.js.map +1 -0
- package/dist/{chunk-3KX5W3ZU.js → chunk-7WLJW457.js} +4 -4
- package/dist/{chunk-3KX5W3ZU.js.map → chunk-7WLJW457.js.map} +1 -1
- package/dist/{chunk-ZJ27BHIH.js → chunk-BXYMGZCI.js} +3 -3
- package/dist/{chunk-ZJ27BHIH.js.map → chunk-BXYMGZCI.js.map} +1 -1
- package/dist/{chunk-2ZI2FFFN.js → chunk-F5Q2RMH4.js} +229 -76
- package/dist/chunk-F5Q2RMH4.js.map +1 -0
- package/dist/{chunk-2JCUYKUN.js → chunk-G6FJZG4C.js} +2 -2
- package/dist/{chunk-2JCUYKUN.js.map → chunk-G6FJZG4C.js.map} +1 -1
- package/dist/{chunk-NQDJQ7WB.js → chunk-GJI6FZ56.js} +8 -4
- package/dist/chunk-GJI6FZ56.js.map +1 -0
- package/dist/{chunk-JAOXG3LL.js → chunk-HVCZLD5Z.js} +4 -4
- package/dist/{chunk-JAOXG3LL.js.map → chunk-HVCZLD5Z.js.map} +1 -1
- package/dist/{chunk-IODU6UDT.js → chunk-JZQFZ55W.js} +2 -2
- package/dist/{chunk-IODU6UDT.js.map → chunk-JZQFZ55W.js.map} +1 -1
- package/dist/{chunk-MO2VGW6U.js → chunk-K5TROTFK.js} +3 -3
- package/dist/{chunk-MO2VGW6U.js.map → chunk-K5TROTFK.js.map} +1 -1
- package/dist/{chunk-MVXXAXDW.js → chunk-KYQNWFJV.js} +3 -3
- package/dist/{chunk-MVXXAXDW.js.map → chunk-KYQNWFJV.js.map} +1 -1
- package/dist/{chunk-KM6DCR7A.js → chunk-OCAQH66V.js} +2 -2
- package/dist/{chunk-KM6DCR7A.js.map → chunk-OCAQH66V.js.map} +1 -1
- package/dist/{chunk-HZXOCRLD.js → chunk-OMAK7GNL.js} +78 -39
- package/dist/chunk-OMAK7GNL.js.map +1 -0
- package/dist/{chunk-X4FCLBI7.js → chunk-R4H6EJW5.js} +7 -5
- package/dist/chunk-R4H6EJW5.js.map +1 -0
- package/dist/{chunk-U3TV7SRR.js → chunk-RSK6FDMV.js} +3 -3
- package/dist/{chunk-U3TV7SRR.js.map → chunk-RSK6FDMV.js.map} +1 -1
- package/dist/{chunk-TB342H55.js → chunk-SURALYSM.js} +4 -4
- package/dist/{chunk-TB342H55.js.map → chunk-SURALYSM.js.map} +1 -1
- package/dist/{chunk-4NZD7423.js → chunk-WJ3RP2FS.js} +3 -3
- package/dist/{chunk-4NZD7423.js.map → chunk-WJ3RP2FS.js.map} +1 -1
- package/dist/{chunk-4ZACMAT3.js → chunk-Z3GAAIJK.js} +4 -4
- package/dist/{chunk-4ZACMAT3.js.map → chunk-Z3GAAIJK.js.map} +1 -1
- package/dist/cli/index.js +34 -34
- package/dist/connectors/config.js +5 -5
- package/dist/connectors/index.js +7 -7
- package/dist/connectors/rclone.js +1 -1
- package/dist/connectors/src/connector-manager.d.ts +17 -0
- package/dist/connectors/src/connector-manager.d.ts.map +1 -1
- package/dist/connectors/src/connector-types.d.ts +26 -0
- package/dist/connectors/src/connector-types.d.ts.map +1 -1
- package/dist/connectors/src/fleet-health-gate.d.ts +53 -36
- package/dist/connectors/src/fleet-health-gate.d.ts.map +1 -1
- package/dist/connectors/src/fleet-utils.d.ts +11 -2
- package/dist/connectors/src/fleet-utils.d.ts.map +1 -1
- package/dist/connectors/src/index.d.ts +3 -3
- package/dist/connectors/src/index.d.ts.map +1 -1
- package/dist/connectors/src/materialized-connectors.d.ts.map +1 -1
- package/dist/connectors/src/mount-placeholder.d.ts +19 -0
- package/dist/connectors/src/mount-placeholder.d.ts.map +1 -1
- package/dist/connectors/src/rclone-process-manager.d.ts +36 -2
- package/dist/connectors/src/rclone-process-manager.d.ts.map +1 -1
- package/dist/core/index.js +4 -4
- package/dist/core/manifest.js +1 -1
- package/dist/core/runtime-assets.js +3 -3
- package/dist/core/src/index.d.ts +1 -1
- package/dist/core/src/index.d.ts.map +1 -1
- package/dist/core/src/manifest.d.ts +11 -0
- package/dist/core/src/manifest.d.ts.map +1 -1
- package/dist/core/src/workspace-config.d.ts +2 -0
- package/dist/core/src/workspace-config.d.ts.map +1 -1
- package/dist/core/workspace-config.js +2 -2
- package/dist/deploy/index.js +4 -4
- package/dist/discovery/index.js +2 -2
- package/dist/{ensure-sources-EWK7EXKN.js → ensure-sources-TZHDV3BF.js} +8 -8
- package/dist/{ensure-sources-EWK7EXKN.js.map → ensure-sources-TZHDV3BF.js.map} +1 -1
- package/dist/factory-assets/connectors/deploy.js +7 -7
- package/dist/factory-assets/connectors/devserver.js +7 -7
- package/dist/factory-assets/connectors/flow/adapter.js +7 -7
- package/dist/factory-assets/connectors/flow/engine.js +4 -4
- package/dist/factory-assets/connectors/flow/run-flow.js +8 -8
- package/dist/factory-assets/connectors/flow.js +7 -7
- package/dist/factory-assets/connectors/git.js +7 -7
- package/dist/factory-assets/connectors/gmail.js +7 -7
- package/dist/factory-assets/connectors/googledrive/driver.d.ts.map +1 -1
- package/dist/factory-assets/connectors/googledrive.js +7 -7
- package/dist/factory-assets/connectors/local.js +7 -7
- package/dist/factory-assets/connectors/mattermost.js +7 -7
- package/dist/factory-assets/connectors/memory.js +7 -7
- package/dist/factory-assets/connectors/minio.js +7 -7
- package/dist/factory-assets/connectors/postgres.js +7 -7
- package/dist/factory-assets/connectors/s3.js +7 -7
- package/dist/factory-assets/connectors/sharepoint/driver.d.ts.map +1 -1
- package/dist/factory-assets/connectors/sharepoint.js +7 -7
- package/dist/factory-assets/connectors/sqlite.js +7 -7
- package/dist/factory-assets/connectors/static-server.js +7 -7
- package/dist/factory-assets/connectors/tunnel.js +7 -7
- package/dist/factory-assets/connectors/webdav/driver.d.ts.map +1 -1
- package/dist/factory-assets/connectors/webdav.js +7 -7
- package/dist/factory-assets/connectors/xstate-store.js +7 -7
- package/dist/factory-assets/connectors/xstate.js +7 -7
- package/dist/{flows-3MBK2PDN.js → flows-KTBCZ5GQ.js} +3 -3
- package/dist/{flows-3MBK2PDN.js.map → flows-KTBCZ5GQ.js.map} +1 -1
- package/dist/library/index.js +6 -6
- package/dist/library/install.js +4 -4
- package/dist/{open-library-QSIPFN5N.js → open-library-EV7UCOFU.js} +9 -9
- package/dist/{open-library-QSIPFN5N.js.map → open-library-EV7UCOFU.js.map} +1 -1
- package/dist/{paths-KNLBYALO.js → paths-7H5CSBLQ.js} +7 -7
- package/dist/{paths-KNLBYALO.js.map → paths-7H5CSBLQ.js.map} +1 -1
- package/dist/{plugin-store-CL6CTREE.js → plugin-store-LGLN2QUX.js} +6 -6
- package/dist/{plugin-store-CL6CTREE.js.map → plugin-store-LGLN2QUX.js.map} +1 -1
- package/dist/runner/index.js +11 -11
- package/dist/runner/src/fleet-health-flag-dispatcher.d.ts +3 -2
- package/dist/runner/src/fleet-health-flag-dispatcher.d.ts.map +1 -1
- package/dist/runner/src/mcp-prompt.d.ts +8 -0
- package/dist/runner/src/mcp-prompt.d.ts.map +1 -0
- package/dist/runner/src/resource-handler.d.ts +1 -1
- package/dist/runner/src/resource-handler.d.ts.map +1 -1
- package/dist/runner/src/resources.d.ts +6 -0
- package/dist/runner/src/resources.d.ts.map +1 -1
- package/dist/runner/src/session-builder.d.ts.map +1 -1
- package/dist/sdk/asset-manager.js +6 -6
- package/dist/sdk/bridge.js +2 -2
- package/dist/sdk/core.js +4 -4
- package/dist/sdk/flow.js +4 -4
- package/dist/sdk/index.js +11 -11
- package/dist/sdk/runner.js +11 -11
- package/dist/sdk/session.js +1 -1
- package/dist/session/index.js +1 -1
- package/dist/session/src/dispatcher.d.ts +8 -0
- package/dist/session/src/dispatcher.d.ts.map +1 -1
- package/dist/{setup-345XOCH3.js → setup-EVNPECSY.js} +8 -8
- package/dist/{setup-345XOCH3.js.map → setup-EVNPECSY.js.map} +1 -1
- package/dist/{store-client-W3HKRE46.js → store-client-4XN7IB3R.js} +7 -7
- package/dist/{store-client-W3HKRE46.js.map → store-client-4XN7IB3R.js.map} +1 -1
- package/dist/tui/index.js +11 -11
- package/dist/types/src/events.d.ts +1 -1
- package/dist/types/src/events.d.ts.map +1 -1
- package/dist/workspace-plugin/adapters/mcp.js +1 -1
- package/dist/workspace-plugin/adapters/omp.js +3 -3
- package/dist/workspace-plugin/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-2ZI2FFFN.js.map +0 -1
- package/dist/chunk-5VJVSYXX.js.map +0 -1
- package/dist/chunk-B5PEERRZ.js.map +0 -1
- package/dist/chunk-HZXOCRLD.js.map +0 -1
- package/dist/chunk-NQDJQ7WB.js.map +0 -1
- package/dist/chunk-SBGHNXJD.js.map +0 -1
- package/dist/chunk-X4FCLBI7.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../cli/src/open-registry.ts","../cli/src/open-library.ts"],"names":["source"],"mappings":"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","file":"chunk-3KX5W3ZU.js","sourcesContent":["/**\n * open-registry.ts — shared helper to create a full AssetKindRegistry.\n *\n * Bootstraps the registry with all built-in providers (9 core + preset)\n * from @skaile/discovery, plus the extension kind providers (flow from\n * @skaile/workspaces/factory-assets/connectors/flow/engine, knowledge from @skaile/library).\n *\n * This is the single registration point for the CLI. All code paths\n * that need a registry (source sync, lib-status, etc.) should use this.\n */\n\nimport type { AssetKindRegistry } from \"@skaile/workspaces/discovery\";\nimport { createDefaultRegistry } from \"@skaile/workspaces/discovery\";\nimport { flowKindProvider } from \"@skaile/workspaces/factory-assets/connectors/flow/engine\";\nimport { knowledgeKindProvider } from \"@skaile/workspaces/library\";\n\n/**\n * Create a fully-configured AssetKindRegistry with all known providers.\n *\n * Registers:\n * - 9 core kinds (skill, agent, connector, mount, mcp-server, contract, prompt, persona, ruleset)\n * - preset (composition entity)\n * - flow (extension, from @skaile/workspaces/factory-assets/connectors/flow/engine)\n * - knowledge (extension, from @skaile/library)\n *\n * @returns An unfrozen registry (auto-freezes on first read)\n */\nexport function createFullRegistry(): AssetKindRegistry {\n const registry = createDefaultRegistry();\n registry.register(flowKindProvider);\n registry.register(knowledgeKindProvider);\n return registry;\n}\n","/**\n * open-library.ts — shared helpers to open the LocalIndex and the configured\n * Catalog source.\n *\n * Lazy-loads the `@skaile/workspaces/library` subpath and returns the\n * LocalIndex instance (backed by `@libsql/client`; runs on Node and Bun).\n * The catalog-source helper reads\n * `~/.skaile/config.yaml` (and project-level overlay if `projectDir` is given)\n * to decide between {@link RemoteCatalogSource} (default — points at\n * `https://skaile.store`) and a {@link LocalCatalogSource} bound to the most\n * recent local library registered via `skaile source add`.\n */\n\nimport { logErr } from \"./helpers.ts\";\nimport { createFullRegistry } from \"./open-registry.ts\";\n\n/**\n * Open the LocalIndex with the full kind registry. Exits with code 1\n * if the library directory cannot be created.\n *\n * @returns A `LocalIndex` instance ready for use.\n * @docLink cli/dev-guide#open-library\n */\nexport async function openLibrary() {\n try {\n const { LocalIndex } = await import(\"@skaile/workspaces/library\");\n return new LocalIndex({ kindRegistry: createFullRegistry() });\n } catch (err) {\n logErr(`Could not open LocalIndex: ${err instanceof Error ? err.message : String(err)}`);\n process.exit(1);\n }\n}\n\n/**\n * Resolve the configured **remote** Catalog source for the CLI.\n *\n * Reads `~/.skaile/config.yaml` (plus the optional project-level overlay) and\n * returns a {@link RemoteCatalogSource} pointing at `catalog.url` (default:\n * `https://skaile.store`). The `cache_ttl: 0` config flag flips the source\n * into air-gapped mode: network reads are disabled, only `skaile update`\n * performs refreshes.\n *\n * **Local-mode rejection.** If the resolved config has `catalog.url: local`\n * this helper throws — callers wanting the dispatched local-or-remote source\n * must use {@link resolveCatalogSource}. Remote-only consumers like\n * `skaile update --catalog-only` rely on this strict behaviour.\n *\n * @param opts - Project directory (overlays project config) and explicit overrides.\n * @returns A configured {@link RemoteCatalogSource}.\n * @throws When `catalog.url` is the `local` sentinel.\n * @docLink cli/dev-guide#open-library\n */\nexport async function openCatalogSource(opts?: {\n projectDir?: string;\n baseUrlOverride?: string;\n /** Override the user-config path for tests. */\n userConfigFile?: string;\n}): Promise<\n | import(\"@skaile/workspaces/library\").RemoteCatalogSource\n | import(\"@skaile/workspaces/library\").RestCatalogSource\n> {\n const { resolveConfig, RemoteCatalogSource, RestCatalogSource, isLocalCatalogUrl } = await import(\n \"@skaile/workspaces/library\"\n );\n const cfg = resolveConfig({\n projectDir: opts?.projectDir,\n userConfigFile: opts?.userConfigFile,\n });\n const baseUrl = opts?.baseUrlOverride ?? cfg.catalog.url;\n if (isLocalCatalogUrl(baseUrl)) {\n throw new Error(\n \"catalog.url is set to 'local' — remote catalog is disabled. \" +\n \"Use `skaile source add <path>` + `skaile source sync` for local sources, \" +\n \"or set `catalog.url: https://skaile.store` in ~/.skaile/config.yaml.\",\n );\n }\n const cacheTtlMs = cfg.catalog.cache_ttl * 1000;\n if (cfg.catalog.framing === \"rest\") {\n return new RestCatalogSource({ baseUrl, cacheTtlMs });\n }\n return new RemoteCatalogSource({ baseUrl, cacheTtlMs });\n}\n\n/**\n * Resolved catalog source plus a close handle for releasing any underlying\n * resources (e.g. the `LocalIndex` SQLite connection in local mode).\n *\n * Callers MUST invoke `close()` when done — typically in a `finally` block.\n * For remote-mode sources `close()` is a no-op, but the contract is uniform\n * so consumers don't have to branch.\n *\n * @docLink cli/dev-guide#open-library\n */\nexport interface ResolvedCatalogSource {\n /** The {@link ICatalogSource} ready for use. */\n source: import(\"@skaile/workspaces/library\").ICatalogSource;\n /** Release any underlying resources (SQLite handle in local mode). */\n close(): void;\n}\n\n/**\n * Resolve the configured Catalog source — local or remote — based on\n * `~/.skaile/config.yaml`.\n *\n * Dispatch:\n * - `catalog.url: local` → opens {@link LocalIndex}, picks the most recently\n * registered local library whose `path` still exists on disk, and returns a\n * {@link LocalCatalogSource} bound to that library. Throws if no usable\n * local library is registered.\n * - any URL → returns {@link RemoteCatalogSource} (same as\n * {@link openCatalogSource}).\n *\n * The returned `close()` releases the underlying `LocalIndex` SQLite handle\n * in local mode (no-op in remote mode). Callers MUST invoke it — typically in\n * a `finally` block — to satisfy `library/CLAUDE.md` § \"Notes for Consumers\".\n *\n * @param opts - Project directory (overlays project config) and explicit overrides.\n * @returns A `ResolvedCatalogSource` carrying the source and a close handle.\n * @throws When `local` is configured but no usable local library is registered.\n * @docLink cli/dev-guide#open-library\n */\nexport async function resolveCatalogSource(opts?: {\n projectDir?: string;\n baseUrlOverride?: string;\n /** Override the user-config path for tests. */\n userConfigFile?: string;\n}): Promise<ResolvedCatalogSource> {\n const {\n resolveConfig,\n RemoteCatalogSource,\n RestCatalogSource,\n LocalCatalogSource,\n isLocalCatalogUrl,\n } = await import(\"@skaile/workspaces/library\");\n const cfg = resolveConfig({\n projectDir: opts?.projectDir,\n userConfigFile: opts?.userConfigFile,\n });\n const baseUrl = opts?.baseUrlOverride ?? cfg.catalog.url;\n\n if (isLocalCatalogUrl(baseUrl)) {\n const fs = await import(\"node:fs\");\n const library = await openLibrary();\n try {\n const sources = await library.listSources();\n type LibraryRow = (typeof sources)[number];\n // Type-narrow: `path` is required for local libraries after the filter.\n const usable = sources\n .filter(\n (s): s is LibraryRow & { path: string } =>\n s.backend === \"local\" && typeof s.path === \"string\" && s.path.length > 0,\n )\n .sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());\n\n if (usable.length === 0) {\n throw new Error(\n \"catalog.url is set to 'local' but no local library is registered. \" +\n \"Run `skaile source add <path>` first, then `skaile source sync`.\",\n );\n }\n\n // Prefer the most recently added library whose path still exists.\n const present = usable.find((s) => fs.existsSync(s.path));\n if (!present) {\n const head = usable[0];\n throw new Error(\n `catalog.url is set to 'local' but every registered local library has a missing path on disk. ` +\n `Most recent: ${head.path} (library ${head.id}). ` +\n `Re-register with \\`skaile source add <existing-path>\\` or run \\`skaile source list\\` to inspect.`,\n );\n }\n\n const source = new LocalCatalogSource(\n library,\n present.id,\n present.path,\n createFullRegistry(),\n );\n return { source, close: () => library.close() };\n } catch (err) {\n // Release the handle on any failure during dispatch — otherwise the\n // SQLite WAL state leaks for the lifetime of the process.\n library.close();\n throw err;\n }\n }\n\n const cacheTtlMs = cfg.catalog.cache_ttl * 1000;\n const source =\n cfg.catalog.framing === \"rest\"\n ? new RestCatalogSource({ baseUrl, cacheTtlMs })\n : new RemoteCatalogSource({ baseUrl, cacheTtlMs });\n return { source, close: () => {} };\n}\n\n/**\n * Open the LibraryManager bound to the active LocalIndex.\n * Caller owns lifetime — must call `close()` (returned helper closes the\n * underlying LocalIndex).\n *\n * @docLink cli/dev-guide#open-library\n */\nexport async function openLibraryManager(): Promise<{\n manager: import(\"@skaile/workspaces/library\").LibraryManager;\n library: import(\"@skaile/workspaces/library\").LocalIndex;\n close: () => void;\n}> {\n const { LibraryManager } = await import(\"@skaile/workspaces/library\");\n const library = await openLibrary();\n const manager = new LibraryManager(library);\n return { manager, library, close: () => library.close() };\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../cli/src/open-registry.ts","../cli/src/open-library.ts"],"names":["source"],"mappings":"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","file":"chunk-7WLJW457.js","sourcesContent":["/**\n * open-registry.ts — shared helper to create a full AssetKindRegistry.\n *\n * Bootstraps the registry with all built-in providers (9 core + preset)\n * from @skaile/discovery, plus the extension kind providers (flow from\n * @skaile/workspaces/factory-assets/connectors/flow/engine, knowledge from @skaile/library).\n *\n * This is the single registration point for the CLI. All code paths\n * that need a registry (source sync, lib-status, etc.) should use this.\n */\n\nimport type { AssetKindRegistry } from \"@skaile/workspaces/discovery\";\nimport { createDefaultRegistry } from \"@skaile/workspaces/discovery\";\nimport { flowKindProvider } from \"@skaile/workspaces/factory-assets/connectors/flow/engine\";\nimport { knowledgeKindProvider } from \"@skaile/workspaces/library\";\n\n/**\n * Create a fully-configured AssetKindRegistry with all known providers.\n *\n * Registers:\n * - 9 core kinds (skill, agent, connector, mount, mcp-server, contract, prompt, persona, ruleset)\n * - preset (composition entity)\n * - flow (extension, from @skaile/workspaces/factory-assets/connectors/flow/engine)\n * - knowledge (extension, from @skaile/library)\n *\n * @returns An unfrozen registry (auto-freezes on first read)\n */\nexport function createFullRegistry(): AssetKindRegistry {\n const registry = createDefaultRegistry();\n registry.register(flowKindProvider);\n registry.register(knowledgeKindProvider);\n return registry;\n}\n","/**\n * open-library.ts — shared helpers to open the LocalIndex and the configured\n * Catalog source.\n *\n * Lazy-loads the `@skaile/workspaces/library` subpath and returns the\n * LocalIndex instance (backed by `@libsql/client`; runs on Node and Bun).\n * The catalog-source helper reads\n * `~/.skaile/config.yaml` (and project-level overlay if `projectDir` is given)\n * to decide between {@link RemoteCatalogSource} (default — points at\n * `https://skaile.store`) and a {@link LocalCatalogSource} bound to the most\n * recent local library registered via `skaile source add`.\n */\n\nimport { logErr } from \"./helpers.ts\";\nimport { createFullRegistry } from \"./open-registry.ts\";\n\n/**\n * Open the LocalIndex with the full kind registry. Exits with code 1\n * if the library directory cannot be created.\n *\n * @returns A `LocalIndex` instance ready for use.\n * @docLink cli/dev-guide#open-library\n */\nexport async function openLibrary() {\n try {\n const { LocalIndex } = await import(\"@skaile/workspaces/library\");\n return new LocalIndex({ kindRegistry: createFullRegistry() });\n } catch (err) {\n logErr(`Could not open LocalIndex: ${err instanceof Error ? err.message : String(err)}`);\n process.exit(1);\n }\n}\n\n/**\n * Resolve the configured **remote** Catalog source for the CLI.\n *\n * Reads `~/.skaile/config.yaml` (plus the optional project-level overlay) and\n * returns a {@link RemoteCatalogSource} pointing at `catalog.url` (default:\n * `https://skaile.store`). The `cache_ttl: 0` config flag flips the source\n * into air-gapped mode: network reads are disabled, only `skaile update`\n * performs refreshes.\n *\n * **Local-mode rejection.** If the resolved config has `catalog.url: local`\n * this helper throws — callers wanting the dispatched local-or-remote source\n * must use {@link resolveCatalogSource}. Remote-only consumers like\n * `skaile update --catalog-only` rely on this strict behaviour.\n *\n * @param opts - Project directory (overlays project config) and explicit overrides.\n * @returns A configured {@link RemoteCatalogSource}.\n * @throws When `catalog.url` is the `local` sentinel.\n * @docLink cli/dev-guide#open-library\n */\nexport async function openCatalogSource(opts?: {\n projectDir?: string;\n baseUrlOverride?: string;\n /** Override the user-config path for tests. */\n userConfigFile?: string;\n}): Promise<\n | import(\"@skaile/workspaces/library\").RemoteCatalogSource\n | import(\"@skaile/workspaces/library\").RestCatalogSource\n> {\n const { resolveConfig, RemoteCatalogSource, RestCatalogSource, isLocalCatalogUrl } = await import(\n \"@skaile/workspaces/library\"\n );\n const cfg = resolveConfig({\n projectDir: opts?.projectDir,\n userConfigFile: opts?.userConfigFile,\n });\n const baseUrl = opts?.baseUrlOverride ?? cfg.catalog.url;\n if (isLocalCatalogUrl(baseUrl)) {\n throw new Error(\n \"catalog.url is set to 'local' — remote catalog is disabled. \" +\n \"Use `skaile source add <path>` + `skaile source sync` for local sources, \" +\n \"or set `catalog.url: https://skaile.store` in ~/.skaile/config.yaml.\",\n );\n }\n const cacheTtlMs = cfg.catalog.cache_ttl * 1000;\n if (cfg.catalog.framing === \"rest\") {\n return new RestCatalogSource({ baseUrl, cacheTtlMs });\n }\n return new RemoteCatalogSource({ baseUrl, cacheTtlMs });\n}\n\n/**\n * Resolved catalog source plus a close handle for releasing any underlying\n * resources (e.g. the `LocalIndex` SQLite connection in local mode).\n *\n * Callers MUST invoke `close()` when done — typically in a `finally` block.\n * For remote-mode sources `close()` is a no-op, but the contract is uniform\n * so consumers don't have to branch.\n *\n * @docLink cli/dev-guide#open-library\n */\nexport interface ResolvedCatalogSource {\n /** The {@link ICatalogSource} ready for use. */\n source: import(\"@skaile/workspaces/library\").ICatalogSource;\n /** Release any underlying resources (SQLite handle in local mode). */\n close(): void;\n}\n\n/**\n * Resolve the configured Catalog source — local or remote — based on\n * `~/.skaile/config.yaml`.\n *\n * Dispatch:\n * - `catalog.url: local` → opens {@link LocalIndex}, picks the most recently\n * registered local library whose `path` still exists on disk, and returns a\n * {@link LocalCatalogSource} bound to that library. Throws if no usable\n * local library is registered.\n * - any URL → returns {@link RemoteCatalogSource} (same as\n * {@link openCatalogSource}).\n *\n * The returned `close()` releases the underlying `LocalIndex` SQLite handle\n * in local mode (no-op in remote mode). Callers MUST invoke it — typically in\n * a `finally` block — to satisfy `library/CLAUDE.md` § \"Notes for Consumers\".\n *\n * @param opts - Project directory (overlays project config) and explicit overrides.\n * @returns A `ResolvedCatalogSource` carrying the source and a close handle.\n * @throws When `local` is configured but no usable local library is registered.\n * @docLink cli/dev-guide#open-library\n */\nexport async function resolveCatalogSource(opts?: {\n projectDir?: string;\n baseUrlOverride?: string;\n /** Override the user-config path for tests. */\n userConfigFile?: string;\n}): Promise<ResolvedCatalogSource> {\n const {\n resolveConfig,\n RemoteCatalogSource,\n RestCatalogSource,\n LocalCatalogSource,\n isLocalCatalogUrl,\n } = await import(\"@skaile/workspaces/library\");\n const cfg = resolveConfig({\n projectDir: opts?.projectDir,\n userConfigFile: opts?.userConfigFile,\n });\n const baseUrl = opts?.baseUrlOverride ?? cfg.catalog.url;\n\n if (isLocalCatalogUrl(baseUrl)) {\n const fs = await import(\"node:fs\");\n const library = await openLibrary();\n try {\n const sources = await library.listSources();\n type LibraryRow = (typeof sources)[number];\n // Type-narrow: `path` is required for local libraries after the filter.\n const usable = sources\n .filter(\n (s): s is LibraryRow & { path: string } =>\n s.backend === \"local\" && typeof s.path === \"string\" && s.path.length > 0,\n )\n .sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());\n\n if (usable.length === 0) {\n throw new Error(\n \"catalog.url is set to 'local' but no local library is registered. \" +\n \"Run `skaile source add <path>` first, then `skaile source sync`.\",\n );\n }\n\n // Prefer the most recently added library whose path still exists.\n const present = usable.find((s) => fs.existsSync(s.path));\n if (!present) {\n const head = usable[0];\n throw new Error(\n `catalog.url is set to 'local' but every registered local library has a missing path on disk. ` +\n `Most recent: ${head.path} (library ${head.id}). ` +\n `Re-register with \\`skaile source add <existing-path>\\` or run \\`skaile source list\\` to inspect.`,\n );\n }\n\n const source = new LocalCatalogSource(\n library,\n present.id,\n present.path,\n createFullRegistry(),\n );\n return { source, close: () => library.close() };\n } catch (err) {\n // Release the handle on any failure during dispatch — otherwise the\n // SQLite WAL state leaks for the lifetime of the process.\n library.close();\n throw err;\n }\n }\n\n const cacheTtlMs = cfg.catalog.cache_ttl * 1000;\n const source =\n cfg.catalog.framing === \"rest\"\n ? new RestCatalogSource({ baseUrl, cacheTtlMs })\n : new RemoteCatalogSource({ baseUrl, cacheTtlMs });\n return { source, close: () => {} };\n}\n\n/**\n * Open the LibraryManager bound to the active LocalIndex.\n * Caller owns lifetime — must call `close()` (returned helper closes the\n * underlying LocalIndex).\n *\n * @docLink cli/dev-guide#open-library\n */\nexport async function openLibraryManager(): Promise<{\n manager: import(\"@skaile/workspaces/library\").LibraryManager;\n library: import(\"@skaile/workspaces/library\").LocalIndex;\n close: () => void;\n}> {\n const { LibraryManager } = await import(\"@skaile/workspaces/library\");\n const library = await openLibrary();\n const manager = new LibraryManager(library);\n return { manager, library, close: () => library.close() };\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { factoryAssetRoots } from './chunk-
|
|
1
|
+
import { factoryAssetRoots } from './chunk-HVCZLD5Z.js';
|
|
2
2
|
import fs from 'fs';
|
|
3
3
|
import os from 'os';
|
|
4
4
|
import path from 'path';
|
|
@@ -24,5 +24,5 @@ function aiResourceRoots() {
|
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
export { AI_RESOURCES, MONOREPO_ROOT, aiResourceRoots };
|
|
27
|
-
//# sourceMappingURL=chunk-
|
|
28
|
-
//# sourceMappingURL=chunk-
|
|
27
|
+
//# sourceMappingURL=chunk-BXYMGZCI.js.map
|
|
28
|
+
//# sourceMappingURL=chunk-BXYMGZCI.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../cli/src/paths.ts"],"names":[],"mappings":";;;;;;AAMA,IAAM,WAAW,IAAA,CAAK,OAAA,CAAQ,aAAA,CAAc,MAAA,CAAA,IAAA,CAAY,GAAG,CAAC,CAAA;AAW5D,SAAS,iBAAiB,IAAA,EAA6B;AACrD,EAAA,IAAI,GAAA,GAAM,IAAA;AACV,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,CAAA,EAAG,CAAA,EAAA,EAAK;AAC1B,IAAA,IAAI,EAAA,CAAG,WAAW,IAAA,CAAK,IAAA,CAAK,KAAK,YAAY,CAAC,GAAG,OAAO,GAAA;AACxD,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,OAAA,CAAQ,GAAG,CAAA;AAC/B,IAAA,IAAI,WAAW,GAAA,EAAK;AACpB,IAAA,GAAA,GAAM,MAAA;AAAA,EACR;AACA,EAAA,OAAO,IAAA;AACT;AAYO,IAAM,aAAA,GAA+B,iBAAiB,QAAQ;AAc9D,IAAM,YAAA,GACX,iBAAA,EAAkB,CAAE,CAAC,CAAA,IAAK,IAAA,CAAK,IAAA,CAAK,EAAA,CAAG,OAAA,EAAQ,EAAG,SAAA,EAAW,WAAW;AAoBnE,SAAS,eAAA,GAA4B;AAC1C,EAAA,MAAM,KAAA,GAAkB,CAAC,GAAG,iBAAA,EAAmB,CAAA;AAC/C,EAAA,KAAA,CAAM,IAAA,CAAK,KAAK,IAAA,CAAK,EAAA,CAAG,SAAQ,EAAG,SAAA,EAAW,WAAW,CAAC,CAAA;AAC1D,EAAA,OAAO,CAAC,GAAG,IAAI,GAAA,CAAI,KAAK,CAAC,CAAA,CAAE,MAAA,CAAO,CAAC,CAAA,KAAM,EAAA,CAAG,UAAA,CAAW,CAAC,CAAC,CAAA;AAC3D","file":"chunk-
|
|
1
|
+
{"version":3,"sources":["../cli/src/paths.ts"],"names":[],"mappings":";;;;;;AAMA,IAAM,WAAW,IAAA,CAAK,OAAA,CAAQ,aAAA,CAAc,MAAA,CAAA,IAAA,CAAY,GAAG,CAAC,CAAA;AAW5D,SAAS,iBAAiB,IAAA,EAA6B;AACrD,EAAA,IAAI,GAAA,GAAM,IAAA;AACV,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,CAAA,EAAG,CAAA,EAAA,EAAK;AAC1B,IAAA,IAAI,EAAA,CAAG,WAAW,IAAA,CAAK,IAAA,CAAK,KAAK,YAAY,CAAC,GAAG,OAAO,GAAA;AACxD,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,OAAA,CAAQ,GAAG,CAAA;AAC/B,IAAA,IAAI,WAAW,GAAA,EAAK;AACpB,IAAA,GAAA,GAAM,MAAA;AAAA,EACR;AACA,EAAA,OAAO,IAAA;AACT;AAYO,IAAM,aAAA,GAA+B,iBAAiB,QAAQ;AAc9D,IAAM,YAAA,GACX,iBAAA,EAAkB,CAAE,CAAC,CAAA,IAAK,IAAA,CAAK,IAAA,CAAK,EAAA,CAAG,OAAA,EAAQ,EAAG,SAAA,EAAW,WAAW;AAoBnE,SAAS,eAAA,GAA4B;AAC1C,EAAA,MAAM,KAAA,GAAkB,CAAC,GAAG,iBAAA,EAAmB,CAAA;AAC/C,EAAA,KAAA,CAAM,IAAA,CAAK,KAAK,IAAA,CAAK,EAAA,CAAG,SAAQ,EAAG,SAAA,EAAW,WAAW,CAAC,CAAA;AAC1D,EAAA,OAAO,CAAC,GAAG,IAAI,GAAA,CAAI,KAAK,CAAC,CAAA,CAAE,MAAA,CAAO,CAAC,CAAA,KAAM,EAAA,CAAG,UAAA,CAAW,CAAC,CAAC,CAAA;AAC3D","file":"chunk-BXYMGZCI.js","sourcesContent":["import fs from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { factoryAssetRoots } from \"@skaile/workspaces/core\";\n\nconst __ownDir = path.dirname(fileURLToPath(import.meta.url));\n\n/**\n * Walk up from `from` looking for the monorepo marker (`biome.json`, the\n * repo-root shared tooling config). Returns the matching directory or `null`\n * when none is found within eight levels — the latter is the typical case when\n * `@skaile/workspaces` has been installed via `npm i` without a skaile-dev\n * workspace context. Used only to gate dev-only commands (e.g.\n * `serve --compile-test`); first-party content is located via\n * {@link aiResourceRoots}, not this.\n */\nfunction findMonorepoRoot(from: string): string | null {\n let dir = from;\n for (let i = 0; i < 8; i++) {\n if (fs.existsSync(path.join(dir, \"biome.json\"))) return dir;\n const parent = path.dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n return null;\n}\n\n/**\n * Absolute path to the monorepo root, or `null` when the CLI is running\n * outside the skaile-dev workspace (typical for `npm i -g` installs).\n *\n * Consumers that only make sense inside the workspace (e.g.\n * `skaile serve --compile-test`) MUST check for `null` and report a\n * \"monorepo-only feature\" error before proceeding.\n *\n * @docLink cli/dev-guide#paths\n */\nexport const MONOREPO_ROOT: string | null = findMonorepoRoot(__ownDir);\n\n/**\n * Default content root used by path display and the `validate` command.\n *\n * The primary first-party `factory-assets/` root resolved through the shared\n * `factoryAssetRoots()` helper — the `SKAILE_FACTORY_ASSETS_DIR` override when\n * set, else the in-repo source during dev / bundled `dist/factory-assets/` after\n * `npm i`. Falls back to `~/.skaile/libraries/` — the user-library directory\n * managed by `skaile library add` — when the package cannot be located.\n * Consumers `fs.existsSync` first and degrade to \"no skills / flows discovered\".\n *\n * @docLink cli/dev-guide#paths\n */\nexport const AI_RESOURCES: string =\n factoryAssetRoots()[0] ?? path.join(os.homedir(), \".skaile\", \"libraries\");\n\n/**\n * All content roots that skill / flow discovery should walk, in priority order,\n * filtered to those that exist on disk and de-duplicated.\n *\n * - The first-party `factory-assets/` roots from the shared `factoryAssetRoots()`\n * helper — the `SKAILE_FACTORY_ASSETS_DIR` override layer (when set) ahead of\n * the bundled tree (in-repo source in dev, `dist/factory-assets/` after\n * install). No monorepo special-case.\n * - The user-library dir `~/.skaile/libraries/`.\n *\n * Order is significant: `findSkills` / flow discovery dedupe first-root-wins, so\n * the env override shadows the bundled tree on a name clash.\n *\n * This is the discovery surface used by `findSkills`, flow discovery, and the\n * completion resolvers.\n *\n * @docLink cli/dev-guide#paths\n */\nexport function aiResourceRoots(): string[] {\n const roots: string[] = [...factoryAssetRoots()];\n roots.push(path.join(os.homedir(), \".skaile\", \"libraries\"));\n return [...new Set(roots)].filter((r) => fs.existsSync(r));\n}\n"]}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { renderGoogleDriveConfig, renderOneDriveConfig, renderWebDAVConfig } from './chunk-OVRSNIKJ.js';
|
|
2
|
-
import { resolveAuthRef, resolveAuth, resolveMountCredentialString, resolveMountCredential } from './chunk-
|
|
3
|
-
import { PortPool, createFsWatcher, RcloneProcessManager, ensureDirMode } from './chunk-
|
|
2
|
+
import { resolveAuthRef, resolveAuth, resolveMountCredentialString, resolveMountCredential } from './chunk-R4H6EJW5.js';
|
|
3
|
+
import { PortPool, createFsWatcher, RcloneProcessManager, ensureDirMode } from './chunk-3HUUP3JC.js';
|
|
4
4
|
import { pluginRegistry } from './chunk-6E6PKKAD.js';
|
|
5
5
|
import { computeFlowStateFromSnapshots } from './chunk-X46FY45B.js';
|
|
6
6
|
import { renderStimulusPrompt } from './chunk-DEYYRFQU.js';
|
|
7
7
|
import { computeStimulus } from './chunk-IFGTRL2I.js';
|
|
8
|
-
import { portableSpawn } from './chunk-
|
|
8
|
+
import { portableSpawn } from './chunk-KYQNWFJV.js';
|
|
9
9
|
import { createLogger } from './chunk-JB35MVBN.js';
|
|
10
10
|
import { existsSync, mkdirSync, renameSync, writeFileSync, readFileSync, cpSync, statSync, createReadStream, readdirSync, openSync, writeSync, closeSync, chmodSync } from 'fs';
|
|
11
11
|
import path, { join, dirname, resolve, sep } from 'path';
|
|
@@ -2098,7 +2098,15 @@ var GoogleDriveConnector = class extends AbstractConnector {
|
|
|
2098
2098
|
log: this.log
|
|
2099
2099
|
});
|
|
2100
2100
|
this.log.info("mount ready", { pid: rcloneHandle.pid });
|
|
2101
|
-
const state = {
|
|
2101
|
+
const state = {
|
|
2102
|
+
rcloneHandle,
|
|
2103
|
+
// Safe to close over the handle directly: GoogleDrive has no token-refresh
|
|
2104
|
+
// recycle (unlike sharepoint/webdav, which dereference a handleRef so the
|
|
2105
|
+
// hook follows the recycled handle). If a refresh/reconfigure path is ever
|
|
2106
|
+
// added here, switch this to the handleRef indirection or it will query a
|
|
2107
|
+
// stale handle.
|
|
2108
|
+
authoritativeSize: (relPath) => this.rclone.statSize(rcloneHandle, relPath)
|
|
2109
|
+
};
|
|
2102
2110
|
return this.makeHandle(declaration, state, targetDir);
|
|
2103
2111
|
}
|
|
2104
2112
|
async disconnect(handle) {
|
|
@@ -3578,7 +3586,14 @@ var SharePointConnector = class extends AbstractConnector {
|
|
|
3578
3586
|
this.log.info("mount ready", { pid: rcloneHandle.pid });
|
|
3579
3587
|
handleRef.current = rcloneHandle;
|
|
3580
3588
|
refresh?.schedule(cred.expiresAt);
|
|
3581
|
-
const state = {
|
|
3589
|
+
const state = {
|
|
3590
|
+
handleRef,
|
|
3591
|
+
refresh,
|
|
3592
|
+
authoritativeSize: (relPath) => {
|
|
3593
|
+
const h = handleRef.current;
|
|
3594
|
+
return h ? this.rclone.statSize(h, relPath) : Promise.resolve(null);
|
|
3595
|
+
}
|
|
3596
|
+
};
|
|
3582
3597
|
return this.makeHandle(declaration, state, targetDir);
|
|
3583
3598
|
}
|
|
3584
3599
|
async disconnect(handle) {
|
|
@@ -4527,7 +4542,14 @@ var WebDAVConnector = class extends AbstractConnector {
|
|
|
4527
4542
|
this.log.info("mount ready", { pid: rcloneHandle.pid });
|
|
4528
4543
|
handleRef.current = rcloneHandle;
|
|
4529
4544
|
refresh?.schedule(cred.expiresAt);
|
|
4530
|
-
const state = {
|
|
4545
|
+
const state = {
|
|
4546
|
+
handleRef,
|
|
4547
|
+
refresh,
|
|
4548
|
+
authoritativeSize: (relPath) => {
|
|
4549
|
+
const h = handleRef.current;
|
|
4550
|
+
return h ? this.rclone.statSize(h, relPath) : Promise.resolve(null);
|
|
4551
|
+
}
|
|
4552
|
+
};
|
|
4531
4553
|
return this.makeHandle(declaration, state, targetDir);
|
|
4532
4554
|
}
|
|
4533
4555
|
async disconnect(handle) {
|
|
@@ -5304,6 +5326,11 @@ var ConnectorStartupError = class extends Error {
|
|
|
5304
5326
|
};
|
|
5305
5327
|
|
|
5306
5328
|
// connectors/src/fleet-health-gate.ts
|
|
5329
|
+
function verdictToSurface(verdict) {
|
|
5330
|
+
if (verdict === "healthy") return "open";
|
|
5331
|
+
if (verdict === "degraded") return "ro";
|
|
5332
|
+
return "masked";
|
|
5333
|
+
}
|
|
5307
5334
|
var FleetHealthGate = class {
|
|
5308
5335
|
constructor(target, barrier, log, opts) {
|
|
5309
5336
|
this.target = target;
|
|
@@ -5311,106 +5338,115 @@ var FleetHealthGate = class {
|
|
|
5311
5338
|
this.log = log;
|
|
5312
5339
|
this.unhealthyThreshold = Math.max(1, opts?.unhealthyThreshold ?? 2);
|
|
5313
5340
|
this.healthyThreshold = Math.max(1, opts?.healthyThreshold ?? 2);
|
|
5341
|
+
const initial = opts?.initialSurface ?? "open";
|
|
5342
|
+
this.surface = initial;
|
|
5343
|
+
this.pendingSurface = initial;
|
|
5344
|
+
this.runSurface = initial;
|
|
5314
5345
|
}
|
|
5315
5346
|
target;
|
|
5316
5347
|
barrier;
|
|
5317
5348
|
log;
|
|
5318
5349
|
unhealthyThreshold;
|
|
5319
5350
|
healthyThreshold;
|
|
5320
|
-
/**
|
|
5321
|
-
|
|
5351
|
+
/** The barrier surface actually applied to the target right now. */
|
|
5352
|
+
surface;
|
|
5322
5353
|
/**
|
|
5323
|
-
* The
|
|
5324
|
-
* Hysteresis
|
|
5325
|
-
* while a (slow, async)
|
|
5326
|
-
* the post-transition
|
|
5327
|
-
* this, fast healthy verdicts arriving during a slow `establish()` could meet
|
|
5328
|
-
* `healthyThreshold` before the gate finished tripping, ungating it on the
|
|
5329
|
-
* first healthy verdict afterwards and defeating the threshold.
|
|
5354
|
+
* The surface the most recently *enqueued* transition will settle on.
|
|
5355
|
+
* Hysteresis and re-enqueue de-duping are measured against this, not
|
|
5356
|
+
* `surface`, so verdicts arriving while a (slow, async) barrier op is still in
|
|
5357
|
+
* flight are counted toward the post-transition surface, not the stale one.
|
|
5330
5358
|
*/
|
|
5331
|
-
|
|
5332
|
-
/**
|
|
5333
|
-
|
|
5334
|
-
|
|
5335
|
-
/** Serialises
|
|
5359
|
+
pendingSurface;
|
|
5360
|
+
/** The surface of the *current* same-verdict run, and its length. */
|
|
5361
|
+
runSurface;
|
|
5362
|
+
runLength = 0;
|
|
5363
|
+
/** Serialises barrier ops so overlapping observe() calls can't race. */
|
|
5336
5364
|
transition = Promise.resolve();
|
|
5337
|
-
/** True while
|
|
5365
|
+
/** True while any read-only barrier (ro or masked) is established. */
|
|
5338
5366
|
get isGated() {
|
|
5339
|
-
return this.
|
|
5367
|
+
return this.surface !== "open";
|
|
5368
|
+
}
|
|
5369
|
+
/** The currently-applied surface (test/observability hook). */
|
|
5370
|
+
get currentSurface() {
|
|
5371
|
+
return this.surface;
|
|
5340
5372
|
}
|
|
5341
5373
|
/**
|
|
5342
|
-
* Feed one health verdict. Applies hysteresis, then
|
|
5343
|
-
*
|
|
5344
|
-
* applied. Never throws — a failed
|
|
5374
|
+
* Feed one health verdict. Applies hysteresis, then drives the barrier toward
|
|
5375
|
+
* the target surface on a change. Resolves once the (possibly no-op)
|
|
5376
|
+
* transition is applied. Never throws — a failed barrier op stays gated
|
|
5377
|
+
* (fail-closed).
|
|
5345
5378
|
*/
|
|
5346
5379
|
observe(verdict) {
|
|
5347
|
-
|
|
5348
|
-
|
|
5349
|
-
this.
|
|
5350
|
-
if (this.pendingGated && this.healthyRun >= this.healthyThreshold) {
|
|
5351
|
-
this.pendingGated = false;
|
|
5352
|
-
this.healthyRun = 0;
|
|
5353
|
-
return this.enqueue(() => this.ungate());
|
|
5354
|
-
}
|
|
5380
|
+
const desired = verdictToSurface(verdict);
|
|
5381
|
+
if (desired === this.runSurface) {
|
|
5382
|
+
this.runLength += 1;
|
|
5355
5383
|
} else {
|
|
5356
|
-
this.
|
|
5357
|
-
this.
|
|
5358
|
-
|
|
5359
|
-
|
|
5360
|
-
|
|
5361
|
-
|
|
5362
|
-
|
|
5384
|
+
this.runSurface = desired;
|
|
5385
|
+
this.runLength = 1;
|
|
5386
|
+
}
|
|
5387
|
+
const threshold = desired === "open" ? this.healthyThreshold : this.unhealthyThreshold;
|
|
5388
|
+
if (desired !== this.pendingSurface && this.runLength >= threshold) {
|
|
5389
|
+
this.pendingSurface = desired;
|
|
5390
|
+
this.runLength = 0;
|
|
5391
|
+
return this.enqueue(() => this.apply(desired));
|
|
5363
5392
|
}
|
|
5364
5393
|
return this.transition;
|
|
5365
5394
|
}
|
|
5366
5395
|
/**
|
|
5367
|
-
* Tear the gate down. If
|
|
5368
|
-
* read-only
|
|
5369
|
-
* is disconnected (top-down, no leaked mount).
|
|
5396
|
+
* Tear the gate down. If any barrier is established (or in flight), removes it
|
|
5397
|
+
* so a leftover read-only surface is not leaked. Call only after the connector
|
|
5398
|
+
* above the target is disconnected (top-down, no leaked mount).
|
|
5370
5399
|
*/
|
|
5371
5400
|
dispose() {
|
|
5372
|
-
if (
|
|
5373
|
-
this.
|
|
5374
|
-
return this.enqueue(() => this.
|
|
5401
|
+
if (this.surface === "open" && this.pendingSurface === "open") return this.transition;
|
|
5402
|
+
this.pendingSurface = "open";
|
|
5403
|
+
return this.enqueue(() => this.apply("open"));
|
|
5375
5404
|
}
|
|
5376
5405
|
enqueue(step) {
|
|
5377
5406
|
this.transition = this.transition.then(step, step);
|
|
5378
5407
|
return this.transition;
|
|
5379
5408
|
}
|
|
5380
|
-
|
|
5381
|
-
|
|
5382
|
-
|
|
5409
|
+
/** Drive the barrier to `desired`, fail-closed to `masked` on any throw. */
|
|
5410
|
+
async apply(desired) {
|
|
5411
|
+
if (this.surface === desired) {
|
|
5412
|
+
this.pendingSurface = desired;
|
|
5383
5413
|
return;
|
|
5384
5414
|
}
|
|
5385
5415
|
try {
|
|
5416
|
+
if (desired === "open") {
|
|
5417
|
+
await this.barrier.remove(this.target, this.log);
|
|
5418
|
+
this.surface = "open";
|
|
5419
|
+
this.log?.info("fleet mount recovered \u2014 gate lifted, writable again", {
|
|
5420
|
+
target: this.target
|
|
5421
|
+
});
|
|
5422
|
+
return;
|
|
5423
|
+
}
|
|
5424
|
+
if (desired === "ro") {
|
|
5425
|
+
if (this.barrier.exposeReadOnly) {
|
|
5426
|
+
await this.barrier.exposeReadOnly(this.target, this.log);
|
|
5427
|
+
} else {
|
|
5428
|
+
await this.barrier.establish(this.target, this.log);
|
|
5429
|
+
}
|
|
5430
|
+
this.surface = "ro";
|
|
5431
|
+
this.log?.warn("fleet mount upload-degraded \u2014 gated read-only (content visible)", {
|
|
5432
|
+
target: this.target
|
|
5433
|
+
});
|
|
5434
|
+
return;
|
|
5435
|
+
}
|
|
5386
5436
|
await this.barrier.establish(this.target, this.log);
|
|
5387
|
-
this.
|
|
5388
|
-
this.log?.warn("fleet mount unhealthy \u2014 gated read-only", { target: this.target });
|
|
5437
|
+
this.surface = "masked";
|
|
5438
|
+
this.log?.warn("fleet mount unhealthy \u2014 gated read-only (masked)", { target: this.target });
|
|
5389
5439
|
} catch (err) {
|
|
5390
|
-
|
|
5440
|
+
const safe = "masked";
|
|
5441
|
+
this.surface = safe;
|
|
5442
|
+
this.pendingSurface = safe;
|
|
5391
5443
|
this.log?.error(
|
|
5392
|
-
|
|
5444
|
+
`fleet read-only gate transition to '${desired}' threw \u2014 biasing to '${safe}' (fail-closed)`,
|
|
5393
5445
|
err,
|
|
5394
|
-
{
|
|
5395
|
-
target: this.target
|
|
5396
|
-
}
|
|
5446
|
+
{ target: this.target }
|
|
5397
5447
|
);
|
|
5398
5448
|
}
|
|
5399
5449
|
}
|
|
5400
|
-
async ungate() {
|
|
5401
|
-
if (!this.gated) return;
|
|
5402
|
-
try {
|
|
5403
|
-
await this.barrier.remove(this.target, this.log);
|
|
5404
|
-
} catch (err) {
|
|
5405
|
-
this.pendingGated = true;
|
|
5406
|
-
this.log?.error("fleet read-only gate remove failed \u2014 staying gated", err, {
|
|
5407
|
-
target: this.target
|
|
5408
|
-
});
|
|
5409
|
-
return;
|
|
5410
|
-
}
|
|
5411
|
-
this.gated = false;
|
|
5412
|
-
this.log?.info("fleet mount recovered \u2014 gate lifted, writable again", { target: this.target });
|
|
5413
|
-
}
|
|
5414
5450
|
};
|
|
5415
5451
|
function isFleetManaged(connectorId) {
|
|
5416
5452
|
const raw = process.env.SKAILE_FLEET_MANAGED_MOUNTS ?? "";
|
|
@@ -5563,11 +5599,52 @@ var RoMountPlaceholderBarrier = class {
|
|
|
5563
5599
|
log?.debug("deferred mount live; degraded barrier lifted", { target, mode });
|
|
5564
5600
|
}
|
|
5565
5601
|
}
|
|
5602
|
+
async exposeReadOnly(target, log) {
|
|
5603
|
+
const mode = this.modes.get(target);
|
|
5604
|
+
if (mode === "ro-bind") return;
|
|
5605
|
+
if (mode === "mount") {
|
|
5606
|
+
let unmounted = await this.run("umount", [target]).then(
|
|
5607
|
+
() => true,
|
|
5608
|
+
() => false
|
|
5609
|
+
);
|
|
5610
|
+
if (!unmounted) {
|
|
5611
|
+
unmounted = await this.run("umount", ["-l", target]).then(
|
|
5612
|
+
() => true,
|
|
5613
|
+
() => false
|
|
5614
|
+
);
|
|
5615
|
+
}
|
|
5616
|
+
if (!unmounted) {
|
|
5617
|
+
log?.error(
|
|
5618
|
+
"deferred mount barrier: could not unmount opaque mask to expose read-only surface \u2014 staying masked",
|
|
5619
|
+
void 0,
|
|
5620
|
+
{ target }
|
|
5621
|
+
);
|
|
5622
|
+
return;
|
|
5623
|
+
}
|
|
5624
|
+
}
|
|
5625
|
+
try {
|
|
5626
|
+
await this.run("mount", ["--bind", target, target]);
|
|
5627
|
+
await this.run("mount", ["-o", "remount,ro,bind", target]);
|
|
5628
|
+
this.modes.set(target, "ro-bind");
|
|
5629
|
+
log?.info("deferred mount barrier downgraded to read-only (content visible)", { target });
|
|
5630
|
+
} catch (err) {
|
|
5631
|
+
const chmodOk = await chmod(target, 365).then(
|
|
5632
|
+
() => true,
|
|
5633
|
+
() => false
|
|
5634
|
+
);
|
|
5635
|
+
this.modes.set(target, chmodOk ? "chmod" : "unprotected");
|
|
5636
|
+
log?.error(
|
|
5637
|
+
chmodOk ? "deferred mount read-only-readable surface degraded to chmod (ro bind unavailable) \u2014 a write by the owning uid could bypass it" : "deferred mount read-only-readable surface FAILED (ro bind and chmod both unavailable) \u2014 target may be writable",
|
|
5638
|
+
err instanceof Error ? err : void 0,
|
|
5639
|
+
{ target }
|
|
5640
|
+
);
|
|
5641
|
+
}
|
|
5642
|
+
}
|
|
5566
5643
|
async remove(target, log) {
|
|
5567
5644
|
const mode = this.modes.get(target);
|
|
5568
5645
|
if (!mode) return;
|
|
5569
5646
|
this.modes.delete(target);
|
|
5570
|
-
if (mode === "mount") {
|
|
5647
|
+
if (mode === "mount" || mode === "ro-bind") {
|
|
5571
5648
|
let unmounted = false;
|
|
5572
5649
|
try {
|
|
5573
5650
|
await this.run("umount", [target]);
|
|
@@ -5638,6 +5715,9 @@ function parseFleetHealthPollMs(raw = process.env.SKAILE_FLEET_HEALTH_POLL_MS) {
|
|
|
5638
5715
|
function hasKnownPrefix(ref) {
|
|
5639
5716
|
return KNOWN_PREFIXES.some((p) => ref.startsWith(p));
|
|
5640
5717
|
}
|
|
5718
|
+
function isStrictlyNested(child, parent) {
|
|
5719
|
+
return child.startsWith(`${parent}/`);
|
|
5720
|
+
}
|
|
5641
5721
|
async function resolveFields(declaration, fields, chain) {
|
|
5642
5722
|
const resolved = {};
|
|
5643
5723
|
for (const field of fields) {
|
|
@@ -5750,6 +5830,8 @@ var ConnectorManager = class {
|
|
|
5750
5830
|
}
|
|
5751
5831
|
opts;
|
|
5752
5832
|
active = /* @__PURE__ */ new Map();
|
|
5833
|
+
// Allocated absolute mount target → owning connector id; collisions rejected at setup, released on disconnect.
|
|
5834
|
+
mountTargets = /* @__PURE__ */ new Map();
|
|
5753
5835
|
workspaceDir;
|
|
5754
5836
|
chain;
|
|
5755
5837
|
secrets;
|
|
@@ -5865,6 +5947,35 @@ var ConnectorManager = class {
|
|
|
5865
5947
|
const mountPath = mountConf?.target ?? `.mounts/${declaration.id}`;
|
|
5866
5948
|
return resolve(this.workspaceDir, mountPath);
|
|
5867
5949
|
}
|
|
5950
|
+
// Record absPath → id: same-id is idempotent, an exact-equal collision throws
|
|
5951
|
+
// (naming both ids + the path) so a silent shadow fails at setup, nesting warns.
|
|
5952
|
+
reserveMountTarget(id, absPath) {
|
|
5953
|
+
const owner = this.mountTargets.get(absPath);
|
|
5954
|
+
if (owner === id) return;
|
|
5955
|
+
if (owner !== void 0) {
|
|
5956
|
+
throw new Error(
|
|
5957
|
+
`Mount target collision: connectors "${owner}" and "${id}" both resolve to "${absPath}". Each filesystem connector needs a distinct mount.target.`
|
|
5958
|
+
);
|
|
5959
|
+
}
|
|
5960
|
+
for (const [otherPath, otherId] of this.mountTargets) {
|
|
5961
|
+
if (otherId === id) continue;
|
|
5962
|
+
if (isStrictlyNested(absPath, otherPath) || isStrictlyNested(otherPath, absPath)) {
|
|
5963
|
+
this.mgrLog.warn("nested mount target overlap between connectors", {
|
|
5964
|
+
connectorId: id,
|
|
5965
|
+
otherConnectorId: otherId,
|
|
5966
|
+
target: absPath,
|
|
5967
|
+
otherTarget: otherPath
|
|
5968
|
+
});
|
|
5969
|
+
}
|
|
5970
|
+
}
|
|
5971
|
+
this.mountTargets.set(absPath, id);
|
|
5972
|
+
}
|
|
5973
|
+
/** Release every mount target owned by `id` (on disconnect). */
|
|
5974
|
+
releaseMountTarget(id) {
|
|
5975
|
+
for (const [path2, owner] of [...this.mountTargets]) {
|
|
5976
|
+
if (owner === id) this.mountTargets.delete(path2);
|
|
5977
|
+
}
|
|
5978
|
+
}
|
|
5868
5979
|
/**
|
|
5869
5980
|
* Build a `ConnectContext` for a connector, resolving fields and — for
|
|
5870
5981
|
* filesystem-face connectors — allocating the mount-target directory.
|
|
@@ -5882,6 +5993,7 @@ var ConnectorManager = class {
|
|
|
5882
5993
|
}
|
|
5883
5994
|
if (connector.filesystem != null) {
|
|
5884
5995
|
const absPath = this.resolveMountTarget(declaration);
|
|
5996
|
+
this.reserveMountTarget(declaration.id, absPath);
|
|
5885
5997
|
if (!existsSync(absPath)) mkdirSync(absPath, { recursive: true });
|
|
5886
5998
|
ctx.mountTarget = absPath;
|
|
5887
5999
|
}
|
|
@@ -5943,6 +6055,9 @@ var ConnectorManager = class {
|
|
|
5943
6055
|
*/
|
|
5944
6056
|
async connectAll(declarations, options) {
|
|
5945
6057
|
this.mgrLog.info("connectAll start", { count: declarations.length });
|
|
6058
|
+
for (const decl of declarations) {
|
|
6059
|
+
if (decl.mount != null) this.reserveMountTarget(decl.id, this.resolveMountTarget(decl));
|
|
6060
|
+
}
|
|
5946
6061
|
const results = [];
|
|
5947
6062
|
const eager = [];
|
|
5948
6063
|
const deferred = [];
|
|
@@ -6160,10 +6275,33 @@ var ConnectorManager = class {
|
|
|
6160
6275
|
* writable* degraded mount that the local probe cannot. The runner watches the
|
|
6161
6276
|
* `<workspace>/.skaile/fleet-health/<connectorId>` flag and forwards its verdict
|
|
6162
6277
|
* here. Unknown / non-fleet ids are ignored.
|
|
6278
|
+
*
|
|
6279
|
+
* The verdict drives the gate across three surfaces (writable / read-only-
|
|
6280
|
+
* readable / masked): `healthy` lifts any barrier, `degraded` downgrades to a
|
|
6281
|
+
* read-only surface that keeps the live content visible, `error` keeps the
|
|
6282
|
+
* opaque mask.
|
|
6283
|
+
*
|
|
6284
|
+
* A deferred remote mount may have been brought up with the *static* boot-time
|
|
6285
|
+
* barrier (it was not fleet-managed at connect — e.g. the host bind landed
|
|
6286
|
+
* late, after `connectAll` placed the not-ready barrier). When a fleet verdict
|
|
6287
|
+
* later arrives for such a connector, a gate is created lazily over that same
|
|
6288
|
+
* barrier (seeded `masked`, matching the static barrier already in place) so the
|
|
6289
|
+
* authoritative platform signal can lift or downgrade it — otherwise a late-
|
|
6290
|
+
* arriving live mount stays masked forever even after it goes healthy.
|
|
6163
6291
|
*/
|
|
6164
6292
|
async reportFleetHealth(connectorId, verdict) {
|
|
6165
6293
|
const entry = this.active.get(connectorId);
|
|
6166
|
-
if (!entry
|
|
6294
|
+
if (!entry) return;
|
|
6295
|
+
if (!entry.fleetHealthGate) {
|
|
6296
|
+
if (!entry.placeholderTarget) return;
|
|
6297
|
+
entry.fleetHealthTarget = entry.placeholderTarget;
|
|
6298
|
+
entry.fleetHealthGate = new FleetHealthGate(
|
|
6299
|
+
entry.placeholderTarget,
|
|
6300
|
+
this.placeholderBarrier,
|
|
6301
|
+
this.mgrLog,
|
|
6302
|
+
{ initialSurface: "masked" }
|
|
6303
|
+
);
|
|
6304
|
+
}
|
|
6167
6305
|
await entry.fleetHealthGate.observe(verdict).catch(() => {
|
|
6168
6306
|
});
|
|
6169
6307
|
}
|
|
@@ -6252,6 +6390,7 @@ var ConnectorManager = class {
|
|
|
6252
6390
|
});
|
|
6253
6391
|
}
|
|
6254
6392
|
this.active.clear();
|
|
6393
|
+
this.mountTargets.clear();
|
|
6255
6394
|
this.mgrLog.info("disconnectAll complete");
|
|
6256
6395
|
}
|
|
6257
6396
|
// ── Hot-plug ──────────────────────────────────────────────────────────────────
|
|
@@ -6297,6 +6436,7 @@ var ConnectorManager = class {
|
|
|
6297
6436
|
});
|
|
6298
6437
|
return handle;
|
|
6299
6438
|
} catch (err) {
|
|
6439
|
+
this.releaseMountTarget(declaration.id);
|
|
6300
6440
|
const msg = err instanceof Error ? err.message : String(err);
|
|
6301
6441
|
this.opts.onStatusChange?.({
|
|
6302
6442
|
type: "connector_status",
|
|
@@ -6338,6 +6478,7 @@ var ConnectorManager = class {
|
|
|
6338
6478
|
if (entry.fleetHealthGate) await entry.fleetHealthGate.dispose().catch(() => {
|
|
6339
6479
|
});
|
|
6340
6480
|
this.active.delete(id);
|
|
6481
|
+
this.releaseMountTarget(id);
|
|
6341
6482
|
this.opts.onStatusChange?.({
|
|
6342
6483
|
type: "connector_status",
|
|
6343
6484
|
connectorId: id,
|
|
@@ -6865,7 +7006,7 @@ function buildConnectorPromptSection(manager, options) {
|
|
|
6865
7006
|
sections.push(buildFilesystemSection(manager, fsConnectors));
|
|
6866
7007
|
}
|
|
6867
7008
|
if (toolConnectors.length > 0) {
|
|
6868
|
-
sections.push(buildToolSection(toolConnectors, shellAccess));
|
|
7009
|
+
sections.push(buildToolSection(manager, toolConnectors, shellAccess));
|
|
6869
7010
|
}
|
|
6870
7011
|
return sections.join("\n\n");
|
|
6871
7012
|
}
|
|
@@ -6920,7 +7061,7 @@ function appendGitAuthNotes(lines, manager, fsConnectors) {
|
|
|
6920
7061
|
);
|
|
6921
7062
|
}
|
|
6922
7063
|
}
|
|
6923
|
-
function buildToolSection(toolConnectors, shellAccess) {
|
|
7064
|
+
function buildToolSection(manager, toolConnectors, shellAccess) {
|
|
6924
7065
|
const lines = ["## Connectors", ""];
|
|
6925
7066
|
lines.push("Currently registered connectors (id \u2014 driver, access):");
|
|
6926
7067
|
for (const r of toolConnectors) {
|
|
@@ -6931,6 +7072,18 @@ function buildToolSection(toolConnectors, shellAccess) {
|
|
|
6931
7072
|
"Additional connectors may be registered mid-session by the host \u2014 notably shared-state stores (driver: `xstate-store`, e.g. `session`, `presence`, per-component stores). Re-enumerate with `connector_list` whenever you need the live set."
|
|
6932
7073
|
);
|
|
6933
7074
|
lines.push("");
|
|
7075
|
+
for (const r of toolConnectors) {
|
|
7076
|
+
let instructions;
|
|
7077
|
+
try {
|
|
7078
|
+
instructions = manager.get(r.id).declaration.instructions;
|
|
7079
|
+
} catch {
|
|
7080
|
+
}
|
|
7081
|
+
if (instructions && instructions.trim().length > 0) {
|
|
7082
|
+
lines.push(`Guidance for \`${r.id}\`:`);
|
|
7083
|
+
lines.push(instructions.trim());
|
|
7084
|
+
lines.push("");
|
|
7085
|
+
}
|
|
7086
|
+
}
|
|
6934
7087
|
if (shellAccess) {
|
|
6935
7088
|
lines.push("Discover connectors:");
|
|
6936
7089
|
lines.push("- `connector_list` tool \u2014 returns the live connector set as JSON.");
|
|
@@ -8458,5 +8611,5 @@ function createConnector() {
|
|
|
8458
8611
|
}
|
|
8459
8612
|
|
|
8460
8613
|
export { AbstractConnector, BUILTIN_CONNECTOR_CATALOG, ConnectorFieldMissingError, ConnectorManager, ConnectorStartupError, DEFAULT_REACTIVE_COOLDOWN_MS, DeployConnector, DevServerConnector, FleetHealthGate, FlowAdapter, GitConnector, GmailConnector, GoogleDriveConnector, LocalConnector, LogBuffer, ManagedGitconfigCollisionError, MattermostConnector, MemoryConnector, MinIOConnector, NOT_READY_SENTINEL, PROACTIVE_RCLONE_REFRESH_MARGIN_MS, PostgresConnector, RoMountPlaceholderBarrier, S3Connector, SQLiteConnector, SharePointConnector, StaticServerConnector, TunnelConnector, WebDAVConnector, XStateConnector, XStateStoreConnector, __test, atomicReplaceCredential, buildConnectorPromptSection, buildSdkConnectorTools, createConnector, createConnector10, createConnector11, createConnector12, createConnector13, createConnector14, createConnector15, createConnector16, createConnector17, createConnector18, createConnector19, createConnector2, createConnector3, createConnector4, createConnector5, createConnector6, createConnector7, createConnector8, createConnector9, createRcloneTokenRefresh, createWorktree, defaultMountPlaceholderBarrier, defaultSpawn, ensureFleetMounted, findGitRoot, findMissingPackages, getConnector, installNpmPackages, isFleetManaged, isPackageResolvable, listConnectors, listWorktrees, probeFleetHealth, registerBuiltinConnectors, removeMountBlock, renderCredentialHelperScript, tryGetConnector, worktreeRegistry, writeHelperScript, writeMountBlock };
|
|
8461
|
-
//# sourceMappingURL=chunk-
|
|
8462
|
-
//# sourceMappingURL=chunk-
|
|
8614
|
+
//# sourceMappingURL=chunk-F5Q2RMH4.js.map
|
|
8615
|
+
//# sourceMappingURL=chunk-F5Q2RMH4.js.map
|