@clinebot/core 0.0.10 → 0.0.12

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 (55) hide show
  1. package/dist/agents/agent-config-loader.d.ts +1 -1
  2. package/dist/agents/agent-config-parser.d.ts +5 -2
  3. package/dist/agents/index.d.ts +1 -1
  4. package/dist/agents/plugin-config-loader.d.ts +4 -0
  5. package/dist/agents/plugin-sandbox-bootstrap.js +446 -0
  6. package/dist/agents/plugin-sandbox.d.ts +4 -0
  7. package/dist/index.node.d.ts +1 -1
  8. package/dist/index.node.js +658 -407
  9. package/dist/runtime/sandbox/subprocess-sandbox.d.ts +8 -1
  10. package/dist/session/default-session-manager.d.ts +5 -0
  11. package/dist/session/session-config-builder.d.ts +4 -1
  12. package/dist/session/session-manager.d.ts +1 -0
  13. package/dist/session/unified-session-persistence-service.d.ts +6 -0
  14. package/dist/session/utils/helpers.d.ts +1 -1
  15. package/dist/session/utils/types.d.ts +10 -0
  16. package/dist/tools/definitions.d.ts +2 -2
  17. package/dist/tools/presets.d.ts +3 -3
  18. package/dist/tools/schemas.d.ts +14 -14
  19. package/dist/types/config.d.ts +5 -0
  20. package/dist/types/events.d.ts +22 -0
  21. package/package.json +5 -4
  22. package/src/agents/agent-config-loader.test.ts +2 -0
  23. package/src/agents/agent-config-loader.ts +1 -0
  24. package/src/agents/agent-config-parser.ts +12 -5
  25. package/src/agents/index.ts +1 -0
  26. package/src/agents/plugin-config-loader.test.ts +49 -0
  27. package/src/agents/plugin-config-loader.ts +10 -73
  28. package/src/agents/plugin-loader.test.ts +128 -2
  29. package/src/agents/plugin-loader.ts +70 -5
  30. package/src/agents/plugin-sandbox-bootstrap.ts +445 -0
  31. package/src/agents/plugin-sandbox.test.ts +198 -1
  32. package/src/agents/plugin-sandbox.ts +223 -353
  33. package/src/index.node.ts +4 -0
  34. package/src/runtime/hook-file-hooks.test.ts +1 -1
  35. package/src/runtime/hook-file-hooks.ts +16 -6
  36. package/src/runtime/runtime-builder.test.ts +67 -0
  37. package/src/runtime/runtime-builder.ts +70 -16
  38. package/src/runtime/sandbox/subprocess-sandbox.ts +35 -11
  39. package/src/session/default-session-manager.e2e.test.ts +20 -1
  40. package/src/session/default-session-manager.test.ts +584 -1
  41. package/src/session/default-session-manager.ts +205 -1
  42. package/src/session/session-config-builder.ts +2 -0
  43. package/src/session/session-manager.ts +1 -0
  44. package/src/session/session-team-coordination.ts +30 -0
  45. package/src/session/unified-session-persistence-service.ts +45 -0
  46. package/src/session/utils/helpers.ts +13 -3
  47. package/src/session/utils/types.ts +11 -0
  48. package/src/storage/sqlite-team-store.ts +16 -5
  49. package/src/tools/definitions.test.ts +87 -8
  50. package/src/tools/definitions.ts +89 -70
  51. package/src/tools/presets.test.ts +2 -3
  52. package/src/tools/presets.ts +3 -3
  53. package/src/tools/schemas.ts +23 -22
  54. package/src/types/config.ts +5 -0
  55. package/src/types/events.ts +23 -0
@@ -1,4 +1,4 @@
1
- import { mkdtemp, rm, writeFile } from "node:fs/promises";
1
+ import { mkdir, mkdtemp, rm, writeFile } from "node:fs/promises";
2
2
  import { tmpdir } from "node:os";
3
3
  import { join } from "node:path";
