prompts-gpt 0.2.11 → 0.2.12

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 CHANGED
@@ -450,15 +450,12 @@ async function runCommand(command, flags) {
450
450
  }
451
451
  else {
452
452
  try {
453
- const healthRes = await Promise.race([
454
- globalThis.fetch(`${DEFAULT_PROMPTS_GPT_API_URL}/api/health`, { method: "HEAD" }),
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 ${healthRes.status}`);
458
+ console.log(` ⚠ prompts-gpt.com responded with status ${siteCheck.status ?? "unknown"}`);
462
459
  }
463
460
  }
464
461
  catch (err) {
@@ -980,6 +977,11 @@ async function runCommand(command, flags) {
980
977
  }
981
978
  return;
982
979
  }
980
+ const providers = await detectProviders(cwd);
981
+ const availableProviders = providers.filter((p) => p.available);
982
+ if (availableProviders.length === 0 && !Boolean(flags.json)) {
983
+ 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" });
984
+ }
983
985
  if (!sweepPromptFile && !Boolean(flags.json)) {
984
986
  const assets = await discoverWorkspaceAssets(cwd);
985
987
  if (assets.sweeps.length === 1) {
@@ -1024,8 +1026,6 @@ async function runCommand(command, flags) {
1024
1026
  flags.iterations = String(iterFromFm);
1025
1027
  }
1026
1028
  }
1027
- const providers = await detectProviders(cwd);
1028
- const availableProviders = providers.filter((p) => p.available);
1029
1029
  if (!getStringFlag(flags, "agent") && isTTYInteractive(flags) && !Boolean(flags.json)) {
1030
1030
  if (availableProviders.length === 1) {
1031
1031
  const only = availableProviders[0];
@@ -1053,6 +1053,12 @@ async function runCommand(command, flags) {
1053
1053
  }
1054
1054
  }
1055
1055
  }
1056
+ const selectedAgent = resolveRunAgent(flags, config.defaultAgent);
1057
+ if (selectedAgent !== "router" && !providers.find((p) => p.provider === selectedAgent)?.available && !Boolean(flags.json)) {
1058
+ const selectedProvider = providers.find((p) => p.provider === selectedAgent);
1059
+ const available = availableProviders.map((p) => p.provider).join(", ");
1060
+ 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" });
1061
+ }
1056
1062
  if (!getStringFlag(flags, "model") && isTTYInteractive(flags) && !Boolean(flags.json)) {
1057
1063
  const currentAgent = resolveRunAgent(flags, config.defaultAgent);
1058
1064
  if (currentAgent !== "router") {
@@ -1421,11 +1427,7 @@ async function runCommand(command, flags) {
1421
1427
  if (!assets.credentialsFound) {
1422
1428
  let networkOk = true;
1423
1429
  try {
1424
- const netCheck = await Promise.race([
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;
1430
+ networkOk = (await checkPromptsGptSiteReachable(DEFAULT_PROMPTS_GPT_API_URL)).ok;
1429
1431
  }
1430
1432
  catch {
1431
1433
  networkOk = false;
@@ -2686,9 +2688,8 @@ const PROVIDER_MODELS = Object.freeze({
2686
2688
  { value: "gpt-4.1", label: "gpt-4.1 — legacy", tier: "budget" },
2687
2689
  ],
2688
2690
  claude: [
2689
- { value: "claude-opus-4-7", label: "claude-opus-4-7latest, most capable", tier: "frontier" },
2690
- { value: "claude-opus-4-6", label: "claude-opus-4-6 — previous gen opus", tier: "frontier" },
2691
- { value: "claude-sonnet-4-6", label: "claude-sonnet-4-6 — speed + intelligence", tier: "standard" },
2691
+ { value: "claude-sonnet-4-6", label: "claude-sonnet-4-6speed + intelligence ★", tier: "standard" },
2692
+ { value: "claude-opus-4-5", label: "claude-opus-4-5 — previous gen opus", tier: "frontier" },
2692
2693
  { value: "claude-haiku-4-5", label: "claude-haiku-4-5 — fastest near-frontier", tier: "fast" },
2693
2694
  ],
2694
2695
  cursor: [
@@ -2702,6 +2703,7 @@ const PROVIDER_MODELS = Object.freeze({
2702
2703
  { value: "gpt-5.3-codex", label: "gpt-5.3-codex — OpenAI codex", tier: "standard" },
2703
2704
  { value: "gpt-5.4-mini", label: "gpt-5.4-mini — fast & affordable", tier: "fast" },
2704
2705
  { value: "gemini-3.1-pro", label: "gemini-3.1-pro — Google frontier", tier: "standard" },
2706
+ { value: "grok-4.3", label: "grok-4.3 — xAI frontier", tier: "frontier" },
2705
2707
  { value: "claude-4.5-opus", label: "claude-4.5-opus — previous gen opus", tier: "standard" },
2706
2708
  ],
2707
2709
  copilot: [
@@ -2709,11 +2711,11 @@ const PROVIDER_MODELS = Object.freeze({
2709
2711
  { value: "gpt-5.5", label: "gpt-5.5 — frontier", tier: "frontier" },
2710
2712
  { value: "gpt-5.4-mini", label: "gpt-5.4-mini — fast", tier: "fast" },
2711
2713
  { value: "claude-sonnet-4-6", label: "claude-sonnet-4-6 — Anthropic", tier: "standard" },
2712
- { value: "claude-opus-4-7", label: "claude-opus-4-7 — Anthropic frontier", tier: "frontier" },
2714
+ { value: "claude-opus-4-5", label: "claude-opus-4-5 — Anthropic frontier", tier: "frontier" },
2713
2715
  ],
2714
2716
  });
2715
2717
  const MODEL_ALIASES = {
2716
- opus: "claude-opus-4-7",
2718
+ opus: "claude-opus-4-5",
2717
2719
  sonnet: "claude-sonnet-4-6",
2718
2720
  haiku: "claude-haiku-4-5",
2719
2721
  codex: "gpt-5.3-codex",
@@ -2723,6 +2725,7 @@ const MODEL_ALIASES = {
2723
2725
  composer: "composer-2",
2724
2726
  fast: "composer-2-fast",
2725
2727
  gemini: "gemini-3.1-pro",
2728
+ grok: "grok-4.3",
2726
2729
  o3: "o3",
2727
2730
  pro: "gpt-5.5-pro",
2728
2731
  };
@@ -3296,6 +3299,9 @@ function interactiveSelect(prompt, options) {
3296
3299
  if (options.length === 0) {
3297
3300
  return Promise.reject(new CliError("No options available for selection.", CLI_EXIT_CODES.usage));
3298
3301
  }
3302
+ if (!Array.isArray(options) || options.some((o) => typeof o.label !== "string" || typeof o.value !== "string")) {
3303
+ return Promise.reject(new CliError("Invalid options for selection.", CLI_EXIT_CODES.usage));
3304
+ }
3299
3305
  if (options.length === 1) {
3300
3306
  return Promise.resolve(options[0].value);
3301
3307
  }
@@ -3309,7 +3315,7 @@ function interactiveSelect(prompt, options) {
3309
3315
  let cursor = 0;
3310
3316
  let escBuf = "";
3311
3317
  let filterText = "";
3312
- const termRows = typeof process.stdout.rows === "number" && process.stdout.rows > 0 ? process.stdout.rows : 24;
3318
+ const termRows = typeof process.stdout.rows === "number" && process.stdout.rows > 2 ? process.stdout.rows : 24;
3313
3319
  const maxVisible = Math.min(options.length, Math.max(3, termRows - 4));
3314
3320
  const useUnicode = supportsColor();
3315
3321
  const pointer = useUnicode ? "❯" : ">";
@@ -3456,8 +3462,11 @@ function interactiveSelect(prompt, options) {
3456
3462
  }
3457
3463
  if (ch === "\x03") {
3458
3464
  cleanup();
3459
- stdout.write("\n");
3460
- process.exit(130);
3465
+ try {
3466
+ stdout.write("\n");
3467
+ }
3468
+ catch { /* stdout may be closed */ }
3469
+ reject(new CliError("Selection cancelled.", CLI_EXIT_CODES.general));
3461
3470
  return;
3462
3471
  }
3463
3472
  if (ch === "\r" || ch === "\n") {
@@ -3514,16 +3523,37 @@ async function interactiveInput(prompt, defaultValue) {
3514
3523
  }
3515
3524
  const { createInterface } = await import("node:readline");
3516
3525
  return new Promise((resolve) => {
3526
+ let resolved = false;
3517
3527
  const rl = createInterface({ input: process.stdin, output: process.stdout });
3518
3528
  const suffix = defaultValue ? ` (${defaultValue})` : "";
3519
3529
  rl.question(`${prompt}${suffix}: `, (answer) => {
3530
+ if (resolved)
3531
+ return;
3532
+ resolved = true;
3520
3533
  rl.close();
3521
3534
  rl.removeAllListeners();
3522
3535
  resolve((answer.trim() || defaultValue || "").slice(0, 1024));
3523
3536
  });
3524
- rl.on("close", () => resolve(defaultValue || ""));
3537
+ rl.on("close", () => {
3538
+ if (resolved)
3539
+ return;
3540
+ resolved = true;
3541
+ resolve(defaultValue || "");
3542
+ });
3525
3543
  });
3526
3544
  }
3545
+ async function checkPromptsGptSiteReachable(apiUrl) {
3546
+ const target = new URL("/", apiUrl).toString();
3547
+ const request = (method) => Promise.race([
3548
+ globalThis.fetch(target, { method }),
3549
+ new Promise((_, rej) => setTimeout(() => rej(new Error("timeout")), 5000)),
3550
+ ]);
3551
+ let response = await request("HEAD");
3552
+ if (response.status === 405) {
3553
+ response = await request("GET");
3554
+ }
3555
+ return { ok: response.ok, status: response.status };
3556
+ }
3527
3557
  async function readSweepFrontmatter(filePath) {
3528
3558
  try {
3529
3559
  const { readFile: fsRead } = await import("node:fs/promises");
@@ -3581,10 +3611,13 @@ function printDataTransmissionNotice(command, input) {
3581
3611
  }
3582
3612
  main().catch((error) => {
3583
3613
  if (error instanceof CliError) {
3584
- console.error(error.message);
3585
- if (error.helpCommand) {
3586
- console.error(`Run \`prompts-gpt help${error.helpCommand ? ` ${error.helpCommand}` : ""}\` for usage.`);
3614
+ try {
3615
+ console.error(error.message);
3616
+ if (error.helpCommand) {
3617
+ console.error(`Run \`prompts-gpt help${error.helpCommand ? ` ${error.helpCommand}` : ""}\` for usage.`);
3618
+ }
3587
3619
  }
3620
+ catch { /* stderr closed or broken pipe */ }
3588
3621
  process.exitCode = error.exitCode;
3589
3622
  return;
3590
3623
  }