wyrm-mcp 8.5.8 → 8.6.1

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/README.md CHANGED
@@ -108,6 +108,16 @@ Claude (Code, desktop, web) · Cursor · GitHub Copilot · Windsurf · Codex, an
108
108
 
109
109
  Node.js 22 or newer. Optional: a local Ollama with `nomic-embed-text` for semantic recall without any hosted call.
110
110
 
111
+ ## Pricing
112
+
113
+ Wyrm is **free to use forever** — the local memory, the firewall, the recall, all of it. Paid plans add cloud sync across devices, encrypted snapshots, shared team memory, and support:
114
+
115
+ - **Pro** — $29/mo · cloud sync, encrypted snapshots, analytics, priority support
116
+ - **Team** — $199/mo · shared team memory, up to 25 seats, admin dashboard
117
+ - **Enterprise** — $499/mo · unlimited seats, SSO/SAML, custom SLA, on-premise option
118
+
119
+ Plans and self-serve checkout: **[account.ghosts.lk/pricing](https://account.ghosts.lk/pricing)**. Custom or on-premise, email [ryan@ghosts.lk](mailto:ryan@ghosts.lk).
120
+
111
121
  ## Community and feedback
112
122
 
113
123
  Wyrm sends no telemetry, so the way we learn what is working is you telling us.
@@ -1,4 +1,4 @@
1
- import{applyBudget as w,resolveBudget as v}from"./token-budget.js";import{autoSummaryPenalty as T,score as p}from"./context-ranking.js";function E(g){const{groundTruths:y,scaffoldLib:h,memory:b,toolAnalytics:$,sessionSeen:u,tokenEstimator:d,rankWeights:f}=g;return function(t){const o=v({callArg:t.maxTokens,envValue:process.env.WYRM_CONTEXT_TOKEN_BUDGET,clientName:null}),x=t.sessionId?u().getSeen(t.sessionId):new Set,a=y.formatForContext(t.project.id),r=d.count(a??"");let m=a??"",k=r;r>o*.5&&!t.strictBudget&&process.stderr.write(`[wyrm_context_build] ground truths consume ${r} of ${o}-token budget \u2014 body will be heavily elided. Pass strict_budget:true to elide truths too.
2
- `),t.strictBudget&&r>o*.5&&(m=(a??"").slice(0,o*2),k=d.count(m));const l=[],c=h.findBest(t.task,t.project.id);if(c){const e=h.formatForContext(c),s=c.scaffold.id;l.push({item:{kind:"scaffold",id:s,title:c.scaffold.problem_type,body:e},key:`scaffold:${s}`,inlineCost:d.count(e),stubCost:20,score:p({confidence:.9,relevance:.9,updatedAt:new Date().toISOString()},f)})}const B=b.recall(t.project.id,t.task,{limit:20,minConfidence:t.minConfidence??.2});for(const e of B){const s=e.artifact;if(t.kinds&&t.kinds.length>0&&!t.kinds.includes(s.kind))continue;const _=[`**${s.kind.toUpperCase()}** \xB7 ${s.problem}`,s.constraints?`Constraints: ${s.constraints}`:"",s.validated_fix?`Fix: ${s.validated_fix}`:"",s.why_it_worked?`Why: ${s.why_it_worked}`:""].filter(Boolean).join(`
3
- `);l.push({item:{kind:"memory",id:s.id,title:s.problem.slice(0,60),body:_},key:`memory:${s.id}`,inlineCost:d.count(_),stubCost:25,score:p({confidence:s.confidence,relevance:e.relevance_score,updatedAt:s.updated_at,sourcePenalty:T(s.problem)},f)})}const i=w(l,{budget:o,alreadySeen:x,reserved:t.strictBudget?0:k});t.sessionId&&(u().markBulk(t.sessionId,i.inline.map(e=>({id:e.id,kind:e.kind,mode:"inline"}))),u().markBulk(t.sessionId,i.elided.map(e=>({id:e.item.id,kind:e.item.kind,mode:"stub"}))));const n=[];n.push(`\u{F115D} **Context Brief** \u2014 "${t.task}"`),n.push(""),n.push("## Ground truths (stable preamble)"),n.push(""),n.push(m||"_no ground truths set for this project yet_"),n.push(""),n.push("## Task-relevant memory"),n.push("");for(const e of i.inline)n.push(`### [${e.kind}:${e.id}] ${e.title}`),n.push(e.body),n.push("");if(i.elided.length>0){n.push("## Elided to stubs"),n.push(""),n.push("_Below the budget cutoff or already seen this session. Recall with `wyrm_recall(id)`:_"),n.push("");for(const e of i.elided){const s=e.reason==="seen"?"shown earlier in session":`~${e.stubCost} tokens`;n.push(`- [${e.item.kind}:${e.item.id}] ${e.item.title} \xB7 ${s}`)}n.push("")}n.push("---"),n.push(`_Budget: ${i.tokensInline}/${o} tokens inline \xB7 ${i.elided.length} stub${i.elided.length===1?"":"s"} \xB7 estimator: ${d.source}_`);const C=n.join(`
4
- `);try{$.log({tool_name:"wyrm_context_build",project_id:t.project.id,args:{budget:o,items_total:l.length,items_inline:i.inline.length,items_elided:i.elided.length,tokens_inline:i.tokensInline,tokens_stubs:i.tokensStubs},success:!0,latency_ms:0})}catch{}return{content:[{type:"text",text:C}]}}}export{E as makeRunBudgetedContextBuild};
1
+ import{applyBudget as I,resolveBudget as S}from"./token-budget.js";import{autoSummaryPenalty as j,score as g}from"./context-ranking.js";function F(y){const{groundTruths:b,scaffoldLib:f,memory:$,toolAnalytics:x,sessionSeen:a,tokenEstimator:d,rankWeights:k,threadText:B}=y;return function(t){const o=S({callArg:t.maxTokens,envValue:process.env.WYRM_CONTEXT_TOKEN_BUDGET,clientName:null}),C=t.sessionId?a().getSeen(t.sessionId):new Set,r=(()=>{try{return B(t.project.id)}catch{return""}})(),w=r?d.count(r):0,h=b.formatForContext(t.project.id),l=d.count(h??"");let m=h??"",p=l;l>o*.5&&!t.strictBudget&&process.stderr.write(`[wyrm_context_build] ground truths consume ${l} of ${o}-token budget \u2014 body will be heavily elided. Pass strict_budget:true to elide truths too.
2
+ `),t.strictBudget&&l>o*.5&&(m=(h??"").slice(0,o*2),p=d.count(m));const u=[],c=f.findBest(t.task,t.project.id);if(c){const n=f.formatForContext(c),s=c.scaffold.id;u.push({item:{kind:"scaffold",id:s,title:c.scaffold.problem_type,body:n},key:`scaffold:${s}`,inlineCost:d.count(n),stubCost:20,score:g({confidence:.9,relevance:.9,updatedAt:new Date().toISOString()},k)})}const T=$.recall(t.project.id,t.task,{limit:20,minConfidence:t.minConfidence??.2,runId:t.runId??null});for(const n of T){const s=n.artifact;if(t.kinds&&t.kinds.length>0&&!t.kinds.includes(s.kind))continue;const _=[`**${s.kind.toUpperCase()}** \xB7 ${s.problem}`,s.constraints?`Constraints: ${s.constraints}`:"",s.validated_fix?`Fix: ${s.validated_fix}`:"",s.why_it_worked?`Why: ${s.why_it_worked}`:""].filter(Boolean).join(`
3
+ `);u.push({item:{kind:"memory",id:s.id,title:s.problem.slice(0,60),body:_},key:`memory:${s.id}`,inlineCost:d.count(_),stubCost:25,score:g({confidence:s.confidence,relevance:n.relevance_score,updatedAt:s.updated_at,sourcePenalty:j(s.problem)},k)})}const i=I(u,{budget:o,alreadySeen:C,reserved:(t.strictBudget?0:p)+w});t.sessionId&&(a().markBulk(t.sessionId,i.inline.map(n=>({id:n.id,kind:n.kind,mode:"inline"}))),a().markBulk(t.sessionId,i.elided.map(n=>({id:n.item.id,kind:n.item.kind,mode:"stub"}))));const e=[];e.push(`\u{F115D} **Context Brief** \u2014 "${t.task}"`),e.push(""),r&&(e.push("## Working thread"),e.push(""),e.push(r),e.push("")),e.push("## Ground truths (stable preamble)"),e.push(""),e.push(m||"_no ground truths set for this project yet_"),e.push(""),e.push("## Task-relevant memory"),e.push("");for(const n of i.inline)e.push(`### [${n.kind}:${n.id}] ${n.title}`),e.push(n.body),e.push("");if(i.elided.length>0){e.push("## Elided to stubs"),e.push(""),e.push("_Below the budget cutoff or already seen this session. Recall with `wyrm_recall(id)`:_"),e.push("");for(const n of i.elided){const s=n.reason==="seen"?"shown earlier in session":`~${n.stubCost} tokens`;e.push(`- [${n.item.kind}:${n.item.id}] ${n.item.title} \xB7 ${s}`)}e.push("")}e.push("---"),e.push(`_Budget: ${i.tokensInline}/${o} tokens inline \xB7 ${i.elided.length} stub${i.elided.length===1?"":"s"} \xB7 estimator: ${d.source}_`);const v=e.join(`
4
+ `);try{x.log({tool_name:"wyrm_context_build",project_id:t.project.id,args:{budget:o,items_total:u.length,items_inline:i.inline.length,items_elided:i.elided.length,tokens_inline:i.tokensInline,tokens_stubs:i.tokensStubs},success:!0,latency_ms:0})}catch{}return{content:[{type:"text",text:v}]}}}export{F as makeRunBudgetedContextBuild};
package/dist/cors.js ADDED
@@ -0,0 +1 @@
1
+ const t={allowedOrigins:["http://localhost:3333","http://127.0.0.1:3333","http://localhost:3000"]};function i(l){t.allowedOrigins.includes(l)||t.allowedOrigins.push(l)}function o(){return t.allowedOrigins}export{t as CORS_CONFIG,i as addOrigin,o as getAllowedOrigins};
@@ -1,21 +1,21 @@
1
- import{readFileSync as L,statSync as m}from"node:fs";import{isAbsolute as j,relative as D,resolve as b,sep as A}from"node:path";import{sanitizeFtsQuery as M}from"./security.js";import{WyrmCrypto as w}from"./crypto.js";import{emitEvent as O,isLiveMemoryEnabled as U}from"./events.js";import{getActor as S,hasExplicitAttribution as k}from"./handlers/boundary.js";import{readActor as H,resolveAttribution as W}from"./attribution.js";import{normalizeContentSignature as I,containsFailedSignature as F}from"./content-signature.js";const $=new Set(["a","an","the","this","that","these","those","and","or","but","if","then","than","so","to","of","in","on","at","by","for","from","with","without","no","not","as","is","are","was","were","be","been","being","will","would","can","could","should","it","its","i","we","you","my","our","your","again","just","now","please","let","lets","do","does","did","into","over","about"]),C={run:0,project:1,global:2},B=8,Z="source changed since this failure was recorded \u2014 re-verify",v=200,q=5;function K(c){const e=n=>Object.entries(n).filter(([,r])=>r>0).map(([r,i])=>`${r} ${i}`).join(" \xB7 ")||"none",t=n=>n.map(r=>`${"who"in r?r.who:r.run_id} \xD7${r.count}`).join(" \xB7 ")||"none",o=c.blocked.this_run.run_id===null?"- This run: (no run identity \u2014 export WYRM_RUN_ID or pass run_id)":`- This run (${c.blocked.this_run.run_id}): ${c.blocked.this_run.blocked} repeat(s) blocked`;return`\u{F115D} **Failure Analytics** (${c.project_id===null?"all projects":`project #${c.project_id}`})
1
+ import{readFileSync as A,statSync as j}from"node:fs";import{isAbsolute as U,relative as k,resolve as b,sep as C}from"node:path";import{sanitizeFtsQuery as W}from"./security.js";import{WyrmCrypto as H}from"./crypto.js";import{emitEvent as O,isLiveMemoryEnabled as F}from"./events.js";import{getActor as R,hasExplicitAttribution as $}from"./handlers/boundary.js";import{readActor as B,resolveAttribution as v}from"./attribution.js";import{normalizeContentSignature as D,containsFailedSignature as q}from"./content-signature.js";const x=new Set(["a","an","the","this","that","these","those","and","or","but","if","then","than","so","to","of","in","on","at","by","for","from","with","without","no","not","as","is","are","was","were","be","been","being","will","would","can","could","should","it","its","i","we","you","my","our","your","again","just","now","please","let","lets","do","does","did","into","over","about"]),y={run:0,project:1,global:2},Y=8,ee="source changed since this failure was recorded \u2014 re-verify",N=200,T=5;function te(s){const e=r=>Object.entries(r).filter(([,n])=>n>0).map(([n,i])=>`${n} ${i}`).join(" \xB7 ")||"none",t=r=>r.map(n=>`${"who"in n?n.who:n.run_id} \xD7${n.count}`).join(" \xB7 ")||"none",o=s.blocked.this_run.run_id===null?"- This run: (no run identity \u2014 export WYRM_RUN_ID or pass run_id)":`- This run (${s.blocked.this_run.run_id}): ${s.blocked.this_run.blocked} repeat(s) blocked`;return`\u{F115D} **Failure Analytics** (${s.project_id===null?"all projects":`project #${s.project_id}`})
2
2
 
3
- **Recorded:** ${c.recorded.total} failure(s), ${c.recorded.unresolved} unresolved
4
- - By quarantine: ${e(c.recorded.by_quarantine_scope)}
5
- - By scope: ${e(c.recorded.by_scope)}
6
- - By agent: ${t(c.recorded.by_agent)}
7
- - By run: ${t(c.recorded.by_run)}
3
+ **Recorded:** ${s.recorded.total} failure(s), ${s.recorded.unresolved} unresolved
4
+ - By quarantine: ${e(s.recorded.by_quarantine_scope)}
5
+ - By scope: ${e(s.recorded.by_scope)}
6
+ - By agent: ${t(s.recorded.by_agent)}
7
+ - By run: ${t(s.recorded.by_run)}
8
8
 
9
- **Confirmations:** ${c.confirmations.total} from ${c.confirmations.distinct_agents} distinct agent(s)
9
+ **Confirmations:** ${s.confirmations.total} from ${s.confirmations.distinct_agents} distinct agent(s)
10
10
 
11
- **Repeats blocked:** ${c.blocked.total} total
11
+ **Repeats blocked:** ${s.blocked.total} total
12
12
  ${o}
13
- - By agent: ${t(c.blocked.by_agent)}
14
- - By run: ${t(c.blocked.by_run)}
15
- - Top blockers: ${c.blocked.top_blocked.map(n=>`#${n.failure_id} ${n.scope}:${n.target} \xD7${n.blocks}`).join(" \xB7 ")||"none"}`}function x(c,e){if(c==="exact")return 1;if(c==="target")return .95;const t=Math.max(0,-(e??0));return Number((.05+.85*(t/(t+2))).toFixed(4))}function N(c){return c.toLowerCase().replace(/\s+/g," ").trim()}function y(c){return N(c).slice(0,200)}class g{db;constructor(e){this.db=e}static signature(e,t,o){return`${e}:${y(t)}:${y(o).slice(0,80)}`}record(e){const t=g.signature(e.scope,e.target,e.description),o=e.project_id??null,n=e.content&&I(e.content)||null,r=S(),a=this.db.transaction(()=>{const s=this.db.prepare(`
13
+ - By agent: ${t(s.blocked.by_agent)}
14
+ - By run: ${t(s.blocked.by_run)}
15
+ - Top blockers: ${s.blocked.top_blocked.map(r=>`#${r.failure_id} ${r.scope}:${r.target} \xD7${r.blocks}`).join(" \xB7 ")||"none"}`}function z(s,e){if(s==="exact")return 1;if(s==="target")return .95;if(s==="canonical")return .9;if(s==="related")return .4;const t=Math.max(0,-(e??0));return Number((.05+.85*(t/(t+2))).toFixed(4))}function g(s){return s.toLowerCase().replace(/\s+/g," ").trim()}function M(s){return g(s).slice(0,200)}function L(s){const e=g(s).split(" ").filter(Boolean);let t=0;const o=[];for(;t<e.length&&!e[t].startsWith("-");)o.push(e[t]),t++;const r=[],n=[];for(;t<e.length;t++){const i=e[t];i.startsWith("-")?!i.includes("=")&&t+1<e.length&&!e[t+1].startsWith("-")?(n.push(`${i}=${e[t+1]}`),t++):n.push(i):r.push(i)}return n.sort(),[...o,...r,...n].join(" ")}function w(s){const e=g(s).split(" ").filter(Boolean),t=[];for(const o of e){if(o.startsWith("-"))break;t.push(o)}return t.length>=2?t.join(" "):""}class m{db;constructor(e){this.db=e}static signature(e,t,o){return`${e}:${M(t)}:${M(o).slice(0,80)}`}record(e){const t=m.signature(e.scope,e.target,e.description),o=e.project_id??null,r=e.content&&D(e.content)||null,n=e.scope==="command"&&L(e.target)||null,i=e.scope==="command"&&w(e.target)||null,a=R(),d=this.db.transaction(()=>{const u=this.db.prepare(`
16
16
  SELECT * FROM failure_patterns
17
17
  WHERE signature = ? AND (project_id IS ? OR project_id = ?)
18
- `).get(t,o,o);if(s)return this.db.prepare(`
18
+ `).get(t,o,o);if(u)return this.db.prepare(`
19
19
  UPDATE failure_patterns
20
20
  SET occurrences = occurrences + 1,
21
21
  last_seen = datetime('now'),
@@ -24,29 +24,29 @@ ${o}
24
24
  content_sig = COALESCE(?, content_sig),
25
25
  resolved = 0
26
26
  WHERE id = ?
27
- `).run(e.why_failed??null,e.severity??s.severity,n,s.id),this.noteConfirmation(s.id,r),this.get(s.id);const l=e.quarantine_scope??(r.run_id!==null?"run":o===null?"global":"project"),p=this.db.prepare(`
27
+ `).run(e.why_failed??null,e.severity??u.severity,r,u.id),this.noteConfirmation(u.id,a),this.get(u.id);const l=e.quarantine_scope??(a.run_id!==null?"run":o===null?"global":"project"),_=this.db.prepare(`
28
28
  INSERT INTO failure_patterns
29
- (project_id, signature, scope, target, description, why_failed, severity, agent_id, run_id, quarantine_scope, content_sig)
30
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
31
- `).run(o,t,e.scope,e.target,e.description,e.why_failed??null,e.severity??"medium",r.agent_id,r.run_id,l,n),u=this.get(p.lastInsertRowid);return this.noteConfirmation(u.id,r),u}).immediate();return O(this.db,{projectId:a.project_id??0,kind:"failure",refTable:"failure_patterns",refId:a.id}),a}contentMatch(e,t,o){const n=this.db.prepare(`
29
+ (project_id, signature, scope, target, description, why_failed, severity, agent_id, run_id, quarantine_scope, content_sig, canonical_target, command_head)
30
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
31
+ `).run(o,t,e.scope,e.target,e.description,e.why_failed??null,e.severity??"medium",a.agent_id,a.run_id,l,r,n,i),p=this.get(_.lastInsertRowid);return this.noteConfirmation(p.id,a),p}).immediate();return O(this.db,{projectId:d.project_id??0,kind:"failure",refTable:"failure_patterns",refId:d.id}),d}contentMatch(e,t,o){const r=this.db.prepare(`
32
32
  SELECT * FROM failure_patterns
33
33
  WHERE content_sig IS NOT NULL AND scope = ? AND resolved = 0
34
34
  AND (project_id IS ? OR project_id = ?)
35
35
  ORDER BY occurrences DESC, last_seen DESC
36
- `).all(t,o,o);for(const r of n)if(r.content_sig&&F(e,r.content_sig))return r;return null}get(e){return this.db.prepare("SELECT * FROM failure_patterns WHERE id = ?").get(e)??null}static anchorSha(e){return w.hash(I(e))}recordAnchors(e,t,o,n=!0){try{const r=b(t),i=new Set(this.db.prepare("SELECT DISTINCT rel_path FROM failure_anchors WHERE failure_id = ?").all(e).map(_=>_.rel_path));let a=B-i.size;const s=this.db.prepare("DELETE FROM failure_anchors WHERE failure_id = ? AND rel_path = ?"),l=this.db.prepare(`
36
+ `).all(t,o,o);for(const n of r)if(n.content_sig&&q(e,n.content_sig))return n;return null}get(e){return this.db.prepare("SELECT * FROM failure_patterns WHERE id = ?").get(e)??null}static anchorSha(e){return H.hash(D(e))}recordAnchors(e,t,o,r=!0){try{const n=b(t),i=new Set(this.db.prepare("SELECT DISTINCT rel_path FROM failure_anchors WHERE failure_id = ?").all(e).map(_=>_.rel_path));let a=Y-i.size;const c=this.db.prepare("DELETE FROM failure_anchors WHERE failure_id = ? AND rel_path = ?"),d=this.db.prepare(`
37
37
  INSERT INTO failure_anchors (failure_id, rel_path, sha, size, mtime_ns)
38
38
  VALUES (?, ?, ?, ?, ?)
39
- `),p=new Set;let u=0;for(const _ of o){if(typeof _!="string"||_.length===0)continue;const f=j(_)?b(_):b(r,_);if(!f.startsWith(r+A)||p.has(f))continue;p.add(f);const h=D(r,f),R=i.has(h);if(!(!R&&(!n||a<=0)))try{const d=m(f,{bigint:!0});if(!d.isFile())continue;const E=g.anchorSha(L(f,"utf-8"));s.run(e,h),l.run(e,h,E,d.size,d.mtimeNs),u++,R||a--}catch{}}return u}catch{return 0}}getAnchors(e){try{const t=this.db.prepare("SELECT rel_path, sha, size, mtime_ns, recorded_at FROM failure_anchors WHERE failure_id = ?");return t.safeIntegers(!0),t.all(e)}catch{return[]}}anchorFreshness(e,t){try{if(!t)return"unverifiable";const o=this.getAnchors(e);if(o.length===0)return"unanchored";const n=b(t);let r=0;for(const i of o)try{const a=b(n,i.rel_path);if(!a.startsWith(n+A))continue;const s=m(a,{bigint:!0});if(!s.isFile())continue;if(s.size===i.size&&s.mtimeNs===i.mtime_ns){r++;continue}if(g.anchorSha(L(a,"utf-8"))===i.sha){r++;continue}return"stale"}catch{}return r>0?"fresh":"unverifiable"}catch{return"unverifiable"}}staleAnchorIds(e,t){const o=new Set,n=new Map;for(const r of e)try{if(r.match==="exact"||r.scope!=="file"&&r.scope!=="symbol"&&r.scope!=="edit")continue;let i=n.get(r.id);i===void 0&&(i=t?this.anchorFreshness(r.id,t):this.getAnchors(r.id).length===0?"unanchored":"unverifiable",n.set(r.id,i)),(i==="unanchored"||i==="stale")&&o.add(r.id)}catch{}return o}noteConfirmation(e,t){if(t.agent_id===null)return;this.db.prepare(`
39
+ `),u=new Set;let l=0;for(const _ of o){if(typeof _!="string"||_.length===0)continue;const p=U(_)?b(_):b(n,_);if(!p.startsWith(n+C)||u.has(p))continue;u.add(p);const h=k(n,p),S=i.has(h);if(!(!S&&(!r||a<=0)))try{const f=j(p,{bigint:!0});if(!f.isFile())continue;const E=m.anchorSha(A(p,"utf-8"));c.run(e,h),d.run(e,h,E,f.size,f.mtimeNs),l++,S||a--}catch{}}return l}catch{return 0}}getAnchors(e){try{const t=this.db.prepare("SELECT rel_path, sha, size, mtime_ns, recorded_at FROM failure_anchors WHERE failure_id = ?");return t.safeIntegers(!0),t.all(e)}catch{return[]}}anchorFreshness(e,t){try{if(!t)return"unverifiable";const o=this.getAnchors(e);if(o.length===0)return"unanchored";const r=b(t);let n=0;for(const i of o)try{const a=b(r,i.rel_path);if(!a.startsWith(r+C))continue;const c=j(a,{bigint:!0});if(!c.isFile())continue;if(c.size===i.size&&c.mtimeNs===i.mtime_ns){n++;continue}if(m.anchorSha(A(a,"utf-8"))===i.sha){n++;continue}return"stale"}catch{}return n>0?"fresh":"unverifiable"}catch{return"unverifiable"}}staleAnchorIds(e,t){const o=new Set,r=new Map;for(const n of e)try{if(n.match==="exact"||n.scope!=="file"&&n.scope!=="symbol"&&n.scope!=="edit")continue;let i=r.get(n.id);i===void 0&&(i=t?this.anchorFreshness(n.id,t):this.getAnchors(n.id).length===0?"unanchored":"unverifiable",r.set(n.id,i)),(i==="unanchored"||i==="stale")&&o.add(n.id)}catch{}return o}noteConfirmation(e,t){if(t.agent_id===null)return;this.db.prepare(`
40
40
  INSERT OR IGNORE INTO failure_confirmations (failure_id, agent_id, run_id)
41
41
  VALUES (?, ?, ?)
42
- `).run(e,t.agent_id,t.run_id);const o=this.get(e);if(!o||o.quarantine_scope!=="run")return;const{n}=this.db.prepare("SELECT COUNT(*) AS n FROM failure_confirmations WHERE failure_id = ?").get(e);n>=2&&this.applyPromotion(e,"project")}applyPromotion(e,t){const o=this.get(e);if(!o)return!1;const n=t==="project"&&o.project_id===null?"global":t;return C[n]<=C[o.quarantine_scope]?!1:(this.db.prepare("UPDATE failure_patterns SET quarantine_scope = ? WHERE id = ?").run(n,e),O(this.db,{projectId:o.project_id??0,kind:"failure",refTable:"failure_patterns",refId:e}),!0)}promote(e,t){if(!k(S()))return{row:this.get(e),authorized:!1,changed:!1};const o=this.applyPromotion(e,t);return{row:this.get(e),authorized:!0,changed:o}}sweepRunQuarantine(e){const t=Math.max(1,Math.floor(e?.runInactiveHours??24)),o=`-${t} hours`,n=Date.now()-t*36e5,r=U(),i=this.db.transaction(()=>{const a=this.db.prepare(`
42
+ `).run(e,t.agent_id,t.run_id);const o=this.get(e);if(!o||o.quarantine_scope!=="run")return;const{n:r}=this.db.prepare("SELECT COUNT(*) AS n FROM failure_confirmations WHERE failure_id = ?").get(e);r>=2&&this.applyPromotion(e,"project")}applyPromotion(e,t){const o=this.get(e);if(!o)return!1;const r=t==="project"&&o.project_id===null?"global":t;return y[r]<=y[o.quarantine_scope]?!1:(this.db.prepare("UPDATE failure_patterns SET quarantine_scope = ? WHERE id = ?").run(r,e),O(this.db,{projectId:o.project_id??0,kind:"failure",refTable:"failure_patterns",refId:e}),!0)}promote(e,t){if(!$(R()))return{row:this.get(e),authorized:!1,changed:!1};const o=this.applyPromotion(e,t);return{row:this.get(e),authorized:!0,changed:o}}sweepRunQuarantine(e){const t=Math.max(1,Math.floor(e?.runInactiveHours??24)),o=`-${t} hours`,r=Date.now()-t*36e5,n=F(),i=this.db.transaction(()=>{const a=this.db.prepare(`
43
43
  UPDATE failure_patterns
44
44
  SET resolved = 1,
45
45
  resolution_note = COALESCE(resolution_note || ' \xB7 ', '')
46
46
  || 'auto-expired by run-quarantine sweep: run ' || run_id || ' was abandoned'
47
47
  WHERE resolved = 0 AND quarantine_scope = 'run' AND run_id IS NOT NULL
48
48
  AND run_id IN (SELECT run_id FROM runs WHERE status = 'abandoned')
49
- `).run().changes,s=this.db.prepare(`
49
+ `).run().changes,c=this.db.prepare(`
50
50
  SELECT fp.id FROM failure_patterns fp
51
51
  WHERE fp.resolved = 0 AND fp.quarantine_scope = 'run' AND fp.run_id IS NOT NULL
52
52
  AND (
@@ -72,18 +72,18 @@ ${o}
72
72
  )
73
73
  )
74
74
  )
75
- `).all({cut:o,cutMs:n,ttl:r?1:0}).map(u=>u.id),l=this.db.prepare(`
75
+ `).all({cut:o,cutMs:r,ttl:n?1:0}).map(l=>l.id),d=this.db.prepare(`
76
76
  UPDATE failure_patterns
77
77
  SET quarantine_scope = CASE WHEN project_id IS NULL THEN 'global' ELSE 'project' END
78
78
  WHERE id = ?
79
- `);for(const u of s)l.run(u);const p=r?this.db.prepare(`
79
+ `);for(const l of c)d.run(l);const u=n?this.db.prepare(`
80
80
  UPDATE runs SET status = 'abandoned', updated_at = datetime('now')
81
81
  WHERE status = 'running' AND updated_at < datetime('now', @cut)
82
82
  AND NOT EXISTS (
83
83
  SELECT 1 FROM events e
84
84
  WHERE e.run_id = runs.run_id AND e.created_at >= @cutMs
85
85
  )
86
- `).run({cut:o,cutMs:n}).changes:0;return{promotedIds:s,expired:a,abandoned:p}})();for(const a of i.promotedIds){const s=this.get(a);O(this.db,{projectId:s?.project_id??0,kind:"failure",refTable:"failure_patterns",refId:a,agentId:null,runId:null})}return{promoted:i.promotedIds.length,expired:i.expired,runs_abandoned:i.abandoned,...r?{}:{degraded:"live memory off (WYRM_LIVE_MEMORY) \u2014 run-tagged events do not exist, so the run-inactivity TTL paths were skipped; only explicit run verdicts acted (completed/failed promote, abandoned expires)"}}}check(e,t,o,n,r){return this.query(e,t,o,n??null,r).map(({_match:i,_rank:a,...s})=>s)}checkVerdict(e,t,o,n,r){const a=this.query(e,t,o,n??null,r).map(s=>this.toVerdictMatch(s,s._match,s._rank));return{blocked:a.length>0,matches:a,recorded_by_agent:a[0]?.recorded_by_agent??null,run_id:a[0]?.run_id??null,confidence:a.reduce((s,l)=>Math.max(s,l.confidence),0)}}toVerdictMatch(e,t,o=null){const n=W(e);return{id:e.id,pattern:e.signature,scope:e.scope,quarantine_scope:e.quarantine_scope,target:e.target,description:e.description,why_failed:e.why_failed,severity:e.severity,occurrences:e.occurrences,last_seen:e.last_seen,recorded_by_agent:n.actor,run_id:n.run_id,match:t,confidence:x(t,o)}}targetIdentityMatches(e,t,o,n){const r=N(t),i=r.slice(0,200);if(i.length===0)return[];const a=n?.callerRunId!==void 0?n.callerRunId:S().run_id,s=`${e}:${i}:`,l=`${e}:${i};`;return this.db.prepare(`
86
+ `).run({cut:o,cutMs:r}).changes:0;return{promotedIds:c,expired:a,abandoned:u}})();for(const a of i.promotedIds){const c=this.get(a);O(this.db,{projectId:c?.project_id??0,kind:"failure",refTable:"failure_patterns",refId:a,agentId:null,runId:null})}return{promoted:i.promotedIds.length,expired:i.expired,runs_abandoned:i.abandoned,...n?{}:{degraded:"live memory off (WYRM_LIVE_MEMORY) \u2014 run-tagged events do not exist, so the run-inactivity TTL paths were skipped; only explicit run verdicts acted (completed/failed promote, abandoned expires)"}}}check(e,t,o,r,n){return this.query(e,t,o,r??null,n).map(({_match:i,_rank:a,...c})=>c)}checkVerdict(e,t,o,r,n){const a=this.query(e,t,o,r??null,n).map(c=>this.toVerdictMatch(c,c._match,c._rank));return{blocked:a.length>0,matches:a,recorded_by_agent:a[0]?.recorded_by_agent??null,run_id:a[0]?.run_id??null,confidence:a.reduce((c,d)=>Math.max(c,d.confidence),0)}}toVerdictMatch(e,t,o=null){const r=v(e);return{id:e.id,pattern:e.signature,scope:e.scope,quarantine_scope:e.quarantine_scope,target:e.target,description:e.description,why_failed:e.why_failed,severity:e.severity,occurrences:e.occurrences,last_seen:e.last_seen,recorded_by_agent:r.actor,run_id:r.run_id,match:t,confidence:z(t,o)}}targetIdentityMatches(e,t,o,r){const n=g(t),i=n.slice(0,200);if(i.length===0)return[];const a=r?.callerRunId!==void 0?r.callerRunId:R().run_id,c=`${e}:${i}:`,d=`${e}:${i};`;return this.db.prepare(`
87
87
  SELECT * FROM failure_patterns
88
88
  WHERE resolved = 0
89
89
  AND signature >= @lo AND signature < @hi
@@ -91,51 +91,65 @@ ${o}
91
91
  AND (quarantine_scope <> 'run' OR run_id = @run)
92
92
  ORDER BY occurrences DESC, last_seen DESC
93
93
  LIMIT @cap
94
- `).all({lo:s,hi:l,project:o??null,run:a,cap:v}).filter(u=>N(u.target)===r).slice(0,q)}recordBlock(e,t){if(!(!e.blocked||e.matches.length===0))try{const o=S(),n=e.matches.find(r=>!r.stale_anchor)??e.matches[0];this.db.prepare(`
94
+ `).all({lo:c,hi:d,project:o??null,run:a,cap:N}).filter(l=>g(l.target)===n).slice(0,T)}canonicalMatches(e,t,o,r){if(e!=="command")return[];const n=L(t);if(n.length===0)return[];const i=r?.callerRunId!==void 0?r.callerRunId:R().run_id;return this.db.prepare(`
95
+ SELECT * FROM failure_patterns
96
+ WHERE resolved = 0 AND scope = 'command' AND canonical_target = @canon
97
+ AND (project_id IS @project OR project_id = @project OR project_id IS NULL)
98
+ AND (quarantine_scope <> 'run' OR run_id = @run)
99
+ ORDER BY occurrences DESC, last_seen DESC
100
+ LIMIT @cap
101
+ `).all({canon:n,project:o??null,run:i,cap:N}).filter(c=>L(c.target)===n).slice(0,T)}commandHeadFamily(e,t,o,r){if(e!=="command")return[];const n=w(t);if(n.length===0)return[];const i=r?.callerRunId!==void 0?r.callerRunId:R().run_id;return this.db.prepare(`
102
+ SELECT * FROM failure_patterns
103
+ WHERE resolved = 0 AND scope = 'command' AND command_head = @head
104
+ AND (project_id IS @project OR project_id = @project OR project_id IS NULL)
105
+ AND (quarantine_scope <> 'run' OR run_id = @run)
106
+ ORDER BY occurrences DESC, last_seen DESC
107
+ LIMIT @cap
108
+ `).all({head:n,project:o??null,run:i,cap:N}).slice(0,T)}recordBlock(e,t){if(!(!e.blocked||e.matches.length===0))try{const o=R(),r=e.matches.find(n=>!n.stale_anchor)??e.matches[0];this.db.prepare(`
95
109
  INSERT INTO failure_blocks (failure_id, project_id, agent_id, run_id)
96
110
  VALUES (?, ?, ?, ?)
97
- `).run(n.id,t??null,o.agent_id,o.run_id)}catch{}}pruneBlocks(e){const t=Math.max(1,Math.floor(e));try{return this.db.prepare("DELETE FROM failure_blocks WHERE blocked_at < datetime('now', @cut)").run({cut:`-${t} days`}).changes}catch{return 0}}failureStats(e){const t=e?.projectId??null,o=e?.callerRunId!==void 0?e.callerRunId:S().run_id,n={project:t},r=this.db.prepare(`
111
+ `).run(r.id,t??null,o.agent_id,o.run_id)}catch{}}pruneBlocks(e){const t=Math.max(1,Math.floor(e));try{return this.db.prepare("DELETE FROM failure_blocks WHERE blocked_at < datetime('now', @cut)").run({cut:`-${t} days`}).changes}catch{return 0}}failureStats(e){const t=e?.projectId??null,o=e?.callerRunId!==void 0?e.callerRunId:R().run_id,r={project:t},n=this.db.prepare(`
98
112
  SELECT COUNT(*) AS total, COALESCE(SUM(resolved = 0), 0) AS unresolved
99
113
  FROM failure_patterns WHERE (@project IS NULL OR project_id = @project)
100
- `).get(n),i={run:0,project:0,global:0};for(const E of this.db.prepare(`
114
+ `).get(r),i={run:0,project:0,global:0};for(const E of this.db.prepare(`
101
115
  SELECT quarantine_scope AS k, COUNT(*) AS n FROM failure_patterns
102
116
  WHERE (@project IS NULL OR project_id = @project) GROUP BY quarantine_scope
103
- `).all(n))i[E.k]=E.n;const a={file:0,symbol:0,command:0,prompt:0,edit:0};for(const E of this.db.prepare(`
117
+ `).all(r))i[E.k]=E.n;const a={file:0,symbol:0,command:0,prompt:0,edit:0};for(const E of this.db.prepare(`
104
118
  SELECT scope AS k, COUNT(*) AS n FROM failure_patterns
105
119
  WHERE (@project IS NULL OR project_id = @project) GROUP BY scope
106
- `).all(n))a[E.k]=E.n;const s=E=>E.map(T=>({who:H(T.agent_id),count:T.count})),l=s(this.db.prepare(`
120
+ `).all(r))a[E.k]=E.n;const c=E=>E.map(I=>({who:B(I.agent_id),count:I.count})),d=c(this.db.prepare(`
107
121
  SELECT agent_id, COUNT(*) AS count FROM failure_patterns
108
122
  WHERE (@project IS NULL OR project_id = @project)
109
123
  GROUP BY agent_id ORDER BY count DESC, agent_id ASC LIMIT 10
110
- `).all(n)),p=this.db.prepare(`
124
+ `).all(r)),u=this.db.prepare(`
111
125
  SELECT run_id, COUNT(*) AS count FROM failure_patterns
112
126
  WHERE run_id IS NOT NULL AND (@project IS NULL OR project_id = @project)
113
127
  GROUP BY run_id ORDER BY count DESC, run_id ASC LIMIT 10
114
- `).all(n),u=s(this.db.prepare(`
128
+ `).all(r),l=c(this.db.prepare(`
115
129
  SELECT agent_id, COUNT(*) AS count FROM failure_blocks
116
130
  WHERE (@project IS NULL OR project_id = @project)
117
131
  GROUP BY agent_id ORDER BY count DESC, agent_id ASC LIMIT 10
118
- `).all(n)),_=this.db.prepare(`
132
+ `).all(r)),_=this.db.prepare(`
119
133
  SELECT run_id, COUNT(*) AS count FROM failure_blocks
120
134
  WHERE run_id IS NOT NULL AND (@project IS NULL OR project_id = @project)
121
135
  GROUP BY run_id ORDER BY count DESC, run_id ASC LIMIT 10
122
- `).all(n),f=this.db.prepare(`
136
+ `).all(r),p=this.db.prepare(`
123
137
  SELECT COUNT(*) AS total, COUNT(DISTINCT fc.agent_id) AS distinct_agents
124
138
  FROM failure_confirmations fc
125
139
  JOIN failure_patterns fp ON fp.id = fc.failure_id
126
140
  WHERE (@project IS NULL OR fp.project_id = @project)
127
- `).get(n),h=this.db.prepare(`
141
+ `).get(r),h=this.db.prepare(`
128
142
  SELECT COUNT(*) AS n FROM failure_blocks WHERE (@project IS NULL OR project_id = @project)
129
- `).get(n).n,R=this.db.prepare(`
143
+ `).get(r).n,S=this.db.prepare(`
130
144
  SELECT COUNT(*) AS n FROM failure_blocks
131
145
  WHERE run_id = @run AND (@project IS NULL OR project_id = @project)
132
- `).get({...n,run:o}).n,d=this.db.prepare(`
146
+ `).get({...r,run:o}).n,f=this.db.prepare(`
133
147
  SELECT fb.failure_id, fp.scope, fp.target, COUNT(*) AS blocks
134
148
  FROM failure_blocks fb
135
149
  JOIN failure_patterns fp ON fp.id = fb.failure_id
136
150
  WHERE (@project IS NULL OR fb.project_id = @project)
137
151
  GROUP BY fb.failure_id ORDER BY blocks DESC, fb.failure_id ASC LIMIT 5
138
- `).all(n);return{view:"failures",project_id:t,recorded:{total:r.total,unresolved:r.unresolved,by_quarantine_scope:i,by_scope:a,by_agent:l,by_run:p},confirmations:{total:f.total,distinct_agents:f.distinct_agents},blocked:{total:h,by_agent:u,by_run:_,this_run:{run_id:o??null,blocked:R},top_blocked:d}}}query(e,t,o,n,r){const i=r?.callerRunId!==void 0?r.callerRunId:S().run_id,a=r?.runScope??"any",s={project:n,run:i,tier:a==="any"?null:a},l=g.signature(e,t,o),p=this.db.prepare(`
152
+ `).all(r);return{view:"failures",project_id:t,recorded:{total:n.total,unresolved:n.unresolved,by_quarantine_scope:i,by_scope:a,by_agent:d,by_run:u},confirmations:{total:p.total,distinct_agents:p.distinct_agents},blocked:{total:h,by_agent:l,by_run:_,this_run:{run_id:o??null,blocked:S},top_blocked:f}}}query(e,t,o,r,n){const i=n?.callerRunId!==void 0?n.callerRunId:R().run_id,a=n?.runScope??"any",c={project:r,run:i,tier:a==="any"?null:a},d=m.signature(e,t,o),u=this.db.prepare(`
139
153
  SELECT *, NULL AS _rank FROM failure_patterns
140
154
  WHERE resolved = 0 AND signature = @sig
141
155
  AND (project_id IS @project OR project_id = @project OR project_id IS NULL)
@@ -143,7 +157,7 @@ ${o}
143
157
  AND (@tier IS NULL OR quarantine_scope = @tier)
144
158
  ORDER BY occurrences DESC, last_seen DESC
145
159
  LIMIT 5
146
- `).all({...s,sig:l});if(p.length>0)return p.map(d=>({...d,_match:"exact",_rank:null}));const u=M(`${t} ${o}`.slice(0,100));if(!u)return[];const _=u.split(" ").filter(d=>/[\p{L}\p{N}]/u.test(d)),f=_.filter(d=>!$.has(d.toLowerCase())),h=f.length?f:_;if(h.length===0)return[];const R=h.map(d=>`"${d.replace(/"/g,"")}"`).join(" ");try{return this.db.prepare(`
160
+ `).all({...c,sig:d});if(u.length>0)return u.map(f=>({...f,_match:"exact",_rank:null}));const l=W(`${t} ${o}`.slice(0,100));if(!l)return[];const _=l.split(" ").filter(f=>/[\p{L}\p{N}]/u.test(f)),p=_.filter(f=>!x.has(f.toLowerCase())),h=p.length?p:_;if(h.length===0)return[];const S=h.map(f=>`"${f.replace(/"/g,"")}"`).join(" ");try{return this.db.prepare(`
147
161
  SELECT fp.*, bm25(failure_patterns_fts) AS _rank FROM failure_patterns fp
