@swarmvaultai/cli 0.7.21 → 0.7.22

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.
Files changed (3) hide show
  1. package/README.md +15 -4
  2. package/dist/index.js +46 -24
  3. package/package.json +2 -2
package/README.md CHANGED
@@ -250,6 +250,8 @@ Watch the inbox directory and trigger import and compile cycles when files chang
250
250
 
251
251
  When `--repo` sees non-code changes under tracked repo roots, SwarmVault records those files under `state/watch/pending-semantic-refresh.json`, marks affected compiled pages stale, and exposes the pending set through `watch status` and the local graph workspace instead of silently re-ingesting them.
252
252
 
253
+ When `--repo` sees only code-file changes under tracked repo roots, SwarmVault takes the faster code-only path: it refreshes code pages and graph structure without re-running non-code semantic analysis for unchanged sources.
254
+
253
255
  ### `swarmvault watch status`
254
256
 
255
257
  Show watched repo roots, the latest watch run, and any pending semantic refresh entries for tracked non-code repo changes.
@@ -299,14 +301,20 @@ Inspect graph metadata, community membership, neighbors, provenance, and group-p
299
301
 
300
302
  List the most connected bridge-heavy nodes in the current graph.
301
303
 
302
- ### `swarmvault graph export --html|--svg|--graphml|--cypher <output>`
304
+ ### `swarmvault graph export --html|--html-standalone|--svg|--graphml|--cypher|--json|--obsidian|--canvas <output>`
303
305
 
304
- Export the current graph as one of four formats:
306
+ Export the current graph as one or more shareable formats:
305
307
 
306
- - `--html` for the standalone read-only graph workspace
308
+ - `--html` for the full self-contained read-only graph workspace
309
+ - `--html-standalone` for a lighter vis.js export with node search, legend, and sidebar inspection
307
310
  - `--svg` for a static shareable diagram
308
311
  - `--graphml` for graph-tool interoperability
309
312
  - `--cypher` for Neo4j-style import scripts
313
+ - `--json` for a deterministic machine-readable graph package
314
+ - `--obsidian` for an Obsidian-friendly markdown vault with one note per node plus community notes
315
+ - `--canvas` for an Obsidian canvas grouped by community
316
+
317
+ You can combine multiple flags in one run to write several exports at once.
310
318
 
311
319
  ### `swarmvault graph push neo4j`
312
320
 
@@ -331,7 +339,7 @@ Defaults:
331
339
  - namespaces every remote record by `vaultId` so multiple vaults can safely share one Neo4j database
332
340
  - upserts current graph records and does not prune stale remote data yet
333
341
 
334
- ### `swarmvault install --agent <codex|claude|cursor|goose|pi|gemini|opencode|aider|copilot>`
342
+ ### `swarmvault install --agent <codex|claude|cursor|goose|pi|gemini|opencode|aider|copilot|trae|claw|droid>`
335
343
 
336
344
  Install agent-specific rules into the current project so an agent understands the SwarmVault workspace contract and workflow.
337
345
 
@@ -352,6 +360,9 @@ Agent target mapping:
352
360
  - `aider` writes `CONVENTIONS.md` and merges `.aider.conf.yml`
353
361
  - `copilot` writes `.github/copilot-instructions.md` plus `AGENTS.md`
354
362
  - `cursor` writes `.cursor/rules/swarmvault.mdc`
363
+ - `trae` writes `.trae/rules/swarmvault.md`
364
+ - `claw` writes `.claw/skills/swarmvault/SKILL.md`
365
+ - `droid` writes `.factory/rules/swarmvault.md`
355
366
 
356
367
  Hook semantics:
357
368
 
package/dist/index.js CHANGED
@@ -16,6 +16,8 @@ import {
16
16
  exploreVault,
17
17
  exportGraphFormat,
18
18
  exportGraphHtml,
19
+ exportObsidianCanvas,
20
+ exportObsidianVault,
19
21
  getGitHookStatus,
20
22
  getWatchStatus,
21
23
  guideManagedSource,
@@ -268,9 +270,9 @@ program.name("swarmvault").description("SwarmVault is a local-first knowledge co
268
270
  function readCliVersion() {
269
271
  try {
270
272
  const packageJson = JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf8"));
271
- return typeof packageJson.version === "string" && packageJson.version.trim() ? packageJson.version : "0.7.21";
273
+ return typeof packageJson.version === "string" && packageJson.version.trim() ? packageJson.version : "0.7.22";
272
274
  } catch {
273
- return "0.7.21";
275
+ return "0.7.22";
274
276
  }
275
277
  }
276
278
  function parsePositiveInt(value, fallback) {
@@ -812,29 +814,49 @@ graph.command("serve").description("Serve the local graph viewer.").option("--po
812
814
  process2.exit(0);
813
815
  });
814
816
  });
