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,70 +1 @@
1
- /**
2
- * @copyright 2026 Ghost Protocol (Pvt) Ltd.
3
- * @license AGPL-3.0-or-later
4
- */
5
- import { TOOL_ANNOTATIONS } from "../tool-annotations.js";
6
- export const invoicingToolSpecs = [
7
- {
8
- name: "wyrm_hours_report",
9
- description: "Hours worked, derived from sessions in a date range. Per-project breakdown + per-session line items. Falls back to a default-hour estimate for sessions with no content.",
10
- inputSchema: {
11
- type: "object",
12
- properties: {
13
- range_start: { type: "string", description: "YYYY-MM-DD" },
14
- range_end: { type: "string", description: "YYYY-MM-DD" },
15
- projectPath: { type: "string", description: "Scope to one project (optional)" },
16
- default_session_hours: { type: "number", description: "Fallback hours for sessions with no recorded content (default 1.0)" },
17
- },
18
- required: ["range_start", "range_end"],
19
- },
20
- annotations: TOOL_ANNOTATIONS["wyrm_hours_report"],
21
- aliases: [],
22
- handler: async (args, ctx) => {
23
- const { db, hours } = ctx;
24
- const { range_start, range_end, projectPath, default_session_hours } = args;
25
- const project = projectPath ? db.getProject(projectPath) : null;
26
- const report = hours.report({
27
- range_start, range_end,
28
- project_id: project?.id,
29
- default_session_hours,
30
- });
31
- return { content: [{ type: "text", text: JSON.stringify(report, null, 2) }] };
32
- },
33
- },
34
- {
35
- name: "wyrm_invoice_generate",
36
- description: "Generate a markdown invoice from a date-ranged hours report. Per-session line items + per-project totals + grand total.",
37
- inputSchema: {
38
- type: "object",
39
- properties: {
40
- client_name: { type: "string" },
41
- client_address: { type: "string" },
42
- business_name: { type: "string", description: "Your business name (e.g. 'Ghost Protocol (Pvt) Ltd')" },
43
- business_address: { type: "string" },
44
- business_contact: { type: "string", description: "Email/phone for the From: block" },
45
- invoice_number: { type: "string", description: "Defaults to INV-YYYYMMDD if omitted" },
46
- hourly_rate_usd: { type: "number", description: "Per-hour rate in the chosen currency" },
47
- range_start: { type: "string", description: "YYYY-MM-DD" },
48
- range_end: { type: "string", description: "YYYY-MM-DD" },
49
- projectPath: { type: "string", description: "Scope to one project (optional)" },
50
- default_session_hours: { type: "number" },
51
- currency: { type: "string", description: "ISO 4217, default USD" },
52
- notes: { type: "string", description: "Free-form notes appended to the invoice" },
53
- },
54
- required: ["client_name", "hourly_rate_usd", "range_start", "range_end"],
55
- },
56
- annotations: TOOL_ANNOTATIONS["wyrm_invoice_generate"],
57
- aliases: [],
58
- handler: async (args, ctx) => {
59
- const { db, hours } = ctx;
60
- const input = args;
61
- const project = input.projectPath ? db.getProject(input.projectPath) : null;
62
- const md = hours.invoice({
63
- ...input,
64
- project_id: project?.id,
65
- });
66
- return { content: [{ type: "text", text: md }] };
67
- },
68
- },
69
- ];
70
- //# sourceMappingURL=invoicing.js.map
1
+ import{TOOL_ANNOTATIONS as a}from"../tool-annotations.js";const _=[{name:"wyrm_hours_report",description:"Hours worked, derived from sessions in a date range. Per-project breakdown + per-session line items. Falls back to a default-hour estimate for sessions with no content.",inputSchema:{type:"object",properties:{range_start:{type:"string",description:"YYYY-MM-DD"},range_end:{type:"string",description:"YYYY-MM-DD"},projectPath:{type:"string",description:"Scope to one project (optional)"},default_session_hours:{type:"number",description:"Fallback hours for sessions with no recorded content (default 1.0)"}},required:["range_start","range_end"]},annotations:a.wyrm_hours_report,aliases:[],handler:async(t,r)=>{const{db:n,hours:o}=r,{range_start:e,range_end:s,projectPath:i,default_session_hours:c}=t,p=i?n.getProject(i):null,d=o.report({range_start:e,range_end:s,project_id:p?.id,default_session_hours:c});return{content:[{type:"text",text:JSON.stringify(d,null,2)}]}}},{name:"wyrm_invoice_generate",description:"Generate a markdown invoice from a date-ranged hours report. Per-session line items + per-project totals + grand total.",inputSchema:{type:"object",properties:{client_name:{type:"string"},client_address:{type:"string"},business_name:{type:"string",description:"Your business name (e.g. 'Ghost Protocol (Pvt) Ltd')"},business_address:{type:"string"},business_contact:{type:"string",description:"Email/phone for the From: block"},invoice_number:{type:"string",description:"Defaults to INV-YYYYMMDD if omitted"},hourly_rate_usd:{type:"number",description:"Per-hour rate in the chosen currency"},range_start:{type:"string",description:"YYYY-MM-DD"},range_end:{type:"string",description:"YYYY-MM-DD"},projectPath:{type:"string",description:"Scope to one project (optional)"},default_session_hours:{type:"number"},currency:{type:"string",description:"ISO 4217, default USD"},notes:{type:"string",description:"Free-form notes appended to the invoice"}},required:["client_name","hourly_rate_usd","range_start","range_end"]},annotations:a.wyrm_invoice_generate,aliases:[],handler:async(t,r)=>{const{db:n,hours:o}=r,e=t,s=e.projectPath?n.getProject(e.projectPath):null;return{content:[{type:"text",text:o.invoice({...e,project_id:s?.id})}]}}}];export{_ as invoicingToolSpecs};
@@ -1,137 +1,6 @@
1
- /**
2
- * @copyright 2026 Ghost Protocol (Pvt) Ltd.
3
- * @license AGPL-3.0-or-later
4
- */
5
- import { TOOL_ANNOTATIONS } from "../tool-annotations.js";
6
- export const mcpclientToolSpecs = [
7
- {
8
- name: "wyrm_mcp_register",
9
- description: "Register an outbound MCP server config. Wyrm can then call its tools via wyrm_call_external. e.g. server_name='github', command='npx', args=['-y', '@modelcontextprotocol/server-github'], env={GITHUB_PERSONAL_ACCESS_TOKEN: '...'}.",
10
- inputSchema: {
11
- type: "object",
12
- properties: {
13
- server_name: { type: "string" },
14
- command: { type: "string", description: "Executable (e.g. 'npx', '/usr/local/bin/some-mcp')" },
15
- args: { type: "array", items: { type: "string" } },
16
- env: { type: "object", description: "Env vars passed to the spawned server" },
17
- },
18
- required: ["server_name", "command"],
19
- },
20
- annotations: TOOL_ANNOTATIONS["wyrm_mcp_register"],
21
- aliases: [],
22
- handler: async (args, ctx) => {
23
- const { mcpClient, server } = ctx;
24
- const a = args;
25
- const cfg = mcpClient.register(a);
26
- return { content: [{ type: "text", text: `󱅝 MCP server '${cfg.server_name}' registered (command: ${cfg.command}).` }] };
27
- },
28
- },
29
- {
30
- name: "wyrm_mcp_list",
31
- description: "List registered MCP server configs.",
32
- inputSchema: { type: "object", properties: {} },
33
- annotations: TOOL_ANNOTATIONS["wyrm_mcp_list"],
34
- aliases: [],
35
- handler: async (args, ctx) => {
36
- const { mcpClient, server } = ctx;
37
- const rows = mcpClient.list();
38
- if (rows.length === 0)
39
- return { content: [{ type: "text", text: "󱅝 No outbound MCP servers registered." }] };
40
- const text = rows.map(r => `• ${r.server_name} ${r.enabled ? '[on]' : '[off]'} — ${r.command} (used ${r.use_count}×)`).join('\n');
41
- return { content: [{ type: "text", text: `󱅝 ${rows.length} server(s):\n${text}` }] };
42
- },
43
- },
44
- {
45
- name: "wyrm_mcp_tools",
46
- description: "List the tools a registered server exposes (one-shot tools/list call over MCP).",
47
- inputSchema: {
48
- type: "object",
49
- properties: { server_name: { type: "string" } },
50
- required: ["server_name"],
51
- },
52
- annotations: TOOL_ANNOTATIONS["wyrm_mcp_tools"],
53
- aliases: [],
54
- handler: async (args, ctx) => {
55
- const { mcpClient, server } = ctx;
56
- const a = args;
57
- const tools = await mcpClient.listTools(a.server_name);
58
- if (!tools)
59
- return { content: [{ type: "text", text: `Could not reach server '${a.server_name}' (not registered, disabled, or spawn failed).` }], isError: true };
60
- const text = tools.map(t => `• ${t.name}${t.description ? ` — ${t.description.slice(0, 120)}` : ''}`).join('\n');
61
- return { content: [{ type: "text", text: `󱅝 ${tools.length} tool(s) on ${a.server_name}:\n${text}` }] };
62
- },
63
- },
64
- {
65
- name: "wyrm_mcp_disable",
66
- description: "Disable an MCP server config (kept in DB but won't be spawned).",
67
- inputSchema: {
68
- type: "object",
69
- properties: { server_name: { type: "string" } },
70
- required: ["server_name"],
71
- },
72
- annotations: TOOL_ANNOTATIONS["wyrm_mcp_disable"],
73
- aliases: [],
74
- handler: async (args, ctx) => {
75
- const { mcpClient } = ctx;
76
- const a = args;
77
- const ok = mcpClient.disable(a.server_name);
78
- return { content: [{ type: "text", text: ok ? `󱅝 ${a.server_name} disabled.` : `${a.server_name} not found.` }], isError: !ok };
79
- },
80
- },
81
- {
82
- name: "wyrm_call_external",
83
- description: "Use to call a tool on an outbound MCP server registered via wyrm_mcp - lazily spawned over stdio, result returned and logged to external_call_log.",
84
- inputSchema: {
85
- type: "object",
86
- properties: {
87
- server: { type: "string", description: "Registered server_name" },
88
- tool: { type: "string", description: "Tool name to invoke" },
89
- args: { type: "object", description: "Tool arguments" },
90
- },
91
- required: ["server", "tool"],
92
- },
93
- annotations: TOOL_ANNOTATIONS["wyrm_call_external"],
94
- aliases: [],
95
- handler: async (args, ctx) => {
96
- const { mcpClient, server } = ctx;
97
- const a = args;
98
- const r = await mcpClient.call(a.server, a.tool, a.args ?? {});
99
- if (!r.ok) {
100
- return { content: [{ type: "text", text: `❌ ${a.server}.${a.tool}: ${r.error}` }], isError: true };
101
- }
102
- return { content: [{ type: "text", text: `󱅝 ${a.server}.${a.tool} (${r.latency_ms}ms):\n${JSON.stringify(r.result, null, 2)}` }] };
103
- },
104
- },
105
- {
106
- name: "wyrm_tool_analytics",
107
- description: "Wyrm watches Wyrm — per-tool usage stats (volume, error rate, p50/p95 latency) over a configurable window. Use to find under-performing tools and tune retrieval/ranking. Pass mode='overview' for the total summary, 'usage' for per-tool, 'errors' for recent error sample.",
108
- inputSchema: {
109
- type: "object",
110
- properties: {
111
- mode: { type: "string", enum: ["overview", "usage", "errors"], description: "Which view (default: usage)" },
112
- days: { type: "number", description: "Window in days (default 30)" },
113
- tool_name: { type: "string", description: "Required when mode='errors'" },
114
- limit: { type: "number", description: "Max rows (default 100 for usage, 10 for errors)" },
115
- },
116
- },
117
- annotations: TOOL_ANNOTATIONS["wyrm_tool_analytics"],
118
- aliases: [],
119
- handler: async (args, ctx) => {
120
- const { toolAnalytics } = ctx;
121
- const { mode, days, tool_name, limit } = args;
122
- const m = mode ?? 'usage';
123
- if (m === 'overview') {
124
- return { content: [{ type: "text", text: JSON.stringify(toolAnalytics.overview({ days }), null, 2) }] };
125
- }
126
- if (m === 'errors') {
127
- if (!tool_name)
128
- return { content: [{ type: "text", text: "tool_name required for mode=errors" }], isError: true };
129
- const errs = toolAnalytics.recentErrors(tool_name, limit ?? 10);
130
- return { content: [{ type: "text", text: JSON.stringify(errs, null, 2) }] };
131
- }
132
- const stats = toolAnalytics.usageStats({ days, limit: limit ?? 100 });
133
- return { content: [{ type: "text", text: JSON.stringify(stats, null, 2) }] };
134
- },
135
- },
136
- ];
137
- //# sourceMappingURL=mcpclient.js.map
1
+ import{TOOL_ANNOTATIONS as c}from"../tool-annotations.js";const d=[{name:"wyrm_mcp_register",description:"Register an outbound MCP server config. Wyrm can then call its tools via wyrm_call_external. e.g. server_name='github', command='npx', args=['-y', '@modelcontextprotocol/server-github'], env={GITHUB_PERSONAL_ACCESS_TOKEN: '...'}.",inputSchema:{type:"object",properties:{server_name:{type:"string"},command:{type:"string",description:"Executable (e.g. 'npx', '/usr/local/bin/some-mcp')"},args:{type:"array",items:{type:"string"}},env:{type:"object",description:"Env vars passed to the spawned server"}},required:["server_name","command"]},annotations:c.wyrm_mcp_register,aliases:[],handler:async(o,n)=>{const{mcpClient:r,server:s}=n,e=o,t=r.register(e);return{content:[{type:"text",text:`\u{F115D} MCP server '${t.server_name}' registered (command: ${t.command}).`}]}}},{name:"wyrm_mcp_list",description:"List registered MCP server configs.",inputSchema:{type:"object",properties:{}},annotations:c.wyrm_mcp_list,aliases:[],handler:async(o,n)=>{const{mcpClient:r,server:s}=n,e=r.list();if(e.length===0)return{content:[{type:"text",text:"\u{F115D} No outbound MCP servers registered."}]};const t=e.map(a=>`\u2022 ${a.server_name} ${a.enabled?"[on]":"[off]"} \u2014 ${a.command} (used ${a.use_count}\xD7)`).join(`
2
+ `);return{content:[{type:"text",text:`\u{F115D} ${e.length} server(s):
3
+ ${t}`}]}}},{name:"wyrm_mcp_tools",description:"List the tools a registered server exposes (one-shot tools/list call over MCP).",inputSchema:{type:"object",properties:{server_name:{type:"string"}},required:["server_name"]},annotations:c.wyrm_mcp_tools,aliases:[],handler:async(o,n)=>{const{mcpClient:r,server:s}=n,e=o,t=await r.listTools(e.server_name);if(!t)return{content:[{type:"text",text:`Could not reach server '${e.server_name}' (not registered, disabled, or spawn failed).`}],isError:!0};const a=t.map(i=>`\u2022 ${i.name}${i.description?` \u2014 ${i.description.slice(0,120)}`:""}`).join(`
4
+ `);return{content:[{type:"text",text:`\u{F115D} ${t.length} tool(s) on ${e.server_name}:
5
+ ${a}`}]}}},{name:"wyrm_mcp_disable",description:"Disable an MCP server config (kept in DB but won't be spawned).",inputSchema:{type:"object",properties:{server_name:{type:"string"}},required:["server_name"]},annotations:c.wyrm_mcp_disable,aliases:[],handler:async(o,n)=>{const{mcpClient:r}=n,s=o,e=r.disable(s.server_name);return{content:[{type:"text",text:e?`\u{F115D} ${s.server_name} disabled.`:`${s.server_name} not found.`}],isError:!e}}},{name:"wyrm_call_external",description:"Use to call a tool on an outbound MCP server registered via wyrm_mcp - lazily spawned over stdio, result returned and logged to external_call_log.",inputSchema:{type:"object",properties:{server:{type:"string",description:"Registered server_name"},tool:{type:"string",description:"Tool name to invoke"},args:{type:"object",description:"Tool arguments"}},required:["server","tool"]},annotations:c.wyrm_call_external,aliases:[],handler:async(o,n)=>{const{mcpClient:r,server:s}=n,e=o,t=await r.call(e.server,e.tool,e.args??{});return t.ok?{content:[{type:"text",text:`\u{F115D} ${e.server}.${e.tool} (${t.latency_ms}ms):
6
+ ${JSON.stringify(t.result,null,2)}`}]}:{content:[{type:"text",text:`\u274C ${e.server}.${e.tool}: ${t.error}`}],isError:!0}}},{name:"wyrm_tool_analytics",description:"Wyrm watches Wyrm \u2014 per-tool usage stats (volume, error rate, p50/p95 latency) over a configurable window. Use to find under-performing tools and tune retrieval/ranking. Pass mode='overview' for the total summary, 'usage' for per-tool, 'errors' for recent error sample.",inputSchema:{type:"object",properties:{mode:{type:"string",enum:["overview","usage","errors"],description:"Which view (default: usage)"},days:{type:"number",description:"Window in days (default 30)"},tool_name:{type:"string",description:"Required when mode='errors'"},limit:{type:"number",description:"Max rows (default 100 for usage, 10 for errors)"}}},annotations:c.wyrm_tool_analytics,aliases:[],handler:async(o,n)=>{const{toolAnalytics:r}=n,{mode:s,days:e,tool_name:t,limit:a}=o,i=s??"usage";if(i==="overview")return{content:[{type:"text",text:JSON.stringify(r.overview({days:e}),null,2)}]};if(i==="errors"){if(!t)return{content:[{type:"text",text:"tool_name required for mode=errors"}],isError:!0};const m=r.recentErrors(t,a??10);return{content:[{type:"text",text:JSON.stringify(m,null,2)}]}}const l=r.usageStats({days:e,limit:a??100});return{content:[{type:"text",text:JSON.stringify(l,null,2)}]}}}];export{d as mcpclientToolSpecs};
@@ -1,125 +1,40 @@
1
- /**
2
- * @copyright 2026 Ghost Protocol (Pvt) Ltd.
3
- * @license AGPL-3.0-or-later
4
- */
5
- import { TOOL_ANNOTATIONS } from "../tool-annotations.js";
6
- import { getDefaultConfig } from "../auto-orchestrator.js";
7
- export const orchestrationToolSpecs = [
8
- {
9
- name: "wyrm_orchestrate_task",
10
- description: "Classify a task and get automatic orchestration recommendation (ensemble voting, parallel research, etc)",
11
- inputSchema: {
12
- type: "object",
13
- properties: {
14
- task: { type: "string", description: "Task description to classify and orchestrate" },
15
- },
16
- required: ["task"],
17
- },
18
- annotations: TOOL_ANNOTATIONS["wyrm_orchestrate_task"],
19
- aliases: [],
20
- handler: async (args, ctx) => {
21
- const { orchestrator } = ctx;
22
- const { task } = args;
23
- const plan = await orchestrator.processTask(task);
24
- let text = `󱅝 **Orchestration Plan**\n\n`;
25
- text += `## Task Classification\n`;
26
- text += `- **Type:** ${plan.taskType}\n`;
27
- text += `- **Confidence:** ${plan.confidence}%\n`;
28
- text += `- **Recommended Approach:** ${plan.approach}\n\n`;
29
- if (plan.appliedPatterns.length > 0) {
30
- text += `## Patterns Applied\n`;
31
- for (const pattern of plan.appliedPatterns) {
32
- text += `- ✓ ${pattern}\n`;
33
- }
34
- text += '\n';
35
- }
36
- text += `## Expected Outcomes\n`;
37
- text += `- **Quality Boost:** +${plan.quality - 60}% (estimated)\n`;
38
- text += `- **Cost Savings:** ${plan.costSavings}% vs Opus\n`;
39
- text += `- **Parallel Execution:** ~${plan.parallelExecutionTime}ms for full pipeline\n\n`;
40
- text += `## Token Efficiency\n`;
41
- text += `- **Boosting Overhead:** ~${plan.metrics.tokensBoosting} tokens\n`;
42
- text += `- **Ensemble Voting:** ~${plan.metrics.tokensEnsemble} tokens\n`;
43
- text += `- **Verification:** ~${plan.metrics.tokensVerification} tokens\n`;
44
- text += `- **Total Estimated:** ~${plan.metrics.tokensBoosting + plan.metrics.tokensEnsemble + plan.metrics.tokensVerification} tokens\n`;
45
- return { content: [{ type: "text", text }] };
46
- },
47
- },
48
- {
49
- name: "wyrm_orchestration_config",
50
- description: "Get or update auto-orchestration configuration",
51
- inputSchema: {
52
- type: "object",
53
- properties: {
54
- get: { type: "boolean", description: "Get current configuration (default: true)" },
55
- autoOrchestrateEnabled: { type: "boolean", description: "Enable/disable auto-orchestration" },
56
- minConfidenceThreshold: { type: "number", description: "Min confidence for auto-apply (0-100)" },
57
- maxParallelAgents: { type: "number", description: "Max agents to spawn in parallel" },
58
- defaultHaikuBoosting: { type: "boolean", description: "Auto-boost all Haiku calls" },
59
- trackMetrics: { type: "boolean", description: "Track quality/cost metrics" },
60
- },
61
- },
62
- annotations: TOOL_ANNOTATIONS["wyrm_orchestration_config"],
63
- aliases: [],
64
- handler: async (args, ctx) => {
65
- const { cachedResponse, orchestrator } = ctx;
66
- const { get = true, autoOrchestrateEnabled, minConfidenceThreshold, maxParallelAgents, defaultHaikuBoosting, trackMetrics, } = args;
67
- // Update config if any properties provided
68
- if (!get && (autoOrchestrateEnabled !== undefined || minConfidenceThreshold !== undefined ||
69
- maxParallelAgents !== undefined || defaultHaikuBoosting !== undefined ||
70
- trackMetrics !== undefined)) {
71
- const updates = {};
72
- if (autoOrchestrateEnabled !== undefined)
73
- updates.autoOrchestrateEnabled = autoOrchestrateEnabled;
74
- if (minConfidenceThreshold !== undefined)
75
- updates.minConfidenceThreshold = minConfidenceThreshold;
76
- if (maxParallelAgents !== undefined)
77
- updates.maxParallelAgents = maxParallelAgents;
78
- if (defaultHaikuBoosting !== undefined)
79
- updates.defaultHaikuBoosting = defaultHaikuBoosting;
80
- if (trackMetrics !== undefined)
81
- updates.trackMetrics = trackMetrics;
82
- orchestrator.updateConfig(updates);
83
- return { content: [{ type: "text", text: `󱅝 Configuration updated:\n${JSON.stringify(updates, null, 2)}` }] };
84
- }
85
- // Get current config
86
- const config = getDefaultConfig();
87
- let text = `󱅝 **Auto-Orchestration Configuration**\n\n`;
88
- text += `- **Auto-Orchestrate Enabled:** ${config.autoOrchestrateEnabled ? '✓ Yes' : '✗ No'}\n`;
89
- text += `- **Min Confidence Threshold:** ${config.minConfidenceThreshold}%\n`;
90
- text += `- **Max Parallel Agents:** ${config.maxParallelAgents}\n`;
91
- text += `- **Default Haiku Boosting:** ${config.defaultHaikuBoosting ? '✓ Yes' : '✗ No'}\n`;
92
- text += `- **Track Metrics:** ${config.trackMetrics ? '✓ Yes' : '✗ No'}\n`;
93
- text += `- **Thinking Budget:** ${config.thinkingBudget} tokens max\n`;
94
- return cachedResponse(text);
95
- },
96
- },
97
- {
98
- name: "wyrm_orchestration_stats",
99
- description: "Get auto-orchestration effectiveness statistics and task distribution",
100
- inputSchema: {
101
- type: "object",
102
- properties: {},
103
- },
104
- annotations: TOOL_ANNOTATIONS["wyrm_orchestration_stats"],
105
- aliases: [],
106
- handler: async (args, ctx) => {
107
- const { cachedResponse, orchestrator } = ctx;
108
- const stats = orchestrator.getStats();
109
- let text = `󱅝 **Auto-Orchestration Statistics**\n\n`;
110
- text += `## Overall\n`;
111
- text += `- **Tasks Processed:** ${stats.tasksProcessed}\n`;
112
- text += `- **Average Quality Boost:** +${stats.estimatedQualityBoost}%\n`;
113
- text += `- **Average Cost Savings:** ${stats.estimatedCostSavings}% vs Opus\n`;
114
- text += `- **Average Complexity:** ${stats.averageComplexity}\n\n`;
115
- text += `## Task Distribution\n`;
116
- const total = stats.tasksProcessed || 1;
117
- for (const [type, count] of Object.entries(stats.distribution)) {
118
- const pct = Math.round((count / total) * 100);
119
- text += `- **${type}:** ${count} (${pct}%)\n`;
120
- }
121
- return cachedResponse(text);
122
- },
123
- },
124
- ];
125
- //# sourceMappingURL=orchestration.js.map
1
+ import{TOOL_ANNOTATIONS as f}from"../tool-annotations.js";import{getDefaultConfig as m}from"../auto-orchestrator.js";const k=[{name:"wyrm_orchestrate_task",description:"Classify a task and get automatic orchestration recommendation (ensemble voting, parallel research, etc)",inputSchema:{type:"object",properties:{task:{type:"string",description:"Task description to classify and orchestrate"}},required:["task"]},annotations:f.wyrm_orchestrate_task,aliases:[],handler:async(p,r)=>{const{orchestrator:c}=r,{task:l}=p,e=await c.processTask(l);let t=`\u{F115D} **Orchestration Plan**
2
+
3
+ `;if(t+=`## Task Classification
4
+ `,t+=`- **Type:** ${e.taskType}
5
+ `,t+=`- **Confidence:** ${e.confidence}%
6
+ `,t+=`- **Recommended Approach:** ${e.approach}
7
+
8
+ `,e.appliedPatterns.length>0){t+=`## Patterns Applied
9
+ `;for(const n of e.appliedPatterns)t+=`- \u2713 ${n}
10
+ `;t+=`
11
+ `}return t+=`## Expected Outcomes
12
+ `,t+=`- **Quality Boost:** +${e.quality-60}% (estimated)
13
+ `,t+=`- **Cost Savings:** ${e.costSavings}% vs Opus
14
+ `,t+=`- **Parallel Execution:** ~${e.parallelExecutionTime}ms for full pipeline
15
+
16
+ `,t+=`## Token Efficiency
17
+ `,t+=`- **Boosting Overhead:** ~${e.metrics.tokensBoosting} tokens
18
+ `,t+=`- **Ensemble Voting:** ~${e.metrics.tokensEnsemble} tokens
19
+ `,t+=`- **Verification:** ~${e.metrics.tokensVerification} tokens
20
+ `,t+=`- **Total Estimated:** ~${e.metrics.tokensBoosting+e.metrics.tokensEnsemble+e.metrics.tokensVerification} tokens
21
+ `,{content:[{type:"text",text:t}]}}},{name:"wyrm_orchestration_config",description:"Get or update auto-orchestration configuration",inputSchema:{type:"object",properties:{get:{type:"boolean",description:"Get current configuration (default: true)"},autoOrchestrateEnabled:{type:"boolean",description:"Enable/disable auto-orchestration"},minConfidenceThreshold:{type:"number",description:"Min confidence for auto-apply (0-100)"},maxParallelAgents:{type:"number",description:"Max agents to spawn in parallel"},defaultHaikuBoosting:{type:"boolean",description:"Auto-boost all Haiku calls"},trackMetrics:{type:"boolean",description:"Track quality/cost metrics"}}},annotations:f.wyrm_orchestration_config,aliases:[],handler:async(p,r)=>{const{cachedResponse:c,orchestrator:l}=r,{get:e=!0,autoOrchestrateEnabled:t,minConfidenceThreshold:n,maxParallelAgents:d,defaultHaikuBoosting:a,trackMetrics:u}=p;if(!e&&(t!==void 0||n!==void 0||d!==void 0||a!==void 0||u!==void 0)){const s={};return t!==void 0&&(s.autoOrchestrateEnabled=t),n!==void 0&&(s.minConfidenceThreshold=n),d!==void 0&&(s.maxParallelAgents=d),a!==void 0&&(s.defaultHaikuBoosting=a),u!==void 0&&(s.trackMetrics=u),l.updateConfig(s),{content:[{type:"text",text:`\u{F115D} Configuration updated:
22
+ ${JSON.stringify(s,null,2)}`}]}}const i=m();let o=`\u{F115D} **Auto-Orchestration Configuration**
23
+
24
+ `;return o+=`- **Auto-Orchestrate Enabled:** ${i.autoOrchestrateEnabled?"\u2713 Yes":"\u2717 No"}
25
+ `,o+=`- **Min Confidence Threshold:** ${i.minConfidenceThreshold}%
26
+ `,o+=`- **Max Parallel Agents:** ${i.maxParallelAgents}
27
+ `,o+=`- **Default Haiku Boosting:** ${i.defaultHaikuBoosting?"\u2713 Yes":"\u2717 No"}
28
+ `,o+=`- **Track Metrics:** ${i.trackMetrics?"\u2713 Yes":"\u2717 No"}
29
+ `,o+=`- **Thinking Budget:** ${i.thinkingBudget} tokens max
30
+ `,c(o)}},{name:"wyrm_orchestration_stats",description:"Get auto-orchestration effectiveness statistics and task distribution",inputSchema:{type:"object",properties:{}},annotations:f.wyrm_orchestration_stats,aliases:[],handler:async(p,r)=>{const{cachedResponse:c,orchestrator:l}=r,e=l.getStats();let t=`\u{F115D} **Auto-Orchestration Statistics**
31
+
32
+ `;t+=`## Overall
33
+ `,t+=`- **Tasks Processed:** ${e.tasksProcessed}
34
+ `,t+=`- **Average Quality Boost:** +${e.estimatedQualityBoost}%
35
+ `,t+=`- **Average Cost Savings:** ${e.estimatedCostSavings}% vs Opus
36
+ `,t+=`- **Average Complexity:** ${e.averageComplexity}
37
+
38
+ `,t+=`## Task Distribution
39
+ `;const n=e.tasksProcessed||1;for(const[d,a]of Object.entries(e.distribution)){const u=Math.round(a/n*100);t+=`- **${d}:** ${a} (${u}%)
40
+ `}return c(t)}}];export{k as orchestrationToolSpecs};
@@ -1,24 +1 @@
1
- /**
2
- * Declared outputSchemas for tools whose handlers still live in the index.ts
3
- * switch (v7 F3 T018). A ToolSpec carries its outputSchema on the spec object;
4
- * a not-yet-extracted tool that ALREADY returns structuredContent declares its
5
- * schema here so the wire contract ships ahead of the extraction. When T026/
6
- * T036 extracts the owning domain, the schema moves onto the domain's ToolSpec
7
- * and the entry here is deleted.
8
- *
9
- * v7 F3 (T026): wyrm_failure_check — the first and only entry — extracted to
10
- * the failure domain; FAILURE_CHECK_OUTPUT_SCHEMA now lives on its ToolSpec
11
- * (src/handlers/failure.ts), exactly as the T018 contract scheduled. The map
12
- * is empty until another switch-resident tool grows structuredContent; the
13
- * applyDeclaredOutputSchemas pipeline step stays wired for that case.
14
- *
15
- * @copyright 2026 Ghost Protocol (Pvt) Ltd.
16
- * @license AGPL-3.0-or-later
17
- */
18
- /**
19
- * tool name → declared outputSchema, for switch-resident tools only.
20
- * Registry-resident tools declare outputSchema on their ToolSpec instead —
21
- * a name present in BOTH places is a contract error (locked by tests).
22
- */
23
- export const declaredOutputSchemas = {};
24
- //# sourceMappingURL=output-schemas.js.map
1
+ const e={};export{e as declaredOutputSchemas};
@@ -1,99 +1,3 @@
1
- /**
2
- * @copyright 2026 Ghost Protocol (Pvt) Ltd.
3
- * @license AGPL-3.0-or-later
4
- */
5
- import { TOOL_ANNOTATIONS } from "../tool-annotations.js";
6
- import { asString } from "../validate.js";
7
- export const presenceToolSpecs = [
8
- {
9
- // T029: description rewritten for the orchestrator audience (T025 house style).
10
- name: "wyrm_presence_announce",
11
- description: "Use from every fleet agent to announce presence and heartbeat liveness: upserts a TTL row that orchestrators and sibling agents poll before assigning or stealing work, stamped with the ambient run_id and the agent's fleet role so the board reads per-run. Re-announce to heartbeat; dead sessions expire by TTL and are reaped by wyrm_maintenance. Announce BEFORE wyrm_quest_claim - claims require a presence row.",
12
- inputSchema: {
13
- type: "object",
14
- properties: {
15
- agent_id: { type: "string", description: "Stable per-session identifier (e.g. 'claude-pid12345')" },
16
- agent_kind: { type: "string", description: "'claude', 'codex', 'cursor', 'human', etc." },
17
- projectPath: { type: "string", description: "Project path (optional)" },
18
- current_file: { type: "string", description: "File currently being edited" },
19
- current_symbol: { type: "string", description: "Symbol currently focused" },
20
- current_quest_id: { type: "number", description: "Quest currently being worked on" },
21
- ttl_seconds: { type: "number", description: "Heartbeat TTL — agent is considered live for this long after announce (default 300)" },
22
- metadata: { type: "object", description: "Caller-defined extras" },
23
- role: { type: "string", description: "Fleet role (default: run_agents membership)" },
24
- },
25
- required: ["agent_id", "agent_kind"],
26
- },
27
- annotations: TOOL_ANNOTATIONS["wyrm_presence_announce"],
28
- aliases: [],
29
- handler: async (args, ctx) => {
30
- const { db, presence } = ctx;
31
- const a = args || {};
32
- const { agent_id, agent_kind, projectPath, current_file, current_symbol, current_quest_id, ttl_seconds, metadata, } = args;
33
- // Security pass #1 (confirmed finding): the T029 `role` param rode in
34
- // on a bare TypeScript cast, bypassing the T020 boundary seam the
35
- // SAME concept gets on wyrm_run action=join — validate identically
36
- // (asString, maxLen 200) before it lands on the presence board.
37
- const role = asString('role', args.role, { maxLen: 200 });
38
- const project = projectPath ? db.getProject(projectPath) : null;
39
- const row = presence.announce({
40
- agent_id, agent_kind,
41
- project_id: project?.id ?? null,
42
- current_file, current_symbol, current_quest_id,
43
- ttl_seconds, metadata, role,
44
- });
45
- return { content: [{ type: "text", text: `󱅝 Presence announced — ${agent_kind}:${agent_id} (TTL ${row.ttl_seconds}s)` }] };
46
- },
47
- },
48
- {
49
- // T029: description rewritten for the orchestrator audience (T025 house style).
50
- name: "wyrm_presence_list",
51
- description: "Use from an orchestrator to see which agents are live right now (heartbeat within TTL) before dispatching work - optionally scoped to a project or to agents touching a specific file, so file-level collisions surface before they happen.",
52
- inputSchema: {
53
- type: "object",
54
- properties: {
55
- projectPath: { type: "string", description: "Project path (optional)" },
56
- on_file: { type: "string", description: "Filter to agents working on this file (optional)" },
57
- },
58
- },
59
- annotations: TOOL_ANNOTATIONS["wyrm_presence_list"],
60
- aliases: [],
61
- handler: async (args, ctx) => {
62
- const { db, presence } = ctx;
63
- const { projectPath, on_file } = args;
64
- const project = projectPath ? db.getProject(projectPath) : null;
65
- const rows = on_file
66
- ? presence.agentsOnFile(on_file)
67
- : presence.liveAgents(project?.id ?? null);
68
- if (rows.length === 0) {
69
- return { content: [{ type: "text", text: "󱅝 No live agents." }] };
70
- }
71
- const text = rows.map(r => {
72
- const focus = [r.current_file && `file:${r.current_file}`, r.current_symbol && `sym:${r.current_symbol}`, r.current_quest_id && `quest:${r.current_quest_id}`].filter(Boolean).join(' ');
73
- return `• ${r.agent_kind}:${r.agent_id}${focus ? ` — ${focus}` : ''} (last ${r.last_heartbeat})`;
74
- }).join('\n');
75
- return { content: [{ type: "text", text: `󱅝 ${rows.length} live agent(s):\n${text}` }] };
76
- },
77
- },
78
- {
79
- // T029: description rewritten for the orchestrator audience (T025 house style).
80
- name: "wyrm_presence_release",
81
- description: "Use on clean agent exit: removes the presence row and drops every quest claim the agent holds, so queued work is immediately re-claimable by the rest of the fleet instead of waiting out the TTL. Idempotent - safe to call twice.",
82
- inputSchema: {
83
- type: "object",
84
- properties: {
85
- agent_id: { type: "string", description: "Agent ID to release" },
86
- },
87
- required: ["agent_id"],
88
- },
89
- annotations: TOOL_ANNOTATIONS["wyrm_presence_release"],
90
- aliases: [],
91
- handler: async (args, ctx) => {
92
- const { presence } = ctx;
93
- const { agent_id } = args;
94
- const ok = presence.release(agent_id);
95
- return { content: [{ type: "text", text: ok ? `󱅝 ${agent_id} released.` : `󱅝 ${agent_id} not present (already released).` }] };
96
- },
97
- },
98
- ];
99
- //# sourceMappingURL=presence.js.map
1
+ import{TOOL_ANNOTATIONS as d}from"../tool-annotations.js";import{asString as h}from"../validate.js";const w=[{name:"wyrm_presence_announce",description:"Use from every fleet agent to announce presence and heartbeat liveness: upserts a TTL row that orchestrators and sibling agents poll before assigning or stealing work, stamped with the ambient run_id and the agent's fleet role so the board reads per-run. Re-announce to heartbeat; dead sessions expire by TTL and are reaped by wyrm_maintenance. Announce BEFORE wyrm_quest_claim - claims require a presence row.",inputSchema:{type:"object",properties:{agent_id:{type:"string",description:"Stable per-session identifier (e.g. 'claude-pid12345')"},agent_kind:{type:"string",description:"'claude', 'codex', 'cursor', 'human', etc."},projectPath:{type:"string",description:"Project path (optional)"},current_file:{type:"string",description:"File currently being edited"},current_symbol:{type:"string",description:"Symbol currently focused"},current_quest_id:{type:"number",description:"Quest currently being worked on"},ttl_seconds:{type:"number",description:"Heartbeat TTL \u2014 agent is considered live for this long after announce (default 300)"},metadata:{type:"object",description:"Caller-defined extras"},role:{type:"string",description:"Fleet role (default: run_agents membership)"}},required:["agent_id","agent_kind"]},annotations:d.wyrm_presence_announce,aliases:[],handler:async(n,o)=>{const{db:s,presence:t}=o,a=n||{},{agent_id:i,agent_kind:c,projectPath:r,current_file:p,current_symbol:e,current_quest_id:l,ttl_seconds:u,metadata:_}=n,g=h("role",n.role,{maxLen:200}),y=r?s.getProject(r):null,m=t.announce({agent_id:i,agent_kind:c,project_id:y?.id??null,current_file:p,current_symbol:e,current_quest_id:l,ttl_seconds:u,metadata:_,role:g});return{content:[{type:"text",text:`\u{F115D} Presence announced \u2014 ${c}:${i} (TTL ${m.ttl_seconds}s)`}]}}},{name:"wyrm_presence_list",description:"Use from an orchestrator to see which agents are live right now (heartbeat within TTL) before dispatching work - optionally scoped to a project or to agents touching a specific file, so file-level collisions surface before they happen.",inputSchema:{type:"object",properties:{projectPath:{type:"string",description:"Project path (optional)"},on_file:{type:"string",description:"Filter to agents working on this file (optional)"}}},annotations:d.wyrm_presence_list,aliases:[],handler:async(n,o)=>{const{db:s,presence:t}=o,{projectPath:a,on_file:i}=n,c=a?s.getProject(a):null,r=i?t.agentsOnFile(i):t.liveAgents(c?.id??null);if(r.length===0)return{content:[{type:"text",text:"\u{F115D} No live agents."}]};const p=r.map(e=>{const l=[e.current_file&&`file:${e.current_file}`,e.current_symbol&&`sym:${e.current_symbol}`,e.current_quest_id&&`quest:${e.current_quest_id}`].filter(Boolean).join(" ");return`\u2022 ${e.agent_kind}:${e.agent_id}${l?` \u2014 ${l}`:""} (last ${e.last_heartbeat})`}).join(`
2
+ `);return{content:[{type:"text",text:`\u{F115D} ${r.length} live agent(s):
3
+ ${p}`}]}}},{name:"wyrm_presence_release",description:"Use on clean agent exit: removes the presence row and drops every quest claim the agent holds, so queued work is immediately re-claimable by the rest of the fleet instead of waiting out the TTL. Idempotent - safe to call twice.",inputSchema:{type:"object",properties:{agent_id:{type:"string",description:"Agent ID to release"}},required:["agent_id"]},annotations:d.wyrm_presence_release,aliases:[],handler:async(n,o)=>{const{presence:s}=o,{agent_id:t}=n;return{content:[{type:"text",text:s.release(t)?`\u{F115D} ${t} released.`:`\u{F115D} ${t} not present (already released).`}]}}}];export{w as presenceToolSpecs};