@nanhara/hara 0.132.1 → 0.132.3

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/CHANGELOG.md CHANGED
@@ -5,17 +5,36 @@ All notable changes to `@nanhara/hara`.
5
5
  > Versioning (pre-1.0, SemVer-style): the **minor** (middle) number bumps for a **new feature**; the
6
6
  > **patch** (last) number bumps for **optimizations/fixes of existing features**.
7
7
 
8
- ## 0.132.1 — 2026-07-22 — stable native release gates
8
+ ## 0.132.3 — 2026-07-22 — immediate prompt-key routing and verified release carrier
9
+
10
+ - TUI approval/select input now reads the live visible prompt and selection through stable refs. A key pressed
11
+ immediately after the prompt paints can no longer hit the previous render's null-prompt closure and be
12
+ swallowed; rapid arrow-plus-Enter input also uses the current selection before the next paint.
13
+ - The confirmation regression waits for the visible prompt and then presses `y` without an arbitrary grace
14
+ delay, covering the Node 24 CI failure directly. Remaining process-tree fixtures also wait for valid PID
15
+ content rather than file creation alone. This patch carries the complete 0.132 feature set into the native
16
+ and Desktop release train. Upgrade with `npm i -g @nanhara/hara@0.132.3`.
17
+
18
+ ## 0.132.2 — 2026-07-22 — complete bounded native release gates (npm published; native assets withheld)
19
+
20
+ - The remaining approved-org process-tree and TUI confirmation tests now wait for concrete PID/render
21
+ readiness before starting their decisive assertion, and always clean up mounted Ink apps after a failure.
22
+ This closes the last Intel macOS release-runner races without weakening runtime timeouts or child cleanup.
23
+ - The npm package contains the observable gateway status, scoped web proxy, complete config redaction, and
24
+ user-managed organization connection features introduced in 0.132.0. Native release assembly was cancelled
25
+ after Node 24 CI exposed a visible-prompt input-handler race; upgrade to 0.132.3 instead.
26
+
27
+ ## 0.132.1 — 2026-07-22 — bounded native release-gate waits (npm published; native assets withheld)
9
28
 
10
29
  - Native release tests now wait for observable child-process and terminal-render handshakes within explicit
11
30
  upper bounds instead of assuming fixed startup delays. This removes an Intel macOS runner race that could
12
31
  read fixture state before Node or Ink had started while preserving the timeout, process-tree cleanup, MCP
13
32
  diagnostic-boundary, and command-history assertions.
14
- - This patch carries the observable gateway status, scoped web proxy, full config redaction, and
15
- user-managed organization connection features introduced in 0.132.0 into the verified standalone and
16
- Desktop release train. Upgrade with `npm i -g @nanhara/hara@0.132.1`.
33
+ - The npm package carries the observable gateway status, scoped web proxy, full config redaction, and
34
+ user-managed organization connection features introduced in 0.132.0. Its native asset release remained
35
+ withheld after two further Intel-only test synchronization failures; upgrade to 0.132.2 instead.
17
36
 
18
- ## 0.132.0 — 2026-07-22 — observable chat gateways and scoped web proxies
37
+ ## 0.132.0 — 2026-07-22 — observable chat gateways and scoped web proxies (npm published; native assets withheld)
19
38
 
20
39
  - `hara gateway status --platform <name>` now reports redacted credential readability, the live
21
40
  credential-scoped lease/PID, transport state, start time, last connection/poll/message, bounded error code,
