@swarmvaultai/engine 0.8.0 → 0.9.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/dist/index.d.ts CHANGED
@@ -43,6 +43,10 @@ declare const agentTypeSchema: z.ZodEnum<{
43
43
  trae: "trae";
44
44
  claw: "claw";
45
45
  droid: "droid";
46
+ kiro: "kiro";
47
+ hermes: "hermes";
48
+ antigravity: "antigravity";
49
+ vscode: "vscode";
46
50
  }>;
47
51
  type AgentType = z.infer<typeof agentTypeSchema>;
48
52
  type PageKind = "index" | "source" | "module" | "concept" | "entity" | "output" | "insight" | "graph_report" | "community_summary";
@@ -113,6 +117,13 @@ interface AudioTranscriptionRequest {
113
117
  bytes: Buffer;
114
118
  fileName?: string;
115
119
  language?: string;
120
+ /**
121
+ * Optional one-sentence domain hint derived from the vault's top god nodes.
122
+ * Providers that accept a prompt (e.g. Whisper) can pass it through to bias
123
+ * transcription toward in-corpus terminology. Providers without prompt
124
+ * support ignore it safely.
125
+ */
126
+ corpusHint?: string;
116
127
  }
117
128
  interface AudioTranscriptionResponse {
118
129
  text: string;
@@ -534,6 +545,8 @@ interface GraphNode {
534
545
  id: string;
535
546
  type: "source" | "concept" | "entity" | "module" | "symbol" | "rationale";
536
547
  label: string;
548
+ /** Lowercased NFKD-normalized label (diacritic-insensitive) for lexical matching. */
549
+ normLabel?: string;
537
550
  pageId?: string;
538
551
  freshness?: Freshness;
539
552
  confidence?: number;
@@ -803,6 +816,7 @@ interface CompileOptions {
803
816
  interface InitOptions {
804
817
  obsidian?: boolean;
805
818
  profile?: string;
819
+ lite?: boolean;
806
820
  }
807
821
  interface CompileResult {
808
822
  graphPath: string;
package/dist/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import {
2
+ PRIMARY_SCHEMA_FILENAME,
2
3
  appendJsonLine,
3
4
  assertProviderCapability,
4
5
  createProvider,
@@ -22,7 +23,7 @@ import {
22
23
  uniqueBy,
23
24
  writeFileIfChanged,
24
25
  writeJsonFile
25
- } from "./chunk-NECZ4MUE.js";
26
+ } from "./chunk-RSQRF4FV.js";
26
27
  import {
27
28
  estimatePageTokens,
28
29
  estimateTokens,
@@ -32,6 +33,7 @@ import {
32
33
  // src/agents.ts
33
34
  import crypto from "crypto";
34
35
  import fs from "fs/promises";
36
+ import os from "os";
35
37
  import path from "path";
36
38
  import { fileURLToPath } from "url";
37
39
  import YAML from "yaml";
@@ -83,23 +85,128 @@ var agentFileKinds = {
83
85
  copilot: ".github/copilot-instructions.md",
84
86
  trae: ".trae/rules/swarmvault.md",
85
87
  claw: ".claw/skills/swarmvault/SKILL.md",
86
- droid: ".factory/rules/swarmvault.md"
88
+ droid: ".factory/rules/swarmvault.md",
89
+ kiro: ".kiro/skills/swarmvault/SKILL.md",
90
+ kiroSteering: ".kiro/steering/swarmvault.md",
91
+ antigravityRules: ".agent/rules/swarmvault.md",
92
+ antigravityWorkflow: ".agent/workflows/swarmvault.md",
93
+ vscode: ".github/chatmodes/swarmvault.chatmode.md"
87
94
  };
95
+ var hermesUserSkillRelative = path.join(".hermes", "skills", "swarmvault", "SKILL.md");
96
+ function hermesUserSkillPath() {
97
+ return path.join(os.homedir(), hermesUserSkillRelative);
98
+ }
99
+ var SWARMVAULT_RULE_BULLETS = [
100
+ "- Read `swarmvault.schema.md` before compile or query style work. It is the canonical schema path.",
101
+ "- Treat `raw/` as immutable source input.",
102
+ "- Treat `wiki/` as generated markdown owned by the agent and compiler workflow.",
103
+ "- Read `wiki/graph/report.md` before broad file searching when it exists; otherwise start with `wiki/index.md`.",
104
+ "- For graph questions, prefer `swarmvault graph query`, `swarmvault graph path`, and `swarmvault graph explain` before broad grep/glob searching.",
105
+ "- Preserve frontmatter fields including `page_id`, `source_ids`, `node_ids`, `freshness`, and `source_hashes`.",
106
+ "- Save high-value answers back into `wiki/outputs/` instead of leaving them only in chat.",
107
+ "- Prefer `swarmvault ingest`, `swarmvault compile`, `swarmvault query`, and `swarmvault lint` for SwarmVault maintenance tasks."
108
+ ];
88
109
  function buildManagedBlock(target) {
89
110
  const heading = target === "aider" ? "# SwarmVault Conventions" : target === "copilot" ? "# SwarmVault Repository Instructions" : "# SwarmVault Rules";
111
+ return [managedStart, heading, "", ...SWARMVAULT_RULE_BULLETS, managedEnd, ""].join("\n");
112
+ }
113
+ function buildSkillFrontmatter() {
114
+ const frontmatter = YAML.stringify({
115
+ name: "swarmvault",
116
+ description: "SwarmVault graph-first workflow. Use to read the compiled wiki and query the knowledge graph before broad file search."
117
+ }).trimEnd();
118
+ return ["---", frontmatter, "---"].join("\n");
119
+ }
120
+ function buildSkillBody() {
90
121
  return [
91
- managedStart,
92
- heading,
122
+ "# SwarmVault",
123
+ "",
124
+ "SwarmVault compiles curated sources in `raw/` into a queryable wiki in `wiki/` and a knowledge graph in `state/graph.json`.",
125
+ "",
126
+ "## Rules",
127
+ "",
128
+ ...SWARMVAULT_RULE_BULLETS,
93
129
  "",
94
- "- Read `swarmvault.schema.md` before compile or query style work. It is the canonical schema path.",
95
- "- Treat `raw/` as immutable source input.",
96
- "- Treat `wiki/` as generated markdown owned by the agent and compiler workflow.",
97
- "- Read `wiki/graph/report.md` before broad file searching when it exists; otherwise start with `wiki/index.md`.",
98
- "- For graph questions, prefer `swarmvault graph query`, `swarmvault graph path`, and `swarmvault graph explain` before broad grep/glob searching.",
99
- "- Preserve frontmatter fields including `page_id`, `source_ids`, `node_ids`, `freshness`, and `source_hashes`.",
100
- "- Save high-value answers back into `wiki/outputs/` instead of leaving them only in chat.",
101
- "- Prefer `swarmvault ingest`, `swarmvault compile`, `swarmvault query`, and `swarmvault lint` for SwarmVault maintenance tasks.",
102
- managedEnd,
130
+ "## Entry points",
131
+ "",
132
+ "- `swarmvault ingest <path>` \u2014 register a new source",
133
+ "- `swarmvault compile` \u2014 refresh wiki pages and graph",
134
+ '- `swarmvault query "<question>"` \u2014 save-first multi-step query',
135
+ "- `swarmvault graph query|path|explain` \u2014 deterministic graph traversal",
136
+ "- `swarmvault lint` \u2014 wiki health and contradiction checks",
137
+ ""
138
+ ].join("\n");
139
+ }
140
+ function buildStandaloneSkillFile() {
141
+ return `${buildSkillFrontmatter()}
142
+
143
+ ${buildSkillBody()}`;
144
+ }
145
+ function buildKiroSteeringFile() {
146
+ const frontmatter = YAML.stringify({
147
+ inclusion: "always",
148
+ description: "Always-on SwarmVault rules."
149
+ }).trimEnd();
150
+ return ["---", frontmatter, "---", "", "# SwarmVault Rules", "", ...SWARMVAULT_RULE_BULLETS, ""].join("\n");
151
+ }
152
+ function buildAntigravityRulesFile() {
153
+ const frontmatter = YAML.stringify({
154
+ alwaysApply: true,
155
+ description: "SwarmVault graph-first repository rules."
156
+ }).trimEnd();
157
+ return [
158
+ "---",
159
+ frontmatter,
160
+ "---",
161
+ "",
162
+ "# SwarmVault Rules",
163
+ "",
164
+ ...SWARMVAULT_RULE_BULLETS,
165
+ "",
166
+ "> MCP navigation hint: SwarmVault exposes a local MCP server via `swarmvault mcp`. Wire it into your Antigravity MCP config to query the graph without shelling out."
167
+ ].join("\n");
168
+ }
169
+ function buildAntigravityWorkflowFile() {
170
+ const frontmatter = YAML.stringify({
171
+ command: "swarmvault",
172
+ description: "Compile, query, and lint the SwarmVault vault."
173
+ }).trimEnd();
174
+ return [
175
+ "---",
176
+ frontmatter,
177
+ "---",
178
+ "",
179
+ "# /swarmvault",
180
+ "",
181
+ "Run SwarmVault against the current directory.",
182
+ "",
183
+ "## Steps",
184
+ "",
185
+ "1. If no vault exists, run `swarmvault init`.",
186
+ "2. For new sources, run `swarmvault ingest <path>`.",
187
+ "3. Run `swarmvault compile` to refresh the wiki and graph.",
188
+ "4. For follow-up questions, prefer `swarmvault query`, `swarmvault graph query`, `swarmvault graph path`, `swarmvault graph explain`.",
189
+ "5. Save high-value answers to `wiki/outputs/`.",
190
+ ""
191
+ ].join("\n");
192
+ }
193
+ function buildVscodeChatmodeFile() {
194
+ const frontmatter = YAML.stringify({
195
+ description: "SwarmVault graph-first workflow for VS Code Copilot Chat.",
196
+ tools: ["codebase", "terminal"]
197
+ }).trimEnd();
198
+ return [
199
+ "---",
200
+ frontmatter,
201
+ "---",
202
+ "",
203
+ "# SwarmVault mode",
204
+ "",
205
+ "You are working inside a SwarmVault vault. Follow these rules before other actions:",
206
+ "",
207
+ ...SWARMVAULT_RULE_BULLETS,
208
+ "",
209
+ "Use the terminal tool to run `swarmvault` commands. Prefer graph queries over broad grep/glob.",
103
210
  ""
104
211
  ].join("\n");
105
212
  }
@@ -136,6 +243,14 @@ function primaryTargetPathForAgent(rootDir, agent) {
136
243
  return path.join(rootDir, agentFileKinds.claw);
137
244
  case "droid":
138
245
  return path.join(rootDir, agentFileKinds.droid);
246
+ case "kiro":
247
+ return path.join(rootDir, agentFileKinds.kiro);
248
+ case "hermes":
249
+ return hermesUserSkillPath();
250
+ case "antigravity":
251
+ return path.join(rootDir, agentFileKinds.antigravityRules);
252
+ case "vscode":
253
+ return path.join(rootDir, agentFileKinds.vscode);
139
254
  default:
140
255
  throw new Error(`Unsupported agent ${String(agent)}`);
141
256
  }
@@ -174,6 +289,15 @@ function targetsForAgent(rootDir, agent, options = {}) {
174
289
  if (agent === "aider") {
175
290
  targets.push(path.join(rootDir, ".aider.conf.yml"));
176
291
  }
292
+ if (agent === "kiro") {
293
+ targets.push(path.join(rootDir, agentFileKinds.kiroSteering));
294
+ }
295
+ if (agent === "hermes") {
296
+ targets.push(path.join(rootDir, agentFileKinds.agents));
297
+ }
298
+ if (agent === "antigravity") {
299
+ targets.push(path.join(rootDir, agentFileKinds.antigravityWorkflow));
300
+ }
177
301
  if (options.hook && supportsAgentHook(agent)) {
178
302
  const configPath = hookConfigPathForAgent(rootDir, agent);
179
303
  const scriptPath = hookScriptPathForAgent(rootDir, agent);
@@ -409,6 +533,21 @@ async function installAgent(rootDir, agent, options = {}) {
409
533
  case "droid":
410
534
  await writeOwnedFile(target, buildManagedBlock("droid"));
411
535
  break;
536
+ case "kiro":
537
+ await writeOwnedFile(target, buildStandaloneSkillFile());
538
+ await writeOwnedFile(path.join(rootDir, agentFileKinds.kiroSteering), buildKiroSteeringFile());
539
+ break;
540
+ case "hermes":
541
+ await upsertManagedBlock(path.join(rootDir, agentFileKinds.agents), buildManagedBlock("agents"));
542
+ await writeOwnedFile(hermesUserSkillPath(), buildStandaloneSkillFile());
543
+ break;
544
+ case "antigravity":
545
+ await writeOwnedFile(target, buildAntigravityRulesFile());
546
+ await writeOwnedFile(path.join(rootDir, agentFileKinds.antigravityWorkflow), buildAntigravityWorkflowFile());
547
+ break;
548
+ case "vscode":
549
+ await writeOwnedFile(target, buildVscodeChatmodeFile());
550
+ break;
412
551
  default:
413
552
  throw new Error(`Unsupported agent ${String(agent)}`);
414
553
  }
@@ -2624,7 +2763,10 @@ async function pushGraphNeo4j(rootDir, options = {}) {
2624
2763
 
2625
2764
  // src/graph-tools.ts
2626
2765
  function normalizeTarget(value) {
2627
- return normalizeWhitespace(value).toLowerCase();
2766
+ return normalizeWhitespace(value).normalize("NFKD").replace(/\p{Mn}+/gu, "").toLowerCase();
2767
+ }
2768
+ function computeNormLabel(label) {
2769
+ return normalizeTarget(label);
2628
2770
  }
2629
2771
  function nodeById(graph) {
2630
2772
  return new Map(graph.nodes.map((node) => [node.id, node]));
@@ -8567,7 +8709,7 @@ async function analyzeCodeSource(manifest, extractedText, schemaHash) {
8567
8709
 
8568
8710
  // src/extraction.ts
8569
8711
  import fs7 from "fs/promises";
8570
- import os from "os";
8712
+ import os2 from "os";
8571
8713
  import path7 from "path";
8572
8714
  import { Readable } from "stream";
8573
8715
  import { parse as parseCsvSync } from "csv-parse/sync";
@@ -8691,7 +8833,7 @@ async function materializeAttachmentPath(input) {
8691
8833
  if (!input.bytes) {
8692
8834
  throw new Error("Image extraction requires a file path or bytes.");
8693
8835
  }
8694
- const tempDir = await fs7.mkdtemp(path7.join(os.tmpdir(), "swarmvault-image-extract-"));
8836
+ const tempDir = await fs7.mkdtemp(path7.join(os2.tmpdir(), "swarmvault-image-extract-"));
8695
8837
  const extension = input.mimeType.split("/")[1]?.split("+")[0] ?? "bin";
8696
8838
  const tempPath = path7.join(tempDir, `source.${extension}`);
8697
8839
  await fs7.writeFile(tempPath, input.bytes);
@@ -8773,6 +8915,27 @@ async function extractImageWithVision(rootDir, input) {
8773
8915
  await attachment.cleanup();
8774
8916
  }
8775
8917
  }
8918
+ async function buildCorpusHint(rootDir, maxTerms = 6) {
8919
+ let graphPath;
8920
+ try {
8921
+ const { paths } = await loadVaultConfig(rootDir);
8922
+ graphPath = paths.graphPath;
8923
+ } catch {
8924
+ return void 0;
8925
+ }
8926
+ if (!await fileExists(graphPath)) {
8927
+ return void 0;
8928
+ }
8929
+ const graph = await readJsonFile(graphPath);
8930
+ if (!graph || !Array.isArray(graph.nodes) || graph.nodes.length === 0) {
8931
+ return void 0;
8932
+ }
8933
+ const top = graph.nodes.filter((node) => node.type !== "source" && Boolean(node.label)).sort((left, right) => (right.degree ?? 0) - (left.degree ?? 0)).slice(0, maxTerms).map((node) => node.label.trim()).filter((label) => label.length > 0);
8934
+ if (top.length === 0) {
8935
+ return void 0;
8936
+ }
8937
+ return `This audio is likely about ${top.join(", ")}.`;
8938
+ }
8776
8939
  async function extractAudioTranscription(rootDir, input) {
8777
8940
  let provider;
8778
8941
  try {
@@ -8793,11 +8956,13 @@ async function extractAudioTranscription(rootDir, input) {
8793
8956
  }
8794
8957
  };
8795
8958
  }
8959
+ const corpusHint = input.corpusHint ?? await buildCorpusHint(rootDir);
8796
8960
  try {
8797
8961
  const result = await provider.transcribeAudio({
8798
8962
  mimeType: input.mimeType,
8799
8963
  bytes: input.bytes,
8800
- fileName: input.fileName
8964
+ fileName: input.fileName,
8965
+ corpusHint
8801
8966
  });
8802
8967
  const metadata = {};
8803
8968
  if (result.duration !== void 0) {
@@ -8806,6 +8971,9 @@ async function extractAudioTranscription(rootDir, input) {
8806
8971
  if (result.language) {
8807
8972
  metadata.language = result.language;
8808
8973
  }
8974
+ if (corpusHint) {
8975
+ metadata.corpus_hint = corpusHint;
8976
+ }
8809
8977
  return {
8810
8978
  extractedText: result.text || void 0,
8811
8979
  artifact: {
@@ -18221,7 +18389,7 @@ async function resolveImageGenerationProvider(rootDir) {
18221
18389
  if (!providerConfig) {
18222
18390
  throw new Error(`No provider configured with id "${preferredProviderId}" for task "imageProvider".`);
18223
18391
  }
18224
- const { createProvider: createProvider2 } = await import("./registry-4C55ZCPL.js");
18392
+ const { createProvider: createProvider2 } = await import("./registry-JR5WY22P.js");
18225
18393
  return createProvider2(preferredProviderId, providerConfig, rootDir);
18226
18394
  }
18227
18395
  async function generateOutputArtifacts(rootDir, input) {
@@ -19255,6 +19423,13 @@ function autoResolution(nodeCount, edgeCount) {
19255
19423
  if (edgeCount / Math.max(1, nodeCount) < 2) return 0.8;
19256
19424
  return 1;
19257
19425
  }
19426
+ function pruneDanglingEdges(nodes, edges) {
19427
+ const nodeIds = new Set(nodes.map((node) => node.id));
19428
+ return edges.filter((edge) => nodeIds.has(edge.source) && nodeIds.has(edge.target));
19429
+ }
19430
+ function applyNormLabel(nodes) {
19431
+ return nodes.map((node) => node.normLabel ? node : { ...node, normLabel: computeNormLabel(node.label) });
19432
+ }
19258
19433
  function deriveGraphMetrics(nodes, edges, options) {
19259
19434
  const adjacency = /* @__PURE__ */ new Map();
19260
19435
  const connect = (left, right) => {
@@ -19672,20 +19847,33 @@ function buildGraph(manifests, analyses, pages, sourceProjects, _codeIndex, opti
19672
19847
  }
19673
19848
  for (const symbol of analysis.code.symbols) {
19674
19849
  for (const targetName of symbol.calls) {
19675
- const targetId = resolveLocalSymbolId(targetName);
19676
- if (!targetId || targetId === symbol.id) {
19850
+ const localTargetId = resolveLocalSymbolId(targetName);
19851
+ if (localTargetId && localTargetId !== symbol.id) {
19852
+ pushEdge({
19853
+ id: `${symbol.id}->${localTargetId}:calls`,
19854
+ source: symbol.id,
19855
+ target: localTargetId,
19856
+ relation: "calls",
19857
+ status: "extracted",
19858
+ evidenceClass: "extracted",
19859
+ confidence: 1,
19860
+ provenance: [analysis.sourceId]
19861
+ });
19677
19862
  continue;
19678
19863
  }
19679
- pushEdge({
19680
- id: `${symbol.id}->${targetId}:calls`,
19681
- source: symbol.id,
19682
- target: targetId,
19683
- relation: "calls",
19684
- status: "extracted",
19685
- evidenceClass: "extracted",
19686
- confidence: 1,
19687
- provenance: [analysis.sourceId]
19688
- });
19864
+ const crossFileTargetId = importedSymbolIdsByName.get(targetName);
19865
+ if (crossFileTargetId && crossFileTargetId !== symbol.id) {
19866
+ pushEdge({
19867
+ id: `${symbol.id}->${crossFileTargetId}:calls`,
19868
+ source: symbol.id,
19869
+ target: crossFileTargetId,
19870
+ relation: "calls",
19871
+ status: "inferred",
19872
+ evidenceClass: "inferred",
19873
+ confidence: 0.8,
19874
+ provenance: [analysis.sourceId]
19875
+ });
19876
+ }
19689
19877
  }
19690
19878
  for (const targetName of symbol.extends) {
19691
19879
  const targetId = resolveLocalSymbolId(targetName) ?? importedSymbolIdsByName.get(targetName);
@@ -19800,11 +19988,17 @@ function buildGraph(manifests, analyses, pages, sourceProjects, _codeIndex, opti
19800
19988
  analyses
19801
19989
  );
19802
19990
  const metrics = deriveGraphMetrics(graphNodes, enriched.edges, { resolution: options?.communityResolution });
19991
+ const finalNodes = applyNormLabel(metrics.nodes);
19992
+ const finalEdges = pruneDanglingEdges(finalNodes, enriched.edges);
19993
+ const finalHyperedges = (enriched.hyperedges ?? []).filter((hyperedge) => {
19994
+ const nodeIdSet = new Set(finalNodes.map((node) => node.id));
19995
+ return hyperedge.nodeIds.every((id) => nodeIdSet.has(id));
19996
+ });
19803
19997
  return {
19804
19998
  generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
19805
- nodes: metrics.nodes,
19806
- edges: enriched.edges,
19807
- hyperedges: enriched.hyperedges,
19999
+ nodes: finalNodes,
20000
+ edges: finalEdges,
20001
+ hyperedges: finalHyperedges,
19808
20002
  communities: metrics.communities,
19809
20003
  sources: manifests,
19810
20004
  pages
@@ -21656,7 +21850,101 @@ async function ensureObsidianWorkspace(rootDir) {
21656
21850
  })
21657
21851
  ]);
21658
21852
  }
21853
+ async function initLiteVault(rootDir, options) {
21854
+ const rawDir = path23.join(rootDir, "raw");
21855
+ const wikiDir = path23.join(rootDir, "wiki");
21856
+ const schemaPath = path23.join(rootDir, PRIMARY_SCHEMA_FILENAME);
21857
+ const indexPath = path23.join(wikiDir, "index.md");
21858
+ const logPath = path23.join(wikiDir, "log.md");
21859
+ await Promise.all([ensureDir(rawDir), ensureDir(wikiDir)]);
21860
+ if (!await fileExists(schemaPath)) {
21861
+ await fs19.writeFile(schemaPath, defaultVaultSchema("default"), "utf8");
21862
+ }
21863
+ const now = (/* @__PURE__ */ new Date()).toISOString();
21864
+ if (!await fileExists(indexPath)) {
21865
+ await fs19.writeFile(
21866
+ indexPath,
21867
+ matter10.stringify(
21868
+ [
21869
+ "# Wiki Index",
21870
+ "",
21871
+ "This lite vault is agent-maintained. Drop sources into `raw/`, edit `swarmvault.schema.md` to teach the agent how the wiki should be organized, then ask your agent to read sources and update pages here.",
21872
+ "",
21873
+ "- Summaries, entity pages, and concept pages live under `wiki/`.",
21874
+ "- Append every ingest/query/lint operation to `wiki/log.md`.",
21875
+ "- Run `swarmvault init` (without `--lite`) when you want the full toolchain with graph, search, and approvals.",
21876
+ ""
21877
+ ].join("\n"),
21878
+ {
21879
+ page_id: "wiki:index",
21880
+ kind: "index",
21881
+ title: "Wiki Index",
21882
+ tags: ["index"],
21883
+ source_ids: [],
21884
+ project_ids: [],
21885
+ node_ids: [],
21886
+ freshness: "fresh",
21887
+ status: "active",
21888
+ confidence: 1,
21889
+ created_at: now,
21890
+ updated_at: now,
21891
+ compiled_from: [],
21892
+ managed_by: "agent",
21893
+ backlinks: [],
21894
+ schema_hash: "",
21895
+ source_hashes: {},
21896
+ source_semantic_hashes: {}
21897
+ }
21898
+ ),
21899
+ "utf8"
21900
+ );
21901
+ }
21902
+ if (!await fileExists(logPath)) {
21903
+ await fs19.writeFile(
21904
+ logPath,
21905
+ matter10.stringify(
21906
+ [
21907
+ "# Activity Log",
21908
+ "",
21909
+ "Append-only chronological record. One line per ingest/query/lint operation, newest at the bottom.",
21910
+ "",
21911
+ "Format: `## [YYYY-MM-DD] <verb> | <subject>`",
21912
+ ""
21913
+ ].join("\n"),
21914
+ {
21915
+ page_id: "wiki:log",
21916
+ kind: "index",
21917
+ title: "Activity Log",
21918
+ tags: ["log", "append-only"],
21919
+ source_ids: [],
21920
+ project_ids: [],
21921
+ node_ids: [],
21922
+ freshness: "fresh",
21923
+ status: "active",
21924
+ confidence: 1,
21925
+ created_at: now,
21926
+ updated_at: now,
21927
+ compiled_from: [],
21928
+ managed_by: "agent",
21929
+ backlinks: [],
21930
+ schema_hash: "",
21931
+ source_hashes: {},
21932
+ source_semantic_hashes: {}
21933
+ }
21934
+ ),
21935
+ "utf8"
21936
+ );
21937
+ }
21938
+ if (options.obsidian) {
21939
+ const obsidianDir = path23.join(rootDir, ".obsidian");
21940
+ await ensureDir(obsidianDir);
21941
+ }
21942
+ }
21659
21943
  async function initVault(rootDir, options = {}) {
21944
+ if (options.lite) {
21945
+ await initLiteVault(rootDir, options);
21946
+ return;
21947
+ }
21660
21948
  const requestedProfile = options.profile ?? "default";
21661
21949
  const { config, paths } = await initWorkspace(rootDir, { profile: requestedProfile });
21662
21950
  const profile = config.profile;
@@ -23352,7 +23640,7 @@ async function getWatchStatus(rootDir) {
23352
23640
  }
23353
23641
 
23354
23642
  // src/mcp.ts
23355
- var SERVER_VERSION = "0.8.0";
23643
+ var SERVER_VERSION = "0.9.0";
23356
23644
  async function createMcpServer(rootDir) {
23357
23645
  const server = new McpServer({
23358
23646
  name: "swarmvault",
@@ -0,0 +1,12 @@
1
+ import {
2
+ assertProviderCapability,
3
+ createProvider,
4
+ getProviderForTask,
5
+ getResolvedPaths
6
+ } from "./chunk-BTWPJEP2.js";
7
+ export {
8
+ assertProviderCapability,
9
+ createProvider,
10
+ getProviderForTask,
11
+ getResolvedPaths
12
+ };
@@ -0,0 +1,12 @@
1
+ import {
2
+ assertProviderCapability,
3
+ createProvider,
4
+ getProviderForTask,
5
+ getResolvedPaths
6
+ } from "./chunk-CG67P2HB.js";
7
+ export {
8
+ assertProviderCapability,
9
+ createProvider,
10
+ getProviderForTask,
11
+ getResolvedPaths
12
+ };
@@ -0,0 +1,12 @@
1
+ import {
2
+ assertProviderCapability,
3
+ createProvider,
4
+ getProviderForTask,
5
+ getResolvedPaths
6
+ } from "./chunk-RSQRF4FV.js";
7
+ export {
8
+ assertProviderCapability,
9
+ createProvider,
10
+ getProviderForTask,
11
+ getResolvedPaths
12
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@swarmvaultai/engine",
3
- "version": "0.8.0",
3
+ "version": "0.9.0",
4
4
  "description": "Core engine for SwarmVault: ingest, compile, query, lint, and provider abstractions.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",