Skip to content

Comments

feat: models.dev integration, create-prd improvements, custom skills_dir, and various fixes#40

Merged
subsy merged 21 commits intomainfrom
feat/recentProgress-in-templates
Jan 14, 2026
Merged

feat: models.dev integration, create-prd improvements, custom skills_dir, and various fixes#40
subsy merged 21 commits intomainfrom
feat/recentProgress-in-templates

Conversation

@subsy
Copy link
Owner

@subsy subsy commented Jan 14, 2026

Summary

This PR adds models.dev integration for provider/model validation, improves the create-prd chat mode, adds custom skills_dir configuration, and fixes several bugs.

Features

models.dev Integration

  • Added src/models-dev/index.ts client that fetches and caches the models.dev API
  • Provides provider/model validation using the official models database
  • Removed restrictive hardcoded provider list from OpenCode plugin (now supports 75+ providers)
  • Added model info display throughout the TUI:
    • Toolbar shows: {agent} | {provider/model} | {tracker}
    • Dashboard (d) shows agent and model info
    • Output view (o) shows agent and model in task header

create-prd Improvements

  • Changed chat input behavior: Enter submits, Shift+Enter/Ctrl+J adds newline
  • Fixed textarea not clearing after message submission
  • Added macOS-style text editing shortcuts:
    • Option + Arrow keys: move by word/paragraph
    • Option + Delete: delete word left/right
    • Shift + Option + Arrow: select by word/paragraph
    • Shift + Arrow: select by character/line
    • Shift + Cmd + Arrow: select to line/document boundaries
  • Allow custom PRD skill selection (--skill flag)
  • Use PRD skill sources in prompts for better context

Custom Skills Directory

  • Added skills_dir configuration option to specify custom skills location
  • Skills can be stored in a user-defined directory outside the project
  • Useful for sharing common skills across multiple projects

Bug Fixes

  1. Handle undefined trackerState - Fixed crash in getSessionSummary when session data is incomplete
  2. Use active agent from engine state - Dashboard and output view now show the actual agent being used (including fallback)
  3. Fix span crash in output view - Changed <span> to <text> for pipe separator
  4. Clear TypeScript build cache in CI - Prevent stale cache from causing false positive lint errors

Files Changed

New Files

  • src/models-dev/index.ts - models.dev API client (+333 lines)

Modified Files

  • src/plugins/agents/builtin/opencode.ts - Less restrictive provider validation
  • src/tui/components/ChatView.tsx - Enter to submit, textarea clearing, text editing shortcuts
  • src/tui/components/Header.tsx - Model display with pipe separators
  • src/tui/components/ProgressDashboard.tsx - Agent/model display
  • src/tui/components/RightPanel.tsx - Agent/model in output view
  • src/tui/types.ts - Added agentName and currentModel to RightPanelProps
  • src/session/persistence.ts - Null checks for trackerState
  • src/commands/create-prd.tsx - Custom skill selection, skills_dir support
  • .github/workflows/ci.yml - Clear TypeScript build cache
  • Plus various other fixes and updates

Commits

  1. f969d94 - fix: isolate task creation from PRD chat
  2. b071fd3 - ci: clear only TypeScript build cache (not node_modules)
  3. a8c4a16 - ci: clear build cache before install to avoid stale cache issues
  4. e808f62 - feat: use PRD skill sources in prompts
  5. 9ab242c - merge: resolve conflict in getSessionSummary with main
  6. 1304809 - feat: allow custom PRD skill selection
  7. 0d34f7c - feat: add macOS-style text editing shortcuts to create-prd chat input
  8. 73fac93 - fix: honor skills_dir in merged config
  9. d9a40b8 - feat: allow skills_dir configuration
  10. 0590da9 - debug: revert progress append logging
  11. 3d27fcb - fix: clear textarea immediately on submit in create-prd mode
  12. 8da528c - fix: use active agent from engine state in dashboard and output view
  13. a62c18e - fix: use text instead of span for pipe separator in output view
  14. ec61696 - feat: show agent and model info in dashboard and output view
  15. eeb42c2 - style: use pipe separator in toolbar for agent/model/tracker display
  16. 629710e - fix: handle undefined trackerState in getSessionSummary
  17. cb00c7a - feat: change chat input to submit on Enter in create-prd mode
  18. 9676709 - feat: add models.dev integration for provider/model validation and display

