mirror of
https://wget.la/https://github.com/leookun/cursor-byok
synced 2026-08-17 19:47:10 +08:00
v0.0.39
This commit is contained in:
@@ -3,6 +3,7 @@ package cursor
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
@@ -23,8 +24,14 @@ const (
|
||||
cursorStateDBRelativePath = "Cursor/User/globalStorage/state.vscdb"
|
||||
cursorStateDarwinRelativePath = "Library/Application Support/Cursor/User/globalStorage/state.vscdb"
|
||||
cursorStateLinuxRelativePath = ".config/Cursor/User/globalStorage/state.vscdb"
|
||||
cursorStateStatsigBootstrapKey = "workbench.experiments.statsigBootstrap"
|
||||
)
|
||||
|
||||
var cursorStateDisabledStatsigGates = []string{
|
||||
"decompose_always_local_ext_host",
|
||||
"cursor_extensions_isolation_v2",
|
||||
}
|
||||
|
||||
// InjectCursorUserInfo synchronizes the Cursor user-level auth cache used by the
|
||||
// Settings page. It does not modify the installed Cursor app bundle.
|
||||
func InjectCursorUserInfo(email, token string) error {
|
||||
@@ -42,11 +49,12 @@ func InjectCursorUserInfo(email, token string) error {
|
||||
}
|
||||
|
||||
logger.Infof(
|
||||
"injectCursorUserInfo synced path=%s email=%s membership=%s subscription=%s",
|
||||
"injectCursorUserInfo synced path=%s email=%s membership=%s subscription=%s disabled_statsig_gates=%s",
|
||||
stateDBPath,
|
||||
values["cursorAuth/cachedEmail"],
|
||||
values["cursorAuth/stripeMembershipType"],
|
||||
values["cursorAuth/stripeSubscriptionStatus"],
|
||||
strings.Join(cursorStateDisabledStatsigGates, ","),
|
||||
)
|
||||
return nil
|
||||
}
|
||||
@@ -111,6 +119,10 @@ func syncCursorAuthStateDB(path string, values map[string]string) error {
|
||||
}
|
||||
}
|
||||
|
||||
if err := disableCursorStatsigGates(ctx, tx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := tx.Commit(); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -118,6 +130,70 @@ func syncCursorAuthStateDB(path string, values map[string]string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func disableCursorStatsigGates(ctx context.Context, tx *sql.Tx) error {
|
||||
var raw []byte
|
||||
err := tx.QueryRowContext(ctx, "SELECT value FROM ItemTable WHERE key = ?", cursorStateStatsigBootstrapKey).Scan(&raw)
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
var payload map[string]any
|
||||
if err := json.Unmarshal(raw, &payload); err != nil {
|
||||
return fmt.Errorf("解析 Cursor Statsig bootstrap 失败: %w", err)
|
||||
}
|
||||
|
||||
featureGates, _ := payload["feature_gates"].(map[string]any)
|
||||
if featureGates == nil {
|
||||
featureGates = map[string]any{}
|
||||
payload["feature_gates"] = featureGates
|
||||
}
|
||||
|
||||
hashUsed, _ := payload["hash_used"].(string)
|
||||
for _, gate := range cursorStateDisabledStatsigGates {
|
||||
disableCursorStatsigGate(featureGates, gate)
|
||||
if strings.EqualFold(hashUsed, "djb2") {
|
||||
disableCursorStatsigGate(featureGates, cursorStateDJB2Hash(gate))
|
||||
}
|
||||
}
|
||||
|
||||
updated, err := json.Marshal(payload)
|
||||
if err != nil {
|
||||
return fmt.Errorf("编码 Cursor Statsig bootstrap 失败: %w", err)
|
||||
}
|
||||
if _, err := tx.ExecContext(ctx, "UPDATE ItemTable SET value = ? WHERE key = ?", updated, cursorStateStatsigBootstrapKey); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func disableCursorStatsigGate(featureGates map[string]any, key string) {
|
||||
gate, _ := featureGates[key].(map[string]any)
|
||||
if gate == nil {
|
||||
gate = map[string]any{
|
||||
"name": key,
|
||||
"rule_id": "local_disabled",
|
||||
"ruleID": "local_disabled",
|
||||
"group_name": "local_disabled",
|
||||
"groupName": "local_disabled",
|
||||
"id_type": "userID",
|
||||
"idType": "userID",
|
||||
}
|
||||
featureGates[key] = gate
|
||||
}
|
||||
gate["value"] = false
|
||||
}
|
||||
|
||||
func cursorStateDJB2Hash(value string) string {
|
||||
var hash uint32
|
||||
for _, b := range []byte(value) {
|
||||
hash = hash*31 + uint32(b)
|
||||
}
|
||||
return fmt.Sprintf("%d", hash)
|
||||
}
|
||||
|
||||
func resolveCursorStateDBPath() (string, error) {
|
||||
homeDir, err := os.UserHomeDir()
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user