@velum-labs/cursorkit 0.1.0

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.
Files changed (142) hide show
  1. package/DISCLAIMER.md +12 -0
  2. package/README.md +157 -0
  3. package/dist/src/agentTools/diff.d.ts +11 -0
  4. package/dist/src/agentTools/diff.js +88 -0
  5. package/dist/src/agentTools/policy.d.ts +3 -0
  6. package/dist/src/agentTools/policy.js +12 -0
  7. package/dist/src/agentTools/registry.d.ts +114 -0
  8. package/dist/src/agentTools/registry.js +663 -0
  9. package/dist/src/agentTools/results.d.ts +14 -0
  10. package/dist/src/agentTools/results.js +117 -0
  11. package/dist/src/agentTools/schemas.d.ts +3 -0
  12. package/dist/src/agentTools/schemas.js +89 -0
  13. package/dist/src/agentTools/surface.d.ts +11 -0
  14. package/dist/src/agentTools/surface.js +251 -0
  15. package/dist/src/certs.d.ts +8 -0
  16. package/dist/src/certs.js +34 -0
  17. package/dist/src/ck.d.ts +2 -0
  18. package/dist/src/ck.js +6 -0
  19. package/dist/src/ckLauncher.d.ts +150 -0
  20. package/dist/src/ckLauncher.js +1496 -0
  21. package/dist/src/cli.d.ts +2 -0
  22. package/dist/src/cli.js +265 -0
  23. package/dist/src/config.d.ts +52 -0
  24. package/dist/src/config.js +210 -0
  25. package/dist/src/connectEnvelope.d.ts +16 -0
  26. package/dist/src/connectEnvelope.js +70 -0
  27. package/dist/src/desktop.d.ts +19 -0
  28. package/dist/src/desktop.js +167 -0
  29. package/dist/src/desktopConnectProxy.d.ts +26 -0
  30. package/dist/src/desktopConnectProxy.js +175 -0
  31. package/dist/src/extensions/index.d.ts +2 -0
  32. package/dist/src/extensions/index.js +1 -0
  33. package/dist/src/extensions/registry.d.ts +8 -0
  34. package/dist/src/extensions/registry.js +52 -0
  35. package/dist/src/extensions/types.d.ts +42 -0
  36. package/dist/src/extensions/types.js +1 -0
  37. package/dist/src/fixtures/modelFusion.d.ts +103 -0
  38. package/dist/src/fixtures/modelFusion.js +404 -0
  39. package/dist/src/fixtures/replay.d.ts +9 -0
  40. package/dist/src/fixtures/replay.js +41 -0
  41. package/dist/src/fixtures/sanitizer.d.ts +9 -0
  42. package/dist/src/fixtures/sanitizer.js +43 -0
  43. package/dist/src/fixtures/schema.d.ts +38 -0
  44. package/dist/src/fixtures/schema.js +33 -0
  45. package/dist/src/gen/agent/v1/agent_pb.d.ts +21577 -0
  46. package/dist/src/gen/agent/v1/agent_pb.js +5325 -0
  47. package/dist/src/gen/aiserver/v1/aiserver_pb.d.ts +135242 -0
  48. package/dist/src/gen/aiserver/v1/aiserver_pb.js +34430 -0
  49. package/dist/src/gen/anyrun/v1/anyrun_pb.d.ts +1163 -0
  50. package/dist/src/gen/anyrun/v1/anyrun_pb.js +374 -0
  51. package/dist/src/gen/google/protobuf/google_pb.d.ts +142 -0
  52. package/dist/src/gen/google/protobuf/google_pb.js +54 -0
  53. package/dist/src/gen/internapi/v1/internapi_pb.d.ts +121 -0
  54. package/dist/src/gen/internapi/v1/internapi_pb.js +79 -0
  55. package/dist/src/logger.d.ts +8 -0
  56. package/dist/src/logger.js +37 -0
  57. package/dist/src/modelFusion/cursorHarness.d.ts +146 -0
  58. package/dist/src/modelFusion/cursorHarness.js +647 -0
  59. package/dist/src/modelFusion/index.d.ts +4 -0
  60. package/dist/src/modelFusion/index.js +2 -0
  61. package/dist/src/models/registry.d.ts +22 -0
  62. package/dist/src/models/registry.js +30 -0
  63. package/dist/src/proto.d.ts +13 -0
  64. package/dist/src/proto.js +61 -0
  65. package/dist/src/providers/openai.d.ts +64 -0
  66. package/dist/src/providers/openai.js +355 -0
  67. package/dist/src/redaction.d.ts +4 -0
  68. package/dist/src/redaction.js +65 -0
  69. package/dist/src/routeInventory.d.ts +16 -0
  70. package/dist/src/routeInventory.js +39 -0
  71. package/dist/src/routes.d.ts +37 -0
  72. package/dist/src/routes.js +227 -0
  73. package/dist/src/server.d.ts +50 -0
  74. package/dist/src/server.js +1353 -0
  75. package/dist/src/services/agent.d.ts +1 -0
  76. package/dist/src/services/agent.js +7 -0
  77. package/dist/src/services/agentRun.d.ts +60 -0
  78. package/dist/src/services/agentRun.js +391 -0
  79. package/dist/src/services/chat.d.ts +11 -0
  80. package/dist/src/services/chat.js +47 -0
  81. package/dist/src/services/models.d.ts +10 -0
  82. package/dist/src/services/models.js +216 -0
  83. package/dist/src/services/serverConfig.d.ts +2 -0
  84. package/dist/src/services/serverConfig.js +19 -0
  85. package/dist/src/testing/artifacts.d.ts +14 -0
  86. package/dist/src/testing/artifacts.js +92 -0
  87. package/dist/src/testing/cli.d.ts +4 -0
  88. package/dist/src/testing/cli.js +192 -0
  89. package/dist/src/testing/localBackend.d.ts +24 -0
  90. package/dist/src/testing/localBackend.js +310 -0
  91. package/dist/src/testing/processRunner.d.ts +7 -0
  92. package/dist/src/testing/processRunner.js +74 -0
  93. package/dist/src/testing/runner.d.ts +9 -0
  94. package/dist/src/testing/runner.js +85 -0
  95. package/dist/src/testing/scenarios.d.ts +3 -0
  96. package/dist/src/testing/scenarios.js +2535 -0
  97. package/dist/src/testing/types.d.ts +66 -0
  98. package/dist/src/testing/types.js +1 -0
  99. package/dist/src/tools/baselineInventory.d.ts +12 -0
  100. package/dist/src/tools/baselineInventory.js +680 -0
  101. package/dist/src/tools/checkModelFusionProtocol.d.ts +1 -0
  102. package/dist/src/tools/checkModelFusionProtocol.js +274 -0
  103. package/dist/src/tools/checkReleasePublishConfig.d.ts +1 -0
  104. package/dist/src/tools/checkReleasePublishConfig.js +99 -0
  105. package/dist/src/tools/generateProtoInventory.d.ts +1 -0
  106. package/dist/src/tools/generateProtoInventory.js +89 -0
  107. package/dist/src/tools/normalizeGeneratedCode.d.ts +1 -0
  108. package/dist/src/tools/normalizeGeneratedCode.js +18 -0
  109. package/dist/src/tools/releaseCheck.d.ts +26 -0
  110. package/dist/src/tools/releaseCheck.js +367 -0
  111. package/dist/src/trace.d.ts +39 -0
  112. package/dist/src/trace.js +106 -0
  113. package/dist/src/translation.d.ts +6 -0
  114. package/dist/src/translation.js +22 -0
  115. package/dist/src/upstream.d.ts +20 -0
  116. package/dist/src/upstream.js +270 -0
  117. package/docs/configuration.md +55 -0
  118. package/docs/cursor-app.md +263 -0
  119. package/docs/implementation-inventory.json +609 -0
  120. package/docs/learnings.md +363 -0
  121. package/docs/model-fusion-protocol-origin.json +126 -0
  122. package/docs/model-fusion-protocol.md +110 -0
  123. package/docs/plugin-authoring.md +24 -0
  124. package/docs/proto-inventory.md +1477 -0
  125. package/docs/protocol-surface-audit.md +92 -0
  126. package/docs/protocol.md +52 -0
  127. package/docs/refreshing-protos.md +78 -0
  128. package/docs/release-gates.md +110 -0
  129. package/docs/release-summary.json +86 -0
  130. package/docs/route-contract-manifest.json +288 -0
  131. package/docs/route-policy.json +133 -0
  132. package/docs/service-manifest.json +9490 -0
  133. package/docs/test-manifest.json +155 -0
  134. package/docs/testing-harness.md +204 -0
  135. package/docs/troubleshooting.md +36 -0
  136. package/docs/type-manifest-summary.json +28927 -0
  137. package/package.json +93 -0
  138. package/proto/agent/v1/agent.proto +5371 -0
  139. package/proto/aiserver/v1/aiserver.proto +32944 -0
  140. package/proto/anyrun/v1/anyrun.proto +294 -0
  141. package/proto/google/protobuf/google.proto +37 -0
  142. package/proto/internapi/v1/internapi.proto +32 -0
