prompt-language-shell 0.9.2 → 0.9.6
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/{ui/Main.js → Main.js} +12 -12
- package/dist/{ui → components}/Component.js +28 -26
- package/dist/{ui → components}/Workflow.js +14 -4
- package/dist/{ui → components/controllers}/Answer.js +18 -17
- package/dist/{ui → components/controllers}/Command.js +11 -18
- package/dist/{ui → components/controllers}/Config.js +8 -116
- package/dist/components/controllers/Confirm.js +42 -0
- package/dist/{ui → components/controllers}/Execute.js +75 -144
- package/dist/{ui → components/controllers}/Introspect.js +12 -28
- package/dist/components/controllers/Refinement.js +18 -0
- package/dist/components/controllers/Schedule.js +134 -0
- package/dist/{ui → components/controllers}/Validate.js +14 -32
- package/dist/components/views/Answer.js +28 -0
- package/dist/components/views/Command.js +11 -0
- package/dist/components/views/Config.js +115 -0
- package/dist/components/views/Confirm.js +24 -0
- package/dist/components/views/Debug.js +12 -0
- package/dist/components/views/Execute.js +60 -0
- package/dist/components/views/Feedback.js +8 -0
- package/dist/components/views/Introspect.js +17 -0
- package/dist/{ui → components/views}/Label.js +3 -3
- package/dist/{ui → components/views}/List.js +1 -1
- package/dist/{ui → components/views}/Output.js +2 -2
- package/dist/components/views/Refinement.js +9 -0
- package/dist/{ui → components/views}/Report.js +1 -1
- package/dist/components/views/Schedule.js +121 -0
- package/dist/{ui → components/views}/Separator.js +1 -1
- package/dist/{ui → components/views}/Spinner.js +1 -1
- package/dist/{ui → components/views}/Subtask.js +4 -4
- package/dist/components/views/Table.js +15 -0
- package/dist/components/views/Task.js +18 -0
- package/dist/components/views/Upcoming.js +30 -0
- package/dist/{ui → components/views}/UserQuery.js +1 -1
- package/dist/components/views/Validate.js +17 -0
- package/dist/{ui → components/views}/Welcome.js +1 -1
- package/dist/configuration/steps.js +1 -1
- package/dist/execution/handlers.js +19 -53
- package/dist/execution/reducer.js +26 -38
- package/dist/execution/runner.js +43 -25
- package/dist/execution/types.js +3 -4
- package/dist/execution/utils.js +1 -1
- package/dist/index.js +1 -1
- package/dist/services/anthropic.js +27 -31
- package/dist/services/colors.js +2 -1
- package/dist/services/logger.js +126 -13
- package/dist/services/messages.js +19 -0
- package/dist/services/parser.js +13 -5
- package/dist/services/refinement.js +8 -2
- package/dist/services/router.js +184 -89
- package/dist/services/shell.js +26 -6
- package/dist/services/skills.js +35 -7
- package/dist/services/timing.js +1 -0
- package/dist/skills/execute.md +15 -7
- package/dist/skills/schedule.md +155 -0
- package/dist/tools/execute.tool.js +0 -4
- package/dist/tools/schedule.tool.js +1 -1
- package/dist/types/schemas.js +0 -1
- package/package.json +4 -4
- package/dist/execution/hooks.js +0 -291
- package/dist/ui/Confirm.js +0 -62
- package/dist/ui/Debug.js +0 -7
- package/dist/ui/Feedback.js +0 -19
- package/dist/ui/Refinement.js +0 -23
- package/dist/ui/Schedule.js +0 -257
- package/dist/ui/Task.js +0 -11
- /package/dist/{ui → components/views}/Message.js +0 -0
- /package/dist/{ui → components/views}/Panel.js +0 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useMemo } from 'react';
|
|
3
|
+
import { Box, Text } from 'ink';
|
|
4
|
+
import { ComponentStatus } from '../../types/components.js';
|
|
5
|
+
import { Colors, getTextColor } from '../../services/colors.js';
|
|
6
|
+
import { getAnswerLoadingMessage } from '../../services/messages.js';
|
|
7
|
+
import { ExecutionStatus } from '../../services/shell.js';
|
|
8
|
+
import { Spinner } from './Spinner.js';
|
|
9
|
+
import { Upcoming } from './Upcoming.js';
|
|
10
|
+
/**
|
|
11
|
+
* Answer view: Displays question and answer
|
|
12
|
+
*/
|
|
13
|
+
export const AnswerView = ({ status, question, lines, error, upcoming, cancelled = false, }) => {
|
|
14
|
+
const isActive = status === ComponentStatus.Active;
|
|
15
|
+
const isLoading = isActive && !lines && !error;
|
|
16
|
+
const loadingMessage = useMemo(() => getAnswerLoadingMessage(), []);
|
|
17
|
+
// Determine upcoming status: cancelled, error, or pending
|
|
18
|
+
const isTerminated = cancelled || error !== null;
|
|
19
|
+
const upcomingStatus = cancelled
|
|
20
|
+
? ExecutionStatus.Aborted
|
|
21
|
+
: error
|
|
22
|
+
? ExecutionStatus.Failed
|
|
23
|
+
: ExecutionStatus.Pending;
|
|
24
|
+
// Build full list of items to show - include current question when terminated
|
|
25
|
+
const upcomingItems = isTerminated && upcoming ? [question, ...upcoming] : (upcoming ?? []);
|
|
26
|
+
const showUpcoming = upcomingItems.length > 0 && (isActive || isTerminated);
|
|
27
|
+
return (_jsxs(Box, { alignSelf: "flex-start", flexDirection: "column", children: [isLoading && (_jsxs(_Fragment, { children: [_jsx(Box, { marginLeft: 1, marginBottom: 1, children: _jsx(Text, { color: getTextColor(isActive), children: question }) }), _jsxs(Box, { paddingLeft: 3, marginBottom: 1, children: [_jsxs(Text, { color: getTextColor(isActive), children: [loadingMessage, " "] }), _jsx(Spinner, {})] })] })), lines && lines.length > 0 && (_jsxs(_Fragment, { children: [_jsx(Box, { marginLeft: 1, marginBottom: 1, children: _jsx(Text, { color: getTextColor(isActive), children: question }) }), _jsx(Box, { flexDirection: "column", paddingLeft: 3, children: lines.map((line, index) => (_jsx(Text, { color: getTextColor(isActive), children: line }, index))) })] })), showUpcoming && (_jsx(Box, { marginTop: lines && lines.length > 0 ? 1 : 0, children: _jsx(Upcoming, { items: upcomingItems, status: upcomingStatus }) })), error && (_jsx(Box, { marginTop: 1, marginLeft: 1, children: _jsxs(Text, { color: Colors.Status.Error, children: ["Error: ", error] }) }))] }));
|
|
28
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Text } from 'ink';
|
|
3
|
+
import { ComponentStatus } from '../../types/components.js';
|
|
4
|
+
import { Colors } from '../../services/colors.js';
|
|
5
|
+
import { Spinner } from './Spinner.js';
|
|
6
|
+
import { UserQuery } from './UserQuery.js';
|
|
7
|
+
export const CommandView = ({ command, state, status }) => {
|
|
8
|
+
const isActive = status === ComponentStatus.Active;
|
|
9
|
+
const { error } = state;
|
|
10
|
+
return (_jsxs(Box, { alignSelf: "flex-start", flexDirection: "column", children: [!isActive ? (_jsxs(UserQuery, { children: ["> pls ", command] })) : (_jsxs(Box, { marginLeft: 1, children: [_jsxs(Text, { color: Colors.Text.Active, children: ["> pls ", command] }), _jsx(Text, { children: " " }), _jsx(Spinner, {})] })), error && (_jsx(Box, { marginTop: 1, marginLeft: 1, children: _jsxs(Text, { color: Colors.Status.Error, children: ["Error: ", error] }) }))] }));
|
|
11
|
+
};
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useState } from 'react';
|
|
3
|
+
import { Box, Text, useFocus } from 'ink';
|
|
4
|
+
import TextInput from 'ink-text-input';
|
|
5
|
+
import { ComponentStatus } from '../../types/components.js';
|
|
6
|
+
import { Colors } from '../../services/colors.js';
|
|
7
|
+
import { DebugLevel } from '../../configuration/types.js';
|
|
8
|
+
import { useInput } from '../../services/keyboard.js';
|
|
9
|
+
/**
|
|
10
|
+
* Get postfix with debug brackets if debug is enabled
|
|
11
|
+
* Info: {key} | Verbose: {key} entry
|
|
12
|
+
*/
|
|
13
|
+
function getPostfix(text, debugLevel) {
|
|
14
|
+
if (debugLevel === DebugLevel.None || !text) {
|
|
15
|
+
return '';
|
|
16
|
+
}
|
|
17
|
+
if (debugLevel === DebugLevel.Info) {
|
|
18
|
+
return `{${text}}`;
|
|
19
|
+
}
|
|
20
|
+
return `{${text}} entry`;
|
|
21
|
+
}
|
|
22
|
+
export var StepType;
|
|
23
|
+
(function (StepType) {
|
|
24
|
+
StepType["Text"] = "text";
|
|
25
|
+
StepType["Selection"] = "selection";
|
|
26
|
+
})(StepType || (StepType = {}));
|
|
27
|
+
function TextStep({ value, placeholder, validate, onChange, onSubmit, }) {
|
|
28
|
+
const [inputValue, setInputValue] = useState(value);
|
|
29
|
+
const [validationFailed, setValidationFailed] = useState(false);
|
|
30
|
+
const { isFocused } = useFocus({ autoFocus: true });
|
|
31
|
+
// Sync internal state with prop changes
|
|
32
|
+
useEffect(() => {
|
|
33
|
+
setInputValue(value);
|
|
34
|
+
}, [value]);
|
|
35
|
+
const handleChange = (newValue) => {
|
|
36
|
+
setInputValue(newValue);
|
|
37
|
+
onChange(newValue);
|
|
38
|
+
if (validationFailed) {
|
|
39
|
+
setValidationFailed(false);
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
const handleSubmit = (value) => {
|
|
43
|
+
// Use placeholder if input is empty
|
|
44
|
+
const finalValue = value || placeholder || '';
|
|
45
|
+
if (!validate(finalValue)) {
|
|
46
|
+
setValidationFailed(true);
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
onSubmit(finalValue);
|
|
50
|
+
};
|
|
51
|
+
// Handle input manually when validation fails
|
|
52
|
+
useInput((input, key) => {
|
|
53
|
+
if (!validationFailed)
|
|
54
|
+
return;
|
|
55
|
+
if (key.return) {
|
|
56
|
+
handleSubmit(inputValue);
|
|
57
|
+
}
|
|
58
|
+
else if (key.backspace || key.delete) {
|
|
59
|
+
const newValue = inputValue.slice(0, -1);
|
|
60
|
+
handleChange(newValue);
|
|
61
|
+
}
|
|
62
|
+
else if (!key.ctrl && !key.meta && input) {
|
|
63
|
+
const newValue = inputValue + input;
|
|
64
|
+
handleChange(newValue);
|
|
65
|
+
}
|
|
66
|
+
}, { isActive: validationFailed });
|
|
67
|
+
// When validation fails, show colored text
|
|
68
|
+
if (validationFailed) {
|
|
69
|
+
return (_jsxs(Text, { color: Colors.Status.Error, children: [inputValue || placeholder, isFocused && _jsx(Text, { inverse: true, children: " " })] }));
|
|
70
|
+
}
|
|
71
|
+
return (_jsx(TextInput, { value: inputValue, onChange: handleChange, onSubmit: handleSubmit, placeholder: placeholder }));
|
|
72
|
+
}
|
|
73
|
+
function SelectionStep({ options, selectedIndex, isCurrentStep, }) {
|
|
74
|
+
return (_jsx(Box, { children: options.map((option, optIndex) => {
|
|
75
|
+
const isSelected = optIndex === selectedIndex;
|
|
76
|
+
return (_jsx(Box, { marginRight: 2, children: _jsx(Text, { dimColor: !isSelected || !isCurrentStep, bold: isSelected, children: option.label }) }, option.value));
|
|
77
|
+
}) }));
|
|
78
|
+
}
|
|
79
|
+
export const ConfigView = ({ steps, state, status, debug = DebugLevel.None, onInputChange, onInputSubmit, }) => {
|
|
80
|
+
const isActive = status === ComponentStatus.Active;
|
|
81
|
+
const { values, completedStep, selectedIndex } = state;
|
|
82
|
+
const renderStepInput = (stepConfig, isCurrentStep) => {
|
|
83
|
+
const configKey = stepConfig.path || stepConfig.key;
|
|
84
|
+
const displayValue = values[configKey];
|
|
85
|
+
switch (stepConfig.type) {
|
|
86
|
+
case StepType.Text:
|
|
87
|
+
if (isCurrentStep && onInputChange && onInputSubmit) {
|
|
88
|
+
return (_jsx(TextStep, { value: values[configKey] || '', placeholder: stepConfig.value || undefined, validate: stepConfig.validate, onChange: onInputChange, onSubmit: onInputSubmit }));
|
|
89
|
+
}
|
|
90
|
+
return (_jsx(Text, { dimColor: true, wrap: "truncate-end", children: displayValue || '' }));
|
|
91
|
+
case StepType.Selection: {
|
|
92
|
+
if (!isCurrentStep) {
|
|
93
|
+
const option = stepConfig.options.find((opt) => opt.value === displayValue);
|
|
94
|
+
return _jsx(Text, { dimColor: true, children: option?.label || '' });
|
|
95
|
+
}
|
|
96
|
+
return (_jsx(SelectionStep, { options: stepConfig.options, selectedIndex: selectedIndex, isCurrentStep: true }));
|
|
97
|
+
}
|
|
98
|
+
default: {
|
|
99
|
+
const _exhaustiveCheck = stepConfig;
|
|
100
|
+
throw new Error('Unsupported step type');
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
return (_jsx(Box, { flexDirection: "column", marginLeft: 1, children: steps.map((stepConfig, index) => {
|
|
105
|
+
const isCurrentStep = index === completedStep && isActive;
|
|
106
|
+
const isCompleted = index < completedStep;
|
|
107
|
+
const wasAborted = index === completedStep && !isActive;
|
|
108
|
+
const shouldShow = isCompleted || isCurrentStep || wasAborted;
|
|
109
|
+
if (!shouldShow) {
|
|
110
|
+
return null;
|
|
111
|
+
}
|
|
112
|
+
const postfix = getPostfix(stepConfig.path, debug);
|
|
113
|
+
return (_jsxs(Box, { flexDirection: "column", marginTop: index === 0 ? 0 : 1, children: [_jsxs(Box, { children: [_jsx(Text, { children: stepConfig.description }), _jsx(Text, { children: ": " }), postfix && _jsx(Text, { color: Colors.Type.Config, children: postfix })] }), _jsxs(Box, { children: [_jsx(Text, { children: " " }), _jsx(Text, { color: Colors.Action.Select, dimColor: !isCurrentStep, children: ">" }), _jsx(Text, { children: " " }), renderStepInput(stepConfig, isCurrentStep)] })] }, stepConfig.path || stepConfig.key));
|
|
114
|
+
}) }));
|
|
115
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Text } from 'ink';
|
|
3
|
+
import { ComponentStatus } from '../../types/components.js';
|
|
4
|
+
import { Colors, getTextColor, Palette } from '../../services/colors.js';
|
|
5
|
+
import { UserQuery } from './UserQuery.js';
|
|
6
|
+
const OPTIONS = [
|
|
7
|
+
{ label: 'yes', value: 'yes', color: Palette.BrightGreen },
|
|
8
|
+
{ label: 'no', value: 'no', color: Colors.Status.Error },
|
|
9
|
+
];
|
|
10
|
+
/**
|
|
11
|
+
* Confirm view: Displays yes/no confirmation prompt
|
|
12
|
+
*/
|
|
13
|
+
export const ConfirmView = ({ status, message, selectedIndex, }) => {
|
|
14
|
+
const isActive = status === ComponentStatus.Active;
|
|
15
|
+
// Timeline rendering (Done status)
|
|
16
|
+
if (status === ComponentStatus.Done) {
|
|
17
|
+
return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { marginBottom: 1, marginLeft: 1, children: _jsx(Text, { color: undefined, children: message }) }), _jsxs(UserQuery, { children: ["> ", OPTIONS[selectedIndex].label] })] }));
|
|
18
|
+
}
|
|
19
|
+
// Active/Pending rendering
|
|
20
|
+
return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { marginBottom: 1, marginLeft: 1, children: _jsx(Text, { color: getTextColor(isActive), children: message }) }), _jsxs(Box, { marginLeft: 1, children: [_jsx(Text, { color: Colors.Action.Select, children: ">" }), _jsx(Text, { children: " " }), _jsx(Box, { children: OPTIONS.map((option, index) => {
|
|
21
|
+
const isSelected = index === selectedIndex;
|
|
22
|
+
return (_jsx(Box, { marginRight: 2, children: _jsx(Text, { color: isSelected ? option.color : undefined, dimColor: !isSelected, children: option.label }) }, option.value));
|
|
23
|
+
}) })] })] }));
|
|
24
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Text } from 'ink';
|
|
3
|
+
const CONTENT_WIDTH = 80;
|
|
4
|
+
const HORIZONTAL_PADDING = 2;
|
|
5
|
+
export const Debug = ({ title, content, color }) => {
|
|
6
|
+
// Plain text content - single bordered box
|
|
7
|
+
if (typeof content === 'string') {
|
|
8
|
+
return (_jsxs(Box, { flexDirection: "column", paddingX: HORIZONTAL_PADDING, paddingY: 1, borderStyle: "single", borderColor: color, width: CONTENT_WIDTH, children: [_jsx(Text, { color: color, wrap: "wrap", children: title }), _jsx(Text, { color: color, wrap: "wrap", children: content })] }));
|
|
9
|
+
}
|
|
10
|
+
// Array content - table with one column, each item in bordered row
|
|
11
|
+
return (_jsxs(Box, { flexDirection: "column", width: CONTENT_WIDTH, children: [_jsx(Box, { paddingX: HORIZONTAL_PADDING, paddingY: 1, borderStyle: "single", borderColor: color, width: CONTENT_WIDTH, children: _jsx(Text, { color: color, wrap: "wrap", children: title }) }), content.map((section, index) => (_jsx(Box, { paddingX: HORIZONTAL_PADDING, paddingY: 1, borderStyle: "single", borderColor: color, width: CONTENT_WIDTH, marginTop: -1, children: _jsx(Text, { color: color, wrap: "wrap", children: section }) }, index)))] }));
|
|
12
|
+
};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Text } from 'ink';
|
|
3
|
+
import { getTextColor, Palette } from '../../services/colors.js';
|
|
4
|
+
import { ExecutionStatus } from '../../services/shell.js';
|
|
5
|
+
import { Spinner } from './Spinner.js';
|
|
6
|
+
import { TaskView } from './Task.js';
|
|
7
|
+
import { Upcoming } from './Upcoming.js';
|
|
8
|
+
/**
|
|
9
|
+
* Check if a task is finished (success, failed, or aborted)
|
|
10
|
+
*/
|
|
11
|
+
function isTaskFinished(task) {
|
|
12
|
+
return (task.status === ExecutionStatus.Success ||
|
|
13
|
+
task.status === ExecutionStatus.Failed ||
|
|
14
|
+
task.status === ExecutionStatus.Aborted);
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Determine the upcoming status based on task states
|
|
18
|
+
*/
|
|
19
|
+
function getUpcomingStatus(tasks) {
|
|
20
|
+
const hasFailed = tasks.some((task) => task.status === ExecutionStatus.Failed);
|
|
21
|
+
const hasCancelled = tasks.some((task) => task.status === ExecutionStatus.Aborted ||
|
|
22
|
+
task.status === ExecutionStatus.Cancelled);
|
|
23
|
+
if (hasFailed)
|
|
24
|
+
return ExecutionStatus.Failed;
|
|
25
|
+
if (hasCancelled)
|
|
26
|
+
return ExecutionStatus.Aborted;
|
|
27
|
+
return ExecutionStatus.Pending;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Convert ExecuteState to view props for timeline rendering
|
|
31
|
+
*/
|
|
32
|
+
export function mapStateToViewProps(state, isActive, upcoming, label) {
|
|
33
|
+
return {
|
|
34
|
+
isLoading: false,
|
|
35
|
+
isExecuting: false,
|
|
36
|
+
isActive,
|
|
37
|
+
error: state.error,
|
|
38
|
+
message: state.message,
|
|
39
|
+
tasks: state.tasks,
|
|
40
|
+
completionMessage: state.completionMessage,
|
|
41
|
+
showTasks: state.tasks.length > 0,
|
|
42
|
+
upcoming,
|
|
43
|
+
label,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Execute view: Pure display component for task execution progress
|
|
48
|
+
*/
|
|
49
|
+
export const ExecuteView = ({ isLoading, isExecuting, isActive, error, message, tasks, completionMessage, showTasks, upcoming, label, }) => {
|
|
50
|
+
// Return null only when loading completes with no commands
|
|
51
|
+
if (!isActive && tasks.length === 0 && !error) {
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
// Determine upcoming status based on task states
|
|
55
|
+
const upcomingStatus = getUpcomingStatus(tasks);
|
|
56
|
+
const isTerminated = upcomingStatus !== ExecutionStatus.Pending;
|
|
57
|
+
// Show upcoming during active execution or when terminated (to show skipped tasks)
|
|
58
|
+
const showUpcoming = upcoming && upcoming.length > 0 && (isActive || isTerminated);
|
|
59
|
+
return (_jsxs(Box, { alignSelf: "flex-start", flexDirection: "column", children: [isLoading && (_jsxs(Box, { flexDirection: "column", marginLeft: 1, children: [label && (_jsx(Box, { marginBottom: 1, children: _jsx(Text, { color: getTextColor(isActive), children: label }) })), _jsxs(Box, { marginLeft: label ? 2 : 0, children: [_jsx(Text, { color: Palette.Gray, children: "Preparing commands. " }), _jsx(Spinner, {})] })] })), (isExecuting || showTasks) && (_jsxs(Box, { flexDirection: "column", marginLeft: 1, children: [message && (_jsxs(Box, { marginBottom: 1, gap: 1, children: [_jsx(Text, { color: getTextColor(isActive), children: message }), isExecuting && _jsx(Spinner, {})] })), tasks.map((task, index) => (_jsx(Box, { marginBottom: index < tasks.length - 1 ? 1 : 0, children: _jsx(TaskView, { label: task.label, command: task.command, status: task.status, elapsed: task.elapsed, output: task.output, isFinished: isTaskFinished(task), isActive: isActive }) }, index)))] })), showUpcoming && (_jsx(Box, { marginTop: 1, children: _jsx(Upcoming, { items: upcoming, status: upcomingStatus }) })), completionMessage && !isActive && (_jsx(Box, { marginTop: 1, marginLeft: 1, children: _jsx(Text, { color: getTextColor(false), children: completionMessage }) })), error && (_jsx(Box, { marginLeft: 1, children: _jsx(Text, { children: error }) }))] }));
|
|
60
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Text } from 'ink';
|
|
3
|
+
import { ComponentStatus } from '../../types/components.js';
|
|
4
|
+
import { getFeedbackColor } from '../../services/colors.js';
|
|
5
|
+
export function Feedback({ type, message }) {
|
|
6
|
+
const color = getFeedbackColor(type, ComponentStatus.Done);
|
|
7
|
+
return (_jsx(Box, { marginLeft: 1, children: _jsx(Text, { color: color, children: message }) }));
|
|
8
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Text } from 'ink';
|
|
3
|
+
import { ComponentStatus } from '../../types/components.js';
|
|
4
|
+
import { Colors, getTextColor } from '../../services/colors.js';
|
|
5
|
+
import { Spinner } from './Spinner.js';
|
|
6
|
+
/**
|
|
7
|
+
* Introspect view: Displays capabilities list
|
|
8
|
+
*/
|
|
9
|
+
export const IntrospectView = ({ status, hasCapabilities, error, children, }) => {
|
|
10
|
+
const isActive = status === ComponentStatus.Active;
|
|
11
|
+
const isLoading = isActive && !hasCapabilities && !error;
|
|
12
|
+
// Don't render wrapper when done and nothing to show
|
|
13
|
+
if (!isActive && !error && !children) {
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
return (_jsxs(Box, { alignSelf: "flex-start", flexDirection: "column", children: [isLoading && (_jsxs(Box, { marginLeft: 1, children: [_jsx(Text, { color: getTextColor(isActive), children: "Listing capabilities. " }), _jsx(Spinner, {})] })), error && (_jsx(Box, { marginTop: 1, marginLeft: 1, children: _jsxs(Text, { color: Colors.Status.Error, children: ["Error: ", error] }) })), children] }));
|
|
17
|
+
};
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { Box, Text } from 'ink';
|
|
3
|
-
import { getTaskColors, getTaskTypeLabel } from '
|
|
4
|
-
import { DebugLevel } from '
|
|
3
|
+
import { getTaskColors, getTaskTypeLabel } from '../../services/colors.js';
|
|
4
|
+
import { DebugLevel } from '../../configuration/types.js';
|
|
5
5
|
import { Separator } from './Separator.js';
|
|
6
|
-
import { ComponentStatus } from '
|
|
6
|
+
import { ComponentStatus } from '../../types/components.js';
|
|
7
7
|
export function Label({ description, taskType, showType = false, status = ComponentStatus.Done, debug = DebugLevel.None, }) {
|
|
8
8
|
const colors = getTaskColors(taskType, status);
|
|
9
9
|
return (_jsxs(Box, { children: [_jsx(Text, { color: colors.description, children: description }), showType && (_jsxs(_Fragment, { children: [_jsx(Separator, {}), _jsx(Text, { color: colors.type, children: getTaskTypeLabel(taskType, debug) })] }))] }));
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { Box, Text } from 'ink';
|
|
3
|
-
import { Palette } from '
|
|
3
|
+
import { Palette } from '../../services/colors.js';
|
|
4
4
|
import { Separator } from './Separator.js';
|
|
5
5
|
export const List = ({ items, level = 0, highlightedIndex = null, highlightedParentIndex = null, showType = false, compact = false, }) => {
|
|
6
6
|
const marginLeft = level > 0 ? 2 : 0;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { Box, Text } from 'ink';
|
|
3
|
-
import { Palette } from '
|
|
4
|
-
import { ExecutionStatus } from '
|
|
3
|
+
import { Palette } from '../../services/colors.js';
|
|
4
|
+
import { ExecutionStatus } from '../../services/shell.js';
|
|
5
5
|
const MAX_LINES = 8;
|
|
6
6
|
const MAX_WIDTH = 75;
|
|
7
7
|
const SHORT_OUTPUT_THRESHOLD = 4;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Box } from 'ink';
|
|
3
|
+
import { ComponentStatus } from '../../types/components.js';
|
|
4
|
+
import { Message } from './Message.js';
|
|
5
|
+
import { Spinner } from './Spinner.js';
|
|
6
|
+
export const RefinementView = ({ text, status }) => {
|
|
7
|
+
const isActive = status === ComponentStatus.Active;
|
|
8
|
+
return (_jsxs(Box, { gap: 1, children: [_jsx(Message, { text: text, status: status }), isActive && _jsx(Spinner, {})] }));
|
|
9
|
+
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { Box, Text } from 'ink';
|
|
3
|
-
import { Colors, getOriginColor } from '
|
|
3
|
+
import { Colors, getOriginColor } from '../../services/colors.js';
|
|
4
4
|
function CapabilityItem({ name, description, origin, isIncomplete, }) {
|
|
5
5
|
const color = getOriginColor(origin);
|
|
6
6
|
return (_jsxs(Box, { children: [_jsx(Text, { children: "- " }), _jsx(Text, { color: color, children: name }), _jsxs(Text, { children: [" - ", description] }), isIncomplete && _jsx(Text, { color: Colors.Status.Warning, children: " (incomplete)" })] }));
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Box } from 'ink';
|
|
3
|
+
import { ComponentStatus } from '../../types/components.js';
|
|
4
|
+
import { TaskType, } from '../../types/types.js';
|
|
5
|
+
import { DebugLevel } from '../../configuration/types.js';
|
|
6
|
+
import { getTaskColors, getTaskTypeLabel, Palette, } from '../../services/colors.js';
|
|
7
|
+
import { Label } from './Label.js';
|
|
8
|
+
import { List } from './List.js';
|
|
9
|
+
export function taskToListItem(task, highlightedChildIndex = null, isDefineTaskWithoutSelection = false, status = ComponentStatus.Done, debug = DebugLevel.None) {
|
|
10
|
+
const taskColors = getTaskColors(task.type, status);
|
|
11
|
+
// Determine description color based on status
|
|
12
|
+
let descriptionColor = taskColors.description;
|
|
13
|
+
if (status === ComponentStatus.Pending) {
|
|
14
|
+
descriptionColor = Palette.SoftWhite;
|
|
15
|
+
}
|
|
16
|
+
const item = {
|
|
17
|
+
description: {
|
|
18
|
+
text: task.action,
|
|
19
|
+
color: descriptionColor,
|
|
20
|
+
},
|
|
21
|
+
type: { text: getTaskTypeLabel(task.type, debug), color: taskColors.type },
|
|
22
|
+
children: [],
|
|
23
|
+
};
|
|
24
|
+
// Mark define tasks with right arrow when no selection has been made
|
|
25
|
+
if (isDefineTaskWithoutSelection) {
|
|
26
|
+
item.marker = ' → ';
|
|
27
|
+
item.markerColor = getTaskColors(TaskType.Schedule, status).type;
|
|
28
|
+
}
|
|
29
|
+
// Add children for Define tasks with options
|
|
30
|
+
if (task.type === TaskType.Define && Array.isArray(task.params?.options)) {
|
|
31
|
+
const options = task.params.options;
|
|
32
|
+
item.children = options.map((option, index) => {
|
|
33
|
+
// Determine the type based on selection state
|
|
34
|
+
let childType = TaskType.Select;
|
|
35
|
+
if (highlightedChildIndex !== null) {
|
|
36
|
+
// A selection was made - mark others as discarded
|
|
37
|
+
childType =
|
|
38
|
+
index === highlightedChildIndex ? TaskType.Execute : TaskType.Discard;
|
|
39
|
+
}
|
|
40
|
+
const colors = getTaskColors(childType, status);
|
|
41
|
+
const planColors = getTaskColors(TaskType.Schedule, status);
|
|
42
|
+
return {
|
|
43
|
+
description: {
|
|
44
|
+
text: option.name,
|
|
45
|
+
color: colors.description,
|
|
46
|
+
highlightedColor: planColors.description,
|
|
47
|
+
},
|
|
48
|
+
type: {
|
|
49
|
+
text: getTaskTypeLabel(childType, debug),
|
|
50
|
+
color: colors.type,
|
|
51
|
+
highlightedColor: planColors.type,
|
|
52
|
+
},
|
|
53
|
+
};
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
// Add children for Group tasks with subtasks
|
|
57
|
+
const scheduledTask = task;
|
|
58
|
+
if (task.type === TaskType.Group &&
|
|
59
|
+
scheduledTask.subtasks &&
|
|
60
|
+
Array.isArray(scheduledTask.subtasks) &&
|
|
61
|
+
scheduledTask.subtasks.length > 0) {
|
|
62
|
+
item.children = scheduledTask.subtasks.map((subtask) => {
|
|
63
|
+
const subtaskColors = getTaskColors(subtask.type, status);
|
|
64
|
+
return {
|
|
65
|
+
description: {
|
|
66
|
+
text: subtask.action,
|
|
67
|
+
color: Palette.AshGray,
|
|
68
|
+
},
|
|
69
|
+
type: {
|
|
70
|
+
text: getTaskTypeLabel(subtask.type, debug),
|
|
71
|
+
color: subtaskColors.type,
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
return item;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Schedule view: Displays task list with navigation
|
|
80
|
+
*/
|
|
81
|
+
export const ScheduleView = ({ status, message, tasks, highlightedIndex, currentDefineGroupIndex, completedSelections, debug = DebugLevel.None, }) => {
|
|
82
|
+
const isActive = status === ComponentStatus.Active;
|
|
83
|
+
// Use compact mode when all tasks are Config type
|
|
84
|
+
const isCompact = tasks.every((task) => task.type === TaskType.Config);
|
|
85
|
+
// Find all Define tasks
|
|
86
|
+
const defineTaskIndices = tasks
|
|
87
|
+
.map((t, idx) => (t.type === TaskType.Define ? idx : -1))
|
|
88
|
+
.filter((idx) => idx !== -1);
|
|
89
|
+
// Get the current active define task
|
|
90
|
+
const currentDefineTaskIndex = defineTaskIndices[currentDefineGroupIndex] ?? -1;
|
|
91
|
+
const listItems = tasks.map((task, idx) => {
|
|
92
|
+
// Find which define group this task belongs to (if any)
|
|
93
|
+
const defineGroupIndex = defineTaskIndices.indexOf(idx);
|
|
94
|
+
const isDefineTask = defineGroupIndex !== -1;
|
|
95
|
+
// Determine child selection state
|
|
96
|
+
let childIndex = null;
|
|
97
|
+
if (isDefineTask) {
|
|
98
|
+
if (defineGroupIndex < currentDefineGroupIndex) {
|
|
99
|
+
// Previously completed group - show the selection
|
|
100
|
+
childIndex = completedSelections[defineGroupIndex] ?? null;
|
|
101
|
+
}
|
|
102
|
+
else if (defineGroupIndex === currentDefineGroupIndex) {
|
|
103
|
+
// Current active group - show live navigation unless not active
|
|
104
|
+
if (!isActive) {
|
|
105
|
+
// If not active, show the completed selection for this group too
|
|
106
|
+
childIndex = completedSelections[defineGroupIndex] ?? null;
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
childIndex = null;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
// Show arrow on current active define task when no child is highlighted and is active
|
|
114
|
+
const isDefineWithoutSelection = isDefineTask &&
|
|
115
|
+
defineGroupIndex === currentDefineGroupIndex &&
|
|
116
|
+
highlightedIndex === null &&
|
|
117
|
+
isActive;
|
|
118
|
+
return taskToListItem(task, childIndex, isDefineWithoutSelection, status, debug);
|
|
119
|
+
});
|
|
120
|
+
return (_jsxs(Box, { flexDirection: "column", children: [message && (_jsx(Box, { marginBottom: 1, marginLeft: 1, children: _jsx(Label, { description: message, taskType: TaskType.Schedule, showType: debug !== DebugLevel.None, status: status, debug: debug }) })), _jsx(Box, { marginLeft: 1, children: _jsx(List, { items: listItems, highlightedIndex: currentDefineTaskIndex >= 0 ? highlightedIndex : null, highlightedParentIndex: currentDefineTaskIndex, showType: debug !== DebugLevel.None, compact: isCompact }) })] }));
|
|
121
|
+
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { Text } from 'ink';
|
|
3
|
-
import { Colors } from '
|
|
3
|
+
import { Colors } from '../../services/colors.js';
|
|
4
4
|
export const Separator = ({ color = Colors.Label.Discarded, spaces = 1, }) => {
|
|
5
5
|
const spacing = ' '.repeat(spaces);
|
|
6
6
|
return (_jsxs(Text, { color: color, children: [spacing, "\u203A", spacing] }));
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { useEffect, useState } from 'react';
|
|
3
3
|
import { Text } from 'ink';
|
|
4
|
-
import { Palette } from '
|
|
4
|
+
import { Palette } from '../../services/colors.js';
|
|
5
5
|
const FRAMES = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
|
|
6
6
|
const INTERVAL = 80;
|
|
7
7
|
const CYCLE = FRAMES.length * INTERVAL;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { Box, Text } from 'ink';
|
|
3
|
-
import { getStatusColors, Palette, STATUS_ICONS } from '
|
|
4
|
-
import { ExecutionStatus } from '
|
|
5
|
-
import { formatDuration } from '
|
|
3
|
+
import { getStatusColors, Palette, STATUS_ICONS, } from '../../services/colors.js';
|
|
4
|
+
import { ExecutionStatus } from '../../services/shell.js';
|
|
5
|
+
import { formatDuration } from '../../services/utils.js';
|
|
6
6
|
import { Spinner } from './Spinner.js';
|
|
7
7
|
/**
|
|
8
8
|
* Pure display component for a single subtask.
|
|
@@ -12,11 +12,11 @@ export function SubtaskView({ label, command, status, elapsed, }) {
|
|
|
12
12
|
const colors = getStatusColors(status);
|
|
13
13
|
const isCancelled = status === ExecutionStatus.Cancelled;
|
|
14
14
|
const isAborted = status === ExecutionStatus.Aborted;
|
|
15
|
-
const shouldStrikethrough = isCancelled || isAborted;
|
|
16
15
|
const isFinished = status === ExecutionStatus.Success ||
|
|
17
16
|
status === ExecutionStatus.Failed ||
|
|
18
17
|
status === ExecutionStatus.Aborted;
|
|
19
18
|
// Apply strikethrough for cancelled and aborted tasks
|
|
19
|
+
const shouldStrikethrough = isCancelled || isAborted;
|
|
20
20
|
const formatText = (text) => shouldStrikethrough ? text.split('').join('\u0336') + '\u0336' : text;
|
|
21
21
|
return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { paddingLeft: 2, gap: 1, children: [_jsx(Text, { color: colors.icon, children: STATUS_ICONS[status] }), _jsx(Text, { color: colors.description, children: shouldStrikethrough
|
|
22
22
|
? formatText(label || command.description)
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { Box, Text } from 'ink';
|
|
4
|
+
const DEFAULT_WIDTH = 80;
|
|
5
|
+
const DEFAULT_PADDING = 1;
|
|
6
|
+
export const Cell = ({ children, padding = DEFAULT_PADDING }) => (_jsx(Box, { paddingX: padding, children: _jsx(Text, { wrap: "wrap", children: children }) }));
|
|
7
|
+
export const Column = ({ children, width }) => (_jsx(Box, { flexDirection: "column", width: width, children: children }));
|
|
8
|
+
const Row = ({ children, color, innerWidth }) => (_jsxs(Box, { children: [_jsx(Text, { color: color, children: '│' }), _jsx(Box, { width: innerWidth, children: children }), _jsx(Text, { color: color, children: '│' })] }));
|
|
9
|
+
export const Table = ({ data, width = DEFAULT_WIDTH, color }) => {
|
|
10
|
+
const innerWidth = width - 2;
|
|
11
|
+
const TOP = '┌' + '─'.repeat(innerWidth) + '┐';
|
|
12
|
+
const DIV = '├' + '─'.repeat(innerWidth) + '┤';
|
|
13
|
+
const BOT = '└' + '─'.repeat(innerWidth) + '┘';
|
|
14
|
+
return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { color: color, children: TOP }), data.map((content, index) => (_jsxs(React.Fragment, { children: [index > 0 && _jsx(Text, { color: color, children: DIV }), _jsx(Row, { color: color, innerWidth: innerWidth, children: _jsx(Cell, { children: content }) })] }, index))), _jsx(Text, { color: color, children: BOT })] }));
|
|
15
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Box } from 'ink';
|
|
3
|
+
import { loadDebugSetting } from '../../configuration/io.js';
|
|
4
|
+
import { DebugLevel } from '../../configuration/types.js';
|
|
5
|
+
import { Output } from './Output.js';
|
|
6
|
+
import { SubtaskView } from './Subtask.js';
|
|
7
|
+
/**
|
|
8
|
+
* Pure display component for a task.
|
|
9
|
+
* Combines SubtaskView (label/command/status) with Output (stdout/stderr).
|
|
10
|
+
* Output is shown during active execution, or in timeline only with debug mode.
|
|
11
|
+
*/
|
|
12
|
+
export function TaskView({ label, command, status, elapsed, output, isFinished, isActive = false, }) {
|
|
13
|
+
const stdout = output?.stdout ?? '';
|
|
14
|
+
const stderr = output?.stderr ?? '';
|
|
15
|
+
// Show output during active execution, or in timeline only with debug enabled
|
|
16
|
+
const showOutput = isActive || loadDebugSetting() !== DebugLevel.None;
|
|
17
|
+
return (_jsxs(Box, { flexDirection: "column", children: [_jsx(SubtaskView, { label: label, command: command, status: status, elapsed: elapsed }), showOutput && (_jsx(Output, { stdout: stdout, stderr: stderr, isFinished: isFinished, status: status }, `${stdout.length}-${stderr.length}`))] }));
|
|
18
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Text } from 'ink';
|
|
3
|
+
import { Palette } from '../../services/colors.js';
|
|
4
|
+
import { ExecutionStatus } from '../../services/shell.js';
|
|
5
|
+
/**
|
|
6
|
+
* Branching symbols for tree-like display
|
|
7
|
+
*/
|
|
8
|
+
const BRANCH_MIDDLE = '├─';
|
|
9
|
+
const BRANCH_LAST = '└─';
|
|
10
|
+
/**
|
|
11
|
+
* Labels for each status
|
|
12
|
+
*/
|
|
13
|
+
const STATUS_LABELS = {
|
|
14
|
+
[ExecutionStatus.Pending]: 'Next:',
|
|
15
|
+
[ExecutionStatus.Failed]: 'Skipped:',
|
|
16
|
+
[ExecutionStatus.Aborted]: 'Cancelled:',
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Upcoming: Displays upcoming tasks in a tree-like structure
|
|
20
|
+
*/
|
|
21
|
+
export const Upcoming = ({ items, status = ExecutionStatus.Pending, }) => {
|
|
22
|
+
if (items.length === 0)
|
|
23
|
+
return null;
|
|
24
|
+
const strikethrough = status !== ExecutionStatus.Pending;
|
|
25
|
+
return (_jsxs(Box, { flexDirection: "column", marginLeft: 1, children: [_jsx(Text, { color: Palette.Gray, children: STATUS_LABELS[status] }), items.map((name, index) => {
|
|
26
|
+
const isLast = index === items.length - 1;
|
|
27
|
+
const symbol = isLast ? BRANCH_LAST : BRANCH_MIDDLE;
|
|
28
|
+
return (_jsx(Box, { marginLeft: 1, children: _jsxs(Text, { color: Palette.DarkGray, strikethrough: strikethrough, children: [symbol, " ", name] }) }, index));
|
|
29
|
+
})] }));
|
|
30
|
+
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { Box, Text } from 'ink';
|
|
3
|
-
import { Colors } from '
|
|
3
|
+
import { Colors } from '../../services/colors.js';
|
|
4
4
|
export function UserQuery({ children }) {
|
|
5
5
|
return (_jsx(Box, { paddingX: 1, alignSelf: "flex-start", backgroundColor: Colors.Background.UserQuery, children: _jsx(Text, { color: Colors.Text.UserQuery, children: children }) }));
|
|
6
6
|
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Text } from 'ink';
|
|
3
|
+
import { ComponentStatus } from '../../types/components.js';
|
|
4
|
+
import { Colors, getTextColor } from '../../services/colors.js';
|
|
5
|
+
import { Spinner } from './Spinner.js';
|
|
6
|
+
/**
|
|
7
|
+
* Validate view: Displays validation and config prompt
|
|
8
|
+
*/
|
|
9
|
+
export const ValidateView = ({ status, completionMessage, error, }) => {
|
|
10
|
+
const isActive = status === ComponentStatus.Active;
|
|
11
|
+
const isLoading = isActive && !completionMessage && !error;
|
|
12
|
+
// Don't render when not active and nothing to show
|
|
13
|
+
if (!isActive && !completionMessage && !error) {
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
return (_jsxs(Box, { alignSelf: "flex-start", flexDirection: "column", children: [isLoading && (_jsxs(Box, { marginLeft: 1, children: [_jsxs(Text, { color: getTextColor(isActive), children: ["Validating configuration requirements.", ' '] }), _jsx(Spinner, {})] })), completionMessage && (_jsx(Box, { marginLeft: 1, children: _jsx(Text, { color: getTextColor(isActive), children: completionMessage }) })), error && (_jsx(Box, { marginTop: 1, children: _jsxs(Text, { color: Colors.Status.Error, children: ["Error: ", error] }) }))] }));
|
|
17
|
+
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { Box, Text } from 'ink';
|
|
3
|
-
import { Palette } from '
|
|
3
|
+
import { Palette } from '../../services/colors.js';
|
|
4
4
|
import { Panel } from './Panel.js';
|
|
5
5
|
export function Welcome({ app }) {
|
|
6
6
|
return (_jsx(Box, { alignSelf: "flex-start", children: _jsxs(Panel, { children: [_jsx(Header, { app: app }), _jsx(Description, { description: app.description }), _jsx(Usage, {})] }) }));
|
|
@@ -4,7 +4,7 @@ import { getConfigPath, loadConfig } from './io.js';
|
|
|
4
4
|
import { getConfigSchema } from './schema.js';
|
|
5
5
|
import { getConfigLabel } from './labels.js';
|
|
6
6
|
import { defaultFileSystem } from '../services/filesystem.js';
|
|
7
|
-
import { StepType } from '../
|
|
7
|
+
import { StepType } from '../components/controllers/Config.js';
|
|
8
8
|
export function createConfigSteps() {
|
|
9
9
|
// Use schema-based config step generation for required Anthropic settings
|
|
10
10
|
return createConfigStepsFromSchema(['anthropic.key', 'anthropic.model']);
|