prompts-gpt 0.2.10 → 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 +71 -42
- 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 +58 -17
- 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
|
@@ -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) {
|
|
@@ -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) {
|
|
@@ -987,7 +989,7 @@ async function runCommand(command, flags) {
|
|
|
987
989
|
const iterFromFm = await readSweepIterationsFromFrontmatter(path.resolve(cwd, autoFile));
|
|
988
990
|
console.log(`Auto-selected sweep: ${path.basename(autoFile)}${iterFromFm ? ` (${iterFromFm} iterations from frontmatter)` : ""}`);
|
|
989
991
|
flags["prompt-file"] = autoFile;
|
|
990
|
-
if (iterFromFm && !getStringFlag(flags, "iterations")) {
|
|
992
|
+
if (iterFromFm && !getStringFlag(flags, "iterations") && !isTTYInteractive(flags)) {
|
|
991
993
|
flags.iterations = String(iterFromFm);
|
|
992
994
|
}
|
|
993
995
|
}
|
|
@@ -995,16 +997,11 @@ async function runCommand(command, flags) {
|
|
|
995
997
|
if (isTTYInteractive(flags)) {
|
|
996
998
|
const sweepOptions = await Promise.all(assets.sweeps.map(async (s) => {
|
|
997
999
|
const fm = await readSweepFrontmatter(path.resolve(cwd, s.file));
|
|
998
|
-
const iterLabel = fm.iterations ? ` (${fm.iterations} iterations)` : "";
|
|
999
1000
|
const titleLabel = fm.title ? ` — ${fm.title}` : "";
|
|
1000
|
-
return { label: `${path.basename(s.file, ".md")}${titleLabel}
|
|
1001
|
+
return { label: `${path.basename(s.file, ".md")}${titleLabel}`, value: s.file };
|
|
1001
1002
|
}));
|
|
1002
1003
|
const picked = await interactiveSelect("Select a sweep file:", sweepOptions);
|
|
1003
1004
|
flags["prompt-file"] = picked;
|
|
1004
|
-
const iterFromFm = await readSweepIterationsFromFrontmatter(path.resolve(cwd, picked));
|
|
1005
|
-
if (iterFromFm && !getStringFlag(flags, "iterations")) {
|
|
1006
|
-
flags.iterations = String(iterFromFm);
|
|
1007
|
-
}
|
|
1008
1005
|
}
|
|
1009
1006
|
else {
|
|
1010
1007
|
console.log(`${assets.sweeps.length} sweep files found. Pick one with --prompt-file:\n`);
|
|
@@ -1023,14 +1020,12 @@ async function runCommand(command, flags) {
|
|
|
1023
1020
|
return;
|
|
1024
1021
|
}
|
|
1025
1022
|
}
|
|
1026
|
-
if (!getStringFlag(flags, "iterations") && getStringFlag(flags, "prompt-file")) {
|
|
1023
|
+
if (!getStringFlag(flags, "iterations") && getStringFlag(flags, "prompt-file") && !isTTYInteractive(flags)) {
|
|
1027
1024
|
const iterFromFm = await readSweepIterationsFromFrontmatter(path.resolve(cwd, getStringFlag(flags, "prompt-file")));
|
|
1028
1025
|
if (iterFromFm) {
|
|
1029
1026
|
flags.iterations = String(iterFromFm);
|
|
1030
1027
|
}
|
|
1031
1028
|
}
|
|
1032
|
-
const providers = await detectProviders(cwd);
|
|
1033
|
-
const availableProviders = providers.filter((p) => p.available);
|
|
1034
1029
|
if (!getStringFlag(flags, "agent") && isTTYInteractive(flags) && !Boolean(flags.json)) {
|
|
1035
1030
|
if (availableProviders.length === 1) {
|
|
1036
1031
|
const only = availableProviders[0];
|
|
@@ -1058,6 +1053,12 @@ async function runCommand(command, flags) {
|
|
|
1058
1053
|
}
|
|
1059
1054
|
}
|
|
1060
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
|
+
}
|
|
1061
1062
|
if (!getStringFlag(flags, "model") && isTTYInteractive(flags) && !Boolean(flags.json)) {
|
|
1062
1063
|
const currentAgent = resolveRunAgent(flags, config.defaultAgent);
|
|
1063
1064
|
if (currentAgent !== "router") {
|
|
@@ -1088,14 +1089,16 @@ async function runCommand(command, flags) {
|
|
|
1088
1089
|
}
|
|
1089
1090
|
if (!getStringFlag(flags, "iterations") && isTTYInteractive(flags) && !Boolean(flags.json) && getStringFlag(flags, "prompt-file")) {
|
|
1090
1091
|
const fmIter = await readSweepIterationsFromFrontmatter(path.resolve(cwd, getStringFlag(flags, "prompt-file")));
|
|
1091
|
-
const defaultIter =
|
|
1092
|
+
const defaultIter = "1";
|
|
1092
1093
|
const iterOptions = [
|
|
1093
1094
|
{ label: `${defaultIter} (default)`, value: defaultIter },
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
...(defaultIter !== "5" ? [{ label: "5", value: "5" }] : []),
|
|
1095
|
+
{ label: "2", value: "2" },
|
|
1096
|
+
{ label: "3", value: "3" },
|
|
1097
|
+
{ label: "5", value: "5" },
|
|
1098
1098
|
];
|
|
1099
|
+
if (fmIter && !iterOptions.some((option) => option.value === String(fmIter))) {
|
|
1100
|
+
iterOptions.push({ label: String(fmIter), value: String(fmIter) });
|
|
1101
|
+
}
|
|
1099
1102
|
flags.iterations = await interactiveSelect("Select iterations:", iterOptions);
|
|
1100
1103
|
}
|
|
1101
1104
|
const agent = resolveRunAgent(flags, config.defaultAgent);
|
|
@@ -1424,11 +1427,7 @@ async function runCommand(command, flags) {
|
|
|
1424
1427
|
if (!assets.credentialsFound) {
|
|
1425
1428
|
let networkOk = true;
|
|
1426
1429
|
try {
|
|
1427
|
-
|
|
1428
|
-
fetch("https://prompts-gpt.com/api/health", { method: "HEAD" }),
|
|
1429
|
-
new Promise((_, rej) => setTimeout(() => rej(new Error("timeout")), 5000)),
|
|
1430
|
-
]);
|
|
1431
|
-
networkOk = netCheck instanceof Response;
|
|
1430
|
+
networkOk = (await checkPromptsGptSiteReachable(DEFAULT_PROMPTS_GPT_API_URL)).ok;
|
|
1432
1431
|
}
|
|
1433
1432
|
catch {
|
|
1434
1433
|
networkOk = false;
|
|
@@ -2689,9 +2688,8 @@ const PROVIDER_MODELS = Object.freeze({
|
|
|
2689
2688
|
{ value: "gpt-4.1", label: "gpt-4.1 — legacy", tier: "budget" },
|
|
2690
2689
|
],
|
|
2691
2690
|
claude: [
|
|
2692
|
-
{ value: "claude-
|
|
2693
|
-
{ value: "claude-opus-4-
|
|
2694
|
-
{ value: "claude-sonnet-4-6", label: "claude-sonnet-4-6 — speed + intelligence", tier: "standard" },
|
|
2691
|
+
{ value: "claude-sonnet-4-6", label: "claude-sonnet-4-6 — speed + intelligence ★", tier: "standard" },
|
|
2692
|
+
{ value: "claude-opus-4-5", label: "claude-opus-4-5 — previous gen opus", tier: "frontier" },
|
|
2695
2693
|
{ value: "claude-haiku-4-5", label: "claude-haiku-4-5 — fastest near-frontier", tier: "fast" },
|
|
2696
2694
|
],
|
|
2697
2695
|
cursor: [
|
|
@@ -2705,6 +2703,7 @@ const PROVIDER_MODELS = Object.freeze({
|
|
|
2705
2703
|
{ value: "gpt-5.3-codex", label: "gpt-5.3-codex — OpenAI codex", tier: "standard" },
|
|
2706
2704
|
{ value: "gpt-5.4-mini", label: "gpt-5.4-mini — fast & affordable", tier: "fast" },
|
|
2707
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" },
|
|
2708
2707
|
{ value: "claude-4.5-opus", label: "claude-4.5-opus — previous gen opus", tier: "standard" },
|
|
2709
2708
|
],
|
|
2710
2709
|
copilot: [
|
|
@@ -2712,11 +2711,11 @@ const PROVIDER_MODELS = Object.freeze({
|
|
|
2712
2711
|
{ value: "gpt-5.5", label: "gpt-5.5 — frontier", tier: "frontier" },
|
|
2713
2712
|
{ value: "gpt-5.4-mini", label: "gpt-5.4-mini — fast", tier: "fast" },
|
|
2714
2713
|
{ value: "claude-sonnet-4-6", label: "claude-sonnet-4-6 — Anthropic", tier: "standard" },
|
|
2715
|
-
{ value: "claude-opus-4-
|
|
2714
|
+
{ value: "claude-opus-4-5", label: "claude-opus-4-5 — Anthropic frontier", tier: "frontier" },
|
|
2716
2715
|
],
|
|
2717
2716
|
});
|
|
2718
2717
|
const MODEL_ALIASES = {
|
|
2719
|
-
opus: "claude-opus-4-
|
|
2718
|
+
opus: "claude-opus-4-5",
|
|
2720
2719
|
sonnet: "claude-sonnet-4-6",
|
|
2721
2720
|
haiku: "claude-haiku-4-5",
|
|
2722
2721
|
codex: "gpt-5.3-codex",
|
|
@@ -2726,6 +2725,7 @@ const MODEL_ALIASES = {
|
|
|
2726
2725
|
composer: "composer-2",
|
|
2727
2726
|
fast: "composer-2-fast",
|
|
2728
2727
|
gemini: "gemini-3.1-pro",
|
|
2728
|
+
grok: "grok-4.3",
|
|
2729
2729
|
o3: "o3",
|
|
2730
2730
|
pro: "gpt-5.5-pro",
|
|
2731
2731
|
};
|
|
@@ -3056,13 +3056,12 @@ Why use it:
|
|
|
3056
3056
|
Runs the same prompt N times, feeding each iteration's summary into the next.
|
|
3057
3057
|
Includes pre-flight checks, safety guards, SIGTERM handling, and progress monitoring.
|
|
3058
3058
|
|
|
3059
|
-
|
|
3060
|
-
|
|
3061
|
-
in the sweep file's YAML frontmatter (or 1 if not specified).
|
|
3059
|
+
Interactive runs always ask for the iteration count. Non-interactive runs use
|
|
3060
|
+
the \`iterations:\` value in the sweep file's YAML frontmatter when present.
|
|
3062
3061
|
|
|
3063
3062
|
Options:
|
|
3064
3063
|
-f, --prompt-file <path> Prompt file to sweep. Auto-detects local sweeps if omitted.
|
|
3065
|
-
-n, --iterations <n> Number of iterations.
|
|
3064
|
+
-n, --iterations <n> Number of iterations. Interactive default: 1.
|
|
3066
3065
|
--agent <name> Orchestration profile. Default from config or router.
|
|
3067
3066
|
--model <name> Model override for the selected provider.
|
|
3068
3067
|
--iteration-timeout <secs> Timeout per iteration in seconds. Default: 5400 (90 min)
|
|
@@ -3300,6 +3299,9 @@ function interactiveSelect(prompt, options) {
|
|
|
3300
3299
|
if (options.length === 0) {
|
|
3301
3300
|
return Promise.reject(new CliError("No options available for selection.", CLI_EXIT_CODES.usage));
|
|
3302
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
|
+
}
|
|
3303
3305
|
if (options.length === 1) {
|
|
3304
3306
|
return Promise.resolve(options[0].value);
|
|
3305
3307
|
}
|
|
@@ -3313,7 +3315,7 @@ function interactiveSelect(prompt, options) {
|
|
|
3313
3315
|
let cursor = 0;
|
|
3314
3316
|
let escBuf = "";
|
|
3315
3317
|
let filterText = "";
|
|
3316
|
-
const termRows = typeof process.stdout.rows === "number" && process.stdout.rows >
|
|
3318
|
+
const termRows = typeof process.stdout.rows === "number" && process.stdout.rows > 2 ? process.stdout.rows : 24;
|
|
3317
3319
|
const maxVisible = Math.min(options.length, Math.max(3, termRows - 4));
|
|
3318
3320
|
const useUnicode = supportsColor();
|
|
3319
3321
|
const pointer = useUnicode ? "❯" : ">";
|
|
@@ -3460,8 +3462,11 @@ function interactiveSelect(prompt, options) {
|
|
|
3460
3462
|
}
|
|
3461
3463
|
if (ch === "\x03") {
|
|
3462
3464
|
cleanup();
|
|
3463
|
-
|
|
3464
|
-
|
|
3465
|
+
try {
|
|
3466
|
+
stdout.write("\n");
|
|
3467
|
+
}
|
|
3468
|
+
catch { /* stdout may be closed */ }
|
|
3469
|
+
reject(new CliError("Selection cancelled.", CLI_EXIT_CODES.general));
|
|
3465
3470
|
return;
|
|
3466
3471
|
}
|
|
3467
3472
|
if (ch === "\r" || ch === "\n") {
|
|
@@ -3518,16 +3523,37 @@ async function interactiveInput(prompt, defaultValue) {
|
|
|
3518
3523
|
}
|
|
3519
3524
|
const { createInterface } = await import("node:readline");
|
|
3520
3525
|
return new Promise((resolve) => {
|
|
3526
|
+
let resolved = false;
|
|
3521
3527
|
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
3522
3528
|
const suffix = defaultValue ? ` (${defaultValue})` : "";
|
|
3523
3529
|
rl.question(`${prompt}${suffix}: `, (answer) => {
|
|
3530
|
+
if (resolved)
|
|
3531
|
+
return;
|
|
3532
|
+
resolved = true;
|
|
3524
3533
|
rl.close();
|
|
3525
3534
|
rl.removeAllListeners();
|
|
3526
3535
|
resolve((answer.trim() || defaultValue || "").slice(0, 1024));
|
|
3527
3536
|
});
|
|
3528
|
-
rl.on("close", () =>
|
|
3537
|
+
rl.on("close", () => {
|
|
3538
|
+
if (resolved)
|
|
3539
|
+
return;
|
|
3540
|
+
resolved = true;
|
|
3541
|
+
resolve(defaultValue || "");
|
|
3542
|
+
});
|
|
3529
3543
|
});
|
|
3530
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
|
+
}
|
|
3531
3557
|
async function readSweepFrontmatter(filePath) {
|
|
3532
3558
|
try {
|
|
3533
3559
|
const { readFile: fsRead } = await import("node:fs/promises");
|
|
@@ -3585,10 +3611,13 @@ function printDataTransmissionNotice(command, input) {
|
|
|
3585
3611
|
}
|
|
3586
3612
|
main().catch((error) => {
|
|
3587
3613
|
if (error instanceof CliError) {
|
|
3588
|
-
|
|
3589
|
-
|
|
3590
|
-
|
|
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
|
+
}
|
|
3591
3619
|
}
|
|
3620
|
+
catch { /* stderr closed or broken pipe */ }
|
|
3592
3621
|
process.exitCode = error.exitCode;
|
|
3593
3622
|
return;
|
|
3594
3623
|
}
|