@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/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
- printHelp();
31
- console.log("Quick start:");
32
- console.log(" prompts-gpt status — check workspace readiness");
33
- console.log(" prompts-gpt list see available prompts, sweeps, agents");
34
- console.log(" prompts-gpt help <cmd> detailed help for a command");
35
- console.log("");
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
- console.log(`${provider.provider}: ${provider.available ? "available" : "missing"} | bin=${provider.bin} | model=${provider.modelDefault}${provider.version ? ` | version=${provider.version}` : ""}`);
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(`Default agent: ${result.config.defaultAgent ?? "router"}`);
128
- console.log(`Provider order: ${(result.config.providerOrder ?? []).join(", ")}`);
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
- if (result.sourceSummary.manifestPath) {
133
- console.log(`Batch default manifest: ${result.sourceSummary.manifestPath}`);
134
- }
135
- else if (result.sourceSummary.promptFiles.length > 0) {
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
- console.log(" prompts-gpt run-batch");
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
- console.log(` ${p.slug} ${p.title} [${p.source}]`);
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
- console.log(` ${s.name}`);
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
- console.log(` Prompts: ${assets.prompts.length > 0 ? `✓ (${assets.prompts.length})` : " none found"}`);
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
- console.log(` Providers: ${availableProviders.length > 0 ? `✓ (${availableProviders.map((p) => p.provider).join(", ")})` : "✗ — no CLI found"}`);
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
- console.log(` prompts-gpt sweep --prompt-file ${assets.sweeps[0].file}`);
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("Next steps:");
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: getStringFlag(flags, "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-selected)`;
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
- console.log(` [${idx + 1}/${result.total}] ${status} ${path.basename(run.promptFile)} -> ${run.provider} (exit=${run.exitCode}, ${formatDuration(run.durationMs)})`);
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
- if (!config.defaultPromptFile) {
395
- const assets = await discoverWorkspaceAssets(cwd);
396
- if (assets.sweeps.length > 0) {
397
- console.log("No default prompt file configured. Available sweep prompts:\n");
398
- for (const s of assets.sweeps) {
399
- console.log(` prompts-gpt sweep --prompt-file ${s.file}`);
400
- }
401
- if (assets.prompts.length > 0) {
402
- console.log("\nOr run a prompt pack instead:");
403
- for (const p of assets.prompts.slice(0, 3)) {
404
- console.log(` prompts-gpt run --prompt-file .prompts-gpt/${p.file}`);
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
- const token = await resolveTokenInput(flags, { command });
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("Next: prompts-gpt sync");
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`.", CLI_EXIT_CODES.validation, {
603
- helpCommand: "generate",
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
- 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.", CLI_EXIT_CODES.auth, { helpCommand: command });
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 message = normalizeParseErrorMessage(error instanceof Error ? error.message : String(error));
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
- return `${trimmed}.`;
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
- Commands:
1270
- init Save a project token in .prompts-gpt/.credentials.json
1271
- setup Scaffold .prompts-gpt/config.json for local orchestration
1272
- load-config Pull configuration and prompts directly from Prompts Studio
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
- validate Validate .prompts-gpt/config.json and report issues
1279
- run Execute a prompt file with local agent orchestration
1280
- run-batch Execute multiple prompt files from config, manifest, or list
1281
- sweep Multi-iteration prompt execution with progress and summaries
1282
- providers Show detected local provider CLIs
1283
- doctor Validate local run prerequisites and config
1284
- project Show the current project linked to the token
1285
- version Show the current CLI version
1286
- help Show global or command-specific help
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
- Supported tools: ${VALID_TOOLS.join(", ")}
1293
- Supported agent targets: ${SUPPORTED_AGENT_TARGETS.join(", ")}
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 (--token <project-token> | --token-stdin | --token-prompt) [--api-url <url>] [--cwd <path>]
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 in a local credentials file so day-one CLI usage does not require re-pasting secrets on every command.
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 so it does not end up in shell history.
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 that will receive .prompts-gpt/.credentials.json.
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
- --sync-agents Sync all agent files after generation.
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 [--prompt-file <path>] [--agent codex|cursor|claude|copilot|router] [--model <name>] [--timeout <seconds>] [--artifacts-dir <path>] [--run-id <id>] [--sandbox <mode>] [--no-approve-mcps] [--background] [--permission-mode <mode>] [--json] [--cwd <path>]
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. If \`--prompt-file\` is omitted, the command uses the configured default prompt.
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> Optional explicit prompt Markdown or text file.
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 codex|cursor|claude|copilot|router] [--model <name>] [--timeout <seconds>] [--artifacts-dir <path>] [--json] [--cwd <path>]
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 [--prompt-file <path>] [--agent codex|cursor|claude|copilot|router] [--model <name>] [--iterations <n>] [--iteration-timeout <seconds>] [--max-retries <n>] [--phase <name>] [--artifacts-dir <path>] [--run-id <id>] [--sandbox <mode>] [--no-approve-mcps] [--background] [--permission-mode <mode>] [--max-run-dirs <n>] [--summary-lines <n>] [--dry-run] [--json] [--cwd <path>]
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
- and a structured sweep manifest.
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> Prompt file to sweep. Reads from config if omitted.
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