@floh-solutions/pharos-cli 0.29.0 → 0.31.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.
Files changed (45) hide show
  1. package/README.md +33 -0
  2. package/dist/capabilities.d.ts +7 -0
  3. package/dist/capabilities.d.ts.map +1 -1
  4. package/dist/capabilities.js +25 -0
  5. package/dist/capabilities.js.map +1 -1
  6. package/dist/cli.d.ts +18 -1
  7. package/dist/cli.d.ts.map +1 -1
  8. package/dist/cli.js +193 -86
  9. package/dist/cli.js.map +1 -1
  10. package/dist/commands/delegate.d.ts +248 -0
  11. package/dist/commands/delegate.d.ts.map +1 -0
  12. package/dist/commands/delegate.js +582 -0
  13. package/dist/commands/delegate.js.map +1 -0
  14. package/dist/commands/doctor.d.ts +8 -0
  15. package/dist/commands/doctor.d.ts.map +1 -1
  16. package/dist/commands/doctor.js +179 -4
  17. package/dist/commands/doctor.js.map +1 -1
  18. package/dist/commands/setup.d.ts.map +1 -1
  19. package/dist/commands/setup.js +7 -3
  20. package/dist/commands/setup.js.map +1 -1
  21. package/dist/delegate/hosts.d.ts +83 -0
  22. package/dist/delegate/hosts.d.ts.map +1 -0
  23. package/dist/delegate/hosts.js +154 -0
  24. package/dist/delegate/hosts.js.map +1 -0
  25. package/dist/delegate/quote.d.ts +78 -0
  26. package/dist/delegate/quote.d.ts.map +1 -0
  27. package/dist/delegate/quote.js +134 -0
  28. package/dist/delegate/quote.js.map +1 -0
  29. package/dist/delegate/sessions.d.ts +121 -0
  30. package/dist/delegate/sessions.d.ts.map +1 -0
  31. package/dist/delegate/sessions.js +229 -0
  32. package/dist/delegate/sessions.js.map +1 -0
  33. package/dist/delegate/vsix.d.ts +122 -0
  34. package/dist/delegate/vsix.d.ts.map +1 -0
  35. package/dist/delegate/vsix.js +329 -0
  36. package/dist/delegate/vsix.js.map +1 -0
  37. package/package.json +5 -4
  38. package/skill/SKILL.md +47 -0
  39. package/vscode/README.md +30 -0
  40. package/vscode/pharos-bridge.json +10 -0
  41. package/vscode/pharos-bridge.vsix +0 -0
  42. package/dist/commands/pr.d.ts +0 -56
  43. package/dist/commands/pr.d.ts.map +0 -1
  44. package/dist/commands/pr.js +0 -202
  45. package/dist/commands/pr.js.map +0 -1
