@dedesfr/prompter 0.5.1 → 0.6.0

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.
Files changed (32) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/dist/cli/index.js +1 -1
  3. package/dist/commands/init.d.ts +1 -0
  4. package/dist/commands/init.d.ts.map +1 -1
  5. package/dist/commands/init.js +55 -21
  6. package/dist/commands/init.js.map +1 -1
  7. package/dist/core/configurators/slash/base.d.ts +2 -2
  8. package/dist/core/configurators/slash/base.d.ts.map +1 -1
  9. package/dist/core/configurators/slash/base.js +10 -4
  10. package/dist/core/configurators/slash/base.js.map +1 -1
  11. package/dist/core/configurators/slash/github-copilot.d.ts +1 -1
  12. package/dist/core/configurators/slash/github-copilot.d.ts.map +1 -1
  13. package/dist/core/configurators/slash/github-copilot.js +2 -2
  14. package/dist/core/configurators/slash/github-copilot.js.map +1 -1
  15. package/dist/core/prompt-templates.d.ts +10 -0
  16. package/dist/core/prompt-templates.d.ts.map +1 -0
  17. package/dist/core/prompt-templates.js +1298 -0
  18. package/dist/core/prompt-templates.js.map +1 -0
  19. package/package.json +1 -1
  20. package/src/cli/index.ts +1 -1
  21. package/src/commands/init.ts +66 -22
  22. package/src/core/configurators/slash/base.ts +11 -4
  23. package/src/core/configurators/slash/github-copilot.ts +2 -2
  24. package/src/core/prompt-templates.ts +1306 -0
  25. package/.github/prompts/ai-humanizer.prompt.md +0 -50
  26. package/.github/prompts/epic-single.prompt.md +0 -64
  27. package/.github/prompts/prd-generator.prompt.md +0 -212
  28. package/.github/prompts/product-brief.prompt.md +0 -142
  29. package/.github/prompts/prompter-enhance.prompt.md +0 -48
  30. package/.github/prompts/qa-test-scenario.prompt.md +0 -150
  31. package/.github/prompts/skill-creator.prompt.md +0 -174
  32. package/.github/prompts/story-single.prompt.md +0 -87
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt-templates.js","sourceRoot":"","sources":["../../src/core/prompt-templates.ts"],"names":[],"mappings":"AAAA,yFAAyF;AAEzF,MAAM,CAAC,MAAM,qBAAqB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6CpC,CAAC;AAEF,MAAM,CAAC,MAAM,oBAAoB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+CnC,CAAC;AAEF,MAAM,CAAC,MAAM,4BAA4B,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoJ3C,CAAC;AAEF,MAAM,CAAC,MAAM,sBAAsB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmMrC,CAAC;AAEF,MAAM,CAAC,MAAM,sBAAsB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiSrC,CAAC;AAEF,MAAM,CAAC,MAAM,yBAAyB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqIxC,CAAC;AAEF,MAAM,CAAC,MAAM,sBAAsB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8VrC,CAAC;AAEF,MAAM,CAAC,MAAM,qBAAqB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsEpC,CAAC;AAEF,4CAA4C;AAC5C,MAAM,CAAC,MAAM,gBAAgB,GAA2B;IACpD,cAAc,EAAE,qBAAqB;IACrC,aAAa,EAAE,oBAAoB;IACnC,qBAAqB,EAAE,4BAA4B;IACnD,eAAe,EAAE,sBAAsB;IACvC,eAAe,EAAE,sBAAsB;IACvC,kBAAkB,EAAE,yBAAyB;IAC7C,eAAe,EAAE,sBAAsB;IACvC,cAAc,EAAE,qBAAqB;CACxC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dedesfr/prompter",
3
- "version": "0.5.1",
3
+ "version": "0.6.0",
4
4
  "description": "Enhance prompts directly in your AI coding workflow",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
