wyrm-mcp 7.2.0 → 7.2.2

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 (156) hide show
  1. package/LICENSE +26 -667
  2. package/NOTICE +14 -33
  3. package/dist/activation.d.ts.map +1 -1
  4. package/dist/activation.js +1 -44
  5. package/dist/activation.js.map +1 -1
  6. package/dist/agent-daemon.js +4 -281
  7. package/dist/agent-loop.js +7 -332
  8. package/dist/analytics.js +13 -236
  9. package/dist/attribution.js +1 -49
  10. package/dist/audit.js +2 -457
  11. package/dist/auto-capture.js +3 -138
  12. package/dist/auto-orchestrator.js +1 -325
  13. package/dist/autoconfig.js +39 -840
  14. package/dist/buddy-runner.js +1 -109
  15. package/dist/buddy.js +14 -564
  16. package/dist/build-flags.js +1 -17
  17. package/dist/capabilities.js +3 -183
  18. package/dist/capture.js +1 -56
  19. package/dist/causality.js +6 -107
  20. package/dist/cli.js +20 -281
  21. package/dist/cloud/cli.js +5 -541
  22. package/dist/cloud/client.js +1 -221
  23. package/dist/cloud/crypto.js +1 -85
  24. package/dist/cloud/machine-id.js +2 -113
  25. package/dist/cloud/recovery.js +1 -60
  26. package/dist/cloud/sync-engine.js +7 -543
  27. package/dist/cloud-backup.js +5 -579
  28. package/dist/cloud-profile.js +1 -138
  29. package/dist/cloud-sync-entrypoint.js +1 -47
  30. package/dist/cloud-sync.js +2 -309
  31. package/dist/constellation.js +12 -168
  32. package/dist/context-build-budgeted.js +4 -144
  33. package/dist/context-ranking.js +1 -69
  34. package/dist/crypto.js +1 -179
  35. package/dist/daemon-write-endpoint.js +1 -290
  36. package/dist/daemon-writer.js +2 -406
  37. package/dist/database.js +43 -1110
  38. package/dist/deprecations.js +2 -162
  39. package/dist/design.js +13 -141
  40. package/dist/event-replication.js +1 -112
  41. package/dist/events-sse.js +7 -43
  42. package/dist/events.js +6 -238
  43. package/dist/failure-patterns.js +42 -659
  44. package/dist/federation.js +12 -236
  45. package/dist/goals.js +13 -101
  46. package/dist/golden.js +3 -355
  47. package/dist/handlers/agent.js +4 -165
  48. package/dist/handlers/alias-adapters.js +1 -129
  49. package/dist/handlers/aliases.js +1 -171
  50. package/dist/handlers/audit.js +1 -87
  51. package/dist/handlers/boundary.js +1 -221
  52. package/dist/handlers/capture.js +73 -1109
  53. package/dist/handlers/causality.js +7 -114
  54. package/dist/handlers/cloud.js +85 -382
  55. package/dist/handlers/companion.js +28 -459
  56. package/dist/handlers/datalake.js +7 -187
  57. package/dist/handlers/dispatch-context.js +0 -22
  58. package/dist/handlers/entity.js +25 -256
  59. package/dist/handlers/events.js +16 -335
  60. package/dist/handlers/failure.js +13 -340
  61. package/dist/handlers/goals.js +4 -296
  62. package/dist/handlers/intelligence.js +126 -674
  63. package/dist/handlers/invoicing.js +1 -70
  64. package/dist/handlers/mcpclient.js +6 -137
  65. package/dist/handlers/orchestration.js +40 -125
  66. package/dist/handlers/output-schemas.js +1 -24
  67. package/dist/handlers/presence.js +3 -99
  68. package/dist/handlers/project.js +28 -182
  69. package/dist/handlers/prompts.js +6 -157
  70. package/dist/handlers/quest.js +4 -224
  71. package/dist/handlers/recall.js +11 -218
  72. package/dist/handlers/registry.js +1 -167
  73. package/dist/handlers/resources.js +1 -288
  74. package/dist/handlers/review.js +11 -74
  75. package/dist/handlers/run.js +17 -487
  76. package/dist/handlers/search.js +15 -326
  77. package/dist/handlers/session.js +28 -615
  78. package/dist/handlers/share.js +8 -184
  79. package/dist/handlers/shims.js +1 -464
  80. package/dist/handlers/skill.js +67 -449
  81. package/dist/handlers/survivors.js +1 -120
  82. package/dist/handlers/symbols.js +8 -109
  83. package/dist/handlers/syncops.js +4 -302
  84. package/dist/handlers/types.js +1 -27
  85. package/dist/harvest.js +5 -191
  86. package/dist/hours.js +7 -156
  87. package/dist/http-auth.js +3 -321
  88. package/dist/http-fast.js +21 -1137
  89. package/dist/icons.js +1 -47
  90. package/dist/index.js +2 -924
  91. package/dist/indexer.js +4 -145
  92. package/dist/intelligence.js +31 -261
  93. package/dist/internal-dispatch.js +3 -212
  94. package/dist/keyset.js +1 -110
  95. package/dist/knowledge-graph.js +12 -176
  96. package/dist/license.d.ts +11 -0
  97. package/dist/license.d.ts.map +1 -1
  98. package/dist/license.js +2 -414
  99. package/dist/license.js.map +1 -1
  100. package/dist/logger.js +2 -199
  101. package/dist/maintenance.js +2 -148
  102. package/dist/mcp-client.js +6 -262
  103. package/dist/memory-artifacts.js +30 -449
  104. package/dist/migrate-prompt.js +2 -124
  105. package/dist/migrations.js +40 -655
  106. package/dist/performance.js +1 -228
  107. package/dist/presence.js +11 -140
  108. package/dist/priority-embed.js +5 -164
  109. package/dist/providers/embedding-provider.js +1 -196
  110. package/dist/readonly-gate.js +1 -29
  111. package/dist/rehydration.js +9 -157
  112. package/dist/reindex.js +1 -88
  113. package/dist/render-target.js +21 -514
  114. package/dist/render.js +4 -280
  115. package/dist/repl-guard.js +1 -173
  116. package/dist/replication-daemon-entrypoint.js +1 -31
  117. package/dist/replication-daemon.js +2 -262
  118. package/dist/resilience.js +1 -591
  119. package/dist/reverse-bridge.js +5 -360
  120. package/dist/security.js +1 -244
  121. package/dist/session-seen.js +3 -51
  122. package/dist/setup.js +1 -260
  123. package/dist/skill-author.js +5 -168
  124. package/dist/spec-kit.js +1 -191
  125. package/dist/sqlite-busy.js +1 -154
  126. package/dist/statusline.js +11 -315
  127. package/dist/sub-agent.js +13 -262
  128. package/dist/summarizer.js +13 -139
  129. package/dist/symbols.js +7 -283
  130. package/dist/sync.js +5 -359
  131. package/dist/tasks-dispatch.js +1 -84
  132. package/dist/tasks.js +1 -282
  133. package/dist/token-budget.js +1 -143
  134. package/dist/tool-analytics.js +7 -129
  135. package/dist/tool-annotations.js +1 -365
  136. package/dist/tool-manifest-v2.json +1 -1
  137. package/dist/tool-manifest.json +1 -1
  138. package/dist/tool-profiles.js +1 -75
  139. package/dist/trace-harvest.js +6 -244
  140. package/dist/types.js +1 -30
  141. package/dist/ui-dashboard.js +41 -50
  142. package/dist/ulid.js +1 -81
  143. package/dist/validate.js +1 -129
  144. package/dist/vault.js +1 -534
  145. package/dist/vectors.js +3 -184
  146. package/dist/version-check.js +4 -136
  147. package/dist/visibility.js +19 -155
  148. package/dist/wyrm-cli.js +98 -2451
  149. package/dist/wyrm-cli.js.map +1 -1
  150. package/dist/wyrm-guard.js +14 -424
  151. package/dist/wyrm-loop.js +3 -150
  152. package/dist/wyrm-manifest.json +1 -1
  153. package/dist/wyrm-statusline-daemon.js +1 -11
  154. package/dist/wyrm-statusline.js +4 -56
  155. package/dist/wyrm-ui.js +9 -77
  156. package/package.json +4 -2
