workflow-agent-cli 2.4.3 → 2.7.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/README.md +48 -15
- package/dist/{chunk-WXXFUPYO.js → chunk-6NWQLGHI.js} +3 -1
- package/dist/{chunk-RDVTKGQV.js → chunk-DEAF7P4L.js} +36 -2
- package/dist/chunk-DEAF7P4L.js.map +1 -0
- package/dist/chunk-HKRWHFVI.js +415 -0
- package/dist/chunk-HKRWHFVI.js.map +1 -0
- package/dist/cli/index.js +3308 -468
- package/dist/cli/index.js.map +1 -1
- package/dist/config/index.d.ts +2 -2
- package/dist/config/index.js +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2 -2
- package/dist/{schema-OJg7YAI_.d.ts → schema-D0zTM83x.d.ts} +111 -0
- package/dist/scripts/postinstall.js +51 -71
- package/dist/scripts/postinstall.js.map +1 -1
- package/dist/validators/index.d.ts +1 -1
- package/package.json +34 -2
- package/templates/PATTERN_ANALYSIS_WORKFLOW.md +72 -55
- package/dist/chunk-RDVTKGQV.js.map +0 -1
- /package/dist/{chunk-WXXFUPYO.js.map → chunk-6NWQLGHI.js.map} +0 -0
package/README.md
CHANGED
|
@@ -61,33 +61,66 @@ pnpm add -D workflow-agent-cli
|
|
|
61
61
|
yarn add -D workflow-agent-cli
|
|
62
62
|
```
|
|
63
63
|
|
|
64
|
-
**
|
|
64
|
+
> ⚠️ **pnpm users:** pnpm blocks postinstall scripts by default. After installation, run the setup command to add workflow scripts to your package.json:
|
|
65
|
+
>
|
|
66
|
+
> ```bash
|
|
67
|
+
> pnpm workflow-agent setup
|
|
68
|
+
> ```
|
|
65
69
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
```bash
|
|
69
|
-
# If using pnpm or npm locally:
|
|
70
|
-
pnpm workflow-agent setup
|
|
71
|
-
# or
|
|
72
|
-
npx workflow-agent setup
|
|
73
|
-
|
|
74
|
-
# If installed globally:
|
|
75
|
-
workflow-agent setup
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
This adds these scripts to your `package.json`:
|
|
70
|
+
On install (npm/yarn) or after running setup (pnpm), **31 workflow scripts** are automatically added to your `package.json`:
|
|
79
71
|
|
|
80
72
|
```json
|
|
81
73
|
{
|
|
82
74
|
"scripts": {
|
|
75
|
+
// Core Commands
|
|
83
76
|
"workflow:init": "workflow-agent init",
|
|
84
77
|
"workflow:validate": "workflow-agent validate",
|
|
78
|
+
"workflow:config": "workflow-agent config",
|
|
85
79
|
"workflow:suggest": "workflow-agent suggest",
|
|
86
|
-
"workflow:
|
|
80
|
+
"workflow:setup": "workflow-agent setup",
|
|
81
|
+
"workflow:doctor": "workflow-agent doctor",
|
|
82
|
+
|
|
83
|
+
// Scope Commands
|
|
84
|
+
"workflow:scope:create": "workflow-agent scope:create",
|
|
85
|
+
"workflow:scope:migrate": "workflow-agent scope:migrate",
|
|
86
|
+
|
|
87
|
+
// Verification
|
|
88
|
+
"workflow:verify": "workflow-agent verify",
|
|
89
|
+
"workflow:verify:fix": "workflow-agent verify --fix",
|
|
90
|
+
"workflow:auto-setup": "workflow-agent auto-setup",
|
|
91
|
+
|
|
92
|
+
// Learning System
|
|
93
|
+
"workflow:learn": "workflow-agent learn:list",
|
|
94
|
+
"workflow:learn:record": "workflow-agent learn:record",
|
|
95
|
+
"workflow:learn:list": "workflow-agent learn:list",
|
|
96
|
+
"workflow:learn:apply": "workflow-agent learn:apply",
|
|
97
|
+
"workflow:learn:sync": "workflow-agent learn:sync",
|
|
98
|
+
"workflow:learn:config": "workflow-agent learn:config",
|
|
99
|
+
"workflow:learn:deprecate": "workflow-agent learn:deprecate",
|
|
100
|
+
"workflow:learn:stats": "workflow-agent learn:stats",
|
|
101
|
+
|
|
102
|
+
// Solution Patterns
|
|
103
|
+
"workflow:solution": "workflow-agent solution:list",
|
|
104
|
+
"workflow:solution:capture": "workflow-agent solution:capture",
|
|
105
|
+
"workflow:solution:search": "workflow-agent solution:search",
|
|
106
|
+
"workflow:solution:list": "workflow-agent solution:list",
|
|
107
|
+
"workflow:solution:apply": "workflow-agent solution:apply",
|
|
108
|
+
"workflow:solution:deprecate": "workflow-agent solution:deprecate",
|
|
109
|
+
"workflow:solution:stats": "workflow-agent solution:stats",
|
|
110
|
+
|
|
111
|
+
// Advisory Board
|
|
112
|
+
"workflow:advisory": "workflow-agent advisory",
|
|
113
|
+
"workflow:advisory:quick": "workflow-agent advisory --depth quick",
|
|
114
|
+
"workflow:advisory:standard": "workflow-agent advisory --depth standard",
|
|
115
|
+
"workflow:advisory:comprehensive": "workflow-agent advisory --depth comprehensive",
|
|
116
|
+
"workflow:advisory:executive": "workflow-agent advisory --depth executive",
|
|
117
|
+
"workflow:advisory:ci": "workflow-agent advisory --ci"
|
|
87
118
|
}
|
|
88
119
|
}
|
|
89
120
|
```
|
|
90
121
|
|
|
122
|
+
**Note:** When you update the package, any new scripts from newer versions are automatically added.
|
|
123
|
+
|
|
91
124
|
---
|
|
92
125
|
|
|
93
126
|
## 📖 Quick Start
|
|
@@ -1430,9 +1430,11 @@ export {
|
|
|
1430
1430
|
runAllChecks,
|
|
1431
1431
|
hasUncommittedChanges,
|
|
1432
1432
|
stageAllChanges,
|
|
1433
|
+
detectPackageManager,
|
|
1434
|
+
isMonorepo,
|
|
1433
1435
|
analyzeProject,
|
|
1434
1436
|
generateAuditReport,
|
|
1435
1437
|
formatAuditReport,
|
|
1436
1438
|
runAllSetups
|
|
1437
1439
|
};
|
|
1438
|
-
//# sourceMappingURL=chunk-
|
|
1440
|
+
//# sourceMappingURL=chunk-6NWQLGHI.js.map
|
|
@@ -82,6 +82,39 @@ var GuidelinesConfigSchema = z.object({
|
|
|
82
82
|
additionalMandatory: z.array(z.string()).optional(),
|
|
83
83
|
optionalOverrides: z.array(z.string()).optional()
|
|
84
84
|
});
|
|
85
|
+
var AdvisoryDepthSchema = z.enum([
|
|
86
|
+
"executive",
|
|
87
|
+
"quick",
|
|
88
|
+
"standard",
|
|
89
|
+
"comprehensive"
|
|
90
|
+
]);
|
|
91
|
+
var AdvisoryQuestionSchema = z.object({
|
|
92
|
+
category: z.string(),
|
|
93
|
+
question: z.string(),
|
|
94
|
+
context: z.string().optional(),
|
|
95
|
+
priority: z.enum(["high", "medium", "low"]).optional()
|
|
96
|
+
});
|
|
97
|
+
var AdvisoryConfigSchema = z.object({
|
|
98
|
+
enabled: z.boolean().default(true),
|
|
99
|
+
defaultDepth: AdvisoryDepthSchema.default("standard"),
|
|
100
|
+
outputDir: z.string().default("docs/advisory"),
|
|
101
|
+
customQuestions: z.array(AdvisoryQuestionSchema).optional(),
|
|
102
|
+
riskThresholds: z.object({
|
|
103
|
+
high: z.number().default(0.7),
|
|
104
|
+
medium: z.number().default(0.4),
|
|
105
|
+
low: z.number().default(0.2)
|
|
106
|
+
}).optional(),
|
|
107
|
+
categories: z.array(z.string()).default([
|
|
108
|
+
"Technology Decisions",
|
|
109
|
+
"Package Utilization",
|
|
110
|
+
"Platform Strategy",
|
|
111
|
+
"Business Alignment",
|
|
112
|
+
"Technical Debt",
|
|
113
|
+
"Growth Opportunities"
|
|
114
|
+
]),
|
|
115
|
+
excludePatterns: z.array(z.string()).optional(),
|
|
116
|
+
includeHealthMetrics: z.boolean().default(false)
|
|
117
|
+
});
|
|
85
118
|
var WorkflowConfigSchema = z.object({
|
|
86
119
|
projectName: z.string().min(1),
|
|
87
120
|
scopes: z.array(ScopeSchema).min(1),
|
|
@@ -94,7 +127,8 @@ var WorkflowConfigSchema = z.object({
|
|
|
94
127
|
syncRemote: z.string().optional(),
|
|
95
128
|
ci: CIConfigSchema.optional(),
|
|
96
129
|
hooks: HooksConfigSchema.optional(),
|
|
97
|
-
guidelines: GuidelinesConfigSchema.optional()
|
|
130
|
+
guidelines: GuidelinesConfigSchema.optional(),
|
|
131
|
+
advisory: AdvisoryConfigSchema.optional()
|
|
98
132
|
});
|
|
99
133
|
function validateScopeDefinitions(scopes) {
|
|
100
134
|
const errors = [];
|
|
@@ -162,4 +196,4 @@ export {
|
|
|
162
196
|
loadConfig,
|
|
163
197
|
hasConfig
|
|
164
198
|
};
|
|
165
|
-
//# sourceMappingURL=chunk-
|
|
199
|
+
//# sourceMappingURL=chunk-DEAF7P4L.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/config/index.ts","../src/config/schema.ts"],"sourcesContent":["import { cosmiconfig } from \"cosmiconfig\";\nimport { WorkflowConfig, WorkflowConfigSchema } from \"./schema.js\";\nimport { join } from \"path\";\nimport { existsSync } from \"fs\";\n\nconst explorer = cosmiconfig(\"workflow\", {\n searchPlaces: [\n \"workflow.config.ts\",\n \"workflow.config.js\",\n \"workflow.config.json\",\n \".workflowrc\",\n \".workflowrc.json\",\n \"package.json\",\n ],\n});\n\nexport async function loadConfig(\n cwd: string = process.cwd(),\n): Promise<WorkflowConfig | null> {\n try {\n const result = await explorer.search(cwd);\n\n if (!result || !result.config) {\n return null;\n }\n\n // Validate config against schema\n const validated = WorkflowConfigSchema.parse(result.config);\n return validated;\n } catch (error) {\n if (error instanceof Error) {\n throw new Error(`Failed to load workflow config: ${error.message}`);\n }\n throw error;\n }\n}\n\nexport function hasConfig(cwd: string = process.cwd()): boolean {\n const configPaths = [\n \"workflow.config.ts\",\n \"workflow.config.js\",\n \"workflow.config.json\",\n \".workflowrc\",\n \".workflowrc.json\",\n ];\n\n return configPaths.some((path) => existsSync(join(cwd, path)));\n}\n\nexport {\n WorkflowConfig,\n WorkflowConfigSchema,\n Scope,\n BranchType,\n ConventionalType,\n} from \"./schema.js\";\n","import { z } from \"zod\";\n\n// Reserved scope names that cannot be used\nconst RESERVED_SCOPE_NAMES = [\n \"init\",\n \"create\",\n \"build\",\n \"test\",\n \"config\",\n \"docs\",\n \"ci\",\n \"deps\",\n];\n\nexport const ScopeSchema = z.object({\n name: z\n .string()\n .min(1)\n .max(32, \"Scope name must be 32 characters or less\")\n .regex(\n /^[a-z0-9-]+$/,\n \"Scope name must be lowercase alphanumeric with hyphens\",\n )\n .refine((name) => !RESERVED_SCOPE_NAMES.includes(name), {\n message: `Scope name cannot be a reserved word: ${RESERVED_SCOPE_NAMES.join(\", \")}`,\n }),\n description: z\n .string()\n .min(10, \"Scope description must be at least 10 characters\"),\n emoji: z.string().optional(),\n category: z\n .enum([\n \"auth\",\n \"features\",\n \"infrastructure\",\n \"documentation\",\n \"testing\",\n \"performance\",\n \"other\",\n ])\n .optional(),\n});\n\nexport const BranchTypeSchema = z.enum([\n \"feature\",\n \"bugfix\",\n \"hotfix\",\n \"chore\",\n \"refactor\",\n \"docs\",\n \"test\",\n \"release\",\n]);\n\nexport const ConventionalTypeSchema = z.enum([\n \"feat\",\n \"fix\",\n \"refactor\",\n \"chore\",\n \"docs\",\n \"test\",\n \"perf\",\n \"style\",\n \"ci\",\n \"build\",\n \"revert\",\n]);\n\nexport const EnforcementLevelSchema = z.enum([\n \"strict\",\n \"advisory\",\n \"learning\",\n]);\n\nexport const AnalyticsConfigSchema = z.object({\n enabled: z.boolean().default(false),\n shareAnonymous: z.boolean().default(false),\n});\n\nexport const CIConfigSchema = z.object({\n provider: z.enum([\"github\", \"gitlab\", \"azure\"]).default(\"github\"),\n nodeVersions: z.array(z.string()).optional(),\n defaultBranch: z.string().default(\"main\"),\n checks: z\n .array(z.enum([\"lint\", \"typecheck\", \"format\", \"build\", \"test\"]))\n .optional(),\n});\n\nexport const HooksConfigSchema = z.object({\n preCommit: z.array(z.string()).optional(),\n commitMsg: z.array(z.string()).optional(),\n prePush: z.array(z.string()).optional(),\n});\n\nexport const GuidelinesConfigSchema = z.object({\n mandatoryTemplates: z.array(z.string()).optional(),\n optionalTemplates: z.array(z.string()).optional(),\n customTemplatesDir: z.string().optional(),\n additionalMandatory: z.array(z.string()).optional(),\n optionalOverrides: z.array(z.string()).optional(),\n});\n\nexport const AdvisoryDepthSchema = z.enum([\n \"executive\",\n \"quick\",\n \"standard\",\n \"comprehensive\",\n]);\n\nexport const AdvisoryQuestionSchema = z.object({\n category: z.string(),\n question: z.string(),\n context: z.string().optional(),\n priority: z.enum([\"high\", \"medium\", \"low\"]).optional(),\n});\n\nexport const AdvisoryConfigSchema = z.object({\n enabled: z.boolean().default(true),\n defaultDepth: AdvisoryDepthSchema.default(\"standard\"),\n outputDir: z.string().default(\"docs/advisory\"),\n customQuestions: z.array(AdvisoryQuestionSchema).optional(),\n riskThresholds: z\n .object({\n high: z.number().default(0.7),\n medium: z.number().default(0.4),\n low: z.number().default(0.2),\n })\n .optional(),\n categories: z\n .array(z.string())\n .default([\n \"Technology Decisions\",\n \"Package Utilization\",\n \"Platform Strategy\",\n \"Business Alignment\",\n \"Technical Debt\",\n \"Growth Opportunities\",\n ]),\n excludePatterns: z.array(z.string()).optional(),\n includeHealthMetrics: z.boolean().default(false),\n});\n\nexport const WorkflowConfigSchema = z.object({\n projectName: z.string().min(1),\n scopes: z.array(ScopeSchema).min(1),\n branchTypes: z.array(BranchTypeSchema).optional(),\n conventionalTypes: z.array(ConventionalTypeSchema).optional(),\n enforcement: EnforcementLevelSchema.default(\"strict\"),\n language: z.string().default(\"en\"),\n analytics: AnalyticsConfigSchema.optional(),\n adapter: z.string().optional(),\n syncRemote: z.string().optional(),\n ci: CIConfigSchema.optional(),\n hooks: HooksConfigSchema.optional(),\n guidelines: GuidelinesConfigSchema.optional(),\n advisory: AdvisoryConfigSchema.optional(),\n});\n\nexport type Scope = z.infer<typeof ScopeSchema>;\nexport type BranchType = z.infer<typeof BranchTypeSchema>;\nexport type ConventionalType = z.infer<typeof ConventionalTypeSchema>;\nexport type EnforcementLevel = z.infer<typeof EnforcementLevelSchema>;\nexport type AnalyticsConfig = z.infer<typeof AnalyticsConfigSchema>;\nexport type CIConfig = z.infer<typeof CIConfigSchema>;\nexport type HooksConfig = z.infer<typeof HooksConfigSchema>;\nexport type GuidelinesConfig = z.infer<typeof GuidelinesConfigSchema>;\nexport type AdvisoryDepth = z.infer<typeof AdvisoryDepthSchema>;\nexport type AdvisoryQuestion = z.infer<typeof AdvisoryQuestionSchema>;\nexport type AdvisoryConfig = z.infer<typeof AdvisoryConfigSchema>;\nexport type WorkflowConfig = z.infer<typeof WorkflowConfigSchema>;\n\nexport const defaultBranchTypes: BranchType[] = [\n \"feature\",\n \"bugfix\",\n \"hotfix\",\n \"chore\",\n \"refactor\",\n \"docs\",\n \"test\",\n];\n\nexport const defaultConventionalTypes: ConventionalType[] = [\n \"feat\",\n \"fix\",\n \"refactor\",\n \"chore\",\n \"docs\",\n \"test\",\n \"perf\",\n \"style\",\n];\n\n/**\n * Validates scope definitions for duplicates, description quality, and category values\n * @param scopes Array of scope definitions to validate\n * @returns Object with validation result and error messages\n */\nexport function validateScopeDefinitions(scopes: Scope[]): {\n valid: boolean;\n errors: string[];\n} {\n const errors: string[] = [];\n const seenNames = new Set<string>();\n\n for (const scope of scopes) {\n // Check for duplicate names\n if (seenNames.has(scope.name)) {\n errors.push(`Duplicate scope name: \"${scope.name}\"`);\n }\n seenNames.add(scope.name);\n\n // Validate using schema (this will catch min length, reserved names, etc.)\n const result = ScopeSchema.safeParse(scope);\n if (!result.success) {\n result.error.errors.forEach((err) => {\n errors.push(`Scope \"${scope.name}\": ${err.message}`);\n });\n }\n }\n\n return {\n valid: errors.length === 0,\n errors,\n };\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,415 @@
|
|
|
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
|
+
};
|
|
361
|
+
var SCRIPT_CATEGORIES = {
|
|
362
|
+
"Core Commands": [
|
|
363
|
+
"workflow:init",
|
|
364
|
+
"workflow:validate",
|
|
365
|
+
"workflow:config",
|
|
366
|
+
"workflow:suggest",
|
|
367
|
+
"workflow:setup",
|
|
368
|
+
"workflow:doctor"
|
|
369
|
+
],
|
|
370
|
+
"Scope Commands": ["workflow:scope:create", "workflow:scope:migrate"],
|
|
371
|
+
Verification: [
|
|
372
|
+
"workflow:verify",
|
|
373
|
+
"workflow:verify:fix",
|
|
374
|
+
"workflow:auto-setup"
|
|
375
|
+
],
|
|
376
|
+
"Learning System": [
|
|
377
|
+
"workflow:learn",
|
|
378
|
+
"workflow:learn:record",
|
|
379
|
+
"workflow:learn:list",
|
|
380
|
+
"workflow:learn:apply",
|
|
381
|
+
"workflow:learn:sync",
|
|
382
|
+
"workflow:learn:config",
|
|
383
|
+
"workflow:learn:deprecate",
|
|
384
|
+
"workflow:learn:stats"
|
|
385
|
+
],
|
|
386
|
+
"Solution Patterns": [
|
|
387
|
+
"workflow:solution",
|
|
388
|
+
"workflow:solution:capture",
|
|
389
|
+
"workflow:solution:search",
|
|
390
|
+
"workflow:solution:list",
|
|
391
|
+
"workflow:solution:apply",
|
|
392
|
+
"workflow:solution:deprecate",
|
|
393
|
+
"workflow:solution:stats"
|
|
394
|
+
],
|
|
395
|
+
"Advisory Board": [
|
|
396
|
+
"workflow:advisory",
|
|
397
|
+
"workflow:advisory:quick",
|
|
398
|
+
"workflow:advisory:standard",
|
|
399
|
+
"workflow:advisory:comprehensive",
|
|
400
|
+
"workflow:advisory:executive",
|
|
401
|
+
"workflow:advisory:ci"
|
|
402
|
+
],
|
|
403
|
+
"AI Agent Instructions": [
|
|
404
|
+
"workflow:generate-instructions"
|
|
405
|
+
]
|
|
406
|
+
};
|
|
407
|
+
var TOTAL_SCRIPTS = Object.keys(WORKFLOW_SCRIPTS).length;
|
|
408
|
+
|
|
409
|
+
export {
|
|
410
|
+
generateCopilotInstructions,
|
|
411
|
+
WORKFLOW_SCRIPTS,
|
|
412
|
+
SCRIPT_CATEGORIES,
|
|
413
|
+
TOTAL_SCRIPTS
|
|
414
|
+
};
|
|
415
|
+
//# sourceMappingURL=chunk-HKRWHFVI.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/scripts/copilot-instructions-generator.ts","../src/scripts/workflow-scripts.ts"],"sourcesContent":["/**\n * Copilot Instructions Generator\n *\n * Generates .github/copilot-instructions.md from the project's guidelines directory.\n * This file serves as the Single Source of Truth for AI agents (GitHub Copilot, Claude, etc.)\n * when working on the codebase.\n *\n * Features:\n * - Reads all markdown files from guidelines/\n * - Extracts key rules and summaries from each guideline\n * - Loads project config from workflow.config.json\n * - Preserves custom user content between markers\n * - Provides links to full guideline documents\n */\n\nimport { readFileSync, writeFileSync, existsSync, readdirSync, mkdirSync } from \"fs\";\nimport { join, basename } from \"path\";\n\n// Markers for custom user content that should be preserved on regeneration\nconst CUSTOM_START_MARKER = \"<!-- CUSTOM START -->\";\nconst CUSTOM_END_MARKER = \"<!-- CUSTOM END -->\";\nconst GENERATED_MARKER = \"<!-- AUTO-GENERATED BY WORKFLOW-AGENT - DO NOT EDIT ABOVE THIS LINE -->\";\n\ninterface WorkflowConfig {\n projectName?: string;\n scopes?: Array<{ name: string; description: string; emoji?: string }>;\n enforcement?: string;\n language?: string;\n}\n\ninterface GuidelineSummary {\n filename: string;\n title: string;\n description: string;\n keyRules: string[];\n}\n\n/**\n * Extract title from markdown content (first H1)\n */\nfunction extractTitle(content: string): string {\n const match = content.match(/^#\\s+(.+)$/m);\n return match ? match[1].trim() : \"Untitled\";\n}\n\n/**\n * Extract description from markdown content (first paragraph after title)\n */\nfunction extractDescription(content: string): string {\n // Look for content after the first heading, before the next heading or section\n const lines = content.split(\"\\n\");\n let foundTitle = false;\n let description = \"\";\n\n for (const line of lines) {\n if (line.startsWith(\"# \")) {\n foundTitle = true;\n continue;\n }\n if (foundTitle) {\n // Skip empty lines and blockquotes at start\n if (line.trim() === \"\" || line.startsWith(\">\")) {\n if (description) break; // End if we already have content\n continue;\n }\n // Stop at next heading or horizontal rule\n if (line.startsWith(\"#\") || line.startsWith(\"---\") || line.startsWith(\"##\")) {\n break;\n }\n description += line.trim() + \" \";\n // Take only first meaningful paragraph\n if (description.length > 150) break;\n }\n }\n\n return description.trim().slice(0, 200) + (description.length > 200 ? \"...\" : \"\");\n}\n\n/**\n * Extract key rules from markdown content\n * Looks for lists, bold text, and important patterns\n */\nfunction extractKeyRules(content: string, maxRules: number = 5): string[] {\n const rules: string[] = [];\n\n // Pattern 1: Look for \"MUST\", \"NEVER\", \"ALWAYS\", \"REQUIRED\" in bold or emphasized\n const emphasisPatterns = [\n /\\*\\*(?:MUST|NEVER|ALWAYS|REQUIRED)[^*]+\\*\\*/gi,\n /(?:^|\\n)\\s*[-*]\\s+\\*\\*[^*]+\\*\\*/gm,\n ];\n\n for (const pattern of emphasisPatterns) {\n const matches = content.match(pattern);\n if (matches) {\n for (const match of matches.slice(0, 2)) {\n const cleaned = match.replace(/\\*\\*/g, \"\").replace(/^[-*]\\s*/, \"\").trim();\n if (cleaned.length > 10 && cleaned.length < 150 && !rules.includes(cleaned)) {\n rules.push(cleaned);\n }\n }\n }\n }\n\n // Pattern 2: Look for numbered or bulleted rules under headings containing \"Rules\", \"Requirements\", \"Guidelines\"\n const rulesSectionMatch = content.match(/##\\s+(?:.*(?:Rules?|Requirements?|Guidelines?|Standards?)[^\\n]*)\\n([\\s\\S]*?)(?=\\n##|\\n#|$)/i);\n if (rulesSectionMatch) {\n const section = rulesSectionMatch[1];\n const listItems = section.match(/^\\s*[-*\\d.]+\\s+(.+)$/gm);\n if (listItems) {\n for (const item of listItems.slice(0, 3)) {\n const cleaned = item.replace(/^[-*\\d.]+\\s*/, \"\").trim();\n if (cleaned.length > 10 && cleaned.length < 150 && !rules.includes(cleaned)) {\n rules.push(cleaned);\n }\n }\n }\n }\n\n // Pattern 3: Look for key points under \"Important\", \"Critical\", \"Key\"\n const importantMatch = content.match(/(?:Important|Critical|Key|Essential)[:\\s]+([^\\n]+)/gi);\n if (importantMatch) {\n for (const match of importantMatch.slice(0, 2)) {\n const cleaned = match.replace(/^(?:Important|Critical|Key|Essential)[:\\s]+/i, \"\").trim();\n if (cleaned.length > 10 && cleaned.length < 150 && !rules.includes(cleaned)) {\n rules.push(cleaned);\n }\n }\n }\n\n // Fallback: Get first few list items if we don't have enough rules\n if (rules.length < 2) {\n const listItems = content.match(/^\\s*[-*]\\s+(.+)$/gm);\n if (listItems) {\n for (const item of listItems.slice(0, 3)) {\n const cleaned = item.replace(/^[-*]\\s*/, \"\").trim();\n if (cleaned.length > 15 && cleaned.length < 150 && !rules.includes(cleaned)) {\n rules.push(cleaned);\n }\n }\n }\n }\n\n return rules.slice(0, maxRules);\n}\n\n/**\n * Parse a guideline markdown file and extract summary\n */\nfunction parseGuideline(filePath: string): GuidelineSummary | null {\n try {\n const content = readFileSync(filePath, \"utf-8\");\n const filename = basename(filePath);\n\n // Skip template example and non-guideline files\n if (filename.startsWith(\"_\") || filename === \"Guidelines.md\") {\n return null;\n }\n\n return {\n filename,\n title: extractTitle(content),\n description: extractDescription(content),\n keyRules: extractKeyRules(content),\n };\n } catch {\n return null;\n }\n}\n\n/**\n * Load workflow config from project root\n */\nfunction loadWorkflowConfig(projectRoot: string): WorkflowConfig | null {\n const configPath = join(projectRoot, \"workflow.config.json\");\n if (!existsSync(configPath)) {\n return null;\n }\n\n try {\n const content = readFileSync(configPath, \"utf-8\");\n return JSON.parse(content) as WorkflowConfig;\n } catch {\n return null;\n }\n}\n\n/**\n * Extract preserved custom content from existing file\n */\nfunction extractCustomContent(existingContent: string): string | null {\n const startIndex = existingContent.indexOf(CUSTOM_START_MARKER);\n const endIndex = existingContent.indexOf(CUSTOM_END_MARKER);\n\n if (startIndex !== -1 && endIndex !== -1 && endIndex > startIndex) {\n return existingContent.slice(\n startIndex + CUSTOM_START_MARKER.length,\n endIndex\n ).trim();\n }\n\n return null;\n}\n\n/**\n * Generate the copilot-instructions.md content\n */\nfunction generateInstructionsContent(\n config: WorkflowConfig | null,\n guidelines: GuidelineSummary[],\n customContent: string | null\n): string {\n const projectName = config?.projectName || \"this project\";\n const scopes = config?.scopes || [];\n\n let content = `# Copilot Instructions for ${projectName}\n\n> **This file is the Single Source of Truth for AI agents working on this codebase.**\n> It is auto-generated from the \\`guidelines/\\` directory by workflow-agent-cli.\n> Last generated: ${new Date().toISOString().split(\"T\")[0]}\n\n${GENERATED_MARKER}\n\n## Project Overview\n\n`;\n\n if (config) {\n content += `- **Project Name**: ${projectName}\\n`;\n content += `- **Enforcement Level**: ${config.enforcement || \"strict\"}\\n`;\n if (scopes.length > 0) {\n content += `- **Available Scopes**: ${scopes.map(s => `\\`${s.name}\\``).join(\", \")}\\n`;\n }\n content += \"\\n\";\n }\n\n // Add scope reference if available\n if (scopes.length > 0) {\n content += `### Valid Scopes for Commits and Branches\n\n| Scope | Description |\n|-------|-------------|\n`;\n for (const scope of scopes.slice(0, 15)) {\n content += `| \\`${scope.name}\\` | ${scope.description} |\\n`;\n }\n if (scopes.length > 15) {\n content += `| ... | See workflow.config.json for all ${scopes.length} scopes |\\n`;\n }\n content += \"\\n\";\n }\n\n // Add guidelines summaries\n if (guidelines.length > 0) {\n content += `## Guidelines Summary\n\nThe following guidelines govern development on this project. **Read the linked documents for full details.**\n\n`;\n\n // Group by importance (mandatory templates first)\n const mandatoryFiles = [\n \"AGENT_EDITING_INSTRUCTIONS.md\",\n \"BRANCHING_STRATEGY.md\",\n \"TESTING_STRATEGY.md\",\n \"SINGLE_SOURCE_OF_TRUTH.md\",\n \"PATTERN_ANALYSIS_WORKFLOW.md\",\n \"SELF_IMPROVEMENT_MANDATE.md\",\n ];\n\n const sortedGuidelines = [...guidelines].sort((a, b) => {\n const aIndex = mandatoryFiles.indexOf(a.filename);\n const bIndex = mandatoryFiles.indexOf(b.filename);\n if (aIndex !== -1 && bIndex !== -1) return aIndex - bIndex;\n if (aIndex !== -1) return -1;\n if (bIndex !== -1) return 1;\n return a.title.localeCompare(b.title);\n });\n\n for (const guideline of sortedGuidelines) {\n content += `### ${guideline.title}\n\n📄 [See full details](../guidelines/${guideline.filename})\n\n${guideline.description}\n\n`;\n if (guideline.keyRules.length > 0) {\n content += `**Key Rules:**\n`;\n for (const rule of guideline.keyRules) {\n content += `- ${rule}\\n`;\n }\n content += \"\\n\";\n }\n }\n }\n\n // Add quick reference section\n content += `## Quick Reference\n\n### Branch Naming Convention\n\\`\\`\\`\n<type>/<scope>/<short-description>\n\\`\\`\\`\n\n**Types**: \\`feature\\`, \\`fix\\`, \\`chore\\`, \\`docs\\`, \\`refactor\\`, \\`test\\`, \\`perf\\`\n\n### Commit Message Format\n\\`\\`\\`\n<type>(<scope>): <description>\n\n[optional body]\n\n[optional footer]\n\\`\\`\\`\n\n### Before Making Changes\n1. Read the relevant guideline document in \\`guidelines/\\`\n2. Check for existing patterns in \\`workflow:solution:search\\`\n3. Create an implementation plan for multi-file changes\n4. Ensure tests are added for new functionality\n\n### Before Committing\n1. Run \\`pnpm run workflow:verify\\` to validate all changes\n2. Ensure branch name follows convention\n3. Ensure commit message follows conventional commits format\n\n`;\n\n // Add custom content section\n content += `## Project-Specific Instructions\n\n${CUSTOM_START_MARKER}\n${customContent || `\n<!-- \nAdd your project-specific instructions here.\nThis section will be preserved when the file is regenerated.\n\nExamples:\n- Specific coding patterns unique to this project\n- Custom review requirements\n- Domain-specific terminology\n- Team-specific workflows\n-->\n`}\n${CUSTOM_END_MARKER}\n\n---\n\n*This file was generated by [workflow-agent-cli](https://www.npmjs.com/package/workflow-agent-cli). Run \\`pnpm run workflow:generate-instructions\\` to regenerate.*\n`;\n\n return content;\n}\n\n/**\n * Result of generating copilot instructions\n */\nexport interface GenerateResult {\n success: boolean;\n filePath: string | null;\n guidelinesCount: number;\n isNew: boolean;\n preservedCustomContent: boolean;\n error?: string;\n}\n\n/**\n * Generate .github/copilot-instructions.md from guidelines directory\n *\n * @param projectRoot - Root directory of the project\n * @param options - Generation options\n * @returns Result of the generation\n */\nexport function generateCopilotInstructions(\n projectRoot: string,\n options: { force?: boolean; silent?: boolean } = {}\n): GenerateResult {\n const { force = false, silent = false } = options;\n\n const guidelinesDir = join(projectRoot, \"guidelines\");\n const githubDir = join(projectRoot, \".github\");\n const outputPath = join(githubDir, \"copilot-instructions.md\");\n\n // Check if guidelines directory exists\n if (!existsSync(guidelinesDir)) {\n if (!silent) {\n // Guidelines don't exist yet - skip silently during postinstall\n }\n return {\n success: false,\n filePath: null,\n guidelinesCount: 0,\n isNew: false,\n preservedCustomContent: false,\n error: \"No guidelines directory found. Run 'workflow init' first.\",\n };\n }\n\n // Read all markdown files from guidelines\n const files = readdirSync(guidelinesDir).filter(f => f.endsWith(\".md\"));\n if (files.length === 0) {\n return {\n success: false,\n filePath: null,\n guidelinesCount: 0,\n isNew: false,\n preservedCustomContent: false,\n error: \"No markdown files found in guidelines directory.\",\n };\n }\n\n // Parse each guideline\n const guidelines: GuidelineSummary[] = [];\n for (const file of files) {\n const summary = parseGuideline(join(guidelinesDir, file));\n if (summary) {\n guidelines.push(summary);\n }\n }\n\n // Load workflow config\n const config = loadWorkflowConfig(projectRoot);\n\n // Check for existing file and extract custom content\n let customContent: string | null = null;\n let isNew = true;\n\n if (existsSync(outputPath)) {\n isNew = false;\n const existingContent = readFileSync(outputPath, \"utf-8\");\n customContent = extractCustomContent(existingContent);\n }\n\n // Generate the content\n const content = generateInstructionsContent(config, guidelines, customContent);\n\n // Ensure .github directory exists\n if (!existsSync(githubDir)) {\n mkdirSync(githubDir, { recursive: true });\n }\n\n // Write the file\n writeFileSync(outputPath, content, \"utf-8\");\n\n return {\n success: true,\n filePath: outputPath,\n guidelinesCount: guidelines.length,\n isNew,\n preservedCustomContent: customContent !== null,\n };\n}\n\n/**\n * Check if copilot instructions need regeneration\n * (e.g., guidelines have been modified since last generation)\n */\nexport function needsRegeneration(projectRoot: string): boolean {\n const guidelinesDir = join(projectRoot, \"guidelines\");\n const outputPath = join(projectRoot, \".github\", \"copilot-instructions.md\");\n\n if (!existsSync(outputPath)) {\n return existsSync(guidelinesDir);\n }\n\n // For now, always regenerate to ensure latest content\n // Future: could compare file modification times\n return true;\n}\n","/**\n * Shared workflow scripts definition\n * Used by postinstall.ts and setup.ts to ensure consistency\n */\n\nexport const WORKFLOW_SCRIPTS = {\n // Core Commands\n \"workflow:init\": \"workflow-agent init\",\n \"workflow:validate\": \"workflow-agent validate\",\n \"workflow:config\": \"workflow-agent config\",\n \"workflow:suggest\": \"workflow-agent suggest\",\n \"workflow:setup\": \"workflow-agent setup\",\n \"workflow:doctor\": \"workflow-agent doctor\",\n\n // Scope Commands\n \"workflow:scope:create\": \"workflow-agent scope:create\",\n \"workflow:scope:migrate\": \"workflow-agent scope:migrate\",\n\n // Verification & Auto-Setup\n \"workflow:verify\": \"workflow-agent verify\",\n \"workflow:verify:fix\": \"workflow-agent verify --fix\",\n \"workflow:auto-setup\": \"workflow-agent auto-setup\",\n\n // Learning System Commands\n \"workflow:learn\": \"workflow-agent learn:list\",\n \"workflow:learn:record\": \"workflow-agent learn:record\",\n \"workflow:learn:list\": \"workflow-agent learn:list\",\n \"workflow:learn:apply\": \"workflow-agent learn:apply\",\n \"workflow:learn:sync\": \"workflow-agent learn:sync\",\n \"workflow:learn:config\": \"workflow-agent learn:config\",\n \"workflow:learn:deprecate\": \"workflow-agent learn:deprecate\",\n \"workflow:learn:stats\": \"workflow-agent learn:stats\",\n\n // Solution Pattern Commands\n \"workflow:solution\": \"workflow-agent solution:list\",\n \"workflow:solution:capture\": \"workflow-agent solution:capture\",\n \"workflow:solution:search\": \"workflow-agent solution:search\",\n \"workflow:solution:list\": \"workflow-agent solution:list\",\n \"workflow:solution:apply\": \"workflow-agent solution:apply\",\n \"workflow:solution:deprecate\": \"workflow-agent solution:deprecate\",\n \"workflow:solution:stats\": \"workflow-agent solution:stats\",\n\n // Advisory Board Commands\n \"workflow:advisory\": \"workflow-agent advisory\",\n \"workflow:advisory:quick\": \"workflow-agent advisory --depth quick\",\n \"workflow:advisory:standard\": \"workflow-agent advisory --depth standard\",\n \"workflow:advisory:comprehensive\":\n \"workflow-agent advisory --depth comprehensive\",\n \"workflow:advisory:executive\": \"workflow-agent advisory --depth executive\",\n \"workflow:advisory:ci\": \"workflow-agent advisory --ci\",\n\n // AI Agent Instructions\n \"workflow:generate-instructions\": \"workflow-agent generate-instructions\",\n} as const;\n\nexport type WorkflowScriptName = keyof typeof WORKFLOW_SCRIPTS;\n\n/**\n * Script categories for organized console output\n */\nexport const SCRIPT_CATEGORIES = {\n \"Core Commands\": [\n \"workflow:init\",\n \"workflow:validate\",\n \"workflow:config\",\n \"workflow:suggest\",\n \"workflow:setup\",\n \"workflow:doctor\",\n ],\n \"Scope Commands\": [\"workflow:scope:create\", \"workflow:scope:migrate\"],\n Verification: [\n \"workflow:verify\",\n \"workflow:verify:fix\",\n \"workflow:auto-setup\",\n ],\n \"Learning System\": [\n \"workflow:learn\",\n \"workflow:learn:record\",\n \"workflow:learn:list\",\n \"workflow:learn:apply\",\n \"workflow:learn:sync\",\n \"workflow:learn:config\",\n \"workflow:learn:deprecate\",\n \"workflow:learn:stats\",\n ],\n \"Solution Patterns\": [\n \"workflow:solution\",\n \"workflow:solution:capture\",\n \"workflow:solution:search\",\n \"workflow:solution:list\",\n \"workflow:solution:apply\",\n \"workflow:solution:deprecate\",\n \"workflow:solution:stats\",\n ],\n \"Advisory Board\": [\n \"workflow:advisory\",\n \"workflow:advisory:quick\",\n \"workflow:advisory:standard\",\n \"workflow:advisory:comprehensive\",\n \"workflow:advisory:executive\",\n \"workflow:advisory:ci\",\n ],\n \"AI Agent Instructions\": [\n \"workflow:generate-instructions\",\n ],\n} as const;\n\nexport const TOTAL_SCRIPTS = Object.keys(WORKFLOW_SCRIPTS).length;\n"],"mappings":"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","names":[]}
|