ocx-cursor 0.5.2 → 1.0.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.
package/README.md CHANGED
@@ -3,16 +3,29 @@
3
3
  [![npm version](https://img.shields.io/npm/v/ocx-cursor.svg)](https://www.npmjs.com/package/ocx-cursor)
4
4
  [![CI](https://github.com/hiddenest/opencodex-cursor-bridge/actions/workflows/ci.yml/badge.svg)](https://github.com/hiddenest/opencodex-cursor-bridge/actions/workflows/ci.yml)
5
5
 
6
- Use your active [OpenCodex](https://github.com/lidge-jun/opencodex) models in Cursor through a local OpenAI-compatible gateway.
6
+ Use your active [OpenCodex](https://github.com/lidge-jun/opencodex) models in Cursor through an authenticated HTTPS endpoint on your Mac.
7
7
 
8
8
  > [!WARNING]
9
- > This package edits private JavaScript files inside `Cursor.app`. The changes invalidate Cursor's vendor signature, so Cursor may report that the installation is corrupt. The installer saves original files under `~/.opencodex/cursor-bridge/cursor-app-backups`. Reinstall Cursor to restore a signed app.
9
+ > The installer edits two private workbench files inside `Cursor.app`. This invalidates Cursor's vendor signature. Cursor may report a corrupt installation. The bridge saves the original files under `~/.opencodex/cursor-bridge/cursor-app-backups`. Reinstall Cursor to restore a signed app.
10
10
 
11
- ## Quick start
11
+ ## Requirements
12
12
 
13
- You need macOS, Node.js 22.5 or newer, and Cursor at `/Applications/Cursor.app`.
13
+ - macOS with Cursor installed at `/Applications/Cursor.app`
14
+ - Node.js 22.5 or newer
15
+ - OpenCodex with at least one active model
16
+ - An HTTPS hostname that forwards to `http://127.0.0.1:10101`
14
17
 
15
- Install and configure OpenCodex:
18
+ Use [Cloudflare Tunnel](https://developers.cloudflare.com/tunnel/) for the HTTPS hostname, or choose another reverse proxy that preserves the `Authorization` header.
19
+
20
+ ## Upgrading from 0.5.x
21
+
22
+ Version 0.5.x enabled Cursor's local-agent mode and edited ten app files. Version 1.0.0 edits two workbench files and leaves local-agent mode disabled.
23
+
24
+ Reinstall Cursor before upgrading so macOS replaces the old app files. Quit the new Cursor installation, then follow the setup below. Your Cursor settings remain under `~/Library/Application Support/Cursor`.
25
+
26
+ ## Getting started
27
+
28
+ Install OpenCodex and start its login service:
16
29
 
17
30
  ```bash
18
31
  npm install --global @bitkyc08/opencodex
@@ -21,98 +34,142 @@ ocx service install
21
34
  ocx service status
22
35
  ```
23
36
 
24
- Check the configured models:
37
+ OpenCodex listens on `http://127.0.0.1:10100`. Check its active models:
25
38
 
26
39
  ```bash
27
40
  ocx models --json
28
41
  ```
29
42
 
30
- Launch Cursor and sign in once, then quit it. Run the bridge installer:
43
+ Install `cloudflared`, sign in, and create a named tunnel:
31
44
 
32
45
  ```bash
33
- npx ocx-cursor init
34
- ~/.local/bin/ocx-cursor status
46
+ brew install cloudflared
47
+ cloudflared tunnel login
48
+ cloudflared tunnel create ocx-cursor
49
+ cloudflared tunnel list
50
+ ```
51
+
52
+ Create `~/.cloudflared/config.yml`. Replace the UUID, username, and hostname:
53
+
54
+ ```yaml
55
+ tunnel: YOUR_TUNNEL_UUID
56
+ credentials-file: /Users/YOUR_USERNAME/.cloudflared/YOUR_TUNNEL_UUID.json
57
+
58
+ ingress:
59
+ - hostname: cursor-api.example.com
60
+ service: http://127.0.0.1:10101
61
+ - service: http_status:404
35
62
  ```
36
63
 
37
- `init` registers `http://127.0.0.1:10101/v1` in Cursor. You do not need a domain or tunnel. Open Cursor after the status command reports `Service: running` and `Gateway: healthy`.
64
+ Create the DNS record and check the ingress rule:
38
65
 
39
- Add the installed command to your shell path if needed:
66
+ ```bash
67
+ cloudflared tunnel route dns ocx-cursor cursor-api.example.com
68
+ cloudflared tunnel ingress validate
69
+ cloudflared tunnel ingress rule https://cursor-api.example.com
70
+ ```
71
+
72
+ Start the tunnel at login with Cloudflare's [macOS service command](https://developers.cloudflare.com/tunnel/advanced/local-management/as-a-service/macos/):
40
73
 
41
74
  ```bash
42
- export PATH="$HOME/.local/bin:$PATH"
75
+ cloudflared service install
43
76
  ```
44
77
 
45
- ## What init changes
78
+ This command reads `~/.cloudflared/config.yml`. `sudo cloudflared service install` starts the tunnel at boot and reads `/etc/cloudflared/config.yml` instead.
46
79
 
47
- | Area | Change |
48
- | --- | --- |
49
- | Cursor settings | Stores the gateway key with macOS Safe Storage and sets the local base URL. |
50
- | Cursor model state | Adds active models under `opencodex/*` with names, effort choices, and Fast metadata. |
51
- | `Cursor.app` | Enables local-agent mode in eight bundles and patches two local-agent runtimes. |
52
- | Login service | Installs `com.opencodex.cursor-bridge`, refreshes models, and reapplies patches after Cursor updates. |
80
+ Launch Cursor once and sign in, then quit it. Install the bridge:
53
81
 
54
- Requests stay on loopback until OpenCodex sends them to your configured provider:
82
+ ```bash
83
+ npx ocx-cursor init --base-url https://cursor-api.example.com/v1
84
+ ~/.local/bin/ocx-cursor status
85
+ ```
86
+
87
+ Open Cursor after `status` reports a running service and a healthy gateway.
88
+
89
+ ## How requests move
55
90
 
56
91
  ```text
57
- Cursor -> 127.0.0.1:10101 -> OpenCodex on 127.0.0.1:10100 -> provider
92
+ Cursor
93
+ -> https://cursor-api.example.com/v1
94
+ -> Cloudflare Tunnel
95
+ -> OpenCodex Cursor Bridge on 127.0.0.1:10101
96
+ -> OpenCodex on 127.0.0.1:10100
97
+ -> your provider
58
98
  ```
59
99
 
60
- The gateway requires its generated bearer token on every `/v1/*` request. It binds to `127.0.0.1` unless you change `OCX_CURSOR_HOST`.
100
+ The bridge generates a bearer token during `init`, stores it in Cursor with macOS Safe Storage, and checks it on each `/v1/*` request. The gateway binds to `127.0.0.1` unless you set `OCX_CURSOR_HOST`.
61
101
 
62
- Active OpenCodex `cursor/*` models are exposed under `opencodex/cursor/*`. The provider is experimental; the bridge cancels its upstream request when Cursor ends the matching client request.
102
+ The package does not create, edit, or remove your Cloudflare Tunnel.
63
103
 
64
- ## Model behavior
104
+ ## Models and Cursor metadata
65
105
 
66
- The bridge reads OpenCodex's active `/v1/models` response and creates stable Cursor aliases:
106
+ The bridge reads the active OpenCodex catalog and adds stable aliases to Cursor:
67
107
 
68
108
  ```text
69
109
  anthropic/claude-sonnet-5 -> opencodex/claude-sonnet-5
70
110
  gpt-5.6-sol -> opencodex/gpt-5.6-sol
71
111
  ```
72
112
 
73
- Cursor shows readable names such as `GPT 5.6 Sol`. Reasoning models receive an effort selector. Models with OpenCodex's `priority` service tier receive a Fast toggle.
113
+ Cursor displays provider prefixes where model names overlap. Examples include `Cursor Kimi K3` and `OpenCode Go Kimi K3`. Claude and GPT names stay short.
114
+
115
+ Reasoning models receive an effort selector. Models that advertise OpenCodex's `priority` service tier receive a Fast toggle. The gateway maps those choices to `reasoning_effort` and `service_tier: priority`.
116
+
117
+ The installer patches these files:
118
+
119
+ ```text
120
+ /Applications/Cursor.app/Contents/Resources/app/out/vs/workbench/workbench.desktop.main.js
121
+ /Applications/Cursor.app/Contents/Resources/app/out/vs/workbench/workbench.glass.main.js
122
+ ```
123
+
124
+ The patch keeps the model metadata that Cursor would discard. It leaves Cursor's local-agent mode disabled and does not edit either local-agent runtime.
74
125
 
75
- Cursor can send `strict: true` with function schemas that fail strict validation. The gateway changes the flag to `false` before forwarding those requests. It leaves tool names, descriptions, and arguments intact.
126
+ The login service refreshes the catalog every 15 seconds. It waits for Cursor to quit before writing the state database or reapplying a patch after a Cursor update.
76
127
 
77
- ## Commands and configuration
128
+ ## Commands
78
129
 
79
- | Command | Purpose |
130
+ | Command | Action |
80
131
  | --- | --- |
81
- | `ocx-cursor init` | Install the service, configure Cursor, patch the app, and sync models. Cursor must be closed. |
82
- | `ocx-cursor install` | Reinstall the service and check app patches. Running Cursor defers app changes until exit. |
83
- | `ocx-cursor update` | Install the newest npm release and run `install`. |
84
- | `ocx-cursor sync` | Refresh the active model list. |
85
- | `ocx-cursor status` | Show service health and pending model sync. |
132
+ | `ocx-cursor init --base-url URL` | Install the service, test the HTTPS endpoint, configure Cursor, and sync models. |
133
+ | `ocx-cursor install` | Reinstall the service and check the two metadata patches. |
134
+ | `ocx-cursor update` | Install the current npm release and restart the service. |
135
+ | `ocx-cursor sync` | Read the active OpenCodex catalog and update Cursor. |
136
+ | `ocx-cursor status` | Print service, gateway, catalog, and pending-sync status. |
86
137
  | `ocx-cursor uninstall` | Remove the service, command link, and bridge state. |
87
138
 
88
- `uninstall` does not restore Cursor settings or patched app files. Reinstall Cursor if you want a clean vendor build.
139
+ `uninstall` leaves Cursor's endpoint setting and patched workbench files in place. Reinstall Cursor if you want a signed app without the metadata patch.
140
+
141
+ ## Configuration
89
142
 
90
143
  | Variable | Default |
91
144
  | --- | --- |
92
- | `OCX_CURSOR_BASE_URL` | `http://127.0.0.1:10101/v1` |
145
+ | `OCX_CURSOR_BASE_URL` | Cursor's stored endpoint |
93
146
  | `OCX_CURSOR_HOME` | `~/.opencodex/cursor-bridge` |
94
147
  | `OCX_CURSOR_HOST` | `127.0.0.1` |
95
148
  | `OCX_CURSOR_PORT` | `10101` |
96
149
  | `OCX_BIN` | `~/.local/bin/ocx` |
97
150
 
98
- The bridge reads an OpenCodex service token from `~/.opencodex/service-api-token` when that file exists.
151
+ The gateway exposes `GET /v1/models`, `POST /v1/chat/completions`, `POST /v1/responses`, `POST /v1/responses/compact`, and `POST /v1/messages`.
152
+
153
+ The bridge reads `~/.opencodex/service-api-token` when OpenCodex uses service authentication.
99
154
 
100
155
  ## Troubleshooting
101
156
 
102
- | Symptom | Fix |
157
+ | Symptom | Check |
103
158
  | --- | --- |
104
- | Cursor returns 401 | Quit Cursor and rerun `npx ocx-cursor init`. |
105
- | Models or effort choices are missing | Quit Cursor, run `ocx-cursor sync`, then check `ocx-cursor status`. |
106
- | A Cursor update removed the patches | Quit Cursor and run `ocx-cursor install`. |
107
- | The gateway is unavailable | Run `ocx-cursor status` and inspect the logs below. |
108
- | The bridge cannot find `ocx` | Run `ln -sf "$(command -v ocx)" ~/.local/bin/ocx`. |
159
+ | Cursor returns 401 | Quit Cursor and rerun `npx ocx-cursor init --base-url https://YOUR_HOST/v1`. |
160
+ | The hostname returns 502 | Run `ocx-cursor status`, then check that the tunnel points to port `10101`. |
161
+ | Cloudflare returns 1016 | Run `cloudflared tunnel info ocx-cursor` and check the service. |
162
+ | Models or controls are missing | Quit Cursor and run `ocx-cursor sync`. |
163
+ | A Cursor update removed the patch | Quit Cursor and run `ocx-cursor install`. |
164
+
165
+ Read the service logs:
109
166
 
110
167
  ```bash
111
168
  tail -n 100 ~/.opencodex/cursor-bridge/service.log
112
169
  tail -n 100 ~/.opencodex/cursor-bridge/service.error.log
113
170
  ```
114
171
 
115
- The patcher stops when a Cursor update no longer matches its known code structure. It reports the file and mismatch in `service.error.log` without replacing that file.
172
+ The patcher stops if a Cursor update removes its known catalog hook. It records the file and error without replacing that file.
116
173
 
117
174
  ## Development
118
175
 
@@ -2,10 +2,11 @@
2
2
 
3
3
  import { readFile } from "node:fs/promises";
4
4
  import process from "node:process";
5
- import { configureCursorOpenAI } from "../src/cursor-config.mjs";
5
+ import { createInterface } from "node:readline/promises";
6
+ import { configureCursorOpenAI, storedCursorOpenAIBaseUrl } from "../src/cursor-config.mjs";
6
7
  import { cursorIsRunning } from "../src/cursor-state.mjs";
7
8
  import { installService, prepareInstallSecret, serviceStatus, uninstallService, updateService } from "../src/install.mjs";
8
- import { cursorLocalBaseUrl, cursorOpenAIBaseUrl, pendingFile } from "../src/paths.mjs";
9
+ import { cursorOpenAIBaseUrl, pendingFile } from "../src/paths.mjs";
9
10
  import { runService } from "../src/service.mjs";
10
11
  import { normalizeBaseUrl, testEndpoint } from "../src/setup.mjs";
11
12
  import { loadCatalogSnapshot, syncNow } from "../src/sync.mjs";
@@ -36,7 +37,19 @@ function argumentValue(name) {
36
37
 
37
38
  async function requestedBaseUrl() {
38
39
  const supplied = argumentValue("--base-url");
39
- return normalizeBaseUrl(supplied || cursorOpenAIBaseUrl || cursorLocalBaseUrl);
40
+ const fallback = cursorOpenAIBaseUrl || storedCursorOpenAIBaseUrl();
41
+ if (supplied) return normalizeBaseUrl(supplied);
42
+ if (!process.stdin.isTTY || !process.stdout.isTTY) return normalizeBaseUrl(fallback);
43
+
44
+ const prompt = fallback
45
+ ? `HTTPS endpoint [${fallback}]: `
46
+ : "HTTPS endpoint (for example, https://cursor-api.example.com): ";
47
+ const readline = createInterface({ input: process.stdin, output: process.stdout });
48
+ try {
49
+ return normalizeBaseUrl((await readline.question(prompt)).trim() || fallback);
50
+ } finally {
51
+ readline.close();
52
+ }
40
53
  }
41
54
 
42
55
  async function pendingCount() {
@@ -63,7 +76,7 @@ function printCursorPatches(result) {
63
76
  return;
64
77
  }
65
78
  const changed = result.cursorPatches.filter(({ status }) => status === "patched").length;
66
- process.stdout.write(`Verified ${result.cursorPatches.length} Cursor app patches (${changed} changed).\n`);
79
+ process.stdout.write(`Verified ${result.cursorPatches.length} Cursor metadata patches (${changed} changed).\n`);
67
80
  }
68
81
 
69
82
  async function main() {
@@ -83,7 +96,7 @@ async function main() {
83
96
  process.stdout.write(`Installed ${installed.launchAgentFile} (API key ${installed.secretStatus}).\nCLI: ${installed.cliLinkFile}\n`);
84
97
  printCursorPatches(installed);
85
98
  printSync(await syncNow());
86
- process.stdout.write("Endpoint: http://127.0.0.1:10101/v1\n");
99
+ process.stdout.write("Local gateway: http://127.0.0.1:10101/v1\n");
87
100
  return;
88
101
  }
89
102
  if (command === "init") {
@@ -100,7 +113,7 @@ async function main() {
100
113
  try {
101
114
  endpoint = await testEndpoint(baseUrl, prepared.secret);
102
115
  } catch (error) {
103
- throw new Error(`${error.message}\nThe bridge service is running locally. Fix the endpoint and rerun ocx-cursor init.`);
116
+ throw new Error(`${error.message}\nThe bridge service is running locally. Fix the HTTPS endpoint and rerun ocx-cursor init.`);
104
117
  }
105
118
  process.stdout.write(`Endpoint is ready (${endpoint.modelCount} models reachable).\n`);
106
119
  const configured = await configureCursorOpenAI({
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "ocx-cursor",
3
- "version": "0.5.2",
4
- "description": "OpenCodex companion service for Cursor custom models",
3
+ "version": "1.0.0",
4
+ "description": "Use OpenCodex models in Cursor through an authenticated HTTPS gateway",
5
5
  "keywords": [
6
6
  "opencodex",
7
7
  "cursor",
@@ -5,6 +5,7 @@ import {
5
5
  cursorBundleFiles,
6
6
  cursorGlassWorkbenchFile,
7
7
  cursorLocalRuntimeFiles,
8
+ cursorModelMetadataFiles,
8
9
  cursorPatchBackupDirectory,
9
10
  cursorWorkbenchFile,
10
11
  } from "./paths.mjs";
@@ -229,6 +230,13 @@ export async function ensureCursorWorkbenchPatched(options = {}) {
229
230
  return await writePatchedFile(file, source, patched, backupDirectory);
230
231
  }
231
232
 
233
+ export async function ensureCursorModelMetadataPatched(options = {}) {
234
+ const file = options.file || cursorWorkbenchFile;
235
+ const backupDirectory = options.backupDirectory || cursorPatchBackupDirectory;
236
+ const source = await readFile(file, "utf8");
237
+ return await writePatchedFile(file, source, patchCursorWorkbenchSource(source), backupDirectory);
238
+ }
239
+
232
240
  export async function ensureCursorLocalRuntimesPatched(options = {}) {
233
241
  const files = options.files || cursorLocalRuntimeFiles;
234
242
  const backupDirectory = options.backupDirectory || cursorPatchBackupDirectory;
@@ -268,6 +276,12 @@ export async function ensureCursorAppPatched(options = {}) {
268
276
  }
269
277
 
270
278
  async function ensureCursorPatchFile(file, localRuntimeFiles, options) {
279
+ if (options.metadataOnly) {
280
+ return {
281
+ file,
282
+ ...await ensureCursorModelMetadataPatched({ ...options, file }),
283
+ };
284
+ }
271
285
  if (localRuntimeFiles.has(file)) {
272
286
  const [result] = await ensureCursorLocalRuntimesPatched({
273
287
  ...options,
@@ -285,6 +299,15 @@ async function ensureCursorPatchFile(file, localRuntimeFiles, options) {
285
299
  };
286
300
  }
287
301
 
302
+ export function startCursorModelMetadataPatchMonitor(options = {}) {
303
+ return startCursorPatchMonitor({
304
+ ...options,
305
+ bundleFiles: options.bundleFiles || cursorModelMetadataFiles,
306
+ localRuntimeFiles: [],
307
+ metadataOnly: true,
308
+ });
309
+ }
310
+
288
311
  export function startCursorPatchMonitor(options = {}) {
289
312
  const intervalMs = options.intervalMs || 250;
290
313
  const bundleFiles = options.file ? [options.file] : (options.bundleFiles || options.files || cursorBundleFiles);
@@ -29,6 +29,11 @@ const displayWords = new Map([
29
29
  ["spark", "Spark"],
30
30
  ["terra", "Terra"],
31
31
  ]);
32
+ const providerDisplayNames = new Map([
33
+ ["cursor", "Cursor"],
34
+ ["opencode-go", "OpenCode Go"],
35
+ ]);
36
+ const unprefixedProviders = new Set(["anthropic", "openai"]);
32
37
 
33
38
  function displayWord(value) {
34
39
  const known = displayWords.get(value);
@@ -42,8 +47,11 @@ function displayWord(value) {
42
47
  }
43
48
 
44
49
  export function displayNameFor(model) {
50
+ const provider = model.provider || (model.sourceId.includes("/") ? model.sourceId.split("/", 1)[0] : "openai");
51
+ const providerDisplayName = providerDisplayNames.get(provider)
52
+ || provider.split(/[-_]/).map(displayWord).join(" ");
45
53
  const displayName = model.sourceId.split("/").at(-1).split("-").map(displayWord).join(" ");
46
- return model.provider === "cursor" || model.sourceId.startsWith("cursor/") ? `Cursor ${displayName}` : displayName;
54
+ return unprefixedProviders.has(provider) ? displayName : `${providerDisplayName} ${displayName}`;
47
55
  }
48
56
 
49
57
  export function cursorIsRunning() {
package/src/install.mjs CHANGED
@@ -4,7 +4,7 @@ import { access, chmod, copyFile, cp, lstat, mkdir, mkdtemp, readFile, readlink,
4
4
  import { tmpdir } from "node:os";
5
5
  import { dirname, join, relative, resolve, sep } from "node:path";
6
6
  import { fileURLToPath } from "node:url";
7
- import { ensureCursorAppPatched } from "./cursor-patch.mjs";
7
+ import { ensureCursorModelMetadataPatched } from "./cursor-patch.mjs";
8
8
  import { cursorIsRunning } from "./cursor-state.mjs";
9
9
  import {
10
10
  cliLinkFile,
@@ -13,6 +13,7 @@ import {
13
13
  launchAgentFile,
14
14
  legacyLaunchAgentFile,
15
15
  legacyServiceLabel,
16
+ cursorModelMetadataFiles,
16
17
  secretFile,
17
18
  serviceLabel,
18
19
  stderrFile,
@@ -167,7 +168,12 @@ function launchAgent(nodePath) {
167
168
  export async function installService() {
168
169
  await mkdir(dirname(launchAgentFile), { recursive: true });
169
170
  const { legacyPlist, secretStatus } = await prepareInstallSecret();
170
- const cursorPatches = cursorIsRunning() ? null : await ensureCursorAppPatched();
171
+ const cursorPatches = cursorIsRunning()
172
+ ? null
173
+ : await Promise.all(cursorModelMetadataFiles.map(async (file) => ({
174
+ file,
175
+ ...await ensureCursorModelMetadataPatched({ file }),
176
+ })));
171
177
  await copyPackage();
172
178
  await installCliLink();
173
179
 
package/src/paths.mjs CHANGED
@@ -17,6 +17,7 @@ export const cursorDatabaseFile = join(homedir(), "Library", "Application Suppor
17
17
  export const cursorAppOutDirectory = "/Applications/Cursor.app/Contents/Resources/app/out";
18
18
  export const cursorWorkbenchFile = join(cursorAppOutDirectory, "vs", "workbench", "workbench.desktop.main.js");
19
19
  export const cursorGlassWorkbenchFile = join(cursorAppOutDirectory, "vs", "workbench", "workbench.glass.main.js");
20
+ export const cursorModelMetadataFiles = [cursorWorkbenchFile, cursorGlassWorkbenchFile];
20
21
  export const cursorLocalRuntimeFiles = [
21
22
  "/Applications/Cursor.app/Contents/Resources/app/extensions/cursor-local-agent-runtime/dist/main.js",
22
23
  "/Applications/Cursor.app/Contents/Resources/app/extensions/cursor-agent-exec/dist/main.js",
@@ -39,6 +40,5 @@ export const opencodexConfigFile = join(homedir(), ".opencodex", "config.json");
39
40
  export const opencodexServiceTokenFile = join(homedir(), ".opencodex", "service-api-token");
40
41
  export const gatewayPort = Number(process.env.OCX_CURSOR_PORT || "10101");
41
42
  export const gatewayHost = process.env.OCX_CURSOR_HOST || "127.0.0.1";
42
- export const cursorLocalBaseUrl = `http://127.0.0.1:${gatewayPort}/v1`;
43
43
  export const cursorOpenAIBaseUrl = process.env.OCX_CURSOR_BASE_URL || "";
44
44
  export const managedPrefix = "opencodex/";
package/src/service.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  import { randomBytes } from "node:crypto";
2
2
  import { chmod, mkdir, readFile, writeFile } from "node:fs/promises";
3
3
  import { buildActiveCatalog } from "./catalog.mjs";
4
- import { startCursorPatchMonitor } from "./cursor-patch.mjs";
4
+ import { startCursorModelMetadataPatchMonitor } from "./cursor-patch.mjs";
5
5
  import {
6
6
  cursorIsRunning,
7
7
  readPendingCatalog,
@@ -59,7 +59,7 @@ export async function runService(options = {}) {
59
59
  }
60
60
 
61
61
  const server = startGateway({ secret, getCatalog: () => catalog, host: options.host, port: options.port });
62
- const patchMonitor = startCursorPatchMonitor({
62
+ const patchMonitor = startCursorModelMetadataPatchMonitor({
63
63
  intervalMs: options.cursorPatchIntervalMs,
64
64
  shouldPatch: () => !cursorIsRunning(),
65
65
  onResult: (result) => {
package/src/setup.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  export function normalizeBaseUrl(value) {
2
2
  if (!value) {
3
- throw new Error("Enter an endpoint URL or pass --base-url http://127.0.0.1:10101/v1");
3
+ throw new Error("Enter an HTTPS endpoint or pass --base-url https://cursor-api.example.com/v1");
4
4
  }
5
5
 
6
6
  const trimmed = value.trim();