@viudes/windsurf-api 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/install-ls.sh ADDED
@@ -0,0 +1,174 @@
1
+ #!/usr/bin/env bash
2
+ # Install / update the Windsurf language server binary.
3
+ #
4
+ # Usage:
5
+ # ./install-ls.sh # auto: WindsurfAPI release → maintained LS mirror → Exafunction fallback
6
+ # ./install-ls.sh /path/to/local.bin # install a local file
7
+ # ./install-ls.sh --file /path/to.bin # same as above
8
+ # ./install-ls.sh --url <direct-url> # install from a custom URL
9
+ #
10
+ # Auto-detects platform (Linux / macOS) and architecture (x64 / arm64).
11
+ # Override install path with LS_INSTALL_PATH env var.
12
+ set -euo pipefail
13
+
14
+ OUR_RELEASE='https://github.com/dwgx/WindsurfAPI/releases/latest/download'
15
+ EXAFUNCTION_API='https://api.github.com/repos/Exafunction/codeium/releases/latest'
16
+ # Maintained mirror for LS binaries extracted from official Windsurf/Devin Desktop builds.
17
+ WINDSURF_LS_RELEASE="${WINDSURFAPI_LS_RELEASE:-https://github.com/dwgx/windsurf-ls-release/releases/latest/download}"
18
+
19
+ log() { echo -e "\033[1;34m==>\033[0m $*"; }
20
+ err() { echo -e "\033[1;31m!!\033[0m $*" >&2; }
21
+
22
+ sha256_file() {
23
+ if command -v sha256sum >/dev/null 2>&1; then
24
+ sha256sum "$1" | awk '{print $1}'
25
+ elif command -v shasum >/dev/null 2>&1; then
26
+ shasum -a 256 "$1" | awk '{print $1}'
27
+ else
28
+ return 127
29
+ fi
30
+ }
31
+
32
+ verify_release_asset_checksum() {
33
+ local release_base="$1"
34
+ local asset="$2"
35
+ local file="$3"
36
+ local checksums_file="${TMP_CHECKSUMS:-${file}.SHA256SUMS}"
37
+ local checksums_url="${release_base}/SHA256SUMS"
38
+
39
+ log "Trying checksum file: $checksums_url"
40
+ if ! curl -fsL -o "$checksums_file" "$checksums_url"; then
41
+ rm -f "$checksums_file"
42
+ log "SHA256SUMS not available; skipping mirror checksum verification"
43
+ return 0
44
+ fi
45
+
46
+ local expected
47
+ expected="$(awk -v asset="$asset" '{ checksum_asset = $2; sub(/\015$/, "", checksum_asset); if (checksum_asset == asset && length($1) == 64 && $1 ~ /^[0-9a-fA-F]+$/) { print tolower($1); exit } }' "$checksums_file")"
48
+ rm -f "$checksums_file"
49
+ if [[ -z "$expected" ]]; then
50
+ err "SHA256SUMS from $release_base does not list $asset"
51
+ return 1
52
+ fi
53
+
54
+ local actual
55
+ if ! actual="$(sha256_file "$file")"; then
56
+ log "No sha256 tool available; skipping mirror checksum verification"
57
+ return 0
58
+ fi
59
+
60
+ if [[ "$actual" != "$expected" ]]; then
61
+ err "Checksum mismatch for $asset"
62
+ err "Expected: $expected"
63
+ err "Actual: $actual"
64
+ return 1
65
+ fi
66
+
67
+ log "Verified $asset against SHA256SUMS"
68
+ }
69
+
70
+ # ─── Platform detection ────────────────────────────────
71
+ os="$(uname -s)"
72
+ arch="$(uname -m)"
73
+
74
+ case "$os" in
75
+ Linux)
76
+ case "$arch" in
77
+ x86_64|amd64) ASSET='language_server_linux_x64' ;;
78
+ aarch64|arm64) ASSET='language_server_linux_arm' ;;
79
+ *) err "Unsupported Linux arch: $arch"; exit 1 ;;
80
+ esac
81
+ DEFAULT_PATH="/opt/windsurf/${ASSET}"
82
+ ;;
83
+ Darwin)
84
+ case "$arch" in
85
+ x86_64) ASSET='language_server_macos_x64' ;;
86
+ arm64) ASSET='language_server_macos_arm' ;;
87
+ *) err "Unsupported macOS arch: $arch"; exit 1 ;;
88
+ esac
89
+ DEFAULT_PATH="$HOME/.windsurf/${ASSET}"
90
+ ;;
91
+ *)
92
+ err "Unsupported OS: $os (only Linux and macOS are supported)"
93
+ exit 1
94
+ ;;
95
+ esac
96
+
97
+ TARGET="${LS_INSTALL_PATH:-$DEFAULT_PATH}"
98
+ log "Platform: $os $arch → asset=$ASSET"
99
+ log "Target: $TARGET"
100
+
101
+ mkdir -p "$(dirname "$TARGET")"
102
+
103
+ # Write to a sibling tmp file then atomic-rename onto the target. If the
104
+ # target is currently being executed (LS process has it mmap'd as the
105
+ # program text), Linux refuses an in-place open(O_WRONLY|O_TRUNC) with
106
+ # ETXTBSY ("file busy"). A rename(2), by contrast, just swaps the dirent
107
+ # pointer to a new inode — running processes keep their old inode and
108
+ # we get a fresh binary in place for the next exec.
109
+ TMP_TARGET="${TARGET}.new.$$"
110
+ TMP_CHECKSUMS="${TMP_TARGET}.SHA256SUMS"
111
+ trap 'rm -f "$TMP_TARGET" "$TMP_CHECKSUMS"' EXIT
112
+
113
+ if [[ $# -gt 0 && "$1" == "--file" && -n "${2:-}" ]]; then
114
+ log "Installing from local file: $2"
115
+ cp -f "$2" "$TMP_TARGET"
116
+ elif [[ $# -gt 0 && "$1" != "--url" && "$1" != "--file" && -f "$1" ]]; then
117
+ log "Installing from local file: $1"
118
+ cp -f "$1" "$TMP_TARGET"
119
+ elif [[ $# -ge 2 && "$1" == "--url" ]]; then
120
+ url="$2"
121
+ log "Downloading from: $url"
122
+ curl -fL --progress-bar -o "$TMP_TARGET" "$url"
123
+ else
124
+ # Try our own GitHub release first, then the maintained public LS mirror,
125
+ # then the older Exafunction/codeium release as a last resort.
126
+ our_url="${OUR_RELEASE}/${ASSET}"
127
+ log "Trying WindsurfAPI release: $our_url"
128
+ if curl -fL --progress-bar -o "$TMP_TARGET" "$our_url" 2>/dev/null; then
129
+ log "Downloaded from WindsurfAPI release"
130
+ else
131
+ log "Not found in WindsurfAPI release, trying maintained Windsurf LS mirror..."
132
+ ws_url="${WINDSURF_LS_RELEASE}/${ASSET}"
133
+ log "Trying maintained Windsurf LS mirror: $ws_url"
134
+ if curl -fL --progress-bar -o "$TMP_TARGET" "$ws_url"; then
135
+ log "Downloaded from maintained Windsurf LS mirror"
136
+ verify_release_asset_checksum "$WINDSURF_LS_RELEASE" "$ASSET" "$TMP_TARGET"
137
+ else
138
+ log "Not found in maintained Windsurf LS mirror, falling back to Exafunction..."
139
+ if command -v jq >/dev/null 2>&1; then
140
+ url="$(curl -fsSL "$EXAFUNCTION_API" | jq -r \
141
+ --arg asset "$ASSET" '.assets[] | select(.name == $asset) | .browser_download_url')"
142
+ else
143
+ url="$(curl -fsSL "$EXAFUNCTION_API" | \
144
+ grep -oE "https://[^\"]+/${ASSET}" | head -1)"
145
+ fi
146
+ if [[ -z "$url" ]]; then
147
+ err "Could not find asset '$ASSET' in any release."
148
+ err "Download manually from Windsurf desktop app:"
149
+ err " macOS: ~/Library/Application Support/Windsurf/.../bin/$ASSET"
150
+ err " Linux: ~/.windsurf/bin/$ASSET"
151
+ exit 1
152
+ fi
153
+ log "Downloading: $url"
154
+ curl -fL --progress-bar -o "$TMP_TARGET" "$url"
155
+ fi
156
+ fi
157
+ fi
158
+
159
+ chmod +x "$TMP_TARGET"
160
+ mv -f "$TMP_TARGET" "$TARGET"
161
+ trap - EXIT
162
+ size="$(du -h "$TARGET" | cut -f1)"
163
+ if full_sha="$(sha256_file "$TARGET")"; then
164
+ sha="$(printf '%s' "$full_sha" | cut -c1-16)"
165
+ else
166
+ sha="(no sha256 tool)"
167
+ fi
168
+ log "Installed: $TARGET ($size, sha256:$sha...)"
169
+
170
+ if [[ "$os" == "Darwin" ]]; then
171
+ log ""
172
+ log "macOS users: set this in your .env:"
173
+ log " LS_BINARY_PATH=$TARGET"
174
+ fi
package/package.json ADDED
@@ -0,0 +1,69 @@
1
+ {
2
+ "name": "@viudes/windsurf-api",
3
+ "version": "0.1.3",
4
+ "publishConfig": {
5
+ "access": "public"
6
+ },
7
+ "description": "Windsurf to OpenAI + Anthropic compatible API proxy. Turns Windsurf's 100+ AI models (Claude, GPT, Gemini, DeepSeek, Grok, Qwen, Kimi, GLM, SWE) into dual-protocol API endpoints. Zero npm deps.",
8
+ "type": "module",
9
+ "main": "dist/app/index.js",
10
+ "bin": {
11
+ "windsurf-api": "bin/windsurf-api.js"
12
+ },
13
+ "files": [
14
+ "dist/app/",
15
+ "dist/dashboard/",
16
+ "bin/",
17
+ "install-ls.sh",
18
+ "LICENSE",
19
+ "README.md",
20
+ ".env.example",
21
+ "config.example.json"
22
+ ],
23
+ "scripts": {
24
+ "build": "node scripts/build-js.mjs",
25
+ "prepublishOnly": "npm run build",
26
+ "start": "node src/app/index.js",
27
+ "start:bun": "bun run src/app/index.js",
28
+ "dev": "node --watch src/app/index.js",
29
+ "build:exe": "bun run scripts/build-exe.mjs",
30
+ "build:exe:all": "bun run scripts/build-exe.mjs --all",
31
+ "test": "node --import ./test/setup-env.mjs --test --test-force-exit test/*/*.test.js",
32
+ "test:shard": "node scripts/run-test-shard.mjs",
33
+ "test:release": "node --import ./test/setup-env.mjs --test --test-force-exit test/conversation-cache/cache.test.js test/account-pool/dashboard-api.test.js test/_meta/dashboard-syntax.test.js test/native-bridge/native-tool-routing.test.js test/language-server/proto-trace.test.js test/_meta/secret-scan.test.js test/_meta/test-shard-script.test.js test/_meta/release-workflow.test.js test/_meta/changelog-script.test.js test/core/version.test.js",
34
+ "smoke:native-bridge": "node scripts/native-bridge-smoke.mjs",
35
+ "smoke:special-agent": "node scripts/special-agent-smoke.mjs",
36
+ "smoke:lsp-matrix": "node scripts/lsp-capacity-matrix.mjs",
37
+ "probe:web-search": "node scripts/web-search-direct-probe.mjs",
38
+ "sync:contributors": "node scripts/sync-docs-contributors.mjs",
39
+ "secret-scan": "node scripts/secret-scan.mjs"
40
+ },
41
+ "engines": {
42
+ "node": ">=24.0.0",
43
+ "bun": ">=1.2.23"
44
+ },
45
+ "license": "MIT",
46
+ "author": "andersonviudes <andersonvieiraviudes@gmail.com> (https://github.com/andersonviudes)",
47
+ "homepage": "https://github.com/andersonviudes/windsurf-openai#readme",
48
+ "repository": {
49
+ "type": "git",
50
+ "url": "git+https://github.com/andersonviudes/windsurf-openai.git"
51
+ },
52
+ "bugs": {
53
+ "url": "https://github.com/andersonviudes/windsurf-openai/issues"
54
+ },
55
+ "keywords": [
56
+ "windsurf",
57
+ "devin",
58
+ "codeium",
59
+ "openai",
60
+ "anthropic",
61
+ "claude",
62
+ "gpt",
63
+ "gemini",
64
+ "api-proxy",
65
+ "llm-gateway",
66
+ "reverse-engineering",
67
+ "zero-dependency"
68
+ ]
69
+ }