@hydra-acp/cli 0.1.38 → 0.1.39

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 (2) hide show
  1. package/dist/cli.js +119 -8
  2. 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 !== u.current) {
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 {
@@ -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
  }
@@ -9085,6 +9124,58 @@ async function pickSession(term, opts) {
9085
9124
  paintIndicator();
9086
9125
  });
9087
9126
  };
9127
+ let pasteActive = false;
9128
+ let pasteBuffer = "";
9129
+ let tkStdinHandler = null;
9130
+ const PASTE_START = "\x1B[200~";
9131
+ const PASTE_END = "\x1B[201~";
9132
+ const rawStdinHandler = (chunk) => {
9133
+ let text = chunk.toString("binary");
9134
+ if (pasteActive) {
9135
+ const endIdx = text.indexOf(PASTE_END);
9136
+ if (endIdx === -1) {
9137
+ pasteBuffer += text;
9138
+ return;
9139
+ }
9140
+ pasteBuffer += text.slice(0, endIdx);
9141
+ pasteActive = false;
9142
+ const pasted = Buffer.from(pasteBuffer, "binary").toString("utf-8").replace(/\r\n?/g, "\n");
9143
+ pasteBuffer = "";
9144
+ const remaining = text.slice(endIdx + PASTE_END.length);
9145
+ if (selectedIdx === 0 && !searchActive) {
9146
+ composer.feed({ type: "paste", text: pasted });
9147
+ const after = composer.state();
9148
+ const newVr = computePromptVisualRows(after.buffer, composerRoom);
9149
+ const newLayout = computePromptLayout(
9150
+ newVr,
9151
+ after,
9152
+ PICKER_COMPOSER_MAX_ROWS
9153
+ );
9154
+ if (newLayout.rendered !== composerRows) {
9155
+ renderFromScratch();
9156
+ } else {
9157
+ repaintComposerBody();
9158
+ }
9159
+ }
9160
+ if (remaining.length > 0 && tkStdinHandler) {
9161
+ tkStdinHandler(Buffer.from(remaining, "binary"));
9162
+ }
9163
+ return;
9164
+ }
9165
+ const startIdx = text.indexOf(PASTE_START);
9166
+ if (startIdx === -1) {
9167
+ tkStdinHandler?.(chunk);
9168
+ return;
9169
+ }
9170
+ if (startIdx > 0) {
9171
+ tkStdinHandler?.(Buffer.from(text.slice(0, startIdx), "binary"));
9172
+ }
9173
+ text = text.slice(startIdx + PASTE_START.length);
9174
+ pasteActive = true;
9175
+ if (text.length > 0) {
9176
+ rawStdinHandler(Buffer.from(text, "binary"));
9177
+ }
9178
+ };
9088
9179
  renderFromScratch();
9089
9180
  return await new Promise((resolve6) => {
9090
9181
  let resolved = false;
@@ -9101,6 +9192,15 @@ async function pickSession(term, opts) {
9101
9192
  resolved = true;
9102
9193
  term.off("key", onKey);
9103
9194
  term.off("resize", onResize);
9195
+ process.stdout.write("\x1B[?2004l");
9196
+ const tClean = term;
9197
+ if (tClean.stdin && tkStdinHandler) {
9198
+ tClean.stdin.removeListener("data", rawStdinHandler);
9199
+ tClean.stdin.on("data", tkStdinHandler);
9200
+ tkStdinHandler = null;
9201
+ }
9202
+ pasteActive = false;
9203
+ pasteBuffer = "";
9104
9204
  term.grabInput(false);
9105
9205
  term.hideCursor(false);
9106
9206
  term.moveTo(1, indicatorRow() + 1);
@@ -9593,6 +9693,13 @@ async function pickSession(term, opts) {
9593
9693
  }
9594
9694
  };
9595
9695
  term.grabInput({});
9696
+ const tSetup = term;
9697
+ if (tSetup.stdin && typeof tSetup.onStdin === "function") {
9698
+ tkStdinHandler = tSetup.onStdin;
9699
+ tSetup.stdin.removeListener("data", tSetup.onStdin);
9700
+ tSetup.stdin.on("data", rawStdinHandler);
9701
+ process.stdout.write("\x1B[?2004h");
9702
+ }
9596
9703
  term.on("key", onKey);
9597
9704
  term.on("resize", onResize);
9598
9705
  });
@@ -11028,9 +11135,12 @@ async function runTuiApp(opts) {
11028
11135
  }
11029
11136
  const term = termkit.terminal;
11030
11137
  const exitHint = {};
11138
+ const viewPrefs = {
11139
+ showThoughts: config.tui.showThoughts
11140
+ };
11031
11141
  let nextOpts = opts;
11032
11142
  while (nextOpts !== null) {
11033
- nextOpts = await runSession(term, config, target, nextOpts, exitHint);
11143
+ nextOpts = await runSession(term, config, target, nextOpts, exitHint, viewPrefs);
11034
11144
  }
11035
11145
  const pendingUpdate = await getPendingUpdate();
11036
11146
  if (pendingUpdate) {
@@ -11047,7 +11157,7 @@ async function runTuiApp(opts) {
11047
11157
  );
11048
11158
  }
11049
11159
  }
11050
- async function runSession(term, config, target, opts, exitHint) {
11160
+ async function runSession(term, config, target, opts, exitHint, viewPrefs) {
11051
11161
  const ctx = await resolveSession(term, config, target, opts);
11052
11162
  if (!ctx) {
11053
11163
  term.grabInput(false);
@@ -11555,7 +11665,6 @@ async function runSession(term, config, target, opts, exitHint) {
11555
11665
  }
11556
11666
  let turnInFlight = null;
11557
11667
  let pendingPrefill = null;
11558
- let showThoughts = config.tui.showThoughts;
11559
11668
  const screen = new Screen({
11560
11669
  term,
11561
11670
  dispatcher,
@@ -11760,7 +11869,7 @@ async function runSession(term, config, target, opts, exitHint) {
11760
11869
  const usage = { ...initialUsage ?? {} };
11761
11870
  installStatus.finalize();
11762
11871
  screen.start();
11763
- screen.setHideThoughts(!showThoughts);
11872
+ screen.setHideThoughts(!viewPrefs.showThoughts);
11764
11873
  screen.setSessionbar({
11765
11874
  agent: sessionbarAgent,
11766
11875
  cwd: resolvedCwd,
@@ -12147,9 +12256,11 @@ async function runSession(term, config, target, opts, exitHint) {
12147
12256
  renderToolsBlock();
12148
12257
  return;
12149
12258
  case "toggle-thoughts":
12150
- showThoughts = !showThoughts;
12151
- screen.setHideThoughts(!showThoughts);
12152
- screen.notify(showThoughts ? "thoughts shown" : "thoughts hidden");
12259
+ viewPrefs.showThoughts = !viewPrefs.showThoughts;
12260
+ screen.setHideThoughts(!viewPrefs.showThoughts);
12261
+ screen.notify(
12262
+ viewPrefs.showThoughts ? "thoughts shown" : "thoughts hidden"
12263
+ );
12153
12264
  return;
12154
12265
  case "toggle-mouse": {
12155
12266
  const next = !screen.isMouseEnabled();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hydra-acp/cli",
3
- "version": "0.1.38",
3
+ "version": "0.1.39",
4
4
  "description": "Multi-client ACP session daemon: spawn agents, attach over WSS, multiplex sessions across editors.",
5
5
  "license": "MIT",
6
6
  "type": "module",