Summary by CodeRabbit

  • New Features

    • Current model/provider is now shown across the UI.
    • PRD skill support: supply a skill name or skill source and a separate task engine for task generation.
    • Models.dev integration: provider/model listing, validation and caching.
  • Bug Fixes

    • Progress-update failures no longer interrupt iterations.
  • Refactor

    • OpenCode agent provider validation loosened to accept broader provider strings.
  • UX

    • Improved chat keyboard handling and immediate submit clearing.
  • Docs

    • Added docs for PRD skills and custom skills directory; README and website updated.
  • Chores

    • CI cache-clearing steps added.

✏️ Tip: You can customize this high-level summary in your review settings.

subsy added 9 commits January 14, 2026 15:59
…splay

- Add models.dev client with API caching for provider/model validation
- Update OpenCode plugin to accept any provider (75+ supported)
- Add model info display to TUI header (provider/model format)
- Add model info display to output panel timing summary
- Pass currentModel prop through RunApp and RunAppWrapper
- Enter now submits the message (instead of creating newline)
- Shift+Enter or Ctrl+J inserts a newline
- Updated hint text to reflect new key bindings
Add null checks for trackerState to prevent crashes when session data is incomplete or from older versions
- Add currentModel prop to ProgressDashboard for dashboard display
- Add agentName and currentModel to RightPanel for output view display
- Show agent|model in task output header when viewing output (o key)
- Display model info in dashboard (d key) alongside agent and tracker
Fixes crash when switching to output detail view (o key)
Previously ProgressDashboard and RightPanel were using the configured agent name from storedConfig, which doesn't reflect when the engine switches to a fallback agent. Now they use displayAgentName which prefers activeAgentState.plugin from the engine.
Previously the textarea wasn't cleared until the parent component's setInputValue('')
took effect, which could cause a visible delay. Now we clear the textarea's
internal buffer immediately when submit is triggered.
@vercel
Copy link

vercel bot commented Jan 14, 2026

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

Project Deployment Review Updated (UTC)
ralph-tui Ready Ready Preview, Comment Jan 14, 2026 6:01pm

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 14, 2026

Warning

Rate limit exceeded

@subsy has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 23 minutes and 8 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 0a7a32d and 4fe5e2d.

📒 Files selected for processing (2)
  • website/content/docs/cli/create-prd.mdx
  • website/content/docs/configuration/options.mdx

Walkthrough

Threads a new optional currentModel prop through run/resume and TUI components, adds a disk-cached models.dev client, relaxes OpenCode provider validation, introduces configurable PRD skills with a task engine, silences certain progress-append errors, and enhances ChatView keyboard/submit behaviour.

Changes

Cohort / File(s) Summary
Model Display Propagation
src/commands/run.tsx, src/commands/resume.tsx, src/tui/components/RunApp.tsx, src/tui/components/Header.tsx, src/tui/components/ProgressDashboard.tsx, src/tui/components/RightPanel.tsx, src/tui/types.ts
Adds optional currentModel?: string throughout commands and TUI; computes/displayAgentName and propagates agentName/currentModel to child components for consistent UI display.
PRD Skill & Task Engine
src/chat/engine.ts, src/tui/components/PrdChatApp.tsx, src/commands/create-prd.tsx
Adds PRD skill support (prdSkill, prdSkillSource), builders for PRD system prompts, and a separate createTaskChatEngine; create-prd CLI now validates/loads skill sources.
Models.dev API Integration
src/models-dev/index.ts
New client module for models.dev with disk-backed TTL cache, normalization, validation/display helpers and cache management (refresh/clear).
OpenCode Provider Validation Relaxation
src/plugins/agents/builtin/opencode.ts
Replaces strict OpenCodeProvider type with string, removes VALID_PROVIDERS, and delegates provider validation to OpenCode CLI; loosens validateModel/validateSetup.
Engine Error Handling
src/engine/index.ts
Changed two progress-append catch blocks to generic catch, removed console.error logging and prevented append failures from interrupting iteration.
ChatView Keyboard & Submit Handling
src/tui/components/ChatView.tsx
Adds useKeyboard handling (Enter submit, navigation/word-edit shortcuts); clears textarea immediately before invoking onSubmit; respects focus/input state.
PRD Skill Config in CLI & Config Schema
src/commands/create-prd.tsx, src/config/schema.ts, src/config/types.ts, src/config/index.ts
Adds --prd-skill / prdSkill and prdSkillSource CLI options and validation; introduces skills_dir in stored config/schema/types and allows project override.
CI Cache Clear Steps
.github/workflows/ci.yml
Adds steps to clear TypeScript build caches before dependency installation in main and website jobs.
Documentation / Website
README.md, website/content/docs/cli/create-prd.mdx, website/content/docs/configuration/options.mdx
Adds docs for Create PRD options, Custom Skills Directory and examples (duplicated in multiple locations).

