@hydra-acp/cli 0.1.46 → 0.1.47

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 +58 -12
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -4916,6 +4916,25 @@ function buildCombinedHistory(global, session) {
4916
4916
  const filteredGlobal = global.filter((e) => !sessionSet.has(e));
4917
4917
  return [...filteredGlobal, ...session];
4918
4918
  }
4919
+ function mergeReplayedEntries(existing, replayed, cap = HISTORY_CAP) {
4920
+ if (replayed.length === 0) {
4921
+ return existing;
4922
+ }
4923
+ const seen = new Set(existing);
4924
+ let out = existing;
4925
+ for (const raw of replayed) {
4926
+ const trimmed = raw.replace(/\n+$/, "");
4927
+ if (trimmed.length === 0) {
4928
+ continue;
4929
+ }
4930
+ if (seen.has(trimmed)) {
4931
+ continue;
4932
+ }
4933
+ seen.add(trimmed);
4934
+ out = appendEntry(out, trimmed, cap);
4935
+ }
4936
+ return out;
4937
+ }
4919
4938
  var HISTORY_CAP;
4920
4939
  var init_history = __esm({
4921
4940
  "src/tui/history.ts"() {
@@ -6388,7 +6407,7 @@ var init_input = __esm({
6388
6407
  case "ctrl-r":
6389
6408
  return this.startHistorySearch();
6390
6409
  case "ctrl-s":
6391
- return [];
6410
+ return this.amend();
6392
6411
  case "ctrl-u":
6393
6412
  this.killLine();
6394
6413
  return [];
@@ -6906,22 +6925,30 @@ var init_input = __esm({
6906
6925
  this.clearBuffer();
6907
6926
  return [{ type: "send", text, planMode, attachments }];
6908
6927
  }
6909
- // Shift+Enter: amend the in-flight turn. Editing a queued slot
6910
- // delegates to the existing queue-edit / queue-remove path Shift+Enter
6911
- // there has no special meaning since the entry is already queued (not
6912
- // running). With an empty draft and no attachments we emit nothing
6913
- // (no-op). Otherwise emit an "amend" effect; the app decides whether
6914
- // to route through amend_prompt or fall through to a regular send.
6928
+ // Shift+Enter (also Ctrl+Enter / ^S): amend the in-flight turn.
6929
+ // While editing a queued slot, this is the "drop and amend" chord:
6930
+ // emit queue-remove for the slot AND amend with the loaded (possibly
6931
+ // edited) text, so the queued prompt becomes the amendment for the
6932
+ // running turn in a single keystroke. Empty buffer + no attachments
6933
+ // on a slot collapses to just queue-remove (matches empty-Enter).
6934
+ // Outside queue editing, an empty draft is a no-op. The app decides
6935
+ // whether to route the amend through amend_prompt or fall through to
6936
+ // a regular send when no turn is in flight.
6915
6937
  amend() {
6916
6938
  const text = this.bufferText();
6917
6939
  if (this.queueIndex >= 0 && this.queueIndex < this.queue.length) {
6918
6940
  const index = this.queueIndex;
6941
+ const planMode2 = this.planMode;
6919
6942
  const attachments2 = [...this.attachments];
6943
+ const empty = text.trim().length === 0 && attachments2.length === 0;
6920
6944
  this.clearBuffer();
6921
- if (text.trim().length === 0) {
6945
+ if (empty) {
6922
6946
  return [{ type: "queue-remove", index }];
6923
6947
  }
6924
- return [{ type: "queue-edit", index, text, attachments: attachments2 }];
6948
+ return [
6949
+ { type: "queue-remove", index },
6950
+ { type: "amend", text, planMode: planMode2, attachments: attachments2 }
6951
+ ];
6925
6952
  }
6926
6953
  if (text.trim().length === 0 && this.attachments.length === 0) {
6927
6954
  return [];
@@ -13017,6 +13044,7 @@ async function runSession(term, config, target, opts, exitHint, viewPrefs) {
13017
13044
  history: buildCombinedHistory(globalHistory, history)
13018
13045
  });
13019
13046
  dispatcherRef = dispatcher;
13047
+ let livePeerHistoryRecording = false;
13020
13048
  const recordHistoryEntry = (entry) => {
13021
13049
  const trimmed = entry.replace(/\n+$/, "");
13022
13050
  if (trimmed.length === 0) {
@@ -13355,10 +13383,10 @@ async function runSession(term, config, target, opts, exitHint, viewPrefs) {
13355
13383
  const amendDesc = "amend the in-flight turn (cancel + replace)";
13356
13384
  const head = config.tui.defaultEnterAction === "amend" ? [
13357
13385
  ["Enter", amendDesc],
13358
- ["Ctrl+Enter / Shift+Enter", enqueueDesc]
13386
+ ["Ctrl+Enter / Shift+Enter / ^S", enqueueDesc]
13359
13387
  ] : [
13360
13388
  ["Enter", enqueueDesc],
13361
- ["Ctrl+Enter / Shift+Enter", amendDesc]
13389
+ ["Ctrl+Enter / Shift+Enter / ^S", amendDesc]
13362
13390
  ];
13363
13391
  return [...head, ...HELP_ENTRIES_TAIL];
13364
13392
  };
@@ -14256,6 +14284,9 @@ async function runSession(term, config, target, opts, exitHint, viewPrefs) {
14256
14284
  return;
14257
14285
  }
14258
14286
  if (event.kind === "user-text") {
14287
+ if (livePeerHistoryRecording) {
14288
+ recordHistoryEntry(event.text);
14289
+ }
14259
14290
  closeAgentText();
14260
14291
  if (toolsBlockStartedAt !== null) {
14261
14292
  toolsBlockEndedAt = Date.now();
@@ -14388,6 +14419,12 @@ async function runSession(term, config, target, opts, exitHint, viewPrefs) {
14388
14419
  };
14389
14420
  const buffered = bufferedEvents;
14390
14421
  bufferedEvents = [];
14422
+ const replayedPromptTexts = [];
14423
+ for (const event of buffered) {
14424
+ if (event.kind === "user-text" && typeof event.text === "string") {
14425
+ replayedPromptTexts.push(event.text);
14426
+ }
14427
+ }
14391
14428
  screen.pauseRepaint();
14392
14429
  try {
14393
14430
  for (const event of buffered) {
@@ -14396,6 +14433,15 @@ async function runSession(term, config, target, opts, exitHint, viewPrefs) {
14396
14433
  } finally {
14397
14434
  screen.resumeRepaint();
14398
14435
  }
14436
+ if (replayedPromptTexts.length > 0) {
14437
+ const merged = mergeReplayedEntries(history, replayedPromptTexts);
14438
+ if (merged !== history) {
14439
+ history = merged;
14440
+ dispatcher.setHistory(buildCombinedHistory(globalHistory, history));
14441
+ saveHistory(historyFile, history).catch(() => void 0);
14442
+ }
14443
+ }
14444
+ livePeerHistoryRecording = true;
14399
14445
  if (initialTurnStartedAt !== void 0 && pendingTurns > 0) {
14400
14446
  sessionBusySince = initialTurnStartedAt;
14401
14447
  screen.setBanner({
@@ -14834,7 +14880,7 @@ var init_app = __esm({
14834
14880
  ["^V", "paste image from clipboard"],
14835
14881
  ["^O", "expand / collapse tools block"],
14836
14882
  null,
14837
- ["^R / ^S", "history reverse / forward search"],
14883
+ ["^R", "history reverse search (^S walks forward once engaged)"],
14838
14884
  ["PgUp / PgDn", "scroll scrollback"],
14839
14885
  ["Mouse wheel", "scroll scrollback (when mouse capture is on)"],
14840
14886
  ["^X", "toggle mouse capture (wheel scroll vs. text selection)"],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hydra-acp/cli",
3
- "version": "0.1.46",
3
+ "version": "0.1.47",
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",