@vinkius-core/mcp-fusion 2.6.0 → 2.8.0

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 (140) hide show
  1. package/dist/cli/fusion.d.ts +101 -0
  2. package/dist/cli/fusion.d.ts.map +1 -0
  3. package/dist/cli/fusion.js +333 -0
  4. package/dist/cli/fusion.js.map +1 -0
  5. package/dist/client/FusionClient.d.ts +122 -1
  6. package/dist/client/FusionClient.d.ts.map +1 -1
  7. package/dist/client/FusionClient.js +173 -11
  8. package/dist/client/FusionClient.js.map +1 -1
  9. package/dist/client/index.d.ts +2 -2
  10. package/dist/client/index.d.ts.map +1 -1
  11. package/dist/client/index.js +1 -1
  12. package/dist/client/index.js.map +1 -1
  13. package/dist/core/StandardSchema.d.ts +178 -0
  14. package/dist/core/StandardSchema.d.ts.map +1 -0
  15. package/dist/core/StandardSchema.js +166 -0
  16. package/dist/core/StandardSchema.js.map +1 -0
  17. package/dist/core/createGroup.d.ts +140 -0
  18. package/dist/core/createGroup.d.ts.map +1 -0
  19. package/dist/core/createGroup.js +133 -0
  20. package/dist/core/createGroup.js.map +1 -0
  21. package/dist/core/execution/ExecutionPipeline.d.ts.map +1 -1
  22. package/dist/core/execution/ExecutionPipeline.js +6 -2
  23. package/dist/core/execution/ExecutionPipeline.js.map +1 -1
  24. package/dist/core/index.d.ts +7 -1
  25. package/dist/core/index.d.ts.map +1 -1
  26. package/dist/core/index.js +6 -0
  27. package/dist/core/index.js.map +1 -1
  28. package/dist/core/initFusion.d.ts +201 -0
  29. package/dist/core/initFusion.d.ts.map +1 -0
  30. package/dist/core/initFusion.js +134 -0
  31. package/dist/core/initFusion.js.map +1 -0
  32. package/dist/core/response.d.ts +49 -2
  33. package/dist/core/response.d.ts.map +1 -1
  34. package/dist/core/response.js +27 -5
  35. package/dist/core/response.js.map +1 -1
  36. package/dist/index.d.ts +57 -9
  37. package/dist/index.d.ts.map +1 -1
  38. package/dist/index.js +30 -4
  39. package/dist/index.js.map +1 -1
  40. package/dist/introspection/BehaviorDigest.d.ts +112 -0
  41. package/dist/introspection/BehaviorDigest.d.ts.map +1 -0
  42. package/dist/introspection/BehaviorDigest.js +146 -0
  43. package/dist/introspection/BehaviorDigest.js.map +1 -0
  44. package/dist/introspection/CapabilityLockfile.d.ts +259 -0
  45. package/dist/introspection/CapabilityLockfile.d.ts.map +1 -0
  46. package/dist/introspection/CapabilityLockfile.js +391 -0
  47. package/dist/introspection/CapabilityLockfile.js.map +1 -0
  48. package/dist/introspection/ContractAwareSelfHealing.d.ts +90 -0
  49. package/dist/introspection/ContractAwareSelfHealing.d.ts.map +1 -0
  50. package/dist/introspection/ContractAwareSelfHealing.js +132 -0
  51. package/dist/introspection/ContractAwareSelfHealing.js.map +1 -0
  52. package/dist/introspection/ContractDiff.d.ts +91 -0
  53. package/dist/introspection/ContractDiff.d.ts.map +1 -0
  54. package/dist/introspection/ContractDiff.js +466 -0
  55. package/dist/introspection/ContractDiff.js.map +1 -0
  56. package/dist/introspection/CryptoAttestation.d.ts +143 -0
  57. package/dist/introspection/CryptoAttestation.d.ts.map +1 -0
  58. package/dist/introspection/CryptoAttestation.js +194 -0
  59. package/dist/introspection/CryptoAttestation.js.map +1 -0
  60. package/dist/introspection/EntitlementScanner.d.ts +124 -0
  61. package/dist/introspection/EntitlementScanner.d.ts.map +1 -0
  62. package/dist/introspection/EntitlementScanner.js +244 -0
  63. package/dist/introspection/EntitlementScanner.js.map +1 -0
  64. package/dist/introspection/GovernanceObserver.d.ts +88 -0
  65. package/dist/introspection/GovernanceObserver.d.ts.map +1 -0
  66. package/dist/introspection/GovernanceObserver.js +132 -0
  67. package/dist/introspection/GovernanceObserver.js.map +1 -0
  68. package/dist/introspection/SemanticProbe.d.ts +207 -0
  69. package/dist/introspection/SemanticProbe.d.ts.map +1 -0
  70. package/dist/introspection/SemanticProbe.js +255 -0
  71. package/dist/introspection/SemanticProbe.js.map +1 -0
  72. package/dist/introspection/TokenEconomics.d.ts +210 -0
  73. package/dist/introspection/TokenEconomics.d.ts.map +1 -0
  74. package/dist/introspection/TokenEconomics.js +286 -0
  75. package/dist/introspection/TokenEconomics.js.map +1 -0
  76. package/dist/introspection/ToolContract.d.ts +159 -0
  77. package/dist/introspection/ToolContract.d.ts.map +1 -0
  78. package/dist/introspection/ToolContract.js +191 -0
  79. package/dist/introspection/ToolContract.js.map +1 -0
  80. package/dist/introspection/canonicalize.d.ts +20 -0
  81. package/dist/introspection/canonicalize.d.ts.map +1 -0
  82. package/dist/introspection/canonicalize.js +51 -0
  83. package/dist/introspection/canonicalize.js.map +1 -0
  84. package/dist/introspection/index.d.ts +20 -0
  85. package/dist/introspection/index.d.ts.map +1 -1
  86. package/dist/introspection/index.js +20 -0
  87. package/dist/introspection/index.js.map +1 -1
  88. package/dist/observability/DebugObserver.d.ts +26 -1
  89. package/dist/observability/DebugObserver.d.ts.map +1 -1
  90. package/dist/observability/DebugObserver.js +8 -1
  91. package/dist/observability/DebugObserver.js.map +1 -1
  92. package/dist/observability/index.d.ts +1 -1
  93. package/dist/observability/index.d.ts.map +1 -1
  94. package/dist/observability/index.js.map +1 -1
  95. package/dist/presenter/ZodDescriptionExtractor.d.ts +54 -0
  96. package/dist/presenter/ZodDescriptionExtractor.d.ts.map +1 -0
  97. package/dist/presenter/ZodDescriptionExtractor.js +131 -0
  98. package/dist/presenter/ZodDescriptionExtractor.js.map +1 -0
  99. package/dist/presenter/definePresenter.d.ts +172 -0
  100. package/dist/presenter/definePresenter.d.ts.map +1 -0
  101. package/dist/presenter/definePresenter.js +96 -0
  102. package/dist/presenter/definePresenter.js.map +1 -0
  103. package/dist/presenter/index.d.ts +3 -0
  104. package/dist/presenter/index.d.ts.map +1 -1
  105. package/dist/presenter/index.js +4 -0
  106. package/dist/presenter/index.js.map +1 -1
  107. package/dist/server/DevServer.d.ts +96 -0
  108. package/dist/server/DevServer.d.ts.map +1 -0
  109. package/dist/server/DevServer.js +187 -0
  110. package/dist/server/DevServer.js.map +1 -0
  111. package/dist/server/ServerAttachment.d.ts +41 -0
  112. package/dist/server/ServerAttachment.d.ts.map +1 -1
  113. package/dist/server/ServerAttachment.js +25 -1
  114. package/dist/server/ServerAttachment.js.map +1 -1
  115. package/dist/server/autoDiscover.d.ts +63 -0
  116. package/dist/server/autoDiscover.d.ts.map +1 -0
  117. package/dist/server/autoDiscover.js +157 -0
  118. package/dist/server/autoDiscover.js.map +1 -0
  119. package/dist/server/index.d.ts +4 -0
  120. package/dist/server/index.d.ts.map +1 -1
  121. package/dist/server/index.js +4 -0
  122. package/dist/server/index.js.map +1 -1
  123. package/dist/state-sync/PolicyValidator.d.ts +36 -0
  124. package/dist/state-sync/PolicyValidator.d.ts.map +1 -1
  125. package/dist/state-sync/PolicyValidator.js +35 -0
  126. package/dist/state-sync/PolicyValidator.js.map +1 -1
  127. package/dist/state-sync/ResponseDecorator.d.ts.map +1 -1
  128. package/dist/state-sync/ResponseDecorator.js +2 -1
  129. package/dist/state-sync/ResponseDecorator.js.map +1 -1
  130. package/dist/state-sync/StateSyncLayer.d.ts +5 -4
  131. package/dist/state-sync/StateSyncLayer.d.ts.map +1 -1
  132. package/dist/state-sync/StateSyncLayer.js +35 -4
  133. package/dist/state-sync/StateSyncLayer.js.map +1 -1
  134. package/dist/state-sync/index.d.ts +3 -1
  135. package/dist/state-sync/index.d.ts.map +1 -1
  136. package/dist/state-sync/index.js +1 -0
  137. package/dist/state-sync/index.js.map +1 -1
  138. package/dist/state-sync/types.d.ts +62 -0
  139. package/dist/state-sync/types.d.ts.map +1 -1
  140. package/package.json +45 -1
