mirror of
https://github.com/eyaltoledano/claude-task-master.git
synced 2026-01-30 06:12:05 +00:00
feat: sort briefs by updated at (#1409)
This commit is contained in:
@@ -3,12 +3,13 @@
|
||||
* Reusable functions for selecting briefs interactively or via URL/ID
|
||||
*/
|
||||
|
||||
import chalk from 'chalk';
|
||||
import search from '@inquirer/search';
|
||||
import ora, { Ora } from 'ora';
|
||||
import { AuthManager } from '@tm/core';
|
||||
import * as ui from './ui.js';
|
||||
import type { AuthManager } from '@tm/core';
|
||||
import { formatRelativeTime } from '@tm/core';
|
||||
import chalk from 'chalk';
|
||||
import ora, { type Ora } from 'ora';
|
||||
import { getBriefStatusWithColor } from '../ui/formatters/status-formatters.js';
|
||||
import * as ui from './ui.js';
|
||||
|
||||
export interface BriefSelectionResult {
|
||||
success: boolean;
|
||||
@@ -122,8 +123,12 @@ export async function selectBriefInteractive(
|
||||
)
|
||||
: '';
|
||||
|
||||
const updatedAtDisplay = brief.updatedAt
|
||||
? chalk.gray(` • ${formatRelativeTime(brief.updatedAt)}`)
|
||||
: '';
|
||||
|
||||
groupedOptions.push({
|
||||
name: ` ${title}${taskCountDisplay} ${chalk.gray(`(${shortId})`)}`,
|
||||
name: ` ${title}${taskCountDisplay} ${chalk.gray(`(${shortId})`)}${updatedAtDisplay}`,
|
||||
value: brief,
|
||||
description: description
|
||||
? chalk.gray(` ${description.slice(0, 80)}`)
|
||||
@@ -158,8 +163,12 @@ export async function selectBriefInteractive(
|
||||
)
|
||||
: '';
|
||||
|
||||
const updatedAtDisplay = brief.updatedAt
|
||||
? chalk.gray(` • ${formatRelativeTime(brief.updatedAt)}`)
|
||||
: '';
|
||||
|
||||
groupedOptions.push({
|
||||
name: ` ${title}${taskCountDisplay} ${chalk.gray(`(${shortId})`)}`,
|
||||
name: ` ${title}${taskCountDisplay} ${chalk.gray(`(${shortId})`)}${updatedAtDisplay}`,
|
||||
value: brief,
|
||||
description: description
|
||||
? chalk.gray(` ${description.slice(0, 80)}`)
|
||||
|
||||
12
package-lock.json
generated
12
package-lock.json
generated
@@ -45,6 +45,7 @@
|
||||
"cli-table3": "^0.6.5",
|
||||
"commander": "^12.1.0",
|
||||
"cors": "^2.8.5",
|
||||
"date-fns": "^4.1.0",
|
||||
"dotenv": "^16.6.1",
|
||||
"express": "^4.21.2",
|
||||
"fastmcp": "^3.23.0",
|
||||
@@ -13239,6 +13240,16 @@
|
||||
"dev": true,
|
||||
"license": "BSD-3-Clause"
|
||||
},
|
||||
"node_modules/date-fns": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-4.1.0.tgz",
|
||||
"integrity": "sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/kossnocorp"
|
||||
}
|
||||
},
|
||||
"node_modules/debug": {
|
||||
"version": "2.6.9",
|
||||
"license": "MIT",
|
||||
@@ -28729,6 +28740,7 @@
|
||||
"name": "@tm/core",
|
||||
"dependencies": {
|
||||
"@supabase/supabase-js": "^2.57.4",
|
||||
"date-fns": "^4.1.0",
|
||||
"fs-extra": "^11.3.2",
|
||||
"simple-git": "^3.28.0",
|
||||
"steno": "^4.0.2",
|
||||
|
||||
@@ -83,6 +83,7 @@
|
||||
"cli-table3": "^0.6.5",
|
||||
"commander": "^12.1.0",
|
||||
"cors": "^2.8.5",
|
||||
"date-fns": "^4.1.0",
|
||||
"dotenv": "^16.6.1",
|
||||
"express": "^4.21.2",
|
||||
"fastmcp": "^3.23.0",
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@supabase/supabase-js": "^2.57.4",
|
||||
"date-fns": "^4.1.0",
|
||||
"fs-extra": "^11.3.2",
|
||||
"simple-git": "^3.28.0",
|
||||
"steno": "^4.0.2",
|
||||
|
||||
@@ -50,6 +50,7 @@ export * from './common/errors/index.js';
|
||||
|
||||
// Utils
|
||||
export * from './common/utils/index.js';
|
||||
export * from './utils/time.utils.js';
|
||||
|
||||
// ========== Domain-Specific Type Exports ==========
|
||||
|
||||
|
||||
@@ -3,13 +3,13 @@
|
||||
* Handles fetching and managing organizations and briefs from the API
|
||||
*/
|
||||
|
||||
import { SupabaseClient } from '@supabase/supabase-js';
|
||||
import type { SupabaseClient } from '@supabase/supabase-js';
|
||||
import {
|
||||
ERROR_CODES,
|
||||
TaskMasterError
|
||||
} from '../../../common/errors/task-master-error.js';
|
||||
import { getLogger } from '../../../common/logger/index.js';
|
||||
import { Database } from '../../../common/types/database.types.js';
|
||||
import type { Database } from '../../../common/types/database.types.js';
|
||||
import type { Brief } from '../../briefs/types.js';
|
||||
|
||||
/**
|
||||
@@ -171,7 +171,8 @@ export class OrganizationService {
|
||||
title
|
||||
)
|
||||
`)
|
||||
.eq('account_id', orgId);
|
||||
.eq('account_id', orgId)
|
||||
.order('updated_at', { ascending: false });
|
||||
|
||||
if (error) {
|
||||
throw new TaskMasterError(
|
||||
|
||||
18
packages/tm-core/src/utils/time.utils.ts
Normal file
18
packages/tm-core/src/utils/time.utils.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
/**
|
||||
* @fileoverview Time utilities for formatting relative timestamps
|
||||
* Shared across CLI, MCP, extension, and other interfaces
|
||||
*/
|
||||
|
||||
import { formatDistanceToNow } from 'date-fns';
|
||||
|
||||
/**
|
||||
* Format a date as relative time from now (e.g., "2 hours ago", "3 days ago")
|
||||
* @param date - Date string or Date object to format
|
||||
* @returns Relative time string (e.g., "less than a minute ago", "5 minutes ago", "2 weeks ago")
|
||||
*/
|
||||
export function formatRelativeTime(date: string | Date): string {
|
||||
const dateObj = typeof date === 'string' ? new Date(date) : date;
|
||||
|
||||
// Use date-fns for robust formatting with proper edge case handling
|
||||
return formatDistanceToNow(dateObj, { addSuffix: true });
|
||||
}
|
||||
Reference in New Issue
Block a user