@prompts-gpt/client 0.1.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 +95 -0
- package/README.md +244 -69
- package/dist/cli.js +742 -130
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +67 -25
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +508 -102
- package/dist/index.js.map +1 -1
- package/package.json +21 -15
package/dist/cli.js
CHANGED
|
@@ -1,178 +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
|
-
|
|
28
|
+
const argv = process.argv.slice(2);
|
|
29
|
+
if (argv.length === 0) {
|
|
30
|
+
printHelp();
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
const normalizedArgv = normalizeLegacyFlags(argv);
|
|
34
|
+
const first = normalizedArgv[0];
|
|
35
|
+
if (first === "--help") {
|
|
9
36
|
printHelp();
|
|
10
37
|
return;
|
|
11
38
|
}
|
|
12
|
-
if (
|
|
13
|
-
|
|
14
|
-
|
|
39
|
+
if (first === "--version") {
|
|
40
|
+
await printVersion();
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
if (first === "help") {
|
|
44
|
+
handleHelpCommand(normalizedArgv.slice(1));
|
|
45
|
+
return;
|
|
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);
|
|
15
68
|
return;
|
|
16
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
|
-
|
|
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);
|
|
23
91
|
const result = await saveLocalCredentials({
|
|
24
92
|
token,
|
|
25
|
-
apiUrl: flags
|
|
26
|
-
cwd
|
|
93
|
+
apiUrl: getStringFlag(flags, "api-url") || DEFAULT_PROMPTS_GPT_API_URL,
|
|
94
|
+
cwd,
|
|
27
95
|
});
|
|
28
96
|
console.log(`Saved Prompts-GPT credentials to ${result.credentialsPath}`);
|
|
29
97
|
console.log("The credentials file is added to .gitignore.");
|
|
30
98
|
return;
|
|
31
99
|
}
|
|
32
|
-
const cwd = flags.cwd || process.cwd();
|
|
33
|
-
const credentials = await loadLocalCredentials(cwd);
|
|
34
|
-
const client = new PromptsGptClient({
|
|
35
|
-
token: flags.token || credentials?.token || process.env.PROMPTS_GPT_TOKEN,
|
|
36
|
-
apiUrl: flags.apiUrl || credentials?.apiUrl || DEFAULT_PROMPTS_GPT_API_URL,
|
|
37
|
-
});
|
|
38
|
-
if (command === "project") {
|
|
39
|
-
const project = await client.getProject();
|
|
40
|
-
console.log(`${project.brandName} (${project.websiteUrl})`);
|
|
41
|
-
return;
|
|
42
|
-
}
|
|
43
100
|
if (command === "pull") {
|
|
44
|
-
const
|
|
101
|
+
const parsedLimit = parseLimitFlag(getStringFlag(flags, "limit"));
|
|
102
|
+
const client = await createClientForCommand(command, flags);
|
|
103
|
+
const prompts = await client.pullPrompts(buildPullQuery(flags, parsedLimit));
|
|
104
|
+
if (prompts.length === 0) {
|
|
105
|
+
console.log("No prompts matched the query. Try different filters or check the project prompt library.");
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
45
108
|
const result = await writePromptMarkdownFiles(prompts, {
|
|
46
|
-
cwd,
|
|
47
|
-
outDir: flags
|
|
109
|
+
cwd: getResolvedCwd(flags),
|
|
110
|
+
outDir: getStringFlag(flags, "out") || DEFAULT_PROMPTS_GPT_OUT_DIR,
|
|
48
111
|
overwrite: Boolean(flags.overwrite),
|
|
49
112
|
});
|
|
50
113
|
console.log(`Wrote ${result.written.length} prompt file(s) to ${result.outDir}.`);
|
|
51
|
-
if (result.skipped.length)
|
|
114
|
+
if (result.skipped.length) {
|
|
52
115
|
console.log(`Skipped ${result.skipped.length} existing file(s). Use --overwrite to replace them.`);
|
|
116
|
+
}
|
|
53
117
|
return;
|
|
54
118
|
}
|
|
55
119
|
if (command === "generate") {
|
|
56
|
-
validateToolFlag(flags
|
|
57
|
-
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);
|
|
58
140
|
const result = await writePromptMarkdownFiles([prompt], {
|
|
59
141
|
cwd,
|
|
60
|
-
outDir: flags
|
|
142
|
+
outDir: getStringFlag(flags, "out") || DEFAULT_PROMPTS_GPT_OUT_DIR,
|
|
61
143
|
overwrite: Boolean(flags.overwrite),
|
|
62
144
|
});
|
|
63
|
-
const
|
|
64
|
-
if (
|
|
145
|
+
const shouldSyncAgents = Boolean(flags["sync-agents"]) || typeof getStringFlag(flags, "agent") === "string";
|
|
146
|
+
if (shouldSyncAgents) {
|
|
147
|
+
const target = getStringFlag(flags, "agent") || "all";
|
|
65
148
|
const agentResult = await writeAgentFiles([prompt], {
|
|
66
149
|
cwd,
|
|
67
|
-
agent:
|
|
150
|
+
agent: target,
|
|
68
151
|
overwriteAgentFiles: true,
|
|
69
152
|
});
|
|
70
153
|
console.log(`Synced ${agentResult.written.length} agent file(s) for ${agentResult.targets.join(", ")}.`);
|
|
71
154
|
}
|
|
72
|
-
console.log(`
|
|
73
|
-
|
|
155
|
+
console.log(`Generated: ${prompt.title}`);
|
|
156
|
+
console.log(`Wrote to ${result.written[0] ?? result.outDir}.`);
|
|
157
|
+
if (result.skipped.length) {
|
|
74
158
|
console.log("Skipped existing generated prompt. Use --overwrite to replace it.");
|
|
159
|
+
}
|
|
75
160
|
return;
|
|
76
161
|
}
|
|
77
162
|
if (command === "sync") {
|
|
78
|
-
validateToolFlag(flags
|
|
163
|
+
validateToolFlag(getStringFlag(flags, "tool"));
|
|
164
|
+
validateAgentFlag(getStringFlag(flags, "agent"));
|
|
165
|
+
const parsedLimit = parseLimitFlag(getStringFlag(flags, "limit"));
|
|
79
166
|
const prompts = [];
|
|
80
|
-
|
|
81
|
-
|
|
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)));
|
|
82
184
|
}
|
|
83
|
-
if (
|
|
84
|
-
prompts.
|
|
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
|
+
});
|
|
189
|
+
}
|
|
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;
|
|
85
195
|
}
|
|
86
|
-
if (prompts.length === 0)
|
|
87
|
-
throw new Error("No prompts to sync. Provide --goal or remove --generated-only.");
|
|
88
196
|
const result = await syncPrompts(prompts, {
|
|
89
|
-
cwd,
|
|
90
|
-
outDir: flags
|
|
197
|
+
cwd: getResolvedCwd(flags),
|
|
198
|
+
outDir: getStringFlag(flags, "out") || DEFAULT_PROMPTS_GPT_OUT_DIR,
|
|
91
199
|
overwrite: Boolean(flags.overwrite),
|
|
92
|
-
agent: flags
|
|
200
|
+
agent: getStringFlag(flags, "agent") || "all",
|
|
93
201
|
});
|
|
94
202
|
console.log(`Synced ${result.markdown.written.length} Markdown prompt file(s) to ${result.markdown.outDir}.`);
|
|
95
203
|
console.log(`Synced ${result.agents.written.length} agent integration file(s): ${result.agents.targets.join(", ")}.`);
|
|
96
204
|
console.log(`Updated manifest: ${result.manifest.manifestPath}`);
|
|
97
|
-
if (result.markdown.skipped.length)
|
|
205
|
+
if (result.markdown.skipped.length) {
|
|
98
206
|
console.log(`Skipped ${result.markdown.skipped.length} existing Markdown file(s). Use --overwrite to replace them.`);
|
|
207
|
+
}
|
|
99
208
|
return;
|
|
100
209
|
}
|
|
101
210
|
if (command === "install-agents") {
|
|
102
|
-
|
|
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
|
+
}
|
|
103
225
|
const result = await writeAgentFiles(prompts, {
|
|
104
|
-
cwd,
|
|
105
|
-
agent: flags
|
|
226
|
+
cwd: getResolvedCwd(flags),
|
|
227
|
+
agent: getStringFlag(flags, "agent") || "all",
|
|
106
228
|
overwriteAgentFiles: true,
|
|
107
229
|
});
|
|
108
230
|
console.log(`Synced ${result.written.length} agent integration file(s): ${result.targets.join(", ")}.`);
|
|
109
231
|
return;
|
|
110
232
|
}
|
|
111
|
-
|
|
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
|
+
}
|
|
112
320
|
}
|
|
113
|
-
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
|
+
}
|
|
114
389
|
return {
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
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" },
|
|
120
399
|
};
|
|
121
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
|
+
}
|
|
122
553
|
function validateToolFlag(tool) {
|
|
123
554
|
if (!tool)
|
|
124
555
|
return;
|
|
125
556
|
const validSet = new Set(VALID_TOOLS);
|
|
126
557
|
if (!validSet.has(tool)) {
|
|
127
|
-
throw new
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
async function generatePromptFromFlags(client, flags) {
|
|
131
|
-
const goal = flags.goal;
|
|
132
|
-
if (!goal)
|
|
133
|
-
throw new Error("Prompt generation requires --goal.");
|
|
134
|
-
return client.generatePrompt({
|
|
135
|
-
goal,
|
|
136
|
-
context: flags.context || "",
|
|
137
|
-
constraints: flags.constraints || "",
|
|
138
|
-
desiredOutput: flags.desiredOutput || "A reusable prompt pack saved as Markdown.",
|
|
139
|
-
tool: flags.tool || "Codex",
|
|
140
|
-
mode: flags.mode || "implement",
|
|
141
|
-
artifactType: flags.artifactType || "prompt-file",
|
|
142
|
-
includeWebSearch: Boolean(flags.webSearch),
|
|
143
|
-
});
|
|
558
|
+
throw new CliError(`Invalid --tool "${tool}". Valid tools: ${VALID_TOOLS.join(", ")}.`, CLI_EXIT_CODES.validation);
|
|
559
|
+
}
|
|
144
560
|
}
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
if (eqIndex !== -1) {
|
|
154
|
-
const key = normalizeFlag(arg.slice(2, eqIndex));
|
|
155
|
-
if (!key || key.length > 64)
|
|
156
|
-
continue;
|
|
157
|
-
flags[key] = arg.slice(eqIndex + 1).slice(0, MAX_FLAG_VALUE_LENGTH);
|
|
158
|
-
continue;
|
|
159
|
-
}
|
|
160
|
-
const key = normalizeFlag(arg.slice(2));
|
|
161
|
-
if (!key || key.length > 64)
|
|
162
|
-
continue;
|
|
163
|
-
const next = args[index + 1];
|
|
164
|
-
if (!next || next.startsWith("--")) {
|
|
165
|
-
flags[key] = true;
|
|
166
|
-
}
|
|
167
|
-
else {
|
|
168
|
-
flags[key] = String(next).slice(0, MAX_FLAG_VALUE_LENGTH);
|
|
169
|
-
index += 1;
|
|
170
|
-
}
|
|
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);
|
|
171
569
|
}
|
|
172
|
-
return flags;
|
|
173
570
|
}
|
|
174
|
-
function
|
|
175
|
-
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}`);
|
|
176
589
|
}
|
|
177
590
|
async function getCliVersion() {
|
|
178
591
|
try {
|
|
@@ -184,47 +597,246 @@ async function getCliVersion() {
|
|
|
184
597
|
return "0.0.0";
|
|
185
598
|
}
|
|
186
599
|
}
|
|
187
|
-
function printHelp() {
|
|
600
|
+
function printHelp(command) {
|
|
601
|
+
if (command) {
|
|
602
|
+
console.log(getCommandHelp(command));
|
|
603
|
+
return;
|
|
604
|
+
}
|
|
188
605
|
console.log(`Prompts-GPT CLI
|
|
189
606
|
|
|
190
|
-
|
|
191
|
-
prompts-gpt
|
|
607
|
+
Usage:
|
|
608
|
+
prompts-gpt <command> [options]
|
|
609
|
+
prompts-gpt help [command]
|
|
192
610
|
prompts-gpt version
|
|
193
|
-
prompts-gpt project
|
|
194
|
-
prompts-gpt pull [--query "repo audit"] [--category coding] [--tool Codex] [--limit 25] [--out .prompts-gpt] [--overwrite]
|
|
195
|
-
prompts-gpt generate --goal "Review this diff" [--context "Next.js app"] [--agent codex,cursor,vscode]
|
|
196
|
-
prompts-gpt sync [--goal "Review this diff"] [--limit 25] [--agent all] [--out .prompts-gpt] [--cwd /path/to/repo]
|
|
197
|
-
prompts-gpt install-agents [--agent codex,cursor,vscode,copilot]
|
|
198
611
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
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
|
|
212
625
|
|
|
213
626
|
Supported tools: ${VALID_TOOLS.join(", ")}
|
|
214
627
|
Supported agent targets: ${SUPPORTED_AGENT_TARGETS.join(", ")}
|
|
215
628
|
`);
|
|
216
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
|
+
}
|
|
217
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
|
+
}
|
|
218
813
|
if (error instanceof PromptsGptApiError) {
|
|
219
|
-
console.error(
|
|
814
|
+
console.error(formatApiError(error));
|
|
220
815
|
process.exitCode = error.status === 401 || error.status === 403
|
|
221
816
|
? CLI_EXIT_CODES.auth
|
|
222
|
-
: error.
|
|
223
|
-
? CLI_EXIT_CODES.
|
|
224
|
-
:
|
|
817
|
+
: error.status === 429
|
|
818
|
+
? CLI_EXIT_CODES.rateLimit
|
|
819
|
+
: error.code === "VALIDATION_ERROR"
|
|
820
|
+
? CLI_EXIT_CODES.validation
|
|
821
|
+
: CLI_EXIT_CODES.general;
|
|
225
822
|
return;
|
|
226
823
|
}
|
|
227
824
|
console.error(error instanceof Error ? error.message : String(error));
|
|
228
825
|
process.exitCode = CLI_EXIT_CODES.general;
|
|
229
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
|
+
}
|
|
230
842
|
//# sourceMappingURL=cli.js.map
|