executant 1.8.0 → 1.9.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/index.js +215 -111
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -863,7 +863,7 @@ init_update();
|
|
|
863
863
|
|
|
864
864
|
// src/ui/App.tsx
|
|
865
865
|
import { useEffect as useEffect2, useReducer, useState } from "react";
|
|
866
|
-
import { Box as
|
|
866
|
+
import { Box as Box5, Text as Text5, useApp, useStdin } from "ink";
|
|
867
867
|
|
|
868
868
|
// src/ui/KeyboardHandler.tsx
|
|
869
869
|
import { useInput } from "ink";
|
|
@@ -931,45 +931,70 @@ function reducer(state, event) {
|
|
|
931
931
|
status: "running",
|
|
932
932
|
startTime: Date.now()
|
|
933
933
|
});
|
|
934
|
-
case "step:complete":
|
|
934
|
+
case "step:complete": {
|
|
935
|
+
const prev = state.tasks[event.index]?.iterationHistory;
|
|
936
|
+
const iterationHistory = prev?.length ? prev.map(
|
|
937
|
+
(r) => r.status === "running" ? { ...r, status: "complete", endTime: Date.now() } : r
|
|
938
|
+
) : void 0;
|
|
935
939
|
return {
|
|
936
940
|
...updateTask(state, event.index, {
|
|
937
941
|
status: "complete",
|
|
938
|
-
endTime: Date.now()
|
|
942
|
+
endTime: Date.now(),
|
|
943
|
+
...iterationHistory ? { iterationHistory } : {}
|
|
939
944
|
}),
|
|
940
945
|
currentIndex: event.index + 1
|
|
941
946
|
};
|
|
942
|
-
|
|
947
|
+
}
|
|
948
|
+
case "step:error": {
|
|
949
|
+
const prev = state.tasks[event.index]?.iterationHistory;
|
|
950
|
+
const iterationHistory = prev?.length ? prev.map(
|
|
951
|
+
(r) => r.status === "running" ? { ...r, status: "error", endTime: Date.now() } : r
|
|
952
|
+
) : void 0;
|
|
943
953
|
return {
|
|
944
954
|
...updateTask(state, event.index, {
|
|
945
955
|
status: "error",
|
|
946
956
|
endTime: Date.now(),
|
|
947
|
-
error: event.error
|
|
957
|
+
error: event.error,
|
|
958
|
+
...iterationHistory ? { iterationHistory } : {}
|
|
948
959
|
}),
|
|
949
960
|
currentIndex: event.index + 1
|
|
950
961
|
};
|
|
962
|
+
}
|
|
951
963
|
case "step:skip":
|
|
952
964
|
return {
|
|
953
965
|
...updateTask(state, event.index, { status: "skipped" }),
|
|
954
966
|
currentIndex: event.index + 1
|
|
955
967
|
};
|
|
956
|
-
case "step:iteration":
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
total: event.total,
|
|
961
|
-
item: event.item
|
|
962
|
-
},
|
|
963
|
-
inner: void 0
|
|
964
|
-
});
|
|
965
|
-
case "step:inner":
|
|
968
|
+
case "step:iteration": {
|
|
969
|
+
const prev = (state.tasks[event.index]?.iterationHistory ?? []).map(
|
|
970
|
+
(r) => r.status === "running" ? { ...r, status: "complete", endTime: Date.now() } : r
|
|
971
|
+
);
|
|
966
972
|
return updateTask(state, event.index, {
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
973
|
+
iterationHistory: [
|
|
974
|
+
...prev,
|
|
975
|
+
{
|
|
976
|
+
item: event.item,
|
|
977
|
+
iteration: event.iteration,
|
|
978
|
+
total: event.total,
|
|
979
|
+
status: "running",
|
|
980
|
+
startTime: Date.now()
|
|
981
|
+
}
|
|
982
|
+
]
|
|
972
983
|
});
|
|
984
|
+
}
|
|
985
|
+
case "step:inner": {
|
|
986
|
+
const iterationHistory = (state.tasks[event.index]?.iterationHistory ?? []).map(
|
|
987
|
+
(r) => r.status === "running" ? {
|
|
988
|
+
...r,
|
|
989
|
+
inner: {
|
|
990
|
+
index: event.innerIndex,
|
|
991
|
+
total: event.innerTotal,
|
|
992
|
+
name: event.name
|
|
993
|
+
}
|
|
994
|
+
} : r
|
|
995
|
+
);
|
|
996
|
+
return updateTask(state, event.index, { iterationHistory });
|
|
997
|
+
}
|
|
973
998
|
case "output:text": {
|
|
974
999
|
const idx = event.index;
|
|
975
1000
|
if (idx >= state.tasks.length) return state;
|
|
@@ -1024,20 +1049,6 @@ function appendLine(state, index, line) {
|
|
|
1024
1049
|
// src/ui/TaskRow.tsx
|
|
1025
1050
|
import { Box, Text } from "ink";
|
|
1026
1051
|
|
|
1027
|
-
// src/ui/utils.ts
|
|
1028
|
-
var SPINNER = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
1029
|
-
var EXIT_DELAY_MS = 300;
|
|
1030
|
-
function formatHeaderElapsed(start, end) {
|
|
1031
|
-
const ms = (end ?? Date.now()) - start;
|
|
1032
|
-
return ms < 1e3 ? `${ms}ms` : `${(ms / 1e3).toFixed(1)}s`;
|
|
1033
|
-
}
|
|
1034
|
-
function formatTaskElapsed(start, end, status) {
|
|
1035
|
-
if (!start) return "";
|
|
1036
|
-
const ms = (end ?? Date.now()) - start;
|
|
1037
|
-
if (status === "running" || status === "complete" || status === "error") return `${(ms / 1e3).toFixed(1)}s`;
|
|
1038
|
-
return "";
|
|
1039
|
-
}
|
|
1040
|
-
|
|
1041
1052
|
// src/ui/theme.ts
|
|
1042
1053
|
import { createRequire } from "node:module";
|
|
1043
1054
|
import { oklchToHex } from "@coston/design-tokens";
|
|
@@ -1066,6 +1077,32 @@ var theme = {
|
|
|
1066
1077
|
// log pane border
|
|
1067
1078
|
};
|
|
1068
1079
|
|
|
1080
|
+
// src/ui/utils.ts
|
|
1081
|
+
var SPINNER = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
1082
|
+
var STATUS_ICON = {
|
|
1083
|
+
complete: "\u2713",
|
|
1084
|
+
error: "\u2717",
|
|
1085
|
+
skipped: "\u2298",
|
|
1086
|
+
pending: "\xB7"
|
|
1087
|
+
};
|
|
1088
|
+
var STATUS_COLOR = {
|
|
1089
|
+
complete: theme.success,
|
|
1090
|
+
error: theme.error,
|
|
1091
|
+
pending: theme.muted
|
|
1092
|
+
};
|
|
1093
|
+
var EXIT_DELAY_MS = 300;
|
|
1094
|
+
function formatHeaderElapsed(start, end) {
|
|
1095
|
+
const ms = (end ?? Date.now()) - start;
|
|
1096
|
+
return ms < 1e3 ? `${ms}ms` : `${(ms / 1e3).toFixed(1)}s`;
|
|
1097
|
+
}
|
|
1098
|
+
function formatTaskElapsed(start, end, status) {
|
|
1099
|
+
if (!start) return "";
|
|
1100
|
+
const ms = (end ?? Date.now()) - start;
|
|
1101
|
+
if (status === "running" || status === "complete" || status === "error")
|
|
1102
|
+
return `${(ms / 1e3).toFixed(1)}s`;
|
|
1103
|
+
return "";
|
|
1104
|
+
}
|
|
1105
|
+
|
|
1069
1106
|
// src/ui/TaskRow.tsx
|
|
1070
1107
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
1071
1108
|
function TaskRow({ taskState, isActive, index, tick }) {
|
|
@@ -1073,9 +1110,8 @@ function TaskRow({ taskState, isActive, index, tick }) {
|
|
|
1073
1110
|
const icon = statusIcon(status, tick);
|
|
1074
1111
|
const color = statusColor(status, isActive);
|
|
1075
1112
|
const elapsed = formatTaskElapsed(startTime, endTime, status);
|
|
1076
|
-
const iterInfo =
|
|
1077
|
-
const
|
|
1078
|
-
const label = `${index + 1}. ${task.name}${iterInfo}${innerInfo}`;
|
|
1113
|
+
const iterInfo = formatIterCount(taskState.iterationHistory);
|
|
1114
|
+
const label = `${index + 1}. ${task.name}${iterInfo}`;
|
|
1079
1115
|
return /* @__PURE__ */ jsxs(Box, { children: [
|
|
1080
1116
|
/* @__PURE__ */ jsxs(Text, { color, children: [
|
|
1081
1117
|
icon,
|
|
@@ -1088,17 +1124,6 @@ function TaskRow({ taskState, isActive, index, tick }) {
|
|
|
1088
1124
|
] })
|
|
1089
1125
|
] });
|
|
1090
1126
|
}
|
|
1091
|
-
var STATUS_ICON = {
|
|
1092
|
-
complete: "\u2713",
|
|
1093
|
-
error: "\u2717",
|
|
1094
|
-
skipped: "\u2298",
|
|
1095
|
-
pending: "\xB7"
|
|
1096
|
-
};
|
|
1097
|
-
var STATUS_COLOR = {
|
|
1098
|
-
complete: theme.success,
|
|
1099
|
-
error: theme.error,
|
|
1100
|
-
pending: theme.muted
|
|
1101
|
-
};
|
|
1102
1127
|
function statusIcon(status, tick) {
|
|
1103
1128
|
return status === "running" ? SPINNER[tick % SPINNER.length] : STATUS_ICON[status] ?? "\xB7";
|
|
1104
1129
|
}
|
|
@@ -1106,16 +1131,74 @@ function statusColor(status, isActive) {
|
|
|
1106
1131
|
if (isActive && status === "running") return theme.primary;
|
|
1107
1132
|
return STATUS_COLOR[status] ?? theme.foreground;
|
|
1108
1133
|
}
|
|
1134
|
+
function formatIterCount(history) {
|
|
1135
|
+
if (!history?.length) return "";
|
|
1136
|
+
const total = history[0].total;
|
|
1137
|
+
const running = history.find((r) => r.status === "running");
|
|
1138
|
+
const current = running?.iteration ?? history.length;
|
|
1139
|
+
return ` (${current}/${total})`;
|
|
1140
|
+
}
|
|
1109
1141
|
|
|
1110
|
-
// src/ui/
|
|
1142
|
+
// src/ui/IterationRow.tsx
|
|
1111
1143
|
import { Box as Box2, Text as Text2 } from "ink";
|
|
1112
|
-
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
1144
|
+
import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
1145
|
+
function IterationRow({ record, tick }) {
|
|
1146
|
+
const icon = record.status === "running" ? SPINNER[tick % SPINNER.length] : STATUS_ICON[record.status] ?? "\xB7";
|
|
1147
|
+
const color = STATUS_COLOR[record.status] ?? theme.primary;
|
|
1148
|
+
const innerText = record.inner ? ` \u2014 ${stripItem(record.inner.name, record.item)} [${record.inner.index + 1}/${record.inner.total}]` : "";
|
|
1149
|
+
const ms = (record.endTime ?? Date.now()) - record.startTime;
|
|
1150
|
+
const elapsed = `${(ms / 1e3).toFixed(1)}s`;
|
|
1151
|
+
return /* @__PURE__ */ jsxs2(Box2, { children: [
|
|
1152
|
+
/* @__PURE__ */ jsx2(Text2, { dimColor: true, children: " " }),
|
|
1153
|
+
/* @__PURE__ */ jsx2(Text2, { color, children: icon }),
|
|
1154
|
+
/* @__PURE__ */ jsx2(Text2, { children: " " }),
|
|
1155
|
+
/* @__PURE__ */ jsxs2(
|
|
1156
|
+
Text2,
|
|
1157
|
+
{
|
|
1158
|
+
color: record.status === "running" ? theme.foreground : theme.muted,
|
|
1159
|
+
children: [
|
|
1160
|
+
record.item,
|
|
1161
|
+
innerText
|
|
1162
|
+
]
|
|
1163
|
+
}
|
|
1164
|
+
),
|
|
1165
|
+
/* @__PURE__ */ jsxs2(Text2, { dimColor: true, children: [
|
|
1166
|
+
" ",
|
|
1167
|
+
elapsed
|
|
1168
|
+
] })
|
|
1169
|
+
] });
|
|
1170
|
+
}
|
|
1171
|
+
function stripItem(name, item) {
|
|
1172
|
+
if (!name.includes(item)) return name;
|
|
1173
|
+
const stripped = name.replace(item, "").replace(/\s{2,}/g, " ").replace(/^[\s\-—–]+/, "").replace(/[\s\-—–]+$/, "").trim();
|
|
1174
|
+
return stripped || name;
|
|
1175
|
+
}
|
|
1176
|
+
function isRepeatStyle(history) {
|
|
1177
|
+
return history.every((r) => r.item === String(r.iteration));
|
|
1178
|
+
}
|
|
1179
|
+
function IterationList({
|
|
1180
|
+
iterationHistory,
|
|
1181
|
+
tick,
|
|
1182
|
+
maxVisible
|
|
1183
|
+
}) {
|
|
1184
|
+
if (isRepeatStyle(iterationHistory)) return null;
|
|
1185
|
+
const hidden = iterationHistory.length - maxVisible;
|
|
1186
|
+
const visible = iterationHistory.slice(-maxVisible);
|
|
1187
|
+
return /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
1188
|
+
hidden > 0 && /* @__PURE__ */ jsx2(Text2, { dimColor: true, children: ` \u2026 ${hidden} earlier` }),
|
|
1189
|
+
visible.map((record) => /* @__PURE__ */ jsx2(IterationRow, { record, tick }, record.iteration))
|
|
1190
|
+
] });
|
|
1191
|
+
}
|
|
1192
|
+
|
|
1193
|
+
// src/ui/LogPane.tsx
|
|
1194
|
+
import { Box as Box3, Text as Text3 } from "ink";
|
|
1195
|
+
import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
1113
1196
|
function LogPane({ lines, isActive = false, maxLines = 15 }) {
|
|
1114
1197
|
const visible = lines.slice(-maxLines);
|
|
1115
1198
|
if (visible.length === 0) {
|
|
1116
|
-
return /* @__PURE__ */
|
|
1199
|
+
return /* @__PURE__ */ jsx3(Box3, { marginTop: 1, children: /* @__PURE__ */ jsx3(Text3, { dimColor: true, children: isActive ? "\u2838 waiting for output\u2026" : "\u2014 no output yet \u2014" }) });
|
|
1117
1200
|
}
|
|
1118
|
-
return /* @__PURE__ */
|
|
1201
|
+
return /* @__PURE__ */ jsx3(Box3, { flexDirection: "column", marginTop: 1, borderStyle: "single", borderColor: theme.border, paddingX: 1, children: visible.map((line, i) => /* @__PURE__ */ jsx3(
|
|
1119
1202
|
LogLine,
|
|
1120
1203
|
{
|
|
1121
1204
|
text: line,
|
|
@@ -1125,29 +1208,29 @@ function LogPane({ lines, isActive = false, maxLines = 15 }) {
|
|
|
1125
1208
|
)) });
|
|
1126
1209
|
}
|
|
1127
1210
|
function LogLine({ text, cursor }) {
|
|
1128
|
-
const suffix = cursor ? /* @__PURE__ */
|
|
1211
|
+
const suffix = cursor ? /* @__PURE__ */ jsx3(Text3, { color: theme.primary, children: " \u258C" }) : null;
|
|
1129
1212
|
if (/^\[[\w:]+\]/.test(text)) {
|
|
1130
1213
|
const bracket = text.match(/^\[[\w:]+\]/)?.[0] ?? "";
|
|
1131
1214
|
const rest = text.slice(bracket.length);
|
|
1132
|
-
return /* @__PURE__ */
|
|
1133
|
-
/* @__PURE__ */
|
|
1134
|
-
/* @__PURE__ */
|
|
1215
|
+
return /* @__PURE__ */ jsxs3(Text3, { children: [
|
|
1216
|
+
/* @__PURE__ */ jsx3(Text3, { color: theme.primary, children: bracket }),
|
|
1217
|
+
/* @__PURE__ */ jsx3(Text3, { children: rest }),
|
|
1135
1218
|
suffix
|
|
1136
1219
|
] });
|
|
1137
1220
|
}
|
|
1138
|
-
if (/^\s*\$\s/.test(text)) return /* @__PURE__ */
|
|
1221
|
+
if (/^\s*\$\s/.test(text)) return /* @__PURE__ */ jsxs3(Text3, { color: theme.warning, children: [
|
|
1139
1222
|
text,
|
|
1140
1223
|
suffix
|
|
1141
1224
|
] });
|
|
1142
|
-
if (text.startsWith("[warn]")) return /* @__PURE__ */
|
|
1225
|
+
if (text.startsWith("[warn]")) return /* @__PURE__ */ jsxs3(Text3, { color: theme.warning, children: [
|
|
1143
1226
|
text,
|
|
1144
1227
|
suffix
|
|
1145
1228
|
] });
|
|
1146
|
-
if (text.startsWith("[error]")) return /* @__PURE__ */
|
|
1229
|
+
if (text.startsWith("[error]")) return /* @__PURE__ */ jsxs3(Text3, { color: theme.error, children: [
|
|
1147
1230
|
text,
|
|
1148
1231
|
suffix
|
|
1149
1232
|
] });
|
|
1150
|
-
return /* @__PURE__ */
|
|
1233
|
+
return /* @__PURE__ */ jsxs3(Text3, { children: [
|
|
1151
1234
|
text,
|
|
1152
1235
|
suffix
|
|
1153
1236
|
] });
|
|
@@ -1167,8 +1250,8 @@ function useInterval(callback, delayMs) {
|
|
|
1167
1250
|
}
|
|
1168
1251
|
|
|
1169
1252
|
// src/ui/BrandMark.tsx
|
|
1170
|
-
import { Box as
|
|
1171
|
-
import { jsx as
|
|
1253
|
+
import { Box as Box4, Text as Text4 } from "ink";
|
|
1254
|
+
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
1172
1255
|
var BRAND = "Executant";
|
|
1173
1256
|
var SWEEP_TICKS = BRAND.length * 2;
|
|
1174
1257
|
var GAP_TICKS = 30;
|
|
@@ -1181,11 +1264,12 @@ function charColor(charIndex, tick, isActive) {
|
|
|
1181
1264
|
return charIndex === charPos ? theme.primaryLight : theme.primary;
|
|
1182
1265
|
}
|
|
1183
1266
|
function BrandMark({ tick, isActive }) {
|
|
1184
|
-
return /* @__PURE__ */
|
|
1267
|
+
return /* @__PURE__ */ jsx4(Box4, { children: [...BRAND].map((char, i) => /* @__PURE__ */ jsx4(Text4, { color: charColor(i, tick, isActive), bold: true, children: char }, i)) });
|
|
1185
1268
|
}
|
|
1186
1269
|
|
|
1187
1270
|
// src/ui/App.tsx
|
|
1188
|
-
import { jsx as
|
|
1271
|
+
import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
1272
|
+
var MAX_VISIBLE_ITERATIONS = 8;
|
|
1189
1273
|
function App({ workflow: workflow2, events: events2, options: options2, updateCheck: updateCheck2 }) {
|
|
1190
1274
|
const { exit } = useApp();
|
|
1191
1275
|
const [state, dispatch] = useReducer(reducer, buildInitialState(workflow2));
|
|
@@ -1203,7 +1287,10 @@ function App({ workflow: workflow2, events: events2, options: options2, updateCh
|
|
|
1203
1287
|
} catch (err) {
|
|
1204
1288
|
if (!active) return;
|
|
1205
1289
|
dispatch({ type: "log", level: "error", text: getErrorMessage(err) });
|
|
1206
|
-
setTimeout(
|
|
1290
|
+
setTimeout(
|
|
1291
|
+
() => exit(err instanceof Error ? err : new Error(getErrorMessage(err))),
|
|
1292
|
+
EXIT_DELAY_MS
|
|
1293
|
+
);
|
|
1207
1294
|
}
|
|
1208
1295
|
})();
|
|
1209
1296
|
return () => {
|
|
@@ -1223,14 +1310,16 @@ function App({ workflow: workflow2, events: events2, options: options2, updateCh
|
|
|
1223
1310
|
}, [updateCheck2]);
|
|
1224
1311
|
const elapsed = formatHeaderElapsed(state.startTime, state.endTime);
|
|
1225
1312
|
const activeTask = state.tasks[state.currentIndex];
|
|
1226
|
-
const completedCount = state.tasks.filter(
|
|
1313
|
+
const completedCount = state.tasks.filter(
|
|
1314
|
+
(t) => t.status === "complete"
|
|
1315
|
+
).length;
|
|
1227
1316
|
const totalCount = state.tasks.length;
|
|
1228
1317
|
const filterInfo = options2?.stepFilter ? ` [step: ${options2.stepFilter}]` : options2?.fromStep ? ` [from step: ${options2.fromStep}]` : "";
|
|
1229
|
-
return /* @__PURE__ */
|
|
1230
|
-
/* @__PURE__ */
|
|
1231
|
-
/* @__PURE__ */
|
|
1232
|
-
/* @__PURE__ */
|
|
1233
|
-
/* @__PURE__ */
|
|
1318
|
+
return /* @__PURE__ */ jsxs4(Box5, { flexDirection: "column", padding: 1, children: [
|
|
1319
|
+
/* @__PURE__ */ jsx5(Box5, { marginBottom: 1, children: /* @__PURE__ */ jsx5(BrandMark, { tick, isActive: !state.endTime }) }),
|
|
1320
|
+
/* @__PURE__ */ jsxs4(Box5, { marginBottom: 1, children: [
|
|
1321
|
+
/* @__PURE__ */ jsx5(Text5, { bold: true, color: theme.primary, children: workflow2.goal }),
|
|
1322
|
+
/* @__PURE__ */ jsxs4(Text5, { dimColor: true, children: [
|
|
1234
1323
|
" ",
|
|
1235
1324
|
completedCount,
|
|
1236
1325
|
"/",
|
|
@@ -1240,33 +1329,48 @@ function App({ workflow: workflow2, events: events2, options: options2, updateCh
|
|
|
1240
1329
|
filterInfo
|
|
1241
1330
|
] })
|
|
1242
1331
|
] }),
|
|
1243
|
-
/* @__PURE__ */
|
|
1244
|
-
|
|
1332
|
+
/* @__PURE__ */ jsx5(Box5, { flexDirection: "column", marginBottom: 1, children: state.tasks.map((taskState, i) => /* @__PURE__ */ jsxs4(Box5, { flexDirection: "column", children: [
|
|
1333
|
+
/* @__PURE__ */ jsx5(
|
|
1334
|
+
TaskRow,
|
|
1335
|
+
{
|
|
1336
|
+
index: i,
|
|
1337
|
+
tick,
|
|
1338
|
+
taskState,
|
|
1339
|
+
isActive: i === state.currentIndex
|
|
1340
|
+
}
|
|
1341
|
+
),
|
|
1342
|
+
taskState.status === "running" && taskState.iterationHistory?.length ? /* @__PURE__ */ jsx5(
|
|
1343
|
+
IterationList,
|
|
1344
|
+
{
|
|
1345
|
+
iterationHistory: taskState.iterationHistory,
|
|
1346
|
+
tick,
|
|
1347
|
+
maxVisible: MAX_VISIBLE_ITERATIONS
|
|
1348
|
+
}
|
|
1349
|
+
) : null
|
|
1350
|
+
] }, taskState.task.name)) }),
|
|
1351
|
+
activeTask && /* @__PURE__ */ jsx5(
|
|
1352
|
+
LogPane,
|
|
1245
1353
|
{
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
activeTask && /* @__PURE__ */ jsx4(LogPane, { lines: activeTask.lines, isActive: activeTask.status === "running" }),
|
|
1254
|
-
state.endTime !== void 0 && state.writtenFiles.length > 0 && /* @__PURE__ */ jsxs3(Box4, { flexDirection: "column", marginTop: 1, children: [
|
|
1255
|
-
/* @__PURE__ */ jsx4(Text4, { dimColor: true, children: "files written:" }),
|
|
1256
|
-
state.writtenFiles.map((f) => /* @__PURE__ */ jsxs3(Text4, { color: theme.primary, children: [
|
|
1354
|
+
lines: activeTask.lines,
|
|
1355
|
+
isActive: activeTask.status === "running"
|
|
1356
|
+
}
|
|
1357
|
+
),
|
|
1358
|
+
state.endTime !== void 0 && state.writtenFiles.length > 0 && /* @__PURE__ */ jsxs4(Box5, { flexDirection: "column", marginTop: 1, children: [
|
|
1359
|
+
/* @__PURE__ */ jsx5(Text5, { dimColor: true, children: "files written:" }),
|
|
1360
|
+
state.writtenFiles.map((f) => /* @__PURE__ */ jsxs4(Text5, { color: theme.primary, children: [
|
|
1257
1361
|
" ",
|
|
1258
1362
|
f
|
|
1259
1363
|
] }, f))
|
|
1260
1364
|
] }),
|
|
1261
|
-
/* @__PURE__ */
|
|
1262
|
-
updateVersion && /* @__PURE__ */
|
|
1365
|
+
/* @__PURE__ */ jsxs4(Box5, { marginTop: 1, flexDirection: "column", children: [
|
|
1366
|
+
updateVersion && /* @__PURE__ */ jsxs4(Text5, { color: theme.warning, children: [
|
|
1263
1367
|
"v",
|
|
1264
1368
|
updateVersion,
|
|
1265
1369
|
" available \u2014 run: executant update"
|
|
1266
1370
|
] }),
|
|
1267
|
-
/* @__PURE__ */
|
|
1371
|
+
/* @__PURE__ */ jsx5(Text5, { dimColor: true, children: "press q to quit" })
|
|
1268
1372
|
] }),
|
|
1269
|
-
isRawModeSupported && /* @__PURE__ */
|
|
1373
|
+
isRawModeSupported && /* @__PURE__ */ jsx5(KeyboardHandler, { onExit: exit })
|
|
1270
1374
|
] });
|
|
1271
1375
|
}
|
|
1272
1376
|
|
|
@@ -1672,8 +1776,8 @@ ${issues}`
|
|
|
1672
1776
|
|
|
1673
1777
|
// src/ui/PlanApp.tsx
|
|
1674
1778
|
import { useEffect as useEffect3, useReducer as useReducer2, useState as useState2 } from "react";
|
|
1675
|
-
import { Box as
|
|
1676
|
-
import { jsx as
|
|
1779
|
+
import { Box as Box6, Text as Text6, useApp as useApp2, useStdin as useStdin2 } from "ink";
|
|
1780
|
+
import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
1677
1781
|
var truncate = (str, max) => str.length > max ? str.slice(0, max - 3) + "..." : str;
|
|
1678
1782
|
function buildInitial(description) {
|
|
1679
1783
|
return {
|
|
@@ -1749,7 +1853,7 @@ function StageProgress({ stage, totalStages, stageNames, tick, isActive, status
|
|
|
1749
1853
|
}
|
|
1750
1854
|
return { icon, color, name, bold, dim };
|
|
1751
1855
|
});
|
|
1752
|
-
return /* @__PURE__ */
|
|
1856
|
+
return /* @__PURE__ */ jsx6(Box6, { flexDirection: "column", marginBottom: 1, children: rows.map(({ icon, color, name, bold, dim }, i) => /* @__PURE__ */ jsx6(Box6, { children: /* @__PURE__ */ jsxs5(Text6, { color, dimColor: dim, bold, children: [
|
|
1753
1857
|
" ",
|
|
1754
1858
|
icon,
|
|
1755
1859
|
name ? ` ${name}` : ""
|
|
@@ -1782,19 +1886,19 @@ function PlanApp({ description, events: events2 }) {
|
|
|
1782
1886
|
const elapsed = formatHeaderElapsed(state.startTime);
|
|
1783
1887
|
const icon = isActive ? SPINNER[tick % SPINNER.length] : state.status === "complete" ? "\u2713" : "\u2717";
|
|
1784
1888
|
const iconColor = state.status === "complete" ? theme.success : state.status === "error" ? theme.error : theme.primary;
|
|
1785
|
-
return /* @__PURE__ */
|
|
1786
|
-
/* @__PURE__ */
|
|
1787
|
-
/* @__PURE__ */
|
|
1788
|
-
/* @__PURE__ */
|
|
1889
|
+
return /* @__PURE__ */ jsxs5(Box6, { flexDirection: "column", padding: 1, children: [
|
|
1890
|
+
/* @__PURE__ */ jsx6(Box6, { marginBottom: 1, children: /* @__PURE__ */ jsx6(BrandMark, { tick, isActive }) }),
|
|
1891
|
+
/* @__PURE__ */ jsxs5(Box6, { marginBottom: 1, children: [
|
|
1892
|
+
/* @__PURE__ */ jsxs5(Text6, { color: iconColor, children: [
|
|
1789
1893
|
icon,
|
|
1790
1894
|
" "
|
|
1791
1895
|
] }),
|
|
1792
|
-
/* @__PURE__ */
|
|
1793
|
-
/* @__PURE__ */
|
|
1896
|
+
/* @__PURE__ */ jsx6(Text6, { bold: true, color: theme.primary, children: "Generating plan" }),
|
|
1897
|
+
/* @__PURE__ */ jsxs5(Text6, { dimColor: true, children: [
|
|
1794
1898
|
" ",
|
|
1795
1899
|
elapsed
|
|
1796
1900
|
] }),
|
|
1797
|
-
state.status === "retrying" && /* @__PURE__ */
|
|
1901
|
+
state.status === "retrying" && /* @__PURE__ */ jsxs5(Text6, { color: theme.warning, children: [
|
|
1798
1902
|
" ",
|
|
1799
1903
|
"(attempt ",
|
|
1800
1904
|
state.attempt,
|
|
@@ -1803,11 +1907,11 @@ function PlanApp({ description, events: events2 }) {
|
|
|
1803
1907
|
")"
|
|
1804
1908
|
] })
|
|
1805
1909
|
] }),
|
|
1806
|
-
/* @__PURE__ */
|
|
1807
|
-
/* @__PURE__ */
|
|
1808
|
-
/* @__PURE__ */
|
|
1910
|
+
/* @__PURE__ */ jsxs5(Box6, { marginBottom: 1, children: [
|
|
1911
|
+
/* @__PURE__ */ jsx6(Text6, { dimColor: true, children: " " }),
|
|
1912
|
+
/* @__PURE__ */ jsx6(Text6, { children: truncate(state.description, 80) })
|
|
1809
1913
|
] }),
|
|
1810
|
-
/* @__PURE__ */
|
|
1914
|
+
/* @__PURE__ */ jsx6(
|
|
1811
1915
|
StageProgress,
|
|
1812
1916
|
{
|
|
1813
1917
|
stage: state.stage,
|
|
@@ -1818,23 +1922,23 @@ function PlanApp({ description, events: events2 }) {
|
|
|
1818
1922
|
status: state.status
|
|
1819
1923
|
}
|
|
1820
1924
|
),
|
|
1821
|
-
state.lines.length > 0 && /* @__PURE__ */
|
|
1822
|
-
state.status === "complete" && state.taskFile && /* @__PURE__ */
|
|
1823
|
-
/* @__PURE__ */
|
|
1925
|
+
state.lines.length > 0 && /* @__PURE__ */ jsx6(LogPane, { lines: state.lines, isActive, maxLines: 10 }),
|
|
1926
|
+
state.status === "complete" && state.taskFile && /* @__PURE__ */ jsxs5(Box6, { flexDirection: "column", marginTop: 1, children: [
|
|
1927
|
+
/* @__PURE__ */ jsxs5(Text6, { color: theme.success, children: [
|
|
1824
1928
|
"\u2705 Task plan saved: ",
|
|
1825
1929
|
state.taskFile
|
|
1826
1930
|
] }),
|
|
1827
|
-
state.preview && /* @__PURE__ */
|
|
1828
|
-
/* @__PURE__ */
|
|
1829
|
-
/* @__PURE__ */
|
|
1931
|
+
state.preview && /* @__PURE__ */ jsxs5(Box6, { flexDirection: "column", marginTop: 1, children: [
|
|
1932
|
+
/* @__PURE__ */ jsx6(Text6, { dimColor: true, children: "Preview:" }),
|
|
1933
|
+
/* @__PURE__ */ jsx6(Text6, { children: state.preview })
|
|
1830
1934
|
] })
|
|
1831
1935
|
] }),
|
|
1832
|
-
state.status === "error" && /* @__PURE__ */
|
|
1936
|
+
state.status === "error" && /* @__PURE__ */ jsx6(Box6, { marginTop: 1, children: /* @__PURE__ */ jsxs5(Text6, { color: theme.error, children: [
|
|
1833
1937
|
"Error: ",
|
|
1834
1938
|
state.errorMessage
|
|
1835
1939
|
] }) }),
|
|
1836
|
-
isActive && /* @__PURE__ */
|
|
1837
|
-
isRawModeSupported && /* @__PURE__ */
|
|
1940
|
+
isActive && /* @__PURE__ */ jsx6(Box6, { marginTop: 1, children: /* @__PURE__ */ jsx6(Text6, { dimColor: true, children: "press q to quit" }) }),
|
|
1941
|
+
isRawModeSupported && /* @__PURE__ */ jsx6(KeyboardHandler, { onExit: exit })
|
|
1838
1942
|
] });
|
|
1839
1943
|
}
|
|
1840
1944
|
|