@skaile/workspaces 0.43.1 → 0.44.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 +31 -0
- package/dist/{asset-feeds-3PSV57NT.js → asset-feeds-EGSG4FUB.js} +15 -11
- package/dist/asset-feeds-EGSG4FUB.js.map +1 -0
- package/dist/asset-manager/index.js +5 -5
- package/dist/asset-manager/installer.js +4 -4
- package/dist/asset-manager/src/index.d.ts +102 -4
- package/dist/asset-manager/src/index.d.ts.map +1 -1
- package/dist/{chunk-N4FSBCLV.js → chunk-5LHPKVGR.js} +9 -9
- package/dist/{chunk-N4FSBCLV.js.map → chunk-5LHPKVGR.js.map} +1 -1
- package/dist/{chunk-WRDHUTOK.js → chunk-7NQXVBCQ.js} +5 -5
- package/dist/{chunk-WRDHUTOK.js.map → chunk-7NQXVBCQ.js.map} +1 -1
- package/dist/{chunk-KYQNWFJV.js → chunk-BLGHFVXE.js} +3 -3
- package/dist/{chunk-KYQNWFJV.js.map → chunk-BLGHFVXE.js.map} +1 -1
- package/dist/{chunk-R4H6EJW5.js → chunk-CBZEIFU4.js} +3 -3
- package/dist/{chunk-R4H6EJW5.js.map → chunk-CBZEIFU4.js.map} +1 -1
- package/dist/{chunk-GJI6FZ56.js → chunk-COSTF7QW.js} +60 -8
- package/dist/chunk-COSTF7QW.js.map +1 -0
- package/dist/{chunk-NYMRKIOR.js → chunk-CVWA4RIK.js} +4 -4
- package/dist/{chunk-NYMRKIOR.js.map → chunk-CVWA4RIK.js.map} +1 -1
- package/dist/{chunk-BXYMGZCI.js → chunk-ETDXTGDF.js} +3 -3
- package/dist/{chunk-BXYMGZCI.js.map → chunk-ETDXTGDF.js.map} +1 -1
- package/dist/{chunk-TDSRLMDB.js → chunk-EVZKWY5J.js} +2 -2
- package/dist/chunk-EVZKWY5J.js.map +1 -0
- package/dist/{chunk-3HUUP3JC.js → chunk-FYLIR4AV.js} +107 -7
- package/dist/chunk-FYLIR4AV.js.map +1 -0
- package/dist/{chunk-G6FJZG4C.js → chunk-GM3BV6JK.js} +2 -2
- package/dist/{chunk-G6FJZG4C.js.map → chunk-GM3BV6JK.js.map} +1 -1
- package/dist/{chunk-WKZ5R4NP.js → chunk-JUZLVRI4.js} +265 -38
- package/dist/chunk-JUZLVRI4.js.map +1 -0
- package/dist/{chunk-U2XHHLE3.js → chunk-LMRO2QNF.js} +5 -5
- package/dist/{chunk-U2XHHLE3.js.map → chunk-LMRO2QNF.js.map} +1 -1
- package/dist/{chunk-R4YUZRGF.js → chunk-NHLXS2CH.js} +2 -2
- package/dist/{chunk-R4YUZRGF.js.map → chunk-NHLXS2CH.js.map} +1 -1
- package/dist/{chunk-CIEKKLMG.js → chunk-PCXU2CVW.js} +3 -3
- package/dist/{chunk-CIEKKLMG.js.map → chunk-PCXU2CVW.js.map} +1 -1
- package/dist/{chunk-HVCZLD5Z.js → chunk-VPXV2Z5E.js} +5 -7
- package/dist/chunk-VPXV2Z5E.js.map +1 -0
- package/dist/{chunk-2BEDUMTA.js → chunk-XF2BBX6P.js} +3 -3
- package/dist/{chunk-2BEDUMTA.js.map → chunk-XF2BBX6P.js.map} +1 -1
- package/dist/{chunk-3K2CYDBT.js → chunk-Z5Z3MYDL.js} +8 -4
- package/dist/chunk-Z5Z3MYDL.js.map +1 -0
- package/dist/{chunk-M54RYUXY.js → chunk-ZAEJ33Y6.js} +19 -7
- package/dist/chunk-ZAEJ33Y6.js.map +1 -0
- package/dist/cli/index.js +395 -286
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/src/asset-feeds.d.ts.map +1 -1
- package/dist/cli/src/commands/cache.d.ts +27 -0
- package/dist/cli/src/commands/cache.d.ts.map +1 -0
- package/dist/cli/src/commands/catalog.d.ts.map +1 -1
- package/dist/cli/src/commands/manage.d.ts.map +1 -1
- package/dist/cli/src/commands/npx.d.ts +1 -1
- package/dist/cli/src/commands/source.d.ts +3 -1
- package/dist/cli/src/commands/source.d.ts.map +1 -1
- package/dist/cli/src/commands/update.d.ts +1 -1
- package/dist/cli/src/ensure-sources.d.ts +2 -2
- package/dist/cli/src/ensure-sources.d.ts.map +1 -1
- package/dist/connectors/config.js +4 -4
- package/dist/connectors/index.js +6 -6
- package/dist/connectors/rclone.js +1 -1
- package/dist/connectors/src/rclone-process-manager.d.ts +57 -2
- package/dist/connectors/src/rclone-process-manager.d.ts.map +1 -1
- package/dist/core/index.js +3 -3
- package/dist/core/runtime-assets.js +2 -2
- package/dist/core/src/cache-paths.d.ts +25 -0
- package/dist/core/src/cache-paths.d.ts.map +1 -0
- package/dist/core/src/index.d.ts +1 -0
- package/dist/core/src/index.d.ts.map +1 -1
- package/dist/core/src/repo-manager.d.ts +11 -8
- package/dist/core/src/repo-manager.d.ts.map +1 -1
- package/dist/core/src/runtime-assets.d.ts.map +1 -1
- package/dist/core/src/workspace-config.d.ts +2 -2
- package/dist/core/src/workspace-config.d.ts.map +1 -1
- package/dist/core/workspace-config.js +1 -1
- package/dist/deploy/index.js +3 -3
- package/dist/{ensure-sources-VQDZB7NT.js → ensure-sources-NSDMTAWN.js} +6 -12
- package/dist/ensure-sources-NSDMTAWN.js.map +1 -0
- package/dist/factory-assets/connectors/deploy.js +6 -6
- package/dist/factory-assets/connectors/devserver.js +6 -6
- package/dist/factory-assets/connectors/flow/adapter.js +6 -6
- package/dist/factory-assets/connectors/flow/engine.js +3 -3
- package/dist/factory-assets/connectors/flow/run-flow.js +7 -7
- package/dist/factory-assets/connectors/flow.js +6 -6
- package/dist/factory-assets/connectors/git.js +6 -6
- package/dist/factory-assets/connectors/gmail.js +6 -6
- package/dist/factory-assets/connectors/googledrive.js +6 -6
- package/dist/factory-assets/connectors/local.js +6 -6
- package/dist/factory-assets/connectors/mattermost.js +6 -6
- package/dist/factory-assets/connectors/memory.js +6 -6
- package/dist/factory-assets/connectors/minio.js +6 -6
- package/dist/factory-assets/connectors/postgres.js +6 -6
- package/dist/factory-assets/connectors/s3.js +6 -6
- package/dist/factory-assets/connectors/sharepoint.js +6 -6
- package/dist/factory-assets/connectors/sqlite.js +6 -6
- package/dist/factory-assets/connectors/static-server.js +6 -6
- package/dist/factory-assets/connectors/tunnel.js +6 -6
- package/dist/factory-assets/connectors/webdav.js +6 -6
- package/dist/factory-assets/connectors/xstate-store.js +6 -6
- package/dist/factory-assets/connectors/xstate.js +6 -6
- package/dist/{flows-KTBCZ5GQ.js → flows-WELXQ7IG.js} +3 -3
- package/dist/{flows-KTBCZ5GQ.js.map → flows-WELXQ7IG.js.map} +1 -1
- package/dist/library/index.js +4 -4
- package/dist/library/install.js +3 -3
- package/dist/library/src/local/local-catalog-source.d.ts +1 -1
- package/dist/library/src/local/sidecar-git.d.ts +2 -2
- package/dist/library/src/local/sidecar-paths.d.ts +12 -10
- package/dist/library/src/local/sidecar-paths.d.ts.map +1 -1
- package/dist/library/src/local/store-paths.d.ts +2 -2
- package/dist/library/src/remote/cache.d.ts +8 -2
- package/dist/library/src/remote/cache.d.ts.map +1 -1
- package/dist/library/src/remote/remote-catalog-source.d.ts +1 -1
- package/dist/library/src/remote/rest-catalog-source.d.ts +1 -1
- package/dist/{open-library-FHUXOCN7.js → open-library-362BZ6OW.js} +7 -7
- package/dist/{open-library-FHUXOCN7.js.map → open-library-362BZ6OW.js.map} +1 -1
- package/dist/{paths-7H5CSBLQ.js → paths-4SSFMX5Z.js} +6 -6
- package/dist/{paths-7H5CSBLQ.js.map → paths-4SSFMX5Z.js.map} +1 -1
- package/dist/{plugin-store-LGLN2QUX.js → plugin-store-RBCDBO7K.js} +5 -5
- package/dist/{plugin-store-LGLN2QUX.js.map → plugin-store-RBCDBO7K.js.map} +1 -1
- package/dist/runner/index.js +9 -9
- package/dist/sdk/asset-manager.js +5 -5
- package/dist/sdk/core.js +3 -3
- package/dist/sdk/flow.js +3 -3
- package/dist/sdk/index.js +9 -9
- package/dist/sdk/runner.js +9 -9
- package/dist/sdk/session.js +2 -2
- package/dist/sdk/types.js +1 -1
- package/dist/session/index.js +2 -2
- package/dist/session/src/index.d.ts +1 -1
- package/dist/session/src/index.d.ts.map +1 -1
- package/dist/session/src/mentions.d.ts +11 -0
- package/dist/session/src/mentions.d.ts.map +1 -1
- package/dist/{setup-EVNPECSY.js → setup-VGZTFQ32.js} +5 -5
- package/dist/{setup-EVNPECSY.js.map → setup-VGZTFQ32.js.map} +1 -1
- package/dist/{store-client-4XN7IB3R.js → store-client-XFZFKY3W.js} +6 -6
- package/dist/{store-client-4XN7IB3R.js.map → store-client-XFZFKY3W.js.map} +1 -1
- package/dist/tui/index.js +9 -9
- package/dist/types/index.js +1 -1
- package/dist/types/src/mentions.d.ts +12 -0
- package/dist/types/src/mentions.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-3PSV57NT.js.map +0 -1
- package/dist/chunk-3HUUP3JC.js.map +0 -1
- package/dist/chunk-3K2CYDBT.js.map +0 -1
- package/dist/chunk-GJI6FZ56.js.map +0 -1
- package/dist/chunk-HVCZLD5Z.js.map +0 -1
- package/dist/chunk-M54RYUXY.js.map +0 -1
- package/dist/chunk-TDSRLMDB.js.map +0 -1
- package/dist/chunk-WKZ5R4NP.js.map +0 -1
- package/dist/ensure-sources-VQDZB7NT.js.map +0 -1
|
@@ -1,15 +1,14 @@
|
|
|
1
|
-
import { deployAll, removeAsset, createScaffold } from './chunk-
|
|
2
|
-
import { writeLock, buildLockFile, readLock, verifyLock, extractForPatch, generatePatch, savePatch, applyPatch } from './chunk-
|
|
3
|
-
import { resolveRuntimeAssets, factoryAssetRoots } from './chunk-
|
|
4
|
-
import { resolveSkWorkspaceConfig,
|
|
1
|
+
import { deployAll, removeAsset, createScaffold } from './chunk-CVWA4RIK.js';
|
|
2
|
+
import { writeLock, buildLockFile, readLock, verifyLock, extractForPatch, generatePatch, savePatch, applyPatch } from './chunk-BLGHFVXE.js';
|
|
3
|
+
import { resolveRuntimeAssets, factoryAssetRoots } from './chunk-VPXV2Z5E.js';
|
|
4
|
+
import { migrateLegacyDir, resolveSkWorkspaceConfig, getGlobalCacheDir, getRepoCommit, resolveAll, buildProvenanceIndex, ensureRepo, scanRepo, checkRepoStatus, resolveAsset, readLinks } from './chunk-COSTF7QW.js';
|
|
5
5
|
import { parseAssetRef } from './chunk-GEEW6SY2.js';
|
|
6
6
|
import { deployedBase, isDeployed, deployedDir } from './chunk-XGCXFX7X.js';
|
|
7
7
|
import { appendHistory, getRecentHistory, clearHistory } from './chunk-KTBKW2FI.js';
|
|
8
8
|
import { commitChanges } from './chunk-UQ6LFBPZ.js';
|
|
9
9
|
import { spawnSync } from 'child_process';
|
|
10
10
|
import { existsSync, readdirSync, rmSync, lstatSync, unlinkSync, readFileSync, writeFileSync } from 'fs';
|
|
11
|
-
import {
|
|
12
|
-
import { resolve, join, dirname } from 'path';
|
|
11
|
+
import { resolve, join, sep, dirname } from 'path';
|
|
13
12
|
import { parse, stringify } from 'yaml';
|
|
14
13
|
|
|
15
14
|
function sourceSlug(url) {
|
|
@@ -18,6 +17,46 @@ function sourceSlug(url) {
|
|
|
18
17
|
function normalizeRepoUrl(url) {
|
|
19
18
|
return url.trim().replace(/^git@([^:]+):/, "https://$1/").replace(/^[a-z]+:\/\//i, "").replace(/\.git$/i, "").replace(/\/+$/, "").toLowerCase();
|
|
20
19
|
}
|
|
20
|
+
var MD_BY_KIND = {
|
|
21
|
+
skill: "SKILL.md",
|
|
22
|
+
agent: "AGENT.md",
|
|
23
|
+
bundle: "BUNDLE.md",
|
|
24
|
+
"mcp-server": "MCP.md",
|
|
25
|
+
connector: "CONNECTOR.md",
|
|
26
|
+
prompt: "PROMPT.md",
|
|
27
|
+
contract: "CONTRACT.md"
|
|
28
|
+
};
|
|
29
|
+
function matchManifestPath(kind, paths) {
|
|
30
|
+
const exact = MD_BY_KIND[kind];
|
|
31
|
+
if (exact) {
|
|
32
|
+
const hit = paths.find((p) => p.endsWith(exact));
|
|
33
|
+
if (hit) return hit;
|
|
34
|
+
}
|
|
35
|
+
if (kind === "prompt") return paths.find((p) => p.endsWith(".prompt.md"));
|
|
36
|
+
if (kind === "flow") {
|
|
37
|
+
return paths.find((p) => p.endsWith(".flow.yaml") || p.endsWith(".flow.json"));
|
|
38
|
+
}
|
|
39
|
+
return void 0;
|
|
40
|
+
}
|
|
41
|
+
var NON_DEPLOYABLE_KINDS = /* @__PURE__ */ new Set([
|
|
42
|
+
"bundle",
|
|
43
|
+
"mcp-server",
|
|
44
|
+
"persona",
|
|
45
|
+
"ruleset",
|
|
46
|
+
"knowledge"
|
|
47
|
+
]);
|
|
48
|
+
function commonDirPrefix(paths) {
|
|
49
|
+
if (paths.length === 0) return "";
|
|
50
|
+
const dirs = paths.map((p) => p.split("/").slice(0, -1));
|
|
51
|
+
let common = dirs[0];
|
|
52
|
+
for (let i = 1; i < dirs.length && common.length > 0; i++) {
|
|
53
|
+
const segs = dirs[i];
|
|
54
|
+
let n = 0;
|
|
55
|
+
while (n < common.length && n < segs.length && common[n] === segs[n]) n++;
|
|
56
|
+
common = common.slice(0, n);
|
|
57
|
+
}
|
|
58
|
+
return common.join("/");
|
|
59
|
+
}
|
|
21
60
|
function indexLockByKindName(lock) {
|
|
22
61
|
const lockByKindName = /* @__PURE__ */ new Map();
|
|
23
62
|
for (const [key] of Object.entries(lock?.assets ?? {})) {
|
|
@@ -99,13 +138,39 @@ var AssetManager = class {
|
|
|
99
138
|
driverTarget;
|
|
100
139
|
/** Whether this instance operates in global-install mode. */
|
|
101
140
|
global;
|
|
141
|
+
/** Injected catalog fetcher (tests / custom); falls back to a built one. */
|
|
142
|
+
injectedStoreFetcher;
|
|
143
|
+
/** Injected byte fetcher for store staging; falls back to GitHub. */
|
|
144
|
+
injectedAssetFetcher;
|
|
145
|
+
/** Injected global catalog URL override for the no-project-store fallback. */
|
|
146
|
+
catalogUrlOverride;
|
|
102
147
|
constructor(opts) {
|
|
103
148
|
this.projectDir = resolve(opts.projectDir);
|
|
104
149
|
this.driverTarget = opts.driverTarget ?? "claude-code";
|
|
105
150
|
this.global = opts.global ?? false;
|
|
151
|
+
this.injectedStoreFetcher = opts.storeFetcher;
|
|
152
|
+
this.injectedAssetFetcher = opts.assetFetcher;
|
|
153
|
+
this.catalogUrlOverride = opts.catalogUrl;
|
|
154
|
+
}
|
|
155
|
+
get storeCacheDir() {
|
|
156
|
+
return migrateLegacyDir(
|
|
157
|
+
join(this.projectDir, ".skaile", "cache", "store"),
|
|
158
|
+
join(this.projectDir, ".skaile", "store-cache")
|
|
159
|
+
);
|
|
106
160
|
}
|
|
107
161
|
get reposDir() {
|
|
108
|
-
return
|
|
162
|
+
return migrateLegacyDir(
|
|
163
|
+
join(this.projectDir, ".skaile", "cache", "sources"),
|
|
164
|
+
join(this.projectDir, ".skaile", "repos")
|
|
165
|
+
);
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Project-scoped cache dirs rooted at `.skaile/cache/` (`store`, `sources`)
|
|
169
|
+
* relative to `projectDir`. Reading is a side effect: it triggers lazy
|
|
170
|
+
* migration of the legacy `.skaile/{store-cache,repos}` dirs.
|
|
171
|
+
*/
|
|
172
|
+
get projectCacheDirs() {
|
|
173
|
+
return { store: this.storeCacheDir, sources: this.reposDir };
|
|
109
174
|
}
|
|
110
175
|
get lockPath() {
|
|
111
176
|
return join(this.projectDir, "skaile.lock.yaml");
|
|
@@ -123,8 +188,7 @@ var AssetManager = class {
|
|
|
123
188
|
const dependencies = config.dependencies ?? [];
|
|
124
189
|
const overrides = config.overrides ?? [];
|
|
125
190
|
const patches = config.patches ?? {};
|
|
126
|
-
const
|
|
127
|
-
const sourcesDir = join(skaileHome, "sources");
|
|
191
|
+
const sourcesDir = getGlobalCacheDir();
|
|
128
192
|
const repositories = {};
|
|
129
193
|
for (const s of sources) {
|
|
130
194
|
const slug = sourceSlug(s.url);
|
|
@@ -185,15 +249,6 @@ var AssetManager = class {
|
|
|
185
249
|
}
|
|
186
250
|
}
|
|
187
251
|
if (!cloneDir || !slug) return null;
|
|
188
|
-
const MD_BY_KIND = {
|
|
189
|
-
skill: "SKILL.md",
|
|
190
|
-
agent: "AGENT.md",
|
|
191
|
-
bundle: "BUNDLE.md",
|
|
192
|
-
"mcp-server": "MCP.md",
|
|
193
|
-
connector: "CONNECTOR.md",
|
|
194
|
-
prompt: "PROMPT.md",
|
|
195
|
-
contract: "CONTRACT.md"
|
|
196
|
-
};
|
|
197
252
|
const mdName = MD_BY_KIND[c.kind];
|
|
198
253
|
const mdRel = c.files.find((f) => mdName ? f.path.endsWith(mdName) : false)?.path;
|
|
199
254
|
const source = mdRel ? join(cloneDir, mdRel) : cloneDir;
|
|
@@ -215,6 +270,184 @@ var AssetManager = class {
|
|
|
215
270
|
if (c.homepage != null) entry.homepage = c.homepage;
|
|
216
271
|
return entry;
|
|
217
272
|
}
|
|
273
|
+
// ── Store fetch-then-deploy ────────────────────────────────────────────
|
|
274
|
+
/** A candidate's stable identity key (`<publisher>/<kind>:<name>@<version>`). */
|
|
275
|
+
candidateKey(c) {
|
|
276
|
+
return `${c.publisher}/${c.kind}:${c.name}@${c.version}`;
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* Resolve `deps`, falling back to the global `catalog.url` store when the
|
|
280
|
+
* project declares no store and the first pass leaves something missing.
|
|
281
|
+
*
|
|
282
|
+
* The first pass uses the project stores only, so locally-resolvable refs
|
|
283
|
+
* never trigger a network probe. The fallback retry is best-effort: any error
|
|
284
|
+
* (offline, store down) keeps the first pass's result rather than regressing.
|
|
285
|
+
*/
|
|
286
|
+
async resolveWithStores(deps, opts) {
|
|
287
|
+
const first = await resolveAll(deps, {
|
|
288
|
+
provenanceIndex: opts.provenanceIndex,
|
|
289
|
+
overrides: opts.overrides,
|
|
290
|
+
stores: opts.stores,
|
|
291
|
+
storeFetcher: this.storeFetcherFor(opts.stores),
|
|
292
|
+
projectDir: this.projectDir
|
|
293
|
+
});
|
|
294
|
+
if (first.missing.length === 0) return first;
|
|
295
|
+
const fallback = await this.globalStoreFallback(opts.stores);
|
|
296
|
+
if (fallback.length === 0) return first;
|
|
297
|
+
const stores = [...opts.stores, ...fallback];
|
|
298
|
+
try {
|
|
299
|
+
const retry = await resolveAll(deps, {
|
|
300
|
+
provenanceIndex: opts.provenanceIndex,
|
|
301
|
+
overrides: opts.overrides,
|
|
302
|
+
stores,
|
|
303
|
+
storeFetcher: this.storeFetcherFor(stores),
|
|
304
|
+
projectDir: this.projectDir
|
|
305
|
+
});
|
|
306
|
+
return retry.missing.length < first.missing.length ? retry : first;
|
|
307
|
+
} catch {
|
|
308
|
+
return first;
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
/** The catalog fetcher to use: an injected one, else built from `stores`. */
|
|
312
|
+
storeFetcherFor(stores) {
|
|
313
|
+
return this.injectedStoreFetcher ?? this.buildStoreFetcher(stores);
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* The global `catalog.url` as a single-store fallback, or `[]` when no
|
|
317
|
+
* project store should be synthesized — `local` sentinel, already-declared,
|
|
318
|
+
* or no URL. Honours an explicit `catalogUrl` injection (`""` disables it).
|
|
319
|
+
*/
|
|
320
|
+
async globalStoreFallback(projectStores) {
|
|
321
|
+
let url = this.catalogUrlOverride;
|
|
322
|
+
if (url === void 0) {
|
|
323
|
+
try {
|
|
324
|
+
const { resolveConfig } = await import('./library/index.js');
|
|
325
|
+
url = resolveConfig({ projectDir: this.projectDir }).catalog.url;
|
|
326
|
+
} catch {
|
|
327
|
+
return [];
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
if (!url || url.trim().toLowerCase() === "local") return [];
|
|
331
|
+
if (projectStores.some((s) => normalizeRepoUrl(s.url) === normalizeRepoUrl(url))) return [];
|
|
332
|
+
return [{ url }];
|
|
333
|
+
}
|
|
334
|
+
/**
|
|
335
|
+
* Build deployable catalog entries from resolved candidates. Store-resolved
|
|
336
|
+
* candidates (no local clone bytes) are fetched + SHA-verified into the
|
|
337
|
+
* project store-cache first, then their entry points at the staged bytes so
|
|
338
|
+
* the existing copy-deploy path works. Source-backed candidates keep the
|
|
339
|
+
* clone-relative entry.
|
|
340
|
+
*/
|
|
341
|
+
async buildCatalogEntries(resolved, repositories) {
|
|
342
|
+
const staged = await this.stageStoreAssets(resolved, repositories);
|
|
343
|
+
const entries = [];
|
|
344
|
+
for (const c of resolved) {
|
|
345
|
+
const stagedPath = staged.get(this.candidateKey(c));
|
|
346
|
+
const entry = stagedPath ? this.stagedCandidateToEntry(c, stagedPath) : this.candidateToCatalogEntry(c, repositories);
|
|
347
|
+
if (entry) entries.push(entry);
|
|
348
|
+
}
|
|
349
|
+
return entries;
|
|
350
|
+
}
|
|
351
|
+
/**
|
|
352
|
+
* Fetch + SHA-verify the bytes of every store-resolved deployable candidate
|
|
353
|
+
* into `.skaile/cache/store/`, reusing the same verified-fetch path the
|
|
354
|
+
* pointer-only `library.install` uses (`installFromManifest` flat mode).
|
|
355
|
+
*
|
|
356
|
+
* @returns Map of candidate key → staged primary-manifest path.
|
|
357
|
+
*/
|
|
358
|
+
async stageStoreAssets(resolved, repositories) {
|
|
359
|
+
const staged = /* @__PURE__ */ new Map();
|
|
360
|
+
let installFromManifest;
|
|
361
|
+
for (const c of resolved) {
|
|
362
|
+
if (NON_DEPLOYABLE_KINDS.has(c.kind)) continue;
|
|
363
|
+
if (!c.files || c.files.length === 0 || !c.sourceUrl || !c.commit) continue;
|
|
364
|
+
if (this.candidateHasLocalBytes(c, repositories)) continue;
|
|
365
|
+
if (!installFromManifest) {
|
|
366
|
+
({ installFromManifest } = await import('./library/index.js'));
|
|
367
|
+
}
|
|
368
|
+
const targetDir = join(this.storeCacheDir, c.publisher, c.kind, c.name, c.version);
|
|
369
|
+
const cacheRoot = resolve(this.storeCacheDir);
|
|
370
|
+
if (!resolve(targetDir).startsWith(cacheRoot + sep)) {
|
|
371
|
+
throw new Error(`unsafe store-cache path for ${this.candidateKey(c)}`);
|
|
372
|
+
}
|
|
373
|
+
const manifest = {
|
|
374
|
+
ref: `${c.kind}:@${c.publisher}/${c.name}#${c.version}`,
|
|
375
|
+
source: { url: c.sourceUrl, commitSha: c.commit },
|
|
376
|
+
files: c.files,
|
|
377
|
+
sha256: c.sha256,
|
|
378
|
+
kind: c.kind,
|
|
379
|
+
// tier = catalog storage hint (S3/CDN); flat-mode verified fetch pulls
|
|
380
|
+
// from source.url@commit and ignores it, so "" is inert.
|
|
381
|
+
tier: ""
|
|
382
|
+
};
|
|
383
|
+
const { installPath } = await installFromManifest({
|
|
384
|
+
manifest,
|
|
385
|
+
libraryRoot: this.storeCacheDir,
|
|
386
|
+
targetDir,
|
|
387
|
+
fetcher: this.injectedAssetFetcher
|
|
388
|
+
});
|
|
389
|
+
staged.set(this.candidateKey(c), join(installPath, this.stagedManifestRel(c)));
|
|
390
|
+
}
|
|
391
|
+
return staged;
|
|
392
|
+
}
|
|
393
|
+
/** Repo-relative path of a candidate's primary manifest (un-stripped). */
|
|
394
|
+
primaryManifestRel(c) {
|
|
395
|
+
const paths = (c.files ?? []).map((f) => f.path);
|
|
396
|
+
return matchManifestPath(c.kind, paths) ?? paths[0];
|
|
397
|
+
}
|
|
398
|
+
/**
|
|
399
|
+
* The primary-manifest path relative to a staged asset dir. Takes the kind's
|
|
400
|
+
* manifest (e.g. `SKILL.md`), then strips the same common-dir prefix
|
|
401
|
+
* `installFromManifest` flat mode removed on write.
|
|
402
|
+
*/
|
|
403
|
+
stagedManifestRel(c) {
|
|
404
|
+
const paths = (c.files ?? []).map((f) => f.path);
|
|
405
|
+
const mdRel = this.primaryManifestRel(c) ?? "";
|
|
406
|
+
const root = commonDirPrefix(paths);
|
|
407
|
+
return root && mdRel.startsWith(`${root}/`) ? mdRel.slice(root.length + 1) : mdRel;
|
|
408
|
+
}
|
|
409
|
+
/**
|
|
410
|
+
* `true` when a candidate's primary manifest is present on a local source
|
|
411
|
+
* clone — its `sourceUrl` matches a registered source AND the manifest file
|
|
412
|
+
* exists on disk at the expected path. A URL match alone is not enough: a
|
|
413
|
+
* store can pin a different commit (or a subtree not bundled) of a repo that
|
|
414
|
+
* is also a registered source, in which case the bytes must be fetched from
|
|
415
|
+
* the store rather than read from the clone. (Only the primary manifest is
|
|
416
|
+
* probed — a partially-cloned source is deployed as-is, matching the existing
|
|
417
|
+
* clone-deploy path.)
|
|
418
|
+
*/
|
|
419
|
+
candidateHasLocalBytes(c, repositories) {
|
|
420
|
+
if (!c.sourceUrl) return false;
|
|
421
|
+
const rel = this.primaryManifestRel(c);
|
|
422
|
+
for (const [slug, decl] of Object.entries(repositories)) {
|
|
423
|
+
if (decl.url === void 0 || decl.url !== c.sourceUrl) continue;
|
|
424
|
+
const dir = this.resolveRepoDir(decl, slug);
|
|
425
|
+
if (!dir) continue;
|
|
426
|
+
if (existsSync(rel ? join(dir, rel) : dir)) return true;
|
|
427
|
+
}
|
|
428
|
+
return false;
|
|
429
|
+
}
|
|
430
|
+
/** Build a copy-deploy catalog entry pointing at staged store bytes. */
|
|
431
|
+
stagedCandidateToEntry(c, stagedManifestPath) {
|
|
432
|
+
const entry = {
|
|
433
|
+
name: c.name,
|
|
434
|
+
kind: c.kind,
|
|
435
|
+
description: c.description ?? "",
|
|
436
|
+
source: stagedManifestPath,
|
|
437
|
+
// Real publisher (never a clone slug) → deployAsset copies rather than
|
|
438
|
+
// symlinking the ephemeral store-cache dir.
|
|
439
|
+
publisher: c.publisher,
|
|
440
|
+
version: c.version,
|
|
441
|
+
requires: [],
|
|
442
|
+
dependencies: c.deps ?? [],
|
|
443
|
+
metadata: c.metadata
|
|
444
|
+
};
|
|
445
|
+
if (c.category != null) entry.category = c.category;
|
|
446
|
+
if (c.keywords && c.keywords.length > 0) entry.keywords = c.keywords;
|
|
447
|
+
if (c.license != null) entry.license = c.license;
|
|
448
|
+
if (c.homepage != null) entry.homepage = c.homepage;
|
|
449
|
+
return entry;
|
|
450
|
+
}
|
|
218
451
|
// ── Install / resolve ──────────────────────────────────────────────────
|
|
219
452
|
/**
|
|
220
453
|
* Install all dependencies declared in `skaile.yaml`.
|
|
@@ -237,15 +470,13 @@ var AssetManager = class {
|
|
|
237
470
|
const provenanceIndex = buildProvenanceIndex(this.buildClones(repositories), {
|
|
238
471
|
projectDir: this.projectDir
|
|
239
472
|
});
|
|
240
|
-
const { resolved, missing, overridesApplied } = await
|
|
473
|
+
const { resolved, missing, overridesApplied } = await this.resolveWithStores(dependencies, {
|
|
241
474
|
provenanceIndex,
|
|
242
475
|
overrides,
|
|
243
|
-
stores
|
|
244
|
-
storeFetcher: this.buildStoreFetcher(stores),
|
|
245
|
-
projectDir: this.projectDir
|
|
476
|
+
stores
|
|
246
477
|
});
|
|
247
478
|
const removed = this.reconcileRemovedAssets(resolved);
|
|
248
|
-
const entries =
|
|
479
|
+
const entries = await this.buildCatalogEntries(resolved, repositories);
|
|
249
480
|
const deployed = deployAll(entries, repositories, patches, this.deployOpts);
|
|
250
481
|
writeLock(this.lockPath, buildLockFile(resolved, overridesApplied));
|
|
251
482
|
this.recordInstallHistory(deployed, removed);
|
|
@@ -453,19 +684,17 @@ var AssetManager = class {
|
|
|
453
684
|
const provenanceIndex = buildProvenanceIndex(this.buildClones(repositories), {
|
|
454
685
|
projectDir: this.projectDir
|
|
455
686
|
});
|
|
456
|
-
const { resolved, missing } = await
|
|
687
|
+
const { resolved, missing } = await this.resolveWithStores([ref], {
|
|
457
688
|
provenanceIndex,
|
|
458
689
|
overrides,
|
|
459
|
-
stores
|
|
460
|
-
storeFetcher: this.buildStoreFetcher(stores),
|
|
461
|
-
projectDir: this.projectDir
|
|
690
|
+
stores
|
|
462
691
|
});
|
|
463
692
|
if (resolved.length === 0) {
|
|
464
693
|
throw new Error(
|
|
465
694
|
`Asset not found: ${ref}${missing.length ? ` (missing: ${missing.join(", ")})` : ""}`
|
|
466
695
|
);
|
|
467
696
|
}
|
|
468
|
-
const entries =
|
|
697
|
+
const entries = await this.buildCatalogEntries(resolved, repositories);
|
|
469
698
|
const deployed = deployAll(entries, repositories, patches, this.deployOpts);
|
|
470
699
|
this.addDependencyToConfig(ref);
|
|
471
700
|
for (const d of deployed) {
|
|
@@ -739,12 +968,10 @@ var AssetManager = class {
|
|
|
739
968
|
const provenanceIndex = buildProvenanceIndex(this.buildClones(repositories), {
|
|
740
969
|
projectDir: this.projectDir
|
|
741
970
|
});
|
|
742
|
-
const { resolved, overridesApplied } = await
|
|
971
|
+
const { resolved, overridesApplied } = await this.resolveWithStores(dependencies, {
|
|
743
972
|
provenanceIndex,
|
|
744
973
|
overrides,
|
|
745
|
-
stores
|
|
746
|
-
storeFetcher: this.buildStoreFetcher(stores),
|
|
747
|
-
projectDir: this.projectDir
|
|
974
|
+
stores
|
|
748
975
|
});
|
|
749
976
|
const lockData = buildLockFile(resolved, overridesApplied);
|
|
750
977
|
writeLock(this.lockPath, lockData);
|
|
@@ -911,8 +1138,8 @@ var AssetManager = class {
|
|
|
911
1138
|
* Remove deployed assets tracked by the lock file and report unmanaged ones.
|
|
912
1139
|
*
|
|
913
1140
|
* With `opts.all`, also deletes `.skaile/history.yaml`, `.skaile/patches/`,
|
|
914
|
-
* `.skaile/
|
|
915
|
-
* to a pre-install state.
|
|
1141
|
+
* `.skaile/cache/sources/`, and `skaile.lock.yaml` — effectively resetting the
|
|
1142
|
+
* workspace to a pre-install state.
|
|
916
1143
|
*
|
|
917
1144
|
* @param opts - Optional cleanup options.
|
|
918
1145
|
* @param opts.all - When `true`, remove all Skaile-managed state in addition to deployed assets.
|
|
@@ -976,7 +1203,7 @@ var AssetManager = class {
|
|
|
976
1203
|
}
|
|
977
1204
|
return unmanaged;
|
|
978
1205
|
}
|
|
979
|
-
/** Delete all Skaile-managed state: history file, patches/,
|
|
1206
|
+
/** Delete all Skaile-managed state: history file, patches/, cache/sources/, lock. */
|
|
980
1207
|
removeAllManagedState() {
|
|
981
1208
|
const historyFile = join(this.projectDir, ".skaile", "history.yaml");
|
|
982
1209
|
try {
|
|
@@ -1039,6 +1266,6 @@ var AssetManager = class {
|
|
|
1039
1266
|
}
|
|
1040
1267
|
};
|
|
1041
1268
|
|
|
1042
|
-
export { AssetManager, parseCanonicalLockKey };
|
|
1043
|
-
//# sourceMappingURL=chunk-
|
|
1044
|
-
//# sourceMappingURL=chunk-
|
|
1269
|
+
export { AssetManager, NON_DEPLOYABLE_KINDS, parseCanonicalLockKey };
|
|
1270
|
+
//# sourceMappingURL=chunk-JUZLVRI4.js.map
|
|
1271
|
+
//# sourceMappingURL=chunk-JUZLVRI4.js.map
|