@cerebriline/core 4.100.246 → 4.100.247

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.
Files changed (116) hide show
  1. package/assets/prompt-templates/claude.md +2 -0
  2. package/assets/prompt-templates/deepseek.md +1 -0
  3. package/assets/prompt-templates/default.md +2 -1
  4. package/assets/prompt-templates/kimi-k3.md +1 -0
  5. package/assets/prompt-templates/kimi.md +1 -0
  6. package/assets/prompt-templates/minimax.md +2 -0
  7. package/assets/prompt-templates/nemotron.md +1 -0
  8. package/assets/skills/browser-automation/SKILL.md +113 -0
  9. package/dist/ClineCore.d.ts +9 -0
  10. package/dist/account/index.d.ts +1 -0
  11. package/dist/account/telemetry.d.ts +22 -0
  12. package/dist/cloud/api.d.ts +122 -0
  13. package/dist/cloud/controller.d.ts +172 -0
  14. package/dist/cloud/index.d.ts +9 -0
  15. package/dist/cloud/index.js +21 -0
  16. package/dist/cloud/models.d.ts +9 -0
  17. package/dist/cloud/repositories.d.ts +21 -0
  18. package/dist/cloud/snapshots.d.ts +22 -0
  19. package/dist/cloud/state.d.ts +13 -0
  20. package/dist/cloud/types.d.ts +84 -0
  21. package/dist/cron/events/cron-event-ingress.d.ts +4 -2
  22. package/dist/cron/runner/cron-runner.d.ts +5 -2
  23. package/dist/cron/service/cron-service.d.ts +2 -1
  24. package/dist/cron/service/schedule-service.d.ts +2 -1
  25. package/dist/cron/store/sqlite-cron-store.d.ts +7 -1
  26. package/dist/extensions/composio/composio-meta-tools.d.ts +39 -0
  27. package/dist/extensions/composio/composio-tools-extension.d.ts +13 -0
  28. package/dist/extensions/context/agentic-compaction.d.ts +1 -1
  29. package/dist/extensions/context/cap-thoughts.d.ts +39 -0
  30. package/dist/extensions/context/compaction-shared.d.ts +76 -1
  31. package/dist/extensions/context/compaction.d.ts +75 -3
  32. package/dist/extensions/mcp/client.d.ts +1 -1
  33. package/dist/extensions/tools/definitions.d.ts +5 -5
  34. package/dist/extensions/tools/executors/bash.d.ts +26 -0
  35. package/dist/extensions/tools/executors/index.d.ts +1 -1
  36. package/dist/extensions/tools/index.d.ts +1 -1
  37. package/dist/extensions/tools/task-progress.d.ts +37 -0
  38. package/dist/extensions/tools/team/index.d.ts +1 -0
  39. package/dist/extensions/tools/team/multi-agent.d.ts +48 -0
  40. package/dist/extensions/tools/team/persistence-policy.d.ts +56 -0
  41. package/dist/extensions/tools/team/runtime.d.ts +1 -1
  42. package/dist/extensions/tools/team/sanitize-team-name.d.ts +5 -0
  43. package/dist/extensions/tools/team/team-tools.d.ts +1 -1
  44. package/dist/hooks/checkpoint-hooks.d.ts +23 -1
  45. package/dist/hooks/hook-file-hooks.d.ts +27 -0
  46. package/dist/hooks/subprocess-runner.d.ts +23 -0
  47. package/dist/hooks/subprocess.d.ts +10 -0
  48. package/dist/hub/client/index.d.ts +29 -3
  49. package/dist/hub/client/session-client.d.ts +0 -3
  50. package/dist/hub/daemon/bind-diagnostics.d.ts +16 -0
  51. package/dist/hub/daemon/entry.js +689 -640
  52. package/dist/hub/daemon/index.d.ts +17 -8
  53. package/dist/hub/discovery/index.d.ts +1 -0
  54. package/dist/hub/index.js +675 -627
  55. package/dist/hub/runtime-host/hub-runtime-host.d.ts +4 -2
  56. package/dist/hub/server/handlers/session-handlers.d.ts +6 -1
  57. package/dist/index.d.ts +21 -11
  58. package/dist/index.js +1032 -964
  59. package/dist/remote/remote-environments.d.ts +155 -0
  60. package/dist/remote/remote-helper-entry.d.ts +1 -0
  61. package/dist/remote/remote-helper-entry.js +5 -0
  62. package/dist/remote/remote-helper.d.ts +29 -0
  63. package/dist/remote/remote-helper.js +4 -0
  64. package/dist/remote/shell-path.d.ts +88 -0
  65. package/dist/runtime/host/local-runtime-host.d.ts +2 -2
  66. package/dist/runtime/host/runtime-host.d.ts +13 -1
  67. package/dist/runtime/orchestration/oauth-refresh-lock.d.ts +6 -0
  68. package/dist/runtime/orchestration/session-runtime-orchestrator.d.ts +7 -0
  69. package/dist/runtime/orchestration/team-persistence-writer.d.ts +65 -0
  70. package/dist/runtime/safety/rules.d.ts +11 -0
  71. package/dist/runtime/turn-queue/pending-prompt-service.d.ts +1 -0
  72. package/dist/services/agent-events.d.ts +1 -0
  73. package/dist/services/cloud-handoff/git-preflight.d.ts +24 -0
  74. package/dist/services/cloud-handoff/index.d.ts +4 -0
  75. package/dist/services/cloud-handoff/metadata.d.ts +7 -0
  76. package/dist/services/cloud-handoff/transcript.d.ts +5 -0
  77. package/dist/services/cloud-handoff/types.d.ts +35 -0
  78. package/dist/services/feature-flags/FeatureFlagsService.d.ts +2 -0
  79. package/dist/services/feature-flags/cline-account-feature-flags.d.ts +5 -0
  80. package/dist/services/llms/cline-recommended-models.d.ts +1 -0
  81. package/dist/services/llms/handler-factory.d.ts +12 -0
  82. package/dist/services/llms/provider-defaults.d.ts +1 -1
  83. package/dist/services/llms/provider-settings.d.ts +19 -17
  84. package/dist/services/local-runtime-bootstrap.d.ts +7 -0
  85. package/dist/services/mcp-install.d.ts +9 -0
  86. package/dist/services/plugin-commands.d.ts +28 -0
  87. package/dist/services/providers/local-provider-registry.d.ts +8 -3
  88. package/dist/services/providers/local-provider-service.d.ts +20 -10
  89. package/dist/services/providers/model-source.d.ts +6 -1
  90. package/dist/services/providers/provider-config-fields.d.ts +11 -0
  91. package/dist/services/session-import/claude-code.d.ts +1 -1
  92. package/dist/services/session-import/paths.d.ts +9 -0
  93. package/dist/services/storage/file-team-store.d.ts +10 -4
  94. package/dist/services/storage/sqlite-team-store.d.ts +48 -5
  95. package/dist/services/storage/team-store.d.ts +1 -0
  96. package/dist/services/telemetry/core-events.d.ts +97 -5
  97. package/dist/services/telemetry/index.d.ts +1 -0
  98. package/dist/services/telemetry/index.js +1 -1
  99. package/dist/services/telemetry/scoped-telemetry.d.ts +31 -0
  100. package/dist/services/workspace/workspace-manifest.d.ts +34 -0
  101. package/dist/services/workspace/workspace-telemetry.d.ts +5 -0
  102. package/dist/session/fork-metadata.d.ts +7 -0
  103. package/dist/session/models/session-compaction.d.ts +8 -1
  104. package/dist/session/services/message-builder.d.ts +8 -1
  105. package/dist/session/services/persistence-service.d.ts +4 -1
  106. package/dist/session/services/tool-result-cache.d.ts +30 -0
  107. package/dist/session/session-versioning-service.d.ts +8 -0
  108. package/dist/session/stores/session-manifest-store.d.ts +2 -4
  109. package/dist/session/team/team-session-coordinator.d.ts +3 -1
  110. package/dist/tasks/task-tool.d.ts +2 -2
  111. package/dist/types/provider-settings.d.ts +11 -0
  112. package/dist/types/session.d.ts +2 -0
  113. package/dist/types/storage.d.ts +22 -1
  114. package/package.json +16 -4
  115. package/dist/cron/runner/resource-limiter.d.ts +0 -8
  116. package/dist/services/storage/team-events-retention.d.ts +0 -25
