Skip to content

feat: add Windsurf IDE adapter for cascade + aichat indexing#10

Open
edcet wants to merge 1 commit into
Pilan-AI:mainfrom
edcet:feat/windsurf-adapter
Open

feat: add Windsurf IDE adapter for cascade + aichat indexing#10
edcet wants to merge 1 commit into
Pilan-AI:mainfrom
edcet:feat/windsurf-adapter

Conversation

@edcet
Copy link
Copy Markdown

@edcet edcet commented Apr 22, 2026

Summary

Adds a native Windsurf IDE adapter that indexes both:

  • Workspace aichat from ++Windsurf/User/workspaceStorage/*/state.vscdb++ (VS Code chat format)
  • Cascade/agent trajectory cache from ++Windsurf/User/globalStorage/state.vscdb++ (base64-encoded protobuf in ++codeium.windsurf++ JSON blob)

Key Design Decisions

  • SQLite as authoritative source: The ++/.codeium/windsurf/cascade/*.pb+~+ files are encrypted at rest and are NOT parsed. The unencrypted live data lives in the SQLite cache.
  • Hard-reject control characters: ++isCleanString++ rejects any byte < 0x20 (except \n, \t, \r) before the printable-ratio heuristic, eliminating protobuf wire-byte leakage into ++first_query++ and ++content++ fields.
  • Model metadata extraction: Populates ++Message.Model++ from trajectory metadata (e.g. ++MODEL_PRIVATE_10++, ++MODEL_SWE_1_5_SLOW++, ++kimi-k2-5++).
  • Meaningful project names: Derives session titles from ++cachedTrajectorySummaries++ metadata instead of generic ++windsurf-cascade++ placeholders.

Validation Matrix (10/10)

# Criterion Result
1 Build zero errors
2 first_query no corruption ✅ 0 control chars
3 Message.Model populated ✅ 3 models, 3,535 msgs
4 Project names meaningful ✅ 4 distinct titles
5 Role balance ~1:1 ✅ 1,767 assistant / 1,768 user
6 No duplicate sessions ✅ 0 duplicates
7 Binary runs
8 index.go integration ✅ 4 points
9 Search clean ✅ No wire-format noise
10 Zero new deps ✅ stdlib only

Testing

  • ++go vet ./...++: clean
  • ++go test -race -v ./...++: all pass
  • ++golangci-lint run --timeout=5m ./...++: clean (after removing unused func)
  • ++gofmt -l .++: our delta clean (2 pre-existing unformatted files untouched)

Files Changed

  • ++cmd/index_windsurf.go++ (new, ~700 lines)
  • ++cmd/index.go++ (integration: 4 insertion points)

Note on Code Signing

The ad-hoc ++codesign -s -++ signature causes macOS SIGKILL when the binary is placed in a Homebrew Cellar path (Gatekeeper/policy interaction). Running unsigned from ++/tmp++ or after removing the signature works correctly. This is a local-dev artifact and does not affect the upstream build (goreleaser handles proper signing).

@edcet edcet force-pushed the feat/windsurf-adapter branch from 01f303d to bec2647 Compare April 22, 2026 03:30
- Indexes Windsurf workspace aichat (workspaceStorage/state.vscdb)
- Indexes cascade/agent trajectory cache (globalStorage/state.vscdb)
- Parses unencrypted base64-encoded protobuf from codeium.windsurf
- Hardened isCleanString: hard-rejects control chars to prevent protobuf
  wire byte leakage into first_query and content fields
- Maps trajectory metadata to meaningful project names
- Populates Message.Model from trajectory metadata
- Role classification ~1:1 user:assistant
- Zero new dependencies, stdlib only
@edcet edcet force-pushed the feat/windsurf-adapter branch from bec2647 to 941f8c4 Compare April 22, 2026 03:31
Copy link
Copy Markdown
Contributor

@0xRaghu 0xRaghu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the substantial Windsurf adapter contribution. I pulled this locally and ran go test ./... plus go vet ./...; both passed.

I’m not comfortable merging it today as-is because the adapter is a large heuristic parser over Windsurf’s cached protobuf-like data and does not include fixture/unit coverage for the parsing and classification paths. I also noticed an incremental-indexing integration risk: the top-level index.go gate uses only globalStorage/state.vscdb to decide whether all Windsurf indexing is unchanged, but workspace aichat lives under per-workspace workspaceStorage/*/state.vscdb. If the global DB is unchanged while a workspace chat DB changed, the current top-level gate can skip indexWindsurf(home) entirely, so workspace chats may not re-index.

Suggested next step: remove the global-only skip from the top-level Windsurf block and let indexWindsurfWorkspaceChat / indexWindsurfTrajectoryCache make their own source-specific skip decisions, then add small fixtures or unit tests around parseTopLevelTrajectory, extractCleanStrings, and classifyMessages. Once that is covered, this should be much safer to merge.

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.

2 participants