@animalabs/agent-framework 0.18.0 → 0.20.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 (203) hide show
  1. package/README.md +29 -0
  2. package/dist/src/agent.d.ts +22 -0
  3. package/dist/src/agent.d.ts.map +1 -1
  4. package/dist/src/agent.js +128 -10
  5. package/dist/src/agent.js.map +1 -1
  6. package/dist/src/api/types.d.ts +1 -1
  7. package/dist/src/api/types.d.ts.map +1 -1
  8. package/dist/src/code-execution/py-runner.d.ts +10 -1
  9. package/dist/src/code-execution/py-runner.d.ts.map +1 -1
  10. package/dist/src/code-execution/py-runner.js +27 -2
  11. package/dist/src/code-execution/py-runner.js.map +1 -1
  12. package/dist/src/code-execution/tool-definition.d.ts +21 -0
  13. package/dist/src/code-execution/tool-definition.d.ts.map +1 -1
  14. package/dist/src/code-execution/tool-definition.js +34 -0
  15. package/dist/src/code-execution/tool-definition.js.map +1 -1
  16. package/dist/src/framework.d.ts +161 -7
  17. package/dist/src/framework.d.ts.map +1 -1
  18. package/dist/src/framework.js +1183 -87
  19. package/dist/src/framework.js.map +1 -1
  20. package/dist/src/index.d.ts +2 -0
  21. package/dist/src/index.d.ts.map +1 -1
  22. package/dist/src/index.js +4 -0
  23. package/dist/src/index.js.map +1 -1
  24. package/dist/src/mcpl/capability-grant.d.ts +1 -1
  25. package/dist/src/mcpl/capability-grant.d.ts.map +1 -1
  26. package/dist/src/mcpl/capability-grant.js +49 -5
  27. package/dist/src/mcpl/capability-grant.js.map +1 -1
  28. package/dist/src/mcpl/channel-registry.d.ts +74 -2
  29. package/dist/src/mcpl/channel-registry.d.ts.map +1 -1
  30. package/dist/src/mcpl/channel-registry.js +156 -10
  31. package/dist/src/mcpl/channel-registry.js.map +1 -1
  32. package/dist/src/mcpl/index.d.ts +3 -0
  33. package/dist/src/mcpl/index.d.ts.map +1 -1
  34. package/dist/src/mcpl/index.js +3 -0
  35. package/dist/src/mcpl/index.js.map +1 -1
  36. package/dist/src/mcpl/push-coalescer.d.ts +318 -0
  37. package/dist/src/mcpl/push-coalescer.d.ts.map +1 -0
  38. package/dist/src/mcpl/push-coalescer.js +709 -0
  39. package/dist/src/mcpl/push-coalescer.js.map +1 -0
  40. package/dist/src/mcpl/push-handler.d.ts +7 -2
  41. package/dist/src/mcpl/push-handler.d.ts.map +1 -1
  42. package/dist/src/mcpl/push-handler.js +43 -4
  43. package/dist/src/mcpl/push-handler.js.map +1 -1
  44. package/dist/src/mcpl/server-connection.d.ts +18 -0
  45. package/dist/src/mcpl/server-connection.d.ts.map +1 -1
  46. package/dist/src/mcpl/server-connection.js +44 -1
  47. package/dist/src/mcpl/server-connection.js.map +1 -1
  48. package/dist/src/mcpl/tool-classes.d.ts +71 -0
  49. package/dist/src/mcpl/tool-classes.d.ts.map +1 -0
  50. package/dist/src/mcpl/tool-classes.js +170 -0
  51. package/dist/src/mcpl/tool-classes.js.map +1 -0
  52. package/dist/src/mcpl/tool-glob.d.ts +16 -0
  53. package/dist/src/mcpl/tool-glob.d.ts.map +1 -0
  54. package/dist/src/mcpl/tool-glob.js +41 -0
  55. package/dist/src/mcpl/tool-glob.js.map +1 -0
  56. package/dist/src/mcpl/tool-lifecycle.d.ts +253 -0
  57. package/dist/src/mcpl/tool-lifecycle.d.ts.map +1 -0
  58. package/dist/src/mcpl/tool-lifecycle.js +592 -0
  59. package/dist/src/mcpl/tool-lifecycle.js.map +1 -0
  60. package/dist/src/mcpl/transport.d.ts +12 -0
  61. package/dist/src/mcpl/transport.d.ts.map +1 -1
  62. package/dist/src/mcpl/transport.js +33 -1
  63. package/dist/src/mcpl/transport.js.map +1 -1
  64. package/dist/src/mcpl/types.d.ts +66 -1
  65. package/dist/src/mcpl/types.d.ts.map +1 -1
  66. package/dist/src/mcpl/types.js +6 -0
  67. package/dist/src/mcpl/types.js.map +1 -1
  68. package/dist/src/modules/discord/index.js +1 -1
  69. package/dist/src/modules/discord/index.js.map +1 -1
  70. package/dist/src/modules/history/index.d.ts +85 -0
  71. package/dist/src/modules/history/index.d.ts.map +1 -1
  72. package/dist/src/modules/history/index.js +1019 -24
  73. package/dist/src/modules/history/index.js.map +1 -1
  74. package/dist/src/modules/history/semantic.d.ts +202 -0
  75. package/dist/src/modules/history/semantic.d.ts.map +1 -0
  76. package/dist/src/modules/history/semantic.js +418 -0
  77. package/dist/src/modules/history/semantic.js.map +1 -0
  78. package/dist/src/modules/index.d.ts +2 -1
  79. package/dist/src/modules/index.d.ts.map +1 -1
  80. package/dist/src/modules/index.js.map +1 -1
  81. package/dist/src/tool-result-guard.d.ts +82 -0
  82. package/dist/src/tool-result-guard.d.ts.map +1 -0
  83. package/dist/src/tool-result-guard.js +306 -0
  84. package/dist/src/tool-result-guard.js.map +1 -0
  85. package/dist/src/types/agent.d.ts +14 -0
  86. package/dist/src/types/agent.d.ts.map +1 -1
  87. package/dist/src/types/framework.d.ts +21 -0
  88. package/dist/src/types/framework.d.ts.map +1 -1
  89. package/dist/src/types/trace.d.ts +17 -0
  90. package/dist/src/types/trace.d.ts.map +1 -1
  91. package/dist/test/channel-registry-routing.test.js +59 -0
  92. package/dist/test/channel-registry-routing.test.js.map +1 -1
  93. package/dist/test/channels-changed-respond-first.test.d.ts +2 -0
  94. package/dist/test/channels-changed-respond-first.test.d.ts.map +1 -0
  95. package/dist/test/channels-changed-respond-first.test.js +74 -0
  96. package/dist/test/channels-changed-respond-first.test.js.map +1 -0
  97. package/dist/test/code-execution.test.js +139 -0
  98. package/dist/test/code-execution.test.js.map +1 -1
  99. package/dist/test/helpers/coalescing-fixture.d.ts +72 -0
  100. package/dist/test/helpers/coalescing-fixture.d.ts.map +1 -0
  101. package/dist/test/helpers/coalescing-fixture.js +145 -0
  102. package/dist/test/helpers/coalescing-fixture.js.map +1 -0
  103. package/dist/test/helpers/coalescing-kill-child.d.ts +2 -0
  104. package/dist/test/helpers/coalescing-kill-child.d.ts.map +1 -0
  105. package/dist/test/helpers/coalescing-kill-child.js +24 -0
  106. package/dist/test/helpers/coalescing-kill-child.js.map +1 -0
  107. package/dist/test/history-module-realstore.test.d.ts +2 -0
  108. package/dist/test/history-module-realstore.test.d.ts.map +1 -0
  109. package/dist/test/history-module-realstore.test.js +363 -0
  110. package/dist/test/history-module-realstore.test.js.map +1 -0
  111. package/dist/test/history-module-semantic.test.d.ts +2 -0
  112. package/dist/test/history-module-semantic.test.d.ts.map +1 -0
  113. package/dist/test/history-module-semantic.test.js +213 -0
  114. package/dist/test/history-module-semantic.test.js.map +1 -0
  115. package/dist/test/history-module-ux.test.d.ts +2 -0
  116. package/dist/test/history-module-ux.test.d.ts.map +1 -0
  117. package/dist/test/history-module-ux.test.js +304 -0
  118. package/dist/test/history-module-ux.test.js.map +1 -0
  119. package/dist/test/history-module.test.js +25 -1
  120. package/dist/test/history-module.test.js.map +1 -1
  121. package/dist/test/history-semantic-review-findings.test.d.ts +2 -0
  122. package/dist/test/history-semantic-review-findings.test.d.ts.map +1 -0
  123. package/dist/test/history-semantic-review-findings.test.js +338 -0
  124. package/dist/test/history-semantic-review-findings.test.js.map +1 -0
  125. package/dist/test/history-semantic-sync-converges.test.d.ts +2 -0
  126. package/dist/test/history-semantic-sync-converges.test.d.ts.map +1 -0
  127. package/dist/test/history-semantic-sync-converges.test.js +109 -0
  128. package/dist/test/history-semantic-sync-converges.test.js.map +1 -0
  129. package/dist/test/journal-tool.test.d.ts +2 -0
  130. package/dist/test/journal-tool.test.d.ts.map +1 -0
  131. package/dist/test/journal-tool.test.js +33 -0
  132. package/dist/test/journal-tool.test.js.map +1 -0
  133. package/dist/test/mcpl-capability-grant.test.js +3 -1
  134. package/dist/test/mcpl-capability-grant.test.js.map +1 -1
  135. package/dist/test/mcpl-child-env.test.d.ts +2 -0
  136. package/dist/test/mcpl-child-env.test.d.ts.map +1 -0
  137. package/dist/test/mcpl-child-env.test.js +69 -0
  138. package/dist/test/mcpl-child-env.test.js.map +1 -0
  139. package/dist/test/mcpl-coalescing.test.d.ts +2 -0
  140. package/dist/test/mcpl-coalescing.test.d.ts.map +1 -0
  141. package/dist/test/mcpl-coalescing.test.js +1050 -0
  142. package/dist/test/mcpl-coalescing.test.js.map +1 -0
  143. package/dist/test/mcpl-list-status.test.js +4 -0
  144. package/dist/test/mcpl-list-status.test.js.map +1 -1
  145. package/dist/test/mcpl-tool-class-listing.test.d.ts +2 -0
  146. package/dist/test/mcpl-tool-class-listing.test.d.ts.map +1 -0
  147. package/dist/test/mcpl-tool-class-listing.test.js +147 -0
  148. package/dist/test/mcpl-tool-class-listing.test.js.map +1 -0
  149. package/dist/test/mcpl-tool-classes.test.d.ts +7 -0
  150. package/dist/test/mcpl-tool-classes.test.d.ts.map +1 -0
  151. package/dist/test/mcpl-tool-classes.test.js +80 -0
  152. package/dist/test/mcpl-tool-classes.test.js.map +1 -0
  153. package/dist/test/mcpl-tool-lifecycle-e2e.test.d.ts +2 -0
  154. package/dist/test/mcpl-tool-lifecycle-e2e.test.d.ts.map +1 -0
  155. package/dist/test/mcpl-tool-lifecycle-e2e.test.js +237 -0
  156. package/dist/test/mcpl-tool-lifecycle-e2e.test.js.map +1 -0
  157. package/dist/test/mcpl-tool-lifecycle-emitter.test.d.ts +11 -0
  158. package/dist/test/mcpl-tool-lifecycle-emitter.test.d.ts.map +1 -0
  159. package/dist/test/mcpl-tool-lifecycle-emitter.test.js +307 -0
  160. package/dist/test/mcpl-tool-lifecycle-emitter.test.js.map +1 -0
  161. package/dist/test/mcpl-tool-lifecycle.test.d.ts +11 -0
  162. package/dist/test/mcpl-tool-lifecycle.test.d.ts.map +1 -0
  163. package/dist/test/mcpl-tool-lifecycle.test.js +270 -0
  164. package/dist/test/mcpl-tool-lifecycle.test.js.map +1 -0
  165. package/dist/test/overbudget-drain-breaker.test.js +44 -4
  166. package/dist/test/overbudget-drain-breaker.test.js.map +1 -1
  167. package/dist/test/silent-heartbeat.test.d.ts +2 -0
  168. package/dist/test/silent-heartbeat.test.d.ts.map +1 -0
  169. package/dist/test/silent-heartbeat.test.js +154 -0
  170. package/dist/test/silent-heartbeat.test.js.map +1 -0
  171. package/dist/test/tool-result-guard.test.d.ts +2 -0
  172. package/dist/test/tool-result-guard.test.d.ts.map +1 -0
  173. package/dist/test/tool-result-guard.test.js +1081 -0
  174. package/dist/test/tool-result-guard.test.js.map +1 -0
  175. package/dist/test/trunk-channel-routing.test.js +67 -0
  176. package/dist/test/trunk-channel-routing.test.js.map +1 -1
  177. package/dist/tsconfig.tsbuildinfo +1 -1
  178. package/package.json +2 -2
  179. package/src/agent.ts +128 -10
  180. package/src/api/types.ts +2 -0
  181. package/src/code-execution/py-runner.ts +34 -2
  182. package/src/code-execution/tool-definition.ts +46 -0
  183. package/src/framework.ts +1215 -91
  184. package/src/index.ts +13 -0
  185. package/src/mcpl/capability-grant.ts +54 -6
  186. package/src/mcpl/channel-registry.ts +170 -10
  187. package/src/mcpl/index.ts +29 -0
  188. package/src/mcpl/push-coalescer.ts +821 -0
  189. package/src/mcpl/push-handler.ts +40 -4
  190. package/src/mcpl/server-connection.ts +48 -2
  191. package/src/mcpl/tool-classes.ts +188 -0
  192. package/src/mcpl/tool-glob.ts +36 -0
  193. package/src/mcpl/tool-lifecycle.ts +730 -0
  194. package/src/mcpl/transport.ts +35 -1
  195. package/src/mcpl/types.ts +69 -1
  196. package/src/modules/discord/index.ts +1 -1
  197. package/src/modules/history/index.ts +1089 -24
  198. package/src/modules/history/semantic.ts +473 -0
  199. package/src/modules/index.ts +2 -1
  200. package/src/tool-result-guard.ts +318 -0
  201. package/src/types/agent.ts +15 -0
  202. package/src/types/framework.ts +23 -0
  203. package/src/types/trace.ts +17 -0
