fecode-cli 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/App.d.ts +33 -0
- package/dist/App.js +2224 -0
- package/dist/approvalResolver.d.ts +12 -0
- package/dist/approvalResolver.js +112 -0
- package/dist/commands.d.ts +11 -0
- package/dist/commands.js +33 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +15175 -0
- package/dist/ui/AppShell.d.ts +14 -0
- package/dist/ui/AppShell.js +25 -0
- package/dist/ui/ApprovalPrompt.d.ts +31 -0
- package/dist/ui/ApprovalPrompt.js +55 -0
- package/dist/ui/BlockedView.d.ts +13 -0
- package/dist/ui/BlockedView.js +7 -0
- package/dist/ui/CommandPalette.d.ts +8 -0
- package/dist/ui/CommandPalette.js +18 -0
- package/dist/ui/CurrentStepView.d.ts +16 -0
- package/dist/ui/CurrentStepView.js +28 -0
- package/dist/ui/DiagnosticsView.d.ts +45 -0
- package/dist/ui/DiagnosticsView.js +23 -0
- package/dist/ui/ExecutionTimeline.d.ts +15 -0
- package/dist/ui/ExecutionTimeline.js +51 -0
- package/dist/ui/ExecutionView.d.ts +42 -0
- package/dist/ui/ExecutionView.js +20 -0
- package/dist/ui/Header.d.ts +15 -0
- package/dist/ui/Header.js +47 -0
- package/dist/ui/HelpView.d.ts +3 -0
- package/dist/ui/HelpView.js +35 -0
- package/dist/ui/MessageBubble.d.ts +9 -0
- package/dist/ui/MessageBubble.js +58 -0
- package/dist/ui/PlanStep.d.ts +16 -0
- package/dist/ui/PlanStep.js +71 -0
- package/dist/ui/PlanView.d.ts +26 -0
- package/dist/ui/PlanView.js +24 -0
- package/dist/ui/ProgressBar.d.ts +10 -0
- package/dist/ui/ProgressBar.js +14 -0
- package/dist/ui/RecoveryView.d.ts +20 -0
- package/dist/ui/RecoveryView.js +19 -0
- package/dist/ui/ReplanView.d.ts +16 -0
- package/dist/ui/ReplanView.js +21 -0
- package/dist/ui/ResumeView.d.ts +15 -0
- package/dist/ui/ResumeView.js +25 -0
- package/dist/ui/RiskNotice.d.ts +10 -0
- package/dist/ui/RiskNotice.js +21 -0
- package/dist/ui/RunHistoryView.d.ts +15 -0
- package/dist/ui/RunHistoryView.js +39 -0
- package/dist/ui/StatusBar.d.ts +16 -0
- package/dist/ui/StatusBar.js +104 -0
- package/dist/ui/TaskInput.d.ts +15 -0
- package/dist/ui/TaskInput.js +8 -0
- package/dist/ui/ThinkingBlock.d.ts +8 -0
- package/dist/ui/ThinkingBlock.js +13 -0
- package/dist/ui/ThinkingIndicator.d.ts +7 -0
- package/dist/ui/ThinkingIndicator.js +20 -0
- package/dist/ui/TurnView.d.ts +13 -0
- package/dist/ui/TurnView.js +11 -0
- package/dist/ui/WorkspaceStatus.d.ts +20 -0
- package/dist/ui/WorkspaceStatus.js +23 -0
- package/dist/ui/index.d.ts +26 -0
- package/dist/ui/index.js +26 -0
- package/package.json +42 -0
- package/skills/accessibility/SKILL.md +98 -0
- package/skills/css/SKILL.md +90 -0
- package/skills/frontend-debugging/SKILL.md +201 -0
- package/skills/frontend-design/SKILL.md +358 -0
- package/skills/frontend-performance/SKILL.md +89 -0
- package/skills/frontend-testing/SKILL.md +87 -0
- package/skills/nextjs/SKILL.md +75 -0
- package/skills/react/SKILL.md +213 -0
- package/skills/responsive-design/SKILL.md +190 -0
- package/skills/svelte/SKILL.md +86 -0
- package/skills/tailwind/SKILL.md +74 -0
- package/skills/ui-review/SKILL.md +245 -0
- package/skills/vue/SKILL.md +72 -0
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Text } from "ink";
|
|
3
|
+
function parseBlocks(content) {
|
|
4
|
+
const lines = content.split("\n");
|
|
5
|
+
const blocks = [];
|
|
6
|
+
let inCodeBlock = false;
|
|
7
|
+
let codeLang = "";
|
|
8
|
+
let codeLines = [];
|
|
9
|
+
for (let i = 0; i < lines.length; i++) {
|
|
10
|
+
const line = lines[i];
|
|
11
|
+
const trimmed = line.trim();
|
|
12
|
+
if (trimmed.startsWith("```")) {
|
|
13
|
+
if (!inCodeBlock) {
|
|
14
|
+
inCodeBlock = true;
|
|
15
|
+
codeLang = trimmed.replace(/^`+/, "").trim();
|
|
16
|
+
codeLines = [];
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
inCodeBlock = false;
|
|
20
|
+
blocks.push({
|
|
21
|
+
type: "code",
|
|
22
|
+
language: codeLang,
|
|
23
|
+
code: codeLines.join("\n")
|
|
24
|
+
});
|
|
25
|
+
codeLines = [];
|
|
26
|
+
}
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
if (inCodeBlock) {
|
|
30
|
+
codeLines.push(line);
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
blocks.push({ type: "line", text: line });
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
if (inCodeBlock && codeLines.length > 0) {
|
|
37
|
+
blocks.push({
|
|
38
|
+
type: "code",
|
|
39
|
+
language: codeLang,
|
|
40
|
+
code: codeLines.join("\n")
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
return blocks;
|
|
44
|
+
}
|
|
45
|
+
export const MessageBubble = ({ role, content, isStreaming = false, error }) => {
|
|
46
|
+
if (role === "user") {
|
|
47
|
+
return (_jsxs(Box, { flexDirection: "column", marginY: 0, children: [_jsxs(Box, { children: [_jsx(Text, { color: "green", bold: true, children: "\u25B6 " }), _jsx(Text, { color: "green", bold: true, children: "You" })] }), _jsx(Box, { marginLeft: 2, children: _jsx(Text, { color: "whiteBright", bold: true, wrap: "wrap", children: content }) })] }));
|
|
48
|
+
}
|
|
49
|
+
// Agent role
|
|
50
|
+
const blocks = content ? parseBlocks(content) : [];
|
|
51
|
+
return (_jsxs(Box, { flexDirection: "column", marginY: 0, children: [_jsx(Box, { children: _jsx(Text, { color: "cyan", dimColor: true, children: " fecode" }) }), error ? (_jsxs(Box, { borderStyle: "single", borderColor: "red", paddingX: 1, marginLeft: 2, flexDirection: "column", children: [_jsx(Text, { bold: true, color: "red", children: "\u2717 Error" }), _jsx(Text, { color: "red", wrap: "wrap", children: error })] })) : content ? (_jsx(Box, { flexDirection: "column", children: blocks.map((block, i) => {
|
|
52
|
+
if (block.type === "code") {
|
|
53
|
+
return (_jsx(Box, { flexDirection: "column", marginY: 0, children: _jsxs(Box, { children: [_jsx(Text, { color: "cyan", dimColor: true, children: "\u2502 " }), _jsxs(Box, { borderStyle: "round", borderColor: "gray", paddingX: 1, flexDirection: "column", children: [block.language ? (_jsx(Box, { marginBottom: 0, children: _jsxs(Text, { color: "cyan", dimColor: true, bold: true, children: ["[", block.language, "]"] }) })) : null, block.code.split("\n").map((cLine, cIdx) => (_jsx(Text, { color: "whiteBright", children: cLine || " " }, `c-${cIdx}`)))] })] }) }, `block-${i}`));
|
|
54
|
+
}
|
|
55
|
+
return (_jsxs(Box, { children: [_jsx(Text, { color: "cyan", dimColor: true, children: "\u2502 " }), _jsx(Text, { color: "white", wrap: "wrap", children: block.text })] }, `block-${i}`));
|
|
56
|
+
}) })) : isStreaming ? (_jsxs(Box, { children: [_jsx(Text, { color: "cyan", dimColor: true, children: "\u2502 " }), _jsx(Text, { color: "gray", dimColor: true, children: "\u2026" })] })) : null] }));
|
|
57
|
+
};
|
|
58
|
+
//# sourceMappingURL=MessageBubble.js.map
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
export interface PlanStepProps {
|
|
3
|
+
stepIndex: number;
|
|
4
|
+
totalSteps: number;
|
|
5
|
+
title: string;
|
|
6
|
+
status: "pending" | "planned" | "ready" | "in_progress" | "executing" | "verifying" | "waiting" | "waiting_approval" | "completed" | "skipped" | "blocked" | "failed" | string;
|
|
7
|
+
riskLevel?: string;
|
|
8
|
+
dependencies?: string[];
|
|
9
|
+
checkpointRequired?: boolean;
|
|
10
|
+
verificationRequired?: boolean;
|
|
11
|
+
durationMs?: number;
|
|
12
|
+
error?: string;
|
|
13
|
+
objective?: string;
|
|
14
|
+
}
|
|
15
|
+
export declare const PlanStep: React.FC<PlanStepProps>;
|
|
16
|
+
//# sourceMappingURL=PlanStep.d.ts.map
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Text } from "ink";
|
|
3
|
+
export const PlanStep = ({ stepIndex, totalSteps, title, status, riskLevel, dependencies, checkpointRequired, verificationRequired, durationMs, error }) => {
|
|
4
|
+
const getStatusIcon = () => {
|
|
5
|
+
switch (status.toLowerCase()) {
|
|
6
|
+
case "completed":
|
|
7
|
+
case "done":
|
|
8
|
+
return _jsx(Text, { color: "green", children: "\u2713" });
|
|
9
|
+
case "in_progress":
|
|
10
|
+
case "executing":
|
|
11
|
+
return _jsx(Text, { color: "yellow", children: "\u25CF" });
|
|
12
|
+
case "verifying":
|
|
13
|
+
return _jsx(Text, { color: "cyan", children: "\u25CC" });
|
|
14
|
+
case "waiting":
|
|
15
|
+
case "waiting_approval":
|
|
16
|
+
return _jsx(Text, { color: "yellow", children: "\u26A0" });
|
|
17
|
+
case "ready":
|
|
18
|
+
return _jsx(Text, { color: "blue", children: "\u25CC" });
|
|
19
|
+
case "skipped":
|
|
20
|
+
return _jsx(Text, { color: "gray", children: "\u2298" });
|
|
21
|
+
case "blocked":
|
|
22
|
+
return _jsx(Text, { color: "red", children: "!" });
|
|
23
|
+
case "failed":
|
|
24
|
+
return _jsx(Text, { color: "red", children: "\u2717" });
|
|
25
|
+
case "pending":
|
|
26
|
+
case "planned":
|
|
27
|
+
default:
|
|
28
|
+
return _jsx(Text, { color: "gray", children: "\u25CB" });
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
const getStatusLabel = () => {
|
|
32
|
+
switch (status.toLowerCase()) {
|
|
33
|
+
case "completed":
|
|
34
|
+
case "done":
|
|
35
|
+
return _jsx(Text, { color: "green", children: "COMPLETED" });
|
|
36
|
+
case "in_progress":
|
|
37
|
+
case "executing":
|
|
38
|
+
return _jsx(Text, { color: "yellow", children: "EXECUTING" });
|
|
39
|
+
case "verifying":
|
|
40
|
+
return _jsx(Text, { color: "cyan", children: "VERIFYING" });
|
|
41
|
+
case "waiting":
|
|
42
|
+
case "waiting_approval":
|
|
43
|
+
return _jsx(Text, { color: "yellow", children: "WAITING FOR APPROVAL" });
|
|
44
|
+
case "ready":
|
|
45
|
+
return _jsx(Text, { color: "blue", children: "READY" });
|
|
46
|
+
case "skipped":
|
|
47
|
+
return _jsx(Text, { color: "gray", children: "SKIPPED" });
|
|
48
|
+
case "blocked":
|
|
49
|
+
return _jsx(Text, { color: "red", children: "BLOCKED" });
|
|
50
|
+
case "failed":
|
|
51
|
+
return _jsx(Text, { color: "red", children: "FAILED" });
|
|
52
|
+
case "pending":
|
|
53
|
+
case "planned":
|
|
54
|
+
default:
|
|
55
|
+
return _jsx(Text, { color: "gray", children: "PLANNED" });
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
const getRiskBadge = () => {
|
|
59
|
+
if (!riskLevel || riskLevel.toLowerCase() === "low" || riskLevel.toLowerCase() === "normal") {
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
const isCrit = riskLevel.toLowerCase() === "critical";
|
|
63
|
+
return _jsxs(Text, { color: isCrit ? "red" : "yellow", children: [" [", riskLevel.toUpperCase(), "]"] });
|
|
64
|
+
};
|
|
65
|
+
return (_jsxs(Box, { flexDirection: "column", marginY: 0, children: [_jsxs(Box, { children: [_jsxs(Text, { color: "gray", children: ["[", stepIndex, "/", totalSteps, "]", " "] }), getStatusIcon(), _jsx(Text, { children: " " }), _jsx(Text, { bold: status === "in_progress" || status === "executing", color: status === "failed" || status === "blocked"
|
|
66
|
+
? "red"
|
|
67
|
+
: "white", children: title }), getRiskBadge(), _jsx(Text, { color: "gray", children: " \u2014 " }), getStatusLabel(), durationMs !== undefined && durationMs > 0 && (_jsxs(Text, { color: "gray", children: [" ", "(", durationMs >= 1000
|
|
68
|
+
? `${(durationMs / 1000).toFixed(1)}s`
|
|
69
|
+
: `${durationMs}ms`, ")"] }))] }), _jsxs(Box, { marginLeft: 4, children: [checkpointRequired && (_jsx(Text, { color: "yellow", children: "[Checkpoint Required] " })), verificationRequired && (_jsx(Text, { color: "cyan", children: "[Verify Required] " })), dependencies && dependencies.length > 0 && (_jsxs(Text, { color: "gray", children: ["[Deps: ", dependencies.join(", "), "] "] }))] }), error && (_jsx(Box, { marginLeft: 4, children: _jsxs(Text, { color: "red", children: ["Error: ", error] }) }))] }));
|
|
70
|
+
};
|
|
71
|
+
//# sourceMappingURL=PlanStep.js.map
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
export interface PlanStepItem {
|
|
3
|
+
stepId: string;
|
|
4
|
+
order: number;
|
|
5
|
+
title: string;
|
|
6
|
+
objective?: string;
|
|
7
|
+
status: string;
|
|
8
|
+
riskLevel?: string;
|
|
9
|
+
dependencies?: string[];
|
|
10
|
+
checkpointRequired?: boolean;
|
|
11
|
+
verificationRequired?: boolean;
|
|
12
|
+
durationMs?: number;
|
|
13
|
+
error?: string;
|
|
14
|
+
}
|
|
15
|
+
export interface PlanViewProps {
|
|
16
|
+
planId?: string;
|
|
17
|
+
objective?: string;
|
|
18
|
+
summary?: string;
|
|
19
|
+
status?: string;
|
|
20
|
+
riskLevel?: string;
|
|
21
|
+
steps?: PlanStepItem[];
|
|
22
|
+
completedCount?: number;
|
|
23
|
+
totalCount?: number;
|
|
24
|
+
}
|
|
25
|
+
export declare const PlanView: React.FC<PlanViewProps>;
|
|
26
|
+
//# sourceMappingURL=PlanView.d.ts.map
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Text } from "ink";
|
|
3
|
+
import { PlanStep } from "./PlanStep.js";
|
|
4
|
+
import { ProgressBar } from "./ProgressBar.js";
|
|
5
|
+
export const PlanView = ({ planId, objective, summary, status = "ready", riskLevel, steps = [], completedCount, totalCount }) => {
|
|
6
|
+
const total = totalCount ?? steps.length;
|
|
7
|
+
const completed = completedCount ?? steps.filter((s) => s.status === "completed").length;
|
|
8
|
+
const getRiskColor = (risk) => {
|
|
9
|
+
switch (risk.toLowerCase()) {
|
|
10
|
+
case "critical":
|
|
11
|
+
return "red";
|
|
12
|
+
case "elevated":
|
|
13
|
+
case "high":
|
|
14
|
+
return "yellow";
|
|
15
|
+
case "low":
|
|
16
|
+
return "green";
|
|
17
|
+
case "normal":
|
|
18
|
+
default:
|
|
19
|
+
return "cyan";
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "blue", paddingX: 1, marginY: 1, children: [_jsxs(Box, { justifyContent: "space-between", marginBottom: 0, children: [_jsxs(Box, { children: [_jsxs(Text, { bold: true, color: "blue", children: ["Plan:", " "] }), _jsx(Text, { bold: true, color: "white", children: objective || summary || "Task Plan" }), planId && _jsxs(Text, { color: "gray", children: [" (", planId, ")"] })] }), _jsxs(Box, { children: [riskLevel && (_jsxs(Text, { color: getRiskColor(riskLevel), bold: true, children: ["[", riskLevel.toUpperCase(), "]", " "] })), _jsxs(Text, { color: "gray", children: ["[", completed, "/", total, "] Status:", " "] }), _jsx(Text, { bold: true, color: "cyan", children: status.toUpperCase() })] })] }), _jsx(Box, { marginY: 0, children: _jsx(ProgressBar, { completed: completed, total: total, width: 24 }) }), steps.length > 0 ? (_jsx(Box, { flexDirection: "column", marginTop: 1, children: steps.map((step, idx) => (_jsx(PlanStep, { stepIndex: step.order || idx + 1, totalSteps: total, title: step.title, status: step.status, riskLevel: step.riskLevel, dependencies: step.dependencies, checkpointRequired: step.checkpointRequired, verificationRequired: step.verificationRequired, durationMs: step.durationMs, error: step.error, objective: step.objective }, step.stepId || `step-${idx}`))) })) : (_jsx(Box, { marginTop: 1, children: _jsx(Text, { color: "gray", children: "No steps defined in this plan." }) }))] }));
|
|
23
|
+
};
|
|
24
|
+
//# sourceMappingURL=PlanView.js.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
export interface ProgressBarProps {
|
|
3
|
+
completed: number;
|
|
4
|
+
total: number;
|
|
5
|
+
width?: number;
|
|
6
|
+
showFraction?: boolean;
|
|
7
|
+
showPercentage?: boolean;
|
|
8
|
+
}
|
|
9
|
+
export declare const ProgressBar: React.FC<ProgressBarProps>;
|
|
10
|
+
//# sourceMappingURL=ProgressBar.d.ts.map
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Text } from "ink";
|
|
3
|
+
export const ProgressBar = ({ completed, total, width = 20, showFraction = true, showPercentage = true }) => {
|
|
4
|
+
const safeTotal = Math.max(total, 1);
|
|
5
|
+
const safeCompleted = Math.min(Math.max(completed, 0), safeTotal);
|
|
6
|
+
const fraction = safeCompleted / safeTotal;
|
|
7
|
+
const percentage = Math.round(fraction * 100);
|
|
8
|
+
const filledCount = Math.round(fraction * width);
|
|
9
|
+
const emptyCount = Math.max(0, width - filledCount);
|
|
10
|
+
const filledBar = "█".repeat(filledCount);
|
|
11
|
+
const emptyBar = "░".repeat(emptyCount);
|
|
12
|
+
return (_jsxs(Box, { flexDirection: "row", alignItems: "center", children: [_jsx(Text, { color: "cyan", children: "[" }), _jsx(Text, { color: "green", children: filledBar }), _jsx(Text, { color: "gray", children: emptyBar }), _jsx(Text, { color: "cyan", children: "]" }), showPercentage && _jsxs(Text, { color: "white", children: [" ", percentage, "%"] }), showFraction && (_jsxs(Text, { color: "gray", children: [" ", "(", safeCompleted, "/", safeTotal, " steps)"] }))] }));
|
|
13
|
+
};
|
|
14
|
+
//# sourceMappingURL=ProgressBar.js.map
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
export interface RecoveryStepItem {
|
|
3
|
+
title: string;
|
|
4
|
+
status: "pending" | "running" | "completed" | "failed";
|
|
5
|
+
}
|
|
6
|
+
export interface RecoveryViewProps {
|
|
7
|
+
strategy?: string;
|
|
8
|
+
steps?: RecoveryStepItem[];
|
|
9
|
+
verificationStatus?: "PASSED" | "FAILED" | "PENDING" | string;
|
|
10
|
+
workspaceStatus?: "CONSISTENT" | "INCONSISTENT" | string;
|
|
11
|
+
outcome?: "RECOVERED" | "RECOVERED_WITH_CHANGES" | "STILL_BLOCKED" | "FAILED" | "CANCELLED" | string;
|
|
12
|
+
blockers?: string[];
|
|
13
|
+
remainingStepsCount?: number;
|
|
14
|
+
isAwaitingContinuation?: boolean;
|
|
15
|
+
value: string;
|
|
16
|
+
onChange: (val: string) => void;
|
|
17
|
+
onSubmit: (val: string) => void;
|
|
18
|
+
}
|
|
19
|
+
export declare const RecoveryView: React.FC<RecoveryViewProps>;
|
|
20
|
+
//# sourceMappingURL=RecoveryView.d.ts.map
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Text } from "ink";
|
|
3
|
+
import TextInput from "ink-text-input";
|
|
4
|
+
export const RecoveryView = ({ strategy = "checkpoint_restore", steps = [], verificationStatus, workspaceStatus, outcome, blockers = [], remainingStepsCount, isAwaitingContinuation = false, value, onChange, onSubmit }) => {
|
|
5
|
+
return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "yellow", paddingX: 1, marginY: 1, children: [_jsx(Box, { marginBottom: 0, children: _jsxs(Text, { bold: true, color: "yellow", children: ["Recovery (", strategy, ")"] }) }), steps.length > 0 && (_jsx(Box, { flexDirection: "column", marginTop: 0, children: steps.map((s, idx) => (_jsxs(Box, { children: [_jsxs(Text, { color: s.status === "completed"
|
|
6
|
+
? "green"
|
|
7
|
+
: s.status === "failed"
|
|
8
|
+
? "red"
|
|
9
|
+
: "yellow", children: [s.status === "completed"
|
|
10
|
+
? "✓"
|
|
11
|
+
: s.status === "failed"
|
|
12
|
+
? "✗"
|
|
13
|
+
: "●", " "] }), _jsx(Text, { color: "white", children: s.title })] }, `rec-step-${idx}`))) })), verificationStatus && (_jsxs(Box, { marginTop: 0, children: [_jsx(Text, { color: "gray", children: "Verification: " }), _jsx(Text, { color: verificationStatus.toUpperCase() === "PASSED" ? "green" : "red", bold: true, children: verificationStatus.toUpperCase() })] })), workspaceStatus && (_jsxs(Box, { marginTop: 0, children: [_jsx(Text, { color: "gray", children: "Workspace: " }), _jsx(Text, { color: workspaceStatus.toUpperCase() === "CONSISTENT" ? "green" : "yellow", bold: true, children: workspaceStatus.toUpperCase() })] })), outcome && (_jsxs(Box, { marginTop: 0, children: [_jsx(Text, { color: "gray", children: "Outcome: " }), _jsx(Text, { color: outcome.toUpperCase() === "RECOVERED" || outcome.toUpperCase() === "RECOVERED_WITH_CHANGES"
|
|
14
|
+
? "green"
|
|
15
|
+
: "red", bold: true, children: outcome.toUpperCase() })] })), !isAwaitingContinuation && outcome?.toUpperCase() !== "STILL_BLOCKED" && (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(Text, { color: "yellow", children: "Proceed with recovery? [y/N]" }), _jsxs(Box, { marginTop: 0, children: [_jsxs(Text, { color: "yellow", bold: true, children: ["Choice [N]:", " "] }), _jsx(TextInput, { value: value, onChange: onChange, onSubmit: onSubmit, placeholder: "n" })] })] })), isAwaitingContinuation && (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(Text, { color: "yellow", children: remainingStepsCount !== undefined && remainingStepsCount > 0
|
|
16
|
+
? `Continue remaining ${remainingStepsCount} plan step(s)? [y/N]`
|
|
17
|
+
: "Continue remaining plan steps? [y/N]" }), _jsxs(Box, { marginTop: 0, children: [_jsxs(Text, { color: "yellow", bold: true, children: ["Choice [N]:", " "] }), _jsx(TextInput, { value: value, onChange: onChange, onSubmit: onSubmit, placeholder: "n" })] })] })), outcome?.toUpperCase() === "STILL_BLOCKED" && (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(Text, { color: "red", children: "\u26A0 Recovery still blocked." }), blockers.length > 0 && (_jsxs(Box, { flexDirection: "column", marginTop: 0, children: [_jsx(Text, { color: "gray", children: "Blockers:" }), blockers.map((b, i) => (_jsxs(Text, { color: "red", children: [" ", "\u2022 ", b] }, `rec-b-${i}`)))] })), _jsxs(Box, { flexDirection: "row", marginTop: 0, children: [_jsx(Text, { bold: true, color: "cyan", children: "[r]" }), _jsx(Text, { color: "white", children: " Replan " }), _jsx(Text, { bold: true, color: "green", children: "[c]" }), _jsx(Text, { color: "white", children: " Re-check " }), _jsx(Text, { bold: true, color: "gray", children: "[x]" }), _jsx(Text, { color: "white", children: " Cancel (Default)" })] }), _jsxs(Box, { marginTop: 0, children: [_jsxs(Text, { color: "yellow", bold: true, children: ["Choice [x]:", " "] }), _jsx(TextInput, { value: value, onChange: onChange, onSubmit: onSubmit, placeholder: "x" })] })] }))] }));
|
|
18
|
+
};
|
|
19
|
+
//# sourceMappingURL=RecoveryView.js.map
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
export interface ReplanViewProps {
|
|
3
|
+
originalPlanId?: string;
|
|
4
|
+
newPlanId?: string;
|
|
5
|
+
reason?: string;
|
|
6
|
+
replanDepth?: number;
|
|
7
|
+
workspaceChanges?: string[];
|
|
8
|
+
riskLevel?: string;
|
|
9
|
+
lineage?: string[];
|
|
10
|
+
newPlanSummary?: string;
|
|
11
|
+
value: string;
|
|
12
|
+
onChange: (val: string) => void;
|
|
13
|
+
onSubmit: (val: string) => void;
|
|
14
|
+
}
|
|
15
|
+
export declare const ReplanView: React.FC<ReplanViewProps>;
|
|
16
|
+
//# sourceMappingURL=ReplanView.d.ts.map
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Text } from "ink";
|
|
3
|
+
import TextInput from "ink-text-input";
|
|
4
|
+
export const ReplanView = ({ originalPlanId, newPlanId, reason = "Workspace changed after plan approval.", replanDepth = 1, workspaceChanges = [], riskLevel = "normal", lineage = [], newPlanSummary, value, onChange, onSubmit }) => {
|
|
5
|
+
const getRiskColor = (risk) => {
|
|
6
|
+
switch (risk.toLowerCase()) {
|
|
7
|
+
case "critical":
|
|
8
|
+
return "red";
|
|
9
|
+
case "elevated":
|
|
10
|
+
case "high":
|
|
11
|
+
return "yellow";
|
|
12
|
+
case "low":
|
|
13
|
+
return "green";
|
|
14
|
+
case "normal":
|
|
15
|
+
default:
|
|
16
|
+
return "cyan";
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
return (_jsxs(Box, { flexDirection: "column", borderStyle: "double", borderColor: "yellow", paddingX: 1, marginY: 1, children: [_jsx(Box, { marginBottom: 0, children: _jsx(Text, { bold: true, color: "yellow", children: "REPLAN REQUIRED" }) }), _jsxs(Box, { marginTop: 0, flexDirection: "column", children: [_jsx(Text, { color: "gray", children: "Reason:" }), _jsx(Text, { color: "white", children: reason })] }), originalPlanId && (_jsxs(Box, { marginTop: 0, children: [_jsx(Text, { color: "gray", children: "Original: " }), _jsx(Text, { color: "white", children: originalPlanId })] })), newPlanId && (_jsxs(Box, { marginTop: 0, children: [_jsx(Text, { color: "gray", children: "New: " }), _jsx(Text, { color: "cyan", children: newPlanId })] })), originalPlanId && (_jsxs(Box, { marginTop: 0, children: [_jsx(Text, { color: "gray", children: "Parent: " }), _jsx(Text, { color: "white", children: originalPlanId })] })), _jsxs(Box, { marginTop: 0, justifyContent: "space-between", children: [_jsxs(Box, { children: [_jsx(Text, { color: "gray", children: "Replan depth: " }), _jsx(Text, { color: "white", children: replanDepth })] }), riskLevel && (_jsxs(Box, { children: [_jsx(Text, { color: "gray", children: "Risk: " }), _jsx(Text, { bold: true, color: getRiskColor(riskLevel), children: riskLevel.toUpperCase() })] }))] }), workspaceChanges.length > 0 && (_jsxs(Box, { flexDirection: "column", marginTop: 0, children: [_jsx(Text, { color: "gray", children: "Workspace changes:" }), workspaceChanges.map((c, i) => (_jsxs(Text, { color: "yellow", children: [" ", "\u26A0 ", c] }, `replan-c-${i}`)))] })), newPlanSummary && (_jsxs(Box, { flexDirection: "column", marginTop: 0, children: [_jsx(Text, { color: "gray", children: "Replacement plan preview:" }), _jsx(Text, { color: "white", children: newPlanSummary })] })), lineage.length > 0 && (_jsxs(Box, { marginTop: 0, children: [_jsx(Text, { color: "gray", children: "Lineage: " }), _jsx(Text, { color: "gray", children: lineage.join(" -> ") })] })), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(Text, { color: "gray", children: "(Note: Creating a replacement plan does NOT automatically execute it.)" }), _jsx(Text, { color: "yellow", children: "Create this replacement plan? [y/N]" })] }), _jsxs(Box, { marginTop: 0, children: [_jsxs(Text, { color: "yellow", bold: true, children: ["Choice [N]:", " "] }), _jsx(TextInput, { value: value, onChange: onChange, onSubmit: onSubmit, placeholder: "n" })] })] }));
|
|
20
|
+
};
|
|
21
|
+
//# sourceMappingURL=ReplanView.js.map
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
export interface ResumeViewProps {
|
|
3
|
+
runId: string;
|
|
4
|
+
status?: string;
|
|
5
|
+
duration?: string;
|
|
6
|
+
originalRequest?: string;
|
|
7
|
+
failureReason?: string;
|
|
8
|
+
workspaceDrift?: string[];
|
|
9
|
+
riskLevel?: string;
|
|
10
|
+
value: string;
|
|
11
|
+
onChange: (val: string) => void;
|
|
12
|
+
onSubmit: (val: string) => void;
|
|
13
|
+
}
|
|
14
|
+
export declare const ResumeView: React.FC<ResumeViewProps>;
|
|
15
|
+
//# sourceMappingURL=ResumeView.d.ts.map
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Text } from "ink";
|
|
3
|
+
import TextInput from "ink-text-input";
|
|
4
|
+
export const ResumeView = ({ runId, status = "FAILED", duration, originalRequest, failureReason, workspaceDrift = [], riskLevel = "ELEVATED", value, onChange, onSubmit }) => {
|
|
5
|
+
const getRiskColor = (risk) => {
|
|
6
|
+
switch (risk.toLowerCase()) {
|
|
7
|
+
case "critical":
|
|
8
|
+
return "red";
|
|
9
|
+
case "elevated":
|
|
10
|
+
case "high":
|
|
11
|
+
return "yellow";
|
|
12
|
+
case "low":
|
|
13
|
+
return "green";
|
|
14
|
+
case "normal":
|
|
15
|
+
default:
|
|
16
|
+
return "cyan";
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
return (_jsxs(Box, { flexDirection: "column", borderStyle: "double", borderColor: "yellow", paddingX: 1, marginY: 1, children: [_jsx(Box, { marginBottom: 0, children: _jsx(Text, { bold: true, color: "yellow", children: "Historical Run (Resume Request)" }) }), _jsxs(Box, { marginTop: 0, justifyContent: "space-between", children: [_jsxs(Box, { children: [_jsx(Text, { color: "gray", children: "ID: " }), _jsx(Text, { color: "white", bold: true, children: runId })] }), _jsxs(Box, { children: [_jsx(Text, { color: "gray", children: "Status: " }), _jsx(Text, { bold: true, color: status.toLowerCase() === "completed"
|
|
20
|
+
? "green"
|
|
21
|
+
: status.toLowerCase() === "failed"
|
|
22
|
+
? "red"
|
|
23
|
+
: "yellow", children: status.toUpperCase() }), duration && _jsxs(Text, { color: "gray", children: [" | Duration: ", duration] })] })] }), originalRequest && (_jsxs(Box, { marginTop: 0, flexDirection: "column", children: [_jsx(Text, { color: "gray", children: "Original request:" }), _jsx(Text, { color: "white", wrap: "wrap", children: originalRequest })] })), failureReason && (_jsxs(Box, { marginTop: 0, flexDirection: "column", children: [_jsx(Text, { color: "gray", children: "Failure reason:" }), _jsx(Text, { color: "red", wrap: "wrap", children: failureReason })] })), workspaceDrift.length > 0 && (_jsxs(Box, { flexDirection: "column", marginTop: 0, children: [_jsx(Text, { color: "gray", children: "Workspace drift:" }), workspaceDrift.map((d, i) => (_jsxs(Text, { color: "yellow", wrap: "wrap", children: [" ", "\u26A0 ", d] }, `drift-${i}`)))] })), riskLevel && (_jsxs(Box, { marginTop: 0, children: [_jsx(Text, { color: "gray", children: "Risk reassessment: " }), _jsx(Text, { bold: true, color: getRiskColor(riskLevel), children: riskLevel.toUpperCase() })] })), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(Text, { color: "gray", children: "(Historical approvals/checkpoints must never be reused.)" }), _jsx(Text, { color: "yellow", children: "Resume this task as a new run? [y/N]" })] }), _jsxs(Box, { marginTop: 0, children: [_jsxs(Text, { color: "yellow", bold: true, children: ["Choice [N]:", " "] }), _jsx(TextInput, { value: value, onChange: onChange, onSubmit: onSubmit, placeholder: "n" })] })] }));
|
|
24
|
+
};
|
|
25
|
+
//# sourceMappingURL=ResumeView.js.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
export interface RiskNoticeProps {
|
|
3
|
+
level?: "low" | "normal" | "elevated" | "high" | "critical" | string;
|
|
4
|
+
reasons?: string[];
|
|
5
|
+
requiresCheckpoint?: boolean;
|
|
6
|
+
requiresExplicitApproval?: boolean;
|
|
7
|
+
affectedFilesCount?: number;
|
|
8
|
+
}
|
|
9
|
+
export declare const RiskNotice: React.FC<RiskNoticeProps>;
|
|
10
|
+
//# sourceMappingURL=RiskNotice.d.ts.map
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Text } from "ink";
|
|
3
|
+
export const RiskNotice = ({ level = "normal", reasons = [], requiresCheckpoint, requiresExplicitApproval, affectedFilesCount }) => {
|
|
4
|
+
const normLevel = level.toLowerCase();
|
|
5
|
+
const getBorderColor = () => {
|
|
6
|
+
switch (normLevel) {
|
|
7
|
+
case "critical":
|
|
8
|
+
return "red";
|
|
9
|
+
case "high":
|
|
10
|
+
case "elevated":
|
|
11
|
+
return "yellow";
|
|
12
|
+
case "low":
|
|
13
|
+
return "green";
|
|
14
|
+
case "normal":
|
|
15
|
+
default:
|
|
16
|
+
return "cyan";
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
return (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: getBorderColor(), paddingX: 1, marginY: 1, children: [_jsx(Box, { children: _jsxs(Text, { bold: true, color: getBorderColor(), children: ["Risk: ", level.toUpperCase()] }) }), reasons.length > 0 && (_jsxs(Box, { flexDirection: "column", marginTop: 0, children: [_jsx(Text, { color: "gray", children: "Reasons:" }), reasons.map((r, i) => (_jsxs(Text, { color: "white", children: [" ", "\u2022 ", r] }, `reason-${i}`)))] })), _jsxs(Box, { marginTop: 0, children: [requiresCheckpoint !== undefined && (_jsxs(Text, { color: "gray", children: ["Checkpoint:", " ", _jsx(Text, { color: requiresCheckpoint ? "yellow" : "green", children: requiresCheckpoint ? "REQUIRED" : "NOT REQUIRED" }), " "] })), requiresExplicitApproval !== undefined && (_jsxs(Text, { color: "gray", children: ["Approval:", " ", _jsx(Text, { color: requiresExplicitApproval ? "yellow" : "green", children: requiresExplicitApproval ? "REQUIRED" : "AUTOMATIC" })] })), affectedFilesCount !== undefined && affectedFilesCount > 0 && (_jsxs(Text, { color: "gray", children: [" (Files affected: ", affectedFilesCount, ")"] }))] })] }));
|
|
20
|
+
};
|
|
21
|
+
//# sourceMappingURL=RiskNotice.js.map
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
export interface HistoricalRunItem {
|
|
3
|
+
runId: string;
|
|
4
|
+
status: string;
|
|
5
|
+
userRequestSummary?: string;
|
|
6
|
+
durationMs?: number;
|
|
7
|
+
startedAt?: number;
|
|
8
|
+
projectId?: string;
|
|
9
|
+
}
|
|
10
|
+
export interface RunHistoryViewProps {
|
|
11
|
+
runs?: HistoricalRunItem[];
|
|
12
|
+
formattedOutput?: string;
|
|
13
|
+
}
|
|
14
|
+
export declare const RunHistoryView: React.FC<RunHistoryViewProps>;
|
|
15
|
+
//# sourceMappingURL=RunHistoryView.d.ts.map
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Text } from "ink";
|
|
3
|
+
export const RunHistoryView = ({ runs = [], formattedOutput }) => {
|
|
4
|
+
if (formattedOutput) {
|
|
5
|
+
return (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: "cyan", paddingX: 1, marginY: 1, children: [_jsx(Box, { marginBottom: 0, children: _jsx(Text, { bold: true, color: "cyan", children: "Recent Runs" }) }), _jsx(Text, { color: "white", children: formattedOutput })] }));
|
|
6
|
+
}
|
|
7
|
+
const getStatusDisplay = (status) => {
|
|
8
|
+
switch (status.toLowerCase()) {
|
|
9
|
+
case "completed":
|
|
10
|
+
case "done":
|
|
11
|
+
return _jsx(Text, { color: "green", children: "\u2713 DONE" });
|
|
12
|
+
case "failed":
|
|
13
|
+
case "error":
|
|
14
|
+
return _jsx(Text, { color: "red", children: "\u2717 FAILED" });
|
|
15
|
+
case "cancelled":
|
|
16
|
+
case "cancel":
|
|
17
|
+
return _jsx(Text, { color: "gray", children: "\u2298 CANCEL" });
|
|
18
|
+
case "running":
|
|
19
|
+
case "executing":
|
|
20
|
+
return _jsx(Text, { color: "yellow", children: "\u25CF RUNNING" });
|
|
21
|
+
case "blocked":
|
|
22
|
+
return _jsx(Text, { color: "red", children: "! BLOCKED" });
|
|
23
|
+
default:
|
|
24
|
+
return _jsxs(Text, { color: "gray", children: ["\u25CB ", status.toUpperCase()] });
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
const formatDuration = (ms) => {
|
|
28
|
+
if (!ms)
|
|
29
|
+
return "0s";
|
|
30
|
+
const sec = Math.round(ms / 1000);
|
|
31
|
+
if (sec < 60)
|
|
32
|
+
return `${sec}s`;
|
|
33
|
+
const min = Math.floor(sec / 60);
|
|
34
|
+
const remSec = sec % 60;
|
|
35
|
+
return `${min}m ${remSec}s`;
|
|
36
|
+
};
|
|
37
|
+
return (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: "cyan", paddingX: 1, marginY: 1, children: [_jsx(Box, { marginBottom: 0, children: _jsx(Text, { bold: true, color: "cyan", children: "Recent Runs" }) }), runs.length === 0 ? (_jsx(Box, { marginTop: 0, children: _jsx(Text, { color: "gray", children: "No recorded historical runs found." }) })) : (_jsxs(Box, { flexDirection: "column", marginTop: 0, children: [_jsxs(Box, { justifyContent: "space-between", marginBottom: 0, children: [_jsx(Box, { width: "15%", children: _jsx(Text, { bold: true, color: "gray", children: "STATUS" }) }), _jsx(Box, { width: "25%", children: _jsx(Text, { bold: true, color: "gray", children: "RUN ID" }) }), _jsx(Box, { width: "45%", children: _jsx(Text, { bold: true, color: "gray", children: "REQUEST / PLAN" }) }), _jsx(Box, { width: "15%", children: _jsx(Text, { bold: true, color: "gray", children: "TIME" }) })] }), runs.map((r, idx) => (_jsxs(Box, { justifyContent: "space-between", children: [_jsx(Box, { width: "15%", children: getStatusDisplay(r.status) }), _jsx(Box, { width: "25%", children: _jsx(Text, { color: "white", children: r.runId.substring(0, 16) }) }), _jsx(Box, { width: "45%", children: _jsx(Text, { color: "white", children: (r.userRequestSummary || "Untitled task").substring(0, 35) }) }), _jsx(Box, { width: "15%", children: _jsx(Text, { color: "gray", children: formatDuration(r.durationMs) }) })] }, `run-${r.runId || idx}`)))] })), _jsx(Box, { marginTop: 1, children: _jsxs(Text, { color: "gray", children: ["Inspect run details: ", _jsx(Text, { color: "cyan", children: "/run <id>" }), " | Resume run:", " ", _jsx(Text, { color: "cyan", children: "/resume <id>" })] }) })] }));
|
|
38
|
+
};
|
|
39
|
+
//# sourceMappingURL=RunHistoryView.js.map
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
export interface StatusBarProps {
|
|
3
|
+
status?: string;
|
|
4
|
+
activeStep?: number;
|
|
5
|
+
totalSteps?: number;
|
|
6
|
+
activeStepTitle?: string;
|
|
7
|
+
isGenerating?: boolean;
|
|
8
|
+
hasModal?: boolean;
|
|
9
|
+
modalType?: "approval" | "blocked" | "recovery" | "replan" | "resume" | string;
|
|
10
|
+
customMessage?: string;
|
|
11
|
+
isReconciliation?: boolean;
|
|
12
|
+
recoveryMode?: "confirm" | "continuation" | "still_blocked" | string;
|
|
13
|
+
activeView?: string;
|
|
14
|
+
}
|
|
15
|
+
export declare const StatusBar: React.FC<StatusBarProps>;
|
|
16
|
+
//# sourceMappingURL=StatusBar.d.ts.map
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useState, useEffect } from "react";
|
|
3
|
+
import { Box, Text } from "ink";
|
|
4
|
+
const SPINNER_FRAMES = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
|
|
5
|
+
const INTERVAL_MS = 80;
|
|
6
|
+
const ACTIVE_STATUSES = new Set([
|
|
7
|
+
"executing",
|
|
8
|
+
"planning",
|
|
9
|
+
"verifying",
|
|
10
|
+
"recovering"
|
|
11
|
+
]);
|
|
12
|
+
export const StatusBar = ({ status = "idle", activeStep, totalSteps, activeStepTitle, isGenerating = false, hasModal = false, modalType, customMessage, isReconciliation = false, recoveryMode = "confirm", activeView = "main" }) => {
|
|
13
|
+
const [frame, setFrame] = useState(0);
|
|
14
|
+
const isAnimating = isGenerating || ACTIVE_STATUSES.has(status.toLowerCase());
|
|
15
|
+
useEffect(() => {
|
|
16
|
+
if (!isAnimating)
|
|
17
|
+
return;
|
|
18
|
+
const timer = setInterval(() => {
|
|
19
|
+
setFrame((prev) => (prev + 1) % SPINNER_FRAMES.length);
|
|
20
|
+
}, INTERVAL_MS);
|
|
21
|
+
return () => clearInterval(timer);
|
|
22
|
+
}, [isAnimating]);
|
|
23
|
+
const spinner = isAnimating ? `${SPINNER_FRAMES[frame]} ` : "";
|
|
24
|
+
const renderStatusText = () => {
|
|
25
|
+
if (customMessage) {
|
|
26
|
+
return (_jsxs(Text, { color: "yellow", children: [spinner, customMessage] }));
|
|
27
|
+
}
|
|
28
|
+
if (activeStep !== undefined && totalSteps !== undefined && totalSteps > 0) {
|
|
29
|
+
const stepText = `Step ${activeStep}/${totalSteps}${activeStepTitle ? `: ${activeStepTitle}` : ""}`;
|
|
30
|
+
if (status === "executing" || isGenerating) {
|
|
31
|
+
return (_jsxs(Text, { color: "green", children: [spinner, "Executing ", stepText] }));
|
|
32
|
+
}
|
|
33
|
+
if (status === "awaiting_step_approval") {
|
|
34
|
+
return _jsxs(Text, { color: "yellow", children: ["\u26A0 Waiting for Approval (", stepText, ")"] });
|
|
35
|
+
}
|
|
36
|
+
if (status === "verifying") {
|
|
37
|
+
return (_jsxs(Text, { color: "cyan", children: [spinner, "Verifying (", stepText, ")"] }));
|
|
38
|
+
}
|
|
39
|
+
if (status === "blocked") {
|
|
40
|
+
return _jsxs(Text, { color: "red", children: ["! Blocked at ", stepText] });
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
switch (status.toLowerCase()) {
|
|
44
|
+
case "in_progress":
|
|
45
|
+
case "generating":
|
|
46
|
+
case "executing":
|
|
47
|
+
case "running":
|
|
48
|
+
return _jsxs(Text, { color: "green", children: [spinner, "Executing task..."] });
|
|
49
|
+
case "planning":
|
|
50
|
+
return _jsxs(Text, { color: "cyan", children: [spinner, "Generating task plan..."] });
|
|
51
|
+
case "awaiting_plan_approval":
|
|
52
|
+
return _jsx(Text, { color: "yellow", children: "\u26A0 Plan approval required" });
|
|
53
|
+
case "awaiting_step_approval":
|
|
54
|
+
return _jsx(Text, { color: "yellow", children: "\u26A0 Step approval required" });
|
|
55
|
+
case "verifying":
|
|
56
|
+
return _jsxs(Text, { color: "cyan", children: [spinner, "Verifying changes..."] });
|
|
57
|
+
case "recovering":
|
|
58
|
+
return _jsxs(Text, { color: "yellow", children: [spinner, "Performing recovery..."] });
|
|
59
|
+
case "blocked":
|
|
60
|
+
return _jsx(Text, { color: "red", children: "! Plan execution blocked" });
|
|
61
|
+
case "completed":
|
|
62
|
+
return _jsx(Text, { color: "green", children: "\u2713 Task completed" });
|
|
63
|
+
case "failed":
|
|
64
|
+
return _jsx(Text, { color: "red", children: "\u2717 Task failed" });
|
|
65
|
+
case "cancelled":
|
|
66
|
+
return _jsx(Text, { color: "gray", children: "\u2298 Task cancelled" });
|
|
67
|
+
case "idle":
|
|
68
|
+
default:
|
|
69
|
+
return _jsx(Text, { color: "gray", children: "\u25CB Ready for task" });
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
const renderShortcuts = () => {
|
|
73
|
+
if (hasModal) {
|
|
74
|
+
if (modalType === "approval") {
|
|
75
|
+
return (_jsxs(Box, { children: [_jsx(Text, { color: "yellow", children: "[y]" }), _jsx(Text, { color: "gray", children: " Approve " }), _jsx(Text, { color: "yellow", children: "[n]" }), _jsx(Text, { color: "gray", children: " Reject " }), _jsx(Text, { color: "gray", children: "[Esc] Cancel" })] }));
|
|
76
|
+
}
|
|
77
|
+
if (modalType === "blocked") {
|
|
78
|
+
if (isReconciliation) {
|
|
79
|
+
return (_jsxs(Box, { children: [_jsx(Text, { color: "yellow", children: "[r]" }), _jsx(Text, { color: "gray", children: " Recover " }), _jsx(Text, { color: "cyan", children: "[p]" }), _jsx(Text, { color: "gray", children: " Replan " }), _jsx(Text, { color: "gray", children: "[x] Cancel" })] }));
|
|
80
|
+
}
|
|
81
|
+
return (_jsxs(Box, { children: [_jsx(Text, { color: "green", children: "[c]" }), _jsx(Text, { color: "gray", children: " Continue " }), _jsx(Text, { color: "cyan", children: "[r]" }), _jsx(Text, { color: "gray", children: " Replan " }), _jsx(Text, { color: "gray", children: "[x] Cancel" })] }));
|
|
82
|
+
}
|
|
83
|
+
if (modalType === "recovery") {
|
|
84
|
+
if (recoveryMode === "still_blocked") {
|
|
85
|
+
return (_jsxs(Box, { children: [_jsx(Text, { color: "cyan", children: "[r]" }), _jsx(Text, { color: "gray", children: " Replan " }), _jsx(Text, { color: "green", children: "[c]" }), _jsx(Text, { color: "gray", children: " Re-check " }), _jsx(Text, { color: "gray", children: "[x] Cancel" })] }));
|
|
86
|
+
}
|
|
87
|
+
if (recoveryMode === "continuation") {
|
|
88
|
+
return (_jsxs(Box, { children: [_jsx(Text, { color: "green", children: "[y]" }), _jsx(Text, { color: "gray", children: " Continue " }), _jsx(Text, { color: "yellow", children: "[n]" }), _jsx(Text, { color: "gray", children: " Cancel " }), _jsx(Text, { color: "gray", children: "[Esc] Cancel" })] }));
|
|
89
|
+
}
|
|
90
|
+
return (_jsxs(Box, { children: [_jsx(Text, { color: "green", children: "[y]" }), _jsx(Text, { color: "gray", children: " Proceed " }), _jsx(Text, { color: "yellow", children: "[n]" }), _jsx(Text, { color: "gray", children: " Cancel " }), _jsx(Text, { color: "gray", children: "[Esc] Cancel" })] }));
|
|
91
|
+
}
|
|
92
|
+
return (_jsxs(Box, { children: [_jsx(Text, { color: "yellow", children: "[y]" }), _jsx(Text, { color: "gray", children: " Yes " }), _jsx(Text, { color: "yellow", children: "[n]" }), _jsx(Text, { color: "gray", children: " No " }), _jsx(Text, { color: "gray", children: "[Esc] Cancel" })] }));
|
|
93
|
+
}
|
|
94
|
+
if (activeView && activeView !== "main") {
|
|
95
|
+
return (_jsxs(Box, { children: [_jsx(Text, { color: "gray", children: "[Esc] Main " }), _jsx(Text, { color: "cyan", children: "[p]" }), _jsx(Text, { color: "gray", children: " Plan " }), _jsx(Text, { color: "cyan", children: "[r]" }), _jsx(Text, { color: "gray", children: " Runs " }), _jsx(Text, { color: "cyan", children: "[d]" }), _jsx(Text, { color: "gray", children: " Diagnostics " }), _jsx(Text, { color: "cyan", children: "[?]" }), _jsx(Text, { color: "gray", children: " Help" })] }));
|
|
96
|
+
}
|
|
97
|
+
if (isGenerating) {
|
|
98
|
+
return (_jsxs(Box, { children: [_jsx(Text, { color: "cyan", children: "[Ctrl+C]" }), _jsx(Text, { color: "gray", children: " Cancel" })] }));
|
|
99
|
+
}
|
|
100
|
+
return (_jsxs(Box, { children: [_jsx(Text, { color: "cyan", children: "[Ctrl+C]" }), _jsx(Text, { color: "gray", children: " Exit " }), _jsx(Text, { color: "cyan", children: "/plan" }), _jsx(Text, { color: "gray", children: " Plan " }), _jsx(Text, { color: "cyan", children: "/runs" }), _jsx(Text, { color: "gray", children: " Runs " }), _jsx(Text, { color: "cyan", children: "/debug" }), _jsx(Text, { color: "gray", children: " Diagnostics " }), _jsx(Text, { color: "cyan", children: "/help" }), _jsx(Text, { color: "gray", children: " Help" })] }));
|
|
101
|
+
};
|
|
102
|
+
return (_jsx(Box, { flexDirection: "column", borderStyle: "single", borderColor: "gray", paddingX: 1, marginTop: 1, children: _jsxs(Box, { justifyContent: "space-between", children: [_jsx(Box, { children: renderStatusText() }), _jsx(Box, { children: renderShortcuts() })] }) }));
|
|
103
|
+
};
|
|
104
|
+
//# sourceMappingURL=StatusBar.js.map
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { CommandDef } from "../commands.js";
|
|
3
|
+
export interface TaskInputProps {
|
|
4
|
+
value: string;
|
|
5
|
+
onChange: (value: string) => void;
|
|
6
|
+
onSubmit: (value: string) => void;
|
|
7
|
+
isDisabled?: boolean;
|
|
8
|
+
placeholder?: string;
|
|
9
|
+
label?: string;
|
|
10
|
+
pendingQuery?: string | null;
|
|
11
|
+
suggestions?: CommandDef[];
|
|
12
|
+
selectedSuggestion?: number;
|
|
13
|
+
}
|
|
14
|
+
export declare const TaskInput: React.FC<TaskInputProps>;
|
|
15
|
+
//# sourceMappingURL=TaskInput.d.ts.map
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Text } from "ink";
|
|
3
|
+
import TextInput from "ink-text-input";
|
|
4
|
+
import { CommandPalette } from "./CommandPalette.js";
|
|
5
|
+
export const TaskInput = ({ value, onChange, onSubmit, isDisabled = false, placeholder = "Describe task or type /help...", label, pendingQuery, suggestions, selectedSuggestion = 0 }) => {
|
|
6
|
+
return (_jsxs(Box, { flexDirection: "column", marginY: 0, children: [!label && (_jsx(Box, { marginBottom: 0, children: _jsx(Text, { color: "gray", dimColor: true, children: "─".repeat(48) }) })), label && (_jsx(Box, { marginBottom: 0, children: _jsx(Text, { bold: true, color: "white", children: label }) })), suggestions && suggestions.length > 0 && (_jsx(CommandPalette, { suggestions: suggestions, selectedIndex: selectedSuggestion })), _jsxs(Box, { children: [_jsx(Text, { color: "cyan", bold: true, children: "\u203A " }), isDisabled ? (_jsx(Text, { color: "gray", children: pendingQuery ? `[queued] ${pendingQuery}` : (value || placeholder) })) : (_jsx(TextInput, { value: value, onChange: onChange, onSubmit: onSubmit, placeholder: placeholder }))] }), isDisabled && pendingQuery && (_jsxs(Box, { marginTop: 0, children: [_jsx(Text, { color: "yellow", children: "\u23CE Queued: " }), _jsx(Text, { color: "white", children: pendingQuery }), _jsx(Text, { color: "gray", children: " (Ctrl+C to cancel)" })] }))] }));
|
|
7
|
+
};
|
|
8
|
+
//# sourceMappingURL=TaskInput.js.map
|