@clinebot/core 0.0.28 → 0.0.30
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 +9 -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 +168 -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 +162 -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/OpenTelemetryAdapter.ts +1 -1
- package/src/telemetry/OpenTelemetryProvider.test.ts +216 -3
- package/src/telemetry/OpenTelemetryProvider.ts +110 -20
- 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
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import { execFileSync } from "node:child_process";
|
|
1
2
|
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
2
3
|
import { tmpdir } from "node:os";
|
|
3
4
|
import { join } from "node:path";
|
|
4
|
-
import type { AgentResult } from "@clinebot/
|
|
5
|
+
import type { AgentResult } from "@clinebot/shared";
|
|
5
6
|
import { setClineDir, setHomeDir } from "@clinebot/shared/storage";
|
|
6
7
|
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
7
8
|
import { TelemetryService } from "../telemetry/TelemetryService";
|
|
@@ -126,10 +127,30 @@ function createConfig(
|
|
|
126
127
|
};
|
|
127
128
|
}
|
|
128
129
|
|
|
130
|
+
function createGitRepo(cwd: string): void {
|
|
131
|
+
execFileSync("git", ["-C", cwd, "init"], { stdio: "pipe" });
|
|
132
|
+
execFileSync("git", ["-C", cwd, "config", "user.name", "Codex Test"], {
|
|
133
|
+
stdio: "pipe",
|
|
134
|
+
});
|
|
135
|
+
execFileSync(
|
|
136
|
+
"git",
|
|
137
|
+
["-C", cwd, "config", "user.email", "codex@example.com"],
|
|
138
|
+
{
|
|
139
|
+
stdio: "pipe",
|
|
140
|
+
},
|
|
141
|
+
);
|
|
142
|
+
writeFileSync(join(cwd, "note.txt"), "base\n", "utf8");
|
|
143
|
+
execFileSync("git", ["-C", cwd, "add", "note.txt"], { stdio: "pipe" });
|
|
144
|
+
execFileSync("git", ["-C", cwd, "commit", "-m", "initial"], {
|
|
145
|
+
stdio: "pipe",
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
|
|
129
149
|
describe("DefaultSessionManager", () => {
|
|
130
150
|
const envSnapshot = {
|
|
131
151
|
HOME: process.env.HOME,
|
|
132
152
|
CLINE_DIR: process.env.CLINE_DIR,
|
|
153
|
+
CLINE_CHECKPOINT: process.env.CLINE_CHECKPOINT,
|
|
133
154
|
};
|
|
134
155
|
let isolatedHomeDir = "";
|
|
135
156
|
|
|
@@ -137,6 +158,7 @@ describe("DefaultSessionManager", () => {
|
|
|
137
158
|
isolatedHomeDir = mkdtempSync(join(tmpdir(), "core-session-home-"));
|
|
138
159
|
process.env.HOME = isolatedHomeDir;
|
|
139
160
|
process.env.CLINE_DIR = join(isolatedHomeDir, ".cline");
|
|
161
|
+
delete process.env.CLINE_CHECKPOINT;
|
|
140
162
|
setHomeDir(isolatedHomeDir);
|
|
141
163
|
setClineDir(process.env.CLINE_DIR);
|
|
142
164
|
});
|
|
@@ -144,6 +166,7 @@ describe("DefaultSessionManager", () => {
|
|
|
144
166
|
afterEach(() => {
|
|
145
167
|
process.env.HOME = envSnapshot.HOME;
|
|
146
168
|
process.env.CLINE_DIR = envSnapshot.CLINE_DIR;
|
|
169
|
+
process.env.CLINE_CHECKPOINT = envSnapshot.CLINE_CHECKPOINT;
|
|
147
170
|
setHomeDir(envSnapshot.HOME ?? "~");
|
|
148
171
|
setClineDir(envSnapshot.CLINE_DIR ?? join("~", ".cline"));
|
|
149
172
|
rmSync(isolatedHomeDir, { recursive: true, force: true });
|
|
@@ -314,6 +337,102 @@ describe("DefaultSessionManager", () => {
|
|
|
314
337
|
expect(started.manifest.source).toBe("kanban");
|
|
315
338
|
});
|
|
316
339
|
|
|
340
|
+
it("reuses the persisted team name when resuming a session", async () => {
|
|
341
|
+
const sessionId = "sess-team-resume";
|
|
342
|
+
const manifest = createManifest(sessionId);
|
|
343
|
+
const sessionService = {
|
|
344
|
+
ensureSessionsDir: vi.fn().mockReturnValue("/tmp/sessions"),
|
|
345
|
+
createRootSessionWithArtifacts: vi.fn().mockResolvedValue({
|
|
346
|
+
manifestPath: "/tmp/manifest.json",
|
|
347
|
+
transcriptPath: "/tmp/transcript.log",
|
|
348
|
+
hookPath: "/tmp/hook.log",
|
|
349
|
+
messagesPath: "/tmp/messages.json",
|
|
350
|
+
manifest,
|
|
351
|
+
}),
|
|
352
|
+
persistSessionMessages: vi.fn(),
|
|
353
|
+
updateSessionStatus: vi.fn().mockResolvedValue({
|
|
354
|
+
updated: true,
|
|
355
|
+
endedAt: "2026-01-01T00:00:05.000Z",
|
|
356
|
+
}),
|
|
357
|
+
writeSessionManifest: vi.fn(),
|
|
358
|
+
listSessions: vi.fn().mockResolvedValue([
|
|
359
|
+
{
|
|
360
|
+
sessionId,
|
|
361
|
+
source: SessionSource.CLI,
|
|
362
|
+
pid: process.pid,
|
|
363
|
+
startedAt: "2026-01-01T00:00:00.000Z",
|
|
364
|
+
endedAt: null,
|
|
365
|
+
exitCode: null,
|
|
366
|
+
status: "running",
|
|
367
|
+
statusLock: 0,
|
|
368
|
+
interactive: true,
|
|
369
|
+
provider: "mock-provider",
|
|
370
|
+
model: "mock-model",
|
|
371
|
+
cwd: "/tmp/project",
|
|
372
|
+
workspaceRoot: "/tmp/project",
|
|
373
|
+
teamName: "persisted-team",
|
|
374
|
+
enableTools: true,
|
|
375
|
+
enableSpawn: true,
|
|
376
|
+
enableTeams: true,
|
|
377
|
+
parentSessionId: null,
|
|
378
|
+
parentAgentId: null,
|
|
379
|
+
agentId: null,
|
|
380
|
+
conversationId: null,
|
|
381
|
+
isSubagent: false,
|
|
382
|
+
prompt: null,
|
|
383
|
+
metadata: null,
|
|
384
|
+
transcriptPath: "/tmp/transcript.log",
|
|
385
|
+
hookPath: "/tmp/hook.log",
|
|
386
|
+
messagesPath: "/tmp/messages.json",
|
|
387
|
+
updatedAt: "2026-01-01T00:00:00.000Z",
|
|
388
|
+
},
|
|
389
|
+
]),
|
|
390
|
+
deleteSession: vi.fn().mockResolvedValue({ deleted: true }),
|
|
391
|
+
};
|
|
392
|
+
const runtimeBuilder = {
|
|
393
|
+
build: vi.fn().mockReturnValue({
|
|
394
|
+
tools: [],
|
|
395
|
+
teamRuntime: {
|
|
396
|
+
getTeamId: vi.fn().mockReturnValue("team_persisted-team"),
|
|
397
|
+
getTeamName: vi.fn().mockReturnValue("persisted-team"),
|
|
398
|
+
},
|
|
399
|
+
teamRestoredFromPersistence: true,
|
|
400
|
+
shutdown: vi.fn(),
|
|
401
|
+
}),
|
|
402
|
+
};
|
|
403
|
+
const agent = {
|
|
404
|
+
run: vi.fn().mockResolvedValue(createResult()),
|
|
405
|
+
continue: vi.fn().mockResolvedValue(createResult()),
|
|
406
|
+
getMessages: vi.fn().mockReturnValue([]),
|
|
407
|
+
getAgentId: vi.fn().mockReturnValue("agent-root-1"),
|
|
408
|
+
getConversationId: vi.fn().mockReturnValue("conv-root-1"),
|
|
409
|
+
abort: vi.fn(),
|
|
410
|
+
shutdown: vi.fn().mockResolvedValue(undefined),
|
|
411
|
+
};
|
|
412
|
+
const manager = new DefaultSessionManager({
|
|
413
|
+
distinctId,
|
|
414
|
+
sessionService: sessionService as never,
|
|
415
|
+
runtimeBuilder: runtimeBuilder as never,
|
|
416
|
+
createAgent: () => agent as never,
|
|
417
|
+
});
|
|
418
|
+
|
|
419
|
+
await manager.start({
|
|
420
|
+
config: createConfig({ sessionId, teamName: undefined }),
|
|
421
|
+
});
|
|
422
|
+
|
|
423
|
+
expect(runtimeBuilder.build).toHaveBeenCalledWith(
|
|
424
|
+
expect.objectContaining({
|
|
425
|
+
config: expect.objectContaining({
|
|
426
|
+
sessionId,
|
|
427
|
+
teamName: "persisted-team",
|
|
428
|
+
}),
|
|
429
|
+
}),
|
|
430
|
+
);
|
|
431
|
+
expect(
|
|
432
|
+
sessionService.createRootSessionWithArtifacts,
|
|
433
|
+
).not.toHaveBeenCalled();
|
|
434
|
+
});
|
|
435
|
+
|
|
317
436
|
it("runs a non-interactive prompt and persists messages/status", async () => {
|
|
318
437
|
const sessionId = "sess-1";
|
|
319
438
|
const manifest = createManifest(sessionId);
|
|
@@ -389,6 +508,335 @@ describe("DefaultSessionManager", () => {
|
|
|
389
508
|
expect(shutdown).toHaveBeenCalledTimes(1);
|
|
390
509
|
});
|
|
391
510
|
|
|
511
|
+
it("preserves manifest metadata updates and persists total cost", async () => {
|
|
512
|
+
const sessionId = "sess-history-meta";
|
|
513
|
+
let storedManifest: SessionManifest = {
|
|
514
|
+
...createManifest(sessionId),
|
|
515
|
+
metadata: {
|
|
516
|
+
checkpoint: {
|
|
517
|
+
latest: {
|
|
518
|
+
ref: "abc123",
|
|
519
|
+
createdAt: 1,
|
|
520
|
+
runCount: 1,
|
|
521
|
+
},
|
|
522
|
+
history: [
|
|
523
|
+
{
|
|
524
|
+
ref: "abc123",
|
|
525
|
+
createdAt: 1,
|
|
526
|
+
runCount: 1,
|
|
527
|
+
},
|
|
528
|
+
],
|
|
529
|
+
},
|
|
530
|
+
},
|
|
531
|
+
};
|
|
532
|
+
const createRootSessionWithArtifacts = vi.fn().mockResolvedValue({
|
|
533
|
+
manifestPath: "/tmp/manifest-history-meta.json",
|
|
534
|
+
transcriptPath: "/tmp/transcript-history-meta.log",
|
|
535
|
+
hookPath: "/tmp/hook-history-meta.log",
|
|
536
|
+
messagesPath: "/tmp/messages-history-meta.json",
|
|
537
|
+
manifest: { ...storedManifest },
|
|
538
|
+
});
|
|
539
|
+
const persistSessionMessages = vi.fn();
|
|
540
|
+
const updateSession = vi.fn().mockImplementation(async (input) => {
|
|
541
|
+
storedManifest = {
|
|
542
|
+
...storedManifest,
|
|
543
|
+
metadata: input.metadata,
|
|
544
|
+
};
|
|
545
|
+
return { updated: true };
|
|
546
|
+
});
|
|
547
|
+
const updateSessionStatus = vi.fn().mockResolvedValue({
|
|
548
|
+
updated: true,
|
|
549
|
+
endedAt: "2026-01-01T00:00:05.000Z",
|
|
550
|
+
});
|
|
551
|
+
const readSessionManifest = vi
|
|
552
|
+
.fn()
|
|
553
|
+
.mockImplementation(() => storedManifest);
|
|
554
|
+
const writeSessionManifest = vi
|
|
555
|
+
.fn()
|
|
556
|
+
.mockImplementation((_path, manifest) => {
|
|
557
|
+
storedManifest = manifest;
|
|
558
|
+
});
|
|
559
|
+
const sessionService = {
|
|
560
|
+
ensureSessionsDir: vi.fn().mockReturnValue("/tmp/sessions"),
|
|
561
|
+
createRootSessionWithArtifacts,
|
|
562
|
+
persistSessionMessages,
|
|
563
|
+
updateSession,
|
|
564
|
+
updateSessionStatus,
|
|
565
|
+
readSessionManifest,
|
|
566
|
+
writeSessionManifest,
|
|
567
|
+
listSessions: vi.fn().mockResolvedValue([]),
|
|
568
|
+
deleteSession: vi.fn().mockResolvedValue({ deleted: true }),
|
|
569
|
+
};
|
|
570
|
+
|
|
571
|
+
const runtimeBuilder = {
|
|
572
|
+
build: vi.fn().mockReturnValue({
|
|
573
|
+
tools: [],
|
|
574
|
+
shutdown: vi.fn(),
|
|
575
|
+
}),
|
|
576
|
+
};
|
|
577
|
+
const agent = {
|
|
578
|
+
run: vi.fn().mockResolvedValue(
|
|
579
|
+
createResult({
|
|
580
|
+
usage: {
|
|
581
|
+
inputTokens: 3,
|
|
582
|
+
outputTokens: 4,
|
|
583
|
+
totalCost: 0.42,
|
|
584
|
+
},
|
|
585
|
+
messages: [
|
|
586
|
+
{ role: "user", content: [{ type: "text", text: "hello" }] },
|
|
587
|
+
],
|
|
588
|
+
}),
|
|
589
|
+
),
|
|
590
|
+
continue: vi.fn(),
|
|
591
|
+
abort: vi.fn(),
|
|
592
|
+
shutdown: vi.fn().mockResolvedValue(undefined),
|
|
593
|
+
getMessages: vi.fn().mockReturnValue([]),
|
|
594
|
+
messages: [],
|
|
595
|
+
};
|
|
596
|
+
|
|
597
|
+
const manager = new DefaultSessionManager({
|
|
598
|
+
distinctId,
|
|
599
|
+
sessionService: sessionService as never,
|
|
600
|
+
runtimeBuilder,
|
|
601
|
+
createAgent: () => agent as never,
|
|
602
|
+
});
|
|
603
|
+
|
|
604
|
+
await manager.start({
|
|
605
|
+
config: createConfig({ sessionId }),
|
|
606
|
+
prompt: "hello",
|
|
607
|
+
interactive: false,
|
|
608
|
+
});
|
|
609
|
+
|
|
610
|
+
expect(updateSession).toHaveBeenCalledWith({
|
|
611
|
+
sessionId,
|
|
612
|
+
metadata: {
|
|
613
|
+
checkpoint: {
|
|
614
|
+
latest: {
|
|
615
|
+
ref: "abc123",
|
|
616
|
+
createdAt: 1,
|
|
617
|
+
runCount: 1,
|
|
618
|
+
},
|
|
619
|
+
history: [
|
|
620
|
+
{
|
|
621
|
+
ref: "abc123",
|
|
622
|
+
createdAt: 1,
|
|
623
|
+
runCount: 1,
|
|
624
|
+
},
|
|
625
|
+
],
|
|
626
|
+
},
|
|
627
|
+
totalCost: 0.42,
|
|
628
|
+
},
|
|
629
|
+
});
|
|
630
|
+
expect(writeSessionManifest).toHaveBeenCalledWith(
|
|
631
|
+
"/tmp/manifest-history-meta.json",
|
|
632
|
+
expect.objectContaining({
|
|
633
|
+
metadata: {
|
|
634
|
+
checkpoint: {
|
|
635
|
+
latest: {
|
|
636
|
+
ref: "abc123",
|
|
637
|
+
createdAt: 1,
|
|
638
|
+
runCount: 1,
|
|
639
|
+
},
|
|
640
|
+
history: [
|
|
641
|
+
{
|
|
642
|
+
ref: "abc123",
|
|
643
|
+
createdAt: 1,
|
|
644
|
+
runCount: 1,
|
|
645
|
+
},
|
|
646
|
+
],
|
|
647
|
+
},
|
|
648
|
+
totalCost: 0.42,
|
|
649
|
+
},
|
|
650
|
+
status: "completed",
|
|
651
|
+
}),
|
|
652
|
+
);
|
|
653
|
+
});
|
|
654
|
+
|
|
655
|
+
it("does not install checkpoint hooks unless CLINE_CHECKPOINT=true", async () => {
|
|
656
|
+
const sessionId = "sess-checkpoint-default-off";
|
|
657
|
+
const manifest = createManifest(sessionId);
|
|
658
|
+
const updateSession = vi.fn().mockResolvedValue({ updated: true });
|
|
659
|
+
const sessionService = {
|
|
660
|
+
ensureSessionsDir: vi.fn().mockReturnValue("/tmp/sessions"),
|
|
661
|
+
createRootSessionWithArtifacts: vi.fn().mockResolvedValue({
|
|
662
|
+
manifestPath: "/tmp/manifest-checkpoint-default-off.json",
|
|
663
|
+
transcriptPath: "/tmp/transcript-checkpoint-default-off.log",
|
|
664
|
+
hookPath: "/tmp/hook-checkpoint-default-off.log",
|
|
665
|
+
messagesPath: "/tmp/messages-checkpoint-default-off.json",
|
|
666
|
+
manifest,
|
|
667
|
+
}),
|
|
668
|
+
persistSessionMessages: vi.fn(),
|
|
669
|
+
updateSession,
|
|
670
|
+
updateSessionStatus: vi.fn().mockResolvedValue({ updated: true }),
|
|
671
|
+
writeSessionManifest: vi.fn(),
|
|
672
|
+
listSessions: vi.fn().mockResolvedValue([
|
|
673
|
+
{
|
|
674
|
+
sessionId,
|
|
675
|
+
provider: "mock-provider",
|
|
676
|
+
model: "mock-model",
|
|
677
|
+
cwd: "/tmp/project",
|
|
678
|
+
workspaceRoot: "/tmp/project",
|
|
679
|
+
createdAt: "2026-01-01T00:00:00.000Z",
|
|
680
|
+
updatedAt: "2026-01-01T00:00:00.000Z",
|
|
681
|
+
status: "running",
|
|
682
|
+
metadata: undefined,
|
|
683
|
+
},
|
|
684
|
+
]),
|
|
685
|
+
deleteSession: vi.fn().mockResolvedValue({ deleted: true }),
|
|
686
|
+
};
|
|
687
|
+
const runtimeBuilder = {
|
|
688
|
+
build: vi.fn().mockImplementation(() => {
|
|
689
|
+
return {
|
|
690
|
+
tools: [],
|
|
691
|
+
shutdown: vi.fn(),
|
|
692
|
+
};
|
|
693
|
+
}),
|
|
694
|
+
};
|
|
695
|
+
const manager = new DefaultSessionManager({
|
|
696
|
+
distinctId,
|
|
697
|
+
sessionService: sessionService as never,
|
|
698
|
+
runtimeBuilder,
|
|
699
|
+
createAgent: (config) =>
|
|
700
|
+
({
|
|
701
|
+
run: vi.fn().mockImplementation(async () => {
|
|
702
|
+
await config.hooks?.onRunStart?.({
|
|
703
|
+
agentId: "agent_1",
|
|
704
|
+
conversationId: "conv_1",
|
|
705
|
+
parentAgentId: null,
|
|
706
|
+
userMessage: "hello",
|
|
707
|
+
});
|
|
708
|
+
await config.hooks?.onBeforeAgentStart?.({
|
|
709
|
+
agentId: "agent_1",
|
|
710
|
+
conversationId: "conv_1",
|
|
711
|
+
parentAgentId: null,
|
|
712
|
+
iteration: 1,
|
|
713
|
+
systemPrompt: "system",
|
|
714
|
+
messages: [],
|
|
715
|
+
});
|
|
716
|
+
return createResult();
|
|
717
|
+
}),
|
|
718
|
+
continue: vi.fn(),
|
|
719
|
+
abort: vi.fn(),
|
|
720
|
+
shutdown: vi.fn().mockResolvedValue(undefined),
|
|
721
|
+
getMessages: vi.fn().mockReturnValue([]),
|
|
722
|
+
messages: [],
|
|
723
|
+
}) as never,
|
|
724
|
+
});
|
|
725
|
+
|
|
726
|
+
await manager.start({
|
|
727
|
+
config: createConfig({ sessionId }),
|
|
728
|
+
prompt: "hello",
|
|
729
|
+
interactive: false,
|
|
730
|
+
});
|
|
731
|
+
expect(updateSession).toHaveBeenCalledTimes(1);
|
|
732
|
+
expect(updateSession).toHaveBeenLastCalledWith({
|
|
733
|
+
sessionId,
|
|
734
|
+
metadata: {
|
|
735
|
+
totalCost: 0,
|
|
736
|
+
},
|
|
737
|
+
});
|
|
738
|
+
});
|
|
739
|
+
|
|
740
|
+
it("installs checkpoint hooks when CLINE_CHECKPOINT=true", async () => {
|
|
741
|
+
process.env.CLINE_CHECKPOINT = "true";
|
|
742
|
+
|
|
743
|
+
const sessionId = "sess-checkpoint-env-on";
|
|
744
|
+
const repoCwd = mkdtempSync(join(isolatedHomeDir, "checkpoint-repo-"));
|
|
745
|
+
createGitRepo(repoCwd);
|
|
746
|
+
const manifest = createManifest(sessionId);
|
|
747
|
+
const updateSession = vi.fn().mockResolvedValue({ updated: true });
|
|
748
|
+
const sessionService = {
|
|
749
|
+
ensureSessionsDir: vi.fn().mockReturnValue("/tmp/sessions"),
|
|
750
|
+
createRootSessionWithArtifacts: vi.fn().mockResolvedValue({
|
|
751
|
+
manifestPath: "/tmp/manifest-checkpoint-env-on.json",
|
|
752
|
+
transcriptPath: "/tmp/transcript-checkpoint-env-on.log",
|
|
753
|
+
hookPath: "/tmp/hook-checkpoint-env-on.log",
|
|
754
|
+
messagesPath: "/tmp/messages-checkpoint-env-on.json",
|
|
755
|
+
manifest,
|
|
756
|
+
}),
|
|
757
|
+
persistSessionMessages: vi.fn(),
|
|
758
|
+
updateSession,
|
|
759
|
+
updateSessionStatus: vi.fn().mockResolvedValue({ updated: true }),
|
|
760
|
+
writeSessionManifest: vi.fn(),
|
|
761
|
+
listSessions: vi.fn().mockResolvedValue([
|
|
762
|
+
{
|
|
763
|
+
sessionId,
|
|
764
|
+
provider: "mock-provider",
|
|
765
|
+
model: "mock-model",
|
|
766
|
+
cwd: repoCwd,
|
|
767
|
+
workspaceRoot: repoCwd,
|
|
768
|
+
createdAt: "2026-01-01T00:00:00.000Z",
|
|
769
|
+
updatedAt: "2026-01-01T00:00:00.000Z",
|
|
770
|
+
status: "running",
|
|
771
|
+
metadata: undefined,
|
|
772
|
+
},
|
|
773
|
+
]),
|
|
774
|
+
deleteSession: vi.fn().mockResolvedValue({ deleted: true }),
|
|
775
|
+
};
|
|
776
|
+
const runtimeBuilder = {
|
|
777
|
+
build: vi.fn().mockImplementation(() => {
|
|
778
|
+
return {
|
|
779
|
+
tools: [],
|
|
780
|
+
shutdown: vi.fn(),
|
|
781
|
+
};
|
|
782
|
+
}),
|
|
783
|
+
};
|
|
784
|
+
const manager = new DefaultSessionManager({
|
|
785
|
+
distinctId,
|
|
786
|
+
sessionService: sessionService as never,
|
|
787
|
+
runtimeBuilder,
|
|
788
|
+
createAgent: (config) =>
|
|
789
|
+
({
|
|
790
|
+
run: vi.fn().mockImplementation(async () => {
|
|
791
|
+
await config.hooks?.onRunStart?.({
|
|
792
|
+
agentId: "agent_1",
|
|
793
|
+
conversationId: "conv_1",
|
|
794
|
+
parentAgentId: null,
|
|
795
|
+
userMessage: "hello",
|
|
796
|
+
});
|
|
797
|
+
await config.hooks?.onBeforeAgentStart?.({
|
|
798
|
+
agentId: "agent_1",
|
|
799
|
+
conversationId: "conv_1",
|
|
800
|
+
parentAgentId: null,
|
|
801
|
+
iteration: 1,
|
|
802
|
+
systemPrompt: "system",
|
|
803
|
+
messages: [],
|
|
804
|
+
});
|
|
805
|
+
return createResult();
|
|
806
|
+
}),
|
|
807
|
+
continue: vi.fn(),
|
|
808
|
+
abort: vi.fn(),
|
|
809
|
+
shutdown: vi.fn().mockResolvedValue(undefined),
|
|
810
|
+
getMessages: vi.fn().mockReturnValue([]),
|
|
811
|
+
messages: [],
|
|
812
|
+
}) as never,
|
|
813
|
+
});
|
|
814
|
+
|
|
815
|
+
await manager.start({
|
|
816
|
+
config: createConfig({ sessionId, cwd: repoCwd }),
|
|
817
|
+
prompt: "hello",
|
|
818
|
+
interactive: false,
|
|
819
|
+
});
|
|
820
|
+
expect(updateSession).toHaveBeenCalledTimes(2);
|
|
821
|
+
expect(updateSession).toHaveBeenNthCalledWith(1, {
|
|
822
|
+
sessionId,
|
|
823
|
+
metadata: expect.objectContaining({
|
|
824
|
+
checkpoint: expect.objectContaining({
|
|
825
|
+
latest: expect.objectContaining({
|
|
826
|
+
ref: expect.stringMatching(/^[0-9a-f]{40}$/),
|
|
827
|
+
runCount: 1,
|
|
828
|
+
}),
|
|
829
|
+
}),
|
|
830
|
+
}),
|
|
831
|
+
});
|
|
832
|
+
expect(updateSession).toHaveBeenNthCalledWith(2, {
|
|
833
|
+
sessionId,
|
|
834
|
+
metadata: expect.objectContaining({
|
|
835
|
+
totalCost: 0,
|
|
836
|
+
}),
|
|
837
|
+
});
|
|
838
|
+
});
|
|
839
|
+
|
|
392
840
|
it("persists assistant message metadata for usage and model identity", async () => {
|
|
393
841
|
const sessionId = "sess-meta";
|
|
394
842
|
const manifest = createManifest(sessionId);
|
|
@@ -432,6 +880,10 @@ describe("DefaultSessionManager", () => {
|
|
|
432
880
|
model: {
|
|
433
881
|
id: "claude-sonnet-4-6",
|
|
434
882
|
provider: "anthropic",
|
|
883
|
+
info: {
|
|
884
|
+
id: "claude-sonnet-4-6",
|
|
885
|
+
family: "claude-sonnet-4",
|
|
886
|
+
},
|
|
435
887
|
},
|
|
436
888
|
endedAt: new Date("2026-01-01T00:00:02.000Z"),
|
|
437
889
|
messages: [
|
|
@@ -470,11 +922,10 @@ describe("DefaultSessionManager", () => {
|
|
|
470
922
|
expect(Array.isArray(persisted)).toBe(true);
|
|
471
923
|
expect(persisted?.[1]).toMatchObject({
|
|
472
924
|
role: "assistant",
|
|
473
|
-
providerId: "anthropic",
|
|
474
|
-
modelId: "claude-sonnet-4-6",
|
|
475
925
|
modelInfo: {
|
|
476
926
|
id: "claude-sonnet-4-6",
|
|
477
927
|
provider: "anthropic",
|
|
928
|
+
family: "claude-sonnet-4",
|
|
478
929
|
},
|
|
479
930
|
metrics: {
|
|
480
931
|
inputTokens: 33,
|
|
@@ -1458,6 +1909,67 @@ describe("DefaultSessionManager", () => {
|
|
|
1458
1909
|
);
|
|
1459
1910
|
});
|
|
1460
1911
|
|
|
1912
|
+
it("injects a core-owned compaction prepareTurn callback into the agent constructor", async () => {
|
|
1913
|
+
const sessionId = "sess-compaction";
|
|
1914
|
+
const manifest = createManifest(sessionId);
|
|
1915
|
+
const sessionService = {
|
|
1916
|
+
ensureSessionsDir: vi.fn().mockReturnValue("/tmp/sessions"),
|
|
1917
|
+
createRootSessionWithArtifacts: vi.fn().mockResolvedValue({
|
|
1918
|
+
manifestPath: "/tmp/manifest-compaction.json",
|
|
1919
|
+
transcriptPath: "/tmp/transcript-compaction.log",
|
|
1920
|
+
hookPath: "/tmp/hook-compaction.log",
|
|
1921
|
+
messagesPath: "/tmp/messages-compaction.json",
|
|
1922
|
+
manifest,
|
|
1923
|
+
}),
|
|
1924
|
+
persistSessionMessages: vi.fn(),
|
|
1925
|
+
updateSessionStatus: vi.fn().mockResolvedValue({ updated: true }),
|
|
1926
|
+
writeSessionManifest: vi.fn(),
|
|
1927
|
+
listSessions: vi.fn().mockResolvedValue([]),
|
|
1928
|
+
deleteSession: vi.fn().mockResolvedValue({ deleted: true }),
|
|
1929
|
+
};
|
|
1930
|
+
const run = vi.fn().mockResolvedValue(createResult());
|
|
1931
|
+
const createAgent = vi.fn().mockReturnValue({
|
|
1932
|
+
run,
|
|
1933
|
+
continue: vi.fn(),
|
|
1934
|
+
abort: vi.fn(),
|
|
1935
|
+
restore: vi.fn(),
|
|
1936
|
+
shutdown: vi.fn().mockResolvedValue(undefined),
|
|
1937
|
+
getMessages: vi.fn().mockReturnValue([]),
|
|
1938
|
+
messages: [],
|
|
1939
|
+
});
|
|
1940
|
+
const compact = vi.fn();
|
|
1941
|
+
const manager = new DefaultSessionManager({
|
|
1942
|
+
distinctId,
|
|
1943
|
+
sessionService: sessionService as never,
|
|
1944
|
+
runtimeBuilder: {
|
|
1945
|
+
build: vi.fn().mockReturnValue({
|
|
1946
|
+
tools: [],
|
|
1947
|
+
shutdown: vi.fn(),
|
|
1948
|
+
}),
|
|
1949
|
+
},
|
|
1950
|
+
createAgent: createAgent as never,
|
|
1951
|
+
});
|
|
1952
|
+
|
|
1953
|
+
await manager.start({
|
|
1954
|
+
config: createConfig({
|
|
1955
|
+
sessionId,
|
|
1956
|
+
compaction: {
|
|
1957
|
+
enabled: true,
|
|
1958
|
+
strategy: "basic",
|
|
1959
|
+
compact,
|
|
1960
|
+
},
|
|
1961
|
+
}),
|
|
1962
|
+
interactive: true,
|
|
1963
|
+
});
|
|
1964
|
+
await manager.send({ sessionId, prompt: "test" });
|
|
1965
|
+
|
|
1966
|
+
expect(createAgent).toHaveBeenCalledWith(
|
|
1967
|
+
expect.objectContaining({
|
|
1968
|
+
prepareTurn: expect.any(Function),
|
|
1969
|
+
}),
|
|
1970
|
+
);
|
|
1971
|
+
});
|
|
1972
|
+
|
|
1461
1973
|
it("formats prompt in core and merges explicit + mention user files", async () => {
|
|
1462
1974
|
const tempCwd = mkdtempSync(join(tmpdir(), "core-session-format-"));
|
|
1463
1975
|
try {
|
|
@@ -1690,13 +2202,29 @@ describe("DefaultSessionManager", () => {
|
|
|
1690
2202
|
},
|
|
1691
2203
|
});
|
|
1692
2204
|
}, 0);
|
|
1693
|
-
return createResult({
|
|
2205
|
+
return createResult({
|
|
2206
|
+
text: "lead scheduled teammate",
|
|
2207
|
+
messages: [
|
|
2208
|
+
{ role: "user", content: "run teammate work" },
|
|
2209
|
+
{ role: "assistant", content: "lead scheduled teammate" },
|
|
2210
|
+
],
|
|
2211
|
+
});
|
|
1694
2212
|
});
|
|
1695
|
-
const continueFn = vi
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
2213
|
+
const continueFn = vi.fn().mockResolvedValue(
|
|
2214
|
+
createResult({
|
|
2215
|
+
text: "lead processed teammate result",
|
|
2216
|
+
messages: [
|
|
2217
|
+
{ role: "user", content: "run teammate work" },
|
|
2218
|
+
{ role: "assistant", content: "lead scheduled teammate" },
|
|
2219
|
+
{
|
|
2220
|
+
role: "user",
|
|
2221
|
+
content:
|
|
2222
|
+
"System-delivered teammate async run updates:\n- investigator completed",
|
|
2223
|
+
},
|
|
2224
|
+
{ role: "assistant", content: "lead processed teammate result" },
|
|
2225
|
+
],
|
|
2226
|
+
}),
|
|
2227
|
+
);
|
|
1700
2228
|
const manager = new DefaultSessionManager({
|
|
1701
2229
|
distinctId,
|
|
1702
2230
|
sessionService: sessionService as never,
|
|
@@ -1727,6 +2255,21 @@ describe("DefaultSessionManager", () => {
|
|
|
1727
2255
|
expect(continueFn.mock.calls[0]?.[0]).toContain(
|
|
1728
2256
|
"System-delivered teammate async run updates:",
|
|
1729
2257
|
);
|
|
2258
|
+
const finalPersistedMessages = (
|
|
2259
|
+
sessionService.persistSessionMessages as ReturnType<typeof vi.fn>
|
|
2260
|
+
).mock.calls.at(-1)?.[1] as Array<Record<string, unknown>> | undefined;
|
|
2261
|
+
expect(finalPersistedMessages?.at(-1)).toMatchObject({
|
|
2262
|
+
role: "assistant",
|
|
2263
|
+
metrics: {
|
|
2264
|
+
inputTokens: 1,
|
|
2265
|
+
outputTokens: 2,
|
|
2266
|
+
cost: 0,
|
|
2267
|
+
},
|
|
2268
|
+
modelInfo: {
|
|
2269
|
+
id: "mock-model",
|
|
2270
|
+
provider: "mock-provider",
|
|
2271
|
+
},
|
|
2272
|
+
});
|
|
1730
2273
|
expect(sessionService.updateSessionStatus).toHaveBeenCalledWith(
|
|
1731
2274
|
sessionId,
|
|
1732
2275
|
"completed",
|
|
@@ -1814,6 +2357,7 @@ describe("DefaultSessionManager", () => {
|
|
|
1814
2357
|
"providers-investigator",
|
|
1815
2358
|
"failed",
|
|
1816
2359
|
"[error] 401 Unauthorized",
|
|
2360
|
+
undefined,
|
|
1817
2361
|
failedMessages,
|
|
1818
2362
|
);
|
|
1819
2363
|
});
|