Sequence Diagram(s)

sequenceDiagram
  participant User as CLI User
  participant CLI as create-prd
  participant FS as Filesystem (skills_dir)
  participant Engine as createPrdChatEngine
  participant TaskEngine as createTaskChatEngine
  participant UI as PrdChatApp

  User->>CLI: run `create-prd --prd-skill <name>`
  CLI->>FS: resolve skill path, read SKILL.md (prdSkillSource)
  alt skill loaded
    CLI->>Engine: invoke runChatMode with prdSkill/prdSkillSource
    Engine->>Engine: build systemPrompt (from skillSource or skillName)
    Engine->>TaskEngine: createTaskChatEngine for task prompts
    Engine->>UI: start PRD UI with both engines and currentModel (if any)
  else load fails
    CLI->>User: print actionable error and exit
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~35 minutes

Poem

🐰
I hopped through models, cached and neat,
Skills tucked in folders, prompt lines sweet,
Providers freed to roam and play,
Tasks now split to work and say,
Keys click — the rabbit dances on its feet 🥕✨

🚥 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 comprehensively covers the main changes: models.dev integration, create-prd improvements, custom skills_dir, and various fixes, aligning well with the PR objectives.
Docstring Coverage ✅ Passed Docstring coverage is 84.62% which is sufficient. The required threshold is 80.00%.

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


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.

Validate custom PRD skill usage when configured.
Copy link
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: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/tui/components/ChatView.tsx (1)

142-142: Default hint text is inconsistent with new keyboard behaviour.

The default hint mentions [Ctrl+Enter] Send but the actual behaviour now uses Enter to send and Shift+Enter/Ctrl+J for newlines. Update the default to match.

📝 Suggested fix
-  hint = '[Ctrl+Enter] Send  [Esc] Cancel',
+  hint = '[Enter] Send  [Shift+Enter/Ctrl+J] Newline  [Esc] Cancel',
🧹 Nitpick comments (11)
src/session/persistence.ts (1)

579-610: Defensive null-checks look good, but consider aligning the type definition.

The optional chaining on trackerState is a sensible safeguard against crashes from legacy or malformed session files. However, the PersistedSessionState interface (line 97) declares trackerState: TrackerStateSnapshot as required, creating a type/runtime mismatch.

Consider making trackerState optional in the interface to reflect reality:

-  /** Tracker state snapshot */
-  trackerState: TrackerStateSnapshot;
+  /** Tracker state snapshot (may be missing in legacy sessions) */
+  trackerState?: TrackerStateSnapshot;

This ensures TypeScript will flag any other code paths that assume trackerState is always present.

src/engine/index.ts (2)

917-922: Consider retaining minimal error logging for observability.

Silently swallowing errors here is reasonable since progress append is non-critical. However, completely removing error logging could mask persistent issues (e.g., disk full, permission errors) that would be valuable to diagnose. Consider a debug-level log or incrementing a counter for monitoring, rather than complete silence.

💡 Optional: Add debug logging
       try {
         const progressEntry = createProgressEntry(result);
         await appendProgress(this.config.cwd, progressEntry);
-      } catch {
-        // Don't fail iteration if progress append fails
+      } catch (err) {
+        // Don't fail iteration if progress append fails
+        // Log at debug level for troubleshooting persistent issues
+        console.debug('[progress] Failed to append progress entry:', err);
       }

953-958: Same observability consideration as above.

Same pattern as lines 917-922. If you choose to add debug logging there, apply it here as well for consistency.

src/tui/components/ChatView.tsx (1)

