-
Notifications
You must be signed in to change notification settings - Fork 592
Releases: dwgx/WindsurfAPI
v2.0.145
v2.0.145 - security hardening (audit follow-up)
Defence-in-depth hardening from an internal security audit. No behavior change
on normal traffic; these only bound malformed/hostile/pathological inputs. The
audit found the core surfaces (auth, SSRF, credential redaction, command
execution) already solid; these close three residual items.
#1 — Resilient trajectory parsing against malformed protobuf
parseTrajectorySteps now degrades gracefully instead of throwing out of the
parser when an upstream Cascade payload is malformed or hostile:
- a bad root buffer returns
[]instead of throwing; - a single corrupt step is skipped instead of discarding the whole trajectory.
(The recursive trace walkers in proto-trace.js were already depth-bounded;
the production parsers descend a fixed set of known fields, so there was no
unbounded-recursion path — this change is about per-step robustness.)
#2 — Validate compose labels before docker self-update
docker-self-update.js already shell-quoted the compose project /
working_dir labels, but the file's own contract says not to trust them
blindly. Added isSafeComposeProject / isSafeComposeWorkingDir shape
validation (charset / clean-absolute-path); a malformed or hostile label now
makes self-update report unsafe-compose-labels and abort rather than reach
the deployer command. (Still opt-in via a mounted docker socket + dashboard
auth.)
#3 — Bound regex work on model output (ReDoS/CPU)
The narrative tool-intent extractor scans the full model output once per
declared tool name, and the reuse-fingerprint meta-tag stripper uses a
backreference regex that is quadratic on inputs with many unclosed tags. None
were exponential (dynamic parts are already escaped), but both could be driven
into polynomial blow-up by pathological model output. Added input length caps:
intent-extractor.js: cap scanned text at 200 KB (NLU recovery is
best-effort, so a prefix is fine);conversation-pool.jsstripMetaTags: cap at 256 KB (output only feeds the
reuse fingerprint, so the worst case is a cache miss).
tool-emulation.js dialect regexes were reviewed and found linear (lazy
quantifiers between escaped literals), so no change was needed there.
Validation
- New
test/v2145-hardening.test.jscovers all three (6 tests). - Full suite green; secret scan clean.
Assets 2
v2.0.144
v2.0.144 - WebFetch completed document handling
This release fixes the lab-gated native WebFetch path when the language server
has already executed read_url_content and returned a real web_document.
- Completed
read_url_content.web_documentsteps are no longer surfaced to
OpenAI clients as dead tool-call proposals. The proxy now preserves Cascade's
final assistant text withfinish_reason="stop". - If Cascade returns a completed WebFetch document but no final text, the proxy
falls back to the fetched document body as assistant content. - Pending WebFetch permission steps without a document keep the existing
proposal/wait behavior, and Bash/Read/Grep native proposal semantics are
unchanged. - Proto trace classification now checks
completed_web_documentbefore
pending_permission, so steps that contain bothweb_documentand a
requested-interaction echo are classified as completed.
Assets 2
v2.0.143
v2.0.143 - diagnostics and canary hardening
This release strengthens diagnostics for tool-call evidence collection
(#177/#178), hardens the WebFetch canary pipeline (#183), and completes
the SWE-1.6 special-agent POC boundary coverage (#190). No default
behavior changes; native bridge production scope remains Bash-family only.
BridgeResult diagnostics (#177/#178)
- New
BridgeResult[reqId]log line emitted after every tool-bearing
request (both streaming and non-streaming paths). - Tracks
cascadeToolCalls,mappedToolCalls,unmappedToolCalls,
emulatedToolCalls,totalToolCalls,argParseFailures, and
reverseFailuresper request. - Logs tool names and Cascade kinds but never arguments or user content.
- Combined with the existing
ToolRoute[...]pre-request log, reporters
can now distinguish: bridge enabled but no Cascade tool call returned,
Cascade tool call returned but reverse-mapping failed, emulation
fallback succeeded, and the zero-tool-call scenario.
WebFetch canary hardening (#183)
HandleCascadeUserInteractionRPC call wrapped in try/catch; approval
failures are logged with SHA-256 hashed cascade/origin identifiers and
do not terminate the polling loop.scripts/native-bridge-smoke.mjsWebFetch scenario now enforces a
hard verdict: onlycompleted_web_documentin proto trace counts as
pass;pending_permission,auto_run_decision_only, and error states
are explicit warn/fail with classification detail.- WebFetch preflight warns when
WEBFETCH_AUTO_APPROVE,
WEBFETCH_AUTO_APPROVE_ORIGINS, orPOLL_AFTER_TOOLenv vars are
missing (non-blocking).
SWE-1.6 special-agent boundary (#190)
/health?verbose=1now exposesqueueTimeoutMs,runTimeoutMs, and
outputLimitBytesin thespecialAgentblock when the backend is
enabled.- Added unit test for media content rejection (
unsupported_mediaon
image_urlcontent parts). scripts/special-agent-smoke.mjsnow runs two negative smoke stages
after the positive text-only chat: tools boundary (400 unsupported_tool_boundary) and media boundary (400 unsupported_media).
Validation
- 1098 tests pass (0 fail).
- Secret scan clean.
- No new dependencies.
Assets 2
v2.0.142
v2.0.142 - partial stream cleanup
This release keeps native bridge defaults unchanged.
Cursor / streaming compatibility
- Fixed the OpenAI streaming error tail after partial assistant content was
already delivered. The stream now finishes with a normalfinish_reason: "stop"chunk and[DONE]instead of appending a structured{"error": ...}
frame after user-visible content. - Empty streams that fail before any real content/tool/thinking payload is sent
still return the structured stream error frame, so clients keep actionable
diagnostics when no answer was delivered.
Validation
- Added regression coverage for partial upstream deadline failures after content
is emitted, plus the opposite case where only an empty role chunk was emitted.
Assets 2
v2.0.141
v2.0.141 - tool routing diagnostics
This release does not widen native bridge production defaults.
Tool routing diagnostics
- Added
ToolRoute[...]request logs for tool-bearing chat requests. The log
records requested tools,tool_choice-filtered tools, native mapped/unmapped
partitions, native bridge decision reason, tool preamble tier, and compact
routing reasons. /v1/responsesnow drops a forcedtool_choicewhen that choice points at
an unbridged server-side tool such asfile_search,computer_use_preview,
ormcp. This prevents a translated request from carrying a forced tool that
no longer exists after flattening.- README now has a short FAQ explaining how to interpret "no tool calls" and
why native bridge is not a general local IDE tool fix.
WebFetch trace canaries
scripts/native-bridge-smoke.mjsnow summarizes redacted
webFetchTrace.statevalues from proto trace JSONL files. Gated WebFetch
canaries can now report whether the LS reachedpending_permission,
completed_web_document,error, or another known branch without manually
inspecting trace records.- The trace summary is diagnostic only and does not change smoke pass/fail
criteria.
Validation
- Added regression coverage for Responses server-side
tool_choicepruning,
tool routing diagnostics, and smoke WebFetch trace summaries.
Assets 2
v2.0.140
v2.0.140 - truthful upstream cooldowns
What changed
- IP-level rate-limit burst short-circuiting now carries the real upstream cooldown instead of always telling clients to wait 30 seconds.
- When Windsurf returns messages like
Resets in: 27m12s, the 429 response now uses the same value inRetry-After,error.retry_after_ms, and the user-facing message. - Non-stream chat handling now supports the same dependency injection hooks as the stream path, so rate-limit behavior can be covered by behavior tests without starting a real language server.
- Non-stream Cascade reuse invalidation now also recognizes structured
upstream_deadline_exceeded/windsurf_provider_deadlineresponses, not only the raw upstream error text. - README FAQ now separates local RPM limits, upstream free-tier throttling, IP cooldowns, and the upstream ~240s provider deadline.
Context
Issues #176 and #189 showed real upstream cooldowns around 26-30 minutes, but the IP-burst guard surfaced a fixed 30-second retry hint. The guard was already doing the right thing by stopping account burn; this release makes the operator/client-facing cooldown truthful.
This does not bypass Windsurf upstream rate limits. It prevents misleading retry timing and reduces repeated hammering during an upstream IP cooldown.
Validation
node --test test/rate-limit.test.jsnpm.cmd run test:releasenode --test test/stream-error.test.js test/cascade-timeout-invalidation.test.js test/stream-pool-exhausted-error.test.jsnpm.cmd run test:shard -- 0 4 --timeout-ms=90000npm.cmd run test:shard -- 1 4 --timeout-ms=90000npm.cmd run test:shard -- 2 4 --timeout-ms=90000npm.cmd run test:shard -- 3 4 --timeout-ms=90000
Assets 2
v2.0.139
v2.0.139 - full CI shard hotfix
What changed
- Fixed
test/audit-fixes.test.json Linux by usingfileURLToPath(import.meta.url)instead of manually stripping the leading slash fromimport.meta.url. - Fixed fake HTTP/2 language-server tests to close/destroy active sessions before
server.close(), preventing CI shard timeouts intest/client-panel-retry.test.jsandtest/native-read-wrapper.test.js. - Bumped the package version and native-bridge canary note to v2.0.139.
Context
v2.0.138 Release, Docker build, and GitHub Release succeeded. The newly restored full CI shards then exposed these test-harness portability/resource-cleanup issues. This release keeps the v2.0.138 product changes and makes the full CI gate green.
Validation
node --test --test-force-exit test/audit-fixes.test.jsnode --test --test-force-exit test/client-panel-retry.test.jsnode --test --test-force-exit test/native-read-wrapper.test.jsnpm.cmd run test:releasenpm.cmd run test:shard -- 0 4 --timeout-ms=90000npm.cmd run test:shard -- 1 4 --timeout-ms=90000npm.cmd run test:shard -- 2 4 --timeout-ms=90000npm.cmd run test:shard -- 3 4 --timeout-ms=90000
Assets 2
v2.0.138
v2.0.138 - release gate, dashboard pagination, and memory guardrails
What changed
- CI now runs the full top-level test suite through deterministic shards instead of reusing the bounded release gate.
- The release gate remains bounded, but now covers the files touched by this stabilization pass: response cache, dashboard syntax, native bridge docs, shard runner, proto trace, secret scan, release workflow, and version metadata.
- Modern dashboard proxy-account and abnormal-account tables now use paged account summaries instead of loading hundreds or thousands of rows in one request. The experimental sketch skin now uses lightweight summary rows for those two panels; its main account table still uses the full account payload because the inline detail editor depends on full fields.
- Native bridge documentation now states the safe default more explicitly: command tools remain the only mature production default; Read, Grep, Glob, WebSearch, and WebFetch stay protocol-lab gated until trace evidence is complete.
- SWE-1.6 is documented as a special-agent / ACP route, not a normal catalog-model fix.
- Response cache now has a byte budget (
RESPONSE_CACHE_MAX_BYTES/WINDSURFAPI_RESPONSE_CACHE_MAX_BYTES, default 16 MiB). Values accept bytes or units such as16m/1g. Oversized entries are skipped, and old entries are evicted when total cached response bytes exceed the budget.
Not changed
- Read
type=14 / field=19reverse engineering is still not declared complete. - WebFetch/WebSearch native LS executor support is still not production-open.
- SSE drain/backpressure handling remains a separate follow-up because it touches the streaming hot path.
Validation
node --test test/cache.test.jsnode --test test/dashboard-syntax.test.jsnode --test test/native-bridge-docs.test.jsnode --test test/test-shard-script.test.js test/release-workflow.test.jsnpm.cmd run test:release
Assets 2
v2.0.137
v2.0.137 - dashboard pagination and protocol trace evidence
What changed
- Dashboard accounts now load a lightweight paged summary list instead of the full heavy account payload.
- Account row expansion and model block editing now lazy-load one full account detail via
GET /dashboard/api/accounts/:id. - The abnormal accounts panel now loads only flagged summary rows and uses server-side account stats.
- Added safe Read wrapper trace evidence for
type=14 / field=19: accepted field, path-like fields, prompt-like rejected fields, and ambiguity, without raw path or prompt text by default. - Added WebFetch trajectory branch evidence for pending permission, completed
web_document, auto-run-only, legacy-summary-only, and permission/precondition error states. - Replaced real-looking email/password examples in
docs/releases/RELEASE_NOTES_2.0.39.mdwith non-login placeholders. - Added
scripts/secret-scan.mjsandnpm run secret-scanfor tracked-file secret scanning. - Secret scan findings print only
path:line rule; matched secret values are never printed. - Added regression tests for secret-scan output redaction and release workflow ordering.
- Release workflow now runs a bounded release test gate first, makes Docker depend on tests, and makes GitHub Release depend on Docker.
- CI now uses the same bounded release gate;
npm testremains the local full-suite entry point. - Docker builds now receive
BUILD_VERSION,BUILD_COMMIT,BUILD_COMMIT_MESSAGE,BUILD_COMMIT_DATE, andBUILD_BRANCH.
Validation
npm.cmd run secret-scannpm.cmd run test:releasenode --test test/dashboard-api.test.jsnode --test test/proto-trace.test.jsnode --test test/secret-scan.test.js test/release-workflow.test.jsnode --test test/*.test.js
Assets 2
v2.0.136
v2.0.136 - audit hardening
What changed
- Oversized HTTP request bodies now return protocol-shaped
413 Request body too largeerrors instead of being misclassified asInvalid JSON. - WebFetch lab auto-approve now canonicalizes URL/origin allowlist entries and rejects non-http(s), malformed, or credential-bearing URLs.
read_url_contentno longer trusts the unconfirmed top-level field 5 summary by default; legacy fallback requiresWINDSURFAPI_NATIVE_TOOL_BRIDGE_READ_URL_LEGACY_SUMMARY=1.- Atomic JSON writes now use unique temporary filenames and retry short-lived Windows rename locks, including
accounts.json. - Added
docs/audits/AUDIT_2026年06月06日.mdwith the audit baseline, findings, fixed items, and remaining follow-ups.
Notes
- Read/WebSearch/WebFetch remain lab-only native bridge surfaces. This release tightens canary behavior; it does not production-open those tools.
- Release workflow metadata/test-gate hardening is documented in the audit, but was not included in this release because the current GitHub token lacks
workflowscope. - Dashboard account pagination for #168 is the next recommended implementation slice.
Validation
node --test test/*.test.js-> 1070/1070 passing.