ruflo 3.6.11 → 3.6.13

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 (29) hide show
  1. package/package.json +4 -1
  2. package/src/ruvocal/.claude-flow/data/pending-insights.jsonl +25 -0
  3. package/src/ruvocal/.claude-flow/neural/stats.json +6 -0
  4. package/src/ruvocal/.dockerignore +5 -1
  5. package/src/ruvocal/.gcloudignore +18 -0
  6. package/src/ruvocal/README.md +107 -133
  7. package/src/ruvocal/cloudbuild.yaml +68 -0
  8. package/src/ruvocal/config/branding.env.example +19 -0
  9. package/src/ruvocal/mcp-bridge/index.js +15 -1
  10. package/src/ruvocal/src/lib/components/FoundationBackground.svelte +242 -0
  11. package/src/ruvocal/src/lib/components/NavMenu.svelte +18 -0
  12. package/src/ruvocal/src/lib/components/RufloHelpModal.svelte +411 -0
  13. package/src/ruvocal/src/lib/components/chat/ChatWindow.svelte +122 -4
  14. package/src/ruvocal/src/lib/components/wasm/GalleryPanel.svelte +357 -0
  15. package/src/ruvocal/src/lib/constants/mcpExamples.ts +56 -77
  16. package/src/ruvocal/src/lib/constants/routerExamples.ts +51 -127
  17. package/src/ruvocal/src/lib/constants/rvagentPresets.ts +206 -0
  18. package/src/ruvocal/src/lib/server/textGeneration/mcp/wasmTools.test.ts +633 -0
  19. package/src/ruvocal/src/lib/stores/mcpServers.ts +195 -6
  20. package/src/ruvocal/src/lib/stores/wasmMcp.ts +472 -0
  21. package/src/ruvocal/src/lib/types/Settings.ts +7 -0
  22. package/src/ruvocal/src/lib/types/Tool.ts +4 -1
  23. package/src/ruvocal/src/lib/wasm/idb.ts +438 -0
  24. package/src/ruvocal/src/lib/wasm/index.ts +1213 -0
  25. package/src/ruvocal/src/lib/wasm/tests/wasm-capabilities.test.ts +565 -0
  26. package/src/ruvocal/src/lib/wasm/wasm.worker.ts +332 -0
  27. package/src/ruvocal/src/lib/wasm/workerClient.ts +166 -0
  28. package/src/ruvocal/static/wasm/rvagent_wasm.js +1539 -0
  29. package/src/ruvocal/static/wasm/rvagent_wasm_bg.wasm +0 -0
