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.
- package/LICENSE +26 -667
- package/NOTICE +14 -33
- package/dist/activation.d.ts.map +1 -1
- package/dist/activation.js +1 -44
- package/dist/activation.js.map +1 -1
- package/dist/agent-daemon.js +4 -281
- package/dist/agent-loop.js +7 -332
- package/dist/analytics.js +13 -236
- package/dist/attribution.js +1 -49
- package/dist/audit.js +2 -457
- package/dist/auto-capture.js +3 -138
- package/dist/auto-orchestrator.js +1 -325
- package/dist/autoconfig.js +39 -840
- package/dist/buddy-runner.js +1 -109
- package/dist/buddy.js +14 -564
- package/dist/build-flags.js +1 -17
- package/dist/capabilities.js +3 -183
- package/dist/capture.js +1 -56
- package/dist/causality.js +6 -107
- package/dist/cli.js +20 -281
- package/dist/cloud/cli.js +5 -541
- package/dist/cloud/client.js +1 -221
- package/dist/cloud/crypto.js +1 -85
- package/dist/cloud/machine-id.js +2 -113
- package/dist/cloud/recovery.js +1 -60
- package/dist/cloud/sync-engine.js +7 -543
- package/dist/cloud-backup.js +5 -579
- package/dist/cloud-profile.js +1 -138
- package/dist/cloud-sync-entrypoint.js +1 -47
- package/dist/cloud-sync.js +2 -309
- package/dist/constellation.js +12 -168
- package/dist/context-build-budgeted.js +4 -144
- package/dist/context-ranking.js +1 -69
- package/dist/crypto.js +1 -179
- package/dist/daemon-write-endpoint.js +1 -290
- package/dist/daemon-writer.js +2 -406
- package/dist/database.js +43 -1110
- package/dist/deprecations.js +2 -162
- package/dist/design.js +13 -141
- package/dist/event-replication.js +1 -112
- package/dist/events-sse.js +7 -43
- package/dist/events.js +6 -238
- package/dist/failure-patterns.js +42 -659
- package/dist/federation.js +12 -236
- package/dist/goals.js +13 -101
- package/dist/golden.js +3 -355
- package/dist/handlers/agent.js +4 -165
- package/dist/handlers/alias-adapters.js +1 -129
- package/dist/handlers/aliases.js +1 -171
- package/dist/handlers/audit.js +1 -87
- package/dist/handlers/boundary.js +1 -221
- package/dist/handlers/capture.js +73 -1109
- package/dist/handlers/causality.js +7 -114
- package/dist/handlers/cloud.js +85 -382
- package/dist/handlers/companion.js +28 -459
- package/dist/handlers/datalake.js +7 -187
- package/dist/handlers/dispatch-context.js +0 -22
- package/dist/handlers/entity.js +25 -256
- package/dist/handlers/events.js +16 -335
- package/dist/handlers/failure.js +13 -340
- package/dist/handlers/goals.js +4 -296
- package/dist/handlers/intelligence.js +126 -674
- package/dist/handlers/invoicing.js +1 -70
- package/dist/handlers/mcpclient.js +6 -137
- package/dist/handlers/orchestration.js +40 -125
- package/dist/handlers/output-schemas.js +1 -24
- package/dist/handlers/presence.js +3 -99
- package/dist/handlers/project.js +28 -182
- package/dist/handlers/prompts.js +6 -157
- package/dist/handlers/quest.js +4 -224
- package/dist/handlers/recall.js +11 -218
- package/dist/handlers/registry.js +1 -167
- package/dist/handlers/resources.js +1 -288
- package/dist/handlers/review.js +11 -74
- package/dist/handlers/run.js +17 -487
- package/dist/handlers/search.js +15 -326
- package/dist/handlers/session.js +28 -615
- package/dist/handlers/share.js +8 -184
- package/dist/handlers/shims.js +1 -464
- package/dist/handlers/skill.js +67 -449
- package/dist/handlers/survivors.js +1 -120
- package/dist/handlers/symbols.js +8 -109
- package/dist/handlers/syncops.js +4 -302
- package/dist/handlers/types.js +1 -27
- package/dist/harvest.js +5 -191
- package/dist/hours.js +7 -156
- package/dist/http-auth.js +3 -321
- package/dist/http-fast.js +21 -1137
- package/dist/icons.js +1 -47
- package/dist/index.js +2 -924
- package/dist/indexer.js +4 -145
- package/dist/intelligence.js +31 -261
- package/dist/internal-dispatch.js +3 -212
- package/dist/keyset.js +1 -110
- package/dist/knowledge-graph.js +12 -176
- package/dist/license.d.ts +11 -0
- package/dist/license.d.ts.map +1 -1
- package/dist/license.js +2 -414
- package/dist/license.js.map +1 -1
- package/dist/logger.js +2 -199
- package/dist/maintenance.js +2 -148
- package/dist/mcp-client.js +6 -262
- package/dist/memory-artifacts.js +30 -449
- package/dist/migrate-prompt.js +2 -124
- package/dist/migrations.js +40 -655
- package/dist/performance.js +1 -228
- package/dist/presence.js +11 -140
- package/dist/priority-embed.js +5 -164
- package/dist/providers/embedding-provider.js +1 -196
- package/dist/readonly-gate.js +1 -29
- package/dist/rehydration.js +9 -157
- package/dist/reindex.js +1 -88
- package/dist/render-target.js +21 -514
- package/dist/render.js +4 -280
- package/dist/repl-guard.js +1 -173
- package/dist/replication-daemon-entrypoint.js +1 -31
- package/dist/replication-daemon.js +2 -262
- package/dist/resilience.js +1 -591
- package/dist/reverse-bridge.js +5 -360
- package/dist/security.js +1 -244
- package/dist/session-seen.js +3 -51
- package/dist/setup.js +1 -260
- package/dist/skill-author.js +5 -168
- package/dist/spec-kit.js +1 -191
- package/dist/sqlite-busy.js +1 -154
- package/dist/statusline.js +11 -315
- package/dist/sub-agent.js +13 -262
- package/dist/summarizer.js +13 -139
- package/dist/symbols.js +7 -283
- package/dist/sync.js +5 -359
- package/dist/tasks-dispatch.js +1 -84
- package/dist/tasks.js +1 -282
- package/dist/token-budget.js +1 -143
- package/dist/tool-analytics.js +7 -129
- package/dist/tool-annotations.js +1 -365
- package/dist/tool-manifest-v2.json +1 -1
- package/dist/tool-manifest.json +1 -1
- package/dist/tool-profiles.js +1 -75
- package/dist/trace-harvest.js +6 -244
- package/dist/types.js +1 -30
- package/dist/ui-dashboard.js +41 -50
- package/dist/ulid.js +1 -81
- package/dist/validate.js +1 -129
- package/dist/vault.js +1 -534
- package/dist/vectors.js +3 -184
- package/dist/version-check.js +4 -136
- package/dist/visibility.js +19 -155
- package/dist/wyrm-cli.js +98 -2451
- package/dist/wyrm-cli.js.map +1 -1
- package/dist/wyrm-guard.js +14 -424
- package/dist/wyrm-loop.js +3 -150
- package/dist/wyrm-manifest.json +1 -1
- package/dist/wyrm-statusline-daemon.js +1 -11
- package/dist/wyrm-statusline.js +4 -56
- package/dist/wyrm-ui.js +9 -77
- package/package.json +4 -2
package/dist/capabilities.js
CHANGED
|
@@ -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
|
-
|
|
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(
|
|
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(
|
|
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,
|
|
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(
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
//# sourceMappingURL=causality.js.map
|
|
23
|
+
`).all(e,d)}}export{g as Causality};
|