148
162
  JOIN failure_patterns_fts fts ON fts.rowid = fp.id
149
163
  WHERE failure_patterns_fts MATCH @q
@@ -154,11 +168,11 @@ ${o}
154
168
  AND (@tier IS NULL OR fp.quarantine_scope = @tier)
155
169
  ORDER BY fp.occurrences DESC, fp.last_seen DESC
156
170
  LIMIT 5
157
- `).all({...s,q:R,scope:e}).map(E=>({...E,_match:"fuzzy"}))}catch{return[]}}list(e,t=20){return e==null?this.db.prepare(`SELECT * FROM failure_patterns WHERE resolved = 0
171
+ `).all({...c,q:S,scope:e}).map(E=>({...E,_match:"fuzzy"}))}catch{return[]}}list(e,t=20){return e==null?this.db.prepare(`SELECT * FROM failure_patterns WHERE resolved = 0
158
172
  ORDER BY last_seen DESC LIMIT ?`).all(t):this.db.prepare(`SELECT * FROM failure_patterns
159
173
  WHERE resolved = 0 AND project_id = ?
160
174
  ORDER BY last_seen DESC LIMIT ?`).all(e,t)}resolve(e,t){return this.db.prepare(`
161
175
  UPDATE failure_patterns
162
176
  SET resolved = 1, resolution_note = ?
