@swarmvaultai/cli 1.2.0 → 1.3.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 CHANGED
@@ -40,6 +40,7 @@ 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
43
44
  swarmvault benchmark
44
45
  swarmvault query "What keeps recurring?" --commit
45
46
  swarmvault query "Turn this into slides" --format slides
@@ -86,7 +87,7 @@ Quick-start a scratch vault from a local directory in one command.
86
87
  - initializes the current directory as a SwarmVault workspace
87
88
  - ingests the supplied directory as local sources
88
89
  - compiles the vault immediately
89
- - writes `wiki/graph/share-card.md` and prints the path
90
+ - writes `wiki/graph/share-card.md` and `wiki/graph/share-card.svg`, then prints both paths
90
91
  - starts `graph serve` unless you pass `--no-serve`
91
92
  - respects `--port` when you want a specific viewer port
92
93
 
@@ -99,7 +100,7 @@ Create a temporary sample vault with bundled sources, compile it immediately, an
99
100
  - writes the demo vault under the system temp directory
100
101
  - requires no API keys or extra setup
101
102
  - 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
103
+ - writes `wiki/graph/share-card.md` and `wiki/graph/share-card.svg` inside the demo vault
103
104
  - respects `--port` when you want a specific viewer port
104
105
 
105
106
  ### `swarmvault diff`
@@ -210,7 +211,7 @@ Compile the current manifests into:
210
211
  - generated markdown in `wiki/`
211
212
  - structured graph data in `state/graph.json`
212
213
  - local search data in `state/search.sqlite`
213
- - a share card at `wiki/graph/share-card.md`
214
+ - share cards at `wiki/graph/share-card.md` and `wiki/graph/share-card.svg`
214
215
 
215
216
  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
217
 
@@ -370,13 +371,14 @@ Inspect graph metadata, community membership, neighbors, provenance, and group-p
370
371
 
371
372
  List the most connected bridge-heavy nodes in the current graph.
372
373
 
373
- ### `swarmvault graph share [--post]`
374
+ ### `swarmvault graph share [--post] [--svg [path]]`
374
375
 
375
376
  Print a shareable summary of the compiled graph.
376
377
 
377
378
  - default output is the same markdown shape written to `wiki/graph/share-card.md`
378
379
  - `--post` prints only the concise social-post text
379
- - `--json` emits the structured share artifact for automation
380
+ - `--svg [path]` writes the 1200x630 visual share card, defaulting to `wiki/graph/share-card.svg`
381
+ - `--json` emits the structured share artifact for automation; with `--svg`, it also includes `svgPath`
380
382
  - useful immediately after `swarmvault scan`, `swarmvault demo`, or a normal compile
381
383
 
382
384
  ### `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";
@@ -61,6 +61,7 @@ import {
61
61
  reloadManagedSources,
62
62
  removeWatchedRoot,
63
63
  renderGraphShareMarkdown,
64
+ renderGraphShareSvg,
64
65
  resumeSourceSession,
65
66
  reviewManagedSource,
66
67
  reviewSourceScope,
@@ -291,9 +292,9 @@ program.name("swarmvault").description("SwarmVault is a local-first knowledge co
291
292
  function readCliVersion() {
292
293
  try {
293
294
  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";
295
+ return typeof packageJson.version === "string" && packageJson.version.trim() ? packageJson.version : "1.3.0";
295
296
  } catch {
296
- return "1.2.0";
297
+ return "1.3.0";
297
298
  }
298
299
  }
299
300
  function parsePositiveInt(value, fallback) {
@@ -975,7 +976,10 @@ graph.command("export").description(
975
976
  }
976
977
  }
977
978
  );
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) => {
979
+ 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").action(async (options) => {
980
+ if (options.post && options.svg) {
981
+ throw new Error("Choose either --post or --svg, not both.");
982
+ }
979
983
  const { paths } = await loadVaultConfig(process2.cwd());
980
984
  const raw = await readFile2(paths.graphPath, "utf-8");
981
985
  const graph2 = JSON.parse(raw);
@@ -985,6 +989,17 @@ graph.command("share").description("Print a shareable summary of the compiled gr
985
989
  report,
986
990
  vaultName: path2.basename(paths.rootDir)
987
991
  });
