@swarmvaultai/cli 0.10.0 → 0.12.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 (2) hide show
  1. package/dist/index.js +62 -5
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -9,6 +9,7 @@ import {
9
9
  acceptApproval,
10
10
  addInput,
11
11
  addManagedSource,
12
+ addWatchedRoot,
12
13
  archiveCandidate,
13
14
  autoCommitWikiChanges,
14
15
  benchmarkVault,
@@ -42,6 +43,7 @@ import {
42
43
  listManagedSourceRecords,
43
44
  listManifests,
44
45
  listSchedules,
46
+ listWatchedRoots,
45
47
  loadVaultConfig,
46
48
  pathGraphVault,
47
49
  previewCandidatePromotions,
@@ -52,10 +54,12 @@ import {
52
54
  readApproval,
53
55
  rejectApproval,
54
56
  reloadManagedSources,
57
+ removeWatchedRoot,
55
58
  resumeSourceSession,
56
59
  reviewManagedSource,
57
60
  reviewSourceScope,
58
61
  runAutoPromotion,
62
+ runMigration,
59
63
  runSchedule,
60
64
  runWatchCycle,
61
65
  serveSchedules,
@@ -280,9 +284,9 @@ program.name("swarmvault").description("SwarmVault is a local-first knowledge co
280
284
  function readCliVersion() {
281
285
  try {
282
286
  const packageJson = JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf8"));
283
- return typeof packageJson.version === "string" && packageJson.version.trim() ? packageJson.version : "0.10.0";
287
+ return typeof packageJson.version === "string" && packageJson.version.trim() ? packageJson.version : "0.12.0";
284
288
  } catch {
285
- return "0.10.0";
289
+ return "0.12.0";
286
290
  }
287
291
  }
288
292
  function parsePositiveInt(value, fallback) {
@@ -290,6 +294,9 @@ function parsePositiveInt(value, fallback) {
290
294
  const parsed = Number.parseInt(value, 10);
291
295
  return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;
292
296
  }
297
+ function collectRepeated(value, previous) {
298
+ return [...previous, value];
299
+ }
293
300
  function sourceScopeFromManifests(input, manifests) {
294
301
  if (!manifests.length) {
295
302
  return null;
@@ -1134,14 +1141,16 @@ candidate.command("preview-scores").description("Show promotion scores for stage
1134
1141
  log(`${verdict} ${decision.pageId} score=${decision.score.toFixed(2)} ${decision.reasons.join("; ")}`);
1135
1142
  }
1136
1143
  });
1137
- 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").action(async (options) => {
1144
+ 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, []).action(async (options) => {
1138
1145
  const debounceMs = parsePositiveInt(options.debounce, 900);
1146
+ const overrideRoots = options.root && options.root.length > 0 ? options.root : void 0;
1139
1147
  if (options.once) {
1140
1148
  const result = await runWatchCycle(process2.cwd(), {
1141
1149
  lint: options.lint ?? false,
1142
1150
  repo: options.repo ?? false,
1143
1151
  codeOnly: options.codeOnly ?? false,
1144
- debounceMs
1152
+ debounceMs,
1153
+ overrideRoots
1145
1154
  });
1146
1155
  if (isJson()) {
1147
1156
  emitJson(result);
@@ -1157,7 +1166,8 @@ var watch = program.command("watch").description("Watch the inbox directory and
1157
1166
  lint: options.lint ?? false,
1158
1167
  repo: options.repo ?? false,
1159
1168
  codeOnly: options.codeOnly ?? false,
1160
- debounceMs
1169
+ debounceMs,
1170
+ overrideRoots
1161
1171
  });
1162
1172
  if (isJson()) {
1163
1173
  emitJson({ status: "watching", inboxDir: paths.inboxDir, repo: options.repo ?? false });
@@ -1172,6 +1182,36 @@ var watch = program.command("watch").description("Watch the inbox directory and
1172
1182
  process2.exit(0);
1173
1183
  });
1174
1184
  });
1185
+ watch.command("list-roots").description("Print the effective watched repo roots resolved from config and auto-discovery.").action(async () => {
1186
+ const roots = await listWatchedRoots(process2.cwd());
1187
+ if (isJson()) {
1188
+ emitJson({ roots });
1189
+ return;
1190
+ }
1191
+ if (roots.length === 0) {
1192
+ log("No watched repo roots.");
1193
+ return;
1194
+ }
1195
+ for (const entry of roots) {
1196
+ log(entry);
1197
+ }
1198
+ });
1199
+ watch.command("add-root <path>").description("Persist a repo root into swarmvault.config.json watch.repoRoots.").action(async (pathValue) => {
1200
+ const resolved = await addWatchedRoot(process2.cwd(), pathValue);
1201
+ if (isJson()) {
1202
+ emitJson({ added: resolved });
1203
+ return;
1204
+ }
1205
+ log(`Watching ${resolved}`);
1206
+ });
1207
+ watch.command("remove-root <path>").description("Remove a repo root from swarmvault.config.json watch.repoRoots.").action(async (pathValue) => {
1208
+ const removed = await removeWatchedRoot(process2.cwd(), pathValue);
1209
+ if (isJson()) {
1210
+ emitJson({ removed });
1211
+ return;
1212
+ }
1213
+ log(removed ? `Removed ${pathValue}` : `${pathValue} was not in watch.repoRoots.`);
1214
+ });
1175
1215
  async function showWatchStatus() {
1176
1216
  const result = await getWatchStatus(process2.cwd());
1177
1217
  if (isJson()) {
@@ -1260,6 +1300,23 @@ schedule.command("serve").description("Run the local schedule loop.").option("--
1260
1300
  process2.exit(0);
1261
1301
  });
1262
1302
  });
1303
+ program.command("migrate").description("Detect vault version and plan or apply schema/config/graph migrations.").option("--target <version>", "Limit migrations to those at or below this target version").option("--apply", "Write migration changes to disk (default is dry-run)", false).option("--dry-run", "Report planned changes without writing (overrides --apply)", false).action(async (options) => {
1304
+ const dryRun = options.dryRun === true ? true : options.apply !== true;
1305
+ const result = await runMigration(process2.cwd(), { targetVersion: options.target, dryRun });
1306
+ if (isJson()) {
1307
+ emitJson(result);
1308
+ return;
1309
+ }
1310
+ log(
1311
+ `Vault version: ${result.fromVersion ?? "unknown"} \u2192 ${result.toVersion} (${result.planned} step${result.planned === 1 ? "" : "s"} planned, ${result.applied.length} applied, ${result.skipped.length} skipped${dryRun ? "; dry-run" : ""})`
1312
+ );
1313
+ for (const entry of result.applied) {
1314
+ log(`applied ${entry.id}: ${entry.changed.length} change${entry.changed.length === 1 ? "" : "s"}`);
1315
+ }
1316
+ for (const entry of result.skipped) {
1317
+ log(`skip ${entry.id}: ${entry.reason}`);
1318
+ }
1319
+ });
1263
1320
  program.command("mcp").description("Run SwarmVault as a local MCP server over stdio.").action(async () => {
1264
1321
  if (isJson()) {
1265
1322
  process2.stderr.write(`${JSON.stringify({ status: "running", transport: "stdio" })}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@swarmvaultai/cli",
3
- "version": "0.10.0",
3
+ "version": "0.12.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": "0.10.0",
47
+ "@swarmvaultai/engine": "0.12.0",
48
48
  "commander": "^14.0.1"
49
49
  },
50
50
  "devDependencies": {