@clinebot/core 0.0.35 → 0.0.36
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 +53 -39
- package/dist/ClineCore.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/index.d.ts +6 -0
- package/dist/cron/index.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 +66 -0
- package/dist/cron/scheduler.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 +9 -2
- package/dist/extensions/plugin/plugin-config-loader.d.ts.map +1 -1
- package/dist/extensions/plugin/plugin-loader.d.ts +5 -3
- 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 +15 -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 +211 -211
- package/dist/extensions/tools/definitions.d.ts +1 -1
- 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/search.d.ts +1 -1
- package/dist/extensions/tools/executors/search.d.ts.map +1 -1
- package/dist/extensions/tools/index.d.ts +2 -0
- package/dist/extensions/tools/index.d.ts.map +1 -1
- package/dist/extensions/tools/presets.d.ts +26 -43
- 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.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/hooks/hook-file-hooks.d.ts +4 -1
- package/dist/hooks/hook-file-hooks.d.ts.map +1 -1
- 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 +45 -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 +1045 -0
- package/dist/hub/daemon.d.ts +5 -0
- package/dist/hub/daemon.d.ts.map +1 -0
- package/dist/hub/defaults.d.ts +13 -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 +1044 -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 +86 -0
- package/dist/hub/server.d.ts.map +1 -0
- package/dist/hub/session-client.d.ts +87 -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 +44 -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 +26 -15
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +498 -476
- package/dist/llms/configured-provider-registry.d.ts +28 -0
- package/dist/llms/configured-provider-registry.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 +202 -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/host.d.ts +1 -2
- package/dist/runtime/host.d.ts.map +1 -1
- 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-host.d.ts +22 -24
- 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.d.ts +1 -19
- package/dist/runtime/session-runtime.d.ts.map +1 -1
- package/dist/services/global-settings.d.ts +12 -0
- package/dist/services/global-settings.d.ts.map +1 -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 +4 -4
- package/dist/services/providers/local-provider-registry.d.ts.map +1 -1
- package/dist/services/providers/local-provider-service.d.ts +13 -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/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/telemetry/index.js +28 -15
- package/dist/services/workspace-manifest.d.ts +11 -0
- package/dist/services/workspace-manifest.d.ts.map +1 -1
- 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-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 +47 -0
- package/dist/transports/hub.d.ts.map +1 -0
- package/dist/transports/local.d.ts +10 -6
- 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 +10 -12
- package/dist/types/chat-schema.d.ts.map +1 -1
- package/dist/types/config.d.ts +8 -7
- package/dist/types/config.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 +2 -1
- package/dist/types/session.d.ts.map +1 -1
- package/dist/types.d.ts +8 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +20 -6
- package/src/ClineCore.ts +68 -40
- package/src/account/index.ts +3 -3
- package/src/account/rpc.ts +12 -12
- package/src/cron/index.ts +5 -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 +637 -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 +17 -2
- package/src/extensions/plugin/plugin-loader.ts +48 -4
- package/src/extensions/plugin/plugin-module-import.ts +0 -2
- package/src/extensions/plugin/plugin-sandbox-bootstrap.ts +93 -39
- package/src/extensions/plugin/plugin-sandbox.ts +47 -27
- package/src/extensions/plugin/plugin-targeting.ts +32 -0
- package/src/extensions/tools/definitions.ts +30 -49
- package/src/extensions/tools/executors/apply-patch.ts +69 -80
- package/src/extensions/tools/executors/search.ts +195 -3
- package/src/extensions/tools/index.ts +10 -0
- package/src/extensions/tools/presets.ts +31 -46
- package/src/extensions/tools/runtime.ts +261 -0
- package/src/extensions/tools/schemas.ts +4 -2
- package/src/extensions/tools/team/team-tools.ts +21 -0
- package/src/hooks/hook-file-hooks.ts +8 -2
- 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 +137 -0
- package/src/hub/client.ts +574 -0
- package/src/hub/connect.ts +156 -0
- package/src/hub/daemon-entry.ts +87 -0
- package/src/hub/daemon.ts +181 -0
- package/src/hub/defaults.ts +43 -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 +140 -0
- package/src/hub/server.ts +1888 -0
- package/src/hub/session-client.ts +460 -0
- package/src/hub/start-shared-server.ts +58 -0
- package/src/hub/transport.ts +14 -0
- package/src/hub/ui-client.ts +122 -0
- package/src/hub/workspace.ts +19 -0
- package/src/index.ts +124 -68
- package/src/llms/configured-provider-registry.ts +193 -0
- package/src/llms/provider-defaults.ts +637 -0
- package/src/llms/provider-settings.ts +263 -0
- package/src/llms/runtime-config.ts +43 -0
- package/src/llms/runtime-registry.ts +171 -0
- package/src/llms/runtime-types.ts +121 -0
- package/src/runtime/host.ts +107 -269
- package/src/runtime/index.ts +1 -0
- package/src/runtime/rules.ts +12 -0
- package/src/runtime/runtime-builder.ts +24 -8
- package/src/runtime/runtime-host.ts +89 -61
- package/src/runtime/runtime-oauth-token-manager.ts +11 -15
- package/src/runtime/session-runtime.ts +0 -24
- package/src/services/global-settings.ts +122 -0
- package/src/services/local-runtime-bootstrap.ts +51 -13
- package/src/services/plugin-tools.ts +85 -0
- package/src/services/providers/local-provider-registry.ts +6 -6
- package/src/services/providers/local-provider-service.ts +42 -37
- package/src/services/session-data.ts +15 -9
- package/src/services/storage/provider-settings-legacy-migration.ts +6 -4
- package/src/services/storage/provider-settings-manager.ts +1 -1
- package/src/services/workspace-manifest.ts +18 -0
- package/src/session/file-session-service.ts +1 -1
- package/src/session/index.ts +6 -27
- 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 +656 -0
- package/src/transports/local.ts +135 -40
- package/src/transports/remote.ts +26 -0
- package/src/transports/runtime-host-support.ts +63 -9
- package/src/types/chat-schema.ts +4 -5
- package/src/types/config.ts +8 -7
- package/src/types/provider-settings.ts +11 -7
- package/src/types/session.ts +2 -4
- package/src/types.ts +27 -1
- 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/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,460 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
ChatRunTurnRequest,
|
|
3
|
+
ChatStartSessionRequest,
|
|
4
|
+
ChatStartSessionResponse,
|
|
5
|
+
ChatTurnResult,
|
|
6
|
+
HubEventEnvelope,
|
|
7
|
+
TeamProgressProjectionEvent,
|
|
8
|
+
} from "@clinebot/shared";
|
|
9
|
+
import { NodeHubClient } from "./client";
|
|
10
|
+
|
|
11
|
+
export interface HubSessionClientOptions {
|
|
12
|
+
address: string;
|
|
13
|
+
clientId?: string;
|
|
14
|
+
clientType?: string;
|
|
15
|
+
displayName?: string;
|
|
16
|
+
workspaceRoot?: string;
|
|
17
|
+
cwd?: string;
|
|
18
|
+
metadata?: Record<string, unknown>;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface HubSessionRow {
|
|
22
|
+
sessionId: string;
|
|
23
|
+
parentSessionId?: string;
|
|
24
|
+
metadata?: Record<string, unknown>;
|
|
25
|
+
messagesPath?: string;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface HubStreamEvent {
|
|
29
|
+
sessionId: string;
|
|
30
|
+
eventType: string;
|
|
31
|
+
payload: Record<string, unknown>;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface HubEventStreamHandlers {
|
|
35
|
+
onEvent?: (event: HubStreamEvent) => void;
|
|
36
|
+
onError?: (error: Error) => void;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export interface HubTeamProgressHandlers {
|
|
40
|
+
onProjection?: (event: TeamProgressProjectionEvent) => void;
|
|
41
|
+
onError?: (error: Error) => void;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function cloneRecord(
|
|
45
|
+
value: Record<string, unknown> | undefined,
|
|
46
|
+
): Record<string, unknown> {
|
|
47
|
+
return value ? JSON.parse(JSON.stringify(value)) : {};
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function extractSessionRow(
|
|
51
|
+
payload: Record<string, unknown> | undefined,
|
|
52
|
+
): HubSessionRow | undefined {
|
|
53
|
+
const session =
|
|
54
|
+
payload?.session && typeof payload.session === "object"
|
|
55
|
+
? (payload.session as Record<string, unknown>)
|
|
56
|
+
: undefined;
|
|
57
|
+
if (!session) {
|
|
58
|
+
return undefined;
|
|
59
|
+
}
|
|
60
|
+
const metadata =
|
|
61
|
+
session.metadata && typeof session.metadata === "object"
|
|
62
|
+
? cloneRecord(session.metadata as Record<string, unknown>)
|
|
63
|
+
: undefined;
|
|
64
|
+
return {
|
|
65
|
+
sessionId: typeof session.sessionId === "string" ? session.sessionId : "",
|
|
66
|
+
parentSessionId:
|
|
67
|
+
typeof metadata?.parentSessionId === "string"
|
|
68
|
+
? metadata.parentSessionId
|
|
69
|
+
: undefined,
|
|
70
|
+
messagesPath:
|
|
71
|
+
typeof metadata?.messagesPath === "string"
|
|
72
|
+
? metadata.messagesPath
|
|
73
|
+
: undefined,
|
|
74
|
+
metadata,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function mapHubEvent(event: HubEventEnvelope): HubStreamEvent | undefined {
|
|
79
|
+
const sessionId = event.sessionId?.trim();
|
|
80
|
+
if (!sessionId) {
|
|
81
|
+
return undefined;
|
|
82
|
+
}
|
|
83
|
+
switch (event.event) {
|
|
84
|
+
case "assistant.delta":
|
|
85
|
+
return {
|
|
86
|
+
sessionId,
|
|
87
|
+
eventType: "runtime.chat.text_delta",
|
|
88
|
+
payload: cloneRecord(event.payload),
|
|
89
|
+
};
|
|
90
|
+
case "tool.started":
|
|
91
|
+
return {
|
|
92
|
+
sessionId,
|
|
93
|
+
eventType: "runtime.chat.tool_call_start",
|
|
94
|
+
payload: cloneRecord(event.payload),
|
|
95
|
+
};
|
|
96
|
+
case "tool.finished":
|
|
97
|
+
return {
|
|
98
|
+
sessionId,
|
|
99
|
+
eventType: "runtime.chat.tool_call_end",
|
|
100
|
+
payload: cloneRecord(event.payload),
|
|
101
|
+
};
|
|
102
|
+
case "approval.requested":
|
|
103
|
+
return {
|
|
104
|
+
sessionId,
|
|
105
|
+
eventType: "approval.requested",
|
|
106
|
+
payload: cloneRecord(event.payload),
|
|
107
|
+
};
|
|
108
|
+
case "run.aborted":
|
|
109
|
+
return {
|
|
110
|
+
sessionId,
|
|
111
|
+
eventType: "runtime.chat.aborted",
|
|
112
|
+
payload: cloneRecord(event.payload),
|
|
113
|
+
};
|
|
114
|
+
case "run.completed":
|
|
115
|
+
return {
|
|
116
|
+
sessionId,
|
|
117
|
+
eventType: "runtime.chat.completed",
|
|
118
|
+
payload: cloneRecord(event.payload),
|
|
119
|
+
};
|
|
120
|
+
default:
|
|
121
|
+
return undefined;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export class HubSessionClient {
|
|
126
|
+
private readonly client: NodeHubClient;
|
|
127
|
+
private metadataApplied = false;
|
|
128
|
+
|
|
129
|
+
constructor(private readonly options: HubSessionClientOptions) {
|
|
130
|
+
this.client = new NodeHubClient({
|
|
131
|
+
url: options.address,
|
|
132
|
+
clientId: options.clientId,
|
|
133
|
+
clientType: options.clientType ?? "hub-session-client",
|
|
134
|
+
displayName: options.displayName ?? "hub session client",
|
|
135
|
+
workspaceRoot: options.workspaceRoot,
|
|
136
|
+
cwd: options.cwd,
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
private async ensureMetadataApplied(): Promise<void> {
|
|
141
|
+
if (this.metadataApplied || !this.options.metadata) {
|
|
142
|
+
if (!this.options.metadata) {
|
|
143
|
+
await this.client.connect();
|
|
144
|
+
}
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
await this.client.connect();
|
|
148
|
+
await this.client.command("client.update", {
|
|
149
|
+
metadata: this.options.metadata,
|
|
150
|
+
});
|
|
151
|
+
this.metadataApplied = true;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
async connect(): Promise<void> {
|
|
155
|
+
await this.ensureMetadataApplied();
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
close(): void {
|
|
159
|
+
this.client.close();
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
async startRuntimeSession(
|
|
163
|
+
request: ChatStartSessionRequest,
|
|
164
|
+
): Promise<ChatStartSessionResponse> {
|
|
165
|
+
await this.ensureMetadataApplied();
|
|
166
|
+
const reply = await this.client.command("session.create", {
|
|
167
|
+
workspaceRoot: request.workspaceRoot,
|
|
168
|
+
cwd: request.cwd,
|
|
169
|
+
sessionConfig: {
|
|
170
|
+
providerId: request.provider,
|
|
171
|
+
modelId: request.model,
|
|
172
|
+
apiKey: request.apiKey,
|
|
173
|
+
cwd: request.cwd ?? request.workspaceRoot,
|
|
174
|
+
workspaceRoot: request.workspaceRoot,
|
|
175
|
+
systemPrompt: request.systemPrompt ?? "",
|
|
176
|
+
mode: request.mode ?? "act",
|
|
177
|
+
rules: request.rules,
|
|
178
|
+
maxIterations: request.maxIterations,
|
|
179
|
+
enableTools: request.enableTools,
|
|
180
|
+
enableSpawnAgent: request.enableSpawn !== false,
|
|
181
|
+
enableAgentTeams: request.enableTeams !== false,
|
|
182
|
+
disableMcpSettingsTools: request.disableMcpSettingsTools,
|
|
183
|
+
missionLogIntervalSteps: request.missionStepInterval,
|
|
184
|
+
missionLogIntervalMs: request.missionTimeIntervalMs,
|
|
185
|
+
},
|
|
186
|
+
metadata: {
|
|
187
|
+
source: request.source ?? "cli",
|
|
188
|
+
provider: request.provider,
|
|
189
|
+
model: request.model,
|
|
190
|
+
enableTools: request.enableTools,
|
|
191
|
+
enableSpawn: request.enableSpawn,
|
|
192
|
+
enableTeams: request.enableTeams,
|
|
193
|
+
prompt: undefined,
|
|
194
|
+
interactive: request.interactive !== false,
|
|
195
|
+
},
|
|
196
|
+
runtimeOptions: {
|
|
197
|
+
mode: request.mode,
|
|
198
|
+
systemPrompt: request.systemPrompt,
|
|
199
|
+
maxIterations: request.maxIterations,
|
|
200
|
+
enableTools: request.enableTools,
|
|
201
|
+
enableSpawn: request.enableSpawn,
|
|
202
|
+
enableTeams: request.enableTeams,
|
|
203
|
+
autoApproveTools: request.autoApproveTools,
|
|
204
|
+
},
|
|
205
|
+
modelSelection: {
|
|
206
|
+
provider: request.provider,
|
|
207
|
+
model: request.model,
|
|
208
|
+
apiKey: request.apiKey,
|
|
209
|
+
},
|
|
210
|
+
toolPolicies: request.toolPolicies,
|
|
211
|
+
initialMessages: request.initialMessages,
|
|
212
|
+
});
|
|
213
|
+
const row = extractSessionRow(reply.payload);
|
|
214
|
+
if (!row?.sessionId) {
|
|
215
|
+
throw new Error("hub session create returned no session id");
|
|
216
|
+
}
|
|
217
|
+
return {
|
|
218
|
+
sessionId: row.sessionId,
|
|
219
|
+
startResult: {
|
|
220
|
+
sessionId: row.sessionId,
|
|
221
|
+
manifestPath: "",
|
|
222
|
+
messagesPath: row.messagesPath ?? "",
|
|
223
|
+
},
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
async sendRuntimeSession(
|
|
228
|
+
sessionId: string,
|
|
229
|
+
request: ChatRunTurnRequest,
|
|
230
|
+
): Promise<{ result?: ChatTurnResult }> {
|
|
231
|
+
await this.ensureMetadataApplied();
|
|
232
|
+
const reply = await this.client.command(
|
|
233
|
+
"session.send_input",
|
|
234
|
+
{
|
|
235
|
+
prompt: request.prompt,
|
|
236
|
+
attachments: request.attachments,
|
|
237
|
+
delivery: request.delivery,
|
|
238
|
+
},
|
|
239
|
+
sessionId,
|
|
240
|
+
);
|
|
241
|
+
return {
|
|
242
|
+
result: reply.payload?.result as ChatTurnResult | undefined,
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
async stopRuntimeSession(sessionId: string): Promise<{ applied: boolean }> {
|
|
247
|
+
await this.ensureMetadataApplied();
|
|
248
|
+
await this.client.command("session.detach", { sessionId }, sessionId);
|
|
249
|
+
return { applied: true };
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
async abortRuntimeSession(sessionId: string): Promise<{ applied: boolean }> {
|
|
253
|
+
await this.ensureMetadataApplied();
|
|
254
|
+
await this.client.command("run.abort", { sessionId }, sessionId);
|
|
255
|
+
return { applied: true };
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
async updateSession(input: {
|
|
259
|
+
sessionId: string;
|
|
260
|
+
metadata?: Record<string, unknown>;
|
|
261
|
+
}): Promise<{ updated: boolean }> {
|
|
262
|
+
await this.ensureMetadataApplied();
|
|
263
|
+
await this.client.command(
|
|
264
|
+
"session.update",
|
|
265
|
+
{
|
|
266
|
+
sessionId: input.sessionId,
|
|
267
|
+
metadata: input.metadata,
|
|
268
|
+
},
|
|
269
|
+
input.sessionId,
|
|
270
|
+
);
|
|
271
|
+
return { updated: true };
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
async getSession(sessionId: string): Promise<HubSessionRow | undefined> {
|
|
275
|
+
await this.ensureMetadataApplied();
|
|
276
|
+
const reply = await this.client.command(
|
|
277
|
+
"session.get",
|
|
278
|
+
undefined,
|
|
279
|
+
sessionId,
|
|
280
|
+
);
|
|
281
|
+
return extractSessionRow(reply.payload);
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
async listSessions(input?: { limit?: number }): Promise<HubSessionRow[]> {
|
|
285
|
+
await this.ensureMetadataApplied();
|
|
286
|
+
const reply = await this.client.command("session.list", {
|
|
287
|
+
limit: input?.limit ?? 200,
|
|
288
|
+
});
|
|
289
|
+
const sessions = Array.isArray(reply.payload?.sessions)
|
|
290
|
+
? (reply.payload?.sessions as Record<string, unknown>[])
|
|
291
|
+
: [];
|
|
292
|
+
return sessions
|
|
293
|
+
.map((session) => extractSessionRow({ session }))
|
|
294
|
+
.filter((row): row is HubSessionRow => Boolean(row?.sessionId));
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
async deleteSession(
|
|
298
|
+
sessionId: string,
|
|
299
|
+
deleteCheckpointRefs = true,
|
|
300
|
+
): Promise<boolean> {
|
|
301
|
+
await this.ensureMetadataApplied();
|
|
302
|
+
const reply = await this.client.command("session.delete", {
|
|
303
|
+
sessionId,
|
|
304
|
+
deleteCheckpointRefs,
|
|
305
|
+
});
|
|
306
|
+
return reply.payload?.deleted === true;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
async respondToolApproval(input: {
|
|
310
|
+
approvalId: string;
|
|
311
|
+
approved: boolean;
|
|
312
|
+
reason?: string;
|
|
313
|
+
responderClientId?: string;
|
|
314
|
+
}): Promise<void> {
|
|
315
|
+
await this.ensureMetadataApplied();
|
|
316
|
+
await this.client.command("approval.respond", {
|
|
317
|
+
approvalId: input.approvalId,
|
|
318
|
+
approved: input.approved,
|
|
319
|
+
payload: input.reason ? { reason: input.reason } : undefined,
|
|
320
|
+
responderClientId: input.responderClientId,
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
streamEvents(
|
|
325
|
+
input: { clientId?: string; sessionIds?: string[] },
|
|
326
|
+
handlers: HubEventStreamHandlers,
|
|
327
|
+
): () => void {
|
|
328
|
+
const allowed = new Set(
|
|
329
|
+
(input.sessionIds ?? []).map((id) => id.trim()).filter(Boolean),
|
|
330
|
+
);
|
|
331
|
+
const unsubscribe = this.client.subscribe((event: HubEventEnvelope) => {
|
|
332
|
+
const mapped = mapHubEvent(event);
|
|
333
|
+
if (!mapped) {
|
|
334
|
+
return;
|
|
335
|
+
}
|
|
336
|
+
if (allowed.size > 0 && !allowed.has(mapped.sessionId)) {
|
|
337
|
+
return;
|
|
338
|
+
}
|
|
339
|
+
handlers.onEvent?.(mapped);
|
|
340
|
+
});
|
|
341
|
+
void this.ensureMetadataApplied().catch((error) => {
|
|
342
|
+
handlers.onError?.(
|
|
343
|
+
error instanceof Error ? error : new Error(String(error)),
|
|
344
|
+
);
|
|
345
|
+
});
|
|
346
|
+
return unsubscribe;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
streamTeamProgress(
|
|
350
|
+
_input: { clientId?: string },
|
|
351
|
+
handlers: HubTeamProgressHandlers,
|
|
352
|
+
): () => void {
|
|
353
|
+
const unsubscribe = this.client.subscribe((event: HubEventEnvelope) => {
|
|
354
|
+
if (event.event !== "team.progress" || !event.payload) {
|
|
355
|
+
return;
|
|
356
|
+
}
|
|
357
|
+
handlers.onProjection?.(
|
|
358
|
+
event.payload as unknown as TeamProgressProjectionEvent,
|
|
359
|
+
);
|
|
360
|
+
});
|
|
361
|
+
void this.ensureMetadataApplied().catch((error) => {
|
|
362
|
+
handlers.onError?.(
|
|
363
|
+
error instanceof Error ? error : new Error(String(error)),
|
|
364
|
+
);
|
|
365
|
+
});
|
|
366
|
+
return unsubscribe;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
async createSchedule(input: Record<string, unknown>): Promise<any> {
|
|
370
|
+
await this.ensureMetadataApplied();
|
|
371
|
+
const reply = await this.client.command("schedule.create", input);
|
|
372
|
+
return reply.payload?.schedule;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
async listSchedules(_input?: { limit?: number }): Promise<any[]> {
|
|
376
|
+
await this.ensureMetadataApplied();
|
|
377
|
+
const reply = await this.client.command("schedule.list");
|
|
378
|
+
return Array.isArray(reply.payload?.schedules)
|
|
379
|
+
? (reply.payload?.schedules as any[])
|
|
380
|
+
: [];
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
async getSchedule(scheduleId: string): Promise<any | undefined> {
|
|
384
|
+
await this.ensureMetadataApplied();
|
|
385
|
+
const reply = await this.client.command("schedule.get", { scheduleId });
|
|
386
|
+
return reply.payload?.schedule;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
async updateSchedule(
|
|
390
|
+
scheduleId: string,
|
|
391
|
+
input: Record<string, unknown>,
|
|
392
|
+
): Promise<any> {
|
|
393
|
+
await this.ensureMetadataApplied();
|
|
394
|
+
const reply = await this.client.command("schedule.update", {
|
|
395
|
+
scheduleId,
|
|
396
|
+
...input,
|
|
397
|
+
});
|
|
398
|
+
return reply.payload?.schedule;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
async pauseSchedule(scheduleId: string): Promise<any> {
|
|
402
|
+
await this.ensureMetadataApplied();
|
|
403
|
+
const reply = await this.client.command("schedule.disable", { scheduleId });
|
|
404
|
+
return reply.payload?.schedule;
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
async resumeSchedule(scheduleId: string): Promise<any> {
|
|
408
|
+
await this.ensureMetadataApplied();
|
|
409
|
+
const reply = await this.client.command("schedule.enable", { scheduleId });
|
|
410
|
+
return reply.payload?.schedule;
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
async deleteSchedule(scheduleId: string): Promise<boolean> {
|
|
414
|
+
await this.ensureMetadataApplied();
|
|
415
|
+
const reply = await this.client.command("schedule.delete", { scheduleId });
|
|
416
|
+
return reply.payload?.deleted === true;
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
async triggerScheduleNow(scheduleId: string): Promise<any> {
|
|
420
|
+
await this.ensureMetadataApplied();
|
|
421
|
+
const reply = await this.client.command("schedule.trigger", { scheduleId });
|
|
422
|
+
return reply.payload?.execution;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
async listScheduleExecutions(
|
|
426
|
+
scheduleId: string,
|
|
427
|
+
limit?: number,
|
|
428
|
+
): Promise<any[]> {
|
|
429
|
+
await this.ensureMetadataApplied();
|
|
430
|
+
const reply = await this.client.command("schedule.list_executions", {
|
|
431
|
+
scheduleId,
|
|
432
|
+
limit,
|
|
433
|
+
});
|
|
434
|
+
return Array.isArray(reply.payload?.executions)
|
|
435
|
+
? (reply.payload?.executions as any[])
|
|
436
|
+
: [];
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
async getScheduleStats(): Promise<any> {
|
|
440
|
+
await this.ensureMetadataApplied();
|
|
441
|
+
const reply = await this.client.command("schedule.stats");
|
|
442
|
+
return reply.payload?.stats;
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
async getActiveScheduledExecutions(): Promise<any[]> {
|
|
446
|
+
await this.ensureMetadataApplied();
|
|
447
|
+
const reply = await this.client.command("schedule.active");
|
|
448
|
+
return Array.isArray(reply.payload?.executions)
|
|
449
|
+
? (reply.payload?.executions as any[])
|
|
450
|
+
: [];
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
async getUpcomingScheduledRuns(limit?: number): Promise<any[]> {
|
|
454
|
+
await this.ensureMetadataApplied();
|
|
455
|
+
const reply = await this.client.command("schedule.upcoming", { limit });
|
|
456
|
+
return Array.isArray(reply.payload?.upcoming)
|
|
457
|
+
? (reply.payload?.upcoming as any[])
|
|
458
|
+
: [];
|
|
459
|
+
}
|
|
460
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { resolveHubEndpointOptions } from "./defaults";
|
|
2
|
+
import {
|
|
3
|
+
type EnsuredHubWebSocketServerResult,
|
|
4
|
+
type EnsureHubWebSocketServerOptions,
|
|
5
|
+
ensureHubWebSocketServer,
|
|
6
|
+
type HubWebSocketServer,
|
|
7
|
+
type HubWebSocketServerOptions,
|
|
8
|
+
startHubWebSocketServer,
|
|
9
|
+
} from "./server";
|
|
10
|
+
import { resolveSharedHubOwnerContext } from "./workspace";
|
|
11
|
+
|
|
12
|
+
export type HubServer = HubWebSocketServer;
|
|
13
|
+
export type EnsureHubServerResult = EnsuredHubWebSocketServerResult;
|
|
14
|
+
|
|
15
|
+
export interface StartHubServerOptions
|
|
16
|
+
extends Omit<HubWebSocketServerOptions, "owner"> {}
|
|
17
|
+
|
|
18
|
+
export interface EnsureHubServerOptions
|
|
19
|
+
extends Omit<EnsureHubWebSocketServerOptions, "owner"> {}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Start a hub WebSocket server bound to the process-local shared owner
|
|
23
|
+
* context. Callers that need a custom owner should invoke
|
|
24
|
+
* {@link startHubWebSocketServer} directly.
|
|
25
|
+
*/
|
|
26
|
+
export async function startHubServer(
|
|
27
|
+
options: StartHubServerOptions,
|
|
28
|
+
): Promise<HubServer> {
|
|
29
|
+
const endpoint = resolveHubEndpointOptions({
|
|
30
|
+
host: options.host,
|
|
31
|
+
port: options.port,
|
|
32
|
+
pathname: options.pathname,
|
|
33
|
+
});
|
|
34
|
+
return await startHubWebSocketServer({
|
|
35
|
+
...options,
|
|
36
|
+
...endpoint,
|
|
37
|
+
owner: resolveSharedHubOwnerContext(),
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Ensure a hub WebSocket server is running in the process-local shared owner
|
|
43
|
+
* context, reusing a compatible in-process instance when available.
|
|
44
|
+
*/
|
|
45
|
+
export async function ensureHubServer(
|
|
46
|
+
options: EnsureHubServerOptions,
|
|
47
|
+
): Promise<EnsureHubServerResult> {
|
|
48
|
+
const endpoint = resolveHubEndpointOptions({
|
|
49
|
+
host: options.host,
|
|
50
|
+
port: options.port,
|
|
51
|
+
pathname: options.pathname,
|
|
52
|
+
});
|
|
53
|
+
return await ensureHubWebSocketServer({
|
|
54
|
+
...options,
|
|
55
|
+
...endpoint,
|
|
56
|
+
owner: resolveSharedHubOwnerContext(),
|
|
57
|
+
});
|
|
58
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
HubCommandEnvelope,
|
|
3
|
+
HubEventEnvelope,
|
|
4
|
+
HubReplyEnvelope,
|
|
5
|
+
} from "@clinebot/shared";
|
|
6
|
+
|
|
7
|
+
export interface HubCommandTransport {
|
|
8
|
+
command(envelope: HubCommandEnvelope): Promise<HubReplyEnvelope>;
|
|
9
|
+
subscribe(
|
|
10
|
+
clientId: string,
|
|
11
|
+
listener: (event: HubEventEnvelope) => void,
|
|
12
|
+
options?: { sessionId?: string },
|
|
13
|
+
): Promise<() => void> | (() => void);
|
|
14
|
+
}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
HubClientRecord,
|
|
3
|
+
HubEventEnvelope,
|
|
4
|
+
HubUINotifyPayload,
|
|
5
|
+
HubUIShowWindowPayload,
|
|
6
|
+
SessionRecord,
|
|
7
|
+
} from "@clinebot/shared";
|
|
8
|
+
import { NodeHubClient } from "./client";
|
|
9
|
+
|
|
10
|
+
export interface HubUIClientOptions {
|
|
11
|
+
address: string;
|
|
12
|
+
clientId?: string;
|
|
13
|
+
clientType?: string;
|
|
14
|
+
displayName?: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* A lightweight hub client for UI/notification concerns.
|
|
19
|
+
* Used by the menu bar app and other UI clients to send/receive
|
|
20
|
+
* UI events (notifications, show window, client tracking).
|
|
21
|
+
*/
|
|
22
|
+
export class HubUIClient {
|
|
23
|
+
private readonly client: NodeHubClient;
|
|
24
|
+
|
|
25
|
+
constructor(options: HubUIClientOptions) {
|
|
26
|
+
this.client = new NodeHubClient({
|
|
27
|
+
url: options.address,
|
|
28
|
+
clientId: options.clientId,
|
|
29
|
+
clientType: options.clientType ?? "hub-ui-client",
|
|
30
|
+
displayName: options.displayName ?? "hub ui client",
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
async connect(): Promise<void> {
|
|
35
|
+
await this.client.connect();
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
close(): void {
|
|
39
|
+
this.client.close();
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
getClientId(): string {
|
|
43
|
+
return this.client.getClientId();
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Send a notification request to the hub.
|
|
48
|
+
* The hub will broadcast a "ui.notify" event to all subscribers (e.g. the menu bar app).
|
|
49
|
+
*/
|
|
50
|
+
async sendNotify(payload: HubUINotifyPayload): Promise<void> {
|
|
51
|
+
await this.client.command(
|
|
52
|
+
"ui.notify",
|
|
53
|
+
payload as unknown as Record<string, unknown>,
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Request the hub to broadcast a "ui.show_window" event to all subscribers.
|
|
59
|
+
*/
|
|
60
|
+
async sendShowWindow(payload?: HubUIShowWindowPayload): Promise<void> {
|
|
61
|
+
await this.client.command(
|
|
62
|
+
"ui.show_window",
|
|
63
|
+
(payload ?? {}) as Record<string, unknown>,
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
async listClients(): Promise<HubClientRecord[]> {
|
|
68
|
+
const reply = await this.client.command("client.list");
|
|
69
|
+
return Array.isArray(reply.payload?.clients)
|
|
70
|
+
? (reply.payload.clients as HubClientRecord[])
|
|
71
|
+
: [];
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
async listSessions(limit = 200): Promise<SessionRecord[]> {
|
|
75
|
+
const reply = await this.client.command("session.list", { limit });
|
|
76
|
+
return Array.isArray(reply.payload?.sessions)
|
|
77
|
+
? (reply.payload.sessions as SessionRecord[])
|
|
78
|
+
: [];
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Subscribe to UI-relevant hub events.
|
|
83
|
+
* Returns an unsubscribe function.
|
|
84
|
+
*/
|
|
85
|
+
subscribeUI(handlers: {
|
|
86
|
+
onNotify?: (payload: HubUINotifyPayload) => void;
|
|
87
|
+
onShowWindow?: (payload: HubUIShowWindowPayload) => void;
|
|
88
|
+
onClientRegistered?: (payload: Record<string, unknown>) => void;
|
|
89
|
+
onClientDisconnected?: (payload: Record<string, unknown>) => void;
|
|
90
|
+
onSessionCreated?: (payload: Record<string, unknown>) => void;
|
|
91
|
+
onSessionUpdated?: (payload: Record<string, unknown>) => void;
|
|
92
|
+
onSessionDetached?: (payload: Record<string, unknown>) => void;
|
|
93
|
+
}): () => void {
|
|
94
|
+
return this.client.subscribe((event: HubEventEnvelope) => {
|
|
95
|
+
switch (event.event) {
|
|
96
|
+
case "ui.notify":
|
|
97
|
+
handlers.onNotify?.(event.payload as unknown as HubUINotifyPayload);
|
|
98
|
+
break;
|
|
99
|
+
case "ui.show_window":
|
|
100
|
+
handlers.onShowWindow?.(
|
|
101
|
+
event.payload as unknown as HubUIShowWindowPayload,
|
|
102
|
+
);
|
|
103
|
+
break;
|
|
104
|
+
case "hub.client.registered":
|
|
105
|
+
handlers.onClientRegistered?.(event.payload ?? {});
|
|
106
|
+
break;
|
|
107
|
+
case "hub.client.disconnected":
|
|
108
|
+
handlers.onClientDisconnected?.(event.payload ?? {});
|
|
109
|
+
break;
|
|
110
|
+
case "session.created":
|
|
111
|
+
handlers.onSessionCreated?.(event.payload ?? {});
|
|
112
|
+
break;
|
|
113
|
+
case "session.updated":
|
|
114
|
+
handlers.onSessionUpdated?.(event.payload ?? {});
|
|
115
|
+
break;
|
|
116
|
+
case "session.detached":
|
|
117
|
+
handlers.onSessionDetached?.(event.payload ?? {});
|
|
118
|
+
break;
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { normalizeWorkspacePath } from "../services/workspace-manifest";
|
|
2
|
+
import { type HubOwnerContext, resolveHubOwnerContext } from "./discovery";
|
|
3
|
+
|
|
4
|
+
const DEFAULT_SHARED_HUB_OWNER_LABEL = "shared:cline";
|
|
5
|
+
|
|
6
|
+
export function resolveWorkspaceHubOwnerContext(
|
|
7
|
+
workspaceRoot: string,
|
|
8
|
+
): HubOwnerContext {
|
|
9
|
+
const normalized = normalizeWorkspacePath(workspaceRoot.trim());
|
|
10
|
+
return resolveHubOwnerContext(
|
|
11
|
+
`workspace:${normalized || workspaceRoot.trim()}`,
|
|
12
|
+
);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function resolveSharedHubOwnerContext(
|
|
16
|
+
label = DEFAULT_SHARED_HUB_OWNER_LABEL,
|
|
17
|
+
): HubOwnerContext {
|
|
18
|
+
return resolveHubOwnerContext(label);
|
|
19
|
+
}
|