Skip to content

fix: make tag listing table use dynamic column widths to prevent truncation#1264

Merged
Crunchyman-ralph merged 2 commits intonextfrom
claude/issue-1263-20251002-1252
Oct 2, 2025
Merged

fix: make tag listing table use dynamic column widths to prevent truncation#1264
Crunchyman-ralph merged 2 commits intonextfrom
claude/issue-1263-20251002-1252

Conversation

@Crunchyman-ralph
Copy link
Collaborator

@Crunchyman-ralph Crunchyman-ralph commented Oct 2, 2025

Fixes #1263

Changes

  • Replace hardcoded colWidths with terminal-width-based calculation
  • Tag Name column now gets 70% width (normal) or 25% width (metadata mode)
  • Add wordWrap support for better handling of long tag names
  • Fixes issue where tag names >20 chars were truncated with ellipsis
  • Users can now see full tag names for use with use-tag command

Testing

Tag names longer than 20 characters should now display fully in the task-master tags command output.

Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Tag list now adapts column widths to your terminal size for improved readability.
    • Automatic word-wrapping prevents content truncation in narrow terminals.
    • Layout adjusts when metadata is shown or hidden to preserve a clean table view.
    • More responsive, consistent tag-table display across different terminal widths.

@changeset-bot
Copy link

changeset-bot bot commented Oct 2, 2025

⚠️ No Changeset found

Latest commit: 10e5591

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@Crunchyman-ralph Crunchyman-ralph changed the base branch from main to next October 2, 2025 13:09
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 2, 2025

Walkthrough

Replaces fixed table column widths with dynamic widths computed from 95% of the terminal width, choosing column weight sets depending on whether metadata is shown, applies computed colWidths, and enables word-wrapping; headers and row construction are unchanged.

Changes

Cohort / File(s) Summary of Changes
Dynamic column widths and wrapping
scripts/modules/task-manager/tag-management.js
Calculate usable terminal width (95% of process.stdout.columns), choose per-column weight arrays for metadata/no-metadata layouts, compute colWidths with minimums, enable wordWrap on the Table, and replace hard-coded column widths while keeping headers/rows logic intact.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Pre-merge checks and finishing touches

✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title clearly and concisely summarizes the primary change by stating that the tag listing table now uses dynamic column widths to prevent truncation, directly reflecting the main focus of the PR without extraneous details. It is concise, specific to the change, and understandable at a glance.
Linked Issues Check ✅ Passed The PR fully addresses the objectives of issue #1263 by replacing hardcoded widths with a terminal-based calculation for the Tag Name column, enabling word wrap, and removing the previous ellipsis truncation so that full tag names display and remain selectable for the use-tag command. This matches the expected behaviors of auto-sizing, wrapping long names, and ensuring complete tag visibility.
Out of Scope Changes Check ✅ Passed All modifications are confined to the tag management script’s column sizing logic, directly targeting the truncation issue specified in the linked issue, with no unrelated or extraneous changes introduced elsewhere.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch claude/issue-1263-20251002-1252

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

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

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3b3dbab and 7f9c425.

📒 Files selected for processing (1)
  • scripts/modules/task-manager/tag-management.js (1 hunks)
🧰 Additional context used
📓 Path-based instructions (5)
scripts/modules/task-manager/*.js

📄 CodeRabbit inference engine (.cursor/rules/ai_services.mdc)

scripts/modules/task-manager/*.js: Centralize all LLM calls through generateTextService or generateObjectService.
Do not import or call anything from the old ai-services.js, ai-client-factory.js, or ai-client-utils.js files.
Do not initialize AI clients (Anthropic, Perplexity, etc.) directly within core logic (task-manager/) or MCP direct functions.
Do not fetch AI-specific parameters (model ID, max tokens, temp) using config-manager.js getters for the AI call. Pass the role instead.
Do not implement fallback or retry logic outside ai-services-unified.js.
Do not handle API key resolution outside the service layer (it uses utils.js internally).
Determine the appropriate role (main, research, fallback) in your core logic and pass it to the service.
Pass the session object (received in the context parameter, especially from direct function wrappers) to the service call when in MCP context.
Use generateTextService and implement robust manual JSON parsing (with Zod validation after parsing) when structured output is needed, as generateObjectService has shown unreliability with some providers/schemas.
Be aware of potential reliability issues with generateObjectService across different providers and complex schemas. Prefer generateTextService + manual parsing as a more robust alternative for structured data needs.

Files in scripts/modules/task-manager/ should each handle a specific action related to task management (e.g., add-task.js, expand-task.js), supporting the tagged task lists system and backward compatibility.

Files:

  • scripts/modules/task-manager/tag-management.js
scripts/modules/**

📄 CodeRabbit inference engine (.cursor/rules/dev_workflow.mdc)

When using the MCP server, restart it if core logic in scripts/modules or MCP tool/direct function definitions change.

Files:

  • scripts/modules/task-manager/tag-management.js
scripts/modules/task-manager/*

📄 CodeRabbit inference engine (.cursor/rules/tags.mdc)

scripts/modules/task-manager/*: All core functions in scripts/modules/task-manager/ must accept a context parameter and use it to extract projectRoot and tag
All core functions in scripts/modules/task-manager/ must use readJSON(tasksPath, projectRoot, tag) and writeJSON(tasksPath, data, projectRoot, tag)

Files:

  • scripts/modules/task-manager/tag-management.js
scripts/modules/task-manager/**/*.js

