@mark-gozner/aigile-method 0.4.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (143) hide show
  1. package/LICENSE.md +26 -0
  2. package/README.md +300 -0
  3. package/core/agent-teams/team-all.yaml +24 -0
  4. package/core/agent-teams/team-company.yaml +17 -0
  5. package/core/agent-teams/team-enterprise.yaml +17 -0
  6. package/core/agent-teams/team-fullstack.yaml +16 -0
  7. package/core/agent-teams/team-ide-minimal.yaml +10 -0
  8. package/core/agents/aigile-master.md +476 -0
  9. package/core/agents/aigile-orchestrator.agent.md +200 -0
  10. package/core/agents/analyst.md +45 -0
  11. package/core/agents/architect.md +43 -0
  12. package/core/agents/code-tour.agent.md +208 -0
  13. package/core/agents/dev.agent.md +145 -0
  14. package/core/agents/dev.md +130 -0
  15. package/core/agents/expert-react-frontend-engineer.agent.md +741 -0
  16. package/core/agents/pm.md +33 -0
  17. package/core/agents/po.md +35 -0
  18. package/core/agents/qa.md +38 -0
  19. package/core/agents/sm.md +31 -0
  20. package/core/agents/ui-expert.md +39 -0
  21. package/core/agents/ux-expert.md +31 -0
  22. package/core/checklists/architect-checklist.md +246 -0
  23. package/core/checklists/change-checklist.md +182 -0
  24. package/core/checklists/pm-checklist.md +286 -0
  25. package/core/checklists/po-master-checklist.md +291 -0
  26. package/core/checklists/story-dod-checklist.md +94 -0
  27. package/core/checklists/story-draft-checklist.md +153 -0
  28. package/core/core-config.yaml +22 -0
  29. package/core/data/aigile-kb.md +112 -0
  30. package/core/data/brainstorming-techniques.md +73 -0
  31. package/core/data/elicitation-methods.md +42 -0
  32. package/core/data/technical-preferences.md +52 -0
  33. package/core/data/test-levels-framework.md +43 -0
  34. package/core/data/test-priorities-matrix.md +26 -0
  35. package/core/instructions/csharp.instructions.md +656 -0
  36. package/core/instructions/dotnet/csharp.instructions.md +656 -0
  37. package/core/instructions/java/java.instructions.md +67 -0
  38. package/core/instructions/java/spring-boot.instructions.md +122 -0
  39. package/core/instructions/java.instructions.md +67 -0
  40. package/core/instructions/spring-boot.instructions.md +122 -0
  41. package/core/prompts/README.md +11 -0
  42. package/core/prompts/architecture/architecture-blueprint-generator.prompt.md +322 -0
  43. package/core/prompts/architecture/architecture-validation.prompt.md +71 -0
  44. package/core/prompts/architecture/file-tree-generator.prompt.md +405 -0
  45. package/core/prompts/architecture/technical-project-analyze.prompt.md +43 -0
  46. package/core/prompts/architecture-blueprint-generator.prompt.md +322 -0
  47. package/core/prompts/architecture-validation.prompt.md +71 -0
  48. package/core/prompts/code-review.prompt.md +107 -0
  49. package/core/prompts/confluence-in-md.prompt.md +167 -0
  50. package/core/prompts/copilot-instructions-blueprint-generator.prompt.md +294 -0
  51. package/core/prompts/create-implementation-plan.prompt.md +157 -0
  52. package/core/prompts/create-oo-component-documentation.prompt.md +193 -0
  53. package/core/prompts/file-tree-generator.prompt.md +405 -0
  54. package/core/prompts/generate-unit-tests.prompt.md +291 -0
  55. package/core/prompts/java/java-doc.prompt.md +24 -0
  56. package/core/prompts/java/java-junit.prompt.md +64 -0
  57. package/core/prompts/java/junit-5.prompt.md +64 -0
  58. package/core/prompts/java-doc.prompt.md +24 -0
  59. package/core/prompts/java-junit.prompt.md +64 -0
  60. package/core/prompts/junit-5.prompt.md +64 -0
  61. package/core/prompts/release-notes/README.md +11 -0
  62. package/core/prompts/release-notes/release-notes.prompt.md +723 -0
  63. package/core/prompts/release-notes.prompt.md +723 -0
  64. package/core/prompts/technical-project-analyze.prompt.md +43 -0
  65. package/core/tasks/advanced-elicitation.md +119 -0
  66. package/core/tasks/check-story-implemented.md +44 -0
  67. package/core/tasks/code-arch-review-with-github.md +40 -0
  68. package/core/tasks/create-architecture-doc.md +55 -0
  69. package/core/tasks/create-jira-epic-from-confluence.md +70 -0
  70. package/core/tasks/create-jira-story-from-confluence.md +39 -0
  71. package/core/tasks/create-jira-story-from-text.md +39 -0
  72. package/core/tasks/create-next-story.md +35 -0
  73. package/core/tasks/create-prd-doc.md +54 -0
  74. package/core/tasks/create-stories-from-epic.md +66 -0
  75. package/core/tasks/create-tasks-for-story.md +60 -0
  76. package/core/tasks/document-project.md +69 -0
  77. package/core/tasks/execute-checklist.md +37 -0
  78. package/core/tasks/explain-story-from-jira.md +44 -0
  79. package/core/tasks/facilitate-brainstorming-session.md +69 -0
  80. package/core/tasks/figma-audit-design-system.md +20 -0
  81. package/core/tasks/front-end-spec-from-design.md +33 -0
  82. package/core/tasks/gate.md +64 -0
  83. package/core/tasks/groom-jira-story.md +52 -0
  84. package/core/tasks/help.md +27 -0
  85. package/core/tasks/implement-freeform-work-item.md +30 -0
  86. package/core/tasks/implement-story-from-jira.md +63 -0
  87. package/core/tasks/implement-unit-tests.md +45 -0
  88. package/core/tasks/market-research-from-context7.md +37 -0
  89. package/core/tasks/review-story.md +30 -0
  90. package/core/tasks/sonarqube-hotspot-review.md +39 -0
  91. package/core/tasks/standup-digest.md +21 -0
  92. package/core/tasks/sync-jira-backlog.md +32 -0
  93. package/core/tasks/test-design.md +68 -0
  94. package/core/tasks/validate-next-story.md +37 -0
  95. package/core/tasks/verify-jira-story-e2e.md +45 -0
  96. package/core/templates/architecture-tmpl.yaml +651 -0
  97. package/core/templates/brainstorming-output-tmpl.yaml +156 -0
  98. package/core/templates/brownfield-architecture-tmpl.yaml +477 -0
  99. package/core/templates/brownfield-prd-tmpl.yaml +281 -0
  100. package/core/templates/front-end-architecture-tmpl.yaml +219 -0
  101. package/core/templates/front-end-spec-tmpl.yaml +350 -0
  102. package/core/templates/fullstack-architecture-tmpl.yaml +824 -0
  103. package/core/templates/market-research-tmpl.yaml +253 -0
  104. package/core/templates/prd-tmpl.yaml +203 -0
  105. package/core/templates/project-brief-tmpl.yaml +222 -0
  106. package/core/templates/qa-gate-tmpl.yaml +103 -0
  107. package/core/templates/story-tmpl.yaml +138 -0
  108. package/core/workflows/brownfield-fullstack.yaml +298 -0
  109. package/core/workflows/brownfield-service.yaml +188 -0
  110. package/core/workflows/brownfield-ui.yaml +198 -0
  111. package/core/workflows/greenfield-fullstack.yaml +241 -0
  112. package/core/workflows/greenfield-service.yaml +207 -0
  113. package/core/workflows/greenfield-ui.yaml +236 -0
  114. package/dist/agents/aigile-master.txt +500 -0
  115. package/dist/agents/aigile-orchestrator.agent.txt +224 -0
  116. package/dist/agents/analyst.txt +69 -0
  117. package/dist/agents/architect.txt +67 -0
  118. package/dist/agents/code-tour.agent.txt +232 -0
  119. package/dist/agents/dev.agent.txt +169 -0
  120. package/dist/agents/dev.txt +154 -0
  121. package/dist/agents/expert-react-frontend-engineer.agent.txt +765 -0
  122. package/dist/agents/pm.txt +57 -0
  123. package/dist/agents/po.txt +59 -0
  124. package/dist/agents/qa.txt +62 -0
  125. package/dist/agents/sm.txt +55 -0
  126. package/dist/agents/ui-expert.txt +63 -0
  127. package/dist/agents/ux-expert.txt +55 -0
  128. package/dist/dev-agent-bundle.txt +154 -0
  129. package/dist/teams/team-company.txt +10789 -0
  130. package/docs/mcp-servers.md +102 -0
  131. package/docs/orchestrator-guide.md +526 -0
  132. package/mcp/servers.json +108 -0
  133. package/mcp/servers.yaml +124 -0
  134. package/package.json +72 -0
  135. package/tools/cli.js +1864 -0
  136. package/tools/installer/README.md +24 -0
  137. package/tools/installer/lib/ide-setup.js +295 -0
  138. package/tools/installer/lib/installer.js +131 -0
  139. package/tools/md-assets/web-agent-startup-instructions.md +21 -0
  140. package/tools/postinstall.js +72 -0
  141. package/tools/shared/bannerArt.js +68 -0
  142. package/tools/validate-bundles.js +54 -0
  143. package/tools/verify-publish-registry.js +34 -0
