prompts-gpt 0.2.9 → 0.2.10

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/README.md CHANGED
@@ -115,8 +115,10 @@ prompts-gpt models --provider codex
115
115
  prompts-gpt sync-models
116
116
 
117
117
  # Use model aliases for shorter commands
118
- prompts-gpt run --model opus # resolves to claude-4.6-opus-high
118
+ prompts-gpt run --model opus # resolves to claude-opus-4-7
119
119
  prompts-gpt run --model mini # resolves to gpt-5.4-mini
120
+ prompts-gpt run --model pro # resolves to gpt-5.5-pro
121
+ prompts-gpt run --model o3 # resolves to o3
120
122
 
121
123
  # Sync from cloud
122
124
  prompts-gpt sync --agent all
package/dist/cli.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { existsSync, readFileSync } from "node:fs";
2
+ import { existsSync, readFileSync, statSync, readdirSync } from "node:fs";
3
3
  import path from "node:path";
4
4
  import { parseArgs } from "node:util";
5
5
  import { hasTokenUsage, DEFAULT_PROMPTS_GPT_API_URL, DEFAULT_PROMPTS_GPT_OUT_DIR, DEFAULT_RUN_CONFIG_PATH, PROMPTS_GPT_CREDENTIALS_FILE, PromptsGptApiError, PromptsGptClient, doctor, initRunConfig, loadRunConfig, normalizeOrchestrationAgent, ORCHESTRATION_AGENT_PROFILES, runBatch, runPrompt, resolveRunProvider, warnModelProviderMismatch, sweepPrompt, validateRunConfig, discoverWorkspaceAssets, SUPPORTED_AGENT_TARGETS, detectProviders, loadLocalCredentials, saveLocalCredentials, syncPrompts, writeAgentFiles, writePromptManifest, writePromptMarkdownFiles, ensureGitignoreEntry, } from "./index.js";
@@ -79,7 +79,10 @@ async function main() {
79
79
  }
80
80
  const command = asCommandName(first);
81
81
  if (!command) {
82
- throw new CliError(`Unknown command: ${first}.`, CLI_EXIT_CODES.usage);
82
+ const suggestion = COMMANDS.find((c) => c.startsWith(first.slice(0, 3)));
83
+ const hint = suggestion ? ` Did you mean \`prompts-gpt ${suggestion}\`?` : "";
84
+ const installHint = "\nIf you installed from npm, ensure you have the latest version: npm install -g prompts-gpt@latest";
85
+ throw new CliError(`Unknown command: ${first}.${hint}${installHint}`, CLI_EXIT_CODES.usage);
83
86
  }
