feat: share local Cursor MCP authentication (#3923)
This commit is contained in:
@@ -0,0 +1,124 @@
|
||||
---
|
||||
created: 2026-09-24
|
||||
status: complete
|
||||
requirements:
|
||||
- REQ-AGENTS-CURSOR-AUTH-001
|
||||
- REQ-AGENTS-CURSOR-AUTH-002
|
||||
- REQ-AGENTS-CURSOR-AUTH-003
|
||||
system_design:
|
||||
- ../../specs/agents/system-design/cursor-mcp-oauth-bridge.md
|
||||
legacy_specs: []
|
||||
---
|
||||
|
||||
# Implementation plan: Cursor MCP OAuth bridge
|
||||
|
||||
## Overview
|
||||
|
||||
Implement the filesystem helper first, then the profile preference and settings control.
|
||||
Connect both to launch preparation last.
|
||||
All work orders run sequentially in the primary session.
|
||||
This package does not authorize implementation or subagents.
|
||||
|
||||
Sources: [requirements](../../specs/agents/requirements/cursor-mcp-oauth-bridge.md) and
|
||||
[system design](../../specs/agents/system-design/cursor-mcp-oauth-bridge.md).
|
||||
|
||||
## Scope
|
||||
|
||||
In scope: local Cursor ACP and CursorStrategy terminal launches, aggregation, atomic links, profile persistence, localized checkbox, and desktop/phone verification.
|
||||
Out of scope: OAuth login, token refresh, remote credential transport, per-server account selection, and background synchronization.
|
||||
|
||||
## Technical approach
|
||||
|
||||
- Add `mcpconfig/cursor_auth_bridge.go` with pure slug derivation and composed filesystem operations.
|
||||
- Add `cursor_mcp_auth_enabled` to the existing profile store and shared API contract. Omission defaults to true on creation.
|
||||
- Carry the value through `AgentProfileInfo`, frontend normalization, draft state, and settings discovery.
|
||||
- Add a checkbox in `ProfileFormFields` or a focused child component. Use the current effective strategy to determine visibility.
|
||||
- Add lifecycle preparation before ACP and terminal process launch. Use resolved execution-profile state, not the stable Office identity.
|
||||
- Update `docs/public/agents-and-profiles.md` with local eligibility, default, conflicts, disable timing, and preservation of regular auth files.
|
||||
|
||||
## ASCII UI preview
|
||||
|
||||
### UI-01: Cursor profile settings
|
||||
|
||||
Entry: Settings > Agents > Cursor profile. Shared desktop/phone composition, enabled state.
|
||||
|
||||
```text
|
||||
Profile settings
|
||||
...existing fields...
|
||||
[x] Share local Cursor MCP credentials
|
||||
Reuse MCP sign-ins from other local
|
||||
Cursor projects. Applies on the next launch.
|
||||
|
||||
Existing settings save controls:
|
||||
[Discard] [Save changes]
|
||||
```
|
||||
|
||||
Unchecked draft: `[ ]`, with the same save controls.
|
||||
After save, unchecked persists across reload.
|
||||
Loading and failed-save behavior use the existing settings surface.
|
||||
The description of disable timing stays visible without hover.
|
||||
|
||||
Required structure: labeled checkbox, visible helper text, existing save/discard flow.
|
||||
Phone: wrap text, make the label target at least 44px high, and retain the existing page scroll owner.
|
||||
Desktop: retain current form density.
|
||||
Copy and spacing are illustrative. Localization supplies final copy.
|
||||
Maps to AC-AGENTS-CURSOR-AUTH-002.2, .5, and .6.
|
||||
|
||||
## Tests
|
||||
|
||||
Proposed test names are implementation targets, not existing evidence.
|
||||
|
||||
| Criteria | Evidence |
|
||||
| --- | --- |
|
||||
| 001.1, .2, .6; 003.1, .5, .6 | `cursor_auth_bridge_test.go`: `TestAggregateCursorMCPAuth` table cases |
|
||||
| 001.4; 003.2, .3, .4 | Same file: `TestDeriveCursorProjectSlug`, `TestLinkCursorMCPAuth`, `TestCursorMCPAuthConcurrentPreparation` |
|
||||
| 002.3, .4 | Same file: `TestDisableCursorMCPAuth`; lifecycle cleanup failure test |
|
||||
| 002.1, .7 | Store migration/round-trip, controller create/patch/duplicate, DTO and settings catalog tests |
|
||||
| 002.2, .5, .6 | Frontend form/state tests and both Playwright files below |
|
||||
| 001.3, .5; 003.7 | `manager_project_mcp_test.go` and `manager_passthrough_mcpfiles_test.go`: eligibility, empty servers, errors, both launch modes |
|
||||
| 001.1, .4 | `TestCursorMCPAuthWorktree`: temporary git worktree and synthetic home |
|
||||
|
||||
Each work order requires RED-GREEN-REFACTOR for changed logic.
|
||||
Production helpers use Go only. Test fixture setup can invoke git to create a real temporary worktree.
|
||||
|
||||
## E2E tests
|
||||
|
||||
Add `apps/web/e2e/tests/settings/cursor-mcp-auth.spec.ts` for the `chromium` project.
|
||||
Add `apps/web/e2e/tests/settings/mobile-cursor-mcp-auth.spec.ts` for `mobile-chrome`.
|
||||
Use shared test helpers for disposable Cursor profile setup.
|
||||
|
||||
Prove default enabled, disable/save/reload, re-enable, discard, and hiding for non-Cursor profiles.
|
||||
Also cover the custom terminal profile with strategy `cursor`.
|
||||
Assert an accessible checkbox name and keyboard Space on desktop.
|
||||
On phone, tap the label, measure its target, and assert no horizontal document overflow.
|
||||
These flows cover AC-AGENTS-CURSOR-AUTH-002.1, .2, .5, and .6.
|
||||
Use causal network/event waits and backend fixtures. Do not authenticate real MCP providers.
|
||||
|
||||
## Work orders
|
||||
|
||||
- [x] [Task 01: Safe Cursor auth helpers](task-01-auth-helpers.md)
|
||||
- [x] [Task 02: Profile preference and settings checkbox](task-02-profile-preference.md)
|
||||
- [x] [Task 03: Launch integration and delivery verification](task-03-launch-integration.md)
|
||||
|
||||
## Verification results
|
||||
|
||||
Design validation on 2026-09-24: catalog validation passed, all specification files passed lint, and 36 specification-linter tests passed.
|
||||
Relative document links and whitespace checks passed for all six new documents.
|
||||
|
||||
Implementation completed on 2026-09-25. `make -C apps/backend build`, focused MCP bridge and lifecycle tests, lifecycle race tests, focused frontend tests (104 tests), TypeScript, i18n, desktop E2E (2 tests), mobile E2E (1 test), documentation validation, specification validation, and `git diff --check` passed.
|
||||
|
||||
The requested `make -C apps/backend test` target ran but did not pass. The process-probe package's two real-tree timing tests also fail in isolation. Common-config and launcher package tests pass in isolation after clearing the host-injected `KANDEV_INTERNAL_CONFIG_FILE` and `KANDEV_INTERNAL_CONFIG_HOME_FILE` values; those values made the broad run load `/root/.kandev/config.yaml` during tests that expect temporary configuration. The broad suite was not rerun during review follow-up.
|
||||
|
||||
Review follow-up passed the full focused MCP bridge and lifecycle suites, their race variants, the backend build, public-doc tests/validation, and whitespace/format checks. Terminal profile resolution now supplies the agent and preference from one successful lookup, and eligible local Cursor launches fail closed on missing profile data. Tests canonicalize workspace paths and cover a workspace under a symlinked parent. Public docs now distinguish symlink replacement while sharing is enabled from preservation of unrelated symlinks during opt-out cleanup.
|
||||
|
||||
## Risks
|
||||
|
||||
- Source modification time is deterministic but does not prove token validity.
|
||||
- Different profiles can share one canonical workspace and therefore one auth link.
|
||||
- Cursor can update the master or replace its symlink. Regular files remain protected.
|
||||
- The bridge cannot coordinate token refresh with external processes.
|
||||
- A non-default process HOME or remote executor cannot safely use the backend's host credentials.
|
||||
- Filesystem rename behavior and symlink permission differ across operating systems.
|
||||
- The supplied Cursor filesystem contract requires real-version compatibility evidence before claiming live OAuth success.
|
||||
- Credential entries are matched by exact server name without checking project MCP URLs or OAuth issuers. Users must trust project configurations launched with sharing enabled and revoke credentials through the provider if an unintended endpoint may have received them.
|
||||
- No automatic backend restart or global runtime release flag is part of this request.
|
||||
@@ -0,0 +1,82 @@
|
||||
---
|
||||
id: "01-auth-helpers"
|
||||
title: "Safe Cursor auth helpers"
|
||||
status: done
|
||||
wave: 1
|
||||
depends_on: []
|
||||
plan: "plan.md"
|
||||
requirements:
|
||||
- REQ-AGENTS-CURSOR-AUTH-001
|
||||
- REQ-AGENTS-CURSOR-AUTH-002
|
||||
- REQ-AGENTS-CURSOR-AUTH-003
|
||||
acceptance_criteria:
|
||||
- AC-AGENTS-CURSOR-AUTH-001.1
|
||||
- AC-AGENTS-CURSOR-AUTH-001.2
|
||||
- AC-AGENTS-CURSOR-AUTH-001.4
|
||||
- AC-AGENTS-CURSOR-AUTH-001.6
|
||||
- AC-AGENTS-CURSOR-AUTH-002.3
|
||||
- AC-AGENTS-CURSOR-AUTH-003.1
|
||||
- AC-AGENTS-CURSOR-AUTH-003.2
|
||||
- AC-AGENTS-CURSOR-AUTH-003.3
|
||||
- AC-AGENTS-CURSOR-AUTH-003.4
|
||||
- AC-AGENTS-CURSOR-AUTH-003.5
|
||||
- AC-AGENTS-CURSOR-AUTH-003.6
|
||||
system_design:
|
||||
- ../../specs/agents/system-design/cursor-mcp-oauth-bridge.md
|
||||
---
|
||||
|
||||
# Safe Cursor auth helpers
|
||||
|
||||
## Summary
|
||||
|
||||
Create safe, independently tested filesystem helpers with synthetic credentials.
|
||||
|
||||
## Scope and owned files
|
||||
|
||||
- New `apps/backend/internal/agent/mcpconfig/cursor_auth_bridge.go`.
|
||||
- New `apps/backend/internal/agent/mcpconfig/cursor_auth_bridge_test.go`.
|
||||
- A focused private helper file if Go size limits require it.
|
||||
- Requested helper signatures, private aggregation result, and bridge-link cleanup. Aggregation accepts excluded workspace roots so task credentials remain excluded with custom `tasks_base_path` values.
|
||||
- Serialization, source selection, canonical workspace resolution, atomic writes, and destination preservation.
|
||||
|
||||
Exclude lifecycle hooks, profile persistence, UI, OAuth calls, and real home-directory reads.
|
||||
|
||||
## Implementation acceptance
|
||||
|
||||
1. All filesystem cases in the design pass, including duplicate timestamps, symlinked source directories, and task worktrees beneath a custom configured root.
|
||||
2. No-source and malformed-source cases cannot create a new link to a stale master. Regular destinations remain unchanged.
|
||||
3. Parallel bridge calls produce complete snapshots and links. Disabled cleanup removes only a matching bridge link.
|
||||
4. Slug derivation covers Windows separators and drive prefixes. Tests that create symlinks skip only when symlink creation is unavailable.
|
||||
|
||||
## TDD and verification
|
||||
|
||||
First write table cases for selection, slug derivation, protected files, and removal.
|
||||
Then implement the smallest helpers that satisfy them.
|
||||
Add error cases for malformed JSON, unreadable entries, invalid master type, and failed publication.
|
||||
Use injected failures where root execution makes permission tests unreliable.
|
||||
Check exact mode bits on supported filesystems.
|
||||
Check temporary-file cleanup after failures.
|
||||
|
||||
From `apps/backend`:
|
||||
|
||||
```bash
|
||||
go test -v ./internal/agent/mcpconfig/...
|
||||
go test -race ./internal/agent/mcpconfig/...
|
||||
```
|
||||
|
||||
## Dependencies and risks
|
||||
|
||||
No implementation dependency. Use only standard-library filesystem and JSON operations.
|
||||
The mutex coordinates Kandev callers, not Cursor or hostile external path replacement.
|
||||
Do not promise token validity or external-process refresh synchronization.
|
||||
|
||||
## Results
|
||||
|
||||
Implemented the synthetic Cursor auth aggregation, atomic master publication, project symlink, protected destination handling, canonical workspace resolution, and disabled cleanup helpers.
|
||||
|
||||
Verification passed from `apps/backend`:
|
||||
|
||||
- `go test ./internal/agent/mcpconfig/...`
|
||||
- `go test -race ./internal/agent/mcpconfig/...`
|
||||
|
||||
Review follow-up adds deterministic Windows drive and UNC slug cases, custom task-root exclusion (including stale Cursor entries after the root is removed), same-name credential sharing coverage for the documented cross-origin trust boundary, and a Windows CI slug test. Symlink-dependent tests probe host support and skip when unavailable.
|
||||
@@ -0,0 +1,132 @@
|
||||
---
|
||||
id: "02-profile-preference"
|
||||
title: "Profile preference and settings checkbox"
|
||||
status: done
|
||||
wave: 2
|
||||
depends_on:
|
||||
- "01-auth-helpers"
|
||||
plan: "plan.md"
|
||||
requirements:
|
||||
- REQ-AGENTS-CURSOR-AUTH-002
|
||||
acceptance_criteria:
|
||||
- AC-AGENTS-CURSOR-AUTH-002.1
|
||||
- AC-AGENTS-CURSOR-AUTH-002.2
|
||||
- AC-AGENTS-CURSOR-AUTH-002.5
|
||||
- AC-AGENTS-CURSOR-AUTH-002.6
|
||||
- AC-AGENTS-CURSOR-AUTH-002.7
|
||||
system_design:
|
||||
- ../../specs/agents/system-design/cursor-mcp-oauth-bridge.md
|
||||
---
|
||||
|
||||
# Profile preference and settings checkbox
|
||||
|
||||
## Summary
|
||||
|
||||
Persist the default-enabled preference and expose one localized checkbox through the existing settings flow.
|
||||
|
||||
## Scope and owned files
|
||||
|
||||
- `apps/backend/internal/agent/settings/models/models.go`.
|
||||
- `settings/store/sqlite.go` and migration/duplicate/round-trip tests.
|
||||
- `settings/dto/profile_contract.go`, `dto.go`, controller CRUD and conversion files, and their tests.
|
||||
- `apps/backend/internal/settingscatalog/defaults.go` and catalog contract tests.
|
||||
- Generated settings discovery contracts in `apps/web/lib/settings-discovery/`.
|
||||
- `apps/backend/internal/agent/runtime/lifecycle/types.go` and `profile_resolver.go` for the resolved preference.
|
||||
- Web `lib/types/agent-profile.ts`, `lib/types/backend.ts`, `lib/api/domains/agent-profile-normalize.ts`, and profile mutation types.
|
||||
- Web `components/settings/profile-form-fields.tsx`, `agent-profile-page.tsx`, `agent-profile-page-state.ts`, `agent-profile-dirty.ts`, and `agent-profile-reconciliation.ts`.
|
||||
- Web `app/settings/agents/[agentId]/agent-save-helpers.ts` and creation flow defaults.
|
||||
- Relevant tests and `src/locales/{en,pt-pt,zh-cn,zh-tw,zh-hk,ja}/agents.json`.
|
||||
- New desktop/phone E2E files from the plan and their shared setup helper.
|
||||
|
||||
Follow existing field mappings into boot payloads, actions, export/import contracts, and event normalization where they explicitly enumerate profile fields.
|
||||
Preserve false through every supported profile round trip.
|
||||
Exclude launch filesystem mutations and changes to generic permission behavior.
|
||||
|
||||
## Implementation acceptance
|
||||
|
||||
1. Migration and all creation paths default to true. Explicit false survives update, duplication, reload, and unrelated edits.
|
||||
2. Applicable profiles expose UI-01 with normal save/discard and conflict behavior. Other profiles do not expose the checkbox.
|
||||
3. Desktop and phone tests prove persistence, accessibility, touch size, and localization completeness.
|
||||
|
||||
## ASCII UI preview
|
||||
|
||||
### UI-01: Cursor profile settings
|
||||
|
||||
Entry: Settings > Agents > Cursor profile. Shared desktop/phone composition, enabled state.
|
||||
|
||||
```text
|
||||
Profile settings
|
||||
...existing fields...
|
||||
[x] Share local Cursor MCP credentials
|
||||
Reuse MCP sign-ins from other local
|
||||
Cursor projects. Applies on the next launch.
|
||||
|
||||
Existing settings save controls:
|
||||
[Discard] [Save changes]
|
||||
```
|
||||
|
||||
Unchecked draft: `[ ]`, with the same save controls.
|
||||
After save, unchecked persists across reload.
|
||||
Loading and failed-save behavior use the existing settings surface.
|
||||
The description of disable timing stays visible without hover.
|
||||
|
||||
Required structure: labeled checkbox, visible helper text, existing save/discard flow.
|
||||
Phone: wrap text, make the label target at least 44px high, and retain the existing page scroll owner.
|
||||
Desktop: retain current form density.
|
||||
Copy and spacing are illustrative. Localization supplies final copy.
|
||||
Maps to AC-AGENTS-CURSOR-AUTH-002.2, .5, and .6.
|
||||
|
||||
Full context: [plan preview](plan.md#ascii-ui-preview).
|
||||
|
||||
## TDD and verification
|
||||
|
||||
Write failing backend tests for omitted create, explicit false, omitted patch, migration, and duplicate.
|
||||
Write frontend tests for normalization, dirty detection, patch conversion, and external update reconciliation.
|
||||
Extend existing tests where the behavior already has a suite.
|
||||
|
||||
From `apps/backend`:
|
||||
|
||||
```bash
|
||||
go test ./internal/agent/settings/... ./internal/settingscatalog/...
|
||||
go test ./internal/agent/runtime/lifecycle/... -run TestProfileResolver
|
||||
```
|
||||
|
||||
From `apps/web`:
|
||||
|
||||
```bash
|
||||
pnpm exec vitest run components/settings/profile-form-fields.test.tsx components/settings/agent-profile-page-state.test.ts components/settings/agent-profile-reconciliation.test.ts lib/api/domains/agent-profile-normalize.test.ts
|
||||
pnpm run typecheck
|
||||
pnpm run i18n:zh-hant
|
||||
pnpm run i18n:check
|
||||
pnpm e2e:run --host --project chromium -- tests/settings/cursor-mcp-auth.spec.ts
|
||||
pnpm e2e:run --host --project mobile-chrome -- tests/settings/mobile-cursor-mcp-auth.spec.ts
|
||||
```
|
||||
|
||||
The managed E2E runner rebuilds production assets.
|
||||
Use the standard fixture mock agents or an existing custom terminal fixture with Cursor strategy.
|
||||
Keep the fixture independent of a real Cursor install.
|
||||
Record screenshots or a rendered inspection for the phone checkbox.
|
||||
|
||||
## Dependencies and risks
|
||||
|
||||
Depends on Task 01 for agreed helper policy.
|
||||
Omitted booleans and explicit false must remain distinct in create and patch requests.
|
||||
Reconciliation and duplicated profiles can silently lose a field if only the main editor changes.
|
||||
|
||||
## Results
|
||||
|
||||
Implemented the profile preference through SQLite, DTO/controller contracts, runtime profile resolution, frontend drafts, save paths, localization, and the settings checkbox. The checkbox appears for Cursor ACP and custom Cursor-strategy agents, defaults on, and uses the normal reset/save and external-conflict flow.
|
||||
|
||||
Validation passed:
|
||||
|
||||
- `go test ./internal/agent/settings/... ./internal/settingscatalog/...`
|
||||
- `go test ./internal/agent/runtime/lifecycle/... -run TestProfileResolver` (the pattern matches no tests; full lifecycle tests remain in Task 03)
|
||||
- Focused Vitest suites for form rendering, reconciliation, normalization, page save, and agent save helpers.
|
||||
- `pnpm run typecheck`
|
||||
- `pnpm run i18n:check`
|
||||
- Chromium settings E2E: 2 passed, including persistence and non-Cursor visibility.
|
||||
- Mobile Chrome settings E2E: 1 passed, including touch-size and overflow checks.
|
||||
|
||||
`pnpm run i18n:zh-hant` is blocked by the existing simplified-string warning at `workflows:openAgentSettings`. The supported namespace-scoped generator wrote the `agents` Traditional Chinese catalogs from Simplified Chinese without reformatting other translated messages.
|
||||
|
||||
Review follow-up makes both profile editor and agent-level profile saves omit an unchanged Cursor MCP auth preference, so stale drafts do not overwrite a newer value. Regression tests cover both save paths. The default-field test now also fails if the catalog field is absent. Regenerated the settings contract snapshots after CI detected that they did not yet include the new preference; `go run ./cmd/settings-catalog --check` passes.
|
||||
@@ -0,0 +1,124 @@
|
||||
---
|
||||
id: "03-launch-integration"
|
||||
title: "Launch integration and delivery verification"
|
||||
status: complete
|
||||
wave: 3
|
||||
depends_on:
|
||||
- "02-profile-preference"
|
||||
plan: "plan.md"
|
||||
requirements:
|
||||
- REQ-AGENTS-CURSOR-AUTH-001
|
||||
- REQ-AGENTS-CURSOR-AUTH-002
|
||||
- REQ-AGENTS-CURSOR-AUTH-003
|
||||
acceptance_criteria:
|
||||
- AC-AGENTS-CURSOR-AUTH-001.1
|
||||
- AC-AGENTS-CURSOR-AUTH-001.3
|
||||
- AC-AGENTS-CURSOR-AUTH-001.4
|
||||
- AC-AGENTS-CURSOR-AUTH-001.5
|
||||
- AC-AGENTS-CURSOR-AUTH-002.3
|
||||
- AC-AGENTS-CURSOR-AUTH-002.4
|
||||
- AC-AGENTS-CURSOR-AUTH-003.7
|
||||
system_design:
|
||||
- ../../specs/agents/system-design/cursor-mcp-oauth-bridge.md
|
||||
---
|
||||
|
||||
# Launch integration and delivery verification
|
||||
|
||||
## Summary
|
||||
|
||||
Apply the preference before eligible local Cursor launches and verify the complete feature.
|
||||
|
||||
## Scope and owned files
|
||||
|
||||
- `apps/backend/internal/agent/runtime/lifecycle/manager_project_mcp.go` and its tests.
|
||||
- A focused lifecycle bridge helper, plus `manager_passthrough.go` and `manager_passthrough_mcpfiles_test.go`.
|
||||
- `manager_launch.go` for resolved-profile forwarding at launch and workspace promotion.
|
||||
- Existing execution-profile, environment, and runtime classification helpers as required for eligibility.
|
||||
- `apps/backend/internal/agent/mcpconfig/cursor_auth_bridge_test.go` for the temporary-worktree integration case.
|
||||
- `docs/public/agents-and-profiles.md`, this package's results/statuses, and paired specifications after verified implementation.
|
||||
|
||||
Exclude remote credential transport, background refresh, process termination, and automatic OAuth login.
|
||||
|
||||
## Implementation acceptance
|
||||
|
||||
1. Both Cursor launch paths prepare auth before process start, including empty profile MCP configuration and workspace promotion.
|
||||
2. Locality and resolved-profile tests prove opt-out, non-Cursor no-op, remote no-op, and failure policy.
|
||||
3. A temporary git worktree receives the expected link. All required backend and desktop/phone checks pass.
|
||||
|
||||
## TDD and verification
|
||||
|
||||
Write lifecycle RED tests before launch changes.
|
||||
Inject a temporary home and use synthetic source credentials.
|
||||
Cover disabled cleanup failure, missing Cursor home, malformed sources, canonical path aliases, and preserved regular destinations.
|
||||
Use the actual resolved execution profile in an Office/dynamic-profile case.
|
||||
Cover resumed process launch and prove an existing running process is not reconfigured.
|
||||
Add `TestCursorMCPAuthWorktree` with a temporary repository and real git worktree.
|
||||
Assert `Readlink`, master JSON, and absence of writes to the original source files.
|
||||
|
||||
From `apps/backend`:
|
||||
|
||||
```bash
|
||||
go test -v ./internal/agent/mcpconfig/... ./internal/agent/runtime/lifecycle/...
|
||||
go test -race ./internal/agent/mcpconfig/... ./internal/agent/runtime/lifecycle/...
|
||||
go test -v ./internal/agent/mcpconfig/... -run TestCursorMCPAuthWorktree
|
||||
```
|
||||
|
||||
From the repository root:
|
||||
|
||||
```bash
|
||||
make -C apps/backend test
|
||||
node --test scripts/validate-public-docs.test.mjs
|
||||
node scripts/validate-public-docs.mjs
|
||||
python3 scripts/list-docs.py validate
|
||||
python3 scripts/lint-spec-files.py --all
|
||||
git diff --check
|
||||
```
|
||||
|
||||
From `apps/web`, after backend integration:
|
||||
|
||||
```bash
|
||||
pnpm e2e:run --host --project chromium -- tests/settings/cursor-mcp-auth.spec.ts
|
||||
pnpm e2e:run --host --project mobile-chrome -- tests/settings/mobile-cursor-mcp-auth.spec.ts
|
||||
```
|
||||
|
||||
Run commands sequentially with the repository worker limits.
|
||||
Record results in this work order and the plan.
|
||||
Public docs use a short reference section in the existing agents guide.
|
||||
Explain local eligibility, newest-file precedence, next-launch opt-out, and token-refresh limitations.
|
||||
|
||||
## Dependencies and risks
|
||||
|
||||
Depends on Task 02 and its profile resolver field.
|
||||
Promotion updates execution identity after part of launch preparation. Pass the incoming resolved profile explicitly.
|
||||
Do not append persistent bridge files to session-owned MCP cleanup lists.
|
||||
The fixture proves filesystem behavior, not successful OAuth against live Atlassian or Figma.
|
||||
|
||||
## Results
|
||||
|
||||
Completed on 2026-09-25.
|
||||
|
||||
- Passed `make -C apps/backend build`.
|
||||
- Passed `go test -v ./internal/agent/mcpconfig/... ./internal/agent/runtime/lifecycle/...` and `go test -race ./internal/agent/mcpconfig/... ./internal/agent/runtime/lifecycle/...`.
|
||||
- Passed `pnpm run typecheck`, `pnpm run i18n:check`, and the five focused Vitest files: 104 tests passed.
|
||||
- Passed desktop Playwright: 2 tests; mobile Chrome Playwright: 1 test.
|
||||
- Passed public-doc validation (62 validator tests and 47 published pages), specification validation/lint (305 decisions, 1144 specifications), and `git diff --check`.
|
||||
- `make -C apps/backend test` ran but failed in checks outside this change. `internal/agentctl/server/process/probe` failed `TestProbeRealTree_AllDescendantsPreTurn_Settled` and `TestProbeRealTree_NewDescendantAfterTurnStart_Live` both in the full run and in isolation. `internal/common/config` and `internal/launcher` failed during the broad run because the host environment injected `KANDEV_INTERNAL_CONFIG_FILE=/root/.kandev/config.yaml`; both packages pass when run in isolation with `KANDEV_INTERNAL_CONFIG_FILE` and `KANDEV_INTERNAL_CONFIG_HOME_FILE` unset.
|
||||
- Review follow-up: `resolvePassthroughAgent` now obtains agent and profile together and propagates resolver failures; eligible local Cursor preparation rejects unresolved profile data. A resume regression verifies opt-out cleanup happens before a later resolver error can prevent process start. Expected test paths resolve the workspace independently, with deterministic symlink-parent coverage. Public documentation now limits unrelated-symlink preservation to disabled cleanup.
|
||||
- Re-ran `go test -v ./internal/agent/mcpconfig/... ./internal/agent/runtime/lifecycle/...`, the matching `-race` command, `make -C apps/backend build`, public-doc tests/validation, `gofmt`, and `git diff --check`; all passed. The broad backend suite was not rerun during review follow-up.
|
||||
|
||||
PR review follow-up on 2026-09-25 also normalizes Windows Cursor project slugs and tests them in the Windows workflow; excludes the configured task-worktree root; recognizes HOME aliases by filesystem identity; and omits unchanged Cursor auth values from profile-save patches. It regenerates both settings discovery snapshots that the initial PR's frontend CI found stale, strengthens the settings-default assertion, and guards symlink-dependent tests on platforms without symlink support. The public guide and authoritative requirements/design now disclose that credentials are shared by exact server name without URL or issuer comparison. A synthetic test records that accepted trust boundary. Existing links remain when a refresh has no valid source, as required by the approved system-design compatibility limit.
|
||||
|
||||
The initial PR-head frontend check failed because its generated settings snapshot was stale. The generated files are now current. Backend results from the original implementation remain as documented above; the broad backend suite was not rerun for this review follow-up.
|
||||
|
||||
|
||||
Local review-fixup verification passed on 2026-09-25:
|
||||
|
||||
- `go test ./internal/agent/mcpconfig/... ./internal/agent/runtime/lifecycle/... ./internal/settingscatalog/...`
|
||||
- `go test -race ./internal/agent/mcpconfig/... ./internal/agent/runtime/lifecycle/... ./internal/settingscatalog/...`
|
||||
- `GOOS=windows GOARCH=amd64 go test -c -o /tmp/cursor-mcpconfig-windows.test.exe ./internal/agent/mcpconfig`
|
||||
- `golangci-lint run ./... --new-from-rev=b88aea31ad49b2cda40e8ad84452356888e36a42 --timeout=5m`
|
||||
- `make -C apps/backend build`
|
||||
- Cursor profile and agent-level save Vitest suites (49 tests combined), web typecheck, targeted ESLint, and Prettier check.
|
||||
- Settings contract CI test (3 tests), public-doc validation (62 tests, 47 pages), specification catalog validation/lint, and `git diff --check`.
|
||||
|
||||
The generated settings snapshots now pass `node --test scripts/settings-contract-ci.test.mjs`. Refreshed PR checks will be recorded after pushing the fixup commit.
|
||||
@@ -225,6 +225,7 @@ Select an agent, create a profile, then open **Settings > Agents > _Agent_ > _Pr
|
||||
| Enabled | Keeps the profile available to existing sessions and settings while hiding it from new task, session, handoff, and Quick Chat selectors. |
|
||||
| Auto-approve all permissions | Answers automatically: the first `allow_once`/`allow_always` option, otherwise the first option supplied by the agent; no options cancels. It is off by default. |
|
||||
| MCP servers | Adds profile-specific external MCP servers when the agent supports MCP. |
|
||||
| Share local Cursor MCP credentials | Enabled by default for Cursor ACP and Cursor-strategy terminal profiles. It applies only to local executions that share the backend home directory. |
|
||||
|
||||
Agents can inspect and update declared profile settings through the compact
|
||||
`search_settings_kandev`, `describe_setting_kandev`, `get_settings_kandev`,
|
||||
@@ -463,6 +464,16 @@ Terminal custom profiles use passthrough and preserve the CLI's native PTY inter
|
||||
|
||||
> **MCP credential exposure:** MCP headers and environment values are stored in profile configuration. Codex may place them in process arguments, and Cursor or Pi may leave them in project files after teardown. Use short-lived, narrowly scoped credentials and review persisted files.
|
||||
|
||||
### Share local Cursor MCP credentials
|
||||
|
||||
The **Share local Cursor MCP credentials** profile option is enabled by default for Cursor ACP and custom terminal profiles that use Cursor's MCP strategy. It applies only to local and worktree executions that use the same home directory as the Kandev backend. Remote and container executors, and profiles that set a different `HOME`, do not share the backend user's credentials.
|
||||
|
||||
On launch, Kandev combines valid `mcp-auth.json` files from other local Cursor projects into `~/.cursor/kandev-mcp-auth-unified.json`. For duplicate server names, the newest source file wins. Equal timestamps use project path order. Kandev links the current project's auth path to this private shared file. It preserves an existing regular `mcp-auth.json` file. While sharing is enabled, it replaces an existing symlink at that path when it points elsewhere. Disabling sharing does not restore the replaced target. On a disabled launch, Kandev removes only its own project auth link and leaves unrelated symlinks unchanged.
|
||||
|
||||
The shared auth file is keyed by MCP server name. Kandev does not compare server URLs or OAuth issuers between projects. A project with a matching server name can therefore use a copied credential even when its MCP configuration points to a different endpoint. Enable sharing only for trusted local project configurations. If a credential may have reached an unintended endpoint, revoke it through that provider.
|
||||
|
||||
To stop sharing, clear the option and launch that profile again. That launch removes only the Kandev-created link for its project. Running processes keep credentials they already loaded. Cursor may refresh credentials through the link, but Kandev does not copy refreshed credentials back to source projects. A later launch rebuilds the shared file from those source projects.
|
||||
|
||||
<details>
|
||||
<summary>Configure external MCP servers</summary>
|
||||
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
---
|
||||
status: draft
|
||||
system: agents
|
||||
created: 2026-09-24
|
||||
owners:
|
||||
- kandev
|
||||
---
|
||||
|
||||
# Cursor MCP OAuth bridge requirements
|
||||
|
||||
## Overview
|
||||
|
||||
Cursor stores MCP OAuth credentials per project. A new task worktree therefore lacks credentials that exist in another local project.
|
||||
The agent system owns this capability because it owns profile preferences and provider launch behavior.
|
||||
|
||||
## Requirements
|
||||
|
||||
### REQ-AGENTS-CURSOR-AUTH-001: Local credential sharing
|
||||
|
||||
**Intent:** Local Cursor sessions inherit MCP credentials from existing projects.
|
||||
|
||||
#### Acceptance criteria
|
||||
|
||||
- **AC-AGENTS-CURSOR-AUTH-001.1:** With sharing enabled, a new local Cursor execution shall inherit credentials from eligible non-task projects. Different server identities shall coexist.
|
||||
- **AC-AGENTS-CURSOR-AUTH-001.2:** For duplicate server identities, the most recently modified source auth file shall win. Equal timestamps shall use ascending project-path order, with the first path winning.
|
||||
- **AC-AGENTS-CURSOR-AUTH-001.3:** Both Cursor ACP and terminal profiles with the Cursor MCP strategy shall support sharing. Sharing shall work without profile-configured MCP servers.
|
||||
- **AC-AGENTS-CURSOR-AUTH-001.4:** A workspace and its canonical filesystem path shall resolve to the same Cursor project identity.
|
||||
- **AC-AGENTS-CURSOR-AUTH-001.5:** Absent Cursor data or absent eligible auth files shall produce a silent no-op. Other agents and remote executions shall not receive host credentials.
|
||||
- **AC-AGENTS-CURSOR-AUTH-001.6:** Each eligible launch shall refresh the shared snapshot from current source files. Kandev shall preserve each selected server object without interpretation.
|
||||
|
||||
### REQ-AGENTS-CURSOR-AUTH-002: Profile control
|
||||
|
||||
**Intent:** Users can choose whether each Cursor profile shares local credentials.
|
||||
|
||||
#### Acceptance criteria
|
||||
|
||||
- **AC-AGENTS-CURSOR-AUTH-002.1:** Existing and new Cursor profiles shall default to enabled. An explicit disabled value shall survive save, reload, restart, duplication, and unrelated profile edits.
|
||||
- **AC-AGENTS-CURSOR-AUTH-002.2:** Applicable profile settings shall expose a labeled checkbox. The description shall explain local cross-project sharing and next-launch timing.
|
||||
- **AC-AGENTS-CURSOR-AUTH-002.3:** On the next disabled launch, Kandev shall remove only that workspace's link to its unified auth file. It shall preserve other links and regular files.
|
||||
- **AC-AGENTS-CURSOR-AUTH-002.4:** Disabling shall not remove the shared file or change running sessions. If link removal fails, the new execution shall fail with a credential-free error.
|
||||
- **AC-AGENTS-CURSOR-AUTH-002.5:** Desktop and phone users shall save, discard, and reload the same value. Keyboard access, visible focus, and localized labels shall remain available.
|
||||
- **AC-AGENTS-CURSOR-AUTH-002.6:** The phone checkbox label shall provide a touch target of at least 44px. The settings page shall have no horizontal overflow.
|
||||
- **AC-AGENTS-CURSOR-AUTH-002.7:** Profile APIs and settings discovery shall expose the saved boolean and its default. They shall preserve omission separately from explicit false.
|
||||
|
||||
### REQ-AGENTS-CURSOR-AUTH-003: Credential file safety
|
||||
|
||||
**Intent:** The bridge preserves user files and keeps credentials out of application data and logs.
|
||||
|
||||
#### Acceptance criteria
|
||||
|
||||
- **AC-AGENTS-CURSOR-AUTH-003.1:** Task-project auth files and symlinked source entries shall never contribute credentials to the shared snapshot.
|
||||
- **AC-AGENTS-CURSOR-AUTH-003.2:** A regular destination auth file shall remain byte-for-byte unchanged. Directories and special files shall also remain unchanged.
|
||||
- **AC-AGENTS-CURSOR-AUTH-003.3:** Updates shall expose complete JSON snapshots and complete symlink targets. Concurrent Kandev launches shall not expose partial writes.
|
||||
- **AC-AGENTS-CURSOR-AUTH-003.4:** Kandev shall create shared credential files with owner-only read/write permissions. Credentials shall never appear in logs, APIs, events, or browser state.
|
||||
- **AC-AGENTS-CURSOR-AUTH-003.5:** Invalid or unreadable source files shall not prevent valid independent sources from contributing. Diagnostics shall omit credential contents.
|
||||
- **AC-AGENTS-CURSOR-AUTH-003.6:** If no valid source remains, Kandev shall not create a new link to an old snapshot. Existing user files shall remain unchanged.
|
||||
- **AC-AGENTS-CURSOR-AUTH-003.7:** Enabled bridge failures shall preserve existing files and allow normal Cursor startup. Cursor can then request authentication through its existing flow.
|
||||
|
||||
## Scope and limits
|
||||
|
||||
The checkbox controls bridge preparation, not OAuth revocation or credential isolation between processes that use the same workspace.
|
||||
A running process can retain credentials already loaded into memory.
|
||||
Profile choices share a filesystem destination when they use the same canonical workspace.
|
||||
|
||||
### Credential trust boundary
|
||||
|
||||
The bridge uses the exact MCP server name as the credential identity. It does not compare server URLs or OAuth issuers between projects. A trusted local project configuration with a matching name can therefore use a copied credential at a different endpoint. This is an accepted consequence of the default-enabled cross-project sharing behavior. Users are responsible for trusting project configurations launched with sharing enabled and for revoking provider credentials if an unintended endpoint may have received them.
|
||||
|
||||
The user chose newest-file conflict precedence and removal of the bridge link on the next disabled launch.
|
||||
File modification time does not prove credential freshness or token validity.
|
||||
|
||||
## Out of scope
|
||||
|
||||
- OAuth login, token validation, token refresh, and server configuration discovery.
|
||||
- Host credential transfer to containers, SSH, Kubernetes, or other remote runtimes.
|
||||
- Per-server account selection, background synchronization, and revocation of cached tokens.
|
||||
- Reading real developer credentials during automated verification.
|
||||
|
||||
## Implementation plans
|
||||
|
||||
- [Cursor auth bridge plan](../../../plans/cursor-mcp-oauth-bridge/plan.md)
|
||||
@@ -0,0 +1,220 @@
|
||||
---
|
||||
status: draft
|
||||
system: agents
|
||||
requirements:
|
||||
- REQ-AGENTS-CURSOR-AUTH-001
|
||||
- REQ-AGENTS-CURSOR-AUTH-002
|
||||
- REQ-AGENTS-CURSOR-AUTH-003
|
||||
---
|
||||
|
||||
# Cursor MCP OAuth bridge system design
|
||||
|
||||
## Ownership and source evidence
|
||||
|
||||
Agents owns the profile value and launch policy. Executors owns the local-versus-remote boundary.
|
||||
The [settings parity contract](../../platform/requirements/agent-settings-parity.md) supplies discovery and mutation conventions.
|
||||
|
||||
Current `materializeRuntimeProjectMCP` writes project MCP configuration for ACP providers.
|
||||
It returns early when no servers exist.
|
||||
Current `applyPassthroughMCP` handles terminal strategies separately.
|
||||
`CursorACP.Runtime` declares `mcpconfig.CursorStrategy{}`.
|
||||
Custom terminal agents can select the persisted strategy key `cursor`.
|
||||
|
||||
The user supplied the Cursor auth layout and slug algorithm.
|
||||
Automated tests will exercise that contract with synthetic credentials.
|
||||
They cannot prove compatibility with every Cursor release.
|
||||
|
||||
## Requirement mapping
|
||||
|
||||
| Requirement | Design sections |
|
||||
| --- | --- |
|
||||
| REQ-AGENTS-CURSOR-AUTH-001 | Eligibility, aggregation, launch integration |
|
||||
| REQ-AGENTS-CURSOR-AUTH-002 | Profile contract, disable behavior, settings UI |
|
||||
| REQ-AGENTS-CURSOR-AUTH-003 | File safety, failures, verification |
|
||||
|
||||
## Profile contract
|
||||
|
||||
Add `cursor_mcp_auth_enabled` to the persisted agent profile and shared DTO contracts.
|
||||
Use `CursorMCPAuthEnabled` in Go and `cursorMcpAuthEnabled` in browser models.
|
||||
This is a profile preference with a user-requested default of true, not a release toggle.
|
||||
|
||||
Add an integer SQLite column with `NOT NULL DEFAULT 1`.
|
||||
Cover fresh schema creation, additive migration, and legacy table reconstruction.
|
||||
Create requests use a boolean pointer so omission selects true and explicit false remains false.
|
||||
Patch omission preserves the saved value.
|
||||
All creation paths, including discovery and seeding, must set the default explicitly when SQL inserts include the column.
|
||||
Duplication copies the value. Reconciliation must not reset a saved false.
|
||||
|
||||
Extend models, DTOs, CRUD conversion, SELECT/scan, INSERT/UPDATE, boot payloads, and profile notifications.
|
||||
Register the boolean in `settings/dto/profile_contract.go` and `settingscatalog/defaults.go`.
|
||||
Use the existing compact settings update contract and field validation.
|
||||
Only the preference crosses APIs. Credential objects never cross those boundaries.
|
||||
|
||||
Extend `AgentProfileInfo` and `profile_resolver.go`.
|
||||
Launch policy uses the resolved concrete execution profile, including Office and dynamic-profile selection.
|
||||
Do not resolve an Office identity profile in place of its execution profile.
|
||||
Missing or failed profile resolution must not silently enable credential sharing.
|
||||
|
||||
## Eligibility and home
|
||||
|
||||
The bridge runs for `cursor-acp` and effective `CursorStrategy` profiles.
|
||||
Other agents do not read or mutate Cursor auth data.
|
||||
Resolve eligibility from the actual agent/strategy, not a command-name substring.
|
||||
|
||||
Only native local executions that share the backend filesystem and user home are eligible.
|
||||
Use existing executor/runtime classification and effective process environment.
|
||||
Exclude containers and remote runtimes even when a backend-local workspace path exists.
|
||||
If a profile overrides HOME to another user directory, skip host sharing rather than link unusable or unintended credentials.
|
||||
Treat unknown execution locality as ineligible.
|
||||
|
||||
Resolve the backend user home through Go, then use its `.cursor` directory.
|
||||
Do not create a missing Cursor home.
|
||||
Tests inject a temporary home and never scan the developer's home.
|
||||
|
||||
## Helper boundary and aggregation
|
||||
|
||||
Add `mcpconfig/cursor_auth_bridge.go` with the requested public helpers:
|
||||
|
||||
- `DeriveCursorProjectSlug(workspacePath string) string`
|
||||
- `AggregateCursorMCPAuth(cursorHome string, excludedWorkspaceRoots ...string) error`
|
||||
- `LinkCursorMCPAuth(workspacePath, cursorHome string, excludedWorkspaceRoots ...string) error`
|
||||
|
||||
Keep slug derivation pure. The link helper resolves an absolute path and evaluates workspace symlinks before derivation.
|
||||
Normalize Windows separators. Replace each slash, dot, underscore, and colon, including a drive-volume separator, with a dash, then trim boundary dashes.
|
||||
Do not collapse internal dash runs. Reject an empty resulting slug.
|
||||
|
||||
Scan direct project directories under `<cursorHome>/projects`.
|
||||
Exclude the current workspace and project slugs under the default task scratch root and configured task-worktree root, names containing `kandev-tasks`, symlinked project entries, and non-directory entries.
|
||||
Task-root exclusion compares each canonical root's project slug with entry slug prefixes, so custom `tasks_base_path` values do not depend on their name containing `kandev-tasks`.
|
||||
When a configured root is absent, resolve its existing parent and append the missing path suffix. This still excludes stale Cursor project entries after task worktree directories are removed. A different root-resolution error prevents aggregation rather than risking task credentials in the snapshot.
|
||||
Use `Lstat` for each auth file and accept only regular, non-symlink files.
|
||||
Also reject a symlinked projects root to avoid scanning an unexpected tree.
|
||||
|
||||
Decode JSON as `map[string]json.RawMessage`.
|
||||
Require an object root and object-valued server entries.
|
||||
Skip invalid files as a whole. Preserve unknown fields inside server objects.
|
||||
Order sources by descending modification time and ascending path.
|
||||
Select the first object for each exact server key.
|
||||
Do not deep-merge tokens or combine accounts.
|
||||
|
||||
Credential identity is the exact server name. The bridge does not read project MCP configuration or compare server URLs or OAuth issuers. A local project that declares an existing server name can therefore use its copied credential at another endpoint. This is an accepted trust boundary of default-enabled sharing: users must trust local project configurations launched with sharing enabled and revoke credentials through the provider if an unintended endpoint may have received them. The synthetic aggregation test covers this name-only sharing behavior.
|
||||
|
||||
Rebuild `<cursorHome>/kandev-mcp-auth-unified.json` from sources on each eligible enabled launch.
|
||||
The prior master is never a source.
|
||||
A valid empty source object can produce an empty snapshot.
|
||||
No eligible valid source means no master publication and no new link.
|
||||
Use an internal result that distinguishes no sources from a successful empty snapshot.
|
||||
The public error-only helper can wrap this result.
|
||||
The composed link operation uses the result directly and must not infer success from an old master.
|
||||
|
||||
## File safety and concurrency
|
||||
|
||||
Use a package mutex around the complete bridge operation.
|
||||
Concurrent Kandev launches serialize discovery, publication, linking, and disabled cleanup.
|
||||
The lock must also cover public helper calls without recursive locking.
|
||||
Independent backend processes and Cursor do not participate in this mutex.
|
||||
Unique temporary names and atomic publication keep their writes complete, but cannot provide token-refresh coordination.
|
||||
|
||||
Write the master to a temporary file in the same directory.
|
||||
Create it with mode `0600`, write complete JSON, close it, then rename it into place.
|
||||
Remove temporary files after every failure.
|
||||
Reject a pre-existing master that is a symlink, directory, or special file.
|
||||
The master is a Kandev-owned regular file and can be replaced.
|
||||
The prohibition on replacing regular user auth files applies to the project destination.
|
||||
|
||||
Create the project directory with requested mode `0755`, subject to umask.
|
||||
Do not change permissions on existing user directories.
|
||||
Reject a symlinked project destination directory.
|
||||
Check destination `mcp-auth.json` with `Lstat`.
|
||||
If it is regular, a directory, or special, preserve it without replacement.
|
||||
If it already points to the master, leave the link unchanged.
|
||||
For an absent destination, create the final symlink directly. Creation is atomic and fails if a file appears concurrently.
|
||||
For an existing symlink, create a uniquely named sibling symlink and rename it over the old link.
|
||||
Recheck destination type immediately before replacement.
|
||||
This prevents ordinary launch races under the package lock.
|
||||
It does not claim protection against an adversarial process that replaces paths between filesystem calls.
|
||||
|
||||
The symlink target is the absolute master path.
|
||||
Bridge files do not enter generic MCP teardown lists.
|
||||
Stopping one session must not remove credentials used by another session.
|
||||
|
||||
## Disable behavior
|
||||
|
||||
On the next eligible disabled launch, resolve the canonical project destination without creating directories.
|
||||
Use `Lstat` and `Readlink`.
|
||||
Remove only a symlink whose normalized absolute target is the Kandev master.
|
||||
Accept an equivalent relative target after resolution against the link directory.
|
||||
Preserve regular files, unrelated links, and the master.
|
||||
Do not aggregate on this path.
|
||||
|
||||
A missing link is successful cleanup.
|
||||
If a matching link cannot be removed, return a sanitized launch error.
|
||||
Otherwise a disabled launch could still inherit shared credentials.
|
||||
Saving the preference does not touch the filesystem or terminate running sessions.
|
||||
|
||||
## Launch integration
|
||||
|
||||
Call one lifecycle helper from `materializeRuntimeProjectMCP` before the empty-server return.
|
||||
Call it from `applyPassthroughMCP` for the Cursor strategy before ordinary MCP materialization.
|
||||
Keep `CursorStrategy.BuildPassthroughMCP` free of home-directory side effects.
|
||||
Its callers also serve command previews and must not publish credentials.
|
||||
|
||||
Pass the resolved execution profile into bridge preparation.
|
||||
The two normal launch sites in `manager_launch.go` already hold resolved profile information.
|
||||
Workspace promotion must use the incoming execution profile even before it updates execution metadata.
|
||||
Exercise initial launch, workspace promotion, and resumed execution that starts a new process.
|
||||
Do not rerun preparation for a message sent to an already running process.
|
||||
|
||||
## Failures and diagnostics
|
||||
|
||||
Missing Cursor home, absent sources, ineligible runtime, and protected user destinations produce no warning.
|
||||
Malformed or unreadable sources can produce a bounded warning with an operation/reason code.
|
||||
Never log JSON, server objects, tokens, or raw parser errors containing source text.
|
||||
|
||||
Enabled publication or link errors produce a sanitized warning and preserve normal launch behavior.
|
||||
A failed publication does not create a link to an older master.
|
||||
Existing links can still reference the previous snapshot after a failed refresh.
|
||||
This is a compatibility limit, not a claim of fresh authentication.
|
||||
Disabled cleanup errors fail the new launch as described above.
|
||||
|
||||
## Settings UI and mobile contract
|
||||
|
||||
Show a checkbox in the existing profile settings card for Cursor and custom terminal agents whose MCP strategy is Cursor.
|
||||
Use `@kandev/ui/checkbox`, a linked label, and visible description.
|
||||
Do not classify this setting as a permission or send it as a CLI flag.
|
||||
The value participates in create/edit drafts, dirty detection, save/discard, external-change reconciliation, and normalization.
|
||||
|
||||
Proposed localized copy:
|
||||
|
||||
- Label: "Share local Cursor MCP credentials"
|
||||
- Description: "Reuse MCP sign-ins from other local Cursor projects. Applies on the next launch."
|
||||
- Disabled timing note: "Turning this off removes the shared link on the next launch. Running sessions keep credentials already loaded."
|
||||
|
||||
Use the existing Settings save controls and failure messages.
|
||||
Add English, Portuguese, Simplified Chinese, both Traditional Chinese catalogs, and Japanese.
|
||||
Generate the Traditional Chinese pair with `pnpm run i18n:zh-hant`.
|
||||
|
||||
Entry point: Settings > Agents > applicable profile.
|
||||
The nearest shipped exemplar is `agent-profile-page.tsx` and its shared settings card.
|
||||
`mobile-agent-profile-layout.spec.ts` demonstrates direct phone navigation and overflow checks.
|
||||
The form stays inline on the full settings route because this is one persistent preference.
|
||||
The existing settings scroll container remains the sole page scroll owner.
|
||||
The phone label wraps and supplies a 44px minimum touch target.
|
||||
Desktop keeps normal form density. Both sizes share draft state and save logic.
|
||||
No overlay or hover-only help is necessary.
|
||||
|
||||
## Verification and limits
|
||||
|
||||
Use synthetic opaque server objects and a temporary HOME.
|
||||
The helper suite covers source exclusion, conflict order, canonical slug, permissions, atomic publication, protected destinations, concurrency, and disable cleanup.
|
||||
Lifecycle tests cover eligibility, both launch modes, promotion, no-server behavior, profile resolution, and failure policy.
|
||||
A temporary git repository/worktree test proves the expected link target without real OAuth.
|
||||
|
||||
Desktop and phone Playwright tests prove default-on, save/reload false, re-enable, discard, and absence for other agents.
|
||||
Unit tests cover request omission, migration, duplication, and frontend draft reconciliation.
|
||||
The [plan](../../../plans/cursor-mcp-oauth-bridge/plan.md) owns exact commands and test names.
|
||||
|
||||
Cursor can replace a symlink during its own auth writes. A later enabled launch repairs it only if it remains a symlink.
|
||||
If Cursor creates a regular file, Kandev preserves that file.
|
||||
Cursor token refresh through a link can update the master, but the next aggregation still uses source-project precedence.
|
||||
This design does not synchronize refresh writes back to source projects.
|
||||
Reference in New Issue
Block a user