@swarmvaultai/cli 1.2.0 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +9 -5
  2. package/dist/index.js +78 -13
  3. package/package.json +2 -2
package/README.md CHANGED
@@ -40,6 +40,8 @@ swarmvault add https://arxiv.org/abs/2401.12345
40
40
  swarmvault compile --max-tokens 120000
41
41
  swarmvault diff
42
42
  swarmvault graph share --post
43
+ swarmvault graph share --svg ./share-card.svg
44
+ swarmvault graph share --bundle ./share-kit
43
45
  swarmvault benchmark
44
46
  swarmvault query "What keeps recurring?" --commit
45
47
  swarmvault query "Turn this into slides" --format slides
@@ -86,7 +88,7 @@ Quick-start a scratch vault from a local directory in one command.
86
88
  - initializes the current directory as a SwarmVault workspace
87
89
  - ingests the supplied directory as local sources
88
90
  - compiles the vault immediately
89
- - writes `wiki/graph/share-card.md` and prints the path
91
+ - writes `wiki/graph/share-card.md`, `wiki/graph/share-card.svg`, and `wiki/graph/share-kit/`, then prints the paths
90
92
  - starts `graph serve` unless you pass `--no-serve`
91
93
  - respects `--port` when you want a specific viewer port
92
94
 
@@ -99,7 +101,7 @@ Create a temporary sample vault with bundled sources, compile it immediately, an
99
101
  - writes the demo vault under the system temp directory
100
102
  - requires no API keys or extra setup
101
103
  - is the fastest way to inspect the full init + ingest + compile + graph workflow on a clean machine
102
- - writes `wiki/graph/share-card.md` inside the demo vault
104
+ - writes `wiki/graph/share-card.md`, `wiki/graph/share-card.svg`, and `wiki/graph/share-kit/` inside the demo vault
103
105
  - respects `--port` when you want a specific viewer port
104
106
 
105
107
  ### `swarmvault diff`
@@ -210,7 +212,7 @@ Compile the current manifests into:
210
212
  - generated markdown in `wiki/`
211
213
  - structured graph data in `state/graph.json`
212
214
  - local search data in `state/search.sqlite`
213
- - a share card at `wiki/graph/share-card.md`
215
+ - share cards at `wiki/graph/share-card.md` and `wiki/graph/share-card.svg`, plus a portable share kit at `wiki/graph/share-kit/`
214
216
 
215
217
  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.
216
218
 
@@ -370,13 +372,15 @@ Inspect graph metadata, community membership, neighbors, provenance, and group-p
370
372
 
371
373
  List the most connected bridge-heavy nodes in the current graph.
372
374
 
373
- ### `swarmvault graph share [--post]`
375
+ ### `swarmvault graph share [--post] [--svg [path]] [--bundle [dir]]`
374
376
 
375
377
  Print a shareable summary of the compiled graph.
376
378
 
377
379
  - default output is the same markdown shape written to `wiki/graph/share-card.md`
378
380
  - `--post` prints only the concise social-post text
379
- - `--json` emits the structured share artifact for automation
381
+ - `--svg [path]` writes the 1200x630 visual share card, defaulting to `wiki/graph/share-card.svg`
382
+ - `--bundle [dir]` writes `share-card.md`, `share-post.txt`, `share-card.svg`, `share-preview.html`, and `share-artifact.json`, defaulting to `wiki/graph/share-kit`
383
+ - `--json` emits the structured share artifact for automation; with `--svg`, it also includes `svgPath`; with `--bundle`, it includes `bundlePath` and named output paths
380
384
  - useful immediately after `swarmvault scan`, `swarmvault demo`, or a normal compile
381
385
 
382
386
  ### `swarmvault graph blast <target> [--depth <n>]`
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  // src/index.ts
4
4
  import { readFileSync } from "fs";