📄 CodeRabbit inference engine (.cursor/rules/telemetry.mdc)

scripts/modules/task-manager/**/*.js: Functions in scripts/modules/task-manager/ that invoke AI services must call the appropriate AI service function (e.g., generateObjectService), passing commandName and outputType in the params object.
Core logic functions in scripts/modules/task-manager/ must return an object that includes aiServiceResponse.telemetryData.
If the core logic function handles CLI output (outputFormat === 'text' or 'cli'), and aiServiceResponse.telemetryData is available, it must call displayAiUsageSummary(aiServiceResponse.telemetryData, 'cli') from scripts/modules/ui.js.

Do not call AI-specific getters (like getMainModelId, getMainMaxTokens) from core logic functions in scripts/modules/task-manager/*; instead, pass the role to the unified AI service.

Files:

  • scripts/modules/task-manager/tag-management.js
**/*.js

📄 CodeRabbit inference engine (.cursor/rules/tests.mdc)

**/*.js: Declare and initialize global variables at the top of modules to avoid hoisting issues.
Use proper function declarations to avoid hoisting issues and initialize variables before they are referenced.
Do not reference variables before their declaration in module scope.
Use dynamic imports (import()) to avoid initialization order issues in modules.

Files:

  • scripts/modules/task-manager/tag-management.js
🧠 Learnings (3)
📚 Learning: 2025-07-18T17:14:29.399Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tasks.mdc:0-0
Timestamp: 2025-07-18T17:14:29.399Z
Learning: Applies to scripts/modules/task-manager.js : Allow filtering tasks by status within the current tag context, handle subtask display in lists, and use consistent table formats.

Applied to files:

  • scripts/modules/task-manager/tag-management.js
📚 Learning: 2025-07-18T17:14:29.399Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tasks.mdc:0-0
Timestamp: 2025-07-18T17:14:29.399Z
Learning: Applies to scripts/modules/task-manager.js : Use tag resolution functions to maintain backward compatibility, returning legacy format to core functions and not exposing the tagged structure to existing core logic.

Applied to files:

  • scripts/modules/task-manager/tag-management.js
📚 Learning: 2025-07-18T17:16:32.622Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/ui.mdc:0-0
Timestamp: 2025-07-18T17:16:32.622Z
Learning: Applies to scripts/modules/ui.js : Use cli-table3 for table rendering, include colored bold headers, and set appropriate column widths for readability

Applied to files:

  • scripts/modules/task-manager/tag-management.js
🧬 Code graph analysis (1)
scripts/modules/task-manager/tag-management.js (1)
scripts/modules/task-manager/add-task.js (1)
  • table (570-577)
🪛 GitHub Actions: CI
scripts/modules/task-manager/tag-management.js

[error] 622-641: Biome format check detected formatting diffs in the file. The formatter would have reformatted content. Run 'npm run format-check' again after applying fixes (or run the formatter directly, e.g., 'biome format .') to resolve the issue.

🔇 Additional comments (1)
scripts/modules/task-manager/tag-management.js (1)

644-648: Approve dynamic widths and wordWrap implementation. Verified no hardcoded truncation (no .slice/substring) remains in tag-management.js; dynamic colWidths and wordWrap: true ensure full tag names display.

claude bot and others added 2 commits October 2, 2025 15:32
…cation

- Replace hardcoded colWidths with terminal-width-based calculation
- Tag Name column now gets 70% width (normal) or 25% width (metadata mode)
- Add wordWrap support for better handling of long tag names
- Fixes issue where tag names >20 chars were truncated with ellipsis
- Users can now see full tag names for use with use-tag command

Co-authored-by: Ralph Khreish <Crunchyman-ralph@users.noreply.github.com>
@Crunchyman-ralph Crunchyman-ralph force-pushed the claude/issue-1263-20251002-1252 branch from 7f9c425 to 10e5591 Compare October 2, 2025 13:35
@Crunchyman-ralph Crunchyman-ralph mentioned this pull request Oct 2, 2025
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

♻️ Duplicate comments (1)
scripts/modules/task-manager/tag-management.js (1)

622-644: Run formatter to fix CI-detected formatting issues.

The past review flagged Biome formatting inconsistencies in this code block. Please run the project formatter before merging.

Based on coding guidelines

Run the following command to fix formatting:

#!/bin/bash
npm run format
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7f9c425 and 10e5591.

📒 Files selected for processing (1)
  • scripts/modules/task-manager/tag-management.js (1 hunks)
🧰 Additional context used
📓 Path-based instructions (5)
scripts/modules/task-manager/*.js

📄 CodeRabbit inference engine (.cursor/rules/ai_services.mdc)

scripts/modules/task-manager/*.js: Centralize all LLM calls through generateTextService or generateObjectService.
Do not import or call anything from the old ai-services.js, ai-client-factory.js, or ai-client-utils.js files.
Do not initialize AI clients (Anthropic, Perplexity, etc.) directly within core logic (task-manager/) or MCP direct functions.
Do not fetch AI-specific parameters (model ID, max tokens, temp) using config-manager.js getters for the AI call. Pass the role instead.
Do not implement fallback or retry logic outside ai-services-unified.js.
Do not handle API key resolution outside the service layer (it uses utils.js internally).
Determine the appropriate role (main, research, fallback) in your core logic and pass it to the service.
Pass the session object (received in the context parameter, especially from direct function wrappers) to the service call when in MCP context.
Use generateTextService and implement robust manual JSON parsing (with Zod validation after parsing) when structured output is needed, as generateObjectService has shown unreliability with some providers/schemas.
Be aware of potential reliability issues with generateObjectService across different providers and complex schemas. Prefer generateTextService + manual parsing as a more robust alternative for structured data needs.

Files in scripts/modules/task-manager/ should each handle a specific action related to task management (e.g., add-task.js, expand-task.js), supporting the tagged task lists system and backward compatibility.

Files:

  • scripts/modules/task-manager/tag-management.js
scripts/modules/**

📄 CodeRabbit inference engine (.cursor/rules/dev_workflow.mdc)

When using the MCP server, restart it if core logic in scripts/modules or MCP tool/direct function definitions change.

Files:

  • scripts/modules/task-manager/tag-management.js
scripts/modules/task-manager/*

📄 CodeRabbit inference engine (.cursor/rules/tags.mdc)

scripts/modules/task-manager/*: All core functions in scripts/modules/task-manager/ must accept a context parameter and use it to extract projectRoot and tag
All core functions in scripts/modules/task-manager/ must use readJSON(tasksPath, projectRoot, tag) and writeJSON(tasksPath, data, projectRoot, tag)

Files:

  • scripts/modules/task-manager/tag-management.js
scripts/modules/task-manager/**/*.js