79-80: Stale JSDoc comment.

The comment states "presses Ctrl+Enter" but the new behaviour uses Enter (without modifiers) to submit. Update the comment to reflect the current implementation.

📝 Suggested fix
-  /** Callback when user submits (presses Ctrl+Enter) with the current input value */
+  /** Callback when user submits (presses Enter) with the current input value */
   onSubmit?: (value: string) => void;
src/models-dev/index.ts (4)

117-121: Consider adding a timeout to the fetch request.

The fetch call has no timeout configured, which could cause the application to hang indefinitely if the models.dev API is unresponsive. Consider adding an AbortController with a reasonable timeout.

⏱️ Suggested fix
 async function fetchAndCache(): Promise<CacheData> {
+  const controller = new AbortController();
+  const timeoutId = setTimeout(() => controller.abort(), 10000); // 10 second timeout
+
-  const response = await fetch(MODELS_DEV_API_URL);
+  const response = await fetch(MODELS_DEV_API_URL, { signal: controller.signal });
+  clearTimeout(timeoutId);
+
   if (!response.ok) {
     throw new Error(`Failed to fetch models.dev API: ${response.status} ${response.statusText}`);
   }

78-92: Type safety note on cache loading.

The JSON.parse result is typed as CacheData but validModelIds is actually an array at that point (JSON doesn't support Sets). The code correctly handles this at lines 88-90, but the intermediate state has an incorrect type. Consider using an intermediate type for the parsed JSON.

🔧 Optional type-safe approach
+interface CacheDataJson {
+  timestamp: number;
+  providers: ProviderInfo[];
+  modelsByProvider: Record<string, ModelInfo[]>;
+  validModelIds: string[]; // JSON stores as array
+}
+
 function loadCache(): CacheData | null {
   try {
     if (!existsSync(CACHE_FILE_PATH)) {
       return null;
     }

     const content = readFileSync(CACHE_FILE_PATH, 'utf-8');
-    const cache = JSON.parse(content) as CacheData;
+    const parsed = JSON.parse(content) as CacheDataJson;

     // Check if cache is expired
-    if (Date.now() - cache.timestamp > CACHE_TTL_MS) {
+    if (Date.now() - parsed.timestamp > CACHE_TTL_MS) {
       return null;
     }

-    // Restore Set from array
-    if (Array.isArray(cache.validModelIds)) {
-      cache.validModelIds = new Set(cache.validModelIds);
-    }
-
-    return cache;
+    return {
+      ...parsed,
+      validModelIds: new Set(parsed.validModelIds),
+    };
   } catch {

328-333: clearCache only clears in-memory cache.

The clearCache function sets cacheData = null but doesn't remove the disk cache file. The next call to getModelsDevData will reload from disk if the file exists and isn't expired. This may be intentional, but consider documenting the behaviour or adding an option to also clear the disk cache.


198-210: Silent fallback to empty cache on fetch failure.

When the API fetch fails and no valid cache exists, the code silently returns an empty cache. This is resilient but could lead to confusing behaviour where all provider/model validations pass (since there's nothing to validate against). Consider logging a warning or exposing the failure state.

src/tui/components/Header.tsx (1)

160-166: Consider extracting model parsing to a shared utility.

This model parsing logic is duplicated across Header.tsx, ProgressDashboard.tsx, and RightPanel.tsx. Consider extracting it to a shared utility function in theme.ts or a dedicated utils.ts file to reduce duplication and ensure consistent behaviour.

♻️ Suggested utility function
// In src/tui/utils.ts or src/tui/theme.ts
export function parseModelInfo(currentModel: string | undefined): { provider: string; model: string; full: string } | null {
  if (!currentModel) return null;
  const [provider, model] = currentModel.includes('/') ? currentModel.split('/') : ['', currentModel];
  return { provider, model, full: currentModel };
}

Then use it in components:

-  const modelDisplay = currentModel
-    ? (() => {
-        const [provider, model] = currentModel.includes('/') ? currentModel.split('/') : ['', currentModel];
-        return { provider, model, full: currentModel };
-      })()
-    : null;
+  const modelDisplay = parseModelInfo(currentModel);
src/tui/components/RightPanel.tsx (2)

473-479: Minor: Non-null assertions can be simplified.

Since the IIFE is only executed when timing.model is truthy (checked in the ternary condition), the non-null assertions (!) on lines 476-477 are safe but could be avoided by capturing the value in a closure variable.

♻️ Cleaner approach
   const modelDisplay = timing.model
     ? (() => {
-        const [provider, model] = timing.model!.includes('/') ? timing.model!.split('/') : ['', timing.model!];
-        return { provider, model, full: timing.model! };
+        const m = timing.model;
+        const [provider, model] = m.includes('/') ? m.split('/') : ['', m];
+        return { provider, model, full: m };
       })()
     : null;

573-579: Same model parsing pattern duplicated within the same file.

This is the third instance of the model parsing IIFE within RightPanel.tsx alone (also at lines 473-479). Extracting this to a local helper or the suggested shared utility would reduce repetition.

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 48d15b9 and 0590da9.

📒 Files selected for processing (13)
  • src/commands/resume.tsx
  • src/commands/run.tsx
  • src/engine/index.ts
  • src/models-dev/index.ts
  • src/plugins/agents/builtin/opencode.ts
  • src/session/persistence.ts
  • src/tui/components/ChatView.tsx
  • src/tui/components/Header.tsx
  • src/tui/components/PrdChatApp.tsx
  • src/tui/components/ProgressDashboard.tsx
  • src/tui/components/RightPanel.tsx
  • src/tui/components/RunApp.tsx
  • src/tui/types.ts
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Start all code files with a file-level JSDoc comment section explaining the file's purpose, prefixed with 'ABOUTME: '

Files:

  • src/tui/components/ChatView.tsx
  • src/tui/components/PrdChatApp.tsx
  • src/session/persistence.ts
  • src/engine/index.ts
  • src/tui/types.ts
  • src/plugins/agents/builtin/opencode.ts
  • src/commands/run.tsx
  • src/tui/components/RunApp.tsx
  • src/commands/resume.tsx
  • src/tui/components/ProgressDashboard.tsx
  • src/tui/components/RightPanel.tsx
  • src/tui/components/Header.tsx
  • src/models-dev/index.ts
**/*.{js,ts,tsx,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

Start all code files with a file-level JSDoc comment section explaining the file's purpose, prefixed with "ABOUTME: "

Files:

  • src/tui/components/ChatView.tsx
  • src/tui/components/PrdChatApp.tsx
  • src/session/persistence.ts
  • src/engine/index.ts
  • src/tui/types.ts
  • src/plugins/agents/builtin/opencode.ts
  • src/commands/run.tsx
  • src/tui/components/RunApp.tsx
  • src/commands/resume.tsx
  • src/tui/components/ProgressDashboard.tsx
  • src/tui/components/RightPanel.tsx
  • src/tui/components/Header.tsx
  • src/models-dev/index.ts
🧬 Code graph analysis (4)
src/tui/components/RunApp.tsx (1)
src/tui/components/ProgressDashboard.tsx (1)
  • ProgressDashboard (76-151)
src/tui/components/ProgressDashboard.tsx (1)
src/tui/theme.ts (1)
  • colors (9-58)
src/tui/components/RightPanel.tsx (1)
src/tui/theme.ts (1)
  • colors (9-58)
src/tui/components/Header.tsx (2)
src/tui/types.ts (1)
  • HeaderProps (76-103)
src/tui/theme.ts (2)
  • formatElapsedTime (203-215)
  • colors (9-58)
🔇 Additional comments (22)
src/tui/components/ChatView.tsx (1)

161-195: LGTM!

The keyboard handling logic correctly differentiates between plain Enter (submit) and modified Enter keys (newline). The implementation properly captures the textarea value before clearing, and the optional chaining on key.preventDefault?.() handles cases where the method may not exist.

src/plugins/agents/builtin/opencode.ts (3)

403-438: LGTM!

The relaxed provider validation appropriately delegates to the OpenCode CLI, which has comprehensive knowledge of supported providers. The defensive type check ensures invalid types are caught early whilst allowing any valid provider string through.


87-108: LGTM!

The provider field and initialisation logic correctly accept any non-empty string, aligning with the PR's goal of supporting 75+ providers through delegation to the OpenCode CLI.


455-461: Model string with multiple slashes is silently truncated before validation.

The split('/') destructuring only captures the first two segments. If the model string contains multiple slashes (e.g., provider/model/extra), everything after the second segment is discarded without error. This is problematic because:

  • The error message explicitly documents the expected format as provider/model
  • The comment states validation is delegated to OpenCode CLI, but the truncated input is passed instead of the original
  • A user providing provider/model/extra would receive no feedback that part of their input was removed

To address this, either reject strings with more than one slash, or preserve everything after the first slash: model.split('/', 2) and rejoin as modelName = segments.slice(1).join('/').

src/tui/components/PrdChatApp.tsx (1)

500-504: LGTM!

The hint text correctly reflects the new keyboard behaviour where Enter submits and Shift+Enter/Ctrl+J inserts newlines.

src/commands/resume.tsx (3)

89-95: LGTM!

The currentModel parameter is cleanly threaded through the runWithTui function signature, maintaining consistency with the run command implementation.


151-167: LGTM!

The currentModel prop is correctly passed to the RunApp component, enabling the UI to display the current provider/model information during resumed sessions.


398-404: LGTM!

The call site correctly passes config.model as the currentModel argument, ensuring the resumed session displays the same model information as a fresh run.

src/models-dev/index.ts (1)

265-266: Edge case: model strings with multiple slashes.

The split('/') approach has a latent vulnerability. According to the models.dev API documentation, model IDs can contain slashes (e.g., openai/gpt-5). If such a model ID is used in the input format, the destructuring at line 266 will discard everything after the second slash. For instance, an input like provider/openai/gpt-5 would be incorrectly split into ["provider", "openai", "gpt-5"] with only the first two parts captured, causing the validation to fail.

Currently, the codebase examples use hyphens rather than slashes in model identifiers (e.g., anthropic/claude-3-5-sonnet), but the code should be defensive. Use split('/', 2) or similar to properly handle multi-part model identifiers.

src/tui/types.ts (1)

101-102: LGTM!

The new optional properties are well-documented with JSDoc comments and follow the existing naming conventions. The additions maintain backward compatibility as all new props are optional.

Also applies to: 138-139, 158-161

src/tui/components/Header.tsx (1)

219-232: LGTM!

The conditional rendering logic correctly handles the optional model display and properly manages the pipe separators between agent, model, and tracker information.

src/commands/run.tsx (1)

544-546: LGTM!

The currentModel prop is correctly threaded through the component hierarchy from config.model to RunAppWrapper and down to RunApp. The changes are minimal and focused on data flow wiring.

Also applies to: 565-566, 691-691, 910-910

src/tui/components/ProgressDashboard.tsx (2)

18-19: LGTM!

The currentModel prop addition and parsing logic are correctly implemented. Note: The model parsing logic duplication was flagged in the Header.tsx review—the same refactor suggestion applies here.

Also applies to: 79-79, 92-98


127-132: LGTM!

The conditional model display rendering integrates well with the existing agent/tracker information display.

src/tui/components/RightPanel.tsx (1)

583-600: LGTM!

The agent and model information is correctly propagated through the component hierarchy from RightPanelTaskDetailsTaskOutputView. The header rendering in TaskOutputView (lines 583-600) provides clear visual context for the active agent and model.

Also applies to: 721-722, 754-755

src/tui/components/RunApp.tsx (7)

94-96: LGTM!

The new currentModel prop is well-documented and follows the existing prop pattern. The optional typing is appropriate since model info may not always be available.


298-298: LGTM!

Prop destructuring follows the established pattern in this component.


392-394: LGTM!

The displayAgentName computation correctly prioritises the active agent from engine state (which reflects runtime fallback scenarios) over the static config value. The nullish coalescing operator appropriately handles both null and undefined cases from activeAgentState?.plugin.


1151-1151: LGTM!

Propagating currentModel to Header enables consistent model display in the toolbar.


1158-1159: LGTM!

ProgressDashboard now receives the runtime-derived displayAgentName and currentModel, which aligns with the component's updated interface shown in the relevant code snippet.


1197-1198: LGTM!

Consistent prop propagation to RightPanel in the tasks view mode.


1230-1231: LGTM!

Consistent prop propagation to RightPanel in the iterations view mode, maintaining parity with the tasks view branch.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

subsy added 4 commits January 14, 2026 17:30
- Option + Left/Right: move cursor by word
- Option + Up/Down: move cursor to buffer start/end
- Option + Delete: delete word to the left
- Option + Fn + Delete: delete word to the right
- Shift + Option + Left/Right: select by word
- Shift + Option + Up/Down: select to buffer start/end
- Shift + Left/Right/Up/Down: select by character/line
- Shift + Cmd + Left/Right: select to line start/end
- Shift + Cmd + Up/Down: select to buffer start/end
The main branch had a cleaner implementation that defines trackerState once and uses it throughout. Using that approach.
Copy link
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: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
src/tui/components/ChatView.tsx (2)

79-79: JSDoc comment is inconsistent with actual behaviour.

The comment states "presses Ctrl+Enter" but the implementation at line 183 uses plain Enter (without modifiers) to submit. Update the documentation to reflect the new behaviour.

📝 Suggested fix
-  /** Callback when user submits (presses Ctrl+Enter) with the current input value */
+  /** Callback when user submits (presses Enter) with the current input value */

142-142: Default hint text does not match the new keyboard shortcuts.

The hint says [Ctrl+Enter] Send but Enter (without modifiers) now submits, and Shift+Enter/Ctrl+J insert newlines. Consider updating the default hint to accurately guide users.

📝 Suggested fix
-  hint = '[Ctrl+Enter] Send  [Esc] Cancel',
+  hint = '[Enter] Send  [Shift+Enter] New line  [Esc] Cancel',
🤖 Fix all issues with AI agents
In `@src/commands/create-prd.tsx`:
- Line 9: Remove the unused readFile import to fix the TS6133 error: edit the
import statement that currently reads "import { access, readFile, stat } from
'node:fs/promises';" and drop readFile so only used symbols (access, stat) are
imported; ensure no other references to readFile exist in the file (e.g., in
functions like create-prd related code) before committing.
- Around line 45-46: Remove the dead field prdSkillSource from the CreatePrdArgs
interface: locate the CreatePrdArgs declaration and delete the prdSkillSource?:
string; member, and ensure no other code references it (notably
parseCreatePrdArgs and any callers) so the type reflects only used args; run
type checks to confirm nothing else relies on that property.
🧹 Nitpick comments (1)
src/plugins/agents/builtin/opencode.ts (1)

420-425: Consider using a limited split to handle potential slashes in model names.

If a model string contains multiple slashes (e.g., "provider/model/variant"), split('/') will produce more than two elements, and the destructuring will only capture the first two, potentially losing part of the model name.

💡 Suggested fix using limit parameter
     if (model.includes('/')) {
-      const [provider, modelName] = model.split('/');
+      const slashIndex = model.indexOf('/');
+      const provider = model.slice(0, slashIndex);
+      const modelName = model.slice(slashIndex + 1);
       if (!provider || !modelName) {
         return `Invalid model format "${model}". Expected format: provider/model (e.g., anthropic/claude-3-5-sonnet)`;
       }
       // Provider and model name are passed through - OpenCode CLI validates them
     }

This ensures that only the first slash is used as the delimiter, preserving any subsequent slashes as part of the model name.

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0590da9 and 9ab242c.

📒 Files selected for processing (8)
  • src/chat/engine.ts
  • src/commands/create-prd.tsx
  • src/config/index.ts
  • src/config/schema.ts
  • src/config/types.ts
  • src/plugins/agents/builtin/opencode.ts
  • src/tui/components/ChatView.tsx
  • src/tui/components/PrdChatApp.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/tui/components/PrdChatApp.tsx
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Start all code files with a file-level JSDoc comment section explaining the file's purpose, prefixed with 'ABOUTME: '

Files:

  • src/config/schema.ts
  • src/tui/components/ChatView.tsx
  • src/config/types.ts
  • src/chat/engine.ts
  • src/commands/create-prd.tsx
  • src/config/index.ts
  • src/plugins/agents/builtin/opencode.ts
**/*.{js,ts,tsx,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

Start all code files with a file-level JSDoc comment section explaining the file's purpose, prefixed with "ABOUTME: "

Files:

  • src/config/schema.ts
  • src/tui/components/ChatView.tsx
  • src/config/types.ts
  • src/chat/engine.ts
  • src/commands/create-prd.tsx
  • src/config/index.ts
  • src/plugins/agents/builtin/opencode.ts
🧬 Code graph analysis (1)
src/commands/create-prd.tsx (1)
src/config/index.ts (1)
  • loadStoredConfig (194-216)
🪛 GitHub Actions: CI
src/commands/create-prd.tsx

[error] 9-9: TypeScript error TS6133: 'readFile' is declared but its value is never read. (Command: tsc --noEmit during bun run typecheck)

🔇 Additional comments (14)
src/plugins/agents/builtin/opencode.ts (3)

87-88: LGTM!

The type widening from a specific provider union to string aligns well with the objective of supporting 75+ providers and delegating validation to the OpenCode CLI. The comment clearly documents this design decision.


105-108: LGTM!

The simplified provider validation correctly accepts any non-empty string, consistent with the design to delegate provider validity checks to the OpenCode CLI.


371-380: LGTM!

The validation correctly ensures provider is a string type when provided, while appropriately deferring value validation to the OpenCode CLI.

src/tui/components/ChatView.tsx (4)

9-10: LGTM!

The new imports for useKeyboard and KeyEvent are correctly added and used in the keyboard handling implementation.


161-170: LGTM!

The submit handler correctly captures the current value before clearing the textarea, ensuring no data loss while providing immediate visual feedback to the user.


172-302: Well-implemented macOS-style keyboard shortcuts.

The keyboard handler is well-structured with proper modifier key checks and early returns. The dependency array correctly includes all referenced values from the enclosing scope.


304-304: LGTM!

The useKeyboard hook is correctly wired up with the callback, and the conditional logic is appropriately handled inside the handler rather than around the hook call.

src/config/types.ts (1)

179-180: LGTM!

The new skills_dir optional field is consistent with the existing pattern for optional string configuration properties and aligns with the corresponding schema and merge logic additions.

src/config/index.ts (1)

166-166: LGTM!

The skills_dir override follows the established pattern for scalar field merging, consistent with adjacent fields like progressFile and autoCommit.

src/config/schema.ts (1)

129-130: LGTM!

The schema addition for skills_dir correctly uses Zod 4's optional string validation and is appropriately placed alongside the related prompt_template field.

src/commands/create-prd.tsx (2)

125-152: LGTM! Well-structured validation with clear error messages.

The validatePrdSkill function properly validates that the skill directory exists and contains the required SKILL.md file, with actionable error messages for each failure case.


274-284: LGTM! Good defensive validation.

The validation logic correctly ensures skills_dir is configured before allowing --prd-skill usage, with clear error messages guiding users to the correct configuration location.

src/chat/engine.ts (2)

22-37: LGTM! Good refactoring for configurable PRD skills.

The extraction of buildPrdSystemPrompt and DEFAULT_PRD_SKILL enables runtime flexibility whilst maintaining backward compatibility via the static PRD_SYSTEM_PROMPT export.


347-359: LGTM! Clean conditional system prompt selection.

The factory function correctly uses the provided prdSkill to build a custom system prompt, falling back to the default when not specified.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

subsy added 3 commits January 14, 2026 17:44
Clear node_modules/.cache, node_modules/.pnpm, and .tsbuildinfo before installing dependencies to prevent stale TypeScript/bun cache from causing false positives in unused variable checks.
Only remove .tsbuildinfo and node_modules/.cache to fix stale TypeScript cache issues without reinstalling all packages.
@subsy subsy changed the title feat: models.dev integration, create-prd improvements, and various fixes feat: models.dev integration, create-prd improvements, custom skills_dir, and various fixes Jan 14, 2026
subsy added 2 commits January 14, 2026 17:57
Document new create-prd options and custom skills_dir configuration
- Add --prd-skill option to create-prd CLI docs
- Add skills_dir configuration option docs
- Add examples for custom skills usage
- Update README with new commands
Add PRD format specification that custom skills must follow for downstream task creation compatibility
@subsy subsy merged commit 03f0275 into main Jan 14, 2026
5 checks passed
@subsy subsy deleted the feat/recentProgress-in-templates branch January 14, 2026 21:43
sakaman pushed a commit to sakaman/ralph-tui that referenced this pull request Feb 15, 2026
feat: models.dev integration, create-prd improvements, custom skills_dir, and various fixes
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.

1 participant