@iservu-inc/adf-cli 0.16.0 → 0.17.1

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 (44) hide show
  1. package/.context/memory/architecture.md +1 -1
  2. package/.context/memory/glossary.md +1 -1
  3. package/CLAUDE.md +4 -4
  4. package/README.md +1 -1
  5. package/lib/analysis/heuristic-gap-analyzer.js +4 -4
  6. package/lib/analysis/synthesis-engine.js +5 -5
  7. package/lib/commands/deploy.js +14 -0
  8. package/lib/commands/guide.js +32 -0
  9. package/lib/commands/init.js +544 -458
  10. package/lib/frameworks/output-generators.js +54 -147
  11. package/lib/frameworks/progress-tracker.js +16 -0
  12. package/lib/frameworks/questions.js +156 -464
  13. package/lib/frameworks/session-manager.js +56 -0
  14. package/lib/generators/a2a-generator.js +289 -0
  15. package/lib/generators/index.js +11 -0
  16. package/lib/learning/analytics-view.js +5 -5
  17. package/lib/learning/analytics.js +22 -6
  18. package/lib/templates/scripts/analyze-docs.js +11 -11
  19. package/lib/templates/scripts/build.js +1 -1
  20. package/lib/templates/scripts/check-framework-updates.js +1 -1
  21. package/lib/templates/scripts/init.js +1 -1
  22. package/lib/templates/shared/agents/analyst.md +1 -1
  23. package/lib/templates/shared/agents/architect.md +1 -1
  24. package/lib/templates/shared/agents/dev.md +1 -1
  25. package/lib/templates/shared/agents/pm.md +2 -2
  26. package/lib/templates/shared/agents/qa.md +1 -1
  27. package/lib/templates/shared/agents/sm.md +3 -3
  28. package/lib/templates/shared/memory/constitution.md +2 -2
  29. package/lib/templates/shared/templates/README.md +13 -13
  30. package/lib/templates/shared/templates/prd-template.md +1 -1
  31. package/lib/utils/context-extractor.js +3 -3
  32. package/lib/utils/framework-detector.js +1 -1
  33. package/lib/utils/tool-feature-registry.js +6 -0
  34. package/package.json +1 -1
  35. package/tests/a2a-generator.test.js +288 -0
  36. package/tests/analytics-view.test.js +12 -10
  37. package/tests/context-extractor.test.js +2 -2
  38. package/tests/decay-manager.test.js +22 -19
  39. package/tests/deploy.test.js +7 -3
  40. package/tests/dynamic-question-generator.test.js +2 -2
  41. package/tests/framework-detector.test.js +3 -3
  42. package/tests/heuristic-gap-analyzer.test.js +5 -5
  43. package/tests/pattern-decay.test.js +34 -52
  44. package/tests/session-manager.test.js +125 -0
@@ -2,6 +2,7 @@ const fs = require('fs-extra');
2
2
  const path = require('path');
3
3
  const chalk = require('chalk');
4
4
  const inquirer = require('inquirer');
5
+ const { getQuestionsForFramework } = require('./questions');
5
6
 
