toolcraft 0.0.5 → 0.0.7

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 (149) hide show
  1. package/README.md +1 -0
  2. package/dist/cli.d.ts +1 -0
  3. package/dist/cli.js +77 -59
  4. package/node_modules/@poe-code/agent-defs/dist/agents/claude-code.d.ts +2 -0
  5. package/node_modules/@poe-code/agent-defs/dist/agents/claude-code.js +15 -0
  6. package/node_modules/@poe-code/agent-defs/dist/agents/claude-desktop.d.ts +2 -0
  7. package/node_modules/@poe-code/agent-defs/dist/agents/claude-desktop.js +13 -0
  8. package/node_modules/@poe-code/agent-defs/dist/agents/codex.d.ts +2 -0
  9. package/node_modules/@poe-code/agent-defs/dist/agents/codex.js +14 -0
  10. package/node_modules/@poe-code/agent-defs/dist/agents/goose.d.ts +2 -0
  11. package/node_modules/@poe-code/agent-defs/dist/agents/goose.js +14 -0
  12. package/node_modules/@poe-code/agent-defs/dist/agents/index.d.ts +7 -0
  13. package/node_modules/@poe-code/agent-defs/dist/agents/index.js +7 -0
  14. package/node_modules/@poe-code/agent-defs/dist/agents/kimi.d.ts +2 -0
  15. package/node_modules/@poe-code/agent-defs/dist/agents/kimi.js +15 -0
  16. package/node_modules/@poe-code/agent-defs/dist/agents/opencode.d.ts +2 -0
  17. package/node_modules/@poe-code/agent-defs/dist/agents/opencode.js +14 -0
  18. package/node_modules/@poe-code/agent-defs/dist/agents/poe-agent.d.ts +2 -0
  19. package/node_modules/@poe-code/agent-defs/dist/agents/poe-agent.js +13 -0
  20. package/node_modules/@poe-code/agent-defs/dist/index.d.ts +5 -0
  21. package/node_modules/@poe-code/agent-defs/dist/index.js +3 -0
  22. package/node_modules/@poe-code/agent-defs/dist/registry.d.ts +3 -0
  23. package/node_modules/@poe-code/agent-defs/dist/registry.js +26 -0
  24. package/node_modules/@poe-code/agent-defs/dist/specifier.d.ts +7 -0
  25. package/node_modules/@poe-code/agent-defs/dist/specifier.js +27 -0
  26. package/node_modules/@poe-code/agent-defs/dist/types.d.ts +16 -0
  27. package/node_modules/@poe-code/agent-defs/dist/types.js +1 -0
  28. package/node_modules/@poe-code/agent-defs/package.json +20 -0
  29. package/node_modules/@poe-code/config-mutations/dist/execution/apply-mutation.d.ts +5 -0
  30. package/node_modules/@poe-code/config-mutations/dist/execution/apply-mutation.js +552 -0
  31. package/node_modules/@poe-code/config-mutations/dist/execution/path-utils.d.ts +17 -0
  32. package/node_modules/@poe-code/config-mutations/dist/execution/path-utils.js +58 -0
  33. package/node_modules/@poe-code/config-mutations/dist/execution/run-mutations.d.ts +7 -0
  34. package/node_modules/@poe-code/config-mutations/dist/execution/run-mutations.js +46 -0
  35. package/node_modules/@poe-code/config-mutations/dist/formats/index.d.ts +13 -0
  36. package/node_modules/@poe-code/config-mutations/dist/formats/index.js +49 -0
  37. package/node_modules/@poe-code/config-mutations/dist/formats/json.d.ts +31 -0
  38. package/node_modules/@poe-code/config-mutations/dist/formats/json.js +140 -0
  39. package/node_modules/@poe-code/config-mutations/dist/formats/toml.d.ts +2 -0
  40. package/node_modules/@poe-code/config-mutations/dist/formats/toml.js +72 -0
  41. package/node_modules/@poe-code/config-mutations/dist/formats/yaml.d.ts +2 -0
  42. package/node_modules/@poe-code/config-mutations/dist/formats/yaml.js +73 -0
  43. package/node_modules/@poe-code/config-mutations/dist/fs-utils.d.ts +18 -0
  44. package/node_modules/@poe-code/config-mutations/dist/fs-utils.js +45 -0
  45. package/node_modules/@poe-code/config-mutations/dist/index.d.ts +8 -0
  46. package/node_modules/@poe-code/config-mutations/dist/index.js +8 -0
  47. package/node_modules/@poe-code/config-mutations/dist/mutations/config-mutation.d.ts +47 -0
  48. package/node_modules/@poe-code/config-mutations/dist/mutations/config-mutation.js +34 -0
  49. package/node_modules/@poe-code/config-mutations/dist/mutations/file-mutation.d.ts +52 -0
  50. package/node_modules/@poe-code/config-mutations/dist/mutations/file-mutation.js +46 -0
  51. package/node_modules/@poe-code/config-mutations/dist/mutations/template-mutation.d.ts +40 -0
  52. package/node_modules/@poe-code/config-mutations/dist/mutations/template-mutation.js +32 -0
  53. package/node_modules/@poe-code/config-mutations/dist/template/render.d.ts +7 -0
  54. package/node_modules/@poe-code/config-mutations/dist/template/render.js +28 -0
  55. package/node_modules/@poe-code/config-mutations/dist/testing/format-utils.d.ts +7 -0
  56. package/node_modules/@poe-code/config-mutations/dist/testing/format-utils.js +21 -0
  57. package/node_modules/@poe-code/config-mutations/dist/testing/index.d.ts +3 -0
  58. package/node_modules/@poe-code/config-mutations/dist/testing/index.js +2 -0
  59. package/node_modules/@poe-code/config-mutations/dist/testing/mock-fs.d.ts +25 -0
  60. package/node_modules/@poe-code/config-mutations/dist/testing/mock-fs.js +170 -0
  61. package/node_modules/@poe-code/config-mutations/dist/types.d.ts +156 -0
  62. package/node_modules/@poe-code/config-mutations/dist/types.js +6 -0
  63. package/node_modules/@poe-code/config-mutations/package.json +33 -0
  64. package/node_modules/@poe-code/file-lock/README.md +52 -0
  65. package/node_modules/@poe-code/file-lock/dist/index.d.ts +1 -0
  66. package/node_modules/@poe-code/file-lock/dist/index.js +1 -0
  67. package/node_modules/@poe-code/file-lock/dist/lock.d.ts +27 -0
  68. package/node_modules/@poe-code/file-lock/dist/lock.js +203 -0
  69. package/node_modules/@poe-code/file-lock/package.json +23 -0
  70. package/node_modules/auth-store/README.md +47 -0
  71. package/node_modules/auth-store/dist/create-secret-store.d.ts +2 -0
  72. package/node_modules/auth-store/dist/create-secret-store.js +35 -0
  73. package/node_modules/auth-store/dist/encrypted-file-store.d.ts +39 -0
  74. package/node_modules/auth-store/dist/encrypted-file-store.js +156 -0
  75. package/node_modules/auth-store/dist/index.d.ts +7 -0
  76. package/node_modules/auth-store/dist/index.js +4 -0
  77. package/node_modules/auth-store/dist/keychain-store.d.ts +22 -0
  78. package/node_modules/auth-store/dist/keychain-store.js +111 -0
  79. package/node_modules/auth-store/dist/provider-store.d.ts +10 -0
  80. package/node_modules/auth-store/dist/provider-store.js +28 -0
  81. package/node_modules/auth-store/dist/types.d.ts +20 -0
  82. package/node_modules/auth-store/dist/types.js +1 -0
  83. package/node_modules/auth-store/package.json +25 -0
  84. package/node_modules/mcp-oauth/README.md +31 -0
  85. package/node_modules/mcp-oauth/dist/client/auth-store-session-store.d.ts +14 -0
  86. package/node_modules/mcp-oauth/dist/client/auth-store-session-store.js +97 -0
  87. package/node_modules/mcp-oauth/dist/client/authorization-state.d.ts +8 -0
  88. package/node_modules/mcp-oauth/dist/client/authorization-state.js +34 -0
  89. package/node_modules/mcp-oauth/dist/client/default-oauth-client-provider.d.ts +3 -0
  90. package/node_modules/mcp-oauth/dist/client/default-oauth-client-provider.js +491 -0
  91. package/node_modules/mcp-oauth/dist/client/loopback-authorization.d.ts +20 -0
  92. package/node_modules/mcp-oauth/dist/client/loopback-authorization.js +169 -0
  93. package/node_modules/mcp-oauth/dist/client/pkce.d.ts +2 -0
  94. package/node_modules/mcp-oauth/dist/client/pkce.js +7 -0
  95. package/node_modules/mcp-oauth/dist/client/token-endpoint.d.ts +40 -0
  96. package/node_modules/mcp-oauth/dist/client/token-endpoint.js +143 -0
  97. package/node_modules/mcp-oauth/dist/client/types.d.ts +113 -0
  98. package/node_modules/mcp-oauth/dist/client/types.js +1 -0
  99. package/node_modules/mcp-oauth/dist/index.d.ts +10 -0
  100. package/node_modules/mcp-oauth/dist/index.js +7 -0
  101. package/node_modules/mcp-oauth/dist/resource-indicator.d.ts +1 -0
  102. package/node_modules/mcp-oauth/dist/resource-indicator.js +11 -0
  103. package/node_modules/mcp-oauth/dist/server/jwks-token-verifier.d.ts +27 -0
  104. package/node_modules/mcp-oauth/dist/server/jwks-token-verifier.js +259 -0
  105. package/node_modules/mcp-oauth/dist/types.compile-check.d.ts +1 -0
  106. package/node_modules/mcp-oauth/dist/types.compile-check.js +22 -0
  107. package/node_modules/mcp-oauth/package.json +31 -0
  108. package/node_modules/tiny-mcp-client/.turbo/turbo-build.log +4 -0
  109. package/node_modules/tiny-mcp-client/dist/index.d.ts +2 -0
  110. package/node_modules/tiny-mcp-client/dist/index.js +1 -0
  111. package/node_modules/tiny-mcp-client/dist/internal.d.ts +547 -0
  112. package/node_modules/tiny-mcp-client/dist/internal.js +2404 -0
  113. package/node_modules/tiny-mcp-client/dist/jsonrpc-types.compile-check.d.ts +1 -0
  114. package/node_modules/tiny-mcp-client/dist/jsonrpc-types.compile-check.js +37 -0
  115. package/node_modules/tiny-mcp-client/dist/mcp-lifecycle-types.compile-check.d.ts +1 -0
  116. package/node_modules/tiny-mcp-client/dist/mcp-lifecycle-types.compile-check.js +50 -0
  117. package/node_modules/tiny-mcp-client/dist/mcp-prompt-types.compile-check.d.ts +1 -0
  118. package/node_modules/tiny-mcp-client/dist/mcp-prompt-types.compile-check.js +50 -0
  119. package/node_modules/tiny-mcp-client/dist/mcp-resource-types.compile-check.d.ts +1 -0
  120. package/node_modules/tiny-mcp-client/dist/mcp-resource-types.compile-check.js +51 -0
  121. package/node_modules/tiny-mcp-client/dist/mcp-tool-types.compile-check.d.ts +1 -0
  122. package/node_modules/tiny-mcp-client/dist/mcp-tool-types.compile-check.js +89 -0
  123. package/node_modules/tiny-mcp-client/dist/mcp-transport-types.compile-check.d.ts +1 -0
  124. package/node_modules/tiny-mcp-client/dist/mcp-transport-types.compile-check.js +56 -0
  125. package/node_modules/tiny-mcp-client/dist/mcp-utility-types.compile-check.d.ts +1 -0
  126. package/node_modules/tiny-mcp-client/dist/mcp-utility-types.compile-check.js +145 -0
  127. package/node_modules/tiny-mcp-client/dist/oauth-discovery.d.ts +24 -0
  128. package/node_modules/tiny-mcp-client/dist/oauth-discovery.js +385 -0
  129. package/node_modules/tiny-mcp-client/package.json +22 -0
  130. package/node_modules/tiny-mcp-client/src/http-oauth.integration.test.ts +823 -0
  131. package/node_modules/tiny-mcp-client/src/http-oauth.test.ts +882 -0
  132. package/node_modules/tiny-mcp-client/src/index.ts +94 -0
  133. package/node_modules/tiny-mcp-client/src/internal.ts +3566 -0
  134. package/node_modules/tiny-mcp-client/src/jsonrpc-types.compile-check.ts +66 -0
  135. package/node_modules/tiny-mcp-client/src/mcp-client-http-transport.integration.test.ts +222 -0
  136. package/node_modules/tiny-mcp-client/src/mcp-client-sdk.test.ts +1294 -0
  137. package/node_modules/tiny-mcp-client/src/mcp-client-tiny-stdio-test-server-tools.test.ts +143 -0
  138. package/node_modules/tiny-mcp-client/src/mcp-lifecycle-types.compile-check.ts +65 -0
  139. package/node_modules/tiny-mcp-client/src/mcp-prompt-types.compile-check.ts +66 -0
  140. package/node_modules/tiny-mcp-client/src/mcp-resource-types.compile-check.ts +70 -0
  141. package/node_modules/tiny-mcp-client/src/mcp-tool-types.compile-check.ts +117 -0
  142. package/node_modules/tiny-mcp-client/src/mcp-transport-types.compile-check.ts +75 -0
  143. package/node_modules/tiny-mcp-client/src/mcp-utility-types.compile-check.ts +181 -0
  144. package/node_modules/tiny-mcp-client/src/mock-servers.test.ts +980 -0
  145. package/node_modules/tiny-mcp-client/src/oauth-discovery.ts +583 -0
  146. package/node_modules/tiny-mcp-client/src/transports.test.ts +8139 -0
  147. package/node_modules/tiny-mcp-client/src/utilities.test.ts +372 -0
  148. package/node_modules/tiny-mcp-client/tsconfig.json +11 -0
  149. package/package.json +24 -11
