@hydra-acp/cli 0.1.26 → 0.1.28
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 +120 -8
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -4655,15 +4655,32 @@ async function runSessionsList(opts = {}) {
|
|
|
4655
4655
|
process.exit(1);
|
|
4656
4656
|
}
|
|
4657
4657
|
const body = await response.json();
|
|
4658
|
+
const host = opts.host ?? "local";
|
|
4659
|
+
const hostFiltered = host === "all" ? body.sessions : host === "local" ? body.sessions.filter(
|
|
4660
|
+
(s) => !s.importedFromMachine || !!s.upstreamSessionId
|
|
4661
|
+
) : body.sessions.filter(
|
|
4662
|
+
(s) => s.importedFromMachine === host && !s.upstreamSessionId
|
|
4663
|
+
);
|
|
4658
4664
|
if (opts.json) {
|
|
4659
|
-
process.stdout.write(JSON.stringify(
|
|
4665
|
+
process.stdout.write(JSON.stringify(hostFiltered, null, 2) + "\n");
|
|
4660
4666
|
return;
|
|
4661
4667
|
}
|
|
4662
|
-
if (
|
|
4668
|
+
if (hostFiltered.length === 0) {
|
|
4669
|
+
if (host === "local" && body.sessions.length > 0) {
|
|
4670
|
+
process.stdout.write(
|
|
4671
|
+
"No local sessions. Use --host=all to include imported sessions.\n"
|
|
4672
|
+
);
|
|
4673
|
+
return;
|
|
4674
|
+
}
|
|
4675
|
+
if (host !== "local" && host !== "all") {
|
|
4676
|
+
process.stdout.write(`No sessions from ${host}.
|
|
4677
|
+
`);
|
|
4678
|
+
return;
|
|
4679
|
+
}
|
|
4663
4680
|
process.stdout.write("No active sessions.\n");
|
|
4664
4681
|
return;
|
|
4665
4682
|
}
|
|
4666
|
-
const sorted =
|
|
4683
|
+
const sorted = hostFiltered.slice().sort((a, b) => {
|
|
4667
4684
|
const liveDiff = (b.status === "live" ? 1 : 0) - (a.status === "live" ? 1 : 0);
|
|
4668
4685
|
if (liveDiff !== 0) {
|
|
4669
4686
|
return liveDiff;
|
|
@@ -5414,8 +5431,18 @@ async function pickSession(term, opts) {
|
|
|
5414
5431
|
return b.updatedAt.localeCompare(a.updatedAt);
|
|
5415
5432
|
});
|
|
5416
5433
|
};
|
|
5434
|
+
let cwdOnly = false;
|
|
5435
|
+
let hostFilter = "__local";
|
|
5436
|
+
if (opts.currentSessionId !== void 0) {
|
|
5437
|
+
const current = opts.sessions.find(
|
|
5438
|
+
(s) => s.sessionId === opts.currentSessionId
|
|
5439
|
+
);
|
|
5440
|
+
if (current?.importedFromMachine) {
|
|
5441
|
+
hostFilter = "__all";
|
|
5442
|
+
}
|
|
5443
|
+
}
|
|
5417
5444
|
let allSessions = sortSessions(opts.sessions);
|
|
5418
|
-
let visible = allSessions;
|
|
5445
|
+
let visible = filterByHost(allSessions, hostFilter);
|
|
5419
5446
|
let rows = visible.map((s) => toRow(s, Date.now()));
|
|
5420
5447
|
let widths = computeWidths(rows);
|
|
5421
5448
|
let total = 1 + visible.length;
|
|
@@ -5429,7 +5456,6 @@ async function pickSession(term, opts) {
|
|
|
5429
5456
|
}
|
|
5430
5457
|
let searchActive = false;
|
|
5431
5458
|
let searchTerm = "";
|
|
5432
|
-
let cwdOnly = false;
|
|
5433
5459
|
let mode = "normal";
|
|
5434
5460
|
let pendingAction = null;
|
|
5435
5461
|
let renameBuffer = "";
|
|
@@ -5463,6 +5489,7 @@ async function pickSession(term, opts) {
|
|
|
5463
5489
|
if (cwdOnly) {
|
|
5464
5490
|
base = base.filter((s) => s.cwd === opts.cwd);
|
|
5465
5491
|
}
|
|
5492
|
+
base = filterByHost(base, hostFilter);
|
|
5466
5493
|
if (searchActive && searchTerm.length > 0) {
|
|
5467
5494
|
visible = base.filter((s) => matchesSearch(s, searchTerm));
|
|
5468
5495
|
} else {
|
|
@@ -5515,6 +5542,11 @@ async function pickSession(term, opts) {
|
|
|
5515
5542
|
if (cwdOnly) {
|
|
5516
5543
|
parts.push("cwd-only");
|
|
5517
5544
|
}
|
|
5545
|
+
if (hostFilter !== "__all") {
|
|
5546
|
+
parts.push(
|
|
5547
|
+
hostFilter === "__local" ? "host: local" : `host: ${hostFilter}`
|
|
5548
|
+
);
|
|
5549
|
+
}
|
|
5518
5550
|
if (above > 0) {
|
|
5519
5551
|
parts.push(`\u2191 ${above} above`);
|
|
5520
5552
|
}
|
|
@@ -5896,6 +5928,20 @@ async function pickSession(term, opts) {
|
|
|
5896
5928
|
renderFromScratch();
|
|
5897
5929
|
return;
|
|
5898
5930
|
}
|
|
5931
|
+
if (name === "h" || name === "H") {
|
|
5932
|
+
const keepId = selectedIdx > 0 ? visible[selectedIdx - 1]?.sessionId : void 0;
|
|
5933
|
+
hostFilter = nextHostFilter(hostFilter, allSessions);
|
|
5934
|
+
applyFilter();
|
|
5935
|
+
if (keepId !== void 0) {
|
|
5936
|
+
const idx = visible.findIndex((s) => s.sessionId === keepId);
|
|
5937
|
+
if (idx >= 0) {
|
|
5938
|
+
selectedIdx = idx + 1;
|
|
5939
|
+
adjustScroll();
|
|
5940
|
+
}
|
|
5941
|
+
}
|
|
5942
|
+
renderFromScratch();
|
|
5943
|
+
return;
|
|
5944
|
+
}
|
|
5899
5945
|
if (name === "r" || name === "R") {
|
|
5900
5946
|
const currentId = selectedIdx > 0 ? visible[selectedIdx - 1]?.sessionId : void 0;
|
|
5901
5947
|
void refresh(currentId);
|
|
@@ -6026,6 +6072,33 @@ function formatNewSessionLabel(cwd, maxWidth) {
|
|
|
6026
6072
|
const budget = Math.max(1, maxWidth - prefix.length);
|
|
6027
6073
|
return prefix + truncateMiddle(shortenHomePath(cwd), budget);
|
|
6028
6074
|
}
|
|
6075
|
+
function filterByHost(sessions, hostFilter) {
|
|
6076
|
+
if (hostFilter === "__all") {
|
|
6077
|
+
return sessions;
|
|
6078
|
+
}
|
|
6079
|
+
if (hostFilter === "__local") {
|
|
6080
|
+
return sessions.filter(
|
|
6081
|
+
(s) => !s.importedFromMachine || !!s.upstreamSessionId
|
|
6082
|
+
);
|
|
6083
|
+
}
|
|
6084
|
+
return sessions.filter(
|
|
6085
|
+
(s) => s.importedFromMachine === hostFilter && !s.upstreamSessionId
|
|
6086
|
+
);
|
|
6087
|
+
}
|
|
6088
|
+
function nextHostFilter(current, sessions) {
|
|
6089
|
+
const hosts = /* @__PURE__ */ new Set();
|
|
6090
|
+
for (const s of sessions) {
|
|
6091
|
+
if (s.importedFromMachine && !s.upstreamSessionId) {
|
|
6092
|
+
hosts.add(s.importedFromMachine);
|
|
6093
|
+
}
|
|
6094
|
+
}
|
|
6095
|
+
const ordered = ["__local", ...[...hosts].sort(), "__all"];
|
|
6096
|
+
const idx = ordered.indexOf(current);
|
|
6097
|
+
if (idx === -1) {
|
|
6098
|
+
return "__local";
|
|
6099
|
+
}
|
|
6100
|
+
return ordered[(idx + 1) % ordered.length] ?? "__local";
|
|
6101
|
+
}
|
|
6029
6102
|
function matchesSearch(s, term) {
|
|
6030
6103
|
if (term.length === 0) {
|
|
6031
6104
|
return true;
|
|
@@ -6064,6 +6137,7 @@ var init_picker = __esm({
|
|
|
6064
6137
|
null,
|
|
6065
6138
|
["/", "search sessions"],
|
|
6066
6139
|
["o", "toggle cwd-only filter"],
|
|
6140
|
+
["h", "cycle host filter (local / <peer> / all)"],
|
|
6067
6141
|
["r", "refresh from daemon"],
|
|
6068
6142
|
null,
|
|
6069
6143
|
["k", "kill the selected live session"],
|
|
@@ -6991,6 +7065,42 @@ var init_screen = __esm({
|
|
|
6991
7065
|
return;
|
|
6992
7066
|
}
|
|
6993
7067
|
}
|
|
7068
|
+
const csiUCtrlMap = {
|
|
7069
|
+
97: "ctrl-a",
|
|
7070
|
+
98: "ctrl-b",
|
|
7071
|
+
99: "ctrl-c",
|
|
7072
|
+
100: "ctrl-d",
|
|
7073
|
+
101: "ctrl-e",
|
|
7074
|
+
102: "ctrl-f",
|
|
7075
|
+
103: "ctrl-g",
|
|
7076
|
+
107: "ctrl-k",
|
|
7077
|
+
108: "ctrl-l",
|
|
7078
|
+
110: "ctrl-n",
|
|
7079
|
+
111: "ctrl-o",
|
|
7080
|
+
112: "ctrl-p",
|
|
7081
|
+
114: "ctrl-r",
|
|
7082
|
+
115: "ctrl-s",
|
|
7083
|
+
116: "ctrl-t",
|
|
7084
|
+
117: "ctrl-u",
|
|
7085
|
+
118: "ctrl-v",
|
|
7086
|
+
119: "ctrl-w",
|
|
7087
|
+
121: "ctrl-y"
|
|
7088
|
+
};
|
|
7089
|
+
const csiUCtrlRe = /\x1b\[(\d+);5u/;
|
|
7090
|
+
const m = csiUCtrlRe.exec(text);
|
|
7091
|
+
if (m !== null) {
|
|
7092
|
+
const keyName = csiUCtrlMap[parseInt(m[1], 10)];
|
|
7093
|
+
if (keyName !== void 0) {
|
|
7094
|
+
const parts = text.split(m[0]);
|
|
7095
|
+
for (let i = 0; i < parts.length; i++) {
|
|
7096
|
+
if (parts[i].length > 0)
|
|
7097
|
+
this.handleRawStdin(Buffer.from(parts[i], "binary"));
|
|
7098
|
+
if (i < parts.length - 1)
|
|
7099
|
+
this.onKey([{ type: "key", name: keyName }]);
|
|
7100
|
+
}
|
|
7101
|
+
return;
|
|
7102
|
+
}
|
|
7103
|
+
}
|
|
6994
7104
|
}
|
|
6995
7105
|
this.handleRawStdinSegment(text);
|
|
6996
7106
|
}
|
|
@@ -18287,7 +18397,8 @@ async function main() {
|
|
|
18287
18397
|
if (sub === void 0 || sub === "list") {
|
|
18288
18398
|
await runSessionsList({
|
|
18289
18399
|
all: flags.all === true,
|
|
18290
|
-
json: flags.json === true
|
|
18400
|
+
json: flags.json === true,
|
|
18401
|
+
host: typeof flags.host === "string" ? flags.host : void 0
|
|
18291
18402
|
});
|
|
18292
18403
|
return;
|
|
18293
18404
|
}
|
|
@@ -18480,8 +18591,9 @@ function printHelp() {
|
|
|
18480
18591
|
" hydra-acp daemon start [--foreground] Start daemon (detached by default; --foreground to attach)",
|
|
18481
18592
|
" hydra-acp daemon stop|restart|status",
|
|
18482
18593
|
" hydra-acp daemon logs [-f] [-n N] Tail or follow the daemon log",
|
|
18483
|
-
" hydra-acp session [list] [--all] [--json]",
|
|
18484
|
-
" List sessions (live + 20 most-recent cold; --all for everything; --json emits
|
|
18594
|
+
" hydra-acp session [list] [--all] [--json] [--host=<host>]",
|
|
18595
|
+
" List sessions (live + 20 most-recent cold; --all for everything; --json emits JSON for scripts).",
|
|
18596
|
+
" --host filters by origin machine: 'local' (default) shows only sessions created here, 'all' shows everything, or pass a hostname (e.g. machine-b) to show only imports from that peer.",
|
|
18485
18597
|
" hydra-acp session kill <id> Demote a live session to cold (keeps the on-disk record)",
|
|
18486
18598
|
" hydra-acp session remove <id> Remove a session entirely (live or cold)",
|
|
18487
18599
|
" hydra-acp session export <id> [--out <file>|.]",
|