6
7
  /**
7
8
  * Session Manager
@@ -45,6 +46,61 @@ class SessionManager {
45
46
  return sessions.filter(s => s.progress.status === 'in-progress' && s.progress.canResume);
46
47
  }
47
48
 
49
+ async getSessionsWithDetails() {
50
+ const sessions = await this.listSessions();
51
+ const detailed = [];
52
+
53
+ for (const session of sessions) {
54
+ const { progress } = session;
55
+ const framework = progress.framework || 'rapid';
56
+ const questions = getQuestionsForFramework(framework);
57
+ const totalQuestions = questions.length;
58
+
59
+ // Count answers that match actual framework questions
60
+ const questionIds = new Set(questions.map(q => q.id));
61
+ const answeredCount = Object.keys(progress.answers || {})
62
+ .filter(id => questionIds.has(id)).length;
63
+ const unansweredCount = totalQuestions - answeredCount;
64
+
65
+ detailed.push({
66
+ ...session,
67
+ totalQuestions,
68
+ answeredCount,
69
+ unansweredCount,
70
+ hasGaps: unansweredCount > 0
71
+ });
72
+ }
73
+
74
+ return detailed;
75
+ }
76
+
77
+ async reopenSession(sessionId) {
78
+ const sessionPath = path.join(this.sessionsDir, sessionId);
79
+ const progressFile = path.join(sessionPath, '_progress.json');
80
+
81
+ if (!await fs.pathExists(progressFile)) {
82
+ throw new Error(`Session not found: ${sessionId}`);
83
+ }
84
+
85
+ const progress = await fs.readJson(progressFile);
86
+
87
+ // Reset status to in-progress while preserving all answer data
88
+ progress.status = 'in-progress';
89
+ progress.canResume = true;
90
+ progress.completedAt = null;
91
+
92
+ // Reset block-tracking counters to avoid duplicates when interviewer
93
+ // replays blocks (it pushes to completedBlocks and increments cumulatively)
94
+ progress.completedBlocks = [];
95
+ progress.skippedBlocks = [];
96
+ progress.totalQuestionsAnswered = 0;
97
+ progress.currentBlock = 0;
98
+
99
+ await fs.writeJson(progressFile, progress, { spaces: 2 });
100
+
101
+ return { sessionId, sessionPath, progress };
102
+ }
103
+
48
104
  async promptToResume() {
49
105
  const resumableSessions = await this.getResumableSessions();
50
106
 
@@ -0,0 +1,289 @@
1
+ const fs = require('fs-extra');
2
+ const path = require('path');
3
+ const ToolConfigGenerator = require('./tool-config-generator');
4
+
5
+ /**
6
+ * Generator for A2A (Agent-to-Agent) protocol agent cards
7
+ * Creates compliant agent discovery cards for interoperability
8
+ * with any A2A-compatible tool.
9
+ *
10
+ * Output structure:
11
+ * .a2a/
12
+ * ├── agent-card.json # Combined discovery card (all agents)
13
+ * └── agents/
14
+ * ├── dev.json # Individual agent cards
15
+ * ├── qa.json
16
+ * └── ...
17
+ */
18
+ class A2AGenerator extends ToolConfigGenerator {
19
+ /**
20
+ * Generate A2A agent cards for all agents in the current framework
21
+ */
22
+ async generate() {
23
+ await this.initialize();
24
+
25
+ const a2aDir = path.join(this.projectPath, '.a2a');
26
+ const agentsDir = path.join(a2aDir, 'agents');
27
+ await fs.ensureDir(agentsDir);
28
+
29
+ const agentsList = this.getAgentsList();
30
+ const individualCards = [];
31
+
32
+ for (const agentName of agentsList) {
33
+ const card = await this.generateAgentCard(agentName);
34
+ if (card) {
35
+ await fs.writeJson(
36
+ path.join(agentsDir, `${agentName}.json`),
37
+ card,
38
+ { spaces: 2 }
39
+ );
40
+ individualCards.push(card);
41
+ }
42
+ }
43
+
44
+ const combinedCard = this.generateCombinedCard(individualCards);
45
+ await fs.writeJson(
46
+ path.join(a2aDir, 'agent-card.json'),
47
+ combinedCard,
48
+ { spaces: 2 }
49
+ );
50
+
51
+ return {
52
+ agentCard: path.join(a2aDir, 'agent-card.json'),
53
+ agents: agentsList.map(a => path.join(agentsDir, `${a}.json`))
54
+ };
55
+ }
56
+
57
+ /**
58
+ * Generate an individual A2A agent card from agent markdown frontmatter
59
+ */
60
+ async generateAgentCard(agentName) {
61
+ const agentPath = path.join(__dirname, '../templates/shared/agents', `${agentName}.md`);
62
+
63
+ if (!await fs.pathExists(agentPath)) {
64
+ return null;
65
+ }
66
+
67
+ const content = await fs.readFile(agentPath, 'utf-8');
68
+ const frontmatter = this.parseAgentFrontmatter(content);
69
+ const skills = this.mapAgentToSkills(agentName, frontmatter);
70
+
71
+ const agentId = (frontmatter.agent && frontmatter.agent.id) || agentName;
72
+ const agentDisplayName = (frontmatter.agent && frontmatter.agent.name) || agentName;
73
+ const role = (frontmatter.agent && frontmatter.agent.role) || agentName;
74
+ const focus = (frontmatter.agent && frontmatter.agent.focus) || '';
75
+
76
+ const description = focus ? `${role} - ${focus}` : role;
77
+
78
+ return {
79
+ name: `ADF ${agentDisplayName} Agent`,
80
+ description,
81
+ version: this.getADFVersion(),
82
+ url: `local://adf/agents/${agentId}`,
83
+ supportedInterfaces: [{
84
+ url: `local://adf/agents/${agentId}`,
85
+ protocolBinding: 'JSONRPC',
86
+ protocolVersion: '0.3'
87
+ }],
88
+ defaultInputModes: ['text/plain', 'application/json'],
89
+ defaultOutputModes: ['text/plain', 'application/json'],
90
+ capabilities: {
91
+ streaming: false,
92
+ pushNotifications: false
93
+ },
94
+ provider: {
95
+ organization: 'ADF CLI',
96
+ url: 'https://github.com/iservu-inc/adf-cli'
97
+ },
98
+ skills
99
+ };
100
+ }
101
+
102
+ /**
103
+ * Generate combined agent-card.json with all agents' skills merged
104
+ */
105
+ generateCombinedCard(individualCards) {
106
+ const projectName = this.getProjectName();
107
+ const allSkills = [];
108
+
109
+ for (const card of individualCards) {
110
+ if (card.skills) {
111
+ allSkills.push(...card.skills);
112
+ }
113
+ }
114
+
115
+ return {
116
+ name: `ADF ${projectName} Agents`,
117
+ description: `Agent-to-Agent discovery card for ${projectName} (${this.framework} workflow)`,
118
+ version: this.getADFVersion(),
119
+ url: 'local://adf/agents',
120
+ supportedInterfaces: [{
121
+ url: 'local://adf/agents',
122
+ protocolBinding: 'JSONRPC',
123
+ protocolVersion: '0.3'
124
+ }],
125
+ defaultInputModes: ['text/plain', 'application/json'],
126
+ defaultOutputModes: ['text/plain', 'application/json'],
127
+ capabilities: {
128
+ streaming: false,
129
+ pushNotifications: false
130
+ },
131
+ provider: {
132
+ organization: 'ADF CLI',
133
+ url: 'https://github.com/iservu-inc/adf-cli'
134
+ },
135
+ skills: allSkills,
136
+ agents: individualCards.map(card => ({
137
+ name: card.name,
138
+ url: card.url,
139
+ description: card.description
140
+ }))
141
+ };
142
+ }
143
+
144
+ /**
145
+ * Parse YAML frontmatter from agent markdown file
146
+ */
147
+ parseAgentFrontmatter(content) {
148
+ const match = content.match(/^---\n([\s\S]*?)\n---/);
149
+ if (!match) return {};
150
+
151
+ const yaml = match[1];
152
+ return this.simpleYamlParse(yaml);
153
+ }
154
+
155
+ /**
156
+ * Simple YAML parser for agent frontmatter
157
+ * Handles the specific nested structure used in agent files
158
+ */
159
+ simpleYamlParse(yaml) {
160
+ const result = {};
161
+ const lines = yaml.split('\n');
162
+ let currentTopKey = null;
163
+ let currentSubKey = null;
164
+ let currentArray = null;
165
+
166
+ for (const line of lines) {
167
+ // Skip empty lines and comments
168
+ if (!line.trim() || line.trim().startsWith('#')) continue;
169
+
170
+ // Check for top-level key (no indentation)
171
+ const topMatch = line.match(/^(\w[\w_]*):(.*)$/);
172
+ if (topMatch) {
173
+ currentTopKey = topMatch[1];
174
+ const value = topMatch[2].trim();
175
+ if (value && !value.startsWith('|')) {
176
+ result[currentTopKey] = value;
177
+ } else if (!value) {
178
+ result[currentTopKey] = {};
179
+ }
180
+ currentSubKey = null;
181
+ currentArray = null;
182
+ continue;
183
+ }
184
+
185
+ // Check for sub-key (2-space indentation)
186
+ const subMatch = line.match(/^ (\w[\w_]*):(.*)$/);
187
+ if (subMatch && currentTopKey) {
188
+ currentSubKey = subMatch[1];
189
+ const value = subMatch[2].trim();
190
+ if (typeof result[currentTopKey] !== 'object') {
191
+ result[currentTopKey] = {};
192
+ }
193
+ if (value) {
194
+ result[currentTopKey][currentSubKey] = value;
195
+ } else {
196
+ result[currentTopKey][currentSubKey] = [];
197
+ currentArray = result[currentTopKey][currentSubKey];
198
+ }
199
+ continue;
200
+ }
201
+
202
+ // Check for array item (4-space indentation with dash)
203
+ const arrayMatch = line.match(/^ - (.+)$/);
204
+ if (arrayMatch && currentArray) {
205
+ // Strip inline comments
206
+ const val = arrayMatch[1].replace(/#.*$/, '').trim();
207
+ currentArray.push(val);
208
+ continue;
209
+ }
210
+
211
+ // Check for top-level array item (2-space indentation with dash)
212
+ const topArrayMatch = line.match(/^ - (.+)$/);
213
+ if (topArrayMatch && currentTopKey && !currentSubKey) {
214
+ if (!Array.isArray(result[currentTopKey])) {
215
+ result[currentTopKey] = [];
216
+ }
217
+ const val = topArrayMatch[1].replace(/#.*$/, '').trim();
218
+ result[currentTopKey].push(val);
219
+ }
220
+ }
221
+
222
+ return result;
223
+ }
224
+
225
+ /**
226
+ * Map an ADF agent's frontmatter to A2A skills
227
+ */
228
+ mapAgentToSkills(agentName, frontmatter) {
229
+ const AGENT_SKILLS = {
230
+ dev: [
231
+ { id: 'tdd-implementation', name: 'TDD Implementation', description: 'Test-driven development with context engineering', tags: ['development', 'tdd', 'testing'] },
232
+ { id: 'code-review', name: 'Code Review', description: 'Self-review against coding standards', tags: ['development', 'review'] },
233
+ { id: 'refactoring', name: 'Refactoring', description: 'Code refactoring while maintaining tests', tags: ['development', 'refactoring'] }
234
+ ],
235
+ qa: [
236
+ { id: 'risk-assessment', name: 'Risk Assessment', description: 'Identify and score project risks', tags: ['quality', 'risk'] },
237
+ { id: 'test-design', name: 'Test Design', description: 'Comprehensive test strategy creation', tags: ['quality', 'testing'] },
238
+ { id: 'quality-gates', name: 'Quality Gates', description: 'Quality gate management and decisions', tags: ['quality', 'gates'] }
239
+ ],
240
+ pm: [
241
+ { id: 'requirements-gathering', name: 'Requirements Gathering', description: 'Product requirements analysis and documentation', tags: ['product', 'requirements'] },
242
+ { id: 'story-creation', name: 'Story Creation', description: 'User story and specification writing', tags: ['product', 'stories'] },
243
+ { id: 'project-planning', name: 'Project Planning', description: 'Sprint planning and backlog management', tags: ['product', 'planning'] }
244
+ ],
245
+ analyst: [
246
+ { id: 'market-analysis', name: 'Market Analysis', description: 'Market research and competitive analysis', tags: ['analysis', 'market'] },
247
+ { id: 'business-requirements', name: 'Business Requirements', description: 'Business requirements documentation', tags: ['analysis', 'requirements'] }
248
+ ],
249
+ architect: [
250
+ { id: 'system-design', name: 'System Design', description: 'System architecture and technical design', tags: ['architecture', 'design'] },
251
+ { id: 'tech-stack-selection', name: 'Tech Stack Selection', description: 'Technology evaluation and selection', tags: ['architecture', 'technology'] }
252
+ ],
253
+ sm: [
254
+ { id: 'sprint-management', name: 'Sprint Management', description: 'Agile sprint planning and execution', tags: ['agile', 'sprint'] },
255
+ { id: 'ceremony-facilitation', name: 'Ceremony Facilitation', description: 'Scrum ceremony facilitation', tags: ['agile', 'ceremonies'] }
256
+ ]
257
+ };
258
+
259
+ const skills = AGENT_SKILLS[agentName] || [];
260
+
261
+ // Enrich with MCP tools from frontmatter if present
262
+ if (frontmatter.mcp_tools && Array.isArray(frontmatter.mcp_tools)) {
263
+ for (const tool of frontmatter.mcp_tools) {
264
+ skills.push({
265
+ id: `mcp-${tool}`,
266
+ name: `MCP: ${tool}`,
267
+ description: `Integration with ${tool} MCP server`,
268
+ tags: ['mcp', tool]
269
+ });
270
+ }
271
+ }
272
+
273
+ return skills;
274
+ }
275
+
276
+ /**
277
+ * Get ADF CLI version from package.json
278
+ */
279
+ getADFVersion() {
280
+ try {
281
+ const packageJson = require('../../package.json');
282
+ return packageJson.version;
283
+ } catch (error) {
284
+ return '0.16.0';
285
+ }
286
+ }
287
+ }
288
+
289
+ module.exports = A2AGenerator;
@@ -15,6 +15,7 @@ const DeepAgentGenerator = require('./deepagent-generator');
15
15
  const KiroGenerator = require('./kiro-generator');
16
16
  const TraeGenerator = require('./trae-generator');
17
17
  const CodexCLIGenerator = require('./codex-cli-generator');
18
+ const A2AGenerator = require('./a2a-generator');
18
19
  const ToolConfigGenerator = require('./tool-config-generator');
19
20
 
20
21
  /**
@@ -171,6 +172,14 @@ async function generateCodexCLI(sessionPath, projectPath, framework) {
171
172
  return await generator.generate();
172
173
  }
173
174
 
175
+ /**
176
+ * Generate A2A (Agent-to-Agent) protocol agent cards
177
+ */
178
+ async function generateA2A(sessionPath, projectPath, framework) {
179
+ const generator = new A2AGenerator(sessionPath, projectPath, framework);
180
+ return await generator.generate();
181
+ }
182
+
174
183
  module.exports = {
175
184
  generateAll,
176
185
  generateAgentsMd,
@@ -185,6 +194,7 @@ module.exports = {
185
194
  generateKiro,
186
195
  generateTrae,
187
196
  generateCodexCLI,
197
+ generateA2A,
188
198
  AgentsMdGenerator,
189
199
  WindsurfGenerator,
190
200
  CursorGenerator,
@@ -197,5 +207,6 @@ module.exports = {
197
207
  KiroGenerator,
198
208
  TraeGenerator,
199
209
  CodexCLIGenerator,
210
+ A2AGenerator,
200
211
  ToolConfigGenerator
201
212
  };
@@ -261,14 +261,14 @@ async function showTimelineView(analyticsData) {
261
261
 
262
262
  console.log(chalk.bold('📅 SESSION HISTORY\n'));
263
263
  console.log(`Total Sessions: ${chalk.cyan(sessionTimeline.totalSessions)}`);
264
- console.log(`Sessions per Week: ${chalk.yellow(sessionTimeline.sessionsPerWeek)}`);
264
+ console.log(`Sessions per Week: ${chalk.yellow(sessionTimeline.avgSessionsPerWeek)}`);
265
265
  console.log(`First Session: ${chalk.white(sessionTimeline.firstSession || 'N/A')}`);
266
266
  console.log(`Last Session: ${chalk.white(sessionTimeline.lastSession || 'N/A')}\n`);
267
267
 
268
- if (sessionTimeline.timeline.length > 0) {
268
+ if (sessionTimeline.sessions.length > 0) {
269
269
  console.log(chalk.bold('Recent Sessions (Last 10):\n'));
270
270
 
271
- const recentSessions = sessionTimeline.timeline.slice(0, 10);
271
+ const recentSessions = sessionTimeline.sessions.slice(0, 10);
272
272
 
273
273
  for (const session of recentSessions) {
274
274
  const date = new Date(session.timestamp).toLocaleDateString();
@@ -336,8 +336,8 @@ async function showImpactfulPatternsView(analyticsData) {
336
336
 
337
337
  // Top by time saved
338
338
  console.log(chalk.bold('⏱️ TOP PATTERNS BY TIME SAVED\n'));
339
- if (impactfulPatterns.topByTimeSaved.length > 0) {
340
- impactfulPatterns.topByTimeSaved.forEach((item, i) => {
339
+ if (impactfulPatterns.byTimeSaved.length > 0) {
340
+ impactfulPatterns.byTimeSaved.forEach((item, i) => {
341
341
  console.log(`${chalk.green((i + 1) + '.')} ${item.pattern.questionText || item.pattern.questionId}`);
342
342
  console.log(` ${chalk.gray(`${item.timeSaved} minutes saved | ${item.appliedCount} applications | ${item.pattern.confidence}% confidence`)}\n`);
343
343
  });
@@ -363,8 +363,8 @@ function calculateSessionTimeline(skipHistory, answerHistory) {
363
363
  }
364
364
 
365
365
  return {
366
- timeline,
367
- sessionsPerWeek,
366
+ sessions: timeline,
367
+ avgSessionsPerWeek: sessionsPerWeek,
368
368
  totalSessions: sessions.length,
369
369
  firstSession,
370
370
  lastSession
@@ -401,10 +401,10 @@ function calculateImpactfulPatterns(patterns, rules, skipHistory) {
401
401
  }
402
402
 
403
403
  return {
404
- topByTimeSaved: impactData
404
+ byTimeSaved: impactData
405
405
  .sort((a, b) => b.timeSaved - a.timeSaved)
406
406
  .slice(0, 5),
407
- topByApplications: impactData
407
+ byApplications: impactData
408
408
  .sort((a, b) => b.appliedCount - a.appliedCount)
409
409
  .slice(0, 5),
410
410
  perfectConfidence: patterns.filter(p => p.confidence === 100),
@@ -477,7 +477,8 @@ function calculateQuestionStats(skipHistory, answerHistory) {
477
477
  lowestSkipRate: stats
478
478
  .filter(q => q.skips + q.answers > 0)
479
479
  .sort((a, b) => a.skipRate - b.skipRate)
480
- .slice(0, 10)
480
+ .slice(0, 10),
481
+ totalUniqueQuestions: Object.keys(questionData).length
481
482
  };
482
483
  }
483
484
 
@@ -506,11 +507,15 @@ function getLast12Weeks() {
506
507
  for (let i = 11; i >= 0; i--) {
507
508
  const weekStart = new Date(now);
508
509
  weekStart.setDate(now.getDate() - (i * 7));
510
+ weekStart.setHours(0, 0, 0, 0);
509
511
  const weekEnd = new Date(weekStart);
510
512
  weekEnd.setDate(weekStart.getDate() + 6);
513
+ weekEnd.setHours(23, 59, 59, 999);
514
+
515
+ const isoLabel = getISOWeekLabel(weekStart);
511
516
 
512
517
  weeks.push({
513
- label: `Week ${getWeekNumber(weekStart)}`,
518
+ label: isoLabel,
514
519
  weekNumber: getWeekNumber(weekStart),
515
520
  start: weekStart,
516
521
  end: weekEnd
@@ -531,6 +536,17 @@ function getWeekNumber(date) {
531
536
  return Math.ceil((pastDaysOfYear + firstDayOfYear.getDay() + 1) / 7);
532
537
  }
533
538
 
539
+ /**
540
+ * Get ISO week label for a date (e.g., "2026-W07")
541
+ * @param {Date} date - Date
542
+ * @returns {string} ISO week label
543
+ */
544
+ function getISOWeekLabel(date) {
545
+ const year = date.getFullYear();
546
+ const weekNum = getWeekNumber(date);
547
+ return `${year}-W${String(weekNum).padStart(2, '0')}`;
548
+ }
549
+
534
550
  /**
535
551
  * Filter sessions by week
536
552
  * @param {Array} sessions - Array of sessions
@@ -194,7 +194,7 @@ class DocumentAnalyzer {
194
194
 
195
195
  // Framework indicators
196
196
  if (content.includes('BMAD')) keywords.add('bmad-method');
197
- if (content.includes('Spec-Kit')) keywords.add('spec-kit');
197
+ if (content.includes('OpenSpec')) keywords.add('openspec');
198
198
  if (content.includes('Context Engineering')) keywords.add('context-engineering');
199
199
  if (content.includes('AgentDevFramework')) keywords.add('adf-framework');
200
200
 
@@ -229,7 +229,7 @@ class DocumentAnalyzer {
229
229
  detectFramework() {
230
230
  const frameworkIndicators = {
231
231
  bmad: 0,
232
- specKit: 0,
232
+ openSpec: 0,
233
233
  contextEngineering: 0,
234
234
  adf: 0
235
235
  };
@@ -246,12 +246,12 @@ class DocumentAnalyzer {
246
246
  if (doc.type === 'prd') frameworkIndicators.bmad += 1;
247
247
  if (doc.type === 'story' && doc.size > 5000) frameworkIndicators.bmad += 2; // Large stories with context
248
248
 
249
- // Specification-Driven (Legacy Spec-Kit) indicators
250
- if (doc.keywords.includes('spec-kit')) frameworkIndicators.specKit += 5;
251
- if (doc.keywords.includes('specification-driven')) frameworkIndicators.specKit += 5; if (doc.keywords.includes('constitutional')) frameworkIndicators.specKit += 3;
252
- if (doc.type === 'constitution') frameworkIndicators.specKit += 4;
253
- if (doc.type === 'spec') frameworkIndicators.specKit += 2;
254
- if (doc.metadata.status && doc.metadata.status.match(/draft|review|approved/i)) frameworkIndicators.specKit += 1;
249
+ // Specification-Driven (OpenSpec) indicators
250
+ if (doc.keywords.includes('openspec')) frameworkIndicators.openSpec += 5;
251
+ if (doc.keywords.includes('specification-driven')) frameworkIndicators.openSpec += 5; if (doc.keywords.includes('constitutional')) frameworkIndicators.openSpec += 3;
252
+ if (doc.type === 'constitution') frameworkIndicators.openSpec += 4;
253
+ if (doc.type === 'spec') frameworkIndicators.openSpec += 2;
254
+ if (doc.metadata.status && doc.metadata.status.match(/draft|review|approved/i)) frameworkIndicators.openSpec += 1;
255
255
 
256
256
  // Context Engineering indicators
257
257
  if (doc.keywords.includes('context-engineering')) frameworkIndicators.contextEngineering += 5;
@@ -328,7 +328,7 @@ class DocumentAnalyzer {
328
328
  return;
329
329
  }
330
330
 
331
- // Spec-Kit workflow: Has specs with structured workflow
331
+ // OpenSpec workflow: Has specs with structured workflow
332
332
  if (docCounts.spec > 0 && docCounts.plan > 0) {
333
333
  this.analysis.detectedWorkflow = 'spec-driven';
334
334
  return;
@@ -397,11 +397,11 @@ class DocumentAnalyzer {
397
397
  priority: 'medium',
398
398
  message: 'BMAD framework detected. Continue using agent-based workflow. Consider adding missing agents if needed.'
399
399
  });
400
- } else if (existingFramework === 'specKit') {
400
+ } else if (existingFramework === 'openSpec') {
401
401
  this.analysis.recommendations.push({
402
402
  type: 'framework',
403
403
  priority: 'medium',
404
- message: 'Spec-Kit framework detected. Continue using specification-driven workflow. Ensure constitutional compliance.'
404
+ message: 'OpenSpec framework detected. Continue using specification-driven workflow. Ensure constitutional compliance.'
405
405
  });
406
406
  } else if (existingFramework === 'contextEngineering') {
407
407
  this.analysis.recommendations.push({
@@ -343,7 +343,7 @@ class FrameworkBuilder {
343
343
  'QUICK-START.md',
344
344
  'AGENTDEVFRAMEWORK-CLAUDE.md',
345
345
  'BMAD-METHOD-CLAUDE.md',
346
- 'SPEC-KIT-CLAUDE.md',
346
+ 'OPENSPEC-CLAUDE.md',
347
347
  'CONTEXT-ENGINEERING-INTRO-CLAUDE.md',
348
348
  'FRAMEWORK-ANALYSIS.md',
349
349
  'DEPLOYMENT-STATUS.md',
@@ -12,7 +12,7 @@ const chalk = require('chalk');
12
12
 
13
13
  const SUBMODULES = [
14
14
  { name: 'BMAD-METHOD', path: 'references/bmad-method', branch: 'main' },
15
- { name: 'Spec-Kit', path: 'references/spec-kit', branch: 'main' },
15
+ { name: 'OpenSpec', path: 'references/spec-kit', branch: 'main' },
16
16
  { name: 'Context Engineering', path: 'references/context-engineering', branch: 'main' },
17
17
  { name: 'PRPs Agentic', path: 'references/prps-agentic', branch: 'main' }
18
18
  ];
@@ -42,7 +42,7 @@ const FRAMEWORK_ELEMENTS = {
42
42
  agents: ['Analyst', 'PM', 'Architect', 'Dev', 'QA'],
43
43
  whenToUse: 'Complex projects, teams, enterprise, unclear requirements'
44
44
  },
45
- specKit: {
45
+ openSpec: {
46
46
  strengths: ['Constitutional governance', 'Quality gates', 'Validation checkpoints'],
47
47
  workflow: ['Constitution', 'Specify', 'Clarify', 'Plan', 'Tasks', 'Implement'],
48
48
  whenToUse: 'Clear requirements, validation needed, compliance-critical'
@@ -536,4 +536,4 @@ Brief ready for PM to create PRD.
536
536
 
537
537
  **Agent Version**: 1.0.0
538
538
  **Framework**: AgentDevFramework
539
- **Methodology**: Agent-Native + Market Research Best Practices
539
+ **Methodology**: BMAD-METHOD + Market Research Best Practices
@@ -550,4 +550,4 @@ Ready for SM to create stories.
550
550
 
551
551
  **Agent Version**: 1.0.0
552
552
  **Framework**: AgentDevFramework
553
- **Methodology**: Agent-Native + Software Architecture Best Practices
553
+ **Methodology**: BMAD-METHOD + Software Architecture Best Practices
@@ -118,7 +118,7 @@ You are a Senior Full-Stack Developer focused on implementing features from deta
118
118
  ### Core Commands
119
119
 
120
120
  ```bash
121
- /implement <story-id> # Implement a feature from requirements
121
+ /implement <story-id> # Implement a story from PRD
122
122
  /test # Run tests and analyze results
123
123
  /review # Perform self-code-review
124
124
  /commit # Create well-formatted commit
@@ -50,7 +50,7 @@ You are a Product Manager focused on creating comprehensive Product Requirements
50
50
 
51
51
  ## Primary Responsibilities
52
52
 
53
- ### 1. PRD Creation (Path A: Agent-Native)
53
+ ### 1. PRD Creation (Path A: Greenfield)
54
54
 
55
55
  **Create comprehensive Product Requirements Document**:
56
56
  - Executive Summary
@@ -672,4 +672,4 @@ PRD complete. Ready for architect review.
672
672
 
673
673
  **Agent Version**: 1.0.0
674
674
  **Framework**: AgentDevFramework
675
- **Methodology**: Agent-Native + Agile Best Practices
675
+ **Methodology**: BMAD-METHOD + Agile Best Practices
@@ -537,4 +537,4 @@ Recommendation: Implement rate limiting and CAPTCHA before beginning development
537
537
 
538
538
  **Agent Version**: 1.0.0
539
539
  **Framework**: AgentDevFramework
540
- **Methodology**: Agent-Native + Risk-Based Testing Best Practices
540
+ **Methodology**: BMAD-METHOD QA + Risk-Based Testing Best Practices
@@ -67,7 +67,7 @@ You are Samira, a Scrum Master focused on creating implementation-ready stories
67
67
 
68
68
  ## Story Creation Workflow
69
69
 
70
- ### 1. Context Gathering (Path A: Agent-Native)
70
+ ### 1. Context Gathering (Path A: Greenfield)
71
71
 
72
72
  ```
73
73
  1. Read Planning Phase Outputs
@@ -77,7 +77,7 @@ You are Samira, a Scrum Master focused on creating implementation-ready stories
77
77
  - Related stories
78
78
  ```
79
79
 
80
- ### 2. Task Breakdown (Level 2: Balanced (OpenSpec))
80
+ ### 2. Task Breakdown (Path B: OpenSpec)
81
81
 
82
82
  ```
83
83
  1. Read Change Context
@@ -785,4 +785,4 @@ Would you like me to:
785
785
 
786
786
  **Agent Version**: 1.0.0
787
787
  **Framework**: AgentDevFramework
788
- **Methodology**: Agent-Native + Agile Best Practices
788
+ **Methodology**: BMAD-METHOD + Context Engineering + Agile Best Practices
@@ -1,6 +1,6 @@
1
1
  # Development Constitution
2
2
 
3
- This document defines the immutable principles governing all development in this project. These principles synthesize best practices from Agent-Native and OpenSpec methodologies.
3
+ This document defines the immutable principles governing all development in this project. These principles synthesize best practices from BMAD-METHOD, OpenSpec, and Context Engineering methodologies.
4
4
 
5
5
  ## Article 1: Specification-First Development
6
6
 
@@ -287,6 +287,6 @@ This constitution is enforced through:
287
287
 
288
288
  **Version**: 1.0.0
289
289
  **Last Updated**: 2025-01-XX
290
- **Source**: Synthesized from Agent-Native and OpenSpec methodologies
290
+ **Source**: Synthesized from BMAD-METHOD, OpenSpec, Context Engineering
291
291
 
292
292
  **Living Document**: This constitution evolves with project needs while maintaining core principles.