@swarmvaultai/cli 0.3.0 → 0.5.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/README.md +9 -3
- package/dist/index.js +126 -28
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -22,9 +22,10 @@ Installed commands:
|
|
|
22
22
|
```bash
|
|
23
23
|
mkdir my-vault
|
|
24
24
|
cd my-vault
|
|
25
|
-
swarmvault init --obsidian
|
|
25
|
+
swarmvault init --obsidian --profile personal-research
|
|
26
26
|
swarmvault source add https://github.com/karpathy/micrograd
|
|
27
27
|
swarmvault source add https://example.com/docs/getting-started
|
|
28
|
+
swarmvault source add ./exports/customer-call.srt --guide
|
|
28
29
|
swarmvault source list
|
|
29
30
|
swarmvault source reload --all
|
|
30
31
|
sed -n '1,120p' swarmvault.schema.md
|
|
@@ -50,7 +51,7 @@ swarmvault graph push neo4j --dry-run
|
|
|
50
51
|
|
|
51
52
|
## Commands
|
|
52
53
|
|
|
53
|
-
### `swarmvault init [--obsidian]`
|
|
54
|
+
### `swarmvault init [--obsidian] [--profile personal-research]`
|
|
54
55
|
|
|
55
56
|
Create a workspace with:
|
|
56
57
|
|
|
@@ -67,19 +68,23 @@ Create a workspace with:
|
|
|
67
68
|
|
|
68
69
|
The schema file is the vault-specific instruction layer. Edit it to define naming rules, categories, grounding expectations, and exclusions before a serious compile.
|
|
69
70
|
|
|
70
|
-
### `swarmvault source add|list|reload|delete`
|
|
71
|
+
### `swarmvault source add|list|reload|review|guide|delete`
|
|
71
72
|
|
|
72
73
|
Manage recurring source roots through a registry-backed workflow.
|
|
73
74
|
|
|
74
75
|
- `source add <input>` supports local directories, public GitHub repo root URLs such as `https://github.com/karpathy/micrograd`, and docs/wiki/help/reference/tutorial hubs
|
|
75
76
|
- by default `source add` registers the source, syncs it into the vault, runs one compile, and writes a source brief to `wiki/outputs/source-briefs/<source-id>.md`
|
|
77
|
+
- add `--guide` when you want a source brief, source review, source guide, and approval bundle for one-source-at-a-time integration
|
|
76
78
|
- `source list` shows every managed source with its kind, status, and current brief path
|
|
77
79
|
- `source reload [id]` re-syncs one source, or use `--all` to refresh everything in the registry and compile once
|
|
80
|
+
- `source review <id>` stages a lighter source-scoped review artifact
|
|
81
|
+
- `source guide <id>` stages the stronger guided-ingest bundle for that source scope
|
|
78
82
|
- `source delete <id>` unregisters the source and removes transient sync state under `state/sources/<id>/`, but leaves canonical `raw/`, `wiki/`, and saved output artifacts intact
|
|
79
83
|
|
|
80
84
|
Useful flags:
|
|
81
85
|
|
|
82
86
|
- `--all`
|
|
87
|
+
- `--guide`
|
|
83
88
|
- `--no-compile`
|
|
84
89
|
- `--no-brief`
|
|
85
90
|
- `--max-pages <n>`
|
|
@@ -97,6 +102,7 @@ Ingest a local file path, directory path, or URL into immutable source storage a
|
|
|
97
102
|
- use `source add` instead when the same local directory, public GitHub repo root, or docs hub should stay registered and reloadable
|
|
98
103
|
- URL ingest still localizes remote image references by default
|
|
99
104
|
- local file ingest supports markdown, text, reStructuredText, HTML, PDF, DOCX, images, and code
|
|
105
|
+
- add `--guide` when you want a source brief, source review, source guide, and approval bundle after ingest
|
|
100
106
|
- code-aware directory ingest currently covers JavaScript, JSX, TypeScript, TSX, Python, Go, Rust, Java, Kotlin, Scala, Lua, Zig, C#, C, C++, PHP, Ruby, and PowerShell
|
|
101
107
|
|
|
102
108
|
Useful flags:
|
package/dist/index.js
CHANGED
|
@@ -17,6 +17,8 @@ import {
|
|
|
17
17
|
exportGraphHtml,
|
|
18
18
|
getGitHookStatus,
|
|
19
19
|
getWatchStatus,
|
|
20
|
+
guideManagedSource,
|
|
21
|
+
guideSourceScope,
|
|
20
22
|
importInbox,
|
|
21
23
|
ingestDirectory,
|
|
22
24
|
ingestInputDetailed,
|
|
@@ -28,6 +30,7 @@ import {
|
|
|
28
30
|
listCandidates,
|
|
29
31
|
listGodNodes,
|
|
30
32
|
listManagedSourceRecords,
|
|
33
|
+
listManifests,
|
|
31
34
|
listSchedules,
|
|
32
35
|
loadVaultConfig,
|
|
33
36
|
pathGraphVault,
|
|
@@ -38,6 +41,8 @@ import {
|
|
|
38
41
|
readApproval,
|
|
39
42
|
rejectApproval,
|
|
40
43
|
reloadManagedSources,
|
|
44
|
+
reviewManagedSource,
|
|
45
|
+
reviewSourceScope,
|
|
41
46
|
runSchedule,
|
|
42
47
|
runWatchCycle,
|
|
43
48
|
serveSchedules,
|
|
@@ -221,9 +226,9 @@ program.name("swarmvault").description("SwarmVault is a local-first knowledge co
|
|
|
221
226
|
function readCliVersion() {
|
|
222
227
|
try {
|
|
223
228
|
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.
|
|
229
|
+
return typeof packageJson.version === "string" && packageJson.version.trim() ? packageJson.version : "0.5.0";
|
|
225
230
|
} catch {
|
|
226
|
-
return "0.
|
|
231
|
+
return "0.5.0";
|
|
227
232
|
}
|
|
228
233
|
}
|
|
229
234
|
function parsePositiveInt(value, fallback) {
|
|
@@ -231,6 +236,21 @@ function parsePositiveInt(value, fallback) {
|
|
|
231
236
|
const parsed = Number.parseInt(value, 10);
|
|
232
237
|
return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;
|
|
233
238
|
}
|
|
239
|
+
function sourceScopeFromManifests(input, manifests) {
|
|
240
|
+
if (!manifests.length) {
|
|
241
|
+
return null;
|
|
242
|
+
}
|
|
243
|
+
const primary = manifests[0];
|
|
244
|
+
return {
|
|
245
|
+
id: primary?.sourceGroupId ?? primary?.sourceId ?? slugForCli(input),
|
|
246
|
+
title: primary?.sourceGroupTitle ?? primary?.title ?? input,
|
|
247
|
+
sourceIds: manifests.map((manifest) => manifest.sourceId),
|
|
248
|
+
kind: primary?.sourceKind
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
function slugForCli(value) {
|
|
252
|
+
return value.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || "source";
|
|
253
|
+
}
|
|
234
254
|
function isJson() {
|
|
235
255
|
return program.opts().json === true;
|
|
236
256
|
}
|
|
@@ -273,15 +293,20 @@ program.hook("postAction", async (_thisCommand, actionCommand) => {
|
|
|
273
293
|
emitNotice(notice);
|
|
274
294
|
}
|
|
275
295
|
});
|
|
276
|
-
program.command("init").description("Initialize a SwarmVault workspace in the current directory.").option("--obsidian", "Generate a minimal .obsidian workspace alongside the vault", false).action(async (options) => {
|
|
277
|
-
await initVault(process2.cwd(), { obsidian: options.obsidian ?? false });
|
|
296
|
+
program.command("init").description("Initialize a SwarmVault workspace in the current directory.").option("--obsidian", "Generate a minimal .obsidian workspace alongside the vault", false).addOption(new Option("--profile <profile>", "Starter workspace profile").choices(["default", "personal-research"])).action(async (options) => {
|
|
297
|
+
await initVault(process2.cwd(), { obsidian: options.obsidian ?? false, profile: options.profile });
|
|
278
298
|
if (isJson()) {
|
|
279
|
-
emitJson({
|
|
299
|
+
emitJson({
|
|
300
|
+
status: "initialized",
|
|
301
|
+
rootDir: process2.cwd(),
|
|
302
|
+
obsidian: options.obsidian ?? false,
|
|
303
|
+
profile: options.profile ?? "default"
|
|
304
|
+
});
|
|
280
305
|
} else {
|
|
281
306
|
log("Initialized SwarmVault workspace.");
|
|
282
307
|
}
|
|
283
308
|
});
|
|
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(
|
|
309
|
+
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("--guide", "Stage a guided source integration bundle 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
310
|
async (input, options) => {
|
|
286
311
|
const maxAssetSize = typeof options.maxAssetSize === "string" && options.maxAssetSize.trim() ? parsePositiveInt(options.maxAssetSize, 0) || void 0 : void 0;
|
|
287
312
|
const maxFiles = typeof options.maxFiles === "string" && options.maxFiles.trim() ? parsePositiveInt(options.maxFiles, 0) || void 0 : void 0;
|
|
@@ -305,18 +330,59 @@ program.command("ingest").description("Ingest a local file path, directory path,
|
|
|
305
330
|
(fs) => fs.stat(input).then((stat) => stat.isDirectory() ? ingestDirectory(process2.cwd(), input, commonOptions) : null).catch(() => null)
|
|
306
331
|
) : null;
|
|
307
332
|
if (directoryResult) {
|
|
333
|
+
const scope2 = options.review || options.guide ? await (async () => {
|
|
334
|
+
const pathModule = await import("path");
|
|
335
|
+
const absoluteInput = pathModule.resolve(process2.cwd(), input);
|
|
336
|
+
const sourceIds = (await listManifests(process2.cwd())).filter((manifest) => {
|
|
337
|
+
if (!manifest.originalPath) {
|
|
338
|
+
return false;
|
|
339
|
+
}
|
|
340
|
+
const relative = pathModule.relative(absoluteInput, pathModule.resolve(manifest.originalPath));
|
|
341
|
+
return relative === "" || !relative.startsWith("..") && !pathModule.isAbsolute(relative);
|
|
342
|
+
}).map((manifest) => manifest.sourceId);
|
|
343
|
+
return sourceIds.length ? {
|
|
344
|
+
id: `directory-${absoluteInput.split(pathModule.sep).pop() ?? "source"}`,
|
|
345
|
+
title: absoluteInput.split(pathModule.sep).pop() ?? absoluteInput,
|
|
346
|
+
sourceIds,
|
|
347
|
+
kind: "directory"
|
|
348
|
+
} : void 0;
|
|
349
|
+
})() : void 0;
|
|
350
|
+
const shouldStage = Boolean(scope2 && (directoryResult.imported.length || directoryResult.updated.length));
|
|
351
|
+
const review3 = shouldStage && options.review && !options.guide ? await (async () => {
|
|
352
|
+
await compileVault(process2.cwd(), {});
|
|
353
|
+
return await reviewSourceScope(process2.cwd(), scope2);
|
|
354
|
+
})() : void 0;
|
|
355
|
+
const guide2 = shouldStage && options.guide ? await (async () => {
|
|
356
|
+
await compileVault(process2.cwd(), {});
|
|
357
|
+
return await guideSourceScope(process2.cwd(), scope2);
|
|
358
|
+
})() : void 0;
|
|
308
359
|
if (isJson()) {
|
|
309
|
-
emitJson(directoryResult);
|
|
360
|
+
emitJson(guide2 ? { ingest: directoryResult, guide: guide2 } : review3 ? { ingest: directoryResult, review: review3 } : directoryResult);
|
|
310
361
|
} else {
|
|
311
362
|
log(
|
|
312
363
|
`Imported ${directoryResult.imported.length} file(s), updated ${directoryResult.updated.length}, skipped ${directoryResult.skipped.length}.`
|
|
313
364
|
);
|
|
365
|
+
if (review3) {
|
|
366
|
+
log(`Staged source review at ${review3.reviewPath}.`);
|
|
367
|
+
}
|
|
368
|
+
if (guide2) {
|
|
369
|
+
log(`Staged source guide at ${guide2.guidePath}.`);
|
|
370
|
+
}
|
|
314
371
|
}
|
|
315
372
|
return;
|
|
316
373
|
}
|
|
317
374
|
const ingest = await ingestInputDetailed(process2.cwd(), input, commonOptions);
|
|
375
|
+
const scope = sourceScopeFromManifests(input, [...ingest.created, ...ingest.updated, ...ingest.unchanged]);
|
|
376
|
+
const review2 = options.review && !options.guide && scope && (ingest.created.length || ingest.updated.length || ingest.unchanged.length) ? await (async () => {
|
|
377
|
+
await compileVault(process2.cwd(), {});
|
|
378
|
+
return await reviewSourceScope(process2.cwd(), scope);
|
|
379
|
+
})() : void 0;
|
|
380
|
+
const guide = options.guide && scope && (ingest.created.length || ingest.updated.length || ingest.unchanged.length) ? await (async () => {
|
|
381
|
+
await compileVault(process2.cwd(), {});
|
|
382
|
+
return await guideSourceScope(process2.cwd(), scope);
|
|
383
|
+
})() : void 0;
|
|
318
384
|
if (isJson()) {
|
|
319
|
-
emitJson(ingest);
|
|
385
|
+
emitJson(guide ? { ingest, guide } : review2 ? { ingest, review: review2 } : ingest);
|
|
320
386
|
} else {
|
|
321
387
|
const primary = [...ingest.created, ...ingest.updated, ...ingest.unchanged][0];
|
|
322
388
|
if (ingest.created.length + ingest.updated.length + ingest.removed.length <= 1 && primary) {
|
|
@@ -326,6 +392,12 @@ program.command("ingest").description("Ingest a local file path, directory path,
|
|
|
326
392
|
`Created ${ingest.created.length}, updated ${ingest.updated.length}, unchanged ${ingest.unchanged.length}, removed ${ingest.removed.length}.`
|
|
327
393
|
);
|
|
328
394
|
}
|
|
395
|
+
if (review2) {
|
|
396
|
+
log(`Staged source review at ${review2.reviewPath}.`);
|
|
397
|
+
}
|
|
398
|
+
if (guide) {
|
|
399
|
+
log(`Staged source guide at ${guide.guidePath}.`);
|
|
400
|
+
}
|
|
329
401
|
}
|
|
330
402
|
}
|
|
331
403
|
);
|
|
@@ -340,22 +412,26 @@ program.command("add").description("Capture supported URLs into normalized markd
|
|
|
340
412
|
log(`${result.captureType}${result.fallback ? " (fallback)" : ""}: ${result.manifest.sourceId}`);
|
|
341
413
|
}
|
|
342
414
|
});
|
|
343
|
-
var source = program.command("source").description("Manage recurring
|
|
344
|
-
source.command("add").description("Register and sync a managed source from a directory, public GitHub repo root URL, or docs hub URL.").argument("<input>", "
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
415
|
+
var source = program.command("source").description("Manage recurring local files, directories, public repos, and docs sources.");
|
|
416
|
+
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("--guide", "Stage a guided source integration bundle 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(
|
|
417
|
+
async (input, options) => {
|
|
418
|
+
const result = await addManagedSource(process2.cwd(), input, {
|
|
419
|
+
compile: options.compile,
|
|
420
|
+
brief: options.brief,
|
|
421
|
+
review: options.review,
|
|
422
|
+
guide: options.guide,
|
|
423
|
+
maxPages: options.maxPages ? parsePositiveInt(options.maxPages, 0) || void 0 : void 0,
|
|
424
|
+
maxDepth: options.maxDepth ? parsePositiveInt(options.maxDepth, 0) || void 0 : void 0
|
|
425
|
+
});
|
|
426
|
+
if (isJson()) {
|
|
427
|
+
emitJson(result);
|
|
428
|
+
} else {
|
|
429
|
+
log(
|
|
430
|
+
`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}` : ""}${result.guide ? ` Guide: ${result.guide.guidePath}` : ""}`
|
|
431
|
+
);
|
|
432
|
+
}
|
|
357
433
|
}
|
|
358
|
-
|
|
434
|
+
);
|
|
359
435
|
source.command("list").description("List managed sources registered in this vault.").action(async () => {
|
|
360
436
|
const sources = await listManagedSourceRecords(process2.cwd());
|
|
361
437
|
if (isJson()) {
|
|
@@ -368,13 +444,15 @@ source.command("list").description("List managed sources registered in this vaul
|
|
|
368
444
|
}
|
|
369
445
|
}
|
|
370
446
|
});
|
|
371
|
-
source.command("reload").description("Re-sync one managed source or all managed sources, then optionally compile and refresh briefs.").argument("[id]", "Managed source id").option("--all", "Reload all managed sources", false).option("--no-compile", "Re-sync without compiling the vault").option("--no-brief", "Skip source brief generation after sync").option("--max-pages <n>", "Maximum number of pages to crawl for docs sources").option("--max-depth <n>", "Maximum crawl depth for docs sources").action(
|
|
447
|
+
source.command("reload").description("Re-sync one managed source or all managed sources, then optionally compile and refresh briefs.").argument("[id]", "Managed source id").option("--all", "Reload all managed sources", false).option("--no-compile", "Re-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("--guide", "Stage a guided source integration bundle 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(
|
|
372
448
|
async (id, options) => {
|
|
373
449
|
const result = await reloadManagedSources(process2.cwd(), {
|
|
374
450
|
id,
|
|
375
451
|
all: options.all ?? false,
|
|
376
452
|
compile: options.compile,
|
|
377
453
|
brief: options.brief,
|
|
454
|
+
review: options.review,
|
|
455
|
+
guide: options.guide,
|
|
378
456
|
maxPages: options.maxPages ? parsePositiveInt(options.maxPages, 0) || void 0 : void 0,
|
|
379
457
|
maxDepth: options.maxDepth ? parsePositiveInt(options.maxDepth, 0) || void 0 : void 0
|
|
380
458
|
});
|
|
@@ -382,7 +460,7 @@ source.command("reload").description("Re-sync one managed source or all managed
|
|
|
382
460
|
emitJson(result);
|
|
383
461
|
} else {
|
|
384
462
|
log(
|
|
385
|
-
`Reloaded ${result.sources.length} source(s).${result.compile ? ` Compiled ${result.compile.sourceCount} source(s).` : ""}${result.briefPaths.length ? ` Briefs: ${result.briefPaths.length}.` : ""}`
|
|
463
|
+
`Reloaded ${result.sources.length} source(s).${result.compile ? ` Compiled ${result.compile.sourceCount} source(s).` : ""}${result.briefPaths.length ? ` Briefs: ${result.briefPaths.length}.` : ""}${result.reviews.length ? ` Reviews: ${result.reviews.length}.` : ""}${result.guides.length ? ` Guides: ${result.guides.length}.` : ""}`
|
|
386
464
|
);
|
|
387
465
|
}
|
|
388
466
|
}
|
|
@@ -395,6 +473,22 @@ source.command("delete").description("Unregister a managed source and remove its
|
|
|
395
473
|
log(`Deleted managed source ${result.removed.id}. Canonical vault content was left in place.`);
|
|
396
474
|
}
|
|
397
475
|
});
|
|
476
|
+
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) => {
|
|
477
|
+
const result = await reviewManagedSource(process2.cwd(), id);
|
|
478
|
+
if (isJson()) {
|
|
479
|
+
emitJson(result);
|
|
480
|
+
} else {
|
|
481
|
+
log(`Staged source review at ${result.reviewPath}.`);
|
|
482
|
+
}
|
|
483
|
+
});
|
|
484
|
+
source.command("guide").description("Stage a guided source integration bundle for a managed source id or raw source id.").argument("<id>", "Managed source id or raw source id").action(async (id) => {
|
|
485
|
+
const result = await guideManagedSource(process2.cwd(), id);
|
|
486
|
+
if (isJson()) {
|
|
487
|
+
emitJson(result);
|
|
488
|
+
} else {
|
|
489
|
+
log(`Staged source guide at ${result.guidePath}.`);
|
|
490
|
+
}
|
|
491
|
+
});
|
|
398
492
|
var inbox = program.command("inbox").description("Inbox and capture workflows.");
|
|
399
493
|
inbox.command("import").description("Import supported files from the configured inbox directory.").argument("[dir]", "Optional inbox directory override").action(async (dir) => {
|
|
400
494
|
const result = await importInbox(process2.cwd(), dir);
|
|
@@ -605,7 +699,7 @@ review.command("list").description("List staged approval bundles and their resol
|
|
|
605
699
|
}
|
|
606
700
|
for (const approval of approvals) {
|
|
607
701
|
log(
|
|
608
|
-
`${approval.approvalId} pending=${approval.pendingCount} accepted=${approval.acceptedCount} rejected=${approval.rejectedCount} created=${approval.createdAt}`
|
|
702
|
+
`${approval.approvalId}${approval.bundleType ? ` [${approval.bundleType}]` : ""}${approval.title ? ` ${approval.title}` : ""} pending=${approval.pendingCount} accepted=${approval.acceptedCount} rejected=${approval.rejectedCount} created=${approval.createdAt}`
|
|
609
703
|
);
|
|
610
704
|
}
|
|
611
705
|
});
|
|
@@ -615,9 +709,13 @@ review.command("show").description("Show the entries inside a staged approval bu
|
|
|
615
709
|
emitJson(approval);
|
|
616
710
|
return;
|
|
617
711
|
}
|
|
618
|
-
log(
|
|
712
|
+
log(
|
|
713
|
+
`${approval.approvalId}${approval.bundleType ? ` [${approval.bundleType}]` : ""}${approval.title ? ` ${approval.title}` : ""} pending=${approval.pendingCount} accepted=${approval.acceptedCount} rejected=${approval.rejectedCount}`
|
|
714
|
+
);
|
|
619
715
|
for (const entry of approval.entries) {
|
|
620
|
-
log(
|
|
716
|
+
log(
|
|
717
|
+
`- ${entry.status} ${entry.changeType}${entry.label ? ` [${entry.label}]` : ""} ${entry.pageId} ${entry.nextPath ?? entry.previousPath ?? ""}`.trim()
|
|
718
|
+
);
|
|
621
719
|
if (entry.changeSummary) log(` Summary: ${entry.changeSummary}`);
|
|
622
720
|
if (entry.diff) {
|
|
623
721
|
log("");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@swarmvaultai/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.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.5.0",
|
|
42
42
|
"commander": "^14.0.1"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|