@swarmvaultai/cli 3.5.0 → 3.7.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 +71 -10
- package/dist/index.js +151 -45
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
`@swarmvaultai/cli` is the global command-line entry point for SwarmVault.
|
|
4
4
|
|
|
5
|
-
It gives you the `swarmvault` command for building a local-first knowledge vault from files, audio transcripts, YouTube URLs, reStructuredText and DOCX documents, browser clips, saved query outputs, and guided exploration runs.
|
|
5
|
+
It gives you the `swarmvault` command for building a local-first knowledge vault from files, audio/video transcripts, YouTube URLs, reStructuredText and DOCX documents, browser clips, saved query outputs, and guided exploration runs.
|
|
6
6
|
|
|
7
7
|
## Install
|
|
8
8
|
|
|
@@ -26,6 +26,7 @@ swarmvault init --obsidian --profile personal-research
|
|
|
26
26
|
swarmvault init --obsidian --profile reader,timeline
|
|
27
27
|
swarmvault demo
|
|
28
28
|
swarmvault source add https://github.com/karpathy/micrograd
|
|
29
|
+
swarmvault source add https://github.com/owner/repo --branch main --checkout-dir .swarmvault-checkouts/repo
|
|
29
30
|
swarmvault source add https://example.com/docs/getting-started
|
|
30
31
|
swarmvault source add ./exports/customer-call.srt --guide
|
|
31
32
|
swarmvault source session file-customer-call-srt-12345678
|
|
@@ -35,6 +36,7 @@ sed -n '1,120p' swarmvault.schema.md
|
|
|
35
36
|
swarmvault ingest ./notes.md
|
|
36
37
|
swarmvault ingest ./customer-call.mp3
|
|
37
38
|
swarmvault ingest https://www.youtube.com/watch?v=dQw4w9WgXcQ
|
|
39
|
+
swarmvault ingest --video https://example.com/product-demo.mp4
|
|
38
40
|
swarmvault ingest ./repo
|
|
39
41
|
swarmvault add https://arxiv.org/abs/2401.12345
|
|
40
42
|
swarmvault compile --max-tokens 120000
|
|
@@ -52,7 +54,10 @@ swarmvault query "Turn this into slides" --format slides
|
|
|
52
54
|
swarmvault explore "What should I research next?" --steps 3
|
|
53
55
|
swarmvault lint --deep
|
|
54
56
|
swarmvault graph blast ./src/index.ts
|
|
57
|
+
swarmvault graph status ./src
|
|
55
58
|
swarmvault graph update .
|
|
59
|
+
swarmvault graph cluster
|
|
60
|
+
swarmvault graph tree --output ./exports/tree.html
|
|
56
61
|
swarmvault graph query "Which nodes bridge the biggest clusters?"
|
|
57
62
|
swarmvault graph explain "concept:drift"
|
|
58
63
|
swarmvault watch status
|
|
@@ -62,6 +67,7 @@ swarmvault graph serve
|
|
|
62
67
|
swarmvault graph export --report ./exports/report.html
|
|
63
68
|
swarmvault graph export --html ./exports/graph.html
|
|
64
69
|
swarmvault graph export --cypher ./exports/graph.cypher
|
|
70
|
+
swarmvault graph merge ./exports/graph.json ./other-graph.json --out ./exports/merged-graph.json
|
|
65
71
|
swarmvault graph push neo4j --dry-run
|
|
66
72
|
```
|
|
67
73
|
|
|
@@ -84,18 +90,21 @@ Create a workspace with:
|
|
|
84
90
|
|
|
85
91
|
The schema file is the vault-specific instruction layer. Edit it to define naming rules, categories, grounding expectations, and exclusions before a serious compile.
|
|
86
92
|
|
|
93
|
+
Set `SWARMVAULT_OUT=<dir>` when generated artifacts should be isolated from the project root. Config and schema files stay at the root; relative `raw/`, `wiki/`, `state/`, `agent/`, and `inbox/` workspace directories resolve under the output root.
|
|
94
|
+
|
|
87
95
|
`--profile` accepts `default`, `personal-research`, or a comma-separated preset list such as `reader,timeline`. For fully custom vault behavior, edit the `profile` block in `swarmvault.config.json`; that deterministic profile layer works alongside the human-written `swarmvault.schema.md`. The `personal-research` preset also sets `profile.guidedIngestDefault: true` and `profile.deepLintDefault: true`, so guided ingest/source and lint flows are on by default until you override them with `--no-guide` or `--no-deep`.
|
|
88
96
|
|
|
89
|
-
### `swarmvault scan <directory> [--port <port>] [--no-serve]`
|
|
97
|
+
### `swarmvault scan <directory|github-url> [--port <port>] [--no-serve] [--branch <name>] [--ref <ref>] [--checkout-dir <path>]`
|
|
90
98
|
|
|
91
|
-
Quick-start a scratch vault from a local directory in one command.
|
|
99
|
+
Quick-start a scratch vault from a local directory or public GitHub repo root URL in one command.
|
|
92
100
|
|
|
93
101
|
- initializes the current directory as a SwarmVault workspace
|
|
94
|
-
- ingests the supplied directory as local sources
|
|
102
|
+
- ingests the supplied directory as local sources, or registers/syncs the supplied public GitHub repo root URL
|
|
95
103
|
- compiles the vault immediately
|
|
96
104
|
- writes `wiki/graph/share-card.md`, `wiki/graph/share-card.svg`, and `wiki/graph/share-kit/`, then prints the paths
|
|
97
105
|
- starts `graph serve` unless you pass `--no-serve`
|
|
98
106
|
- respects `--port` when you want a specific viewer port
|
|
107
|
+
- for GitHub repo URLs, supports `--branch`, `--ref`, and `--checkout-dir`
|
|
99
108
|
|
|
100
109
|
Use this when you want the fastest repo or docs-tree walkthrough without first deciding on managed-source registration.
|
|
101
110
|
|
|
@@ -134,6 +143,7 @@ Run a whole-vault health check before handing the workspace to an agent or openi
|
|
|
134
143
|
Manage recurring source roots through a registry-backed workflow.
|
|
135
144
|
|
|
136
145
|
- `source add <input>` supports local files, local directories, public GitHub repo root URLs such as `https://github.com/karpathy/micrograd`, and docs/wiki/help/reference/tutorial hubs
|
|
146
|
+
- for public GitHub repo roots, `source add` supports `--branch <name>`, `--ref <ref>`, and `--checkout-dir <path>` so recurring sources can pin a branch, tag, commit, or reusable checkout directory
|
|
137
147
|
- 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`
|
|
138
148
|
- add `--guide` when you want a resumable source session, source brief, source review, source guide, and approval-bundled canonical page edits when `profile.guidedSessionMode` is `canonical_review`, with `wiki/insights/` fallback for `insights_only`
|
|
139
149
|
- set `profile.guidedIngestDefault: true` when guided mode should be the default for `source add` and `source reload`, and use `--no-guide` for individual light-path runs
|
|
@@ -171,15 +181,16 @@ Source-scoped artifacts are intentionally split by role:
|
|
|
171
181
|
Ingest a local file path, directory path, or URL into immutable source storage and write manifests to `state/manifests/`.
|
|
172
182
|
|
|
173
183
|
- local directories recurse by default
|
|
174
|
-
- directory ingest respects `.gitignore` unless you pass `--no-gitignore`
|
|
184
|
+
- directory ingest respects `.gitignore` and `.swarmvaultignore` unless you pass `--no-gitignore` or `--no-swarmvaultignore`
|
|
175
185
|
- repo-aware directory ingest records `repoRelativePath` and later compile writes `state/code-index.json`
|
|
176
186
|
- use `source add` instead when the same local directory, public GitHub repo root, or docs hub should stay registered and reloadable
|
|
177
187
|
- URL ingest still localizes remote image references by default
|
|
178
188
|
- YouTube URLs short-circuit to direct transcript capture instead of generic HTML fetch
|
|
179
|
-
-
|
|
189
|
+
- public video URLs passed with `--video` use `yt-dlp` for audio extraction before provider-backed transcription
|
|
190
|
+
- local file and archive ingest supports markdown, text, reStructuredText, HTML, PDF, Word, RTF, OpenDocument, EPUB, CSV/TSV, Excel, PowerPoint, Jupyter notebooks, BibTeX, Org-mode, AsciiDoc, transcripts, Slack exports, email, calendar, audio, video, structured config/data, developer manifests, images, and code
|
|
180
191
|
- add `--guide` when you want a resumable source session, source brief, source review, source guide, and approval-bundled canonical page edits when `profile.guidedSessionMode` is `canonical_review`, with `wiki/insights/` fallback for `insights_only`
|
|
181
192
|
- set `profile.guidedIngestDefault: true` when guided mode should be the default for `ingest`, and use `--no-guide` to force a plain ingest for one run
|
|
182
|
-
- code-aware directory ingest currently covers JavaScript, JSX, TypeScript, TSX, Bash/shell scripts, Python, Go, Rust, Java, Kotlin, Scala, Dart, Lua, Zig, C#, C, C++, PHP, Ruby, PowerShell, Elixir, OCaml, Objective-C, ReScript, Solidity, HTML, CSS,
|
|
193
|
+
- code-aware directory ingest currently covers JavaScript, JSX, TypeScript, TSX, Bash/shell scripts, Python, Go, Rust, Java, Kotlin, Scala, Dart, Lua, Zig, C#, C, C++, PHP, Ruby, PowerShell, Elixir, OCaml, Objective-C, ReScript, Solidity, HTML, CSS, Vue single-file components, Svelte single-file components, and SQL files with table/view graph relations. Julia, Verilog/SystemVerilog, and R files are detected as code sources and emit explicit parser-asset diagnostics until packaged WASM grammars are available.
|
|
183
194
|
|
|
184
195
|
Useful flags:
|
|
185
196
|
|
|
@@ -193,6 +204,8 @@ Useful flags:
|
|
|
193
204
|
- `--include-resources`
|
|
194
205
|
- `--include-generated`
|
|
195
206
|
- `--no-gitignore`
|
|
207
|
+
- `--no-swarmvaultignore`
|
|
208
|
+
- `--video`
|
|
196
209
|
- `--no-include-assets`
|
|
197
210
|
- `--max-asset-size <bytes>`
|
|
198
211
|
- `--commit`
|
|
@@ -201,7 +214,7 @@ Repo ingest defaults to `first_party` material. The extra `--include-*` flags op
|
|
|
201
214
|
|
|
202
215
|
Large repo ingest now emits low-noise progress on materially large batches, and parser compatibility failures stay local to the affected source instead of aborting unrelated analysis.
|
|
203
216
|
|
|
204
|
-
Audio files use `tasks.audioProvider` when you configure a provider with `audio` capability. When no
|
|
217
|
+
Audio and video files use `tasks.audioProvider` when you configure a provider with `audio` capability. Local video extraction shells out to `ffmpeg`; public video URL extraction with `--video` shells out to `yt-dlp`. When no audio provider or extractor binary is configured, SwarmVault still ingests the source and records an explicit extraction warning instead of failing. YouTube transcript ingest does not require a model provider.
|
|
205
218
|
|
|
206
219
|
When `--commit` is set, SwarmVault stages `wiki/` and `state/` changes and creates a git commit when the vault root is inside a git worktree. Outside git, it becomes a no-op instead of failing.
|
|
207
220
|
|
|
@@ -215,6 +228,7 @@ Capture supported URLs through a normalized markdown layer before ingesting them
|
|
|
215
228
|
- X/Twitter URLs use a graceful public capture path
|
|
216
229
|
- unsupported URLs fall back to generic URL ingest instead of failing
|
|
217
230
|
- optional metadata: `--author <name>` and `--contributor <name>`
|
|
231
|
+
- `--video` treats the URL as a public video and routes extracted audio through `tasks.audioProvider`
|
|
218
232
|
- normalized captures record fields such as `source_type`, `source_url`, `canonical_url`, `title`, `authors`, `published_at`, `updated_at`, `doi`, and `tags` when available
|
|
219
233
|
- use `source add` instead when the URL is a public GitHub repo root or a docs hub that should stay synced over time
|
|
220
234
|
|
|
@@ -381,8 +395,50 @@ Refresh code-derived graph artifacts from tracked repo roots or one explicit rep
|
|
|
381
395
|
- runs the same code-only repo refresh path as `swarmvault watch --repo --code-only --once`
|
|
382
396
|
- without `path`, uses configured or auto-discovered watched repo roots
|
|
383
397
|
- with `path`, refreshes that repo root instead of the tracked set
|
|
398
|
+
- aborts if nodes or edges drop by more than 25% compared with the existing graph; pass `--force` or set `SWARMVAULT_FORCE_UPDATE=1` when the shrink is expected
|
|
384
399
|
- `--json` returns the same one-shot watch result shape, including repo import/update/remove counts and pending semantic refresh entries
|
|
385
400
|
|
|
401
|
+
### `swarmvault graph tree [--output <html>] [--root <path>] [--label <name>] [--max-children <n>]`
|
|
402
|
+
|
|
403
|
+
Write a collapsible HTML source tree for the current `state/graph.json`.
|
|
404
|
+
|
|
405
|
+
- groups sources by path, then shows module, symbol, and rationale nodes underneath each source
|
|
406
|
+
- defaults to `wiki/graph/tree.html`
|
|
407
|
+
- `--root` reads a different vault root without changing directories
|
|
408
|
+
- `--max-children` caps very wide folders or modules with a `+N more` row
|
|
409
|
+
- `--json` returns the output path, source count, node count, and tree payload
|
|
410
|
+
|
|
411
|
+
### `swarmvault graph merge <graph...> --out <path> [--label <name>]`
|
|
412
|
+
|
|
413
|
+
Merge multiple graph JSON files into one namespaced graph artifact.
|
|
414
|
+
|
|
415
|
+
- accepts native SwarmVault `state/graph.json` payloads
|
|
416
|
+
- accepts NetworkX/node-link style JSON with `nodes` plus `links` or `edges`
|
|
417
|
+
- prefixes ids from every input to avoid collisions
|
|
418
|
+
- maps explicit extracted/inferred/ambiguous edge evidence into SwarmVault edge semantics
|
|
419
|
+
- `--json` returns the merged graph, input summaries, and warnings
|
|
420
|
+
|
|
421
|
+
### `swarmvault graph status [path]`
|
|
422
|
+
|
|
423
|
+
Read-only graph freshness check for tracked repo roots or one explicit repo path.
|
|
424
|
+
|
|
425
|
+
- reports graph and graph-report presence
|
|
426
|
+
- lists tracked repo roots and changed files without writing watch status
|
|
427
|
+
- separates code-only changes from semantic refresh changes
|
|
428
|
+
- recommends `swarmvault graph update` for code-only graph drift
|
|
429
|
+
- recommends `swarmvault compile` when graph/report artifacts are missing, non-code files changed, or a semantic refresh is pending
|
|
430
|
+
- supports global `--json` for automation
|
|
431
|
+
|
|
432
|
+
### `swarmvault graph cluster [--resolution <n>]`
|
|
433
|
+
|
|
434
|
+
Recompute communities, node degrees, bridge scores, god-node flags, and graph report artifacts from the existing `state/graph.json` without re-ingesting or re-analyzing sources.
|
|
435
|
+
|
|
436
|
+
- writes refreshed graph metrics back to `state/graph.json`
|
|
437
|
+
- updates `wiki/graph/report.md`, `wiki/graph/report.json`, share artifacts, and per-community graph pages
|
|
438
|
+
- uses `graph.communityResolution` by default, or `--resolution <n>` for a one-off override
|
|
439
|
+
- splits oversized or low-cohesion communities after the initial Louvain pass so large-repo reports stay scannable
|
|
440
|
+
- `--json` returns counts plus the graph/report paths
|
|
441
|
+
|
|
386
442
|
### `swarmvault hook install|uninstall|status`
|
|
387
443
|
|
|
388
444
|
Manage SwarmVault's local git hook blocks for the nearest git repository.
|
|
@@ -428,6 +484,7 @@ Run SwarmVault as a local MCP server over stdio. This exposes the vault to compa
|
|
|
428
484
|
- `query_graph`
|
|
429
485
|
- `graph_report`
|
|
430
486
|
- `graph_stats`
|
|
487
|
+
- `cluster_graph`
|
|
431
488
|
- `get_node`
|
|
432
489
|
- `get_community`
|
|
433
490
|
- `get_neighbors`
|
|
@@ -435,7 +492,7 @@ Run SwarmVault as a local MCP server over stdio. This exposes the vault to compa
|
|
|
435
492
|
- `shortest_path`
|
|
436
493
|
- `god_nodes`
|
|
437
494
|
|
|
438
|
-
`compile_vault` also accepts `maxTokens` for bounded wiki output, `graph_stats` returns lightweight graph counts, `get_community` resolves community members and pages, `blast_radius` traces reverse import impact for a file or module target, `build_context_pack` creates the same bounded agent evidence bundles as `swarmvault context build`, the task tools mirror `swarmvault task`, the memory tools mirror the compatibility command group, `doctor_vault` mirrors `swarmvault doctor`, and retrieval tools inspect or repair the local index.
|
|
495
|
+
`compile_vault` also accepts `maxTokens` for bounded wiki output, `graph_stats` returns lightweight graph counts, `cluster_graph` mirrors `swarmvault graph cluster`, `get_community` resolves community members and pages, `blast_radius` traces reverse import impact for a file or module target, `build_context_pack` creates the same bounded agent evidence bundles as `swarmvault context build`, the task tools mirror `swarmvault task`, the memory tools mirror the compatibility command group, `doctor_vault` mirrors `swarmvault doctor`, and retrieval tools inspect or repair the local index.
|
|
439
496
|
|
|
440
497
|
The MCP surface also exposes `swarmvault://schema`, `swarmvault://sessions`, `swarmvault://sessions/{path}`, `swarmvault://context-packs`, `swarmvault://tasks`, `swarmvault://memory-tasks`, and includes `schemaPath` in `workspace_info`.
|
|
441
498
|
|
|
@@ -523,7 +580,7 @@ Defaults:
|
|
|
523
580
|
- namespaces every remote record by `vaultId` so multiple vaults can safely share one Neo4j database
|
|
524
581
|
- upserts current graph records and does not prune stale remote data yet
|
|
525
582
|
|
|
526
|
-
### `swarmvault install --agent <
|
|
583
|
+
### `swarmvault install --agent <agent>`
|
|
527
584
|
|
|
528
585
|
Install agent-specific rules into the current project so an agent understands the SwarmVault workspace contract and workflow.
|
|
529
586
|
|
|
@@ -548,6 +605,10 @@ Agent target mapping:
|
|
|
548
605
|
- `trae` writes `.trae/rules/swarmvault.md`
|
|
549
606
|
- `claw` writes `.claw/skills/swarmvault/SKILL.md`
|
|
550
607
|
- `droid` writes `.factory/rules/swarmvault.md`
|
|
608
|
+
- `kiro` writes `.kiro/skills/swarmvault/SKILL.md` and `.kiro/steering/swarmvault.md`
|
|
609
|
+
- `hermes` writes `~/.hermes/skills/swarmvault/SKILL.md` plus `AGENTS.md`
|
|
610
|
+
- `antigravity` writes `.agents/rules/swarmvault.md` and `.agents/workflows/swarmvault.md`, and removes older fully managed `.agent/` files during reinstall
|
|
611
|
+
- `vscode` writes `.github/chatmodes/swarmvault.chatmode.md` plus `.github/copilot-instructions.md`
|
|
551
612
|
|
|
552
613
|
Hook semantics:
|
|
553
614
|
|
package/dist/index.js
CHANGED
|
@@ -30,10 +30,12 @@ import {
|
|
|
30
30
|
exportGraphFormat,
|
|
31
31
|
exportGraphHtml,
|
|
32
32
|
exportGraphReportHtml,
|
|
33
|
+
exportGraphTree,
|
|
33
34
|
exportObsidianCanvas,
|
|
34
35
|
exportObsidianVault,
|
|
35
36
|
finishMemoryTask,
|
|
36
37
|
getGitHookStatus,
|
|
38
|
+
getGraphStatus,
|
|
37
39
|
getRetrievalStatus,
|
|
38
40
|
getWatchStatus,
|
|
39
41
|
graphDiff,
|
|
@@ -56,6 +58,7 @@ import {
|
|
|
56
58
|
listSchedules,
|
|
57
59
|
listWatchedRoots,
|
|
58
60
|
loadVaultConfig,
|
|
61
|
+
mergeGraphFiles,
|
|
59
62
|
pathGraphVault,
|
|
60
63
|
previewCandidatePromotions,
|
|
61
64
|
promoteCandidate,
|
|
@@ -67,6 +70,7 @@ import {
|
|
|
67
70
|
readGraphReport,
|
|
68
71
|
readMemoryTask,
|
|
69
72
|
rebuildRetrievalIndex,
|
|
73
|
+
refreshGraphClusters,
|
|
70
74
|
registerLocalWhisperProvider,
|
|
71
75
|
rejectApproval,
|
|
72
76
|
reloadManagedSources,
|
|
@@ -309,9 +313,9 @@ program.name("swarmvault").description("SwarmVault is a local-first knowledge co
|
|
|
309
313
|
function readCliVersion() {
|
|
310
314
|
try {
|
|
311
315
|
const packageJson = JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf8"));
|
|
312
|
-
return typeof packageJson.version === "string" && packageJson.version.trim() ? packageJson.version : "3.
|
|
316
|
+
return typeof packageJson.version === "string" && packageJson.version.trim() ? packageJson.version : "3.7.0";
|
|
313
317
|
} catch {
|
|
314
|
-
return "3.
|
|
318
|
+
return "3.7.0";
|
|
315
319
|
}
|
|
316
320
|
}
|
|
317
321
|
function parsePositiveInt(value, fallback) {
|
|
@@ -319,9 +323,17 @@ function parsePositiveInt(value, fallback) {
|
|
|
319
323
|
const parsed = Number.parseInt(value, 10);
|
|
320
324
|
return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;
|
|
321
325
|
}
|
|
326
|
+
function parsePositiveNumber(value) {
|
|
327
|
+
if (value === void 0) return void 0;
|
|
328
|
+
const parsed = Number.parseFloat(value);
|
|
329
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : void 0;
|
|
330
|
+
}
|
|
322
331
|
function collectRepeated(value, previous) {
|
|
323
332
|
return [...previous, value];
|
|
324
333
|
}
|
|
334
|
+
function isHttpUrlInput(input) {
|
|
335
|
+
return input.startsWith("http://") || input.startsWith("https://");
|
|
336
|
+
}
|
|
325
337
|
function sourceScopeFromManifests(input, manifests) {
|
|
326
338
|
if (!manifests.length) {
|
|
327
339
|
return null;
|
|
@@ -506,7 +518,7 @@ program.command("init").description("Initialize a SwarmVault workspace in the cu
|
|
|
506
518
|
log(options.lite ? "Initialized SwarmVault lite workspace." : "Initialized SwarmVault workspace.");
|
|
507
519
|
}
|
|
508
520
|
});
|
|
509
|
-
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 (default: from config)").option("--no-guide", "Skip guided mode even if enabled in config").option("--answers-file <path>", "JSON file with guided-session answers keyed by question id or listed in prompt order").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").option("--resume <run-id>", "Re-run only the failed files from a prior ingest run id").option("--commit", "Auto-commit wiki and state changes after ingest").option("--no-redact", "Skip PII/secret redaction for this run (overrides config)").action(
|
|
521
|
+
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 (default: from config)").option("--no-guide", "Skip guided mode even if enabled in config").option("--answers-file <path>", "JSON file with guided-session answers keyed by question id or listed in prompt order").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").option("--no-swarmvaultignore", "Ignore .swarmvaultignore rules when ingesting a directory").option("--video", "Treat a URL input as a public video and transcribe extracted audio", false).option("--resume <run-id>", "Re-run only the failed files from a prior ingest run id").option("--commit", "Auto-commit wiki and state changes after ingest").option("--no-redact", "Skip PII/secret redaction for this run (overrides config)").action(
|
|
510
522
|
async (input, options) => {
|
|
511
523
|
const guideAnswers = readGuideAnswersFile(options.answersFile);
|
|
512
524
|
const vaultConfig = await loadVaultConfig(process2.cwd()).catch(() => null);
|
|
@@ -527,6 +539,8 @@ program.command("ingest").description("Ingest a local file path, directory path,
|
|
|
527
539
|
exclude: options.exclude,
|
|
528
540
|
maxFiles,
|
|
529
541
|
gitignore: options.gitignore,
|
|
542
|
+
swarmvaultignore: options.swarmvaultignore,
|
|
543
|
+
video: options.video,
|
|
530
544
|
extractClasses,
|
|
531
545
|
resume: options.resume,
|
|
532
546
|
redact: options.redact
|
|
@@ -643,10 +657,11 @@ program.command("ingest").description("Ingest a local file path, directory path,
|
|
|
643
657
|
}
|
|
644
658
|
}
|
|
645
659
|
);
|
|
646
|
-
program.command("add").description("Capture supported URLs into normalized markdown before ingesting them.").argument("<input>", "Supported URL or bare arXiv id").option("--author <name>", "Human author or curator for this capture").option("--contributor <name>", "Additional contributor metadata for this capture").option("--no-redact", "Skip PII/secret redaction for this capture (overrides config)").action(async (input, options) => {
|
|
660
|
+
program.command("add").description("Capture supported URLs into normalized markdown before ingesting them.").argument("<input>", "Supported URL or bare arXiv id").option("--author <name>", "Human author or curator for this capture").option("--contributor <name>", "Additional contributor metadata for this capture").option("--video", "Treat the URL as a public video and transcribe extracted audio", false).option("--no-redact", "Skip PII/secret redaction for this capture (overrides config)").action(async (input, options) => {
|
|
647
661
|
const result = await addInput(process2.cwd(), input, {
|
|
648
662
|
author: options.author,
|
|
649
663
|
contributor: options.contributor,
|
|
664
|
+
video: options.video,
|
|
650
665
|
redact: options.redact
|
|
651
666
|
});
|
|
652
667
|
if (isJson()) {
|
|
@@ -656,7 +671,7 @@ program.command("add").description("Capture supported URLs into normalized markd
|
|
|
656
671
|
}
|
|
657
672
|
});
|
|
658
673
|
var source = program.command("source").description("Manage recurring local files, directories, public repos, and docs sources.");
|
|
659
|
-
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 (default: from config)").option("--no-guide", "Skip guided mode even if enabled in config").option("--answers-file <path>", "JSON file with guided-session answers keyed by question id or listed in prompt order").option("--max-pages <n>", "Maximum number of pages to crawl for docs sources").option("--max-depth <n>", "Maximum crawl depth for docs sources").action(
|
|
674
|
+
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 (default: from config)").option("--no-guide", "Skip guided mode even if enabled in config").option("--answers-file <path>", "JSON file with guided-session answers keyed by question id or listed in prompt order").option("--max-pages <n>", "Maximum number of pages to crawl for docs sources").option("--max-depth <n>", "Maximum crawl depth for docs sources").option("--branch <name>", "GitHub branch to clone for public repo sources").option("--ref <ref>", "Git ref, tag, or commit to check out after cloning a public repo source").option("--checkout-dir <path>", "Persistent checkout directory for a public GitHub repo source").action(
|
|
660
675
|
async (input, options) => {
|
|
661
676
|
const guideAnswers = readGuideAnswersFile(options.answersFile);
|
|
662
677
|
const addConfig = await loadVaultConfig(process2.cwd()).catch(() => null);
|
|
@@ -668,7 +683,10 @@ source.command("add").description("Register and sync a managed source from a loc
|
|
|
668
683
|
guide: guideEnabled,
|
|
669
684
|
guideAnswers,
|
|
670
685
|
maxPages: options.maxPages ? parsePositiveInt(options.maxPages, 0) || void 0 : void 0,
|
|
671
|
-
maxDepth: options.maxDepth ? parsePositiveInt(options.maxDepth, 0) || void 0 : void 0
|
|
686
|
+
maxDepth: options.maxDepth ? parsePositiveInt(options.maxDepth, 0) || void 0 : void 0,
|
|
687
|
+
branch: options.branch,
|
|
688
|
+
ref: options.ref,
|
|
689
|
+
checkoutDir: options.checkoutDir
|
|
672
690
|
});
|
|
673
691
|
if (result.guide && !options.answersFile) {
|
|
674
692
|
result.guide = await completeGuideInteractively(result.guide, result.source.id);
|
|
@@ -1134,12 +1152,13 @@ program.command("lint").description("Run anti-drift and wiki-health checks.").op
|
|
|
1134
1152
|
});
|
|
1135
1153
|
var graph = program.command("graph").description("Graph-related commands.").enablePositionalOptions();
|
|
1136
1154
|
var graphPush = graph.command("push").description("Push the compiled graph into external sinks.");
|
|
1137
|
-
graph.command("update").alias("refresh").description("Refresh code-derived graph artifacts from tracked repo roots or one explicit repo path.").argument("[path]", "Optional repo root to refresh instead of configured/tracked roots").option("--lint", "Run lint after the refresh cycle", false).action(async (targetPath, options) => {
|
|
1155
|
+
graph.command("update").alias("refresh").description("Refresh code-derived graph artifacts from tracked repo roots or one explicit repo path.").argument("[path]", "Optional repo root to refresh instead of configured/tracked roots").option("--lint", "Run lint after the refresh cycle", false).option("--force", "Allow graph updates even when node or edge counts shrink sharply", false).action(async (targetPath, options) => {
|
|
1138
1156
|
const overrideRoots = targetPath ? [path2.resolve(process2.cwd(), targetPath)] : void 0;
|
|
1139
1157
|
const result = await runWatchCycle(process2.cwd(), {
|
|
1140
1158
|
repo: true,
|
|
1141
1159
|
codeOnly: true,
|
|
1142
1160
|
lint: options.lint ?? false,
|
|
1161
|
+
force: options.force ?? false,
|
|
1143
1162
|
overrideRoots
|
|
1144
1163
|
});
|
|
1145
1164
|
if (isJson()) {
|
|
@@ -1150,6 +1169,76 @@ graph.command("update").alias("refresh").description("Refresh code-derived graph
|
|
|
1150
1169
|
`Updated graph from ${result.watchedRepoRoots.length} repo root${result.watchedRepoRoots.length === 1 ? "" : "s"}. Imported ${result.repoImportedCount}, updated ${result.repoUpdatedCount}, removed ${result.repoRemovedCount}, pending semantic refresh ${result.pendingSemanticRefreshCount}.`
|
|
1151
1170
|
);
|
|
1152
1171
|
});
|
|
1172
|
+
graph.command("tree").description("Write a collapsible source/module/symbol tree for the compiled graph.").option("--output <html>", "Output HTML path (default: wiki/graph/tree.html)").option("--root <path>", "Vault root to read instead of the current directory").option("--label <name>", "Tree title").option("--max-children <n>", "Maximum children to render per tree node", "250").action(async (options) => {
|
|
1173
|
+
const rootDir = options.root ? path2.resolve(process2.cwd(), options.root) : process2.cwd();
|
|
1174
|
+
const result = await exportGraphTree(rootDir, options.output, {
|
|
1175
|
+
label: options.label,
|
|
1176
|
+
maxChildren: parsePositiveInt(options.maxChildren, 250)
|
|
1177
|
+
});
|
|
1178
|
+
if (isJson()) {
|
|
1179
|
+
emitJson(result);
|
|
1180
|
+
return;
|
|
1181
|
+
}
|
|
1182
|
+
log(`Graph tree: ${result.outputPath}`);
|
|
1183
|
+
log(`Sources: ${result.sourceCount}; nodes: ${result.nodeCount}.`);
|
|
1184
|
+
});
|
|
1185
|
+
graph.command("merge").description("Merge SwarmVault or node-link JSON graph files into one namespaced graph artifact.").argument("<graphs...>", "Graph JSON files to merge").requiredOption("--out <path>", "Output graph JSON path").option("--label <name>", "Label/prefix to use when merging one graph").action(async (graphPaths, options) => {
|
|
1186
|
+
const result = await mergeGraphFiles(
|
|
1187
|
+
graphPaths.map((inputPath) => path2.resolve(process2.cwd(), inputPath)),
|
|
1188
|
+
path2.resolve(process2.cwd(), options.out),
|
|
1189
|
+
{ label: options.label }
|
|
1190
|
+
);
|
|
1191
|
+
if (isJson()) {
|
|
1192
|
+
emitJson(result);
|
|
1193
|
+
return;
|
|
1194
|
+
}
|
|
1195
|
+
log(
|
|
1196
|
+
`Merged ${result.inputGraphs.length} graph${result.inputGraphs.length === 1 ? "" : "s"} into ${result.outputPath}. Nodes ${result.graph.nodes.length}, edges ${result.graph.edges.length}.`
|
|
1197
|
+
);
|
|
1198
|
+
for (const warning of result.warnings) {
|
|
1199
|
+
log(`Warning: ${warning}`);
|
|
1200
|
+
}
|
|
1201
|
+
});
|
|
1202
|
+
graph.command("status").description("Read-only check for graph/report presence and tracked repo changes.").argument("[path]", "Optional repo root to check instead of configured/tracked roots").action(async (targetPath) => {
|
|
1203
|
+
const overrideRoots = targetPath ? [path2.resolve(process2.cwd(), targetPath)] : void 0;
|
|
1204
|
+
const status = await getGraphStatus(process2.cwd(), { repoRoots: overrideRoots });
|
|
1205
|
+
if (isJson()) {
|
|
1206
|
+
emitJson(status);
|
|
1207
|
+
return;
|
|
1208
|
+
}
|
|
1209
|
+
log(`Graph: ${status.graphExists ? status.graphPath : `missing (${status.graphPath})`}`);
|
|
1210
|
+
log(`Report: ${status.reportExists ? status.reportPath : `missing (${status.reportPath})`}`);
|
|
1211
|
+
log(`Tracked repo roots: ${status.trackedRepoRoots.length ? status.trackedRepoRoots.join(", ") : "none"}`);
|
|
1212
|
+
log(`Code changes: ${status.codeChangeCount}`);
|
|
1213
|
+
log(`Semantic changes: ${status.semanticChangeCount}`);
|
|
1214
|
+
log(`Pending semantic refresh: ${status.pendingSemanticRefresh.length}`);
|
|
1215
|
+
if (status.changes.length) {
|
|
1216
|
+
for (const change of status.changes.slice(0, 20)) {
|
|
1217
|
+
log(`- ${change.refreshType} ${change.changeType} ${change.path}`);
|
|
1218
|
+
}
|
|
1219
|
+
if (status.changes.length > 20) {
|
|
1220
|
+
log(`... and ${status.changes.length - 20} more`);
|
|
1221
|
+
}
|
|
1222
|
+
}
|
|
1223
|
+
log(`State: ${status.stale ? "stale" : "fresh"}`);
|
|
1224
|
+
if (status.recommendedCommand) {
|
|
1225
|
+
log(`Recommended: ${status.recommendedCommand}`);
|
|
1226
|
+
}
|
|
1227
|
+
});
|
|
1228
|
+
graph.command("cluster").alias("clusters").description("Recompute graph communities, degrees, god-node flags, and graph report artifacts without re-ingesting sources.").option("--resolution <number>", "Override the Louvain community resolution for this run").action(async (options) => {
|
|
1229
|
+
const resolution = parsePositiveNumber(options.resolution);
|
|
1230
|
+
if (options.resolution && resolution === void 0) {
|
|
1231
|
+
throw new Error("--resolution must be a positive number.");
|
|
1232
|
+
}
|
|
1233
|
+
const result = await refreshGraphClusters(process2.cwd(), { resolution });
|
|
1234
|
+
if (isJson()) {
|
|
1235
|
+
emitJson(result);
|
|
1236
|
+
return;
|
|
1237
|
+
}
|
|
1238
|
+
log(
|
|
1239
|
+
`Refreshed ${result.communityCount} communities across ${result.nodeCount} nodes and ${result.edgeCount} edges. Report: ${result.reportPath}`
|
|
1240
|
+
);
|
|
1241
|
+
});
|
|
1153
1242
|
graphPush.command("neo4j").description("Push the compiled graph directly into Neo4j over Bolt/Aura.").option("--uri <bolt-uri>", "Neo4j Bolt or Aura URI").option("--username <user>", "Neo4j username").option("--password-env <env-var>", "Environment variable containing the Neo4j password").option("--database <name>", "Neo4j database name").option("--vault-id <id>", "Stable vault identifier used for shared-database namespacing").option("--batch-size <n>", "Maximum rows to write per Neo4j transaction batch").option("--include-third-party", "Also push third-party repo material", false).option("--include-resources", "Also push resource-like content", false).option("--include-generated", "Also push generated output", false).option("--dry-run", "Show what would be pushed without writing to Neo4j", false).action(
|
|
1154
1243
|
async (options) => {
|
|
1155
1244
|
const batchSize = typeof options.batchSize === "string" && options.batchSize.trim() ? parsePositiveInt(options.batchSize, 0) || void 0 : void 0;
|
|
@@ -1538,47 +1627,51 @@ async function confirmInteractive(message) {
|
|
|
1538
1627
|
rl.close();
|
|
1539
1628
|
}
|
|
1540
1629
|
}
|
|
1541
|
-
var watch = program.command("watch").description("Watch the inbox directory and optionally tracked repos, or run one refresh cycle immediately.").option("--lint", "Run lint after each compile cycle", false).option("--repo", "Also refresh tracked repo sources and watch their repo roots", false).option("--once", "Run one import/refresh cycle immediately instead of starting a watcher", false).option("--code-only", "Only re-extract code sources (AST-only, no LLM re-analysis)", false).option("--debounce <ms>", "Debounce window in milliseconds", "900").option("--root <path>", "Watch this repo root instead of config/auto-discovery (repeat for multiple)", collectRepeated, []).
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1630
|
+
var watch = program.command("watch").description("Watch the inbox directory and optionally tracked repos, or run one refresh cycle immediately.").option("--lint", "Run lint after each compile cycle", false).option("--repo", "Also refresh tracked repo sources and watch their repo roots", false).option("--once", "Run one import/refresh cycle immediately instead of starting a watcher", false).option("--code-only", "Only re-extract code sources (AST-only, no LLM re-analysis)", false).option("--debounce <ms>", "Debounce window in milliseconds", "900").option("--root <path>", "Watch this repo root instead of config/auto-discovery (repeat for multiple)", collectRepeated, []).option("--force", "Allow graph updates even when node or edge counts shrink sharply", false).action(
|
|
1631
|
+
async (options) => {
|
|
1632
|
+
const debounceMs = parsePositiveInt(options.debounce, 900);
|
|
1633
|
+
const overrideRoots = options.root && options.root.length > 0 ? options.root : void 0;
|
|
1634
|
+
if (options.once) {
|
|
1635
|
+
const result = await runWatchCycle(process2.cwd(), {
|
|
1636
|
+
lint: options.lint ?? false,
|
|
1637
|
+
repo: options.repo ?? false,
|
|
1638
|
+
codeOnly: options.codeOnly ?? false,
|
|
1639
|
+
debounceMs,
|
|
1640
|
+
force: options.force ?? false,
|
|
1641
|
+
overrideRoots
|
|
1642
|
+
});
|
|
1643
|
+
if (isJson()) {
|
|
1644
|
+
emitJson(result);
|
|
1645
|
+
} else {
|
|
1646
|
+
log(
|
|
1647
|
+
`Refreshed inbox${options.repo ? " and tracked repos" : ""}. Imported ${result.importedCount}, repo imported ${result.repoImportedCount}, repo updated ${result.repoUpdatedCount}, repo removed ${result.repoRemovedCount}.`
|
|
1648
|
+
);
|
|
1649
|
+
}
|
|
1650
|
+
return;
|
|
1651
|
+
}
|
|
1652
|
+
const { paths } = await loadVaultConfig(process2.cwd());
|
|
1653
|
+
const controller = await watchVault(process2.cwd(), {
|
|
1546
1654
|
lint: options.lint ?? false,
|
|
1547
1655
|
repo: options.repo ?? false,
|
|
1548
1656
|
codeOnly: options.codeOnly ?? false,
|
|
1549
1657
|
debounceMs,
|
|
1658
|
+
force: options.force ?? false,
|
|
1550
1659
|
overrideRoots
|
|
1551
1660
|
});
|
|
1552
1661
|
if (isJson()) {
|
|
1553
|
-
emitJson(
|
|
1662
|
+
emitJson({ status: "watching", inboxDir: paths.inboxDir, repo: options.repo ?? false });
|
|
1554
1663
|
} else {
|
|
1555
|
-
log(
|
|
1556
|
-
`Refreshed inbox${options.repo ? " and tracked repos" : ""}. Imported ${result.importedCount}, repo imported ${result.repoImportedCount}, repo updated ${result.repoUpdatedCount}, repo removed ${result.repoRemovedCount}.`
|
|
1557
|
-
);
|
|
1664
|
+
log(`Watching inbox${options.repo ? " and tracked repos" : ""} for changes. Press Ctrl+C to stop.`);
|
|
1558
1665
|
}
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
debounceMs,
|
|
1567
|
-
overrideRoots
|
|
1568
|
-
});
|
|
1569
|
-
if (isJson()) {
|
|
1570
|
-
emitJson({ status: "watching", inboxDir: paths.inboxDir, repo: options.repo ?? false });
|
|
1571
|
-
} else {
|
|
1572
|
-
log(`Watching inbox${options.repo ? " and tracked repos" : ""} for changes. Press Ctrl+C to stop.`);
|
|
1666
|
+
process2.on("SIGINT", async () => {
|
|
1667
|
+
try {
|
|
1668
|
+
await controller.close();
|
|
1669
|
+
} catch {
|
|
1670
|
+
}
|
|
1671
|
+
process2.exit(0);
|
|
1672
|
+
});
|
|
1573
1673
|
}
|
|
1574
|
-
|
|
1575
|
-
try {
|
|
1576
|
-
await controller.close();
|
|
1577
|
-
} catch {
|
|
1578
|
-
}
|
|
1579
|
-
process2.exit(0);
|
|
1580
|
-
});
|
|
1581
|
-
});
|
|
1674
|
+
);
|
|
1582
1675
|
watch.command("list-roots").description("Print the effective watched repo roots resolved from config and auto-discovery.").action(async () => {
|
|
1583
1676
|
const roots = await listWatchedRoots(process2.cwd());
|
|
1584
1677
|
if (isJson()) {
|
|
@@ -2103,20 +2196,33 @@ retrieval.command("doctor").description("Diagnose retrieval index problems and o
|
|
|
2103
2196
|
log(`Warning: ${warning}`);
|
|
2104
2197
|
}
|
|
2105
2198
|
});
|
|
2106
|
-
program.command("scan").description("Quick-start: initialize, ingest, compile, and serve a graph viewer in one command.").argument("<
|
|
2199
|
+
program.command("scan").description("Quick-start: initialize, ingest, compile, and serve a graph viewer in one command.").argument("<input>", "Directory or public GitHub repo root URL to scan").option("--port <port>", "Port for the graph viewer").option("--no-serve", "Skip launching the graph viewer after compile").option("--branch <name>", "GitHub branch to clone when scanning a public repo URL").option("--ref <ref>", "Git ref, tag, or commit to check out when scanning a public repo URL").option("--checkout-dir <path>", "Persistent checkout directory for a public GitHub repo scan").action(async (input, options) => {
|
|
2107
2200
|
const rootDir = process2.cwd();
|
|
2108
2201
|
await initVault(rootDir, {});
|
|
2109
2202
|
if (!isJson()) {
|
|
2110
2203
|
log("Initialized workspace.");
|
|
2111
2204
|
}
|
|
2112
|
-
const result = await
|
|
2205
|
+
const result = isHttpUrlInput(input) ? await addManagedSource(rootDir, input, {
|
|
2206
|
+
compile: true,
|
|
2207
|
+
brief: false,
|
|
2208
|
+
branch: options.branch,
|
|
2209
|
+
ref: options.ref,
|
|
2210
|
+
checkoutDir: options.checkoutDir
|
|
2211
|
+
}) : await ingestDirectory(rootDir, input, {});
|
|
2113
2212
|
if (!isJson()) {
|
|
2114
|
-
|
|
2213
|
+
if ("source" in result) {
|
|
2214
|
+
log(
|
|
2215
|
+
`Registered ${result.source.kind} source ${result.source.id}. Imported ${result.source.lastSyncCounts?.importedCount ?? 0}, updated ${result.source.lastSyncCounts?.updatedCount ?? 0}.`
|
|
2216
|
+
);
|
|
2217
|
+
} else {
|
|
2218
|
+
log(`Ingested ${result.imported.length} file(s).`);
|
|
2219
|
+
}
|
|
2115
2220
|
}
|
|
2116
|
-
const compiled = await compileVault(rootDir, {});
|
|
2117
|
-
const
|
|
2118
|
-
const
|
|
2119
|
-
const
|
|
2221
|
+
const compiled = "compile" in result && result.compile ? result.compile : await compileVault(rootDir, {});
|
|
2222
|
+
const { paths } = await loadVaultConfig(rootDir);
|
|
2223
|
+
const shareCardPath = path2.join(paths.wikiDir, "graph", "share-card.md");
|
|
2224
|
+
const shareCardSvgPath = path2.join(paths.wikiDir, "graph", "share-card.svg");
|
|
2225
|
+
const shareKitPath = path2.join(paths.wikiDir, "graph", "share-kit");
|
|
2120
2226
|
if (!isJson()) {
|
|
2121
2227
|
log(`Compiled ${compiled.sourceCount} source(s), ${compiled.pageCount} page(s).`);
|
|
2122
2228
|
log(`Share card: ${shareCardPath}`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@swarmvaultai/cli",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.7.0",
|
|
4
4
|
"description": "Global CLI for SwarmVault.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
"prepublishOnly": "node ../../scripts/check-release-sync.mjs && node ../../scripts/check-published-manifests.mjs"
|
|
45
45
|
},
|
|
46
46
|
"dependencies": {
|
|
47
|
-
"@swarmvaultai/engine": "3.
|
|
47
|
+
"@swarmvaultai/engine": "3.7.0",
|
|
48
48
|
"commander": "^14.0.1"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|