@swarmvaultai/cli 0.2.2 → 0.4.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/dist/index.js +76 -23
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
getWatchStatus,
|
|
20
20
|
importInbox,
|
|
21
21
|
ingestDirectory,
|
|
22
|
-
|
|
22
|
+
ingestInputDetailed,
|
|
23
23
|
initVault,
|
|
24
24
|
installAgent,
|
|
25
25
|
installGitHooks,
|
|
@@ -28,6 +28,7 @@ import {
|
|
|
28
28
|
listCandidates,
|
|
29
29
|
listGodNodes,
|
|
30
30
|
listManagedSourceRecords,
|
|
31
|
+
listManifests,
|
|
31
32
|
listSchedules,
|
|
32
33
|
loadVaultConfig,
|
|
33
34
|
pathGraphVault,
|
|
@@ -38,6 +39,8 @@ import {
|
|
|
38
39
|
readApproval,
|
|
39
40
|
rejectApproval,
|
|
40
41
|
reloadManagedSources,
|
|
42
|
+
reviewManagedSource,
|
|
43
|
+
reviewSourceScope,
|
|
41
44
|
runSchedule,
|
|
42
45
|
runWatchCycle,
|
|
43
46
|
serveSchedules,
|
|
@@ -221,9 +224,9 @@ program.name("swarmvault").description("SwarmVault is a local-first knowledge co
|
|
|
221
224
|
function readCliVersion() {
|
|
222
225
|
try {
|
|
223
226
|
const packageJson = JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf8"));
|
|
224
|
-
return typeof packageJson.version === "string" && packageJson.version.trim() ? packageJson.version : "0.
|
|
227
|
+
return typeof packageJson.version === "string" && packageJson.version.trim() ? packageJson.version : "0.4.0";
|
|
225
228
|
} catch {
|
|
226
|
-
return "0.
|
|
229
|
+
return "0.4.0";
|
|
227
230
|
}
|
|
228
231
|
}
|
|
229
232
|
function parsePositiveInt(value, fallback) {
|
|
@@ -281,7 +284,7 @@ program.command("init").description("Initialize a SwarmVault workspace in the cu
|
|
|
281
284
|
log("Initialized SwarmVault workspace.");
|
|
282
285
|
}
|
|
283
286
|
});
|
|
284
|
-
program.command("ingest").description("Ingest a local file path, directory path, or URL into the raw SwarmVault workspace.").argument("<input>", "Local file path, directory path, or URL").option("--include-assets", "Download remote image assets when ingesting URLs", true).option("--no-include-assets", "Skip downloading remote image assets when ingesting URLs").option("--max-asset-size <bytes>", "Maximum number of bytes to fetch for a single remote image asset").option("--repo-root <path>", "Override the detected repo root when ingesting a directory").option("--include <glob...>", "Only ingest files matching one or more glob patterns").option("--exclude <glob...>", "Skip files matching one or more glob patterns").option("--max-files <n>", "Maximum number of files to ingest from a directory").option("--include-third-party", "Also ingest repo files classified as third-party", false).option("--include-resources", "Also ingest repo files classified as resources", false).option("--include-generated", "Also ingest repo files classified as generated output", false).option("--no-gitignore", "Ignore .gitignore rules when ingesting a directory").action(
|
|
287
|
+
program.command("ingest").description("Ingest a local file path, directory path, or URL into the raw SwarmVault workspace.").argument("<input>", "Local file path, directory path, or URL").option("--review", "Stage a source review artifact after ingest and compile", false).option("--include-assets", "Download remote image assets when ingesting URLs", true).option("--no-include-assets", "Skip downloading remote image assets when ingesting URLs").option("--max-asset-size <bytes>", "Maximum number of bytes to fetch for a single remote image asset").option("--repo-root <path>", "Override the detected repo root when ingesting a directory").option("--include <glob...>", "Only ingest files matching one or more glob patterns").option("--exclude <glob...>", "Skip files matching one or more glob patterns").option("--max-files <n>", "Maximum number of files to ingest from a directory").option("--include-third-party", "Also ingest repo files classified as third-party", false).option("--include-resources", "Also ingest repo files classified as resources", false).option("--include-generated", "Also ingest repo files classified as generated output", false).option("--no-gitignore", "Ignore .gitignore rules when ingesting a directory").action(
|
|
285
288
|
async (input, options) => {
|
|
286
289
|
const maxAssetSize = typeof options.maxAssetSize === "string" && options.maxAssetSize.trim() ? parsePositiveInt(options.maxAssetSize, 0) || void 0 : void 0;
|
|
287
290
|
const maxFiles = typeof options.maxFiles === "string" && options.maxFiles.trim() ? parsePositiveInt(options.maxFiles, 0) || void 0 : void 0;
|
|
@@ -305,20 +308,59 @@ program.command("ingest").description("Ingest a local file path, directory path,
|
|
|
305
308
|
(fs) => fs.stat(input).then((stat) => stat.isDirectory() ? ingestDirectory(process2.cwd(), input, commonOptions) : null).catch(() => null)
|
|
306
309
|
) : null;
|
|
307
310
|
if (directoryResult) {
|
|
311
|
+
const review3 = options.review && (directoryResult.imported.length || directoryResult.updated.length) ? await (async () => {
|
|
312
|
+
await compileVault(process2.cwd(), {});
|
|
313
|
+
const pathModule = await import("path");
|
|
314
|
+
const absoluteInput = pathModule.resolve(process2.cwd(), input);
|
|
315
|
+
const sourceIds = (await listManifests(process2.cwd())).filter((manifest) => {
|
|
316
|
+
if (!manifest.originalPath) {
|
|
317
|
+
return false;
|
|
318
|
+
}
|
|
319
|
+
const relative = pathModule.relative(absoluteInput, pathModule.resolve(manifest.originalPath));
|
|
320
|
+
return relative === "" || !relative.startsWith("..") && !pathModule.isAbsolute(relative);
|
|
321
|
+
}).map((manifest) => manifest.sourceId);
|
|
322
|
+
return sourceIds.length ? await reviewSourceScope(process2.cwd(), {
|
|
323
|
+
id: `directory-${absoluteInput.split(pathModule.sep).pop() ?? "source"}`,
|
|
324
|
+
title: absoluteInput.split(pathModule.sep).pop() ?? absoluteInput,
|
|
325
|
+
sourceIds
|
|
326
|
+
}) : void 0;
|
|
327
|
+
})() : void 0;
|
|
308
328
|
if (isJson()) {
|
|
309
|
-
emitJson(directoryResult);
|
|
329
|
+
emitJson(review3 ? { ingest: directoryResult, review: review3 } : directoryResult);
|
|
310
330
|
} else {
|
|
311
331
|
log(
|
|
312
332
|
`Imported ${directoryResult.imported.length} file(s), updated ${directoryResult.updated.length}, skipped ${directoryResult.skipped.length}.`
|
|
313
333
|
);
|
|
334
|
+
if (review3) {
|
|
335
|
+
log(`Staged source review at ${review3.reviewPath}.`);
|
|
336
|
+
}
|
|
314
337
|
}
|
|
315
338
|
return;
|
|
316
339
|
}
|
|
317
|
-
const
|
|
340
|
+
const ingest = await ingestInputDetailed(process2.cwd(), input, commonOptions);
|
|
341
|
+
const review2 = options.review && (ingest.created.length || ingest.updated.length || ingest.unchanged.length) ? await (async () => {
|
|
342
|
+
await compileVault(process2.cwd(), {});
|
|
343
|
+
const scopeSourceIds = [...ingest.created, ...ingest.updated, ...ingest.unchanged].map((manifest) => manifest.sourceId);
|
|
344
|
+
return await reviewSourceScope(process2.cwd(), {
|
|
345
|
+
id: ingest.created[0]?.sourceGroupId ?? ingest.updated[0]?.sourceGroupId ?? ingest.unchanged[0]?.sourceGroupId ?? scopeSourceIds[0],
|
|
346
|
+
title: [...ingest.created, ...ingest.updated, ...ingest.unchanged][0]?.sourceGroupTitle ?? [...ingest.created, ...ingest.updated, ...ingest.unchanged][0]?.title ?? input,
|
|
347
|
+
sourceIds: scopeSourceIds
|
|
348
|
+
});
|
|
349
|
+
})() : void 0;
|
|
318
350
|
if (isJson()) {
|
|
319
|
-
emitJson(
|
|
351
|
+
emitJson(review2 ? { ingest, review: review2 } : ingest);
|
|
320
352
|
} else {
|
|
321
|
-
|
|
353
|
+
const primary = [...ingest.created, ...ingest.updated, ...ingest.unchanged][0];
|
|
354
|
+
if (ingest.created.length + ingest.updated.length + ingest.removed.length <= 1 && primary) {
|
|
355
|
+
log(primary.sourceId);
|
|
356
|
+
} else {
|
|
357
|
+
log(
|
|
358
|
+
`Created ${ingest.created.length}, updated ${ingest.updated.length}, unchanged ${ingest.unchanged.length}, removed ${ingest.removed.length}.`
|
|
359
|
+
);
|
|
360
|
+
}
|
|
361
|
+
if (review2) {
|
|
362
|
+
log(`Staged source review at ${review2.reviewPath}.`);
|
|
363
|
+
}
|
|
322
364
|
}
|
|
323
365
|
}
|
|
324
366
|
);
|
|
@@ -333,22 +375,25 @@ program.command("add").description("Capture supported URLs into normalized markd
|
|
|
333
375
|
log(`${result.captureType}${result.fallback ? " (fallback)" : ""}: ${result.manifest.sourceId}`);
|
|
334
376
|
}
|
|
335
377
|
});
|
|
336
|
-
var source = program.command("source").description("Manage recurring
|
|
337
|
-
source.command("add").description("Register and sync a managed source from a directory, public GitHub repo root URL, or docs hub URL.").argument("<input>", "
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
378
|
+
var source = program.command("source").description("Manage recurring local files, directories, public repos, and docs sources.");
|
|
379
|
+
source.command("add").description("Register and sync a managed source from a local file, directory, public GitHub repo root URL, or docs hub URL.").argument("<input>", "Local file path, directory path, public GitHub repo root URL, or docs hub URL").option("--no-compile", "Register and sync without compiling the vault").option("--no-brief", "Skip source brief generation after sync").option("--review", "Stage a source review artifact after sync and compile", false).option("--max-pages <n>", "Maximum number of pages to crawl for docs sources").option("--max-depth <n>", "Maximum crawl depth for docs sources").action(
|
|
380
|
+
async (input, options) => {
|
|
381
|
+
const result = await addManagedSource(process2.cwd(), input, {
|
|
382
|
+
compile: options.compile,
|
|
383
|
+
brief: options.brief,
|
|
384
|
+
review: options.review,
|
|
385
|
+
maxPages: options.maxPages ? parsePositiveInt(options.maxPages, 0) || void 0 : void 0,
|
|
386
|
+
maxDepth: options.maxDepth ? parsePositiveInt(options.maxDepth, 0) || void 0 : void 0
|
|
387
|
+
});
|
|
388
|
+
if (isJson()) {
|
|
389
|
+
emitJson(result);
|
|
390
|
+
} else {
|
|
391
|
+
log(
|
|
392
|
+
`Registered ${result.source.kind} source ${result.source.id}. Status: ${result.source.status}.${result.compile ? ` Compiled ${result.compile.sourceCount} source(s).` : ""}${result.briefGenerated ? ` Brief: ${result.source.briefPath}` : ""}${result.review ? ` Review: ${result.review.reviewPath}` : ""}`
|
|
393
|
+
);
|
|
394
|
+
}
|
|
350
395
|
}
|
|
351
|
-
|
|
396
|
+
);
|
|
352
397
|
source.command("list").description("List managed sources registered in this vault.").action(async () => {
|
|
353
398
|
const sources = await listManagedSourceRecords(process2.cwd());
|
|
354
399
|
if (isJson()) {
|
|
@@ -388,6 +433,14 @@ source.command("delete").description("Unregister a managed source and remove its
|
|
|
388
433
|
log(`Deleted managed source ${result.removed.id}. Canonical vault content was left in place.`);
|
|
389
434
|
}
|
|
390
435
|
});
|
|
436
|
+
source.command("review").description("Stage a source review artifact for a managed source id or raw source id.").argument("<id>", "Managed source id or raw source id").action(async (id) => {
|
|
437
|
+
const result = await reviewManagedSource(process2.cwd(), id);
|
|
438
|
+
if (isJson()) {
|
|
439
|
+
emitJson(result);
|
|
440
|
+
} else {
|
|
441
|
+
log(`Staged source review at ${result.reviewPath}.`);
|
|
442
|
+
}
|
|
443
|
+
});
|
|
391
444
|
var inbox = program.command("inbox").description("Inbox and capture workflows.");
|
|
392
445
|
inbox.command("import").description("Import supported files from the configured inbox directory.").argument("[dir]", "Optional inbox directory override").action(async (dir) => {
|
|
393
446
|
const result = await importInbox(process2.cwd(), dir);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@swarmvaultai/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Global CLI for SwarmVault.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"node": ">=24.0.0"
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@swarmvaultai/engine": "0.
|
|
41
|
+
"@swarmvaultai/engine": "0.4.0",
|
|
42
42
|
"commander": "^14.0.1"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|