5
- import { readFile as readFile2 } from "fs/promises";
5
+ import { mkdir as mkdir2, readFile as readFile2, 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";
@@ -60,7 +60,9 @@ import {
60
60
  rejectApproval,
61
61
  reloadManagedSources,
62
62
  removeWatchedRoot,
63
+ renderGraphShareBundleFiles,
63
64
  renderGraphShareMarkdown,
65
+ renderGraphShareSvg,
64
66
  resumeSourceSession,
65
67
  reviewManagedSource,
66
68
  reviewSourceScope,
@@ -291,9 +293,9 @@ program.name("swarmvault").description("SwarmVault is a local-first knowledge co
291
293
  function readCliVersion() {
292
294
  try {
293
295
  const packageJson = JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf8"));
294
- return typeof packageJson.version === "string" && packageJson.version.trim() ? packageJson.version : "1.2.0";
296
+ return typeof packageJson.version === "string" && packageJson.version.trim() ? packageJson.version : "1.4.0";
295
297
  } catch {
296
- return "1.2.0";
298
+ return "1.4.0";
297
299
  }
298
300
  }
299
301
  function parsePositiveInt(value, fallback) {
@@ -347,6 +349,20 @@ function log(message) {
347
349
  `);
348
350
  }
349
351
  }
352
+ async function writeShareBundle(bundlePath, files) {
353
+ await mkdir2(bundlePath, { recursive: true });
354
+ const bundleFiles = {
355
+ markdownPath: path2.join(bundlePath, "share-card.md"),
356
+ postPath: path2.join(bundlePath, "share-post.txt"),
357
+ svgPath: path2.join(bundlePath, "share-card.svg"),
358
+ previewHtmlPath: path2.join(bundlePath, "share-preview.html"),
359
+ artifactJsonPath: path2.join(bundlePath, "share-artifact.json")
360
+ };
361
+ for (const file of files) {
362
+ await writeFile2(path2.join(bundlePath, file.relativePath), file.content, "utf8");
363
+ }
364
+ return bundleFiles;
365
+ }
350
366
  function emitNotice(message) {
351
367
  process2.stderr.write(`[swarmvault] ${message}
352
368
  `);
@@ -975,7 +991,11 @@ graph.command("export").description(
975
991
  }
976
992
  }
977
993
  );
978
- graph.command("share").description("Print a shareable summary of the compiled graph.").option("--post", "Print only the short social post text", false).action(async (options) => {
994
+ graph.command("share").description("Print a shareable summary of the compiled graph.").option("--post", "Print only the short social post text", false).option("--svg [path]", "Write the visual SVG share card, defaulting to wiki/graph/share-card.svg").option("--bundle [dir]", "Write the portable share kit bundle, defaulting to wiki/graph/share-kit").action(async (options) => {
995
+ const outputModeCount = [options.post, options.svg, options.bundle].filter(Boolean).length;
996
+ if (outputModeCount > 1) {
997
+ throw new Error("Choose one graph share output mode: --post, --svg, or --bundle.");
998
+ }
979
999
  const { paths } = await loadVaultConfig(process2.cwd());
980
1000
  const raw = await readFile2(paths.graphPath, "utf-8");
981
1001
  const graph2 = JSON.parse(raw);
@@ -985,6 +1005,27 @@ graph.command("share").description("Print a shareable summary of the compiled gr
985
1005
  report,
986
1006
  vaultName: path2.basename(paths.rootDir)
987
1007
  });
1008
+ if (options.svg) {
1009
+ const svgPath = typeof options.svg === "string" ? path2.resolve(process2.cwd(), options.svg) : path2.join(paths.wikiDir, "graph", "share-card.svg");
1010
+ await mkdir2(path2.dirname(svgPath), { recursive: true });
1011
+ await writeFile2(svgPath, renderGraphShareSvg(artifact), "utf8");
1012
+ if (isJson()) {
1013
+ emitJson({ ...artifact, svgPath });
1014
+ return;
1015
+ }
1016
+ log(`Wrote SVG share card to ${svgPath}`);
1017
+ return;
1018
+ }
1019
+ if (options.bundle) {
1020
+ const bundlePath = typeof options.bundle === "string" ? path2.resolve(process2.cwd(), options.bundle) : path2.join(paths.wikiDir, "graph", "share-kit");
1021
+ const bundleFiles = await writeShareBundle(bundlePath, renderGraphShareBundleFiles(artifact));
1022
+ if (isJson()) {
1023
+ emitJson({ ...artifact, bundlePath, bundleFiles });
1024
+ return;
1025
+ }
1026
+ log(`Wrote share kit to ${bundlePath}`);
1027
+ return;
1028
+ }
988
1029
  if (isJson()) {
989
1030
  emitJson(artifact);
990
1031
  return;
@@ -1449,7 +1490,7 @@ program.command("install").description("Install SwarmVault instructions for an a
1449
1490
  }
1450
1491
  );
1451
1492
  program.command("demo").description("Try SwarmVault with a bundled sample vault \u2014 zero config, zero API keys.").option("--port <port>", "Port for the graph viewer").option("--no-serve", "Skip launching the graph viewer after compile").action(async (options) => {
1452
- const { mkdtemp, writeFile: writeFile2, mkdir: mkdir2 } = await import("fs/promises");
1493
+ const { mkdtemp, writeFile: writeFile3, mkdir: mkdir3 } = await import("fs/promises");
1453
1494
  const { tmpdir } = await import("os");
1454
1495
  const path3 = await import("path");
1455
1496
  const demoDir = await mkdtemp(path3.join(tmpdir(), "swarmvault-demo-"));
@@ -1457,8 +1498,8 @@ program.command("demo").description("Try SwarmVault with a bundled sample vault
1457
1498
  log(`Creating demo vault in ${demoDir}`);
1458
1499
  }
1459
1500
  const rawDir = path3.join(demoDir, "raw", "sources");
1460
- await mkdir2(rawDir, { recursive: true });
1461
- await writeFile2(
1501
+ await mkdir3(rawDir, { recursive: true });
1502
+ await writeFile3(
1462
1503
  path3.join(rawDir, "llm-wiki-pattern.md"),
1463
1504
  [
1464
1505
  "# The LLM Wiki Pattern",
@@ -1487,7 +1528,7 @@ program.command("demo").description("Try SwarmVault with a bundled sample vault
1487
1528
  ""
1488
1529
  ].join("\n")
1489
1530
  );
1490
- await writeFile2(
1531
+ await writeFile3(
1491
1532
  path3.join(rawDir, "knowledge-graphs.md"),
1492
1533
  [
1493
1534
  "# Knowledge Graphs for AI",
@@ -1520,7 +1561,7 @@ program.command("demo").description("Try SwarmVault with a bundled sample vault
1520
1561
  ""
1521
1562
  ].join("\n")
1522
1563
  );
1523
- await writeFile2(
1564
+ await writeFile3(
1524
1565
  path3.join(rawDir, "local-first-tools.md"),
1525
1566
  [
1526
1567
  "# Local-First AI Tools",
@@ -1552,6 +1593,8 @@ program.command("demo").description("Try SwarmVault with a bundled sample vault
1552
1593
  await compileVault(demoDir, {});
1553
1594
  const { paths } = await loadVaultConfig(demoDir);
1554
1595
  const shareCardPath = path3.join(demoDir, "wiki", "graph", "share-card.md");
1596
+ const shareCardSvgPath = path3.join(demoDir, "wiki", "graph", "share-card.svg");
1597
+ const shareKitPath = path3.join(demoDir, "wiki", "graph", "share-kit");
1555
1598
  let graphStats = "";
1556
1599
  try {
1557
1600
  const raw = await readFile2(paths.graphPath, "utf-8");
@@ -1570,12 +1613,22 @@ program.command("demo").description("Try SwarmVault with a bundled sample vault
1570
1613
  log("");
1571
1614
  log(`Vault location: ${demoDir}`);
1572
1615
  log(`Share card: ${shareCardPath}`);
1616
+ log(`Visual card: ${shareCardSvgPath}`);
1617
+ log(`Share kit: ${shareKitPath}`);
1573
1618
  }
1574
1619
  if (options.serve !== false) {
1575
1620
  const port = options.port ? parsePositiveInt(options.port, 0) || void 0 : void 0;
1576
1621
  const server = await startGraphServer(demoDir, port, { full: false });
1577
1622
  if (isJson()) {
1578
- emitJson({ demoDir, graphStats: graphStats.trim(), shareCardPath, port: server.port, url: `http://localhost:${server.port}` });
1623
+ emitJson({
1624
+ demoDir,
1625
+ graphStats: graphStats.trim(),
1626
+ shareCardPath,
1627
+ shareCardSvgPath,
1628
+ shareKitPath,
1629
+ port: server.port,
1630
+ url: `http://localhost:${server.port}`
1631
+ });
1579
1632
  } else {
1580
1633
  log(`Graph viewer running at http://localhost:${server.port}`);
1581
1634
  log("");
@@ -1593,7 +1646,7 @@ program.command("demo").description("Try SwarmVault with a bundled sample vault
1593
1646
  process2.exit(0);
1594
1647
  });
1595
1648
  } else if (isJson()) {
1596
- emitJson({ demoDir, graphStats: graphStats.trim(), shareCardPath });
1649
+ emitJson({ demoDir, graphStats: graphStats.trim(), shareCardPath, shareCardSvgPath, shareKitPath });
1597
1650
  } else {
1598
1651
  log("");
1599
1652
  log("Try next:");
@@ -1727,16 +1780,28 @@ program.command("scan").description("Quick-start: initialize, ingest, compile, a
1727
1780
  }
1728
1781
  const compiled = await compileVault(rootDir, {});
1729
1782
  const shareCardPath = path2.join(rootDir, "wiki", "graph", "share-card.md");
1783
+ const shareCardSvgPath = path2.join(rootDir, "wiki", "graph", "share-card.svg");
1784
+ const shareKitPath = path2.join(rootDir, "wiki", "graph", "share-kit");
1730
1785
  if (!isJson()) {
1731
1786
  log(`Compiled ${compiled.sourceCount} source(s), ${compiled.pageCount} page(s).`);
1732
1787
  log(`Share card: ${shareCardPath}`);
1788
+ log(`Visual card: ${shareCardSvgPath}`);
1789
+ log(`Share kit: ${shareKitPath}`);
1733
1790
  log("Post text: swarmvault graph share --post");
1734
1791
  }
1735
1792
  if (options.serve !== false) {
1736
1793
  const port = options.port ? parsePositiveInt(options.port, 0) || void 0 : void 0;
1737
1794
  const server = await startGraphServer(rootDir, port, { full: false });
1738
1795
  if (isJson()) {
1739
- emitJson({ ...result, compiled, shareCardPath, port: server.port, url: `http://localhost:${server.port}` });
1796
+ emitJson({
1797
+ ...result,
1798
+ compiled,
1799
+ shareCardPath,
1800
+ shareCardSvgPath,
1801
+ shareKitPath,
1802
+ port: server.port,
1803
+ url: `http://localhost:${server.port}`
1804
+ });
1740
1805
  } else {
1741
1806
  log(`Graph viewer running at http://localhost:${server.port}`);
1742
1807
  }
@@ -1748,7 +1813,7 @@ program.command("scan").description("Quick-start: initialize, ingest, compile, a
1748
1813
  process2.exit(0);
1749
1814
  });
1750
1815
  } else if (isJson()) {
1751
- emitJson({ ...result, compiled, shareCardPath });
1816
+ emitJson({ ...result, compiled, shareCardPath, shareCardSvgPath, shareKitPath });
1752
1817
  }
1753
1818
  });
1754
1819
  function enableStructuredJsonOnSubcommands(command) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@swarmvaultai/cli",
3
- "version": "1.2.0",
3
+ "version": "1.4.0",
4
4
  "description": "Global CLI for SwarmVault.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -38,7 +38,7 @@
38
38
  "node": ">=24.0.0"
39
39
  },
40
40
  "dependencies": {
41
- "@swarmvaultai/engine": "1.2.0",
41
+ "@swarmvaultai/engine": "1.4.0",
42
42
  "commander": "^14.0.1"
43
43
  },
44
44
  "devDependencies": {