815
- graph.command("export").description("Export the graph as HTML, SVG, GraphML, or Cypher. Combine flags to write multiple formats in one run.").option("--html <output>", "Output HTML file path").option("--svg <output>", "Output SVG file path").option("--graphml <output>", "Output GraphML file path").option("--cypher <output>", "Output Cypher file path").option("--full", "Disable overview sampling for HTML export", false).action(async (options) => {
816
- const targets = [
817
- options.html ? { format: "html", outputPath: options.html } : null,
818
- options.svg ? { format: "svg", outputPath: options.svg } : null,
819
- options.graphml ? { format: "graphml", outputPath: options.graphml } : null,
820
- options.cypher ? { format: "cypher", outputPath: options.cypher } : null
821
- ].filter((target) => Boolean(target));
822
- if (targets.length === 0) {
823
- throw new Error("Pass at least one of --html, --svg, --graphml, or --cypher.");
824
- }
825
- const results = [];
826
- for (const target of targets) {
827
- const outputPath = target.format === "html" ? await exportGraphHtml(process2.cwd(), target.outputPath, { full: options.full ?? false }) : (await exportGraphFormat(process2.cwd(), target.format, target.outputPath)).outputPath;
828
- results.push({ format: target.format, outputPath });
829
- }
830
- if (isJson()) {
831
- emitJson(results.length === 1 ? results[0] : { exports: results });
832
- } else {
833
- for (const result of results) {
834
- log(`Exported graph ${result.format} to ${result.outputPath}`);
817
+ graph.command("export").description(
818
+ "Export the graph as HTML, SVG, GraphML, Cypher, JSON, Obsidian vault, or Obsidian canvas. Combine flags to write multiple formats in one run."
819
+ ).option("--html <output>", "Output HTML file path").option("--html-standalone <output>", "Output lightweight standalone HTML file path (vis.js, no build tooling)").option("--svg <output>", "Output SVG file path").option("--graphml <output>", "Output GraphML file path").option("--cypher <output>", "Output Cypher file path").option("--json <output>", "Output JSON file path").option("--obsidian <output>", "Output Obsidian vault directory path").option("--canvas <output>", "Output Obsidian canvas file path").option("--full", "Disable overview sampling for HTML export", false).action(
820
+ async (options) => {
821
+ const targets = [
822
+ options.html ? { format: "html", outputPath: options.html } : null,
823
+ options.htmlStandalone ? { format: "html-standalone", outputPath: options.htmlStandalone } : null,
824
+ options.svg ? { format: "svg", outputPath: options.svg } : null,
825
+ options.graphml ? { format: "graphml", outputPath: options.graphml } : null,
826
+ options.cypher ? { format: "cypher", outputPath: options.cypher } : null,
827
+ options.json ? { format: "json", outputPath: options.json } : null,
828
+ options.obsidian ? { format: "obsidian", outputPath: options.obsidian } : null,
829
+ options.canvas ? { format: "canvas", outputPath: options.canvas } : null
830
+ ].filter((target) => Boolean(target));
831
+ if (targets.length === 0) {
832
+ throw new Error("Pass at least one of --html, --html-standalone, --svg, --graphml, --cypher, --json, --obsidian, or --canvas.");
833
+ }
834
+ const results = [];
835
+ for (const target of targets) {
836
+ if (target.format === "html") {
837
+ const outputPath = await exportGraphHtml(process2.cwd(), target.outputPath, { full: options.full ?? false });
838
+ results.push({ format: target.format, outputPath });
839
+ } else if (target.format === "obsidian") {
840
+ const result = await exportObsidianVault(process2.cwd(), target.outputPath);
841
+ results.push({ format: result.format, outputPath: result.outputPath, fileCount: result.fileCount });
842
+ } else if (target.format === "canvas") {
843
+ const result = await exportObsidianCanvas(process2.cwd(), target.outputPath);
844
+ results.push({ format: result.format, outputPath: result.outputPath });
845
+ } else {
846
+ const result = await exportGraphFormat(process2.cwd(), target.format, target.outputPath);
847
+ results.push({ format: result.format, outputPath: result.outputPath });
848
+ }
849
+ }
850
+ if (isJson()) {
851
+ emitJson(results.length === 1 ? results[0] : { exports: results });
852
+ } else {
853
+ for (const result of results) {
854
+ const suffix = result.fileCount ? ` (${result.fileCount} files)` : "";
855
+ log(`Exported graph ${result.format} to ${result.outputPath}${suffix}`);
856
+ }
835
857
  }
836
858
  }
837
- });
859
+ );
838
860
  graph.command("query").description("Traverse the compiled graph deterministically from local search seeds.").argument("<question>", "Question or graph search seed").option("--dfs", "Prefer a depth-first traversal instead of breadth-first", false).option("--budget <n>", "Maximum number of graph nodes to summarize").action(async (question, options) => {
839
861
  const budget = options.budget ? parsePositiveInt(options.budget, 0) || void 0 : void 0;
840
862
  const result = await queryGraphVault(process2.cwd(), question, {
@@ -1097,7 +1119,7 @@ program.command("mcp").description("Run SwarmVault as a local MCP server over st
1097
1119
  process2.exit(0);
1098
1120
  });
1099
1121
  });
1100
- program.command("install").description("Install SwarmVault instructions for an agent in the current project.").requiredOption("--agent <agent>", "codex, claude, cursor, goose, pi, gemini, opencode, aider, or copilot").option("--hook", "Also install hook/plugin guidance when the target agent supports it", false).action(
1122
+ program.command("install").description("Install SwarmVault instructions for an agent in the current project.").requiredOption("--agent <agent>", "codex, claude, cursor, goose, pi, gemini, opencode, aider, copilot, trae, claw, or droid").option("--hook", "Also install hook/plugin guidance when the target agent supports it", false).action(
1101
1123
  async (options) => {
1102
1124
  const hookCapableAgents = /* @__PURE__ */ new Set(["claude", "opencode", "gemini", "copilot"]);
1103
1125
  if (options.hook && !hookCapableAgents.has(options.agent)) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@swarmvaultai/cli",
3
- "version": "0.7.21",
3
+ "version": "0.7.22",
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.7.21",
41
+ "@swarmvaultai/engine": "0.7.22",
42
42
  "commander": "^14.0.1"
43
43
  },
44
44
  "devDependencies": {