@hydra-acp/cli 0.1.38 → 0.1.40
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 +132 -22
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -4941,6 +4941,35 @@ function disabled() {
|
|
|
4941
4941
|
}
|
|
4942
4942
|
return false;
|
|
4943
4943
|
}
|
|
4944
|
+
function parseVersion(v) {
|
|
4945
|
+
const core = v.split("-", 1)[0] ?? v;
|
|
4946
|
+
const parts = core.split(".");
|
|
4947
|
+
const major = Number(parts[0]);
|
|
4948
|
+
const minor = Number(parts[1]);
|
|
4949
|
+
const patch = Number(parts[2]);
|
|
4950
|
+
if (!Number.isFinite(major) || !Number.isFinite(minor) || !Number.isFinite(patch)) {
|
|
4951
|
+
return null;
|
|
4952
|
+
}
|
|
4953
|
+
return [major, minor, patch];
|
|
4954
|
+
}
|
|
4955
|
+
function isNewer(latest, current) {
|
|
4956
|
+
const a = parseVersion(latest);
|
|
4957
|
+
const b = parseVersion(current);
|
|
4958
|
+
if (!a || !b) {
|
|
4959
|
+
return latest !== current;
|
|
4960
|
+
}
|
|
4961
|
+
for (let i = 0; i < 3; i++) {
|
|
4962
|
+
const av = a[i];
|
|
4963
|
+
const bv = b[i];
|
|
4964
|
+
if (av > bv) {
|
|
4965
|
+
return true;
|
|
4966
|
+
}
|
|
4967
|
+
if (av < bv) {
|
|
4968
|
+
return false;
|
|
4969
|
+
}
|
|
4970
|
+
}
|
|
4971
|
+
return false;
|
|
4972
|
+
}
|
|
4944
4973
|
async function getPendingUpdate() {
|
|
4945
4974
|
if (cached !== void 0) {
|
|
4946
4975
|
return cached;
|
|
@@ -4956,7 +4985,7 @@ async function getPendingUpdate() {
|
|
|
4956
4985
|
pkg: { name: PKG_NAME, version: HYDRA_VERSION }
|
|
4957
4986
|
});
|
|
4958
4987
|
const u = notifier.update;
|
|
4959
|
-
if (u && typeof u.latest === "string" && typeof u.current === "string" && u.latest
|
|
4988
|
+
if (u && typeof u.latest === "string" && typeof u.current === "string" && isNewer(u.latest, u.current)) {
|
|
4960
4989
|
try {
|
|
4961
4990
|
notifier.config?.set?.("update", u);
|
|
4962
4991
|
} catch {
|
|
@@ -4967,6 +4996,12 @@ async function getPendingUpdate() {
|
|
|
4967
4996
|
type: typeof u.type === "string" ? u.type : "unknown"
|
|
4968
4997
|
};
|
|
4969
4998
|
} else {
|
|
4999
|
+
if (u && typeof u.latest === "string" && typeof u.current === "string") {
|
|
5000
|
+
try {
|
|
5001
|
+
notifier.config?.set?.("update", void 0);
|
|
5002
|
+
} catch {
|
|
5003
|
+
}
|
|
5004
|
+
}
|
|
4970
5005
|
cached = null;
|
|
4971
5006
|
}
|
|
4972
5007
|
} catch {
|
|
@@ -6099,7 +6134,7 @@ function writeStyled(term, text, style) {
|
|
|
6099
6134
|
term(text);
|
|
6100
6135
|
return;
|
|
6101
6136
|
case "thought":
|
|
6102
|
-
term.dim.
|
|
6137
|
+
term.brightBlack.dim.noFormat(text);
|
|
6103
6138
|
return;
|
|
6104
6139
|
case "tool":
|
|
6105
6140
|
term.brightBlue.noFormat(text);
|
|
@@ -8022,6 +8057,7 @@ uncaught: ${err.stack ?? err.message}
|
|
|
8022
8057
|
this.lastFrameH = h;
|
|
8023
8058
|
}
|
|
8024
8059
|
withSync(() => {
|
|
8060
|
+
this.term.hideCursor();
|
|
8025
8061
|
this.drawScrollback();
|
|
8026
8062
|
this.drawCompletionZone();
|
|
8027
8063
|
this.drawQueuedZone();
|
|
@@ -8034,6 +8070,9 @@ uncaught: ${err.stack ?? err.message}
|
|
|
8034
8070
|
this.drawSeparator(h - SESSIONBAR_ROWS);
|
|
8035
8071
|
this.drawSessionbar();
|
|
8036
8072
|
this.placeCursor();
|
|
8073
|
+
if (this.permissionPrompt || this.confirmPrompt || this.helpPrompt) {
|
|
8074
|
+
this.term.hideCursor(false);
|
|
8075
|
+
}
|
|
8037
8076
|
this.lastPromptRows = promptRows;
|
|
8038
8077
|
});
|
|
8039
8078
|
}
|
|
@@ -8852,14 +8891,11 @@ async function pickSession(term, opts) {
|
|
|
8852
8891
|
const composerBoxInner = () => Math.max(2, termWidth - 2);
|
|
8853
8892
|
const paintComposerTopBorder = () => {
|
|
8854
8893
|
const inner = composerBoxInner();
|
|
8855
|
-
const focused = selectedIdx === 0;
|
|
8856
8894
|
const titleFragment = `\u2500 ${composerTitle} `;
|
|
8857
8895
|
const dashCount = Math.max(1, inner - titleFragment.length);
|
|
8858
8896
|
const dashes = "\u2500".repeat(dashCount);
|
|
8859
|
-
if (
|
|
8860
|
-
term.
|
|
8861
|
-
term.brightCyan.bold.noFormat(titleFragment);
|
|
8862
|
-
term.brightCyan.noFormat(`${dashes}\u256E`);
|
|
8897
|
+
if (selectedIdx === 0) {
|
|
8898
|
+
term.brightBlue.noFormat(`\u256D${titleFragment}${dashes}\u256E`);
|
|
8863
8899
|
} else {
|
|
8864
8900
|
term.dim.noFormat(`\u256D${titleFragment}${dashes}\u256E`);
|
|
8865
8901
|
}
|
|
@@ -8868,15 +8904,13 @@ async function pickSession(term, opts) {
|
|
|
8868
8904
|
const inner = composerBoxInner();
|
|
8869
8905
|
const dashes = "\u2500".repeat(inner);
|
|
8870
8906
|
if (selectedIdx === 0) {
|
|
8871
|
-
term.
|
|
8907
|
+
term.brightBlue.noFormat(`\u2570${dashes}\u256F`);
|
|
8872
8908
|
} else {
|
|
8873
8909
|
term.dim.noFormat(`\u2570${dashes}\u256F`);
|
|
8874
8910
|
}
|
|
8875
8911
|
};
|
|
8876
8912
|
const paintComposerBodyRow = (visualIdx) => {
|
|
8877
8913
|
const inner = composerBoxInner();
|
|
8878
|
-
const sideStyle = selectedIdx === 0 ? term.brightCyan : term.dim;
|
|
8879
|
-
sideStyle.noFormat("\u2502");
|
|
8880
8914
|
const vr = composerVisualRows[visualIdx];
|
|
8881
8915
|
let slice = "";
|
|
8882
8916
|
if (vr) {
|
|
@@ -8885,13 +8919,17 @@ async function pickSession(term, opts) {
|
|
|
8885
8919
|
vr.endCol
|
|
8886
8920
|
);
|
|
8887
8921
|
}
|
|
8888
|
-
term.noFormat(" ");
|
|
8889
|
-
term.noFormat(slice);
|
|
8890
8922
|
const padWidth = Math.max(0, inner - 1 - slice.length);
|
|
8891
|
-
|
|
8892
|
-
|
|
8923
|
+
const pad = " ".repeat(padWidth);
|
|
8924
|
+
if (selectedIdx === 0) {
|
|
8925
|
+
term.brightBlue.noFormat("\u2502");
|
|
8926
|
+
term.noFormat(` ${slice}${pad}`);
|
|
8927
|
+
term.brightBlue.noFormat("\u2502");
|
|
8928
|
+
} else {
|
|
8929
|
+
term.dim.noFormat("\u2502");
|
|
8930
|
+
term.noFormat(` ${slice}${pad}`);
|
|
8931
|
+
term.dim.noFormat("\u2502");
|
|
8893
8932
|
}
|
|
8894
|
-
sideStyle.noFormat("\u2502");
|
|
8895
8933
|
};
|
|
8896
8934
|
const paintSessionRow = (sessionIdx) => {
|
|
8897
8935
|
const label = sessionLines[sessionIdx] ?? "";
|
|
@@ -9085,6 +9123,58 @@ async function pickSession(term, opts) {
|
|
|
9085
9123
|
paintIndicator();
|
|
9086
9124
|
});
|
|
9087
9125
|
};
|
|
9126
|
+
let pasteActive = false;
|
|
9127
|
+
let pasteBuffer = "";
|
|
9128
|
+
let tkStdinHandler = null;
|
|
9129
|
+
const PASTE_START = "\x1B[200~";
|
|
9130
|
+
const PASTE_END = "\x1B[201~";
|
|
9131
|
+
const rawStdinHandler = (chunk) => {
|
|
9132
|
+
let text = chunk.toString("binary");
|
|
9133
|
+
if (pasteActive) {
|
|
9134
|
+
const endIdx = text.indexOf(PASTE_END);
|
|
9135
|
+
if (endIdx === -1) {
|
|
9136
|
+
pasteBuffer += text;
|
|
9137
|
+
return;
|
|
9138
|
+
}
|
|
9139
|
+
pasteBuffer += text.slice(0, endIdx);
|
|
9140
|
+
pasteActive = false;
|
|
9141
|
+
const pasted = Buffer.from(pasteBuffer, "binary").toString("utf-8").replace(/\r\n?/g, "\n");
|
|
9142
|
+
pasteBuffer = "";
|
|
9143
|
+
const remaining = text.slice(endIdx + PASTE_END.length);
|
|
9144
|
+
if (selectedIdx === 0 && !searchActive) {
|
|
9145
|
+
composer.feed({ type: "paste", text: pasted });
|
|
9146
|
+
const after = composer.state();
|
|
9147
|
+
const newVr = computePromptVisualRows(after.buffer, composerRoom);
|
|
9148
|
+
const newLayout = computePromptLayout(
|
|
9149
|
+
newVr,
|
|
9150
|
+
after,
|
|
9151
|
+
PICKER_COMPOSER_MAX_ROWS
|
|
9152
|
+
);
|
|
9153
|
+
if (newLayout.rendered !== composerRows) {
|
|
9154
|
+
renderFromScratch();
|
|
9155
|
+
} else {
|
|
9156
|
+
repaintComposerBody();
|
|
9157
|
+
}
|
|
9158
|
+
}
|
|
9159
|
+
if (remaining.length > 0 && tkStdinHandler) {
|
|
9160
|
+
tkStdinHandler(Buffer.from(remaining, "binary"));
|
|
9161
|
+
}
|
|
9162
|
+
return;
|
|
9163
|
+
}
|
|
9164
|
+
const startIdx = text.indexOf(PASTE_START);
|
|
9165
|
+
if (startIdx === -1) {
|
|
9166
|
+
tkStdinHandler?.(chunk);
|
|
9167
|
+
return;
|
|
9168
|
+
}
|
|
9169
|
+
if (startIdx > 0) {
|
|
9170
|
+
tkStdinHandler?.(Buffer.from(text.slice(0, startIdx), "binary"));
|
|
9171
|
+
}
|
|
9172
|
+
text = text.slice(startIdx + PASTE_START.length);
|
|
9173
|
+
pasteActive = true;
|
|
9174
|
+
if (text.length > 0) {
|
|
9175
|
+
rawStdinHandler(Buffer.from(text, "binary"));
|
|
9176
|
+
}
|
|
9177
|
+
};
|
|
9088
9178
|
renderFromScratch();
|
|
9089
9179
|
return await new Promise((resolve6) => {
|
|
9090
9180
|
let resolved = false;
|
|
@@ -9101,6 +9191,15 @@ async function pickSession(term, opts) {
|
|
|
9101
9191
|
resolved = true;
|
|
9102
9192
|
term.off("key", onKey);
|
|
9103
9193
|
term.off("resize", onResize);
|
|
9194
|
+
process.stdout.write("\x1B[?2004l");
|
|
9195
|
+
const tClean = term;
|
|
9196
|
+
if (tClean.stdin && tkStdinHandler) {
|
|
9197
|
+
tClean.stdin.removeListener("data", rawStdinHandler);
|
|
9198
|
+
tClean.stdin.on("data", tkStdinHandler);
|
|
9199
|
+
tkStdinHandler = null;
|
|
9200
|
+
}
|
|
9201
|
+
pasteActive = false;
|
|
9202
|
+
pasteBuffer = "";
|
|
9104
9203
|
term.grabInput(false);
|
|
9105
9204
|
term.hideCursor(false);
|
|
9106
9205
|
term.moveTo(1, indicatorRow() + 1);
|
|
@@ -9593,6 +9692,13 @@ async function pickSession(term, opts) {
|
|
|
9593
9692
|
}
|
|
9594
9693
|
};
|
|
9595
9694
|
term.grabInput({});
|
|
9695
|
+
const tSetup = term;
|
|
9696
|
+
if (tSetup.stdin && typeof tSetup.onStdin === "function") {
|
|
9697
|
+
tkStdinHandler = tSetup.onStdin;
|
|
9698
|
+
tSetup.stdin.removeListener("data", tSetup.onStdin);
|
|
9699
|
+
tSetup.stdin.on("data", rawStdinHandler);
|
|
9700
|
+
process.stdout.write("\x1B[?2004h");
|
|
9701
|
+
}
|
|
9596
9702
|
term.on("key", onKey);
|
|
9597
9703
|
term.on("resize", onResize);
|
|
9598
9704
|
});
|
|
@@ -11028,9 +11134,12 @@ async function runTuiApp(opts) {
|
|
|
11028
11134
|
}
|
|
11029
11135
|
const term = termkit.terminal;
|
|
11030
11136
|
const exitHint = {};
|
|
11137
|
+
const viewPrefs = {
|
|
11138
|
+
showThoughts: config.tui.showThoughts
|
|
11139
|
+
};
|
|
11031
11140
|
let nextOpts = opts;
|
|
11032
11141
|
while (nextOpts !== null) {
|
|
11033
|
-
nextOpts = await runSession(term, config, target, nextOpts, exitHint);
|
|
11142
|
+
nextOpts = await runSession(term, config, target, nextOpts, exitHint, viewPrefs);
|
|
11034
11143
|
}
|
|
11035
11144
|
const pendingUpdate = await getPendingUpdate();
|
|
11036
11145
|
if (pendingUpdate) {
|
|
@@ -11047,7 +11156,7 @@ async function runTuiApp(opts) {
|
|
|
11047
11156
|
);
|
|
11048
11157
|
}
|
|
11049
11158
|
}
|
|
11050
|
-
async function runSession(term, config, target, opts, exitHint) {
|
|
11159
|
+
async function runSession(term, config, target, opts, exitHint, viewPrefs) {
|
|
11051
11160
|
const ctx = await resolveSession(term, config, target, opts);
|
|
11052
11161
|
if (!ctx) {
|
|
11053
11162
|
term.grabInput(false);
|
|
@@ -11555,7 +11664,6 @@ async function runSession(term, config, target, opts, exitHint) {
|
|
|
11555
11664
|
}
|
|
11556
11665
|
let turnInFlight = null;
|
|
11557
11666
|
let pendingPrefill = null;
|
|
11558
|
-
let showThoughts = config.tui.showThoughts;
|
|
11559
11667
|
const screen = new Screen({
|
|
11560
11668
|
term,
|
|
11561
11669
|
dispatcher,
|
|
@@ -11760,7 +11868,7 @@ async function runSession(term, config, target, opts, exitHint) {
|
|
|
11760
11868
|
const usage = { ...initialUsage ?? {} };
|
|
11761
11869
|
installStatus.finalize();
|
|
11762
11870
|
screen.start();
|
|
11763
|
-
screen.setHideThoughts(!showThoughts);
|
|
11871
|
+
screen.setHideThoughts(!viewPrefs.showThoughts);
|
|
11764
11872
|
screen.setSessionbar({
|
|
11765
11873
|
agent: sessionbarAgent,
|
|
11766
11874
|
cwd: resolvedCwd,
|
|
@@ -12147,9 +12255,11 @@ async function runSession(term, config, target, opts, exitHint) {
|
|
|
12147
12255
|
renderToolsBlock();
|
|
12148
12256
|
return;
|
|
12149
12257
|
case "toggle-thoughts":
|
|
12150
|
-
showThoughts = !showThoughts;
|
|
12151
|
-
screen.setHideThoughts(!showThoughts);
|
|
12152
|
-
screen.notify(
|
|
12258
|
+
viewPrefs.showThoughts = !viewPrefs.showThoughts;
|
|
12259
|
+
screen.setHideThoughts(!viewPrefs.showThoughts);
|
|
12260
|
+
screen.notify(
|
|
12261
|
+
viewPrefs.showThoughts ? "thoughts shown" : "thoughts hidden"
|
|
12262
|
+
);
|
|
12153
12263
|
return;
|
|
12154
12264
|
case "toggle-mouse": {
|
|
12155
12265
|
const next = !screen.isMouseEnabled();
|