@polterware/polter 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api.js +1 -1
- package/dist/{chunk-TWWRDI3Q.js → chunk-2OZZNSKW.js} +48 -68
- package/dist/index.js +500 -194
- package/dist/mcp.js +129 -6
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -24,7 +24,7 @@ import {
|
|
|
24
24
|
runSupabaseCommand,
|
|
25
25
|
savePipeline,
|
|
26
26
|
writeProjectConfig
|
|
27
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-2OZZNSKW.js";
|
|
28
28
|
|
|
29
29
|
// src/index.tsx
|
|
30
30
|
import React19 from "react";
|
|
@@ -743,8 +743,8 @@ function buildHomeItems({
|
|
|
743
743
|
kind: "header",
|
|
744
744
|
selectable: false
|
|
745
745
|
});
|
|
746
|
-
const toolOrder = { supabase: 0, vercel: 1, gh: 2,
|
|
747
|
-
const toolIcons = { supabase: "\u{1F7E2}", vercel: "\u26AA", gh: "\u{1F535}",
|
|
746
|
+
const toolOrder = { supabase: 0, vercel: 1, gh: 2, git: 3 };
|
|
747
|
+
const toolIcons = { supabase: "\u{1F7E2}", vercel: "\u26AA", gh: "\u{1F535}", git: "\u{1F7E0}" };
|
|
748
748
|
const grouped = /* @__PURE__ */ new Map();
|
|
749
749
|
for (const cmd of activeFeature.commands) {
|
|
750
750
|
const existing = grouped.get(cmd.tool) ?? [];
|
|
@@ -997,13 +997,13 @@ var toolColors = {
|
|
|
997
997
|
supabase: "#3ECF8E",
|
|
998
998
|
gh: "#58A6FF",
|
|
999
999
|
vercel: "#FFFFFF",
|
|
1000
|
-
|
|
1000
|
+
git: "#F05032"
|
|
1001
1001
|
};
|
|
1002
1002
|
var toolLabels = {
|
|
1003
1003
|
supabase: "supabase",
|
|
1004
1004
|
gh: "github",
|
|
1005
1005
|
vercel: "vercel",
|
|
1006
|
-
|
|
1006
|
+
git: "git"
|
|
1007
1007
|
};
|
|
1008
1008
|
function ToolBadge({ tool }) {
|
|
1009
1009
|
return /* @__PURE__ */ jsx7(Text7, { color: toolColors[tool], dimColor: true, children: toolLabels[tool] });
|
|
@@ -1255,24 +1255,28 @@ function CustomCommand({
|
|
|
1255
1255
|
onNavigate,
|
|
1256
1256
|
onBack,
|
|
1257
1257
|
width = 80,
|
|
1258
|
+
height = 24,
|
|
1258
1259
|
panelMode = false,
|
|
1259
1260
|
isInputActive = true
|
|
1260
1261
|
}) {
|
|
1261
1262
|
const [phase, setPhase] = useState7("tool-select");
|
|
1262
1263
|
const [selectedTool, setSelectedTool] = useState7("supabase");
|
|
1263
1264
|
if (phase === "tool-select") {
|
|
1264
|
-
|
|
1265
|
+
const toolItems = [
|
|
1266
|
+
{ value: "__section__", label: "\u{1F6E0} Select Tool", kind: "header", selectable: false },
|
|
1267
|
+
{ value: "supabase", label: "Supabase CLI", hint: "supabase ...", kind: "action" },
|
|
1268
|
+
{ value: "gh", label: "GitHub CLI", hint: "gh ...", kind: "action" },
|
|
1269
|
+
{ value: "vercel", label: "Vercel CLI", hint: "vercel ...", kind: "action" },
|
|
1270
|
+
{ value: "git", label: "Git", hint: "git ...", kind: "action" },
|
|
1271
|
+
...!panelMode ? [{ value: "__back__", label: "\u2190 Back" }] : []
|
|
1272
|
+
];
|
|
1273
|
+
return /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", paddingX: panelMode ? 1 : 0, children: [
|
|
1265
1274
|
/* @__PURE__ */ jsx9(Box8, { marginBottom: 1, children: /* @__PURE__ */ jsx9(Text9, { bold: true, color: inkColors.accent, children: "\u270F\uFE0F Custom Command" }) }),
|
|
1266
|
-
/* @__PURE__ */ jsx9(Text9, { dimColor: true, children: "Select tool:" }),
|
|
1275
|
+
!panelMode && /* @__PURE__ */ jsx9(Text9, { dimColor: true, children: "Select tool:" }),
|
|
1267
1276
|
/* @__PURE__ */ jsx9(
|
|
1268
1277
|
SelectList,
|
|
1269
1278
|
{
|
|
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
|
-
],
|
|
1279
|
+
items: toolItems,
|
|
1276
1280
|
onSelect: (value) => {
|
|
1277
1281
|
if (value === "__back__") {
|
|
1278
1282
|
onBack();
|
|
@@ -1282,7 +1286,9 @@ function CustomCommand({
|
|
|
1282
1286
|
setPhase("input");
|
|
1283
1287
|
},
|
|
1284
1288
|
onCancel: onBack,
|
|
1285
|
-
|
|
1289
|
+
boxedSections: panelMode,
|
|
1290
|
+
width: panelMode ? Math.max(20, width - 4) : width,
|
|
1291
|
+
maxVisible: panelMode ? Math.max(6, height - 6) : void 0,
|
|
1286
1292
|
isInputActive,
|
|
1287
1293
|
arrowNavigation: panelMode
|
|
1288
1294
|
}
|
|
@@ -1290,7 +1296,7 @@ function CustomCommand({
|
|
|
1290
1296
|
!panelMode && /* @__PURE__ */ jsx9(StatusBar, { hint: "\u2191\u2193 navigate \xB7 Enter select \xB7 Esc back", width })
|
|
1291
1297
|
] });
|
|
1292
1298
|
}
|
|
1293
|
-
return /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", children: [
|
|
1299
|
+
return /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", paddingX: panelMode ? 1 : 0, children: [
|
|
1294
1300
|
/* @__PURE__ */ jsxs8(Box8, { marginBottom: 1, gap: 1, children: [
|
|
1295
1301
|
/* @__PURE__ */ jsx9(Text9, { bold: true, color: inkColors.accent, children: "\u270F\uFE0F Custom Command" }),
|
|
1296
1302
|
/* @__PURE__ */ jsxs8(Text9, { dimColor: true, children: [
|
|
@@ -1329,7 +1335,9 @@ import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
|
1329
1335
|
function FlagToggle({
|
|
1330
1336
|
flags,
|
|
1331
1337
|
onSubmit,
|
|
1332
|
-
onCancel
|
|
1338
|
+
onCancel,
|
|
1339
|
+
isInputActive = true,
|
|
1340
|
+
arrowNavigation = false
|
|
1333
1341
|
}) {
|
|
1334
1342
|
const [cursor, setCursor] = useState8(0);
|
|
1335
1343
|
const [selected, setSelected] = useState8(/* @__PURE__ */ new Set());
|
|
@@ -1358,7 +1366,10 @@ function FlagToggle({
|
|
|
1358
1366
|
if (key.escape && onCancel) {
|
|
1359
1367
|
onCancel();
|
|
1360
1368
|
}
|
|
1361
|
-
|
|
1369
|
+
if (arrowNavigation && key.leftArrow && onCancel) {
|
|
1370
|
+
onCancel();
|
|
1371
|
+
}
|
|
1372
|
+
}, { isActive: isInputActive });
|
|
1362
1373
|
return /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", children: [
|
|
1363
1374
|
/* @__PURE__ */ jsxs9(Box9, { marginBottom: 1, children: [
|
|
1364
1375
|
/* @__PURE__ */ jsx10(Text10, { bold: true, color: inkColors.accent, children: "\u2691 Global Flags" }),
|
|
@@ -1417,7 +1428,9 @@ function FlagSelection({
|
|
|
1417
1428
|
const finalArgs = selectedFlags.length > 0 ? [...args, ...selectedFlags] : args;
|
|
1418
1429
|
onNavigate("confirm-execute", { args: finalArgs, tool });
|
|
1419
1430
|
},
|
|
1420
|
-
onCancel: onBack
|
|
1431
|
+
onCancel: onBack,
|
|
1432
|
+
isInputActive,
|
|
1433
|
+
arrowNavigation: panelMode
|
|
1421
1434
|
}
|
|
1422
1435
|
),
|
|
1423
1436
|
!panelMode && /* @__PURE__ */ jsx11(StatusBar, { hint: "Space toggle \xB7 Enter confirm \xB7 Esc back", width })
|
|
@@ -1449,9 +1462,20 @@ import { jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
|
1449
1462
|
function ConfirmPrompt({
|
|
1450
1463
|
message,
|
|
1451
1464
|
defaultValue = true,
|
|
1452
|
-
onConfirm
|
|
1465
|
+
onConfirm,
|
|
1466
|
+
onCancel,
|
|
1467
|
+
isInputActive = true,
|
|
1468
|
+
arrowNavigation = false
|
|
1453
1469
|
}) {
|
|
1454
|
-
useInput5((input2) => {
|
|
1470
|
+
useInput5((input2, key) => {
|
|
1471
|
+
if (key.escape && onCancel) {
|
|
1472
|
+
onCancel();
|
|
1473
|
+
return;
|
|
1474
|
+
}
|
|
1475
|
+
if (arrowNavigation && key.leftArrow && onCancel) {
|
|
1476
|
+
onCancel();
|
|
1477
|
+
return;
|
|
1478
|
+
}
|
|
1455
1479
|
if (input2 === "y" || input2 === "Y") {
|
|
1456
1480
|
onConfirm(true);
|
|
1457
1481
|
} else if (input2 === "n" || input2 === "N") {
|
|
@@ -1459,7 +1483,7 @@ function ConfirmPrompt({
|
|
|
1459
1483
|
} else if (input2 === "\r") {
|
|
1460
1484
|
onConfirm(defaultValue);
|
|
1461
1485
|
}
|
|
1462
|
-
});
|
|
1486
|
+
}, { isActive: isInputActive });
|
|
1463
1487
|
return /* @__PURE__ */ jsxs12(Box11, { gap: 1, children: [
|
|
1464
1488
|
/* @__PURE__ */ jsx13(Text12, { color: inkColors.accent, bold: true, children: "?" }),
|
|
1465
1489
|
/* @__PURE__ */ jsx13(Text12, { children: message }),
|
|
@@ -1548,6 +1572,7 @@ function CommandExecution({
|
|
|
1548
1572
|
onBack,
|
|
1549
1573
|
onExit,
|
|
1550
1574
|
width = 80,
|
|
1575
|
+
height = 24,
|
|
1551
1576
|
panelMode = false,
|
|
1552
1577
|
isInputActive = true
|
|
1553
1578
|
}) {
|
|
@@ -1575,7 +1600,7 @@ function CommandExecution({
|
|
|
1575
1600
|
}
|
|
1576
1601
|
}, [phase, runCommand2, status]);
|
|
1577
1602
|
if (phase === "confirm") {
|
|
1578
|
-
return /* @__PURE__ */ jsx15(Box12, { flexDirection: "column", children: /* @__PURE__ */ jsx15(
|
|
1603
|
+
return /* @__PURE__ */ jsx15(Box12, { flexDirection: "column", paddingX: panelMode ? 1 : 0, children: /* @__PURE__ */ jsx15(
|
|
1579
1604
|
ConfirmPrompt,
|
|
1580
1605
|
{
|
|
1581
1606
|
message: `Execute ${cmdDisplay}?`,
|
|
@@ -1586,26 +1611,29 @@ function CommandExecution({
|
|
|
1586
1611
|
} else {
|
|
1587
1612
|
onBack();
|
|
1588
1613
|
}
|
|
1589
|
-
}
|
|
1614
|
+
},
|
|
1615
|
+
onCancel: onBack,
|
|
1616
|
+
isInputActive,
|
|
1617
|
+
arrowNavigation: panelMode
|
|
1590
1618
|
}
|
|
1591
1619
|
) });
|
|
1592
1620
|
}
|
|
1593
1621
|
if (phase === "running") {
|
|
1594
|
-
return /* @__PURE__ */ jsxs14(Box12, { flexDirection: "column", children: [
|
|
1595
|
-
/* @__PURE__ */ jsx15(Divider, { width }),
|
|
1622
|
+
return /* @__PURE__ */ jsxs14(Box12, { flexDirection: "column", paddingX: panelMode ? 1 : 0, children: [
|
|
1623
|
+
/* @__PURE__ */ jsx15(Divider, { width: panelMode ? width - 4 : width }),
|
|
1596
1624
|
/* @__PURE__ */ jsxs14(Box12, { marginY: 1, gap: 1, children: [
|
|
1597
1625
|
/* @__PURE__ */ jsx15(Text14, { color: inkColors.accent, bold: true, children: "\u25B6" }),
|
|
1598
1626
|
/* @__PURE__ */ jsx15(Text14, { dimColor: true, children: "Running:" }),
|
|
1599
1627
|
/* @__PURE__ */ jsx15(Text14, { children: cmdDisplay }),
|
|
1600
1628
|
/* @__PURE__ */ jsx15(ToolBadge, { tool })
|
|
1601
1629
|
] }),
|
|
1602
|
-
/* @__PURE__ */ jsx15(Divider, { width }),
|
|
1630
|
+
/* @__PURE__ */ jsx15(Divider, { width: panelMode ? width - 4 : width }),
|
|
1603
1631
|
/* @__PURE__ */ jsx15(Box12, { marginTop: 1, children: /* @__PURE__ */ jsx15(Spinner, { label: `Executing ${cmdDisplay}...` }) })
|
|
1604
1632
|
] });
|
|
1605
1633
|
}
|
|
1606
1634
|
if (phase === "success-pin-offer") {
|
|
1607
|
-
return /* @__PURE__ */ jsxs14(Box12, { flexDirection: "column", children: [
|
|
1608
|
-
/* @__PURE__ */ jsx15(Divider, { width }),
|
|
1635
|
+
return /* @__PURE__ */ jsxs14(Box12, { flexDirection: "column", paddingX: panelMode ? 1 : 0, children: [
|
|
1636
|
+
/* @__PURE__ */ jsx15(Divider, { width: panelMode ? width - 4 : width }),
|
|
1609
1637
|
/* @__PURE__ */ jsxs14(Box12, { marginY: 1, gap: 1, children: [
|
|
1610
1638
|
/* @__PURE__ */ jsx15(Text14, { color: inkColors.accent, bold: true, children: "\u2713" }),
|
|
1611
1639
|
/* @__PURE__ */ jsx15(Text14, { color: inkColors.accent, bold: true, children: "Command completed successfully!" })
|
|
@@ -1621,28 +1649,34 @@ function CommandExecution({
|
|
|
1621
1649
|
setPinMessage("Exact command pinned to Pinned Runs.");
|
|
1622
1650
|
}
|
|
1623
1651
|
setPhase("success");
|
|
1624
|
-
}
|
|
1652
|
+
},
|
|
1653
|
+
onCancel: () => setPhase("success"),
|
|
1654
|
+
isInputActive,
|
|
1655
|
+
arrowNavigation: panelMode
|
|
1625
1656
|
}
|
|
1626
1657
|
)
|
|
1627
1658
|
] });
|
|
1628
1659
|
}
|
|
1629
1660
|
if (phase === "success") {
|
|
1630
|
-
|
|
1631
|
-
|
|
1661
|
+
const successItems = panelMode ? [] : [{ value: "__back__", label: "\u2190 Back to menu" }];
|
|
1662
|
+
return /* @__PURE__ */ jsxs14(Box12, { flexDirection: "column", paddingX: panelMode ? 1 : 0, children: [
|
|
1663
|
+
/* @__PURE__ */ jsx15(Divider, { width: panelMode ? width - 4 : width }),
|
|
1632
1664
|
/* @__PURE__ */ jsxs14(Box12, { marginY: 1, gap: 1, children: [
|
|
1633
1665
|
/* @__PURE__ */ jsx15(Text14, { color: inkColors.accent, bold: true, children: "\u2713" }),
|
|
1634
1666
|
/* @__PURE__ */ jsx15(Text14, { color: inkColors.accent, bold: true, children: "Command completed successfully!" })
|
|
1635
1667
|
] }),
|
|
1636
1668
|
pinMessage && /* @__PURE__ */ jsx15(Box12, { marginBottom: 1, children: /* @__PURE__ */ jsx15(Text14, { color: inkColors.accent, children: pinMessage }) }),
|
|
1637
|
-
/* @__PURE__ */ jsx15(
|
|
1669
|
+
successItems.length > 0 && /* @__PURE__ */ jsx15(
|
|
1638
1670
|
SelectList,
|
|
1639
1671
|
{
|
|
1640
|
-
items:
|
|
1672
|
+
items: successItems,
|
|
1641
1673
|
onSelect: onBack,
|
|
1642
1674
|
onCancel: onBack,
|
|
1643
|
-
width,
|
|
1675
|
+
width: panelMode ? Math.max(20, width - 4) : width,
|
|
1676
|
+
maxVisible: panelMode ? Math.max(6, height - 6) : void 0,
|
|
1644
1677
|
isInputActive,
|
|
1645
|
-
arrowNavigation: panelMode
|
|
1678
|
+
arrowNavigation: panelMode,
|
|
1679
|
+
boxedSections: panelMode
|
|
1646
1680
|
}
|
|
1647
1681
|
)
|
|
1648
1682
|
] });
|
|
@@ -1659,16 +1693,16 @@ function CommandExecution({
|
|
|
1659
1693
|
});
|
|
1660
1694
|
}
|
|
1661
1695
|
}
|
|
1662
|
-
errorItems.push(
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
{ value: "menu", label: "\u2190 Return to main menu" }
|
|
1668
|
-
|
|
1669
|
-
);
|
|
1670
|
-
return /* @__PURE__ */ jsxs14(Box12, { flexDirection: "column", children: [
|
|
1671
|
-
/* @__PURE__ */ jsx15(Divider, { width }),
|
|
1696
|
+
errorItems.push({
|
|
1697
|
+
value: "copy",
|
|
1698
|
+
label: "\u{1F4CB} Copy command to clipboard"
|
|
1699
|
+
});
|
|
1700
|
+
if (!panelMode) {
|
|
1701
|
+
errorItems.push({ value: "menu", label: "\u2190 Return to main menu" });
|
|
1702
|
+
}
|
|
1703
|
+
errorItems.push({ value: "exit", label: "\u{1F6AA} Exit Polter" });
|
|
1704
|
+
return /* @__PURE__ */ jsxs14(Box12, { flexDirection: "column", paddingX: panelMode ? 1 : 0, children: [
|
|
1705
|
+
/* @__PURE__ */ jsx15(Divider, { width: panelMode ? width - 4 : width }),
|
|
1672
1706
|
result?.spawnError ? /* @__PURE__ */ jsxs14(Box12, { flexDirection: "column", marginY: 1, children: [
|
|
1673
1707
|
/* @__PURE__ */ jsxs14(Box12, { gap: 1, children: [
|
|
1674
1708
|
/* @__PURE__ */ jsx15(Text14, { color: "red", bold: true, children: "\u2717" }),
|
|
@@ -1733,7 +1767,9 @@ function CommandExecution({
|
|
|
1733
1767
|
}
|
|
1734
1768
|
},
|
|
1735
1769
|
onCancel: onBack,
|
|
1736
|
-
|
|
1770
|
+
boxedSections: panelMode,
|
|
1771
|
+
width: panelMode ? Math.max(20, width - 4) : width,
|
|
1772
|
+
maxVisible: panelMode ? Math.max(6, height - 6) : void 0,
|
|
1737
1773
|
isInputActive,
|
|
1738
1774
|
arrowNavigation: panelMode
|
|
1739
1775
|
}
|
|
@@ -1756,6 +1792,7 @@ function SelfUpdate({
|
|
|
1756
1792
|
onBack,
|
|
1757
1793
|
onExit,
|
|
1758
1794
|
width = 80,
|
|
1795
|
+
height = 24,
|
|
1759
1796
|
panelMode = false,
|
|
1760
1797
|
isInputActive = true
|
|
1761
1798
|
}) {
|
|
@@ -1784,24 +1821,28 @@ function SelfUpdate({
|
|
|
1784
1821
|
}
|
|
1785
1822
|
}, [phase, status]);
|
|
1786
1823
|
if (phase === "target") {
|
|
1787
|
-
|
|
1824
|
+
const targetItems = [
|
|
1825
|
+
{ value: "__section__", label: "\u{1F4E6} Update Target", kind: "header", selectable: false },
|
|
1826
|
+
{
|
|
1827
|
+
value: "repository",
|
|
1828
|
+
label: "Current repository",
|
|
1829
|
+
hint: "Pin the latest version in package.json",
|
|
1830
|
+
kind: "action"
|
|
1831
|
+
},
|
|
1832
|
+
{
|
|
1833
|
+
value: "global",
|
|
1834
|
+
label: "Global install",
|
|
1835
|
+
hint: "Update the shared version available in PATH",
|
|
1836
|
+
kind: "action"
|
|
1837
|
+
},
|
|
1838
|
+
...!panelMode ? [{ value: "back", label: "\u2190 Back to menu" }] : []
|
|
1839
|
+
];
|
|
1840
|
+
return /* @__PURE__ */ jsxs15(Box13, { flexDirection: "column", paddingX: panelMode ? 1 : 0, children: [
|
|
1788
1841
|
/* @__PURE__ */ jsx16(Box13, { marginBottom: 1, children: /* @__PURE__ */ jsx16(Text15, { bold: true, children: "Choose where to update Polter." }) }),
|
|
1789
1842
|
/* @__PURE__ */ jsx16(
|
|
1790
1843
|
SelectList,
|
|
1791
1844
|
{
|
|
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
|
-
],
|
|
1845
|
+
items: targetItems,
|
|
1805
1846
|
onSelect: (value) => {
|
|
1806
1847
|
if (value === "back") {
|
|
1807
1848
|
onBack();
|
|
@@ -1812,7 +1853,9 @@ function SelfUpdate({
|
|
|
1812
1853
|
setPhase("confirm");
|
|
1813
1854
|
},
|
|
1814
1855
|
onCancel: onBack,
|
|
1815
|
-
|
|
1856
|
+
boxedSections: panelMode,
|
|
1857
|
+
width: panelMode ? Math.max(20, width - 4) : width,
|
|
1858
|
+
maxVisible: panelMode ? Math.max(6, height - 6) : void 0,
|
|
1816
1859
|
isInputActive,
|
|
1817
1860
|
arrowNavigation: panelMode
|
|
1818
1861
|
}
|
|
@@ -1824,7 +1867,7 @@ function SelfUpdate({
|
|
|
1824
1867
|
] });
|
|
1825
1868
|
}
|
|
1826
1869
|
if (phase === "confirm") {
|
|
1827
|
-
return /* @__PURE__ */ jsxs15(Box13, { flexDirection: "column", children: [
|
|
1870
|
+
return /* @__PURE__ */ jsxs15(Box13, { flexDirection: "column", paddingX: panelMode ? 1 : 0, children: [
|
|
1828
1871
|
/* @__PURE__ */ jsx16(
|
|
1829
1872
|
ConfirmPrompt,
|
|
1830
1873
|
{
|
|
@@ -1841,7 +1884,16 @@ function SelfUpdate({
|
|
|
1841
1884
|
return;
|
|
1842
1885
|
}
|
|
1843
1886
|
onBack();
|
|
1844
|
-
}
|
|
1887
|
+
},
|
|
1888
|
+
onCancel: () => {
|
|
1889
|
+
if (repositoryRoot) {
|
|
1890
|
+
setPhase("target");
|
|
1891
|
+
} else {
|
|
1892
|
+
onBack();
|
|
1893
|
+
}
|
|
1894
|
+
},
|
|
1895
|
+
isInputActive,
|
|
1896
|
+
arrowNavigation: panelMode
|
|
1845
1897
|
}
|
|
1846
1898
|
),
|
|
1847
1899
|
/* @__PURE__ */ jsxs15(Box13, { marginTop: 1, marginLeft: 2, flexDirection: "column", children: [
|
|
@@ -1854,20 +1906,25 @@ function SelfUpdate({
|
|
|
1854
1906
|
] });
|
|
1855
1907
|
}
|
|
1856
1908
|
if (phase === "running") {
|
|
1857
|
-
return /* @__PURE__ */ jsxs15(Box13, { flexDirection: "column", children: [
|
|
1858
|
-
/* @__PURE__ */ jsx16(Divider, { width }),
|
|
1909
|
+
return /* @__PURE__ */ jsxs15(Box13, { flexDirection: "column", paddingX: panelMode ? 1 : 0, children: [
|
|
1910
|
+
/* @__PURE__ */ jsx16(Divider, { width: panelMode ? width - 4 : width }),
|
|
1859
1911
|
/* @__PURE__ */ jsxs15(Box13, { marginY: 1, gap: 1, children: [
|
|
1860
1912
|
/* @__PURE__ */ jsx16(Text15, { color: inkColors.accent, bold: true, children: "\u25B6" }),
|
|
1861
1913
|
/* @__PURE__ */ jsx16(Text15, { dimColor: true, children: "Running:" }),
|
|
1862
1914
|
/* @__PURE__ */ jsx16(Text15, { children: updateDisplay })
|
|
1863
1915
|
] }),
|
|
1864
|
-
/* @__PURE__ */ jsx16(Divider, { width }),
|
|
1916
|
+
/* @__PURE__ */ jsx16(Divider, { width: panelMode ? width - 4 : width }),
|
|
1865
1917
|
/* @__PURE__ */ jsx16(Box13, { marginTop: 1, children: /* @__PURE__ */ jsx16(Spinner, { label: "Updating Polter..." }) })
|
|
1866
1918
|
] });
|
|
1867
1919
|
}
|
|
1868
1920
|
if (phase === "success") {
|
|
1869
|
-
|
|
1870
|
-
|
|
1921
|
+
const successItems = [
|
|
1922
|
+
{ value: "__section__", label: "\u2705 Update Complete", kind: "header", selectable: false },
|
|
1923
|
+
...!panelMode ? [{ value: "__back__", label: "\u2190 Back to menu", kind: "action" }] : [],
|
|
1924
|
+
{ value: "__exit__", label: "\u{1F6AA} Exit Polter", kind: "action" }
|
|
1925
|
+
];
|
|
1926
|
+
return /* @__PURE__ */ jsxs15(Box13, { flexDirection: "column", paddingX: panelMode ? 1 : 0, children: [
|
|
1927
|
+
/* @__PURE__ */ jsx16(Divider, { width: panelMode ? width - 4 : width }),
|
|
1871
1928
|
/* @__PURE__ */ jsxs15(Box13, { marginY: 1, gap: 1, children: [
|
|
1872
1929
|
/* @__PURE__ */ jsx16(Text15, { color: inkColors.accent, bold: true, children: "\u2713" }),
|
|
1873
1930
|
/* @__PURE__ */ jsx16(Text15, { color: inkColors.accent, bold: true, children: "Update completed successfully!" })
|
|
@@ -1882,10 +1939,7 @@ function SelfUpdate({
|
|
|
1882
1939
|
/* @__PURE__ */ jsx16(
|
|
1883
1940
|
SelectList,
|
|
1884
1941
|
{
|
|
1885
|
-
items:
|
|
1886
|
-
{ value: "__back__", label: "\u2190 Back to menu" },
|
|
1887
|
-
{ value: "__exit__", label: "\u{1F6AA} Exit Polter" }
|
|
1888
|
-
],
|
|
1942
|
+
items: successItems,
|
|
1889
1943
|
onSelect: (value) => {
|
|
1890
1944
|
if (value === "__exit__") {
|
|
1891
1945
|
onExit();
|
|
@@ -1894,15 +1948,24 @@ function SelfUpdate({
|
|
|
1894
1948
|
onBack();
|
|
1895
1949
|
},
|
|
1896
1950
|
onCancel: onBack,
|
|
1897
|
-
|
|
1951
|
+
boxedSections: panelMode,
|
|
1952
|
+
width: panelMode ? Math.max(20, width - 4) : width,
|
|
1953
|
+
maxVisible: panelMode ? Math.max(6, height - 6) : void 0,
|
|
1898
1954
|
isInputActive,
|
|
1899
1955
|
arrowNavigation: panelMode
|
|
1900
1956
|
}
|
|
1901
1957
|
)
|
|
1902
1958
|
] });
|
|
1903
1959
|
}
|
|
1904
|
-
|
|
1905
|
-
|
|
1960
|
+
const errorItems = [
|
|
1961
|
+
{ value: "__section__", label: "\u{1F527} Recovery Options", kind: "header", selectable: false },
|
|
1962
|
+
{ value: "retry", label: "\u{1F504} Retry update", kind: "action" },
|
|
1963
|
+
...repositoryRoot ? [{ value: "target", label: "\u2194 Choose update target", kind: "action" }] : [],
|
|
1964
|
+
...!panelMode ? [{ value: "menu", label: "\u2190 Return to main menu", kind: "action" }] : [],
|
|
1965
|
+
{ value: "exit", label: "\u{1F6AA} Exit Polter", kind: "action" }
|
|
1966
|
+
];
|
|
1967
|
+
return /* @__PURE__ */ jsxs15(Box13, { flexDirection: "column", paddingX: panelMode ? 1 : 0, children: [
|
|
1968
|
+
/* @__PURE__ */ jsx16(Divider, { width: panelMode ? width - 4 : width }),
|
|
1906
1969
|
result?.spawnError ? /* @__PURE__ */ jsxs15(Box13, { flexDirection: "column", marginY: 1, children: [
|
|
1907
1970
|
/* @__PURE__ */ jsxs15(Box13, { gap: 1, children: [
|
|
1908
1971
|
/* @__PURE__ */ jsx16(Text15, { color: "red", bold: true, children: "\u2717" }),
|
|
@@ -1933,16 +1996,11 @@ function SelfUpdate({
|
|
|
1933
1996
|
repositoryRoot
|
|
1934
1997
|
] })
|
|
1935
1998
|
] }),
|
|
1936
|
-
/* @__PURE__ */ jsx16(Box13, { marginTop: 1, marginBottom: 1, children: /* @__PURE__ */ jsx16(Text15, { bold: true, children: "What would you like to do?" }) }),
|
|
1999
|
+
!panelMode && /* @__PURE__ */ jsx16(Box13, { marginTop: 1, marginBottom: 1, children: /* @__PURE__ */ jsx16(Text15, { bold: true, children: "What would you like to do?" }) }),
|
|
1937
2000
|
/* @__PURE__ */ jsx16(
|
|
1938
2001
|
SelectList,
|
|
1939
2002
|
{
|
|
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
|
-
],
|
|
2003
|
+
items: errorItems,
|
|
1946
2004
|
onSelect: (value) => {
|
|
1947
2005
|
switch (value) {
|
|
1948
2006
|
case "retry":
|
|
@@ -1962,7 +2020,9 @@ function SelfUpdate({
|
|
|
1962
2020
|
}
|
|
1963
2021
|
},
|
|
1964
2022
|
onCancel: onBack,
|
|
1965
|
-
|
|
2023
|
+
boxedSections: panelMode,
|
|
2024
|
+
width: panelMode ? Math.max(20, width - 4) : width,
|
|
2025
|
+
maxVisible: panelMode ? Math.max(6, height - 6) : void 0,
|
|
1966
2026
|
isInputActive,
|
|
1967
2027
|
arrowNavigation: panelMode
|
|
1968
2028
|
}
|
|
@@ -1975,9 +2035,19 @@ function SelfUpdate({
|
|
|
1975
2035
|
import { useMemo as useMemo4 } from "react";
|
|
1976
2036
|
import { Box as Box14, Text as Text16 } from "ink";
|
|
1977
2037
|
import { jsx as jsx17, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
1978
|
-
var toolIds = ["supabase", "gh", "vercel", "
|
|
1979
|
-
function ToolStatus({ onBack, width = 80, panelMode = false, isInputActive = true }) {
|
|
2038
|
+
var toolIds = ["supabase", "gh", "vercel", "git"];
|
|
2039
|
+
function ToolStatus({ onBack, width = 80, height = 24, panelMode = false, isInputActive = true }) {
|
|
1980
2040
|
const tools = useMemo4(() => toolIds.map(getToolInfo), []);
|
|
2041
|
+
if (panelMode) {
|
|
2042
|
+
return /* @__PURE__ */ jsxs16(Box14, { flexDirection: "column", paddingX: 1, children: [
|
|
2043
|
+
/* @__PURE__ */ jsx17(Box14, { marginBottom: 1, children: /* @__PURE__ */ jsx17(Text16, { bold: true, color: inkColors.accent, children: "\u{1F527} Tool Status" }) }),
|
|
2044
|
+
tools.map((tool) => /* @__PURE__ */ jsxs16(Box14, { gap: 1, marginLeft: 2, children: [
|
|
2045
|
+
/* @__PURE__ */ jsx17(Text16, { color: tool.installed ? inkColors.accent : "red", children: tool.installed ? "\u2713" : "\u2717" }),
|
|
2046
|
+
/* @__PURE__ */ jsx17(Box14, { width: 16, children: /* @__PURE__ */ jsx17(Text16, { bold: true, children: tool.label }) }),
|
|
2047
|
+
/* @__PURE__ */ jsx17(Text16, { dimColor: true, children: tool.installed ? tool.version ?? "installed" : "not found" })
|
|
2048
|
+
] }, tool.id))
|
|
2049
|
+
] });
|
|
2050
|
+
}
|
|
1981
2051
|
return /* @__PURE__ */ jsxs16(Box14, { flexDirection: "column", children: [
|
|
1982
2052
|
/* @__PURE__ */ jsx17(Box14, { marginBottom: 1, children: /* @__PURE__ */ jsx17(Text16, { bold: true, color: inkColors.accent, children: "\u{1F527} Tool Status" }) }),
|
|
1983
2053
|
tools.map((tool) => /* @__PURE__ */ jsxs16(Box14, { gap: 1, marginLeft: 2, children: [
|
|
@@ -1992,11 +2062,10 @@ function ToolStatus({ onBack, width = 80, panelMode = false, isInputActive = tru
|
|
|
1992
2062
|
onSelect: onBack,
|
|
1993
2063
|
onCancel: onBack,
|
|
1994
2064
|
width,
|
|
1995
|
-
isInputActive
|
|
1996
|
-
arrowNavigation: panelMode
|
|
2065
|
+
isInputActive
|
|
1997
2066
|
}
|
|
1998
2067
|
) }),
|
|
1999
|
-
|
|
2068
|
+
/* @__PURE__ */ jsx17(StatusBar, { hint: "Enter to go back", width })
|
|
2000
2069
|
] });
|
|
2001
2070
|
}
|
|
2002
2071
|
|
|
@@ -2081,6 +2150,7 @@ import { jsx as jsx18, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
|
2081
2150
|
function ProjectConfig({
|
|
2082
2151
|
onBack,
|
|
2083
2152
|
width = 80,
|
|
2153
|
+
height = 24,
|
|
2084
2154
|
panelMode = false,
|
|
2085
2155
|
isInputActive = true
|
|
2086
2156
|
}) {
|
|
@@ -2090,23 +2160,22 @@ function ProjectConfig({
|
|
|
2090
2160
|
const [feedback, setFeedback] = useState13();
|
|
2091
2161
|
const { openEditor, isEditing } = useEditor();
|
|
2092
2162
|
if (!configPath) {
|
|
2093
|
-
return /* @__PURE__ */ jsxs17(Box15, { flexDirection: "column", children: [
|
|
2163
|
+
return /* @__PURE__ */ jsxs17(Box15, { flexDirection: "column", paddingX: panelMode ? 1 : 0, children: [
|
|
2094
2164
|
/* @__PURE__ */ jsx18(Text17, { color: "red", children: "No package.json found. Run from a project directory." }),
|
|
2095
|
-
/* @__PURE__ */ jsx18(
|
|
2165
|
+
!panelMode && /* @__PURE__ */ jsx18(
|
|
2096
2166
|
SelectList,
|
|
2097
2167
|
{
|
|
2098
2168
|
items: [{ value: "__back__", label: "\u2190 Back" }],
|
|
2099
2169
|
onSelect: onBack,
|
|
2100
2170
|
onCancel: onBack,
|
|
2101
2171
|
width,
|
|
2102
|
-
isInputActive
|
|
2103
|
-
arrowNavigation: panelMode
|
|
2172
|
+
isInputActive
|
|
2104
2173
|
}
|
|
2105
2174
|
)
|
|
2106
2175
|
] });
|
|
2107
2176
|
}
|
|
2108
2177
|
if (phase === "edit-supabase-ref") {
|
|
2109
|
-
return /* @__PURE__ */ jsx18(Box15, { flexDirection: "column", children: /* @__PURE__ */ jsx18(
|
|
2178
|
+
return /* @__PURE__ */ jsx18(Box15, { flexDirection: "column", paddingX: panelMode ? 1 : 0, children: /* @__PURE__ */ jsx18(
|
|
2110
2179
|
TextPrompt,
|
|
2111
2180
|
{
|
|
2112
2181
|
label: "Supabase project ref:",
|
|
@@ -2129,7 +2198,7 @@ function ProjectConfig({
|
|
|
2129
2198
|
) });
|
|
2130
2199
|
}
|
|
2131
2200
|
if (phase === "edit-vercel-id") {
|
|
2132
|
-
return /* @__PURE__ */ jsx18(Box15, { flexDirection: "column", children: /* @__PURE__ */ jsx18(
|
|
2201
|
+
return /* @__PURE__ */ jsx18(Box15, { flexDirection: "column", paddingX: panelMode ? 1 : 0, children: /* @__PURE__ */ jsx18(
|
|
2133
2202
|
TextPrompt,
|
|
2134
2203
|
{
|
|
2135
2204
|
label: "Vercel project ID:",
|
|
@@ -2152,7 +2221,7 @@ function ProjectConfig({
|
|
|
2152
2221
|
) });
|
|
2153
2222
|
}
|
|
2154
2223
|
if (phase === "edit-gh-repo") {
|
|
2155
|
-
return /* @__PURE__ */ jsx18(Box15, { flexDirection: "column", children: /* @__PURE__ */ jsx18(
|
|
2224
|
+
return /* @__PURE__ */ jsx18(Box15, { flexDirection: "column", paddingX: panelMode ? 1 : 0, children: /* @__PURE__ */ jsx18(
|
|
2156
2225
|
TextPrompt,
|
|
2157
2226
|
{
|
|
2158
2227
|
label: "GitHub repo (owner/name):",
|
|
@@ -2174,6 +2243,77 @@ function ProjectConfig({
|
|
|
2174
2243
|
}
|
|
2175
2244
|
) });
|
|
2176
2245
|
}
|
|
2246
|
+
const configItems = [
|
|
2247
|
+
{ value: "__section_current__", label: "\u{1F4CB} Current Values", kind: "header", selectable: false },
|
|
2248
|
+
{ value: "__info_supabase__", label: `Supabase ref: ${config2.tools.supabase?.projectRef ?? "not set"}`, kind: "header", selectable: false },
|
|
2249
|
+
{ value: "__info_vercel__", label: `Vercel ID: ${config2.tools.vercel?.projectId ?? "not set"}`, kind: "header", selectable: false },
|
|
2250
|
+
{ value: "__info_gh__", label: `GitHub repo: ${config2.tools.gh?.repo ?? "not set"}`, kind: "header", selectable: false },
|
|
2251
|
+
{ value: "__section_actions__", label: "\u26A1 Actions", kind: "header", selectable: false },
|
|
2252
|
+
{ value: "supabase", label: "Set Supabase project ref", kind: "action" },
|
|
2253
|
+
{ value: "vercel", label: "Set Vercel project ID", kind: "action" },
|
|
2254
|
+
{ value: "gh", label: "Set GitHub repo", kind: "action" },
|
|
2255
|
+
{ value: "editor", label: "Open config in editor", kind: "action" },
|
|
2256
|
+
...!panelMode ? [{ value: "__back__", label: "\u2190 Back" }] : []
|
|
2257
|
+
];
|
|
2258
|
+
const flatItems = [
|
|
2259
|
+
{ value: "supabase", label: "Set Supabase project ref" },
|
|
2260
|
+
{ value: "vercel", label: "Set Vercel project ID" },
|
|
2261
|
+
{ value: "gh", label: "Set GitHub repo" },
|
|
2262
|
+
{ value: "editor", label: "Open config in editor" },
|
|
2263
|
+
...!panelMode ? [{ value: "__back__", label: "\u2190 Back" }] : []
|
|
2264
|
+
];
|
|
2265
|
+
const handleSelect = (value) => {
|
|
2266
|
+
switch (value) {
|
|
2267
|
+
case "supabase":
|
|
2268
|
+
setPhase("edit-supabase-ref");
|
|
2269
|
+
break;
|
|
2270
|
+
case "vercel":
|
|
2271
|
+
setPhase("edit-vercel-id");
|
|
2272
|
+
break;
|
|
2273
|
+
case "gh":
|
|
2274
|
+
setPhase("edit-gh-repo");
|
|
2275
|
+
break;
|
|
2276
|
+
case "editor":
|
|
2277
|
+
openEditor(configPath.file).then(() => {
|
|
2278
|
+
try {
|
|
2279
|
+
const reloaded = getOrCreateProjectConfig();
|
|
2280
|
+
setConfig(reloaded);
|
|
2281
|
+
setFeedback("Config reloaded from file");
|
|
2282
|
+
} catch {
|
|
2283
|
+
setFeedback("Warning: could not parse config after editing");
|
|
2284
|
+
}
|
|
2285
|
+
});
|
|
2286
|
+
break;
|
|
2287
|
+
default:
|
|
2288
|
+
onBack();
|
|
2289
|
+
}
|
|
2290
|
+
};
|
|
2291
|
+
if (panelMode) {
|
|
2292
|
+
return /* @__PURE__ */ jsxs17(Box15, { flexDirection: "column", paddingX: 1, children: [
|
|
2293
|
+
/* @__PURE__ */ jsx18(Box15, { marginBottom: 1, children: /* @__PURE__ */ jsx18(Text17, { bold: true, color: inkColors.accent, children: "\u2699\uFE0F Project Config" }) }),
|
|
2294
|
+
/* @__PURE__ */ jsx18(Box15, { marginBottom: 1, marginLeft: 2, children: /* @__PURE__ */ jsxs17(Text17, { dimColor: true, children: [
|
|
2295
|
+
"Path: ",
|
|
2296
|
+
configPath.file
|
|
2297
|
+
] }) }),
|
|
2298
|
+
feedback && /* @__PURE__ */ jsx18(Box15, { marginBottom: 1, children: /* @__PURE__ */ jsxs17(Text17, { color: inkColors.accent, children: [
|
|
2299
|
+
"\u2713 ",
|
|
2300
|
+
feedback
|
|
2301
|
+
] }) }),
|
|
2302
|
+
/* @__PURE__ */ jsx18(
|
|
2303
|
+
SelectList,
|
|
2304
|
+
{
|
|
2305
|
+
items: configItems,
|
|
2306
|
+
onSelect: handleSelect,
|
|
2307
|
+
onCancel: onBack,
|
|
2308
|
+
boxedSections: true,
|
|
2309
|
+
width: Math.max(20, width - 4),
|
|
2310
|
+
maxVisible: Math.max(6, height - 6),
|
|
2311
|
+
isInputActive,
|
|
2312
|
+
arrowNavigation: true
|
|
2313
|
+
}
|
|
2314
|
+
)
|
|
2315
|
+
] });
|
|
2316
|
+
}
|
|
2177
2317
|
return /* @__PURE__ */ jsxs17(Box15, { flexDirection: "column", children: [
|
|
2178
2318
|
/* @__PURE__ */ jsx18(Box15, { marginBottom: 1, children: /* @__PURE__ */ jsx18(Text17, { bold: true, color: inkColors.accent, children: "\u2699\uFE0F Project Config" }) }),
|
|
2179
2319
|
/* @__PURE__ */ jsxs17(Box15, { marginBottom: 1, marginLeft: 2, flexDirection: "column", children: [
|
|
@@ -2201,46 +2341,15 @@ function ProjectConfig({
|
|
|
2201
2341
|
/* @__PURE__ */ jsx18(
|
|
2202
2342
|
SelectList,
|
|
2203
2343
|
{
|
|
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
|
-
},
|
|
2344
|
+
items: flatItems,
|
|
2345
|
+
onSelect: handleSelect,
|
|
2237
2346
|
onCancel: onBack,
|
|
2238
2347
|
width,
|
|
2239
2348
|
isInputActive,
|
|
2240
2349
|
arrowNavigation: panelMode
|
|
2241
2350
|
}
|
|
2242
2351
|
),
|
|
2243
|
-
|
|
2352
|
+
/* @__PURE__ */ jsx18(StatusBar, { hint: "\u2191\u2193 navigate \xB7 Enter select \xB7 Esc back", width })
|
|
2244
2353
|
] });
|
|
2245
2354
|
}
|
|
2246
2355
|
|
|
@@ -2252,6 +2361,7 @@ function PipelineList({
|
|
|
2252
2361
|
onNavigate,
|
|
2253
2362
|
onBack,
|
|
2254
2363
|
width = 80,
|
|
2364
|
+
height = 24,
|
|
2255
2365
|
panelMode = false,
|
|
2256
2366
|
isInputActive = true
|
|
2257
2367
|
}) {
|
|
@@ -2299,15 +2409,17 @@ function PipelineList({
|
|
|
2299
2409
|
icon: "\u2795",
|
|
2300
2410
|
kind: "action"
|
|
2301
2411
|
});
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2412
|
+
if (!panelMode) {
|
|
2413
|
+
list.push({
|
|
2414
|
+
id: "action-back",
|
|
2415
|
+
value: "__back__",
|
|
2416
|
+
label: "\u2190 Back",
|
|
2417
|
+
kind: "action"
|
|
2418
|
+
});
|
|
2419
|
+
}
|
|
2308
2420
|
return list;
|
|
2309
|
-
}, [pipelines]);
|
|
2310
|
-
return /* @__PURE__ */ jsxs18(Box16, { flexDirection: "column", children: [
|
|
2421
|
+
}, [pipelines, panelMode]);
|
|
2422
|
+
return /* @__PURE__ */ jsxs18(Box16, { flexDirection: "column", paddingX: panelMode ? 1 : 0, children: [
|
|
2311
2423
|
/* @__PURE__ */ jsx19(Box16, { marginBottom: 1, children: /* @__PURE__ */ jsx19(Text18, { bold: true, color: inkColors.accent, children: "\u{1F517} Pipelines" }) }),
|
|
2312
2424
|
/* @__PURE__ */ jsx19(
|
|
2313
2425
|
SelectList,
|
|
@@ -2325,7 +2437,9 @@ function PipelineList({
|
|
|
2325
2437
|
onNavigate("pipeline-execution", { pipelineId: value });
|
|
2326
2438
|
},
|
|
2327
2439
|
onCancel: onBack,
|
|
2328
|
-
|
|
2440
|
+
boxedSections: panelMode,
|
|
2441
|
+
width: panelMode ? Math.max(20, width - 4) : width,
|
|
2442
|
+
maxVisible: panelMode ? Math.max(6, height - 6) : void 0,
|
|
2329
2443
|
isInputActive,
|
|
2330
2444
|
arrowNavigation: panelMode
|
|
2331
2445
|
}
|
|
@@ -2952,30 +3066,30 @@ function usePanelFocus() {
|
|
|
2952
3066
|
|
|
2953
3067
|
// src/hooks/useSidebarItems.ts
|
|
2954
3068
|
import { useMemo as useMemo8 } from "react";
|
|
2955
|
-
function useSidebarItems(
|
|
3069
|
+
function useSidebarItems() {
|
|
2956
3070
|
return useMemo8(() => {
|
|
2957
3071
|
const items = [];
|
|
2958
|
-
|
|
2959
|
-
|
|
2960
|
-
|
|
2961
|
-
}
|
|
3072
|
+
items.push({ id: "__sep_workflows__", label: "---", icon: "", type: "separator", sectionTitle: "Workflows" });
|
|
3073
|
+
items.push({ id: "pipelines", label: "Pipelines", icon: "\u{1F517}", type: "action", section: "workflows" });
|
|
3074
|
+
items.push({ id: "pinned", label: "Pinned", icon: "\u{1F4CC}", type: "action", section: "workflows" });
|
|
3075
|
+
items.push({ id: "custom-command", label: "Custom Cmd", icon: "\u270F\uFE0F", type: "action", section: "workflows" });
|
|
3076
|
+
items.push({ id: "__sep_features__", label: "---", icon: "", type: "separator", sectionTitle: "Features" });
|
|
2962
3077
|
for (const feature of features) {
|
|
2963
3078
|
items.push({
|
|
2964
3079
|
id: feature.id,
|
|
2965
3080
|
label: feature.label,
|
|
2966
3081
|
icon: feature.icon,
|
|
2967
|
-
type: "feature"
|
|
3082
|
+
type: "feature",
|
|
3083
|
+
section: "features"
|
|
2968
3084
|
});
|
|
2969
3085
|
}
|
|
2970
|
-
items.push({ id: "
|
|
2971
|
-
items.push({ id: "
|
|
2972
|
-
items.push({ id: "
|
|
2973
|
-
items.push({ id: "
|
|
2974
|
-
items.push({ id: "
|
|
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" });
|
|
3086
|
+
items.push({ id: "__sep_system__", label: "---", icon: "", type: "separator", sectionTitle: "System" });
|
|
3087
|
+
items.push({ id: "tool-status", label: "Tool Status", icon: "\u{1F527}", type: "action", section: "system" });
|
|
3088
|
+
items.push({ id: "config", label: "Config", icon: "\u2699\uFE0F", type: "action", section: "system" });
|
|
3089
|
+
items.push({ id: "self-update", label: "Update", icon: "\u2B06\uFE0F", type: "action", section: "system" });
|
|
3090
|
+
items.push({ id: "exit", label: "Exit", icon: "\u{1F6AA}", type: "action", section: "system" });
|
|
2977
3091
|
return items;
|
|
2978
|
-
}, [
|
|
3092
|
+
}, []);
|
|
2979
3093
|
}
|
|
2980
3094
|
|
|
2981
3095
|
// src/hooks/useModal.ts
|
|
@@ -3061,6 +3175,19 @@ function Panel({
|
|
|
3061
3175
|
import { useEffect as useEffect9, useMemo as useMemo9, useState as useState19 } from "react";
|
|
3062
3176
|
import { Box as Box24, Text as Text25, useInput as useInput6 } from "ink";
|
|
3063
3177
|
import { jsx as jsx26, jsxs as jsxs26 } from "react/jsx-runtime";
|
|
3178
|
+
function groupSections(items) {
|
|
3179
|
+
const groups = [];
|
|
3180
|
+
let current = null;
|
|
3181
|
+
for (const item of items) {
|
|
3182
|
+
if (item.type === "separator" && item.sectionTitle) {
|
|
3183
|
+
current = { title: item.sectionTitle, items: [] };
|
|
3184
|
+
groups.push(current);
|
|
3185
|
+
} else if (current) {
|
|
3186
|
+
current.items.push(item);
|
|
3187
|
+
}
|
|
3188
|
+
}
|
|
3189
|
+
return groups;
|
|
3190
|
+
}
|
|
3064
3191
|
function Sidebar({
|
|
3065
3192
|
items,
|
|
3066
3193
|
selectedId,
|
|
@@ -3075,6 +3202,7 @@ function Sidebar({
|
|
|
3075
3202
|
);
|
|
3076
3203
|
const selectedIdx = selectableItems.findIndex((item) => item.id === selectedId);
|
|
3077
3204
|
const [cursorIdx, setCursorIdx] = useState19(Math.max(0, selectedIdx));
|
|
3205
|
+
const sections = useMemo9(() => groupSections(items), [items]);
|
|
3078
3206
|
useEffect9(() => {
|
|
3079
3207
|
const idx = selectableItems.findIndex((item) => item.id === selectedId);
|
|
3080
3208
|
if (idx >= 0) setCursorIdx(idx);
|
|
@@ -3106,29 +3234,47 @@ function Sidebar({
|
|
|
3106
3234
|
},
|
|
3107
3235
|
{ isActive: isFocused }
|
|
3108
3236
|
);
|
|
3109
|
-
let
|
|
3110
|
-
return /* @__PURE__ */ jsx26(Box24, { flexDirection: "column",
|
|
3111
|
-
|
|
3112
|
-
|
|
3113
|
-
|
|
3114
|
-
const
|
|
3115
|
-
|
|
3116
|
-
const
|
|
3117
|
-
|
|
3118
|
-
return /* @__PURE__ */ jsx26(Box24, { gap: 0, children: /* @__PURE__ */ jsxs26(
|
|
3119
|
-
Text25,
|
|
3237
|
+
let flatIdx = 0;
|
|
3238
|
+
return /* @__PURE__ */ jsx26(Box24, { flexDirection: "column", gap: 2, children: sections.map((section) => {
|
|
3239
|
+
const sectionStartIdx = flatIdx;
|
|
3240
|
+
const sectionEndIdx = sectionStartIdx + section.items.length - 1;
|
|
3241
|
+
const hasCursorInSection = isFocused && cursorIdx >= sectionStartIdx && cursorIdx <= sectionEndIdx;
|
|
3242
|
+
const hasActiveInSection = section.items.some((item) => item.id === selectedId);
|
|
3243
|
+
const borderColor = hasCursorInSection || hasActiveInSection ? inkColors.accent : "#555555";
|
|
3244
|
+
const rendered = /* @__PURE__ */ jsxs26(
|
|
3245
|
+
Box24,
|
|
3120
3246
|
{
|
|
3121
|
-
|
|
3122
|
-
|
|
3123
|
-
|
|
3247
|
+
flexDirection: "column",
|
|
3248
|
+
borderStyle: "round",
|
|
3249
|
+
borderColor,
|
|
3250
|
+
paddingX: 1,
|
|
3124
3251
|
children: [
|
|
3125
|
-
|
|
3126
|
-
item
|
|
3127
|
-
|
|
3128
|
-
|
|
3252
|
+
/* @__PURE__ */ jsx26(Text25, { dimColor: true, bold: true, children: section.title }),
|
|
3253
|
+
section.items.map((item) => {
|
|
3254
|
+
const thisIdx = flatIdx;
|
|
3255
|
+
flatIdx++;
|
|
3256
|
+
const isCursor = isFocused && thisIdx === cursorIdx;
|
|
3257
|
+
const isActive = item.id === selectedId;
|
|
3258
|
+
return /* @__PURE__ */ jsx26(Box24, { gap: 0, children: /* @__PURE__ */ jsxs26(
|
|
3259
|
+
Text25,
|
|
3260
|
+
{
|
|
3261
|
+
color: isCursor ? inkColors.accent : isActive ? inkColors.accent : void 0,
|
|
3262
|
+
bold: isCursor || isActive,
|
|
3263
|
+
dimColor: !isCursor && !isActive,
|
|
3264
|
+
children: [
|
|
3265
|
+
isCursor ? `${symbols.pointerActive} ` : " ",
|
|
3266
|
+
item.icon,
|
|
3267
|
+
" ",
|
|
3268
|
+
item.label
|
|
3269
|
+
]
|
|
3270
|
+
}
|
|
3271
|
+
) }, item.id);
|
|
3272
|
+
})
|
|
3129
3273
|
]
|
|
3130
|
-
}
|
|
3131
|
-
|
|
3274
|
+
},
|
|
3275
|
+
section.title
|
|
3276
|
+
);
|
|
3277
|
+
return rendered;
|
|
3132
3278
|
}) });
|
|
3133
3279
|
}
|
|
3134
3280
|
|
|
@@ -3396,6 +3542,58 @@ function PinnedCommands({
|
|
|
3396
3542
|
|
|
3397
3543
|
// src/appPanel.tsx
|
|
3398
3544
|
import { jsx as jsx31, jsxs as jsxs31 } from "react/jsx-runtime";
|
|
3545
|
+
var screenLabels = {
|
|
3546
|
+
"command-args": "Args",
|
|
3547
|
+
"flag-selection": "Flags",
|
|
3548
|
+
"confirm-execute": "Execute",
|
|
3549
|
+
"command-execution": "Execute",
|
|
3550
|
+
"custom-command": "Custom Cmd",
|
|
3551
|
+
"pipeline-list": "Pipelines",
|
|
3552
|
+
"pipeline-builder": "Builder",
|
|
3553
|
+
"pipeline-execution": "Run",
|
|
3554
|
+
"self-update": "Update",
|
|
3555
|
+
"tool-status": "Status",
|
|
3556
|
+
"project-config": "Config"
|
|
3557
|
+
};
|
|
3558
|
+
function buildBreadcrumb(nav) {
|
|
3559
|
+
let base;
|
|
3560
|
+
switch (nav.view) {
|
|
3561
|
+
case "feature":
|
|
3562
|
+
base = getFeatureById(nav.featureId)?.label ?? nav.featureId;
|
|
3563
|
+
break;
|
|
3564
|
+
case "pinned":
|
|
3565
|
+
base = "Pinned";
|
|
3566
|
+
break;
|
|
3567
|
+
case "custom-command":
|
|
3568
|
+
base = "Custom Cmd";
|
|
3569
|
+
break;
|
|
3570
|
+
case "pipelines":
|
|
3571
|
+
base = "Pipelines";
|
|
3572
|
+
break;
|
|
3573
|
+
case "tool-status":
|
|
3574
|
+
base = "Status";
|
|
3575
|
+
break;
|
|
3576
|
+
case "config":
|
|
3577
|
+
base = "Config";
|
|
3578
|
+
break;
|
|
3579
|
+
case "self-update":
|
|
3580
|
+
base = "Update";
|
|
3581
|
+
break;
|
|
3582
|
+
default:
|
|
3583
|
+
base = nav.view;
|
|
3584
|
+
}
|
|
3585
|
+
if (nav.innerScreen === "home") {
|
|
3586
|
+
return base;
|
|
3587
|
+
}
|
|
3588
|
+
const parts = [base];
|
|
3589
|
+
for (const entry of nav.innerStack) {
|
|
3590
|
+
if (entry.screen !== "home") {
|
|
3591
|
+
parts.push(screenLabels[entry.screen] ?? entry.screen);
|
|
3592
|
+
}
|
|
3593
|
+
}
|
|
3594
|
+
parts.push(screenLabels[nav.innerScreen] ?? nav.innerScreen);
|
|
3595
|
+
return parts.join(" \u203A ");
|
|
3596
|
+
}
|
|
3399
3597
|
var FOOTER_HINTS = [
|
|
3400
3598
|
{ key: "\u2190\u2192", action: "panels" },
|
|
3401
3599
|
{ key: "j/k", action: "nav" },
|
|
@@ -3411,18 +3609,10 @@ function AppPanel() {
|
|
|
3411
3609
|
const { exit } = useApp2();
|
|
3412
3610
|
const nav = usePanelNavigation();
|
|
3413
3611
|
const focus = usePanelFocus();
|
|
3414
|
-
const
|
|
3415
|
-
() => getPinnedCommands().length > 0 || getPinnedRuns().length > 0
|
|
3416
|
-
);
|
|
3417
|
-
const sidebarItems = useSidebarItems(hasPins);
|
|
3612
|
+
const sidebarItems = useSidebarItems();
|
|
3418
3613
|
const modal = useModal();
|
|
3419
3614
|
const refreshPins = React18.useCallback(() => {
|
|
3420
|
-
|
|
3421
|
-
setHasPins(newHasPins);
|
|
3422
|
-
if (!newHasPins && nav.view === "pinned") {
|
|
3423
|
-
nav.selectSidebarItem("database");
|
|
3424
|
-
}
|
|
3425
|
-
}, [nav.view, nav.selectSidebarItem]);
|
|
3615
|
+
}, []);
|
|
3426
3616
|
const singlePanel = width < 60 || height < 15;
|
|
3427
3617
|
const handleExit = () => {
|
|
3428
3618
|
process.stdout.write(
|
|
@@ -3575,6 +3765,7 @@ function AppPanel() {
|
|
|
3575
3765
|
onNavigate: nav.navigateInner,
|
|
3576
3766
|
onBack: focus.focusSidebar,
|
|
3577
3767
|
width: mainContentWidth - 2,
|
|
3768
|
+
height: mainContentHeight,
|
|
3578
3769
|
panelMode: true,
|
|
3579
3770
|
isInputActive: focus.isMainFocused
|
|
3580
3771
|
}
|
|
@@ -3586,6 +3777,7 @@ function AppPanel() {
|
|
|
3586
3777
|
onNavigate: nav.navigateInner,
|
|
3587
3778
|
onBack: focus.focusSidebar,
|
|
3588
3779
|
width: mainContentWidth - 2,
|
|
3780
|
+
height: mainContentHeight,
|
|
3589
3781
|
panelMode: true,
|
|
3590
3782
|
isInputActive: focus.isMainFocused
|
|
3591
3783
|
}
|
|
@@ -3596,6 +3788,7 @@ function AppPanel() {
|
|
|
3596
3788
|
{
|
|
3597
3789
|
onBack: focus.focusSidebar,
|
|
3598
3790
|
width: mainContentWidth - 2,
|
|
3791
|
+
height: mainContentHeight,
|
|
3599
3792
|
panelMode: true,
|
|
3600
3793
|
isInputActive: focus.isMainFocused
|
|
3601
3794
|
}
|
|
@@ -3606,6 +3799,7 @@ function AppPanel() {
|
|
|
3606
3799
|
{
|
|
3607
3800
|
onBack: focus.focusSidebar,
|
|
3608
3801
|
width: mainContentWidth - 2,
|
|
3802
|
+
height: mainContentHeight,
|
|
3609
3803
|
panelMode: true,
|
|
3610
3804
|
isInputActive: focus.isMainFocused
|
|
3611
3805
|
}
|
|
@@ -3617,6 +3811,7 @@ function AppPanel() {
|
|
|
3617
3811
|
onBack: focus.focusSidebar,
|
|
3618
3812
|
onExit: handleExit,
|
|
3619
3813
|
width: mainContentWidth - 2,
|
|
3814
|
+
height: mainContentHeight,
|
|
3620
3815
|
panelMode: true,
|
|
3621
3816
|
isInputActive: focus.isMainFocused
|
|
3622
3817
|
}
|
|
@@ -3649,6 +3844,7 @@ function AppPanel() {
|
|
|
3649
3844
|
onNavigate: nav.navigateInner,
|
|
3650
3845
|
onBack: nav.goBackInner,
|
|
3651
3846
|
width: w,
|
|
3847
|
+
height: mainContentHeight,
|
|
3652
3848
|
panelMode: true,
|
|
3653
3849
|
isInputActive: isActive
|
|
3654
3850
|
}
|
|
@@ -3676,6 +3872,7 @@ function AppPanel() {
|
|
|
3676
3872
|
onBack: nav.goBackInner,
|
|
3677
3873
|
onExit: handleExit,
|
|
3678
3874
|
width: w,
|
|
3875
|
+
height: mainContentHeight,
|
|
3679
3876
|
panelMode: true,
|
|
3680
3877
|
isInputActive: isActive
|
|
3681
3878
|
}
|
|
@@ -3687,6 +3884,7 @@ function AppPanel() {
|
|
|
3687
3884
|
onNavigate: nav.navigateInner,
|
|
3688
3885
|
onBack: nav.goBackInner,
|
|
3689
3886
|
width: w,
|
|
3887
|
+
height: mainContentHeight,
|
|
3690
3888
|
panelMode: true,
|
|
3691
3889
|
isInputActive: isActive
|
|
3692
3890
|
}
|
|
@@ -3721,6 +3919,7 @@ function AppPanel() {
|
|
|
3721
3919
|
onBack: nav.goBackInner,
|
|
3722
3920
|
onExit: handleExit,
|
|
3723
3921
|
width: w,
|
|
3922
|
+
height: mainContentHeight,
|
|
3724
3923
|
panelMode: true,
|
|
3725
3924
|
isInputActive: isActive
|
|
3726
3925
|
}
|
|
@@ -3731,6 +3930,7 @@ function AppPanel() {
|
|
|
3731
3930
|
{
|
|
3732
3931
|
onBack: nav.goBackInner,
|
|
3733
3932
|
width: w,
|
|
3933
|
+
height: mainContentHeight,
|
|
3734
3934
|
panelMode: true,
|
|
3735
3935
|
isInputActive: isActive
|
|
3736
3936
|
}
|
|
@@ -3741,6 +3941,7 @@ function AppPanel() {
|
|
|
3741
3941
|
{
|
|
3742
3942
|
onBack: nav.goBackInner,
|
|
3743
3943
|
width: w,
|
|
3944
|
+
height: mainContentHeight,
|
|
3744
3945
|
panelMode: true,
|
|
3745
3946
|
isInputActive: isActive
|
|
3746
3947
|
}
|
|
@@ -3781,7 +3982,7 @@ function AppPanel() {
|
|
|
3781
3982
|
Panel,
|
|
3782
3983
|
{
|
|
3783
3984
|
id: "main",
|
|
3784
|
-
title:
|
|
3985
|
+
title: buildBreadcrumb(nav),
|
|
3785
3986
|
width: mainContentWidth,
|
|
3786
3987
|
height: Math.max(5, height - bannerHeight - 1),
|
|
3787
3988
|
focused: focus.isMainFocused,
|
|
@@ -3832,11 +4033,17 @@ function parseCliArgs(argv) {
|
|
|
3832
4033
|
if (argv_[0] === "pipeline" && argv_[1] === "run" && argv_[2]) {
|
|
3833
4034
|
return { mode: "pipeline-run", options: {}, pipelineName: argv_[2] };
|
|
3834
4035
|
}
|
|
3835
|
-
if (argv_[0] === "mcp"
|
|
3836
|
-
|
|
3837
|
-
if (
|
|
3838
|
-
|
|
3839
|
-
|
|
4036
|
+
if (argv_[0] === "mcp") {
|
|
4037
|
+
const sub = argv_[1];
|
|
4038
|
+
if (sub === "status") {
|
|
4039
|
+
return { mode: "mcp", options: {}, mcpAction: "status" };
|
|
4040
|
+
}
|
|
4041
|
+
if (sub === "install" || sub === "update" || sub === "remove") {
|
|
4042
|
+
let mcpScope = "local";
|
|
4043
|
+
if (argv_.includes("--project")) mcpScope = "project";
|
|
4044
|
+
else if (argv_.includes("--global")) mcpScope = "user";
|
|
4045
|
+
return { mode: "mcp", options: {}, mcpAction: sub, mcpScope };
|
|
4046
|
+
}
|
|
3840
4047
|
}
|
|
3841
4048
|
if (argv_[0] === "config") {
|
|
3842
4049
|
const edit = argv_.includes("--edit");
|
|
@@ -3925,6 +4132,9 @@ function printCliHelp() {
|
|
|
3925
4132
|
" polter mcp install Install Polter MCP server into Claude Code (local scope)",
|
|
3926
4133
|
" polter mcp install --project Install for this project only (shared via repo)",
|
|
3927
4134
|
" polter mcp install --global Install globally for all projects",
|
|
4135
|
+
" polter mcp update Update MCP server to latest version",
|
|
4136
|
+
" polter mcp status Show MCP registration and version info",
|
|
4137
|
+
" polter mcp remove Remove MCP server registration",
|
|
3928
4138
|
"",
|
|
3929
4139
|
" polter app setup ops [--path <dir>] [--create-project|--use-existing-project] [--yes]",
|
|
3930
4140
|
" polter app link ops [--path <dir>] [--relink]",
|
|
@@ -4750,8 +4960,10 @@ import { spawnSync as spawnSync2 } from "child_process";
|
|
|
4750
4960
|
import { readFileSync as readFileSync2, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2, existsSync as existsSync2 } from "fs";
|
|
4751
4961
|
import { join as join3 } from "path";
|
|
4752
4962
|
import { homedir as homedir2 } from "os";
|
|
4963
|
+
import { createRequire as createRequire2 } from "module";
|
|
4753
4964
|
import pc4 from "picocolors";
|
|
4754
|
-
var
|
|
4965
|
+
var require3 = createRequire2(import.meta.url);
|
|
4966
|
+
var MCP_ARGS = ["npx", "-y", "-p", "@polterware/polter@latest", "polter-mcp"];
|
|
4755
4967
|
var SCOPE_LABELS = {
|
|
4756
4968
|
local: "local (this machine)",
|
|
4757
4969
|
project: "project (shared via repo)",
|
|
@@ -4789,7 +5001,7 @@ function tryManualInstall(scope) {
|
|
|
4789
5001
|
const mcpServers = settings.mcpServers ?? {};
|
|
4790
5002
|
mcpServers.polter = {
|
|
4791
5003
|
command: "npx",
|
|
4792
|
-
args: ["-y", "-p", "@polterware/polter", "polter-mcp"]
|
|
5004
|
+
args: ["-y", "-p", "@polterware/polter@latest", "polter-mcp"]
|
|
4793
5005
|
};
|
|
4794
5006
|
settings.mcpServers = mcpServers;
|
|
4795
5007
|
writeFileSync2(settingsPath, JSON.stringify(settings, null, 2) + "\n");
|
|
@@ -4815,11 +5027,93 @@ async function installMcpServer(scope) {
|
|
|
4815
5027
|
process.stdout.write(pc4.green("\n Done! Restart Claude Code to use Polter tools.\n"));
|
|
4816
5028
|
} else {
|
|
4817
5029
|
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))}
|
|
5030
|
+
process.stderr.write(` ${pc4.dim(JSON.stringify({ mcpServers: { polter: { command: "npx", args: ["-y", "-p", "@polterware/polter@latest", "polter-mcp"] } } }, null, 2))}
|
|
4819
5031
|
`);
|
|
4820
5032
|
process.exit(1);
|
|
4821
5033
|
}
|
|
4822
5034
|
}
|
|
5035
|
+
async function removeMcpServer(scope) {
|
|
5036
|
+
process.stdout.write(pc4.bold(`Removing Polter MCP server \u2014 ${SCOPE_LABELS[scope]}
|
|
5037
|
+
|
|
5038
|
+
`));
|
|
5039
|
+
if (commandExists("claude")) {
|
|
5040
|
+
const result = spawnSync2("claude", ["mcp", "remove", "-s", scope, "polter"], {
|
|
5041
|
+
stdio: "inherit",
|
|
5042
|
+
shell: true
|
|
5043
|
+
});
|
|
5044
|
+
if (result.status === 0) {
|
|
5045
|
+
process.stdout.write(pc4.green("\n Done! Polter MCP server removed.\n"));
|
|
5046
|
+
return;
|
|
5047
|
+
}
|
|
5048
|
+
process.stdout.write(pc4.yellow(" 'claude mcp remove' failed, falling back to manual removal...\n\n"));
|
|
5049
|
+
}
|
|
5050
|
+
const settingsPath = getSettingsPath(scope);
|
|
5051
|
+
if (!existsSync2(settingsPath)) {
|
|
5052
|
+
process.stdout.write(pc4.yellow(" No settings file found. Nothing to remove.\n"));
|
|
5053
|
+
return;
|
|
5054
|
+
}
|
|
5055
|
+
let settings;
|
|
5056
|
+
try {
|
|
5057
|
+
settings = JSON.parse(readFileSync2(settingsPath, "utf-8"));
|
|
5058
|
+
} catch {
|
|
5059
|
+
process.stderr.write(pc4.red(` Failed to parse ${settingsPath}
|
|
5060
|
+
`));
|
|
5061
|
+
process.exit(1);
|
|
5062
|
+
return;
|
|
5063
|
+
}
|
|
5064
|
+
const mcpServers = settings.mcpServers;
|
|
5065
|
+
if (!mcpServers?.polter) {
|
|
5066
|
+
process.stdout.write(pc4.yellow(" Polter MCP server not found in settings. Nothing to remove.\n"));
|
|
5067
|
+
return;
|
|
5068
|
+
}
|
|
5069
|
+
delete mcpServers.polter;
|
|
5070
|
+
settings.mcpServers = mcpServers;
|
|
5071
|
+
writeFileSync2(settingsPath, JSON.stringify(settings, null, 2) + "\n");
|
|
5072
|
+
process.stdout.write(pc4.green(" Done! Polter MCP server removed.\n"));
|
|
5073
|
+
}
|
|
5074
|
+
async function mcpStatus() {
|
|
5075
|
+
process.stdout.write(pc4.bold("Polter MCP Server Status\n\n"));
|
|
5076
|
+
const pkg = require3("../../package.json");
|
|
5077
|
+
process.stdout.write(` Installed version: ${pc4.cyan(pkg.version)}
|
|
5078
|
+
`);
|
|
5079
|
+
const latestResult = spawnSync2("npm", ["view", "@polterware/polter", "version"], {
|
|
5080
|
+
encoding: "utf-8",
|
|
5081
|
+
shell: true,
|
|
5082
|
+
timeout: 1e4
|
|
5083
|
+
});
|
|
5084
|
+
const latest = latestResult.stdout?.trim();
|
|
5085
|
+
if (latest) {
|
|
5086
|
+
const upToDate = latest === pkg.version;
|
|
5087
|
+
process.stdout.write(` Latest version: ${upToDate ? pc4.green(latest) : pc4.yellow(`${latest} (update available)`)}
|
|
5088
|
+
`);
|
|
5089
|
+
}
|
|
5090
|
+
process.stdout.write("\n");
|
|
5091
|
+
const scopes = [
|
|
5092
|
+
{ label: "Project (.mcp.json)", path: join3(process.cwd(), ".mcp.json"), key: "project" },
|
|
5093
|
+
{ label: "User (~/.claude/settings.json)", path: join3(homedir2(), ".claude", "settings.json"), key: "user" }
|
|
5094
|
+
];
|
|
5095
|
+
for (const scope of scopes) {
|
|
5096
|
+
if (!existsSync2(scope.path)) {
|
|
5097
|
+
process.stdout.write(` ${scope.label}: ${pc4.dim("not found")}
|
|
5098
|
+
`);
|
|
5099
|
+
continue;
|
|
5100
|
+
}
|
|
5101
|
+
try {
|
|
5102
|
+
const settings = JSON.parse(readFileSync2(scope.path, "utf-8"));
|
|
5103
|
+
const mcpServers = settings.mcpServers;
|
|
5104
|
+
if (mcpServers?.polter) {
|
|
5105
|
+
process.stdout.write(` ${scope.label}: ${pc4.green("registered")}
|
|
5106
|
+
`);
|
|
5107
|
+
} else {
|
|
5108
|
+
process.stdout.write(` ${scope.label}: ${pc4.dim("not registered")}
|
|
5109
|
+
`);
|
|
5110
|
+
}
|
|
5111
|
+
} catch {
|
|
5112
|
+
process.stdout.write(` ${scope.label}: ${pc4.red("error reading file")}
|
|
5113
|
+
`);
|
|
5114
|
+
}
|
|
5115
|
+
}
|
|
5116
|
+
}
|
|
4823
5117
|
|
|
4824
5118
|
// src/index.tsx
|
|
4825
5119
|
import pc5 from "picocolors";
|
|
@@ -4829,8 +5123,20 @@ async function main() {
|
|
|
4829
5123
|
printCliHelp();
|
|
4830
5124
|
return;
|
|
4831
5125
|
}
|
|
4832
|
-
if (parsed.mode === "mcp
|
|
4833
|
-
|
|
5126
|
+
if (parsed.mode === "mcp") {
|
|
5127
|
+
const scope = parsed.mcpScope ?? "local";
|
|
5128
|
+
switch (parsed.mcpAction) {
|
|
5129
|
+
case "install":
|
|
5130
|
+
case "update":
|
|
5131
|
+
await installMcpServer(scope);
|
|
5132
|
+
break;
|
|
5133
|
+
case "remove":
|
|
5134
|
+
await removeMcpServer(scope);
|
|
5135
|
+
break;
|
|
5136
|
+
case "status":
|
|
5137
|
+
await mcpStatus();
|
|
5138
|
+
break;
|
|
5139
|
+
}
|
|
4834
5140
|
return;
|
|
4835
5141
|
}
|
|
4836
5142
|
if (parsed.mode === "app") {
|
|
@@ -4867,7 +5173,7 @@ Pipeline completed with ${errors.length} error(s)
|
|
|
4867
5173
|
return;
|
|
4868
5174
|
}
|
|
4869
5175
|
if (parsed.mode === "status") {
|
|
4870
|
-
const tools = ["supabase", "gh", "vercel"];
|
|
5176
|
+
const tools = ["supabase", "gh", "vercel", "git"];
|
|
4871
5177
|
process.stdout.write(pc5.bold("Tool Status\n\n"));
|
|
4872
5178
|
for (const toolId of tools) {
|
|
4873
5179
|
const info = getToolInfo(toolId);
|