992
+ if (options.svg) {
993
+ const svgPath = typeof options.svg === "string" ? path2.resolve(process2.cwd(), options.svg) : path2.join(paths.wikiDir, "graph", "share-card.svg");
994
+ await mkdir2(path2.dirname(svgPath), { recursive: true });
995
+ await writeFile2(svgPath, renderGraphShareSvg(artifact), "utf8");
996
+ if (isJson()) {
997
+ emitJson({ ...artifact, svgPath });
998
+ return;
999
+ }
1000
+ log(`Wrote SVG share card to ${svgPath}`);
1001
+ return;
1002
+ }
988
1003
  if (isJson()) {
989
1004
  emitJson(artifact);
990
1005
  return;
@@ -1449,7 +1464,7 @@ program.command("install").description("Install SwarmVault instructions for an a
1449
1464
  }
1450
1465
  );
1451
1466
  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");
1467
+ const { mkdtemp, writeFile: writeFile3, mkdir: mkdir3 } = await import("fs/promises");
1453
1468
  const { tmpdir } = await import("os");
1454
1469
  const path3 = await import("path");
1455
1470
  const demoDir = await mkdtemp(path3.join(tmpdir(), "swarmvault-demo-"));
@@ -1457,8 +1472,8 @@ program.command("demo").description("Try SwarmVault with a bundled sample vault
1457
1472
  log(`Creating demo vault in ${demoDir}`);
1458
1473
  }
1459
1474
  const rawDir = path3.join(demoDir, "raw", "sources");
