feat(orchestration): recognize Cursor & Windsurf as first-class harnesses#4775
feat(orchestration): recognize Cursor & Windsurf as first-class harnesses#4775CodeGhost21 wants to merge 8 commits into
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
✅ Files skipped from review due to trivial changes (1)
📝 WalkthroughWalkthroughAdds first-class ChangesHarness recognition and presentation
Estimated code review effort: 2 (Simple) | ~10 minutes Sequence Diagram(s)sequenceDiagram
participant HarnessSource
participant orchestrationSchema
participant HarnessGlyph
participant TinyPlaceRoster
HarnessSource->>orchestrationSchema: provide cursor or windsurf source
orchestrationSchema-->>HarnessGlyph: expose recognized harness type
orchestrationSchema-->>TinyPlaceRoster: expose recognized harness type
HarnessGlyph-->>TinyPlaceRoster: render glyph and grouped session
Possibly related PRs
Suggested labels: Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
Comment |
cargo fmt --all --check wraps the matches! arm now that the pattern list exceeds the line width; apply it so Rust Quality + Frontend format:check pass.
oxoxDev
left a comment
There was a problem hiding this comment.
Review — recognize Cursor & Windsurf ✅
Clean recognition slice. Approving.
harness_type_for()widened tocursor/windsurf; theHarnessTypeunion widen forces the exhaustiveGLYPH+HARNESS_GROUPStables complete at compile time — no silent "Other" fallthrough for the new providers.- Rust and frontend agree on the same 5-provider set; unknown sources still fall to "Other" (match →
None). - TDD on both sides:
harness_type_only_for_known_providersextended +TinyPlaceRosterasserts the sessions group under their own headers, not "Other". - Recognition-only: inert until an emitter produces
source = "cursor"|"windsurf"(the tiny.place adapters PR) — no runtime risk here.
No findings.
Findings from the Layer-2 adapter spike (companion to the recognition design): both harnesses are buildable observe+respond adapters; Cursor verified (cursor-agent -p), Windsurf/Devin build-from-docs. Records the adapter-contract mapping, the GUI-IDE differences vs codex/claude, and the Windsurf->Devin Desktop rebrand. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
3e41012
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/superpowers/specs/2026-07-10-cursor-windsurf-adapter-spike.md`:
- Around line 46-47: Resolve the canonical provider key before adapter
implementation: choose either “windsurf” or “devin,” or explicitly define alias
support, and apply that decision consistently across Rust recognition, frontend
grouping, and adapter provider values. Update the naming decision and
recognition slice documentation to remove the ambiguity.
- Line 12: The feasibility statement should remain conditional until the
required empirical spike tests pass. Update the opening claim to say both
adapters are likely feasible pending tests, remove the assertion that neither
has a hard blocker, and make any recommendation contingent on successful tests A
and B while preserving the inbound-delivery limitation.
- Line 20: Update the “MCP stdio hosting” row to state that Windsurf supports
both remote MCP field names, `serverUrl` and `url`, rather than claiming it uses
`serverUrl` instead of `url`; preserve the existing configuration details.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 60fb8f3e-9ca8-411d-847f-71ca9b3f9aa7
📒 Files selected for processing (1)
docs/superpowers/specs/2026-07-10-cursor-windsurf-adapter-spike.md
… windsurf mcp config, naming) Address review feedback on the adapter feasibility spike: - headline reframed as conditional on the two empirical spike-tests - windsurf mcp_config remote key clarified (serverUrl/url; moot for our stdio adapter) - naming decision resolved: keep harness key 'windsurf' (matches on-disk brand) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Empirical results from a throwaway Cursor hooks observer run against staging: - observe -> normalize -> render as a 'cursor' runtime session works live (real Cursor chat, conversation 4c17e405, both turns rendered) - spike-test A: MCP/hook subprocess gets a sanitized env; adapter must bake every needed var into mcp.json's env block - Gap 1: orchestrator reply fails 'No agent found' -- base58 agentId vs base64 identityKey encoding mismatch at the reply boundary (next PR) - Gap 2 / spike-test B: no supported way to inject into Cursor's live GUI chat; headless cursor-agent -p answers as a separate turn (open research) - first-contact ratchet desync recoverable via reset_session(rehandshake:true) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Summary
Teaches OpenHuman's orchestration engine to recognize
cursorandwindsurfas harness providers, so their sessions render with a first-class roster group and brand glyph instead of falling into the generic "Other" catch-all.This is the recognition slice of #4730 (renders the sessions once something emits them). The session-origination adapters that actually emit
harness.provider = "cursor" | "windsurf"live in thetiny.placeSDK and are a separate PR.Changes
Backend (
src/openhuman/orchestration/schemas.rs)harness_type_for()to accept"cursor"and"windsurf"alongsideclaude | codex | gemini.Frontend (
app/src/)HarnessTypeunion (orchestrationClient.ts) — the type-checker then forces the two exhaustive lookup tables to stay complete.HarnessGlyph.tsx): CursorCu(slate), WindsurfWs(teal).TinyPlaceRoster.tsx): Cursor, Windsurf.Testing
harness_type_only_for_known_providersextended withcursor/windsurfassertions — TDD red→green (cargo test -p openhuman --lib harness_type_only_for_known_providers: ok).HarnessGlyph.test.tsx+TinyPlaceRoster.test.tsxextended (assert the sessions group under Cursor/Windsurf headers, not "Other") — 11 tests pass.tsc --noEmitclean — confirms the widened union left no exhaustive consumer incomplete.Design + implementation-plan docs included under
docs/superpowers/.🤖 Generated with Claude Code
Summary by CodeRabbit