@prompts-gpt/client 0.2.3 → 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/README.md +49 -17
- package/dist/cli.js +599 -119
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -21
- package/dist/index.js.map +1 -1
- package/dist/runtime.d.ts +18 -0
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +277 -6
- package/dist/runtime.js.map +1 -1
- package/dist/sweep.d.ts +7 -1
- package/dist/sweep.d.ts.map +1 -1
- package/dist/sweep.js +16 -4
- package/dist/sweep.js.map +1 -1
- package/package.json +3 -4
- package/CHANGELOG.md +0 -110
package/dist/cli.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { existsSync } from "node:fs";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { parseArgs } from "node:util";
|
|
5
|
-
import { 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, sweepPrompt, validateRunConfig, discoverWorkspaceAssets, SUPPORTED_AGENT_TARGETS, detectProviders, loadLocalCredentials, saveLocalCredentials, syncPrompts, writeAgentFiles, writePromptManifest, writePromptMarkdownFiles, } from "./index.js";
|
|
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, } from "./index.js";
|
|
6
6
|
const CLI_EXIT_CODES = {
|
|
7
7
|
success: 0,
|
|
8
8
|
general: 1,
|
|
@@ -12,7 +12,7 @@ const CLI_EXIT_CODES = {
|
|
|
12
12
|
usage: 64,
|
|
13
13
|
};
|
|
14
14
|
const VALID_TOOLS = ["Codex", "Claude Code", "Cursor", "GitHub Copilot", "ChatGPT", "Gemini", "Perplexity", "Grok", "DeepSeek", "Claude"];
|
|
15
|
-
const COMMANDS = ["setup", "init", "project", "pull", "generate", "sync", "run", "run-batch", "sweep", "list", "status", "validate", "providers", "doctor", "load-config", "version", "help"];
|
|
15
|
+
const COMMANDS = ["setup", "init", "project", "pull", "generate", "sync", "run", "run-batch", "sweep", "list", "status", "validate", "providers", "doctor", "load-config", "quickstart", "version", "help"];
|
|
16
16
|
const MAX_STDIN_TOKEN_LENGTH = 4_096;
|
|
17
17
|
class CliError extends Error {
|
|
18
18
|
exitCode;
|
|
@@ -27,12 +27,15 @@ class CliError extends Error {
|
|
|
27
27
|
async function main() {
|
|
28
28
|
const argv = process.argv.slice(2);
|
|
29
29
|
if (argv.length === 0) {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
30
|
+
console.log(`Prompts-GPT CLI — sync and run AI prompt packs locally
|
|
31
|
+
|
|
32
|
+
Get started:
|
|
33
|
+
prompts-gpt quickstart — setup credentials, config, and first run
|
|
34
|
+
prompts-gpt list — see available prompts and sweeps
|
|
35
|
+
prompts-gpt sweep — run a multi-iteration sweep (auto-detects local sweeps)
|
|
36
|
+
|
|
37
|
+
Run \`prompts-gpt help\` for the full command list.
|
|
38
|
+
`);
|
|
36
39
|
return;
|
|
37
40
|
}
|
|
38
41
|
const first = argv[0];
|
|
@@ -83,7 +86,11 @@ async function runCommand(command, flags) {
|
|
|
83
86
|
}
|
|
84
87
|
console.log(`Workspace: ${cwd}`);
|
|
85
88
|
for (const provider of providers) {
|
|
86
|
-
|
|
89
|
+
const status = provider.available ? "✓ available" : "✗ missing";
|
|
90
|
+
console.log(`${provider.provider}: ${status} | bin=${provider.bin} | model=${provider.modelDefault}${provider.version ? ` | version=${provider.version}` : ""}`);
|
|
91
|
+
if (!provider.available) {
|
|
92
|
+
console.log(` install: ${provider.installHint}`);
|
|
93
|
+
}
|
|
87
94
|
}
|
|
88
95
|
return;
|
|
89
96
|
}
|
|
@@ -124,27 +131,23 @@ async function runCommand(command, flags) {
|
|
|
124
131
|
return;
|
|
125
132
|
}
|
|
126
133
|
console.log(`Created run config: ${result.configPath}`);
|
|
127
|
-
console.log(`
|
|
128
|
-
console.log(`
|
|
134
|
+
console.log(`Config: ${result.configPath}`);
|
|
135
|
+
console.log(`Agent: ${result.config.defaultAgent ?? "router"} | Providers: ${(result.config.providerOrder ?? []).join(", ")}`);
|
|
129
136
|
if (result.sourceSummary.defaultPromptFile) {
|
|
130
137
|
console.log(`Default prompt file: ${result.sourceSummary.defaultPromptFile}`);
|
|
138
|
+
console.log(`Default prompt: ${result.sourceSummary.defaultPromptFile}`);
|
|
131
139
|
}
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
console.log(`Batch default prompt files: ${result.sourceSummary.promptFiles.length}`);
|
|
137
|
-
}
|
|
138
|
-
else {
|
|
139
|
-
console.log("Batch default prompt sources: none detected");
|
|
140
|
-
}
|
|
141
|
-
console.log("Detected providers:");
|
|
142
|
-
for (const provider of result.providerSummary) {
|
|
143
|
-
console.log(`- ${provider.provider}: ${provider.available ? "available" : "missing"} | bin=${provider.bin}`);
|
|
140
|
+
const availableCount = result.providerSummary.filter((p) => p.available).length;
|
|
141
|
+
console.log(`Providers: ${availableCount}/${result.providerSummary.length} available`);
|
|
142
|
+
if (availableCount === 0) {
|
|
143
|
+
console.log("⚠ No provider CLIs detected. Install codex, cursor agent, claude, or copilot.");
|
|
144
144
|
}
|
|
145
|
+
const setupAssets = await discoverWorkspaceAssets(cwd);
|
|
145
146
|
console.log("Next steps:");
|
|
146
147
|
console.log(` prompts-gpt run${result.sourceSummary.defaultPromptFile ? "" : " --prompt-file <path>"}`);
|
|
147
|
-
|
|
148
|
+
if (setupAssets.sweeps.length > 0) {
|
|
149
|
+
console.log(` prompts-gpt sweep — run a multi-iteration sweep (${setupAssets.sweeps.length} found)`);
|
|
150
|
+
}
|
|
148
151
|
console.log(" prompts-gpt list — see all runnable assets");
|
|
149
152
|
console.log(" prompts-gpt status — check workspace readiness");
|
|
150
153
|
console.log(" prompts-gpt validate — validate your config");
|
|
@@ -180,10 +183,15 @@ async function runCommand(command, flags) {
|
|
|
180
183
|
}
|
|
181
184
|
console.log(`Workspace: ${cwd}`);
|
|
182
185
|
console.log("");
|
|
186
|
+
const providers = await detectProviders(cwd);
|
|
187
|
+
const availableProviderNames = providers.filter((p) => p.available).map((p) => p.provider);
|
|
183
188
|
if (assets.prompts.length > 0) {
|
|
184
189
|
console.log(`Prompt packs (${assets.prompts.length}):`);
|
|
185
190
|
for (const p of assets.prompts) {
|
|
186
|
-
|
|
191
|
+
const providerHint = availableProviderNames.length > 0
|
|
192
|
+
? ` (run with: ${availableProviderNames[0]})`
|
|
193
|
+
: "";
|
|
194
|
+
console.log(` ${p.slug} — ${p.title} [${p.source}]${providerHint}`);
|
|
187
195
|
console.log(` file: .prompts-gpt/${p.file}`);
|
|
188
196
|
console.log(` run: prompts-gpt run --prompt-file .prompts-gpt/${p.file}`);
|
|
189
197
|
}
|
|
@@ -197,9 +205,12 @@ async function runCommand(command, flags) {
|
|
|
197
205
|
if (assets.sweeps.length > 0) {
|
|
198
206
|
console.log(`Sweep prompts (${assets.sweeps.length}):`);
|
|
199
207
|
for (const s of assets.sweeps) {
|
|
200
|
-
|
|
208
|
+
const iterCount = await readSweepIterationsFromFrontmatter(path.resolve(cwd, s.file));
|
|
209
|
+
const iterHint = iterCount ? ` (${iterCount} iterations)` : "";
|
|
210
|
+
const iterFlag = iterCount ? ` --iterations ${iterCount}` : "";
|
|
211
|
+
console.log(` ${s.name}${iterHint}`);
|
|
201
212
|
console.log(` file: ${s.file}`);
|
|
202
|
-
console.log(` sweep: prompts-gpt sweep --prompt-file ${s.file}`);
|
|
213
|
+
console.log(` sweep: prompts-gpt sweep --prompt-file ${s.file}${iterFlag}`);
|
|
203
214
|
}
|
|
204
215
|
console.log("");
|
|
205
216
|
}
|
|
@@ -240,20 +251,38 @@ async function runCommand(command, flags) {
|
|
|
240
251
|
console.log(` Credentials: ${assets.credentialsFound ? "✓" : "✗ — run \`prompts-gpt init --token <token>\`"}`);
|
|
241
252
|
console.log(` Config: ${assets.configFound ? "✓" : "✗ — run \`prompts-gpt setup\`"}`);
|
|
242
253
|
console.log(` Manifest: ${assets.manifestFound ? "✓" : "✗ — run \`prompts-gpt sync\`"}`);
|
|
243
|
-
|
|
254
|
+
const cloudCount = assets.prompts.filter((p) => p.source === "library" || p.source === "generated").length;
|
|
255
|
+
const localCount = assets.prompts.filter((p) => p.source === "local").length;
|
|
256
|
+
const promptSummary = assets.prompts.length > 0
|
|
257
|
+
? `✓ (${assets.prompts.length}${cloudCount > 0 ? `, ${cloudCount} synced` : ""}${localCount > 0 ? `, ${localCount} local-only` : ""})`
|
|
258
|
+
: "✗ — none found";
|
|
259
|
+
console.log(` Prompts: ${promptSummary}`);
|
|
244
260
|
console.log(` Sweeps: ${assets.sweeps.length > 0 ? `✓ (${assets.sweeps.length})` : "— none found"}`);
|
|
245
261
|
console.log(` Agents: ${assets.agents.length > 0 ? `✓ (${assets.agents.length} targets)` : "✗ — run \`prompts-gpt sync\`"}`);
|
|
246
|
-
|
|
262
|
+
if (availableProviders.length > 0) {
|
|
263
|
+
console.log(` Providers: ✓`);
|
|
264
|
+
for (const p of availableProviders) {
|
|
265
|
+
console.log(` ${p.provider}: ${p.bin} | model: ${p.modelDefault}${p.version ? ` | ${p.version}` : ""}`);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
else {
|
|
269
|
+
console.log(" Providers: ✗ — no CLI found");
|
|
270
|
+
}
|
|
247
271
|
console.log("");
|
|
248
272
|
if (assets.prompts.length > 0 && availableProviders.length > 0) {
|
|
249
273
|
console.log("Ready to run:");
|
|
250
274
|
console.log(` prompts-gpt run --prompt-file .prompts-gpt/${assets.prompts[0].file}`);
|
|
251
275
|
if (assets.sweeps.length > 0) {
|
|
252
|
-
|
|
276
|
+
for (const s of assets.sweeps) {
|
|
277
|
+
console.log(` prompts-gpt sweep --prompt-file ${s.file}`);
|
|
278
|
+
}
|
|
253
279
|
}
|
|
254
280
|
}
|
|
255
281
|
else {
|
|
256
|
-
console.log("
|
|
282
|
+
console.log("Not ready yet. Quick fix:");
|
|
283
|
+
console.log(" prompts-gpt quickstart");
|
|
284
|
+
console.log("");
|
|
285
|
+
console.log("Or step by step:");
|
|
257
286
|
let step = 1;
|
|
258
287
|
if (!assets.credentialsFound)
|
|
259
288
|
console.log(` ${step++}. prompts-gpt init --token <project-token>`);
|
|
@@ -295,7 +324,7 @@ async function runCommand(command, flags) {
|
|
|
295
324
|
if (!config.defaultPromptFile && config.batchDefaults.promptFiles.length === 0 && !config.batchDefaults.manifestPath) {
|
|
296
325
|
const assets = await discoverWorkspaceAssets(cwd);
|
|
297
326
|
if (assets.prompts.length > 0 || assets.sweeps.length > 0) {
|
|
298
|
-
console.log("No default prompt file configured. Available options:\n");
|
|
327
|
+
console.log("No default prompt configured. No default prompt file configured. Available options:\n");
|
|
299
328
|
if (assets.prompts.length > 0) {
|
|
300
329
|
console.log("Prompt packs:");
|
|
301
330
|
for (const p of assets.prompts) {
|
|
@@ -303,7 +332,7 @@ async function runCommand(command, flags) {
|
|
|
303
332
|
}
|
|
304
333
|
}
|
|
305
334
|
if (assets.sweeps.length > 0) {
|
|
306
|
-
console.log("\nSweep prompts:");
|
|
335
|
+
console.log("\nSweep prompts (use `sweep` command):");
|
|
307
336
|
for (const s of assets.sweeps) {
|
|
308
337
|
console.log(` prompts-gpt sweep --prompt-file ${s.file}`);
|
|
309
338
|
}
|
|
@@ -314,11 +343,43 @@ async function runCommand(command, flags) {
|
|
|
314
343
|
}
|
|
315
344
|
}
|
|
316
345
|
const agent = resolveRunAgent(flags, config.defaultAgent);
|
|
346
|
+
if (Boolean(flags["dry-run"])) {
|
|
347
|
+
const providers = await detectProviders(cwd);
|
|
348
|
+
const resolvedProvider = resolveRunProvider(agent, providers, config.providerOrder);
|
|
349
|
+
const resolvedModel = getStringFlag(flags, "model")?.trim() || config.modelOverrides[resolvedProvider]?.trim() || "";
|
|
350
|
+
let resolvedPrompt = promptFile || getStringFlag(flags, "prompt-file") || config.defaultPromptFile || null;
|
|
351
|
+
if (!resolvedPrompt) {
|
|
352
|
+
try {
|
|
353
|
+
const { resolveDefaultPromptFile: resolvePf } = await import("./index.js");
|
|
354
|
+
resolvedPrompt = await resolvePf(cwd, config);
|
|
355
|
+
}
|
|
356
|
+
catch {
|
|
357
|
+
resolvedPrompt = null;
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
const agentStr = getStringFlag(flags, "agent") ? agent : `${agent} (auto-selected)`;
|
|
361
|
+
console.log("[dry-run] Would execute:");
|
|
362
|
+
console.log(` Agent: ${agentStr}`);
|
|
363
|
+
console.log(` Provider: ${resolvedProvider}`);
|
|
364
|
+
console.log(` Model: ${resolvedModel || "(default)"}`);
|
|
365
|
+
console.log(` Prompt: ${resolvedPrompt || "(none found — pass --prompt-file)"}`);
|
|
366
|
+
console.log(` Timeout: ${getStringFlag(flags, "timeout") || config.timeoutSeconds}s`);
|
|
367
|
+
return;
|
|
368
|
+
}
|
|
369
|
+
const modelFlag = getStringFlag(flags, "model");
|
|
370
|
+
if (modelFlag && !Boolean(flags.json) && agent !== "router") {
|
|
371
|
+
const providers = await detectProviders(cwd);
|
|
372
|
+
const resolvedProvider = resolveRunProvider(agent, providers, config.providerOrder);
|
|
373
|
+
const mismatchWarning = warnModelProviderMismatch(resolvedProvider, modelFlag);
|
|
374
|
+
if (mismatchWarning) {
|
|
375
|
+
console.error(`[warning] ${mismatchWarning}`);
|
|
376
|
+
}
|
|
377
|
+
}
|
|
317
378
|
const result = await runPrompt({
|
|
318
379
|
cwd,
|
|
319
380
|
promptFile,
|
|
320
381
|
agent,
|
|
321
|
-
model:
|
|
382
|
+
model: modelFlag,
|
|
322
383
|
timeoutSeconds: parsePositiveIntFlag(getStringFlag(flags, "timeout"), "timeout"),
|
|
323
384
|
artifactsDir: getStringFlag(flags, "artifacts-dir"),
|
|
324
385
|
runId: getStringFlag(flags, "run-id"),
|
|
@@ -331,14 +392,31 @@ async function runCommand(command, flags) {
|
|
|
331
392
|
console.log(JSON.stringify(result, null, 2));
|
|
332
393
|
return;
|
|
333
394
|
}
|
|
334
|
-
const agentLabel = getStringFlag(flags, "agent") ? result.provider : `${result.provider} (auto
|
|
395
|
+
const agentLabel = getStringFlag(flags, "agent") ? result.provider : `${result.provider} (auto — first available from provider order)`;
|
|
335
396
|
console.log(`Run ID: ${result.runId}`);
|
|
336
397
|
console.log(`Provider: ${agentLabel} | Model: ${result.model}`);
|
|
337
398
|
console.log(`Exit code: ${result.exitCode}`);
|
|
338
399
|
console.log(`Duration: ${formatDuration(result.durationMs)}`);
|
|
400
|
+
if (hasTokenUsage(result.tokenUsage)) {
|
|
401
|
+
console.log(`Tokens: ${formatTokenUsage(result.tokenUsage)}`);
|
|
402
|
+
}
|
|
339
403
|
console.log(`Run dir: ${result.runDir}`);
|
|
340
404
|
console.log(`Summary: ${result.summaryFile}`);
|
|
341
405
|
console.log(`Log: ${result.logFile}`);
|
|
406
|
+
if (result.exitCode === 0) {
|
|
407
|
+
console.log("");
|
|
408
|
+
console.log(`View results: cat ${result.summaryFile}`);
|
|
409
|
+
}
|
|
410
|
+
if (result.exitCode !== 0) {
|
|
411
|
+
const diagnostics = await extractRunDiagnostics(result.logFile, result.provider, result.model);
|
|
412
|
+
if (diagnostics.length > 0) {
|
|
413
|
+
console.log("");
|
|
414
|
+
console.log("Diagnostics:");
|
|
415
|
+
for (const d of diagnostics) {
|
|
416
|
+
console.log(` ${d}`);
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
}
|
|
342
420
|
return;
|
|
343
421
|
}
|
|
344
422
|
if (command === "run-batch") {
|
|
@@ -379,9 +457,13 @@ async function runCommand(command, flags) {
|
|
|
379
457
|
return;
|
|
380
458
|
}
|
|
381
459
|
console.log(`Batch complete: total=${result.total} success=${result.success} failed=${result.failed}`);
|
|
460
|
+
if (hasTokenUsage(result.tokenUsage)) {
|
|
461
|
+
console.log(`Batch tokens: ${formatTokenUsage(result.tokenUsage)}`);
|
|
462
|
+
}
|
|
382
463
|
for (const [idx, run] of result.results.entries()) {
|
|
383
464
|
const status = run.exitCode === 0 ? "ok" : "FAIL";
|
|
384
|
-
|
|
465
|
+
const usageStr = hasTokenUsage(run.tokenUsage) ? `, tokens=${run.tokenUsage.totalTokens.toLocaleString()}` : "";
|
|
466
|
+
console.log(` [${idx + 1}/${result.total}] ${status} ${path.basename(run.promptFile)} -> ${run.provider} (exit=${run.exitCode}, ${formatDuration(run.durationMs)}${usageStr})`);
|
|
385
467
|
}
|
|
386
468
|
return;
|
|
387
469
|
}
|
|
@@ -391,22 +473,43 @@ async function runCommand(command, flags) {
|
|
|
391
473
|
const config = await loadRunConfig(cwd);
|
|
392
474
|
warnOnConfigIssues(config);
|
|
393
475
|
if (!sweepPromptFile && !Boolean(flags.json)) {
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
476
|
+
const assets = await discoverWorkspaceAssets(cwd);
|
|
477
|
+
if (assets.sweeps.length === 1) {
|
|
478
|
+
const autoFile = assets.sweeps[0].file;
|
|
479
|
+
const iterFromFm = await readSweepIterationsFromFrontmatter(path.resolve(cwd, autoFile));
|
|
480
|
+
console.log(`Auto-selected sweep: ${autoFile}${iterFromFm ? ` (${iterFromFm} iterations from frontmatter)` : ""}`);
|
|
481
|
+
flags["prompt-file"] = autoFile;
|
|
482
|
+
if (iterFromFm && !getStringFlag(flags, "iterations")) {
|
|
483
|
+
flags.iterations = String(iterFromFm);
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
else if (assets.sweeps.length > 1) {
|
|
487
|
+
console.log(`${assets.sweeps.length} sweep files found. Pick one with --prompt-file:\n`);
|
|
488
|
+
for (const s of assets.sweeps) {
|
|
489
|
+
const iterCount = await readSweepIterationsFromFrontmatter(path.resolve(cwd, s.file));
|
|
490
|
+
const iterFlag = iterCount ? ` --iterations ${iterCount}` : "";
|
|
491
|
+
console.log(` prompts-gpt sweep --prompt-file ${s.file}${iterFlag}`);
|
|
492
|
+
}
|
|
493
|
+
if (assets.prompts.length > 0) {
|
|
494
|
+
console.log("\nOr run a single prompt:");
|
|
495
|
+
for (const p of assets.prompts.slice(0, 3)) {
|
|
496
|
+
console.log(` prompts-gpt run --prompt-file .prompts-gpt/${p.file}`);
|
|
406
497
|
}
|
|
407
|
-
console.log("\nOr set a default: prompts-gpt setup --prompt-file <path>");
|
|
408
|
-
return;
|
|
409
498
|
}
|
|
499
|
+
return;
|
|
500
|
+
}
|
|
501
|
+
else {
|
|
502
|
+
console.log("No sweep files found.");
|
|
503
|
+
console.log(" Create .prompts-gpt/sweeps/<name>.md to add sweep prompts.");
|
|
504
|
+
console.log(" Or set a default: prompts-gpt setup --prompt-file <path>");
|
|
505
|
+
console.log(" Run `prompts-gpt list` to see what's available.");
|
|
506
|
+
return;
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
if (!getStringFlag(flags, "iterations") && getStringFlag(flags, "prompt-file")) {
|
|
510
|
+
const iterFromFm = await readSweepIterationsFromFrontmatter(path.resolve(cwd, getStringFlag(flags, "prompt-file")));
|
|
511
|
+
if (iterFromFm) {
|
|
512
|
+
flags.iterations = String(iterFromFm);
|
|
410
513
|
}
|
|
411
514
|
}
|
|
412
515
|
const agent = resolveRunAgent(flags, config.defaultAgent);
|
|
@@ -454,6 +557,8 @@ async function runCommand(command, flags) {
|
|
|
454
557
|
dryRun: Boolean(flags["dry-run"]),
|
|
455
558
|
maxRunDirs: parsePositiveIntFlag(getStringFlag(flags, "max-run-dirs"), "max-run-dirs"),
|
|
456
559
|
summaryLines: parsePositiveIntFlag(getStringFlag(flags, "summary-lines"), "summary-lines"),
|
|
560
|
+
background: Boolean(flags.background),
|
|
561
|
+
permissionMode: getStringFlag(flags, "permission-mode"),
|
|
457
562
|
onProgress,
|
|
458
563
|
});
|
|
459
564
|
if (Boolean(flags.json)) {
|
|
@@ -461,11 +566,25 @@ async function runCommand(command, flags) {
|
|
|
461
566
|
return;
|
|
462
567
|
}
|
|
463
568
|
if (result.dryRun) {
|
|
569
|
+
const iterTimeout = parsePositiveIntFlag(getStringFlag(flags, "iteration-timeout"), "iteration-timeout") ?? 5400;
|
|
570
|
+
const estMaxDuration = result.totalIterations * iterTimeout;
|
|
464
571
|
console.log("[dry-run] Would execute sweep with:");
|
|
465
572
|
console.log(` Provider: ${result.provider}`);
|
|
466
573
|
console.log(` Model: ${result.model}`);
|
|
467
574
|
console.log(` Iterations: ${result.totalIterations}`);
|
|
468
575
|
console.log(` Prompt: ${result.promptFile}`);
|
|
576
|
+
console.log(` Max duration: ~${formatDuration(estMaxDuration * 1000)} (${result.totalIterations} x ${formatDuration(iterTimeout * 1000)})`);
|
|
577
|
+
try {
|
|
578
|
+
const { readFile: fsRead } = await import("node:fs/promises");
|
|
579
|
+
const previewText = await fsRead(result.promptFile, "utf8");
|
|
580
|
+
const previewLines = previewText.split("\n").slice(0, 5);
|
|
581
|
+
console.log(` Prompt preview:`);
|
|
582
|
+
for (const line of previewLines)
|
|
583
|
+
console.log(` ${line}`);
|
|
584
|
+
if (previewText.split("\n").length > 5)
|
|
585
|
+
console.log(` ... (${previewText.split("\n").length - 5} more lines)`);
|
|
586
|
+
}
|
|
587
|
+
catch { /* skip preview */ }
|
|
469
588
|
return;
|
|
470
589
|
}
|
|
471
590
|
console.log(`Run ID: ${result.runId}`);
|
|
@@ -473,13 +592,131 @@ async function runCommand(command, flags) {
|
|
|
473
592
|
console.log(`Prompt: ${result.promptFile}`);
|
|
474
593
|
console.log(`Iterations: ${result.succeeded}/${result.totalIterations} succeeded`);
|
|
475
594
|
console.log(`Duration: ${formatDuration(result.totalDurationMs)}`);
|
|
595
|
+
if (hasTokenUsage(result.tokenUsage)) {
|
|
596
|
+
console.log(`Tokens: ${formatTokenUsage(result.tokenUsage)}`);
|
|
597
|
+
}
|
|
476
598
|
console.log(`Run dir: ${result.runDir}`);
|
|
477
599
|
console.log(`Manifest: ${result.manifestFile}`);
|
|
600
|
+
if (result.iterations.length > 1) {
|
|
601
|
+
console.log("");
|
|
602
|
+
console.log("Per-iteration results:");
|
|
603
|
+
for (const iter of result.iterations) {
|
|
604
|
+
const tools = iter.toolCounts;
|
|
605
|
+
const toolStr = tools.total > 0 ? ` | tools: ${tools.total} (R:${tools.reads} W:${tools.writes} S:${tools.shells})` : "";
|
|
606
|
+
const usageStr = hasTokenUsage(iter.tokenUsage) ? ` | tokens: ${iter.tokenUsage.totalTokens.toLocaleString()}` : "";
|
|
607
|
+
console.log(` [${iter.iteration}/${result.totalIterations}] ${iter.status} (${formatDuration(iter.durationMs)})${toolStr}${usageStr}`);
|
|
608
|
+
}
|
|
609
|
+
const totalTools = result.iterations.reduce((acc, i) => ({
|
|
610
|
+
reads: acc.reads + i.toolCounts.reads, writes: acc.writes + i.toolCounts.writes,
|
|
611
|
+
shells: acc.shells + i.toolCounts.shells, searches: acc.searches + i.toolCounts.searches,
|
|
612
|
+
webSearches: acc.webSearches + i.toolCounts.webSearches, total: acc.total + i.toolCounts.total,
|
|
613
|
+
}), { reads: 0, writes: 0, shells: 0, searches: 0, webSearches: 0, total: 0 });
|
|
614
|
+
if (totalTools.total > 0) {
|
|
615
|
+
console.log(` Total tools: ${totalTools.total} (reads: ${totalTools.reads}, writes: ${totalTools.writes}, shells: ${totalTools.shells}, searches: ${totalTools.searches})`);
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
console.log("");
|
|
619
|
+
console.log("Inspect results:");
|
|
620
|
+
console.log(` cat ${result.manifestFile}`);
|
|
621
|
+
console.log(` ls ${result.runDir}`);
|
|
478
622
|
if (result.failed > 0) {
|
|
479
623
|
process.exitCode = 1;
|
|
480
624
|
}
|
|
481
625
|
return;
|
|
482
626
|
}
|
|
627
|
+
if (command === "quickstart") {
|
|
628
|
+
const cwd = getResolvedCwd(flags);
|
|
629
|
+
const assets = await discoverWorkspaceAssets(cwd);
|
|
630
|
+
const providers = await detectProviders(cwd);
|
|
631
|
+
const availableProviders = providers.filter((p) => p.available);
|
|
632
|
+
console.log("Prompts-GPT Quickstart");
|
|
633
|
+
console.log("======================");
|
|
634
|
+
console.log("");
|
|
635
|
+
if (!assets.credentialsFound) {
|
|
636
|
+
console.log("Step 1: Save your project token");
|
|
637
|
+
console.log(" prompts-gpt init --token-prompt");
|
|
638
|
+
console.log("");
|
|
639
|
+
console.log(" Get your token from: https://prompts-gpt.com/studio/projects");
|
|
640
|
+
console.log("");
|
|
641
|
+
console.log("Run `prompts-gpt quickstart` again after saving your token.");
|
|
642
|
+
return;
|
|
643
|
+
}
|
|
644
|
+
console.log("✓ Credentials found");
|
|
645
|
+
if (!assets.configFound) {
|
|
646
|
+
console.log("→ Setting up config...");
|
|
647
|
+
try {
|
|
648
|
+
await initRunConfig({ cwd, overwrite: false });
|
|
649
|
+
console.log("✓ Config created");
|
|
650
|
+
}
|
|
651
|
+
catch {
|
|
652
|
+
console.log("✓ Config already exists");
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
else {
|
|
656
|
+
console.log("✓ Config found");
|
|
657
|
+
}
|
|
658
|
+
if (availableProviders.length === 0) {
|
|
659
|
+
console.log("");
|
|
660
|
+
console.log("✗ No provider CLIs found. Install at least one:");
|
|
661
|
+
console.log(" - codex: npm install -g @openai/codex");
|
|
662
|
+
console.log(" - claude: npm install -g @anthropic-ai/claude-code");
|
|
663
|
+
console.log(" - cursor: Install Cursor IDE (includes `agent` CLI)");
|
|
664
|
+
return;
|
|
665
|
+
}
|
|
666
|
+
console.log(`✓ Providers: ${availableProviders.map((p) => p.provider).join(", ")}`);
|
|
667
|
+
if (assets.prompts.length === 0 && assets.sweeps.length === 0) {
|
|
668
|
+
console.log("");
|
|
669
|
+
console.log("→ No prompts found. Syncing from Prompts Studio...");
|
|
670
|
+
try {
|
|
671
|
+
const clientOpts = await resolveClientOptions("quickstart", flags).catch(() => null);
|
|
672
|
+
if (clientOpts) {
|
|
673
|
+
const qsClient = new PromptsGptClient(clientOpts);
|
|
674
|
+
const pulledPrompts = await qsClient.pullPrompts();
|
|
675
|
+
if (pulledPrompts.length > 0) {
|
|
676
|
+
const syncResult = await syncPrompts(pulledPrompts, { cwd, agent: "all" });
|
|
677
|
+
console.log(`✓ Synced ${syncResult.markdown.written.length} prompt(s) and ${syncResult.agents.written.length} agent file(s)`);
|
|
678
|
+
const refreshed = await discoverWorkspaceAssets(cwd);
|
|
679
|
+
if (refreshed.prompts.length > 0 || refreshed.sweeps.length > 0) {
|
|
680
|
+
console.log(`✓ Prompts: ${refreshed.prompts.length} prompt packs, ${refreshed.sweeps.length} sweeps`);
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
else {
|
|
684
|
+
console.log("No prompts found in your Prompts Studio library.");
|
|
685
|
+
console.log(" Configure prompts at: https://prompts-gpt.com/studio/projects");
|
|
686
|
+
console.log(" Or run: prompts-gpt generate --goal \"Your task\"");
|
|
687
|
+
return;
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
else {
|
|
691
|
+
console.log("✗ Could not sync (credentials issue). Run manually:");
|
|
692
|
+
console.log(" prompts-gpt sync");
|
|
693
|
+
return;
|
|
694
|
+
}
|
|
695
|
+
}
|
|
696
|
+
catch (syncErr) {
|
|
697
|
+
console.log(`✗ Sync failed: ${syncErr instanceof Error ? syncErr.message : String(syncErr)}`);
|
|
698
|
+
console.log(" Run manually: prompts-gpt sync");
|
|
699
|
+
return;
|
|
700
|
+
}
|
|
701
|
+
const refreshedAssets = await discoverWorkspaceAssets(cwd);
|
|
702
|
+
if (refreshedAssets.prompts.length === 0 && refreshedAssets.sweeps.length === 0) {
|
|
703
|
+
return;
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
console.log(`✓ Prompts: ${assets.prompts.length} prompt packs, ${assets.sweeps.length} sweeps`);
|
|
707
|
+
console.log("");
|
|
708
|
+
console.log("You're ready! Try these commands:");
|
|
709
|
+
console.log("");
|
|
710
|
+
if (assets.prompts.length > 0) {
|
|
711
|
+
console.log(` prompts-gpt run --prompt-file .prompts-gpt/${assets.prompts[0].file}`);
|
|
712
|
+
}
|
|
713
|
+
if (assets.sweeps.length > 0) {
|
|
714
|
+
console.log(` prompts-gpt sweep --prompt-file ${assets.sweeps[0].file}`);
|
|
715
|
+
}
|
|
716
|
+
console.log(" prompts-gpt list — see all available prompts and sweeps");
|
|
717
|
+
console.log(" prompts-gpt status — check workspace readiness");
|
|
718
|
+
return;
|
|
719
|
+
}
|
|
483
720
|
if (command === "load-config") {
|
|
484
721
|
const cwd = getResolvedCwd(flags);
|
|
485
722
|
const client = await createClientForCommand(command, flags);
|
|
@@ -532,10 +769,22 @@ async function runCommand(command, flags) {
|
|
|
532
769
|
console.log(` prompts-gpt run --prompt-file .prompts-gpt/${firstFile}`);
|
|
533
770
|
}
|
|
534
771
|
}
|
|
772
|
+
const lcAssets = await discoverWorkspaceAssets(cwd);
|
|
773
|
+
if (lcAssets.sweeps.length > 0) {
|
|
774
|
+
console.log(`\nSweep files available (${lcAssets.sweeps.length}):`);
|
|
775
|
+
for (const s of lcAssets.sweeps) {
|
|
776
|
+
console.log(` prompts-gpt sweep --prompt-file ${s.file}`);
|
|
777
|
+
}
|
|
778
|
+
}
|
|
535
779
|
return;
|
|
536
780
|
}
|
|
537
781
|
if (command === "init") {
|
|
538
|
-
|
|
782
|
+
let token = await resolveTokenInput(flags, { command });
|
|
783
|
+
if (!token && process.stdin.isTTY && process.stdout.isTTY) {
|
|
784
|
+
console.log("No token flag provided — prompting interactively.");
|
|
785
|
+
console.log("Get your token from: https://prompts-gpt.com/studio/projects\n");
|
|
786
|
+
token = await readTokenFromPrompt(command);
|
|
787
|
+
}
|
|
539
788
|
if (!token) {
|
|
540
789
|
throw new CliError("Run `prompts-gpt init --token <project-token>`, `--token-stdin`, or `--token-prompt`.", CLI_EXIT_CODES.validation, {
|
|
541
790
|
helpCommand: "init",
|
|
@@ -573,7 +822,10 @@ async function runCommand(command, flags) {
|
|
|
573
822
|
});
|
|
574
823
|
console.log(`Saved Prompts-GPT credentials to ${result.credentialsPath}`);
|
|
575
824
|
console.log("The credentials file is added to .gitignore.");
|
|
576
|
-
console.log("
|
|
825
|
+
console.log("");
|
|
826
|
+
console.log("Next steps:");
|
|
827
|
+
console.log(" prompts-gpt quickstart — interactive setup (recommended)");
|
|
828
|
+
console.log(" prompts-gpt sync — pull prompts and sync agent files");
|
|
577
829
|
return;
|
|
578
830
|
}
|
|
579
831
|
if (command === "pull") {
|
|
@@ -593,28 +845,30 @@ async function runCommand(command, flags) {
|
|
|
593
845
|
if (result.skipped.length) {
|
|
594
846
|
console.log(`Skipped ${result.skipped.length} existing file(s). Use --overwrite to replace them.`);
|
|
595
847
|
}
|
|
848
|
+
if (result.written.length > 0) {
|
|
849
|
+
console.log("");
|
|
850
|
+
console.log("Run a pulled prompt:");
|
|
851
|
+
console.log(` prompts-gpt run --prompt-file ${result.written[0]}`);
|
|
852
|
+
console.log(" prompts-gpt list — see all available prompts");
|
|
853
|
+
}
|
|
596
854
|
return;
|
|
597
855
|
}
|
|
598
856
|
if (command === "generate") {
|
|
599
857
|
validateToolFlag(getStringFlag(flags, "tool"));
|
|
600
858
|
const goal = getStringFlag(flags, "goal");
|
|
601
859
|
if (!goal) {
|
|
602
|
-
throw new CliError("Prompt generation requires `--goal
|
|
603
|
-
|
|
604
|
-
|
|
860
|
+
throw new CliError("Prompt generation requires `--goal`.\n\n" +
|
|
861
|
+
"Example:\n" +
|
|
862
|
+
" prompts-gpt generate --goal \"Review pull requests for security issues\"\n" +
|
|
863
|
+
" prompts-gpt generate --goal \"Write unit tests\" --sync-agents\n\n" +
|
|
864
|
+
"Use --sync-agents to also write agent files (AGENTS.md, .cursor/rules, etc.).", CLI_EXIT_CODES.validation, { helpCommand: "generate" });
|
|
605
865
|
}
|
|
606
866
|
validateAgentFlag(getStringFlag(flags, "agent"));
|
|
867
|
+
if (!Boolean(flags.json)) {
|
|
868
|
+
printDataTransmissionNotice("generate", { goal, context: getStringFlag(flags, "context"), constraints: getStringFlag(flags, "constraints") });
|
|
869
|
+
}
|
|
607
870
|
const client = await createClientForCommand(command, flags);
|
|
608
|
-
const prompt = await client.generatePrompt(
|
|
609
|
-
goal,
|
|
610
|
-
context: getStringFlag(flags, "context") || "",
|
|
611
|
-
constraints: getStringFlag(flags, "constraints") || "",
|
|
612
|
-
desiredOutput: getStringFlag(flags, "desired-output") || "A reusable prompt pack saved as Markdown.",
|
|
613
|
-
tool: getStringFlag(flags, "tool") || "Codex",
|
|
614
|
-
mode: getStringFlag(flags, "mode") || "implement",
|
|
615
|
-
artifactType: getStringFlag(flags, "artifact-type") || "prompt-file",
|
|
616
|
-
includeWebSearch: Boolean(flags["web-search"]),
|
|
617
|
-
});
|
|
871
|
+
const prompt = await client.generatePrompt(buildGenerateInput(flags));
|
|
618
872
|
const cwd = getResolvedCwd(flags);
|
|
619
873
|
const result = await writePromptMarkdownFiles([prompt], {
|
|
620
874
|
cwd,
|
|
@@ -624,7 +878,12 @@ async function runCommand(command, flags) {
|
|
|
624
878
|
const shouldSyncAgents = Boolean(flags["sync-agents"]) || typeof getStringFlag(flags, "agent") === "string";
|
|
625
879
|
if (shouldSyncAgents) {
|
|
626
880
|
const target = getStringFlag(flags, "agent") || "all";
|
|
627
|
-
const pulled = await client.pullPrompts().catch(() =>
|
|
881
|
+
const pulled = await client.pullPrompts().catch((err) => {
|
|
882
|
+
if (!Boolean(flags.json)) {
|
|
883
|
+
console.error(`[warning] Could not pull existing prompts for agent sync: ${err.message}`);
|
|
884
|
+
}
|
|
885
|
+
return [];
|
|
886
|
+
});
|
|
628
887
|
const syncedPrompts = mergePromptPacks([prompt, ...pulled]);
|
|
629
888
|
const agentResult = await writeAgentFiles(syncedPrompts, {
|
|
630
889
|
cwd,
|
|
@@ -653,17 +912,11 @@ async function runCommand(command, flags) {
|
|
|
653
912
|
const goal = getStringFlag(flags, "goal");
|
|
654
913
|
const generatedOnly = Boolean(flags["generated-only"]);
|
|
655
914
|
const client = await createClientForCommand(command, flags);
|
|
915
|
+
if (goal && !Boolean(flags.json)) {
|
|
916
|
+
printDataTransmissionNotice("sync", { goal, context: getStringFlag(flags, "context"), constraints: getStringFlag(flags, "constraints") });
|
|
917
|
+
}
|
|
656
918
|
if (goal) {
|
|
657
|
-
prompts.push(await client.generatePrompt(
|
|
658
|
-
goal,
|
|
659
|
-
context: getStringFlag(flags, "context") || "",
|
|
660
|
-
constraints: getStringFlag(flags, "constraints") || "",
|
|
661
|
-
desiredOutput: getStringFlag(flags, "desired-output") || "A reusable prompt pack saved as Markdown.",
|
|
662
|
-
tool: getStringFlag(flags, "tool") || "Codex",
|
|
663
|
-
mode: getStringFlag(flags, "mode") || "implement",
|
|
664
|
-
artifactType: getStringFlag(flags, "artifact-type") || "prompt-file",
|
|
665
|
-
includeWebSearch: Boolean(flags["web-search"]),
|
|
666
|
-
}));
|
|
919
|
+
prompts.push(await client.generatePrompt(buildGenerateInput(flags)));
|
|
667
920
|
}
|
|
668
921
|
if (!generatedOnly) {
|
|
669
922
|
prompts.push(...await client.pullPrompts(buildPullQuery(flags, parsedLimit)));
|
|
@@ -691,6 +944,21 @@ async function runCommand(command, flags) {
|
|
|
691
944
|
}
|
|
692
945
|
console.log(`Synced ${result.agents.written.length} agent file(s): ${result.agents.targets.join(", ")}.`);
|
|
693
946
|
console.log(`Manifest: ${result.manifest.manifestPath}`);
|
|
947
|
+
const syncCwd = getResolvedCwd(flags);
|
|
948
|
+
const postSyncAssets = await discoverWorkspaceAssets(syncCwd);
|
|
949
|
+
if (postSyncAssets.sweeps.length > 0) {
|
|
950
|
+
console.log(`Sweeps: ${postSyncAssets.sweeps.length} sweep file(s) available.`);
|
|
951
|
+
}
|
|
952
|
+
const postProviders = await detectProviders(syncCwd);
|
|
953
|
+
const postAvailable = postProviders.filter((p) => p.available);
|
|
954
|
+
if (postAvailable.length > 0 && postSyncAssets.prompts.length > 0) {
|
|
955
|
+
console.log("");
|
|
956
|
+
console.log("Next steps:");
|
|
957
|
+
console.log(` prompts-gpt run --prompt-file .prompts-gpt/${postSyncAssets.prompts[0].file}`);
|
|
958
|
+
if (postSyncAssets.sweeps.length > 0) {
|
|
959
|
+
console.log(` prompts-gpt sweep --prompt-file ${postSyncAssets.sweeps[0].file}`);
|
|
960
|
+
}
|
|
961
|
+
}
|
|
694
962
|
return;
|
|
695
963
|
}
|
|
696
964
|
if (command === "project") {
|
|
@@ -744,7 +1012,11 @@ async function resolveClientOptions(command, flags) {
|
|
|
744
1012
|
}
|
|
745
1013
|
}
|
|
746
1014
|
if (!token) {
|
|
747
|
-
|
|
1015
|
+
const cloudCommands = new Set(["sync", "generate", "pull", "load-config", "project"]);
|
|
1016
|
+
const extra = cloudCommands.has(command)
|
|
1017
|
+
? `\n\nThis command connects to prompts-gpt.com. Set up credentials first:\n prompts-gpt init --token <project-token>\n prompts-gpt quickstart`
|
|
1018
|
+
: "";
|
|
1019
|
+
throw new CliError(`Project token is missing. Run \`prompts-gpt init --token <project-token>\` or pass \`--token\`, \`--token-stdin\`, or \`--token-prompt\` for this command.${extra}`, CLI_EXIT_CODES.auth, { helpCommand: command });
|
|
748
1020
|
}
|
|
749
1021
|
return {
|
|
750
1022
|
token,
|
|
@@ -911,7 +1183,7 @@ function getCommandOptions(command) {
|
|
|
911
1183
|
help: { type: "boolean" },
|
|
912
1184
|
cwd: { type: "string" },
|
|
913
1185
|
json: { type: "boolean" },
|
|
914
|
-
"prompt-file": { type: "string" },
|
|
1186
|
+
"prompt-file": { type: "string", short: "f" },
|
|
915
1187
|
agent: { type: "string" },
|
|
916
1188
|
model: { type: "string" },
|
|
917
1189
|
timeout: { type: "string" },
|
|
@@ -921,6 +1193,7 @@ function getCommandOptions(command) {
|
|
|
921
1193
|
"no-approve-mcps": { type: "boolean" },
|
|
922
1194
|
background: { type: "boolean" },
|
|
923
1195
|
"permission-mode": { type: "string" },
|
|
1196
|
+
"dry-run": { type: "boolean" },
|
|
924
1197
|
};
|
|
925
1198
|
}
|
|
926
1199
|
if (command === "sweep") {
|
|
@@ -928,10 +1201,10 @@ function getCommandOptions(command) {
|
|
|
928
1201
|
help: { type: "boolean" },
|
|
929
1202
|
cwd: { type: "string" },
|
|
930
1203
|
json: { type: "boolean" },
|
|
931
|
-
"prompt-file": { type: "string" },
|
|
1204
|
+
"prompt-file": { type: "string", short: "f" },
|
|
932
1205
|
agent: { type: "string" },
|
|
933
1206
|
model: { type: "string" },
|
|
934
|
-
iterations: { type: "string" },
|
|
1207
|
+
iterations: { type: "string", short: "n" },
|
|
935
1208
|
"iteration-timeout": { type: "string" },
|
|
936
1209
|
"max-retries": { type: "string" },
|
|
937
1210
|
"artifacts-dir": { type: "string" },
|
|
@@ -967,7 +1240,7 @@ function getCommandOptions(command) {
|
|
|
967
1240
|
agent: { type: "string" },
|
|
968
1241
|
};
|
|
969
1242
|
}
|
|
970
|
-
if (command === "list" || command === "status" || command === "validate" || command === "providers" || command === "doctor") {
|
|
1243
|
+
if (command === "quickstart" || command === "list" || command === "status" || command === "validate" || command === "providers" || command === "doctor") {
|
|
971
1244
|
return {
|
|
972
1245
|
help: { type: "boolean" },
|
|
973
1246
|
cwd: { type: "string" },
|
|
@@ -979,18 +1252,61 @@ function getCommandOptions(command) {
|
|
|
979
1252
|
});
|
|
980
1253
|
}
|
|
981
1254
|
function toCliParseError(error, command) {
|
|
982
|
-
const
|
|
1255
|
+
const runnableCmd = isRunnableCommand(command) ? command : undefined;
|
|
1256
|
+
const message = normalizeParseErrorMessage(error instanceof Error ? error.message : String(error), runnableCmd);
|
|
983
1257
|
return new CliError(message, CLI_EXIT_CODES.usage, {
|
|
984
1258
|
helpCommand: command,
|
|
985
1259
|
});
|
|
986
1260
|
}
|
|
987
|
-
function normalizeParseErrorMessage(message) {
|
|
1261
|
+
function normalizeParseErrorMessage(message, command) {
|
|
988
1262
|
const trimmed = message.trim();
|
|
989
1263
|
if (trimmed.startsWith("Unknown option")) {
|
|
990
|
-
|
|
1264
|
+
const match = trimmed.match(/Unknown option '(--[^']+)'/);
|
|
1265
|
+
const unknownFlag = match?.[1];
|
|
1266
|
+
const base = trimmed.endsWith(".") ? trimmed : `${trimmed}.`;
|
|
1267
|
+
if (unknownFlag && command) {
|
|
1268
|
+
const suggestion = suggestClosestFlag(unknownFlag, command);
|
|
1269
|
+
if (suggestion) {
|
|
1270
|
+
return `${base} Did you mean ${suggestion}?`;
|
|
1271
|
+
}
|
|
1272
|
+
}
|
|
1273
|
+
return base;
|
|
991
1274
|
}
|
|
992
1275
|
return trimmed;
|
|
993
1276
|
}
|
|
1277
|
+
function suggestClosestFlag(unknown, command) {
|
|
1278
|
+
const options = getCommandOptions(command);
|
|
1279
|
+
const flagName = unknown.replace(/^--/, "");
|
|
1280
|
+
const candidates = Object.keys(options);
|
|
1281
|
+
let best = null;
|
|
1282
|
+
let bestScore = 0;
|
|
1283
|
+
for (const candidate of candidates) {
|
|
1284
|
+
const score = computeFlagSimilarity(flagName, candidate);
|
|
1285
|
+
if (score > bestScore && score >= 0.4) {
|
|
1286
|
+
bestScore = score;
|
|
1287
|
+
best = candidate;
|
|
1288
|
+
}
|
|
1289
|
+
}
|
|
1290
|
+
return best ? `--${best}` : null;
|
|
1291
|
+
}
|
|
1292
|
+
function computeFlagSimilarity(a, b) {
|
|
1293
|
+
if (a === b)
|
|
1294
|
+
return 1;
|
|
1295
|
+
const shorter = a.length < b.length ? a : b;
|
|
1296
|
+
const longer = a.length < b.length ? b : a;
|
|
1297
|
+
if (longer.startsWith(shorter) || longer.endsWith(shorter))
|
|
1298
|
+
return 0.8;
|
|
1299
|
+
if (longer.includes(shorter) && shorter.length >= 3)
|
|
1300
|
+
return 0.6;
|
|
1301
|
+
if (shorter.length === 0)
|
|
1302
|
+
return 0;
|
|
1303
|
+
let matches = 0;
|
|
1304
|
+
for (let i = 0; i < Math.min(a.length, b.length); i++) {
|
|
1305
|
+
if (a[i] === b[i])
|
|
1306
|
+
matches++;
|
|
1307
|
+
}
|
|
1308
|
+
return matches / Math.max(a.length, b.length);
|
|
1309
|
+
}
|
|
994
1310
|
function validateFlagConflicts(command, flags) {
|
|
995
1311
|
const tokenSourceCount = [Boolean(flags.token), Boolean(flags["token-stdin"]), Boolean(flags["token-prompt"])].filter(Boolean).length;
|
|
996
1312
|
if (tokenSourceCount > 1) {
|
|
@@ -1266,32 +1582,36 @@ Usage:
|
|
|
1266
1582
|
prompts-gpt help [command]
|
|
1267
1583
|
prompts-gpt version
|
|
1268
1584
|
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
pull Download prompt packs as Markdown files
|
|
1274
|
-
generate Generate one prompt pack from a goal
|
|
1275
|
-
sync Generate and/or pull prompt packs, then sync agent files
|
|
1276
|
-
list Show available prompts, sweeps, and agent integrations
|
|
1585
|
+
Setup:
|
|
1586
|
+
quickstart Interactive setup — credentials, config, and first run
|
|
1587
|
+
init Save a project token
|
|
1588
|
+
setup Scaffold local orchestration config
|
|
1277
1589
|
status Show workspace readiness and next steps
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1590
|
+
doctor Validate prerequisites and config
|
|
1591
|
+
|
|
1592
|
+
Sync & Generate:
|
|
1593
|
+
sync Pull prompt packs and sync agent files
|
|
1594
|
+
pull Download prompt packs as Markdown files
|
|
1595
|
+
generate Generate a prompt pack from a goal
|
|
1596
|
+
load-config Pull config and prompts from Prompts Studio
|
|
1597
|
+
|
|
1598
|
+
Run:
|
|
1599
|
+
run Execute one prompt with a local agent (-f <file>)
|
|
1600
|
+
run-batch Execute multiple prompts
|
|
1601
|
+
sweep Multi-iteration execution (-f <file> -n <count>)
|
|
1602
|
+
|
|
1603
|
+
Inspect:
|
|
1604
|
+
list Show prompts, sweeps, and agent integrations
|
|
1605
|
+
validate Check config for errors
|
|
1606
|
+
providers Show detected provider CLIs
|
|
1607
|
+
project Show project linked to the token
|
|
1287
1608
|
|
|
1288
1609
|
Global options:
|
|
1289
1610
|
--help Show help
|
|
1290
1611
|
--version Show the current CLI version
|
|
1291
1612
|
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
Run agent profiles: ${ORCHESTRATION_AGENT_PROFILES.join(", ")}
|
|
1613
|
+
Providers: ${ORCHESTRATION_AGENT_PROFILES.filter((p) => p !== "router").join(", ")} (or router for auto-select)
|
|
1614
|
+
Agent targets: ${SUPPORTED_AGENT_TARGETS.join(", ")}
|
|
1295
1615
|
`);
|
|
1296
1616
|
}
|
|
1297
1617
|
function parsePositiveIntFlag(raw, flagName) {
|
|
@@ -1339,18 +1659,24 @@ function getCommandHelp(command) {
|
|
|
1339
1659
|
return `prompts-gpt init
|
|
1340
1660
|
|
|
1341
1661
|
Usage:
|
|
1342
|
-
prompts-gpt init
|
|
1662
|
+
prompts-gpt init [--token <project-token> | --token-stdin | --token-prompt] [--api-url <url>] [--cwd <path>]
|
|
1343
1663
|
|
|
1344
1664
|
Why use it:
|
|
1345
|
-
Stores a project token
|
|
1665
|
+
Stores a project token locally so you don't have to pass it on every command.
|
|
1666
|
+
If run without flags in an interactive terminal, it will prompt for the token.
|
|
1346
1667
|
|
|
1347
1668
|
Options:
|
|
1348
1669
|
--token <token> Project API token. Must start with pgpt_.
|
|
1349
|
-
--token-stdin Read the project token from stdin
|
|
1670
|
+
--token-stdin Read the project token from stdin (for CI/CD pipelines).
|
|
1350
1671
|
--token-prompt Prompt for the project token without echoing it.
|
|
1351
1672
|
--api-url <url> Custom API base URL for self-hosted instances.
|
|
1352
|
-
--cwd <path> Target project directory
|
|
1673
|
+
--cwd <path> Target project directory.
|
|
1353
1674
|
--help Show this command help.
|
|
1675
|
+
|
|
1676
|
+
Examples:
|
|
1677
|
+
prompts-gpt init # interactive prompt
|
|
1678
|
+
prompts-gpt init --token pgpt_abc123 # direct token
|
|
1679
|
+
printf '%s' "$TOKEN" | prompts-gpt init --token-stdin # CI/CD
|
|
1354
1680
|
`;
|
|
1355
1681
|
}
|
|
1356
1682
|
if (command === "setup") {
|
|
@@ -1411,6 +1737,10 @@ Usage:
|
|
|
1411
1737
|
Why use it:
|
|
1412
1738
|
Pulls prompt packs into local Markdown files so teams can review and use the same prompt assets inside their repository.
|
|
1413
1739
|
|
|
1740
|
+
Data privacy:
|
|
1741
|
+
Downloads prompts from your prompts-gpt.com project library.
|
|
1742
|
+
No local files or repo content are uploaded.
|
|
1743
|
+
|
|
1414
1744
|
Options:
|
|
1415
1745
|
--query <text> Search query for the project prompt library.
|
|
1416
1746
|
--q <text> Short alias for --query.
|
|
@@ -1437,6 +1767,11 @@ Usage:
|
|
|
1437
1767
|
Why use it:
|
|
1438
1768
|
Creates a new reusable prompt pack from a concrete developer goal, then optionally installs agent-readable files immediately.
|
|
1439
1769
|
|
|
1770
|
+
Data privacy:
|
|
1771
|
+
The text you pass via --goal, --context, and --constraints is sent to prompts-gpt.com
|
|
1772
|
+
for AI-powered prompt generation. No local files or repo content are uploaded.
|
|
1773
|
+
Do not include PII, secrets, or confidential data in these flags.
|
|
1774
|
+
|
|
1440
1775
|
Options:
|
|
1441
1776
|
--goal <text> Required. The task to generate a prompt pack for.
|
|
1442
1777
|
--context <text> Extra project or stack context for the generator.
|
|
@@ -1449,13 +1784,19 @@ Options:
|
|
|
1449
1784
|
--out <dir> Output directory inside the current project. Default: .prompts-gpt
|
|
1450
1785
|
--overwrite Replace an existing generated Markdown file.
|
|
1451
1786
|
--agent <targets> Sync agent files for specific targets after generation.
|
|
1452
|
-
|
|
1787
|
+
When set, also writes agent-specific files (AGENTS.md, .cursor/rules, etc.).
|
|
1788
|
+
--sync-agents Sync all agent files after generation (same as --agent all).
|
|
1453
1789
|
--token <token> Override the saved local token for this command only.
|
|
1454
1790
|
--token-stdin Read the override token from stdin for this command only.
|
|
1455
1791
|
--token-prompt Prompt for the override token without echoing it.
|
|
1456
1792
|
--api-url <url> Override the saved API base URL for this command only.
|
|
1457
1793
|
--cwd <path> Project directory to inspect for local credentials and output files.
|
|
1458
1794
|
--help Show this command help.
|
|
1795
|
+
|
|
1796
|
+
Examples:
|
|
1797
|
+
prompts-gpt generate --goal "Review PRs for security issues"
|
|
1798
|
+
prompts-gpt generate --goal "Write unit tests" --sync-agents
|
|
1799
|
+
prompts-gpt generate --goal "Add error handling" --agent cursor,codex
|
|
1459
1800
|
`;
|
|
1460
1801
|
}
|
|
1461
1802
|
if (command === "sync") {
|
|
@@ -1467,6 +1808,13 @@ Usage:
|
|
|
1467
1808
|
Why use it:
|
|
1468
1809
|
Gives teams a one-command path to refresh Markdown prompts, agent files, and the local manifest from the same source of truth.
|
|
1469
1810
|
|
|
1811
|
+
Data privacy:
|
|
1812
|
+
Prompts are downloaded from your prompts-gpt.com project library.
|
|
1813
|
+
When --goal is used, the text you pass is sent to prompts-gpt.com for AI generation.
|
|
1814
|
+
No local files or repo content are uploaded — only explicit flag values are transmitted.
|
|
1815
|
+
Do not include PII, secrets, or confidential data in --goal, --context, or --constraints.
|
|
1816
|
+
Use --dry-run to preview what would be synced without sending or writing anything.
|
|
1817
|
+
|
|
1470
1818
|
Options:
|
|
1471
1819
|
--goal <text> Generate one prompt pack before syncing.
|
|
1472
1820
|
--generated-only Skip library pull and sync only the generated prompt pack from --goal.
|
|
@@ -1492,19 +1840,26 @@ Options:
|
|
|
1492
1840
|
--api-url <url> Override the saved API base URL for this command only.
|
|
1493
1841
|
--cwd <path> Project directory to inspect for local credentials and output files.
|
|
1494
1842
|
--help Show this command help.
|
|
1843
|
+
|
|
1844
|
+
Examples:
|
|
1845
|
+
prompts-gpt sync # pull all prompts + sync agent files
|
|
1846
|
+
prompts-gpt sync --goal "Add error handling" # generate + pull + sync
|
|
1847
|
+
prompts-gpt sync --dry-run # preview without writing
|
|
1848
|
+
prompts-gpt sync --agent cursor,codex # sync only specific agents
|
|
1495
1849
|
`;
|
|
1496
1850
|
}
|
|
1497
1851
|
if (command === "run") {
|
|
1498
1852
|
return `prompts-gpt run
|
|
1499
1853
|
|
|
1500
1854
|
Usage:
|
|
1501
|
-
prompts-gpt run [
|
|
1855
|
+
prompts-gpt run [-f <path>] [--agent <name>] [--model <name>] [--timeout <seconds>] [--dry-run]
|
|
1502
1856
|
|
|
1503
1857
|
Why use it:
|
|
1504
|
-
Executes one local prompt file with the built-in provider adapter runtime and writes run artifacts.
|
|
1858
|
+
Executes one local prompt file with the built-in provider adapter runtime and writes run artifacts.
|
|
1859
|
+
If \`--prompt-file\` is omitted and only one prompt exists locally, it is auto-selected.
|
|
1505
1860
|
|
|
1506
1861
|
Options:
|
|
1507
|
-
--prompt-file <path>
|
|
1862
|
+
-f, --prompt-file <path> Optional explicit prompt Markdown or text file.
|
|
1508
1863
|
--agent <name> Orchestration profile. Default from ${DEFAULT_RUN_CONFIG_PATH} or router.
|
|
1509
1864
|
--model <name> Optional model override for the selected provider.
|
|
1510
1865
|
--timeout <seconds> Execution timeout in seconds.
|
|
@@ -1514,6 +1869,7 @@ Options:
|
|
|
1514
1869
|
--no-approve-mcps Disable Cursor MCP auto-approval flag.
|
|
1515
1870
|
--background Run as a background agent (Cursor cloud agent mode).
|
|
1516
1871
|
--permission-mode <mode> Claude Code permission mode. Default: acceptEdits.
|
|
1872
|
+
--dry-run Preview the execution parameters without actually running.
|
|
1517
1873
|
--json Print machine-readable JSON output.
|
|
1518
1874
|
--cwd <path> Project directory.
|
|
1519
1875
|
--help Show this command help.
|
|
@@ -1523,7 +1879,7 @@ Options:
|
|
|
1523
1879
|
return `prompts-gpt run-batch
|
|
1524
1880
|
|
|
1525
1881
|
Usage:
|
|
1526
|
-
prompts-gpt run-batch [--manifest <path> | --prompt-files <a,b,c>] [--agent
|
|
1882
|
+
prompts-gpt run-batch [--manifest <path> | --prompt-files <a,b,c>] [--agent <name>] [--model <name>] [--timeout <seconds>]
|
|
1527
1883
|
|
|
1528
1884
|
Why use it:
|
|
1529
1885
|
Executes multiple prompt files in sequence using the configured prompt source, a manifest, or an explicit file list.
|
|
@@ -1538,25 +1894,31 @@ Options:
|
|
|
1538
1894
|
--json Print machine-readable JSON output.
|
|
1539
1895
|
--cwd <path> Project directory.
|
|
1540
1896
|
--help Show this command help.
|
|
1897
|
+
|
|
1898
|
+
Examples:
|
|
1899
|
+
prompts-gpt run-batch --manifest .prompts-gpt/manifest.json
|
|
1900
|
+
prompts-gpt run-batch --prompt-files .prompts-gpt/review.md,.prompts-gpt/tests.md
|
|
1541
1901
|
`;
|
|
1542
1902
|
}
|
|
1543
1903
|
if (command === "sweep") {
|
|
1544
1904
|
return `prompts-gpt sweep
|
|
1545
1905
|
|
|
1546
1906
|
Usage:
|
|
1547
|
-
prompts-gpt sweep [
|
|
1907
|
+
prompts-gpt sweep [-f <path>] [-n <count>] [--agent <name>] [--model <name>] [--dry-run]
|
|
1548
1908
|
|
|
1549
1909
|
Why use it:
|
|
1550
|
-
Replaces the bash sweep scripts with a generic multi-iteration execution engine.
|
|
1551
1910
|
Runs the same prompt N times, feeding each iteration's summary into the next.
|
|
1552
|
-
Includes pre-flight checks, safety guards, SIGTERM handling, progress monitoring
|
|
1553
|
-
|
|
1911
|
+
Includes pre-flight checks, safety guards, SIGTERM handling, and progress monitoring.
|
|
1912
|
+
|
|
1913
|
+
When --prompt-file is omitted and only one .prompts-gpt/sweeps/*.md file exists,
|
|
1914
|
+
it is auto-selected. The iteration count defaults to the \`iterations:\` value
|
|
1915
|
+
in the sweep file's YAML frontmatter (or 1 if not specified).
|
|
1554
1916
|
|
|
1555
1917
|
Options:
|
|
1556
|
-
--prompt-file <path>
|
|
1918
|
+
-f, --prompt-file <path> Prompt file to sweep. Auto-detects local sweeps if omitted.
|
|
1919
|
+
-n, --iterations <n> Number of iterations. Default: from frontmatter or 1.
|
|
1557
1920
|
--agent <name> Orchestration profile. Default from config or router.
|
|
1558
1921
|
--model <name> Model override for the selected provider.
|
|
1559
|
-
--iterations <n> Number of sweep iterations. Default: 1
|
|
1560
1922
|
--iteration-timeout <secs> Timeout per iteration in seconds. Default: 5400 (90 min)
|
|
1561
1923
|
--max-retries <n> Max retries per iteration on spawn/timeout. Default: 2
|
|
1562
1924
|
--phase <name> Optional phase label injected into the prompt.
|
|
@@ -1572,6 +1934,12 @@ Options:
|
|
|
1572
1934
|
--json Print machine-readable JSON output.
|
|
1573
1935
|
--cwd <path> Project directory.
|
|
1574
1936
|
--help Show this command help.
|
|
1937
|
+
|
|
1938
|
+
Examples:
|
|
1939
|
+
prompts-gpt sweep # auto-pick local sweep
|
|
1940
|
+
prompts-gpt sweep -f .prompts-gpt/sweeps/sdk-hardening.md # explicit file
|
|
1941
|
+
prompts-gpt sweep -f .prompts-gpt/sweeps/design.md -n 5 # 5 iterations
|
|
1942
|
+
prompts-gpt sweep --dry-run # preview without running
|
|
1575
1943
|
`;
|
|
1576
1944
|
}
|
|
1577
1945
|
if (command === "list") {
|
|
@@ -1653,6 +2021,10 @@ Why use it:
|
|
|
1653
2021
|
into your local workspace. Replaces the multi-step init + sync + setup flow
|
|
1654
2022
|
for users who manage their prompt library in the Prompts Studio web app.
|
|
1655
2023
|
|
|
2024
|
+
Data privacy:
|
|
2025
|
+
Downloads prompts and project config from your prompts-gpt.com project.
|
|
2026
|
+
No local files or repo content are uploaded.
|
|
2027
|
+
|
|
1656
2028
|
Options:
|
|
1657
2029
|
--agent <targets> Comma-separated agent targets. Default: all
|
|
1658
2030
|
--out <dir> Output directory. Default: .prompts-gpt
|
|
@@ -1663,6 +2035,22 @@ Options:
|
|
|
1663
2035
|
--api-url <url> Override API URL.
|
|
1664
2036
|
--cwd <path> Project directory.
|
|
1665
2037
|
--help Show this command help.
|
|
2038
|
+
`;
|
|
2039
|
+
}
|
|
2040
|
+
if (command === "quickstart") {
|
|
2041
|
+
return `prompts-gpt quickstart
|
|
2042
|
+
|
|
2043
|
+
Usage:
|
|
2044
|
+
prompts-gpt quickstart [--json] [--cwd <path>]
|
|
2045
|
+
|
|
2046
|
+
Why use it:
|
|
2047
|
+
Walks through setup in one command — checks credentials, creates config, detects providers,
|
|
2048
|
+
and shows runnable commands. The fastest path from install to first run.
|
|
2049
|
+
|
|
2050
|
+
Options:
|
|
2051
|
+
--json Print machine-readable JSON output.
|
|
2052
|
+
--cwd <path> Project directory.
|
|
2053
|
+
--help Show this command help.
|
|
1666
2054
|
`;
|
|
1667
2055
|
}
|
|
1668
2056
|
if (command === "version") {
|
|
@@ -1684,6 +2072,41 @@ Why use it:
|
|
|
1684
2072
|
Shows focused usage for the exact command you are trying to run so shell users do not have to scan the full command list.
|
|
1685
2073
|
`;
|
|
1686
2074
|
}
|
|
2075
|
+
async function readSweepIterationsFromFrontmatter(filePath) {
|
|
2076
|
+
try {
|
|
2077
|
+
const { readFile: fsRead } = await import("node:fs/promises");
|
|
2078
|
+
const content = await fsRead(filePath, "utf8");
|
|
2079
|
+
const match = content.match(/iterations:\s*(\d+)/i);
|
|
2080
|
+
if (match) {
|
|
2081
|
+
const val = parseInt(match[1], 10);
|
|
2082
|
+
if (val > 0 && val <= 50)
|
|
2083
|
+
return val;
|
|
2084
|
+
}
|
|
2085
|
+
}
|
|
2086
|
+
catch { /* skip */ }
|
|
2087
|
+
return null;
|
|
2088
|
+
}
|
|
2089
|
+
function buildGenerateInput(flags) {
|
|
2090
|
+
return {
|
|
2091
|
+
goal: getStringFlag(flags, "goal") || "",
|
|
2092
|
+
context: sanitizeGenerateInput(getStringFlag(flags, "context") || ""),
|
|
2093
|
+
constraints: sanitizeGenerateInput(getStringFlag(flags, "constraints") || ""),
|
|
2094
|
+
desiredOutput: getStringFlag(flags, "desired-output") || "A reusable prompt pack saved as Markdown.",
|
|
2095
|
+
tool: getStringFlag(flags, "tool") || "Codex",
|
|
2096
|
+
mode: getStringFlag(flags, "mode") || "implement",
|
|
2097
|
+
artifactType: getStringFlag(flags, "artifact-type") || "prompt-file",
|
|
2098
|
+
includeWebSearch: Boolean(flags["web-search"]),
|
|
2099
|
+
};
|
|
2100
|
+
}
|
|
2101
|
+
function sanitizeGenerateInput(value) {
|
|
2102
|
+
return value.replace(/pgpt_[a-zA-Z0-9]{4,}/g, "pgpt_***").replace(/sk-[a-zA-Z0-9]{20,}/g, "sk-***").replace(/ghp_[a-zA-Z0-9]{36,}/g, "ghp_***");
|
|
2103
|
+
}
|
|
2104
|
+
function printDataTransmissionNotice(command, input) {
|
|
2105
|
+
console.log(`[notice] The --goal text${input.context ? ", --context" : ""}${input.constraints ? ", --constraints" : ""} you provided will be sent to prompts-gpt.com to generate a prompt.`);
|
|
2106
|
+
console.log("[notice] Do not include PII, secrets, or confidential data in these flags.");
|
|
2107
|
+
console.log(`[notice] No local files or repo content are uploaded. Only the explicit flag values for \`${command}\` are transmitted.`);
|
|
2108
|
+
console.log("");
|
|
2109
|
+
}
|
|
1687
2110
|
main().catch((error) => {
|
|
1688
2111
|
if (error instanceof CliError) {
|
|
1689
2112
|
console.error(error.message);
|
|
@@ -1708,6 +2131,46 @@ main().catch((error) => {
|
|
|
1708
2131
|
console.error(msg.replace(/pgpt_[a-zA-Z0-9]{4,}/g, "pgpt_***"));
|
|
1709
2132
|
process.exitCode = CLI_EXIT_CODES.general;
|
|
1710
2133
|
});
|
|
2134
|
+
async function extractRunDiagnostics(logFile, provider, model) {
|
|
2135
|
+
const diagnostics = [];
|
|
2136
|
+
try {
|
|
2137
|
+
const { readFile: fsReadFile } = await import("node:fs/promises");
|
|
2138
|
+
const log = await fsReadFile(logFile, "utf8");
|
|
2139
|
+
const errorLines = log.split("\n").filter((line) => line.startsWith("ERROR:") || line.includes('"error"'));
|
|
2140
|
+
for (const line of errorLines.slice(0, 5)) {
|
|
2141
|
+
if (line.includes("not supported")) {
|
|
2142
|
+
const modelMatch = line.match(/The '([^']+)' model is not supported/);
|
|
2143
|
+
const badModel = modelMatch?.[1] ?? model;
|
|
2144
|
+
diagnostics.push(`Model "${badModel}" is not supported by ${provider} with your account.`);
|
|
2145
|
+
diagnostics.push(`Fix: prompts-gpt run --model o4-mini`);
|
|
2146
|
+
diagnostics.push(`Or: prompts-gpt run --agent claude`);
|
|
2147
|
+
break;
|
|
2148
|
+
}
|
|
2149
|
+
if (line.includes("unauthorized") || line.includes("authentication")) {
|
|
2150
|
+
diagnostics.push(`Authentication failed for ${provider}. Check your ${provider} account login.`);
|
|
2151
|
+
diagnostics.push(`Fix: Run the ${provider} CLI directly to verify auth: ${provider} --version`);
|
|
2152
|
+
break;
|
|
2153
|
+
}
|
|
2154
|
+
if (line.includes("rate_limit") || line.includes("429")) {
|
|
2155
|
+
diagnostics.push(`Rate limited by ${provider}. Wait and try again.`);
|
|
2156
|
+
break;
|
|
2157
|
+
}
|
|
2158
|
+
}
|
|
2159
|
+
if (diagnostics.length === 0 && errorLines.length > 0) {
|
|
2160
|
+
const firstError = errorLines[0].slice(0, 200);
|
|
2161
|
+
diagnostics.push(`Provider error: ${firstError}`);
|
|
2162
|
+
}
|
|
2163
|
+
if (diagnostics.length === 0) {
|
|
2164
|
+
diagnostics.push(`${provider} exited with code 1. Check the log for details:`);
|
|
2165
|
+
diagnostics.push(` cat ${logFile}`);
|
|
2166
|
+
diagnostics.push(`Try a different provider: prompts-gpt run --agent claude`);
|
|
2167
|
+
}
|
|
2168
|
+
}
|
|
2169
|
+
catch {
|
|
2170
|
+
diagnostics.push(`Could not read log file. Check: ${logFile}`);
|
|
2171
|
+
}
|
|
2172
|
+
return diagnostics;
|
|
2173
|
+
}
|
|
1711
2174
|
function warnOnConfigIssues(config) {
|
|
1712
2175
|
for (const w of config.configWarnings) {
|
|
1713
2176
|
console.error(`[config warning] ${w}`);
|
|
@@ -1728,4 +2191,21 @@ function formatApiError(error) {
|
|
|
1728
2191
|
}
|
|
1729
2192
|
return lines.join("\n");
|
|
1730
2193
|
}
|
|
2194
|
+
function formatTokenUsage(usage) {
|
|
2195
|
+
const parts = [
|
|
2196
|
+
`total=${usage.totalTokens.toLocaleString()}`,
|
|
2197
|
+
`input=${usage.inputTokens.toLocaleString()}`,
|
|
2198
|
+
`output=${usage.outputTokens.toLocaleString()}`,
|
|
2199
|
+
];
|
|
2200
|
+
if (usage.reasoningTokens > 0) {
|
|
2201
|
+
parts.push(`reasoning=${usage.reasoningTokens.toLocaleString()}`);
|
|
2202
|
+
}
|
|
2203
|
+
if (usage.cacheReadTokens > 0) {
|
|
2204
|
+
parts.push(`cache-read=${usage.cacheReadTokens.toLocaleString()}`);
|
|
2205
|
+
}
|
|
2206
|
+
if (usage.cacheWriteTokens > 0) {
|
|
2207
|
+
parts.push(`cache-write=${usage.cacheWriteTokens.toLocaleString()}`);
|
|
2208
|
+
}
|
|
2209
|
+
return parts.join(" | ");
|
|
2210
|
+
}
|
|
1731
2211
|
//# sourceMappingURL=cli.js.map
|