@prompts-gpt/client 0.2.0 → 0.2.2
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/CHANGELOG.md +67 -1
- package/README.md +76 -16
- package/dist/cli.js +736 -132
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +66 -24
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +474 -97
- package/dist/index.js.map +1 -1
- package/package.json +8 -7
package/dist/cli.js
CHANGED
|
@@ -1,186 +1,591 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
|
|
2
|
+
import { existsSync } from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { parseArgs } from "node:util";
|
|
5
|
+
import { DEFAULT_PROMPTS_GPT_API_URL, DEFAULT_PROMPTS_GPT_OUT_DIR, PROMPTS_GPT_CREDENTIALS_FILE, PromptsGptApiError, PromptsGptClient, SUPPORTED_AGENT_TARGETS, loadLocalCredentials, saveLocalCredentials, syncPrompts, writeAgentFiles, writePromptMarkdownFiles, } from "./index.js";
|
|
6
|
+
const CLI_EXIT_CODES = {
|
|
7
|
+
success: 0,
|
|
8
|
+
general: 1,
|
|
9
|
+
auth: 2,
|
|
10
|
+
validation: 3,
|
|
11
|
+
rateLimit: 4,
|
|
12
|
+
usage: 64,
|
|
13
|
+
};
|
|
4
14
|
const VALID_TOOLS = ["Codex", "Claude Code", "Cursor", "GitHub Copilot", "ChatGPT", "Gemini", "Perplexity", "Grok", "DeepSeek", "Claude"];
|
|
15
|
+
const COMMANDS = ["init", "project", "pull", "generate", "sync", "install-agents", "version", "help"];
|
|
16
|
+
const MAX_STDIN_TOKEN_LENGTH = 4_096;
|
|
17
|
+
class CliError extends Error {
|
|
18
|
+
exitCode;
|
|
19
|
+
helpCommand;
|
|
20
|
+
constructor(message, exitCode, options) {
|
|
21
|
+
super(message);
|
|
22
|
+
this.name = "CliError";
|
|
23
|
+
this.exitCode = exitCode;
|
|
24
|
+
this.helpCommand = options?.helpCommand;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
5
27
|
async function main() {
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
if (!command || command === "help" || flags.help) {
|
|
28
|
+
const argv = process.argv.slice(2);
|
|
29
|
+
if (argv.length === 0) {
|
|
9
30
|
printHelp();
|
|
10
31
|
return;
|
|
11
32
|
}
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
33
|
+
const normalizedArgv = normalizeLegacyFlags(argv);
|
|
34
|
+
const first = normalizedArgv[0];
|
|
35
|
+
if (first === "--help") {
|
|
36
|
+
printHelp();
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
if (first === "--version") {
|
|
40
|
+
await printVersion();
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
if (first === "help") {
|
|
44
|
+
handleHelpCommand(normalizedArgv.slice(1));
|
|
15
45
|
return;
|
|
16
46
|
}
|
|
47
|
+
if (first === "version") {
|
|
48
|
+
if (normalizedArgv.length > 1) {
|
|
49
|
+
throw new CliError("The `version` command does not accept additional arguments.", CLI_EXIT_CODES.usage, {
|
|
50
|
+
helpCommand: "version",
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
await printVersion();
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
const command = asCommandName(first);
|
|
57
|
+
if (!command) {
|
|
58
|
+
throw new CliError(`Unknown command: ${first}.`, CLI_EXIT_CODES.usage);
|
|
59
|
+
}
|
|
60
|
+
if (!isRunnableCommand(command)) {
|
|
61
|
+
throw new CliError(`Unknown command: ${first}.`, CLI_EXIT_CODES.usage, {
|
|
62
|
+
helpCommand: "help",
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
const flags = parseCommandFlags(command, normalizedArgv.slice(1));
|
|
66
|
+
if (Boolean(flags.help)) {
|
|
67
|
+
printHelp(command);
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
await runCommand(command, flags);
|
|
71
|
+
}
|
|
72
|
+
async function runCommand(command, flags) {
|
|
17
73
|
if (command === "init") {
|
|
18
|
-
const token = flags
|
|
19
|
-
if (!token)
|
|
20
|
-
throw new
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
74
|
+
const token = await resolveTokenInput(flags, { command });
|
|
75
|
+
if (!token) {
|
|
76
|
+
throw new CliError("Run `prompts-gpt init --token <project-token>`, `--token-stdin`, or `--token-prompt`.", CLI_EXIT_CODES.validation, {
|
|
77
|
+
helpCommand: "init",
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
if (token.length > 256) {
|
|
81
|
+
throw new CliError("Token value is invalid or too long.", CLI_EXIT_CODES.validation, {
|
|
82
|
+
helpCommand: "init",
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
if (!token.startsWith("pgpt_")) {
|
|
86
|
+
throw new CliError("Token must start with `pgpt_`. Copy the full token from the Prompts-GPT dashboard.", CLI_EXIT_CODES.validation, {
|
|
87
|
+
helpCommand: "init",
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
const cwd = getResolvedCwd(flags);
|
|
25
91
|
const result = await saveLocalCredentials({
|
|
26
92
|
token,
|
|
27
|
-
apiUrl: flags
|
|
28
|
-
cwd
|
|
93
|
+
apiUrl: getStringFlag(flags, "api-url") || DEFAULT_PROMPTS_GPT_API_URL,
|
|
94
|
+
cwd,
|
|
29
95
|
});
|
|
30
96
|
console.log(`Saved Prompts-GPT credentials to ${result.credentialsPath}`);
|
|
31
97
|
console.log("The credentials file is added to .gitignore.");
|
|
32
98
|
return;
|
|
33
99
|
}
|
|
34
|
-
const cwd = flags.cwd || process.cwd();
|
|
35
|
-
const credentials = await loadLocalCredentials(cwd);
|
|
36
|
-
const client = new PromptsGptClient({
|
|
37
|
-
token: flags.token || credentials?.token || "",
|
|
38
|
-
apiUrl: flags.apiUrl || credentials?.apiUrl || DEFAULT_PROMPTS_GPT_API_URL,
|
|
39
|
-
fetch,
|
|
40
|
-
});
|
|
41
|
-
if (command === "project") {
|
|
42
|
-
const project = await client.getProject();
|
|
43
|
-
console.log(`${project.brandName} (${project.websiteUrl})`);
|
|
44
|
-
return;
|
|
45
|
-
}
|
|
46
100
|
if (command === "pull") {
|
|
47
|
-
const
|
|
101
|
+
const parsedLimit = parseLimitFlag(getStringFlag(flags, "limit"));
|
|
102
|
+
const client = await createClientForCommand(command, flags);
|
|
103
|
+
const prompts = await client.pullPrompts(buildPullQuery(flags, parsedLimit));
|
|
48
104
|
if (prompts.length === 0) {
|
|
49
105
|
console.log("No prompts matched the query. Try different filters or check the project prompt library.");
|
|
50
106
|
return;
|
|
51
107
|
}
|
|
52
108
|
const result = await writePromptMarkdownFiles(prompts, {
|
|
53
|
-
cwd,
|
|
54
|
-
outDir: flags
|
|
109
|
+
cwd: getResolvedCwd(flags),
|
|
110
|
+
outDir: getStringFlag(flags, "out") || DEFAULT_PROMPTS_GPT_OUT_DIR,
|
|
55
111
|
overwrite: Boolean(flags.overwrite),
|
|
56
112
|
});
|
|
57
113
|
console.log(`Wrote ${result.written.length} prompt file(s) to ${result.outDir}.`);
|
|
58
|
-
if (result.skipped.length)
|
|
114
|
+
if (result.skipped.length) {
|
|
59
115
|
console.log(`Skipped ${result.skipped.length} existing file(s). Use --overwrite to replace them.`);
|
|
116
|
+
}
|
|
60
117
|
return;
|
|
61
118
|
}
|
|
62
119
|
if (command === "generate") {
|
|
63
|
-
validateToolFlag(flags
|
|
64
|
-
const
|
|
120
|
+
validateToolFlag(getStringFlag(flags, "tool"));
|
|
121
|
+
const goal = getStringFlag(flags, "goal");
|
|
122
|
+
if (!goal) {
|
|
123
|
+
throw new CliError("Prompt generation requires `--goal`.", CLI_EXIT_CODES.validation, {
|
|
124
|
+
helpCommand: "generate",
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
validateAgentFlag(getStringFlag(flags, "agent"));
|
|
128
|
+
const client = await createClientForCommand(command, flags);
|
|
129
|
+
const prompt = await client.generatePrompt({
|
|
130
|
+
goal,
|
|
131
|
+
context: getStringFlag(flags, "context") || "",
|
|
132
|
+
constraints: getStringFlag(flags, "constraints") || "",
|
|
133
|
+
desiredOutput: getStringFlag(flags, "desired-output") || "A reusable prompt pack saved as Markdown.",
|
|
134
|
+
tool: getStringFlag(flags, "tool") || "Codex",
|
|
135
|
+
mode: getStringFlag(flags, "mode") || "implement",
|
|
136
|
+
artifactType: getStringFlag(flags, "artifact-type") || "prompt-file",
|
|
137
|
+
includeWebSearch: Boolean(flags["web-search"]),
|
|
138
|
+
});
|
|
139
|
+
const cwd = getResolvedCwd(flags);
|
|
65
140
|
const result = await writePromptMarkdownFiles([prompt], {
|
|
66
141
|
cwd,
|
|
67
|
-
outDir: flags
|
|
142
|
+
outDir: getStringFlag(flags, "out") || DEFAULT_PROMPTS_GPT_OUT_DIR,
|
|
68
143
|
overwrite: Boolean(flags.overwrite),
|
|
69
144
|
});
|
|
70
|
-
const
|
|
71
|
-
if (
|
|
145
|
+
const shouldSyncAgents = Boolean(flags["sync-agents"]) || typeof getStringFlag(flags, "agent") === "string";
|
|
146
|
+
if (shouldSyncAgents) {
|
|
147
|
+
const target = getStringFlag(flags, "agent") || "all";
|
|
72
148
|
const agentResult = await writeAgentFiles([prompt], {
|
|
73
149
|
cwd,
|
|
74
|
-
agent:
|
|
150
|
+
agent: target,
|
|
75
151
|
overwriteAgentFiles: true,
|
|
76
152
|
});
|
|
77
153
|
console.log(`Synced ${agentResult.written.length} agent file(s) for ${agentResult.targets.join(", ")}.`);
|
|
78
154
|
}
|
|
79
155
|
console.log(`Generated: ${prompt.title}`);
|
|
80
156
|
console.log(`Wrote to ${result.written[0] ?? result.outDir}.`);
|
|
81
|
-
if (result.skipped.length)
|
|
157
|
+
if (result.skipped.length) {
|
|
82
158
|
console.log("Skipped existing generated prompt. Use --overwrite to replace it.");
|
|
159
|
+
}
|
|
83
160
|
return;
|
|
84
161
|
}
|
|
85
162
|
if (command === "sync") {
|
|
86
|
-
validateToolFlag(flags
|
|
163
|
+
validateToolFlag(getStringFlag(flags, "tool"));
|
|
164
|
+
validateAgentFlag(getStringFlag(flags, "agent"));
|
|
165
|
+
const parsedLimit = parseLimitFlag(getStringFlag(flags, "limit"));
|
|
87
166
|
const prompts = [];
|
|
88
|
-
|
|
89
|
-
|
|
167
|
+
const goal = getStringFlag(flags, "goal");
|
|
168
|
+
const generatedOnly = Boolean(flags["generated-only"]);
|
|
169
|
+
const client = await createClientForCommand(command, flags);
|
|
170
|
+
if (goal) {
|
|
171
|
+
prompts.push(await client.generatePrompt({
|
|
172
|
+
goal,
|
|
173
|
+
context: getStringFlag(flags, "context") || "",
|
|
174
|
+
constraints: getStringFlag(flags, "constraints") || "",
|
|
175
|
+
desiredOutput: getStringFlag(flags, "desired-output") || "A reusable prompt pack saved as Markdown.",
|
|
176
|
+
tool: getStringFlag(flags, "tool") || "Codex",
|
|
177
|
+
mode: getStringFlag(flags, "mode") || "implement",
|
|
178
|
+
artifactType: getStringFlag(flags, "artifact-type") || "prompt-file",
|
|
179
|
+
includeWebSearch: Boolean(flags["web-search"]),
|
|
180
|
+
}));
|
|
181
|
+
}
|
|
182
|
+
if (!generatedOnly) {
|
|
183
|
+
prompts.push(...await client.pullPrompts(buildPullQuery(flags, parsedLimit)));
|
|
184
|
+
}
|
|
185
|
+
if (prompts.length === 0) {
|
|
186
|
+
throw new CliError("No prompts to sync. Provide `--goal` or remove `--generated-only`.", CLI_EXIT_CODES.validation, {
|
|
187
|
+
helpCommand: "sync",
|
|
188
|
+
});
|
|
90
189
|
}
|
|
91
|
-
if (
|
|
92
|
-
|
|
190
|
+
if (Boolean(flags["dry-run"])) {
|
|
191
|
+
console.log(`[dry-run] Would sync ${prompts.length} prompt(s) for agent target: ${getStringFlag(flags, "agent") || "all"}.`);
|
|
192
|
+
for (const p of prompts)
|
|
193
|
+
console.log(` - ${p.title} (${p.source})`);
|
|
194
|
+
return;
|
|
93
195
|
}
|
|
94
|
-
if (prompts.length === 0)
|
|
95
|
-
throw new Error("No prompts to sync. Provide --goal or remove --generated-only.");
|
|
96
196
|
const result = await syncPrompts(prompts, {
|
|
97
|
-
cwd,
|
|
98
|
-
outDir: flags
|
|
197
|
+
cwd: getResolvedCwd(flags),
|
|
198
|
+
outDir: getStringFlag(flags, "out") || DEFAULT_PROMPTS_GPT_OUT_DIR,
|
|
99
199
|
overwrite: Boolean(flags.overwrite),
|
|
100
|
-
agent: flags
|
|
200
|
+
agent: getStringFlag(flags, "agent") || "all",
|
|
101
201
|
});
|
|
102
202
|
console.log(`Synced ${result.markdown.written.length} Markdown prompt file(s) to ${result.markdown.outDir}.`);
|
|
103
203
|
console.log(`Synced ${result.agents.written.length} agent integration file(s): ${result.agents.targets.join(", ")}.`);
|
|
104
204
|
console.log(`Updated manifest: ${result.manifest.manifestPath}`);
|
|
105
|
-
if (result.markdown.skipped.length)
|
|
205
|
+
if (result.markdown.skipped.length) {
|
|
106
206
|
console.log(`Skipped ${result.markdown.skipped.length} existing Markdown file(s). Use --overwrite to replace them.`);
|
|
207
|
+
}
|
|
107
208
|
return;
|
|
108
209
|
}
|
|
109
210
|
if (command === "install-agents") {
|
|
110
|
-
|
|
211
|
+
validateAgentFlag(getStringFlag(flags, "agent"));
|
|
212
|
+
const parsedLimit = parseLimitFlag(getStringFlag(flags, "limit"));
|
|
213
|
+
const client = await createClientForCommand(command, flags);
|
|
214
|
+
const prompts = await client.pullPrompts(buildPullQuery(flags, parsedLimit));
|
|
215
|
+
if (prompts.length === 0) {
|
|
216
|
+
console.log("No prompts matched the query, so no agent files were written.");
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
if (Boolean(flags["dry-run"])) {
|
|
220
|
+
console.log(`[dry-run] Would install agent files for ${prompts.length} prompt(s), target: ${getStringFlag(flags, "agent") || "all"}.`);
|
|
221
|
+
for (const p of prompts)
|
|
222
|
+
console.log(` - ${p.title}`);
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
111
225
|
const result = await writeAgentFiles(prompts, {
|
|
112
|
-
cwd,
|
|
113
|
-
agent: flags
|
|
226
|
+
cwd: getResolvedCwd(flags),
|
|
227
|
+
agent: getStringFlag(flags, "agent") || "all",
|
|
114
228
|
overwriteAgentFiles: true,
|
|
115
229
|
});
|
|
116
230
|
console.log(`Synced ${result.written.length} agent integration file(s): ${result.targets.join(", ")}.`);
|
|
117
231
|
return;
|
|
118
232
|
}
|
|
119
|
-
|
|
233
|
+
if (command === "project") {
|
|
234
|
+
const client = await createClientForCommand(command, flags);
|
|
235
|
+
const project = await client.getProject();
|
|
236
|
+
console.log(`${project.brandName} (${project.websiteUrl})`);
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
async function createClientForCommand(command, flags) {
|
|
241
|
+
const cwd = getResolvedCwd(flags);
|
|
242
|
+
const explicitToken = await resolveTokenInput(flags, { command });
|
|
243
|
+
const explicitApiUrl = getStringFlag(flags, "api-url");
|
|
244
|
+
const credentialsPath = path.resolve(cwd, DEFAULT_PROMPTS_GPT_OUT_DIR, PROMPTS_GPT_CREDENTIALS_FILE);
|
|
245
|
+
const hasCredentialsFile = existsSync(credentialsPath);
|
|
246
|
+
const credentials = await loadLocalCredentials(cwd);
|
|
247
|
+
if (hasCredentialsFile && !credentials && !explicitToken) {
|
|
248
|
+
throw new CliError(`Could not read local credentials at ${credentialsPath}. Re-run \`prompts-gpt init --token <project-token>\` to replace the file.`, CLI_EXIT_CODES.auth, { helpCommand: command });
|
|
249
|
+
}
|
|
250
|
+
const token = explicitToken || credentials?.token || "";
|
|
251
|
+
if (!token) {
|
|
252
|
+
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 });
|
|
253
|
+
}
|
|
254
|
+
return new PromptsGptClient({
|
|
255
|
+
token,
|
|
256
|
+
apiUrl: explicitApiUrl || credentials?.apiUrl || DEFAULT_PROMPTS_GPT_API_URL,
|
|
257
|
+
fetch,
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
function buildPullQuery(flags, limit) {
|
|
261
|
+
return {
|
|
262
|
+
q: getStringFlag(flags, "query") || getStringFlag(flags, "q"),
|
|
263
|
+
category: getStringFlag(flags, "category"),
|
|
264
|
+
tool: getStringFlag(flags, "tool"),
|
|
265
|
+
outputType: getStringFlag(flags, "output-type"),
|
|
266
|
+
limit,
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
function parseCommandFlags(command, argv) {
|
|
270
|
+
const options = getCommandOptions(command);
|
|
271
|
+
try {
|
|
272
|
+
const result = parseArgs({
|
|
273
|
+
args: argv,
|
|
274
|
+
options,
|
|
275
|
+
allowPositionals: false,
|
|
276
|
+
strict: true,
|
|
277
|
+
});
|
|
278
|
+
const values = result.values;
|
|
279
|
+
validateFlagConflicts(command, values);
|
|
280
|
+
return values;
|
|
281
|
+
}
|
|
282
|
+
catch (error) {
|
|
283
|
+
throw toCliParseError(error, command);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
function handleHelpCommand(argv) {
|
|
287
|
+
try {
|
|
288
|
+
const { positionals, values } = parseArgs({
|
|
289
|
+
args: argv,
|
|
290
|
+
options: { help: { type: "boolean" } },
|
|
291
|
+
allowPositionals: true,
|
|
292
|
+
strict: true,
|
|
293
|
+
});
|
|
294
|
+
if (values.help) {
|
|
295
|
+
printHelp();
|
|
296
|
+
return;
|
|
297
|
+
}
|
|
298
|
+
if (positionals.length > 1) {
|
|
299
|
+
throw new CliError("The `help` command accepts at most one command name.", CLI_EXIT_CODES.usage, {
|
|
300
|
+
helpCommand: "help",
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
if (positionals.length === 0) {
|
|
304
|
+
printHelp();
|
|
305
|
+
return;
|
|
306
|
+
}
|
|
307
|
+
const topic = asCommandName(positionals[0]);
|
|
308
|
+
if (!topic) {
|
|
309
|
+
throw new CliError(`Unknown help topic: ${positionals[0]}.`, CLI_EXIT_CODES.usage, {
|
|
310
|
+
helpCommand: "help",
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
printHelp(topic);
|
|
314
|
+
}
|
|
315
|
+
catch (error) {
|
|
316
|
+
if (error instanceof CliError)
|
|
317
|
+
throw error;
|
|
318
|
+
throw toCliParseError(error, "help");
|
|
319
|
+
}
|
|
120
320
|
}
|
|
121
|
-
function
|
|
321
|
+
function getCommandOptions(command) {
|
|
322
|
+
const common = {
|
|
323
|
+
help: { type: "boolean" },
|
|
324
|
+
token: { type: "string" },
|
|
325
|
+
"token-stdin": { type: "boolean" },
|
|
326
|
+
"token-prompt": { type: "boolean" },
|
|
327
|
+
"api-url": { type: "string" },
|
|
328
|
+
cwd: { type: "string" },
|
|
329
|
+
};
|
|
330
|
+
if (command === "init") {
|
|
331
|
+
return common;
|
|
332
|
+
}
|
|
333
|
+
if (command === "project") {
|
|
334
|
+
return common;
|
|
335
|
+
}
|
|
336
|
+
if (command === "pull") {
|
|
337
|
+
return {
|
|
338
|
+
...common,
|
|
339
|
+
query: { type: "string" },
|
|
340
|
+
q: { type: "string" },
|
|
341
|
+
category: { type: "string" },
|
|
342
|
+
tool: { type: "string" },
|
|
343
|
+
"output-type": { type: "string" },
|
|
344
|
+
limit: { type: "string" },
|
|
345
|
+
out: { type: "string" },
|
|
346
|
+
overwrite: { type: "boolean" },
|
|
347
|
+
};
|
|
348
|
+
}
|
|
349
|
+
if (command === "generate") {
|
|
350
|
+
return {
|
|
351
|
+
...common,
|
|
352
|
+
goal: { type: "string" },
|
|
353
|
+
context: { type: "string" },
|
|
354
|
+
constraints: { type: "string" },
|
|
355
|
+
"desired-output": { type: "string" },
|
|
356
|
+
tool: { type: "string" },
|
|
357
|
+
mode: { type: "string" },
|
|
358
|
+
"artifact-type": { type: "string" },
|
|
359
|
+
"web-search": { type: "boolean" },
|
|
360
|
+
out: { type: "string" },
|
|
361
|
+
overwrite: { type: "boolean" },
|
|
362
|
+
agent: { type: "string" },
|
|
363
|
+
"sync-agents": { type: "boolean" },
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
if (command === "sync") {
|
|
367
|
+
return {
|
|
368
|
+
...common,
|
|
369
|
+
goal: { type: "string" },
|
|
370
|
+
context: { type: "string" },
|
|
371
|
+
constraints: { type: "string" },
|
|
372
|
+
"desired-output": { type: "string" },
|
|
373
|
+
tool: { type: "string" },
|
|
374
|
+
mode: { type: "string" },
|
|
375
|
+
"artifact-type": { type: "string" },
|
|
376
|
+
"web-search": { type: "boolean" },
|
|
377
|
+
query: { type: "string" },
|
|
378
|
+
q: { type: "string" },
|
|
379
|
+
category: { type: "string" },
|
|
380
|
+
"output-type": { type: "string" },
|
|
381
|
+
limit: { type: "string" },
|
|
382
|
+
out: { type: "string" },
|
|
383
|
+
overwrite: { type: "boolean" },
|
|
384
|
+
agent: { type: "string" },
|
|
385
|
+
"generated-only": { type: "boolean" },
|
|
386
|
+
"dry-run": { type: "boolean" },
|
|
387
|
+
};
|
|
388
|
+
}
|
|
122
389
|
return {
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
390
|
+
...common,
|
|
391
|
+
query: { type: "string" },
|
|
392
|
+
q: { type: "string" },
|
|
393
|
+
category: { type: "string" },
|
|
394
|
+
tool: { type: "string" },
|
|
395
|
+
"output-type": { type: "string" },
|
|
396
|
+
limit: { type: "string" },
|
|
397
|
+
agent: { type: "string" },
|
|
398
|
+
"dry-run": { type: "boolean" },
|
|
128
399
|
};
|
|
129
400
|
}
|
|
401
|
+
function normalizeLegacyFlags(argv) {
|
|
402
|
+
const aliases = new Map([
|
|
403
|
+
["agents", "agent"],
|
|
404
|
+
["apiUrl", "api-url"],
|
|
405
|
+
["desiredOutput", "desired-output"],
|
|
406
|
+
["artifactType", "artifact-type"],
|
|
407
|
+
["outputType", "output-type"],
|
|
408
|
+
["webSearch", "web-search"],
|
|
409
|
+
["generatedOnly", "generated-only"],
|
|
410
|
+
["syncAgents", "sync-agents"],
|
|
411
|
+
["tokenStdin", "token-stdin"],
|
|
412
|
+
["tokenPrompt", "token-prompt"],
|
|
413
|
+
["dryRun", "dry-run"],
|
|
414
|
+
]);
|
|
415
|
+
return argv.map((arg) => {
|
|
416
|
+
if (!arg.startsWith("--"))
|
|
417
|
+
return arg;
|
|
418
|
+
const eqIndex = arg.indexOf("=");
|
|
419
|
+
const rawKey = eqIndex === -1 ? arg.slice(2) : arg.slice(2, eqIndex);
|
|
420
|
+
const mappedKey = aliases.get(rawKey) ?? rawKey;
|
|
421
|
+
return eqIndex === -1 ? `--${mappedKey}` : `--${mappedKey}=${arg.slice(eqIndex + 1)}`;
|
|
422
|
+
});
|
|
423
|
+
}
|
|
424
|
+
function toCliParseError(error, command) {
|
|
425
|
+
const message = normalizeParseErrorMessage(error instanceof Error ? error.message : String(error));
|
|
426
|
+
return new CliError(message, CLI_EXIT_CODES.usage, {
|
|
427
|
+
helpCommand: command,
|
|
428
|
+
});
|
|
429
|
+
}
|
|
430
|
+
function normalizeParseErrorMessage(message) {
|
|
431
|
+
const trimmed = message.trim();
|
|
432
|
+
if (trimmed.startsWith("Unknown option")) {
|
|
433
|
+
return `${trimmed}.`;
|
|
434
|
+
}
|
|
435
|
+
return trimmed;
|
|
436
|
+
}
|
|
437
|
+
function validateFlagConflicts(command, flags) {
|
|
438
|
+
const tokenSourceCount = [Boolean(flags.token), Boolean(flags["token-stdin"]), Boolean(flags["token-prompt"])].filter(Boolean).length;
|
|
439
|
+
if (tokenSourceCount > 1) {
|
|
440
|
+
throw new CliError("Use only one token source: `--token`, `--token-stdin`, or `--token-prompt`.", CLI_EXIT_CODES.usage, {
|
|
441
|
+
helpCommand: command,
|
|
442
|
+
});
|
|
443
|
+
}
|
|
444
|
+
if (flags.query && flags.q) {
|
|
445
|
+
throw new CliError("Use either `--query` or `--q`, not both.", CLI_EXIT_CODES.usage, {
|
|
446
|
+
helpCommand: command,
|
|
447
|
+
});
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
async function resolveTokenInput(flags, options) {
|
|
451
|
+
const explicitToken = getStringFlag(flags, "token")?.trim();
|
|
452
|
+
if (explicitToken) {
|
|
453
|
+
return explicitToken;
|
|
454
|
+
}
|
|
455
|
+
if (flags["token-stdin"]) {
|
|
456
|
+
const token = await readTokenFromStdin();
|
|
457
|
+
if (!token) {
|
|
458
|
+
throw new CliError("No token was received on stdin. Pipe a project token into `--token-stdin`.", CLI_EXIT_CODES.validation, {
|
|
459
|
+
helpCommand: options.command,
|
|
460
|
+
});
|
|
461
|
+
}
|
|
462
|
+
return token;
|
|
463
|
+
}
|
|
464
|
+
if (flags["token-prompt"]) {
|
|
465
|
+
return readTokenFromPrompt(options.command);
|
|
466
|
+
}
|
|
467
|
+
return undefined;
|
|
468
|
+
}
|
|
469
|
+
async function readTokenFromStdin() {
|
|
470
|
+
if (process.stdin.isTTY) {
|
|
471
|
+
throw new CliError("`--token-stdin` expects piped input. Use `--token-prompt` for an interactive terminal.", CLI_EXIT_CODES.usage);
|
|
472
|
+
}
|
|
473
|
+
const chunks = [];
|
|
474
|
+
let totalLength = 0;
|
|
475
|
+
for await (const chunk of process.stdin) {
|
|
476
|
+
const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk));
|
|
477
|
+
totalLength += buffer.length;
|
|
478
|
+
if (totalLength > MAX_STDIN_TOKEN_LENGTH) {
|
|
479
|
+
throw new CliError("Token input from stdin is too long.", CLI_EXIT_CODES.validation);
|
|
480
|
+
}
|
|
481
|
+
chunks.push(buffer);
|
|
482
|
+
}
|
|
483
|
+
return Buffer.concat(chunks).toString("utf8").trim();
|
|
484
|
+
}
|
|
485
|
+
function readTokenFromPrompt(command) {
|
|
486
|
+
if (!process.stdin.isTTY || !process.stdout.isTTY) {
|
|
487
|
+
throw new CliError("`--token-prompt` requires an interactive terminal. Use `--token-stdin` for CI or piped input.", CLI_EXIT_CODES.usage, {
|
|
488
|
+
helpCommand: command,
|
|
489
|
+
});
|
|
490
|
+
}
|
|
491
|
+
return new Promise((resolve, reject) => {
|
|
492
|
+
const stdin = process.stdin;
|
|
493
|
+
const stdout = process.stdout;
|
|
494
|
+
let token = "";
|
|
495
|
+
const cleanup = () => {
|
|
496
|
+
stdin.removeListener("data", onData);
|
|
497
|
+
stdin.setRawMode?.(false);
|
|
498
|
+
stdin.pause();
|
|
499
|
+
};
|
|
500
|
+
const finish = (callback) => {
|
|
501
|
+
stdout.write("\n");
|
|
502
|
+
cleanup();
|
|
503
|
+
callback();
|
|
504
|
+
};
|
|
505
|
+
const onData = (chunk) => {
|
|
506
|
+
const value = typeof chunk === "string" ? chunk : chunk.toString("utf8");
|
|
507
|
+
for (const char of value) {
|
|
508
|
+
if (char === "\u0003") {
|
|
509
|
+
finish(() => reject(new CliError("Token entry cancelled.", CLI_EXIT_CODES.general, { helpCommand: command })));
|
|
510
|
+
return;
|
|
511
|
+
}
|
|
512
|
+
if (char === "\r" || char === "\n") {
|
|
513
|
+
const trimmed = token.trim();
|
|
514
|
+
if (!trimmed) {
|
|
515
|
+
finish(() => reject(new CliError("Project token is required.", CLI_EXIT_CODES.validation, { helpCommand: command })));
|
|
516
|
+
return;
|
|
517
|
+
}
|
|
518
|
+
finish(() => resolve(trimmed));
|
|
519
|
+
return;
|
|
520
|
+
}
|
|
521
|
+
if (char === "\u007f" || char === "\b") {
|
|
522
|
+
token = token.slice(0, -1);
|
|
523
|
+
continue;
|
|
524
|
+
}
|
|
525
|
+
if (char >= " ") {
|
|
526
|
+
token += char;
|
|
527
|
+
if (token.length > MAX_STDIN_TOKEN_LENGTH) {
|
|
528
|
+
finish(() => reject(new CliError("Token input is too long.", CLI_EXIT_CODES.validation, { helpCommand: command })));
|
|
529
|
+
return;
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
};
|
|
534
|
+
stdout.write("Project token: ");
|
|
535
|
+
stdin.setEncoding("utf8");
|
|
536
|
+
stdin.setRawMode?.(true);
|
|
537
|
+
stdin.resume();
|
|
538
|
+
stdin.on("data", onData);
|
|
539
|
+
});
|
|
540
|
+
}
|
|
541
|
+
function parseLimitFlag(raw) {
|
|
542
|
+
if (raw === undefined)
|
|
543
|
+
return undefined;
|
|
544
|
+
if (!/^\d+$/.test(raw)) {
|
|
545
|
+
throw new CliError("`--limit` must be a positive integer.", CLI_EXIT_CODES.validation);
|
|
546
|
+
}
|
|
547
|
+
const value = Number.parseInt(raw, 10);
|
|
548
|
+
if (!Number.isSafeInteger(value) || value < 1) {
|
|
549
|
+
throw new CliError("`--limit` must be a positive integer.", CLI_EXIT_CODES.validation);
|
|
550
|
+
}
|
|
551
|
+
return value;
|
|
552
|
+
}
|
|
130
553
|
function validateToolFlag(tool) {
|
|
131
554
|
if (!tool)
|
|
132
555
|
return;
|
|
133
556
|
const validSet = new Set(VALID_TOOLS);
|
|
134
557
|
if (!validSet.has(tool)) {
|
|
135
|
-
throw new
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
async function generatePromptFromFlags(client, flags) {
|
|
139
|
-
const goal = flags.goal;
|
|
140
|
-
if (!goal)
|
|
141
|
-
throw new Error("Prompt generation requires --goal.");
|
|
142
|
-
return client.generatePrompt({
|
|
143
|
-
goal,
|
|
144
|
-
context: flags.context || "",
|
|
145
|
-
constraints: flags.constraints || "",
|
|
146
|
-
desiredOutput: flags.desiredOutput || "A reusable prompt pack saved as Markdown.",
|
|
147
|
-
tool: flags.tool || "Codex",
|
|
148
|
-
mode: flags.mode || "implement",
|
|
149
|
-
artifactType: flags.artifactType || "prompt-file",
|
|
150
|
-
includeWebSearch: Boolean(flags.webSearch),
|
|
151
|
-
});
|
|
558
|
+
throw new CliError(`Invalid --tool "${tool}". Valid tools: ${VALID_TOOLS.join(", ")}.`, CLI_EXIT_CODES.validation);
|
|
559
|
+
}
|
|
152
560
|
}
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
if (eqIndex !== -1) {
|
|
162
|
-
const key = normalizeFlag(arg.slice(2, eqIndex));
|
|
163
|
-
if (!key || key.length > 64)
|
|
164
|
-
continue;
|
|
165
|
-
flags[key] = arg.slice(eqIndex + 1).slice(0, MAX_FLAG_VALUE_LENGTH);
|
|
166
|
-
continue;
|
|
167
|
-
}
|
|
168
|
-
const key = normalizeFlag(arg.slice(2));
|
|
169
|
-
if (!key || key.length > 64)
|
|
170
|
-
continue;
|
|
171
|
-
const next = args[index + 1];
|
|
172
|
-
if (!next || next.startsWith("--")) {
|
|
173
|
-
flags[key] = true;
|
|
174
|
-
}
|
|
175
|
-
else {
|
|
176
|
-
flags[key] = String(next).slice(0, MAX_FLAG_VALUE_LENGTH);
|
|
177
|
-
index += 1;
|
|
178
|
-
}
|
|
561
|
+
function validateAgentFlag(agent) {
|
|
562
|
+
if (!agent)
|
|
563
|
+
return;
|
|
564
|
+
const targets = agent.split(",").map((item) => item.trim().toLowerCase()).filter(Boolean);
|
|
565
|
+
const validSet = new Set([...SUPPORTED_AGENT_TARGETS, "all"]);
|
|
566
|
+
const invalid = [...new Set(targets.filter((target) => !validSet.has(target)))];
|
|
567
|
+
if (invalid.length) {
|
|
568
|
+
throw new CliError(`Invalid --agent target: ${invalid.join(", ")}. Use ${SUPPORTED_AGENT_TARGETS.join(", ")}, or all.`, CLI_EXIT_CODES.validation);
|
|
179
569
|
}
|
|
180
|
-
return flags;
|
|
181
570
|
}
|
|
182
|
-
function
|
|
183
|
-
return
|
|
571
|
+
function getResolvedCwd(flags) {
|
|
572
|
+
return path.resolve(getStringFlag(flags, "cwd") || process.cwd());
|
|
573
|
+
}
|
|
574
|
+
function getStringFlag(flags, name) {
|
|
575
|
+
const value = flags[name];
|
|
576
|
+
return typeof value === "string" ? value : undefined;
|
|
577
|
+
}
|
|
578
|
+
function asCommandName(value) {
|
|
579
|
+
if (!value)
|
|
580
|
+
return undefined;
|
|
581
|
+
return COMMANDS.find((command) => command === value);
|
|
582
|
+
}
|
|
583
|
+
function isRunnableCommand(command) {
|
|
584
|
+
return command !== "help" && command !== "version";
|
|
585
|
+
}
|
|
586
|
+
async function printVersion() {
|
|
587
|
+
const version = await getCliVersion();
|
|
588
|
+
console.log(`@prompts-gpt/client v${version}`);
|
|
184
589
|
}
|
|
185
590
|
async function getCliVersion() {
|
|
186
591
|
try {
|
|
@@ -192,47 +597,246 @@ async function getCliVersion() {
|
|
|
192
597
|
return "0.0.0";
|
|
193
598
|
}
|
|
194
599
|
}
|
|
195
|
-
function printHelp() {
|
|
600
|
+
function printHelp(command) {
|
|
601
|
+
if (command) {
|
|
602
|
+
console.log(getCommandHelp(command));
|
|
603
|
+
return;
|
|
604
|
+
}
|
|
196
605
|
console.log(`Prompts-GPT CLI
|
|
197
606
|
|
|
198
|
-
|
|
199
|
-
prompts-gpt
|
|
607
|
+
Usage:
|
|
608
|
+
prompts-gpt <command> [options]
|
|
609
|
+
prompts-gpt help [command]
|
|
200
610
|
prompts-gpt version
|
|
201
|
-
prompts-gpt project
|
|
202
|
-
prompts-gpt pull [--query "repo audit"] [--category coding] [--tool Codex] [--limit 25] [--out .prompts-gpt] [--overwrite]
|
|
203
|
-
prompts-gpt generate --goal "Review this diff" [--context "Next.js app"] [--agent codex,cursor,vscode]
|
|
204
|
-
prompts-gpt sync [--goal "Review this diff"] [--limit 25] [--agent all] [--out .prompts-gpt] [--cwd /path/to/repo]
|
|
205
|
-
prompts-gpt install-agents [--agent codex,cursor,vscode,copilot]
|
|
206
611
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
612
|
+
Commands:
|
|
613
|
+
init Save a project token in .prompts-gpt/.credentials.json
|
|
614
|
+
project Show the current project linked to the token
|
|
615
|
+
pull Download prompt packs as Markdown files
|
|
616
|
+
generate Generate one prompt pack from a goal
|
|
617
|
+
sync Generate and/or pull prompt packs, then sync agent files
|
|
618
|
+
install-agents Refresh agent-specific instruction files from pulled prompts
|
|
619
|
+
version Show the current CLI version
|
|
620
|
+
help Show global or command-specific help
|
|
621
|
+
|
|
622
|
+
Global options:
|
|
623
|
+
--help Show help
|
|
624
|
+
--version Show the current CLI version
|
|
220
625
|
|
|
221
626
|
Supported tools: ${VALID_TOOLS.join(", ")}
|
|
222
627
|
Supported agent targets: ${SUPPORTED_AGENT_TARGETS.join(", ")}
|
|
223
628
|
`);
|
|
224
629
|
}
|
|
630
|
+
function getCommandHelp(command) {
|
|
631
|
+
if (command === "init") {
|
|
632
|
+
return `prompts-gpt init
|
|
633
|
+
|
|
634
|
+
Usage:
|
|
635
|
+
prompts-gpt init (--token <project-token> | --token-stdin | --token-prompt) [--api-url <url>] [--cwd <path>]
|
|
636
|
+
|
|
637
|
+
Why use it:
|
|
638
|
+
Stores a project token in a local credentials file so day-one CLI usage does not require re-pasting secrets on every command.
|
|
639
|
+
|
|
640
|
+
Options:
|
|
641
|
+
--token <token> Project API token. Must start with pgpt_.
|
|
642
|
+
--token-stdin Read the project token from stdin so it does not end up in shell history.
|
|
643
|
+
--token-prompt Prompt for the project token without echoing it.
|
|
644
|
+
--api-url <url> Custom API base URL for self-hosted instances.
|
|
645
|
+
--cwd <path> Target project directory that will receive .prompts-gpt/.credentials.json.
|
|
646
|
+
--help Show this command help.
|
|
647
|
+
`;
|
|
648
|
+
}
|
|
649
|
+
if (command === "project") {
|
|
650
|
+
return `prompts-gpt project
|
|
651
|
+
|
|
652
|
+
Usage:
|
|
653
|
+
prompts-gpt project [--token <project-token> | --token-stdin | --token-prompt] [--api-url <url>] [--cwd <path>]
|
|
654
|
+
|
|
655
|
+
Why use it:
|
|
656
|
+
Verifies that the current local token resolves to the expected Prompts-GPT project before syncing files.
|
|
657
|
+
|
|
658
|
+
Options:
|
|
659
|
+
--token <token> Override the saved local token for this command only.
|
|
660
|
+
--token-stdin Read the override token from stdin for this command only.
|
|
661
|
+
--token-prompt Prompt for the override token without echoing it.
|
|
662
|
+
--api-url <url> Override the saved API base URL for this command only.
|
|
663
|
+
--cwd <path> Project directory to inspect for local credentials.
|
|
664
|
+
--help Show this command help.
|
|
665
|
+
`;
|
|
666
|
+
}
|
|
667
|
+
if (command === "pull") {
|
|
668
|
+
return `prompts-gpt pull
|
|
669
|
+
|
|
670
|
+
Usage:
|
|
671
|
+
prompts-gpt pull [--query <text> | --q <text>] [--category <name>] [--tool <name>] [--output-type <name>] [--limit <n>] [--out <dir>] [--overwrite] [--token <project-token> | --token-stdin | --token-prompt] [--api-url <url>] [--cwd <path>]
|
|
672
|
+
|
|
673
|
+
Why use it:
|
|
674
|
+
Pulls prompt packs into local Markdown files so teams can review and use the same prompt assets inside their repository.
|
|
675
|
+
|
|
676
|
+
Options:
|
|
677
|
+
--query <text> Search query for the project prompt library.
|
|
678
|
+
--q <text> Short alias for --query.
|
|
679
|
+
--category <name> Filter prompts by category.
|
|
680
|
+
--tool <name> Filter prompts by supported tool.
|
|
681
|
+
--output-type <name> Filter prompts by output type.
|
|
682
|
+
--limit <n> Positive integer limit for returned prompts.
|
|
683
|
+
--out <dir> Output directory inside the current project. Default: .prompts-gpt
|
|
684
|
+
--overwrite Replace existing Markdown files instead of skipping them.
|
|
685
|
+
--token <token> Override the saved local token for this command only.
|
|
686
|
+
--token-stdin Read the override token from stdin for this command only.
|
|
687
|
+
--token-prompt Prompt for the override token without echoing it.
|
|
688
|
+
--api-url <url> Override the saved API base URL for this command only.
|
|
689
|
+
--cwd <path> Project directory to inspect for local credentials and output files.
|
|
690
|
+
--help Show this command help.
|
|
691
|
+
`;
|
|
692
|
+
}
|
|
693
|
+
if (command === "generate") {
|
|
694
|
+
return `prompts-gpt generate
|
|
695
|
+
|
|
696
|
+
Usage:
|
|
697
|
+
prompts-gpt generate --goal <text> [--context <text>] [--constraints <text>] [--desired-output <text>] [--tool <name>] [--mode <name>] [--artifact-type <name>] [--web-search] [--out <dir>] [--overwrite] [--agent <targets>] [--sync-agents] [--token <project-token> | --token-stdin | --token-prompt] [--api-url <url>] [--cwd <path>]
|
|
698
|
+
|
|
699
|
+
Why use it:
|
|
700
|
+
Creates a new reusable prompt pack from a concrete developer goal, then optionally installs agent-readable files immediately.
|
|
701
|
+
|
|
702
|
+
Options:
|
|
703
|
+
--goal <text> Required. The task to generate a prompt pack for.
|
|
704
|
+
--context <text> Extra project or stack context for the generator.
|
|
705
|
+
--constraints <text> Constraints that the generated prompt must honor.
|
|
706
|
+
--desired-output <text> Preferred output shape for the generated prompt pack.
|
|
707
|
+
--tool <name> Target tool. Default: Codex
|
|
708
|
+
--mode <name> Prompt generation mode. Default: implement
|
|
709
|
+
--artifact-type <name> Artifact type. Default: prompt-file
|
|
710
|
+
--web-search Allow server-side web research when generating the prompt.
|
|
711
|
+
--out <dir> Output directory inside the current project. Default: .prompts-gpt
|
|
712
|
+
--overwrite Replace an existing generated Markdown file.
|
|
713
|
+
--agent <targets> Sync agent files for specific targets after generation.
|
|
714
|
+
--sync-agents Sync all agent files after generation.
|
|
715
|
+
--token <token> Override the saved local token for this command only.
|
|
716
|
+
--token-stdin Read the override token from stdin for this command only.
|
|
717
|
+
--token-prompt Prompt for the override token without echoing it.
|
|
718
|
+
--api-url <url> Override the saved API base URL for this command only.
|
|
719
|
+
--cwd <path> Project directory to inspect for local credentials and output files.
|
|
720
|
+
--help Show this command help.
|
|
721
|
+
`;
|
|
722
|
+
}
|
|
723
|
+
if (command === "sync") {
|
|
724
|
+
return `prompts-gpt sync
|
|
725
|
+
|
|
726
|
+
Usage:
|
|
727
|
+
prompts-gpt sync [--goal <text>] [--generated-only] [--query <text> | --q <text>] [--category <name>] [--tool <name>] [--output-type <name>] [--limit <n>] [--context <text>] [--constraints <text>] [--desired-output <text>] [--mode <name>] [--artifact-type <name>] [--web-search] [--agent <targets>] [--out <dir>] [--overwrite] [--dry-run] [--token <project-token> | --token-stdin | --token-prompt] [--api-url <url>] [--cwd <path>]
|
|
728
|
+
|
|
729
|
+
Why use it:
|
|
730
|
+
Gives teams a one-command path to refresh Markdown prompts, agent files, and the local manifest from the same source of truth.
|
|
731
|
+
|
|
732
|
+
Options:
|
|
733
|
+
--goal <text> Generate one prompt pack before syncing.
|
|
734
|
+
--generated-only Skip library pull and sync only the generated prompt pack from --goal.
|
|
735
|
+
--query <text> Search query for pulled prompt packs.
|
|
736
|
+
--q <text> Short alias for --query.
|
|
737
|
+
--category <name> Filter pulled prompt packs by category.
|
|
738
|
+
--tool <name> Filter pulled prompt packs and generated output by tool.
|
|
739
|
+
--output-type <name> Filter pulled prompt packs by output type.
|
|
740
|
+
--limit <n> Positive integer limit for pulled prompt packs.
|
|
741
|
+
--context <text> Extra project or stack context for generated prompt packs.
|
|
742
|
+
--constraints <text> Constraints for generated prompt packs.
|
|
743
|
+
--desired-output <text> Preferred output shape for generated prompt packs.
|
|
744
|
+
--mode <name> Prompt generation mode. Default: implement
|
|
745
|
+
--artifact-type <name> Artifact type. Default: prompt-file
|
|
746
|
+
--web-search Allow server-side web research when generating a prompt pack.
|
|
747
|
+
--agent <targets> Comma-separated agent targets. Default: all
|
|
748
|
+
--out <dir> Output directory inside the current project. Default: .prompts-gpt
|
|
749
|
+
--overwrite Replace existing Markdown files instead of skipping them.
|
|
750
|
+
--dry-run Preview what would be synced without writing any files.
|
|
751
|
+
--token <token> Override the saved local token for this command only.
|
|
752
|
+
--token-stdin Read the override token from stdin for this command only.
|
|
753
|
+
--token-prompt Prompt for the override token without echoing it.
|
|
754
|
+
--api-url <url> Override the saved API base URL for this command only.
|
|
755
|
+
--cwd <path> Project directory to inspect for local credentials and output files.
|
|
756
|
+
--help Show this command help.
|
|
757
|
+
`;
|
|
758
|
+
}
|
|
759
|
+
if (command === "install-agents") {
|
|
760
|
+
return `prompts-gpt install-agents
|
|
761
|
+
|
|
762
|
+
Usage:
|
|
763
|
+
prompts-gpt install-agents [--query <text> | --q <text>] [--category <name>] [--tool <name>] [--output-type <name>] [--limit <n>] [--agent <targets>] [--dry-run] [--token <project-token> | --token-stdin | --token-prompt] [--api-url <url>] [--cwd <path>]
|
|
764
|
+
|
|
765
|
+
Why use it:
|
|
766
|
+
Refreshes agent-specific instruction files from the current prompt library without rewriting the Markdown prompt directory.
|
|
767
|
+
|
|
768
|
+
Options:
|
|
769
|
+
--query <text> Search query for the project prompt library.
|
|
770
|
+
--q <text> Short alias for --query.
|
|
771
|
+
--category <name> Filter prompts by category.
|
|
772
|
+
--tool <name> Filter prompts by supported tool.
|
|
773
|
+
--output-type <name> Filter prompts by output type.
|
|
774
|
+
--limit <n> Positive integer limit for returned prompts.
|
|
775
|
+
--agent <targets> Comma-separated agent targets. Default: all
|
|
776
|
+
--dry-run Preview what would be installed without writing any files.
|
|
777
|
+
--token <token> Override the saved local token for this command only.
|
|
778
|
+
--token-stdin Read the override token from stdin for this command only.
|
|
779
|
+
--token-prompt Prompt for the override token without echoing it.
|
|
780
|
+
--api-url <url> Override the saved API base URL for this command only.
|
|
781
|
+
--cwd <path> Project directory to inspect for local credentials and agent files.
|
|
782
|
+
--help Show this command help.
|
|
783
|
+
`;
|
|
784
|
+
}
|
|
785
|
+
if (command === "version") {
|
|
786
|
+
return `prompts-gpt version
|
|
787
|
+
|
|
788
|
+
Usage:
|
|
789
|
+
prompts-gpt version
|
|
790
|
+
|
|
791
|
+
Why use it:
|
|
792
|
+
Confirms the installed CLI version when debugging package resolution or publish issues.
|
|
793
|
+
`;
|
|
794
|
+
}
|
|
795
|
+
return `prompts-gpt help
|
|
796
|
+
|
|
797
|
+
Usage:
|
|
798
|
+
prompts-gpt help [command]
|
|
799
|
+
|
|
800
|
+
Why use it:
|
|
801
|
+
Shows focused usage for the exact command you are trying to run so shell users do not have to scan the full command list.
|
|
802
|
+
`;
|
|
803
|
+
}
|
|
225
804
|
main().catch((error) => {
|
|
805
|
+
if (error instanceof CliError) {
|
|
806
|
+
console.error(error.message);
|
|
807
|
+
if (error.helpCommand) {
|
|
808
|
+
console.error(`Run \`prompts-gpt help${error.helpCommand ? ` ${error.helpCommand}` : ""}\` for usage.`);
|
|
809
|
+
}
|
|
810
|
+
process.exitCode = error.exitCode;
|
|
811
|
+
return;
|
|
812
|
+
}
|
|
226
813
|
if (error instanceof PromptsGptApiError) {
|
|
227
|
-
console.error(
|
|
814
|
+
console.error(formatApiError(error));
|
|
228
815
|
process.exitCode = error.status === 401 || error.status === 403
|
|
229
816
|
? CLI_EXIT_CODES.auth
|
|
230
|
-
: error.
|
|
231
|
-
? CLI_EXIT_CODES.
|
|
232
|
-
:
|
|
817
|
+
: error.status === 429
|
|
818
|
+
? CLI_EXIT_CODES.rateLimit
|
|
819
|
+
: error.code === "VALIDATION_ERROR"
|
|
820
|
+
? CLI_EXIT_CODES.validation
|
|
821
|
+
: CLI_EXIT_CODES.general;
|
|
233
822
|
return;
|
|
234
823
|
}
|
|
235
824
|
console.error(error instanceof Error ? error.message : String(error));
|
|
236
825
|
process.exitCode = CLI_EXIT_CODES.general;
|
|
237
826
|
});
|
|
827
|
+
function formatApiError(error) {
|
|
828
|
+
const lines = [error.message];
|
|
829
|
+
for (const [field, messages] of Object.entries(error.fieldErrors ?? {})) {
|
|
830
|
+
for (const message of messages ?? []) {
|
|
831
|
+
lines.push(`- ${field}: ${message}`);
|
|
832
|
+
}
|
|
833
|
+
}
|
|
834
|
+
if (error.requestId) {
|
|
835
|
+
lines.push(`Request ID: ${error.requestId}`);
|
|
836
|
+
}
|
|
837
|
+
if (error.recovery) {
|
|
838
|
+
lines.push(error.recovery);
|
|
839
|
+
}
|
|
840
|
+
return lines.join("\n");
|
|
841
|
+
}
|
|
238
842
|
//# sourceMappingURL=cli.js.map
|