prompts-gpt 0.2.11 → 0.2.13
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/cli.js +138 -64
- package/dist/cli.js.map +1 -1
- package/dist/index.js +6 -3
- package/dist/index.js.map +1 -1
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +121 -31
- package/dist/runtime.js.map +1 -1
- package/dist/sweep.d.ts.map +1 -1
- package/dist/sweep.js +190 -58
- package/dist/sweep.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -182,7 +182,7 @@ async function runCommand(command, flags) {
|
|
|
182
182
|
const setupPicked = await interactiveSelect("What next?", setupOptions);
|
|
183
183
|
if (setupPicked === "list") {
|
|
184
184
|
const { spawnSync: spSync } = await import("node:child_process");
|
|
185
|
-
const cliEntry =
|
|
185
|
+
const cliEntry = resolveCliEntry();
|
|
186
186
|
spSync(process.execPath, [cliEntry, "list"], { stdio: "inherit", cwd });
|
|
187
187
|
}
|
|
188
188
|
else if (setupPicked !== "done") {
|
|
@@ -190,7 +190,7 @@ async function runCommand(command, flags) {
|
|
|
190
190
|
const cmd = action === "sweep" ? "sweep" : "run";
|
|
191
191
|
console.log(`\nRunning: prompts-gpt ${cmd} -f ${file}\n`);
|
|
192
192
|
const { spawnSync: spSync } = await import("node:child_process");
|
|
193
|
-
const cliEntry =
|
|
193
|
+
const cliEntry = resolveCliEntry();
|
|
194
194
|
const setupResult = spSync(process.execPath, [cliEntry, cmd, "-f", file], { stdio: "inherit", cwd });
|
|
195
195
|
process.exitCode = setupResult.status ?? 1;
|
|
196
196
|
}
|
|
@@ -450,15 +450,12 @@ async function runCommand(command, flags) {
|
|
|
450
450
|
}
|
|
451
451
|
else {
|
|
452
452
|
try {
|
|
453
|
-
const
|
|
454
|
-
|
|
455
|
-
new Promise((_, rej) => setTimeout(() => rej(new Error("timeout")), 5000)),
|
|
456
|
-
]);
|
|
457
|
-
if (healthRes instanceof Response && healthRes.ok) {
|
|
453
|
+
const siteCheck = await checkPromptsGptSiteReachable(DEFAULT_PROMPTS_GPT_API_URL);
|
|
454
|
+
if (siteCheck.ok) {
|
|
458
455
|
console.log(` ✓ prompts-gpt.com reachable`);
|
|
459
456
|
}
|
|
460
457
|
else {
|
|
461
|
-
console.log(` ⚠ prompts-gpt.com responded with status ${
|
|
458
|
+
console.log(` ⚠ prompts-gpt.com responded with status ${siteCheck.status ?? "unknown"}`);
|
|
462
459
|
}
|
|
463
460
|
}
|
|
464
461
|
catch (err) {
|
|
@@ -573,7 +570,7 @@ async function runCommand(command, flags) {
|
|
|
573
570
|
const cmd = action === "sweep" ? "sweep" : "run";
|
|
574
571
|
console.log(`\nRunning: prompts-gpt ${cmd} -f ${file}\n`);
|
|
575
572
|
const { spawnSync: spSync } = await import("node:child_process");
|
|
576
|
-
const cliEntry =
|
|
573
|
+
const cliEntry = resolveCliEntry();
|
|
577
574
|
const result = spSync(process.execPath, [cliEntry, cmd, "-f", file], { stdio: "inherit", cwd });
|
|
578
575
|
process.exitCode = result.status ?? 1;
|
|
579
576
|
}
|
|
@@ -755,23 +752,36 @@ async function runCommand(command, flags) {
|
|
|
755
752
|
}
|
|
756
753
|
const runProviders = await detectProviders(cwd);
|
|
757
754
|
const runAvailable = runProviders.filter((p) => p.available);
|
|
758
|
-
if (!getStringFlag(flags, "agent") &&
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
if (
|
|
766
|
-
const
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
providerOpts.unshift(item);
|
|
770
|
-
}
|
|
755
|
+
if (!getStringFlag(flags, "agent") && runAvailable.length === 0 && !isTTYInteractive(flags)) {
|
|
756
|
+
throw new CliError("No supported provider CLI found on PATH. Install Codex, Cursor Agent, Claude Code, or Copilot CLI.\nRun `prompts-gpt doctor` for details.", CLI_EXIT_CODES.validation, { helpCommand: "providers" });
|
|
757
|
+
}
|
|
758
|
+
if (!getStringFlag(flags, "agent") && isTTYInteractive(flags) && !Boolean(flags.json)) {
|
|
759
|
+
if (runAvailable.length === 0) {
|
|
760
|
+
throw new CliError("No supported provider CLI found on PATH. Install Codex, Cursor Agent, Claude Code, or Copilot CLI.\nRun `prompts-gpt doctor` for details.", CLI_EXIT_CODES.validation, { helpCommand: "providers" });
|
|
761
|
+
}
|
|
762
|
+
else if (runAvailable.length === 1) {
|
|
763
|
+
const only = runAvailable[0];
|
|
764
|
+
console.log(`Using provider: ${only.provider} (${only.modelDefault}${only.version ? `, ${only.version}` : ""})`);
|
|
765
|
+
flags.agent = only.provider;
|
|
771
766
|
}
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
767
|
+
else {
|
|
768
|
+
const lastRunProvider = await getLastUsedProvider(cwd);
|
|
769
|
+
const providerOpts = runAvailable.map((p) => ({
|
|
770
|
+
label: `${p.provider} (${p.modelDefault}${p.version ? `, ${p.version}` : ""})${p.provider === lastRunProvider ? " ★" : ""}`,
|
|
771
|
+
value: p.provider,
|
|
772
|
+
}));
|
|
773
|
+
providerOpts.push({ label: "router (auto-select)", value: "router" });
|
|
774
|
+
if (lastRunProvider) {
|
|
775
|
+
const idx = providerOpts.findIndex((o) => o.value === lastRunProvider);
|
|
776
|
+
if (idx > 0) {
|
|
777
|
+
const [item] = providerOpts.splice(idx, 1);
|
|
778
|
+
providerOpts.unshift(item);
|
|
779
|
+
}
|
|
780
|
+
}
|
|
781
|
+
flags.agent = await interactiveSelect("Select a provider:", providerOpts);
|
|
782
|
+
if (flags.agent !== "router") {
|
|
783
|
+
await saveLastUsedProvider(cwd, flags.agent);
|
|
784
|
+
}
|
|
775
785
|
}
|
|
776
786
|
}
|
|
777
787
|
if (!getStringFlag(flags, "model") && isTTYInteractive(flags) && !Boolean(flags.json)) {
|
|
@@ -894,13 +904,18 @@ async function runCommand(command, flags) {
|
|
|
894
904
|
}
|
|
895
905
|
catch { /* skip */ }
|
|
896
906
|
console.log("");
|
|
897
|
-
console.log(`View results:
|
|
907
|
+
console.log(`View results: ${viewFileCmd} ${result.summaryFile}`);
|
|
898
908
|
}
|
|
899
909
|
if (Boolean(flags.open) && result.summaryFile) {
|
|
900
910
|
try {
|
|
901
911
|
const { spawn: openSpawn } = await import("node:child_process");
|
|
902
|
-
|
|
903
|
-
|
|
912
|
+
if (process.platform === "win32") {
|
|
913
|
+
openSpawn("cmd", ["/c", "start", "", result.summaryFile], { detached: true, stdio: "ignore", windowsHide: true }).unref();
|
|
914
|
+
}
|
|
915
|
+
else {
|
|
916
|
+
const openCmd = process.platform === "darwin" ? "open" : "xdg-open";
|
|
917
|
+
openSpawn(openCmd, [result.summaryFile], { detached: true, stdio: "ignore" }).unref();
|
|
918
|
+
}
|
|
904
919
|
}
|
|
905
920
|
catch { /* ignore */ }
|
|
906
921
|
}
|
|
@@ -980,6 +995,16 @@ async function runCommand(command, flags) {
|
|
|
980
995
|
}
|
|
981
996
|
return;
|
|
982
997
|
}
|
|
998
|
+
const providers = await detectProviders(cwd);
|
|
999
|
+
const availableProviders = providers.filter((p) => p.available);
|
|
1000
|
+
if (availableProviders.length === 0) {
|
|
1001
|
+
if (Boolean(flags.json)) {
|
|
1002
|
+
console.log(JSON.stringify({ error: "no_providers", message: "No supported provider CLI was found on PATH." }, null, 2));
|
|
1003
|
+
process.exitCode = CLI_EXIT_CODES.validation;
|
|
1004
|
+
return;
|
|
1005
|
+
}
|
|
1006
|
+
throw new CliError("No supported provider CLI was found on PATH. Install Codex, Cursor Agent, Claude Code, or Copilot CLI, then run `prompts-gpt doctor`.", CLI_EXIT_CODES.validation, { helpCommand: "providers" });
|
|
1007
|
+
}
|
|
983
1008
|
if (!sweepPromptFile && !Boolean(flags.json)) {
|
|
984
1009
|
const assets = await discoverWorkspaceAssets(cwd);
|
|
985
1010
|
if (assets.sweeps.length === 1) {
|
|
@@ -1024,8 +1049,6 @@ async function runCommand(command, flags) {
|
|
|
1024
1049
|
flags.iterations = String(iterFromFm);
|
|
1025
1050
|
}
|
|
1026
1051
|
}
|
|
1027
|
-
const providers = await detectProviders(cwd);
|
|
1028
|
-
const availableProviders = providers.filter((p) => p.available);
|
|
1029
1052
|
if (!getStringFlag(flags, "agent") && isTTYInteractive(flags) && !Boolean(flags.json)) {
|
|
1030
1053
|
if (availableProviders.length === 1) {
|
|
1031
1054
|
const only = availableProviders[0];
|
|
@@ -1053,6 +1076,12 @@ async function runCommand(command, flags) {
|
|
|
1053
1076
|
}
|
|
1054
1077
|
}
|
|
1055
1078
|
}
|
|
1079
|
+
const selectedAgent = resolveRunAgent(flags, config.defaultAgent);
|
|
1080
|
+
if (selectedAgent !== "router" && !providers.find((p) => p.provider === selectedAgent)?.available && !Boolean(flags.json)) {
|
|
1081
|
+
const selectedProvider = providers.find((p) => p.provider === selectedAgent);
|
|
1082
|
+
const available = availableProviders.map((p) => p.provider).join(", ");
|
|
1083
|
+
throw new CliError(`Provider ${selectedAgent} is not available. ${selectedProvider?.installHint ?? "Install the provider CLI and ensure it is on PATH."}${available ? ` Available providers: ${available}.` : ""}`, CLI_EXIT_CODES.validation, { helpCommand: "providers" });
|
|
1084
|
+
}
|
|
1056
1085
|
if (!getStringFlag(flags, "model") && isTTYInteractive(flags) && !Boolean(flags.json)) {
|
|
1057
1086
|
const currentAgent = resolveRunAgent(flags, config.defaultAgent);
|
|
1058
1087
|
if (currentAgent !== "router") {
|
|
@@ -1120,7 +1149,8 @@ async function runCommand(command, flags) {
|
|
|
1120
1149
|
`${formatDuration(iterTimeout * 1000)} per iteration`, `~${formatDuration(estMaxMs)}`,
|
|
1121
1150
|
String(maxRetries), tierBadge,
|
|
1122
1151
|
];
|
|
1123
|
-
const
|
|
1152
|
+
const stripEmoji = (s) => s.replace(/[\u{1F300}-\u{1F9FF}\u{2600}-\u{27BF}\u{2B50}]/gu, " ");
|
|
1153
|
+
const longestVal = Math.max(...boxValues.map((v) => stripEmoji(v).length), 30);
|
|
1124
1154
|
const innerW = longestVal + 16;
|
|
1125
1155
|
const uc = supportsColor();
|
|
1126
1156
|
const [TL, H, TR, V, ML, MR, BL, BR] = uc ? ["╔", "═", "╗", "║", "╠", "╣", "╚", "╝"] : ["+", "-", "+", "|", "+", "+", "+", "+"];
|
|
@@ -1369,13 +1399,18 @@ async function runCommand(command, flags) {
|
|
|
1369
1399
|
}
|
|
1370
1400
|
console.log("");
|
|
1371
1401
|
console.log("Inspect results:");
|
|
1372
|
-
console.log(`
|
|
1373
|
-
console.log(`
|
|
1402
|
+
console.log(` ${viewFileCmd} ${result.manifestFile}`);
|
|
1403
|
+
console.log(` ${listDirCmd} ${result.runDir}`);
|
|
1374
1404
|
if (Boolean(flags.open) && result.manifestFile) {
|
|
1375
1405
|
try {
|
|
1376
1406
|
const { spawn: openSpawn } = await import("node:child_process");
|
|
1377
|
-
|
|
1378
|
-
|
|
1407
|
+
if (process.platform === "win32") {
|
|
1408
|
+
openSpawn("cmd", ["/c", "start", "", result.manifestFile], { detached: true, stdio: "ignore", windowsHide: true }).unref();
|
|
1409
|
+
}
|
|
1410
|
+
else {
|
|
1411
|
+
const openCmd = process.platform === "darwin" ? "open" : "xdg-open";
|
|
1412
|
+
openSpawn(openCmd, [result.manifestFile], { detached: true, stdio: "ignore" }).unref();
|
|
1413
|
+
}
|
|
1379
1414
|
}
|
|
1380
1415
|
catch { /* ignore */ }
|
|
1381
1416
|
}
|
|
@@ -1421,11 +1456,7 @@ async function runCommand(command, flags) {
|
|
|
1421
1456
|
if (!assets.credentialsFound) {
|
|
1422
1457
|
let networkOk = true;
|
|
1423
1458
|
try {
|
|
1424
|
-
|
|
1425
|
-
fetch("https://prompts-gpt.com/api/health", { method: "HEAD" }),
|
|
1426
|
-
new Promise((_, rej) => setTimeout(() => rej(new Error("timeout")), 5000)),
|
|
1427
|
-
]);
|
|
1428
|
-
networkOk = netCheck instanceof Response;
|
|
1459
|
+
networkOk = (await checkPromptsGptSiteReachable(DEFAULT_PROMPTS_GPT_API_URL)).ok;
|
|
1429
1460
|
}
|
|
1430
1461
|
catch {
|
|
1431
1462
|
networkOk = false;
|
|
@@ -1540,7 +1571,7 @@ async function runCommand(command, flags) {
|
|
|
1540
1571
|
const cmd = action === "sweep" ? "sweep" : "run";
|
|
1541
1572
|
console.log(`\nRunning: prompts-gpt ${cmd} -f ${file}\n`);
|
|
1542
1573
|
const { spawnSync: spSync } = await import("node:child_process");
|
|
1543
|
-
const cliEntry =
|
|
1574
|
+
const cliEntry = resolveCliEntry();
|
|
1544
1575
|
const result = spSync(process.execPath, [cliEntry, cmd, "-f", file], { stdio: "inherit", cwd });
|
|
1545
1576
|
process.exitCode = result.status ?? 1;
|
|
1546
1577
|
return;
|
|
@@ -1678,7 +1709,7 @@ async function runCommand(command, flags) {
|
|
|
1678
1709
|
const runQs = await interactiveInput("Run quickstart now? [Y/n]", "Y");
|
|
1679
1710
|
if (runQs.toLowerCase() !== "n" && runQs.toLowerCase() !== "no") {
|
|
1680
1711
|
const { spawnSync: spSync } = await import("node:child_process");
|
|
1681
|
-
const cliEntry =
|
|
1712
|
+
const cliEntry = resolveCliEntry();
|
|
1682
1713
|
const qsResult = spSync(process.execPath, [cliEntry, "quickstart", "--cwd", cwd], { stdio: "inherit", cwd });
|
|
1683
1714
|
process.exitCode = qsResult.status ?? 1;
|
|
1684
1715
|
return;
|
|
@@ -1786,7 +1817,7 @@ async function runCommand(command, flags) {
|
|
|
1786
1817
|
if (runNow.toLowerCase() !== "n" && runNow.toLowerCase() !== "no") {
|
|
1787
1818
|
console.log(`\nRunning: prompts-gpt run -f ${genFile}\n`);
|
|
1788
1819
|
const { spawnSync: spSync } = await import("node:child_process");
|
|
1789
|
-
const cliEntry =
|
|
1820
|
+
const cliEntry = resolveCliEntry();
|
|
1790
1821
|
const genResult = spSync(process.execPath, [cliEntry, "run", "-f", genFile], { stdio: "inherit", cwd });
|
|
1791
1822
|
process.exitCode = genResult.status ?? 1;
|
|
1792
1823
|
}
|
|
@@ -1909,7 +1940,7 @@ async function runCommand(command, flags) {
|
|
|
1909
1940
|
if (syncNow.toLowerCase() !== "n" && syncNow.toLowerCase() !== "no") {
|
|
1910
1941
|
console.log("\nSyncing...");
|
|
1911
1942
|
const { spawnSync: spSync } = await import("node:child_process");
|
|
1912
|
-
const cliEntry =
|
|
1943
|
+
const cliEntry = resolveCliEntry();
|
|
1913
1944
|
const projCwd = getResolvedCwd(flags);
|
|
1914
1945
|
const syncResult = spSync(process.execPath, [cliEntry, "sync", "--cwd", projCwd], { stdio: "inherit", cwd: projCwd });
|
|
1915
1946
|
process.exitCode = syncResult.status ?? 1;
|
|
@@ -2654,7 +2685,7 @@ async function getLastUsedModel(cwd, provider) {
|
|
|
2654
2685
|
}
|
|
2655
2686
|
async function saveLastUsedModel(cwd, provider, model) {
|
|
2656
2687
|
try {
|
|
2657
|
-
const { readFile: fsRead, writeFile: fsWrite, mkdir: fsMkdir
|
|
2688
|
+
const { readFile: fsRead, writeFile: fsWrite, mkdir: fsMkdir } = await import("node:fs/promises");
|
|
2658
2689
|
const dir = path.resolve(cwd, DEFAULT_PROMPTS_GPT_OUT_DIR);
|
|
2659
2690
|
await fsMkdir(dir, { recursive: true });
|
|
2660
2691
|
const filePath = path.resolve(dir, ".last-models");
|
|
@@ -2664,9 +2695,7 @@ async function saveLastUsedModel(cwd, provider, model) {
|
|
|
2664
2695
|
}
|
|
2665
2696
|
catch { /* new file */ }
|
|
2666
2697
|
existing[provider] = model;
|
|
2667
|
-
|
|
2668
|
-
await fsWrite(tmpPath, JSON.stringify(existing, null, 2));
|
|
2669
|
-
await rename(tmpPath, filePath);
|
|
2698
|
+
await fsWrite(filePath, JSON.stringify(existing, null, 2));
|
|
2670
2699
|
}
|
|
2671
2700
|
catch { /* ignore */ }
|
|
2672
2701
|
}
|
|
@@ -2686,9 +2715,8 @@ const PROVIDER_MODELS = Object.freeze({
|
|
|
2686
2715
|
{ value: "gpt-4.1", label: "gpt-4.1 — legacy", tier: "budget" },
|
|
2687
2716
|
],
|
|
2688
2717
|
claude: [
|
|
2689
|
-
{ value: "claude-
|
|
2690
|
-
{ value: "claude-opus-4-
|
|
2691
|
-
{ value: "claude-sonnet-4-6", label: "claude-sonnet-4-6 — speed + intelligence", tier: "standard" },
|
|
2718
|
+
{ value: "claude-sonnet-4-6", label: "claude-sonnet-4-6 — speed + intelligence ★", tier: "standard" },
|
|
2719
|
+
{ value: "claude-opus-4-5", label: "claude-opus-4-5 — previous gen opus", tier: "frontier" },
|
|
2692
2720
|
{ value: "claude-haiku-4-5", label: "claude-haiku-4-5 — fastest near-frontier", tier: "fast" },
|
|
2693
2721
|
],
|
|
2694
2722
|
cursor: [
|
|
@@ -2702,6 +2730,7 @@ const PROVIDER_MODELS = Object.freeze({
|
|
|
2702
2730
|
{ value: "gpt-5.3-codex", label: "gpt-5.3-codex — OpenAI codex", tier: "standard" },
|
|
2703
2731
|
{ value: "gpt-5.4-mini", label: "gpt-5.4-mini — fast & affordable", tier: "fast" },
|
|
2704
2732
|
{ value: "gemini-3.1-pro", label: "gemini-3.1-pro — Google frontier", tier: "standard" },
|
|
2733
|
+
{ value: "grok-4.3", label: "grok-4.3 — xAI frontier", tier: "frontier" },
|
|
2705
2734
|
{ value: "claude-4.5-opus", label: "claude-4.5-opus — previous gen opus", tier: "standard" },
|
|
2706
2735
|
],
|
|
2707
2736
|
copilot: [
|
|
@@ -2709,11 +2738,11 @@ const PROVIDER_MODELS = Object.freeze({
|
|
|
2709
2738
|
{ value: "gpt-5.5", label: "gpt-5.5 — frontier", tier: "frontier" },
|
|
2710
2739
|
{ value: "gpt-5.4-mini", label: "gpt-5.4-mini — fast", tier: "fast" },
|
|
2711
2740
|
{ value: "claude-sonnet-4-6", label: "claude-sonnet-4-6 — Anthropic", tier: "standard" },
|
|
2712
|
-
{ value: "claude-opus-4-
|
|
2741
|
+
{ value: "claude-opus-4-5", label: "claude-opus-4-5 — Anthropic frontier", tier: "frontier" },
|
|
2713
2742
|
],
|
|
2714
2743
|
});
|
|
2715
2744
|
const MODEL_ALIASES = {
|
|
2716
|
-
opus: "claude-opus-4-
|
|
2745
|
+
opus: "claude-opus-4-5",
|
|
2717
2746
|
sonnet: "claude-sonnet-4-6",
|
|
2718
2747
|
haiku: "claude-haiku-4-5",
|
|
2719
2748
|
codex: "gpt-5.3-codex",
|
|
@@ -2723,6 +2752,7 @@ const MODEL_ALIASES = {
|
|
|
2723
2752
|
composer: "composer-2",
|
|
2724
2753
|
fast: "composer-2-fast",
|
|
2725
2754
|
gemini: "gemini-3.1-pro",
|
|
2755
|
+
grok: "grok-4.3",
|
|
2726
2756
|
o3: "o3",
|
|
2727
2757
|
pro: "gpt-5.5-pro",
|
|
2728
2758
|
};
|
|
@@ -3276,6 +3306,19 @@ function supportsColor() {
|
|
|
3276
3306
|
function colorize(text, code) {
|
|
3277
3307
|
return supportsColor() ? `${code}${text}\x1b[0m` : text;
|
|
3278
3308
|
}
|
|
3309
|
+
const viewFileCmd = process.platform === "win32" ? "type" : "cat";
|
|
3310
|
+
const listDirCmd = process.platform === "win32" ? "dir" : "ls";
|
|
3311
|
+
function resolveCliEntry() {
|
|
3312
|
+
if (process.argv[1])
|
|
3313
|
+
return process.argv[1];
|
|
3314
|
+
try {
|
|
3315
|
+
const { fileURLToPath } = require("node:url");
|
|
3316
|
+
return fileURLToPath(import.meta.url);
|
|
3317
|
+
}
|
|
3318
|
+
catch {
|
|
3319
|
+
return "cli.js";
|
|
3320
|
+
}
|
|
3321
|
+
}
|
|
3279
3322
|
function isTTYInteractive(flags) {
|
|
3280
3323
|
if (!process.stdin.isTTY || !process.stdout.isTTY)
|
|
3281
3324
|
return false;
|
|
@@ -3288,7 +3331,7 @@ function isTTYInteractive(flags) {
|
|
|
3288
3331
|
return false;
|
|
3289
3332
|
if (process.env.PROMPTS_GPT_NON_INTERACTIVE === "1" || process.env.PROMPTS_GPT_NON_INTERACTIVE === "true")
|
|
3290
3333
|
return false;
|
|
3291
|
-
if (process.env.POWERSHELL_ISE === "1"
|
|
3334
|
+
if (process.env.POWERSHELL_ISE === "1")
|
|
3292
3335
|
return false;
|
|
3293
3336
|
return true;
|
|
3294
3337
|
}
|
|
@@ -3296,6 +3339,9 @@ function interactiveSelect(prompt, options) {
|
|
|
3296
3339
|
if (options.length === 0) {
|
|
3297
3340
|
return Promise.reject(new CliError("No options available for selection.", CLI_EXIT_CODES.usage));
|
|
3298
3341
|
}
|
|
3342
|
+
if (!Array.isArray(options) || options.some((o) => typeof o.label !== "string" || typeof o.value !== "string")) {
|
|
3343
|
+
return Promise.reject(new CliError("Invalid options for selection.", CLI_EXIT_CODES.usage));
|
|
3344
|
+
}
|
|
3299
3345
|
if (options.length === 1) {
|
|
3300
3346
|
return Promise.resolve(options[0].value);
|
|
3301
3347
|
}
|
|
@@ -3309,7 +3355,7 @@ function interactiveSelect(prompt, options) {
|
|
|
3309
3355
|
let cursor = 0;
|
|
3310
3356
|
let escBuf = "";
|
|
3311
3357
|
let filterText = "";
|
|
3312
|
-
const termRows = typeof process.stdout.rows === "number" && process.stdout.rows >
|
|
3358
|
+
const termRows = typeof process.stdout.rows === "number" && process.stdout.rows > 2 ? process.stdout.rows : 24;
|
|
3313
3359
|
const maxVisible = Math.min(options.length, Math.max(3, termRows - 4));
|
|
3314
3360
|
const useUnicode = supportsColor();
|
|
3315
3361
|
const pointer = useUnicode ? "❯" : ">";
|
|
@@ -3333,7 +3379,7 @@ function interactiveSelect(prompt, options) {
|
|
|
3333
3379
|
}
|
|
3334
3380
|
stdout.write(`${hints}\n`);
|
|
3335
3381
|
};
|
|
3336
|
-
const supportsAnsiCursor = supportsColor() || (process.platform === "win32" && Boolean(process.env.WT_SESSION));
|
|
3382
|
+
const supportsAnsiCursor = supportsColor() || (process.platform === "win32" && Boolean(process.env.WT_SESSION || process.env.TERM_PROGRAM || process.env.ConEmuANSI));
|
|
3337
3383
|
const render = () => {
|
|
3338
3384
|
const visibleCount = Math.min(maxVisible, options.length);
|
|
3339
3385
|
const footerLines = 1 + (options.length > maxVisible ? 1 : 0) + 1;
|
|
@@ -3342,7 +3388,8 @@ function interactiveSelect(prompt, options) {
|
|
|
3342
3388
|
stdout.write(`\x1b[${lines}A\x1b[J`);
|
|
3343
3389
|
}
|
|
3344
3390
|
else {
|
|
3345
|
-
|
|
3391
|
+
for (let i = 0; i < lines; i++)
|
|
3392
|
+
stdout.write("\x1b[A\x1b[2K");
|
|
3346
3393
|
}
|
|
3347
3394
|
const posLabel = options.length > 1 ? ` (${cursor + 1}/${options.length})` : "";
|
|
3348
3395
|
const filterLabel = filterText ? colorize(` filter: "${filterText}"`, "\x1b[33m") : "";
|
|
@@ -3456,8 +3503,11 @@ function interactiveSelect(prompt, options) {
|
|
|
3456
3503
|
}
|
|
3457
3504
|
if (ch === "\x03") {
|
|
3458
3505
|
cleanup();
|
|
3459
|
-
|
|
3460
|
-
|
|
3506
|
+
try {
|
|
3507
|
+
stdout.write("\n");
|
|
3508
|
+
}
|
|
3509
|
+
catch { /* stdout may be closed */ }
|
|
3510
|
+
reject(new CliError("Selection cancelled.", CLI_EXIT_CODES.general));
|
|
3461
3511
|
return;
|
|
3462
3512
|
}
|
|
3463
3513
|
if (ch === "\r" || ch === "\n") {
|
|
@@ -3514,16 +3564,37 @@ async function interactiveInput(prompt, defaultValue) {
|
|
|
3514
3564
|
}
|
|
3515
3565
|
const { createInterface } = await import("node:readline");
|
|
3516
3566
|
return new Promise((resolve) => {
|
|
3567
|
+
let resolved = false;
|
|
3517
3568
|
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
3518
3569
|
const suffix = defaultValue ? ` (${defaultValue})` : "";
|
|
3519
3570
|
rl.question(`${prompt}${suffix}: `, (answer) => {
|
|
3571
|
+
if (resolved)
|
|
3572
|
+
return;
|
|
3573
|
+
resolved = true;
|
|
3520
3574
|
rl.close();
|
|
3521
3575
|
rl.removeAllListeners();
|
|
3522
3576
|
resolve((answer.trim() || defaultValue || "").slice(0, 1024));
|
|
3523
3577
|
});
|
|
3524
|
-
rl.on("close", () =>
|
|
3578
|
+
rl.on("close", () => {
|
|
3579
|
+
if (resolved)
|
|
3580
|
+
return;
|
|
3581
|
+
resolved = true;
|
|
3582
|
+
resolve(defaultValue || "");
|
|
3583
|
+
});
|
|
3525
3584
|
});
|
|
3526
3585
|
}
|
|
3586
|
+
async function checkPromptsGptSiteReachable(apiUrl) {
|
|
3587
|
+
const target = new URL("/", apiUrl).toString();
|
|
3588
|
+
const request = (method) => Promise.race([
|
|
3589
|
+
globalThis.fetch(target, { method }),
|
|
3590
|
+
new Promise((_, rej) => setTimeout(() => rej(new Error("timeout")), 5000)),
|
|
3591
|
+
]);
|
|
3592
|
+
let response = await request("HEAD");
|
|
3593
|
+
if (response.status === 405) {
|
|
3594
|
+
response = await request("GET");
|
|
3595
|
+
}
|
|
3596
|
+
return { ok: response.ok, status: response.status };
|
|
3597
|
+
}
|
|
3527
3598
|
async function readSweepFrontmatter(filePath) {
|
|
3528
3599
|
try {
|
|
3529
3600
|
const { readFile: fsRead } = await import("node:fs/promises");
|
|
@@ -3581,10 +3652,13 @@ function printDataTransmissionNotice(command, input) {
|
|
|
3581
3652
|
}
|
|
3582
3653
|
main().catch((error) => {
|
|
3583
3654
|
if (error instanceof CliError) {
|
|
3584
|
-
|
|
3585
|
-
|
|
3586
|
-
|
|
3655
|
+
try {
|
|
3656
|
+
console.error(error.message);
|
|
3657
|
+
if (error.helpCommand) {
|
|
3658
|
+
console.error(`Run \`prompts-gpt help${error.helpCommand ? ` ${error.helpCommand}` : ""}\` for usage.`);
|
|
3659
|
+
}
|
|
3587
3660
|
}
|
|
3661
|
+
catch { /* stderr closed or broken pipe */ }
|
|
3588
3662
|
process.exitCode = error.exitCode;
|
|
3589
3663
|
return;
|
|
3590
3664
|
}
|
|
@@ -3645,7 +3719,7 @@ async function extractRunDiagnostics(logFile, provider, model) {
|
|
|
3645
3719
|
}
|
|
3646
3720
|
if (diagnostics.length === 0) {
|
|
3647
3721
|
diagnostics.push(`${provider} exited with code 1. Check the log for details:`);
|
|
3648
|
-
diagnostics.push(`
|
|
3722
|
+
diagnostics.push(` ${viewFileCmd} ${logFile}`);
|
|
3649
3723
|
diagnostics.push(`Try a different provider: prompts-gpt run --agent claude`);
|
|
3650
3724
|
}
|
|
3651
3725
|
}
|