1460
- await mkdir2(rawDir, { recursive: true });
1461
- await writeFile2(
1475
+ await mkdir3(rawDir, { recursive: true });
1476
+ await writeFile3(
1462
1477
  path3.join(rawDir, "llm-wiki-pattern.md"),
1463
1478
  [
1464
1479
  "# The LLM Wiki Pattern",
@@ -1487,7 +1502,7 @@ program.command("demo").description("Try SwarmVault with a bundled sample vault
1487
1502
  ""
1488
1503
  ].join("\n")
1489
1504
  );
1490
- await writeFile2(
1505
+ await writeFile3(
1491
1506
  path3.join(rawDir, "knowledge-graphs.md"),
1492
1507
  [
1493
1508
  "# Knowledge Graphs for AI",
@@ -1520,7 +1535,7 @@ program.command("demo").description("Try SwarmVault with a bundled sample vault
1520
1535
  ""
1521
1536
  ].join("\n")
1522
1537
  );
1523
- await writeFile2(
1538
+ await writeFile3(
1524
1539
  path3.join(rawDir, "local-first-tools.md"),
1525
1540
  [
1526
1541
  "# Local-First AI Tools",
@@ -1552,6 +1567,7 @@ program.command("demo").description("Try SwarmVault with a bundled sample vault
1552
1567
  await compileVault(demoDir, {});
1553
1568
  const { paths } = await loadVaultConfig(demoDir);
1554
1569
  const shareCardPath = path3.join(demoDir, "wiki", "graph", "share-card.md");
1570
+ const shareCardSvgPath = path3.join(demoDir, "wiki", "graph", "share-card.svg");
1555
1571
  let graphStats = "";
1556
1572
  try {
1557
1573
  const raw = await readFile2(paths.graphPath, "utf-8");
@@ -1570,12 +1586,20 @@ program.command("demo").description("Try SwarmVault with a bundled sample vault
1570
1586
  log("");
1571
1587
  log(`Vault location: ${demoDir}`);
1572
1588
  log(`Share card: ${shareCardPath}`);
1589
+ log(`Visual card: ${shareCardSvgPath}`);
1573
1590
  }
1574
1591
  if (options.serve !== false) {
1575
1592
  const port = options.port ? parsePositiveInt(options.port, 0) || void 0 : void 0;
1576
1593
  const server = await startGraphServer(demoDir, port, { full: false });
1577
1594
  if (isJson()) {
1578
- emitJson({ demoDir, graphStats: graphStats.trim(), shareCardPath, port: server.port, url: `http://localhost:${server.port}` });
1595
+ emitJson({
1596
+ demoDir,
1597
+ graphStats: graphStats.trim(),
1598
+ shareCardPath,
1599
+ shareCardSvgPath,
1600
+ port: server.port,
1601
+ url: `http://localhost:${server.port}`
1602
+ });
1579
1603
  } else {
1580
1604
  log(`Graph viewer running at http://localhost:${server.port}`);
1581
1605
  log("");
@@ -1593,7 +1617,7 @@ program.command("demo").description("Try SwarmVault with a bundled sample vault
1593
1617
  process2.exit(0);
1594
1618
  });
1595
1619
  } else if (isJson()) {
1596
- emitJson({ demoDir, graphStats: graphStats.trim(), shareCardPath });
1620
+ emitJson({ demoDir, graphStats: graphStats.trim(), shareCardPath, shareCardSvgPath });
1597
1621
  } else {
1598
1622
  log("");
1599
1623
  log("Try next:");
@@ -1727,16 +1751,18 @@ program.command("scan").description("Quick-start: initialize, ingest, compile, a
1727
1751
  }
1728
1752
  const compiled = await compileVault(rootDir, {});
1729
1753
  const shareCardPath = path2.join(rootDir, "wiki", "graph", "share-card.md");
1754
+ const shareCardSvgPath = path2.join(rootDir, "wiki", "graph", "share-card.svg");
1730
1755
  if (!isJson()) {
1731
1756
  log(`Compiled ${compiled.sourceCount} source(s), ${compiled.pageCount} page(s).`);
1732
1757
  log(`Share card: ${shareCardPath}`);
1758
+ log(`Visual card: ${shareCardSvgPath}`);
1733
1759
  log("Post text: swarmvault graph share --post");
1734
1760
  }
1735
1761
  if (options.serve !== false) {
1736
1762
  const port = options.port ? parsePositiveInt(options.port, 0) || void 0 : void 0;
1737
1763
  const server = await startGraphServer(rootDir, port, { full: false });
1738
1764
  if (isJson()) {
1739
- emitJson({ ...result, compiled, shareCardPath, port: server.port, url: `http://localhost:${server.port}` });
1765
+ emitJson({ ...result, compiled, shareCardPath, shareCardSvgPath, port: server.port, url: `http://localhost:${server.port}` });
1740
1766
  } else {
1741
1767
  log(`Graph viewer running at http://localhost:${server.port}`);
1742
1768
  }
@@ -1748,7 +1774,7 @@ program.command("scan").description("Quick-start: initialize, ingest, compile, a
1748
1774
  process2.exit(0);
1749
1775
  });
1750
1776
  } else if (isJson()) {
1751
- emitJson({ ...result, compiled, shareCardPath });
1777
+ emitJson({ ...result, compiled, shareCardPath, shareCardSvgPath });
1752
1778
  }
1753
1779
  });
1754
1780
  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.3.0",
4
4
  "description": "Global CLI for SwarmVault.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -37,18 +37,19 @@
37
37
  "engines": {
38
38
  "node": ">=24.0.0"
39
39
  },
40
+ "scripts": {
41
+ "build": "tsup src/index.ts --format esm --dts",
42
+ "test": "vitest run",
43
+ "typecheck": "tsc --noEmit",
44
+ "prepublishOnly": "node ../../scripts/check-release-sync.mjs && node ../../scripts/check-published-manifests.mjs"
45
+ },
40
46
  "dependencies": {
41
- "@swarmvaultai/engine": "1.2.0",
47
+ "@swarmvaultai/engine": "1.3.0",
42
48
  "commander": "^14.0.1"
43
49
  },
44
50
  "devDependencies": {
45
51
  "@types/node": "^24.6.0",
46
52
  "tsup": "^8.5.0",
47
53
  "vitest": "^3.2.4"
48
- },
49
- "scripts": {
50
- "build": "tsup src/index.ts --format esm --dts",
51
- "test": "vitest run",
52
- "typecheck": "tsc --noEmit"
53
54
  }
54
- }
55
+ }
package/LICENSE DELETED
@@ -1,21 +0,0 @@
1
- MIT License
2
-
3
- Copyright (c) 2026 SwarmVault
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.