@@ -0,0 +1,101 @@
1
+ #!/usr/bin/env node
2
+ import { type PromptBuilderLike } from '../introspection/CapabilityLockfile.js';
3
+ /**
4
+ * Step status for CLI progress reporting.
5
+ * @internal
6
+ */
7
+ export type StepStatus = 'pending' | 'running' | 'done' | 'failed';
8
+ /**
9
+ * A progress step emitted during CLI operations.
10
+ * @internal
11
+ */
12
+ export interface ProgressStep {
13
+ /** Step identifier */
14
+ readonly id: string;
15
+ /** Human-readable label */
16
+ readonly label: string;
17
+ /** Current status */
18
+ readonly status: StepStatus;
19
+ /** Optional detail (e.g. "12 tools, 3 prompts") */
20
+ readonly detail?: string;
21
+ /** Duration in milliseconds (set when done/failed) */
22
+ readonly durationMs?: number;
23
+ }
24
+ /**
25
+ * Callback that receives progress updates.
26
+ * Default implementation writes to stderr like Composer / Yarn.
27
+ * @internal
28
+ */
29
+ export type ProgressReporter = (step: ProgressStep) => void;
30
+ /**
31
+ * Create the default pretty-print progress reporter.
32
+ * Output goes to stderr so it doesn't pollute piped stdout.
33
+ * @internal exported for testing
34
+ */
35
+ export declare function createDefaultReporter(): ProgressReporter;
36
+ /**
37
+ * A progress tracker that drives step-by-step progress reporting.
38
+ * @internal exported for testing
39
+ */
40
+ export declare class ProgressTracker {
41
+ private readonly reporter;
42
+ private startTimes;
43
+ constructor(reporter?: ProgressReporter);
44
+ /** Mark a step as running */
45
+ start(id: string, label: string): void;
46
+ /** Mark a step as completed */
47
+ done(id: string, label: string, detail?: string): void;
48
+ /** Mark a step as failed */
49
+ fail(id: string, label: string, detail?: string): void;
50
+ private elapsed;
51
+ }
52
+ /** @internal exported for testing */
53
+ export declare const MCP_FUSION_VERSION = "1.1.0";
54
+ /** @internal exported for testing */
55
+ export declare const HELP: string;
56
+ /** @internal exported for testing */
57
+ export interface CliArgs {
58
+ command: string;
59
+ check: boolean;
60
+ server: string | undefined;
61
+ name: string | undefined;
62
+ cwd: string;
63
+ help: boolean;
64
+ }
65
+ /** @internal exported for testing */
66
+ export declare function parseArgs(argv: string[]): CliArgs;
67
+ /**
68
+ * Duck-typed interface for objects that can provide tool builders.
69
+ * Supports both ToolRegistry and FusionInstance.
70
+ */
71
+ /** @internal exported for testing */
72
+ export interface RegistryLike {
73
+ getBuilders(): Iterable<import('../core/types.js').ToolBuilder<unknown>>;
74
+ }
75
+ /**
76
+ * Duck-typed interface for objects that can provide prompt builders.
77
+ * Supports PromptRegistry.
78
+ */
79
+ /** @internal exported for testing */
80
+ export interface PromptRegistryLike {
81
+ getBuilders?(): Iterable<PromptBuilderLike>;
82
+ }
83
+ /**
84
+ * Attempt to load and resolve a tool registry from a server entrypoint.
85
+ *
86
+ * Supports common export patterns:
87
+ * - `export const registry = new ToolRegistry()`
88
+ * - `export default { registry }`
89
+ * - `export const fusion = initFusion()`
90
+ *
91
+ * @internal
92
+ */
93
+ /** @internal exported for testing */
94
+ export declare function resolveRegistry(serverPath: string): Promise<{
95
+ registry: RegistryLike;
96
+ name: string;
97
+ promptRegistry?: PromptRegistryLike;
98
+ }>;
99
+ /** @internal exported for testing */
100
+ export declare function commandLock(args: CliArgs, reporter?: ProgressReporter): Promise<void>;
101
+ //# sourceMappingURL=fusion.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fusion.d.ts","sourceRoot":"","sources":["../../src/cli/fusion.ts"],"names":[],"mappings":";AAuBA,OAAO,EAOH,KAAK,iBAAiB,EACzB,MAAM,wCAAwC,CAAC;AAMhD;;;GAGG;AACH,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,SAAS,GAAG,MAAM,GAAG,QAAQ,CAAC;AAEnE;;;GAGG;AACH,MAAM,WAAW,YAAY;IACzB,sBAAsB;IACtB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,2BAA2B;IAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,qBAAqB;IACrB,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAC5B,mDAAmD;IACnD,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,sDAAsD;IACtD,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAChC;AAED;;;;GAIG;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,IAAI,EAAE,YAAY,KAAK,IAAI,CAAC;AAU5D;;;;GAIG;AACH,wBAAgB,qBAAqB,IAAI,gBAAgB,CAOxD;AAED;;;GAGG;AACH,qBAAa,eAAe;IACxB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAmB;IAC5C,OAAO,CAAC,UAAU,CAA6B;gBAEnC,QAAQ,CAAC,EAAE,gBAAgB;IAIvC,6BAA6B;IAC7B,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAKtC,+BAA+B;IAC/B,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI;IAStD,4BAA4B;IAC5B,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI;IAStD,OAAO,CAAC,OAAO;CAMlB;AAMD,qCAAqC;AACrC,eAAO,MAAM,kBAAkB,UAAU,CAAC;AAE1C,qCAAqC;AACrC,eAAO,MAAM,IAAI,QAiBT,CAAC;AAMT,qCAAqC;AACrC,MAAM,WAAW,OAAO;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,OAAO,CAAC;CACjB;AAED,qCAAqC;AACrC,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CA0CjD;AAMD;;;GAGG;AACH,qCAAqC;AACrC,MAAM,WAAW,YAAY;IACzB,WAAW,IAAI,QAAQ,CAAC,OAAO,kBAAkB,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC;CAC5E;AAED;;;GAGG;AACH,qCAAqC;AACrC,MAAM,WAAW,kBAAkB;IAC/B,WAAW,CAAC,IAAI,QAAQ,CAAC,iBAAiB,CAAC,CAAC;CAC/C;AAED;;;;;;;;;GASG;AACH,qCAAqC;AACrC,wBAAsB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,QAAQ,EAAE,YAAY,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,cAAc,CAAC,EAAE,kBAAkB,CAAA;CAAE,CAAC,CA+DhJ;AAMD,qCAAqC;AACrC,wBAAsB,WAAW,CAAC,IAAI,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAgF3F"}
@@ -0,0 +1,333 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * MCP Fusion CLI — `fusion`
4
+ *
5
+ * Commands:
6
+ *
7
+ * fusion lock [--server <entrypoint>] [--name <serverName>]
8
+ * Generate or update `mcp-fusion.lock`.
9
+ *
10
+ * fusion lock --check [--server <entrypoint>]
11
+ * Verify the lockfile matches the current server.
12
+ * Exits 0 if up-to-date, 1 if stale (CI gate).
13
+ *
14
+ * The lockfile captures the complete behavioral surface of your
15
+ * MCP Fusion server — tool contracts, cognitive guardrails,
16
+ * entitlements, and token economics — in a deterministic,
17
+ * git-diffable format.
18
+ *
19
+ * @module
20
+ */
21
+ import { resolve } from 'node:path';
22
+ import { pathToFileURL } from 'node:url';
23
+ import { compileContracts } from '../introspection/ToolContract.js';
24
+ import { generateLockfile, writeLockfile, readLockfile, checkLockfile, serializeLockfile, LOCKFILE_NAME, } from '../introspection/CapabilityLockfile.js';
25
+ /** Icon map for each step status */
26
+ const STATUS_ICONS = {
27
+ pending: '○',
28
+ running: '◐',
29
+ done: '●',
30
+ failed: '✗',
31
+ };
32
+ /**
33
+ * Create the default pretty-print progress reporter.
34
+ * Output goes to stderr so it doesn't pollute piped stdout.
35
+ * @internal exported for testing
36
+ */
37
+ export function createDefaultReporter() {
38
+ return (step) => {
39
+ const icon = STATUS_ICONS[step.status];
40
+ const timing = step.durationMs !== undefined ? ` (${step.durationMs}ms)` : '';
41
+ const detail = step.detail ? ` — ${step.detail}` : '';
42
+ process.stderr.write(` ${icon} ${step.label}${detail}${timing}\n`);
43
+ };
44
+ }
45
+ /**
46
+ * A progress tracker that drives step-by-step progress reporting.
47
+ * @internal exported for testing
48
+ */
49
+ export class ProgressTracker {
50
+ reporter;
51
+ startTimes = new Map();
52
+ constructor(reporter) {
53
+ this.reporter = reporter ?? createDefaultReporter();
54
+ }
55
+ /** Mark a step as running */
56
+ start(id, label) {
57
+ this.startTimes.set(id, Date.now());
58
+ this.reporter({ id, label, status: 'running' });
59
+ }
60
+ /** Mark a step as completed */
61
+ done(id, label, detail) {
62
+ const durationMs = this.elapsed(id);
63
+ this.reporter({
64
+ id, label, status: 'done',
65
+ ...(detail !== undefined ? { detail } : {}),
66
+ ...(durationMs !== undefined ? { durationMs } : {}),
67
+ });
68
+ }
69
+ /** Mark a step as failed */
70
+ fail(id, label, detail) {
71
+ const durationMs = this.elapsed(id);
72
+ this.reporter({
73
+ id, label, status: 'failed',
74
+ ...(detail !== undefined ? { detail } : {}),
75
+ ...(durationMs !== undefined ? { durationMs } : {}),
76
+ });
77
+ }
78
+ elapsed(id) {
79
+ const start = this.startTimes.get(id);
80
+ if (start === undefined)
81
+ return undefined;
82
+ this.startTimes.delete(id);
83
+ return Date.now() - start;
84
+ }
85
+ }
86
+ // ============================================================================
87
+ // Constants
88
+ // ============================================================================
89
+ /** @internal exported for testing */
90
+ export const MCP_FUSION_VERSION = '1.1.0';
91
+ /** @internal exported for testing */
92
+ export const HELP = `
93
+ fusion — MCP Fusion Capability Lockfile CLI
94
+
95
+ USAGE
96
+ fusion lock Generate or update ${LOCKFILE_NAME}
97
+ fusion lock --check Verify lockfile is up to date (CI gate)
98
+
99
+ OPTIONS
100
+ --server, -s <path> Path to server entrypoint (default: auto-discover)
101
+ --name, -n <name> Server name for lockfile header
102
+ --cwd <dir> Project root directory (default: process.cwd())
103
+ --help, -h Show this help message
104
+
105
+ EXAMPLES
106
+ fusion lock
107
+ fusion lock --check
108
+ fusion lock --server ./src/server.ts --name my-server
109
+ `.trim();
110
+ /** @internal exported for testing */
111
+ export function parseArgs(argv) {
112
+ const args = argv.slice(2);
113
+ const result = {
114
+ command: '',
115
+ check: false,
116
+ server: undefined,
117
+ name: undefined,
118
+ cwd: process.cwd(),
119
+ help: false,
120
+ };
121
+ for (let i = 0; i < args.length; i++) {
122
+ const arg = args[i];
123
+ switch (arg) {
124
+ case 'lock':
125
+ result.command = 'lock';
126
+ break;
127
+ case '--check':
128
+ result.check = true;
129
+ break;
130
+ case '-s':
131
+ case '--server':
132
+ result.server = args[++i];
133
+ break;
134
+ case '-n':
135
+ case '--name':
136
+ result.name = args[++i];
137
+ break;
138
+ case '--cwd':
139
+ result.cwd = args[++i] ?? process.cwd();
140
+ break;
141
+ case '-h':
142
+ case '--help':
143
+ result.help = true;
144
+ break;
145
+ default:
146
+ if (!result.command)
147
+ result.command = arg;
148
+ break;
149
+ }
150
+ }
151
+ return result;
152
+ }
153
+ /**
154
+ * Attempt to load and resolve a tool registry from a server entrypoint.
155
+ *
156
+ * Supports common export patterns:
157
+ * - `export const registry = new ToolRegistry()`
158
+ * - `export default { registry }`
159
+ * - `export const fusion = initFusion()`
160
+ *
161
+ * @internal
162
+ */
163
+ /** @internal exported for testing */
164
+ export async function resolveRegistry(serverPath) {
165
+ const absolutePath = resolve(serverPath);
166
+ const fileUrl = pathToFileURL(absolutePath).href;
167
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
168
+ const mod = await import(fileUrl);
169
+ /** Extract prompt registry from a module-like object */
170
+ function extractPrompts(obj) {
171
+ // Look for promptRegistry, prompts, or promptsRegistry
172
+ for (const key of ['promptRegistry', 'prompts', 'promptsRegistry']) {
173
+ const candidate = obj[key];
174
+ if (candidate && typeof candidate === 'object' && candidate !== null) {
175
+ return candidate;
176
+ }
177
+ }
178
+ return undefined;
179
+ }
180
+ // Strategy 1: Named `registry` export (ToolRegistry pattern)
181
+ if (mod.registry && typeof mod.registry.getBuilders === 'function') {
182
+ const pr = extractPrompts(mod);
183
+ return {
184
+ registry: mod.registry,
185
+ name: mod.serverName ?? 'mcp-fusion-server',
186
+ ...(pr ? { promptRegistry: pr } : {}),
187
+ };
188
+ }
189
+ // Strategy 2: Named `fusion` export (initFusion pattern)
190
+ if (mod.fusion && mod.fusion.registry && typeof mod.fusion.registry.getBuilders === 'function') {
191
+ const pr = extractPrompts(mod.fusion);
192
+ return {
193
+ registry: mod.fusion.registry,
194
+ name: mod.fusion.name ?? 'mcp-fusion-server',
195
+ ...(pr ? { promptRegistry: pr } : {}),
196
+ };
197
+ }
198
+ // Strategy 3: Default export with registry
199
+ if (mod.default) {
200
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
201
+ const def = mod.default;
202
+ if (def.registry && typeof def.registry.getBuilders === 'function') {
203
+ const pr = extractPrompts(def);
204
+ return {
205
+ registry: def.registry,
206
+ name: def.serverName ?? 'mcp-fusion-server',
207
+ ...(pr ? { promptRegistry: pr } : {}),
208
+ };
209
+ }
210
+ if (typeof def.getBuilders === 'function') {
211
+ return { registry: def, name: 'mcp-fusion-server' };
212
+ }
213
+ }
214
+ throw new Error(`Could not resolve a ToolRegistry from "${serverPath}".\n` +
215
+ `Expected one of:\n` +
216
+ ` export const registry = new ToolRegistry() // named 'registry' with getBuilders()\n` +
217
+ ` export const fusion = initFusion() // named 'fusion' with .registry\n` +
218
+ ` export default { registry } // default export with .registry`);
219
+ }
220
+ // ============================================================================
221
+ // Commands
222
+ // ============================================================================
223
+ /** @internal exported for testing */
224
+ export async function commandLock(args, reporter) {
225
+ const progress = new ProgressTracker(reporter);
226
+ if (!args.server) {
227
+ console.error('Error: --server <path> is required.\n');
228
+ console.error('Usage: fusion lock --server ./src/server.ts');
229
+ process.exit(1);
230
+ }
231
+ const mode = args.check ? 'Verifying' : 'Generating';
232
+ process.stderr.write(`\n fusion lock — ${mode} ${LOCKFILE_NAME}\n\n`);
233
+ // Step 1: Resolve registry
234
+ progress.start('resolve', 'Resolving server entrypoint');
235
+ const { registry, name, promptRegistry } = await resolveRegistry(args.server);
236
+ const serverName = args.name ?? name;
237
+ progress.done('resolve', 'Resolving server entrypoint', serverName);
238
+ // Step 2: Compile tool contracts
239
+ progress.start('compile', 'Compiling tool contracts');
240
+ const builders = [...registry.getBuilders()];
241
+ const contracts = compileContracts(builders);
242
+ const toolCount = Object.keys(contracts).length;
243
+ progress.done('compile', 'Compiling tool contracts', `${toolCount} tool${toolCount !== 1 ? 's' : ''}`);
244
+ // Step 3: Discover prompts
245
+ progress.start('prompts', 'Discovering prompts');
246
+ const promptBuilders = [];
247
+ if (promptRegistry && typeof promptRegistry.getBuilders === 'function') {
248
+ promptBuilders.push(...promptRegistry.getBuilders());
249
+ }
250
+ const options = promptBuilders.length > 0 ? { prompts: promptBuilders } : undefined;
251
+ const promptCount = promptBuilders.length;
252
+ progress.done('prompts', 'Discovering prompts', `${promptCount} prompt${promptCount !== 1 ? 's' : ''}`);
253
+ if (args.check) {
254
+ // ── Check Mode ──
255
+ progress.start('read', 'Reading existing lockfile');
256
+ const existing = await readLockfile(args.cwd);
257
+ if (!existing) {
258
+ progress.fail('read', 'Reading existing lockfile', 'not found');
259
+ console.error(`\n✗ No ${LOCKFILE_NAME} found. Run \`fusion lock\` to generate.`);
260
+ process.exit(1);
261
+ }
262
+ progress.done('read', 'Reading existing lockfile');
263
+ progress.start('verify', 'Verifying integrity');
264
+ const result = checkLockfile(existing, contracts, options);
265
+ if (result.ok) {
266
+ progress.done('verify', 'Verifying integrity', 'up to date');
267
+ console.log(`\n✓ ${LOCKFILE_NAME} is up to date.`);
268
+ process.exit(0);
269
+ }
270
+ else {
271
+ progress.fail('verify', 'Verifying integrity', 'stale');
272
+ console.error(`\n✗ ${result.message}`);
273
+ if (result.added.length > 0)
274
+ console.error(` + Tools added: ${result.added.join(', ')}`);
275
+ if (result.removed.length > 0)
276
+ console.error(` - Tools removed: ${result.removed.join(', ')}`);
277
+ if (result.changed.length > 0)
278
+ console.error(` ~ Tools changed: ${result.changed.join(', ')}`);
279
+ if (result.addedPrompts.length > 0)
280
+ console.error(` + Prompts added: ${result.addedPrompts.join(', ')}`);
281
+ if (result.removedPrompts.length > 0)
282
+ console.error(` - Prompts removed: ${result.removedPrompts.join(', ')}`);
283
+ if (result.changedPrompts.length > 0)
284
+ console.error(` ~ Prompts changed: ${result.changedPrompts.join(', ')}`);
285
+ process.exit(1);
286
+ }
287
+ }
288
+ else {
289
+ // ── Generate Mode ──
290
+ progress.start('generate', 'Computing behavioral digests');
291
+ const lockfile = generateLockfile(serverName, contracts, MCP_FUSION_VERSION, options);
292
+ progress.done('generate', 'Computing behavioral digests');
293
+ progress.start('write', `Writing ${LOCKFILE_NAME}`);
294
+ await writeLockfile(lockfile, args.cwd);
295
+ progress.done('write', `Writing ${LOCKFILE_NAME}`);
296
+ const tc = Object.keys(lockfile.capabilities.tools).length;
297
+ const pc = Object.keys(lockfile.capabilities.prompts ?? {}).length;
298
+ const parts = [`${tc} tool${tc !== 1 ? 's' : ''}`];
299
+ if (pc > 0)
300
+ parts.push(`${pc} prompt${pc !== 1 ? 's' : ''}`);
301
+ console.log(`\n✓ ${LOCKFILE_NAME} generated (${parts.join(', ')}).`);
302
+ console.log(` Integrity: ${lockfile.integrityDigest}`);
303
+ }
304
+ }
305
+ // ============================================================================
306
+ // Entry Point
307
+ // ============================================================================
308
+ async function main() {
309
+ const args = parseArgs(process.argv);
310
+ if (args.help || !args.command) {
311
+ console.log(HELP);
312
+ process.exit(args.help ? 0 : 1);
313
+ }
314
+ switch (args.command) {
315
+ case 'lock':
316
+ await commandLock(args);
317
+ break;
318
+ default:
319
+ console.error(`Unknown command: "${args.command}"\n`);
320
+ console.log(HELP);
321
+ process.exit(1);
322
+ }
323
+ }
324
+ /* c8 ignore next 6 — CLI entry-point guard */
325
+ const isCLI = typeof process !== 'undefined' &&
326
+ process.argv[1]?.endsWith('fusion') || process.argv[1]?.endsWith('fusion.js');
327
+ if (isCLI) {
328
+ main().catch((err) => {
329
+ console.error(`Error: ${err.message}`);
330
+ process.exit(1);
331
+ });
332
+ }
333
+ //# sourceMappingURL=fusion.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fusion.js","sourceRoot":"","sources":["../../src/cli/fusion.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AACpE,OAAO,EACH,gBAAgB,EAChB,aAAa,EACb,YAAY,EACZ,aAAa,EACb,iBAAiB,EACjB,aAAa,GAEhB,MAAM,wCAAwC,CAAC;AAoChD,oCAAoC;AACpC,MAAM,YAAY,GAA+B;IAC7C,OAAO,EAAE,GAAG;IACZ,OAAO,EAAE,GAAG;IACZ,IAAI,EAAE,GAAG;IACT,MAAM,EAAE,GAAG;CACd,CAAC;AAEF;;;;GAIG;AACH,MAAM,UAAU,qBAAqB;IACjC,OAAO,CAAC,IAAkB,EAAQ,EAAE;QAChC,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACvC,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,UAAU,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9E,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACtD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,IAAI,IAAI,IAAI,CAAC,KAAK,GAAG,MAAM,GAAG,MAAM,IAAI,CAAC,CAAC;IACxE,CAAC,CAAC;AACN,CAAC;AAED;;;GAGG;AACH,MAAM,OAAO,eAAe;IACP,QAAQ,CAAmB;IACpC,UAAU,GAAG,IAAI,GAAG,EAAkB,CAAC;IAE/C,YAAY,QAA2B;QACnC,IAAI,CAAC,QAAQ,GAAG,QAAQ,IAAI,qBAAqB,EAAE,CAAC;IACxD,CAAC;IAED,6BAA6B;IAC7B,KAAK,CAAC,EAAU,EAAE,KAAa;QAC3B,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;QACpC,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;IACpD,CAAC;IAED,+BAA+B;IAC/B,IAAI,CAAC,EAAU,EAAE,KAAa,EAAE,MAAe;QAC3C,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QACpC,IAAI,CAAC,QAAQ,CAAC;YACV,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM;YACzB,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC3C,GAAG,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACtD,CAAC,CAAC;IACP,CAAC;IAED,4BAA4B;IAC5B,IAAI,CAAC,EAAU,EAAE,KAAa,EAAE,MAAe;QAC3C,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QACpC,IAAI,CAAC,QAAQ,CAAC;YACV,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ;YAC3B,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC3C,GAAG,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACtD,CAAC,CAAC;IACP,CAAC;IAEO,OAAO,CAAC,EAAU;QACtB,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACtC,IAAI,KAAK,KAAK,SAAS;YAAE,OAAO,SAAS,CAAC;QAC1C,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAC3B,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC;IAC9B,CAAC;CACJ;AAED,+EAA+E;AAC/E,YAAY;AACZ,+EAA+E;AAE/E,qCAAqC;AACrC,MAAM,CAAC,MAAM,kBAAkB,GAAG,OAAO,CAAC;AAE1C,qCAAqC;AACrC,MAAM,CAAC,MAAM,IAAI,GAAG;;;;2DAIuC,aAAa;;;;;;;;;;;;;CAavE,CAAC,IAAI,EAAE,CAAC;AAgBT,qCAAqC;AACrC,MAAM,UAAU,SAAS,CAAC,IAAc;IACpC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAC3B,MAAM,MAAM,GAAY;QACpB,OAAO,EAAE,EAAE;QACX,KAAK,EAAE,KAAK;QACZ,MAAM,EAAE,SAAS;QACjB,IAAI,EAAE,SAAS;QACf,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE;QAClB,IAAI,EAAE,KAAK;KACd,CAAC;IAEF,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACnC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAE,CAAC;QACrB,QAAQ,GAAG,EAAE,CAAC;YACV,KAAK,MAAM;gBACP,MAAM,CAAC,OAAO,GAAG,MAAM,CAAC;gBACxB,MAAM;YACV,KAAK,SAAS;gBACV,MAAM,CAAC,KAAK,GAAG,IAAI,CAAC;gBACpB,MAAM;YACV,KAAK,IAAI,CAAC;YACV,KAAK,UAAU;gBACX,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;gBAC1B,MAAM;YACV,KAAK,IAAI,CAAC;YACV,KAAK,QAAQ;gBACT,MAAM,CAAC,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;gBACxB,MAAM;YACV,KAAK,OAAO;gBACR,MAAM,CAAC,GAAG,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;gBACxC,MAAM;YACV,KAAK,IAAI,CAAC;YACV,KAAK,QAAQ;gBACT,MAAM,CAAC,IAAI,GAAG,IAAI,CAAC;gBACnB,MAAM;YACV;gBACI,IAAI,CAAC,MAAM,CAAC,OAAO;oBAAE,MAAM,CAAC,OAAO,GAAG,GAAG,CAAC;gBAC1C,MAAM;QACd,CAAC;IACL,CAAC;IAED,OAAO,MAAM,CAAC;AAClB,CAAC;AAwBD;;;;;;;;;GASG;AACH,qCAAqC;AACrC,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,UAAkB;IACpD,MAAM,YAAY,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IACzC,MAAM,OAAO,GAAG,aAAa,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC;IAEjD,mEAAmE;IACnE,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,CAAC;IAElC,wDAAwD;IACxD,SAAS,cAAc,CAAC,GAA4B;QAChD,uDAAuD;QACvD,KAAK,MAAM,GAAG,IAAI,CAAC,gBAAgB,EAAE,SAAS,EAAE,iBAAiB,CAAC,EAAE,CAAC;YACjE,MAAM,SAAS,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;YAC3B,IAAI,SAAS,IAAI,OAAO,SAAS,KAAK,QAAQ,IAAI,SAAS,KAAK,IAAI,EAAE,CAAC;gBACnE,OAAO,SAA+B,CAAC;YAC3C,CAAC;QACL,CAAC;QACD,OAAO,SAAS,CAAC;IACrB,CAAC;IAED,6DAA6D;IAC7D,IAAI,GAAG,CAAC,QAAQ,IAAI,OAAO,GAAG,CAAC,QAAQ,CAAC,WAAW,KAAK,UAAU,EAAE,CAAC;QACjE,MAAM,EAAE,GAAG,cAAc,CAAC,GAA8B,CAAC,CAAC;QAC1D,OAAO;YACH,QAAQ,EAAE,GAAG,CAAC,QAAwB;YACtC,IAAI,EAAE,GAAG,CAAC,UAAU,IAAI,mBAAmB;YAC3C,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACxC,CAAC;IACN,CAAC;IAED,yDAAyD;IACzD,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC,QAAQ,IAAI,OAAO,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,WAAW,KAAK,UAAU,EAAE,CAAC;QAC7F,MAAM,EAAE,GAAG,cAAc,CAAC,GAAG,CAAC,MAAiC,CAAC,CAAC;QACjE,OAAO;YACH,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,QAAwB;YAC7C,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,IAAI,IAAI,mBAAmB;YAC5C,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACxC,CAAC;IACN,CAAC;IAED,2CAA2C;IAC3C,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;QACd,+GAA+G;QAC/G,MAAM,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC;QACxB,IAAI,GAAG,CAAC,QAAQ,IAAI,OAAO,GAAG,CAAC,QAAQ,CAAC,WAAW,KAAK,UAAU,EAAE,CAAC;YACjE,MAAM,EAAE,GAAG,cAAc,CAAC,GAA8B,CAAC,CAAC;YAC1D,OAAO;gBACH,QAAQ,EAAE,GAAG,CAAC,QAAwB;gBACtC,IAAI,EAAG,GAAG,CAAC,UAAqB,IAAI,mBAAmB;gBACvD,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aACxC,CAAC;QACN,CAAC;QACD,IAAI,OAAO,GAAG,CAAC,WAAW,KAAK,UAAU,EAAE,CAAC;YACxC,OAAO,EAAE,QAAQ,EAAE,GAAmB,EAAE,IAAI,EAAE,mBAAmB,EAAE,CAAC;QACxE,CAAC;IACL,CAAC;IAED,MAAM,IAAI,KAAK,CACX,0CAA0C,UAAU,MAAM;QAC1D,oBAAoB;QACpB,wFAAwF;QACxF,mFAAmF;QACnF,iFAAiF,CACpF,CAAC;AACN,CAAC;AAED,+EAA+E;AAC/E,WAAW;AACX,+EAA+E;AAE/E,qCAAqC;AACrC,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,IAAa,EAAE,QAA2B;IACxE,MAAM,QAAQ,GAAG,IAAI,eAAe,CAAC,QAAQ,CAAC,CAAC;IAE/C,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,uCAAuC,CAAC,CAAC;QACvD,OAAO,CAAC,KAAK,CAAC,6CAA6C,CAAC,CAAC;QAC7D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;IAED,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,YAAY,CAAC;IACrD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,qBAAqB,IAAI,IAAI,aAAa,MAAM,CAAC,CAAC;IAEvE,2BAA2B;IAC3B,QAAQ,CAAC,KAAK,CAAC,SAAS,EAAE,6BAA6B,CAAC,CAAC;IACzD,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,cAAc,EAAE,GAAG,MAAM,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC9E,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC;IACrC,QAAQ,CAAC,IAAI,CAAC,SAAS,EAAE,6BAA6B,EAAE,UAAU,CAAC,CAAC;IAEpE,iCAAiC;IACjC,QAAQ,CAAC,KAAK,CAAC,SAAS,EAAE,0BAA0B,CAAC,CAAC;IACtD,MAAM,QAAQ,GAAG,CAAC,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC;IAC7C,MAAM,SAAS,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IAC7C,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC;IAChD,QAAQ,CAAC,IAAI,CAAC,SAAS,EAAE,0BAA0B,EAAE,GAAG,SAAS,QAAQ,SAAS,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAEvG,2BAA2B;IAC3B,QAAQ,CAAC,KAAK,CAAC,SAAS,EAAE,qBAAqB,CAAC,CAAC;IACjD,MAAM,cAAc,GAAwB,EAAE,CAAC;IAC/C,IAAI,cAAc,IAAI,OAAO,cAAc,CAAC,WAAW,KAAK,UAAU,EAAE,CAAC;QACrE,cAAc,CAAC,IAAI,CAAC,GAAG,cAAc,CAAC,WAAW,EAAE,CAAC,CAAC;IACzD,CAAC;IACD,MAAM,OAAO,GAAG,cAAc,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,cAAc,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;IACpF,MAAM,WAAW,GAAG,cAAc,CAAC,MAAM,CAAC;IAC1C,QAAQ,CAAC,IAAI,CAAC,SAAS,EAAE,qBAAqB,EAAE,GAAG,WAAW,UAAU,WAAW,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAExG,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QACb,mBAAmB;QACnB,QAAQ,CAAC,KAAK,CAAC,MAAM,EAAE,2BAA2B,CAAC,CAAC;QACpD,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC9C,IAAI,CAAC,QAAQ,EAAE,CAAC;YACZ,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,2BAA2B,EAAE,WAAW,CAAC,CAAC;YAChE,OAAO,CAAC,KAAK,CAAC,UAAU,aAAa,0CAA0C,CAAC,CAAC;YACjF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACpB,CAAC;QACD,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,2BAA2B,CAAC,CAAC;QAEnD,QAAQ,CAAC,KAAK,CAAC,QAAQ,EAAE,qBAAqB,CAAC,CAAC;QAChD,MAAM,MAAM,GAAG,aAAa,CAAC,QAAQ,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;QAC3D,IAAI,MAAM,CAAC,EAAE,EAAE,CAAC;YACZ,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,qBAAqB,EAAE,YAAY,CAAC,CAAC;YAC7D,OAAO,CAAC,GAAG,CAAC,OAAO,aAAa,iBAAiB,CAAC,CAAC;YACnD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACpB,CAAC;aAAM,CAAC;YACJ,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,qBAAqB,EAAE,OAAO,CAAC,CAAC;YACxD,OAAO,CAAC,KAAK,CAAC,OAAO,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;YACvC,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC;gBAAE,OAAO,CAAC,KAAK,CAAC,oBAAoB,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAC1F,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC;gBAAE,OAAO,CAAC,KAAK,CAAC,sBAAsB,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAChG,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC;gBAAE,OAAO,CAAC,KAAK,CAAC,sBAAsB,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAChG,IAAI,MAAM,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC;gBAAE,OAAO,CAAC,KAAK,CAAC,sBAAsB,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAC1G,IAAI,MAAM,CAAC,cAAc,CAAC,MAAM,GAAG,CAAC;gBAAE,OAAO,CAAC,KAAK,CAAC,wBAAwB,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAChH,IAAI,MAAM,CAAC,cAAc,CAAC,MAAM,GAAG,CAAC;gBAAE,OAAO,CAAC,KAAK,CAAC,wBAAwB,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAChH,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACpB,CAAC;IACL,CAAC;SAAM,CAAC;QACJ,sBAAsB;QACtB,QAAQ,CAAC,KAAK,CAAC,UAAU,EAAE,8BAA8B,CAAC,CAAC;QAC3D,MAAM,QAAQ,GAAG,gBAAgB,CAAC,UAAU,EAAE,SAAS,EAAE,kBAAkB,EAAE,OAAO,CAAC,CAAC;QACtF,QAAQ,CAAC,IAAI,CAAC,UAAU,EAAE,8BAA8B,CAAC,CAAC;QAE1D,QAAQ,CAAC,KAAK,CAAC,OAAO,EAAE,WAAW,aAAa,EAAE,CAAC,CAAC;QACpD,MAAM,aAAa,CAAC,QAAQ,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;QACxC,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,aAAa,EAAE,CAAC,CAAC;QAEnD,MAAM,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC;QAC3D,MAAM,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC;QACnE,MAAM,KAAK,GAAG,CAAC,GAAG,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACnD,IAAI,EAAE,GAAG,CAAC;YAAE,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAC7D,OAAO,CAAC,GAAG,CAAC,OAAO,aAAa,eAAe,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACrE,OAAO,CAAC,GAAG,CAAC,gBAAgB,QAAQ,CAAC,eAAe,EAAE,CAAC,CAAC;IAC5D,CAAC;AACL,CAAC;AAED,+EAA+E;AAC/E,cAAc;AACd,+EAA+E;AAE/E,KAAK,UAAU,IAAI;IACf,MAAM,IAAI,GAAG,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAErC,IAAI,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;QAC7B,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAClB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACpC,CAAC;IAED,QAAQ,IAAI,CAAC,OAAO,EAAE,CAAC;QACnB,KAAK,MAAM;YACP,MAAM,WAAW,CAAC,IAAI,CAAC,CAAC;YACxB,MAAM;QACV;YACI,OAAO,CAAC,KAAK,CAAC,qBAAqB,IAAI,CAAC,OAAO,KAAK,CAAC,CAAC;YACtD,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAClB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACxB,CAAC;AACL,CAAC;AAED,8CAA8C;AAC9C,MAAM,KAAK,GACP,OAAO,OAAO,KAAK,WAAW;IAC9B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,QAAQ,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAC;AAClF,IAAI,KAAK,EAAE,CAAC;IACR,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAU,EAAE,EAAE;QACxB,OAAO,CAAC,KAAK,CAAC,UAAU,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QACvC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -50,6 +50,84 @@ export interface FusionTransport {
50
50
  * ```
51
51
  */
52
52
  export type RouterMap = Record<string, Record<string, unknown>>;
53
+ /**
54
+ * Client-side middleware for request/response interception.
55
+ *
56
+ * Follows the same onion model as server-side middleware:
57
+ * each middleware wraps the next, forming a pipeline.
58
+ *
59
+ * Use cases: authentication injection, request logging,
60
+ * retry logic, timeout enforcement, response transformation.
61
+ *
62
+ * @example
63
+ * ```typescript
64
+ * const authMiddleware: ClientMiddleware = async (action, args, next) => {
65
+ * const enrichedArgs = { ...args, _token: getToken() };
66
+ * return next(action, enrichedArgs);
67
+ * };
68
+ *
69
+ * const retryMiddleware: ClientMiddleware = async (action, args, next) => {
70
+ * for (let i = 0; i < 3; i++) {
71
+ * const result = await next(action, args);
72
+ * if (!result.isError) return result;
73
+ * }
74
+ * return next(action, args);
75
+ * };
76
+ * ```
77
+ */
78
+ export type ClientMiddleware = (action: string, args: Record<string, unknown>, next: (action: string, args: Record<string, unknown>) => Promise<ToolResponse>) => Promise<ToolResponse>;
79
+ /**
80
+ * Structured error parsed from a `<tool_error>` XML envelope.
81
+ *
82
+ * Provides typed access to self-healing fields so client code
83
+ * can programmatically react to server errors without regex parsing.
84
+ */
85
+ export declare class FusionClientError extends Error {
86
+ /** Error code from the `code` attribute (e.g. `'NOT_FOUND'`). */
87
+ readonly code: string;
88
+ /** Recovery suggestion from `<recovery>` element. */
89
+ readonly recovery?: string | undefined;
90
+ /** Available actions from `<available_actions>` children. */
91
+ readonly availableActions: readonly string[];
92
+ /** Error severity from the `severity` attribute. */
93
+ readonly severity: string;
94
+ /** Raw ToolResponse that caused the error. */
95
+ readonly raw: ToolResponse;
96
+ constructor(message: string, code: string, raw: ToolResponse, options?: {
97
+ recovery?: string | undefined;
98
+ availableActions?: string[] | undefined;
99
+ severity?: string | undefined;
100
+ });
101
+ }
102
+ /**
103
+ * Options for creating a FusionClient.
104
+ */
105
+ export interface FusionClientOptions {
106
+ /**
107
+ * Client-side middleware pipeline.
108
+ *
109
+ * Middleware execute in registration order (first = outermost).
110
+ * Each middleware can modify the request, response, or both.
111
+ *
112
+ * @example
113
+ * ```typescript
114
+ * const client = createFusionClient<AppRouter>(transport, {
115
+ * middleware: [authMiddleware, loggingMiddleware],
116
+ * });
117
+ * ```
118
+ */
119
+ middleware?: ClientMiddleware[];
120
+ /**
121
+ * When `true`, `execute()` throws a {@link FusionClientError}
122
+ * for responses with `isError: true`.
123
+ *
124
+ * When `false` (default), error responses are returned normally
125
+ * and the caller must check `result.isError`.
126
+ *
127
+ * @default false
128
+ */
129
+ throwOnError?: boolean;
130
+ }
53
131
  /**
54
132
  * Type-safe client that provides autocomplete and compile-time
55
133
  * validation for MCP tool calls.
@@ -65,6 +143,32 @@ export interface FusionClient<TRouter extends RouterMap> {
65
143
  * @returns The tool response
66
144
  */
67
145
  execute<TAction extends keyof TRouter & string>(action: TAction, args: TRouter[TAction]): Promise<ToolResponse>;
146
+ /**
147
+ * Execute multiple tool actions concurrently.
148
+ *
149
+ * All calls run in parallel via `Promise.all`.
150
+ * Use `{ sequential: true }` for ordered execution.
151
+ *
152
+ * @param calls - Array of `{ action, args }` objects
153
+ * @param options - Optional execution mode
154
+ * @returns Array of tool responses, one per call
155
+ *
156
+ * @example
157
+ * ```typescript
158
+ * const results = await client.executeBatch([
159
+ * { action: 'projects.list', args: { workspace_id: 'ws_1' } },
160
+ * { action: 'billing.balance', args: { account_id: 'acc_1' } },
161
+ * ]);
162
+ * ```
163
+ */
164
+ executeBatch<TActions extends ReadonlyArray<keyof TRouter & string>>(calls: {
165
+ [K in keyof TActions]: {
166
+ action: TActions[K];
167
+ args: TRouter[TActions[K] & keyof TRouter];
168
+ };
169
+ }, options?: {
170
+ sequential?: boolean | undefined;
171
+ } | undefined): Promise<ToolResponse[]>;
68
172
  }
69
173
  /**
70
174
  * Create a type-safe MCP client.
@@ -75,6 +179,7 @@ export interface FusionClient<TRouter extends RouterMap> {
75
179
  *
76
180
  * @typeParam TRouter - The router map (use `InferRouter<typeof registry>`)
77
181
  * @param transport - The MCP transport layer
182
+ * @param options - Client options (middleware, error handling)
78
183
  * @returns A typed {@link FusionClient}
79
184
  *
80
185
  * @example
@@ -92,6 +197,22 @@ export interface FusionClient<TRouter extends RouterMap> {
92
197
  * // TS error: missing required arg 'name'
93
198
  * await client.execute('projects.create', {});
94
199
  * ```
