Original Summary

我是team账号,大概在4天前10.14看不到opus5.5等一众A/模型了,今天让grok4.7看了看,做了个补丁,虽然会报错,但是至少又能用了。不知道有多少人受到影响,分享出来。 #!/usr/bin/env python3 """把 Cursor IDE 的模型目录身份从 glass/ide 改成 desktop。 desktop 和 cli 拿到的模型目录相同,包含 Opus / Sonnet。 glass 和 ide 的目录里没有 Claude。 只改两类位置: 1. header.set("x-cursor-client-type", <变量>??"ide") 改成 header.set("x-cursor-client-type","desktop") 2. clientIdentity:{clientType:"ide"} 改成 clientIdentity:{clientType:"desktop"} 不改 main.js 里登录用的 "x-cursor-client-type":"ide"。 用法: 先完全退出 Cursor,再执行。 python3 apply.py # 自动找安装目录,先预览 python3 apply.py --apply # 真正写入 python3 apply.py --apply /path/to/resources/app sudo python3 apply.py --apply # Linux 系统目录需要 root python3 apply.py --revert --apply """ from __future__ import annotations import argparse import re import sys from pathlib import Path HEADER_RE = re.compile( r'header\.set\("x-cursor-client-type",(?P<expr>[A-Za-z_$][\w$]\?\?"ide"|\"desktop\")\)' ) HEADER_NEW = 'header.set("x-cursor-client-type","desktop")' IDENTITY_OLD = 'clientIdentity:{clientType:"ide"}' IDENTITY_NEW = 'clientIdentity:{clientType:"desktop"}' RELATIVE_FILES = [ "out/vs/workbench/workbench.glass.main.js", "out/vs/workbench/workbench.desktop.main.js", "out/vs/workbench/api/node/extensionHostProcess.js", "out/vs/workbench/api/worker/extensionHostWorkerMain.js", "extensions/cursor-agent-host/dist/main.js", ] def candidate_apps() -> list[Path]: home = Path.home() found: list[Path] = [] roots = [ Path("/usr/share/cursor/resources/app"), Path("/usr/lib/cursor/resources/app"), Path("/opt/Cursor/resources/app"), Path("/opt/cursor/resources/app"), home / ".local/share/cursor/resources/app", Path("/Applications/Cursor.app/Contents/Resources/app"), home / "Applications/Cursor.app/Contents/Resources/app", Path.home() / "AppData/Local/Programs/cursor/resources/app", Path.home() / "AppData/Local/cursor/resources/app", ] local = Path.home() / "AppData/Local" if local.is_dir(): roots.append(local / "Programs/cursor/resources/app") for root in roots: if (root / "out/vs/workbench").is_dir(): found.append(root) return found def cache_dirs() -> list[Path]: home = Path.home() dirs = [ home / ".config/Cursor/CachedData", home / "Library/Application Support/Cursor/CachedData", home / "AppData/Roaming/Cursor/CachedData", ] return [d for d in dirs if d.is_dir()] def transform(text: str, revert: bool) -> tuple[str, list[str]]: notes: list[str] = [] def header_sub(match: re.Match[str]) -> str: expr = match.group("expr") if revert: if expr == '"desktop"': notes.append("header desktop -> <var>??\"ide\" 无法自动还原变量名,跳过;请用 .bak 文件") return match.group(0) notes.append("header 已是原样") return match.group(0) if expr == '"desktop"': notes.append("header 已经是 desktop") return match.group(0) notes.append(f"header {expr} -> \"desktop\"") return HEADER_NEW new_text, header_count = HEADER_RE.subn(header_sub, text) if header_count == 0 and '??"ide"' in text: notes.append('文件里还有 ??"ide",但没匹配到 header.set,需要手工看') if revert: count = new_text.count(IDENTITY_NEW) if count: new_text = new_text.replace(IDENTITY_NEW, IDENTITY_OLD) notes.append(f"clientIdentity desktop -> ide x{count}") elif IDENTITY_OLD in new_text: notes.append("clientIdentity 已是 ide") else: count = new_text.count(IDENTITY_OLD) if count: new_text = new_text.replace(IDENTITY_OLD, IDENTITY_NEW) notes.append(f"clientIdentity ide -> desktop x{count}") elif IDENTITY_NEW in new_text: notes.append("clientIdentity 已经是 desktop") return new_text, notes def backup(path: Path) -> Path: bak = path.with_name(path.name + ".bak-before-desktop-identity") if not bak.exists(): bak.write_bytes(path.read_bytes()) return bak def clear_cache() -> None: for cache in cache_dirs(): for child in cache.iterdir(): if child.is_dir(): for sub in child.rglob(""): if sub.is_file(): sub.unlink() for sub in sorted(child.rglob("*"), reverse=True): if sub.is_dir(): sub.rmdir() child.rmdir() print(f"cleared {child}") def main() -> int: parser = argparse.ArgumentParser() parser.add_argument("app", nargs="?", help="Cursor 的 resources/app 目录") parser.add_argument("--apply", action="store_true", help="写入文件。不加这个参数只预览") parser.add_argument("--revert", action="store_true", help="用备份还原;没有备份时只能还原 clientIdentity") parser.add_argument("--clear-cache", action="store_true", help="删掉 CachedData,避免沿用旧字节码") args = parser.parse_args() if args.app: apps = [Path(args.app)] else: apps = candidate_apps() if not apps: print("没找到 Cursor 安装目录。请传入 resources/app 的路径。", file=sys.stderr) return 1 for app in apps: print(f"app {app}") for rel in RELATIVE_FILES: path = app / rel if not path.is_file(): print(f" skip 缺少 {rel}") continue original = path.read_text(encoding="utf-8", errors="replace") if args.revert: bak = path.with_name(path.name + ".bak-before-desktop-identity") if bak.is_file(): print(f" revert {rel} <- {bak.name}") if args.apply: path.write_bytes(bak.read_bytes()) continue updated, notes = transform(original, revert=args.revert) print(f" {rel}") for note in notes: print(f" {note}") if updated == original: continue if not args.apply: print(" 预览,未写入") continue bak = backup(path) path.write_text(updated, encoding="utf-8") print(f" 已写入,备份 {bak.name}") if args.apply and args.clear_cache: clear_cache() elif args.apply: print("下次启动前可以再跑一次并加上 --clear-cache,或者手动删掉 Cursor 的 CachedData。") else: print("这是预览。确认后加上 --apply。Linux 系统目录要加 sudo。") return 0 if __name__ == "__main__": raise SystemExit(main()) 使用方法: 完全退出 Cursor,包括托盘里的进程。 把 apply.py 拷过去。 先预览,再写入。Linux 装在 /usr/share/cursor 时要加 sudo 。 python3 apply.py sudo python3 apply.py --apply --clear-cache 脚本会自己找这些目录: Linux: /usr/share/cursor/resources/app 、 /opt/Cursor/resources/app macOS: /Applications/Cursor.app/Contents/Resources/app Windows: %LOCALAPPDATA%\Programs\cursor\resources\app 找不到就自己把 resources/app 的路径传进去: python3 apply.py --apply --clear-cache "/path/to/resources/app" 重新打开 Cursor,模型列表里应有 Opus 5.5。 Cursor 以后更新会盖掉这几处,现象再出现时把脚本再跑一次。要还原: sudo python3 apply.py --revert --apply --clear-cache 1 个帖子 - 1 位参与者 阅读完整话题


  • 情报分类:技术学习与提效
  • 分类依据:内容涉及技术、AI、软件工具或工程实践
  • 信息来源:服务器 / LINUX DO - 最新话题
  • 发布时间:2026/10/18 17:44:09