@@ -0,0 +1,155 @@
1
+ export interface RemoteEnvironmentProfile {
2
+ id: string;
3
+ name: string;
4
+ host: string;
5
+ user?: string;
6
+ port?: number;
7
+ identityFile?: string;
8
+ createdAt: string;
9
+ updatedAt: string;
10
+ }
11
+ export interface RemoteEnvironmentInput {
12
+ id?: string;
13
+ name: string;
14
+ host: string;
15
+ user?: string;
16
+ port?: number;
17
+ identityFile?: string;
18
+ }
19
+ export type RemoteEnvironmentState = "disconnected" | "testing" | "available" | "connecting" | "connected" | "error";
20
+ export interface RemoteEnvironmentStatus {
21
+ profileId: string;
22
+ state: RemoteEnvironmentState;
23
+ updatedAt: string;
24
+ message?: string;
25
+ remotePlatform?: "linux" | "darwin";
26
+ remoteArch?: "x64" | "arm64";
27
+ remoteHome?: string;
28
+ }
29
+ export interface RemoteEnvironmentConnection {
30
+ profile: RemoteEnvironmentProfile;
31
+ profileId: string;
32
+ state: "connected";
33
+ endpoint: string;
34
+ authToken: string;
35
+ workspaceRoot: string;
36
+ homeDir: string;
37
+ platform: "linux" | "darwin";
38
+ arch: "x64" | "arm64";
39
+ remoteHubUrl: string;
40
+ localPort: number;
41
+ connectedAt: string;
42
+ }
43
+ export interface RemoteCommandInput {
44
+ command: string;
45
+ args: string[];
46
+ cwd?: string;
47
+ }
48
+ export interface RemoteCommandResult {
49
+ stdout: string;
50
+ stderr: string;
51
+ exitCode: number;
52
+ }
53
+ export interface RemoteHelperTarget {
54
+ platform: "linux" | "darwin";
55
+ arch: "x64" | "arm64";
56
+ }
57
+ export interface RemoteTunnelProcess {
58
+ readonly pid?: number;
59
+ readonly exitCode: number | null;
60
+ kill(signal?: NodeJS.Signals): boolean;
61
+ once(event: "exit", listener: (code: number | null, signal: NodeJS.Signals | null) => void): unknown;
62
+ once(event: "error", listener: (error: Error) => void): unknown;
63
+ }
64
+ export interface RemoteProcessOptions {
65
+ timeoutMs: number;
66
+ inputFile?: string;
67
+ /** Combined stdout/stderr limit; defaults to 8 MiB. */
68
+ maxOutputBytes?: number;
69
+ }
70
+ export interface RemoteEnvironmentDependencies {
71
+ runProcess(executable: string, args: string[], options: RemoteProcessOptions): Promise<RemoteCommandResult>;
72
+ spawnTunnel(executable: string, args: string[]): RemoteTunnelProcess;
73
+ waitForTunnel(port: number, tunnel: RemoteTunnelProcess, timeoutMs: number): Promise<void>;
74
+ reservePort(): Promise<number>;
75
+ hashFile(path: string): Promise<string>;
76
+ resolveHelperBinary(target: RemoteHelperTarget): Promise<string | undefined>;
77
+ fileReadable(path: string): Promise<boolean>;
78
+ requestHubShutdown(url: string, authToken?: string): Promise<boolean>;
79
+ now(): Date;
80
+ randomId(): string;
81
+ }
82
+ export interface RemoteEnvironmentServiceOptions {
83
+ profilesPath?: string;
84
+ sshPath?: string;
85
+ knownHostsPath?: string;
86
+ connectTimeoutSeconds?: number;
87
+ commandTimeoutMs?: number;
88
+ uploadTimeoutMs?: number;
89
+ tunnelTimeoutMs?: number;
90
+ hubShutdownTimeoutMs?: number;
91
+ helperBinaryPath?: string;
92
+ helperBinaryDirectory?: string;
93
+ env?: NodeJS.ProcessEnv;
94
+ onStatusChange?: (status: RemoteEnvironmentStatus) => void;
95
+ onConnectionLost?: (status: RemoteEnvironmentStatus) => void;
96
+ dependencies?: Partial<RemoteEnvironmentDependencies>;
97
+ }
98
+ export declare class RemoteEnvironmentService {
99
+ private readonly profilesPath;
100
+ private readonly ownerId;
101
+ private readonly sshPath;
102
+ private readonly knownHostsPath?;
103
+ private readonly connectTimeoutSeconds;
104
+ private readonly commandTimeoutMs;
105
+ private readonly uploadTimeoutMs;
106
+ private readonly tunnelTimeoutMs;
107
+ private readonly hubShutdownTimeoutMs;
108
+ private readonly dependencies;
109
+ private readonly onStatusChange?;
110
+ private readonly onConnectionLost?;
111
+ private readonly statuses;
112
+ private readonly connections;
113
+ private activeProfileId;
114
+ private mutationTail;
115
+ constructor(options?: RemoteEnvironmentServiceOptions);
116
+ list(): Promise<RemoteEnvironmentProfile[]>;
117
+ upsert(input: RemoteEnvironmentInput): Promise<RemoteEnvironmentProfile>;
118
+ delete(id: string): Promise<boolean>;
119
+ test(id: string): Promise<RemoteEnvironmentStatus>;
120
+ connect(id: string): Promise<RemoteEnvironmentConnection>;
121
+ private connectProfile;
122
+ disconnect(id?: string): Promise<boolean>;
123
+ private disconnectProfile;
124
+ getActive(): RemoteEnvironmentConnection | undefined;
125
+ getConnection(id: string): RemoteEnvironmentConnection | undefined;
126
+ /**
127
+ * Marks an already-established tunnel as active without doing any SSH work.
128
+ * A client uses this to roll back a host switch when the
129
+ * new Hub runtime cannot be initialized.
130
+ */
131
+ activateConnection(id: string): boolean;
132
+ getStatuses(): RemoteEnvironmentStatus[];
133
+ run(id: string, input: RemoteCommandInput): Promise<RemoteCommandResult>;
134
+ dispose(): Promise<void>;
135
+ private ensureHelper;
136
+ private installHelper;
137
+ private stopManagedHub;
138
+ private inspectRemote;
139
+ private validateDirectory;
140
+ private execRemote;
141
+ private execRemoteAllowFailure;
142
+ private buildSshArgs;
143
+ private buildTunnelArgs;
144
+ private destination;
145
+ private requireProfile;
146
+ private setStatus;
147
+ private handleTunnelEnd;
148
+ private persistPendingCleanup;
149
+ private retryPendingCleanup;
150
+ private readProfiles;
151
+ private writeProfiles;
152
+ private withMutation;
153
+ }
154
+ export declare function remoteHelperBinaryFilename(target: RemoteHelperTarget): string;
155
+ export declare function runRemoteProcess(executable: string, args: string[], options: RemoteProcessOptions): Promise<RemoteCommandResult>;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,5 @@
1
+ import{createRequire as d0}from"node:module";var t0=d0(import.meta.url);import{homedir as p1}from"node:os";import{claimHubDaemonProcess as l1}from"@cerebriline/shared";import{setHomeDirIfUnset as c1}from"@cerebriline/shared/storage";import{createSessionId as L1,ensureLoopbackProxyBypass as P0,isHubProtocolCompatible as O1,resolveClineBuildEnv as A1,resolveHubCommandTimeoutMs as B1}from"@cerebriline/shared";import f1 from"ws";var x={name:"@cerebriline/core",description:"Cline Core SDK for Node Runtime",version:"0.0.92",repository:{type:"git",url:"https://github.com/cline/cline",directory:"sdk/packages/core"},type:"module",types:"./dist/index.d.ts",main:"./dist/index.js",private:!1,publishConfig:{access:"public"},exports:{".":{types:"./dist/index.d.ts",import:"./dist/index.js"},"./hub":{types:"./dist/hub/index.d.ts",import:"./dist/hub/index.js"},"./hub/daemon-entry":{types:"./dist/hub/daemon/entry.d.ts",import:"./dist/hub/daemon/entry.js"},"./telemetry":{types:"./dist/services/telemetry/index.d.ts",import:"./dist/services/telemetry/index.js"},"./services/feature-flags/posthog":{types:"./dist/services/feature-flags/posthog.d.ts",import:"./dist/services/feature-flags/posthog.js"},"./remote/helper-entry":{types:"./dist/remote/remote-helper-entry.d.ts",import:"./dist/remote/remote-helper-entry.js"},"./cloud":{types:"./dist/cloud/index.d.ts",import:"./dist/cloud/index.js"},"./remote/helper":{types:"./dist/remote/remote-helper.d.ts",import:"./dist/remote/remote-helper.js"}},scripts:{build:"bun run ./bun.mts && bun tsc -p tsconfig.build.json && bun run ./scripts/verify-runtime-build-id.ts",typecheck:"bun tsc -p tsconfig.dev.json --noEmit && bun run typecheck:smoke","typecheck:smoke":"bun tsc -p tsconfig.smoke.json --noEmit",test:"bun run test:unit && bun run test:e2e","test:live":"vitest run --config vitest.config.ts src/extensions/context/compaction.live.test.ts","test:compaction":"bun --conditions=development run scripts/compact-session.ts","test:unit":"vitest run --config vitest.config.ts","test:e2e":"vitest run --config vitest.e2e.config.ts","verify:routines":"zsh -lc 'bunx vitest run src/cron/schedule-service.test.ts --config vitest.config.ts'","test:watch":"vitest --config vitest.config.ts"},dependencies:{"@cerebriline/agents":"workspace:*","@cerebriline/llms":"workspace:*","@cerebriline/shared":"workspace:*","@joplin/turndown-plugin-gfm":"1.0.68","@lingo-reader/epub-parser":"0.4.6","@lingo-reader/fb2-parser":"0.4.6","@lingo-reader/mobi-parser":"0.4.6","@modelcontextprotocol/sdk":"^1.29.0","@opentelemetry/api":"^1.9.0","@opentelemetry/api-logs":"^0.214.0","@opentelemetry/exporter-logs-otlp-http":"^0.214.0","@opentelemetry/exporter-metrics-otlp-http":"^0.214.0","@opentelemetry/exporter-trace-otlp-http":"^0.214.0","@opentelemetry/resources":"^2.6.1","@opentelemetry/sdk-logs":"^0.214.0","@opentelemetry/sdk-metrics":"^2.6.1","@opentelemetry/sdk-trace-base":"^2.6.1","@opentelemetry/sdk-trace-node":"^2.6.1","@opentelemetry/semantic-conventions":"^1.40.0","@tesseract.js-data/eng":"1.0.0",cfb:"1.2.2","fast-png":"8.0.0",jiti:"^2.7.0",nanoid:"^5.1.7","node-machine-id":"^1.1.12",officeparser:"8.0.0","pdfjs-dist":"6.2.108","simple-git":"3.36.0","tesseract.js":"7.0.0","tree-sitter-wasms":"^0.1.12",turndown:"7.2.0","web-tree-sitter":"^0.25.0",ws:"^8.20.0",yaml:"^2.8.2",zod:"^4.3.6"},peerDependencies:{"posthog-node":"^5.8.0"},peerDependenciesMeta:{"posthog-node":{optional:!0}},devDependencies:{"@types/turndown":"^5.0.6","@types/ws":"^8.18.1","posthog-node":"^5.8.0"},engines:{node:">=22"},files:["assets","dist","scripts/document-reader-assets.mjs","!dist/**/*.d.ts.map"]};var Z0="session_not_found";class v extends Error{sessionId;code="session_not_found";constructor(J,j){super(j??(J?`session not found: ${J}`:"session not found"));this.sessionId=J;this.name="SessionNotFoundError"}}import{spawn as H2}from"node:child_process";import{closeSync as k2,mkdirSync as y2,openSync as b2,readFileSync as h2,unlinkSync as m2}from"node:fs";import{basename as v2,dirname as u2,join as p2}from"node:path";import{fileURLToPath as l2}from"node:url";import{CLINE_RUN_AS_HUB_DAEMON_ENV as c2,isBunEmbeddedModulePath as i2,isHubDaemonProcess as n2,resolveClineBuildEnv as E0,withResolvedClineBuildEnv as s2}from"@cerebriline/shared";import{createHash as o0,randomBytes as r0}from"node:crypto";import{mkdir as p,open as $0,readFile as N0,rename as e0,rm as I,writeFile as J2}from"node:fs/promises";import{dirname as W0,join as l}from"node:path";import{ensureLoopbackProxyBypass as j2,isHubProtocolCompatible as Q2}from"@cerebriline/shared";import{resolveClineDataDir as D,resolveClineDir as j6}from"@cerebriline/shared/storage";var Z2="CLINE_HUB_DISCOVERY_PATH",$2="CLINE_HUB_BUILD_ID",X2="CLINE_HUB_BUILD_EPOCH_MS",z2=30000,V2=15000,X0=100;function Y2(J){return J.replace(/[^a-zA-Z0-9_.-]+/g,"_")}function N2(J){return o0("sha256").update(J).digest("hex").slice(0,12)}function W2(J){if(!Number.isInteger(J)||!J||J<=0)return!1;try{return process.kill(J,0),!0}catch(j){return j instanceof Error&&"code"in j?String(j.code)==="EPERM":!1}}function z0(J){return new Promise((j)=>setTimeout(j,J))}function K2(J){return`${J}.lock`}async function G2(J){try{let j=JSON.parse(await N0(l(J,"owner.json"),"utf8"));if(typeof j.pid!=="number"||typeof j.acquiredAt!=="string")return;return{pid:j.pid,acquiredAt:j.acquiredAt}}catch{return}}async function u(J){await I(J,{recursive:!0,force:!0}).catch(()=>{return})}function C(){let J=process.env[$2]?.trim();if(J)return J;return"sdk-v1-eaa21cb169ac821d9a60e7382c178ff666d1e71f1d99d93bb7a92a0b758ae6d0".trim()||`source-${String(x.version)}`}function q2(){let J=Number(process.env[X2]);if(Number.isFinite(J)&&J>0)return J;return Number.isFinite(1791721996794)?1791721996794:void 0}function T(J,j=C()){let Q=Q2(J);if(!Q.compatible)return Q;let Z=J.buildId?.trim();if(!Z)return{compatible:!1,reason:"missing_build"};if(Z!==j)return{compatible:!1,reason:"build_mismatch"};return{compatible:!0}}function V0(J){return typeof J==="number"&&Number.isFinite(J)&&J>0?J:void 0}function Y0(J){let j=J?.trim().split(/[-+]/,1)[0];if(!j)return;let Q=j.split(".").map((Z)=>Number(Z));if(Q.length===0||Q.some((Z)=>!Number.isInteger(Z)||Z<0))return;return Q}function F2(J,j){for(let Q=0;Q<Math.max(J.length,j.length);Q++){let Z=J[Q]??0,$=j[Q]??0;if(Z!==$)return Z<$?-1:1}return 0}function K0(J,j){let Q=J.buildId?.trim(),Z=j.buildId?.trim();if(Q&&Z&&Q===Z)return 0;let $=V0(J.buildEpochMs),X=V0(j.buildEpochMs);if($!==void 0&&X!==void 0&&$!==X)return $<X?-1:1;let z=Y0(J.coreVersion),N=Y0(j.coreVersion);if(z&&N){let Y=F2(z,N);if(Y!==0)return Y}if(Q&&Z&&Q!==Z)return Q<Z?-1:1;return 0}function G0(){return{buildId:C(),buildEpochMs:q2(),coreVersion:String(x.version)}}function w(J,j){let Q=j?.self??G0(),Z=T(J,Q.buildId??"");if(Z.compatible)return!0;if(Z.reason!=="build_mismatch"&&Z.reason!=="missing_build")return!1;return K0(Q,J)<=0}function q0(J=process.argv[1]?.trim()||process.cwd()){let j=`hub-${N2(J)}`,Q=process.env[Z2]?.trim()||l(D(),"locks","hub","owners",`${Y2(j)}.json`);return{ownerId:j,discoveryPath:Q}}async function A(J){try{let j=JSON.parse(await N0(J,"utf8"));if(typeof j.hubId!=="string"||typeof j.protocolVersion!=="string"||typeof j.authToken!=="string"||typeof j.host!=="string"||typeof j.port!=="number"||typeof j.url!=="string"||typeof j.startedAt!=="string"||typeof j.updatedAt!=="string")return;return{hubId:j.hubId,protocolVersion:j.protocolVersion,minClientProtocolVersion:typeof j.minClientProtocolVersion==="string"?j.minClientProtocolVersion:void 0,maxClientProtocolVersion:typeof j.maxClientProtocolVersion==="string"?j.maxClientProtocolVersion:void 0,capabilities:Array.isArray(j.capabilities)?j.capabilities.filter((Q)=>typeof Q==="string"):void 0,coreVersion:typeof j.coreVersion==="string"?j.coreVersion:void 0,buildId:typeof j.buildId==="string"?j.buildId:void 0,buildEpochMs:typeof j.buildEpochMs==="number"?j.buildEpochMs:void 0,authToken:j.authToken,host:j.host,port:j.port,url:j.url,pid:typeof j.pid==="number"?j.pid:void 0,startedAt:j.startedAt,updatedAt:j.updatedAt}}catch{return}}async function F0(J,j,Q){await c(J,async()=>{let Z=W0(J);await p(Z,{recursive:!0});let $=`${J}.${process.pid}.${r0(6).toString("hex")}.tmp`,X;try{X=await $0($,"wx",384),await X.writeFile(`${JSON.stringify(j,null,2)}
2
+ `,{encoding:"utf8"}),await X.sync(),await X.close(),X=void 0,Q?.beforePublish?.(),await e0($,J);let z;try{z=await $0(Z,"r"),await z.sync()}catch{}finally{await z?.close().catch(()=>{return})}}catch(z){throw await X?.close().catch(()=>{return}),await I($,{force:!0}).catch(()=>{return}),z}})}async function _(J){await c(J,async()=>{await I(J,{force:!0}).catch(()=>{return})})}async function L0(J,j){return await c(J,async()=>{if((await A(J))?.hubId!==j)return!1;return await I(J,{force:!0}),!0})}async function O0(J,j,Q){let Z=K2(J);await p(W0(Z),{recursive:!0});let $=Date.now()+V2;while(!0){try{await p(Z,{recursive:!1})}catch(X){if((X instanceof Error&&"code"in X?String(X.code):"")!=="EEXIST")throw X;let N=await G2(Z);if(!N){if(Date.now()>=$){await u(Z);continue}await z0(X0);continue}let Y=Date.now()-Date.parse(N.acquiredAt);if(!W2(N.pid)||Y>z2){await u(Z);continue}if(Date.now()>=$)throw Error(`Timed out waiting for hub ${j} lock ${Z}`);await z0(X0);continue}try{return await J2(l(Z,"owner.json"),`${JSON.stringify({pid:process.pid,acquiredAt:new Date().toISOString()},null,2)}
3
+ `,"utf8"),await Q()}finally{await u(Z)}}}function c(J,j){return O0(`${J}.mutation`,"discovery mutation",j)}function A0(J,j){return O0(J,"startup",j)}async function P(J,j){j2();try{let Q=await fetch(j?.authToken?L2(J):f0(J),{headers:j?.authToken?{authorization:`Bearer ${j.authToken}`}:void 0,signal:j?.signal});if(!Q.ok)return;let Z=await Q.json();if(typeof Z.protocolVersion!=="string"||typeof Z.host!=="string"||typeof Z.port!=="number"||typeof Z.url!=="string")return;return{protocolVersion:Z.protocolVersion,minClientProtocolVersion:typeof Z.minClientProtocolVersion==="string"?Z.minClientProtocolVersion:void 0,maxClientProtocolVersion:typeof Z.maxClientProtocolVersion==="string"?Z.maxClientProtocolVersion:void 0,capabilities:Array.isArray(Z.capabilities)?Z.capabilities.filter(($)=>typeof $==="string"):void 0,coreVersion:typeof Z.coreVersion==="string"?Z.coreVersion:void 0,buildId:typeof Z.buildId==="string"?Z.buildId:void 0,buildEpochMs:typeof Z.buildEpochMs==="number"?Z.buildEpochMs:void 0,host:Z.host,port:Z.port,url:Z.url,hubId:typeof Z.hubId==="string"?Z.hubId:void 0,authToken:typeof Z.authToken==="string"?Z.authToken:void 0,pid:typeof Z.pid==="number"?Z.pid:void 0,startedAt:typeof Z.startedAt==="string"?Z.startedAt:void 0,updatedAt:typeof Z.updatedAt==="string"?Z.updatedAt:void 0}}catch{return}}function B0(J,j,Q="/hub"){return new URL(`ws://${J}:${j}${Q}`).toString()}function f0(J){let j=new URL(J);return j.protocol=j.protocol==="wss:"?"https:":"http:",j.pathname="/health",j.search="",j.toString()}function L2(J){let j=new URL(f0(J));return j.pathname="/status",j.toString()}import{CLINE_HUB_DEV_PORT as O2,CLINE_HUB_PORT as A2,resolveClineBuildEnv as B2}from"@cerebriline/shared";var f2="CLINE_HUB_HOST",U2="CLINE_HUB_PORT",M2="CLINE_HUB_PATHNAME",x2="127.0.0.1",C2=A2,_2="/hub";function U0(J){return B2(J)==="development"?O2:C2}function D2(J={}){return(J.env??process.env)[f2]?.trim()||x2}function R2(J={}){let Q=(J.env??process.env)[U2]?.trim();if(!Q)return U0(J);let Z=Number.parseInt(Q,10);if(!Number.isInteger(Z)||Z<1||Z>65535)return U0(J);return Z}function E2(J={}){return(J.env??process.env)[M2]?.trim()||_2}function M0(J={},j={}){return{host:J.host??D2(j),port:J.port??R2(j),pathname:J.pathname??E2(j)}}import{join as I2}from"node:path";import{execFile as S2}from"node:child_process";import{promisify as g2}from"node:util";import{processWorkspaceInfo as N6}from"@cerebriline/shared";import K6 from"simple-git";var G6=g2(S2);var T2="shared:cline",w2="CLINE_HUB_DISCOVERY_PATH",P2="hub-production";function R(J=T2){return q0(`${J}@${C()}`)}function H(){return{ownerId:P2,discoveryPath:process.env[w2]?.trim()||I2(D(),"locks","hub","production.json")}}var x0=15000,d2=200,C0=3000,t2=100,a2=[100,250,500,1000,2000],o2="--cline-hub-daemon",r2=3,e2=60000,_0=new Map;function J1(J,j=Date.now()){let Q=_0.get(J);if(!Q||j-Q.windowStartedAt>e2)return _0.set(J,{count:1,windowStartedAt:j}),!0;return Q.count+=1,Q.count<=r2}function j1(J){return[...J.host?["--host",J.host]:[],...typeof J.port==="number"?["--port",String(J.port)]:[],...J.pathname?["--pathname",J.pathname]:[]]}function Q1(){try{let J=p2(D(),"logs","hub-daemon.log");return y2(u2(J),{recursive:!0}),{fd:b2(J,"a"),logPath:J}}catch{return}}function Z1(){return E0()==="production"?H():R()}function E(J){return w(J)}function $1(J){try{let j=JSON.parse(h2(`${J}.superseded`,"utf8"));return{url:typeof j.url==="string"?j.url:void 0,authToken:typeof j.authToken==="string"?j.authToken:void 0,pid:typeof j.pid==="number"?j.pid:void 0}}catch{return}}function i(J){try{m2(`${J}.superseded`)}catch{}}function D0(J,j,Q){if(!j||j.url!==Q)return J;return{...J,authToken:J.authToken??j.authToken,pid:J.pid??j.pid}}async function S(J,j){try{return await P(J,{authToken:j})}catch{return}}async function R0(J,j){let Q=Date.now()+j;while(Date.now()<Q){if(!(await S(J))?.url)return!0;await new Promise(($)=>setTimeout($,t2))}return!1}async function s(J,j){if(!J1(J.url))return!1;await g(J.url,J.authToken,"retired by newer install").catch(()=>!1),await b(J.url,J.authToken).catch(()=>!1);let Q=await R0(J.url,C0);if(!Q&&J.pid&&X1(J.pid)){try{process.kill(J.pid,"SIGTERM")}catch{}Q=await R0(J.url,C0)}if(Q)await _(j).catch(()=>{return});return Q}function X1(J){try{return process.kill(J,0),!0}catch(j){return j?.code==="EPERM"}}async function z1(J){try{return(await d(J.url,J.authToken)).activeSessionCount>0}catch{return!1}}async function n(J,j){if(E(J))return"reusable";let Q=await g(J.url,J.authToken,"retired by newer install").catch(()=>!1);if(await z1(J)){if(Q)await g(J.url,J.authToken,"hub retirement deferred",{off:!0}).catch(()=>!1);return"deferred_busy"}let Z=await s(J,j);if(!Z&&Q)await g(J.url,J.authToken,"hub retirement failed",{off:!0}).catch(()=>!1);return Z?"retired":"failed"}async function V1(J){if(E0()!=="production")return;let j=R();if(j.discoveryPath===J.discoveryPath)return;let Q=await A(j.discoveryPath);if(Q?.url)await s(Q,j.discoveryPath);else await _(j.discoveryPath).catch(()=>{return})}function Y1(){let J=import.meta.url.endsWith(".ts")?"ts":"js";return l2(new URL(`./entry.${J}`,import.meta.url))}function N1(J,j){if(i2(J))return[o2];return[...j&&J.toLowerCase().endsWith(".ts")?["--conditions=development"]:[],J]}function W1(J,j){let Q=Y1(),Z=process.execPath?.trim();if(!Z)throw Error("unable to resolve runtime executable for hub daemon");let $=v2(Z).toLowerCase().includes("bun"),X=N1(Q,$);return{launcher:Z,args:[...X,"--cwd",J,...j1(j),...j.manageConnectors===!1?["--no-connectors"]:[]],cwd:J,env:{...s2(process.env),CLINE_NO_INTERACTIVE:"1",[c2]:"1"}}}function K1(J){if(!J||typeof J!=="object")return!1;if(("code"in J?J.code:void 0)==="ETXTBSY")return!0;let Q="message"in J?J.message:void 0;return typeof Q==="string"&&Q.includes("ETXTBSY")}function G1(J,j={}){if(n2())return;let Q=W1(J,j),Z=Q1();try{H2(Q.launcher,Q.args,{detached:!0,stdio:Z?["ignore",Z.fd,Z.fd]:"ignore",env:Q.env,cwd:Q.cwd,windowsHide:!0}).unref()}finally{if(Z)k2(Z.fd)}}async function q1(J,j={}){for(let Q=0;;Q++)try{G1(J,j);return}catch(Z){let $=a2[Q];if(!K1(Z)||$===void 0)throw Z;await new Promise((X)=>setTimeout(X,$))}}async function F1(J,j,Q={}){let Z=Q.host!==void 0||Q.port!==void 0||Q.pathname!==void 0||!!process.env.CLINE_HUB_PORT?.trim(),$=M0(Q),X=B0($.host,$.port,$.pathname),z=(K)=>{if(!Z)y(K.url,K.authToken);return K};await V1(J).catch(()=>{return});let N=await A(J.discoveryPath),Y=N?.url?void 0:$1(J.discoveryPath),W=!1;if(N?.url){let K=N.authToken;if(!K)W=!0,await s(N,J.discoveryPath);else{let G=await S(N.url,K);if(G?.url&&E(G)&&await B(G.url,{authToken:K}))return i(J.discoveryPath),z({url:G.url,authToken:K});if(G?.url){if(await n({...G,authToken:K},J.discoveryPath)==="deferred_busy"&&await B(G.url,{authToken:K}))return z({url:G.url,authToken:K})}else await _(J.discoveryPath).catch(()=>{return})}}let V=await S(X);if(V?.url){let K=D0(V,N??Y,X);if(E(V)){let L=[V.authToken,N?.authToken,Y?.authToken].filter((M)=>typeof M==="string"&&M.trim().length>0);for(let M of L){if(!await B(V.url,{authToken:M}))continue;let s0={hubId:V.hubId??`repaired-${V.port}`,protocolVersion:V.protocolVersion,minClientProtocolVersion:V.minClientProtocolVersion,maxClientProtocolVersion:V.maxClientProtocolVersion,capabilities:V.capabilities,coreVersion:V.coreVersion,buildId:V.buildId,authToken:M,host:V.host,port:V.port,url:V.url,pid:V.pid??N?.pid??Y?.pid,startedAt:V.startedAt??new Date().toISOString(),updatedAt:new Date().toISOString()};try{await F0(J.discoveryPath,s0)}catch{}return i(J.discoveryPath),z({url:V.url,authToken:M})}throw Error(`A compatible Cline Hub is already running at ${X}, but its discovery record is missing or unreadable and no usable auth token is available. Run 'cline doctor fix' to repair local hub discovery.${W?" This can happen immediately after upgrading from a build that wrote an empty hub auth token; run 'cline doctor fix' to stop the old daemon and repair local hub discovery.":""}`)}let G=await n(K,J.discoveryPath);if(G==="deferred_busy"){for(let L of[K.authToken,N?.authToken].filter((U)=>typeof U==="string"&&U.trim().length>0))if(await B(V.url,{authToken:L}))return z({url:V.url,authToken:L});if(Q.allowPortFallback!==!0&&$.port!==0)throw Error(`An older Cline Hub is running at ${X} and is still serving active sessions, so it was not replaced, but no usable auth token is available to attach to it. Finish those sessions, or run 'cline doctor fix' to stop the hub.`)}if(G==="failed"&&Q.allowPortFallback!==!0&&$.port!==0)throw Error(`An incompatible Cline Hub is already running at ${X} and could not be retired automatically. Run 'cline doctor fix' to stop stale hub daemons before starting a new hub.`)}let O=Q.allowPortFallback===!0&&$.port!==0?{...$,port:0}:$;await q1(j,{...O,manageConnectors:Q.manageConnectors});let f=Date.now()+x0;while(Date.now()<f){let K=await A(J.discoveryPath);if(K?.url&&K.authToken){let L=await S(K.url,K.authToken);if(L?.url&&E(L)&&await B(L.url,{authToken:K.authToken}))return i(J.discoveryPath),z({url:L.url,authToken:K.authToken})}let G=await S(X);if(G?.url&&!E(G)){let L=D0(G,K??Y,X),U=await n(L,J.discoveryPath);if(U==="deferred_busy"&&K?.authToken&&await B(G.url,{authToken:K.authToken}))return z({url:G.url,authToken:K.authToken});if(U==="failed"&&Q.allowPortFallback!==!0&&$.port!==0)throw Error(`An incompatible Cline Hub is still running at ${X} and could not be retired automatically. Run 'cline doctor fix' to stop stale hub daemons before starting a new hub.`)}await new Promise((L)=>setTimeout(L,d2))}throw Error(`Timed out after ${x0}ms waiting for detached hub startup.`)}async function k(J,j={}){let Q=Z1();return await A0(Q.discoveryPath,async()=>F1(Q,J,j))}function U1(){return A1()==="production"?H():R()}function M1(){let J=globalThis.WebSocket;if(!J)throw Error("Global WebSocket is not available in this runtime. Node 22+ is required for hub mode.");return J}function H0(J){if(typeof J==="string")return J;if(J instanceof Uint8Array)return Buffer.from(J).toString();if(J instanceof ArrayBuffer)return Buffer.from(J).toString();if(Array.isArray(J))return Buffer.concat(J.map((j)=>Buffer.from(j))).toString();if(J&&typeof J==="object"&&"data"in J&&typeof J.data<"u")return H0(J.data);return String(J)}function x1(J){if(typeof J==="string")return J;if(J instanceof Uint8Array)return Buffer.from(J).toString("utf8");if(J instanceof ArrayBuffer)return Buffer.from(J).toString("utf8");return""}function S0(J){let j=J,Q=x1(j.reason);return new q("hub_connection_closed",j.code||Q?`Hub connection closed (code=${j.code??0}${Q?`, reason=${Q}`:""})`:a,{closeCode:j.code,closeReason:Q||void 0})}function g0(J,j){if(J instanceof q)return J;if(J instanceof Error)return new q("hub_connect_failed",J.message);if(J&&typeof J==="object"&&"error"in J&&J.error instanceof Error)return new q("hub_connect_failed",J.error.message);let Q=J&&typeof J==="object"&&"message"in J&&typeof J.message==="string"?J.message.trim():"";if(Q)return new q("hub_connect_failed",Q);let Z=J&&typeof J==="object"&&"type"in J&&typeof J.type==="string"?J.type.trim():"";return new q("hub_connect_failed",Z?`Failed to connect to hub at ${j.toString()} (${Z} event before socket open).`:`Failed to connect to hub at ${j.toString()}.`)}var t="*",h=8000,C1="cline-hub-auth.",k0=new Map,y0=new Set,_1=3000;var a="Hub connection closed",D1=250,R1=5000,I0=0.5;class q extends Error{code;details;constructor(J,j,Q){super(j);this.code=J;this.details=Q;this.name="HubTransportError"}}function E1(J){return J instanceof q}class o extends Error{command;code;constructor(J,j,Q){super(Q);this.command=J;this.code=j;this.name="HubCommandError"}}function e(J,j={}){let Q=J.searchParams.get("authToken")?.trim();if(J.searchParams.delete("authToken"),Q)return Q;if(j.skipRegistry)return;let Z=J0(J.toString());return Z?k0.get(Z):void 0}function S1(J){try{let Q=new URL(J).hostname.toLowerCase().replace(/^\[|\]$/g,"");return Q==="localhost"||Q==="127.0.0.1"||Q==="::1"}catch{return!1}}function J0(J){if(!S1(J))return;let j=new URL(b0(J));return j.search="",j.hash="",j.toString()}function T0(J){let j=J0(J);return!!j&&y0.has(j)}function y(J,j){let Q=J0(J);if(Q){if(y0.add(Q),j?.trim())k0.set(Q,j)}return J}class j0{options;socket;connectPromise;clientId;currentUrl;recoveryPromise;pendingReplies=new Map;listeners=new Set;subscriptionCounts=new Map;lastEventSequenceByKey=new Map;reconnectTimer;reconnectAttempt=0;closedByClient=!1;connectGeneration=0;lastCloseError=new q("hub_connection_closed",a);sawSocketClose=!1;registered=!1;capabilities;constructor(J){this.options=J;if(J.authToken?.trim()&&J.resolveConnectionHeaders)throw Error("Hub connection headers cannot be combined with authToken authentication.");this.clientId=J.clientId??`core-${Math.random().toString(36).slice(2,10)}-${Date.now().toString(36)}`,this.currentUrl=J.url,this.capabilities=[...J.capabilities??[]]}getClientId(){return this.clientId}getUrl(){return this.currentUrl}isConnected(){return this.socket?.readyState===1&&this.registered}getConnectionError(){return this.isConnected()?null:this.lastCloseError}async updateCapabilities(J){if(this.capabilities=J.map((j)=>({...j})),!this.registered)return;await this.command("client.update",{capabilities:this.capabilities})}async connect(){if(this.connectPromise)return this.connectPromise;if(this.socket&&(this.socket.readyState===1||this.socket.readyState===0))return this.connectPromise??Promise.resolve();this.closedByClient=!1,this.clearReconnectTimer();let J=new URL(this.currentUrl),j=this.options.authToken?.trim()||e(J,{skipRegistry:Boolean(this.options.resolveConnectionHeaders)});if(J.hash="",j&&this.options.resolveConnectionHeaders)throw Error("Hub connection headers cannot be combined with authToken authentication.");let Q=++this.connectGeneration,Z=this.openSocket(J,j,Q),$;this.connectPromise=Z.then(async(z)=>{if($=z,await this.commandOnce("client.register",{clientId:this.clientId,clientType:this.options.clientType??"core",displayName:this.options.displayName??"core",transport:"native",actorKind:"client",capabilities:this.capabilities,metadata:{...this.options.metadata,version:this.options.clientVersion??String(x.version),pid:process.pid},workspaceContext:{workspaceRoot:this.options.workspaceRoot,cwd:this.options.cwd}},void 0,void 0,!1),Q!==this.connectGeneration||this.closedByClient){try{z.close()}catch{}throw this.lastCloseError}this.registered=!0;for(let N of this.subscriptionCounts.keys())this.sendSubscriptionFrame("stream.subscribe",this.subscriptionSessionIdFromKey(N));this.reconnectAttempt=0});let X=this.connectPromise;try{await X}catch(z){if(this.connectPromise===X)this.connectPromise=void 0;if($&&this.socket===$){this.lastCloseError=g0(z,J),this.registered=!1,this.sawSocketClose=!1,this.socket=void 0;try{$.close()}catch{}}if(!this.closedByClient&&this.hasActiveSubscriptions())this.scheduleReconnect();throw z}}async openSocket(J,j,Q){let Z=this.options.resolveConnectionHeaders,$;if(Z){let Y;try{$=await Promise.race([Promise.resolve().then(()=>Z()),new Promise((W,V)=>{Y=setTimeout(()=>{V(new q("hub_connect_timeout",`Timed out resolving hub connection headers after ${h}ms`))},h)})])}catch(W){let V=W instanceof q?W:new q("hub_connect_failed",W instanceof Error?W.message:String(W));if(Q===this.connectGeneration)this.lastCloseError=V;throw V}finally{clearTimeout(Y)}}if(Q!==this.connectGeneration||this.closedByClient)throw this.lastCloseError;if($&&Object.keys($).some((Y)=>Y.toLowerCase()==="sec-websocket-protocol")){let Y=new q("hub_connect_failed","Hub connection headers cannot set Sec-WebSocket-Protocol.");if(Q===this.connectGeneration)this.lastCloseError=Y;throw Y}let X=$?new f1(J.toString(),{headers:{...$}}):new(M1())(J.toString(),j?[`${C1}${j}`]:void 0);this.socket=X;let z=!1,N=new Promise((Y,W)=>{let V=!1,F=setTimeout(()=>{if(V)return;V=!0,z=!0;let O=new q("hub_connect_timeout",`Timed out connecting to hub after ${h}ms`);if(this.socket===X)this.lastCloseError=O,this.sawSocketClose=!1,this.connectPromise=void 0,this.socket=void 0;try{X.close()}catch{}W(O)},h);X.addEventListener("open",()=>{if(V)return;V=!0,clearTimeout(F),Y()}),X.addEventListener("error",(O)=>{if(V)return;V=!0,clearTimeout(F);let f=g0(O,J);if(this.socket===X)this.lastCloseError=f,this.sawSocketClose=!1,this.connectPromise=void 0,this.socket=void 0;W(f)}),X.addEventListener("close",(O)=>{if(V)return;V=!0,clearTimeout(F);let f=z?this.lastCloseError:S0(O);if(this.socket===X){if(!z)this.lastCloseError=f,this.sawSocketClose=!0;this.connectPromise=void 0,this.socket=void 0}W(f)})});return X.addEventListener("message",(Y)=>{this.handleFrame(JSON.parse(H0(Y)))}),X.addEventListener("close",(Y)=>{if(this.socket!==X)return;if(!z)this.lastCloseError=S0(Y),this.sawSocketClose=!0;this.registered=!1;for(let W of this.pendingReplies.values())W.reject(this.lastCloseError);if(this.pendingReplies.clear(),this.connectPromise=void 0,this.socket=void 0,!this.closedByClient&&this.hasActiveSubscriptions())this.scheduleReconnect()}),await N,X}subscribe(J,j){let Q=j?.sessionId?.trim()||void 0,Z={listener:J,sessionId:Q};return this.listeners.add(Z),this.adjustSubscriptionCount(Q,1),()=>{if(!this.listeners.delete(Z))return;this.adjustSubscriptionCount(Q,-1)}}async command(J,j,Q,Z){let $=0,X=J!=="client.register"&&J!=="client.unregister";while(!0)try{return await this.commandOnce(J,j,Q,Z)}catch(z){if(!X||$>=1||!await this.recoverLocalHubTransport(z))throw z;$+=1}}async commandOnce(J,j,Q,Z,$=!0){if($)await this.connect();Z?.beforeDispatch?.();let X=L1("hubreq_");Z?.onDispatch?.(X);let z=B1(J,Z?.timeoutMs),N=new Promise((W,V)=>{let F=z===null?void 0:setTimeout(()=>{if(!this.pendingReplies.delete(X))return;V(new o(J,"hub_command_timeout",`Hub command ${J} timed out after ${z}ms (hub=${this.currentUrl}, requestId=${X}, clientId=${this.clientId}). Check hub-daemon.log for matching command.start/command.slow entries, or run 'cline doctor fix' to restart the hub.`))},z);this.pendingReplies.set(X,{resolve:(O)=>{if(F)clearTimeout(F);W(O)},reject:(O)=>{if(F)clearTimeout(F);V(O)}})});try{this.sendFrame({kind:"command",envelope:{version:"v1",command:J,requestId:X,clientId:this.clientId,sessionId:Q,timeoutMs:z,payload:j}})}catch(W){throw this.pendingReplies.delete(X),W}let Y=await N;if(!Y.ok){if(Y.error?.code===Z0){let W=Q??(typeof j?.sessionId==="string"?j.sessionId:void 0);throw new v(W,Y.error.message)}throw new o(J,Y.error?.code,Y.error?.message??`Hub command ${J} failed`)}return Y}async recoverLocalHubTransport(J){if(!T0(this.currentUrl)||!E1(J))return!1;if(this.recoveryPromise)return await this.recoveryPromise;return this.recoveryPromise=(async()=>{let j=await w0({workspaceRoot:this.options.workspaceRoot,cwd:this.options.cwd}).catch(()=>{return});if(!j)return!1;return this.currentUrl=j,this.close(),!0})().finally(()=>{this.recoveryPromise=void 0}),await this.recoveryPromise}hasActiveSubscriptions(){return this.subscriptionCounts.size>0}clearReconnectTimer(){if(!this.reconnectTimer)return;clearTimeout(this.reconnectTimer),this.reconnectTimer=void 0}scheduleReconnect(){if(this.reconnectTimer||this.closedByClient||!this.hasActiveSubscriptions())return;let J=Math.min(D1*2**this.reconnectAttempt,R1),j=Math.round(J*(1-I0)+Math.random()*J*I0);this.reconnectTimer=setTimeout(()=>{this.reconnectTimer=void 0,this.reconnectSubscribedTransport()},j)}async reconnectSubscribedTransport(){if(this.closedByClient||!this.hasActiveSubscriptions())return;try{await this.connect(),this.reconnectAttempt=0}catch{if(!T0(this.currentUrl)){this.reconnectAttempt+=1,this.scheduleReconnect();return}try{let J=await w0({workspaceRoot:this.options.workspaceRoot,cwd:this.options.cwd});if(J){this.currentUrl=J,await this.connect(),this.reconnectAttempt=0;return}}catch{}this.reconnectAttempt+=1,this.scheduleReconnect()}}close(){let J=this.socket;if(this.closedByClient=!0,this.connectGeneration+=1,this.clearReconnectTimer(),this.registered=!1,J)this.lastCloseError=new q("hub_connection_closed",a);for(let j of this.pendingReplies.values())j.reject(this.lastCloseError);if(this.pendingReplies.clear(),this.connectPromise=void 0,!J)return;this.sawSocketClose=!1,this.socket=void 0;try{J.close()}catch{}}async dispose(){if(this.socket?.readyState===1&&this.registered)try{await this.command("client.unregister",void 0,void 0,{timeoutMs:2000})}catch{}this.close()}sendFrame(J){if(!this.socket||this.socket.readyState!==1){if(this.lastCloseError.code==="hub_connection_closed"&&!this.sawSocketClose)throw new q("hub_connection_not_open","Hub connection is not open.");throw this.lastCloseError}this.socket.send(JSON.stringify(J))}sendSubscriptionFrame(J,j){let Q=J==="stream.subscribe"?this.lastEventSequenceByKey.get(this.subscriptionKeyForSessionId(j)):void 0;this.sendFrame({kind:J,clientId:this.clientId,...j?{sessionId:j}:{},...Q!==void 0?{sinceSequence:Q}:{}})}adjustSubscriptionCount(J,j){let Q=this.subscriptionKeyForSessionId(J),Z=(this.subscriptionCounts.get(Q)??0)+j;if(Z<=0){if(this.subscriptionCounts.delete(Q),!this.hasActiveSubscriptions())this.clearReconnectTimer();if(j<0&&this.socket?.readyState===1)this.sendSubscriptionFrame("stream.unsubscribe",J);return}if(this.subscriptionCounts.set(Q,Z),j>0&&Z===1&&this.socket?.readyState===1)this.sendSubscriptionFrame("stream.subscribe",J)}subscriptionKeyForSessionId(J){return J??t}subscriptionSessionIdFromKey(J){return J===t?void 0:J}handleFrame(J){switch(J.kind){case"reply":{let j=J.envelope.requestId;if(!j)return;let Q=this.pendingReplies.get(j);if(!Q)return;this.pendingReplies.delete(j),Q.resolve(J.envelope);return}case"event":{let j=J.envelope.sequence;if(typeof j==="number"){let Q=J.envelope.sessionId?.trim();for(let Z of[t,Q]){if(!Z||!this.subscriptionCounts.has(Z))continue;let $=this.lastEventSequenceByKey.get(Z)??0;if(j>$)this.lastEventSequenceByKey.set(Z,j)}}for(let Q of this.listeners){if(Q.sessionId&&Q.sessionId!==J.envelope.sessionId?.trim())continue;Q.listener(J.envelope)}return}case"command":case"stream.subscribe":case"stream.unsubscribe":return}}}function b0(J){let j=new URL(J);if(j.protocol==="http:")j.protocol="ws:";else if(j.protocol==="https:")j.protocol="wss:";return j.toString()}async function B(J,j){let Q=new j0({url:J,authToken:j?.authToken,clientType:"hub-healthcheck",displayName:"hub healthcheck",workspaceRoot:j?.workspaceRoot,cwd:j?.cwd});try{return await Q.connect(),!0}catch{return!1}finally{Q.close()}}async function r(J,j){let Q=b0(J),Z=await P(Q,{authToken:j?.authToken});if(!Z)return{status:"unreachable",url:Q};if(j?.requireCurrentBuild){let $=C(),X=T(Z,$);if(!X.compatible&&!w(Z))return{status:X.reason==="unsupported_protocol"?"protocol_mismatch":"build_mismatch",url:Q}}else if(!O1(Z).compatible)return{status:"protocol_mismatch",url:Q};if(j?.verifyConnection===!0&&!await B(Q,{workspaceRoot:j.workspaceRoot,cwd:j.cwd,authToken:j.authToken}))return{status:"unreachable",url:Q};return{status:"compatible",url:Q}}function g1(J){let j=J&&typeof J==="object"&&Array.isArray(J.sessions)?J.sessions:[],Q=0,Z=new Set;for(let $ of j){if(!$||typeof $!=="object")continue;let X=$.participants;if(!Array.isArray(X)||X.length===0)continue;Q+=1;for(let z of X){let N=z&&typeof z==="object"?z.clientId:void 0;if(typeof N==="string"&&N.trim())Z.add(N)}}return{activeSessionCount:Q,participantClientCount:Z.size}}async function d(J,j,Q){let Z=new j0({url:J,authToken:j,clientType:"hub-recovery-check",displayName:"hub recovery check",workspaceRoot:Q?.workspaceRoot,cwd:Q?.cwd});try{let $=await Z.command("session.list",{limit:500},void 0,{timeoutMs:_1});return g1($.payload)}finally{await Z.dispose().catch(()=>{return})}}async function I1(J,j,Q){try{return(await d(J,j,Q)).activeSessionCount===0}catch{return!1}}async function T1(J,j){let Q=`${J.discoveryPath}.superseded`,Z=await A(Q);if(!Z?.url||!Z.authToken)return;let $=await r(Z.url,{authToken:Z.authToken});if($.status!=="compatible")return;if(await I1($.url,Z.authToken,j))return;return y($.url,Z.authToken)}async function w1(J={}){if(J.endpoint?.trim()){let $=await r(J.endpoint);return $.status==="compatible"?$.url:void 0}let j=U1(),Q=await A(j.discoveryPath);if(!Q?.url)return await T1(j,J);let Z=await r(Q.url,{authToken:Q.authToken,requireCurrentBuild:!0});if(Z.status==="compatible")return y(Z.url,Q.authToken);if(Z.status==="protocol_mismatch")await _(j.discoveryPath).catch(()=>{return});return}async function w0(J={}){let j=await w1(J);if(j&&await B(j,{workspaceRoot:J.workspaceRoot,cwd:J.cwd}))return j;if(J.endpoint?.trim())return;try{return(await k(J.workspaceRoot??process.cwd())).url}catch(Q){J.onStartupError?.(Q);return}}async function g(J,j,Q,Z){P0();let $=new URL(J),X=j?.trim()||e($);if($.protocol==="ws:")$.protocol="http:";else if($.protocol==="wss:")$.protocol="https:";if($.pathname="/drain",$.hash="",Q)$.searchParams.set("reason",Q);if(Z?.off)$.searchParams.set("off","1");return(await fetch($,{method:"POST",headers:X?{authorization:`Bearer ${X}`}:void 0})).ok}async function b(J,j){P0();let Q=new URL(J),Z=j?.trim()||e(Q);if(Q.protocol==="ws:")Q.protocol="http:";else if(Q.protocol==="wss:")Q.protocol="https:";return Q.pathname="/shutdown",Q.hash="",(await fetch(Q,{method:"POST",headers:Z?{authorization:`Bearer ${Z}`}:void 0})).ok}import{spawn as P1}from"node:child_process";import{userInfo as H1}from"node:os";import{basename as k1,delimiter as m}from"node:path";var Q0="__CLINE_SIDECAR_PATH_START__",m0="__CLINE_SIDECAR_PATH_END__",v0=5000,y1=`/bin/sh -c 'printf "%s%s%s" "${Q0}" "$PATH" "${m0}"'`,h0="CLINE_SIDECAR_SKIP_SHELL_PATH";function u0(J){return J==="darwin"?"/bin/zsh":"/bin/bash"}function b1(J,j){try{let Q=H1().shell?.trim();if(Q)return Q}catch{}return j.SHELL?.trim()||u0(J)}function h1(J,j){let Q=k1(J);if(Q==="csh"||Q==="tcsh")return{args:["-c",j],argv0:`-${Q}`};return{args:["-i","-l","-c",j]}}function m1(J){let j=J.indexOf(Q0);if(j===-1)return;let Q=J.indexOf(m0,j);if(Q===-1)return;let Z=J.slice(j+Q0.length,Q).trim();return Z.length>0?Z:void 0}function v1(J,j){let Q=[...J.split(m),...j.split(m)].map((Z)=>Z.trim()).filter((Z)=>Z.length>0);return Array.from(new Set(Q)).join(m)}function u1(J,j=v0){return new Promise((Q)=>{let Z=h1(J,y1),$=P1(J,Z.args,{argv0:Z.argv0,stdio:["ignore","pipe","ignore"],detached:!0}),X="",z=0,N=()=>{try{if($.pid)process.kill(-$.pid,"SIGKILL")}catch{$.kill("SIGKILL")}},Y=!1,W=(F)=>{if(Y)return;Y=!0,clearTimeout(V),$.stdout?.destroy(),N(),Q(F)},V=setTimeout(()=>{try{if($.pid)process.kill(-$.pid,"SIGKILL")}catch{$.kill("SIGKILL")}W(void 0)},j);$.stdout?.on("data",(F)=>{if(Y)return;if(z+=F.length,z>65536){W(void 0);return}X+=F.toString("utf8")}),$.on("error",()=>W(void 0)),$.on("close",()=>W(m1(X)))})}async function p0(J){let j=J?.platform??process.platform,Q=J?.env??process.env;if(j==="win32")return{status:"skipped",reason:"windows"};if(Q[h0]?.trim())return{status:"skipped",reason:h0};let Z=J?.userShell??b1(j,Q),$=J?.fallbackShell??u0(j),X=J?.timeoutMs??v0,z=Z===$?[[Z,X]]:[[Z,X],[$,X/2]];for(let[N,Y]of z){let W=await u1(N,Y);if(!W)continue;let V=v1(W,Q.PATH??"");return Q.PATH=V,{status:"applied",pathEntries:V.split(m).length,shell:N}}return{status:"failed",shell:Z}}var l0={readHubDiscovery:A,clearHubDiscoveryIfOwned:L0,probeProcess:(J)=>{process.kill(J,0)},requestHubShutdown:b,ensureDetachedHubServer:k,claimHubDaemonProcess:l1,loadHubDaemon:()=>import("@cerebriline/core/hub/daemon-entry"),ensureLoginShellPath:p0,setHomeDirIfUnset:c1,homeDir:p1,cwd:()=>process.cwd(),env:process.env,writeOutput:(J)=>process.stdout.write(J)};function c0(J,j){let Q=J.indexOf(j);return(Q>=0?J[Q+1]:void 0)?.trim()||void 0}function i0(J,j){let Q=c0(J,"--discovery-path");if(!Q)throw Error("--discovery-path is required for remote Hub management");return j.env.CLINE_HUB_DISCOVERY_PATH=Q,Q}async function i1(J=process.argv,j=l0){j.setHomeDirIfUnset(j.homeDir()),await j.ensureLoginShellPath();let Q=c0(J,"--cwd")??j.cwd();i0(J,j);let Z=await j.ensureDetachedHubServer(Q,{host:"127.0.0.1",port:0,pathname:"/hub",allowPortFallback:!0,manageConnectors:!1});j.writeOutput(`${JSON.stringify({...Z,cwd:Q,platform:process.platform,arch:process.arch})}
4
+ `)}async function n0(J=process.argv,j=l0){if(J.includes("--remote-hub-stop")){let Q=i0(J,j),Z=await j.readHubDiscovery(Q);if(Z&&typeof Z.pid==="number"&&Number.isInteger(Z.pid)&&Z.pid>0)try{j.probeProcess(Z.pid)}catch($){if($?.code==="ESRCH")return await j.clearHubDiscoveryIfOwned(Q,Z.hubId),!0}if(Z&&!await j.requestHubShutdown(Z.url,Z.authToken))throw Error("Remote Hub shutdown failed");return!0}if(J.includes("--remote-hub-ensure"))return await i1(J,j),!0;if(j.claimHubDaemonProcess())return await j.loadHubDaemon(),!0;return!1}(async()=>{if(!await n0())throw Error("A remote helper command is required")})().catch((J)=>{process.stderr.write(`${J instanceof Error?J.message:String(J)}
5
+ `),process.exitCode=1});
@@ -0,0 +1,29 @@
1
+ import { claimHubDaemonProcess } from "@cerebriline/shared";
2
+ import { setHomeDirIfUnset } from "@cerebriline/shared/storage";
3
+ import { requestHubShutdown } from "../hub/client";
4
+ import { ensureDetachedHubServer } from "../hub/daemon";
5
+ import { clearHubDiscoveryIfOwned, readHubDiscovery } from "../hub/discovery";
6
+ import { ensureLoginShellPath } from "./shell-path";
7
+ export type RemoteHelperDependencies = {
8
+ readHubDiscovery: typeof readHubDiscovery;
9
+ clearHubDiscoveryIfOwned: typeof clearHubDiscoveryIfOwned;
10
+ probeProcess: (pid: number) => void;
11
+ requestHubShutdown: typeof requestHubShutdown;
12
+ ensureDetachedHubServer: typeof ensureDetachedHubServer;
13
+ claimHubDaemonProcess: typeof claimHubDaemonProcess;
14
+ loadHubDaemon: () => Promise<unknown>;
15
+ ensureLoginShellPath: typeof ensureLoginShellPath;
16
+ setHomeDirIfUnset: typeof setHomeDirIfUnset;
17
+ homeDir: () => string;
18
+ cwd: () => string;
19
+ env: NodeJS.ProcessEnv;
20
+ writeOutput: (output: string) => void;
21
+ };
22
+ export declare function runRemoteHubEnsure(argv?: string[], dependencies?: RemoteHelperDependencies): Promise<void>;
23
+ /**
24
+ * Handles the SSH bootstrap command and the detached-daemon sentinel. The
25
+ * standalone helper is compiled for the target host and contains no client UI
26
+ * server or command router. Client executables may also use this entrypoint
27
+ * to support the daemon sentinel.
28
+ */
29
+ export declare function runRemoteHelperEntrypoint(argv?: string[], dependencies?: RemoteHelperDependencies): Promise<boolean>;
@@ -0,0 +1,4 @@
1
+ import{createRequire as s0}from"node:module";var t0=s0(import.meta.url);import{homedir as u1}from"node:os";import{claimHubDaemonProcess as p1}from"@cerebriline/shared";import{setHomeDirIfUnset as l1}from"@cerebriline/shared/storage";import{createSessionId as F1,ensureLoopbackProxyBypass as P0,isHubProtocolCompatible as L1,resolveClineBuildEnv as O1,resolveHubCommandTimeoutMs as A1}from"@cerebriline/shared";import B1 from"ws";var x={name:"@cerebriline/core",description:"Cline Core SDK for Node Runtime",version:"0.0.92",repository:{type:"git",url:"https://github.com/cline/cline",directory:"sdk/packages/core"},type:"module",types:"./dist/index.d.ts",main:"./dist/index.js",private:!1,publishConfig:{access:"public"},exports:{".":{types:"./dist/index.d.ts",import:"./dist/index.js"},"./hub":{types:"./dist/hub/index.d.ts",import:"./dist/hub/index.js"},"./hub/daemon-entry":{types:"./dist/hub/daemon/entry.d.ts",import:"./dist/hub/daemon/entry.js"},"./telemetry":{types:"./dist/services/telemetry/index.d.ts",import:"./dist/services/telemetry/index.js"},"./services/feature-flags/posthog":{types:"./dist/services/feature-flags/posthog.d.ts",import:"./dist/services/feature-flags/posthog.js"},"./remote/helper-entry":{types:"./dist/remote/remote-helper-entry.d.ts",import:"./dist/remote/remote-helper-entry.js"},"./cloud":{types:"./dist/cloud/index.d.ts",import:"./dist/cloud/index.js"},"./remote/helper":{types:"./dist/remote/remote-helper.d.ts",import:"./dist/remote/remote-helper.js"}},scripts:{build:"bun run ./bun.mts && bun tsc -p tsconfig.build.json && bun run ./scripts/verify-runtime-build-id.ts",typecheck:"bun tsc -p tsconfig.dev.json --noEmit && bun run typecheck:smoke","typecheck:smoke":"bun tsc -p tsconfig.smoke.json --noEmit",test:"bun run test:unit && bun run test:e2e","test:live":"vitest run --config vitest.config.ts src/extensions/context/compaction.live.test.ts","test:compaction":"bun --conditions=development run scripts/compact-session.ts","test:unit":"vitest run --config vitest.config.ts","test:e2e":"vitest run --config vitest.e2e.config.ts","verify:routines":"zsh -lc 'bunx vitest run src/cron/schedule-service.test.ts --config vitest.config.ts'","test:watch":"vitest --config vitest.config.ts"},dependencies:{"@cerebriline/agents":"workspace:*","@cerebriline/llms":"workspace:*","@cerebriline/shared":"workspace:*","@joplin/turndown-plugin-gfm":"1.0.68","@lingo-reader/epub-parser":"0.4.6","@lingo-reader/fb2-parser":"0.4.6","@lingo-reader/mobi-parser":"0.4.6","@modelcontextprotocol/sdk":"^1.29.0","@opentelemetry/api":"^1.9.0","@opentelemetry/api-logs":"^0.214.0","@opentelemetry/exporter-logs-otlp-http":"^0.214.0","@opentelemetry/exporter-metrics-otlp-http":"^0.214.0","@opentelemetry/exporter-trace-otlp-http":"^0.214.0","@opentelemetry/resources":"^2.6.1","@opentelemetry/sdk-logs":"^0.214.0","@opentelemetry/sdk-metrics":"^2.6.1","@opentelemetry/sdk-trace-base":"^2.6.1","@opentelemetry/sdk-trace-node":"^2.6.1","@opentelemetry/semantic-conventions":"^1.40.0","@tesseract.js-data/eng":"1.0.0",cfb:"1.2.2","fast-png":"8.0.0",jiti:"^2.7.0",nanoid:"^5.1.7","node-machine-id":"^1.1.12",officeparser:"8.0.0","pdfjs-dist":"6.2.108","simple-git":"3.36.0","tesseract.js":"7.0.0","tree-sitter-wasms":"^0.1.12",turndown:"7.2.0","web-tree-sitter":"^0.25.0",ws:"^8.20.0",yaml:"^2.8.2",zod:"^4.3.6"},peerDependencies:{"posthog-node":"^5.8.0"},peerDependenciesMeta:{"posthog-node":{optional:!0}},devDependencies:{"@types/turndown":"^5.0.6","@types/ws":"^8.18.1","posthog-node":"^5.8.0"},engines:{node:">=22"},files:["assets","dist","scripts/document-reader-assets.mjs","!dist/**/*.d.ts.map"]};var Z0="session_not_found";class v extends Error{sessionId;code="session_not_found";constructor(J,j){super(j??(J?`session not found: ${J}`:"session not found"));this.sessionId=J;this.name="SessionNotFoundError"}}import{spawn as P2}from"node:child_process";import{closeSync as H2,mkdirSync as k2,openSync as y2,readFileSync as b2,unlinkSync as h2}from"node:fs";import{basename as m2,dirname as v2,join as u2}from"node:path";import{fileURLToPath as p2}from"node:url";import{CLINE_RUN_AS_HUB_DAEMON_ENV as l2,isBunEmbeddedModulePath as c2,isHubDaemonProcess as i2,resolveClineBuildEnv as E0,withResolvedClineBuildEnv as n2}from"@cerebriline/shared";import{createHash as a0,randomBytes as o0}from"node:crypto";import{mkdir as p,open as $0,readFile as N0,rename as r0,rm as I,writeFile as e0}from"node:fs/promises";import{dirname as W0,join as l}from"node:path";import{ensureLoopbackProxyBypass as J2,isHubProtocolCompatible as j2}from"@cerebriline/shared";import{resolveClineDataDir as D,resolveClineDir as J6}from"@cerebriline/shared/storage";var Q2="CLINE_HUB_DISCOVERY_PATH",Z2="CLINE_HUB_BUILD_ID",$2="CLINE_HUB_BUILD_EPOCH_MS",X2=30000,z2=15000,X0=100;function V2(J){return J.replace(/[^a-zA-Z0-9_.-]+/g,"_")}function Y2(J){return a0("sha256").update(J).digest("hex").slice(0,12)}function N2(J){if(!Number.isInteger(J)||!J||J<=0)return!1;try{return process.kill(J,0),!0}catch(j){return j instanceof Error&&"code"in j?String(j.code)==="EPERM":!1}}function z0(J){return new Promise((j)=>setTimeout(j,J))}function W2(J){return`${J}.lock`}async function K2(J){try{let j=JSON.parse(await N0(l(J,"owner.json"),"utf8"));if(typeof j.pid!=="number"||typeof j.acquiredAt!=="string")return;return{pid:j.pid,acquiredAt:j.acquiredAt}}catch{return}}async function u(J){await I(J,{recursive:!0,force:!0}).catch(()=>{return})}function C(){let J=process.env[Z2]?.trim();if(J)return J;return"sdk-v1-eaa21cb169ac821d9a60e7382c178ff666d1e71f1d99d93bb7a92a0b758ae6d0".trim()||`source-${String(x.version)}`}function G2(){let J=Number(process.env[$2]);if(Number.isFinite(J)&&J>0)return J;return Number.isFinite(1791721996794)?1791721996794:void 0}function T(J,j=C()){let Q=j2(J);if(!Q.compatible)return Q;let Z=J.buildId?.trim();if(!Z)return{compatible:!1,reason:"missing_build"};if(Z!==j)return{compatible:!1,reason:"build_mismatch"};return{compatible:!0}}function V0(J){return typeof J==="number"&&Number.isFinite(J)&&J>0?J:void 0}function Y0(J){let j=J?.trim().split(/[-+]/,1)[0];if(!j)return;let Q=j.split(".").map((Z)=>Number(Z));if(Q.length===0||Q.some((Z)=>!Number.isInteger(Z)||Z<0))return;return Q}function q2(J,j){for(let Q=0;Q<Math.max(J.length,j.length);Q++){let Z=J[Q]??0,$=j[Q]??0;if(Z!==$)return Z<$?-1:1}return 0}function K0(J,j){let Q=J.buildId?.trim(),Z=j.buildId?.trim();if(Q&&Z&&Q===Z)return 0;let $=V0(J.buildEpochMs),X=V0(j.buildEpochMs);if($!==void 0&&X!==void 0&&$!==X)return $<X?-1:1;let z=Y0(J.coreVersion),N=Y0(j.coreVersion);if(z&&N){let Y=q2(z,N);if(Y!==0)return Y}if(Q&&Z&&Q!==Z)return Q<Z?-1:1;return 0}function G0(){return{buildId:C(),buildEpochMs:G2(),coreVersion:String(x.version)}}function w(J,j){let Q=j?.self??G0(),Z=T(J,Q.buildId??"");if(Z.compatible)return!0;if(Z.reason!=="build_mismatch"&&Z.reason!=="missing_build")return!1;return K0(Q,J)<=0}function q0(J=process.argv[1]?.trim()||process.cwd()){let j=`hub-${Y2(J)}`,Q=process.env[Q2]?.trim()||l(D(),"locks","hub","owners",`${V2(j)}.json`);return{ownerId:j,discoveryPath:Q}}async function A(J){try{let j=JSON.parse(await N0(J,"utf8"));if(typeof j.hubId!=="string"||typeof j.protocolVersion!=="string"||typeof j.authToken!=="string"||typeof j.host!=="string"||typeof j.port!=="number"||typeof j.url!=="string"||typeof j.startedAt!=="string"||typeof j.updatedAt!=="string")return;return{hubId:j.hubId,protocolVersion:j.protocolVersion,minClientProtocolVersion:typeof j.minClientProtocolVersion==="string"?j.minClientProtocolVersion:void 0,maxClientProtocolVersion:typeof j.maxClientProtocolVersion==="string"?j.maxClientProtocolVersion:void 0,capabilities:Array.isArray(j.capabilities)?j.capabilities.filter((Q)=>typeof Q==="string"):void 0,coreVersion:typeof j.coreVersion==="string"?j.coreVersion:void 0,buildId:typeof j.buildId==="string"?j.buildId:void 0,buildEpochMs:typeof j.buildEpochMs==="number"?j.buildEpochMs:void 0,authToken:j.authToken,host:j.host,port:j.port,url:j.url,pid:typeof j.pid==="number"?j.pid:void 0,startedAt:j.startedAt,updatedAt:j.updatedAt}}catch{return}}async function F0(J,j,Q){await c(J,async()=>{let Z=W0(J);await p(Z,{recursive:!0});let $=`${J}.${process.pid}.${o0(6).toString("hex")}.tmp`,X;try{X=await $0($,"wx",384),await X.writeFile(`${JSON.stringify(j,null,2)}
2
+ `,{encoding:"utf8"}),await X.sync(),await X.close(),X=void 0,Q?.beforePublish?.(),await r0($,J);let z;try{z=await $0(Z,"r"),await z.sync()}catch{}finally{await z?.close().catch(()=>{return})}}catch(z){throw await X?.close().catch(()=>{return}),await I($,{force:!0}).catch(()=>{return}),z}})}async function _(J){await c(J,async()=>{await I(J,{force:!0}).catch(()=>{return})})}async function L0(J,j){return await c(J,async()=>{if((await A(J))?.hubId!==j)return!1;return await I(J,{force:!0}),!0})}async function O0(J,j,Q){let Z=W2(J);await p(W0(Z),{recursive:!0});let $=Date.now()+z2;while(!0){try{await p(Z,{recursive:!1})}catch(X){if((X instanceof Error&&"code"in X?String(X.code):"")!=="EEXIST")throw X;let N=await K2(Z);if(!N){if(Date.now()>=$){await u(Z);continue}await z0(X0);continue}let Y=Date.now()-Date.parse(N.acquiredAt);if(!N2(N.pid)||Y>X2){await u(Z);continue}if(Date.now()>=$)throw Error(`Timed out waiting for hub ${j} lock ${Z}`);await z0(X0);continue}try{return await e0(l(Z,"owner.json"),`${JSON.stringify({pid:process.pid,acquiredAt:new Date().toISOString()},null,2)}
3
+ `,"utf8"),await Q()}finally{await u(Z)}}}function c(J,j){return O0(`${J}.mutation`,"discovery mutation",j)}function A0(J,j){return O0(J,"startup",j)}async function P(J,j){J2();try{let Q=await fetch(j?.authToken?F2(J):f0(J),{headers:j?.authToken?{authorization:`Bearer ${j.authToken}`}:void 0,signal:j?.signal});if(!Q.ok)return;let Z=await Q.json();if(typeof Z.protocolVersion!=="string"||typeof Z.host!=="string"||typeof Z.port!=="number"||typeof Z.url!=="string")return;return{protocolVersion:Z.protocolVersion,minClientProtocolVersion:typeof Z.minClientProtocolVersion==="string"?Z.minClientProtocolVersion:void 0,maxClientProtocolVersion:typeof Z.maxClientProtocolVersion==="string"?Z.maxClientProtocolVersion:void 0,capabilities:Array.isArray(Z.capabilities)?Z.capabilities.filter(($)=>typeof $==="string"):void 0,coreVersion:typeof Z.coreVersion==="string"?Z.coreVersion:void 0,buildId:typeof Z.buildId==="string"?Z.buildId:void 0,buildEpochMs:typeof Z.buildEpochMs==="number"?Z.buildEpochMs:void 0,host:Z.host,port:Z.port,url:Z.url,hubId:typeof Z.hubId==="string"?Z.hubId:void 0,authToken:typeof Z.authToken==="string"?Z.authToken:void 0,pid:typeof Z.pid==="number"?Z.pid:void 0,startedAt:typeof Z.startedAt==="string"?Z.startedAt:void 0,updatedAt:typeof Z.updatedAt==="string"?Z.updatedAt:void 0}}catch{return}}function B0(J,j,Q="/hub"){return new URL(`ws://${J}:${j}${Q}`).toString()}function f0(J){let j=new URL(J);return j.protocol=j.protocol==="wss:"?"https:":"http:",j.pathname="/health",j.search="",j.toString()}function F2(J){let j=new URL(f0(J));return j.pathname="/status",j.toString()}import{CLINE_HUB_DEV_PORT as L2,CLINE_HUB_PORT as O2,resolveClineBuildEnv as A2}from"@cerebriline/shared";var B2="CLINE_HUB_HOST",f2="CLINE_HUB_PORT",U2="CLINE_HUB_PATHNAME",M2="127.0.0.1",x2=O2,C2="/hub";function U0(J){return A2(J)==="development"?L2:x2}function _2(J={}){return(J.env??process.env)[B2]?.trim()||M2}function D2(J={}){let Q=(J.env??process.env)[f2]?.trim();if(!Q)return U0(J);let Z=Number.parseInt(Q,10);if(!Number.isInteger(Z)||Z<1||Z>65535)return U0(J);return Z}function R2(J={}){return(J.env??process.env)[U2]?.trim()||C2}function M0(J={},j={}){return{host:J.host??_2(j),port:J.port??D2(j),pathname:J.pathname??R2(j)}}import{join as g2}from"node:path";import{execFile as E2}from"node:child_process";import{promisify as S2}from"node:util";import{processWorkspaceInfo as Y6}from"@cerebriline/shared";import W6 from"simple-git";var K6=S2(E2);var I2="shared:cline",T2="CLINE_HUB_DISCOVERY_PATH",w2="hub-production";function R(J=I2){return q0(`${J}@${C()}`)}function H(){return{ownerId:w2,discoveryPath:process.env[T2]?.trim()||g2(D(),"locks","hub","production.json")}}var x0=15000,s2=200,C0=3000,t2=100,d2=[100,250,500,1000,2000],a2="--cline-hub-daemon",o2=3,r2=60000,_0=new Map;function e2(J,j=Date.now()){let Q=_0.get(J);if(!Q||j-Q.windowStartedAt>r2)return _0.set(J,{count:1,windowStartedAt:j}),!0;return Q.count+=1,Q.count<=o2}function J1(J){return[...J.host?["--host",J.host]:[],...typeof J.port==="number"?["--port",String(J.port)]:[],...J.pathname?["--pathname",J.pathname]:[]]}function j1(){try{let J=u2(D(),"logs","hub-daemon.log");return k2(v2(J),{recursive:!0}),{fd:y2(J,"a"),logPath:J}}catch{return}}function Q1(){return E0()==="production"?H():R()}function E(J){return w(J)}function Z1(J){try{let j=JSON.parse(b2(`${J}.superseded`,"utf8"));return{url:typeof j.url==="string"?j.url:void 0,authToken:typeof j.authToken==="string"?j.authToken:void 0,pid:typeof j.pid==="number"?j.pid:void 0}}catch{return}}function i(J){try{h2(`${J}.superseded`)}catch{}}function D0(J,j,Q){if(!j||j.url!==Q)return J;return{...J,authToken:J.authToken??j.authToken,pid:J.pid??j.pid}}async function S(J,j){try{return await P(J,{authToken:j})}catch{return}}async function R0(J,j){let Q=Date.now()+j;while(Date.now()<Q){if(!(await S(J))?.url)return!0;await new Promise(($)=>setTimeout($,t2))}return!1}async function s(J,j){if(!e2(J.url))return!1;await g(J.url,J.authToken,"retired by newer install").catch(()=>!1),await b(J.url,J.authToken).catch(()=>!1);let Q=await R0(J.url,C0);if(!Q&&J.pid&&$1(J.pid)){try{process.kill(J.pid,"SIGTERM")}catch{}Q=await R0(J.url,C0)}if(Q)await _(j).catch(()=>{return});return Q}function $1(J){try{return process.kill(J,0),!0}catch(j){return j?.code==="EPERM"}}async function X1(J){try{return(await t(J.url,J.authToken)).activeSessionCount>0}catch{return!1}}async function n(J,j){if(E(J))return"reusable";let Q=await g(J.url,J.authToken,"retired by newer install").catch(()=>!1);if(await X1(J)){if(Q)await g(J.url,J.authToken,"hub retirement deferred",{off:!0}).catch(()=>!1);return"deferred_busy"}let Z=await s(J,j);if(!Z&&Q)await g(J.url,J.authToken,"hub retirement failed",{off:!0}).catch(()=>!1);return Z?"retired":"failed"}async function z1(J){if(E0()!=="production")return;let j=R();if(j.discoveryPath===J.discoveryPath)return;let Q=await A(j.discoveryPath);if(Q?.url)await s(Q,j.discoveryPath);else await _(j.discoveryPath).catch(()=>{return})}function V1(){let J=import.meta.url.endsWith(".ts")?"ts":"js";return p2(new URL(`./entry.${J}`,import.meta.url))}function Y1(J,j){if(c2(J))return[a2];return[...j&&J.toLowerCase().endsWith(".ts")?["--conditions=development"]:[],J]}function N1(J,j){let Q=V1(),Z=process.execPath?.trim();if(!Z)throw Error("unable to resolve runtime executable for hub daemon");let $=m2(Z).toLowerCase().includes("bun"),X=Y1(Q,$);return{launcher:Z,args:[...X,"--cwd",J,...J1(j),...j.manageConnectors===!1?["--no-connectors"]:[]],cwd:J,env:{...n2(process.env),CLINE_NO_INTERACTIVE:"1",[l2]:"1"}}}function W1(J){if(!J||typeof J!=="object")return!1;if(("code"in J?J.code:void 0)==="ETXTBSY")return!0;let Q="message"in J?J.message:void 0;return typeof Q==="string"&&Q.includes("ETXTBSY")}function K1(J,j={}){if(i2())return;let Q=N1(J,j),Z=j1();try{P2(Q.launcher,Q.args,{detached:!0,stdio:Z?["ignore",Z.fd,Z.fd]:"ignore",env:Q.env,cwd:Q.cwd,windowsHide:!0}).unref()}finally{if(Z)H2(Z.fd)}}async function G1(J,j={}){for(let Q=0;;Q++)try{K1(J,j);return}catch(Z){let $=d2[Q];if(!W1(Z)||$===void 0)throw Z;await new Promise((X)=>setTimeout(X,$))}}async function q1(J,j,Q={}){let Z=Q.host!==void 0||Q.port!==void 0||Q.pathname!==void 0||!!process.env.CLINE_HUB_PORT?.trim(),$=M0(Q),X=B0($.host,$.port,$.pathname),z=(K)=>{if(!Z)y(K.url,K.authToken);return K};await z1(J).catch(()=>{return});let N=await A(J.discoveryPath),Y=N?.url?void 0:Z1(J.discoveryPath),W=!1;if(N?.url){let K=N.authToken;if(!K)W=!0,await s(N,J.discoveryPath);else{let G=await S(N.url,K);if(G?.url&&E(G)&&await B(G.url,{authToken:K}))return i(J.discoveryPath),z({url:G.url,authToken:K});if(G?.url){if(await n({...G,authToken:K},J.discoveryPath)==="deferred_busy"&&await B(G.url,{authToken:K}))return z({url:G.url,authToken:K})}else await _(J.discoveryPath).catch(()=>{return})}}let V=await S(X);if(V?.url){let K=D0(V,N??Y,X);if(E(V)){let L=[V.authToken,N?.authToken,Y?.authToken].filter((M)=>typeof M==="string"&&M.trim().length>0);for(let M of L){if(!await B(V.url,{authToken:M}))continue;let n0={hubId:V.hubId??`repaired-${V.port}`,protocolVersion:V.protocolVersion,minClientProtocolVersion:V.minClientProtocolVersion,maxClientProtocolVersion:V.maxClientProtocolVersion,capabilities:V.capabilities,coreVersion:V.coreVersion,buildId:V.buildId,authToken:M,host:V.host,port:V.port,url:V.url,pid:V.pid??N?.pid??Y?.pid,startedAt:V.startedAt??new Date().toISOString(),updatedAt:new Date().toISOString()};try{await F0(J.discoveryPath,n0)}catch{}return i(J.discoveryPath),z({url:V.url,authToken:M})}throw Error(`A compatible Cline Hub is already running at ${X}, but its discovery record is missing or unreadable and no usable auth token is available. Run 'cline doctor fix' to repair local hub discovery.${W?" This can happen immediately after upgrading from a build that wrote an empty hub auth token; run 'cline doctor fix' to stop the old daemon and repair local hub discovery.":""}`)}let G=await n(K,J.discoveryPath);if(G==="deferred_busy"){for(let L of[K.authToken,N?.authToken].filter((U)=>typeof U==="string"&&U.trim().length>0))if(await B(V.url,{authToken:L}))return z({url:V.url,authToken:L});if(Q.allowPortFallback!==!0&&$.port!==0)throw Error(`An older Cline Hub is running at ${X} and is still serving active sessions, so it was not replaced, but no usable auth token is available to attach to it. Finish those sessions, or run 'cline doctor fix' to stop the hub.`)}if(G==="failed"&&Q.allowPortFallback!==!0&&$.port!==0)throw Error(`An incompatible Cline Hub is already running at ${X} and could not be retired automatically. Run 'cline doctor fix' to stop stale hub daemons before starting a new hub.`)}let O=Q.allowPortFallback===!0&&$.port!==0?{...$,port:0}:$;await G1(j,{...O,manageConnectors:Q.manageConnectors});let f=Date.now()+x0;while(Date.now()<f){let K=await A(J.discoveryPath);if(K?.url&&K.authToken){let L=await S(K.url,K.authToken);if(L?.url&&E(L)&&await B(L.url,{authToken:K.authToken}))return i(J.discoveryPath),z({url:L.url,authToken:K.authToken})}let G=await S(X);if(G?.url&&!E(G)){let L=D0(G,K??Y,X),U=await n(L,J.discoveryPath);if(U==="deferred_busy"&&K?.authToken&&await B(G.url,{authToken:K.authToken}))return z({url:G.url,authToken:K.authToken});if(U==="failed"&&Q.allowPortFallback!==!0&&$.port!==0)throw Error(`An incompatible Cline Hub is still running at ${X} and could not be retired automatically. Run 'cline doctor fix' to stop stale hub daemons before starting a new hub.`)}await new Promise((L)=>setTimeout(L,s2))}throw Error(`Timed out after ${x0}ms waiting for detached hub startup.`)}async function k(J,j={}){let Q=Q1();return await A0(Q.discoveryPath,async()=>q1(Q,J,j))}function f1(){return O1()==="production"?H():R()}function U1(){let J=globalThis.WebSocket;if(!J)throw Error("Global WebSocket is not available in this runtime. Node 22+ is required for hub mode.");return J}function H0(J){if(typeof J==="string")return J;if(J instanceof Uint8Array)return Buffer.from(J).toString();if(J instanceof ArrayBuffer)return Buffer.from(J).toString();if(Array.isArray(J))return Buffer.concat(J.map((j)=>Buffer.from(j))).toString();if(J&&typeof J==="object"&&"data"in J&&typeof J.data<"u")return H0(J.data);return String(J)}function M1(J){if(typeof J==="string")return J;if(J instanceof Uint8Array)return Buffer.from(J).toString("utf8");if(J instanceof ArrayBuffer)return Buffer.from(J).toString("utf8");return""}function S0(J){let j=J,Q=M1(j.reason);return new q("hub_connection_closed",j.code||Q?`Hub connection closed (code=${j.code??0}${Q?`, reason=${Q}`:""})`:a,{closeCode:j.code,closeReason:Q||void 0})}function g0(J,j){if(J instanceof q)return J;if(J instanceof Error)return new q("hub_connect_failed",J.message);if(J&&typeof J==="object"&&"error"in J&&J.error instanceof Error)return new q("hub_connect_failed",J.error.message);let Q=J&&typeof J==="object"&&"message"in J&&typeof J.message==="string"?J.message.trim():"";if(Q)return new q("hub_connect_failed",Q);let Z=J&&typeof J==="object"&&"type"in J&&typeof J.type==="string"?J.type.trim():"";return new q("hub_connect_failed",Z?`Failed to connect to hub at ${j.toString()} (${Z} event before socket open).`:`Failed to connect to hub at ${j.toString()}.`)}var d="*",h=8000,x1="cline-hub-auth.",k0=new Map,y0=new Set,C1=3000;var a="Hub connection closed",_1=250,D1=5000,I0=0.5;class q extends Error{code;details;constructor(J,j,Q){super(j);this.code=J;this.details=Q;this.name="HubTransportError"}}function R1(J){return J instanceof q}class o extends Error{command;code;constructor(J,j,Q){super(Q);this.command=J;this.code=j;this.name="HubCommandError"}}function e(J,j={}){let Q=J.searchParams.get("authToken")?.trim();if(J.searchParams.delete("authToken"),Q)return Q;if(j.skipRegistry)return;let Z=J0(J.toString());return Z?k0.get(Z):void 0}function E1(J){try{let Q=new URL(J).hostname.toLowerCase().replace(/^\[|\]$/g,"");return Q==="localhost"||Q==="127.0.0.1"||Q==="::1"}catch{return!1}}function J0(J){if(!E1(J))return;let j=new URL(b0(J));return j.search="",j.hash="",j.toString()}function T0(J){let j=J0(J);return!!j&&y0.has(j)}function y(J,j){let Q=J0(J);if(Q){if(y0.add(Q),j?.trim())k0.set(Q,j)}return J}class j0{options;socket;connectPromise;clientId;currentUrl;recoveryPromise;pendingReplies=new Map;listeners=new Set;subscriptionCounts=new Map;lastEventSequenceByKey=new Map;reconnectTimer;reconnectAttempt=0;closedByClient=!1;connectGeneration=0;lastCloseError=new q("hub_connection_closed",a);sawSocketClose=!1;registered=!1;capabilities;constructor(J){this.options=J;if(J.authToken?.trim()&&J.resolveConnectionHeaders)throw Error("Hub connection headers cannot be combined with authToken authentication.");this.clientId=J.clientId??`core-${Math.random().toString(36).slice(2,10)}-${Date.now().toString(36)}`,this.currentUrl=J.url,this.capabilities=[...J.capabilities??[]]}getClientId(){return this.clientId}getUrl(){return this.currentUrl}isConnected(){return this.socket?.readyState===1&&this.registered}getConnectionError(){return this.isConnected()?null:this.lastCloseError}async updateCapabilities(J){if(this.capabilities=J.map((j)=>({...j})),!this.registered)return;await this.command("client.update",{capabilities:this.capabilities})}async connect(){if(this.connectPromise)return this.connectPromise;if(this.socket&&(this.socket.readyState===1||this.socket.readyState===0))return this.connectPromise??Promise.resolve();this.closedByClient=!1,this.clearReconnectTimer();let J=new URL(this.currentUrl),j=this.options.authToken?.trim()||e(J,{skipRegistry:Boolean(this.options.resolveConnectionHeaders)});if(J.hash="",j&&this.options.resolveConnectionHeaders)throw Error("Hub connection headers cannot be combined with authToken authentication.");let Q=++this.connectGeneration,Z=this.openSocket(J,j,Q),$;this.connectPromise=Z.then(async(z)=>{if($=z,await this.commandOnce("client.register",{clientId:this.clientId,clientType:this.options.clientType??"core",displayName:this.options.displayName??"core",transport:"native",actorKind:"client",capabilities:this.capabilities,metadata:{...this.options.metadata,version:this.options.clientVersion??String(x.version),pid:process.pid},workspaceContext:{workspaceRoot:this.options.workspaceRoot,cwd:this.options.cwd}},void 0,void 0,!1),Q!==this.connectGeneration||this.closedByClient){try{z.close()}catch{}throw this.lastCloseError}this.registered=!0;for(let N of this.subscriptionCounts.keys())this.sendSubscriptionFrame("stream.subscribe",this.subscriptionSessionIdFromKey(N));this.reconnectAttempt=0});let X=this.connectPromise;try{await X}catch(z){if(this.connectPromise===X)this.connectPromise=void 0;if($&&this.socket===$){this.lastCloseError=g0(z,J),this.registered=!1,this.sawSocketClose=!1,this.socket=void 0;try{$.close()}catch{}}if(!this.closedByClient&&this.hasActiveSubscriptions())this.scheduleReconnect();throw z}}async openSocket(J,j,Q){let Z=this.options.resolveConnectionHeaders,$;if(Z){let Y;try{$=await Promise.race([Promise.resolve().then(()=>Z()),new Promise((W,V)=>{Y=setTimeout(()=>{V(new q("hub_connect_timeout",`Timed out resolving hub connection headers after ${h}ms`))},h)})])}catch(W){let V=W instanceof q?W:new q("hub_connect_failed",W instanceof Error?W.message:String(W));if(Q===this.connectGeneration)this.lastCloseError=V;throw V}finally{clearTimeout(Y)}}if(Q!==this.connectGeneration||this.closedByClient)throw this.lastCloseError;if($&&Object.keys($).some((Y)=>Y.toLowerCase()==="sec-websocket-protocol")){let Y=new q("hub_connect_failed","Hub connection headers cannot set Sec-WebSocket-Protocol.");if(Q===this.connectGeneration)this.lastCloseError=Y;throw Y}let X=$?new B1(J.toString(),{headers:{...$}}):new(U1())(J.toString(),j?[`${x1}${j}`]:void 0);this.socket=X;let z=!1,N=new Promise((Y,W)=>{let V=!1,F=setTimeout(()=>{if(V)return;V=!0,z=!0;let O=new q("hub_connect_timeout",`Timed out connecting to hub after ${h}ms`);if(this.socket===X)this.lastCloseError=O,this.sawSocketClose=!1,this.connectPromise=void 0,this.socket=void 0;try{X.close()}catch{}W(O)},h);X.addEventListener("open",()=>{if(V)return;V=!0,clearTimeout(F),Y()}),X.addEventListener("error",(O)=>{if(V)return;V=!0,clearTimeout(F);let f=g0(O,J);if(this.socket===X)this.lastCloseError=f,this.sawSocketClose=!1,this.connectPromise=void 0,this.socket=void 0;W(f)}),X.addEventListener("close",(O)=>{if(V)return;V=!0,clearTimeout(F);let f=z?this.lastCloseError:S0(O);if(this.socket===X){if(!z)this.lastCloseError=f,this.sawSocketClose=!0;this.connectPromise=void 0,this.socket=void 0}W(f)})});return X.addEventListener("message",(Y)=>{this.handleFrame(JSON.parse(H0(Y)))}),X.addEventListener("close",(Y)=>{if(this.socket!==X)return;if(!z)this.lastCloseError=S0(Y),this.sawSocketClose=!0;this.registered=!1;for(let W of this.pendingReplies.values())W.reject(this.lastCloseError);if(this.pendingReplies.clear(),this.connectPromise=void 0,this.socket=void 0,!this.closedByClient&&this.hasActiveSubscriptions())this.scheduleReconnect()}),await N,X}subscribe(J,j){let Q=j?.sessionId?.trim()||void 0,Z={listener:J,sessionId:Q};return this.listeners.add(Z),this.adjustSubscriptionCount(Q,1),()=>{if(!this.listeners.delete(Z))return;this.adjustSubscriptionCount(Q,-1)}}async command(J,j,Q,Z){let $=0,X=J!=="client.register"&&J!=="client.unregister";while(!0)try{return await this.commandOnce(J,j,Q,Z)}catch(z){if(!X||$>=1||!await this.recoverLocalHubTransport(z))throw z;$+=1}}async commandOnce(J,j,Q,Z,$=!0){if($)await this.connect();Z?.beforeDispatch?.();let X=F1("hubreq_");Z?.onDispatch?.(X);let z=A1(J,Z?.timeoutMs),N=new Promise((W,V)=>{let F=z===null?void 0:setTimeout(()=>{if(!this.pendingReplies.delete(X))return;V(new o(J,"hub_command_timeout",`Hub command ${J} timed out after ${z}ms (hub=${this.currentUrl}, requestId=${X}, clientId=${this.clientId}). Check hub-daemon.log for matching command.start/command.slow entries, or run 'cline doctor fix' to restart the hub.`))},z);this.pendingReplies.set(X,{resolve:(O)=>{if(F)clearTimeout(F);W(O)},reject:(O)=>{if(F)clearTimeout(F);V(O)}})});try{this.sendFrame({kind:"command",envelope:{version:"v1",command:J,requestId:X,clientId:this.clientId,sessionId:Q,timeoutMs:z,payload:j}})}catch(W){throw this.pendingReplies.delete(X),W}let Y=await N;if(!Y.ok){if(Y.error?.code===Z0){let W=Q??(typeof j?.sessionId==="string"?j.sessionId:void 0);throw new v(W,Y.error.message)}throw new o(J,Y.error?.code,Y.error?.message??`Hub command ${J} failed`)}return Y}async recoverLocalHubTransport(J){if(!T0(this.currentUrl)||!R1(J))return!1;if(this.recoveryPromise)return await this.recoveryPromise;return this.recoveryPromise=(async()=>{let j=await w0({workspaceRoot:this.options.workspaceRoot,cwd:this.options.cwd}).catch(()=>{return});if(!j)return!1;return this.currentUrl=j,this.close(),!0})().finally(()=>{this.recoveryPromise=void 0}),await this.recoveryPromise}hasActiveSubscriptions(){return this.subscriptionCounts.size>0}clearReconnectTimer(){if(!this.reconnectTimer)return;clearTimeout(this.reconnectTimer),this.reconnectTimer=void 0}scheduleReconnect(){if(this.reconnectTimer||this.closedByClient||!this.hasActiveSubscriptions())return;let J=Math.min(_1*2**this.reconnectAttempt,D1),j=Math.round(J*(1-I0)+Math.random()*J*I0);this.reconnectTimer=setTimeout(()=>{this.reconnectTimer=void 0,this.reconnectSubscribedTransport()},j)}async reconnectSubscribedTransport(){if(this.closedByClient||!this.hasActiveSubscriptions())return;try{await this.connect(),this.reconnectAttempt=0}catch{if(!T0(this.currentUrl)){this.reconnectAttempt+=1,this.scheduleReconnect();return}try{let J=await w0({workspaceRoot:this.options.workspaceRoot,cwd:this.options.cwd});if(J){this.currentUrl=J,await this.connect(),this.reconnectAttempt=0;return}}catch{}this.reconnectAttempt+=1,this.scheduleReconnect()}}close(){let J=this.socket;if(this.closedByClient=!0,this.connectGeneration+=1,this.clearReconnectTimer(),this.registered=!1,J)this.lastCloseError=new q("hub_connection_closed",a);for(let j of this.pendingReplies.values())j.reject(this.lastCloseError);if(this.pendingReplies.clear(),this.connectPromise=void 0,!J)return;this.sawSocketClose=!1,this.socket=void 0;try{J.close()}catch{}}async dispose(){if(this.socket?.readyState===1&&this.registered)try{await this.command("client.unregister",void 0,void 0,{timeoutMs:2000})}catch{}this.close()}sendFrame(J){if(!this.socket||this.socket.readyState!==1){if(this.lastCloseError.code==="hub_connection_closed"&&!this.sawSocketClose)throw new q("hub_connection_not_open","Hub connection is not open.");throw this.lastCloseError}this.socket.send(JSON.stringify(J))}sendSubscriptionFrame(J,j){let Q=J==="stream.subscribe"?this.lastEventSequenceByKey.get(this.subscriptionKeyForSessionId(j)):void 0;this.sendFrame({kind:J,clientId:this.clientId,...j?{sessionId:j}:{},...Q!==void 0?{sinceSequence:Q}:{}})}adjustSubscriptionCount(J,j){let Q=this.subscriptionKeyForSessionId(J),Z=(this.subscriptionCounts.get(Q)??0)+j;if(Z<=0){if(this.subscriptionCounts.delete(Q),!this.hasActiveSubscriptions())this.clearReconnectTimer();if(j<0&&this.socket?.readyState===1)this.sendSubscriptionFrame("stream.unsubscribe",J);return}if(this.subscriptionCounts.set(Q,Z),j>0&&Z===1&&this.socket?.readyState===1)this.sendSubscriptionFrame("stream.subscribe",J)}subscriptionKeyForSessionId(J){return J??d}subscriptionSessionIdFromKey(J){return J===d?void 0:J}handleFrame(J){switch(J.kind){case"reply":{let j=J.envelope.requestId;if(!j)return;let Q=this.pendingReplies.get(j);if(!Q)return;this.pendingReplies.delete(j),Q.resolve(J.envelope);return}case"event":{let j=J.envelope.sequence;if(typeof j==="number"){let Q=J.envelope.sessionId?.trim();for(let Z of[d,Q]){if(!Z||!this.subscriptionCounts.has(Z))continue;let $=this.lastEventSequenceByKey.get(Z)??0;if(j>$)this.lastEventSequenceByKey.set(Z,j)}}for(let Q of this.listeners){if(Q.sessionId&&Q.sessionId!==J.envelope.sessionId?.trim())continue;Q.listener(J.envelope)}return}case"command":case"stream.subscribe":case"stream.unsubscribe":return}}}function b0(J){let j=new URL(J);if(j.protocol==="http:")j.protocol="ws:";else if(j.protocol==="https:")j.protocol="wss:";return j.toString()}async function B(J,j){let Q=new j0({url:J,authToken:j?.authToken,clientType:"hub-healthcheck",displayName:"hub healthcheck",workspaceRoot:j?.workspaceRoot,cwd:j?.cwd});try{return await Q.connect(),!0}catch{return!1}finally{Q.close()}}async function r(J,j){let Q=b0(J),Z=await P(Q,{authToken:j?.authToken});if(!Z)return{status:"unreachable",url:Q};if(j?.requireCurrentBuild){let $=C(),X=T(Z,$);if(!X.compatible&&!w(Z))return{status:X.reason==="unsupported_protocol"?"protocol_mismatch":"build_mismatch",url:Q}}else if(!L1(Z).compatible)return{status:"protocol_mismatch",url:Q};if(j?.verifyConnection===!0&&!await B(Q,{workspaceRoot:j.workspaceRoot,cwd:j.cwd,authToken:j.authToken}))return{status:"unreachable",url:Q};return{status:"compatible",url:Q}}function S1(J){let j=J&&typeof J==="object"&&Array.isArray(J.sessions)?J.sessions:[],Q=0,Z=new Set;for(let $ of j){if(!$||typeof $!=="object")continue;let X=$.participants;if(!Array.isArray(X)||X.length===0)continue;Q+=1;for(let z of X){let N=z&&typeof z==="object"?z.clientId:void 0;if(typeof N==="string"&&N.trim())Z.add(N)}}return{activeSessionCount:Q,participantClientCount:Z.size}}async function t(J,j,Q){let Z=new j0({url:J,authToken:j,clientType:"hub-recovery-check",displayName:"hub recovery check",workspaceRoot:Q?.workspaceRoot,cwd:Q?.cwd});try{let $=await Z.command("session.list",{limit:500},void 0,{timeoutMs:C1});return S1($.payload)}finally{await Z.dispose().catch(()=>{return})}}async function g1(J,j,Q){try{return(await t(J,j,Q)).activeSessionCount===0}catch{return!1}}async function I1(J,j){let Q=`${J.discoveryPath}.superseded`,Z=await A(Q);if(!Z?.url||!Z.authToken)return;let $=await r(Z.url,{authToken:Z.authToken});if($.status!=="compatible")return;if(await g1($.url,Z.authToken,j))return;return y($.url,Z.authToken)}async function T1(J={}){if(J.endpoint?.trim()){let $=await r(J.endpoint);return $.status==="compatible"?$.url:void 0}let j=f1(),Q=await A(j.discoveryPath);if(!Q?.url)return await I1(j,J);let Z=await r(Q.url,{authToken:Q.authToken,requireCurrentBuild:!0});if(Z.status==="compatible")return y(Z.url,Q.authToken);if(Z.status==="protocol_mismatch")await _(j.discoveryPath).catch(()=>{return});return}async function w0(J={}){let j=await T1(J);if(j&&await B(j,{workspaceRoot:J.workspaceRoot,cwd:J.cwd}))return j;if(J.endpoint?.trim())return;try{return(await k(J.workspaceRoot??process.cwd())).url}catch(Q){J.onStartupError?.(Q);return}}async function g(J,j,Q,Z){P0();let $=new URL(J),X=j?.trim()||e($);if($.protocol==="ws:")$.protocol="http:";else if($.protocol==="wss:")$.protocol="https:";if($.pathname="/drain",$.hash="",Q)$.searchParams.set("reason",Q);if(Z?.off)$.searchParams.set("off","1");return(await fetch($,{method:"POST",headers:X?{authorization:`Bearer ${X}`}:void 0})).ok}async function b(J,j){P0();let Q=new URL(J),Z=j?.trim()||e(Q);if(Q.protocol==="ws:")Q.protocol="http:";else if(Q.protocol==="wss:")Q.protocol="https:";return Q.pathname="/shutdown",Q.hash="",(await fetch(Q,{method:"POST",headers:Z?{authorization:`Bearer ${Z}`}:void 0})).ok}import{spawn as w1}from"node:child_process";import{userInfo as P1}from"node:os";import{basename as H1,delimiter as m}from"node:path";var Q0="__CLINE_SIDECAR_PATH_START__",m0="__CLINE_SIDECAR_PATH_END__",v0=5000,k1=`/bin/sh -c 'printf "%s%s%s" "${Q0}" "$PATH" "${m0}"'`,h0="CLINE_SIDECAR_SKIP_SHELL_PATH";function u0(J){return J==="darwin"?"/bin/zsh":"/bin/bash"}function y1(J,j){try{let Q=P1().shell?.trim();if(Q)return Q}catch{}return j.SHELL?.trim()||u0(J)}function b1(J,j){let Q=H1(J);if(Q==="csh"||Q==="tcsh")return{args:["-c",j],argv0:`-${Q}`};return{args:["-i","-l","-c",j]}}function h1(J){let j=J.indexOf(Q0);if(j===-1)return;let Q=J.indexOf(m0,j);if(Q===-1)return;let Z=J.slice(j+Q0.length,Q).trim();return Z.length>0?Z:void 0}function m1(J,j){let Q=[...J.split(m),...j.split(m)].map((Z)=>Z.trim()).filter((Z)=>Z.length>0);return Array.from(new Set(Q)).join(m)}function v1(J,j=v0){return new Promise((Q)=>{let Z=b1(J,k1),$=w1(J,Z.args,{argv0:Z.argv0,stdio:["ignore","pipe","ignore"],detached:!0}),X="",z=0,N=()=>{try{if($.pid)process.kill(-$.pid,"SIGKILL")}catch{$.kill("SIGKILL")}},Y=!1,W=(F)=>{if(Y)return;Y=!0,clearTimeout(V),$.stdout?.destroy(),N(),Q(F)},V=setTimeout(()=>{try{if($.pid)process.kill(-$.pid,"SIGKILL")}catch{$.kill("SIGKILL")}W(void 0)},j);$.stdout?.on("data",(F)=>{if(Y)return;if(z+=F.length,z>65536){W(void 0);return}X+=F.toString("utf8")}),$.on("error",()=>W(void 0)),$.on("close",()=>W(h1(X)))})}async function p0(J){let j=J?.platform??process.platform,Q=J?.env??process.env;if(j==="win32")return{status:"skipped",reason:"windows"};if(Q[h0]?.trim())return{status:"skipped",reason:h0};let Z=J?.userShell??y1(j,Q),$=J?.fallbackShell??u0(j),X=J?.timeoutMs??v0,z=Z===$?[[Z,X]]:[[Z,X],[$,X/2]];for(let[N,Y]of z){let W=await v1(N,Y);if(!W)continue;let V=m1(W,Q.PATH??"");return Q.PATH=V,{status:"applied",pathEntries:V.split(m).length,shell:N}}return{status:"failed",shell:Z}}var l0={readHubDiscovery:A,clearHubDiscoveryIfOwned:L0,probeProcess:(J)=>{process.kill(J,0)},requestHubShutdown:b,ensureDetachedHubServer:k,claimHubDaemonProcess:p1,loadHubDaemon:()=>import("@cerebriline/core/hub/daemon-entry"),ensureLoginShellPath:p0,setHomeDirIfUnset:l1,homeDir:u1,cwd:()=>process.cwd(),env:process.env,writeOutput:(J)=>process.stdout.write(J)};function c0(J,j){let Q=J.indexOf(j);return(Q>=0?J[Q+1]:void 0)?.trim()||void 0}function i0(J,j){let Q=c0(J,"--discovery-path");if(!Q)throw Error("--discovery-path is required for remote Hub management");return j.env.CLINE_HUB_DISCOVERY_PATH=Q,Q}async function c1(J=process.argv,j=l0){j.setHomeDirIfUnset(j.homeDir()),await j.ensureLoginShellPath();let Q=c0(J,"--cwd")??j.cwd();i0(J,j);let Z=await j.ensureDetachedHubServer(Q,{host:"127.0.0.1",port:0,pathname:"/hub",allowPortFallback:!0,manageConnectors:!1});j.writeOutput(`${JSON.stringify({...Z,cwd:Q,platform:process.platform,arch:process.arch})}
4
+ `)}async function s6(J=process.argv,j=l0){if(J.includes("--remote-hub-stop")){let Q=i0(J,j),Z=await j.readHubDiscovery(Q);if(Z&&typeof Z.pid==="number"&&Number.isInteger(Z.pid)&&Z.pid>0)try{j.probeProcess(Z.pid)}catch($){if($?.code==="ESRCH")return await j.clearHubDiscoveryIfOwned(Q,Z.hubId),!0}if(Z&&!await j.requestHubShutdown(Z.url,Z.authToken))throw Error("Remote Hub shutdown failed");return!0}if(J.includes("--remote-hub-ensure"))return await c1(J,j),!0;if(j.claimHubDaemonProcess())return await j.loadHubDaemon(),!0;return!1}export{c1 as runRemoteHubEnsure,s6 as runRemoteHelperEntrypoint};
@@ -0,0 +1,88 @@
1
+ /**
2
+ * Login-shell PATH resolution for the desktop sidecar.
3
+ *
4
+ * When the Tauri app is launched from Finder/the Dock on macOS, it inherits
5
+ * launchd's minimal PATH (/usr/bin:/bin:/usr/sbin:/sbin) instead of the
6
+ * user's shell PATH. The sidecar — and every process it spawns for the agent
7
+ * (bash tool, MCP servers) — then can't find tools like `gh` that live in
8
+ * /opt/homebrew/bin or other shell-profile-added directories, even though
9
+ * the same task works from the CLI in a terminal.
10
+ *
11
+ * At startup we ask the user's login shell for its PATH and merge it into
12
+ * process.env.PATH, so child processes see the same PATH a terminal would.
13
+ */
14
+ export declare function defaultShellFor(platform: NodeJS.Platform): string;
15
+ /**
16
+ * The user's configured login shell. The account database is authoritative:
17
+ * a GUI-launched process has no parent shell, so $SHELL may be unset there.
18
+ * userInfo() reads getpwuid(), which on macOS goes through DirectoryServices
19
+ * — the same source `dscl . -read /Users/$USER UserShell` reports — and on
20
+ * Linux resolves via NSS (/etc/passwd et al.). $SHELL and the platform
21
+ * default are fallbacks for environments with no passwd entry.
22
+ */
23
+ export declare function loginShellFor(platform: NodeJS.Platform, env: NodeJS.ProcessEnv): string;
24
+ export interface ShellInvocation {
25
+ args: string[];
26
+ /**
27
+ * argv[0] the shell should see. A leading dash is the historical "you
28
+ * are a login shell" signal, used where -l can't be passed as a flag.
29
+ */
30
+ argv0?: string;
31
+ }
32
+ /**
33
+ * How to invoke a shell so it sources its profiles and runs a command.
34
+ * csh/tcsh accept -l only as the sole flag, so they're marked login via the
35
+ * argv[0] dash convention instead (sources ~/.login on top of the always-read
36
+ * ~/.cshrc or ~/.tcshrc); everything else gets login (-l, ~/.zprofile —
37
+ * Homebrew's shellenv) plus interactive (-i, ~/.zshrc — nvm-style version
38
+ * managers) as separate flags.
39
+ */
40
+ export declare function shellInvocation(shell: string, command: string): ShellInvocation;
41
+ /**
42
+ * Extract the PATH value printed between the sentinel markers, ignoring any
43
+ * noise a shell profile writes to stdout around it.
44
+ */
45
+ export declare function extractMarkedPath(output: string): string | undefined;
46
+ /**
47
+ * Merge the login shell's PATH with the current one: shell entries first (so
48
+ * profile-managed dirs like /opt/homebrew/bin win), then any current entries
49
+ * the shell PATH doesn't already contain (so explicitly-injected dirs from
50
+ * the launching environment aren't lost). Duplicates are dropped.
51
+ */
52
+ export declare function mergePaths(shellPath: string, currentPath: string): string;
53
+ /**
54
+ * Run the user's shell with its profiles sourced and capture its PATH.
55
+ * Resolves to undefined on any failure (missing shell, timeout, profile
56
+ * error) — callers should treat that as "keep the current PATH".
57
+ */
58
+ export declare function resolveLoginShellPath(shell: string, timeoutMs?: number): Promise<string | undefined>;
59
+ /**
60
+ * Resolve the login shell's PATH and merge it into process.env.PATH. The
61
+ * shell comes from the account database (see loginShellFor); if it can't
62
+ * produce a PATH (exotic shell, broken profile), retry once with the
63
+ * platform default shell before giving up.
64
+ *
65
+ * No-op on Windows (the GUI PATH comes from the registry there) and when
66
+ * CLINE_SIDECAR_SKIP_SHELL_PATH is set. Failures are reported via the
67
+ * returned status but never block startup. The result never contains the
68
+ * resolved PATH itself so it is safe to log verbatim.
69
+ */
70
+ export declare function ensureLoginShellPath(options?: {
71
+ platform?: NodeJS.Platform;
72
+ env?: NodeJS.ProcessEnv;
73
+ timeoutMs?: number;
74
+ /** Test seam: overrides passwd/$SHELL discovery of the user's shell. */
75
+ userShell?: string;
76
+ /** Test seam: overrides the platform-default fallback shell. */
77
+ fallbackShell?: string;
78
+ }): Promise<{
79
+ status: "applied";
80
+ pathEntries: number;
81
+ shell: string;
82
+ } | {
83
+ status: "skipped";
84
+ reason: string;
85
+ } | {
86
+ status: "failed";
87
+ shell: string;
88
+ }>;
@@ -13,7 +13,7 @@ import { RuntimeOAuthTokenManager } from "../orchestration/runtime-oauth-token-m
13
13
  import type { RuntimeBuilder } from "../orchestration/session-runtime";
