Skip to content

Fix subtask title display in task modal#1837

Open
AndyMik90 wants to merge 18 commits intodevelopfrom
auto-claude/231-investigate-and-fix-subtask-title-display
Open

Fix subtask title display in task modal#1837
AndyMik90 wants to merge 18 commits intodevelopfrom
auto-claude/231-investigate-and-fix-subtask-title-display

Conversation

@AndyMik90
Copy link
Owner

@AndyMik90 AndyMik90 commented Feb 15, 2026

Base Branch

  • This PR targets the develop branch (required for all feature/fix PRs)
  • This PR targets main (hotfix only - maintainers)

Description

This PR fixes excessively long subtask titles in the task modal by adding a title field to the planner's subtask JSON schema and implementing a fallback extraction utility. Subtask titles now display concisely (≤80 chars) by using the new title field when available, falling back to an intelligent extraction of the first sentence or truncated description. CSS truncation (line-clamp-2) provides an additional UI safety net.

Related Issue

Closes #231

Type of Change

  • 🐛 Bug fix
  • ✨ New feature
  • 📚 Documentation
  • ♻️ Refactor
  • 🧪 Test

Area

  • Frontend
  • Backend
  • Fullstack

Commit Message Format

Follow conventional commits: <type>: <subject>

Types: feat, fix, docs, style, refactor, test, chore

Example: feat: add user authentication system

AI Disclosure

  • This PR includes AI-generated code (Claude, Codex, Copilot, etc.)

Tool(s) used: Claude Code

Testing level:

  • Untested -- AI output not yet verified

  • Lightly tested -- ran the app / spot-checked key paths

  • Fully tested -- all tests pass, manually verified behavior

  • I understand what this PR does and how the underlying code works

Checklist

  • I've synced with develop branch
  • I've tested my changes locally
  • I've followed the code principles (SOLID, DRY, KISS)
  • My PR is small and focused (< 400 lines ideally)

Platform Testing Checklist

CRITICAL: This project supports Windows, macOS, and Linux. Platform-specific bugs are a common source of breakage.

  • Windows tested (either on Windows or via CI)
  • macOS tested (either on macOS or via CI)
  • Linux tested (CI covers this)
  • Used centralized platform/ module instead of direct process.platform checks
  • No hardcoded paths (used findExecutable() or platform abstractions)

If you only have access to one OS: CI now tests on all platforms. Ensure all checks pass before submitting.

CI/Testing Requirements

  • All CI checks pass on all platforms (Windows, macOS, Linux)
  • All existing tests pass
  • New features include test coverage
  • Bug fixes include regression tests

Screenshots

N/A - No UI changes visible to users; internal data mapping fix.

Feature Toggle

  • Behind localStorage flag: use_feature_name
  • Behind settings toggle
  • Behind environment variable/config
  • N/A - Feature is complete and ready for all users

Breaking Changes

Breaking: No

Details:
Changes are fully backward compatible. The new title field is optional in the PlanSubtask interface and in the backend subtask dataclass. Existing implementation plans without a title field continue to work via the extractSubtaskTitle() fallback, which intelligently derives a short title from the description.

Summary by CodeRabbit

  • New Features

    • Subtasks now support explicit titles for clearer identification.
  • Improvements

    • Automatic generation of concise subtask titles from descriptions when none provided.
    • Subtask titles constrained to two-line display; descriptions show tooltips only when distinct and lengthy.
  • Documentation

    • Implementation plan examples and guidelines updated to require short imperative subtask titles; README release links revised.
  • Tests

    • Added comprehensive tests for title-extraction logic.

github-actions bot and others added 9 commits January 30, 2026 21:29
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…examples

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…interface

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add shared utility for extracting concise titles from subtask descriptions
with sentence extraction and word-boundary truncation fallback.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… fallback in project-store

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… fallback in task-store

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…e span

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@github-actions github-actions bot added area/fullstack This is Frontend + Backend size/M Medium (100-499 lines) labels Feb 15, 2026
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @AndyMik90, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request enhances the display of subtask titles in the task modal by introducing a dedicated title field within the subtask schema. This change improves UI readability by providing concise titles, while maintaining detailed descriptions. It includes a robust fallback mechanism to intelligently generate titles from descriptions when a specific title is not provided, ensuring a consistent and user-friendly experience.

Highlights

  • Subtask Title Field: Introduced an optional title field to the Subtask data structure in both the backend and frontend, allowing for explicit, concise titles separate from the detailed description.
  • Intelligent Title Extraction: Implemented a new utility function, extractSubtaskTitle, which intelligently derives a concise title (up to 80 characters) from a subtask's description. It prioritizes extracting the first sentence or truncating at a word boundary with an ellipsis.
  • Frontend Display Logic: Updated the frontend to use the new title field if available, falling back to the extractSubtaskTitle utility for subtasks without an explicit title. Additionally, CSS line-clamp-2 was applied to ensure subtask titles in the UI do not exceed two lines.
  • Prompt Guidance Update: Modified the planner.md prompt to include guidelines for generating short, imperative title fields for subtasks, along with updated examples.
  • Test Coverage: Added comprehensive unit tests for the extractSubtaskTitle utility to ensure its robustness across various input scenarios, including short, long, and empty descriptions, and custom length limits.
Changelog
  • apps/backend/implementation_plan/subtask.py
    • Added an optional title field to the Subtask dataclass.
    • Updated to_dict method to include the title field if present.
    • Modified from_dict method to safely retrieve the title field.
  • apps/backend/prompts/planner.md
    • Added title field to several subtask examples within the prompt.
    • Included a new guideline emphasizing that title must be a short, imperative label (max 60 chars) while description contains full details.
  • apps/frontend/src/tests/subtask-title.test.ts
    • Added a new test file for the extractSubtaskTitle utility.
    • Included tests for short, long, and empty descriptions, sentence boundary truncation, word boundary truncation, and custom maxLength.
  • apps/frontend/src/main/project-store.ts
    • Imported the new extractSubtaskTitle utility.
    • Modified the subtask mapping logic to use subtask.title if available, otherwise falling back to extractSubtaskTitle(subtask.description).
  • apps/frontend/src/renderer/components/task-detail/TaskSubtasks.tsx
    • Applied the line-clamp-2 CSS class to subtask titles for UI truncation.
    • Updated the display logic to show subtask.title or a fallback 'Untitled' if no title is present.
  • apps/frontend/src/renderer/stores/task-store.ts
    • Imported the extractSubtaskTitle utility.
    • Updated the subtask creation logic to assign subtask.title or extractSubtaskTitle(description) as the title.
  • apps/frontend/src/shared/types/task.ts
    • Added an optional title property to the PlanSubtask interface.
  • apps/frontend/src/shared/utils/subtask-title.ts
    • Added a new utility file containing the extractSubtaskTitle function.
    • Implemented logic to extract concise titles from descriptions, handling sentence boundaries, word boundaries, truncation, and default values.
