@cozibud/harness 0.2.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/README.md +6 -0
- package/dist/pairing.js +2 -0
- package/dist/process-driver.js +36 -7
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -28,6 +28,12 @@ child context go to your signed-in Codex client and its model service.
|
|
|
28
28
|
Your Codex login stays local. Pairing credentials are protected with your
|
|
29
29
|
Windows account's DPAPI on Windows, or a user-only file on other systems.
|
|
30
30
|
Disconnect the computer in Cozibud's Watch settings to revoke its access.
|
|
31
|
+
Each Cozibud account can pair two computers. The one connected longest answers
|
|
32
|
+
requests from the web app, the phone app and the watch; the other is a backup
|
|
33
|
+
that takes over when the first stops reporting in. Run `pair` again on a computer
|
|
34
|
+
to replace its pairing, or choose the household and account by signing in to the
|
|
35
|
+
one you want when you approve the link. Codex uses whichever account `codex login`
|
|
36
|
+
signed in (set `CODEX_HOME` to keep a separate Codex profile).
|
|
31
37
|
Use `COZIBUD_RELAY_URL` to choose another HTTPS server before pairing; pairings
|
|
32
38
|
are scoped to that origin. The relay requires no inbound computer port.
|
|
33
39
|
The separate local HTTP adapter must remain on loopback.
|
package/dist/pairing.js
CHANGED
|
@@ -73,6 +73,8 @@ export async function pairRelay(options) {
|
|
|
73
73
|
interval += 5;
|
|
74
74
|
continue;
|
|
75
75
|
}
|
|
76
|
+
if (result.error?.code === "bridge_limit")
|
|
77
|
+
throw new Error("Your account already has two computers paired. Disconnect one in Cozibud under Settings → Assistants & API → Voice with a local agent, then run pair again.");
|
|
76
78
|
throw new Error("Pairing was denied or expired. Run pair again.");
|
|
77
79
|
}
|
|
78
80
|
throw new Error("Pairing expired. Run pair again.");
|
package/dist/process-driver.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { spawn } from "node:child_process";
|
|
2
2
|
import { mkdtemp, rm } from "node:fs/promises";
|
|
3
|
-
import { existsSync } from "node:fs";
|
|
3
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
4
4
|
import { tmpdir } from "node:os";
|
|
5
|
-
import { delimiter, isAbsolute, join } from "node:path";
|
|
5
|
+
import { delimiter, dirname, isAbsolute, join, resolve } from "node:path";
|
|
6
6
|
import { StringDecoder } from "node:string_decoder";
|
|
7
7
|
import { ensureCursorWorkspace } from "./cursor-workspace.js";
|
|
8
8
|
const DEFAULT_TIMEOUT_MS = 120_000;
|
|
@@ -307,17 +307,46 @@ export function executable(configured) {
|
|
|
307
307
|
for (const directory of directories) {
|
|
308
308
|
const base = directory ? join(directory, configured) : configured;
|
|
309
309
|
const script = /\.ps1$/i.test(base) ? base : `${base}.ps1`;
|
|
310
|
-
if (existsSync(script))
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
310
|
+
if (!existsSync(script))
|
|
311
|
+
continue;
|
|
312
|
+
const shimmed = nodeShimTarget(script);
|
|
313
|
+
if (shimmed)
|
|
314
|
+
return shimmed;
|
|
315
|
+
return {
|
|
316
|
+
command: join(process.env.SystemRoot ?? "C:\\Windows", "System32", "WindowsPowerShell", "v1.0", "powershell.exe"),
|
|
317
|
+
prefixArgs: ["-NoLogo", "-NoProfile", "-File", script],
|
|
318
|
+
};
|
|
315
319
|
}
|
|
316
320
|
}
|
|
317
321
|
return /\.(?:c|m)?js$/i.test(configured)
|
|
318
322
|
? { command: process.execPath, prefixArgs: [configured] }
|
|
319
323
|
: { command: configured, prefixArgs: [] };
|
|
320
324
|
}
|
|
325
|
+
/**
|
|
326
|
+
* npm, pnpm and Yarn install a CLI on Windows as a PowerShell shim that runs a JavaScript entry point
|
|
327
|
+
* with Node. Running that entry point directly keeps arguments intact: `powershell -File` treats a bare
|
|
328
|
+
* `-` (read the prompt from stdin) as an unnamed parameter and fails before the CLI starts.
|
|
329
|
+
*/
|
|
330
|
+
function nodeShimTarget(script) {
|
|
331
|
+
let source;
|
|
332
|
+
try {
|
|
333
|
+
source = readFileSync(script, "utf8");
|
|
334
|
+
}
|
|
335
|
+
catch {
|
|
336
|
+
return null;
|
|
337
|
+
}
|
|
338
|
+
if (source.length > 16_384)
|
|
339
|
+
return null;
|
|
340
|
+
const target = /"\$basedir[\\/]([^"$`]+\.[cm]?js)"/i.exec(source)?.[1];
|
|
341
|
+
if (!target)
|
|
342
|
+
return null;
|
|
343
|
+
const basedir = dirname(script);
|
|
344
|
+
const entry = resolve(basedir, target);
|
|
345
|
+
if (!existsSync(entry))
|
|
346
|
+
return null;
|
|
347
|
+
const bundledNode = join(basedir, "node.exe");
|
|
348
|
+
return { command: existsSync(bundledNode) ? bundledNode : process.execPath, prefixArgs: [entry] };
|
|
349
|
+
}
|
|
321
350
|
const codexExecutable = executable(process.env.COZIBUD_CODEX_PATH || "codex");
|
|
322
351
|
const claudeExecutable = executable(process.env.COZIBUD_CLAUDE_PATH || "claude");
|
|
323
352
|
const geminiExecutable = executable(process.env.COZIBUD_GEMINI_PATH || "gemini");
|