@@ -1,25 +1,4 @@
1
- /**
2
- * Capabilities self-description.
3
- *
4
- * Returns a structured pitch the AI can read at session start so it knows
5
- * exactly what Wyrm offers beyond "store and recall". The categories are
6
- * grouped by *what the operator gets*, not by table or module — the AI
7
- * should be able to read this once and immediately reach for the right
8
- * tool without re-discovering the surface.
9
- *
10
- * Also used as the body of the `wyrm_capabilities` MCP tool, the
11
- * `wyrm_inject_prompt` block, and the postinstall pitch.
12
- *
13
- * @copyright 2026 Ghost Protocol (Pvt) Ltd.
14
- * @license AGPL-3.0-or-later — dual-licensed; commercial terms: ghosts.lk@proton.me. See LICENSE.
15
- */
16
- import { homedir } from 'os';
17
- import { join, dirname } from 'path';
18
- import { readFileSync, existsSync } from 'fs';
19
- import { fileURLToPath } from 'url';
20
- const __filename = fileURLToPath(import.meta.url);
21
- const __dirname = dirname(__filename);
22
- const PITCH = `Wyrm is not "AI memory" in the file-write sense. It's a layered intelligence
1
+ import{homedir as n}from"os";import{join as o,dirname as l}from"path";import{readFileSync as c,existsSync as m}from"fs";import{fileURLToPath as y}from"url";const h=y(import.meta.url),a=l(h),d=`Wyrm is not "AI memory" in the file-write sense. It's a layered intelligence
23
2
  substrate that solves the four specific problems AI assistants share:
24
3
 
25
4
  1. Amnesia. Sessions inherit prior state via lossless rehydration.
@@ -32,164 +11,5 @@ substrate that solves the four specific problems AI assistants share:
32
11
  Every Wyrm session is local-first SQLite with FTS5 + hybrid semantic search.
