Skip to content

Improve terminal input handling and task loading (supersedes #235)#265

Merged
subsy merged 15 commits intomainfrom
pr-235-merged
Feb 3, 2026
Merged

Improve terminal input handling and task loading (supersedes #235)#265
subsy merged 15 commits intomainfrom
pr-235-merged

Conversation

@subsy
Copy link
Copy Markdown
Owner

@subsy subsy commented Feb 3, 2026

Summary

This PR contains the changes from #235 by @DeliLevente99, merged with current main and conflict resolved.

Original PR: #235 - All credit to the original contributor

Changes included:

  • Terminal input sanitization: stripEscapeCodes(), disableMouseTracking(), and raw mode promptText() for handling mouse tracking codes
  • PRD parsing enhancements: H4 header support, "Feature X.Y" format, multi-tier fallback parsing
  • Resume command improvements: Task event handling (task:activated, task:completed) now matches run.tsx
  • Historical output loading: Improved logic for resume scenarios
  • Animated progress bar: UX enhancement in ChatView
  • Better error messages: Shows all supported PRD formats when no user stories found
  • Template workflow improvements: Added pre-implementation steps for AI agents

Conflict resolution

  • RunApp.tsx: Kept the PR's more sophisticated historical output loading logic that only loads for active tasks when no current iteration exists (resume scenario)

Test plan

  • Typecheck and build pass ✅
  • Terminal input handles mouse tracking codes correctly
  • PRD parsing supports all documented formats
  • Resume command properly tracks task state
  • Template workflow guides agents through pre-implementation review

Summary by CodeRabbit

  • New Features

    • UI task preloading and lifecycle sync; UI-triggerable engine start with auto-start.
  • Improvements

    • Animated progress bar for unknown-duration tasks.
    • Escape-code stripping and mouse-tracking disablement for safer prompts/input.
    • Multi-format user-story parsing and clearer PRD guidance.
    • Expanded workflow templates with pre-implementation review and progress logging.
    • Smarter historical log loading to avoid redundant fetches during live streaming.
  • Tests

    • Expanded parser tests and new terminal-utility tests.

DeliLevente99 and others added 13 commits January 28, 2026 09:25
Enhances prompt input by filtering out mouse tracking and escape codes, adds real-time input filtering for text prompts, and disables mouse tracking in the terminal. Also updates the resume command to load tasks from the tracker and passes them to the TUI. Expands user story header parsing to support up to four hash marks.
…orted by coderabbitai

Enhances the TUI session to better track active tasks by subscribing to engine events for task activation and completion, ensuring session state is updated and persisted accordingly. Refactors prompt cleanup to remove only the relevant data listener, and updates escape code stripping to use RegExp constructors for better linter compatibility. Also refines historical output loading logic in RunApp to allow showing previous output when resuming in-progress tasks.
…error reported by coderabbitai

Refines the regex for filtering mouse tracking codes to avoid false positives and adds error handling for invalid pattern configurations in prompt input validation.
…e error reported by coderabbitai

Refines the regex in stripEscapeCodes to avoid false positives when removing mouse tracking patterns. Adds an AnimatedProgressBar component to ChatView for simulating progress during loading states.
The parser now recognizes user stories defined with H4 headers (####) and 'Feature X.Y' formats, normalizing them to 'FEAT-X-Y' IDs. Tests have been added for all header and ID format combinations. The error message in the PRD chat app was updated to document all supported user story header formats. Utility functions for stripping escape codes and disabling mouse tracking are now exported and tested.
Enhanced the PRD parser to recognize user story headers with version-style IDs (e.g., US-2.1.1, US-1.2) and added a fallback mechanism to extract stories from any header with a colon in the User Stories section. Updated related tests and user guidance to reflect the new supported formats. Improved escape code stripping to preserve legitimate semicolons in user input.
Enhanced the parser to better distinguish valid US-XXX formats, exclude US-1 and US-9999 from generic pattern matching, and add a 3-tier fallback strategy to always extract user stories from markdown. Added ultimate fallback to parse any H2/H3/H4 headers with colons, skipping common non-story headers. Updated and expanded tests to cover new parsing logic and edge cases.
Updated the user story header and normalization patterns to handle 'Feature X.Y' identifiers in a case-insensitive manner. This improves flexibility when parsing user story headers with different casing.
Resolved conflict in RunApp.tsx by keeping the PR's more sophisticated
historical output loading logic that only loads for active tasks when
no current iteration exists (resume scenario).
@vercel
Copy link
Copy Markdown

vercel bot commented Feb 3, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
ralph-tui Ignored Ignored Preview Feb 3, 2026 9:15pm

Request Review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Feb 3, 2026

Walkthrough

Adds tracker task preloading and lifecycle wiring to the TUI run loop, introduces engine auto-start control, expands PRD parsing to support H2–H4 headers with multiple ID formats and fallbacks, adds terminal escape-code sanitisation utilities, inserts pre-implementation steps and progress logging into tracker templates, and UI tweaks (progress bar, PRD guidance).

Changes

Cohort / File(s) Summary
TUI resume & task lifecycle
src/commands/resume.tsx, src/tui/components/RunApp.tsx
Adds initialTasks: TrackerTask[] to runWithTui, loads tracker tasks before launching TUI, wires task:activated/task:completed/iteration:completed to active-task state with persisted saves and non-fatal catches, introduces handleStart engine-start guard and background start behaviour, and tightens historical-log loading to skip active streaming iterations.
PRD parser & tests
src/prd/parser.ts, src/prd/parser.test.ts
Reworks story header matching to support H2–H4 and multiple ID formats, adds normalizeStoryId, implements strict→fallback→ultimate extraction tiers, normalises IDs, and adds extensive tests covering mixed headers, ID formats and edge cases.
Terminal I/O / prompts
src/setup/prompts.ts, src/setup/prompts.test.ts
Adds stripEscapeCodes() and disableMouseTracking(), strips escape codes from prompt inputs, disables mouse tracking for raw input, and adds tests for these utilities and behaviours.
UI enhancements
src/tui/components/ChatView.tsx, src/tui/components/PrdChatApp.tsx
Adds an AnimatedProgressBar for unknown-duration loading in ChatView and expands PRD "no stories" error guidance to list multiple accepted header formats.
Tracker template updates
src/plugins/trackers/builtin/.../template.hbs
src/plugins/trackers/builtin/beads-bv/template.hbs, .../beads-rust/template.hbs, .../beads/template.hbs, .../json/template.hbs
Inserts explicit pre-implementation review steps (review codebase patterns, check related tasks, implement missing related work), renumbers steps, and appends a standardized progress.md snippet and learnings template.

Sequence Diagram(s)

sequenceDiagram
    participant CLI as Client/CLI
    participant Resume as resume.tsx
    participant Tracker as Tracker Plugin
    participant Engine as ExecutionEngine
    participant TUI as RunApp/TUI
    participant State as Persisted State

    CLI->>Resume: runWithTui(engine, cwd, initialState, initialTasks)
    Resume->>Tracker: load tasks (open|in_progress|completed)
    Tracker-->>Resume: TrackerTask[]
    Resume->>TUI: start UI with initialTasks prop
    par Engine auto-start
      Resume->>Engine: handleStart() (guarded, background)
      Engine->>Engine: start background loop
    end
    TUI->>Engine: user actions (start / control)
    Engine->>TUI: events (task:activated / task:completed / iteration:completed)
    TUI->>State: update active-tasks & save (errors caught)
    State-->>TUI: persisted
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main changes: terminal input handling improvements and task loading enhancements, which are the primary focuses across multiple files.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch pr-235-merged

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov
Copy link
Copy Markdown

codecov bot commented Feb 3, 2026

Codecov Report

❌ Patch coverage is 47.95918% with 153 lines in your changes missing coverage. Please review.
✅ Project coverage is 43.69%. Comparing base (952550d) to head (0ad7404).
⚠️ Report is 16 commits behind head on main.

Files with missing lines Patch % Lines
src/prd/parser.ts 62.82% 71 Missing ⚠️
src/commands/resume.tsx 0.00% 52 Missing ⚠️
src/setup/prompts.ts 41.17% 30 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main     #265      +/-   ##
==========================================
+ Coverage   43.57%   43.69%   +0.11%     
==========================================
  Files          94       94              
  Lines       28756    29040     +284     
==========================================
+ Hits        12531    12688     +157     
- Misses      16225    16352     +127     
Files with missing lines Coverage Δ
src/setup/prompts.ts 13.00% <41.17%> (+4.97%) ⬆️
src/commands/resume.tsx 27.80% <0.00%> (-2.61%) ⬇️
src/prd/parser.ts 64.69% <62.82%> (+4.56%) ⬆️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@src/tui/components/RunApp.tsx`:
- Around line 2393-2403: The current checks can still load historical logs when
in the tasks view because selectedIteration is undefined; add a guard that
returns early if the currently selected task is the same as the task being
executed and there is no selectedIteration to prevent reading disk/stale output.
Specifically, before loading historical data add a condition that checks
selectedTask?.id === effectiveTaskId (and selectedTask?.status === 'active' if
you want to be strict) and that selectedIteration is null/undefined, and return
in that case; update the logic near the existing
isRunning/isActiveTask/hasCurrentIteration checks (references:
selectedIteration, selectedTask, effectiveTaskId, iterations, isRunning,
isActiveTask, hasCurrentIteration).
🧹 Nitpick comments (4)
src/setup/prompts.ts (2)

193-203: Minor: Backspace redraw could cause brief flicker.

The double-write approach (clearing and redrawing the full line, then repositioning the cursor) works correctly but may cause visible flicker on slower terminals or with long input. Consider using ANSI cursor positioning sequences (\x1b[nG) to move the cursor directly instead of redrawing twice.


138-144: Consider adding error handling for stdin.

If process.stdin emits an error whilst in raw mode, the cleanup function won't be called, potentially leaving the terminal in an inconsistent state. Consider adding an error listener that calls cleanup.

♻️ Proposed fix to handle stdin errors
     const cleanup = () => {
       process.stdin.removeListener('data', onData);
+      process.stdin.removeListener('error', onError);
       process.stdin.pause();
       if (process.stdin.isTTY) {
         process.stdin.setRawMode(false);
       }
     };

+    const onError = (err: Error) => {
+      cleanup();
+      console.error(`${colors.yellow}Input error: ${err.message}${colors.reset}`);
+      resolve(options.default || '');
+    };

     const onData = (key: string) => {

And add the listener after onData:

     process.stdin.on('data', onData);
+    process.stdin.on('error', onError);
src/prd/parser.ts (2)

94-117: Normalise case for standard IDs when matching is case-insensitive.
With /i on the header regex, lower-case IDs can flow through unchanged; normalising avoids mixed-case IDs downstream.

Suggested change
-  if (/^(US-\d{3}|[A-Z]+-\d+)$/.test(rawId)) {
-    return rawId;
-  }
+  if (/^(US-\d{3}|US-\d+(?:\.\d+)+|[A-Z]+-\d+)$/i.test(rawId)) {
+    return rawId.toUpperCase();
+  }

472-477: Deduplicate the valid-ID regex to prevent drift.
The same pattern appears in both fallback parsers; extracting a shared constant keeps changes safe and consistent.

Suggested change
-      const validIdPattern = /^US-\d{3}$|^US-\d+(?:\.\d+)+$|^(?!US-)[A-Z]+-\d+$|^Feature\s+\d+\.\d+$/i;
-      if (validIdPattern.test(prefix)) {
+      if (VALID_STORY_ID_PATTERN.test(prefix)) {
         id = normalizeStoryId(prefix);
       } else {
         id = `STORY-${String(storyCounter).padStart(3, '0')}`;
       }
...
-      const validIdPattern = /^US-\d{3}$|^US-\d+(?:\.\d+)+$|^(?!US-)[A-Z]+-\d+$|^Feature\s+\d+\.\d+$/i;
-      if (validIdPattern.test(prefix)) {
+      if (VALID_STORY_ID_PATTERN.test(prefix)) {
         id = normalizeStoryId(prefix);
       } else {
         id = `STORY-${String(storyCounter).padStart(3, '0')}`;
       }

You can place the shared constant with the other patterns, for example:

const VALID_STORY_ID_PATTERN =
  /^US-\d{3}$|^US-\d+(?:\.\d+)+$|^(?!US-)[A-Z]+-\d+$|^Feature\s+\d+\.\d+$/i;

Also applies to: 550-552

AI Agent added 2 commits February 3, 2026 21:10
Remove raw mode implementation in favor of simpler readline approach.
The raw mode introduced several risks:
- Terminal stuck in raw mode on crash
- Missing stdin error handler
- Hard process.exit(0) bypassing cleanup
- Missing arrow key/readline shortcut support

The simpler solution:
- disableMouseTracking() prevents mouse codes at source
- stripEscapeCodes() provides fallback sanitization
- Standard readline handles all edge cases properly

-84 lines, same protection, no footguns.
Add guard to skip historical data loading when:
- Viewing the currently executing task (selectedTask.id === currentTaskId)
- Task is active
- No iteration is selected (tasks view, not iteration view)

This prevents showing stale disk output when live output should be displayed.
@subsy subsy merged commit 106f026 into main Feb 3, 2026
9 checks passed
sakaman pushed a commit to sakaman/ralph-tui that referenced this pull request Feb 15, 2026
Improve terminal input handling and task loading (supersedes subsy#235)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants