@clinebot/core 0.0.28 → 0.0.29
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 +7 -0
- package/dist/ClineCore.d.ts +28 -2
- package/dist/ClineCore.d.ts.map +1 -1
- package/dist/account/cline-account-service.d.ts +1 -1
- package/dist/account/cline-account-service.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/types.d.ts +5 -0
- package/dist/account/types.d.ts.map +1 -1
- package/dist/auth/bounded-ttl-cache.d.ts +14 -0
- package/dist/auth/bounded-ttl-cache.d.ts.map +1 -0
- package/dist/auth/cline.d.ts +27 -2
- package/dist/auth/cline.d.ts.map +1 -1
- package/dist/auth/oca.d.ts.map +1 -1
- package/dist/chat/chat-schema.d.ts +11 -11
- package/dist/extensions/config/agent-config-loader.d.ts.map +1 -0
- package/dist/{agents → extensions/config}/agent-config-parser.d.ts +2 -2
- package/dist/extensions/config/agent-config-parser.d.ts.map +1 -0
- package/dist/{agents → extensions/config}/hooks-config-loader.d.ts +1 -1
- package/dist/extensions/config/hooks-config-loader.d.ts.map +1 -0
- package/dist/{agents → extensions/config}/index.d.ts +2 -4
- package/dist/extensions/config/index.d.ts.map +1 -0
- package/dist/{runtime/commands.d.ts → extensions/config/runtime-commands.d.ts} +2 -3
- package/dist/extensions/config/runtime-commands.d.ts.map +1 -0
- package/dist/extensions/config/unified-config-file-watcher.d.ts.map +1 -0
- package/dist/extensions/config/user-instruction-config-loader.d.ts.map +1 -0
- package/dist/extensions/context/agentic-compaction.d.ts +13 -0
- package/dist/extensions/context/agentic-compaction.d.ts.map +1 -0
- package/dist/extensions/context/basic-compaction.d.ts +9 -0
- package/dist/extensions/context/basic-compaction.d.ts.map +1 -0
- package/dist/extensions/context/compaction-shared.d.ts +60 -0
- package/dist/extensions/context/compaction-shared.d.ts.map +1 -0
- package/dist/extensions/context/compaction.d.ts +20 -0
- package/dist/extensions/context/compaction.d.ts.map +1 -0
- package/dist/extensions/index.d.ts +5 -0
- package/dist/extensions/index.d.ts.map +1 -0
- package/dist/extensions/mcp/client.d.ts +3 -0
- package/dist/extensions/mcp/client.d.ts.map +1 -0
- package/dist/extensions/mcp/config-loader.d.ts.map +1 -0
- package/dist/extensions/mcp/index.d.ts +9 -0
- package/dist/extensions/mcp/index.d.ts.map +1 -0
- package/dist/{mcp → extensions/mcp}/manager.d.ts +1 -2
- package/dist/extensions/mcp/manager.d.ts.map +1 -0
- package/dist/extensions/mcp/name-transform.d.ts +3 -0
- package/dist/extensions/mcp/name-transform.d.ts.map +1 -0
- package/dist/extensions/mcp/policies.d.ts +15 -0
- package/dist/extensions/mcp/policies.d.ts.map +1 -0
- package/dist/extensions/mcp/tools.d.ts +4 -0
- package/dist/extensions/mcp/tools.d.ts.map +1 -0
- package/dist/{mcp → extensions/mcp}/types.d.ts +29 -1
- package/dist/extensions/mcp/types.d.ts.map +1 -0
- package/dist/{agents → extensions/plugin}/plugin-config-loader.d.ts +1 -1
- package/dist/extensions/plugin/plugin-config-loader.d.ts.map +1 -0
- package/dist/{agents → extensions/plugin}/plugin-loader.d.ts +1 -1
- package/dist/extensions/plugin/plugin-loader.d.ts.map +1 -0
- package/dist/extensions/plugin/plugin-module-import.d.ts +5 -0
- package/dist/extensions/plugin/plugin-module-import.d.ts.map +1 -0
- package/dist/{agents → extensions/plugin}/plugin-sandbox.d.ts +1 -1
- package/dist/extensions/plugin/plugin-sandbox.d.ts.map +1 -0
- package/dist/extensions/plugin-sandbox-bootstrap.js +485 -0
- package/dist/hooks/index.d.ts +4 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/persistent.d.ts +64 -0
- package/dist/hooks/persistent.d.ts.map +1 -0
- package/dist/hooks/subprocess-runner.d.ts +22 -0
- package/dist/hooks/subprocess-runner.d.ts.map +1 -0
- package/dist/hooks/subprocess.d.ts +189 -0
- package/dist/hooks/subprocess.d.ts.map +1 -0
- package/dist/index.d.ts +22 -25
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +560 -447
- package/dist/prompt/default-system.d.ts +2 -0
- package/dist/prompt/default-system.d.ts.map +1 -0
- package/dist/providers/local-provider-service.d.ts +1 -1
- package/dist/providers/local-provider-service.d.ts.map +1 -1
- package/dist/runtime/checkpoint-hooks.d.ts +21 -0
- package/dist/runtime/checkpoint-hooks.d.ts.map +1 -0
- package/dist/runtime/hook-file-hooks.d.ts +1 -1
- package/dist/runtime/hook-file-hooks.d.ts.map +1 -1
- package/dist/runtime/rules.d.ts +1 -1
- package/dist/runtime/rules.d.ts.map +1 -1
- package/dist/runtime/runtime-builder.d.ts +1 -1
- package/dist/runtime/runtime-builder.d.ts.map +1 -1
- package/dist/runtime/session-runtime.d.ts +25 -5
- package/dist/runtime/session-runtime.d.ts.map +1 -1
- package/dist/runtime/subprocess-sandbox.d.ts.map +1 -0
- package/dist/runtime/team-runtime-registry.d.ts +1 -1
- package/dist/runtime/team-runtime-registry.d.ts.map +1 -1
- package/dist/runtime/tool-approval.d.ts +1 -1
- package/dist/session/default-session-manager.d.ts +4 -3
- package/dist/session/default-session-manager.d.ts.map +1 -1
- package/dist/session/file-session-service.d.ts +1 -1
- package/dist/session/file-session-service.d.ts.map +1 -1
- package/dist/session/{unified-session-persistence-service.d.ts → persistence-service.d.ts} +11 -42
- package/dist/session/persistence-service.d.ts.map +1 -0
- package/dist/session/rpc-session-service.d.ts +1 -1
- package/dist/session/rpc-session-service.d.ts.map +1 -1
- package/dist/session/session-agent-events.d.ts +1 -1
- package/dist/session/session-artifacts.d.ts.map +1 -1
- package/dist/session/session-config-builder.d.ts.map +1 -1
- package/dist/session/session-graph.d.ts +1 -1
- package/dist/session/session-graph.d.ts.map +1 -1
- package/dist/session/session-host.d.ts.map +1 -1
- package/dist/session/session-manager.d.ts +6 -5
- package/dist/session/session-manager.d.ts.map +1 -1
- package/dist/session/session-manifest.d.ts +1 -1
- package/dist/session/session-service.d.ts +3 -2
- package/dist/session/session-service.d.ts.map +1 -1
- package/dist/session/session-team-coordination.d.ts +2 -1
- package/dist/session/session-team-coordination.d.ts.map +1 -1
- package/dist/session/utils/helpers.d.ts +51 -3
- package/dist/session/utils/helpers.d.ts.map +1 -1
- package/dist/session/utils/types.d.ts +41 -7
- package/dist/session/utils/types.d.ts.map +1 -1
- package/dist/session/workspace-manager.d.ts +1 -2
- package/dist/session/workspace-manager.d.ts.map +1 -1
- package/dist/session/workspace-manifest.d.ts +1 -22
- package/dist/session/workspace-manifest.d.ts.map +1 -1
- package/dist/storage/file-team-store.d.ts +2 -1
- package/dist/storage/file-team-store.d.ts.map +1 -1
- package/dist/storage/sqlite-team-store.d.ts +4 -1
- package/dist/storage/sqlite-team-store.d.ts.map +1 -1
- package/dist/storage/team-store.d.ts.map +1 -1
- package/dist/team/delegated-agent.d.ts +44 -0
- package/dist/team/delegated-agent.d.ts.map +1 -0
- package/dist/team/index.d.ts +1 -0
- package/dist/team/index.d.ts.map +1 -1
- package/dist/team/multi-agent.d.ts +229 -0
- package/dist/team/multi-agent.d.ts.map +1 -0
- package/dist/team/projections.d.ts +2 -2
- package/dist/team/projections.d.ts.map +1 -1
- package/dist/team/runtime.d.ts +5 -0
- package/dist/team/runtime.d.ts.map +1 -0
- package/dist/team/spawn-agent-tool.d.ts +85 -0
- package/dist/team/spawn-agent-tool.d.ts.map +1 -0
- package/dist/team/subagent-prompts.d.ts +4 -0
- package/dist/team/subagent-prompts.d.ts.map +1 -0
- package/dist/team/team-tools.d.ts +35 -0
- package/dist/team/team-tools.d.ts.map +1 -0
- package/dist/telemetry/OpenTelemetryProvider.d.ts +11 -1
- package/dist/telemetry/OpenTelemetryProvider.d.ts.map +1 -1
- package/dist/telemetry/{LoggerTelemetryAdapter.d.ts → TelemetryLoggerSink.d.ts} +10 -4
- package/dist/telemetry/TelemetryLoggerSink.d.ts.map +1 -0
- package/dist/telemetry/TelemetryService.d.ts.map +1 -1
- package/dist/telemetry/index.js +15 -28
- package/dist/tools/definitions.d.ts +4 -3
- package/dist/tools/definitions.d.ts.map +1 -1
- package/dist/tools/index.d.ts +5 -5
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/model-tool-routing.d.ts.map +1 -1
- package/dist/tools/presets.d.ts +26 -0
- package/dist/tools/presets.d.ts.map +1 -1
- package/dist/tools/schemas.d.ts +8 -0
- package/dist/tools/schemas.d.ts.map +1 -1
- package/dist/tools/types.d.ts +23 -2
- package/dist/tools/types.d.ts.map +1 -1
- package/dist/types/config.d.ts +47 -3
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/events.d.ts +1 -1
- package/dist/types/provider-settings.d.ts +1 -1
- package/dist/types/provider-settings.d.ts.map +1 -1
- package/dist/types/storage.d.ts +2 -1
- package/dist/types/storage.d.ts.map +1 -1
- package/dist/types.d.ts +7 -16
- package/dist/types.d.ts.map +1 -1
- package/package.json +15 -12
- package/src/ClineCore.test.ts +150 -0
- package/src/ClineCore.ts +114 -8
- package/src/account/cline-account-service.test.ts +84 -0
- package/src/account/cline-account-service.ts +2 -2
- package/src/account/index.ts +1 -0
- package/src/account/types.ts +6 -0
- package/src/auth/bounded-ttl-cache.test.ts +38 -0
- package/src/auth/bounded-ttl-cache.ts +53 -0
- package/src/auth/cline.test.ts +173 -36
- package/src/auth/cline.ts +395 -93
- package/src/auth/oca.test.ts +125 -0
- package/src/auth/oca.ts +17 -4
- package/src/{agents → extensions/config}/agent-config-loader.test.ts +1 -1
- package/src/{agents → extensions/config}/agent-config-parser.ts +2 -2
- package/src/{agents → extensions/config}/hooks-config-loader.ts +1 -1
- package/src/{agents → extensions/config}/index.ts +7 -11
- package/src/{runtime/commands.test.ts → extensions/config/runtime-commands.test.ts} +20 -3
- package/src/{runtime/commands.ts → extensions/config/runtime-commands.ts} +1 -8
- package/src/{agents → extensions/config}/unified-config-file-watcher.ts +15 -2
- package/src/{agents → extensions/config}/user-instruction-config-loader.test.ts +90 -2
- package/src/{agents → extensions/config}/user-instruction-config-loader.ts +126 -12
- package/src/extensions/context/agentic-compaction.ts +119 -0
- package/src/extensions/context/basic-compaction.ts +275 -0
- package/src/extensions/context/compaction-shared.ts +458 -0
- package/src/extensions/context/compaction.test.ts +477 -0
- package/src/extensions/context/compaction.ts +203 -0
- package/src/extensions/index.ts +12 -0
- package/src/extensions/mcp/client.ts +420 -0
- package/src/{mcp → extensions/mcp}/index.ts +16 -0
- package/src/{mcp → extensions/mcp}/manager.test.ts +1 -2
- package/src/{mcp → extensions/mcp}/manager.ts +3 -5
- package/src/extensions/mcp/name-transform.ts +33 -0
- package/src/extensions/mcp/policies.ts +47 -0
- package/src/extensions/mcp/tools.ts +47 -0
- package/src/{mcp → extensions/mcp}/types.ts +35 -7
- package/src/{agents → extensions/plugin}/plugin-config-loader.test.ts +18 -13
- package/src/{agents → extensions/plugin}/plugin-config-loader.ts +1 -1
- package/src/{agents → extensions/plugin}/plugin-loader.test.ts +41 -4
- package/src/extensions/plugin/plugin-loader.ts +106 -0
- package/src/extensions/plugin/plugin-module-import.ts +278 -0
- package/src/{agents → extensions/plugin}/plugin-sandbox-bootstrap.ts +30 -92
- package/src/{agents → extensions/plugin}/plugin-sandbox.test.ts +60 -3
- package/src/{agents → extensions/plugin}/plugin-sandbox.ts +146 -56
- package/src/hooks/index.ts +25 -0
- package/src/hooks/persistent.ts +661 -0
- package/src/hooks/subprocess-runner.ts +196 -0
- package/src/hooks/subprocess.ts +669 -0
- package/src/index.ts +200 -118
- package/src/prompt/default-system.ts +21 -0
- package/src/providers/local-provider-registry.ts +1 -1
- package/src/providers/local-provider-service.test.ts +23 -2
- package/src/providers/local-provider-service.ts +2 -2
- package/src/runtime/checkpoint-hooks.test.ts +167 -0
- package/src/runtime/checkpoint-hooks.ts +186 -0
- package/src/runtime/hook-file-hooks.test.ts +40 -1
- package/src/runtime/hook-file-hooks.ts +35 -16
- package/src/runtime/index.ts +4 -19
- package/src/runtime/rules.ts +4 -1
- package/src/runtime/runtime-builder.team-persistence.test.ts +3 -6
- package/src/runtime/runtime-builder.test.ts +266 -160
- package/src/runtime/runtime-builder.ts +120 -47
- package/src/runtime/runtime-parity.test.ts +22 -22
- package/src/runtime/session-runtime.ts +36 -6
- package/src/runtime/{sandbox/subprocess-sandbox.ts → subprocess-sandbox.ts} +24 -3
- package/src/runtime/team-runtime-registry.ts +1 -4
- package/src/runtime/tool-approval.ts +1 -1
- package/src/session/default-session-manager.e2e.test.ts +2 -2
- package/src/session/default-session-manager.test.ts +553 -9
- package/src/session/default-session-manager.ts +140 -46
- package/src/session/file-session-service.ts +3 -3
- package/src/session/index.ts +6 -6
- package/src/session/persistence-service.test.ts +212 -0
- package/src/session/{unified-session-persistence-service.ts → persistence-service.ts} +106 -172
- package/src/session/rpc-session-service.ts +3 -3
- package/src/session/runtime-oauth-token-manager.ts +1 -1
- package/src/session/session-agent-events.ts +1 -1
- package/src/session/session-artifacts.ts +32 -4
- package/src/session/session-config-builder.ts +22 -9
- package/src/session/session-graph.ts +1 -1
- package/src/session/session-host.ts +19 -11
- package/src/session/session-manager.ts +11 -6
- package/src/session/session-service.team-persistence.test.ts +1 -1
- package/src/session/session-service.ts +6 -9
- package/src/session/session-team-coordination.ts +7 -3
- package/src/session/session-telemetry.ts +1 -1
- package/src/session/utils/helpers.test.ts +160 -0
- package/src/session/utils/helpers.ts +289 -42
- package/src/session/utils/types.ts +47 -7
- package/src/session/workspace-manager.ts +5 -3
- package/src/session/workspace-manifest.ts +3 -49
- package/src/storage/file-team-store.ts +2 -5
- package/src/storage/provider-settings-legacy-migration.ts +2 -2
- package/src/storage/provider-settings-manager.test.ts +1 -1
- package/src/storage/sqlite-team-store.ts +212 -125
- package/src/storage/team-store.ts +1 -5
- package/src/team/delegated-agent.ts +131 -0
- package/src/team/index.ts +1 -0
- package/src/team/multi-agent.lifecycle.test.ts +201 -0
- package/src/team/multi-agent.ts +1666 -0
- package/src/team/projections.ts +2 -4
- package/src/team/runtime.ts +54 -0
- package/src/team/spawn-agent-tool.test.ts +387 -0
- package/src/team/spawn-agent-tool.ts +207 -0
- package/src/team/subagent-prompts.ts +41 -0
- package/src/team/team-tools.test.ts +802 -0
- package/src/team/team-tools.ts +792 -0
- package/src/telemetry/OpenTelemetryProvider.test.ts +25 -3
- package/src/telemetry/OpenTelemetryProvider.ts +108 -18
- package/src/telemetry/TelemetryLoggerSink.test.ts +42 -0
- package/src/telemetry/{LoggerTelemetryAdapter.ts → TelemetryLoggerSink.ts} +21 -14
- package/src/telemetry/TelemetryService.test.ts +7 -7
- package/src/telemetry/TelemetryService.ts +2 -4
- package/src/tools/definitions.test.ts +76 -0
- package/src/tools/definitions.ts +41 -2
- package/src/tools/executors/apply-patch.ts +1 -1
- package/src/tools/executors/editor.ts +1 -1
- package/src/tools/executors/file-read.ts +1 -1
- package/src/tools/executors/search.ts +1 -1
- package/src/tools/executors/web-fetch.ts +1 -1
- package/src/tools/index.ts +6 -1
- package/src/tools/model-tool-routing.ts +2 -0
- package/src/tools/presets.test.ts +8 -0
- package/src/tools/presets.ts +40 -2
- package/src/tools/schemas.ts +19 -0
- package/src/tools/types.ts +31 -2
- package/src/types/config.ts +61 -7
- package/src/types/events.ts +1 -1
- package/src/types/index.ts +0 -1
- package/src/types/provider-settings.ts +1 -1
- package/src/types/storage.ts +2 -5
- package/src/types.ts +32 -44
- package/dist/agents/agent-config-loader.d.ts.map +0 -1
- package/dist/agents/agent-config-parser.d.ts.map +0 -1
- package/dist/agents/hooks-config-loader.d.ts.map +0 -1
- package/dist/agents/index.d.ts.map +0 -1
- package/dist/agents/plugin-config-loader.d.ts.map +0 -1
- package/dist/agents/plugin-loader.d.ts.map +0 -1
- package/dist/agents/plugin-sandbox-bootstrap.js +0 -446
- package/dist/agents/plugin-sandbox.d.ts.map +0 -1
- package/dist/agents/unified-config-file-watcher.d.ts.map +0 -1
- package/dist/agents/user-instruction-config-loader.d.ts.map +0 -1
- package/dist/mcp/config-loader.d.ts.map +0 -1
- package/dist/mcp/index.d.ts +0 -5
- package/dist/mcp/index.d.ts.map +0 -1
- package/dist/mcp/manager.d.ts.map +0 -1
- package/dist/mcp/types.d.ts.map +0 -1
- package/dist/runtime/commands.d.ts.map +0 -1
- package/dist/runtime/sandbox/subprocess-sandbox.d.ts.map +0 -1
- package/dist/runtime/skills.d.ts +0 -14
- package/dist/runtime/skills.d.ts.map +0 -1
- package/dist/runtime/workflows.d.ts +0 -14
- package/dist/runtime/workflows.d.ts.map +0 -1
- package/dist/session/unified-session-persistence-service.d.ts.map +0 -1
- package/dist/telemetry/LoggerTelemetryAdapter.d.ts.map +0 -1
- package/dist/types/workspace.d.ts +0 -8
- package/dist/types/workspace.d.ts.map +0 -1
- package/src/agents/plugin-loader.ts +0 -175
- package/src/runtime/skills.ts +0 -44
- package/src/runtime/workflows.test.ts +0 -119
- package/src/runtime/workflows.ts +0 -45
- package/src/session/unified-session-persistence-service.test.ts +0 -85
- package/src/telemetry/LoggerTelemetryAdapter.test.ts +0 -42
- package/src/types/workspace.ts +0 -7
- /package/dist/{agents → extensions/config}/agent-config-loader.d.ts +0 -0
- /package/dist/{agents → extensions/config}/unified-config-file-watcher.d.ts +0 -0
- /package/dist/{agents → extensions/config}/user-instruction-config-loader.d.ts +0 -0
- /package/dist/{mcp → extensions/mcp}/config-loader.d.ts +0 -0
- /package/dist/runtime/{sandbox/subprocess-sandbox.d.ts → subprocess-sandbox.d.ts} +0 -0
- /package/src/{agents → extensions/config}/agent-config-loader.ts +0 -0
- /package/src/{agents → extensions/config}/hooks-config-loader.test.ts +0 -0
- /package/src/{agents → extensions/config}/unified-config-file-watcher.test.ts +0 -0
- /package/src/{mcp → extensions/mcp}/config-loader.test.ts +0 -0
- /package/src/{mcp → extensions/mcp}/config-loader.ts +0 -0
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import { execFile as execFileCallback } from "node:child_process";
|
|
2
|
+
import { promisify } from "node:util";
|
|
3
|
+
import type { AgentHooks, BasicLogger } from "@clinebot/shared";
|
|
4
|
+
|
|
5
|
+
const execFile = promisify(execFileCallback);
|
|
6
|
+
|
|
7
|
+
export interface CheckpointEntry {
|
|
8
|
+
ref: string;
|
|
9
|
+
createdAt: number;
|
|
10
|
+
runCount: number;
|
|
11
|
+
kind?: "stash" | "commit";
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface CheckpointMetadata {
|
|
15
|
+
latest: CheckpointEntry;
|
|
16
|
+
history: CheckpointEntry[];
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
type CreateCheckpointHooksOptions = {
|
|
20
|
+
cwd: string;
|
|
21
|
+
sessionId: string;
|
|
22
|
+
logger?: BasicLogger;
|
|
23
|
+
readSessionMetadata: () => Promise<Record<string, unknown> | undefined>;
|
|
24
|
+
writeSessionMetadata: (
|
|
25
|
+
metadata: Record<string, unknown>,
|
|
26
|
+
) => Promise<void> | void;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
function warn(logger: BasicLogger | undefined, message: string): void {
|
|
30
|
+
logger?.log(message, { severity: "warn" });
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function readCheckpointMetadata(
|
|
34
|
+
metadata: Record<string, unknown> | undefined,
|
|
35
|
+
): CheckpointMetadata | undefined {
|
|
36
|
+
const candidate = metadata?.checkpoint;
|
|
37
|
+
if (!candidate || typeof candidate !== "object" || Array.isArray(candidate)) {
|
|
38
|
+
return undefined;
|
|
39
|
+
}
|
|
40
|
+
const record = candidate as Partial<CheckpointMetadata>;
|
|
41
|
+
if (!record.latest || !Array.isArray(record.history)) {
|
|
42
|
+
return undefined;
|
|
43
|
+
}
|
|
44
|
+
const latest = record.latest as Partial<CheckpointEntry>;
|
|
45
|
+
const history = record.history.filter(
|
|
46
|
+
(entry): entry is CheckpointEntry =>
|
|
47
|
+
!!entry &&
|
|
48
|
+
typeof entry === "object" &&
|
|
49
|
+
typeof (entry as Partial<CheckpointEntry>).ref === "string" &&
|
|
50
|
+
typeof (entry as Partial<CheckpointEntry>).createdAt === "number" &&
|
|
51
|
+
typeof (entry as Partial<CheckpointEntry>).runCount === "number",
|
|
52
|
+
);
|
|
53
|
+
if (
|
|
54
|
+
typeof latest.ref !== "string" ||
|
|
55
|
+
typeof latest.createdAt !== "number" ||
|
|
56
|
+
typeof latest.runCount !== "number"
|
|
57
|
+
) {
|
|
58
|
+
return undefined;
|
|
59
|
+
}
|
|
60
|
+
return {
|
|
61
|
+
latest: latest as CheckpointEntry,
|
|
62
|
+
history,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
async function runGit(
|
|
67
|
+
cwd: string,
|
|
68
|
+
args: string[],
|
|
69
|
+
): Promise<{ stdout: string; stderr: string }> {
|
|
70
|
+
const result = await execFile("git", ["-C", cwd, ...args], {
|
|
71
|
+
windowsHide: true,
|
|
72
|
+
});
|
|
73
|
+
return {
|
|
74
|
+
stdout: result.stdout.trim(),
|
|
75
|
+
stderr: result.stderr.trim(),
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export function createCheckpointHooks(
|
|
80
|
+
options: CreateCheckpointHooksOptions,
|
|
81
|
+
): AgentHooks {
|
|
82
|
+
let runCount = 0;
|
|
83
|
+
let repoSupported: boolean | undefined;
|
|
84
|
+
|
|
85
|
+
const ensureGitRepository = async (): Promise<boolean> => {
|
|
86
|
+
if (repoSupported !== undefined) {
|
|
87
|
+
return repoSupported;
|
|
88
|
+
}
|
|
89
|
+
try {
|
|
90
|
+
const result = await runGit(options.cwd, [
|
|
91
|
+
"rev-parse",
|
|
92
|
+
"--is-inside-work-tree",
|
|
93
|
+
]);
|
|
94
|
+
repoSupported = result.stdout === "true";
|
|
95
|
+
} catch {
|
|
96
|
+
repoSupported = false;
|
|
97
|
+
}
|
|
98
|
+
return repoSupported;
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
const createCheckpoint = async (): Promise<CheckpointEntry | undefined> => {
|
|
102
|
+
if (!(await ensureGitRepository())) {
|
|
103
|
+
return undefined;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const message = `cline checkpoint session=${options.sessionId} run=${runCount}`;
|
|
107
|
+
let ref = "";
|
|
108
|
+
try {
|
|
109
|
+
const result = await runGit(options.cwd, ["stash", "create", message]);
|
|
110
|
+
ref = result.stdout.trim();
|
|
111
|
+
} catch (error) {
|
|
112
|
+
warn(
|
|
113
|
+
options.logger,
|
|
114
|
+
`Checkpoint snapshot failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
115
|
+
);
|
|
116
|
+
return undefined;
|
|
117
|
+
}
|
|
118
|
+
if (!ref) {
|
|
119
|
+
try {
|
|
120
|
+
const result = await runGit(options.cwd, ["rev-parse", "HEAD"]);
|
|
121
|
+
ref = result.stdout.trim();
|
|
122
|
+
} catch (error) {
|
|
123
|
+
warn(
|
|
124
|
+
options.logger,
|
|
125
|
+
`Checkpoint HEAD fallback failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
126
|
+
);
|
|
127
|
+
return undefined;
|
|
128
|
+
}
|
|
129
|
+
if (!ref) {
|
|
130
|
+
return undefined;
|
|
131
|
+
}
|
|
132
|
+
return {
|
|
133
|
+
ref,
|
|
134
|
+
createdAt: Date.now(),
|
|
135
|
+
runCount,
|
|
136
|
+
kind: "commit",
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
try {
|
|
141
|
+
await runGit(options.cwd, ["stash", "store", "-m", message, ref]);
|
|
142
|
+
} catch (error) {
|
|
143
|
+
warn(
|
|
144
|
+
options.logger,
|
|
145
|
+
`Checkpoint store failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
146
|
+
);
|
|
147
|
+
return undefined;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
return {
|
|
151
|
+
ref,
|
|
152
|
+
createdAt: Date.now(),
|
|
153
|
+
runCount,
|
|
154
|
+
kind: "stash",
|
|
155
|
+
};
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
return {
|
|
159
|
+
onRunStart: async ({ parentAgentId }) => {
|
|
160
|
+
if (parentAgentId === null) {
|
|
161
|
+
runCount += 1;
|
|
162
|
+
}
|
|
163
|
+
return undefined;
|
|
164
|
+
},
|
|
165
|
+
onBeforeAgentStart: async ({ parentAgentId, iteration }) => {
|
|
166
|
+
if (parentAgentId !== null || iteration !== 1 || runCount < 1) {
|
|
167
|
+
return undefined;
|
|
168
|
+
}
|
|
169
|
+
const entry = await createCheckpoint();
|
|
170
|
+
if (!entry) {
|
|
171
|
+
return undefined;
|
|
172
|
+
}
|
|
173
|
+
const metadata = await options.readSessionMetadata();
|
|
174
|
+
const existing = readCheckpointMetadata(metadata);
|
|
175
|
+
const history = [...(existing?.history ?? []), entry];
|
|
176
|
+
await options.writeSessionMetadata({
|
|
177
|
+
...(metadata ?? {}),
|
|
178
|
+
checkpoint: {
|
|
179
|
+
latest: entry,
|
|
180
|
+
history,
|
|
181
|
+
} satisfies CheckpointMetadata,
|
|
182
|
+
});
|
|
183
|
+
return undefined;
|
|
184
|
+
},
|
|
185
|
+
};
|
|
186
|
+
}
|
|
@@ -2,7 +2,7 @@ import { mkdir, mkdtemp, readFile, rm, writeFile } from "node:fs/promises";
|
|
|
2
2
|
import { tmpdir } from "node:os";
|
|
3
3
|
import { join } from "node:path";
|
|
4
4
|
import { describe, expect, it } from "vitest";
|
|
5
|
-
import { createHookConfigFileHooks } from "./hook-file-hooks";
|
|
5
|
+
import { createHookConfigFileHooks, mergeAgentHooks } from "./hook-file-hooks";
|
|
6
6
|
|
|
7
7
|
async function waitForFile(
|
|
8
8
|
filePath: string,
|
|
@@ -234,4 +234,43 @@ describe("createHookConfigFileHooks", () => {
|
|
|
234
234
|
await rm(workspace, { recursive: true, force: true });
|
|
235
235
|
}
|
|
236
236
|
});
|
|
237
|
+
|
|
238
|
+
it("merges before-agent-start controls across hook layers", async () => {
|
|
239
|
+
const hooks = mergeAgentHooks([
|
|
240
|
+
{
|
|
241
|
+
onBeforeAgentStart: async () => ({
|
|
242
|
+
systemPrompt: "system-a",
|
|
243
|
+
}),
|
|
244
|
+
},
|
|
245
|
+
{
|
|
246
|
+
onBeforeAgentStart: async () => ({
|
|
247
|
+
appendMessages: [
|
|
248
|
+
{
|
|
249
|
+
role: "user",
|
|
250
|
+
content: [{ type: "text", text: "ctx-a" }],
|
|
251
|
+
},
|
|
252
|
+
],
|
|
253
|
+
}),
|
|
254
|
+
},
|
|
255
|
+
]);
|
|
256
|
+
|
|
257
|
+
const control = await hooks?.onBeforeAgentStart?.({
|
|
258
|
+
agentId: "agent_1",
|
|
259
|
+
conversationId: "conv_1",
|
|
260
|
+
parentAgentId: null,
|
|
261
|
+
iteration: 1,
|
|
262
|
+
systemPrompt: "base",
|
|
263
|
+
messages: [],
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
expect(control).toMatchObject({
|
|
267
|
+
systemPrompt: "system-a",
|
|
268
|
+
appendMessages: [
|
|
269
|
+
{
|
|
270
|
+
role: "user",
|
|
271
|
+
content: [{ type: "text", text: "ctx-a" }],
|
|
272
|
+
},
|
|
273
|
+
],
|
|
274
|
+
});
|
|
275
|
+
});
|
|
237
276
|
});
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import { spawn } from "node:child_process";
|
|
2
2
|
import { appendFileSync, readFileSync } from "node:fs";
|
|
3
|
-
import type {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
3
|
+
import type { AgentHooks } from "@clinebot/agents";
|
|
4
|
+
import {
|
|
5
|
+
augmentNodeCommandForDebug,
|
|
6
|
+
type BasicLogger,
|
|
7
|
+
type HookSessionContext,
|
|
8
|
+
withResolvedClineBuildEnv,
|
|
9
|
+
} from "@clinebot/shared";
|
|
9
10
|
import { ensureParentDir } from "@clinebot/shared/storage";
|
|
10
|
-
import { listHookConfigFiles } from "../
|
|
11
|
+
import { listHookConfigFiles } from "../extensions/config/hooks-config-loader";
|
|
12
|
+
import type { HookEventName, HookEventPayload } from "../hooks";
|
|
11
13
|
|
|
12
14
|
type HookContextBase = {
|
|
13
15
|
agentId: string;
|
|
@@ -64,8 +66,15 @@ function logHookError(
|
|
|
64
66
|
): void {
|
|
65
67
|
const detail = error instanceof Error ? `: ${error.message}` : "";
|
|
66
68
|
const text = `${message}${detail}`;
|
|
67
|
-
if (logger
|
|
68
|
-
|
|
69
|
+
if (logger) {
|
|
70
|
+
try {
|
|
71
|
+
logger.log(text, {
|
|
72
|
+
severity: "warn",
|
|
73
|
+
...(error !== undefined ? { error } : {}),
|
|
74
|
+
});
|
|
75
|
+
} catch {
|
|
76
|
+
// Logging failures must not break hook execution.
|
|
77
|
+
}
|
|
69
78
|
return;
|
|
70
79
|
}
|
|
71
80
|
console.warn(text);
|
|
@@ -264,9 +273,13 @@ async function runHookCommand(
|
|
|
264
273
|
if (options.command.length === 0) {
|
|
265
274
|
throw new Error("runHookCommand requires non-empty command");
|
|
266
275
|
}
|
|
267
|
-
const
|
|
268
|
-
cwd: options.cwd,
|
|
276
|
+
const command = augmentNodeCommandForDebug(options.command, {
|
|
269
277
|
env: options.env,
|
|
278
|
+
debugRole: "hook-worker",
|
|
279
|
+
});
|
|
280
|
+
const child = spawn(command[0], command.slice(1), {
|
|
281
|
+
cwd: options.cwd,
|
|
282
|
+
env: withResolvedClineBuildEnv(options.env),
|
|
270
283
|
stdio: options.detached
|
|
271
284
|
? ["pipe", "ignore", "ignore"]
|
|
272
285
|
: ["pipe", "pipe", "pipe"],
|
|
@@ -386,7 +399,9 @@ function inferHookCommand(path: string): string[] {
|
|
|
386
399
|
lowered.endsWith(".mjs") ||
|
|
387
400
|
lowered.endsWith(".cjs")
|
|
388
401
|
) {
|
|
389
|
-
return ["node", path]
|
|
402
|
+
return augmentNodeCommandForDebug(["node", path], {
|
|
403
|
+
debugRole: "hook-worker",
|
|
404
|
+
});
|
|
390
405
|
}
|
|
391
406
|
if (
|
|
392
407
|
lowered.endsWith(".ts") ||
|
|
@@ -415,9 +430,10 @@ function createHookCommandMap(workspacePath: string): HookCommandMap {
|
|
|
415
430
|
if (!file.hookEventName) {
|
|
416
431
|
continue;
|
|
417
432
|
}
|
|
418
|
-
const
|
|
433
|
+
const hookEventName = file.hookEventName;
|
|
434
|
+
const existing = map[hookEventName] ?? [];
|
|
419
435
|
existing.push(inferHookCommand(file.path));
|
|
420
|
-
map[
|
|
436
|
+
map[hookEventName] = existing;
|
|
421
437
|
}
|
|
422
438
|
return map;
|
|
423
439
|
}
|
|
@@ -436,7 +452,7 @@ async function runBlockingHookCommands(options: {
|
|
|
436
452
|
const result = await runHookCommand(options.payload, {
|
|
437
453
|
command,
|
|
438
454
|
cwd: options.cwd,
|
|
439
|
-
env: process.env,
|
|
455
|
+
env: withResolvedClineBuildEnv(process.env),
|
|
440
456
|
detached: false,
|
|
441
457
|
timeoutMs: options.timeoutMs,
|
|
442
458
|
});
|
|
@@ -474,7 +490,7 @@ function runAsyncHookCommands(options: {
|
|
|
474
490
|
void runHookCommand(options.payload, {
|
|
475
491
|
command,
|
|
476
492
|
cwd: options.cwd,
|
|
477
|
-
env: process.env,
|
|
493
|
+
env: withResolvedClineBuildEnv(process.env),
|
|
478
494
|
detached: true,
|
|
479
495
|
}).catch((error) => {
|
|
480
496
|
logHookError(
|
|
@@ -845,12 +861,15 @@ export function mergeAgentHooks(
|
|
|
845
861
|
}
|
|
846
862
|
|
|
847
863
|
return {
|
|
864
|
+
onSessionStart: mergeHookFunction(activeLayers, "onSessionStart"),
|
|
848
865
|
onRunStart: mergeHookFunction(activeLayers, "onRunStart"),
|
|
849
866
|
onRunEnd: mergeHookFunction(activeLayers, "onRunEnd"),
|
|
850
867
|
onIterationStart: mergeHookFunction(activeLayers, "onIterationStart"),
|
|
851
868
|
onIterationEnd: mergeHookFunction(activeLayers, "onIterationEnd"),
|
|
852
869
|
onTurnStart: mergeHookFunction(activeLayers, "onTurnStart"),
|
|
870
|
+
onBeforeAgentStart: mergeHookFunction(activeLayers, "onBeforeAgentStart"),
|
|
853
871
|
onTurnEnd: mergeHookFunction(activeLayers, "onTurnEnd"),
|
|
872
|
+
onStopError: mergeHookFunction(activeLayers, "onStopError"),
|
|
854
873
|
onToolCallStart: mergeHookFunction(activeLayers, "onToolCallStart"),
|
|
855
874
|
onToolCallEnd: mergeHookFunction(activeLayers, "onToolCallEnd"),
|
|
856
875
|
onSessionShutdown: mergeHookFunction(activeLayers, "onSessionShutdown"),
|
package/src/runtime/index.ts
CHANGED
|
@@ -1,8 +1,3 @@
|
|
|
1
|
-
export {
|
|
2
|
-
type AvailableRuntimeCommand,
|
|
3
|
-
listAvailableRuntimeCommandsFromWatcher,
|
|
4
|
-
resolveRuntimeSlashCommandFromWatcher,
|
|
5
|
-
} from "./commands";
|
|
6
1
|
export {
|
|
7
2
|
formatRulesForSystemPrompt,
|
|
8
3
|
isRuleEnabled,
|
|
@@ -10,11 +5,6 @@ export {
|
|
|
10
5
|
loadRulesForSystemPromptFromWatcher,
|
|
11
6
|
} from "./rules";
|
|
12
7
|
export { createTeamName, DefaultRuntimeBuilder } from "./runtime-builder";
|
|
13
|
-
export {
|
|
14
|
-
type SandboxCallOptions,
|
|
15
|
-
SubprocessSandbox,
|
|
16
|
-
type SubprocessSandboxOptions,
|
|
17
|
-
} from "./sandbox/subprocess-sandbox";
|
|
18
8
|
export type {
|
|
19
9
|
BuiltRuntime,
|
|
20
10
|
RuntimeBuilder,
|
|
@@ -22,16 +12,11 @@ export type {
|
|
|
22
12
|
SessionRuntime,
|
|
23
13
|
} from "./session-runtime";
|
|
24
14
|
export {
|
|
25
|
-
type
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
} from "./
|
|
15
|
+
type SandboxCallOptions,
|
|
16
|
+
SubprocessSandbox,
|
|
17
|
+
type SubprocessSandboxOptions,
|
|
18
|
+
} from "./subprocess-sandbox";
|
|
29
19
|
export {
|
|
30
20
|
type DesktopToolApprovalOptions,
|
|
31
21
|
requestDesktopToolApproval,
|
|
32
22
|
} from "./tool-approval";
|
|
33
|
-
export {
|
|
34
|
-
type AvailableWorkflow,
|
|
35
|
-
listAvailableWorkflowsFromWatcher,
|
|
36
|
-
resolveWorkflowSlashCommandFromWatcher,
|
|
37
|
-
} from "./workflows";
|
package/src/runtime/rules.ts
CHANGED
|
@@ -35,7 +35,7 @@ class MockAgentTeamsRuntime {
|
|
|
35
35
|
shutdownTeammate = vi.fn();
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
vi.mock("
|
|
38
|
+
vi.mock("../team", () => ({
|
|
39
39
|
AgentTeamsRuntime: MockAgentTeamsRuntime,
|
|
40
40
|
bootstrapAgentTeams: bootstrapAgentTeamsMock,
|
|
41
41
|
createDelegatedAgentConfigProvider: (config: Record<string, unknown>) => {
|
|
@@ -109,7 +109,7 @@ describe("DefaultRuntimeBuilder team persistence boundary", () => {
|
|
|
109
109
|
const { DefaultRuntimeBuilder } = await import("./runtime-builder");
|
|
110
110
|
const onTeamRestored = vi.fn();
|
|
111
111
|
|
|
112
|
-
new DefaultRuntimeBuilder().build({
|
|
112
|
+
await new DefaultRuntimeBuilder().build({
|
|
113
113
|
config: {
|
|
114
114
|
providerId: "anthropic",
|
|
115
115
|
modelId: "claude-sonnet-4-6",
|
|
@@ -194,7 +194,7 @@ describe("DefaultRuntimeBuilder team persistence boundary", () => {
|
|
|
194
194
|
const { DefaultRuntimeBuilder } = await import("./runtime-builder");
|
|
195
195
|
bootstrapAgentTeamsMock.mockClear();
|
|
196
196
|
|
|
197
|
-
new DefaultRuntimeBuilder().build({
|
|
197
|
+
await new DefaultRuntimeBuilder().build({
|
|
198
198
|
config: {
|
|
199
199
|
providerId: "cline",
|
|
200
200
|
modelId: "anthropic/claude-sonnet-4.6",
|
|
@@ -236,9 +236,6 @@ describe("DefaultRuntimeBuilder team persistence boundary", () => {
|
|
|
236
236
|
expect.objectContaining({
|
|
237
237
|
providerId: "cline",
|
|
238
238
|
cwd: "/repo/demo",
|
|
239
|
-
clineWorkspaceMetadata: expect.stringContaining(
|
|
240
|
-
"# Workspace Configuration",
|
|
241
|
-
),
|
|
242
239
|
}),
|
|
243
240
|
);
|
|
244
241
|
});
|