feat: sort briefs by updated at#1409
Conversation
|
WalkthroughAdds a relative-time utility and exports it from tm-core, displays briefs' updatedAt as human-friendly relative strings in the CLI, orders briefs by updated_at in the DB query, and adds date-fns as a dependency in root and tm-core. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor CLI
participant TMCore as tm-core (org service)
participant DB as Supabase
participant Utils as formatRelativeTime
participant UI as CLI UI
CLI->>TMCore: request briefs (getBriefs)
TMCore->>DB: query briefs (filter by account_id, order by updated_at desc)
DB-->>TMCore: briefs list
TMCore-->>CLI: briefs list
CLI->>Utils: formatRelativeTime(brief.updatedAt) [per brief with updatedAt]
Utils-->>CLI: "2 hours ago" (relative string)
CLI->>UI: render brief list (name + updatedAtDisplay)
UI-->>CLI: rendered output
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes
Possibly related PRs
Suggested reviewers
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (2)
packages/tm-core/src/utils/time.utils.ts (1)
13-18: Consider handling invalid dates gracefully.The function converts strings to Date objects without validation. While
formatDistanceToNowcan handle invalid dates, it may not produce user-friendly output for malformed date strings.Consider adding validation:
export function formatRelativeTime(date: string | Date): string { const dateObj = typeof date === 'string' ? new Date(date) : date; + + // Handle invalid dates gracefully + if (isNaN(dateObj.getTime())) { + return 'unknown'; + } // Use date-fns for robust formatting with proper edge case handling return formatDistanceToNow(dateObj, { addSuffix: true }); }apps/cli/src/utils/brief-selection.ts (1)
126-129: TEMP comments suggest work in progress.The "TEMP: Show updatedAt for verification" comments on lines 126 and 167 indicate this feature may still be under testing. Ensure you remove these comments before merging if the feature is finalized.
Additionally, this exact code block appears twice (lines 126-129 and 167-170). Consider extracting it to avoid duplication:
// Near the top of the function or as a helper const getUpdatedAtDisplay = (updatedAt?: string) => updatedAt ? chalk.gray(` • ${formatRelativeTime(updatedAt)}`) : ''; // Then use it in both places: const updatedAtDisplay = getUpdatedAtDisplay(brief.updatedAt);Also applies to: 167-170
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (6)
apps/cli/src/utils/brief-selection.ts(3 hunks)package.json(1 hunks)packages/tm-core/package.json(1 hunks)packages/tm-core/src/index.ts(1 hunks)packages/tm-core/src/modules/auth/services/organization.service.ts(2 hunks)packages/tm-core/src/utils/time.utils.ts(1 hunks)
🧰 Additional context used
🧠 Learnings (8)
📓 Common learnings
Learnt from: Crunchyman-ralph
Repo: eyaltoledano/claude-task-master PR: 1178
File: packages/tm-core/src/auth/config.ts:5-7
Timestamp: 2025-09-02T21:51:27.921Z
Learning: The user Crunchyman-ralph prefers not to use node: scheme imports (e.g., 'node:os', 'node:path') for Node.js core modules and considers suggestions to change bare imports to node: scheme as too nitpicky.
Learnt from: Crunchyman-ralph
Repo: eyaltoledano/claude-task-master PR: 1069
File: .changeset/fix-tag-complexity-detection.md:0-0
Timestamp: 2025-08-02T15:33:22.656Z
Learning: For changeset files (.changeset/*.md), Crunchyman-ralph prefers to ignore formatting nitpicks about blank lines between frontmatter and descriptions, as he doesn't mind having them and wants to avoid such comments in future reviews.
Learnt from: Crunchyman-ralph
Repo: eyaltoledano/claude-task-master PR: 1132
File: .github/workflows/weekly-metrics-discord.yml:81-93
Timestamp: 2025-08-13T22:10:46.958Z
Learning: Crunchyman-ralph ignores YAML formatting nitpicks about trailing spaces when there's no project-specific YAML formatter configured, preferring to focus on functionality over cosmetic formatting issues.
Learnt from: Crunchyman-ralph
Repo: eyaltoledano/claude-task-master PR: 1132
File: .github/workflows/weekly-metrics-discord.yml:81-93
Timestamp: 2025-08-13T22:10:46.958Z
Learning: Crunchyman-ralph ignores YAML formatting nitpicks about trailing spaces when there's no project-specific YAML formatter configured, preferring to focus on functionality over cosmetic formatting issues.
Learnt from: Crunchyman-ralph
Repo: eyaltoledano/claude-task-master PR: 1105
File: scripts/modules/supported-models.json:242-254
Timestamp: 2025-08-08T11:33:15.297Z
Learning: Preference: In scripts/modules/supported-models.json, the "name" field is optional. For OpenAI entries (e.g., "gpt-5"), Crunchyman-ralph prefers omitting "name" when the id is explicit enough; avoid nitpicks requesting a "name" in such cases.
Learnt from: Crunchyman-ralph
Repo: eyaltoledano/claude-task-master PR: 1200
File: src/ai-providers/custom-sdk/grok-cli/language-model.js:96-100
Timestamp: 2025-09-19T16:06:42.182Z
Learning: The user Crunchyman-ralph prefers to keep environment variable names explicit (like GROK_CLI_API_KEY) rather than supporting multiple aliases, to avoid overlap and ensure clear separation between different CLI implementations.
Learnt from: Crunchyman-ralph
Repo: eyaltoledano/claude-task-master PR: 1178
File: packages/tm-core/src/subpath-exports.test.ts:6-9
Timestamp: 2025-09-03T12:45:30.724Z
Learning: The user Crunchyman-ralph prefers to avoid overly nitpicky or detailed suggestions in code reviews, especially for test coverage of minor import paths. Focus on more substantial issues rather than comprehensive coverage of all possible edge cases.
Learnt from: Crunchyman-ralph
Repo: eyaltoledano/claude-task-master PR: 1217
File: apps/cli/src/index.ts:16-21
Timestamp: 2025-09-18T16:35:35.147Z
Learning: The user Crunchyman-ralph considers suggestions to export types for better ergonomics (like exporting UpdateInfo type alongside related functions) as nitpicky and prefers not to implement such suggestions.
📚 Learning: 2025-09-26T19:03:33.225Z
Learnt from: Crunchyman-ralph
Repo: eyaltoledano/claude-task-master PR: 1252
File: package.json:130-132
Timestamp: 2025-09-26T19:03:33.225Z
Learning: In the eyaltoledano/claude-task-master repository, packages are bundled using tsdown during the build process, which means dependencies imported by the source code (including tm internal packages like tm/ai-sdk-provider-grok-cli) are included in the final bundle and don't need to be available as separate runtime dependencies, so they should remain as devDependencies rather than being moved to dependencies.
Applied to files:
package.jsonpackages/tm-core/package.json
📚 Learning: 2025-09-26T19:07:10.485Z
Learnt from: Crunchyman-ralph
Repo: eyaltoledano/claude-task-master PR: 1252
File: packages/ai-sdk-provider-grok-cli/package.json:21-35
Timestamp: 2025-09-26T19:07:10.485Z
Learning: In the eyaltoledano/claude-task-master repository, the tsdown build configuration uses `noExternal: [/^tm\//]` which means internal tm/ packages are bundled into the final output while external npm dependencies remain external and are resolved from the root package.json dependencies at runtime. This eliminates the need for peer dependencies in internal packages since the root package.json already provides the required external dependencies.
Applied to files:
packages/tm-core/package.json
📚 Learning: 2025-10-08T19:57:00.982Z
Learnt from: Crunchyman-ralph
Repo: eyaltoledano/claude-task-master PR: 1282
File: packages/tm-core/src/utils/index.ts:16-34
Timestamp: 2025-10-08T19:57:00.982Z
Learning: For the tm-core package in the eyaltoledano/claude-task-master repository, the team prefers a minimal, need-based export strategy in index files rather than exposing all internal utilities. Exports should only be added when functions are actually consumed by other packages in the monorepo.
Applied to files:
packages/tm-core/package.jsonpackages/tm-core/src/index.ts
📚 Learning: 2025-09-22T19:45:04.337Z
Learnt from: Crunchyman-ralph
Repo: eyaltoledano/claude-task-master PR: 1232
File: packages/tm-core/package.json:50-51
Timestamp: 2025-09-22T19:45:04.337Z
Learning: In the eyaltoledano/claude-task-master project, Crunchyman-ralph intentionally omits version fields from internal/private packages in package.json files to prevent changesets from releasing new versions of these packages while still allowing them to be processed for dependency updates. The changesets warnings about missing versions are acceptable as they don't break the process and achieve the desired behavior of only releasing public packages.
Applied to files:
packages/tm-core/package.json
📚 Learning: 2025-09-26T19:05:47.555Z
Learnt from: Crunchyman-ralph
Repo: eyaltoledano/claude-task-master PR: 1252
File: packages/ai-sdk-provider-grok-cli/package.json:11-13
Timestamp: 2025-09-26T19:05:47.555Z
Learning: In the eyaltoledano/claude-task-master repository, internal tm/ packages use a specific export pattern where the "exports" field points to TypeScript source files (./src/index.ts) while "main" points to compiled output (./dist/index.js) and "types" points to source files (./src/index.ts). This pattern is used consistently across internal packages like tm/core and tm/ai-sdk-provider-grok-cli because they are consumed directly during build-time bundling with tsdown rather than being published as separate packages.
Applied to files:
packages/tm-core/package.jsonpackages/tm-core/src/index.ts
📚 Learning: 2025-07-18T17:09:40.548Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/dependencies.mdc:0-0
Timestamp: 2025-07-18T17:09:40.548Z
Learning: Applies to scripts/modules/dependency-manager.js : Track and report changes made during dependency cleanup
Applied to files:
packages/tm-core/package.json
📚 Learning: 2025-09-26T19:10:32.906Z
Learnt from: Crunchyman-ralph
Repo: eyaltoledano/claude-task-master PR: 1252
File: tsconfig.json:22-28
Timestamp: 2025-09-26T19:10:32.906Z
Learning: In the eyaltoledano/claude-task-master repository, all internal tm/ package path mappings in tsconfig.json consistently point to TypeScript source files (e.g., "./packages/*/src/index.ts") rather than built JavaScript. This is intentional architecture because tsdown bundles internal packages directly from source during build time, eliminating the need for separate compilation of internal packages.
Applied to files:
packages/tm-core/package.json
🧬 Code graph analysis (1)
apps/cli/src/utils/brief-selection.ts (1)
packages/tm-core/src/utils/time.utils.ts (1)
formatRelativeTime(13-18)
⏰ 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 (5)
packages/tm-core/src/modules/auth/services/organization.service.ts (2)
6-6: LGTM: Type-only imports improve build optimization.Converting these to type-only imports is good practice for tree-shaking and cleaner builds.
Also applies to: 12-12
174-175: LGTM: Ordering ensures most recently updated briefs appear first.The descending order by
updated_ataligns well with the new relative time display feature, ensuring users see the most recently updated briefs at the top.packages/tm-core/package.json (1)
34-34: LGTM: Dependency added for time utilities.The date-fns dependency correctly supports the new
formatRelativeTimeutility.packages/tm-core/src/index.ts (1)
53-53: LGTM: Time utility properly exported.The new time utility export follows the project's minimal, need-based export strategy and is consumed by the CLI for brief selection.
Based on learnings
package.json (1)
86-86: No issues found.date-fns version 4.1.0 exists and no security vulnerabilities were detected in the npm registry or GitHub's security advisory database.
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (1)
apps/cli/src/utils/brief-selection.ts (1)
114-137: Consider extracting duplicate brief option building logic.The logic for building brief options (computing title, shortId, taskCountDisplay, updatedAtDisplay, and formatting the name) is duplicated in both the ordered and unordered status sections. Extracting this into a helper function would improve maintainability and reduce the risk of inconsistency.
Example helper function:
function buildBriefOption(brief: typeof briefs[0]) { const title = brief.document?.title || `Brief ${brief.id.slice(-8)}`; const shortId = brief.id.slice(-8); const description = brief.document?.description || ''; const taskCountDisplay = brief.taskCount !== undefined && brief.taskCount > 0 ? chalk.gray( ` (${brief.taskCount} ${brief.taskCount === 1 ? 'task' : 'tasks'})` ) : ''; const updatedAtDisplay = brief.updatedAt ? chalk.gray(` • ${formatRelativeTime(brief.updatedAt)}`) : ''; return { name: ` ${title}${taskCountDisplay} ${chalk.gray(`(${shortId})`)}${updatedAtDisplay}`, value: brief, description: description ? chalk.gray(` ${description.slice(0, 80)}`) : undefined }; }Then replace both duplicated sections with:
statusBriefs.forEach((brief) => { groupedOptions.push(buildBriefOption(brief)); });Also applies to: 154-177
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
apps/cli/src/utils/brief-selection.ts(3 hunks)
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: Crunchyman-ralph
Repo: eyaltoledano/claude-task-master PR: 1252
File: package.json:130-132
Timestamp: 2025-09-26T19:03:33.225Z
Learning: In the eyaltoledano/claude-task-master repository, packages are bundled using tsdown during the build process, which means dependencies imported by the source code (including tm internal packages like tm/ai-sdk-provider-grok-cli) are included in the final bundle and don't need to be available as separate runtime dependencies, so they should remain as devDependencies rather than being moved to dependencies.
Learnt from: Crunchyman-ralph
Repo: eyaltoledano/claude-task-master PR: 1178
File: packages/tm-core/src/auth/config.ts:5-7
Timestamp: 2025-09-02T21:51:27.921Z
Learning: The user Crunchyman-ralph prefers not to use node: scheme imports (e.g., 'node:os', 'node:path') for Node.js core modules and considers suggestions to change bare imports to node: scheme as too nitpicky.
Learnt from: Crunchyman-ralph
Repo: eyaltoledano/claude-task-master PR: 1069
File: .changeset/fix-tag-complexity-detection.md:0-0
Timestamp: 2025-08-02T15:33:22.656Z
Learning: For changeset files (.changeset/*.md), Crunchyman-ralph prefers to ignore formatting nitpicks about blank lines between frontmatter and descriptions, as he doesn't mind having them and wants to avoid such comments in future reviews.
Learnt from: Crunchyman-ralph
Repo: eyaltoledano/claude-task-master PR: 1132
File: .github/workflows/weekly-metrics-discord.yml:81-93
Timestamp: 2025-08-13T22:10:46.958Z
Learning: Crunchyman-ralph ignores YAML formatting nitpicks about trailing spaces when there's no project-specific YAML formatter configured, preferring to focus on functionality over cosmetic formatting issues.
Learnt from: Crunchyman-ralph
Repo: eyaltoledano/claude-task-master PR: 1132
File: .github/workflows/weekly-metrics-discord.yml:81-93
Timestamp: 2025-08-13T22:10:46.958Z
Learning: Crunchyman-ralph ignores YAML formatting nitpicks about trailing spaces when there's no project-specific YAML formatter configured, preferring to focus on functionality over cosmetic formatting issues.
Learnt from: Crunchyman-ralph
Repo: eyaltoledano/claude-task-master PR: 1105
File: scripts/modules/supported-models.json:242-254
Timestamp: 2025-08-08T11:33:15.297Z
Learning: Preference: In scripts/modules/supported-models.json, the "name" field is optional. For OpenAI entries (e.g., "gpt-5"), Crunchyman-ralph prefers omitting "name" when the id is explicit enough; avoid nitpicks requesting a "name" in such cases.
Learnt from: Crunchyman-ralph
Repo: eyaltoledano/claude-task-master PR: 1200
File: src/ai-providers/custom-sdk/grok-cli/language-model.js:96-100
Timestamp: 2025-09-19T16:06:42.182Z
Learning: The user Crunchyman-ralph prefers to keep environment variable names explicit (like GROK_CLI_API_KEY) rather than supporting multiple aliases, to avoid overlap and ensure clear separation between different CLI implementations.
Learnt from: Crunchyman-ralph
Repo: eyaltoledano/claude-task-master PR: 1178
File: packages/tm-core/src/subpath-exports.test.ts:6-9
Timestamp: 2025-09-03T12:45:30.724Z
Learning: The user Crunchyman-ralph prefers to avoid overly nitpicky or detailed suggestions in code reviews, especially for test coverage of minor import paths. Focus on more substantial issues rather than comprehensive coverage of all possible edge cases.
Learnt from: Crunchyman-ralph
Repo: eyaltoledano/claude-task-master PR: 1217
File: apps/cli/src/index.ts:16-21
Timestamp: 2025-09-18T16:35:35.147Z
Learning: The user Crunchyman-ralph considers suggestions to export types for better ergonomics (like exporting UpdateInfo type alongside related functions) as nitpicky and prefers not to implement such suggestions.
🧬 Code graph analysis (1)
apps/cli/src/utils/brief-selection.ts (1)
packages/tm-core/src/utils/time.utils.ts (1)
formatRelativeTime(13-18)
⏰ 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 (2)
apps/cli/src/utils/brief-selection.ts (2)
6-12: LGTM - Clean import improvements!The type-only imports for
AuthManagerandOraare appropriate, and the newformatRelativeTimeutility is correctly imported for the timestamp display feature.
126-128: Good implementation of relative time display!The conditional check for
brief.updatedAtprevents errors, and usingformatRelativeTimeprovides a user-friendly display. The styling withchalk.grayand the bullet separator maintains visual consistency with the rest of the UI.Also applies to: 166-168
What type of PR is this?
Description
Related Issues
How to Test This
# Example commands or stepsExpected result:
Contributor Checklist
npm run changesetnpm testnpm run format-check(ornpm run formatto fix)Changelog Entry
For Maintainers
Summary by CodeRabbit