prjct-cli 0.18.2 → 0.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +82 -0
- package/CLAUDE.md +74 -211
- package/core/agentic/prompt-builder.ts +3 -7
- package/core/command-registry/optional-commands.ts +0 -20
- package/core/infrastructure/command-installer/command-installer.ts +8 -1
- package/core/infrastructure/command-installer/global-config.ts +31 -1
- package/core/infrastructure/command-installer/index.ts +1 -1
- package/core/infrastructure/setup.ts +3 -0
- package/package.json +3 -17
- package/templates/agentic/agents/uxui.md +210 -0
- package/templates/commands/bug.md +219 -41
- package/templates/commands/done.md +57 -258
- package/templates/commands/feature.md +368 -80
- package/templates/commands/now.md +72 -277
- package/templates/commands/ship.md +167 -246
- package/templates/commands/sync.md +62 -3
- package/templates/commands/test.md +160 -20
- package/templates/global/CLAUDE.md +40 -205
- package/templates/global/docs/agents.md +88 -0
- package/templates/global/docs/architecture.md +103 -0
- package/templates/global/docs/commands.md +98 -0
- package/templates/global/docs/validation.md +95 -0
- package/bin/dev.js +0 -216
- package/bin/serve.js +0 -361
- package/packages/web/README.md +0 -36
- package/packages/web/app/api/claude/sessions/route.ts +0 -44
- package/packages/web/app/api/claude/status/route.ts +0 -34
- package/packages/web/app/api/projects/[id]/icon/route.ts +0 -33
- package/packages/web/app/api/projects/[id]/momentum/route.ts +0 -257
- package/packages/web/app/api/projects/[id]/route.ts +0 -29
- package/packages/web/app/api/projects/[id]/stats/route.ts +0 -41
- package/packages/web/app/api/projects/[id]/status/route.ts +0 -21
- package/packages/web/app/api/projects/route.ts +0 -16
- package/packages/web/app/api/sessions/current/route.ts +0 -132
- package/packages/web/app/api/sessions/history/route.ts +0 -204
- package/packages/web/app/error.tsx +0 -34
- package/packages/web/app/favicon.ico +0 -0
- package/packages/web/app/globals.css +0 -198
- package/packages/web/app/layout.tsx +0 -53
- package/packages/web/app/loading.tsx +0 -7
- package/packages/web/app/not-found.tsx +0 -25
- package/packages/web/app/page.tsx +0 -12
- package/packages/web/app/project/[id]/code/layout.tsx +0 -18
- package/packages/web/app/project/[id]/code/page.tsx +0 -408
- package/packages/web/app/project/[id]/error.tsx +0 -41
- package/packages/web/app/project/[id]/loading.tsx +0 -9
- package/packages/web/app/project/[id]/not-found.tsx +0 -27
- package/packages/web/app/project/[id]/page.tsx +0 -384
- package/packages/web/app/project/[id]/reports/page.tsx +0 -59
- package/packages/web/app/project/[id]/reports/print/page.tsx +0 -58
- package/packages/web/app/sessions/page.tsx +0 -165
- package/packages/web/app/settings/page.tsx +0 -151
- package/packages/web/components/ActivityTimeline/ActivityTimeline.constants.ts +0 -2
- package/packages/web/components/ActivityTimeline/ActivityTimeline.tsx +0 -49
- package/packages/web/components/ActivityTimeline/ActivityTimeline.types.ts +0 -8
- package/packages/web/components/ActivityTimeline/hooks/index.ts +0 -2
- package/packages/web/components/ActivityTimeline/hooks/useExpandable.ts +0 -9
- package/packages/web/components/ActivityTimeline/hooks/useGroupedEvents.ts +0 -23
- package/packages/web/components/ActivityTimeline/index.ts +0 -2
- package/packages/web/components/AgentsCard/AgentsCard.tsx +0 -93
- package/packages/web/components/AgentsCard/AgentsCard.types.ts +0 -14
- package/packages/web/components/AgentsCard/index.ts +0 -2
- package/packages/web/components/AppSidebar/AppSidebar.tsx +0 -316
- package/packages/web/components/AppSidebar/index.ts +0 -1
- package/packages/web/components/BackLink/BackLink.tsx +0 -18
- package/packages/web/components/BackLink/BackLink.types.ts +0 -5
- package/packages/web/components/BackLink/index.ts +0 -2
- package/packages/web/components/BentoCard/BentoCard.constants.ts +0 -16
- package/packages/web/components/BentoCard/BentoCard.tsx +0 -48
- package/packages/web/components/BentoCard/BentoCard.types.ts +0 -15
- package/packages/web/components/BentoCard/index.ts +0 -2
- package/packages/web/components/BentoCardSkeleton/BentoCardSkeleton.constants.ts +0 -9
- package/packages/web/components/BentoCardSkeleton/BentoCardSkeleton.tsx +0 -18
- package/packages/web/components/BentoCardSkeleton/BentoCardSkeleton.types.ts +0 -5
- package/packages/web/components/BentoCardSkeleton/index.ts +0 -2
- package/packages/web/components/BentoGrid/BentoGrid.tsx +0 -18
- package/packages/web/components/BentoGrid/BentoGrid.types.ts +0 -4
- package/packages/web/components/BentoGrid/index.ts +0 -2
- package/packages/web/components/BlockersCard/BlockersCard.tsx +0 -75
- package/packages/web/components/BlockersCard/BlockersCard.types.ts +0 -12
- package/packages/web/components/BlockersCard/index.ts +0 -2
- package/packages/web/components/CommandBar/CommandBar.tsx +0 -67
- package/packages/web/components/CommandBar/index.ts +0 -1
- package/packages/web/components/CommandButton/CommandButton.tsx +0 -46
- package/packages/web/components/CommandButton/index.ts +0 -1
- package/packages/web/components/ConnectionStatus/ConnectionStatus.tsx +0 -29
- package/packages/web/components/ConnectionStatus/index.ts +0 -1
- package/packages/web/components/DashboardContent/DashboardContent.tsx +0 -284
- package/packages/web/components/DashboardContent/index.ts +0 -1
- package/packages/web/components/DateGroup/DateGroup.tsx +0 -18
- package/packages/web/components/DateGroup/DateGroup.types.ts +0 -6
- package/packages/web/components/DateGroup/DateGroup.utils.ts +0 -11
- package/packages/web/components/DateGroup/index.ts +0 -2
- package/packages/web/components/EmptyState/EmptyState.tsx +0 -76
- package/packages/web/components/EmptyState/EmptyState.types.ts +0 -11
- package/packages/web/components/EmptyState/index.ts +0 -2
- package/packages/web/components/EventRow/EventRow.constants.ts +0 -10
- package/packages/web/components/EventRow/EventRow.tsx +0 -49
- package/packages/web/components/EventRow/EventRow.types.ts +0 -7
- package/packages/web/components/EventRow/EventRow.utils.ts +0 -49
- package/packages/web/components/EventRow/index.ts +0 -2
- package/packages/web/components/ExpandButton/ExpandButton.tsx +0 -18
- package/packages/web/components/ExpandButton/ExpandButton.types.ts +0 -6
- package/packages/web/components/ExpandButton/index.ts +0 -2
- package/packages/web/components/HealthGradientBackground/HealthGradientBackground.tsx +0 -14
- package/packages/web/components/HealthGradientBackground/HealthGradientBackground.types.ts +0 -5
- package/packages/web/components/HealthGradientBackground/HealthGradientBackground.utils.ts +0 -13
- package/packages/web/components/HealthGradientBackground/index.ts +0 -2
- package/packages/web/components/HeroSection/HeroSection.tsx +0 -92
- package/packages/web/components/HeroSection/HeroSection.types.ts +0 -14
- package/packages/web/components/HeroSection/HeroSection.utils.ts +0 -11
- package/packages/web/components/HeroSection/hooks/index.ts +0 -2
- package/packages/web/components/HeroSection/hooks/useCountUp.ts +0 -45
- package/packages/web/components/HeroSection/hooks/useWeeklyActivity.ts +0 -18
- package/packages/web/components/HeroSection/index.ts +0 -2
- package/packages/web/components/IdeasCard/IdeasCard.tsx +0 -115
- package/packages/web/components/IdeasCard/IdeasCard.types.ts +0 -10
- package/packages/web/components/IdeasCard/index.ts +0 -2
- package/packages/web/components/InsightMessage/InsightMessage.tsx +0 -9
- package/packages/web/components/InsightMessage/InsightMessage.types.ts +0 -3
- package/packages/web/components/InsightMessage/index.ts +0 -2
- package/packages/web/components/Logo/Logo.tsx +0 -65
- package/packages/web/components/Logo/index.ts +0 -1
- package/packages/web/components/MarkdownContent/MarkdownContent.tsx +0 -123
- package/packages/web/components/MarkdownContent/index.ts +0 -1
- package/packages/web/components/MasonryGrid/MasonryGrid.tsx +0 -18
- package/packages/web/components/MasonryGrid/index.ts +0 -1
- package/packages/web/components/MomentumWidget/MomentumWidget.tsx +0 -119
- package/packages/web/components/MomentumWidget/MomentumWidget.types.ts +0 -16
- package/packages/web/components/MomentumWidget/index.ts +0 -2
- package/packages/web/components/NowCard/NowCard.tsx +0 -118
- package/packages/web/components/NowCard/NowCard.types.ts +0 -16
- package/packages/web/components/NowCard/index.ts +0 -2
- package/packages/web/components/PageHeader/PageHeader.tsx +0 -24
- package/packages/web/components/PageHeader/index.ts +0 -1
- package/packages/web/components/ProgressRing/ProgressRing.constants.ts +0 -20
- package/packages/web/components/ProgressRing/ProgressRing.tsx +0 -51
- package/packages/web/components/ProgressRing/ProgressRing.types.ts +0 -11
- package/packages/web/components/ProgressRing/index.ts +0 -2
- package/packages/web/components/ProjectAvatar/ProjectAvatar.tsx +0 -54
- package/packages/web/components/ProjectAvatar/index.ts +0 -1
- package/packages/web/components/ProjectColorDot/ProjectColorDot.tsx +0 -37
- package/packages/web/components/ProjectColorDot/index.ts +0 -1
- package/packages/web/components/ProjectSelectorModal/ProjectSelectorModal.tsx +0 -104
- package/packages/web/components/ProjectSelectorModal/index.ts +0 -1
- package/packages/web/components/Providers/Providers.tsx +0 -48
- package/packages/web/components/Providers/index.ts +0 -1
- package/packages/web/components/QueueCard/QueueCard.tsx +0 -125
- package/packages/web/components/QueueCard/QueueCard.types.ts +0 -12
- package/packages/web/components/QueueCard/QueueCard.utils.ts +0 -12
- package/packages/web/components/QueueCard/index.ts +0 -2
- package/packages/web/components/RecoverCard/RecoverCard.tsx +0 -72
- package/packages/web/components/RecoverCard/RecoverCard.types.ts +0 -16
- package/packages/web/components/RecoverCard/index.ts +0 -2
- package/packages/web/components/RoadmapCard/RoadmapCard.tsx +0 -145
- package/packages/web/components/RoadmapCard/RoadmapCard.types.ts +0 -16
- package/packages/web/components/RoadmapCard/index.ts +0 -2
- package/packages/web/components/ShipsCard/ShipsCard.tsx +0 -95
- package/packages/web/components/ShipsCard/ShipsCard.types.ts +0 -14
- package/packages/web/components/ShipsCard/ShipsCard.utils.ts +0 -4
- package/packages/web/components/ShipsCard/index.ts +0 -2
- package/packages/web/components/SparklineChart/SparklineChart.tsx +0 -40
- package/packages/web/components/SparklineChart/SparklineChart.types.ts +0 -6
- package/packages/web/components/SparklineChart/index.ts +0 -2
- package/packages/web/components/StatsMasonry/StatsMasonry.tsx +0 -95
- package/packages/web/components/StatsMasonry/index.ts +0 -1
- package/packages/web/components/StreakCard/StreakCard.constants.ts +0 -2
- package/packages/web/components/StreakCard/StreakCard.tsx +0 -55
- package/packages/web/components/StreakCard/StreakCard.types.ts +0 -4
- package/packages/web/components/StreakCard/index.ts +0 -2
- package/packages/web/components/TasksCounter/TasksCounter.tsx +0 -14
- package/packages/web/components/TasksCounter/TasksCounter.types.ts +0 -3
- package/packages/web/components/TasksCounter/index.ts +0 -2
- package/packages/web/components/TechStackBadges/TechStackBadges.tsx +0 -28
- package/packages/web/components/TechStackBadges/index.ts +0 -1
- package/packages/web/components/TerminalDock/DockToggleTab.tsx +0 -29
- package/packages/web/components/TerminalDock/TerminalDock.tsx +0 -386
- package/packages/web/components/TerminalDock/TerminalDockTab.tsx +0 -130
- package/packages/web/components/TerminalDock/TerminalTabBar.tsx +0 -142
- package/packages/web/components/TerminalDock/index.ts +0 -2
- package/packages/web/components/TerminalTabs/TerminalTab.tsx +0 -95
- package/packages/web/components/TerminalTabs/TerminalTabs.tsx +0 -211
- package/packages/web/components/TerminalTabs/index.ts +0 -1
- package/packages/web/components/VelocityBadge/VelocityBadge.tsx +0 -32
- package/packages/web/components/VelocityBadge/VelocityBadge.types.ts +0 -3
- package/packages/web/components/VelocityBadge/index.ts +0 -2
- package/packages/web/components/VelocityCard/VelocityCard.tsx +0 -73
- package/packages/web/components/VelocityCard/VelocityCard.types.ts +0 -7
- package/packages/web/components/VelocityCard/index.ts +0 -2
- package/packages/web/components/WeeklyReports/PrintableReport.tsx +0 -259
- package/packages/web/components/WeeklyReports/ReportPreviewCard.tsx +0 -187
- package/packages/web/components/WeeklyReports/WeekCalendar.tsx +0 -288
- package/packages/web/components/WeeklyReports/WeeklyReports.tsx +0 -149
- package/packages/web/components/WeeklyReports/index.ts +0 -4
- package/packages/web/components/WeeklySparkline/WeeklySparkline.tsx +0 -25
- package/packages/web/components/WeeklySparkline/WeeklySparkline.types.ts +0 -4
- package/packages/web/components/WeeklySparkline/index.ts +0 -2
- package/packages/web/components/charts/SessionsChart.tsx +0 -175
- package/packages/web/components/ui/alert-dialog.tsx +0 -157
- package/packages/web/components/ui/badge.tsx +0 -46
- package/packages/web/components/ui/button.tsx +0 -60
- package/packages/web/components/ui/card.tsx +0 -92
- package/packages/web/components/ui/chart.tsx +0 -385
- package/packages/web/components/ui/dialog.tsx +0 -143
- package/packages/web/components/ui/drawer.tsx +0 -135
- package/packages/web/components/ui/dropdown-menu.tsx +0 -257
- package/packages/web/components/ui/input.tsx +0 -21
- package/packages/web/components/ui/scroll-area.tsx +0 -58
- package/packages/web/components/ui/select.tsx +0 -187
- package/packages/web/components/ui/sheet.tsx +0 -139
- package/packages/web/components/ui/tabs.tsx +0 -66
- package/packages/web/components/ui/tooltip.tsx +0 -61
- package/packages/web/components.json +0 -22
- package/packages/web/context/GlobalTerminalContext.tsx +0 -538
- package/packages/web/context/TerminalContext.tsx +0 -45
- package/packages/web/context/TerminalTabsContext.tsx +0 -181
- package/packages/web/eslint.config.mjs +0 -18
- package/packages/web/hooks/useClaudeTerminal.ts +0 -425
- package/packages/web/hooks/useProjectStats.ts +0 -93
- package/packages/web/hooks/useProjects.ts +0 -73
- package/packages/web/lib/actions/projects.ts +0 -15
- package/packages/web/lib/commands.ts +0 -81
- package/packages/web/lib/format.ts +0 -23
- package/packages/web/lib/generate-week-report.ts +0 -285
- package/packages/web/lib/parse-prjct-files.ts +0 -1123
- package/packages/web/lib/project-colors.ts +0 -58
- package/packages/web/lib/projects.ts +0 -506
- package/packages/web/lib/pty.ts +0 -101
- package/packages/web/lib/query-config.ts +0 -44
- package/packages/web/lib/services/index.ts +0 -9
- package/packages/web/lib/services/projects.server.ts +0 -66
- package/packages/web/lib/services/stats.server.ts +0 -562
- package/packages/web/lib/unified-loader.ts +0 -396
- package/packages/web/lib/utils.ts +0 -6
- package/packages/web/next-env.d.ts +0 -6
- package/packages/web/next.config.ts +0 -7
- package/packages/web/package.json +0 -57
- package/packages/web/postcss.config.mjs +0 -7
- package/packages/web/public/file.svg +0 -1
- package/packages/web/public/globe.svg +0 -1
- package/packages/web/public/next.svg +0 -1
- package/packages/web/public/vercel.svg +0 -1
- package/packages/web/public/window.svg +0 -1
- package/packages/web/server.ts +0 -312
- package/packages/web/tsconfig.json +0 -34
- package/templates/commands/serve.md +0 -121
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
export type MomentumStatus = 'hot' | 'active' | 'cooling' | 'cold'
|
|
2
|
-
|
|
3
|
-
export interface MomentumData {
|
|
4
|
-
dailyTasks: number[]
|
|
5
|
-
totalTasks: number
|
|
6
|
-
totalShips: number
|
|
7
|
-
lastActivityDate: string | null
|
|
8
|
-
daysSinceActivity: number
|
|
9
|
-
streak: number
|
|
10
|
-
status: MomentumStatus
|
|
11
|
-
message: string
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export interface MomentumWidgetProps {
|
|
15
|
-
projectId: string
|
|
16
|
-
}
|
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
'use client'
|
|
2
|
-
|
|
3
|
-
import Link from 'next/link'
|
|
4
|
-
import { EmptyState } from '@/components/EmptyState'
|
|
5
|
-
import { Target, Clock, Bot, Pause, Play, CheckCircle2 } from 'lucide-react'
|
|
6
|
-
import { cn } from '@/lib/utils'
|
|
7
|
-
import type { NowCardProps } from './NowCard.types'
|
|
8
|
-
|
|
9
|
-
export function NowCard({ currentTask, codeHref, className }: NowCardProps) {
|
|
10
|
-
return (
|
|
11
|
-
<div className={cn(
|
|
12
|
-
'relative overflow-hidden rounded-xl border bg-card p-4',
|
|
13
|
-
className
|
|
14
|
-
)}>
|
|
15
|
-
<div className="flex items-center justify-between mb-3">
|
|
16
|
-
<div className="flex items-center gap-2">
|
|
17
|
-
<Target className="h-4 w-4 text-muted-foreground" />
|
|
18
|
-
<span className="text-xs font-bold uppercase tracking-[0.15em] text-muted-foreground">
|
|
19
|
-
Now
|
|
20
|
-
</span>
|
|
21
|
-
</div>
|
|
22
|
-
{currentTask && (
|
|
23
|
-
<div className="flex items-center gap-2">
|
|
24
|
-
{currentTask.pausedAt ? (
|
|
25
|
-
<span className="inline-flex items-center gap-1 text-xs font-semibold text-muted-foreground bg-muted px-2 py-0.5 rounded-full">
|
|
26
|
-
<Pause className="w-2.5 h-2.5" />
|
|
27
|
-
Paused
|
|
28
|
-
</span>
|
|
29
|
-
) : (
|
|
30
|
-
<span className="inline-flex items-center gap-1 text-xs font-semibold text-foreground bg-muted px-2 py-0.5 rounded-full">
|
|
31
|
-
<Play className="w-2.5 h-2.5 fill-current" />
|
|
32
|
-
Working
|
|
33
|
-
</span>
|
|
34
|
-
)}
|
|
35
|
-
</div>
|
|
36
|
-
)}
|
|
37
|
-
</div>
|
|
38
|
-
|
|
39
|
-
{currentTask ? (
|
|
40
|
-
<div className="space-y-3">
|
|
41
|
-
<p className="text-sm font-medium leading-tight break-words">
|
|
42
|
-
{currentTask.task}
|
|
43
|
-
</p>
|
|
44
|
-
|
|
45
|
-
<div className="flex flex-wrap items-center gap-3">
|
|
46
|
-
{currentTask.agent && (
|
|
47
|
-
<div className="inline-flex items-center gap-1.5 text-xs text-muted-foreground bg-muted/50 px-2 py-1 rounded">
|
|
48
|
-
<Bot className="h-3 w-3" />
|
|
49
|
-
<span className="font-mono">{currentTask.agent}</span>
|
|
50
|
-
</div>
|
|
51
|
-
)}
|
|
52
|
-
|
|
53
|
-
{currentTask.startedAt && (
|
|
54
|
-
<div className="inline-flex items-center gap-1.5 text-xs text-muted-foreground">
|
|
55
|
-
<Clock className="h-3 w-3" />
|
|
56
|
-
<span>Started {new Date(currentTask.startedAt).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}</span>
|
|
57
|
-
</div>
|
|
58
|
-
)}
|
|
59
|
-
|
|
60
|
-
{currentTask.estimatedDuration && (
|
|
61
|
-
<span className="text-xs text-muted-foreground">
|
|
62
|
-
Est. {currentTask.estimatedDuration}
|
|
63
|
-
</span>
|
|
64
|
-
)}
|
|
65
|
-
</div>
|
|
66
|
-
|
|
67
|
-
{/* Progress indicator */}
|
|
68
|
-
<div className="pt-1">
|
|
69
|
-
<div className="h-1.5 bg-muted rounded-full overflow-hidden">
|
|
70
|
-
<div
|
|
71
|
-
className="h-full rounded-full transition-all duration-300 bg-foreground"
|
|
72
|
-
style={{ width: currentTask.pausedAt ? '30%' : '60%' }}
|
|
73
|
-
/>
|
|
74
|
-
</div>
|
|
75
|
-
</div>
|
|
76
|
-
|
|
77
|
-
{/* Action buttons */}
|
|
78
|
-
{codeHref && (
|
|
79
|
-
<div className="flex gap-2 pt-2">
|
|
80
|
-
<Link
|
|
81
|
-
href={`${codeHref}?cmd=p.%20done`}
|
|
82
|
-
className="flex-1 flex items-center justify-center gap-1.5 text-xs font-medium px-3 py-2 rounded-lg bg-muted text-foreground hover:bg-muted/80 transition-colors"
|
|
83
|
-
>
|
|
84
|
-
<CheckCircle2 className="h-3.5 w-3.5" />
|
|
85
|
-
Done
|
|
86
|
-
</Link>
|
|
87
|
-
{currentTask.pausedAt ? (
|
|
88
|
-
<Link
|
|
89
|
-
href={`${codeHref}?cmd=p.%20resume`}
|
|
90
|
-
className="flex-1 flex items-center justify-center gap-1.5 text-xs font-medium px-3 py-2 rounded-lg bg-muted text-foreground hover:bg-muted/80 transition-colors"
|
|
91
|
-
>
|
|
92
|
-
<Play className="h-3.5 w-3.5" />
|
|
93
|
-
Resume
|
|
94
|
-
</Link>
|
|
95
|
-
) : (
|
|
96
|
-
<Link
|
|
97
|
-
href={`${codeHref}?cmd=p.%20pause`}
|
|
98
|
-
className="flex-1 flex items-center justify-center gap-1.5 text-xs font-medium px-3 py-2 rounded-lg bg-muted text-foreground hover:bg-muted/80 transition-colors"
|
|
99
|
-
>
|
|
100
|
-
<Pause className="h-3.5 w-3.5" />
|
|
101
|
-
Pause
|
|
102
|
-
</Link>
|
|
103
|
-
)}
|
|
104
|
-
</div>
|
|
105
|
-
)}
|
|
106
|
-
</div>
|
|
107
|
-
) : (
|
|
108
|
-
<EmptyState
|
|
109
|
-
icon={Target}
|
|
110
|
-
title="No active task"
|
|
111
|
-
description="Start working on something"
|
|
112
|
-
command="/p:now"
|
|
113
|
-
href={codeHref}
|
|
114
|
-
/>
|
|
115
|
-
)}
|
|
116
|
-
</div>
|
|
117
|
-
)
|
|
118
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
export interface CurrentTask {
|
|
2
|
-
task: string
|
|
3
|
-
startedAt?: string
|
|
4
|
-
agent?: string
|
|
5
|
-
agentConfidence?: number
|
|
6
|
-
estimatedDuration?: string
|
|
7
|
-
pausedAt?: string
|
|
8
|
-
pauseReason?: string
|
|
9
|
-
duration?: string
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export interface NowCardProps {
|
|
13
|
-
currentTask: CurrentTask | null
|
|
14
|
-
codeHref?: string
|
|
15
|
-
className?: string
|
|
16
|
-
}
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { getProjectBgClass } from '@/lib/project-colors'
|
|
2
|
-
|
|
3
|
-
interface PageHeaderProps {
|
|
4
|
-
projectId: string
|
|
5
|
-
projectName: string
|
|
6
|
-
section?: string
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export function PageHeader({ projectId, projectName, section }: PageHeaderProps) {
|
|
10
|
-
const colorBg = getProjectBgClass(projectId)
|
|
11
|
-
|
|
12
|
-
return (
|
|
13
|
-
<div className="flex items-center gap-3 mb-6">
|
|
14
|
-
<div className={`w-3 h-3 rounded-full shrink-0 ${colorBg}`} />
|
|
15
|
-
<h1 className="text-2xl font-semibold">{projectName}</h1>
|
|
16
|
-
{section && (
|
|
17
|
-
<>
|
|
18
|
-
<span className="text-muted-foreground/50">/</span>
|
|
19
|
-
<span className="text-xl text-muted-foreground">{section}</span>
|
|
20
|
-
</>
|
|
21
|
-
)}
|
|
22
|
-
</div>
|
|
23
|
-
)
|
|
24
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { PageHeader } from './PageHeader'
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import type { ProgressRingSize, AccentColor } from './ProgressRing.types'
|
|
2
|
-
|
|
3
|
-
export const PROGRESS_RING_SIZES: Record<ProgressRingSize, {
|
|
4
|
-
container: string
|
|
5
|
-
text: string
|
|
6
|
-
viewBox: number
|
|
7
|
-
radius: number
|
|
8
|
-
}> = {
|
|
9
|
-
sm: { container: 'h-8 w-8', text: 'text-xs', viewBox: 36, radius: 14 },
|
|
10
|
-
md: { container: 'h-12 w-12', text: 'text-xs', viewBox: 36, radius: 14 },
|
|
11
|
-
lg: { container: 'h-16 w-16', text: 'text-sm', viewBox: 36, radius: 14 },
|
|
12
|
-
xl: { container: 'h-20 w-20', text: 'text-base', viewBox: 36, radius: 14 },
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export const PROGRESS_RING_COLOR_STYLES: Record<AccentColor, string> = {
|
|
16
|
-
default: 'text-foreground',
|
|
17
|
-
success: 'text-emerald-500',
|
|
18
|
-
warning: 'text-amber-500',
|
|
19
|
-
destructive: 'text-red-500',
|
|
20
|
-
}
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
'use client'
|
|
2
|
-
|
|
3
|
-
import { cn } from '@/lib/utils'
|
|
4
|
-
import { PROGRESS_RING_SIZES, PROGRESS_RING_COLOR_STYLES } from './ProgressRing.constants'
|
|
5
|
-
import type { ProgressRingProps } from './ProgressRing.types'
|
|
6
|
-
|
|
7
|
-
export function ProgressRing({
|
|
8
|
-
value,
|
|
9
|
-
size = 'md',
|
|
10
|
-
showValue = true,
|
|
11
|
-
strokeWidth = 3,
|
|
12
|
-
className,
|
|
13
|
-
accentColor = 'default',
|
|
14
|
-
}: ProgressRingProps) {
|
|
15
|
-
const { container, text, viewBox, radius } = PROGRESS_RING_SIZES[size]
|
|
16
|
-
const circumference = 2 * Math.PI * radius
|
|
17
|
-
const strokeDashoffset = circumference - (value / 100) * circumference
|
|
18
|
-
|
|
19
|
-
return (
|
|
20
|
-
<div className={cn('relative', container, className)}>
|
|
21
|
-
<svg className="h-full w-full -rotate-90" viewBox={`0 0 ${viewBox} ${viewBox}`}>
|
|
22
|
-
<circle
|
|
23
|
-
cx={viewBox / 2}
|
|
24
|
-
cy={viewBox / 2}
|
|
25
|
-
r={radius}
|
|
26
|
-
fill="none"
|
|
27
|
-
stroke="currentColor"
|
|
28
|
-
strokeWidth={strokeWidth}
|
|
29
|
-
className="text-foreground/10"
|
|
30
|
-
/>
|
|
31
|
-
<circle
|
|
32
|
-
cx={viewBox / 2}
|
|
33
|
-
cy={viewBox / 2}
|
|
34
|
-
r={radius}
|
|
35
|
-
fill="none"
|
|
36
|
-
stroke="currentColor"
|
|
37
|
-
strokeWidth={strokeWidth}
|
|
38
|
-
strokeDasharray={circumference}
|
|
39
|
-
strokeDashoffset={strokeDashoffset}
|
|
40
|
-
strokeLinecap="round"
|
|
41
|
-
className={cn('transition-all duration-700 ease-out', PROGRESS_RING_COLOR_STYLES[accentColor])}
|
|
42
|
-
/>
|
|
43
|
-
</svg>
|
|
44
|
-
{showValue && (
|
|
45
|
-
<span className={cn('absolute inset-0 flex items-center justify-center font-bold tabular-nums', text)}>
|
|
46
|
-
{value}
|
|
47
|
-
</span>
|
|
48
|
-
)}
|
|
49
|
-
</div>
|
|
50
|
-
)
|
|
51
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
export type ProgressRingSize = 'sm' | 'md' | 'lg' | 'xl'
|
|
2
|
-
export type AccentColor = 'default' | 'success' | 'warning' | 'destructive'
|
|
3
|
-
|
|
4
|
-
export interface ProgressRingProps {
|
|
5
|
-
value: number
|
|
6
|
-
size?: ProgressRingSize
|
|
7
|
-
showValue?: boolean
|
|
8
|
-
strokeWidth?: number
|
|
9
|
-
className?: string
|
|
10
|
-
accentColor?: AccentColor
|
|
11
|
-
}
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
'use client'
|
|
2
|
-
|
|
3
|
-
import { cn } from '@/lib/utils'
|
|
4
|
-
|
|
5
|
-
interface ProjectAvatarProps {
|
|
6
|
-
projectId: string
|
|
7
|
-
name: string
|
|
8
|
-
iconPath?: string | null
|
|
9
|
-
size?: 'sm' | 'md' | 'lg'
|
|
10
|
-
className?: string
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
const sizeClasses = {
|
|
14
|
-
sm: 'w-8 h-8 text-xs',
|
|
15
|
-
md: 'w-9 h-9 text-sm',
|
|
16
|
-
lg: 'w-10 h-10 text-sm'
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export function ProjectAvatar({
|
|
20
|
-
projectId,
|
|
21
|
-
name,
|
|
22
|
-
iconPath,
|
|
23
|
-
size = 'md',
|
|
24
|
-
className
|
|
25
|
-
}: ProjectAvatarProps) {
|
|
26
|
-
const initials = name.slice(0, 2).toUpperCase()
|
|
27
|
-
|
|
28
|
-
return (
|
|
29
|
-
<div
|
|
30
|
-
className={cn(
|
|
31
|
-
'rounded-lg flex items-center justify-center overflow-hidden shrink-0 bg-muted border border-border',
|
|
32
|
-
sizeClasses[size],
|
|
33
|
-
className
|
|
34
|
-
)}
|
|
35
|
-
>
|
|
36
|
-
{iconPath ? (
|
|
37
|
-
<img
|
|
38
|
-
src={`/api/projects/${projectId}/icon`}
|
|
39
|
-
alt=""
|
|
40
|
-
className="w-full h-full object-cover"
|
|
41
|
-
onError={(e) => {
|
|
42
|
-
e.currentTarget.style.display = 'none'
|
|
43
|
-
if (e.currentTarget.nextElementSibling) {
|
|
44
|
-
(e.currentTarget.nextElementSibling as HTMLElement).classList.remove('hidden')
|
|
45
|
-
}
|
|
46
|
-
}}
|
|
47
|
-
/>
|
|
48
|
-
) : null}
|
|
49
|
-
<span className={cn('font-medium text-muted-foreground', iconPath ? 'hidden' : '')}>
|
|
50
|
-
{initials}
|
|
51
|
-
</span>
|
|
52
|
-
</div>
|
|
53
|
-
)
|
|
54
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { ProjectAvatar } from './ProjectAvatar'
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
'use client'
|
|
2
|
-
|
|
3
|
-
import { cn } from '@/lib/utils'
|
|
4
|
-
import { getProjectColor } from '@/lib/project-colors'
|
|
5
|
-
|
|
6
|
-
interface ProjectColorDotProps {
|
|
7
|
-
projectId: string
|
|
8
|
-
size?: 'sm' | 'md' | 'lg' | 'xl'
|
|
9
|
-
className?: string
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
const sizeClasses = {
|
|
13
|
-
sm: 'w-2 h-2',
|
|
14
|
-
md: 'w-3 h-3',
|
|
15
|
-
lg: 'w-4 h-4',
|
|
16
|
-
xl: 'w-5 h-5',
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export function ProjectColorDot({
|
|
20
|
-
projectId,
|
|
21
|
-
size = 'md',
|
|
22
|
-
className
|
|
23
|
-
}: ProjectColorDotProps) {
|
|
24
|
-
const color = getProjectColor(projectId)
|
|
25
|
-
|
|
26
|
-
return (
|
|
27
|
-
<div
|
|
28
|
-
className={cn(
|
|
29
|
-
'rounded-full shrink-0',
|
|
30
|
-
sizeClasses[size],
|
|
31
|
-
color.bg,
|
|
32
|
-
className
|
|
33
|
-
)}
|
|
34
|
-
aria-hidden="true"
|
|
35
|
-
/>
|
|
36
|
-
)
|
|
37
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { ProjectColorDot } from './ProjectColorDot'
|
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
'use client'
|
|
2
|
-
|
|
3
|
-
import { useState } from 'react'
|
|
4
|
-
import { useProjects } from '@/hooks/useProjects'
|
|
5
|
-
import {
|
|
6
|
-
Dialog,
|
|
7
|
-
DialogContent,
|
|
8
|
-
DialogHeader,
|
|
9
|
-
DialogTitle,
|
|
10
|
-
DialogDescription,
|
|
11
|
-
} from '@/components/ui/dialog'
|
|
12
|
-
import { Input } from '@/components/ui/input'
|
|
13
|
-
import { ProjectAvatar } from '@/components/ProjectAvatar'
|
|
14
|
-
import { Loader2, Search, FolderGit2 } from 'lucide-react'
|
|
15
|
-
import { cn } from '@/lib/utils'
|
|
16
|
-
import { formatPath } from '@/lib/format'
|
|
17
|
-
|
|
18
|
-
interface ProjectSelectorModalProps {
|
|
19
|
-
isOpen: boolean
|
|
20
|
-
onClose: () => void
|
|
21
|
-
onSelectProject: (projectId: string, projectName: string, projectPath: string) => void
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export function ProjectSelectorModal({
|
|
25
|
-
isOpen,
|
|
26
|
-
onClose,
|
|
27
|
-
onSelectProject,
|
|
28
|
-
}: ProjectSelectorModalProps) {
|
|
29
|
-
const [search, setSearch] = useState('')
|
|
30
|
-
const { data: projects, isLoading } = useProjects()
|
|
31
|
-
|
|
32
|
-
const filteredProjects = projects?.filter((project) =>
|
|
33
|
-
project.name?.toLowerCase().includes(search.toLowerCase()) ||
|
|
34
|
-
project.repoPath?.toLowerCase().includes(search.toLowerCase())
|
|
35
|
-
) || []
|
|
36
|
-
|
|
37
|
-
return (
|
|
38
|
-
<Dialog open={isOpen} onOpenChange={onClose}>
|
|
39
|
-
<DialogContent className="sm:max-w-md">
|
|
40
|
-
<DialogHeader>
|
|
41
|
-
<DialogTitle>Select a Project</DialogTitle>
|
|
42
|
-
<DialogDescription>
|
|
43
|
-
Choose a project to open a terminal session
|
|
44
|
-
</DialogDescription>
|
|
45
|
-
</DialogHeader>
|
|
46
|
-
|
|
47
|
-
<div className="relative">
|
|
48
|
-
<Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" />
|
|
49
|
-
<Input
|
|
50
|
-
placeholder="Search projects..."
|
|
51
|
-
value={search}
|
|
52
|
-
onChange={(e) => setSearch(e.target.value)}
|
|
53
|
-
className="pl-9"
|
|
54
|
-
/>
|
|
55
|
-
</div>
|
|
56
|
-
|
|
57
|
-
<div className="max-h-[300px] overflow-y-auto space-y-1">
|
|
58
|
-
{isLoading ? (
|
|
59
|
-
<div className="flex items-center justify-center py-8">
|
|
60
|
-
<Loader2 className="h-6 w-6 animate-spin text-muted-foreground" />
|
|
61
|
-
</div>
|
|
62
|
-
) : filteredProjects.length === 0 ? (
|
|
63
|
-
<div className="text-center py-8 text-muted-foreground">
|
|
64
|
-
{search ? 'No projects found' : 'No projects available'}
|
|
65
|
-
</div>
|
|
66
|
-
) : (
|
|
67
|
-
filteredProjects.map((project) => (
|
|
68
|
-
<button
|
|
69
|
-
key={project.id}
|
|
70
|
-
onClick={() => {
|
|
71
|
-
const projectPath = project.repoPath || project.path || '/tmp'
|
|
72
|
-
const projectName = project.name || project.id
|
|
73
|
-
onSelectProject(project.id, projectName, projectPath)
|
|
74
|
-
}}
|
|
75
|
-
className={cn(
|
|
76
|
-
'w-full flex items-center gap-3 p-3 rounded-lg transition-colors',
|
|
77
|
-
'hover:bg-accent text-left'
|
|
78
|
-
)}
|
|
79
|
-
>
|
|
80
|
-
<ProjectAvatar
|
|
81
|
-
projectId={project.id}
|
|
82
|
-
name={project.name || project.id}
|
|
83
|
-
iconPath={project.iconPath}
|
|
84
|
-
size="sm"
|
|
85
|
-
/>
|
|
86
|
-
<div className="flex-1 min-w-0">
|
|
87
|
-
<div className="font-medium truncate">
|
|
88
|
-
{project.name || project.id}
|
|
89
|
-
</div>
|
|
90
|
-
{project.repoPath && (
|
|
91
|
-
<div className="text-xs text-muted-foreground flex items-center gap-1 truncate">
|
|
92
|
-
<FolderGit2 className="h-3 w-3 shrink-0" />
|
|
93
|
-
<span className="truncate">{formatPath(project.repoPath)}</span>
|
|
94
|
-
</div>
|
|
95
|
-
)}
|
|
96
|
-
</div>
|
|
97
|
-
</button>
|
|
98
|
-
))
|
|
99
|
-
)}
|
|
100
|
-
</div>
|
|
101
|
-
</DialogContent>
|
|
102
|
-
</Dialog>
|
|
103
|
-
)
|
|
104
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { ProjectSelectorModal } from './ProjectSelectorModal'
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
'use client'
|
|
2
|
-
|
|
3
|
-
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
|
|
4
|
-
import { useState, type ReactNode } from 'react'
|
|
5
|
-
import { ThemeProvider, type ThemeProviderProps } from 'next-themes'
|
|
6
|
-
import { TerminalProvider } from '@/context/TerminalContext'
|
|
7
|
-
import { GlobalTerminalProvider } from '@/context/GlobalTerminalContext'
|
|
8
|
-
|
|
9
|
-
function ThemeWrapper({ children, ...props }: ThemeProviderProps & { children: ReactNode }) {
|
|
10
|
-
return <ThemeProvider {...props}>{children}</ThemeProvider>
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export function Providers({ children }: { children: ReactNode }) {
|
|
14
|
-
const [queryClient] = useState(() => new QueryClient({
|
|
15
|
-
defaultOptions: {
|
|
16
|
-
queries: {
|
|
17
|
-
// Data considered fresh for 2.5 seconds
|
|
18
|
-
staleTime: 2500,
|
|
19
|
-
// Garbage collect after 5 minutes
|
|
20
|
-
gcTime: 5 * 60 * 1000,
|
|
21
|
-
// Refetch on window focus for real-time feel
|
|
22
|
-
refetchOnWindowFocus: true,
|
|
23
|
-
// Refetch when reconnecting
|
|
24
|
-
refetchOnReconnect: true,
|
|
25
|
-
// Retry failed requests once
|
|
26
|
-
retry: 1,
|
|
27
|
-
retryDelay: 1000,
|
|
28
|
-
},
|
|
29
|
-
},
|
|
30
|
-
}))
|
|
31
|
-
|
|
32
|
-
return (
|
|
33
|
-
<QueryClientProvider client={queryClient}>
|
|
34
|
-
<ThemeWrapper
|
|
35
|
-
attribute="class"
|
|
36
|
-
defaultTheme="dark"
|
|
37
|
-
enableSystem
|
|
38
|
-
disableTransitionOnChange
|
|
39
|
-
>
|
|
40
|
-
<TerminalProvider>
|
|
41
|
-
<GlobalTerminalProvider>
|
|
42
|
-
{children}
|
|
43
|
-
</GlobalTerminalProvider>
|
|
44
|
-
</TerminalProvider>
|
|
45
|
-
</ThemeWrapper>
|
|
46
|
-
</QueryClientProvider>
|
|
47
|
-
)
|
|
48
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { Providers } from './Providers'
|
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
'use client'
|
|
2
|
-
|
|
3
|
-
import { useState } from 'react'
|
|
4
|
-
import Link from 'next/link'
|
|
5
|
-
import { EmptyState } from '@/components/EmptyState'
|
|
6
|
-
import { ExpandButton } from '@/components/ExpandButton'
|
|
7
|
-
import { ListTodo, Bot, Play, X } from 'lucide-react'
|
|
8
|
-
import { cn } from '@/lib/utils'
|
|
9
|
-
import { getPriorityColor } from './QueueCard.utils'
|
|
10
|
-
import type { QueueCardProps } from './QueueCard.types'
|
|
11
|
-
|
|
12
|
-
const COLLAPSED_LIMIT = 10
|
|
13
|
-
const EXPANDED_LIMIT = 50
|
|
14
|
-
|
|
15
|
-
export function QueueCard({ queue, codeHref, className }: QueueCardProps) {
|
|
16
|
-
const [expanded, setExpanded] = useState(false)
|
|
17
|
-
const limit = expanded ? EXPANDED_LIMIT : COLLAPSED_LIMIT
|
|
18
|
-
const displayItems = queue.slice(0, limit)
|
|
19
|
-
const hasMore = queue.length > limit
|
|
20
|
-
|
|
21
|
-
return (
|
|
22
|
-
<div className={cn(
|
|
23
|
-
'relative overflow-hidden rounded-xl border bg-card p-4',
|
|
24
|
-
className
|
|
25
|
-
)}>
|
|
26
|
-
<div className="flex items-center justify-between mb-3">
|
|
27
|
-
<div className="flex items-center gap-2">
|
|
28
|
-
<ListTodo className="h-4 w-4 text-muted-foreground" />
|
|
29
|
-
<span className="text-xs font-bold uppercase tracking-[0.15em] text-muted-foreground">
|
|
30
|
-
Queue
|
|
31
|
-
</span>
|
|
32
|
-
</div>
|
|
33
|
-
<span className="text-xs font-medium text-muted-foreground tabular-nums">
|
|
34
|
-
{queue.length} tasks
|
|
35
|
-
</span>
|
|
36
|
-
</div>
|
|
37
|
-
|
|
38
|
-
{queue.length === 0 ? (
|
|
39
|
-
<EmptyState
|
|
40
|
-
icon={ListTodo}
|
|
41
|
-
title="Queue empty"
|
|
42
|
-
description="Plan your next tasks"
|
|
43
|
-
command="/p:next"
|
|
44
|
-
href={codeHref}
|
|
45
|
-
compact
|
|
46
|
-
/>
|
|
47
|
-
) : (
|
|
48
|
-
<div className="space-y-1.5">
|
|
49
|
-
{displayItems.map((item, i) => {
|
|
50
|
-
const priorityColor = getPriorityColor(item.priority)
|
|
51
|
-
const startHref = codeHref
|
|
52
|
-
? `${codeHref}?cmd=${encodeURIComponent(`p. now "${item.task}"`)}`
|
|
53
|
-
: undefined
|
|
54
|
-
const deleteHref = codeHref
|
|
55
|
-
? `${codeHref}?cmd=${encodeURIComponent(`p. queue remove ${i + 1}`)}`
|
|
56
|
-
: undefined
|
|
57
|
-
|
|
58
|
-
return (
|
|
59
|
-
<div
|
|
60
|
-
key={i}
|
|
61
|
-
className="flex items-start gap-2 group py-1.5 hover:bg-muted/50 rounded px-1 -mx-1"
|
|
62
|
-
>
|
|
63
|
-
<span className={cn(
|
|
64
|
-
"text-xs font-bold w-5 shrink-0 pt-0.5 tabular-nums",
|
|
65
|
-
priorityColor
|
|
66
|
-
)}>
|
|
67
|
-
{i + 1}.
|
|
68
|
-
</span>
|
|
69
|
-
<div className="flex-1 min-w-0">
|
|
70
|
-
<p className="text-sm leading-tight">
|
|
71
|
-
{item.task}
|
|
72
|
-
</p>
|
|
73
|
-
{(item.suggestedAgent || item.estimatedDuration) && (
|
|
74
|
-
<div className="flex items-center gap-2 mt-0.5">
|
|
75
|
-
{item.suggestedAgent && (
|
|
76
|
-
<span className="inline-flex items-center gap-0.5 text-xs text-muted-foreground">
|
|
77
|
-
<Bot className="h-3 w-3" />
|
|
78
|
-
{item.suggestedAgent}
|
|
79
|
-
</span>
|
|
80
|
-
)}
|
|
81
|
-
{item.estimatedDuration && (
|
|
82
|
-
<span className="text-xs text-muted-foreground">
|
|
83
|
-
~{item.estimatedDuration}
|
|
84
|
-
</span>
|
|
85
|
-
)}
|
|
86
|
-
</div>
|
|
87
|
-
)}
|
|
88
|
-
</div>
|
|
89
|
-
{/* Always visible action buttons */}
|
|
90
|
-
<div className="flex items-center gap-1 shrink-0">
|
|
91
|
-
{startHref && (
|
|
92
|
-
<Link
|
|
93
|
-
href={startHref}
|
|
94
|
-
className="p-1 rounded hover:bg-muted text-muted-foreground hover:text-foreground transition-colors"
|
|
95
|
-
title="Start now"
|
|
96
|
-
>
|
|
97
|
-
<Play className="h-3.5 w-3.5" />
|
|
98
|
-
</Link>
|
|
99
|
-
)}
|
|
100
|
-
{deleteHref && (
|
|
101
|
-
<Link
|
|
102
|
-
href={deleteHref}
|
|
103
|
-
className="p-1 rounded hover:bg-muted text-muted-foreground hover:text-foreground transition-colors"
|
|
104
|
-
title="Remove from queue"
|
|
105
|
-
>
|
|
106
|
-
<X className="h-3.5 w-3.5" />
|
|
107
|
-
</Link>
|
|
108
|
-
)}
|
|
109
|
-
</div>
|
|
110
|
-
</div>
|
|
111
|
-
)
|
|
112
|
-
})}
|
|
113
|
-
{(hasMore || expanded) && queue.length > COLLAPSED_LIMIT && (
|
|
114
|
-
<ExpandButton
|
|
115
|
-
expanded={expanded}
|
|
116
|
-
totalCount={queue.length}
|
|
117
|
-
collapsedLimit={COLLAPSED_LIMIT}
|
|
118
|
-
onToggle={() => setExpanded(!expanded)}
|
|
119
|
-
/>
|
|
120
|
-
)}
|
|
121
|
-
</div>
|
|
122
|
-
)}
|
|
123
|
-
</div>
|
|
124
|
-
)
|
|
125
|
-
}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
export interface QueueItem {
|
|
2
|
-
task: string
|
|
3
|
-
priority?: 'low' | 'medium' | 'high' | 'critical' | number
|
|
4
|
-
suggestedAgent?: string
|
|
5
|
-
estimatedDuration?: string
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
export interface QueueCardProps {
|
|
9
|
-
queue: QueueItem[]
|
|
10
|
-
codeHref?: string
|
|
11
|
-
className?: string
|
|
12
|
-
}
|