@cozibud/harness 0.1.0 → 0.2.1

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/dist/setup.d.ts CHANGED
@@ -7,6 +7,7 @@ export type SetupCommandResult = {
7
7
  };
8
8
  export type SetupCommandRunner = (command: string, args: string[], options: {
9
9
  interactive: boolean;
10
+ cwd?: string;
10
11
  }) => Promise<SetupCommandResult>;
11
12
  export type SetupWriter = (message: string) => void;
12
13
  export declare const runSetupCommand: SetupCommandRunner;
@@ -23,6 +24,7 @@ export declare function setupProvider(options?: {
23
24
  run?: SetupCommandRunner;
24
25
  write?: SetupWriter;
25
26
  cursorConfig?: CursorMcpConfigStore;
27
+ cursorWorkspace?: string;
26
28
  }): Promise<void>;
27
29
  export declare function setupCodex(options?: {
28
30
  command?: string;
package/dist/setup.js CHANGED
@@ -3,11 +3,13 @@ import { mkdir, readFile, writeFile } from "node:fs/promises";
3
3
  import { homedir } from "node:os";
4
4
  import { dirname, join } from "node:path";
5
5
  import { executable } from "./process-driver.js";
6
+ import { ensureCursorWorkspace } from "./cursor-workspace.js";
6
7
  export const DEFAULT_COZIBUD_MCP_URL = "https://cozibud.com/api/mcp";
7
8
  const MAX_SETUP_OUTPUT_BYTES = 64 * 1024;
8
9
  export const runSetupCommand = async (command, args, options) => await new Promise((resolve) => {
9
10
  const resolved = executable(command);
10
11
  const child = spawn(resolved.command, [...resolved.prefixArgs, ...args], {
12
+ cwd: options.cwd,
11
13
  windowsHide: true,
12
14
  stdio: options.interactive ? "inherit" : ["ignore", "pipe", "pipe"],
13
15
  });
@@ -242,16 +244,22 @@ async function setupCursorProvider(options) {
242
244
  const executable = providerCommand("cursor", options.command);
243
245
  const args = (...values) => [...executable.prefixArgs, ...values];
244
246
  const missing = `Cursor Agent is not installed or is not on PATH. Install it from ${installUrl("cursor")} and run setup again.`;
247
+ const cwd = ensureCursorWorkspace(options.workspace);
248
+ const runInWorkspace = async (values, interactive) => {
249
+ const result = await options.run(executable.command, values, { interactive, cwd: ensureCursorWorkspace(cwd) });
250
+ ensureCursorWorkspace(cwd);
251
+ return result;
252
+ };
245
253
  options.write("Checking Cursor Agent…");
246
- requireSuccess(await options.run(executable.command, args("--version"), { interactive: false }), missing, "Cursor Agent was found but could not be started.");
247
- const login = await options.run(executable.command, args("status"), { interactive: false });
254
+ requireSuccess(await runInWorkspace(args("--version"), false), missing, "Cursor Agent was found but could not be started.");
255
+ const login = await runInWorkspace(args("status"), false);
248
256
  if (!succeeded(login)) {
249
257
  options.write("Opening Cursor sign-in in your browser…");
250
- requireSuccess(await options.run(executable.command, args("login"), { interactive: true }), missing, "Cursor sign-in did not complete.");
258
+ requireSuccess(await runInWorkspace(args("login"), true), missing, "Cursor sign-in did not complete.");
251
259
  }
252
260
  else
253
261
  options.write("Cursor sign-in is ready.");
254
- requireSuccess(await options.run(executable.command, args("status"), { interactive: false }), missing, "Cursor still reports that you are signed out.");
262
+ requireSuccess(await runInWorkspace(args("status"), false), missing, "Cursor still reports that you are signed out.");
255
263
  const currentConfig = await options.config.read();
256
264
  if (cursorConfiguredUrl(currentConfig) !== options.mcpUrl) {
257
265
  options.write("Adding the Cozibud connection to Cursor's user MCP configuration…");
@@ -260,8 +268,8 @@ async function setupCursorProvider(options) {
260
268
  else
261
269
  options.write("The Cozibud connection is configured with the expected endpoint.");
262
270
  options.write("Opening Cozibud sign-in and permission approval in your browser…");
263
- requireSuccess(await options.run(executable.command, args("mcp", "login", "cozibud"), { interactive: true }), missing, "Cozibud sign-in or permission approval did not complete.");
264
- const verified = await options.run(executable.command, args("mcp", "list"), { interactive: false });
271
+ requireSuccess(await runInWorkspace(args("mcp", "login", "cozibud"), true), missing, "Cozibud sign-in or permission approval did not complete.");
272
+ const verified = await runInWorkspace(args("mcp", "list"), false);
265
273
  requireSuccess(verified, missing, "Cursor could not verify the Cozibud MCP connection after sign-in.");
266
274
  if (!cursorReportsConnected(verified.output))
267
275
  throw new Error("Cursor did not report a ready Cozibud MCP connection after sign-in.");
@@ -277,7 +285,7 @@ export async function setupProvider(options = {}) {
277
285
  if (provider === "codex")
278
286
  await setupCodexProvider({ command: options.command, mcpUrl, run, write });
279
287
  else if (provider === "cursor")
280
- await setupCursorProvider({ command: options.command, mcpUrl, run, write, config: options.cursorConfig ?? cursorConfigStore() });
288
+ await setupCursorProvider({ command: options.command, mcpUrl, run, write, config: options.cursorConfig ?? cursorConfigStore(), workspace: options.cursorWorkspace });
281
289
  else
282
290
  await setupInteractiveProvider(provider, { command: options.command, mcpUrl, run, write });
283
291
  }
package/package.json CHANGED
@@ -1,43 +1,43 @@
1
- {
2
- "name": "@cozibud/harness",
3
- "version": "0.1.0",
4
- "description": "Cozibud local-client bridge and CLI.",
5
- "type": "module",
6
- "license": "Apache-2.0",
7
- "repository": {
8
- "type": "git",
9
- "url": "git+https://github.com/rongduan-zhu/cozibud.git",
10
- "directory": "packages/harness"
11
- },
12
- "homepage": "https://github.com/rongduan-zhu/cozibud/tree/main/packages/harness#readme",
13
- "bugs": {
14
- "url": "https://github.com/rongduan-zhu/cozibud/issues"
15
- },
16
- "files": [
17
- "dist"
18
- ],
19
- "publishConfig": {
20
- "access": "public"
21
- },
22
- "engines": {
23
- "node": ">=22"
24
- },
25
- "main": "./dist/index.js",
26
- "types": "./dist/index.d.ts",
27
- "bin": {
28
- "cozibud-harness": "dist/cli.js"
29
- },
30
- "exports": {
31
- ".": {
32
- "types": "./dist/index.d.ts",
33
- "default": "./dist/index.js"
34
- }
35
- },
36
- "scripts": {
37
- "clean": "node -e \"require('node:fs').rmSync('dist', { recursive: true, force: true })\"",
38
- "build": "npm run clean && tsc -p tsconfig.json",
39
- "prepack": "npm run build",
40
- "typecheck": "tsc -p tsconfig.json --noEmit",
41
- "test": "vitest run --root ../.. packages/harness/src"
42
- }
43
- }
1
+ {
2
+ "name": "@cozibud/harness",
3
+ "version": "0.2.1",
4
+ "description": "Cozibud local-client bridge and CLI.",
5
+ "type": "module",
6
+ "license": "Apache-2.0",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/rongduan-zhu/cozibud.git",
10
+ "directory": "packages/harness"
11
+ },
12
+ "homepage": "https://github.com/rongduan-zhu/cozibud/tree/main/packages/harness#readme",
13
+ "bugs": {
14
+ "url": "https://github.com/rongduan-zhu/cozibud/issues"
15
+ },
16
+ "files": [
17
+ "dist"
18
+ ],
19
+ "publishConfig": {
20
+ "access": "public"
21
+ },
22
+ "engines": {
23
+ "node": ">=22"
24
+ },
25
+ "main": "./dist/index.js",
26
+ "types": "./dist/index.d.ts",
27
+ "bin": {
28
+ "cozibud-harness": "dist/cli.js"
29
+ },
30
+ "exports": {
31
+ ".": {
32
+ "types": "./dist/index.d.ts",
33
+ "default": "./dist/index.js"
34
+ }
35
+ },
36
+ "scripts": {
37
+ "clean": "node -e \"require('node:fs').rmSync('dist', { recursive: true, force: true })\"",
38
+ "build": "npm run clean && tsc -p tsconfig.json",
39
+ "prepack": "npm run build",
40
+ "typecheck": "tsc -p tsconfig.json --noEmit",
41
+ "test": "vitest run --root ../.. packages/harness/src"
42
+ }
43
+ }