@polterware/polter 0.1.1 → 0.2.1
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/api.js +1 -1
- package/dist/{chunk-TWWRDI3Q.js → chunk-3XNNC5AW.js} +52 -69
- package/dist/index.js +1260 -620
- package/dist/mcp.js +129 -6
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -24,14 +24,14 @@ import {
|
|
|
24
24
|
runSupabaseCommand,
|
|
25
25
|
savePipeline,
|
|
26
26
|
writeProjectConfig
|
|
27
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-3XNNC5AW.js";
|
|
28
28
|
|
|
29
29
|
// src/index.tsx
|
|
30
|
-
import
|
|
30
|
+
import React20 from "react";
|
|
31
31
|
import { render } from "ink";
|
|
32
32
|
|
|
33
33
|
// src/app.tsx
|
|
34
|
-
import { Box as
|
|
34
|
+
import { Box as Box22, Text as Text26, useApp } from "ink";
|
|
35
35
|
|
|
36
36
|
// src/hooks/useNavigation.ts
|
|
37
37
|
import { useState, useCallback } from "react";
|
|
@@ -403,7 +403,8 @@ function SelectList({
|
|
|
403
403
|
boxedSections = false,
|
|
404
404
|
width = 80,
|
|
405
405
|
isInputActive = true,
|
|
406
|
-
arrowNavigation = false
|
|
406
|
+
arrowNavigation = false,
|
|
407
|
+
panelFocused = true
|
|
407
408
|
}) {
|
|
408
409
|
const labelWidth = labelWidthProp ?? Math.max(16, Math.floor(width * 0.45));
|
|
409
410
|
const isNarrow = width < 50;
|
|
@@ -564,7 +565,7 @@ function SelectList({
|
|
|
564
565
|
{
|
|
565
566
|
flexDirection: "column",
|
|
566
567
|
borderStyle: "round",
|
|
567
|
-
borderColor: inkColors.accent,
|
|
568
|
+
borderColor: panelFocused ? inkColors.accent : panel.borderDim,
|
|
568
569
|
borderDimColor: !hasSelectedRow && !isPinnedSection,
|
|
569
570
|
paddingX: 1,
|
|
570
571
|
children: [
|
|
@@ -723,7 +724,8 @@ function buildHomeItems({
|
|
|
723
724
|
activeFeature,
|
|
724
725
|
pinnedCommands,
|
|
725
726
|
pinnedRuns,
|
|
726
|
-
showPinnedSection = true
|
|
727
|
+
showPinnedSection = true,
|
|
728
|
+
showFeatureHeader = true
|
|
727
729
|
}) {
|
|
728
730
|
const items = [];
|
|
729
731
|
if (showPinnedSection && (pinnedRuns.length > 0 || pinnedCommands.length > 0)) {
|
|
@@ -736,15 +738,17 @@ function buildHomeItems({
|
|
|
736
738
|
});
|
|
737
739
|
items.push(...buildPinnedOnlyItems(pinnedCommands, pinnedRuns));
|
|
738
740
|
}
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
741
|
+
if (showFeatureHeader) {
|
|
742
|
+
items.push({
|
|
743
|
+
id: "section-commands",
|
|
744
|
+
value: "__section_commands__",
|
|
745
|
+
label: `\u{1F4C2} ${activeFeature.label} Commands`,
|
|
746
|
+
kind: "header",
|
|
747
|
+
selectable: false
|
|
748
|
+
});
|
|
749
|
+
}
|
|
750
|
+
const toolOrder = { supabase: 0, vercel: 1, gh: 2, git: 3 };
|
|
751
|
+
const toolIcons = { supabase: "\u{1F7E2}", vercel: "\u26AA", gh: "\u{1F535}", git: "\u{1F7E0}" };
|
|
748
752
|
const grouped = /* @__PURE__ */ new Map();
|
|
749
753
|
for (const cmd of activeFeature.commands) {
|
|
750
754
|
const existing = grouped.get(cmd.tool) ?? [];
|
|
@@ -931,7 +935,7 @@ function Home({
|
|
|
931
935
|
|
|
932
936
|
// src/screens/CommandArgs.tsx
|
|
933
937
|
import { useEffect as useEffect4, useMemo as useMemo3, useState as useState6 } from "react";
|
|
934
|
-
import { Box as Box7, Text as Text8 } from "ink";
|
|
938
|
+
import { Box as Box7, Text as Text8, useInput as useInput4 } from "ink";
|
|
935
939
|
|
|
936
940
|
// src/components/TextPrompt.tsx
|
|
937
941
|
import { useState as useState5 } from "react";
|
|
@@ -943,7 +947,11 @@ function TextPrompt({
|
|
|
943
947
|
placeholder,
|
|
944
948
|
onSubmit,
|
|
945
949
|
onCancel,
|
|
946
|
-
validate
|
|
950
|
+
validate,
|
|
951
|
+
arrowNavigation = false,
|
|
952
|
+
isInputActive = true,
|
|
953
|
+
boxed = false,
|
|
954
|
+
focused = true
|
|
947
955
|
}) {
|
|
948
956
|
const [value, setValue] = useState5("");
|
|
949
957
|
const [error, setError] = useState5();
|
|
@@ -951,7 +959,10 @@ function TextPrompt({
|
|
|
951
959
|
if (key.escape && onCancel) {
|
|
952
960
|
onCancel();
|
|
953
961
|
}
|
|
954
|
-
|
|
962
|
+
if (arrowNavigation && key.leftArrow && value === "" && onCancel) {
|
|
963
|
+
onCancel();
|
|
964
|
+
}
|
|
965
|
+
}, { isActive: isInputActive });
|
|
955
966
|
const handleSubmit = (val) => {
|
|
956
967
|
if (validate) {
|
|
957
968
|
const err = validate(val);
|
|
@@ -963,7 +974,7 @@ function TextPrompt({
|
|
|
963
974
|
setError(void 0);
|
|
964
975
|
onSubmit(val);
|
|
965
976
|
};
|
|
966
|
-
|
|
977
|
+
const content = /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", children: [
|
|
967
978
|
/* @__PURE__ */ jsxs6(Box6, { gap: 1, children: [
|
|
968
979
|
/* @__PURE__ */ jsx6(Text6, { color: inkColors.accent, bold: true, children: "?" }),
|
|
969
980
|
/* @__PURE__ */ jsx6(Text6, { children: label })
|
|
@@ -988,6 +999,10 @@ function TextPrompt({
|
|
|
988
999
|
error
|
|
989
1000
|
] }) })
|
|
990
1001
|
] });
|
|
1002
|
+
if (boxed) {
|
|
1003
|
+
return /* @__PURE__ */ jsx6(Box6, { borderStyle: "round", borderColor: focused ? inkColors.accent : panel.borderDim, paddingX: 1, children: content });
|
|
1004
|
+
}
|
|
1005
|
+
return content;
|
|
991
1006
|
}
|
|
992
1007
|
|
|
993
1008
|
// src/components/ToolBadge.tsx
|
|
@@ -997,13 +1012,13 @@ var toolColors = {
|
|
|
997
1012
|
supabase: "#3ECF8E",
|
|
998
1013
|
gh: "#58A6FF",
|
|
999
1014
|
vercel: "#FFFFFF",
|
|
1000
|
-
|
|
1015
|
+
git: "#F05032"
|
|
1001
1016
|
};
|
|
1002
1017
|
var toolLabels = {
|
|
1003
1018
|
supabase: "supabase",
|
|
1004
1019
|
gh: "github",
|
|
1005
1020
|
vercel: "vercel",
|
|
1006
|
-
|
|
1021
|
+
git: "git"
|
|
1007
1022
|
};
|
|
1008
1023
|
function ToolBadge({ tool }) {
|
|
1009
1024
|
return /* @__PURE__ */ jsx7(Text7, { color: toolColors[tool], dimColor: true, children: toolLabels[tool] });
|
|
@@ -1073,11 +1088,6 @@ function buildCommandArgItems({
|
|
|
1073
1088
|
label: "Custom args...",
|
|
1074
1089
|
hint: "Type any arguments manually",
|
|
1075
1090
|
kind: "action"
|
|
1076
|
-
},
|
|
1077
|
-
{
|
|
1078
|
-
value: "__back__",
|
|
1079
|
-
label: "\u2190 Back to menu",
|
|
1080
|
-
kind: "action"
|
|
1081
1091
|
}
|
|
1082
1092
|
];
|
|
1083
1093
|
}
|
|
@@ -1120,25 +1130,20 @@ function CommandArgs({
|
|
|
1120
1130
|
tool: resolvedTool
|
|
1121
1131
|
});
|
|
1122
1132
|
};
|
|
1133
|
+
useInput4((_input, key) => {
|
|
1134
|
+
if (!command && (key.escape || key.leftArrow)) {
|
|
1135
|
+
onBack();
|
|
1136
|
+
}
|
|
1137
|
+
}, { isActive: isInputActive && !command });
|
|
1123
1138
|
if (!command) {
|
|
1124
1139
|
return /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", children: [
|
|
1125
|
-
/* @__PURE__ */ jsx8(
|
|
1126
|
-
/* @__PURE__ */ jsx8(
|
|
1127
|
-
SelectList,
|
|
1128
|
-
{
|
|
1129
|
-
items: [{ value: "__back__", label: "\u2190 Back to menu" }],
|
|
1130
|
-
onSelect: onBack,
|
|
1131
|
-
onCancel: onBack,
|
|
1132
|
-
width,
|
|
1133
|
-
isInputActive,
|
|
1134
|
-
arrowNavigation: panelMode
|
|
1135
|
-
}
|
|
1136
|
-
)
|
|
1140
|
+
/* @__PURE__ */ jsx8(Text8, { color: "red", children: "Command not provided." }),
|
|
1141
|
+
/* @__PURE__ */ jsx8(Text8, { dimColor: true, children: "Press Esc or \u2190 to go back" })
|
|
1137
1142
|
] });
|
|
1138
1143
|
}
|
|
1139
1144
|
if (phase === "custom") {
|
|
1140
1145
|
const toolLabel = resolvedTool === "supabase" ? "supabase" : resolvedTool;
|
|
1141
|
-
return /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", children: [
|
|
1146
|
+
return /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", paddingX: panelMode ? 1 : 0, children: [
|
|
1142
1147
|
/* @__PURE__ */ jsxs7(Box7, { marginBottom: 1, gap: 1, children: [
|
|
1143
1148
|
/* @__PURE__ */ jsx8(Text8, { color: inkColors.accent, bold: true, children: "Command" }),
|
|
1144
1149
|
/* @__PURE__ */ jsx8(Text8, { children: command }),
|
|
@@ -1159,7 +1164,11 @@ function CommandArgs({
|
|
|
1159
1164
|
return;
|
|
1160
1165
|
}
|
|
1161
1166
|
onBack();
|
|
1162
|
-
}
|
|
1167
|
+
},
|
|
1168
|
+
arrowNavigation: panelMode,
|
|
1169
|
+
isInputActive,
|
|
1170
|
+
boxed: panelMode,
|
|
1171
|
+
focused: isInputActive
|
|
1163
1172
|
}
|
|
1164
1173
|
),
|
|
1165
1174
|
!panelMode && /* @__PURE__ */ jsx8(StatusBar, { hint: "Type args \xB7 Enter to continue \xB7 Esc to go back", width })
|
|
@@ -1179,7 +1188,7 @@ function CommandArgs({
|
|
|
1179
1188
|
}),
|
|
1180
1189
|
[command, legacySuggestions, pinnedRuns]
|
|
1181
1190
|
);
|
|
1182
|
-
return /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", children: [
|
|
1191
|
+
return /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", paddingX: panelMode ? 1 : 0, children: [
|
|
1183
1192
|
/* @__PURE__ */ jsxs7(Box7, { marginBottom: 1, gap: 1, children: [
|
|
1184
1193
|
/* @__PURE__ */ jsx8(Text8, { color: inkColors.accent, bold: true, children: "Command" }),
|
|
1185
1194
|
/* @__PURE__ */ jsx8(Text8, { children: command }),
|
|
@@ -1238,9 +1247,10 @@ function CommandArgs({
|
|
|
1238
1247
|
},
|
|
1239
1248
|
onCancel: onBack,
|
|
1240
1249
|
boxedSections: true,
|
|
1241
|
-
width,
|
|
1250
|
+
width: panelMode ? Math.max(20, width - 4) : width,
|
|
1242
1251
|
isInputActive,
|
|
1243
|
-
arrowNavigation: panelMode
|
|
1252
|
+
arrowNavigation: panelMode,
|
|
1253
|
+
panelFocused: isInputActive
|
|
1244
1254
|
}
|
|
1245
1255
|
),
|
|
1246
1256
|
!panelMode && /* @__PURE__ */ jsx8(StatusBar, { hint: "\u2191\u2193 navigate \xB7 Enter select \xB7 p pin \xB7 Esc back", width })
|
|
@@ -1255,24 +1265,28 @@ function CustomCommand({
|
|
|
1255
1265
|
onNavigate,
|
|
1256
1266
|
onBack,
|
|
1257
1267
|
width = 80,
|
|
1268
|
+
height = 24,
|
|
1258
1269
|
panelMode = false,
|
|
1259
1270
|
isInputActive = true
|
|
1260
1271
|
}) {
|
|
1261
1272
|
const [phase, setPhase] = useState7("tool-select");
|
|
1262
1273
|
const [selectedTool, setSelectedTool] = useState7("supabase");
|
|
1263
1274
|
if (phase === "tool-select") {
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1275
|
+
const toolItems = [
|
|
1276
|
+
{ value: "__section__", label: "\u{1F6E0} Select Tool", kind: "header", selectable: false },
|
|
1277
|
+
{ value: "supabase", label: "Supabase CLI", hint: "supabase ...", kind: "action" },
|
|
1278
|
+
{ value: "gh", label: "GitHub CLI", hint: "gh ...", kind: "action" },
|
|
1279
|
+
{ value: "vercel", label: "Vercel CLI", hint: "vercel ...", kind: "action" },
|
|
1280
|
+
{ value: "git", label: "Git", hint: "git ...", kind: "action" },
|
|
1281
|
+
...!panelMode ? [{ value: "__back__", label: "\u2190 Back" }] : []
|
|
1282
|
+
];
|
|
1283
|
+
return /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", paddingX: panelMode ? 1 : 0, children: [
|
|
1284
|
+
!panelMode && /* @__PURE__ */ jsx9(Box8, { marginBottom: 1, children: /* @__PURE__ */ jsx9(Text9, { bold: true, color: inkColors.accent, children: "\u270F\uFE0F Custom Command" }) }),
|
|
1285
|
+
!panelMode && /* @__PURE__ */ jsx9(Text9, { dimColor: true, children: "Select tool:" }),
|
|
1267
1286
|
/* @__PURE__ */ jsx9(
|
|
1268
1287
|
SelectList,
|
|
1269
1288
|
{
|
|
1270
|
-
items:
|
|
1271
|
-
{ value: "supabase", label: "Supabase CLI", hint: "supabase ..." },
|
|
1272
|
-
{ value: "gh", label: "GitHub CLI", hint: "gh ..." },
|
|
1273
|
-
{ value: "vercel", label: "Vercel CLI", hint: "vercel ..." },
|
|
1274
|
-
{ value: "__back__", label: "\u2190 Back" }
|
|
1275
|
-
],
|
|
1289
|
+
items: toolItems,
|
|
1276
1290
|
onSelect: (value) => {
|
|
1277
1291
|
if (value === "__back__") {
|
|
1278
1292
|
onBack();
|
|
@@ -1282,16 +1296,19 @@ function CustomCommand({
|
|
|
1282
1296
|
setPhase("input");
|
|
1283
1297
|
},
|
|
1284
1298
|
onCancel: onBack,
|
|
1285
|
-
|
|
1299
|
+
boxedSections: panelMode,
|
|
1300
|
+
width: panelMode ? Math.max(20, width - 4) : width,
|
|
1301
|
+
maxVisible: panelMode ? Math.max(6, height - 6) : void 0,
|
|
1286
1302
|
isInputActive,
|
|
1287
|
-
arrowNavigation: panelMode
|
|
1303
|
+
arrowNavigation: panelMode,
|
|
1304
|
+
panelFocused: isInputActive
|
|
1288
1305
|
}
|
|
1289
1306
|
),
|
|
1290
1307
|
!panelMode && /* @__PURE__ */ jsx9(StatusBar, { hint: "\u2191\u2193 navigate \xB7 Enter select \xB7 Esc back", width })
|
|
1291
1308
|
] });
|
|
1292
1309
|
}
|
|
1293
|
-
return /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", children: [
|
|
1294
|
-
/* @__PURE__ */ jsxs8(Box8, { marginBottom: 1, gap: 1, children: [
|
|
1310
|
+
return /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", paddingX: panelMode ? 1 : 0, children: [
|
|
1311
|
+
!panelMode && /* @__PURE__ */ jsxs8(Box8, { marginBottom: 1, gap: 1, children: [
|
|
1295
1312
|
/* @__PURE__ */ jsx9(Text9, { bold: true, color: inkColors.accent, children: "\u270F\uFE0F Custom Command" }),
|
|
1296
1313
|
/* @__PURE__ */ jsxs8(Text9, { dimColor: true, children: [
|
|
1297
1314
|
"(",
|
|
@@ -1312,7 +1329,11 @@ function CustomCommand({
|
|
|
1312
1329
|
const args = value.split(" ").filter(Boolean);
|
|
1313
1330
|
onNavigate("flag-selection", { args, tool: selectedTool });
|
|
1314
1331
|
},
|
|
1315
|
-
onCancel: () => setPhase("tool-select")
|
|
1332
|
+
onCancel: () => setPhase("tool-select"),
|
|
1333
|
+
arrowNavigation: panelMode,
|
|
1334
|
+
isInputActive,
|
|
1335
|
+
boxed: panelMode,
|
|
1336
|
+
focused: isInputActive
|
|
1316
1337
|
}
|
|
1317
1338
|
),
|
|
1318
1339
|
!panelMode && /* @__PURE__ */ jsx9(StatusBar, { hint: "Type a command \xB7 Enter to continue \xB7 Esc to go back", width })
|
|
@@ -1320,20 +1341,22 @@ function CustomCommand({
|
|
|
1320
1341
|
}
|
|
1321
1342
|
|
|
1322
1343
|
// src/screens/FlagSelection.tsx
|
|
1323
|
-
import { Box as Box10 } from "ink";
|
|
1344
|
+
import { Box as Box10, Text as Text11 } from "ink";
|
|
1324
1345
|
|
|
1325
1346
|
// src/components/FlagToggle.tsx
|
|
1326
1347
|
import { useState as useState8 } from "react";
|
|
1327
|
-
import { Box as Box9, Text as Text10, useInput as
|
|
1348
|
+
import { Box as Box9, Text as Text10, useInput as useInput5 } from "ink";
|
|
1328
1349
|
import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
1329
1350
|
function FlagToggle({
|
|
1330
1351
|
flags,
|
|
1331
1352
|
onSubmit,
|
|
1332
|
-
onCancel
|
|
1353
|
+
onCancel,
|
|
1354
|
+
isInputActive = true,
|
|
1355
|
+
arrowNavigation = false
|
|
1333
1356
|
}) {
|
|
1334
1357
|
const [cursor, setCursor] = useState8(0);
|
|
1335
1358
|
const [selected, setSelected] = useState8(/* @__PURE__ */ new Set());
|
|
1336
|
-
|
|
1359
|
+
useInput5((input2, key) => {
|
|
1337
1360
|
if (key.upArrow || input2 === "k") {
|
|
1338
1361
|
setCursor((prev) => prev > 0 ? prev - 1 : flags.length - 1);
|
|
1339
1362
|
}
|
|
@@ -1352,17 +1375,24 @@ function FlagToggle({
|
|
|
1352
1375
|
return next;
|
|
1353
1376
|
});
|
|
1354
1377
|
}
|
|
1355
|
-
if (key.return) {
|
|
1378
|
+
if (key.return || arrowNavigation && key.rightArrow) {
|
|
1356
1379
|
onSubmit(Array.from(selected));
|
|
1357
1380
|
}
|
|
1358
1381
|
if (key.escape && onCancel) {
|
|
1359
1382
|
onCancel();
|
|
1360
1383
|
}
|
|
1361
|
-
|
|
1384
|
+
if (arrowNavigation && key.leftArrow && onCancel) {
|
|
1385
|
+
onCancel();
|
|
1386
|
+
}
|
|
1387
|
+
}, { isActive: isInputActive });
|
|
1362
1388
|
return /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", children: [
|
|
1363
1389
|
/* @__PURE__ */ jsxs9(Box9, { marginBottom: 1, children: [
|
|
1364
1390
|
/* @__PURE__ */ jsx10(Text10, { bold: true, color: inkColors.accent, children: "\u2691 Global Flags" }),
|
|
1365
|
-
/* @__PURE__ */
|
|
1391
|
+
/* @__PURE__ */ jsxs9(Text10, { dimColor: true, children: [
|
|
1392
|
+
" (Space to toggle, ",
|
|
1393
|
+
arrowNavigation ? "\u2192" : "Enter",
|
|
1394
|
+
" to confirm)"
|
|
1395
|
+
] })
|
|
1366
1396
|
] }),
|
|
1367
1397
|
flags.map((flag, i) => {
|
|
1368
1398
|
const isActive = cursor === i;
|
|
@@ -1388,7 +1418,7 @@ function FlagToggle({
|
|
|
1388
1418
|
flag.hint && /* @__PURE__ */ jsx10(Text10, { dimColor: true, children: flag.hint })
|
|
1389
1419
|
] }, flag.value);
|
|
1390
1420
|
}),
|
|
1391
|
-
/* @__PURE__ */ jsx10(Box9, { marginTop: 1, children: /* @__PURE__ */ jsx10(Text10, { dimColor: true, children: selected.size > 0 ? `${selected.size} flag${selected.size > 1 ? "s" : ""} selected` :
|
|
1421
|
+
/* @__PURE__ */ jsx10(Box9, { marginTop: 1, children: /* @__PURE__ */ jsx10(Text10, { dimColor: true, children: selected.size > 0 ? `${selected.size} flag${selected.size > 1 ? "s" : ""} selected` : `No flags selected (${arrowNavigation ? "\u2192" : "Enter"} to skip)` }) })
|
|
1392
1422
|
] });
|
|
1393
1423
|
}
|
|
1394
1424
|
|
|
@@ -1400,6 +1430,7 @@ function FlagSelection({
|
|
|
1400
1430
|
onNavigate,
|
|
1401
1431
|
onBack,
|
|
1402
1432
|
width = 80,
|
|
1433
|
+
height = 24,
|
|
1403
1434
|
panelMode = false,
|
|
1404
1435
|
isInputActive = true
|
|
1405
1436
|
}) {
|
|
@@ -1408,8 +1439,36 @@ function FlagSelection({
|
|
|
1408
1439
|
onNavigate("confirm-execute", { args, tool });
|
|
1409
1440
|
return /* @__PURE__ */ jsx11(Box10, {});
|
|
1410
1441
|
}
|
|
1411
|
-
|
|
1412
|
-
|
|
1442
|
+
const cmdDisplay = `${tool} ${args.join(" ")}`;
|
|
1443
|
+
return /* @__PURE__ */ jsxs10(Box10, { flexDirection: "column", paddingX: panelMode ? 1 : 0, children: [
|
|
1444
|
+
panelMode && /* @__PURE__ */ jsx11(Box10, { marginBottom: 1, gap: 1, children: /* @__PURE__ */ jsxs10(Text11, { color: inkColors.accent, bold: true, children: [
|
|
1445
|
+
"\u25B6",
|
|
1446
|
+
" ",
|
|
1447
|
+
cmdDisplay
|
|
1448
|
+
] }) }),
|
|
1449
|
+
panelMode ? /* @__PURE__ */ jsx11(
|
|
1450
|
+
Box10,
|
|
1451
|
+
{
|
|
1452
|
+
flexDirection: "column",
|
|
1453
|
+
borderStyle: "round",
|
|
1454
|
+
borderColor: isInputActive ? inkColors.accent : panel.borderDim,
|
|
1455
|
+
borderDimColor: true,
|
|
1456
|
+
paddingX: 1,
|
|
1457
|
+
children: /* @__PURE__ */ jsx11(
|
|
1458
|
+
FlagToggle,
|
|
1459
|
+
{
|
|
1460
|
+
flags,
|
|
1461
|
+
onSubmit: (selectedFlags) => {
|
|
1462
|
+
const finalArgs = selectedFlags.length > 0 ? [...args, ...selectedFlags] : args;
|
|
1463
|
+
onNavigate("confirm-execute", { args: finalArgs, tool });
|
|
1464
|
+
},
|
|
1465
|
+
onCancel: onBack,
|
|
1466
|
+
isInputActive,
|
|
1467
|
+
arrowNavigation: panelMode
|
|
1468
|
+
}
|
|
1469
|
+
)
|
|
1470
|
+
}
|
|
1471
|
+
) : /* @__PURE__ */ jsx11(
|
|
1413
1472
|
FlagToggle,
|
|
1414
1473
|
{
|
|
1415
1474
|
flags,
|
|
@@ -1417,7 +1476,9 @@ function FlagSelection({
|
|
|
1417
1476
|
const finalArgs = selectedFlags.length > 0 ? [...args, ...selectedFlags] : args;
|
|
1418
1477
|
onNavigate("confirm-execute", { args: finalArgs, tool });
|
|
1419
1478
|
},
|
|
1420
|
-
onCancel: onBack
|
|
1479
|
+
onCancel: onBack,
|
|
1480
|
+
isInputActive,
|
|
1481
|
+
arrowNavigation: panelMode
|
|
1421
1482
|
}
|
|
1422
1483
|
),
|
|
1423
1484
|
!panelMode && /* @__PURE__ */ jsx11(StatusBar, { hint: "Space toggle \xB7 Enter confirm \xB7 Esc back", width })
|
|
@@ -1425,33 +1486,44 @@ function FlagSelection({
|
|
|
1425
1486
|
}
|
|
1426
1487
|
|
|
1427
1488
|
// src/screens/CommandExecution.tsx
|
|
1428
|
-
import { useState as
|
|
1429
|
-
import { Box as
|
|
1489
|
+
import { useState as useState11, useEffect as useEffect5 } from "react";
|
|
1490
|
+
import { Box as Box13, Text as Text17 } from "ink";
|
|
1430
1491
|
|
|
1431
1492
|
// src/components/Spinner.tsx
|
|
1432
|
-
import { Text as
|
|
1493
|
+
import { Text as Text12 } from "ink";
|
|
1433
1494
|
import InkSpinner from "ink-spinner";
|
|
1434
1495
|
import { jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
1435
1496
|
function Spinner({
|
|
1436
1497
|
label = "Running...",
|
|
1437
1498
|
color = inkColors.accent
|
|
1438
1499
|
}) {
|
|
1439
|
-
return /* @__PURE__ */ jsxs11(
|
|
1440
|
-
/* @__PURE__ */ jsx12(
|
|
1500
|
+
return /* @__PURE__ */ jsxs11(Text12, { children: [
|
|
1501
|
+
/* @__PURE__ */ jsx12(Text12, { color, children: /* @__PURE__ */ jsx12(InkSpinner, { type: "dots" }) }),
|
|
1441
1502
|
" ",
|
|
1442
|
-
/* @__PURE__ */ jsx12(
|
|
1503
|
+
/* @__PURE__ */ jsx12(Text12, { children: label })
|
|
1443
1504
|
] });
|
|
1444
1505
|
}
|
|
1445
1506
|
|
|
1446
1507
|
// src/components/ConfirmPrompt.tsx
|
|
1447
|
-
import { Box as Box11, Text as
|
|
1508
|
+
import { Box as Box11, Text as Text13, useInput as useInput6 } from "ink";
|
|
1448
1509
|
import { jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
1449
1510
|
function ConfirmPrompt({
|
|
1450
1511
|
message,
|
|
1451
1512
|
defaultValue = true,
|
|
1452
|
-
onConfirm
|
|
1513
|
+
onConfirm,
|
|
1514
|
+
onCancel,
|
|
1515
|
+
isInputActive = true,
|
|
1516
|
+
arrowNavigation = false
|
|
1453
1517
|
}) {
|
|
1454
|
-
|
|
1518
|
+
useInput6((input2, key) => {
|
|
1519
|
+
if (key.escape && onCancel) {
|
|
1520
|
+
onCancel();
|
|
1521
|
+
return;
|
|
1522
|
+
}
|
|
1523
|
+
if (arrowNavigation && key.leftArrow && onCancel) {
|
|
1524
|
+
onCancel();
|
|
1525
|
+
return;
|
|
1526
|
+
}
|
|
1455
1527
|
if (input2 === "y" || input2 === "Y") {
|
|
1456
1528
|
onConfirm(true);
|
|
1457
1529
|
} else if (input2 === "n" || input2 === "N") {
|
|
@@ -1459,16 +1531,16 @@ function ConfirmPrompt({
|
|
|
1459
1531
|
} else if (input2 === "\r") {
|
|
1460
1532
|
onConfirm(defaultValue);
|
|
1461
1533
|
}
|
|
1462
|
-
});
|
|
1534
|
+
}, { isActive: isInputActive });
|
|
1463
1535
|
return /* @__PURE__ */ jsxs12(Box11, { gap: 1, children: [
|
|
1464
|
-
/* @__PURE__ */ jsx13(
|
|
1465
|
-
/* @__PURE__ */ jsx13(
|
|
1466
|
-
/* @__PURE__ */ jsx13(
|
|
1536
|
+
/* @__PURE__ */ jsx13(Text13, { color: inkColors.accent, bold: true, children: "?" }),
|
|
1537
|
+
/* @__PURE__ */ jsx13(Text13, { children: message }),
|
|
1538
|
+
/* @__PURE__ */ jsx13(Text13, { dimColor: true, children: defaultValue ? "(Y/n)" : "(y/N)" })
|
|
1467
1539
|
] });
|
|
1468
1540
|
}
|
|
1469
1541
|
|
|
1470
1542
|
// src/components/Divider.tsx
|
|
1471
|
-
import { Text as
|
|
1543
|
+
import { Text as Text14 } from "ink";
|
|
1472
1544
|
import { jsx as jsx14, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
1473
1545
|
function Divider({
|
|
1474
1546
|
label,
|
|
@@ -1480,7 +1552,7 @@ function Divider({
|
|
|
1480
1552
|
const sideLen = Math.max(2, Math.floor((effectiveWidth - labelLen) / 2));
|
|
1481
1553
|
const left = "\u2500".repeat(sideLen);
|
|
1482
1554
|
const right = "\u2500".repeat(sideLen);
|
|
1483
|
-
return /* @__PURE__ */ jsxs13(
|
|
1555
|
+
return /* @__PURE__ */ jsxs13(Text14, { dimColor: true, children: [
|
|
1484
1556
|
left,
|
|
1485
1557
|
" ",
|
|
1486
1558
|
label,
|
|
@@ -1488,14 +1560,82 @@ function Divider({
|
|
|
1488
1560
|
right
|
|
1489
1561
|
] });
|
|
1490
1562
|
}
|
|
1491
|
-
return /* @__PURE__ */ jsx14(
|
|
1563
|
+
return /* @__PURE__ */ jsx14(Text14, { dimColor: true, children: "\u2500".repeat(effectiveWidth) });
|
|
1564
|
+
}
|
|
1565
|
+
|
|
1566
|
+
// src/components/CommandOutput.tsx
|
|
1567
|
+
import { Text as Text16 } from "ink";
|
|
1568
|
+
|
|
1569
|
+
// src/components/ScrollableBox.tsx
|
|
1570
|
+
import { useState as useState9 } from "react";
|
|
1571
|
+
import { Box as Box12, Text as Text15, useInput as useInput7 } from "ink";
|
|
1572
|
+
import { jsx as jsx15, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
1573
|
+
function ScrollableBox({
|
|
1574
|
+
height,
|
|
1575
|
+
isActive = true,
|
|
1576
|
+
children
|
|
1577
|
+
}) {
|
|
1578
|
+
const totalItems = children.length;
|
|
1579
|
+
const [scrollOffset, setScrollOffset] = useState9(0);
|
|
1580
|
+
const visibleCount = Math.max(1, height - 2);
|
|
1581
|
+
useInput7(
|
|
1582
|
+
(input2, key) => {
|
|
1583
|
+
if (key.upArrow || input2 === "k") {
|
|
1584
|
+
setScrollOffset((prev) => Math.max(0, prev - 1));
|
|
1585
|
+
}
|
|
1586
|
+
if (key.downArrow || input2 === "j") {
|
|
1587
|
+
setScrollOffset((prev) => Math.min(Math.max(0, totalItems - visibleCount), prev + 1));
|
|
1588
|
+
}
|
|
1589
|
+
},
|
|
1590
|
+
{ isActive }
|
|
1591
|
+
);
|
|
1592
|
+
const showScrollUp = scrollOffset > 0;
|
|
1593
|
+
const showScrollDown = scrollOffset + visibleCount < totalItems;
|
|
1594
|
+
const visible = children.slice(scrollOffset, scrollOffset + visibleCount);
|
|
1595
|
+
return /* @__PURE__ */ jsxs14(Box12, { flexDirection: "column", height, children: [
|
|
1596
|
+
showScrollUp && /* @__PURE__ */ jsx15(Text15, { dimColor: true, children: " \u2191 more" }),
|
|
1597
|
+
visible,
|
|
1598
|
+
showScrollDown && /* @__PURE__ */ jsx15(Text15, { dimColor: true, children: " \u2193 more" })
|
|
1599
|
+
] });
|
|
1600
|
+
}
|
|
1601
|
+
|
|
1602
|
+
// src/lib/ansi.ts
|
|
1603
|
+
var ANSI_RE = (
|
|
1604
|
+
// biome-ignore lint/suspicious/noControlCharactersInRegex: intentional ANSI stripping
|
|
1605
|
+
/[\u001B\u009B][[\]()#;?]*(?:(?:(?:[a-zA-Z\d]*(?:;[-a-zA-Z\d/#&.:=?%@~_]*)*)?\u0007)|(?:(?:\d{1,4}(?:;\d{0,4})*)?[\dA-PR-TZcf-nq-uy=><~]))/g
|
|
1606
|
+
);
|
|
1607
|
+
function stripAnsi(text) {
|
|
1608
|
+
return text.replace(ANSI_RE, "");
|
|
1609
|
+
}
|
|
1610
|
+
|
|
1611
|
+
// src/components/CommandOutput.tsx
|
|
1612
|
+
import { jsx as jsx16 } from "react/jsx-runtime";
|
|
1613
|
+
function cleanLines(raw) {
|
|
1614
|
+
const stripped = stripAnsi(raw);
|
|
1615
|
+
return stripped.replace(/\r/g, "").split("\n").filter((line) => line.length > 0);
|
|
1616
|
+
}
|
|
1617
|
+
function CommandOutput({
|
|
1618
|
+
stdout,
|
|
1619
|
+
stderr,
|
|
1620
|
+
height,
|
|
1621
|
+
isActive = false
|
|
1622
|
+
}) {
|
|
1623
|
+
const outLines = stdout ? cleanLines(stdout) : [];
|
|
1624
|
+
const errLines = stderr ? cleanLines(stderr) : [];
|
|
1625
|
+
if (outLines.length === 0 && errLines.length === 0) {
|
|
1626
|
+
return null;
|
|
1627
|
+
}
|
|
1628
|
+
return /* @__PURE__ */ jsx16(ScrollableBox, { height: Math.max(3, height), isActive, children: [
|
|
1629
|
+
...outLines.map((line, i) => /* @__PURE__ */ jsx16(Text16, { children: line }, `o-${i}`)),
|
|
1630
|
+
...errLines.map((line, i) => /* @__PURE__ */ jsx16(Text16, { color: "red", children: line }, `e-${i}`))
|
|
1631
|
+
] });
|
|
1492
1632
|
}
|
|
1493
1633
|
|
|
1494
1634
|
// src/hooks/useCommand.ts
|
|
1495
|
-
import { useState as
|
|
1496
|
-
function useCommand(execution = "supabase", cwd = process.cwd()) {
|
|
1497
|
-
const [status, setStatus] =
|
|
1498
|
-
const [result, setResult] =
|
|
1635
|
+
import { useState as useState10, useCallback as useCallback2 } from "react";
|
|
1636
|
+
function useCommand(execution = "supabase", cwd = process.cwd(), options) {
|
|
1637
|
+
const [status, setStatus] = useState10("idle");
|
|
1638
|
+
const [result, setResult] = useState10(null);
|
|
1499
1639
|
const run = useCallback2(async (args) => {
|
|
1500
1640
|
setStatus("running");
|
|
1501
1641
|
setResult(null);
|
|
@@ -1511,7 +1651,8 @@ function useCommand(execution = "supabase", cwd = process.cwd()) {
|
|
|
1511
1651
|
} else {
|
|
1512
1652
|
resolvedExecution = execution;
|
|
1513
1653
|
}
|
|
1514
|
-
const
|
|
1654
|
+
const runOpts = options?.quiet ? { quiet: true } : void 0;
|
|
1655
|
+
const res = await runCommand(resolvedExecution, args, cwd, runOpts);
|
|
1515
1656
|
setResult(res);
|
|
1516
1657
|
if (res.spawnError || res.exitCode !== null && res.exitCode !== 0) {
|
|
1517
1658
|
setStatus("error");
|
|
@@ -1519,7 +1660,7 @@ function useCommand(execution = "supabase", cwd = process.cwd()) {
|
|
|
1519
1660
|
setStatus("success");
|
|
1520
1661
|
}
|
|
1521
1662
|
return res;
|
|
1522
|
-
}, [cwd, execution]);
|
|
1663
|
+
}, [cwd, execution, options?.quiet]);
|
|
1523
1664
|
const reset = useCallback2(() => {
|
|
1524
1665
|
setStatus("idle");
|
|
1525
1666
|
setResult(null);
|
|
@@ -1540,21 +1681,71 @@ async function copyToClipboard(text) {
|
|
|
1540
1681
|
});
|
|
1541
1682
|
}
|
|
1542
1683
|
|
|
1684
|
+
// src/lib/errorSuggestions.ts
|
|
1685
|
+
var KNOWN_TOOLS = ["supabase", "gh", "vercel", "git"];
|
|
1686
|
+
var BACKTICK_CMD = /(?:try\s+)?(?:run(?:ning)?|use|execute)\s+`([^`]+)`/gi;
|
|
1687
|
+
var HAVE_YOU_RUN = /have you (?:run|tried|used)\s+((?:supabase|gh|vercel|git)\s+[\w][\w -]*\w)\??/gi;
|
|
1688
|
+
var DID_YOU_MEAN = /did you mean[:\s]+[`']?([a-z][\w -]*\w)[`']?\??/gi;
|
|
1689
|
+
var INDENTED_TOOL_CMD = /^\s{2,}((?:supabase|gh|vercel|git)\s+[\w][\w -]*\w)$/gm;
|
|
1690
|
+
var ARROW_BULLET = /[→•\-*]\s*(?:run:?\s*)?((?:supabase|gh|vercel|git)\s+[\w][\w -]*\w)/gim;
|
|
1691
|
+
var MAX_SUGGESTIONS = 3;
|
|
1692
|
+
function detectTool(rawCommand, fallback) {
|
|
1693
|
+
const first = rawCommand.trim().split(/\s+/)[0]?.toLowerCase();
|
|
1694
|
+
const match = KNOWN_TOOLS.find((t) => t === first);
|
|
1695
|
+
return match ?? fallback;
|
|
1696
|
+
}
|
|
1697
|
+
function parseRawCommand(raw, currentTool) {
|
|
1698
|
+
const trimmed = raw.trim();
|
|
1699
|
+
const tool = detectTool(trimmed, currentTool);
|
|
1700
|
+
const parts = trimmed.split(/\s+/);
|
|
1701
|
+
const args = parts[0]?.toLowerCase() === tool ? parts.slice(1) : parts;
|
|
1702
|
+
const display = `${tool} ${args.join(" ")}`;
|
|
1703
|
+
return { tool, args, display };
|
|
1704
|
+
}
|
|
1705
|
+
function parseErrorSuggestions(stdout, stderr, currentTool) {
|
|
1706
|
+
const combined = stripAnsi(`${stdout}
|
|
1707
|
+
${stderr}`);
|
|
1708
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1709
|
+
const suggestions = [];
|
|
1710
|
+
const patterns = [BACKTICK_CMD, HAVE_YOU_RUN, DID_YOU_MEAN, INDENTED_TOOL_CMD, ARROW_BULLET];
|
|
1711
|
+
for (const pattern of patterns) {
|
|
1712
|
+
pattern.lastIndex = 0;
|
|
1713
|
+
let match;
|
|
1714
|
+
while ((match = pattern.exec(combined)) !== null) {
|
|
1715
|
+
const raw = match[1];
|
|
1716
|
+
const suggestion = parseRawCommand(raw, currentTool);
|
|
1717
|
+
const key = suggestion.display;
|
|
1718
|
+
if (!seen.has(key)) {
|
|
1719
|
+
seen.add(key);
|
|
1720
|
+
suggestions.push(suggestion);
|
|
1721
|
+
}
|
|
1722
|
+
if (suggestions.length >= MAX_SUGGESTIONS) break;
|
|
1723
|
+
}
|
|
1724
|
+
if (suggestions.length >= MAX_SUGGESTIONS) break;
|
|
1725
|
+
}
|
|
1726
|
+
return suggestions;
|
|
1727
|
+
}
|
|
1728
|
+
|
|
1543
1729
|
// src/screens/CommandExecution.tsx
|
|
1544
|
-
import { jsx as
|
|
1730
|
+
import { jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
1545
1731
|
function CommandExecution({
|
|
1546
1732
|
args: initialArgs,
|
|
1547
1733
|
tool = "supabase",
|
|
1548
1734
|
onBack,
|
|
1735
|
+
onHome,
|
|
1549
1736
|
onExit,
|
|
1737
|
+
onRunSuggestion,
|
|
1550
1738
|
width = 80,
|
|
1739
|
+
height = 24,
|
|
1551
1740
|
panelMode = false,
|
|
1552
1741
|
isInputActive = true
|
|
1553
1742
|
}) {
|
|
1554
|
-
const [phase, setPhase] =
|
|
1555
|
-
const [currentArgs, setCurrentArgs] =
|
|
1556
|
-
const [pinMessage, setPinMessage] =
|
|
1557
|
-
const { status, result, run, reset } = useCommand(tool)
|
|
1743
|
+
const [phase, setPhase] = useState11("confirm");
|
|
1744
|
+
const [currentArgs, setCurrentArgs] = useState11(initialArgs);
|
|
1745
|
+
const [pinMessage, setPinMessage] = useState11();
|
|
1746
|
+
const { status, result, run, reset } = useCommand(tool, process.cwd(), {
|
|
1747
|
+
quiet: panelMode
|
|
1748
|
+
});
|
|
1558
1749
|
const cmdDisplay = `${tool} ${currentArgs.join(" ")}`;
|
|
1559
1750
|
const runCommand2 = currentArgs.join(" ");
|
|
1560
1751
|
useEffect5(() => {
|
|
@@ -1575,42 +1766,67 @@ function CommandExecution({
|
|
|
1575
1766
|
}
|
|
1576
1767
|
}, [phase, runCommand2, status]);
|
|
1577
1768
|
if (phase === "confirm") {
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1769
|
+
const confirmContent = /* @__PURE__ */ jsxs15(Box13, { flexDirection: "column", children: [
|
|
1770
|
+
/* @__PURE__ */ jsxs15(Box13, { marginBottom: 1, gap: 1, children: [
|
|
1771
|
+
/* @__PURE__ */ jsxs15(Text17, { color: inkColors.accent, bold: true, children: [
|
|
1772
|
+
"\u25B6",
|
|
1773
|
+
" ",
|
|
1774
|
+
cmdDisplay
|
|
1775
|
+
] }),
|
|
1776
|
+
/* @__PURE__ */ jsx17(ToolBadge, { tool })
|
|
1777
|
+
] }),
|
|
1778
|
+
/* @__PURE__ */ jsx17(
|
|
1779
|
+
ConfirmPrompt,
|
|
1780
|
+
{
|
|
1781
|
+
message: `Execute ${cmdDisplay}?`,
|
|
1782
|
+
defaultValue: true,
|
|
1783
|
+
onConfirm: (confirmed) => {
|
|
1784
|
+
if (confirmed) {
|
|
1785
|
+
setPhase("running");
|
|
1786
|
+
} else {
|
|
1787
|
+
onBack();
|
|
1788
|
+
}
|
|
1789
|
+
},
|
|
1790
|
+
onCancel: onBack,
|
|
1791
|
+
isInputActive,
|
|
1792
|
+
arrowNavigation: panelMode
|
|
1589
1793
|
}
|
|
1794
|
+
),
|
|
1795
|
+
/* @__PURE__ */ jsx17(Box13, { marginTop: 1, children: /* @__PURE__ */ jsx17(Text17, { dimColor: true, children: "Enter to execute \xB7 n to cancel" }) })
|
|
1796
|
+
] });
|
|
1797
|
+
return /* @__PURE__ */ jsx17(Box13, { flexDirection: "column", paddingX: panelMode ? 1 : 0, children: panelMode ? /* @__PURE__ */ jsx17(
|
|
1798
|
+
Box13,
|
|
1799
|
+
{
|
|
1800
|
+
flexDirection: "column",
|
|
1801
|
+
borderStyle: "round",
|
|
1802
|
+
borderColor: isInputActive ? inkColors.accent : panel.borderDim,
|
|
1803
|
+
borderDimColor: true,
|
|
1804
|
+
paddingX: 1,
|
|
1805
|
+
children: confirmContent
|
|
1590
1806
|
}
|
|
1591
|
-
) });
|
|
1807
|
+
) : confirmContent });
|
|
1592
1808
|
}
|
|
1593
1809
|
if (phase === "running") {
|
|
1594
|
-
return /* @__PURE__ */
|
|
1595
|
-
/* @__PURE__ */
|
|
1596
|
-
/* @__PURE__ */
|
|
1597
|
-
/* @__PURE__ */
|
|
1598
|
-
/* @__PURE__ */
|
|
1599
|
-
/* @__PURE__ */
|
|
1600
|
-
/* @__PURE__ */
|
|
1810
|
+
return /* @__PURE__ */ jsxs15(Box13, { flexDirection: "column", paddingX: panelMode ? 1 : 0, children: [
|
|
1811
|
+
/* @__PURE__ */ jsx17(Divider, { width: panelMode ? width - 4 : width }),
|
|
1812
|
+
/* @__PURE__ */ jsxs15(Box13, { marginY: 1, gap: 1, children: [
|
|
1813
|
+
/* @__PURE__ */ jsx17(Text17, { color: inkColors.accent, bold: true, children: "\u25B6" }),
|
|
1814
|
+
/* @__PURE__ */ jsx17(Text17, { dimColor: true, children: "Running:" }),
|
|
1815
|
+
/* @__PURE__ */ jsx17(Text17, { children: cmdDisplay }),
|
|
1816
|
+
/* @__PURE__ */ jsx17(ToolBadge, { tool })
|
|
1601
1817
|
] }),
|
|
1602
|
-
/* @__PURE__ */
|
|
1603
|
-
/* @__PURE__ */
|
|
1818
|
+
/* @__PURE__ */ jsx17(Divider, { width: panelMode ? width - 4 : width }),
|
|
1819
|
+
/* @__PURE__ */ jsx17(Box13, { marginTop: 1, children: /* @__PURE__ */ jsx17(Spinner, { label: `Executing ${cmdDisplay}...` }) })
|
|
1604
1820
|
] });
|
|
1605
1821
|
}
|
|
1606
1822
|
if (phase === "success-pin-offer") {
|
|
1607
|
-
return /* @__PURE__ */
|
|
1608
|
-
/* @__PURE__ */
|
|
1609
|
-
/* @__PURE__ */
|
|
1610
|
-
/* @__PURE__ */
|
|
1611
|
-
/* @__PURE__ */
|
|
1823
|
+
return /* @__PURE__ */ jsxs15(Box13, { flexDirection: "column", paddingX: panelMode ? 1 : 0, children: [
|
|
1824
|
+
/* @__PURE__ */ jsx17(Divider, { width: panelMode ? width - 4 : width }),
|
|
1825
|
+
/* @__PURE__ */ jsxs15(Box13, { marginY: 1, gap: 1, children: [
|
|
1826
|
+
/* @__PURE__ */ jsx17(Text17, { color: inkColors.accent, bold: true, children: "\u2713" }),
|
|
1827
|
+
/* @__PURE__ */ jsx17(Text17, { color: inkColors.accent, bold: true, children: "Command completed successfully!" })
|
|
1612
1828
|
] }),
|
|
1613
|
-
/* @__PURE__ */
|
|
1829
|
+
/* @__PURE__ */ jsx17(
|
|
1614
1830
|
ConfirmPrompt,
|
|
1615
1831
|
{
|
|
1616
1832
|
message: "Pin this exact command?",
|
|
@@ -1621,34 +1837,75 @@ function CommandExecution({
|
|
|
1621
1837
|
setPinMessage("Exact command pinned to Pinned Runs.");
|
|
1622
1838
|
}
|
|
1623
1839
|
setPhase("success");
|
|
1624
|
-
}
|
|
1840
|
+
},
|
|
1841
|
+
onCancel: () => setPhase("success"),
|
|
1842
|
+
isInputActive,
|
|
1843
|
+
arrowNavigation: panelMode
|
|
1625
1844
|
}
|
|
1626
1845
|
)
|
|
1627
1846
|
] });
|
|
1628
1847
|
}
|
|
1629
1848
|
if (phase === "success") {
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1849
|
+
const successItems = [
|
|
1850
|
+
{ value: "__back__", label: "\u2190 Back to menu" }
|
|
1851
|
+
];
|
|
1852
|
+
const outputHeight = Math.max(3, height - 12);
|
|
1853
|
+
return /* @__PURE__ */ jsxs15(Box13, { flexDirection: "column", paddingX: panelMode ? 1 : 0, children: [
|
|
1854
|
+
/* @__PURE__ */ jsx17(Divider, { width: panelMode ? width - 4 : width }),
|
|
1855
|
+
/* @__PURE__ */ jsxs15(Box13, { marginY: 1, gap: 1, children: [
|
|
1856
|
+
/* @__PURE__ */ jsx17(Text17, { color: inkColors.accent, bold: true, children: "\u2713" }),
|
|
1857
|
+
/* @__PURE__ */ jsx17(Text17, { color: inkColors.accent, bold: true, children: "Command completed successfully!" })
|
|
1635
1858
|
] }),
|
|
1636
|
-
pinMessage && /* @__PURE__ */
|
|
1637
|
-
/* @__PURE__ */
|
|
1859
|
+
pinMessage && /* @__PURE__ */ jsx17(Box13, { marginBottom: 1, children: /* @__PURE__ */ jsx17(Text17, { color: inkColors.accent, children: pinMessage }) }),
|
|
1860
|
+
/* @__PURE__ */ jsx17(
|
|
1861
|
+
CommandOutput,
|
|
1862
|
+
{
|
|
1863
|
+
stdout: result?.stdout,
|
|
1864
|
+
stderr: result?.stderr,
|
|
1865
|
+
height: outputHeight,
|
|
1866
|
+
isActive: isInputActive
|
|
1867
|
+
}
|
|
1868
|
+
),
|
|
1869
|
+
/* @__PURE__ */ jsx17(
|
|
1638
1870
|
SelectList,
|
|
1639
1871
|
{
|
|
1640
|
-
items:
|
|
1641
|
-
onSelect: onBack,
|
|
1642
|
-
onCancel: onBack,
|
|
1643
|
-
width,
|
|
1872
|
+
items: successItems,
|
|
1873
|
+
onSelect: onHome ?? onBack,
|
|
1874
|
+
onCancel: onHome ?? onBack,
|
|
1875
|
+
width: panelMode ? Math.max(20, width - 4) : width,
|
|
1876
|
+
maxVisible: panelMode ? Math.max(6, height - 6) : void 0,
|
|
1644
1877
|
isInputActive,
|
|
1645
|
-
arrowNavigation: panelMode
|
|
1878
|
+
arrowNavigation: panelMode,
|
|
1879
|
+
boxedSections: panelMode,
|
|
1880
|
+
panelFocused: isInputActive
|
|
1646
1881
|
}
|
|
1647
1882
|
)
|
|
1648
1883
|
] });
|
|
1649
1884
|
}
|
|
1650
1885
|
const hasDebug = currentArgs.includes("--debug");
|
|
1886
|
+
const suggestions = result ? parseErrorSuggestions(result.stdout, result.stderr, tool) : [];
|
|
1651
1887
|
const errorItems = [];
|
|
1888
|
+
if (suggestions.length > 0) {
|
|
1889
|
+
errorItems.push({
|
|
1890
|
+
value: "__suggestions_header__",
|
|
1891
|
+
label: "\u{1F4A1} Suggested fixes",
|
|
1892
|
+
kind: "header"
|
|
1893
|
+
});
|
|
1894
|
+
for (const s of suggestions) {
|
|
1895
|
+
errorItems.push({
|
|
1896
|
+
value: `suggest:${s.display}`,
|
|
1897
|
+
label: s.display,
|
|
1898
|
+
hint: "from error output"
|
|
1899
|
+
});
|
|
1900
|
+
}
|
|
1901
|
+
}
|
|
1902
|
+
if (suggestions.length > 0) {
|
|
1903
|
+
errorItems.push({
|
|
1904
|
+
value: "__actions_header__",
|
|
1905
|
+
label: "",
|
|
1906
|
+
kind: "header"
|
|
1907
|
+
});
|
|
1908
|
+
}
|
|
1652
1909
|
if (!result?.spawnError) {
|
|
1653
1910
|
errorItems.push({ value: "retry", label: "\u{1F504} Retry the same command" });
|
|
1654
1911
|
if (!hasDebug) {
|
|
@@ -1659,54 +1916,82 @@ function CommandExecution({
|
|
|
1659
1916
|
});
|
|
1660
1917
|
}
|
|
1661
1918
|
}
|
|
1662
|
-
errorItems.push(
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
);
|
|
1670
|
-
return /* @__PURE__ */
|
|
1671
|
-
/* @__PURE__ */
|
|
1672
|
-
result?.spawnError ? /* @__PURE__ */
|
|
1673
|
-
/* @__PURE__ */
|
|
1674
|
-
/* @__PURE__ */
|
|
1675
|
-
/* @__PURE__ */
|
|
1919
|
+
errorItems.push({
|
|
1920
|
+
value: "copy",
|
|
1921
|
+
label: "\u{1F4CB} Copy command to clipboard"
|
|
1922
|
+
});
|
|
1923
|
+
errorItems.push({
|
|
1924
|
+
value: "menu",
|
|
1925
|
+
label: "\u2190 Back to menu"
|
|
1926
|
+
});
|
|
1927
|
+
return /* @__PURE__ */ jsxs15(Box13, { flexDirection: "column", paddingX: panelMode ? 1 : 0, children: [
|
|
1928
|
+
/* @__PURE__ */ jsx17(Divider, { width: panelMode ? width - 4 : width }),
|
|
1929
|
+
result?.spawnError ? /* @__PURE__ */ jsxs15(Box13, { flexDirection: "column", marginY: 1, children: [
|
|
1930
|
+
/* @__PURE__ */ jsxs15(Box13, { gap: 1, children: [
|
|
1931
|
+
/* @__PURE__ */ jsx17(Text17, { color: "red", bold: true, children: "\u2717" }),
|
|
1932
|
+
/* @__PURE__ */ jsx17(Text17, { color: "red", bold: true, children: "Failed to start command" })
|
|
1676
1933
|
] }),
|
|
1677
|
-
/* @__PURE__ */
|
|
1678
|
-
/* @__PURE__ */
|
|
1679
|
-
/* @__PURE__ */
|
|
1934
|
+
/* @__PURE__ */ jsxs15(Box13, { marginLeft: 2, marginTop: 1, children: [
|
|
1935
|
+
/* @__PURE__ */ jsx17(Text17, { dimColor: true, children: "Error: " }),
|
|
1936
|
+
/* @__PURE__ */ jsx17(Text17, { color: "red", children: result.spawnError })
|
|
1680
1937
|
] }),
|
|
1681
|
-
(result.spawnError.includes("ENOENT") || result.spawnError.includes("not found")) && /* @__PURE__ */
|
|
1682
|
-
"\u{1F4A1}
|
|
1938
|
+
(result.spawnError.includes("ENOENT") || result.spawnError.includes("not found")) && /* @__PURE__ */ jsx17(Box13, { flexDirection: "column", marginLeft: 2, marginTop: 1, children: /* @__PURE__ */ jsxs15(Text17, { color: inkColors.accent, bold: true, children: [
|
|
1939
|
+
"\u{1F4A1}",
|
|
1940
|
+
" ",
|
|
1683
1941
|
tool,
|
|
1684
1942
|
" CLI not found in this repository or PATH"
|
|
1685
1943
|
] }) })
|
|
1686
|
-
] }) : /* @__PURE__ */
|
|
1687
|
-
/* @__PURE__ */
|
|
1688
|
-
/* @__PURE__ */
|
|
1689
|
-
/* @__PURE__ */
|
|
1690
|
-
/* @__PURE__ */
|
|
1691
|
-
/* @__PURE__ */
|
|
1692
|
-
/* @__PURE__ */
|
|
1944
|
+
] }) : /* @__PURE__ */ jsxs15(Box13, { flexDirection: "column", marginY: 1, children: [
|
|
1945
|
+
/* @__PURE__ */ jsxs15(Box13, { gap: 1, children: [
|
|
1946
|
+
/* @__PURE__ */ jsx17(Text17, { color: "red", bold: true, children: "\u2717" }),
|
|
1947
|
+
/* @__PURE__ */ jsx17(Text17, { color: "red", children: "Command failed " }),
|
|
1948
|
+
/* @__PURE__ */ jsx17(Text17, { dimColor: true, children: "(exit code " }),
|
|
1949
|
+
/* @__PURE__ */ jsx17(Text17, { color: "red", bold: true, children: String(result?.exitCode) }),
|
|
1950
|
+
/* @__PURE__ */ jsx17(Text17, { dimColor: true, children: ")" })
|
|
1693
1951
|
] }),
|
|
1694
|
-
/* @__PURE__ */
|
|
1695
|
-
/* @__PURE__ */
|
|
1696
|
-
/* @__PURE__ */
|
|
1952
|
+
/* @__PURE__ */ jsxs15(Box13, { marginLeft: 2, marginTop: 1, children: [
|
|
1953
|
+
/* @__PURE__ */ jsx17(Text17, { dimColor: true, children: "Command: " }),
|
|
1954
|
+
/* @__PURE__ */ jsx17(Text17, { children: cmdDisplay })
|
|
1697
1955
|
] }),
|
|
1698
|
-
!hasDebug && /* @__PURE__ */
|
|
1699
|
-
/* @__PURE__ */
|
|
1700
|
-
|
|
1701
|
-
|
|
1956
|
+
!hasDebug && /* @__PURE__ */ jsxs15(Box13, { marginLeft: 2, marginTop: 1, gap: 1, children: [
|
|
1957
|
+
/* @__PURE__ */ jsxs15(Text17, { dimColor: true, children: [
|
|
1958
|
+
"\u{1F4A1}",
|
|
1959
|
+
" Tip: retry with"
|
|
1960
|
+
] }),
|
|
1961
|
+
/* @__PURE__ */ jsx17(Text17, { color: inkColors.accent, children: "--debug" }),
|
|
1962
|
+
/* @__PURE__ */ jsx17(Text17, { dimColor: true, children: "to see detailed logs" })
|
|
1702
1963
|
] })
|
|
1703
1964
|
] }),
|
|
1704
|
-
/* @__PURE__ */
|
|
1705
|
-
|
|
1965
|
+
/* @__PURE__ */ jsx17(
|
|
1966
|
+
CommandOutput,
|
|
1967
|
+
{
|
|
1968
|
+
stdout: result?.stdout,
|
|
1969
|
+
stderr: result?.stderr,
|
|
1970
|
+
height: Math.max(3, height - 16 - (suggestions.length > 0 ? suggestions.length + 4 : 0)),
|
|
1971
|
+
isActive: false
|
|
1972
|
+
}
|
|
1973
|
+
),
|
|
1974
|
+
/* @__PURE__ */ jsx17(Box13, { marginTop: 1, marginBottom: 1, children: /* @__PURE__ */ jsx17(Text17, { bold: true, children: "What would you like to do?" }) }),
|
|
1975
|
+
/* @__PURE__ */ jsx17(
|
|
1706
1976
|
SelectList,
|
|
1707
1977
|
{
|
|
1708
1978
|
items: errorItems,
|
|
1709
1979
|
onSelect: async (action) => {
|
|
1980
|
+
if (action.startsWith("suggest:")) {
|
|
1981
|
+
const rawCmd = action.slice("suggest:".length);
|
|
1982
|
+
const parts = rawCmd.split(/\s+/);
|
|
1983
|
+
const sugTool = parts[0];
|
|
1984
|
+
const sugArgs = parts.slice(1);
|
|
1985
|
+
if (onRunSuggestion) {
|
|
1986
|
+
onRunSuggestion(sugTool, sugArgs);
|
|
1987
|
+
} else {
|
|
1988
|
+
setCurrentArgs(sugArgs);
|
|
1989
|
+
setPinMessage(void 0);
|
|
1990
|
+
reset();
|
|
1991
|
+
setPhase("confirm");
|
|
1992
|
+
}
|
|
1993
|
+
return;
|
|
1994
|
+
}
|
|
1710
1995
|
switch (action) {
|
|
1711
1996
|
case "retry":
|
|
1712
1997
|
setPinMessage(void 0);
|
|
@@ -1725,7 +2010,7 @@ function CommandExecution({
|
|
|
1725
2010
|
await copyToClipboard(cmdDisplay);
|
|
1726
2011
|
break;
|
|
1727
2012
|
case "menu":
|
|
1728
|
-
onBack();
|
|
2013
|
+
(onHome ?? onBack)();
|
|
1729
2014
|
break;
|
|
1730
2015
|
case "exit":
|
|
1731
2016
|
onExit();
|
|
@@ -1733,19 +2018,22 @@ function CommandExecution({
|
|
|
1733
2018
|
}
|
|
1734
2019
|
},
|
|
1735
2020
|
onCancel: onBack,
|
|
1736
|
-
|
|
2021
|
+
boxedSections: panelMode,
|
|
2022
|
+
width: panelMode ? Math.max(20, width - 4) : width,
|
|
2023
|
+
maxVisible: panelMode ? Math.max(errorItems.length + (suggestions.length > 0 ? 4 : 0), height - 6) : void 0,
|
|
1737
2024
|
isInputActive,
|
|
1738
|
-
arrowNavigation: panelMode
|
|
2025
|
+
arrowNavigation: panelMode,
|
|
2026
|
+
panelFocused: isInputActive
|
|
1739
2027
|
}
|
|
1740
2028
|
),
|
|
1741
|
-
!panelMode && /* @__PURE__ */
|
|
2029
|
+
!panelMode && /* @__PURE__ */ jsx17(StatusBar, { width })
|
|
1742
2030
|
] });
|
|
1743
2031
|
}
|
|
1744
2032
|
|
|
1745
2033
|
// src/screens/SelfUpdate.tsx
|
|
1746
|
-
import { useEffect as useEffect6, useState as
|
|
1747
|
-
import { Box as
|
|
1748
|
-
import { jsx as
|
|
2034
|
+
import { useEffect as useEffect6, useState as useState12 } from "react";
|
|
2035
|
+
import { Box as Box14, Text as Text18 } from "ink";
|
|
2036
|
+
import { jsx as jsx18, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
1749
2037
|
var packageName = "@polterware/polter";
|
|
1750
2038
|
var globalUpdateArgs = ["install", "-g", `${packageName}@latest`];
|
|
1751
2039
|
var repositoryUpdateArgs = ["install", "-D", `${packageName}@latest`];
|
|
@@ -1756,20 +2044,23 @@ function SelfUpdate({
|
|
|
1756
2044
|
onBack,
|
|
1757
2045
|
onExit,
|
|
1758
2046
|
width = 80,
|
|
2047
|
+
height = 24,
|
|
1759
2048
|
panelMode = false,
|
|
1760
2049
|
isInputActive = true
|
|
1761
2050
|
}) {
|
|
1762
2051
|
const repositoryRoot = findNearestPackageRoot();
|
|
1763
|
-
const [target, setTarget] =
|
|
2052
|
+
const [target, setTarget] = useState12(
|
|
1764
2053
|
repositoryRoot ? "repository" : "global"
|
|
1765
2054
|
);
|
|
1766
|
-
const [phase, setPhase] =
|
|
2055
|
+
const [phase, setPhase] = useState12(
|
|
1767
2056
|
repositoryRoot ? "target" : "confirm"
|
|
1768
2057
|
);
|
|
1769
2058
|
const updateArgs = getUpdateArgs(target);
|
|
1770
2059
|
const updateDisplay = `npm ${updateArgs.join(" ")}`;
|
|
1771
2060
|
const updateCwd = target === "repository" && repositoryRoot ? repositoryRoot : process.cwd();
|
|
1772
|
-
const { status, result, run, reset } = useCommand("npm", updateCwd
|
|
2061
|
+
const { status, result, run, reset } = useCommand("npm", updateCwd, {
|
|
2062
|
+
quiet: panelMode
|
|
2063
|
+
});
|
|
1773
2064
|
useEffect6(() => {
|
|
1774
2065
|
if (phase === "running" && status === "idle") {
|
|
1775
2066
|
run(updateArgs);
|
|
@@ -1784,24 +2075,28 @@ function SelfUpdate({
|
|
|
1784
2075
|
}
|
|
1785
2076
|
}, [phase, status]);
|
|
1786
2077
|
if (phase === "target") {
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
2078
|
+
const targetItems = [
|
|
2079
|
+
{ value: "__section__", label: "\u{1F4E6} Update Target", kind: "header", selectable: false },
|
|
2080
|
+
{
|
|
2081
|
+
value: "repository",
|
|
2082
|
+
label: "Current repository",
|
|
2083
|
+
hint: "Pin the latest version in package.json",
|
|
2084
|
+
kind: "action"
|
|
2085
|
+
},
|
|
2086
|
+
{
|
|
2087
|
+
value: "global",
|
|
2088
|
+
label: "Global install",
|
|
2089
|
+
hint: "Update the shared version available in PATH",
|
|
2090
|
+
kind: "action"
|
|
2091
|
+
},
|
|
2092
|
+
...!panelMode ? [{ value: "back", label: "\u2190 Back to menu" }] : []
|
|
2093
|
+
];
|
|
2094
|
+
return /* @__PURE__ */ jsxs16(Box14, { flexDirection: "column", paddingX: panelMode ? 1 : 0, children: [
|
|
2095
|
+
/* @__PURE__ */ jsx18(Box14, { marginBottom: 1, children: /* @__PURE__ */ jsx18(Text18, { bold: true, children: "Choose where to update Polter." }) }),
|
|
2096
|
+
/* @__PURE__ */ jsx18(
|
|
1790
2097
|
SelectList,
|
|
1791
2098
|
{
|
|
1792
|
-
items:
|
|
1793
|
-
{
|
|
1794
|
-
value: "repository",
|
|
1795
|
-
label: "Current repository",
|
|
1796
|
-
hint: "Pin the latest version in package.json"
|
|
1797
|
-
},
|
|
1798
|
-
{
|
|
1799
|
-
value: "global",
|
|
1800
|
-
label: "Global install",
|
|
1801
|
-
hint: "Update the shared version available in PATH"
|
|
1802
|
-
},
|
|
1803
|
-
{ value: "back", label: "\u2190 Back to menu" }
|
|
1804
|
-
],
|
|
2099
|
+
items: targetItems,
|
|
1805
2100
|
onSelect: (value) => {
|
|
1806
2101
|
if (value === "back") {
|
|
1807
2102
|
onBack();
|
|
@@ -1812,20 +2107,23 @@ function SelfUpdate({
|
|
|
1812
2107
|
setPhase("confirm");
|
|
1813
2108
|
},
|
|
1814
2109
|
onCancel: onBack,
|
|
1815
|
-
|
|
2110
|
+
boxedSections: panelMode,
|
|
2111
|
+
width: panelMode ? Math.max(20, width - 4) : width,
|
|
2112
|
+
maxVisible: panelMode ? Math.max(6, height - 6) : void 0,
|
|
1816
2113
|
isInputActive,
|
|
1817
|
-
arrowNavigation: panelMode
|
|
2114
|
+
arrowNavigation: panelMode,
|
|
2115
|
+
panelFocused: isInputActive
|
|
1818
2116
|
}
|
|
1819
2117
|
),
|
|
1820
|
-
repositoryRoot && /* @__PURE__ */
|
|
2118
|
+
repositoryRoot && /* @__PURE__ */ jsx18(Box14, { marginTop: 1, marginLeft: 2, children: /* @__PURE__ */ jsxs16(Text18, { dimColor: true, children: [
|
|
1821
2119
|
"Repository root: ",
|
|
1822
2120
|
repositoryRoot
|
|
1823
2121
|
] }) })
|
|
1824
2122
|
] });
|
|
1825
2123
|
}
|
|
1826
2124
|
if (phase === "confirm") {
|
|
1827
|
-
return /* @__PURE__ */
|
|
1828
|
-
/* @__PURE__ */
|
|
2125
|
+
return /* @__PURE__ */ jsxs16(Box14, { flexDirection: "column", paddingX: panelMode ? 1 : 0, children: [
|
|
2126
|
+
/* @__PURE__ */ jsx18(
|
|
1829
2127
|
ConfirmPrompt,
|
|
1830
2128
|
{
|
|
1831
2129
|
message: `Run ${updateDisplay}?`,
|
|
@@ -1841,12 +2139,21 @@ function SelfUpdate({
|
|
|
1841
2139
|
return;
|
|
1842
2140
|
}
|
|
1843
2141
|
onBack();
|
|
1844
|
-
}
|
|
2142
|
+
},
|
|
2143
|
+
onCancel: () => {
|
|
2144
|
+
if (repositoryRoot) {
|
|
2145
|
+
setPhase("target");
|
|
2146
|
+
} else {
|
|
2147
|
+
onBack();
|
|
2148
|
+
}
|
|
2149
|
+
},
|
|
2150
|
+
isInputActive,
|
|
2151
|
+
arrowNavigation: panelMode
|
|
1845
2152
|
}
|
|
1846
2153
|
),
|
|
1847
|
-
/* @__PURE__ */
|
|
1848
|
-
/* @__PURE__ */
|
|
1849
|
-
target === "repository" && repositoryRoot && /* @__PURE__ */
|
|
2154
|
+
/* @__PURE__ */ jsxs16(Box14, { marginTop: 1, marginLeft: 2, flexDirection: "column", children: [
|
|
2155
|
+
/* @__PURE__ */ jsx18(Text18, { dimColor: true, children: target === "repository" ? "This updates the dependency in the current repository." : "This updates the global npm install." }),
|
|
2156
|
+
target === "repository" && repositoryRoot && /* @__PURE__ */ jsxs16(Text18, { dimColor: true, children: [
|
|
1850
2157
|
"Run location: ",
|
|
1851
2158
|
repositoryRoot
|
|
1852
2159
|
] })
|
|
@@ -1854,38 +2161,49 @@ function SelfUpdate({
|
|
|
1854
2161
|
] });
|
|
1855
2162
|
}
|
|
1856
2163
|
if (phase === "running") {
|
|
1857
|
-
return /* @__PURE__ */
|
|
1858
|
-
/* @__PURE__ */
|
|
1859
|
-
/* @__PURE__ */
|
|
1860
|
-
/* @__PURE__ */
|
|
1861
|
-
/* @__PURE__ */
|
|
1862
|
-
/* @__PURE__ */
|
|
2164
|
+
return /* @__PURE__ */ jsxs16(Box14, { flexDirection: "column", paddingX: panelMode ? 1 : 0, children: [
|
|
2165
|
+
/* @__PURE__ */ jsx18(Divider, { width: panelMode ? width - 4 : width }),
|
|
2166
|
+
/* @__PURE__ */ jsxs16(Box14, { marginY: 1, gap: 1, children: [
|
|
2167
|
+
/* @__PURE__ */ jsx18(Text18, { color: inkColors.accent, bold: true, children: "\u25B6" }),
|
|
2168
|
+
/* @__PURE__ */ jsx18(Text18, { dimColor: true, children: "Running:" }),
|
|
2169
|
+
/* @__PURE__ */ jsx18(Text18, { children: updateDisplay })
|
|
1863
2170
|
] }),
|
|
1864
|
-
/* @__PURE__ */
|
|
1865
|
-
/* @__PURE__ */
|
|
2171
|
+
/* @__PURE__ */ jsx18(Divider, { width: panelMode ? width - 4 : width }),
|
|
2172
|
+
/* @__PURE__ */ jsx18(Box14, { marginTop: 1, children: /* @__PURE__ */ jsx18(Spinner, { label: "Updating Polter..." }) })
|
|
1866
2173
|
] });
|
|
1867
2174
|
}
|
|
1868
2175
|
if (phase === "success") {
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
2176
|
+
const successItems = [
|
|
2177
|
+
{ value: "__section__", label: "\u2705 Update Complete", kind: "header", selectable: false },
|
|
2178
|
+
...!panelMode ? [{ value: "__back__", label: "\u2190 Back to menu", kind: "action" }] : [],
|
|
2179
|
+
{ value: "__exit__", label: "\u{1F6AA} Exit Polter", kind: "action" }
|
|
2180
|
+
];
|
|
2181
|
+
return /* @__PURE__ */ jsxs16(Box14, { flexDirection: "column", paddingX: panelMode ? 1 : 0, children: [
|
|
2182
|
+
/* @__PURE__ */ jsx18(Divider, { width: panelMode ? width - 4 : width }),
|
|
2183
|
+
/* @__PURE__ */ jsxs16(Box14, { marginY: 1, gap: 1, children: [
|
|
2184
|
+
/* @__PURE__ */ jsx18(Text18, { color: inkColors.accent, bold: true, children: "\u2713" }),
|
|
2185
|
+
/* @__PURE__ */ jsx18(Text18, { color: inkColors.accent, bold: true, children: "Update completed successfully!" })
|
|
1874
2186
|
] }),
|
|
1875
|
-
/* @__PURE__ */
|
|
1876
|
-
/* @__PURE__ */
|
|
1877
|
-
target === "repository" && repositoryRoot && /* @__PURE__ */
|
|
2187
|
+
/* @__PURE__ */ jsxs16(Box14, { marginBottom: 1, marginLeft: 2, flexDirection: "column", children: [
|
|
2188
|
+
/* @__PURE__ */ jsx18(Text18, { dimColor: true, children: "Restart Polter to use the latest version." }),
|
|
2189
|
+
target === "repository" && repositoryRoot && /* @__PURE__ */ jsxs16(Text18, { dimColor: true, children: [
|
|
1878
2190
|
"Repository updated in: ",
|
|
1879
2191
|
repositoryRoot
|
|
1880
2192
|
] })
|
|
1881
2193
|
] }),
|
|
1882
|
-
/* @__PURE__ */
|
|
2194
|
+
/* @__PURE__ */ jsx18(
|
|
2195
|
+
CommandOutput,
|
|
2196
|
+
{
|
|
2197
|
+
stdout: result?.stdout,
|
|
2198
|
+
stderr: result?.stderr,
|
|
2199
|
+
height: Math.max(3, height - 12),
|
|
2200
|
+
isActive: isInputActive
|
|
2201
|
+
}
|
|
2202
|
+
),
|
|
2203
|
+
/* @__PURE__ */ jsx18(
|
|
1883
2204
|
SelectList,
|
|
1884
2205
|
{
|
|
1885
|
-
items:
|
|
1886
|
-
{ value: "__back__", label: "\u2190 Back to menu" },
|
|
1887
|
-
{ value: "__exit__", label: "\u{1F6AA} Exit Polter" }
|
|
1888
|
-
],
|
|
2206
|
+
items: successItems,
|
|
1889
2207
|
onSelect: (value) => {
|
|
1890
2208
|
if (value === "__exit__") {
|
|
1891
2209
|
onExit();
|
|
@@ -1894,55 +2212,69 @@ function SelfUpdate({
|
|
|
1894
2212
|
onBack();
|
|
1895
2213
|
},
|
|
1896
2214
|
onCancel: onBack,
|
|
1897
|
-
|
|
2215
|
+
boxedSections: panelMode,
|
|
2216
|
+
width: panelMode ? Math.max(20, width - 4) : width,
|
|
2217
|
+
maxVisible: panelMode ? Math.max(6, height - 6) : void 0,
|
|
1898
2218
|
isInputActive,
|
|
1899
|
-
arrowNavigation: panelMode
|
|
2219
|
+
arrowNavigation: panelMode,
|
|
2220
|
+
panelFocused: isInputActive
|
|
1900
2221
|
}
|
|
1901
2222
|
)
|
|
1902
2223
|
] });
|
|
1903
2224
|
}
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
2225
|
+
const errorItems = [
|
|
2226
|
+
{ value: "__section__", label: "\u{1F527} Recovery Options", kind: "header", selectable: false },
|
|
2227
|
+
{ value: "retry", label: "\u{1F504} Retry update", kind: "action" },
|
|
2228
|
+
...repositoryRoot ? [{ value: "target", label: "\u2194 Choose update target", kind: "action" }] : [],
|
|
2229
|
+
...!panelMode ? [{ value: "menu", label: "\u2190 Return to main menu", kind: "action" }] : [],
|
|
2230
|
+
{ value: "exit", label: "\u{1F6AA} Exit Polter", kind: "action" }
|
|
2231
|
+
];
|
|
2232
|
+
return /* @__PURE__ */ jsxs16(Box14, { flexDirection: "column", paddingX: panelMode ? 1 : 0, children: [
|
|
2233
|
+
/* @__PURE__ */ jsx18(Divider, { width: panelMode ? width - 4 : width }),
|
|
2234
|
+
result?.spawnError ? /* @__PURE__ */ jsxs16(Box14, { flexDirection: "column", marginY: 1, children: [
|
|
2235
|
+
/* @__PURE__ */ jsxs16(Box14, { gap: 1, children: [
|
|
2236
|
+
/* @__PURE__ */ jsx18(Text18, { color: "red", bold: true, children: "\u2717" }),
|
|
2237
|
+
/* @__PURE__ */ jsx18(Text18, { color: "red", bold: true, children: "Failed to start update" })
|
|
1910
2238
|
] }),
|
|
1911
|
-
/* @__PURE__ */
|
|
1912
|
-
/* @__PURE__ */
|
|
1913
|
-
/* @__PURE__ */
|
|
2239
|
+
/* @__PURE__ */ jsxs16(Box14, { marginLeft: 2, marginTop: 1, children: [
|
|
2240
|
+
/* @__PURE__ */ jsx18(Text18, { dimColor: true, children: "Error: " }),
|
|
2241
|
+
/* @__PURE__ */ jsx18(Text18, { color: "red", children: result.spawnError })
|
|
1914
2242
|
] })
|
|
1915
|
-
] }) : /* @__PURE__ */
|
|
1916
|
-
/* @__PURE__ */
|
|
1917
|
-
/* @__PURE__ */
|
|
1918
|
-
/* @__PURE__ */
|
|
1919
|
-
/* @__PURE__ */
|
|
1920
|
-
/* @__PURE__ */
|
|
1921
|
-
/* @__PURE__ */
|
|
2243
|
+
] }) : /* @__PURE__ */ jsxs16(Box14, { flexDirection: "column", marginY: 1, children: [
|
|
2244
|
+
/* @__PURE__ */ jsxs16(Box14, { gap: 1, children: [
|
|
2245
|
+
/* @__PURE__ */ jsx18(Text18, { color: "red", bold: true, children: "\u2717" }),
|
|
2246
|
+
/* @__PURE__ */ jsx18(Text18, { color: "red", children: "Update failed " }),
|
|
2247
|
+
/* @__PURE__ */ jsx18(Text18, { dimColor: true, children: "(exit code " }),
|
|
2248
|
+
/* @__PURE__ */ jsx18(Text18, { color: "red", bold: true, children: String(result?.exitCode) }),
|
|
2249
|
+
/* @__PURE__ */ jsx18(Text18, { dimColor: true, children: ")" })
|
|
1922
2250
|
] }),
|
|
1923
|
-
/* @__PURE__ */
|
|
1924
|
-
/* @__PURE__ */
|
|
1925
|
-
/* @__PURE__ */
|
|
2251
|
+
/* @__PURE__ */ jsxs16(Box14, { marginLeft: 2, marginTop: 1, children: [
|
|
2252
|
+
/* @__PURE__ */ jsx18(Text18, { dimColor: true, children: "Command: " }),
|
|
2253
|
+
/* @__PURE__ */ jsx18(Text18, { children: updateDisplay })
|
|
1926
2254
|
] })
|
|
1927
2255
|
] }),
|
|
1928
|
-
/* @__PURE__ */
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
2256
|
+
/* @__PURE__ */ jsx18(
|
|
2257
|
+
CommandOutput,
|
|
2258
|
+
{
|
|
2259
|
+
stdout: result?.stdout,
|
|
2260
|
+
stderr: result?.stderr,
|
|
2261
|
+
height: Math.max(3, height - 16),
|
|
2262
|
+
isActive: false
|
|
2263
|
+
}
|
|
2264
|
+
),
|
|
2265
|
+
/* @__PURE__ */ jsxs16(Box14, { marginBottom: 1, marginLeft: 2, flexDirection: "column", children: [
|
|
2266
|
+
/* @__PURE__ */ jsx18(Text18, { dimColor: true, children: "Manual fallback:" }),
|
|
2267
|
+
/* @__PURE__ */ jsx18(Text18, { color: inkColors.accent, children: updateDisplay }),
|
|
2268
|
+
target === "repository" && repositoryRoot && /* @__PURE__ */ jsxs16(Text18, { dimColor: true, children: [
|
|
1932
2269
|
"Run location: ",
|
|
1933
2270
|
repositoryRoot
|
|
1934
2271
|
] })
|
|
1935
2272
|
] }),
|
|
1936
|
-
/* @__PURE__ */
|
|
1937
|
-
/* @__PURE__ */
|
|
2273
|
+
!panelMode && /* @__PURE__ */ jsx18(Box14, { marginTop: 1, marginBottom: 1, children: /* @__PURE__ */ jsx18(Text18, { bold: true, children: "What would you like to do?" }) }),
|
|
2274
|
+
/* @__PURE__ */ jsx18(
|
|
1938
2275
|
SelectList,
|
|
1939
2276
|
{
|
|
1940
|
-
items:
|
|
1941
|
-
{ value: "retry", label: "\u{1F504} Retry update" },
|
|
1942
|
-
...repositoryRoot ? [{ value: "target", label: "\u2194 Choose update target" }] : [],
|
|
1943
|
-
{ value: "menu", label: "\u2190 Return to main menu" },
|
|
1944
|
-
{ value: "exit", label: "\u{1F6AA} Exit Polter" }
|
|
1945
|
-
],
|
|
2277
|
+
items: errorItems,
|
|
1946
2278
|
onSelect: (value) => {
|
|
1947
2279
|
switch (value) {
|
|
1948
2280
|
case "retry":
|
|
@@ -1962,50 +2294,78 @@ function SelfUpdate({
|
|
|
1962
2294
|
}
|
|
1963
2295
|
},
|
|
1964
2296
|
onCancel: onBack,
|
|
1965
|
-
|
|
2297
|
+
boxedSections: panelMode,
|
|
2298
|
+
width: panelMode ? Math.max(20, width - 4) : width,
|
|
2299
|
+
maxVisible: panelMode ? Math.max(6, height - 6) : void 0,
|
|
1966
2300
|
isInputActive,
|
|
1967
|
-
arrowNavigation: panelMode
|
|
2301
|
+
arrowNavigation: panelMode,
|
|
2302
|
+
panelFocused: isInputActive
|
|
1968
2303
|
}
|
|
1969
2304
|
),
|
|
1970
|
-
!panelMode && /* @__PURE__ */
|
|
2305
|
+
!panelMode && /* @__PURE__ */ jsx18(StatusBar, { width })
|
|
1971
2306
|
] });
|
|
1972
2307
|
}
|
|
1973
2308
|
|
|
1974
2309
|
// src/screens/ToolStatus.tsx
|
|
1975
2310
|
import { useMemo as useMemo4 } from "react";
|
|
1976
|
-
import { Box as
|
|
1977
|
-
import { jsx as
|
|
1978
|
-
var toolIds = ["supabase", "gh", "vercel", "
|
|
1979
|
-
function ToolStatus({ onBack, width = 80, panelMode = false, isInputActive = true }) {
|
|
2311
|
+
import { Box as Box15, Text as Text19 } from "ink";
|
|
2312
|
+
import { jsx as jsx19, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
2313
|
+
var toolIds = ["supabase", "gh", "vercel", "git"];
|
|
2314
|
+
function ToolStatus({ onBack, width = 80, height = 24, panelMode = false, isInputActive = true }) {
|
|
1980
2315
|
const tools = useMemo4(() => toolIds.map(getToolInfo), []);
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
2316
|
+
if (panelMode) {
|
|
2317
|
+
const statusItems = [
|
|
2318
|
+
{ value: "__section__", label: "Installed Tools", kind: "header", selectable: false },
|
|
2319
|
+
...tools.map((tool) => ({
|
|
2320
|
+
value: tool.id,
|
|
2321
|
+
label: `${tool.installed ? "\u2713" : "\u2717"} ${tool.label}`,
|
|
2322
|
+
hint: tool.installed ? tool.version ?? "installed" : "not found",
|
|
2323
|
+
kind: "action"
|
|
2324
|
+
}))
|
|
2325
|
+
];
|
|
2326
|
+
return /* @__PURE__ */ jsx19(Box15, { flexDirection: "column", paddingX: 1, children: /* @__PURE__ */ jsx19(
|
|
2327
|
+
SelectList,
|
|
2328
|
+
{
|
|
2329
|
+
items: statusItems,
|
|
2330
|
+
onSelect: () => {
|
|
2331
|
+
},
|
|
2332
|
+
onCancel: onBack,
|
|
2333
|
+
boxedSections: true,
|
|
2334
|
+
width: Math.max(20, width - 4),
|
|
2335
|
+
maxVisible: Math.max(6, height - 6),
|
|
2336
|
+
isInputActive,
|
|
2337
|
+
arrowNavigation: true,
|
|
2338
|
+
panelFocused: isInputActive
|
|
2339
|
+
}
|
|
2340
|
+
) });
|
|
2341
|
+
}
|
|
2342
|
+
return /* @__PURE__ */ jsxs17(Box15, { flexDirection: "column", children: [
|
|
2343
|
+
/* @__PURE__ */ jsx19(Box15, { marginBottom: 1, children: /* @__PURE__ */ jsx19(Text19, { bold: true, color: inkColors.accent, children: "\u{1F527} Tool Status" }) }),
|
|
2344
|
+
tools.map((tool) => /* @__PURE__ */ jsxs17(Box15, { gap: 1, marginLeft: 2, children: [
|
|
2345
|
+
/* @__PURE__ */ jsx19(Text19, { color: tool.installed ? inkColors.accent : "red", children: tool.installed ? "\u2713" : "\u2717" }),
|
|
2346
|
+
/* @__PURE__ */ jsx19(Box15, { width: 16, children: /* @__PURE__ */ jsx19(Text19, { bold: true, children: tool.label }) }),
|
|
2347
|
+
/* @__PURE__ */ jsx19(Text19, { dimColor: true, children: tool.installed ? tool.version ?? "installed" : "not found" })
|
|
1987
2348
|
] }, tool.id)),
|
|
1988
|
-
/* @__PURE__ */
|
|
2349
|
+
/* @__PURE__ */ jsx19(Box15, { marginTop: 1, children: /* @__PURE__ */ jsx19(
|
|
1989
2350
|
SelectList,
|
|
1990
2351
|
{
|
|
1991
2352
|
items: [{ value: "__back__", label: "\u2190 Back" }],
|
|
1992
2353
|
onSelect: onBack,
|
|
1993
2354
|
onCancel: onBack,
|
|
1994
2355
|
width,
|
|
1995
|
-
isInputActive
|
|
1996
|
-
arrowNavigation: panelMode
|
|
2356
|
+
isInputActive
|
|
1997
2357
|
}
|
|
1998
2358
|
) }),
|
|
1999
|
-
|
|
2359
|
+
/* @__PURE__ */ jsx19(StatusBar, { hint: "Enter to go back", width })
|
|
2000
2360
|
] });
|
|
2001
2361
|
}
|
|
2002
2362
|
|
|
2003
2363
|
// src/screens/ProjectConfig.tsx
|
|
2004
|
-
import { useMemo as useMemo5, useState as
|
|
2005
|
-
import { Box as
|
|
2364
|
+
import { useMemo as useMemo5, useState as useState14 } from "react";
|
|
2365
|
+
import { Box as Box16, Text as Text20 } from "ink";
|
|
2006
2366
|
|
|
2007
2367
|
// src/hooks/useEditor.ts
|
|
2008
|
-
import { useState as
|
|
2368
|
+
import { useState as useState13, useCallback as useCallback3 } from "react";
|
|
2009
2369
|
import { useStdin } from "ink";
|
|
2010
2370
|
|
|
2011
2371
|
// src/lib/editor.ts
|
|
@@ -2056,7 +2416,7 @@ function openInEditor(filePath) {
|
|
|
2056
2416
|
// src/hooks/useEditor.ts
|
|
2057
2417
|
function useEditor() {
|
|
2058
2418
|
const { setRawMode } = useStdin();
|
|
2059
|
-
const [isEditing, setIsEditing] =
|
|
2419
|
+
const [isEditing, setIsEditing] = useState13(false);
|
|
2060
2420
|
const openEditor = useCallback3(async (filePath) => {
|
|
2061
2421
|
const editor = resolveEditor();
|
|
2062
2422
|
const terminal = isTerminalEditor(editor.command);
|
|
@@ -2077,36 +2437,36 @@ function useEditor() {
|
|
|
2077
2437
|
}
|
|
2078
2438
|
|
|
2079
2439
|
// src/screens/ProjectConfig.tsx
|
|
2080
|
-
import { jsx as
|
|
2440
|
+
import { jsx as jsx20, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
2081
2441
|
function ProjectConfig({
|
|
2082
2442
|
onBack,
|
|
2083
2443
|
width = 80,
|
|
2444
|
+
height = 24,
|
|
2084
2445
|
panelMode = false,
|
|
2085
2446
|
isInputActive = true
|
|
2086
2447
|
}) {
|
|
2087
2448
|
const configPath = useMemo5(() => getProjectConfigPath(), []);
|
|
2088
|
-
const [config2, setConfig] =
|
|
2089
|
-
const [phase, setPhase] =
|
|
2090
|
-
const [feedback, setFeedback] =
|
|
2449
|
+
const [config2, setConfig] = useState14(() => getOrCreateProjectConfig());
|
|
2450
|
+
const [phase, setPhase] = useState14("overview");
|
|
2451
|
+
const [feedback, setFeedback] = useState14();
|
|
2091
2452
|
const { openEditor, isEditing } = useEditor();
|
|
2092
2453
|
if (!configPath) {
|
|
2093
|
-
return /* @__PURE__ */
|
|
2094
|
-
/* @__PURE__ */
|
|
2095
|
-
/* @__PURE__ */
|
|
2454
|
+
return /* @__PURE__ */ jsxs18(Box16, { flexDirection: "column", paddingX: panelMode ? 1 : 0, children: [
|
|
2455
|
+
/* @__PURE__ */ jsx20(Text20, { color: "red", children: "No package.json found. Run from a project directory." }),
|
|
2456
|
+
!panelMode && /* @__PURE__ */ jsx20(
|
|
2096
2457
|
SelectList,
|
|
2097
2458
|
{
|
|
2098
2459
|
items: [{ value: "__back__", label: "\u2190 Back" }],
|
|
2099
2460
|
onSelect: onBack,
|
|
2100
2461
|
onCancel: onBack,
|
|
2101
2462
|
width,
|
|
2102
|
-
isInputActive
|
|
2103
|
-
arrowNavigation: panelMode
|
|
2463
|
+
isInputActive
|
|
2104
2464
|
}
|
|
2105
2465
|
)
|
|
2106
2466
|
] });
|
|
2107
2467
|
}
|
|
2108
2468
|
if (phase === "edit-supabase-ref") {
|
|
2109
|
-
return /* @__PURE__ */
|
|
2469
|
+
return /* @__PURE__ */ jsx20(Box16, { flexDirection: "column", paddingX: panelMode ? 1 : 0, children: /* @__PURE__ */ jsx20(
|
|
2110
2470
|
TextPrompt,
|
|
2111
2471
|
{
|
|
2112
2472
|
label: "Supabase project ref:",
|
|
@@ -2124,12 +2484,16 @@ function ProjectConfig({
|
|
|
2124
2484
|
setFeedback("Supabase project ref updated");
|
|
2125
2485
|
setPhase("overview");
|
|
2126
2486
|
},
|
|
2127
|
-
onCancel: () => setPhase("overview")
|
|
2487
|
+
onCancel: () => setPhase("overview"),
|
|
2488
|
+
arrowNavigation: panelMode,
|
|
2489
|
+
isInputActive,
|
|
2490
|
+
boxed: panelMode,
|
|
2491
|
+
focused: isInputActive
|
|
2128
2492
|
}
|
|
2129
2493
|
) });
|
|
2130
2494
|
}
|
|
2131
2495
|
if (phase === "edit-vercel-id") {
|
|
2132
|
-
return /* @__PURE__ */
|
|
2496
|
+
return /* @__PURE__ */ jsx20(Box16, { flexDirection: "column", paddingX: panelMode ? 1 : 0, children: /* @__PURE__ */ jsx20(
|
|
2133
2497
|
TextPrompt,
|
|
2134
2498
|
{
|
|
2135
2499
|
label: "Vercel project ID:",
|
|
@@ -2147,12 +2511,16 @@ function ProjectConfig({
|
|
|
2147
2511
|
setFeedback("Vercel project ID updated");
|
|
2148
2512
|
setPhase("overview");
|
|
2149
2513
|
},
|
|
2150
|
-
onCancel: () => setPhase("overview")
|
|
2514
|
+
onCancel: () => setPhase("overview"),
|
|
2515
|
+
arrowNavigation: panelMode,
|
|
2516
|
+
isInputActive,
|
|
2517
|
+
boxed: panelMode,
|
|
2518
|
+
focused: isInputActive
|
|
2151
2519
|
}
|
|
2152
2520
|
) });
|
|
2153
2521
|
}
|
|
2154
2522
|
if (phase === "edit-gh-repo") {
|
|
2155
|
-
return /* @__PURE__ */
|
|
2523
|
+
return /* @__PURE__ */ jsx20(Box16, { flexDirection: "column", paddingX: panelMode ? 1 : 0, children: /* @__PURE__ */ jsx20(
|
|
2156
2524
|
TextPrompt,
|
|
2157
2525
|
{
|
|
2158
2526
|
label: "GitHub repo (owner/name):",
|
|
@@ -2170,88 +2538,133 @@ function ProjectConfig({
|
|
|
2170
2538
|
setFeedback("GitHub repo updated");
|
|
2171
2539
|
setPhase("overview");
|
|
2172
2540
|
},
|
|
2173
|
-
onCancel: () => setPhase("overview")
|
|
2541
|
+
onCancel: () => setPhase("overview"),
|
|
2542
|
+
arrowNavigation: panelMode,
|
|
2543
|
+
isInputActive,
|
|
2544
|
+
boxed: panelMode,
|
|
2545
|
+
focused: isInputActive
|
|
2174
2546
|
}
|
|
2175
2547
|
) });
|
|
2176
2548
|
}
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2549
|
+
const configItems = [
|
|
2550
|
+
{ value: "__section_current__", label: "\u{1F4CB} Current Values", kind: "header", selectable: false },
|
|
2551
|
+
{ value: "__info_supabase__", label: `Supabase ref: ${config2.tools.supabase?.projectRef ?? "not set"}`, kind: "header", selectable: false },
|
|
2552
|
+
{ value: "__info_vercel__", label: `Vercel ID: ${config2.tools.vercel?.projectId ?? "not set"}`, kind: "header", selectable: false },
|
|
2553
|
+
{ value: "__info_gh__", label: `GitHub repo: ${config2.tools.gh?.repo ?? "not set"}`, kind: "header", selectable: false },
|
|
2554
|
+
{ value: "__section_actions__", label: "\u26A1 Actions", kind: "header", selectable: false },
|
|
2555
|
+
{ value: "supabase", label: "Set Supabase project ref", kind: "action" },
|
|
2556
|
+
{ value: "vercel", label: "Set Vercel project ID", kind: "action" },
|
|
2557
|
+
{ value: "gh", label: "Set GitHub repo", kind: "action" },
|
|
2558
|
+
{ value: "editor", label: "Open config in editor", kind: "action" },
|
|
2559
|
+
...!panelMode ? [{ value: "__back__", label: "\u2190 Back" }] : []
|
|
2560
|
+
];
|
|
2561
|
+
const flatItems = [
|
|
2562
|
+
{ value: "supabase", label: "Set Supabase project ref" },
|
|
2563
|
+
{ value: "vercel", label: "Set Vercel project ID" },
|
|
2564
|
+
{ value: "gh", label: "Set GitHub repo" },
|
|
2565
|
+
{ value: "editor", label: "Open config in editor" },
|
|
2566
|
+
...!panelMode ? [{ value: "__back__", label: "\u2190 Back" }] : []
|
|
2567
|
+
];
|
|
2568
|
+
const handleSelect = (value) => {
|
|
2569
|
+
switch (value) {
|
|
2570
|
+
case "supabase":
|
|
2571
|
+
setPhase("edit-supabase-ref");
|
|
2572
|
+
break;
|
|
2573
|
+
case "vercel":
|
|
2574
|
+
setPhase("edit-vercel-id");
|
|
2575
|
+
break;
|
|
2576
|
+
case "gh":
|
|
2577
|
+
setPhase("edit-gh-repo");
|
|
2578
|
+
break;
|
|
2579
|
+
case "editor":
|
|
2580
|
+
openEditor(configPath.file).then(() => {
|
|
2581
|
+
try {
|
|
2582
|
+
const reloaded = getOrCreateProjectConfig();
|
|
2583
|
+
setConfig(reloaded);
|
|
2584
|
+
setFeedback("Config reloaded from file");
|
|
2585
|
+
} catch {
|
|
2586
|
+
setFeedback("Warning: could not parse config after editing");
|
|
2587
|
+
}
|
|
2588
|
+
});
|
|
2589
|
+
break;
|
|
2590
|
+
default:
|
|
2591
|
+
onBack();
|
|
2592
|
+
}
|
|
2593
|
+
};
|
|
2594
|
+
if (panelMode) {
|
|
2595
|
+
return /* @__PURE__ */ jsxs18(Box16, { flexDirection: "column", paddingX: 1, children: [
|
|
2596
|
+
/* @__PURE__ */ jsx20(Box16, { marginBottom: 1, marginLeft: 2, children: /* @__PURE__ */ jsxs18(Text20, { dimColor: true, children: [
|
|
2597
|
+
"Path: ",
|
|
2598
|
+
configPath.file
|
|
2599
|
+
] }) }),
|
|
2600
|
+
feedback && /* @__PURE__ */ jsx20(Box16, { marginBottom: 1, children: /* @__PURE__ */ jsxs18(Text20, { color: inkColors.accent, children: [
|
|
2601
|
+
"\u2713 ",
|
|
2602
|
+
feedback
|
|
2603
|
+
] }) }),
|
|
2604
|
+
/* @__PURE__ */ jsx20(
|
|
2605
|
+
SelectList,
|
|
2606
|
+
{
|
|
2607
|
+
items: configItems,
|
|
2608
|
+
onSelect: handleSelect,
|
|
2609
|
+
onCancel: onBack,
|
|
2610
|
+
boxedSections: true,
|
|
2611
|
+
width: Math.max(20, width - 4),
|
|
2612
|
+
maxVisible: Math.max(6, height - 6),
|
|
2613
|
+
isInputActive,
|
|
2614
|
+
arrowNavigation: true,
|
|
2615
|
+
panelFocused: isInputActive
|
|
2616
|
+
}
|
|
2617
|
+
)
|
|
2618
|
+
] });
|
|
2619
|
+
}
|
|
2620
|
+
return /* @__PURE__ */ jsxs18(Box16, { flexDirection: "column", children: [
|
|
2621
|
+
/* @__PURE__ */ jsx20(Box16, { marginBottom: 1, children: /* @__PURE__ */ jsx20(Text20, { bold: true, color: inkColors.accent, children: "\u2699\uFE0F Project Config" }) }),
|
|
2622
|
+
/* @__PURE__ */ jsxs18(Box16, { marginBottom: 1, marginLeft: 2, flexDirection: "column", children: [
|
|
2623
|
+
/* @__PURE__ */ jsxs18(Text20, { dimColor: true, children: [
|
|
2181
2624
|
"Path: ",
|
|
2182
2625
|
configPath.file
|
|
2183
2626
|
] }),
|
|
2184
|
-
/* @__PURE__ */
|
|
2627
|
+
/* @__PURE__ */ jsxs18(Text20, { children: [
|
|
2185
2628
|
"Supabase ref: ",
|
|
2186
|
-
config2.tools.supabase?.projectRef ?? /* @__PURE__ */
|
|
2629
|
+
config2.tools.supabase?.projectRef ?? /* @__PURE__ */ jsx20(Text20, { dimColor: true, children: "not set" })
|
|
2187
2630
|
] }),
|
|
2188
|
-
/* @__PURE__ */
|
|
2631
|
+
/* @__PURE__ */ jsxs18(Text20, { children: [
|
|
2189
2632
|
"Vercel ID: ",
|
|
2190
|
-
config2.tools.vercel?.projectId ?? /* @__PURE__ */
|
|
2633
|
+
config2.tools.vercel?.projectId ?? /* @__PURE__ */ jsx20(Text20, { dimColor: true, children: "not set" })
|
|
2191
2634
|
] }),
|
|
2192
|
-
/* @__PURE__ */
|
|
2635
|
+
/* @__PURE__ */ jsxs18(Text20, { children: [
|
|
2193
2636
|
"GitHub repo: ",
|
|
2194
|
-
config2.tools.gh?.repo ?? /* @__PURE__ */
|
|
2637
|
+
config2.tools.gh?.repo ?? /* @__PURE__ */ jsx20(Text20, { dimColor: true, children: "not set" })
|
|
2195
2638
|
] })
|
|
2196
2639
|
] }),
|
|
2197
|
-
feedback && /* @__PURE__ */
|
|
2640
|
+
feedback && /* @__PURE__ */ jsx20(Box16, { marginBottom: 1, children: /* @__PURE__ */ jsxs18(Text20, { color: inkColors.accent, children: [
|
|
2198
2641
|
"\u2713 ",
|
|
2199
2642
|
feedback
|
|
2200
2643
|
] }) }),
|
|
2201
|
-
/* @__PURE__ */
|
|
2644
|
+
/* @__PURE__ */ jsx20(
|
|
2202
2645
|
SelectList,
|
|
2203
2646
|
{
|
|
2204
|
-
items:
|
|
2205
|
-
|
|
2206
|
-
{ value: "vercel", label: "Set Vercel project ID" },
|
|
2207
|
-
{ value: "gh", label: "Set GitHub repo" },
|
|
2208
|
-
{ value: "editor", label: "Open config in editor" },
|
|
2209
|
-
{ value: "__back__", label: "\u2190 Back" }
|
|
2210
|
-
],
|
|
2211
|
-
onSelect: (value) => {
|
|
2212
|
-
switch (value) {
|
|
2213
|
-
case "supabase":
|
|
2214
|
-
setPhase("edit-supabase-ref");
|
|
2215
|
-
break;
|
|
2216
|
-
case "vercel":
|
|
2217
|
-
setPhase("edit-vercel-id");
|
|
2218
|
-
break;
|
|
2219
|
-
case "gh":
|
|
2220
|
-
setPhase("edit-gh-repo");
|
|
2221
|
-
break;
|
|
2222
|
-
case "editor":
|
|
2223
|
-
openEditor(configPath.file).then(() => {
|
|
2224
|
-
try {
|
|
2225
|
-
const reloaded = getOrCreateProjectConfig();
|
|
2226
|
-
setConfig(reloaded);
|
|
2227
|
-
setFeedback("Config reloaded from file");
|
|
2228
|
-
} catch {
|
|
2229
|
-
setFeedback("Warning: could not parse config after editing");
|
|
2230
|
-
}
|
|
2231
|
-
});
|
|
2232
|
-
break;
|
|
2233
|
-
default:
|
|
2234
|
-
onBack();
|
|
2235
|
-
}
|
|
2236
|
-
},
|
|
2647
|
+
items: flatItems,
|
|
2648
|
+
onSelect: handleSelect,
|
|
2237
2649
|
onCancel: onBack,
|
|
2238
2650
|
width,
|
|
2239
2651
|
isInputActive,
|
|
2240
2652
|
arrowNavigation: panelMode
|
|
2241
2653
|
}
|
|
2242
2654
|
),
|
|
2243
|
-
|
|
2655
|
+
/* @__PURE__ */ jsx20(StatusBar, { hint: "\u2191\u2193 navigate \xB7 Enter select \xB7 Esc back", width })
|
|
2244
2656
|
] });
|
|
2245
2657
|
}
|
|
2246
2658
|
|
|
2247
2659
|
// src/screens/PipelineList.tsx
|
|
2248
2660
|
import { useMemo as useMemo6 } from "react";
|
|
2249
|
-
import { Box as
|
|
2250
|
-
import { jsx as
|
|
2661
|
+
import { Box as Box17, Text as Text21 } from "ink";
|
|
2662
|
+
import { jsx as jsx21, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
2251
2663
|
function PipelineList({
|
|
2252
2664
|
onNavigate,
|
|
2253
2665
|
onBack,
|
|
2254
2666
|
width = 80,
|
|
2667
|
+
height = 24,
|
|
2255
2668
|
panelMode = false,
|
|
2256
2669
|
isInputActive = true
|
|
2257
2670
|
}) {
|
|
@@ -2299,17 +2712,19 @@ function PipelineList({
|
|
|
2299
2712
|
icon: "\u2795",
|
|
2300
2713
|
kind: "action"
|
|
2301
2714
|
});
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2715
|
+
if (!panelMode) {
|
|
2716
|
+
list.push({
|
|
2717
|
+
id: "action-back",
|
|
2718
|
+
value: "__back__",
|
|
2719
|
+
label: "\u2190 Back",
|
|
2720
|
+
kind: "action"
|
|
2721
|
+
});
|
|
2722
|
+
}
|
|
2308
2723
|
return list;
|
|
2309
|
-
}, [pipelines]);
|
|
2310
|
-
return /* @__PURE__ */
|
|
2311
|
-
/* @__PURE__ */
|
|
2312
|
-
/* @__PURE__ */
|
|
2724
|
+
}, [pipelines, panelMode]);
|
|
2725
|
+
return /* @__PURE__ */ jsxs19(Box17, { flexDirection: "column", paddingX: panelMode ? 1 : 0, children: [
|
|
2726
|
+
!panelMode && /* @__PURE__ */ jsx21(Box17, { marginBottom: 1, children: /* @__PURE__ */ jsx21(Text21, { bold: true, color: inkColors.accent, children: "\u{1F517} Pipelines" }) }),
|
|
2727
|
+
/* @__PURE__ */ jsx21(
|
|
2313
2728
|
SelectList,
|
|
2314
2729
|
{
|
|
2315
2730
|
items,
|
|
@@ -2325,19 +2740,22 @@ function PipelineList({
|
|
|
2325
2740
|
onNavigate("pipeline-execution", { pipelineId: value });
|
|
2326
2741
|
},
|
|
2327
2742
|
onCancel: onBack,
|
|
2328
|
-
|
|
2743
|
+
boxedSections: panelMode,
|
|
2744
|
+
width: panelMode ? Math.max(20, width - 4) : width,
|
|
2745
|
+
maxVisible: panelMode ? Math.max(6, height - 6) : void 0,
|
|
2329
2746
|
isInputActive,
|
|
2330
|
-
arrowNavigation: panelMode
|
|
2747
|
+
arrowNavigation: panelMode,
|
|
2748
|
+
panelFocused: isInputActive
|
|
2331
2749
|
}
|
|
2332
2750
|
),
|
|
2333
|
-
!panelMode && /* @__PURE__ */
|
|
2751
|
+
!panelMode && /* @__PURE__ */ jsx21(StatusBar, { hint: "\u2191\u2193 navigate \xB7 Enter select \xB7 Esc back", width })
|
|
2334
2752
|
] });
|
|
2335
2753
|
}
|
|
2336
2754
|
|
|
2337
2755
|
// src/screens/PipelineBuilder.tsx
|
|
2338
|
-
import { useState as
|
|
2339
|
-
import { Box as
|
|
2340
|
-
import { jsx as
|
|
2756
|
+
import { useState as useState15 } from "react";
|
|
2757
|
+
import { Box as Box18, Text as Text22 } from "ink";
|
|
2758
|
+
import { jsx as jsx22, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
2341
2759
|
var stepCounter = 0;
|
|
2342
2760
|
function nextStepId() {
|
|
2343
2761
|
stepCounter += 1;
|
|
@@ -2350,13 +2768,13 @@ function PipelineBuilder({
|
|
|
2350
2768
|
panelMode = false,
|
|
2351
2769
|
isInputActive = true
|
|
2352
2770
|
}) {
|
|
2353
|
-
const [phase, setPhase] =
|
|
2354
|
-
const [name, setName] =
|
|
2355
|
-
const [steps, setSteps] =
|
|
2771
|
+
const [phase, setPhase] = useState15("name");
|
|
2772
|
+
const [name, setName] = useState15("");
|
|
2773
|
+
const [steps, setSteps] = useState15([]);
|
|
2356
2774
|
if (phase === "name") {
|
|
2357
|
-
return /* @__PURE__ */
|
|
2358
|
-
/* @__PURE__ */
|
|
2359
|
-
/* @__PURE__ */
|
|
2775
|
+
return /* @__PURE__ */ jsxs20(Box18, { flexDirection: "column", paddingX: panelMode ? 1 : 0, children: [
|
|
2776
|
+
/* @__PURE__ */ jsx22(Box18, { marginBottom: 1, children: /* @__PURE__ */ jsx22(Text22, { bold: true, color: inkColors.accent, children: "\u{1F517} New Pipeline" }) }),
|
|
2777
|
+
/* @__PURE__ */ jsx22(
|
|
2360
2778
|
TextPrompt,
|
|
2361
2779
|
{
|
|
2362
2780
|
label: "Pipeline name:",
|
|
@@ -2369,10 +2787,14 @@ function PipelineBuilder({
|
|
|
2369
2787
|
setName(val.trim());
|
|
2370
2788
|
setPhase("add-step");
|
|
2371
2789
|
},
|
|
2372
|
-
onCancel: onBack
|
|
2790
|
+
onCancel: onBack,
|
|
2791
|
+
arrowNavigation: panelMode,
|
|
2792
|
+
isInputActive,
|
|
2793
|
+
boxed: panelMode,
|
|
2794
|
+
focused: isInputActive
|
|
2373
2795
|
}
|
|
2374
2796
|
),
|
|
2375
|
-
!panelMode && /* @__PURE__ */
|
|
2797
|
+
!panelMode && /* @__PURE__ */ jsx22(StatusBar, { hint: "Type name \xB7 Enter to continue \xB7 Esc cancel", width })
|
|
2376
2798
|
] });
|
|
2377
2799
|
}
|
|
2378
2800
|
if (phase === "add-step") {
|
|
@@ -2405,26 +2827,26 @@ function PipelineBuilder({
|
|
|
2405
2827
|
kind: "action"
|
|
2406
2828
|
}
|
|
2407
2829
|
];
|
|
2408
|
-
return /* @__PURE__ */
|
|
2409
|
-
/* @__PURE__ */
|
|
2410
|
-
/* @__PURE__ */
|
|
2830
|
+
return /* @__PURE__ */ jsxs20(Box18, { flexDirection: "column", paddingX: panelMode ? 1 : 0, children: [
|
|
2831
|
+
/* @__PURE__ */ jsxs20(Box18, { marginBottom: 1, gap: 1, children: [
|
|
2832
|
+
/* @__PURE__ */ jsxs20(Text22, { bold: true, color: inkColors.accent, children: [
|
|
2411
2833
|
"\u{1F517} ",
|
|
2412
2834
|
name
|
|
2413
2835
|
] }),
|
|
2414
|
-
/* @__PURE__ */
|
|
2836
|
+
/* @__PURE__ */ jsxs20(Text22, { dimColor: true, children: [
|
|
2415
2837
|
"(",
|
|
2416
2838
|
steps.length,
|
|
2417
2839
|
" steps)"
|
|
2418
2840
|
] })
|
|
2419
2841
|
] }),
|
|
2420
|
-
steps.length > 0 && /* @__PURE__ */
|
|
2842
|
+
steps.length > 0 && /* @__PURE__ */ jsx22(Box18, { flexDirection: "column", marginBottom: 1, children: steps.map((step, i) => /* @__PURE__ */ jsxs20(Text22, { dimColor: true, children: [
|
|
2421
2843
|
i + 1,
|
|
2422
2844
|
". ",
|
|
2423
2845
|
step.commandId,
|
|
2424
2846
|
step.args.length > 0 ? ` ${step.args.join(" ")}` : ""
|
|
2425
2847
|
] }, step.id)) }),
|
|
2426
|
-
/* @__PURE__ */
|
|
2427
|
-
/* @__PURE__ */
|
|
2848
|
+
/* @__PURE__ */ jsx22(Text22, { dimColor: true, children: "Select a command to add as step:" }),
|
|
2849
|
+
/* @__PURE__ */ jsx22(
|
|
2428
2850
|
SelectList,
|
|
2429
2851
|
{
|
|
2430
2852
|
items: commandItems,
|
|
@@ -2456,12 +2878,14 @@ function PipelineBuilder({
|
|
|
2456
2878
|
}
|
|
2457
2879
|
},
|
|
2458
2880
|
maxVisible: Math.max(8, height - 14),
|
|
2459
|
-
|
|
2881
|
+
boxedSections: panelMode,
|
|
2882
|
+
width: panelMode ? Math.max(20, width - 4) : width,
|
|
2460
2883
|
isInputActive,
|
|
2461
|
-
arrowNavigation: panelMode
|
|
2884
|
+
arrowNavigation: panelMode,
|
|
2885
|
+
panelFocused: isInputActive
|
|
2462
2886
|
}
|
|
2463
2887
|
),
|
|
2464
|
-
!panelMode && /* @__PURE__ */
|
|
2888
|
+
!panelMode && /* @__PURE__ */ jsx22(StatusBar, { hint: "\u2191\u2193 navigate \xB7 Enter add step \xB7 Esc done", width })
|
|
2465
2889
|
] });
|
|
2466
2890
|
}
|
|
2467
2891
|
const reviewItems = [
|
|
@@ -2484,18 +2908,18 @@ function PipelineBuilder({
|
|
|
2484
2908
|
kind: "action"
|
|
2485
2909
|
}
|
|
2486
2910
|
];
|
|
2487
|
-
return /* @__PURE__ */
|
|
2488
|
-
/* @__PURE__ */
|
|
2911
|
+
return /* @__PURE__ */ jsxs20(Box18, { flexDirection: "column", paddingX: panelMode ? 1 : 0, children: [
|
|
2912
|
+
/* @__PURE__ */ jsx22(Box18, { marginBottom: 1, children: /* @__PURE__ */ jsxs20(Text22, { bold: true, color: inkColors.accent, children: [
|
|
2489
2913
|
"\u{1F517} Review: ",
|
|
2490
2914
|
name
|
|
2491
2915
|
] }) }),
|
|
2492
|
-
/* @__PURE__ */
|
|
2916
|
+
/* @__PURE__ */ jsx22(Box18, { flexDirection: "column", marginBottom: 1, children: steps.map((step, i) => /* @__PURE__ */ jsxs20(Text22, { children: [
|
|
2493
2917
|
i + 1,
|
|
2494
2918
|
". ",
|
|
2495
2919
|
step.commandId,
|
|
2496
2920
|
step.args.length > 0 ? ` ${step.args.join(" ")}` : ""
|
|
2497
2921
|
] }, step.id)) }),
|
|
2498
|
-
/* @__PURE__ */
|
|
2922
|
+
/* @__PURE__ */ jsx22(
|
|
2499
2923
|
SelectList,
|
|
2500
2924
|
{
|
|
2501
2925
|
items: reviewItems,
|
|
@@ -2520,22 +2944,24 @@ function PipelineBuilder({
|
|
|
2520
2944
|
onBack();
|
|
2521
2945
|
},
|
|
2522
2946
|
onCancel: onBack,
|
|
2523
|
-
|
|
2947
|
+
boxedSections: panelMode,
|
|
2948
|
+
width: panelMode ? Math.max(20, width - 4) : width,
|
|
2524
2949
|
isInputActive,
|
|
2525
|
-
arrowNavigation: panelMode
|
|
2950
|
+
arrowNavigation: panelMode,
|
|
2951
|
+
panelFocused: isInputActive
|
|
2526
2952
|
}
|
|
2527
2953
|
),
|
|
2528
|
-
!panelMode && /* @__PURE__ */
|
|
2954
|
+
!panelMode && /* @__PURE__ */ jsx22(StatusBar, { hint: "\u2191\u2193 navigate \xB7 Enter select \xB7 Esc back", width })
|
|
2529
2955
|
] });
|
|
2530
2956
|
}
|
|
2531
2957
|
|
|
2532
2958
|
// src/screens/PipelineExecution.tsx
|
|
2533
|
-
import { useState as
|
|
2534
|
-
import { Box as
|
|
2959
|
+
import { useState as useState16, useEffect as useEffect7, useMemo as useMemo7 } from "react";
|
|
2960
|
+
import { Box as Box21, Text as Text25 } from "ink";
|
|
2535
2961
|
|
|
2536
2962
|
// src/components/StepIndicator.tsx
|
|
2537
|
-
import { Box as
|
|
2538
|
-
import { jsx as
|
|
2963
|
+
import { Box as Box19, Text as Text23 } from "ink";
|
|
2964
|
+
import { jsx as jsx23, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
2539
2965
|
var statusIcons = {
|
|
2540
2966
|
pending: "\u25CB",
|
|
2541
2967
|
running: "",
|
|
@@ -2555,21 +2981,21 @@ function StepIndicator({
|
|
|
2555
2981
|
status,
|
|
2556
2982
|
index
|
|
2557
2983
|
}) {
|
|
2558
|
-
return /* @__PURE__ */
|
|
2559
|
-
/* @__PURE__ */
|
|
2984
|
+
return /* @__PURE__ */ jsxs21(Box19, { gap: 1, children: [
|
|
2985
|
+
/* @__PURE__ */ jsxs21(Text23, { dimColor: true, children: [
|
|
2560
2986
|
String(index + 1).padStart(2, " "),
|
|
2561
2987
|
"."
|
|
2562
2988
|
] }),
|
|
2563
|
-
status === "running" ? /* @__PURE__ */
|
|
2564
|
-
|
|
2989
|
+
status === "running" ? /* @__PURE__ */ jsx23(Spinner, { label: "" }) : /* @__PURE__ */ jsx23(
|
|
2990
|
+
Text23,
|
|
2565
2991
|
{
|
|
2566
2992
|
color: statusColors[status],
|
|
2567
2993
|
dimColor: status === "pending" || status === "skipped",
|
|
2568
2994
|
children: statusIcons[status]
|
|
2569
2995
|
}
|
|
2570
2996
|
),
|
|
2571
|
-
/* @__PURE__ */
|
|
2572
|
-
|
|
2997
|
+
/* @__PURE__ */ jsx23(
|
|
2998
|
+
Text23,
|
|
2573
2999
|
{
|
|
2574
3000
|
color: statusColors[status],
|
|
2575
3001
|
dimColor: status === "pending" || status === "skipped",
|
|
@@ -2581,8 +3007,8 @@ function StepIndicator({
|
|
|
2581
3007
|
}
|
|
2582
3008
|
|
|
2583
3009
|
// src/components/PipelineProgress.tsx
|
|
2584
|
-
import { Box as
|
|
2585
|
-
import { jsxs as
|
|
3010
|
+
import { Box as Box20, Text as Text24 } from "ink";
|
|
3011
|
+
import { jsxs as jsxs22 } from "react/jsx-runtime";
|
|
2586
3012
|
function PipelineProgressBar({
|
|
2587
3013
|
total,
|
|
2588
3014
|
completed,
|
|
@@ -2593,14 +3019,14 @@ function PipelineProgressBar({
|
|
|
2593
3019
|
const filledCount = total > 0 ? Math.round(completed / total * barWidth) : 0;
|
|
2594
3020
|
const filled = "\u2588".repeat(filledCount);
|
|
2595
3021
|
const empty = "\u2591".repeat(barWidth - filledCount);
|
|
2596
|
-
return /* @__PURE__ */
|
|
2597
|
-
/* @__PURE__ */
|
|
3022
|
+
return /* @__PURE__ */ jsxs22(Box20, { gap: 1, children: [
|
|
3023
|
+
/* @__PURE__ */ jsxs22(Text24, { color: errors > 0 ? "red" : inkColors.accent, children: [
|
|
2598
3024
|
"[",
|
|
2599
3025
|
filled,
|
|
2600
3026
|
empty,
|
|
2601
3027
|
"]"
|
|
2602
3028
|
] }),
|
|
2603
|
-
/* @__PURE__ */
|
|
3029
|
+
/* @__PURE__ */ jsxs22(Text24, { dimColor: true, children: [
|
|
2604
3030
|
completed,
|
|
2605
3031
|
"/",
|
|
2606
3032
|
total,
|
|
@@ -2610,7 +3036,7 @@ function PipelineProgressBar({
|
|
|
2610
3036
|
}
|
|
2611
3037
|
|
|
2612
3038
|
// src/screens/PipelineExecution.tsx
|
|
2613
|
-
import { Fragment, jsx as
|
|
3039
|
+
import { Fragment, jsx as jsx24, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
2614
3040
|
function PipelineExecution({
|
|
2615
3041
|
pipelineId,
|
|
2616
3042
|
onBack,
|
|
@@ -2623,9 +3049,9 @@ function PipelineExecution({
|
|
|
2623
3049
|
() => getAllPipelines().find((p) => p.id === pipelineId),
|
|
2624
3050
|
[pipelineId]
|
|
2625
3051
|
);
|
|
2626
|
-
const [phase, setPhase] =
|
|
2627
|
-
const [progress, setProgress] =
|
|
2628
|
-
const [results, setResults] =
|
|
3052
|
+
const [phase, setPhase] = useState16("running");
|
|
3053
|
+
const [progress, setProgress] = useState16(null);
|
|
3054
|
+
const [results, setResults] = useState16([]);
|
|
2629
3055
|
useEffect7(() => {
|
|
2630
3056
|
if (!pipeline) return;
|
|
2631
3057
|
executePipeline(pipeline, (p) => {
|
|
@@ -2639,20 +3065,22 @@ function PipelineExecution({
|
|
|
2639
3065
|
});
|
|
2640
3066
|
}, [pipeline]);
|
|
2641
3067
|
if (!pipeline) {
|
|
2642
|
-
return /* @__PURE__ */
|
|
2643
|
-
/* @__PURE__ */
|
|
3068
|
+
return /* @__PURE__ */ jsxs23(Box21, { flexDirection: "column", paddingX: panelMode ? 1 : 0, children: [
|
|
3069
|
+
/* @__PURE__ */ jsxs23(Text25, { color: "red", children: [
|
|
2644
3070
|
"Pipeline not found: ",
|
|
2645
3071
|
pipelineId
|
|
2646
3072
|
] }),
|
|
2647
|
-
/* @__PURE__ */
|
|
3073
|
+
/* @__PURE__ */ jsx24(
|
|
2648
3074
|
SelectList,
|
|
2649
3075
|
{
|
|
2650
3076
|
items: [{ value: "__back__", label: "\u2190 Back" }],
|
|
2651
3077
|
onSelect: onBack,
|
|
2652
3078
|
onCancel: onBack,
|
|
2653
|
-
|
|
3079
|
+
boxedSections: panelMode,
|
|
3080
|
+
width: panelMode ? Math.max(20, width - 4) : width,
|
|
2654
3081
|
isInputActive,
|
|
2655
|
-
arrowNavigation: panelMode
|
|
3082
|
+
arrowNavigation: panelMode,
|
|
3083
|
+
panelFocused: isInputActive
|
|
2656
3084
|
}
|
|
2657
3085
|
)
|
|
2658
3086
|
] });
|
|
@@ -2667,15 +3095,15 @@ function PipelineExecution({
|
|
|
2667
3095
|
const base = cmdDef ? `${cmdDef.tool}: ${cmdDef.label}` : step.commandId;
|
|
2668
3096
|
return step.args.length > 0 ? `${base} ${step.args.join(" ")}` : base;
|
|
2669
3097
|
}
|
|
2670
|
-
return /* @__PURE__ */
|
|
2671
|
-
/* @__PURE__ */
|
|
2672
|
-
/* @__PURE__ */
|
|
3098
|
+
return /* @__PURE__ */ jsxs23(Box21, { flexDirection: "column", paddingX: panelMode ? 1 : 0, children: [
|
|
3099
|
+
/* @__PURE__ */ jsxs23(Box21, { marginBottom: 1, gap: 1, children: [
|
|
3100
|
+
/* @__PURE__ */ jsxs23(Text25, { bold: true, color: inkColors.accent, children: [
|
|
2673
3101
|
"\u{1F517} ",
|
|
2674
3102
|
pipeline.name
|
|
2675
3103
|
] }),
|
|
2676
|
-
/* @__PURE__ */
|
|
3104
|
+
/* @__PURE__ */ jsx24(Text25, { dimColor: true, children: phase === "running" ? "Running..." : "Complete" })
|
|
2677
3105
|
] }),
|
|
2678
|
-
/* @__PURE__ */
|
|
3106
|
+
/* @__PURE__ */ jsx24(
|
|
2679
3107
|
PipelineProgressBar,
|
|
2680
3108
|
{
|
|
2681
3109
|
total: pipeline.steps.length,
|
|
@@ -2684,8 +3112,8 @@ function PipelineExecution({
|
|
|
2684
3112
|
width
|
|
2685
3113
|
}
|
|
2686
3114
|
),
|
|
2687
|
-
/* @__PURE__ */
|
|
2688
|
-
/* @__PURE__ */
|
|
3115
|
+
/* @__PURE__ */ jsx24(Divider, { width }),
|
|
3116
|
+
/* @__PURE__ */ jsx24(Box21, { flexDirection: "column", marginY: 1, children: pipeline.steps.map((step, i) => /* @__PURE__ */ jsx24(
|
|
2689
3117
|
StepIndicator,
|
|
2690
3118
|
{
|
|
2691
3119
|
label: step.label ?? getStepLabel(step),
|
|
@@ -2694,17 +3122,17 @@ function PipelineExecution({
|
|
|
2694
3122
|
},
|
|
2695
3123
|
step.id
|
|
2696
3124
|
)) }),
|
|
2697
|
-
phase === "done" && /* @__PURE__ */
|
|
2698
|
-
/* @__PURE__ */
|
|
2699
|
-
/* @__PURE__ */
|
|
2700
|
-
|
|
3125
|
+
phase === "done" && /* @__PURE__ */ jsxs23(Fragment, { children: [
|
|
3126
|
+
/* @__PURE__ */ jsx24(Divider, { width }),
|
|
3127
|
+
/* @__PURE__ */ jsx24(Box21, { marginY: 1, children: /* @__PURE__ */ jsx24(
|
|
3128
|
+
Text25,
|
|
2701
3129
|
{
|
|
2702
3130
|
color: errorCount > 0 ? "red" : inkColors.accent,
|
|
2703
3131
|
bold: true,
|
|
2704
3132
|
children: errorCount > 0 ? `Pipeline completed with ${errorCount} error(s)` : "Pipeline completed successfully!"
|
|
2705
3133
|
}
|
|
2706
3134
|
) }),
|
|
2707
|
-
/* @__PURE__ */
|
|
3135
|
+
/* @__PURE__ */ jsx24(
|
|
2708
3136
|
SelectList,
|
|
2709
3137
|
{
|
|
2710
3138
|
items: [
|
|
@@ -2719,13 +3147,15 @@ function PipelineExecution({
|
|
|
2719
3147
|
onBack();
|
|
2720
3148
|
},
|
|
2721
3149
|
onCancel: onBack,
|
|
2722
|
-
|
|
3150
|
+
boxedSections: panelMode,
|
|
3151
|
+
width: panelMode ? Math.max(20, width - 4) : width,
|
|
2723
3152
|
isInputActive,
|
|
2724
|
-
arrowNavigation: panelMode
|
|
3153
|
+
arrowNavigation: panelMode,
|
|
3154
|
+
panelFocused: isInputActive
|
|
2725
3155
|
}
|
|
2726
3156
|
)
|
|
2727
3157
|
] }),
|
|
2728
|
-
!panelMode && /* @__PURE__ */
|
|
3158
|
+
!panelMode && /* @__PURE__ */ jsx24(
|
|
2729
3159
|
StatusBar,
|
|
2730
3160
|
{
|
|
2731
3161
|
hint: phase === "running" ? "Running pipeline..." : "Enter select \xB7 Esc back",
|
|
@@ -2736,7 +3166,7 @@ function PipelineExecution({
|
|
|
2736
3166
|
}
|
|
2737
3167
|
|
|
2738
3168
|
// src/app.tsx
|
|
2739
|
-
import { jsx as
|
|
3169
|
+
import { jsx as jsx25, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
2740
3170
|
function AppClassic() {
|
|
2741
3171
|
const { screen, params, navigate, goBack, goHome } = useNavigation();
|
|
2742
3172
|
const { exit } = useApp();
|
|
@@ -2751,9 +3181,9 @@ function AppClassic() {
|
|
|
2751
3181
|
const renderScreen = () => {
|
|
2752
3182
|
switch (screen) {
|
|
2753
3183
|
case "home":
|
|
2754
|
-
return /* @__PURE__ */
|
|
3184
|
+
return /* @__PURE__ */ jsx25(Home, { onNavigate: navigate, onExit: handleExit, width, height });
|
|
2755
3185
|
case "command-args":
|
|
2756
|
-
return /* @__PURE__ */
|
|
3186
|
+
return /* @__PURE__ */ jsx25(
|
|
2757
3187
|
CommandArgs,
|
|
2758
3188
|
{
|
|
2759
3189
|
command: params.command ?? "",
|
|
@@ -2764,9 +3194,9 @@ function AppClassic() {
|
|
|
2764
3194
|
}
|
|
2765
3195
|
);
|
|
2766
3196
|
case "custom-command":
|
|
2767
|
-
return /* @__PURE__ */
|
|
3197
|
+
return /* @__PURE__ */ jsx25(CustomCommand, { onNavigate: navigate, onBack: goBack, width });
|
|
2768
3198
|
case "flag-selection":
|
|
2769
|
-
return /* @__PURE__ */
|
|
3199
|
+
return /* @__PURE__ */ jsx25(
|
|
2770
3200
|
FlagSelection,
|
|
2771
3201
|
{
|
|
2772
3202
|
args: params.args ?? [],
|
|
@@ -2778,28 +3208,32 @@ function AppClassic() {
|
|
|
2778
3208
|
);
|
|
2779
3209
|
case "confirm-execute":
|
|
2780
3210
|
case "command-execution":
|
|
2781
|
-
return /* @__PURE__ */
|
|
3211
|
+
return /* @__PURE__ */ jsx25(
|
|
2782
3212
|
CommandExecution,
|
|
2783
3213
|
{
|
|
2784
3214
|
args: params.args ?? [],
|
|
2785
3215
|
tool: params.tool,
|
|
2786
3216
|
onBack: goBack,
|
|
2787
3217
|
onExit: handleExit,
|
|
3218
|
+
onRunSuggestion: (sugTool, sugArgs) => {
|
|
3219
|
+
goHome();
|
|
3220
|
+
navigate("confirm-execute", { tool: sugTool, args: sugArgs });
|
|
3221
|
+
},
|
|
2788
3222
|
width
|
|
2789
3223
|
}
|
|
2790
3224
|
);
|
|
2791
3225
|
case "self-update":
|
|
2792
|
-
return /* @__PURE__ */
|
|
3226
|
+
return /* @__PURE__ */ jsx25(SelfUpdate, { onBack: goBack, onExit: handleExit, width });
|
|
2793
3227
|
case "tool-status":
|
|
2794
|
-
return /* @__PURE__ */
|
|
3228
|
+
return /* @__PURE__ */ jsx25(ToolStatus, { onBack: goBack, width });
|
|
2795
3229
|
case "project-config":
|
|
2796
|
-
return /* @__PURE__ */
|
|
3230
|
+
return /* @__PURE__ */ jsx25(ProjectConfig, { onBack: goBack, width });
|
|
2797
3231
|
case "pipeline-list":
|
|
2798
|
-
return /* @__PURE__ */
|
|
3232
|
+
return /* @__PURE__ */ jsx25(PipelineList, { onNavigate: navigate, onBack: goBack, width });
|
|
2799
3233
|
case "pipeline-builder":
|
|
2800
|
-
return /* @__PURE__ */
|
|
3234
|
+
return /* @__PURE__ */ jsx25(PipelineBuilder, { onBack: goBack, width, height });
|
|
2801
3235
|
case "pipeline-execution":
|
|
2802
|
-
return /* @__PURE__ */
|
|
3236
|
+
return /* @__PURE__ */ jsx25(
|
|
2803
3237
|
PipelineExecution,
|
|
2804
3238
|
{
|
|
2805
3239
|
pipelineId: params.pipelineId ?? "",
|
|
@@ -2809,21 +3243,21 @@ function AppClassic() {
|
|
|
2809
3243
|
}
|
|
2810
3244
|
);
|
|
2811
3245
|
default:
|
|
2812
|
-
return /* @__PURE__ */
|
|
3246
|
+
return /* @__PURE__ */ jsx25(Box22, { children: /* @__PURE__ */ jsxs24(Text26, { color: "red", children: [
|
|
2813
3247
|
"Unknown screen: ",
|
|
2814
3248
|
screen
|
|
2815
3249
|
] }) });
|
|
2816
3250
|
}
|
|
2817
3251
|
};
|
|
2818
|
-
return /* @__PURE__ */
|
|
2819
|
-
/* @__PURE__ */
|
|
3252
|
+
return /* @__PURE__ */ jsxs24(Box22, { flexDirection: "column", children: [
|
|
3253
|
+
/* @__PURE__ */ jsx25(GhostBanner, { width }),
|
|
2820
3254
|
renderScreen()
|
|
2821
3255
|
] });
|
|
2822
3256
|
}
|
|
2823
3257
|
|
|
2824
3258
|
// src/appPanel.tsx
|
|
2825
|
-
import
|
|
2826
|
-
import { Box as
|
|
3259
|
+
import React19 from "react";
|
|
3260
|
+
import { Box as Box30, Text as Text33, useApp as useApp2, useInput as useInput9 } from "ink";
|
|
2827
3261
|
|
|
2828
3262
|
// src/hooks/useFullscreen.ts
|
|
2829
3263
|
import { useEffect as useEffect8 } from "react";
|
|
@@ -2841,10 +3275,10 @@ function useFullscreen() {
|
|
|
2841
3275
|
}
|
|
2842
3276
|
|
|
2843
3277
|
// src/hooks/usePanelNavigation.ts
|
|
2844
|
-
import { useState as
|
|
3278
|
+
import { useState as useState17, useCallback as useCallback4 } from "react";
|
|
2845
3279
|
function usePanelNavigation() {
|
|
2846
|
-
const [state, setState] =
|
|
2847
|
-
view: "
|
|
3280
|
+
const [state, setState] = useState17({
|
|
3281
|
+
view: "pipelines",
|
|
2848
3282
|
featureId: "database",
|
|
2849
3283
|
innerScreen: "home",
|
|
2850
3284
|
innerParams: {},
|
|
@@ -2922,19 +3356,32 @@ function usePanelNavigation() {
|
|
|
2922
3356
|
innerStack: []
|
|
2923
3357
|
}));
|
|
2924
3358
|
}, []);
|
|
3359
|
+
const switchViewAndNavigate = useCallback4(
|
|
3360
|
+
(view, screen, params) => {
|
|
3361
|
+
setState((prev) => ({
|
|
3362
|
+
...prev,
|
|
3363
|
+
view,
|
|
3364
|
+
innerScreen: screen,
|
|
3365
|
+
innerParams: params ?? {},
|
|
3366
|
+
innerStack: [{ screen: "home", params: {} }]
|
|
3367
|
+
}));
|
|
3368
|
+
},
|
|
3369
|
+
[]
|
|
3370
|
+
);
|
|
2925
3371
|
return {
|
|
2926
3372
|
...state,
|
|
2927
3373
|
selectSidebarItem,
|
|
2928
3374
|
navigateInner,
|
|
2929
3375
|
goBackInner,
|
|
2930
|
-
goHomeInner
|
|
3376
|
+
goHomeInner,
|
|
3377
|
+
switchViewAndNavigate
|
|
2931
3378
|
};
|
|
2932
3379
|
}
|
|
2933
3380
|
|
|
2934
3381
|
// src/hooks/usePanelFocus.ts
|
|
2935
|
-
import { useState as
|
|
3382
|
+
import { useState as useState18, useCallback as useCallback5 } from "react";
|
|
2936
3383
|
function usePanelFocus() {
|
|
2937
|
-
const [focused, setFocused] =
|
|
3384
|
+
const [focused, setFocused] = useState18("sidebar");
|
|
2938
3385
|
const toggleFocus = useCallback5(() => {
|
|
2939
3386
|
setFocused((prev) => prev === "sidebar" ? "main" : "sidebar");
|
|
2940
3387
|
}, []);
|
|
@@ -2952,36 +3399,35 @@ function usePanelFocus() {
|
|
|
2952
3399
|
|
|
2953
3400
|
// src/hooks/useSidebarItems.ts
|
|
2954
3401
|
import { useMemo as useMemo8 } from "react";
|
|
2955
|
-
function useSidebarItems(
|
|
3402
|
+
function useSidebarItems() {
|
|
2956
3403
|
return useMemo8(() => {
|
|
2957
3404
|
const items = [];
|
|
2958
|
-
|
|
2959
|
-
|
|
2960
|
-
|
|
2961
|
-
}
|
|
3405
|
+
items.push({ id: "__sep_workflows__", label: "---", icon: "", type: "separator", sectionTitle: "Workflows" });
|
|
3406
|
+
items.push({ id: "pipelines", label: "Pipelines", icon: "\u{1F517}", type: "action", section: "workflows" });
|
|
3407
|
+
items.push({ id: "pinned", label: "Pinned", icon: "\u{1F4CC}", type: "action", section: "workflows" });
|
|
3408
|
+
items.push({ id: "custom-command", label: "Custom Cmd", icon: "\u270F\uFE0F", type: "action", section: "workflows" });
|
|
3409
|
+
items.push({ id: "__sep_features__", label: "---", icon: "", type: "separator", sectionTitle: "Features" });
|
|
2962
3410
|
for (const feature of features) {
|
|
2963
3411
|
items.push({
|
|
2964
3412
|
id: feature.id,
|
|
2965
3413
|
label: feature.label,
|
|
2966
3414
|
icon: feature.icon,
|
|
2967
|
-
type: "feature"
|
|
3415
|
+
type: "feature",
|
|
3416
|
+
section: "features"
|
|
2968
3417
|
});
|
|
2969
3418
|
}
|
|
2970
|
-
items.push({ id: "
|
|
2971
|
-
items.push({ id: "
|
|
2972
|
-
items.push({ id: "
|
|
2973
|
-
items.push({ id: "
|
|
2974
|
-
items.push({ id: "config", label: "Config", icon: "\u2699\uFE0F", type: "action" });
|
|
2975
|
-
items.push({ id: "self-update", label: "Update", icon: "\u2B06\uFE0F", type: "action" });
|
|
2976
|
-
items.push({ id: "exit", label: "Exit", icon: "\u{1F6AA}", type: "action" });
|
|
3419
|
+
items.push({ id: "__sep_system__", label: "---", icon: "", type: "separator", sectionTitle: "System" });
|
|
3420
|
+
items.push({ id: "tool-status", label: "Tool Status", icon: "\u{1F527}", type: "action", section: "system" });
|
|
3421
|
+
items.push({ id: "config", label: "Config", icon: "\u2699\uFE0F", type: "action", section: "system" });
|
|
3422
|
+
items.push({ id: "self-update", label: "Update", icon: "\u2B06\uFE0F", type: "action", section: "system" });
|
|
2977
3423
|
return items;
|
|
2978
|
-
}, [
|
|
3424
|
+
}, []);
|
|
2979
3425
|
}
|
|
2980
3426
|
|
|
2981
3427
|
// src/hooks/useModal.ts
|
|
2982
|
-
import { useState as
|
|
3428
|
+
import { useState as useState19, useCallback as useCallback6 } from "react";
|
|
2983
3429
|
function useModal() {
|
|
2984
|
-
const [state, setState] =
|
|
3430
|
+
const [state, setState] = useState19(null);
|
|
2985
3431
|
const openModal = useCallback6((content, title) => {
|
|
2986
3432
|
setState({ content, title });
|
|
2987
3433
|
}, []);
|
|
@@ -2998,8 +3444,8 @@ function useModal() {
|
|
|
2998
3444
|
}
|
|
2999
3445
|
|
|
3000
3446
|
// src/components/PanelLayout.tsx
|
|
3001
|
-
import { Box as
|
|
3002
|
-
import { jsx as
|
|
3447
|
+
import { Box as Box23 } from "ink";
|
|
3448
|
+
import { jsx as jsx26, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
3003
3449
|
function PanelLayout({
|
|
3004
3450
|
header,
|
|
3005
3451
|
footer,
|
|
@@ -3014,19 +3460,19 @@ function PanelLayout({
|
|
|
3014
3460
|
const contentHeight = Math.max(5, height - bannerHeight - footerHeight);
|
|
3015
3461
|
const sidebarWidth = singlePanel ? 0 : panel.sidebarWidth(width);
|
|
3016
3462
|
const mainWidth = singlePanel ? width : width - sidebarWidth;
|
|
3017
|
-
return /* @__PURE__ */
|
|
3463
|
+
return /* @__PURE__ */ jsxs25(Box23, { flexDirection: "column", width, height, children: [
|
|
3018
3464
|
header,
|
|
3019
|
-
/* @__PURE__ */
|
|
3020
|
-
!singlePanel && /* @__PURE__ */
|
|
3021
|
-
/* @__PURE__ */
|
|
3465
|
+
/* @__PURE__ */ jsxs25(Box23, { flexDirection: "row", height: contentHeight, children: [
|
|
3466
|
+
!singlePanel && /* @__PURE__ */ jsx26(Box23, { width: sidebarWidth, height: contentHeight, children: sidebar }),
|
|
3467
|
+
/* @__PURE__ */ jsx26(Box23, { width: mainWidth, height: contentHeight, children: main2 })
|
|
3022
3468
|
] }),
|
|
3023
|
-
/* @__PURE__ */
|
|
3469
|
+
/* @__PURE__ */ jsx26(Box23, { height: footerHeight, children: footer })
|
|
3024
3470
|
] });
|
|
3025
3471
|
}
|
|
3026
3472
|
|
|
3027
3473
|
// src/components/Panel.tsx
|
|
3028
|
-
import { Box as
|
|
3029
|
-
import { jsx as
|
|
3474
|
+
import { Box as Box24, Text as Text27 } from "ink";
|
|
3475
|
+
import { jsx as jsx27, jsxs as jsxs26 } from "react/jsx-runtime";
|
|
3030
3476
|
function Panel({
|
|
3031
3477
|
id,
|
|
3032
3478
|
title,
|
|
@@ -3036,8 +3482,8 @@ function Panel({
|
|
|
3036
3482
|
children
|
|
3037
3483
|
}) {
|
|
3038
3484
|
const borderColor = focused ? panel.borderFocused : panel.borderDim;
|
|
3039
|
-
return /* @__PURE__ */
|
|
3040
|
-
|
|
3485
|
+
return /* @__PURE__ */ jsxs26(
|
|
3486
|
+
Box24,
|
|
3041
3487
|
{
|
|
3042
3488
|
flexDirection: "column",
|
|
3043
3489
|
width,
|
|
@@ -3046,21 +3492,34 @@ function Panel({
|
|
|
3046
3492
|
borderColor,
|
|
3047
3493
|
overflow: "hidden",
|
|
3048
3494
|
children: [
|
|
3049
|
-
title && /* @__PURE__ */
|
|
3495
|
+
title && /* @__PURE__ */ jsx27(Box24, { marginBottom: 0, children: /* @__PURE__ */ jsxs26(Text27, { color: focused ? inkColors.accent : void 0, bold: focused, dimColor: !focused, children: [
|
|
3050
3496
|
" ",
|
|
3051
3497
|
title,
|
|
3052
3498
|
" "
|
|
3053
3499
|
] }) }),
|
|
3054
|
-
/* @__PURE__ */
|
|
3500
|
+
/* @__PURE__ */ jsx27(Box24, { flexDirection: "column", flexGrow: 1, overflow: "hidden", children })
|
|
3055
3501
|
]
|
|
3056
3502
|
}
|
|
3057
3503
|
);
|
|
3058
3504
|
}
|
|
3059
3505
|
|
|
3060
3506
|
// src/components/Sidebar.tsx
|
|
3061
|
-
import { useEffect as useEffect9, useMemo as useMemo9, useState as
|
|
3062
|
-
import { Box as
|
|
3063
|
-
import { jsx as
|
|
3507
|
+
import { useEffect as useEffect9, useMemo as useMemo9, useState as useState20 } from "react";
|
|
3508
|
+
import { Box as Box25, Text as Text28, useInput as useInput8 } from "ink";
|
|
3509
|
+
import { jsx as jsx28, jsxs as jsxs27 } from "react/jsx-runtime";
|
|
3510
|
+
function groupSections(items) {
|
|
3511
|
+
const groups = [];
|
|
3512
|
+
let current = null;
|
|
3513
|
+
for (const item of items) {
|
|
3514
|
+
if (item.type === "separator" && item.sectionTitle) {
|
|
3515
|
+
current = { title: item.sectionTitle, items: [] };
|
|
3516
|
+
groups.push(current);
|
|
3517
|
+
} else if (current) {
|
|
3518
|
+
current.items.push(item);
|
|
3519
|
+
}
|
|
3520
|
+
}
|
|
3521
|
+
return groups;
|
|
3522
|
+
}
|
|
3064
3523
|
function Sidebar({
|
|
3065
3524
|
items,
|
|
3066
3525
|
selectedId,
|
|
@@ -3074,12 +3533,13 @@ function Sidebar({
|
|
|
3074
3533
|
[items]
|
|
3075
3534
|
);
|
|
3076
3535
|
const selectedIdx = selectableItems.findIndex((item) => item.id === selectedId);
|
|
3077
|
-
const [cursorIdx, setCursorIdx] =
|
|
3536
|
+
const [cursorIdx, setCursorIdx] = useState20(Math.max(0, selectedIdx));
|
|
3537
|
+
const sections = useMemo9(() => groupSections(items), [items]);
|
|
3078
3538
|
useEffect9(() => {
|
|
3079
3539
|
const idx = selectableItems.findIndex((item) => item.id === selectedId);
|
|
3080
3540
|
if (idx >= 0) setCursorIdx(idx);
|
|
3081
3541
|
}, [selectedId, selectableItems]);
|
|
3082
|
-
|
|
3542
|
+
useInput8(
|
|
3083
3543
|
(input2, key) => {
|
|
3084
3544
|
if (key.upArrow || input2 === "k") {
|
|
3085
3545
|
setCursorIdx((prev) => {
|
|
@@ -3106,39 +3566,57 @@ function Sidebar({
|
|
|
3106
3566
|
},
|
|
3107
3567
|
{ isActive: isFocused }
|
|
3108
3568
|
);
|
|
3109
|
-
let
|
|
3110
|
-
return /* @__PURE__ */
|
|
3111
|
-
|
|
3112
|
-
|
|
3113
|
-
|
|
3114
|
-
const
|
|
3115
|
-
|
|
3116
|
-
const
|
|
3117
|
-
|
|
3118
|
-
return /* @__PURE__ */ jsx26(Box24, { gap: 0, children: /* @__PURE__ */ jsxs26(
|
|
3119
|
-
Text25,
|
|
3569
|
+
let flatIdx = 0;
|
|
3570
|
+
return /* @__PURE__ */ jsx28(Box25, { flexDirection: "column", gap: 0, children: sections.map((section) => {
|
|
3571
|
+
const sectionStartIdx = flatIdx;
|
|
3572
|
+
const sectionEndIdx = sectionStartIdx + section.items.length - 1;
|
|
3573
|
+
const hasCursorInSection = isFocused && cursorIdx >= sectionStartIdx && cursorIdx <= sectionEndIdx;
|
|
3574
|
+
const hasActiveInSection = section.items.some((item) => item.id === selectedId);
|
|
3575
|
+
const borderColor = hasCursorInSection || hasActiveInSection ? inkColors.accent : "#555555";
|
|
3576
|
+
const rendered = /* @__PURE__ */ jsxs27(
|
|
3577
|
+
Box25,
|
|
3120
3578
|
{
|
|
3121
|
-
|
|
3122
|
-
|
|
3123
|
-
|
|
3579
|
+
flexDirection: "column",
|
|
3580
|
+
borderStyle: "round",
|
|
3581
|
+
borderColor,
|
|
3582
|
+
paddingX: 1,
|
|
3124
3583
|
children: [
|
|
3125
|
-
|
|
3126
|
-
item
|
|
3127
|
-
|
|
3128
|
-
|
|
3584
|
+
/* @__PURE__ */ jsx28(Text28, { dimColor: true, bold: true, children: section.title }),
|
|
3585
|
+
section.items.map((item) => {
|
|
3586
|
+
const thisIdx = flatIdx;
|
|
3587
|
+
flatIdx++;
|
|
3588
|
+
const isCursor = isFocused && thisIdx === cursorIdx;
|
|
3589
|
+
const isActive = item.id === selectedId;
|
|
3590
|
+
return /* @__PURE__ */ jsx28(Box25, { gap: 0, children: /* @__PURE__ */ jsxs27(
|
|
3591
|
+
Text28,
|
|
3592
|
+
{
|
|
3593
|
+
color: isCursor ? inkColors.accent : isActive ? inkColors.accent : void 0,
|
|
3594
|
+
bold: isCursor || isActive,
|
|
3595
|
+
dimColor: !isCursor && !isActive,
|
|
3596
|
+
children: [
|
|
3597
|
+
isCursor ? `${symbols.pointerActive} ` : " ",
|
|
3598
|
+
item.icon,
|
|
3599
|
+
" ",
|
|
3600
|
+
item.label
|
|
3601
|
+
]
|
|
3602
|
+
}
|
|
3603
|
+
) }, item.id);
|
|
3604
|
+
})
|
|
3129
3605
|
]
|
|
3130
|
-
}
|
|
3131
|
-
|
|
3606
|
+
},
|
|
3607
|
+
section.title
|
|
3608
|
+
);
|
|
3609
|
+
return rendered;
|
|
3132
3610
|
}) });
|
|
3133
3611
|
}
|
|
3134
3612
|
|
|
3135
3613
|
// src/components/PanelFooter.tsx
|
|
3136
|
-
import { Box as
|
|
3137
|
-
import { jsx as
|
|
3614
|
+
import { Box as Box26, Text as Text29 } from "ink";
|
|
3615
|
+
import { jsx as jsx29, jsxs as jsxs28 } from "react/jsx-runtime";
|
|
3138
3616
|
function PanelFooter({ hints, width }) {
|
|
3139
|
-
return /* @__PURE__ */
|
|
3140
|
-
/* @__PURE__ */
|
|
3141
|
-
/* @__PURE__ */
|
|
3617
|
+
return /* @__PURE__ */ jsx29(Box26, { width, children: /* @__PURE__ */ jsx29(Box26, { gap: 1, children: hints.map((hint) => /* @__PURE__ */ jsxs28(Box26, { gap: 0, children: [
|
|
3618
|
+
/* @__PURE__ */ jsx29(Text29, { color: inkColors.accent, bold: true, children: hint.key }),
|
|
3619
|
+
/* @__PURE__ */ jsxs28(Text29, { dimColor: true, children: [
|
|
3142
3620
|
":",
|
|
3143
3621
|
hint.action
|
|
3144
3622
|
] })
|
|
@@ -3146,8 +3624,8 @@ function PanelFooter({ hints, width }) {
|
|
|
3146
3624
|
}
|
|
3147
3625
|
|
|
3148
3626
|
// src/components/Modal.tsx
|
|
3149
|
-
import { Box as
|
|
3150
|
-
import { jsx as
|
|
3627
|
+
import { Box as Box27, Text as Text30 } from "ink";
|
|
3628
|
+
import { jsx as jsx30, jsxs as jsxs29 } from "react/jsx-runtime";
|
|
3151
3629
|
function Modal({
|
|
3152
3630
|
title,
|
|
3153
3631
|
width,
|
|
@@ -3158,10 +3636,10 @@ function Modal({
|
|
|
3158
3636
|
const modalHeight = Math.min(height - 4, 20);
|
|
3159
3637
|
const padX = Math.max(0, Math.floor((width - modalWidth) / 2));
|
|
3160
3638
|
const padY = Math.max(0, Math.floor((height - modalHeight) / 2));
|
|
3161
|
-
return /* @__PURE__ */
|
|
3162
|
-
padY > 0 && /* @__PURE__ */
|
|
3163
|
-
/* @__PURE__ */
|
|
3164
|
-
|
|
3639
|
+
return /* @__PURE__ */ jsxs29(Box27, { flexDirection: "column", width, height, children: [
|
|
3640
|
+
padY > 0 && /* @__PURE__ */ jsx30(Box27, { height: padY }),
|
|
3641
|
+
/* @__PURE__ */ jsx30(Box27, { marginLeft: padX, children: /* @__PURE__ */ jsxs29(
|
|
3642
|
+
Box27,
|
|
3165
3643
|
{
|
|
3166
3644
|
flexDirection: "column",
|
|
3167
3645
|
width: modalWidth,
|
|
@@ -3170,8 +3648,8 @@ function Modal({
|
|
|
3170
3648
|
borderColor: inkColors.accent,
|
|
3171
3649
|
paddingX: 1,
|
|
3172
3650
|
children: [
|
|
3173
|
-
/* @__PURE__ */
|
|
3174
|
-
/* @__PURE__ */
|
|
3651
|
+
/* @__PURE__ */ jsx30(Box27, { marginBottom: 1, children: /* @__PURE__ */ jsx30(Text30, { color: inkColors.accent, bold: true, children: title }) }),
|
|
3652
|
+
/* @__PURE__ */ jsx30(Box27, { flexDirection: "column", flexGrow: 1, overflow: "hidden", children })
|
|
3175
3653
|
]
|
|
3176
3654
|
}
|
|
3177
3655
|
) })
|
|
@@ -3179,9 +3657,9 @@ function Modal({
|
|
|
3179
3657
|
}
|
|
3180
3658
|
|
|
3181
3659
|
// src/components/FeatureCommands.tsx
|
|
3182
|
-
import { useEffect as useEffect10, useMemo as useMemo10, useState as
|
|
3183
|
-
import { Box as
|
|
3184
|
-
import { jsx as
|
|
3660
|
+
import { useEffect as useEffect10, useMemo as useMemo10, useState as useState21 } from "react";
|
|
3661
|
+
import { Box as Box28, Text as Text31 } from "ink";
|
|
3662
|
+
import { jsx as jsx31, jsxs as jsxs30 } from "react/jsx-runtime";
|
|
3185
3663
|
function FeatureCommands({
|
|
3186
3664
|
feature,
|
|
3187
3665
|
onNavigate,
|
|
@@ -3192,9 +3670,9 @@ function FeatureCommands({
|
|
|
3192
3670
|
height = 24,
|
|
3193
3671
|
isInputActive = true
|
|
3194
3672
|
}) {
|
|
3195
|
-
const [pinnedCommands, setPinnedCommands2] =
|
|
3196
|
-
const [pinnedRuns, setPinnedRuns2] =
|
|
3197
|
-
const [pinFeedback, setPinFeedback] =
|
|
3673
|
+
const [pinnedCommands, setPinnedCommands2] = useState21(() => getPinnedCommands());
|
|
3674
|
+
const [pinnedRuns, setPinnedRuns2] = useState21(() => getPinnedRuns());
|
|
3675
|
+
const [pinFeedback, setPinFeedback] = useState21();
|
|
3198
3676
|
useEffect10(() => {
|
|
3199
3677
|
if (!pinFeedback) return;
|
|
3200
3678
|
const timeout = setTimeout(() => setPinFeedback(void 0), 1400);
|
|
@@ -3205,7 +3683,8 @@ function FeatureCommands({
|
|
|
3205
3683
|
activeFeature: feature,
|
|
3206
3684
|
pinnedCommands,
|
|
3207
3685
|
pinnedRuns,
|
|
3208
|
-
showPinnedSection: false
|
|
3686
|
+
showPinnedSection: false,
|
|
3687
|
+
showFeatureHeader: false
|
|
3209
3688
|
}),
|
|
3210
3689
|
[feature, pinnedCommands, pinnedRuns]
|
|
3211
3690
|
);
|
|
@@ -3262,17 +3741,12 @@ function FeatureCommands({
|
|
|
3262
3741
|
);
|
|
3263
3742
|
}
|
|
3264
3743
|
};
|
|
3265
|
-
return /* @__PURE__ */
|
|
3266
|
-
/* @__PURE__ */
|
|
3267
|
-
feature.icon,
|
|
3268
|
-
" ",
|
|
3269
|
-
feature.label
|
|
3270
|
-
] }) }),
|
|
3271
|
-
pinFeedback && /* @__PURE__ */ jsx29(Box27, { marginBottom: 1, children: /* @__PURE__ */ jsxs29(Text28, { color: inkColors.accent, children: [
|
|
3744
|
+
return /* @__PURE__ */ jsxs30(Box28, { flexDirection: "column", paddingX: 1, children: [
|
|
3745
|
+
pinFeedback && /* @__PURE__ */ jsx31(Box28, { marginBottom: 1, children: /* @__PURE__ */ jsxs30(Text31, { color: inkColors.accent, children: [
|
|
3272
3746
|
"\u2713 ",
|
|
3273
3747
|
pinFeedback
|
|
3274
3748
|
] }) }),
|
|
3275
|
-
/* @__PURE__ */
|
|
3749
|
+
/* @__PURE__ */ jsx31(
|
|
3276
3750
|
SelectList,
|
|
3277
3751
|
{
|
|
3278
3752
|
items,
|
|
@@ -3283,16 +3757,17 @@ function FeatureCommands({
|
|
|
3283
3757
|
maxVisible: Math.max(6, height - 6),
|
|
3284
3758
|
onCancel: onBack,
|
|
3285
3759
|
isInputActive,
|
|
3286
|
-
arrowNavigation: true
|
|
3760
|
+
arrowNavigation: true,
|
|
3761
|
+
panelFocused: isInputActive
|
|
3287
3762
|
}
|
|
3288
3763
|
)
|
|
3289
3764
|
] });
|
|
3290
3765
|
}
|
|
3291
3766
|
|
|
3292
3767
|
// src/components/PinnedCommands.tsx
|
|
3293
|
-
import { useEffect as useEffect11, useMemo as useMemo11, useState as
|
|
3294
|
-
import { Box as
|
|
3295
|
-
import { jsx as
|
|
3768
|
+
import { useEffect as useEffect11, useMemo as useMemo11, useState as useState22 } from "react";
|
|
3769
|
+
import { Box as Box29, Text as Text32 } from "ink";
|
|
3770
|
+
import { jsx as jsx32, jsxs as jsxs31 } from "react/jsx-runtime";
|
|
3296
3771
|
function PinnedCommands({
|
|
3297
3772
|
onNavigate,
|
|
3298
3773
|
onBack,
|
|
@@ -3301,9 +3776,9 @@ function PinnedCommands({
|
|
|
3301
3776
|
height = 24,
|
|
3302
3777
|
isInputActive = true
|
|
3303
3778
|
}) {
|
|
3304
|
-
const [pinnedCommands, setPinnedCommands2] =
|
|
3305
|
-
const [pinnedRuns, setPinnedRuns2] =
|
|
3306
|
-
const [pinFeedback, setPinFeedback] =
|
|
3779
|
+
const [pinnedCommands, setPinnedCommands2] = useState22(() => getPinnedCommands());
|
|
3780
|
+
const [pinnedRuns, setPinnedRuns2] = useState22(() => getPinnedRuns());
|
|
3781
|
+
const [pinFeedback, setPinFeedback] = useState22();
|
|
3307
3782
|
useEffect11(() => {
|
|
3308
3783
|
if (!pinFeedback) return;
|
|
3309
3784
|
const timeout = setTimeout(() => setPinFeedback(void 0), 1400);
|
|
@@ -3366,18 +3841,14 @@ function PinnedCommands({
|
|
|
3366
3841
|
}
|
|
3367
3842
|
};
|
|
3368
3843
|
if (items.length === 0) {
|
|
3369
|
-
return /* @__PURE__ */
|
|
3370
|
-
/* @__PURE__ */ jsx30(Box28, { marginBottom: 1, children: /* @__PURE__ */ jsx30(Text29, { color: inkColors.accent, bold: true, children: "\u{1F4CC} Pinned" }) }),
|
|
3371
|
-
/* @__PURE__ */ jsx30(Text29, { color: "gray", children: "No pinned items. Press p on any command to pin it." })
|
|
3372
|
-
] });
|
|
3844
|
+
return /* @__PURE__ */ jsx32(Box29, { flexDirection: "column", paddingX: 1, children: /* @__PURE__ */ jsx32(Text32, { color: "gray", children: "No pinned items. Press p on any command to pin it." }) });
|
|
3373
3845
|
}
|
|
3374
|
-
return /* @__PURE__ */
|
|
3375
|
-
/* @__PURE__ */
|
|
3376
|
-
pinFeedback && /* @__PURE__ */ jsx30(Box28, { marginBottom: 1, children: /* @__PURE__ */ jsxs30(Text29, { color: inkColors.accent, children: [
|
|
3846
|
+
return /* @__PURE__ */ jsxs31(Box29, { flexDirection: "column", paddingX: 1, children: [
|
|
3847
|
+
pinFeedback && /* @__PURE__ */ jsx32(Box29, { marginBottom: 1, children: /* @__PURE__ */ jsxs31(Text32, { color: inkColors.accent, children: [
|
|
3377
3848
|
"\u2713 ",
|
|
3378
3849
|
pinFeedback
|
|
3379
3850
|
] }) }),
|
|
3380
|
-
/* @__PURE__ */
|
|
3851
|
+
/* @__PURE__ */ jsx32(
|
|
3381
3852
|
SelectList,
|
|
3382
3853
|
{
|
|
3383
3854
|
items,
|
|
@@ -3388,21 +3859,76 @@ function PinnedCommands({
|
|
|
3388
3859
|
maxVisible: Math.max(6, height - 6),
|
|
3389
3860
|
onCancel: onBack,
|
|
3390
3861
|
isInputActive,
|
|
3391
|
-
arrowNavigation: true
|
|
3862
|
+
arrowNavigation: true,
|
|
3863
|
+
panelFocused: isInputActive
|
|
3392
3864
|
}
|
|
3393
3865
|
)
|
|
3394
3866
|
] });
|
|
3395
3867
|
}
|
|
3396
3868
|
|
|
3397
3869
|
// src/appPanel.tsx
|
|
3398
|
-
import { jsx as
|
|
3870
|
+
import { jsx as jsx33, jsxs as jsxs32 } from "react/jsx-runtime";
|
|
3871
|
+
var screenLabels = {
|
|
3872
|
+
"command-args": "Args",
|
|
3873
|
+
"flag-selection": "Flags",
|
|
3874
|
+
"confirm-execute": "Execute",
|
|
3875
|
+
"command-execution": "Execute",
|
|
3876
|
+
"custom-command": "Custom Cmd",
|
|
3877
|
+
"pipeline-list": "Pipelines",
|
|
3878
|
+
"pipeline-builder": "Builder",
|
|
3879
|
+
"pipeline-execution": "Run",
|
|
3880
|
+
"self-update": "Update",
|
|
3881
|
+
"tool-status": "Status",
|
|
3882
|
+
"project-config": "Config"
|
|
3883
|
+
};
|
|
3884
|
+
function buildBreadcrumb(nav) {
|
|
3885
|
+
let base;
|
|
3886
|
+
switch (nav.view) {
|
|
3887
|
+
case "feature": {
|
|
3888
|
+
const feat = getFeatureById(nav.featureId);
|
|
3889
|
+
base = feat ? `${feat.icon} ${feat.label}` : nav.featureId;
|
|
3890
|
+
break;
|
|
3891
|
+
}
|
|
3892
|
+
case "pinned":
|
|
3893
|
+
base = "\u{1F4CC} Pinned";
|
|
3894
|
+
break;
|
|
3895
|
+
case "custom-command":
|
|
3896
|
+
base = "\u270F\uFE0F Custom Cmd";
|
|
3897
|
+
break;
|
|
3898
|
+
case "pipelines":
|
|
3899
|
+
base = "\u{1F517} Pipelines";
|
|
3900
|
+
break;
|
|
3901
|
+
case "tool-status":
|
|
3902
|
+
base = "\u{1F527} Status";
|
|
3903
|
+
break;
|
|
3904
|
+
case "config":
|
|
3905
|
+
base = "\u2699\uFE0F Config";
|
|
3906
|
+
break;
|
|
3907
|
+
case "self-update":
|
|
3908
|
+
base = "\u2B06\uFE0F Update";
|
|
3909
|
+
break;
|
|
3910
|
+
default:
|
|
3911
|
+
base = nav.view;
|
|
3912
|
+
}
|
|
3913
|
+
if (nav.innerScreen === "home") {
|
|
3914
|
+
return base;
|
|
3915
|
+
}
|
|
3916
|
+
const parts = [base];
|
|
3917
|
+
for (const entry of nav.innerStack) {
|
|
3918
|
+
if (entry.screen !== "home") {
|
|
3919
|
+
parts.push(screenLabels[entry.screen] ?? entry.screen);
|
|
3920
|
+
}
|
|
3921
|
+
}
|
|
3922
|
+
parts.push(screenLabels[nav.innerScreen] ?? nav.innerScreen);
|
|
3923
|
+
return parts.join(" \u203A ");
|
|
3924
|
+
}
|
|
3399
3925
|
var FOOTER_HINTS = [
|
|
3400
|
-
{ key: "
|
|
3926
|
+
{ key: "Tab", action: "focus" },
|
|
3927
|
+
{ key: "\u2190/Esc", action: "back" },
|
|
3928
|
+
{ key: "\u2192/Enter", action: "select" },
|
|
3401
3929
|
{ key: "j/k", action: "nav" },
|
|
3402
|
-
{ key: "Enter", action: "select" },
|
|
3403
|
-
{ key: "Esc", action: "back" },
|
|
3404
|
-
{ key: "q", action: "quit" },
|
|
3405
3930
|
{ key: "p", action: "pin" },
|
|
3931
|
+
{ key: "q", action: "quit" },
|
|
3406
3932
|
{ key: "?", action: "help" }
|
|
3407
3933
|
];
|
|
3408
3934
|
function AppPanel() {
|
|
@@ -3411,18 +3937,10 @@ function AppPanel() {
|
|
|
3411
3937
|
const { exit } = useApp2();
|
|
3412
3938
|
const nav = usePanelNavigation();
|
|
3413
3939
|
const focus = usePanelFocus();
|
|
3414
|
-
const
|
|
3415
|
-
() => getPinnedCommands().length > 0 || getPinnedRuns().length > 0
|
|
3416
|
-
);
|
|
3417
|
-
const sidebarItems = useSidebarItems(hasPins);
|
|
3940
|
+
const sidebarItems = useSidebarItems();
|
|
3418
3941
|
const modal = useModal();
|
|
3419
|
-
const refreshPins =
|
|
3420
|
-
|
|
3421
|
-
setHasPins(newHasPins);
|
|
3422
|
-
if (!newHasPins && nav.view === "pinned") {
|
|
3423
|
-
nav.selectSidebarItem("database");
|
|
3424
|
-
}
|
|
3425
|
-
}, [nav.view, nav.selectSidebarItem]);
|
|
3942
|
+
const refreshPins = React19.useCallback(() => {
|
|
3943
|
+
}, []);
|
|
3426
3944
|
const singlePanel = width < 60 || height < 15;
|
|
3427
3945
|
const handleExit = () => {
|
|
3428
3946
|
process.stdout.write(
|
|
@@ -3430,7 +3948,7 @@ function AppPanel() {
|
|
|
3430
3948
|
);
|
|
3431
3949
|
exit();
|
|
3432
3950
|
};
|
|
3433
|
-
|
|
3951
|
+
useInput9((input2, key) => {
|
|
3434
3952
|
if (modal.isOpen) {
|
|
3435
3953
|
if (key.escape || input2 === "q") {
|
|
3436
3954
|
modal.closeModal();
|
|
@@ -3455,37 +3973,37 @@ function AppPanel() {
|
|
|
3455
3973
|
}
|
|
3456
3974
|
if (input2 === "?") {
|
|
3457
3975
|
modal.openModal(
|
|
3458
|
-
/* @__PURE__ */
|
|
3459
|
-
/* @__PURE__ */
|
|
3460
|
-
/* @__PURE__ */
|
|
3976
|
+
/* @__PURE__ */ jsxs32(Box30, { flexDirection: "column", children: [
|
|
3977
|
+
/* @__PURE__ */ jsxs32(Text33, { children: [
|
|
3978
|
+
/* @__PURE__ */ jsx33(Text33, { bold: true, children: "\u2190/\u2192" }),
|
|
3461
3979
|
" Move between sidebar and main panel"
|
|
3462
3980
|
] }),
|
|
3463
|
-
/* @__PURE__ */
|
|
3464
|
-
/* @__PURE__ */
|
|
3981
|
+
/* @__PURE__ */ jsxs32(Text33, { children: [
|
|
3982
|
+
/* @__PURE__ */ jsx33(Text33, { bold: true, children: "Tab" }),
|
|
3465
3983
|
" Toggle sidebar / main panel"
|
|
3466
3984
|
] }),
|
|
3467
|
-
/* @__PURE__ */
|
|
3468
|
-
/* @__PURE__ */
|
|
3985
|
+
/* @__PURE__ */ jsxs32(Text33, { children: [
|
|
3986
|
+
/* @__PURE__ */ jsx33(Text33, { bold: true, children: "j/k" }),
|
|
3469
3987
|
" Navigate up/down"
|
|
3470
3988
|
] }),
|
|
3471
|
-
/* @__PURE__ */
|
|
3472
|
-
/* @__PURE__ */
|
|
3989
|
+
/* @__PURE__ */ jsxs32(Text33, { children: [
|
|
3990
|
+
/* @__PURE__ */ jsx33(Text33, { bold: true, children: "Enter" }),
|
|
3473
3991
|
" Select item"
|
|
3474
3992
|
] }),
|
|
3475
|
-
/* @__PURE__ */
|
|
3476
|
-
/* @__PURE__ */
|
|
3993
|
+
/* @__PURE__ */ jsxs32(Text33, { children: [
|
|
3994
|
+
/* @__PURE__ */ jsx33(Text33, { bold: true, children: "Esc" }),
|
|
3477
3995
|
" Go back (or return to sidebar)"
|
|
3478
3996
|
] }),
|
|
3479
|
-
/* @__PURE__ */
|
|
3480
|
-
/* @__PURE__ */
|
|
3997
|
+
/* @__PURE__ */ jsxs32(Text33, { children: [
|
|
3998
|
+
/* @__PURE__ */ jsx33(Text33, { bold: true, children: "q" }),
|
|
3481
3999
|
" Quit Polter"
|
|
3482
4000
|
] }),
|
|
3483
|
-
/* @__PURE__ */
|
|
3484
|
-
/* @__PURE__ */
|
|
4001
|
+
/* @__PURE__ */ jsxs32(Text33, { children: [
|
|
4002
|
+
/* @__PURE__ */ jsx33(Text33, { bold: true, children: "?" }),
|
|
3485
4003
|
" Show this help"
|
|
3486
4004
|
] }),
|
|
3487
|
-
/* @__PURE__ */
|
|
3488
|
-
/* @__PURE__ */
|
|
4005
|
+
/* @__PURE__ */ jsxs32(Text33, { children: [
|
|
4006
|
+
/* @__PURE__ */ jsx33(Text33, { bold: true, children: "p" }),
|
|
3489
4007
|
" Pin/unpin command"
|
|
3490
4008
|
] })
|
|
3491
4009
|
] }),
|
|
@@ -3535,7 +4053,7 @@ function AppPanel() {
|
|
|
3535
4053
|
}
|
|
3536
4054
|
switch (nav.view) {
|
|
3537
4055
|
case "pinned":
|
|
3538
|
-
return /* @__PURE__ */
|
|
4056
|
+
return /* @__PURE__ */ jsx33(
|
|
3539
4057
|
PinnedCommands,
|
|
3540
4058
|
{
|
|
3541
4059
|
onNavigate: nav.navigateInner,
|
|
@@ -3549,12 +4067,12 @@ function AppPanel() {
|
|
|
3549
4067
|
case "feature": {
|
|
3550
4068
|
const feature = getFeatureById(nav.featureId);
|
|
3551
4069
|
if (!feature) {
|
|
3552
|
-
return /* @__PURE__ */
|
|
4070
|
+
return /* @__PURE__ */ jsxs32(Text33, { color: "red", children: [
|
|
3553
4071
|
"Feature not found: ",
|
|
3554
4072
|
nav.featureId
|
|
3555
4073
|
] });
|
|
3556
4074
|
}
|
|
3557
|
-
return /* @__PURE__ */
|
|
4075
|
+
return /* @__PURE__ */ jsx33(
|
|
3558
4076
|
FeatureCommands,
|
|
3559
4077
|
{
|
|
3560
4078
|
feature,
|
|
@@ -3569,60 +4087,65 @@ function AppPanel() {
|
|
|
3569
4087
|
);
|
|
3570
4088
|
}
|
|
3571
4089
|
case "custom-command":
|
|
3572
|
-
return /* @__PURE__ */
|
|
4090
|
+
return /* @__PURE__ */ jsx33(
|
|
3573
4091
|
CustomCommand,
|
|
3574
4092
|
{
|
|
3575
4093
|
onNavigate: nav.navigateInner,
|
|
3576
4094
|
onBack: focus.focusSidebar,
|
|
3577
4095
|
width: mainContentWidth - 2,
|
|
4096
|
+
height: mainContentHeight,
|
|
3578
4097
|
panelMode: true,
|
|
3579
4098
|
isInputActive: focus.isMainFocused
|
|
3580
4099
|
}
|
|
3581
4100
|
);
|
|
3582
4101
|
case "pipelines":
|
|
3583
|
-
return /* @__PURE__ */
|
|
4102
|
+
return /* @__PURE__ */ jsx33(
|
|
3584
4103
|
PipelineList,
|
|
3585
4104
|
{
|
|
3586
4105
|
onNavigate: nav.navigateInner,
|
|
3587
4106
|
onBack: focus.focusSidebar,
|
|
3588
4107
|
width: mainContentWidth - 2,
|
|
4108
|
+
height: mainContentHeight,
|
|
3589
4109
|
panelMode: true,
|
|
3590
4110
|
isInputActive: focus.isMainFocused
|
|
3591
4111
|
}
|
|
3592
4112
|
);
|
|
3593
4113
|
case "tool-status":
|
|
3594
|
-
return /* @__PURE__ */
|
|
4114
|
+
return /* @__PURE__ */ jsx33(
|
|
3595
4115
|
ToolStatus,
|
|
3596
4116
|
{
|
|
3597
4117
|
onBack: focus.focusSidebar,
|
|
3598
4118
|
width: mainContentWidth - 2,
|
|
4119
|
+
height: mainContentHeight,
|
|
3599
4120
|
panelMode: true,
|
|
3600
4121
|
isInputActive: focus.isMainFocused
|
|
3601
4122
|
}
|
|
3602
4123
|
);
|
|
3603
4124
|
case "config":
|
|
3604
|
-
return /* @__PURE__ */
|
|
4125
|
+
return /* @__PURE__ */ jsx33(
|
|
3605
4126
|
ProjectConfig,
|
|
3606
4127
|
{
|
|
3607
4128
|
onBack: focus.focusSidebar,
|
|
3608
4129
|
width: mainContentWidth - 2,
|
|
4130
|
+
height: mainContentHeight,
|
|
3609
4131
|
panelMode: true,
|
|
3610
4132
|
isInputActive: focus.isMainFocused
|
|
3611
4133
|
}
|
|
3612
4134
|
);
|
|
3613
4135
|
case "self-update":
|
|
3614
|
-
return /* @__PURE__ */
|
|
4136
|
+
return /* @__PURE__ */ jsx33(
|
|
3615
4137
|
SelfUpdate,
|
|
3616
4138
|
{
|
|
3617
4139
|
onBack: focus.focusSidebar,
|
|
3618
4140
|
onExit: handleExit,
|
|
3619
4141
|
width: mainContentWidth - 2,
|
|
4142
|
+
height: mainContentHeight,
|
|
3620
4143
|
panelMode: true,
|
|
3621
4144
|
isInputActive: focus.isMainFocused
|
|
3622
4145
|
}
|
|
3623
4146
|
);
|
|
3624
4147
|
default:
|
|
3625
|
-
return /* @__PURE__ */
|
|
4148
|
+
return /* @__PURE__ */ jsx33(Text33, { children: "Select an item from the sidebar" });
|
|
3626
4149
|
}
|
|
3627
4150
|
};
|
|
3628
4151
|
const renderInnerScreen = () => {
|
|
@@ -3630,7 +4153,7 @@ function AppPanel() {
|
|
|
3630
4153
|
const w = mainContentWidth - 2;
|
|
3631
4154
|
switch (nav.innerScreen) {
|
|
3632
4155
|
case "command-args":
|
|
3633
|
-
return /* @__PURE__ */
|
|
4156
|
+
return /* @__PURE__ */ jsx33(
|
|
3634
4157
|
CommandArgs,
|
|
3635
4158
|
{
|
|
3636
4159
|
command: nav.innerParams.command ?? "",
|
|
@@ -3643,18 +4166,19 @@ function AppPanel() {
|
|
|
3643
4166
|
}
|
|
3644
4167
|
);
|
|
3645
4168
|
case "custom-command":
|
|
3646
|
-
return /* @__PURE__ */
|
|
4169
|
+
return /* @__PURE__ */ jsx33(
|
|
3647
4170
|
CustomCommand,
|
|
3648
4171
|
{
|
|
3649
4172
|
onNavigate: nav.navigateInner,
|
|
3650
4173
|
onBack: nav.goBackInner,
|
|
3651
4174
|
width: w,
|
|
4175
|
+
height: mainContentHeight,
|
|
3652
4176
|
panelMode: true,
|
|
3653
4177
|
isInputActive: isActive
|
|
3654
4178
|
}
|
|
3655
4179
|
);
|
|
3656
4180
|
case "flag-selection":
|
|
3657
|
-
return /* @__PURE__ */
|
|
4181
|
+
return /* @__PURE__ */ jsx33(
|
|
3658
4182
|
FlagSelection,
|
|
3659
4183
|
{
|
|
3660
4184
|
args: nav.innerParams.args ?? [],
|
|
@@ -3662,37 +4186,45 @@ function AppPanel() {
|
|
|
3662
4186
|
onNavigate: nav.navigateInner,
|
|
3663
4187
|
onBack: nav.goBackInner,
|
|
3664
4188
|
width: w,
|
|
4189
|
+
height: mainContentHeight,
|
|
3665
4190
|
panelMode: true,
|
|
3666
4191
|
isInputActive: isActive
|
|
3667
4192
|
}
|
|
3668
4193
|
);
|
|
3669
4194
|
case "confirm-execute":
|
|
3670
4195
|
case "command-execution":
|
|
3671
|
-
return /* @__PURE__ */
|
|
4196
|
+
return /* @__PURE__ */ jsx33(
|
|
3672
4197
|
CommandExecution,
|
|
3673
4198
|
{
|
|
3674
4199
|
args: nav.innerParams.args ?? [],
|
|
3675
4200
|
tool: nav.innerParams.tool,
|
|
3676
4201
|
onBack: nav.goBackInner,
|
|
4202
|
+
onHome: nav.goHomeInner,
|
|
3677
4203
|
onExit: handleExit,
|
|
4204
|
+
onRunSuggestion: (sugTool, sugArgs) => {
|
|
4205
|
+
nav.switchViewAndNavigate("custom-command", "confirm-execute", { tool: sugTool, args: sugArgs });
|
|
4206
|
+
},
|
|
3678
4207
|
width: w,
|
|
4208
|
+
height: mainContentHeight,
|
|
3679
4209
|
panelMode: true,
|
|
3680
4210
|
isInputActive: isActive
|
|
3681
|
-
}
|
|
4211
|
+
},
|
|
4212
|
+
`${nav.view}-${nav.innerParams.tool}-${(nav.innerParams.args ?? []).join("-")}`
|
|
3682
4213
|
);
|
|
3683
4214
|
case "pipeline-list":
|
|
3684
|
-
return /* @__PURE__ */
|
|
4215
|
+
return /* @__PURE__ */ jsx33(
|
|
3685
4216
|
PipelineList,
|
|
3686
4217
|
{
|
|
3687
4218
|
onNavigate: nav.navigateInner,
|
|
3688
4219
|
onBack: nav.goBackInner,
|
|
3689
4220
|
width: w,
|
|
4221
|
+
height: mainContentHeight,
|
|
3690
4222
|
panelMode: true,
|
|
3691
4223
|
isInputActive: isActive
|
|
3692
4224
|
}
|
|
3693
4225
|
);
|
|
3694
4226
|
case "pipeline-builder":
|
|
3695
|
-
return /* @__PURE__ */
|
|
4227
|
+
return /* @__PURE__ */ jsx33(
|
|
3696
4228
|
PipelineBuilder,
|
|
3697
4229
|
{
|
|
3698
4230
|
onBack: nav.goBackInner,
|
|
@@ -3703,7 +4235,7 @@ function AppPanel() {
|
|
|
3703
4235
|
}
|
|
3704
4236
|
);
|
|
3705
4237
|
case "pipeline-execution":
|
|
3706
|
-
return /* @__PURE__ */
|
|
4238
|
+
return /* @__PURE__ */ jsx33(
|
|
3707
4239
|
PipelineExecution,
|
|
3708
4240
|
{
|
|
3709
4241
|
pipelineId: nav.innerParams.pipelineId ?? "",
|
|
@@ -3715,48 +4247,51 @@ function AppPanel() {
|
|
|
3715
4247
|
}
|
|
3716
4248
|
);
|
|
3717
4249
|
case "self-update":
|
|
3718
|
-
return /* @__PURE__ */
|
|
4250
|
+
return /* @__PURE__ */ jsx33(
|
|
3719
4251
|
SelfUpdate,
|
|
3720
4252
|
{
|
|
3721
4253
|
onBack: nav.goBackInner,
|
|
3722
4254
|
onExit: handleExit,
|
|
3723
4255
|
width: w,
|
|
4256
|
+
height: mainContentHeight,
|
|
3724
4257
|
panelMode: true,
|
|
3725
4258
|
isInputActive: isActive
|
|
3726
4259
|
}
|
|
3727
4260
|
);
|
|
3728
4261
|
case "tool-status":
|
|
3729
|
-
return /* @__PURE__ */
|
|
4262
|
+
return /* @__PURE__ */ jsx33(
|
|
3730
4263
|
ToolStatus,
|
|
3731
4264
|
{
|
|
3732
4265
|
onBack: nav.goBackInner,
|
|
3733
4266
|
width: w,
|
|
4267
|
+
height: mainContentHeight,
|
|
3734
4268
|
panelMode: true,
|
|
3735
4269
|
isInputActive: isActive
|
|
3736
4270
|
}
|
|
3737
4271
|
);
|
|
3738
4272
|
case "project-config":
|
|
3739
|
-
return /* @__PURE__ */
|
|
4273
|
+
return /* @__PURE__ */ jsx33(
|
|
3740
4274
|
ProjectConfig,
|
|
3741
4275
|
{
|
|
3742
4276
|
onBack: nav.goBackInner,
|
|
3743
4277
|
width: w,
|
|
4278
|
+
height: mainContentHeight,
|
|
3744
4279
|
panelMode: true,
|
|
3745
4280
|
isInputActive: isActive
|
|
3746
4281
|
}
|
|
3747
4282
|
);
|
|
3748
4283
|
default:
|
|
3749
|
-
return /* @__PURE__ */
|
|
4284
|
+
return /* @__PURE__ */ jsxs32(Text33, { color: "red", children: [
|
|
3750
4285
|
"Unknown screen: ",
|
|
3751
4286
|
nav.innerScreen
|
|
3752
4287
|
] });
|
|
3753
4288
|
}
|
|
3754
4289
|
};
|
|
3755
4290
|
if (modal.isOpen) {
|
|
3756
|
-
return /* @__PURE__ */
|
|
4291
|
+
return /* @__PURE__ */ jsx33(Box30, { flexDirection: "column", width, height, children: /* @__PURE__ */ jsx33(Modal, { title: modal.modalTitle, width, height, children: modal.modalContent }) });
|
|
3757
4292
|
}
|
|
3758
|
-
const header = /* @__PURE__ */
|
|
3759
|
-
const sidebar = /* @__PURE__ */
|
|
4293
|
+
const header = /* @__PURE__ */ jsx33(GhostBanner, { width, compact: true });
|
|
4294
|
+
const sidebar = /* @__PURE__ */ jsx33(
|
|
3760
4295
|
Panel,
|
|
3761
4296
|
{
|
|
3762
4297
|
id: "sidebar",
|
|
@@ -3764,7 +4299,7 @@ function AppPanel() {
|
|
|
3764
4299
|
width: Math.max(20, Math.min(35, Math.floor(width * 0.3))),
|
|
3765
4300
|
height: Math.max(5, height - bannerHeight - 1),
|
|
3766
4301
|
focused: focus.isSidebarFocused,
|
|
3767
|
-
children: /* @__PURE__ */
|
|
4302
|
+
children: /* @__PURE__ */ jsx33(
|
|
3768
4303
|
Sidebar,
|
|
3769
4304
|
{
|
|
3770
4305
|
items: sidebarItems,
|
|
@@ -3777,19 +4312,19 @@ function AppPanel() {
|
|
|
3777
4312
|
)
|
|
3778
4313
|
}
|
|
3779
4314
|
);
|
|
3780
|
-
const main2 = /* @__PURE__ */
|
|
4315
|
+
const main2 = /* @__PURE__ */ jsx33(
|
|
3781
4316
|
Panel,
|
|
3782
4317
|
{
|
|
3783
4318
|
id: "main",
|
|
3784
|
-
title:
|
|
4319
|
+
title: buildBreadcrumb(nav),
|
|
3785
4320
|
width: mainContentWidth,
|
|
3786
4321
|
height: Math.max(5, height - bannerHeight - 1),
|
|
3787
4322
|
focused: focus.isMainFocused,
|
|
3788
4323
|
children: renderMainContent()
|
|
3789
4324
|
}
|
|
3790
4325
|
);
|
|
3791
|
-
const footer = /* @__PURE__ */
|
|
3792
|
-
return /* @__PURE__ */
|
|
4326
|
+
const footer = /* @__PURE__ */ jsx33(PanelFooter, { hints: footerHints, width });
|
|
4327
|
+
return /* @__PURE__ */ jsx33(
|
|
3793
4328
|
PanelLayout,
|
|
3794
4329
|
{
|
|
3795
4330
|
header,
|
|
@@ -3832,11 +4367,17 @@ function parseCliArgs(argv) {
|
|
|
3832
4367
|
if (argv_[0] === "pipeline" && argv_[1] === "run" && argv_[2]) {
|
|
3833
4368
|
return { mode: "pipeline-run", options: {}, pipelineName: argv_[2] };
|
|
3834
4369
|
}
|
|
3835
|
-
if (argv_[0] === "mcp"
|
|
3836
|
-
|
|
3837
|
-
if (
|
|
3838
|
-
|
|
3839
|
-
|
|
4370
|
+
if (argv_[0] === "mcp") {
|
|
4371
|
+
const sub = argv_[1];
|
|
4372
|
+
if (sub === "status") {
|
|
4373
|
+
return { mode: "mcp", options: {}, mcpAction: "status" };
|
|
4374
|
+
}
|
|
4375
|
+
if (sub === "install" || sub === "update" || sub === "remove") {
|
|
4376
|
+
let mcpScope = "local";
|
|
4377
|
+
if (argv_.includes("--project")) mcpScope = "project";
|
|
4378
|
+
else if (argv_.includes("--global")) mcpScope = "user";
|
|
4379
|
+
return { mode: "mcp", options: {}, mcpAction: sub, mcpScope };
|
|
4380
|
+
}
|
|
3840
4381
|
}
|
|
3841
4382
|
if (argv_[0] === "config") {
|
|
3842
4383
|
const edit = argv_.includes("--edit");
|
|
@@ -3925,6 +4466,9 @@ function printCliHelp() {
|
|
|
3925
4466
|
" polter mcp install Install Polter MCP server into Claude Code (local scope)",
|
|
3926
4467
|
" polter mcp install --project Install for this project only (shared via repo)",
|
|
3927
4468
|
" polter mcp install --global Install globally for all projects",
|
|
4469
|
+
" polter mcp update Update MCP server to latest version",
|
|
4470
|
+
" polter mcp status Show MCP registration and version info",
|
|
4471
|
+
" polter mcp remove Remove MCP server registration",
|
|
3928
4472
|
"",
|
|
3929
4473
|
" polter app setup ops [--path <dir>] [--create-project|--use-existing-project] [--yes]",
|
|
3930
4474
|
" polter app link ops [--path <dir>] [--relink]",
|
|
@@ -4750,8 +5294,10 @@ import { spawnSync as spawnSync2 } from "child_process";
|
|
|
4750
5294
|
import { readFileSync as readFileSync2, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2, existsSync as existsSync2 } from "fs";
|
|
4751
5295
|
import { join as join3 } from "path";
|
|
4752
5296
|
import { homedir as homedir2 } from "os";
|
|
5297
|
+
import { createRequire as createRequire2 } from "module";
|
|
4753
5298
|
import pc4 from "picocolors";
|
|
4754
|
-
var
|
|
5299
|
+
var require3 = createRequire2(import.meta.url);
|
|
5300
|
+
var MCP_ARGS = ["npx", "-y", "-p", "@polterware/polter@latest", "polter-mcp"];
|
|
4755
5301
|
var SCOPE_LABELS = {
|
|
4756
5302
|
local: "local (this machine)",
|
|
4757
5303
|
project: "project (shared via repo)",
|
|
@@ -4789,7 +5335,7 @@ function tryManualInstall(scope) {
|
|
|
4789
5335
|
const mcpServers = settings.mcpServers ?? {};
|
|
4790
5336
|
mcpServers.polter = {
|
|
4791
5337
|
command: "npx",
|
|
4792
|
-
args: ["-y", "-p", "@polterware/polter", "polter-mcp"]
|
|
5338
|
+
args: ["-y", "-p", "@polterware/polter@latest", "polter-mcp"]
|
|
4793
5339
|
};
|
|
4794
5340
|
settings.mcpServers = mcpServers;
|
|
4795
5341
|
writeFileSync2(settingsPath, JSON.stringify(settings, null, 2) + "\n");
|
|
@@ -4815,11 +5361,93 @@ async function installMcpServer(scope) {
|
|
|
4815
5361
|
process.stdout.write(pc4.green("\n Done! Restart Claude Code to use Polter tools.\n"));
|
|
4816
5362
|
} else {
|
|
4817
5363
|
process.stderr.write(pc4.red("\n Failed to install. Add manually:\n\n"));
|
|
4818
|
-
process.stderr.write(` ${pc4.dim(JSON.stringify({ mcpServers: { polter: { command: "npx", args: ["-y", "-p", "@polterware/polter", "polter-mcp"] } } }, null, 2))}
|
|
5364
|
+
process.stderr.write(` ${pc4.dim(JSON.stringify({ mcpServers: { polter: { command: "npx", args: ["-y", "-p", "@polterware/polter@latest", "polter-mcp"] } } }, null, 2))}
|
|
4819
5365
|
`);
|
|
4820
5366
|
process.exit(1);
|
|
4821
5367
|
}
|
|
4822
5368
|
}
|
|
5369
|
+
async function removeMcpServer(scope) {
|
|
5370
|
+
process.stdout.write(pc4.bold(`Removing Polter MCP server \u2014 ${SCOPE_LABELS[scope]}
|
|
5371
|
+
|
|
5372
|
+
`));
|
|
5373
|
+
if (commandExists("claude")) {
|
|
5374
|
+
const result = spawnSync2("claude", ["mcp", "remove", "-s", scope, "polter"], {
|
|
5375
|
+
stdio: "inherit",
|
|
5376
|
+
shell: true
|
|
5377
|
+
});
|
|
5378
|
+
if (result.status === 0) {
|
|
5379
|
+
process.stdout.write(pc4.green("\n Done! Polter MCP server removed.\n"));
|
|
5380
|
+
return;
|
|
5381
|
+
}
|
|
5382
|
+
process.stdout.write(pc4.yellow(" 'claude mcp remove' failed, falling back to manual removal...\n\n"));
|
|
5383
|
+
}
|
|
5384
|
+
const settingsPath = getSettingsPath(scope);
|
|
5385
|
+
if (!existsSync2(settingsPath)) {
|
|
5386
|
+
process.stdout.write(pc4.yellow(" No settings file found. Nothing to remove.\n"));
|
|
5387
|
+
return;
|
|
5388
|
+
}
|
|
5389
|
+
let settings;
|
|
5390
|
+
try {
|
|
5391
|
+
settings = JSON.parse(readFileSync2(settingsPath, "utf-8"));
|
|
5392
|
+
} catch {
|
|
5393
|
+
process.stderr.write(pc4.red(` Failed to parse ${settingsPath}
|
|
5394
|
+
`));
|
|
5395
|
+
process.exit(1);
|
|
5396
|
+
return;
|
|
5397
|
+
}
|
|
5398
|
+
const mcpServers = settings.mcpServers;
|
|
5399
|
+
if (!mcpServers?.polter) {
|
|
5400
|
+
process.stdout.write(pc4.yellow(" Polter MCP server not found in settings. Nothing to remove.\n"));
|
|
5401
|
+
return;
|
|
5402
|
+
}
|
|
5403
|
+
delete mcpServers.polter;
|
|
5404
|
+
settings.mcpServers = mcpServers;
|
|
5405
|
+
writeFileSync2(settingsPath, JSON.stringify(settings, null, 2) + "\n");
|
|
5406
|
+
process.stdout.write(pc4.green(" Done! Polter MCP server removed.\n"));
|
|
5407
|
+
}
|
|
5408
|
+
async function mcpStatus() {
|
|
5409
|
+
process.stdout.write(pc4.bold("Polter MCP Server Status\n\n"));
|
|
5410
|
+
const pkg = require3("../../package.json");
|
|
5411
|
+
process.stdout.write(` Installed version: ${pc4.cyan(pkg.version)}
|
|
5412
|
+
`);
|
|
5413
|
+
const latestResult = spawnSync2("npm", ["view", "@polterware/polter", "version"], {
|
|
5414
|
+
encoding: "utf-8",
|
|
5415
|
+
shell: true,
|
|
5416
|
+
timeout: 1e4
|
|
5417
|
+
});
|
|
5418
|
+
const latest = latestResult.stdout?.trim();
|
|
5419
|
+
if (latest) {
|
|
5420
|
+
const upToDate = latest === pkg.version;
|
|
5421
|
+
process.stdout.write(` Latest version: ${upToDate ? pc4.green(latest) : pc4.yellow(`${latest} (update available)`)}
|
|
5422
|
+
`);
|
|
5423
|
+
}
|
|
5424
|
+
process.stdout.write("\n");
|
|
5425
|
+
const scopes = [
|
|
5426
|
+
{ label: "Project (.mcp.json)", path: join3(process.cwd(), ".mcp.json"), key: "project" },
|
|
5427
|
+
{ label: "User (~/.claude/settings.json)", path: join3(homedir2(), ".claude", "settings.json"), key: "user" }
|
|
5428
|
+
];
|
|
5429
|
+
for (const scope of scopes) {
|
|
5430
|
+
if (!existsSync2(scope.path)) {
|
|
5431
|
+
process.stdout.write(` ${scope.label}: ${pc4.dim("not found")}
|
|
5432
|
+
`);
|
|
5433
|
+
continue;
|
|
5434
|
+
}
|
|
5435
|
+
try {
|
|
5436
|
+
const settings = JSON.parse(readFileSync2(scope.path, "utf-8"));
|
|
5437
|
+
const mcpServers = settings.mcpServers;
|
|
5438
|
+
if (mcpServers?.polter) {
|
|
5439
|
+
process.stdout.write(` ${scope.label}: ${pc4.green("registered")}
|
|
5440
|
+
`);
|
|
5441
|
+
} else {
|
|
5442
|
+
process.stdout.write(` ${scope.label}: ${pc4.dim("not registered")}
|
|
5443
|
+
`);
|
|
5444
|
+
}
|
|
5445
|
+
} catch {
|
|
5446
|
+
process.stdout.write(` ${scope.label}: ${pc4.red("error reading file")}
|
|
5447
|
+
`);
|
|
5448
|
+
}
|
|
5449
|
+
}
|
|
5450
|
+
}
|
|
4823
5451
|
|
|
4824
5452
|
// src/index.tsx
|
|
4825
5453
|
import pc5 from "picocolors";
|
|
@@ -4829,8 +5457,20 @@ async function main() {
|
|
|
4829
5457
|
printCliHelp();
|
|
4830
5458
|
return;
|
|
4831
5459
|
}
|
|
4832
|
-
if (parsed.mode === "mcp
|
|
4833
|
-
|
|
5460
|
+
if (parsed.mode === "mcp") {
|
|
5461
|
+
const scope = parsed.mcpScope ?? "local";
|
|
5462
|
+
switch (parsed.mcpAction) {
|
|
5463
|
+
case "install":
|
|
5464
|
+
case "update":
|
|
5465
|
+
await installMcpServer(scope);
|
|
5466
|
+
break;
|
|
5467
|
+
case "remove":
|
|
5468
|
+
await removeMcpServer(scope);
|
|
5469
|
+
break;
|
|
5470
|
+
case "status":
|
|
5471
|
+
await mcpStatus();
|
|
5472
|
+
break;
|
|
5473
|
+
}
|
|
4834
5474
|
return;
|
|
4835
5475
|
}
|
|
4836
5476
|
if (parsed.mode === "app") {
|
|
@@ -4867,7 +5507,7 @@ Pipeline completed with ${errors.length} error(s)
|
|
|
4867
5507
|
return;
|
|
4868
5508
|
}
|
|
4869
5509
|
if (parsed.mode === "status") {
|
|
4870
|
-
const tools = ["supabase", "gh", "vercel"];
|
|
5510
|
+
const tools = ["supabase", "gh", "vercel", "git"];
|
|
4871
5511
|
process.stdout.write(pc5.bold("Tool Status\n\n"));
|
|
4872
5512
|
for (const toolId of tools) {
|
|
4873
5513
|
const info = getToolInfo(toolId);
|
|
@@ -4958,11 +5598,11 @@ Apply completed with ${errors.length} error(s).
|
|
|
4958
5598
|
process.exit(result.exitCode ?? 0);
|
|
4959
5599
|
}
|
|
4960
5600
|
const AppComponent2 = parsed.classic ? AppClassic : AppPanel;
|
|
4961
|
-
render(
|
|
5601
|
+
render(React20.createElement(AppComponent2));
|
|
4962
5602
|
return;
|
|
4963
5603
|
}
|
|
4964
5604
|
const AppComponent = parsed.classic ? AppClassic : AppPanel;
|
|
4965
|
-
render(
|
|
5605
|
+
render(React20.createElement(AppComponent));
|
|
4966
5606
|
}
|
|
4967
5607
|
main().catch((error) => {
|
|
4968
5608
|
const message = error instanceof Error ? error.message : String(error);
|