@@ -0,0 +1,237 @@
1
+ /**
2
+ * RFC-007 end to end: a real framework, two real MCPL servers over stdio, a
3
+ * scripted model turn.
4
+ *
5
+ * provider — offers `click` (classed `computer`) and `run` (unclassed,
6
+ * returns an error result)
7
+ * observer — granted toolLifecycle.observe + inputs (narrowed by tool
8
+ * name to prov--*), sends a tools/observe filter asking for click
9
+ * coordinates and every other call's full arguments
10
+ *
11
+ * The agent calls prov--click, prov--run and the observer's own obs--ping in
12
+ * one round. The observer must see: click with ONLY the requested fields;
13
+ * run with its class empty and its arguments withheld (unclassed tools never
14
+ * carry arguments); run's terminal as completed+isError; nothing at all for
15
+ * its own tool; and no tool result anywhere.
16
+ */
17
+ import { describe, it, before, after } from 'node:test';
18
+ import assert from 'node:assert/strict';
19
+ import { tmpdir } from 'node:os';
20
+ import { mkdtempSync, rmSync, readFileSync, existsSync, writeFileSync } from 'node:fs';
21
+ import { join } from 'node:path';
22
+ import { AgentFramework } from '../src/index.js';
23
+ import { MockMembrane, createMockResponse } from './helpers/mock-membrane.js';
24
+ const FIXTURE = join(import.meta.dirname, 'fixtures/tool-lifecycle-mcpl-server.mjs');
25
+ class Trigger {
26
+ name = 'trigger';
27
+ async start(_ctx) { }
28
+ async stop() { }
29
+ getTools() { return []; }
30
+ async handleToolCall() { return { success: false, error: 'no tools', isError: true }; }
31
+ async onProcess(event, _state) {
32
+ if (event.type === 'external-message') {
33
+ // Wake the named agents when the event names them (broadcast skips
34
+ // conversation forks), everyone otherwise.
35
+ const targets = event.targetAgents;
36
+ return {
37
+ addMessages: [{ participant: 'User', content: [{ type: 'text', text: 'go' }] }],
38
+ requestInference: targets ?? true,
39
+ };
40
+ }
41
+ return {};
42
+ }
43
+ }
44
+ async function waitFor(cond, what, timeoutMs = 15_000) {
45
+ const deadline = Date.now() + timeoutMs;
46
+ while (Date.now() < deadline) {
47
+ if (cond())
48
+ return;
49
+ await new Promise((r) => setTimeout(r, 50));
50
+ }
51
+ throw new Error(`timed out waiting for: ${what}`);
52
+ }
53
+ const readLog = (path) => existsSync(path) ? readFileSync(path, 'utf8').split('\n').filter(Boolean).map((l) => JSON.parse(l)) : [];
54
+ describe('tool lifecycle end to end (RFC-007)', () => {
55
+ let tempDir;
56
+ let obsLog;
57
+ let provLog;
58
+ let diePath;
59
+ let membrane;
60
+ let framework;
61
+ before(async () => {
62
+ tempDir = mkdtempSync(join(tmpdir(), 'tool-lifecycle-e2e-'));
63
+ obsLog = join(tempDir, 'observer.jsonl');
64
+ provLog = join(tempDir, 'provider.jsonl');
65
+ diePath = join(tempDir, 'provider.die');
66
+ membrane = new MockMembrane();
67
+ framework = await AgentFramework.create({
68
+ storePath: join(tempDir, 'test.chronicle'),
69
+ membrane: membrane.asMembrane(),
70
+ agents: [{ name: 'scout', model: 'test-model', systemPrompt: 'You are scout.' }],
71
+ modules: [new Trigger()],
72
+ mcplServers: [
73
+ {
74
+ id: 'prov',
75
+ toolPrefix: 'prov',
76
+ command: process.execPath,
77
+ args: [FIXTURE],
78
+ env: { ROLE: 'provider', LOG_PATH: provLog, DIE_PATH: diePath },
79
+ },
80
+ {
81
+ id: 'obs',
82
+ toolPrefix: 'obs',
83
+ command: process.execPath,
84
+ args: [FIXTURE],
85
+ env: {
86
+ ROLE: 'observer',
87
+ LOG_PATH: obsLog,
88
+ FILTER: JSON.stringify([
89
+ { match: { serverTool: 'click' }, input: ['x', 'y', 'target.window_id'] },
90
+ { match: {}, input: true },
91
+ ]),
92
+ },
93
+ // Narrowed by NAME, which admits prov--run: only the class
94
+ // exclusion (unclassed never carries arguments) can withhold it.
95
+ toolLifecycle: { observe: {}, inputs: { tools: ['prov--*'] } },
96
+ },
97
+ ],
98
+ });
99
+ await framework.start();
100
+ await waitFor(() => readLog(obsLog).some((e) => e.event === 'observe-applied'), 'observer filter applied');
101
+ await waitFor(() => ['prov--click', 'prov--run', 'obs--ping'].every((n) => framework.getAllTools().some((t) => t.name === n)), 'MCPL tools listed');
102
+ });
103
+ after(async () => {
104
+ await framework?.stop();
105
+ if (tempDir)
106
+ rmSync(tempDir, { recursive: true, force: true });
107
+ });
108
+ it('lists every tool with its effective class, source, and server (RFC-008 §6)', () => {
109
+ const byTool = new Map(framework.listToolClasses().map((e) => [e.tool, e]));
110
+ assert.deepEqual(byTool.get('prov--click'), { tool: 'prov--click', class: ['computer'], source: 'server', serverId: 'prov' });
111
+ assert.deepEqual(byTool.get('prov--run'), { tool: 'prov--run', class: [], source: 'none', serverId: 'prov' });
112
+ assert.deepEqual(byTool.get('obs--ping'), { tool: 'obs--ping', class: ['body'], source: 'server', serverId: 'obs' });
113
+ const prov = framework.listMcplServers().find((s) => s.id === 'prov');
114
+ assert.deepEqual(prov.toolClasses.map((t) => `${t.serverTool}:${t.class.join('+') || '-'}:${t.source}`), [
115
+ 'click:computer:server', 'run:-:none',
116
+ ]);
117
+ });
118
+ it('reports other servers\' calls with requested fields only, never results', async () => {
119
+ const policy = readLog(obsLog).find((e) => e.event === 'policy');
120
+ assert.ok((policy?.effectiveCapabilities).includes('toolLifecycle.inputs'), 'the policy block granted both paths');
121
+ membrane.pushResponse(createMockResponse([
122
+ { type: 'text', text: 'Acting.' },
123
+ {
124
+ type: 'tool_use', id: 'toolu_01AAAAAAAAAAAAAAAAAAAAAA', name: 'prov--click',
125
+ input: { x: 812, y: 440, button: 'left', target: { window_id: 3312, title: 'Invoice.pdf' } },
126
+ },
127
+ { type: 'tool_use', id: 'toolu_01BBBBBBBBBBBBBBBBBBBBBB', name: 'prov--run', input: { cmd: 'make secret-arg' } },
128
+ { type: 'tool_use', id: 'toolu_01CCCCCCCCCCCCCCCCCCCCCC', name: 'obs--ping', input: {} },
129
+ ], 'tool_use'));
130
+ membrane.pushResponse(createMockResponse([{ type: 'text', text: 'Done.' }]));
131
+ framework.pushEvent({
132
+ type: 'external-message',
133
+ source: 'test',
134
+ content: [{ type: 'text', text: 'go' }],
135
+ metadata: {},
136
+ triggerInference: true,
137
+ });
138
+ const lifecycle = () => readLog(obsLog).filter((e) => e.event === 'lifecycle').map((e) => e.params);
139
+ await waitFor(() => lifecycle().length >= 4, 'two calls, both phases');
140
+ // Let the turn finish, so a stray or duplicate notification would land
141
+ // before the counts below are taken.
142
+ await waitFor(() => membrane.lastStream?.receivedToolResults.length === 1, 'tool results returned to the model');
143
+ await new Promise((r) => setTimeout(r, 300));
144
+ const events = lifecycle();
145
+ const byTool = (tool, phase) => events.filter((p) => p.tool === tool && p.phase === phase);
146
+ // Own tool: the observer saw its own call as tools/call, never as lifecycle.
147
+ assert.ok(readLog(obsLog).some((e) => e.event === 'tools-call' && e.name === 'ping'));
148
+ assert.equal(events.filter((p) => p.tool === 'obs--ping').length, 0, 'own tools are excluded');
149
+ // click: classed computer → the requested fields and nothing else.
150
+ const [clickStart] = byTool('prov--click', 'started');
151
+ assert.deepEqual(clickStart.class, ['computer']);
152
+ assert.equal(clickStart.serverId, 'prov');
153
+ assert.equal(clickStart.serverTool, 'click');
154
+ assert.equal(clickStart.conversationId, 'scout');
155
+ assert.deepEqual(clickStart.input, { x: 812, y: 440, target: { window_id: 3312 } });
156
+ const [clickEnd] = byTool('prov--click', 'completed');
157
+ assert.equal(clickEnd.toolCallId, clickStart.toolCallId);
158
+ assert.equal(clickEnd.inferenceId, clickStart.inferenceId);
159
+ assert.equal(clickEnd.isError, false);
160
+ assert.equal(typeof clickEnd.durationMs, 'number');
161
+ // run: unclassed → arguments withheld though the rule asked; error RESULT
162
+ // is a completed call with isError, not a failure.
163
+ const [runStart] = byTool('prov--run', 'started');
164
+ assert.deepEqual(runStart.class, []);
165
+ assert.equal(runStart.input, undefined);
166
+ assert.equal(runStart.inputWithheld, true);
167
+ const [runEnd] = byTool('prov--run', 'completed');
168
+ assert.equal(runEnd.isError, true);
169
+ // Exactly one opening and one terminal per call.
170
+ assert.equal(events.length, 4);
171
+ const wire = JSON.stringify(events);
172
+ for (const secret of ['RESULT-MARKER', 'secret-arg', 'Invoice.pdf', 'left']) {
173
+ assert.ok(!wire.includes(secret), `"${secret}" must not reach the observer`);
174
+ }
175
+ // The provider, which holds no toolLifecycle grant, received nothing.
176
+ assert.equal(readLog(provLog).filter((e) => e.event === 'lifecycle').length, 0);
177
+ });
178
+ it('a provider that dies takes its classes with it, and calls to it are never reported (review #3, #4)', async () => {
179
+ const internals = framework;
180
+ assert.deepEqual(internals.describeToolForLifecycle('prov--click').class, ['computer'], 'classed while alive');
181
+ writeFileSync(diePath, '');
182
+ await waitFor(() => internals.mcplServerRegistry?.getServer('prov') == null, 'provider removed from the registry');
183
+ // #3: the stale declaration is gone — unclassed (restrictive) until re-listed.
184
+ assert.deepEqual(internals.describeToolForLifecycle('prov--click').class, []);
185
+ const before = readLog(obsLog).filter((e) => e.event === 'lifecycle').length;
186
+ membrane.pushResponse(createMockResponse([
187
+ { type: 'tool_use', id: 'toolu_01DDDDDDDDDDDDDDDDDDDDDD', name: 'prov--click', input: { x: 1, y: 2 } },
188
+ ], 'tool_use'));
189
+ membrane.pushResponse(createMockResponse([{ type: 'text', text: 'It is gone.' }]));
190
+ framework.pushEvent({
191
+ type: 'external-message',
192
+ source: 'test',
193
+ content: [{ type: 'text', text: 'again' }],
194
+ metadata: {},
195
+ triggerInference: true,
196
+ });
197
+ await waitFor(() => (membrane.lastStream?.receivedToolResults.length ?? 0) >= 1
198
+ && membrane.lastStream !== null && membrane.calls.length >= 2, 'the refused call answered');
199
+ await new Promise((r) => setTimeout(r, 300));
200
+ const after = readLog(obsLog).filter((e) => e.event === 'lifecycle').length;
201
+ assert.equal(after, before, 'a call the host refused (provider gone) produces no events');
202
+ });
203
+ it('a host-tool refusal (conversation-bound channel guard) is never reported (re-review #1)', async () => {
204
+ const internals = framework;
205
+ // Make scout a conversation fork bound to one channel: the guard in
206
+ // dispatchChannelToolCall refuses channel_open before it runs.
207
+ internals.conversationAgentHomes.set('scout', 'disc:guild:home');
208
+ try {
209
+ const before = readLog(obsLog).filter((e) => e.event === 'lifecycle').length;
210
+ const callsBefore = membrane.calls.length;
211
+ membrane.pushResponse(createMockResponse([
212
+ { type: 'tool_use', id: 'toolu_01EEEEEEEEEEEEEEEEEEEEEE', name: 'channel_open', input: { channelId: 'disc:guild:other' } },
213
+ ], 'tool_use'));
214
+ membrane.pushResponse(createMockResponse([{ type: 'text', text: 'Refused.' }]));
215
+ framework.pushEvent({
216
+ type: 'external-message',
217
+ source: 'test',
218
+ content: [{ type: 'text', text: 'open another channel' }],
219
+ metadata: {},
220
+ triggerInference: true,
221
+ // Broadcast wakes skip conversation forks; address scout directly.
222
+ targetAgents: ['scout'],
223
+ });
224
+ await waitFor(() => membrane.calls.length > callsBefore
225
+ && (membrane.lastStream?.receivedToolResults.length ?? 0) >= 1, 'the refused call answered');
226
+ const answer = JSON.stringify(membrane.lastStream.receivedToolResults[0]);
227
+ assert.match(answer, /cannot open channels/, 'the guard did refuse it');
228
+ await new Promise((r) => setTimeout(r, 300));
229
+ const after = readLog(obsLog).filter((e) => e.event === 'lifecycle').length;
230
+ assert.equal(after, before, 'a refused host-tool call produces no events');
231
+ }
232
+ finally {
233
+ internals.conversationAgentHomes.delete('scout');
234
+ }
235
+ });
236
+ });
237
+ //# sourceMappingURL=mcpl-tool-lifecycle-e2e.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcpl-tool-lifecycle-e2e.test.js","sourceRoot":"","sources":["../../test/mcpl-tool-lifecycle-e2e.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * MCPL RFC-007 tool lifecycle — the emitter's pairing (started at dispatch →
3
+ * exactly one terminal, to exactly the connection epochs the opening went
4
+ * to, unless their grant no longer covers the call), host-unique call ids,
5
+ * and the grant computation for the two toolLifecycle paths.
6
+ *
7
+ * Tests named "review #N" are regressions for the Greptile review of
8
+ * agent-framework PR #199.
9
+ */
10
+ export {};
11
+ //# sourceMappingURL=mcpl-tool-lifecycle-emitter.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcpl-tool-lifecycle-emitter.test.d.ts","sourceRoot":"","sources":["../../test/mcpl-tool-lifecycle-emitter.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG"}
@@ -0,0 +1,307 @@
1
+ /**
2
+ * MCPL RFC-007 tool lifecycle — the emitter's pairing (started at dispatch →
3
+ * exactly one terminal, to exactly the connection epochs the opening went
4
+ * to, unless their grant no longer covers the call), host-unique call ids,
5
+ * and the grant computation for the two toolLifecycle paths.
6
+ *
7
+ * Tests named "review #N" are regressions for the Greptile review of
8
+ * agent-framework PR #199.
9
+ */
10
+ import { test, describe } from 'node:test';
11
+ import assert from 'node:assert/strict';
12
+ import { CapabilityGrant, computeGrant } from '../src/mcpl/capability-grant.js';
13
+ import { ToolLifecycleEmitter, openingFor, parseToolObserveParams, } from '../src/mcpl/tool-lifecycle.js';
14
+ const OBSERVE = 'toolLifecycle.observe';
15
+ const INPUTS = 'toolLifecycle.inputs';
16
+ function observer(id, paths, filter = null) {
17
+ const sent = [];
18
+ return {
19
+ id,
20
+ grant: new CapabilityGrant(new Set(paths), []),
21
+ toolObserveFilter: filter,
22
+ transportEpoch: 0,
23
+ sendToolLifecycle: (p) => { sent.push(p); },
24
+ sent,
25
+ };
26
+ }
27
+ function rules(raw) {
28
+ const parsed = parseToolObserveParams({ rules: raw });
29
+ assert.ok(parsed.ok, `rules should parse: ${JSON.stringify(raw)}`);
30
+ return parsed.rules;
31
+ }
32
+ const DEFAULT_INPUTS = { observe: {}, inputs: { classes: 'default' } };
33
+ function harness(opts) {
34
+ let clock = 1000;
35
+ const emitter = new ToolLifecycleEmitter({
36
+ observers: () => opts.observers,
37
+ configFor: (id) => opts.config?.[id],
38
+ describe: (tool) => {
39
+ const sep = tool.indexOf('--');
40
+ const cls = opts.classes?.[tool] ?? ['shell'];
41
+ return sep > 0
42
+ ? { class: cls, serverId: tool.slice(0, sep), serverTool: tool.slice(sep + 2) }
43
+ : { class: cls };
44
+ },
45
+ }, () => clock);
46
+ return { emitter, tick: (ms) => { clock += ms; } };
47
+ }
48
+ /**
49
+ * What the framework does at its dispatch point: register, run dispatch
50
+ * (whose refusal sites may call refuse()), then open.
51
+ */
52
+ function dispatch(emitter, agent, inferenceId, call, refusedByHost = false) {
53
+ emitter.register(agent, inferenceId, call);
54
+ if (refusedByHost)
55
+ emitter.refuse(agent, call.id);
56
+ emitter.open(agent, call.id);
57
+ }
58
+ /** An Anthropic-shaped, provider-unique tool_use id. */
59
+ const TOOLU = (n) => `toolu_01${String(n).padStart(22, '0')}`;
60
+ describe('ToolLifecycleEmitter', () => {
61
+ test('started at dispatch, completed on result — isError from the result, never its content', () => {
62
+ const o = observer('obs', [OBSERVE]);
63
+ const { emitter, tick } = harness({ observers: [o] });
64
+ dispatch(emitter, 'scout', 'inf_1', { id: TOOLU(1), name: 'prov--run', input: { cmd: 'make' } });
65
+ assert.deepEqual(o.sent.map((p) => p.phase), ['started']);
66
+ tick(40);
67
+ emitter.onResult('scout', TOOLU(1), { success: true, isError: true, data: 'SECRET-OUTPUT' });
68
+ assert.deepEqual(o.sent.map((p) => p.phase), ['started', 'completed']);
69
+ assert.equal(o.sent[1].isError, true);
70
+ assert.equal(o.sent[1].durationMs, 40);
71
+ assert.equal(o.sent[0].toolCallId, o.sent[1].toolCallId);
72
+ assert.ok(!JSON.stringify(o.sent).includes('SECRET-OUTPUT'), 'vector 26: no outcome leakage');
73
+ for (const p of o.sent) {
74
+ for (const k of ['result', 'output', 'content'])
75
+ assert.equal(k in p, false, `vector 27: no ${k}`);
76
+ }
77
+ assert.equal(emitter.openCount, 0);
78
+ });
79
+ test('review #6 — an error RESULT is completed+isError; only a marked dispatch failure is failed', () => {
80
+ const o = observer('obs', [OBSERVE]);
81
+ const { emitter } = harness({ observers: [o] });
82
+ dispatch(emitter, 'scout', 'inf_1', { id: TOOLU(2), name: 'utils', input: {} });
83
+ emitter.onResult('scout', TOOLU(2), { success: false, isError: true });
84
+ dispatch(emitter, 'scout', 'inf_1', { id: TOOLU(3), name: 'prov--run', input: {} });
85
+ emitter.markDispatchFailure('scout', TOOLU(3));
86
+ emitter.onResult('scout', TOOLU(3), { success: false, isError: true });
87
+ const terminals = o.sent.filter((p) => p.phase !== 'started');
88
+ assert.deepEqual(terminals.map((p) => `${p.tool}:${p.phase}:${p.isError}`), [
89
+ 'utils:completed:true',
90
+ 'prov--run:failed:undefined',
91
+ ]);
92
+ });
93
+ test('review #4 — a call the host refuses before executing (provider gone, policy) produces no events', () => {
94
+ const o = observer('obs', [OBSERVE, INPUTS], rules([{ match: {}, input: true }]));
95
+ const { emitter } = harness({ observers: [o], config: { obs: DEFAULT_INPUTS } });
96
+ dispatch(emitter, 'scout', 'inf_1', { id: TOOLU(4), name: 'gone--click', input: { x: 1 } }, true);
97
+ emitter.onResult('scout', TOOLU(4), { success: false, isError: true });
98
+ assert.equal(o.sent.length, 0);
99
+ assert.equal(emitter.openCount, 0);
100
+ });
101
+ test('re-review #1 — a host-tool refusal (conversation-bound channel guard) produces no events', () => {
102
+ const o = observer('obs', [OBSERVE]);
103
+ const { emitter } = harness({ observers: [o], classes: { channel_open: ['comms'] } });
104
+ dispatch(emitter, 'fork-1', 'inf_1', { id: TOOLU(40), name: 'channel_open', input: { channelId: 'x' } }, true);
105
+ emitter.onResult('fork-1', TOOLU(40), { success: false, isError: true });
106
+ assert.equal(o.sent.length, 0, 'never reported as started or completed');
107
+ // refuse() after the opening went out changes nothing: refusal is only
108
+ // meaningful before execution, and the call is then paired normally.
109
+ dispatch(emitter, 'scout', 'inf_2', { id: TOOLU(41), name: 'prov--a', input: {} });
110
+ emitter.refuse('scout', TOOLU(41));
111
+ emitter.onResult('scout', TOOLU(41), { success: true });
112
+ assert.deepEqual(o.sent.map((p) => p.phase), ['started', 'completed']);
113
+ });
114
+ test('review #2 — two agents with the same short call id never cross', () => {
115
+ const o = observer('obs', [OBSERVE]);
116
+ const { emitter } = harness({ observers: [o] });
117
+ dispatch(emitter, 'alice', 'inf_a', { id: 'call_0', name: 'prov--a', input: {} });
118
+ dispatch(emitter, 'bob', 'inf_b', { id: 'call_0', name: 'prov--b', input: {} });
119
+ emitter.markDispatchFailure('bob', 'call_0');
120
+ emitter.onResult('bob', 'call_0', { success: false, isError: true });
121
+ emitter.onResult('alice', 'call_0', { success: true });
122
+ const byTool = (tool) => o.sent.filter((p) => p.tool === tool).map((p) => p.phase);
123
+ assert.deepEqual(byTool('prov--a'), ['started', 'completed']);
124
+ assert.deepEqual(byTool('prov--b'), ['started', 'failed']);
125
+ const ids = new Set(o.sent.filter((p) => p.phase === 'started').map((p) => p.toolCallId));
126
+ assert.equal(ids.size, 2, 'distinct host ids for the two call_0s');
127
+ });
128
+ test('review #5 — a stream end aborts only its own inference ids, never a successor\'s calls', () => {
129
+ const o = observer('obs', [OBSERVE]);
130
+ const { emitter } = harness({ observers: [o] });
131
+ dispatch(emitter, 'scout', 'inf_old', { id: TOOLU(5), name: 'prov--a', input: {} });
132
+ dispatch(emitter, 'scout', 'inf_new', { id: TOOLU(6), name: 'prov--b', input: {} });
133
+ dispatch(emitter, 'other', 'inf_x', { id: TOOLU(7), name: 'prov--c', input: {} });
134
+ emitter.abortOpen('scout', ['inf_old']);
135
+ assert.deepEqual(o.sent.filter((p) => p.phase === 'aborted').map((p) => p.tool), ['prov--a']);
136
+ emitter.onResult('scout', TOOLU(6), { success: true });
137
+ assert.deepEqual(o.sent.filter((p) => p.tool === 'prov--b').map((p) => p.phase), ['started', 'completed']);
138
+ emitter.onResult('scout', TOOLU(5), { success: true });
139
+ assert.equal(o.sent.filter((p) => p.tool === 'prov--a').length, 2, 'no second terminal after abort');
140
+ assert.equal(emitter.openCount, 1, "the other agent's call stays open");
141
+ });
142
+ test('re-review #2 — durationMs counts from before dispatch, so synchronous work inside dispatch is included', () => {
143
+ const o = observer('obs', [OBSERVE]);
144
+ const { emitter, tick } = harness({ observers: [o] });
145
+ emitter.register('scout', 'inf_1', { id: TOOLU(42), name: 'sleep', input: {} });
146
+ tick(25); // a synchronous tool doing its work inside dispatch
147
+ emitter.open('scout', TOOLU(42));
148
+ tick(5); // the queued result waiting to be processed
149
+ emitter.onResult('scout', TOOLU(42), { success: true });
150
+ assert.deepEqual(o.sent.map((p) => p.phase), ['started', 'completed']);
151
+ assert.equal(o.sent[1].durationMs, 30);
152
+ });
153
+ test('parallel calls pair by toolCallId', () => {
154
+ const o = observer('obs', [OBSERVE]);
155
+ const { emitter } = harness({ observers: [o] });
156
+ dispatch(emitter, 'scout', 'inf_1', { id: TOOLU(8), name: 'prov--a', input: {} });
157
+ dispatch(emitter, 'scout', 'inf_1', { id: TOOLU(9), name: 'prov--b', input: {} });
158
+ emitter.onResult('scout', TOOLU(9), { success: true });
159
+ emitter.onResult('scout', TOOLU(8), { success: true });
160
+ assert.deepEqual(o.sent.map((p) => `${p.toolCallId}:${p.phase}`), [
161
+ `${TOOLU(8)}:started`, `${TOOLU(9)}:started`, `${TOOLU(9)}:completed`, `${TOOLU(8)}:completed`,
162
+ ]);
163
+ });
164
+ test('observe revoked mid-call → no terminal; inputs revoked mid-call → terminal still sent (§4.5)', () => {
165
+ const a = observer('a', [OBSERVE]);
166
+ const b = observer('b', [OBSERVE, INPUTS]);
167
+ const { emitter } = harness({ observers: [a, b] });
168
+ dispatch(emitter, 'scout', 'inf_1', { id: TOOLU(10), name: 'prov--a', input: {} });
169
+ a.grant = a.grant.without(OBSERVE);
170
+ b.grant = b.grant.without(INPUTS);
171
+ emitter.onResult('scout', TOOLU(10), { success: true });
172
+ assert.deepEqual(a.sent.map((p) => p.phase), ['started']);
173
+ assert.deepEqual(b.sent.map((p) => p.phase), ['started', 'completed']);
174
+ });
175
+ test('review #7 — a reconnected observer never gets a terminal for an opening its old transport saw', () => {
176
+ const o = observer('obs', [OBSERVE]);
177
+ const { emitter } = harness({ observers: [o] });
178
+ dispatch(emitter, 'scout', 'inf_1', { id: TOOLU(11), name: 'prov--a', input: {} });
179
+ o.transportEpoch++; // reconnect; grant re-established
180
+ emitter.onResult('scout', TOOLU(11), { success: true });
181
+ assert.deepEqual(o.sent.map((p) => p.phase), ['started']);
182
+ });
183
+ test('a filter change mid-call does not suppress the terminal (§6.5)', () => {
184
+ const o = observer('obs', [OBSERVE]);
185
+ const { emitter } = harness({ observers: [o] });
186
+ dispatch(emitter, 'scout', 'inf_1', { id: TOOLU(12), name: 'prov--a', input: {} });
187
+ o.toolObserveFilter = [];
188
+ emitter.onResult('scout', TOOLU(12), { success: true });
189
+ assert.deepEqual(o.sent.map((p) => p.phase), ['started', 'completed']);
190
+ });
191
+ test('terminals go only where the opening went', () => {
192
+ const early = observer('early', [OBSERVE]);
193
+ const late = observer('late', []);
194
+ const { emitter } = harness({ observers: [early, late] });
195
+ dispatch(emitter, 'scout', 'inf_1', { id: TOOLU(13), name: 'prov--a', input: {} });
196
+ late.grant = new CapabilityGrant(new Set([OBSERVE]), []);
197
+ emitter.onResult('scout', TOOLU(13), { success: true });
198
+ assert.deepEqual(early.sent.map((p) => p.phase), ['started', 'completed']);
199
+ assert.equal(late.sent.length, 0, 'granted mid-call: no terminal without an opening');
200
+ });
201
+ test('review #9 — ids: provider-unique toolu ids kept; everything else and any repeat minted (§3)', () => {
202
+ const o = observer('obs', [OBSERVE]);
203
+ const { emitter } = harness({ observers: [o] });
204
+ const run = (id) => {
205
+ dispatch(emitter, 'scout', 'inf', { id, name: 'prov--a', input: {} });
206
+ emitter.onResult('scout', id, { success: true });
207
+ };
208
+ run('call_0');
209
+ run('call_0');
210
+ run(TOOLU(14));
211
+ run(TOOLU(14));
212
+ run('call_abcdefghijklmnopqrstuvwxyz0123'); // long, but not a provider-guaranteed format
213
+ const opened = o.sent.filter((p) => p.phase === 'started').map((p) => p.toolCallId);
214
+ assert.equal(new Set(opened).size, 5, `ids must be unique: ${opened.join(', ')}`);
215
+ assert.ok(opened[0].startsWith('call_0~'));
216
+ assert.equal(opened[2], TOOLU(14), 'a provider-unique id is used as is');
217
+ assert.notEqual(opened[3], TOOLU(14), 'its repeat is minted over');
218
+ assert.ok(opened[4].startsWith('call_abcdefghijklmnopqrstuvwxyz0123~'), 'unknown formats are minted');
219
+ });
220
+ test('inert while nothing observes: register tracks nothing', () => {
221
+ const o = observer('obs', []);
222
+ const { emitter } = harness({ observers: [o] });
223
+ dispatch(emitter, 'scout', 'inf', { id: TOOLU(15), name: 'prov--a', input: {} });
224
+ assert.equal(emitter.openCount, 0);
225
+ });
226
+ test('the filter and the grant compose end to end', () => {
227
+ const o = observer('obs', [OBSERVE, INPUTS], rules([
228
+ { match: { serverTool: 'click' }, input: ['x', 'y'] },
229
+ { match: { class: 'comms' }, report: false },
230
+ { match: {} },
231
+ ]));
232
+ const { emitter } = harness({
233
+ observers: [o],
234
+ config: { obs: DEFAULT_INPUTS },
235
+ classes: { 'computer--click': ['computer'], 'chat--send': ['comms'], 'blender--execute': [] },
236
+ });
237
+ const go = (id, name, input) => {
238
+ dispatch(emitter, 'scout', 'inf', { id, name, input });
239
+ emitter.onResult('scout', id, { success: true });
240
+ };
241
+ go(TOOLU(20), 'computer--click', { x: 1, y: 2, button: 'left' });
242
+ go(TOOLU(21), 'chat--send', { text: 'private words' });
243
+ go(TOOLU(22), 'blender--execute', { code: 'import bpy' });
244
+ const started = o.sent.filter((p) => p.phase === 'started');
245
+ assert.deepEqual(started.map((p) => p.tool), ['computer--click', 'blender--execute']);
246
+ assert.deepEqual(started[0].input, { x: 1, y: 2 });
247
+ assert.equal(started[1].input, undefined);
248
+ assert.ok(!JSON.stringify(o.sent).includes('private words'));
249
+ assert.ok(!JSON.stringify(o.sent).includes('import bpy'));
250
+ });
251
+ });
252
+ // ── Grant computation and config robustness ─────────────────────────────────
253
+ describe('toolLifecycle grant', () => {
254
+ const caps = (o) => ({ version: '0.5', ...o });
255
+ const quiet = (fn) => {
256
+ const orig = console.error;
257
+ console.error = () => { };
258
+ try {
259
+ return fn();
260
+ }
261
+ finally {
262
+ console.error = orig;
263
+ }
264
+ };
265
+ const anyCall = {
266
+ toolCallId: TOOLU(30), inferenceId: 'inf', conversationId: 'scout', tool: 'prov--a',
267
+ class: ['shell'], serverId: 'prov', serverTool: 'a', input: {},
268
+ };
269
+ test('vector 49 — advertised but not granted by default', () => {
270
+ const g = quiet(() => computeGrant(caps({ toolLifecycle: true }), {}));
271
+ assert.equal(g.has(OBSERVE), false);
272
+ assert.equal(g.has(INPUTS), false);
273
+ assert.ok(g.deniedPaths.includes(OBSERVE) && g.deniedPaths.includes(INPUTS));
274
+ });
275
+ test('vector 50 — a policy object is the explicit grant of the path it states', () => {
276
+ const g1 = quiet(() => computeGrant(caps({ toolLifecycle: true }), { toolLifecycle: { observe: {} } }));
277
+ assert.equal(g1.has(OBSERVE), true);
278
+ assert.equal(g1.has(INPUTS), false);
279
+ const g2 = quiet(() => computeGrant(caps({ toolLifecycle: true }), { toolLifecycle: { observe: {}, inputs: { classes: 'default' } } }));
280
+ assert.equal(g2.has(INPUTS), true);
281
+ });
282
+ test('review #1 — `observe: false` (or null, or a string) grants nothing', () => {
283
+ for (const value of [false, null, 'yes', 0]) {
284
+ const g = quiet(() => computeGrant(caps({ toolLifecycle: true }), { toolLifecycle: { observe: value } }));
285
+ assert.equal(g.has(OBSERVE), false, JSON.stringify(value));
286
+ }
287
+ });
288
+ test('review #1 — a non-object narrowing under an explicit grant admits nothing', () => {
289
+ const o = observer('obs', [OBSERVE]);
290
+ for (const observe of [false, null, 'x', { tools: 'prov--*' }, { conversations: 7 }, { classes: 'shell' }]) {
291
+ assert.equal(openingFor(o, { observe }, anyCall, 'started'), null, JSON.stringify(observe));
292
+ }
293
+ assert.ok(openingFor(o, { observe: { tools: ['prov--*'] } }, anyCall, 'started'));
294
+ assert.ok(openingFor(o, undefined, anyCall, 'started'), 'absent narrowing = the grant is enough');
295
+ });
296
+ test('enabledCapabilities grants explicitly too; never beyond the advertisement', () => {
297
+ const g = quiet(() => computeGrant(caps({ toolLifecycle: { observe: true } }), { enabledCapabilities: ['toolLifecycle.*'] }));
298
+ assert.equal(g.has(OBSERVE), true);
299
+ assert.equal(g.has(INPUTS), false, 'inputs was not advertised');
300
+ });
301
+ test('review #8 — an unknown params member is rejected, not read as "no rules"', () => {
302
+ const r = parseToolObserveParams({ ruless: [{ match: {} }] });
303
+ assert.equal(r.ok, false);
304
+ assert.equal(parseToolObserveParams({ rules: [], _meta: { trace: 'x' } }).ok, true, "MCP's _meta is allowed");
305
+ });
306
+ });
307
+ //# sourceMappingURL=mcpl-tool-lifecycle-emitter.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcpl-tool-lifecycle-emitter.test.js","sourceRoot":"","sources":["../../test/mcpl-tool-lifecycle-emitter.test.ts"],"names":[],"mappings":"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"}