84
87
  if (!isRunnableCommand(command)) {
85
88
  throw new CliError(`Unknown command: ${first}.`, CLI_EXIT_CODES.usage, {
@@ -617,8 +620,7 @@ async function runCommand(command, flags) {
617
620
  const statusModelCache = path.resolve(cwd, DEFAULT_PROMPTS_GPT_OUT_DIR, ".models.json");
618
621
  if (existsSync(statusModelCache)) {
619
622
  try {
620
- const fs = require("node:fs");
621
- const mStat = fs.statSync(statusModelCache);
623
+ const mStat = statSync(statusModelCache);
622
624
  const ageMs = Date.now() - mStat.mtimeMs;
623
625
  const ageDays = Math.floor(ageMs / (1000 * 60 * 60 * 24));
624
626
  console.log(` Models: ${ageDays <= 7 ? "✓" : "⚠"} synced ${ageDays === 0 ? "today" : `${ageDays}d ago`}${ageDays > 7 ? " — run 'prompts-gpt sync-models'" : ""}`);
@@ -629,18 +631,6 @@ async function runCommand(command, flags) {
629
631
  console.log(" Models: — not synced. Run 'prompts-gpt sync-models'");
630
632
  }
631
633
  console.log("");
632
- const lockFile = path.resolve(cwd, ".sweep.lock");
633
- if (existsSync(lockFile)) {
634
- try {
635
- const { readFile: fsRead } = await import("node:fs/promises");
636
- const lockData = JSON.parse(await fsRead(lockFile, "utf8"));
637
- console.log(` Sweep lock: ⚠ active (PID ${lockData.pid}, started ${lockData.startedAt})`);
638
- }
639
- catch {
640
- console.log(" Sweep lock: ⚠ found but unreadable");
641
- }
642
- }
643
- console.log("");
644
634
  if (assets.prompts.length > 0 && availableProviders.length > 0) {
645
635
  console.log("Ready to run:");
646
636
  console.log(` prompts-gpt run --prompt-file .prompts-gpt/${assets.prompts[0].file}`);
@@ -1114,7 +1104,7 @@ async function runCommand(command, flags) {
1114
1104
  const resolvedP = resolveRunProvider(agent, providers, config.providerOrder);
1115
1105
  const check = validateModelForProvider(sweepModelFlag, resolvedP);
1116
1106
  if (!check.valid) {
1117
- console.log(`⚠ Model "${sweepModelFlag}" may not be available for ${resolvedP}.${check.suggestion ? ` Did you mean "${check.suggestion}"?` : ""}`);
1107
+ console.log(`⚠ Model "${sweepModelFlag}" may not be available for ${resolvedP}.${check.suggestion ? ` Did you mean "${check.suggestion}"?` : ""}\n Run \`prompts-gpt sweep --list-models --agent ${resolvedP}\` to see available models.`);
1118
1108
  }
1119
1109
  }
1120
1110
  if (isTTYInteractive(flags) && !Boolean(flags.json) && !Boolean(flags["dry-run"])) {
@@ -1135,14 +1125,16 @@ async function runCommand(command, flags) {
1135
1125
  ];
1136
1126
  const longestVal = Math.max(...boxValues.map((v) => v.length), 30);
1137
1127
  const innerW = longestVal + 16;
1138
- const bar = "═".repeat(innerW);
1128
+ const uc = supportsColor();
1129
+ const [TL, H, TR, V, ML, MR, BL, BR] = uc ? ["╔", "═", "╗", "║", "╠", "╣", "╚", "╝"] : ["+", "-", "+", "|", "+", "+", "+", "+"];
1130
+ const bar = H.repeat(innerW);
1139
1131
  const pad = (v) => v.padEnd(longestVal);
1140
- const row = (label, val) => `${colorize("║", "\x1b[36m")} ${label.padEnd(12)} ${pad(val)} ${colorize("║", "\x1b[36m")}`;
1132
+ const row = (label, val) => `${colorize(V, "\x1b[36m")} ${label.padEnd(12)} ${pad(val)} ${colorize(V, "\x1b[36m")}`;
1141
1133
  const titleText = "Prompts-GPT Sweep";
1142
1134
  const titlePad = Math.max(0, Math.floor((innerW - titleText.length) / 2));
1143
- console.log(colorize(`╔${bar}╗`, "\x1b[36m"));
1144
- console.log(colorize(`║${" ".repeat(titlePad)}${titleText}${" ".repeat(innerW - titlePad - titleText.length)}║`, "\x1b[36m"));
1145
- console.log(colorize(`╠${bar}╣`, "\x1b[36m"));
1135
+ console.log(colorize(`${TL}${bar}${TR}`, "\x1b[36m"));
1136
+ console.log(colorize(`${V}${" ".repeat(titlePad)}${titleText}${" ".repeat(innerW - titlePad - titleText.length)}${V}`, "\x1b[36m"));
1137
+ console.log(colorize(`${ML}${bar}${MR}`, "\x1b[36m"));
1146
1138
  console.log(row("Sweep:", path.basename(sweepFile)));
1147
1139
  console.log(row("Provider:", resolvedProvider));
1148
1140
  console.log(row("Model:", resolvedModel));
@@ -1152,9 +1144,9 @@ async function runCommand(command, flags) {
1152
1144
  console.log(row("Retries:", String(maxRetries)));
1153
1145
  console.log(row("Tier:", tierBadge));
1154
1146
  if (modelTier === "frontier") {
1155
- console.log(`${colorize("║", "\x1b[36m")} ${colorize("⚠ Frontier model — higher cost per token", "\x1b[33m")}${" ".repeat(Math.max(0, innerW - 43))} ${colorize("║", "\x1b[36m")}`);
1147
+ console.log(`${colorize(V, "\x1b[36m")} ${colorize(uc ? "⚠ Frontier model — higher cost per token" : "! Frontier model -- higher cost per token", "\x1b[33m")}${" ".repeat(Math.max(0, innerW - 43))} ${colorize(V, "\x1b[36m")}`);
1156
1148
  }
1157
- console.log(colorize(`╚${bar}╝`, "\x1b[36m"));
1149
+ console.log(colorize(`${BL}${bar}${BR}`, "\x1b[36m"));
1158
1150
  console.log("");
1159
1151
  const confirmOpts = [
1160
1152
  { label: "Yes, run this sweep", value: "y" },
@@ -1178,12 +1170,11 @@ async function runCommand(command, flags) {
1178
1170
  console.log(`Branch: ${report.gitBranch} | Dirty files: ${report.gitDirtyFiles} | Free disk: ${report.diskFreeMb}MB`);
1179
1171
  console.log(`Prompt: ${path.basename(report.promptFile)}`);
1180
1172
  try {
1181
- const fs = require("node:fs");
1182
1173
  const skillDir = path.resolve(cwd, ".agents", "skills");
1183
1174
  const ruleDir = path.resolve(cwd, ".cursor", "rules");
1184
- const skillCount = fs.existsSync(skillDir) ? fs.readdirSync(skillDir, { recursive: true }).filter((f) => String(f).endsWith("SKILL.md")).length : 0;
1185
- const ruleCount = fs.existsSync(ruleDir) ? fs.readdirSync(ruleDir).filter((f) => String(f).endsWith(".mdc")).length : 0;
1186
- const mcpConfig = fs.existsSync(path.resolve(cwd, ".cursor", "mcp.json")) ? "found" : "none";
1175
+ const skillCount = existsSync(skillDir) ? readdirSync(skillDir, { recursive: true }).filter((f) => String(f).endsWith("SKILL.md")).length : 0;
1176
+ const ruleCount = existsSync(ruleDir) ? readdirSync(ruleDir).filter((f) => String(f).endsWith(".mdc")).length : 0;
1177
+ const mcpConfig = existsSync(path.resolve(cwd, ".cursor", "mcp.json")) ? "found" : "none";
1187
1178
  console.log(`Skills: ${skillCount} | Rules: ${ruleCount} | MCP config: ${mcpConfig}`);
1188
1179
  }
1189
1180
  catch { /* skip */ }
@@ -2486,6 +2477,8 @@ function getStringFlag(flags, name) {
2486
2477
  return typeof value === "string" ? value : undefined;
2487
2478
  }
2488
2479
  function formatDuration(ms) {
2480
+ if (!Number.isFinite(ms) || ms < 0)
2481
+ return "unknown";
2489
2482
  if (ms < 1000)
2490
2483
  return ms < 1 ? "<1ms" : `${Math.round(ms)}ms`;
2491
2484
  const totalSeconds = Math.round(ms / 1000);
@@ -2696,16 +2689,15 @@ const PROVIDER_MODELS = Object.freeze({
2696
2689
  { value: "gpt-4.1", label: "gpt-4.1 — legacy", tier: "budget" },
2697
2690
  ],
2698
2691
  claude: [
2699
- { value: "claude-opus-4-7", label: "claude-opus-4-7 — most capable, complex reasoning", tier: "frontier" },
2692
+ { value: "claude-opus-4-7", label: "claude-opus-4-7 — latest, most capable", tier: "frontier" },
2693
+ { value: "claude-opus-4-6", label: "claude-opus-4-6 — previous gen opus", tier: "frontier" },
2700
2694
  { value: "claude-sonnet-4-6", label: "claude-sonnet-4-6 — speed + intelligence", tier: "standard" },
2701
2695
  { value: "claude-haiku-4-5", label: "claude-haiku-4-5 — fastest near-frontier", tier: "fast" },
2702
- { value: "claude-4.6-opus-high", label: "claude-4.6-opus-high — high-thinking opus", tier: "frontier" },
2703
- { value: "claude-4.6-sonnet-high", label: "claude-4.6-sonnet-high — high-thinking sonnet", tier: "standard" },
2704
- { value: "claude-4.5-opus", label: "claude-4.5-opus — previous gen opus", tier: "standard" },
2705
2696
  ],
2706
2697
  cursor: [
2707
2698
  { value: "auto", label: "auto — Cursor auto-selects best", tier: "standard" },
2708
2699
  { value: "claude-4.6-opus-high", label: "claude-4.6-opus-high — frontier reasoning", tier: "frontier" },
2700
+ { value: "claude-4.6-opus-high-thinking", label: "claude-4.6-opus-high-thinking — reasoning + thinking", tier: "frontier" },
2709
2701
  { value: "claude-4.6-sonnet-high", label: "claude-4.6-sonnet-high — fast + smart", tier: "standard" },
2710
2702
  { value: "gpt-5.5-medium", label: "gpt-5.5-medium — GPT frontier", tier: "frontier" },
2711
2703
  { value: "composer-2", label: "composer-2 — balanced multi-file", tier: "standard" },
@@ -2724,7 +2716,7 @@ const PROVIDER_MODELS = Object.freeze({
2724
2716
  ],
2725
2717
  });
2726
2718
  const MODEL_ALIASES = {
2727
- opus: "claude-4.6-opus-high",
2719
+ opus: "claude-opus-4-7",
2728
2720
  sonnet: "claude-sonnet-4-6",
2729
2721
  haiku: "claude-haiku-4-5",
2730
2722
  codex: "gpt-5.3-codex",
@@ -2734,6 +2726,8 @@ const MODEL_ALIASES = {
2734
2726
  composer: "composer-2",
2735
2727
  fast: "composer-2-fast",
2736
2728
  gemini: "gemini-3.1-pro",
2729
+ o3: "o3",
2730
+ pro: "gpt-5.5-pro",
2737
2731
  };
2738
2732
  function resolveModelAlias(model) {
2739
2733
  return MODEL_ALIASES[model.toLowerCase().trim()] ?? model;
@@ -3401,10 +3395,14 @@ function interactiveSelect(prompt, options) {
3401
3395
  const onData = (data) => {
3402
3396
  for (let ci = 0; ci < data.length; ci++) {
3403
3397
  const ch = data[ci];
3404
- if (escBuf.length > 0) {
3398
+ if (escBuf.length > 0 && escBuf[0] === "\x1b") {
3405
3399
  escBuf += ch;
3406
3400
  if (escBuf.length === 2 && ch === "[")
3407
3401
  continue;
3402
+ if (escBuf.length === 2 && ch !== "[") {
3403
+ escBuf = "";
3404
+ continue;
3405
+ }
3408
3406
  if (escBuf.length >= 3) {
3409
3407
  if (escBuf === "\x1b[A" || escBuf === "\x1b[k") {
3410
3408
  cursor = cursor > 0 ? cursor - 1 : options.length - 1;
@@ -3426,6 +3424,8 @@ function interactiveSelect(prompt, options) {
3426
3424
  }
3427
3425
  escBuf = "";
3428
3426
  }
3427
+ if (escBuf.length > 8)
3428
+ escBuf = "";
3429
3429
  continue;
3430
3430
  }
3431
3431
  if (ch === "\x1b") {
@@ -3593,7 +3593,12 @@ main().catch((error) => {
3593
3593
  return;
3594
3594
  }
3595
3595
  if (error instanceof PromptsGptApiError) {
3596
- console.error(formatApiError(error));
3596
+ try {
3597
+ console.error(formatApiError(error));
3598
+ }
3599
+ catch {
3600
+ console.error(`API error: ${error.message} (${error.status})`);
3601
+ }
3597
3602
  process.exitCode = error.status === 401 || error.status === 403
3598
3603
  ? CLI_EXIT_CODES.auth
3599
3604
  : error.status === 429
@@ -3604,10 +3609,13 @@ main().catch((error) => {
3604
3609
  return;
3605
3610
  }
3606
3611
  const msg = error instanceof Error ? error.message : String(error);
3607
- console.error(msg.replace(/pgpt_[a-zA-Z0-9]{4,}/g, "pgpt_***"));
3608
- if (process.env.PROMPTS_GPT_DEBUG === "1" && error instanceof Error && error.stack) {
3609
- console.error(error.stack.replace(/pgpt_[a-zA-Z0-9]{4,}/g, "pgpt_***"));
3612
+ try {
3613
+ console.error(msg.replace(/pgpt_[a-zA-Z0-9]{4,}/g, "pgpt_***"));
3614
+ if (process.env.PROMPTS_GPT_DEBUG === "1" && error instanceof Error && error.stack) {
3615
+ console.error(error.stack.replace(/pgpt_[a-zA-Z0-9]{4,}/g, "pgpt_***"));
3616
+ }
3610
3617
  }
3618
+ catch { /* stderr closed or broken pipe */ }
3611
3619
  process.exitCode = CLI_EXIT_CODES.general;
3612
3620
  });
3613
3621
  async function extractRunDiagnostics(logFile, provider, model) {