@mind-fold/open-flow
Advanced tools
| interface DashboardOptions { | ||
| path?: string; | ||
| } | ||
| export declare function dashboard(options: DashboardOptions): Promise<void>; | ||
| export {}; | ||
| //# sourceMappingURL=dashboard.d.ts.map |
| {"version":3,"file":"dashboard.d.ts","sourceRoot":"","sources":["../../src/commands/dashboard.ts"],"names":[],"mappings":"AAIA,UAAU,gBAAgB;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,wBAAsB,SAAS,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAQxE"} |
| import React from "react"; | ||
| import { render } from "ink"; | ||
| import { AgentDashboard } from "../tui/components/AgentDashboard.js"; | ||
| export async function dashboard(options) { | ||
| const workflowPath = options.path || process.cwd(); | ||
| const { waitUntilExit } = render(React.createElement(AgentDashboard, { workflowPath })); | ||
| await waitUntilExit(); | ||
| } | ||
| //# sourceMappingURL=dashboard.js.map |
| {"version":3,"file":"dashboard.js","sourceRoot":"","sources":["../../src/commands/dashboard.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,MAAM,EAAE,MAAM,KAAK,CAAC;AAC7B,OAAO,EAAE,cAAc,EAAE,MAAM,qCAAqC,CAAC;AAMrE,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,OAAyB;IACvD,MAAM,YAAY,GAAG,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IAEnD,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,CAC9B,KAAK,CAAC,aAAa,CAAC,cAAc,EAAE,EAAE,YAAY,EAAE,CAAC,CACtD,CAAC;IAEF,MAAM,aAAa,EAAE,CAAC;AACxB,CAAC"} |
| import type { Agent } from "../hooks/useAgents.js"; | ||
| interface AgentCardProps { | ||
| agent: Agent; | ||
| isSelected: boolean; | ||
| compact?: boolean; | ||
| } | ||
| export declare function AgentCard({ agent, isSelected, compact }: AgentCardProps): import("react/jsx-runtime").JSX.Element; | ||
| export {}; | ||
| //# sourceMappingURL=AgentCard.d.ts.map |
| {"version":3,"file":"AgentCard.d.ts","sourceRoot":"","sources":["../../../src/tui/components/AgentCard.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAEnD,UAAU,cAAc;IACtB,KAAK,EAAE,KAAK,CAAC;IACb,UAAU,EAAE,OAAO,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAsBD,wBAAgB,SAAS,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,EAAE,cAAc,2CA8GvE"} |
| import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime"; | ||
| import { Box, Text } from "ink"; | ||
| const statusColors = { | ||
| running: "green", | ||
| in_progress: "green", | ||
| blocked: "yellow", | ||
| review: "magenta", | ||
| completed: "cyan", | ||
| failed: "red", | ||
| stopped: "gray", | ||
| }; | ||
| const statusIcons = { | ||
| running: "●", | ||
| in_progress: "●", | ||
| blocked: "◐", | ||
| review: "◉", | ||
| completed: "✓", | ||
| failed: "✗", | ||
| stopped: "○", | ||
| }; | ||
| export function AgentCard({ agent, isSelected, compact }) { | ||
| const statusColor = statusColors[agent.status] || "white"; | ||
| const statusIcon = statusIcons[agent.status] || "?"; | ||
| // Format elapsed time | ||
| const elapsed = getElapsedTime(agent.started_at); | ||
| // Compact mode for kanban columns | ||
| if (compact) { | ||
| return (_jsxs(Box, { flexDirection: "column", borderStyle: isSelected ? "bold" : "single", borderColor: isSelected ? "cyan" : "gray", paddingX: 1, marginBottom: 1, children: [_jsxs(Box, { children: [_jsxs(Text, { color: statusColor, children: [statusIcon, " "] }), _jsx(Text, { bold: isSelected, wrap: "truncate", children: truncate(agent.name, 15) }), !agent.is_alive && | ||
| (agent.status === "running" || agent.status === "in_progress") && (_jsx(Text, { color: "red", children: " !" }))] }), _jsxs(Text, { color: "gray", dimColor: true, children: ["P", agent.current_phase, " | ", elapsed] }), agent.error && _jsxs(Text, { color: "red", children: ["\u26A0 ", truncate(agent.error, 12)] })] })); | ||
| } | ||
| // Full mode | ||
| return (_jsxs(Box, { flexDirection: "column", borderStyle: isSelected ? "double" : "single", borderColor: isSelected ? "cyan" : "gray", paddingX: 1, marginBottom: 1, children: [_jsxs(Box, { children: [_jsxs(Text, { color: statusColor, children: [statusIcon, " "] }), _jsx(Text, { bold: isSelected, wrap: "truncate", children: agent.name })] }), agent.branch && (_jsx(Text, { color: "gray", dimColor: true, children: agent.branch })), _jsxs(Box, { children: [_jsxs(Text, { color: "blue", children: ["Phase ", agent.current_phase] }), _jsx(Text, { color: "gray", children: " | " }), _jsx(Text, { color: statusColor, children: agent.status }), !agent.is_alive && | ||
| (agent.status === "running" || agent.status === "in_progress") && (_jsx(Text, { color: "red", children: " (dead)" }))] }), _jsxs(Box, { children: [_jsx(Text, { color: "gray", dimColor: true, children: elapsed }), _jsxs(Text, { color: "gray", children: [" | PID: ", agent.pid] })] }), agent.last_log_lines && agent.last_log_lines.length > 0 && (_jsx(Box, { marginTop: 1, children: _jsx(Text, { color: "gray", dimColor: true, wrap: "truncate", children: truncate(cleanLogLine(agent.last_log_lines[agent.last_log_lines.length - 1]), 60) }) })), agent.error && (_jsx(Text, { color: "red", wrap: "truncate", children: truncate(agent.error, 50) })), agent.pr_url && (_jsxs(Text, { color: "green", children: ["PR: ", truncate(agent.pr_url, 50)] }))] })); | ||
| } | ||
| function getElapsedTime(startedAt) { | ||
| try { | ||
| const start = new Date(startedAt); | ||
| const now = new Date(); | ||
| const diffMs = now.getTime() - start.getTime(); | ||
| const seconds = Math.floor(diffMs / 1000); | ||
| const minutes = Math.floor(seconds / 60); | ||
| const hours = Math.floor(minutes / 60); | ||
| if (hours > 0) { | ||
| return `${hours}h ${minutes % 60}m`; | ||
| } | ||
| else if (minutes > 0) { | ||
| return `${minutes}m ${seconds % 60}s`; | ||
| } | ||
| else { | ||
| return `${seconds}s`; | ||
| } | ||
| } | ||
| catch { | ||
| return "unknown"; | ||
| } | ||
| } | ||
| function truncate(str, maxLen) { | ||
| if (!str) | ||
| return ""; | ||
| if (str.length <= maxLen) | ||
| return str; | ||
| return str.slice(0, maxLen - 3) + "..."; | ||
| } | ||
| function cleanLogLine(line) { | ||
| // Remove ANSI color codes and JSON formatting | ||
| return line | ||
| .replace(/\x1b\[[0-9;]*m/g, "") | ||
| .replace(/^\s*\{.*\}\s*$/, "[JSON output]") | ||
| .trim(); | ||
| } | ||
| //# sourceMappingURL=AgentCard.js.map |
| {"version":3,"file":"AgentCard.js","sourceRoot":"","sources":["../../../src/tui/components/AgentCard.tsx"],"names":[],"mappings":"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"} |
| interface AgentDashboardProps { | ||
| workflowPath?: string; | ||
| } | ||
| export declare function AgentDashboard({ workflowPath }: AgentDashboardProps): import("react/jsx-runtime").JSX.Element; | ||
| export {}; | ||
| //# sourceMappingURL=AgentDashboard.d.ts.map |
| {"version":3,"file":"AgentDashboard.d.ts","sourceRoot":"","sources":["../../../src/tui/components/AgentDashboard.tsx"],"names":[],"mappings":"AAMA,UAAU,mBAAmB;IAC3B,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AA8BD,wBAAgB,cAAc,CAAC,EAAE,YAAY,EAAE,EAAE,mBAAmB,2CAuHnE"} |
| import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; | ||
| import { useState } from "react"; | ||
| import { Box, Text, useApp, useInput } from "ink"; | ||
| import { useAgents } from "../hooks/useAgents.js"; | ||
| import { AgentCard } from "./AgentCard.js"; | ||
| const COLUMNS = [ | ||
| { | ||
| id: "running", | ||
| title: "Running", | ||
| statuses: ["running", "in_progress"], | ||
| color: "green", | ||
| }, | ||
| { | ||
| id: "blocked", | ||
| title: "Blocked", | ||
| statuses: ["blocked", "stopped", "failed"], | ||
| color: "red", | ||
| }, | ||
| { | ||
| id: "review", | ||
| title: "Review", | ||
| statuses: ["review", "completed"], | ||
| color: "magenta", | ||
| }, | ||
| ]; | ||
| export function AgentDashboard({ workflowPath }) { | ||
| const { exit } = useApp(); | ||
| const { agents, loading, error, refresh } = useAgents(workflowPath); | ||
| const [selectedColumn, setSelectedColumn] = useState(0); | ||
| const [selectedIndex, setSelectedIndex] = useState(0); | ||
| // Get agents for each column | ||
| const getColumnAgents = (column) => { | ||
| return agents.filter((agent) => column.statuses.includes(agent.status)); | ||
| }; | ||
| // Keyboard navigation | ||
| useInput((input, key) => { | ||
| if (input === "q" || (key.ctrl && input === "c")) { | ||
| exit(); | ||
| return; | ||
| } | ||
| if (input === "r") { | ||
| refresh(); | ||
| return; | ||
| } | ||
| // Navigate between columns | ||
| if (key.leftArrow) { | ||
| setSelectedColumn((prev) => Math.max(0, prev - 1)); | ||
| setSelectedIndex(0); | ||
| } | ||
| if (key.rightArrow) { | ||
| setSelectedColumn((prev) => Math.min(COLUMNS.length - 1, prev + 1)); | ||
| setSelectedIndex(0); | ||
| } | ||
| // Navigate within column | ||
| const currentColumn = COLUMNS[selectedColumn]; | ||
| const columnAgents = getColumnAgents(currentColumn); | ||
| if (key.upArrow) { | ||
| setSelectedIndex((prev) => Math.max(0, prev - 1)); | ||
| } | ||
| if (key.downArrow) { | ||
| setSelectedIndex((prev) => Math.min(columnAgents.length - 1, prev + 1)); | ||
| } | ||
| }); | ||
| return (_jsxs(Box, { flexDirection: "column", width: "100%", children: [_jsxs(Box, { borderStyle: "single", borderColor: "gray", paddingX: 1, justifyContent: "space-between", children: [_jsxs(Box, { children: [_jsx(Text, { color: "cyan", bold: true, children: "Multi-Agent Dashboard" }), _jsx(Text, { color: "gray", children: " | " }), _jsxs(Text, { children: [agents.length, " agents"] })] }), _jsxs(Box, { children: [error && _jsxs(Text, { color: "red", children: ["Error: ", error] }), !error && _jsx(Text, { color: "gray", children: "Auto-refresh: 1s" })] })] }), _jsx(Box, { flexDirection: "row", width: "100%", minHeight: 20, children: COLUMNS.map((column, colIndex) => { | ||
| const columnAgents = getColumnAgents(column); | ||
| const isSelected = colIndex === selectedColumn; | ||
| return (_jsxs(Box, { flexDirection: "column", flexGrow: 1, flexBasis: 0, borderStyle: isSelected ? "bold" : "single", borderColor: isSelected ? column.color : "gray", marginRight: colIndex < COLUMNS.length - 1 ? 1 : 0, children: [_jsxs(Box, { justifyContent: "center", paddingX: 1, children: [_jsx(Text, { bold: true, color: column.color, children: column.title }), _jsxs(Text, { color: "gray", children: [" (", columnAgents.length, ")"] })] }), _jsx(Box, { flexDirection: "column", paddingX: 1, paddingY: 1, children: columnAgents.length === 0 ? (_jsx(Text, { color: "gray", dimColor: true, children: "-" })) : (columnAgents.map((agent, agentIndex) => (_jsx(AgentCard, { agent: agent, isSelected: isSelected && agentIndex === selectedIndex, compact: true }, agent.id)))) })] }, column.id)); | ||
| }) }), _jsx(Box, { borderStyle: "single", borderColor: "gray", paddingX: 1, marginTop: 1, children: _jsx(Text, { color: "gray", children: "\u2190\u2192 Column | \u2191\u2193 Select | r Refresh | q Quit" }) })] })); | ||
| } | ||
| //# sourceMappingURL=AgentDashboard.js.map |
| {"version":3,"file":"AgentDashboard.js","sourceRoot":"","sources":["../../../src/tui/components/AgentDashboard.tsx"],"names":[],"mappings":"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"} |
| interface AppProps { | ||
| workflowPath?: string; | ||
| } | ||
| export declare function App({ workflowPath }: AppProps): import("react/jsx-runtime").JSX.Element; | ||
| export {}; | ||
| //# sourceMappingURL=App.d.ts.map |
| {"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../../../src/tui/components/App.tsx"],"names":[],"mappings":"AAyCA,UAAU,QAAQ;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,GAAG,CAAC,EAAE,YAAY,EAAE,EAAE,QAAQ,2CA6D7C"} |
| import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; | ||
| import { useState } from "react"; | ||
| import { Box, useApp, useInput } from "ink"; | ||
| import { useFeatures } from "../hooks/useFeatures.js"; | ||
| import { KanbanBoard } from "./KanbanBoard.js"; | ||
| import { StatusBar } from "./StatusBar.js"; | ||
| // Default kanban columns | ||
| const DEFAULT_COLUMNS = [ | ||
| { | ||
| id: "backlog", | ||
| title: "Backlog", | ||
| statuses: ["backlog", "pending"], | ||
| color: "gray", | ||
| }, | ||
| { | ||
| id: "planning", | ||
| title: "Planning", | ||
| statuses: ["planning"], | ||
| color: "blue", | ||
| }, | ||
| { | ||
| id: "in_progress", | ||
| title: "In Progress", | ||
| statuses: ["in_progress", "in-progress"], | ||
| color: "yellow", | ||
| }, | ||
| { | ||
| id: "review", | ||
| title: "Review", | ||
| statuses: ["review"], | ||
| color: "magenta", | ||
| }, | ||
| { | ||
| id: "completed", | ||
| title: "Completed", | ||
| statuses: ["completed"], | ||
| color: "green", | ||
| }, | ||
| ]; | ||
| export function App({ workflowPath }) { | ||
| const { exit } = useApp(); | ||
| const { features, loading, error, refresh } = useFeatures(workflowPath); | ||
| const [selectedColumn, setSelectedColumn] = useState(0); | ||
| const [selectedFeature, setSelectedFeature] = useState(0); | ||
| // Keyboard navigation | ||
| useInput((input, key) => { | ||
| if (input === "q" || (key.ctrl && input === "c")) { | ||
| exit(); | ||
| return; | ||
| } | ||
| if (input === "r") { | ||
| refresh(); | ||
| return; | ||
| } | ||
| // Navigate columns | ||
| if (key.leftArrow) { | ||
| setSelectedColumn((prev) => Math.max(0, prev - 1)); | ||
| setSelectedFeature(0); | ||
| } | ||
| if (key.rightArrow) { | ||
| setSelectedColumn((prev) => Math.min(DEFAULT_COLUMNS.length - 1, prev + 1)); | ||
| setSelectedFeature(0); | ||
| } | ||
| // Navigate features within column | ||
| const currentColumn = DEFAULT_COLUMNS[selectedColumn]; | ||
| const columnFeatures = features.filter((f) => currentColumn.statuses.includes(f.status)); | ||
| if (key.upArrow) { | ||
| setSelectedFeature((prev) => Math.max(0, prev - 1)); | ||
| } | ||
| if (key.downArrow) { | ||
| setSelectedFeature((prev) => Math.min(columnFeatures.length - 1, prev + 1)); | ||
| } | ||
| }); | ||
| return (_jsxs(Box, { flexDirection: "column", width: "100%", children: [_jsx(StatusBar, { featureCount: features.length, loading: loading, error: error }), _jsx(KanbanBoard, { features: features, columns: DEFAULT_COLUMNS, selectedColumn: selectedColumn, selectedFeature: selectedFeature })] })); | ||
| } | ||
| //# sourceMappingURL=App.js.map |
| {"version":3,"file":"App.js","sourceRoot":"","sources":["../../../src/tui/components/App.tsx"],"names":[],"mappings":"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"} |
| import type { Feature } from "../types.js"; | ||
| interface FeatureCardProps { | ||
| feature: Feature; | ||
| isSelected: boolean; | ||
| } | ||
| export declare function FeatureCard({ feature, isSelected }: FeatureCardProps): import("react/jsx-runtime").JSX.Element; | ||
| export {}; | ||
| //# sourceMappingURL=FeatureCard.d.ts.map |
| {"version":3,"file":"FeatureCard.d.ts","sourceRoot":"","sources":["../../../src/tui/components/FeatureCard.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE3C,UAAU,gBAAgB;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,OAAO,CAAC;CACpB;AAmBD,wBAAgB,WAAW,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,EAAE,gBAAgB,2CAkCpE"} |
| import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime"; | ||
| import { Box, Text } from "ink"; | ||
| const priorityColors = { | ||
| critical: "red", | ||
| high: "yellow", | ||
| medium: "blue", | ||
| low: "gray", | ||
| }; | ||
| const statusIcons = { | ||
| pending: "○", | ||
| backlog: "○", | ||
| planning: "◐", | ||
| in_progress: "●", | ||
| "in-progress": "●", | ||
| review: "◉", | ||
| completed: "✓", | ||
| }; | ||
| export function FeatureCard({ feature, isSelected }) { | ||
| const icon = statusIcons[feature.status] || "○"; | ||
| const priorityColor = priorityColors[feature.priority || "medium"] || "white"; | ||
| return (_jsxs(Box, { flexDirection: "column", borderStyle: isSelected ? "double" : "single", borderColor: isSelected ? "cyan" : "gray", paddingX: 1, marginBottom: 1, children: [_jsxs(Box, { children: [_jsxs(Text, { color: priorityColor, children: [icon, " "] }), _jsx(Text, { bold: isSelected, wrap: "truncate", children: feature.name || feature.id })] }), feature.branch && (_jsx(Text, { color: "gray", dimColor: true, children: feature.branch })), feature.next_action && feature.next_action.length > 0 && (_jsxs(Text, { color: "blue", children: ["Phase ", feature.current_phase || 1, "/", feature.next_action.length] })), feature.pr_url && _jsx(Text, { color: "green", children: "PR ready" })] })); | ||
| } | ||
| //# sourceMappingURL=FeatureCard.js.map |
| {"version":3,"file":"FeatureCard.js","sourceRoot":"","sources":["../../../src/tui/components/FeatureCard.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAQhC,MAAM,cAAc,GAA2B;IAC9C,QAAQ,EAAE,KAAK;IACf,IAAI,EAAE,QAAQ;IACd,MAAM,EAAE,MAAM;IACd,GAAG,EAAE,MAAM;CACX,CAAC;AAEF,MAAM,WAAW,GAA2B;IAC3C,OAAO,EAAE,GAAG;IACZ,OAAO,EAAE,GAAG;IACZ,QAAQ,EAAE,GAAG;IACb,WAAW,EAAE,GAAG;IAChB,aAAa,EAAE,GAAG;IAClB,MAAM,EAAE,GAAG;IACX,SAAS,EAAE,GAAG;CACd,CAAC;AAEF,MAAM,UAAU,WAAW,CAAC,EAAE,OAAO,EAAE,UAAU,EAAoB;IACpE,MAAM,IAAI,GAAG,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,GAAG,CAAC;IAChD,MAAM,aAAa,GAAG,cAAc,CAAC,OAAO,CAAC,QAAQ,IAAI,QAAQ,CAAC,IAAI,OAAO,CAAC;IAE9E,OAAO,CACN,MAAC,GAAG,IACH,aAAa,EAAC,QAAQ,EACtB,WAAW,EAAE,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,EAC7C,WAAW,EAAE,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EACzC,QAAQ,EAAE,CAAC,EACX,YAAY,EAAE,CAAC,aAEf,MAAC,GAAG,eACH,MAAC,IAAI,IAAC,KAAK,EAAE,aAAa,aAAG,IAAI,SAAS,EAC1C,KAAC,IAAI,IAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAC,UAAU,YACrC,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,EAAE,GACrB,IACF,EAEL,OAAO,CAAC,MAAM,IAAI,CAClB,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,EAAC,QAAQ,kBACzB,OAAO,CAAC,MAAM,GACT,CACP,EAEA,OAAO,CAAC,WAAW,IAAI,OAAO,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,IAAI,CACzD,MAAC,IAAI,IAAC,KAAK,EAAC,MAAM,uBACV,OAAO,CAAC,aAAa,IAAI,CAAC,OAAG,OAAO,CAAC,WAAW,CAAC,MAAM,IACxD,CACP,EAEA,OAAO,CAAC,MAAM,IAAI,KAAC,IAAI,IAAC,KAAK,EAAC,OAAO,yBAAgB,IACjD,CACN,CAAC;AACH,CAAC"} |
| import type { Feature, KanbanColumn } from "../types.js"; | ||
| interface KanbanBoardProps { | ||
| features: Feature[]; | ||
| columns: KanbanColumn[]; | ||
| selectedColumn: number; | ||
| selectedFeature: number; | ||
| } | ||
| export declare function KanbanBoard({ features, columns, selectedColumn, selectedFeature, }: KanbanBoardProps): import("react/jsx-runtime").JSX.Element; | ||
| export {}; | ||
| //# sourceMappingURL=KanbanBoard.d.ts.map |
| {"version":3,"file":"KanbanBoard.d.ts","sourceRoot":"","sources":["../../../src/tui/components/KanbanBoard.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAGzD,UAAU,gBAAgB;IACzB,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;CACxB;AAED,wBAAgB,WAAW,CAAC,EAC3B,QAAQ,EACR,OAAO,EACP,cAAc,EACd,eAAe,GACf,EAAE,gBAAgB,2CAkDlB"} |
| import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; | ||
| import { Box, Text } from "ink"; | ||
| import { FeatureCard } from "./FeatureCard.js"; | ||
| export function KanbanBoard({ features, columns, selectedColumn, selectedFeature, }) { | ||
| return (_jsx(Box, { flexDirection: "row", width: "100%", children: columns.map((column, colIndex) => { | ||
| const columnFeatures = features.filter((f) => column.statuses.includes(f.status)); | ||
| const isColumnSelected = colIndex === selectedColumn; | ||
| return (_jsxs(Box, { flexDirection: "column", flexGrow: 1, flexBasis: 0, marginRight: 1, borderStyle: isColumnSelected ? "bold" : "single", borderColor: isColumnSelected ? column.color : "gray", children: [_jsxs(Box, { justifyContent: "center", paddingX: 1, children: [_jsx(Text, { bold: true, color: column.color, children: column.title }), _jsxs(Text, { color: "gray", children: [" (", columnFeatures.length, ")"] })] }), _jsx(Box, { flexDirection: "column", paddingX: 1, paddingY: 1, children: columnFeatures.length === 0 ? (_jsx(Text, { color: "gray", dimColor: true, children: "No features" })) : (columnFeatures.map((feature, featureIndex) => (_jsx(FeatureCard, { feature: feature, isSelected: isColumnSelected && featureIndex === selectedFeature }, feature.id)))) })] }, column.id)); | ||
| }) })); | ||
| } | ||
| //# sourceMappingURL=KanbanBoard.js.map |
| {"version":3,"file":"KanbanBoard.js","sourceRoot":"","sources":["../../../src/tui/components/KanbanBoard.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAEhC,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAS/C,MAAM,UAAU,WAAW,CAAC,EAC3B,QAAQ,EACR,OAAO,EACP,cAAc,EACd,eAAe,GACG;IAClB,OAAO,CACN,KAAC,GAAG,IAAC,aAAa,EAAC,KAAK,EAAC,KAAK,EAAC,MAAM,YACnC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,QAAQ,EAAE,EAAE;YACjC,MAAM,cAAc,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAC5C,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAClC,CAAC;YACF,MAAM,gBAAgB,GAAG,QAAQ,KAAK,cAAc,CAAC;YAErD,OAAO,CACN,MAAC,GAAG,IAEH,aAAa,EAAC,QAAQ,EACtB,QAAQ,EAAE,CAAC,EACX,SAAS,EAAE,CAAC,EACZ,WAAW,EAAE,CAAC,EACd,WAAW,EAAE,gBAAgB,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,EACjD,WAAW,EAAE,gBAAgB,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,aAGrD,MAAC,GAAG,IAAC,cAAc,EAAC,QAAQ,EAAC,QAAQ,EAAE,CAAC,aACvC,KAAC,IAAI,IAAC,IAAI,QAAC,KAAK,EAAE,MAAM,CAAC,KAAK,YAC5B,MAAM,CAAC,KAAK,GACP,EACP,MAAC,IAAI,IAAC,KAAK,EAAC,MAAM,mBAAI,cAAc,CAAC,MAAM,SAAS,IAC/C,EAGN,KAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,QAAQ,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,YAClD,cAAc,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAC9B,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,EAAC,QAAQ,kCAEpB,CACP,CAAC,CAAC,CAAC,CACH,cAAc,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,YAAY,EAAE,EAAE,CAAC,CAC7C,KAAC,WAAW,IAEX,OAAO,EAAE,OAAO,EAChB,UAAU,EACT,gBAAgB,IAAI,YAAY,KAAK,eAAe,IAHhD,OAAO,CAAC,EAAE,CAKd,CACF,CAAC,CACF,GACI,KAjCD,MAAM,CAAC,EAAE,CAkCT,CACN,CAAC;QACH,CAAC,CAAC,GACG,CACN,CAAC;AACH,CAAC"} |
| interface StatusBarProps { | ||
| featureCount: number; | ||
| loading: boolean; | ||
| error?: string | null; | ||
| } | ||
| export declare function StatusBar({ featureCount, loading, error }: StatusBarProps): import("react/jsx-runtime").JSX.Element; | ||
| export {}; | ||
| //# sourceMappingURL=StatusBar.d.ts.map |
| {"version":3,"file":"StatusBar.d.ts","sourceRoot":"","sources":["../../../src/tui/components/StatusBar.tsx"],"names":[],"mappings":"AAGA,UAAU,cAAc;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAED,wBAAgB,SAAS,CAAC,EAAE,YAAY,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,cAAc,2CA8BzE"} |
| import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; | ||
| import { Box, Text } from "ink"; | ||
| export function StatusBar({ featureCount, loading, error }) { | ||
| return (_jsxs(Box, { flexDirection: "row", justifyContent: "space-between", borderStyle: "single", borderColor: "gray", paddingX: 1, children: [_jsxs(Box, { children: [_jsx(Text, { color: "cyan", bold: true, children: "Open Flow Dashboard" }), _jsx(Text, { color: "gray", children: " | " }), _jsxs(Text, { children: [featureCount, " features"] })] }), _jsxs(Box, { children: [loading && _jsx(Text, { color: "yellow", children: "Loading..." }), error && _jsxs(Text, { color: "red", children: ["Error: ", error] }), !loading && !error && _jsx(Text, { color: "green", children: "Ready" })] }), _jsx(Box, { children: _jsx(Text, { color: "gray", children: "\u2190\u2191\u2193\u2192 Navigate | r Refresh | q Quit" }) })] })); | ||
| } | ||
| //# sourceMappingURL=StatusBar.js.map |
| {"version":3,"file":"StatusBar.js","sourceRoot":"","sources":["../../../src/tui/components/StatusBar.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAQhC,MAAM,UAAU,SAAS,CAAC,EAAE,YAAY,EAAE,OAAO,EAAE,KAAK,EAAkB;IACzE,OAAO,CACN,MAAC,GAAG,IACH,aAAa,EAAC,KAAK,EACnB,cAAc,EAAC,eAAe,EAC9B,WAAW,EAAC,QAAQ,EACpB,WAAW,EAAC,MAAM,EAClB,QAAQ,EAAE,CAAC,aAEX,MAAC,GAAG,eACH,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,EAAC,IAAI,0CAEhB,EACP,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,oBAAW,EAC7B,MAAC,IAAI,eAAE,YAAY,iBAAiB,IAC/B,EAEN,MAAC,GAAG,eACF,OAAO,IAAI,KAAC,IAAI,IAAC,KAAK,EAAC,QAAQ,2BAAkB,EACjD,KAAK,IAAI,MAAC,IAAI,IAAC,KAAK,EAAC,KAAK,wBAAS,KAAK,IAAQ,EAChD,CAAC,OAAO,IAAI,CAAC,KAAK,IAAI,KAAC,IAAI,IAAC,KAAK,EAAC,OAAO,sBAAa,IAClD,EAEN,KAAC,GAAG,cACH,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,uEAEX,GACF,IACD,CACN,CAAC;AACH,CAAC"} |
| export interface Agent { | ||
| id: string; | ||
| worktree_path: string; | ||
| pid: number; | ||
| started_at: string; | ||
| name: string; | ||
| status: "running" | "in_progress" | "blocked" | "completed" | "review" | "failed" | "stopped"; | ||
| branch?: string; | ||
| current_phase: number; | ||
| priority?: string; | ||
| pr_url?: string; | ||
| is_alive: boolean; | ||
| log_file: string; | ||
| last_log_lines: string[]; | ||
| error?: string; | ||
| } | ||
| interface UseAgentsResult { | ||
| agents: Agent[]; | ||
| loading: boolean; | ||
| error: string | null; | ||
| refresh: () => Promise<void>; | ||
| } | ||
| export declare function useAgents(workflowPath?: string): UseAgentsResult; | ||
| export {}; | ||
| //# sourceMappingURL=useAgents.d.ts.map |
| {"version":3,"file":"useAgents.d.ts","sourceRoot":"","sources":["../../../src/tui/hooks/useAgents.ts"],"names":[],"mappings":"AAwBA,MAAM,WAAW,KAAK;IAEpB,EAAE,EAAE,MAAM,CAAC;IACX,aAAa,EAAE,MAAM,CAAC;IACtB,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;IAEnB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EACF,SAAS,GACT,aAAa,GACb,SAAS,GACT,WAAW,GACX,QAAQ,GACR,QAAQ,GACR,SAAS,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,EAAE,CAAC;IAEzB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,UAAU,eAAe;IACvB,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9B;AAED,wBAAgB,SAAS,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,eAAe,CAqKhE"} |
| import { useState, useEffect, useCallback } from "react"; | ||
| import { readFile, readdir } from "fs/promises"; | ||
| import { join } from "path"; | ||
| export function useAgents(workflowPath) { | ||
| const [agents, setAgents] = useState([]); | ||
| const [loading, setLoading] = useState(true); | ||
| const [error, setError] = useState(null); | ||
| const basePath = workflowPath || process.cwd(); | ||
| const loadAgents = useCallback(async () => { | ||
| setLoading(true); | ||
| setError(null); | ||
| try { | ||
| // Find developer name from .developer file | ||
| const developerFile = join(basePath, "workflow", ".developer"); | ||
| let developer = "unknown"; | ||
| try { | ||
| const content = await readFile(developerFile, "utf-8"); | ||
| const match = content.match(/^name=(.+)$/m); | ||
| if (match) { | ||
| developer = match[1].trim(); | ||
| } | ||
| } | ||
| catch { | ||
| // .developer not found, try to find any agent-progress directory | ||
| const agentProgressDir = join(basePath, "workflow", "agent-progress"); | ||
| try { | ||
| const dirs = await readdir(agentProgressDir); | ||
| if (dirs.length > 0 && !dirs[0].startsWith(".")) { | ||
| developer = dirs[0]; | ||
| } | ||
| } | ||
| catch { | ||
| // No agent-progress directory | ||
| } | ||
| } | ||
| // Read registry.json (just contains worktree locations) | ||
| const registryPath = join(basePath, "workflow", "agent-progress", developer, ".agents", "registry.json"); | ||
| let registryData = { agents: [] }; | ||
| try { | ||
| const content = await readFile(registryPath, "utf-8"); | ||
| registryData = JSON.parse(content); | ||
| } | ||
| catch { | ||
| // Registry doesn't exist yet | ||
| } | ||
| // For each registry entry, read status from worktree/.feature/ | ||
| const enrichedAgents = await Promise.all(registryData.agents.map(async (entry) => { | ||
| const agent = { | ||
| // From registry | ||
| id: entry.id, | ||
| worktree_path: entry.worktree_path, | ||
| pid: entry.pid, | ||
| started_at: entry.started_at, | ||
| // Defaults (will be overwritten) | ||
| name: entry.id, | ||
| status: "running", | ||
| current_phase: 1, | ||
| is_alive: false, | ||
| log_file: join(entry.worktree_path, ".agent-log"), | ||
| last_log_lines: [], | ||
| }; | ||
| // Check if PID is alive | ||
| agent.is_alive = isPidAlive(entry.pid); | ||
| // Read feature.json from worktree/.feature/ | ||
| try { | ||
| const featureJsonPath = join(entry.worktree_path, ".feature", "feature.json"); | ||
| const featureContent = await readFile(featureJsonPath, "utf-8"); | ||
| const featureJson = JSON.parse(featureContent); | ||
| agent.name = featureJson.name || entry.id; | ||
| agent.status = normalizeStatus(featureJson.status); | ||
| agent.branch = featureJson.branch; | ||
| agent.current_phase = featureJson.current_phase || 1; | ||
| agent.priority = featureJson.priority; | ||
| agent.pr_url = featureJson.pr_url; | ||
| } | ||
| catch { | ||
| // Can't read feature.json | ||
| } | ||
| // Get last few lines of log (needed for status detection) | ||
| try { | ||
| const logContent = await readFile(agent.log_file, "utf-8"); | ||
| const lines = logContent.split("\n").filter((l) => l.trim()); | ||
| agent.last_log_lines = lines.slice(-10); // Read more lines to find success marker | ||
| } | ||
| catch { | ||
| // Can't read log | ||
| } | ||
| // If process is dead but status is still "running/in_progress" | ||
| // Check log to see if it completed successfully | ||
| if (!agent.is_alive && | ||
| (agent.status === "running" || agent.status === "in_progress")) { | ||
| // Check if log indicates successful completion | ||
| const lastLines = agent.last_log_lines.join("\n"); | ||
| if (lastLines.includes('"subtype":"success"')) { | ||
| agent.status = "completed"; | ||
| } | ||
| else { | ||
| agent.status = "stopped"; | ||
| } | ||
| } | ||
| // Read blocked.json if exists | ||
| try { | ||
| const blockedPath = join(entry.worktree_path, ".feature", "blocked.json"); | ||
| const blockedContent = await readFile(blockedPath, "utf-8"); | ||
| const blockedJson = JSON.parse(blockedContent); | ||
| agent.error = blockedJson.message; | ||
| if (blockedJson.type === "blocked") { | ||
| agent.status = "blocked"; | ||
| } | ||
| } | ||
| catch { | ||
| // No blocked.json | ||
| } | ||
| return agent; | ||
| })); | ||
| setAgents(enrichedAgents); | ||
| } | ||
| catch (err) { | ||
| setError(err instanceof Error ? err.message : "Failed to load agents"); | ||
| } | ||
| finally { | ||
| setLoading(false); | ||
| } | ||
| }, [basePath]); | ||
| // Initial load | ||
| useEffect(() => { | ||
| loadAgents(); | ||
| }, [loadAgents]); | ||
| // Auto-refresh every 1 second | ||
| useEffect(() => { | ||
| const interval = setInterval(loadAgents, 1000); | ||
| return () => clearInterval(interval); | ||
| }, [loadAgents]); | ||
| return { | ||
| agents, | ||
| loading, | ||
| error, | ||
| refresh: loadAgents, | ||
| }; | ||
| } | ||
| function isPidAlive(pid) { | ||
| try { | ||
| process.kill(pid, 0); | ||
| return true; | ||
| } | ||
| catch { | ||
| return false; | ||
| } | ||
| } | ||
| function normalizeStatus(status) { | ||
| const statusMap = { | ||
| running: "running", | ||
| in_progress: "in_progress", | ||
| "in-progress": "in_progress", | ||
| blocked: "blocked", | ||
| completed: "completed", | ||
| done: "completed", | ||
| review: "review", | ||
| failed: "failed", | ||
| stopped: "stopped", | ||
| planning: "running", | ||
| }; | ||
| return statusMap[status?.toLowerCase()] || "running"; | ||
| } | ||
| //# sourceMappingURL=useAgents.js.map |
| {"version":3,"file":"useAgents.js","sourceRoot":"","sources":["../../../src/tui/hooks/useAgents.ts"],"names":[],"mappings":"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"} |
| import type { Feature } from "../types.js"; | ||
| interface UseFeaturesResult { | ||
| features: Feature[]; | ||
| loading: boolean; | ||
| error: string | null; | ||
| refresh: () => Promise<void>; | ||
| } | ||
| export declare function useFeatures(workflowPath?: string): UseFeaturesResult; | ||
| export {}; | ||
| //# sourceMappingURL=useFeatures.d.ts.map |
| {"version":3,"file":"useFeatures.d.ts","sourceRoot":"","sources":["../../../src/tui/hooks/useFeatures.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE3C,UAAU,iBAAiB;IACzB,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9B;AAED,wBAAgB,WAAW,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,iBAAiB,CAqEpE"} |
| import { useState, useEffect } from "react"; | ||
| import { readFile, readdir, stat } from "fs/promises"; | ||
| import { join } from "path"; | ||
| export function useFeatures(workflowPath) { | ||
| const [features, setFeatures] = useState([]); | ||
| const [loading, setLoading] = useState(true); | ||
| const [error, setError] = useState(null); | ||
| const basePath = workflowPath || process.cwd(); | ||
| const loadFeatures = async () => { | ||
| setLoading(true); | ||
| setError(null); | ||
| try { | ||
| // Search in workflow/agent-progress/*/features/ (actual structure) | ||
| const agentProgressDir = join(basePath, "workflow", "agent-progress"); | ||
| const featureFiles = await findAllFeatureFiles(agentProgressDir); | ||
| const loadedFeatures = []; | ||
| for (const filePath of featureFiles) { | ||
| try { | ||
| const content = await readFile(filePath, "utf-8"); | ||
| const data = JSON.parse(content); | ||
| // Normalize the feature data | ||
| const feature = { | ||
| id: data.id || data.name || "unknown", | ||
| name: data.name || data.id || "Unnamed Feature", | ||
| status: normalizeStatus(data.status), | ||
| branch: data.branch, | ||
| priority: data.priority || "medium", | ||
| developer: data.developer, | ||
| created_at: data.created_at, | ||
| pr_url: data.pr_url, | ||
| next_action: data.next_action, | ||
| current_phase: data.current_phase, | ||
| }; | ||
| loadedFeatures.push(feature); | ||
| } | ||
| catch { | ||
| // Skip files that can't be parsed | ||
| } | ||
| } | ||
| // Sort by priority (critical > high > medium > low) | ||
| const priorityOrder = { critical: 0, high: 1, medium: 2, low: 3 }; | ||
| loadedFeatures.sort((a, b) => (priorityOrder[a.priority || "medium"] || 2) - | ||
| (priorityOrder[b.priority || "medium"] || 2)); | ||
| setFeatures(loadedFeatures); | ||
| } | ||
| catch (err) { | ||
| setError(err instanceof Error ? err.message : "Failed to load features"); | ||
| } | ||
| finally { | ||
| setLoading(false); | ||
| } | ||
| }; | ||
| useEffect(() => { | ||
| loadFeatures(); | ||
| }, [basePath]); | ||
| return { | ||
| features, | ||
| loading, | ||
| error, | ||
| refresh: loadFeatures, | ||
| }; | ||
| } | ||
| // Find all feature.json files in workflow/agent-progress/*/features/ | ||
| async function findAllFeatureFiles(agentProgressDir) { | ||
| const results = []; | ||
| try { | ||
| // List all user directories (e.g., taosu, other-dev) | ||
| const users = await readdir(agentProgressDir); | ||
| for (const user of users) { | ||
| const userFeaturesDir = join(agentProgressDir, user, "features"); | ||
| const userFeatures = await findFeatureFilesRecursive(userFeaturesDir); | ||
| results.push(...userFeatures); | ||
| } | ||
| } | ||
| catch { | ||
| // Directory doesn't exist | ||
| } | ||
| return results; | ||
| } | ||
| // Recursively find feature.json files, skipping archive | ||
| async function findFeatureFilesRecursive(dir) { | ||
| const results = []; | ||
| try { | ||
| const entries = await readdir(dir); | ||
| for (const entry of entries) { | ||
| // Skip archive and node_modules | ||
| if (entry === "archive" || entry === "node_modules") { | ||
| continue; | ||
| } | ||
| const fullPath = join(dir, entry); | ||
| const entryStat = await stat(fullPath); | ||
| if (entryStat.isDirectory()) { | ||
| // Check for feature.json in this directory | ||
| const featureJsonPath = join(fullPath, "feature.json"); | ||
| try { | ||
| await stat(featureJsonPath); | ||
| results.push(featureJsonPath); | ||
| } | ||
| catch { | ||
| // No feature.json here, recurse into subdirectory | ||
| const subResults = await findFeatureFilesRecursive(fullPath); | ||
| results.push(...subResults); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| catch { | ||
| // Directory doesn't exist or can't be read | ||
| } | ||
| return results; | ||
| } | ||
| function normalizeStatus(status) { | ||
| const statusMap = { | ||
| pending: "pending", | ||
| backlog: "backlog", | ||
| planning: "planning", | ||
| in_progress: "in_progress", | ||
| "in-progress": "in_progress", | ||
| inprogress: "in_progress", | ||
| review: "review", | ||
| completed: "completed", | ||
| done: "completed", | ||
| }; | ||
| return statusMap[status?.toLowerCase()] || "pending"; | ||
| } | ||
| //# sourceMappingURL=useFeatures.js.map |
| {"version":3,"file":"useFeatures.js","sourceRoot":"","sources":["../../../src/tui/hooks/useFeatures.ts"],"names":[],"mappings":"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"} |
| export { AgentDashboard } from "./components/AgentDashboard.js"; | ||
| export { AgentCard } from "./components/AgentCard.js"; | ||
| export { App } from "./components/App.js"; | ||
| export { KanbanBoard } from "./components/KanbanBoard.js"; | ||
| export { FeatureCard } from "./components/FeatureCard.js"; | ||
| export { StatusBar } from "./components/StatusBar.js"; | ||
| export { useAgents } from "./hooks/useAgents.js"; | ||
| export { useFeatures } from "./hooks/useFeatures.js"; | ||
| export type { Agent } from "./hooks/useAgents.js"; | ||
| export type { Feature, FeatureStatus, PhaseAction, KanbanColumn, DashboardState, } from "./types.js"; | ||
| //# sourceMappingURL=index.d.ts.map |
| {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tui/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAChE,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAGtD,OAAO,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC1D,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC1D,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAGtD,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAGrD,YAAY,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAClD,YAAY,EACV,OAAO,EACP,aAAa,EACb,WAAW,EACX,YAAY,EACZ,cAAc,GACf,MAAM,YAAY,CAAC"} |
| // TUI components | ||
| export { AgentDashboard } from "./components/AgentDashboard.js"; | ||
| export { AgentCard } from "./components/AgentCard.js"; | ||
| // Legacy components (for feature.json based view) | ||
| export { App } from "./components/App.js"; | ||
| export { KanbanBoard } from "./components/KanbanBoard.js"; | ||
| export { FeatureCard } from "./components/FeatureCard.js"; | ||
| export { StatusBar } from "./components/StatusBar.js"; | ||
| // Hooks | ||
| export { useAgents } from "./hooks/useAgents.js"; | ||
| export { useFeatures } from "./hooks/useFeatures.js"; | ||
| //# sourceMappingURL=index.js.map |
| {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tui/index.ts"],"names":[],"mappings":"AAAA,iBAAiB;AACjB,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAChE,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAEtD,kDAAkD;AAClD,OAAO,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC1D,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC1D,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAEtD,QAAQ;AACR,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC"} |
| export type FeatureStatus = "pending" | "in_progress" | "in-progress" | "review" | "completed" | "backlog" | "planning"; | ||
| export interface Feature { | ||
| id: string; | ||
| name: string; | ||
| status: FeatureStatus; | ||
| branch?: string; | ||
| priority?: "low" | "medium" | "high" | "critical"; | ||
| developer?: string; | ||
| created_at?: string; | ||
| pr_url?: string; | ||
| next_action?: PhaseAction[]; | ||
| current_phase?: number; | ||
| } | ||
| export interface PhaseAction { | ||
| phase: number; | ||
| action: string; | ||
| target: string; | ||
| detail?: string; | ||
| } | ||
| export interface KanbanColumn { | ||
| id: string; | ||
| title: string; | ||
| statuses: FeatureStatus[]; | ||
| color: string; | ||
| } | ||
| export interface DashboardState { | ||
| features: Feature[]; | ||
| selectedColumn: number; | ||
| selectedFeature: number; | ||
| loading: boolean; | ||
| error?: string; | ||
| } | ||
| //# sourceMappingURL=types.d.ts.map |
| {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/tui/types.ts"],"names":[],"mappings":"AACA,MAAM,MAAM,aAAa,GACtB,SAAS,GACT,aAAa,GACb,aAAa,GACb,QAAQ,GACR,WAAW,GACX,SAAS,GACT,UAAU,CAAC;AAGd,MAAM,WAAW,OAAO;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,aAAa,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,UAAU,CAAC;IAClD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,WAAW,EAAE,CAAC;IAC5B,aAAa,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,WAAW;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB;AAGD,MAAM,WAAW,YAAY;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,KAAK,EAAE,MAAM,CAAC;CACd;AAGD,MAAM,WAAW,cAAc;IAC9B,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CACf"} |
| export {}; | ||
| //# sourceMappingURL=types.js.map |
| {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/tui/types.ts"],"names":[],"mappings":""} |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"AAWA,eAAO,MAAM,OAAO,KAAsB,CAAC"} | ||
| {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"AAYA,eAAO,MAAM,OAAO,KAAsB,CAAC"} |
+15
-0
@@ -7,2 +7,3 @@ import fs from "node:fs"; | ||
| import { init } from "../commands/init.js"; | ||
| import { dashboard } from "../commands/dashboard.js"; | ||
| // Read version from package.json | ||
@@ -42,3 +43,17 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url)); | ||
| }); | ||
| program | ||
| .command("dashboard") | ||
| .alias("db") | ||
| .description("Open the TUI dashboard to view feature status") | ||
| .option("-p, --path <path>", "Path to the workflow directory") | ||
| .action(async (options) => { | ||
| try { | ||
| await dashboard(options); | ||
| } | ||
| catch (error) { | ||
| console.error(chalk.red("Error:"), error instanceof Error ? error.message : error); | ||
| process.exit(1); | ||
| } | ||
| }); | ||
| program.parse(); | ||
| //# sourceMappingURL=index.js.map |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAE3C,iCAAiC;AACjC,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAC/D,MAAM,eAAe,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,oBAAoB,CAAC,CAAC;AACtE,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC,CAAC;AAC1E,MAAM,CAAC,MAAM,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC;AAE3C,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACL,IAAI,CAAC,WAAW,CAAC;KACjB,WAAW,CACX,+EAA+E,CAC/E;KACA,OAAO,CAAC,OAAO,EAAE,eAAe,EAAE,2BAA2B,CAAC,CAAC;AAEjE,OAAO;KACL,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,6CAA6C,CAAC;KAC1D,MAAM,CAAC,UAAU,EAAE,yBAAyB,CAAC;KAC7C,MAAM,CAAC,UAAU,EAAE,8BAA8B,CAAC;KAClD,MAAM,CAAC,WAAW,EAAE,+BAA+B,CAAC;KACpD,MAAM,CACN,mBAAmB,EACnB,mDAAmD,CACnD;KACA,MAAM,CAAC,aAAa,EAAE,yCAAyC,CAAC;KAChE,MAAM,CAAC,qBAAqB,EAAE,oCAAoC,CAAC;KACnE,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;IACzB,IAAI,CAAC;QACJ,MAAM,IAAI,CAAC,OAAO,CAAC,CAAC;IACrB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,OAAO,CAAC,KAAK,CACZ,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,EACnB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAC9C,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACjB,CAAC;AACF,CAAC,CAAC,CAAC;AAEJ,OAAO;KACL,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,6CAA6C,CAAC;KAC1D,MAAM,CAAC,KAAK,IAAI,EAAE;IAClB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,6BAA6B,CAAC,CAAC,CAAC;AAC1D,CAAC,CAAC,CAAC;AAEJ,OAAO,CAAC,KAAK,EAAE,CAAC"} | ||
| {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"} |
+7
-2
| { | ||
| "name": "@mind-fold/open-flow", | ||
| "version": "0.2.17", | ||
| "version": "0.2.19", | ||
| "description": "AI-assisted development workflow initializer for Cursor, Claude Code and more", | ||
@@ -40,3 +40,7 @@ "type": "module", | ||
| "commander": "^12.1.0", | ||
| "inquirer": "^9.3.7" | ||
| "ink": "^6.0.0", | ||
| "ink-select-input": "^6.2.0", | ||
| "ink-spinner": "^5.0.0", | ||
| "inquirer": "^9.3.7", | ||
| "react": "^19.2.3" | ||
| }, | ||
@@ -46,2 +50,3 @@ "devDependencies": { | ||
| "@types/node": "^20.17.10", | ||
| "@types/react": "^19.2.7", | ||
| "typescript": "^5.7.2" | ||
@@ -48,0 +53,0 @@ }, |
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
389753
18.87%148
42.31%1753
68.56%7
133.33%4
33.33%8
100%+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added