@polterware/polter 0.3.0 → 0.4.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 +7 -1
- package/dist/{chunk-7MIUDIAI.js → chunk-YNOZDU75.js} +35 -6
- package/dist/index.js +714 -348
- package/dist/mcp.js +169 -9
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
findNearestPackageRoot,
|
|
11
11
|
findPipelineByName,
|
|
12
12
|
findPolterYaml,
|
|
13
|
+
generateProcessId,
|
|
13
14
|
getAllPipelines,
|
|
14
15
|
getCommandById,
|
|
15
16
|
getCommandValue,
|
|
@@ -20,6 +21,7 @@ import {
|
|
|
20
21
|
getOrCreateProjectConfig,
|
|
21
22
|
getProcessOutput,
|
|
22
23
|
getProjectConfigPath,
|
|
24
|
+
getToolDisplayName,
|
|
23
25
|
getToolInfo,
|
|
24
26
|
getToolLinkInfo,
|
|
25
27
|
installMcpServer,
|
|
@@ -36,16 +38,18 @@ import {
|
|
|
36
38
|
runInteractiveCommand,
|
|
37
39
|
runSupabaseCommand,
|
|
38
40
|
savePipeline,
|
|
41
|
+
startProcess,
|
|
39
42
|
stopProcess,
|
|
43
|
+
translateCommand,
|
|
40
44
|
writeProjectConfig
|
|
41
|
-
} from "./chunk-
|
|
45
|
+
} from "./chunk-YNOZDU75.js";
|
|
42
46
|
|
|
43
47
|
// src/index.tsx
|
|
44
|
-
import
|
|
48
|
+
import React28 from "react";
|
|
45
49
|
import { render } from "ink";
|
|
46
50
|
|
|
47
51
|
// src/app.tsx
|
|
48
|
-
import { Box as
|
|
52
|
+
import { Box as Box29, Text as Text33, useApp } from "ink";
|
|
49
53
|
|
|
50
54
|
// src/hooks/useNavigation.ts
|
|
51
55
|
import { useState, useCallback } from "react";
|
|
@@ -110,7 +114,7 @@ function useTerminalHeight() {
|
|
|
110
114
|
}
|
|
111
115
|
|
|
112
116
|
// src/components/GhostBanner.tsx
|
|
113
|
-
import React from "react";
|
|
117
|
+
import React, { useState as useState3, useEffect as useEffect2 } from "react";
|
|
114
118
|
import { Box, Text as Text2 } from "ink";
|
|
115
119
|
|
|
116
120
|
// src/theme.ts
|
|
@@ -197,6 +201,12 @@ var toolColors = {
|
|
|
197
201
|
git: "#F05032",
|
|
198
202
|
pkg: "#CB3837"
|
|
199
203
|
};
|
|
204
|
+
var pkgManagerColors = {
|
|
205
|
+
npm: "#CB3837",
|
|
206
|
+
pnpm: "#F69220",
|
|
207
|
+
yarn: "#2C8EBB",
|
|
208
|
+
bun: "#FBF0DF"
|
|
209
|
+
};
|
|
200
210
|
var toolLabels = {
|
|
201
211
|
supabase: "supabase",
|
|
202
212
|
gh: "github",
|
|
@@ -204,8 +214,21 @@ var toolLabels = {
|
|
|
204
214
|
git: "git",
|
|
205
215
|
pkg: "pkg"
|
|
206
216
|
};
|
|
217
|
+
function resolveToolColor(tool) {
|
|
218
|
+
if (tool === "pkg") {
|
|
219
|
+
const name = getToolDisplayName(tool);
|
|
220
|
+
return pkgManagerColors[name] ?? toolColors.pkg;
|
|
221
|
+
}
|
|
222
|
+
return toolColors[tool];
|
|
223
|
+
}
|
|
224
|
+
function resolveToolLabel(tool) {
|
|
225
|
+
if (tool === "pkg") {
|
|
226
|
+
return getToolDisplayName(tool);
|
|
227
|
+
}
|
|
228
|
+
return toolLabels[tool];
|
|
229
|
+
}
|
|
207
230
|
function ToolBadge({ tool }) {
|
|
208
|
-
return /* @__PURE__ */ jsx(Text, { color:
|
|
231
|
+
return /* @__PURE__ */ jsx(Text, { color: resolveToolColor(tool), dimColor: true, children: resolveToolLabel(tool) });
|
|
209
232
|
}
|
|
210
233
|
|
|
211
234
|
// src/components/GhostBanner.tsx
|
|
@@ -219,6 +242,23 @@ var McpBadge = React.memo(function McpBadge2() {
|
|
|
219
242
|
registered ? "ok" : "x"
|
|
220
243
|
] }) });
|
|
221
244
|
});
|
|
245
|
+
function ProcessBadge() {
|
|
246
|
+
const [count, setCount] = useState3(() => {
|
|
247
|
+
return listProcesses().filter((p) => p.status === "running").length;
|
|
248
|
+
});
|
|
249
|
+
useEffect2(() => {
|
|
250
|
+
const id = setInterval(() => {
|
|
251
|
+
const c = listProcesses().filter((p) => p.status === "running").length;
|
|
252
|
+
setCount(c);
|
|
253
|
+
}, 2e3);
|
|
254
|
+
return () => clearInterval(id);
|
|
255
|
+
}, []);
|
|
256
|
+
const color = count > 0 ? "#3ECF8E" : inkColors.accent;
|
|
257
|
+
return /* @__PURE__ */ jsx2(Box, { borderStyle: "round", borderColor: color, borderDimColor: count === 0, children: /* @__PURE__ */ jsxs(Text2, { color, dimColor: count === 0, children: [
|
|
258
|
+
"runs:",
|
|
259
|
+
count
|
|
260
|
+
] }) });
|
|
261
|
+
}
|
|
222
262
|
var ToolStatusBadges = React.memo(function ToolStatusBadges2() {
|
|
223
263
|
const tools = ["supabase", "gh", "vercel"].map((id) => getToolLinkInfo(id));
|
|
224
264
|
return /* @__PURE__ */ jsxs(Box, { gap: 1, children: [
|
|
@@ -237,13 +277,16 @@ function GhostBanner({ width = 80, compact = false }) {
|
|
|
237
277
|
if (compact) {
|
|
238
278
|
if (width < 60) {
|
|
239
279
|
return /* @__PURE__ */ jsxs(Box, { borderStyle: "round", borderColor: inkColors.accent, flexDirection: "column", alignItems: "flex-start", children: [
|
|
240
|
-
/* @__PURE__ */ jsxs(Box, {
|
|
241
|
-
/* @__PURE__ */
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
280
|
+
/* @__PURE__ */ jsxs(Box, { gap: 1, children: [
|
|
281
|
+
/* @__PURE__ */ jsxs(Box, { borderStyle: "round", borderColor: inkColors.accent, paddingX: 1, gap: 2, children: [
|
|
282
|
+
/* @__PURE__ */ jsx2(Text2, { color: inkColors.accent, bold: true, children: "POLTER" }),
|
|
283
|
+
/* @__PURE__ */ jsxs(Text2, { dimColor: true, children: [
|
|
284
|
+
"v",
|
|
285
|
+
VERSION
|
|
286
|
+
] }),
|
|
287
|
+
/* @__PURE__ */ jsx2(Text2, { color: "yellow", children: "alpha" })
|
|
245
288
|
] }),
|
|
246
|
-
/* @__PURE__ */ jsx2(
|
|
289
|
+
/* @__PURE__ */ jsx2(ProcessBadge, {})
|
|
247
290
|
] }),
|
|
248
291
|
/* @__PURE__ */ jsx2(Box, { borderStyle: "round", borderColor: inkColors.accent, paddingX: 1, children: /* @__PURE__ */ jsx2(ToolStatusBadges, {}) })
|
|
249
292
|
] });
|
|
@@ -251,13 +294,16 @@ function GhostBanner({ width = 80, compact = false }) {
|
|
|
251
294
|
return /* @__PURE__ */ jsxs(Box, { flexDirection: "row", borderStyle: "round", borderColor: inkColors.accent, gap: 1, alignItems: "flex-start", children: [
|
|
252
295
|
/* @__PURE__ */ jsx2(Box, { flexDirection: "column", children: ghost.art.map((line, i) => /* @__PURE__ */ jsx2(Text2, { color: inkColors.accent, children: line }, i)) }),
|
|
253
296
|
/* @__PURE__ */ jsxs(Box, { flexDirection: "column", alignItems: "flex-start", children: [
|
|
254
|
-
/* @__PURE__ */ jsxs(Box, {
|
|
255
|
-
/* @__PURE__ */
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
297
|
+
/* @__PURE__ */ jsxs(Box, { gap: 1, children: [
|
|
298
|
+
/* @__PURE__ */ jsxs(Box, { borderStyle: "round", borderColor: inkColors.accent, paddingX: 1, gap: 2, children: [
|
|
299
|
+
/* @__PURE__ */ jsx2(Text2, { color: inkColors.accent, bold: true, children: "POLTER" }),
|
|
300
|
+
/* @__PURE__ */ jsxs(Text2, { dimColor: true, children: [
|
|
301
|
+
"v",
|
|
302
|
+
VERSION
|
|
303
|
+
] }),
|
|
304
|
+
/* @__PURE__ */ jsx2(Text2, { color: "yellow", children: "alpha" })
|
|
259
305
|
] }),
|
|
260
|
-
/* @__PURE__ */ jsx2(
|
|
306
|
+
/* @__PURE__ */ jsx2(ProcessBadge, {})
|
|
261
307
|
] }),
|
|
262
308
|
/* @__PURE__ */ jsx2(Box, { borderStyle: "round", borderColor: inkColors.accent, paddingX: 1, children: /* @__PURE__ */ jsx2(ToolStatusBadges, {}) })
|
|
263
309
|
] })
|
|
@@ -265,13 +311,16 @@ function GhostBanner({ width = 80, compact = false }) {
|
|
|
265
311
|
}
|
|
266
312
|
if (width < 50) {
|
|
267
313
|
return /* @__PURE__ */ jsxs(Box, { marginBottom: 1, borderStyle: "round", borderColor: inkColors.accent, flexDirection: "column", alignItems: "flex-start", children: [
|
|
268
|
-
/* @__PURE__ */ jsxs(Box, {
|
|
269
|
-
/* @__PURE__ */
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
314
|
+
/* @__PURE__ */ jsxs(Box, { gap: 1, children: [
|
|
315
|
+
/* @__PURE__ */ jsxs(Box, { borderStyle: "round", borderColor: inkColors.accent, paddingX: 1, gap: 2, children: [
|
|
316
|
+
/* @__PURE__ */ jsx2(Text2, { color: inkColors.accent, bold: true, children: "POLTER" }),
|
|
317
|
+
/* @__PURE__ */ jsxs(Text2, { dimColor: true, children: [
|
|
318
|
+
"v",
|
|
319
|
+
VERSION
|
|
320
|
+
] }),
|
|
321
|
+
/* @__PURE__ */ jsx2(Text2, { color: "yellow", children: "alpha" })
|
|
273
322
|
] }),
|
|
274
|
-
/* @__PURE__ */ jsx2(
|
|
323
|
+
/* @__PURE__ */ jsx2(ProcessBadge, {})
|
|
275
324
|
] }),
|
|
276
325
|
/* @__PURE__ */ jsx2(Box, { borderStyle: "round", borderColor: inkColors.accent, paddingX: 1, children: /* @__PURE__ */ jsx2(ToolStatusBadges, {}) })
|
|
277
326
|
] });
|
|
@@ -286,13 +335,16 @@ function GhostBanner({ width = 80, compact = false }) {
|
|
|
286
335
|
borderColor: inkColors.accent,
|
|
287
336
|
marginBottom: 1,
|
|
288
337
|
children: [
|
|
289
|
-
/* @__PURE__ */ jsxs(Box, {
|
|
290
|
-
/* @__PURE__ */
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
338
|
+
/* @__PURE__ */ jsxs(Box, { gap: 1, children: [
|
|
339
|
+
/* @__PURE__ */ jsxs(Box, { borderStyle: "round", borderColor: inkColors.accent, paddingX: 1, gap: 2, children: [
|
|
340
|
+
/* @__PURE__ */ jsx2(Text2, { color: inkColors.accent, bold: true, children: "POLTER" }),
|
|
341
|
+
/* @__PURE__ */ jsxs(Text2, { dimColor: true, children: [
|
|
342
|
+
"v",
|
|
343
|
+
VERSION
|
|
344
|
+
] }),
|
|
345
|
+
/* @__PURE__ */ jsx2(Text2, { color: "yellow", children: "alpha" })
|
|
294
346
|
] }),
|
|
295
|
-
/* @__PURE__ */ jsx2(
|
|
347
|
+
/* @__PURE__ */ jsx2(ProcessBadge, {})
|
|
296
348
|
] }),
|
|
297
349
|
/* @__PURE__ */ jsx2(Box, { borderStyle: "round", borderColor: inkColors.accent, paddingX: 1, children: /* @__PURE__ */ jsx2(ToolStatusBadges, {}) }),
|
|
298
350
|
/* @__PURE__ */ jsx2(Text2, { dimColor: true, children: "Project & infrastructure orchestrator" })
|
|
@@ -303,13 +355,16 @@ function GhostBanner({ width = 80, compact = false }) {
|
|
|
303
355
|
return /* @__PURE__ */ jsxs(Box, { flexDirection: "row", alignItems: "flex-start", borderStyle: "round", borderColor: inkColors.accent, gap: 1, marginBottom: 1, children: [
|
|
304
356
|
/* @__PURE__ */ jsx2(Box, { flexDirection: "column", children: ghost.art.map((line, i) => /* @__PURE__ */ jsx2(Text2, { color: inkColors.accent, children: line }, i)) }),
|
|
305
357
|
/* @__PURE__ */ jsxs(Box, { flexDirection: "column", alignItems: "flex-start", children: [
|
|
306
|
-
/* @__PURE__ */ jsxs(Box, {
|
|
307
|
-
/* @__PURE__ */
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
358
|
+
/* @__PURE__ */ jsxs(Box, { gap: 1, children: [
|
|
359
|
+
/* @__PURE__ */ jsxs(Box, { borderStyle: "round", borderColor: inkColors.accent, paddingX: 1, gap: 2, children: [
|
|
360
|
+
/* @__PURE__ */ jsx2(Text2, { color: inkColors.accent, bold: true, children: "POLTER" }),
|
|
361
|
+
/* @__PURE__ */ jsxs(Text2, { dimColor: true, children: [
|
|
362
|
+
"v",
|
|
363
|
+
VERSION
|
|
364
|
+
] }),
|
|
365
|
+
/* @__PURE__ */ jsx2(Text2, { color: "yellow", children: "alpha" })
|
|
311
366
|
] }),
|
|
312
|
-
/* @__PURE__ */ jsx2(
|
|
367
|
+
/* @__PURE__ */ jsx2(ProcessBadge, {})
|
|
313
368
|
] }),
|
|
314
369
|
/* @__PURE__ */ jsx2(Box, { borderStyle: "round", borderColor: inkColors.accent, paddingX: 1, children: /* @__PURE__ */ jsx2(ToolStatusBadges, {}) }),
|
|
315
370
|
/* @__PURE__ */ jsx2(Text2, { dimColor: true, children: " Project & infrastructure orchestrator" })
|
|
@@ -318,7 +373,7 @@ function GhostBanner({ width = 80, compact = false }) {
|
|
|
318
373
|
}
|
|
319
374
|
|
|
320
375
|
// src/screens/Home.tsx
|
|
321
|
-
import { useEffect as
|
|
376
|
+
import { useEffect as useEffect4, useMemo as useMemo2, useState as useState5 } from "react";
|
|
322
377
|
import { Box as Box5, Text as Text6, useInput as useInput2 } from "ink";
|
|
323
378
|
|
|
324
379
|
// src/components/TabBar.tsx
|
|
@@ -347,7 +402,7 @@ function TabBar({ tabs, activeIndex, width = 80 }) {
|
|
|
347
402
|
}
|
|
348
403
|
|
|
349
404
|
// src/components/SelectList.tsx
|
|
350
|
-
import { useEffect as
|
|
405
|
+
import { useEffect as useEffect3, useMemo, useState as useState4 } from "react";
|
|
351
406
|
import { Box as Box3, Text as Text4, useInput } from "ink";
|
|
352
407
|
|
|
353
408
|
// src/components/selectListSections.ts
|
|
@@ -454,8 +509,8 @@ function SelectList({
|
|
|
454
509
|
}, []),
|
|
455
510
|
[items]
|
|
456
511
|
);
|
|
457
|
-
const [selectedSelectableIndex, setSelectedSelectableIndex] =
|
|
458
|
-
|
|
512
|
+
const [selectedSelectableIndex, setSelectedSelectableIndex] = useState4(0);
|
|
513
|
+
useEffect3(() => {
|
|
459
514
|
if (selectableIndexes.length === 0) {
|
|
460
515
|
setSelectedSelectableIndex(0);
|
|
461
516
|
return;
|
|
@@ -707,13 +762,13 @@ function buildPinnedOnlyItems(pinnedCommands, pinnedRuns) {
|
|
|
707
762
|
if (pinnedCommands.length > 0) {
|
|
708
763
|
for (const command of pinnedCommands) {
|
|
709
764
|
const cmdDef = findCommandByValue(command);
|
|
710
|
-
const
|
|
765
|
+
const toolDisplay = cmdDef ? getToolDisplayName(cmdDef.tool) : "supabase";
|
|
711
766
|
const labelHint = cmdDef?.hint;
|
|
712
767
|
items.push({
|
|
713
768
|
id: `command:${command}`,
|
|
714
769
|
value: command,
|
|
715
|
-
label: cmdDef ? `${
|
|
716
|
-
hint: [
|
|
770
|
+
label: cmdDef ? `${toolDisplay} ${command}` : command,
|
|
771
|
+
hint: [toolDisplay, labelHint].filter(Boolean).join(" \xB7 "),
|
|
717
772
|
icon: "\u{1F4CC}",
|
|
718
773
|
kind: "command",
|
|
719
774
|
rightActionable: true,
|
|
@@ -725,12 +780,12 @@ function buildPinnedOnlyItems(pinnedCommands, pinnedRuns) {
|
|
|
725
780
|
for (const runCommand2 of pinnedRuns) {
|
|
726
781
|
const baseCommand = runCommand2.split(" ").filter(Boolean)[0] ?? "";
|
|
727
782
|
const cmdDef = findCommandByValue(baseCommand);
|
|
728
|
-
const
|
|
783
|
+
const toolDisplay = cmdDef ? getToolDisplayName(cmdDef.tool) : "supabase";
|
|
729
784
|
items.push({
|
|
730
785
|
id: `run:${runCommand2}`,
|
|
731
786
|
value: runCommand2,
|
|
732
|
-
label: cmdDef ? `${
|
|
733
|
-
hint:
|
|
787
|
+
label: cmdDef ? `${toolDisplay} ${runCommand2}` : runCommand2,
|
|
788
|
+
hint: toolDisplay,
|
|
734
789
|
icon: "\u25B6",
|
|
735
790
|
kind: "run",
|
|
736
791
|
rightActionable: true,
|
|
@@ -767,8 +822,8 @@ function buildHomeItems({
|
|
|
767
822
|
selectable: false
|
|
768
823
|
});
|
|
769
824
|
}
|
|
770
|
-
const toolOrder = { supabase: 0, vercel: 1, gh: 2, git: 3 };
|
|
771
|
-
const toolIcons = { supabase: "\u{1F7E2}", vercel: "\u26AA", gh: "\u{1F535}", git: "\u{1F7E0}" };
|
|
825
|
+
const toolOrder = { supabase: 0, vercel: 1, gh: 2, git: 3, pkg: 4 };
|
|
826
|
+
const toolIcons = { supabase: "\u{1F7E2}", vercel: "\u26AA", gh: "\u{1F535}", git: "\u{1F7E0}", pkg: "\u{1F4E6}" };
|
|
772
827
|
const grouped = /* @__PURE__ */ new Map();
|
|
773
828
|
for (const cmd of activeFeature.commands) {
|
|
774
829
|
const existing = grouped.get(cmd.tool) ?? [];
|
|
@@ -784,7 +839,7 @@ function buildHomeItems({
|
|
|
784
839
|
items.push({
|
|
785
840
|
id: `tool-header-${tool}`,
|
|
786
841
|
value: `__tool_header_${tool}__`,
|
|
787
|
-
label: `${icon} ${tool}`,
|
|
842
|
+
label: `${icon} ${getToolDisplayName(tool)}`,
|
|
788
843
|
kind: "header",
|
|
789
844
|
selectable: false
|
|
790
845
|
});
|
|
@@ -883,16 +938,16 @@ function Home({
|
|
|
883
938
|
height = 24
|
|
884
939
|
}) {
|
|
885
940
|
const allFeatures = useMemo2(() => getFeatures(), []);
|
|
886
|
-
const [activeTabIndex, setActiveTabIndex] =
|
|
887
|
-
const [pinnedCommands, setPinnedCommands2] =
|
|
941
|
+
const [activeTabIndex, setActiveTabIndex] = useState5(0);
|
|
942
|
+
const [pinnedCommands, setPinnedCommands2] = useState5(
|
|
888
943
|
() => getPinnedCommands()
|
|
889
944
|
);
|
|
890
|
-
const [pinnedRuns, setPinnedRuns2] =
|
|
945
|
+
const [pinnedRuns, setPinnedRuns2] = useState5(
|
|
891
946
|
() => getPinnedRuns()
|
|
892
947
|
);
|
|
893
|
-
const [pinFeedback, setPinFeedback] =
|
|
948
|
+
const [pinFeedback, setPinFeedback] = useState5();
|
|
894
949
|
const activeFeature = allFeatures[activeTabIndex];
|
|
895
|
-
|
|
950
|
+
useEffect4(() => {
|
|
896
951
|
if (!pinFeedback) return;
|
|
897
952
|
const timeout = setTimeout(() => setPinFeedback(void 0), 1400);
|
|
898
953
|
return () => clearTimeout(timeout);
|
|
@@ -1031,11 +1086,11 @@ function Home({
|
|
|
1031
1086
|
}
|
|
1032
1087
|
|
|
1033
1088
|
// src/screens/CommandArgs.tsx
|
|
1034
|
-
import { useEffect as
|
|
1089
|
+
import { useEffect as useEffect5, useMemo as useMemo3, useState as useState7 } from "react";
|
|
1035
1090
|
import { Box as Box7, Text as Text8, useInput as useInput4 } from "ink";
|
|
1036
1091
|
|
|
1037
1092
|
// src/components/TextPrompt.tsx
|
|
1038
|
-
import { useState as
|
|
1093
|
+
import { useState as useState6 } from "react";
|
|
1039
1094
|
import { Box as Box6, Text as Text7, useInput as useInput3 } from "ink";
|
|
1040
1095
|
import TextInputComponent from "ink-text-input";
|
|
1041
1096
|
import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
@@ -1050,8 +1105,8 @@ function TextPrompt({
|
|
|
1050
1105
|
boxed = false,
|
|
1051
1106
|
focused = true
|
|
1052
1107
|
}) {
|
|
1053
|
-
const [value, setValue] =
|
|
1054
|
-
const [error, setError] =
|
|
1108
|
+
const [value, setValue] = useState6("");
|
|
1109
|
+
const [error, setError] = useState6();
|
|
1055
1110
|
useInput3((_input, key) => {
|
|
1056
1111
|
if (key.escape && onCancel) {
|
|
1057
1112
|
onCancel();
|
|
@@ -1190,15 +1245,15 @@ function CommandArgs({
|
|
|
1190
1245
|
() => cmdDef?.suggestedArgs ?? [],
|
|
1191
1246
|
[cmdDef]
|
|
1192
1247
|
);
|
|
1193
|
-
const [pinnedRuns, setPinnedRuns2] =
|
|
1194
|
-
const [pinFeedback, setPinFeedback] =
|
|
1195
|
-
const [phase, setPhase] =
|
|
1248
|
+
const [pinnedRuns, setPinnedRuns2] = useState7(() => getPinnedRuns());
|
|
1249
|
+
const [pinFeedback, setPinFeedback] = useState7();
|
|
1250
|
+
const [phase, setPhase] = useState7(
|
|
1196
1251
|
suggestions.length > 0 ? "select" : "custom"
|
|
1197
1252
|
);
|
|
1198
|
-
|
|
1253
|
+
useEffect5(() => {
|
|
1199
1254
|
setPhase(suggestions.length > 0 ? "select" : "custom");
|
|
1200
1255
|
}, [command, suggestions.length]);
|
|
1201
|
-
|
|
1256
|
+
useEffect5(() => {
|
|
1202
1257
|
if (!pinFeedback) return;
|
|
1203
1258
|
const timeout = setTimeout(() => setPinFeedback(void 0), 1400);
|
|
1204
1259
|
return () => clearTimeout(timeout);
|
|
@@ -1340,7 +1395,7 @@ function CommandArgs({
|
|
|
1340
1395
|
}
|
|
1341
1396
|
|
|
1342
1397
|
// src/screens/CustomCommand.tsx
|
|
1343
|
-
import { useState as
|
|
1398
|
+
import { useState as useState8 } from "react";
|
|
1344
1399
|
import { Box as Box8, Text as Text9 } from "ink";
|
|
1345
1400
|
import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1346
1401
|
function CustomCommand({
|
|
@@ -1351,8 +1406,8 @@ function CustomCommand({
|
|
|
1351
1406
|
panelMode = false,
|
|
1352
1407
|
isInputActive = true
|
|
1353
1408
|
}) {
|
|
1354
|
-
const [phase, setPhase] =
|
|
1355
|
-
const [selectedTool, setSelectedTool] =
|
|
1409
|
+
const [phase, setPhase] = useState8("tool-select");
|
|
1410
|
+
const [selectedTool, setSelectedTool] = useState8("supabase");
|
|
1356
1411
|
if (phase === "tool-select") {
|
|
1357
1412
|
const toolItems = [
|
|
1358
1413
|
{ value: "__section__", label: "\u{1F6E0} Select Tool", kind: "header", selectable: false },
|
|
@@ -1360,6 +1415,8 @@ function CustomCommand({
|
|
|
1360
1415
|
{ value: "gh", label: "GitHub CLI", hint: "gh ...", kind: "action" },
|
|
1361
1416
|
{ value: "vercel", label: "Vercel CLI", hint: "vercel ...", kind: "action" },
|
|
1362
1417
|
{ value: "git", label: "Git", hint: "git ...", kind: "action" },
|
|
1418
|
+
{ value: "__free_header__", label: "", kind: "header", selectable: false },
|
|
1419
|
+
{ value: "free", label: "\u2328 Free command", hint: "any command", kind: "action" },
|
|
1363
1420
|
...!panelMode ? [{ value: "__back__", label: "\u2190 Back" }] : []
|
|
1364
1421
|
];
|
|
1365
1422
|
return /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", paddingX: panelMode ? 1 : 0, children: [
|
|
@@ -1374,6 +1431,10 @@ function CustomCommand({
|
|
|
1374
1431
|
onBack();
|
|
1375
1432
|
return;
|
|
1376
1433
|
}
|
|
1434
|
+
if (value === "free") {
|
|
1435
|
+
setPhase("free-input");
|
|
1436
|
+
return;
|
|
1437
|
+
}
|
|
1377
1438
|
setSelectedTool(value);
|
|
1378
1439
|
setPhase("input");
|
|
1379
1440
|
},
|
|
@@ -1389,6 +1450,34 @@ function CustomCommand({
|
|
|
1389
1450
|
!panelMode && /* @__PURE__ */ jsx9(StatusBar, { hint: "\u2191\u2193 navigate \xB7 Enter select \xB7 Esc back", width })
|
|
1390
1451
|
] });
|
|
1391
1452
|
}
|
|
1453
|
+
if (phase === "free-input") {
|
|
1454
|
+
return /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", paddingX: panelMode ? 1 : 0, children: [
|
|
1455
|
+
!panelMode && /* @__PURE__ */ jsx9(Box8, { marginBottom: 1, children: /* @__PURE__ */ jsx9(Text9, { bold: true, color: inkColors.accent, children: "\u2328 Free Command" }) }),
|
|
1456
|
+
/* @__PURE__ */ jsx9(
|
|
1457
|
+
TextPrompt,
|
|
1458
|
+
{
|
|
1459
|
+
label: "Enter full command:",
|
|
1460
|
+
placeholder: "e.g. docker ps, curl -s http://..., make build",
|
|
1461
|
+
validate: (val) => {
|
|
1462
|
+
if (!val || !val.trim()) return "Please enter a command";
|
|
1463
|
+
return void 0;
|
|
1464
|
+
},
|
|
1465
|
+
onSubmit: (value) => {
|
|
1466
|
+
const parts = value.split(" ").filter(Boolean);
|
|
1467
|
+
const cmd = parts[0];
|
|
1468
|
+
const args = parts.slice(1);
|
|
1469
|
+
onNavigate("command-execution", { args, rawCommand: cmd });
|
|
1470
|
+
},
|
|
1471
|
+
onCancel: () => setPhase("tool-select"),
|
|
1472
|
+
arrowNavigation: panelMode,
|
|
1473
|
+
isInputActive,
|
|
1474
|
+
boxed: panelMode,
|
|
1475
|
+
focused: isInputActive
|
|
1476
|
+
}
|
|
1477
|
+
),
|
|
1478
|
+
!panelMode && /* @__PURE__ */ jsx9(StatusBar, { hint: "Type full command \xB7 Enter to execute \xB7 Esc to go back", width })
|
|
1479
|
+
] });
|
|
1480
|
+
}
|
|
1392
1481
|
return /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", paddingX: panelMode ? 1 : 0, children: [
|
|
1393
1482
|
!panelMode && /* @__PURE__ */ jsxs8(Box8, { marginBottom: 1, gap: 1, children: [
|
|
1394
1483
|
/* @__PURE__ */ jsx9(Text9, { bold: true, color: inkColors.accent, children: "\u270F\uFE0F Custom Command" }),
|
|
@@ -1409,7 +1498,7 @@ function CustomCommand({
|
|
|
1409
1498
|
},
|
|
1410
1499
|
onSubmit: (value) => {
|
|
1411
1500
|
const args = value.split(" ").filter(Boolean);
|
|
1412
|
-
onNavigate("
|
|
1501
|
+
onNavigate("command-execution", { args, tool: selectedTool });
|
|
1413
1502
|
},
|
|
1414
1503
|
onCancel: () => setPhase("tool-select"),
|
|
1415
1504
|
arrowNavigation: panelMode,
|
|
@@ -1426,7 +1515,7 @@ function CustomCommand({
|
|
|
1426
1515
|
import { Box as Box10, Text as Text11 } from "ink";
|
|
1427
1516
|
|
|
1428
1517
|
// src/components/FlagToggle.tsx
|
|
1429
|
-
import { useState as
|
|
1518
|
+
import { useState as useState9 } from "react";
|
|
1430
1519
|
import { Box as Box9, Text as Text10, useInput as useInput5 } from "ink";
|
|
1431
1520
|
import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
1432
1521
|
function FlagToggle({
|
|
@@ -1436,8 +1525,8 @@ function FlagToggle({
|
|
|
1436
1525
|
isInputActive = true,
|
|
1437
1526
|
arrowNavigation = false
|
|
1438
1527
|
}) {
|
|
1439
|
-
const [cursor, setCursor] =
|
|
1440
|
-
const [selected, setSelected] =
|
|
1528
|
+
const [cursor, setCursor] = useState9(0);
|
|
1529
|
+
const [selected, setSelected] = useState9(/* @__PURE__ */ new Set());
|
|
1441
1530
|
useInput5((input2, key) => {
|
|
1442
1531
|
if (key.upArrow || input2 === "k") {
|
|
1443
1532
|
setCursor((prev) => prev > 0 ? prev - 1 : flags.length - 1);
|
|
@@ -1569,7 +1658,7 @@ function FlagSelection({
|
|
|
1569
1658
|
}
|
|
1570
1659
|
|
|
1571
1660
|
// src/screens/CommandExecution.tsx
|
|
1572
|
-
import { useState as
|
|
1661
|
+
import { useState as useState12, useEffect as useEffect9 } from "react";
|
|
1573
1662
|
import { Box as Box13, Text as Text17, useInput as useInput8 } from "ink";
|
|
1574
1663
|
|
|
1575
1664
|
// src/components/Spinner.tsx
|
|
@@ -1650,24 +1739,40 @@ function Divider({
|
|
|
1650
1739
|
import { Text as Text16 } from "ink";
|
|
1651
1740
|
|
|
1652
1741
|
// src/components/ScrollableBox.tsx
|
|
1653
|
-
import { useState as
|
|
1742
|
+
import { useState as useState10, useEffect as useEffect6, useRef } from "react";
|
|
1654
1743
|
import { Box as Box12, Text as Text15, useInput as useInput7 } from "ink";
|
|
1655
1744
|
import { jsx as jsx15, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
1656
1745
|
function ScrollableBox({
|
|
1657
1746
|
height,
|
|
1658
1747
|
isActive = true,
|
|
1748
|
+
autoScrollToBottom = false,
|
|
1659
1749
|
children
|
|
1660
1750
|
}) {
|
|
1661
1751
|
const totalItems = children.length;
|
|
1662
|
-
const [scrollOffset, setScrollOffset] =
|
|
1752
|
+
const [scrollOffset, setScrollOffset] = useState10(0);
|
|
1663
1753
|
const visibleCount = Math.max(1, height - 2);
|
|
1754
|
+
const maxOffset = Math.max(0, totalItems - visibleCount);
|
|
1755
|
+
const pinnedToBottom = useRef(autoScrollToBottom);
|
|
1756
|
+
useEffect6(() => {
|
|
1757
|
+
if (autoScrollToBottom && pinnedToBottom.current) {
|
|
1758
|
+
setScrollOffset(maxOffset);
|
|
1759
|
+
}
|
|
1760
|
+
}, [autoScrollToBottom, maxOffset]);
|
|
1664
1761
|
useInput7(
|
|
1665
1762
|
(input2, key) => {
|
|
1666
1763
|
if (key.upArrow || input2 === "k") {
|
|
1667
|
-
setScrollOffset((prev) =>
|
|
1764
|
+
setScrollOffset((prev) => {
|
|
1765
|
+
const next = Math.max(0, prev - 1);
|
|
1766
|
+
pinnedToBottom.current = next >= maxOffset;
|
|
1767
|
+
return next;
|
|
1768
|
+
});
|
|
1668
1769
|
}
|
|
1669
1770
|
if (key.downArrow || input2 === "j") {
|
|
1670
|
-
setScrollOffset((prev) =>
|
|
1771
|
+
setScrollOffset((prev) => {
|
|
1772
|
+
const next = Math.min(maxOffset, prev + 1);
|
|
1773
|
+
pinnedToBottom.current = next >= maxOffset;
|
|
1774
|
+
return next;
|
|
1775
|
+
});
|
|
1671
1776
|
}
|
|
1672
1777
|
},
|
|
1673
1778
|
{ isActive }
|
|
@@ -1715,12 +1820,14 @@ function CommandOutput({
|
|
|
1715
1820
|
}
|
|
1716
1821
|
|
|
1717
1822
|
// src/hooks/useCommand.ts
|
|
1718
|
-
import { useState as
|
|
1823
|
+
import { useState as useState11, useCallback as useCallback2, useRef as useRef2, useEffect as useEffect7 } from "react";
|
|
1719
1824
|
function useCommand(execution = "supabase", cwd = process.cwd(), options) {
|
|
1720
|
-
const [status, setStatus] =
|
|
1721
|
-
const [result, setResult] =
|
|
1722
|
-
const
|
|
1723
|
-
|
|
1825
|
+
const [status, setStatus] = useState11("idle");
|
|
1826
|
+
const [result, setResult] = useState11(null);
|
|
1827
|
+
const [partialStdout, setPartialStdout] = useState11("");
|
|
1828
|
+
const [partialStderr, setPartialStderr] = useState11("");
|
|
1829
|
+
const abortRef = useRef2(null);
|
|
1830
|
+
useEffect7(() => {
|
|
1724
1831
|
return () => {
|
|
1725
1832
|
abortRef.current?.();
|
|
1726
1833
|
abortRef.current = null;
|
|
@@ -1729,9 +1836,11 @@ function useCommand(execution = "supabase", cwd = process.cwd(), options) {
|
|
|
1729
1836
|
const run = useCallback2(async (args) => {
|
|
1730
1837
|
setStatus("running");
|
|
1731
1838
|
setResult(null);
|
|
1839
|
+
setPartialStdout("");
|
|
1840
|
+
setPartialStderr("");
|
|
1732
1841
|
let resolvedExecution;
|
|
1733
1842
|
if (typeof execution === "string") {
|
|
1734
|
-
const toolIds2 = ["supabase", "gh", "vercel"];
|
|
1843
|
+
const toolIds2 = ["supabase", "gh", "vercel", "git", "pkg"];
|
|
1735
1844
|
if (toolIds2.includes(execution)) {
|
|
1736
1845
|
const resolved = resolveToolCommand(execution, cwd);
|
|
1737
1846
|
resolvedExecution = { command: resolved.command, env: resolved.env };
|
|
@@ -1741,7 +1850,11 @@ function useCommand(execution = "supabase", cwd = process.cwd(), options) {
|
|
|
1741
1850
|
} else {
|
|
1742
1851
|
resolvedExecution = execution;
|
|
1743
1852
|
}
|
|
1744
|
-
const
|
|
1853
|
+
const onData = (stdout, stderr) => {
|
|
1854
|
+
setPartialStdout(stdout);
|
|
1855
|
+
setPartialStderr(stderr);
|
|
1856
|
+
};
|
|
1857
|
+
const runOpts = { quiet: options?.quiet, onData };
|
|
1745
1858
|
const handle = runCommand(resolvedExecution, args, cwd, runOpts);
|
|
1746
1859
|
abortRef.current = handle.abort;
|
|
1747
1860
|
const res = await handle.promise;
|
|
@@ -1761,21 +1874,23 @@ function useCommand(execution = "supabase", cwd = process.cwd(), options) {
|
|
|
1761
1874
|
const reset = useCallback2(() => {
|
|
1762
1875
|
setStatus("idle");
|
|
1763
1876
|
setResult(null);
|
|
1877
|
+
setPartialStdout("");
|
|
1878
|
+
setPartialStderr("");
|
|
1764
1879
|
}, []);
|
|
1765
|
-
return { status, result, run, reset, abort };
|
|
1880
|
+
return { status, result, run, reset, abort, partialStdout, partialStderr };
|
|
1766
1881
|
}
|
|
1767
1882
|
|
|
1768
1883
|
// src/hooks/useInteractiveRun.ts
|
|
1769
1884
|
import { useCallback as useCallback3 } from "react";
|
|
1770
1885
|
|
|
1771
1886
|
// src/hooks/useFullscreen.ts
|
|
1772
|
-
import { useEffect as
|
|
1887
|
+
import { useEffect as useEffect8 } from "react";
|
|
1773
1888
|
var ENTER_ALT_SCREEN = "\x1B[?1049h";
|
|
1774
1889
|
var LEAVE_ALT_SCREEN = "\x1B[?1049l";
|
|
1775
1890
|
var HIDE_CURSOR = "\x1B[?25l";
|
|
1776
1891
|
var SHOW_CURSOR = "\x1B[?25h";
|
|
1777
1892
|
function useFullscreen() {
|
|
1778
|
-
|
|
1893
|
+
useEffect8(() => {
|
|
1779
1894
|
process.stdout.write(ENTER_ALT_SCREEN + HIDE_CURSOR);
|
|
1780
1895
|
return () => {
|
|
1781
1896
|
process.stdout.write(SHOW_CURSOR + LEAVE_ALT_SCREEN);
|
|
@@ -1880,6 +1995,7 @@ import { jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
|
1880
1995
|
function CommandExecution({
|
|
1881
1996
|
args: initialArgs,
|
|
1882
1997
|
tool = "supabase",
|
|
1998
|
+
rawCommand,
|
|
1883
1999
|
interactive = false,
|
|
1884
2000
|
onBack,
|
|
1885
2001
|
onHome,
|
|
@@ -1890,16 +2006,17 @@ function CommandExecution({
|
|
|
1890
2006
|
panelMode = false,
|
|
1891
2007
|
isInputActive = true
|
|
1892
2008
|
}) {
|
|
1893
|
-
const [phase, setPhase] =
|
|
1894
|
-
const [currentArgs, setCurrentArgs] =
|
|
1895
|
-
const [pinMessage, setPinMessage] =
|
|
1896
|
-
const
|
|
2009
|
+
const [phase, setPhase] = useState12("confirm");
|
|
2010
|
+
const [currentArgs, setCurrentArgs] = useState12(initialArgs);
|
|
2011
|
+
const [pinMessage, setPinMessage] = useState12();
|
|
2012
|
+
const execution = rawCommand ?? tool;
|
|
2013
|
+
const { status, result, run, reset, abort, partialStdout, partialStderr } = useCommand(execution, process.cwd(), {
|
|
1897
2014
|
quiet: panelMode
|
|
1898
2015
|
});
|
|
1899
2016
|
const { runInteractive } = useInteractiveRun();
|
|
1900
|
-
const [outputFocused, setOutputFocused] =
|
|
1901
|
-
const [copyMessage, setCopyMessage] =
|
|
1902
|
-
const cmdDisplay = `${tool} ${currentArgs.join(" ")}`;
|
|
2017
|
+
const [outputFocused, setOutputFocused] = useState12(false);
|
|
2018
|
+
const [copyMessage, setCopyMessage] = useState12();
|
|
2019
|
+
const cmdDisplay = rawCommand ? `${rawCommand} ${currentArgs.join(" ")}`.trim() : `${getToolDisplayName(tool)} ${currentArgs.join(" ")}`;
|
|
1903
2020
|
const runCommand2 = currentArgs.join(" ");
|
|
1904
2021
|
useInput8(
|
|
1905
2022
|
(_input, key) => {
|
|
@@ -1921,7 +2038,13 @@ function CommandExecution({
|
|
|
1921
2038
|
},
|
|
1922
2039
|
{ isActive: isInputActive && phase === "error-menu" }
|
|
1923
2040
|
);
|
|
1924
|
-
|
|
2041
|
+
useEffect9(() => {
|
|
2042
|
+
if (phase === "background-started") {
|
|
2043
|
+
const t = setTimeout(() => onBack(), 1500);
|
|
2044
|
+
return () => clearTimeout(t);
|
|
2045
|
+
}
|
|
2046
|
+
}, [phase, onBack]);
|
|
2047
|
+
useEffect9(() => {
|
|
1925
2048
|
if (phase === "running" && status === "idle") {
|
|
1926
2049
|
if (panelMode && interactive) {
|
|
1927
2050
|
const interactiveResult = runInteractive(tool, currentArgs);
|
|
@@ -1935,7 +2058,7 @@ function CommandExecution({
|
|
|
1935
2058
|
}
|
|
1936
2059
|
}
|
|
1937
2060
|
}, [phase, status, run, currentArgs, panelMode, interactive, tool, runInteractive]);
|
|
1938
|
-
|
|
2061
|
+
useEffect9(() => {
|
|
1939
2062
|
if (phase === "running" && status === "success") {
|
|
1940
2063
|
if (isPinnedRun(runCommand2)) {
|
|
1941
2064
|
setPhase("success");
|
|
@@ -1956,6 +2079,11 @@ function CommandExecution({
|
|
|
1956
2079
|
label: pinned ? "\u{1F4CC} Unpin command" : "\u{1F4CC} Pin command",
|
|
1957
2080
|
hint: "Save to quick access"
|
|
1958
2081
|
},
|
|
2082
|
+
{
|
|
2083
|
+
value: "background",
|
|
2084
|
+
label: "\u23E9 Run in background",
|
|
2085
|
+
hint: "Start as background process"
|
|
2086
|
+
},
|
|
1959
2087
|
{ value: "cancel", label: "\u2190 Cancel" }
|
|
1960
2088
|
];
|
|
1961
2089
|
const confirmContent = /* @__PURE__ */ jsxs15(Box13, { flexDirection: "column", children: [
|
|
@@ -1984,6 +2112,19 @@ function CommandExecution({
|
|
|
1984
2112
|
isPinnedRun(runCommand2) ? "\u2713 Command pinned" : "\u2713 Command unpinned"
|
|
1985
2113
|
);
|
|
1986
2114
|
break;
|
|
2115
|
+
case "background": {
|
|
2116
|
+
const cwd = process.cwd();
|
|
2117
|
+
if (rawCommand) {
|
|
2118
|
+
const id = generateProcessId(rawCommand, currentArgs);
|
|
2119
|
+
startProcess(id, rawCommand, currentArgs, cwd);
|
|
2120
|
+
} else {
|
|
2121
|
+
const resolved = resolveToolCommand(tool, cwd);
|
|
2122
|
+
const id = generateProcessId(resolved.command, currentArgs);
|
|
2123
|
+
startProcess(id, resolved.command, currentArgs, cwd, resolved.env);
|
|
2124
|
+
}
|
|
2125
|
+
setPhase("background-started");
|
|
2126
|
+
break;
|
|
2127
|
+
}
|
|
1987
2128
|
case "cancel":
|
|
1988
2129
|
onBack();
|
|
1989
2130
|
break;
|
|
@@ -2010,7 +2151,21 @@ function CommandExecution({
|
|
|
2010
2151
|
}
|
|
2011
2152
|
) : confirmContent });
|
|
2012
2153
|
}
|
|
2154
|
+
if (phase === "background-started") {
|
|
2155
|
+
return /* @__PURE__ */ jsxs15(Box13, { flexDirection: "column", paddingX: panelMode ? 1 : 0, children: [
|
|
2156
|
+
/* @__PURE__ */ jsxs15(Box13, { marginY: 1, gap: 1, children: [
|
|
2157
|
+
/* @__PURE__ */ jsx17(Text17, { color: "#3ECF8E", bold: true, children: "\u2713" }),
|
|
2158
|
+
/* @__PURE__ */ jsx17(Text17, { color: "#3ECF8E", bold: true, children: "Started in background" })
|
|
2159
|
+
] }),
|
|
2160
|
+
/* @__PURE__ */ jsxs15(Box13, { children: [
|
|
2161
|
+
/* @__PURE__ */ jsx17(Text17, { dimColor: true, children: "Command: " }),
|
|
2162
|
+
/* @__PURE__ */ jsx17(Text17, { children: cmdDisplay })
|
|
2163
|
+
] })
|
|
2164
|
+
] });
|
|
2165
|
+
}
|
|
2013
2166
|
if (phase === "running") {
|
|
2167
|
+
const hasPartialOutput = partialStdout.length > 0 || partialStderr.length > 0;
|
|
2168
|
+
const streamOutputHeight = Math.max(3, height - 10);
|
|
2014
2169
|
return /* @__PURE__ */ jsxs15(Box13, { flexDirection: "column", paddingX: panelMode ? 1 : 0, children: [
|
|
2015
2170
|
/* @__PURE__ */ jsx17(Divider, { width: panelMode ? width - 4 : width }),
|
|
2016
2171
|
/* @__PURE__ */ jsxs15(Box13, { marginY: 1, gap: 1, children: [
|
|
@@ -2021,6 +2176,15 @@ function CommandExecution({
|
|
|
2021
2176
|
] }),
|
|
2022
2177
|
/* @__PURE__ */ jsx17(Divider, { width: panelMode ? width - 4 : width }),
|
|
2023
2178
|
/* @__PURE__ */ jsx17(Box13, { marginTop: 1, children: /* @__PURE__ */ jsx17(Spinner, { label: `Executing ${cmdDisplay}...` }) }),
|
|
2179
|
+
hasPartialOutput && /* @__PURE__ */ jsx17(
|
|
2180
|
+
CommandOutput,
|
|
2181
|
+
{
|
|
2182
|
+
stdout: partialStdout,
|
|
2183
|
+
stderr: partialStderr,
|
|
2184
|
+
height: streamOutputHeight,
|
|
2185
|
+
isActive: false
|
|
2186
|
+
}
|
|
2187
|
+
),
|
|
2024
2188
|
/* @__PURE__ */ jsxs15(Box13, { marginTop: 1, children: [
|
|
2025
2189
|
/* @__PURE__ */ jsx17(Text17, { dimColor: true, children: "Press " }),
|
|
2026
2190
|
/* @__PURE__ */ jsx17(Text17, { color: inkColors.accent, children: "Esc" }),
|
|
@@ -2282,7 +2446,7 @@ function CommandExecution({
|
|
|
2282
2446
|
}
|
|
2283
2447
|
|
|
2284
2448
|
// src/screens/SelfUpdate.tsx
|
|
2285
|
-
import { useEffect as
|
|
2449
|
+
import { useEffect as useEffect10, useState as useState13 } from "react";
|
|
2286
2450
|
import { Box as Box14, Text as Text18 } from "ink";
|
|
2287
2451
|
import { jsx as jsx18, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
2288
2452
|
var packageName = "@polterware/polter";
|
|
@@ -2300,10 +2464,10 @@ function SelfUpdate({
|
|
|
2300
2464
|
isInputActive = true
|
|
2301
2465
|
}) {
|
|
2302
2466
|
const repositoryRoot = findNearestPackageRoot();
|
|
2303
|
-
const [target, setTarget] =
|
|
2467
|
+
const [target, setTarget] = useState13(
|
|
2304
2468
|
repositoryRoot ? "repository" : "global"
|
|
2305
2469
|
);
|
|
2306
|
-
const [phase, setPhase] =
|
|
2470
|
+
const [phase, setPhase] = useState13(
|
|
2307
2471
|
repositoryRoot ? "target" : "confirm"
|
|
2308
2472
|
);
|
|
2309
2473
|
const updateArgs = getUpdateArgs(target);
|
|
@@ -2312,12 +2476,12 @@ function SelfUpdate({
|
|
|
2312
2476
|
const { status, result, run, reset } = useCommand("npm", updateCwd, {
|
|
2313
2477
|
quiet: panelMode
|
|
2314
2478
|
});
|
|
2315
|
-
|
|
2479
|
+
useEffect10(() => {
|
|
2316
2480
|
if (phase === "running" && status === "idle") {
|
|
2317
2481
|
run(updateArgs);
|
|
2318
2482
|
}
|
|
2319
2483
|
}, [phase, run, status, updateArgs]);
|
|
2320
|
-
|
|
2484
|
+
useEffect10(() => {
|
|
2321
2485
|
if (phase === "running" && status === "success") {
|
|
2322
2486
|
setPhase("success");
|
|
2323
2487
|
}
|
|
@@ -2558,15 +2722,15 @@ function SelfUpdate({
|
|
|
2558
2722
|
}
|
|
2559
2723
|
|
|
2560
2724
|
// src/screens/ToolStatus.tsx
|
|
2561
|
-
import { useEffect as
|
|
2725
|
+
import { useEffect as useEffect11, useState as useState14 } from "react";
|
|
2562
2726
|
import { Box as Box15, Text as Text19 } from "ink";
|
|
2563
2727
|
import { jsx as jsx19, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
2564
2728
|
var toolIds = ["supabase", "gh", "vercel", "git", "pkg"];
|
|
2565
2729
|
var linkableTools = /* @__PURE__ */ new Set(["supabase", "gh", "vercel", "pkg"]);
|
|
2566
2730
|
function ToolStatus({ onBack, onNavigate, width = 80, height = 24, panelMode = false, isInputActive = true }) {
|
|
2567
|
-
const [tools, setTools] =
|
|
2568
|
-
const [mcpInfo, setMcpInfo] =
|
|
2569
|
-
|
|
2731
|
+
const [tools, setTools] = useState14(null);
|
|
2732
|
+
const [mcpInfo, setMcpInfo] = useState14(null);
|
|
2733
|
+
useEffect11(() => {
|
|
2570
2734
|
const t = setTimeout(() => {
|
|
2571
2735
|
setTools(toolIds.map((id) => getToolLinkInfo(id)));
|
|
2572
2736
|
setMcpInfo(getMcpStatusInfo());
|
|
@@ -2652,11 +2816,11 @@ function ToolStatus({ onBack, onNavigate, width = 80, height = 24, panelMode = f
|
|
|
2652
2816
|
}
|
|
2653
2817
|
|
|
2654
2818
|
// src/screens/ProjectConfig.tsx
|
|
2655
|
-
import { useMemo as useMemo4, useState as
|
|
2819
|
+
import { useMemo as useMemo4, useState as useState16 } from "react";
|
|
2656
2820
|
import { Box as Box16, Text as Text20 } from "ink";
|
|
2657
2821
|
|
|
2658
2822
|
// src/hooks/useEditor.ts
|
|
2659
|
-
import { useState as
|
|
2823
|
+
import { useState as useState15, useCallback as useCallback4 } from "react";
|
|
2660
2824
|
import { useStdin } from "ink";
|
|
2661
2825
|
|
|
2662
2826
|
// src/lib/editor.ts
|
|
@@ -2707,7 +2871,7 @@ function openInEditor(filePath) {
|
|
|
2707
2871
|
// src/hooks/useEditor.ts
|
|
2708
2872
|
function useEditor() {
|
|
2709
2873
|
const { setRawMode } = useStdin();
|
|
2710
|
-
const [isEditing, setIsEditing] =
|
|
2874
|
+
const [isEditing, setIsEditing] = useState15(false);
|
|
2711
2875
|
const openEditor = useCallback4(async (filePath) => {
|
|
2712
2876
|
const editor = resolveEditor();
|
|
2713
2877
|
const terminal = isTerminalEditor(editor.command);
|
|
@@ -2737,11 +2901,11 @@ function ProjectConfig({
|
|
|
2737
2901
|
isInputActive = true
|
|
2738
2902
|
}) {
|
|
2739
2903
|
const configPath = useMemo4(() => getProjectConfigPath(), []);
|
|
2740
|
-
const [config2, setConfig] =
|
|
2741
|
-
const [phase, setPhase] =
|
|
2742
|
-
const [feedback, setFeedback] =
|
|
2743
|
-
const [envKey, setEnvKey] =
|
|
2744
|
-
const [selectedEnvKey, setSelectedEnvKey] =
|
|
2904
|
+
const [config2, setConfig] = useState16(() => getOrCreateProjectConfig());
|
|
2905
|
+
const [phase, setPhase] = useState16("overview");
|
|
2906
|
+
const [feedback, setFeedback] = useState16();
|
|
2907
|
+
const [envKey, setEnvKey] = useState16("");
|
|
2908
|
+
const [selectedEnvKey, setSelectedEnvKey] = useState16("");
|
|
2745
2909
|
const { openEditor, isEditing } = useEditor();
|
|
2746
2910
|
const detectedPkg = useMemo4(() => detectPkgManager(), []);
|
|
2747
2911
|
if (!configPath) {
|
|
@@ -3223,7 +3387,7 @@ function PipelineList({
|
|
|
3223
3387
|
}
|
|
3224
3388
|
|
|
3225
3389
|
// src/screens/PipelineBuilder.tsx
|
|
3226
|
-
import { useState as
|
|
3390
|
+
import { useState as useState17 } from "react";
|
|
3227
3391
|
import { Box as Box18, Text as Text22 } from "ink";
|
|
3228
3392
|
import { jsx as jsx22, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
3229
3393
|
var stepCounter = 0;
|
|
@@ -3238,9 +3402,9 @@ function PipelineBuilder({
|
|
|
3238
3402
|
panelMode = false,
|
|
3239
3403
|
isInputActive = true
|
|
3240
3404
|
}) {
|
|
3241
|
-
const [phase, setPhase] =
|
|
3242
|
-
const [name, setName] =
|
|
3243
|
-
const [steps, setSteps] =
|
|
3405
|
+
const [phase, setPhase] = useState17("name");
|
|
3406
|
+
const [name, setName] = useState17("");
|
|
3407
|
+
const [steps, setSteps] = useState17([]);
|
|
3244
3408
|
if (phase === "name") {
|
|
3245
3409
|
return /* @__PURE__ */ jsxs20(Box18, { flexDirection: "column", paddingX: panelMode ? 1 : 0, children: [
|
|
3246
3410
|
/* @__PURE__ */ jsx22(Box18, { marginBottom: 1, children: /* @__PURE__ */ jsx22(Text22, { bold: true, color: inkColors.accent, children: "\u{1F517} New Pipeline" }) }),
|
|
@@ -3426,7 +3590,7 @@ function PipelineBuilder({
|
|
|
3426
3590
|
}
|
|
3427
3591
|
|
|
3428
3592
|
// src/screens/PipelineExecution.tsx
|
|
3429
|
-
import { useState as
|
|
3593
|
+
import { useState as useState18, useEffect as useEffect12, useMemo as useMemo6 } from "react";
|
|
3430
3594
|
import { Box as Box21, Text as Text25 } from "ink";
|
|
3431
3595
|
|
|
3432
3596
|
// src/components/StepIndicator.tsx
|
|
@@ -3519,10 +3683,10 @@ function PipelineExecution({
|
|
|
3519
3683
|
() => getAllPipelines().find((p) => p.id === pipelineId),
|
|
3520
3684
|
[pipelineId]
|
|
3521
3685
|
);
|
|
3522
|
-
const [phase, setPhase] =
|
|
3523
|
-
const [progress, setProgress] =
|
|
3524
|
-
const [results, setResults] =
|
|
3525
|
-
|
|
3686
|
+
const [phase, setPhase] = useState18("running");
|
|
3687
|
+
const [progress, setProgress] = useState18(null);
|
|
3688
|
+
const [results, setResults] = useState18([]);
|
|
3689
|
+
useEffect12(() => {
|
|
3526
3690
|
if (!pipeline) return;
|
|
3527
3691
|
executePipeline(pipeline, (p) => {
|
|
3528
3692
|
setProgress({ ...p });
|
|
@@ -3636,7 +3800,7 @@ function PipelineExecution({
|
|
|
3636
3800
|
}
|
|
3637
3801
|
|
|
3638
3802
|
// src/screens/McpManage.tsx
|
|
3639
|
-
import { useState as
|
|
3803
|
+
import { useState as useState19, useCallback as useCallback5 } from "react";
|
|
3640
3804
|
import { Box as Box22, Text as Text26 } from "ink";
|
|
3641
3805
|
import { jsx as jsx25, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
3642
3806
|
function McpManage({
|
|
@@ -3646,10 +3810,10 @@ function McpManage({
|
|
|
3646
3810
|
panelMode = false,
|
|
3647
3811
|
isInputActive = true
|
|
3648
3812
|
}) {
|
|
3649
|
-
const [status, setStatus] =
|
|
3650
|
-
const [phase, setPhase] =
|
|
3651
|
-
const [action, setAction] =
|
|
3652
|
-
const [result, setResult] =
|
|
3813
|
+
const [status, setStatus] = useState19(() => getMcpStatusInfo());
|
|
3814
|
+
const [phase, setPhase] = useState19("overview");
|
|
3815
|
+
const [action, setAction] = useState19(null);
|
|
3816
|
+
const [result, setResult] = useState19(null);
|
|
3653
3817
|
const refreshStatus = useCallback5(() => {
|
|
3654
3818
|
setStatus(getMcpStatusInfo());
|
|
3655
3819
|
}, []);
|
|
@@ -3791,7 +3955,7 @@ function McpManage({
|
|
|
3791
3955
|
}
|
|
3792
3956
|
|
|
3793
3957
|
// src/screens/ProcessList.tsx
|
|
3794
|
-
import { useState as
|
|
3958
|
+
import { useState as useState20, useEffect as useEffect13, useCallback as useCallback6 } from "react";
|
|
3795
3959
|
import { Box as Box23, Text as Text27, useInput as useInput9 } from "ink";
|
|
3796
3960
|
import { homedir } from "os";
|
|
3797
3961
|
import { jsx as jsx26, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
@@ -3831,22 +3995,22 @@ function ProcessList({
|
|
|
3831
3995
|
panelMode = false,
|
|
3832
3996
|
isInputActive = true
|
|
3833
3997
|
}) {
|
|
3834
|
-
const [processes, setProcesses] =
|
|
3835
|
-
const [selectedIndex, setSelectedIndex] =
|
|
3836
|
-
const [feedback, setFeedback] =
|
|
3837
|
-
|
|
3998
|
+
const [processes, setProcesses] = useState20(() => listProcesses());
|
|
3999
|
+
const [selectedIndex, setSelectedIndex] = useState20(0);
|
|
4000
|
+
const [feedback, setFeedback] = useState20();
|
|
4001
|
+
useEffect13(() => {
|
|
3838
4002
|
const interval = setInterval(() => {
|
|
3839
4003
|
setProcesses(listProcesses());
|
|
3840
4004
|
}, 2e3);
|
|
3841
4005
|
return () => clearInterval(interval);
|
|
3842
4006
|
}, []);
|
|
3843
|
-
|
|
4007
|
+
useEffect13(() => {
|
|
3844
4008
|
if (feedback) {
|
|
3845
4009
|
const timer = setTimeout(() => setFeedback(void 0), 2e3);
|
|
3846
4010
|
return () => clearTimeout(timer);
|
|
3847
4011
|
}
|
|
3848
4012
|
}, [feedback]);
|
|
3849
|
-
|
|
4013
|
+
useEffect13(() => {
|
|
3850
4014
|
if (selectedIndex >= processes.length && processes.length > 0) {
|
|
3851
4015
|
setSelectedIndex(processes.length - 1);
|
|
3852
4016
|
}
|
|
@@ -3996,7 +4160,7 @@ function ProcessList({
|
|
|
3996
4160
|
}
|
|
3997
4161
|
|
|
3998
4162
|
// src/screens/ProcessLogs.tsx
|
|
3999
|
-
import { useState as
|
|
4163
|
+
import { useState as useState21, useEffect as useEffect14, useCallback as useCallback7 } from "react";
|
|
4000
4164
|
import { Box as Box24, Text as Text28, useInput as useInput10 } from "ink";
|
|
4001
4165
|
import { spawn as spawn3 } from "child_process";
|
|
4002
4166
|
import { jsx as jsx27, jsxs as jsxs26 } from "react/jsx-runtime";
|
|
@@ -4015,16 +4179,16 @@ function ProcessLogs({
|
|
|
4015
4179
|
panelMode = false,
|
|
4016
4180
|
isInputActive = true
|
|
4017
4181
|
}) {
|
|
4018
|
-
const [stream, setStream] =
|
|
4019
|
-
const [lines, setLines] =
|
|
4020
|
-
const [proc, setProc] =
|
|
4021
|
-
const [feedback, setFeedback] =
|
|
4182
|
+
const [stream, setStream] = useState21("both");
|
|
4183
|
+
const [lines, setLines] = useState21([]);
|
|
4184
|
+
const [proc, setProc] = useState21();
|
|
4185
|
+
const [feedback, setFeedback] = useState21();
|
|
4022
4186
|
const logBoxHeight = Math.max(3, height - 6);
|
|
4023
|
-
|
|
4187
|
+
useEffect14(() => {
|
|
4024
4188
|
const refresh = () => {
|
|
4025
4189
|
try {
|
|
4026
|
-
const output2 = getProcessOutput(processId,
|
|
4027
|
-
const combined = stream === "stderr" ? output2.stderr : stream === "stdout" ? output2.stdout : [...output2.stdout, ...output2.stderr].slice(-
|
|
4190
|
+
const output2 = getProcessOutput(processId, 1e3, stream);
|
|
4191
|
+
const combined = stream === "stderr" ? output2.stderr : stream === "stdout" ? output2.stdout : [...output2.stdout, ...output2.stderr].slice(-1e3);
|
|
4028
4192
|
setLines(combined);
|
|
4029
4193
|
} catch {
|
|
4030
4194
|
setLines([`Process "${processId}" not found`]);
|
|
@@ -4035,8 +4199,8 @@ function ProcessLogs({
|
|
|
4035
4199
|
refresh();
|
|
4036
4200
|
const interval = setInterval(refresh, 1e3);
|
|
4037
4201
|
return () => clearInterval(interval);
|
|
4038
|
-
}, [processId,
|
|
4039
|
-
|
|
4202
|
+
}, [processId, stream]);
|
|
4203
|
+
useEffect14(() => {
|
|
4040
4204
|
if (feedback) {
|
|
4041
4205
|
const timer = setTimeout(() => setFeedback(void 0), 2e3);
|
|
4042
4206
|
return () => clearTimeout(timer);
|
|
@@ -4104,10 +4268,16 @@ function ProcessLogs({
|
|
|
4104
4268
|
borderStyle: "round",
|
|
4105
4269
|
borderColor: inkColors.accent,
|
|
4106
4270
|
paddingX: 1,
|
|
4107
|
-
height: logBoxHeight + 2,
|
|
4108
4271
|
width: cardWidth,
|
|
4109
|
-
|
|
4110
|
-
|
|
4272
|
+
children: /* @__PURE__ */ jsx27(
|
|
4273
|
+
ScrollableBox,
|
|
4274
|
+
{
|
|
4275
|
+
height: logBoxHeight,
|
|
4276
|
+
isActive: isInputActive,
|
|
4277
|
+
autoScrollToBottom: true,
|
|
4278
|
+
children: lines.length === 0 ? [/* @__PURE__ */ jsx27(Text28, { dimColor: true, children: "No output yet..." }, "empty")] : lines.map((line, i) => /* @__PURE__ */ jsx27(Text28, { wrap: "truncate", children: line }, i))
|
|
4279
|
+
}
|
|
4280
|
+
)
|
|
4111
4281
|
}
|
|
4112
4282
|
),
|
|
4113
4283
|
feedback && /* @__PURE__ */ jsx27(Box24, { children: /* @__PURE__ */ jsx27(Text28, { color: inkColors.accent, children: feedback }) }),
|
|
@@ -4117,6 +4287,7 @@ function ProcessLogs({
|
|
|
4117
4287
|
/* @__PURE__ */ jsx27(Text28, { bold: true, color: inkColors.accent, children: stream }),
|
|
4118
4288
|
"]"
|
|
4119
4289
|
] }),
|
|
4290
|
+
/* @__PURE__ */ jsx27(Text28, { dimColor: true, children: "\u2191\u2193:scroll" }),
|
|
4120
4291
|
/* @__PURE__ */ jsx27(Text28, { dimColor: true, children: "s:toggle" }),
|
|
4121
4292
|
/* @__PURE__ */ jsx27(Text28, { dimColor: true, children: "x:stop" }),
|
|
4122
4293
|
/* @__PURE__ */ jsx27(Text28, { dimColor: true, children: "c:copy" }),
|
|
@@ -4126,7 +4297,7 @@ function ProcessLogs({
|
|
|
4126
4297
|
}
|
|
4127
4298
|
|
|
4128
4299
|
// src/screens/DeclarativePlan.tsx
|
|
4129
|
-
import { useEffect as
|
|
4300
|
+
import { useEffect as useEffect15, useState as useState22 } from "react";
|
|
4130
4301
|
import { Box as Box25, Text as Text29 } from "ink";
|
|
4131
4302
|
import { jsx as jsx28, jsxs as jsxs27 } from "react/jsx-runtime";
|
|
4132
4303
|
function DeclarativePlan({
|
|
@@ -4137,10 +4308,10 @@ function DeclarativePlan({
|
|
|
4137
4308
|
panelMode = false,
|
|
4138
4309
|
isInputActive = true
|
|
4139
4310
|
}) {
|
|
4140
|
-
const [phase, setPhase] =
|
|
4141
|
-
const [actions, setActions] =
|
|
4142
|
-
const [applyProgress, setApplyProgress] =
|
|
4143
|
-
const [applyResults, setApplyResults] =
|
|
4311
|
+
const [phase, setPhase] = useState22("loading");
|
|
4312
|
+
const [actions, setActions] = useState22([]);
|
|
4313
|
+
const [applyProgress, setApplyProgress] = useState22("");
|
|
4314
|
+
const [applyResults, setApplyResults] = useState22([]);
|
|
4144
4315
|
const { openEditor } = useEditor();
|
|
4145
4316
|
const loadPlan = () => {
|
|
4146
4317
|
setPhase("loading");
|
|
@@ -4160,7 +4331,7 @@ function DeclarativePlan({
|
|
|
4160
4331
|
setPhase("plan-view");
|
|
4161
4332
|
}, 0);
|
|
4162
4333
|
};
|
|
4163
|
-
|
|
4334
|
+
useEffect15(() => {
|
|
4164
4335
|
loadPlan();
|
|
4165
4336
|
}, []);
|
|
4166
4337
|
if (phase === "loading") {
|
|
@@ -4354,7 +4525,7 @@ function DeclarativePlan({
|
|
|
4354
4525
|
}
|
|
4355
4526
|
|
|
4356
4527
|
// src/screens/DeclarativeStatus.tsx
|
|
4357
|
-
import { useEffect as
|
|
4528
|
+
import { useEffect as useEffect16, useState as useState23 } from "react";
|
|
4358
4529
|
import { Box as Box26, Text as Text30 } from "ink";
|
|
4359
4530
|
import { jsx as jsx29, jsxs as jsxs28 } from "react/jsx-runtime";
|
|
4360
4531
|
function DeclarativeStatus({
|
|
@@ -4364,10 +4535,10 @@ function DeclarativeStatus({
|
|
|
4364
4535
|
panelMode = false,
|
|
4365
4536
|
isInputActive = true
|
|
4366
4537
|
}) {
|
|
4367
|
-
const [phase, setPhase] =
|
|
4368
|
-
const [status, setStatus] =
|
|
4369
|
-
const [config2, setConfig] =
|
|
4370
|
-
const [pkgInfo, setPkgInfo] =
|
|
4538
|
+
const [phase, setPhase] = useState23("loading");
|
|
4539
|
+
const [status, setStatus] = useState23({});
|
|
4540
|
+
const [config2, setConfig] = useState23(null);
|
|
4541
|
+
const [pkgInfo, setPkgInfo] = useState23(null);
|
|
4371
4542
|
const load = () => {
|
|
4372
4543
|
setPhase("loading");
|
|
4373
4544
|
setTimeout(() => {
|
|
@@ -4380,7 +4551,7 @@ function DeclarativeStatus({
|
|
|
4380
4551
|
setPhase("display");
|
|
4381
4552
|
}, 0);
|
|
4382
4553
|
};
|
|
4383
|
-
|
|
4554
|
+
useEffect16(() => {
|
|
4384
4555
|
load();
|
|
4385
4556
|
}, []);
|
|
4386
4557
|
if (phase === "loading") {
|
|
@@ -4486,7 +4657,7 @@ function DeclarativeStatus({
|
|
|
4486
4657
|
}
|
|
4487
4658
|
|
|
4488
4659
|
// src/screens/InitScaffold.tsx
|
|
4489
|
-
import { useEffect as
|
|
4660
|
+
import { useEffect as useEffect17, useState as useState24 } from "react";
|
|
4490
4661
|
import { Box as Box27, Text as Text31 } from "ink";
|
|
4491
4662
|
import { writeFileSync } from "fs";
|
|
4492
4663
|
import { join } from "path";
|
|
@@ -4630,9 +4801,9 @@ function InitScaffold({
|
|
|
4630
4801
|
panelMode = false,
|
|
4631
4802
|
isInputActive = true
|
|
4632
4803
|
}) {
|
|
4633
|
-
const [phase, setPhase] =
|
|
4634
|
-
const [yamlString, setYamlString] =
|
|
4635
|
-
const [overwrite, setOverwrite] =
|
|
4804
|
+
const [phase, setPhase] = useState24("detecting");
|
|
4805
|
+
const [yamlString, setYamlString] = useState24("");
|
|
4806
|
+
const [overwrite, setOverwrite] = useState24(false);
|
|
4636
4807
|
const { openEditor } = useEditor();
|
|
4637
4808
|
const cwd = process.cwd();
|
|
4638
4809
|
const yamlPath = join(cwd, "polter.yaml");
|
|
@@ -4678,7 +4849,7 @@ function InitScaffold({
|
|
|
4678
4849
|
setPhase("preview");
|
|
4679
4850
|
}, 0);
|
|
4680
4851
|
};
|
|
4681
|
-
|
|
4852
|
+
useEffect17(() => {
|
|
4682
4853
|
detect();
|
|
4683
4854
|
}, []);
|
|
4684
4855
|
if (phase === "detecting") {
|
|
@@ -4790,8 +4961,164 @@ function InitScaffold({
|
|
|
4790
4961
|
] });
|
|
4791
4962
|
}
|
|
4792
4963
|
|
|
4793
|
-
// src/
|
|
4964
|
+
// src/screens/ScriptPicker.tsx
|
|
4965
|
+
import { useState as useState25, useEffect as useEffect18, useMemo as useMemo8 } from "react";
|
|
4966
|
+
import { Box as Box28, Text as Text32, useInput as useInput11 } from "ink";
|
|
4967
|
+
import { readFileSync, existsSync } from "fs";
|
|
4968
|
+
import { join as join2 } from "path";
|
|
4794
4969
|
import { jsx as jsx31, jsxs as jsxs30 } from "react/jsx-runtime";
|
|
4970
|
+
function readScripts(cwd) {
|
|
4971
|
+
const pkgPath = join2(cwd, "package.json");
|
|
4972
|
+
if (!existsSync(pkgPath)) return [];
|
|
4973
|
+
try {
|
|
4974
|
+
const raw = JSON.parse(readFileSync(pkgPath, "utf-8"));
|
|
4975
|
+
const scripts = raw.scripts ?? {};
|
|
4976
|
+
return Object.entries(scripts).map(([name, command]) => ({ name, command }));
|
|
4977
|
+
} catch {
|
|
4978
|
+
return [];
|
|
4979
|
+
}
|
|
4980
|
+
}
|
|
4981
|
+
function ScriptPicker({
|
|
4982
|
+
onNavigate,
|
|
4983
|
+
onBack,
|
|
4984
|
+
width = 80,
|
|
4985
|
+
height = 24,
|
|
4986
|
+
panelMode = false,
|
|
4987
|
+
isInputActive = true
|
|
4988
|
+
}) {
|
|
4989
|
+
const cwd = process.cwd();
|
|
4990
|
+
const scripts = useMemo8(() => readScripts(cwd), [cwd]);
|
|
4991
|
+
const mgr = useMemo8(() => detectPkgManager(cwd), [cwd]);
|
|
4992
|
+
const [selectedIndex, setSelectedIndex] = useState25(0);
|
|
4993
|
+
const [feedback, setFeedback] = useState25();
|
|
4994
|
+
useEffect18(() => {
|
|
4995
|
+
if (feedback) {
|
|
4996
|
+
const timer = setTimeout(() => setFeedback(void 0), 3e3);
|
|
4997
|
+
return () => clearTimeout(timer);
|
|
4998
|
+
}
|
|
4999
|
+
}, [feedback]);
|
|
5000
|
+
useEffect18(() => {
|
|
5001
|
+
if (selectedIndex >= scripts.length && scripts.length > 0) {
|
|
5002
|
+
setSelectedIndex(scripts.length - 1);
|
|
5003
|
+
}
|
|
5004
|
+
}, [scripts.length, selectedIndex]);
|
|
5005
|
+
useInput11((input2, key) => {
|
|
5006
|
+
if (!isInputActive) return;
|
|
5007
|
+
if (key.escape || key.leftArrow && !key.ctrl) {
|
|
5008
|
+
onBack();
|
|
5009
|
+
return;
|
|
5010
|
+
}
|
|
5011
|
+
if (scripts.length === 0) return;
|
|
5012
|
+
if (key.upArrow || input2 === "k") {
|
|
5013
|
+
setSelectedIndex((i) => Math.max(0, i - 1));
|
|
5014
|
+
return;
|
|
5015
|
+
}
|
|
5016
|
+
if (key.downArrow || input2 === "j") {
|
|
5017
|
+
setSelectedIndex((i) => Math.min(scripts.length - 1, i + 1));
|
|
5018
|
+
return;
|
|
5019
|
+
}
|
|
5020
|
+
if (key.return || key.rightArrow) {
|
|
5021
|
+
const script = scripts[selectedIndex];
|
|
5022
|
+
if (script) {
|
|
5023
|
+
const resolved = resolveToolCommand("pkg", cwd);
|
|
5024
|
+
try {
|
|
5025
|
+
const translated = translateCommand(["run", script.name], mgr.id);
|
|
5026
|
+
onNavigate("command-execution", {
|
|
5027
|
+
tool: "pkg",
|
|
5028
|
+
args: translated.args
|
|
5029
|
+
});
|
|
5030
|
+
} catch {
|
|
5031
|
+
setFeedback(`"run" is not supported by ${mgr.id}`);
|
|
5032
|
+
}
|
|
5033
|
+
}
|
|
5034
|
+
return;
|
|
5035
|
+
}
|
|
5036
|
+
if (input2 === "b") {
|
|
5037
|
+
const script = scripts[selectedIndex];
|
|
5038
|
+
if (script) {
|
|
5039
|
+
try {
|
|
5040
|
+
const translated = translateCommand(["run", script.name], mgr.id);
|
|
5041
|
+
const id = generateProcessId(mgr.command, translated.args);
|
|
5042
|
+
startProcess(id, mgr.command, translated.args, cwd);
|
|
5043
|
+
setFeedback(`Started ${mgr.id} run ${script.name} as background process`);
|
|
5044
|
+
} catch (err) {
|
|
5045
|
+
setFeedback(err instanceof Error ? err.message : "Failed to start process");
|
|
5046
|
+
}
|
|
5047
|
+
}
|
|
5048
|
+
return;
|
|
5049
|
+
}
|
|
5050
|
+
});
|
|
5051
|
+
const contentWidth = Math.max(30, (panelMode ? width - 4 : width) - 2);
|
|
5052
|
+
if (scripts.length === 0) {
|
|
5053
|
+
return /* @__PURE__ */ jsxs30(Box28, { flexDirection: "column", paddingX: panelMode ? 1 : 0, children: [
|
|
5054
|
+
!panelMode && /* @__PURE__ */ jsx31(Box28, { marginBottom: 1, children: /* @__PURE__ */ jsxs30(Text32, { bold: true, color: inkColors.accent, children: [
|
|
5055
|
+
"\u{1F4DC}",
|
|
5056
|
+
" ",
|
|
5057
|
+
mgr.id,
|
|
5058
|
+
" scripts"
|
|
5059
|
+
] }) }),
|
|
5060
|
+
/* @__PURE__ */ jsx31(
|
|
5061
|
+
Box28,
|
|
5062
|
+
{
|
|
5063
|
+
flexDirection: "column",
|
|
5064
|
+
borderStyle: "round",
|
|
5065
|
+
borderColor: panel.borderDim,
|
|
5066
|
+
borderDimColor: true,
|
|
5067
|
+
paddingX: 1,
|
|
5068
|
+
width: contentWidth,
|
|
5069
|
+
children: /* @__PURE__ */ jsx31(Text32, { dimColor: true, children: "No scripts found in package.json" })
|
|
5070
|
+
}
|
|
5071
|
+
),
|
|
5072
|
+
/* @__PURE__ */ jsx31(Box28, { marginTop: 1, gap: 2, children: /* @__PURE__ */ jsx31(Text32, { dimColor: true, children: "Esc:back" }) })
|
|
5073
|
+
] });
|
|
5074
|
+
}
|
|
5075
|
+
const headerHeight = panelMode ? 0 : 2;
|
|
5076
|
+
const footerHeight = 2;
|
|
5077
|
+
const feedbackHeight = feedback ? 2 : 0;
|
|
5078
|
+
const availableHeight = height - headerHeight - footerHeight - feedbackHeight;
|
|
5079
|
+
const itemHeight = 1;
|
|
5080
|
+
const visibleCount = Math.max(1, Math.floor(availableHeight / itemHeight));
|
|
5081
|
+
const windowStart = Math.max(0, Math.min(selectedIndex - Math.floor(visibleCount / 2), scripts.length - visibleCount));
|
|
5082
|
+
const visibleScripts = scripts.slice(windowStart, windowStart + visibleCount);
|
|
5083
|
+
return /* @__PURE__ */ jsxs30(Box28, { flexDirection: "column", paddingX: panelMode ? 1 : 0, children: [
|
|
5084
|
+
!panelMode && /* @__PURE__ */ jsx31(Box28, { marginBottom: 1, children: /* @__PURE__ */ jsxs30(Text32, { bold: true, color: inkColors.accent, children: [
|
|
5085
|
+
"\u{1F4DC}",
|
|
5086
|
+
" ",
|
|
5087
|
+
mgr.id,
|
|
5088
|
+
" scripts"
|
|
5089
|
+
] }) }),
|
|
5090
|
+
feedback && /* @__PURE__ */ jsx31(Box28, { marginBottom: 1, children: /* @__PURE__ */ jsx31(Text32, { color: inkColors.accent, children: feedback }) }),
|
|
5091
|
+
/* @__PURE__ */ jsx31(Box28, { flexDirection: "column", width: contentWidth, children: visibleScripts.map((script) => {
|
|
5092
|
+
const idx = scripts.indexOf(script);
|
|
5093
|
+
const isFocused = idx === selectedIndex;
|
|
5094
|
+
return /* @__PURE__ */ jsxs30(Box28, { gap: 1, children: [
|
|
5095
|
+
/* @__PURE__ */ jsxs30(Text32, { color: isFocused ? inkColors.accent : void 0, bold: isFocused, children: [
|
|
5096
|
+
isFocused ? "\u25B6" : " ",
|
|
5097
|
+
" ",
|
|
5098
|
+
script.name
|
|
5099
|
+
] }),
|
|
5100
|
+
/* @__PURE__ */ jsx31(Text32, { dimColor: true, children: script.command })
|
|
5101
|
+
] }, script.name);
|
|
5102
|
+
}) }),
|
|
5103
|
+
scripts.length > visibleCount && /* @__PURE__ */ jsx31(Box28, { children: /* @__PURE__ */ jsxs30(Text32, { dimColor: true, children: [
|
|
5104
|
+
windowStart > 0 ? "\u25B2 " : " ",
|
|
5105
|
+
windowStart + visibleCount < scripts.length ? "\u25BC " : " ",
|
|
5106
|
+
scripts.length,
|
|
5107
|
+
" scripts"
|
|
5108
|
+
] }) }),
|
|
5109
|
+
/* @__PURE__ */ jsxs30(Box28, { marginTop: 1, gap: 2, children: [
|
|
5110
|
+
/* @__PURE__ */ jsxs30(Text32, { dimColor: true, children: [
|
|
5111
|
+
"\u21B5",
|
|
5112
|
+
":run"
|
|
5113
|
+
] }),
|
|
5114
|
+
/* @__PURE__ */ jsx31(Text32, { dimColor: true, children: "b:background" }),
|
|
5115
|
+
/* @__PURE__ */ jsx31(Text32, { dimColor: true, children: "Esc:back" })
|
|
5116
|
+
] })
|
|
5117
|
+
] });
|
|
5118
|
+
}
|
|
5119
|
+
|
|
5120
|
+
// src/app.tsx
|
|
5121
|
+
import { jsx as jsx32, jsxs as jsxs31 } from "react/jsx-runtime";
|
|
4795
5122
|
function AppClassic() {
|
|
4796
5123
|
const { screen, params, navigate, goBack, goHome } = useNavigation();
|
|
4797
5124
|
const { exit } = useApp();
|
|
@@ -4806,9 +5133,9 @@ function AppClassic() {
|
|
|
4806
5133
|
const renderScreen = () => {
|
|
4807
5134
|
switch (screen) {
|
|
4808
5135
|
case "home":
|
|
4809
|
-
return /* @__PURE__ */
|
|
5136
|
+
return /* @__PURE__ */ jsx32(Home, { onNavigate: navigate, onExit: handleExit, width, height });
|
|
4810
5137
|
case "command-args":
|
|
4811
|
-
return /* @__PURE__ */
|
|
5138
|
+
return /* @__PURE__ */ jsx32(
|
|
4812
5139
|
CommandArgs,
|
|
4813
5140
|
{
|
|
4814
5141
|
command: params.command ?? "",
|
|
@@ -4819,9 +5146,9 @@ function AppClassic() {
|
|
|
4819
5146
|
}
|
|
4820
5147
|
);
|
|
4821
5148
|
case "custom-command":
|
|
4822
|
-
return /* @__PURE__ */
|
|
5149
|
+
return /* @__PURE__ */ jsx32(CustomCommand, { onNavigate: navigate, onBack: goBack, width });
|
|
4823
5150
|
case "flag-selection":
|
|
4824
|
-
return /* @__PURE__ */
|
|
5151
|
+
return /* @__PURE__ */ jsx32(
|
|
4825
5152
|
FlagSelection,
|
|
4826
5153
|
{
|
|
4827
5154
|
args: params.args ?? [],
|
|
@@ -4833,11 +5160,12 @@ function AppClassic() {
|
|
|
4833
5160
|
);
|
|
4834
5161
|
case "confirm-execute":
|
|
4835
5162
|
case "command-execution":
|
|
4836
|
-
return /* @__PURE__ */
|
|
5163
|
+
return /* @__PURE__ */ jsx32(
|
|
4837
5164
|
CommandExecution,
|
|
4838
5165
|
{
|
|
4839
5166
|
args: params.args ?? [],
|
|
4840
5167
|
tool: params.tool,
|
|
5168
|
+
rawCommand: params.rawCommand,
|
|
4841
5169
|
onBack: goBack,
|
|
4842
5170
|
onExit: handleExit,
|
|
4843
5171
|
onRunSuggestion: (sugTool, sugArgs) => {
|
|
@@ -4848,23 +5176,23 @@ function AppClassic() {
|
|
|
4848
5176
|
}
|
|
4849
5177
|
);
|
|
4850
5178
|
case "self-update":
|
|
4851
|
-
return /* @__PURE__ */
|
|
5179
|
+
return /* @__PURE__ */ jsx32(SelfUpdate, { onBack: goBack, onExit: handleExit, width });
|
|
4852
5180
|
case "tool-status":
|
|
4853
|
-
return /* @__PURE__ */
|
|
5181
|
+
return /* @__PURE__ */ jsx32(ToolStatus, { onBack: goBack, onNavigate: navigate, width });
|
|
4854
5182
|
case "mcp-manage":
|
|
4855
|
-
return /* @__PURE__ */
|
|
5183
|
+
return /* @__PURE__ */ jsx32(McpManage, { onBack: goBack, width });
|
|
4856
5184
|
case "process-list":
|
|
4857
|
-
return /* @__PURE__ */
|
|
5185
|
+
return /* @__PURE__ */ jsx32(ProcessList, { onNavigate: navigate, onBack: goBack, width, height });
|
|
4858
5186
|
case "process-logs":
|
|
4859
|
-
return /* @__PURE__ */
|
|
5187
|
+
return /* @__PURE__ */ jsx32(ProcessLogs, { processId: params.processId ?? "", onBack: goBack, width, height });
|
|
4860
5188
|
case "project-config":
|
|
4861
|
-
return /* @__PURE__ */
|
|
5189
|
+
return /* @__PURE__ */ jsx32(ProjectConfig, { onBack: goBack, width });
|
|
4862
5190
|
case "pipeline-list":
|
|
4863
|
-
return /* @__PURE__ */
|
|
5191
|
+
return /* @__PURE__ */ jsx32(PipelineList, { onNavigate: navigate, onBack: goBack, width });
|
|
4864
5192
|
case "pipeline-builder":
|
|
4865
|
-
return /* @__PURE__ */
|
|
5193
|
+
return /* @__PURE__ */ jsx32(PipelineBuilder, { onBack: goBack, width, height });
|
|
4866
5194
|
case "pipeline-execution":
|
|
4867
|
-
return /* @__PURE__ */
|
|
5195
|
+
return /* @__PURE__ */ jsx32(
|
|
4868
5196
|
PipelineExecution,
|
|
4869
5197
|
{
|
|
4870
5198
|
pipelineId: params.pipelineId ?? "",
|
|
@@ -4874,32 +5202,34 @@ function AppClassic() {
|
|
|
4874
5202
|
}
|
|
4875
5203
|
);
|
|
4876
5204
|
case "declarative-plan":
|
|
4877
|
-
return /* @__PURE__ */
|
|
5205
|
+
return /* @__PURE__ */ jsx32(DeclarativePlan, { onBack: goBack, onNavigate: navigate, width, height });
|
|
4878
5206
|
case "declarative-status":
|
|
4879
|
-
return /* @__PURE__ */
|
|
5207
|
+
return /* @__PURE__ */ jsx32(DeclarativeStatus, { onBack: goBack, width, height });
|
|
4880
5208
|
case "init-scaffold":
|
|
4881
|
-
return /* @__PURE__ */
|
|
5209
|
+
return /* @__PURE__ */ jsx32(InitScaffold, { onBack: goBack, onNavigate: navigate, width, height });
|
|
5210
|
+
case "script-picker":
|
|
5211
|
+
return /* @__PURE__ */ jsx32(ScriptPicker, { onNavigate: navigate, onBack: goBack, width, height });
|
|
4882
5212
|
default:
|
|
4883
|
-
return /* @__PURE__ */
|
|
5213
|
+
return /* @__PURE__ */ jsx32(Box29, { children: /* @__PURE__ */ jsxs31(Text33, { color: "red", children: [
|
|
4884
5214
|
"Unknown screen: ",
|
|
4885
5215
|
screen
|
|
4886
5216
|
] }) });
|
|
4887
5217
|
}
|
|
4888
5218
|
};
|
|
4889
|
-
return /* @__PURE__ */
|
|
4890
|
-
/* @__PURE__ */
|
|
5219
|
+
return /* @__PURE__ */ jsxs31(Box29, { flexDirection: "column", children: [
|
|
5220
|
+
/* @__PURE__ */ jsx32(GhostBanner, { width }),
|
|
4891
5221
|
renderScreen()
|
|
4892
5222
|
] });
|
|
4893
5223
|
}
|
|
4894
5224
|
|
|
4895
5225
|
// src/appPanel.tsx
|
|
4896
|
-
import
|
|
4897
|
-
import { Box as
|
|
5226
|
+
import React27 from "react";
|
|
5227
|
+
import { Box as Box38, Text as Text40, useApp as useApp2, useInput as useInput13 } from "ink";
|
|
4898
5228
|
|
|
4899
5229
|
// src/hooks/usePanelNavigation.ts
|
|
4900
|
-
import { useState as
|
|
5230
|
+
import { useState as useState26, useCallback as useCallback8 } from "react";
|
|
4901
5231
|
function usePanelNavigation() {
|
|
4902
|
-
const [state, setState] =
|
|
5232
|
+
const [state, setState] = useState26({
|
|
4903
5233
|
view: "pipelines",
|
|
4904
5234
|
featureId: "database",
|
|
4905
5235
|
innerScreen: "home",
|
|
@@ -4937,6 +5267,7 @@ function usePanelNavigation() {
|
|
|
4937
5267
|
config: "config",
|
|
4938
5268
|
"self-update": "self-update",
|
|
4939
5269
|
processes: "processes",
|
|
5270
|
+
scripts: "scripts",
|
|
4940
5271
|
declarative: "declarative"
|
|
4941
5272
|
};
|
|
4942
5273
|
const view = viewMap[itemId];
|
|
@@ -5004,9 +5335,9 @@ function usePanelNavigation() {
|
|
|
5004
5335
|
}
|
|
5005
5336
|
|
|
5006
5337
|
// src/hooks/usePanelFocus.ts
|
|
5007
|
-
import { useState as
|
|
5338
|
+
import { useState as useState27, useCallback as useCallback9 } from "react";
|
|
5008
5339
|
function usePanelFocus() {
|
|
5009
|
-
const [focused, setFocused] =
|
|
5340
|
+
const [focused, setFocused] = useState27("sidebar");
|
|
5010
5341
|
const toggleFocus = useCallback9(() => {
|
|
5011
5342
|
setFocused((prev) => prev === "sidebar" ? "main" : "sidebar");
|
|
5012
5343
|
}, []);
|
|
@@ -5023,15 +5354,16 @@ function usePanelFocus() {
|
|
|
5023
5354
|
}
|
|
5024
5355
|
|
|
5025
5356
|
// src/hooks/useSidebarItems.ts
|
|
5026
|
-
import { useMemo as
|
|
5357
|
+
import { useMemo as useMemo9 } from "react";
|
|
5027
5358
|
function useSidebarItems() {
|
|
5028
|
-
return
|
|
5359
|
+
return useMemo9(() => {
|
|
5029
5360
|
const items = [];
|
|
5030
5361
|
items.push({ id: "__sep_workflows__", label: "---", icon: "", type: "separator", sectionTitle: "Workflows" });
|
|
5031
5362
|
items.push({ id: "pipelines", label: "Pipelines", icon: "\u{1F517}", type: "action", section: "workflows" });
|
|
5032
5363
|
items.push({ id: "pinned", label: "Pinned", icon: "\u{1F4CC}", type: "action", section: "workflows" });
|
|
5033
5364
|
items.push({ id: "custom-command", label: "Custom Cmd", icon: "\u270F\uFE0F", type: "action", section: "workflows" });
|
|
5034
5365
|
items.push({ id: "processes", label: "Processes", icon: "\u{1F4BB}", type: "action", section: "workflows" });
|
|
5366
|
+
items.push({ id: "scripts", label: "Scripts", icon: "\u{1F4DC}", type: "action", section: "workflows" });
|
|
5035
5367
|
items.push({ id: "__sep_features__", label: "---", icon: "", type: "separator", sectionTitle: "Features" });
|
|
5036
5368
|
for (const feature of features) {
|
|
5037
5369
|
items.push({
|
|
@@ -5052,9 +5384,9 @@ function useSidebarItems() {
|
|
|
5052
5384
|
}
|
|
5053
5385
|
|
|
5054
5386
|
// src/hooks/useModal.ts
|
|
5055
|
-
import { useState as
|
|
5387
|
+
import { useState as useState28, useCallback as useCallback10 } from "react";
|
|
5056
5388
|
function useModal() {
|
|
5057
|
-
const [state, setState] =
|
|
5389
|
+
const [state, setState] = useState28(null);
|
|
5058
5390
|
const openModal = useCallback10((content, title) => {
|
|
5059
5391
|
setState({ content, title });
|
|
5060
5392
|
}, []);
|
|
@@ -5071,8 +5403,8 @@ function useModal() {
|
|
|
5071
5403
|
}
|
|
5072
5404
|
|
|
5073
5405
|
// src/components/PanelLayout.tsx
|
|
5074
|
-
import { Box as
|
|
5075
|
-
import { jsx as
|
|
5406
|
+
import { Box as Box30 } from "ink";
|
|
5407
|
+
import { jsx as jsx33, jsxs as jsxs32 } from "react/jsx-runtime";
|
|
5076
5408
|
function PanelLayout({
|
|
5077
5409
|
header,
|
|
5078
5410
|
footer,
|
|
@@ -5087,19 +5419,19 @@ function PanelLayout({
|
|
|
5087
5419
|
const contentHeight = Math.max(5, height - bannerHeight - footerHeight);
|
|
5088
5420
|
const sidebarWidth = singlePanel ? 0 : panel.sidebarWidth(width);
|
|
5089
5421
|
const mainWidth = singlePanel ? width : width - sidebarWidth;
|
|
5090
|
-
return /* @__PURE__ */
|
|
5422
|
+
return /* @__PURE__ */ jsxs32(Box30, { flexDirection: "column", width, height, children: [
|
|
5091
5423
|
header,
|
|
5092
|
-
/* @__PURE__ */
|
|
5093
|
-
!singlePanel && /* @__PURE__ */
|
|
5094
|
-
/* @__PURE__ */
|
|
5424
|
+
/* @__PURE__ */ jsxs32(Box30, { flexDirection: "row", height: contentHeight, children: [
|
|
5425
|
+
!singlePanel && /* @__PURE__ */ jsx33(Box30, { width: sidebarWidth, height: contentHeight, children: sidebar }),
|
|
5426
|
+
/* @__PURE__ */ jsx33(Box30, { width: mainWidth, height: contentHeight, children: main2 })
|
|
5095
5427
|
] }),
|
|
5096
|
-
/* @__PURE__ */
|
|
5428
|
+
/* @__PURE__ */ jsx33(Box30, { height: footerHeight, children: footer })
|
|
5097
5429
|
] });
|
|
5098
5430
|
}
|
|
5099
5431
|
|
|
5100
5432
|
// src/components/Panel.tsx
|
|
5101
|
-
import { Box as
|
|
5102
|
-
import { jsx as
|
|
5433
|
+
import { Box as Box31, Text as Text34 } from "ink";
|
|
5434
|
+
import { jsx as jsx34, jsxs as jsxs33 } from "react/jsx-runtime";
|
|
5103
5435
|
function Panel({
|
|
5104
5436
|
id,
|
|
5105
5437
|
title,
|
|
@@ -5109,8 +5441,8 @@ function Panel({
|
|
|
5109
5441
|
children
|
|
5110
5442
|
}) {
|
|
5111
5443
|
const borderColor = focused ? panel.borderFocused : panel.borderDim;
|
|
5112
|
-
return /* @__PURE__ */
|
|
5113
|
-
|
|
5444
|
+
return /* @__PURE__ */ jsxs33(
|
|
5445
|
+
Box31,
|
|
5114
5446
|
{
|
|
5115
5447
|
flexDirection: "column",
|
|
5116
5448
|
width,
|
|
@@ -5119,21 +5451,21 @@ function Panel({
|
|
|
5119
5451
|
borderColor,
|
|
5120
5452
|
overflow: "hidden",
|
|
5121
5453
|
children: [
|
|
5122
|
-
title && /* @__PURE__ */
|
|
5454
|
+
title && /* @__PURE__ */ jsx34(Box31, { marginBottom: 0, children: /* @__PURE__ */ jsxs33(Text34, { color: focused ? inkColors.accent : void 0, bold: focused, dimColor: !focused, children: [
|
|
5123
5455
|
" ",
|
|
5124
5456
|
title,
|
|
5125
5457
|
" "
|
|
5126
5458
|
] }) }),
|
|
5127
|
-
/* @__PURE__ */
|
|
5459
|
+
/* @__PURE__ */ jsx34(Box31, { flexDirection: "column", flexGrow: 1, overflow: "hidden", children })
|
|
5128
5460
|
]
|
|
5129
5461
|
}
|
|
5130
5462
|
);
|
|
5131
5463
|
}
|
|
5132
5464
|
|
|
5133
5465
|
// src/components/Sidebar.tsx
|
|
5134
|
-
import { useEffect as
|
|
5135
|
-
import { Box as
|
|
5136
|
-
import { jsx as
|
|
5466
|
+
import { useEffect as useEffect19, useMemo as useMemo10, useState as useState29 } from "react";
|
|
5467
|
+
import { Box as Box32, Text as Text35, useInput as useInput12 } from "ink";
|
|
5468
|
+
import { jsx as jsx35, jsxs as jsxs34 } from "react/jsx-runtime";
|
|
5137
5469
|
function groupSections(items) {
|
|
5138
5470
|
const groups = [];
|
|
5139
5471
|
let current = null;
|
|
@@ -5155,18 +5487,18 @@ function Sidebar({
|
|
|
5155
5487
|
onSelect,
|
|
5156
5488
|
onHighlight
|
|
5157
5489
|
}) {
|
|
5158
|
-
const selectableItems =
|
|
5490
|
+
const selectableItems = useMemo10(
|
|
5159
5491
|
() => items.filter((item) => item.type !== "separator"),
|
|
5160
5492
|
[items]
|
|
5161
5493
|
);
|
|
5162
5494
|
const selectedIdx = selectableItems.findIndex((item) => item.id === selectedId);
|
|
5163
|
-
const [cursorIdx, setCursorIdx] =
|
|
5164
|
-
const sections =
|
|
5165
|
-
|
|
5495
|
+
const [cursorIdx, setCursorIdx] = useState29(Math.max(0, selectedIdx));
|
|
5496
|
+
const sections = useMemo10(() => groupSections(items), [items]);
|
|
5497
|
+
useEffect19(() => {
|
|
5166
5498
|
const idx = selectableItems.findIndex((item) => item.id === selectedId);
|
|
5167
5499
|
if (idx >= 0) setCursorIdx(idx);
|
|
5168
5500
|
}, [selectedId, selectableItems]);
|
|
5169
|
-
|
|
5501
|
+
useInput12(
|
|
5170
5502
|
(input2, key) => {
|
|
5171
5503
|
if (key.upArrow || input2 === "k") {
|
|
5172
5504
|
setCursorIdx((prev) => {
|
|
@@ -5194,28 +5526,28 @@ function Sidebar({
|
|
|
5194
5526
|
{ isActive: isFocused }
|
|
5195
5527
|
);
|
|
5196
5528
|
let flatIdx = 0;
|
|
5197
|
-
return /* @__PURE__ */
|
|
5529
|
+
return /* @__PURE__ */ jsx35(Box32, { flexDirection: "column", gap: 0, children: sections.map((section) => {
|
|
5198
5530
|
const sectionStartIdx = flatIdx;
|
|
5199
5531
|
const sectionEndIdx = sectionStartIdx + section.items.length - 1;
|
|
5200
5532
|
const hasCursorInSection = isFocused && cursorIdx >= sectionStartIdx && cursorIdx <= sectionEndIdx;
|
|
5201
5533
|
const hasActiveInSection = section.items.some((item) => item.id === selectedId);
|
|
5202
5534
|
const borderColor = hasCursorInSection || hasActiveInSection ? inkColors.accent : "#555555";
|
|
5203
|
-
const rendered = /* @__PURE__ */
|
|
5204
|
-
|
|
5535
|
+
const rendered = /* @__PURE__ */ jsxs34(
|
|
5536
|
+
Box32,
|
|
5205
5537
|
{
|
|
5206
5538
|
flexDirection: "column",
|
|
5207
5539
|
borderStyle: "round",
|
|
5208
5540
|
borderColor,
|
|
5209
5541
|
paddingX: 1,
|
|
5210
5542
|
children: [
|
|
5211
|
-
/* @__PURE__ */
|
|
5543
|
+
/* @__PURE__ */ jsx35(Text35, { dimColor: true, bold: true, children: section.title }),
|
|
5212
5544
|
section.items.map((item) => {
|
|
5213
5545
|
const thisIdx = flatIdx;
|
|
5214
5546
|
flatIdx++;
|
|
5215
5547
|
const isCursor = isFocused && thisIdx === cursorIdx;
|
|
5216
5548
|
const isActive = item.id === selectedId;
|
|
5217
|
-
return /* @__PURE__ */
|
|
5218
|
-
|
|
5549
|
+
return /* @__PURE__ */ jsx35(Box32, { gap: 0, children: /* @__PURE__ */ jsxs34(
|
|
5550
|
+
Text35,
|
|
5219
5551
|
{
|
|
5220
5552
|
color: isCursor ? inkColors.accent : isActive ? inkColors.accent : void 0,
|
|
5221
5553
|
bold: isCursor || isActive,
|
|
@@ -5238,12 +5570,12 @@ function Sidebar({
|
|
|
5238
5570
|
}
|
|
5239
5571
|
|
|
5240
5572
|
// src/components/PanelFooter.tsx
|
|
5241
|
-
import { Box as
|
|
5242
|
-
import { jsx as
|
|
5573
|
+
import { Box as Box33, Text as Text36 } from "ink";
|
|
5574
|
+
import { jsx as jsx36, jsxs as jsxs35 } from "react/jsx-runtime";
|
|
5243
5575
|
function PanelFooter({ hints, width }) {
|
|
5244
|
-
return /* @__PURE__ */
|
|
5245
|
-
/* @__PURE__ */
|
|
5246
|
-
/* @__PURE__ */
|
|
5576
|
+
return /* @__PURE__ */ jsx36(Box33, { width, children: /* @__PURE__ */ jsx36(Box33, { gap: 1, children: hints.map((hint) => /* @__PURE__ */ jsxs35(Box33, { gap: 0, children: [
|
|
5577
|
+
/* @__PURE__ */ jsx36(Text36, { color: inkColors.accent, bold: true, children: hint.key }),
|
|
5578
|
+
/* @__PURE__ */ jsxs35(Text36, { dimColor: true, children: [
|
|
5247
5579
|
":",
|
|
5248
5580
|
hint.action
|
|
5249
5581
|
] })
|
|
@@ -5251,8 +5583,8 @@ function PanelFooter({ hints, width }) {
|
|
|
5251
5583
|
}
|
|
5252
5584
|
|
|
5253
5585
|
// src/components/Modal.tsx
|
|
5254
|
-
import { Box as
|
|
5255
|
-
import { jsx as
|
|
5586
|
+
import { Box as Box34, Text as Text37 } from "ink";
|
|
5587
|
+
import { jsx as jsx37, jsxs as jsxs36 } from "react/jsx-runtime";
|
|
5256
5588
|
function Modal({
|
|
5257
5589
|
title,
|
|
5258
5590
|
width,
|
|
@@ -5263,10 +5595,10 @@ function Modal({
|
|
|
5263
5595
|
const modalHeight = Math.min(height - 4, 20);
|
|
5264
5596
|
const padX = Math.max(0, Math.floor((width - modalWidth) / 2));
|
|
5265
5597
|
const padY = Math.max(0, Math.floor((height - modalHeight) / 2));
|
|
5266
|
-
return /* @__PURE__ */
|
|
5267
|
-
padY > 0 && /* @__PURE__ */
|
|
5268
|
-
/* @__PURE__ */
|
|
5269
|
-
|
|
5598
|
+
return /* @__PURE__ */ jsxs36(Box34, { flexDirection: "column", width, height, children: [
|
|
5599
|
+
padY > 0 && /* @__PURE__ */ jsx37(Box34, { height: padY }),
|
|
5600
|
+
/* @__PURE__ */ jsx37(Box34, { marginLeft: padX, children: /* @__PURE__ */ jsxs36(
|
|
5601
|
+
Box34,
|
|
5270
5602
|
{
|
|
5271
5603
|
flexDirection: "column",
|
|
5272
5604
|
width: modalWidth,
|
|
@@ -5275,8 +5607,8 @@ function Modal({
|
|
|
5275
5607
|
borderColor: inkColors.accent,
|
|
5276
5608
|
paddingX: 1,
|
|
5277
5609
|
children: [
|
|
5278
|
-
/* @__PURE__ */
|
|
5279
|
-
/* @__PURE__ */
|
|
5610
|
+
/* @__PURE__ */ jsx37(Box34, { marginBottom: 1, children: /* @__PURE__ */ jsx37(Text37, { color: inkColors.accent, bold: true, children: title }) }),
|
|
5611
|
+
/* @__PURE__ */ jsx37(Box34, { flexDirection: "column", flexGrow: 1, overflow: "hidden", children })
|
|
5280
5612
|
]
|
|
5281
5613
|
}
|
|
5282
5614
|
) })
|
|
@@ -5284,9 +5616,9 @@ function Modal({
|
|
|
5284
5616
|
}
|
|
5285
5617
|
|
|
5286
5618
|
// src/components/FeatureCommands.tsx
|
|
5287
|
-
import { useEffect as
|
|
5288
|
-
import { Box as
|
|
5289
|
-
import { jsx as
|
|
5619
|
+
import { useEffect as useEffect20, useMemo as useMemo11, useState as useState30 } from "react";
|
|
5620
|
+
import { Box as Box35, Text as Text38 } from "ink";
|
|
5621
|
+
import { jsx as jsx38, jsxs as jsxs37 } from "react/jsx-runtime";
|
|
5290
5622
|
function FeatureCommands({
|
|
5291
5623
|
feature,
|
|
5292
5624
|
onNavigate,
|
|
@@ -5297,15 +5629,15 @@ function FeatureCommands({
|
|
|
5297
5629
|
height = 24,
|
|
5298
5630
|
isInputActive = true
|
|
5299
5631
|
}) {
|
|
5300
|
-
const [pinnedCommands, setPinnedCommands2] =
|
|
5301
|
-
const [pinnedRuns, setPinnedRuns2] =
|
|
5302
|
-
const [pinFeedback, setPinFeedback] =
|
|
5303
|
-
|
|
5632
|
+
const [pinnedCommands, setPinnedCommands2] = useState30(() => getPinnedCommands());
|
|
5633
|
+
const [pinnedRuns, setPinnedRuns2] = useState30(() => getPinnedRuns());
|
|
5634
|
+
const [pinFeedback, setPinFeedback] = useState30();
|
|
5635
|
+
useEffect20(() => {
|
|
5304
5636
|
if (!pinFeedback) return;
|
|
5305
5637
|
const timeout = setTimeout(() => setPinFeedback(void 0), 1400);
|
|
5306
5638
|
return () => clearTimeout(timeout);
|
|
5307
5639
|
}, [pinFeedback]);
|
|
5308
|
-
const items =
|
|
5640
|
+
const items = useMemo11(
|
|
5309
5641
|
() => buildHomeItems({
|
|
5310
5642
|
activeFeature: feature,
|
|
5311
5643
|
pinnedCommands,
|
|
@@ -5315,8 +5647,8 @@ function FeatureCommands({
|
|
|
5315
5647
|
}),
|
|
5316
5648
|
[feature, pinnedCommands, pinnedRuns]
|
|
5317
5649
|
);
|
|
5318
|
-
const pinnedCommandSet =
|
|
5319
|
-
const pinnedRunSet =
|
|
5650
|
+
const pinnedCommandSet = useMemo11(() => new Set(pinnedCommands), [pinnedCommands]);
|
|
5651
|
+
const pinnedRunSet = useMemo11(() => new Set(pinnedRuns), [pinnedRuns]);
|
|
5320
5652
|
const refreshPins = () => {
|
|
5321
5653
|
setPinnedCommands2(getPinnedCommands());
|
|
5322
5654
|
setPinnedRuns2(getPinnedRuns());
|
|
@@ -5368,12 +5700,12 @@ function FeatureCommands({
|
|
|
5368
5700
|
);
|
|
5369
5701
|
}
|
|
5370
5702
|
};
|
|
5371
|
-
return /* @__PURE__ */
|
|
5372
|
-
pinFeedback && /* @__PURE__ */
|
|
5703
|
+
return /* @__PURE__ */ jsxs37(Box35, { flexDirection: "column", paddingX: 1, children: [
|
|
5704
|
+
pinFeedback && /* @__PURE__ */ jsx38(Box35, { marginBottom: 1, children: /* @__PURE__ */ jsxs37(Text38, { color: inkColors.accent, children: [
|
|
5373
5705
|
"\u2713 ",
|
|
5374
5706
|
pinFeedback
|
|
5375
5707
|
] }) }),
|
|
5376
|
-
/* @__PURE__ */
|
|
5708
|
+
/* @__PURE__ */ jsx38(
|
|
5377
5709
|
SelectList,
|
|
5378
5710
|
{
|
|
5379
5711
|
items,
|
|
@@ -5392,9 +5724,9 @@ function FeatureCommands({
|
|
|
5392
5724
|
}
|
|
5393
5725
|
|
|
5394
5726
|
// src/components/PinnedCommands.tsx
|
|
5395
|
-
import { useEffect as
|
|
5396
|
-
import { Box as
|
|
5397
|
-
import { jsx as
|
|
5727
|
+
import { useEffect as useEffect21, useMemo as useMemo12, useState as useState31 } from "react";
|
|
5728
|
+
import { Box as Box36, Text as Text39 } from "ink";
|
|
5729
|
+
import { jsx as jsx39, jsxs as jsxs38 } from "react/jsx-runtime";
|
|
5398
5730
|
function PinnedCommands({
|
|
5399
5731
|
onNavigate,
|
|
5400
5732
|
onBack,
|
|
@@ -5403,20 +5735,20 @@ function PinnedCommands({
|
|
|
5403
5735
|
height = 24,
|
|
5404
5736
|
isInputActive = true
|
|
5405
5737
|
}) {
|
|
5406
|
-
const [pinnedCommands, setPinnedCommands2] =
|
|
5407
|
-
const [pinnedRuns, setPinnedRuns2] =
|
|
5408
|
-
const [pinFeedback, setPinFeedback] =
|
|
5409
|
-
|
|
5738
|
+
const [pinnedCommands, setPinnedCommands2] = useState31(() => getPinnedCommands());
|
|
5739
|
+
const [pinnedRuns, setPinnedRuns2] = useState31(() => getPinnedRuns());
|
|
5740
|
+
const [pinFeedback, setPinFeedback] = useState31();
|
|
5741
|
+
useEffect21(() => {
|
|
5410
5742
|
if (!pinFeedback) return;
|
|
5411
5743
|
const timeout = setTimeout(() => setPinFeedback(void 0), 1400);
|
|
5412
5744
|
return () => clearTimeout(timeout);
|
|
5413
5745
|
}, [pinFeedback]);
|
|
5414
|
-
const items =
|
|
5746
|
+
const items = useMemo12(
|
|
5415
5747
|
() => buildPinnedOnlyItems(pinnedCommands, pinnedRuns),
|
|
5416
5748
|
[pinnedCommands, pinnedRuns]
|
|
5417
5749
|
);
|
|
5418
|
-
const pinnedCommandSet =
|
|
5419
|
-
const pinnedRunSet =
|
|
5750
|
+
const pinnedCommandSet = useMemo12(() => new Set(pinnedCommands), [pinnedCommands]);
|
|
5751
|
+
const pinnedRunSet = useMemo12(() => new Set(pinnedRuns), [pinnedRuns]);
|
|
5420
5752
|
const refreshPins = () => {
|
|
5421
5753
|
setPinnedCommands2(getPinnedCommands());
|
|
5422
5754
|
setPinnedRuns2(getPinnedRuns());
|
|
@@ -5468,14 +5800,14 @@ function PinnedCommands({
|
|
|
5468
5800
|
}
|
|
5469
5801
|
};
|
|
5470
5802
|
if (items.length === 0) {
|
|
5471
|
-
return /* @__PURE__ */
|
|
5803
|
+
return /* @__PURE__ */ jsx39(Box36, { flexDirection: "column", paddingX: 1, children: /* @__PURE__ */ jsx39(Text39, { color: "gray", children: "No pinned items. Press p on any command to pin it." }) });
|
|
5472
5804
|
}
|
|
5473
|
-
return /* @__PURE__ */
|
|
5474
|
-
pinFeedback && /* @__PURE__ */
|
|
5805
|
+
return /* @__PURE__ */ jsxs38(Box36, { flexDirection: "column", paddingX: 1, children: [
|
|
5806
|
+
pinFeedback && /* @__PURE__ */ jsx39(Box36, { marginBottom: 1, children: /* @__PURE__ */ jsxs38(Text39, { color: inkColors.accent, children: [
|
|
5475
5807
|
"\u2713 ",
|
|
5476
5808
|
pinFeedback
|
|
5477
5809
|
] }) }),
|
|
5478
|
-
/* @__PURE__ */
|
|
5810
|
+
/* @__PURE__ */ jsx39(
|
|
5479
5811
|
SelectList,
|
|
5480
5812
|
{
|
|
5481
5813
|
items,
|
|
@@ -5494,9 +5826,9 @@ function PinnedCommands({
|
|
|
5494
5826
|
}
|
|
5495
5827
|
|
|
5496
5828
|
// src/screens/DeclarativeHome.tsx
|
|
5497
|
-
import { useMemo as
|
|
5498
|
-
import { Box as
|
|
5499
|
-
import { jsx as
|
|
5829
|
+
import { useMemo as useMemo13 } from "react";
|
|
5830
|
+
import { Box as Box37 } from "ink";
|
|
5831
|
+
import { jsx as jsx40 } from "react/jsx-runtime";
|
|
5500
5832
|
var ITEMS = [
|
|
5501
5833
|
{ value: "declarative-plan", label: "Plan / Apply", hint: "Diff and apply polter.yaml", kind: "action" },
|
|
5502
5834
|
{ value: "declarative-status", label: "Infrastructure Status", hint: "Live state from CLI tools", kind: "action" },
|
|
@@ -5509,11 +5841,11 @@ function DeclarativeHome({
|
|
|
5509
5841
|
height = 24,
|
|
5510
5842
|
isInputActive = true
|
|
5511
5843
|
}) {
|
|
5512
|
-
const handleSelect =
|
|
5844
|
+
const handleSelect = useMemo13(
|
|
5513
5845
|
() => (value) => onNavigate(value),
|
|
5514
5846
|
[onNavigate]
|
|
5515
5847
|
);
|
|
5516
|
-
return /* @__PURE__ */
|
|
5848
|
+
return /* @__PURE__ */ jsx40(Box37, { flexDirection: "column", paddingX: 1, children: /* @__PURE__ */ jsx40(
|
|
5517
5849
|
SelectList,
|
|
5518
5850
|
{
|
|
5519
5851
|
items: ITEMS,
|
|
@@ -5529,7 +5861,7 @@ function DeclarativeHome({
|
|
|
5529
5861
|
}
|
|
5530
5862
|
|
|
5531
5863
|
// src/appPanel.tsx
|
|
5532
|
-
import { jsx as
|
|
5864
|
+
import { jsx as jsx41, jsxs as jsxs39 } from "react/jsx-runtime";
|
|
5533
5865
|
var screenLabels = {
|
|
5534
5866
|
"command-args": "Args",
|
|
5535
5867
|
"flag-selection": "Flags",
|
|
@@ -5547,7 +5879,8 @@ var screenLabels = {
|
|
|
5547
5879
|
"process-logs": "Logs",
|
|
5548
5880
|
"declarative-plan": "Plan/Apply",
|
|
5549
5881
|
"declarative-status": "Status",
|
|
5550
|
-
"init-scaffold": "Init"
|
|
5882
|
+
"init-scaffold": "Init",
|
|
5883
|
+
"script-picker": "Scripts"
|
|
5551
5884
|
};
|
|
5552
5885
|
function buildBreadcrumb(nav) {
|
|
5553
5886
|
let base;
|
|
@@ -5578,6 +5911,9 @@ function buildBreadcrumb(nav) {
|
|
|
5578
5911
|
case "processes":
|
|
5579
5912
|
base = "\u{1F4BB} Processes";
|
|
5580
5913
|
break;
|
|
5914
|
+
case "scripts":
|
|
5915
|
+
base = "\u{1F4DC} Scripts";
|
|
5916
|
+
break;
|
|
5581
5917
|
case "declarative":
|
|
5582
5918
|
base = "\u{1F3D7}\uFE0F Infrastructure";
|
|
5583
5919
|
break;
|
|
@@ -5613,7 +5949,7 @@ function AppPanel() {
|
|
|
5613
5949
|
const focus = usePanelFocus();
|
|
5614
5950
|
const sidebarItems = useSidebarItems();
|
|
5615
5951
|
const modal = useModal();
|
|
5616
|
-
const refreshPins =
|
|
5952
|
+
const refreshPins = React27.useCallback(() => {
|
|
5617
5953
|
}, []);
|
|
5618
5954
|
const singlePanel = width < 60 || height < 15;
|
|
5619
5955
|
const handleExit = () => {
|
|
@@ -5622,7 +5958,7 @@ function AppPanel() {
|
|
|
5622
5958
|
);
|
|
5623
5959
|
exit();
|
|
5624
5960
|
};
|
|
5625
|
-
|
|
5961
|
+
useInput13((input2, key) => {
|
|
5626
5962
|
if (modal.isOpen) {
|
|
5627
5963
|
if (key.escape || input2 === "q") {
|
|
5628
5964
|
modal.closeModal();
|
|
@@ -5647,37 +5983,37 @@ function AppPanel() {
|
|
|
5647
5983
|
}
|
|
5648
5984
|
if (input2 === "?") {
|
|
5649
5985
|
modal.openModal(
|
|
5650
|
-
/* @__PURE__ */
|
|
5651
|
-
/* @__PURE__ */
|
|
5652
|
-
/* @__PURE__ */
|
|
5986
|
+
/* @__PURE__ */ jsxs39(Box38, { flexDirection: "column", children: [
|
|
5987
|
+
/* @__PURE__ */ jsxs39(Text40, { children: [
|
|
5988
|
+
/* @__PURE__ */ jsx41(Text40, { bold: true, children: "\u2190/\u2192" }),
|
|
5653
5989
|
" Move between sidebar and main panel"
|
|
5654
5990
|
] }),
|
|
5655
|
-
/* @__PURE__ */
|
|
5656
|
-
/* @__PURE__ */
|
|
5991
|
+
/* @__PURE__ */ jsxs39(Text40, { children: [
|
|
5992
|
+
/* @__PURE__ */ jsx41(Text40, { bold: true, children: "Tab" }),
|
|
5657
5993
|
" Toggle sidebar / main panel"
|
|
5658
5994
|
] }),
|
|
5659
|
-
/* @__PURE__ */
|
|
5660
|
-
/* @__PURE__ */
|
|
5995
|
+
/* @__PURE__ */ jsxs39(Text40, { children: [
|
|
5996
|
+
/* @__PURE__ */ jsx41(Text40, { bold: true, children: "j/k" }),
|
|
5661
5997
|
" Navigate up/down"
|
|
5662
5998
|
] }),
|
|
5663
|
-
/* @__PURE__ */
|
|
5664
|
-
/* @__PURE__ */
|
|
5999
|
+
/* @__PURE__ */ jsxs39(Text40, { children: [
|
|
6000
|
+
/* @__PURE__ */ jsx41(Text40, { bold: true, children: "Enter" }),
|
|
5665
6001
|
" Select item"
|
|
5666
6002
|
] }),
|
|
5667
|
-
/* @__PURE__ */
|
|
5668
|
-
/* @__PURE__ */
|
|
6003
|
+
/* @__PURE__ */ jsxs39(Text40, { children: [
|
|
6004
|
+
/* @__PURE__ */ jsx41(Text40, { bold: true, children: "Esc" }),
|
|
5669
6005
|
" Go back (or return to sidebar)"
|
|
5670
6006
|
] }),
|
|
5671
|
-
/* @__PURE__ */
|
|
5672
|
-
/* @__PURE__ */
|
|
6007
|
+
/* @__PURE__ */ jsxs39(Text40, { children: [
|
|
6008
|
+
/* @__PURE__ */ jsx41(Text40, { bold: true, children: "q" }),
|
|
5673
6009
|
" Quit Polter"
|
|
5674
6010
|
] }),
|
|
5675
|
-
/* @__PURE__ */
|
|
5676
|
-
/* @__PURE__ */
|
|
6011
|
+
/* @__PURE__ */ jsxs39(Text40, { children: [
|
|
6012
|
+
/* @__PURE__ */ jsx41(Text40, { bold: true, children: "?" }),
|
|
5677
6013
|
" Show this help"
|
|
5678
6014
|
] }),
|
|
5679
|
-
/* @__PURE__ */
|
|
5680
|
-
/* @__PURE__ */
|
|
6015
|
+
/* @__PURE__ */ jsxs39(Text40, { children: [
|
|
6016
|
+
/* @__PURE__ */ jsx41(Text40, { bold: true, children: "p" }),
|
|
5681
6017
|
" Pin/unpin command"
|
|
5682
6018
|
] })
|
|
5683
6019
|
] }),
|
|
@@ -5703,6 +6039,8 @@ function AppPanel() {
|
|
|
5703
6039
|
return "self-update";
|
|
5704
6040
|
case "processes":
|
|
5705
6041
|
return "processes";
|
|
6042
|
+
case "scripts":
|
|
6043
|
+
return "scripts";
|
|
5706
6044
|
case "declarative":
|
|
5707
6045
|
return "declarative";
|
|
5708
6046
|
default:
|
|
@@ -5721,7 +6059,7 @@ function AppPanel() {
|
|
|
5721
6059
|
nav.selectSidebarItem(itemId);
|
|
5722
6060
|
focus.focusMain();
|
|
5723
6061
|
};
|
|
5724
|
-
const bannerHeight = width < 60 ?
|
|
6062
|
+
const bannerHeight = width < 60 ? 6 : 10;
|
|
5725
6063
|
const footerHints = FOOTER_HINTS;
|
|
5726
6064
|
const mainContentHeight = Math.max(5, height - bannerHeight - 1 - 2);
|
|
5727
6065
|
const mainContentWidth = singlePanel ? width : width - Math.max(20, Math.min(35, Math.floor(width * 0.3)));
|
|
@@ -5731,7 +6069,7 @@ function AppPanel() {
|
|
|
5731
6069
|
}
|
|
5732
6070
|
switch (nav.view) {
|
|
5733
6071
|
case "pinned":
|
|
5734
|
-
return /* @__PURE__ */
|
|
6072
|
+
return /* @__PURE__ */ jsx41(
|
|
5735
6073
|
PinnedCommands,
|
|
5736
6074
|
{
|
|
5737
6075
|
onNavigate: nav.navigateInner,
|
|
@@ -5745,12 +6083,12 @@ function AppPanel() {
|
|
|
5745
6083
|
case "feature": {
|
|
5746
6084
|
const feature = getFeatureById(nav.featureId);
|
|
5747
6085
|
if (!feature) {
|
|
5748
|
-
return /* @__PURE__ */
|
|
6086
|
+
return /* @__PURE__ */ jsxs39(Text40, { color: "red", children: [
|
|
5749
6087
|
"Feature not found: ",
|
|
5750
6088
|
nav.featureId
|
|
5751
6089
|
] });
|
|
5752
6090
|
}
|
|
5753
|
-
return /* @__PURE__ */
|
|
6091
|
+
return /* @__PURE__ */ jsx41(
|
|
5754
6092
|
FeatureCommands,
|
|
5755
6093
|
{
|
|
5756
6094
|
feature,
|
|
@@ -5765,7 +6103,7 @@ function AppPanel() {
|
|
|
5765
6103
|
);
|
|
5766
6104
|
}
|
|
5767
6105
|
case "custom-command":
|
|
5768
|
-
return /* @__PURE__ */
|
|
6106
|
+
return /* @__PURE__ */ jsx41(
|
|
5769
6107
|
CustomCommand,
|
|
5770
6108
|
{
|
|
5771
6109
|
onNavigate: nav.navigateInner,
|
|
@@ -5777,7 +6115,7 @@ function AppPanel() {
|
|
|
5777
6115
|
}
|
|
5778
6116
|
);
|
|
5779
6117
|
case "pipelines":
|
|
5780
|
-
return /* @__PURE__ */
|
|
6118
|
+
return /* @__PURE__ */ jsx41(
|
|
5781
6119
|
PipelineList,
|
|
5782
6120
|
{
|
|
5783
6121
|
onNavigate: nav.navigateInner,
|
|
@@ -5789,7 +6127,7 @@ function AppPanel() {
|
|
|
5789
6127
|
}
|
|
5790
6128
|
);
|
|
5791
6129
|
case "tool-status":
|
|
5792
|
-
return /* @__PURE__ */
|
|
6130
|
+
return /* @__PURE__ */ jsx41(
|
|
5793
6131
|
ToolStatus,
|
|
5794
6132
|
{
|
|
5795
6133
|
onBack: focus.focusSidebar,
|
|
@@ -5801,7 +6139,7 @@ function AppPanel() {
|
|
|
5801
6139
|
}
|
|
5802
6140
|
);
|
|
5803
6141
|
case "processes":
|
|
5804
|
-
return /* @__PURE__ */
|
|
6142
|
+
return /* @__PURE__ */ jsx41(
|
|
5805
6143
|
ProcessList,
|
|
5806
6144
|
{
|
|
5807
6145
|
onNavigate: nav.navigateInner,
|
|
@@ -5812,8 +6150,20 @@ function AppPanel() {
|
|
|
5812
6150
|
isInputActive: focus.isMainFocused
|
|
5813
6151
|
}
|
|
5814
6152
|
);
|
|
6153
|
+
case "scripts":
|
|
6154
|
+
return /* @__PURE__ */ jsx41(
|
|
6155
|
+
ScriptPicker,
|
|
6156
|
+
{
|
|
6157
|
+
onNavigate: nav.navigateInner,
|
|
6158
|
+
onBack: focus.focusSidebar,
|
|
6159
|
+
width: mainContentWidth - 2,
|
|
6160
|
+
height: mainContentHeight,
|
|
6161
|
+
panelMode: true,
|
|
6162
|
+
isInputActive: focus.isMainFocused
|
|
6163
|
+
}
|
|
6164
|
+
);
|
|
5815
6165
|
case "declarative":
|
|
5816
|
-
return /* @__PURE__ */
|
|
6166
|
+
return /* @__PURE__ */ jsx41(
|
|
5817
6167
|
DeclarativeHome,
|
|
5818
6168
|
{
|
|
5819
6169
|
onNavigate: nav.navigateInner,
|
|
@@ -5824,7 +6174,7 @@ function AppPanel() {
|
|
|
5824
6174
|
}
|
|
5825
6175
|
);
|
|
5826
6176
|
case "config":
|
|
5827
|
-
return /* @__PURE__ */
|
|
6177
|
+
return /* @__PURE__ */ jsx41(
|
|
5828
6178
|
ProjectConfig,
|
|
5829
6179
|
{
|
|
5830
6180
|
onBack: focus.focusSidebar,
|
|
@@ -5835,7 +6185,7 @@ function AppPanel() {
|
|
|
5835
6185
|
}
|
|
5836
6186
|
);
|
|
5837
6187
|
case "self-update":
|
|
5838
|
-
return /* @__PURE__ */
|
|
6188
|
+
return /* @__PURE__ */ jsx41(
|
|
5839
6189
|
SelfUpdate,
|
|
5840
6190
|
{
|
|
5841
6191
|
onBack: focus.focusSidebar,
|
|
@@ -5847,7 +6197,7 @@ function AppPanel() {
|
|
|
5847
6197
|
}
|
|
5848
6198
|
);
|
|
5849
6199
|
default:
|
|
5850
|
-
return /* @__PURE__ */
|
|
6200
|
+
return /* @__PURE__ */ jsx41(Text40, { children: "Select an item from the sidebar" });
|
|
5851
6201
|
}
|
|
5852
6202
|
};
|
|
5853
6203
|
const renderInnerScreen = () => {
|
|
@@ -5855,7 +6205,7 @@ function AppPanel() {
|
|
|
5855
6205
|
const w = mainContentWidth - 2;
|
|
5856
6206
|
switch (nav.innerScreen) {
|
|
5857
6207
|
case "command-args":
|
|
5858
|
-
return /* @__PURE__ */
|
|
6208
|
+
return /* @__PURE__ */ jsx41(
|
|
5859
6209
|
CommandArgs,
|
|
5860
6210
|
{
|
|
5861
6211
|
command: nav.innerParams.command ?? "",
|
|
@@ -5868,7 +6218,7 @@ function AppPanel() {
|
|
|
5868
6218
|
}
|
|
5869
6219
|
);
|
|
5870
6220
|
case "custom-command":
|
|
5871
|
-
return /* @__PURE__ */
|
|
6221
|
+
return /* @__PURE__ */ jsx41(
|
|
5872
6222
|
CustomCommand,
|
|
5873
6223
|
{
|
|
5874
6224
|
onNavigate: nav.navigateInner,
|
|
@@ -5880,7 +6230,7 @@ function AppPanel() {
|
|
|
5880
6230
|
}
|
|
5881
6231
|
);
|
|
5882
6232
|
case "flag-selection":
|
|
5883
|
-
return /* @__PURE__ */
|
|
6233
|
+
return /* @__PURE__ */ jsx41(
|
|
5884
6234
|
FlagSelection,
|
|
5885
6235
|
{
|
|
5886
6236
|
args: nav.innerParams.args ?? [],
|
|
@@ -5896,11 +6246,12 @@ function AppPanel() {
|
|
|
5896
6246
|
);
|
|
5897
6247
|
case "confirm-execute":
|
|
5898
6248
|
case "command-execution":
|
|
5899
|
-
return /* @__PURE__ */
|
|
6249
|
+
return /* @__PURE__ */ jsx41(
|
|
5900
6250
|
CommandExecution,
|
|
5901
6251
|
{
|
|
5902
6252
|
args: nav.innerParams.args ?? [],
|
|
5903
6253
|
tool: nav.innerParams.tool,
|
|
6254
|
+
rawCommand: nav.innerParams.rawCommand,
|
|
5904
6255
|
interactive: nav.innerParams.interactive,
|
|
5905
6256
|
onBack: nav.goBackInner,
|
|
5906
6257
|
onHome: nav.goHomeInner,
|
|
@@ -5916,7 +6267,7 @@ function AppPanel() {
|
|
|
5916
6267
|
`${nav.view}-${nav.innerParams.tool}-${(nav.innerParams.args ?? []).join("-")}`
|
|
5917
6268
|
);
|
|
5918
6269
|
case "pipeline-list":
|
|
5919
|
-
return /* @__PURE__ */
|
|
6270
|
+
return /* @__PURE__ */ jsx41(
|
|
5920
6271
|
PipelineList,
|
|
5921
6272
|
{
|
|
5922
6273
|
onNavigate: nav.navigateInner,
|
|
@@ -5928,7 +6279,7 @@ function AppPanel() {
|
|
|
5928
6279
|
}
|
|
5929
6280
|
);
|
|
5930
6281
|
case "pipeline-builder":
|
|
5931
|
-
return /* @__PURE__ */
|
|
6282
|
+
return /* @__PURE__ */ jsx41(
|
|
5932
6283
|
PipelineBuilder,
|
|
5933
6284
|
{
|
|
5934
6285
|
onBack: nav.goBackInner,
|
|
@@ -5939,7 +6290,7 @@ function AppPanel() {
|
|
|
5939
6290
|
}
|
|
5940
6291
|
);
|
|
5941
6292
|
case "pipeline-execution":
|
|
5942
|
-
return /* @__PURE__ */
|
|
6293
|
+
return /* @__PURE__ */ jsx41(
|
|
5943
6294
|
PipelineExecution,
|
|
5944
6295
|
{
|
|
5945
6296
|
pipelineId: nav.innerParams.pipelineId ?? "",
|
|
@@ -5951,7 +6302,7 @@ function AppPanel() {
|
|
|
5951
6302
|
}
|
|
5952
6303
|
);
|
|
5953
6304
|
case "self-update":
|
|
5954
|
-
return /* @__PURE__ */
|
|
6305
|
+
return /* @__PURE__ */ jsx41(
|
|
5955
6306
|
SelfUpdate,
|
|
5956
6307
|
{
|
|
5957
6308
|
onBack: nav.goBackInner,
|
|
@@ -5963,7 +6314,7 @@ function AppPanel() {
|
|
|
5963
6314
|
}
|
|
5964
6315
|
);
|
|
5965
6316
|
case "tool-status":
|
|
5966
|
-
return /* @__PURE__ */
|
|
6317
|
+
return /* @__PURE__ */ jsx41(
|
|
5967
6318
|
ToolStatus,
|
|
5968
6319
|
{
|
|
5969
6320
|
onBack: nav.goBackInner,
|
|
@@ -5975,7 +6326,7 @@ function AppPanel() {
|
|
|
5975
6326
|
}
|
|
5976
6327
|
);
|
|
5977
6328
|
case "mcp-manage":
|
|
5978
|
-
return /* @__PURE__ */
|
|
6329
|
+
return /* @__PURE__ */ jsx41(
|
|
5979
6330
|
McpManage,
|
|
5980
6331
|
{
|
|
5981
6332
|
onBack: nav.goBackInner,
|
|
@@ -5986,7 +6337,7 @@ function AppPanel() {
|
|
|
5986
6337
|
}
|
|
5987
6338
|
);
|
|
5988
6339
|
case "process-list":
|
|
5989
|
-
return /* @__PURE__ */
|
|
6340
|
+
return /* @__PURE__ */ jsx41(
|
|
5990
6341
|
ProcessList,
|
|
5991
6342
|
{
|
|
5992
6343
|
onNavigate: nav.navigateInner,
|
|
@@ -5998,7 +6349,7 @@ function AppPanel() {
|
|
|
5998
6349
|
}
|
|
5999
6350
|
);
|
|
6000
6351
|
case "process-logs":
|
|
6001
|
-
return /* @__PURE__ */
|
|
6352
|
+
return /* @__PURE__ */ jsx41(
|
|
6002
6353
|
ProcessLogs,
|
|
6003
6354
|
{
|
|
6004
6355
|
processId: nav.innerParams.processId ?? "",
|
|
@@ -6010,7 +6361,7 @@ function AppPanel() {
|
|
|
6010
6361
|
}
|
|
6011
6362
|
);
|
|
6012
6363
|
case "project-config":
|
|
6013
|
-
return /* @__PURE__ */
|
|
6364
|
+
return /* @__PURE__ */ jsx41(
|
|
6014
6365
|
ProjectConfig,
|
|
6015
6366
|
{
|
|
6016
6367
|
onBack: nav.goBackInner,
|
|
@@ -6021,7 +6372,7 @@ function AppPanel() {
|
|
|
6021
6372
|
}
|
|
6022
6373
|
);
|
|
6023
6374
|
case "declarative-plan":
|
|
6024
|
-
return /* @__PURE__ */
|
|
6375
|
+
return /* @__PURE__ */ jsx41(
|
|
6025
6376
|
DeclarativePlan,
|
|
6026
6377
|
{
|
|
6027
6378
|
onBack: nav.goBackInner,
|
|
@@ -6033,7 +6384,7 @@ function AppPanel() {
|
|
|
6033
6384
|
}
|
|
6034
6385
|
);
|
|
6035
6386
|
case "declarative-status":
|
|
6036
|
-
return /* @__PURE__ */
|
|
6387
|
+
return /* @__PURE__ */ jsx41(
|
|
6037
6388
|
DeclarativeStatus,
|
|
6038
6389
|
{
|
|
6039
6390
|
onBack: nav.goBackInner,
|
|
@@ -6044,7 +6395,7 @@ function AppPanel() {
|
|
|
6044
6395
|
}
|
|
6045
6396
|
);
|
|
6046
6397
|
case "init-scaffold":
|
|
6047
|
-
return /* @__PURE__ */
|
|
6398
|
+
return /* @__PURE__ */ jsx41(
|
|
6048
6399
|
InitScaffold,
|
|
6049
6400
|
{
|
|
6050
6401
|
onBack: nav.goBackInner,
|
|
@@ -6055,18 +6406,30 @@ function AppPanel() {
|
|
|
6055
6406
|
isInputActive: isActive
|
|
6056
6407
|
}
|
|
6057
6408
|
);
|
|
6409
|
+
case "script-picker":
|
|
6410
|
+
return /* @__PURE__ */ jsx41(
|
|
6411
|
+
ScriptPicker,
|
|
6412
|
+
{
|
|
6413
|
+
onNavigate: nav.navigateInner,
|
|
6414
|
+
onBack: nav.goBackInner,
|
|
6415
|
+
width: w,
|
|
6416
|
+
height: mainContentHeight,
|
|
6417
|
+
panelMode: true,
|
|
6418
|
+
isInputActive: isActive
|
|
6419
|
+
}
|
|
6420
|
+
);
|
|
6058
6421
|
default:
|
|
6059
|
-
return /* @__PURE__ */
|
|
6422
|
+
return /* @__PURE__ */ jsxs39(Text40, { color: "red", children: [
|
|
6060
6423
|
"Unknown screen: ",
|
|
6061
6424
|
nav.innerScreen
|
|
6062
6425
|
] });
|
|
6063
6426
|
}
|
|
6064
6427
|
};
|
|
6065
6428
|
if (modal.isOpen) {
|
|
6066
|
-
return /* @__PURE__ */
|
|
6429
|
+
return /* @__PURE__ */ jsx41(Box38, { flexDirection: "column", width, height, children: /* @__PURE__ */ jsx41(Modal, { title: modal.modalTitle, width, height, children: modal.modalContent }) });
|
|
6067
6430
|
}
|
|
6068
|
-
const header = /* @__PURE__ */
|
|
6069
|
-
const sidebar = /* @__PURE__ */
|
|
6431
|
+
const header = /* @__PURE__ */ jsx41(GhostBanner, { width, compact: true });
|
|
6432
|
+
const sidebar = /* @__PURE__ */ jsx41(
|
|
6070
6433
|
Panel,
|
|
6071
6434
|
{
|
|
6072
6435
|
id: "sidebar",
|
|
@@ -6074,7 +6437,7 @@ function AppPanel() {
|
|
|
6074
6437
|
width: Math.max(20, Math.min(35, Math.floor(width * 0.3))),
|
|
6075
6438
|
height: Math.max(5, height - bannerHeight - 1),
|
|
6076
6439
|
focused: focus.isSidebarFocused,
|
|
6077
|
-
children: /* @__PURE__ */
|
|
6440
|
+
children: /* @__PURE__ */ jsx41(
|
|
6078
6441
|
Sidebar,
|
|
6079
6442
|
{
|
|
6080
6443
|
items: sidebarItems,
|
|
@@ -6087,7 +6450,7 @@ function AppPanel() {
|
|
|
6087
6450
|
)
|
|
6088
6451
|
}
|
|
6089
6452
|
);
|
|
6090
|
-
const main2 = /* @__PURE__ */
|
|
6453
|
+
const main2 = /* @__PURE__ */ jsx41(
|
|
6091
6454
|
Panel,
|
|
6092
6455
|
{
|
|
6093
6456
|
id: "main",
|
|
@@ -6098,8 +6461,8 @@ function AppPanel() {
|
|
|
6098
6461
|
children: renderMainContent()
|
|
6099
6462
|
}
|
|
6100
6463
|
);
|
|
6101
|
-
const footer = /* @__PURE__ */
|
|
6102
|
-
return /* @__PURE__ */
|
|
6464
|
+
const footer = /* @__PURE__ */ jsx41(PanelFooter, { hints: footerHints, width });
|
|
6465
|
+
return /* @__PURE__ */ jsx41(
|
|
6103
6466
|
PanelLayout,
|
|
6104
6467
|
{
|
|
6105
6468
|
header,
|
|
@@ -6263,19 +6626,19 @@ function printCliHelp() {
|
|
|
6263
6626
|
import pc3 from "picocolors";
|
|
6264
6627
|
|
|
6265
6628
|
// src/apps/ops.ts
|
|
6266
|
-
import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync as writeFileSync2 } from "fs";
|
|
6629
|
+
import { existsSync as existsSync2, mkdirSync, readFileSync as readFileSync2, rmSync, writeFileSync as writeFileSync2 } from "fs";
|
|
6267
6630
|
import { mkdtemp, readdir, stat } from "fs/promises";
|
|
6268
|
-
import { dirname, join as
|
|
6631
|
+
import { dirname, join as join4, resolve } from "path";
|
|
6269
6632
|
import { tmpdir } from "os";
|
|
6270
6633
|
import pc2 from "picocolors";
|
|
6271
6634
|
|
|
6272
6635
|
// src/apps/bootstrapPaths.ts
|
|
6273
6636
|
import { homedir as homedir2 } from "os";
|
|
6274
|
-
import { join as
|
|
6637
|
+
import { join as join3 } from "path";
|
|
6275
6638
|
function getOpsBootstrapPayloadPath() {
|
|
6276
6639
|
const home = homedir2();
|
|
6277
6640
|
if (process.platform === "darwin") {
|
|
6278
|
-
return
|
|
6641
|
+
return join3(
|
|
6279
6642
|
home,
|
|
6280
6643
|
"Library",
|
|
6281
6644
|
"Application Support",
|
|
@@ -6285,10 +6648,10 @@ function getOpsBootstrapPayloadPath() {
|
|
|
6285
6648
|
);
|
|
6286
6649
|
}
|
|
6287
6650
|
if (process.platform === "win32") {
|
|
6288
|
-
const appData = process.env.APPDATA ??
|
|
6289
|
-
return
|
|
6651
|
+
const appData = process.env.APPDATA ?? join3(home, "AppData", "Roaming");
|
|
6652
|
+
return join3(appData, "ops", "bootstrap", "supabase.json");
|
|
6290
6653
|
}
|
|
6291
|
-
return
|
|
6654
|
+
return join3(home, ".config", "ops", "bootstrap", "supabase.json");
|
|
6292
6655
|
}
|
|
6293
6656
|
|
|
6294
6657
|
// src/apps/opsRelease.ts
|
|
@@ -6560,9 +6923,9 @@ async function promptSelect(label, options, defaultValue) {
|
|
|
6560
6923
|
}
|
|
6561
6924
|
|
|
6562
6925
|
// src/apps/ops.ts
|
|
6563
|
-
var LINK_REF_FILE =
|
|
6926
|
+
var LINK_REF_FILE = join4("supabase", ".temp", "project-ref");
|
|
6564
6927
|
function isOpsProjectRoot(candidate) {
|
|
6565
|
-
return
|
|
6928
|
+
return existsSync2(join4(candidate, "src-tauri", "tauri.conf.json")) && existsSync2(join4(candidate, "supabase", "migrations")) && existsSync2(join4(candidate, "package.json"));
|
|
6566
6929
|
}
|
|
6567
6930
|
function findNearestOpsRoot(startDir) {
|
|
6568
6931
|
let currentDir = resolve(startDir);
|
|
@@ -6570,7 +6933,7 @@ function findNearestOpsRoot(startDir) {
|
|
|
6570
6933
|
if (isOpsProjectRoot(currentDir)) {
|
|
6571
6934
|
return currentDir;
|
|
6572
6935
|
}
|
|
6573
|
-
const siblingCandidate =
|
|
6936
|
+
const siblingCandidate = join4(currentDir, "ops");
|
|
6574
6937
|
if (isOpsProjectRoot(siblingCandidate)) {
|
|
6575
6938
|
return siblingCandidate;
|
|
6576
6939
|
}
|
|
@@ -6582,10 +6945,10 @@ function findNearestOpsRoot(startDir) {
|
|
|
6582
6945
|
}
|
|
6583
6946
|
}
|
|
6584
6947
|
function readEnvFile(envPath) {
|
|
6585
|
-
if (!
|
|
6948
|
+
if (!existsSync2(envPath)) {
|
|
6586
6949
|
return {};
|
|
6587
6950
|
}
|
|
6588
|
-
const content =
|
|
6951
|
+
const content = readFileSync2(envPath, "utf-8");
|
|
6589
6952
|
const entries = {};
|
|
6590
6953
|
for (const line of content.split("\n")) {
|
|
6591
6954
|
const trimmed = line.trim();
|
|
@@ -6616,11 +6979,11 @@ function assertProjectRoot(projectRoot) {
|
|
|
6616
6979
|
return projectRoot;
|
|
6617
6980
|
}
|
|
6618
6981
|
function getLinkedProjectRef(projectRoot) {
|
|
6619
|
-
const refPath =
|
|
6620
|
-
if (!
|
|
6982
|
+
const refPath = join4(projectRoot, LINK_REF_FILE);
|
|
6983
|
+
if (!existsSync2(refPath)) {
|
|
6621
6984
|
return null;
|
|
6622
6985
|
}
|
|
6623
|
-
const value =
|
|
6986
|
+
const value = readFileSync2(refPath, "utf-8").trim();
|
|
6624
6987
|
return value || null;
|
|
6625
6988
|
}
|
|
6626
6989
|
function getDbPasswordArgs() {
|
|
@@ -6674,7 +7037,7 @@ async function ensureSupabaseLink(projectRoot, forceRelink = false) {
|
|
|
6674
7037
|
);
|
|
6675
7038
|
}
|
|
6676
7039
|
async function collectSupabaseConfig(projectRoot) {
|
|
6677
|
-
const envPath = projectRoot ?
|
|
7040
|
+
const envPath = projectRoot ? join4(projectRoot, ".env.local") : void 0;
|
|
6678
7041
|
const currentEnv = envPath ? readEnvFile(envPath) : {};
|
|
6679
7042
|
const currentRef = projectRoot ? getLinkedProjectRef(projectRoot) : null;
|
|
6680
7043
|
const url = await promptText("Supabase URL", {
|
|
@@ -6696,7 +7059,7 @@ async function collectSupabaseConfig(projectRoot) {
|
|
|
6696
7059
|
};
|
|
6697
7060
|
}
|
|
6698
7061
|
function writeOpsEnv(projectRoot, config2) {
|
|
6699
|
-
const envPath =
|
|
7062
|
+
const envPath = join4(projectRoot, ".env.local");
|
|
6700
7063
|
const currentEnv = readEnvFile(envPath);
|
|
6701
7064
|
const nextEnv = {
|
|
6702
7065
|
...currentEnv,
|
|
@@ -6896,7 +7259,7 @@ async function extractArchive(archivePath, outputDir) {
|
|
|
6896
7259
|
async function findFirstAppBundle(dir) {
|
|
6897
7260
|
const entries = await readdir(dir);
|
|
6898
7261
|
for (const entry of entries) {
|
|
6899
|
-
const fullPath =
|
|
7262
|
+
const fullPath = join4(dir, entry);
|
|
6900
7263
|
const entryStat = await stat(fullPath);
|
|
6901
7264
|
if (entryStat.isDirectory() && entry.endsWith(".app")) {
|
|
6902
7265
|
return fullPath;
|
|
@@ -6912,9 +7275,9 @@ async function findFirstAppBundle(dir) {
|
|
|
6912
7275
|
}
|
|
6913
7276
|
async function deployMacosApp(context, options) {
|
|
6914
7277
|
const artifact = await resolveOpsMacosArtifact(context.options);
|
|
6915
|
-
const tempRoot = await mkdtemp(
|
|
6916
|
-
const archivePath =
|
|
6917
|
-
const extractDir =
|
|
7278
|
+
const tempRoot = await mkdtemp(join4(tmpdir(), "polter-ops-"));
|
|
7279
|
+
const archivePath = join4(tempRoot, artifact.fileName);
|
|
7280
|
+
const extractDir = join4(tempRoot, "extract");
|
|
6918
7281
|
mkdirSync(extractDir, { recursive: true });
|
|
6919
7282
|
if (artifact.source === "github-release") {
|
|
6920
7283
|
const releaseLabel = artifact.tagName ?? "latest";
|
|
@@ -6943,13 +7306,13 @@ async function deployMacosApp(context, options) {
|
|
|
6943
7306
|
}
|
|
6944
7307
|
const installDir = context.options.installDir ?? "/Applications";
|
|
6945
7308
|
mkdirSync(installDir, { recursive: true });
|
|
6946
|
-
const destination =
|
|
6947
|
-
if (options.requireExistingInstallation && !
|
|
7309
|
+
const destination = join4(installDir, "ops.app");
|
|
7310
|
+
if (options.requireExistingInstallation && !existsSync2(destination)) {
|
|
6948
7311
|
throw new Error(
|
|
6949
7312
|
`No existing Ops installation was found at ${destination}. Run \`polter app install ops\` first.`
|
|
6950
7313
|
);
|
|
6951
7314
|
}
|
|
6952
|
-
if (
|
|
7315
|
+
if (existsSync2(destination)) {
|
|
6953
7316
|
const confirmed = context.options.yes || await promptConfirm(`Replace existing installation at ${destination}?`, false);
|
|
6954
7317
|
if (!confirmed) {
|
|
6955
7318
|
process.stdout.write(`${pc2.yellow("Cancelled.")}
|
|
@@ -7213,11 +7576,14 @@ Apply completed with ${errors.length} error(s).
|
|
|
7213
7576
|
process.exit(result.exitCode ?? 0);
|
|
7214
7577
|
}
|
|
7215
7578
|
const AppComponent2 = parsed.classic ? AppClassic : AppPanel;
|
|
7216
|
-
render(
|
|
7217
|
-
|
|
7579
|
+
const inst = render(React28.createElement(AppComponent2));
|
|
7580
|
+
await inst.waitUntilExit();
|
|
7581
|
+
process.exit(0);
|
|
7218
7582
|
}
|
|
7219
7583
|
const AppComponent = parsed.classic ? AppClassic : AppPanel;
|
|
7220
|
-
render(
|
|
7584
|
+
const instance = render(React28.createElement(AppComponent));
|
|
7585
|
+
await instance.waitUntilExit();
|
|
7586
|
+
process.exit(0);
|
|
7221
7587
|
}
|
|
7222
7588
|
main().catch((error) => {
|
|
7223
7589
|
const message = error instanceof Error ? error.message : String(error);
|