38 Commits

Author SHA1 Message Date
tjb-tech 330ece7a62 feat(tui): support clipboard image paste
Fixes #265
2026-05-17 06:13:19 +00:00
yl-jiang f61f70d7b1 feat(tui): preview diffs before edit and write approval
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-13 13:44:43 +08:00
tjb-tech f10d8875ee feat(ui): make mode switching and stop explicit 2026-05-03 09:02:47 +00:00
ancietyding b731c3ede1 fix(tui): allow escape to interrupt active runs
Add an explicit frontend-to-backend interrupt request so Esc can stop the current agent turn without relying on platform-specific terminal signals.
2026-04-27 14:17:49 +08:00
tjb-tech f683b4aed2 fix(tui): handle repeated backspace chunks on windows terminals 2026-04-24 16:35:09 +00:00
Yufeng He 0bba07fe19 fix(tui): complete slash commands without cursor drift (#185)
Three related bugs in the React TUI slash-command flow (fixes #183):

1. Tab completion left a trailing space after the command, so hitting
   Enter right after Tab would submit "/exit " (with arg) instead of
   running /exit. Drop the space — user can add one themselves if they
   want to type an argument.

2. After a programmatic setInput() from completion/history, the
   MultilineTextInput cursor stayed at its previous offset instead of
   moving to the end of the newly-inserted text. Subsequent keystrokes
   landed in the middle of the completed command ("/eXxit" when typing
   X after Tab-completing "/exit"). Track the last internally-authored
   value via a ref; when the incoming value differs, treat it as an
   external change and snap the cursor to the end.

3. /quit is the other obvious word for "exit" and users were surprised
   when it wasn't registered. Add an `aliases` field to SlashCommand
   and make /quit an alias of /exit. help/list output deduplicates
   aliases so they resolve via lookup without cluttering the command
   listing.

Tests:
- tests/test_commands/test_registry.py: new tests for the alias path
  and for help/list dedup. Both pass locally.
- MultilineTextInput doesn't have a standalone unit test for the
  cursor behavior (uses node:test + ink render harness, can't run
  without node toolchain on this machine), but the fix is a local,
  obvious change in a single component.

Co-authored-by: Yufeng He <40085740+universeplayer@users.noreply.github.com>
2026-04-23 19:25:50 +08:00
Auauau 9078071803 fix(tui): restore backspace behavior for raw DEL terminals (#182)
Ink reports the common DEL byte as a delete key, which means React TUI prompt editing can lose Backspace behavior on terminals that send 0x7f for backward delete. This change records the raw input sequence so PromptInput can treat raw DEL as backward delete while preserving true forward-delete escape sequences, and it adds a focused regression test plus changelog entry.\n\nConstraint: Ink normalizes raw DEL into key.delete for some terminal environments\nRejected: Treat delete at end-of-line as backspace | breaks true forward delete semantics on terminals that send distinct delete sequences\nConfidence: high\nScope-risk: narrow\nReversibility: clean\nDirective: Keep raw-sequence disambiguation aligned with Ink input semantics before refactoring PromptInput keyboard handling\nTested: /Users/wangxin/.openharness-venv/bin/ruff check src tests scripts\nTested: /Users/wangxin/.openharness-venv/bin/pytest -q\nTested: cd frontend/terminal && npx tsc --noEmit\nTested: cd frontend/terminal && node --import tsx --test src/components/MarkdownText.test.tsx src/components/PromptInput.test.tsx\nNot-tested: Manual verification on non-macOS terminals\nRelated: d4eae15

Co-authored-by: wangxin <wangxinwxwx@shopee.com>
2026-04-22 16:15:11 +08:00
tjb-tech d4eae153d3 fix(shell): address Windows backspace and TUI shell regressions 2026-04-19 14:22:37 +00:00
tjb-tech 738da98b34 fix(terminal): support multiline input and reduce flashing 2026-04-17 11:42:01 +00:00
tjb-tech d38796518a Merge branch 'pr-141' into integrate-pr141
# Conflicts:
#	CHANGELOG.md
#	frontend/terminal/src/App.tsx
#	frontend/terminal/src/components/ConversationView.tsx
#	frontend/terminal/src/components/ToolCallDisplay.tsx
#	frontend/terminal/src/hooks/useBackendSession.ts
2026-04-14 12:07:30 +00:00
siaochuan 7d2a0104ba feat(tui): add codex output style to reduce streaming flicker 2026-04-14 19:18:20 +08:00
yulin ed0b5f02ab fix(tui): write trailing newline on exit so shell prompt starts on a fresh line (#133)
* fix(tui): write newline on exit so shell prompt starts on fresh line

Ink hides the cursor during rendering and restores it on exit, but does
not emit a trailing newline.  When the TUI process ends, the terminal
cursor sits at the end of the last rendered line, causing the shell
prompt to appear directly concatenated with the TUI output.

Rename restoreCursor → restoreTerminal and append '\n' alongside the
cursor-show escape sequence so the parent shell always receives the
prompt on a clean new line.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* test(tui): add regression guard for exit newline; update changelog

- Add tests/test_ui/test_tui_exit_sequence.py with two tests:
  * test_tui_exit_handler_writes_newline: asserts the cleanup write
    includes the trailing \n alongside \x1B[?25h
  * test_tui_exit_handler_registered_for_all_signals: asserts cleanup
    is registered for 'exit', SIGINT, and SIGTERM
- Add entry to CHANGELOG.md [Unreleased] Fixed section

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix(tests): update ohmo cli test inputs for allow_remote_admin_commands prompt

Commit dd1d235 added a new 'Allow explicitly listed administrative slash
commands from remote channels?' confirmation step to the gateway config
wizard, but the four interactive test cases in test_ohmo/test_cli.py were
not updated to provide an answer for it. This caused stdin to be exhausted
and click to emit Abort(), making all four tests fail with exit_code=1.

Add 'n' as the answer for allow_remote_admin_commands in each affected
test, and move the existing 'restart gateway' answer after it in
test_ohmo_config_interactive_can_restart_gateway.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-13 18:49:47 +08:00
tjb-tech 63ce793cba fix(tui): batch backend updates to reduce flicker 2026-04-13 07:31:24 +00:00
tjb-tech 1f5087c819 feat(subagents): improve discovery and reduce tui rerenders 2026-04-13 07:23:17 +00:00
JiangYulin b40007753f fix(tui): keep busy spinner active throughout agent turn
- Remove premature setBusy(false) from assistant_complete handler;
  busy state should only clear at true end-of-turn (line_complete).
- Add setBusy(true) to tool_started handler so the spinner activates
  even when tool calls come immediately after an assistant message.
- Show 'Processing...' label on tool_completed instead of clearing label.
- Improve inline comments to clarify the intended event flow.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-11 18:53:46 +08:00
JiangYulin 8b6b3b26d0 feat(tui): pair tool-call and tool-result rows for cleaner transcript
Previously, tool calls and their results were rendered as independent
rows. This flooded the transcript with raw result text on every agent
turn and gave no at-a-glance signal about whether a call succeeded.

Changes:
- ConversationView groups adjacent tool/tool_result items into pairs
  before rendering, using a new groupToolPairs() helper.
- ToolCallDisplay accepts an optional resultItem prop and renders a
  compound row:
    * Success  → result line count shown inline (e.g. "→ 24L")
    * Error    → red error icon inline + up to 5 error lines expanded
- Standalone successful tool_result rows are suppressed (no output).
- Standalone tool_result errors are still surfaced so failures are
  never silently swallowed.

Closes #109

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-11 16:34:04 +08:00
tjb-tech aca4016898 feat(compact): align lifecycle and carry-over behavior 2026-04-10 08:17:10 +00:00
tjb-tech 702e429c06 Merge branch 'feat/react-tui-markdown-rendering'
# Conflicts:
#	frontend/terminal/src/components/MarkdownText.tsx
2026-04-10 07:12:00 +00:00
tjb-tech 038d0a7956 fix(ci): restore import order and improve running feedback 2026-04-10 04:08:35 +00:00
tjb-tech 27abeae3eb Merge #88 and fix agent team creation 2026-04-10 03:59:44 +00:00
yl-jiang 9e0d15733b fix(frontend): address markdown renderer review
- remove fixed sleep delays from Ink output tests
- align inline fallback rendering with width calculation
- preserve nested markdown blocks inside blockquotes
- memoize markdown tokenization for transcript rerenders

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-09 19:54:08 +08:00
yl-jiang 32773f3489 feat(frontend): render assistant markdown in React TUI
- render assistant transcript rows with MarkdownText\n- align markdown tables by rendered cell width\n- add changelog and regression coverage\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-09 19:34:58 +08:00
tjb-tech a359e0204b fix(ui): avoid redundant backend snapshot rerenders 2026-04-09 07:43:10 +00:00
tjb-tech cb90ff8686 feat(ui): clear prompt input on double escape 2026-04-08 12:26:07 +00:00
tjb-tech 69c85e411c fix(ui): avoid blocking paste and permission responses in terminal 2026-04-07 16:30:00 +00:00
solon a913c86d40 fix(ui): handle EIO crashes in Ink TUI and wire up --debug logging
The Ink React TUI crashes with unhandled EIO errors when stdin.setRawMode()
is called during React reconciler mount/unmount cycles. This happens
reliably in SSH, tmux, and Docker terminal environments, causing the
spinner to appear frozen on tool execution.

Changes:
- Monkey-patch stdin.setRawMode to catch EIO/EAGAIN gracefully
- Add uncaughtException handler as fallback for React internals
- Wire up the existing --debug CLI flag to logging.basicConfig
- Support OPENHARNESS_LOG_LEVEL env var for log level control
- Add debug logging to tool execution loop (permission, timing, output)
- Add debug logging to backend event emission

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-07 13:46:13 +00:00
Javis486 1870ed55ba fix:windows下,uv run oh 启动后 新cmd一闪而过 2026-04-07 16:25:41 +08:00
tjb-tech cd52191f6e feat(auth): add provider profiles and subscription clients 2026-04-06 08:47:10 +00:00
Aashish Thapa df635c56f5 fix: TUI confirmation dialog not accepting input on WSL/Windows (#37)
On WSL/Windows, the `npm exec -- tsx` process chain can spawn
intermediate shell processes that break TTY stdin inheritance.
When stdin loses its TTY status, Ink's useInput silently fails
to enable raw mode, making the permission dialog unresponsive.

Two fixes:

1. react_launcher.py: Invoke the tsx binary directly from
   node_modules/.bin/ instead of going through npm exec, which
   preserves TTY inheritance across the process boundary.

2. index.tsx: When process.stdin is not a TTY, open /dev/tty
   directly as a fallback stdin stream for Ink, giving raw-mode
   keyboard access regardless of how stdin was inherited.

Closes #37
2026-04-05 20:27:51 -05:00
tjb-tech 39ee8ab8d9 fix: network error notification + permission dialog input race (#36)
Bug 1 (network error): API errors now yield ErrorEvent instead of silently
hanging the spinner. The query loop catches ConnectionError/TimeoutError
and surfaces a user-visible message.

Bug 2 (bash stuck): Permission modal handler is now explicitly placed
before the busy-guard in useInput, with a question-modal early return.
Added 300s timeout on backend permission future to prevent permanent hang.

Added ErrorEvent to StreamEvent union for TUI error display.

Fixes #36
2026-04-05 14:41:13 +00:00
tjb-tech 06dc9998cf fix(ui): restore OH MY HARNESS ASCII art in WelcomeBanner
The theme-frontend agent accidentally removed the ASCII logo when
adding theme support. Restored from initial commit (5dd8b95) with
theme.colors.primary integration.
2026-04-05 13:00:52 +00:00
tjb-tech 7f7081b8a5 Merge branch 'clawteam/openharness-dev/tui-agent'
# Conflicts:
#	frontend/terminal/src/components/StatusBar.tsx
2026-04-05 10:23:30 +00:00
tjb-tech 21ba2b0795 feat(tui): add TodoPanel, SwarmPanel, PlanMode indicator, enhanced AskUser modal
- Add TodoPanel.tsx: renders markdown checklist (- [ ]/- [x]) with Ink Box,
  checkbox icons (☐/☑), compact/expand toggle via ctrl+t
- Add SwarmPanel.tsx: shows swarm teammate list with status icons (🟢🟡🔴),
  duration, task summary, coordinator notifications; ctrl+w to collapse
- Enhance StatusBar.tsx: PlanModeIndicator highlights [PLAN MODE] in yellow,
  shows 🚫 blocked when write tools run in plan mode, flashes on exit
- Enhance ModalHost.tsx (question kind): animated waiting text, double-border
  styling, tool context display, shift+enter for multi-line input
- Add backend protocol events: todo_update, plan_mode_change, swarm_status
  with new fields in BackendEvent (todo_markdown, plan_mode, swarm_teammates,
  swarm_notifications)
- Emit todo_update in backend_host.py when TodoWrite tool completes
- Update useBackendSession.ts to handle new event types and expose state
- Update types.ts with TodoItemSnapshot, SwarmTeammateSnapshot, etc.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-05 10:21:20 +00:00
tjb-tech c2c8c6bf19 feat(ui): add TUI theme system with ThemeContext and 5 builtin themes
- Add ThemeConfig TypeScript type with colors and icons fields
- Add 5 builtin themes: default, dark, minimal, cyberpunk, solarized
- Add ThemeProvider / useTheme() React context
- Update StatusBar, ConversationView, ToolCallDisplay, Spinner,
  PromptInput, WelcomeBanner to consume useTheme()
- Wrap App with ThemeProvider; support /theme set <name> command
- All hardcoded colors replaced with theme.colors.* references
2026-04-05 10:17:22 +00:00
小川 ee4c6222b4 fix(ui): throttle assistant delta rendering (#3)
Co-authored-by: solon <solon@debian176.solon>
2026-04-05 08:59:28 +00:00
小川 c8f6a53d25 fix(ui): improve TUI startup experience and process cleanup
- Show "Connecting to backend..." instead of stale "model: unknown" during init
- Hide input prompt, status bar, and keyboard hints until backend is ready
- Block message submission while backend is not ready
- Restore terminal cursor visibility on exit (Ink hides it by default)
- Replace oversized ASCII art banner with compact 2-line header
- Kill entire process group on exit to prevent stale Node/Python processes
- Register cleanup handlers on SIGINT/SIGTERM for reliable teardown

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
(cherry picked from commit 93562d65ff66631c24f57dfc79a17c4fe4b3658a)
2026-04-05 08:53:44 +00:00
washi4 d2ceecf3d0 fix: prevent double Enter submission in React TUI (#13)
The useInput hook and TextInput's onSubmit both fired on Enter,
causing every user message to be submitted twice. Remove the
duplicate key.return handler in useInput — TextInput already
handles normal Enter submission.
2026-04-04 17:57:41 +08:00
tjb-tech 5dd8b952ec Initial release: oh — OpenHarness: Open Agent Harness v0.1.0
A lightweight open-source Python implementation of the Agent Harness architecture.
44x lighter than Claude Code (11K vs 512K lines), 98% core tool coverage.

- 43 tools with Pydantic validation and parallel execution
- Skills system compatible with anthropics/skills (17+ tested)
- Plugin system compatible with claude-code/plugins (12+ tested)
- API retry with exponential backoff
- Multi-level permissions with path rules
- React/Ink TUI with "Oh my Harness!" branding
- 114 unit tests + 6 E2E test suites
- MIT License
2026-04-01 16:32:25 +00:00