@hydra-acp/cli 0.1.41 → 0.1.43
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 +113 -17
- package/dist/index.d.ts +3 -0
- package/dist/index.js +10 -3
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -985,7 +985,8 @@ function mergeMeta(passthrough, ours) {
|
|
|
985
985
|
function sessionListEntryToWire(entry) {
|
|
986
986
|
const hydraMeta = {
|
|
987
987
|
attachedClients: entry.attachedClients,
|
|
988
|
-
status: entry.status
|
|
988
|
+
status: entry.status,
|
|
989
|
+
busy: entry.busy
|
|
989
990
|
};
|
|
990
991
|
if (entry.agentId !== void 0) {
|
|
991
992
|
hydraMeta.agentId = entry.agentId;
|
|
@@ -1131,6 +1132,10 @@ var init_types = __esm({
|
|
|
1131
1132
|
updatedAt: z3.string(),
|
|
1132
1133
|
attachedClients: z3.number().int().nonnegative(),
|
|
1133
1134
|
status: z3.enum(["live", "cold"]).default("live"),
|
|
1135
|
+
// True while the session is mid-turn (an agent prompt is in flight).
|
|
1136
|
+
// Always false for cold sessions. Lets pickers render a busy dot
|
|
1137
|
+
// without having to attach.
|
|
1138
|
+
busy: z3.boolean().default(false),
|
|
1134
1139
|
_meta: z3.record(z3.unknown()).optional()
|
|
1135
1140
|
});
|
|
1136
1141
|
SessionListEntryWire = z3.object({
|
|
@@ -4449,7 +4454,8 @@ async function listSessions(target, opts = {}, fetchImpl = fetch) {
|
|
|
4449
4454
|
currentUsage: s.currentUsage,
|
|
4450
4455
|
title: s.title,
|
|
4451
4456
|
importedFromMachine: s.importedFromMachine,
|
|
4452
|
-
importedFromUpstreamSessionId: s.importedFromUpstreamSessionId
|
|
4457
|
+
importedFromUpstreamSessionId: s.importedFromUpstreamSessionId,
|
|
4458
|
+
busy: s.busy
|
|
4453
4459
|
}));
|
|
4454
4460
|
}
|
|
4455
4461
|
async function killSession(target, id, fetchImpl = fetch) {
|
|
@@ -4573,7 +4579,7 @@ function toRow(s, now = Date.now()) {
|
|
|
4573
4579
|
return {
|
|
4574
4580
|
session: stripHydraSessionPrefix(s.sessionId),
|
|
4575
4581
|
upstream: formatUpstreamCell(s.upstreamSessionId, s.importedFromMachine),
|
|
4576
|
-
state: formatState(s.status, s.
|
|
4582
|
+
state: formatState(s.status, s.busy),
|
|
4577
4583
|
agent: formatAgentCell(s.agentId, s.currentUsage),
|
|
4578
4584
|
age: formatRelativeAge(s.updatedAt, now),
|
|
4579
4585
|
title: s.title ?? "-",
|
|
@@ -4589,11 +4595,11 @@ function formatUpstreamCell(upstreamSessionId, importedFromMachine) {
|
|
|
4589
4595
|
}
|
|
4590
4596
|
return "-";
|
|
4591
4597
|
}
|
|
4592
|
-
function formatState(status,
|
|
4598
|
+
function formatState(status, busy) {
|
|
4593
4599
|
if (status === "cold") {
|
|
4594
4600
|
return "COLD";
|
|
4595
4601
|
}
|
|
4596
|
-
return
|
|
4602
|
+
return busy ? "LIVE\u2022" : "LIVE";
|
|
4597
4603
|
}
|
|
4598
4604
|
function computeWidths(rows) {
|
|
4599
4605
|
return {
|
|
@@ -6158,7 +6164,7 @@ function writeStyled(term, text, style) {
|
|
|
6158
6164
|
term(text);
|
|
6159
6165
|
return;
|
|
6160
6166
|
case "thought":
|
|
6161
|
-
term.brightBlack.
|
|
6167
|
+
term.brightBlack.noFormat(text);
|
|
6162
6168
|
return;
|
|
6163
6169
|
case "tool":
|
|
6164
6170
|
term.brightBlue.noFormat(text);
|
|
@@ -7029,6 +7035,10 @@ uncaught: ${err.stack ?? err.message}
|
|
|
7029
7035
|
this.handleCsi27Stdin(text);
|
|
7030
7036
|
return;
|
|
7031
7037
|
}
|
|
7038
|
+
if (text.includes("\x1B[200~")) {
|
|
7039
|
+
this.handleRawStdinSegment(text);
|
|
7040
|
+
return;
|
|
7041
|
+
}
|
|
7032
7042
|
if (text.includes("\n")) {
|
|
7033
7043
|
const parts = text.split("\n");
|
|
7034
7044
|
for (let i = 0; i < parts.length; i++) {
|
|
@@ -8793,7 +8803,7 @@ async function pickSession(term, opts) {
|
|
|
8793
8803
|
if (tier !== 0) {
|
|
8794
8804
|
return tier;
|
|
8795
8805
|
}
|
|
8796
|
-
return b.updatedAt.localeCompare(a.updatedAt);
|
|
8806
|
+
return b.updatedAt.slice(0, 16).localeCompare(a.updatedAt.slice(0, 16));
|
|
8797
8807
|
});
|
|
8798
8808
|
};
|
|
8799
8809
|
let cwdOnly = false;
|
|
@@ -9145,6 +9155,27 @@ async function pickSession(term, opts) {
|
|
|
9145
9155
|
paintIndicator();
|
|
9146
9156
|
});
|
|
9147
9157
|
};
|
|
9158
|
+
const repaintDataZone = () => {
|
|
9159
|
+
withSync(() => {
|
|
9160
|
+
term.moveTo(1, headerRow());
|
|
9161
|
+
term.dim.noFormat(` ${headerLine}`);
|
|
9162
|
+
for (let v = 0; v < viewportSize; v++) {
|
|
9163
|
+
const row = headerRow() + 1 + v;
|
|
9164
|
+
const sessionIdx = scrollOffset + v;
|
|
9165
|
+
if (sessionIdx < visible.length) {
|
|
9166
|
+
term.moveTo(1, row);
|
|
9167
|
+
paintSessionRow(sessionIdx);
|
|
9168
|
+
} else {
|
|
9169
|
+
term.moveTo(1, row).eraseLineAfter();
|
|
9170
|
+
}
|
|
9171
|
+
}
|
|
9172
|
+
paintIndicator();
|
|
9173
|
+
if (selectedIdx === 0) {
|
|
9174
|
+
placeComposerCursor();
|
|
9175
|
+
term.hideCursor(false);
|
|
9176
|
+
}
|
|
9177
|
+
});
|
|
9178
|
+
};
|
|
9148
9179
|
let pasteActive = false;
|
|
9149
9180
|
let pasteBuffer = "";
|
|
9150
9181
|
let tkStdinHandler = null;
|
|
@@ -9200,6 +9231,8 @@ async function pickSession(term, opts) {
|
|
|
9200
9231
|
renderFromScratch();
|
|
9201
9232
|
return await new Promise((resolve6) => {
|
|
9202
9233
|
let resolved = false;
|
|
9234
|
+
let autoRefreshTimer = null;
|
|
9235
|
+
let autoRefreshInFlight = false;
|
|
9203
9236
|
const onResize = () => {
|
|
9204
9237
|
if (resolved) {
|
|
9205
9238
|
return;
|
|
@@ -9211,6 +9244,10 @@ async function pickSession(term, opts) {
|
|
|
9211
9244
|
return;
|
|
9212
9245
|
}
|
|
9213
9246
|
resolved = true;
|
|
9247
|
+
if (autoRefreshTimer) {
|
|
9248
|
+
clearInterval(autoRefreshTimer);
|
|
9249
|
+
autoRefreshTimer = null;
|
|
9250
|
+
}
|
|
9214
9251
|
term.off("key", onKey);
|
|
9215
9252
|
term.off("resize", onResize);
|
|
9216
9253
|
process.stdout.write("\x1B[?2004l");
|
|
@@ -9227,8 +9264,17 @@ async function pickSession(term, opts) {
|
|
|
9227
9264
|
term.moveTo(1, indicatorRow() + 1);
|
|
9228
9265
|
term("\n");
|
|
9229
9266
|
};
|
|
9230
|
-
const
|
|
9267
|
+
const renderFingerprint = () => {
|
|
9268
|
+
const cells = rows.map(
|
|
9269
|
+
(r) => `${r.session}|${r.upstream}|${r.state}|${r.agent}|${r.age}|${r.title}|${r.cwd}`
|
|
9270
|
+
).join("\n");
|
|
9271
|
+
return `${selectedIdx}:${scrollOffset}:${transientStatus ?? ""}
|
|
9272
|
+
${cells}`;
|
|
9273
|
+
};
|
|
9274
|
+
const refresh = async (preferredId, refreshOpts = {}) => {
|
|
9231
9275
|
try {
|
|
9276
|
+
const beforeKey = refreshOpts.silent ? renderFingerprint() : "";
|
|
9277
|
+
const beforeTotal = total;
|
|
9232
9278
|
const next = await listSessions(opts.target);
|
|
9233
9279
|
allSessions = sortSessions(next);
|
|
9234
9280
|
applyFilter();
|
|
@@ -9245,8 +9291,18 @@ async function pickSession(term, opts) {
|
|
|
9245
9291
|
scrollOffset = Math.max(0, visible.length - viewportSize);
|
|
9246
9292
|
}
|
|
9247
9293
|
adjustScroll();
|
|
9248
|
-
|
|
9294
|
+
if (refreshOpts.silent && renderFingerprint() === beforeKey) {
|
|
9295
|
+
return;
|
|
9296
|
+
}
|
|
9297
|
+
if (total === beforeTotal) {
|
|
9298
|
+
repaintDataZone();
|
|
9299
|
+
} else {
|
|
9300
|
+
renderFromScratch();
|
|
9301
|
+
}
|
|
9249
9302
|
} catch (err) {
|
|
9303
|
+
if (refreshOpts.silent) {
|
|
9304
|
+
return;
|
|
9305
|
+
}
|
|
9250
9306
|
transientStatus = `refresh failed: ${err.message}`;
|
|
9251
9307
|
renderFromScratch();
|
|
9252
9308
|
}
|
|
@@ -9723,6 +9779,16 @@ async function pickSession(term, opts) {
|
|
|
9723
9779
|
}
|
|
9724
9780
|
term.on("key", onKey);
|
|
9725
9781
|
term.on("resize", onResize);
|
|
9782
|
+
autoRefreshTimer = setInterval(() => {
|
|
9783
|
+
if (resolved || mode !== "normal" || searchActive || autoRefreshInFlight) {
|
|
9784
|
+
return;
|
|
9785
|
+
}
|
|
9786
|
+
const currentId = selectedIdx > 0 ? visible[selectedIdx - 1]?.sessionId : void 0;
|
|
9787
|
+
autoRefreshInFlight = true;
|
|
9788
|
+
void refresh(currentId, { silent: true }).finally(() => {
|
|
9789
|
+
autoRefreshInFlight = false;
|
|
9790
|
+
});
|
|
9791
|
+
}, 3e3);
|
|
9726
9792
|
});
|
|
9727
9793
|
}
|
|
9728
9794
|
function readTermHeight(term) {
|
|
@@ -11161,9 +11227,38 @@ async function runTuiApp(opts) {
|
|
|
11161
11227
|
const viewPrefs = {
|
|
11162
11228
|
showThoughts: config.tui.showThoughts
|
|
11163
11229
|
};
|
|
11230
|
+
let altScreenEngaged = false;
|
|
11231
|
+
const enterAltScreen = () => {
|
|
11232
|
+
if (altScreenEngaged) {
|
|
11233
|
+
return;
|
|
11234
|
+
}
|
|
11235
|
+
term.fullscreen(true);
|
|
11236
|
+
altScreenEngaged = true;
|
|
11237
|
+
};
|
|
11238
|
+
const leaveAltScreen = () => {
|
|
11239
|
+
if (!altScreenEngaged) {
|
|
11240
|
+
return;
|
|
11241
|
+
}
|
|
11242
|
+
term.fullscreen(false);
|
|
11243
|
+
altScreenEngaged = false;
|
|
11244
|
+
process.stdout.write("\n");
|
|
11245
|
+
};
|
|
11246
|
+
enterAltScreen();
|
|
11247
|
+
const altScreenCleanup = () => {
|
|
11248
|
+
if (altScreenEngaged) {
|
|
11249
|
+
term.fullscreen(false);
|
|
11250
|
+
altScreenEngaged = false;
|
|
11251
|
+
}
|
|
11252
|
+
};
|
|
11253
|
+
process.once("exit", altScreenCleanup);
|
|
11164
11254
|
let nextOpts = opts;
|
|
11165
|
-
|
|
11166
|
-
|
|
11255
|
+
try {
|
|
11256
|
+
while (nextOpts !== null) {
|
|
11257
|
+
nextOpts = await runSession(term, config, target, nextOpts, exitHint, viewPrefs);
|
|
11258
|
+
}
|
|
11259
|
+
} finally {
|
|
11260
|
+
leaveAltScreen();
|
|
11261
|
+
process.off("exit", altScreenCleanup);
|
|
11167
11262
|
}
|
|
11168
11263
|
const pendingUpdate = await getPendingUpdate();
|
|
11169
11264
|
if (pendingUpdate) {
|
|
@@ -11173,7 +11268,6 @@ async function runTuiApp(opts) {
|
|
|
11173
11268
|
if (exitHint.sessionId && process.stdout.isTTY) {
|
|
11174
11269
|
const short = stripHydraSessionPrefix(exitHint.sessionId);
|
|
11175
11270
|
const flags = exitHint.readonly ? " --readonly" : "";
|
|
11176
|
-
process.stdout.write("\x1B[2J\x1B[H");
|
|
11177
11271
|
process.stdout.write(
|
|
11178
11272
|
`To resume: ${invokedBinName()} tui --session ${short}${flags}
|
|
11179
11273
|
`
|
|
@@ -11184,7 +11278,7 @@ async function runSession(term, config, target, opts, exitHint, viewPrefs) {
|
|
|
11184
11278
|
const ctx = await resolveSession(term, config, target, opts);
|
|
11185
11279
|
if (!ctx) {
|
|
11186
11280
|
term.grabInput(false);
|
|
11187
|
-
|
|
11281
|
+
return null;
|
|
11188
11282
|
}
|
|
11189
11283
|
const launchLabelBase = ctx.sessionId === "__new__" ? "Starting new session\u2026" : "Resuming session\u2026";
|
|
11190
11284
|
const installStatus = createInstallStatusLine(term, launchLabelBase);
|
|
@@ -11917,7 +12011,7 @@ async function runSession(term, config, target, opts, exitHint, viewPrefs) {
|
|
|
11917
12011
|
const sessionbarAgent = resolvedAgentId || agentInfoName || "?";
|
|
11918
12012
|
const usage = { ...initialUsage ?? {} };
|
|
11919
12013
|
installStatus.finalize();
|
|
11920
|
-
screen.start();
|
|
12014
|
+
screen.start({ skipFullscreen: true });
|
|
11921
12015
|
screen.setHideThoughts(!viewPrefs.showThoughts);
|
|
11922
12016
|
screen.setSessionbar({
|
|
11923
12017
|
agent: sessionbarAgent,
|
|
@@ -12065,7 +12159,7 @@ async function runSession(term, config, target, opts, exitHint, viewPrefs) {
|
|
|
12065
12159
|
sessionElapsedTimer = null;
|
|
12066
12160
|
}
|
|
12067
12161
|
screen.clearWindowTitle();
|
|
12068
|
-
screen.stop();
|
|
12162
|
+
screen.stop({ keepFullscreen: true });
|
|
12069
12163
|
saveHistory(historyFile, history).catch(() => void 0);
|
|
12070
12164
|
void stream.close().catch(() => void 0);
|
|
12071
12165
|
};
|
|
@@ -15692,7 +15786,8 @@ var SessionManager = class {
|
|
|
15692
15786
|
currentUsage: session.currentUsage,
|
|
15693
15787
|
updatedAt: used,
|
|
15694
15788
|
attachedClients: session.attachedCount,
|
|
15695
|
-
status: "live"
|
|
15789
|
+
status: "live",
|
|
15790
|
+
busy: session.turnStartedAt !== void 0
|
|
15696
15791
|
});
|
|
15697
15792
|
}
|
|
15698
15793
|
const records = await this.store.list().catch(() => []);
|
|
@@ -15716,7 +15811,8 @@ var SessionManager = class {
|
|
|
15716
15811
|
importedFromUpstreamSessionId: r.importedFromUpstreamSessionId,
|
|
15717
15812
|
updatedAt: used,
|
|
15718
15813
|
attachedClients: 0,
|
|
15719
|
-
status: "cold"
|
|
15814
|
+
status: "cold",
|
|
15815
|
+
busy: false
|
|
15720
15816
|
});
|
|
15721
15817
|
}
|
|
15722
15818
|
entries.sort((a, b) => a.updatedAt < b.updatedAt ? 1 : -1);
|
package/dist/index.d.ts
CHANGED
|
@@ -1415,6 +1415,7 @@ declare const SessionListEntry: z.ZodObject<{
|
|
|
1415
1415
|
updatedAt: z.ZodString;
|
|
1416
1416
|
attachedClients: z.ZodNumber;
|
|
1417
1417
|
status: z.ZodDefault<z.ZodEnum<["live", "cold"]>>;
|
|
1418
|
+
busy: z.ZodDefault<z.ZodBoolean>;
|
|
1418
1419
|
_meta: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
1419
1420
|
}, "strip", z.ZodTypeAny, {
|
|
1420
1421
|
sessionId: string;
|
|
@@ -1422,6 +1423,7 @@ declare const SessionListEntry: z.ZodObject<{
|
|
|
1422
1423
|
status: "live" | "cold";
|
|
1423
1424
|
updatedAt: string;
|
|
1424
1425
|
attachedClients: number;
|
|
1426
|
+
busy: boolean;
|
|
1425
1427
|
agentId?: string | undefined;
|
|
1426
1428
|
upstreamSessionId?: string | undefined;
|
|
1427
1429
|
title?: string | undefined;
|
|
@@ -1454,6 +1456,7 @@ declare const SessionListEntry: z.ZodObject<{
|
|
|
1454
1456
|
} | undefined;
|
|
1455
1457
|
importedFromMachine?: string | undefined;
|
|
1456
1458
|
importedFromUpstreamSessionId?: string | undefined;
|
|
1459
|
+
busy?: boolean | undefined;
|
|
1457
1460
|
}>;
|
|
1458
1461
|
type SessionListEntry = z.infer<typeof SessionListEntry>;
|
|
1459
1462
|
declare const SessionListResult: z.ZodObject<{
|
package/dist/index.js
CHANGED
|
@@ -1388,6 +1388,10 @@ var SessionListEntry = z3.object({
|
|
|
1388
1388
|
updatedAt: z3.string(),
|
|
1389
1389
|
attachedClients: z3.number().int().nonnegative(),
|
|
1390
1390
|
status: z3.enum(["live", "cold"]).default("live"),
|
|
1391
|
+
// True while the session is mid-turn (an agent prompt is in flight).
|
|
1392
|
+
// Always false for cold sessions. Lets pickers render a busy dot
|
|
1393
|
+
// without having to attach.
|
|
1394
|
+
busy: z3.boolean().default(false),
|
|
1391
1395
|
_meta: z3.record(z3.unknown()).optional()
|
|
1392
1396
|
});
|
|
1393
1397
|
var SessionListEntryWire = z3.object({
|
|
@@ -1404,7 +1408,8 @@ var SessionListResult = z3.object({
|
|
|
1404
1408
|
function sessionListEntryToWire(entry) {
|
|
1405
1409
|
const hydraMeta = {
|
|
1406
1410
|
attachedClients: entry.attachedClients,
|
|
1407
|
-
status: entry.status
|
|
1411
|
+
status: entry.status,
|
|
1412
|
+
busy: entry.busy
|
|
1408
1413
|
};
|
|
1409
1414
|
if (entry.agentId !== void 0) {
|
|
1410
1415
|
hydraMeta.agentId = entry.agentId;
|
|
@@ -5307,7 +5312,8 @@ var SessionManager = class {
|
|
|
5307
5312
|
currentUsage: session.currentUsage,
|
|
5308
5313
|
updatedAt: used,
|
|
5309
5314
|
attachedClients: session.attachedCount,
|
|
5310
|
-
status: "live"
|
|
5315
|
+
status: "live",
|
|
5316
|
+
busy: session.turnStartedAt !== void 0
|
|
5311
5317
|
});
|
|
5312
5318
|
}
|
|
5313
5319
|
const records = await this.store.list().catch(() => []);
|
|
@@ -5331,7 +5337,8 @@ var SessionManager = class {
|
|
|
5331
5337
|
importedFromUpstreamSessionId: r.importedFromUpstreamSessionId,
|
|
5332
5338
|
updatedAt: used,
|
|
5333
5339
|
attachedClients: 0,
|
|
5334
|
-
status: "cold"
|
|
5340
|
+
status: "cold",
|
|
5341
|
+
busy: false
|
|
5335
5342
|
});
|
|
5336
5343
|
}
|
|
5337
5344
|
entries.sort((a, b) => a.updatedAt < b.updatedAt ? 1 : -1);
|