@clinebot/core 0.0.36 → 0.0.37
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/dist/ClineCore.d.ts +312 -3
- package/dist/ClineCore.d.ts.map +1 -1
- package/dist/account/cline-account-service.d.ts.map +1 -1
- package/dist/cron/cron-event-ingress.d.ts +38 -0
- package/dist/cron/cron-event-ingress.d.ts.map +1 -0
- package/dist/cron/cron-materializer.d.ts +36 -0
- package/dist/cron/cron-materializer.d.ts.map +1 -0
- package/dist/cron/cron-reconciler.d.ts +62 -0
- package/dist/cron/cron-reconciler.d.ts.map +1 -0
- package/dist/cron/cron-report-writer.d.ts +41 -0
- package/dist/cron/cron-report-writer.d.ts.map +1 -0
- package/dist/cron/cron-runner.d.ts +43 -0
- package/dist/cron/cron-runner.d.ts.map +1 -0
- package/dist/cron/cron-schema.d.ts +3 -0
- package/dist/cron/cron-schema.d.ts.map +1 -0
- package/dist/cron/cron-service.d.ts +57 -0
- package/dist/cron/cron-service.d.ts.map +1 -0
- package/dist/cron/cron-spec-parser.d.ts +27 -0
- package/dist/cron/cron-spec-parser.d.ts.map +1 -0
- package/dist/cron/cron-watcher.d.ts +23 -0
- package/dist/cron/cron-watcher.d.ts.map +1 -0
- package/dist/cron/scheduler.d.ts +3 -1
- package/dist/cron/scheduler.d.ts.map +1 -1
- package/dist/cron/sqlite-cron-store.d.ts +230 -0
- package/dist/cron/sqlite-cron-store.d.ts.map +1 -0
- package/dist/extensions/plugin/plugin-config-loader.d.ts +7 -1
- package/dist/extensions/plugin/plugin-config-loader.d.ts.map +1 -1
- package/dist/extensions/plugin/plugin-loader.d.ts +10 -6
- package/dist/extensions/plugin/plugin-loader.d.ts.map +1 -1
- package/dist/extensions/plugin/plugin-sandbox.d.ts +7 -1
- package/dist/extensions/plugin/plugin-sandbox.d.ts.map +1 -1
- package/dist/extensions/plugin-sandbox-bootstrap.js +236 -275
- package/dist/extensions/tools/constants.d.ts +1 -0
- package/dist/extensions/tools/constants.d.ts.map +1 -1
- package/dist/extensions/tools/definitions.d.ts +2 -3
- package/dist/extensions/tools/definitions.d.ts.map +1 -1
- package/dist/extensions/tools/executors/editor.d.ts.map +1 -1
- package/dist/extensions/tools/helpers.d.ts +1 -0
- package/dist/extensions/tools/helpers.d.ts.map +1 -1
- package/dist/extensions/tools/index.d.ts +1 -2
- package/dist/extensions/tools/index.d.ts.map +1 -1
- package/dist/extensions/tools/presets.d.ts +1 -1
- package/dist/extensions/tools/schemas.d.ts +25 -3
- package/dist/extensions/tools/schemas.d.ts.map +1 -1
- package/dist/extensions/tools/team/delegated-agent.d.ts +2 -2
- package/dist/extensions/tools/team/delegated-agent.d.ts.map +1 -1
- package/dist/extensions/tools/team/multi-agent.d.ts +7 -3
- package/dist/extensions/tools/team/multi-agent.d.ts.map +1 -1
- package/dist/extensions/tools/team/team-tools.d.ts.map +1 -1
- package/dist/extensions/tools/types.d.ts +0 -5
- package/dist/extensions/tools/types.d.ts.map +1 -1
- package/dist/hooks/hook-bridge.d.ts +118 -0
- package/dist/hooks/hook-bridge.d.ts.map +1 -0
- package/dist/hooks/hook-file-hooks.d.ts +2 -1
- package/dist/hooks/hook-file-hooks.d.ts.map +1 -1
- package/dist/hooks/hook-registry.d.ts +16 -0
- package/dist/hooks/hook-registry.d.ts.map +1 -0
- package/dist/hub/browser-websocket.d.ts.map +1 -1
- package/dist/hub/client.d.ts +7 -1
- package/dist/hub/client.d.ts.map +1 -1
- package/dist/hub/daemon-entry.js +721 -461
- package/dist/hub/daemon.d.ts.map +1 -1
- package/dist/hub/defaults.d.ts +8 -4
- package/dist/hub/defaults.d.ts.map +1 -1
- package/dist/hub/index.js +665 -415
- package/dist/hub/runtime-handlers.d.ts.map +1 -1
- package/dist/hub/server.d.ts +18 -0
- package/dist/hub/server.d.ts.map +1 -1
- package/dist/hub/session-client.d.ts +3 -0
- package/dist/hub/session-client.d.ts.map +1 -1
- package/dist/hub/start-shared-server.d.ts.map +1 -1
- package/dist/hub/ui-client.d.ts +1 -0
- package/dist/hub/ui-client.d.ts.map +1 -1
- package/dist/index.d.ts +9 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +756 -467
- package/dist/llms/cline-recommended-models.d.ts +20 -0
- package/dist/llms/cline-recommended-models.d.ts.map +1 -0
- package/dist/llms/handler-factory.d.ts +16 -0
- package/dist/llms/handler-factory.d.ts.map +1 -0
- package/dist/llms/provider-defaults.d.ts.map +1 -1
- package/dist/llms/provider-settings.d.ts +45 -2
- package/dist/llms/provider-settings.d.ts.map +1 -1
- package/dist/llms/runtime-registry.d.ts.map +1 -1
- package/dist/runtime/agent-config-adapter.d.ts +148 -0
- package/dist/runtime/agent-config-adapter.d.ts.map +1 -0
- package/dist/runtime/agent-runtime-config-builder.d.ts +96 -0
- package/dist/runtime/agent-runtime-config-builder.d.ts.map +1 -0
- package/dist/runtime/history.d.ts +6 -0
- package/dist/runtime/history.d.ts.map +1 -1
- package/dist/runtime/host.d.ts.map +1 -1
- package/dist/runtime/loop-detection.d.ts +59 -0
- package/dist/runtime/loop-detection.d.ts.map +1 -0
- package/dist/runtime/mistake-tracker.d.ts +69 -0
- package/dist/runtime/mistake-tracker.d.ts.map +1 -0
- package/dist/runtime/runtime-builder.d.ts.map +1 -1
- package/dist/runtime/runtime-event-adapter.d.ts +102 -0
- package/dist/runtime/runtime-event-adapter.d.ts.map +1 -0
- package/dist/runtime/runtime-host.d.ts +28 -3
- package/dist/runtime/runtime-host.d.ts.map +1 -1
- package/dist/runtime/session-runtime-orchestrator.d.ts +261 -0
- package/dist/runtime/session-runtime-orchestrator.d.ts.map +1 -0
- package/dist/runtime/session-runtime.d.ts +16 -3
- package/dist/runtime/session-runtime.d.ts.map +1 -1
- package/dist/runtime/user-input-builder.d.ts +24 -0
- package/dist/runtime/user-input-builder.d.ts.map +1 -0
- package/dist/services/index.js +28 -0
- package/dist/services/local-runtime-bootstrap.d.ts.map +1 -1
- package/dist/services/plugin-tools.d.ts.map +1 -1
- package/dist/services/providers/local-provider-registry.d.ts +197 -21
- package/dist/services/providers/local-provider-registry.d.ts.map +1 -1
- package/dist/services/providers/local-provider-service.d.ts +3 -1
- package/dist/services/providers/local-provider-service.d.ts.map +1 -1
- package/dist/services/session-data.d.ts.map +1 -1
- package/dist/services/session-telemetry.d.ts +7 -2
- package/dist/services/session-telemetry.d.ts.map +1 -1
- package/dist/services/storage/file-team-store.d.ts.map +1 -1
- package/dist/services/storage/provider-settings-legacy-migration.d.ts.map +1 -1
- package/dist/services/storage/provider-settings-manager.d.ts +1 -0
- package/dist/services/storage/provider-settings-manager.d.ts.map +1 -1
- package/dist/services/storage/sqlite-team-store.d.ts.map +1 -1
- package/dist/session/conversation-store.d.ts +30 -0
- package/dist/session/conversation-store.d.ts.map +1 -0
- package/dist/session/message-builder.d.ts +65 -0
- package/dist/session/message-builder.d.ts.map +1 -0
- package/dist/session/session-manifest.d.ts +1 -1
- package/dist/transports/hub.d.ts +14 -3
- package/dist/transports/hub.d.ts.map +1 -1
- package/dist/transports/local.d.ts +14 -4
- package/dist/transports/local.d.ts.map +1 -1
- package/dist/transports/remote.d.ts.map +1 -1
- package/dist/types/chat-schema.d.ts +5 -5
- package/dist/types/config.d.ts +9 -0
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/events.d.ts +7 -6
- package/dist/types/events.d.ts.map +1 -1
- package/dist/types/provider-settings.d.ts +2 -2
- package/dist/types/provider-settings.d.ts.map +1 -1
- package/dist/types/session.d.ts +5 -2
- package/dist/types/session.d.ts.map +1 -1
- package/dist/types.d.ts +4 -4
- package/dist/types.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/ClineCore.ts +691 -6
- package/src/account/cline-account-service.ts +44 -6
- package/src/cron/cron-event-ingress.ts +357 -0
- package/src/cron/cron-materializer.ts +97 -0
- package/src/cron/cron-reconciler.ts +241 -0
- package/src/cron/cron-report-writer.ts +153 -0
- package/src/cron/cron-runner.ts +495 -0
- package/src/cron/cron-schema.ts +127 -0
- package/src/cron/cron-service.ts +163 -0
- package/src/cron/cron-spec-parser.ts +489 -0
- package/src/cron/cron-watcher.ts +102 -0
- package/src/cron/index.ts +10 -0
- package/src/cron/scheduler.ts +141 -6
- package/src/cron/sqlite-cron-store.ts +1286 -0
- package/src/extensions/plugin/plugin-config-loader.ts +21 -1
- package/src/extensions/plugin/plugin-loader.ts +25 -9
- package/src/extensions/plugin/plugin-sandbox-bootstrap.ts +151 -1
- package/src/extensions/plugin/plugin-sandbox.ts +131 -7
- package/src/extensions/tools/constants.ts +2 -0
- package/src/extensions/tools/definitions.ts +31 -22
- package/src/extensions/tools/executors/editor.ts +4 -3
- package/src/extensions/tools/helpers.ts +24 -0
- package/src/extensions/tools/index.ts +1 -2
- package/src/extensions/tools/presets.ts +1 -1
- package/src/extensions/tools/schemas.ts +13 -18
- package/src/extensions/tools/team/delegated-agent.ts +8 -3
- package/src/extensions/tools/team/multi-agent.ts +135 -19
- package/src/extensions/tools/team/team-tools.ts +151 -91
- package/src/extensions/tools/types.ts +0 -6
- package/src/hooks/hook-bridge.ts +489 -0
- package/src/hooks/hook-file-hooks.ts +58 -3
- package/src/hooks/hook-registry.ts +257 -0
- package/src/hub/browser-websocket.ts +26 -4
- package/src/hub/client.ts +72 -13
- package/src/hub/daemon-entry.ts +35 -0
- package/src/hub/daemon.ts +117 -14
- package/src/hub/defaults.ts +39 -12
- package/src/hub/runtime-handlers.ts +4 -3
- package/src/hub/server.ts +506 -77
- package/src/hub/session-client.ts +43 -1
- package/src/hub/start-shared-server.ts +3 -0
- package/src/hub/ui-client.ts +4 -0
- package/src/index.ts +46 -1
- package/src/llms/cline-recommended-models.ts +167 -0
- package/src/llms/handler-factory.ts +56 -0
- package/src/llms/provider-defaults.ts +17 -1
- package/src/llms/provider-settings.ts +48 -1
- package/src/llms/runtime-registry.ts +1 -0
- package/src/runtime/agent-config-adapter.ts +636 -0
- package/src/runtime/agent-runtime-config-builder.ts +205 -0
- package/src/runtime/error-feedback.ts +142 -0
- package/src/runtime/history.ts +137 -0
- package/src/runtime/host.ts +22 -0
- package/src/runtime/loop-detection.ts +162 -0
- package/src/runtime/mistake-tracker.ts +221 -0
- package/src/runtime/runtime-builder.ts +61 -5
- package/src/runtime/runtime-event-adapter.ts +412 -0
- package/src/runtime/runtime-host.ts +45 -1
- package/src/runtime/session-runtime-orchestrator.ts +1253 -0
- package/src/runtime/session-runtime.ts +16 -2
- package/src/runtime/user-input-builder.ts +167 -0
- package/src/services/local-runtime-bootstrap.ts +128 -22
- package/src/services/plugin-tools.ts +1 -0
- package/src/services/providers/local-provider-registry.ts +273 -57
- package/src/services/providers/local-provider-service.ts +67 -7
- package/src/services/session-data.ts +16 -14
- package/src/services/session-telemetry.ts +6 -15
- package/src/services/storage/file-team-store.ts +1 -5
- package/src/services/storage/provider-settings-legacy-migration.ts +8 -47
- package/src/services/storage/provider-settings-manager.ts +16 -1
- package/src/services/storage/sqlite-team-store.ts +1 -5
- package/src/session/conversation-store.ts +77 -0
- package/src/session/message-builder.ts +941 -0
- package/src/transports/hub.ts +458 -33
- package/src/transports/local.ts +296 -65
- package/src/transports/remote.ts +1 -0
- package/src/types/config.ts +9 -0
- package/src/types/events.ts +8 -6
- package/src/types/index.ts +3 -0
- package/src/types/provider-settings.ts +8 -1
- package/src/types/session.ts +5 -2
- package/src/types.ts +15 -1
- package/dist/cron/index.d.ts +0 -6
- package/dist/cron/index.d.ts.map +0 -1
- package/dist/services/telemetry/index.js +0 -28
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { existsSync } from "node:fs";
|
|
2
|
-
import type {
|
|
2
|
+
import type {
|
|
3
|
+
AgentConfig,
|
|
4
|
+
PluginSetupContext,
|
|
5
|
+
WorkspaceInfo,
|
|
6
|
+
} from "@clinebot/shared";
|
|
3
7
|
import {
|
|
4
8
|
discoverPluginModulePaths as discoverPluginModulePathsFromShared,
|
|
5
9
|
resolveConfiguredPluginModulePaths,
|
|
@@ -69,6 +73,12 @@ export interface ResolveAndLoadAgentPluginsOptions
|
|
|
69
73
|
* in the extension context.
|
|
70
74
|
*/
|
|
71
75
|
workspaceInfo?: WorkspaceInfo;
|
|
76
|
+
session?: PluginSetupContext["session"];
|
|
77
|
+
client?: PluginSetupContext["client"];
|
|
78
|
+
user?: PluginSetupContext["user"];
|
|
79
|
+
automation?: PluginSetupContext["automation"];
|
|
80
|
+
logger?: PluginSetupContext["logger"];
|
|
81
|
+
telemetry?: PluginSetupContext["telemetry"];
|
|
72
82
|
}
|
|
73
83
|
|
|
74
84
|
export async function resolveAndLoadAgentPlugins(
|
|
@@ -90,7 +100,13 @@ export async function resolveAndLoadAgentPlugins(
|
|
|
90
100
|
exportName: options.exportName,
|
|
91
101
|
providerId: options.providerId,
|
|
92
102
|
modelId: options.modelId,
|
|
103
|
+
session: options.session,
|
|
104
|
+
client: options.client,
|
|
105
|
+
user: options.user,
|
|
93
106
|
workspaceInfo: options.workspaceInfo,
|
|
107
|
+
automation: options.automation,
|
|
108
|
+
logger: options.logger,
|
|
109
|
+
telemetry: options.telemetry,
|
|
94
110
|
});
|
|
95
111
|
return {
|
|
96
112
|
extensions: report.plugins,
|
|
@@ -109,7 +125,11 @@ export async function resolveAndLoadAgentPlugins(
|
|
|
109
125
|
providerId: options.providerId,
|
|
110
126
|
modelId: options.modelId,
|
|
111
127
|
cwd: options.cwd,
|
|
128
|
+
session: options.session,
|
|
129
|
+
client: options.client,
|
|
130
|
+
user: options.user,
|
|
112
131
|
workspaceInfo: options.workspaceInfo,
|
|
132
|
+
logger: options.logger,
|
|
113
133
|
});
|
|
114
134
|
return {
|
|
115
135
|
extensions: sandboxed.extensions ?? [],
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { resolve } from "node:path";
|
|
2
|
-
import type {
|
|
2
|
+
import type { AgentExtension, PluginSetupContext } from "@clinebot/shared";
|
|
3
3
|
import { normalizePluginManifest } from "@clinebot/shared";
|
|
4
4
|
import type {
|
|
5
5
|
PluginInitializationFailure,
|
|
@@ -11,7 +11,6 @@ import {
|
|
|
11
11
|
type PluginTargeting,
|
|
12
12
|
} from "./plugin-targeting";
|
|
13
13
|
|
|
14
|
-
type AgentPlugin = NonNullable<AgentConfig["extensions"]>[number];
|
|
15
14
|
type PluginLike = {
|
|
16
15
|
name: string;
|
|
17
16
|
manifest: {
|
|
@@ -26,7 +25,13 @@ export interface LoadAgentPluginFromPathOptions {
|
|
|
26
25
|
exportName?: string;
|
|
27
26
|
cwd?: string;
|
|
28
27
|
useCache?: boolean;
|
|
28
|
+
session?: PluginSetupContext["session"];
|
|
29
|
+
client?: PluginSetupContext["client"];
|
|
30
|
+
user?: PluginSetupContext["user"];
|
|
29
31
|
workspaceInfo?: PluginSetupContext["workspaceInfo"];
|
|
32
|
+
automation?: PluginSetupContext["automation"];
|
|
33
|
+
logger?: PluginSetupContext["logger"];
|
|
34
|
+
telemetry?: PluginSetupContext["telemetry"];
|
|
30
35
|
}
|
|
31
36
|
|
|
32
37
|
function isObject(value: unknown): value is Record<string, unknown> {
|
|
@@ -109,7 +114,7 @@ function validatePluginExport(
|
|
|
109
114
|
export async function loadAgentPluginFromPath(
|
|
110
115
|
pluginPath: string,
|
|
111
116
|
options: LoadAgentPluginFromPathOptions = {},
|
|
112
|
-
): Promise<
|
|
117
|
+
): Promise<AgentExtension> {
|
|
113
118
|
const absolutePath = resolve(options.cwd ?? process.cwd(), pluginPath);
|
|
114
119
|
const moduleExports = await importPluginModule(absolutePath, {
|
|
115
120
|
useCache: options.useCache,
|
|
@@ -119,14 +124,25 @@ export async function loadAgentPluginFromPath(
|
|
|
119
124
|
moduleExports[exportName]) as unknown;
|
|
120
125
|
|
|
121
126
|
validatePluginExport(plugin, absolutePath);
|
|
122
|
-
const pluginTyped = plugin as
|
|
127
|
+
const pluginTyped = plugin as AgentExtension;
|
|
123
128
|
const originalSetup = pluginTyped.setup;
|
|
124
129
|
|
|
125
130
|
// Wrap setup to inject workspace context
|
|
126
|
-
const setupWithContext:
|
|
131
|
+
const setupWithContext: AgentExtension["setup"] = originalSetup
|
|
127
132
|
? (api, _ctx) => {
|
|
133
|
+
const session = {
|
|
134
|
+
...options.session,
|
|
135
|
+
..._ctx.session,
|
|
136
|
+
};
|
|
128
137
|
const ctx = {
|
|
129
|
-
|
|
138
|
+
..._ctx,
|
|
139
|
+
session: Object.keys(session).length > 0 ? session : undefined,
|
|
140
|
+
client: options.client ?? _ctx.client,
|
|
141
|
+
user: options.user ?? _ctx.user,
|
|
142
|
+
workspaceInfo: options.workspaceInfo ?? _ctx.workspaceInfo,
|
|
143
|
+
automation: options.automation ?? _ctx.automation,
|
|
144
|
+
logger: options.logger ?? _ctx.logger,
|
|
145
|
+
telemetry: options.telemetry ?? _ctx.telemetry,
|
|
130
146
|
};
|
|
131
147
|
return originalSetup(api, ctx);
|
|
132
148
|
}
|
|
@@ -142,7 +158,7 @@ export async function loadAgentPluginFromPath(
|
|
|
142
158
|
export async function loadAgentPluginsFromPaths(
|
|
143
159
|
pluginPaths: string[],
|
|
144
160
|
options: LoadAgentPluginFromPathOptions & PluginTargeting = {},
|
|
145
|
-
): Promise<
|
|
161
|
+
): Promise<AgentExtension[]> {
|
|
146
162
|
const report = await loadAgentPluginsFromPathsWithDiagnostics(
|
|
147
163
|
pluginPaths,
|
|
148
164
|
options,
|
|
@@ -154,7 +170,7 @@ export async function loadAgentPluginsFromPathsWithDiagnostics(
|
|
|
154
170
|
pluginPaths: string[],
|
|
155
171
|
options: LoadAgentPluginFromPathOptions & PluginTargeting = {},
|
|
156
172
|
): Promise<{
|
|
157
|
-
plugins:
|
|
173
|
+
plugins: AgentExtension[];
|
|
158
174
|
failures: PluginInitializationFailure[];
|
|
159
175
|
warnings: PluginInitializationWarning[];
|
|
160
176
|
}> {
|
|
@@ -162,7 +178,7 @@ export async function loadAgentPluginsFromPathsWithDiagnostics(
|
|
|
162
178
|
const warnings: PluginInitializationWarning[] = [];
|
|
163
179
|
const loadedByName = new Map<
|
|
164
180
|
string,
|
|
165
|
-
{ plugin:
|
|
181
|
+
{ plugin: AgentExtension; pluginPath: string; order: number }
|
|
166
182
|
>();
|
|
167
183
|
let order = 0;
|
|
168
184
|
|
|
@@ -10,7 +10,11 @@
|
|
|
10
10
|
* depend on local helpers that can be inlined into the sandbox build.
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
-
import {
|
|
13
|
+
import {
|
|
14
|
+
type AutomationEventEnvelope,
|
|
15
|
+
normalizePluginManifest,
|
|
16
|
+
type PluginManifest,
|
|
17
|
+
} from "@clinebot/shared";
|
|
14
18
|
import { importPluginModule } from "./plugin-module-import";
|
|
15
19
|
import {
|
|
16
20
|
matchesPluginManifestTargeting,
|
|
@@ -47,15 +51,37 @@ interface PluginProvider {
|
|
|
47
51
|
metadata?: Record<string, unknown>;
|
|
48
52
|
}
|
|
49
53
|
|
|
54
|
+
interface PluginAutomationEventType {
|
|
55
|
+
eventType: string;
|
|
56
|
+
source: string;
|
|
57
|
+
description?: string;
|
|
58
|
+
attributesSchema?: Record<string, unknown>;
|
|
59
|
+
payloadSchema?: Record<string, unknown>;
|
|
60
|
+
examples?: AutomationEventEnvelope[];
|
|
61
|
+
metadata?: Record<string, unknown>;
|
|
62
|
+
}
|
|
63
|
+
|
|
50
64
|
interface PluginApi {
|
|
51
65
|
registerTool(tool: PluginTool): void;
|
|
52
66
|
registerCommand(command: PluginCommand): void;
|
|
53
67
|
registerMessageBuilder(builder: PluginMessageBuilder): void;
|
|
54
68
|
registerProvider(provider: PluginProvider): void;
|
|
69
|
+
registerAutomationEventType(eventType: PluginAutomationEventType): void;
|
|
55
70
|
}
|
|
56
71
|
|
|
57
72
|
interface PluginSetupCtx {
|
|
73
|
+
session?: unknown;
|
|
74
|
+
client?: unknown;
|
|
75
|
+
user?: unknown;
|
|
58
76
|
workspaceInfo?: unknown;
|
|
77
|
+
automation?: {
|
|
78
|
+
ingestEvent(event: AutomationEventEnvelope): void | Promise<void>;
|
|
79
|
+
};
|
|
80
|
+
logger?: {
|
|
81
|
+
debug(message: string, metadata?: Record<string, unknown>): void;
|
|
82
|
+
log(message: string, metadata?: Record<string, unknown>): void;
|
|
83
|
+
error(message: string, metadata?: Record<string, unknown>): void;
|
|
84
|
+
};
|
|
59
85
|
}
|
|
60
86
|
|
|
61
87
|
interface PluginModule {
|
|
@@ -77,6 +103,17 @@ interface ContributionDescriptor {
|
|
|
77
103
|
metadata?: Record<string, unknown>;
|
|
78
104
|
}
|
|
79
105
|
|
|
106
|
+
interface AutomationEventTypeDescriptor {
|
|
107
|
+
id: string;
|
|
108
|
+
eventType: string;
|
|
109
|
+
source: string;
|
|
110
|
+
description?: string;
|
|
111
|
+
attributesSchema?: Record<string, unknown>;
|
|
112
|
+
payloadSchema?: Record<string, unknown>;
|
|
113
|
+
examples?: AutomationEventEnvelope[];
|
|
114
|
+
metadata?: Record<string, unknown>;
|
|
115
|
+
}
|
|
116
|
+
|
|
80
117
|
interface PluginDescriptor {
|
|
81
118
|
pluginId: string;
|
|
82
119
|
pluginPath: string;
|
|
@@ -87,6 +124,7 @@ interface PluginDescriptor {
|
|
|
87
124
|
commands: ContributionDescriptor[];
|
|
88
125
|
messageBuilders: ContributionDescriptor[];
|
|
89
126
|
providers: ContributionDescriptor[];
|
|
127
|
+
automationEventTypes: AutomationEventTypeDescriptor[];
|
|
90
128
|
shortcuts?: ContributionDescriptor[];
|
|
91
129
|
flags?: ContributionDescriptor[];
|
|
92
130
|
};
|
|
@@ -166,9 +204,32 @@ function assertValidPluginSetupCtx(
|
|
|
166
204
|
if (!isObject(ctx)) {
|
|
167
205
|
throw new Error("Plugin setup context must be an object");
|
|
168
206
|
}
|
|
207
|
+
if (ctx.session !== undefined && !isObject(ctx.session)) {
|
|
208
|
+
throw new Error("Plugin setup context session must be an object");
|
|
209
|
+
}
|
|
210
|
+
if (ctx.client !== undefined && !isObject(ctx.client)) {
|
|
211
|
+
throw new Error("Plugin setup context client must be an object");
|
|
212
|
+
}
|
|
213
|
+
if (ctx.user !== undefined && !isObject(ctx.user)) {
|
|
214
|
+
throw new Error("Plugin setup context user must be an object");
|
|
215
|
+
}
|
|
169
216
|
if (ctx.workspaceInfo !== undefined && !isObject(ctx.workspaceInfo)) {
|
|
170
217
|
throw new Error("Plugin setup context workspaceInfo must be an object");
|
|
171
218
|
}
|
|
219
|
+
if (ctx.automation !== undefined && !isObject(ctx.automation)) {
|
|
220
|
+
throw new Error("Plugin setup context automation must be an object");
|
|
221
|
+
}
|
|
222
|
+
if (
|
|
223
|
+
ctx.automation !== undefined &&
|
|
224
|
+
typeof ctx.automation.ingestEvent !== "function"
|
|
225
|
+
) {
|
|
226
|
+
throw new Error(
|
|
227
|
+
"Plugin setup context automation.ingestEvent must be a function",
|
|
228
|
+
);
|
|
229
|
+
}
|
|
230
|
+
if (ctx.logger !== undefined && !isObject(ctx.logger)) {
|
|
231
|
+
throw new Error("Plugin setup context logger must be an object");
|
|
232
|
+
}
|
|
172
233
|
}
|
|
173
234
|
|
|
174
235
|
// ---------------------------------------------------------------------------
|
|
@@ -226,6 +287,45 @@ function sanitizeObject(value: unknown): Record<string, unknown> {
|
|
|
226
287
|
return value as Record<string, unknown>;
|
|
227
288
|
}
|
|
228
289
|
|
|
290
|
+
function sanitizeLogMetadata(
|
|
291
|
+
value: unknown,
|
|
292
|
+
): Record<string, unknown> | undefined {
|
|
293
|
+
if (!value || typeof value !== "object") {
|
|
294
|
+
return undefined;
|
|
295
|
+
}
|
|
296
|
+
const metadata = { ...(value as Record<string, unknown>) };
|
|
297
|
+
if (metadata.error instanceof Error) {
|
|
298
|
+
metadata.error = {
|
|
299
|
+
name: metadata.error.name,
|
|
300
|
+
message: metadata.error.message,
|
|
301
|
+
stack: metadata.error.stack,
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
return metadata;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
function createPluginLogger(
|
|
308
|
+
pluginName: string,
|
|
309
|
+
): NonNullable<PluginSetupCtx["logger"]> {
|
|
310
|
+
const emitLog = (
|
|
311
|
+
level: "debug" | "log" | "error",
|
|
312
|
+
message: string,
|
|
313
|
+
metadata?: Record<string, unknown>,
|
|
314
|
+
) => {
|
|
315
|
+
emitEvent("plugin_log", {
|
|
316
|
+
level,
|
|
317
|
+
pluginName,
|
|
318
|
+
message,
|
|
319
|
+
metadata: sanitizeLogMetadata(metadata),
|
|
320
|
+
});
|
|
321
|
+
};
|
|
322
|
+
return {
|
|
323
|
+
debug: (message, metadata) => emitLog("debug", message, metadata),
|
|
324
|
+
log: (message, metadata) => emitLog("log", message, metadata),
|
|
325
|
+
error: (message, metadata) => emitLog("error", message, metadata),
|
|
326
|
+
};
|
|
327
|
+
}
|
|
328
|
+
|
|
229
329
|
function makeId(pluginId: string, prefix: string): string {
|
|
230
330
|
const key = `${pluginId}:${prefix}`;
|
|
231
331
|
const next = (contributionCounters.get(key) ?? 0) + 1;
|
|
@@ -233,6 +333,30 @@ function makeId(pluginId: string, prefix: string): string {
|
|
|
233
333
|
return `${pluginId}_${prefix}_${next}`;
|
|
234
334
|
}
|
|
235
335
|
|
|
336
|
+
function normalizeAutomationEventType(
|
|
337
|
+
eventType: PluginAutomationEventType,
|
|
338
|
+
): PluginAutomationEventType {
|
|
339
|
+
const normalizedEventType =
|
|
340
|
+
typeof eventType.eventType === "string" ? eventType.eventType.trim() : "";
|
|
341
|
+
const source =
|
|
342
|
+
typeof eventType.source === "string" ? eventType.source.trim() : "";
|
|
343
|
+
if (!normalizedEventType) {
|
|
344
|
+
throw new Error("Automation event type contribution requires eventType");
|
|
345
|
+
}
|
|
346
|
+
if (!source) {
|
|
347
|
+
throw new Error("Automation event type contribution requires source");
|
|
348
|
+
}
|
|
349
|
+
return {
|
|
350
|
+
...eventType,
|
|
351
|
+
eventType: normalizedEventType,
|
|
352
|
+
source,
|
|
353
|
+
examples: eventType.examples ? [...eventType.examples] : undefined,
|
|
354
|
+
metadata: eventType.metadata
|
|
355
|
+
? sanitizeObject(eventType.metadata)
|
|
356
|
+
: undefined,
|
|
357
|
+
};
|
|
358
|
+
}
|
|
359
|
+
|
|
236
360
|
function getPlugin(pluginId: string): PluginState {
|
|
237
361
|
const state = pluginState.get(pluginId);
|
|
238
362
|
if (!state) {
|
|
@@ -251,7 +375,11 @@ async function initialize(args: {
|
|
|
251
375
|
providerId?: string;
|
|
252
376
|
modelId?: string;
|
|
253
377
|
cwd?: string;
|
|
378
|
+
session?: unknown;
|
|
379
|
+
client?: unknown;
|
|
380
|
+
user?: unknown;
|
|
254
381
|
workspaceInfo?: unknown;
|
|
382
|
+
loggerEnabled?: boolean;
|
|
255
383
|
}): Promise<InitializeResult> {
|
|
256
384
|
pluginState.clear();
|
|
257
385
|
pluginCounter = 0;
|
|
@@ -305,6 +433,7 @@ async function initialize(args: {
|
|
|
305
433
|
commands: [],
|
|
306
434
|
messageBuilders: [],
|
|
307
435
|
providers: [],
|
|
436
|
+
automationEventTypes: [],
|
|
308
437
|
shortcuts: [],
|
|
309
438
|
flags: [],
|
|
310
439
|
};
|
|
@@ -351,12 +480,33 @@ async function initialize(args: {
|
|
|
351
480
|
metadata: sanitizeObject(provider.metadata),
|
|
352
481
|
});
|
|
353
482
|
},
|
|
483
|
+
registerAutomationEventType: (eventType) => {
|
|
484
|
+
contributions.automationEventTypes.push({
|
|
485
|
+
id: makeId(pluginId, "automation_event"),
|
|
486
|
+
...normalizeAutomationEventType(eventType),
|
|
487
|
+
});
|
|
488
|
+
},
|
|
354
489
|
};
|
|
355
490
|
|
|
356
491
|
if (typeof plugin.setup === "function") {
|
|
357
492
|
try {
|
|
358
493
|
const setupCtx = {
|
|
494
|
+
session: args.session,
|
|
495
|
+
client: args.client,
|
|
496
|
+
user: args.user,
|
|
359
497
|
workspaceInfo: args.workspaceInfo,
|
|
498
|
+
...(args.loggerEnabled
|
|
499
|
+
? { logger: createPluginLogger(plugin.name) }
|
|
500
|
+
: {}),
|
|
501
|
+
...(plugin.manifest.capabilities.includes("automationEvents")
|
|
502
|
+
? {
|
|
503
|
+
automation: {
|
|
504
|
+
ingestEvent: (event: AutomationEventEnvelope) => {
|
|
505
|
+
emitEvent("automation_event", event);
|
|
506
|
+
},
|
|
507
|
+
},
|
|
508
|
+
}
|
|
509
|
+
: {}),
|
|
360
510
|
};
|
|
361
511
|
assertValidPluginSetupCtx(setupCtx);
|
|
362
512
|
await plugin.setup(api, setupCtx);
|
|
@@ -4,7 +4,10 @@ import { dirname, join } from "node:path";
|
|
|
4
4
|
import { fileURLToPath } from "node:url";
|
|
5
5
|
import type {
|
|
6
6
|
AgentConfig,
|
|
7
|
+
AgentExtensionAutomationEventType,
|
|
7
8
|
HookStage,
|
|
9
|
+
Message,
|
|
10
|
+
PluginSetupContext,
|
|
8
11
|
Tool,
|
|
9
12
|
WorkspaceInfo,
|
|
10
13
|
} from "@clinebot/shared";
|
|
@@ -12,6 +15,11 @@ import { SubprocessSandbox } from "../../runtime/subprocess-sandbox";
|
|
|
12
15
|
import type { PluginLoadDiagnostics } from "./plugin-load-report";
|
|
13
16
|
import type { PluginTargeting } from "./plugin-targeting";
|
|
14
17
|
|
|
18
|
+
export type SandboxedPluginSetupContext = Pick<
|
|
19
|
+
PluginSetupContext,
|
|
20
|
+
"session" | "client" | "user" | "workspaceInfo" | "logger"
|
|
21
|
+
>;
|
|
22
|
+
|
|
15
23
|
export interface PluginSandboxOptions extends PluginTargeting {
|
|
16
24
|
pluginPaths: string[];
|
|
17
25
|
exportName?: string;
|
|
@@ -31,6 +39,11 @@ export interface PluginSandboxOptions extends PluginTargeting {
|
|
|
31
39
|
* so they can inspect git state without running their own commands.
|
|
32
40
|
*/
|
|
33
41
|
workspaceInfo?: WorkspaceInfo;
|
|
42
|
+
session?: SandboxedPluginSetupContext["session"];
|
|
43
|
+
client?: SandboxedPluginSetupContext["client"];
|
|
44
|
+
user?: SandboxedPluginSetupContext["user"];
|
|
45
|
+
/** Enables a logger bridge that forwards sandbox log calls to the host. */
|
|
46
|
+
logger?: SandboxedPluginSetupContext["logger"];
|
|
34
47
|
}
|
|
35
48
|
|
|
36
49
|
type AgentExtension = NonNullable<AgentConfig["extensions"]>[number];
|
|
@@ -46,6 +59,11 @@ type SandboxedContributionDescriptor = {
|
|
|
46
59
|
metadata?: Record<string, unknown>;
|
|
47
60
|
};
|
|
48
61
|
|
|
62
|
+
type SandboxedAutomationEventTypeDescriptor =
|
|
63
|
+
AgentExtensionAutomationEventType & {
|
|
64
|
+
id: string;
|
|
65
|
+
};
|
|
66
|
+
|
|
49
67
|
type SandboxedPluginDescriptor = {
|
|
50
68
|
pluginId: string;
|
|
51
69
|
pluginPath: string;
|
|
@@ -56,6 +74,7 @@ type SandboxedPluginDescriptor = {
|
|
|
56
74
|
commands: SandboxedContributionDescriptor[];
|
|
57
75
|
messageBuilders: SandboxedContributionDescriptor[];
|
|
58
76
|
providers: SandboxedContributionDescriptor[];
|
|
77
|
+
automationEventTypes: SandboxedAutomationEventTypeDescriptor[];
|
|
59
78
|
shortcuts?: SandboxedContributionDescriptor[];
|
|
60
79
|
flags?: SandboxedContributionDescriptor[];
|
|
61
80
|
};
|
|
@@ -75,6 +94,8 @@ function normalizeDescriptor(
|
|
|
75
94
|
commands: descriptor.contributions?.commands ?? [],
|
|
76
95
|
messageBuilders: descriptor.contributions?.messageBuilders ?? [],
|
|
77
96
|
providers: descriptor.contributions?.providers ?? [],
|
|
97
|
+
automationEventTypes:
|
|
98
|
+
descriptor.contributions?.automationEventTypes ?? [],
|
|
78
99
|
shortcuts: descriptor.contributions?.shortcuts ?? [],
|
|
79
100
|
flags: descriptor.contributions?.flags ?? [],
|
|
80
101
|
},
|
|
@@ -145,6 +166,21 @@ const HOOK_BINDINGS: Array<{
|
|
|
145
166
|
extensionKey: "onSessionStart",
|
|
146
167
|
sandboxHookName: "onSessionStart",
|
|
147
168
|
},
|
|
169
|
+
{
|
|
170
|
+
stage: "run_start",
|
|
171
|
+
extensionKey: "onRunStart",
|
|
172
|
+
sandboxHookName: "onRunStart",
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
stage: "iteration_start",
|
|
176
|
+
extensionKey: "onIterationStart",
|
|
177
|
+
sandboxHookName: "onIterationStart",
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
stage: "turn_start",
|
|
181
|
+
extensionKey: "onTurnStart",
|
|
182
|
+
sandboxHookName: "onTurnStart",
|
|
183
|
+
},
|
|
148
184
|
{
|
|
149
185
|
stage: "before_agent_start",
|
|
150
186
|
extensionKey: "onBeforeAgentStart",
|
|
@@ -165,6 +201,21 @@ const HOOK_BINDINGS: Array<{
|
|
|
165
201
|
extensionKey: "onTurnEnd",
|
|
166
202
|
sandboxHookName: "onTurnEnd",
|
|
167
203
|
},
|
|
204
|
+
{
|
|
205
|
+
stage: "stop_error",
|
|
206
|
+
extensionKey: "onAgentError",
|
|
207
|
+
sandboxHookName: "onAgentError",
|
|
208
|
+
},
|
|
209
|
+
{
|
|
210
|
+
stage: "iteration_end",
|
|
211
|
+
extensionKey: "onIterationEnd",
|
|
212
|
+
sandboxHookName: "onIterationEnd",
|
|
213
|
+
},
|
|
214
|
+
{
|
|
215
|
+
stage: "run_end",
|
|
216
|
+
extensionKey: "onRunEnd",
|
|
217
|
+
sandboxHookName: "onRunEnd",
|
|
218
|
+
},
|
|
168
219
|
{
|
|
169
220
|
stage: "session_shutdown",
|
|
170
221
|
extensionKey: "onSessionShutdown",
|
|
@@ -216,7 +267,11 @@ export async function loadSandboxedPlugins(
|
|
|
216
267
|
providerId: options.providerId,
|
|
217
268
|
modelId: options.modelId,
|
|
218
269
|
cwd: options.cwd,
|
|
270
|
+
session: options.session,
|
|
271
|
+
client: options.client,
|
|
272
|
+
user: options.user,
|
|
219
273
|
workspaceInfo: options.workspaceInfo,
|
|
274
|
+
loggerEnabled: Boolean(options.logger),
|
|
220
275
|
};
|
|
221
276
|
|
|
222
277
|
// Guard against concurrent re-initialization when multiple tools/hooks
|
|
@@ -266,6 +321,13 @@ export async function loadSandboxedPlugins(
|
|
|
266
321
|
contributionTimeoutMs,
|
|
267
322
|
reinitialize,
|
|
268
323
|
);
|
|
324
|
+
registerMessageBuilders(
|
|
325
|
+
api,
|
|
326
|
+
sandbox,
|
|
327
|
+
descriptor,
|
|
328
|
+
contributionTimeoutMs,
|
|
329
|
+
reinitialize,
|
|
330
|
+
);
|
|
269
331
|
registerSimpleContributions(api, descriptor);
|
|
270
332
|
},
|
|
271
333
|
};
|
|
@@ -393,13 +455,6 @@ function registerSimpleContributions(
|
|
|
393
455
|
api: AgentExtensionApi,
|
|
394
456
|
descriptor: SandboxedPluginDescriptor,
|
|
395
457
|
): void {
|
|
396
|
-
for (const rd of descriptor.contributions?.messageBuilders ?? []) {
|
|
397
|
-
api.registerMessageBuilder({
|
|
398
|
-
name: rd.name,
|
|
399
|
-
build: (m) => m,
|
|
400
|
-
});
|
|
401
|
-
}
|
|
402
|
-
|
|
403
458
|
for (const pd of descriptor.contributions?.providers ?? []) {
|
|
404
459
|
api.registerProvider({
|
|
405
460
|
name: pd.name,
|
|
@@ -407,6 +462,75 @@ function registerSimpleContributions(
|
|
|
407
462
|
metadata: pd.metadata,
|
|
408
463
|
});
|
|
409
464
|
}
|
|
465
|
+
|
|
466
|
+
for (const eventType of descriptor.contributions?.automationEventTypes ??
|
|
467
|
+
[]) {
|
|
468
|
+
api.registerAutomationEventType({
|
|
469
|
+
eventType: eventType.eventType,
|
|
470
|
+
source: eventType.source,
|
|
471
|
+
description: eventType.description,
|
|
472
|
+
attributesSchema: eventType.attributesSchema,
|
|
473
|
+
payloadSchema: eventType.payloadSchema,
|
|
474
|
+
examples: eventType.examples,
|
|
475
|
+
metadata: eventType.metadata,
|
|
476
|
+
});
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
function registerMessageBuilders(
|
|
481
|
+
api: AgentExtensionApi,
|
|
482
|
+
sandbox: SubprocessSandbox,
|
|
483
|
+
descriptor: SandboxedPluginDescriptor,
|
|
484
|
+
timeoutMs: number,
|
|
485
|
+
reinitialize: () => Promise<void>,
|
|
486
|
+
): void {
|
|
487
|
+
for (const bd of descriptor.contributions?.messageBuilders ?? []) {
|
|
488
|
+
api.registerMessageBuilder({
|
|
489
|
+
name: bd.name,
|
|
490
|
+
async build(messages) {
|
|
491
|
+
try {
|
|
492
|
+
const result = await sandbox.call<unknown[]>(
|
|
493
|
+
"buildMessages",
|
|
494
|
+
{
|
|
495
|
+
pluginId: descriptor.pluginId,
|
|
496
|
+
contributionId: bd.id,
|
|
497
|
+
messages,
|
|
498
|
+
},
|
|
499
|
+
{ timeoutMs },
|
|
500
|
+
);
|
|
501
|
+
return isMessageArray(result) ? result : messages;
|
|
502
|
+
} catch (error) {
|
|
503
|
+
if (!isUnknownPluginIdError(error)) {
|
|
504
|
+
throw error;
|
|
505
|
+
}
|
|
506
|
+
await reinitialize();
|
|
507
|
+
const result = await sandbox.call<unknown[]>(
|
|
508
|
+
"buildMessages",
|
|
509
|
+
{
|
|
510
|
+
pluginId: descriptor.pluginId,
|
|
511
|
+
contributionId: bd.id,
|
|
512
|
+
messages,
|
|
513
|
+
},
|
|
514
|
+
{ timeoutMs },
|
|
515
|
+
);
|
|
516
|
+
return isMessageArray(result) ? result : messages;
|
|
517
|
+
}
|
|
518
|
+
},
|
|
519
|
+
});
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
function isMessageArray(value: unknown): value is Message[] {
|
|
524
|
+
return (
|
|
525
|
+
Array.isArray(value) &&
|
|
526
|
+
value.every(
|
|
527
|
+
(entry) =>
|
|
528
|
+
typeof entry === "object" &&
|
|
529
|
+
entry !== null &&
|
|
530
|
+
"role" in entry &&
|
|
531
|
+
"content" in entry,
|
|
532
|
+
)
|
|
533
|
+
);
|
|
410
534
|
}
|
|
411
535
|
|
|
412
536
|
function makeHookHandler(
|
|
@@ -18,6 +18,7 @@ export const DefaultToolNames = {
|
|
|
18
18
|
EDITOR: "editor",
|
|
19
19
|
SKILLS: "skills",
|
|
20
20
|
ASK: "ask_question",
|
|
21
|
+
SUBMIT_AND_EXIT: "submit_and_exit",
|
|
21
22
|
} as const;
|
|
22
23
|
|
|
23
24
|
/**
|
|
@@ -32,4 +33,5 @@ export const ALL_DEFAULT_TOOL_NAMES: DefaultToolName[] = [
|
|
|
32
33
|
DefaultToolNames.EDITOR,
|
|
33
34
|
DefaultToolNames.SKILLS,
|
|
34
35
|
DefaultToolNames.ASK,
|
|
36
|
+
DefaultToolNames.SUBMIT_AND_EXIT,
|
|
35
37
|
];
|