@@ -0,0 +1,24 @@
1
+ # AIgile Installer (GitHub Copilot Only)
2
+
3
+ Usage:
4
+
5
+ - Interactive (via your existing CLI):
6
+ - `npx aigile-method install`
7
+ - `npm run install:aigile`
8
+ - Add MCP templates: `npx aigile-method install --with-mcp`
9
+ - Add mock VS Code MCP settings: `npx aigile-method install --with-mcp-settings`
10
+ - Interactive prompts will ask about MCP options; use `--yes` to accept defaults quickly
11
+
12
+ What it does:
13
+ - Copies `core/` into `.aigile-core/` in your current project
14
+ - Generates GitHub Copilot chat modes from your agents into `.github/chatmodes/*.chatmode.md`
15
+ - Leaves your repo otherwise untouched
16
+ - Prints a friendly ASCII banner during installation
17
+ - Optional: generates `.vscode/mcp.json` with template servers and input prompts
18
+ - Optional: updates `.vscode/settings.json` with mock MCP endpoints (for demos)
19
+ - Shows a small “Created by GM” banner and a short summary on completion
20
+
21
+ Notes:
22
+ - This installer is intentionally scoped to GitHub Copilot compatibility.
23
+ - MCP/other IDEs can be added later as separate options.
24
+ - After generating `.vscode/mcp.json`, open VS Code and fill in the prompted API keys.
@@ -0,0 +1,295 @@
1
+ import path from 'node:path';
2
+ import fs from 'fs-extra';
3
+
4
+ /**
5
+ * Full tool list for all agents (except orchestrator)
6
+ */
7
+ const FULL_AGENT_TOOLS = [
8
+ // VS Code tools
9
+ 'vscode/getProjectSetupInfo', 'vscode/installExtension', 'vscode/newWorkspace',
10
+ 'vscode/openSimpleBrowser', 'vscode/runCommand', 'vscode/vscodeAPI', 'vscode/extensions',
11
+ // Execute tools
12
+ 'execute/runNotebookCell', 'execute/testFailure', 'execute/getTerminalOutput',
13
+ 'execute/runTask', 'execute/createAndRunTask', 'execute/runInTerminal', 'execute/runTests',
14
+ // Read tools
15
+ 'read/getNotebookSummary', 'read/problems', 'read/readFile', 'read/readNotebookCellOutput',
16
+ 'read/terminalSelection', 'read/terminalLastCommand', 'read/getTaskOutput',
17
+ // Agent tools
18
+ 'agent/runSubagent',
19
+ // Edit tools
20
+ 'edit/createDirectory', 'edit/createFile', 'edit/createJupyterNotebook',
21
+ 'edit/editFiles', 'edit/editNotebook',
22
+ // Search tools
23
+ 'search/changes', 'search/codebase', 'search/fileSearch', 'search/listDirectory',
24
+ 'search/searchResults', 'search/textSearch', 'search/usages', 'search/searchSubagent',
25
+ // Web tools
26
+ 'web/fetch', 'web/githubRepo',
27
+ // Context7 MCP
28
+ 'upstash/context7/query-docs', 'upstash/context7/resolve-library-id',
29
+ // GitHub MCP
30
+ 'github/add_comment_to_pending_review', 'github/add_issue_comment', 'github/assign_copilot_to_issue',
31
+ 'github/create_branch', 'github/create_or_update_file', 'github/create_pull_request',
32
+ 'github/create_repository', 'github/delete_file', 'github/fork_repository', 'github/get_commit',
33
+ 'github/get_file_contents', 'github/get_label', 'github/get_latest_release', 'github/get_me',
34
+ 'github/get_release_by_tag', 'github/get_tag', 'github/get_team_members', 'github/get_teams',
35
+ 'github/issue_read', 'github/issue_write', 'github/list_branches', 'github/list_commits',
36
+ 'github/list_issue_types', 'github/list_issues', 'github/list_pull_requests', 'github/list_releases',
37
+ 'github/list_tags', 'github/merge_pull_request', 'github/pull_request_read',
38
+ 'github/pull_request_review_write', 'github/push_files', 'github/request_copilot_review',
39
+ 'github/search_code', 'github/search_issues', 'github/search_pull_requests',
40
+ 'github/search_repositories', 'github/search_users', 'github/sub_issue_write',
41
+ 'github/update_pull_request', 'github/update_pull_request_branch',
42
+ // Other tools
43
+ 'askQuestions', 'todo',
44
+ // GitHub PR extension tools
45
+ 'github.vscode-pull-request-github/issue_fetch', 'github.vscode-pull-request-github/suggest-fix',
46
+ 'github.vscode-pull-request-github/searchSyntax', 'github.vscode-pull-request-github/doSearch',
47
+ 'github.vscode-pull-request-github/renderIssues', 'github.vscode-pull-request-github/activePullRequest',
48
+ 'github.vscode-pull-request-github/openPullRequest'
49
+ ];
50
+
51
+ /**
52
+ * Agent metadata extracted from legacy YAML blocks
53
+ */
54
+ const AGENT_METADATA = {
55
+ 'aigile-orchestrator': {
56
+ description: 'PURE COORDINATOR - I have NO implementation tools. I can ONLY delegate via runSubagent.',
57
+ tools: ['agent/runSubagent'],
58
+ model: 'Claude Opus 4.5',
59
+ handoffs: [
60
+ { label: '🏗️ Architecture Review', agent: 'architect', prompt: 'Analyze the architecture and provide recommendations.', send: false },
61
+ { label: '💻 Start Implementation', agent: 'dev', prompt: 'Implement the plan using test-driven development.', send: false },
62
+ { label: '🧪 Run QA Gate', agent: 'qa', prompt: 'Review and test the implementation for quality.', send: false },
63
+ { label: '📋 Refine Backlog', agent: 'po', prompt: 'Refine the backlog items based on discussion.', send: false },
64
+ { label: '🧠 Analyze Requirements', agent: 'analyst', prompt: 'Analyze requirements and provide breakdown.', send: false },
65
+ ],
66
+ infer: false
67
+ },
68
+ 'dev': {
69
+ description: 'Full Stack Developer - code implementation, debugging, refactoring, and test-driven development.',
70
+ tools: FULL_AGENT_TOOLS,
71
+ model: 'Claude Opus 4.5',
72
+ handoffs: [
73
+ { label: '🧪 Request QA Review', agent: 'qa', prompt: 'Review the implementation above for quality.', send: false },
74
+ { label: '🏗️ Architecture Check', agent: 'architect', prompt: 'Verify architecture compliance.', send: false },
75
+ ],
76
+ infer: true
77
+ },
78
+ 'architect': {
79
+ description: 'Software Architect - architecture analysis, code review, documentation, and system design.',
80
+ tools: FULL_AGENT_TOOLS,
81
+ model: 'Claude Opus 4.5',
82
+ handoffs: [
83
+ { label: '💻 Start Implementation', agent: 'dev', prompt: 'Implement the architecture recommendations.', send: false },
84
+ { label: '📋 Create Stories', agent: 'po', prompt: 'Create backlog items for architecture changes.', send: false },
85
+ ],
86
+ infer: true
87
+ },
88
+ 'po': {
89
+ description: 'Product Owner - story creation, backlog management, and Jira integration.',
90
+ tools: FULL_AGENT_TOOLS,
91
+ model: 'Claude Opus 4.5',
92
+ handoffs: [
93
+ { label: '💻 Implement Story', agent: 'dev', prompt: 'Implement the story defined above.', send: false },
94
+ { label: '🧠 Analyze Further', agent: 'analyst', prompt: 'Provide deeper analysis of requirements.', send: false },
95
+ ],
96
+ infer: true
97
+ },
98
+ 'qa': {
99
+ description: 'QA Engineer - testing, quality gates, E2E verification, and test automation.',
100
+ tools: FULL_AGENT_TOOLS,
101
+ model: 'Claude Opus 4.5',
102
+ handoffs: [
103
+ { label: '💻 Fix Issues', agent: 'dev', prompt: 'Fix the issues identified in QA review.', send: false },
104
+ { label: '📋 Update Stories', agent: 'po', prompt: 'Update stories based on QA findings.', send: false },
105
+ ],
106
+ infer: true
107
+ },
108
+ 'analyst': {
109
+ description: 'Business Analyst - requirements analysis, brainstorming, research, and elicitation.',
110
+ tools: FULL_AGENT_TOOLS,
111
+ model: 'Claude Opus 4.5',
112
+ handoffs: [
113
+ { label: '📋 Create Stories', agent: 'po', prompt: 'Create stories from analysis findings.', send: false },
114
+ { label: '🏗️ Architecture Review', agent: 'architect', prompt: 'Review architecture implications.', send: false },
115
+ ],
116
+ infer: true
117
+ },
118
+ 'pm': {
119
+ description: 'Project Manager - project planning, backlog sync, PRDs, and roadmap management.',
120
+ tools: FULL_AGENT_TOOLS,
121
+ model: 'Claude Opus 4.5',
122
+ handoffs: [
123
+ { label: '📋 Refine Stories', agent: 'po', prompt: 'Refine the stories in the plan.', send: false },
124
+ ],
125
+ infer: true
126
+ },
127
+ 'sm': {
128
+ description: 'Scrum Master - sprint ceremonies, standup facilitation, and team coordination.',
129
+ tools: FULL_AGENT_TOOLS,
130
+ model: 'Claude Opus 4.5',
131
+ handoffs: [],
132
+ infer: true
133
+ },
134
+ 'ui-expert': {
135
+ description: 'UI Expert - design system audit, Figma integration, and component specifications.',
136
+ tools: FULL_AGENT_TOOLS,
137
+ model: 'Claude Opus 4.5',
138
+ handoffs: [
139
+ { label: '💻 Implement UI', agent: 'dev', prompt: 'Implement the UI specifications.', send: false },
140
+ ],
141
+ infer: true
142
+ },
143
+ 'ux-expert': {
144
+ description: 'UX Expert - user experience design, frontend specs, and user journey mapping.',
145
+ tools: FULL_AGENT_TOOLS,
146
+ model: 'Claude Opus 4.5',
147
+ handoffs: [
148
+ { label: '🖌️ Design System', agent: 'ui-expert', prompt: 'Create design system components.', send: false },
149
+ { label: '💻 Implement UX', agent: 'dev', prompt: 'Implement the UX recommendations.', send: false },
150
+ ],
151
+ infer: true
152
+ },
153
+ };
154
+
155
+ /**
156
+ * Extract agent ID from filename
157
+ */
158
+ function getAgentId(filename) {
159
+ return filename
160
+ .replace(/\.agent\.md$/, '')
161
+ .replace(/\.md$/, '');
162
+ }
163
+
164
+ /**
165
+ * Check if file is already in new agent format
166
+ */
167
+ function isNewAgentFormat(filename) {
168
+ return filename.endsWith('.agent.md');
169
+ }
170
+
171
+ /**
172
+ * Generate YAML frontmatter for custom agent
173
+ */
174
+ function generateFrontmatter(id, metadata) {
175
+ const lines = ['---'];
176
+
177
+ if (metadata.name) lines.push(`name: ${metadata.name}`);
178
+ lines.push(`description: "${metadata.description || `Activates the ${id} agent persona (AIgile).`}"`);
179
+ if (metadata.argumentHint) lines.push(`argument-hint: "${metadata.argumentHint}"`);
180
+
181
+ if (metadata.tools && metadata.tools.length > 0) {
182
+ lines.push('tools:');
183
+ for (const tool of metadata.tools) {
184
+ lines.push(` - ${tool}`);
185
+ }
186
+ }
187
+
188
+ // Always add model - default to Claude Opus 4.5
189
+ lines.push(`model: ${metadata.model || 'Claude Opus 4.5'}`);
190
+ if (metadata.infer !== undefined) lines.push(`infer: ${metadata.infer}`);
191
+
192
+ if (metadata.handoffs && metadata.handoffs.length > 0) {
193
+ lines.push('handoffs:');
194
+ for (const handoff of metadata.handoffs) {
195
+ lines.push(` - label: "${handoff.label}"`);
196
+ lines.push(` agent: ${handoff.agent}`);
197
+ lines.push(` prompt: "${handoff.prompt}"`);
198
+ lines.push(` send: ${handoff.send}`);
199
+ }
200
+ }
201
+
202
+ lines.push('---');
203
+ return lines.join('\n');
204
+ }
205
+
206
+ /**
207
+ * Setup GitHub Copilot custom agents (new format)
208
+ * Creates .agent.md files in .github/agents/ folder
209
+ *
210
+ * @deprecated destChatmodesDir parameter - now creates agents in .github/agents/
211
+ */
212
+ export function setupGithubCopilot({ srcAgentsDir, destChatmodesDir, destAgentsDir }){
213
+ // Use new agents directory, fallback to chatmodes for backward compatibility
214
+ const targetDir = destAgentsDir || destChatmodesDir?.replace('chatmodes', 'agents') || destChatmodesDir;
215
+
216
+ fs.mkdirpSync(targetDir);
217
+ if(!srcAgentsDir || !fs.existsSync(srcAgentsDir)) return;
218
+
219
+ const processedAgents = [];
220
+
221
+ for(const name of fs.readdirSync(srcAgentsDir)){
222
+ if(!name.endsWith('.md')) continue;
223
+
224
+ const id = getAgentId(name);
225
+ const srcPath = path.join(srcAgentsDir, name);
226
+ const agentMd = fs.readFileSync(srcPath, 'utf8');
227
+
228
+ // If already in new .agent.md format, copy directly
229
+ if (isNewAgentFormat(name)) {
230
+ fs.copyFileSync(srcPath, path.join(targetDir, name));
231
+ processedAgents.push({ id, format: 'native' });
232
+ continue;
233
+ }
234
+
235
+ // Convert legacy format to new custom agent format
236
+ const metadata = AGENT_METADATA[id] || {
237
+ description: `Activates the ${id} agent persona (AIgile).`,
238
+ tools: ['search', 'fetch', 'codebase', 'problems'],
239
+ handoffs: [],
240
+ infer: true
241
+ };
242
+
243
+ const frontmatter = generateFrontmatter(id, metadata);
244
+
245
+ // Transform the content - remove old activation notice if present
246
+ let content = agentMd;
247
+
248
+ // Add activation context header
249
+ const header = [
250
+ '',
251
+ '# Activation Notice',
252
+ '',
253
+ 'This agent is part of the AIgile framework. The instructions below define your operating guidelines.',
254
+ 'Use `#tool:runSubagent` to delegate specialized tasks to other agents when appropriate.',
255
+ '',
256
+ ].join('\n');
257
+
258
+ const out = `${frontmatter}${header}${content}`;
259
+ const destFile = path.join(targetDir, `${id}.agent.md`);
260
+ fs.writeFileSync(destFile, out, 'utf8');
261
+ processedAgents.push({ id, format: 'converted' });
262
+ }
263
+
264
+ return processedAgents;
265
+ }
266
+
267
+ /**
268
+ * Setup legacy chatmodes (deprecated - for backward compatibility)
269
+ * @deprecated Use setupGithubCopilot with destAgentsDir instead
270
+ */
271
+ export function setupLegacyChatmodes({ srcAgentsDir, destChatmodesDir }){
272
+ console.warn('Warning: chatmodes are deprecated. Use custom agents (.github/agents/) instead.');
273
+ fs.mkdirpSync(destChatmodesDir);
274
+ if(!srcAgentsDir || !fs.existsSync(srcAgentsDir)) return;
275
+
276
+ for(const name of fs.readdirSync(srcAgentsDir)){
277
+ if(!name.endsWith('.md')) continue;
278
+ const id = getAgentId(name);
279
+ const agentMd = fs.readFileSync(path.join(srcAgentsDir, name), 'utf8');
280
+
281
+ const header = [
282
+ '---',
283
+ `description: "Activates the ${id} agent persona (AIgile)."`,
284
+ '---',
285
+ '',
286
+ '# Activation Notice',
287
+ 'This file contains the full agent operating guidelines for GitHub Copilot Chat.',
288
+ 'Follow the YAML inside to assume this role and operate within these constraints.',
289
+ '',
290
+ ].join('\n');
291
+
292
+ const out = `${header}${agentMd}`;
293
+ fs.writeFileSync(path.join(destChatmodesDir, `${id}.chatmode.md`), out, 'utf8');
294
+ }
295
+ }
@@ -0,0 +1,131 @@
1
+ import path from 'node:path';
2
+ import fs from 'fs-extra';
3
+ import { fileURLToPath } from 'node:url';
4
+ import { setupGithubCopilot, setupLegacyChatmodes } from './ide-setup.js';
5
+
6
+ const __filename = fileURLToPath(import.meta.url);
7
+ const __dirname = path.dirname(__filename);
8
+ const projectRoot = path.resolve(__dirname, '..', '..');
9
+
10
+ function copyDir(src, dest){
11
+ if(!fs.existsSync(src)) return;
12
+ fs.mkdirpSync(dest);
13
+ for(const entry of fs.readdirSync(src, {withFileTypes:true})){
14
+ const sp = path.join(src, entry.name);
15
+ const dp = path.join(dest, entry.name);
16
+ if(entry.isDirectory()) copyDir(sp, dp);
17
+ else fs.copyFileSync(sp, dp);
18
+ }
19
+ }
20
+
21
+ // legacy helper kept for compatibility; now defers to setupGithubCopilot
22
+ function makeChatModesFromAgents(srcAgentsDir, destChatmodesDir){
23
+ setupGithubCopilot({ srcAgentsDir, destChatmodesDir });
24
+ }
25
+
26
+ export async function runInstall({ withMcp=false, includeJavaInstructions=false, useLegacyChatmodes=false } = {}){
27
+ const cwd = process.cwd();
28
+
29
+ // 1) Copy core -> .aigile-core
30
+ const coreSrc = path.join(projectRoot, 'core');
31
+ const coreDest = path.join(cwd, '.aigile-core');
32
+ copyDir(coreSrc, coreDest);
33
+
34
+ // 2) Generate GitHub Copilot custom agents (new format: .github/agents/*.agent.md)
35
+ // Or legacy chatmodes if explicitly requested
36
+ const srcAgentsDir = path.join(coreSrc, 'agents');
37
+ let outputDir;
38
+
39
+ if (useLegacyChatmodes) {
40
+ // Deprecated: Use legacy chatmodes format
41
+ outputDir = path.join(cwd, '.github', 'chatmodes');
42
+ setupLegacyChatmodes({ srcAgentsDir, destChatmodesDir: outputDir });
43
+ console.log('⚠️ Warning: Using legacy chatmodes format. Consider upgrading to custom agents.');
44
+ } else {
45
+ // New format: Custom agents with handoffs and runSubagent support
46
+ outputDir = path.join(cwd, '.github', 'agents');
47
+ const agents = setupGithubCopilot({ srcAgentsDir, destAgentsDir: outputDir });
48
+ console.log(`✅ Created ${agents?.length || 0} custom agents in .github/agents/`);
49
+ }
50
+
51
+ // 3) Create copilot-instructions.md for workspace-wide settings
52
+ const instructionsDir = path.join(cwd, '.github');
53
+ fs.mkdirpSync(instructionsDir);
54
+ const copilotInstructionsPath = path.join(instructionsDir, 'copilot-instructions.md');
55
+ if (!fs.existsSync(copilotInstructionsPath)) {
56
+ const copilotInstructions = `# AIgile Copilot Instructions
57
+
58
+ This project uses the AIgile framework for AI-assisted development.
59
+
60
+ ## Custom Agents
61
+
62
+ Custom agents are available in \`.github/agents/\`. Use them by selecting from the agent dropdown in Copilot Chat.
63
+
64
+ ### Available Agents
65
+ - **aigile-orchestrator**: Master orchestrator - coordinates workflows and delegates to specialists
66
+ - **dev**: Full Stack Developer - implementation, debugging, TDD
67
+ - **architect**: Software Architect - architecture review, documentation
68
+ - **po**: Product Owner - story creation, backlog management
69
+ - **qa**: QA Engineer - testing, quality gates
70
+ - **analyst**: Business Analyst - requirements analysis
71
+ - **pm**: Project Manager - project planning
72
+ - **sm**: Scrum Master - ceremonies, team coordination
73
+ - **ui-expert**: UI Expert - design systems, Figma
74
+ - **ux-expert**: UX Expert - user experience design
75
+
76
+ ## Subagent Delegation
77
+
78
+ The orchestrator and specialist agents can delegate tasks using \`#tool:runSubagent\`.
79
+ This enables autonomous multi-step workflows where complex tasks are broken down
80
+ and routed to the appropriate specialist.
81
+
82
+ ## Handoffs
83
+
84
+ Agents support handoffs - use the handoff buttons after a response to transition
85
+ to another specialist with context preserved.
86
+
87
+ ## Project Configuration
88
+
89
+ See \`.aigile-core/core-config.yaml\` for project-specific settings.
90
+ `;
91
+ fs.writeFileSync(copilotInstructionsPath, copilotInstructions, 'utf8');
92
+ }
93
+
94
+ // 4) Optional MCP scaffolding into .vscode (disabled by default for Copilot-only)
95
+ if(withMcp){
96
+ const vsSettingsDir = path.join(cwd, '.vscode');
97
+ fs.mkdirpSync(vsSettingsDir);
98
+ const settingsPath = path.join(vsSettingsDir, 'settings.json');
99
+ if(!fs.existsSync(settingsPath)){
100
+ fs.writeFileSync(settingsPath, JSON.stringify({
101
+ "aigile.mcp": { enabled: true },
102
+ "github.copilot.chat.customAgents.showOrganizationAndEnterpriseAgents": true
103
+ }, null, 2));
104
+ }
105
+ }
106
+
107
+ if(includeJavaInstructions){
108
+ const javaInstructionsSrc = path.join(projectRoot, 'core', 'instructions', 'java.instructions.md');
109
+ if(fs.existsSync(javaInstructionsSrc)){
110
+ const instructionsDest = path.join(cwd, '.github', 'instructions');
111
+ fs.mkdirpSync(instructionsDest);
112
+ fs.copyFileSync(javaInstructionsSrc, path.join(instructionsDest, 'java.instructions.md'));
113
+ }
114
+ }
115
+
116
+ // Marker file with version info
117
+ const markerContent = JSON.stringify({
118
+ version: '0.3.0',
119
+ format: useLegacyChatmodes ? 'chatmodes' : 'agents',
120
+ installedAt: new Date().toISOString(),
121
+ features: {
122
+ customAgents: !useLegacyChatmodes,
123
+ handoffs: !useLegacyChatmodes,
124
+ runSubagent: !useLegacyChatmodes,
125
+ mcp: withMcp
126
+ }
127
+ }, null, 2);
128
+ fs.writeFileSync(path.join(cwd, '.aigile'), markerContent, 'utf8');
129
+
130
+ return { coreDest, agentsDir: outputDir, chatmodesDir: useLegacyChatmodes ? outputDir : null };
131
+ }
@@ -0,0 +1,21 @@
1
+ # Web Agent Bundle Instructions
2
+
3
+ This header is included at the top of each generated AIgile bundle (team and per-agent) to provide context for downstream tooling and validation.
4
+
5
+ Purpose:
6
+ - Identify the file as a structured AIgile bundle
7
+ - Provide quick usage guidance
8
+ - Ensure automated validators can assert presence (looks for the phrase: Web Agent Bundle Instructions)
9
+
10
+ Usage Guidance:
11
+ 1. Each subsequent section is wrapped with START/END markers of the form:
12
+ ==================== START: .aigile-core/<relative-path> ====================
13
+ (content)
14
+ ==================== END: .aigile-core/<relative-path> ====================
15
+ 2. Tools parsing this file should iterate over marker pairs to reconstruct original source files under `.aigile-core/`.
16
+ 3. Do not edit marker lines manually—regenerate bundles instead (`npm run build`).
17
+ 4. Additional metadata or future headers can be appended below this notice.
18
+
19
+ Notes:
20
+ - Missing this header triggers validation failure.
21
+ - Keep this concise; large instructions inflate bundle size.
@@ -0,0 +1,72 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Postinstall bootstrap for @mark-gozner/aigile-method
4
+ *
5
+ * Goal: Allow a single command install:
6
+ * npm install @mark-gozner/aigile-method
7
+ * which automatically lays down .aigile-core and agents in the *consuming* project.
8
+ *
9
+ * Safeguards / Opt-outs:
10
+ * - Set AIGILE_NO_POSTINSTALL=1 to skip entirely
11
+ * - Set CI=true (common in pipelines) to skip (avoid polluting build images)
12
+ * - Set AIGILE_INSTALL_ARGS="--with-mcp" to pass extra flags
13
+ * - Set AIGILE_SILENT=1 to suppress non-error logging
14
+ *
15
+ * Behavior:
16
+ * 1. Detect if running inside the package itself (development) -> if so, skip
17
+ * 2. Otherwise invoke tools/cli.js install with optional flags
18
+ */
19
+ import { fileURLToPath } from 'node:url';
20
+ import path from 'node:path';
21
+ import { spawn } from 'node:child_process';
22
+ import fs from 'node:fs';
23
+
24
+ const __filename = fileURLToPath(import.meta.url);
25
+ const __dirname = path.dirname(__filename);
26
+ const pkgRoot = path.resolve(__dirname, '..');
27
+
28
+ function log(msg){ if(!process.env.AIGILE_SILENT) console.log(`[aigile-postinstall] ${msg}`); }
29
+ function warn(msg){ console.warn(`[aigile-postinstall] WARN: ${msg}`); }
30
+ function skip(reason){ log(`Skipped automatic install: ${reason}`); process.exit(0); }
31
+
32
+ // 1. Global skips
33
+ if(process.env.AIGILE_NO_POSTINSTALL === '1') skip('AIGILE_NO_POSTINSTALL=1');
34
+ if(process.env.CI === 'true') skip('CI=true');
35
+
36
+ // 2. Detect if we're inside the package's own repo (development scenario)
37
+ // Heuristic: presence of .git AND core/agents folder at same root as this script.
38
+ const devIndicators = [
39
+ path.join(pkgRoot, '.git'),
40
+ path.join(pkgRoot, 'core', 'agents')
41
+ ];
42
+ const looksLikeDev = devIndicators.every(p => fs.existsSync(p));
43
+ if(looksLikeDev) skip('development workspace detected');
44
+
45
+ // 3. Determine project root (one level above node_modules/<this package>)
46
+ // process.cwd() during postinstall is the consuming project root for npm (unless workspaces alter it)
47
+ const projectRoot = process.cwd();
48
+ if(projectRoot.startsWith(pkgRoot)) {
49
+ // Unusual but guard anyway
50
+ skip('ambiguous install path (project root equals package root)');
51
+ }
52
+
53
+ // 4. Build args
54
+ const extra = process.env.AIGILE_INSTALL_ARGS ? process.env.AIGILE_INSTALL_ARGS.split(/\s+/).filter(Boolean) : [];
55
+ const cliPath = path.join(pkgRoot, 'tools', 'cli.js');
56
+ // Use 'install' command with --yes for non-interactive install
57
+ const args = [cliPath, 'install', '--yes'];
58
+ args.push(...extra);
59
+
60
+ log(`Running automatic install into consumer project: ${projectRoot}`);
61
+ log(`Command: node ${args.map(a => (a.includes(' ') ? '"'+a+'"' : a)).join(' ')}`);
62
+
63
+ const child = spawn(process.execPath, args, {
64
+ cwd: projectRoot,
65
+ stdio: 'inherit',
66
+ env: process.env
67
+ });
68
+
69
+ child.on('exit', (code) => {
70
+ if(code === 0) log('AIgile installed successfully (postinstall).');
71
+ else warn(`AIgile postinstall exited with code ${code}. You can rerun: npx @mark-gozner/aigile-method install`);
72
+ });
@@ -0,0 +1,68 @@
1
+ // Simple ASCII banners for AIgile installer output (ESM)
2
+
3
+ export const AIGILE_TITLE = 'AIgile-Method';
4
+ export const INSTALLER_TITLE = 'INSTALLER';
5
+
6
+ export const AIGILE_LARGE = `
7
+ █████╗ ██╗ ██████╗ ██╗██╗ ███████╗ ██╗███╗ ██╗███████╗████████╗ █████╗ ██╗ ██╗ ███████╗██████╗
8
+ ██╔══██╗██║██╔════╝ ██║██║ ██╔════╝ ██║████╗ ██║██╔════╝╚══██╔══╝██╔══██╗██║ ██║ ██╔════╝██╔══██╗
9
+ ███████║██║██║ ███╗██║██║ █████╗ ██║██╔██╗ ██║███████╗ ██║ ███████║██║ ██║ █████╗ ██████╔╝
10
+ ██╔══██║██║██║ ██║██║██║ ██╔══╝ ██║██║╚██╗██║╚════██║ ██║ ██╔══██║██║ ██║ ██╔══╝ ██╔══██╗
11
+ ██║ ██║██║╚██████╔╝██║███████╗███████╗ ██║██║ ╚████║███████║ ██║ ██║ ██║███████╗███████╗███████╗██║ ██║
12
+ ╚═╝ ╚═╝╚═╝ ╚═════╝ ╚═╝╚══════╝╚══════╝ ╚═╝╚═╝ ╚═══╝╚══════╝ ╚═╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚══════╝╚═╝ ╚═╝
13
+
14
+ `;
15
+
16
+ export const INSTALLER_SMALL = `
17
+ ╭──────────────────────────╮
18
+ │ AIgile Installer │
19
+ ╰──────────────────────────╯
20
+ `;
21
+
22
+ // GM signature banners
23
+ export const GM_LARGE = `
24
+ ██████╗██████╗ ███████╗ █████╗ ████████╗███████╗██████╗ ██████╗ ██╗ ██╗ ██████╗ ███╗ ███╗
25
+ ██╔════╝██╔══██╗██╔════╝██╔══██╗╚══██╔══╝██╔════╝██╔══██╗ ██╔══██╗╚██╗ ██╔╝ ██╔════╝ ████╗ ████║
26
+ ██║ ██████╔╝█████╗ ███████║ ██║ █████╗ ██║ ██║ ██████╔╝ ╚████╔╝ ██║ ███╗██╔████╔██║
27
+ ██║ ██╔══██╗██╔══╝ ██╔══██║ ██║ ██╔══╝ ██║ ██║ ██╔══██╗ ╚██╔╝ ██║ ██║██║╚██╔╝██║
28
+ ╚██████╗██║ ██║███████╗██║ ██║ ██║ ███████╗██████╔╝ ██████╔╝ ██║ ╚██████╔╝██║ ╚═╝ ██║
29
+ ╚═════╝╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝ ╚═╝ ╚══════╝╚═════╝ ╚═════╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝
30
+
31
+ `;
32
+ export const GM_MEDIUM = `
33
+ ╭──────────────────────────╮
34
+ │ Created by GM │
35
+ ╰──────────────────────────╯
36
+ `;
37
+
38
+ function applyGradient(text, startColor, endColor) {
39
+ const length = text.length;
40
+ let result = '';
41
+
42
+ for (let i = 0; i < length; i++) {
43
+ const char = text[i];
44
+ if (char === '\n') {
45
+ result += char;
46
+ continue;
47
+ }
48
+ const ratio = i / length;
49
+ const r = Math.round(startColor.r + ratio * (endColor.r - startColor.r));
50
+ const g = Math.round(startColor.g + ratio * (endColor.g - startColor.g));
51
+ const b = Math.round(startColor.b + ratio * (endColor.b - startColor.b));
52
+ result += `\x1b[38;2;${r};${g};${b}m${char}\x1b[0m`;
53
+ }
54
+
55
+ return result;
56
+ }
57
+
58
+ export function printInstallBanner({ showGMSignature = true } = {}) {
59
+ const neonGreen = { r: 57, g: 255, b: 20 }; // Neon green
60
+ const cyan = { r: 0, g: 255, b: 255 }; // Cyan
61
+ const magenta = { r: 255, g: 0, b: 255 }; // Magenta
62
+ const orange = { r: 255, g: 165, b: 0 }; // Orange
63
+
64
+ console.log('\n' + applyGradient(AIGILE_LARGE, neonGreen, cyan));
65
+ if (showGMSignature) {
66
+ console.log(applyGradient(GM_LARGE, magenta, orange));
67
+ }
68
+ }
@@ -0,0 +1,54 @@
1
+ #!/usr/bin/env node
2
+ import fs from 'node:fs';
3
+ import path from 'node:path';
4
+ import { fileURLToPath } from 'node:url';
5
+
6
+ const __filename = fileURLToPath(import.meta.url);
7
+ const __dirname = path.dirname(__filename);
8
+ const root = path.resolve(__dirname, '..');
9
+ const dist = path.join(root, 'dist');
10
+
11
+ function fail(msg){
12
+ console.error('❌', msg);
13
+ process.exitCode = 1;
14
+ }
15
+
16
+ function ok(msg){
17
+ console.log('✅', msg);
18
+ }
19
+
20
+ function mustExist(p){
21
+ if(!fs.existsSync(p)) fail(`Missing: ${path.relative(root, p)}`);
22
+ else ok(`Exists: ${path.relative(root, p)}`);
23
+ }
24
+
25
+ function checkMarkers(file){
26
+ const txt = fs.readFileSync(file, 'utf8');
27
+ if(!txt.includes('Web Agent Bundle Instructions')) fail(`${path.basename(file)} missing header`);
28
+ const startCount = (txt.match(/==================== START:/g) || []).length;
29
+ const endCount = (txt.match(/==================== END:/g) || []).length;
30
+ if(startCount === 0 || endCount === 0) fail(`${path.basename(file)} missing START/END markers`);
31
+ if(startCount !== endCount) fail(`${path.basename(file)} START/END count mismatch (${startCount} vs ${endCount})`);
32
+ else ok(`${path.basename(file)} markers balanced (${startCount})`);
33
+ if(!txt.includes('.aigile-core/')) fail(`${path.basename(file)} missing .aigile-core paths`);
34
+ }
35
+
36
+ function main(){
37
+ mustExist(dist);
38
+ const team = path.join(dist, 'teams', 'team-company.txt');
39
+ const agentsDir = path.join(dist, 'agents');
40
+ mustExist(team);
41
+ mustExist(agentsDir);
42
+ const dev = path.join(agentsDir, 'dev.txt');
43
+ if(fs.existsSync(dev)) ok('dev agent bundle present');
44
+ else console.warn('ℹ️ dev agent bundle not found (ok if no dev.md)');
45
+ checkMarkers(team);
46
+ if(fs.existsSync(dev)) checkMarkers(dev);
47
+
48
+ // Sanity: ensure team includes at least one agent file content by looking for core/agents/
49
+ const teamTxt = fs.readFileSync(team, 'utf8');
50
+ if(!teamTxt.includes('/agents/')) fail('team-company.txt does not seem to include any agent content');
51
+ else ok('team-company.txt includes agent content');
52
+ }
53
+
54
+ main();