@paigy/harness 0.2.0 → 0.2.2
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/cli.js +37 -8
- package/dist/main.js +37 -8
- package/package.json +13 -13
package/dist/cli.js
CHANGED
|
@@ -31967,7 +31967,7 @@ var clip = (s) => (s.length > 120 ? `${s.slice(0, 117)}\u2026` : s) || "(no text
|
|
|
31967
31967
|
import { spawn } from "child_process";
|
|
31968
31968
|
import { existsSync as existsSync3 } from "fs";
|
|
31969
31969
|
import { homedir as homedir3 } from "os";
|
|
31970
|
-
import { resolve, delimiter } from "path";
|
|
31970
|
+
import { dirname, resolve, delimiter } from "path";
|
|
31971
31971
|
|
|
31972
31972
|
// src/harness/acp.ts
|
|
31973
31973
|
var none = { events: [], writes: [] };
|
|
@@ -32194,9 +32194,15 @@ function startSession(opts) {
|
|
|
32194
32194
|
}
|
|
32195
32195
|
const child = (opts.spawnFn ?? spawn)(opts.bin ?? ADAPTER_BIN[opts.harness], [], {
|
|
32196
32196
|
cwd,
|
|
32197
|
-
// The adapter shells out to its vendor CLI (`claude`, `codex`), and a GUI-
|
|
32198
|
-
//
|
|
32199
|
-
|
|
32197
|
+
// The adapter shells out to its vendor CLI (`claude`, `codex`), and a GUI- or
|
|
32198
|
+
// launchd-launched process's PATH won't have it — probe dirs plus the RUNNING
|
|
32199
|
+
// node's own bin dir (nvm installs the adapters next to node; launchd's bare
|
|
32200
|
+
// PATH knows neither — live catch 2026-08-04: the first slot-wake ENOENT'd).
|
|
32201
|
+
env: {
|
|
32202
|
+
...process.env,
|
|
32203
|
+
PATH: [process.env.PATH, dirname(process.execPath), ...probeDirs()].filter(Boolean).join(delimiter),
|
|
32204
|
+
...opts.token ? { PAIGY_TOKEN: opts.token } : {}
|
|
32205
|
+
},
|
|
32200
32206
|
stdio: ["pipe", "pipe", "pipe"]
|
|
32201
32207
|
});
|
|
32202
32208
|
const write = (frames) => {
|
|
@@ -32209,8 +32215,12 @@ function startSession(opts) {
|
|
|
32209
32215
|
});
|
|
32210
32216
|
child.on("exit", (code) => {
|
|
32211
32217
|
opts.onEvent({ kind: "idle", failed: code !== 0, ...code ? { result: `exited ${code}` } : {} });
|
|
32218
|
+
opts.onExit?.();
|
|
32219
|
+
});
|
|
32220
|
+
child.on("error", (e) => {
|
|
32221
|
+
opts.onEvent({ kind: "error", message: e.message });
|
|
32222
|
+
opts.onExit?.();
|
|
32212
32223
|
});
|
|
32213
|
-
child.on("error", (e) => opts.onEvent({ kind: "error", message: e.message }));
|
|
32214
32224
|
const driver = createAcpDriver({ cwd, mode: opts.mode, ...opts.mcp ? { mcp: opts.mcp } : {} });
|
|
32215
32225
|
let buffer = "";
|
|
32216
32226
|
child.stdout?.on("data", (chunk) => {
|
|
@@ -32293,7 +32303,9 @@ function runHarness(opts) {
|
|
|
32293
32303
|
cwd: opts.cwd,
|
|
32294
32304
|
mode: opts.mode,
|
|
32295
32305
|
...paigyMcp ? { mcp: paigyMcp } : {},
|
|
32306
|
+
...opts.token ? { token: opts.token } : {},
|
|
32296
32307
|
...opts.bin ? { bin: opts.bin } : {},
|
|
32308
|
+
...opts.onExit ? { onExit: opts.onExit } : {},
|
|
32297
32309
|
onEvent: (event) => void handle(event).catch((err) => opts.log(`\u26A0 ${err.message}`))
|
|
32298
32310
|
});
|
|
32299
32311
|
if (opts.prompt) session.send(opts.prompt);
|
|
@@ -32317,7 +32329,7 @@ function runHarness(opts) {
|
|
|
32317
32329
|
|
|
32318
32330
|
// src/workspaces.ts
|
|
32319
32331
|
import { existsSync as existsSync4, mkdirSync as mkdirSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "fs";
|
|
32320
|
-
import { dirname, join as join3, resolve as resolve2 } from "path";
|
|
32332
|
+
import { dirname as dirname2, join as join3, resolve as resolve2 } from "path";
|
|
32321
32333
|
import { homedir as homedir4 } from "os";
|
|
32322
32334
|
function workspacesFile() {
|
|
32323
32335
|
return join3(homedir4(), ".paigy", "workspaces.json");
|
|
@@ -32335,7 +32347,7 @@ function addWorkspace(dir, deps) {
|
|
|
32335
32347
|
const all = listWorkspaces(deps);
|
|
32336
32348
|
if (!all.includes(next)) {
|
|
32337
32349
|
all.push(next);
|
|
32338
|
-
mkdirSync2(
|
|
32350
|
+
mkdirSync2(dirname2(deps.file), { recursive: true });
|
|
32339
32351
|
writeFileSync2(deps.file, JSON.stringify(all, null, 2));
|
|
32340
32352
|
}
|
|
32341
32353
|
return all;
|
|
@@ -32364,6 +32376,10 @@ function startHost(opts) {
|
|
|
32364
32376
|
prompt: spec.prompt ?? "",
|
|
32365
32377
|
exclusive: true,
|
|
32366
32378
|
token: spec.token,
|
|
32379
|
+
onExit: () => {
|
|
32380
|
+
runs.delete(spec.sessionId);
|
|
32381
|
+
opts.log(`\u2716 ${label} ended`);
|
|
32382
|
+
},
|
|
32367
32383
|
log
|
|
32368
32384
|
});
|
|
32369
32385
|
runs.set(spec.sessionId, { run, label });
|
|
@@ -32383,7 +32399,20 @@ function startHost(opts) {
|
|
|
32383
32399
|
const work = await checkReplies({ token }).catch(() => null);
|
|
32384
32400
|
if (!work || work.requests.length === 0 && work.replies.length === 0) continue;
|
|
32385
32401
|
const log = (line) => opts.log(`[${slot}] ${line}`);
|
|
32386
|
-
const run = runHarness({
|
|
32402
|
+
const run = runHarness({
|
|
32403
|
+
harness,
|
|
32404
|
+
cwd: workspace,
|
|
32405
|
+
mode: "bypass",
|
|
32406
|
+
prompt: "",
|
|
32407
|
+
exclusive: true,
|
|
32408
|
+
token,
|
|
32409
|
+
// A dead run must not squat the slot — evict so the next wake can respawn.
|
|
32410
|
+
onExit: () => {
|
|
32411
|
+
runs.delete(key);
|
|
32412
|
+
opts.log(`\u2716 ${slot} ended`);
|
|
32413
|
+
},
|
|
32414
|
+
log
|
|
32415
|
+
});
|
|
32387
32416
|
runs.set(key, { run, label: slot });
|
|
32388
32417
|
opts.log(`\u25B6 woke ${slot} (${harness}) \u2014 work was waiting in ${workspace}`);
|
|
32389
32418
|
}
|
package/dist/main.js
CHANGED
|
@@ -4577,7 +4577,7 @@ var require_lib = __commonJS({
|
|
|
4577
4577
|
import { app, BrowserWindow, dialog, ipcMain } from "electron";
|
|
4578
4578
|
import { spawn as spawn2 } from "child_process";
|
|
4579
4579
|
import { fileURLToPath } from "url";
|
|
4580
|
-
import { dirname as
|
|
4580
|
+
import { dirname as dirname3, join as join4 } from "path";
|
|
4581
4581
|
|
|
4582
4582
|
// ../../packages/sdk/dist/index.js
|
|
4583
4583
|
import { createRequire as __sdkCreateRequire } from "module";
|
|
@@ -12380,7 +12380,7 @@ function removeWorkspace(dir, deps) {
|
|
|
12380
12380
|
import { spawn } from "child_process";
|
|
12381
12381
|
import { existsSync as existsSync4 } from "fs";
|
|
12382
12382
|
import { homedir as homedir4 } from "os";
|
|
12383
|
-
import { resolve as resolve2, delimiter } from "path";
|
|
12383
|
+
import { dirname as dirname2, resolve as resolve2, delimiter } from "path";
|
|
12384
12384
|
|
|
12385
12385
|
// src/harness/acp.ts
|
|
12386
12386
|
var none = { events: [], writes: [] };
|
|
@@ -12607,9 +12607,15 @@ function startSession(opts) {
|
|
|
12607
12607
|
}
|
|
12608
12608
|
const child = (opts.spawnFn ?? spawn)(opts.bin ?? ADAPTER_BIN[opts.harness], [], {
|
|
12609
12609
|
cwd,
|
|
12610
|
-
// The adapter shells out to its vendor CLI (`claude`, `codex`), and a GUI-
|
|
12611
|
-
//
|
|
12612
|
-
|
|
12610
|
+
// The adapter shells out to its vendor CLI (`claude`, `codex`), and a GUI- or
|
|
12611
|
+
// launchd-launched process's PATH won't have it — probe dirs plus the RUNNING
|
|
12612
|
+
// node's own bin dir (nvm installs the adapters next to node; launchd's bare
|
|
12613
|
+
// PATH knows neither — live catch 2026-08-04: the first slot-wake ENOENT'd).
|
|
12614
|
+
env: {
|
|
12615
|
+
...process.env,
|
|
12616
|
+
PATH: [process.env.PATH, dirname2(process.execPath), ...probeDirs()].filter(Boolean).join(delimiter),
|
|
12617
|
+
...opts.token ? { PAIGY_TOKEN: opts.token } : {}
|
|
12618
|
+
},
|
|
12613
12619
|
stdio: ["pipe", "pipe", "pipe"]
|
|
12614
12620
|
});
|
|
12615
12621
|
const write = (frames) => {
|
|
@@ -12622,8 +12628,12 @@ function startSession(opts) {
|
|
|
12622
12628
|
});
|
|
12623
12629
|
child.on("exit", (code) => {
|
|
12624
12630
|
opts.onEvent({ kind: "idle", failed: code !== 0, ...code ? { result: `exited ${code}` } : {} });
|
|
12631
|
+
opts.onExit?.();
|
|
12632
|
+
});
|
|
12633
|
+
child.on("error", (e) => {
|
|
12634
|
+
opts.onEvent({ kind: "error", message: e.message });
|
|
12635
|
+
opts.onExit?.();
|
|
12625
12636
|
});
|
|
12626
|
-
child.on("error", (e) => opts.onEvent({ kind: "error", message: e.message }));
|
|
12627
12637
|
const driver = createAcpDriver({ cwd, mode: opts.mode, ...opts.mcp ? { mcp: opts.mcp } : {} });
|
|
12628
12638
|
let buffer = "";
|
|
12629
12639
|
child.stdout?.on("data", (chunk) => {
|
|
@@ -13790,7 +13800,9 @@ function runHarness(opts) {
|
|
|
13790
13800
|
cwd: opts.cwd,
|
|
13791
13801
|
mode: opts.mode,
|
|
13792
13802
|
...paigyMcp ? { mcp: paigyMcp } : {},
|
|
13803
|
+
...opts.token ? { token: opts.token } : {},
|
|
13793
13804
|
...opts.bin ? { bin: opts.bin } : {},
|
|
13805
|
+
...opts.onExit ? { onExit: opts.onExit } : {},
|
|
13794
13806
|
onEvent: (event) => void handle(event).catch((err) => opts.log(`\u26A0 ${err.message}`))
|
|
13795
13807
|
});
|
|
13796
13808
|
if (opts.prompt) session.send(opts.prompt);
|
|
@@ -13835,6 +13847,10 @@ function startHost(opts) {
|
|
|
13835
13847
|
prompt: spec.prompt ?? "",
|
|
13836
13848
|
exclusive: true,
|
|
13837
13849
|
token: spec.token,
|
|
13850
|
+
onExit: () => {
|
|
13851
|
+
runs.delete(spec.sessionId);
|
|
13852
|
+
opts.log(`\u2716 ${label} ended`);
|
|
13853
|
+
},
|
|
13838
13854
|
log: log2
|
|
13839
13855
|
});
|
|
13840
13856
|
runs.set(spec.sessionId, { run, label });
|
|
@@ -13854,7 +13870,20 @@ function startHost(opts) {
|
|
|
13854
13870
|
const work = await checkReplies({ token }).catch(() => null);
|
|
13855
13871
|
if (!work || work.requests.length === 0 && work.replies.length === 0) continue;
|
|
13856
13872
|
const log2 = (line) => opts.log(`[${slot}] ${line}`);
|
|
13857
|
-
const run = runHarness({
|
|
13873
|
+
const run = runHarness({
|
|
13874
|
+
harness,
|
|
13875
|
+
cwd: workspace,
|
|
13876
|
+
mode: "bypass",
|
|
13877
|
+
prompt: "",
|
|
13878
|
+
exclusive: true,
|
|
13879
|
+
token,
|
|
13880
|
+
// A dead run must not squat the slot — evict so the next wake can respawn.
|
|
13881
|
+
onExit: () => {
|
|
13882
|
+
runs.delete(key);
|
|
13883
|
+
opts.log(`\u2716 ${slot} ended`);
|
|
13884
|
+
},
|
|
13885
|
+
log: log2
|
|
13886
|
+
});
|
|
13858
13887
|
runs.set(key, { run, label: slot });
|
|
13859
13888
|
opts.log(`\u25B6 woke ${slot} (${harness}) \u2014 work was waiting in ${workspace}`);
|
|
13860
13889
|
}
|
|
@@ -13884,7 +13913,7 @@ function startHost(opts) {
|
|
|
13884
13913
|
}
|
|
13885
13914
|
|
|
13886
13915
|
// src/main.ts
|
|
13887
|
-
var here =
|
|
13916
|
+
var here = dirname3(fileURLToPath(import.meta.url));
|
|
13888
13917
|
var wsDeps = { file: workspacesFile() };
|
|
13889
13918
|
var DEVICE_SLOT = "Desktop";
|
|
13890
13919
|
var deviceToken = () => readToken(DEVICE_SLOT) || readToken();
|
package/package.json
CHANGED
|
@@ -1,13 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@paigy/harness",
|
|
3
|
-
"version": "0.2.
|
|
4
|
-
"description": "Run Claude Code / Codex on this machine, bridged to Paigy
|
|
3
|
+
"version": "0.2.2",
|
|
4
|
+
"description": "Run Claude Code / Codex on this machine, bridged to Paigy \u2014 launchable from your phone.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "dist/main.js",
|
|
8
8
|
"bin": {
|
|
9
9
|
"paigy-harness": "dist/cli.js"
|
|
10
10
|
},
|
|
11
|
+
"scripts": {
|
|
12
|
+
"build": "tsup",
|
|
13
|
+
"dev": "pnpm build && electron .",
|
|
14
|
+
"start": "electron .",
|
|
15
|
+
"typecheck": "tsc --noEmit",
|
|
16
|
+
"test": "vitest run"
|
|
17
|
+
},
|
|
11
18
|
"dependencies": {},
|
|
12
19
|
"devDependencies": {
|
|
13
20
|
"@types/node": "^22.0.0",
|
|
@@ -16,10 +23,10 @@
|
|
|
16
23
|
"tsup": "^8.3.5",
|
|
17
24
|
"typescript": "^5.7.2",
|
|
18
25
|
"vitest": "^2.1.8",
|
|
26
|
+
"@paigy/schema": "workspace:*",
|
|
27
|
+
"@paigy/sdk": "workspace:*",
|
|
19
28
|
"qrcode": "^1.5.4",
|
|
20
|
-
"zod": "^3.24.1"
|
|
21
|
-
"@paigy/sdk": "0.1.0",
|
|
22
|
-
"@paigy/schema": "0.0.0"
|
|
29
|
+
"zod": "^3.24.1"
|
|
23
30
|
},
|
|
24
31
|
"files": [
|
|
25
32
|
"dist/cli.js",
|
|
@@ -27,12 +34,5 @@
|
|
|
27
34
|
],
|
|
28
35
|
"publishConfig": {
|
|
29
36
|
"access": "public"
|
|
30
|
-
},
|
|
31
|
-
"scripts": {
|
|
32
|
-
"build": "tsup",
|
|
33
|
-
"dev": "pnpm build && electron .",
|
|
34
|
-
"start": "electron .",
|
|
35
|
-
"typecheck": "tsc --noEmit",
|
|
36
|
-
"test": "vitest run"
|
|
37
37
|
}
|
|
38
|
-
}
|
|
38
|
+
}
|