@paigy/harness 0.1.1 → 0.1.5
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 +16 -0
- package/dist/cli.js +112 -12
- package/dist/main.js +15 -6
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -193,6 +193,22 @@ the window.
|
|
|
193
193
|
Pairing is one-time and lives in `~/.paigy` — the app reads it, never mints it. If
|
|
194
194
|
you've never paired: `npx -y -p @paigy/mcp paigy-mcp-onboard`.
|
|
195
195
|
|
|
196
|
+
## Uninstall
|
|
197
|
+
|
|
198
|
+
`curl -fsSL https://paigy.ai/uninstall.sh | sh` removes the harness surface (service,
|
|
199
|
+
global package, workspace list, the machine's Desktop slot — other agents' slots
|
|
200
|
+
survive). Then revoke the machine on the phone's Agents screen: server-side tokens
|
|
201
|
+
outlive local files.
|
|
202
|
+
|
|
203
|
+
The FULL Paigy strip (tested 2026-08-03) additionally removes, in order: every
|
|
204
|
+
`~/.paigy` slot (unpairs ALL local agents — re-pairing resets voices), the ACP
|
|
205
|
+
adapters (`npm rm -g @agentclientprotocol/{claude-agent-acp,codex-acp}`), Electron
|
|
206
|
+
userData, the statusline block + `paigy@paigy` plugin enablement + marketplace +
|
|
207
|
+
`mcp__paigy__*` permission entries in `~/.claude/settings.json`, the project
|
|
208
|
+
`.mcp.json` paigy server, the plugin cache/registry entries, and `~/.npm/_npx` (so
|
|
209
|
+
`@paigy/mcp@latest` can't serve stale). Hooks can recreate `~/.paigy` — delete it
|
|
210
|
+
LAST, after the hooks are gone.
|
|
211
|
+
|
|
196
212
|
## Known gaps (#804)
|
|
197
213
|
|
|
198
214
|
- **Protocol churn is the standing risk.** Neither `stream-json` nor ACP adapter
|
package/dist/cli.js
CHANGED
|
@@ -30857,7 +30857,7 @@ async function setTaskState(notificationId, state, opts = {}) {
|
|
|
30857
30857
|
// src/cli.ts
|
|
30858
30858
|
var import_qrcode = __toESM(require_lib(), 1);
|
|
30859
30859
|
import { hostname } from "os";
|
|
30860
|
-
import {
|
|
30860
|
+
import { existsSync as existsSync5, mkdirSync as mkdirSync3, readFileSync as readFileSync3, writeFileSync as writeFileSync3 } from "fs";
|
|
30861
30861
|
import { execSync } from "child_process";
|
|
30862
30862
|
import { homedir as homedir5 } from "os";
|
|
30863
30863
|
import { join as join4 } from "path";
|
|
@@ -31729,9 +31729,10 @@ async function drainInput(state, deps = {}) {
|
|
|
31729
31729
|
return [];
|
|
31730
31730
|
}
|
|
31731
31731
|
const ours = (parentId) => state.exclusive || parentId === state.parentId;
|
|
31732
|
+
const claimable = (notificationId) => !state.sharedWithAgent || (state.mine?.has(notificationId) ?? false);
|
|
31732
31733
|
const mine = [
|
|
31733
|
-
...work.replies.filter((r) => ours(r.parentId)).map((r) => ({ notificationId: r.notificationId, parentId: r.parentId, answer: r.answer })),
|
|
31734
|
-
...work.requests.filter((r) => ours(r.parentId)).map((r) => ({ notificationId: r.notificationId, parentId: r.parentId, answer: { kind: "text", text: r.text } }))
|
|
31734
|
+
...work.replies.filter((r) => ours(r.parentId) && claimable(r.notificationId)).map((r) => ({ notificationId: r.notificationId, parentId: r.parentId, answer: r.answer })),
|
|
31735
|
+
...work.requests.filter((r) => ours(r.parentId) && claimable(r.notificationId)).map((r) => ({ notificationId: r.notificationId, parentId: r.parentId, answer: { kind: "text", text: r.text } }))
|
|
31735
31736
|
];
|
|
31736
31737
|
const claimed = [];
|
|
31737
31738
|
for (const item of mine) {
|
|
@@ -31881,6 +31882,7 @@ async function mirror(event, state, deps = {}) {
|
|
|
31881
31882
|
try {
|
|
31882
31883
|
const req = NotifyRequestSchema2.parse(entry);
|
|
31883
31884
|
const { notificationId, parentId } = await (deps.submit ?? submitNotification)(req);
|
|
31885
|
+
(state.mine ??= /* @__PURE__ */ new Set()).add(notificationId);
|
|
31884
31886
|
return { parentId, notificationId };
|
|
31885
31887
|
} catch {
|
|
31886
31888
|
return {};
|
|
@@ -31895,6 +31897,7 @@ async function askPermission(event, state, deps = {}) {
|
|
|
31895
31897
|
if (!entry) return { decision: { allow: false, reason: "Could not ask" } };
|
|
31896
31898
|
try {
|
|
31897
31899
|
const sent = await (deps.submit ?? submitNotification)(NotifyRequestSchema2.parse(entry));
|
|
31900
|
+
(state.mine ??= /* @__PURE__ */ new Set()).add(sent.notificationId);
|
|
31898
31901
|
const answer = await awaitAnswer(state, sent.notificationId);
|
|
31899
31902
|
return { decision: decisionFrom(answer), parentId: sent.parentId };
|
|
31900
31903
|
} catch (e) {
|
|
@@ -31913,6 +31916,7 @@ async function askQuestion(question, state, deps = {}) {
|
|
|
31913
31916
|
};
|
|
31914
31917
|
try {
|
|
31915
31918
|
const sent = await (deps.submit ?? submitNotification)(NotifyRequestSchema2.parse(entry));
|
|
31919
|
+
(state.mine ??= /* @__PURE__ */ new Set()).add(sent.notificationId);
|
|
31916
31920
|
return spokenText(await awaitAnswer(state, sent.notificationId));
|
|
31917
31921
|
} catch {
|
|
31918
31922
|
return null;
|
|
@@ -31965,15 +31969,17 @@ function optionFor(options, decision) {
|
|
|
31965
31969
|
return options.find((o) => o.kind === want)?.optionId ?? null;
|
|
31966
31970
|
}
|
|
31967
31971
|
function createAcpDriver(opts) {
|
|
31968
|
-
return new AcpDriver(opts.cwd, opts.mode);
|
|
31972
|
+
return new AcpDriver(opts.cwd, opts.mode, opts.mcp ?? []);
|
|
31969
31973
|
}
|
|
31970
31974
|
var AcpDriver = class {
|
|
31971
|
-
constructor(cwd, mode) {
|
|
31975
|
+
constructor(cwd, mode, mcp = []) {
|
|
31972
31976
|
this.cwd = cwd;
|
|
31973
31977
|
this.mode = mode;
|
|
31978
|
+
this.mcp = mcp;
|
|
31974
31979
|
}
|
|
31975
31980
|
cwd;
|
|
31976
31981
|
mode;
|
|
31982
|
+
mcp;
|
|
31977
31983
|
nextId = 1;
|
|
31978
31984
|
initId;
|
|
31979
31985
|
sessionNewId;
|
|
@@ -32049,7 +32055,7 @@ var AcpDriver = class {
|
|
|
32049
32055
|
this.sessionNewId = this.nextId++;
|
|
32050
32056
|
return {
|
|
32051
32057
|
events: [],
|
|
32052
|
-
writes: [frame({ id: this.sessionNewId, method: "session/new", params: { cwd: this.cwd, mcpServers:
|
|
32058
|
+
writes: [frame({ id: this.sessionNewId, method: "session/new", params: { cwd: this.cwd, mcpServers: this.mcp } })]
|
|
32053
32059
|
};
|
|
32054
32060
|
}
|
|
32055
32061
|
if (msg.id === this.sessionNewId) {
|
|
@@ -32198,7 +32204,7 @@ function startSession(opts) {
|
|
|
32198
32204
|
opts.onEvent({ kind: "idle", failed: code !== 0, ...code ? { result: `exited ${code}` } : {} });
|
|
32199
32205
|
});
|
|
32200
32206
|
child.on("error", (e) => opts.onEvent({ kind: "error", message: e.message }));
|
|
32201
|
-
const driver = createAcpDriver({ cwd, mode: opts.mode });
|
|
32207
|
+
const driver = createAcpDriver({ cwd, mode: opts.mode, ...opts.mcp ? { mcp: opts.mcp } : {} });
|
|
32202
32208
|
let buffer = "";
|
|
32203
32209
|
child.stdout?.on("data", (chunk) => {
|
|
32204
32210
|
const { lines, rest } = splitLines(buffer, String(chunk));
|
|
@@ -32273,10 +32279,13 @@ function runHarness(opts) {
|
|
|
32273
32279
|
}
|
|
32274
32280
|
}
|
|
32275
32281
|
}
|
|
32282
|
+
const paigyMcp = opts.exclusive && opts.token ? [{ name: "paigy", command: "npx", args: ["-y", "@paigy/mcp@latest"], env: { PAIGY_TOKEN: opts.token } }] : void 0;
|
|
32283
|
+
if (paigyMcp) state.sharedWithAgent = true;
|
|
32276
32284
|
session = startSession({
|
|
32277
32285
|
harness: opts.harness,
|
|
32278
32286
|
cwd: opts.cwd,
|
|
32279
32287
|
mode: opts.mode,
|
|
32288
|
+
...paigyMcp ? { mcp: paigyMcp } : {},
|
|
32280
32289
|
...opts.bin ? { bin: opts.bin } : {},
|
|
32281
32290
|
onEvent: (event) => void handle(event).catch((err) => opts.log(`\u26A0 ${err.message}`))
|
|
32282
32291
|
});
|
|
@@ -32377,7 +32386,7 @@ function startHost(opts) {
|
|
|
32377
32386
|
|
|
32378
32387
|
// src/cli.ts
|
|
32379
32388
|
function parseArgs(argv) {
|
|
32380
|
-
const args = { harness: "claude", mode: "bypass", cwd: process.cwd(), doctor: false, host: false, pair: false, service: false, grant: [], hatch: null, identity: null, graceSeconds: 90, prompt: "" };
|
|
32389
|
+
const args = { harness: "claude", mode: "bypass", cwd: process.cwd(), doctor: false, host: false, pair: false, service: false, setup: false, grant: [], hatch: null, voice: null, slot: null, identity: null, graceSeconds: 90, prompt: "" };
|
|
32381
32390
|
const words = [];
|
|
32382
32391
|
for (let i = 0; i < argv.length; i++) {
|
|
32383
32392
|
const arg = argv[i];
|
|
@@ -32404,6 +32413,8 @@ function parseArgs(argv) {
|
|
|
32404
32413
|
args.host = true;
|
|
32405
32414
|
} else if (arg === "pair") {
|
|
32406
32415
|
args.pair = true;
|
|
32416
|
+
} else if (arg === "setup") {
|
|
32417
|
+
args.setup = true;
|
|
32407
32418
|
} else if (arg === "service") {
|
|
32408
32419
|
args.service = true;
|
|
32409
32420
|
} else if (arg === "--grant") {
|
|
@@ -32414,6 +32425,10 @@ function parseArgs(argv) {
|
|
|
32414
32425
|
const v = next();
|
|
32415
32426
|
if (!v) return { error: 'hatch needs a name: paigy-harness hatch "Voice bug hunter"' };
|
|
32416
32427
|
args.hatch = v;
|
|
32428
|
+
} else if (arg === "--voice") {
|
|
32429
|
+
args.voice = next() ?? null;
|
|
32430
|
+
} else if (arg === "--slot") {
|
|
32431
|
+
args.slot = next() ?? null;
|
|
32417
32432
|
} else if (arg === "--identity") {
|
|
32418
32433
|
const v = next();
|
|
32419
32434
|
if (!v) return { error: "--identity needs a hatched agent's name" };
|
|
@@ -32425,7 +32440,7 @@ function parseArgs(argv) {
|
|
|
32425
32440
|
}
|
|
32426
32441
|
}
|
|
32427
32442
|
args.prompt = words.join(" ");
|
|
32428
|
-
if (!args.doctor && !args.hatch && !args.host && !args.pair && !args.service && !args.prompt) return { error: "a prompt is required (or --doctor / pair / host / service / hatch NAME)" };
|
|
32443
|
+
if (!args.doctor && !args.hatch && !args.host && !args.pair && !args.service && !args.setup && !args.prompt) return { error: "a prompt is required (or setup / --doctor / pair / host / service / hatch NAME)" };
|
|
32429
32444
|
return args;
|
|
32430
32445
|
}
|
|
32431
32446
|
var STATUS_MARK = { ready: "\u2713", login: "\u25D0", "adapter-missing": "\u25D0", missing: "\u2717" };
|
|
@@ -32433,7 +32448,7 @@ async function main() {
|
|
|
32433
32448
|
const parsed = parseArgs(process.argv.slice(2));
|
|
32434
32449
|
if ("error" in parsed) {
|
|
32435
32450
|
console.error(`paigy-harness: ${parsed.error}`);
|
|
32436
|
-
console.error("usage: paigy-harness pair | host [--grant DIR]\u2026 | service | hatch NAME | [--harness claude|codex] [--mode bypass|ask] [--cwd DIR] [--identity NAME] [--grace SECONDS] [--doctor] PROMPT\u2026");
|
|
32451
|
+
console.error("usage: paigy-harness setup | pair | host [--grant DIR]\u2026 | service | hatch NAME [--voice KEY] [--slot SLOT] | [--harness claude|codex] [--mode bypass|ask] [--cwd DIR] [--identity NAME] [--grace SECONDS] [--doctor] PROMPT\u2026");
|
|
32437
32452
|
process.exit(2);
|
|
32438
32453
|
}
|
|
32439
32454
|
if (parsed.doctor) {
|
|
@@ -32443,6 +32458,91 @@ async function main() {
|
|
|
32443
32458
|
}
|
|
32444
32459
|
return;
|
|
32445
32460
|
}
|
|
32461
|
+
if (parsed.setup) {
|
|
32462
|
+
if (!readToken("Desktop")) {
|
|
32463
|
+
const code = await requestCode(hostname().replace(/\.local$/, ""));
|
|
32464
|
+
console.log(await import_qrcode.default.toString(code.verification_uri_complete, { type: "terminal", small: true }));
|
|
32465
|
+
console.log(`Scan with your phone's camera, or enter code ${code.user_code} at ${code.verification_uri}`);
|
|
32466
|
+
const deadline = Date.now() + code.expires_in * 1e3;
|
|
32467
|
+
let paired = false;
|
|
32468
|
+
while (!paired && Date.now() < deadline) {
|
|
32469
|
+
const token = await pollToken(code.device_code).catch(() => null);
|
|
32470
|
+
if (token) {
|
|
32471
|
+
saveToken(token, "Desktop");
|
|
32472
|
+
console.log(`\u2713 paired as "${token.name}"`);
|
|
32473
|
+
paired = true;
|
|
32474
|
+
} else await sleep(code.interval * 1e3);
|
|
32475
|
+
}
|
|
32476
|
+
if (!paired) {
|
|
32477
|
+
console.error("Pairing code expired \u2014 run `paigy-harness setup` again.");
|
|
32478
|
+
process.exit(1);
|
|
32479
|
+
}
|
|
32480
|
+
} else console.log("\u2713 already paired as this machine");
|
|
32481
|
+
for (const a of detectAll()) {
|
|
32482
|
+
if (a.status === "adapter-missing" && a.install) {
|
|
32483
|
+
console.log(`\u2192 installing the ${a.label} bridge\u2026`);
|
|
32484
|
+
try {
|
|
32485
|
+
execSync(a.install, { stdio: "inherit", shell: "/bin/sh" });
|
|
32486
|
+
} catch {
|
|
32487
|
+
console.log(` couldn't install \u2014 later: ${a.install}`);
|
|
32488
|
+
}
|
|
32489
|
+
} else if (a.status === "missing") console.log(`\u2717 ${a.label} CLI not installed \u2014 ${a.hint ?? ""}`);
|
|
32490
|
+
else if (a.status === "login") console.log(`\u25D0 ${a.label}: ${a.hint ?? "sign in"}`);
|
|
32491
|
+
else console.log(`\u2713 ${a.label} ready`);
|
|
32492
|
+
}
|
|
32493
|
+
const wsDeps = { file: workspacesFile() };
|
|
32494
|
+
for (const dir of parsed.grant) addWorkspace(dir, wsDeps);
|
|
32495
|
+
if (!listWorkspaces(wsDeps).length) {
|
|
32496
|
+
const guess = join4(homedir5(), "projects");
|
|
32497
|
+
if (existsSync5(guess)) {
|
|
32498
|
+
addWorkspace(guess, wsDeps);
|
|
32499
|
+
console.log(`\u2713 workspace granted: ${guess} (change with --grant DIR)`);
|
|
32500
|
+
} else console.log("no workspace granted yet \u2014 grant one with: paigy-harness host --grant DIR");
|
|
32501
|
+
}
|
|
32502
|
+
if (process.platform === "darwin") {
|
|
32503
|
+
try {
|
|
32504
|
+
execSync(`${JSON.stringify(process.execPath)} ${JSON.stringify(process.argv[1])} service`, { stdio: "inherit", shell: "/bin/sh" });
|
|
32505
|
+
} catch {
|
|
32506
|
+
console.log("service install failed \u2014 run `paigy-harness host` to host in the foreground");
|
|
32507
|
+
}
|
|
32508
|
+
} else console.log("start hosting with: paigy-harness host (keep it running under your init system)");
|
|
32509
|
+
const TERMINAL_AGENTS = [
|
|
32510
|
+
{ cli: "claude", name: "Claude Code", slot: "mcp-agent", wire: "claude mcp add --scope user paigy -- npx -y @paigy/mcp@latest" },
|
|
32511
|
+
{ cli: "codex", name: "Codex", slot: "codex", wire: "codex mcp add paigy -- npx -y @paigy/mcp@latest" },
|
|
32512
|
+
{ cli: "antigravity", name: "Antigravity", slot: "antigravity" }
|
|
32513
|
+
];
|
|
32514
|
+
for (const t of TERMINAL_AGENTS) {
|
|
32515
|
+
try {
|
|
32516
|
+
if (!which(t.cli) || readToken(t.slot)) continue;
|
|
32517
|
+
const minted = await hatch(t.name, null);
|
|
32518
|
+
saveToken({ access_token: minted.token, name: minted.name, device: null }, t.slot);
|
|
32519
|
+
console.log(`\u2713 hatched "${minted.name}" for ${t.cli} sessions (name/voice it on the phone)`);
|
|
32520
|
+
if (t.wire) {
|
|
32521
|
+
try {
|
|
32522
|
+
execSync(t.wire, { stdio: "ignore", shell: "/bin/sh" });
|
|
32523
|
+
console.log(`\u2713 paigy MCP registered for ${t.cli} (restart open sessions)`);
|
|
32524
|
+
} catch {
|
|
32525
|
+
}
|
|
32526
|
+
}
|
|
32527
|
+
} catch {
|
|
32528
|
+
}
|
|
32529
|
+
}
|
|
32530
|
+
try {
|
|
32531
|
+
const settings = join4(homedir5(), ".claude", "settings.json");
|
|
32532
|
+
if (which("claude") && existsSync5(settings)) {
|
|
32533
|
+
const cfg = JSON.parse(readFileSync3(settings, "utf8"));
|
|
32534
|
+
if (!cfg["statusLine"]) {
|
|
32535
|
+
cfg["statusLine"] = { type: "command", command: "npx -y -p @paigy/mcp@latest paigy-statusline" };
|
|
32536
|
+
writeFileSync3(settings, JSON.stringify(cfg, null, 2));
|
|
32537
|
+
console.log("\u2713 statusline wired");
|
|
32538
|
+
}
|
|
32539
|
+
}
|
|
32540
|
+
} catch {
|
|
32541
|
+
}
|
|
32542
|
+
console.log("\n\u2705 Done \u2014 look at your phone: Agents shows this machine with a green dot,");
|
|
32543
|
+
console.log(" and \u201C+ New session\u201D launches agents on it.");
|
|
32544
|
+
return;
|
|
32545
|
+
}
|
|
32446
32546
|
if (parsed.pair) {
|
|
32447
32547
|
if (readToken("Desktop")) {
|
|
32448
32548
|
console.log("\u2713 already paired as this machine");
|
|
@@ -32499,8 +32599,8 @@ async function main() {
|
|
|
32499
32599
|
process.exit(1);
|
|
32500
32600
|
}
|
|
32501
32601
|
if (parsed.hatch) {
|
|
32502
|
-
const minted = await hatch(parsed.hatch);
|
|
32503
|
-
saveToken({ access_token: minted.token, name: minted.name, device: null }, minted.name);
|
|
32602
|
+
const minted = await hatch(parsed.hatch, parsed.voice ?? null);
|
|
32603
|
+
saveToken({ access_token: minted.token, name: minted.name, device: null }, parsed.slot ?? minted.name);
|
|
32504
32604
|
console.log(`\u2713 hatched "${minted.name}" \u2014 it's on your phone's Agents screen now.`);
|
|
32505
32605
|
console.log(` speak as it: PAIGY_AGENT="${minted.name}" <any paigy tool>`);
|
|
32506
32606
|
console.log(` run with it: paigy-harness --identity "${minted.name}" --harness codex "\u2026"`);
|
package/dist/main.js
CHANGED
|
@@ -12386,15 +12386,17 @@ function optionFor(options, decision) {
|
|
|
12386
12386
|
return options.find((o) => o.kind === want)?.optionId ?? null;
|
|
12387
12387
|
}
|
|
12388
12388
|
function createAcpDriver(opts) {
|
|
12389
|
-
return new AcpDriver(opts.cwd, opts.mode);
|
|
12389
|
+
return new AcpDriver(opts.cwd, opts.mode, opts.mcp ?? []);
|
|
12390
12390
|
}
|
|
12391
12391
|
var AcpDriver = class {
|
|
12392
|
-
constructor(cwd, mode) {
|
|
12392
|
+
constructor(cwd, mode, mcp = []) {
|
|
12393
12393
|
this.cwd = cwd;
|
|
12394
12394
|
this.mode = mode;
|
|
12395
|
+
this.mcp = mcp;
|
|
12395
12396
|
}
|
|
12396
12397
|
cwd;
|
|
12397
12398
|
mode;
|
|
12399
|
+
mcp;
|
|
12398
12400
|
nextId = 1;
|
|
12399
12401
|
initId;
|
|
12400
12402
|
sessionNewId;
|
|
@@ -12470,7 +12472,7 @@ var AcpDriver = class {
|
|
|
12470
12472
|
this.sessionNewId = this.nextId++;
|
|
12471
12473
|
return {
|
|
12472
12474
|
events: [],
|
|
12473
|
-
writes: [frame({ id: this.sessionNewId, method: "session/new", params: { cwd: this.cwd, mcpServers:
|
|
12475
|
+
writes: [frame({ id: this.sessionNewId, method: "session/new", params: { cwd: this.cwd, mcpServers: this.mcp } })]
|
|
12474
12476
|
};
|
|
12475
12477
|
}
|
|
12476
12478
|
if (msg.id === this.sessionNewId) {
|
|
@@ -12619,7 +12621,7 @@ function startSession(opts) {
|
|
|
12619
12621
|
opts.onEvent({ kind: "idle", failed: code !== 0, ...code ? { result: `exited ${code}` } : {} });
|
|
12620
12622
|
});
|
|
12621
12623
|
child.on("error", (e) => opts.onEvent({ kind: "error", message: e.message }));
|
|
12622
|
-
const driver = createAcpDriver({ cwd, mode: opts.mode });
|
|
12624
|
+
const driver = createAcpDriver({ cwd, mode: opts.mode, ...opts.mcp ? { mcp: opts.mcp } : {} });
|
|
12623
12625
|
let buffer = "";
|
|
12624
12626
|
child.stdout?.on("data", (chunk) => {
|
|
12625
12627
|
const { lines, rest } = splitLines(buffer, String(chunk));
|
|
@@ -13512,9 +13514,10 @@ async function drainInput(state, deps = {}) {
|
|
|
13512
13514
|
return [];
|
|
13513
13515
|
}
|
|
13514
13516
|
const ours = (parentId) => state.exclusive || parentId === state.parentId;
|
|
13517
|
+
const claimable = (notificationId) => !state.sharedWithAgent || (state.mine?.has(notificationId) ?? false);
|
|
13515
13518
|
const mine = [
|
|
13516
|
-
...work.replies.filter((r) => ours(r.parentId)).map((r) => ({ notificationId: r.notificationId, parentId: r.parentId, answer: r.answer })),
|
|
13517
|
-
...work.requests.filter((r) => ours(r.parentId)).map((r) => ({ notificationId: r.notificationId, parentId: r.parentId, answer: { kind: "text", text: r.text } }))
|
|
13519
|
+
...work.replies.filter((r) => ours(r.parentId) && claimable(r.notificationId)).map((r) => ({ notificationId: r.notificationId, parentId: r.parentId, answer: r.answer })),
|
|
13520
|
+
...work.requests.filter((r) => ours(r.parentId) && claimable(r.notificationId)).map((r) => ({ notificationId: r.notificationId, parentId: r.parentId, answer: { kind: "text", text: r.text } }))
|
|
13518
13521
|
];
|
|
13519
13522
|
const claimed = [];
|
|
13520
13523
|
for (const item of mine) {
|
|
@@ -13664,6 +13667,7 @@ async function mirror(event, state, deps = {}) {
|
|
|
13664
13667
|
try {
|
|
13665
13668
|
const req = NotifyRequestSchema2.parse(entry);
|
|
13666
13669
|
const { notificationId, parentId } = await (deps.submit ?? submitNotification)(req);
|
|
13670
|
+
(state.mine ??= /* @__PURE__ */ new Set()).add(notificationId);
|
|
13667
13671
|
return { parentId, notificationId };
|
|
13668
13672
|
} catch {
|
|
13669
13673
|
return {};
|
|
@@ -13678,6 +13682,7 @@ async function askPermission(event, state, deps = {}) {
|
|
|
13678
13682
|
if (!entry) return { decision: { allow: false, reason: "Could not ask" } };
|
|
13679
13683
|
try {
|
|
13680
13684
|
const sent = await (deps.submit ?? submitNotification)(NotifyRequestSchema2.parse(entry));
|
|
13685
|
+
(state.mine ??= /* @__PURE__ */ new Set()).add(sent.notificationId);
|
|
13681
13686
|
const answer = await awaitAnswer(state, sent.notificationId);
|
|
13682
13687
|
return { decision: decisionFrom(answer), parentId: sent.parentId };
|
|
13683
13688
|
} catch (e) {
|
|
@@ -13696,6 +13701,7 @@ async function askQuestion(question, state, deps = {}) {
|
|
|
13696
13701
|
};
|
|
13697
13702
|
try {
|
|
13698
13703
|
const sent = await (deps.submit ?? submitNotification)(NotifyRequestSchema2.parse(entry));
|
|
13704
|
+
(state.mine ??= /* @__PURE__ */ new Set()).add(sent.notificationId);
|
|
13699
13705
|
return spokenText(await awaitAnswer(state, sent.notificationId));
|
|
13700
13706
|
} catch {
|
|
13701
13707
|
return null;
|
|
@@ -13773,10 +13779,13 @@ function runHarness(opts) {
|
|
|
13773
13779
|
}
|
|
13774
13780
|
}
|
|
13775
13781
|
}
|
|
13782
|
+
const paigyMcp = opts.exclusive && opts.token ? [{ name: "paigy", command: "npx", args: ["-y", "@paigy/mcp@latest"], env: { PAIGY_TOKEN: opts.token } }] : void 0;
|
|
13783
|
+
if (paigyMcp) state.sharedWithAgent = true;
|
|
13776
13784
|
session = startSession({
|
|
13777
13785
|
harness: opts.harness,
|
|
13778
13786
|
cwd: opts.cwd,
|
|
13779
13787
|
mode: opts.mode,
|
|
13788
|
+
...paigyMcp ? { mcp: paigyMcp } : {},
|
|
13780
13789
|
...opts.bin ? { bin: opts.bin } : {},
|
|
13781
13790
|
onEvent: (event) => void handle(event).catch((err) => opts.log(`\u26A0 ${err.message}`))
|
|
13782
13791
|
});
|