@clinebot/core 0.0.35 → 0.0.37
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -2
- package/dist/ClineCore.d.ts +362 -39
- package/dist/ClineCore.d.ts.map +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/rpc.d.ts +6 -6
- package/dist/account/rpc.d.ts.map +1 -1
- package/dist/cron/cron-event-ingress.d.ts +38 -0
- package/dist/cron/cron-event-ingress.d.ts.map +1 -0
- package/dist/cron/cron-materializer.d.ts +36 -0
- package/dist/cron/cron-materializer.d.ts.map +1 -0
- package/dist/cron/cron-reconciler.d.ts +62 -0
- package/dist/cron/cron-reconciler.d.ts.map +1 -0
- package/dist/cron/cron-report-writer.d.ts +41 -0
- package/dist/cron/cron-report-writer.d.ts.map +1 -0
- package/dist/cron/cron-runner.d.ts +43 -0
- package/dist/cron/cron-runner.d.ts.map +1 -0
- package/dist/cron/cron-schema.d.ts +3 -0
- package/dist/cron/cron-schema.d.ts.map +1 -0
- package/dist/cron/cron-service.d.ts +57 -0
- package/dist/cron/cron-service.d.ts.map +1 -0
- package/dist/cron/cron-spec-parser.d.ts +27 -0
- package/dist/cron/cron-spec-parser.d.ts.map +1 -0
- package/dist/cron/cron-watcher.d.ts +23 -0
- package/dist/cron/cron-watcher.d.ts.map +1 -0
- package/dist/cron/resource-limiter.d.ts +9 -0
- package/dist/cron/resource-limiter.d.ts.map +1 -0
- package/dist/cron/schedule-command-service.d.ts +10 -0
- package/dist/cron/schedule-command-service.d.ts.map +1 -0
- package/dist/cron/schedule-service.d.ts +100 -0
- package/dist/cron/schedule-service.d.ts.map +1 -0
- package/dist/cron/scheduler.d.ts +68 -0
- package/dist/cron/scheduler.d.ts.map +1 -0
- package/dist/cron/sqlite-cron-store.d.ts +230 -0
- package/dist/cron/sqlite-cron-store.d.ts.map +1 -0
- package/dist/cron/sqlite-schedule-store.d.ts +52 -0
- package/dist/cron/sqlite-schedule-store.d.ts.map +1 -0
- package/dist/extensions/config/agent-config-loader.d.ts +4 -3
- package/dist/extensions/config/agent-config-loader.d.ts.map +1 -1
- package/dist/extensions/config/runtime-commands.d.ts +1 -0
- package/dist/extensions/config/runtime-commands.d.ts.map +1 -1
- package/dist/extensions/config/user-instruction-config-loader.d.ts +1 -0
- package/dist/extensions/config/user-instruction-config-loader.d.ts.map +1 -1
- package/dist/extensions/context/agentic-compaction.d.ts +2 -2
- package/dist/extensions/context/agentic-compaction.d.ts.map +1 -1
- package/dist/extensions/context/compaction-shared.d.ts +5 -4
- package/dist/extensions/context/compaction-shared.d.ts.map +1 -1
- package/dist/extensions/context/compaction.d.ts.map +1 -1
- package/dist/extensions/plugin/plugin-config-loader.d.ts +15 -2
- package/dist/extensions/plugin/plugin-config-loader.d.ts.map +1 -1
- package/dist/extensions/plugin/plugin-loader.d.ts +13 -7
- package/dist/extensions/plugin/plugin-loader.d.ts.map +1 -1
- package/dist/extensions/plugin/plugin-module-import.d.ts.map +1 -1
- package/dist/extensions/plugin/plugin-sandbox.d.ts +21 -2
- package/dist/extensions/plugin/plugin-sandbox.d.ts.map +1 -1
- package/dist/extensions/plugin/plugin-targeting.d.ts +7 -0
- package/dist/extensions/plugin/plugin-targeting.d.ts.map +1 -0
- package/dist/extensions/plugin-sandbox-bootstrap.js +237 -276
- package/dist/extensions/tools/constants.d.ts +1 -0
- package/dist/extensions/tools/constants.d.ts.map +1 -1
- package/dist/extensions/tools/definitions.d.ts +3 -4
- package/dist/extensions/tools/definitions.d.ts.map +1 -1
- package/dist/extensions/tools/executors/apply-patch.d.ts +3 -1
- package/dist/extensions/tools/executors/apply-patch.d.ts.map +1 -1
- package/dist/extensions/tools/executors/editor.d.ts.map +1 -1
- package/dist/extensions/tools/executors/search.d.ts +1 -1
- package/dist/extensions/tools/executors/search.d.ts.map +1 -1
- package/dist/extensions/tools/helpers.d.ts +1 -0
- package/dist/extensions/tools/helpers.d.ts.map +1 -1
- package/dist/extensions/tools/index.d.ts +3 -2
- package/dist/extensions/tools/index.d.ts.map +1 -1
- package/dist/extensions/tools/presets.d.ts +27 -44
- package/dist/extensions/tools/presets.d.ts.map +1 -1
- package/dist/extensions/tools/runtime.d.ts +25 -0
- package/dist/extensions/tools/runtime.d.ts.map +1 -0
- package/dist/extensions/tools/schemas.d.ts +25 -3
- package/dist/extensions/tools/schemas.d.ts.map +1 -1
- package/dist/extensions/tools/team/delegated-agent.d.ts +2 -2
- package/dist/extensions/tools/team/delegated-agent.d.ts.map +1 -1
- package/dist/extensions/tools/team/multi-agent.d.ts +7 -3
- package/dist/extensions/tools/team/multi-agent.d.ts.map +1 -1
- package/dist/extensions/tools/team/team-tools.d.ts +1 -0
- package/dist/extensions/tools/team/team-tools.d.ts.map +1 -1
- package/dist/extensions/tools/types.d.ts +0 -5
- package/dist/extensions/tools/types.d.ts.map +1 -1
- package/dist/hooks/hook-bridge.d.ts +118 -0
- package/dist/hooks/hook-bridge.d.ts.map +1 -0
- package/dist/hooks/hook-file-hooks.d.ts +6 -2
- package/dist/hooks/hook-file-hooks.d.ts.map +1 -1
- package/dist/hooks/hook-registry.d.ts +16 -0
- package/dist/hooks/hook-registry.d.ts.map +1 -0
- package/dist/hooks/index.d.ts +0 -1
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/subprocess.d.ts +8 -1
- package/dist/hooks/subprocess.d.ts.map +1 -1
- package/dist/hub/browser-websocket.d.ts +18 -0
- package/dist/hub/browser-websocket.d.ts.map +1 -0
- package/dist/hub/client.d.ts +51 -0
- package/dist/hub/client.d.ts.map +1 -0
- package/dist/hub/connect.d.ts +15 -0
- package/dist/hub/connect.d.ts.map +1 -0
- package/dist/hub/daemon-entry.d.ts +2 -0
- package/dist/hub/daemon-entry.d.ts.map +1 -0
- package/dist/hub/daemon-entry.js +1305 -0
- package/dist/hub/daemon.d.ts +5 -0
- package/dist/hub/daemon.d.ts.map +1 -0
- package/dist/hub/defaults.d.ts +17 -0
- package/dist/hub/defaults.d.ts.map +1 -0
- package/dist/hub/discovery.d.ts +29 -0
- package/dist/hub/discovery.d.ts.map +1 -0
- package/dist/hub/index.d.ts +15 -0
- package/dist/hub/index.d.ts.map +1 -0
- package/dist/hub/index.js +1294 -0
- package/dist/hub/native-transport.d.ts +17 -0
- package/dist/hub/native-transport.d.ts.map +1 -0
- package/dist/hub/runtime-handlers.d.ts +11 -0
- package/dist/hub/runtime-handlers.d.ts.map +1 -0
- package/dist/hub/server.d.ts +104 -0
- package/dist/hub/server.d.ts.map +1 -0
- package/dist/hub/session-client.d.ts +90 -0
- package/dist/hub/session-client.d.ts.map +1 -0
- package/dist/hub/start-shared-server.d.ts +19 -0
- package/dist/hub/start-shared-server.d.ts.map +1 -0
- package/dist/hub/transport.d.ts +8 -0
- package/dist/hub/transport.d.ts.map +1 -0
- package/dist/hub/ui-client.d.ts +45 -0
- package/dist/hub/ui-client.d.ts.map +1 -0
- package/dist/hub/workspace.d.ts +4 -0
- package/dist/hub/workspace.d.ts.map +1 -0
- package/dist/index.d.ts +29 -16
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +782 -471
- package/dist/llms/cline-recommended-models.d.ts +20 -0
- package/dist/llms/cline-recommended-models.d.ts.map +1 -0
- package/dist/llms/configured-provider-registry.d.ts +28 -0
- package/dist/llms/configured-provider-registry.d.ts.map +1 -0
- package/dist/llms/handler-factory.d.ts +16 -0
- package/dist/llms/handler-factory.d.ts.map +1 -0
- package/dist/llms/provider-defaults.d.ts +27 -0
- package/dist/llms/provider-defaults.d.ts.map +1 -0
- package/dist/llms/provider-settings.d.ts +245 -0
- package/dist/llms/provider-settings.d.ts.map +1 -0
- package/dist/llms/runtime-config.d.ts +4 -0
- package/dist/llms/runtime-config.d.ts.map +1 -0
- package/dist/llms/runtime-registry.d.ts +20 -0
- package/dist/llms/runtime-registry.d.ts.map +1 -0
- package/dist/llms/runtime-types.d.ts +85 -0
- package/dist/llms/runtime-types.d.ts.map +1 -0
- package/dist/runtime/agent-config-adapter.d.ts +148 -0
- package/dist/runtime/agent-config-adapter.d.ts.map +1 -0
- package/dist/runtime/agent-runtime-config-builder.d.ts +96 -0
- package/dist/runtime/agent-runtime-config-builder.d.ts.map +1 -0
- package/dist/runtime/history.d.ts +6 -0
- package/dist/runtime/history.d.ts.map +1 -1
- package/dist/runtime/host.d.ts +1 -2
- package/dist/runtime/host.d.ts.map +1 -1
- package/dist/runtime/loop-detection.d.ts +59 -0
- package/dist/runtime/loop-detection.d.ts.map +1 -0
- package/dist/runtime/mistake-tracker.d.ts +69 -0
- package/dist/runtime/mistake-tracker.d.ts.map +1 -0
- package/dist/runtime/rules.d.ts +1 -0
- package/dist/runtime/rules.d.ts.map +1 -1
- package/dist/runtime/runtime-builder.d.ts.map +1 -1
- package/dist/runtime/runtime-event-adapter.d.ts +102 -0
- package/dist/runtime/runtime-event-adapter.d.ts.map +1 -0
- package/dist/runtime/runtime-host.d.ts +49 -26
- package/dist/runtime/runtime-host.d.ts.map +1 -1
- package/dist/runtime/runtime-oauth-token-manager.d.ts.map +1 -1
- package/dist/runtime/session-runtime-orchestrator.d.ts +261 -0
- package/dist/runtime/session-runtime-orchestrator.d.ts.map +1 -0
- package/dist/runtime/session-runtime.d.ts +16 -21
- package/dist/runtime/session-runtime.d.ts.map +1 -1
- package/dist/runtime/user-input-builder.d.ts +24 -0
- package/dist/runtime/user-input-builder.d.ts.map +1 -0
- package/dist/services/global-settings.d.ts +12 -0
- package/dist/services/global-settings.d.ts.map +1 -0
- package/dist/services/index.js +28 -0
- package/dist/services/local-runtime-bootstrap.d.ts +9 -3
- package/dist/services/local-runtime-bootstrap.d.ts.map +1 -1
- package/dist/services/plugin-tools.d.ts +16 -0
- package/dist/services/plugin-tools.d.ts.map +1 -0
- package/dist/services/providers/local-provider-registry.d.ts +199 -23
- package/dist/services/providers/local-provider-registry.d.ts.map +1 -1
- package/dist/services/providers/local-provider-service.d.ts +15 -13
- package/dist/services/providers/local-provider-service.d.ts.map +1 -1
- package/dist/services/session-data.d.ts +1 -1
- package/dist/services/session-data.d.ts.map +1 -1
- package/dist/services/session-telemetry.d.ts +7 -2
- package/dist/services/session-telemetry.d.ts.map +1 -1
- package/dist/services/storage/file-team-store.d.ts.map +1 -1
- package/dist/services/storage/provider-settings-legacy-migration.d.ts +1 -1
- package/dist/services/storage/provider-settings-legacy-migration.d.ts.map +1 -1
- package/dist/services/storage/provider-settings-manager.d.ts +1 -0
- package/dist/services/storage/provider-settings-manager.d.ts.map +1 -1
- package/dist/services/storage/sqlite-team-store.d.ts.map +1 -1
- package/dist/services/workspace-manifest.d.ts +11 -0
- package/dist/services/workspace-manifest.d.ts.map +1 -1
- package/dist/session/conversation-store.d.ts +30 -0
- package/dist/session/conversation-store.d.ts.map +1 -0
- package/dist/session/message-builder.d.ts +65 -0
- package/dist/session/message-builder.d.ts.map +1 -0
- package/dist/session/persistence-service.d.ts +11 -23
- package/dist/session/persistence-service.d.ts.map +1 -1
- package/dist/session/session-manifest-store.d.ts +22 -0
- package/dist/session/session-manifest-store.d.ts.map +1 -0
- package/dist/session/session-manifest.d.ts +1 -1
- package/dist/session/session-row.d.ts +93 -0
- package/dist/session/session-row.d.ts.map +1 -0
- package/dist/session/session-service.d.ts +2 -102
- package/dist/session/session-service.d.ts.map +1 -1
- package/dist/session/subagent-session-manager.d.ts +36 -0
- package/dist/session/subagent-session-manager.d.ts.map +1 -0
- package/dist/session/team-persistence-store.d.ts +24 -0
- package/dist/session/team-persistence-store.d.ts.map +1 -0
- package/dist/transports/hub.d.ts +58 -0
- package/dist/transports/hub.d.ts.map +1 -0
- package/dist/transports/local.d.ts +23 -9
- package/dist/transports/local.d.ts.map +1 -1
- package/dist/transports/remote.d.ts +10 -0
- package/dist/transports/remote.d.ts.map +1 -0
- package/dist/transports/runtime-host-support.d.ts +3 -2
- package/dist/transports/runtime-host-support.d.ts.map +1 -1
- package/dist/types/chat-schema.d.ts +15 -17
- package/dist/types/chat-schema.d.ts.map +1 -1
- package/dist/types/config.d.ts +17 -7
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/events.d.ts +7 -6
- package/dist/types/events.d.ts.map +1 -1
- package/dist/types/provider-settings.d.ts +4 -5
- package/dist/types/provider-settings.d.ts.map +1 -1
- package/dist/types/session.d.ts +7 -3
- package/dist/types/session.d.ts.map +1 -1
- package/dist/types.d.ts +11 -4
- package/dist/types.d.ts.map +1 -1
- package/package.json +20 -6
- package/src/ClineCore.ts +757 -44
- package/src/account/cline-account-service.ts +44 -6
- package/src/account/index.ts +3 -3
- package/src/account/rpc.ts +12 -12
- package/src/cron/cron-event-ingress.ts +357 -0
- package/src/cron/cron-materializer.ts +97 -0
- package/src/cron/cron-reconciler.ts +241 -0
- package/src/cron/cron-report-writer.ts +153 -0
- package/src/cron/cron-runner.ts +495 -0
- package/src/cron/cron-schema.ts +127 -0
- package/src/cron/cron-service.ts +163 -0
- package/src/cron/cron-spec-parser.ts +489 -0
- package/src/cron/cron-watcher.ts +102 -0
- package/src/cron/index.ts +15 -0
- package/src/cron/resource-limiter.ts +46 -0
- package/src/cron/schedule-command-service.ts +193 -0
- package/src/cron/schedule-service.ts +703 -0
- package/src/cron/scheduler.ts +772 -0
- package/src/cron/sqlite-cron-store.ts +1286 -0
- package/src/cron/sqlite-schedule-store.ts +708 -0
- package/src/extensions/config/agent-config-loader.ts +17 -7
- package/src/extensions/config/runtime-commands.ts +6 -0
- package/src/extensions/config/user-instruction-config-loader.ts +1 -0
- package/src/extensions/context/agentic-compaction.ts +3 -3
- package/src/extensions/context/basic-compaction.ts +2 -2
- package/src/extensions/context/compaction-shared.ts +5 -4
- package/src/extensions/context/compaction.ts +3 -3
- package/src/extensions/plugin/plugin-config-loader.ts +37 -2
- package/src/extensions/plugin/plugin-loader.ts +69 -9
- package/src/extensions/plugin/plugin-module-import.ts +0 -2
- package/src/extensions/plugin/plugin-sandbox-bootstrap.ts +243 -39
- package/src/extensions/plugin/plugin-sandbox.ts +173 -29
- package/src/extensions/plugin/plugin-targeting.ts +32 -0
- package/src/extensions/tools/constants.ts +2 -0
- package/src/extensions/tools/definitions.ts +61 -71
- package/src/extensions/tools/executors/apply-patch.ts +69 -80
- package/src/extensions/tools/executors/editor.ts +4 -3
- package/src/extensions/tools/executors/search.ts +195 -3
- package/src/extensions/tools/helpers.ts +24 -0
- package/src/extensions/tools/index.ts +11 -2
- package/src/extensions/tools/presets.ts +32 -47
- package/src/extensions/tools/runtime.ts +261 -0
- package/src/extensions/tools/schemas.ts +17 -20
- package/src/extensions/tools/team/delegated-agent.ts +8 -3
- package/src/extensions/tools/team/multi-agent.ts +135 -19
- package/src/extensions/tools/team/team-tools.ts +172 -91
- package/src/extensions/tools/types.ts +0 -6
- package/src/hooks/hook-bridge.ts +489 -0
- package/src/hooks/hook-file-hooks.ts +66 -5
- package/src/hooks/hook-registry.ts +257 -0
- package/src/hooks/index.ts +0 -7
- package/src/hooks/subprocess-runner.ts +1 -1
- package/src/hooks/subprocess.ts +9 -0
- package/src/hub/browser-websocket.ts +159 -0
- package/src/hub/client.ts +633 -0
- package/src/hub/connect.ts +156 -0
- package/src/hub/daemon-entry.ts +122 -0
- package/src/hub/daemon.ts +284 -0
- package/src/hub/defaults.ts +70 -0
- package/src/hub/discovery.ts +247 -0
- package/src/hub/index.ts +14 -0
- package/src/hub/native-transport.ts +31 -0
- package/src/hub/runtime-handlers.ts +141 -0
- package/src/hub/server.ts +2317 -0
- package/src/hub/session-client.ts +502 -0
- package/src/hub/start-shared-server.ts +61 -0
- package/src/hub/transport.ts +14 -0
- package/src/hub/ui-client.ts +126 -0
- package/src/hub/workspace.ts +19 -0
- package/src/index.ts +169 -68
- package/src/llms/cline-recommended-models.ts +167 -0
- package/src/llms/configured-provider-registry.ts +193 -0
- package/src/llms/handler-factory.ts +56 -0
- package/src/llms/provider-defaults.ts +653 -0
- package/src/llms/provider-settings.ts +310 -0
- package/src/llms/runtime-config.ts +43 -0
- package/src/llms/runtime-registry.ts +172 -0
- package/src/llms/runtime-types.ts +121 -0
- package/src/runtime/agent-config-adapter.ts +636 -0
- package/src/runtime/agent-runtime-config-builder.ts +205 -0
- package/src/runtime/error-feedback.ts +142 -0
- package/src/runtime/history.ts +137 -0
- package/src/runtime/host.ts +127 -267
- package/src/runtime/index.ts +1 -0
- package/src/runtime/loop-detection.ts +162 -0
- package/src/runtime/mistake-tracker.ts +221 -0
- package/src/runtime/rules.ts +12 -0
- package/src/runtime/runtime-builder.ts +85 -13
- package/src/runtime/runtime-event-adapter.ts +412 -0
- package/src/runtime/runtime-host.ts +134 -62
- package/src/runtime/runtime-oauth-token-manager.ts +11 -15
- package/src/runtime/session-runtime-orchestrator.ts +1253 -0
- package/src/runtime/session-runtime.ts +16 -26
- package/src/runtime/user-input-builder.ts +167 -0
- package/src/services/global-settings.ts +122 -0
- package/src/services/local-runtime-bootstrap.ts +175 -31
- package/src/services/plugin-tools.ts +86 -0
- package/src/services/providers/local-provider-registry.ts +277 -61
- package/src/services/providers/local-provider-service.ts +109 -44
- package/src/services/session-data.ts +18 -10
- package/src/services/session-telemetry.ts +6 -15
- package/src/services/storage/file-team-store.ts +1 -5
- package/src/services/storage/provider-settings-legacy-migration.ts +14 -51
- package/src/services/storage/provider-settings-manager.ts +17 -2
- package/src/services/storage/sqlite-team-store.ts +1 -5
- package/src/services/workspace-manifest.ts +18 -0
- package/src/session/conversation-store.ts +77 -0
- package/src/session/file-session-service.ts +1 -1
- package/src/session/index.ts +6 -27
- package/src/session/message-builder.ts +941 -0
- package/src/session/persistence-service.ts +119 -504
- package/src/session/session-manifest-store.ts +158 -0
- package/src/session/session-row.ts +199 -0
- package/src/session/session-service.ts +17 -376
- package/src/session/session-team-coordination.ts +1 -1
- package/src/session/subagent-session-manager.ts +397 -0
- package/src/session/team-persistence-store.ts +176 -0
- package/src/transports/hub.ts +1081 -0
- package/src/transports/local.ts +419 -93
- package/src/transports/remote.ts +27 -0
- package/src/transports/runtime-host-support.ts +63 -9
- package/src/types/chat-schema.ts +4 -5
- package/src/types/config.ts +17 -7
- package/src/types/events.ts +8 -6
- package/src/types/index.ts +3 -0
- package/src/types/provider-settings.ts +18 -7
- package/src/types/session.ts +7 -6
- package/src/types.ts +42 -2
- package/dist/hooks/persistent.d.ts +0 -64
- package/dist/hooks/persistent.d.ts.map +0 -1
- package/dist/runtime/rpc-runtime-ensure.d.ts +0 -65
- package/dist/runtime/rpc-runtime-ensure.d.ts.map +0 -1
- package/dist/runtime/rpc-spawn-lease.d.ts +0 -8
- package/dist/runtime/rpc-spawn-lease.d.ts.map +0 -1
- package/dist/services/telemetry/index.js +0 -15
- package/dist/session/rpc-session-service.d.ts +0 -16
- package/dist/session/rpc-session-service.d.ts.map +0 -1
- package/dist/session/sqlite-rpc-session-backend.d.ts +0 -31
- package/dist/session/sqlite-rpc-session-backend.d.ts.map +0 -1
- package/dist/transports/rpc.d.ts +0 -51
- package/dist/transports/rpc.d.ts.map +0 -1
- package/src/ClineCore.test.ts +0 -226
- package/src/account/cline-account-service.test.ts +0 -185
- package/src/account/featurebase-token.test.ts +0 -175
- package/src/account/rpc.test.ts +0 -63
- package/src/auth/bounded-ttl-cache.test.ts +0 -38
- package/src/auth/client.test.ts +0 -69
- package/src/auth/cline.test.ts +0 -267
- package/src/auth/codex.test.ts +0 -170
- package/src/auth/oca.test.ts +0 -340
- package/src/auth/server.test.ts +0 -287
- package/src/auth/utils.test.ts +0 -128
- package/src/extensions/config/agent-config-loader.test.ts +0 -236
- package/src/extensions/config/hooks-config-loader.test.ts +0 -20
- package/src/extensions/config/runtime-commands.test.ts +0 -115
- package/src/extensions/config/unified-config-file-watcher.test.ts +0 -196
- package/src/extensions/config/user-instruction-config-loader.test.ts +0 -246
- package/src/extensions/context/compaction.test.ts +0 -483
- package/src/extensions/mcp/config-loader.test.ts +0 -238
- package/src/extensions/mcp/manager.test.ts +0 -105
- package/src/extensions/plugin/plugin-config-loader.test.ts +0 -184
- package/src/extensions/plugin/plugin-loader.test.ts +0 -292
- package/src/extensions/plugin/plugin-sandbox.test.ts +0 -423
- package/src/extensions/tools/definitions.test.ts +0 -780
- package/src/extensions/tools/executors/bash.test.ts +0 -87
- package/src/extensions/tools/executors/editor.test.ts +0 -35
- package/src/extensions/tools/executors/file-read.test.ts +0 -125
- package/src/extensions/tools/model-tool-routing.test.ts +0 -86
- package/src/extensions/tools/presets.test.ts +0 -70
- package/src/extensions/tools/team/multi-agent.lifecycle.test.ts +0 -455
- package/src/extensions/tools/team/spawn-agent-tool.test.ts +0 -381
- package/src/extensions/tools/team/team-tools.test.ts +0 -918
- package/src/hooks/checkpoint-hooks.test.ts +0 -168
- package/src/hooks/hook-file-hooks.test.ts +0 -311
- package/src/hooks/persistent.ts +0 -661
- package/src/runtime/history.test.ts +0 -114
- package/src/runtime/host.test.ts +0 -230
- package/src/runtime/rpc-runtime-ensure.test.ts +0 -123
- package/src/runtime/rpc-runtime-ensure.ts +0 -659
- package/src/runtime/rpc-spawn-lease.test.ts +0 -81
- package/src/runtime/rpc-spawn-lease.ts +0 -156
- package/src/runtime/runtime-builder.team-persistence.test.ts +0 -245
- package/src/runtime/runtime-builder.test.ts +0 -615
- package/src/runtime/runtime-oauth-token-manager.test.ts +0 -137
- package/src/runtime/runtime-parity.test.ts +0 -143
- package/src/services/providers/local-provider-service.test.ts +0 -1062
- package/src/services/session-data.test.ts +0 -160
- package/src/services/storage/provider-settings-legacy-migration.test.ts +0 -424
- package/src/services/storage/provider-settings-manager.test.ts +0 -191
- package/src/services/telemetry/OpenTelemetryAdapter.test.ts +0 -157
- package/src/services/telemetry/OpenTelemetryProvider.test.ts +0 -326
- package/src/services/telemetry/TelemetryLoggerSink.test.ts +0 -42
- package/src/services/telemetry/TelemetryService.test.ts +0 -134
- package/src/services/telemetry/distinct-id.test.ts +0 -57
- package/src/services/workspace/file-indexer.d.ts +0 -11
- package/src/services/workspace/file-indexer.test.ts +0 -156
- package/src/services/workspace/mention-enricher.test.ts +0 -106
- package/src/session/persistence-service.test.ts +0 -300
- package/src/session/rpc-session-service.ts +0 -114
- package/src/session/session-service.team-persistence.test.ts +0 -48
- package/src/session/sqlite-rpc-session-backend.ts +0 -301
- package/src/transports/local.e2e.test.ts +0 -380
- package/src/transports/local.test.ts +0 -2559
- package/src/transports/rpc.test.ts +0 -82
- package/src/transports/rpc.ts +0 -665
|
@@ -0,0 +1,495 @@
|
|
|
1
|
+
import { basename } from "node:path";
|
|
2
|
+
import type {
|
|
3
|
+
BasicLogger,
|
|
4
|
+
ChatRunTurnRequest,
|
|
5
|
+
ChatStartSessionRequest,
|
|
6
|
+
} from "@clinebot/shared";
|
|
7
|
+
import { buildClineSystemPrompt } from "@clinebot/shared";
|
|
8
|
+
import { nowIso } from "@clinebot/shared/db";
|
|
9
|
+
import type { ResolveCronSpecsDirOptions } from "@clinebot/shared/storage";
|
|
10
|
+
import { createUserInstructionConfigWatcher } from "../extensions/config";
|
|
11
|
+
import { DefaultToolNames } from "../extensions/tools/constants";
|
|
12
|
+
import {
|
|
13
|
+
loadRulesForSystemPromptFromWatcher,
|
|
14
|
+
mergeRulesForSystemPrompt,
|
|
15
|
+
} from "../runtime/rules";
|
|
16
|
+
import { buildWorkspaceMetadata } from "../services/workspace-manifest";
|
|
17
|
+
import type { CronMaterializer } from "./cron-materializer";
|
|
18
|
+
import { writeCronRunReport } from "./cron-report-writer";
|
|
19
|
+
import { ResourceLimiter } from "./resource-limiter";
|
|
20
|
+
import type { HubScheduleRuntimeHandlers } from "./schedule-service";
|
|
21
|
+
import type {
|
|
22
|
+
ClaimedCronRun,
|
|
23
|
+
CronEventLogRecord,
|
|
24
|
+
CronSpecRecord,
|
|
25
|
+
SqliteCronStore,
|
|
26
|
+
} from "./sqlite-cron-store";
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Trigger-agnostic runner for queued cron runs.
|
|
30
|
+
*
|
|
31
|
+
* Polls cron.db every N seconds, atomically claims queued runs, executes
|
|
32
|
+
* them through the existing runtime handlers (same surface used by the
|
|
33
|
+
* legacy `HubScheduleService`), persists status transitions transactionally,
|
|
34
|
+
* and writes a markdown report per completion/failure.
|
|
35
|
+
*/
|
|
36
|
+
|
|
37
|
+
const DEFAULT_POLL_INTERVAL_MS = 15_000;
|
|
38
|
+
const DEFAULT_CLAIM_LEASE_SECONDS = 90;
|
|
39
|
+
const DEFAULT_CRON_EXTENSIONS = ["rules", "skills", "plugins"] as const;
|
|
40
|
+
|
|
41
|
+
interface HubTurnResult {
|
|
42
|
+
text: string;
|
|
43
|
+
usage?: {
|
|
44
|
+
inputTokens?: number;
|
|
45
|
+
outputTokens?: number;
|
|
46
|
+
cacheReadTokens?: number;
|
|
47
|
+
cacheWriteTokens?: number;
|
|
48
|
+
totalCost?: number;
|
|
49
|
+
};
|
|
50
|
+
toolCalls?: Array<{
|
|
51
|
+
name: string;
|
|
52
|
+
error?: string;
|
|
53
|
+
durationMs?: number;
|
|
54
|
+
}>;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function cronExtensionEnabled(
|
|
58
|
+
spec: CronSpecRecord,
|
|
59
|
+
extension: (typeof DEFAULT_CRON_EXTENSIONS)[number],
|
|
60
|
+
): boolean {
|
|
61
|
+
return new Set(spec.extensions ?? DEFAULT_CRON_EXTENSIONS).has(extension);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function buildToolPolicies(
|
|
65
|
+
spec: CronSpecRecord,
|
|
66
|
+
mode: "act" | "plan" | "yolo",
|
|
67
|
+
): ChatStartSessionRequest["toolPolicies"] | undefined {
|
|
68
|
+
if (spec.tools === undefined) {
|
|
69
|
+
return { "*": { autoApprove: true } };
|
|
70
|
+
}
|
|
71
|
+
const policies: NonNullable<ChatStartSessionRequest["toolPolicies"]> = {
|
|
72
|
+
"*": { enabled: false, autoApprove: true },
|
|
73
|
+
};
|
|
74
|
+
for (const tool of spec.tools) {
|
|
75
|
+
policies[tool] = { enabled: true, autoApprove: true };
|
|
76
|
+
}
|
|
77
|
+
if (mode === "yolo") {
|
|
78
|
+
policies[DefaultToolNames.SUBMIT_AND_EXIT] = {
|
|
79
|
+
enabled: true,
|
|
80
|
+
autoApprove: true,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
return policies;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function buildNotesSystemPromptSection(
|
|
87
|
+
notesDirectory: string | undefined,
|
|
88
|
+
): string | undefined {
|
|
89
|
+
const trimmed = notesDirectory?.trim();
|
|
90
|
+
if (!trimmed) return undefined;
|
|
91
|
+
return [
|
|
92
|
+
"# Notes Directory",
|
|
93
|
+
`Use ${trimmed} for durable notes related to this automation.`,
|
|
94
|
+
"Before starting, inspect relevant existing notes there when useful. During or after the run, write concise notes there when they would help future runs continue with context.",
|
|
95
|
+
].join("\n");
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
class TimeoutError extends Error {
|
|
99
|
+
constructor(message: string) {
|
|
100
|
+
super(message);
|
|
101
|
+
this.name = "TimeoutError";
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
async function withTimeout<T>(
|
|
106
|
+
promise: Promise<T>,
|
|
107
|
+
timeoutMs: number,
|
|
108
|
+
): Promise<T> {
|
|
109
|
+
if (timeoutMs <= 0) return promise;
|
|
110
|
+
let handle: ReturnType<typeof setTimeout> | undefined;
|
|
111
|
+
const timeoutPromise = new Promise<never>((_, reject) => {
|
|
112
|
+
handle = setTimeout(() => {
|
|
113
|
+
reject(new TimeoutError("cron run timed out"));
|
|
114
|
+
}, timeoutMs);
|
|
115
|
+
});
|
|
116
|
+
try {
|
|
117
|
+
return await Promise.race([promise, timeoutPromise]);
|
|
118
|
+
} finally {
|
|
119
|
+
if (handle) clearTimeout(handle);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export interface CronRunnerOptions {
|
|
124
|
+
store: SqliteCronStore;
|
|
125
|
+
materializer: CronMaterializer;
|
|
126
|
+
runtimeHandlers: HubScheduleRuntimeHandlers;
|
|
127
|
+
/** Default runtime workspace for the hub/daemon process. */
|
|
128
|
+
workspaceRoot: string;
|
|
129
|
+
/** Cron spec source/report location. Defaults to global `~/.cline/cron`. */
|
|
130
|
+
specs?: ResolveCronSpecsDirOptions;
|
|
131
|
+
logger?: BasicLogger;
|
|
132
|
+
pollIntervalMs?: number;
|
|
133
|
+
claimLeaseSeconds?: number;
|
|
134
|
+
globalMaxConcurrency?: number;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export class CronRunner {
|
|
138
|
+
private readonly store: SqliteCronStore;
|
|
139
|
+
private readonly materializer: CronMaterializer;
|
|
140
|
+
private readonly options: CronRunnerOptions;
|
|
141
|
+
private readonly limiter: ResourceLimiter;
|
|
142
|
+
private readonly claimLeaseMs: number;
|
|
143
|
+
private timer: ReturnType<typeof setInterval> | undefined;
|
|
144
|
+
private started = false;
|
|
145
|
+
private ticking = false;
|
|
146
|
+
private disposed = false;
|
|
147
|
+
private stopping = false;
|
|
148
|
+
private readonly activeRuns = new Map<
|
|
149
|
+
string,
|
|
150
|
+
{ claimToken: string; sessionId?: string }
|
|
151
|
+
>();
|
|
152
|
+
|
|
153
|
+
constructor(options: CronRunnerOptions) {
|
|
154
|
+
this.store = options.store;
|
|
155
|
+
this.materializer = options.materializer;
|
|
156
|
+
this.options = options;
|
|
157
|
+
this.limiter = new ResourceLimiter(options.globalMaxConcurrency ?? 10);
|
|
158
|
+
this.claimLeaseMs = Math.max(
|
|
159
|
+
5_000,
|
|
160
|
+
(options.claimLeaseSeconds ?? DEFAULT_CLAIM_LEASE_SECONDS) * 1000,
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
public async start(): Promise<void> {
|
|
165
|
+
if (this.disposed) throw new Error("CronRunner disposed");
|
|
166
|
+
if (this.started) return;
|
|
167
|
+
this.stopping = false;
|
|
168
|
+
this.started = true;
|
|
169
|
+
const interval = Math.max(
|
|
170
|
+
2_000,
|
|
171
|
+
this.options.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS,
|
|
172
|
+
);
|
|
173
|
+
await this.tick();
|
|
174
|
+
this.timer = setInterval(() => void this.tick(), interval);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
public async stop(): Promise<void> {
|
|
178
|
+
const wasStarted = this.started;
|
|
179
|
+
this.started = false;
|
|
180
|
+
this.stopping = true;
|
|
181
|
+
if (this.timer) {
|
|
182
|
+
clearInterval(this.timer);
|
|
183
|
+
this.timer = undefined;
|
|
184
|
+
}
|
|
185
|
+
if (!wasStarted) return;
|
|
186
|
+
const active = [...this.activeRuns.entries()];
|
|
187
|
+
await Promise.all(
|
|
188
|
+
active.map(async ([runId, run]) => {
|
|
189
|
+
if (run.sessionId) {
|
|
190
|
+
try {
|
|
191
|
+
await this.options.runtimeHandlers.abortSession(run.sessionId);
|
|
192
|
+
} catch {
|
|
193
|
+
// best effort
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
try {
|
|
197
|
+
this.store.requeueRun({
|
|
198
|
+
runId,
|
|
199
|
+
claimToken: run.claimToken,
|
|
200
|
+
error: "runner stopped before completion",
|
|
201
|
+
});
|
|
202
|
+
} catch {
|
|
203
|
+
// best effort
|
|
204
|
+
}
|
|
205
|
+
}),
|
|
206
|
+
);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
public async dispose(): Promise<void> {
|
|
210
|
+
if (this.disposed) return;
|
|
211
|
+
this.disposed = true;
|
|
212
|
+
await this.stop();
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
public async tick(): Promise<void> {
|
|
216
|
+
if (this.ticking) return;
|
|
217
|
+
this.ticking = true;
|
|
218
|
+
try {
|
|
219
|
+
this.materializer.materializeAll();
|
|
220
|
+
const claims = this.store.claimDueRuns({
|
|
221
|
+
nowIso: nowIso(),
|
|
222
|
+
leaseMs: this.claimLeaseMs,
|
|
223
|
+
});
|
|
224
|
+
await Promise.allSettled(claims.map((claim) => this.executeClaim(claim)));
|
|
225
|
+
} catch (err) {
|
|
226
|
+
const log = this.options.logger;
|
|
227
|
+
if (log) {
|
|
228
|
+
if (log.error) log.error("cron.runner.tick.failed", { error: err });
|
|
229
|
+
else log.log("cron.runner.tick.failed", { error: err });
|
|
230
|
+
}
|
|
231
|
+
} finally {
|
|
232
|
+
this.ticking = false;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
private async executeClaim(claim: ClaimedCronRun): Promise<void> {
|
|
237
|
+
const run = claim.run;
|
|
238
|
+
const spec = this.store.getSpec(run.specId);
|
|
239
|
+
if (!spec) {
|
|
240
|
+
this.store.completeRun(run.runId, {
|
|
241
|
+
status: "failed",
|
|
242
|
+
error: "spec not found",
|
|
243
|
+
claimToken: claim.claimToken,
|
|
244
|
+
});
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
if (!spec.enabled || spec.removed) {
|
|
248
|
+
this.store.completeRun(run.runId, {
|
|
249
|
+
status: "cancelled",
|
|
250
|
+
error: "spec disabled or removed",
|
|
251
|
+
claimToken: claim.claimToken,
|
|
252
|
+
});
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
const maxParallel =
|
|
257
|
+
spec.maxParallel && spec.maxParallel > 0 ? spec.maxParallel : 1;
|
|
258
|
+
const acquired = this.limiter.acquire(spec.specId, run.runId, maxParallel);
|
|
259
|
+
if (!acquired) {
|
|
260
|
+
this.store.requeueRun({
|
|
261
|
+
runId: run.runId,
|
|
262
|
+
claimToken: claim.claimToken,
|
|
263
|
+
error: "concurrency limit reached",
|
|
264
|
+
});
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
if (this.stopping) {
|
|
268
|
+
this.limiter.release(spec.specId, run.runId);
|
|
269
|
+
this.store.requeueRun({
|
|
270
|
+
runId: run.runId,
|
|
271
|
+
claimToken: claim.claimToken,
|
|
272
|
+
error: "runner stopped before execution",
|
|
273
|
+
});
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
this.activeRuns.set(run.runId, { claimToken: claim.claimToken });
|
|
278
|
+
const triggerEvent = run.triggerEventId
|
|
279
|
+
? this.store.getEventLog(run.triggerEventId)
|
|
280
|
+
: undefined;
|
|
281
|
+
let sessionId: string | undefined;
|
|
282
|
+
let releaseLeaseHeartbeat: (() => void) | undefined;
|
|
283
|
+
const startMs = Date.now();
|
|
284
|
+
let executionDeadlineMs: number | undefined;
|
|
285
|
+
if (spec.timeoutSeconds && spec.timeoutSeconds > 0) {
|
|
286
|
+
executionDeadlineMs = startMs + spec.timeoutSeconds * 1000;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
try {
|
|
290
|
+
releaseLeaseHeartbeat = this.startClaimLeaseHeartbeat(claim);
|
|
291
|
+
const startRequest = await this.buildStartRequest(spec);
|
|
292
|
+
const startResp =
|
|
293
|
+
await this.options.runtimeHandlers.startSession(startRequest);
|
|
294
|
+
sessionId = startResp.sessionId.trim();
|
|
295
|
+
if (!sessionId) throw new Error("runtime returned empty sessionId");
|
|
296
|
+
this.activeRuns.set(run.runId, {
|
|
297
|
+
claimToken: claim.claimToken,
|
|
298
|
+
sessionId,
|
|
299
|
+
});
|
|
300
|
+
this.store.attachSessionIdToRun(run.runId, sessionId);
|
|
301
|
+
|
|
302
|
+
const turnRequest: ChatRunTurnRequest = {
|
|
303
|
+
config: startRequest,
|
|
304
|
+
prompt: this.buildPrompt(spec, triggerEvent),
|
|
305
|
+
};
|
|
306
|
+
const sendPromise = this.options.runtimeHandlers.sendSession(
|
|
307
|
+
sessionId,
|
|
308
|
+
turnRequest,
|
|
309
|
+
);
|
|
310
|
+
const timeoutMs = executionDeadlineMs
|
|
311
|
+
? Math.max(1, executionDeadlineMs - Date.now())
|
|
312
|
+
: 0;
|
|
313
|
+
const sendResult = await withTimeout(sendPromise, timeoutMs);
|
|
314
|
+
const result = sendResult.result as HubTurnResult;
|
|
315
|
+
|
|
316
|
+
const endMs = Date.now();
|
|
317
|
+
const reportPath = writeCronRunReport({
|
|
318
|
+
specs: this.options.specs,
|
|
319
|
+
workspaceRoot: this.options.workspaceRoot,
|
|
320
|
+
run: { ...run, sessionId, status: "done" },
|
|
321
|
+
spec,
|
|
322
|
+
data: {
|
|
323
|
+
finalText: result.text,
|
|
324
|
+
usage: result.usage,
|
|
325
|
+
toolCalls: result.toolCalls,
|
|
326
|
+
durationMs: endMs - startMs,
|
|
327
|
+
triggerEvent,
|
|
328
|
+
},
|
|
329
|
+
});
|
|
330
|
+
this.store.completeRun(run.runId, {
|
|
331
|
+
status: "done",
|
|
332
|
+
sessionId,
|
|
333
|
+
reportPath,
|
|
334
|
+
claimToken: claim.claimToken,
|
|
335
|
+
});
|
|
336
|
+
this.store.updateSpecLastRunAt(spec.specId, nowIso());
|
|
337
|
+
} catch (err) {
|
|
338
|
+
const isTimeout = err instanceof TimeoutError;
|
|
339
|
+
if (sessionId && isTimeout) {
|
|
340
|
+
try {
|
|
341
|
+
await this.options.runtimeHandlers.abortSession(sessionId);
|
|
342
|
+
} catch {
|
|
343
|
+
// best effort
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
347
|
+
const endMs = Date.now();
|
|
348
|
+
const reportPath = writeCronRunReport({
|
|
349
|
+
specs: this.options.specs,
|
|
350
|
+
workspaceRoot: this.options.workspaceRoot,
|
|
351
|
+
run: { ...run, sessionId, status: "failed" },
|
|
352
|
+
spec,
|
|
353
|
+
data: { error: message, durationMs: endMs - startMs, triggerEvent },
|
|
354
|
+
});
|
|
355
|
+
this.store.completeRun(run.runId, {
|
|
356
|
+
status: "failed",
|
|
357
|
+
sessionId,
|
|
358
|
+
reportPath,
|
|
359
|
+
error: message,
|
|
360
|
+
claimToken: claim.claimToken,
|
|
361
|
+
});
|
|
362
|
+
} finally {
|
|
363
|
+
releaseLeaseHeartbeat?.();
|
|
364
|
+
if (sessionId) {
|
|
365
|
+
try {
|
|
366
|
+
await this.options.runtimeHandlers.stopSession(sessionId);
|
|
367
|
+
} catch {
|
|
368
|
+
// best effort
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
this.activeRuns.delete(run.runId);
|
|
372
|
+
this.limiter.release(spec.specId, run.runId);
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
private buildPrompt(
|
|
377
|
+
spec: CronSpecRecord,
|
|
378
|
+
triggerEvent: CronEventLogRecord | undefined,
|
|
379
|
+
): string {
|
|
380
|
+
const prompt = spec.prompt ?? "";
|
|
381
|
+
if (!triggerEvent) return prompt;
|
|
382
|
+
const eventContext = {
|
|
383
|
+
eventId: triggerEvent.eventId,
|
|
384
|
+
eventType: triggerEvent.eventType,
|
|
385
|
+
source: triggerEvent.source,
|
|
386
|
+
subject: triggerEvent.subject,
|
|
387
|
+
occurredAt: triggerEvent.occurredAt,
|
|
388
|
+
workspaceRoot: triggerEvent.workspaceRoot,
|
|
389
|
+
dedupeKey: triggerEvent.dedupeKey,
|
|
390
|
+
attributes: triggerEvent.attributes,
|
|
391
|
+
payload: triggerEvent.payload,
|
|
392
|
+
};
|
|
393
|
+
return `${prompt}\n\nTrigger event:\n${JSON.stringify(eventContext, null, 2)}`;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
private startClaimLeaseHeartbeat(claim: ClaimedCronRun): () => void {
|
|
397
|
+
const heartbeatMs = Math.max(1_000, Math.floor(this.claimLeaseMs / 2));
|
|
398
|
+
const interval = setInterval(() => {
|
|
399
|
+
const leaseUntilAt = new Date(
|
|
400
|
+
Date.now() + this.claimLeaseMs,
|
|
401
|
+
).toISOString();
|
|
402
|
+
const renewed = this.store.renewClaim(
|
|
403
|
+
claim.run.runId,
|
|
404
|
+
claim.claimToken,
|
|
405
|
+
leaseUntilAt,
|
|
406
|
+
);
|
|
407
|
+
if (!renewed) {
|
|
408
|
+
clearInterval(interval);
|
|
409
|
+
}
|
|
410
|
+
}, heartbeatMs);
|
|
411
|
+
return () => clearInterval(interval);
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
private async loadRulesForSpec(
|
|
415
|
+
spec: CronSpecRecord,
|
|
416
|
+
): Promise<string | undefined> {
|
|
417
|
+
if (!cronExtensionEnabled(spec, "rules")) return undefined;
|
|
418
|
+
const workspaceRoot = spec.workspaceRoot?.trim();
|
|
419
|
+
if (!workspaceRoot) return undefined;
|
|
420
|
+
const watcher = createUserInstructionConfigWatcher({
|
|
421
|
+
skills: { directories: [] },
|
|
422
|
+
rules: { workspacePath: workspaceRoot },
|
|
423
|
+
workflows: { workspacePath: workspaceRoot },
|
|
424
|
+
});
|
|
425
|
+
try {
|
|
426
|
+
await watcher.start();
|
|
427
|
+
return loadRulesForSystemPromptFromWatcher(watcher);
|
|
428
|
+
} finally {
|
|
429
|
+
watcher.stop();
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
private async buildSystemPrompt(
|
|
434
|
+
spec: CronSpecRecord,
|
|
435
|
+
workspaceRoot: string,
|
|
436
|
+
mode: "act" | "plan" | "yolo",
|
|
437
|
+
provider: string,
|
|
438
|
+
): Promise<string> {
|
|
439
|
+
const rules = await this.loadRulesForSpec(spec);
|
|
440
|
+
const notes = buildNotesSystemPromptSection(spec.notesDirectory);
|
|
441
|
+
const additional = mergeRulesForSystemPrompt(rules, notes);
|
|
442
|
+
const metadata = await buildWorkspaceMetadata(workspaceRoot);
|
|
443
|
+
const base = buildClineSystemPrompt({
|
|
444
|
+
ide: "Cline Cron",
|
|
445
|
+
workspaceRoot,
|
|
446
|
+
workspaceName: basename(workspaceRoot),
|
|
447
|
+
metadata,
|
|
448
|
+
rules: spec.systemPrompt ? undefined : additional,
|
|
449
|
+
mode,
|
|
450
|
+
providerId: provider,
|
|
451
|
+
overridePrompt: spec.systemPrompt,
|
|
452
|
+
platform:
|
|
453
|
+
(typeof process !== "undefined" && process?.platform) || "unknown",
|
|
454
|
+
});
|
|
455
|
+
return spec.systemPrompt
|
|
456
|
+
? (mergeRulesForSystemPrompt(base, additional) ?? base)
|
|
457
|
+
: base;
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
private async buildStartRequest(
|
|
461
|
+
spec: CronSpecRecord,
|
|
462
|
+
): Promise<ChatStartSessionRequest> {
|
|
463
|
+
const workspaceRoot = (spec.workspaceRoot ?? "").trim();
|
|
464
|
+
const provider = (spec.providerId ?? "").trim();
|
|
465
|
+
const model = (spec.modelId ?? "").trim();
|
|
466
|
+
if (!workspaceRoot) {
|
|
467
|
+
throw new Error("cron spec requires workspaceRoot");
|
|
468
|
+
}
|
|
469
|
+
const mode =
|
|
470
|
+
spec.mode === "plan" ? "plan" : spec.mode === "act" ? "act" : "yolo";
|
|
471
|
+
return {
|
|
472
|
+
workspaceRoot,
|
|
473
|
+
cwd: workspaceRoot,
|
|
474
|
+
provider,
|
|
475
|
+
model,
|
|
476
|
+
mode,
|
|
477
|
+
source: spec.source?.trim() || "user",
|
|
478
|
+
systemPrompt: await this.buildSystemPrompt(
|
|
479
|
+
spec,
|
|
480
|
+
workspaceRoot,
|
|
481
|
+
mode,
|
|
482
|
+
provider,
|
|
483
|
+
),
|
|
484
|
+
maxIterations: spec.maxIterations,
|
|
485
|
+
enableTools: true,
|
|
486
|
+
enableSpawn: true,
|
|
487
|
+
enableTeams: true,
|
|
488
|
+
autoApproveTools: true,
|
|
489
|
+
toolPolicies: buildToolPolicies(spec, mode),
|
|
490
|
+
configExtensions: DEFAULT_CRON_EXTENSIONS.filter((extension) =>
|
|
491
|
+
cronExtensionEnabled(spec, extension),
|
|
492
|
+
),
|
|
493
|
+
};
|
|
494
|
+
}
|
|
495
|
+
}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import type { SqliteDb } from "@clinebot/shared/db";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Bootstrap the dedicated cron.db schema. Unlike @clinebot/shared's
|
|
5
|
+
* `ensureSessionSchema`, this schema is fully owned by @clinebot/core
|
|
6
|
+
* because cron lifecycle (specs, runs, reports) is a core concern and
|
|
7
|
+
* should not be coupled to session storage.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
const CRON_SCHEMA_STATEMENTS: readonly string[] = [
|
|
11
|
+
`CREATE TABLE IF NOT EXISTS cron_specs (
|
|
12
|
+
spec_id TEXT PRIMARY KEY,
|
|
13
|
+
external_id TEXT NOT NULL,
|
|
14
|
+
source_path TEXT NOT NULL UNIQUE,
|
|
15
|
+
trigger_kind TEXT NOT NULL CHECK (trigger_kind IN ('one_off', 'schedule', 'event')),
|
|
16
|
+
source_mtime_ms INTEGER,
|
|
17
|
+
source_hash TEXT,
|
|
18
|
+
parse_status TEXT NOT NULL CHECK (parse_status IN ('valid', 'invalid')),
|
|
19
|
+
parse_error TEXT,
|
|
20
|
+
enabled INTEGER NOT NULL DEFAULT 1,
|
|
21
|
+
removed INTEGER NOT NULL DEFAULT 0,
|
|
22
|
+
title TEXT NOT NULL,
|
|
23
|
+
prompt TEXT,
|
|
24
|
+
workspace_root TEXT,
|
|
25
|
+
schedule_expr TEXT,
|
|
26
|
+
timezone TEXT,
|
|
27
|
+
event_type TEXT,
|
|
28
|
+
filters_json TEXT,
|
|
29
|
+
debounce_seconds INTEGER,
|
|
30
|
+
dedupe_window_seconds INTEGER,
|
|
31
|
+
cooldown_seconds INTEGER,
|
|
32
|
+
mode TEXT,
|
|
33
|
+
system_prompt TEXT,
|
|
34
|
+
provider_id TEXT,
|
|
35
|
+
model_id TEXT,
|
|
36
|
+
max_iterations INTEGER,
|
|
37
|
+
timeout_seconds INTEGER,
|
|
38
|
+
max_parallel INTEGER,
|
|
39
|
+
tools_json TEXT,
|
|
40
|
+
notes_directory TEXT,
|
|
41
|
+
extensions_json TEXT,
|
|
42
|
+
source TEXT,
|
|
43
|
+
tags_json TEXT,
|
|
44
|
+
metadata_json TEXT,
|
|
45
|
+
revision INTEGER NOT NULL DEFAULT 1,
|
|
46
|
+
last_materialized_run_id TEXT,
|
|
47
|
+
last_run_at TEXT,
|
|
48
|
+
next_run_at TEXT,
|
|
49
|
+
created_at TEXT NOT NULL,
|
|
50
|
+
updated_at TEXT NOT NULL
|
|
51
|
+
);`,
|
|
52
|
+
`CREATE TABLE IF NOT EXISTS cron_runs (
|
|
53
|
+
run_id TEXT PRIMARY KEY,
|
|
54
|
+
spec_id TEXT NOT NULL REFERENCES cron_specs(spec_id) ON DELETE CASCADE,
|
|
55
|
+
spec_revision INTEGER NOT NULL,
|
|
56
|
+
trigger_kind TEXT NOT NULL CHECK (trigger_kind IN ('one_off', 'schedule', 'event', 'manual', 'retry')),
|
|
57
|
+
status TEXT NOT NULL CHECK (status IN ('queued', 'running', 'done', 'failed', 'cancelled')),
|
|
58
|
+
claim_token TEXT,
|
|
59
|
+
claim_started_at TEXT,
|
|
60
|
+
claim_until_at TEXT,
|
|
61
|
+
scheduled_for TEXT,
|
|
62
|
+
trigger_event_id TEXT,
|
|
63
|
+
started_at TEXT,
|
|
64
|
+
completed_at TEXT,
|
|
65
|
+
session_id TEXT,
|
|
66
|
+
report_path TEXT,
|
|
67
|
+
error TEXT,
|
|
68
|
+
attempt_count INTEGER NOT NULL DEFAULT 0,
|
|
69
|
+
created_at TEXT NOT NULL,
|
|
70
|
+
updated_at TEXT NOT NULL
|
|
71
|
+
);`,
|
|
72
|
+
`CREATE TABLE IF NOT EXISTS cron_event_log (
|
|
73
|
+
event_id TEXT PRIMARY KEY,
|
|
74
|
+
event_type TEXT NOT NULL,
|
|
75
|
+
source TEXT NOT NULL,
|
|
76
|
+
subject TEXT,
|
|
77
|
+
occurred_at TEXT NOT NULL,
|
|
78
|
+
received_at TEXT NOT NULL,
|
|
79
|
+
workspace_root TEXT,
|
|
80
|
+
dedupe_key TEXT,
|
|
81
|
+
payload_json TEXT,
|
|
82
|
+
attributes_json TEXT,
|
|
83
|
+
processing_status TEXT NOT NULL DEFAULT 'received'
|
|
84
|
+
CHECK (processing_status IN ('received', 'unmatched', 'queued', 'suppressed', 'failed')),
|
|
85
|
+
matched_spec_count INTEGER NOT NULL DEFAULT 0,
|
|
86
|
+
queued_run_count INTEGER NOT NULL DEFAULT 0,
|
|
87
|
+
suppressed_count INTEGER NOT NULL DEFAULT 0,
|
|
88
|
+
error TEXT,
|
|
89
|
+
created_at TEXT NOT NULL,
|
|
90
|
+
updated_at TEXT NOT NULL
|
|
91
|
+
);`,
|
|
92
|
+
`DROP INDEX IF EXISTS cron_runs_one_off_active_idx;`,
|
|
93
|
+
`CREATE UNIQUE INDEX IF NOT EXISTS cron_runs_one_off_active_idx
|
|
94
|
+
ON cron_runs(spec_id, spec_revision)
|
|
95
|
+
WHERE trigger_kind = 'one_off';`,
|
|
96
|
+
`CREATE INDEX IF NOT EXISTS cron_runs_claimable_idx
|
|
97
|
+
ON cron_runs(status, scheduled_for, claim_until_at);`,
|
|
98
|
+
`CREATE INDEX IF NOT EXISTS cron_runs_spec_idx
|
|
99
|
+
ON cron_runs(spec_id, created_at DESC);`,
|
|
100
|
+
`CREATE INDEX IF NOT EXISTS cron_runs_trigger_event_idx
|
|
101
|
+
ON cron_runs(trigger_event_id);`,
|
|
102
|
+
`CREATE INDEX IF NOT EXISTS cron_runs_event_spec_status_idx
|
|
103
|
+
ON cron_runs(spec_id, trigger_kind, status, scheduled_for);`,
|
|
104
|
+
`CREATE INDEX IF NOT EXISTS cron_event_log_type_idx
|
|
105
|
+
ON cron_event_log(event_type, received_at DESC);`,
|
|
106
|
+
`CREATE INDEX IF NOT EXISTS cron_event_log_received_idx
|
|
107
|
+
ON cron_event_log(received_at DESC);`,
|
|
108
|
+
`CREATE INDEX IF NOT EXISTS cron_event_log_dedupe_idx
|
|
109
|
+
ON cron_event_log(event_type, source, dedupe_key, received_at DESC);`,
|
|
110
|
+
`CREATE INDEX IF NOT EXISTS cron_specs_next_run_idx
|
|
111
|
+
ON cron_specs(trigger_kind, enabled, next_run_at);`,
|
|
112
|
+
`CREATE INDEX IF NOT EXISTS cron_specs_event_match_idx
|
|
113
|
+
ON cron_specs(trigger_kind, event_type, enabled);`,
|
|
114
|
+
`CREATE INDEX IF NOT EXISTS cron_specs_parse_status_idx
|
|
115
|
+
ON cron_specs(parse_status, updated_at DESC);`,
|
|
116
|
+
`CREATE INDEX IF NOT EXISTS cron_specs_source_path_idx
|
|
117
|
+
ON cron_specs(source_path);`,
|
|
118
|
+
];
|
|
119
|
+
|
|
120
|
+
export function ensureCronSchema(db: SqliteDb): void {
|
|
121
|
+
db.exec("PRAGMA journal_mode = WAL;");
|
|
122
|
+
db.exec("PRAGMA busy_timeout = 5000;");
|
|
123
|
+
db.exec("PRAGMA foreign_keys = ON;");
|
|
124
|
+
for (const stmt of CRON_SCHEMA_STATEMENTS) {
|
|
125
|
+
db.exec(stmt);
|
|
126
|
+
}
|
|
127
|
+
}
|