@clinebot/core 0.0.35 → 0.0.36
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.
- package/README.md +1 -2
- package/dist/ClineCore.d.ts +53 -39
- package/dist/ClineCore.d.ts.map +1 -1
- package/dist/account/index.d.ts +1 -1
- package/dist/account/index.d.ts.map +1 -1
- package/dist/account/rpc.d.ts +6 -6
- package/dist/account/rpc.d.ts.map +1 -1
- package/dist/cron/index.d.ts +6 -0
- package/dist/cron/index.d.ts.map +1 -0
- package/dist/cron/resource-limiter.d.ts +9 -0
- package/dist/cron/resource-limiter.d.ts.map +1 -0
- package/dist/cron/schedule-command-service.d.ts +10 -0
- package/dist/cron/schedule-command-service.d.ts.map +1 -0
- package/dist/cron/schedule-service.d.ts +100 -0
- package/dist/cron/schedule-service.d.ts.map +1 -0
- package/dist/cron/scheduler.d.ts +66 -0
- package/dist/cron/scheduler.d.ts.map +1 -0
- package/dist/cron/sqlite-schedule-store.d.ts +52 -0
- package/dist/cron/sqlite-schedule-store.d.ts.map +1 -0
- package/dist/extensions/config/agent-config-loader.d.ts +4 -3
- package/dist/extensions/config/agent-config-loader.d.ts.map +1 -1
- package/dist/extensions/config/runtime-commands.d.ts +1 -0
- package/dist/extensions/config/runtime-commands.d.ts.map +1 -1
- package/dist/extensions/config/user-instruction-config-loader.d.ts +1 -0
- package/dist/extensions/config/user-instruction-config-loader.d.ts.map +1 -1
- package/dist/extensions/context/agentic-compaction.d.ts +2 -2
- package/dist/extensions/context/agentic-compaction.d.ts.map +1 -1
- package/dist/extensions/context/compaction-shared.d.ts +5 -4
- package/dist/extensions/context/compaction-shared.d.ts.map +1 -1
- package/dist/extensions/context/compaction.d.ts.map +1 -1
- package/dist/extensions/plugin/plugin-config-loader.d.ts +9 -2
- package/dist/extensions/plugin/plugin-config-loader.d.ts.map +1 -1
- package/dist/extensions/plugin/plugin-loader.d.ts +5 -3
- package/dist/extensions/plugin/plugin-loader.d.ts.map +1 -1
- package/dist/extensions/plugin/plugin-module-import.d.ts.map +1 -1
- package/dist/extensions/plugin/plugin-sandbox.d.ts +15 -2
- package/dist/extensions/plugin/plugin-sandbox.d.ts.map +1 -1
- package/dist/extensions/plugin/plugin-targeting.d.ts +7 -0
- package/dist/extensions/plugin/plugin-targeting.d.ts.map +1 -0
- package/dist/extensions/plugin-sandbox-bootstrap.js +211 -211
- package/dist/extensions/tools/definitions.d.ts +1 -1
- package/dist/extensions/tools/definitions.d.ts.map +1 -1
- package/dist/extensions/tools/executors/apply-patch.d.ts +3 -1
- package/dist/extensions/tools/executors/apply-patch.d.ts.map +1 -1
- package/dist/extensions/tools/executors/search.d.ts +1 -1
- package/dist/extensions/tools/executors/search.d.ts.map +1 -1
- package/dist/extensions/tools/index.d.ts +2 -0
- package/dist/extensions/tools/index.d.ts.map +1 -1
- package/dist/extensions/tools/presets.d.ts +26 -43
- package/dist/extensions/tools/presets.d.ts.map +1 -1
- package/dist/extensions/tools/runtime.d.ts +25 -0
- package/dist/extensions/tools/runtime.d.ts.map +1 -0
- package/dist/extensions/tools/schemas.d.ts.map +1 -1
- package/dist/extensions/tools/team/team-tools.d.ts +1 -0
- package/dist/extensions/tools/team/team-tools.d.ts.map +1 -1
- package/dist/hooks/hook-file-hooks.d.ts +4 -1
- package/dist/hooks/hook-file-hooks.d.ts.map +1 -1
- package/dist/hooks/index.d.ts +0 -1
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/subprocess.d.ts +8 -1
- package/dist/hooks/subprocess.d.ts.map +1 -1
- package/dist/hub/browser-websocket.d.ts +18 -0
- package/dist/hub/browser-websocket.d.ts.map +1 -0
- package/dist/hub/client.d.ts +45 -0
- package/dist/hub/client.d.ts.map +1 -0
- package/dist/hub/connect.d.ts +15 -0
- package/dist/hub/connect.d.ts.map +1 -0
- package/dist/hub/daemon-entry.d.ts +2 -0
- package/dist/hub/daemon-entry.d.ts.map +1 -0
- package/dist/hub/daemon-entry.js +1045 -0
- package/dist/hub/daemon.d.ts +5 -0
- package/dist/hub/daemon.d.ts.map +1 -0
- package/dist/hub/defaults.d.ts +13 -0
- package/dist/hub/defaults.d.ts.map +1 -0
- package/dist/hub/discovery.d.ts +29 -0
- package/dist/hub/discovery.d.ts.map +1 -0
- package/dist/hub/index.d.ts +15 -0
- package/dist/hub/index.d.ts.map +1 -0
- package/dist/hub/index.js +1044 -0
- package/dist/hub/native-transport.d.ts +17 -0
- package/dist/hub/native-transport.d.ts.map +1 -0
- package/dist/hub/runtime-handlers.d.ts +11 -0
- package/dist/hub/runtime-handlers.d.ts.map +1 -0
- package/dist/hub/server.d.ts +86 -0
- package/dist/hub/server.d.ts.map +1 -0
- package/dist/hub/session-client.d.ts +87 -0
- package/dist/hub/session-client.d.ts.map +1 -0
- package/dist/hub/start-shared-server.d.ts +19 -0
- package/dist/hub/start-shared-server.d.ts.map +1 -0
- package/dist/hub/transport.d.ts +8 -0
- package/dist/hub/transport.d.ts.map +1 -0
- package/dist/hub/ui-client.d.ts +44 -0
- package/dist/hub/ui-client.d.ts.map +1 -0
- package/dist/hub/workspace.d.ts +4 -0
- package/dist/hub/workspace.d.ts.map +1 -0
- package/dist/index.d.ts +26 -15
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +498 -476
- package/dist/llms/configured-provider-registry.d.ts +28 -0
- package/dist/llms/configured-provider-registry.d.ts.map +1 -0
- package/dist/llms/provider-defaults.d.ts +27 -0
- package/dist/llms/provider-defaults.d.ts.map +1 -0
- package/dist/llms/provider-settings.d.ts +202 -0
- package/dist/llms/provider-settings.d.ts.map +1 -0
- package/dist/llms/runtime-config.d.ts +4 -0
- package/dist/llms/runtime-config.d.ts.map +1 -0
- package/dist/llms/runtime-registry.d.ts +20 -0
- package/dist/llms/runtime-registry.d.ts.map +1 -0
- package/dist/llms/runtime-types.d.ts +85 -0
- package/dist/llms/runtime-types.d.ts.map +1 -0
- package/dist/runtime/host.d.ts +1 -2
- package/dist/runtime/host.d.ts.map +1 -1
- package/dist/runtime/rules.d.ts +1 -0
- package/dist/runtime/rules.d.ts.map +1 -1
- package/dist/runtime/runtime-builder.d.ts.map +1 -1
- package/dist/runtime/runtime-host.d.ts +22 -24
- package/dist/runtime/runtime-host.d.ts.map +1 -1
- package/dist/runtime/runtime-oauth-token-manager.d.ts.map +1 -1
- package/dist/runtime/session-runtime.d.ts +1 -19
- package/dist/runtime/session-runtime.d.ts.map +1 -1
- package/dist/services/global-settings.d.ts +12 -0
- package/dist/services/global-settings.d.ts.map +1 -0
- package/dist/services/local-runtime-bootstrap.d.ts +9 -3
- package/dist/services/local-runtime-bootstrap.d.ts.map +1 -1
- package/dist/services/plugin-tools.d.ts +16 -0
- package/dist/services/plugin-tools.d.ts.map +1 -0
- package/dist/services/providers/local-provider-registry.d.ts +4 -4
- package/dist/services/providers/local-provider-registry.d.ts.map +1 -1
- package/dist/services/providers/local-provider-service.d.ts +13 -13
- package/dist/services/providers/local-provider-service.d.ts.map +1 -1
- package/dist/services/session-data.d.ts +1 -1
- package/dist/services/session-data.d.ts.map +1 -1
- package/dist/services/storage/provider-settings-legacy-migration.d.ts +1 -1
- package/dist/services/storage/provider-settings-legacy-migration.d.ts.map +1 -1
- package/dist/services/telemetry/index.js +28 -15
- package/dist/services/workspace-manifest.d.ts +11 -0
- package/dist/services/workspace-manifest.d.ts.map +1 -1
- package/dist/session/persistence-service.d.ts +11 -23
- package/dist/session/persistence-service.d.ts.map +1 -1
- package/dist/session/session-manifest-store.d.ts +22 -0
- package/dist/session/session-manifest-store.d.ts.map +1 -0
- package/dist/session/session-row.d.ts +93 -0
- package/dist/session/session-row.d.ts.map +1 -0
- package/dist/session/session-service.d.ts +2 -102
- package/dist/session/session-service.d.ts.map +1 -1
- package/dist/session/subagent-session-manager.d.ts +36 -0
- package/dist/session/subagent-session-manager.d.ts.map +1 -0
- package/dist/session/team-persistence-store.d.ts +24 -0
- package/dist/session/team-persistence-store.d.ts.map +1 -0
- package/dist/transports/hub.d.ts +47 -0
- package/dist/transports/hub.d.ts.map +1 -0
- package/dist/transports/local.d.ts +10 -6
- package/dist/transports/local.d.ts.map +1 -1
- package/dist/transports/remote.d.ts +10 -0
- package/dist/transports/remote.d.ts.map +1 -0
- package/dist/transports/runtime-host-support.d.ts +3 -2
- package/dist/transports/runtime-host-support.d.ts.map +1 -1
- package/dist/types/chat-schema.d.ts +10 -12
- package/dist/types/chat-schema.d.ts.map +1 -1
- package/dist/types/config.d.ts +8 -7
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/provider-settings.d.ts +4 -5
- package/dist/types/provider-settings.d.ts.map +1 -1
- package/dist/types/session.d.ts +2 -1
- package/dist/types/session.d.ts.map +1 -1
- package/dist/types.d.ts +8 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +20 -6
- package/src/ClineCore.ts +68 -40
- package/src/account/index.ts +3 -3
- package/src/account/rpc.ts +12 -12
- package/src/cron/index.ts +5 -0
- package/src/cron/resource-limiter.ts +46 -0
- package/src/cron/schedule-command-service.ts +193 -0
- package/src/cron/schedule-service.ts +703 -0
- package/src/cron/scheduler.ts +637 -0
- package/src/cron/sqlite-schedule-store.ts +708 -0
- package/src/extensions/config/agent-config-loader.ts +17 -7
- package/src/extensions/config/runtime-commands.ts +6 -0
- package/src/extensions/config/user-instruction-config-loader.ts +1 -0
- package/src/extensions/context/agentic-compaction.ts +3 -3
- package/src/extensions/context/basic-compaction.ts +2 -2
- package/src/extensions/context/compaction-shared.ts +5 -4
- package/src/extensions/context/compaction.ts +3 -3
- package/src/extensions/plugin/plugin-config-loader.ts +17 -2
- package/src/extensions/plugin/plugin-loader.ts +48 -4
- package/src/extensions/plugin/plugin-module-import.ts +0 -2
- package/src/extensions/plugin/plugin-sandbox-bootstrap.ts +93 -39
- package/src/extensions/plugin/plugin-sandbox.ts +47 -27
- package/src/extensions/plugin/plugin-targeting.ts +32 -0
- package/src/extensions/tools/definitions.ts +30 -49
- package/src/extensions/tools/executors/apply-patch.ts +69 -80
- package/src/extensions/tools/executors/search.ts +195 -3
- package/src/extensions/tools/index.ts +10 -0
- package/src/extensions/tools/presets.ts +31 -46
- package/src/extensions/tools/runtime.ts +261 -0
- package/src/extensions/tools/schemas.ts +4 -2
- package/src/extensions/tools/team/team-tools.ts +21 -0
- package/src/hooks/hook-file-hooks.ts +8 -2
- package/src/hooks/index.ts +0 -7
- package/src/hooks/subprocess-runner.ts +1 -1
- package/src/hooks/subprocess.ts +9 -0
- package/src/hub/browser-websocket.ts +137 -0
- package/src/hub/client.ts +574 -0
- package/src/hub/connect.ts +156 -0
- package/src/hub/daemon-entry.ts +87 -0
- package/src/hub/daemon.ts +181 -0
- package/src/hub/defaults.ts +43 -0
- package/src/hub/discovery.ts +247 -0
- package/src/hub/index.ts +14 -0
- package/src/hub/native-transport.ts +31 -0
- package/src/hub/runtime-handlers.ts +140 -0
- package/src/hub/server.ts +1888 -0
- package/src/hub/session-client.ts +460 -0
- package/src/hub/start-shared-server.ts +58 -0
- package/src/hub/transport.ts +14 -0
- package/src/hub/ui-client.ts +122 -0
- package/src/hub/workspace.ts +19 -0
- package/src/index.ts +124 -68
- package/src/llms/configured-provider-registry.ts +193 -0
- package/src/llms/provider-defaults.ts +637 -0
- package/src/llms/provider-settings.ts +263 -0
- package/src/llms/runtime-config.ts +43 -0
- package/src/llms/runtime-registry.ts +171 -0
- package/src/llms/runtime-types.ts +121 -0
- package/src/runtime/host.ts +107 -269
- package/src/runtime/index.ts +1 -0
- package/src/runtime/rules.ts +12 -0
- package/src/runtime/runtime-builder.ts +24 -8
- package/src/runtime/runtime-host.ts +89 -61
- package/src/runtime/runtime-oauth-token-manager.ts +11 -15
- package/src/runtime/session-runtime.ts +0 -24
- package/src/services/global-settings.ts +122 -0
- package/src/services/local-runtime-bootstrap.ts +51 -13
- package/src/services/plugin-tools.ts +85 -0
- package/src/services/providers/local-provider-registry.ts +6 -6
- package/src/services/providers/local-provider-service.ts +42 -37
- package/src/services/session-data.ts +15 -9
- package/src/services/storage/provider-settings-legacy-migration.ts +6 -4
- package/src/services/storage/provider-settings-manager.ts +1 -1
- package/src/services/workspace-manifest.ts +18 -0
- package/src/session/file-session-service.ts +1 -1
- package/src/session/index.ts +6 -27
- package/src/session/persistence-service.ts +119 -504
- package/src/session/session-manifest-store.ts +158 -0
- package/src/session/session-row.ts +199 -0
- package/src/session/session-service.ts +17 -376
- package/src/session/session-team-coordination.ts +1 -1
- package/src/session/subagent-session-manager.ts +397 -0
- package/src/session/team-persistence-store.ts +176 -0
- package/src/transports/hub.ts +656 -0
- package/src/transports/local.ts +135 -40
- package/src/transports/remote.ts +26 -0
- package/src/transports/runtime-host-support.ts +63 -9
- package/src/types/chat-schema.ts +4 -5
- package/src/types/config.ts +8 -7
- package/src/types/provider-settings.ts +11 -7
- package/src/types/session.ts +2 -4
- package/src/types.ts +27 -1
- package/dist/hooks/persistent.d.ts +0 -64
- package/dist/hooks/persistent.d.ts.map +0 -1
- package/dist/runtime/rpc-runtime-ensure.d.ts +0 -65
- package/dist/runtime/rpc-runtime-ensure.d.ts.map +0 -1
- package/dist/runtime/rpc-spawn-lease.d.ts +0 -8
- package/dist/runtime/rpc-spawn-lease.d.ts.map +0 -1
- package/dist/session/rpc-session-service.d.ts +0 -16
- package/dist/session/rpc-session-service.d.ts.map +0 -1
- package/dist/session/sqlite-rpc-session-backend.d.ts +0 -31
- package/dist/session/sqlite-rpc-session-backend.d.ts.map +0 -1
- package/dist/transports/rpc.d.ts +0 -51
- package/dist/transports/rpc.d.ts.map +0 -1
- package/src/ClineCore.test.ts +0 -226
- package/src/account/cline-account-service.test.ts +0 -185
- package/src/account/featurebase-token.test.ts +0 -175
- package/src/account/rpc.test.ts +0 -63
- package/src/auth/bounded-ttl-cache.test.ts +0 -38
- package/src/auth/client.test.ts +0 -69
- package/src/auth/cline.test.ts +0 -267
- package/src/auth/codex.test.ts +0 -170
- package/src/auth/oca.test.ts +0 -340
- package/src/auth/server.test.ts +0 -287
- package/src/auth/utils.test.ts +0 -128
- package/src/extensions/config/agent-config-loader.test.ts +0 -236
- package/src/extensions/config/hooks-config-loader.test.ts +0 -20
- package/src/extensions/config/runtime-commands.test.ts +0 -115
- package/src/extensions/config/unified-config-file-watcher.test.ts +0 -196
- package/src/extensions/config/user-instruction-config-loader.test.ts +0 -246
- package/src/extensions/context/compaction.test.ts +0 -483
- package/src/extensions/mcp/config-loader.test.ts +0 -238
- package/src/extensions/mcp/manager.test.ts +0 -105
- package/src/extensions/plugin/plugin-config-loader.test.ts +0 -184
- package/src/extensions/plugin/plugin-loader.test.ts +0 -292
- package/src/extensions/plugin/plugin-sandbox.test.ts +0 -423
- package/src/extensions/tools/definitions.test.ts +0 -780
- package/src/extensions/tools/executors/bash.test.ts +0 -87
- package/src/extensions/tools/executors/editor.test.ts +0 -35
- package/src/extensions/tools/executors/file-read.test.ts +0 -125
- package/src/extensions/tools/model-tool-routing.test.ts +0 -86
- package/src/extensions/tools/presets.test.ts +0 -70
- package/src/extensions/tools/team/multi-agent.lifecycle.test.ts +0 -455
- package/src/extensions/tools/team/spawn-agent-tool.test.ts +0 -381
- package/src/extensions/tools/team/team-tools.test.ts +0 -918
- package/src/hooks/checkpoint-hooks.test.ts +0 -168
- package/src/hooks/hook-file-hooks.test.ts +0 -311
- package/src/hooks/persistent.ts +0 -661
- package/src/runtime/history.test.ts +0 -114
- package/src/runtime/host.test.ts +0 -230
- package/src/runtime/rpc-runtime-ensure.test.ts +0 -123
- package/src/runtime/rpc-runtime-ensure.ts +0 -659
- package/src/runtime/rpc-spawn-lease.test.ts +0 -81
- package/src/runtime/rpc-spawn-lease.ts +0 -156
- package/src/runtime/runtime-builder.team-persistence.test.ts +0 -245
- package/src/runtime/runtime-builder.test.ts +0 -615
- package/src/runtime/runtime-oauth-token-manager.test.ts +0 -137
- package/src/runtime/runtime-parity.test.ts +0 -143
- package/src/services/providers/local-provider-service.test.ts +0 -1062
- package/src/services/session-data.test.ts +0 -160
- package/src/services/storage/provider-settings-legacy-migration.test.ts +0 -424
- package/src/services/storage/provider-settings-manager.test.ts +0 -191
- package/src/services/telemetry/OpenTelemetryAdapter.test.ts +0 -157
- package/src/services/telemetry/OpenTelemetryProvider.test.ts +0 -326
- package/src/services/telemetry/TelemetryLoggerSink.test.ts +0 -42
- package/src/services/telemetry/TelemetryService.test.ts +0 -134
- package/src/services/telemetry/distinct-id.test.ts +0 -57
- package/src/services/workspace/file-indexer.d.ts +0 -11
- package/src/services/workspace/file-indexer.test.ts +0 -156
- package/src/services/workspace/mention-enricher.test.ts +0 -106
- package/src/session/persistence-service.test.ts +0 -300
- package/src/session/rpc-session-service.ts +0 -114
- package/src/session/session-service.team-persistence.test.ts +0 -48
- package/src/session/sqlite-rpc-session-backend.ts +0 -301
- package/src/transports/local.e2e.test.ts +0 -380
- package/src/transports/local.test.ts +0 -2559
- package/src/transports/rpc.test.ts +0 -82
- package/src/transports/rpc.ts +0 -665
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it, vi } from "vitest";
|
|
2
|
-
import { InMemoryMcpManager } from "./manager";
|
|
3
|
-
import type { McpServerClient, McpToolDescriptor } from "./types";
|
|
4
|
-
|
|
5
|
-
function createClient(overrides?: Partial<McpServerClient>): McpServerClient {
|
|
6
|
-
return {
|
|
7
|
-
connect: vi.fn(async () => {}),
|
|
8
|
-
disconnect: vi.fn(async () => {}),
|
|
9
|
-
listTools: vi.fn(async () => []),
|
|
10
|
-
callTool: vi.fn(async () => ({ ok: true })),
|
|
11
|
-
...overrides,
|
|
12
|
-
};
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
describe("InMemoryMcpManager", () => {
|
|
16
|
-
it("registers servers, connects on demand, and calls tools", async () => {
|
|
17
|
-
const toolDescriptors: readonly McpToolDescriptor[] = [
|
|
18
|
-
{
|
|
19
|
-
name: "search",
|
|
20
|
-
inputSchema: {
|
|
21
|
-
type: "object",
|
|
22
|
-
properties: { q: { type: "string" } },
|
|
23
|
-
required: ["q"],
|
|
24
|
-
},
|
|
25
|
-
},
|
|
26
|
-
];
|
|
27
|
-
const client = createClient({
|
|
28
|
-
listTools: vi.fn(async () => toolDescriptors),
|
|
29
|
-
});
|
|
30
|
-
const manager = new InMemoryMcpManager({
|
|
31
|
-
clientFactory: vi.fn(async () => client),
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
await manager.registerServer({
|
|
35
|
-
name: "docs",
|
|
36
|
-
transport: {
|
|
37
|
-
type: "streamableHttp",
|
|
38
|
-
url: "https://mcp.example.test",
|
|
39
|
-
},
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
const tools = await manager.listTools("docs");
|
|
43
|
-
expect(tools).toHaveLength(1);
|
|
44
|
-
|
|
45
|
-
await manager.callTool({
|
|
46
|
-
serverName: "docs",
|
|
47
|
-
toolName: "search",
|
|
48
|
-
arguments: { q: "oauth flow" },
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
expect(client.connect).toHaveBeenCalledTimes(1);
|
|
52
|
-
expect(client.callTool).toHaveBeenCalledWith({
|
|
53
|
-
name: "search",
|
|
54
|
-
arguments: { q: "oauth flow" },
|
|
55
|
-
context: undefined,
|
|
56
|
-
});
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
it("uses tool list cache to avoid repeated listTools round trips", async () => {
|
|
60
|
-
const toolDescriptors: readonly McpToolDescriptor[] = [
|
|
61
|
-
{
|
|
62
|
-
name: "echo",
|
|
63
|
-
inputSchema: { type: "object", properties: {} },
|
|
64
|
-
},
|
|
65
|
-
];
|
|
66
|
-
const client = createClient({
|
|
67
|
-
listTools: vi.fn(async () => toolDescriptors),
|
|
68
|
-
});
|
|
69
|
-
const manager = new InMemoryMcpManager({
|
|
70
|
-
clientFactory: async () => client,
|
|
71
|
-
toolsCacheTtlMs: 60_000,
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
await manager.registerServer({
|
|
75
|
-
name: "cache-test",
|
|
76
|
-
transport: {
|
|
77
|
-
type: "stdio",
|
|
78
|
-
command: "node",
|
|
79
|
-
args: ["./mcp.js"],
|
|
80
|
-
},
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
await manager.listTools("cache-test");
|
|
84
|
-
await manager.listTools("cache-test");
|
|
85
|
-
expect(client.listTools).toHaveBeenCalledTimes(1);
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
it("prevents tool calls on disabled servers", async () => {
|
|
89
|
-
const manager = new InMemoryMcpManager({
|
|
90
|
-
clientFactory: async () => createClient(),
|
|
91
|
-
});
|
|
92
|
-
await manager.registerServer({
|
|
93
|
-
name: "disabled",
|
|
94
|
-
transport: { type: "sse", url: "https://example.test/sse" },
|
|
95
|
-
disabled: true,
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
await expect(
|
|
99
|
-
manager.callTool({
|
|
100
|
-
serverName: "disabled",
|
|
101
|
-
toolName: "anything",
|
|
102
|
-
}),
|
|
103
|
-
).rejects.toThrow(/disabled/i);
|
|
104
|
-
});
|
|
105
|
-
});
|
|
@@ -1,184 +0,0 @@
|
|
|
1
|
-
import { mkdir, mkdtemp, rm, writeFile } from "node:fs/promises";
|
|
2
|
-
import { tmpdir } from "node:os";
|
|
3
|
-
import { join } from "node:path";
|
|
4
|
-
import { setHomeDir } from "@clinebot/shared/storage";
|
|
5
|
-
import { afterEach, describe, expect, it } from "vitest";
|
|
6
|
-
import {
|
|
7
|
-
discoverPluginModulePaths,
|
|
8
|
-
resolveAgentPluginPaths,
|
|
9
|
-
resolveAndLoadAgentPlugins,
|
|
10
|
-
resolvePluginConfigSearchPaths,
|
|
11
|
-
} from "./plugin-config-loader";
|
|
12
|
-
|
|
13
|
-
describe("plugin-config-loader", () => {
|
|
14
|
-
const envSnapshot = {
|
|
15
|
-
HOME: process.env.HOME,
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
afterEach(() => {
|
|
19
|
-
process.env.HOME = envSnapshot.HOME;
|
|
20
|
-
setHomeDir(envSnapshot.HOME ?? "~");
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
it("discovers plugin modules recursively", async () => {
|
|
24
|
-
const root = await mkdtemp(join(tmpdir(), "core-plugin-config-loader-"));
|
|
25
|
-
try {
|
|
26
|
-
const nested = join(root, "nested");
|
|
27
|
-
await mkdir(nested, { recursive: true });
|
|
28
|
-
await writeFile(join(root, "a.js"), "export default {}", "utf8");
|
|
29
|
-
await writeFile(join(nested, "b.ts"), "export default {}", "utf8");
|
|
30
|
-
await writeFile(
|
|
31
|
-
join(root, ".a.js.cline-plugin.js"),
|
|
32
|
-
"export default {}",
|
|
33
|
-
"utf8",
|
|
34
|
-
);
|
|
35
|
-
await writeFile(join(root, "ignore.txt"), "noop", "utf8");
|
|
36
|
-
|
|
37
|
-
const discovered = discoverPluginModulePaths(root);
|
|
38
|
-
expect(discovered).toEqual([join(root, "a.js"), join(nested, "b.ts")]);
|
|
39
|
-
} finally {
|
|
40
|
-
await rm(root, { recursive: true, force: true });
|
|
41
|
-
}
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
it("resolves plugin paths from explicit files/directories", async () => {
|
|
45
|
-
const root = await mkdtemp(join(tmpdir(), "core-plugin-config-loader-"));
|
|
46
|
-
try {
|
|
47
|
-
process.env.HOME = root;
|
|
48
|
-
setHomeDir(root);
|
|
49
|
-
const pluginsDir = join(root, "plugins");
|
|
50
|
-
await mkdir(pluginsDir, { recursive: true });
|
|
51
|
-
const filePath = join(root, "direct.js");
|
|
52
|
-
const dirPluginPath = join(pluginsDir, "dir-plugin.js");
|
|
53
|
-
await writeFile(filePath, "export default {}", "utf8");
|
|
54
|
-
await writeFile(dirPluginPath, "export default {}", "utf8");
|
|
55
|
-
|
|
56
|
-
const resolved = resolveAgentPluginPaths({
|
|
57
|
-
pluginPaths: ["./direct.js", "./plugins"],
|
|
58
|
-
workspacePath: join(root, "workspace"),
|
|
59
|
-
cwd: root,
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
expect(resolved).toEqual([filePath, dirPluginPath]);
|
|
63
|
-
} finally {
|
|
64
|
-
await rm(root, { recursive: true, force: true });
|
|
65
|
-
}
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
it("prefers package manifest plugin entries for configured directories", async () => {
|
|
69
|
-
const root = await mkdtemp(join(tmpdir(), "core-plugin-config-loader-"));
|
|
70
|
-
try {
|
|
71
|
-
const pluginDir = join(root, "plugin-package");
|
|
72
|
-
const srcDir = join(pluginDir, "src");
|
|
73
|
-
await mkdir(srcDir, { recursive: true });
|
|
74
|
-
const declaredEntry = join(srcDir, "index.ts");
|
|
75
|
-
const ignoredEntry = join(pluginDir, "ignored.js");
|
|
76
|
-
await writeFile(
|
|
77
|
-
join(pluginDir, "package.json"),
|
|
78
|
-
JSON.stringify({
|
|
79
|
-
name: "plugin-package",
|
|
80
|
-
private: true,
|
|
81
|
-
cline: {
|
|
82
|
-
plugins: [
|
|
83
|
-
{
|
|
84
|
-
paths: ["./src/index.ts"],
|
|
85
|
-
capabilities: ["tools"],
|
|
86
|
-
},
|
|
87
|
-
],
|
|
88
|
-
},
|
|
89
|
-
}),
|
|
90
|
-
"utf8",
|
|
91
|
-
);
|
|
92
|
-
await writeFile(declaredEntry, "export default {}", "utf8");
|
|
93
|
-
await writeFile(ignoredEntry, "export default {}", "utf8");
|
|
94
|
-
|
|
95
|
-
const resolved = resolveAgentPluginPaths({
|
|
96
|
-
pluginPaths: ["./plugin-package"],
|
|
97
|
-
cwd: root,
|
|
98
|
-
workspacePath: join(root, "workspace"),
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
expect(resolved).toContain(declaredEntry);
|
|
102
|
-
expect(resolved).not.toContain(ignoredEntry);
|
|
103
|
-
} finally {
|
|
104
|
-
await rm(root, { recursive: true, force: true });
|
|
105
|
-
}
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
it("includes shared search-path plugins", async () => {
|
|
109
|
-
const home = await mkdtemp(
|
|
110
|
-
join(tmpdir(), "core-plugin-config-loader-home-"),
|
|
111
|
-
);
|
|
112
|
-
const workspace = await mkdtemp(
|
|
113
|
-
join(tmpdir(), "core-plugin-config-loader-workspace-"),
|
|
114
|
-
);
|
|
115
|
-
try {
|
|
116
|
-
process.env.HOME = home;
|
|
117
|
-
setHomeDir(home);
|
|
118
|
-
const workspacePlugins = join(workspace, ".cline", "plugins");
|
|
119
|
-
const userPlugins = join(home, ".cline", "plugins");
|
|
120
|
-
const documentsPlugins = join(home, "Documents", "Cline", "Plugins");
|
|
121
|
-
await mkdir(workspacePlugins, { recursive: true });
|
|
122
|
-
await mkdir(userPlugins, { recursive: true });
|
|
123
|
-
await mkdir(documentsPlugins, { recursive: true });
|
|
124
|
-
const workspacePlugin = join(workspacePlugins, "workspace.js");
|
|
125
|
-
const userPlugin = join(userPlugins, "user.js");
|
|
126
|
-
const documentsPlugin = join(documentsPlugins, "documents.js");
|
|
127
|
-
await writeFile(workspacePlugin, "export default {}", "utf8");
|
|
128
|
-
await writeFile(userPlugin, "export default {}", "utf8");
|
|
129
|
-
await writeFile(documentsPlugin, "export default {}", "utf8");
|
|
130
|
-
|
|
131
|
-
const searchPaths = resolvePluginConfigSearchPaths(workspace);
|
|
132
|
-
expect(searchPaths).toHaveLength(3);
|
|
133
|
-
expect(searchPaths).toContain(workspacePlugins);
|
|
134
|
-
expect(searchPaths).toContain(userPlugins);
|
|
135
|
-
expect(searchPaths).toContain(documentsPlugins);
|
|
136
|
-
|
|
137
|
-
const resolved = resolveAgentPluginPaths({ workspacePath: workspace });
|
|
138
|
-
expect(resolved).toContain(workspacePlugin);
|
|
139
|
-
expect(resolved).toContain(userPlugin);
|
|
140
|
-
expect(resolved).toContain(documentsPlugin);
|
|
141
|
-
} finally {
|
|
142
|
-
await rm(home, { recursive: true, force: true });
|
|
143
|
-
await rm(workspace, { recursive: true, force: true });
|
|
144
|
-
}
|
|
145
|
-
});
|
|
146
|
-
|
|
147
|
-
it("loads valid plugins while reporting failures and duplicate overrides", async () => {
|
|
148
|
-
const root = await mkdtemp(join(tmpdir(), "core-plugin-config-loader-"));
|
|
149
|
-
try {
|
|
150
|
-
const first = join(root, "duplicate-one.js");
|
|
151
|
-
const second = join(root, "duplicate-two.js");
|
|
152
|
-
const invalid = join(root, "invalid.js");
|
|
153
|
-
await writeFile(
|
|
154
|
-
first,
|
|
155
|
-
"export default { name: 'duplicate-plugin', manifest: { capabilities: ['tools'] } };",
|
|
156
|
-
"utf8",
|
|
157
|
-
);
|
|
158
|
-
await writeFile(
|
|
159
|
-
second,
|
|
160
|
-
"export default { name: 'duplicate-plugin', manifest: { capabilities: ['commands'] } };",
|
|
161
|
-
"utf8",
|
|
162
|
-
);
|
|
163
|
-
await writeFile(invalid, "export default { name: 'broken' };", "utf8");
|
|
164
|
-
|
|
165
|
-
const loaded = await resolveAndLoadAgentPlugins({
|
|
166
|
-
mode: "in_process",
|
|
167
|
-
pluginPaths: [first, invalid, second],
|
|
168
|
-
cwd: root,
|
|
169
|
-
});
|
|
170
|
-
|
|
171
|
-
// Filter to only our test plugins to ignore any discovered system plugins
|
|
172
|
-
const testPlugins = loaded.extensions.filter(
|
|
173
|
-
(plugin) => plugin.name === "duplicate-plugin",
|
|
174
|
-
);
|
|
175
|
-
expect(testPlugins).toHaveLength(1);
|
|
176
|
-
expect(testPlugins[0]?.manifest.capabilities).toEqual(["commands"]);
|
|
177
|
-
expect(loaded.failures).toHaveLength(1);
|
|
178
|
-
expect(loaded.warnings).toHaveLength(1);
|
|
179
|
-
expect(loaded.warnings[0]?.overriddenPluginPath).toBe(first);
|
|
180
|
-
} finally {
|
|
181
|
-
await rm(root, { recursive: true, force: true });
|
|
182
|
-
}
|
|
183
|
-
});
|
|
184
|
-
});
|
|
@@ -1,292 +0,0 @@
|
|
|
1
|
-
import { mkdir, mkdtemp, rm, writeFile } from "node:fs/promises";
|
|
2
|
-
import { tmpdir } from "node:os";
|
|
3
|
-
import { join } from "node:path";
|
|
4
|
-
import { afterAll, beforeAll, describe, expect, it } from "vitest";
|
|
5
|
-
import {
|
|
6
|
-
loadAgentPluginFromPath,
|
|
7
|
-
loadAgentPluginsFromPaths,
|
|
8
|
-
loadAgentPluginsFromPathsWithDiagnostics,
|
|
9
|
-
} from "./plugin-loader";
|
|
10
|
-
|
|
11
|
-
describe("plugin-loader", () => {
|
|
12
|
-
let dir = "";
|
|
13
|
-
let copyDir = "";
|
|
14
|
-
|
|
15
|
-
beforeAll(async () => {
|
|
16
|
-
dir = await mkdtemp(join(tmpdir(), "core-plugin-loader-"));
|
|
17
|
-
copyDir = await mkdtemp(join(tmpdir(), "core-plugin-loader-copy-"));
|
|
18
|
-
|
|
19
|
-
await writeFile(
|
|
20
|
-
join(dir, "plugin-default.mjs"),
|
|
21
|
-
[
|
|
22
|
-
"export default {",
|
|
23
|
-
" name: 'from-default',",
|
|
24
|
-
" manifest: { capabilities: ['hooks'], hookStages: ['input'] },",
|
|
25
|
-
" onInput: ({ input }) => ({ overrideInput: input })",
|
|
26
|
-
"};",
|
|
27
|
-
].join("\n"),
|
|
28
|
-
"utf8",
|
|
29
|
-
);
|
|
30
|
-
await writeFile(
|
|
31
|
-
join(dir, "plugin-named.mjs"),
|
|
32
|
-
[
|
|
33
|
-
"export const plugin = {",
|
|
34
|
-
" name: 'from-named',",
|
|
35
|
-
" manifest: { capabilities: ['tools'] },",
|
|
36
|
-
"};",
|
|
37
|
-
].join("\n"),
|
|
38
|
-
"utf8",
|
|
39
|
-
);
|
|
40
|
-
await writeFile(
|
|
41
|
-
join(dir, "plugin-a.mjs"),
|
|
42
|
-
"export default { name: 'plugin-a', manifest: { capabilities: ['tools'] } };",
|
|
43
|
-
"utf8",
|
|
44
|
-
);
|
|
45
|
-
await writeFile(
|
|
46
|
-
join(dir, "plugin-b.mjs"),
|
|
47
|
-
"export default { name: 'plugin-b', manifest: { capabilities: ['commands'] } };",
|
|
48
|
-
"utf8",
|
|
49
|
-
);
|
|
50
|
-
await writeFile(
|
|
51
|
-
join(dir, "plugin-ts.ts"),
|
|
52
|
-
[
|
|
53
|
-
"const name: string = 'plugin-ts';",
|
|
54
|
-
"export default {",
|
|
55
|
-
" name,",
|
|
56
|
-
" manifest: { capabilities: ['tools'] },",
|
|
57
|
-
"};",
|
|
58
|
-
].join("\n"),
|
|
59
|
-
"utf8",
|
|
60
|
-
);
|
|
61
|
-
|
|
62
|
-
const depDir = join(dir, "node_modules", "plugin-local-dep");
|
|
63
|
-
await mkdir(depDir, { recursive: true });
|
|
64
|
-
await writeFile(
|
|
65
|
-
join(depDir, "package.json"),
|
|
66
|
-
JSON.stringify({
|
|
67
|
-
name: "plugin-local-dep",
|
|
68
|
-
type: "module",
|
|
69
|
-
exports: "./index.js",
|
|
70
|
-
}),
|
|
71
|
-
"utf8",
|
|
72
|
-
);
|
|
73
|
-
await writeFile(
|
|
74
|
-
join(depDir, "index.js"),
|
|
75
|
-
"export const depName = 'plugin-local-dep';\n",
|
|
76
|
-
"utf8",
|
|
77
|
-
);
|
|
78
|
-
await writeFile(
|
|
79
|
-
join(dir, "plugin-with-dep.ts"),
|
|
80
|
-
[
|
|
81
|
-
"import { depName } from 'plugin-local-dep';",
|
|
82
|
-
"export default {",
|
|
83
|
-
" name: depName,",
|
|
84
|
-
" manifest: { capabilities: ['tools'] },",
|
|
85
|
-
"};",
|
|
86
|
-
].join("\n"),
|
|
87
|
-
"utf8",
|
|
88
|
-
);
|
|
89
|
-
|
|
90
|
-
const sdkDir = join(dir, "node_modules", "@clinebot", "shared");
|
|
91
|
-
await mkdir(sdkDir, { recursive: true });
|
|
92
|
-
await writeFile(
|
|
93
|
-
join(sdkDir, "package.json"),
|
|
94
|
-
JSON.stringify({
|
|
95
|
-
name: "@clinebot/shared",
|
|
96
|
-
type: "module",
|
|
97
|
-
exports: "./index.js",
|
|
98
|
-
}),
|
|
99
|
-
"utf8",
|
|
100
|
-
);
|
|
101
|
-
await writeFile(
|
|
102
|
-
join(sdkDir, "index.js"),
|
|
103
|
-
"export const sdkMarker = 'plugin-installed-sdk';\n",
|
|
104
|
-
"utf8",
|
|
105
|
-
);
|
|
106
|
-
await writeFile(
|
|
107
|
-
join(dir, "plugin-with-sdk-dep.ts"),
|
|
108
|
-
[
|
|
109
|
-
"import { sdkMarker } from '@clinebot/shared';",
|
|
110
|
-
"export default {",
|
|
111
|
-
" name: sdkMarker,",
|
|
112
|
-
" manifest: { capabilities: ['tools'] },",
|
|
113
|
-
"};",
|
|
114
|
-
].join("\n"),
|
|
115
|
-
"utf8",
|
|
116
|
-
);
|
|
117
|
-
|
|
118
|
-
await writeFile(
|
|
119
|
-
join(copyDir, "portable-subagents.ts"),
|
|
120
|
-
[
|
|
121
|
-
"import { safeJsonStringify } from '@clinebot/shared';",
|
|
122
|
-
"import { resolveClineDataDir } from '@clinebot/shared/storage';",
|
|
123
|
-
"import YAML from 'yaml';",
|
|
124
|
-
"export default {",
|
|
125
|
-
" name: typeof safeJsonStringify === 'function' ? YAML.stringify({ ok: !!resolveClineDataDir() }) : 'invalid',",
|
|
126
|
-
" manifest: { capabilities: ['tools'] },",
|
|
127
|
-
"};",
|
|
128
|
-
].join("\n"),
|
|
129
|
-
"utf8",
|
|
130
|
-
);
|
|
131
|
-
|
|
132
|
-
const packagedCopyDir = join(copyDir, "packaged-plugin");
|
|
133
|
-
await mkdir(packagedCopyDir, { recursive: true });
|
|
134
|
-
await writeFile(
|
|
135
|
-
join(packagedCopyDir, "package.json"),
|
|
136
|
-
JSON.stringify({
|
|
137
|
-
name: "packaged-plugin",
|
|
138
|
-
type: "module",
|
|
139
|
-
cline: {
|
|
140
|
-
plugins: ["index.ts"],
|
|
141
|
-
},
|
|
142
|
-
}),
|
|
143
|
-
"utf8",
|
|
144
|
-
);
|
|
145
|
-
await writeFile(
|
|
146
|
-
join(packagedCopyDir, "index.ts"),
|
|
147
|
-
[
|
|
148
|
-
"import YAML from 'yaml';",
|
|
149
|
-
"export default {",
|
|
150
|
-
" name: YAML.stringify({ ok: true }),",
|
|
151
|
-
" manifest: { capabilities: ['tools'] },",
|
|
152
|
-
"};",
|
|
153
|
-
].join("\n"),
|
|
154
|
-
"utf8",
|
|
155
|
-
);
|
|
156
|
-
|
|
157
|
-
await writeFile(
|
|
158
|
-
join(dir, "invalid-plugin.mjs"),
|
|
159
|
-
"export default { name: 'invalid-plugin' };",
|
|
160
|
-
"utf8",
|
|
161
|
-
);
|
|
162
|
-
|
|
163
|
-
await writeFile(
|
|
164
|
-
join(dir, "duplicate-one.mjs"),
|
|
165
|
-
"export default { name: 'duplicate-plugin', manifest: { capabilities: ['tools'] } };",
|
|
166
|
-
"utf8",
|
|
167
|
-
);
|
|
168
|
-
await writeFile(
|
|
169
|
-
join(dir, "duplicate-two.mjs"),
|
|
170
|
-
"export default { name: 'duplicate-plugin', manifest: { capabilities: ['commands'] } };",
|
|
171
|
-
"utf8",
|
|
172
|
-
);
|
|
173
|
-
});
|
|
174
|
-
|
|
175
|
-
afterAll(async () => {
|
|
176
|
-
if (dir) {
|
|
177
|
-
await rm(dir, { recursive: true, force: true });
|
|
178
|
-
}
|
|
179
|
-
if (copyDir) {
|
|
180
|
-
await rm(copyDir, { recursive: true, force: true });
|
|
181
|
-
}
|
|
182
|
-
});
|
|
183
|
-
|
|
184
|
-
it("loads default-exported plugin from path", async () => {
|
|
185
|
-
const plugin = await loadAgentPluginFromPath(
|
|
186
|
-
join(dir, "plugin-default.mjs"),
|
|
187
|
-
);
|
|
188
|
-
expect(plugin.name).toBe("from-default");
|
|
189
|
-
expect(plugin.manifest.capabilities).toContain("hooks");
|
|
190
|
-
});
|
|
191
|
-
|
|
192
|
-
it("loads named plugin export from path", async () => {
|
|
193
|
-
const plugin = await loadAgentPluginFromPath(
|
|
194
|
-
join(dir, "plugin-named.mjs"),
|
|
195
|
-
{
|
|
196
|
-
exportName: "plugin",
|
|
197
|
-
},
|
|
198
|
-
);
|
|
199
|
-
expect(plugin.name).toBe("from-named");
|
|
200
|
-
});
|
|
201
|
-
|
|
202
|
-
it("loads multiple plugins from file paths", async () => {
|
|
203
|
-
const plugins = await loadAgentPluginsFromPaths([
|
|
204
|
-
join(dir, "plugin-a.mjs"),
|
|
205
|
-
join(dir, "plugin-b.mjs"),
|
|
206
|
-
]);
|
|
207
|
-
expect(plugins.map((plugin) => plugin.name)).toEqual([
|
|
208
|
-
"plugin-a",
|
|
209
|
-
"plugin-b",
|
|
210
|
-
]);
|
|
211
|
-
});
|
|
212
|
-
|
|
213
|
-
it("loads TypeScript plugins from file paths", async () => {
|
|
214
|
-
const plugin = await loadAgentPluginFromPath(join(dir, "plugin-ts.ts"));
|
|
215
|
-
expect(plugin.name).toBe("plugin-ts");
|
|
216
|
-
});
|
|
217
|
-
|
|
218
|
-
it("resolves plugin-local dependencies from the plugin path", async () => {
|
|
219
|
-
const plugin = await loadAgentPluginFromPath(
|
|
220
|
-
join(dir, "plugin-with-dep.ts"),
|
|
221
|
-
{ cwd: dir },
|
|
222
|
-
);
|
|
223
|
-
expect(plugin.name).toBe("plugin-local-dep");
|
|
224
|
-
});
|
|
225
|
-
|
|
226
|
-
it("prefers plugin-installed SDK packages over workspace aliases", async () => {
|
|
227
|
-
const plugin = await loadAgentPluginFromPath(
|
|
228
|
-
join(dir, "plugin-with-sdk-dep.ts"),
|
|
229
|
-
{ cwd: dir },
|
|
230
|
-
);
|
|
231
|
-
expect(plugin.name).toBe("plugin-installed-sdk");
|
|
232
|
-
});
|
|
233
|
-
|
|
234
|
-
it("allows standalone file plugins to use host runtime dependencies", async () => {
|
|
235
|
-
const plugin = await loadAgentPluginFromPath(
|
|
236
|
-
join(copyDir, "portable-subagents.ts"),
|
|
237
|
-
{
|
|
238
|
-
cwd: copyDir,
|
|
239
|
-
useCache: true,
|
|
240
|
-
},
|
|
241
|
-
);
|
|
242
|
-
expect(plugin.name).toMatch(/ok: true/i);
|
|
243
|
-
});
|
|
244
|
-
|
|
245
|
-
it("requires package-based plugins to provide their own non-SDK dependencies", async () => {
|
|
246
|
-
await expect(
|
|
247
|
-
loadAgentPluginFromPath(join(copyDir, "packaged-plugin", "index.ts"), {
|
|
248
|
-
cwd: join(copyDir, "packaged-plugin"),
|
|
249
|
-
useCache: true,
|
|
250
|
-
}),
|
|
251
|
-
).rejects.toThrow(/Cannot find (package|module) 'yaml'/i);
|
|
252
|
-
});
|
|
253
|
-
|
|
254
|
-
it("rejects invalid plugin export missing manifest", async () => {
|
|
255
|
-
await expect(
|
|
256
|
-
loadAgentPluginFromPath(join(dir, "invalid-plugin.mjs")),
|
|
257
|
-
).rejects.toThrow(/missing required "manifest"/i);
|
|
258
|
-
});
|
|
259
|
-
|
|
260
|
-
it("continues loading valid plugins when one plugin fails", async () => {
|
|
261
|
-
const report = await loadAgentPluginsFromPathsWithDiagnostics([
|
|
262
|
-
join(dir, "plugin-a.mjs"),
|
|
263
|
-
join(dir, "invalid-plugin.mjs"),
|
|
264
|
-
join(dir, "plugin-b.mjs"),
|
|
265
|
-
]);
|
|
266
|
-
|
|
267
|
-
expect(report.plugins.map((plugin) => plugin.name)).toEqual([
|
|
268
|
-
"plugin-a",
|
|
269
|
-
"plugin-b",
|
|
270
|
-
]);
|
|
271
|
-
expect(report.failures).toHaveLength(1);
|
|
272
|
-
expect(report.failures[0]?.pluginPath).toBe(
|
|
273
|
-
join(dir, "invalid-plugin.mjs"),
|
|
274
|
-
);
|
|
275
|
-
expect(report.warnings).toEqual([]);
|
|
276
|
-
});
|
|
277
|
-
|
|
278
|
-
it("keeps the later duplicate plugin and reports the override", async () => {
|
|
279
|
-
const report = await loadAgentPluginsFromPathsWithDiagnostics([
|
|
280
|
-
join(dir, "duplicate-one.mjs"),
|
|
281
|
-
join(dir, "duplicate-two.mjs"),
|
|
282
|
-
]);
|
|
283
|
-
|
|
284
|
-
expect(report.plugins).toHaveLength(1);
|
|
285
|
-
expect(report.plugins[0]?.name).toBe("duplicate-plugin");
|
|
286
|
-
expect(report.plugins[0]?.manifest.capabilities).toEqual(["commands"]);
|
|
287
|
-
expect(report.warnings).toHaveLength(1);
|
|
288
|
-
expect(report.warnings[0]?.overriddenPluginPath).toBe(
|
|
289
|
-
join(dir, "duplicate-one.mjs"),
|
|
290
|
-
);
|
|
291
|
-
});
|
|
292
|
-
});
|