@@ -0,0 +1,1213 @@
1
+ /**
2
+ * WASM Integration Layer
3
+ * Loads rvagent-wasm and provides TypeScript bindings
4
+ */
5
+
6
+ import { browser } from "$app/environment";
7
+
8
+ // Types for WASM exports
9
+ export interface WasmMcpServer {
10
+ handle_message(message: string): string;
11
+ gallery(): WasmGallery;
12
+ }
13
+
14
+ export interface WasmGallery {
15
+ list(): GalleryTemplate[];
16
+ listByCategory(category: string): GalleryTemplate[];
17
+ search(query: string): SearchResult[];
18
+ get(id: string): GalleryTemplate;
19
+ loadRvf(id: string): Uint8Array;
20
+ setActive(id: string): void;
21
+ getActive(): string | null;
22
+ configure(configJson: string): void;
23
+ getConfig(): unknown;
24
+ addCustom(templateJson: string): void;
25
+ removeCustom(id: string): void;
26
+ getCategories(): Record<string, number>;
27
+ count(): number;
28
+ exportCustom(): GalleryTemplate[];
29
+ importCustom(templatesJson: string): number;
30
+ }
31
+
32
+ export interface WasmRvfBuilder {
33
+ addTool(toolJson: string): void;
34
+ addTools(toolsJson: string): void;
35
+ addPrompt(promptJson: string): void;
36
+ addPrompts(promptsJson: string): void;
37
+ addSkill(skillJson: string): void;
38
+ addSkills(skillsJson: string): void;
39
+ addMcpTools(mcpToolsJson: string): void;
40
+ addCapabilities(capsJson: string): void;
41
+ setOrchestrator(orchestratorJson: string): void;
42
+ build(): Uint8Array;
43
+ }
44
+
45
+ export interface GalleryTemplate {
46
+ id: string;
47
+ name: string;
48
+ description: string;
49
+ category: string;
50
+ version: string;
51
+ author: string;
52
+ tags: string[];
53
+ builtin: boolean;
54
+ tools?: ToolDefinition[];
55
+ prompts?: AgentPrompt[];
56
+ skills?: SkillDefinition[];
57
+ mcp_tools?: McpToolEntry[];
58
+ capabilities?: CapabilityDef[];
59
+ orchestrator?: OrchestratorConfig;
60
+ }
61
+
62
+ export interface SearchResult {
63
+ id: string;
64
+ name: string;
65
+ description: string;
66
+ category: string;
67
+ tags: string[];
68
+ relevance: number;
69
+ }
70
+
71
+ export interface ToolDefinition {
72
+ name: string;
73
+ description: string;
74
+ parameters: unknown;
75
+ returns?: string;
76
+ }
77
+
78
+ export interface AgentPrompt {
79
+ name: string;
80
+ system_prompt: string;
81
+ version: string;
82
+ }
83
+
84
+ export interface SkillDefinition {
85
+ name: string;
86
+ description: string;
87
+ trigger: string;
88
+ content: string;
89
+ }
90
+
91
+ export interface McpToolEntry {
92
+ name: string;
93
+ description: string;
94
+ input_schema: unknown;
95
+ group?: string;
96
+ }
97
+
98
+ export interface CapabilityDef {
99
+ name: string;
100
+ rights: string[];
101
+ scope: string;
102
+ delegation_depth: number;
103
+ }
104
+
105
+ export interface OrchestratorConfig {
106
+ topology: string;
107
+ agents: AgentNode[];
108
+ connections: [string, string][];
109
+ }
110
+
111
+ export interface AgentNode {
112
+ id: string;
113
+ agent_type: string;
114
+ prompt_ref: string;
115
+ }
116
+
117
+ // WASM module instance
118
+ let wasmModule: {
119
+ WasmMcpServer: new () => WasmMcpServer;
120
+ WasmGallery: new () => WasmGallery;
121
+ WasmRvfBuilder: new () => WasmRvfBuilder;
122
+ } | null = null;
123
+
124
+ type WasmModuleType = {
125
+ WasmMcpServer: new () => WasmMcpServer;
126
+ WasmGallery: new () => WasmGallery;
127
+ WasmRvfBuilder: new () => WasmRvfBuilder;
128
+ } | null;
129
+
130
+ let loadPromise: Promise<WasmModuleType> | null = null;
131
+
132
+ /**
133
+ * Create a mock WASM module for development/testing when actual WASM isn't available
134
+ * Implements the full rvAgent feature set with 8 tools, 14 middleware capabilities,
135
+ * SONA learning, HNSW search, AGI containers, and security controls
136
+ */
137
+ function createMockWasmModule() {
138
+ // Built-in templates for mock gallery - comprehensive rvAgent implementations
139
+ const builtinTemplates: GalleryTemplate[] = [
140
+ {
141
+ id: "development-agent",
142
+ name: "Development Agent",
143
+ description: "Full-featured development agent with code editing, file management, testing, and task tracking. O(1) state cloning for instant subagent spawning.",
144
+ category: "development",
145
+ version: "2.0.0",
146
+ author: "RuVector",
147
+ tags: ["development", "coding", "testing", "files", "tasks", "production"],
148
+ builtin: true,
149
+ tools: [
150
+ { name: "read_file", description: "Read file contents from the virtual filesystem", parameters: { path: "string" } },
151
+ { name: "write_file", description: "Write content to a file in the virtual filesystem", parameters: { path: "string", content: "string" } },
152
+ { name: "edit_file", description: "Edit a file by replacing old content with new content", parameters: { path: "string", old_content: "string", new_content: "string" } },
153
+ { name: "list_files", description: "List all files in the virtual filesystem", parameters: {} },
154
+ { name: "delete_file", description: "Delete a file from the virtual filesystem", parameters: { path: "string" } },
155
+ { name: "grep", description: "Search for patterns in files using regex", parameters: { pattern: "string", path: "string?" } },
156
+ { name: "glob", description: "Find files matching a glob pattern", parameters: { pattern: "string" } },
157
+ { name: "execute", description: "Execute a shell command (sandboxed)", parameters: { command: "string", cwd: "string?" } },
158
+ ],
159
+ prompts: [{
160
+ name: "developer",
161
+ system_prompt: "You are a production-grade coding assistant powered by rvAgent. You have access to file operations, search, and task management. Be concise and focus on writing correct, secure code. Use the task tracking tools to manage complex workflows. Always validate inputs and handle errors gracefully.",
162
+ version: "2.0.0"
163
+ }],
164
+ skills: [
165
+ { name: "commit", description: "Create a git commit with conventional commit messages", trigger: "/commit", content: "Review changes, generate commit message, stage files, create commit" },
166
+ { name: "review", description: "Review code for security, performance, and best practices", trigger: "/review", content: "Analyze code for issues, suggest improvements, check for vulnerabilities" },
167
+ { name: "test", description: "Run tests and analyze failures", trigger: "/test", content: "Execute test suite, analyze failures, suggest fixes" },
168
+ { name: "refactor", description: "Refactor code while maintaining behavior", trigger: "/refactor", content: "Identify code smells, propose refactoring, maintain tests" },
169
+ ],
170
+ mcp_tools: [
171
+ { name: "todo_add", description: "Add a task to the todo list", input_schema: { type: "object", properties: { task: { type: "string" } } }, group: "tasks" },
172
+ { name: "todo_list", description: "List all pending tasks", input_schema: { type: "object" }, group: "tasks" },
173
+ { name: "todo_complete", description: "Mark a task as complete", input_schema: { type: "object", properties: { id: { type: "string" } } }, group: "tasks" },
174
+ { name: "memory_store", description: "Store information in semantic memory", input_schema: { type: "object", properties: { key: { type: "string" }, value: { type: "string" } } }, group: "memory" },
175
+ { name: "memory_search", description: "Search semantic memory using HNSW", input_schema: { type: "object", properties: { query: { type: "string" } } }, group: "memory" },
176
+ ],
177
+ capabilities: [
178
+ { name: "file_ops", rights: ["read", "write", "delete"], scope: "/workspace", delegation_depth: 2 },
179
+ { name: "execute", rights: ["run"], scope: "sandboxed", delegation_depth: 1 },
180
+ { name: "memory", rights: ["read", "write", "search"], scope: "session", delegation_depth: 0 },
181
+ ],
182
+ },
183
+ {
184
+ id: "research-agent",
185
+ name: "Research Agent",
186
+ description: "Research-focused agent with web search, document analysis, and semantic memory. HNSW-indexed memory for O(log n) retrieval across millions of entries.",
187
+ category: "research",
188
+ version: "2.0.0",
189
+ author: "RuVector",
190
+ tags: ["research", "analysis", "documentation", "memory", "search"],
191
+ builtin: true,
192
+ tools: [
193
+ { name: "read_file", description: "Read file contents", parameters: { path: "string" } },
194
+ { name: "write_file", description: "Write content to a file", parameters: { path: "string", content: "string" } },
195
+ { name: "list_files", description: "List files", parameters: {} },
196
+ { name: "web_search", description: "Search the web for information", parameters: { query: "string", limit: "number?" } },
197
+ { name: "analyze_document", description: "Analyze a document for key insights", parameters: { content: "string", focus: "string?" } },
198
+ { name: "summarize", description: "Summarize long content", parameters: { content: "string", max_length: "number?" } },
199
+ ],
200
+ prompts: [{
201
+ name: "researcher",
202
+ system_prompt: "You are an expert research assistant with access to semantic memory and document analysis tools. Your goal is to find accurate information, synthesize insights, and provide well-sourced answers. Use memory to track findings across sessions. Always cite sources and acknowledge uncertainty.",
203
+ version: "2.0.0"
204
+ }],
205
+ skills: [
206
+ { name: "deep-dive", description: "Conduct deep research on a topic", trigger: "/deep-dive", content: "Comprehensive multi-source research with citations" },
207
+ { name: "summarize", description: "Create executive summary", trigger: "/summarize", content: "Condense information into key points" },
208
+ { name: "compare", description: "Compare multiple sources", trigger: "/compare", content: "Analyze similarities and differences" },
209
+ ],
210
+ mcp_tools: [
211
+ { name: "memory_store", description: "Store research findings", input_schema: { type: "object", properties: { key: { type: "string" }, value: { type: "string" }, tags: { type: "array" } } }, group: "memory" },
212
+ { name: "memory_search", description: "Search past research (HNSW)", input_schema: { type: "object", properties: { query: { type: "string" }, top_k: { type: "number" } } }, group: "memory" },
213
+ { name: "cite", description: "Generate citation", input_schema: { type: "object", properties: { source: { type: "string" }, format: { type: "string" } } }, group: "research" },
214
+ ],
215
+ capabilities: [
216
+ { name: "web_access", rights: ["search", "fetch"], scope: "internet", delegation_depth: 1 },
217
+ { name: "memory", rights: ["read", "write", "search"], scope: "persistent", delegation_depth: 0 },
218
+ ],
219
+ },
220
+ {
221
+ id: "security-agent",
222
+ name: "Security Agent",
223
+ description: "Security-focused agent for code auditing, vulnerability scanning, and threat detection. 15 built-in security controls including path traversal, injection, and credential protection.",
224
+ category: "security",
225
+ version: "2.0.0",
226
+ author: "RuVector",
227
+ tags: ["security", "audit", "vulnerabilities", "penetration-testing", "compliance"],
228
+ builtin: true,
229
+ tools: [
230
+ { name: "read_file", description: "Read file contents (path-confined)", parameters: { path: "string" } },
231
+ { name: "list_files", description: "List files", parameters: {} },
232
+ { name: "grep", description: "Search for patterns (e.g., credentials)", parameters: { pattern: "string", path: "string?" } },
233
+ { name: "scan_vulnerabilities", description: "Scan code for known vulnerabilities", parameters: { path: "string", severity: "string?" } },
234
+ { name: "audit_code", description: "Audit code for security issues", parameters: { path: "string", ruleset: "string?" } },
235
+ { name: "check_dependencies", description: "Check dependencies for CVEs", parameters: { manifest: "string" } },
236
+ ],
237
+ prompts: [{
238
+ name: "security",
239
+ system_prompt: "You are a security expert powered by rvAgent's 15 built-in security controls. You can detect path traversal, credential leaks, injection attacks, and unicode spoofing. Analyze code with a security-first mindset. Report vulnerabilities with severity, impact, and remediation steps. Never expose sensitive data in outputs.",
240
+ version: "2.0.0"
241
+ }],
242
+ skills: [
243
+ { name: "audit", description: "Full security audit", trigger: "/audit", content: "Comprehensive security review with OWASP checks" },
244
+ { name: "pentest", description: "Penetration testing simulation", trigger: "/pentest", content: "Simulate attack vectors and report findings" },
245
+ { name: "compliance", description: "Compliance check", trigger: "/compliance", content: "Check against security frameworks (SOC2, HIPAA, etc.)" },
246
+ ],
247
+ mcp_tools: [
248
+ { name: "cve_lookup", description: "Lookup CVE details", input_schema: { type: "object", properties: { cve_id: { type: "string" } } }, group: "security" },
249
+ { name: "report_vuln", description: "Generate vulnerability report", input_schema: { type: "object", properties: { findings: { type: "array" } } }, group: "security" },
250
+ { name: "witness_log", description: "Log to witness chain (immutable audit)", input_schema: { type: "object", properties: { action: { type: "string" }, data: { type: "object" } } }, group: "audit" },
251
+ ],
252
+ capabilities: [
253
+ { name: "file_ops", rights: ["read"], scope: "/workspace", delegation_depth: 1 },
254
+ { name: "audit", rights: ["read", "write"], scope: "witness_chain", delegation_depth: 0 },
255
+ ],
256
+ },
257
+ {
258
+ id: "multi-agent-orchestrator",
259
+ name: "Multi-Agent Orchestrator",
260
+ description: "Coordinate multiple specialized agents with CRDT-based state merging. Spawn subagents instantly with O(1) state cloning, merge results deterministically.",
261
+ category: "orchestration",
262
+ version: "2.0.0",
263
+ author: "RuVector",
264
+ tags: ["multi-agent", "orchestration", "coordination", "parallel", "subagents"],
265
+ builtin: true,
266
+ tools: [
267
+ { name: "read_file", description: "Read file contents", parameters: { path: "string" } },
268
+ { name: "write_file", description: "Write content to a file", parameters: { path: "string", content: "string" } },
269
+ { name: "list_files", description: "List files", parameters: {} },
270
+ { name: "spawn_agent", description: "Spawn a specialized subagent", parameters: { type: "string", task: "string" } },
271
+ { name: "merge_results", description: "Merge subagent results using CRDT", parameters: { results: "array" } },
272
+ ],
273
+ prompts: [{
274
+ name: "orchestrator",
275
+ system_prompt: "You are a multi-agent orchestrator. You can spawn specialized subagents (security-reviewer, performance-reviewer, code-reviewer) and coordinate their work. Use CRDT merging for conflict-free result combination. Delegate effectively and synthesize findings into actionable insights.",
276
+ version: "2.0.0"
277
+ }],
278
+ skills: [
279
+ { name: "parallel-review", description: "Parallel code review with multiple agents", trigger: "/parallel-review", content: "Spawn security, performance, and style reviewers simultaneously" },
280
+ { name: "swarm", description: "Deploy agent swarm for complex task", trigger: "/swarm", content: "Coordinate multiple agents for large-scale analysis" },
281
+ ],
282
+ mcp_tools: [
283
+ { name: "agent_spawn", description: "Spawn a subagent", input_schema: { type: "object", properties: { type: { type: "string" }, task: { type: "string" } } }, group: "orchestration" },
284
+ { name: "agent_status", description: "Get subagent status", input_schema: { type: "object", properties: { id: { type: "string" } } }, group: "orchestration" },
285
+ { name: "results_merge", description: "Merge results with CRDT", input_schema: { type: "object", properties: { results: { type: "array" } } }, group: "orchestration" },
286
+ ],
287
+ capabilities: [
288
+ { name: "orchestration", rights: ["spawn", "terminate", "merge"], scope: "subagents", delegation_depth: 3 },
289
+ { name: "file_ops", rights: ["read", "write"], scope: "/workspace", delegation_depth: 2 },
290
+ ],
291
+ orchestrator: {
292
+ topology: "hierarchical",
293
+ agents: [
294
+ { id: "coordinator", agent_type: "orchestrator", prompt_ref: "orchestrator" },
295
+ { id: "security", agent_type: "security-reviewer", prompt_ref: "security" },
296
+ { id: "performance", agent_type: "performance-reviewer", prompt_ref: "performance" },
297
+ { id: "style", agent_type: "style-reviewer", prompt_ref: "style" },
298
+ ],
299
+ connections: [["coordinator", "security"], ["coordinator", "performance"], ["coordinator", "style"]],
300
+ },
301
+ },
302
+ {
303
+ id: "sona-learning-agent",
304
+ name: "SONA Learning Agent",
305
+ description: "Self-improving agent with SONA (Self-Optimizing Neural Architecture). 3-loop learning: instant feedback (<0.05ms), background optimization, deep consolidation.",
306
+ category: "learning",
307
+ version: "2.0.0",
308
+ author: "RuVector",
309
+ tags: ["learning", "adaptive", "self-improving", "sona", "neural"],
310
+ builtin: true,
311
+ tools: [
312
+ { name: "read_file", description: "Read file contents", parameters: { path: "string" } },
313
+ { name: "write_file", description: "Write content to a file", parameters: { path: "string", content: "string" } },
314
+ { name: "edit_file", description: "Edit a file", parameters: { path: "string", old_content: "string", new_content: "string" } },
315
+ { name: "list_files", description: "List files", parameters: {} },
316
+ { name: "learn_pattern", description: "Learn a new pattern from experience", parameters: { pattern: "string", outcome: "string" } },
317
+ { name: "predict_action", description: "Predict best action based on learned patterns", parameters: { context: "string" } },
318
+ ],
319
+ prompts: [{
320
+ name: "learner",
321
+ system_prompt: "You are a self-improving agent with SONA learning capabilities. You learn from every interaction through 3 feedback loops: Loop A (instant, <0.05ms) for immediate adjustments, Loop B (background) for pattern optimization, Loop C (consolidation) for deep learning. Track your performance and continuously improve your responses.",
322
+ version: "2.0.0"
323
+ }],
324
+ skills: [
325
+ { name: "learn", description: "Learn from experience", trigger: "/learn", content: "Record pattern and outcome for future use" },
326
+ { name: "recall", description: "Recall learned patterns", trigger: "/recall", content: "Search learned patterns matching context" },
327
+ { name: "optimize", description: "Trigger optimization cycle", trigger: "/optimize", content: "Run background optimization on learned patterns" },
328
+ ],
329
+ mcp_tools: [
330
+ { name: "pattern_store", description: "Store learned pattern", input_schema: { type: "object", properties: { pattern: { type: "string" }, outcome: { type: "string" }, confidence: { type: "number" } } }, group: "learning" },
331
+ { name: "pattern_search", description: "Search patterns (HNSW)", input_schema: { type: "object", properties: { query: { type: "string" }, top_k: { type: "number" } } }, group: "learning" },
332
+ { name: "feedback_record", description: "Record feedback for learning", input_schema: { type: "object", properties: { action: { type: "string" }, success: { type: "boolean" } } }, group: "learning" },
333
+ ],
334
+ capabilities: [
335
+ { name: "learning", rights: ["read", "write", "optimize"], scope: "neural", delegation_depth: 0 },
336
+ { name: "file_ops", rights: ["read", "write"], scope: "/workspace", delegation_depth: 1 },
337
+ ],
338
+ },
339
+ {
340
+ id: "agi-container-builder",
341
+ name: "AGI Container Builder",
342
+ description: "Build portable AI agent packages (AGI Containers) with tools, prompts, skills, and verified checksums. SHA3-256 integrity verification for secure deployment.",
343
+ category: "tooling",
344
+ version: "2.0.0",
345
+ author: "RuVector",
346
+ tags: ["agi", "container", "portable", "deployment", "rvf"],
347
+ builtin: true,
348
+ tools: [
349
+ { name: "read_file", description: "Read file contents", parameters: { path: "string" } },
350
+ { name: "write_file", description: "Write content to a file", parameters: { path: "string", content: "string" } },
351
+ { name: "list_files", description: "List files", parameters: {} },
352
+ { name: "build_container", description: "Build an AGI container", parameters: { manifest: "object" } },
353
+ { name: "verify_container", description: "Verify container integrity", parameters: { path: "string" } },
354
+ { name: "extract_container", description: "Extract container contents", parameters: { path: "string", dest: "string" } },
355
+ ],
356
+ prompts: [{
357
+ name: "builder",
358
+ system_prompt: "You are an AGI Container builder. You help create portable, verified AI agent packages that bundle tools, prompts, skills, and capabilities. Each container has SHA3-256 checksum verification for security. Guide users through container creation, validation, and deployment.",
359
+ version: "2.0.0"
360
+ }],
361
+ skills: [
362
+ { name: "build", description: "Build AGI container", trigger: "/build", content: "Create verified RVF container from manifest" },
363
+ { name: "verify", description: "Verify container", trigger: "/verify", content: "Check SHA3-256 integrity and validate structure" },
364
+ { name: "deploy", description: "Deploy container", trigger: "/deploy", content: "Extract and activate container in runtime" },
365
+ ],
366
+ mcp_tools: [
367
+ { name: "rvf_build", description: "Build RVF container", input_schema: { type: "object", properties: { tools: { type: "array" }, prompts: { type: "array" }, skills: { type: "array" } } }, group: "container" },
368
+ { name: "rvf_verify", description: "Verify RVF container", input_schema: { type: "object", properties: { data: { type: "string" } } }, group: "container" },
369
+ { name: "rvf_extract", description: "Extract RVF contents", input_schema: { type: "object", properties: { data: { type: "string" } } }, group: "container" },
370
+ ],
371
+ capabilities: [
372
+ { name: "container", rights: ["build", "verify", "extract"], scope: "rvf", delegation_depth: 0 },
373
+ { name: "file_ops", rights: ["read", "write"], scope: "/workspace", delegation_depth: 1 },
374
+ ],
375
+ },
376
+ {
377
+ id: "witness-auditor",
378
+ name: "Witness Chain Auditor",
379
+ description: "Cryptographic audit trail agent with immutable witness chains. Every action is logged with a hash chain for forensic debugging and compliance.",
380
+ category: "compliance",
381
+ version: "2.0.0",
382
+ author: "RuVector",
383
+ tags: ["audit", "compliance", "forensics", "witness", "immutable"],
384
+ builtin: true,
385
+ tools: [
386
+ { name: "read_file", description: "Read file contents", parameters: { path: "string" } },
387
+ { name: "list_files", description: "List files", parameters: {} },
388
+ { name: "witness_log", description: "Log action to witness chain", parameters: { action: "string", data: "object" } },
389
+ { name: "witness_verify", description: "Verify witness chain integrity", parameters: { chain_id: "string" } },
390
+ { name: "witness_query", description: "Query witness chain", parameters: { filter: "object" } },
391
+ ],
392
+ prompts: [{
393
+ name: "auditor",
394
+ system_prompt: "You are a compliance auditor with access to immutable witness chains. Every tool call creates a cryptographic log entry forming a hash chain. Use this for forensic debugging, compliance audits, and security investigations. You can verify chain integrity and trace exactly what happened and when.",
395
+ version: "2.0.0"
396
+ }],
397
+ skills: [
398
+ { name: "audit-trail", description: "Generate audit trail", trigger: "/audit-trail", content: "Create comprehensive audit report from witness chain" },
399
+ { name: "verify-chain", description: "Verify chain integrity", trigger: "/verify-chain", content: "Validate all hashes in witness chain" },
400
+ { name: "compliance-report", description: "Generate compliance report", trigger: "/compliance-report", content: "Create compliance report for SOC2/HIPAA/etc." },
401
+ ],
402
+ mcp_tools: [
403
+ { name: "witness_append", description: "Append to witness chain", input_schema: { type: "object", properties: { action: { type: "string" }, data: { type: "object" } } }, group: "audit" },
404
+ { name: "witness_verify", description: "Verify chain integrity", input_schema: { type: "object", properties: { chain_id: { type: "string" } } }, group: "audit" },
405
+ { name: "witness_export", description: "Export chain for external audit", input_schema: { type: "object", properties: { chain_id: { type: "string" }, format: { type: "string" } } }, group: "audit" },
406
+ ],
407
+ capabilities: [
408
+ { name: "audit", rights: ["read", "write", "verify"], scope: "witness_chain", delegation_depth: 0 },
409
+ { name: "file_ops", rights: ["read"], scope: "/workspace", delegation_depth: 1 },
410
+ ],
411
+ },
412
+ {
413
+ id: "minimal-agent",
414
+ name: "Minimal Agent",
415
+ description: "Lightweight agent with just file operations. Perfect for simple tasks or as a starting point for custom agents.",
416
+ category: "basic",
417
+ version: "2.0.0",
418
+ author: "RuVector",
419
+ tags: ["minimal", "simple", "files", "basic"],
420
+ builtin: true,
421
+ tools: [
422
+ { name: "read_file", description: "Read file contents", parameters: { path: "string" } },
423
+ { name: "write_file", description: "Write content to a file", parameters: { path: "string", content: "string" } },
424
+ { name: "list_files", description: "List files", parameters: {} },
425
+ ],
426
+ prompts: [{
427
+ name: "assistant",
428
+ system_prompt: "You are a helpful assistant with access to file operations. Keep responses concise.",
429
+ version: "2.0.0"
430
+ }],
431
+ skills: [],
432
+ mcp_tools: [],
433
+ capabilities: [
434
+ { name: "file_ops", rights: ["read", "write"], scope: "/workspace", delegation_depth: 0 },
435
+ ],
436
+ },
437
+ ];
438
+
439
+ // Virtual filesystem for mock MCP server
440
+ const virtualFS = new Map<string, string>();
441
+ let activeTemplateId: string | null = null;
442
+
443
+ // Todo list for task tracking
444
+ const todoList: { id: string; task: string; completed: boolean; created: number }[] = [];
445
+ let todoIdCounter = 1;
446
+
447
+ // Memory store for semantic memory (simulated HNSW)
448
+ const memoryStore = new Map<string, { key: string; value: string; tags: string[]; embedding?: number[] }>();
449
+
450
+ // Witness chain for audit trail
451
+ const witnessChain: { hash: string; prev_hash: string; action: string; data: unknown; timestamp: number }[] = [];
452
+ let lastWitnessHash = "genesis";
453
+
454
+ // Helper: Simple hash for witness chain
455
+ function simpleHash(data: string): string {
456
+ let hash = 0;
457
+ for (let i = 0; i < data.length; i++) {
458
+ const char = data.charCodeAt(i);
459
+ hash = ((hash << 5) - hash) + char;
460
+ hash = hash & hash;
461
+ }
462
+ return Math.abs(hash).toString(16).padStart(8, '0');
463
+ }
464
+
465
+ // Helper: Add witness entry
466
+ function addWitnessEntry(action: string, data: unknown): string {
467
+ const entry = {
468
+ hash: '',
469
+ prev_hash: lastWitnessHash,
470
+ action,
471
+ data,
472
+ timestamp: Date.now(),
473
+ };
474
+ entry.hash = simpleHash(JSON.stringify(entry));
475
+ witnessChain.push(entry);
476
+ lastWitnessHash = entry.hash;
477
+ return entry.hash;
478
+ }
479
+
480
+ class MockWasmMcpServer implements WasmMcpServer {
481
+ handle_message(message: string): string {
482
+ const request = JSON.parse(message);
483
+ const { method, params, id } = request;
484
+
485
+ const response = {
486
+ jsonrpc: "2.0",
487
+ id,
488
+ result: null as unknown,
489
+ error: undefined as { code: number; message: string } | undefined,
490
+ };
491
+
492
+ switch (method) {
493
+ case "initialize":
494
+ response.result = {
495
+ protocolVersion: "2024-11-05",
496
+ serverInfo: { name: "rvagent-wasm", version: "2.0.0" },
497
+ capabilities: {
498
+ tools: { listChanged: true },
499
+ prompts: { listChanged: true },
500
+ resources: {},
501
+ },
502
+ };
503
+ break;
504
+
505
+ case "tools/list":
506
+ response.result = {
507
+ tools: [
508
+ // === SYSTEM GUIDANCE (1) - CALL THIS FIRST ===
509
+ {
510
+ name: "system_guidance",
511
+ description: `🔮 CALL FIRST: Get help on ALL available tools. Examples: {} for full guide, {"tool": "read_file"} for specific tool, {"category": "memory"} for category.`,
512
+ inputSchema: {
513
+ type: "object",
514
+ properties: {
515
+ tool: { type: "string", description: "Get help for specific tool name" },
516
+ category: { type: "string", description: "Filter by: files, memory, tasks, gallery, witness, brain, search" }
517
+ }
518
+ }
519
+ },
520
+ // === FILE OPERATIONS (5) ===
521
+ {
522
+ name: "read_file",
523
+ description: `Read file contents. REQUIRED: path (string). Example: {"path": "src/index.ts"}`,
524
+ inputSchema: {
525
+ type: "object",
526
+ properties: { path: { type: "string", description: "File path (REQUIRED) - e.g., 'src/index.ts'" } },
527
+ required: ["path"]
528
+ }
529
+ },
530
+ {
531
+ name: "write_file",
532
+ description: `Create or overwrite a file. REQUIRED: path, content. Example: {"path": "hello.txt", "content": "Hello World"}`,
533
+ inputSchema: {
534
+ type: "object",
535
+ properties: {
536
+ path: { type: "string", description: "File path (REQUIRED) - e.g., 'src/new-file.ts'" },
537
+ content: { type: "string", description: "Content to write (REQUIRED)" }
538
+ },
539
+ required: ["path", "content"]
540
+ }
541
+ },
542
+ {
543
+ name: "list_files",
544
+ description: `List all files in the virtual filesystem. No parameters needed. Returns file paths.`,
545
+ inputSchema: { type: "object", properties: {} }
546
+ },
547
+ {
548
+ name: "delete_file",
549
+ description: `Delete a file. REQUIRED: path. Example: {"path": "temp.txt"}`,
550
+ inputSchema: {
551
+ type: "object",
552
+ properties: { path: { type: "string", description: "File path to delete (REQUIRED)" } },
553
+ required: ["path"]
554
+ }
555
+ },
556
+ {
557
+ name: "edit_file",
558
+ description: `Replace text in a file. REQUIRED: path, old_content, new_content. Example: {"path": "src/index.ts", "old_content": "const x = 1", "new_content": "const x = 2"}`,
559
+ inputSchema: {
560
+ type: "object",
561
+ properties: {
562
+ path: { type: "string", description: "File path (REQUIRED)" },
563
+ old_content: { type: "string", description: "Text to find (REQUIRED) - must match exactly" },
564
+ new_content: { type: "string", description: "Replacement text (REQUIRED)" }
565
+ },
566
+ required: ["path", "old_content", "new_content"]
567
+ }
568
+ },
569
+ // === SEARCH TOOLS (2) ===
570
+ {
571
+ name: "grep",
572
+ description: `Search for regex patterns. REQUIRED: pattern. OPTIONAL: path. Example: {"pattern": "function.*export", "path": "src/utils.ts"}`,
573
+ inputSchema: {
574
+ type: "object",
575
+ properties: {
576
+ pattern: { type: "string", description: "Regex pattern (REQUIRED) - e.g., 'TODO|FIXME'" },
577
+ path: { type: "string", description: "Limit search to file (optional)" }
578
+ },
579
+ required: ["pattern"]
580
+ }
581
+ },
582
+ {
583
+ name: "glob",
584
+ description: `Find files by pattern. REQUIRED: pattern. Examples: {"pattern": "*.ts"}, {"pattern": "src/**/*.tsx"}`,
585
+ inputSchema: {
586
+ type: "object",
587
+ properties: { pattern: { type: "string", description: "Glob pattern (REQUIRED) - e.g., '*.ts', 'src/**/*.js'" } },
588
+ required: ["pattern"]
589
+ }
590
+ },
591
+ // === TASK MANAGEMENT (3) ===
592
+ {
593
+ name: "todo_add",
594
+ description: `Add a task. REQUIRED: task. Example: {"task": "Fix login bug"}`,
595
+ inputSchema: {
596
+ type: "object",
597
+ properties: { task: { type: "string", description: "Task description (REQUIRED)" } },
598
+ required: ["task"]
599
+ }
600
+ },
601
+ {
602
+ name: "todo_list",
603
+ description: `List all tasks with status (○ pending, ✓ complete). No parameters needed.`,
604
+ inputSchema: { type: "object", properties: {} }
605
+ },
606
+ {
607
+ name: "todo_complete",
608
+ description: `Mark task complete. REQUIRED: id. Example: {"id": "todo-1"}`,
609
+ inputSchema: {
610
+ type: "object",
611
+ properties: { id: { type: "string", description: "Task ID (REQUIRED) - e.g., 'todo-1'" } },
612
+ required: ["id"]
613
+ }
614
+ },
615
+ // === MEMORY TOOLS (2) ===
616
+ {
617
+ name: "memory_store",
618
+ description: `Store data in semantic memory. REQUIRED: key, value. OPTIONAL: tags. Example: {"key": "auth-pattern", "value": "JWT with refresh tokens", "tags": ["security", "patterns"]}`,
619
+ inputSchema: {
620
+ type: "object",
621
+ properties: {
622
+ key: { type: "string", description: "Unique key (REQUIRED)" },
623
+ value: { type: "string", description: "Value to store (REQUIRED)" },
624
+ tags: { type: "array", items: { type: "string" }, description: "Tags for filtering (optional)" }
625
+ },
626
+ required: ["key", "value"]
627
+ }
628
+ },
629
+ {
630
+ name: "memory_search",
631
+ description: `Search stored memories. REQUIRED: query. OPTIONAL: top_k. Example: {"query": "authentication", "top_k": 5}`,
632
+ inputSchema: {
633
+ type: "object",
634
+ properties: {
635
+ query: { type: "string", description: "Search query (REQUIRED)" },
636
+ top_k: { type: "number", description: "Max results (default: 5)" }
637
+ },
638
+ required: ["query"]
639
+ }
640
+ },
641
+ // === AUDIT TOOLS (2) ===
642
+ {
643
+ name: "witness_log",
644
+ description: `Log action to immutable audit chain. REQUIRED: action. OPTIONAL: data. Example: {"action": "file_modified", "data": {"path": "config.json"}}`,
645
+ inputSchema: {
646
+ type: "object",
647
+ properties: {
648
+ action: { type: "string", description: "Action name (REQUIRED) - e.g., 'file_created', 'deploy_started'" },
649
+ data: { type: "object", description: "Additional context (optional)" }
650
+ },
651
+ required: ["action"]
652
+ }
653
+ },
654
+ {
655
+ name: "witness_verify",
656
+ description: `Verify audit chain integrity. No parameters. Returns VALID/INVALID with entry count.`,
657
+ inputSchema: { type: "object", properties: {} }
658
+ },
659
+ // === RVF GALLERY (3) ===
660
+ {
661
+ name: "gallery_list",
662
+ description: `List agent templates. OPTIONAL: category. Examples: {"category": "development"}, {} for all templates`,
663
+ inputSchema: {
664
+ type: "object",
665
+ properties: { category: { type: "string", description: "Filter by category (optional) - development, research, security, etc." } }
666
+ }
667
+ },
668
+ {
669
+ name: "gallery_load",
670
+ description: `Load a template. REQUIRED: id. Example: {"id": "development-agent"}`,
671
+ inputSchema: {
672
+ type: "object",
673
+ properties: { id: { type: "string", description: "Template ID (REQUIRED) - e.g., 'development-agent', 'security-agent'" } },
674
+ required: ["id"]
675
+ }
676
+ },
677
+ {
678
+ name: "gallery_search",
679
+ description: `Search templates by name, description, or tags. REQUIRED: query. Example: {"query": "security"}`,
680
+ inputSchema: {
681
+ type: "object",
682
+ properties: { query: { type: "string", description: "Search query (REQUIRED)" } },
683
+ required: ["query"]
684
+ }
685
+ },
686
+ ],
687
+ };
688
+ break;
689
+
690
+ case "tools/call": {
691
+ const { name, arguments: args } = params;
692
+ // Log to witness chain for audit
693
+ addWitnessEntry(`tool_call:${name}`, { args: args || {} });
694
+
695
+ switch (name) {
696
+ case "system_guidance": {
697
+ const toolDocs: Record<string, { cat: string; desc: string; ex: string }> = {
698
+ // --- Help ---
699
+ system_guidance: { cat: "help", desc: "Get help on all available tools, a specific tool, or a category", ex: '{} or {"tool": "brain_search"} or {"category": "brain"}' },
700
+ // --- Files (local virtual filesystem in browser) ---
701
+ read_file: { cat: "files", desc: "Read a file from the virtual filesystem. REQUIRED: path", ex: '{"path": "src/index.ts"}' },
702
+ write_file: { cat: "files", desc: "Create or overwrite a file. REQUIRED: path, content", ex: '{"path": "hello.txt", "content": "Hello World"}' },
703
+ list_files: { cat: "files", desc: "List all files stored in the virtual filesystem", ex: "{}" },
704
+ delete_file: { cat: "files", desc: "Delete a file. REQUIRED: path", ex: '{"path": "temp.txt"}' },
705
+ edit_file: { cat: "files", desc: "Find-and-replace text in a file. REQUIRED: path, old_content, new_content", ex: '{"path": "app.ts", "old_content": "const x = 1", "new_content": "const x = 2"}' },
706
+ grep: { cat: "files", desc: "Search file contents with regex. REQUIRED: pattern. OPTIONAL: path (limit to one file)", ex: '{"pattern": "TODO|FIXME"}' },
707
+ glob: { cat: "files", desc: "Find files by glob pattern. REQUIRED: pattern", ex: '{"pattern": "src/**/*.tsx"}' },
708
+ // --- Memory (persistent key-value with semantic search) ---
709
+ memory_store: { cat: "memory", desc: "Store a value in persistent memory with optional tags. REQUIRED: key, value. OPTIONAL: tags[]", ex: '{"key": "auth-pattern", "value": "JWT with refresh tokens", "tags": ["security"]}' },
710
+ memory_search: { cat: "memory", desc: "Semantic search across stored memories. REQUIRED: query. OPTIONAL: top_k (default 5)", ex: '{"query": "authentication", "top_k": 3}' },
711
+ // --- Tasks ---
712
+ todo_add: { cat: "tasks", desc: "Add a new task. REQUIRED: task (description string)", ex: '{"task": "Fix login redirect bug"}' },
713
+ todo_list: { cat: "tasks", desc: "List all tasks with status indicators", ex: "{}" },
714
+ todo_complete: { cat: "tasks", desc: "Mark a task as complete. REQUIRED: id", ex: '{"id": "todo-1"}' },
715
+ // --- Witness Chain (immutable audit log) ---
716
+ witness_log: { cat: "witness", desc: "Log an action to the immutable witness chain. REQUIRED: action. OPTIONAL: data", ex: '{"action": "file_modified", "data": {"path": "config.json"}}' },
717
+ witness_verify: { cat: "witness", desc: "Verify the integrity of the entire witness chain. Returns VALID/INVALID", ex: "{}" },
718
+ // --- Gallery (agent templates) ---
719
+ gallery_list: { cat: "gallery", desc: "List available agent templates. OPTIONAL: category", ex: '{"category": "development"}' },
720
+ gallery_load: { cat: "gallery", desc: "Load and activate an agent template. REQUIRED: id", ex: '{"id": "development-agent"}' },
721
+ gallery_search: { cat: "gallery", desc: "Search templates by keyword. REQUIRED: query", ex: '{"query": "security"}' },
722
+ // --- Brain (shared collective intelligence at pi.ruv.io, via pi-brain MCP) ---
723
+ brain_status: { cat: "brain", desc: "Check brain health: memory count, graph edges, clusters, embedding engine, drift status", ex: "{}" },
724
+ brain_search: { cat: "brain", desc: "Semantic search across 2,000+ shared memories. REQUIRED: query. OPTIONAL: limit, min_quality", ex: '{"query": "authentication patterns", "limit": 5}' },
725
+ brain_list: { cat: "brain", desc: "List recent memories. OPTIONAL: limit, category, min_quality", ex: '{"limit": 10, "category": "pattern"}' },
726
+ brain_share: { cat: "brain", desc: "Share a learning with the collective. REQUIRED: category, title, content. OPTIONAL: tags[]. Categories: architecture|pattern|solution|convention|security|performance|tooling|debug", ex: '{"category": "pattern", "title": "React auth hook", "content": "useAuth() with refresh token rotation", "tags": ["react", "auth"]}' },
727
+ brain_drift: { cat: "brain", desc: "Check knowledge drift across categories. Shows how knowledge is evolving over time", ex: "{}" },
728
+ brain_partition: { cat: "brain", desc: "Get MinCut knowledge clusters. Shows emergent topic groupings with coherence scores. Use compact=true (default) to avoid large responses", ex: '{"compact": true}' },
729
+ };
730
+
731
+ let text: string;
732
+ const reqTool = args?.tool?.toLowerCase();
733
+ const reqCat = args?.category?.toLowerCase();
734
+
735
+ if (reqTool && toolDocs[reqTool]) {
736
+ const d = toolDocs[reqTool];
737
+ text = `TOOL: ${reqTool}\nCategory: ${d.cat}\nDescription: ${d.desc}\nExample: ${reqTool}(${d.ex})`;
738
+ } else if (reqCat && reqCat !== "all") {
739
+ const filtered = Object.entries(toolDocs)
740
+ .filter(([, d]) => d.cat === reqCat)
741
+ .map(([n, d]) => ` ${n} — ${d.desc}\n Example: ${n}(${d.ex})`);
742
+ text = filtered.length > 0
743
+ ? `${reqCat.toUpperCase()} TOOLS:\n\n${filtered.join("\n\n")}`
744
+ : `No tools in category: ${reqCat}. Available categories: help, files, memory, tasks, witness, gallery, brain`;
745
+ } else {
746
+ const cats = ["brain", "files", "memory", "tasks", "gallery", "witness", "help"];
747
+ const sections = cats.map((c) => {
748
+ const items = Object.entries(toolDocs)
749
+ .filter(([, d]) => d.cat === c)
750
+ .map(([n, d]) => ` ${n} — ${d.desc}\n Ex: ${n}(${d.ex})`);
751
+ return items.length > 0 ? `${c.toUpperCase()} (${items.length}):\n${items.join("\n")}` : null;
752
+ }).filter(Boolean);
753
+ text = `SYSTEM GUIDANCE — AVAILABLE TOOLS\n\n` +
754
+ `You have two MCP servers:\n` +
755
+ ` 1. RVAgent Local (WASM) — files, memory, tasks, witness, gallery (runs in browser)\n` +
756
+ ` 2. pi-brain (mcp.pi.ruv.io) — shared collective intelligence with 2,000+ memories\n\n` +
757
+ `${sections.join("\n\n")}\n\n` +
758
+ `TIPS:\n` +
759
+ `• Brain tools (brain_*) connect to pi.ruv.io shared knowledge — search before implementing\n` +
760
+ `• Local tools (files, memory, tasks) operate in this browser sandbox\n` +
761
+ `• Always pass REQUIRED parameters in JSON format\n` +
762
+ `• Use witness_log to create audit trails for important actions`;
763
+ }
764
+ response.result = { content: [{ type: "text", text }] };
765
+ break;
766
+ }
767
+ case "read_file": {
768
+ const content = virtualFS.get(args.path);
769
+ if (content === undefined) {
770
+ response.result = { content: [{ type: "text", text: `Error: File not found: ${args.path}` }], isError: true };
771
+ } else {
772
+ response.result = { content: [{ type: "text", text: content }] };
773
+ }
774
+ break;
775
+ }
776
+ case "write_file": {
777
+ virtualFS.set(args.path, args.content);
778
+ response.result = { content: [{ type: "text", text: `Successfully wrote ${args.content.length} bytes to ${args.path}` }] };
779
+ break;
780
+ }
781
+ case "list_files": {
782
+ const files = [...virtualFS.keys()];
783
+ if (files.length === 0) {
784
+ response.result = { content: [{ type: "text", text: "No files in virtual filesystem" }] };
785
+ } else {
786
+ response.result = { content: [{ type: "text", text: `Files:\n${files.map(f => `- ${f}`).join('\n')}` }] };
787
+ }
788
+ break;
789
+ }
790
+ case "delete_file": {
791
+ if (!virtualFS.has(args.path)) {
792
+ response.result = { content: [{ type: "text", text: `Error: File not found: ${args.path}` }], isError: true };
793
+ } else {
794
+ virtualFS.delete(args.path);
795
+ response.result = { content: [{ type: "text", text: `Deleted: ${args.path}` }] };
796
+ }
797
+ break;
798
+ }
799
+ case "edit_file": {
800
+ const existing = virtualFS.get(args.path);
801
+ if (existing === undefined) {
802
+ response.result = { content: [{ type: "text", text: `Error: File not found: ${args.path}` }], isError: true };
803
+ } else if (!existing.includes(args.old_content)) {
804
+ response.result = { content: [{ type: "text", text: `Error: old_content not found in file` }], isError: true };
805
+ } else {
806
+ virtualFS.set(args.path, existing.replace(args.old_content, args.new_content));
807
+ response.result = { content: [{ type: "text", text: `Successfully edited ${args.path}` }] };
808
+ }
809
+ break;
810
+ }
811
+ case "grep": {
812
+ const pattern = new RegExp(args.pattern, 'gi');
813
+ const results: string[] = [];
814
+ for (const [path, content] of virtualFS.entries()) {
815
+ if (args.path && path !== args.path) continue;
816
+ const lines = content.split('\n');
817
+ lines.forEach((line, idx) => {
818
+ if (pattern.test(line)) {
819
+ results.push(`${path}:${idx + 1}: ${line}`);
820
+ }
821
+ });
822
+ }
823
+ response.result = { content: [{ type: "text", text: results.length > 0 ? results.join('\n') : 'No matches found' }] };
824
+ break;
825
+ }
826
+ case "glob": {
827
+ const globPattern = args.pattern.replace(/\*/g, '.*').replace(/\?/g, '.');
828
+ const regex = new RegExp(`^${globPattern}$`);
829
+ const matches = [...virtualFS.keys()].filter(f => regex.test(f));
830
+ response.result = { content: [{ type: "text", text: matches.length > 0 ? matches.join('\n') : 'No matches found' }] };
831
+ break;
832
+ }
833
+ case "todo_add": {
834
+ const id = `todo-${todoIdCounter++}`;
835
+ todoList.push({ id, task: args.task, completed: false, created: Date.now() });
836
+ response.result = { content: [{ type: "text", text: `Added task: ${args.task} (id: ${id})` }] };
837
+ break;
838
+ }
839
+ case "todo_list": {
840
+ if (todoList.length === 0) {
841
+ response.result = { content: [{ type: "text", text: "No tasks in todo list" }] };
842
+ } else {
843
+ const formatted = todoList.map(t =>
844
+ `${t.completed ? '✓' : '○'} [${t.id}] ${t.task}`
845
+ ).join('\n');
846
+ response.result = { content: [{ type: "text", text: `Tasks:\n${formatted}` }] };
847
+ }
848
+ break;
849
+ }
850
+ case "todo_complete": {
851
+ const todo = todoList.find(t => t.id === args.id);
852
+ if (!todo) {
853
+ response.result = { content: [{ type: "text", text: `Error: Task not found: ${args.id}` }], isError: true };
854
+ } else {
855
+ todo.completed = true;
856
+ response.result = { content: [{ type: "text", text: `Completed: ${todo.task}` }] };
857
+ }
858
+ break;
859
+ }
860
+ case "memory_store": {
861
+ memoryStore.set(args.key, { key: args.key, value: args.value, tags: args.tags || [] });
862
+ response.result = { content: [{ type: "text", text: `Stored memory: ${args.key}` }] };
863
+ break;
864
+ }
865
+ case "memory_search": {
866
+ const query = (args.query as string).toLowerCase();
867
+ const topK = args.top_k || 5;
868
+ const results = [...memoryStore.values()]
869
+ .filter(m => m.key.toLowerCase().includes(query) || m.value.toLowerCase().includes(query) || m.tags.some(t => t.toLowerCase().includes(query)))
870
+ .slice(0, topK)
871
+ .map(m => `[${m.key}] ${m.value.slice(0, 100)}${m.value.length > 100 ? '...' : ''}`);
872
+ response.result = { content: [{ type: "text", text: results.length > 0 ? `Found ${results.length} results:\n${results.join('\n')}` : 'No memories found' }] };
873
+ break;
874
+ }
875
+ case "witness_log": {
876
+ const hash = addWitnessEntry(args.action, args.data || {});
877
+ response.result = { content: [{ type: "text", text: `Logged to witness chain: ${args.action} (hash: ${hash})` }] };
878
+ break;
879
+ }
880
+ case "witness_verify": {
881
+ let valid = true;
882
+ let prevHash = "genesis";
883
+ for (const entry of witnessChain) {
884
+ if (entry.prev_hash !== prevHash) {
885
+ valid = false;
886
+ break;
887
+ }
888
+ prevHash = entry.hash;
889
+ }
890
+ response.result = { content: [{ type: "text", text: `Witness chain: ${valid ? 'VALID' : 'INVALID'} (${witnessChain.length} entries)` }] };
891
+ break;
892
+ }
893
+ case "gallery_list": {
894
+ const filtered = args.category
895
+ ? builtinTemplates.filter(t => t.category === args.category)
896
+ : builtinTemplates;
897
+ const list = filtered.map(t => `- ${t.id}: ${t.name} (${t.category})`).join('\n');
898
+ response.result = { content: [{ type: "text", text: `Gallery Templates:\n${list}` }] };
899
+ break;
900
+ }
901
+ case "gallery_load": {
902
+ const template = builtinTemplates.find(t => t.id === args.id);
903
+ if (!template) {
904
+ response.result = { content: [{ type: "text", text: `Error: Template not found: ${args.id}` }], isError: true };
905
+ } else {
906
+ activeTemplateId = args.id;
907
+ response.result = { content: [{ type: "text", text: `Loaded template: ${template.name}\nDescription: ${template.description}\nTools: ${template.tools?.map(t => t.name).join(', ') || 'none'}\nSkills: ${template.skills?.map(s => s.trigger).join(', ') || 'none'}` }] };
908
+ }
909
+ break;
910
+ }
911
+ case "gallery_search": {
912
+ const q = (args.query as string).toLowerCase();
913
+ const matches = builtinTemplates.filter(t =>
914
+ t.name.toLowerCase().includes(q) ||
915
+ t.description.toLowerCase().includes(q) ||
916
+ t.tags.some(tag => tag.toLowerCase().includes(q))
917
+ );
918
+ if (matches.length === 0) {
919
+ response.result = { content: [{ type: "text", text: "No templates found matching your query" }] };
920
+ } else {
921
+ const list = matches.map(t => `- ${t.id}: ${t.name}\n ${t.description}`).join('\n');
922
+ response.result = { content: [{ type: "text", text: `Found ${matches.length} templates:\n${list}` }] };
923
+ }
924
+ break;
925
+ }
926
+ default:
927
+ response.error = { code: -32601, message: `Unknown tool: ${name}` };
928
+ }
929
+ break;
930
+ }
931
+
932
+ case "prompts/list": {
933
+ // Return prompts from active template or all templates
934
+ const prompts = activeTemplateId
935
+ ? builtinTemplates.find(t => t.id === activeTemplateId)?.prompts || []
936
+ : builtinTemplates.flatMap(t => t.prompts || []);
937
+ response.result = { prompts: prompts.map(p => ({ name: p.name, description: `Prompt: ${p.name}` })) };
938
+ break;
939
+ }
940
+
941
+ case "prompts/get": {
942
+ const allPrompts = builtinTemplates.flatMap(t => t.prompts || []);
943
+ const prompt = allPrompts.find(p => p.name === params.name);
944
+ if (prompt) {
945
+ response.result = {
946
+ messages: [{ role: "assistant", content: { type: "text", text: prompt.system_prompt } }],
947
+ };
948
+ } else {
949
+ response.error = { code: -32602, message: `Prompt not found: ${params.name}` };
950
+ }
951
+ break;
952
+ }
953
+
954
+ case "gallery/list":
955
+ response.result = { templates: builtinTemplates };
956
+ break;
957
+
958
+ case "gallery/load": {
959
+ const template = builtinTemplates.find((t) => t.id === params.id);
960
+ if (template) {
961
+ activeTemplateId = params.id;
962
+ response.result = { template_id: template.id, name: template.name };
963
+ } else {
964
+ response.error = { code: -32602, message: `Template not found: ${params.id}` };
965
+ }
966
+ break;
967
+ }
968
+
969
+ case "gallery/search": {
970
+ const q = (params.query as string).toLowerCase();
971
+ const results = builtinTemplates
972
+ .filter(t => t.name.toLowerCase().includes(q) || t.description.toLowerCase().includes(q) || t.tags.some(tag => tag.toLowerCase().includes(q)))
973
+ .map(t => ({ id: t.id, name: t.name, description: t.description, category: t.category, tags: t.tags, relevance: t.name.toLowerCase().includes(q) ? 1.0 : 0.5 }));
974
+ response.result = { results };
975
+ break;
976
+ }
977
+
978
+ default:
979
+ response.error = { code: -32601, message: `Method not found: ${method}` };
980
+ }
981
+
982
+ return JSON.stringify(response);
983
+ }
984
+
985
+ gallery(): WasmGallery {
986
+ return new MockWasmGallery();
987
+ }
988
+ }
989
+
990
+ class MockWasmGallery implements WasmGallery {
991
+ list(): GalleryTemplate[] {
992
+ return builtinTemplates;
993
+ }
994
+
995
+ listByCategory(category: string): GalleryTemplate[] {
996
+ return builtinTemplates.filter((t) => t.category === category);
997
+ }
998
+
999
+ search(query: string): SearchResult[] {
1000
+ const q = query.toLowerCase();
1001
+ return builtinTemplates
1002
+ .filter((t) => t.name.toLowerCase().includes(q) || t.description.toLowerCase().includes(q) || t.tags.some((tag) => tag.toLowerCase().includes(q)))
1003
+ .map((t) => ({
1004
+ id: t.id,
1005
+ name: t.name,
1006
+ description: t.description,
1007
+ category: t.category,
1008
+ tags: t.tags,
1009
+ relevance: t.name.toLowerCase().includes(q) ? 1.0 : 0.5,
1010
+ }));
1011
+ }
1012
+
1013
+ get(id: string): GalleryTemplate {
1014
+ const template = builtinTemplates.find((t) => t.id === id);
1015
+ if (!template) throw new Error(`Template not found: ${id}`);
1016
+ return template;
1017
+ }
1018
+
1019
+ loadRvf(id: string): Uint8Array {
1020
+ const template = this.get(id);
1021
+ // Return mock RVF bytes (magic + version + minimal content)
1022
+ const encoder = new TextEncoder();
1023
+ const json = JSON.stringify(template);
1024
+ const jsonBytes = encoder.encode(json);
1025
+ const rvf = new Uint8Array(8 + jsonBytes.length);
1026
+ rvf.set([0x52, 0x56, 0x46, 0x00, 0x01, 0x00, 0x00, 0x00]); // RVF\0 + version
1027
+ rvf.set(jsonBytes, 8);
1028
+ return rvf;
1029
+ }
1030
+
1031
+ setActive(id: string): void {
1032
+ activeTemplateId = id;
1033
+ }
1034
+
1035
+ getActive(): string | null {
1036
+ return activeTemplateId;
1037
+ }
1038
+
1039
+ configure(_configJson: string): void {}
1040
+
1041
+ getConfig(): unknown {
1042
+ return {};
1043
+ }
1044
+
1045
+ addCustom(_templateJson: string): void {}
1046
+
1047
+ removeCustom(_id: string): void {}
1048
+
1049
+ getCategories(): Record<string, number> {
1050
+ const categories: Record<string, number> = {};
1051
+ builtinTemplates.forEach((t) => {
1052
+ categories[t.category] = (categories[t.category] || 0) + 1;
1053
+ });
1054
+ return categories;
1055
+ }
1056
+
1057
+ count(): number {
1058
+ return builtinTemplates.length;
1059
+ }
1060
+
1061
+ exportCustom(): GalleryTemplate[] {
1062
+ return [];
1063
+ }
1064
+
1065
+ importCustom(_templatesJson: string): number {
1066
+ return 0;
1067
+ }
1068
+ }
1069
+
1070
+ class MockWasmRvfBuilder implements WasmRvfBuilder {
1071
+ private tools: unknown[] = [];
1072
+ private prompts: unknown[] = [];
1073
+ private skills: unknown[] = [];
1074
+ private mcpTools: unknown[] = [];
1075
+ private capabilities: unknown[] = [];
1076
+ private orchestrator: unknown = null;
1077
+
1078
+ addTool(toolJson: string): void {
1079
+ this.tools.push(JSON.parse(toolJson));
1080
+ }
1081
+
1082
+ addTools(toolsJson: string): void {
1083
+ this.tools.push(...JSON.parse(toolsJson));
1084
+ }
1085
+
1086
+ addPrompt(promptJson: string): void {
1087
+ this.prompts.push(JSON.parse(promptJson));
1088
+ }
1089
+
1090
+ addPrompts(promptsJson: string): void {
1091
+ this.prompts.push(...JSON.parse(promptsJson));
1092
+ }
1093
+
1094
+ addSkill(skillJson: string): void {
1095
+ this.skills.push(JSON.parse(skillJson));
1096
+ }
1097
+
1098
+ addSkills(skillsJson: string): void {
1099
+ this.skills.push(...JSON.parse(skillsJson));
1100
+ }
1101
+
1102
+ addMcpTools(mcpToolsJson: string): void {
1103
+ this.mcpTools.push(...JSON.parse(mcpToolsJson));
1104
+ }
1105
+
1106
+ addCapabilities(capsJson: string): void {
1107
+ this.capabilities.push(...JSON.parse(capsJson));
1108
+ }
1109
+
1110
+ setOrchestrator(orchestratorJson: string): void {
1111
+ this.orchestrator = JSON.parse(orchestratorJson);
1112
+ }
1113
+
1114
+ build(): Uint8Array {
1115
+ const content = {
1116
+ tools: this.tools,
1117
+ prompts: this.prompts,
1118
+ skills: this.skills,
1119
+ mcp_tools: this.mcpTools,
1120
+ capabilities: this.capabilities,
1121
+ orchestrator: this.orchestrator,
1122
+ };
1123
+ const encoder = new TextEncoder();
1124
+ const json = JSON.stringify(content);
1125
+ const jsonBytes = encoder.encode(json);
1126
+ const rvf = new Uint8Array(8 + jsonBytes.length);
1127
+ rvf.set([0x52, 0x56, 0x46, 0x00, 0x01, 0x00, 0x00, 0x00]); // RVF\0 + version
1128
+ rvf.set(jsonBytes, 8);
1129
+ return rvf;
1130
+ }
1131
+ }
1132
+
1133
+ return {
1134
+ WasmMcpServer: MockWasmMcpServer as unknown as new () => WasmMcpServer,
1135
+ WasmGallery: MockWasmGallery as unknown as new () => WasmGallery,
1136
+ WasmRvfBuilder: MockWasmRvfBuilder as unknown as new () => WasmRvfBuilder,
1137
+ };
1138
+ }
1139
+
1140
+ /**
1141
+ * Load the WASM module
1142
+ */
1143
+ export async function loadWasm(): Promise<typeof wasmModule> {
1144
+ if (!browser) {
1145
+ return null;
1146
+ }
1147
+
1148
+ if (wasmModule) {
1149
+ return wasmModule;
1150
+ }
1151
+
1152
+ if (loadPromise) {
1153
+ return loadPromise;
1154
+ }
1155
+
1156
+ loadPromise = (async () => {
1157
+ try {
1158
+ // Check if WASM is already loaded globally (e.g., via script tag in index.html)
1159
+ // To use real WASM, add this to your index.html:
1160
+ // <script type="module">
1161
+ // import init, * as wasm from '/wasm/rvagent_wasm.js';
1162
+ // await init();
1163
+ // window.rvagent_wasm = wasm;
1164
+ // </script>
1165
+ if (typeof window !== "undefined" && (window as unknown as Record<string, unknown>).rvagent_wasm) {
1166
+ const wasm = (window as unknown as Record<string, unknown>).rvagent_wasm as {
1167
+ WasmMcpServer: new () => WasmMcpServer;
1168
+ WasmGallery: new () => WasmGallery;
1169
+ WasmRvfBuilder: new () => WasmRvfBuilder;
1170
+ };
1171
+
1172
+ wasmModule = {
1173
+ WasmMcpServer: wasm.WasmMcpServer,
1174
+ WasmGallery: wasm.WasmGallery,
1175
+ WasmRvfBuilder: wasm.WasmRvfBuilder,
1176
+ };
1177
+
1178
+ console.log("[WASM] rvagent-wasm loaded from global");
1179
+ return wasmModule;
1180
+ }
1181
+
1182
+ // Use mock module for development/testing
1183
+ // The mock provides full MCP functionality with an in-memory virtual filesystem
1184
+ console.log("[WASM] Using mock rvagent-wasm implementation");
1185
+ wasmModule = createMockWasmModule();
1186
+ return wasmModule;
1187
+ } catch (error) {
1188
+ console.error("[WASM] Failed to initialize:", error);
1189
+ loadPromise = null;
1190
+ wasmModule = createMockWasmModule();
1191
+ return wasmModule;
1192
+ }
1193
+ })();
1194
+
1195
+ return loadPromise;
1196
+ }
1197
+
1198
+ /**
1199
+ * Check if WASM is loaded
1200
+ */
1201
+ export function isWasmLoaded(): boolean {
1202
+ return wasmModule !== null;
1203
+ }
1204
+
1205
+ /**
1206
+ * Get the WASM module (throws if not loaded)
1207
+ */
1208
+ export function getWasm(): NonNullable<typeof wasmModule> {
1209
+ if (!wasmModule) {
1210
+ throw new Error("WASM module not loaded. Call loadWasm() first.");
1211
+ }
1212
+ return wasmModule;
1213
+ }