@@ -0,0 +1,155 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "generatedBy": "src/tools/baselineInventory.ts",
4
+ "suites": [
5
+ {
6
+ "id": "baseline-drift",
7
+ "command": "pnpm baseline:check",
8
+ "deterministic": true,
9
+ "status": "implemented",
10
+ "categories": ["baseline-drift", "protocol", "final-gate"],
11
+ "releaseCheck": "required",
12
+ "prerequisites": ["node>=22", "pnpm install"],
13
+ "timeoutMs": 30000,
14
+ "artifactOutputs": [
15
+ "docs/route-contract-manifest.json",
16
+ "docs/implementation-inventory.json",
17
+ "docs/test-manifest.json",
18
+ "docs/release-summary.json"
19
+ ],
20
+ "completionCriteria": [
21
+ "Generated route/config/docs artifacts match committed files.",
22
+ "Every route in src/routes.ts has a route contract entry.",
23
+ "Every env var read by src/config.ts has a config inventory entry."
24
+ ]
25
+ },
26
+ {
27
+ "id": "build",
28
+ "command": "pnpm build",
29
+ "deterministic": true,
30
+ "status": "implemented",
31
+ "categories": ["static", "final-gate"],
32
+ "prerequisites": ["node>=22", "pnpm install"],
33
+ "releaseCheck": "required",
34
+ "timeoutMs": 60000,
35
+ "artifactOutputs": [".cursor-rpc/release-check/release-summary.json"],
36
+ "completionCriteria": ["TypeScript build and declaration emit pass."]
37
+ },
38
+ {
39
+ "id": "unit-tests",
40
+ "command": "pnpm test",
41
+ "deterministic": true,
42
+ "status": "implemented",
43
+ "categories": [
44
+ "protocol",
45
+ "mlx",
46
+ "tool",
47
+ "reliability-security",
48
+ "final-gate"
49
+ ],
50
+ "releaseCheck": "required",
51
+ "prerequisites": ["node>=22", "pnpm install"],
52
+ "timeoutMs": 120000,
53
+ "artifactOutputs": [".cursor-rpc/release-check/release-summary.json"],
54
+ "completionCriteria": [
55
+ "Protocol route shapes, fixture replay, MLX contract, tool runtime, desktop proxy, and reliability/security regression tests pass."
56
+ ]
57
+ },
58
+ {
59
+ "id": "format-check",
60
+ "command": "pnpm format:check",
61
+ "deterministic": true,
62
+ "status": "implemented",
63
+ "categories": ["static", "final-gate"],
64
+ "releaseCheck": "required",
65
+ "prerequisites": ["node>=22", "pnpm install"],
66
+ "timeoutMs": 60000,
67
+ "artifactOutputs": [".cursor-rpc/release-check/release-summary.json"],
68
+ "completionCriteria": [
69
+ "Source, tests, docs, JSON, YAML, and examples formatting pass."
70
+ ]
71
+ },
72
+ {
73
+ "id": "examples-typecheck",
74
+ "command": "pnpm examples:check",
75
+ "deterministic": true,
76
+ "status": "implemented",
77
+ "categories": ["packaging", "final-gate"],
78
+ "releaseCheck": "required",
79
+ "prerequisites": ["node>=22", "pnpm install", "pnpm build"],
80
+ "timeoutMs": 60000,
81
+ "artifactOutputs": [".cursor-rpc/release-check/release-summary.json"],
82
+ "completionCriteria": [
83
+ "Examples typecheck against the built package exports that tarball consumers use."
84
+ ]
85
+ },
86
+ {
87
+ "id": "pack-smoke",
88
+ "command": "pnpm pack && pnpm add --offline <tarball> && cursorkit --help",
89
+ "deterministic": true,
90
+ "status": "implemented",
91
+ "categories": ["packaging", "final-gate"],
92
+ "releaseCheck": "required",
93
+ "prerequisites": ["node>=22", "pnpm install", "pnpm build"],
94
+ "timeoutMs": 60000,
95
+ "artifactOutputs": [".cursor-rpc/release-check/release-summary.json"],
96
+ "completionCriteria": [
97
+ "Packed tarball contains required dist/src, proto, docs, README.md, and DISCLAIMER.md files.",
98
+ "Source examples are typechecked but intentionally excluded from the tarball.",
99
+ "A clean temporary project can install the tarball from the local pnpm store.",
100
+ "The packed cursorkit binary executes --help successfully."
101
+ ]
102
+ },
103
+ {
104
+ "id": "mlx-live",
105
+ "command": "pnpm test:harness -- --suite local-backend --base-url <mlx-url> --provider-model <mlx-model>",
106
+ "deterministic": false,
107
+ "status": "optional_live",
108
+ "categories": ["mlx"],
109
+ "releaseCheck": "reported_skipped_with_reason",
110
+ "prerequisites": ["Running MLX OpenAI-compatible backend"],
111
+ "timeoutMs": 30000,
112
+ "artifactOutputs": [".cursor-rpc/test-runs/*/local-backend-report.json"],
113
+ "completionCriteria": [
114
+ "/v1/models returns the configured provider model.",
115
+ "/v1/chat/completions returns a non-empty response."
116
+ ]
117
+ },
118
+ {
119
+ "id": "real-client-live",
120
+ "command": "pnpm test:harness -- --suite traffic,acp --base-url <mlx-url> --model <cursor-model> --provider-model <mlx-model>",
121
+ "deterministic": false,
122
+ "status": "optional_live",
123
+ "categories": ["protocol", "mlx", "tool"],
124
+ "releaseCheck": "reported_skipped_with_reason",
125
+ "prerequisites": [
126
+ "cursor-agent installed",
127
+ "Cursor auth available",
128
+ "Running MLX OpenAI-compatible backend"
129
+ ],
130
+ "timeoutMs": 120000,
131
+ "artifactOutputs": [".cursor-rpc/test-runs/*/summary.json"],
132
+ "completionCriteria": [
133
+ "CLI, ACP, and desktop flows report passed or skipped_with_reason."
134
+ ]
135
+ },
136
+ {
137
+ "id": "desktop-live",
138
+ "command": "pnpm test:harness -- --suite desktop-ui-experimental --include-experimental --base-url <mlx-url> --model <cursor-model> --provider-model <mlx-model>",
139
+ "deterministic": false,
140
+ "status": "optional_live",
141
+ "categories": ["desktop-optional-live"],
142
+ "releaseCheck": "reported_skipped_with_reason",
143
+ "prerequisites": [
144
+ "Cursor desktop installed",
145
+ "Cursor auth available",
146
+ "Running MLX OpenAI-compatible backend"
147
+ ],
148
+ "timeoutMs": 180000,
149
+ "artifactOutputs": [".cursor-rpc/test-runs/*/desktop-ui-report.json"],
150
+ "completionCriteria": [
151
+ "Desktop route inventory, picker visibility, selected local model, submitted prompt, MLX request, and visible response pass or report skipped_with_reason with an actionable prerequisite."
152
+ ]
153
+ }
154
+ ]
155
+ }
@@ -0,0 +1,204 @@
1
+ # Unified Testing Harness
2
+
3
+ The unified harness orchestrates the existing test layers and writes structured
4
+ evidence for each run. It does not replace `pnpm check`, `pnpm e2e:cursor-agent`,
5
+ or `pnpm ck test`; it wraps them so failures can be compared with the same
6
+ artifact and diagnosis format.
7
+
8
+ ## Commands
9
+
10
+ Build before running the harness:
11
+
12
+ ```bash
13
+ pnpm build
14
+ ```
15
+
16
+ Run deterministic local checks:
17
+
18
+ ```bash
19
+ pnpm test:harness -- --suite static
20
+ pnpm test:harness -- --suite bridge-protocol
21
+ pnpm test:harness -- --suite cli
22
+ pnpm test:harness -- --suite traffic
23
+ pnpm test:harness -- --suite acp
24
+ ```
25
+
26
+ Validate a local OpenAI-compatible MLX server:
27
+
28
+ ```bash
29
+ pnpm test:harness -- \
30
+ --suite local-backend \
31
+ --base-url http://127.0.0.1:8080/v1 \
32
+ --model mlx-community/Qwen3.5-4B-8bit \
33
+ --display-name local-qwen \
34
+ --api-key local
35
+ ```
36
+
37
+ When the Cursor-facing id should be friendlier than the backend id, use both:
38
+
39
+ ```bash
40
+ pnpm test:harness -- \
41
+ --suite local-backend,desktop-ui-experimental \
42
+ --include-experimental \
43
+ --base-url http://127.0.0.1:8080/v1 \
44
+ --model local-qwen \
45
+ --provider-model mlx-community/Qwen3.5-4B-8bit \
46
+ --display-name local-qwen \
47
+ --api-key local
48
+ ```
49
+
50
+ Run the desktop route-inventory smoke test:
51
+
52
+ ```bash
53
+ pnpm test:harness -- \
54
+ --suite desktop \
55
+ --use-default-profile \
56
+ --timeout-ms 30000 \
57
+ --base-url http://127.0.0.1:8080/v1 \
58
+ --model mlx-community/Qwen3.5-4B-8bit \
59
+ --display-name local-qwen \
60
+ --api-key local
61
+ ```
62
+
63
+ ## Suites
64
+
65
+ - `static`: runs `pnpm check`.
66
+ - `bridge-protocol`: runs focused bridge integration tests for server behavior,
67
+ route inventory, and upstream connection handling.
68
+ - `local-backend`: checks `/v1/models` and `/v1/chat/completions` against a
69
+ local OpenAI-compatible server.
70
+ - `cursor-agent` or `cli`: runs the real `cursor-agent` e2e smoke test with
71
+ desktop-specific environment variables isolated.
72
+ - `cursor-agent-traffic` or `traffic`: starts the bridge with route inventory
73
+ enabled, runs real `cursor-agent --list-models` and `cursor-agent --print`
74
+ commands through the bridge, then writes a redacted route inventory report.
75
+ - `cursor-agent-acp-experimental` or `acp`: starts the bridge and drives
76
+ `cursor-agent acp` with newline-delimited JSON-RPC
77
+ `initialize`/`authenticate`/`session/new`/`session/prompt` messages. It checks
78
+ the same local completion and route-inventory evidence as the traffic suite,
79
+ but without PTY automation.
80
+ - `desktop` or `desktop-route`: runs `ck test`, then parses desktop route
81
+ inventory logs.
82
+ - `desktop-ui-experimental`: launches an isolated Cursor instance with auth rows
83
+ seeded from the logged-in default Cursor profile, opens the current workspace,
84
+ attaches to the Electron renderer through CDP, dismisses safe onboarding
85
+ prompts, waits for Cursor to create its settings state, activates the local
86
+ model in the isolated profile, reloads the workbench, opens a new Agent
87
+ composer, clicks the active model picker trigger, and fails unless the
88
+ configured local model and existing built-in Cursor models are both visible.
89
+ It also attempts to submit a probe prompt, but currently treats Monaco composer
90
+ submission as an explicit gate instead of inferring success from inserted text.
91
+
92
+ `all` runs the deterministic core suites. Desktop testing stays explicit because
93
+ it launches Cursor.
94
+
95
+ `pnpm release:check` does not run optional live suites. It reports MLX,
96
+ real-client, and desktop live gates as `skipped_with_reason` unless an operator
97
+ runs them explicitly with the prerequisites above. This keeps deterministic
98
+ release readiness separate from final-gate validation on a machine with Cursor
99
+ auth, Cursor desktop, and a running MLX backend.
100
+
101
+ ## Artifacts
102
+
103
+ Every run writes to `.cursor-rpc/test-runs/<timestamp>/` unless
104
+ `--artifacts-dir` is provided.
105
+
106
+ Artifacts include:
107
+
108
+ - `summary.json`: machine-readable scenario results.
109
+ - `summary.md`: human-readable result list.
110
+ - `junit.xml`: basic CI-compatible test report.
111
+ - `logs/*.log`: command stdout/stderr transcripts.
112
+ - scenario-specific JSON reports, such as `local-backend-report.json` and
113
+ `desktop-route-report.json`.
114
+ - route reports include `routeSummary`, an aggregated per-path view with count,
115
+ method, status, framing, policy, and outcome sets.
116
+ - traffic and ACP reports include `agentRunDiagnostics`, a body-free summary of
117
+ model id, prompt length, context counts, MCP tool count/names, and how many
118
+ context messages were injected into the local OpenAI-compatible request.
119
+
120
+ ## Failure Codes
121
+
122
+ - `backend_unreachable`: the local MLX/OpenAI-compatible server is not reachable
123
+ or does not expose the requested model.
124
+ - `bridge_start_failed`: the bridge did not start or `ck test` failed before
125
+ route evidence.
126
+ - `route_missing`: desktop or CLI traffic did not reach the bridge.
127
+ - `model_route_missing`: traffic reached the bridge, but known model-list RPCs
128
+ did not.
129
+ - `extension_host_route_missing`: desktop traffic reached the bridge, but an
130
+ active Agent prompt did not produce a known agent send route.
131
+ - `model_metadata_rejected`: model routes were served, but Cursor did not accept
132
+ or display the local model.
133
+ - `local_completion_failed`: model listing worked, but chat completion failed.
134
+ - `upstream_passthrough_failed`: unknown route pass-through failed.
135
+ - `auth_profile_blocked`: desktop auth/profile state blocked testing before
136
+ route evidence.
137
+ - `command_failed`, `timeout`, `not_available`: generic harness-level outcomes.
138
+
139
+ ## Desktop Notes
140
+
141
+ Desktop testing remains evidence-first, but the model picker itself is
142
+ settings-backed. In observed Cursor builds, opening the picker does not
143
+ necessarily issue a fresh model-list RPC; it reads cached/activated model state
144
+ from the profile. The UI suite therefore activates the local model in the
145
+ isolated profile and asserts additive behavior in the real picker. Route
146
+ inventory is still captured as supporting evidence for backend traffic, but it
147
+ is not required for the picker-visibility assertion.
148
+
149
+ If the result is `route_missing`, run `pnpm ck route status` and then
150
+ `pnpm ck route` before applying the manual routing fallback. The route commands
151
+ print operator-reviewed setup and rollback commands only.
152
+
153
+ Use `desktop-ui-experimental` as the real app-level gate. It is intentionally
154
+ strict: CDP attach alone is not enough. The suite opens the picker, confirms the
155
+ local model is additive, selects the local model in the active Agent composer,
156
+ and attempts to submit a prompt. The first-class CONNECT proxy has been
157
+ validated to route desktop traffic through the bridge, including model and
158
+ default-model routes. The current failing edge is the app's Monaco-backed
159
+ composer input: the harness refuses to report a local response until it can
160
+ prove the prompt was submitted and a known Agent send route reached the bridge.
161
+
162
+ ## Traffic Discovery
163
+
164
+ Use the traffic suite when changing route handling or model metadata:
165
+
166
+ ```bash
167
+ pnpm test:harness -- \
168
+ --suite traffic \
169
+ --base-url http://127.0.0.1:8080/v1 \
170
+ --model local-qwen \
171
+ --provider-model mlx-community/Qwen3.5-4B-8bit \
172
+ --display-name local-qwen \
173
+ --api-key local
174
+ ```
175
+
176
+ This suite captures route metadata only. It does not persist request or response
177
+ bodies. The useful artifact is `traffic-probe-report.json`, which records the
178
+ observed paths, `routeSummary`, known model-route coverage, and whether the real
179
+ CLI listed and used the configured local model.
180
+
181
+ Healthy pass-through routes are reported separately from failed routes. A
182
+ pass-through entry with HTTP 200 usually means the bridge correctly forwarded an
183
+ unknown route to upstream. A failed route means the upstream or interceptor
184
+ returned an HTTP error.
185
+
186
+ ## ACP Probe
187
+
188
+ Use the ACP suite to exercise the same bridge path through the structured Agent
189
+ Client Protocol instead of a terminal UI:
190
+
191
+ ```bash
192
+ pnpm test:harness -- \
193
+ --suite acp \
194
+ --base-url http://127.0.0.1:8080/v1 \
195
+ --model local-qwen \
196
+ --provider-model mlx-community/Qwen3.5-4B-8bit \
197
+ --display-name local-qwen \
198
+ --api-key local
199
+ ```
200
+
201
+ ACP still depends on local Cursor login state, so `auth_profile_blocked` means
202
+ `cursor-agent` could not authenticate or create a session before route evidence
203
+ was available. When it passes, `acp-probe-report.json` should include
204
+ `traffic-probe-ok`, the three known model routes, `RunSSE`, and `BidiAppend`.
@@ -0,0 +1,36 @@
1
+ # Troubleshooting
2
+
3
+ For the full set of observed CLI, desktop, model-picker, and proxy lessons, see
4
+ `docs/learnings.md`.
5
+
6
+ ## `doctor` Warns About Missing Upstream
7
+
8
+ Set `CURSOR_UPSTREAM_BASE_URL` before using pass-through traffic. Without it, unknown routes cannot be forwarded.
9
+
10
+ ## Cursor Rejects The Bridge Certificate
11
+
12
+ The bridge does not install trust silently. Set `BRIDGE_USE_TLS=true` and either provide `BRIDGE_CERT_PATH` plus `BRIDGE_KEY_PATH` or use the generated self-signed development certificate. Trust installation is a manual local action.
13
+
14
+ For the Cursor desktop app, the certificate must cover `api2.cursor.sh`. Run `cursorkit desktop-cert`, trust the generated certificate manually, then start with the printed `BRIDGE_CERT_PATH` and `BRIDGE_KEY_PATH` values.
15
+
16
+ ## Streaming Hangs
17
+
18
+ Unknown routes are streamed to upstream. Typed local model routes depend on the OpenAI-compatible backend sending `data:` SSE lines and a `[DONE]` event. Run with `BRIDGE_LOG_LEVEL=debug` and verify the model backend independently.
19
+
20
+ ## Local Model Does Not Appear
21
+
22
+ Run `cursorkit doctor` and confirm `local models` includes the expected ID. The bridge appends conservative local model capabilities and does not advertise tools, images, agent mode, Cmd-K, plan mode, or sandboxing by default.
23
+
24
+ For Cursor Agent CLI, run with `BRIDGE_LOG_LEVEL=debug` and confirm `/aiserver.v1.AiService/GetUsableModels` is intercepted. The CLI model picker is populated from this route; seeing only `/aiserver.v1.AiService/AvailableModels` intercepted is not enough.
25
+
26
+ If `GetUsableModels` is intercepted but the picker still appears empty, decode the response and confirm the local model includes `api_key_credentials.base_url`. Cursor Agent CLI treats this route as a usable model list, not just a display list.
27
+
28
+ Cursor Agent CLI model routes use raw `application/proto` responses. If a local decoder using `application/connect+proto` works but `cursor-agent --list-models` prints no models, check that the bridge is not wrapping raw CLI responses in Connect envelopes.
29
+
30
+ The interactive `/model` picker uses picker metadata from `AvailableModels`, not only the flat model list. Local models need named-picker fields such as `named_model_section_index`, `vendor`, and at least one default non-max variant to show up when filtering in interactive mode.
31
+
32
+ For Cursor desktop app experiments, start with `cursorkit desktop-proxy` and `BRIDGE_LOG_LEVEL=debug`. Confirm the logs contain `desktop route inventory` entries for model and chat routes before adding new interceptors. If the app does not call the same model routes as `cursor-agent`, use the logged route inventory to decode and add typed support from the generated proto.
33
+
34
+ ## Capture Safety
35
+
36
+ Captured traffic can include prompts, paths, cookies, request IDs, and API keys. Do not commit captures unless fixture validation says `redaction.status=sanitized`.