@@ -0,0 +1,582 @@
1
+ import { execFile } from "node:child_process";
2
+ import { stat } from "node:fs/promises";
3
+ import { basename, isAbsolute, join } from "node:path";
4
+ import { promisify } from "node:util";
5
+ import { findApp, HOSTS, HOST_IDS, AGENT_IDS, MODES, isAgentId, isHostId, isMode, } from "../delegate/hosts.js";
6
+ import { asTypedInput, LAUNCH_SCRIPT, launchCommand, SEND_TO_TAB_SCRIPT } from "../delegate/quote.js";
7
+ import { findSessions, rankSessions, systemProbes, } from "../delegate/sessions.js";
8
+ import { BRIDGE_EXTENSION_ID, CLAUDE_EXTENSION_ID, extensionsDirectory, installedExtensions, } from "../delegate/vsix.js";
9
+ import { CliError, EXIT_FAILED, EXIT_USAGE, emit, emitText, usageError } from "../output.js";
10
+ import { resolveOnPath } from "./doctor.js";
11
+ const run = promisify(execFile);
12
+ /**
13
+ * The closed set. The app renders these as facts; do not rename one without a
14
+ * note on the board and a matching change on the app side.
15
+ */
16
+ export const REASONS = [
17
+ "host-not-installed",
18
+ "agent-not-installed",
19
+ "bridge-not-installed",
20
+ "automation-denied",
21
+ "folder-missing",
22
+ "unsupported",
23
+ /** `--session <id>` named a session that is no longer a target on this folder. */
24
+ "session-gone",
25
+ ];
26
+ export const SYSTEM_DEPS = {
27
+ findApp,
28
+ resolveOnPath,
29
+ probes: systemProbes,
30
+ installedExtensions,
31
+ osascript: async (source, args) => {
32
+ // `--` ends option parsing, so a prompt that begins with a dash is an
33
+ // argument and not a flag. Every variable value travels as argv; nothing
34
+ // is spliced into the script (see `delegate/quote.ts`).
35
+ const { stdout } = await run("/usr/bin/osascript", ["-e", source, "--", ...args], {
36
+ timeout: 30_000,
37
+ maxBuffer: 1024 * 1024,
38
+ // Scrubbed: if this Apple Event auto-launches Terminal, the app must not
39
+ // inherit a nested-session identity. See {@link childEnv}.
40
+ env: childEnv(process.env),
41
+ });
42
+ return stdout;
43
+ },
44
+ open: async (uri) => {
45
+ // **`open` hands the caller's environment to the app it launches** (measured
46
+ // by the bridge track, #1375): a VS Code launched with `CLAUDE_CODE_*` set
47
+ // gives every integrated terminal a nested-session identity for the app's
48
+ // whole lifetime, so a `claude` started in one registers as a child and
49
+ // never appears in `claude agents --json`. Scrubbed here at the source.
50
+ await run("/usr/bin/open", [uri], { timeout: 30_000, env: childEnv(process.env) });
51
+ },
52
+ };
53
+ /**
54
+ * The environment to hand a launched app or shell, with this session's
55
+ * Claude Code identity removed.
56
+ *
57
+ * A `pharos delegate` run BY a coding agent inherits that agent's
58
+ * `CLAUDECODE`, `CLAUDE_PID` and `CLAUDE_CODE_*` variables. Passed on to `open`
59
+ * or an auto-launched Terminal, they stamp the launched agent as a *child* of
60
+ * the launcher's session — invisible to `claude agents --json`, with its
61
+ * transcript off — which is exactly the session both this verb and the bridge
62
+ * rely on `agents --json` to find. `CLAUDE_CODE_SSE_PORT` is kept: it points a
63
+ * child at a shared MCP server rather than at the parent's identity, and
64
+ * dropping it would break that connection without helping here.
65
+ */
66
+ export function childEnv(env) {
67
+ const clean = {};
68
+ for (const [key, value] of Object.entries(env)) {
69
+ if (key === "CLAUDECODE" || key === "CLAUDE_PID")
70
+ continue;
71
+ if (key.startsWith("CLAUDE_CODE_") && key !== "CLAUDE_CODE_SSE_PORT")
72
+ continue;
73
+ clean[key] = value;
74
+ }
75
+ return clean;
76
+ }
77
+ /** The reserved id. `--list` never prints it, so it can never shadow a real session. */
78
+ export const NEW_SESSION = "new";
79
+ /**
80
+ * `--session <id>` → a pick, or a usage error.
81
+ *
82
+ * A malformed id is a **usage error rather than a refusal**: `session-gone` is
83
+ * a fact about the machine ("that session is not there any more"), and the app
84
+ * renders it as one. An id the verb could never have printed is the caller
85
+ * getting the call wrong, and saying `session-gone` about it would teach the
86
+ * person their session had died when it never existed.
87
+ */
88
+ export function sessionPick(value, host) {
89
+ if (value === undefined)
90
+ return undefined;
91
+ const given = value.trim();
92
+ if (given === "") {
93
+ throw usageError(`--session needs an id from \`pharos delegate --list\`, or ${NEW_SESSION} for a fresh session.`);
94
+ }
95
+ if (given === NEW_SESSION)
96
+ return { kind: "new" };
97
+ if (!/^[0-9]+$/.test(given) || !Number.isSafeInteger(Number(given)) || Number(given) <= 0) {
98
+ throw usageError(`--session takes the \`id\` \`pharos delegate --list\` printed, which in ${HOSTS[host].name} is a process `
99
+ + `id, or the reserved ${NEW_SESSION} — not ${JSON.stringify(given)}. (Navarch's ids are worker UUIDs, and `
100
+ + "that route is not available yet.)", { session: given, host });
101
+ }
102
+ return { kind: "pid", pid: Number(given) };
103
+ }
104
+ export async function runDelegate(io, env, options, deps = SYSTEM_DEPS) {
105
+ const host = oneOf(options.host, "--host", HOST_IDS, isHostId);
106
+ const agent = oneOf(options.agent, "--agent", AGENT_IDS, isAgentId);
107
+ const mode = options.mode === undefined ? "terminal" : oneOf(options.mode, "--mode", MODES, isMode);
108
+ if (mode === "extension" && HOSTS[host].vscode === undefined) {
109
+ throw usageError(`--mode extension applies to the VS Code hosts only; ${HOSTS[host].name} has no extension to `
110
+ + "open the prompt in. Leave --mode off, or pass --host vscode / vscode-insiders.", { host, mode });
111
+ }
112
+ if (options.list && options.session !== undefined) {
113
+ throw usageError("--list and --session are different questions: --list reports what is running and sends nothing, "
114
+ + "--session sends to one of the ids it printed. Pass one.");
115
+ }
116
+ const pick = sessionPick(options.session, host);
117
+ // **`--list` needs no prompt**, and demanding one would make the app build a
118
+ // message it is only going to throw away to refresh a menu.
119
+ const text = (options.text ?? "").replace(/\r\n/g, "\n").trim();
120
+ if (text === "" && !options.list) {
121
+ throw usageError("Nothing to send. Pass the prompt with --text, --file or --stdin.");
122
+ }
123
+ const folder = (options.folder ?? "").trim();
124
+ if (folder === "")
125
+ throw usageError("--folder is required: the absolute path of the project folder.");
126
+ if (!isAbsolute(folder)) {
127
+ throw usageError(`--folder must be absolute, got ${JSON.stringify(folder)}.`, { folder });
128
+ }
129
+ const base = { host, agent, mode, folder };
130
+ const refuse = (reason, detail) => emitRefusal(io, options.pretty, { ok: false, reason, detail, ...base });
131
+ const succeed = (outcome) => emitOutcome(io, options.pretty, {
132
+ ok: true,
133
+ ...base,
134
+ ...outcome,
135
+ ...(options.dryRun ? { dryRun: true } : {}),
136
+ });
137
+ // Cheapest fact first: nothing else is worth asking about a folder that is
138
+ // not there, and it is the one refusal that is entirely the caller's to fix.
139
+ const info = await stat(folder).catch(() => null);
140
+ if (info === null || !info.isDirectory()) {
141
+ return refuse("folder-missing", `${folder} is not a directory on this machine. The linked folder for this project has moved `
142
+ + "or was never here — pick it again in Settings ▸ Agents.");
143
+ }
144
+ const app = await deps.findApp(host, env);
145
+ if (app === null) {
146
+ return refuse("host-not-installed", `${HOSTS[host].name} is not installed — looked up by bundle id ${HOSTS[host].bundleId} through `
147
+ + "Spotlight and at the usual paths under /Applications and ~/Applications."
148
+ + (HOSTS[host].cask === undefined ? "" : ` \`brew install --cask ${HOSTS[host].cask}\` installs it.`));
149
+ }
150
+ // Navarch is refused before the agent is even resolved: it cannot take a
151
+ // delegation at all yet, so an `agent-not-installed` about it would name the
152
+ // wrong problem.
153
+ //
154
+ // **`--list` is refused here too, rather than answering with rows.** The
155
+ // contract gives a Navarch row the worker's UUID as its `id` and the worker's
156
+ // name as its `name`, and both come from `fleet_status` over the Argus socket
157
+ // — which is #1393's half of this. Listing the pids instead would hand the
158
+ // app ids that `--session` can never accept, so the whole route is one honest
159
+ // refusal until #1393 lifts it in one place.
160
+ if (host === "navarch") {
161
+ return refuse("unsupported", "Navarch cannot take a delegation yet, and cannot list its sessions either. The Argus side of "
162
+ + "it exists — #1378 added a `delegate` op that finds-or-creates a worker on a folder without "
163
+ + "a board todo, which every other operator action there still needs — but this verb does not "
164
+ + "speak that socket yet. #1393 on the ask-agent board is the todo that teaches it, and it is "
165
+ + "also what supplies the worker ids `--session` would take; until it lands, choose Terminal "
166
+ + "or VS Code.");
167
+ }
168
+ // **May be null, and that is not always a refusal.** The Terminal route runs
169
+ // the agent by this path, so it must exist there; the VS Code extension route
170
+ // runs the agent's OWN bundled binary through the extension, so an agent off
171
+ // PATH is fine there. Each route decides — see {@link delegateToVsCode}.
172
+ const agentPath = await deps.resolveOnPath(agent, env);
173
+ if (options.list) {
174
+ return listSessions(io, host, agent, mode, folder, agentPath, env, deps, options.pretty, refuse);
175
+ }
176
+ if (host === "vscode" || host === "vscode-insiders") {
177
+ return delegateToVsCode(host, agent, mode, folder, text, agentPath, env, deps, options.dryRun, pick, refuse, succeed);
178
+ }
179
+ if (agentPath === null)
180
+ return refuse("agent-not-installed", agentNotInstalled(agent, env));
181
+ return delegateToTerminal(agent, folder, text, agentPath, env, deps, options.dryRun, pick, refuse, succeed);
182
+ }
183
+ /**
184
+ * `--list` — the inventory, and nothing else.
185
+ *
186
+ * **The bridge is deliberately NOT required here.** Listing is
187
+ * `claude agents --json` plus `ps`; it reads the same on a VS Code with no
188
+ * extensions at all. Refusing `bridge-not-installed` for a question the bridge
189
+ * plays no part in would hide the answer behind an unrelated fix, so only the
190
+ * three facts that make the question unanswerable refuse: the host, the agent
191
+ * and the folder.
192
+ *
193
+ * The agent still has to be findable, because that is what runs the inventory —
194
+ * and for Codex, where detection is `ps` and needs no binary, it is refused all
195
+ * the same: a list is offered so it can be picked from, and `delegate` with
196
+ * these flags would refuse on the next call anyway.
197
+ */
198
+ async function listSessions(io, host, agent, mode, folder, agentPath, env, deps, pretty, refuse) {
199
+ // The Claude Code extension bundles its own `claude`, and it can list the
200
+ // machine's sessions as well as the one on PATH — so a VS Code host with the
201
+ // extension installed still answers when PATH has none.
202
+ let probePath = agent === "claude" ? agentPath : null;
203
+ if (agent === "claude" && probePath === null && HOSTS[host].vscode !== undefined) {
204
+ const extensions = await deps.installedExtensions(host, env);
205
+ probePath = bundledClaude(extensions?.find((extension) => extension.id === CLAUDE_EXTENSION_ID));
206
+ }
207
+ if (agent === "claude" ? probePath === null : agentPath === null) {
208
+ return refuse("agent-not-installed", agentNotInstalled(agent, env));
209
+ }
210
+ const { sessions, incomplete, detail: probeDetail } = await findSessions(agent, folder, deps.probes(env, probePath));
211
+ const ranked = rankSessions(sessions, host);
212
+ const rows = ranked.map((session, index) => toRow(session, index === 0));
213
+ const agentName = nameOf(agent);
214
+ const where = `${HOSTS[host].name} on ${folder}`;
215
+ const core = rows.length === 0
216
+ ? `No ${agentName} session is running in ${where}.`
217
+ : `${rows.length} ${agentName} session${rows.length === 1 ? "" : "s"} in ${where}. A plain delegate `
218
+ + `would use ${rows[0].name} (${rows[0].status}).`;
219
+ const detail = incomplete
220
+ ? `${core} Detection was incomplete (${probeDetail ?? "a probe failed"}), so this list may be short.`
221
+ : core;
222
+ const listing = { ok: true, host, agent, mode, folder, sessions: rows, incomplete, detail };
223
+ if (!pretty)
224
+ return emit(io, listing);
225
+ return emitText(io, [
226
+ detail,
227
+ ...rows.map((row) => `${row.recommended ? "*" : " "} ${row.id} ${row.name} — ${row.status}, ${row.detail}`),
228
+ ].join("\n"));
229
+ }
230
+ /** The `claude` the Claude Code extension carries, at the path measured on 2.1.228. */
231
+ function bundledClaude(claudeExt) {
232
+ return claudeExt === undefined ? null : join(claudeExt.path, "resources", "native-binary", "claude");
233
+ }
234
+ /** One listed row. `recommended` is passed in, because the ranking decides it, not this. */
235
+ function toRow(session, recommended) {
236
+ // `rankSessions` filtered on the host, so it is never null here.
237
+ const host = session.host;
238
+ return {
239
+ id: String(session.pid),
240
+ name: displayName(session),
241
+ agent: session.agent,
242
+ host,
243
+ status: session.status ?? "unknown",
244
+ detail: host === "terminal"
245
+ ? session.tty === null ? "Terminal" : `Terminal tab ${basename(session.tty)}`
246
+ : HOSTS[host].name,
247
+ recommended,
248
+ };
249
+ }
250
+ /**
251
+ * What to call a session in a menu.
252
+ *
253
+ * Claude names its own (`team-sync-6c`) and that is what the person sees in the
254
+ * session itself, so it wins. Codex names nothing, so the pid is the identity —
255
+ * and a Claude session too old or too new to carry a name falls back to the
256
+ * same shape rather than to an empty row.
257
+ */
258
+ function displayName(session) {
259
+ if (session.agent === "codex")
260
+ return `Codex · pid ${session.pid}`;
261
+ return session.name ?? `Claude · pid ${session.pid}`;
262
+ }
263
+ function nameOf(agent) {
264
+ return agent === "claude" ? "Claude" : "Codex";
265
+ }
266
+ /**
267
+ * The `session-gone` detail: what was asked for, what is actually there, and
268
+ * why nothing was started instead.
269
+ */
270
+ function sessionGone(pid, agent, host, ranked, incomplete, probeDetail) {
271
+ const agentName = nameOf(agent);
272
+ const now = ranked.length === 0
273
+ ? `No ${agentName} session is in ${HOSTS[host].name} on this folder now`
274
+ : `What is there now: ${ranked.map((session) => `${displayName(session)} (pid ${session.pid})`).join(", ")}`;
275
+ return (`Session ${pid} is no longer a ${agentName} session in ${HOSTS[host].name} on this folder — it exited, `
276
+ + `moved, or the list it came from is stale. ${now}. Nothing was sent and nothing was launched: a chosen `
277
+ + "session is a choice, so this refuses rather than quietly starting a second one. Re-read the inventory "
278
+ + "with `pharos delegate --list`, or pass `--session new` to start a fresh session on purpose."
279
+ + (incomplete
280
+ ? ` Detection was also incomplete (${probeDetail ?? "a probe failed"}), so the session may be running and unseeable.`
281
+ : ""));
282
+ }
283
+ /** The `agent-not-installed` detail — one place, because two routes reach it. */
284
+ function agentNotInstalled(agent, env) {
285
+ const entries = (env["PATH"] ?? "").split(":").filter((entry) => entry !== "").length;
286
+ return (`\`${agent}\` is not on the PATH this ran with (${entries} entries). A coding agent is your `
287
+ + "login and is never installed by pharos — "
288
+ + (agent === "claude" ? "`npm i -g @anthropic-ai/claude-code`" : "`npm i -g @openai/codex`")
289
+ + " puts it there. If it IS installed, `pharos doctor` prints the PATH that was searched.");
290
+ }
291
+ /**
292
+ * The URI the bridge handles.
293
+ *
294
+ * **Every value is percent-encoded TWICE.** VS Code decodes the query once
295
+ * before any extension sees it (`Uri.parse` percent-decodes the query
296
+ * component — measured by the bridge track with `vscode-uri`, the class the
297
+ * workbench uses), so a single encoding breaks on any prompt holding `&`,
298
+ * `=`, `+` or `%`: `text=a%26b` would arrive as `text=a&b` and split. The
299
+ * bridge refuses a query with unknown keys, so that failure would be loud
300
+ * rather than a silently truncated prompt — but loud is still failed.
301
+ *
302
+ * `session` is added only when one was asked for, and it is `agent`/`mode`
303
+ * shaped rather than `text` shaped: digits or the literal `new`, so there is
304
+ * nothing in it for either decode to change. Its absence is what says "the
305
+ * ordinary rule", which is why it is omitted rather than sent empty.
306
+ */
307
+ export function delegateUri(scheme, job) {
308
+ const twice = (value) => encodeURIComponent(encodeURIComponent(value));
309
+ const session = job.session === undefined ? "" : `&session=${job.session.kind === "new" ? NEW_SESSION : job.session.pid}`;
310
+ return `${scheme}://${BRIDGE_EXTENSION_ID}/delegate?folder=${twice(job.folder)}&agent=${job.agent}`
311
+ + `&mode=${job.mode}&text=${twice(job.text)}${session}`;
312
+ }
313
+ async function delegateToVsCode(host, agent, mode, folder, text, agentPath, env, deps, dryRun, pick, refuse, succeed) {
314
+ const spec = HOSTS[host];
315
+ const name = spec.name;
316
+ if (mode === "extension" && agent === "codex") {
317
+ return refuse("unsupported", "The Codex extension takes no prompt from outside — measured on 26.5803: its URI handler "
318
+ + "routes only to its own views and `chatgpt.newChat` takes no arguments. Use --mode terminal "
319
+ + "for Codex; the bridge runs it in an integrated terminal instead.");
320
+ }
321
+ const extensions = await deps.installedExtensions(host, env);
322
+ const bridge = extensions?.find((extension) => extension.id === BRIDGE_EXTENSION_ID);
323
+ if (bridge === undefined) {
324
+ const directory = extensionsDirectory(host, env) ?? "the extensions directory";
325
+ return refuse("bridge-not-installed", `The Pharos bridge (${BRIDGE_EXTENSION_ID}) is not installed in ${name} — looked in ${directory}`
326
+ + (extensions === null ? ", which does not exist: that VS Code has never run" : "")
327
+ + ". `pharos setup --install vscode-bridge` installs the one this pharos ships.");
328
+ }
329
+ const claudeExt = extensions?.find((extension) => extension.id === CLAUDE_EXTENSION_ID);
330
+ const usesExtensionBinary = mode === "extension" && agent === "claude" && claudeExt !== undefined;
331
+ // **The extension route needs no agent on PATH.** The Claude Code extension
332
+ // bundles its own binary at `resources/native-binary/claude` and the bridge
333
+ // runs it through `claude-vscode.terminal.open`, so an agent off PATH is only
334
+ // a refusal when there is no extension to fall back on. This is the ask's
335
+ // "if their VS Code has claude extensions installed … use the extension".
336
+ if (agentPath === null && !usesExtensionBinary) {
337
+ return refuse("agent-not-installed", agentNotInstalled(agent, env));
338
+ }
339
+ // Detect against the bundled binary when that is the only `claude` there, so
340
+ // the prediction still holds; the bridge does its own detection regardless.
341
+ const probePath = agent === "claude" ? agentPath ?? bundledClaude(claudeExt) : null;
342
+ const { sessions, incomplete, detail: probeDetail } = await findSessions(agent, folder, deps.probes(env, probePath));
343
+ const ranked = rankSessions(sessions, host);
344
+ // **`--session <pid>` is pre-checked here AND honoured again by the bridge,
345
+ // and the two are independent on purpose.** The URI is one-way: nothing comes
346
+ // back, so the CLI can never report the bridge's verdict. This check catches a
347
+ // stale pick before an editor is disturbed at all; the bridge's own check is
348
+ // the strict one, because it knows which terminals are ITS window's and this
349
+ // process only knows which VS Code flavour a pid hangs off. A pid that passes
350
+ // here can still be `session-gone` there, and the bridge says so in its
351
+ // notification — that is not a disagreement, it is the narrower question.
352
+ let session;
353
+ if (pick === undefined) {
354
+ session = ranked[0] ?? null;
355
+ }
356
+ else if (pick.kind === "new") {
357
+ session = null;
358
+ }
359
+ else {
360
+ session = ranked.find((found) => found.pid === pick.pid) ?? null;
361
+ if (session === null) {
362
+ return refuse("session-gone", sessionGone(pick.pid, agent, host, ranked, incomplete, probeDetail));
363
+ }
364
+ }
365
+ const uri = delegateUri(spec.vscode.scheme, { folder, agent, mode, text, session: pick });
366
+ const agentName = nameOf(agent);
367
+ const claudeExtInstalled = mode === "extension" && agent === "claude" ? claudeExt !== undefined : true;
368
+ // The bridge decides; this is the same detection it runs, so the prediction
369
+ // is honest and the wording says whose call it is. One tense throughout —
370
+ // `would` in a dry run, plain past/present otherwise.
371
+ const hand = dryRun ? "Would hand this to" : "Handed to";
372
+ const asked = pick?.kind !== "new"
373
+ ? ""
374
+ : ranked.length === 0
375
+ ? " A fresh session was asked for; none was running there anyway."
376
+ : " A fresh session was asked for, so the running one is not reused.";
377
+ const core = session !== null
378
+ ? `${hand} the Pharos bridge in ${name}, which ${dryRun ? "would send" : "sends"} it to the `
379
+ + `${agentName} session there${describeStatus(session)}.`
380
+ : mode === "extension"
381
+ ? `${hand} the Pharos bridge in ${name}, which ${dryRun ? "would open" : "opens"} it in the `
382
+ + "Claude Code extension."
383
+ + (claudeExtInstalled ? "" : " That extension is not installed there, so the bridge falls back to an integrated terminal.")
384
+ : `${hand} the Pharos bridge in ${name}, which ${dryRun ? "would start" : "starts"} ${agentName} `
385
+ + `in an integrated terminal in ${folder}.`;
386
+ // A deliberate new session makes "a session may exist that was not seen"
387
+ // beside the point: one was not wanted. So the two notes are exclusive.
388
+ const detail = pick?.kind === "new"
389
+ ? `${core}${asked}`
390
+ : session === null && incomplete
391
+ ? `${core} Detection was incomplete (${probeDetail ?? "a probe failed"}); a running session may exist that could not be found.`
392
+ : core;
393
+ if (!dryRun) {
394
+ try {
395
+ await deps.open(uri);
396
+ }
397
+ catch (error) {
398
+ throw new CliError(`\`open\` could not hand the URI to ${name}: ${messageOf(error)}`, "internal", EXIT_FAILED, { host, uri });
399
+ }
400
+ }
401
+ return succeed({
402
+ action: session !== null ? "sent" : "launched",
403
+ session: report(session),
404
+ detail,
405
+ uri,
406
+ ...(dryRun ? { sessions: ranked.map((found, index) => toRow(found, index === 0)) } : {}),
407
+ });
408
+ }
409
+ /**
410
+ * Terminal.app — measured on Terminal 2.15 with Claude Code 2.1.268.
411
+ *
412
+ * `do script … in tab` writes to the tab's tty as typed input and follows it
413
+ * with a return, which the running agent's input box submits. A multi-line
414
+ * prompt is wrapped in bracketed paste so it lands as one message (see
415
+ * `delegate/quote.ts`). With no session in a Terminal tab, a window is opened
416
+ * running the agent with the prompt as its first message.
417
+ *
418
+ * Both are Apple Events. The first time, macOS asks whether the RESPONSIBLE
419
+ * process — Pharos.app when the app ran this, your terminal when you did —
420
+ * may control Terminal; a refusal comes back as `-1743` and is reported as
421
+ * `automation-denied` with the Settings pane named.
422
+ */
423
+ async function delegateToTerminal(agent, folder, text, agentPath, env, deps, dryRun, pick, refuse, succeed) {
424
+ const { sessions, incomplete, detail: probeDetail } = await findSessions(agent, folder, deps.probes(env, agent === "claude" ? agentPath : null));
425
+ const ranked = rankSessions(sessions, "terminal");
426
+ const rows = () => ranked.map((found, index) => toRow(found, index === 0));
427
+ let session;
428
+ if (pick === undefined) {
429
+ session = ranked[0] ?? null;
430
+ }
431
+ else if (pick.kind === "new") {
432
+ session = null;
433
+ }
434
+ else {
435
+ session = ranked.find((found) => found.pid === pick.pid) ?? null;
436
+ if (session === null) {
437
+ return refuse("session-gone", sessionGone(pick.pid, agent, "terminal", ranked, incomplete, probeDetail));
438
+ }
439
+ }
440
+ const agentName = nameOf(agent);
441
+ // `rankSessions` already dropped tty-less sessions, so `session` is a real
442
+ // send target. A found session tells us where it is; `[...new Set(…)]` so two
443
+ // sessions in one app do not read as "Navarch and Navarch".
444
+ const elsewhere = sessions.filter((found) => found.host !== "terminal");
445
+ const elsewhereApps = [
446
+ ...new Set(elsewhere.map((found) => (found.host === null ? "another app" : HOSTS[found.host].name))),
447
+ ];
448
+ const elsewhereNote = elsewhereApps.length === 0 || pick?.kind === "new"
449
+ ? ""
450
+ : ` A ${agentName} session on this folder is running in ${elsewhereApps.join(" and ")}, not in Terminal.`;
451
+ // Both of these answer "why did you not use a running session", which is not
452
+ // a question when a fresh one was asked for.
453
+ const incompleteNote = session === null && incomplete && pick?.kind !== "new"
454
+ ? ` Detection was incomplete (${probeDetail ?? "a probe failed"}); a running session may exist that could not be found.`
455
+ : "";
456
+ const askedNote = pick?.kind !== "new"
457
+ ? ""
458
+ : ranked.length === 0
459
+ ? " A fresh session was asked for; none was running in Terminal anyway."
460
+ : ` A fresh session was asked for, so the ${ranked.length === 1 ? "one" : String(ranked.length)} already `
461
+ + `running in Terminal ${ranked.length === 1 ? "was" : "were"} left alone.`;
462
+ if (session !== null && session.tty !== null) {
463
+ if (dryRun) {
464
+ return succeed({
465
+ action: "sent",
466
+ session: report(session),
467
+ detail: `Would type the prompt into the ${agentName} session in Terminal${describeStatus(session)}.`,
468
+ sessions: rows(),
469
+ });
470
+ }
471
+ const result = await appleEvent(deps, SEND_TO_TAB_SCRIPT, [session.tty, asTypedInput(text)], refuse);
472
+ if (typeof result !== "string")
473
+ return result;
474
+ if (result.trim() === "sent") {
475
+ return succeed({
476
+ action: "sent",
477
+ session: report(session),
478
+ detail: `Sent to the ${agentName} session in Terminal${describeStatus(session)}.`,
479
+ });
480
+ }
481
+ // The process tree says Terminal, but no window of this Terminal has a tab
482
+ // on that tty — a session in a tab that was closed, or a Terminal this
483
+ // instance cannot see.
484
+ //
485
+ // **Which way that falls depends on whether a session was NAMED.** Without
486
+ // `--session` a new window is the honest outcome and the detail says why;
487
+ // with it, opening a window would be exactly the silent substitution
488
+ // `--session` exists to prevent, so it refuses instead — and this is the
489
+ // case the pre-check cannot catch, because only Terminal knows its tabs.
490
+ if (pick?.kind === "pid") {
491
+ return refuse("session-gone", `${agentName} session ${session.pid} is still attributed to Terminal, but no Terminal tab holds its `
492
+ + `tty ${session.tty} — the tab was closed, or it belongs to a Terminal this process cannot see. `
493
+ + "Nothing was sent and no window was opened, because a chosen session is a choice. Re-read the "
494
+ + "inventory with `pharos delegate --list`, or pass `--session new` to start a fresh session.");
495
+ }
496
+ const launched = await launch(deps, folder, agentPath, text, refuse);
497
+ if (typeof launched !== "string")
498
+ return launched;
499
+ return succeed({
500
+ action: "launched",
501
+ session: null,
502
+ detail: `Opened a new Terminal window in ${folder} running ${agentName} with the prompt, because the `
503
+ + `${agentName} session attributed to Terminal (pid ${session.pid}) holds no tab on tty `
504
+ + `${session.tty} that could be typed into.`,
505
+ });
506
+ }
507
+ const opened = dryRun ? "Would open" : "Opened";
508
+ const detail = `${opened} a new Terminal window in ${folder} running ${agentName} with the prompt.`
509
+ + `${askedNote}${elsewhereNote}${incompleteNote}`;
510
+ if (dryRun) {
511
+ return succeed({ action: "launched", session: null, detail, sessions: rows() });
512
+ }
513
+ const launched = await launch(deps, folder, agentPath, text, refuse);
514
+ if (typeof launched !== "string")
515
+ return launched;
516
+ return succeed({ action: "launched", session: null, detail });
517
+ }
518
+ async function launch(deps, folder, agentPath, text, refuse) {
519
+ return appleEvent(deps, LAUNCH_SCRIPT, [launchCommand(folder, agentPath, text)], refuse);
520
+ }
521
+ /**
522
+ * Run one AppleScript, turning the Automation refusal into its reason id and
523
+ * anything else into the CLI's ordinary failure.
524
+ *
525
+ * `-1743` is `errAEEventNotPermitted`: the responsible process is not allowed
526
+ * to send Apple Events to Terminal. It is the one error that is a setting
527
+ * rather than a fault, so it is the one that gets a stable id.
528
+ */
529
+ async function appleEvent(deps, source, args, refuse) {
530
+ try {
531
+ return await deps.osascript(source, args);
532
+ }
533
+ catch (error) {
534
+ const message = messageOf(error);
535
+ if (/-1743\b/.test(message) || /not authori[sz]ed to send apple events/i.test(message)) {
536
+ return refuse("automation-denied", "macOS refused to let this process control Terminal (Apple Event error -1743). Allow it "
537
+ + "in System Settings ▸ Privacy & Security ▸ Automation: under the app that ran this "
538
+ + "command — Pharos when the app did, your terminal app when you did — switch on "
539
+ + "Terminal, then try again. If no prompt ever appeared, the app was denied once and "
540
+ + "macOS does not ask twice.");
541
+ }
542
+ throw new CliError(`Terminal did not take the Apple Event: ${message}`, "internal", EXIT_FAILED);
543
+ }
544
+ }
545
+ function describeStatus(session) {
546
+ const parts = [session.status ?? "status unknown", `pid ${session.pid}`];
547
+ if (session.tty !== null)
548
+ parts.push(session.tty);
549
+ return ` (${parts.join(", ")})`;
550
+ }
551
+ function report(session) {
552
+ if (session === null)
553
+ return null;
554
+ return { pid: session.pid, cwd: session.cwd, name: session.name, status: session.status, tty: session.tty };
555
+ }
556
+ function emitOutcome(io, pretty, outcome) {
557
+ return pretty ? emitText(io, outcome.detail) : emit(io, outcome);
558
+ }
559
+ function emitRefusal(io, pretty, refusal) {
560
+ if (pretty)
561
+ io.stdout(`${refusal.reason}: ${refusal.detail}`);
562
+ else
563
+ io.stdout(JSON.stringify(refusal, undefined, 2));
564
+ return EXIT_USAGE;
565
+ }
566
+ function oneOf(value, flag, allowed, guard) {
567
+ const given = (value ?? "").trim();
568
+ if (given === "")
569
+ throw usageError(`${flag} is required: one of ${allowed.join(", ")}.`, { flag, allowed });
570
+ if (!guard(given)) {
571
+ throw usageError(`${flag} takes one of ${allowed.join(", ")}, not ${JSON.stringify(given)}.`, {
572
+ flag,
573
+ given,
574
+ allowed,
575
+ });
576
+ }
577
+ return given;
578
+ }
579
+ function messageOf(error) {
580
+ return error instanceof Error ? error.message : String(error);
581
+ }
582
+ //# sourceMappingURL=delegate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delegate.js","sourceRoot":"","sources":["../../src/commands/delegate.ts"],"names":[],"mappings":"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"}
@@ -207,6 +207,14 @@ export declare function authCheck(base: Omit<Check, "ok" | "install">, accounts:
207
207
  * is a real fault with a real fix, and the fix is named for the fault.
208
208
  */
209
209
  export declare function repoAccessCheck(client: GitHubClient, bindings: readonly RepoBinding[], configPath: string): Promise<Check>;
210
+ /**
211
+ * Where a bare command name actually resolves, by walking `PATH` in order.
212
+ *
213
+ * Deliberately not `which`: spawning a shell to answer this would inherit a
214
+ * DIFFERENT environment from the one the probes just ran in, which is the exact
215
+ * class of mistake this command exists to catch.
216
+ */
217
+ export declare function resolveOnPath(executable: string, env: NodeJS.ProcessEnv): Promise<string | null>;
210
218
  /**
211
219
  * The mark beside one repository — and there are **three** of them, not two.
212
220
  *