Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .changeset/upgrade-ink-v8.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
"@nanocollective/nanocoder": minor
---

Upgrades Ink from 6.8 to 8.0 and raises the React dependency floor to 19.3. Ink 8 types `useStdout()`'s stream as a plain Node.js `WritableStream` and drops terminal control sequences it cannot map to a key before they reach `useInput`.

- The stdin proxy rewrites xterm's modifyOtherKeys form of modified Enter (`ESC [27;<m>;13~`, used by VS Code terminal keybindings) into kitty CSI-u (`ESC [13;<m>u`), which Ink parses natively. Fragmented sequences are reassembled before rewriting.
- Preserves the patch-independent raw-input handling introduced by #1670, including its guard against reading `key.raw`. Backspace and forward Delete remain distinct; the upgrade does not revert the packaging fix.

The startup-time patch importing `es-toolkit/compat/throttle` directly instead of the barrel file is carried over to Ink 8.

Related input regressions: #1505 (already fixed on main by #1670) and #1664. This upgrade is related follow-up work, not a claim that those reports require Ink 8. See [terminal compatibility checks](../docs/features/terminal-compatibility.md) for automated coverage and the manual smoke-test procedure.
47 changes: 47 additions & 0 deletions docs/features/terminal-compatibility.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
---
title: "Terminal Compatibility Checks"
description: "Reproducing modified Enter and external-editor handoff checks"
---

# Terminal Compatibility Checks

These checks distinguish byte-sequence regression coverage from interaction with a real terminal. An automated parser or Ink rendering test does not establish that VS Code emits the expected bytes or that an external editor receives a usable terminal.

## Related input issues

- [#1505](https://github.com/Nano-Collective/nanocoder/issues/1505): Backspace acted as forward Delete on published installations. Main fixed the dependency on patched `key.raw` in [#1670](https://github.com/Nano-Collective/nanocoder/pull/1670). The Ink upgrade must retain that patch-independent behavior and its regression guard.
- [#1664](https://github.com/Nano-Collective/nanocoder/issues/1664): another Backspace report involving Konsole and VS Code. This is related coverage, not a claim that upgrading Ink is required to fix that report.

## Automated coverage

Run from the repository root:

```sh
pnpm run test:types
pnpm run test:ava source/utils/terminal-keypress.spec.ts source/utils/terminal-input.spec.ts source/utils/terminal-paste.spec.ts source/utils/newline-key.spec.ts source/components/text-input-keys.spec.tsx source/components/text-input-newline.spec.tsx source/components/input-swap.spec.tsx source/components/user-input.spec.tsx
pnpm run test:ava source/wizards/base-config-wizard.spec.tsx source/wizards/steps/mcp-step.spec.tsx
```

These suites cover modified Enter (including fragmented reads), ordinary Enter, Backspace versus forward Delete, keys interleaved with bracketed paste, focused paste targets, and input after a same-commit component swap. They do not replace either manual check below. Run each command only on the branch that contains the referenced feature and tests; a minimal Ink-upgrade PR need not include the paste/FIFO suites.

## VS Code integrated-terminal smoke test

1. Build with `pnpm run build`. Launch `node dist/cli.js` inside the VS Code integrated terminal, not the VS Code extension's separate chat view. Record VS Code version, OS, shell, and Nanocoder commit.
2. Record the existing terminal keybindings. For the xterm rewrite check, temporarily use `workbench.action.terminal.sendSequence` with `"when": "terminalFocus"`, mapping Shift+Enter to `"\u001b[27;2;13~"` and Alt+Enter to `"\u001b[27;3;13~"`. Testing only a binding that sends `"\n"` does not exercise that rewrite.
3. Type `ab`, move the caret between the letters, press Shift+Enter, then type `x`. The result must be `a\nxb`, with no submission and no literal escape-sequence text. Repeat with Alt+Enter and with Ctrl+J.
4. Check Backspace and Delete in the middle of `abc`: Backspace removes the character to the left; Delete removes the character to the right. Repeat beside an emoji.
5. Paste a multiline block between typed characters, then type immediately afterwards. The surrounding text must stay in order and the paste must not submit. Test the MCP wizard's env-vars field separately if the paste-target change is present.
6. Verify plain Enter still submits only when intended, then restore the original keybindings. Repeat in inline mode (`--no-alt-screen`).

## External-editor handoff smoke test

Use a disposable workspace and configuration directory without credentials. Select a terminal editor such as `vi` as the editor for the configuration wizard; a GUI editor does not exercise raw/cooked terminal handoff.

1. In the configuration wizard, reach the review step and choose its external-editor action. Record the editor version, OS, terminal, and Nanocoder commit.
2. Confirm that the editor accepts normal typing, cursor movement, and multiline paste without literal paste/mouse escape sequences. Save a harmless configuration change and quit.
3. Confirm that the wizard repaints and responds to keys after the editor exits. Try a second handoff and an exit without saving; check that each returns control to the wizard.
4. Repeat in fullscreen and inline modes. After leaving Nanocoder, check that the shell echoes input normally and that paste markers and mouse-report bytes do not appear as text.

## Reporting results

For each manual check, report the commit, OS, terminal/editor versions, keybinding sequences, screen mode, and observed result in the PR. Mark unperformed checks **not run**. In particular, do not report the external-editor handoff or real VS Code interaction as verified solely because the automated suites passed.
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@
"diff": "^9.0.0",
"dotenv": "^18.0.5",
"ignore": "^7.0.5",
"ink": "^6.3.1",
"ink": "8.0.0",
"ink-big-text": "^2.0.0",
"ink-gradient": "^4.0.0",
"ink-select-input": "^6.2.0",
Expand All @@ -106,7 +106,7 @@
"lru-cache": "^11.5.1",
"pino": "^10.1.0",
"playwright-core": "^1.63.0",
"react": "^19.0.0",
"react": "^19.3.0",
"string-width": "^8.2.2",
"tiktoken": "^1.0.22",
"undici": "^8.5.0",
Expand All @@ -122,7 +122,7 @@
"@nanocollective/nanocoder-voice": "workspace:*",
"@types/cross-spawn": "^6.0.6",
"@types/node": "^26.1.2",
"@types/react": "^19.0.0",
"@types/react": "^19.3.0",
"@types/ws": "^8.18.1",
"ajv": "^8.20.0",
"ava": "^8.0.1",
Expand Down
52 changes: 0 additions & 52 deletions patches/ink@6.8.0.patch

This file was deleted.

17 changes: 17 additions & 0 deletions patches/ink@8.0.0.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
diff --git a/build/ink.js b/build/ink.js
index 30019a073d38ed05dca08f6221af187c429a536b..5254bf400cda5f4d7fdc95c0a0f6ccd8fd5cfd35 100644
--- a/build/ink.js
+++ b/build/ink.js
@@ -1,6 +1,11 @@
import process from 'node:process';
import React from 'react';
-import { throttle } from 'es-toolkit/compat';
+// Patched by nanocoder: import the deep subpath directly so Node doesn't
+// resolve the entire `es-toolkit/compat` barrel file (which eagerly requires
+// ~1244 individual utility modules just to re-export them). Using the
+// subpath loads only `throttle`, dropping the CLI startup module count by
+// ~1240.
+import throttle from 'es-toolkit/compat/throttle';
import ansiEscapes from 'ansi-escapes';
import isInCi from 'is-in-ci';
import autoBind from 'auto-bind';
Loading
Loading