@@ -0,0 +1,372 @@
1
+ import { once } from "node:events";
2
+ import { Readable } from "node:stream";
3
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
4
+ import { InMemoryTransport } from "@modelcontextprotocol/sdk/inMemory.js";
5
+ import type { JSONRPCMessage } from "@modelcontextprotocol/sdk/types.js";
6
+ import { createTestServer } from "tiny-stdio-mcp-test-server";
7
+ import { afterEach, describe, expect, it, vi } from "vitest";
8
+ import {
9
+ type McpTransport,
10
+ type JsonRpcRequest,
11
+ ERROR_INTERNAL,
12
+ ERROR_INVALID_PARAMS,
13
+ ERROR_INVALID_REQUEST,
14
+ ERROR_METHOD_NOT_FOUND,
15
+ ERROR_PARSE,
16
+ McpError,
17
+ SdkTransportAdapter,
18
+ createSdkTestPair,
19
+ createInMemoryTransportPair,
20
+ createTestPair,
21
+ parseJsonRpcMessage,
22
+ serializeJsonRpcMessage,
23
+ readLines,
24
+ } from "./internal.js";
25
+ import * as api from "./index.js";
26
+
27
+ const cleanup: Array<() => void> = [];
28
+
29
+ afterEach(() => {
30
+ while (cleanup.length > 0) {
31
+ cleanup.pop()?.();
32
+ }
33
+ });
34
+
35
+ async function readSingleLine(stream: Readable): Promise<string> {
36
+ for await (const line of readLines(stream)) {
37
+ return line;
38
+ }
39
+
40
+ throw new Error("Stream ended before a line was read");
41
+ }
42
+
43
+ class FakeClient {
44
+ connectedTransport: McpTransport | undefined;
45
+
46
+ readonly connect = vi.fn(async (transport: McpTransport) => {
47
+ this.connectedTransport = transport;
48
+ });
49
+
50
+ readonly close = vi.fn(async () => {});
51
+ }
52
+
53
+ async function collect<T>(iterable: AsyncIterable<T>): Promise<T[]> {
54
+ const items: T[] = [];
55
+ for await (const item of iterable) {
56
+ items.push(item);
57
+ }
58
+
59
+ return items;
60
+ }
61
+
62
+ // --- createInMemoryTransportPair ---
63
+
64
+ describe("createInMemoryTransportPair", () => {
65
+ it("writes from client transport to server transport readable", async () => {
66
+ const { clientTransport, serverTransport } = createInMemoryTransportPair();
67
+ cleanup.push(() => clientTransport.dispose());
68
+
69
+ clientTransport.writable.write('{"from":"client"}\n');
70
+
71
+ await expect(readSingleLine(serverTransport.readable)).resolves.toBe(
72
+ '{"from":"client"}'
73
+ );
74
+ });
75
+
76
+ it("writes from server transport to client transport readable", async () => {
77
+ const { clientTransport, serverTransport } = createInMemoryTransportPair();
78
+ cleanup.push(() => clientTransport.dispose());
79
+
80
+ serverTransport.writable.write('{"from":"server"}\n');
81
+
82
+ await expect(readSingleLine(clientTransport.readable)).resolves.toBe(
83
+ '{"from":"server"}'
84
+ );
85
+ });
86
+
87
+ it("dispose on client transport ends both readable streams", async () => {
88
+ const { clientTransport, serverTransport } = createInMemoryTransportPair();
89
+ const clientReadableEnded = once(clientTransport.readable, "end");
90
+ const serverReadableEnded = once(serverTransport.readable, "end");
91
+
92
+ clientTransport.readable.resume();
93
+ serverTransport.readable.resume();
94
+ clientTransport.dispose();
95
+
96
+ await Promise.all([clientReadableEnded, serverReadableEnded]);
97
+ await expect(clientTransport.closed).resolves.toMatchObject({
98
+ reason: expect.any(Error),
99
+ });
100
+ });
101
+ });
102
+
103
+ // --- createSdkTestPair ---
104
+
105
+ describe("createSdkTestPair", () => {
106
+ it("connects sdk server to in-memory transport and returns cleanup", async () => {
107
+ const server = new Server({ name: "test-server", version: "1.0.0" });
108
+ const connectSpy = vi.spyOn(server, "connect");
109
+ const client = new FakeClient();
110
+
111
+ const { client: connectedClient, cleanup: pairCleanup } = await createSdkTestPair(
112
+ server,
113
+ () => client
114
+ );
115
+
116
+ expect(connectedClient).toBe(client);
117
+ expect(connectSpy).toHaveBeenCalledTimes(1);
118
+ expect(client.connect).toHaveBeenCalledTimes(1);
119
+ expect(client.connectedTransport).toBeInstanceOf(SdkTransportAdapter);
120
+
121
+ const serverTransport = connectSpy.mock.calls[0]?.[0];
122
+ if (serverTransport === undefined) {
123
+ throw new Error("Expected server connect transport argument");
124
+ }
125
+
126
+ const closeSpy = vi.spyOn(serverTransport, "close");
127
+
128
+ await pairCleanup();
129
+
130
+ expect(client.close).toHaveBeenCalledTimes(1);
131
+ expect(closeSpy).toHaveBeenCalled();
132
+ await expect(client.connectedTransport?.closed).resolves.toMatchObject({
133
+ reason: expect.any(Error),
134
+ });
135
+ });
136
+ });
137
+
138
+ // --- createTestPair ---
139
+
140
+ describe("createTestPair", () => {
141
+ it("connects tiny server to in-memory transport and returns cleanup", async () => {
142
+ const server = createTestServer();
143
+ const connectSpy = vi.spyOn(server, "connect");
144
+ const client = new FakeClient();
145
+
146
+ const { client: connectedClient, cleanup: pairCleanup } = await createTestPair(
147
+ server,
148
+ () => client
149
+ );
150
+
151
+ expect(connectedClient).toBe(client);
152
+ expect(connectSpy).toHaveBeenCalledTimes(1);
153
+ expect(client.connect).toHaveBeenCalledTimes(1);
154
+
155
+ const serverTransport = connectSpy.mock.calls[0]?.[0];
156
+ if (serverTransport === undefined) {
157
+ throw new Error("Expected server connect transport argument");
158
+ }
159
+
160
+ if (client.connectedTransport === undefined) {
161
+ throw new Error("Expected client to receive transport");
162
+ }
163
+
164
+ serverTransport.writable.write('{"from":"server"}\n');
165
+ await expect(readSingleLine(client.connectedTransport.readable)).resolves.toBe(
166
+ '{"from":"server"}'
167
+ );
168
+
169
+ await pairCleanup();
170
+
171
+ expect(client.close).toHaveBeenCalledTimes(1);
172
+ await expect(client.connectedTransport.closed).resolves.toMatchObject({
173
+ reason: expect.any(Error),
174
+ });
175
+ });
176
+ });
177
+
178
+ // --- index public API exports ---
179
+
180
+ describe("index public API exports", () => {
181
+ it("exports required runtime symbols", () => {
182
+ expect(api).toHaveProperty("McpClient");
183
+ expect(api).toHaveProperty("StdioTransport");
184
+ expect(api).toHaveProperty("HttpTransport");
185
+ expect(api).toHaveProperty("McpError");
186
+ expect(api).toHaveProperty("JsonRpcMessageLayer");
187
+ expect(api).toHaveProperty("createTestPair");
188
+ expect(api).toHaveProperty("createInMemoryTransportPair");
189
+ expect(api).toHaveProperty("createSdkTestPair");
190
+
191
+ expect(api).toHaveProperty("ERROR_PARSE", -32700);
192
+ expect(api).toHaveProperty("ERROR_INVALID_REQUEST", -32600);
193
+ expect(api).toHaveProperty("ERROR_METHOD_NOT_FOUND", -32601);
194
+ expect(api).toHaveProperty("ERROR_INVALID_PARAMS", -32602);
195
+ expect(api).toHaveProperty("ERROR_INTERNAL", -32603);
196
+ });
197
+
198
+ it("does not export internal helpers", () => {
199
+ expect(api).not.toHaveProperty("readLines");
200
+ expect(api).not.toHaveProperty("parseJsonRpcMessage");
201
+ expect(api).not.toHaveProperty("serializeJsonRpcMessage");
202
+ expect(api).not.toHaveProperty("SseParser");
203
+ expect(api).not.toHaveProperty("SdkTransportAdapter");
204
+ expect(api).not.toHaveProperty("createMockEchoToolServer");
205
+ expect(api).not.toHaveProperty("createMockResourceServer");
206
+ expect(api).not.toHaveProperty("createMockPromptServer");
207
+ expect(api).not.toHaveProperty("createMockSlowToolServer");
208
+ });
209
+ });
210
+
211
+ // --- McpError ---
212
+
213
+ describe("McpError", () => {
214
+ it("defines standard JSON-RPC error code constants", () => {
215
+ expect(ERROR_PARSE).toBe(-32700);
216
+ expect(ERROR_INVALID_REQUEST).toBe(-32600);
217
+ expect(ERROR_METHOD_NOT_FOUND).toBe(-32601);
218
+ expect(ERROR_INVALID_PARAMS).toBe(-32602);
219
+ expect(ERROR_INTERNAL).toBe(-32603);
220
+ });
221
+
222
+ it("constructs with code, message, and data", () => {
223
+ const data = { field: "path" };
224
+ const error = new McpError(-32602, "Invalid params", data);
225
+
226
+ expect(error).toBeInstanceOf(Error);
227
+ expect(error).toBeInstanceOf(McpError);
228
+ expect(error.name).toBe("McpError");
229
+ expect(error.code).toBe(-32602);
230
+ expect(error.message).toBe("Invalid params");
231
+ expect(error.data).toBe(data);
232
+ expect(Object.prototype.hasOwnProperty.call(error, "data")).toBe(true);
233
+ });
234
+
235
+ it("does not define data when omitted", () => {
236
+ const error = new McpError(-32600, "Invalid request");
237
+
238
+ expect(error.data).toBeUndefined();
239
+ expect(Object.prototype.hasOwnProperty.call(error, "data")).toBe(false);
240
+ });
241
+
242
+ it("passes instanceof checks", () => {
243
+ const error: Error = new McpError(-32603, "Internal error");
244
+
245
+ expect(error instanceof Error).toBe(true);
246
+ expect(error instanceof McpError).toBe(true);
247
+ });
248
+ });
249
+
250
+ // --- readLines ---
251
+
252
+ describe("readLines", () => {
253
+ it("yields complete lines from a single chunk with multiple lines", async () => {
254
+ const stream = Readable.from(["alpha\nbeta\ngamma\n"]);
255
+
256
+ await expect(collect(readLines(stream))).resolves.toEqual(["alpha", "beta", "gamma"]);
257
+ });
258
+
259
+ it("handles lines split across multiple chunks", async () => {
260
+ const stream = Readable.from(["al", "pha\nbe", "ta\ngam", "ma"]);
261
+
262
+ await expect(collect(readLines(stream))).resolves.toEqual(["alpha", "beta", "gamma"]);
263
+ });
264
+
265
+ it("strips carriage returns for CR+LF line endings", async () => {
266
+ const stream = Readable.from(["alpha\r", "\nbeta\r\n", "gamma\r\n"]);
267
+
268
+ await expect(collect(readLines(stream))).resolves.toEqual(["alpha", "beta", "gamma"]);
269
+ });
270
+
271
+ it("yields remaining buffered content when stream closes without trailing newline", async () => {
272
+ const stream = Readable.from(["alpha\nbeta"]);
273
+
274
+ await expect(collect(readLines(stream))).resolves.toEqual(["alpha", "beta"]);
275
+ });
276
+
277
+ it("yields empty lines between delimiters", async () => {
278
+ const stream = Readable.from(["alpha\n\nbeta\n"]);
279
+
280
+ await expect(collect(readLines(stream))).resolves.toEqual(["alpha", "", "beta"]);
281
+ });
282
+ });
283
+
284
+ // --- serializeJsonRpcMessage ---
285
+
286
+ describe("serializeJsonRpcMessage", () => {
287
+ it("serializes JSON-RPC message to newline-delimited JSON", () => {
288
+ const message: JsonRpcRequest = {
289
+ jsonrpc: "2.0",
290
+ id: 1,
291
+ method: "tools/list",
292
+ params: { cursor: "next" },
293
+ };
294
+
295
+ const serialized = serializeJsonRpcMessage(message);
296
+
297
+ expect(serialized).toBe(`${JSON.stringify(message)}\n`);
298
+ expect(serialized.endsWith("\n")).toBe(true);
299
+ });
300
+
301
+ it("round-trips through parseJsonRpcMessage", () => {
302
+ const message: JsonRpcRequest = {
303
+ jsonrpc: "2.0",
304
+ id: "request-1",
305
+ method: "tools/call",
306
+ params: {
307
+ name: "echo",
308
+ arguments: { text: "hello" },
309
+ },
310
+ };
311
+
312
+ const parsed = parseJsonRpcMessage(serializeJsonRpcMessage(message));
313
+
314
+ expect(parsed).toEqual({
315
+ type: "request",
316
+ message,
317
+ });
318
+ });
319
+ });
320
+
321
+ // --- SdkTransportAdapter ---
322
+
323
+ describe("SdkTransportAdapter", () => {
324
+ it("passes messages bidirectionally between sdk transport and line streams", async () => {
325
+ const [adapterSide, peerSide] = InMemoryTransport.createLinkedPair();
326
+ const adapter = new SdkTransportAdapter(adapterSide);
327
+ cleanup.push(() => adapter.dispose());
328
+
329
+ const messageForPeer: JSONRPCMessage = {
330
+ jsonrpc: "2.0",
331
+ id: 1,
332
+ method: "tools/list",
333
+ };
334
+
335
+ const onPeerMessage = new Promise<JSONRPCMessage>((resolve) => {
336
+ peerSide.onmessage = (message) => {
337
+ resolve(message);
338
+ };
339
+ });
340
+
341
+ adapter.writable.write(`${JSON.stringify(messageForPeer)}\n`);
342
+
343
+ await expect(onPeerMessage).resolves.toEqual(messageForPeer);
344
+
345
+ const messageForAdapter: JSONRPCMessage = {
346
+ jsonrpc: "2.0",
347
+ id: 1,
348
+ result: { tools: [] },
349
+ };
350
+
351
+ await peerSide.send(messageForAdapter);
352
+
353
+ await expect(readSingleLine(adapter.readable)).resolves.toBe(
354
+ JSON.stringify(messageForAdapter)
355
+ );
356
+ });
357
+
358
+ it("resolves closed when disposed", async () => {
359
+ const [adapterSide] = InMemoryTransport.createLinkedPair();
360
+ const adapter = new SdkTransportAdapter(adapterSide);
361
+
362
+ const readableEnded = once(adapter.readable, "end");
363
+ adapter.readable.resume();
364
+
365
+ adapter.dispose();
366
+
367
+ await readableEnded;
368
+ await expect(adapter.closed).resolves.toMatchObject({
369
+ reason: expect.any(Error),
370
+ });
371
+ });
372
+ });
@@ -0,0 +1,11 @@
1
+ {
2
+ "extends": "../../tsconfig.json",
3
+ "compilerOptions": {
4
+ "outDir": "dist",
5
+ "rootDir": "src",
6
+ "noEmit": false,
7
+ "declaration": true
8
+ },
9
+ "include": ["src"],
10
+ "exclude": ["**/*.test.ts"]
11
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "toolcraft",
3
- "version": "0.0.5",
3
+ "version": "0.0.7",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -35,22 +35,17 @@
35
35
  "test": "cd ../.. && vitest run packages/toolcraft/src",
36
36
  "test:unit": "cd ../.. && vitest run packages/toolcraft/src",
37
37
  "lint": "cd ../.. && eslint packages/toolcraft/src --ext ts && tsc -p packages/toolcraft/tsconfig.json --noEmit",
38
- "prepack": "node ../../scripts/manage-bundled-workspace-deps.mjs prepare . @poe-code/design-system @poe-code/agent-mcp-config @poe-code/agent-human-in-loop @poe-code/task-list",
39
- "postpack": "node ../../scripts/manage-bundled-workspace-deps.mjs cleanup . @poe-code/design-system @poe-code/agent-mcp-config @poe-code/agent-human-in-loop @poe-code/task-list"
38
+ "prepack": "node ../../scripts/manage-bundled-workspace-deps.mjs prepare . @poe-code/design-system @poe-code/agent-mcp-config @poe-code/agent-human-in-loop @poe-code/task-list @poe-code/file-lock @poe-code/agent-defs @poe-code/config-mutations tiny-mcp-client mcp-oauth auth-store",
39
+ "postpack": "node ../../scripts/manage-bundled-workspace-deps.mjs cleanup . @poe-code/design-system @poe-code/agent-mcp-config @poe-code/agent-human-in-loop @poe-code/task-list @poe-code/file-lock @poe-code/agent-defs @poe-code/config-mutations tiny-mcp-client mcp-oauth auth-store"
40
40
  },
