@mind-fold/open-flow 0.2.17 → 0.2.19
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/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +15 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/commands/dashboard.d.ts +6 -0
- package/dist/commands/dashboard.d.ts.map +1 -0
- package/dist/commands/dashboard.js +9 -0
- package/dist/commands/dashboard.js.map +1 -0
- package/dist/tui/components/AgentCard.d.ts +9 -0
- package/dist/tui/components/AgentCard.d.ts.map +1 -0
- package/dist/tui/components/AgentCard.js +71 -0
- package/dist/tui/components/AgentCard.js.map +1 -0
- package/dist/tui/components/AgentDashboard.d.ts +6 -0
- package/dist/tui/components/AgentDashboard.d.ts.map +1 -0
- package/dist/tui/components/AgentDashboard.js +70 -0
- package/dist/tui/components/AgentDashboard.js.map +1 -0
- package/dist/tui/components/App.d.ts +6 -0
- package/dist/tui/components/App.d.ts.map +1 -0
- package/dist/tui/components/App.js +76 -0
- package/dist/tui/components/App.js.map +1 -0
- package/dist/tui/components/FeatureCard.d.ts +8 -0
- package/dist/tui/components/FeatureCard.d.ts.map +1 -0
- package/dist/tui/components/FeatureCard.js +23 -0
- package/dist/tui/components/FeatureCard.js.map +1 -0
- package/dist/tui/components/KanbanBoard.d.ts +10 -0
- package/dist/tui/components/KanbanBoard.d.ts.map +1 -0
- package/dist/tui/components/KanbanBoard.js +11 -0
- package/dist/tui/components/KanbanBoard.js.map +1 -0
- package/dist/tui/components/StatusBar.d.ts +8 -0
- package/dist/tui/components/StatusBar.d.ts.map +1 -0
- package/dist/tui/components/StatusBar.js +6 -0
- package/dist/tui/components/StatusBar.js.map +1 -0
- package/dist/tui/hooks/useAgents.d.ts +25 -0
- package/dist/tui/hooks/useAgents.d.ts.map +1 -0
- package/dist/tui/hooks/useAgents.js +165 -0
- package/dist/tui/hooks/useAgents.js.map +1 -0
- package/dist/tui/hooks/useFeatures.d.ts +10 -0
- package/dist/tui/hooks/useFeatures.d.ts.map +1 -0
- package/dist/tui/hooks/useFeatures.js +126 -0
- package/dist/tui/hooks/useFeatures.js.map +1 -0
- package/dist/tui/index.d.ts +11 -0
- package/dist/tui/index.d.ts.map +1 -0
- package/dist/tui/index.js +12 -0
- package/dist/tui/index.js.map +1 -0
- package/dist/tui/types.d.ts +33 -0
- package/dist/tui/types.d.ts.map +1 -0
- package/dist/tui/types.js +2 -0
- package/dist/tui/types.js.map +1 -0
- package/package.json +7 -2
package/dist/cli/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"AAYA,eAAO,MAAM,OAAO,KAAsB,CAAC"}
|
package/dist/cli/index.js
CHANGED
|
@@ -4,6 +4,7 @@ import { fileURLToPath } from "node:url";
|
|
|
4
4
|
import chalk from "chalk";
|
|
5
5
|
import { Command } from "commander";
|
|
6
6
|
import { init } from "../commands/init.js";
|
|
7
|
+
import { dashboard } from "../commands/dashboard.js";
|
|
7
8
|
// Read version from package.json
|
|
8
9
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
9
10
|
const packageJsonPath = path.resolve(__dirname, "../../package.json");
|
|
@@ -38,5 +39,19 @@ program
|
|
|
38
39
|
.action(async () => {
|
|
39
40
|
console.log(chalk.yellow("Coming soon: update command"));
|
|
40
41
|
});
|
|
42
|
+
program
|
|
43
|
+
.command("dashboard")
|
|
44
|
+
.alias("db")
|
|
45
|
+
.description("Open the TUI dashboard to view feature status")
|
|
46
|
+
.option("-p, --path <path>", "Path to the workflow directory")
|
|
47
|
+
.action(async (options) => {
|
|
48
|
+
try {
|
|
49
|
+
await dashboard(options);
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
console.error(chalk.red("Error:"), error instanceof Error ? error.message : error);
|
|
53
|
+
process.exit(1);
|
|
54
|
+
}
|
|
55
|
+
});
|
|
41
56
|
program.parse();
|
|
42
57
|
//# sourceMappingURL=index.js.map
|
package/dist/cli/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
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;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { render } from "ink";
|
|
3
|
+
import { AgentDashboard } from "../tui/components/AgentDashboard.js";
|
|
4
|
+
export async function dashboard(options) {
|
|
5
|
+
const workflowPath = options.path || process.cwd();
|
|
6
|
+
const { waitUntilExit } = render(React.createElement(AgentDashboard, { workflowPath }));
|
|
7
|
+
await waitUntilExit();
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=dashboard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Agent } from "../hooks/useAgents.js";
|
|
2
|
+
interface AgentCardProps {
|
|
3
|
+
agent: Agent;
|
|
4
|
+
isSelected: boolean;
|
|
5
|
+
compact?: boolean;
|
|
6
|
+
}
|
|
7
|
+
export declare function AgentCard({ agent, isSelected, compact }: AgentCardProps): import("react/jsx-runtime").JSX.Element;
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=AgentCard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"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"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Text } from "ink";
|
|
3
|
+
const statusColors = {
|
|
4
|
+
running: "green",
|
|
5
|
+
in_progress: "green",
|
|
6
|
+
blocked: "yellow",
|
|
7
|
+
review: "magenta",
|
|
8
|
+
completed: "cyan",
|
|
9
|
+
failed: "red",
|
|
10
|
+
stopped: "gray",
|
|
11
|
+
};
|
|
12
|
+
const statusIcons = {
|
|
13
|
+
running: "●",
|
|
14
|
+
in_progress: "●",
|
|
15
|
+
blocked: "◐",
|
|
16
|
+
review: "◉",
|
|
17
|
+
completed: "✓",
|
|
18
|
+
failed: "✗",
|
|
19
|
+
stopped: "○",
|
|
20
|
+
};
|
|
21
|
+
export function AgentCard({ agent, isSelected, compact }) {
|
|
22
|
+
const statusColor = statusColors[agent.status] || "white";
|
|
23
|
+
const statusIcon = statusIcons[agent.status] || "?";
|
|
24
|
+
// Format elapsed time
|
|
25
|
+
const elapsed = getElapsedTime(agent.started_at);
|
|
26
|
+
// Compact mode for kanban columns
|
|
27
|
+
if (compact) {
|
|
28
|
+
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 &&
|
|
29
|
+
(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)] })] }));
|
|
30
|
+
}
|
|
31
|
+
// Full mode
|
|
32
|
+
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 &&
|
|
33
|
+
(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)] }))] }));
|
|
34
|
+
}
|
|
35
|
+
function getElapsedTime(startedAt) {
|
|
36
|
+
try {
|
|
37
|
+
const start = new Date(startedAt);
|
|
38
|
+
const now = new Date();
|
|
39
|
+
const diffMs = now.getTime() - start.getTime();
|
|
40
|
+
const seconds = Math.floor(diffMs / 1000);
|
|
41
|
+
const minutes = Math.floor(seconds / 60);
|
|
42
|
+
const hours = Math.floor(minutes / 60);
|
|
43
|
+
if (hours > 0) {
|
|
44
|
+
return `${hours}h ${minutes % 60}m`;
|
|
45
|
+
}
|
|
46
|
+
else if (minutes > 0) {
|
|
47
|
+
return `${minutes}m ${seconds % 60}s`;
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
return `${seconds}s`;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
return "unknown";
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
function truncate(str, maxLen) {
|
|
58
|
+
if (!str)
|
|
59
|
+
return "";
|
|
60
|
+
if (str.length <= maxLen)
|
|
61
|
+
return str;
|
|
62
|
+
return str.slice(0, maxLen - 3) + "...";
|
|
63
|
+
}
|
|
64
|
+
function cleanLogLine(line) {
|
|
65
|
+
// Remove ANSI color codes and JSON formatting
|
|
66
|
+
return line
|
|
67
|
+
.replace(/\x1b\[[0-9;]*m/g, "")
|
|
68
|
+
.replace(/^\s*\{.*\}\s*$/, "[JSON output]")
|
|
69
|
+
.trim();
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=AgentCard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AgentCard.js","sourceRoot":"","sources":["../../../src/tui/components/AgentCard.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"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"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from "react";
|
|
3
|
+
import { Box, Text, useApp, useInput } from "ink";
|
|
4
|
+
import { useAgents } from "../hooks/useAgents.js";
|
|
5
|
+
import { AgentCard } from "./AgentCard.js";
|
|
6
|
+
const COLUMNS = [
|
|
7
|
+
{
|
|
8
|
+
id: "running",
|
|
9
|
+
title: "Running",
|
|
10
|
+
statuses: ["running", "in_progress"],
|
|
11
|
+
color: "green",
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
id: "blocked",
|
|
15
|
+
title: "Blocked",
|
|
16
|
+
statuses: ["blocked", "stopped", "failed"],
|
|
17
|
+
color: "red",
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
id: "review",
|
|
21
|
+
title: "Review",
|
|
22
|
+
statuses: ["review", "completed"],
|
|
23
|
+
color: "magenta",
|
|
24
|
+
},
|
|
25
|
+
];
|
|
26
|
+
export function AgentDashboard({ workflowPath }) {
|
|
27
|
+
const { exit } = useApp();
|
|
28
|
+
const { agents, loading, error, refresh } = useAgents(workflowPath);
|
|
29
|
+
const [selectedColumn, setSelectedColumn] = useState(0);
|
|
30
|
+
const [selectedIndex, setSelectedIndex] = useState(0);
|
|
31
|
+
// Get agents for each column
|
|
32
|
+
const getColumnAgents = (column) => {
|
|
33
|
+
return agents.filter((agent) => column.statuses.includes(agent.status));
|
|
34
|
+
};
|
|
35
|
+
// Keyboard navigation
|
|
36
|
+
useInput((input, key) => {
|
|
37
|
+
if (input === "q" || (key.ctrl && input === "c")) {
|
|
38
|
+
exit();
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
if (input === "r") {
|
|
42
|
+
refresh();
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
// Navigate between columns
|
|
46
|
+
if (key.leftArrow) {
|
|
47
|
+
setSelectedColumn((prev) => Math.max(0, prev - 1));
|
|
48
|
+
setSelectedIndex(0);
|
|
49
|
+
}
|
|
50
|
+
if (key.rightArrow) {
|
|
51
|
+
setSelectedColumn((prev) => Math.min(COLUMNS.length - 1, prev + 1));
|
|
52
|
+
setSelectedIndex(0);
|
|
53
|
+
}
|
|
54
|
+
// Navigate within column
|
|
55
|
+
const currentColumn = COLUMNS[selectedColumn];
|
|
56
|
+
const columnAgents = getColumnAgents(currentColumn);
|
|
57
|
+
if (key.upArrow) {
|
|
58
|
+
setSelectedIndex((prev) => Math.max(0, prev - 1));
|
|
59
|
+
}
|
|
60
|
+
if (key.downArrow) {
|
|
61
|
+
setSelectedIndex((prev) => Math.min(columnAgents.length - 1, prev + 1));
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
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) => {
|
|
65
|
+
const columnAgents = getColumnAgents(column);
|
|
66
|
+
const isSelected = colIndex === selectedColumn;
|
|
67
|
+
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));
|
|
68
|
+
}) }), _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" }) })] }));
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=AgentDashboard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AgentDashboard.js","sourceRoot":"","sources":["../../../src/tui/components/AgentDashboard.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"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"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from "react";
|
|
3
|
+
import { Box, useApp, useInput } from "ink";
|
|
4
|
+
import { useFeatures } from "../hooks/useFeatures.js";
|
|
5
|
+
import { KanbanBoard } from "./KanbanBoard.js";
|
|
6
|
+
import { StatusBar } from "./StatusBar.js";
|
|
7
|
+
// Default kanban columns
|
|
8
|
+
const DEFAULT_COLUMNS = [
|
|
9
|
+
{
|
|
10
|
+
id: "backlog",
|
|
11
|
+
title: "Backlog",
|
|
12
|
+
statuses: ["backlog", "pending"],
|
|
13
|
+
color: "gray",
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
id: "planning",
|
|
17
|
+
title: "Planning",
|
|
18
|
+
statuses: ["planning"],
|
|
19
|
+
color: "blue",
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
id: "in_progress",
|
|
23
|
+
title: "In Progress",
|
|
24
|
+
statuses: ["in_progress", "in-progress"],
|
|
25
|
+
color: "yellow",
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
id: "review",
|
|
29
|
+
title: "Review",
|
|
30
|
+
statuses: ["review"],
|
|
31
|
+
color: "magenta",
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
id: "completed",
|
|
35
|
+
title: "Completed",
|
|
36
|
+
statuses: ["completed"],
|
|
37
|
+
color: "green",
|
|
38
|
+
},
|
|
39
|
+
];
|
|
40
|
+
export function App({ workflowPath }) {
|
|
41
|
+
const { exit } = useApp();
|
|
42
|
+
const { features, loading, error, refresh } = useFeatures(workflowPath);
|
|
43
|
+
const [selectedColumn, setSelectedColumn] = useState(0);
|
|
44
|
+
const [selectedFeature, setSelectedFeature] = useState(0);
|
|
45
|
+
// Keyboard navigation
|
|
46
|
+
useInput((input, key) => {
|
|
47
|
+
if (input === "q" || (key.ctrl && input === "c")) {
|
|
48
|
+
exit();
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
if (input === "r") {
|
|
52
|
+
refresh();
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
// Navigate columns
|
|
56
|
+
if (key.leftArrow) {
|
|
57
|
+
setSelectedColumn((prev) => Math.max(0, prev - 1));
|
|
58
|
+
setSelectedFeature(0);
|
|
59
|
+
}
|
|
60
|
+
if (key.rightArrow) {
|
|
61
|
+
setSelectedColumn((prev) => Math.min(DEFAULT_COLUMNS.length - 1, prev + 1));
|
|
62
|
+
setSelectedFeature(0);
|
|
63
|
+
}
|
|
64
|
+
// Navigate features within column
|
|
65
|
+
const currentColumn = DEFAULT_COLUMNS[selectedColumn];
|
|
66
|
+
const columnFeatures = features.filter((f) => currentColumn.statuses.includes(f.status));
|
|
67
|
+
if (key.upArrow) {
|
|
68
|
+
setSelectedFeature((prev) => Math.max(0, prev - 1));
|
|
69
|
+
}
|
|
70
|
+
if (key.downArrow) {
|
|
71
|
+
setSelectedFeature((prev) => Math.min(columnFeatures.length - 1, prev + 1));
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
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 })] }));
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=App.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"App.js","sourceRoot":"","sources":["../../../src/tui/components/App.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Feature } from "../types.js";
|
|
2
|
+
interface FeatureCardProps {
|
|
3
|
+
feature: Feature;
|
|
4
|
+
isSelected: boolean;
|
|
5
|
+
}
|
|
6
|
+
export declare function FeatureCard({ feature, isSelected }: FeatureCardProps): import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export {};
|
|
8
|
+
//# sourceMappingURL=FeatureCard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Text } from "ink";
|
|
3
|
+
const priorityColors = {
|
|
4
|
+
critical: "red",
|
|
5
|
+
high: "yellow",
|
|
6
|
+
medium: "blue",
|
|
7
|
+
low: "gray",
|
|
8
|
+
};
|
|
9
|
+
const statusIcons = {
|
|
10
|
+
pending: "○",
|
|
11
|
+
backlog: "○",
|
|
12
|
+
planning: "◐",
|
|
13
|
+
in_progress: "●",
|
|
14
|
+
"in-progress": "●",
|
|
15
|
+
review: "◉",
|
|
16
|
+
completed: "✓",
|
|
17
|
+
};
|
|
18
|
+
export function FeatureCard({ feature, isSelected }) {
|
|
19
|
+
const icon = statusIcons[feature.status] || "○";
|
|
20
|
+
const priorityColor = priorityColors[feature.priority || "medium"] || "white";
|
|
21
|
+
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" })] }));
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=FeatureCard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Feature, KanbanColumn } from "../types.js";
|
|
2
|
+
interface KanbanBoardProps {
|
|
3
|
+
features: Feature[];
|
|
4
|
+
columns: KanbanColumn[];
|
|
5
|
+
selectedColumn: number;
|
|
6
|
+
selectedFeature: number;
|
|
7
|
+
}
|
|
8
|
+
export declare function KanbanBoard({ features, columns, selectedColumn, selectedFeature, }: KanbanBoardProps): import("react/jsx-runtime").JSX.Element;
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=KanbanBoard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Text } from "ink";
|
|
3
|
+
import { FeatureCard } from "./FeatureCard.js";
|
|
4
|
+
export function KanbanBoard({ features, columns, selectedColumn, selectedFeature, }) {
|
|
5
|
+
return (_jsx(Box, { flexDirection: "row", width: "100%", children: columns.map((column, colIndex) => {
|
|
6
|
+
const columnFeatures = features.filter((f) => column.statuses.includes(f.status));
|
|
7
|
+
const isColumnSelected = colIndex === selectedColumn;
|
|
8
|
+
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));
|
|
9
|
+
}) }));
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=KanbanBoard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
interface StatusBarProps {
|
|
2
|
+
featureCount: number;
|
|
3
|
+
loading: boolean;
|
|
4
|
+
error?: string | null;
|
|
5
|
+
}
|
|
6
|
+
export declare function StatusBar({ featureCount, loading, error }: StatusBarProps): import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export {};
|
|
8
|
+
//# sourceMappingURL=StatusBar.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Text } from "ink";
|
|
3
|
+
export function StatusBar({ featureCount, loading, error }) {
|
|
4
|
+
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" }) })] }));
|
|
5
|
+
}
|
|
6
|
+
//# sourceMappingURL=StatusBar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export interface Agent {
|
|
2
|
+
id: string;
|
|
3
|
+
worktree_path: string;
|
|
4
|
+
pid: number;
|
|
5
|
+
started_at: string;
|
|
6
|
+
name: string;
|
|
7
|
+
status: "running" | "in_progress" | "blocked" | "completed" | "review" | "failed" | "stopped";
|
|
8
|
+
branch?: string;
|
|
9
|
+
current_phase: number;
|
|
10
|
+
priority?: string;
|
|
11
|
+
pr_url?: string;
|
|
12
|
+
is_alive: boolean;
|
|
13
|
+
log_file: string;
|
|
14
|
+
last_log_lines: string[];
|
|
15
|
+
error?: string;
|
|
16
|
+
}
|
|
17
|
+
interface UseAgentsResult {
|
|
18
|
+
agents: Agent[];
|
|
19
|
+
loading: boolean;
|
|
20
|
+
error: string | null;
|
|
21
|
+
refresh: () => Promise<void>;
|
|
22
|
+
}
|
|
23
|
+
export declare function useAgents(workflowPath?: string): UseAgentsResult;
|
|
24
|
+
export {};
|
|
25
|
+
//# sourceMappingURL=useAgents.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"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"}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import { useState, useEffect, useCallback } from "react";
|
|
2
|
+
import { readFile, readdir } from "fs/promises";
|
|
3
|
+
import { join } from "path";
|
|
4
|
+
export function useAgents(workflowPath) {
|
|
5
|
+
const [agents, setAgents] = useState([]);
|
|
6
|
+
const [loading, setLoading] = useState(true);
|
|
7
|
+
const [error, setError] = useState(null);
|
|
8
|
+
const basePath = workflowPath || process.cwd();
|
|
9
|
+
const loadAgents = useCallback(async () => {
|
|
10
|
+
setLoading(true);
|
|
11
|
+
setError(null);
|
|
12
|
+
try {
|
|
13
|
+
// Find developer name from .developer file
|
|
14
|
+
const developerFile = join(basePath, "workflow", ".developer");
|
|
15
|
+
let developer = "unknown";
|
|
16
|
+
try {
|
|
17
|
+
const content = await readFile(developerFile, "utf-8");
|
|
18
|
+
const match = content.match(/^name=(.+)$/m);
|
|
19
|
+
if (match) {
|
|
20
|
+
developer = match[1].trim();
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
// .developer not found, try to find any agent-progress directory
|
|
25
|
+
const agentProgressDir = join(basePath, "workflow", "agent-progress");
|
|
26
|
+
try {
|
|
27
|
+
const dirs = await readdir(agentProgressDir);
|
|
28
|
+
if (dirs.length > 0 && !dirs[0].startsWith(".")) {
|
|
29
|
+
developer = dirs[0];
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
// No agent-progress directory
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
// Read registry.json (just contains worktree locations)
|
|
37
|
+
const registryPath = join(basePath, "workflow", "agent-progress", developer, ".agents", "registry.json");
|
|
38
|
+
let registryData = { agents: [] };
|
|
39
|
+
try {
|
|
40
|
+
const content = await readFile(registryPath, "utf-8");
|
|
41
|
+
registryData = JSON.parse(content);
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
// Registry doesn't exist yet
|
|
45
|
+
}
|
|
46
|
+
// For each registry entry, read status from worktree/.feature/
|
|
47
|
+
const enrichedAgents = await Promise.all(registryData.agents.map(async (entry) => {
|
|
48
|
+
const agent = {
|
|
49
|
+
// From registry
|
|
50
|
+
id: entry.id,
|
|
51
|
+
worktree_path: entry.worktree_path,
|
|
52
|
+
pid: entry.pid,
|
|
53
|
+
started_at: entry.started_at,
|
|
54
|
+
// Defaults (will be overwritten)
|
|
55
|
+
name: entry.id,
|
|
56
|
+
status: "running",
|
|
57
|
+
current_phase: 1,
|
|
58
|
+
is_alive: false,
|
|
59
|
+
log_file: join(entry.worktree_path, ".agent-log"),
|
|
60
|
+
last_log_lines: [],
|
|
61
|
+
};
|
|
62
|
+
// Check if PID is alive
|
|
63
|
+
agent.is_alive = isPidAlive(entry.pid);
|
|
64
|
+
// Read feature.json from worktree/.feature/
|
|
65
|
+
try {
|
|
66
|
+
const featureJsonPath = join(entry.worktree_path, ".feature", "feature.json");
|
|
67
|
+
const featureContent = await readFile(featureJsonPath, "utf-8");
|
|
68
|
+
const featureJson = JSON.parse(featureContent);
|
|
69
|
+
agent.name = featureJson.name || entry.id;
|
|
70
|
+
agent.status = normalizeStatus(featureJson.status);
|
|
71
|
+
agent.branch = featureJson.branch;
|
|
72
|
+
agent.current_phase = featureJson.current_phase || 1;
|
|
73
|
+
agent.priority = featureJson.priority;
|
|
74
|
+
agent.pr_url = featureJson.pr_url;
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
// Can't read feature.json
|
|
78
|
+
}
|
|
79
|
+
// Get last few lines of log (needed for status detection)
|
|
80
|
+
try {
|
|
81
|
+
const logContent = await readFile(agent.log_file, "utf-8");
|
|
82
|
+
const lines = logContent.split("\n").filter((l) => l.trim());
|
|
83
|
+
agent.last_log_lines = lines.slice(-10); // Read more lines to find success marker
|
|
84
|
+
}
|
|
85
|
+
catch {
|
|
86
|
+
// Can't read log
|
|
87
|
+
}
|
|
88
|
+
// If process is dead but status is still "running/in_progress"
|
|
89
|
+
// Check log to see if it completed successfully
|
|
90
|
+
if (!agent.is_alive &&
|
|
91
|
+
(agent.status === "running" || agent.status === "in_progress")) {
|
|
92
|
+
// Check if log indicates successful completion
|
|
93
|
+
const lastLines = agent.last_log_lines.join("\n");
|
|
94
|
+
if (lastLines.includes('"subtype":"success"')) {
|
|
95
|
+
agent.status = "completed";
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
agent.status = "stopped";
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
// Read blocked.json if exists
|
|
102
|
+
try {
|
|
103
|
+
const blockedPath = join(entry.worktree_path, ".feature", "blocked.json");
|
|
104
|
+
const blockedContent = await readFile(blockedPath, "utf-8");
|
|
105
|
+
const blockedJson = JSON.parse(blockedContent);
|
|
106
|
+
agent.error = blockedJson.message;
|
|
107
|
+
if (blockedJson.type === "blocked") {
|
|
108
|
+
agent.status = "blocked";
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
catch {
|
|
112
|
+
// No blocked.json
|
|
113
|
+
}
|
|
114
|
+
return agent;
|
|
115
|
+
}));
|
|
116
|
+
setAgents(enrichedAgents);
|
|
117
|
+
}
|
|
118
|
+
catch (err) {
|
|
119
|
+
setError(err instanceof Error ? err.message : "Failed to load agents");
|
|
120
|
+
}
|
|
121
|
+
finally {
|
|
122
|
+
setLoading(false);
|
|
123
|
+
}
|
|
124
|
+
}, [basePath]);
|
|
125
|
+
// Initial load
|
|
126
|
+
useEffect(() => {
|
|
127
|
+
loadAgents();
|
|
128
|
+
}, [loadAgents]);
|
|
129
|
+
// Auto-refresh every 1 second
|
|
130
|
+
useEffect(() => {
|
|
131
|
+
const interval = setInterval(loadAgents, 1000);
|
|
132
|
+
return () => clearInterval(interval);
|
|
133
|
+
}, [loadAgents]);
|
|
134
|
+
return {
|
|
135
|
+
agents,
|
|
136
|
+
loading,
|
|
137
|
+
error,
|
|
138
|
+
refresh: loadAgents,
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
function isPidAlive(pid) {
|
|
142
|
+
try {
|
|
143
|
+
process.kill(pid, 0);
|
|
144
|
+
return true;
|
|
145
|
+
}
|
|
146
|
+
catch {
|
|
147
|
+
return false;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
function normalizeStatus(status) {
|
|
151
|
+
const statusMap = {
|
|
152
|
+
running: "running",
|
|
153
|
+
in_progress: "in_progress",
|
|
154
|
+
"in-progress": "in_progress",
|
|
155
|
+
blocked: "blocked",
|
|
156
|
+
completed: "completed",
|
|
157
|
+
done: "completed",
|
|
158
|
+
review: "review",
|
|
159
|
+
failed: "failed",
|
|
160
|
+
stopped: "stopped",
|
|
161
|
+
planning: "running",
|
|
162
|
+
};
|
|
163
|
+
return statusMap[status?.toLowerCase()] || "running";
|
|
164
|
+
}
|
|
165
|
+
//# sourceMappingURL=useAgents.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useAgents.js","sourceRoot":"","sources":["../../../src/tui/hooks/useAgents.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AACzD,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAyD5B,MAAM,UAAU,SAAS,CAAC,YAAqB;IAC7C,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAU,EAAE,CAAC,CAAC;IAClD,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC7C,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAgB,IAAI,CAAC,CAAC;IAExD,MAAM,QAAQ,GAAG,YAAY,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IAE/C,MAAM,UAAU,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE;QACxC,UAAU,CAAC,IAAI,CAAC,CAAC;QACjB,QAAQ,CAAC,IAAI,CAAC,CAAC;QAEf,IAAI,CAAC;YACH,2CAA2C;YAC3C,MAAM,aAAa,GAAG,IAAI,CAAC,QAAQ,EAAE,UAAU,EAAE,YAAY,CAAC,CAAC;YAC/D,IAAI,SAAS,GAAG,SAAS,CAAC;YAE1B,IAAI,CAAC;gBACH,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;gBACvD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;gBAC5C,IAAI,KAAK,EAAE,CAAC;oBACV,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;gBAC9B,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,iEAAiE;gBACjE,MAAM,gBAAgB,GAAG,IAAI,CAAC,QAAQ,EAAE,UAAU,EAAE,gBAAgB,CAAC,CAAC;gBACtE,IAAI,CAAC;oBACH,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,gBAAgB,CAAC,CAAC;oBAC7C,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;wBAChD,SAAS,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;oBACtB,CAAC;gBACH,CAAC;gBAAC,MAAM,CAAC;oBACP,8BAA8B;gBAChC,CAAC;YACH,CAAC;YAED,wDAAwD;YACxD,MAAM,YAAY,GAAG,IAAI,CACvB,QAAQ,EACR,UAAU,EACV,gBAAgB,EAChB,SAAS,EACT,SAAS,EACT,eAAe,CAChB,CAAC;YAEF,IAAI,YAAY,GAAgC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;YAE/D,IAAI,CAAC;gBACH,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;gBACtD,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YACrC,CAAC;YAAC,MAAM,CAAC;gBACP,6BAA6B;YAC/B,CAAC;YAED,+DAA+D;YAC/D,MAAM,cAAc,GAAG,MAAM,OAAO,CAAC,GAAG,CACtC,YAAY,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;gBACtC,MAAM,KAAK,GAAU;oBACnB,gBAAgB;oBAChB,EAAE,EAAE,KAAK,CAAC,EAAE;oBACZ,aAAa,EAAE,KAAK,CAAC,aAAa;oBAClC,GAAG,EAAE,KAAK,CAAC,GAAG;oBACd,UAAU,EAAE,KAAK,CAAC,UAAU;oBAC5B,iCAAiC;oBACjC,IAAI,EAAE,KAAK,CAAC,EAAE;oBACd,MAAM,EAAE,SAAS;oBACjB,aAAa,EAAE,CAAC;oBAChB,QAAQ,EAAE,KAAK;oBACf,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,aAAa,EAAE,YAAY,CAAC;oBACjD,cAAc,EAAE,EAAE;iBACnB,CAAC;gBAEF,wBAAwB;gBACxB,KAAK,CAAC,QAAQ,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gBAEvC,4CAA4C;gBAC5C,IAAI,CAAC;oBACH,MAAM,eAAe,GAAG,IAAI,CAC1B,KAAK,CAAC,aAAa,EACnB,UAAU,EACV,cAAc,CACf,CAAC;oBACF,MAAM,cAAc,GAAG,MAAM,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC;oBAChE,MAAM,WAAW,GAAgB,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;oBAE5D,KAAK,CAAC,IAAI,GAAG,WAAW,CAAC,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC;oBAC1C,KAAK,CAAC,MAAM,GAAG,eAAe,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;oBACnD,KAAK,CAAC,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC;oBAClC,KAAK,CAAC,aAAa,GAAG,WAAW,CAAC,aAAa,IAAI,CAAC,CAAC;oBACrD,KAAK,CAAC,QAAQ,GAAG,WAAW,CAAC,QAAQ,CAAC;oBACtC,KAAK,CAAC,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC;gBACpC,CAAC;gBAAC,MAAM,CAAC;oBACP,0BAA0B;gBAC5B,CAAC;gBAED,0DAA0D;gBAC1D,IAAI,CAAC;oBACH,MAAM,UAAU,GAAG,MAAM,QAAQ,CAAC,KAAK,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;oBAC3D,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;oBAC7D,KAAK,CAAC,cAAc,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,yCAAyC;gBACpF,CAAC;gBAAC,MAAM,CAAC;oBACP,iBAAiB;gBACnB,CAAC;gBAED,+DAA+D;gBAC/D,gDAAgD;gBAChD,IACE,CAAC,KAAK,CAAC,QAAQ;oBACf,CAAC,KAAK,CAAC,MAAM,KAAK,SAAS,IAAI,KAAK,CAAC,MAAM,KAAK,aAAa,CAAC,EAC9D,CAAC;oBACD,+CAA+C;oBAC/C,MAAM,SAAS,GAAG,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;oBAClD,IAAI,SAAS,CAAC,QAAQ,CAAC,qBAAqB,CAAC,EAAE,CAAC;wBAC9C,KAAK,CAAC,MAAM,GAAG,WAAW,CAAC;oBAC7B,CAAC;yBAAM,CAAC;wBACN,KAAK,CAAC,MAAM,GAAG,SAAS,CAAC;oBAC3B,CAAC;gBACH,CAAC;gBAED,8BAA8B;gBAC9B,IAAI,CAAC;oBACH,MAAM,WAAW,GAAG,IAAI,CACtB,KAAK,CAAC,aAAa,EACnB,UAAU,EACV,cAAc,CACf,CAAC;oBACF,MAAM,cAAc,GAAG,MAAM,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;oBAC5D,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;oBAC/C,KAAK,CAAC,KAAK,GAAG,WAAW,CAAC,OAAO,CAAC;oBAClC,IAAI,WAAW,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;wBACnC,KAAK,CAAC,MAAM,GAAG,SAAS,CAAC;oBAC3B,CAAC;gBACH,CAAC;gBAAC,MAAM,CAAC;oBACP,kBAAkB;gBACpB,CAAC;gBAED,OAAO,KAAK,CAAC;YACf,CAAC,CAAC,CACH,CAAC;YAEF,SAAS,CAAC,cAAc,CAAC,CAAC;QAC5B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,QAAQ,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC;QACzE,CAAC;gBAAS,CAAC;YACT,UAAU,CAAC,KAAK,CAAC,CAAC;QACpB,CAAC;IACH,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;IAEf,eAAe;IACf,SAAS,CAAC,GAAG,EAAE;QACb,UAAU,EAAE,CAAC;IACf,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC;IAEjB,8BAA8B;IAC9B,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,QAAQ,GAAG,WAAW,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;QAC/C,OAAO,GAAG,EAAE,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;IACvC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC;IAEjB,OAAO;QACL,MAAM;QACN,OAAO;QACP,KAAK;QACL,OAAO,EAAE,UAAU;KACpB,CAAC;AACJ,CAAC;AAED,SAAS,UAAU,CAAC,GAAW;IAC7B,IAAI,CAAC;QACH,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACrB,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,SAAS,eAAe,CAAC,MAAc;IACrC,MAAM,SAAS,GAAoC;QACjD,OAAO,EAAE,SAAS;QAClB,WAAW,EAAE,aAAa;QAC1B,aAAa,EAAE,aAAa;QAC5B,OAAO,EAAE,SAAS;QAClB,SAAS,EAAE,WAAW;QACtB,IAAI,EAAE,WAAW;QACjB,MAAM,EAAE,QAAQ;QAChB,MAAM,EAAE,QAAQ;QAChB,OAAO,EAAE,SAAS;QAClB,QAAQ,EAAE,SAAS;KACpB,CAAC;IACF,OAAO,SAAS,CAAC,MAAM,EAAE,WAAW,EAAE,CAAC,IAAI,SAAS,CAAC;AACvD,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Feature } from "../types.js";
|
|
2
|
+
interface UseFeaturesResult {
|
|
3
|
+
features: Feature[];
|
|
4
|
+
loading: boolean;
|
|
5
|
+
error: string | null;
|
|
6
|
+
refresh: () => Promise<void>;
|
|
7
|
+
}
|
|
8
|
+
export declare function useFeatures(workflowPath?: string): UseFeaturesResult;
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=useFeatures.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"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"}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { useState, useEffect } from "react";
|
|
2
|
+
import { readFile, readdir, stat } from "fs/promises";
|
|
3
|
+
import { join } from "path";
|
|
4
|
+
export function useFeatures(workflowPath) {
|
|
5
|
+
const [features, setFeatures] = useState([]);
|
|
6
|
+
const [loading, setLoading] = useState(true);
|
|
7
|
+
const [error, setError] = useState(null);
|
|
8
|
+
const basePath = workflowPath || process.cwd();
|
|
9
|
+
const loadFeatures = async () => {
|
|
10
|
+
setLoading(true);
|
|
11
|
+
setError(null);
|
|
12
|
+
try {
|
|
13
|
+
// Search in workflow/agent-progress/*/features/ (actual structure)
|
|
14
|
+
const agentProgressDir = join(basePath, "workflow", "agent-progress");
|
|
15
|
+
const featureFiles = await findAllFeatureFiles(agentProgressDir);
|
|
16
|
+
const loadedFeatures = [];
|
|
17
|
+
for (const filePath of featureFiles) {
|
|
18
|
+
try {
|
|
19
|
+
const content = await readFile(filePath, "utf-8");
|
|
20
|
+
const data = JSON.parse(content);
|
|
21
|
+
// Normalize the feature data
|
|
22
|
+
const feature = {
|
|
23
|
+
id: data.id || data.name || "unknown",
|
|
24
|
+
name: data.name || data.id || "Unnamed Feature",
|
|
25
|
+
status: normalizeStatus(data.status),
|
|
26
|
+
branch: data.branch,
|
|
27
|
+
priority: data.priority || "medium",
|
|
28
|
+
developer: data.developer,
|
|
29
|
+
created_at: data.created_at,
|
|
30
|
+
pr_url: data.pr_url,
|
|
31
|
+
next_action: data.next_action,
|
|
32
|
+
current_phase: data.current_phase,
|
|
33
|
+
};
|
|
34
|
+
loadedFeatures.push(feature);
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
// Skip files that can't be parsed
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
// Sort by priority (critical > high > medium > low)
|
|
41
|
+
const priorityOrder = { critical: 0, high: 1, medium: 2, low: 3 };
|
|
42
|
+
loadedFeatures.sort((a, b) => (priorityOrder[a.priority || "medium"] || 2) -
|
|
43
|
+
(priorityOrder[b.priority || "medium"] || 2));
|
|
44
|
+
setFeatures(loadedFeatures);
|
|
45
|
+
}
|
|
46
|
+
catch (err) {
|
|
47
|
+
setError(err instanceof Error ? err.message : "Failed to load features");
|
|
48
|
+
}
|
|
49
|
+
finally {
|
|
50
|
+
setLoading(false);
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
useEffect(() => {
|
|
54
|
+
loadFeatures();
|
|
55
|
+
}, [basePath]);
|
|
56
|
+
return {
|
|
57
|
+
features,
|
|
58
|
+
loading,
|
|
59
|
+
error,
|
|
60
|
+
refresh: loadFeatures,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
// Find all feature.json files in workflow/agent-progress/*/features/
|
|
64
|
+
async function findAllFeatureFiles(agentProgressDir) {
|
|
65
|
+
const results = [];
|
|
66
|
+
try {
|
|
67
|
+
// List all user directories (e.g., taosu, other-dev)
|
|
68
|
+
const users = await readdir(agentProgressDir);
|
|
69
|
+
for (const user of users) {
|
|
70
|
+
const userFeaturesDir = join(agentProgressDir, user, "features");
|
|
71
|
+
const userFeatures = await findFeatureFilesRecursive(userFeaturesDir);
|
|
72
|
+
results.push(...userFeatures);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
// Directory doesn't exist
|
|
77
|
+
}
|
|
78
|
+
return results;
|
|
79
|
+
}
|
|
80
|
+
// Recursively find feature.json files, skipping archive
|
|
81
|
+
async function findFeatureFilesRecursive(dir) {
|
|
82
|
+
const results = [];
|
|
83
|
+
try {
|
|
84
|
+
const entries = await readdir(dir);
|
|
85
|
+
for (const entry of entries) {
|
|
86
|
+
// Skip archive and node_modules
|
|
87
|
+
if (entry === "archive" || entry === "node_modules") {
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
const fullPath = join(dir, entry);
|
|
91
|
+
const entryStat = await stat(fullPath);
|
|
92
|
+
if (entryStat.isDirectory()) {
|
|
93
|
+
// Check for feature.json in this directory
|
|
94
|
+
const featureJsonPath = join(fullPath, "feature.json");
|
|
95
|
+
try {
|
|
96
|
+
await stat(featureJsonPath);
|
|
97
|
+
results.push(featureJsonPath);
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
// No feature.json here, recurse into subdirectory
|
|
101
|
+
const subResults = await findFeatureFilesRecursive(fullPath);
|
|
102
|
+
results.push(...subResults);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
catch {
|
|
108
|
+
// Directory doesn't exist or can't be read
|
|
109
|
+
}
|
|
110
|
+
return results;
|
|
111
|
+
}
|
|
112
|
+
function normalizeStatus(status) {
|
|
113
|
+
const statusMap = {
|
|
114
|
+
pending: "pending",
|
|
115
|
+
backlog: "backlog",
|
|
116
|
+
planning: "planning",
|
|
117
|
+
in_progress: "in_progress",
|
|
118
|
+
"in-progress": "in_progress",
|
|
119
|
+
inprogress: "in_progress",
|
|
120
|
+
review: "review",
|
|
121
|
+
completed: "completed",
|
|
122
|
+
done: "completed",
|
|
123
|
+
};
|
|
124
|
+
return statusMap[status?.toLowerCase()] || "pending";
|
|
125
|
+
}
|
|
126
|
+
//# sourceMappingURL=useFeatures.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useFeatures.js","sourceRoot":"","sources":["../../../src/tui/hooks/useFeatures.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export { AgentDashboard } from "./components/AgentDashboard.js";
|
|
2
|
+
export { AgentCard } from "./components/AgentCard.js";
|
|
3
|
+
export { App } from "./components/App.js";
|
|
4
|
+
export { KanbanBoard } from "./components/KanbanBoard.js";
|
|
5
|
+
export { FeatureCard } from "./components/FeatureCard.js";
|
|
6
|
+
export { StatusBar } from "./components/StatusBar.js";
|
|
7
|
+
export { useAgents } from "./hooks/useAgents.js";
|
|
8
|
+
export { useFeatures } from "./hooks/useFeatures.js";
|
|
9
|
+
export type { Agent } from "./hooks/useAgents.js";
|
|
10
|
+
export type { Feature, FeatureStatus, PhaseAction, KanbanColumn, DashboardState, } from "./types.js";
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// TUI components
|
|
2
|
+
export { AgentDashboard } from "./components/AgentDashboard.js";
|
|
3
|
+
export { AgentCard } from "./components/AgentCard.js";
|
|
4
|
+
// Legacy components (for feature.json based view)
|
|
5
|
+
export { App } from "./components/App.js";
|
|
6
|
+
export { KanbanBoard } from "./components/KanbanBoard.js";
|
|
7
|
+
export { FeatureCard } from "./components/FeatureCard.js";
|
|
8
|
+
export { StatusBar } from "./components/StatusBar.js";
|
|
9
|
+
// Hooks
|
|
10
|
+
export { useAgents } from "./hooks/useAgents.js";
|
|
11
|
+
export { useFeatures } from "./hooks/useFeatures.js";
|
|
12
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export type FeatureStatus = "pending" | "in_progress" | "in-progress" | "review" | "completed" | "backlog" | "planning";
|
|
2
|
+
export interface Feature {
|
|
3
|
+
id: string;
|
|
4
|
+
name: string;
|
|
5
|
+
status: FeatureStatus;
|
|
6
|
+
branch?: string;
|
|
7
|
+
priority?: "low" | "medium" | "high" | "critical";
|
|
8
|
+
developer?: string;
|
|
9
|
+
created_at?: string;
|
|
10
|
+
pr_url?: string;
|
|
11
|
+
next_action?: PhaseAction[];
|
|
12
|
+
current_phase?: number;
|
|
13
|
+
}
|
|
14
|
+
export interface PhaseAction {
|
|
15
|
+
phase: number;
|
|
16
|
+
action: string;
|
|
17
|
+
target: string;
|
|
18
|
+
detail?: string;
|
|
19
|
+
}
|
|
20
|
+
export interface KanbanColumn {
|
|
21
|
+
id: string;
|
|
22
|
+
title: string;
|
|
23
|
+
statuses: FeatureStatus[];
|
|
24
|
+
color: string;
|
|
25
|
+
}
|
|
26
|
+
export interface DashboardState {
|
|
27
|
+
features: Feature[];
|
|
28
|
+
selectedColumn: number;
|
|
29
|
+
selectedFeature: number;
|
|
30
|
+
loading: boolean;
|
|
31
|
+
error?: string;
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/tui/types.ts"],"names":[],"mappings":""}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mind-fold/open-flow",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.19",
|
|
4
4
|
"description": "AI-assisted development workflow initializer for Cursor, Claude Code and more",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -37,11 +37,16 @@
|
|
|
37
37
|
"dependencies": {
|
|
38
38
|
"chalk": "^5.3.0",
|
|
39
39
|
"commander": "^12.1.0",
|
|
40
|
-
"
|
|
40
|
+
"ink": "^6.0.0",
|
|
41
|
+
"ink-select-input": "^6.2.0",
|
|
42
|
+
"ink-spinner": "^5.0.0",
|
|
43
|
+
"inquirer": "^9.3.7",
|
|
44
|
+
"react": "^19.2.3"
|
|
41
45
|
},
|
|
42
46
|
"devDependencies": {
|
|
43
47
|
"@types/inquirer": "^9.0.7",
|
|
44
48
|
"@types/node": "^20.17.10",
|
|
49
|
+
"@types/react": "^19.2.7",
|
|
45
50
|
"typescript": "^5.7.2"
|
|
46
51
|
},
|
|
47
52
|
"engines": {
|