@clinebot/core 0.0.34 → 0.0.35
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 +12 -8
- package/dist/ClineCore.d.ts +48 -29
- package/dist/ClineCore.d.ts.map +1 -1
- package/dist/extensions/config/agent-config-loader.d.ts +2 -2
- package/dist/extensions/config/agent-config-loader.d.ts.map +1 -1
- package/dist/extensions/config/agent-config-parser.d.ts +1 -1
- package/dist/extensions/config/agent-config-parser.d.ts.map +1 -1
- package/dist/extensions/config/hooks-config-loader.d.ts +2 -2
- package/dist/extensions/config/hooks-config-loader.d.ts.map +1 -1
- package/dist/extensions/config/index.d.ts +3 -3
- package/dist/extensions/config/index.d.ts.map +1 -1
- package/dist/extensions/config/user-instruction-config-loader.d.ts +2 -2
- package/dist/extensions/config/user-instruction-config-loader.d.ts.map +1 -1
- package/dist/extensions/plugin-sandbox-bootstrap.js +248 -248
- package/dist/extensions/tools/constants.d.ts.map +1 -0
- package/dist/extensions/tools/definitions.d.ts.map +1 -0
- package/dist/extensions/tools/executors/apply-patch-parser.d.ts.map +1 -0
- package/dist/extensions/tools/executors/apply-patch.d.ts.map +1 -0
- package/dist/extensions/tools/executors/bash.d.ts.map +1 -0
- package/dist/extensions/tools/executors/editor.d.ts.map +1 -0
- package/dist/extensions/tools/executors/file-read.d.ts.map +1 -0
- package/dist/extensions/tools/executors/index.d.ts.map +1 -0
- package/dist/extensions/tools/executors/search.d.ts.map +1 -0
- package/dist/extensions/tools/executors/web-fetch.d.ts.map +1 -0
- package/dist/extensions/tools/helpers.d.ts.map +1 -0
- package/dist/extensions/tools/index.d.ts.map +1 -0
- package/dist/{tools → extensions/tools}/model-tool-routing.d.ts +1 -1
- package/dist/extensions/tools/model-tool-routing.d.ts.map +1 -0
- package/dist/{tools → extensions/tools}/presets.d.ts +1 -2
- package/dist/extensions/tools/presets.d.ts.map +1 -0
- package/dist/extensions/tools/schemas.d.ts.map +1 -0
- package/dist/extensions/tools/team/delegated-agent.d.ts.map +1 -0
- package/dist/extensions/tools/team/index.d.ts.map +1 -0
- package/dist/{team → extensions/tools/team}/multi-agent.d.ts +1 -3
- package/dist/extensions/tools/team/multi-agent.d.ts.map +1 -0
- package/dist/extensions/tools/team/projections.d.ts.map +1 -0
- package/dist/extensions/tools/team/runtime.d.ts.map +1 -0
- package/dist/{team → extensions/tools/team}/spawn-agent-tool.d.ts +0 -1
- package/dist/extensions/tools/team/spawn-agent-tool.d.ts.map +1 -0
- package/dist/extensions/tools/team/subagent-prompts.d.ts.map +1 -0
- package/dist/extensions/tools/team/team-tools.d.ts.map +1 -0
- package/dist/{tools → extensions/tools}/types.d.ts +4 -3
- package/dist/extensions/tools/types.d.ts.map +1 -0
- package/dist/{runtime → hooks}/checkpoint-hooks.d.ts +7 -0
- package/dist/hooks/checkpoint-hooks.d.ts.map +1 -0
- package/dist/{runtime → hooks}/hook-file-hooks.d.ts +0 -2
- package/dist/hooks/hook-file-hooks.d.ts.map +1 -0
- package/dist/hooks/subprocess.d.ts +3 -130
- package/dist/hooks/subprocess.d.ts.map +1 -1
- package/dist/index.d.ts +35 -33
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +381 -379
- package/dist/runtime/history.d.ts +4 -0
- package/dist/runtime/history.d.ts.map +1 -0
- package/dist/runtime/host.d.ts +9 -0
- package/dist/runtime/host.d.ts.map +1 -0
- package/dist/{session → runtime}/rpc-runtime-ensure.d.ts +13 -1
- package/dist/{session → runtime}/rpc-runtime-ensure.d.ts.map +1 -1
- package/dist/{session → runtime}/rpc-spawn-lease.d.ts.map +1 -1
- package/dist/runtime/runtime-builder.d.ts.map +1 -1
- package/dist/{session/session-manager.d.ts → runtime/runtime-host.d.ts} +55 -12
- package/dist/runtime/runtime-host.d.ts.map +1 -0
- package/dist/{session → runtime}/runtime-oauth-token-manager.d.ts +1 -1
- package/dist/{session → runtime}/runtime-oauth-token-manager.d.ts.map +1 -1
- package/dist/runtime/session-runtime.d.ts +2 -2
- package/dist/runtime/session-runtime.d.ts.map +1 -1
- package/dist/{session/session-agent-events.d.ts → services/agent-events.d.ts} +4 -4
- package/dist/services/agent-events.d.ts.map +1 -0
- package/dist/services/config.d.ts +3 -0
- package/dist/services/config.d.ts.map +1 -0
- package/dist/services/local-runtime-bootstrap.d.ts +41 -0
- package/dist/services/local-runtime-bootstrap.d.ts.map +1 -0
- package/dist/services/providers/local-provider-registry.d.ts.map +1 -0
- package/dist/services/providers/local-provider-service.d.ts.map +1 -0
- package/dist/{session → services}/session-artifacts.d.ts +0 -4
- package/dist/services/session-artifacts.d.ts.map +1 -0
- package/dist/{session/utils/helpers.d.ts → services/session-data.d.ts} +19 -27
- package/dist/services/session-data.d.ts.map +1 -0
- package/dist/{session → services}/session-telemetry.d.ts +2 -2
- package/dist/services/session-telemetry.d.ts.map +1 -0
- package/dist/{storage → services/storage}/file-team-store.d.ts +2 -2
- package/dist/services/storage/file-team-store.d.ts.map +1 -0
- package/dist/{storage → services/storage}/provider-settings-legacy-migration.d.ts +1 -1
- package/dist/services/storage/provider-settings-legacy-migration.d.ts.map +1 -0
- package/dist/{storage → services/storage}/provider-settings-manager.d.ts +1 -1
- package/dist/services/storage/provider-settings-manager.d.ts.map +1 -0
- package/dist/{storage → services/storage}/sqlite-session-store.d.ts +3 -3
- package/dist/services/storage/sqlite-session-store.d.ts.map +1 -0
- package/dist/{storage → services/storage}/sqlite-team-store.d.ts +2 -2
- package/dist/services/storage/sqlite-team-store.d.ts.map +1 -0
- package/dist/{storage → services/storage}/team-store.d.ts +1 -1
- package/dist/services/storage/team-store.d.ts.map +1 -0
- package/dist/services/telemetry/ITelemetryAdapter.d.ts.map +1 -0
- package/dist/services/telemetry/OpenTelemetryAdapter.d.ts.map +1 -0
- package/dist/services/telemetry/OpenTelemetryProvider.d.ts.map +1 -0
- package/dist/services/telemetry/TelemetryLoggerSink.d.ts.map +1 -0
- package/dist/services/telemetry/TelemetryService.d.ts.map +1 -0
- package/dist/services/telemetry/core-events.d.ts.map +1 -0
- package/dist/services/telemetry/distinct-id.d.ts.map +1 -0
- package/dist/services/telemetry/index.d.ts.map +1 -0
- package/dist/{telemetry → services/telemetry}/index.js +6 -6
- package/dist/{session/utils → services}/usage.d.ts +1 -1
- package/dist/services/usage.d.ts.map +1 -0
- package/dist/services/workspace/file-indexer.d.ts.map +1 -0
- package/dist/services/workspace/index.d.ts.map +1 -0
- package/dist/services/workspace/mention-enricher.d.ts.map +1 -0
- package/dist/services/workspace-manifest.d.ts.map +1 -0
- package/dist/session/file-session-service.d.ts +4 -1
- package/dist/session/file-session-service.d.ts.map +1 -1
- package/dist/session/persistence-service.d.ts +8 -6
- package/dist/session/persistence-service.d.ts.map +1 -1
- package/dist/session/rpc-session-service.d.ts +3 -0
- package/dist/session/rpc-session-service.d.ts.map +1 -1
- package/dist/session/session-service.d.ts +8 -9
- package/dist/session/session-service.d.ts.map +1 -1
- package/dist/session/session-team-coordination.d.ts +4 -4
- package/dist/session/session-team-coordination.d.ts.map +1 -1
- package/dist/session/sqlite-rpc-session-backend.d.ts.map +1 -1
- package/dist/{session/default-session-manager.d.ts → transports/local.d.ts} +24 -14
- package/dist/transports/local.d.ts.map +1 -0
- package/dist/transports/rpc.d.ts +51 -0
- package/dist/transports/rpc.d.ts.map +1 -0
- package/dist/transports/runtime-host-support.d.ts +21 -0
- package/dist/transports/runtime-host-support.d.ts.map +1 -0
- package/dist/types/chat-schema.d.ts.map +1 -0
- package/dist/types/config.d.ts +2 -2
- package/dist/types/config.d.ts.map +1 -1
- package/dist/{session/utils/types.d.ts → types/session.d.ts} +15 -6
- package/dist/types/session.d.ts.map +1 -0
- package/dist/types/sessions.d.ts +19 -0
- package/dist/types/sessions.d.ts.map +1 -1
- package/dist/types/storage.d.ts +1 -3
- package/dist/types/storage.d.ts.map +1 -1
- package/dist/types.d.ts +7 -6
- package/dist/types.d.ts.map +1 -1
- package/package.json +7 -12
- package/src/ClineCore.test.ts +95 -19
- package/src/ClineCore.ts +120 -50
- package/src/auth/cline.ts +1 -1
- package/src/auth/codex.ts +1 -1
- package/src/auth/oca.ts +1 -1
- package/src/extensions/config/agent-config-loader.test.ts +3 -3
- package/src/extensions/config/agent-config-loader.ts +1 -5
- package/src/extensions/config/agent-config-parser.ts +1 -1
- package/src/extensions/config/hooks-config-loader.ts +1 -2
- package/src/extensions/config/index.ts +0 -4
- package/src/extensions/config/user-instruction-config-loader.ts +0 -4
- package/src/extensions/plugin/plugin-config-loader.test.ts +6 -4
- package/src/{tools → extensions/tools}/definitions.ts +1 -1
- package/src/extensions/tools/executors/file-read.test.ts +125 -0
- package/src/{tools → extensions/tools}/executors/file-read.ts +29 -4
- package/src/{tools → extensions/tools}/executors/search.ts +1 -1
- package/src/{tools → extensions/tools}/model-tool-routing.ts +1 -1
- package/src/{tools → extensions/tools}/presets.ts +2 -3
- package/src/extensions/tools/team/multi-agent.lifecycle.test.ts +455 -0
- package/src/{team → extensions/tools/team}/multi-agent.ts +80 -17
- package/src/{team → extensions/tools/team}/spawn-agent-tool.test.ts +0 -6
- package/src/{team → extensions/tools/team}/spawn-agent-tool.ts +1 -7
- package/src/{team → extensions/tools/team}/subagent-prompts.ts +2 -2
- package/src/{team → extensions/tools/team}/team-tools.test.ts +43 -31
- package/src/{team → extensions/tools/team}/team-tools.ts +63 -53
- package/src/{tools → extensions/tools}/types.ts +5 -3
- package/src/{runtime → hooks}/checkpoint-hooks.ts +27 -0
- package/src/{runtime → hooks}/hook-file-hooks.ts +6 -11
- package/src/hooks/subprocess.ts +48 -257
- package/src/index.ts +167 -158
- package/src/runtime/history.test.ts +114 -0
- package/src/runtime/history.ts +237 -0
- package/src/runtime/host.test.ts +230 -0
- package/src/runtime/host.ts +362 -0
- package/src/runtime/rpc-runtime-ensure.test.ts +123 -0
- package/src/{session → runtime}/rpc-runtime-ensure.ts +165 -27
- package/src/{session → runtime}/rpc-spawn-lease.test.ts +33 -1
- package/src/{session → runtime}/rpc-spawn-lease.ts +54 -20
- package/src/runtime/runtime-builder.team-persistence.test.ts +6 -3
- package/src/runtime/runtime-builder.test.ts +3 -4
- package/src/runtime/runtime-builder.ts +13 -21
- package/src/runtime/runtime-host.ts +178 -0
- package/src/{session → runtime}/runtime-oauth-token-manager.ts +1 -1
- package/src/runtime/runtime-parity.test.ts +1 -1
- package/src/runtime/session-runtime.ts +2 -2
- package/src/{session/session-agent-events.ts → services/agent-events.ts} +7 -7
- package/src/services/config.ts +5 -0
- package/src/services/local-runtime-bootstrap.ts +280 -0
- package/src/{providers → services/providers}/local-provider-service.ts +4 -4
- package/src/{session → services}/session-artifacts.ts +7 -19
- package/src/{session/utils/helpers.test.ts → services/session-data.test.ts} +1 -1
- package/src/{session/utils/helpers.ts → services/session-data.ts} +76 -72
- package/src/{session → services}/session-telemetry.ts +7 -9
- package/src/services/storage/artifact-store.ts +1 -0
- package/src/{storage → services/storage}/file-team-store.ts +2 -2
- package/src/{storage → services/storage}/provider-settings-legacy-migration.test.ts +1 -1
- package/src/{storage → services/storage}/provider-settings-legacy-migration.ts +2 -2
- package/src/{storage → services/storage}/provider-settings-manager.ts +2 -2
- package/src/services/storage/session-store.ts +1 -0
- package/src/{storage → services/storage}/sqlite-session-store.ts +7 -12
- package/src/{storage → services/storage}/sqlite-team-store.ts +4 -4
- package/src/{storage → services/storage}/team-store.ts +1 -1
- package/src/{session/utils → services}/usage.ts +1 -1
- package/src/{input → services/workspace}/file-indexer.test.ts +30 -1
- package/src/{input → services/workspace}/file-indexer.ts +26 -2
- package/src/{input → services/workspace}/mention-enricher.test.ts +21 -0
- package/src/{input → services/workspace}/mention-enricher.ts +1 -1
- package/src/session/file-session-service.ts +9 -7
- package/src/session/index.ts +25 -17
- package/src/session/persistence-service.test.ts +86 -27
- package/src/session/persistence-service.ts +104 -103
- package/src/session/rpc-session-service.ts +9 -2
- package/src/session/session-service.team-persistence.test.ts +1 -1
- package/src/session/session-service.ts +32 -19
- package/src/session/session-team-coordination.ts +13 -6
- package/src/session/sqlite-rpc-session-backend.ts +4 -6
- package/src/session/workspace-manager.ts +1 -1
- package/src/{session/default-session-manager.e2e.test.ts → transports/local.e2e.test.ts} +13 -17
- package/src/{session/default-session-manager.test.ts → transports/local.test.ts} +316 -230
- package/src/{session/default-session-manager.ts → transports/local.ts} +137 -169
- package/src/transports/rpc.test.ts +82 -0
- package/src/transports/rpc.ts +665 -0
- package/src/transports/runtime-host-support.ts +86 -0
- package/src/types/config.ts +2 -2
- package/src/{session/utils/types.ts → types/session.ts} +18 -5
- package/src/types/sessions.ts +21 -0
- package/src/types/storage.ts +1 -6
- package/src/types.ts +25 -18
- package/dist/chat/chat-schema.d.ts.map +0 -1
- package/dist/input/file-indexer.d.ts.map +0 -1
- package/dist/input/index.d.ts.map +0 -1
- package/dist/input/mention-enricher.d.ts.map +0 -1
- package/dist/prompt/default-system.d.ts +0 -2
- package/dist/prompt/default-system.d.ts.map +0 -1
- package/dist/providers/local-provider-registry.d.ts.map +0 -1
- package/dist/providers/local-provider-service.d.ts.map +0 -1
- package/dist/runtime/checkpoint-hooks.d.ts.map +0 -1
- package/dist/runtime/hook-file-hooks.d.ts.map +0 -1
- package/dist/session/default-session-manager.d.ts.map +0 -1
- package/dist/session/session-agent-events.d.ts.map +0 -1
- package/dist/session/session-artifacts.d.ts.map +0 -1
- package/dist/session/session-config-builder.d.ts +0 -16
- package/dist/session/session-config-builder.d.ts.map +0 -1
- package/dist/session/session-host.d.ts +0 -15
- package/dist/session/session-host.d.ts.map +0 -1
- package/dist/session/session-manager.d.ts.map +0 -1
- package/dist/session/session-telemetry.d.ts.map +0 -1
- package/dist/session/utils/helpers.d.ts.map +0 -1
- package/dist/session/utils/types.d.ts.map +0 -1
- package/dist/session/utils/usage.d.ts.map +0 -1
- package/dist/session/workspace-manifest.d.ts.map +0 -1
- package/dist/storage/file-team-store.d.ts.map +0 -1
- package/dist/storage/provider-settings-legacy-migration.d.ts.map +0 -1
- package/dist/storage/provider-settings-manager.d.ts.map +0 -1
- package/dist/storage/sqlite-session-store.d.ts.map +0 -1
- package/dist/storage/sqlite-team-store.d.ts.map +0 -1
- package/dist/storage/team-store.d.ts.map +0 -1
- package/dist/team/delegated-agent.d.ts.map +0 -1
- package/dist/team/index.d.ts.map +0 -1
- package/dist/team/multi-agent.d.ts.map +0 -1
- package/dist/team/projections.d.ts.map +0 -1
- package/dist/team/runtime.d.ts.map +0 -1
- package/dist/team/spawn-agent-tool.d.ts.map +0 -1
- package/dist/team/subagent-prompts.d.ts.map +0 -1
- package/dist/team/team-tools.d.ts.map +0 -1
- package/dist/telemetry/ITelemetryAdapter.d.ts.map +0 -1
- package/dist/telemetry/OpenTelemetryAdapter.d.ts.map +0 -1
- package/dist/telemetry/OpenTelemetryProvider.d.ts.map +0 -1
- package/dist/telemetry/TelemetryLoggerSink.d.ts.map +0 -1
- package/dist/telemetry/TelemetryService.d.ts.map +0 -1
- package/dist/telemetry/core-events.d.ts.map +0 -1
- package/dist/telemetry/distinct-id.d.ts.map +0 -1
- package/dist/telemetry/index.d.ts.map +0 -1
- package/dist/tools/constants.d.ts.map +0 -1
- package/dist/tools/definitions.d.ts.map +0 -1
- package/dist/tools/executors/apply-patch-parser.d.ts.map +0 -1
- package/dist/tools/executors/apply-patch.d.ts.map +0 -1
- package/dist/tools/executors/bash.d.ts.map +0 -1
- package/dist/tools/executors/editor.d.ts.map +0 -1
- package/dist/tools/executors/file-read.d.ts.map +0 -1
- package/dist/tools/executors/index.d.ts.map +0 -1
- package/dist/tools/executors/search.d.ts.map +0 -1
- package/dist/tools/executors/web-fetch.d.ts.map +0 -1
- package/dist/tools/helpers.d.ts.map +0 -1
- package/dist/tools/index.d.ts.map +0 -1
- package/dist/tools/model-tool-routing.d.ts.map +0 -1
- package/dist/tools/presets.d.ts.map +0 -1
- package/dist/tools/schemas.d.ts.map +0 -1
- package/dist/tools/types.d.ts.map +0 -1
- package/src/prompt/default-system.ts +0 -21
- package/src/session/session-config-builder.ts +0 -172
- package/src/session/session-host.test.ts +0 -89
- package/src/session/session-host.ts +0 -213
- package/src/session/session-manager.ts +0 -74
- package/src/storage/artifact-store.ts +0 -1
- package/src/storage/session-store.ts +0 -1
- package/src/team/multi-agent.lifecycle.test.ts +0 -201
- package/src/tools/executors/file-read.test.ts +0 -49
- /package/dist/{tools → extensions/tools}/constants.d.ts +0 -0
- /package/dist/{tools → extensions/tools}/definitions.d.ts +0 -0
- /package/dist/{tools → extensions/tools}/executors/apply-patch-parser.d.ts +0 -0
- /package/dist/{tools → extensions/tools}/executors/apply-patch.d.ts +0 -0
- /package/dist/{tools → extensions/tools}/executors/bash.d.ts +0 -0
- /package/dist/{tools → extensions/tools}/executors/editor.d.ts +0 -0
- /package/dist/{tools → extensions/tools}/executors/file-read.d.ts +0 -0
- /package/dist/{tools → extensions/tools}/executors/index.d.ts +0 -0
- /package/dist/{tools → extensions/tools}/executors/search.d.ts +0 -0
- /package/dist/{tools → extensions/tools}/executors/web-fetch.d.ts +0 -0
- /package/dist/{tools → extensions/tools}/helpers.d.ts +0 -0
- /package/dist/{tools → extensions/tools}/index.d.ts +0 -0
- /package/dist/{tools → extensions/tools}/schemas.d.ts +0 -0
- /package/dist/{team → extensions/tools/team}/delegated-agent.d.ts +0 -0
- /package/dist/{team → extensions/tools/team}/index.d.ts +0 -0
- /package/dist/{team → extensions/tools/team}/projections.d.ts +0 -0
- /package/dist/{team → extensions/tools/team}/runtime.d.ts +0 -0
- /package/dist/{team → extensions/tools/team}/subagent-prompts.d.ts +0 -0
- /package/dist/{team → extensions/tools/team}/team-tools.d.ts +0 -0
- /package/dist/{session → runtime}/rpc-spawn-lease.d.ts +0 -0
- /package/dist/{providers → services/providers}/local-provider-registry.d.ts +0 -0
- /package/dist/{providers → services/providers}/local-provider-service.d.ts +0 -0
- /package/dist/{telemetry → services/telemetry}/ITelemetryAdapter.d.ts +0 -0
- /package/dist/{telemetry → services/telemetry}/OpenTelemetryAdapter.d.ts +0 -0
- /package/dist/{telemetry → services/telemetry}/OpenTelemetryProvider.d.ts +0 -0
- /package/dist/{telemetry → services/telemetry}/TelemetryLoggerSink.d.ts +0 -0
- /package/dist/{telemetry → services/telemetry}/TelemetryService.d.ts +0 -0
- /package/dist/{telemetry → services/telemetry}/core-events.d.ts +0 -0
- /package/dist/{telemetry → services/telemetry}/distinct-id.d.ts +0 -0
- /package/dist/{telemetry → services/telemetry}/index.d.ts +0 -0
- /package/dist/{input → services/workspace}/file-indexer.d.ts +0 -0
- /package/dist/{input → services/workspace}/index.d.ts +0 -0
- /package/dist/{input → services/workspace}/mention-enricher.d.ts +0 -0
- /package/dist/{session → services}/workspace-manifest.d.ts +0 -0
- /package/dist/{chat → types}/chat-schema.d.ts +0 -0
- /package/src/{tools → extensions/tools}/constants.ts +0 -0
- /package/src/{tools → extensions/tools}/definitions.test.ts +0 -0
- /package/src/{tools → extensions/tools}/executors/apply-patch-parser.ts +0 -0
- /package/src/{tools → extensions/tools}/executors/apply-patch.ts +0 -0
- /package/src/{tools → extensions/tools}/executors/bash.test.ts +0 -0
- /package/src/{tools → extensions/tools}/executors/bash.ts +0 -0
- /package/src/{tools → extensions/tools}/executors/editor.test.ts +0 -0
- /package/src/{tools → extensions/tools}/executors/editor.ts +0 -0
- /package/src/{tools → extensions/tools}/executors/index.ts +0 -0
- /package/src/{tools → extensions/tools}/executors/web-fetch.ts +0 -0
- /package/src/{tools → extensions/tools}/helpers.ts +0 -0
- /package/src/{tools → extensions/tools}/index.ts +0 -0
- /package/src/{tools → extensions/tools}/model-tool-routing.test.ts +0 -0
- /package/src/{tools → extensions/tools}/presets.test.ts +0 -0
- /package/src/{tools → extensions/tools}/schemas.ts +0 -0
- /package/src/{team → extensions/tools/team}/delegated-agent.ts +0 -0
- /package/src/{team → extensions/tools/team}/index.ts +0 -0
- /package/src/{team → extensions/tools/team}/projections.ts +0 -0
- /package/src/{team → extensions/tools/team}/runtime.ts +0 -0
- /package/src/{runtime → hooks}/checkpoint-hooks.test.ts +0 -0
- /package/src/{runtime → hooks}/hook-file-hooks.test.ts +0 -0
- /package/src/{session → runtime}/runtime-oauth-token-manager.test.ts +0 -0
- /package/src/{providers → services/providers}/local-provider-registry.ts +0 -0
- /package/src/{providers → services/providers}/local-provider-service.test.ts +0 -0
- /package/src/{storage → services/storage}/index.ts +0 -0
- /package/src/{storage → services/storage}/provider-settings-manager.test.ts +0 -0
- /package/src/{telemetry → services/telemetry}/ITelemetryAdapter.ts +0 -0
- /package/src/{telemetry → services/telemetry}/OpenTelemetryAdapter.test.ts +0 -0
- /package/src/{telemetry → services/telemetry}/OpenTelemetryAdapter.ts +0 -0
- /package/src/{telemetry → services/telemetry}/OpenTelemetryProvider.test.ts +0 -0
- /package/src/{telemetry → services/telemetry}/OpenTelemetryProvider.ts +0 -0
- /package/src/{telemetry → services/telemetry}/TelemetryLoggerSink.test.ts +0 -0
- /package/src/{telemetry → services/telemetry}/TelemetryLoggerSink.ts +0 -0
- /package/src/{telemetry → services/telemetry}/TelemetryService.test.ts +0 -0
- /package/src/{telemetry → services/telemetry}/TelemetryService.ts +0 -0
- /package/src/{telemetry → services/telemetry}/core-events.ts +0 -0
- /package/src/{telemetry → services/telemetry}/distinct-id.test.ts +0 -0
- /package/src/{telemetry → services/telemetry}/distinct-id.ts +0 -0
- /package/src/{telemetry → services/telemetry}/index.ts +0 -0
- /package/src/{input → services/workspace}/file-indexer.d.ts +0 -0
- /package/src/{input → services/workspace}/index.ts +0 -0
- /package/src/{session → services}/workspace-manifest.ts +0 -0
- /package/src/{chat → types}/chat-schema.ts +0 -0
|
@@ -24,6 +24,10 @@ type RpcStartupLockRecord = {
|
|
|
24
24
|
pid: number;
|
|
25
25
|
address: string;
|
|
26
26
|
acquiredAt: string;
|
|
27
|
+
updatedAt: string;
|
|
28
|
+
status: "starting" | "running";
|
|
29
|
+
resolvedAddress?: string;
|
|
30
|
+
serverId?: string;
|
|
27
31
|
};
|
|
28
32
|
|
|
29
33
|
export type RpcDiscoveryRecord = {
|
|
@@ -233,22 +237,54 @@ function isProbeBlocked(error: unknown): boolean {
|
|
|
233
237
|
return isUnimplementedError(error) || isAuthenticationError(error);
|
|
234
238
|
}
|
|
235
239
|
|
|
236
|
-
|
|
240
|
+
function formatProbeError(error: unknown): string {
|
|
241
|
+
if (error instanceof Error && error.message.trim()) {
|
|
242
|
+
return error.message.trim();
|
|
243
|
+
}
|
|
244
|
+
return String(error);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
type RuntimeMethodsProbeResult = {
|
|
248
|
+
available: boolean;
|
|
249
|
+
reason?: string;
|
|
250
|
+
};
|
|
251
|
+
|
|
252
|
+
async function probeRuntimeMethods(
|
|
253
|
+
address: string,
|
|
254
|
+
): Promise<RuntimeMethodsProbeResult> {
|
|
237
255
|
const client = new RpcSessionClient({ address });
|
|
238
256
|
try {
|
|
239
257
|
try {
|
|
240
258
|
await client.stopRuntimeSession("__rpc_probe__");
|
|
241
259
|
} catch (error) {
|
|
242
|
-
if (isProbeBlocked(error))
|
|
260
|
+
if (isProbeBlocked(error)) {
|
|
261
|
+
return {
|
|
262
|
+
available: false,
|
|
263
|
+
reason: `runtime probe blocked (${formatProbeError(error)})`,
|
|
264
|
+
};
|
|
265
|
+
}
|
|
243
266
|
}
|
|
244
|
-
return true;
|
|
267
|
+
return { available: true };
|
|
245
268
|
} catch (error) {
|
|
246
|
-
|
|
269
|
+
if (isProbeBlocked(error)) {
|
|
270
|
+
return {
|
|
271
|
+
available: false,
|
|
272
|
+
reason: `runtime probe blocked (${formatProbeError(error)})`,
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
return {
|
|
276
|
+
available: false,
|
|
277
|
+
reason: `runtime probe failed (${formatProbeError(error)})`,
|
|
278
|
+
};
|
|
247
279
|
} finally {
|
|
248
280
|
client.close();
|
|
249
281
|
}
|
|
250
282
|
}
|
|
251
283
|
|
|
284
|
+
async function hasRuntimeMethods(address: string): Promise<boolean> {
|
|
285
|
+
return (await probeRuntimeMethods(address)).available;
|
|
286
|
+
}
|
|
287
|
+
|
|
252
288
|
export async function isCompatibleRuntime(address: string): Promise<boolean> {
|
|
253
289
|
const health = await getRpcServerHealth(address);
|
|
254
290
|
return (
|
|
@@ -258,6 +294,32 @@ export async function isCompatibleRuntime(address: string): Promise<boolean> {
|
|
|
258
294
|
);
|
|
259
295
|
}
|
|
260
296
|
|
|
297
|
+
async function describeRpcRuntimeReadinessFailure(
|
|
298
|
+
address: string,
|
|
299
|
+
): Promise<string> {
|
|
300
|
+
let health: Awaited<ReturnType<typeof getRpcServerHealth>> | undefined;
|
|
301
|
+
try {
|
|
302
|
+
health = await getRpcServerHealth(address);
|
|
303
|
+
} catch (error) {
|
|
304
|
+
return `health probe failed (${formatProbeError(error)})`;
|
|
305
|
+
}
|
|
306
|
+
if (!health?.running) {
|
|
307
|
+
return "health probe reported no running server";
|
|
308
|
+
}
|
|
309
|
+
if (!isHealthCompatible(health)) {
|
|
310
|
+
const actualVersion =
|
|
311
|
+
typeof health.rpcVersion === "string" && health.rpcVersion.trim()
|
|
312
|
+
? health.rpcVersion.trim()
|
|
313
|
+
: "unknown";
|
|
314
|
+
return `protocol mismatch (expected=${RPC_PROTOCOL_VERSION}, actual=${actualVersion})`;
|
|
315
|
+
}
|
|
316
|
+
const runtimeProbe = await probeRuntimeMethods(address);
|
|
317
|
+
if (!runtimeProbe.available) {
|
|
318
|
+
return runtimeProbe.reason ?? "runtime methods unavailable";
|
|
319
|
+
}
|
|
320
|
+
return "runtime did not become compatible before readiness deadline";
|
|
321
|
+
}
|
|
322
|
+
|
|
261
323
|
async function isPortFree(host: string, port: number): Promise<boolean> {
|
|
262
324
|
return new Promise<boolean>((resolve) => {
|
|
263
325
|
const server = createServer();
|
|
@@ -294,13 +356,8 @@ function isPidAlive(pid: number | undefined): boolean {
|
|
|
294
356
|
|
|
295
357
|
async function writeRpcStartupLockRecord(
|
|
296
358
|
lockDir: string,
|
|
297
|
-
|
|
359
|
+
record: RpcStartupLockRecord,
|
|
298
360
|
): Promise<void> {
|
|
299
|
-
const record: RpcStartupLockRecord = {
|
|
300
|
-
pid: process.pid,
|
|
301
|
-
address,
|
|
302
|
-
acquiredAt: new Date().toISOString(),
|
|
303
|
-
};
|
|
304
361
|
await writeFile(
|
|
305
362
|
join(lockDir, "owner.json"),
|
|
306
363
|
JSON.stringify(record, null, 2),
|
|
@@ -318,7 +375,9 @@ async function readRpcStartupLockRecord(
|
|
|
318
375
|
if (
|
|
319
376
|
typeof parsed.pid !== "number" ||
|
|
320
377
|
typeof parsed.address !== "string" ||
|
|
321
|
-
typeof parsed.acquiredAt !== "string"
|
|
378
|
+
typeof parsed.acquiredAt !== "string" ||
|
|
379
|
+
typeof parsed.updatedAt !== "string" ||
|
|
380
|
+
(parsed.status !== "starting" && parsed.status !== "running")
|
|
322
381
|
) {
|
|
323
382
|
return undefined;
|
|
324
383
|
}
|
|
@@ -326,6 +385,14 @@ async function readRpcStartupLockRecord(
|
|
|
326
385
|
pid: parsed.pid,
|
|
327
386
|
address: parsed.address,
|
|
328
387
|
acquiredAt: parsed.acquiredAt,
|
|
388
|
+
updatedAt: parsed.updatedAt,
|
|
389
|
+
status: parsed.status,
|
|
390
|
+
resolvedAddress:
|
|
391
|
+
typeof parsed.resolvedAddress === "string"
|
|
392
|
+
? parsed.resolvedAddress
|
|
393
|
+
: undefined,
|
|
394
|
+
serverId:
|
|
395
|
+
typeof parsed.serverId === "string" ? parsed.serverId : undefined,
|
|
329
396
|
};
|
|
330
397
|
} catch {
|
|
331
398
|
return undefined;
|
|
@@ -336,12 +403,59 @@ async function removeRpcStartupLockDir(lockDir: string): Promise<void> {
|
|
|
336
403
|
await rm(lockDir, { recursive: true, force: true }).catch(() => {});
|
|
337
404
|
}
|
|
338
405
|
|
|
406
|
+
async function updateRpcStartupLockRecord(
|
|
407
|
+
lockDir: string,
|
|
408
|
+
patch: Partial<Omit<RpcStartupLockRecord, "pid" | "address" | "acquiredAt">>,
|
|
409
|
+
): Promise<void> {
|
|
410
|
+
const current = await readRpcStartupLockRecord(lockDir);
|
|
411
|
+
if (!current) {
|
|
412
|
+
return;
|
|
413
|
+
}
|
|
414
|
+
await writeRpcStartupLockRecord(lockDir, {
|
|
415
|
+
...current,
|
|
416
|
+
...patch,
|
|
417
|
+
updatedAt: new Date().toISOString(),
|
|
418
|
+
});
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
async function isRpcStartupLockStale(
|
|
422
|
+
existing: RpcStartupLockRecord | undefined,
|
|
423
|
+
): Promise<boolean> {
|
|
424
|
+
const acquiredAtMs = existing ? new Date(existing.acquiredAt).getTime() : NaN;
|
|
425
|
+
if (
|
|
426
|
+
!existing ||
|
|
427
|
+
!Number.isFinite(acquiredAtMs) ||
|
|
428
|
+
Date.now() - acquiredAtMs > RPC_STARTUP_LOCK_MAX_AGE_MS ||
|
|
429
|
+
!isPidAlive(existing.pid)
|
|
430
|
+
) {
|
|
431
|
+
return true;
|
|
432
|
+
}
|
|
433
|
+
if (existing.status !== "running") {
|
|
434
|
+
return false;
|
|
435
|
+
}
|
|
436
|
+
const targetAddress = existing.resolvedAddress?.trim() || existing.address;
|
|
437
|
+
try {
|
|
438
|
+
return !(await getRpcServerHealth(targetAddress))?.running;
|
|
439
|
+
} catch {
|
|
440
|
+
return true;
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
export type RpcStartupLockHandle = {
|
|
445
|
+
markRunning: (details?: {
|
|
446
|
+
resolvedAddress?: string;
|
|
447
|
+
serverId?: string;
|
|
448
|
+
}) => Promise<void>;
|
|
449
|
+
};
|
|
450
|
+
|
|
339
451
|
export async function withRpcStartupLock<T>(
|
|
340
452
|
address: string,
|
|
341
|
-
action: () => Promise<T>,
|
|
453
|
+
action: (lock: RpcStartupLockHandle) => Promise<T>,
|
|
342
454
|
): Promise<T> {
|
|
343
455
|
if (process.env[RPC_STARTUP_LOCK_BYPASS_ENV] === "1") {
|
|
344
|
-
return await action(
|
|
456
|
+
return await action({
|
|
457
|
+
markRunning: async () => undefined,
|
|
458
|
+
});
|
|
345
459
|
}
|
|
346
460
|
|
|
347
461
|
const lockDir = getRpcStartupLockDir(address);
|
|
@@ -351,9 +465,23 @@ export async function withRpcStartupLock<T>(
|
|
|
351
465
|
while (true) {
|
|
352
466
|
try {
|
|
353
467
|
await mkdir(lockDir, { recursive: false });
|
|
354
|
-
await writeRpcStartupLockRecord(lockDir,
|
|
468
|
+
await writeRpcStartupLockRecord(lockDir, {
|
|
469
|
+
pid: process.pid,
|
|
470
|
+
address,
|
|
471
|
+
acquiredAt: new Date().toISOString(),
|
|
472
|
+
updatedAt: new Date().toISOString(),
|
|
473
|
+
status: "starting",
|
|
474
|
+
});
|
|
355
475
|
try {
|
|
356
|
-
return await action(
|
|
476
|
+
return await action({
|
|
477
|
+
markRunning: async (details) => {
|
|
478
|
+
await updateRpcStartupLockRecord(lockDir, {
|
|
479
|
+
status: "running",
|
|
480
|
+
resolvedAddress: details?.resolvedAddress?.trim() || undefined,
|
|
481
|
+
serverId: details?.serverId?.trim() || undefined,
|
|
482
|
+
});
|
|
483
|
+
},
|
|
484
|
+
});
|
|
357
485
|
} finally {
|
|
358
486
|
await removeRpcStartupLockDir(lockDir);
|
|
359
487
|
}
|
|
@@ -361,22 +489,17 @@ export async function withRpcStartupLock<T>(
|
|
|
361
489
|
if (errorCode(error) !== "EEXIST") throw error;
|
|
362
490
|
|
|
363
491
|
const existing = await readRpcStartupLockRecord(lockDir);
|
|
364
|
-
const
|
|
365
|
-
? new Date(existing.acquiredAt).getTime()
|
|
366
|
-
: Number.NaN;
|
|
367
|
-
const isStale =
|
|
368
|
-
!existing ||
|
|
369
|
-
!Number.isFinite(acquiredAtMs) ||
|
|
370
|
-
Date.now() - acquiredAtMs > RPC_STARTUP_LOCK_MAX_AGE_MS ||
|
|
371
|
-
!isPidAlive(existing.pid);
|
|
492
|
+
const isStale = await isRpcStartupLockStale(existing);
|
|
372
493
|
if (isStale) {
|
|
373
494
|
await removeRpcStartupLockDir(lockDir);
|
|
374
495
|
continue;
|
|
375
496
|
}
|
|
376
497
|
|
|
377
498
|
if (Date.now() - startedAt >= RPC_STARTUP_LOCK_WAIT_MS) {
|
|
499
|
+
const ownerPid =
|
|
500
|
+
typeof existing?.pid === "number" ? existing.pid : "unknown";
|
|
378
501
|
throw new Error(
|
|
379
|
-
`timed out waiting for rpc startup lock at ${address} (owner pid=${
|
|
502
|
+
`timed out waiting for rpc startup lock at ${address} (owner pid=${ownerPid})`,
|
|
380
503
|
);
|
|
381
504
|
}
|
|
382
505
|
await sleep(RPC_STARTUP_LOCK_POLL_MS);
|
|
@@ -415,11 +538,18 @@ export async function resolveEnsuredRpcRuntime(
|
|
|
415
538
|
options: {
|
|
416
539
|
owner?: RpcOwnerContext;
|
|
417
540
|
resolveOwner?: () => RpcOwnerContext;
|
|
541
|
+
/**
|
|
542
|
+
* When true, skip startup lock acquisition. Use this when the caller
|
|
543
|
+
* already holds the lock via {@link withRpcStartupLock} to avoid a
|
|
544
|
+
* deadlock from nested lock acquisition on the same address.
|
|
545
|
+
*/
|
|
546
|
+
lockAlreadyHeld?: boolean;
|
|
418
547
|
} = {},
|
|
419
548
|
): Promise<ResolveRpcRuntimeResult> {
|
|
420
549
|
const owner =
|
|
421
550
|
options.owner ?? options.resolveOwner?.() ?? resolveRpcOwnerContext();
|
|
422
|
-
|
|
551
|
+
|
|
552
|
+
const core = async (): Promise<ResolveRpcRuntimeResult> => {
|
|
423
553
|
const discovery = await readRpcDiscovery(owner);
|
|
424
554
|
if (discovery?.address) {
|
|
425
555
|
const discoveredHealth = await getRpcServerHealth(discovery.address);
|
|
@@ -475,7 +605,12 @@ export async function resolveEnsuredRpcRuntime(
|
|
|
475
605
|
action: "new-port",
|
|
476
606
|
owner,
|
|
477
607
|
} satisfies ResolveRpcRuntimeResult;
|
|
478
|
-
}
|
|
608
|
+
};
|
|
609
|
+
|
|
610
|
+
if (options.lockAlreadyHeld) {
|
|
611
|
+
return await core();
|
|
612
|
+
}
|
|
613
|
+
return await withRpcStartupLock(requestedAddress, core);
|
|
479
614
|
}
|
|
480
615
|
|
|
481
616
|
export async function waitForCompatibleRpcRuntime(
|
|
@@ -506,7 +641,10 @@ export async function ensureRpcRuntimeAddress(
|
|
|
506
641
|
options.readinessCheck,
|
|
507
642
|
))
|
|
508
643
|
) {
|
|
509
|
-
|
|
644
|
+
const reason = await describeRpcRuntimeReadinessFailure(resolved.address);
|
|
645
|
+
throw new Error(
|
|
646
|
+
`failed to ensure rpc runtime at ${resolved.address}: ${reason}`,
|
|
647
|
+
);
|
|
510
648
|
}
|
|
511
649
|
const health = await getRpcServerHealth(resolved.address);
|
|
512
650
|
await recordRpcDiscovery(resolved.owner, {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import { mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
2
3
|
import os from "node:os";
|
|
3
4
|
import path from "node:path";
|
|
4
5
|
import { afterEach, describe, expect, it } from "vitest";
|
|
@@ -46,4 +47,35 @@ describe("tryAcquireRpcSpawnLease", () => {
|
|
|
46
47
|
first?.release();
|
|
47
48
|
second?.release();
|
|
48
49
|
});
|
|
50
|
+
|
|
51
|
+
it("reclaims a leftover lease owned by the current process", () => {
|
|
52
|
+
const dataDir = mkdtempSync(path.join(os.tmpdir(), "rpc-spawn-lease-"));
|
|
53
|
+
tempDirs.push(dataDir);
|
|
54
|
+
process.env.CLINE_DATA_DIR = dataDir;
|
|
55
|
+
|
|
56
|
+
const first = tryAcquireRpcSpawnLease("127.0.0.1:4317");
|
|
57
|
+
expect(first).toBeDefined();
|
|
58
|
+
const leasePath = first?.path;
|
|
59
|
+
expect(leasePath).toBeTruthy();
|
|
60
|
+
first?.release();
|
|
61
|
+
|
|
62
|
+
writeFileSync(
|
|
63
|
+
leasePath!,
|
|
64
|
+
JSON.stringify({
|
|
65
|
+
address: "127.0.0.1:4317",
|
|
66
|
+
pid: process.pid,
|
|
67
|
+
createdAt: Date.now(),
|
|
68
|
+
}),
|
|
69
|
+
"utf8",
|
|
70
|
+
);
|
|
71
|
+
|
|
72
|
+
const second = tryAcquireRpcSpawnLease("127.0.0.1:4317");
|
|
73
|
+
assert(second);
|
|
74
|
+
expect(
|
|
75
|
+
JSON.parse(readFileSync(second.path, "utf8")) as { pid: number },
|
|
76
|
+
).toMatchObject({
|
|
77
|
+
pid: process.pid,
|
|
78
|
+
});
|
|
79
|
+
second.release();
|
|
80
|
+
});
|
|
49
81
|
});
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
import { dirname, resolve } from "node:path";
|
|
11
11
|
import { resolveSessionDataDir } from "@clinebot/shared/storage";
|
|
12
12
|
|
|
13
|
-
const DEFAULT_LEASE_TTL_MS =
|
|
13
|
+
const DEFAULT_LEASE_TTL_MS = 5_000;
|
|
14
14
|
|
|
15
15
|
interface RpcSpawnLeaseRecord {
|
|
16
16
|
address: string;
|
|
@@ -23,6 +23,10 @@ export interface RpcSpawnLease {
|
|
|
23
23
|
release: () => void;
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
+
const ACTIVE_LEASE_RELEASES = new Set<() => void>();
|
|
27
|
+
const ACTIVE_LEASE_PATHS = new Set<string>();
|
|
28
|
+
let EXIT_CLEANUP_REGISTERED = false;
|
|
29
|
+
|
|
26
30
|
function encodeAddress(address: string): string {
|
|
27
31
|
return Buffer.from(address).toString("base64url");
|
|
28
32
|
}
|
|
@@ -52,19 +56,43 @@ function shouldClearLease(path: string, ttlMs: number): boolean {
|
|
|
52
56
|
try {
|
|
53
57
|
const raw = readFileSync(path, "utf8");
|
|
54
58
|
const parsed = JSON.parse(raw) as Partial<RpcSpawnLeaseRecord>;
|
|
59
|
+
const pid = Number(parsed.pid ?? 0);
|
|
55
60
|
const createdAt = Number(parsed.createdAt ?? 0);
|
|
61
|
+
if (pid === process.pid && !ACTIVE_LEASE_PATHS.has(path)) {
|
|
62
|
+
return true;
|
|
63
|
+
}
|
|
56
64
|
if (!Number.isFinite(createdAt) || createdAt <= 0) {
|
|
57
65
|
return true;
|
|
58
66
|
}
|
|
59
67
|
if (Date.now() - createdAt > ttlMs) {
|
|
60
68
|
return true;
|
|
61
69
|
}
|
|
62
|
-
return !isProcessAlive(
|
|
70
|
+
return !isProcessAlive(pid);
|
|
63
71
|
} catch {
|
|
64
72
|
return true;
|
|
65
73
|
}
|
|
66
74
|
}
|
|
67
75
|
|
|
76
|
+
function cleanupActiveLeases(): void {
|
|
77
|
+
for (const release of [...ACTIVE_LEASE_RELEASES]) {
|
|
78
|
+
try {
|
|
79
|
+
release();
|
|
80
|
+
} catch {
|
|
81
|
+
// Best effort.
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function registerExitCleanupOnce(): void {
|
|
87
|
+
if (EXIT_CLEANUP_REGISTERED) {
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
EXIT_CLEANUP_REGISTERED = true;
|
|
91
|
+
process.once("exit", cleanupActiveLeases);
|
|
92
|
+
process.once("SIGINT", cleanupActiveLeases);
|
|
93
|
+
process.once("SIGTERM", cleanupActiveLeases);
|
|
94
|
+
}
|
|
95
|
+
|
|
68
96
|
export function tryAcquireRpcSpawnLease(
|
|
69
97
|
address: string,
|
|
70
98
|
options?: { ttlMs?: number },
|
|
@@ -98,25 +126,31 @@ export function tryAcquireRpcSpawnLease(
|
|
|
98
126
|
}
|
|
99
127
|
|
|
100
128
|
let released = false;
|
|
129
|
+
const release = () => {
|
|
130
|
+
if (released) {
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
released = true;
|
|
134
|
+
ACTIVE_LEASE_RELEASES.delete(release);
|
|
135
|
+
ACTIVE_LEASE_PATHS.delete(path);
|
|
136
|
+
try {
|
|
137
|
+
if (typeof fd === "number") {
|
|
138
|
+
closeSync(fd);
|
|
139
|
+
}
|
|
140
|
+
} catch {
|
|
141
|
+
// Best effort.
|
|
142
|
+
}
|
|
143
|
+
try {
|
|
144
|
+
rmSync(path, { force: true });
|
|
145
|
+
} catch {
|
|
146
|
+
// Best effort.
|
|
147
|
+
}
|
|
148
|
+
};
|
|
149
|
+
registerExitCleanupOnce();
|
|
150
|
+
ACTIVE_LEASE_RELEASES.add(release);
|
|
151
|
+
ACTIVE_LEASE_PATHS.add(path);
|
|
101
152
|
return {
|
|
102
153
|
path,
|
|
103
|
-
release
|
|
104
|
-
if (released) {
|
|
105
|
-
return;
|
|
106
|
-
}
|
|
107
|
-
released = true;
|
|
108
|
-
try {
|
|
109
|
-
if (typeof fd === "number") {
|
|
110
|
-
closeSync(fd);
|
|
111
|
-
}
|
|
112
|
-
} catch {
|
|
113
|
-
// Best effort.
|
|
114
|
-
}
|
|
115
|
-
try {
|
|
116
|
-
rmSync(path, { force: true });
|
|
117
|
-
} catch {
|
|
118
|
-
// Best effort.
|
|
119
|
-
}
|
|
120
|
-
},
|
|
154
|
+
release,
|
|
121
155
|
};
|
|
122
156
|
}
|
|
@@ -35,7 +35,7 @@ class MockAgentTeamsRuntime {
|
|
|
35
35
|
shutdownTeammate = vi.fn();
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
vi.mock("../team", () => ({
|
|
38
|
+
vi.mock("../extensions/tools/team", () => ({
|
|
39
39
|
AgentTeamsRuntime: MockAgentTeamsRuntime,
|
|
40
40
|
bootstrapAgentTeams: bootstrapAgentTeamsMock,
|
|
41
41
|
createDelegatedAgentConfigProvider: (config: Record<string, unknown>) => {
|
|
@@ -59,13 +59,16 @@ vi.mock("../team", () => ({
|
|
|
59
59
|
},
|
|
60
60
|
}));
|
|
61
61
|
|
|
62
|
-
vi.mock("../
|
|
62
|
+
vi.mock("../extensions/tools", () => ({
|
|
63
63
|
ALL_DEFAULT_TOOL_NAMES: [],
|
|
64
64
|
createBuiltinTools: createBuiltinToolsMock,
|
|
65
65
|
ToolPresets: {
|
|
66
66
|
development: {},
|
|
67
67
|
readonly: {},
|
|
68
68
|
},
|
|
69
|
+
resolveToolPresetName: () => "development",
|
|
70
|
+
resolveToolRoutingConfig: () => [],
|
|
71
|
+
DEFAULT_MODEL_TOOL_ROUTING_RULES: [],
|
|
69
72
|
}));
|
|
70
73
|
|
|
71
74
|
let teamStoreInstance: MockTeamStore | undefined;
|
|
@@ -100,7 +103,7 @@ class MockTeamStore {
|
|
|
100
103
|
persistRuntime = vi.fn();
|
|
101
104
|
}
|
|
102
105
|
|
|
103
|
-
vi.mock("../storage/team-store", () => ({
|
|
106
|
+
vi.mock("../services/storage/team-store", () => ({
|
|
104
107
|
createLocalTeamStore: () => new MockTeamStore(),
|
|
105
108
|
}));
|
|
106
109
|
|
|
@@ -3,7 +3,7 @@ import { tmpdir } from "node:os";
|
|
|
3
3
|
import { join } from "node:path";
|
|
4
4
|
import type { Tool } from "@clinebot/shared";
|
|
5
5
|
import { describe, expect, it } from "vitest";
|
|
6
|
-
import { TelemetryService } from "../telemetry/TelemetryService";
|
|
6
|
+
import { TelemetryService } from "../services/telemetry/TelemetryService";
|
|
7
7
|
import type { CoreSessionConfig } from "../types/config";
|
|
8
8
|
import { DefaultRuntimeBuilder } from "./runtime-builder";
|
|
9
9
|
|
|
@@ -83,8 +83,7 @@ describe("DefaultRuntimeBuilder", () => {
|
|
|
83
83
|
it("uses yolo preset only when yolo mode is explicit", async () => {
|
|
84
84
|
const runtime = await new DefaultRuntimeBuilder().build({
|
|
85
85
|
config: makeBaseConfig({
|
|
86
|
-
mode: "
|
|
87
|
-
yolo: true,
|
|
86
|
+
mode: "yolo",
|
|
88
87
|
}),
|
|
89
88
|
defaultToolExecutors: {
|
|
90
89
|
submit: async () => "submitted",
|
|
@@ -120,7 +119,7 @@ describe("DefaultRuntimeBuilder", () => {
|
|
|
120
119
|
config: {
|
|
121
120
|
...makeBaseConfig({
|
|
122
121
|
enableTools: false,
|
|
123
|
-
|
|
122
|
+
mode: "yolo",
|
|
124
123
|
}),
|
|
125
124
|
} as CoreSessionConfig,
|
|
126
125
|
createSpawnTool: makeSpawnTool,
|
|
@@ -16,13 +16,6 @@ import {
|
|
|
16
16
|
registerMcpServersFromSettingsFile,
|
|
17
17
|
resolveDefaultMcpSettingsPath,
|
|
18
18
|
} from "../extensions/mcp";
|
|
19
|
-
import { createLocalTeamStore } from "../storage/team-store";
|
|
20
|
-
import {
|
|
21
|
-
AgentTeamsRuntime,
|
|
22
|
-
bootstrapAgentTeams,
|
|
23
|
-
createDelegatedAgentConfigProvider,
|
|
24
|
-
type TeamEvent,
|
|
25
|
-
} from "../team";
|
|
26
19
|
import {
|
|
27
20
|
createBuiltinTools,
|
|
28
21
|
DEFAULT_MODEL_TOOL_ROUTING_RULES,
|
|
@@ -32,7 +25,14 @@ import {
|
|
|
32
25
|
type ToolExecutors,
|
|
33
26
|
ToolPresets,
|
|
34
27
|
type ToolRoutingRule,
|
|
35
|
-
} from "../tools";
|
|
28
|
+
} from "../extensions/tools";
|
|
29
|
+
import {
|
|
30
|
+
AgentTeamsRuntime,
|
|
31
|
+
bootstrapAgentTeams,
|
|
32
|
+
createDelegatedAgentConfigProvider,
|
|
33
|
+
type TeamEvent,
|
|
34
|
+
} from "../extensions/tools/team";
|
|
35
|
+
import { createLocalTeamStore } from "../services/storage/team-store";
|
|
36
36
|
import type { CoreAgentMode, CoreSessionConfig } from "../types/config";
|
|
37
37
|
import type {
|
|
38
38
|
RuntimeBuilder,
|
|
@@ -82,14 +82,13 @@ function createBuiltinToolsList(
|
|
|
82
82
|
cwd: string,
|
|
83
83
|
providerId: string,
|
|
84
84
|
mode: CoreAgentMode,
|
|
85
|
-
yolo: boolean | undefined,
|
|
86
85
|
modelId: string,
|
|
87
86
|
toolRoutingRules: ToolRoutingRule[] | undefined,
|
|
88
87
|
toolPolicies: CoreSessionConfig["toolPolicies"],
|
|
89
88
|
skillsExecutor?: SkillsExecutorWithMetadata,
|
|
90
89
|
executorOverrides?: Partial<ToolExecutors>,
|
|
91
90
|
): Tool[] {
|
|
92
|
-
const preset = ToolPresets[resolveToolPresetName({ mode
|
|
91
|
+
const preset = ToolPresets[resolveToolPresetName({ mode })];
|
|
93
92
|
const toolRoutingConfig = resolveToolRoutingConfig(
|
|
94
93
|
providerId,
|
|
95
94
|
modelId,
|
|
@@ -429,16 +428,11 @@ function normalizeConfig(
|
|
|
429
428
|
| "sessionId"
|
|
430
429
|
>
|
|
431
430
|
> {
|
|
432
|
-
const preset =
|
|
433
|
-
ToolPresets[
|
|
434
|
-
resolveToolPresetName({
|
|
435
|
-
mode: config.mode,
|
|
436
|
-
yolo: config.yolo,
|
|
437
|
-
})
|
|
438
|
-
];
|
|
431
|
+
const preset = ToolPresets[resolveToolPresetName({ mode: config.mode })];
|
|
439
432
|
return {
|
|
440
433
|
sessionId: config.sessionId || "",
|
|
441
|
-
mode:
|
|
434
|
+
mode:
|
|
435
|
+
config.mode === "plan" ? "plan" : config.mode === "yolo" ? "yolo" : "act",
|
|
442
436
|
enableTools: config.enableTools !== false,
|
|
443
437
|
enableSpawnAgent:
|
|
444
438
|
config.enableSpawnAgent ?? preset.enableSpawnAgent ?? true,
|
|
@@ -523,7 +517,6 @@ export class DefaultRuntimeBuilder implements RuntimeBuilder {
|
|
|
523
517
|
config.cwd,
|
|
524
518
|
config.providerId,
|
|
525
519
|
normalized.mode,
|
|
526
|
-
normalized.yolo,
|
|
527
520
|
config.modelId,
|
|
528
521
|
config.toolRoutingRules,
|
|
529
522
|
config.toolPolicies,
|
|
@@ -653,7 +646,6 @@ export class DefaultRuntimeBuilder implements RuntimeBuilder {
|
|
|
653
646
|
config.cwd,
|
|
654
647
|
config.providerId,
|
|
655
648
|
normalized.mode,
|
|
656
|
-
normalized.yolo,
|
|
657
649
|
config.modelId,
|
|
658
650
|
config.toolRoutingRules,
|
|
659
651
|
config.toolPolicies,
|
|
@@ -715,7 +707,7 @@ export class DefaultRuntimeBuilder implements RuntimeBuilder {
|
|
|
715
707
|
if (pending) parts.push(`Unfinished tasks: ${pending}`);
|
|
716
708
|
if (activeRunSummary)
|
|
717
709
|
parts.push(`Active runs: ${activeRunSummary}`);
|
|
718
|
-
return `[SYSTEM] You still have team obligations. ${parts.join(". ")}. Use team_run_task to delegate work, or team_task with action=complete to mark tasks done, or
|
|
710
|
+
return `[SYSTEM] You still have team obligations. ${parts.join(". ")}. Use team_run_task to delegate work, or team_task with action=complete to mark tasks done, or team_await_runs to wait for active runs. Do NOT stop until all tasks are completed.`;
|
|
719
711
|
}
|
|
720
712
|
return undefined;
|
|
721
713
|
}
|