4
4
  import type { AgentConfig, Tool, ToolContext } from "@clinebot/agents";
@@ -117,4 +117,201 @@ describe("plugin-sandbox", () => {
117
117
  await rm(dir, { recursive: true, force: true });
118
118
  }
119
119
  });
120
+
121
+ it("forwards sandbox plugin events to the host", async () => {
122
+ const dir = await mkdtemp(join(tmpdir(), "core-plugin-sandbox-events-"));
123
+ try {
124
+ const pluginPath = join(dir, "plugin-events.mjs");
125
+ await writeFile(
126
+ pluginPath,
127
+ [
128
+ "export default {",
129
+ " name: 'sandbox-events',",
130
+ " manifest: { capabilities: ['tools'] },",
131
+ " setup(api) {",
132
+ " api.registerTool({",
133
+ " name: 'emit_event',",
134
+ " description: 'emit host event',",
135
+ " inputSchema: { type: 'object', properties: { value: { type: 'string' } }, required: ['value'] },",
136
+ " execute: async (input) => {",
137
+ " globalThis.__clinePluginHost?.emitEvent?.('test_event', { value: input.value });",
138
+ " return { ok: true };",
139
+ " },",
140
+ " });",
141
+ " },",
142
+ "};",
143
+ ].join("\n"),
144
+ "utf8",
145
+ );
146
+
147
+ const events: Array<{ name: string; payload?: unknown }> = [];
148
+ const sandboxed = await loadSandboxedPlugins({
149
+ pluginPaths: [pluginPath],
150
+ onEvent: (event) => {
151
+ events.push(event);
152
+ },
153
+ });
154
+ try {
155
+ const extension = sandboxed.extensions?.[0];
156
+ const { tools, api } = createApiCapture();
157
+ await extension?.setup?.(api);
158
+ const tool = tools.find((entry) => entry.name === "emit_event");
159
+ await tool?.execute({ value: "hello" }, {
160
+ agentId: "agent-1",
161
+ conversationId: "conv-1",
162
+ iteration: 1,
163
+ } as ToolContext);
164
+ expect(events).toEqual([
165
+ {
166
+ name: "test_event",
167
+ payload: { value: "hello" },
168
+ },
169
+ ]);
170
+ } finally {
171
+ await sandboxed.shutdown();
172
+ }
173
+ } finally {
174
+ await rm(dir, { recursive: true, force: true });
175
+ }
176
+ });
177
+
178
+ it("loads TypeScript plugins in the sandbox process", async () => {
179
+ const dir = await mkdtemp(join(tmpdir(), "core-plugin-sandbox-ts-"));
180
+ try {
181
+ const pluginPath = join(dir, "plugin-ts.ts");
182
+ await writeFile(
183
+ pluginPath,
184
+ [
185
+ "const TOOL_NAME: string = 'sandbox_ts_echo';",
186
+ "export default {",
187
+ " name: 'sandbox-ts',",
188
+ " manifest: { capabilities: ['tools'] },",
189
+ " setup(api) {",
190
+ " api.registerTool({",
191
+ " name: TOOL_NAME,",
192
+ " description: 'echo',",
193
+ " inputSchema: { type: 'object', properties: { value: { type: 'string' } }, required: ['value'] },",
194
+ " execute: async (input) => ({ echoed: input.value }),",
195
+ " });",
196
+ " },",
197
+ "};",
198
+ ].join("\n"),
199
+ "utf8",
200
+ );
201
+
202
+ const sandboxed = await loadSandboxedPlugins({
203
+ pluginPaths: [pluginPath],
204
+ });
205
+ try {
206
+ const extension = sandboxed.extensions?.[0];
207
+ expect(extension?.name).toBe("sandbox-ts");
208
+ const { tools, api } = createApiCapture();
209
+ await extension?.setup?.(api);
210
+ const tool = tools.find((entry) => entry.name === "sandbox_ts_echo");
211
+ expect(tool).toBeDefined();
212
+ const result = await tool?.execute({ value: "ok" }, {
213
+ agentId: "agent-1",
214
+ conversationId: "conv-1",
215
+ iteration: 1,
216
+ } as ToolContext);
217
+ expect(result).toEqual({ echoed: "ok" });
218
+ } finally {
219
+ await sandboxed.shutdown();
220
+ }
221
+ } finally {
222
+ await rm(dir, { recursive: true, force: true });
223
+ }
224
+ });
225
+
226
+ it("resolves plugin-local dependencies in the sandbox process", async () => {
227
+ const dir = await mkdtemp(join(tmpdir(), "core-plugin-sandbox-deps-"));
228
+ try {
229
+ const depDir = join(dir, "node_modules", "sandbox-local-dep");
230
+ await mkdir(depDir, { recursive: true });
231
+ await writeFile(
232
+ join(depDir, "package.json"),
233
+ JSON.stringify({
234
+ name: "sandbox-local-dep",
235
+ type: "module",
236
+ exports: "./index.js",
237
+ }),
238
+ "utf8",
239
+ );
240
+ await writeFile(
241
+ join(depDir, "index.js"),
242
+ "export const depName = 'sandbox-local-dep';\n",
243
+ "utf8",
244
+ );
245
+ const pluginPath = join(dir, "plugin-dep.ts");
246
+ await writeFile(
247
+ pluginPath,
248
+ [
249
+ "import { depName } from 'sandbox-local-dep';",
250
+ "export default {",
251
+ " name: depName,",
252
+ " manifest: { capabilities: ['tools'] },",
253
+ "};",
254
+ ].join("\n"),
255
+ "utf8",
256
+ );
257
+
258
+ const sandboxed = await loadSandboxedPlugins({
259
+ pluginPaths: [pluginPath],
260
+ });
261
+ try {
262
+ expect(sandboxed.extensions?.[0]?.name).toBe("sandbox-local-dep");
263
+ } finally {
264
+ await sandboxed.shutdown();
265
+ }
266
+ } finally {
267
+ await rm(dir, { recursive: true, force: true });
268
+ }
269
+ });
270
+
271
+ it("prefers plugin-installed SDK packages in the sandbox process", async () => {
272
+ const dir = await mkdtemp(join(tmpdir(), "core-plugin-sandbox-sdk-"));
273
+ try {
274
+ const depDir = join(dir, "node_modules", "@clinebot", "shared");
275
+ await mkdir(depDir, { recursive: true });
276
+ await writeFile(
277
+ join(depDir, "package.json"),
278
+ JSON.stringify({
279
+ name: "@clinebot/shared",
280
+ type: "module",
281
+ exports: "./index.js",
282
+ }),
283
+ "utf8",
284
+ );
285
+ await writeFile(
286
+ join(depDir, "index.js"),
287
+ "export const sdkMarker = 'sandbox-plugin-installed-sdk';\n",
288
+ "utf8",
289
+ );
290
+ const pluginPath = join(dir, "plugin-sdk.ts");
291
+ await writeFile(
292
+ pluginPath,
293
+ [
294
+ "import { sdkMarker } from '@clinebot/shared';",
295
+ "export default {",
296
+ " name: sdkMarker,",
297
+ " manifest: { capabilities: ['tools'] },",
298
+ "};",
299
+ ].join("\n"),
300
+ "utf8",
301
+ );
302
+
303
+ const sandboxed = await loadSandboxedPlugins({
304
+ pluginPaths: [pluginPath],
305
+ });
306
+ try {
307
+ expect(sandboxed.extensions?.[0]?.name).toBe(
308
+ "sandbox-plugin-installed-sdk",
309
+ );
310
+ } finally {
311
+ await sandboxed.shutdown();
312
+ }
313
+ } finally {
314
+ await rm(dir, { recursive: true, force: true });
315
+ }
316
+ });
120
317
  });