200
+ *
201
+ * @example
202
+ * ```typescript
203
+ * // With client middleware and throwOnError
204
+ * const client = createFusionClient<AppRouter>(transport, {
205
+ * throwOnError: true,
206
+ * middleware: [
207
+ * async (action, args, next) => {
208
+ * console.log(`[Client] calling ${action}`);
209
+ * const result = await next(action, args);
210
+ * console.log(`[Client] ${action} done`);
211
+ * return result;
212
+ * },
213
+ * ],
214
+ * });
215
+ * ```
95
216
  */
96
- export declare function createFusionClient<TRouter extends RouterMap>(transport: FusionTransport): FusionClient<TRouter>;
217
+ export declare function createFusionClient<TRouter extends RouterMap>(transport: FusionTransport, options?: FusionClientOptions): FusionClient<TRouter>;
97
218
  //# sourceMappingURL=FusionClient.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"FusionClient.d.ts","sourceRoot":"","sources":["../../src/client/FusionClient.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAMxD;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC5B,yCAAyC;IACzC,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;CAChF;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AAEhE;;;;;GAKG;AACH,MAAM,WAAW,YAAY,CAAC,OAAO,SAAS,SAAS;IACnD;;;;;;OAMG;IACH,OAAO,CAAC,OAAO,SAAS,MAAM,OAAO,GAAG,MAAM,EAC1C,MAAM,EAAE,OAAO,EACf,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,GACvB,OAAO,CAAC,YAAY,CAAC,CAAC;CAC5B;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,SAAS,SAAS,EACxD,SAAS,EAAE,eAAe,GAC3B,YAAY,CAAC,OAAO,CAAC,CAqBvB"}
