Skip to content

chore(desktop): retire Cursor subscription - #2037

Merged
Astro-Han merged 1 commit into
apache:mainfrom
me2seeks:chore/1982-retire-cursor-subscription
Aug 3, 2026
Merged

chore(desktop): retire Cursor subscription#2037
Astro-Han merged 1 commit into
apache:mainfrom
me2seeks:chore/1982-retire-cursor-subscription

Conversation

@me2seeks

@me2seeks me2seeks commented Aug 3, 2026

Copy link
Copy Markdown
Contributor
English

Summary

  • remove the retired Cursor subscription service, IPC handlers, preload bridge, boot wiring, and provider fixtures
  • add deletion-only startup cleanup for the legacy token file and shared OAuth credential left by older builds
  • update current credential-boundary documentation and remove stale Cursor references

Safety boundary

The cleanup never reads, imports, parses, or refreshes either credential source. It independently attempts both deletions so a partial failure is logged and retried on the next launch.

Only cursor-subscription:oauth_token is removed from the shared store. A same-slug API key can belong to a user-created connection and remains untouched, as do credentials for every other provider. Re-running the cleanup after success is safe.

Validation

  • npm run build:test
  • focused Cursor retirement, shared credential-store, IPC surface, and Runtime OAuth persistence tests
  • npm --workspace @maka/desktop run test:checks
  • npm run lint
  • npm run format:check
  • git diff --check origin/main...HEAD

Part of #1982.

简体中文

概要

  • 删除已退役的 Cursor subscription service、IPC handlers、preload bridge、启动接线与 provider fixtures
  • 增加只执行删除的启动清理,处理旧版本遗留的 token 文件和共享 OAuth 凭据
  • 同步当前凭据安全边界文档,并移除过期的 Cursor 描述

安全边界

清理过程不会读取、导入、解析或刷新任何一处历史凭据。两个删除会被独立尝试,因此单侧失败会被记录,并在下次启动时自然重试。

共享存储中只删除 cursor-subscription:oauth_token。同 slug 的 API key 可能属于用户创建的连接,因此会被保留;其他 provider 的凭据也完全不受影响。清理成功后重复执行仍然安全。

验证

  • npm run build:test
  • Cursor 退役、共享凭据存储、IPC surface 与 Runtime OAuth 持久化的 focused tests
  • npm --workspace @maka/desktop run test:checks
  • npm run lint
  • npm run format:check
  • git diff --check origin/main...HEAD

属于 #1982 的一部分。

@Astro-Han Astro-Han left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Approve — non-blocking suggestions only

Three independent reviews (deletion completeness / retirement logic & tests / first-principles & refactoring) all passed. The removal is clean and complete (no residual imports or IPC channels; typecheck plus the 1535 desktop tests are green), and every safety-boundary claim in the description checks out against the code: deleteSecret is a no-op for missing keys (idempotent), and the slug/legacy file name match the retired service exactly. The current shape is already the optimal solution under the existing constraints — no refactor needed. The following are optional P3-level suggestions:

  1. Document two decisions in cursor-subscription-retirement.ts (zero-cost, leaves a trail for a future chore):
    • This is a bounded-lifetime sweeper: deleteSecret is read-modify-write, so every launch rewrites credentials.json, and a fresh install materializes an empty credentials file on first launch (also under the first-run e2e fixture). Once the legacy window closes, the whole 44-line module can be removed.
    • Unconditional deletion is deliberate (avoids the "read-then-delete" semantics and TOCTOU of existence checks; no one-off upgrade marker needed).
  2. Two cheap test additions: the both-fail branch (both sides reject, AggregateError aggregates both reasons) is unasserted, and test 1's rerun doesn't re-assert oauth_token is still null.
  3. PR body wording nit: "never reads/parses" isn't literally true — deleteSecret necessarily reads and parses the whole store file. Suggest "never consumes, imports, or refreshes" (no committed docs are affected).
  4. Drive-by fix (pre-existing from #1851, not introduced here): SECURITY.md:167/:218 and preload.ts:618 reference the deleted claude-subscription-ipc-boundary.test.ts.
简体中文

三份独立 review(删除完整性 / 清理逻辑与测试 / 第一性原理与重构)结论一致:PASS。删除彻底无残留(无 import/IPC 通道残留,typecheck 与 1535 个 desktop 测试全绿),四条安全边界声明逐条核验为真(deleteSecret 对缺失 key 为 no-op,幂等成立;slug 与遗留文件名与退役 service 完全一致)。当前实现已是既有约束下的最优解,无需重构。以下均为非阻塞建议:

  1. 建议在 cursor-subscription-retirement.ts 注释中记录两个决策:该逻辑是有界存活期 sweeperdeleteSecret 为 read-modify-write,每次启动都会改写 credentials.json,全新安装会在首次启动物化出空凭据文件,e2e first-run fixture 下同样触发),遗留窗口关闭后可整体移除这 44 行;无条件删除是刻意选择(避免存在性检查的读取语义与 TOCTOU,也无需一次性升级标记)。
  2. 可补 2 个测试点:双失败分支(两侧同时 reject 时 AggregateError 聚合两个 reason)未断言;test 1 的 rerun 未重断言 oauth_token 仍为 null。
  3. PR body 措辞微调(不影响已合入文档):"never reads/parses" 字面不成立——deleteSecret 内部必然读+解析整个文件;建议改为 "never consumes, imports, or refreshes"。
  4. 顺带修正(#1851 遗留,非本 PR 引入):SECURITY.md:167/:218 与 preload.ts:618 引用了已删除的 claude-subscription-ipc-boundary.test.ts

@Astro-Han
Astro-Han merged commit 61a0ca1 into apache:main Aug 3, 2026
11 checks passed
Astro-Han pushed a commit that referenced this pull request Aug 4, 2026
* refactor(desktop): remove consumer-less IPC bridge surface

Deletes three renderer-dead bridge surfaces, all verified zero-consumer
across renderer/overlay/e2e:

- appWindow.subscribeOpenSettings + the window:openSettings wiring in
  app-shell-effects: the only sender (app-menu item) was removed in #390;
  Cmd/Ctrl+, keeps working through the renderer keydown handler.
- dailyReview.list/get/delete aliases duplicating the live *Archive
  variants, plus the daily-review:delete channel end-to-end - retention
  cleanup calls store.deleteArchive directly and no renderer spelling of
  delete has a consumer.
- The speculative maka.usage preload namespace, per the decision recorded
  on #1982: the main-side usage:* authority handlers (#1596) stay for the
  #2010 M4 client adapter, so the IPC surface contract test now carries a
  self-checking MAIN_ONLY_CHANNELS allowlist documenting that state.

The third #1978 item (ungated cursor-subscription:logout) became moot when
#2037 retired the whole Cursor subscription surface.

Closes #1978. Ref #1982.

Verification: desktop typecheck clean; main suite 1585/1585 including the
IPC surface contract and app-shell effect stability contracts.

* test(e2e): assert both Skill chips land before leaving the session

The leave-and-return journey only asserted the first chip before
navigating away; leaving while the second token is still committing
races the draft snapshot and loses the chip on return, which is exactly
how this spec failed on CI. Mirror the projectChip assertion for
workspaceChip so the draft is known-complete before the navigation.
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