@dedesfr/prompter 0.3.1 → 0.3.3
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/.github/prompts/{epic-single.md → epic-single.prompt.md} +1 -0
- package/.github/prompts/{prd-generator.md → prd-generator.prompt.md} +1 -0
- package/.github/prompts/{prompter-enhance.md → prompter-enhance.prompt.md} +1 -0
- package/.github/prompts/{qa-test-scenario.md → qa-test-scenario.prompt.md} +1 -0
- package/.github/prompts/{story-single.md → story-single.prompt.md} +1 -0
- package/dist/cli/index.js +1 -1
- package/dist/commands/update.d.ts +2 -0
- package/dist/commands/update.d.ts.map +1 -1
- package/dist/commands/update.js +61 -6
- package/dist/commands/update.js.map +1 -1
- package/dist/core/configurators/slash/github-copilot.d.ts +2 -0
- package/dist/core/configurators/slash/github-copilot.d.ts.map +1 -1
- package/dist/core/configurators/slash/github-copilot.js +44 -5
- package/dist/core/configurators/slash/github-copilot.js.map +1 -1
- package/package.json +1 -1
- package/src/cli/index.ts +1 -1
- package/src/commands/update.ts +67 -6
- package/src/core/configurators/slash/github-copilot.ts +49 -5
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
description: Generate a comprehensive Product Requirements Document (PRD)
|
|
3
3
|
---
|
|
4
|
+
$ARGUMENTS
|
|
4
5
|
<!-- prompter-managed-start -->
|
|
5
6
|
# Role & Expertise
|
|
6
7
|
You are an experienced Product Manager specializing in creating comprehensive Product Requirements Documents (PRDs). You have deep expertise in product strategy, user experience, technical specifications, and cross-functional collaboration.
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
description: Generate focused QA test scenarios from PRD
|
|
3
3
|
---
|
|
4
|
+
$ARGUMENTS
|
|
4
5
|
<!-- prompter-managed-start -->
|
|
5
6
|
# Role & Expertise
|
|
6
7
|
You are a Senior QA Architect and Test Strategy Expert with extensive experience in creating focused, actionable test plans. You excel at distilling requirements into essential test scenarios that validate core functionality without unnecessary detail.
|
package/dist/cli/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../../src/commands/update.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../../src/commands/update.ts"],"names":[],"mappings":"AAMA,qBAAa,aAAa;IAChB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;YA8DhB,UAAU;YASV,qBAAqB;CAuBtC"}
|
package/dist/commands/update.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
|
+
import { promises as fs } from 'fs';
|
|
3
|
+
import path from 'path';
|
|
2
4
|
import { PrompterConfig } from '../core/config.js';
|
|
3
5
|
import { registry } from '../core/configurators/slash/index.js';
|
|
4
6
|
export class UpdateCommand {
|
|
@@ -12,27 +14,80 @@ export class UpdateCommand {
|
|
|
12
14
|
process.exitCode = 1;
|
|
13
15
|
return;
|
|
14
16
|
}
|
|
17
|
+
// Detect configured tools
|
|
18
|
+
const configuredTools = await this.detectConfiguredTools(projectPath);
|
|
19
|
+
if (configuredTools.length === 0) {
|
|
20
|
+
console.log(chalk.yellow('⚠️ No configured tools found.'));
|
|
21
|
+
console.log(chalk.gray(' Run `prompter init` to configure tools.\n'));
|
|
22
|
+
process.exitCode = 1;
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
15
25
|
let updatedCount = 0;
|
|
16
|
-
|
|
17
|
-
|
|
26
|
+
let createdCount = 0;
|
|
27
|
+
// Update and add missing workflow files for configured tools only
|
|
28
|
+
for (const toolId of configuredTools) {
|
|
29
|
+
const configurator = registry.get(toolId);
|
|
30
|
+
if (!configurator)
|
|
31
|
+
continue;
|
|
18
32
|
try {
|
|
19
|
-
|
|
20
|
-
|
|
33
|
+
// Update existing files
|
|
34
|
+
const updatedFiles = await configurator.updateExisting(projectPath);
|
|
35
|
+
for (const file of updatedFiles) {
|
|
21
36
|
console.log(chalk.green('✓') + ` Updated ${chalk.cyan(file)}`);
|
|
22
37
|
updatedCount++;
|
|
23
38
|
}
|
|
39
|
+
// Generate all workflow files (including missing ones)
|
|
40
|
+
const allFiles = await configurator.generateAll(projectPath);
|
|
41
|
+
const newFiles = allFiles.filter(f => !updatedFiles.includes(f));
|
|
42
|
+
for (const file of newFiles) {
|
|
43
|
+
console.log(chalk.green('✓') + ` Created ${chalk.cyan(file)}`);
|
|
44
|
+
createdCount++;
|
|
45
|
+
}
|
|
24
46
|
}
|
|
25
47
|
catch (error) {
|
|
26
48
|
console.log(chalk.red('✗') + ` Failed to update ${configurator.toolId}: ${error}`);
|
|
27
49
|
}
|
|
28
50
|
}
|
|
29
|
-
if (updatedCount === 0) {
|
|
51
|
+
if (updatedCount === 0 && createdCount === 0) {
|
|
30
52
|
console.log(chalk.yellow('⚠️ No workflow files found to update.'));
|
|
31
53
|
console.log(chalk.gray(' Run `prompter init` to create them.\n'));
|
|
32
54
|
}
|
|
33
55
|
else {
|
|
34
|
-
|
|
56
|
+
const summary = [];
|
|
57
|
+
if (updatedCount > 0)
|
|
58
|
+
summary.push(`${updatedCount} updated`);
|
|
59
|
+
if (createdCount > 0)
|
|
60
|
+
summary.push(`${createdCount} created`);
|
|
61
|
+
console.log(chalk.green(`\n✅ ${summary.join(', ')}.\n`));
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
async fileExists(filePath) {
|
|
65
|
+
try {
|
|
66
|
+
await fs.access(filePath);
|
|
67
|
+
return true;
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
async detectConfiguredTools(projectPath) {
|
|
74
|
+
const configuredTools = [];
|
|
75
|
+
const allConfigurators = registry.getAll();
|
|
76
|
+
for (const configurator of allConfigurators) {
|
|
77
|
+
const targets = configurator.getTargets();
|
|
78
|
+
let hasFiles = false;
|
|
79
|
+
for (const target of targets) {
|
|
80
|
+
const filePath = path.join(projectPath, target.path);
|
|
81
|
+
if (await this.fileExists(filePath)) {
|
|
82
|
+
hasFiles = true;
|
|
83
|
+
break;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
if (hasFiles) {
|
|
87
|
+
configuredTools.push(configurator.toolId);
|
|
88
|
+
}
|
|
35
89
|
}
|
|
90
|
+
return configuredTools;
|
|
36
91
|
}
|
|
37
92
|
}
|
|
38
93
|
//# sourceMappingURL=update.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"update.js","sourceRoot":"","sources":["../../src/commands/update.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,QAAQ,EAAE,MAAM,sCAAsC,CAAC;AAEhE,MAAM,OAAO,aAAa;IACtB,KAAK,CAAC,OAAO;QACT,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;QAElC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,4CAA4C,CAAC,CAAC,CAAC;QAEtE,uBAAuB;QACvB,IAAI,CAAC,MAAM,cAAc,CAAC,iBAAiB,CAAC,WAAW,CAAC,EAAE,CAAC;YACvD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,gDAAgD,CAAC,CAAC,CAAC;YACzE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAC,CAAC;YAC3D,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;YACrB,OAAO;QACX,CAAC;QAED,IAAI,YAAY,GAAG,CAAC,CAAC;QAErB,
|
|
1
|
+
{"version":3,"file":"update.js","sourceRoot":"","sources":["../../src/commands/update.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,5 +5,7 @@ export declare class GithubCopilotConfigurator extends SlashCommandConfigurator
|
|
|
5
5
|
readonly isAvailable = true;
|
|
6
6
|
protected getRelativePath(id: SlashCommandId): string;
|
|
7
7
|
protected getFrontmatter(id: SlashCommandId): string | undefined;
|
|
8
|
+
generateAll(projectPath: string): Promise<string[]>;
|
|
9
|
+
private checkFileExists;
|
|
8
10
|
}
|
|
9
11
|
//# sourceMappingURL=github-copilot.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"github-copilot.d.ts","sourceRoot":"","sources":["../../../../src/core/configurators/slash/github-copilot.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,WAAW,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"github-copilot.d.ts","sourceRoot":"","sources":["../../../../src/core/configurators/slash/github-copilot.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,WAAW,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAqB1D,qBAAa,yBAA0B,SAAQ,wBAAwB;IACnE,QAAQ,CAAC,MAAM,oBAAoB;IACnC,QAAQ,CAAC,WAAW,QAAQ;IAE5B,SAAS,CAAC,eAAe,CAAC,EAAE,EAAE,cAAc,GAAG,MAAM;IAIrD,SAAS,CAAC,cAAc,CAAC,EAAE,EAAE,cAAc,GAAG,MAAM,GAAG,SAAS;IAK1D,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;YAgC3C,eAAe;CAQhC"}
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import { SlashCommandConfigurator } from './base.js';
|
|
2
|
+
import { promises as fs } from 'fs';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import { PROMPTER_MARKERS } from '../../config.js';
|
|
2
5
|
const FILE_PATHS = {
|
|
3
|
-
enhance: '.github/prompts/prompter-enhance.md',
|
|
4
|
-
'prd-generator': '.github/prompts/prd-generator.md',
|
|
5
|
-
'epic-single': '.github/prompts/epic-single.md',
|
|
6
|
-
'story-single': '.github/prompts/story-single.md',
|
|
7
|
-
'qa-test-scenario': '.github/prompts/qa-test-scenario.md'
|
|
6
|
+
enhance: '.github/prompts/prompter-enhance.prompt.md',
|
|
7
|
+
'prd-generator': '.github/prompts/prd-generator.prompt.md',
|
|
8
|
+
'epic-single': '.github/prompts/epic-single.prompt.md',
|
|
9
|
+
'story-single': '.github/prompts/story-single.prompt.md',
|
|
10
|
+
'qa-test-scenario': '.github/prompts/qa-test-scenario.prompt.md'
|
|
8
11
|
};
|
|
9
12
|
const DESCRIPTIONS = {
|
|
10
13
|
enhance: 'Enhance a rough prompt into a professional specification',
|
|
@@ -23,5 +26,41 @@ export class GithubCopilotConfigurator extends SlashCommandConfigurator {
|
|
|
23
26
|
const description = DESCRIPTIONS[id];
|
|
24
27
|
return `---\ndescription: ${description}\n---`;
|
|
25
28
|
}
|
|
29
|
+
async generateAll(projectPath) {
|
|
30
|
+
const createdOrUpdated = [];
|
|
31
|
+
for (const target of this.getTargets()) {
|
|
32
|
+
const body = this.getBody(target.id);
|
|
33
|
+
const filePath = path.join(projectPath, target.path);
|
|
34
|
+
// Ensure directory exists
|
|
35
|
+
await fs.mkdir(path.dirname(filePath), { recursive: true });
|
|
36
|
+
const exists = await this.checkFileExists(filePath);
|
|
37
|
+
if (exists) {
|
|
38
|
+
await this.updateBody(filePath, body);
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
const frontmatter = this.getFrontmatter(target.id);
|
|
42
|
+
const sections = [];
|
|
43
|
+
if (frontmatter) {
|
|
44
|
+
sections.push(frontmatter.trim());
|
|
45
|
+
}
|
|
46
|
+
// Add $ARGUMENTS after frontmatter
|
|
47
|
+
sections.push('$ARGUMENTS');
|
|
48
|
+
sections.push(`${PROMPTER_MARKERS.start}\n${body}\n${PROMPTER_MARKERS.end}`);
|
|
49
|
+
const content = sections.join('\n') + '\n';
|
|
50
|
+
await fs.writeFile(filePath, content, 'utf-8');
|
|
51
|
+
}
|
|
52
|
+
createdOrUpdated.push(target.path);
|
|
53
|
+
}
|
|
54
|
+
return createdOrUpdated;
|
|
55
|
+
}
|
|
56
|
+
async checkFileExists(filePath) {
|
|
57
|
+
try {
|
|
58
|
+
await fs.access(filePath);
|
|
59
|
+
return true;
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
26
65
|
}
|
|
27
66
|
//# sourceMappingURL=github-copilot.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"github-copilot.js","sourceRoot":"","sources":["../../../../src/core/configurators/slash/github-copilot.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"github-copilot.js","sourceRoot":"","sources":["../../../../src/core/configurators/slash/github-copilot.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,WAAW,CAAC;AAErD,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,IAAI,CAAC;AACpC,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAEnD,MAAM,UAAU,GAAmC;IAC/C,OAAO,EAAE,4CAA4C;IACrD,eAAe,EAAE,yCAAyC;IAC1D,aAAa,EAAE,uCAAuC;IACtD,cAAc,EAAE,wCAAwC;IACxD,kBAAkB,EAAE,4CAA4C;CACnE,CAAC;AAEF,MAAM,YAAY,GAAmC;IACjD,OAAO,EAAE,0DAA0D;IACnE,eAAe,EAAE,8DAA8D;IAC/E,aAAa,EAAE,0CAA0C;IACzD,cAAc,EAAE,qDAAqD;IACrE,kBAAkB,EAAE,6CAA6C;CACpE,CAAC;AAEF,MAAM,OAAO,yBAA0B,SAAQ,wBAAwB;IAC1D,MAAM,GAAG,gBAAgB,CAAC;IAC1B,WAAW,GAAG,IAAI,CAAC;IAElB,eAAe,CAAC,EAAkB;QACxC,OAAO,UAAU,CAAC,EAAE,CAAC,CAAC;IAC1B,CAAC;IAES,cAAc,CAAC,EAAkB;QACvC,MAAM,WAAW,GAAG,YAAY,CAAC,EAAE,CAAC,CAAC;QACrC,OAAO,qBAAqB,WAAW,OAAO,CAAC;IACnD,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,WAAmB;QACjC,MAAM,gBAAgB,GAAa,EAAE,CAAC;QAEtC,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,UAAU,EAAE,EAAE,CAAC;YACrC,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YACrC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;YAErD,0BAA0B;YAC1B,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAE5D,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC;YACpD,IAAI,MAAM,EAAE,CAAC;gBACT,MAAM,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;YAC1C,CAAC;iBAAM,CAAC;gBACJ,MAAM,WAAW,GAAG,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;gBACnD,MAAM,QAAQ,GAAa,EAAE,CAAC;gBAC9B,IAAI,WAAW,EAAE,CAAC;oBACd,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC;gBACtC,CAAC;gBACD,mCAAmC;gBACnC,QAAQ,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;gBAC5B,QAAQ,CAAC,IAAI,CAAC,GAAG,gBAAgB,CAAC,KAAK,KAAK,IAAI,KAAK,gBAAgB,CAAC,GAAG,EAAE,CAAC,CAAC;gBAC7E,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;gBAC3C,MAAM,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;YACnD,CAAC;YAED,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACvC,CAAC;QAED,OAAO,gBAAgB,CAAC;IAC5B,CAAC;IAEO,KAAK,CAAC,eAAe,CAAC,QAAgB;QAC1C,IAAI,CAAC;YACD,MAAM,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YAC1B,OAAO,IAAI,CAAC;QAChB,CAAC;QAAC,MAAM,CAAC;YACL,OAAO,KAAK,CAAC;QACjB,CAAC;IACL,CAAC;CACJ"}
|
package/package.json
CHANGED
package/src/cli/index.ts
CHANGED
package/src/commands/update.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
|
+
import { promises as fs } from 'fs';
|
|
3
|
+
import path from 'path';
|
|
2
4
|
import { PrompterConfig } from '../core/config.js';
|
|
3
5
|
import { registry } from '../core/configurators/slash/index.js';
|
|
4
6
|
|
|
@@ -16,26 +18,85 @@ export class UpdateCommand {
|
|
|
16
18
|
return;
|
|
17
19
|
}
|
|
18
20
|
|
|
21
|
+
// Detect configured tools
|
|
22
|
+
const configuredTools = await this.detectConfiguredTools(projectPath);
|
|
23
|
+
|
|
24
|
+
if (configuredTools.length === 0) {
|
|
25
|
+
console.log(chalk.yellow('⚠️ No configured tools found.'));
|
|
26
|
+
console.log(chalk.gray(' Run `prompter init` to configure tools.\n'));
|
|
27
|
+
process.exitCode = 1;
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
|
|
19
31
|
let updatedCount = 0;
|
|
32
|
+
let createdCount = 0;
|
|
33
|
+
|
|
34
|
+
// Update and add missing workflow files for configured tools only
|
|
35
|
+
for (const toolId of configuredTools) {
|
|
36
|
+
const configurator = registry.get(toolId);
|
|
37
|
+
if (!configurator) continue;
|
|
20
38
|
|
|
21
|
-
// Update workflow files for all tools
|
|
22
|
-
for (const configurator of registry.getAvailable()) {
|
|
23
39
|
try {
|
|
24
|
-
|
|
25
|
-
|
|
40
|
+
// Update existing files
|
|
41
|
+
const updatedFiles = await configurator.updateExisting(projectPath);
|
|
42
|
+
for (const file of updatedFiles) {
|
|
26
43
|
console.log(chalk.green('✓') + ` Updated ${chalk.cyan(file)}`);
|
|
27
44
|
updatedCount++;
|
|
28
45
|
}
|
|
46
|
+
|
|
47
|
+
// Generate all workflow files (including missing ones)
|
|
48
|
+
const allFiles = await configurator.generateAll(projectPath);
|
|
49
|
+
const newFiles = allFiles.filter(f => !updatedFiles.includes(f));
|
|
50
|
+
for (const file of newFiles) {
|
|
51
|
+
console.log(chalk.green('✓') + ` Created ${chalk.cyan(file)}`);
|
|
52
|
+
createdCount++;
|
|
53
|
+
}
|
|
29
54
|
} catch (error) {
|
|
30
55
|
console.log(chalk.red('✗') + ` Failed to update ${configurator.toolId}: ${error}`);
|
|
31
56
|
}
|
|
32
57
|
}
|
|
33
58
|
|
|
34
|
-
if (updatedCount === 0) {
|
|
59
|
+
if (updatedCount === 0 && createdCount === 0) {
|
|
35
60
|
console.log(chalk.yellow('⚠️ No workflow files found to update.'));
|
|
36
61
|
console.log(chalk.gray(' Run `prompter init` to create them.\n'));
|
|
37
62
|
} else {
|
|
38
|
-
|
|
63
|
+
const summary: string[] = [];
|
|
64
|
+
if (updatedCount > 0) summary.push(`${updatedCount} updated`);
|
|
65
|
+
if (createdCount > 0) summary.push(`${createdCount} created`);
|
|
66
|
+
console.log(chalk.green(`\n✅ ${summary.join(', ')}.\n`));
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
private async fileExists(filePath: string): Promise<boolean> {
|
|
71
|
+
try {
|
|
72
|
+
await fs.access(filePath);
|
|
73
|
+
return true;
|
|
74
|
+
} catch {
|
|
75
|
+
return false;
|
|
39
76
|
}
|
|
40
77
|
}
|
|
78
|
+
|
|
79
|
+
private async detectConfiguredTools(projectPath: string): Promise<string[]> {
|
|
80
|
+
const configuredTools: string[] = [];
|
|
81
|
+
const allConfigurators = registry.getAll();
|
|
82
|
+
|
|
83
|
+
for (const configurator of allConfigurators) {
|
|
84
|
+
const targets = configurator.getTargets();
|
|
85
|
+
let hasFiles = false;
|
|
86
|
+
|
|
87
|
+
for (const target of targets) {
|
|
88
|
+
const filePath = path.join(projectPath, target.path);
|
|
89
|
+
if (await this.fileExists(filePath)) {
|
|
90
|
+
hasFiles = true;
|
|
91
|
+
break;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (hasFiles) {
|
|
96
|
+
configuredTools.push(configurator.toolId);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return configuredTools;
|
|
101
|
+
}
|
|
41
102
|
}
|
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
import { SlashCommandConfigurator } from './base.js';
|
|
2
2
|
import { SlashCommandId } from '../../templates/index.js';
|
|
3
|
+
import { promises as fs } from 'fs';
|
|
4
|
+
import path from 'path';
|
|
5
|
+
import { PROMPTER_MARKERS } from '../../config.js';
|
|
3
6
|
|
|
4
7
|
const FILE_PATHS: Record<SlashCommandId, string> = {
|
|
5
|
-
enhance: '.github/prompts/prompter-enhance.md',
|
|
6
|
-
'prd-generator': '.github/prompts/prd-generator.md',
|
|
7
|
-
'epic-single': '.github/prompts/epic-single.md',
|
|
8
|
-
'story-single': '.github/prompts/story-single.md',
|
|
9
|
-
'qa-test-scenario': '.github/prompts/qa-test-scenario.md'
|
|
8
|
+
enhance: '.github/prompts/prompter-enhance.prompt.md',
|
|
9
|
+
'prd-generator': '.github/prompts/prd-generator.prompt.md',
|
|
10
|
+
'epic-single': '.github/prompts/epic-single.prompt.md',
|
|
11
|
+
'story-single': '.github/prompts/story-single.prompt.md',
|
|
12
|
+
'qa-test-scenario': '.github/prompts/qa-test-scenario.prompt.md'
|
|
10
13
|
};
|
|
11
14
|
|
|
12
15
|
const DESCRIPTIONS: Record<SlashCommandId, string> = {
|
|
@@ -29,4 +32,45 @@ export class GithubCopilotConfigurator extends SlashCommandConfigurator {
|
|
|
29
32
|
const description = DESCRIPTIONS[id];
|
|
30
33
|
return `---\ndescription: ${description}\n---`;
|
|
31
34
|
}
|
|
35
|
+
|
|
36
|
+
async generateAll(projectPath: string): Promise<string[]> {
|
|
37
|
+
const createdOrUpdated: string[] = [];
|
|
38
|
+
|
|
39
|
+
for (const target of this.getTargets()) {
|
|
40
|
+
const body = this.getBody(target.id);
|
|
41
|
+
const filePath = path.join(projectPath, target.path);
|
|
42
|
+
|
|
43
|
+
// Ensure directory exists
|
|
44
|
+
await fs.mkdir(path.dirname(filePath), { recursive: true });
|
|
45
|
+
|
|
46
|
+
const exists = await this.checkFileExists(filePath);
|
|
47
|
+
if (exists) {
|
|
48
|
+
await this.updateBody(filePath, body);
|
|
49
|
+
} else {
|
|
50
|
+
const frontmatter = this.getFrontmatter(target.id);
|
|
51
|
+
const sections: string[] = [];
|
|
52
|
+
if (frontmatter) {
|
|
53
|
+
sections.push(frontmatter.trim());
|
|
54
|
+
}
|
|
55
|
+
// Add $ARGUMENTS after frontmatter
|
|
56
|
+
sections.push('$ARGUMENTS');
|
|
57
|
+
sections.push(`${PROMPTER_MARKERS.start}\n${body}\n${PROMPTER_MARKERS.end}`);
|
|
58
|
+
const content = sections.join('\n') + '\n';
|
|
59
|
+
await fs.writeFile(filePath, content, 'utf-8');
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
createdOrUpdated.push(target.path);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return createdOrUpdated;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
private async checkFileExists(filePath: string): Promise<boolean> {
|
|
69
|
+
try {
|
|
70
|
+
await fs.access(filePath);
|
|
71
|
+
return true;
|
|
72
|
+
} catch {
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
32
76
|
}
|