mirror of
https://github.com/cline/cline.git
synced 2026-10-25 18:33:44 +08:00
dpc/remove-legacy-loader
8
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
82486434b3 |
fix(cli): make build:platforms:single work on Windows (#15206)
* fix(cli): make build:platforms:single work on Windows Replace shell rm -rf with rmSync in apps/cli/script/build.ts, retry temporary smoke-test directory cleanup while the detached hub process exits on Windows, and use mkdtempSync with non-Windows chmodSync in apps/cli/script/compile-binary.ts. * fix(cli): warn if smoke-test directory cleanup fails after retries Use rmSync maxRetries/retryDelay for post-smoke-test cleanup and log a warning with the directory path and error if removal still fails. |
||
|
|
2377a20973 |
fix(core): load embedded plugin and dashboard resources (#15080)
* fix(core): load embedded plugin and dashboard resources * fix(core): isolate subprocess Bun mode and retain system CA trust * fix(core): load compiled plugin resources directly from bunfs * test(desktop): compare native paths and tolerate Hub cleanup on Windows The standalone plugin test compared the child's process.execPath to realpathSync(cli), which keeps Windows 8.3 short names (RUNNER~1) while the child reports the long path. Use realpathSync.native. The dashboard test's cleanup could hit EBUSY while the stopped Hub released its cwd; retry it like the startup scenario cleanup does. Co-authored-by: Saoud Rizwan <saoudrizwan@users.noreply.github.com> * fix(core): package every declared SDK runtime export --------- Co-authored-by: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Co-authored-by: Saoud Rizwan <saoudrizwan@users.noreply.github.com> |
||
|
|
83ea9a41d1 |
refactor: Start the desktop and SSH remote hubs through the bundled Cline CLI (#14792)
* Let hosts choose the hub daemon launcher and defer spawn-only setup Adds setHubDaemonLauncher so an embedding process can start the hub daemon through a bundled Cline CLI instead of its own executable, and a beforeSpawn hook on ensureDetachedHubServer that only runs when a new daemon is actually started. * Add programmatic options to cline hub ensure hub ensure/start gain --json (URL + auth token), --allow-port-fallback, --no-connectors and --login-shell-path, and the hub command accepts --discovery-path for a dedicated discovery record. These let the desktop app and SSH remotes start or reuse a hub through the CLI. Also extracts the standalone binary compile step into script/compile-binary.ts so other packages can build the CLI binary. * Run SSH remote hubs through the Cline CLI SSH remotes now upload the Cline CLI binary and start or reuse the remote hub with 'cline hub ensure --json --discovery-path ...', stopping it with 'cline hub stop'. The dedicated remote helper entrypoint is removed; cleanup records from older releases still stop through the old flag. * Run the desktop backend on the bundled Cline CLI The desktop app no longer compiles its own executable. It bundles the self-contained Cline CLI (externalBin cline-cli) plus the backend as a JS bundle that runs on the CLI's embedded runtime. At startup the backend has the CLI run 'hub ensure', which reuses a compatible healthy Hub or starts one, and any Hub it starts later also goes through the CLI binary. Linux CLI copies are bundled for SSH remotes. * Launch the desktop backend through the bundled Cline CLI The Tauri shell resolves the bundled cline-cli and the backend bundle (per-platform resource layouts) and starts 'cline-cli run' on it. The Windows installer stops users of cline-cli.exe, and also stops and removes the backend executable of earlier releases on upgrade. * Recognize the CLI-hosted desktop backend in cline doctor --fix * Update desktop publish workflow and docs for the bundled Cline CLI Telemetry selfchecks and smoke tests run the backend bundle on the bundled CLI, and the Windows signature gate verifies cline-cli.exe. * fix(desktop): address runtime packaging review findings * fix(desktop): preserve failed hub cleanup and handle exited daemons * fix(hub): distinguish missing discovery records from read failures * fix(hub): preserve discovery recovery while enforcing strict shutdown reads * fix(cli): do not count hub commands as CLI activations (#14870) * fix(cli): do not count hub commands as CLI activations The desktop app runs `cline-cli hub ensure` on every launch and the SSH remote flow runs `cline hub ensure` on every connect. Both went through runCli(), which captured user.extension_activated unconditionally, so each desktop launch was double-counted as a CLI activation and every SSH remote host (with its own distinct id) showed up as a new CLI user. Skip the activation capture for the hub subcommand; it is plumbing other clients invoke, not a user activation. Hub-owned task telemetry is unaffected since the daemon path never enters runCli(). * test(cli): clear the hub command mock between main.test.ts cases * test(cli): stop stubbing the hub command module in main.test.ts The module-wide vi.mock("./commands/hub") replaced createHubCommand with a no-op, so `cline hub dashboard` (routed through createHubCommand) never reached the dashboard mock and three dashboard tests failed. Drop the module mock and assert the activation exclusion through `hub dashboard --no-open`, which is already mocked. --------- Co-authored-by: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> |
||
|
|
df56169ed5 |
fix(cli): let the compiled binary resolve plugin SDK imports natively (#15048)
* fix(cli): let the compiled binary resolve plugin SDK imports natively
Plugins import @cline/core from the wrapper's node_modules. Bun standalone
executables skip package.json loading at runtime by default, so every bare
import from those files failed to resolve natively and jiti fell back to
babel-transpiling the whole SDK graph (~440 files, ~8s cold). That blew the
8s plugin load timeout after an upgrade or reboot and left the plugin
failed for the life of the hub. With autoloadPackageJson the cold load
takes ~1.4s, matching the 3.0.70 subprocess sandbox.
* fix(cli): show the resumed transcript when startup posts a notice
Resuming a session hydrates the transcript after the session starts. A
plugin load failure posts a status notice during that start, and the
hydration guard treated any existing entry as user activity and skipped
the transcript, so the resumed session looked empty. Skip only once the
user has submitted, and keep startup notices after the transcript.
* Revert "fix(cli): show the resumed transcript when startup posts a notice"
This reverts commit
|
||
|
|
3ba8dd8fa7 |
chore: upgrade Bun to 1.4.2 (#14631)
* chore: upgrade Bun toolchain and embedded runtime to 1.4.2 Bun 1.4.1+ writes a valid ad-hoc Mach-O signature for bun build --compile output, so the CLI is no longer SIGKILLed on macOS 27, and 1.4 ships x64 runtimes as baseline-only, so compiled binaries run on pre-AVX2 CPUs. Pins engines.bun, packageManager, .tool-versions, every setup-bun step, and @types/bun. The lockfile only moves @types/bun/bun-types so the AI SDK hoisting is left untouched. * fix(core): swallow reader.cancel() rejection in web_fetch size guard Bun 1.4 rejects cancel() on an errored stream, which surfaced as an unhandled rejection right before the size-limit error was thrown. * build(cli): boot the hub from the compiled binary as a smoke test --version only proves the executable launches. Bun 1.4.1/1.4.2 have a compile-time chunk ordering regression with splitting: true that only shows up once real modules load, so start the hub daemon from the freshly compiled host binary in an isolated data dir and require a healthy status before the build is considered good. * test(core): stop asserting the forced-exit path in hub shutdown e2e Under Bun 1.3 http.Server.close() never settled while a WebSocket was open, so the daemon always exited through the 2s deadline and the e2e asserted the forced-exit log line. Bun 1.4 completes the graceful close (~50ms instead of ~2s in a side-by-side probe), so that line no longer appears. The exit code, timing, discovery cleanup, and endpoint checks still cover the behavior; the forced path stays covered by shutdown-coordinator.test.ts. * build(cli): isolate the smoke test hub from CLINE_HUB_DISCOVERY_PATH The env var overrides the data-dir-derived discovery record, so an inherited value would have pointed hub start/stop at a real hub. |
||
|
|
632fce5071 |
feat(llms): sampled cline-provider AI SDK tracing via the host OTLP exporter (#13974)
* fix(llms): limit Langfuse telemetry to Cline provider Refs ENG-2505 * fix(llms): include ClinePass in Langfuse telemetry Refs ENG-2505 * feat(llms): sampled cline-provider AI SDK tracing via the host OTLP exporter Enables the collector-relay tracing path: when the host telemetry service has registered an OTLP tracer provider, cline-provider streams can emit AI SDK spans without Langfuse credentials in the process. - CLINE_TRACE_SAMPLE_PERCENT (default 0 = off) gates emission; sampling is a deterministic FNV-1a hash of the task/session id, so whole tasks sample together and retries decide identically. - Metadata-only by default (recordInputs/recordOutputs false): models, tokens, timings, errors — no prompt or completion content. Content requires CLINE_TRACE_RECORD_CONTENT=true explicitly. - The direct Langfuse path (env credentials, hub/internal) is unchanged: full content, every request, provider-gated as before. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * feat(telemetry): client OTLP trace pipeline for cline-provider AI SDK spans Extension side of the Langfuse collector relay: - OpenTelemetryClientProvider gains a TracerProvider: when tracesExporter is configured, spans batch-export over OTLP (grpc / http/json / http/protobuf) to the same collector endpoint as logs/metrics. register() also installs the async context manager span parenting needs. - tracesExporter plumbed through all three config sources: build constants (OTEL_TRACES_EXPORTER), runtime env (CLINE_OTEL_TRACES_EXPORTER), and remote config (openTelemetryTracesExporter) — the last is the no-release kill switch. - SDK: a host that registers a traces exporter now defaults to 100% task sampling; CLINE_TRACE_SAMPLE_PERCENT reduces it (0 disables). Env reads are literal so build-time inlining works. Metadata-only stays the default; content still requires CLINE_TRACE_RECORD_CONTENT=true. - CLI build inlines the new envs alongside the existing OTEL set. No publish workflow sets OTEL_TRACES_EXPORTER yet, so shipped builds keep tracing dark — activation is a separate one-line-per-workflow PR. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(llms): honor the global telemetry opt-out on the trace relay path AI SDK spans bypass the ITelemetryService wrapper that enforces the user's opt-out for events and metrics, so an opted-out user's prompts would still have traced once a host registered an OTLP exporter. resolveAiSdkTelemetry now re-checks the shared global settings file (telemetryOptOut) per stream — covering startup state and mid-session opt-outs across extension and CLI. The credentialed direct Langfuse path is unchanged: it only activates on explicit operator config. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * style: biome format Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(llms): one trace export path per host — direct Langfuse declines when an OTLP tracer is registered Enablement is a per-stream boolean but export fan-out is processor-level: attaching the direct LangfuseSpanProcessor to a host-registered tracer provider ships every span twice (direct + collector relay). The direct path now declines instead of cooperating when a recording provider already owns the global slot; it only exports when it registers its own provider. A host therefore configures exactly one of LANGFUSE_* credentials or an OTLP traces exporter, and misconfiguring both is safe. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * feat(hub): daemon-distinct trace identity for Langfuse hub coverage (#14034) The detached hub daemon already has everything needed to emit AI SDK traces: it ships in the same compiled binary as the CLI (so the publish build's OTEL_TRACES_EXPORTER / CLINE_TRACE_RECORD_CONTENT inlining reaches it), its telemetry handle flows into the hub server and the scheduled-run handlers, core's OpenTelemetryProvider registers a global tracer when the exporter is configured, and shutdown already flushes with a hard deadline. What was missing is identity: spans carry only the OTel resource, not per-event metadata, so daemon-emitted traces were indistinguishable from CLI-local ones (both service.name=cline). The daemon now declares serviceName=cline-hub-daemon (+ serviceVersion), via new optional serviceName/serviceVersion fields on the shared OpenTelemetryClientConfig. Opt-out holds for the daemon unchanged: it is a same-machine, same-user process, so the shared global settings file the per-stream gate reads is the requesting user's own (shared/cloud topologies tracked in ENG-2525). Co-authored-by: Claude Fable 5 <noreply@anthropic.com> * fix(llms): fail closed when the telemetry opt-out cannot be verified The relay's opt-out guard treated every settings read failure as 'no opt-out recorded', so a corrupted or unreadable settings file (including a torn read of the non-atomic writer) silently re-enabled tracing for a user who had opted out. Only a genuinely absent file (ENOENT, first run) now reads as opted in; malformed JSON and every other read failure disable the relay — consent that cannot be verified is not consent. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(llms): identify the OTLP relay explicitly instead of inferring it from any recording tracer 'Some recording tracer exists' misclassified console-only tracing as the collector relay (enabling the relay decision) and — for mutable providers — newly suppressed the direct Langfuse attach that worked before the one-path guard. The hosts that build tracer providers now stamp a relay marker only when a real OTLP span processor was created (console-only providers stay unmarked), and the trace decisions key off that marker: - relay path enables only behind a marked provider; - the one-path decline fires only for marked providers — unmarked mutable providers keep the original cooperative attach behavior; - a relay decline is no longer cached, so direct Langfuse gets to retry once a relay is disposed. The marker lives on the provider instance (reached through the OTel API global), which survives bundled module duplication where a module-level registry would not. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * style: organize imports Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(telemetry): own and dispose remote trace clients across config updates * fix(llms): wire per-call Langfuse telemetry and isolate direct export * refactor(telemetry): reject unsupported providers before initialization * test(desktop): raise sidecar vitest timeout above the module-graph import cost The first test in each sidecar file pays the @cline/core → @cline/llms import cost, which lands within ~100ms of the 5s default on CI runners (commands-account failed at 5009ms; context.test.ts passed at 4923ms). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com> Co-authored-by: abeatrix <beatrix@cline.bot> |
||
|
|
d3d3bd8749 |
fix(cli): defer auto-update install until no CLI is attached to the hub (#13233)
* fix(core): bridge protections for updates landing under pre-3.0.55 clients Three pieces, each proven against real released artifacts: - postinstall shield: CLI versions <= 3.0.54 restart the hub daemon after a background auto-update even while it serves live sessions, and their fingerprint check then rejects every replacement hub, bricking the running TUI. That code is on users' machines and cannot be patched — but it runs only after the install completes, and it bails out harmlessly when no hub discovery record exists. The newly installed package's postinstall sets the record aside so the old updater never fires. - superseded-record fallback: the set-aside record is also the only source of the auth token and pid the next new-build launch needs to retire the displaced hub (a port probe carries neither); ensure reads it back. - bind retry: a hub retired on the fixed port can hold it ~2s after acking shutdown (watchdog force-exit); the replacement daemon retries EADDRINUSE for up to 5s instead of dying and leaving no hub at all. * fix(cli): defer auto-update install until no CLI is attached to the hub Installing while cline processes run swaps the npm package under them: their respawn paths break on the new build fingerprint, and the updater then restarted the hub daemon out from under live sessions (the 'Hub connection closed (code=1006)' incident). Guarding the restart treats the symptom; the fix is to never install under a running process. The startup check now only records that an update is available. The install runs at process exit, and only when the hub confirms no other cli* client is attached — desktop sidecars and connectors ship their own binaries, so only cli* clients make the swap unsafe. With nothing old running at install time, no hub restart is needed at all: the next launch retires the stale hub through the existing ensure path. Deletes restartHubServerIfRunning, ensureCliHubServerAfterUpdate, and their support code; manual 'cline update' still installs immediately and now just notes that the update applies on next start. * fix(cli): apply deferred update from the entrypoint exit sequence The CLI entrypoint always terminates with an explicit process.exit(), which never emits beforeExit — the hook the deferred installer waited on, so it would never have run (caught by review). Invoke applyDeferredUpdate directly from the entrypoint's exit sequence after disposeAll(), where every normal termination passes; crash paths deliberately skip it. Also clear the pending update once an install spawns so the apply is idempotent. * test(cli): isolate unit tests from the real ~/.cline A full vitest run could leave a real hub daemon running against the developer's actual ~/.cline discovery record (observed while validating this PR: a daemon spawned from the globally installed cline binary, attached to the real data dir). Point CLINE_DIR, CLINE_DATA_DIR, and CLINE_HUB_DISCOVERY_PATH at a per-worker temp dir and disable auto-update before any test file loads; subprocesses inherit the isolation via env. * fix(core): discard the superseded discovery record once consumed The set-aside record is one-shot recovery metadata, but nothing deleted it, and it feeds a pid into retireDiscoveredHub's SIGTERM. Weeks later a launch that finds no live record (routine after any retirement) could read the stale file and signal whatever process the OS recycled that pid onto (review finding by @abeatrix). Unlink it at every ensure resolution that ends with a live, verified hub; failure paths keep it for the next attempt. * fix(cli): harden the exit-time update gate Three review findings on the deferred-apply path: - A wedged hub could stall an otherwise-finished CLI for tens of seconds via the hub client's default timeouts; the whole exit-time query is now bounded to 3s, with timeout counting as attached (never install unless the hub positively confirms). - Sub-second commands exited before the startup version check resolved and silently dropped the update every time for one-shot-only usage; exit now grants the in-flight check a 250ms grace. - client.list can lose a TUI's registration during transport churn while its session connection survives, so an empty client list is not proof of safety; cross-check sessions with participants. Participants rather than session status: finished sessions linger idle forever and must not pin updates, and participant-less scheduled runs live in the hub process, which the binary swap does not touch. Verified live: a session-holding client invisible to client.list defers the install, and the gate opens once it disconnects. * docs(cli): fix stale beforeExit reference in the exit-gate comment * style(cli): apply biome formatting to update deferral code * fix(cli): let doctor see a hub whose record the update shield set aside During the shielded update window the discovery record is renamed to .superseded so pre-3.0.55 updaters cannot restart a busy hub. Doctor read only the primary record, so in that window it reported the live daemon - the one serving the user's still-open old session - as a stale hub daemon and advised 'cline doctor fix', which kills it and reproduces the exact 1006 incident the shield exists to prevent (found by QA). Doctor now falls back to the set-aside record the same way the ensure path does, and doctor fix clears the set-aside file along with the primary record so a deliberate reset does not leave stale retirement metadata pointing at a recyclable pid. * fix(core): keep shielded sessions on one Hub authority (#13244) * fix(core): recover shielded busy hub discovery * chore(core): instrument shielded hub recovery * fix(core): recover shielded hubs with attached clients * fix(cli): recognize shielded hubs in doctor * refactor(core): keep shield recovery minimal * fix(core): retain shared Hub idle helper semantics * chore(core): align busyness helper with the #13231 wording The participants-only hasActiveHubSessions here duplicates the change on bee/hub-lifecycle (this branch needs its semantics for the participant gate). Matching that version byte for byte lets the two merges resolve cleanly instead of conflicting. Also restores the module-registry reset comment this branch dropped - it documents a real local-vs-CI gotcha. |
||
|
|
220a21bdcf |
Move sdk/apps/ to apps/ (#11200)
* Move the apps to the root dir * Update all references from sdk/apps/ to apps/ * Update dependencies * Install bun types * Fix types * Fix types * Fix linter * Ingore apps from vscode * Fix security warning * Fix windows install * Enable windows dev mode * Revert "Enable windows dev mode" This reverts commit |