📄 CodeRabbit inference engine (.cursor/rules/telemetry.mdc)

scripts/modules/task-manager/**/*.js: Functions in scripts/modules/task-manager/ that invoke AI services must call the appropriate AI service function (e.g., generateObjectService), passing commandName and outputType in the params object.
Core logic functions in scripts/modules/task-manager/ must return an object that includes aiServiceResponse.telemetryData.
If the core logic function handles CLI output (outputFormat === 'text' or 'cli'), and aiServiceResponse.telemetryData is available, it must call displayAiUsageSummary(aiServiceResponse.telemetryData, 'cli') from scripts/modules/ui.js.

Do not call AI-specific getters (like getMainModelId, getMainMaxTokens) from core logic functions in scripts/modules/task-manager/*; instead, pass the role to the unified AI service.

Files:

  • scripts/modules/task-manager/tag-management.js
**/*.js

📄 CodeRabbit inference engine (.cursor/rules/tests.mdc)

**/*.js: Declare and initialize global variables at the top of modules to avoid hoisting issues.
Use proper function declarations to avoid hoisting issues and initialize variables before they are referenced.
Do not reference variables before their declaration in module scope.
Use dynamic imports (import()) to avoid initialization order issues in modules.

Files:

  • scripts/modules/task-manager/tag-management.js
🧠 Learnings (2)
📚 Learning: 2025-07-18T17:14:29.399Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tasks.mdc:0-0
Timestamp: 2025-07-18T17:14:29.399Z
Learning: Applies to scripts/modules/task-manager.js : Allow filtering tasks by status within the current tag context, handle subtask display in lists, and use consistent table formats.

Applied to files:

  • scripts/modules/task-manager/tag-management.js
📚 Learning: 2025-07-18T17:16:32.622Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/ui.mdc:0-0
Timestamp: 2025-07-18T17:16:32.622Z
Learning: Applies to scripts/modules/ui.js : Use cli-table3 for table rendering, include colored bold headers, and set appropriate column widths for readability

Applied to files:

  • scripts/modules/task-manager/tag-management.js
🧬 Code graph analysis (1)
scripts/modules/task-manager/tag-management.js (1)
scripts/modules/task-manager/add-task.js (1)
  • table (570-577)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Test
🔇 Additional comments (1)
scripts/modules/task-manager/tag-management.js (1)

641-645: LGTM! Table configuration meets PR objectives.

The computed colWidths and wordWrap: true changes successfully address the truncation issue. Tag names longer than 20 characters will now display fully with word wrapping enabled.

Comment on lines +626 to +639
let colWidths;
if (showMetadata) {
// With metadata: Tag Name, Tasks, Completed, Created, Description
const widths = [0.25, 0.1, 0.12, 0.15, 0.38];
colWidths = widths.map((w, i) =>
Math.max(Math.floor(usableWidth * w), i === 0 ? 15 : 8)
);
} else {
// Without metadata: Tag Name, Tasks, Completed
const widths = [0.7, 0.15, 0.15];
colWidths = widths.map((w, i) =>
Math.max(Math.floor(usableWidth * w), i === 0 ? 20 : 10)
);
}
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 redistributing remainder pixels to avoid rounding gaps.

The current implementation uses Math.floor independently on each column, which may leave 1-4 pixels of terminal width unused due to rounding. While this has minimal visual impact, you could add the remainder to the tag name column for perfect width utilization.

Apply this diff if you want to eliminate rounding gaps:

 			let colWidths;
 			if (showMetadata) {
 				// With metadata: Tag Name, Tasks, Completed, Created, Description
 				const widths = [0.25, 0.1, 0.12, 0.15, 0.38];
 				colWidths = widths.map((w, i) =>
 					Math.max(Math.floor(usableWidth * w), i === 0 ? 15 : 8)
 				);
+				// Add any remainder pixels to the tag name column
+				const remainder = usableWidth - colWidths.reduce((sum, w) => sum + w, 0);
+				colWidths[0] += remainder;
 			} else {
 				// Without metadata: Tag Name, Tasks, Completed
 				const widths = [0.7, 0.15, 0.15];
 				colWidths = widths.map((w, i) =>
 					Math.max(Math.floor(usableWidth * w), i === 0 ? 20 : 10)
 				);
+				// Add any remainder pixels to the tag name column
+				const remainder = usableWidth - colWidths.reduce((sum, w) => sum + w, 0);
+				colWidths[0] += remainder;
 			}
📝 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
let colWidths;
if (showMetadata) {
// With metadata: Tag Name, Tasks, Completed, Created, Description
const widths = [0.25, 0.1, 0.12, 0.15, 0.38];
colWidths = widths.map((w, i) =>
Math.max(Math.floor(usableWidth * w), i === 0 ? 15 : 8)
);
} else {
// Without metadata: Tag Name, Tasks, Completed
const widths = [0.7, 0.15, 0.15];
colWidths = widths.map((w, i) =>
Math.max(Math.floor(usableWidth * w), i === 0 ? 20 : 10)
);
}
let colWidths;
if (showMetadata) {
// With metadata: Tag Name, Tasks, Completed, Created, Description
const widths = [0.25, 0.1, 0.12, 0.15, 0.38];
colWidths = widths.map((w, i) =>
Math.max(Math.floor(usableWidth * w), i === 0 ? 15 : 8)
);
// Add any remainder pixels to the tag name column
const remainder = usableWidth - colWidths.reduce((sum, w) => sum + w, 0);
colWidths[0] += remainder;
} else {
// Without metadata: Tag Name, Tasks, Completed
const widths = [0.7, 0.15, 0.15];
colWidths = widths.map((w, i) =>
Math.max(Math.floor(usableWidth * w), i === 0 ? 20 : 10)
);
// Add any remainder pixels to the tag name column
const remainder = usableWidth - colWidths.reduce((sum, w) => sum + w, 0);
colWidths[0] += remainder;
}
🤖 Prompt for AI Agents
In scripts/modules/task-manager/tag-management.js around lines 626 to 639, the
column width calculation floors each column independently which can leave a few
unused pixels; compute the floored widths as now, sum them, compute remainder =
usableWidth - sumFloored, and add the remainder to the first (tag name) column
width so total equals usableWidth while still enforcing the current minimums
(15/20 for first column, 8/10 for others); apply this adjustment in both the
showMetadata and the non-metadata branches.

@Crunchyman-ralph Crunchyman-ralph merged commit c7418c4 into next Oct 2, 2025
8 checks passed
sfc-gh-dflippo pushed a commit to sfc-gh-dflippo/task-master-ai that referenced this pull request Dec 4, 2025
…cation (eyaltoledano#1264)

Co-authored-by: Ralph Khreish <Crunchyman-ralph@users.noreply.github.com>
Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com>
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.

bug:

1 participant