@polterware/polter 0.2.2 → 0.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api.js +1 -1
- package/dist/{chunk-2MXXRP4H.js → chunk-2B2UWOVQ.js} +91 -29
- package/dist/index.js +44 -26
- package/dist/mcp.js +1 -1
- package/package.json +1 -1
package/dist/api.js
CHANGED
|
@@ -12,21 +12,24 @@ var supabaseCommands = [
|
|
|
12
12
|
tool: "supabase",
|
|
13
13
|
base: ["bootstrap"],
|
|
14
14
|
label: "bootstrap",
|
|
15
|
-
hint: "Bootstrap from a starter template"
|
|
15
|
+
hint: "Bootstrap from a starter template",
|
|
16
|
+
interactive: true
|
|
16
17
|
},
|
|
17
18
|
{
|
|
18
19
|
id: "supabase:init",
|
|
19
20
|
tool: "supabase",
|
|
20
21
|
base: ["init"],
|
|
21
22
|
label: "init",
|
|
22
|
-
hint: "Initialize a local project"
|
|
23
|
+
hint: "Initialize a local project",
|
|
24
|
+
interactive: true
|
|
23
25
|
},
|
|
24
26
|
{
|
|
25
27
|
id: "supabase:login",
|
|
26
28
|
tool: "supabase",
|
|
27
29
|
base: ["login"],
|
|
28
30
|
label: "login",
|
|
29
|
-
hint: "Authenticate with access token"
|
|
31
|
+
hint: "Authenticate with access token",
|
|
32
|
+
interactive: true
|
|
30
33
|
},
|
|
31
34
|
{
|
|
32
35
|
id: "supabase:logout",
|
|
@@ -132,14 +135,7 @@ var supabaseCommands = [
|
|
|
132
135
|
base: ["link"],
|
|
133
136
|
label: "link",
|
|
134
137
|
hint: "Link to remote project",
|
|
135
|
-
|
|
136
|
-
{
|
|
137
|
-
value: "project-ref",
|
|
138
|
-
label: "--project-ref <ref>",
|
|
139
|
-
hint: "Link with project ref",
|
|
140
|
-
args: ["--project-ref"]
|
|
141
|
-
}
|
|
142
|
-
]
|
|
138
|
+
interactive: true
|
|
143
139
|
},
|
|
144
140
|
{
|
|
145
141
|
id: "supabase:unlink",
|
|
@@ -333,7 +329,8 @@ var ghCommands = [
|
|
|
333
329
|
tool: "gh",
|
|
334
330
|
base: ["repo", "create"],
|
|
335
331
|
label: "repo create",
|
|
336
|
-
hint: "Create a new repository"
|
|
332
|
+
hint: "Create a new repository",
|
|
333
|
+
interactive: true
|
|
337
334
|
},
|
|
338
335
|
{
|
|
339
336
|
id: "gh:repo:view",
|
|
@@ -497,7 +494,8 @@ var ghCommands = [
|
|
|
497
494
|
tool: "gh",
|
|
498
495
|
base: ["auth", "login"],
|
|
499
496
|
label: "auth login",
|
|
500
|
-
hint: "Log in to GitHub"
|
|
497
|
+
hint: "Log in to GitHub",
|
|
498
|
+
interactive: true
|
|
501
499
|
},
|
|
502
500
|
{
|
|
503
501
|
id: "gh:auth:status",
|
|
@@ -618,14 +616,16 @@ var vercelCommands = [
|
|
|
618
616
|
tool: "vercel",
|
|
619
617
|
base: ["link"],
|
|
620
618
|
label: "link",
|
|
621
|
-
hint: "Link to a Vercel project"
|
|
619
|
+
hint: "Link to a Vercel project",
|
|
620
|
+
interactive: true
|
|
622
621
|
},
|
|
623
622
|
{
|
|
624
623
|
id: "vercel:login",
|
|
625
624
|
tool: "vercel",
|
|
626
625
|
base: ["login"],
|
|
627
626
|
label: "login",
|
|
628
|
-
hint: "Log in to Vercel"
|
|
627
|
+
hint: "Log in to Vercel",
|
|
628
|
+
interactive: true
|
|
629
629
|
},
|
|
630
630
|
{
|
|
631
631
|
id: "vercel:whoami",
|
|
@@ -981,6 +981,10 @@ async function runSupabaseCommand(args, cwd = process.cwd()) {
|
|
|
981
981
|
return runCommand(resolveSupabaseCommand(cwd), args, cwd);
|
|
982
982
|
}
|
|
983
983
|
|
|
984
|
+
// src/lib/toolResolver.ts
|
|
985
|
+
import { existsSync as existsSync2, readFileSync } from "fs";
|
|
986
|
+
import { join as join2 } from "path";
|
|
987
|
+
|
|
984
988
|
// src/lib/system.ts
|
|
985
989
|
import { execSync } from "child_process";
|
|
986
990
|
function commandExists(command) {
|
|
@@ -1053,6 +1057,63 @@ function getToolInfo(toolId) {
|
|
|
1053
1057
|
toolInfoCache.set(toolId, info);
|
|
1054
1058
|
return info;
|
|
1055
1059
|
}
|
|
1060
|
+
function detectSupabaseLink(cwd) {
|
|
1061
|
+
try {
|
|
1062
|
+
const configPath = join2(cwd, ".supabase", "config.toml");
|
|
1063
|
+
if (existsSync2(configPath)) {
|
|
1064
|
+
const content = readFileSync(configPath, "utf-8");
|
|
1065
|
+
const match = content.match(/project_id\s*=\s*"([^"]+)"/);
|
|
1066
|
+
return { linked: true, project: match?.[1] };
|
|
1067
|
+
}
|
|
1068
|
+
} catch {
|
|
1069
|
+
}
|
|
1070
|
+
return { linked: false };
|
|
1071
|
+
}
|
|
1072
|
+
function detectVercelLink(cwd) {
|
|
1073
|
+
try {
|
|
1074
|
+
const projectPath = join2(cwd, ".vercel", "project.json");
|
|
1075
|
+
if (existsSync2(projectPath)) {
|
|
1076
|
+
const data = JSON.parse(readFileSync(projectPath, "utf-8"));
|
|
1077
|
+
return { linked: true, project: data.projectId };
|
|
1078
|
+
}
|
|
1079
|
+
} catch {
|
|
1080
|
+
}
|
|
1081
|
+
return { linked: false };
|
|
1082
|
+
}
|
|
1083
|
+
function detectGhLink(cwd) {
|
|
1084
|
+
try {
|
|
1085
|
+
const remote = execCapture(`git -C "${cwd}" remote get-url origin 2>/dev/null`);
|
|
1086
|
+
if (remote) {
|
|
1087
|
+
const match = remote.match(/[/:]([\w.-]+\/[\w.-]+?)(?:\.git)?$/);
|
|
1088
|
+
return { linked: true, project: match?.[1] ?? remote };
|
|
1089
|
+
}
|
|
1090
|
+
} catch {
|
|
1091
|
+
}
|
|
1092
|
+
return { linked: false };
|
|
1093
|
+
}
|
|
1094
|
+
var toolLinkCache = /* @__PURE__ */ new Map();
|
|
1095
|
+
function getToolLinkInfo(toolId, cwd = process.cwd()) {
|
|
1096
|
+
const cached = toolLinkCache.get(toolId);
|
|
1097
|
+
if (cached) return cached;
|
|
1098
|
+
const base = getToolInfo(toolId);
|
|
1099
|
+
let linkStatus = { linked: false };
|
|
1100
|
+
if (base.installed) {
|
|
1101
|
+
switch (toolId) {
|
|
1102
|
+
case "supabase":
|
|
1103
|
+
linkStatus = detectSupabaseLink(cwd);
|
|
1104
|
+
break;
|
|
1105
|
+
case "vercel":
|
|
1106
|
+
linkStatus = detectVercelLink(cwd);
|
|
1107
|
+
break;
|
|
1108
|
+
case "gh":
|
|
1109
|
+
linkStatus = detectGhLink(cwd);
|
|
1110
|
+
break;
|
|
1111
|
+
}
|
|
1112
|
+
}
|
|
1113
|
+
const info = { ...base, ...linkStatus };
|
|
1114
|
+
toolLinkCache.set(toolId, info);
|
|
1115
|
+
return info;
|
|
1116
|
+
}
|
|
1056
1117
|
|
|
1057
1118
|
// src/pipeline/engine.ts
|
|
1058
1119
|
async function executePipeline(pipeline, onProgress, cwd = process.cwd()) {
|
|
@@ -1100,19 +1161,19 @@ async function executePipeline(pipeline, onProgress, cwd = process.cwd()) {
|
|
|
1100
1161
|
}
|
|
1101
1162
|
|
|
1102
1163
|
// src/config/projectConfig.ts
|
|
1103
|
-
import { existsSync as
|
|
1104
|
-
import { join as
|
|
1164
|
+
import { existsSync as existsSync4, readFileSync as readFileSync2, writeFileSync, mkdirSync } from "fs";
|
|
1165
|
+
import { join as join4 } from "path";
|
|
1105
1166
|
|
|
1106
1167
|
// src/lib/packageRoot.ts
|
|
1107
|
-
import { existsSync as
|
|
1108
|
-
import { dirname as dirname2, join as
|
|
1168
|
+
import { existsSync as existsSync3 } from "fs";
|
|
1169
|
+
import { dirname as dirname2, join as join3, resolve as resolve2 } from "path";
|
|
1109
1170
|
var rootCache = /* @__PURE__ */ new Map();
|
|
1110
1171
|
function findNearestPackageRoot(startDir = process.cwd()) {
|
|
1111
1172
|
const resolvedStart = resolve2(startDir);
|
|
1112
1173
|
if (rootCache.has(resolvedStart)) return rootCache.get(resolvedStart);
|
|
1113
1174
|
let currentDir = resolvedStart;
|
|
1114
1175
|
while (true) {
|
|
1115
|
-
if (
|
|
1176
|
+
if (existsSync3(join3(currentDir, "package.json"))) {
|
|
1116
1177
|
rootCache.set(resolvedStart, currentDir);
|
|
1117
1178
|
return currentDir;
|
|
1118
1179
|
}
|
|
@@ -1138,15 +1199,15 @@ function defaultConfig() {
|
|
|
1138
1199
|
function getProjectConfigPath(startDir) {
|
|
1139
1200
|
const root = findNearestPackageRoot(startDir);
|
|
1140
1201
|
if (!root) return void 0;
|
|
1141
|
-
const dir =
|
|
1142
|
-
return { dir, file:
|
|
1202
|
+
const dir = join4(root, CONFIG_DIR);
|
|
1203
|
+
return { dir, file: join4(dir, CONFIG_FILE) };
|
|
1143
1204
|
}
|
|
1144
1205
|
function readProjectConfig(startDir) {
|
|
1145
1206
|
const paths = getProjectConfigPath(startDir);
|
|
1146
1207
|
if (!paths) return void 0;
|
|
1147
|
-
if (!
|
|
1208
|
+
if (!existsSync4(paths.file)) return void 0;
|
|
1148
1209
|
try {
|
|
1149
|
-
const raw =
|
|
1210
|
+
const raw = readFileSync2(paths.file, "utf-8");
|
|
1150
1211
|
return JSON.parse(raw);
|
|
1151
1212
|
} catch {
|
|
1152
1213
|
return void 0;
|
|
@@ -1245,8 +1306,8 @@ function findPipelineByName(name, startDir) {
|
|
|
1245
1306
|
}
|
|
1246
1307
|
|
|
1247
1308
|
// src/declarative/parser.ts
|
|
1248
|
-
import { existsSync as
|
|
1249
|
-
import { join as
|
|
1309
|
+
import { existsSync as existsSync5, readFileSync as readFileSync3 } from "fs";
|
|
1310
|
+
import { join as join5 } from "path";
|
|
1250
1311
|
var YAML_FILE = "polter.yaml";
|
|
1251
1312
|
function parseSimpleYaml(content) {
|
|
1252
1313
|
const lines = content.split("\n");
|
|
@@ -1318,13 +1379,13 @@ function parseValue(raw) {
|
|
|
1318
1379
|
return raw;
|
|
1319
1380
|
}
|
|
1320
1381
|
function findPolterYaml(startDir = process.cwd()) {
|
|
1321
|
-
const filePath =
|
|
1322
|
-
return
|
|
1382
|
+
const filePath = join5(startDir, YAML_FILE);
|
|
1383
|
+
return existsSync5(filePath) ? filePath : void 0;
|
|
1323
1384
|
}
|
|
1324
1385
|
function parsePolterYaml(startDir = process.cwd()) {
|
|
1325
1386
|
const filePath = findPolterYaml(startDir);
|
|
1326
1387
|
if (!filePath) return void 0;
|
|
1327
|
-
const content =
|
|
1388
|
+
const content = readFileSync3(filePath, "utf-8");
|
|
1328
1389
|
const raw = parseSimpleYaml(content);
|
|
1329
1390
|
return raw;
|
|
1330
1391
|
}
|
|
@@ -1480,6 +1541,7 @@ export {
|
|
|
1480
1541
|
commandExists,
|
|
1481
1542
|
resolveToolCommand,
|
|
1482
1543
|
getToolInfo,
|
|
1544
|
+
getToolLinkInfo,
|
|
1483
1545
|
executePipeline,
|
|
1484
1546
|
findNearestPackageRoot,
|
|
1485
1547
|
getProjectConfigPath,
|
package/dist/index.js
CHANGED
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
getOrCreateProjectConfig,
|
|
18
18
|
getProjectConfigPath,
|
|
19
19
|
getToolInfo,
|
|
20
|
+
getToolLinkInfo,
|
|
20
21
|
parsePolterYaml,
|
|
21
22
|
planChanges,
|
|
22
23
|
resolveToolCommand,
|
|
@@ -25,7 +26,7 @@ import {
|
|
|
25
26
|
runSupabaseCommand,
|
|
26
27
|
savePipeline,
|
|
27
28
|
writeProjectConfig
|
|
28
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-2B2UWOVQ.js";
|
|
29
30
|
|
|
30
31
|
// src/index.tsx
|
|
31
32
|
import React20 from "react";
|
|
@@ -177,16 +178,16 @@ var ghost = {
|
|
|
177
178
|
// src/components/GhostBanner.tsx
|
|
178
179
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
179
180
|
var ToolStatusBadges = React.memo(function ToolStatusBadges2() {
|
|
180
|
-
const tools = ["supabase", "gh", "vercel"].map(
|
|
181
|
+
const tools = ["supabase", "gh", "vercel"].map((id) => getToolLinkInfo(id));
|
|
181
182
|
return /* @__PURE__ */ jsx(Box, { gap: 1, children: tools.map((t) => /* @__PURE__ */ jsxs(
|
|
182
183
|
Text,
|
|
183
184
|
{
|
|
184
|
-
color: t.
|
|
185
|
+
color: t.linked ? inkColors.accent : t.installed ? "yellow" : "red",
|
|
185
186
|
dimColor: !t.installed,
|
|
186
187
|
children: [
|
|
187
188
|
t.id,
|
|
188
189
|
":",
|
|
189
|
-
t.installed ? "ok" : "x"
|
|
190
|
+
t.linked ? "linked" : t.installed ? "ok" : "x"
|
|
190
191
|
]
|
|
191
192
|
},
|
|
192
193
|
t.id
|
|
@@ -869,7 +870,7 @@ function Home({
|
|
|
869
870
|
const basePart = args[0] ?? "";
|
|
870
871
|
const cmdDef = findCommandByValue(basePart);
|
|
871
872
|
const tool = cmdDef?.tool ?? "supabase";
|
|
872
|
-
onNavigate("confirm-execute", { args, tool });
|
|
873
|
+
onNavigate("confirm-execute", { args, tool, interactive: cmdDef?.interactive });
|
|
873
874
|
}
|
|
874
875
|
return;
|
|
875
876
|
}
|
|
@@ -1128,7 +1129,8 @@ function CommandArgs({
|
|
|
1128
1129
|
onNavigate("flag-selection", {
|
|
1129
1130
|
args: [...baseArgs, ...extraArgs],
|
|
1130
1131
|
command,
|
|
1131
|
-
tool: resolvedTool
|
|
1132
|
+
tool: resolvedTool,
|
|
1133
|
+
interactive: cmdDef?.interactive
|
|
1132
1134
|
});
|
|
1133
1135
|
};
|
|
1134
1136
|
useInput4((_input, key) => {
|
|
@@ -1328,7 +1330,7 @@ function CustomCommand({
|
|
|
1328
1330
|
},
|
|
1329
1331
|
onSubmit: (value) => {
|
|
1330
1332
|
const args = value.split(" ").filter(Boolean);
|
|
1331
|
-
onNavigate("flag-selection", { args, tool: selectedTool });
|
|
1333
|
+
onNavigate("flag-selection", { args, tool: selectedTool, interactive: true });
|
|
1332
1334
|
},
|
|
1333
1335
|
onCancel: () => setPhase("tool-select"),
|
|
1334
1336
|
arrowNavigation: panelMode,
|
|
@@ -1428,6 +1430,7 @@ import { jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
|
1428
1430
|
function FlagSelection({
|
|
1429
1431
|
args,
|
|
1430
1432
|
tool = "supabase",
|
|
1433
|
+
interactive,
|
|
1431
1434
|
onNavigate,
|
|
1432
1435
|
onBack,
|
|
1433
1436
|
width = 80,
|
|
@@ -1437,7 +1440,7 @@ function FlagSelection({
|
|
|
1437
1440
|
}) {
|
|
1438
1441
|
const flags = getFlagsForTool(tool);
|
|
1439
1442
|
if (flags.length === 0) {
|
|
1440
|
-
onNavigate("confirm-execute", { args, tool });
|
|
1443
|
+
onNavigate("confirm-execute", { args, tool, interactive });
|
|
1441
1444
|
return /* @__PURE__ */ jsx11(Box10, {});
|
|
1442
1445
|
}
|
|
1443
1446
|
const cmdDisplay = `${tool} ${args.join(" ")}`;
|
|
@@ -1461,7 +1464,7 @@ function FlagSelection({
|
|
|
1461
1464
|
flags,
|
|
1462
1465
|
onSubmit: (selectedFlags) => {
|
|
1463
1466
|
const finalArgs = selectedFlags.length > 0 ? [...args, ...selectedFlags] : args;
|
|
1464
|
-
onNavigate("confirm-execute", { args: finalArgs, tool });
|
|
1467
|
+
onNavigate("confirm-execute", { args: finalArgs, tool, interactive });
|
|
1465
1468
|
},
|
|
1466
1469
|
onCancel: onBack,
|
|
1467
1470
|
isInputActive,
|
|
@@ -1475,7 +1478,7 @@ function FlagSelection({
|
|
|
1475
1478
|
flags,
|
|
1476
1479
|
onSubmit: (selectedFlags) => {
|
|
1477
1480
|
const finalArgs = selectedFlags.length > 0 ? [...args, ...selectedFlags] : args;
|
|
1478
|
-
onNavigate("confirm-execute", { args: finalArgs, tool });
|
|
1481
|
+
onNavigate("confirm-execute", { args: finalArgs, tool, interactive });
|
|
1479
1482
|
},
|
|
1480
1483
|
onCancel: onBack,
|
|
1481
1484
|
isInputActive,
|
|
@@ -1671,7 +1674,6 @@ function useCommand(execution = "supabase", cwd = process.cwd(), options) {
|
|
|
1671
1674
|
|
|
1672
1675
|
// src/hooks/useInteractiveRun.ts
|
|
1673
1676
|
import { useCallback as useCallback3 } from "react";
|
|
1674
|
-
import { useStdin } from "ink";
|
|
1675
1677
|
|
|
1676
1678
|
// src/hooks/useFullscreen.ts
|
|
1677
1679
|
import { useEffect as useEffect5 } from "react";
|
|
@@ -1690,11 +1692,12 @@ function useFullscreen() {
|
|
|
1690
1692
|
|
|
1691
1693
|
// src/hooks/useInteractiveRun.ts
|
|
1692
1694
|
function useInteractiveRun() {
|
|
1693
|
-
const { setRawMode } = useStdin();
|
|
1694
1695
|
const runInteractive = useCallback3(
|
|
1695
1696
|
(tool, args, cwd) => {
|
|
1696
|
-
process.stdout.write(SHOW_CURSOR + LEAVE_ALT_SCREEN);
|
|
1697
|
-
|
|
1697
|
+
process.stdout.write(SHOW_CURSOR + LEAVE_ALT_SCREEN + "\x1B[2J\x1B[H");
|
|
1698
|
+
if (process.stdin.isTTY) {
|
|
1699
|
+
process.stdin.setRawMode(false);
|
|
1700
|
+
}
|
|
1698
1701
|
process.stdout.write(`
|
|
1699
1702
|
Running: ${tool} ${args.join(" ")}
|
|
1700
1703
|
|
|
@@ -1710,11 +1713,13 @@ function useInteractiveRun() {
|
|
|
1710
1713
|
Command exited (code ${result.exitCode ?? "?"}). Returning to Polter...
|
|
1711
1714
|
`
|
|
1712
1715
|
);
|
|
1713
|
-
|
|
1716
|
+
if (process.stdin.isTTY) {
|
|
1717
|
+
process.stdin.setRawMode(true);
|
|
1718
|
+
}
|
|
1714
1719
|
process.stdout.write(ENTER_ALT_SCREEN + HIDE_CURSOR);
|
|
1715
1720
|
return result;
|
|
1716
1721
|
},
|
|
1717
|
-
[
|
|
1722
|
+
[]
|
|
1718
1723
|
);
|
|
1719
1724
|
return { runInteractive };
|
|
1720
1725
|
}
|
|
@@ -1782,6 +1787,7 @@ import { jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
|
1782
1787
|
function CommandExecution({
|
|
1783
1788
|
args: initialArgs,
|
|
1784
1789
|
tool = "supabase",
|
|
1790
|
+
interactive = false,
|
|
1785
1791
|
onBack,
|
|
1786
1792
|
onHome,
|
|
1787
1793
|
onExit,
|
|
@@ -1802,9 +1808,18 @@ function CommandExecution({
|
|
|
1802
1808
|
const runCommand2 = currentArgs.join(" ");
|
|
1803
1809
|
useEffect6(() => {
|
|
1804
1810
|
if (phase === "running" && status === "idle") {
|
|
1805
|
-
|
|
1811
|
+
if (panelMode && interactive) {
|
|
1812
|
+
const interactiveResult = runInteractive(tool, currentArgs);
|
|
1813
|
+
if (!interactiveResult.spawnError && interactiveResult.exitCode === 0) {
|
|
1814
|
+
setPhase("success");
|
|
1815
|
+
} else {
|
|
1816
|
+
setPhase("error-menu");
|
|
1817
|
+
}
|
|
1818
|
+
} else {
|
|
1819
|
+
run(currentArgs);
|
|
1820
|
+
}
|
|
1806
1821
|
}
|
|
1807
|
-
}, [phase, status, run, currentArgs]);
|
|
1822
|
+
}, [phase, status, run, currentArgs, panelMode, interactive, tool, runInteractive]);
|
|
1808
1823
|
useEffect6(() => {
|
|
1809
1824
|
if (phase === "running" && status === "success") {
|
|
1810
1825
|
if (isPinnedRun(runCommand2)) {
|
|
@@ -2377,15 +2392,16 @@ import { useMemo as useMemo4 } from "react";
|
|
|
2377
2392
|
import { Box as Box15, Text as Text19 } from "ink";
|
|
2378
2393
|
import { jsx as jsx19, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
2379
2394
|
var toolIds = ["supabase", "gh", "vercel", "git"];
|
|
2395
|
+
var linkableTools = /* @__PURE__ */ new Set(["supabase", "gh", "vercel"]);
|
|
2380
2396
|
function ToolStatus({ onBack, width = 80, height = 24, panelMode = false, isInputActive = true }) {
|
|
2381
|
-
const tools = useMemo4(() => toolIds.map(
|
|
2397
|
+
const tools = useMemo4(() => toolIds.map((id) => getToolLinkInfo(id)), []);
|
|
2382
2398
|
if (panelMode) {
|
|
2383
2399
|
const statusItems = [
|
|
2384
2400
|
{ value: "__section__", label: "Installed Tools", kind: "header", selectable: false },
|
|
2385
2401
|
...tools.map((tool) => ({
|
|
2386
2402
|
value: tool.id,
|
|
2387
2403
|
label: `${tool.installed ? "\u2713" : "\u2717"} ${tool.label}`,
|
|
2388
|
-
hint: tool.installed ? tool.version ?? "installed" : "not found",
|
|
2404
|
+
hint: tool.installed ? `${tool.version ?? "installed"}${linkableTools.has(tool.id) ? tool.linked ? ` \u2192 ${tool.project ? `linked (${tool.project})` : "linked"}` : " \u2192 not linked" : ""}` : "not found",
|
|
2389
2405
|
kind: "action"
|
|
2390
2406
|
}))
|
|
2391
2407
|
];
|
|
@@ -2410,7 +2426,7 @@ function ToolStatus({ onBack, width = 80, height = 24, panelMode = false, isInpu
|
|
|
2410
2426
|
tools.map((tool) => /* @__PURE__ */ jsxs17(Box15, { gap: 1, marginLeft: 2, children: [
|
|
2411
2427
|
/* @__PURE__ */ jsx19(Text19, { color: tool.installed ? inkColors.accent : "red", children: tool.installed ? "\u2713" : "\u2717" }),
|
|
2412
2428
|
/* @__PURE__ */ jsx19(Box15, { width: 16, children: /* @__PURE__ */ jsx19(Text19, { bold: true, children: tool.label }) }),
|
|
2413
|
-
/* @__PURE__ */ jsx19(Text19, { dimColor: true, children: tool.installed ? tool.version ?? "installed" : "not found" })
|
|
2429
|
+
/* @__PURE__ */ jsx19(Text19, { dimColor: true, children: tool.installed ? `${tool.version ?? "installed"}${linkableTools.has(tool.id) ? tool.linked ? ` \u2192 ${tool.project ?? "linked"}` : " \u2192 not linked" : ""}` : "not found" })
|
|
2414
2430
|
] }, tool.id)),
|
|
2415
2431
|
/* @__PURE__ */ jsx19(Box15, { marginTop: 1, children: /* @__PURE__ */ jsx19(
|
|
2416
2432
|
SelectList,
|
|
@@ -2432,7 +2448,7 @@ import { Box as Box16, Text as Text20 } from "ink";
|
|
|
2432
2448
|
|
|
2433
2449
|
// src/hooks/useEditor.ts
|
|
2434
2450
|
import { useState as useState13, useCallback as useCallback4 } from "react";
|
|
2435
|
-
import { useStdin
|
|
2451
|
+
import { useStdin } from "ink";
|
|
2436
2452
|
|
|
2437
2453
|
// src/lib/editor.ts
|
|
2438
2454
|
import { spawnSync, spawn as spawn2 } from "child_process";
|
|
@@ -2481,7 +2497,7 @@ function openInEditor(filePath) {
|
|
|
2481
2497
|
|
|
2482
2498
|
// src/hooks/useEditor.ts
|
|
2483
2499
|
function useEditor() {
|
|
2484
|
-
const { setRawMode } =
|
|
2500
|
+
const { setRawMode } = useStdin();
|
|
2485
2501
|
const [isEditing, setIsEditing] = useState13(false);
|
|
2486
2502
|
const openEditor = useCallback4(async (filePath) => {
|
|
2487
2503
|
const editor = resolveEditor();
|
|
@@ -3766,7 +3782,7 @@ function FeatureCommands({
|
|
|
3766
3782
|
const basePart = args[0] ?? "";
|
|
3767
3783
|
const cmdDef = findCommandByValue(basePart);
|
|
3768
3784
|
const tool = cmdDef?.tool ?? "supabase";
|
|
3769
|
-
onNavigate("confirm-execute", { args, tool });
|
|
3785
|
+
onNavigate("confirm-execute", { args, tool, interactive: cmdDef?.interactive });
|
|
3770
3786
|
}
|
|
3771
3787
|
return;
|
|
3772
3788
|
}
|
|
@@ -3866,7 +3882,7 @@ function PinnedCommands({
|
|
|
3866
3882
|
const basePart = args[0] ?? "";
|
|
3867
3883
|
const cmdDef = findCommandByValue(basePart);
|
|
3868
3884
|
const tool = cmdDef?.tool ?? "supabase";
|
|
3869
|
-
onNavigate("confirm-execute", { args, tool });
|
|
3885
|
+
onNavigate("confirm-execute", { args, tool, interactive: cmdDef?.interactive });
|
|
3870
3886
|
}
|
|
3871
3887
|
}
|
|
3872
3888
|
};
|
|
@@ -4234,6 +4250,7 @@ function AppPanel() {
|
|
|
4234
4250
|
{
|
|
4235
4251
|
args: nav.innerParams.args ?? [],
|
|
4236
4252
|
tool: nav.innerParams.tool,
|
|
4253
|
+
interactive: nav.innerParams.interactive,
|
|
4237
4254
|
onNavigate: nav.navigateInner,
|
|
4238
4255
|
onBack: nav.goBackInner,
|
|
4239
4256
|
width: w,
|
|
@@ -4249,11 +4266,12 @@ function AppPanel() {
|
|
|
4249
4266
|
{
|
|
4250
4267
|
args: nav.innerParams.args ?? [],
|
|
4251
4268
|
tool: nav.innerParams.tool,
|
|
4269
|
+
interactive: nav.innerParams.interactive,
|
|
4252
4270
|
onBack: nav.goBackInner,
|
|
4253
4271
|
onHome: nav.goHomeInner,
|
|
4254
4272
|
onExit: handleExit,
|
|
4255
4273
|
onRunSuggestion: (sugTool, sugArgs) => {
|
|
4256
|
-
nav.switchViewAndNavigate("custom-command", "confirm-execute", { tool: sugTool, args: sugArgs });
|
|
4274
|
+
nav.switchViewAndNavigate("custom-command", "confirm-execute", { tool: sugTool, args: sugArgs, interactive: true });
|
|
4257
4275
|
},
|
|
4258
4276
|
width: w,
|
|
4259
4277
|
height: mainContentHeight,
|
package/dist/mcp.js
CHANGED