163
177
  WHERE id = ?
164
- `).run(t??null,e),this.get(e)}delete(e){try{this.db.prepare("DELETE FROM failure_anchors WHERE failure_id = ?").run(e)}catch{}return this.db.prepare("DELETE FROM failure_patterns WHERE id = ?").run(e).changes>0}}export{B as ANCHOR_CAP,g as FailurePatterns,Z as STALE_ANCHOR_FLAG,x as matchConfidence,N as normalizeIdentity,y as normalizeSignal,K as renderFailureStats};
178
+ `).run(t??null,e),this.get(e)}delete(e){try{this.db.prepare("DELETE FROM failure_anchors WHERE failure_id = ?").run(e)}catch{}return this.db.prepare("DELETE FROM failure_patterns WHERE id = ?").run(e).changes>0}}export{Y as ANCHOR_CAP,m as FailurePatterns,ee as STALE_ANCHOR_FLAG,L as canonicalizeCommand,w as commandHead,z as matchConfidence,g as normalizeIdentity,M as normalizeSignal,te as renderFailureStats};
@@ -1 +1 @@
1
- import{CLI_EXILE_TOOLS as y}from"../deprecations.js";import{ALIAS_ROUTE_OVERRIDES as m}from"./alias-adapters.js";const s=["wyrm_activate","wyrm_agent_init","wyrm_agent_restart","wyrm_agent_status","wyrm_agent_stop","wyrm_all_quests","wyrm_analytics_dashboard","wyrm_ask","wyrm_audit_export","wyrm_audit_log","wyrm_audit_verify","wyrm_auto_capture","wyrm_buddy","wyrm_capture_trace","wyrm_check_update","wyrm_cloud_backup","wyrm_cloud_sync","wyrm_constellation","wyrm_cost_report","wyrm_data_batch_insert","wyrm_data_categories","wyrm_data_insert","wyrm_data_query","wyrm_decision_downstream","wyrm_decision_invalidate","wyrm_decision_upstream","wyrm_digest","wyrm_distill","wyrm_embed","wyrm_encrypt_setup","wyrm_entity_add","wyrm_entity_graph","wyrm_entity_link","wyrm_entity_merge","wyrm_entity_path","wyrm_entity_search","wyrm_events_publish","wyrm_events_replicate","wyrm_events_since","wyrm_events_subscribe","wyrm_failure_list","wyrm_failure_resolve","wyrm_feedback","wyrm_global_context","wyrm_goal_abandon","wyrm_goal_complete","wyrm_goal_iterations","wyrm_goal_list","wyrm_goal_pause","wyrm_goal_resume","wyrm_goal_set","wyrm_harvest","wyrm_hours_report","wyrm_import_git","wyrm_import_pr","wyrm_import_rules","wyrm_inject_prompt","wyrm_intro","wyrm_invoice_generate","wyrm_license","wyrm_list_projects","wyrm_mcp_disable","wyrm_mcp_list","wyrm_mcp_register","wyrm_mcp_tools","wyrm_migrate_prompt","wyrm_orchestrate_task","wyrm_orchestration_config","wyrm_orchestration_stats","wyrm_presence_announce","wyrm_presence_list","wyrm_presence_release","wyrm_project_context","wyrm_prune","wyrm_quest_add","wyrm_quest_claim","wyrm_quest_complete","wyrm_quest_release","wyrm_reference_add","wyrm_reference_list","wyrm_reference_search","wyrm_reindex","wyrm_remember","wyrm_scaffold_get","wyrm_scaffold_save","wyrm_scan_projects","wyrm_self_update","wyrm_session_rehydrate","wyrm_session_start","wyrm_session_update","wyrm_set_global","wyrm_setup","wyrm_skill_activate","wyrm_skill_create","wyrm_skill_deactivate","wyrm_skill_delete","wyrm_skill_get","wyrm_skill_graph","wyrm_skill_list","wyrm_skill_register","wyrm_skill_search","wyrm_skill_stats","wyrm_spec_register","wyrm_symbol_callers","wyrm_symbol_index","wyrm_symbol_search","wyrm_symbol_stats","wyrm_sync","wyrm_sync_conflicts","wyrm_sync_export","wyrm_sync_import","wyrm_sync_resolve","wyrm_token_delete","wyrm_token_get","wyrm_token_set","wyrm_tool_analytics","wyrm_unshare","wyrm_usage","wyrm_vector_setup"],w=_=>_,a=new Map(s.map(_=>{const e=m[_],r=y[_],t={name:_,target:e?.target??_,kind:r?"cli-exile":"route",...r?{cli:r.cli}:{},adapt:e?.adapt??w};return[_,t]}));function l(_,e){const r=a.get(_);return r?{tool:r.target,args:r.adapt(e),via:r}:{tool:_,args:e,via:null}}export{s as ALIAS_NAMES,a as ALIAS_SPINE,l as resolveAliasCall};
1
+ import{CLI_EXILE_TOOLS as y}from"../deprecations.js";import{ALIAS_ROUTE_OVERRIDES as m}from"./alias-adapters.js";const s=["wyrm_activate","wyrm_agent_init","wyrm_agent_restart","wyrm_agent_status","wyrm_agent_stop","wyrm_all_quests","wyrm_analytics_dashboard","wyrm_ask","wyrm_audit_export","wyrm_audit_log","wyrm_audit_verify","wyrm_auto_capture","wyrm_buddy","wyrm_capture_trace","wyrm_check_update","wyrm_cloud_backup","wyrm_cloud_sync","wyrm_constellation","wyrm_cost_report","wyrm_data_batch_insert","wyrm_data_categories","wyrm_data_insert","wyrm_data_query","wyrm_decision_downstream","wyrm_decision_invalidate","wyrm_decision_upstream","wyrm_digest","wyrm_distill","wyrm_embed","wyrm_encrypt_setup","wyrm_entity_add","wyrm_entity_graph","wyrm_entity_link","wyrm_entity_merge","wyrm_entity_path","wyrm_entity_search","wyrm_events_publish","wyrm_events_replicate","wyrm_events_since","wyrm_events_subscribe","wyrm_failure_list","wyrm_failure_resolve","wyrm_feedback","wyrm_global_context","wyrm_goal_abandon","wyrm_goal_complete","wyrm_goal_iterations","wyrm_goal_list","wyrm_goal_pause","wyrm_goal_resume","wyrm_goal_set","wyrm_harvest","wyrm_hours_report","wyrm_import_git","wyrm_import_pr","wyrm_import_rules","wyrm_inject_prompt","wyrm_intro","wyrm_invoice_generate","wyrm_license","wyrm_list_projects","wyrm_mcp_disable","wyrm_mcp_list","wyrm_mcp_register","wyrm_mcp_tools","wyrm_migrate_prompt","wyrm_orchestrate_task","wyrm_orchestration_config","wyrm_orchestration_stats","wyrm_presence_announce","wyrm_presence_list","wyrm_presence_release","wyrm_project_context","wyrm_prune","wyrm_quest_add","wyrm_quest_claim","wyrm_quest_complete","wyrm_quest_release","wyrm_recall_propose","wyrm_recall_set","wyrm_reference_add","wyrm_reference_list","wyrm_reference_search","wyrm_reindex","wyrm_remember","wyrm_scaffold_get","wyrm_scaffold_save","wyrm_scan_projects","wyrm_self_update","wyrm_session_rehydrate","wyrm_session_start","wyrm_session_update","wyrm_set_global","wyrm_setup","wyrm_skill_activate","wyrm_skill_create","wyrm_skill_deactivate","wyrm_skill_delete","wyrm_skill_get","wyrm_skill_graph","wyrm_skill_list","wyrm_skill_register","wyrm_skill_search","wyrm_skill_stats","wyrm_spec_register","wyrm_symbol_callers","wyrm_symbol_index","wyrm_symbol_search","wyrm_symbol_stats","wyrm_sync","wyrm_sync_conflicts","wyrm_sync_export","wyrm_sync_import","wyrm_sync_resolve","wyrm_token_delete","wyrm_token_get","wyrm_token_set","wyrm_tool_analytics","wyrm_unshare","wyrm_usage","wyrm_vector_setup"],w=r=>r,a=new Map(s.map(r=>{const e=m[r],_=y[r],t={name:r,target:e?.target??r,kind:_?"cli-exile":"route",..._?{cli:_.cli}:{},adapt:e?.adapt??w};return[r,t]}));function o(r,e){const _=a.get(r);return _?{tool:_.target,args:_.adapt(e),via:_}:{tool:r,args:e,via:null}}export{s as ALIAS_NAMES,a as ALIAS_SPINE,o as resolveAliasCall};
@@ -1,9 +1,9 @@
1
- import{TOOL_ANNOTATIONS as u}from"../tool-annotations.js";import{staleFoundationWarning as f}from"../causality.js";const $=[{name:"wyrm_decided_because",description:"Use to link a choice or decision to the assumption or evidence it was based on - records a causal edge (truth/quest/artifact/session) so stale foundations invalidate downstream.",inputSchema:{type:"object",properties:{projectPath:{type:"string"},from_kind:{type:"string",enum:["truth","artifact","quest","session","data"]},from_id:{type:"number"},to_kind:{type:"string",enum:["truth","artifact","quest","session","data"]},to_id:{type:"number"},relation:{type:"string",enum:["because_of","supersedes","refutes","verifies"],description:"Default because_of"},rationale:{type:"string",description:"Why"},confidence:{type:"number",description:"0-1, default 1.0"}},required:["projectPath","from_kind","from_id","to_kind","to_id"]},annotations:u.wyrm_decided_because,aliases:[],handler:async(a,d)=>{const{causality:r,db:o}=d,{projectPath:i,from_kind:e,from_id:s,to_kind:t,to_id:c,relation:n,rationale:m,confidence:y}=a,p=o.getProject(i);if(!p)return{content:[{type:"text",text:"Project not found"}],isError:!0};const l=r.link({project_id:p.id,from_kind:e,from_id:s,to_kind:t,to_id:c,relation:n,rationale:m,confidence:y});return{content:[{type:"text",text:`\u{F115D} Edge #${l.id} \u2014 ${e}#${s} ${l.relation} ${t}#${c}`}]}}},{name:"wyrm_decision_downstream",description:"List all decisions that depend on the given source. Use before invalidating a truth to see the blast radius.",inputSchema:{type:"object",properties:{kind:{type:"string",enum:["truth","artifact","quest","session","data"]},id:{type:"number"}},required:["kind","id"]},annotations:u.wyrm_decision_downstream,aliases:[],handler:async(a,d)=>{const{causality:r}=d,{kind:o,id:i}=a,e=r.downstreamOf(o,i);if(e.length===0)return{content:[{type:"text",text:`\u{F115D} No active dependents on ${o}#${i}.`}]};const s=e.map(t=>`\u2022 ${t.from_kind}#${t.from_id} (${t.relation}, conf ${t.confidence})${t.rationale?` \u2014 ${t.rationale}`:""}`).join(`
1
+ import{TOOL_ANNOTATIONS as u}from"../tool-annotations.js";import{staleFoundationWarning as y}from"../causality.js";import{refreshThread as h}from"../thread-assemble.js";const b=[{name:"wyrm_decided_because",description:"Use to link a choice or decision to the assumption or evidence it was based on - records a causal edge (truth/quest/artifact/session) so stale foundations invalidate downstream.",inputSchema:{type:"object",properties:{projectPath:{type:"string"},from_kind:{type:"string",enum:["truth","artifact","quest","session","data"]},from_id:{type:"number"},to_kind:{type:"string",enum:["truth","artifact","quest","session","data"]},to_id:{type:"number"},relation:{type:"string",enum:["because_of","supersedes","refutes","verifies"],description:"Default because_of"},rationale:{type:"string",description:"Why"},confidence:{type:"number",description:"0-1, default 1.0"}},required:["projectPath","from_kind","from_id","to_kind","to_id"]},annotations:u.wyrm_decided_because,aliases:[],handler:async(a,d)=>{const{causality:r,db:o}=d,{projectPath:i,from_kind:e,from_id:s,to_kind:t,to_id:c,relation:n,rationale:m,confidence:f}=a,p=o.getProject(i);if(!p)return{content:[{type:"text",text:"Project not found"}],isError:!0};const l=r.link({project_id:p.id,from_kind:e,from_id:s,to_kind:t,to_id:c,relation:n,rationale:m,confidence:f});return h(o.getDatabase(),p.id),{content:[{type:"text",text:`\u{F115D} Edge #${l.id} \u2014 ${e}#${s} ${l.relation} ${t}#${c}`}]}}},{name:"wyrm_decision_downstream",description:"List all decisions that depend on the given source. Use before invalidating a truth to see the blast radius.",inputSchema:{type:"object",properties:{kind:{type:"string",enum:["truth","artifact","quest","session","data"]},id:{type:"number"}},required:["kind","id"]},annotations:u.wyrm_decision_downstream,aliases:[],handler:async(a,d)=>{const{causality:r}=d,{kind:o,id:i}=a,e=r.downstreamOf(o,i);if(e.length===0)return{content:[{type:"text",text:`\u{F115D} No active dependents on ${o}#${i}.`}]};const s=e.map(t=>`\u2022 ${t.from_kind}#${t.from_id} (${t.relation}, conf ${t.confidence})${t.rationale?` \u2014 ${t.rationale}`:""}`).join(`
2
2
  `);return{content:[{type:"text",text:`\u{F115D} ${e.length} dependent(s):
3
- ${s}`}]}}},{name:"wyrm_decision_upstream",description:"List all sources a decision was based on (incoming edges). Walks the 'why did we choose this?' chain.",inputSchema:{type:"object",properties:{kind:{type:"string",enum:["truth","artifact","quest","session","data"]},id:{type:"number"}},required:["kind","id"]},annotations:u.wyrm_decision_upstream,aliases:[],handler:async(a,d)=>{const{causality:r}=d,{kind:o,id:i}=a,e=r.upstreamOf(o,i),s=f(r.staleFoundations(o,i)),t=s?`${s}
3
+ ${s}`}]}}},{name:"wyrm_decision_upstream",description:"List all sources a decision was based on (incoming edges). Walks the 'why did we choose this?' chain.",inputSchema:{type:"object",properties:{kind:{type:"string",enum:["truth","artifact","quest","session","data"]},id:{type:"number"}},required:["kind","id"]},annotations:u.wyrm_decision_upstream,aliases:[],handler:async(a,d)=>{const{causality:r}=d,{kind:o,id:i}=a,e=r.upstreamOf(o,i),s=y(r.staleFoundations(o,i)),t=s?`${s}
4
4
 
5
5
  `:"";if(e.length===0)return{content:[{type:"text",text:`${t}\u{F115D} No recorded basis for ${o}#${i}.`}]};const c=e.map(n=>`\u2022 ${n.to_kind}#${n.to_id} (${n.relation}, conf ${n.confidence})${n.rationale?` \u2014 ${n.rationale}`:""}`).join(`
6
6
  `);return{content:[{type:"text",text:`${t}\u{F115D} ${e.length} basis edge(s):
7
7
  ${c}`}]}}},{name:"wyrm_decision_invalidate",description:"Cascade-invalidate all decisions downstream of a source (recursive). Use when a foundational truth turns out to be wrong. Returns the set of affected (kind, id) pairs.",inputSchema:{type:"object",properties:{kind:{type:"string",enum:["truth","artifact","quest","session","data"]},id:{type:"number"},reason:{type:"string",description:"Why the source was invalidated"}},required:["kind","id"]},annotations:u.wyrm_decision_invalidate,aliases:[],handler:async(a,d)=>{const{causality:r}=d,o=a||{},{kind:i,id:e,reason:s}=a,t=r.invalidateDownstream(i,e,s);if(t.invalidated===0)return{content:[{type:"text",text:`\u{F115D} No dependents to invalidate from ${i}#${e}.`}]};const c=t.affected.map(n=>`\u2022 ${n.kind}#${n.id} (edge #${n.edge_id})`).join(`
8
8
  `);return{content:[{type:"text",text:`\u{F115D} Invalidated ${t.invalidated} downstream decision(s):
9
- ${c}`}]}}}];export{$ as causalityToolSpecs};
9
+ ${c}`}]}}}];export{b as causalityToolSpecs};