1
+ {"version":3,"file":"FusionClient.d.ts","sourceRoot":"","sources":["../../src/client/FusionClient.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAMxD;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC5B,yCAAyC;IACzC,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;CAChF;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AAMhE;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,MAAM,gBAAgB,GAAG,CAC3B,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,YAAY,CAAC,KAC7E,OAAO,CAAC,YAAY,CAAC,CAAC;AAM3B;;;;;GAKG;AACH,qBAAa,iBAAkB,SAAQ,KAAK;IACxC,iEAAiE;IACjE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,qDAAqD;IACrD,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACvC,6DAA6D;IAC7D,QAAQ,CAAC,gBAAgB,EAAE,SAAS,MAAM,EAAE,CAAC;IAC7C,oDAAoD;IACpD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,8CAA8C;IAC9C,QAAQ,CAAC,GAAG,EAAE,YAAY,CAAC;gBAGvB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,YAAY,EACjB,OAAO,CAAC,EAAE;QACN,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;QAC9B,gBAAgB,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;QACxC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;KACjC;CAUR;AAMD;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAChC;;;;;;;;;;;;OAYG;IACH,UAAU,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAEhC;;;;;;;;OAQG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;CAC1B;AAMD;;;;;GAKG;AACH,MAAM,WAAW,YAAY,CAAC,OAAO,SAAS,SAAS;IACnD;;;;;;OAMG;IACH,OAAO,CAAC,OAAO,SAAS,MAAM,OAAO,GAAG,MAAM,EAC1C,MAAM,EAAE,OAAO,EACf,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,GACvB,OAAO,CAAC,YAAY,CAAC,CAAC;IAEzB;;;;;;;;;;;;;;;;;OAiBG;IACH,YAAY,CAAC,QAAQ,SAAS,aAAa,CAAC,MAAM,OAAO,GAAG,MAAM,CAAC,EAC/D,KAAK,EAAE;SAAG,CAAC,IAAI,MAAM,QAAQ,GAAG;YAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC;YAAC,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,MAAM,OAAO,CAAC,CAAA;SAAE;KAAE,EACrG,OAAO,CAAC,EAAE;QAAE,UAAU,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;KAAE,GAAG,SAAS,GAC3D,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;CAC9B;AA2GD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,SAAS,SAAS,EACxD,SAAS,EAAE,eAAe,EAC1B,OAAO,CAAC,EAAE,mBAAmB,GAC9B,YAAY,CAAC,OAAO,CAAC,CA6EvB"}