@skaile/workspaces 0.50.0 → 0.53.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +232 -0
- package/dist/asset-feeds-OEGJ6NOF.js +205 -0
- package/dist/asset-feeds-OEGJ6NOF.js.map +1 -0
- package/dist/asset-manager/index.js +8 -8
- package/dist/asset-manager/installer.js +7 -7
- package/dist/asset-manager/src/index.d.ts +83 -7
- package/dist/asset-manager/src/index.d.ts.map +1 -1
- package/dist/asset-manager/src/installer.d.ts.map +1 -1
- package/dist/{chunk-P4BDTJMI.js → chunk-2D5YE3FL.js} +4 -4
- package/dist/{chunk-P4BDTJMI.js.map → chunk-2D5YE3FL.js.map} +1 -1
- package/dist/{chunk-4IGNQG6E.js → chunk-2ZK7M2SG.js} +3 -3
- package/dist/{chunk-4IGNQG6E.js.map → chunk-2ZK7M2SG.js.map} +1 -1
- package/dist/{chunk-SXT6BAQJ.js → chunk-3IHBGDCG.js} +2 -2
- package/dist/{chunk-SXT6BAQJ.js.map → chunk-3IHBGDCG.js.map} +1 -1
- package/dist/{chunk-SDAKQCOB.js → chunk-3KPNDTMR.js} +3 -3
- package/dist/{chunk-SDAKQCOB.js.map → chunk-3KPNDTMR.js.map} +1 -1
- package/dist/{chunk-2Y4HIITD.js → chunk-7ZWLZ5H3.js} +13 -9
- package/dist/chunk-7ZWLZ5H3.js.map +1 -0
- package/dist/{chunk-6IDBWPK2.js → chunk-BQCGFPHW.js} +4 -3
- package/dist/chunk-BQCGFPHW.js.map +1 -0
- package/dist/chunk-BXC5547R.js +377 -0
- package/dist/chunk-BXC5547R.js.map +1 -0
- package/dist/{chunk-3A3OACI2.js → chunk-EOINYN5T.js} +2 -2
- package/dist/{chunk-3A3OACI2.js.map → chunk-EOINYN5T.js.map} +1 -1
- package/dist/{chunk-XGCXFX7X.js → chunk-F3HNW354.js} +3 -3
- package/dist/{chunk-XGCXFX7X.js.map → chunk-F3HNW354.js.map} +1 -1
- package/dist/{chunk-33WB7VFV.js → chunk-LKOMH3QC.js} +3 -3
- package/dist/{chunk-33WB7VFV.js.map → chunk-LKOMH3QC.js.map} +1 -1
- package/dist/{chunk-O4JH3KUE.js → chunk-MENCWIHW.js} +11 -3
- package/dist/chunk-MENCWIHW.js.map +1 -0
- package/dist/{chunk-PBO6SCT2.js → chunk-NXC6IEL4.js} +37 -14
- package/dist/chunk-NXC6IEL4.js.map +1 -0
- package/dist/{chunk-EBSIZYM6.js → chunk-QLLFCQU5.js} +12 -12
- package/dist/chunk-QLLFCQU5.js.map +1 -0
- package/dist/{chunk-X46FY45B.js → chunk-SKADPHAM.js} +12 -8
- package/dist/chunk-SKADPHAM.js.map +1 -0
- package/dist/{chunk-C5RYGUF4.js → chunk-TCNYSHPM.js} +157 -31
- package/dist/chunk-TCNYSHPM.js.map +1 -0
- package/dist/{chunk-JXHULIOA.js → chunk-UTHEIPEY.js} +387 -42
- package/dist/chunk-UTHEIPEY.js.map +1 -0
- package/dist/{chunk-LV73DB4G.js → chunk-V4BGVOJC.js} +26 -22
- package/dist/chunk-V4BGVOJC.js.map +1 -0
- package/dist/{chunk-ZJ3VRPOI.js → chunk-VE2UIJ7Y.js} +11 -15
- package/dist/chunk-VE2UIJ7Y.js.map +1 -0
- package/dist/{chunk-H74X4TSR.js → chunk-VGT2R662.js} +6 -6
- package/dist/{chunk-H74X4TSR.js.map → chunk-VGT2R662.js.map} +1 -1
- package/dist/{chunk-WBF7JLTY.js → chunk-W53D5Q52.js} +4 -4
- package/dist/{chunk-WBF7JLTY.js.map → chunk-W53D5Q52.js.map} +1 -1
- package/dist/{chunk-HNORRENR.js → chunk-WD2NRI3T.js} +5 -5
- package/dist/{chunk-HNORRENR.js.map → chunk-WD2NRI3T.js.map} +1 -1
- package/dist/cli/index.js +679 -477
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/src/asset-feeds.d.ts +17 -3
- package/dist/cli/src/asset-feeds.d.ts.map +1 -1
- package/dist/cli/src/commands/catalog.d.ts +3 -2
- package/dist/cli/src/commands/catalog.d.ts.map +1 -1
- package/dist/cli/src/commands/manage.d.ts +47 -8
- package/dist/cli/src/commands/manage.d.ts.map +1 -1
- package/dist/cli/src/commands/project.d.ts.map +1 -1
- package/dist/cli/src/commands/source.d.ts +32 -0
- package/dist/cli/src/commands/source.d.ts.map +1 -1
- package/dist/cli/src/commands/update.d.ts +7 -0
- package/dist/cli/src/commands/update.d.ts.map +1 -1
- package/dist/connectors/config.js +7 -7
- package/dist/connectors/index.js +9 -9
- package/dist/connectors/src/config.d.ts +5 -13
- package/dist/connectors/src/config.d.ts.map +1 -1
- package/dist/connectors/src/index.d.ts +1 -1
- package/dist/connectors/src/index.d.ts.map +1 -1
- package/dist/core/driver-targets.js +1 -1
- package/dist/core/index.js +6 -6
- package/dist/core/manifest.js +1 -1
- package/dist/core/runtime-assets.js +4 -3
- package/dist/core/src/cache-paths.d.ts +6 -0
- package/dist/core/src/cache-paths.d.ts.map +1 -1
- package/dist/core/src/driver-targets.d.ts +12 -7
- package/dist/core/src/driver-targets.d.ts.map +1 -1
- package/dist/core/src/index.d.ts +3 -3
- package/dist/core/src/index.d.ts.map +1 -1
- package/dist/core/src/manifest.d.ts +6 -6
- package/dist/core/src/manifest.d.ts.map +1 -1
- package/dist/core/src/workspace-config.d.ts +36 -0
- package/dist/core/src/workspace-config.d.ts.map +1 -1
- package/dist/core/store.js +2 -2
- package/dist/core/workspace-config.js +3 -2
- package/dist/deploy/index.js +6 -6
- package/dist/discovery/index.js +2 -2
- package/dist/discovery/src/atomization-conventions.d.ts +30 -0
- package/dist/discovery/src/atomization-conventions.d.ts.map +1 -0
- package/dist/discovery/src/builtin-providers.d.ts.map +1 -1
- package/dist/discovery/src/discover-manifest.d.ts.map +1 -1
- package/dist/discovery/src/discover.d.ts +38 -0
- package/dist/discovery/src/discover.d.ts.map +1 -1
- package/dist/discovery/src/index.d.ts +5 -2
- package/dist/discovery/src/index.d.ts.map +1 -1
- package/dist/discovery/src/reference-lint.d.ts +112 -0
- package/dist/discovery/src/reference-lint.d.ts.map +1 -0
- package/dist/discovery/src/requires-graph.d.ts +1 -1
- package/dist/discovery/src/tree-entries.d.ts +9 -1
- package/dist/discovery/src/tree-entries.d.ts.map +1 -1
- package/dist/{ensure-sources-EE7Z2HKS.js → ensure-sources-GJOXWVWO.js} +8 -8
- package/dist/{ensure-sources-EE7Z2HKS.js.map → ensure-sources-GJOXWVWO.js.map} +1 -1
- package/dist/factory-assets/connectors/deploy.js +9 -9
- package/dist/factory-assets/connectors/devserver.js +9 -9
- package/dist/factory-assets/connectors/flow/adapter.js +9 -9
- package/dist/factory-assets/connectors/flow/engine/flow-kind-provider.d.ts +1 -1
- package/dist/factory-assets/connectors/flow/engine/flow-kind-provider.d.ts.map +1 -1
- package/dist/factory-assets/connectors/flow/engine.js +7 -7
- package/dist/factory-assets/connectors/flow/run-flow.js +10 -10
- package/dist/factory-assets/connectors/flow.js +9 -9
- package/dist/factory-assets/connectors/git.js +9 -9
- package/dist/factory-assets/connectors/gmail/adapter.d.ts.map +1 -1
- package/dist/factory-assets/connectors/gmail.js +9 -9
- package/dist/factory-assets/connectors/googledrive.js +9 -9
- package/dist/factory-assets/connectors/local.js +9 -9
- package/dist/factory-assets/connectors/mattermost/adapter.d.ts.map +1 -1
- package/dist/factory-assets/connectors/mattermost.js +9 -9
- package/dist/factory-assets/connectors/memory.js +9 -9
- package/dist/factory-assets/connectors/minio/adapter.d.ts.map +1 -1
- package/dist/factory-assets/connectors/minio.js +9 -9
- package/dist/factory-assets/connectors/postgres/adapter.d.ts.map +1 -1
- package/dist/factory-assets/connectors/postgres.js +9 -9
- package/dist/factory-assets/connectors/s3/driver.d.ts.map +1 -1
- package/dist/factory-assets/connectors/s3.js +9 -9
- package/dist/factory-assets/connectors/sharepoint.js +9 -9
- package/dist/factory-assets/connectors/sqlite/adapter.d.ts.map +1 -1
- package/dist/factory-assets/connectors/sqlite.js +9 -9
- package/dist/factory-assets/connectors/static-server.js +9 -9
- package/dist/factory-assets/connectors/tunnel.js +9 -9
- package/dist/factory-assets/connectors/webdav.js +9 -9
- package/dist/factory-assets/connectors/xstate-store.js +9 -9
- package/dist/factory-assets/connectors/xstate.js +9 -9
- package/dist/{flows-AAHXXXCH.js → flows-AGPIE6JM.js} +3 -3
- package/dist/{flows-AAHXXXCH.js.map → flows-AGPIE6JM.js.map} +1 -1
- package/dist/library/index.js +8 -8
- package/dist/library/install.js +6 -6
- package/dist/open-library-ERKRGH4B.js +23 -0
- package/dist/{open-library-TXJMFG34.js.map → open-library-ERKRGH4B.js.map} +1 -1
- package/dist/paths-D6RUQ522.js +15 -0
- package/dist/{paths-OMVC4UWY.js.map → paths-D6RUQ522.js.map} +1 -1
- package/dist/{plugin-store-JWJHIPUT.js → plugin-store-SGNJTBYS.js} +8 -8
- package/dist/{plugin-store-JWJHIPUT.js.map → plugin-store-SGNJTBYS.js.map} +1 -1
- package/dist/runner/index.js +11 -11
- package/dist/runner/src/serve.d.ts +6 -4
- package/dist/runner/src/serve.d.ts.map +1 -1
- package/dist/sdk/asset-manager.js +8 -8
- package/dist/sdk/core.js +6 -6
- package/dist/sdk/flow.js +7 -7
- package/dist/sdk/index.js +17 -11
- package/dist/sdk/index.js.map +1 -1
- package/dist/sdk/runner.js +11 -11
- package/dist/sdk/src/transport.d.ts +2 -0
- package/dist/sdk/src/transport.d.ts.map +1 -1
- package/dist/{setup-ETNBVZQA.js → setup-IV2JFW3T.js} +8 -8
- package/dist/{setup-ETNBVZQA.js.map → setup-IV2JFW3T.js.map} +1 -1
- package/dist/source-FGOMQMZT.js +24 -0
- package/dist/source-FGOMQMZT.js.map +1 -0
- package/dist/store-client-GJT2XQ5Z.js +15 -0
- package/dist/{store-client-SLFAAKSV.js.map → store-client-GJT2XQ5Z.js.map} +1 -1
- package/dist/tui/index.js +11 -11
- package/dist/types/src/transport.d.ts +12 -0
- package/dist/types/src/transport.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/asset-feeds-O6R6J4RI.js +0 -128
- package/dist/asset-feeds-O6R6J4RI.js.map +0 -1
- package/dist/chunk-2Y4HIITD.js.map +0 -1
- package/dist/chunk-6IDBWPK2.js.map +0 -1
- package/dist/chunk-C5RYGUF4.js.map +0 -1
- package/dist/chunk-EBSIZYM6.js.map +0 -1
- package/dist/chunk-JXHULIOA.js.map +0 -1
- package/dist/chunk-LV73DB4G.js.map +0 -1
- package/dist/chunk-O4JH3KUE.js.map +0 -1
- package/dist/chunk-PBO6SCT2.js.map +0 -1
- package/dist/chunk-X46FY45B.js.map +0 -1
- package/dist/chunk-ZJ3VRPOI.js.map +0 -1
- package/dist/open-library-TXJMFG34.js +0 -23
- package/dist/paths-OMVC4UWY.js +0 -15
- package/dist/store-client-SLFAAKSV.js +0 -15
|
@@ -172,9 +172,10 @@ function fromBundleYaml(filePath, repoName) {
|
|
|
172
172
|
};
|
|
173
173
|
}
|
|
174
174
|
function bundleDepRefs(filePath) {
|
|
175
|
+
const wholeDoc = /\.(bundle\.yaml|flow\.yaml|flow\.json)$/.test(filePath);
|
|
175
176
|
let meta = {};
|
|
176
177
|
try {
|
|
177
|
-
meta =
|
|
178
|
+
meta = wholeDoc ? parse(readFileSync(filePath, "utf8")) ?? {} : parseFrontmatter(readFileSync(filePath, "utf8")).data;
|
|
178
179
|
} catch {
|
|
179
180
|
return [];
|
|
180
181
|
}
|
|
@@ -340,5 +341,5 @@ function scanDirectory(root, repoName) {
|
|
|
340
341
|
}
|
|
341
342
|
|
|
342
343
|
export { bundleDepRefs, fromAgentMd, fromAgentYaml, fromBundleYaml, fromConnectorMd, fromContractMd, fromFlowYaml, fromKnowledgeYaml, fromMcpServerMd, fromMcpServerMdContent, fromPromptMd, fromSkillMd, parseFrontmatter, parseRequires, scanDirectory, walkDir };
|
|
343
|
-
//# sourceMappingURL=chunk-
|
|
344
|
-
//# sourceMappingURL=chunk-
|
|
344
|
+
//# sourceMappingURL=chunk-BQCGFPHW.js.map
|
|
345
|
+
//# sourceMappingURL=chunk-BQCGFPHW.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../core/src/manifest.ts"],"names":[],"mappings":"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","file":"chunk-BQCGFPHW.js","sourcesContent":["/**\n * Manifest parsing — reads SKILL.md, AGENT.md, agent.yaml, CONTRACT.md,\n * CONNECTOR.md, *.prompt.md, *.flow.yaml, *.bundle.yaml files and\n * produces CatalogEntry objects.\n * Used by @skaile/asset-manager for on-demand repo scanning.\n */\n\nimport { readdirSync, readFileSync, statSync } from \"node:fs\";\nimport { basename, dirname, join } from \"node:path\";\nimport { parse } from \"yaml\";\nimport type { AssetKind, CatalogEntry, Dependency } from \"./models.js\";\nimport { isValidAssetName, parseDep, slugifyAssetName } from \"./models.js\";\n\n// ── Frontmatter helpers ───────────────────────────────────────────────────────\n\n/**\n * Result of parsing YAML frontmatter from a markdown file.\n * @docLink packages/core/concepts#frontmatter-result\n */\nexport interface FrontmatterResult {\n /** Parsed YAML data. Empty object if no frontmatter block is present. */\n data: Record<string, unknown>;\n /** Markdown body below the frontmatter block (trimmed). */\n body: string;\n}\n\n/**\n * Parse YAML frontmatter from a markdown file (`---` delimited).\n * Returns `{ data: {}, body: text }` when no frontmatter block is present.\n *\n * @param text - Raw file contents\n * @returns Parsed frontmatter data and the remaining body text\n * @docLink packages/core/concepts#parse-frontmatter\n */\nexport function parseFrontmatter(text: string): FrontmatterResult {\n const m = text.match(/^---\\s*\\n([\\s\\S]*?)\\n---/);\n if (!m) return { data: {}, body: text.trim() };\n try {\n const data = (parse(m[1]!) as Record<string, unknown>) ?? {};\n const body = text.slice(m[0].length).trim();\n return { data, body };\n } catch {\n return { data: {}, body: text.trim() };\n }\n}\n\n/** Extract version from frontmatter, checking both top-level and metadata.version. */\nfunction extractVersion(meta: Record<string, unknown>): string {\n return String(\n meta.version ?? (meta.metadata as Record<string, unknown> | undefined)?.version ?? \"\",\n );\n}\n\n/**\n * Parse the `requires:` field from manifest frontmatter into typed `Dependency` objects.\n * Accepts a comma-separated string or an array of `\"kind:name\"` strings. Reads from either\n * the root or `metadata.requires` (matching `extractVersion`'s dual-location behavior) so\n * skill authors can follow the agentskills.io convention of placing skaile extensions under\n * `metadata:` while remaining backward-compatible with root-level declarations.\n *\n * @param meta - Parsed frontmatter data object\n * @returns Array of `Dependency` objects (empty when `requires` is absent)\n * @docLink packages/core/concepts#parse-requires\n */\nexport function parseRequires(meta: Record<string, unknown>): Dependency[] {\n const raw = meta.requires ?? (meta.metadata as Record<string, unknown> | undefined)?.requires;\n if (!raw) return [];\n const list =\n typeof raw === \"string\"\n ? raw.split(\",\").map((s) => s.trim())\n : Array.isArray(raw)\n ? (raw as string[])\n : [];\n return list.filter(Boolean).map(parseDep);\n}\n\n// ── agent.yaml dependency collectors ───────────────────────────────────────────\n\n/**\n * Collect named sub-agent dependencies from an `agent.yaml` array field.\n * Each `{name, ...}` object entry becomes an `{kind: \"agent\", name}` dependency.\n * Covers both the new `requires[]` and legacy `dependencies[]` formats.\n */\nfunction collectAgentDeps(raw: unknown, out: Dependency[]): void {\n if (!Array.isArray(raw)) return;\n for (const d of raw) {\n if (typeof d === \"object\" && d !== null && \"name\" in d) {\n out.push({ kind: \"agent\", name: String((d as Record<string, unknown>).name) });\n }\n }\n}\n\n/**\n * Collect string refs from an `agent.yaml` array field (`abilities[]`,\n * `contracts[]`) as `{kind, name}` dependencies, skipping empty entries.\n */\nfunction collectStringRefs(raw: unknown, kind: Dependency[\"kind\"], out: Dependency[]): void {\n if (!Array.isArray(raw)) return;\n for (const r of raw) {\n if (typeof r === \"string\" && r) out.push({ kind, name: r });\n }\n}\n\n/**\n * Collect catalog refs from an `agent.yaml` mixin field (`persona`, `rules`,\n * `knowledge`) as requires so `skaile install` pulls them automatically. Local\n * paths (`.`/`/`) are skipped — not catalog assets. Refs without a `kind:`\n * prefix get `defaultKind` injected; the publisher scope and `#pin` are stripped\n * so only `kind:name` is tracked.\n */\nfunction collectMixinRefs(raw: unknown, defaultKind: string, out: Dependency[]): void {\n if (!Array.isArray(raw)) return;\n for (const r of raw) {\n if (typeof r !== \"string\" || !r) continue;\n if (r.startsWith(\".\") || r.startsWith(\"/\")) continue; // local path — skip\n // Normalize: if no kind: prefix, inject the default kind\n const normalized = r.includes(\":\") ? r : `${defaultKind}:${r}`;\n // Only kind:name matters for requires — strip the publisher scope and #pin.\n const colonIdx = normalized.indexOf(\":\");\n const kind = normalized.slice(0, colonIdx).trim();\n let rest = normalized.slice(colonIdx + 1).trim();\n const hashIdx = rest.indexOf(\"#\");\n if (hashIdx !== -1) rest = rest.slice(0, hashIdx).trim();\n let name: string;\n if (rest.startsWith(\"@\")) {\n // Scoped form @publisher/name → name is the segment after the slash.\n const slashIdx = rest.indexOf(\"/\");\n name = slashIdx !== -1 ? rest.slice(slashIdx + 1).trim() : \"\";\n } else {\n // Legacy name@publisher (deprecated) or a bare name.\n const atIdx = rest.indexOf(\"@\");\n name = atIdx !== -1 ? rest.slice(0, atIdx).trim() : rest;\n }\n if (name) out.push({ kind, name });\n }\n}\n\n// ── Manifest parsers ──────────────────────────────────────────────────────────\n\n/**\n * Parse a `SKILL.md` file into a `CatalogEntry`.\n * The `kind` field defaults to `\"skill\"` but can be overridden to `\"agent\"` or `\"prompt\"`\n * via the `type:` frontmatter key. Falls back to the parent directory name when `name:` is absent.\n *\n * @param filePath - Absolute path to the `SKILL.md` file\n * @param repoName - Repository name used as the `repository` field of the entry\n * @returns Populated `CatalogEntry` with kind, name, description, version, and requires\n * @docLink packages/core/concepts#from-skill-md\n */\nexport function fromSkillMd(filePath: string, repoName: string): CatalogEntry {\n const { data: meta } = parseFrontmatter(readFileSync(filePath, \"utf8\"));\n let kind = String(meta.type ?? \"skill\") as AssetKind;\n if (![\"skill\", \"agent\", \"prompt\", \"persona\", \"ruleset\", \"knowledge\"].includes(kind))\n kind = \"skill\";\n return {\n name: String(meta.name ?? basename(dirname(filePath))),\n kind,\n description: String(meta.description ?? \"\"),\n source: filePath,\n publisher: repoName,\n version: extractVersion(meta),\n requires: parseRequires(meta),\n dependencies: [],\n };\n}\n\n/**\n * Parse an `AGENT.md` file into a `CatalogEntry` with `kind: \"agent\"`.\n * Falls back to the parent directory name when `name:` is absent.\n *\n * @param filePath - Absolute path to the `AGENT.md` file\n * @param repoName - Repository name used as the `repository` field of the entry\n * @returns Populated `CatalogEntry` with kind `\"agent\"`\n * @docLink packages/core/concepts#from-agent-md\n */\nexport function fromAgentMd(filePath: string, repoName: string): CatalogEntry {\n const { data: meta } = parseFrontmatter(readFileSync(filePath, \"utf8\"));\n return {\n name: String(meta.name ?? basename(dirname(filePath))),\n kind: \"agent\",\n description: String(meta.description ?? \"\"),\n source: filePath,\n publisher: repoName,\n version: extractVersion(meta),\n requires: parseRequires(meta),\n dependencies: [],\n };\n}\n\n/**\n * Parse an `agent.yaml` file into a `CatalogEntry` with `kind: \"agent\"`.\n * Collects sub-agent dependencies from `requires[]` (new format) and `dependencies[]`\n * (legacy format), skill abilities from `abilities[]`, and contracts from `contracts[]`.\n *\n * @param filePath - Absolute path to the `agent.yaml` file\n * @param repoName - Repository name used as the `repository` field of the entry\n * @returns Populated `CatalogEntry` with kind `\"agent\"` and full dependency graph\n * @docLink packages/core/concepts#from-agent-yaml\n */\nexport function fromAgentYaml(filePath: string, repoName: string): CatalogEntry {\n let meta: Record<string, unknown> = {};\n try {\n meta = (parse(readFileSync(filePath, \"utf8\")) as Record<string, unknown>) ?? {};\n } catch {}\n\n const requires: Dependency[] = [];\n\n // Sub-agent dependencies from requires[] (new format: {name, source, ...})\n collectAgentDeps(meta.requires, requires);\n // Legacy sub-agent dependencies from dependencies[] (old format: {name, ...})\n collectAgentDeps(meta.dependencies, requires);\n // Skill abilities referenced in the system prompt\n collectStringRefs(meta.abilities, \"skill\", requires);\n // Contracts referenced in the system prompt (co-located in skills dir)\n collectStringRefs(meta.contracts, \"contract\", requires);\n\n // Mixin composition fields — track catalog refs as requires so `skaile install`\n // automatically pulls them. Local paths (. or /) are skipped — not catalog assets.\n for (const [field, defaultKind] of [\n [\"persona\", \"persona\"],\n [\"rules\", \"ruleset\"],\n [\"knowledge\", \"knowledge\"],\n ] as const) {\n collectMixinRefs(meta[field], defaultKind, requires);\n }\n\n return {\n name: String(meta.name ?? basename(dirname(filePath))),\n kind: \"agent\",\n description: String(meta.description ?? \"\"),\n source: filePath,\n publisher: repoName,\n version: String(meta.version ?? \"\"),\n requires,\n dependencies: [],\n };\n}\n\n/**\n * Parse a `*.prompt.md` file into a `CatalogEntry` with `kind: \"prompt\"`.\n * The name defaults to the filename stem (without the `.prompt.md` suffix)\n * when no `name:` frontmatter key is present.\n *\n * @param filePath - Absolute path to the `.prompt.md` file\n * @param repoName - Repository name used as the `repository` field of the entry\n * @returns Populated `CatalogEntry` with kind `\"prompt\"`\n * @docLink packages/core/concepts#from-prompt-md\n */\nexport function fromPromptMd(filePath: string, repoName: string): CatalogEntry {\n const { data: meta } = parseFrontmatter(readFileSync(filePath, \"utf8\"));\n const name = String(meta.name ?? basename(filePath).replace(/\\.prompt\\.md$/, \"\"));\n return {\n name,\n kind: \"prompt\",\n description: String(meta.description ?? \"\"),\n source: filePath,\n publisher: repoName,\n version: extractVersion(meta),\n requires: parseRequires(meta),\n dependencies: [],\n };\n}\n\n/**\n * Parse a `*.flow.yaml` or `*.flow.json` file into a `CatalogEntry` with `kind: \"flow\"`.\n * The name resolves from `name:` or `id:` frontmatter, falling back to the filename stem.\n *\n * @param filePath - Absolute path to the flow definition file\n * @param repoName - Repository name used as the `repository` field of the entry\n * @returns Populated `CatalogEntry` with kind `\"flow\"`\n * @docLink packages/core/concepts#from-flow-yaml\n */\nexport function fromFlowYaml(filePath: string, repoName: string): CatalogEntry {\n let meta: Record<string, unknown> = {};\n try {\n meta = (parse(readFileSync(filePath, \"utf8\")) as Record<string, unknown>) ?? {};\n } catch {}\n\n const stem = basename(filePath)\n .replace(/\\.flow\\.yaml$/, \"\")\n .replace(/\\.flow\\.json$/, \"\");\n return {\n name: String(meta.name ?? meta.id ?? stem),\n kind: \"flow\",\n description: String(meta.description ?? \"\"),\n source: filePath,\n publisher: repoName,\n version: String(meta.version ?? \"\"),\n requires: parseRequires(meta),\n dependencies: [],\n };\n}\n\n/**\n * Parse a `*.bundle.yaml` file into a `CatalogEntry` with `kind: \"bundle\"`.\n * Bundles declare a flat list of string `dependencies` (asset refs) rather than\n * typed `Dependency` objects; both `requires` and `dependencies` are populated.\n *\n * @param filePath - Absolute path to the bundle YAML file\n * @param repoName - Repository name used as the `repository` field of the entry\n * @returns Populated `CatalogEntry` with kind `\"bundle\"`\n * @docLink packages/core/concepts#from-bundle-yaml\n */\nexport function fromBundleYaml(filePath: string, repoName: string): CatalogEntry {\n let meta: Record<string, unknown> = {};\n try {\n meta = (parse(readFileSync(filePath, \"utf8\")) as Record<string, unknown>) ?? {};\n } catch {}\n\n const name = String(meta.name ?? basename(filePath).replace(/\\.bundle\\.yaml$/, \"\"));\n\n const deps = meta.dependencies;\n const dependencies = Array.isArray(deps) ? (deps as string[]).filter(Boolean) : [];\n\n return {\n name,\n kind: \"bundle\",\n description: String(meta.description ?? \"\"),\n source: filePath,\n publisher: repoName,\n version: String(meta.version ?? \"\"),\n requires: parseRequires(meta),\n dependencies,\n };\n}\n\n/**\n * Extract a bundle's raw transitive dependency ref strings from its manifest\n * file — the union of its `requires` and `dependencies` lists, kept verbatim\n * (publisher/pin qualifiers preserved, comments dropped by the parser).\n *\n * Supports `*.bundle.yaml` / `*.flow.{yaml,json}` (top-level\n * `requires`/`dependencies`) and the `BUNDLE.md` frontmatter layout\n * (`requires`/`dependencies`, incl. nested under `metadata`). Unlike\n * {@link parseRequires}, refs are returned as-is — the resolver needs the full\n * `kind:name@<publisher>[#pin]` form, not a publisher-stripped {@link Dependency}.\n *\n * @param filePath - Absolute path to a `.bundle.yaml`, `.flow.{yaml,json}`, or `BUNDLE.md`.\n * @returns Deduped list of ref strings; `[]` on parse failure or no deps.\n * @docLink packages/core/concepts#bundle-dep-refs\n */\nexport function bundleDepRefs(filePath: string): string[] {\n // `.bundle.yaml` / `.flow.yaml` / `.flow.json` carry their dep list as a\n // top-level document key (`requires`/`dependencies`); `BUNDLE.md` carries it\n // in frontmatter. YAML is a JSON superset, so `parse` reads `.flow.json` too.\n const wholeDoc = /\\.(bundle\\.yaml|flow\\.yaml|flow\\.json)$/.test(filePath);\n let meta: Record<string, unknown> = {};\n try {\n meta = wholeDoc\n ? ((parse(readFileSync(filePath, \"utf8\")) as Record<string, unknown>) ?? {})\n : parseFrontmatter(readFileSync(filePath, \"utf8\")).data;\n } catch {\n return [];\n }\n const out: string[] = [];\n const collect = (v: unknown) => {\n if (Array.isArray(v))\n for (const x of v) if (typeof x === \"string\" && x.trim()) out.push(x.trim());\n };\n collect(meta.requires);\n collect((meta.metadata as Record<string, unknown> | undefined)?.requires);\n collect(meta.dependencies);\n return [...new Set(out)];\n}\n\n/**\n * Parse a `CONTRACT.md` file into a `CatalogEntry` with `kind: \"contract\"`.\n * Falls back to the parent directory name when `name:` is absent.\n *\n * @param filePath - Absolute path to the `CONTRACT.md` file\n * @param repoName - Repository name used as the `repository` field of the entry\n * @returns Populated `CatalogEntry` with kind `\"contract\"`\n * @docLink packages/core/concepts#from-contract-md\n */\nexport function fromContractMd(filePath: string, repoName: string): CatalogEntry {\n const { data: meta } = parseFrontmatter(readFileSync(filePath, \"utf8\"));\n return {\n name: String(meta.name ?? basename(dirname(filePath))),\n kind: \"contract\",\n description: String(meta.description ?? \"\"),\n source: filePath,\n publisher: repoName,\n version: extractVersion(meta),\n requires: parseRequires(meta),\n dependencies: [],\n };\n}\n\n/**\n * Parse an `MCP.md` file into a `CatalogEntry` with `kind: \"mcp-server\"`.\n * Falls back to the parent directory name when `name:` is absent.\n *\n * Frontmatter fields (catalog identity):\n * - `name` — server name (default: parent dir name)\n * - `description` — short description\n * - `version` — semver\n * - `keywords` — array of discovery tags\n *\n * Frontmatter fields (runtime defaults, stored in `metadata`):\n * - `transport` — \"stdio\" | \"sse\" | \"http\" (default: \"stdio\")\n * - `command` — command to execute (stdio)\n * - `args` — command arguments (stdio)\n * - `env` — environment variables (stdio)\n * - `url` — server URL (sse/http)\n * - `headers` — HTTP headers (sse/http)\n *\n * When `mcp:name` appears in `skaile.yaml` `dependencies`, the runner reads\n * these defaults from `metadata` to build a `McpServerDeclaration` without\n * requiring verbose inline config.\n *\n * @param filePath - Absolute path to the `MCP.md` file\n * @param repoName - Repository name used as the `repository` field of the entry\n * @returns Populated `CatalogEntry` with kind `\"mcp-server\"`\n * @docLink packages/core/concepts#from-mcp-server-md\n */\nexport function fromMcpServerMd(filePath: string, repoName: string): CatalogEntry {\n return fromMcpServerMdContent(readFileSync(filePath, \"utf8\"), repoName, filePath);\n}\n\n/**\n * Parse pre-read MCP.md content into a `CatalogEntry`.\n * Callers that already hold the file content (e.g. to avoid a second read) use\n * this directly; `fromMcpServerMd` is a thin wrapper that reads then delegates here.\n *\n * @param content - UTF-8 content of the `MCP.md` file\n * @param repoName - Repository name used as the `publisher` field of the entry\n * @param filePath - Absolute path (used as `source` and for name fallback)\n * @returns Populated `CatalogEntry` with kind `\"mcp-server\"`\n */\nexport function fromMcpServerMdContent(\n content: string,\n repoName: string,\n filePath: string,\n): CatalogEntry {\n const { data: meta } = parseFrontmatter(content);\n\n // Extract runtime defaults into metadata\n const metadata: Record<string, unknown> = {};\n if (meta.transport) metadata.transport = String(meta.transport);\n if (meta.command) metadata.command = String(meta.command);\n if (Array.isArray(meta.args)) metadata.args = meta.args.map(String);\n if (meta.env && typeof meta.env === \"object\" && !Array.isArray(meta.env)) {\n metadata.env = meta.env as Record<string, string>;\n }\n if (meta.url) metadata.url = String(meta.url);\n if (meta.headers && typeof meta.headers === \"object\" && !Array.isArray(meta.headers)) {\n metadata.headers = meta.headers as Record<string, string>;\n }\n if (meta.recipe && typeof meta.recipe === \"object\" && !Array.isArray(meta.recipe)) {\n metadata.recipe = meta.recipe;\n }\n\n return {\n name: String(meta.name ?? basename(dirname(filePath))),\n kind: \"mcp-server\",\n description: String(meta.description ?? \"\"),\n source: filePath,\n publisher: repoName,\n version: extractVersion(meta),\n requires: parseRequires(meta),\n dependencies: [],\n metadata: Object.keys(metadata).length > 0 ? metadata : undefined,\n };\n}\n\n/**\n * Parse a `knowledge.yaml` file into a `CatalogEntry` with `kind: \"knowledge\"`.\n * Falls back to the parent directory name when `name:` is absent.\n *\n * @param filePath - Absolute path to the `knowledge.yaml` file\n * @param repoName - Repository name used as the `repository` field of the entry\n * @returns Populated `CatalogEntry` with kind `\"knowledge\"`\n * @docLink packages/core/concepts#from-knowledge-yaml\n */\nexport function fromKnowledgeYaml(filePath: string, repoName: string): CatalogEntry {\n let meta: Record<string, unknown> = {};\n try {\n meta = (parse(readFileSync(filePath, \"utf8\")) as Record<string, unknown>) ?? {};\n } catch {}\n return {\n name: String(meta.name ?? basename(dirname(filePath))),\n kind: \"knowledge\",\n description: String(meta.description ?? \"\"),\n source: filePath,\n publisher: repoName,\n version: String(meta.version ?? \"\"),\n requires: parseRequires(meta),\n dependencies: [],\n };\n}\n\n/**\n * Parse a `CONNECTOR.md` file into a `CatalogEntry` with `kind: \"connector\"`.\n * Falls back to the parent directory name when `name:` is absent.\n *\n * Frontmatter fields (catalog identity):\n * - `name` — connector name (default: parent dir name)\n * - `description` — short description\n * - `version` — semver\n *\n * Frontmatter fields (runtime defaults, stored in `metadata`):\n * - `entry` — adapter entry point (default: \"./adapter.ts\")\n * - `npm_deps` — npm dependencies required by the adapter\n * - `fields` — configuration fields the adapter expects\n * - `health_check` — whether to run a health check on connect\n *\n * The markdown body (below the frontmatter) is stored in `metadata.body`\n * so the runner can inject the connector's skill description into the\n * system prompt when `expose_as_skill` is enabled.\n *\n * @param filePath - Absolute path to the `CONNECTOR.md` file\n * @param repoName - Repository name used as the `repository` field of the entry\n * @returns Populated `CatalogEntry` with kind `\"connector\"`\n * @docLink packages/core/concepts#from-connector-md\n */\nexport function fromConnectorMd(filePath: string, repoName: string): CatalogEntry {\n const text = readFileSync(filePath, \"utf-8\");\n const { data: meta, body } = parseFrontmatter(text);\n const name = String(meta.name ?? basename(dirname(filePath)));\n return {\n name,\n kind: \"connector\" as AssetKind,\n description: String(meta.description ?? \"\"),\n source: filePath,\n publisher: repoName,\n version: extractVersion(meta),\n requires: parseRequires(meta),\n dependencies: [],\n metadata: {\n entry: meta.entry ?? \"./adapter.ts\",\n npm_deps: meta.npm_deps ?? {},\n fields: meta.fields ?? [],\n health_check: meta.health_check ?? null,\n body,\n },\n };\n}\n\n// ── Recursive walker ──────────────────────────────────────────────────────────\n\ninterface WalkEntry {\n path: string;\n name: string;\n}\n\n/**\n * Recursively yield every file entry under `dir`, sorted alphabetically at each level.\n * Skips `.git` and `node_modules` directories and follows symlinks (resolving to\n * the stat target). `node_modules` is excluded because Bun's `node_modules/.bun/...`\n * layout contains symlink farms that form cycles when packages reference each other\n * transitively — entering them causes unbounded recursion in this walker.\n *\n * @param dir - Absolute path to the directory to walk\n * @docLink packages/core/concepts#walk-dir\n */\nexport function* walkDir(dir: string): Generator<WalkEntry> {\n let dirEntries: import(\"node:fs\").Dirent<string>[];\n try {\n dirEntries = readdirSync(dir, { withFileTypes: true, encoding: \"utf8\" });\n } catch {\n return;\n }\n for (const e of dirEntries.sort((a, b) => (a.name < b.name ? -1 : 1))) {\n const full = join(dir, e.name);\n if (e.isSymbolicLink()) {\n try {\n if (statSync(full).isDirectory()) yield* walkDir(full);\n else yield { path: full, name: e.name };\n } catch {}\n } else if (e.isDirectory()) {\n if (e.name !== \".git\" && e.name !== \"node_modules\") yield* walkDir(full);\n } else if (e.isFile()) {\n yield { path: full, name: e.name };\n }\n }\n}\n\n// ── Public scanner ────────────────────────────────────────────────────────────\n\n/**\n * Walk `root` recursively and return a `CatalogEntry` for every recognized asset manifest found.\n *\n * Recognized filenames: `SKILL.md`, `AGENT.md`, `agent.yaml`, `CONTRACT.md`, `MCP.md`,\n * `CONNECTOR.md`, `*.prompt.md`, `*.bundle.yaml`, `*.flow.yaml`, `*.flow.json`.\n *\n * When two entries share the same `kind:name` key, the one with the alphabetically\n * later source path wins (consistent with catalog precedence rules).\n *\n * @param root - Absolute path to the directory tree to scan\n * @param repoName - Repository name attached to every produced entry\n * @returns Array of deduplicated `CatalogEntry` objects, one per manifest file\n * @docLink packages/core/concepts#scan-directory\n */\n/**\n * Coerce a scanned entry's `name` to a canonical asset name in place. When the\n * raw name is already canonical this is a no-op; otherwise the original is stashed\n * on `metadata.displayName` (only when not already set) so callers keep the pretty\n * label for display while identity uses the slug. A name that slugifies to empty\n * is left untouched — `parseAssetRef` will reject it downstream with its full hint.\n */\nfunction normalizeEntryName(e: CatalogEntry): void {\n if (isValidAssetName(e.name)) return;\n let slug: string;\n try {\n slug = slugifyAssetName(e.name);\n } catch {\n return;\n }\n const original = e.name;\n e.name = slug;\n if (e.metadata?.displayName === undefined) {\n e.metadata = { ...e.metadata, displayName: original };\n }\n}\n\nexport function scanDirectory(root: string, repoName: string): CatalogEntry[] {\n const entries = new Map<string, CatalogEntry>();\n\n function add(e: CatalogEntry): void {\n // Boundary normalization: a third-party source we don't control may name an\n // asset with a human-styled identity (\"Complex App\"). Slugify it to a\n // canonical name so the ref it produces parses, preserving the original on\n // `metadata.displayName` for display. No-op for already-canonical names.\n normalizeEntryName(e);\n const key = `${e.kind}:${e.name}`;\n const existing = entries.get(key);\n if (!existing) {\n entries.set(key, e);\n return;\n }\n // Among duplicates, alphabetically later source path wins\n if (e.source > existing.source) entries.set(key, e);\n }\n\n for (const { path: filePath, name } of walkDir(root)) {\n try {\n if (name === \"SKILL.md\") add(fromSkillMd(filePath, repoName));\n else if (name === \"AGENT.md\") add(fromAgentMd(filePath, repoName));\n else if (name === \"agent.yaml\") add(fromAgentYaml(filePath, repoName));\n else if (name === \"CONTRACT.md\") add(fromContractMd(filePath, repoName));\n else if (name === \"MCP.md\") add(fromMcpServerMd(filePath, repoName));\n else if (name === \"CONNECTOR.md\") add(fromConnectorMd(filePath, repoName));\n else if (name === \"knowledge.yaml\") add(fromKnowledgeYaml(filePath, repoName));\n else if (name.endsWith(\".prompt.md\")) add(fromPromptMd(filePath, repoName));\n else if (name.endsWith(\".bundle.yaml\")) add(fromBundleYaml(filePath, repoName));\n else if (name.endsWith(\".flow.yaml\") || name.endsWith(\".flow.json\"))\n add(fromFlowYaml(filePath, repoName));\n } catch {}\n }\n\n return [...entries.values()];\n}\n"]}
|
|
@@ -0,0 +1,377 @@
|
|
|
1
|
+
import { openLibraryManager, createFullRegistry } from './chunk-WD2NRI3T.js';
|
|
2
|
+
import { logInfo, logWarn, logErr, logOk, S } from './chunk-GYPA2Q7F.js';
|
|
3
|
+
import { LocalCatalogSource } from './chunk-2D5YE3FL.js';
|
|
4
|
+
import { WorkspaceYamlEditor } from './chunk-3KPNDTMR.js';
|
|
5
|
+
import { getGlobalCacheDir, sourceCacheKey, sourceShortName, findWorkspaceRoot, workspaceConfigFilename } from './chunk-NXC6IEL4.js';
|
|
6
|
+
import { spawnSync } from 'child_process';
|
|
7
|
+
import { existsSync, mkdirSync, rmSync } from 'fs';
|
|
8
|
+
import * as path from 'path';
|
|
9
|
+
import * as p from '@clack/prompts';
|
|
10
|
+
import { Command } from 'commander';
|
|
11
|
+
|
|
12
|
+
// cli/src/commands/source-manifest.ts
|
|
13
|
+
var NOT_WIRED_MSG = "`skaile source manifest *` is scaffolded but not yet wired. Server-side endpoint (`POST /sources/<id>/manifest`) lands in a follow-up PR.";
|
|
14
|
+
function notWired(verb) {
|
|
15
|
+
logErr(`${NOT_WIRED_MSG} (verb: source manifest ${verb})`);
|
|
16
|
+
process.exit(2);
|
|
17
|
+
}
|
|
18
|
+
function addSourceManifestCommands(src) {
|
|
19
|
+
const manifest = src.command("manifest").description("Sidecar manifest lifecycle for a source");
|
|
20
|
+
manifest.command("init <src>").description("Start a sidecar manifest for a source").action(() => notWired("init"));
|
|
21
|
+
manifest.command("edit <src>").description("Open the sidecar manifest in $EDITOR").action(() => notWired("edit"));
|
|
22
|
+
manifest.command("rebuild <src>").description("Re-derive the manifest after an upstream change").option("--merge", "Merge with existing entries instead of overwriting", false).action(() => notWired("rebuild"));
|
|
23
|
+
manifest.command("verify <src>").description("Verify hashes, deps, and schema").option("--strict", "Fail on advisory checks", false).action(() => notWired("verify"));
|
|
24
|
+
manifest.command("publish <src>").description("Register the manifest in the store (provenance=curator)").action(() => notWired("publish"));
|
|
25
|
+
manifest.command("propose <src>").description("Open a PR to upstream with the sidecar manifest").action(() => notWired("propose"));
|
|
26
|
+
manifest.command("yank <src>").description("Retract a published manifest from the remote store").option("--version <v>", "Version to yank").action(() => notWired("yank"));
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// cli/src/commands/source.ts
|
|
30
|
+
function sourceClonePath(key) {
|
|
31
|
+
return path.join(getGlobalCacheDir(), key);
|
|
32
|
+
}
|
|
33
|
+
var SKAILE_MANIFEST_FILENAME = "skaile.manifest.yaml";
|
|
34
|
+
var LEGACY_SOURCE_CONFIG_FILENAME = ".skaile-source.yaml";
|
|
35
|
+
function indexingHadFailures(result) {
|
|
36
|
+
return result.errors.length > 0;
|
|
37
|
+
}
|
|
38
|
+
function legacySourceConfigHint(dest) {
|
|
39
|
+
const hasLegacy = existsSync(path.join(dest, LEGACY_SOURCE_CONFIG_FILENAME));
|
|
40
|
+
const hasManifest = existsSync(path.join(dest, SKAILE_MANIFEST_FILENAME));
|
|
41
|
+
if (hasLegacy && !hasManifest) {
|
|
42
|
+
return `This source ships a legacy ${LEGACY_SOURCE_CONFIG_FILENAME} but no ${SKAILE_MANIFEST_FILENAME}; its declared publisher is ignored and assets are published under their first path segment. Add a ${SKAILE_MANIFEST_FILENAME} (\`skaile source manifest init\`) to set the publisher and asset inventory.`;
|
|
43
|
+
}
|
|
44
|
+
return void 0;
|
|
45
|
+
}
|
|
46
|
+
function normalizeSourceUrl(input) {
|
|
47
|
+
const s = input.trim();
|
|
48
|
+
if (/^(?:https?|git|ssh|file):\/\//.test(s) || /^git@/.test(s)) return s;
|
|
49
|
+
const repo = s.replace(/\.git$/, "");
|
|
50
|
+
if (/^[\w.-]+\/[\w.-]+$/.test(repo)) return `git@github.com:${repo}.git`;
|
|
51
|
+
if (/^[\w.-]+$/.test(repo)) return `git@github.com:skaile-ai/${repo}.git`;
|
|
52
|
+
return s;
|
|
53
|
+
}
|
|
54
|
+
function sourceMatchesKey(entry, key) {
|
|
55
|
+
if (entry.url === key) return true;
|
|
56
|
+
if (sourceCacheKey(entry.url) === key || sourceShortName(entry.url) === key) return true;
|
|
57
|
+
return entry.url === normalizeSourceUrl(key);
|
|
58
|
+
}
|
|
59
|
+
function findCacheKeyCollision(sources, url) {
|
|
60
|
+
const key = sourceCacheKey(url);
|
|
61
|
+
return sources.find((s) => s.url !== url && sourceCacheKey(s.url) === key);
|
|
62
|
+
}
|
|
63
|
+
function requireProjectYamlPath() {
|
|
64
|
+
const root = findWorkspaceRoot(process.cwd());
|
|
65
|
+
if (!root) {
|
|
66
|
+
logErr(
|
|
67
|
+
"No skaile.yaml found in the current directory or any parent. Run `skaile init` first."
|
|
68
|
+
);
|
|
69
|
+
process.exit(1);
|
|
70
|
+
}
|
|
71
|
+
return path.join(root, workspaceConfigFilename());
|
|
72
|
+
}
|
|
73
|
+
function readProjectSources(yamlPath) {
|
|
74
|
+
if (!existsSync(yamlPath)) return [];
|
|
75
|
+
try {
|
|
76
|
+
return WorkspaceYamlEditor.load(yamlPath).getSources();
|
|
77
|
+
} catch (err) {
|
|
78
|
+
logErr(`Could not read ${yamlPath}: ${err instanceof Error ? err.message : String(err)}`);
|
|
79
|
+
process.exit(1);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
function ensureClone(entry, opts = {}) {
|
|
83
|
+
const dest = sourceClonePath(sourceCacheKey(entry.url));
|
|
84
|
+
if (existsSync(dest)) {
|
|
85
|
+
if (!opts.force) return false;
|
|
86
|
+
rmSync(dest, { recursive: true, force: true });
|
|
87
|
+
}
|
|
88
|
+
mkdirSync(path.dirname(dest), { recursive: true });
|
|
89
|
+
const args = ["clone", entry.url, dest];
|
|
90
|
+
if (entry.pin) args.splice(1, 0, "--branch", entry.pin);
|
|
91
|
+
const clone = spawnSync("git", args, { stdio: "inherit" });
|
|
92
|
+
if (clone.status !== 0) {
|
|
93
|
+
logErr(`git clone failed for ${entry.url}`);
|
|
94
|
+
process.exit(1);
|
|
95
|
+
}
|
|
96
|
+
return true;
|
|
97
|
+
}
|
|
98
|
+
async function refreshManifestCache(entry, includeDev = false) {
|
|
99
|
+
const { manager, library, close } = await openLibraryManager();
|
|
100
|
+
try {
|
|
101
|
+
const name = sourceShortName(entry.url);
|
|
102
|
+
const dest = sourceClonePath(sourceCacheKey(entry.url));
|
|
103
|
+
const existing = (await manager.listLibraries()).find((l) => l.name === name);
|
|
104
|
+
const lib = existing ?? await manager.addLibrary({
|
|
105
|
+
name,
|
|
106
|
+
path: dest,
|
|
107
|
+
backend: "git",
|
|
108
|
+
backendConfig: { url: entry.url, branch: entry.pin ?? "main", authHint: "ssh" },
|
|
109
|
+
ownership: "reader"
|
|
110
|
+
});
|
|
111
|
+
const catalog = new LocalCatalogSource(library, lib.id, dest, createFullRegistry());
|
|
112
|
+
const result = await catalog.sync({ includeDev });
|
|
113
|
+
await library.syncSource(lib.id);
|
|
114
|
+
return result;
|
|
115
|
+
} finally {
|
|
116
|
+
close();
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
async function autoSyncForSearch(projectDir) {
|
|
120
|
+
const root = findWorkspaceRoot(projectDir);
|
|
121
|
+
if (!root) return false;
|
|
122
|
+
if (readProjectSources(path.join(root, workspaceConfigFilename())).length === 0) return false;
|
|
123
|
+
logInfo("sources not synced \u2014 syncing now\u2026");
|
|
124
|
+
const { synced } = await syncProjectSources(projectDir);
|
|
125
|
+
return synced > 0;
|
|
126
|
+
}
|
|
127
|
+
async function syncProjectSources(projectDir, opts = {}) {
|
|
128
|
+
const root = findWorkspaceRoot(projectDir) ?? projectDir;
|
|
129
|
+
const sources = readProjectSources(path.join(root, workspaceConfigFilename()));
|
|
130
|
+
let synced = 0;
|
|
131
|
+
let failed = 0;
|
|
132
|
+
for (const entry of sources) {
|
|
133
|
+
const slug = sourceShortName(entry.url);
|
|
134
|
+
const dest = sourceClonePath(sourceCacheKey(entry.url));
|
|
135
|
+
try {
|
|
136
|
+
if (!existsSync(dest)) {
|
|
137
|
+
mkdirSync(path.dirname(dest), { recursive: true });
|
|
138
|
+
const args = ["clone", entry.url, dest];
|
|
139
|
+
if (entry.pin) args.splice(1, 0, "--branch", entry.pin);
|
|
140
|
+
const clone = spawnSync("git", args, { stdio: "ignore" });
|
|
141
|
+
if (clone.status !== 0) {
|
|
142
|
+
logWarn(`${slug}: git clone failed, skipping.`);
|
|
143
|
+
failed++;
|
|
144
|
+
continue;
|
|
145
|
+
}
|
|
146
|
+
} else {
|
|
147
|
+
const pull = spawnSync("git", ["pull", "--ff-only"], { cwd: dest, stdio: "ignore" });
|
|
148
|
+
if (pull.status !== 0) {
|
|
149
|
+
logWarn(`${slug}: git pull failed, skipping manifest refresh.`);
|
|
150
|
+
failed++;
|
|
151
|
+
continue;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
const result = await refreshManifestCache(entry, opts.dev);
|
|
155
|
+
for (const err of result.errors) logWarn(`${slug}: ${err}`);
|
|
156
|
+
synced++;
|
|
157
|
+
} catch (err) {
|
|
158
|
+
logWarn(`${slug}: sync failed \u2014 ${err instanceof Error ? err.message : String(err)}`);
|
|
159
|
+
failed++;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
return { total: sources.length, synced, failed };
|
|
163
|
+
}
|
|
164
|
+
async function dropManifestCache(url, purgeClone) {
|
|
165
|
+
const name = sourceShortName(url);
|
|
166
|
+
const { manager, close } = await openLibraryManager();
|
|
167
|
+
try {
|
|
168
|
+
const existing = (await manager.listLibraries()).find((l) => l.name === name);
|
|
169
|
+
if (existing) {
|
|
170
|
+
await manager.removeLibrary(name, { purge: false });
|
|
171
|
+
}
|
|
172
|
+
} finally {
|
|
173
|
+
close();
|
|
174
|
+
}
|
|
175
|
+
if (purgeClone) {
|
|
176
|
+
const dest = sourceClonePath(sourceCacheKey(url));
|
|
177
|
+
if (existsSync(dest)) rmSync(dest, { recursive: true, force: true });
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
function makeSourceCommand() {
|
|
181
|
+
const cmd = new Command("source").description(
|
|
182
|
+
"Manage github sources for the current project (recorded in skaile.yaml)"
|
|
183
|
+
);
|
|
184
|
+
cmd.command("add <source>").description(
|
|
185
|
+
"Clone a github repo and register it in this project's skaile.yaml. <source> may be a full git URL, an owner/repo shorthand, or a bare name (\u2192 git@github.com:skaile-ai/<name>.git)."
|
|
186
|
+
).option("--name <slug>", "[deprecated] no-op \u2014 the source entry stores only the URL").option("--pin <ref>", "Pin a branch, tag, or 40-char SHA").option("--branch <branch>", "[deprecated] alias for --pin").option("--force", "Remove an existing clone and re-clone", false).option("--dev", "Also index dev-only assets under the source's dev_paths", false).action(
|
|
187
|
+
async (source, opts) => {
|
|
188
|
+
const url = normalizeSourceUrl(source);
|
|
189
|
+
const yamlPath = requireProjectYamlPath();
|
|
190
|
+
const collision = findCacheKeyCollision(readProjectSources(yamlPath), url);
|
|
191
|
+
if (collision) {
|
|
192
|
+
logErr(
|
|
193
|
+
`"${url}" maps to the same cache key (${sourceCacheKey(url)}) as already-registered "${collision.url}". Remove that source first (skaile source remove) or re-use its exact URL to update it.`
|
|
194
|
+
);
|
|
195
|
+
process.exitCode = 1;
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
if (opts.name) {
|
|
199
|
+
logWarn(
|
|
200
|
+
"the --name flag is deprecated; the source entry now stores only the URL (the cache slug is derived from it)."
|
|
201
|
+
);
|
|
202
|
+
}
|
|
203
|
+
const pin = opts.pin ?? opts.branch;
|
|
204
|
+
const slug = sourceShortName(url);
|
|
205
|
+
const entry = { url };
|
|
206
|
+
if (pin) entry.pin = pin;
|
|
207
|
+
const editor = WorkspaceYamlEditor.load(yamlPath);
|
|
208
|
+
editor.setSource(entry);
|
|
209
|
+
editor.save();
|
|
210
|
+
const dest = sourceClonePath(sourceCacheKey(url));
|
|
211
|
+
const preexisting = existsSync(dest);
|
|
212
|
+
const cloned = ensureClone(entry, { force: opts.force });
|
|
213
|
+
if (!cloned) {
|
|
214
|
+
logOk(`Reusing cached clone at ${dest}`);
|
|
215
|
+
} else if (preexisting) {
|
|
216
|
+
logOk(`Re-cloned ${url} \u2192 ${dest}`);
|
|
217
|
+
} else {
|
|
218
|
+
logOk(`Cloned ${url} \u2192 ${dest}`);
|
|
219
|
+
}
|
|
220
|
+
const result = await refreshManifestCache(entry, opts.dev);
|
|
221
|
+
const failed = indexingHadFailures(result);
|
|
222
|
+
const indexedMsg = `Indexed ${result.assetsUpdated} of ${result.assetsFound} asset(s) from "${slug}".`;
|
|
223
|
+
if (failed) {
|
|
224
|
+
logWarn(indexedMsg);
|
|
225
|
+
} else {
|
|
226
|
+
logOk(indexedMsg);
|
|
227
|
+
}
|
|
228
|
+
for (const err of result.errors) logWarn(err);
|
|
229
|
+
const legacyHint = legacySourceConfigHint(dest);
|
|
230
|
+
if (legacyHint) logWarn(legacyHint);
|
|
231
|
+
const where = path.relative(process.cwd(), yamlPath);
|
|
232
|
+
if (failed) {
|
|
233
|
+
logWarn(
|
|
234
|
+
`Source "${slug}" registered in ${where}, but ${result.errors.length} asset(s) failed to index (see above). Fix the cause, then re-run \`skaile source sync ${slug}\`.`
|
|
235
|
+
);
|
|
236
|
+
process.exitCode = 1;
|
|
237
|
+
} else {
|
|
238
|
+
logOk(`Source "${slug}" registered in ${where}.`);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
);
|
|
242
|
+
cmd.command("list").description("List sources registered in this project's skaile.yaml").option("--json", "Output as JSON").action(async (opts) => {
|
|
243
|
+
const yamlPath = requireProjectYamlPath();
|
|
244
|
+
const sources = readProjectSources(yamlPath);
|
|
245
|
+
if (opts.json) return console.log(JSON.stringify(sources, null, 2));
|
|
246
|
+
if (sources.length === 0) {
|
|
247
|
+
logInfo("No sources in skaile.yaml. Run `skaile source add <git-url>` to register one.");
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
console.log();
|
|
251
|
+
console.log(S.heading(" Sources"));
|
|
252
|
+
for (const s of sources) {
|
|
253
|
+
const slug = sourceShortName(s.url);
|
|
254
|
+
const cached = existsSync(sourceClonePath(sourceCacheKey(s.url))) ? "" : S.warn(" (not cached)");
|
|
255
|
+
console.log(` ${S.cmd(slug.padEnd(24))} ${S.dim(s.url)}${cached}`);
|
|
256
|
+
}
|
|
257
|
+
console.log(`
|
|
258
|
+
${S.dim(`${sources.length} source(s)`)}
|
|
259
|
+
`);
|
|
260
|
+
});
|
|
261
|
+
cmd.command("show <name-or-url>").description("Show details for a source (matched by URL or derived slug)").action(async (key) => {
|
|
262
|
+
const yamlPath = requireProjectYamlPath();
|
|
263
|
+
const entry = readProjectSources(yamlPath).find((s) => sourceMatchesKey(s, key));
|
|
264
|
+
if (!entry) {
|
|
265
|
+
logErr(`No source matching "${key}" in ${yamlPath}.`);
|
|
266
|
+
process.exit(1);
|
|
267
|
+
}
|
|
268
|
+
const slug = sourceShortName(entry.url);
|
|
269
|
+
const clonePath = sourceClonePath(sourceCacheKey(entry.url));
|
|
270
|
+
console.log(
|
|
271
|
+
JSON.stringify(
|
|
272
|
+
{
|
|
273
|
+
...entry,
|
|
274
|
+
slug,
|
|
275
|
+
clonePath,
|
|
276
|
+
cached: existsSync(clonePath)
|
|
277
|
+
},
|
|
278
|
+
null,
|
|
279
|
+
2
|
|
280
|
+
)
|
|
281
|
+
);
|
|
282
|
+
});
|
|
283
|
+
cmd.command("remove <name-or-url>").description("Remove a source from this project's skaile.yaml (matched by URL or slug)").option("--purge", "Also delete the cached clone from ~/.skaile/cache/sources/", false).action(async (key, opts) => {
|
|
284
|
+
const yamlPath = requireProjectYamlPath();
|
|
285
|
+
const editor = WorkspaceYamlEditor.load(yamlPath);
|
|
286
|
+
const match = editor.getSources().find((s) => sourceMatchesKey(s, key));
|
|
287
|
+
if (!match) {
|
|
288
|
+
logErr(`No source matching "${key}" in ${yamlPath}.`);
|
|
289
|
+
process.exit(1);
|
|
290
|
+
}
|
|
291
|
+
const slug = sourceShortName(match.url);
|
|
292
|
+
editor.removeSource(match.url);
|
|
293
|
+
editor.save();
|
|
294
|
+
await dropManifestCache(match.url, opts.purge);
|
|
295
|
+
logOk(
|
|
296
|
+
opts.purge ? `Removed source "${slug}" and purged its clone.` : `Removed source "${slug}" from skaile.yaml (clone left in ~/.skaile/cache/sources/).`
|
|
297
|
+
);
|
|
298
|
+
});
|
|
299
|
+
cmd.command("sync [name]").description("Pull upstream changes and refresh the manifest cache").option("--dev", "Also index dev-only assets under each source's dev_paths", false).option("--all", "Sync every source without prompting", false).action(async (key, opts) => {
|
|
300
|
+
const yamlPath = requireProjectYamlPath();
|
|
301
|
+
const sources = readProjectSources(yamlPath);
|
|
302
|
+
if (sources.length === 0) {
|
|
303
|
+
logInfo("No sources in skaile.yaml.");
|
|
304
|
+
return;
|
|
305
|
+
}
|
|
306
|
+
let targets;
|
|
307
|
+
if (key) {
|
|
308
|
+
targets = sources.filter((s) => sourceMatchesKey(s, key));
|
|
309
|
+
if (targets.length === 0) {
|
|
310
|
+
logInfo(`No source matching "${key}".`);
|
|
311
|
+
return;
|
|
312
|
+
}
|
|
313
|
+
} else if (opts.all || sources.length === 1 || !process.stdin.isTTY) {
|
|
314
|
+
targets = sources;
|
|
315
|
+
} else {
|
|
316
|
+
const selected = await p.multiselect({
|
|
317
|
+
message: "Select sources to sync",
|
|
318
|
+
options: sources.map((s) => ({
|
|
319
|
+
value: s.url,
|
|
320
|
+
label: sourceShortName(s.url),
|
|
321
|
+
hint: s.url
|
|
322
|
+
})),
|
|
323
|
+
required: true
|
|
324
|
+
});
|
|
325
|
+
if (p.isCancel(selected)) {
|
|
326
|
+
p.cancel("Cancelled.");
|
|
327
|
+
return;
|
|
328
|
+
}
|
|
329
|
+
const picked = new Set(selected);
|
|
330
|
+
targets = sources.filter((s) => picked.has(s.url));
|
|
331
|
+
}
|
|
332
|
+
for (const entry of targets) {
|
|
333
|
+
const slug = sourceShortName(entry.url);
|
|
334
|
+
const dest = sourceClonePath(sourceCacheKey(entry.url));
|
|
335
|
+
if (!existsSync(dest)) {
|
|
336
|
+
ensureClone(entry);
|
|
337
|
+
logOk(`${slug}: cloned to ${dest}.`);
|
|
338
|
+
} else {
|
|
339
|
+
const pull = spawnSync("git", ["pull", "--ff-only"], { cwd: dest, stdio: "inherit" });
|
|
340
|
+
if (pull.status !== 0) {
|
|
341
|
+
logWarn(`${slug}: git pull failed, skipping manifest refresh.`);
|
|
342
|
+
continue;
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
const result = await refreshManifestCache(entry, opts.dev);
|
|
346
|
+
const failed = indexingHadFailures(result);
|
|
347
|
+
const indexedMsg = `${slug}: indexed ${result.assetsUpdated} of ${result.assetsFound} asset(s).`;
|
|
348
|
+
if (failed) {
|
|
349
|
+
logWarn(indexedMsg);
|
|
350
|
+
process.exitCode = 1;
|
|
351
|
+
} else {
|
|
352
|
+
logOk(indexedMsg);
|
|
353
|
+
}
|
|
354
|
+
for (const err of result.errors) logWarn(`${slug}: ${err}`);
|
|
355
|
+
const legacyHint = legacySourceConfigHint(dest);
|
|
356
|
+
if (legacyHint) logWarn(`${slug}: ${legacyHint}`);
|
|
357
|
+
}
|
|
358
|
+
});
|
|
359
|
+
cmd.command("patch <ref>").description("Extract an asset for editing against the source").action((_ref) => {
|
|
360
|
+
logErr(
|
|
361
|
+
"`skaile source patch` is scaffolded but not yet wired. The patch flow lands in a follow-up PR."
|
|
362
|
+
);
|
|
363
|
+
process.exit(2);
|
|
364
|
+
});
|
|
365
|
+
cmd.command("propose <ref>").description("Open a PR with the patch against the source upstream").action((_ref) => {
|
|
366
|
+
logErr(
|
|
367
|
+
"`skaile source propose` is scaffolded but not yet wired. The propose flow lands in a follow-up PR."
|
|
368
|
+
);
|
|
369
|
+
process.exit(2);
|
|
370
|
+
});
|
|
371
|
+
addSourceManifestCommands(cmd);
|
|
372
|
+
return cmd;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
export { autoSyncForSearch, findCacheKeyCollision, indexingHadFailures, legacySourceConfigHint, makeSourceCommand, normalizeSourceUrl, sourceClonePath, sourceMatchesKey, syncProjectSources };
|
|
376
|
+
//# sourceMappingURL=chunk-BXC5547R.js.map
|
|
377
|
+
//# sourceMappingURL=chunk-BXC5547R.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../cli/src/commands/source-manifest.ts","../cli/src/commands/source.ts"],"names":[],"mappings":"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","file":"chunk-BXC5547R.js","sourcesContent":["/**\n * `skaile source manifest …` — sidecar manifest lifecycle, refactored under\n * the `source` noun (was `source sidecar …`).\n *\n * The verbs are stubs for now — the real wiring lands when the publish path\n * through `POST /sources/<id>/manifest` is finalised on the store backend.\n * Each subcommand exits with code 2 plus a clear \"not yet wired\" hint so\n * smoke tests can verify the surface without depending on the server.\n *\n * @docLink cli/commands/source#manifest\n */\n\nimport type { Command } from \"commander\";\nimport { logErr } from \"../helpers.ts\";\n\nconst NOT_WIRED_MSG =\n \"`skaile source manifest *` is scaffolded but not yet wired. \" +\n \"Server-side endpoint (`POST /sources/<id>/manifest`) lands in a follow-up PR.\";\n\nfunction notWired(verb: string): never {\n logErr(`${NOT_WIRED_MSG} (verb: source manifest ${verb})`);\n process.exit(2);\n}\n\n/**\n * Append the `manifest` sub-tree to a `source` command.\n *\n * Called from `makeSourceCommand()` in `source.ts`.\n */\nexport function addSourceManifestCommands(src: Command): void {\n const manifest = src.command(\"manifest\").description(\"Sidecar manifest lifecycle for a source\");\n\n manifest\n .command(\"init <src>\")\n .description(\"Start a sidecar manifest for a source\")\n .action(() => notWired(\"init\"));\n\n manifest\n .command(\"edit <src>\")\n .description(\"Open the sidecar manifest in $EDITOR\")\n .action(() => notWired(\"edit\"));\n\n manifest\n .command(\"rebuild <src>\")\n .description(\"Re-derive the manifest after an upstream change\")\n .option(\"--merge\", \"Merge with existing entries instead of overwriting\", false)\n .action(() => notWired(\"rebuild\"));\n\n manifest\n .command(\"verify <src>\")\n .description(\"Verify hashes, deps, and schema\")\n .option(\"--strict\", \"Fail on advisory checks\", false)\n .action(() => notWired(\"verify\"));\n\n manifest\n .command(\"publish <src>\")\n .description(\"Register the manifest in the store (provenance=curator)\")\n .action(() => notWired(\"publish\"));\n\n manifest\n .command(\"propose <src>\")\n .description(\"Open a PR to upstream with the sidecar manifest\")\n .action(() => notWired(\"propose\"));\n\n manifest\n .command(\"yank <src>\")\n .description(\"Retract a published manifest from the remote store\")\n .option(\"--version <v>\", \"Version to yank\")\n .action(() => notWired(\"yank\"));\n}\n","/**\n * `skaile source …` — manage github sources for the current project.\n *\n * A *source* is a third-party github repo of AI assets. The project's\n * `skaile.yaml` `sources:` array is the source of truth for which sources\n * this project uses. The clone itself lives at\n * `~/.skaile/cache/sources/<host>/<owner>/<repo>/` (machine-global cache, shared\n * across projects, URL-keyed so cross-org repos never collide), and the manifest is\n * mirrored into `~/.skaile/index.db` (machine-global manifest cache).\n *\n * @docLink cli/commands/source\n */\n\nimport { spawnSync } from \"node:child_process\";\nimport { existsSync, mkdirSync, rmSync } from \"node:fs\";\nimport * as path from \"node:path\";\nimport {\n findWorkspaceRoot,\n getGlobalCacheDir,\n type SourceEntry,\n sourceCacheKey,\n sourceShortName,\n WorkspaceYamlEditor,\n workspaceConfigFilename,\n} from \"@skaile/workspaces/core\";\nimport { LocalCatalogSource } from \"@skaile/workspaces/library\";\nimport * as p from \"@clack/prompts\";\nimport { Command } from \"commander\";\nimport { logErr, logInfo, logOk, logWarn, S } from \"../helpers.ts\";\nimport { openLibraryManager } from \"../open-library.ts\";\nimport { createFullRegistry } from \"../open-registry.ts\";\nimport { addSourceManifestCommands } from \"./source-manifest.ts\";\n\n/**\n * Clone dir for one source cache key (`<host>/<owner>/<repo>`). Exported for the\n * cache-path regression test. Callers pass `sourceCacheKey(url)`.\n */\nexport function sourceClonePath(key: string): string {\n return path.join(getGlobalCacheDir(), key);\n}\n\nconst SKAILE_MANIFEST_FILENAME = \"skaile.manifest.yaml\";\nconst LEGACY_SOURCE_CONFIG_FILENAME = \".skaile-source.yaml\";\n\n/**\n * Whether a manifest-cache refresh actually failed to index something. Keyed on\n * `errors`, NOT on `assetsUpdated < assetsFound`: the discovery walk counts\n * presets (and other intentionally-not-cataloged kinds) toward `assetsFound` but\n * never upserts them, so a source shipping a `.preset.yaml` would otherwise read\n * as a partial failure — false `! N asset(s) failed to index` + exit 1 — with\n * zero real errors.\n */\nexport function indexingHadFailures(result: { errors: string[] }): boolean {\n return result.errors.length > 0;\n}\n\n/**\n * A clone that ships only the legacy `.skaile-source.yaml` (no\n * `skaile.manifest.yaml`) has its declared `publisher_default` silently ignored\n * — discovery only reads `skaile.manifest.yaml`, so publisher resolution falls\n * back to the first path segment. Surface a hint so the author can fix it.\n */\nexport function legacySourceConfigHint(dest: string): string | undefined {\n const hasLegacy = existsSync(path.join(dest, LEGACY_SOURCE_CONFIG_FILENAME));\n const hasManifest = existsSync(path.join(dest, SKAILE_MANIFEST_FILENAME));\n if (hasLegacy && !hasManifest) {\n return (\n `This source ships a legacy ${LEGACY_SOURCE_CONFIG_FILENAME} but no ` +\n `${SKAILE_MANIFEST_FILENAME}; its declared publisher is ignored and assets ` +\n `are published under their first path segment. Add a ${SKAILE_MANIFEST_FILENAME} ` +\n `(\\`skaile source manifest init\\`) to set the publisher and asset inventory.`\n );\n }\n return undefined;\n}\n\n/**\n * Normalize a `source add` argument into a clonable git URL. Full URLs and\n * scp-style (`git@host:…`) specs pass through unchanged; an `owner/repo`\n * shorthand and a bare repo name expand to GitHub over SSH — a bare name\n * defaults to the `skaile-ai` org (`git@github.com:skaile-ai/<name>.git`).\n */\nexport function normalizeSourceUrl(input: string): string {\n const s = input.trim();\n if (/^(?:https?|git|ssh|file):\\/\\//.test(s) || /^git@/.test(s)) return s;\n const repo = s.replace(/\\.git$/, \"\");\n if (/^[\\w.-]+\\/[\\w.-]+$/.test(repo)) return `git@github.com:${repo}.git`;\n if (/^[\\w.-]+$/.test(repo)) return `git@github.com:skaile-ai/${repo}.git`;\n return s;\n}\n\n/**\n * Match a stored source against a user-supplied key. Mirrors the shortcut\n * expansion `source add` applies (`normalizeSourceUrl`) so any form that `add`\n * accepted — bare name, `owner/repo`, `.git`-suffixed, full URL — also resolves\n * at `sync`/`show`/`remove` time, not just the raw stored URL or derived slug.\n */\nexport function sourceMatchesKey(entry: SourceEntry, key: string): boolean {\n if (entry.url === key) return true;\n if (sourceCacheKey(entry.url) === key || sourceShortName(entry.url) === key) return true;\n return entry.url === normalizeSourceUrl(key);\n}\n\n/**\n * Find an already-registered source that maps to the same cache key as `url`\n * but is stored under a *different* URL string (e.g. the `.git`-suffixed or\n * scp form of the same remote). Two such entries would fight over one clone\n * dir, so `source add` rejects the ambiguity. Returns the colliding entry, or\n * `undefined` when the URL is unique or only matches an exact-string duplicate\n * (which `setSource` updates in place).\n */\nexport function findCacheKeyCollision(\n sources: SourceEntry[],\n url: string,\n): SourceEntry | undefined {\n const key = sourceCacheKey(url);\n return sources.find((s) => s.url !== url && sourceCacheKey(s.url) === key);\n}\n\nfunction requireProjectYamlPath(): string {\n const root = findWorkspaceRoot(process.cwd());\n if (!root) {\n logErr(\n \"No skaile.yaml found in the current directory or any parent. \" + \"Run `skaile init` first.\",\n );\n process.exit(1);\n }\n return path.join(root, workspaceConfigFilename());\n}\n\nfunction readProjectSources(yamlPath: string): SourceEntry[] {\n if (!existsSync(yamlPath)) return [];\n try {\n return WorkspaceYamlEditor.load(yamlPath).getSources();\n } catch (err) {\n logErr(`Could not read ${yamlPath}: ${err instanceof Error ? err.message : String(err)}`);\n process.exit(1);\n }\n}\n\n/**\n * Clone the source if its clone directory does not yet exist. When `force` is\n * set, the existing clone is removed and a fresh one is checked out. Returns\n * true when a clone happened. The cache slug is derived from the URL.\n */\nfunction ensureClone(entry: SourceEntry, opts: { force?: boolean } = {}): boolean {\n const dest = sourceClonePath(sourceCacheKey(entry.url));\n if (existsSync(dest)) {\n if (!opts.force) return false;\n rmSync(dest, { recursive: true, force: true });\n }\n mkdirSync(path.dirname(dest), { recursive: true });\n const args = [\"clone\", entry.url, dest];\n // `pin` may be a branch/tag; pass it as the clone branch when present.\n if (entry.pin) args.splice(1, 0, \"--branch\", entry.pin);\n const clone = spawnSync(\"git\", args, { stdio: \"inherit\" });\n if (clone.status !== 0) {\n logErr(`git clone failed for ${entry.url}`);\n process.exit(1);\n }\n return true;\n}\n\n/**\n * Refresh the machine-global manifest cache for `entry` by running discovery\n * and upserting AssetDefinitions into `~/.skaile/index.db`. Creates the\n * libraries-table cache row if missing (ownership: reader = cache state).\n */\nasync function refreshManifestCache(\n entry: SourceEntry,\n includeDev = false,\n): Promise<{\n assetsFound: number;\n assetsUpdated: number;\n errors: string[];\n}> {\n const { manager, library, close } = await openLibraryManager();\n try {\n const name = sourceShortName(entry.url);\n const dest = sourceClonePath(sourceCacheKey(entry.url));\n const existing = (await manager.listLibraries()).find((l) => l.name === name);\n const lib =\n existing ??\n (await manager.addLibrary({\n name,\n path: dest,\n backend: \"git\",\n backendConfig: { url: entry.url, branch: entry.pin ?? \"main\", authHint: \"ssh\" },\n ownership: \"reader\",\n }));\n const catalog = new LocalCatalogSource(library, lib.id, dest, createFullRegistry());\n const result = await catalog.sync({ includeDev });\n await library.syncSource(lib.id);\n return result;\n } finally {\n close();\n }\n}\n\n/**\n * Auto-sync hook for `skaile search` on an unsynced workspace. Clones/pulls and\n * re-indexes every source declared in the project's `skaile.yaml`, then returns\n * whether the manifest cache may have changed (caller re-queries on `true`).\n *\n * Unlike `source sync`, this degrades gracefully — a clone/pull/index failure is\n * logged and skipped (never `process.exit`) so a failed auto-sync falls back to\n * the \"run sync first\" hint rather than killing the search. Returns `false`\n * (silently, no announce) when no sources are declared. Callers must guard\n * air-gapped mode themselves — this always touches the network.\n */\nexport async function autoSyncForSearch(projectDir: string): Promise<boolean> {\n const root = findWorkspaceRoot(projectDir);\n if (!root) return false;\n if (readProjectSources(path.join(root, workspaceConfigFilename())).length === 0) return false;\n\n logInfo(\"sources not synced — syncing now…\");\n const { synced } = await syncProjectSources(projectDir);\n return synced > 0;\n}\n\n/**\n * Clone-or-pull every source declared in the project's `skaile.yaml`, then\n * refresh its manifest cache. Shared by `autoSyncForSearch` and `skaile update`\n * (the latter offers it behind a confirm) so a re-deploy can see upstream\n * commits — `update` re-deploys against the local source cache, which is\n * otherwise frozen at the commit captured when the source was first cloned.\n *\n * Graceful by design: a clone/pull/index failure for one source is logged and\n * skipped (never `process.exit`), so a single bad remote can't abort the run.\n * Existing clones are advanced with `git pull --ff-only` (no `--depth=1`, unlike\n * the installer's `pullRepo`, so it fast-forwards instead of tripping the\n * shallow-divergence path). Returns a count summary for the caller to report.\n */\nexport async function syncProjectSources(\n projectDir: string,\n opts: { dev?: boolean } = {},\n): Promise<{ total: number; synced: number; failed: number }> {\n const root = findWorkspaceRoot(projectDir) ?? projectDir;\n const sources = readProjectSources(path.join(root, workspaceConfigFilename()));\n let synced = 0;\n let failed = 0;\n for (const entry of sources) {\n const slug = sourceShortName(entry.url);\n const dest = sourceClonePath(sourceCacheKey(entry.url));\n try {\n // Quiet git — the sync is a preparatory step; keep progress bars out of\n // the foreground output (spinner / install result).\n if (!existsSync(dest)) {\n mkdirSync(path.dirname(dest), { recursive: true });\n const args = [\"clone\", entry.url, dest];\n if (entry.pin) args.splice(1, 0, \"--branch\", entry.pin);\n const clone = spawnSync(\"git\", args, { stdio: \"ignore\" });\n if (clone.status !== 0) {\n logWarn(`${slug}: git clone failed, skipping.`);\n failed++;\n continue;\n }\n } else {\n const pull = spawnSync(\"git\", [\"pull\", \"--ff-only\"], { cwd: dest, stdio: \"ignore\" });\n if (pull.status !== 0) {\n logWarn(`${slug}: git pull failed, skipping manifest refresh.`);\n failed++;\n continue;\n }\n }\n const result = await refreshManifestCache(entry, opts.dev);\n for (const err of result.errors) logWarn(`${slug}: ${err}`);\n synced++;\n } catch (err) {\n logWarn(`${slug}: sync failed — ${err instanceof Error ? err.message : String(err)}`);\n failed++;\n }\n }\n return { total: sources.length, synced, failed };\n}\n\n/** Remove the libraries-table cache row and (optionally) the clone bytes. */\nasync function dropManifestCache(url: string, purgeClone: boolean): Promise<void> {\n const name = sourceShortName(url);\n const { manager, close } = await openLibraryManager();\n try {\n const existing = (await manager.listLibraries()).find((l) => l.name === name);\n if (existing) {\n await manager.removeLibrary(name, { purge: false });\n }\n } finally {\n close();\n }\n if (purgeClone) {\n const dest = sourceClonePath(sourceCacheKey(url));\n if (existsSync(dest)) rmSync(dest, { recursive: true, force: true });\n }\n}\n\nexport function makeSourceCommand(): Command {\n const cmd = new Command(\"source\").description(\n \"Manage github sources for the current project (recorded in skaile.yaml)\",\n );\n\n // ── source add ──────────────────────────────────────────────────────────\n cmd\n .command(\"add <source>\")\n .description(\n \"Clone a github repo and register it in this project's skaile.yaml. \" +\n \"<source> may be a full git URL, an owner/repo shorthand, or a bare \" +\n \"name (→ git@github.com:skaile-ai/<name>.git).\",\n )\n .option(\"--name <slug>\", \"[deprecated] no-op — the source entry stores only the URL\")\n .option(\"--pin <ref>\", \"Pin a branch, tag, or 40-char SHA\")\n .option(\"--branch <branch>\", \"[deprecated] alias for --pin\")\n .option(\"--force\", \"Remove an existing clone and re-clone\", false)\n .option(\"--dev\", \"Also index dev-only assets under the source's dev_paths\", false)\n .action(\n async (\n source: string,\n opts: {\n name?: string;\n pin?: string;\n branch?: string;\n force?: boolean;\n dev?: boolean;\n },\n ) => {\n const url = normalizeSourceUrl(source);\n const yamlPath = requireProjectYamlPath();\n\n // A different URL string that maps to the same cache key (e.g. the\n // `.git`-suffixed or scp form of an already-registered remote) would\n // fight over one clone dir. setSource only dedupes exact strings, so\n // reject the ambiguous collision here instead of silently shadowing.\n const collision = findCacheKeyCollision(readProjectSources(yamlPath), url);\n if (collision) {\n logErr(\n `\"${url}\" maps to the same cache key (${sourceCacheKey(url)}) as ` +\n `already-registered \"${collision.url}\". Remove that source first ` +\n `(skaile source remove) or re-use its exact URL to update it.`,\n );\n process.exitCode = 1;\n return;\n }\n\n if (opts.name) {\n logWarn(\n \"the --name flag is deprecated; the source entry now stores only the URL \" +\n \"(the cache slug is derived from it).\",\n );\n }\n const pin = opts.pin ?? opts.branch;\n const slug = sourceShortName(url);\n const entry: SourceEntry = { url };\n if (pin) entry.pin = pin;\n\n const editor = WorkspaceYamlEditor.load(yamlPath);\n editor.setSource(entry);\n editor.save();\n\n const dest = sourceClonePath(sourceCacheKey(url));\n const preexisting = existsSync(dest);\n const cloned = ensureClone(entry, { force: opts.force });\n if (!cloned) {\n logOk(`Reusing cached clone at ${dest}`);\n } else if (preexisting) {\n logOk(`Re-cloned ${url} → ${dest}`);\n } else {\n logOk(`Cloned ${url} → ${dest}`);\n }\n\n const result = await refreshManifestCache(entry, opts.dev);\n const failed = indexingHadFailures(result);\n const indexedMsg = `Indexed ${result.assetsUpdated} of ${result.assetsFound} asset(s) from \"${slug}\".`;\n if (failed) {\n logWarn(indexedMsg);\n } else {\n logOk(indexedMsg);\n }\n for (const err of result.errors) logWarn(err);\n\n const legacyHint = legacySourceConfigHint(dest);\n if (legacyHint) logWarn(legacyHint);\n\n const where = path.relative(process.cwd(), yamlPath);\n if (failed) {\n // The entry IS recorded in skaile.yaml, but indexing did not fully\n // succeed — don't present it as a clean success.\n logWarn(\n `Source \"${slug}\" registered in ${where}, but ${result.errors.length} ` +\n `asset(s) failed to index (see above). Fix the cause, then re-run ` +\n `\\`skaile source sync ${slug}\\`.`,\n );\n process.exitCode = 1;\n } else {\n logOk(`Source \"${slug}\" registered in ${where}.`);\n }\n },\n );\n\n // ── source list ─────────────────────────────────────────────────────────\n cmd\n .command(\"list\")\n .description(\"List sources registered in this project's skaile.yaml\")\n .option(\"--json\", \"Output as JSON\")\n .action(async (opts: { json?: boolean }) => {\n const yamlPath = requireProjectYamlPath();\n const sources = readProjectSources(yamlPath);\n if (opts.json) return console.log(JSON.stringify(sources, null, 2));\n if (sources.length === 0) {\n logInfo(\"No sources in skaile.yaml. Run `skaile source add <git-url>` to register one.\");\n return;\n }\n console.log();\n console.log(S.heading(\" Sources\"));\n for (const s of sources) {\n const slug = sourceShortName(s.url);\n const cached = existsSync(sourceClonePath(sourceCacheKey(s.url)))\n ? \"\"\n : S.warn(\" (not cached)\");\n console.log(` ${S.cmd(slug.padEnd(24))} ${S.dim(s.url)}${cached}`);\n }\n console.log(`\\n ${S.dim(`${sources.length} source(s)`)}\\n`);\n });\n\n // ── source show ─────────────────────────────────────────────────────────\n cmd\n .command(\"show <name-or-url>\")\n .description(\"Show details for a source (matched by URL or derived slug)\")\n .action(async (key: string) => {\n const yamlPath = requireProjectYamlPath();\n const entry = readProjectSources(yamlPath).find((s) => sourceMatchesKey(s, key));\n if (!entry) {\n logErr(`No source matching \"${key}\" in ${yamlPath}.`);\n process.exit(1);\n }\n const slug = sourceShortName(entry.url);\n const clonePath = sourceClonePath(sourceCacheKey(entry.url));\n console.log(\n JSON.stringify(\n {\n ...entry,\n slug,\n clonePath,\n cached: existsSync(clonePath),\n },\n null,\n 2,\n ),\n );\n });\n\n // ── source remove ───────────────────────────────────────────────────────\n cmd\n .command(\"remove <name-or-url>\")\n .description(\"Remove a source from this project's skaile.yaml (matched by URL or slug)\")\n .option(\"--purge\", \"Also delete the cached clone from ~/.skaile/cache/sources/\", false)\n .action(async (key: string, opts: { purge: boolean }) => {\n const yamlPath = requireProjectYamlPath();\n const editor = WorkspaceYamlEditor.load(yamlPath);\n // Resolve to the stored URL (entries are keyed by url in the editor).\n const match = editor.getSources().find((s) => sourceMatchesKey(s, key));\n if (!match) {\n logErr(`No source matching \"${key}\" in ${yamlPath}.`);\n process.exit(1);\n }\n const slug = sourceShortName(match.url);\n editor.removeSource(match.url);\n editor.save();\n await dropManifestCache(match.url, opts.purge);\n logOk(\n opts.purge\n ? `Removed source \"${slug}\" and purged its clone.`\n : `Removed source \"${slug}\" from skaile.yaml (clone left in ~/.skaile/cache/sources/).`,\n );\n });\n\n // ── source sync ─────────────────────────────────────────────────────────\n cmd\n .command(\"sync [name]\")\n .description(\"Pull upstream changes and refresh the manifest cache\")\n .option(\"--dev\", \"Also index dev-only assets under each source's dev_paths\", false)\n .option(\"--all\", \"Sync every source without prompting\", false)\n .action(async (key: string | undefined, opts: { dev?: boolean; all?: boolean }) => {\n const yamlPath = requireProjectYamlPath();\n const sources = readProjectSources(yamlPath);\n if (sources.length === 0) {\n logInfo(\"No sources in skaile.yaml.\");\n return;\n }\n\n let targets: SourceEntry[];\n if (key) {\n targets = sources.filter((s) => sourceMatchesKey(s, key));\n if (targets.length === 0) {\n logInfo(`No source matching \"${key}\".`);\n return;\n }\n } else if (opts.all || sources.length === 1 || !process.stdin.isTTY) {\n // --all, a single source, or a non-interactive shell: sync everything.\n targets = sources;\n } else {\n const selected = await p.multiselect({\n message: \"Select sources to sync\",\n options: sources.map((s) => ({\n value: s.url,\n label: sourceShortName(s.url),\n hint: s.url,\n })),\n required: true,\n });\n if (p.isCancel(selected)) {\n p.cancel(\"Cancelled.\");\n return;\n }\n const picked = new Set(selected as string[]);\n targets = sources.filter((s) => picked.has(s.url));\n }\n for (const entry of targets) {\n const slug = sourceShortName(entry.url);\n const dest = sourceClonePath(sourceCacheKey(entry.url));\n if (!existsSync(dest)) {\n ensureClone(entry);\n logOk(`${slug}: cloned to ${dest}.`);\n } else {\n const pull = spawnSync(\"git\", [\"pull\", \"--ff-only\"], { cwd: dest, stdio: \"inherit\" });\n if (pull.status !== 0) {\n logWarn(`${slug}: git pull failed, skipping manifest refresh.`);\n continue;\n }\n }\n const result = await refreshManifestCache(entry, opts.dev);\n const failed = indexingHadFailures(result);\n const indexedMsg = `${slug}: indexed ${result.assetsUpdated} of ${result.assetsFound} asset(s).`;\n if (failed) {\n logWarn(indexedMsg);\n process.exitCode = 1;\n } else {\n logOk(indexedMsg);\n }\n for (const err of result.errors) logWarn(`${slug}: ${err}`);\n const legacyHint = legacySourceConfigHint(dest);\n if (legacyHint) logWarn(`${slug}: ${legacyHint}`);\n }\n });\n\n // ── source patch / propose (stubs) ──────────────────────────────────────\n cmd\n .command(\"patch <ref>\")\n .description(\"Extract an asset for editing against the source\")\n .action((_ref: string) => {\n logErr(\n \"`skaile source patch` is scaffolded but not yet wired. \" +\n \"The patch flow lands in a follow-up PR.\",\n );\n process.exit(2);\n });\n\n cmd\n .command(\"propose <ref>\")\n .description(\"Open a PR with the patch against the source upstream\")\n .action((_ref: string) => {\n logErr(\n \"`skaile source propose` is scaffolded but not yet wired. \" +\n \"The propose flow lands in a follow-up PR.\",\n );\n process.exit(2);\n });\n\n // ── source manifest * ───────────────────────────────────────────────────\n addSourceManifestCommands(cmd);\n\n return cmd;\n}\n"]}
|
|
@@ -68,5 +68,5 @@ async function flowFindFlowForSession(projectDir, runId) {
|
|
|
68
68
|
}
|
|
69
69
|
|
|
70
70
|
export { flowFindFlowForSession, flowGetSession, flowList, flowListSessions, flowShow };
|
|
71
|
-
//# sourceMappingURL=chunk-
|
|
72
|
-
//# sourceMappingURL=chunk-
|
|
71
|
+
//# sourceMappingURL=chunk-EOINYN5T.js.map
|
|
72
|
+
//# sourceMappingURL=chunk-EOINYN5T.js.map
|