Commit Graph
31 Commits
Author SHA1 Message Date
Bill 2653ab1820 feat(i18n): tab auto titles follow the UI language
Titles are stored display text (layout templates, session snapshot,
broadcast registry), so a pane used to keep the wording of the language it
was opened in, and nextTerminalTitle could not even parse the number back
out of another language's pattern (numbering restarted, duplicates).

New pure module src/shared/terminalTitle.ts: resolution tries all four
languages' patterns, rendering uses the active one; i18n gains tFor(lang)
for off-language rendering. Workspace retitles auto-numbered local tabs in
place on language switch, snapshot restore and template apply; SSH panels
(user-typed connection names) are never touched. dockview's title-change
event propagates the new title to the broadcast registry and the snapshot
save with no extra wiring.

New test terminal-title.mjs (16 writer/reader language pairs, non-auto
title boundaries, gap filling); offline suite grows 17 -> 18.
2026-10-08 00:11:20 +08:00
Bill eea40d87a6 build(deps): move renderer-only deps to devDependencies, shrink asar 98MB -> 8.1MB
Renderer code is fully bundled by Vite into out/renderer; externalizeDepsPlugin
only applies to main/preload, so renderer packages in 'dependencies' were
shipped twice. Moved to devDependencies: @xterm/*, antd, dockview-react,
react, react-dom, zustand. Kept in dependencies (imported by src/main):
@lydell/node-pty, ssh2, zmodem.js, font-list, electron-updater. undici is
now explicit (release.cjs/download-stats.cjs require it). Also dropped the
dead @xterm/addon-serialize (zero imports anywhere).

Verified: npm test 17/17 green, dist:dir builds, asar node_modules contains
only main-process deps, asarUnpack natives intact, win-unpacked smoke
(window, theme, pty spawn) passes.
2026-10-07 23:08:43 +08:00
Bill a0be827650 test(main): cover updater fallback, ipc sender guard, log sanitizer, sftp timeouts
- updater-fallback.mjs (82 assertions): GitHub probe fallback to Gitea,
  timeout budgets, in-flight check never stuck in 'checking'; updater.ts
  gains a setUpdateTimeouts test seam, electron-updater aliased to a stub
- ipc-guard.mjs (43): trusted-frame guard exercised through real
  registerIpc handlers with forged senderFrames; electron-stub now records
  registrations via globalThis so bundle and test share one instance
- log-sanitizer.mjs (71): CSI/OSC/charset state machine, alt-screen fold,
  byte-split fuzz equal to whole-chunk output; fixes a wrong comment
- sftp-timeout.mjs (39): per-op timeouts (metadata 30s, transfer chunk 60s,
  open 10s) evict half-dead channels with one retry, slow-but-progressing
  transfers untouched, late rejections never unhandled
- reservedAccelerators.ts: single pure isReservedAccelerator shared by the
  settings recorder and applyGlobalShortcut (the two tables had drifted —
  main now also refuses Ctrl+=/-/0/PgUp/PgDn legacy values); 56 assertions
- ssh-loopback.mjs loads the real ssh.ts via a bundle (50 assertions):
  TOFU pinning, fail-closed stores, auth gate, connect budget

Offline suite grows 13 -> 17. Renderer test framework evaluated: not
introducing vitest/jsdom; pure logic keeps being extracted and tested
through the existing bundle harness.
2026-10-07 22:57:16 +08:00
Bill d22923aedd security(main): dialog-grant admission for local paths, explicit webPreferences
New localPathGrants.ts: an in-memory registry of paths the user picked in a
native dialog. Every check resolves realpath + stat at grant and use time;
Windows case folding; missing files, directories-as-files, devices and
symlinked parents can never pass. SFTP upload/download and zmodem send/
receive now refuse renderer-supplied local paths that were never granted,
returning the resolved path so callers never re-traverse a symlink. keyPath
is validated as a regular file <= 1MB before reading (a device node would
have blocked the UI thread forever). Tests inject a stub policy via
setLocalPathPolicy; production always defaults to the real registry.

Also: webPreferences now explicitly pins contextIsolation/nodeIntegration/
webSecurity instead of relying on defaults.

New offline test tests/local-path-grants.mjs (37 assertions incl. symlink
escape); offline suite grows to 13. i18n: 6 main.sftp/main.key error keys
in 4 languages.
2026-10-07 22:06:45 +08:00
Bill 655c660607 fix(store): back up unparseable connections/commands files before rebuild 2026-10-07 20:44:10 +08:00
954801926@qq.com d1376b7d1d chore: release v1.0.20
CI / typecheck + test + build (windows) (push) Canceled after 0s
2026-10-01 21:56:24 +08:00
954801926@qq.com d04452cd7f fix(ime): pin @xterm/xterm 6.1.0-beta.304 for IME caret follow; sync lockfile root version in predist
CI / typecheck + test + build (windows) (push) Canceled after 0s
2026-10-01 21:28:07 +08:00
Bill 86f51df2e6 fix(lock): harden lock screen input paths
CI / typecheck + test + build (windows) (push) Canceled after 0s
- remove the application menu while locked (lockMenu.ts): Alt reveals the
  default menu and its mouse-clickable Reload/DevTools/Zoom items bypass
  before-input-event entirely; menu is rebuilt from the default template on
  unlock, startup-restored locks covered from initLockController
- extract the keyboard classification into pure lockShortcuts.ts
  (isLockBlockedShortcut/isPanicLockChord) with a table-driven test
  (lock-shortcuts.mjs, 29 cases) — the v1.0.17 lockout escaped CI because
  this decision lived inline in createWindow()
- reserve Ctrl+L in the global show/hide shortcut recorder: a global
  registration intercepts the chord at OS level and silently disables the
  panic lock
- skip auto-repeat keydowns in the panic-lock branch (held Ctrl+L on an
  unconfigured app re-read lock.json + settings.json per repeat)
- LockScreen: re-sync the cooldown clock on visibilitychange/focus/pageshow
  so a suspended renderer timer cannot leave the password input disabled
  past the real deadline
2026-09-30 00:38:57 +08:00
Bill dd08f8054a chore: release v1.0.19
CI / typecheck + test + build (windows) (push) Canceled after 0s
2026-09-28 13:39:27 +08:00
Bill 33efbe921e chore: release v1.0.18
CI / typecheck + test + build (windows) (push) Canceled after 0s
2026-09-24 22:53:29 +08:00
Bill 244199c512 chore: release v1.0.17
CI / typecheck + test + build (windows) (push) Canceled after 0s
2026-09-24 22:16:49 +08:00
Bill 471f8c3e73 chore: release v1.0.16 2026-09-23 12:00:56 +08:00
Bill e08e1cfec4 feat(highlight): preset overhaul, categories, stats, theme colours, per-host profiles
Rules & engine:
- 22 presets (was 11): split status into okstate/warnstate/badstate, add delop,
  createop, danger, secret, level, exitcode, percent, http; status words are
  case-insensitive and cover the ✓ ✔ ✅ ✗ ✘ ✖ ❌ ⚠ symbol set
- value bands: the first number in a match picks the colour
  (percent: <20% red / 20-50% yellow / 50-80% light green / >=80% green)
- optional per-rule `caseInsensitive`, `category`, `bands`; load-time
  `refreshBuiltinRules` upgrades untouched built-in patterns in place

Settings page:
- three-way master switch `highlightMode` (all / basic / off); `basic` runs only
  the five safety+status rules and `off` empties the rule set rather than
  bypassing HighlightStream (which would drop the held tail)
- category column + grouping (`highlightGroupByCategory`), per-rule hit/duration
  stats (`highlightStats`, opt-in sink, snapshot once a second), theme-following
  colours (`highlightThemeColors`, hue-bucket mapping onto the ANSI palette),
  import/export JSON envelope, live preview through the real engine
- named rule subsets bound per host (`highlightPerHost` + `highlightProfiles`
  + `SshConnection.highlightProfileId`); empty ruleIds = every rule

Tests: new tests/hl-rules.mjs (word boundaries, case flag, negative words,
bands, import/export, preview, basic mode, categories, stats, theme colours,
profiles) + profile round-trip in tests/settings-store.mjs
2026-09-23 11:14:31 +08:00
Bill c01d3eb365 feat: product website for GitHub Pages + author CodingPlan.Site
Deploy website to GitHub Pages / deploy (push) Canceled after 0s
- website/: zero-dependency static landing page (HTML+CSS), corporate
  light theme, real app screenshots, download links pointing to the
  git.codingplan.site release channel (exe/msi) with GitHub mirror
- .github/workflows/deploy-website.yml: deploy website/ to GitHub Pages
  on push to main (paths: website/**)
- package.json: author -> CodingPlan.Site
- README: link to the site and its source folder
2026-09-21 09:11:05 +08:00
Bill 8442103343 chore: release v1.0.15 2026-09-21 00:00:36 +08:00
Bill eccc1f52e7 chore: bump version to 1.0.14 2026-09-20 21:04:35 +08:00
Bill cca4ba029a test: rebuildable bundles, npm test entry point
- esbuild alias fixed in the session/sysinfo/sftp test commands (they
  could not build at all), .sftp-svc.mjs build documented, real
  connection-stability assertions
- tests/build-bundles.cjs builds every bundle fresh; npm test runs the
  seven offline suites; esbuild pinned in devDependencies
- remove the assertion-less .exact-inline.mjs; ignore/clean test temp dirs
2026-09-20 20:27:06 +08:00
Bill 4c6a29ef28 feat: multi-language interface (zh-CN/zh-TW/en/ja), multilingual offline changelog, settings robustness
i18n
- shared/i18n: dependency-free t() with flat per-namespace dictionaries
  (common/settings/workspace/terminal/ssh/panels/main), zh-CN fallback
- language picker in Settings -> System; antd ConfigProvider locale follows it
- main process tracks the language too: tray menu, close prompt, ssh/sftp/
  zmodem errors and the log TUI marker are translated; tray rebuilds on change

changelog
- CHANGELOG.md (zh-CN canonical) + .zh-TW/.en/.ja, bundled via ?raw and read
  per interface language with per-version fallback to zh-CN (no network)
- sync-changelog.cjs merges RELEASE_NOTES[.<lang>].md per release; release.cjs
  refuses to publish without a zh-CN entry for the version

settings robustness
- closeAction 'ask' survives the sanitizer (was silently coerced to 'tray',
  which made the 'ask every time' option dead)
- highlight rules are repaired instead of dropped: string priority, 0/1
  enabled, missing fg colour; unknown fields preserved
- load-time warnings are written to settings-warnings.log (deduped, capped)

terminal/UI
- configurable terminal toolbar: open working directory (default on), session
  log recording (off), open logs folder (off)
- global shortcut field records key combos (modifier or F-key required)
- input suggestions + command history default to off, with a one-time reset
  migration for existing installs
- settings dialog scrolling fixed (antd v6 renamed the tabs container), theme
  gallery nested scrollbar removed, joined segmented pickers with readable
  selected-state text

tests: settings-store.mjs (15 checks) added; commands-store.mjs updated for
the new off-by-default history setting
2026-09-20 14:22:29 +08:00
Bill c1744184a3 chore: bump version to 1.0.12 2026-09-17 09:26:20 +08:00
Bill 9e453e272c chore: bump version to 1.0.11 2026-09-15 15:08:13 +08:00
Bill 97fc7171cc chore: bump version to 1.0.10 2026-09-15 13:17:28 +08:00
Bill 4b336360f8 fix(release): scope the proxy to GitHub so the domestic channel stays direct
setGlobalDispatcher routed every request — including the Gitea release and
channel PUTs — through the local proxy, which reset mid-upload once and left
the channel half-written. The proxy agent is now passed explicitly on the
GitHub requests only.
2026-09-15 00:34:30 +08:00
Bill 03aa79a691 chore: bump version to 1.0.8 2026-09-14 21:41:46 +08:00
Bill fcb2781694 chore: bump version to 1.0.7 2026-09-14 20:12:04 +08:00
Bill 3c193a48a7 chore: bump version to 1.0.6 2026-09-14 17:31:00 +08:00
Bill 3aa8b28f89 chore: bump version to 1.0.5 2026-09-14 14:00:55 +08:00
Bill 70c33a5572 fix: register update IPC handlers (dead check/download buttons since 1.0.1); bump 1.0.4 2026-09-08 21:40:25 +08:00
Bill 2b3fefafd0 feat: close-to-tray default + system settings entry; bump 1.0.3 2026-09-08 17:00:09 +08:00
Bill 8cb193fa6a feat: theme-driven chrome, customizable tab accent, UI polish
- Sidebar/tab bars/dividers/settings dialog follow the terminal theme
- Tab accent color customizable in theme settings (color picker)
- Title bar shows the app icon; Material Dark is the default theme
- Slimmer rectangular tabs (28px), slate scrollbars, visible pane dividers
- Fix pure-black xterm viewport gaps after pane resize
2026-09-08 00:57:56 +08:00
Bill 0de0eee58d chore: bump version to 1.0.1 2026-09-07 17:55:41 +08:00
Bill a9acdbe500 Initial commit: OpenTerminal v0.1.0
Open-source terminal app (local + SSH): split panes, themes, SFTP,
server monitoring, broadcast input, ZMODEM, system tray, single instance.
Electron + React + TypeScript. MIT License.
2026-09-07 16:15:50 +08:00