14
14
  import { SessionRuntime } from "../orchestration/session-runtime-orchestrator";
15
15
  import { type SessionBackend } from "./local/session-record";
16
- import type { PendingPromptsServiceApi, RestoreSessionInput, RestoreSessionResult, RuntimeHost, RuntimeHostSubscribeOptions, SendSessionInput, SessionConnectionUpdate, SessionUsageSummary, StartSessionInput, StartSessionResult } from "./runtime-host";
16
+ import type { ListSessionsOptions, PendingPromptsServiceApi, RestoreSessionInput, RestoreSessionResult, RuntimeHost, RuntimeHostSubscribeOptions, SendSessionInput, SessionConnectionUpdate, SessionUsageSummary, StartSessionInput, StartSessionResult } from "./runtime-host";
17
17
  export interface LocalRuntimeHostOptions {
18
18
  distinctId?: string;
19
19
  sessionService: SessionBackend;
@@ -106,7 +106,7 @@ export declare class LocalRuntimeHost implements RuntimeHost {
106
106
  stopSession(sessionId: string): Promise<void>;
107
107
  dispose(reason?: string): Promise<void>;
108
108
  getSession(sessionId: string): Promise<SessionRecord | undefined>;
109
- listSessions(limit?: number): Promise<SessionRecord[]>;
109
+ listSessions(limit?: number, options?: ListSessionsOptions): Promise<SessionRecord[]>;
110
110
  deleteSession(sessionId: string): Promise<boolean>;
111
111
  updateSession(sessionId: string, updates: {
112
112
  prompt?: string | null;
@@ -143,6 +143,8 @@ export interface PendingPromptsDeleteInput {
143
143
  promptId: string;
144
144
  }
145
145
  export interface PendingPromptsServiceApi {
146
+ /** Select and steer the current queue head atomically in the runtime. */
147
+ steerFirst(input: PendingPromptsListInput): Promise<PendingPromptMutationResult>;
146
148
  list(input: PendingPromptsListInput): Promise<SessionPendingPrompt[]>;
147
149
  update(input: PendingPromptsUpdateInput): Promise<PendingPromptMutationResult>;
148
150
  delete(input: PendingPromptsDeleteInput): Promise<PendingPromptMutationResult>;
@@ -183,6 +185,10 @@ export interface RestoreSessionResult {
183
185
  messages?: LlmsProviders.MessageWithMetadata[];
184
186
  checkpoint: CheckpointEntry;
185
187
  }
188
+ export interface ListSessionsOptions {
189
+ /** Only root sessions: excludes subagent and team-task child rows. */
190
+ rootOnly?: boolean;
191
+ }
186
192
  /**
187
193
  * RuntimeHost is the transport/runtime boundary for core session execution.
188
194
  * Callers must normalize broad local config into `RuntimeSessionConfig`
@@ -197,7 +203,7 @@ export interface RuntimeHost {
197
203
  stopSession(sessionId: string): Promise<void>;
198
204
  dispose(reason?: string): Promise<void>;
199
205
  getSession(sessionId: string): Promise<SessionRecord | undefined>;
200
- listSessions(limit?: number): Promise<SessionRecord[]>;
206
+ listSessions(limit?: number, options?: ListSessionsOptions): Promise<SessionRecord[]>;
201
207
  deleteSession(sessionId: string): Promise<boolean>;
202
208
  updateSession(sessionId: string, updates: {
203
209
  prompt?: string | null;
@@ -275,6 +281,12 @@ export interface RuntimeHost {
275
281
  }): Promise<boolean>;
276
282
  dispatchHookEvent(payload: HookEventPayload): Promise<void>;
277
283
  subscribe(listener: (event: CoreSessionEvent) => void, options?: RuntimeHostSubscribeOptions): () => void;
284
+ /**
285
+ * Whether this host currently holds a live-event subscription for the
286
+ * session. Optional: only hosts that subscribe to sessions individually
287
+ * (e.g. hub clients) have anything to report.
288
+ */
289
+ hasSessionSubscription?(sessionId: string): boolean;
278
290
  }
279
291
  export type RuntimeHostMode = "auto" | "local" | "hub" | "remote";
280
292
  export {};
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Serialize refresh/read/save across managers and processes sharing credentials.
3
+ * SQLite uses OS file locks, released even when a holder crashes. The lock file
4
+ * contains no credentials and must not be removed while processes are running.
5
+ */
6
+ export declare function withOAuthRefreshLock<T>(settingsPath: string, storageProviderId: string, run: () => Promise<T>): Promise<T>;
@@ -108,6 +108,10 @@ export declare class SessionRuntime {
108
108
  private readonly logger?;
109
109
  readonly telemetry?: ITelemetryService;
110
110
  private readonly conversation;
111
+ private readonly toolResultCache;
112
+ private cacheableToolNames;
113
+ private readonly maxCachedResultChars;
114
+ private pendingTerminalError;
111
115
  private readonly mistakeTracker;
112
116
  private readonly loopTracker;
113
117
  /** Loop-guard warnings awaiting the tool result they belong to. */
@@ -256,6 +260,7 @@ export declare class SessionRuntime {
256
260
  * pre-swap shape.
257
261
  */
258
262
  subscribeEvents(listener: SessionEventListener): () => void;
263
+ notifyPendingUserMessage(): void;
259
264
  abort(reason?: unknown): void;
260
265
  /** Shut the session down after any active run drains. */
261
266
  shutdown(_reason?: string, _timeoutMs?: number): Promise<void>;
@@ -271,7 +276,9 @@ export declare class SessionRuntime {
271
276
  runWithHead(head: readonly string[], userMessage: string): Promise<AgentResult>;
272
277
  continue(userMessage?: string, userImages?: string[], userFiles?: string[]): Promise<AgentResult>;
273
278
  private composeSystemPrompt;
279
+ private getRunAdmissionError;
274
280
  private executeRun;
281
+ private recordTerminalError;
275
282
  /**
276
283
  * Retry a run once when it failed with an auth-like error and the host
277
284
  * refreshed credentials via `config.onAuthError`. The failed attempt's