Commit Graph
3070 Commits
Author SHA1 Message Date
Netcatty-Bot 5df2181392 fix(terminal): self-heal cursor line highlight on external decoration disposal (#3657)
Recreate cursor-line markers/decorations when xterm disposes them externally, and treat empty decoration sets as intact so fully colored rows do not churn markers every frame.

Fixes #3656
2026-10-13 17:35:01 +08:00
Netcatty-Bot 231982d673 fix(window): fit minimum size to small displays and restore terminal focus after resize (#3648)
Clamps the window layout minimum to the current display work area so small screens (e.g. 1366×768 at 125%) can fit and shrink. Restores terminal keyboard focus after OS resize/maximize, without stealing from active editable fields.

Fixes #3647

Merged by judgment: four Codex rounds already addressed the real bugs and multi-monitor sync; the latest P2 (protect every non-editable focusable control on resize) is edge-case thrash.
2026-10-13 17:29:35 +08:00
11c90b45ec feat(terminal): disable auto-close-on-exit by default (#3619)
* feat(terminal): disable auto-close-on-exit by default

Remote graceful channel closes (VPN half-close, server-side idle kick) can be reported as a clean exit with code 0, so with auto-close enabled the tab gets destroyed exactly when the user needs it kept - bypassing the SSH auto-reconnect loop, which intentionally skips exited events.

Keep tabs on exit by default; users who want close-on-exit can enable it in Settings > Terminal > Behavior. Attach-mode close behavior is unchanged.

* fix(terminal): keep session tabs when the auto-close setting is unavailable

The resolver's own default and the TerminalLayer call-site fallback still
treated a missing terminal setting as auto-close enabled. Remote graceful
channel closes (a jump host reaping an idle session) are reported as a
clean exit, so before the settings store had loaded, those closes silently
deleted the session tab and its scrollback. This completes the opt-in
default introduced above: only an explicit autoCloseOnExit true closes tabs.

* fix(terminal): migrate the materialized auto-close-on-exit default once

Builds before the default flip shipped autoCloseOnExit: true as the
default and materialized it into netcatty_term_settings_v1 on any
settings write, so most upgraders carry a value they never chose and
the new default-off never reaches them: bastion and idle-harvesting
servers reporting clean exits keep silently deleting their tabs.

Reset that materialized true exactly once behind a marker key before
the settings blob is first ingested, then persist the marker so every
later stored value is treated as the user's own choice. The cost is
documented: a user who deliberately enabled auto-close before this
release must re-enable it once.

* fix(terminal): keep synced legacy auto-close from coming back

A device that already wrote the one-shot migration marker was accepting
a pre-migration cloud or backup payload with autoCloseOnExit true.
Unversioned true is rewritten to false. Payloads that record the
migration still sync an explicit opt-in, including across a three-way
merge that would otherwise glue the local marker onto a legacy true.

Co-authored-by: 陈大猫 <binaricat@users.noreply.github.com>

---------

Co-authored-by: xu <tbqyomnnnbltzxy2t@aliyun.com>
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: 陈大猫 <binaricat@users.noreply.github.com>
2026-10-13 17:11:15 +08:00
陈大猫 747fdeb0f3 fix(shortcuts): save modifier edits when the chord is released (#3641) 2026-10-13 16:44:27 +08:00
Netcatty-Bot 201ebcb21a feat(ai): search session history titles and bounded content (#3601)
Keep history search bounds local and preserve complete-field shared pinyin matching.

Fixes #3598
2026-10-12 11:52:21 +08:00
Netcatty-Bot 11f2b7dbd8 fix(terminal): surface snippet completions while typing an argument (#3623)
Match argument snippets conservatively and remove stale snippet rows on input edits before the debounced refresh.

Related to #3622; the email-entry/editor concern remains unverified and the issue stays open.
2026-10-12 11:41:39 +08:00
陈大猫 c89e4c7246 fix(notes): preserve pending drafts after storage write failures (#3629)
Preserve pending local notes and conflicting external content across failed writes and successful retries.

Retain explicit clear/import replacement ownership until the current generation persists.
2026-10-12 11:40:17 +08:00
90ab87efcc feat(editor): detached multi-tab window with acknowledged content handoff (#3606)
Add a detached multi-tab editor window with acknowledged content ownership, focused Monaco shortcuts, and shared close/save confirmation. Preserve source contents until handoff acknowledgement and block edits or incoming transfers during ownership changes.

Continuation of #3439. Original implementation by pplulee.

Co-authored-by: pplulee <hi@pplulee.me>
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-08 18:11:23 +08:00
陈大猫andnetcatty-bot 4cd6a7191d feat(sftp): add Cancel all action to transfer center (#3574)
* feat(sftp): add cancel all to transfer center

* fix: address Codex review on PR #3574

* fix: address Codex review on PR #3574

* fix: address Codex review on PR #3574

* fix: address Codex review on PR #3574

* fix: address Codex review on PR #3574

* fix: address Codex review on PR #3574

* fix: address Codex review on PR #3574

* fix: address Codex review on PR #3574

* fix: address Codex review on PR #3574

* fix: address Codex review on PR #3574

* fix: address Codex review on PR #3574

* fix: address Codex review on PR #3574

* fix: address Codex review on PR #3574

* fix: address Codex review on PR #3574

* fix: address Codex review on PR #3574

* fix: address Codex review on PR #3574

* fix: address Codex review on PR #3574

* fix: address Codex review on PR #3574

* fix(sftp): settle cancelled walks before directory recovery

* fix(sftp): report failed cancel attempts without blocking retries

* fix(sftp): batch pending cancel cleanup for large queues

* fix(sftp): preserve settled children during cancel recovery

* fix(sftp): release skipped cancel-all pre-latches

* fix(sftp): satisfy cancellation result and fixture types

* fix(sftp): dispatch cancel batches before walk settlement

* fix(sftp): distinguish live compression recovery from restored attention

---------

Co-authored-by: netcatty-bot <308658023+netcatty-bot@users.noreply.github.com>
2026-10-08 17:50:41 +08:00
f7483f0593 fix(scripts): add persistable stacked chip view to script library panel (#3567)
* fix(#3565): automated AI fix

* fix: address Codex review on PR #3567

* fix: address Codex review on PR #3567

* fix: address Codex review on PR #3567

* fix: address Codex review on PR #3567

* fix(scripts): observe stacked sentinel again after returning to library

* fix(scripts): reuse shared persisted string hook for cross-window view changes

---------

Co-authored-by: netcatty-bot <308658023+netcatty-bot@users.noreply.github.com>
Co-authored-by: 陈大猫 <16399091+binaricat@users.noreply.github.com>
2026-10-08 15:20:22 +08:00
Netcatty-Botandnetcatty-bot 1209bfa61c fix(ai): opencode model catalog loading state, retry, and warmer list server (#3585)
* fix(#3584): automated AI fix

* fix: address Codex review on PR #3585

* fix: address Codex review on PR #3585

---------

Co-authored-by: netcatty-bot <308658023+netcatty-bot@users.noreply.github.com>
2026-10-08 15:16:49 +08:00
Netcatty-Botandsi1enteee 16376a2117 fix(terminal): use xterm synchronized-output state for clear handling (#3596)
Use xterm's native synchronized output state for viewport preservation, remove the redundant mode tracker, and exercise the production callback path in regression tests.

Fixes #3595

Co-authored-by: si1enteee <si1enteee@users.noreply.github.com>
2026-10-08 15:08:11 +08:00
Yohannandyangheng 75c155b748 feat(vault): add host connection test to the host editor (#2984)
* feat(vault): add host connection test to the host editor

Add a 'Test' button next to Save in the host editor that opens a dialog reusing the terminal's connection progress/auth/host-key UI, and runs a headless connection probe:

- Main process: netcatty:test-connection reuses startSSHSession in a testMode that authenticates then tears down without opening a shell, reports via netcatty:test:result, and supports cancellation (netcatty:test-connection:cancel).
- Renderer: useHostConnectionTest hook + HostConnectionTestDialog component; single-credential auth (no agent/default-key fallback) with short test timeouts (8s TCP / 15s auth).
- Reuses terminal chain progress, host-key verification, and auth prompts; success keeps the same dialog with retry/close.

* fix(ssh): cancel test connections during chain/proxy dial

Register the headless test-connection transport before connectThroughChain / createProxySocket runs, and update its pendingConn / chainConnections as hops and proxy sockets are established. This lets cancelTestConnection abort a slow/unreachable bastion or proxy dial instead of leaving it running until timeout.

* fix(ssh): address host connection test review feedback

- Route jump-host keyboard-interactive prompts through the external scope in test mode
- Always offer keyboard-interactive for requiresMfa hosts in test mode, including key/certificate-only auth
- Derive the renderer test deadline from the probe options and cancel the attempt on timeout
- Run the macOS Local Network preflight before connection tests
- Add regression tests for jump-host MFA, MFA auth order, test deadline, and macOS preflight

Author: yangheng
Model: claude-opus-5

---------

Co-authored-by: yangheng <492238647@qq.com>
2026-10-08 14:42:18 +08:00
Netcatty-Botandnetcatty-bot 6fcd6a3ec3 fix(#3591): automated AI fix (#3593)
Co-authored-by: netcatty-bot <308658023+netcatty-bot@users.noreply.github.com>
2026-10-08 14:31:43 +08:00
b2ed83ae51 fix(tray): add independent persisted show-tray-icon setting (#3572)
* fix(#3553): automated AI fix

* fix(tray): keep icon visible independently of close behavior

* docs(settings): clarify background close behavior

* fix(settings): preserve tray visibility for existing users

---------

Co-authored-by: netcatty-bot <308658023+netcatty-bot@users.noreply.github.com>
Co-authored-by: binaricat <16399091+binaricat@users.noreply.github.com>
2026-09-30 15:11:23 +08:00
陈大猫 f91b2cd04e feat(ai): scope external MCP approvals to connection or host (#3569)
* feat(ai): scope external MCP approvals to connection or host

* test(ai): keep MCP fixture in Netcatty temp directory

* fix(ai): refine external MCP approval UI and grant safety

* fix(ai): wrap long approval targets and support Node 22

* fix(ai): keep automatic scripts in observer mode

* fix(sftp): release preflight markers after transfer

* fix(sftp): retain preflight cap through conflict resolution

* Keep SFTP preflight cap across panel remount

* Update worker terminal metadata expectations

* Persist SFTP preflight skip state across restart

* Limit persistent host approvals to saved hosts

* Scope host-open approvals to the selected saved host

* Exclude serial hosts from persistent approval scopes
2026-09-30 09:57:47 +08:00
1d10d1679e fix(terminal): opt-in broadcast without password protection during interactive prompts (#3491)
* fix(#3488): automated AI fix

* fix: address Codex review on PR #3491

* fix: address Codex review on PR #3491

* fix: address Codex review on PR #3491

* fix: address Codex review on PR #3491

* fix: address Codex review on PR #3491

* fix: address Codex review on PR #3491

* fix: address Codex review on PR #3491

* fix: address Codex review on PR #3491

* fix: address Codex review on PR #3491

* fix: address Codex review on PR #3491

* fix: address Codex review on PR #3491

* fix: address Codex review on PR #3491

* test: verify broadcast password prompts on Windows desktop

* test: run desktop SSH check only in Windows job

* fix: preserve sensitive peer input across compose wake

* fix: retain compose history when sensitive peer receives nothing

* fix: protect compose history during sensitive fallback writes

---------

Co-authored-by: netcatty-bot <308658023+netcatty-bot@users.noreply.github.com>
Co-authored-by: bincxz <16399091+binaricat@users.noreply.github.com>
2026-09-30 00:38:50 +08:00
陈大猫 8d2058267a fix(terminal): commit live IME transcription once (#3568)
* fix(terminal): commit live IME transcription once

xterm sends a rewritten dictation hypothesis as the interim, the full
final string, and the tail. Keep the pending textarea diff from firing
again when composition starts, and send only the part that is not
already on the PTY.

* fix(terminal): retype rewritten IME tails as separate backspaces

A shared suffix has to be deleted and typed again because the cursor
stays at the end of the line. One-character hypotheses are real
prefixes, and each backspace is its own input event so Ctrl-H hosts
still erase.

* fix(terminal): rewrite a revised IME hypothesis in place

A composition that replaces the snapshot, instead of extending it,
sends the cancelled textarea edit. Deletions are counted in graphemes
so a surrogate pair is one backspace.

* fix(terminal): send a new IME word that shares a finished prefix

A composition that starts at or after the snapshot is a new word.
Sharing the first character with text already on the PTY is not
enough to treat it as the same hypothesis.

* fix(terminal): remember a rewritten IME hypothesis in full

A 229 rewrite stored only the inserted tail, so a later
compositionend with no composition marker sent the revised
line again. Remember the whole revised textarea instead.

* fix(terminal): preserve IME rewrite state across delayed commits
2026-09-29 23:07:10 +08:00
陈大猫 9423a1d1cd fix(ssh): drop the manual single-channel SSH toggle (#3561)
* fix(ssh): 去掉单通道 SSH 的手动开关

单通道只在握手后匹配 BHostSSH、TERM-SSHD、CLOUDBILITY 时生效。
主机和分组不再保存这个选项,读到旧字段时直接丢掉。

* test(sftp): 对齐单通道登录后的重连扫描

专用 SFTP 登录改为 reuseTerminalTransport 之后,旧的 sourceSessionId 三元表达式扫描不再匹配,lint-and-test 因此失败。扫描改为锁定当前门槛:已连接,或已经钉住严格来源,才复用终端传输。
2026-09-29 20:05:51 +08:00
Netcatty-Botandnetcatty-bot 50ca182e1e fix(#3562): automated AI fix (#3564)
Co-authored-by: netcatty-bot <308658023+netcatty-bot@users.noreply.github.com>
2026-09-29 19:47:06 +08:00
陈大猫 04a63c653a fix(ui): apply the chosen app icon to the Windows tray (#3563)
* fix(ui): apply the chosen app icon to the Windows tray

Settings already swap the taskbar icon. On Windows, the notification
area now follows that choice. Original keeps the multi-size tray ico;
other variants are scaled to the small-icon size Windows asks for.

* fix(ui): crop the app-icon margin before sizing the Windows tray

The variant PNGs keep a transparent inset, so scaling them straight into
the notification slot made every non-original style smaller than the
full-bleed tray ico. Crop to the opaque artwork first.

* test(sftp): update the side-panel reuse source lock

The single-channel change replaced the connected-only sourceSessionId
ternary with reuseTerminalTransport. The source lock still expected the
old expression, so lint-and-test fails on main.
2026-09-29 19:25:29 +08:00
又是一条懒汉 5805d15746 feat(ssh): add single-channel SSH option for bastion hosts (#3458)
Add a host and group toggle for bastions that allow one session channel per TCP connection. After the handshake, BHostSSH, TERM-SSHD, and CLOUDBILITY take that path automatically. File transfer uses a separate SFTP login, and the interactive terminal is not given another exec, SFTP, copy/split, or port-forward channel.

The manual toggle remains for bastions that still advertise OpenSSH.
2026-09-29 18:01:04 +08:00
陈大猫 bd8476fb34 fix(terminal): enable font ligatures from the terminal setting (#3557)
fontLigatures already defaulted to on, but the terminal never loaded
the ligatures addon, so Fira Code and Maple Mono kept drawing != as two
cells. Activate the addon after open and before WebGL, and rebuild the
WebGL atlas when the setting changes so glyphs are not rasterized
without the calt feature.

The addon bundles lru-cache's node:diagnostics_channel import. Alias
that builtin to a no-op channel in the Vite renderer build and in the
Electron live-test bundles.

Closes #3543
2026-09-29 17:34:00 +08:00
f1425c8d5a feat(ai): add MiMo Code (mimo) agent support (#3500)
* feat(ai): add MiMo Code (mimo) agent support scaffolding

Registry/wiring only: discovery entry, managed-agent metadata, model presets, icon, i18n and Settings UI for Xiaomi's MiMo Code CLI (an OpenCode fork). The SDK driver is intentionally not wired yet - it depends on the pending @mimo-ai/sdk parity probe, so DRIVER_REGISTRY keeps a TODO and run-turn/list-models reject the mimo backend until then.

* feat(ai): add MiMo Code (mimo) agent support

Adds Xiaomi's MiMo Code CLI as a managed agent backend, mirroring the existing
OpenCode integration (discovery, managed-agent metadata, model presets, icon,
i18n, Settings UI) and adding the SDK driver that was left as a TODO in the
scaffolding commit.

Driver notes:
- New electron/bridges/aiBridge/sdk/mimoDriver.cjs reuses the pure translation
  helpers exported by opencodeDriver.cjs (config/prompt building, event
  translation, model mapping) because MiMo Code is an OpenCode fork and speaks
  the same wire protocol.
- It does NOT use @mimo-ai/sdk's createOpencode(). On 0.1.15 that helper spawns
  a binary named "opencode", waits for an "opencode server listening" banner,
  and passes config via OPENCODE_CONFIG_CONTENT; the mimo CLI prints
  "mimocode server listening on <url>", reads MIMOCODE_CONFIG_CONTENT, and ships
  as "mimo"/"mimo.exe". So createOpencode() can only ever time out. The driver
  runs "mimo serve" itself, parses the readiness URL, and attaches the SDK's
  createOpencodeClient({ baseUrl }).
- Binary resolution honours binPath, MIMOCODE_BIN and MIMOCODE_BIN_PATH, then
  falls back to PATH via resolveCliFromPath (the npm shim is mimo.cmd on
  Windows, which Node cannot spawn directly).
- @mimo-ai/sdk ^0.1.15 added as a dependency.

Verified on Windows against mimo 0.1.15 + @mimo-ai/sdk 0.1.15:
- "mimo serve --port" boots and reports its URL; driver parses it.
- SDK symbols used all exist: createOpencodeClient, client.config.providers(),
  client.global.event() (SSE stream), client.session.create/abort/promptAsync.
- Live provider catalog reads 2 providers (xiaomi, mimo); MIMO_MODEL_PRESETS
  updated to the real lower-case provider-prefixed ids and its TODO removed.
- Server process is killed on close (taskkill tree kill), no orphan processes.

Not yet verified at runtime:
- A full end-to-end turn (no prompt was sent, so no tokens were spent): text /
  reasoning / tool-part streaming and abort handling are untested against a
  live model.
- MIMOCODE_CONFIG_CONTENT accepting the OpenCode config schema (permission,
  mcp, model, share, autoupdate) end-to-end; only that the env var exists in
  the binary has been confirmed.
- Whether the loopback server needs MIMOCODE_SERVER_PASSWORD when the API
  client attaches.
- The placeholder public/ai/agents/mimo.svg still needs an official asset.
- Multi-turn resume (resumeSessionId) and MCP injection against the live CLI.

* feat(ai): inject MIMOCODE_BIN for discovered MiMo Code agents

Mirror the OpenCode OPENCODE_BIN handling so a discovered or re-detected
mimo binary path reaches the driver, and cover it with the same assertion
shape as the opencode managed-agent env test.

* fix(ai): use MiMo branding in the mimo driver

* test(ai): cover the mimo driver

Add a unit test file for the MiMo Code driver, matching the existing
opencode driver test in shape, runner (node:test via node --test) and
`.test.cjs` extension. It is the last driver in the registry without
one.

Coverage:
- spawn/launch: `mimo serve --hostname/--port` argv, binary resolution
  (explicit binPath / MIMOCODE_BIN / MIMOCODE_BIN_PATH), pass-through
  env and MIMOCODE_CONFIG_CONTENT; `child_process.spawn` is stubbed, so
  no real `mimo` process is ever started.
- readiness: parsing of `mimocode server listening on <url>` from
  stdout (including split chunks) and stderr, the OpenCode spelling,
  and the MIMO_SERVE_TIMEOUT_MS timeout path (asserts the rejection and
  that the child is killed).
- abort/cleanup: stopMimoProcess kill/idempotency/swallow, the Windows
  taskkill tree kill, server.close() teardown, and abort mid-turn with
  a throwing close().
- branding: OpenCode -> MiMo Code for the busy/idle/status, failed and
  tool-failure fallback strings, with tool output and non-brand
  technical errors left verbatim.
- happy path: session create -> streamed event translation -> done,
  plus listMimoModels catalog mapping and the empty/aborted paths.

* fix(ai): filter MiMo events by session and stop the server behind the npm shim

Address review on #3500:

- The global SSE stream carries every session on the server, and
  runMimoTurn translated all of them, so another session's text could leak
  into the reply and its session.idle could end the turn early. Skip events
  whose session id is not ours, reusing the OpenCode driver's
  getOpenCodeSessionIdFromEvent (now exported). Covered by a test with
  interleaved sessions.
- On macOS/Linux the official @mimo-ai/cli `mimo` is a Node shim that runs
  the native binary through spawnSync, so killing the shim left the server
  listening. `mimo serve` is now spawned detached on POSIX and
  stopMimoProcess signals its whole process group (SIGTERM, then SIGKILL
  after a grace period). Windows keeps taskkill /T.

Verified against the real @mimo-ai/cli@0.1.15 npm shim: on Linux (WSL
Ubuntu 22.04) the listener is the native .mimocode child; before this change
it was still listening 3s after close(), now the port is released within 1s
and no mimo process remains. On Windows the .cmd shim path also releases the
port within 1s.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix: harden MiMo CLI integration before merge

* fix: wait for MiMo events and handle setup cancellation

* fix: finish MiMo stream handling and scope skill access

* fix: preflight MiMo skill paths before one server startup

* fix: scope MiMo skill reads to trusted roots

* fix: allow MiMo skills from ancestor project roots

* fix: honor MiMo observer and confirm command permissions

* fix: clear MiMo approval when its service exits

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: bincxz <16399091+binaricat@users.noreply.github.com>
2026-09-29 14:51:22 +08:00
fc55e9ac17 feat(vault): let Skills + CLI operate notes with the same approval as MCP (#3512)
* feat(vault): let Skills + CLI operate notes with the same approval as MCP

Expose vault note list, read, write, and markdown import on the tool CLI so agents can save generated documents only after the user approves.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(vault): keep explicit empty note fields in the CLI

A supplied empty string was treated as an omitted flag, so note clears and empty markdown imports never reached the note service.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(vault): allow an explicit empty note body on CLI create

notes create --content "" was rejected as a missing flag, so it did not match vault_notes_create.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(vault): stop echoing imported note bodies and recognize leading CLI flags

A batch import resent every document over IPC, and a leading --json hid the notes command from artifact inference.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(vault): make note CLI import safe and fail writes cleanly

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: bincxz <16399091+binaricat@users.noreply.github.com>
2026-09-29 12:22:35 +08:00
OOKAMISAMAandbincxz 6ece7e8222 feat(terminal): Add configurable terminal bar cursor width (#3495)
* feat(terminal): Add configurable terminal bar cursor width

Adds a configurable bar-cursor width for the terminal so thin vertical cursors are easier to find, particularly when vi/vim switches to insert mode.

* Add terminal bar cursor width setting

This adds the terminal bar cursor width control to the settings UI with an aria-label for accessibility and a matching test. It also adds localized labels/descriptions and search catalog entries so the setting is discoverable in both English and Chinese.

* Fix terminal cursor width override bug

Prevent width-only cursor updates from clearing DEC/vi cursor overrides by tracking the last applied shape/blink snapshot. The runtime now resets the snapshot on teardown, skips full cursor reapplication for width-only changes, and preserves remote bar/underline cursor styles. Added regression tests covering boot-time and later width updates.

* Fix terminal cursor preference lifecycle

Preserve DEC/vi cursor overrides during the first width-only terminal update after runtime creation. The runtime now records the user cursor preference snapshot when a term is published and applies width-only updates without clearing active cursor style or blink overrides. This prevents regressions when terminal settings change before the panel has fully booted.

---------

Co-authored-by: bincxz <16399091+binaricat@users.noreply.github.com>
2026-09-29 00:24:27 +08:00
GOUKI9999andClaude Opus 5.5 e3894eb850 terminal: allow Shift+Enter text fallback inside ConPTY Win32 input mode (#3464)
* terminal: allow Shift+Enter text inside ConPTY Win32 input mode

Win32 input mode (PR #3247) delivers Shift+Enter to ConPTY as a lossless
INPUT_RECORD, which CLIs reading console records natively (Codex, Grok) can
use. Node/Bun CLIs read input through libuv, which drops modifier state when
translating INPUT_RECORD to VT bytes, so Claude Code and CodeBuddy still see a
bare CR and submit instead of inserting a newline (anthropics/claude-code#92771,
reproducing on 2.1.278).

While the mode is active, Netcatty also skips its Shift+Enter text fallback and
Kitty encoding, so shiftEnterNewlineText had no effect on local Windows
sessions at all.

Add shiftEnterForceText (default false): when enabled, Shift+Enter sends the
configured text even inside Win32 input mode, and consumes the keydown so no
native record is emitted as well. Add `\e` (ESC) to the escape decoder so the
text can carry the legacy Alt+Enter encoding, which is the only sequence that
survives the ConPTY input path.

Defaults keep the #2974 behaviour untouched for Codex/Grok.

* docs: record libuv input findings and the Win32 input mode opt-out

* fix(terminal): don't swallow Shift+Enter when there is no text to send

The Shift+Enter send-text interception resolved its text after already
calling preventDefault/stopPropagation, and returned false outside the
`if (shiftEnterText)` guard. When resolveShiftEnterText() yields an empty
string (e.g. a persisted empty setting) the keydown was therefore consumed
with nothing written, and the handler never fell through to the Win32
bookkeeping or Kitty paths below, so no Enter reached the session either.
The result was indistinguishable from a dead feature.

Resolve the text first and only enter the interception block when it is
non-empty; empty text now falls through exactly as it did before the
`shiftEnterForceText` setting existed, so a normal Enter is still produced.
The opt-out semantics for the non-empty case are unchanged.

Also tighten the source-shape test so it verifies the real intent: the
interception (preventDefault through return false) must live inside the
empty-text guard, which fails against the previous code.

* fix(terminal): scope Shift+Enter force-text to Win32 mode, honor it per broadcast target

Address review on #3464:

- The force-text opt-out could override a negotiated Kitty encoding that
  preserves Shift+Enter in non-Win32 sessions. The keydown decision now
  lives in shouldClaimShiftEnterForText: under Win32 input mode it follows
  shiftEnterForceText, otherwise only the existing collapse fallback
  applies. Covered by a regression test for a non-Win32 session whose Kitty
  encoding already preserves the chord.
- Broadcast Win32 targets returned the native record without consulting
  their own shiftEnterForceText. They now send their configured text for
  Shift+Enter when opted in, whether the source forwarded a key chord or a
  native Win32 record, and drop the paired release so ConPTY never sees a
  key-up without its key-down. Targets without the opt-out keep the native
  press/release pair. Tests cover source and target settings that differ.

ShiftEnterEvent now accepts KittyKeyboardEvent's optional type/modifier
fields so broadcast events can be checked with the same helper.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 23:36:10 +08:00
陈大猫 1b8228b23d fix(ui): choose side panel position from one menu (#3544)
* fix: expose all side panel dock positions

* fix: use compact dock position menu
2026-09-28 23:03:01 +08:00
bincxz 91db655a1a revert(ui): withdraw #3478 window control alignment 2026-09-27 22:32:08 +08:00
bincxz 3fd954d2bf fix(sftp): keep selection scroll on reconnect listing updates 2026-09-27 22:11:35 +08:00
bincxz ff28c9b412 revert(sftp): remove terminal command auto-refresh (#3371) 2026-09-27 22:03:47 +08:00
bincxz 459f3a5278 revert(vault): remove SFTP sidebar option from #3504
Revert the changes merged in #3506 while preserving the later bottom-tab removal.
2026-09-27 21:14:53 +08:00
bincxz 5af2c86f8f revert(ui): remove bottom tab bar option from #3366 2026-09-27 20:51:27 +08:00
69497ccc6a fix(terminal): offer saved password identities in SSH re-auth dialog (#3477)
* fix(#3475): automated AI fix

* fix: address Codex review on PR #3477

* fix: keep SSH identity picker state accurate

* style: keep SSH identity picker source ASCII-only

* fix: require usernames for saved SSH identity retries

* Keep selected SSH identity for terminal SFTP

* Share reauthenticated identity with all terminal SFTP entry points

* Pass SFTP identity source setter into layer effects

* Use effective identity for preset SFTP panel

* fix: keep focused SFTP identity in sync for toggle

* fix(terminal): use selected vault identity without exposing password

---------

Co-authored-by: netcatty-bot <308658023+netcatty-bot@users.noreply.github.com>
Co-authored-by: bincxz <16399091+binaricat@users.noreply.github.com>
2026-09-27 15:43:25 +08:00
Netcatty-Botandnetcatty-bot 078353dc87 fix(ai): allow custom model ids in composer picker and persist manual picks (#3535)
* fix(#3534): automated AI fix

* fix: address Codex review on PR #3535

* fix: address Codex review on PR #3535

* fix: address Codex review on PR #3535

* fix: address Codex review on PR #3535

---------

Co-authored-by: netcatty-bot <308658023+netcatty-bot@users.noreply.github.com>
2026-09-27 14:57:10 +08:00
85bddba538 feat(ai): add bottom dock position for AI assistant side panel (#3482)
* fix(#3481): automated AI fix

* fix: address Codex review on PR #3482

* fix: address Codex review on PR #3482

* fix: address Codex review on PR #3482

* fix: address Codex review on PR #3482

* fix: address Codex review on PR #3482

* fix: remeasure bottom dock when compose bar toggles

* fix: preserve terminal height when bottom dock cannot fit

* fix: preserve dock preference through temporary shrinkage

* fix: update bottom dock when compose bar toggles

---------

Co-authored-by: netcatty-bot <308658023+netcatty-bot@users.noreply.github.com>
Co-authored-by: bincxz <16399091+binaricat@users.noreply.github.com>
2026-09-25 17:35:49 +08:00
7cce9c9dbb fix(terminal): center titlebar window control buttons in the title bar (#3478)
* fix(#3476): automated AI fix

* fix: align window controls with full title bar

---------

Co-authored-by: netcatty-bot <308658023+netcatty-bot@users.noreply.github.com>
Co-authored-by: bincxz <16399091+binaricat@users.noreply.github.com>
2026-09-25 17:28:51 +08:00
954b60acf2 feat(vault): keep SFTP in the sidebar with a persistent vault rail (#3506)
* fix(#3504): automated AI fix

* fix: address Codex review on PR #3506

* fix: address Codex review on PR #3506

* fix: address Codex review on PR #3506

* fix: address Codex review on PR #3506

* fix: keep sidebar SFTP visible above inactive terminal

---------

Co-authored-by: netcatty-bot <308658023+netcatty-bot@users.noreply.github.com>
Co-authored-by: bincxz <16399091+binaricat@users.noreply.github.com>
2026-09-25 17:15:43 +08:00
73284582f5 fix(ai): keep Claude/Codex/Grok model pickers on live CLI catalogs instead of build-time presets (#3499)
* fix(#3496): automated AI fix

* fix: address Codex review on PR #3499

* fix: address Codex review on PR #3499

* fix: keep live model catalogs scoped and surface discovery failures

* fix: isolate Claude catalog profiles and support xhigh effort

* fix: handle missing external model catalog state

* fix: isolate Claude model catalogs by credentials

---------

Co-authored-by: netcatty-bot <308658023+netcatty-bot@users.noreply.github.com>
Co-authored-by: bincxz <16399091+binaricat@users.noreply.github.com>
2026-09-25 17:15:03 +08:00
33853398d4 fix(keychain): detect ECDSA key type in imported OpenSSH and PKCS#8 keys (#3490)
* fix(#3489): automated AI fix

* fix(keychain): read OpenSSH algorithm field precisely

* fix: preserve imported key size after vault reload

---------

Co-authored-by: netcatty-bot <308658023+netcatty-bot@users.noreply.github.com>
Co-authored-by: bincxz <16399091+binaricat@users.noreply.github.com>
2026-09-25 16:51:13 +08:00
陈大猫 9497cd65fc fix(sftp): focus the safe conflict action on open (#3531) 2026-09-25 15:37:48 +08:00
626e0ce5bd fix(quick-connect): accept multi-@ jump chains like JumpServer (#3525)
* fix(#3523): automated AI fix

* fix(#3523): parse JumpServer login on final SSH host

* fix(#3523): preserve login with SSH HostName override

* fix(#3523): guard JumpServer credential presets

* fix(#3523): retain SSH user with HostName alias

* fix(#3523): distinguish JumpServer login from SSH user option

---------

Co-authored-by: netcatty-bot <308658023+netcatty-bot@users.noreply.github.com>
Co-authored-by: bincxz <16399091+binaricat@users.noreply.github.com>
2026-09-24 17:49:46 +08:00
71d378c9b8 fix(sftp): verify current source before side-panel download (#3524)
* fix(#3521): automated AI fix

* fix: address Codex review on PR #3524

* fix: address Codex review on PR #3524

* fix(sftp): require fresh source metadata before downloads

* fix(sftp): refresh SCP symlink targets before download

* test(sftp): include download regression in default suite

---------

Co-authored-by: netcatty-bot <308658023+netcatty-bot@users.noreply.github.com>
Co-authored-by: bincxz <16399091+binaricat@users.noreply.github.com>
2026-09-24 17:48:22 +08:00
陈大猫 0261931f95 fix(terminal): keep broadcast going on vim ex command-line (#3467)
* fix(terminal): keep broadcast going on vim ex command-line

Broadcast pauses on fail-closed colon prompts so passwords are not
copied to peers. Vim command mode's last line is a bare `:`, which
matched that heuristic. Exempt lines that start with `:` so `:w` and
friends stay in sync; `Password:` is unchanged.

* fix(terminal): only treat a bare colon as vim command-mode

Codex: exempting every `:`-prefixed line would broadcast into custom
prompts such as `sudo -p ':'`. The hang is the first `:` key; later
`:w` no longer matches the trailing-colon heuristic.

* fix(terminal): exempt vim colon only on the alternate screen

A bare `:` on the primary screen can be `sudo -p ':'`. Vim command mode
uses DEC 1049, so require alternateScreen before treating `:` as ex.

* test(terminal): allow alternateScreen in prompt-security options
2026-09-21 16:09:50 +08:00
1b4e826e15 feat(terminal): save and auto-apply a default side panel layout on connect (#3456)
* fix(#3455): automated AI fix

* fix: address Codex review on PR #3456

* fix: address Codex review on PR #3456

* fix: address Codex review on PR #3456

* fix: address Codex review on PR #3456

* fix: address Codex review on PR #3456

* fix: address Codex review on PR #3456

* fix: address Codex review on PR #3456

* fix(terminal): let explicit SFTP auto-open beat the saved layout

A JumpServer SFTP deep link or host.autoOpenSftpPanel must still open
file transfer when the saved default layout omitted SFTP.

* fix(terminal): skip saved layout only when SFTP auto-open is available

Telnet/plugin hosts can carry autoOpenSidePanel=sftp even though the
protocol cannot serve SFTP. Those sessions should still get the saved
default with the SFTP pane pruned.

---------

Co-authored-by: netcatty-bot <308658023+netcatty-bot@users.noreply.github.com>
Co-authored-by: bincxz <16399091+binaricat@users.noreply.github.com>
2026-09-21 15:45:59 +08:00
Netcatty-Botandnetcatty-bot ff65339e04 fix(terminal): keep IME preedit commits alive when Shift ends composition (#3444)
Co-authored-by: netcatty-bot <308658023+netcatty-bot@users.noreply.github.com>
2026-09-21 14:56:48 +08:00
Netcatty-Botandnetcatty-bot a70c43e302 fix(vault): keep host groups unchanged when dragging host cards (#3442)
Co-authored-by: netcatty-bot <308658023+netcatty-bot@users.noreply.github.com>
2026-09-21 14:56:28 +08:00
cb06857480 feat(terminal): confirm before pasting multiple lines (#3398) (#3400)
* fix(#3398): automated AI fix

* fix: address Codex review on PR #3400

* fix: address Codex review on PR #3400

* fix: address Codex review on PR #3400

* fix: address Codex review on PR #3400

* fix: address Codex review on PR #3400

* fix: address Codex review on PR #3400

* fix: address Codex review on PR #3400

* fix: address Codex review on PR #3400

* fix: address Codex review on PR #3400

* fix: address Codex review on PR #3400

* fix(terminal): protect popup and sanitized multiline pastes

* fix(terminal): preserve input state across paste confirmation

* fix(terminal): retain serial character-mode paste echo

* test(terminal): cover paced input write options

* fix(terminal): retain telnet echo for paced pastes

* test(terminal): scope serial buffer assertion to serial sessions

* fix(terminal): align runtime write options with bridge contract

* fix(terminal): preserve bookkeeping for all paced pastes

* fix(terminal): record confirmed paste lines in order

* fix: record paced paste commands after transport writes

* fix: omit paste receipts for filtered input

* fix: cancel superseded paste batches across input paths

* fix: classify each acknowledged paste line before recording

* fix: stop paced paste when editing buffered serial input

* fix: preserve recording pause boundaries and serial edit cancellation

* fix: treat paced terminal pastes as user input

* fix: preserve paste drafts until write and snippet broadcast origin

* fix: retain filtered paste drafts and invalidate urgent input ownership

* fix: broadcast paced user paste only on guarded line receipts

---------

Co-authored-by: netcatty-bot <308658023+netcatty-bot@users.noreply.github.com>
Co-authored-by: bincxz <16399091+binaricat@users.noreply.github.com>
2026-09-18 15:19:34 +08:00
0d21e37a19 fix(terminal): map macOS Command+. to interrupt running command like Ctrl+C (#3409)
* fix(#3408): automated AI fix

* fix: address Codex review on PR #3409

* fix: address Codex review on PR #3409

* fix: address Codex review on PR #3409

* fix: address Codex review on PR #3409

* fix: address Codex review on PR #3409

* fix: address Codex review on PR #3409

* fix: address Codex review on PR #3409

* fix: preserve physical releases for Command-period interrupts

* fix: allow Command-period with selected terminal text

* style: keep Command-period additions ASCII-only

* test: validate Command-period fixture without renderer errors

* fix: support logical period across macOS keyboard layouts

---------

Co-authored-by: netcatty-bot <308658023+netcatty-bot@users.noreply.github.com>
Co-authored-by: bincxz <16399091+binaricat@users.noreply.github.com>
2026-09-18 14:11:05 +08:00
9082aa08a4 fix(serial): auto-login on serial consoles with saved host credentials (#3418)
* fix(#3417): automated AI fix

* fix: address Codex review on PR #3418

* fix: address Codex review on PR #3418

* fix: address Codex review on PR #3418

* fix: address Codex review on PR #3418

* fix: address Codex review on PR #3418

* fix: address Codex review on PR #3418

* fix: address Codex review on PR #3418

* fix: address Codex review on PR #3418

* fix: address Codex review on PR #3418

* fix: guard serial quick login and reconnect startup commands

* fix: preserve serial startup while tabs sleep

---------

Co-authored-by: netcatty-bot <308658023+netcatty-bot@users.noreply.github.com>
Co-authored-by: bincxz <16399091+binaricat@users.noreply.github.com>
2026-09-18 14:10:58 +08:00