@skaile/workspaces 0.15.0 → 0.15.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 +35 -0
- package/dist/asset-manager/index.js +2 -2
- package/dist/asset-manager/installer.js +1 -1
- package/dist/asset-manager/src/index.d.ts.map +1 -1
- package/dist/asset-manager/src/installer.d.ts.map +1 -1
- package/dist/base-assets/connectors/flow/run-flow.js +1 -1
- package/dist/{chunk-SO43XRWF.js → chunk-67TJEQJE.js} +2 -2
- package/dist/{chunk-SO43XRWF.js.map → chunk-67TJEQJE.js.map} +1 -1
- package/dist/{chunk-7R4WLTZW.js → chunk-DEZVZSBN.js} +11 -16
- package/dist/chunk-DEZVZSBN.js.map +1 -0
- package/dist/{chunk-4GEVGRWB.js → chunk-ERCOCLW5.js} +9 -11
- package/dist/chunk-ERCOCLW5.js.map +1 -0
- package/dist/{chunk-2NIOMFSQ.js → chunk-FNCYNUGS.js} +78 -81
- package/dist/chunk-FNCYNUGS.js.map +1 -0
- package/dist/{chunk-Z24KPZKU.js → chunk-HJV7MHG5.js} +2 -2
- package/dist/{chunk-Z24KPZKU.js.map → chunk-HJV7MHG5.js.map} +1 -1
- package/dist/{chunk-6EN5IJ2Y.js → chunk-IY4X7PZN.js} +3 -3
- package/dist/{chunk-6EN5IJ2Y.js.map → chunk-IY4X7PZN.js.map} +1 -1
- package/dist/cli/index.js +146 -98
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/src/commands/manage.d.ts +31 -20
- package/dist/cli/src/commands/manage.d.ts.map +1 -1
- package/dist/library/index.js +1 -1
- package/dist/library/src/local/db.d.ts.map +1 -1
- package/dist/library/src/local/store-paths.d.ts.map +1 -1
- package/dist/{open-library-XD7QYLMW.js → open-library-T6RXQJTQ.js} +4 -4
- package/dist/{open-library-XD7QYLMW.js.map → open-library-T6RXQJTQ.js.map} +1 -1
- package/dist/runner/index.js +1 -1
- package/dist/sdk/asset-manager.js +2 -2
- package/dist/sdk/index.js +1 -1
- package/dist/sdk/runner.js +1 -1
- package/dist/tui/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-2NIOMFSQ.js.map +0 -1
- package/dist/chunk-4GEVGRWB.js.map +0 -1
- package/dist/chunk-7R4WLTZW.js.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { logErr } from './chunk-4NDWKA64.js';
|
|
2
|
-
import { knowledgeKindProvider } from './chunk-
|
|
2
|
+
import { knowledgeKindProvider } from './chunk-FNCYNUGS.js';
|
|
3
3
|
import { createDefaultRegistry } from './chunk-GKIA2PU5.js';
|
|
4
4
|
import { flowKindProvider } from './chunk-ICS76R4T.js';
|
|
5
5
|
|
|
@@ -97,5 +97,5 @@ async function openLibraryManager() {
|
|
|
97
97
|
}
|
|
98
98
|
|
|
99
99
|
export { createFullRegistry, openCatalogSource, openLibrary, openLibraryManager, resolveCatalogSource };
|
|
100
|
-
//# sourceMappingURL=chunk-
|
|
101
|
-
//# sourceMappingURL=chunk-
|
|
100
|
+
//# sourceMappingURL=chunk-IY4X7PZN.js.map
|
|
101
|
+
//# sourceMappingURL=chunk-IY4X7PZN.js.map
|
|
@@ -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-6EN5IJ2Y.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/base-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 { flowKindProvider } from \"@skaile/workspaces/base-assets/connectors/flow/engine\";\nimport type { AssetKindRegistry } from \"@skaile/workspaces/discovery\";\nimport { createDefaultRegistry } from \"@skaile/workspaces/discovery\";\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/base-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":";;;;;;AA2BO,SAAS,kBAAA,GAAwC;AACtD,EAAA,MAAM,WAAW,qBAAA,EAAsB;AACvC,EAAA,QAAA,CAAS,SAAS,gBAAgB,CAAA;AAClC,EAAA,QAAA,CAAS,SAAS,qBAAqB,CAAA;AACvC,EAAA,OAAO,QAAA;AACT;;;ACTA,eAAsB,WAAA,GAAc;AAClC,EAAA,IAAI;AACF,IAAA,MAAM,EAAE,UAAA,EAAW,GAAI,MAAM,OAAO,oBAA4B,CAAA;AAChE,IAAA,OAAO,IAAI,UAAA,CAAW,EAAE,YAAA,EAAc,kBAAA,IAAsB,CAAA;AAAA,EAC9D,SAAS,GAAA,EAAK;AACZ,IAAA,MAAA,CAAO,CAAA,2BAAA,EAA8B,eAAe,KAAA,GAAQ,GAAA,CAAI,UAAU,MAAA,CAAO,GAAG,CAAC,CAAA,CAAE,CAAA;AACvF,IAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,EAChB;AACF;AAqBA,eAAsB,kBAAkB,IAAA,EAQtC;AACA,EAAA,MAAM,EAAE,eAAe,mBAAA,EAAqB,iBAAA,EAAmB,mBAAkB,GAAI,MAAM,OACzF,oBACF,CAAA;AACA,EAAA,MAAM,MAAM,aAAA,CAAc;AAAA,IACxB,YAAY,IAAA,EAAM,UAAA;AAAA,IAClB,gBAAgB,IAAA,EAAM;AAAA,GACvB,CAAA;AACD,EAAA,MAAM,OAAA,GAAU,IAAA,EAAM,eAAA,IAAmB,GAAA,CAAI,OAAA,CAAQ,GAAA;AACrD,EAAA,IAAI,iBAAA,CAAkB,OAAO,CAAA,EAAG;AAC9B,IAAA,MAAM,IAAI,KAAA;AAAA,MACR;AAAA,KAGF;AAAA,EACF;AACA,EAAA,MAAM,UAAA,GAAa,GAAA,CAAI,OAAA,CAAQ,SAAA,GAAY,GAAA;AAC3C,EAAA,IAAI,GAAA,CAAI,OAAA,CAAQ,OAAA,KAAY,MAAA,EAAQ;AAClC,IAAA,OAAO,IAAI,iBAAA,CAAkB,EAAE,OAAA,EAAS,YAAY,CAAA;AAAA,EACtD;AACA,EAAA,OAAO,IAAI,mBAAA,CAAoB,EAAE,OAAA,EAAS,YAAY,CAAA;AACxD;AAwCA,eAAsB,qBAAqB,IAAA,EAKR;AACjC,EAAA,MAAM;AAAA,IACJ,aAAA;AAAA,IACA,mBAAA;AAAA,IACA,iBAAA;AAAA,IACA,kBAAA;AAAA,IACA;AAAA,GACF,GAAI,MAAM,OAAO,oBAA4B,CAAA;AAC7C,EAAA,MAAM,MAAM,aAAA,CAAc;AAAA,IACxB,YAAY,IAAA,EAAM,UAAA;AAAA,IAClB,gBAAgB,IAAA,EAAM;AAAA,GACvB,CAAA;AACD,EAAA,MAAM,OAAA,GAAU,IAAA,EAAM,eAAA,IAAmB,GAAA,CAAI,OAAA,CAAQ,GAAA;AAErD,EAAA,IAAI,iBAAA,CAAkB,OAAO,CAAA,EAAG;AAC9B,IAAA,MAAM,EAAA,GAAK,MAAM,OAAO,IAAS,CAAA;AACjC,IAAA,MAAM,OAAA,GAAU,MAAM,WAAA,EAAY;AAClC,IAAA,IAAI;AACF,MAAA,MAAM,OAAA,GAAU,MAAM,OAAA,CAAQ,WAAA,EAAY;AAG1C,MAAA,MAAM,SAAS,OAAA,CACZ,MAAA;AAAA,QACC,CAAC,CAAA,KACC,CAAA,CAAE,OAAA,KAAY,OAAA,IAAW,OAAO,CAAA,CAAE,IAAA,KAAS,QAAA,IAAY,CAAA,CAAE,IAAA,CAAK,MAAA,GAAS;AAAA,OAC3E,CACC,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM,CAAA,CAAE,SAAA,CAAU,OAAA,EAAQ,GAAI,CAAA,CAAE,SAAA,CAAU,OAAA,EAAS,CAAA;AAE/D,MAAA,IAAI,MAAA,CAAO,WAAW,CAAA,EAAG;AACvB,QAAA,MAAM,IAAI,KAAA;AAAA,UACR;AAAA,SAEF;AAAA,MACF;AAGA,MAAA,MAAM,OAAA,GAAU,OAAO,IAAA,CAAK,CAAC,MAAM,EAAA,CAAG,UAAA,CAAW,CAAA,CAAE,IAAI,CAAC,CAAA;AACxD,MAAA,IAAI,CAAC,OAAA,EAAS;AACZ,QAAA,MAAM,IAAA,GAAO,OAAO,CAAC,CAAA;AACrB,QAAA,MAAM,IAAI,KAAA;AAAA,UACR,CAAA,0GAAA,EACkB,IAAA,CAAK,IAAI,CAAA,UAAA,EAAa,KAAK,EAAE,CAAA,mGAAA;AAAA,SAEjD;AAAA,MACF;AAEA,MAAA,MAAMA,UAAS,IAAI,kBAAA;AAAA,QACjB,OAAA;AAAA,QACA,OAAA,CAAQ,EAAA;AAAA,QACR,OAAA,CAAQ,IAAA;AAAA,QACR,kBAAA;AAAmB,OACrB;AACA,MAAA,OAAO,EAAE,MAAA,EAAAA,OAAAA,EAAQ,OAAO,MAAM,OAAA,CAAQ,OAAM,EAAE;AAAA,IAChD,SAAS,GAAA,EAAK;AAGZ,MAAA,OAAA,CAAQ,KAAA,EAAM;AACd,MAAA,MAAM,GAAA;AAAA,IACR;AAAA,EACF;AAEA,EAAA,MAAM,UAAA,GAAa,GAAA,CAAI,OAAA,CAAQ,SAAA,GAAY,GAAA;AAC3C,EAAA,MAAM,SACJ,GAAA,CAAI,OAAA,CAAQ,OAAA,KAAY,MAAA,GACpB,IAAI,iBAAA,CAAkB,EAAE,OAAA,EAAS,UAAA,EAAY,CAAA,GAC7C,IAAI,oBAAoB,EAAE,OAAA,EAAS,YAAY,CAAA;AACrD,EAAA,OAAO,EAAE,MAAA,EAAQ,KAAA,EAAO,MAAM;AAAA,EAAC,CAAA,EAAE;AACnC;AASA,eAAsB,kBAAA,GAInB;AACD,EAAA,MAAM,EAAE,cAAA,EAAe,GAAI,MAAM,OAAO,oBAA4B,CAAA;AACpE,EAAA,MAAM,OAAA,GAAU,MAAM,WAAA,EAAY;AAClC,EAAA,MAAM,OAAA,GAAU,IAAI,cAAA,CAAe,OAAO,CAAA;AAC1C,EAAA,OAAO,EAAE,OAAA,EAAS,OAAA,EAAS,OAAO,MAAM,OAAA,CAAQ,OAAM,EAAE;AAC1D","file":"chunk-IY4X7PZN.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/base-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 { flowKindProvider } from \"@skaile/workspaces/base-assets/connectors/flow/engine\";\nimport type { AssetKindRegistry } from \"@skaile/workspaces/discovery\";\nimport { createDefaultRegistry } from \"@skaile/workspaces/discovery\";\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/base-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"]}
|
package/dist/cli/index.js
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { openCatalogSource, openLibrary, createFullRegistry, openLibraryManager } from '../chunk-
|
|
2
|
+
import { openCatalogSource, openLibrary, createFullRegistry, openLibraryManager } from '../chunk-IY4X7PZN.js';
|
|
3
3
|
import { logErr, S, logOk, colorRef, logInfo, logWarn, kindColorPad, kindColor, formatRelativeTime } from '../chunk-4NDWKA64.js';
|
|
4
4
|
import { getStoreConfig, storeFetch, saveStoreTokens, clearStoreTokens, isStoreAuthenticated } from '../chunk-6DEGWPAR.js';
|
|
5
5
|
import { AI_RESOURCES } from '../chunk-2M3XTMOL.js';
|
|
6
6
|
import { LocalSecretsProvider } from '../chunk-JDX54X4Y.js';
|
|
7
|
-
import { resolveLibraryDir, skaileHomeDir } from '../chunk-
|
|
7
|
+
import { resolveLibraryDir, skaileHomeDir } from '../chunk-FNCYNUGS.js';
|
|
8
8
|
import '../chunk-R7FOF242.js';
|
|
9
9
|
import '../chunk-GKIA2PU5.js';
|
|
10
10
|
import '../chunk-OKRUTSG7.js';
|
|
11
|
-
import { runFlow, resumeFlow } from '../chunk-
|
|
11
|
+
import { runFlow, resumeFlow } from '../chunk-67TJEQJE.js';
|
|
12
12
|
import '../chunk-GCJXPUHG.js';
|
|
13
13
|
import { validateFlowVersions, parseSkillFrontmatter } from '../chunk-IPUYL6TD.js';
|
|
14
|
-
import { runAgentChat, loadSessionById, loadSession, listSessions, setCurrentSession, deleteSession, clearSession, loadAgentManifest, compileComposition, MarkdownStreamer, resolveMixin } from '../chunk-
|
|
14
|
+
import { runAgentChat, loadSessionById, loadSession, listSessions, setCurrentSession, deleteSession, clearSession, loadAgentManifest, compileComposition, MarkdownStreamer, resolveMixin } from '../chunk-HJV7MHG5.js';
|
|
15
15
|
import { buildClaudePluginFiles } from '../chunk-G7O7WDXX.js';
|
|
16
16
|
import '../chunk-X5YPJV4N.js';
|
|
17
17
|
import '../chunk-O7SG5PC2.js';
|
|
@@ -32,8 +32,8 @@ import '../chunk-QAVZOJCV.js';
|
|
|
32
32
|
import { loadAllFlows } from '../chunk-ICS76R4T.js';
|
|
33
33
|
import '../chunk-GZWJGNNN.js';
|
|
34
34
|
import '../chunk-FVTV7M76.js';
|
|
35
|
-
import { AssetManager } from '../chunk-
|
|
36
|
-
import '../chunk-
|
|
35
|
+
import { AssetManager } from '../chunk-DEZVZSBN.js';
|
|
36
|
+
import '../chunk-ERCOCLW5.js';
|
|
37
37
|
import { readLock, resolveSettings, globalSettingsPath, projectSettingsPath, loadSettings, saveSettings, portableSpawn, portableSpawnSync } from '../chunk-4RUVG5GX.js';
|
|
38
38
|
import '../chunk-JKNWJ64A.js';
|
|
39
39
|
import { SUPPORTED_DRIVER_TARGETS } from '../chunk-O4JH3KUE.js';
|
|
@@ -470,7 +470,7 @@ function makeCatalogCommand() {
|
|
|
470
470
|
const cfg = resolveConfig({ projectDir });
|
|
471
471
|
const baseUrl = opts.url ?? cfg.catalog.url;
|
|
472
472
|
if (isLocalCatalogUrl(baseUrl)) {
|
|
473
|
-
const { resolveCatalogSource } = await import('../open-library-
|
|
473
|
+
const { resolveCatalogSource } = await import('../open-library-T6RXQJTQ.js');
|
|
474
474
|
let resolved;
|
|
475
475
|
try {
|
|
476
476
|
resolved = await resolveCatalogSource({ projectDir: opts.projectDir });
|
|
@@ -2022,42 +2022,43 @@ function makeLogsCommand() {
|
|
|
2022
2022
|
}
|
|
2023
2023
|
var am;
|
|
2024
2024
|
var state = {
|
|
2025
|
-
tab: "
|
|
2025
|
+
tab: "assets",
|
|
2026
2026
|
cursor: 0,
|
|
2027
2027
|
assetRows: [],
|
|
2028
|
+
sourceRows: [],
|
|
2028
2029
|
libraryRows: [],
|
|
2029
2030
|
visibleRows: [],
|
|
2030
2031
|
pendingAdds: /* @__PURE__ */ new Set(),
|
|
2031
2032
|
pendingRemoves: /* @__PURE__ */ new Set(),
|
|
2032
|
-
|
|
2033
|
+
collapsedSources: /* @__PURE__ */ new Set(),
|
|
2033
2034
|
collapsedDomains: /* @__PURE__ */ new Set(),
|
|
2034
2035
|
message: "",
|
|
2035
2036
|
cols: 80,
|
|
2036
2037
|
awaitingExitConfirm: false
|
|
2037
2038
|
};
|
|
2038
|
-
function buildVisibleRows(rows,
|
|
2039
|
+
function buildVisibleRows(rows, collapsedSources, collapsedDomains) {
|
|
2039
2040
|
return rows.filter((row) => {
|
|
2040
|
-
if (row.type === "
|
|
2041
|
-
if (row.type === "header") return !
|
|
2042
|
-
const
|
|
2041
|
+
if (row.type === "source-header") return true;
|
|
2042
|
+
if (row.type === "header") return !collapsedSources.has(row.source);
|
|
2043
|
+
const source = row.entry?.repository ?? "other";
|
|
2043
2044
|
const domain = row.entry?.domain ?? "other";
|
|
2044
|
-
return !
|
|
2045
|
+
return !collapsedSources.has(source) && !collapsedDomains.has(`${source}:${domain}`);
|
|
2045
2046
|
});
|
|
2046
2047
|
}
|
|
2047
|
-
function domainAssetRefs(rows,
|
|
2048
|
-
return rows.filter((r) => isAsset(r) && inDomain(r,
|
|
2048
|
+
function domainAssetRefs(rows, source, domain) {
|
|
2049
|
+
return rows.filter((r) => isAsset(r) && inDomain(r, source, domain)).map((r) => assetRefOf(r));
|
|
2049
2050
|
}
|
|
2050
|
-
function
|
|
2051
|
-
return rows.filter((r) => isAsset(r) &&
|
|
2051
|
+
function sourceAssetRefs(rows, source) {
|
|
2052
|
+
return rows.filter((r) => isAsset(r) && inSource(r, source)).map((r) => assetRefOf(r));
|
|
2052
2053
|
}
|
|
2053
2054
|
function isAsset(r) {
|
|
2054
2055
|
return r.type === "asset";
|
|
2055
2056
|
}
|
|
2056
|
-
function
|
|
2057
|
-
return (r.entry?.repository ?? "other") ===
|
|
2057
|
+
function inSource(r, source) {
|
|
2058
|
+
return (r.entry?.repository ?? "other") === source;
|
|
2058
2059
|
}
|
|
2059
|
-
function inDomain(r,
|
|
2060
|
-
return
|
|
2060
|
+
function inDomain(r, source, domain) {
|
|
2061
|
+
return inSource(r, source) && (r.entry?.domain ?? "other") === domain;
|
|
2061
2062
|
}
|
|
2062
2063
|
function assetRefOf(r) {
|
|
2063
2064
|
if (!isAsset(r) || !r.entry) return null;
|
|
@@ -2081,17 +2082,17 @@ function setSelection(ref, action) {
|
|
|
2081
2082
|
state.pendingRemoves.delete(ref);
|
|
2082
2083
|
return;
|
|
2083
2084
|
}
|
|
2084
|
-
resolved = row.
|
|
2085
|
+
resolved = row.installed ? "remove" : "add";
|
|
2085
2086
|
} else {
|
|
2086
2087
|
resolved = action;
|
|
2087
2088
|
}
|
|
2088
2089
|
if (resolved === "add") {
|
|
2089
2090
|
state.pendingRemoves.delete(ref);
|
|
2090
|
-
if (row.
|
|
2091
|
+
if (row.installed) return;
|
|
2091
2092
|
state.pendingAdds.add(ref);
|
|
2092
2093
|
} else {
|
|
2093
2094
|
state.pendingAdds.delete(ref);
|
|
2094
|
-
if (!row.
|
|
2095
|
+
if (!row.installed) return;
|
|
2095
2096
|
state.pendingRemoves.add(ref);
|
|
2096
2097
|
}
|
|
2097
2098
|
}
|
|
@@ -2099,51 +2100,53 @@ function bulkSelection(refs, action) {
|
|
|
2099
2100
|
for (const ref of refs) setSelection(ref, action);
|
|
2100
2101
|
}
|
|
2101
2102
|
function actOnHeader(row, action) {
|
|
2102
|
-
if (row.type === "
|
|
2103
|
-
bulkSelection(
|
|
2103
|
+
if (row.type === "source-header") {
|
|
2104
|
+
bulkSelection(sourceAssetRefs(state.assetRows, row.source), action);
|
|
2104
2105
|
return true;
|
|
2105
2106
|
}
|
|
2106
2107
|
if (row.type === "header") {
|
|
2107
|
-
bulkSelection(domainAssetRefs(state.assetRows, row.
|
|
2108
|
+
bulkSelection(domainAssetRefs(state.assetRows, row.source, row.domain), action);
|
|
2108
2109
|
return true;
|
|
2109
2110
|
}
|
|
2110
2111
|
return false;
|
|
2111
2112
|
}
|
|
2112
2113
|
function loadAssets() {
|
|
2113
2114
|
const entries = am.search();
|
|
2114
|
-
const
|
|
2115
|
-
const
|
|
2115
|
+
const installed = new Set(am.listDeployed().map((e) => `${e.kind}:${e.name}`));
|
|
2116
|
+
const bySource = /* @__PURE__ */ new Map();
|
|
2116
2117
|
for (const e of entries) {
|
|
2117
|
-
const
|
|
2118
|
+
const source = e.repository ?? "other";
|
|
2118
2119
|
const domain = e.domain ?? "other";
|
|
2119
|
-
if (!
|
|
2120
|
-
const domainMap =
|
|
2120
|
+
if (!bySource.has(source)) bySource.set(source, /* @__PURE__ */ new Map());
|
|
2121
|
+
const domainMap = bySource.get(source);
|
|
2121
2122
|
if (!domainMap.has(domain)) domainMap.set(domain, []);
|
|
2122
2123
|
domainMap.get(domain).push(e);
|
|
2123
2124
|
}
|
|
2124
2125
|
const rows = [];
|
|
2125
|
-
for (const [
|
|
2126
|
-
|
|
2126
|
+
for (const [source, domainMap] of [...bySource.entries()].sort(
|
|
2127
|
+
(a, b) => a[0].localeCompare(b[0])
|
|
2128
|
+
)) {
|
|
2129
|
+
rows.push({ type: "source-header", source });
|
|
2127
2130
|
for (const [domain, items] of [...domainMap.entries()].sort(
|
|
2128
2131
|
(a, b) => a[0].localeCompare(b[0])
|
|
2129
2132
|
)) {
|
|
2130
|
-
rows.push({ type: "header",
|
|
2133
|
+
rows.push({ type: "header", source, domain });
|
|
2131
2134
|
items.sort(
|
|
2132
2135
|
(a, b) => a.kind !== b.kind ? a.kind.localeCompare(b.kind) : a.name.localeCompare(b.name)
|
|
2133
2136
|
);
|
|
2134
2137
|
for (const entry of items) {
|
|
2135
2138
|
const ref = `${entry.kind}:${entry.name}`;
|
|
2136
|
-
rows.push({ type: "asset", entry,
|
|
2139
|
+
rows.push({ type: "asset", entry, installed: installed.has(ref) });
|
|
2137
2140
|
}
|
|
2138
2141
|
}
|
|
2139
2142
|
}
|
|
2140
2143
|
state.assetRows = rows;
|
|
2141
|
-
const
|
|
2142
|
-
for (const
|
|
2143
|
-
if (!
|
|
2144
|
+
const newSources = new Set(rows.filter((r) => r.type === "source-header").map((r) => r.source));
|
|
2145
|
+
for (const s of state.collapsedSources) {
|
|
2146
|
+
if (!newSources.has(s)) state.collapsedSources.delete(s);
|
|
2144
2147
|
}
|
|
2145
2148
|
const newDomainKeys = new Set(
|
|
2146
|
-
rows.filter((r) => r.type === "header").map((r) => `${r.
|
|
2149
|
+
rows.filter((r) => r.type === "header").map((r) => `${r.source}:${r.domain}`)
|
|
2147
2150
|
);
|
|
2148
2151
|
for (const d of state.collapsedDomains) {
|
|
2149
2152
|
if (!newDomainKeys.has(d)) state.collapsedDomains.delete(d);
|
|
@@ -2151,11 +2154,16 @@ function loadAssets() {
|
|
|
2151
2154
|
for (const d of newDomainKeys) state.collapsedDomains.add(d);
|
|
2152
2155
|
rebuildVisible();
|
|
2153
2156
|
}
|
|
2154
|
-
async function
|
|
2157
|
+
async function loadSourcesAndLibraries() {
|
|
2155
2158
|
try {
|
|
2156
|
-
const { openLibraryManager: openLibraryManager2 } = await
|
|
2159
|
+
const [{ openLibraryManager: openLibraryManager2 }, { skaileHomeDir: skaileHomeDir2 }] = await Promise.all([
|
|
2160
|
+
import('../open-library-T6RXQJTQ.js'),
|
|
2161
|
+
import('../library/index.js')
|
|
2162
|
+
]);
|
|
2157
2163
|
const { manager, library, close } = await openLibraryManager2();
|
|
2158
2164
|
try {
|
|
2165
|
+
const sourcesDir2 = path15__default.join(skaileHomeDir2(), "sources");
|
|
2166
|
+
const isSourceRow2 = (l) => l.path.startsWith(sourcesDir2);
|
|
2159
2167
|
const libs = await manager.listLibraries();
|
|
2160
2168
|
const defs = await library.listAssetDefs();
|
|
2161
2169
|
const counts = /* @__PURE__ */ new Map();
|
|
@@ -2163,7 +2171,13 @@ async function loadLibraries() {
|
|
|
2163
2171
|
const id = d.libraryId ?? "";
|
|
2164
2172
|
counts.set(id, (counts.get(id) ?? 0) + 1);
|
|
2165
2173
|
}
|
|
2166
|
-
state.
|
|
2174
|
+
state.sourceRows = libs.filter(isSourceRow2).map((l) => ({
|
|
2175
|
+
name: l.name,
|
|
2176
|
+
path: l.path,
|
|
2177
|
+
ownership: l.ownership,
|
|
2178
|
+
assetCount: counts.get(l.id) ?? 0
|
|
2179
|
+
}));
|
|
2180
|
+
state.libraryRows = libs.filter((l) => !isSourceRow2(l)).map((l) => ({
|
|
2167
2181
|
name: l.name,
|
|
2168
2182
|
backend: l.backend,
|
|
2169
2183
|
ownership: l.ownership,
|
|
@@ -2174,13 +2188,14 @@ async function loadLibraries() {
|
|
|
2174
2188
|
close();
|
|
2175
2189
|
}
|
|
2176
2190
|
} catch {
|
|
2191
|
+
state.sourceRows = [];
|
|
2177
2192
|
state.libraryRows = [];
|
|
2178
2193
|
}
|
|
2179
2194
|
}
|
|
2180
2195
|
function rebuildVisible() {
|
|
2181
2196
|
state.visibleRows = buildVisibleRows(
|
|
2182
2197
|
state.assetRows,
|
|
2183
|
-
state.
|
|
2198
|
+
state.collapsedSources,
|
|
2184
2199
|
state.collapsedDomains
|
|
2185
2200
|
);
|
|
2186
2201
|
clampCursor();
|
|
@@ -2195,19 +2210,11 @@ function moveCursor(delta) {
|
|
|
2195
2210
|
state.cursor = Math.max(0, Math.min(maxCursor(), state.cursor + delta));
|
|
2196
2211
|
}
|
|
2197
2212
|
function nextTab() {
|
|
2198
|
-
const order = ["
|
|
2213
|
+
const order = ["assets", "sources", "libraries", "pending", "sync"];
|
|
2199
2214
|
state.tab = order[(order.indexOf(state.tab) + 1) % order.length];
|
|
2200
2215
|
state.cursor = 0;
|
|
2201
2216
|
}
|
|
2202
2217
|
var TABS = {
|
|
2203
|
-
libraries: {
|
|
2204
|
-
label: "Libraries",
|
|
2205
|
-
rowCount: () => state.libraryRows.length,
|
|
2206
|
-
selectableCount: () => state.libraryRows.length,
|
|
2207
|
-
emptyMsg: " No libraries registered. Run `skaile library init <name>` or `skaile library add <git-url>` from the shell.",
|
|
2208
|
-
renderRow: (i, sel) => renderLibraryRow(state.libraryRows[i], sel),
|
|
2209
|
-
footer: " \u2191\u2193 navigate Tab switch q quit (use `skaile library \u2026` from the shell for CRUD)"
|
|
2210
|
-
},
|
|
2211
2218
|
assets: {
|
|
2212
2219
|
label: "Assets",
|
|
2213
2220
|
rowCount: () => state.visibleRows.length,
|
|
@@ -2215,6 +2222,22 @@ var TABS = {
|
|
|
2215
2222
|
renderRow: (i, sel) => renderAssetRow(state.visibleRows[i], sel),
|
|
2216
2223
|
footer: " \u2191\u2193/jk navigate \u2190/\u2192 collapse/expand [space/+/-] select [a/\u21B5] apply [i] info Tab switch [q/esc] quit"
|
|
2217
2224
|
},
|
|
2225
|
+
sources: {
|
|
2226
|
+
label: "Sources",
|
|
2227
|
+
rowCount: () => state.sourceRows.length,
|
|
2228
|
+
selectableCount: () => state.sourceRows.length,
|
|
2229
|
+
emptyMsg: " No sources registered. Run `skaile source add <git-url>` from the shell to track a github repo.",
|
|
2230
|
+
renderRow: (i, sel) => renderSourceRow(state.sourceRows[i], sel),
|
|
2231
|
+
footer: " \u2191\u2193 navigate Tab switch q quit (use `skaile source \u2026` from the shell for CRUD)"
|
|
2232
|
+
},
|
|
2233
|
+
libraries: {
|
|
2234
|
+
label: "Libraries",
|
|
2235
|
+
rowCount: () => state.libraryRows.length,
|
|
2236
|
+
selectableCount: () => state.libraryRows.length,
|
|
2237
|
+
emptyMsg: " No libraries registered. Run `skaile library init <name>` from the shell to author your own.",
|
|
2238
|
+
renderRow: (i, sel) => renderLibraryRow(state.libraryRows[i], sel),
|
|
2239
|
+
footer: " \u2191\u2193 navigate Tab switch q quit (use `skaile library \u2026` from the shell for CRUD)"
|
|
2240
|
+
},
|
|
2218
2241
|
pending: {
|
|
2219
2242
|
label: "Pending",
|
|
2220
2243
|
rowCount: () => 0,
|
|
@@ -2227,7 +2250,7 @@ var TABS = {
|
|
|
2227
2250
|
label: "Sync",
|
|
2228
2251
|
rowCount: () => 0,
|
|
2229
2252
|
selectableCount: () => 0,
|
|
2230
|
-
emptyMsg: " Press S to sync all libraries (rich rendering deferred to AF-LIB-TUI-RICH).",
|
|
2253
|
+
emptyMsg: " Press S to sync all sources + libraries (rich rendering deferred to AF-LIB-TUI-RICH).",
|
|
2231
2254
|
renderRow: () => "",
|
|
2232
2255
|
footer: " s sync all Tab switch q quit"
|
|
2233
2256
|
}
|
|
@@ -2264,13 +2287,13 @@ function groupStatus(refs) {
|
|
|
2264
2287
|
if (refs.length === 0) return pc5.dim("\xB7 ");
|
|
2265
2288
|
if (refs.some((r) => state.pendingAdds.has(r))) return pc5.blue("+ ");
|
|
2266
2289
|
if (refs.some((r) => state.pendingRemoves.has(r))) return pc5.red("- ");
|
|
2267
|
-
const
|
|
2268
|
-
return
|
|
2290
|
+
const allInstalled = refs.every((r) => findAssetRow(r)?.installed);
|
|
2291
|
+
return allInstalled ? pc5.green("\u2713 ") : pc5.dim("\xB7 ");
|
|
2269
2292
|
}
|
|
2270
2293
|
function renderHeaderLine(opts) {
|
|
2271
2294
|
const indicator = opts.collapsed ? "\u25B6" : "\u25BC";
|
|
2272
2295
|
const total = state.assetRows.filter(opts.match).length;
|
|
2273
|
-
const installed = state.assetRows.filter((r) => opts.match(r) && r.
|
|
2296
|
+
const installed = state.assetRows.filter((r) => opts.match(r) && r.installed).length;
|
|
2274
2297
|
const [add, remove] = pendingCountsFor(opts.match);
|
|
2275
2298
|
let count = String(installed);
|
|
2276
2299
|
if (add > 0) count += pc5.green(`+${add}`);
|
|
@@ -2281,22 +2304,22 @@ function renderHeaderLine(opts) {
|
|
|
2281
2304
|
return opts.selected ? pc5.bgWhite(pc5.black(`${line} `.padEnd(state.cols))) : line;
|
|
2282
2305
|
}
|
|
2283
2306
|
function renderAssetRow(row, selected) {
|
|
2284
|
-
if (row.type === "
|
|
2307
|
+
if (row.type === "source-header") {
|
|
2285
2308
|
return renderHeaderLine({
|
|
2286
2309
|
indent: " ",
|
|
2287
|
-
collapsed: state.
|
|
2288
|
-
match: (r) => isAsset(r) &&
|
|
2289
|
-
refs:
|
|
2290
|
-
label: pc5.bold(pc5.cyan(row.
|
|
2310
|
+
collapsed: state.collapsedSources.has(row.source),
|
|
2311
|
+
match: (r) => isAsset(r) && inSource(r, row.source),
|
|
2312
|
+
refs: sourceAssetRefs(state.assetRows, row.source),
|
|
2313
|
+
label: pc5.bold(pc5.cyan(row.source)),
|
|
2291
2314
|
selected
|
|
2292
2315
|
});
|
|
2293
2316
|
}
|
|
2294
2317
|
if (row.type === "header") {
|
|
2295
2318
|
return renderHeaderLine({
|
|
2296
2319
|
indent: " ",
|
|
2297
|
-
collapsed: state.collapsedDomains.has(`${row.
|
|
2298
|
-
match: (r) => isAsset(r) && inDomain(r, row.
|
|
2299
|
-
refs: domainAssetRefs(state.assetRows, row.
|
|
2320
|
+
collapsed: state.collapsedDomains.has(`${row.source}:${row.domain}`),
|
|
2321
|
+
match: (r) => isAsset(r) && inDomain(r, row.source, row.domain),
|
|
2322
|
+
refs: domainAssetRefs(state.assetRows, row.source, row.domain),
|
|
2300
2323
|
label: pc5.bold(row.domain),
|
|
2301
2324
|
selected
|
|
2302
2325
|
});
|
|
@@ -2306,7 +2329,7 @@ function renderAssetRow(row, selected) {
|
|
|
2306
2329
|
let status4;
|
|
2307
2330
|
if (state.pendingAdds.has(ref)) status4 = pc5.blue("+ ");
|
|
2308
2331
|
else if (state.pendingRemoves.has(ref)) status4 = pc5.red("- ");
|
|
2309
|
-
else if (row.
|
|
2332
|
+
else if (row.installed) status4 = pc5.green("\u2713 ");
|
|
2310
2333
|
else status4 = pc5.dim("\xB7 ");
|
|
2311
2334
|
const kind = kindColorPad(e.kind, 8);
|
|
2312
2335
|
const name = e.name.padEnd(30);
|
|
@@ -2314,6 +2337,10 @@ function renderAssetRow(row, selected) {
|
|
|
2314
2337
|
const line = ` ${status4} ${kind} ${name} ${pc5.dim(desc)}`;
|
|
2315
2338
|
return selected ? pc5.inverse(line.padEnd(state.cols)) : line;
|
|
2316
2339
|
}
|
|
2340
|
+
function renderSourceRow(row, selected) {
|
|
2341
|
+
const line = ` ${S.cmd(row.name.padEnd(20))} ${pc5.dim(row.ownership.padEnd(12))} ${pc5.dim(`${row.assetCount} assets`)} ${pc5.dim(row.path)}`;
|
|
2342
|
+
return selected ? pc5.inverse(line.padEnd(state.cols)) : line;
|
|
2343
|
+
}
|
|
2317
2344
|
function renderLibraryRow(row, selected) {
|
|
2318
2345
|
const mark = row.isDefault ? pc5.green("\u25B8") : " ";
|
|
2319
2346
|
const line = `${mark} ${S.cmd(row.name.padEnd(16))} ${pc5.dim(row.backend.padEnd(7))} ${pc5.dim(row.ownership.padEnd(12))} ${pc5.dim(`${row.assetCount} assets`)}`;
|
|
@@ -2396,14 +2423,19 @@ async function applyChanges() {
|
|
|
2396
2423
|
if (removed > 0) parts.push(pc5.red(`-${removed} removed`));
|
|
2397
2424
|
if (parts.length) state.message = parts.join(" ");
|
|
2398
2425
|
}
|
|
2399
|
-
async function
|
|
2426
|
+
async function syncAll() {
|
|
2427
|
+
state.message = pc5.yellow(
|
|
2428
|
+
"Sync is not yet driven from the manage TUI. Run `skaile source sync` (sources) or `skaile library sync <name>` (git-backed libraries) from the shell."
|
|
2429
|
+
);
|
|
2430
|
+
}
|
|
2431
|
+
function sourceShellHint(action) {
|
|
2400
2432
|
state.message = pc5.yellow(
|
|
2401
|
-
|
|
2433
|
+
`${action} is a shell command. Run \`skaile source \u2026\` from the shell.`
|
|
2402
2434
|
);
|
|
2403
2435
|
}
|
|
2404
|
-
function
|
|
2436
|
+
function libraryShellHint(action) {
|
|
2405
2437
|
state.message = pc5.yellow(
|
|
2406
|
-
`${action} is a shell command
|
|
2438
|
+
`${action} is a shell command. Run \`skaile library \u2026\` from the shell.`
|
|
2407
2439
|
);
|
|
2408
2440
|
}
|
|
2409
2441
|
async function showInfo() {
|
|
@@ -2417,9 +2449,9 @@ async function showInfo() {
|
|
|
2417
2449
|
console.log(` ${S.rule(50)}`);
|
|
2418
2450
|
if (e.version) console.log(` version: ${e.version}`);
|
|
2419
2451
|
if (e.description) console.log(` description: ${e.description}`);
|
|
2420
|
-
if (e.repository) console.log(`
|
|
2421
|
-
console.log(`
|
|
2422
|
-
console.log(`
|
|
2452
|
+
if (e.repository) console.log(` source: ${pc5.dim(e.repository)}`);
|
|
2453
|
+
console.log(` manifest: ${pc5.dim(e.source)}`);
|
|
2454
|
+
console.log(` installed: ${row.installed ? pc5.green("yes") : pc5.red("no")}`);
|
|
2423
2455
|
if (e.requires.length) {
|
|
2424
2456
|
console.log(` requires:`);
|
|
2425
2457
|
for (const d of e.requires) console.log(` ${kindColor(d.kind)}:${d.name}`);
|
|
@@ -2441,11 +2473,11 @@ async function showInfo() {
|
|
|
2441
2473
|
function expandUnderCursor() {
|
|
2442
2474
|
const row = state.visibleRows[state.cursor];
|
|
2443
2475
|
if (!row) return;
|
|
2444
|
-
if (row.type === "
|
|
2445
|
-
state.
|
|
2476
|
+
if (row.type === "source-header" && state.collapsedSources.has(row.source)) {
|
|
2477
|
+
state.collapsedSources.delete(row.source);
|
|
2446
2478
|
rebuildVisible();
|
|
2447
2479
|
} else if (row.type === "header") {
|
|
2448
|
-
const dk = `${row.
|
|
2480
|
+
const dk = `${row.source}:${row.domain}`;
|
|
2449
2481
|
if (state.collapsedDomains.has(dk)) {
|
|
2450
2482
|
state.collapsedDomains.delete(dk);
|
|
2451
2483
|
rebuildVisible();
|
|
@@ -2455,15 +2487,15 @@ function expandUnderCursor() {
|
|
|
2455
2487
|
function collapseOrJumpUnderCursor() {
|
|
2456
2488
|
const row = state.visibleRows[state.cursor];
|
|
2457
2489
|
if (!row) return;
|
|
2458
|
-
if (row.type === "
|
|
2459
|
-
if (!state.
|
|
2460
|
-
state.
|
|
2490
|
+
if (row.type === "source-header") {
|
|
2491
|
+
if (!state.collapsedSources.has(row.source)) {
|
|
2492
|
+
state.collapsedSources.add(row.source);
|
|
2461
2493
|
rebuildVisible();
|
|
2462
2494
|
}
|
|
2463
2495
|
return;
|
|
2464
2496
|
}
|
|
2465
2497
|
if (row.type === "header") {
|
|
2466
|
-
const dk = `${row.
|
|
2498
|
+
const dk = `${row.source}:${row.domain}`;
|
|
2467
2499
|
if (!state.collapsedDomains.has(dk)) {
|
|
2468
2500
|
state.collapsedDomains.add(dk);
|
|
2469
2501
|
rebuildVisible();
|
|
@@ -2471,7 +2503,7 @@ function collapseOrJumpUnderCursor() {
|
|
|
2471
2503
|
const idx2 = findLastIndex(
|
|
2472
2504
|
state.visibleRows,
|
|
2473
2505
|
state.cursor,
|
|
2474
|
-
(r) => r.type === "
|
|
2506
|
+
(r) => r.type === "source-header"
|
|
2475
2507
|
);
|
|
2476
2508
|
if (idx2 >= 0) state.cursor = idx2;
|
|
2477
2509
|
}
|
|
@@ -2480,7 +2512,7 @@ function collapseOrJumpUnderCursor() {
|
|
|
2480
2512
|
const idx = findLastIndex(
|
|
2481
2513
|
state.visibleRows,
|
|
2482
2514
|
state.cursor,
|
|
2483
|
-
(r) => r.type === "header" || r.type === "
|
|
2515
|
+
(r) => r.type === "header" || r.type === "source-header"
|
|
2484
2516
|
);
|
|
2485
2517
|
if (idx >= 0) state.cursor = idx;
|
|
2486
2518
|
}
|
|
@@ -2491,6 +2523,7 @@ function findLastIndex(arr, endExclusive, pred) {
|
|
|
2491
2523
|
return -1;
|
|
2492
2524
|
}
|
|
2493
2525
|
var TAB_ASSETS = (t) => t === "assets";
|
|
2526
|
+
var TAB_SOURCES = (t) => t === "sources";
|
|
2494
2527
|
var TAB_LIBRARIES = (t) => t === "libraries";
|
|
2495
2528
|
var KEYMAP = [
|
|
2496
2529
|
// Quit (with pending check) — handled here, not via a modal subroutine, so
|
|
@@ -2513,7 +2546,7 @@ var KEYMAP = [
|
|
|
2513
2546
|
// Collapse / expand — assets tab only
|
|
2514
2547
|
{ keys: ["\x1B[C"], when: TAB_ASSETS, run: expandUnderCursor },
|
|
2515
2548
|
{ keys: ["\x1B[D"], when: TAB_ASSETS, run: collapseOrJumpUnderCursor },
|
|
2516
|
-
// + : assets → bulk-add or single-add toggle
|
|
2549
|
+
// + : assets → bulk-add or single-add toggle
|
|
2517
2550
|
{
|
|
2518
2551
|
keys: ["+"],
|
|
2519
2552
|
when: TAB_ASSETS,
|
|
@@ -2526,9 +2559,28 @@ var KEYMAP = [
|
|
|
2526
2559
|
}
|
|
2527
2560
|
}
|
|
2528
2561
|
},
|
|
2529
|
-
//
|
|
2530
|
-
{ keys: ["+", "n"], when:
|
|
2531
|
-
|
|
2562
|
+
// Sources tab: +/-/n/r/x map to shell hints in the minimal scaffold.
|
|
2563
|
+
{ keys: ["+", "n", "a"], when: TAB_SOURCES, run: () => sourceShellHint("Adding a source") },
|
|
2564
|
+
{ keys: ["-", "r", "x"], when: TAB_SOURCES, run: () => sourceShellHint("Removing a source") },
|
|
2565
|
+
{ keys: ["\r", "\n"], when: TAB_SOURCES, run: () => sourceShellHint("Source actions") },
|
|
2566
|
+
// Libraries tab: +/-/n/r/x/d/enter map to shell hints in the minimal scaffold.
|
|
2567
|
+
{
|
|
2568
|
+
keys: ["+", "n", "a"],
|
|
2569
|
+
when: TAB_LIBRARIES,
|
|
2570
|
+
run: () => libraryShellHint("Adding a library")
|
|
2571
|
+
},
|
|
2572
|
+
{
|
|
2573
|
+
keys: ["-", "r", "x"],
|
|
2574
|
+
when: TAB_LIBRARIES,
|
|
2575
|
+
run: () => libraryShellHint("Removing a library")
|
|
2576
|
+
},
|
|
2577
|
+
{
|
|
2578
|
+
keys: ["d"],
|
|
2579
|
+
when: TAB_LIBRARIES,
|
|
2580
|
+
run: () => libraryShellHint("Setting the default library")
|
|
2581
|
+
},
|
|
2582
|
+
{ keys: ["\r", "\n"], when: TAB_LIBRARIES, run: () => libraryShellHint("Library actions") },
|
|
2583
|
+
// - : assets → bulk-remove or single-remove toggle
|
|
2532
2584
|
{
|
|
2533
2585
|
keys: ["-"],
|
|
2534
2586
|
when: TAB_ASSETS,
|
|
@@ -2541,8 +2593,6 @@ var KEYMAP = [
|
|
|
2541
2593
|
}
|
|
2542
2594
|
}
|
|
2543
2595
|
},
|
|
2544
|
-
{ keys: ["-", "r", "x"], when: TAB_LIBRARIES, run: () => shellHint("Removing a library") },
|
|
2545
|
-
{ keys: ["d"], when: TAB_LIBRARIES, run: () => shellHint("Setting the default library") },
|
|
2546
2596
|
// Space — auto-toggle (single asset or bulk header)
|
|
2547
2597
|
{
|
|
2548
2598
|
keys: [" "],
|
|
@@ -2556,14 +2606,12 @@ var KEYMAP = [
|
|
|
2556
2606
|
}
|
|
2557
2607
|
}
|
|
2558
2608
|
},
|
|
2559
|
-
// s — sync (any tab) — minimal scaffold delegates to shell.
|
|
2560
|
-
{ keys: ["s"], run:
|
|
2561
|
-
// a : assets → apply
|
|
2609
|
+
// s — sync all (any tab) — minimal scaffold delegates to shell.
|
|
2610
|
+
{ keys: ["s"], run: syncAll },
|
|
2611
|
+
// a : assets → apply
|
|
2562
2612
|
{ keys: ["a"], when: TAB_ASSETS, run: applyChanges },
|
|
2563
|
-
|
|
2564
|
-
// Enter — apply on assets tab; libraries → shell hint
|
|
2613
|
+
// Enter — apply on assets tab
|
|
2565
2614
|
{ keys: ["\r", "\n"], when: TAB_ASSETS, run: applyChanges },
|
|
2566
|
-
{ keys: ["\r", "\n"], when: TAB_LIBRARIES, run: () => shellHint("Library actions") },
|
|
2567
2615
|
// Info — assets only
|
|
2568
2616
|
{ keys: ["i"], when: TAB_ASSETS, run: showInfo }
|
|
2569
2617
|
];
|
|
@@ -2592,7 +2640,7 @@ async function handleExitConfirm(key) {
|
|
|
2592
2640
|
async function run(projectDir) {
|
|
2593
2641
|
am = new AssetManager({ projectDir });
|
|
2594
2642
|
loadAssets();
|
|
2595
|
-
await
|
|
2643
|
+
await loadSourcesAndLibraries();
|
|
2596
2644
|
hideCursor();
|
|
2597
2645
|
process.stdin.setRawMode(true);
|
|
2598
2646
|
process.stdin.resume();
|
|
@@ -2610,7 +2658,7 @@ async function run(projectDir) {
|
|
|
2610
2658
|
clearScreen();
|
|
2611
2659
|
}
|
|
2612
2660
|
function makeManageCommand() {
|
|
2613
|
-
return new Command("manage").description("Interactive TUI for managing
|
|
2661
|
+
return new Command("manage").description("Interactive TUI for managing assets, sources, and libraries").option("--project-dir <path>", "Project directory", process.cwd()).action(async (opts) => {
|
|
2614
2662
|
await run(path15__default.resolve(opts.projectDir));
|
|
2615
2663
|
});
|
|
2616
2664
|
}
|
|
@@ -3588,7 +3636,7 @@ function makeInstallCommand() {
|
|
|
3588
3636
|
const spinner6 = p5.spinner();
|
|
3589
3637
|
spinner6.start(`Installing ${ref}`);
|
|
3590
3638
|
try {
|
|
3591
|
-
const { openCatalogSource: openCatalogSource2, openLibrary: openLibrary2 } = await import('../open-library-
|
|
3639
|
+
const { openCatalogSource: openCatalogSource2, openLibrary: openLibrary2 } = await import('../open-library-T6RXQJTQ.js');
|
|
3592
3640
|
const catalog = await openCatalogSource2({ projectDir: path15__default.resolve(opts.projectDir) });
|
|
3593
3641
|
if (!supportsInstallManifest(catalog)) {
|
|
3594
3642
|
throw new Error(
|