package/dist/tui/App.js CHANGED
@@ -373,6 +373,13 @@ export function App({ initialStatus, model, cwd, header, onSubmit, agentSlashCom
373
373
  const [status, setStatus] = useState({ ...initialStatus, agents: 0 });
374
374
  const [prompt, setPrompt] = useState(null);
375
375
  const [promptSel, setPromptSel] = useState(0);
376
+ // Ink updates useInput's callback after a render effect. Keep the visible prompt/selection in refs too,
377
+ // so the already-registered handler can consume a key pressed immediately after the prompt paints instead
378
+ // of routing it through the previous render's null prompt closure.
379
+ const promptRef = useRef(prompt);
380
+ promptRef.current = prompt;
381
+ const promptSelRef = useRef(promptSel);
382
+ promptSelRef.current = promptSel;
376
383
  // Free-text question prompt (ask_user with no/declined options): re-enables the InputBox to capture one
377
384
  // line, then resolves the awaiting tool with that text. Separate from `prompt` (the select-only path).
378
385
  const [askText, setAskText] = useState(null);
@@ -598,6 +605,7 @@ export function App({ initialStatus, model, cwd, header, onSubmit, agentSlashCom
598
605
  reject(promptAbortReason(signal));
599
606
  };
600
607
  signal.addEventListener("abort", onAbort, { once: true });
608
+ promptSelRef.current = 0;
601
609
  setPromptSel(0);
602
610
  setPrompt({
603
611
  token,
@@ -720,6 +728,7 @@ export function App({ initialStatus, model, cwd, header, onSubmit, agentSlashCom
720
728
  });
721
729
  }, [working, prompt, askText, handleSubmit]);
722
730
  useInput((input, key) => {
731
+ const activePrompt = promptRef.current;
723
732
  if (key.ctrl && input === "t")
724
733
  return setShowTranscript((x) => !x); // open/close the full-transcript overlay
725
734
  if (showTranscript)
@@ -736,28 +745,36 @@ export function App({ initialStatus, model, cwd, header, onSubmit, agentSlashCom
736
745
  }
737
746
  return;
738
747
  }
739
- if (prompt) {
740
- const opts = prompt.options;
748
+ if (activePrompt) {
749
+ const opts = activePrompt.options;
741
750
  if (key.upArrow)
742
- setPromptSel((s) => (s - 1 + opts.length) % opts.length);
751
+ setPromptSel((s) => {
752
+ const next = (s - 1 + opts.length) % opts.length;
753
+ promptSelRef.current = next;
754
+ return next;
755
+ });
743
756
  else if (key.downArrow)
744
- setPromptSel((s) => (s + 1) % opts.length);
757
+ setPromptSel((s) => {
758
+ const next = (s + 1) % opts.length;
759
+ promptSelRef.current = next;
760
+ return next;
761
+ });
745
762
  else if (key.return) {
746
- prompt.resolve(opts[Math.min(promptSel, opts.length - 1)].value);
763
+ activePrompt.resolve(opts[Math.min(promptSelRef.current, opts.length - 1)].value);
747
764
  }
748
765
  else if (key.escape) {
749
- if (prompt.abortTurnOnEscape && working && ctrlRef.current)
766
+ if (activePrompt.abortTurnOnEscape && working && ctrlRef.current)
750
767
  abortCurrentTurn();
751
768
  else
752
- prompt.resolve(opts[opts.length - 1].value); // select-only prompt: last option = cancel/no
769
+ activePrompt.resolve(opts[opts.length - 1].value); // select-only prompt: last option = cancel/no
753
770
  }
754
771
  else if (/^[1-9]$/.test(input) && Number(input) <= opts.length) {
755
- prompt.resolve(opts[Number(input) - 1].value); // type a number to pick directly
772
+ activePrompt.resolve(opts[Number(input) - 1].value); // type a number to pick directly
756
773
  }
757
774
  else if (input) {
758
775
  const hit = opts.find((o) => o.key && o.key === input.toLowerCase());
759
776
  if (hit) {
760
- prompt.resolve(hit.value);
777
+ activePrompt.resolve(hit.value);
761
778
  }
762
779
  }
763
780
  return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nanhara/hara",
3
- "version": "0.132.1",
3
+ "version": "0.132.3",
4
4
  "description": "hara — a coding agent CLI that runs like an engineering org.",
5
5
  "bin": {
6
6
  "hara": "runtime-bootstrap.cjs"