@swarmvaultai/cli 3.14.1 → 3.15.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 +17 -7
- package/dist/index.js +32 -16
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -105,25 +105,26 @@ Set `SWARMVAULT_OUT=<dir>` when generated artifacts should be isolated from the
|
|
|
105
105
|
|
|
106
106
|
`--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`.
|
|
107
107
|
|
|
108
|
-
### `swarmvault quickstart <directory|github-url> [--port <port>] [--no-serve] [--no-viz] [--mcp] [--branch <name>] [--ref <ref>] [--checkout-dir <path>]`
|
|
108
|
+
### `swarmvault quickstart <file|directory|github-url> [--port <port>] [--no-serve] [--no-viz] [--mcp] [--branch <name>] [--ref <ref>] [--checkout-dir <path>] [--install-agent-rules]`
|
|
109
109
|
|
|
110
110
|
Beginner-friendly alias for `swarmvault scan`.
|
|
111
111
|
|
|
112
112
|
- initializes the current directory as a SwarmVault workspace
|
|
113
|
-
- ingests the supplied local directory, or registers/syncs the supplied public GitHub repo root URL
|
|
113
|
+
- ingests the supplied local file or directory, or registers/syncs the supplied public GitHub repo root URL
|
|
114
114
|
- compiles wiki, graph, search, and share artifacts immediately
|
|
115
115
|
- prints the generated `raw/`, `wiki/`, `state/graph.json`, and `wiki/graph/` paths in human output
|
|
116
116
|
- starts `graph serve` unless you pass `--no-serve` or `--no-viz`
|
|
117
117
|
- keeps the same JSON output contract as `scan`
|
|
118
|
+
- leaves agent rule files alone unless you pass `--install-agent-rules`
|
|
118
119
|
|
|
119
120
|
Use this as the default first-run command in docs and onboarding.
|
|
120
121
|
|
|
121
|
-
### `swarmvault scan <directory|github-url> [--port <port>] [--no-serve] [--no-viz] [--mcp] [--branch <name>] [--ref <ref>] [--checkout-dir <path>]`
|
|
122
|
+
### `swarmvault scan <file|directory|github-url> [--port <port>] [--no-serve] [--no-viz] [--mcp] [--branch <name>] [--ref <ref>] [--checkout-dir <path>] [--install-agent-rules]`
|
|
122
123
|
|
|
123
|
-
Quick-start a scratch vault from a local directory or public GitHub repo root URL in one command.
|
|
124
|
+
Quick-start a scratch vault from a local file, directory, or public GitHub repo root URL in one command.
|
|
124
125
|
|
|
125
126
|
- initializes the current directory as a SwarmVault workspace
|
|
126
|
-
- ingests the supplied directory as local sources, or registers/syncs the supplied public GitHub repo root URL
|
|
127
|
+
- ingests the supplied file or directory as local sources, or registers/syncs the supplied public GitHub repo root URL
|
|
127
128
|
- compiles the vault immediately
|
|
128
129
|
- writes `wiki/graph/share-card.md`, `wiki/graph/share-card.svg`, and `wiki/graph/share-kit/`, then prints the paths
|
|
129
130
|
- starts `graph serve` unless you pass `--no-serve` or `--no-viz`
|
|
@@ -131,10 +132,11 @@ Quick-start a scratch vault from a local directory or public GitHub repo root UR
|
|
|
131
132
|
- `--mcp` starts the MCP stdio server after compile instead of the graph viewer
|
|
132
133
|
- respects `--port` when you want a specific viewer port
|
|
133
134
|
- for GitHub repo URLs, supports `--branch`, `--ref`, and `--checkout-dir`
|
|
135
|
+
- `--install-agent-rules` installs the configured `agents` targets during initialization
|
|
134
136
|
|
|
135
137
|
Use this when you want the fastest repo or docs-tree walkthrough without first deciding on managed-source registration.
|
|
136
138
|
|
|
137
|
-
### `swarmvault clone <directory|github-url> [--no-viz] [--mcp] [--branch <name>] [--ref <ref>] [--checkout-dir <path>]`
|
|
139
|
+
### `swarmvault clone <file|directory|github-url> [--no-viz] [--mcp] [--branch <name>] [--ref <ref>] [--checkout-dir <path>] [--install-agent-rules]`
|
|
138
140
|
|
|
139
141
|
Compatibility alias for `swarmvault scan`.
|
|
140
142
|
|
|
@@ -268,7 +270,7 @@ Useful flags:
|
|
|
268
270
|
|
|
269
271
|
Repo ingest defaults to `first_party` material. The extra `--include-*` flags opt dependency trees, resource bundles, and generated output back in when you actually want them in the vault.
|
|
270
272
|
|
|
271
|
-
|
|
273
|
+
Interactive file and directory ingest now emits bounded stderr progress, including the active file and processed content size. JSON, MCP, watch, and CI-style flows stay quiet, and parser compatibility failures stay local to the affected source instead of aborting unrelated analysis.
|
|
272
274
|
|
|
273
275
|
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.
|
|
274
276
|
|
|
@@ -303,6 +305,8 @@ Compile the current manifests into:
|
|
|
303
305
|
|
|
304
306
|
The compiler also reads `swarmvault.schema.md` and records a `schema_hash` plus lifecycle metadata such as `status`, `created_at`, `updated_at`, `compiled_from`, and `managed_by` in generated pages so schema edits can mark pages stale without losing lifecycle state.
|
|
305
307
|
|
|
308
|
+
Large compile runs process source analysis in bounded batches and use a sparse graph co-occurrence projection so high-overlap note sets do not explode into unbounded pairwise graph work.
|
|
309
|
+
|
|
306
310
|
For ingested code trees, compile also writes `state/code-index.json` so local imports and module aliases can resolve across the repo-aware code graph.
|
|
307
311
|
|
|
308
312
|
New concept and entity pages are staged into `wiki/candidates/` first. A later matching compile promotes them into `wiki/concepts/` or `wiki/entities/`.
|
|
@@ -713,6 +717,8 @@ Defaults:
|
|
|
713
717
|
|
|
714
718
|
Install agent-specific rules into the current project so an agent understands the SwarmVault workspace contract and workflow.
|
|
715
719
|
|
|
720
|
+
`init`, `quickstart`, `scan`, and `clone` do not write project-local agent rule files by default. Run `swarmvault install --agent <agent>` for one target at a time, or list targets in `swarmvault.config.json` and pass `--install-agent-rules` to `init`, `quickstart`, `scan`, or `clone` when you intentionally want configured targets installed together.
|
|
721
|
+
|
|
716
722
|
Hook-capable installs:
|
|
717
723
|
|
|
718
724
|
```bash
|
|
@@ -739,6 +745,8 @@ Agent target mapping:
|
|
|
739
745
|
- `antigravity` writes `.agents/rules/swarmvault.md` and `.agents/workflows/swarmvault.md`, and removes older fully managed `.agent/` files during reinstall
|
|
740
746
|
- `vscode` writes `.github/chatmodes/swarmvault.chatmode.md` plus `.github/copilot-instructions.md`
|
|
741
747
|
|
|
748
|
+
SwarmVault only owns the managed block inside shared markdown rule files. It keeps the SwarmVault block aligned across targets while preserving any user-owned text before or after the block, so `AGENTS.md` and `CLAUDE.md` do not need to be byte-identical.
|
|
749
|
+
|
|
742
750
|
Hook semantics:
|
|
743
751
|
|
|
744
752
|
- `codex --hook` writes `.codex/hooks.json` plus `.codex/hooks/swarmvault-graph-first.js` and emits model-visible guidance before broad shell search
|
|
@@ -841,6 +849,8 @@ Search behavior is configurable separately from provider routing:
|
|
|
841
849
|
- If a provider claims OpenAI compatibility but fails structured generation, declare only the capabilities it actually supports
|
|
842
850
|
- If `lint --deep --web` fails immediately, make sure a `webSearch` provider is configured and mapped to `tasks.deepLintProvider`
|
|
843
851
|
- If you still see a `node:sqlite` experimental warning on Node 24, upgrade to the latest CLI; current releases suppress that upstream warning during normal runs
|
|
852
|
+
- If compile reports `Failed to parse JSON file ...`, the named derived state file is corrupt or empty. Remove the named file or restore it from git, then rerun `swarmvault compile`; current releases write JSON state atomically to reduce partial-file failures.
|
|
853
|
+
- If a large heuristic vault fails with heap exhaustion or `Map maximum size exceeded` on an older CLI, upgrade and rerun compile. Current releases bound analysis concurrency and graph projection during compile.
|
|
844
854
|
|
|
845
855
|
## Links
|
|
846
856
|
|
package/dist/index.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
// src/index.ts
|
|
4
4
|
import { readFileSync } from "fs";
|
|
5
|
-
import { access, mkdir as mkdir2, readFile as readFile2, writeFile as writeFile2 } from "fs/promises";
|
|
5
|
+
import { access, mkdir as mkdir2, readFile as readFile2, stat, writeFile as writeFile2 } from "fs/promises";
|
|
6
6
|
import path2 from "path";
|
|
7
7
|
import process2 from "process";
|
|
8
8
|
import { createInterface } from "readline/promises";
|
|
@@ -330,9 +330,9 @@ program.addHelpText(
|
|
|
330
330
|
function readCliVersion() {
|
|
331
331
|
try {
|
|
332
332
|
const packageJson = JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf8"));
|
|
333
|
-
return typeof packageJson.version === "string" && packageJson.version.trim() ? packageJson.version : "3.
|
|
333
|
+
return typeof packageJson.version === "string" && packageJson.version.trim() ? packageJson.version : "3.15.0";
|
|
334
334
|
} catch {
|
|
335
|
-
return "3.
|
|
335
|
+
return "3.15.0";
|
|
336
336
|
}
|
|
337
337
|
}
|
|
338
338
|
function parsePositiveInt(value, fallback) {
|
|
@@ -818,7 +818,8 @@ async function runGraphMergeCommand(graphPaths, options) {
|
|
|
818
818
|
}
|
|
819
819
|
async function runScanCommand(input, options) {
|
|
820
820
|
const rootDir = process2.cwd();
|
|
821
|
-
|
|
821
|
+
const progress = !isJson() && !options.mcp;
|
|
822
|
+
await initVault(rootDir, { installAgentRules: options.installAgentRules ?? false });
|
|
822
823
|
if (!isJson()) {
|
|
823
824
|
log("Initialized workspace.");
|
|
824
825
|
}
|
|
@@ -828,14 +829,17 @@ async function runScanCommand(input, options) {
|
|
|
828
829
|
branch: options.branch,
|
|
829
830
|
ref: options.ref,
|
|
830
831
|
checkoutDir: options.checkoutDir
|
|
831
|
-
}) : await
|
|
832
|
+
}) : await ingestScanInput(rootDir, input, progress);
|
|
832
833
|
if (!isJson()) {
|
|
833
834
|
if ("source" in result) {
|
|
834
835
|
log(
|
|
835
836
|
`Registered ${result.source.kind} source ${result.source.id}. Imported ${result.source.lastSyncCounts?.importedCount ?? 0}, updated ${result.source.lastSyncCounts?.updatedCount ?? 0}.`
|
|
836
837
|
);
|
|
837
|
-
} else {
|
|
838
|
+
} else if ("inputDir" in result) {
|
|
838
839
|
log(`Ingested ${result.imported.length} file(s).`);
|
|
840
|
+
} else {
|
|
841
|
+
const sourceCount = result.created.length + result.updated.length + result.unchanged.length;
|
|
842
|
+
log(`Ingested ${sourceCount} source(s).`);
|
|
839
843
|
}
|
|
840
844
|
}
|
|
841
845
|
const compiled = "compile" in result && result.compile ? result.compile : await compileVault(rootDir, {});
|
|
@@ -901,6 +905,17 @@ async function runScanCommand(input, options) {
|
|
|
901
905
|
emitJson({ ...result, compiled, shareCardPath, shareCardSvgPath, shareKitPath });
|
|
902
906
|
}
|
|
903
907
|
}
|
|
908
|
+
async function ingestScanInput(rootDir, input, progress) {
|
|
909
|
+
const absoluteInput = path2.resolve(rootDir, input);
|
|
910
|
+
const inputStat = await stat(absoluteInput);
|
|
911
|
+
if (inputStat.isDirectory()) {
|
|
912
|
+
return ingestDirectory(rootDir, input, { progress });
|
|
913
|
+
}
|
|
914
|
+
if (inputStat.isFile()) {
|
|
915
|
+
return ingestInputDetailed(rootDir, input, { progress });
|
|
916
|
+
}
|
|
917
|
+
throw new Error(`Input must be a file or directory: ${input}`);
|
|
918
|
+
}
|
|
904
919
|
async function resolveChatResumeId(resume) {
|
|
905
920
|
if (!resume) {
|
|
906
921
|
return void 0;
|
|
@@ -1022,7 +1037,7 @@ program.command("next").description("Show the safest next command for this direc
|
|
|
1022
1037
|
}
|
|
1023
1038
|
printNextCommandReport(report);
|
|
1024
1039
|
});
|
|
1025
|
-
program.command("quickstart").description("Beginner path: initialize, ingest, compile, and optionally open the graph viewer in one command.").argument("<input>", "Directory or public GitHub repo root URL to turn into a vault").option("--port <port>", "Port for the graph viewer").option("--no-serve", "Skip launching the graph viewer after compile").option("--no-viz", "Compatibility alias for --no-serve; skip launching the graph viewer after compile").option("--mcp", "Start the MCP stdio server after compile instead of launching the graph viewer", false).option("--branch <name>", "GitHub branch to clone when the input is a public repo URL").option("--ref <ref>", "Git ref, tag, or commit to check out when the input is a public repo URL").option("--checkout-dir <path>", "Persistent checkout directory for a public GitHub repo input").action(runScanCommand);
|
|
1040
|
+
program.command("quickstart").description("Beginner path: initialize, ingest, compile, and optionally open the graph viewer in one command.").argument("<input>", "Directory or public GitHub repo root URL to turn into a vault").option("--port <port>", "Port for the graph viewer").option("--no-serve", "Skip launching the graph viewer after compile").option("--no-viz", "Compatibility alias for --no-serve; skip launching the graph viewer after compile").option("--mcp", "Start the MCP stdio server after compile instead of launching the graph viewer", false).option("--branch <name>", "GitHub branch to clone when the input is a public repo URL").option("--ref <ref>", "Git ref, tag, or commit to check out when the input is a public repo URL").option("--checkout-dir <path>", "Persistent checkout directory for a public GitHub repo input").option("--install-agent-rules", "Install configured agent rule files during initialization", false).action(runScanCommand);
|
|
1026
1041
|
program.command("init").description("Initialize a SwarmVault workspace in the current directory.").option("--obsidian", "Generate a minimal .obsidian workspace alongside the vault", false).option(
|
|
1027
1042
|
"--profile <profile>",
|
|
1028
1043
|
"Starter workspace profile or comma-separated preset list (for example: personal-research or reader,timeline)"
|
|
@@ -1030,11 +1045,12 @@ program.command("init").description("Initialize a SwarmVault workspace in the cu
|
|
|
1030
1045
|
"--lite",
|
|
1031
1046
|
"Minimal LLM-Wiki starter (raw/, wiki/, wiki/index.md, wiki/log.md, swarmvault.schema.md) without config, state, or agent installs",
|
|
1032
1047
|
false
|
|
1033
|
-
).action(async (options) => {
|
|
1048
|
+
).option("--install-agent-rules", "Install configured agent rule files during initialization", false).action(async (options) => {
|
|
1034
1049
|
await initVault(process2.cwd(), {
|
|
1035
1050
|
obsidian: options.obsidian ?? false,
|
|
1036
1051
|
profile: options.profile,
|
|
1037
|
-
lite: options.lite ?? false
|
|
1052
|
+
lite: options.lite ?? false,
|
|
1053
|
+
installAgentRules: options.installAgentRules ?? false
|
|
1038
1054
|
});
|
|
1039
1055
|
if (isJson()) {
|
|
1040
1056
|
emitJson({
|
|
@@ -1042,7 +1058,8 @@ program.command("init").description("Initialize a SwarmVault workspace in the cu
|
|
|
1042
1058
|
rootDir: process2.cwd(),
|
|
1043
1059
|
obsidian: options.obsidian ?? false,
|
|
1044
1060
|
profile: options.profile ?? "default",
|
|
1045
|
-
lite: options.lite ?? false
|
|
1061
|
+
lite: options.lite ?? false,
|
|
1062
|
+
installAgentRules: options.installAgentRules ?? false
|
|
1046
1063
|
});
|
|
1047
1064
|
} else {
|
|
1048
1065
|
log(options.lite ? "Initialized SwarmVault lite workspace." : "Initialized SwarmVault workspace.");
|
|
@@ -1074,11 +1091,10 @@ program.command("ingest").description("Ingest a local file path, directory path,
|
|
|
1074
1091
|
video: options.video,
|
|
1075
1092
|
extractClasses,
|
|
1076
1093
|
resume: options.resume,
|
|
1077
|
-
redact: options.redact
|
|
1094
|
+
redact: options.redact,
|
|
1095
|
+
progress: !isJson()
|
|
1078
1096
|
};
|
|
1079
|
-
const directoryResult = !/^https?:\/\//i.test(input) ? await
|
|
1080
|
-
(fs) => fs.stat(input).then((stat) => stat.isDirectory() ? ingestDirectory(process2.cwd(), input, commonOptions) : null).catch(() => null)
|
|
1081
|
-
) : null;
|
|
1097
|
+
const directoryResult = !/^https?:\/\//i.test(input) ? await stat(input).then((inputStat) => inputStat.isDirectory() ? ingestDirectory(process2.cwd(), input, commonOptions) : null).catch(() => null) : null;
|
|
1082
1098
|
if (directoryResult) {
|
|
1083
1099
|
const scope2 = options.review || guideEnabled ? await (async () => {
|
|
1084
1100
|
const pathModule = await import("path");
|
|
@@ -2765,8 +2781,8 @@ retrieval.command("doctor").description("Diagnose retrieval index problems and o
|
|
|
2765
2781
|
log(`Warning: ${warning}`);
|
|
2766
2782
|
}
|
|
2767
2783
|
});
|
|
2768
|
-
program.command("scan", { hidden: true }).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("--no-viz", "Compatibility alias for --no-serve; skip launching the graph viewer after compile").option("--mcp", "Start the MCP stdio server after compile instead of launching the graph viewer", false).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(runScanCommand);
|
|
2769
|
-
program.command("clone", { hidden: true }).description("Compatibility alias for scan: initialize, clone/register a public repo URL, and compile it into the vault.").argument("<input>", "Public GitHub repo URL or local directory to scan").option("--port <port>", "Port for the graph viewer").option("--no-serve", "Skip launching the graph viewer after compile").option("--no-viz", "Compatibility alias for --no-serve; skip launching the graph viewer after compile").option("--mcp", "Start the MCP stdio server after compile instead of launching the graph viewer", false).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(runScanCommand);
|
|
2784
|
+
program.command("scan", { hidden: true }).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("--no-viz", "Compatibility alias for --no-serve; skip launching the graph viewer after compile").option("--mcp", "Start the MCP stdio server after compile instead of launching the graph viewer", false).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").option("--install-agent-rules", "Install configured agent rule files during initialization", false).action(runScanCommand);
|
|
2785
|
+
program.command("clone", { hidden: true }).description("Compatibility alias for scan: initialize, clone/register a public repo URL, and compile it into the vault.").argument("<input>", "Public GitHub repo URL or local directory to scan").option("--port <port>", "Port for the graph viewer").option("--no-serve", "Skip launching the graph viewer after compile").option("--no-viz", "Compatibility alias for --no-serve; skip launching the graph viewer after compile").option("--mcp", "Start the MCP stdio server after compile instead of launching the graph viewer", false).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").option("--install-agent-rules", "Install configured agent rule files during initialization", false).action(runScanCommand);
|
|
2770
2786
|
function enableStructuredJsonOnSubcommands(command) {
|
|
2771
2787
|
for (const subcommand of command.commands) {
|
|
2772
2788
|
const hasJsonOption = subcommand.options.some((option) => option.attributeName() === "json");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@swarmvaultai/cli",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.15.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.15.0",
|
|
48
48
|
"commander": "^14.0.1"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|