wyrm-mcp 7.2.1 → 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 (150) hide show
  1. package/LICENSE +26 -667
  2. package/NOTICE +14 -33
  3. package/dist/activation.js +1 -60
  4. package/dist/agent-daemon.js +4 -281
  5. package/dist/agent-loop.js +7 -332
  6. package/dist/analytics.js +13 -236
  7. package/dist/attribution.js +1 -49
  8. package/dist/audit.js +2 -457
  9. package/dist/auto-capture.js +3 -138
  10. package/dist/auto-orchestrator.js +1 -325
  11. package/dist/autoconfig.js +39 -840
  12. package/dist/buddy-runner.js +1 -109
  13. package/dist/buddy.js +14 -564
  14. package/dist/build-flags.js +1 -17
  15. package/dist/capabilities.js +3 -183
  16. package/dist/capture.js +1 -56
  17. package/dist/causality.js +6 -107
  18. package/dist/cli.js +20 -281
  19. package/dist/cloud/cli.js +5 -541
  20. package/dist/cloud/client.js +1 -221
  21. package/dist/cloud/crypto.js +1 -85
  22. package/dist/cloud/machine-id.js +2 -113
  23. package/dist/cloud/recovery.js +1 -60
  24. package/dist/cloud/sync-engine.js +7 -543
  25. package/dist/cloud-backup.js +5 -579
  26. package/dist/cloud-profile.js +1 -138
  27. package/dist/cloud-sync-entrypoint.js +1 -47
  28. package/dist/cloud-sync.js +2 -309
  29. package/dist/constellation.js +12 -168
  30. package/dist/context-build-budgeted.js +4 -144
  31. package/dist/context-ranking.js +1 -69
  32. package/dist/crypto.js +1 -179
  33. package/dist/daemon-write-endpoint.js +1 -290
  34. package/dist/daemon-writer.js +2 -406
  35. package/dist/database.js +43 -1110
  36. package/dist/deprecations.js +2 -162
  37. package/dist/design.js +13 -141
  38. package/dist/event-replication.js +1 -112
  39. package/dist/events-sse.js +7 -43
  40. package/dist/events.js +6 -238
  41. package/dist/failure-patterns.js +42 -659
  42. package/dist/federation.js +12 -236
  43. package/dist/goals.js +13 -101
  44. package/dist/golden.js +3 -355
  45. package/dist/handlers/agent.js +4 -165
  46. package/dist/handlers/alias-adapters.js +1 -129
  47. package/dist/handlers/aliases.js +1 -171
  48. package/dist/handlers/audit.js +1 -87
  49. package/dist/handlers/boundary.js +1 -221
  50. package/dist/handlers/capture.js +73 -1109
  51. package/dist/handlers/causality.js +7 -114
  52. package/dist/handlers/cloud.js +85 -382
  53. package/dist/handlers/companion.js +28 -459
  54. package/dist/handlers/datalake.js +7 -187
  55. package/dist/handlers/dispatch-context.js +0 -22
  56. package/dist/handlers/entity.js +25 -256
  57. package/dist/handlers/events.js +16 -335
  58. package/dist/handlers/failure.js +13 -340
  59. package/dist/handlers/goals.js +4 -296
  60. package/dist/handlers/intelligence.js +126 -674
  61. package/dist/handlers/invoicing.js +1 -70
  62. package/dist/handlers/mcpclient.js +6 -137
  63. package/dist/handlers/orchestration.js +40 -125
  64. package/dist/handlers/output-schemas.js +1 -24
  65. package/dist/handlers/presence.js +3 -99
  66. package/dist/handlers/project.js +28 -182
  67. package/dist/handlers/prompts.js +6 -157
  68. package/dist/handlers/quest.js +4 -224
  69. package/dist/handlers/recall.js +11 -218
  70. package/dist/handlers/registry.js +1 -167
  71. package/dist/handlers/resources.js +1 -288
  72. package/dist/handlers/review.js +11 -74
  73. package/dist/handlers/run.js +17 -487
  74. package/dist/handlers/search.js +15 -326
  75. package/dist/handlers/session.js +28 -615
  76. package/dist/handlers/share.js +8 -184
  77. package/dist/handlers/shims.js +1 -464
  78. package/dist/handlers/skill.js +67 -449
  79. package/dist/handlers/survivors.js +1 -120
  80. package/dist/handlers/symbols.js +8 -109
  81. package/dist/handlers/syncops.js +4 -302
  82. package/dist/handlers/types.js +1 -27
  83. package/dist/harvest.js +5 -191
  84. package/dist/hours.js +7 -156
  85. package/dist/http-auth.js +3 -321
  86. package/dist/http-fast.js +21 -1137
  87. package/dist/icons.js +1 -47
  88. package/dist/index.js +2 -924
  89. package/dist/indexer.js +4 -145
  90. package/dist/intelligence.js +31 -261
  91. package/dist/internal-dispatch.js +3 -212
  92. package/dist/keyset.js +1 -110
  93. package/dist/knowledge-graph.js +12 -176
  94. package/dist/license.js +2 -441
  95. package/dist/logger.js +2 -199
  96. package/dist/maintenance.js +2 -148
  97. package/dist/mcp-client.js +6 -262
  98. package/dist/memory-artifacts.js +30 -449
  99. package/dist/migrate-prompt.js +2 -124
  100. package/dist/migrations.js +40 -655
  101. package/dist/performance.js +1 -228
  102. package/dist/presence.js +11 -140
  103. package/dist/priority-embed.js +5 -164
  104. package/dist/providers/embedding-provider.js +1 -196
  105. package/dist/readonly-gate.js +1 -29
  106. package/dist/rehydration.js +9 -157
  107. package/dist/reindex.js +1 -88
  108. package/dist/render-target.js +21 -514
  109. package/dist/render.js +4 -280
  110. package/dist/repl-guard.js +1 -173
  111. package/dist/replication-daemon-entrypoint.js +1 -31
  112. package/dist/replication-daemon.js +2 -262
  113. package/dist/resilience.js +1 -591
  114. package/dist/reverse-bridge.js +5 -360
  115. package/dist/security.js +1 -244
  116. package/dist/session-seen.js +3 -51
  117. package/dist/setup.js +1 -260
  118. package/dist/skill-author.js +5 -168
  119. package/dist/spec-kit.js +1 -191
  120. package/dist/sqlite-busy.js +1 -154
  121. package/dist/statusline.js +11 -315
  122. package/dist/sub-agent.js +13 -262
  123. package/dist/summarizer.js +13 -139
  124. package/dist/symbols.js +7 -283
  125. package/dist/sync.js +5 -359
  126. package/dist/tasks-dispatch.js +1 -84
  127. package/dist/tasks.js +1 -282
  128. package/dist/token-budget.js +1 -143
  129. package/dist/tool-analytics.js +7 -129
  130. package/dist/tool-annotations.js +1 -365
  131. package/dist/tool-manifest-v2.json +1 -1
  132. package/dist/tool-manifest.json +1 -1
  133. package/dist/tool-profiles.js +1 -75
  134. package/dist/trace-harvest.js +6 -244
  135. package/dist/types.js +1 -30
  136. package/dist/ui-dashboard.js +41 -50
  137. package/dist/ulid.js +1 -81
  138. package/dist/validate.js +1 -129
  139. package/dist/vault.js +1 -534
  140. package/dist/vectors.js +3 -184
  141. package/dist/version-check.js +4 -136
  142. package/dist/visibility.js +19 -155
  143. package/dist/wyrm-cli.js +98 -2464
  144. package/dist/wyrm-guard.js +14 -424
  145. package/dist/wyrm-loop.js +3 -150
  146. package/dist/wyrm-manifest.json +1 -1
  147. package/dist/wyrm-statusline-daemon.js +1 -11
  148. package/dist/wyrm-statusline.js +4 -56
  149. package/dist/wyrm-ui.js +9 -77
  150. 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};