Skip to content

Release v1.47.0#567

Merged
conradkoh merged 6 commits into
masterfrom
release/v1.47.0
May 29, 2026
Merged

Release v1.47.0#567
conradkoh merged 6 commits into
masterfrom
release/v1.47.0

Conversation

@conradkoh
Copy link
Copy Markdown
Owner

@conradkoh conradkoh commented May 28, 2026

Release v1.47.0

What's in this release

feat: Cursor SDK harness (cursor-sdk)

Adds a new Cursor (SDK) agent harness using @cursor/sdk (Agent.create + agent.send + run.stream()), sitting alongside the existing Cursor (CLI) harness. Both appear in the UI.

Changes included:

  • CursorSdkAgentService + CursorSdkStreamAdapter — new SDK-based harness with lazy SDK loading (protects against sqlite3 native addon failures), keeper process pattern for PID-based lifecycle management, local.force + idempotencyKey on agent.send, proper stop() override calling run.cancel() + agent.close()
  • chatroom machine harness status — new diagnostic command listing all harnesses and their detection status
  • build.config.ts — TypeScript-typed Bun build config replacing raw CLI flags; @cursor/sdk externalized to fix pnpm isolation / sqlite3 native addon resolution
  • AgentProcessManager.doStop() — delegates to service.stop(pid) for consistent shutdown across all harnesses (CLI and SDK); cursor-sdk agents now get proper run.cancel() on daemon restart
  • HARNESS_GUIDE.md — end-to-end guide for implementing new harnesses (CLI-based and SDK-based), linked from all 8 harness implementation files
  • Webapp / backend: cursor-sdk harness ID registered in AGENT_HARNESSES, HARNESS_DISPLAY_NAMES, and isCursorSdkHarness() helper

chore: version bump to 1.47.0

test(cli): initDaemon test timeout increases for CI stability

Version

  • All package.json files → 1.47.0

Verification

  • pnpm typecheck — pass
  • pnpm test — 1139/1143 pass (4 pre-existing flaky timer tests in init.test.ts unrelated to this release)

conradkoh and others added 3 commits May 28, 2026 13:29
Co-authored-by: Cursor <cursoragent@cursor.com>
Pre-push hook was flaky: 2s auth poll plus init work exceeded the 5s default under parallel test load.

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@vercel
Copy link
Copy Markdown

vercel Bot commented May 28, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
chatroom Ready Ready Preview, Comment May 29, 2026 1:46am

…arness

* feat(cursor-sdk): add @cursor/sdk dependency

Co-authored-by: Cursor <cursoragent@cursor.com>

* feat(cursor-sdk): register harness, webapp labels, and tests

Co-authored-by: Cursor <cursoragent@cursor.com>

* feat(cursor-sdk): add cursor-sdk to AGENT_HARNESSES

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(cursor-sdk): lazy-load @cursor/sdk to prevent daemon crash on sqlite3 failure

The static top-level import caused the entire daemon to crash at startup if
sqlite3's native binary failed to load (ABI mismatch, wrong Node version, or
unsupported platform). Replace with a lazy dynamic import via loadSdk() so that:

- isInstalled() returns false when the SDK can't be loaded (harness hides
  gracefully instead of crashing the daemon)
- listModels() and spawn() call loadSdk() at runtime and surface the error
  only to that specific operation
- All other harnesses are unaffected when cursor-sdk native deps fail

Ref: https://forum.cursor.com/t/cursor-sdk-in-public-beta/159285 (sqlite3
native dep known issue; Cursor team working on custom store alternative)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(cursor-sdk): override detectInstallationEffect to use API key + SDK check

BaseCLIAgentService.detectInstallationEffect() checks for a CLI binary named
after the service's command ('cursor-sdk'). No such binary exists — the SDK
harness authenticates via CURSOR_API_KEY, not a CLI tool. This caused the
harness to always appear as NotInstalled and never show in the UI.

Override detectInstallationEffect() to delegate to isInstalled() (checks
CURSOR_API_KEY presence + successful @cursor/sdk native module load), matching
the actual installation semantics of this SDK-based harness.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(cli): add chatroom machine harness status command

Lists all registered harnesses and their detection status on the current
machine — useful for debugging why a harness is or isn't appearing in the UI
without needing to inspect daemon logs.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(cursor-sdk): externalize @cursor/sdk in bun build to fix sqlite3 resolution

Bun was inlining @cursor/sdk into the bundle. When bundled, the SDK's
internal require('sqlite3') resolved from dist/index.js's context, where
sqlite3 is not reachable due to pnpm's isolation. Marking @cursor/sdk as
external keeps it as a real runtime import so sqlite3 resolves correctly
from the SDK's own node_modules.

This fixes cursor-sdk showing "not installed" even when CURSOR_API_KEY is set.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* refactor(cli): extract bun build config to build.config.ts with type validation

Moves the build flags from a long inline CLI command to a dedicated
build.config.ts using the Bun.build() API. TypeScript's BuildConfig type
from @types/bun provides compile-time schema validation — invalid options
are caught by tsc before the build runs. The package.json build script is
now a concise two-step: typecheck then run the config file.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(cursor-sdk): add name, local.force, and idempotencyKey to agent calls

- name: labels each agent as "role@chatroomId" in Agent.list() for observability
- local.force: true on send() clears wedged runs left by crashed daemon processes
- idempotencyKey: unique per spawn prevents double-execution on network retries

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(cursor-sdk): enable sandboxOptions on local agent

Enables the SDK sandbox for local agents. The exact OS-level restrictions
aren't documented in the SDK, but enabling it applies whatever policy
Cursor loads — useful for limiting agent surface area during testing.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* revert(cursor-sdk): disable sandboxOptions — breaks agent functionality

The sandbox was too restrictive and caused the agent to stop working.
Reverting to the previous state without sandbox until the SDK documents
exactly what it restricts.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(daemon): call service.stop(pid) in doStop() for consistent shutdown across all harnesses

AgentProcessManager.doStop() was directly calling kill(-pid, 'SIGTERM') and bypassing
service.stop(pid). For CLI harnesses this worked, but for cursor-sdk the actual SDK run
lives as an async IIFE in the daemon process — killing the keeper placeholder didn't
stop the Cursor SDK run or call run.cancel()/agent.close().

Now doStop() delegates to the harness-registered service.stop(pid), which properly:
- For CLI harnesses: sends SIGTERM to process group + polls (BaseCLIAgentService.stop)
- For cursor-sdk: cancels SDK run, closes agent, then kills keeper (override in CursorSdkAgentService)

Falls back to direct kill-and-poll when no service is registered for the harness.
Also explicitly calls service.untrack(pid) after stop() since handleExit() returns
early in 'stopping' state and won't untrack otherwise.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Add harness implementation guide and link comments in all agent services.

Documents CLI-based and SDK-based harness patterns so future contributors can implement new runtimes without spelunking existing code.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(cursor-sdk): skip run.wait on abort and unify error logs

Guard run.wait() when session is aborted to avoid hanging the background
IIFE for up to an hour. Pass SIGTERM on cancelled exits and use logPrefix
for stderr error lines. Add test covering abort-during-stream path.

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
@conradkoh conradkoh merged commit aa42f44 into master May 29, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant