@grackle-ai/web-components 0.107.2
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/.rush/temp/3ae72563f781afd72723475938136f113846603e.untar.log +10 -0
- package/.rush/temp/bc1d5bf9201ce71abeaeaddd096deb9b0805d703.untar.log +10 -0
- package/.rush/temp/operation/_phase_build/all.log +18 -0
- package/.rush/temp/operation/_phase_build/log-chunks.jsonl +18 -0
- package/.rush/temp/operation/_phase_build/state.json +3 -0
- package/.rush/temp/operation/_phase_test/all.log +121 -0
- package/.rush/temp/operation/_phase_test/log-chunks.jsonl +121 -0
- package/.rush/temp/operation/_phase_test/state.json +3 -0
- package/.rush/temp/shrinkwrap-deps.json +938 -0
- package/.storybook/main.ts +22 -0
- package/.storybook/preview.tsx +30 -0
- package/config/rig.json +4 -0
- package/config/rush-project.json +12 -0
- package/dist/index.css +1 -0
- package/dist/index.js +39221 -0
- package/eslint.config.cjs +5 -0
- package/package.json +83 -0
- package/rush-logs/web-components._phase_build.cache.log +4 -0
- package/rush-logs/web-components._phase_test.cache.log +4 -0
- package/src/components/chat/ChatInput.module.scss +81 -0
- package/src/components/chat/ChatInput.stories.tsx +91 -0
- package/src/components/chat/ChatInput.tsx +168 -0
- package/src/components/chat/index.ts +6 -0
- package/src/components/dag/DagView.module.scss +149 -0
- package/src/components/dag/DagView.stories.tsx +125 -0
- package/src/components/dag/DagView.tsx +109 -0
- package/src/components/dag/TaskNode.stories.tsx +133 -0
- package/src/components/dag/TaskNode.tsx +40 -0
- package/src/components/dag/useDagLayout.ts +139 -0
- package/src/components/display/Breadcrumbs.module.scss +71 -0
- package/src/components/display/Breadcrumbs.stories.tsx +80 -0
- package/src/components/display/Breadcrumbs.tsx +46 -0
- package/src/components/display/Button.module.scss +110 -0
- package/src/components/display/Button.stories.tsx +88 -0
- package/src/components/display/Button.tsx +40 -0
- package/src/components/display/ConfirmDialog.module.scss +67 -0
- package/src/components/display/ConfirmDialog.stories.tsx +81 -0
- package/src/components/display/ConfirmDialog.tsx +88 -0
- package/src/components/display/CopyButton.module.scss +41 -0
- package/src/components/display/CopyButton.stories.tsx +78 -0
- package/src/components/display/CopyButton.tsx +64 -0
- package/src/components/display/DemoBanner.module.scss +37 -0
- package/src/components/display/DemoBanner.stories.tsx +40 -0
- package/src/components/display/DemoBanner.tsx +23 -0
- package/src/components/display/EventHoverRow.module.scss +102 -0
- package/src/components/display/EventHoverRow.stories.tsx +99 -0
- package/src/components/display/EventHoverRow.tsx +154 -0
- package/src/components/display/EventRenderer.module.scss +272 -0
- package/src/components/display/EventRenderer.stories.tsx +186 -0
- package/src/components/display/EventRenderer.tsx +271 -0
- package/src/components/display/EventStream.module.scss +93 -0
- package/src/components/display/EventStream.stories.tsx +249 -0
- package/src/components/display/EventStream.tsx +369 -0
- package/src/components/display/FloatingActionBar.module.scss +107 -0
- package/src/components/display/FloatingActionBar.stories.tsx +122 -0
- package/src/components/display/FloatingActionBar.tsx +119 -0
- package/src/components/display/SessionAttemptSelector.module.scss +50 -0
- package/src/components/display/SessionAttemptSelector.stories.tsx +78 -0
- package/src/components/display/SessionAttemptSelector.tsx +49 -0
- package/src/components/display/SessionPicker.module.scss +200 -0
- package/src/components/display/SessionPicker.stories.tsx +169 -0
- package/src/components/display/SessionPicker.tsx +214 -0
- package/src/components/display/Skeleton.module.scss +58 -0
- package/src/components/display/Skeleton.stories.tsx +94 -0
- package/src/components/display/Skeleton.tsx +127 -0
- package/src/components/display/Spinner.module.scss +41 -0
- package/src/components/display/Spinner.stories.tsx +66 -0
- package/src/components/display/Spinner.tsx +32 -0
- package/src/components/display/SplashScreen.module.scss +20 -0
- package/src/components/display/SplashScreen.stories.tsx +26 -0
- package/src/components/display/SplashScreen.tsx +16 -0
- package/src/components/display/SplitButton.module.scss +166 -0
- package/src/components/display/SplitButton.stories.tsx +95 -0
- package/src/components/display/SplitButton.tsx +128 -0
- package/src/components/display/Tooltip.module.scss +84 -0
- package/src/components/display/Tooltip.stories.tsx +240 -0
- package/src/components/display/Tooltip.tsx +184 -0
- package/src/components/display/extractText.test.tsx +48 -0
- package/src/components/display/index.ts +20 -0
- package/src/components/editable/EditableCheckbox.stories.tsx +54 -0
- package/src/components/editable/EditableCheckbox.tsx +39 -0
- package/src/components/editable/EditableField.module.scss +135 -0
- package/src/components/editable/EditableSelect.tsx +164 -0
- package/src/components/editable/EditableTextArea.stories.tsx +50 -0
- package/src/components/editable/EditableTextArea.tsx +148 -0
- package/src/components/editable/EditableTextField.stories.tsx +62 -0
- package/src/components/editable/EditableTextField.tsx +153 -0
- package/src/components/editable/EnvironmentSelect.module.scss +17 -0
- package/src/components/editable/EnvironmentSelect.stories.tsx +61 -0
- package/src/components/editable/EnvironmentSelect.tsx +87 -0
- package/src/components/editable/index.ts +13 -0
- package/src/components/editable/useEditableField.test.tsx +233 -0
- package/src/components/editable/useEditableField.ts +173 -0
- package/src/components/index.ts +20 -0
- package/src/components/knowledge/KnowledgeDetailPanel.module.scss +162 -0
- package/src/components/knowledge/KnowledgeDetailPanel.stories.tsx +208 -0
- package/src/components/knowledge/KnowledgeDetailPanel.tsx +122 -0
- package/src/components/knowledge/KnowledgeGraph.module.scss +110 -0
- package/src/components/knowledge/KnowledgeGraph.stories.tsx +180 -0
- package/src/components/knowledge/KnowledgeGraph.tsx +455 -0
- package/src/components/knowledge/KnowledgeNav.module.scss +130 -0
- package/src/components/knowledge/KnowledgeNav.stories.tsx +108 -0
- package/src/components/knowledge/KnowledgeNav.tsx +138 -0
- package/src/components/knowledge/index.ts +3 -0
- package/src/components/layout/AppNav.module.scss +82 -0
- package/src/components/layout/AppNav.stories.tsx +115 -0
- package/src/components/layout/AppNav.tsx +133 -0
- package/src/components/layout/BottomStatusBar.module.scss +58 -0
- package/src/components/layout/BottomStatusBar.stories.tsx +35 -0
- package/src/components/layout/BottomStatusBar.tsx +206 -0
- package/src/components/layout/Sidebar.module.scss +60 -0
- package/src/components/layout/Sidebar.stories.tsx +46 -0
- package/src/components/layout/Sidebar.tsx +84 -0
- package/src/components/layout/StatusBar.module.scss +108 -0
- package/src/components/layout/StatusBar.stories.tsx +119 -0
- package/src/components/layout/StatusBar.tsx +70 -0
- package/src/components/layout/index.ts +9 -0
- package/src/components/lists/EnvironmentNav.module.scss +118 -0
- package/src/components/lists/EnvironmentNav.stories.tsx +121 -0
- package/src/components/lists/EnvironmentNav.tsx +133 -0
- package/src/components/lists/FindingsNav.module.scss +126 -0
- package/src/components/lists/FindingsNav.tsx +146 -0
- package/src/components/lists/TaskList.module.scss +206 -0
- package/src/components/lists/TaskList.stories.tsx +401 -0
- package/src/components/lists/TaskList.tsx +509 -0
- package/src/components/lists/index.ts +6 -0
- package/src/components/lists/listHelpers.tsx +130 -0
- package/src/components/notifications/Callout.module.scss +83 -0
- package/src/components/notifications/Callout.stories.tsx +81 -0
- package/src/components/notifications/Callout.tsx +64 -0
- package/src/components/notifications/Toast.module.scss +86 -0
- package/src/components/notifications/Toast.stories.tsx +71 -0
- package/src/components/notifications/Toast.tsx +51 -0
- package/src/components/notifications/ToastContainer.module.scss +23 -0
- package/src/components/notifications/ToastContainer.stories.tsx +66 -0
- package/src/components/notifications/ToastContainer.tsx +29 -0
- package/src/components/notifications/UpdateBanner.stories.tsx +77 -0
- package/src/components/notifications/UpdateBanner.test.tsx +64 -0
- package/src/components/notifications/UpdateBanner.tsx +44 -0
- package/src/components/notifications/index.ts +8 -0
- package/src/components/panels/AboutPanel.stories.tsx +70 -0
- package/src/components/panels/AboutPanel.tsx +66 -0
- package/src/components/panels/AppearancePanel.stories.tsx +45 -0
- package/src/components/panels/AppearancePanel.tsx +97 -0
- package/src/components/panels/CredentialProvidersPanel.stories.tsx +62 -0
- package/src/components/panels/CredentialProvidersPanel.tsx +111 -0
- package/src/components/panels/EnvironmentEditPanel.module.scss +170 -0
- package/src/components/panels/EnvironmentEditPanel.stories.tsx +206 -0
- package/src/components/panels/EnvironmentEditPanel.tsx +785 -0
- package/src/components/panels/FindingsPanel.module.scss +94 -0
- package/src/components/panels/FindingsPanel.stories.tsx +109 -0
- package/src/components/panels/FindingsPanel.tsx +76 -0
- package/src/components/panels/KeyboardShortcutsPanel.module.scss +65 -0
- package/src/components/panels/KeyboardShortcutsPanel.stories.tsx +40 -0
- package/src/components/panels/KeyboardShortcutsPanel.tsx +104 -0
- package/src/components/panels/PluginsPanel.tsx +77 -0
- package/src/components/panels/SettingsPanel.module.scss +336 -0
- package/src/components/panels/TaskActionButtons.module.scss +22 -0
- package/src/components/panels/TaskActionButtons.stories.tsx +125 -0
- package/src/components/panels/TaskActionButtons.tsx +87 -0
- package/src/components/panels/TaskEditPanel.module.scss +202 -0
- package/src/components/panels/TaskEditPanel.stories.tsx +75 -0
- package/src/components/panels/TaskEditPanel.tsx +328 -0
- package/src/components/panels/TaskOverviewPanel.module.scss +236 -0
- package/src/components/panels/TaskOverviewPanel.stories.tsx +219 -0
- package/src/components/panels/TaskOverviewPanel.tsx +270 -0
- package/src/components/panels/TokensPanel.stories.tsx +131 -0
- package/src/components/panels/TokensPanel.tsx +143 -0
- package/src/components/panels/WorkpadPanel.module.scss +39 -0
- package/src/components/panels/WorkpadPanel.stories.tsx +56 -0
- package/src/components/panels/WorkpadPanel.tsx +63 -0
- package/src/components/panels/index.ts +13 -0
- package/src/components/personas/McpToolSelector.module.scss +109 -0
- package/src/components/personas/McpToolSelector.stories.tsx +129 -0
- package/src/components/personas/McpToolSelector.tsx +180 -0
- package/src/components/personas/PersonaManager.module.scss +233 -0
- package/src/components/personas/PersonaManager.stories.tsx +139 -0
- package/src/components/personas/PersonaManager.tsx +122 -0
- package/src/components/schedules/ScheduleManager.module.scss +98 -0
- package/src/components/schedules/ScheduleManager.stories.tsx +78 -0
- package/src/components/schedules/ScheduleManager.tsx +160 -0
- package/src/components/settings/SettingsNav.module.scss +82 -0
- package/src/components/settings/SettingsNav.stories.tsx +83 -0
- package/src/components/settings/SettingsNav.tsx +104 -0
- package/src/components/streams/StreamDetailPanel.module.scss +206 -0
- package/src/components/streams/StreamDetailPanel.stories.tsx +132 -0
- package/src/components/streams/StreamDetailPanel.tsx +119 -0
- package/src/components/streams/StreamList.module.scss +92 -0
- package/src/components/streams/StreamList.stories.tsx +99 -0
- package/src/components/streams/StreamList.tsx +114 -0
- package/src/components/streams/index.ts +10 -0
- package/src/components/tools/AgentToolCard.module.scss +118 -0
- package/src/components/tools/AgentToolCard.stories.tsx +304 -0
- package/src/components/tools/AgentToolCard.tsx +247 -0
- package/src/components/tools/FileEditCard.stories.tsx +138 -0
- package/src/components/tools/FileEditCard.tsx +160 -0
- package/src/components/tools/FileReadCard.stories.tsx +120 -0
- package/src/components/tools/FileReadCard.tsx +106 -0
- package/src/components/tools/FindingCard.stories.tsx +124 -0
- package/src/components/tools/FindingCard.tsx +178 -0
- package/src/components/tools/GenericToolCard.stories.tsx +80 -0
- package/src/components/tools/GenericToolCard.tsx +111 -0
- package/src/components/tools/IpcCard.stories.tsx +129 -0
- package/src/components/tools/IpcCard.tsx +178 -0
- package/src/components/tools/KnowledgeCard.stories.tsx +112 -0
- package/src/components/tools/KnowledgeCard.tsx +165 -0
- package/src/components/tools/MetadataCard.stories.tsx +32 -0
- package/src/components/tools/MetadataCard.tsx +39 -0
- package/src/components/tools/SearchCard.stories.tsx +74 -0
- package/src/components/tools/SearchCard.tsx +86 -0
- package/src/components/tools/ShellCard.stories.tsx +112 -0
- package/src/components/tools/ShellCard.tsx +106 -0
- package/src/components/tools/TaskCard.stories.tsx +123 -0
- package/src/components/tools/TaskCard.tsx +203 -0
- package/src/components/tools/TodoCard.module.scss +131 -0
- package/src/components/tools/TodoCard.stories.tsx +202 -0
- package/src/components/tools/TodoCard.tsx +200 -0
- package/src/components/tools/ToolCard.stories.tsx +177 -0
- package/src/components/tools/ToolCard.tsx +60 -0
- package/src/components/tools/ToolCardProps.ts +20 -0
- package/src/components/tools/ToolSearchCard.stories.tsx +81 -0
- package/src/components/tools/ToolSearchCard.tsx +86 -0
- package/src/components/tools/WorkpadCard.stories.tsx +106 -0
- package/src/components/tools/WorkpadCard.tsx +125 -0
- package/src/components/tools/classifyTool.test.ts +44 -0
- package/src/components/tools/classifyTool.ts +134 -0
- package/src/components/tools/parseDiff.ts +95 -0
- package/src/components/tools/parseShellOutput.ts +28 -0
- package/src/components/tools/toolCardHelpers.test.ts +53 -0
- package/src/components/tools/toolCards.module.scss +234 -0
- package/src/components/workspace/WorkspaceBoard.module.scss +238 -0
- package/src/components/workspace/WorkspaceBoard.stories.tsx +240 -0
- package/src/components/workspace/WorkspaceBoard.tsx +232 -0
- package/src/components/workspace/WorkspaceFormFields.module.scss +79 -0
- package/src/components/workspace/WorkspaceFormFields.stories.tsx +133 -0
- package/src/components/workspace/WorkspaceFormFields.tsx +185 -0
- package/src/context/GrackleContext.ts +28 -0
- package/src/context/GrackleContextTypes.ts +64 -0
- package/src/context/SidebarContext.tsx +53 -0
- package/src/context/ThemeContext.tsx +21 -0
- package/src/context/ToastContext.tsx +56 -0
- package/src/hooks/types.ts +864 -0
- package/src/hooks/useEventSelection.test.ts +204 -0
- package/src/hooks/useEventSelection.ts +158 -0
- package/src/hooks/useSmartScroll.ts +151 -0
- package/src/hooks/useTheme.ts +228 -0
- package/src/index.ts +210 -0
- package/src/mocks/MockGrackleProvider.tsx +1397 -0
- package/src/mocks/mockData.ts +1966 -0
- package/src/mocks/mockKnowledgeData.ts +294 -0
- package/src/scss.d.ts +12 -0
- package/src/styles/global.scss +244 -0
- package/src/styles/mixins.scss +278 -0
- package/src/styles/prism-theme.scss +148 -0
- package/src/styles/theme.scss +1102 -0
- package/src/test-utils/storybook-decorators.tsx +50 -0
- package/src/test-utils/storybook-helpers.ts +262 -0
- package/src/themes.ts +142 -0
- package/src/utils/boardColumns.ts +141 -0
- package/src/utils/breadcrumbs.test.ts +285 -0
- package/src/utils/breadcrumbs.ts +222 -0
- package/src/utils/dashboard.test.ts +156 -0
- package/src/utils/dashboard.ts +195 -0
- package/src/utils/eventContent.test.ts +353 -0
- package/src/utils/eventContent.ts +209 -0
- package/src/utils/findingCategory.ts +33 -0
- package/src/utils/format.ts +27 -0
- package/src/utils/iconSize.ts +18 -0
- package/src/utils/navigation.ts +205 -0
- package/src/utils/route-config.test.ts +128 -0
- package/src/utils/scrollUtils.test.ts +65 -0
- package/src/utils/scrollUtils.ts +49 -0
- package/src/utils/sessionEvents.test.ts +302 -0
- package/src/utils/sessionEvents.ts +233 -0
- package/src/utils/taskStatus.tsx +137 -0
- package/src/utils/time.ts +92 -0
- package/tsconfig.json +8 -0
- package/vite.config.ts +20 -0
- package/vitest.config.ts +10 -0
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared task-status metadata: labels, icons, colors, and column order.
|
|
3
|
+
*
|
|
4
|
+
* Every view (sidebar, DAG, board, task page) should import from here so that
|
|
5
|
+
* labels, icons, colors, and ordering stay consistent across the UI.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { ReactNode } from "react";
|
|
9
|
+
import { Ban, Check, Circle, Pause, X } from "lucide-react";
|
|
10
|
+
import { ICON_SM } from "./iconSize.js";
|
|
11
|
+
|
|
12
|
+
// ---------------------------------------------------------------------------
|
|
13
|
+
// Core types
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
|
|
16
|
+
/** Canonical task statuses displayed in the UI. */
|
|
17
|
+
export type TaskStatusKey = "not_started" | "working" | "paused" | "complete" | "failed";
|
|
18
|
+
|
|
19
|
+
/** Virtual status for tasks with unresolved dependencies. Not stored on the task itself. */
|
|
20
|
+
export type VirtualStatus = "blocked";
|
|
21
|
+
|
|
22
|
+
/** All statuses the UI may display, including virtual ones. */
|
|
23
|
+
export type DisplayStatus = TaskStatusKey | VirtualStatus;
|
|
24
|
+
|
|
25
|
+
/** Visual metadata for a single task status. */
|
|
26
|
+
export interface TaskStatusStyle {
|
|
27
|
+
/** CSS color value (typically a custom-property reference). */
|
|
28
|
+
color: string;
|
|
29
|
+
/** Status icon element. */
|
|
30
|
+
icon: ReactNode;
|
|
31
|
+
/** Human-readable label. */
|
|
32
|
+
label: string;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// ---------------------------------------------------------------------------
|
|
36
|
+
// Style map
|
|
37
|
+
// ---------------------------------------------------------------------------
|
|
38
|
+
|
|
39
|
+
/** Complete style map for every displayable status (canonical + virtual). */
|
|
40
|
+
export const TASK_STATUS_STYLES: Record<DisplayStatus, TaskStatusStyle> = {
|
|
41
|
+
not_started: { color: "var(--text-tertiary)", icon: <Circle size={ICON_SM} />, label: "Not Started" },
|
|
42
|
+
working: { color: "var(--accent-green)", icon: <Circle size={ICON_SM} fill="currentColor" />, label: "Working" },
|
|
43
|
+
paused: { color: "var(--accent-yellow)", icon: <Pause size={ICON_SM} />, label: "Paused" },
|
|
44
|
+
complete: { color: "var(--accent-green)", icon: <Check size={ICON_SM} />, label: "Complete" },
|
|
45
|
+
failed: { color: "var(--accent-red)", icon: <X size={ICON_SM} />, label: "Failed" },
|
|
46
|
+
blocked: { color: "var(--accent-yellow)", icon: <Ban size={ICON_SM} />, label: "Blocked" },
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
/** Safe accessor — returns a style for any status string, falling back to `not_started`. */
|
|
50
|
+
export function getStatusStyle(status: string): TaskStatusStyle {
|
|
51
|
+
if (status === "blocked") {
|
|
52
|
+
return TASK_STATUS_STYLES.blocked;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return TASK_STATUS_STYLES[resolveStatus(status)];
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// ---------------------------------------------------------------------------
|
|
59
|
+
// CSS-class map for badge-style rendering (TaskPage)
|
|
60
|
+
// ---------------------------------------------------------------------------
|
|
61
|
+
|
|
62
|
+
/** Maps a canonical status key to a CSS class suffix used for badge coloring. */
|
|
63
|
+
export const STATUS_BADGE_CLASS_MAP: Record<string, string> = {
|
|
64
|
+
not_started: "statusPending",
|
|
65
|
+
working: "statusInProgress",
|
|
66
|
+
paused: "statusWaitingInput",
|
|
67
|
+
complete: "statusDone",
|
|
68
|
+
failed: "statusFailed",
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
/** Resolve a task status to the corresponding badge class key. */
|
|
72
|
+
export function getStatusBadgeClassKey(status: string): string {
|
|
73
|
+
return STATUS_BADGE_CLASS_MAP[resolveStatus(status)] ?? "statusPending";
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// ---------------------------------------------------------------------------
|
|
77
|
+
// Ordering
|
|
78
|
+
// ---------------------------------------------------------------------------
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Sidebar group order — includes virtual "blocked" group.
|
|
82
|
+
* This is the urgency-first ordering used by the sidebar grouped view.
|
|
83
|
+
*/
|
|
84
|
+
export const SIDEBAR_STATUS_ORDER: DisplayStatus[] = [
|
|
85
|
+
"working", "paused", "failed", "not_started", "blocked", "complete",
|
|
86
|
+
];
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Board columns — the five concrete columns shown on the Kanban board.
|
|
90
|
+
* "blocked" is NOT a column; blocked tasks stay in their original column
|
|
91
|
+
* with a badge overlay.
|
|
92
|
+
*/
|
|
93
|
+
export const BOARD_COLUMN_ORDER: TaskStatusKey[] = [
|
|
94
|
+
"not_started", "working", "paused", "complete", "failed",
|
|
95
|
+
];
|
|
96
|
+
|
|
97
|
+
// ---------------------------------------------------------------------------
|
|
98
|
+
// Alias resolution (legacy proto names → canonical)
|
|
99
|
+
// ---------------------------------------------------------------------------
|
|
100
|
+
|
|
101
|
+
/** Maps legacy / proto status strings to canonical UI status keys. */
|
|
102
|
+
const STATUS_ALIASES: Record<string, TaskStatusKey> = {
|
|
103
|
+
pending: "not_started",
|
|
104
|
+
assigned: "not_started",
|
|
105
|
+
in_progress: "working",
|
|
106
|
+
waiting_input: "paused",
|
|
107
|
+
review: "paused",
|
|
108
|
+
done: "complete",
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
/** Resolve a raw status string to a canonical `TaskStatusKey`, treating unknown values as `not_started`. */
|
|
112
|
+
export function resolveStatus(raw: string): TaskStatusKey {
|
|
113
|
+
if (raw in TASK_STATUS_STYLES && raw !== "blocked") {
|
|
114
|
+
return raw as TaskStatusKey;
|
|
115
|
+
}
|
|
116
|
+
return STATUS_ALIASES[raw] ?? "not_started";
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// ---------------------------------------------------------------------------
|
|
120
|
+
// MiniMap color resolution (DagView)
|
|
121
|
+
// ---------------------------------------------------------------------------
|
|
122
|
+
|
|
123
|
+
/** CSS variable names used for MiniMap node coloring by task status. */
|
|
124
|
+
export const STATUS_CSS_VAR_MAP: Record<string, string> = {
|
|
125
|
+
not_started: "--text-tertiary",
|
|
126
|
+
working: "--accent-green",
|
|
127
|
+
paused: "--accent-yellow",
|
|
128
|
+
complete: "--accent-green",
|
|
129
|
+
failed: "--accent-red",
|
|
130
|
+
// Legacy aliases
|
|
131
|
+
pending: "--text-tertiary",
|
|
132
|
+
assigned: "--text-tertiary",
|
|
133
|
+
in_progress: "--accent-green",
|
|
134
|
+
review: "--accent-yellow",
|
|
135
|
+
done: "--accent-green",
|
|
136
|
+
waiting_input: "--accent-yellow",
|
|
137
|
+
};
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Formats an ISO timestamp string as a human-readable relative time.
|
|
3
|
+
*
|
|
4
|
+
* Examples:
|
|
5
|
+
* "just now" (< 1 minute ago)
|
|
6
|
+
* "5m ago" (< 1 hour ago)
|
|
7
|
+
* "2h ago" (< 24 hours ago)
|
|
8
|
+
* "yesterday" (1–2 days ago)
|
|
9
|
+
* "3 days ago" (2–7 days ago)
|
|
10
|
+
* "Feb 27" (> 7 days ago, same year)
|
|
11
|
+
* "Feb 27 2025" (different year)
|
|
12
|
+
*/
|
|
13
|
+
export function formatRelativeTime(isoString: string): string {
|
|
14
|
+
const date = new Date(isoString);
|
|
15
|
+
const now = new Date();
|
|
16
|
+
const diffMs = now.getTime() - date.getTime();
|
|
17
|
+
const diffSeconds = Math.floor(diffMs / 1000);
|
|
18
|
+
const diffMinutes = Math.floor(diffSeconds / 60);
|
|
19
|
+
const diffHours = Math.floor(diffMinutes / 60);
|
|
20
|
+
const diffDays = Math.floor(diffHours / 24);
|
|
21
|
+
|
|
22
|
+
if (diffSeconds < 60) {
|
|
23
|
+
return "just now";
|
|
24
|
+
}
|
|
25
|
+
if (diffMinutes < 60) {
|
|
26
|
+
return `${diffMinutes}m ago`;
|
|
27
|
+
}
|
|
28
|
+
if (diffHours < 24) {
|
|
29
|
+
return `${diffHours}h ago`;
|
|
30
|
+
}
|
|
31
|
+
if (diffDays === 1) {
|
|
32
|
+
return "yesterday";
|
|
33
|
+
}
|
|
34
|
+
if (diffDays < 7) {
|
|
35
|
+
return `${diffDays} days ago`;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Older than a week — show a short date
|
|
39
|
+
const sameYear = date.getFullYear() === now.getFullYear();
|
|
40
|
+
const month = date.toLocaleString("en-US", { month: "short" });
|
|
41
|
+
const day = date.getDate();
|
|
42
|
+
return sameYear ? `${month} ${day}` : `${month} ${day} ${date.getFullYear()}`;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Formats an ISO timestamp string as a human-readable countdown to a future event.
|
|
47
|
+
*
|
|
48
|
+
* Examples:
|
|
49
|
+
* "in 45s" (< 1 minute away)
|
|
50
|
+
* "in 5m" (< 1 hour away)
|
|
51
|
+
* "in 2h" (< 24 hours away)
|
|
52
|
+
* "in 3 days" (< 7 days away)
|
|
53
|
+
* "Feb 27" (> 7 days away, same year)
|
|
54
|
+
*
|
|
55
|
+
* Returns "overdue" if the timestamp is in the past.
|
|
56
|
+
*/
|
|
57
|
+
export function formatCountdown(isoString: string): string {
|
|
58
|
+
const date = new Date(isoString);
|
|
59
|
+
if (Number.isNaN(date.getTime())) {
|
|
60
|
+
return "\u2014";
|
|
61
|
+
}
|
|
62
|
+
const now = new Date();
|
|
63
|
+
const diffMs = date.getTime() - now.getTime();
|
|
64
|
+
|
|
65
|
+
if (diffMs <= 0) {
|
|
66
|
+
return "overdue";
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const diffSeconds = Math.floor(diffMs / 1000);
|
|
70
|
+
const diffMinutes = Math.floor(diffSeconds / 60);
|
|
71
|
+
const diffHours = Math.floor(diffMinutes / 60);
|
|
72
|
+
const diffDays = Math.floor(diffHours / 24);
|
|
73
|
+
|
|
74
|
+
if (diffSeconds < 60) {
|
|
75
|
+
return `in ${diffSeconds}s`;
|
|
76
|
+
}
|
|
77
|
+
if (diffMinutes < 60) {
|
|
78
|
+
return `in ${diffMinutes}m`;
|
|
79
|
+
}
|
|
80
|
+
if (diffHours < 24) {
|
|
81
|
+
return `in ${diffHours}h`;
|
|
82
|
+
}
|
|
83
|
+
if (diffDays < 7) {
|
|
84
|
+
return `in ${diffDays} day${diffDays === 1 ? "" : "s"}`;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Further out — show a short date
|
|
88
|
+
const sameYear = date.getFullYear() === now.getFullYear();
|
|
89
|
+
const month = date.toLocaleString("en-US", { month: "short" });
|
|
90
|
+
const day = date.getDate();
|
|
91
|
+
return sameYear ? `${month} ${day}` : `${month} ${day} ${date.getFullYear()}`;
|
|
92
|
+
}
|
package/tsconfig.json
ADDED
package/vite.config.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { defineConfig } from "vite";
|
|
2
|
+
import react from "@vitejs/plugin-react";
|
|
3
|
+
import { resolve } from "node:path";
|
|
4
|
+
|
|
5
|
+
export default defineConfig({
|
|
6
|
+
plugins: [react()],
|
|
7
|
+
build: {
|
|
8
|
+
lib: {
|
|
9
|
+
entry: resolve(__dirname, "src/index.ts"),
|
|
10
|
+
formats: ["es"],
|
|
11
|
+
fileName: "index",
|
|
12
|
+
},
|
|
13
|
+
rollupOptions: {
|
|
14
|
+
external: [
|
|
15
|
+
"react", "react-dom", "react-router", "react/jsx-runtime",
|
|
16
|
+
/^@grackle-ai\//,
|
|
17
|
+
],
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
});
|