33
12
  Encryption is operator-controlled. Federation is opt-in per row. The audit
34
13
  log is hash-chained and Ed25519-signable for SOC2/HIPAA scenarios. None of
35
- this requires you to leave your laptop.`;
36
- const FEATURES = [
37
- {
38
- name: 'Counter-pattern memory',
39
- what: 'Records failed approaches with (scope, target, description) and blocks the same suggestion next time.',
40
- why: 'Other memory tools learn only from success. Wyrm refuses to repeat mistakes — saves the most expensive class of tokens (the regenerated wrong answer).',
41
- tools: ['wyrm_failure_record', 'wyrm_failure_check', 'wyrm_failure_list', 'wyrm_failure_resolve'],
42
- },
43
- {
44
- name: 'Ground truths (versioned, cascade-aware)',
45
- what: 'Validated project facts (architecture, constraints, decisions) — each truth carries a version, last-verified timestamp, and outbound decision links.',
46
- why: 'Truths are injected first into every wyrm_context_build call so the AI never works from contradicted assumptions. When a truth changes, dependent decisions auto-invalidate.',
47
- tools: ['wyrm_truth_set', 'wyrm_truth_get', 'wyrm_decided_because', 'wyrm_decision_upstream', 'wyrm_decision_downstream', 'wyrm_decision_invalidate'],
48
- },
49
- {
50
- name: 'Reasoning scaffolds',
51
- what: 'Saved step-by-step checklists for problem types ("debug a slow query", "ship a migration") that surface automatically when a task description matches.',
52
- why: 'Replaces ad-hoc rediscovery of process knowledge with structured prompts. Cheaper than re-explaining the playbook every session.',
53
- tools: ['wyrm_scaffold_save', 'wyrm_scaffold_get'],
54
- },
55
- {
56
- name: 'Lossless session rehydration',
57
- what: 'wyrm_session_rehydrate produces a complete briefing markdown a fresh AI ingests to inherit prior state — decisions, open quests, failures, recent commits, files touched.',
58
- why: 'Cross-session continuity without re-exploration. The single biggest token-saver in the toolkit.',
59
- tools: ['wyrm_session_rehydrate', 'wyrm_session_prime', 'wyrm_session_start', 'wyrm_session_update'],
60
- },
61
- {
62
- name: 'Distillation queue',
63
- what: 'Candidate memory artifacts extracted from sessions land in a review queue; the operator approves or rejects each.',
64
- why: 'Bayesian confidence updates after each review — Wyrm gets sharper with use without auto-trusting noise.',
65
- tools: ['wyrm_distill', 'wyrm_review', 'wyrm_remember', 'wyrm_recall', 'wyrm_feedback'],
66
- },
67
- {
68
- name: 'Knowledge graph',
69
- what: 'Named entities + typed directional relationships, neighborhood traversal, shortest-path queries.',
70
- why: 'When the AI asks "how does X relate to Y?", Wyrm answers in O(log n) instead of grepping the corpus.',
71
- tools: ['wyrm_entity_add', 'wyrm_entity_link', 'wyrm_entity_search', 'wyrm_entity_graph', 'wyrm_entity_path', 'wyrm_entity_merge'],
72
- },
73
- {
74
- name: 'Cross-repo symbol index',
75
- what: 'Workspace-wide function/class/type index across TS/JS/Python/Rust/Go/PHP/Ruby with caller resolution.',
76
- why: 'Symbol lookups don\'t require re-grepping every project. "Who calls handleAuth?" answers immediately.',
77
- tools: ['wyrm_symbol_index', 'wyrm_symbol_search', 'wyrm_symbol_callers', 'wyrm_symbol_stats'],
78
- },
79
- {
80
- name: 'OODA agent loop (autonomous goals)',
81
- what: 'wyrm_goal_set persists an objective with success criteria. The wyrm-loop daemon runs Observe→Orient→Decide→Act every interval, dispatching whitelisted tools. Replayable, capped, auditable.',
82
- why: 'Lets you hand the AI a multi-step objective and walk away. No data-exfil tools accessible from inside the loop.',
83
- tools: ['wyrm_goal_set', 'wyrm_goal_list', 'wyrm_goal_pause', 'wyrm_goal_resume', 'wyrm_goal_complete', 'wyrm_goal_abandon', 'wyrm_goal_iterations', 'wyrm_act', 'wyrm_agent_init', 'wyrm_agent_status', 'wyrm_agent_stop', 'wyrm_agent_restart'],
84
- },
85
- {
86
- name: 'Outbound MCP client',
87
- what: 'Wyrm calls other MCP servers (GitHub, Slack, Linear, …) over stdio. The agent loop dispatches them like internal tools.',
88
- why: 'Composability: Wyrm becomes the orchestration layer over your entire MCP stack instead of a sibling.',
89
- tools: ['wyrm_mcp_register', 'wyrm_mcp_list', 'wyrm_mcp_disable', 'wyrm_mcp_tools', 'wyrm_call_external'],
90
- },
91
- {
92
- name: 'Hybrid semantic search',
93
- what: 'wyrm_search fuses FTS5 keyword candidates with vector candidates (Ollama nomic-embed-text by default; OpenAI optional) via Reciprocal Rank Fusion.',
94
- why: 'Catches both "exact term" and "semantically similar" hits in one call. Silently falls back to FTS5-only if Ollama isn\'t running.',
95
- tools: ['wyrm_search', 'wyrm_vector_setup'],
96
- },
97
- {
98
- name: 'Multi-agent presence + work-stealing',
99
- what: 'Claude, Copilot, Cursor, and Codex announce themselves via TTL heartbeats. Quests can be claimed exclusively.',
100
- why: 'No two agents step on the same quest. The work-stealing semantics scale to teams.',
101
- tools: ['wyrm_presence_announce', 'wyrm_presence_list', 'wyrm_presence_release', 'wyrm_quest_claim', 'wyrm_quest_release'],
102
- },
103
- {
104
- name: 'Federated team sync',
105
- what: 'Per-row is_shared flag, /sync/push endpoint, conflict-as-quest semantics. PII never leaves the box unless explicitly shared.',
106
- why: 'Team memory without a SaaS. No silent overwrites — every conflict becomes a quest the operator resolves.',
107
- tools: ['wyrm_share', 'wyrm_unshare', 'wyrm_sync', 'wyrm_sync_export', 'wyrm_sync_import', 'wyrm_sync_conflicts', 'wyrm_sync_resolve'],
108
- },
109
- {
110
- name: 'Compliance audit trail',
111
- what: 'Hash-chained audit log with optional Ed25519 signatures. wyrm_audit_export produces tamper-evident bundles.',
112
- why: 'SOC2/HIPAA reviewers get a real artifact. The hash chain detects any tampering after the fact.',
113
- tools: ['wyrm_audit_log', 'wyrm_audit_export', 'wyrm_audit_verify'],
114
- },
115
- {
116
- name: 'Hour ledger + invoice generation',
117
- what: 'Derives billable hours from session content and emits markdown invoices.',
118
- why: 'For solo operators and small teams: Wyrm is also the time tracker. No second tool to keep in sync.',
119
- tools: ['wyrm_hours_report', 'wyrm_invoice_generate', 'wyrm_cost_report'],
120
- },
121
- {
122
- name: 'Self-improvement analytics',
123
- what: 'Per-tool error rate, p50/p95 latency, cost-per-tool. Wyrm watches Wyrm.',
124
- why: 'Lets you spot which tools are hot, which are slow, which fail — input for both ops tuning and product decisions.',
125
- tools: ['wyrm_analytics_dashboard', 'wyrm_tool_analytics', 'wyrm_usage', 'wyrm_stats'],
126
- },
127
- ];
128
- function readPackageVersion() {
129
- try {
130
- // Resolve relative to this file. After tsc compile, this lives at
131
- // dist/capabilities.js, so package.json is one dir up.
132
- const candidates = [
133
- join(__dirname, '..', 'package.json'),
134
- join(__dirname, '..', '..', 'package.json'),
135
- ];
136
- for (const p of candidates) {
137
- if (existsSync(p)) {
138
- return JSON.parse(readFileSync(p, 'utf-8')).version ?? 'unknown';
139
- }
140
- }
141
- }
142
- catch {
143
- // fall through
144
- }
145
- return 'unknown';
146
- }
147
- export function getCapabilities(db, toolCount, probe) {
148
- void db; // reserved — future versions may surface runtime DB stats here
149
- const dbPath = process.env.WYRM_DB_PATH ?? join(homedir(), '.wyrm', 'wyrm.db');
150
- const agentState = probe.isAgentRunning();
151
- return {
152
- product: 'Wyrm',
153
- version: readPackageVersion(),
154
- pitch: PITCH,
155
- install: {
156
- dbPath,
157
- nodeVersion: process.version,
158
- platform: `${process.platform}-${process.arch}`,
159
- },
160
- runtime: {
161
- vectorProvider: probe.detectVectorProvider(),
162
- encryption: probe.hasEncryption(),
163
- federation: probe.isFederationEnabled(),
164
- agentLoop: agentState === null ? 'unknown' : agentState ? 'running' : 'stopped',
165
- },
166
- features: FEATURES,
167
- toolCount,
168
- };
169
- }
170
- /**
171
- * Render the capability report as a markdown briefing the AI can drop into a
172
- * session-prime answer or a user-facing reply. Keeps the structure stable so
173
- * the model can predict where to look.
174
- */
175
- export function renderCapabilityBriefing(report) {
176
- const lines = [];
177
- lines.push(`# 󱅝 ${report.product} ${report.version} — Capability Briefing`);
178
- lines.push('');
179
- lines.push(report.pitch);
180
- lines.push('');
181
- lines.push(`**Runtime:** ${report.toolCount} MCP tools · ${report.runtime.vectorProvider} embeddings · ${report.runtime.encryption ? 'encryption ON' : 'encryption off'} · agent ${report.runtime.agentLoop}`);
182
- lines.push(`**Install:** ${report.install.platform} · Node ${report.install.nodeVersion} · DB ${report.install.dbPath}`);
183
- lines.push('');
184
- lines.push('## What Wyrm gives you beyond "AI memory"');
185
- lines.push('');
186
- for (const f of report.features) {
187
- lines.push(`### ${f.name}`);
188
- lines.push(`- **What:** ${f.what}`);
189
- lines.push(`- **Why:** ${f.why}`);
190
- lines.push(`- **Tools:** \`${f.tools.join('`, `')}\``);
191
- lines.push('');
192
- }
193
- return lines.join('\n');
194
- }
195
- //# sourceMappingURL=capabilities.js.map
14
+ this requires you to leave your laptop.`,w=[{name:"Counter-pattern memory",what:"Records failed approaches with (scope, target, description) and blocks the same suggestion next time.",why:"Other memory tools learn only from success. Wyrm refuses to repeat mistakes \u2014 saves the most expensive class of tokens (the regenerated wrong answer).",tools:["wyrm_failure_record","wyrm_failure_check","wyrm_failure_list","wyrm_failure_resolve"]},{name:"Ground truths (versioned, cascade-aware)",what:"Validated project facts (architecture, constraints, decisions) \u2014 each truth carries a version, last-verified timestamp, and outbound decision links.",why:"Truths are injected first into every wyrm_context_build call so the AI never works from contradicted assumptions. When a truth changes, dependent decisions auto-invalidate.",tools:["wyrm_truth_set","wyrm_truth_get","wyrm_decided_because","wyrm_decision_upstream","wyrm_decision_downstream","wyrm_decision_invalidate"]},{name:"Reasoning scaffolds",what:'Saved step-by-step checklists for problem types ("debug a slow query", "ship a migration") that surface automatically when a task description matches.',why:"Replaces ad-hoc rediscovery of process knowledge with structured prompts. Cheaper than re-explaining the playbook every session.",tools:["wyrm_scaffold_save","wyrm_scaffold_get"]},{name:"Lossless session rehydration",what:"wyrm_session_rehydrate produces a complete briefing markdown a fresh AI ingests to inherit prior state \u2014 decisions, open quests, failures, recent commits, files touched.",why:"Cross-session continuity without re-exploration. The single biggest token-saver in the toolkit.",tools:["wyrm_session_rehydrate","wyrm_session_prime","wyrm_session_start","wyrm_session_update"]},{name:"Distillation queue",what:"Candidate memory artifacts extracted from sessions land in a review queue; the operator approves or rejects each.",why:"Bayesian confidence updates after each review \u2014 Wyrm gets sharper with use without auto-trusting noise.",tools:["wyrm_distill","wyrm_review","wyrm_remember","wyrm_recall","wyrm_feedback"]},{name:"Knowledge graph",what:"Named entities + typed directional relationships, neighborhood traversal, shortest-path queries.",why:'When the AI asks "how does X relate to Y?", Wyrm answers in O(log n) instead of grepping the corpus.',tools:["wyrm_entity_add","wyrm_entity_link","wyrm_entity_search","wyrm_entity_graph","wyrm_entity_path","wyrm_entity_merge"]},{name:"Cross-repo symbol index",what:"Workspace-wide function/class/type index across TS/JS/Python/Rust/Go/PHP/Ruby with caller resolution.",why:`Symbol lookups don't require re-grepping every project. "Who calls handleAuth?" answers immediately.`,tools:["wyrm_symbol_index","wyrm_symbol_search","wyrm_symbol_callers","wyrm_symbol_stats"]},{name:"OODA agent loop (autonomous goals)",what:"wyrm_goal_set persists an objective with success criteria. The wyrm-loop daemon runs Observe\u2192Orient\u2192Decide\u2192Act every interval, dispatching whitelisted tools. Replayable, capped, auditable.",why:"Lets you hand the AI a multi-step objective and walk away. No data-exfil tools accessible from inside the loop.",tools:["wyrm_goal_set","wyrm_goal_list","wyrm_goal_pause","wyrm_goal_resume","wyrm_goal_complete","wyrm_goal_abandon","wyrm_goal_iterations","wyrm_act","wyrm_agent_init","wyrm_agent_status","wyrm_agent_stop","wyrm_agent_restart"]},{name:"Outbound MCP client",what:"Wyrm calls other MCP servers (GitHub, Slack, Linear, \u2026) over stdio. The agent loop dispatches them like internal tools.",why:"Composability: Wyrm becomes the orchestration layer over your entire MCP stack instead of a sibling.",tools:["wyrm_mcp_register","wyrm_mcp_list","wyrm_mcp_disable","wyrm_mcp_tools","wyrm_call_external"]},{name:"Hybrid semantic search",what:"wyrm_search fuses FTS5 keyword candidates with vector candidates (Ollama nomic-embed-text by default; OpenAI optional) via Reciprocal Rank Fusion.",why:`Catches both "exact term" and "semantically similar" hits in one call. Silently falls back to FTS5-only if Ollama isn't running.`,tools:["wyrm_search","wyrm_vector_setup"]},{name:"Multi-agent presence + work-stealing",what:"Claude, Copilot, Cursor, and Codex announce themselves via TTL heartbeats. Quests can be claimed exclusively.",why:"No two agents step on the same quest. The work-stealing semantics scale to teams.",tools:["wyrm_presence_announce","wyrm_presence_list","wyrm_presence_release","wyrm_quest_claim","wyrm_quest_release"]},{name:"Federated team sync",what:"Per-row is_shared flag, /sync/push endpoint, conflict-as-quest semantics. PII never leaves the box unless explicitly shared.",why:"Team memory without a SaaS. No silent overwrites \u2014 every conflict becomes a quest the operator resolves.",tools:["wyrm_share","wyrm_unshare","wyrm_sync","wyrm_sync_export","wyrm_sync_import","wyrm_sync_conflicts","wyrm_sync_resolve"]},{name:"Compliance audit trail",what:"Hash-chained audit log with optional Ed25519 signatures. wyrm_audit_export produces tamper-evident bundles.",why:"SOC2/HIPAA reviewers get a real artifact. The hash chain detects any tampering after the fact.",tools:["wyrm_audit_log","wyrm_audit_export","wyrm_audit_verify"]},{name:"Hour ledger + invoice generation",what:"Derives billable hours from session content and emits markdown invoices.",why:"For solo operators and small teams: Wyrm is also the time tracker. No second tool to keep in sync.",tools:["wyrm_hours_report","wyrm_invoice_generate","wyrm_cost_report"]},{name:"Self-improvement analytics",what:"Per-tool error rate, p50/p95 latency, cost-per-tool. Wyrm watches Wyrm.",why:"Lets you spot which tools are hot, which are slow, which fail \u2014 input for both ops tuning and product decisions.",tools:["wyrm_analytics_dashboard","wyrm_tool_analytics","wyrm_usage","wyrm_stats"]}];function u(){try{const t=[o(a,"..","package.json"),o(a,"..","..","package.json")];for(const e of t)if(m(e))return JSON.parse(c(e,"utf-8")).version??"unknown"}catch{}return"unknown"}function v(t,e,s){const i=process.env.WYRM_DB_PATH??o(n(),".wyrm","wyrm.db"),r=s.isAgentRunning();return{product:"Wyrm",version:u(),pitch:d,install:{dbPath:i,nodeVersion:process.version,platform:`${process.platform}-${process.arch}`},runtime:{vectorProvider:s.detectVectorProvider(),encryption:s.hasEncryption(),federation:s.isFederationEnabled(),agentLoop:r===null?"unknown":r?"running":"stopped"},features:w,toolCount:e}}function b(t){const e=[];e.push(`# \u{F115D} ${t.product} ${t.version} \u2014 Capability Briefing`),e.push(""),e.push(t.pitch),e.push(""),e.push(`**Runtime:** ${t.toolCount} MCP tools \xB7 ${t.runtime.vectorProvider} embeddings \xB7 ${t.runtime.encryption?"encryption ON":"encryption off"} \xB7 agent ${t.runtime.agentLoop}`),e.push(`**Install:** ${t.install.platform} \xB7 Node ${t.install.nodeVersion} \xB7 DB ${t.install.dbPath}`),e.push(""),e.push('## What Wyrm gives you beyond "AI memory"'),e.push("");for(const s of t.features)e.push(`### ${s.name}`),e.push(`- **What:** ${s.what}`),e.push(`- **Why:** ${s.why}`),e.push(`- **Tools:** \`${s.tools.join("`, `")}\``),e.push("");return e.join(`
15
+ `)}export{v as getCapabilities,b as renderCapabilityBriefing};
package/dist/capture.js CHANGED
@@ -1,56 +1 @@
1
- /**
2
- * Wyrm Capture Helpers — Classification logic for unified auto-capture.
3
- *
4
- * @copyright 2026 Ghost Protocol (Pvt) Ltd.
5
- * @license AGPL-3.0-or-later — dual-licensed; commercial terms: ghosts.lk@proton.me. See LICENSE.
6
- */
7
- /**
8
- * Classify a piece of content into quest/truth/memory using heuristic patterns.
9
- * Patterns are applied in priority order; first match wins.
10
- */
11
- export function classifyCapture(content) {
12
- // Pattern 1: quest — action-oriented task starters
13
- if (/^(TODO|TASK|QUEST|implement|build|fix|add|create|refactor|migrate|update|remove)\b/i.test(content)) {
14
- return {
15
- type: 'quest',
16
- subtype: 'quest',
17
- confidence: 85,
18
- reasoning: 'Starts with action/task keyword -- classified as a quest',
19
- };
20
- }
21
- // Pattern 2: truth — architectural decisions / constraints
22
- if (/\b(always|never|must not|we use|we decided|architecture decision|constraint:|rule:|standard:)\b/i.test(content)) {
23
- return {
24
- type: 'truth',
25
- subtype: 'decision',
26
- confidence: 80,
27
- reasoning: 'Contains ground-truth / decision marker -- classified as truth',
28
- };
29
- }
30
- // Pattern 3: lesson — retrospective / root-cause learning
31
- if (/\b(learned|lesson|anti-pattern|mistake|bug was|root cause|turned out|retrospective)\b/i.test(content)) {
32
- return {
33
- type: 'memory',
34
- subtype: 'lesson',
35
- confidence: 80,
36
- reasoning: 'Contains lesson / retrospective marker -- classified as lesson',
37
- };
38
- }
39
- // Pattern 4: heuristic — guidelines / conditional rules
40
- if (/\b(when.*use|if.*then|prefer.*over|avoid|guideline|best practice)\b/i.test(content)) {
41
- return {
42
- type: 'memory',
43
- subtype: 'heuristic',
44
- confidence: 75,
45
- reasoning: 'Contains guideline / heuristic marker -- classified as heuristic',
46
- };
47
- }
48
- // Pattern 5: pattern — default fallback
49
- return {
50
- type: 'memory',
51
- subtype: 'pattern',
52
- confidence: 60,
53
- reasoning: 'No specific marker detected -- stored as general pattern',
54
- };
55
- }
56
- //# sourceMappingURL=capture.js.map
1
+ function t(e){return/^(TODO|TASK|QUEST|implement|build|fix|add|create|refactor|migrate|update|remove)\b/i.test(e)?{type:"quest",subtype:"quest",confidence:85,reasoning:"Starts with action/task keyword -- classified as a quest"}:/\b(always|never|must not|we use|we decided|architecture decision|constraint:|rule:|standard:)\b/i.test(e)?{type:"truth",subtype:"decision",confidence:80,reasoning:"Contains ground-truth / decision marker -- classified as truth"}:/\b(learned|lesson|anti-pattern|mistake|bug was|root cause|turned out|retrospective)\b/i.test(e)?{type:"memory",subtype:"lesson",confidence:80,reasoning:"Contains lesson / retrospective marker -- classified as lesson"}:/\b(when.*use|if.*then|prefer.*over|avoid|guideline|best practice)\b/i.test(e)?{type:"memory",subtype:"heuristic",confidence:75,reasoning:"Contains guideline / heuristic marker -- classified as heuristic"}:{type:"memory",subtype:"pattern",confidence:60,reasoning:"No specific marker detected -- stored as general pattern"}}export{t as classifyCapture};
package/dist/causality.js CHANGED
@@ -1,124 +1,23 @@
1
- /**
2
- * Causality — decision chains + downstream invalidation.
3
- *
4
- * "We chose Postgres because Y" → "Y turned out to be wrong" → flag every
5
- * downstream decision built on Y for re-evaluation.
6
- *
7
- * Edges link a `(kind, id)` pair to another `(kind, id)` pair with a
8
- * relation (`because_of`, `supersedes`, `refutes`, `verifies`). When a
9
- * ground truth flips to stale or gets superseded, the invalidation
10
- * cascade walks the edge graph and flags downstream decisions.
11
- *
12
- * @copyright 2026 Ghost Protocol (Pvt) Ltd.
13
- * @license AGPL-3.0-or-later — dual-licensed; commercial terms: ghosts.lk@proton.me. See LICENSE.
14
- */
15
- import { emitEvent } from './events.js';
16
- import { getActor } from './handlers/boundary.js';
17
- export class Causality {
18
- db;
19
- constructor(db) {
20
- this.db = db;
21
- }
22
- /** Record that `from` was decided BECAUSE OF `to` (or other relation). */
23
- link(input) {
24
- // v7 F2 (T009): stamp the writing actor (NULL outside a fleet context).
25
- const ambient = getActor();
26
- const info = this.db.prepare(`
1
+ import{emitEvent as l}from"./events.js";import{getActor as f}from"./handlers/boundary.js";class g{db;constructor(e){this.db=e}link(e){const d=f(),s=this.db.prepare(`
27
2
  INSERT INTO decision_edges
28
3
  (project_id, from_kind, from_id, to_kind, to_id, relation, rationale, confidence, agent_id, run_id)
29
4
  VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
30
- `).run(input.project_id, input.from_kind, input.from_id, input.to_kind, input.to_id, input.relation ?? 'because_of', input.rationale ?? null, input.confidence ?? 1.0, ambient.agent_id, ambient.run_id);
31
- const edge = this.get(info.lastInsertRowid);
32
- emitEvent(this.db, {
33
- projectId: input.project_id, kind: 'decision', refTable: 'decision_edges', refId: edge.id,
34
- isShared: !!edge.is_shared,
35
- });
36
- return edge;
37
- }
38
- get(id) {
39
- return this.db.prepare('SELECT * FROM decision_edges WHERE id = ?').get(id) ?? null;
40
- }
41
- /** All decisions that depend on the given source (outgoing edges from source). */
42
- downstreamOf(kind, id) {
43
- return this.db.prepare(`
5
+ `).run(e.project_id,e.from_kind,e.from_id,e.to_kind,e.to_id,e.relation??"because_of",e.rationale??null,e.confidence??1,d.agent_id,d.run_id),i=this.get(s.lastInsertRowid);return l(this.db,{projectId:e.project_id,kind:"decision",refTable:"decision_edges",refId:i.id,isShared:!!i.is_shared}),i}get(e){return this.db.prepare("SELECT * FROM decision_edges WHERE id = ?").get(e)??null}downstreamOf(e,d){return this.db.prepare(`
44
6
  SELECT * FROM decision_edges
45
7
  WHERE to_kind = ? AND to_id = ? AND invalidated_at IS NULL
46
8
  ORDER BY created_at DESC
47
- `).all(kind, id);
48
- }
49
- /** All sources that the given decision was based on (incoming edges to decision). */
50
- upstreamOf(kind, id) {
51
- return this.db.prepare(`
9
+ `).all(e,d)}upstreamOf(e,d){return this.db.prepare(`
52
10
  SELECT * FROM decision_edges
53
11
  WHERE from_kind = ? AND from_id = ? AND invalidated_at IS NULL
54
12
  ORDER BY created_at DESC
55
- `).all(kind, id);
56
- }
57
- /** Walk downstream from a source, depth-first, marking dependent decisions.
58
- * Returns the set of (kind, id) pairs affected. Idempotent — already-
59
- * invalidated edges are skipped. */
60
- invalidateDownstream(kind, id, reason) {
61
- const affected = [];
62
- const seen = new Set();
63
- const queue = [{ kind, id }];
64
- const markEdge = this.db.prepare(`
13
+ `).all(e,d)}invalidateDownstream(e,d,s){const i=[],r=new Set,t=[{kind:e,id:d}],c=this.db.prepare(`
65
14
  UPDATE decision_edges
66
15
  SET invalidated_at = datetime('now'),
67
16
  rationale = COALESCE(?, rationale)
68
17
  WHERE id = ?
69
- `);
70
- while (queue.length > 0) {
71
- const node = queue.shift();
72
- const key = `${node.kind}:${node.id}`;
73
- if (seen.has(key))
74
- continue;
75
- seen.add(key);
76
- const edges = this.downstreamOf(node.kind, node.id);
77
- for (const edge of edges) {
78
- markEdge.run(reason ?? null, edge.id);
79
- affected.push({
80
- kind: edge.from_kind,
81
- id: edge.from_id,
82
- edge_id: edge.id,
83
- rationale: edge.rationale,
84
- });
85
- queue.push({ kind: edge.from_kind, id: edge.from_id });
86
- }
87
- }
88
- return { invalidated: affected.length, affected };
89
- }
90
- /** Path query: list edges forming the decision chain from `from` back to `to`,
91
- * walking upstream up to maxDepth. Returns empty if no path. */
92
- pathTo(from, to, maxDepth = 6) {
93
- const visited = new Set();
94
- const stack = [
95
- { node: from, path: [] },
96
- ];
97
- while (stack.length > 0) {
98
- const { node, path } = stack.pop();
99
- const key = `${node.kind}:${node.id}`;
100
- if (visited.has(key) || path.length > maxDepth)
101
- continue;
102
- visited.add(key);
103
- if (node.kind === to.kind && node.id === to.id)
104
- return path;
105
- for (const edge of this.upstreamOf(node.kind, node.id)) {
106
- stack.push({
107
- node: { kind: edge.to_kind, id: edge.to_id },
108
- path: [...path, edge],
109
- });
110
- }
111
- }
112
- return [];
113
- }
114
- /** List all currently-invalidated edges that touch a project. */
115
- invalidatedInProject(projectId, limit = 50) {
116
- return this.db.prepare(`
18
+ `);for(;t.length>0;){const n=t.shift(),a=`${n.kind}:${n.id}`;if(r.has(a))continue;r.add(a);const _=this.downstreamOf(n.kind,n.id);for(const o of _)c.run(s??null,o.id),i.push({kind:o.from_kind,id:o.from_id,edge_id:o.id,rationale:o.rationale}),t.push({kind:o.from_kind,id:o.from_id})}return{invalidated:i.length,affected:i}}pathTo(e,d,s=6){const i=new Set,r=[{node:e,path:[]}];for(;r.length>0;){const{node:t,path:c}=r.pop(),n=`${t.kind}:${t.id}`;if(!(i.has(n)||c.length>s)){if(i.add(n),t.kind===d.kind&&t.id===d.id)return c;for(const a of this.upstreamOf(t.kind,t.id))r.push({node:{kind:a.to_kind,id:a.to_id},path:[...c,a]})}}return[]}invalidatedInProject(e,d=50){return this.db.prepare(`
117
19
  SELECT * FROM decision_edges
118
20
  WHERE project_id = ? AND invalidated_at IS NOT NULL
119
21
  ORDER BY invalidated_at DESC
120
22
  LIMIT ?
121
- `).all(projectId, limit);
122
- }
123
- }
124
- //# sourceMappingURL=causality.js.map
23
+ `).all(e,d)}}export{g as Causality};