41
41
  "dependencies": {
42
42
  "@clack/core": "^1.0.0",
43
43
  "@clack/prompts": "^1.0.0",
44
- "@poe-code/agent-human-in-loop": "*",
45
- "@poe-code/agent-mcp-config": "*",
46
- "@poe-code/design-system": "^0.0.1",
47
- "@poe-code/task-list": "*",
48
44
  "chalk": "^5.6.2",
49
45
  "commander": "^14.0.3",
50
46
  "console-table-printer": "^2.15.0",
51
- "tiny-mcp-client": "*",
52
47
  "tiny-stdio-mcp-server": "^0.1.0",
53
- "toolcraft-schema": "^0.0.5"
48
+ "toolcraft-schema": "^0.0.7"
54
49
  },
55
50
  "files": [
56
51
  "dist"
@@ -67,6 +62,24 @@
67
62
  "@poe-code/design-system",
68
63
  "@poe-code/agent-mcp-config",
69
64
  "@poe-code/agent-human-in-loop",
70
- "@poe-code/task-list"
71
- ]
65
+ "@poe-code/task-list",
66
+ "@poe-code/file-lock",
67
+ "@poe-code/agent-defs",
68
+ "@poe-code/config-mutations",
69
+ "tiny-mcp-client",
70
+ "mcp-oauth",
71
+ "auth-store"
72
+ ],
73
+ "optionalDependencies": {
74
+ "@poe-code/agent-defs": "*",
75
+ "@poe-code/agent-human-in-loop": "*",
76
+ "@poe-code/agent-mcp-config": "*",
77
+ "@poe-code/config-mutations": "*",
78
+ "@poe-code/design-system": "^0.0.1",
79
+ "@poe-code/file-lock": "*",
80
+ "@poe-code/task-list": "*",
81
+ "auth-store": "*",
82
+ "mcp-oauth": "*",
83
+ "tiny-mcp-client": "*"
84
+ }
72
85
  }