workflow-agent-cli 2.6.0 → 2.8.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.
- package/dist/chunk-2WUPMAH3.js +695 -0
- package/dist/chunk-2WUPMAH3.js.map +1 -0
- package/dist/cli/index.js +537 -272
- package/dist/cli/index.js.map +1 -1
- package/dist/scripts/postinstall.js +37 -3
- package/dist/scripts/postinstall.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-LN5OAWEQ.js +0 -92
- package/dist/chunk-LN5OAWEQ.js.map +0 -1
|
@@ -0,0 +1,695 @@
|
|
|
1
|
+
// src/scripts/copilot-instructions-generator.ts
|
|
2
|
+
import { readFileSync, writeFileSync, existsSync, readdirSync, mkdirSync } from "fs";
|
|
3
|
+
import { join, basename } from "path";
|
|
4
|
+
var CUSTOM_START_MARKER = "<!-- CUSTOM START -->";
|
|
5
|
+
var CUSTOM_END_MARKER = "<!-- CUSTOM END -->";
|
|
6
|
+
var GENERATED_MARKER = "<!-- AUTO-GENERATED BY WORKFLOW-AGENT - DO NOT EDIT ABOVE THIS LINE -->";
|
|
7
|
+
function extractTitle(content) {
|
|
8
|
+
const match = content.match(/^#\s+(.+)$/m);
|
|
9
|
+
return match ? match[1].trim() : "Untitled";
|
|
10
|
+
}
|
|
11
|
+
function extractDescription(content) {
|
|
12
|
+
const lines = content.split("\n");
|
|
13
|
+
let foundTitle = false;
|
|
14
|
+
let description = "";
|
|
15
|
+
for (const line of lines) {
|
|
16
|
+
if (line.startsWith("# ")) {
|
|
17
|
+
foundTitle = true;
|
|
18
|
+
continue;
|
|
19
|
+
}
|
|
20
|
+
if (foundTitle) {
|
|
21
|
+
if (line.trim() === "" || line.startsWith(">")) {
|
|
22
|
+
if (description) break;
|
|
23
|
+
continue;
|
|
24
|
+
}
|
|
25
|
+
if (line.startsWith("#") || line.startsWith("---") || line.startsWith("##")) {
|
|
26
|
+
break;
|
|
27
|
+
}
|
|
28
|
+
description += line.trim() + " ";
|
|
29
|
+
if (description.length > 150) break;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return description.trim().slice(0, 200) + (description.length > 200 ? "..." : "");
|
|
33
|
+
}
|
|
34
|
+
function extractKeyRules(content, maxRules = 5) {
|
|
35
|
+
const rules = [];
|
|
36
|
+
const emphasisPatterns = [
|
|
37
|
+
/\*\*(?:MUST|NEVER|ALWAYS|REQUIRED)[^*]+\*\*/gi,
|
|
38
|
+
/(?:^|\n)\s*[-*]\s+\*\*[^*]+\*\*/gm
|
|
39
|
+
];
|
|
40
|
+
for (const pattern of emphasisPatterns) {
|
|
41
|
+
const matches = content.match(pattern);
|
|
42
|
+
if (matches) {
|
|
43
|
+
for (const match of matches.slice(0, 2)) {
|
|
44
|
+
const cleaned = match.replace(/\*\*/g, "").replace(/^[-*]\s*/, "").trim();
|
|
45
|
+
if (cleaned.length > 10 && cleaned.length < 150 && !rules.includes(cleaned)) {
|
|
46
|
+
rules.push(cleaned);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
const rulesSectionMatch = content.match(/##\s+(?:.*(?:Rules?|Requirements?|Guidelines?|Standards?)[^\n]*)\n([\s\S]*?)(?=\n##|\n#|$)/i);
|
|
52
|
+
if (rulesSectionMatch) {
|
|
53
|
+
const section = rulesSectionMatch[1];
|
|
54
|
+
const listItems = section.match(/^\s*[-*\d.]+\s+(.+)$/gm);
|
|
55
|
+
if (listItems) {
|
|
56
|
+
for (const item of listItems.slice(0, 3)) {
|
|
57
|
+
const cleaned = item.replace(/^[-*\d.]+\s*/, "").trim();
|
|
58
|
+
if (cleaned.length > 10 && cleaned.length < 150 && !rules.includes(cleaned)) {
|
|
59
|
+
rules.push(cleaned);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
const importantMatch = content.match(/(?:Important|Critical|Key|Essential)[:\s]+([^\n]+)/gi);
|
|
65
|
+
if (importantMatch) {
|
|
66
|
+
for (const match of importantMatch.slice(0, 2)) {
|
|
67
|
+
const cleaned = match.replace(/^(?:Important|Critical|Key|Essential)[:\s]+/i, "").trim();
|
|
68
|
+
if (cleaned.length > 10 && cleaned.length < 150 && !rules.includes(cleaned)) {
|
|
69
|
+
rules.push(cleaned);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
if (rules.length < 2) {
|
|
74
|
+
const listItems = content.match(/^\s*[-*]\s+(.+)$/gm);
|
|
75
|
+
if (listItems) {
|
|
76
|
+
for (const item of listItems.slice(0, 3)) {
|
|
77
|
+
const cleaned = item.replace(/^[-*]\s*/, "").trim();
|
|
78
|
+
if (cleaned.length > 15 && cleaned.length < 150 && !rules.includes(cleaned)) {
|
|
79
|
+
rules.push(cleaned);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return rules.slice(0, maxRules);
|
|
85
|
+
}
|
|
86
|
+
function parseGuideline(filePath) {
|
|
87
|
+
try {
|
|
88
|
+
const content = readFileSync(filePath, "utf-8");
|
|
89
|
+
const filename = basename(filePath);
|
|
90
|
+
if (filename.startsWith("_") || filename === "Guidelines.md") {
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
return {
|
|
94
|
+
filename,
|
|
95
|
+
title: extractTitle(content),
|
|
96
|
+
description: extractDescription(content),
|
|
97
|
+
keyRules: extractKeyRules(content)
|
|
98
|
+
};
|
|
99
|
+
} catch {
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
function loadWorkflowConfig(projectRoot) {
|
|
104
|
+
const configPath = join(projectRoot, "workflow.config.json");
|
|
105
|
+
if (!existsSync(configPath)) {
|
|
106
|
+
return null;
|
|
107
|
+
}
|
|
108
|
+
try {
|
|
109
|
+
const content = readFileSync(configPath, "utf-8");
|
|
110
|
+
return JSON.parse(content);
|
|
111
|
+
} catch {
|
|
112
|
+
return null;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
function extractCustomContent(existingContent) {
|
|
116
|
+
const startIndex = existingContent.indexOf(CUSTOM_START_MARKER);
|
|
117
|
+
const endIndex = existingContent.indexOf(CUSTOM_END_MARKER);
|
|
118
|
+
if (startIndex !== -1 && endIndex !== -1 && endIndex > startIndex) {
|
|
119
|
+
return existingContent.slice(
|
|
120
|
+
startIndex + CUSTOM_START_MARKER.length,
|
|
121
|
+
endIndex
|
|
122
|
+
).trim();
|
|
123
|
+
}
|
|
124
|
+
return null;
|
|
125
|
+
}
|
|
126
|
+
function generateInstructionsContent(config, guidelines, customContent) {
|
|
127
|
+
const projectName = config?.projectName || "this project";
|
|
128
|
+
const scopes = config?.scopes || [];
|
|
129
|
+
let content = `# Copilot Instructions for ${projectName}
|
|
130
|
+
|
|
131
|
+
> **This file is the Single Source of Truth for AI agents working on this codebase.**
|
|
132
|
+
> It is auto-generated from the \`guidelines/\` directory by workflow-agent-cli.
|
|
133
|
+
> Last generated: ${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}
|
|
134
|
+
|
|
135
|
+
${GENERATED_MARKER}
|
|
136
|
+
|
|
137
|
+
## Project Overview
|
|
138
|
+
|
|
139
|
+
`;
|
|
140
|
+
if (config) {
|
|
141
|
+
content += `- **Project Name**: ${projectName}
|
|
142
|
+
`;
|
|
143
|
+
content += `- **Enforcement Level**: ${config.enforcement || "strict"}
|
|
144
|
+
`;
|
|
145
|
+
if (scopes.length > 0) {
|
|
146
|
+
content += `- **Available Scopes**: ${scopes.map((s) => `\`${s.name}\``).join(", ")}
|
|
147
|
+
`;
|
|
148
|
+
}
|
|
149
|
+
content += "\n";
|
|
150
|
+
}
|
|
151
|
+
if (scopes.length > 0) {
|
|
152
|
+
content += `### Valid Scopes for Commits and Branches
|
|
153
|
+
|
|
154
|
+
| Scope | Description |
|
|
155
|
+
|-------|-------------|
|
|
156
|
+
`;
|
|
157
|
+
for (const scope of scopes.slice(0, 15)) {
|
|
158
|
+
content += `| \`${scope.name}\` | ${scope.description} |
|
|
159
|
+
`;
|
|
160
|
+
}
|
|
161
|
+
if (scopes.length > 15) {
|
|
162
|
+
content += `| ... | See workflow.config.json for all ${scopes.length} scopes |
|
|
163
|
+
`;
|
|
164
|
+
}
|
|
165
|
+
content += "\n";
|
|
166
|
+
}
|
|
167
|
+
if (guidelines.length > 0) {
|
|
168
|
+
content += `## Guidelines Summary
|
|
169
|
+
|
|
170
|
+
The following guidelines govern development on this project. **Read the linked documents for full details.**
|
|
171
|
+
|
|
172
|
+
`;
|
|
173
|
+
const mandatoryFiles = [
|
|
174
|
+
"AGENT_EDITING_INSTRUCTIONS.md",
|
|
175
|
+
"BRANCHING_STRATEGY.md",
|
|
176
|
+
"TESTING_STRATEGY.md",
|
|
177
|
+
"SINGLE_SOURCE_OF_TRUTH.md",
|
|
178
|
+
"PATTERN_ANALYSIS_WORKFLOW.md",
|
|
179
|
+
"SELF_IMPROVEMENT_MANDATE.md"
|
|
180
|
+
];
|
|
181
|
+
const sortedGuidelines = [...guidelines].sort((a, b) => {
|
|
182
|
+
const aIndex = mandatoryFiles.indexOf(a.filename);
|
|
183
|
+
const bIndex = mandatoryFiles.indexOf(b.filename);
|
|
184
|
+
if (aIndex !== -1 && bIndex !== -1) return aIndex - bIndex;
|
|
185
|
+
if (aIndex !== -1) return -1;
|
|
186
|
+
if (bIndex !== -1) return 1;
|
|
187
|
+
return a.title.localeCompare(b.title);
|
|
188
|
+
});
|
|
189
|
+
for (const guideline of sortedGuidelines) {
|
|
190
|
+
content += `### ${guideline.title}
|
|
191
|
+
|
|
192
|
+
\u{1F4C4} [See full details](../guidelines/${guideline.filename})
|
|
193
|
+
|
|
194
|
+
${guideline.description}
|
|
195
|
+
|
|
196
|
+
`;
|
|
197
|
+
if (guideline.keyRules.length > 0) {
|
|
198
|
+
content += `**Key Rules:**
|
|
199
|
+
`;
|
|
200
|
+
for (const rule of guideline.keyRules) {
|
|
201
|
+
content += `- ${rule}
|
|
202
|
+
`;
|
|
203
|
+
}
|
|
204
|
+
content += "\n";
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
content += `## Quick Reference
|
|
209
|
+
|
|
210
|
+
### Branch Naming Convention
|
|
211
|
+
\`\`\`
|
|
212
|
+
<type>/<scope>/<short-description>
|
|
213
|
+
\`\`\`
|
|
214
|
+
|
|
215
|
+
**Types**: \`feature\`, \`fix\`, \`chore\`, \`docs\`, \`refactor\`, \`test\`, \`perf\`
|
|
216
|
+
|
|
217
|
+
### Commit Message Format
|
|
218
|
+
\`\`\`
|
|
219
|
+
<type>(<scope>): <description>
|
|
220
|
+
|
|
221
|
+
[optional body]
|
|
222
|
+
|
|
223
|
+
[optional footer]
|
|
224
|
+
\`\`\`
|
|
225
|
+
|
|
226
|
+
### Before Making Changes
|
|
227
|
+
1. Read the relevant guideline document in \`guidelines/\`
|
|
228
|
+
2. Check for existing patterns in \`workflow:solution:search\`
|
|
229
|
+
3. Create an implementation plan for multi-file changes
|
|
230
|
+
4. Ensure tests are added for new functionality
|
|
231
|
+
|
|
232
|
+
### Before Committing
|
|
233
|
+
1. Run \`pnpm run workflow:verify\` to validate all changes
|
|
234
|
+
2. Ensure branch name follows convention
|
|
235
|
+
3. Ensure commit message follows conventional commits format
|
|
236
|
+
|
|
237
|
+
`;
|
|
238
|
+
content += `## Project-Specific Instructions
|
|
239
|
+
|
|
240
|
+
${CUSTOM_START_MARKER}
|
|
241
|
+
${customContent || `
|
|
242
|
+
<!--
|
|
243
|
+
Add your project-specific instructions here.
|
|
244
|
+
This section will be preserved when the file is regenerated.
|
|
245
|
+
|
|
246
|
+
Examples:
|
|
247
|
+
- Specific coding patterns unique to this project
|
|
248
|
+
- Custom review requirements
|
|
249
|
+
- Domain-specific terminology
|
|
250
|
+
- Team-specific workflows
|
|
251
|
+
-->
|
|
252
|
+
`}
|
|
253
|
+
${CUSTOM_END_MARKER}
|
|
254
|
+
|
|
255
|
+
---
|
|
256
|
+
|
|
257
|
+
*This file was generated by [workflow-agent-cli](https://www.npmjs.com/package/workflow-agent-cli). Run \`pnpm run workflow:generate-instructions\` to regenerate.*
|
|
258
|
+
`;
|
|
259
|
+
return content;
|
|
260
|
+
}
|
|
261
|
+
function generateCopilotInstructions(projectRoot, options = {}) {
|
|
262
|
+
const { force = false, silent = false } = options;
|
|
263
|
+
const guidelinesDir = join(projectRoot, "guidelines");
|
|
264
|
+
const githubDir = join(projectRoot, ".github");
|
|
265
|
+
const outputPath = join(githubDir, "copilot-instructions.md");
|
|
266
|
+
if (!existsSync(guidelinesDir)) {
|
|
267
|
+
if (!silent) {
|
|
268
|
+
}
|
|
269
|
+
return {
|
|
270
|
+
success: false,
|
|
271
|
+
filePath: null,
|
|
272
|
+
guidelinesCount: 0,
|
|
273
|
+
isNew: false,
|
|
274
|
+
preservedCustomContent: false,
|
|
275
|
+
error: "No guidelines directory found. Run 'workflow init' first."
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
const files = readdirSync(guidelinesDir).filter((f) => f.endsWith(".md"));
|
|
279
|
+
if (files.length === 0) {
|
|
280
|
+
return {
|
|
281
|
+
success: false,
|
|
282
|
+
filePath: null,
|
|
283
|
+
guidelinesCount: 0,
|
|
284
|
+
isNew: false,
|
|
285
|
+
preservedCustomContent: false,
|
|
286
|
+
error: "No markdown files found in guidelines directory."
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
const guidelines = [];
|
|
290
|
+
for (const file of files) {
|
|
291
|
+
const summary = parseGuideline(join(guidelinesDir, file));
|
|
292
|
+
if (summary) {
|
|
293
|
+
guidelines.push(summary);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
const config = loadWorkflowConfig(projectRoot);
|
|
297
|
+
let customContent = null;
|
|
298
|
+
let isNew = true;
|
|
299
|
+
if (existsSync(outputPath)) {
|
|
300
|
+
isNew = false;
|
|
301
|
+
const existingContent = readFileSync(outputPath, "utf-8");
|
|
302
|
+
customContent = extractCustomContent(existingContent);
|
|
303
|
+
}
|
|
304
|
+
const content = generateInstructionsContent(config, guidelines, customContent);
|
|
305
|
+
if (!existsSync(githubDir)) {
|
|
306
|
+
mkdirSync(githubDir, { recursive: true });
|
|
307
|
+
}
|
|
308
|
+
writeFileSync(outputPath, content, "utf-8");
|
|
309
|
+
return {
|
|
310
|
+
success: true,
|
|
311
|
+
filePath: outputPath,
|
|
312
|
+
guidelinesCount: guidelines.length,
|
|
313
|
+
isNew,
|
|
314
|
+
preservedCustomContent: customContent !== null
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
// src/scripts/workflow-scripts.ts
|
|
319
|
+
var WORKFLOW_SCRIPTS = {
|
|
320
|
+
// Core Commands
|
|
321
|
+
"workflow:init": "workflow-agent init",
|
|
322
|
+
"workflow:validate": "workflow-agent validate",
|
|
323
|
+
"workflow:config": "workflow-agent config",
|
|
324
|
+
"workflow:suggest": "workflow-agent suggest",
|
|
325
|
+
"workflow:setup": "workflow-agent setup",
|
|
326
|
+
"workflow:doctor": "workflow-agent doctor",
|
|
327
|
+
// Scope Commands
|
|
328
|
+
"workflow:scope:create": "workflow-agent scope:create",
|
|
329
|
+
"workflow:scope:migrate": "workflow-agent scope:migrate",
|
|
330
|
+
// Verification & Auto-Setup
|
|
331
|
+
"workflow:verify": "workflow-agent verify",
|
|
332
|
+
"workflow:verify:fix": "workflow-agent verify --fix",
|
|
333
|
+
"workflow:auto-setup": "workflow-agent auto-setup",
|
|
334
|
+
// Learning System Commands
|
|
335
|
+
"workflow:learn": "workflow-agent learn:list",
|
|
336
|
+
"workflow:learn:record": "workflow-agent learn:record",
|
|
337
|
+
"workflow:learn:list": "workflow-agent learn:list",
|
|
338
|
+
"workflow:learn:apply": "workflow-agent learn:apply",
|
|
339
|
+
"workflow:learn:sync": "workflow-agent learn:sync",
|
|
340
|
+
"workflow:learn:config": "workflow-agent learn:config",
|
|
341
|
+
"workflow:learn:deprecate": "workflow-agent learn:deprecate",
|
|
342
|
+
"workflow:learn:stats": "workflow-agent learn:stats",
|
|
343
|
+
// Solution Pattern Commands
|
|
344
|
+
"workflow:solution": "workflow-agent solution:list",
|
|
345
|
+
"workflow:solution:capture": "workflow-agent solution:capture",
|
|
346
|
+
"workflow:solution:search": "workflow-agent solution:search",
|
|
347
|
+
"workflow:solution:list": "workflow-agent solution:list",
|
|
348
|
+
"workflow:solution:apply": "workflow-agent solution:apply",
|
|
349
|
+
"workflow:solution:deprecate": "workflow-agent solution:deprecate",
|
|
350
|
+
"workflow:solution:stats": "workflow-agent solution:stats",
|
|
351
|
+
// Advisory Board Commands
|
|
352
|
+
"workflow:advisory": "workflow-agent advisory",
|
|
353
|
+
"workflow:advisory:quick": "workflow-agent advisory --depth quick",
|
|
354
|
+
"workflow:advisory:standard": "workflow-agent advisory --depth standard",
|
|
355
|
+
"workflow:advisory:comprehensive": "workflow-agent advisory --depth comprehensive",
|
|
356
|
+
"workflow:advisory:executive": "workflow-agent advisory --depth executive",
|
|
357
|
+
"workflow:advisory:ci": "workflow-agent advisory --ci",
|
|
358
|
+
// AI Agent Instructions
|
|
359
|
+
"workflow:generate-instructions": "workflow-agent generate-instructions",
|
|
360
|
+
// Template Management
|
|
361
|
+
"workflow:update-templates": "workflow-agent update-templates",
|
|
362
|
+
"workflow:update-templates:force": "workflow-agent update-templates --force"
|
|
363
|
+
};
|
|
364
|
+
var SCRIPT_CATEGORIES = {
|
|
365
|
+
"Core Commands": [
|
|
366
|
+
"workflow:init",
|
|
367
|
+
"workflow:validate",
|
|
368
|
+
"workflow:config",
|
|
369
|
+
"workflow:suggest",
|
|
370
|
+
"workflow:setup",
|
|
371
|
+
"workflow:doctor"
|
|
372
|
+
],
|
|
373
|
+
"Scope Commands": ["workflow:scope:create", "workflow:scope:migrate"],
|
|
374
|
+
Verification: [
|
|
375
|
+
"workflow:verify",
|
|
376
|
+
"workflow:verify:fix",
|
|
377
|
+
"workflow:auto-setup"
|
|
378
|
+
],
|
|
379
|
+
"Learning System": [
|
|
380
|
+
"workflow:learn",
|
|
381
|
+
"workflow:learn:record",
|
|
382
|
+
"workflow:learn:list",
|
|
383
|
+
"workflow:learn:apply",
|
|
384
|
+
"workflow:learn:sync",
|
|
385
|
+
"workflow:learn:config",
|
|
386
|
+
"workflow:learn:deprecate",
|
|
387
|
+
"workflow:learn:stats"
|
|
388
|
+
],
|
|
389
|
+
"Solution Patterns": [
|
|
390
|
+
"workflow:solution",
|
|
391
|
+
"workflow:solution:capture",
|
|
392
|
+
"workflow:solution:search",
|
|
393
|
+
"workflow:solution:list",
|
|
394
|
+
"workflow:solution:apply",
|
|
395
|
+
"workflow:solution:deprecate",
|
|
396
|
+
"workflow:solution:stats"
|
|
397
|
+
],
|
|
398
|
+
"Advisory Board": [
|
|
399
|
+
"workflow:advisory",
|
|
400
|
+
"workflow:advisory:quick",
|
|
401
|
+
"workflow:advisory:standard",
|
|
402
|
+
"workflow:advisory:comprehensive",
|
|
403
|
+
"workflow:advisory:executive",
|
|
404
|
+
"workflow:advisory:ci"
|
|
405
|
+
],
|
|
406
|
+
"AI Agent Instructions": [
|
|
407
|
+
"workflow:generate-instructions"
|
|
408
|
+
],
|
|
409
|
+
"Template Management": [
|
|
410
|
+
"workflow:update-templates",
|
|
411
|
+
"workflow:update-templates:force"
|
|
412
|
+
]
|
|
413
|
+
};
|
|
414
|
+
var TOTAL_SCRIPTS = Object.keys(WORKFLOW_SCRIPTS).length;
|
|
415
|
+
|
|
416
|
+
// src/scripts/template-installer.ts
|
|
417
|
+
import { existsSync as existsSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2 } from "fs";
|
|
418
|
+
import { readdirSync as readdirSync2 } from "fs";
|
|
419
|
+
import { join as join2, basename as basename2 } from "path";
|
|
420
|
+
|
|
421
|
+
// src/templates/metadata.ts
|
|
422
|
+
var templateMetadata = {
|
|
423
|
+
"AGENT_EDITING_INSTRUCTIONS.md": {
|
|
424
|
+
filename: "AGENT_EDITING_INSTRUCTIONS.md",
|
|
425
|
+
displayName: "Agent Editing Instructions",
|
|
426
|
+
mandatory: true,
|
|
427
|
+
category: "workflow",
|
|
428
|
+
validators: ["implementation-plan"],
|
|
429
|
+
description: "Core rules for AI agents: implementation plans, coding standards, architecture"
|
|
430
|
+
},
|
|
431
|
+
"BRANCHING_STRATEGY.md": {
|
|
432
|
+
filename: "BRANCHING_STRATEGY.md",
|
|
433
|
+
displayName: "Branching Strategy",
|
|
434
|
+
mandatory: true,
|
|
435
|
+
category: "workflow",
|
|
436
|
+
validators: ["branch-name", "pr-title"],
|
|
437
|
+
description: "Git branch naming conventions, PR requirements, merge policies"
|
|
438
|
+
},
|
|
439
|
+
"TESTING_STRATEGY.md": {
|
|
440
|
+
filename: "TESTING_STRATEGY.md",
|
|
441
|
+
displayName: "Testing Strategy",
|
|
442
|
+
mandatory: true,
|
|
443
|
+
category: "development",
|
|
444
|
+
validators: ["test-coverage"],
|
|
445
|
+
description: "Testing pyramid, Vitest/Playwright patterns, when tests are required"
|
|
446
|
+
},
|
|
447
|
+
"SELF_IMPROVEMENT_MANDATE.md": {
|
|
448
|
+
filename: "SELF_IMPROVEMENT_MANDATE.md",
|
|
449
|
+
displayName: "Self-Improvement Mandate",
|
|
450
|
+
mandatory: true,
|
|
451
|
+
category: "workflow",
|
|
452
|
+
validators: [],
|
|
453
|
+
description: "Continuous improvement tracking, changelog requirements"
|
|
454
|
+
},
|
|
455
|
+
"PATTERN_ANALYSIS_WORKFLOW.md": {
|
|
456
|
+
filename: "PATTERN_ANALYSIS_WORKFLOW.md",
|
|
457
|
+
displayName: "Pattern Analysis Workflow",
|
|
458
|
+
mandatory: true,
|
|
459
|
+
category: "workflow",
|
|
460
|
+
validators: [],
|
|
461
|
+
description: "AI agent workflow for analyzing codebases, extracting patterns, and updating the central pattern store"
|
|
462
|
+
},
|
|
463
|
+
"SINGLE_SOURCE_OF_TRUTH.md": {
|
|
464
|
+
filename: "SINGLE_SOURCE_OF_TRUTH.md",
|
|
465
|
+
displayName: "Single Source of Truth",
|
|
466
|
+
mandatory: true,
|
|
467
|
+
category: "workflow",
|
|
468
|
+
validators: [],
|
|
469
|
+
description: "Canonical code locations, service patterns, avoiding duplication"
|
|
470
|
+
},
|
|
471
|
+
"COMPONENT_LIBRARY.md": {
|
|
472
|
+
filename: "COMPONENT_LIBRARY.md",
|
|
473
|
+
displayName: "Component Library",
|
|
474
|
+
mandatory: false,
|
|
475
|
+
category: "development",
|
|
476
|
+
validators: [],
|
|
477
|
+
description: "UI component patterns, design tokens, decision tree"
|
|
478
|
+
},
|
|
479
|
+
"DEPLOYMENT_STRATEGY.md": {
|
|
480
|
+
filename: "DEPLOYMENT_STRATEGY.md",
|
|
481
|
+
displayName: "Deployment Strategy",
|
|
482
|
+
mandatory: false,
|
|
483
|
+
category: "development",
|
|
484
|
+
validators: [],
|
|
485
|
+
description: "Deployment workflow, environments, migrations, rollback"
|
|
486
|
+
},
|
|
487
|
+
"LIBRARY_INVENTORY.md": {
|
|
488
|
+
filename: "LIBRARY_INVENTORY.md",
|
|
489
|
+
displayName: "Library Inventory",
|
|
490
|
+
mandatory: false,
|
|
491
|
+
category: "development",
|
|
492
|
+
validators: [],
|
|
493
|
+
description: "Dependency catalog, approved libraries, new library process"
|
|
494
|
+
},
|
|
495
|
+
"SCOPE_CREATION_WORKFLOW.md": {
|
|
496
|
+
filename: "SCOPE_CREATION_WORKFLOW.md",
|
|
497
|
+
displayName: "Scope Creation Workflow",
|
|
498
|
+
mandatory: false,
|
|
499
|
+
category: "workflow",
|
|
500
|
+
validators: [],
|
|
501
|
+
description: "Workflow for AI agents creating custom scopes"
|
|
502
|
+
},
|
|
503
|
+
"CUSTOM_SCOPE_TEMPLATE.md": {
|
|
504
|
+
filename: "CUSTOM_SCOPE_TEMPLATE.md",
|
|
505
|
+
displayName: "Custom Scope Template",
|
|
506
|
+
mandatory: false,
|
|
507
|
+
category: "workflow",
|
|
508
|
+
validators: [],
|
|
509
|
+
description: "Template for defining custom scope packages"
|
|
510
|
+
},
|
|
511
|
+
"PROJECT_TEMPLATE_README.md": {
|
|
512
|
+
filename: "PROJECT_TEMPLATE_README.md",
|
|
513
|
+
displayName: "Project Template README",
|
|
514
|
+
mandatory: false,
|
|
515
|
+
category: "documentation",
|
|
516
|
+
validators: [],
|
|
517
|
+
description: "Meta-document describing project structure"
|
|
518
|
+
},
|
|
519
|
+
"Guidelines.md": {
|
|
520
|
+
filename: "Guidelines.md",
|
|
521
|
+
displayName: "Custom Guidelines",
|
|
522
|
+
mandatory: false,
|
|
523
|
+
category: "documentation",
|
|
524
|
+
validators: [],
|
|
525
|
+
description: "Placeholder for custom user guidelines"
|
|
526
|
+
}
|
|
527
|
+
};
|
|
528
|
+
function getMandatoryTemplates() {
|
|
529
|
+
return Object.values(templateMetadata).filter((t) => t.mandatory);
|
|
530
|
+
}
|
|
531
|
+
function getMandatoryTemplateFilenames() {
|
|
532
|
+
return getMandatoryTemplates().map((t) => t.filename);
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
// src/scripts/template-installer.ts
|
|
536
|
+
function getProjectName(projectRoot) {
|
|
537
|
+
try {
|
|
538
|
+
const pkgPath = join2(projectRoot, "package.json");
|
|
539
|
+
if (existsSync2(pkgPath)) {
|
|
540
|
+
const pkg = JSON.parse(readFileSync2(pkgPath, "utf-8"));
|
|
541
|
+
return pkg.name || basename2(projectRoot);
|
|
542
|
+
}
|
|
543
|
+
} catch {
|
|
544
|
+
}
|
|
545
|
+
return basename2(projectRoot);
|
|
546
|
+
}
|
|
547
|
+
function renderTemplate(template, context) {
|
|
548
|
+
return template.replace(/\{\{(\w+)\}\}/g, (match, key) => {
|
|
549
|
+
return context[key] ?? match;
|
|
550
|
+
});
|
|
551
|
+
}
|
|
552
|
+
function buildDefaultContext(projectRoot) {
|
|
553
|
+
const projectName = getProjectName(projectRoot);
|
|
554
|
+
return {
|
|
555
|
+
projectName,
|
|
556
|
+
framework: "unknown",
|
|
557
|
+
scopes: "feat, fix, docs, refactor, test, chore",
|
|
558
|
+
scopeList: `- **feat** - New features
|
|
559
|
+
- **fix** - Bug fixes
|
|
560
|
+
- **docs** - Documentation
|
|
561
|
+
- **refactor** - Code refactoring
|
|
562
|
+
- **test** - Testing
|
|
563
|
+
- **chore** - Maintenance`,
|
|
564
|
+
pathStructure: "N/A",
|
|
565
|
+
enforcement: "strict",
|
|
566
|
+
year: (/* @__PURE__ */ new Date()).getFullYear().toString()
|
|
567
|
+
};
|
|
568
|
+
}
|
|
569
|
+
function findTemplatesDirectory(callerDirname) {
|
|
570
|
+
const possiblePaths = [
|
|
571
|
+
join2(callerDirname, "../../templates"),
|
|
572
|
+
join2(callerDirname, "../templates"),
|
|
573
|
+
join2(callerDirname, "templates")
|
|
574
|
+
];
|
|
575
|
+
for (const templatePath of possiblePaths) {
|
|
576
|
+
if (existsSync2(templatePath)) {
|
|
577
|
+
return templatePath;
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
return null;
|
|
581
|
+
}
|
|
582
|
+
function installMandatoryTemplates(projectRoot, templatesDir, options = {}) {
|
|
583
|
+
const {
|
|
584
|
+
force = false,
|
|
585
|
+
skipIfExists = true,
|
|
586
|
+
silent = false,
|
|
587
|
+
mandatoryOnly = true
|
|
588
|
+
} = options;
|
|
589
|
+
const result = {
|
|
590
|
+
success: true,
|
|
591
|
+
installed: [],
|
|
592
|
+
skipped: [],
|
|
593
|
+
updated: [],
|
|
594
|
+
errors: [],
|
|
595
|
+
guidelinesExisted: false
|
|
596
|
+
};
|
|
597
|
+
const guidelinesDir = join2(projectRoot, "guidelines");
|
|
598
|
+
result.guidelinesExisted = existsSync2(guidelinesDir);
|
|
599
|
+
if (result.guidelinesExisted && skipIfExists && !force) {
|
|
600
|
+
if (!silent) {
|
|
601
|
+
console.log(" Guidelines directory already exists, skipping templates");
|
|
602
|
+
}
|
|
603
|
+
return result;
|
|
604
|
+
}
|
|
605
|
+
const mandatoryFiles = getMandatoryTemplateFilenames();
|
|
606
|
+
if (!existsSync2(templatesDir)) {
|
|
607
|
+
result.success = false;
|
|
608
|
+
result.errors.push(`Templates directory not found: ${templatesDir}`);
|
|
609
|
+
return result;
|
|
610
|
+
}
|
|
611
|
+
let availableFiles;
|
|
612
|
+
try {
|
|
613
|
+
availableFiles = readdirSync2(templatesDir).filter((f) => f.endsWith(".md"));
|
|
614
|
+
} catch (error) {
|
|
615
|
+
result.success = false;
|
|
616
|
+
result.errors.push(`Failed to read templates directory: ${error}`);
|
|
617
|
+
return result;
|
|
618
|
+
}
|
|
619
|
+
const filesToInstall = mandatoryOnly ? availableFiles.filter((f) => mandatoryFiles.includes(f)) : availableFiles;
|
|
620
|
+
if (filesToInstall.length === 0) {
|
|
621
|
+
result.success = false;
|
|
622
|
+
result.errors.push("No template files found to install");
|
|
623
|
+
return result;
|
|
624
|
+
}
|
|
625
|
+
const context = buildDefaultContext(projectRoot);
|
|
626
|
+
try {
|
|
627
|
+
mkdirSync2(guidelinesDir, { recursive: true });
|
|
628
|
+
} catch (error) {
|
|
629
|
+
result.success = false;
|
|
630
|
+
result.errors.push(`Failed to create guidelines directory: ${error}`);
|
|
631
|
+
return result;
|
|
632
|
+
}
|
|
633
|
+
for (const filename of filesToInstall) {
|
|
634
|
+
const sourcePath = join2(templatesDir, filename);
|
|
635
|
+
const destPath = join2(guidelinesDir, filename);
|
|
636
|
+
const fileExists = existsSync2(destPath);
|
|
637
|
+
if (fileExists && !force) {
|
|
638
|
+
result.skipped.push(filename);
|
|
639
|
+
continue;
|
|
640
|
+
}
|
|
641
|
+
try {
|
|
642
|
+
const template = readFileSync2(sourcePath, "utf-8");
|
|
643
|
+
const rendered = renderTemplate(template, context);
|
|
644
|
+
writeFileSync2(destPath, rendered, "utf-8");
|
|
645
|
+
if (fileExists) {
|
|
646
|
+
result.updated.push(filename);
|
|
647
|
+
} else {
|
|
648
|
+
result.installed.push(filename);
|
|
649
|
+
}
|
|
650
|
+
} catch (error) {
|
|
651
|
+
result.errors.push(`Failed to install ${filename}: ${error}`);
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
if (!silent) {
|
|
655
|
+
if (result.installed.length > 0) {
|
|
656
|
+
console.log(
|
|
657
|
+
`
|
|
658
|
+
\u2713 Installed ${result.installed.length} guideline templates:`
|
|
659
|
+
);
|
|
660
|
+
for (const file of result.installed) {
|
|
661
|
+
console.log(` - ${file}`);
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
if (result.updated.length > 0) {
|
|
665
|
+
console.log(`
|
|
666
|
+
\u2713 Updated ${result.updated.length} guideline templates:`);
|
|
667
|
+
for (const file of result.updated) {
|
|
668
|
+
console.log(` - ${file}`);
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
return result;
|
|
673
|
+
}
|
|
674
|
+
function updateTemplates(projectRoot, templatesDir, options = {}) {
|
|
675
|
+
return installMandatoryTemplates(projectRoot, templatesDir, {
|
|
676
|
+
...options,
|
|
677
|
+
skipIfExists: false,
|
|
678
|
+
// Don't skip - we want to update
|
|
679
|
+
mandatoryOnly: false
|
|
680
|
+
// Install all templates during update
|
|
681
|
+
});
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
export {
|
|
685
|
+
generateCopilotInstructions,
|
|
686
|
+
WORKFLOW_SCRIPTS,
|
|
687
|
+
SCRIPT_CATEGORIES,
|
|
688
|
+
TOTAL_SCRIPTS,
|
|
689
|
+
templateMetadata,
|
|
690
|
+
getMandatoryTemplateFilenames,
|
|
691
|
+
findTemplatesDirectory,
|
|
692
|
+
installMandatoryTemplates,
|
|
693
|
+
updateTemplates
|
|
694
|
+
};
|
|
695
|
+
//# sourceMappingURL=chunk-2WUPMAH3.js.map
|