package/src/cli/index.ts CHANGED
@@ -10,7 +10,7 @@ const program = new Command();
10
10
  program
11
11
  .name('prompter')
12
12
  .description('Enhance prompts directly in your AI coding workflow')
13
- .version('0.5.1');
13
+ .version('0.6.0');
14
14
 
15
15
  program
16
16
  .command('init')
@@ -4,12 +4,9 @@ import chalk from 'chalk';
4
4
  import { checkbox } from '@inquirer/prompts';
5
5
  import { PROMPTER_DIR, SUPPORTED_TOOLS, AVAILABLE_PROMPTS, PrompterConfig } from '../core/config.js';
6
6
  import { projectTemplate, agentsTemplate } from '../core/templates/index.js';
7
+ import { PROMPT_TEMPLATES } from '../core/prompt-templates.js';
7
8
  import { registry } from '../core/configurators/slash/index.js';
8
- import { fileURLToPath } from 'url';
9
- import { dirname } from 'path';
10
-
11
- const __filename = fileURLToPath(import.meta.url);
12
- const __dirname = dirname(__filename);
9
+ import { SlashCommandId } from '../core/templates/index.js';
13
10
 
14
11
  interface InitOptions {
15
12
  tools?: string[];
@@ -57,7 +54,8 @@ export class InitCommand {
57
54
  let selectedTools: string[] = [];
58
55
 
59
56
  if (options.tools && options.tools.length > 0) {
60
- selectedTools = options.tools;
57
+ // Handle comma-separated values in a single string or array of strings
58
+ selectedTools = options.tools.flatMap(tool => tool.split(',').map(t => t.trim()));
61
59
  } else if (!options.noInteractive) {
62
60
  try {
63
61
  const message = isReInitialization
@@ -88,7 +86,8 @@ export class InitCommand {
88
86
  let selectedPrompts: string[] = [];
89
87
 
90
88
  if (options.prompts && options.prompts.length > 0) {
91
- selectedPrompts = options.prompts;
89
+ // Handle comma-separated values in a single string or array of strings
90
+ selectedPrompts = options.prompts.flatMap(prompt => prompt.split(',').map(p => p.trim()));
92
91
  } else if (!options.noInteractive) {
93
92
  try {
94
93
  // Detect currently installed prompts (use path.join to get prompter path)
@@ -170,21 +169,31 @@ export class InitCommand {
170
169
  // Remove unchecked prompts
171
170
  if (promptsToRemove.length > 0) {
172
171
  console.log(chalk.blue('\nšŸ—‘ļø Removing prompt templates...\n'));
172
+
173
+ // Remove from prompter/ folder
173
174
  const removedPrompts = await this.removePrompts(prompterPath, promptsToRemove);
174
175
  for (const promptName of removedPrompts) {
175
176
  console.log(chalk.yellow('āœ“') + ` Removed ${chalk.cyan(promptName)}`);
176
177
  }
178
+
179
+ // Remove workflow files from all configured tools
180
+ await this.removeWorkflowFilesForPrompts(projectPath, currentTools, promptsToRemove);
177
181
  }
178
182
 
179
183
  // Generate workflow files for new tools
180
184
  if (toolsToAdd.length > 0) {
181
185
  console.log(chalk.blue('\nšŸ“ Creating workflow files...\n'));
182
186
 
187
+ // Convert selected prompt values to SlashCommandIds
188
+ const slashCommandIds: SlashCommandId[] = selectedPrompts as SlashCommandId[];
189
+
183
190
  for (const toolId of toolsToAdd) {
184
191
  const configurator = registry.get(toolId);
185
192
  if (configurator) {
186
193
  try {
187
- const files = await configurator.generateAll(projectPath);
194
+ // Pass selected prompts to only generate those workflow files
195
+ // Pass empty array if no prompts selected to generate nothing
196
+ const files = await configurator.generateAll(projectPath, slashCommandIds);
188
197
  for (const file of files) {
189
198
  console.log(chalk.green('āœ“') + ` Created ${chalk.cyan(file)}`);
190
199
  }
@@ -198,11 +207,17 @@ export class InitCommand {
198
207
  // Add missing workflow files for existing tools
199
208
  if (isReInitialization && toolsToKeep.length > 0) {
200
209
  const missingFiles: string[] = [];
210
+
211
+ // Convert selected prompt values to SlashCommandIds
212
+ const slashCommandIds: SlashCommandId[] = selectedPrompts as SlashCommandId[];
213
+
201
214
  for (const toolId of toolsToKeep) {
202
215
  const configurator = registry.get(toolId);
203
216
  if (configurator) {
204
217
  try {
205
- const files = await configurator.generateAll(projectPath);
218
+ // Pass selected prompts to only generate those workflow files
219
+ // Pass empty array if no prompts selected to generate nothing
220
+ const files = await configurator.generateAll(projectPath, slashCommandIds);
206
221
  for (const file of files) {
207
222
  missingFiles.push(file);
208
223
  }
@@ -353,9 +368,10 @@ export class InitCommand {
353
368
 
354
369
  private async detectInstalledPrompts(prompterPath: string): Promise<string[]> {
355
370
  const installedPrompts: string[] = [];
371
+ const corePath = path.join(prompterPath, 'core');
356
372
 
357
373
  for (const prompt of AVAILABLE_PROMPTS) {
358
- const promptFilePath = path.join(prompterPath, prompt.sourceFile);
374
+ const promptFilePath = path.join(corePath, prompt.sourceFile);
359
375
  if (await this.fileExists(promptFilePath)) {
360
376
  installedPrompts.push(prompt.value);
361
377
  }
@@ -366,28 +382,27 @@ export class InitCommand {
366
382
 
367
383
  private async installPrompts(projectPath: string, prompterPath: string, selectedPrompts: string[]): Promise<string[]> {
368
384
  const installedPrompts: string[] = [];
385
+ const corePath = path.join(prompterPath, 'core');
369
386
 
370
- // Get the path to the prompt templates directory
371
- // In production: node_modules/prompter/prompt/
372
- // In development: prompt/
373
- const promptSourceDir = path.join(__dirname, '../../prompt');
387
+ // Ensure core directory exists
388
+ await fs.mkdir(corePath, { recursive: true });
374
389
 
375
390
  for (const promptId of selectedPrompts) {
376
391
  const prompt = AVAILABLE_PROMPTS.find(p => p.value === promptId);
377
392
  if (!prompt) continue;
378
393
 
379
- const sourcePath = path.join(promptSourceDir, prompt.sourceFile);
380
- const destPath = path.join(prompterPath, prompt.sourceFile);
394
+ const destPath = path.join(corePath, prompt.sourceFile);
381
395
 
382
396
  try {
383
- // Check if source file exists
384
- if (!await this.fileExists(sourcePath)) {
385
- console.log(chalk.yellow(` Warning: Source file not found for ${prompt.name}`));
397
+ // Get template content from embedded templates
398
+ const content = PROMPT_TEMPLATES[promptId];
399
+
400
+ if (!content) {
401
+ console.log(chalk.yellow(` Warning: Template not found for ${prompt.name}`));
386
402
  continue;
387
403
  }
388
404
 
389
- // Copy the prompt file
390
- const content = await fs.readFile(sourcePath, 'utf-8');
405
+ // Write the prompt file from embedded template
391
406
  await fs.writeFile(destPath, content, 'utf-8');
392
407
  installedPrompts.push(prompt.name);
393
408
  } catch (error) {
@@ -400,12 +415,13 @@ export class InitCommand {
400
415
 
401
416
  private async removePrompts(prompterPath: string, promptsToRemove: string[]): Promise<string[]> {
402
417
  const removedPrompts: string[] = [];
418
+ const corePath = path.join(prompterPath, 'core');
403
419
 
404
420
  for (const promptId of promptsToRemove) {
405
421
  const prompt = AVAILABLE_PROMPTS.find(p => p.value === promptId);
406
422
  if (!prompt) continue;
407
423
 
408
- const filePath = path.join(prompterPath, prompt.sourceFile);
424
+ const filePath = path.join(corePath, prompt.sourceFile);
409
425
 
410
426
  try {
411
427
  if (await this.fileExists(filePath)) {
@@ -419,4 +435,32 @@ export class InitCommand {
419
435
 
420
436
  return removedPrompts;
421
437
  }
438
+
439
+ private async removeWorkflowFilesForPrompts(projectPath: string, toolIds: string[], promptIds: string[]): Promise<void> {
440
+ const slashCommandIds: SlashCommandId[] = promptIds as SlashCommandId[];
441
+
442
+ for (const toolId of toolIds) {
443
+ const configurator = registry.get(toolId);
444
+ if (!configurator) continue;
445
+
446
+ // Get targets for the prompts to remove
447
+ const targets = configurator.getTargets(slashCommandIds);
448
+
449
+ for (const target of targets) {
450
+ const filePath = path.join(projectPath, target.path);
451
+
452
+ try {
453
+ if (await this.fileExists(filePath)) {
454
+ await fs.unlink(filePath);
455
+ console.log(chalk.yellow('āœ“') + ` Removed ${chalk.cyan(target.path)}`);
456
+
457
+ // Remove empty parent directories
458
+ await this.removeEmptyDirs(path.dirname(filePath), projectPath);
459
+ }
460
+ } catch (error) {
461
+ // Silently ignore errors for workflow file removal
462
+ }
463
+ }
464
+ }
465
+ }
422
466
  }
@@ -15,18 +15,25 @@ export abstract class SlashCommandConfigurator {
15
15
  abstract readonly toolId: string;
16
16
  abstract readonly isAvailable: boolean;
17
17
 
18
- getTargets(): SlashCommandTarget[] {
19
- return ALL_COMMANDS.map((id) => ({
18
+ getTargets(filterIds?: SlashCommandId[]): SlashCommandTarget[] {
19
+ // If filterIds is undefined, generate all commands
20
+ // If filterIds is an empty array, generate nothing
21
+ // If filterIds has items, generate only those
22
+ const commandsToGenerate = filterIds === undefined
23
+ ? ALL_COMMANDS
24
+ : ALL_COMMANDS.filter(id => filterIds.includes(id));
25
+
26
+ return commandsToGenerate.map((id) => ({
20
27
  id,
21
28
  path: this.getRelativePath(id),
22
29
  kind: 'slash'
23
30
  }));
24
31
  }
25
32
 
26
- async generateAll(projectPath: string): Promise<string[]> {
33
+ async generateAll(projectPath: string, filterIds?: SlashCommandId[]): Promise<string[]> {
27
34
  const createdOrUpdated: string[] = [];
28
35
 
29
- for (const target of this.getTargets()) {
36
+ for (const target of this.getTargets(filterIds)) {
30
37
  const body = this.getBody(target.id);
31
38
  const filePath = path.join(projectPath, target.path);
32
39
 
@@ -41,10 +41,10 @@ export class GithubCopilotConfigurator extends SlashCommandConfigurator {
41
41
  return `---\ndescription: ${description}\n---`;
42
42
  }
43
43
 
44
- async generateAll(projectPath: string): Promise<string[]> {
44
+ async generateAll(projectPath: string, filterIds?: SlashCommandId[]): Promise<string[]> {
45
45
  const createdOrUpdated: string[] = [];
46
46
 
47
- for (const target of this.getTargets()) {
47
+ for (const target of this.getTargets(filterIds)) {
48
48
  const body = this.getBody(target.id);
49
49
  const filePath = path.join(projectPath, target.path);
50
50