Activity
  • No human activity has been recorded on this pull request yet.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 15, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds an optional title field to subtasks (backend schema and dataclass), updates planner examples and frontend types/stores/components to prefer title with a new extractSubtaskTitle fallback and tests, and updates README release links.

Changes

Cohort / File(s) Summary
Backend data model
apps/backend/implementation_plan/subtask.py
Add optional `title: str
Backend schema/validation
apps/backend/spec/validate_pkg/schemas.py
Add "title" to optional fields in subtask schema within IMPLEMENTATION_PLAN_SCHEMA.
Planner prompts / examples
apps/backend/prompts/planner.md
Inserted title into implementation_plan.json examples and special subtask templates; added guideline that titles are short imperative labels (<=60 chars).
Frontend types
apps/frontend/src/shared/types/task.ts
Add optional title?: string to PlanSubtask.
Title extraction utility & tests
apps/frontend/src/shared/utils/subtask-title.ts, apps/frontend/src/shared/utils/__tests__/subtask-title.test.ts
Add extractSubtaskTitle(description, maxLength) to derive concise titles (sentence/colon extraction, word-boundary truncation with ellipsis); add comprehensive unit tests.
Frontend stores / loader
apps/frontend/src/main/project-store.ts, apps/frontend/src/renderer/stores/task-store.ts
Subtask creation/loading now prefers subtask.title and falls back to extractSubtaskTitle(subtask.description); imports added.
UI display
apps/frontend/src/renderer/components/task-detail/TaskSubtasks.tsx
Render subtask title with line-clamp-2; show description tooltip only when description exists and differs from title (long-tooltip conditional).
Docs
README.md
Replace beta.5 references with beta.1 in release badge and platform download links.
sequenceDiagram
    participant PlanFile as Plan JSON
    participant Backend as Backend (schema + Subtask dataclass)
    participant Frontend as Frontend (loader/store)
    participant UI as Renderer UI
    PlanFile->>Backend: upload/serve plan (may include subtask.title)
    Backend->>Backend: validate schema (optional "title")
    Frontend->>Backend: fetch plan
    Frontend->>Frontend: for each subtask use `title` || extractSubtaskTitle(description)
    Frontend->>UI: provide subtasks (title, description)
    UI->>UI: render title (line-clamp) and conditional description tooltip
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

bug, area/backend, area/frontend

Poem

🐇 I nibble descriptions, trim them light,
Titles hop out tidy, two lines in sight,
A dot or colon shows where to start,
If words run long, I leave an ellipsis-heart,
From backend burrow to frontend bright.

🚥 Pre-merge checks | ✅ 3 | ❌ 3
❌ Failed checks (3 warnings)
Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The PR does not address the coding requirements of the linked issue #231, which requires diagnosing and eliminating excessive lsof process spawning on macOS, causing high CPU usage. Investigate and fix the root cause of lsof spawning (likely in process monitoring code) to reduce CPU utilization on macOS systems.
Out of Scope Changes check ⚠️ Warning The PR introduces subtask title handling (field addition, extraction utility, display logic) which is unrelated to the stated objective of fixing excessive lsof process spawning in issue #231. Either address the lsof spawning issue as stated in #231 or update the PR objectives to clarify that this PR solves a different problem than issue #231.
Docstring Coverage ⚠️ Warning Docstring coverage is 75.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ 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 'Fix subtask title display in task modal' accurately describes the primary change: improving how subtask titles are displayed in the task modal component through a new optional title field and fallback extraction logic.
Merge Conflict Detection ✅ Passed ✅ No merge conflicts detected when merging into develop

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

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch auto-claude/231-investigate-and-fix-subtask-title-display

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.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request effectively addresses the issue of long subtask titles by introducing a new title field and a fallback utility, extractSubtaskTitle, to generate concise titles from descriptions. The changes are implemented consistently across the backend, frontend, and AI prompts, ensuring backward compatibility. The addition of comprehensive unit tests for the new utility is a great practice. I've included a few suggestions to enhance the title extraction logic and improve the examples in the planner prompt to provide clearer guidance for the AI.

Comment on lines +277 to 278
"title": "Create aggregation Celery task",
"description": "Create aggregation Celery task",
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The title and description are identical. According to the new guideline on line 370, the description should contain "full implementation details". To better guide the AI, consider making the description more detailed.

For example: "description": "Create a Celery task that aggregates analytics events from the last hour into a summary table."

Comment on lines +394 to 395
"title": "Identify root cause of memory leak",
"description": "Identify root cause of memory leak",
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The title and description are identical. To align with the guideline on line 370, the description should be more detailed than the title.

For example: "description": "Use memory profiling tools to trace the source of the memory leak reported in issue #123. The investigation should focus on the data processing pipeline."

Comment on lines +410 to 411
"title": "Add new auth system alongside old",
"description": "Add new auth system alongside old",
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The title and description are identical. The new guideline on line 370 states that the description should provide full implementation details. A more detailed description here would be a better example for the AI.

For instance: "description": "Implement the new JWT-based authentication system in 'src/auth/new_auth.ts' and integrate it into the main auth flow in 'src/auth/index.ts' behind a feature flag."

Comment on lines 23 to 28
const sentenceMatch = trimmed.match(/^(.+?(?:\. |: ))/);
if (sentenceMatch) {
let sentence = sentenceMatch[1].trimEnd();
// Strip trailing period or colon+space artifacts
sentence = sentence.replace(/[.:]\s*$/, '');
if (sentence.length <= maxLength) {
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The current regex for sentence extraction only handles sentences ending with a period or colon followed by a space. This can be made more robust to handle other common sentence-ending punctuation (like ! and ?) and to correctly identify sentences at the end of the string that aren't followed by a space.

Suggested change
const sentenceMatch = trimmed.match(/^(.+?(?:\. |: ))/);
if (sentenceMatch) {
let sentence = sentenceMatch[1].trimEnd();
// Strip trailing period or colon+space artifacts
sentence = sentence.replace(/[.:]\s*$/, '');
if (sentence.length <= maxLength) {
const sentenceMatch = trimmed.match(/^(.+?[.?!:])(?=\s+|$)/);
if (sentenceMatch) {
let sentence = sentenceMatch[1];
// Strip trailing punctuation
sentence = sentence.replace(/[.?!:]$/, '');
if (sentence.length <= maxLength) {

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: 4

🤖 Fix all issues with AI agents
In `@apps/backend/implementation_plan/subtask.py`:
- Around line 57-58: The current truthy check in the serialization (in the
Subtask class's to_dict/serialize method) uses "if self.title:" which drops
empty-string titles; change it to "if self.title is not None:" to match the
pattern used for other optional fields like session_id and ensure empty-string
titles are preserved in the resulting dict; update the conditional guarding
result["title"] in the method where self.title is handled.

In `@apps/backend/prompts/planner.md`:
- Around line 276-278: The example subtask "subtask-2-1" currently has identical
"title" and "description", which teaches the wrong pattern; update the example
entries (e.g., subtask-2-1) so the "title" remains a short action phrase and the
"description" provides full implementation details, acceptance criteria, and any
constraints or inputs/outputs expected (distinct from the title) to follow the
guideline that descriptions contain full implementation details.

In `@apps/frontend/src/shared/utils/subtask-title.ts`:
- Around line 22-31: The sentence extraction regex requires a space after the
period or colon so single-sentence descriptions ending with '.' or ':' won't
match; update the regex used to set sentenceMatch to allow a period or colon
followed by either whitespace or end-of-string (e.g. change /^(.+?(?:\. |: ))/
to a pattern that accepts [.:] followed by \s or $) so trimmed sentences like
"Fix the login button styling." are captured; keep the subsequent trimming/strip
logic (variables: trimmed, sentenceMatch, sentence, maxLength) and ensure you
still remove trailing punctuation with the existing replace call.
- Around line 12-13: The function extractSubtaskTitle currently returns the
hardcoded string 'Untitled' which prevents the downstream i18n fallback in
TaskSubtasks.tsx (t('tasks:subtasks.untitled')) from running; modify
extractSubtaskTitle to return an empty string (or a sentinel like
null/undefined) when description is empty OR add an optional fallback parameter
so callers can supply the translation key/value, updating the function signature
(extractSubtaskTitle) and its usages accordingly so no user-facing strings are
hardcoded in the utility.

Comment on lines +57 to +58
if self.title:
result["title"] = self.title
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Falsy check drops empty-string titles — use is not None for consistency.

if self.title: skips serialization when title is "". Other optional fields in this method (e.g., session_id on Line 79) correctly use is not None. Use the same pattern here to stay consistent and avoid silently losing data.

Proposed fix
-        if self.title:
+        if self.title is not None:
             result["title"] = self.title
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if self.title:
result["title"] = self.title
if self.title is not None:
result["title"] = self.title
🤖 Prompt for AI Agents
In `@apps/backend/implementation_plan/subtask.py` around lines 57 - 58, The
current truthy check in the serialization (in the Subtask class's
to_dict/serialize method) uses "if self.title:" which drops empty-string titles;
change it to "if self.title is not None:" to match the pattern used for other
optional fields like session_id and ensure empty-string titles are preserved in
the resulting dict; update the conditional guarding result["title"] in the
method where self.title is handled.

Comment on lines 276 to 278
"id": "subtask-2-1",
"title": "Create aggregation Celery task",
"description": "Create aggregation Celery task",
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Example subtask has identical title and description — demonstrates the wrong pattern.

Several examples (e.g., subtask-2-1) have title and description set to the same string. Since the guideline on Line 370 says "Description contains full implementation details," the examples should show descriptions that are more detailed than the title. Otherwise, the LLM will learn to duplicate them.

🤖 Prompt for AI Agents
In `@apps/backend/prompts/planner.md` around lines 276 - 278, The example subtask
"subtask-2-1" currently has identical "title" and "description", which teaches
the wrong pattern; update the example entries (e.g., subtask-2-1) so the "title"
remains a short action phrase and the "description" provides full implementation
details, acceptance criteria, and any constraints or inputs/outputs expected
(distinct from the title) to follow the guideline that descriptions contain full
implementation details.

Comment on lines 22 to 31
// Try to extract first sentence via '. ' or ': '
const sentenceMatch = trimmed.match(/^(.+?(?:\. |: ))/);
if (sentenceMatch) {
let sentence = sentenceMatch[1].trimEnd();
// Strip trailing period or colon+space artifacts
sentence = sentence.replace(/[.:]\s*$/, '');
if (sentence.length <= maxLength) {
return sentence;
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Sentence extraction won't match a description that is a single sentence ending with a period (no trailing text).

The regex /^(.+?(?:\. |: ))/ requires a space after the period. A description like "Fix the login button styling." (>80 chars, ending with . and no trailing space) won't match, falling through to word-boundary truncation. This may be intentional but is worth noting since many AI-generated descriptions end with a period.

🤖 Prompt for AI Agents
In `@apps/frontend/src/shared/utils/subtask-title.ts` around lines 22 - 31, The
sentence extraction regex requires a space after the period or colon so
single-sentence descriptions ending with '.' or ':' won't match; update the
regex used to set sentenceMatch to allow a period or colon followed by either
whitespace or end-of-string (e.g. change /^(.+?(?:\. |: ))/ to a pattern that
accepts [.:] followed by \s or $) so trimmed sentences like "Fix the login
button styling." are captured; keep the subsequent trimming/strip logic
(variables: trimmed, sentenceMatch, sentence, maxLength) and ensure you still
remove trailing punctuation with the existing replace call.

@AndyMik90 AndyMik90 self-assigned this Feb 15, 2026
Copy link
Owner Author

@AndyMik90 AndyMik90 left a comment

Choose a reason for hiding this comment

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

🤖 Auto Claude PR Review

Merge Verdict: 🟠 NEEDS REVISION

🟠 Needs revision - 2 issue(s) require attention.

Branch is out of date with base branch. Update branch first - if no conflicts arise, you can merge. If merge conflicts arise, resolve them and run follow-up review again. 2 issue(s) must be addressed (0 required, 2 recommended).

Risk Assessment

Factor Level Notes
Complexity Low Based on lines changed
Security Impact None Based on security findings
Scope Coherence Good Based on structural review

🚨 Blocking Issues (Must Fix)

  • Branch Out of Date: PR branch is behind the base branch and needs to be updated

Findings Summary

  • Medium: 2 issue(s)

Generated by Auto Claude PR Review

Findings (2 selected of 2 total)

🟡 [086d238cc4a4] [MEDIUM] Hardcoded 'Untitled' string bypasses i18n fallback in UI component

📁 apps/frontend/src/shared/utils/subtask-title.ts:13

The extractSubtaskTitle() utility returns the hardcoded English string 'Untitled' for empty/null/undefined inputs. This is consumed by project-store.ts:506 which sets title: subtask.title || extractSubtaskTitle(subtask.description). When subtask.description is undefined (e.g., malformed plan JSON), the title becomes the truthy string 'Untitled'.

The UI component TaskSubtasks.tsx:72 already has a proper i18n fallback: {subtask.title || t('tasks:subtasks.untitled')} which maps to 'Untitled subtask' (en) / 'Sous-tâche sans titre' (fr). But since 'Untitled' is truthy, the component's i18n fallback is never reached — French users would see the raw English 'Untitled' instead of 'Sous-tâche sans titre'.

The project's CLAUDE.md mandates: 'All frontend user-facing text MUST use react-i18next translation keys. Never hardcode strings.'

Suggested fix:

Return an empty string `''` instead of `'Untitled'` from `extractSubtaskTitle()` for falsy inputs. This way the component's existing i18n fallback `subtask.title || t('tasks:subtasks.untitled')` will activate correctly since `''` is falsy. Update the tests to expect `''` instead of `'Untitled'`.

🟡 [f6e963a1ded3] [MEDIUM] Test file placed in wrong directory, breaking established pattern

📁 apps/frontend/src/__tests__/subtask-title.test.ts:1

The test for subtask-title.ts is placed at src/__tests__/subtask-title.test.ts, but the established pattern for shared utility tests is to co-locate them at src/shared/utils/__tests__/. Both existing shared utility test files (ansi-sanitizer.test.ts and task-status.test.ts) follow this co-located pattern. The src/__tests__/ directory is reserved for integration and e2e tests (e.g., integration/claude-profile-ipc.test.ts, integration/task-lifecycle.test.ts, e2e/smoke.test.ts), not unit tests for individual utilities.

Verified by Glob search: src/shared/utils/__tests__/ contains ansi-sanitizer.test.ts and task-status.test.ts; src/__tests__/ contains only integration and e2e tests (plus this misplaced file).

Suggested fix:

Move `apps/frontend/src/__tests__/subtask-title.test.ts` to `apps/frontend/src/shared/utils/__tests__/subtask-title.test.ts` and update the import to `import { extractSubtaskTitle } from '../subtask-title';`

This review was generated by Auto Claude.

AndyMik90 and others added 2 commits February 15, 2026 14:50
…tigate-and-fix-subtask-title-display

# Conflicts:
#	README.md
Return empty string instead of hardcoded 'Untitled' from
extractSubtaskTitle() so the UI component's i18n fallback
(t('tasks:subtasks.untitled')) activates correctly for all locales.

Move subtask-title.test.ts to src/shared/utils/__tests__/ to match
the established co-located test pattern for shared utilities.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@AndyMik90 AndyMik90 force-pushed the auto-claude/231-investigate-and-fix-subtask-title-display branch from 3bbbfb6 to c588c83 Compare February 15, 2026 13:51
@CLAassistant
Copy link

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you all sign our Contributor License Agreement before we can accept your contribution.
1 out of 2 committers have signed the CLA.

✅ AndyMik90
❌ github-actions[bot]
You have signed the CLA already but the status is still pending? Let us recheck it.

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: 3

🤖 Fix all issues with AI agents
In `@apps/frontend/src/shared/utils/__tests__/subtask-title.test.ts`:
- Around line 5-6: The test imports extractSubtaskTitle using a relative path;
update the import to use the project path alias so it follows tsconfig
conventions: replace "../subtask-title" with "@shared/utils/subtask-title" in
the test file that imports extractSubtaskTitle so the symbol extractSubtaskTitle
is resolved via the `@shared/`* alias.
- Around line 21-31: Add a unit test to cover the regex edge case where a long
description is a single sentence that ends with a period but has no trailing
space: inside the existing describe('long descriptions with sentence boundary')
block add an it(...) that passes a long (>80 chars) string like "Implement the
complete authentication flow for the new user registration module." to
extractSubtaskTitle and asserts the returned title equals that sentence without
the trailing period; this documents and verifies sentence extraction for a
single-sentence description ending with '.' and no following whitespace.

In `@apps/frontend/src/shared/utils/subtask-title.ts`:
- Around line 33-38: The truncation logic in
apps/frontend/src/shared/utils/subtask-title.ts can return trimmed plus an
ellipsis that exceeds maxLength for single-word inputs; update the branch that
computes cutoff (where variables truncated, lastSpace, cutoff are used) so when
no space is found (lastSpace <= 0) you reserve room for the ellipsis by setting
cutoff to max(1, maxLength - 1) (or otherwise subtract 1 from maxLength) before
returning `${trimmed.substring(0, cutoff)}\u2026`, ensuring the final string
length does not exceed maxLength.

Comment on lines +5 to +6
import { describe, it, expect } from 'vitest';
import { extractSubtaskTitle } from '../subtask-title';
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Consider using the @shared/ path alias for the import.

Per the project's coding guidelines, frontend files should use path aliases defined in tsconfig.json.

-import { extractSubtaskTitle } from '../subtask-title';
+import { extractSubtaskTitle } from '@shared/utils/subtask-title';

As per coding guidelines: "Use path aliases defined in tsconfig.json: … @shared/*src/shared/*"

🤖 Prompt for AI Agents
In `@apps/frontend/src/shared/utils/__tests__/subtask-title.test.ts` around lines
5 - 6, The test imports extractSubtaskTitle using a relative path; update the
import to use the project path alias so it follows tsconfig conventions: replace
"../subtask-title" with "@shared/utils/subtask-title" in the test file that
imports extractSubtaskTitle so the symbol extractSubtaskTitle is resolved via
the `@shared/`* alias.

Comment on lines +21 to +31
describe('long descriptions with sentence boundary', () => {
it('should truncate at first sentence ending with period-space', () => {
const desc = 'Fix the login button styling. Then update the tests and make sure everything works correctly across all browsers.';
expect(extractSubtaskTitle(desc)).toBe('Fix the login button styling');
});

it('should truncate at first sentence ending with colon-space', () => {
const desc = 'Fix the login button: Then update the tests and make sure everything works correctly across all browsers and devices.';
expect(extractSubtaskTitle(desc)).toBe('Fix the login button');
});
});
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Add a test case for a single sentence ending with . but no trailing text.

This is the known regex edge case — a long description like "Implement the complete authentication flow for the new user registration module." (>80 chars, ends in . with no space after) will fall through to word-boundary truncation rather than sentence extraction. Adding a test documents this behavior explicitly.

Suggested test
+    it('should fall through to word truncation for a single sentence ending with period (no trailing text)', () => {
+      const desc = 'Implement the complete authentication flow for the new user registration module.';
+      // No '. ' match, so falls to word-boundary truncation if > maxLength
+      const result = extractSubtaskTitle(desc, 40);
+      expect(result.endsWith('\u2026')).toBe(true);
+    });
🤖 Prompt for AI Agents
In `@apps/frontend/src/shared/utils/__tests__/subtask-title.test.ts` around lines
21 - 31, Add a unit test to cover the regex edge case where a long description
is a single sentence that ends with a period but has no trailing space: inside
the existing describe('long descriptions with sentence boundary') block add an
it(...) that passes a long (>80 chars) string like "Implement the complete
authentication flow for the new user registration module." to
extractSubtaskTitle and asserts the returned title equals that sentence without
the trailing period; this documents and verifies sentence extraction for a
single-sentence description ending with '.' and no following whitespace.

Comment on lines 33 to 38
// Truncate at last word boundary within maxLength
const truncated = trimmed.substring(0, maxLength);
const lastSpace = truncated.lastIndexOf(' ');
const cutoff = lastSpace > 0 ? lastSpace : maxLength;

return `${trimmed.substring(0, cutoff)}\u2026`;
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Edge case: single-word input longer than maxLength produces a result exceeding the limit.

When trimmed has no spaces and exceeds maxLength, lastSpace is -1, so cutoff = maxLength, and the return is maxLength + 1 characters (the truncated text plus the ellipsis). This is technically fine since the ellipsis is a single display character, but worth noting for consistency with the documented "≤80 characters" contract.

🤖 Prompt for AI Agents
In `@apps/frontend/src/shared/utils/subtask-title.ts` around lines 33 - 38, The
truncation logic in apps/frontend/src/shared/utils/subtask-title.ts can return
trimmed plus an ellipsis that exceeds maxLength for single-word inputs; update
the branch that computes cutoff (where variables truncated, lastSpace, cutoff
are used) so when no space is found (lastSpace <= 0) you reserve room for the
ellipsis by setting cutoff to max(1, maxLength - 1) (or otherwise subtract 1
from maxLength) before returning `${trimmed.substring(0, cutoff)}\u2026`,
ensuring the final string length does not exceed maxLength.

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: 1

🤖 Fix all issues with AI agents
In `@README.md`:
- Around line 39-50: The README contains a beta badge and a BETA_DOWNLOADS table
that reference a non-existent GitHub release tag "v2.7.6-beta.1"; fix this by
either removing the Beta badge block and the entire BETA_DOWNLOADS table or
updating all occurrences of the release tag and asset URLs (the "Beta" badge
line and every link in the BETA_DOWNLOADS table) to point to an actual published
release tag/URLs or an existing stable version. Ensure the badge comment markers
(<!-- BETA_VERSION_BADGE_END --> and <!-- BETA_DOWNLOADS -->) and the exact tag
string "v2.7.6-beta.1" are updated/removed so no broken links remain.

README.md Outdated
Comment on lines 39 to 50
[![Beta](https://img.shields.io/badge/beta-2.7.6--beta.1-orange?style=flat-square)](https://github.com/AndyMik90/Auto-Claude/releases/tag/v2.7.6-beta.1)
<!-- BETA_VERSION_BADGE_END -->

<!-- BETA_DOWNLOADS -->
| Platform | Download |
|----------|----------|
| **Windows** | [Auto-Claude-2.7.6-beta.5-win32-x64.exe](https://github.com/AndyMik90/Auto-Claude/releases/download/v2.7.6-beta.5/Auto-Claude-2.7.6-beta.5-win32-x64.exe) |
| **macOS (Apple Silicon)** | [Auto-Claude-2.7.6-beta.5-darwin-arm64.dmg](https://github.com/AndyMik90/Auto-Claude/releases/download/v2.7.6-beta.5/Auto-Claude-2.7.6-beta.5-darwin-arm64.dmg) |
| **macOS (Intel)** | [Auto-Claude-2.7.6-beta.5-darwin-x64.dmg](https://github.com/AndyMik90/Auto-Claude/releases/download/v2.7.6-beta.5/Auto-Claude-2.7.6-beta.5-darwin-x64.dmg) |
| **Linux** | [Auto-Claude-2.7.6-beta.5-linux-x86_64.AppImage](https://github.com/AndyMik90/Auto-Claude/releases/download/v2.7.6-beta.5/Auto-Claude-2.7.6-beta.5-linux-x86_64.AppImage) |
| **Linux (Debian)** | [Auto-Claude-2.7.6-beta.5-linux-amd64.deb](https://github.com/AndyMik90/Auto-Claude/releases/download/v2.7.6-beta.5/Auto-Claude-2.7.6-beta.5-linux-amd64.deb) |
| **Linux (Flatpak)** | [Auto-Claude-2.7.6-beta.5-linux-x86_64.flatpak](https://github.com/AndyMik90/Auto-Claude/releases/download/v2.7.6-beta.5/Auto-Claude-2.7.6-beta.5-linux-x86_64.flatpak) |
| **Windows** | [Auto-Claude-2.7.6-beta.1-win32-x64.exe](https://github.com/AndyMik90/Auto-Claude/releases/download/v2.7.6-beta.1/Auto-Claude-2.7.6-beta.1-win32-x64.exe) |
| **macOS (Apple Silicon)** | [Auto-Claude-2.7.6-beta.1-darwin-arm64.dmg](https://github.com/AndyMik90/Auto-Claude/releases/download/v2.7.6-beta.1/Auto-Claude-2.7.6-beta.1-darwin-arm64.dmg) |
| **macOS (Intel)** | [Auto-Claude-2.7.6-beta.1-darwin-x64.dmg](https://github.com/AndyMik90/Auto-Claude/releases/download/v2.7.6-beta.1/Auto-Claude-2.7.6-beta.1-darwin-x64.dmg) |
| **Linux** | [Auto-Claude-2.7.6-beta.1-linux-x86_64.AppImage](https://github.com/AndyMik90/Auto-Claude/releases/download/v2.7.6-beta.1/Auto-Claude-2.7.6-beta.1-linux-x86_64.AppImage) |
| **Linux (Debian)** | [Auto-Claude-2.7.6-beta.1-linux-amd64.deb](https://github.com/AndyMik90/Auto-Claude/releases/download/v2.7.6-beta.1/Auto-Claude-2.7.6-beta.1-linux-amd64.deb) |
| **Linux (Flatpak)** | [Auto-Claude-2.7.6-beta.1-linux-x86_64.flatpak](https://github.com/AndyMik90/Auto-Claude/releases/download/v2.7.6-beta.1/Auto-Claude-2.7.6-beta.1-linux-x86_64.flatpak) |
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify release tag and assets exist in GitHub for v2.7.6-beta.1
gh api repos/AndyMik90/Auto-Claude/releases/tags/v2.7.6-beta.1 2>&1 \
  | jq -r '.tag_name, (.assets[]?.name)' 2>/dev/null || echo "Release not found or API error"

Repository: AndyMik90/Auto-Claude

Length of output: 100


Remove or correct the non-existent beta release links—release v2.7.6-beta.1 does not exist on GitHub.

The GitHub release tag v2.7.6-beta.1 is not published, making all download links in this table (lines 39-50) broken. Either publish the release with these assets, revert to an existing version, or remove the beta section.

🤖 Prompt for AI Agents
In `@README.md` around lines 39 - 50, The README contains a beta badge and a
BETA_DOWNLOADS table that reference a non-existent GitHub release tag
"v2.7.6-beta.1"; fix this by either removing the Beta badge block and the entire
BETA_DOWNLOADS table or updating all occurrences of the release tag and asset
URLs (the "Beta" badge line and every link in the BETA_DOWNLOADS table) to point
to an actual published release tag/URLs or an existing stable version. Ensure
the badge comment markers (<!-- BETA_VERSION_BADGE_END --> and <!--
BETA_DOWNLOADS -->) and the exact tag string "v2.7.6-beta.1" are updated/removed
so no broken links remain.

Copy link
Owner Author

@AndyMik90 AndyMik90 left a comment

Choose a reason for hiding this comment

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

🤖 Auto Claude PR Review

🟠 Follow-up Review: Needs Revision

🟠 Needs revision - 1 blocking issue(s) require fixes.

Resolution Status

  • Resolved: 2 previous findings addressed
  • Unresolved: 0 previous findings remain
  • 🆕 New Issues: 3 new findings in recent changes

Finding Validation

  • 🔍 Dismissed as False Positives: 1 findings were re-investigated and found to be incorrect
  • Confirmed Valid: 3 findings verified as genuine issues
  • 👤 Needs Human Review: 0 findings require manual verification

🚨 Blocking Issues

  • quality: Title and description show duplicate content for short subtask descriptions

Verdict

CI Status: ⏳ 1 CI check still pending — cannot approve for merge until all checks pass.

Previous Findings: Both previous findings (i18n bypass and test file location) have been properly resolved in commit c588c83. The author addressed the review feedback accurately.

New Finding [MEDIUM]: NEW-001 identifies that short subtask descriptions (≤80 chars) without an explicit backend title result in duplicate text in the UI (title and description show identical content). This is confirmed valid, though notably this is a partially pre-existing pattern — before this PR, title = description was always true. This PR actually improves the situation for long descriptions and subtasks with explicit titles. A simple conditional render (subtask.description !== subtask.title) would address this.

Low Severity Items (non-blocking): The regex terminal period edge case (NEW-002) and missing test case (CMT-002) are minor improvement suggestions. CMT-001 (maxLength+1) was dismissed as false positive since the test suite explicitly documents this as intended behavior.

Comments: All major CodeRabbit concerns have been addressed. The path alias suggestion was correctly identified as contradicting codebase convention. The CLA signature check is a process issue for the maintainer to resolve.

Review Process

Agents invoked: resolution-verifier, new-code-reviewer, comment-analyzer, finding-validator


This is an AI-generated follow-up review using parallel specialist analysis with finding validation.

Findings (3 selected of 3 total)

🟡 [NEW-001] [MEDIUM] Title and description show duplicate content for short subtask descriptions

📁 apps/frontend/src/renderer/components/task-detail/TaskSubtasks.tsx:71

When a subtask has no explicit title from the backend and its description is short (<=80 chars), extractSubtaskTitle() returns the full description as the title. TaskSubtasks.tsx renders both the title (line 72) and the description (line 78) independently, causing the same text to appear twice — once as bold title and again as muted description below. This affects subtasks without explicit backend titles, which is the common case for plans created before this PR. Note: this is partially a pre-existing pattern (title was always set to description before this PR), but the PR could address it by conditionally hiding the description when it equals the title.

Suggested fix:

Conditionally render the description only when it differs from the title: {subtask.description && subtask.description !== subtask.title && (<p>...</p>)}

🔵 [NEW-002] [LOW] Sentence extraction regex does not handle terminal period without trailing space

📁 apps/frontend/src/shared/utils/subtask-title.ts:23

The regex /^(.+?(?:\. |: ))/ only matches sentences ending with '. ' (period-space) or ': ' (colon-space). Descriptions with sentences separated by newlines or ending with a bare period would not match, falling through to word-boundary truncation instead of sentence extraction. This is a minor edge case since the fallback behavior is reasonable.

Suggested fix:

Extend the regex to handle period followed by newline: /^(.+?(?:\.[\s\n]|:\s))/

🔵 [CMT-002] [LOW] Missing test for single sentence ending with period and no trailing text

📁 apps/frontend/src/shared/utils/__tests__/subtask-title.test.ts:0

No test covers a long description that is a single sentence ending with '.' but no trailing text/space. This would document the expected behavior that such input falls through to word-boundary truncation rather than sentence extraction.

Suggested fix:

Add test: it('should truncate at word boundary for single sentence with terminal period', () => { const desc = 'This is a very long single sentence that exceeds the maximum length threshold and ends with a period.'; const result = extractSubtaskTitle(desc); expect(result.endsWith('\u2026')).toBe(true); });

This review was generated by Auto Claude.

Address review finding NEW-001 by conditionally rendering description
only when it differs from the title. This prevents duplicate text when
extractSubtaskTitle() returns the full description for short subtasks.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Comment on lines 232 to 238
"subtasks": [
{
"id": "subtask-1-1",
"title": "Create data models for analytics",
"description": "Create data models for [feature]",
"service": "backend",
"files_to_modify": ["src/models/user.py"],

This comment was marked as outdated.

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: 1

🤖 Fix all issues with AI agents
In `@apps/frontend/src/renderer/components/task-detail/TaskSubtasks.tsx`:
- Around line 75-88: The Tooltip is being mounted even when no TooltipContent is
rendered, causing Radix accessibility/state issues; change the rendering in
TaskSubtasks (around the subtask.description use) so that when
subtask.description exists but its length is <= 80 you render the plain <p> (the
current paragraph) directly, and only render the <Tooltip> wrapper with
<TooltipTrigger> and <TooltipContent> when subtask.description.length > 80;
update the conditional around Tooltip/TooltipTrigger/TooltipContent to check
subtask.description.length > 80 and keep the existing line-clamp/paragraph
markup outside the Tooltip for short descriptions.

Copy link
Owner Author

@AndyMik90 AndyMik90 left a comment

Choose a reason for hiding this comment

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

🤖 Auto Claude PR Review

🟠 Follow-up Review: Needs Revision

🟠 Needs revision - 1 unresolved finding(s) from previous review.

Resolution Status

  • Resolved: 2 previous findings addressed
  • Unresolved: 1 previous findings remain
  • 🆕 New Issues: 1 new findings in recent changes

Finding Validation

  • 🔍 Dismissed as False Positives: 5 findings were re-investigated and found to be incorrect
  • Confirmed Valid: 3 findings verified as genuine issues
  • 👤 Needs Human Review: 0 findings require manual verification

Verdict

CI Status: ⏳ 1 CI check still pending — cannot approve for merge until all checks pass.

Previous Findings: The blocking MEDIUM finding (NEW-001: duplicate title/description display) has been properly resolved in commit c6745ad. The author added subtask.description !== subtask.title to conditionally suppress the description when it matches the title. Two LOW findings (NEW-002: regex terminal period, CMT-002: missing test) remain unresolved but were re-validated as genuine — they are minor edge cases that don't block functionality.

New Code: 5 new findings were identified by code review and comment analysis. After thorough validation by finding-validator, 4 were dismissed as false positives (schema optional_fields not used by validator, serialization asymmetry follows established patterns, abbreviation edge case unrealistic for AI input, whitespace comparison theoretical only). 1 new finding was confirmed valid: the Tooltip rendering without TooltipContent for short descriptions (LOW severity, accessibility concern flagged by both new-code-reviewer and CodeRabbit).

Bottom Line: Only 3 LOW severity findings remain confirmed valid, and the MEDIUM blocking issue from the previous review is resolved. Once CI passes, this PR would qualify for MERGE_WITH_CHANGES. The remaining findings are minor improvements that could be addressed in a follow-up.

Review Process

Agents invoked: resolution-verifier, new-code-reviewer, comment-analyzer, finding-validator


This is an AI-generated follow-up review using parallel specialist analysis with finding validation.

Findings (2 selected of 2 total)

🔵 [NEW-002] [LOW] [UNRESOLVED] Sentence extraction regex does not handle terminal period without trailing space

📁 apps/frontend/src/shared/utils/subtask-title.ts:23

The regex /^(.+?(?:\. |: ))/ only matches sentences ending with '. ' (period-space) or ': ' (colon-space). Descriptions with sentences separated by newlines or ending with a bare period would not match, falling through to word-boundary truncation instead of sentence extraction. This is a minor edge case since the fallback behavior is reasonable.

Resolution note: subtask-title.ts line 23: const sentenceMatch = trimmed.match(/^(.+?(?:\. |: ))/); — the regex still only matches period-space or colon-space. A description >80 chars ending with '.' but no trailing space falls through to word-boundary truncation instead of clean sentence extraction. Commit c6745ad did not modify this file's regex.

Suggested fix:

Extend the regex to handle period followed by newline: /^(.+?(?:\.[\s\n]|:\s))/

🔵 [NCR-003] [LOW] Tooltip without TooltipContent renders for descriptions <= 80 chars

📁 apps/frontend/src/renderer/components/task-detail/TaskSubtasks.tsx:76

When subtask.description exists, differs from subtask.title, but has length <= 80 characters, a Radix wraps but no is produced (line 82 condition is false). This creates a dangling aria-describedby reference — a minor accessibility anti-pattern also flagged by CodeRabbit. Fix: conditionally render the Tooltip wrapper only when description.length > 80, render a plain

otherwise.

Suggested fix:

Restructure rendering: when description.length > 80, wrap in Tooltip/TooltipTrigger/TooltipContent; otherwise render a plain <p> element without Tooltip wrapper.

This review was generated by Auto Claude.

AndyMik90 and others added 2 commits February 15, 2026 20:28
Address review findings from sentry and CodeRabbit:
1. Add 'title' to subtask validation schema optional_fields so the AI
   planner can actually generate the field (HIGH severity finding)
2. Fix Tooltip rendering to only wrap content when description >80 chars,
   preventing Radix accessibility issues when TooltipContent is absent

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Owner Author

@AndyMik90 AndyMik90 left a comment

Choose a reason for hiding this comment

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

🤖 Auto Claude PR Review

🟠 Follow-up Review: Needs Revision

🟠 Needs revision - 1 unresolved finding(s) from previous review.

Resolution Status

  • Resolved: 1 previous findings addressed
  • Unresolved: 1 previous findings remain
  • 🆕 New Issues: 3 new findings in recent changes

Finding Validation

  • 🔍 Dismissed as False Positives: 1 findings were re-investigated and found to be incorrect
  • Confirmed Valid: 4 findings verified as genuine issues
  • 👤 Needs Human Review: 0 findings require manual verification

Verdict

[Recovered via extraction] CI has 1 check still pending, which per guidelines requires NEEDS_REVISION. Additionally, there is 1 unresolved prior finding (NEW-002 regex terminal period) and 3 new low-severity findings identified.

Review Process

Agents invoked: resolution-verifier, new-code-reviewer, comment-analyzer, finding-validator


This is an AI-generated follow-up review using parallel specialist analysis with finding validation.

Findings (4 selected of 4 total)

🔵 [FU-64C97113] [LOW] Hardcoded 80 threshold coupled between files (NCR-NEW-001)

📁 unknown:0

[Recovered via extraction] Hardcoded 80 threshold coupled between files (NCR-NEW-001)

🔵 [FU-6FEBC716] [LOW] Degenerate single-char title extraction (NCR-NEW-002)

📁 unknown:0

[Recovered via extraction] Degenerate single-char title extraction (NCR-NEW-002)

🔵 [FU-10F41F34] [LOW] Tooltip trigger not keyboard-focusable (CMT-002)

📁 unknown:0

[Recovered via extraction] Tooltip trigger not keyboard-focusable (CMT-002)

🔵 [NEW-002] [LOW] [UNRESOLVED] [UNRESOLVED] Sentence extraction regex does not handle terminal period without trailing space

📁 apps/frontend/src/shared/utils/subtask-title.ts:23

The regex /^(.+?(?:\. |: ))/ only matches sentences ending with '. ' (period-space) or ': ' (colon-space). Descriptions with sentences separated by newlines or ending with a bare period would not match, falling through to word-boundary truncation instead of sentence extraction. This is a minor edge case since the fallback behavior is reasonable.

Resolution note: subtask-title.ts line 23: const sentenceMatch = trimmed.match(/^(.+?(?:\. |: ))/); — the regex still only matches period-space or colon-space. A description >80 chars ending with '.' but no trailing space falls through to word-boundary truncation instead of clean sentence extraction. Commit c6745ad did not modify this file's regex.

Suggested fix:

Extend the regex to handle period followed by newline: /^(.+?(?:\.[\s\n]|:\s))/

This review was generated by Auto Claude.

Replace paragraph element with button for tooltip trigger to enable keyboard navigation and focus visibility. Adds proper focus ring styling for accessibility compliance.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Owner Author

@AndyMik90 AndyMik90 left a comment

Choose a reason for hiding this comment

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

🤖 Auto Claude PR Review

🟠 Follow-up Review: Needs Revision

🟠 Needs revision - 3 unresolved finding(s) from previous review.

Resolution Status

  • Resolved: 1 previous findings addressed
  • Unresolved: 3 previous findings remain
  • 🆕 New Issues: 0 new findings in recent changes

Finding Validation

  • 🔍 Dismissed as False Positives: 2 findings were re-investigated and found to be incorrect
  • Confirmed Valid: 3 findings verified as genuine issues
  • 👤 Needs Human Review: 0 findings require manual verification

Verdict

Ready once CI passes: 1 check(s) still pending. All code issues addressed, waiting for CI completion.

Review Process

Agents invoked: resolution-verifier, new-code-reviewer, comment-analyzer, finding-validator


This is an AI-generated follow-up review using parallel specialist analysis with finding validation.

Findings (3 selected of 3 total)

🔵 [FU-64C97113] [LOW] [UNRESOLVED] Hardcoded 80 threshold coupled between files (NCR-NEW-001)

📁 unknown:0

[Recovered via extraction] Hardcoded 80 threshold coupled between files (NCR-NEW-001)

🔵 [FU-6FEBC716] [LOW] [UNRESOLVED] Degenerate single-char title extraction (NCR-NEW-002)

📁 unknown:0

[Recovered via extraction] Degenerate single-char title extraction (NCR-NEW-002)

🔵 [NEW-002] [LOW] [UNRESOLVED] [UNRESOLVED] [UNRESOLVED] Sentence extraction regex does not handle terminal period without trailing space

📁 apps/frontend/src/shared/utils/subtask-title.ts:23

The regex /^(.+?(?:\. |: ))/ only matches sentences ending with '. ' (period-space) or ': ' (colon-space). Descriptions with sentences separated by newlines or ending with a bare period would not match, falling through to word-boundary truncation instead of sentence extraction. This is a minor edge case since the fallback behavior is reasonable.

Resolution note: subtask-title.ts line 23: const sentenceMatch = trimmed.match(/^(.+?(?:\. |: ))/); — the regex still only matches period-space or colon-space. A description >80 chars ending with '.' but no trailing space falls through to word-boundary truncation instead of clean sentence extraction. Commit c6745ad did not modify this file's regex.

Suggested fix:

Extend the regex to handle period followed by newline: /^(.+?(?:\.[\s\n]|:\s))/

This review was generated by Auto Claude.

Fixes three LOW severity findings from auto-claude PR review:
1. Decouple hardcoded 80-char threshold using SUBTASK_TITLE_MAX_LENGTH constant
2. Improve regex to handle terminal periods without trailing space/newline
3. Fix truncation to never exceed maxLength even for single-word inputs

Changes:
- Export SUBTASK_TITLE_MAX_LENGTH constant from subtask-title.ts
- Update TaskSubtasks.tsx to use the constant instead of magic number 80
- Enhanced sentence extraction regex to handle period+newline and terminal periods
- Improved truncation logic to ensure maxLength-1 + ellipsis for degenerate cases
- Added comprehensive tests for terminal period edge cases and degenerate truncation

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Owner Author

@AndyMik90 AndyMik90 left a comment

Choose a reason for hiding this comment

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

🤖 Auto Claude PR Review

🟠 Follow-up Review: Needs Revision

🟠 Needs revision - 1 blocking issue(s) require fixes.

Resolution Status

  • Resolved: 3 previous findings addressed
  • Unresolved: 0 previous findings remain
  • 🆕 New Issues: 4 new findings in recent changes

Finding Validation

  • 🔍 Dismissed as False Positives: 0 findings were re-investigated and found to be incorrect
  • Confirmed Valid: 4 findings verified as genuine issues
  • 👤 Needs Human Review: 0 findings require manual verification

🚨 Blocking Issues

  • quality: Regex abbreviation splitting issue in subtask title truncation

Verdict

Ready once CI passes: 1 check(s) still pending. All code issues addressed, waiting for CI completion.

Review Process

Agents invoked: resolution-verifier, new-code-reviewer, finding-validator


This is an AI-generated follow-up review using parallel specialist analysis with finding validation.

Findings (4 selected of 4 total)

🟡 [FU-98D59AB2] [MEDIUM] Regex abbreviation splitting issue in subtask title truncation

📁 unknown:0

[Recovered via extraction] Regex abbreviation splitting issue in subtask title truncation

🔵 [FU-A1AB6453] [LOW] Test assertion too loose - checks 81 instead of 80 character limit

📁 unknown:0

[Recovered via extraction] Test assertion too loose - checks 81 instead of 80 character limit

🔵 [FU-BA31837C] [LOW] Docstring parameter order mismatch in truncation function

📁 unknown:0

[Recovered via extraction] Docstring parameter order mismatch in truncation function

🔵 [FU-D91FC851] [LOW] Custom maxLength test assertion too loose

📁 unknown:0

[Recovered via extraction] Custom maxLength test assertion too loose


This review was generated by Auto Claude.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/fullstack This is Frontend + Backend size/M Medium (100-499 lines)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Excessive Spawning of lsof

2 participants