@skaile/workspaces 0.14.0 → 0.15.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +111 -0
- package/dist/asset-manager/index.js +2 -2
- package/dist/asset-manager/installer.js +1 -1
- package/dist/asset-manager/src/index.d.ts.map +1 -1
- package/dist/asset-manager/src/installer.d.ts.map +1 -1
- package/dist/base-assets/connectors/flow/run-flow.js +1 -1
- package/dist/{chunk-OIFGKFZY.js → chunk-67TJEQJE.js} +2 -2
- package/dist/{chunk-OIFGKFZY.js.map → chunk-67TJEQJE.js.map} +1 -1
- package/dist/{chunk-7R4WLTZW.js → chunk-DEZVZSBN.js} +11 -16
- package/dist/chunk-DEZVZSBN.js.map +1 -0
- package/dist/{chunk-4GEVGRWB.js → chunk-ERCOCLW5.js} +9 -11
- package/dist/chunk-ERCOCLW5.js.map +1 -0
- package/dist/{chunk-42OQF7UU.js → chunk-FNCYNUGS.js} +304 -227
- package/dist/chunk-FNCYNUGS.js.map +1 -0
- package/dist/{chunk-DN5476SV.js → chunk-HJV7MHG5.js} +17 -10
- package/dist/chunk-HJV7MHG5.js.map +1 -0
- package/dist/{chunk-VAJB2UJ5.js → chunk-IY4X7PZN.js} +13 -13
- package/dist/chunk-IY4X7PZN.js.map +1 -0
- package/dist/cli/index.js +807 -601
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/src/commands/asset-cmd.d.ts +4 -1
- package/dist/cli/src/commands/asset-cmd.d.ts.map +1 -1
- package/dist/cli/src/commands/library-cmd.d.ts +6 -4
- package/dist/cli/src/commands/library-cmd.d.ts.map +1 -1
- package/dist/cli/src/commands/manage.d.ts +31 -20
- package/dist/cli/src/commands/manage.d.ts.map +1 -1
- package/dist/cli/src/commands/npx.d.ts.map +1 -1
- package/dist/cli/src/commands/project.d.ts +2 -2
- package/dist/cli/src/commands/source-manifest.d.ts +19 -0
- package/dist/cli/src/commands/source-manifest.d.ts.map +1 -0
- package/dist/cli/src/commands/source.d.ts +6 -2
- package/dist/cli/src/commands/source.d.ts.map +1 -1
- package/dist/cli/src/commands/store.d.ts.map +1 -1
- package/dist/cli/src/open-library.d.ts +18 -18
- package/dist/cli/src/open-library.d.ts.map +1 -1
- package/dist/library/index.js +1 -1
- package/dist/library/src/config.d.ts +12 -3
- package/dist/library/src/config.d.ts.map +1 -1
- package/dist/library/src/index.d.ts +7 -8
- package/dist/library/src/index.d.ts.map +1 -1
- package/dist/library/src/library.d.ts +24 -77
- package/dist/library/src/library.d.ts.map +1 -1
- package/dist/library/src/local/db.d.ts +3 -2
- package/dist/library/src/local/db.d.ts.map +1 -1
- package/dist/library/src/local/{user-library-manager.d.ts → library-manager.d.ts} +15 -16
- package/dist/library/src/local/library-manager.d.ts.map +1 -0
- package/dist/library/src/local/library.d.ts +27 -23
- package/dist/library/src/local/library.d.ts.map +1 -1
- package/dist/library/src/local/local-catalog-source.d.ts +5 -5
- package/dist/library/src/local/local-catalog-source.d.ts.map +1 -1
- package/dist/library/src/local/sidecar-paths.d.ts +3 -3
- package/dist/library/src/local/store-paths.d.ts +42 -0
- package/dist/library/src/local/store-paths.d.ts.map +1 -0
- package/dist/library/src/preset/apply.d.ts +2 -2
- package/dist/library/src/preset/apply.d.ts.map +1 -1
- package/dist/library/src/preset/placeholders.d.ts +3 -3
- package/dist/library/src/preset/placeholders.d.ts.map +1 -1
- package/dist/library/src/preset/resolve-item.d.ts +3 -3
- package/dist/library/src/preset/resolve-item.d.ts.map +1 -1
- package/dist/library/src/sync/driver.d.ts +6 -6
- package/dist/library/src/sync/driver.d.ts.map +1 -1
- package/dist/library/src/sync/git-driver.d.ts +6 -6
- package/dist/library/src/sync/git-driver.d.ts.map +1 -1
- package/dist/library/src/sync/local-driver.d.ts +6 -6
- package/dist/library/src/sync/local-driver.d.ts.map +1 -1
- package/dist/library/src/user-library.d.ts +12 -17
- package/dist/library/src/user-library.d.ts.map +1 -1
- package/dist/{open-library-S6FK4N4S.js → open-library-T6RXQJTQ.js} +4 -4
- package/dist/{open-library-S6FK4N4S.js.map → open-library-T6RXQJTQ.js.map} +1 -1
- package/dist/runner/index.js +1 -1
- package/dist/runner/src/composition/resolve.d.ts +3 -3
- package/dist/runner/src/composition/resolve.d.ts.map +1 -1
- package/dist/sdk/asset-manager.js +2 -2
- package/dist/sdk/index.js +1 -1
- package/dist/sdk/runner.js +1 -1
- package/dist/tui/index.js +1 -1
- package/dist/types/src/install-manifest.d.ts +1 -1
- package/package.json +1 -1
- package/dist/chunk-42OQF7UU.js.map +0 -1
- package/dist/chunk-4GEVGRWB.js.map +0 -1
- package/dist/chunk-7R4WLTZW.js.map +0 -1
- package/dist/chunk-DN5476SV.js.map +0 -1
- package/dist/chunk-VAJB2UJ5.js.map +0 -1
- package/dist/cli/src/commands/library-status.d.ts +0 -19
- package/dist/cli/src/commands/library-status.d.ts.map +0 -1
- package/dist/cli/src/commands/source-sidecar.d.ts +0 -6
- package/dist/cli/src/commands/source-sidecar.d.ts.map +0 -1
- package/dist/library/src/local/user-library-manager.d.ts.map +0 -1
- package/dist/library/src/sync/store-driver.d.ts +0 -21
- package/dist/library/src/sync/store-driver.d.ts.map +0 -1
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { discoverAssetsInTree, loadSourceConfig } from './chunk-GKIA2PU5.js';
|
|
2
2
|
import { PresetManifestSchema } from './chunk-NELZIQ2E.js';
|
|
3
|
-
import { __export
|
|
3
|
+
import { __export } from './chunk-NSBPE2FW.js';
|
|
4
4
|
import * as crypto from 'crypto';
|
|
5
5
|
import { createHash } from 'crypto';
|
|
6
|
-
import * as
|
|
7
|
-
import * as
|
|
6
|
+
import * as fs12 from 'fs';
|
|
7
|
+
import * as path4 from 'path';
|
|
8
8
|
import { resolve, join, sep, dirname, isAbsolute } from 'path';
|
|
9
9
|
import { eq, like, and } from 'drizzle-orm';
|
|
10
10
|
import * as z2 from 'zod';
|
|
@@ -13,8 +13,8 @@ import { stringify, parse, parseDocument } from 'yaml';
|
|
|
13
13
|
import { createClient } from '@libsql/client';
|
|
14
14
|
import { drizzle } from 'drizzle-orm/libsql';
|
|
15
15
|
import { sqliteTable, text, integer } from 'drizzle-orm/sqlite-core';
|
|
16
|
-
import { rm, mkdir, writeFile } from 'fs/promises';
|
|
17
16
|
import { spawnSync } from 'child_process';
|
|
17
|
+
import { rm, mkdir, writeFile } from 'fs/promises';
|
|
18
18
|
|
|
19
19
|
// library/src/library.ts
|
|
20
20
|
var KNOWN_ASSET_KINDS = [
|
|
@@ -41,7 +41,7 @@ var LibraryError = class extends Error {
|
|
|
41
41
|
};
|
|
42
42
|
var SourceNotFoundError = class extends LibraryError {
|
|
43
43
|
constructor(id) {
|
|
44
|
-
super(`
|
|
44
|
+
super(`Library not found: ${id}`, "LIBRARY_NOT_FOUND");
|
|
45
45
|
this.name = "SourceNotFoundError";
|
|
46
46
|
}
|
|
47
47
|
};
|
|
@@ -107,19 +107,23 @@ var SkaileConfigSchema = z2.object({
|
|
|
107
107
|
catalog: CatalogConfigSchema.optional(),
|
|
108
108
|
library: LibraryConfigSchema.optional()
|
|
109
109
|
});
|
|
110
|
+
function skaileHomeDir() {
|
|
111
|
+
return path4.join(os.homedir(), ".skaile");
|
|
112
|
+
}
|
|
110
113
|
function defaultLibraryDir() {
|
|
111
|
-
return
|
|
114
|
+
return path4.join(skaileHomeDir(), "libraries");
|
|
115
|
+
}
|
|
116
|
+
function defaultIndexPath() {
|
|
117
|
+
return path4.join(skaileHomeDir(), "index.db");
|
|
112
118
|
}
|
|
113
119
|
function resolveLibraryDir() {
|
|
114
120
|
if (process.env.SKAILE_LIBRARIES_DIR) return process.env.SKAILE_LIBRARIES_DIR;
|
|
115
|
-
if (process.env.SKAILE_LIBRARY_DIR) {
|
|
116
|
-
process.stderr.write(
|
|
117
|
-
"[skaile/library] SKAILE_LIBRARY_DIR is deprecated \u2014 use SKAILE_LIBRARIES_DIR.\n"
|
|
118
|
-
);
|
|
119
|
-
return process.env.SKAILE_LIBRARY_DIR;
|
|
120
|
-
}
|
|
121
121
|
return defaultLibraryDir();
|
|
122
122
|
}
|
|
123
|
+
function resolveIndexPath() {
|
|
124
|
+
if (process.env.SKAILE_INDEX_PATH) return process.env.SKAILE_INDEX_PATH;
|
|
125
|
+
return defaultIndexPath();
|
|
126
|
+
}
|
|
123
127
|
function getConfigDefaults() {
|
|
124
128
|
return {
|
|
125
129
|
catalog: { url: "https://skaile.store", cache_ttl: 86400, framing: "trpc" },
|
|
@@ -128,15 +132,15 @@ function getConfigDefaults() {
|
|
|
128
132
|
}
|
|
129
133
|
var CONFIG_FILENAME = "config.yaml";
|
|
130
134
|
function userConfigPath() {
|
|
131
|
-
return
|
|
135
|
+
return path4.join(os.homedir(), ".skaile", CONFIG_FILENAME);
|
|
132
136
|
}
|
|
133
137
|
function projectConfigPath(projectDir) {
|
|
134
|
-
return
|
|
138
|
+
return path4.join(projectDir, ".skaile", CONFIG_FILENAME);
|
|
135
139
|
}
|
|
136
140
|
function loadConfigFile(filePath) {
|
|
137
|
-
if (!
|
|
141
|
+
if (!fs12.existsSync(filePath)) return null;
|
|
138
142
|
try {
|
|
139
|
-
const content =
|
|
143
|
+
const content = fs12.readFileSync(filePath, "utf-8");
|
|
140
144
|
const raw = parse(content);
|
|
141
145
|
if (!raw || typeof raw !== "object") return null;
|
|
142
146
|
return SkaileConfigSchema.partial().parse(raw);
|
|
@@ -184,11 +188,11 @@ function resolveConfig(opts) {
|
|
|
184
188
|
return resolved;
|
|
185
189
|
}
|
|
186
190
|
function saveConfig(filePath, config) {
|
|
187
|
-
const dir =
|
|
188
|
-
if (!
|
|
189
|
-
|
|
191
|
+
const dir = path4.dirname(filePath);
|
|
192
|
+
if (!fs12.existsSync(dir)) {
|
|
193
|
+
fs12.mkdirSync(dir, { recursive: true });
|
|
190
194
|
}
|
|
191
|
-
|
|
195
|
+
fs12.writeFileSync(filePath, stringify(config, { indent: 2 }), "utf-8");
|
|
192
196
|
}
|
|
193
197
|
|
|
194
198
|
// library/src/local/schema.ts
|
|
@@ -260,6 +264,103 @@ var subscriptions = sqliteTable("subscriptions", {
|
|
|
260
264
|
pinPolicy: text("pin_policy").notNull(),
|
|
261
265
|
subscribedAt: text("subscribed_at").notNull()
|
|
262
266
|
});
|
|
267
|
+
var SKAILE_HOME_ENV = "SKAILE_HOME";
|
|
268
|
+
function getSidecarRoot() {
|
|
269
|
+
const home = process.env[SKAILE_HOME_ENV] ?? path4.join(os.homedir(), ".skaile");
|
|
270
|
+
return path4.join(home, "sources");
|
|
271
|
+
}
|
|
272
|
+
function resolveSidecarPaths(slug) {
|
|
273
|
+
const rootDir = getSidecarRoot();
|
|
274
|
+
const sidecarDir = path4.join(rootDir, slug);
|
|
275
|
+
return {
|
|
276
|
+
rootDir,
|
|
277
|
+
sidecarDir,
|
|
278
|
+
manifestFile: path4.join(sidecarDir, ".skaile-source.yaml"),
|
|
279
|
+
readmeFile: path4.join(sidecarDir, "README.md"),
|
|
280
|
+
lockFile: path4.join(sidecarDir, ".skaile-source.lock.json")
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
function deriveSlug(sourceConfig, sourcePath, existingSlugs) {
|
|
284
|
+
const fromConfig = sourceConfig && typeof sourceConfig.name === "string" ? sourceConfig.name : void 0;
|
|
285
|
+
const base = fromConfig && fromConfig.length > 0 ? slugify(fromConfig) : slugify(path4.basename(sourcePath || "")) || "unnamed-source";
|
|
286
|
+
const taken = new Set(existingSlugs);
|
|
287
|
+
if (!taken.has(base)) return base;
|
|
288
|
+
for (let i = 2; i < 1e3; i++) {
|
|
289
|
+
const candidate = `${base}-${i}`;
|
|
290
|
+
if (!taken.has(candidate)) return candidate;
|
|
291
|
+
}
|
|
292
|
+
return `${base}-${Math.random().toString(36).slice(2, 8)}`;
|
|
293
|
+
}
|
|
294
|
+
function listSidecarSlugsOnDisk() {
|
|
295
|
+
const root = getSidecarRoot();
|
|
296
|
+
if (!fs12.existsSync(root)) return [];
|
|
297
|
+
const out = [];
|
|
298
|
+
for (const entry of fs12.readdirSync(root, { withFileTypes: true })) {
|
|
299
|
+
if (!entry.isDirectory()) continue;
|
|
300
|
+
if (entry.name.startsWith(".")) continue;
|
|
301
|
+
out.push(entry.name);
|
|
302
|
+
}
|
|
303
|
+
return out.sort();
|
|
304
|
+
}
|
|
305
|
+
function slugify(input) {
|
|
306
|
+
return input.toLowerCase().replace(/[^a-z0-9._-]+/g, "-").replace(/-+/g, "-").replace(/^[-.]+|[-.]+$/g, "");
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
// library/src/local/store-paths.ts
|
|
310
|
+
function getStoreRoot() {
|
|
311
|
+
const home = process.env.SKAILE_HOME ?? path4.join(os.homedir(), ".skaile");
|
|
312
|
+
return path4.join(home, "store");
|
|
313
|
+
}
|
|
314
|
+
function getStoreManifestsDir() {
|
|
315
|
+
return path4.join(getStoreRoot(), "manifests");
|
|
316
|
+
}
|
|
317
|
+
function migratedMarkerPath() {
|
|
318
|
+
return path4.join(getStoreRoot(), ".migrated");
|
|
319
|
+
}
|
|
320
|
+
function migrateSidecarsToStoreIfNeeded() {
|
|
321
|
+
const storeRoot = getStoreRoot();
|
|
322
|
+
const marker = migratedMarkerPath();
|
|
323
|
+
if (fs12.existsSync(marker)) return { migrated: 0, storeRoot };
|
|
324
|
+
const sidecarRoot = getSidecarRoot();
|
|
325
|
+
const manifestsDir = getStoreManifestsDir();
|
|
326
|
+
const candidates = [];
|
|
327
|
+
if (fs12.existsSync(sidecarRoot)) {
|
|
328
|
+
for (const entry of fs12.readdirSync(sidecarRoot, { withFileTypes: true })) {
|
|
329
|
+
if (!entry.isDirectory()) continue;
|
|
330
|
+
if (entry.name.startsWith(".")) continue;
|
|
331
|
+
const src = path4.join(sidecarRoot, entry.name, ".skaile-source.yaml");
|
|
332
|
+
if (fs12.existsSync(src)) candidates.push({ src, slug: entry.name });
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
fs12.mkdirSync(manifestsDir, { recursive: true });
|
|
336
|
+
let migrated = 0;
|
|
337
|
+
for (const { src, slug } of candidates) {
|
|
338
|
+
const dest = path4.join(manifestsDir, `${slug}.yaml`);
|
|
339
|
+
if (fs12.existsSync(dest)) continue;
|
|
340
|
+
try {
|
|
341
|
+
fs12.renameSync(src, dest);
|
|
342
|
+
migrated++;
|
|
343
|
+
} catch (err) {
|
|
344
|
+
process.stderr.write(
|
|
345
|
+
`[skaile/store] Failed to migrate sidecar ${slug}: ${err instanceof Error ? err.message : String(err)}
|
|
346
|
+
`
|
|
347
|
+
);
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
if (!fs12.existsSync(path4.join(storeRoot, ".git"))) {
|
|
351
|
+
try {
|
|
352
|
+
spawnSync("git", ["init", "--quiet"], { cwd: storeRoot, stdio: "ignore" });
|
|
353
|
+
fs12.writeFileSync(
|
|
354
|
+
path4.join(storeRoot, ".gitignore"),
|
|
355
|
+
"# Remote-store cache \u2014 local to this machine.\nremote-cache/\n",
|
|
356
|
+
"utf8"
|
|
357
|
+
);
|
|
358
|
+
} catch {
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
fs12.writeFileSync(marker, (/* @__PURE__ */ new Date()).toISOString(), "utf8");
|
|
362
|
+
return { migrated, storeRoot };
|
|
363
|
+
}
|
|
263
364
|
|
|
264
365
|
// library/src/local/db.ts
|
|
265
366
|
var DDL = `
|
|
@@ -337,8 +438,8 @@ async function librariesPresent(client) {
|
|
|
337
438
|
);
|
|
338
439
|
return rs.rows.length > 0;
|
|
339
440
|
}
|
|
340
|
-
function
|
|
341
|
-
const base =
|
|
441
|
+
function slugify2(p) {
|
|
442
|
+
const base = path4.basename(p) || "lib";
|
|
342
443
|
return base.toLowerCase().replace(/[^a-z0-9-]+/g, "-").replace(/^-|-$/g, "") || "lib";
|
|
343
444
|
}
|
|
344
445
|
async function runLibrariesMigration(client) {
|
|
@@ -364,14 +465,14 @@ async function runLibrariesMigration(client) {
|
|
|
364
465
|
});
|
|
365
466
|
const usedNames = /* @__PURE__ */ new Set();
|
|
366
467
|
for (const row of oldRows) {
|
|
367
|
-
const backend = row.type === "github"
|
|
468
|
+
const backend = row.type === "github" || row.type === "catalog" ? "git" : "local";
|
|
368
469
|
const ownership = backend === "local" ? "owner" : "reader";
|
|
369
|
-
const baseSlug =
|
|
470
|
+
const baseSlug = slugify2(row.path ?? row.url);
|
|
370
471
|
let name = baseSlug;
|
|
371
472
|
let i = 2;
|
|
372
473
|
while (usedNames.has(name)) name = `${baseSlug}-${i++}`;
|
|
373
474
|
usedNames.add(name);
|
|
374
|
-
const cfg = backend === "git" ? { url: row.url, branch: row.ref ?? "main", authHint: "ssh" } :
|
|
475
|
+
const cfg = backend === "git" ? { url: row.url, branch: row.ref ?? "main", authHint: "ssh" } : {};
|
|
375
476
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
376
477
|
stmts.push({
|
|
377
478
|
sql: `INSERT INTO libraries
|
|
@@ -403,21 +504,39 @@ async function runLibrariesMigration(client) {
|
|
|
403
504
|
stmts.push({ sql: `DROP TABLE sources;` });
|
|
404
505
|
await client.batch(stmts);
|
|
405
506
|
}
|
|
406
|
-
function
|
|
407
|
-
|
|
408
|
-
const parent =
|
|
409
|
-
|
|
410
|
-
const
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
507
|
+
function assertNoLegacyLibDb(newDbPath) {
|
|
508
|
+
if (fs12.existsSync(newDbPath)) return;
|
|
509
|
+
const parent = path4.dirname(newDbPath);
|
|
510
|
+
const skaileHome = path4.join(os.homedir(), ".skaile");
|
|
511
|
+
const defaultIndexPath2 = path4.join(skaileHome, "index.db");
|
|
512
|
+
const candidates = [];
|
|
513
|
+
if (path4.basename(newDbPath) === "index.db") {
|
|
514
|
+
candidates.push(path4.join(parent, "lib.db"));
|
|
515
|
+
}
|
|
516
|
+
if (newDbPath === defaultIndexPath2) {
|
|
517
|
+
candidates.push(path4.join(skaileHome, "libraries", "lib.db"));
|
|
518
|
+
candidates.push(path4.join(skaileHome, "library", "lib.db"));
|
|
519
|
+
}
|
|
520
|
+
if (path4.basename(parent) === "libraries") {
|
|
521
|
+
candidates.push(path4.join(path4.dirname(parent), "library", "lib.db"));
|
|
522
|
+
}
|
|
523
|
+
for (const legacy of candidates) {
|
|
524
|
+
if (!fs12.existsSync(legacy)) continue;
|
|
525
|
+
throw new Error(
|
|
526
|
+
`Found legacy index database at ${legacy}. The lib.db \u2192 index.db relocation ran for one release and has been removed. Move the file manually to ${newDbPath} (and any -wal / -shm siblings), then retry.`
|
|
527
|
+
);
|
|
417
528
|
}
|
|
418
529
|
}
|
|
419
530
|
async function createLibraryDb(dbPath) {
|
|
420
|
-
|
|
531
|
+
assertNoLegacyLibDb(dbPath);
|
|
532
|
+
try {
|
|
533
|
+
migrateSidecarsToStoreIfNeeded();
|
|
534
|
+
} catch (err) {
|
|
535
|
+
process.stderr.write(
|
|
536
|
+
`[skaile/store] sidecar migration skipped: ${err instanceof Error ? err.message : String(err)}
|
|
537
|
+
`
|
|
538
|
+
);
|
|
539
|
+
}
|
|
421
540
|
const client = createClient({ url: `file:${dbPath}` });
|
|
422
541
|
await client.execute("PRAGMA journal_mode = WAL");
|
|
423
542
|
await client.execute("PRAGMA foreign_keys = ON");
|
|
@@ -425,6 +544,19 @@ async function createLibraryDb(dbPath) {
|
|
|
425
544
|
await runLibrariesMigration(client);
|
|
426
545
|
}
|
|
427
546
|
await client.executeMultiple(DDL);
|
|
547
|
+
if (await librariesPresent(client)) {
|
|
548
|
+
const storeRows = await client.execute({
|
|
549
|
+
sql: "SELECT id, name FROM libraries WHERE backend = ?",
|
|
550
|
+
args: ["store"]
|
|
551
|
+
});
|
|
552
|
+
if (storeRows.rows.length > 0) {
|
|
553
|
+
const names = storeRows.rows.map((r) => String(r.name)).join(", ");
|
|
554
|
+
client.close();
|
|
555
|
+
throw new Error(
|
|
556
|
+
`The 'store' library backend was removed in the 2026-05-27 vocabulary cleanup. Found rows still using it: ${names}. Run \`skaile library link <git-url>\` to convert each, or remove them with \`skaile library remove <name>\`.`
|
|
557
|
+
);
|
|
558
|
+
}
|
|
559
|
+
}
|
|
428
560
|
try {
|
|
429
561
|
await client.execute("ALTER TABLE instances ADD COLUMN source_commit_sha TEXT");
|
|
430
562
|
} catch (err) {
|
|
@@ -511,7 +643,7 @@ async function installFromManifest(opts) {
|
|
|
511
643
|
function escapeLikePrefix(prefix) {
|
|
512
644
|
return prefix.replace(/[%_]/g, "\\$&");
|
|
513
645
|
}
|
|
514
|
-
function
|
|
646
|
+
function rowToLibrary(row) {
|
|
515
647
|
const cfg = (() => {
|
|
516
648
|
try {
|
|
517
649
|
return JSON.parse(row.backendConfig);
|
|
@@ -521,19 +653,17 @@ function rowToSource(row) {
|
|
|
521
653
|
})();
|
|
522
654
|
return {
|
|
523
655
|
id: row.id,
|
|
524
|
-
type: row.backend,
|
|
525
656
|
name: row.name,
|
|
526
657
|
path: row.path,
|
|
527
|
-
|
|
528
|
-
isDefault: row.isDefault,
|
|
658
|
+
backend: row.backend,
|
|
529
659
|
backendConfig: cfg,
|
|
660
|
+
ownership: row.ownership,
|
|
530
661
|
structure: row.structure ?? void 0,
|
|
662
|
+
isDefault: row.isDefault,
|
|
531
663
|
manifestGenerated: row.manifestGenerated,
|
|
532
|
-
|
|
664
|
+
lastSyncAt: row.lastSyncAt ? new Date(row.lastSyncAt) : void 0,
|
|
533
665
|
createdAt: new Date(row.createdAt),
|
|
534
|
-
updatedAt: new Date(row.updatedAt)
|
|
535
|
-
url: typeof cfg.url === "string" ? cfg.url : void 0,
|
|
536
|
-
ref: typeof cfg.branch === "string" ? cfg.branch : void 0
|
|
666
|
+
updatedAt: new Date(row.updatedAt)
|
|
537
667
|
};
|
|
538
668
|
}
|
|
539
669
|
function rowToAssetDef(row) {
|
|
@@ -548,7 +678,7 @@ function rowToAssetDef(row) {
|
|
|
548
678
|
license: row.license ?? void 0,
|
|
549
679
|
category: row.category ?? void 0,
|
|
550
680
|
manifest: JSON.parse(row.manifest),
|
|
551
|
-
|
|
681
|
+
libraryId: row.libraryId ?? void 0,
|
|
552
682
|
kindProviderVersion: row.kindProviderVersion ?? void 0,
|
|
553
683
|
cachedAt: new Date(row.cachedAt),
|
|
554
684
|
updatedAt: new Date(row.updatedAt)
|
|
@@ -576,32 +706,48 @@ function rowToSubscription(row) {
|
|
|
576
706
|
subscribedAt: new Date(row.subscribedAt)
|
|
577
707
|
};
|
|
578
708
|
}
|
|
579
|
-
var
|
|
709
|
+
var LocalIndex = class {
|
|
580
710
|
dbPath;
|
|
581
711
|
dbHandleRef = null;
|
|
582
712
|
dbPromise = null;
|
|
583
713
|
_kindRegistry;
|
|
584
|
-
/** Absolute path to the library
|
|
714
|
+
/** Absolute path to the library checkouts directory. */
|
|
585
715
|
libraryDir;
|
|
586
716
|
/**
|
|
587
|
-
* Construct a
|
|
717
|
+
* Construct a LocalIndex. Synchronous — does not open the DB.
|
|
588
718
|
*
|
|
589
|
-
* @param optionsOrDir - Either a `
|
|
590
|
-
* path (legacy signature,
|
|
719
|
+
* @param optionsOrDir - Either a `LocalIndexOptions` object or a string
|
|
720
|
+
* path (legacy signature: treated as the libraryDir, with the index file
|
|
721
|
+
* landing at `<dir>/index.db`).
|
|
591
722
|
*/
|
|
592
723
|
constructor(optionsOrDir) {
|
|
593
724
|
let dir;
|
|
725
|
+
let dbPath;
|
|
594
726
|
if (typeof optionsOrDir === "string") {
|
|
595
727
|
dir = optionsOrDir;
|
|
728
|
+
dbPath = path4.join(dir, "index.db");
|
|
729
|
+
} else if (optionsOrDir?.indexPath) {
|
|
730
|
+
dbPath = optionsOrDir.indexPath;
|
|
731
|
+
dir = optionsOrDir.libraryDir ?? resolveLibraryDir();
|
|
732
|
+
this._kindRegistry = optionsOrDir.kindRegistry;
|
|
733
|
+
} else if (optionsOrDir?.libraryDir) {
|
|
734
|
+
dir = optionsOrDir.libraryDir;
|
|
735
|
+
dbPath = path4.join(dir, "index.db");
|
|
736
|
+
this._kindRegistry = optionsOrDir.kindRegistry;
|
|
596
737
|
} else {
|
|
597
|
-
dir =
|
|
738
|
+
dir = resolveLibraryDir();
|
|
739
|
+
dbPath = resolveIndexPath();
|
|
598
740
|
this._kindRegistry = optionsOrDir?.kindRegistry;
|
|
599
741
|
}
|
|
600
|
-
if (!
|
|
601
|
-
|
|
742
|
+
if (!fs12.existsSync(dir)) {
|
|
743
|
+
fs12.mkdirSync(dir, { recursive: true });
|
|
744
|
+
}
|
|
745
|
+
const dbParent = path4.dirname(dbPath);
|
|
746
|
+
if (!fs12.existsSync(dbParent)) {
|
|
747
|
+
fs12.mkdirSync(dbParent, { recursive: true });
|
|
602
748
|
}
|
|
603
749
|
this.libraryDir = dir;
|
|
604
|
-
this.dbPath =
|
|
750
|
+
this.dbPath = dbPath;
|
|
605
751
|
}
|
|
606
752
|
/**
|
|
607
753
|
* Lazily open the SQLite DB on first use. The `??=` dedupes concurrent
|
|
@@ -623,15 +769,15 @@ var LocalLibrary = class {
|
|
|
623
769
|
this.dbHandleRef = null;
|
|
624
770
|
this.dbPromise = null;
|
|
625
771
|
}
|
|
626
|
-
/** Internal access for
|
|
772
|
+
/** Internal access for LibraryManager. Do not call from user code. */
|
|
627
773
|
async dbHandle() {
|
|
628
774
|
return this.ensureDb();
|
|
629
775
|
}
|
|
630
|
-
// -- Sources
|
|
776
|
+
// -- Libraries (formerly "Sources") --------------------------------------
|
|
631
777
|
async listSources() {
|
|
632
778
|
const db = await this.ensureDb();
|
|
633
779
|
const rows = await db.select().from(libraries).all();
|
|
634
|
-
return rows.map(
|
|
780
|
+
return rows.map(rowToLibrary);
|
|
635
781
|
}
|
|
636
782
|
async addSource(input) {
|
|
637
783
|
const db = await this.ensureDb();
|
|
@@ -641,16 +787,17 @@ var LocalLibrary = class {
|
|
|
641
787
|
id,
|
|
642
788
|
name: input.name,
|
|
643
789
|
path: input.path,
|
|
644
|
-
backend: input.
|
|
790
|
+
backend: input.backend,
|
|
645
791
|
backendConfig: JSON.stringify(input.backendConfig ?? {}),
|
|
646
|
-
ownership: input.ownership ?? (input.
|
|
792
|
+
ownership: input.ownership ?? (input.backend === "local" ? "owner" : "reader"),
|
|
647
793
|
isDefault: input.isDefault ?? false,
|
|
648
|
-
manifestGenerated: false,
|
|
794
|
+
manifestGenerated: input.manifestGenerated ?? false,
|
|
795
|
+
structure: input.structure ?? null,
|
|
649
796
|
createdAt: now,
|
|
650
797
|
updatedAt: now
|
|
651
798
|
}).run();
|
|
652
799
|
const row = await db.select().from(libraries).where(eq(libraries.id, id)).get();
|
|
653
|
-
return
|
|
800
|
+
return rowToLibrary(row);
|
|
654
801
|
}
|
|
655
802
|
async removeSource(id) {
|
|
656
803
|
const db = await this.ensureDb();
|
|
@@ -664,7 +811,7 @@ var LocalLibrary = class {
|
|
|
664
811
|
if (!existing) throw new SourceNotFoundError(id);
|
|
665
812
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
666
813
|
await db.update(libraries).set({ lastSyncAt: now, updatedAt: now }).where(eq(libraries.id, id)).run();
|
|
667
|
-
return {
|
|
814
|
+
return { libraryId: id, assetsFound: 0, assetsUpdated: 0, errors: [] };
|
|
668
815
|
}
|
|
669
816
|
// -- Asset definitions ---------------------------------------------------
|
|
670
817
|
/**
|
|
@@ -694,7 +841,7 @@ var LocalLibrary = class {
|
|
|
694
841
|
license: def.license ?? null,
|
|
695
842
|
category: def.category ?? null,
|
|
696
843
|
manifest: JSON.stringify(def.manifest),
|
|
697
|
-
libraryId: def.
|
|
844
|
+
libraryId: def.libraryId ?? null,
|
|
698
845
|
kindProviderVersion: providerVersion,
|
|
699
846
|
cachedAt: def.cachedAt?.toISOString() ?? now,
|
|
700
847
|
updatedAt: now
|
|
@@ -710,7 +857,7 @@ var LocalLibrary = class {
|
|
|
710
857
|
license: def.license ?? null,
|
|
711
858
|
category: def.category ?? null,
|
|
712
859
|
manifest: JSON.stringify(def.manifest),
|
|
713
|
-
libraryId: def.
|
|
860
|
+
libraryId: def.libraryId ?? null,
|
|
714
861
|
kindProviderVersion: providerVersion,
|
|
715
862
|
updatedAt: now
|
|
716
863
|
}
|
|
@@ -731,7 +878,7 @@ var LocalLibrary = class {
|
|
|
731
878
|
if (filter.publisher) conditions.push(eq(assetDefinitions.publisher, filter.publisher));
|
|
732
879
|
if (filter.prefix)
|
|
733
880
|
conditions.push(like(assetDefinitions.id, `${escapeLikePrefix(filter.prefix)}%`));
|
|
734
|
-
if (filter.
|
|
881
|
+
if (filter.libraryId) conditions.push(eq(assetDefinitions.libraryId, filter.libraryId));
|
|
735
882
|
const where = conditions.length > 0 ? and(...conditions) : void 0;
|
|
736
883
|
let rows = where ? await db.select().from(assetDefinitions).where(where).all() : await db.select().from(assetDefinitions).all();
|
|
737
884
|
if (filter.offset) rows = rows.slice(filter.offset);
|
|
@@ -781,7 +928,7 @@ var LocalLibrary = class {
|
|
|
781
928
|
* 2. records an {@link Instance} row carrying `sourceCommitSha` so the
|
|
782
929
|
* install is auditable and re-verifiable.
|
|
783
930
|
*
|
|
784
|
-
* Not part of the {@link
|
|
931
|
+
* Not part of the {@link IAssetIndex} interface — `LocalIndex`-only, since
|
|
785
932
|
* the platform variant resolves install bytes differently.
|
|
786
933
|
*
|
|
787
934
|
* @param manifest - The pointer-only install manifest from the Catalog.
|
|
@@ -795,7 +942,7 @@ var LocalLibrary = class {
|
|
|
795
942
|
* @returns The created Instance plus its on-disk install path.
|
|
796
943
|
*/
|
|
797
944
|
async install(manifest, opts) {
|
|
798
|
-
const libraryRoot = opts?.libraryRoot ??
|
|
945
|
+
const libraryRoot = opts?.libraryRoot ?? path4.join(this.libraryDir, "installed");
|
|
799
946
|
const { installPath } = await installFromManifest({
|
|
800
947
|
manifest,
|
|
801
948
|
libraryRoot,
|
|
@@ -907,7 +1054,7 @@ var LocalLibrary = class {
|
|
|
907
1054
|
};
|
|
908
1055
|
|
|
909
1056
|
// library/src/user-library.ts
|
|
910
|
-
var LIBRARY_BACKENDS = ["local", "git"
|
|
1057
|
+
var LIBRARY_BACKENDS = ["local", "git"];
|
|
911
1058
|
var LIBRARY_OWNERSHIPS = ["owner", "contributor", "reader"];
|
|
912
1059
|
var LIBRARY_STRUCTURES = ["flat", "domain"];
|
|
913
1060
|
var LibrarySyncError = class extends Error {
|
|
@@ -1101,35 +1248,8 @@ var LocalSyncDriver = class {
|
|
|
1101
1248
|
}
|
|
1102
1249
|
};
|
|
1103
1250
|
|
|
1104
|
-
// library/src/
|
|
1105
|
-
|
|
1106
|
-
backend = "store";
|
|
1107
|
-
async status(_lib) {
|
|
1108
|
-
return {
|
|
1109
|
-
reachable: true,
|
|
1110
|
-
localChanges: { added: [], modified: [], deleted: [] },
|
|
1111
|
-
notes: ["catalog refresh only \u2014 store write path is a stub in MVP"]
|
|
1112
|
-
};
|
|
1113
|
-
}
|
|
1114
|
-
async pull(_lib, _opts) {
|
|
1115
|
-
return { applied: 0, conflicts: [] };
|
|
1116
|
-
}
|
|
1117
|
-
async push(_lib, _opts) {
|
|
1118
|
-
throw new OperationNotPermittedError("push", "store libraries publish via `publish`");
|
|
1119
|
-
}
|
|
1120
|
-
async propose(_lib, _opts) {
|
|
1121
|
-
throw new OperationNotPermittedError("propose", "store libraries publish via `publish`");
|
|
1122
|
-
}
|
|
1123
|
-
async publish(_lib, _refs, _opts) {
|
|
1124
|
-
throw new LibrarySyncError(
|
|
1125
|
-
"store backend write path is not yet wired (MVP stub)",
|
|
1126
|
-
"remote_error"
|
|
1127
|
-
);
|
|
1128
|
-
}
|
|
1129
|
-
};
|
|
1130
|
-
|
|
1131
|
-
// library/src/local/user-library-manager.ts
|
|
1132
|
-
function rowToUserLibrary(row) {
|
|
1251
|
+
// library/src/local/library-manager.ts
|
|
1252
|
+
function rowToLibrary2(row) {
|
|
1133
1253
|
const cfg = (() => {
|
|
1134
1254
|
try {
|
|
1135
1255
|
return JSON.parse(row.backendConfig);
|
|
@@ -1152,14 +1272,13 @@ function rowToUserLibrary(row) {
|
|
|
1152
1272
|
updatedAt: new Date(row.updatedAt)
|
|
1153
1273
|
};
|
|
1154
1274
|
}
|
|
1155
|
-
var
|
|
1275
|
+
var LibraryManager = class {
|
|
1156
1276
|
constructor(lib) {
|
|
1157
1277
|
this.lib = lib;
|
|
1158
1278
|
}
|
|
1159
1279
|
lib;
|
|
1160
1280
|
localDrv = new LocalSyncDriver();
|
|
1161
1281
|
gitDrv = new GitSyncDriver();
|
|
1162
|
-
storeDrv = new StoreSyncDriver();
|
|
1163
1282
|
/** Resolve the sync driver for a given backend. */
|
|
1164
1283
|
driverFor(backend) {
|
|
1165
1284
|
switch (backend) {
|
|
@@ -1167,8 +1286,6 @@ var UserLibraryManager = class {
|
|
|
1167
1286
|
return this.localDrv;
|
|
1168
1287
|
case "git":
|
|
1169
1288
|
return this.gitDrv;
|
|
1170
|
-
case "store":
|
|
1171
|
-
return this.storeDrv;
|
|
1172
1289
|
}
|
|
1173
1290
|
}
|
|
1174
1291
|
async addLibrary(input) {
|
|
@@ -1198,7 +1315,7 @@ var UserLibraryManager = class {
|
|
|
1198
1315
|
async listLibraries() {
|
|
1199
1316
|
const db = await this.lib.dbHandle();
|
|
1200
1317
|
const rows = await db.select().from(libraries).all();
|
|
1201
|
-
return rows.map(
|
|
1318
|
+
return rows.map(rowToLibrary2).sort((a, b) => a.createdAt.getTime() - b.createdAt.getTime());
|
|
1202
1319
|
}
|
|
1203
1320
|
async getLibrary(nameOrId) {
|
|
1204
1321
|
const db = await this.lib.dbHandle();
|
|
@@ -1206,7 +1323,7 @@ var UserLibraryManager = class {
|
|
|
1206
1323
|
if (!row) {
|
|
1207
1324
|
row = await db.select().from(libraries).where(eq(libraries.id, nameOrId)).get();
|
|
1208
1325
|
}
|
|
1209
|
-
return row ?
|
|
1326
|
+
return row ? rowToLibrary2(row) : null;
|
|
1210
1327
|
}
|
|
1211
1328
|
async requireLibrary(nameOrId) {
|
|
1212
1329
|
const lib = await this.getLibrary(nameOrId);
|
|
@@ -1221,6 +1338,7 @@ var UserLibraryManager = class {
|
|
|
1221
1338
|
};
|
|
1222
1339
|
if (patch.name !== void 0) updates.name = patch.name;
|
|
1223
1340
|
if (patch.path !== void 0) updates.path = patch.path;
|
|
1341
|
+
if (patch.backend !== void 0) updates.backend = patch.backend;
|
|
1224
1342
|
if (patch.backendConfig !== void 0)
|
|
1225
1343
|
updates.backendConfig = JSON.stringify(patch.backendConfig);
|
|
1226
1344
|
if (patch.ownership !== void 0) updates.ownership = patch.ownership;
|
|
@@ -1242,8 +1360,8 @@ var UserLibraryManager = class {
|
|
|
1242
1360
|
const lib = await this.requireLibrary(nameOrId);
|
|
1243
1361
|
const db = await this.lib.dbHandle();
|
|
1244
1362
|
await db.delete(libraries).where(eq(libraries.id, lib.id)).run();
|
|
1245
|
-
if (opts.purge &&
|
|
1246
|
-
|
|
1363
|
+
if (opts.purge && fs12.existsSync(lib.path)) {
|
|
1364
|
+
fs12.rmSync(lib.path, { recursive: true, force: true });
|
|
1247
1365
|
}
|
|
1248
1366
|
}
|
|
1249
1367
|
/**
|
|
@@ -1259,8 +1377,8 @@ var UserLibraryManager = class {
|
|
|
1259
1377
|
(l) => l.isDefault && (l.ownership === "owner" || l.ownership === "contributor")
|
|
1260
1378
|
);
|
|
1261
1379
|
if (writableDefault) return { library: writableDefault, created: false };
|
|
1262
|
-
const personalPath =
|
|
1263
|
-
|
|
1380
|
+
const personalPath = path4.join(librariesDir, "personal");
|
|
1381
|
+
fs12.mkdirSync(personalPath, { recursive: true });
|
|
1264
1382
|
const lib = await this.addLibrary({
|
|
1265
1383
|
name: "personal",
|
|
1266
1384
|
path: personalPath,
|
|
@@ -1278,54 +1396,13 @@ var UserLibraryManager = class {
|
|
|
1278
1396
|
return { library: lib, created: true };
|
|
1279
1397
|
}
|
|
1280
1398
|
};
|
|
1281
|
-
var SKAILE_HOME_ENV = "SKAILE_HOME";
|
|
1282
|
-
function getSidecarRoot() {
|
|
1283
|
-
const home = process.env[SKAILE_HOME_ENV] ?? path5.join(os.homedir(), ".skaile");
|
|
1284
|
-
return path5.join(home, "sources");
|
|
1285
|
-
}
|
|
1286
|
-
function resolveSidecarPaths(slug) {
|
|
1287
|
-
const rootDir = getSidecarRoot();
|
|
1288
|
-
const sidecarDir = path5.join(rootDir, slug);
|
|
1289
|
-
return {
|
|
1290
|
-
rootDir,
|
|
1291
|
-
sidecarDir,
|
|
1292
|
-
manifestFile: path5.join(sidecarDir, ".skaile-source.yaml"),
|
|
1293
|
-
readmeFile: path5.join(sidecarDir, "README.md"),
|
|
1294
|
-
lockFile: path5.join(sidecarDir, ".skaile-source.lock.json")
|
|
1295
|
-
};
|
|
1296
|
-
}
|
|
1297
|
-
function deriveSlug(sourceConfig, sourcePath, existingSlugs) {
|
|
1298
|
-
const fromConfig = sourceConfig && typeof sourceConfig.name === "string" ? sourceConfig.name : void 0;
|
|
1299
|
-
const base = fromConfig && fromConfig.length > 0 ? slugify2(fromConfig) : slugify2(path5.basename(sourcePath || "")) || "unnamed-source";
|
|
1300
|
-
const taken = new Set(existingSlugs);
|
|
1301
|
-
if (!taken.has(base)) return base;
|
|
1302
|
-
for (let i = 2; i < 1e3; i++) {
|
|
1303
|
-
const candidate = `${base}-${i}`;
|
|
1304
|
-
if (!taken.has(candidate)) return candidate;
|
|
1305
|
-
}
|
|
1306
|
-
return `${base}-${Math.random().toString(36).slice(2, 8)}`;
|
|
1307
|
-
}
|
|
1308
|
-
function listSidecarSlugsOnDisk() {
|
|
1309
|
-
const root = getSidecarRoot();
|
|
1310
|
-
if (!fs10.existsSync(root)) return [];
|
|
1311
|
-
const out = [];
|
|
1312
|
-
for (const entry of fs10.readdirSync(root, { withFileTypes: true })) {
|
|
1313
|
-
if (!entry.isDirectory()) continue;
|
|
1314
|
-
if (entry.name.startsWith(".")) continue;
|
|
1315
|
-
out.push(entry.name);
|
|
1316
|
-
}
|
|
1317
|
-
return out.sort();
|
|
1318
|
-
}
|
|
1319
|
-
function slugify2(input) {
|
|
1320
|
-
return input.toLowerCase().replace(/[^a-z0-9._-]+/g, "-").replace(/-+/g, "-").replace(/^[-.]+|[-.]+$/g, "");
|
|
1321
|
-
}
|
|
1322
1399
|
var FALLBACK_USER_NAME = "Skaile CLI";
|
|
1323
1400
|
var FALLBACK_USER_EMAIL = "skaile-cli@local";
|
|
1324
1401
|
var ROOT_README = `# Skaile Sidecar Manifests
|
|
1325
1402
|
|
|
1326
1403
|
This directory is managed by \`skaile source sidecar\` commands. Each
|
|
1327
1404
|
subdirectory is a curated local-overlay manifest for an asset source
|
|
1328
|
-
registered in your
|
|
1405
|
+
registered in your LocalIndex at \`~/.skaile/index.db\`.
|
|
1329
1406
|
|
|
1330
1407
|
You can push this repo to your own remote (e.g. a private dotfiles repo)
|
|
1331
1408
|
to share or back up your sidecars across machines:
|
|
@@ -1363,21 +1440,21 @@ var SidecarGit = class {
|
|
|
1363
1440
|
* @docLink packages/library/concepts#sidecar-git
|
|
1364
1441
|
*/
|
|
1365
1442
|
async ensureInitialized() {
|
|
1366
|
-
if (!
|
|
1367
|
-
|
|
1443
|
+
if (!fs12.existsSync(this.rootDir)) {
|
|
1444
|
+
fs12.mkdirSync(this.rootDir, { recursive: true });
|
|
1368
1445
|
}
|
|
1369
|
-
const gitDir =
|
|
1370
|
-
const freshRepo = !
|
|
1446
|
+
const gitDir = path4.join(this.rootDir, ".git");
|
|
1447
|
+
const freshRepo = !fs12.existsSync(gitDir);
|
|
1371
1448
|
if (freshRepo) {
|
|
1372
1449
|
const init = this.spawn(["init", "-b", "main"]);
|
|
1373
1450
|
if (init.exitCode !== 0) {
|
|
1374
1451
|
throw new Error(`git init failed: ${init.stderr || init.stdout}`);
|
|
1375
1452
|
}
|
|
1376
1453
|
}
|
|
1377
|
-
const attrsPath =
|
|
1378
|
-
if (!
|
|
1379
|
-
const readmePath =
|
|
1380
|
-
if (!
|
|
1454
|
+
const attrsPath = path4.join(this.rootDir, ".gitattributes");
|
|
1455
|
+
if (!fs12.existsSync(attrsPath)) fs12.writeFileSync(attrsPath, GITATTRIBUTES, "utf-8");
|
|
1456
|
+
const readmePath = path4.join(this.rootDir, "README.md");
|
|
1457
|
+
if (!fs12.existsSync(readmePath)) fs12.writeFileSync(readmePath, ROOT_README, "utf-8");
|
|
1381
1458
|
if (!this.hasGlobalGitConfig("user.name")) {
|
|
1382
1459
|
this.spawn(["config", "user.name", FALLBACK_USER_NAME]);
|
|
1383
1460
|
}
|
|
@@ -1402,8 +1479,8 @@ var SidecarGit = class {
|
|
|
1402
1479
|
*/
|
|
1403
1480
|
async commit(slug, message, opts) {
|
|
1404
1481
|
if (opts?.skip) return;
|
|
1405
|
-
const slugDir =
|
|
1406
|
-
if (
|
|
1482
|
+
const slugDir = path4.join(this.rootDir, slug);
|
|
1483
|
+
if (fs12.existsSync(slugDir)) {
|
|
1407
1484
|
this.spawn(["add", "--", slug]);
|
|
1408
1485
|
} else {
|
|
1409
1486
|
this.spawn(["add", "-A"]);
|
|
@@ -1513,42 +1590,42 @@ function parseWorkspaceV2(raw) {
|
|
|
1513
1590
|
return WorkspaceConfigV2Schema.parse(raw);
|
|
1514
1591
|
}
|
|
1515
1592
|
function loadWorkspaceV2(dir, filename = "skaile.yaml") {
|
|
1516
|
-
const filePath =
|
|
1517
|
-
if (!
|
|
1518
|
-
const content =
|
|
1593
|
+
const filePath = path4.join(dir, filename);
|
|
1594
|
+
if (!fs12.existsSync(filePath)) return null;
|
|
1595
|
+
const content = fs12.readFileSync(filePath, "utf-8");
|
|
1519
1596
|
const raw = parse(content);
|
|
1520
1597
|
if (!raw || typeof raw !== "object") return null;
|
|
1521
1598
|
return parseWorkspaceV2(raw);
|
|
1522
1599
|
}
|
|
1523
1600
|
function saveWorkspaceV2(dir, v2, filename = "skaile.yaml") {
|
|
1524
|
-
const filePath =
|
|
1601
|
+
const filePath = path4.join(dir, filename);
|
|
1525
1602
|
let existing = {};
|
|
1526
|
-
if (
|
|
1527
|
-
const content =
|
|
1603
|
+
if (fs12.existsSync(filePath)) {
|
|
1604
|
+
const content = fs12.readFileSync(filePath, "utf-8");
|
|
1528
1605
|
existing = parse(content) ?? {};
|
|
1529
1606
|
}
|
|
1530
1607
|
existing.version = 2;
|
|
1531
1608
|
if (v2.library !== void 0) existing.library = v2.library;
|
|
1532
1609
|
if (v2.presets_applied !== void 0) existing.presets_applied = v2.presets_applied;
|
|
1533
|
-
if (!
|
|
1534
|
-
|
|
1610
|
+
if (!fs12.existsSync(dir)) {
|
|
1611
|
+
fs12.mkdirSync(dir, { recursive: true });
|
|
1535
1612
|
}
|
|
1536
|
-
|
|
1613
|
+
fs12.writeFileSync(filePath, stringify(existing, { indent: 2 }), "utf-8");
|
|
1537
1614
|
}
|
|
1538
1615
|
var LOCK_FILENAME = "skaile.lock.yaml";
|
|
1539
1616
|
function loadLockFile(dir) {
|
|
1540
|
-
const filePath =
|
|
1541
|
-
if (!
|
|
1542
|
-
const content =
|
|
1617
|
+
const filePath = path4.join(dir, LOCK_FILENAME);
|
|
1618
|
+
if (!fs12.existsSync(filePath)) return null;
|
|
1619
|
+
const content = fs12.readFileSync(filePath, "utf-8");
|
|
1543
1620
|
const raw = parse(content);
|
|
1544
1621
|
return LockFileSchema.parse(raw);
|
|
1545
1622
|
}
|
|
1546
1623
|
function saveLockFile(dir, lock) {
|
|
1547
|
-
const filePath =
|
|
1548
|
-
if (!
|
|
1549
|
-
|
|
1624
|
+
const filePath = path4.join(dir, LOCK_FILENAME);
|
|
1625
|
+
if (!fs12.existsSync(dir)) {
|
|
1626
|
+
fs12.mkdirSync(dir, { recursive: true });
|
|
1550
1627
|
}
|
|
1551
|
-
|
|
1628
|
+
fs12.writeFileSync(
|
|
1552
1629
|
filePath,
|
|
1553
1630
|
`# Auto-generated by skaile. Do not edit manually.
|
|
1554
1631
|
${stringify(lock, { indent: 2 })}`,
|
|
@@ -1565,17 +1642,17 @@ function createEmptyLockFile() {
|
|
|
1565
1642
|
};
|
|
1566
1643
|
}
|
|
1567
1644
|
function detectWorkspaceVersion(dir, filename = "skaile.yaml") {
|
|
1568
|
-
const filePath =
|
|
1569
|
-
if (!
|
|
1570
|
-
const content =
|
|
1645
|
+
const filePath = path4.join(dir, filename);
|
|
1646
|
+
if (!fs12.existsSync(filePath)) return null;
|
|
1647
|
+
const content = fs12.readFileSync(filePath, "utf-8");
|
|
1571
1648
|
const raw = parse(content);
|
|
1572
1649
|
if (!raw || typeof raw !== "object") return null;
|
|
1573
1650
|
return raw.version === 2 ? 2 : 1;
|
|
1574
1651
|
}
|
|
1575
1652
|
var MANIFEST_FILENAME = ".skaile-source.yaml";
|
|
1576
1653
|
async function writeManifestIfMissing(input) {
|
|
1577
|
-
const manifestPath =
|
|
1578
|
-
if (
|
|
1654
|
+
const manifestPath = path4.join(input.libraryPath, MANIFEST_FILENAME);
|
|
1655
|
+
if (fs12.existsSync(manifestPath)) return { wrote: false, manifestPath };
|
|
1579
1656
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
1580
1657
|
const yaml = `# Generated by skaile library add on ${now}
|
|
1581
1658
|
# Edit by hand to inline discovered assets; or run \`skaile library refresh-manifest\`.
|
|
@@ -1584,13 +1661,13 @@ structure: ${input.structure}
|
|
|
1584
1661
|
publisher: ""
|
|
1585
1662
|
assets: []
|
|
1586
1663
|
`;
|
|
1587
|
-
|
|
1664
|
+
fs12.writeFileSync(manifestPath, yaml, "utf-8");
|
|
1588
1665
|
if (input.ownership !== "owner") {
|
|
1589
|
-
const excludePath =
|
|
1590
|
-
if (
|
|
1591
|
-
const current =
|
|
1666
|
+
const excludePath = path4.join(input.libraryPath, ".git", "info", "exclude");
|
|
1667
|
+
if (fs12.existsSync(path4.dirname(excludePath))) {
|
|
1668
|
+
const current = fs12.existsSync(excludePath) ? fs12.readFileSync(excludePath, "utf-8") : "";
|
|
1592
1669
|
if (!current.includes(MANIFEST_FILENAME)) {
|
|
1593
|
-
|
|
1670
|
+
fs12.writeFileSync(
|
|
1594
1671
|
excludePath,
|
|
1595
1672
|
(current.endsWith("\n") || current === "" ? current : `${current}
|
|
1596
1673
|
`) + `# skaile-managed local-overlay manifest
|
|
@@ -1605,11 +1682,11 @@ ${MANIFEST_FILENAME}
|
|
|
1605
1682
|
}
|
|
1606
1683
|
function migrateWorkspaceConfig(dir, opts) {
|
|
1607
1684
|
const filename = opts?.filename ?? "skaile.yaml";
|
|
1608
|
-
const filePath =
|
|
1609
|
-
if (!
|
|
1685
|
+
const filePath = path4.join(dir, filename);
|
|
1686
|
+
if (!fs12.existsSync(filePath)) {
|
|
1610
1687
|
return { migrated: false, version: 1, warnings: ["No skaile.yaml found"] };
|
|
1611
1688
|
}
|
|
1612
|
-
const content =
|
|
1689
|
+
const content = fs12.readFileSync(filePath, "utf-8");
|
|
1613
1690
|
const raw = parse(content);
|
|
1614
1691
|
if (!raw || typeof raw !== "object") {
|
|
1615
1692
|
return { migrated: false, version: 1, warnings: ["Invalid YAML content"] };
|
|
@@ -1641,7 +1718,7 @@ function migrateWorkspaceConfig(dir, opts) {
|
|
|
1641
1718
|
} else {
|
|
1642
1719
|
doc.set("version", 2);
|
|
1643
1720
|
}
|
|
1644
|
-
|
|
1721
|
+
fs12.writeFileSync(filePath, doc.toString(), "utf-8");
|
|
1645
1722
|
}
|
|
1646
1723
|
return {
|
|
1647
1724
|
migrated: !opts?.dryRun,
|
|
@@ -1741,11 +1818,11 @@ var LocalCatalogSource = class {
|
|
|
1741
1818
|
sidecarPath;
|
|
1742
1819
|
async resolve(ref) {
|
|
1743
1820
|
const def = await this.library.getAssetDef(ref);
|
|
1744
|
-
if (!def || def.
|
|
1821
|
+
if (!def || def.libraryId !== this.sourceId) return null;
|
|
1745
1822
|
return defToCatalogAsset(def);
|
|
1746
1823
|
}
|
|
1747
1824
|
async listAssets(filter) {
|
|
1748
|
-
const libraryFilter = {
|
|
1825
|
+
const libraryFilter = { libraryId: this.sourceId };
|
|
1749
1826
|
if (filter?.kind) libraryFilter.kind = filter.kind;
|
|
1750
1827
|
if (filter?.publisher) libraryFilter.publisher = filter.publisher;
|
|
1751
1828
|
if (filter?.prefix) libraryFilter.prefix = filter.prefix;
|
|
@@ -1764,7 +1841,7 @@ var LocalCatalogSource = class {
|
|
|
1764
1841
|
* Sync: discover assets in the source directory and cache them in the library.
|
|
1765
1842
|
*
|
|
1766
1843
|
* Runs the discovery pipeline (glob -> parse -> filter -> hash -> requires)
|
|
1767
|
-
* and upserts each discovered asset into the
|
|
1844
|
+
* and upserts each discovered asset into the LocalIndex cache.
|
|
1768
1845
|
*
|
|
1769
1846
|
* @returns Discovery statistics and any errors encountered.
|
|
1770
1847
|
*/
|
|
@@ -1793,7 +1870,7 @@ var LocalCatalogSource = class {
|
|
|
1793
1870
|
license: typeof asset.manifest.license === "string" ? asset.manifest.license : void 0,
|
|
1794
1871
|
category: typeof asset.manifest.category === "string" ? asset.manifest.category : void 0,
|
|
1795
1872
|
manifest: asset.manifest,
|
|
1796
|
-
|
|
1873
|
+
libraryId: this.sourceId,
|
|
1797
1874
|
cachedAt: /* @__PURE__ */ new Date(),
|
|
1798
1875
|
updatedAt: /* @__PURE__ */ new Date()
|
|
1799
1876
|
});
|
|
@@ -1823,10 +1900,10 @@ function defToCatalogAsset(def) {
|
|
|
1823
1900
|
};
|
|
1824
1901
|
}
|
|
1825
1902
|
function loadSourceConfigIfPresent(rootPath) {
|
|
1826
|
-
const configPath =
|
|
1827
|
-
if (!
|
|
1903
|
+
const configPath = path4.join(rootPath, ".skaile-source.yaml");
|
|
1904
|
+
if (!fs12.existsSync(configPath)) return void 0;
|
|
1828
1905
|
try {
|
|
1829
|
-
const content =
|
|
1906
|
+
const content = fs12.readFileSync(configPath, "utf-8");
|
|
1830
1907
|
const result = loadSourceConfig(content);
|
|
1831
1908
|
if (!result.ok) return void 0;
|
|
1832
1909
|
return result.config;
|
|
@@ -1835,7 +1912,7 @@ function loadSourceConfigIfPresent(rootPath) {
|
|
|
1835
1912
|
}
|
|
1836
1913
|
}
|
|
1837
1914
|
function defaultCacheDir() {
|
|
1838
|
-
return
|
|
1915
|
+
return path4.join(os.homedir(), ".skaile", "catalog-cache");
|
|
1839
1916
|
}
|
|
1840
1917
|
var INDEX_FILE = "index.json";
|
|
1841
1918
|
var TARBALL_DIR = "tarballs";
|
|
@@ -1907,22 +1984,22 @@ var CatalogCache = class {
|
|
|
1907
1984
|
// ── public: tarball cache ───────────────────────────────────────────────
|
|
1908
1985
|
/** Absolute path where a tarball with `sha256` would be cached. */
|
|
1909
1986
|
tarballPath(sha256) {
|
|
1910
|
-
return
|
|
1987
|
+
return path4.join(this.dir, TARBALL_DIR, `${sha256}.tgz`);
|
|
1911
1988
|
}
|
|
1912
1989
|
/** Read a cached tarball from disk if present, otherwise `null`. */
|
|
1913
1990
|
readTarball(sha256) {
|
|
1914
1991
|
const p = this.tarballPath(sha256);
|
|
1915
|
-
if (!
|
|
1916
|
-
return
|
|
1992
|
+
if (!fs12.existsSync(p)) return null;
|
|
1993
|
+
return fs12.readFileSync(p);
|
|
1917
1994
|
}
|
|
1918
1995
|
/** Persist a tarball blob to disk (atomic write). */
|
|
1919
1996
|
writeTarball(sha256, bytes) {
|
|
1920
|
-
const dir =
|
|
1921
|
-
if (!
|
|
1997
|
+
const dir = path4.join(this.dir, TARBALL_DIR);
|
|
1998
|
+
if (!fs12.existsSync(dir)) fs12.mkdirSync(dir, { recursive: true });
|
|
1922
1999
|
const finalPath = this.tarballPath(sha256);
|
|
1923
2000
|
const tmpPath = `${finalPath}.${process.pid}.${Math.random().toString(36).slice(2)}.tmp`;
|
|
1924
|
-
|
|
1925
|
-
|
|
2001
|
+
fs12.writeFileSync(tmpPath, bytes);
|
|
2002
|
+
fs12.renameSync(tmpPath, finalPath);
|
|
1926
2003
|
}
|
|
1927
2004
|
// ── public: invalidation ────────────────────────────────────────────────
|
|
1928
2005
|
/**
|
|
@@ -1941,9 +2018,9 @@ var CatalogCache = class {
|
|
|
1941
2018
|
*/
|
|
1942
2019
|
invalidateEverything() {
|
|
1943
2020
|
this.invalidateAll();
|
|
1944
|
-
const tarballDir =
|
|
1945
|
-
if (
|
|
1946
|
-
|
|
2021
|
+
const tarballDir = path4.join(this.dir, TARBALL_DIR);
|
|
2022
|
+
if (fs12.existsSync(tarballDir)) {
|
|
2023
|
+
fs12.rmSync(tarballDir, { recursive: true, force: true });
|
|
1947
2024
|
}
|
|
1948
2025
|
}
|
|
1949
2026
|
/** Return whether `ttlMs` is zero (air-gapped mode). */
|
|
@@ -1952,22 +2029,22 @@ var CatalogCache = class {
|
|
|
1952
2029
|
}
|
|
1953
2030
|
// ── private ─────────────────────────────────────────────────────────────
|
|
1954
2031
|
ensureDir() {
|
|
1955
|
-
if (!
|
|
1956
|
-
const tarballDir =
|
|
1957
|
-
if (!
|
|
2032
|
+
if (!fs12.existsSync(this.dir)) fs12.mkdirSync(this.dir, { recursive: true });
|
|
2033
|
+
const tarballDir = path4.join(this.dir, TARBALL_DIR);
|
|
2034
|
+
if (!fs12.existsSync(tarballDir)) fs12.mkdirSync(tarballDir, { recursive: true });
|
|
1958
2035
|
}
|
|
1959
2036
|
indexPath() {
|
|
1960
|
-
return
|
|
2037
|
+
return path4.join(this.dir, INDEX_FILE);
|
|
1961
2038
|
}
|
|
1962
2039
|
loadIndex() {
|
|
1963
2040
|
if (this.index) return this.index;
|
|
1964
2041
|
const p = this.indexPath();
|
|
1965
|
-
if (!
|
|
2042
|
+
if (!fs12.existsSync(p)) {
|
|
1966
2043
|
this.index = { version: 1, resolve: {}, list: {} };
|
|
1967
2044
|
return this.index;
|
|
1968
2045
|
}
|
|
1969
2046
|
try {
|
|
1970
|
-
const raw = JSON.parse(
|
|
2047
|
+
const raw = JSON.parse(fs12.readFileSync(p, "utf-8"));
|
|
1971
2048
|
if (raw && typeof raw === "object" && raw.version === 1) {
|
|
1972
2049
|
this.index = {
|
|
1973
2050
|
version: 1,
|
|
@@ -1985,8 +2062,8 @@ var CatalogCache = class {
|
|
|
1985
2062
|
this.index = idx;
|
|
1986
2063
|
const p = this.indexPath();
|
|
1987
2064
|
const tmp = `${p}.${process.pid}.${Math.random().toString(36).slice(2)}.tmp`;
|
|
1988
|
-
|
|
1989
|
-
|
|
2065
|
+
fs12.writeFileSync(tmp, JSON.stringify(idx, null, 2), "utf-8");
|
|
2066
|
+
fs12.renameSync(tmp, p);
|
|
1990
2067
|
}
|
|
1991
2068
|
};
|
|
1992
2069
|
function filterKey(filter) {
|
|
@@ -2718,11 +2795,11 @@ function validateKnowledge(data) {
|
|
|
2718
2795
|
};
|
|
2719
2796
|
}
|
|
2720
2797
|
function collectDirRecursive(baseDir, relativeDir) {
|
|
2721
|
-
const full =
|
|
2722
|
-
if (!
|
|
2798
|
+
const full = path4.join(baseDir, relativeDir);
|
|
2799
|
+
if (!fs12.existsSync(full) || !fs12.statSync(full).isDirectory()) return [];
|
|
2723
2800
|
const results = [];
|
|
2724
|
-
for (const entry of
|
|
2725
|
-
const rel =
|
|
2801
|
+
for (const entry of fs12.readdirSync(full, { withFileTypes: true })) {
|
|
2802
|
+
const rel = path4.posix.join(relativeDir, entry.name);
|
|
2726
2803
|
if (entry.isDirectory()) {
|
|
2727
2804
|
results.push(...collectDirRecursive(baseDir, rel));
|
|
2728
2805
|
} else if (entry.isFile()) {
|
|
@@ -2749,8 +2826,8 @@ var knowledgeKindProvider = {
|
|
|
2749
2826
|
return validateKnowledge(data);
|
|
2750
2827
|
},
|
|
2751
2828
|
defaultFileFilter(manifestPath) {
|
|
2752
|
-
const dir =
|
|
2753
|
-
const manifestName =
|
|
2829
|
+
const dir = path4.dirname(manifestPath);
|
|
2830
|
+
const manifestName = path4.basename(manifestPath);
|
|
2754
2831
|
const files = [manifestName];
|
|
2755
2832
|
files.push(...collectDirRecursive(dir, "documents"));
|
|
2756
2833
|
files.sort();
|
|
@@ -3128,8 +3205,8 @@ function resolveTemplate(template, context) {
|
|
|
3128
3205
|
});
|
|
3129
3206
|
return { value: result, hasSecret: false };
|
|
3130
3207
|
}
|
|
3131
|
-
function setNestedValue(obj,
|
|
3132
|
-
const parts =
|
|
3208
|
+
function setNestedValue(obj, path14, value) {
|
|
3209
|
+
const parts = path14.split(".");
|
|
3133
3210
|
let current = obj;
|
|
3134
3211
|
for (let i = 0; i < parts.length - 1; i++) {
|
|
3135
3212
|
const key = parts[i];
|
|
@@ -3430,6 +3507,6 @@ function deepEqual(a, b) {
|
|
|
3430
3507
|
return JSON.stringify(a) === JSON.stringify(b);
|
|
3431
3508
|
}
|
|
3432
3509
|
|
|
3433
|
-
export { CatalogCache, CatalogConfigSchema, CatalogHttpError, DuplicateLibraryNameError, DuplicateSubscriptionError, GitSyncDriver, InstanceHasConsumersError, InstanceNotFoundError, InterpolationError, KNOWN_ASSET_KINDS, KnowledgeManifestSchema, LIBRARY_BACKENDS, LIBRARY_OWNERSHIPS, LIBRARY_STRUCTURES, LOCAL_CATALOG_URL, LibraryConfigSchema, LibraryError, LibraryInstanceRefSchema, LibrarySectionSchema, LibrarySyncError, LocalCatalogSource,
|
|
3434
|
-
//# sourceMappingURL=chunk-
|
|
3435
|
-
//# sourceMappingURL=chunk-
|
|
3510
|
+
export { CatalogCache, CatalogConfigSchema, CatalogHttpError, DuplicateLibraryNameError, DuplicateSubscriptionError, GitSyncDriver, InstanceHasConsumersError, InstanceNotFoundError, InterpolationError, KNOWN_ASSET_KINDS, KnowledgeManifestSchema, LIBRARY_BACKENDS, LIBRARY_OWNERSHIPS, LIBRARY_STRUCTURES, LOCAL_CATALOG_URL, LibraryConfigSchema, LibraryError, LibraryInstanceRefSchema, LibraryManager, LibrarySectionSchema, LibrarySyncError, LocalCatalogSource, LocalIndex, LocalSyncDriver, LockFileSchema, LockSubscriptionSchema, OfflineError, OperationNotPermittedError, PIN_POLICIES, PinPolicySchema, PresetAppliedSchema, PresetExpandedSchema, RemoteCatalogSource, RequiresEdgeSchema, RestCatalogSource, SidecarGit, SkaileConfigSchema, SourceNotFoundError, SubscriptionNotFoundError, TarballHashMismatchError, UserLibraryNotFoundError, WorkspaceConfigV2Schema, applyNonStructuralUpgrade, applyPreset, applyPresetFromData, classifyRef, createEmptyLockFile, deriveSlug, detectChanges, detectNestedPresetRefs, detectWorkspaceVersion, evaluateUpgrade, extractLibraryInstanceId, extractReferencedKeys, filterKey, getConfigDefaults, getDefaultValue, getSidecarRoot, getStoreManifestsDir, getStoreRoot, hasInterpolationTokens, installFromManifest, interpolate, isLocalCatalogUrl, isSecretPlaceholder, knowledgeKindProvider, listSidecarSlugsOnDisk, loadLockFile, loadWorkspaceV2, migrateSidecarsToStoreIfNeeded, migrateWorkspaceConfig, parsePreset, parsePresetYaml, parseWorkspaceV2, projectConfigPath, queryInstancePickerChoices, resolveAllItems, resolveConfig, resolveIndexPath, resolveItem, resolveLibraryDir, resolvePin, resolveSidecarPaths, saveConfig, saveLockFile, saveWorkspaceV2, sha256Hex, skaileHomeDir, storeSecrets, trpcGetUrl, userConfigPath, validateAllPlaceholders, validateKnowledge, validateNestingDepth, validatePlaceholder, writeManifestIfMissing };
|
|
3511
|
+
//# sourceMappingURL=chunk-FNCYNUGS.js.map
|
|
3512
|
+
//# sourceMappingURL=chunk-FNCYNUGS.js.map
|