very-happy-cli 0.2.155 → 0.2.157
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/{AcpBackend-DmFcRh54.cjs → AcpBackend-BymWX-LI.cjs} +2 -2
- package/dist/{AcpBackend-DVB0nzgR.mjs → AcpBackend-Cy18U7yw.mjs} +2 -2
- package/dist/{AcpSessionManager-CWaSYTnT.cjs → AcpSessionManager-BF7zBGAi.cjs} +1 -1
- package/dist/{AcpSessionManager-dGDgNb-p.mjs → AcpSessionManager-Ds8rcp95.mjs} +1 -1
- package/dist/{agentGuidance-BWxFC6UL.mjs → agentGuidance-CU6YD_Ms.mjs} +560 -29
- package/dist/{agentGuidance-un7YPryB.cjs → agentGuidance-Db76O1kw.cjs} +579 -28
- package/dist/{agentHome-aucT8BHw.cjs → agentHome-B0CLy0Qx.cjs} +2 -2
- package/dist/{agentHome-ByLb2HFg.mjs → agentHome-BaJ9xtxB.mjs} +2 -2
- package/dist/{auto-BQnD6gVx.mjs → auto-B1YAwaeU.mjs} +6 -6
- package/dist/{auto-P9RoJaY0.cjs → auto-DqKGFq8U.cjs} +6 -6
- package/dist/codex/happyMcpStdioBridge.cjs +2 -2
- package/dist/codex/happyMcpStdioBridge.mjs +2 -2
- package/dist/{config-BoePh9PX.cjs → config-CzkBjZnV.cjs} +4 -4
- package/dist/{config-BPZ2Y6o8.mjs → config-aAbhJllb.mjs} +4 -4
- package/dist/{index-BjzdXb9x.mjs → index-BVu8Cufk.mjs} +8 -8
- package/dist/{index-B4oXnbYw.mjs → index-BYU1e81k.mjs} +372 -65
- package/dist/{index-D_fYUxVg.cjs → index-C9QzZsUQ.cjs} +375 -68
- package/dist/{index-DRrLaljt.cjs → index-CTbGqVFY.cjs} +7 -7
- package/dist/{index--KCpVs1c.cjs → index-Cz-uqnJk.cjs} +4 -4
- package/dist/{index-DVVRqaVG.mjs → index-DQcRkI9r.mjs} +4 -4
- package/dist/index.cjs +4 -4
- package/dist/index.mjs +4 -4
- package/dist/{install-CGigiocs.cjs → install-BMlV0Tnr.cjs} +1 -1
- package/dist/{install-DP5aPNEX.mjs → install-BuYnqtVa.mjs} +1 -1
- package/dist/{installTerminalHooks-XrcPvfBs.cjs → installTerminalHooks-BVVOEGhG.cjs} +4 -4
- package/dist/{installTerminalHooks-tIg7mANc.mjs → installTerminalHooks-ELDoqh0A.mjs} +4 -4
- package/dist/lib.cjs +2 -2
- package/dist/lib.d.cts +101 -9
- package/dist/lib.d.mts +101 -9
- package/dist/lib.mjs +2 -2
- package/dist/{limits-C_DW0M0q.mjs → limits-A2c-3M-_.mjs} +162 -11
- package/dist/{limits-DkfHJ3nS.cjs → limits-CyuIt-Vl.cjs} +169 -10
- package/dist/{mcp-o7QglAQM.mjs → mcp-Bo934Kpy.mjs} +4 -4
- package/dist/{mcp-BqlXl10F.cjs → mcp-CXkvnztT.cjs} +4 -4
- package/dist/{piRuntime-BxP4B_zY.cjs → piRuntime-CJjA26oD.cjs} +2 -2
- package/dist/{piRuntime-MjiJI-nV.mjs → piRuntime-DdEY2mE9.mjs} +2 -2
- package/dist/{piTerminal-DYzRcwgb.cjs → piTerminal-CpU3hzrX.cjs} +6 -6
- package/dist/{piTerminal-Dpq6yqKU.mjs → piTerminal-DwWmgumi.mjs} +6 -6
- package/dist/{runGemini-CDlcQ-OA.mjs → runGemini-Cj6oJQ-I.mjs} +6 -6
- package/dist/{runGemini-8Pxh94Fm.cjs → runGemini-DS-0qm0L.cjs} +6 -6
- package/dist/{runOpenClaw-B5FSZIbK.cjs → runOpenClaw-CvSm8oTc.cjs} +5 -5
- package/dist/{runOpenClaw-YkhsgPs0.mjs → runOpenClaw-DUCQxkI-.mjs} +5 -5
- package/dist/{send-CwrYXTPr.cjs → send-CHxobaoI.cjs} +43 -31
- package/dist/{send-DJStmLBv.mjs → send-D5CyRyZ_.mjs} +43 -31
- package/dist/{sessions-MX21NJXd.cjs → sessions-BFlIrKCY.cjs} +133 -49
- package/dist/{sessions-JaVXlSqj.mjs → sessions-DsE01xKc.mjs} +133 -49
- package/dist/{spawn-BaPnjClT.mjs → spawn-CdihhwHs.mjs} +4 -4
- package/dist/{spawn-cIoglKVf.cjs → spawn-HV345RN-.cjs} +4 -4
- package/dist/{teams-DXV5Pwwt.mjs → teams-BE8nMB6O.mjs} +5 -5
- package/dist/{teams-Dqk7F3D-.cjs → teams-BahinMnH.cjs} +5 -5
- package/dist/{todo-Buuqn9gm.cjs → todo-CMMQ6yhU.cjs} +2 -2
- package/dist/{todo-2Z1REhfx.mjs → todo-CuQAkSp2.mjs} +2 -2
- package/dist/{types-a2xsH2UI.cjs → types-B0sSi6eM.cjs} +125 -13
- package/dist/{types-CkbfdRzq.mjs → types-BrGJ7PJz.mjs} +125 -13
- package/package.json +7 -7
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
|
-
import { D as DEFAULT_RECENT_LIMIT, M as MAX_READ_LIMIT, l as listAccountSessions, e as listSessions,
|
|
3
|
-
import { d as readPersistedSessions, i as isValidSessionId } from './limits-
|
|
2
|
+
import { D as DEFAULT_RECENT_LIMIT, M as MAX_READ_LIMIT, l as listAccountSessions, f as fillForeignAccountRows, e as listRemoteSessions, g as listSessions, h as cliPeerSelf, i as listRemotePeers, j as listPeerSessions, s as sendPeerMessage, w as waitForTurnEnd, T as TurnWaitTimeoutError, k as readSessionTranscript, m as waitForRemoteTurnEnd, n as readRemoteTranscript, o as stopSession, p as resolvePermissionRequest, q as archiveSession, t as PEER_SCOPES } from './agentGuidance-CU6YD_Ms.mjs';
|
|
3
|
+
import { d as readPersistedSessions, i as isValidSessionId } from './limits-A2c-3M-_.mjs';
|
|
4
4
|
import { resolve } from 'node:path';
|
|
5
5
|
import 'zod';
|
|
6
6
|
import 'node:crypto';
|
|
@@ -13,6 +13,7 @@ import '@paralleldrive/cuid2';
|
|
|
13
13
|
import 'tweetnacl';
|
|
14
14
|
import 'node:util';
|
|
15
15
|
|
|
16
|
+
const MACHINE_ID_RE = /^[a-zA-Z0-9_-]{1,128}$/;
|
|
16
17
|
const ACTIONS = ["list", "read", "stop", "archive", "approve", "deny", "peers", "message"];
|
|
17
18
|
const ACTIONS_NEEDING_ID = /* @__PURE__ */ new Set(["read", "stop", "archive", "approve", "deny", "message"]);
|
|
18
19
|
const ACTIONS_NEEDING_REQUEST_ID = /* @__PURE__ */ new Set(["approve", "deny"]);
|
|
@@ -65,6 +66,10 @@ function parseSessionsArgs(args) {
|
|
|
65
66
|
const value = args[++i];
|
|
66
67
|
if (value === void 0 || value.trim() === "") throw new Error("--reply-to requires a value");
|
|
67
68
|
options.replyTo = value;
|
|
69
|
+
} else if (arg === "--machine") {
|
|
70
|
+
const value = args[++i];
|
|
71
|
+
if (value === void 0 || !MACHINE_ID_RE.test(value)) throw new Error("--machine requires a machine id");
|
|
72
|
+
options.machine = value;
|
|
68
73
|
} else if (arg === "--tag") {
|
|
69
74
|
const value = args[++i];
|
|
70
75
|
if (value === void 0) throw new Error("--tag requires a value");
|
|
@@ -130,31 +135,45 @@ function parseSessionsArgs(args) {
|
|
|
130
135
|
if (options.cwd !== void 0) throw new Error("--cwd only applies to `sessions peers`");
|
|
131
136
|
}
|
|
132
137
|
if (options.replyTo !== void 0 && options.action !== "message") throw new Error("--reply-to only applies to `sessions message`");
|
|
138
|
+
if (options.machine !== void 0) {
|
|
139
|
+
if (!MACHINE_ACTIONS.has(options.action)) throw new Error("--machine only applies to `sessions list|read|peers|message`");
|
|
140
|
+
if (options.all) throw new Error("--machine cannot be combined with --all (--all already asks every online machine)");
|
|
141
|
+
}
|
|
133
142
|
return options;
|
|
134
143
|
}
|
|
144
|
+
const MACHINE_ACTIONS = /* @__PURE__ */ new Set(["list", "read", "peers", "message"]);
|
|
135
145
|
const SESSIONS_HELP = `
|
|
136
|
-
${chalk.bold("very-happy sessions")} - Inspect and control sessions on this machine (for automation)
|
|
146
|
+
${chalk.bold("very-happy sessions")} - Inspect and control sessions on this machine and, through their daemons, on the account's other machines (for automation)
|
|
137
147
|
|
|
138
148
|
${chalk.bold("Usage:")}
|
|
139
|
-
very-happy sessions list [--all [--include-archived]] [--tag <name>] [--limit <n>] [--json]
|
|
140
|
-
very-happy sessions read <id> [--limit <n>] [--full] [--answer]
|
|
149
|
+
very-happy sessions list [--all [--include-archived]] [--machine <id>] [--tag <name>] [--limit <n>] [--json]
|
|
150
|
+
very-happy sessions read <id> [--machine <id>] [--limit <n>] [--full] [--answer]
|
|
141
151
|
[--wait [--timeout <s>]] [--json]
|
|
142
152
|
very-happy sessions stop <id> [--json]
|
|
143
153
|
very-happy sessions archive <id> [--json]
|
|
144
154
|
very-happy sessions approve <id> <requestId> [--for-session] [--json]
|
|
145
155
|
very-happy sessions deny <id> <requestId> [--reason <text>] [--json]
|
|
146
|
-
very-happy sessions peers [--scope repo|cwd|machine] [--cwd <dir>] [--json]
|
|
147
|
-
very-happy sessions message <id> <text> [--reply-to <msgId>] [--json]
|
|
156
|
+
very-happy sessions peers [--scope repo|cwd|machine] [--cwd <dir>] [--machine <id>] [--json]
|
|
157
|
+
very-happy sessions message <id> <text> [--reply-to <msgId>] [--machine <id>] [--json]
|
|
148
158
|
|
|
149
159
|
${chalk.bold("Actions:")}
|
|
150
160
|
list Running sessions plus recently seen ones, newest first.
|
|
151
161
|
With --all: every session on the account (newest 150, server
|
|
152
|
-
REST), attention first.
|
|
153
|
-
|
|
162
|
+
REST), attention first. Rows this machine cannot decrypt are
|
|
163
|
+
filled in by the online machine that spawned them (\`readable\`,
|
|
164
|
+
\`via\`, \`machine\` in --json; \`decryptable\` stays "this
|
|
165
|
+
machine's own key"); what no online machine holds shows only
|
|
154
166
|
id / active / archived / timestamps / url.
|
|
167
|
+
With --machine <id>: that machine's own listing (its daemon's
|
|
168
|
+
children plus what it saw lately).
|
|
155
169
|
read The tail of a session as a role-tagged transcript, plus where
|
|
156
170
|
the latest turn stands (\`turn\` in --json: ended, status and
|
|
157
|
-
\`answer\` = the agent's reply to the latest prompt).
|
|
171
|
+
\`answer\` = the agent's reply to the latest prompt). A session
|
|
172
|
+
another machine spawned is read through that machine's daemon.
|
|
173
|
+
Both list and read carry \`backgroundTasks\` ({count, tasks[]}):
|
|
174
|
+
async sub-agents / backgrounded commands still running after
|
|
175
|
+
the turn ended \u2014 such a session is NOT idle (absent = the
|
|
176
|
+
daemon or CLI is too old to report it).
|
|
158
177
|
stop SIGTERM the session's process via the local daemon.
|
|
159
178
|
archive Mark the session inactive server-side (it stays resumable).
|
|
160
179
|
approve Answer a pending permission request \`requestId\` with approve \u2014
|
|
@@ -165,13 +184,17 @@ ${chalk.bold("Actions:")}
|
|
|
165
184
|
the last 30 minutes. Default scope \`repo\`: same git repository,
|
|
166
185
|
including its other worktrees (\`sameWorktree\` says which share
|
|
167
186
|
your checkout); \`cwd\`: same directory; \`machine\`: everything.
|
|
168
|
-
|
|
169
|
-
|
|
187
|
+
With --machine <id>: the live sessions on that machine (scope
|
|
188
|
+
\`machine\` unless --cwd names a directory there).
|
|
189
|
+
message Send <text> into a running session. It arrives tagged with the
|
|
190
|
+
sender (the session named by VH_PEER_SESSION_ID when run from a
|
|
170
191
|
managed session's shell, else this CLI) and tells the peer how to
|
|
171
|
-
reply.
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
192
|
+
reply. A session another machine spawned is delivered through
|
|
193
|
+
that machine's daemon, with this host named in the header.
|
|
194
|
+
Refused for sessions that are not running, or terminal mirrors.
|
|
195
|
+
\`delivered\` follows \`very-happy send\`: true only when a
|
|
196
|
+
wrapper was attached before and after the POST (\`stored\` = it
|
|
197
|
+
is on the server anyway).
|
|
175
198
|
|
|
176
199
|
${chalk.bold("Options:")}
|
|
177
200
|
--all list only: account-wide over REST instead of this
|
|
@@ -197,26 +220,31 @@ ${chalk.bold("Options:")}
|
|
|
197
220
|
--cwd <dir> peers only: directory the scope is computed from
|
|
198
221
|
(default: the process cwd, or HAPPY_SESSION_ID's cwd).
|
|
199
222
|
--reply-to <id> message only: the peer message id being answered.
|
|
223
|
+
--machine <id> list / read / peers / message: go through this account
|
|
224
|
+
machine's daemon (its id as the web's machine list shows
|
|
225
|
+
it). read / message: skip the lookup across machines.
|
|
200
226
|
--json Machine-readable output.
|
|
201
227
|
-h, --help Show this help
|
|
202
228
|
|
|
203
229
|
${chalk.bold("Scope:")}
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
the
|
|
230
|
+
Sessions this machine's daemon spawned are handled with the local key in
|
|
231
|
+
~/.happy/sessions.json (pruned after 14 days). Any other session of the
|
|
232
|
+
account is handled by the daemon of the machine that spawned it: that
|
|
233
|
+
machine must be online and on CLI \u2265 0.2.157, the operation runs there with
|
|
234
|
+
its keys, and only the result travels back \u2014 this CLI never holds the
|
|
235
|
+
account content key or another machine's session key. Without --machine
|
|
236
|
+
the online machines are asked in turn which one holds the session.
|
|
237
|
+
approve / deny / stop / archive remain local-only.
|
|
211
238
|
|
|
212
239
|
${chalk.bold("Exit codes:")}
|
|
213
240
|
2 read --wait: the turn had not ended when --timeout ran out (the
|
|
214
241
|
partial state is still printed)
|
|
215
242
|
0 success (approve/deny: the wrapper acknowledged the verdict; check
|
|
216
243
|
\`settled\` in --json to see whether the request has left the pending set)
|
|
217
|
-
1 bad arguments, unknown session, no
|
|
218
|
-
|
|
219
|
-
|
|
244
|
+
1 bad arguments, unknown session, no machine of the account holds it (or
|
|
245
|
+
its machine is offline / too old), request not pending, session not
|
|
246
|
+
online, or the operation failed (including \`stop\` on a session the
|
|
247
|
+
daemon is not running)
|
|
220
248
|
`;
|
|
221
249
|
function formatWait(ms) {
|
|
222
250
|
const minutes = Math.floor(ms / 6e4);
|
|
@@ -225,17 +253,19 @@ function formatWait(ms) {
|
|
|
225
253
|
return `${Math.floor(minutes / 60)}h${minutes % 60}m`;
|
|
226
254
|
}
|
|
227
255
|
function formatAccountSummaryLine(summary) {
|
|
228
|
-
const state = summary.attention ? "[attention]" : summary.live ? "[running here]" : summary.active ? "[active elsewhere]" : summary.archived ? "[archived]" : "[idle]";
|
|
256
|
+
const state = summary.attention ? "[attention]" : summary.live ? summary.machine ? `[running on ${summary.machine.host}]` : "[running here]" : summary.active ? "[active elsewhere]" : summary.archived ? "[archived]" : "[idle]";
|
|
229
257
|
const parts = [summary.id, state];
|
|
230
|
-
if (!summary.
|
|
231
|
-
parts.push("(not
|
|
258
|
+
if (!summary.readable) {
|
|
259
|
+
parts.push("(not readable: no online machine holds its key)");
|
|
232
260
|
} else {
|
|
261
|
+
if (summary.machine) parts.push(`via=${summary.machine.host}`);
|
|
233
262
|
if (summary.title) parts.push(`title="${summary.title}"`);
|
|
234
263
|
if (summary.flavor) parts.push(`agent=${summary.flavor}`);
|
|
235
264
|
if (summary.tags?.length) parts.push(`tags=${summary.tags.join(",")}`);
|
|
236
265
|
if (summary.variant) parts.push(`variant=${summary.variant}`);
|
|
237
266
|
if (summary.machineId) parts.push(`machine=${summary.machineId}`);
|
|
238
267
|
if (summary.cwd) parts.push(`cwd=${summary.cwd}`);
|
|
268
|
+
if (summary.backgroundTasks && summary.backgroundTasks.count > 0) parts.push(formatBackgroundTasks(summary.backgroundTasks));
|
|
239
269
|
for (const request of summary.pending ?? []) {
|
|
240
270
|
parts.push(`pending=${request.id}:${request.tool}${request.waitingMs !== void 0 ? `(${formatWait(request.waitingMs)})` : ""}`);
|
|
241
271
|
}
|
|
@@ -246,6 +276,10 @@ function formatAccountSummaryLine(summary) {
|
|
|
246
276
|
function permissionFailureRecord(sessionId, requestId, error) {
|
|
247
277
|
return { sessionId, requestId, error: error instanceof Error ? error.message : String(error) };
|
|
248
278
|
}
|
|
279
|
+
function formatBackgroundTasks(report) {
|
|
280
|
+
const types = report.tasks.map((task) => task.type).filter(Boolean);
|
|
281
|
+
return `background=${report.count}${types.length ? `(${types.join(",")})` : ""}`;
|
|
282
|
+
}
|
|
249
283
|
function formatSummaryLine(summary) {
|
|
250
284
|
const parts = [summary.id, summary.live ? "[running]" : "[not running]"];
|
|
251
285
|
if (summary.title) parts.push(`title="${summary.title}"`);
|
|
@@ -254,6 +288,7 @@ function formatSummaryLine(summary) {
|
|
|
254
288
|
if (summary.variant) parts.push(`variant=${summary.variant}`);
|
|
255
289
|
if (summary.cwd) parts.push(`cwd=${summary.cwd}`);
|
|
256
290
|
if (summary.pid !== void 0) parts.push(`pid=${summary.pid}`);
|
|
291
|
+
if (summary.backgroundTasks && summary.backgroundTasks.count > 0) parts.push(formatBackgroundTasks(summary.backgroundTasks));
|
|
257
292
|
parts.push(summary.url);
|
|
258
293
|
return parts.join(" ");
|
|
259
294
|
}
|
|
@@ -272,20 +307,48 @@ async function handleSessionsCommand(args) {
|
|
|
272
307
|
}
|
|
273
308
|
try {
|
|
274
309
|
if (options.action === "list" && options.all) {
|
|
275
|
-
const
|
|
310
|
+
const listed = await listAccountSessions({ recentLimit: options.tag ? 150 : options.limit, includeArchived: options.includeArchived });
|
|
311
|
+
const fill = await fillForeignAccountRows(listed);
|
|
312
|
+
let sessions = fill.rows;
|
|
313
|
+
if (options.tag) {
|
|
314
|
+
const wanted = options.tag;
|
|
315
|
+
sessions = sessions.filter((summary) => summary.tags?.includes(wanted) === true);
|
|
316
|
+
const recentLimit = Math.max(0, options.limit ?? DEFAULT_RECENT_LIMIT);
|
|
317
|
+
let idleKept = 0;
|
|
318
|
+
sessions = sessions.filter((summary) => summary.attention || summary.live || idleKept++ < recentLimit);
|
|
319
|
+
}
|
|
276
320
|
if (options.json) {
|
|
277
|
-
console.log(JSON.stringify({ sessions, scope: "account" }));
|
|
321
|
+
console.log(JSON.stringify({ sessions, scope: "account", machines: { asked: fill.asked, skipped: fill.skipped } }));
|
|
278
322
|
} else if (sessions.length === 0) {
|
|
279
|
-
console.log(options.tag ? `No
|
|
323
|
+
console.log(options.tag ? `No readable sessions tagged "${options.tag}" on this account.` : "No sessions found on this account.");
|
|
280
324
|
} else {
|
|
281
325
|
for (const summary of sessions) console.log(formatAccountSummaryLine(summary));
|
|
282
|
-
const foreign = sessions.filter((summary) => !summary.
|
|
326
|
+
const foreign = sessions.filter((summary) => !summary.readable).length;
|
|
327
|
+
const filled = fill.asked.reduce((n, a) => n + a.filled, 0);
|
|
328
|
+
if (filled > 0) {
|
|
329
|
+
console.log(chalk.dim(`${filled} session(s) read through their own machine's daemon (${fill.asked.filter((a) => a.filled > 0).map((a) => a.host ?? a.machineId).join(", ")}).`));
|
|
330
|
+
}
|
|
331
|
+
for (const asked of fill.asked.filter((a) => a.error)) console.log(chalk.dim(`machine ${asked.machineId}: ${asked.error}`));
|
|
283
332
|
if (foreign > 0) {
|
|
284
|
-
|
|
333
|
+
const why = fill.skipped.length > 0 ? ` (${fill.skipped.map((s) => `${s.machineId}: ${s.reason}`).join("; ")})` : "";
|
|
334
|
+
console.log(chalk.dim(`${foreign} session(s) belong to a machine that is not reachable right now${why}.`));
|
|
285
335
|
}
|
|
286
336
|
}
|
|
287
337
|
process.exit(0);
|
|
288
338
|
}
|
|
339
|
+
if (options.action === "list" && options.machine) {
|
|
340
|
+
const listing = await listRemoteSessions(options.machine, { tag: options.tag, limit: options.limit });
|
|
341
|
+
const sessions = listing.sessions;
|
|
342
|
+
if (options.json) {
|
|
343
|
+
console.log(JSON.stringify({ sessions, machine: { id: listing.machineId, host: listing.host } }));
|
|
344
|
+
} else if (sessions.length === 0) {
|
|
345
|
+
console.log(options.tag ? `No sessions tagged "${options.tag}" on ${listing.host}.` : `No sessions found on ${listing.host}.`);
|
|
346
|
+
} else {
|
|
347
|
+
console.log(chalk.dim(`machine ${listing.host} (${listing.machineId})`));
|
|
348
|
+
for (const summary of sessions) console.log(formatSummaryLine(summary));
|
|
349
|
+
}
|
|
350
|
+
process.exit(0);
|
|
351
|
+
}
|
|
289
352
|
if (options.action === "list") {
|
|
290
353
|
const sessions = await listSessions({ tag: options.tag, recentLimit: options.limit });
|
|
291
354
|
if (options.json) {
|
|
@@ -302,12 +365,13 @@ async function handleSessionsCommand(args) {
|
|
|
302
365
|
const persisted = readPersistedSessions();
|
|
303
366
|
const context = { self: () => cliPeerSelf(process.env, cwd, persisted), readPersisted: () => persisted };
|
|
304
367
|
if (options.action === "peers") {
|
|
305
|
-
const listing = await listPeerSessions(context, options.scope ?? "repo");
|
|
368
|
+
const listing = options.machine ? await listRemotePeers(options.machine, { ...options.scope ? { scope: options.scope } : {}, ...options.cwd ? { cwd: options.cwd } : {} }) : await listPeerSessions(context, options.scope ?? "repo");
|
|
306
369
|
if (options.json) {
|
|
307
370
|
console.log(JSON.stringify(listing));
|
|
308
371
|
} else if (listing.peers.length === 0) {
|
|
309
|
-
console.log(`No other live sessions in scope "${listing.scope}"${listing.self.repoRoot ? ` (repo ${listing.self.repoRoot})` : ""}.`);
|
|
372
|
+
console.log(`No other live sessions in scope "${listing.scope}"${listing.self.repoRoot ? ` (repo ${listing.self.repoRoot})` : ""}${"host" in listing ? ` on ${listing.host}` : ""}.`);
|
|
310
373
|
} else {
|
|
374
|
+
if ("host" in listing) console.log(chalk.dim(`machine ${String(listing.host)} (${String(listing.machineId)})`));
|
|
311
375
|
for (const peer of listing.peers) {
|
|
312
376
|
const parts = [peer.sessionId, `[${peer.kind === "mirror" ? "terminal" : "running"}]`];
|
|
313
377
|
if (peer.title) parts.push(`title="${peer.title}"`);
|
|
@@ -322,9 +386,9 @@ async function handleSessionsCommand(args) {
|
|
|
322
386
|
}
|
|
323
387
|
const target = options.sessionId;
|
|
324
388
|
try {
|
|
325
|
-
const result = await sendPeerMessage(context, { to: target, body: options.text, replyTo: options.replyTo });
|
|
389
|
+
const result = await sendPeerMessage(context, { to: target, body: options.text, replyTo: options.replyTo, ...options.machine ? { machineId: options.machine } : {} });
|
|
326
390
|
if (options.json) console.log(JSON.stringify(result));
|
|
327
|
-
else if (result.delivered) console.log(`Message ${result.messageId} delivered to ${target}
|
|
391
|
+
else if (result.delivered) console.log(`Message ${result.messageId} delivered to ${target}${result.machine ? ` on ${result.machine.host}` : ""}
|
|
328
392
|
${result.url}`);
|
|
329
393
|
else console.error(chalk.yellow("Not delivered:"), result.error ?? `session is ${result.status}`, result.stored ? "(stored server-side, unread)" : "");
|
|
330
394
|
process.exit(result.delivered ? 0 : 1);
|
|
@@ -336,24 +400,44 @@ ${result.url}`);
|
|
|
336
400
|
const sessionId = options.sessionId;
|
|
337
401
|
if (options.action === "read") {
|
|
338
402
|
let timedOut = false;
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
403
|
+
const local = !options.machine && readPersistedSessions()[sessionId] !== void 0;
|
|
404
|
+
let result;
|
|
405
|
+
if (local) {
|
|
406
|
+
if (options.wait) {
|
|
407
|
+
try {
|
|
408
|
+
await waitForTurnEnd(sessionId, { timeoutMs: (options.timeoutSec ?? 600) * 1e3 });
|
|
409
|
+
} catch (error) {
|
|
410
|
+
if (!(error instanceof TurnWaitTimeoutError)) throw error;
|
|
411
|
+
timedOut = true;
|
|
412
|
+
console.error(chalk.yellow("Timeout:"), error.message);
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
result = await readSessionTranscript(sessionId, options.limit ?? 20, { full: options.full });
|
|
416
|
+
} else {
|
|
417
|
+
const readOptions = { limit: options.limit ?? 20, full: options.full, ...options.machine ? { machineId: options.machine } : {} };
|
|
418
|
+
let remote;
|
|
419
|
+
if (options.wait) {
|
|
420
|
+
const timeoutMs = (options.timeoutSec ?? 600) * 1e3;
|
|
421
|
+
const waited = await waitForRemoteTurnEnd(sessionId, { ...readOptions, timeoutMs });
|
|
422
|
+
remote = waited.read;
|
|
423
|
+
if (waited.timedOut) {
|
|
424
|
+
timedOut = true;
|
|
425
|
+
console.error(chalk.yellow("Timeout:"), `Session ${sessionId} on ${remote.host}: the latest turn did not end within ${Math.round(timeoutMs / 1e3)}s`);
|
|
426
|
+
}
|
|
427
|
+
} else {
|
|
428
|
+
remote = await readRemoteTranscript(sessionId, readOptions);
|
|
346
429
|
}
|
|
430
|
+
const { machineId, host, ...rest } = remote;
|
|
431
|
+
result = { ...rest, machine: { id: machineId, host } };
|
|
347
432
|
}
|
|
348
|
-
const result = await readSessionTranscript(sessionId, options.limit ?? 20, { full: options.full });
|
|
349
433
|
if (options.json) {
|
|
350
|
-
console.log(JSON.stringify(options.answer ? { sessionId, turn: result.turn } : result));
|
|
434
|
+
console.log(JSON.stringify(options.answer ? { sessionId, turn: result.turn, ...result.machine ? { machine: result.machine } : {} } : result));
|
|
351
435
|
} else if (options.answer) {
|
|
352
436
|
if (result.turn.answer.length > 0) console.log(result.turn.answer);
|
|
353
437
|
else console.error(chalk.dim("(the agent has not replied to the latest prompt yet)"));
|
|
354
438
|
} else {
|
|
355
|
-
console.log(formatSummaryLine(result.summary));
|
|
356
|
-
console.log(`--- last ${result.messageCount} message(s) ---`);
|
|
439
|
+
console.log(formatSummaryLine(result.summary) + (result.machine ? chalk.dim(` machine=${result.machine.host}`) : ""));
|
|
440
|
+
console.log(`--- last ${result.messageCount} message(s)${result.truncated ? " (truncated to fit the RPC budget)" : ""} ---`);
|
|
357
441
|
console.log(result.transcript.length > 0 ? result.transcript : "(no readable conversation content in this range)");
|
|
358
442
|
const turn = result.turn;
|
|
359
443
|
console.log(chalk.dim(`--- latest turn: ${turn.ended ? `ended (${turn.status ?? "unknown"})` : "running"}${turn.error ? ` \u2014 ${turn.error}` : ""} ---`));
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
2
|
import { readFileSync, statSync } from 'node:fs';
|
|
3
3
|
import { resolve } from 'node:path';
|
|
4
|
-
import { d as readPersistedSessions, k as checkIfDaemonRunningAndCleanupStaleState, l as logger, m as spawnDaemonSession, n as stopDaemonSession } from './limits-
|
|
5
|
-
import { r as resolveSpawnPermissionMode, c as resolveFirstMessageMeta, i as isValidSpawnOrigin, s as sanitizeSpawnPermissionMode, A as ALLOWED_SPAWN_PERMISSION_MODES, S as SPAWN_AGENTS } from './index-
|
|
6
|
-
import { f as forkSession, g as getProjectPath, F as ForkSourceMissingError, C as CodexAppServerClient, c as forkCodexThread } from './types-
|
|
7
|
-
import {
|
|
4
|
+
import { d as readPersistedSessions, k as checkIfDaemonRunningAndCleanupStaleState, l as logger, m as spawnDaemonSession, n as stopDaemonSession } from './limits-A2c-3M-_.mjs';
|
|
5
|
+
import { r as resolveSpawnPermissionMode, c as resolveFirstMessageMeta, i as isValidSpawnOrigin, s as sanitizeSpawnPermissionMode, A as ALLOWED_SPAWN_PERMISSION_MODES, S as SPAWN_AGENTS } from './index-BYU1e81k.mjs';
|
|
6
|
+
import { f as forkSession, g as getProjectPath, F as ForkSourceMissingError, C as CodexAppServerClient, c as forkCodexThread } from './types-BrGJ7PJz.mjs';
|
|
7
|
+
import { F as readSessionMetadata, x as sessionWebUrl, G as waitForSessionKey, H as sendUserMessage } from './agentGuidance-CU6YD_Ms.mjs';
|
|
8
8
|
import 'zod';
|
|
9
9
|
import '@paralleldrive/cuid2';
|
|
10
10
|
import 'node:fs/promises';
|
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
var chalk = require('chalk');
|
|
4
4
|
var node_fs = require('node:fs');
|
|
5
5
|
var path = require('node:path');
|
|
6
|
-
var persistence = require('./limits-
|
|
7
|
-
var index = require('./index-
|
|
8
|
-
var index$1 = require('./types-
|
|
9
|
-
var agentGuidance = require('./agentGuidance-
|
|
6
|
+
var persistence = require('./limits-CyuIt-Vl.cjs');
|
|
7
|
+
var index = require('./index-C9QzZsUQ.cjs');
|
|
8
|
+
var index$1 = require('./types-B0sSi6eM.cjs');
|
|
9
|
+
var agentGuidance = require('./agentGuidance-Db76O1kw.cjs');
|
|
10
10
|
require('zod');
|
|
11
11
|
require('@paralleldrive/cuid2');
|
|
12
12
|
require('node:fs/promises');
|
|
@@ -2,9 +2,9 @@ import { homedir } from 'node:os';
|
|
|
2
2
|
import { readFile } from 'node:fs/promises';
|
|
3
3
|
import { z } from 'zod';
|
|
4
4
|
import { randomUUID } from 'node:crypto';
|
|
5
|
-
import {
|
|
6
|
-
import { h as readCredentialsForConfiguredRelay } from './limits-
|
|
7
|
-
import { a as installTeamSkill, i as installAutomationSkill } from './install-
|
|
5
|
+
import { I as teamRequest, J as createTeamsClient } from './agentGuidance-CU6YD_Ms.mjs';
|
|
6
|
+
import { h as readCredentialsForConfiguredRelay } from './limits-A2c-3M-_.mjs';
|
|
7
|
+
import { a as installTeamSkill, i as installAutomationSkill } from './install-BuYnqtVa.mjs';
|
|
8
8
|
import 'node:fs';
|
|
9
9
|
import 'node:path';
|
|
10
10
|
import 'axios';
|
|
@@ -13,8 +13,8 @@ import '@paralleldrive/cuid2';
|
|
|
13
13
|
import 'tweetnacl';
|
|
14
14
|
import 'chalk';
|
|
15
15
|
import 'node:util';
|
|
16
|
-
import './index-
|
|
17
|
-
import './types-
|
|
16
|
+
import './index-BYU1e81k.mjs';
|
|
17
|
+
import './types-BrGJ7PJz.mjs';
|
|
18
18
|
import 'node:events';
|
|
19
19
|
import 'child_process';
|
|
20
20
|
import 'util';
|
|
@@ -4,9 +4,9 @@ var os = require('node:os');
|
|
|
4
4
|
var promises = require('node:fs/promises');
|
|
5
5
|
var z = require('zod');
|
|
6
6
|
var node_crypto = require('node:crypto');
|
|
7
|
-
var agentGuidance = require('./agentGuidance-
|
|
8
|
-
var persistence = require('./limits-
|
|
9
|
-
var install = require('./install-
|
|
7
|
+
var agentGuidance = require('./agentGuidance-Db76O1kw.cjs');
|
|
8
|
+
var persistence = require('./limits-CyuIt-Vl.cjs');
|
|
9
|
+
var install = require('./install-BMlV0Tnr.cjs');
|
|
10
10
|
require('node:fs');
|
|
11
11
|
require('node:path');
|
|
12
12
|
require('axios');
|
|
@@ -15,8 +15,8 @@ require('@paralleldrive/cuid2');
|
|
|
15
15
|
require('tweetnacl');
|
|
16
16
|
require('chalk');
|
|
17
17
|
require('node:util');
|
|
18
|
-
require('./index-
|
|
19
|
-
require('./types-
|
|
18
|
+
require('./index-C9QzZsUQ.cjs');
|
|
19
|
+
require('./types-B0sSi6eM.cjs');
|
|
20
20
|
require('node:events');
|
|
21
21
|
require('child_process');
|
|
22
22
|
require('util');
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var persistence = require('./limits-
|
|
4
|
-
var agentGuidance = require('./agentGuidance-
|
|
3
|
+
var persistence = require('./limits-CyuIt-Vl.cjs');
|
|
4
|
+
var agentGuidance = require('./agentGuidance-Db76O1kw.cjs');
|
|
5
5
|
require('zod');
|
|
6
6
|
require('@paralleldrive/cuid2');
|
|
7
7
|
require('node:fs/promises');
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { h as readCredentialsForConfiguredRelay, j as createBuiltinTodoClient, c as configuration, B as BUILTIN_TODO_SKILL } from './limits-
|
|
2
|
-
import {
|
|
1
|
+
import { h as readCredentialsForConfiguredRelay, j as createBuiltinTodoClient, c as configuration, B as BUILTIN_TODO_SKILL } from './limits-A2c-3M-_.mjs';
|
|
2
|
+
import { C as readTeamScope, E as teamScopePath } from './agentGuidance-CU6YD_Ms.mjs';
|
|
3
3
|
import 'zod';
|
|
4
4
|
import '@paralleldrive/cuid2';
|
|
5
5
|
import 'node:fs/promises';
|