@brunosps00/dev-workflow 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +156 -0
- package/bin/dev-workflow.js +64 -0
- package/lib/constants.js +97 -0
- package/lib/init.js +101 -0
- package/lib/mcp.js +40 -0
- package/lib/prompts.js +36 -0
- package/lib/utils.js +69 -0
- package/lib/wrappers.js +22 -0
- package/package.json +41 -0
- package/scaffold/en/commands/analyze-project.md +695 -0
- package/scaffold/en/commands/brainstorm.md +79 -0
- package/scaffold/en/commands/bugfix.md +345 -0
- package/scaffold/en/commands/code-review.md +280 -0
- package/scaffold/en/commands/commit.md +179 -0
- package/scaffold/en/commands/create-prd.md +99 -0
- package/scaffold/en/commands/create-tasks.md +134 -0
- package/scaffold/en/commands/create-techspec.md +138 -0
- package/scaffold/en/commands/deep-research.md +411 -0
- package/scaffold/en/commands/fix-qa.md +109 -0
- package/scaffold/en/commands/generate-pr.md +206 -0
- package/scaffold/en/commands/help.md +289 -0
- package/scaffold/en/commands/refactoring-analysis.md +298 -0
- package/scaffold/en/commands/review-implementation.md +239 -0
- package/scaffold/en/commands/run-plan.md +236 -0
- package/scaffold/en/commands/run-qa.md +296 -0
- package/scaffold/en/commands/run-task.md +174 -0
- package/scaffold/en/templates/bugfix-template.md +91 -0
- package/scaffold/en/templates/prd-template.md +70 -0
- package/scaffold/en/templates/task-template.md +62 -0
- package/scaffold/en/templates/tasks-template.md +34 -0
- package/scaffold/en/templates/techspec-template.md +123 -0
- package/scaffold/pt-br/commands/analyze-project.md +628 -0
- package/scaffold/pt-br/commands/brainstorm.md +79 -0
- package/scaffold/pt-br/commands/bugfix.md +251 -0
- package/scaffold/pt-br/commands/code-review.md +220 -0
- package/scaffold/pt-br/commands/commit.md +127 -0
- package/scaffold/pt-br/commands/create-prd.md +98 -0
- package/scaffold/pt-br/commands/create-tasks.md +134 -0
- package/scaffold/pt-br/commands/create-techspec.md +136 -0
- package/scaffold/pt-br/commands/deep-research.md +158 -0
- package/scaffold/pt-br/commands/fix-qa.md +97 -0
- package/scaffold/pt-br/commands/generate-pr.md +162 -0
- package/scaffold/pt-br/commands/help.md +226 -0
- package/scaffold/pt-br/commands/refactoring-analysis.md +298 -0
- package/scaffold/pt-br/commands/review-implementation.md +201 -0
- package/scaffold/pt-br/commands/run-plan.md +159 -0
- package/scaffold/pt-br/commands/run-qa.md +238 -0
- package/scaffold/pt-br/commands/run-task.md +158 -0
- package/scaffold/pt-br/templates/bugfix-template.md +91 -0
- package/scaffold/pt-br/templates/prd-template.md +70 -0
- package/scaffold/pt-br/templates/task-template.md +62 -0
- package/scaffold/pt-br/templates/tasks-template.md +34 -0
- package/scaffold/pt-br/templates/techspec-template.md +123 -0
- package/scaffold/rules-readme.md +25 -0
package/README.md
ADDED
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
# dev-workflow
|
|
2
|
+
|
|
3
|
+
AI-driven development workflow commands for any project. Scaffolds a complete PRD-to-PR pipeline with multi-platform AI assistant support.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npx @brunosps00/dev-workflow init
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
This will:
|
|
12
|
+
1. Ask you to select a language (English or Portuguese)
|
|
13
|
+
2. Create `ai/commands/` with 17 workflow commands
|
|
14
|
+
3. Create `ai/templates/` with document templates
|
|
15
|
+
4. Create `ai/rules/` (populated by `/analyze-project`)
|
|
16
|
+
5. Generate skill wrappers for Claude Code, Codex, Copilot, and OpenCode
|
|
17
|
+
6. Configure MCP servers (Context7 + Playwright)
|
|
18
|
+
|
|
19
|
+
## Commands
|
|
20
|
+
|
|
21
|
+
### Planning
|
|
22
|
+
|
|
23
|
+
#### `/brainstorm`
|
|
24
|
+
Facilitates structured ideation before opening a PRD or implementation. Explores multiple directions — conservative, balanced, and bold — with trade-offs for each, then converges on concrete next steps. No code is written or files modified.
|
|
25
|
+
|
|
26
|
+
#### `/create-prd`
|
|
27
|
+
Creates a Product Requirements Document by first asking at least 7 clarification questions to fully understand the feature. Generates a structured PRD with numbered functional requirements focused on what and why, saved to `ai/spec/prd-[feature-name]/prd.md`.
|
|
28
|
+
|
|
29
|
+
#### `/create-techspec`
|
|
30
|
+
Generates a Technical Specification from an existing PRD after performing web searches and asking at least 7 clarification questions. Evaluates existing libraries vs custom development, defines testing strategy, branch naming, and integration architecture. Output is saved to `ai/spec/prd-[feature-name]/techspec.md`.
|
|
31
|
+
|
|
32
|
+
#### `/create-tasks`
|
|
33
|
+
Breaks down the PRD and TechSpec into implementable tasks with a target of ~6 tasks per feature (max 2 functional requirements each). Creates individual task files with subtasks and success criteria, ensuring end-to-end coverage across backend, frontend, and functional UI. Requires approval before finalizing.
|
|
34
|
+
|
|
35
|
+
### Execution
|
|
36
|
+
|
|
37
|
+
#### `/run-task`
|
|
38
|
+
Executes a single task from the task list, implementing code that follows project patterns and includes mandatory unit tests. Performs Level 1 validation (acceptance criteria + tests + standards check) and creates a commit upon completion.
|
|
39
|
+
|
|
40
|
+
#### `/run-plan`
|
|
41
|
+
Executes all pending tasks sequentially and automatically, with Level 1 validation after each task. After all tasks are complete, performs a final Level 2 review (PRD compliance) with an interactive corrections cycle until no gaps remain or the user accepts pending items.
|
|
42
|
+
|
|
43
|
+
#### `/bugfix`
|
|
44
|
+
Analyzes and fixes bugs with automatic triage that distinguishes between bugs, feature requests, and excessive scope. Asks exactly 3 clarification questions before proposing a solution. Supports Direct mode (executes fix immediately) and Analysis mode (`--analysis`) that generates a document for the techspec/tasks pipeline.
|
|
45
|
+
|
|
46
|
+
### Quality
|
|
47
|
+
|
|
48
|
+
#### `/run-qa`
|
|
49
|
+
Validates the implementation against PRD, TechSpec, and Tasks using Playwright MCP for E2E browser automation. Tests happy paths, edge cases, negative flows, and regressions while verifying WCAG 2.2 accessibility compliance. Generates a QA report, documents bugs with screenshot evidence, and detects stub/placeholder pages.
|
|
50
|
+
|
|
51
|
+
#### `/fix-qa`
|
|
52
|
+
Fixes bugs found during QA testing with evidence-driven retesting via Playwright MCP. Runs iterative cycles of identify → fix → retest, updating `QA/bugs.md` and `QA/qa-report.md` with status and retest evidence including screenshots and logs.
|
|
53
|
+
|
|
54
|
+
#### `/review-implementation`
|
|
55
|
+
Compares documented requirements (PRD + TechSpec + Tasks) against actual code as a Level 2 review. Maps each requirement to endpoints and tasks with evidence, identifies gaps, partial implementations, and extra undocumented code. Does not execute fixes — waits for user instruction.
|
|
56
|
+
|
|
57
|
+
#### `/code-review`
|
|
58
|
+
Performs a formal Level 3 code review before PR creation, verifying PRD compliance, code quality (SOLID, DRY, complexity, security), and conformance with project rules in `ai/rules/`. Runs tests, verifies coverage targets, and generates a persistent report with APPROVED, APPROVED WITH CAVEATS, or REJECTED status.
|
|
59
|
+
|
|
60
|
+
#### `/refactoring-analysis`
|
|
61
|
+
Audits the codebase for code smells and refactoring opportunities using Martin Fowler's catalog. Detects bloaters, change preventers, dispensables, couplers, conditional complexity, and DRY violations, then maps each to a concrete refactoring technique with before/after code sketches. Includes coupling/cohesion metrics, SOLID analysis, and a prioritized action plan (P0-P3).
|
|
62
|
+
|
|
63
|
+
### Git & PR
|
|
64
|
+
|
|
65
|
+
#### `/commit`
|
|
66
|
+
Analyzes pending changes, groups them by feature or logical context, and creates atomic semantic commits following the Conventional Commits format. Uses allowed types: `feat`, `fix`, `docs`, `style`, `refactor`, `perf`, `test`, `chore`, `ci`, `build`.
|
|
67
|
+
|
|
68
|
+
#### `/generate-pr`
|
|
69
|
+
Pushes the branch to remote and creates a Pull Request on GitHub with a structured description. Collects information from the PRD and modified files, runs tests, then generates a PR body with summary, changes grouped by module, test plan, and deploy notes.
|
|
70
|
+
|
|
71
|
+
### Utilities
|
|
72
|
+
|
|
73
|
+
#### `/analyze-project`
|
|
74
|
+
Scans the repository to identify tech stack, architectural patterns, naming conventions, and anti-patterns. Generates structured documentation in `ai/rules/` with a project overview (`index.md`) and per-module rule files containing real code examples, which are consumed by other workflow commands.
|
|
75
|
+
|
|
76
|
+
#### `/deep-research`
|
|
77
|
+
Conducts multi-source research with citation tracking and verification across quick, standard, deep, and ultradeep modes. Executes parallel information gathering, triangulation, and cross-reference verification through 8+ phases, producing a professional report with complete bibliography.
|
|
78
|
+
|
|
79
|
+
#### `/help`
|
|
80
|
+
Displays the complete guide of available commands, integration flows, and when to use each one. Can be invoked without arguments for the full guide or with a specific command name (e.g., `/help create-prd`) for a detailed section.
|
|
81
|
+
|
|
82
|
+
## Workflow
|
|
83
|
+
|
|
84
|
+
```
|
|
85
|
+
/brainstorm
|
|
86
|
+
|
|
|
87
|
+
/create-prd --> ai/spec/prd-{name}/prd.md
|
|
88
|
+
|
|
|
89
|
+
/create-techspec --> ai/spec/prd-{name}/techspec.md
|
|
90
|
+
|
|
|
91
|
+
/create-tasks --> ai/spec/prd-{name}/tasks.md + {N}_task.md
|
|
92
|
+
|
|
|
93
|
+
/run-task (or /run-plan for all)
|
|
94
|
+
|
|
|
95
|
+
/run-qa --> ai/spec/prd-{name}/QA/
|
|
96
|
+
|
|
|
97
|
+
/fix-qa (if bugs found)
|
|
98
|
+
|
|
|
99
|
+
/review-implementation --> PRD compliance check
|
|
100
|
+
|
|
|
101
|
+
/refactoring-analysis --> ai/spec/prd-{name}/refactoring-analysis.md (optional)
|
|
102
|
+
|
|
|
103
|
+
/code-review --> ai/spec/prd-{name}/QA/code-review.md
|
|
104
|
+
|
|
|
105
|
+
/commit + /generate-pr
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## Platform Support
|
|
109
|
+
|
|
110
|
+
| Platform | Wrapper Location | Status |
|
|
111
|
+
|----------|-----------------|--------|
|
|
112
|
+
| Claude Code | `.claude/skills/` | Full support |
|
|
113
|
+
| Codex CLI | `.codex/skills/` | Full support |
|
|
114
|
+
| Copilot | `.agents/skills/` | Full support |
|
|
115
|
+
| OpenCode | `.agents/skills/` | Full support |
|
|
116
|
+
|
|
117
|
+
All wrappers point to `ai/commands/` as the single source of truth.
|
|
118
|
+
|
|
119
|
+
## Project Structure (after init)
|
|
120
|
+
|
|
121
|
+
```
|
|
122
|
+
your-project/
|
|
123
|
+
├── ai/
|
|
124
|
+
│ ├── commands/ # 16 workflow command files
|
|
125
|
+
│ ├── templates/ # Document templates (PRD, TechSpec, etc.)
|
|
126
|
+
│ ├── rules/ # Project-specific rules (run /analyze-project)
|
|
127
|
+
│ └── spec/ # PRD directories created by commands
|
|
128
|
+
├── .claude/
|
|
129
|
+
│ ├── skills/ # Claude Code wrappers
|
|
130
|
+
│ └── settings.json # MCP servers (Context7, Playwright)
|
|
131
|
+
├── .codex/skills/ # Codex CLI wrappers
|
|
132
|
+
└── .agents/skills/ # Copilot/OpenCode wrappers
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## Options
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
npx @brunosps00/dev-workflow init # Interactive language selection
|
|
139
|
+
npx @brunosps00/dev-workflow init --lang=en # English, skip prompt
|
|
140
|
+
npx @brunosps00/dev-workflow init --lang=pt-br # Portuguese, skip prompt
|
|
141
|
+
npx @brunosps00/dev-workflow init --force # Overwrite existing files
|
|
142
|
+
npx @brunosps00/dev-workflow update # Update commands/templates only
|
|
143
|
+
npx @brunosps00/dev-workflow help # Show help
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
## Getting Started
|
|
147
|
+
|
|
148
|
+
After running `npx @brunosps00/dev-workflow init`:
|
|
149
|
+
|
|
150
|
+
1. **Run `/analyze-project`** in your AI assistant to generate project rules
|
|
151
|
+
2. **Run `/brainstorm`** to start planning a new feature
|
|
152
|
+
3. **Run `/help`** to see all available commands and workflows
|
|
153
|
+
|
|
154
|
+
## License
|
|
155
|
+
|
|
156
|
+
MIT
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const { run } = require('../lib/init');
|
|
4
|
+
|
|
5
|
+
const args = process.argv.slice(2);
|
|
6
|
+
const command = args[0];
|
|
7
|
+
|
|
8
|
+
const flags = {};
|
|
9
|
+
for (const arg of args) {
|
|
10
|
+
if (arg.startsWith('--')) {
|
|
11
|
+
const [key, value] = arg.slice(2).split('=');
|
|
12
|
+
flags[key] = value || true;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const HELP_TEXT = `
|
|
17
|
+
dev-workflow - AI-driven development workflow commands
|
|
18
|
+
|
|
19
|
+
Usage:
|
|
20
|
+
npx dev-workflow init [--force] [--lang=en|pt-br]
|
|
21
|
+
npx dev-workflow update [--force]
|
|
22
|
+
npx dev-workflow help
|
|
23
|
+
|
|
24
|
+
Commands:
|
|
25
|
+
init Scaffold ai/commands, templates, rules, and platform wrappers
|
|
26
|
+
update Update commands and templates (preserves rules and tasks)
|
|
27
|
+
help Show this help message
|
|
28
|
+
|
|
29
|
+
Options:
|
|
30
|
+
--force Overwrite existing files
|
|
31
|
+
--lang=LANG Set language without prompt (en or pt-br)
|
|
32
|
+
|
|
33
|
+
Examples:
|
|
34
|
+
npx dev-workflow init # Interactive language selection
|
|
35
|
+
npx dev-workflow init --lang=en # English, no prompt
|
|
36
|
+
npx dev-workflow init --lang=pt-br # Portuguese, no prompt
|
|
37
|
+
npx dev-workflow init --force # Overwrite existing files
|
|
38
|
+
`;
|
|
39
|
+
|
|
40
|
+
async function main() {
|
|
41
|
+
switch (command) {
|
|
42
|
+
case 'init':
|
|
43
|
+
await run({ force: !!flags.force, lang: flags.lang, mode: 'init' });
|
|
44
|
+
break;
|
|
45
|
+
case 'update':
|
|
46
|
+
await run({ force: !!flags.force, lang: flags.lang, mode: 'update' });
|
|
47
|
+
break;
|
|
48
|
+
case 'help':
|
|
49
|
+
case '--help':
|
|
50
|
+
case '-h':
|
|
51
|
+
case undefined:
|
|
52
|
+
console.log(HELP_TEXT);
|
|
53
|
+
break;
|
|
54
|
+
default:
|
|
55
|
+
console.error(`Unknown command: ${command}`);
|
|
56
|
+
console.log(HELP_TEXT);
|
|
57
|
+
process.exit(1);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
main().catch((err) => {
|
|
62
|
+
console.error('Error:', err.message);
|
|
63
|
+
process.exit(1);
|
|
64
|
+
});
|
package/lib/constants.js
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
const COMMANDS = {
|
|
2
|
+
en: [
|
|
3
|
+
{ name: 'analyze-project', description: 'Analyze repository stack, patterns, and conventions to generate project rules' },
|
|
4
|
+
{ name: 'brainstorm', description: 'Explore ideas and directions before starting implementation' },
|
|
5
|
+
{ name: 'bugfix', description: 'Analyze and fix bugs with automatic triage (bug vs feature vs scope)' },
|
|
6
|
+
{ name: 'code-review', description: 'Formal code review (Level 3) with persisted report' },
|
|
7
|
+
{ name: 'commit', description: 'Create semantic commits following Conventional Commits' },
|
|
8
|
+
{ name: 'create-prd', description: 'Create a Product Requirements Document with clarification questions' },
|
|
9
|
+
{ name: 'create-tasks', description: 'Break down PRD and TechSpec into implementable tasks' },
|
|
10
|
+
{ name: 'create-techspec', description: 'Create a Technical Specification from an existing PRD' },
|
|
11
|
+
{ name: 'deep-research', description: 'Conduct multi-source research with citation tracking and verification' },
|
|
12
|
+
{ name: 'fix-qa', description: 'Fix bugs found during QA and retest until stable' },
|
|
13
|
+
{ name: 'generate-pr', description: 'Generate a Pull Request with structured description' },
|
|
14
|
+
{ name: 'help', description: 'Show complete guide of available commands and workflows' },
|
|
15
|
+
{ name: 'refactoring-analysis', description: 'Audit codebase for code smells and refactoring opportunities with prioritized report' },
|
|
16
|
+
{ name: 'review-implementation', description: 'Review if all PRD requirements were correctly implemented' },
|
|
17
|
+
{ name: 'run-plan', description: 'Execute ALL tasks sequentially until the plan is complete' },
|
|
18
|
+
{ name: 'run-qa', description: 'Run visual QA with browser automation, E2E tests, and accessibility' },
|
|
19
|
+
{ name: 'run-task', description: 'Execute a single task with built-in validation and testing' },
|
|
20
|
+
],
|
|
21
|
+
'pt-br': [
|
|
22
|
+
{ name: 'analyze-project', description: 'Analisa stack, patterns e convencoes do repositorio para gerar regras do projeto' },
|
|
23
|
+
{ name: 'brainstorm', description: 'Explorar ideias e direcoes antes de comecar a implementacao' },
|
|
24
|
+
{ name: 'bugfix', description: 'Analisar e corrigir bugs com triagem automatica (bug vs feature vs escopo)' },
|
|
25
|
+
{ name: 'code-review', description: 'Code review formal (Nivel 3) com relatorio persistido' },
|
|
26
|
+
{ name: 'commit', description: 'Criar commits semanticos seguindo Conventional Commits' },
|
|
27
|
+
{ name: 'create-prd', description: 'Criar um Product Requirements Document com perguntas de clarificacao' },
|
|
28
|
+
{ name: 'create-tasks', description: 'Quebrar PRD e TechSpec em tasks implementaveis' },
|
|
29
|
+
{ name: 'create-techspec', description: 'Criar uma Especificacao Tecnica a partir de um PRD existente' },
|
|
30
|
+
{ name: 'deep-research', description: 'Pesquisa multi-fonte com rastreamento de citacoes e verificacao' },
|
|
31
|
+
{ name: 'fix-qa', description: 'Corrigir bugs encontrados no QA e retestar ate estabilizar' },
|
|
32
|
+
{ name: 'generate-pr', description: 'Gerar um Pull Request com descricao estruturada' },
|
|
33
|
+
{ name: 'help', description: 'Mostrar guia completo dos comandos e fluxos disponiveis' },
|
|
34
|
+
{ name: 'refactoring-analysis', description: 'Auditar codebase para code smells e oportunidades de refatoracao com relatorio priorizado' },
|
|
35
|
+
{ name: 'review-implementation', description: 'Revisar se todos os requisitos do PRD foram implementados corretamente' },
|
|
36
|
+
{ name: 'run-plan', description: 'Executar TODAS as tasks sequencialmente ate completar o plano' },
|
|
37
|
+
{ name: 'run-qa', description: 'Executar QA visual com automacao de browser, testes E2E e acessibilidade' },
|
|
38
|
+
{ name: 'run-task', description: 'Executar uma task com validacao e testes integrados' },
|
|
39
|
+
],
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
const PLATFORMS = {
|
|
43
|
+
claude: {
|
|
44
|
+
dir: '.claude/skills',
|
|
45
|
+
wrapperTemplate: (name, description) => `---
|
|
46
|
+
name: ${name}
|
|
47
|
+
description: ${description}
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
Read and follow ALL instructions in \`ai/commands/${name}.md\`.
|
|
51
|
+
`,
|
|
52
|
+
},
|
|
53
|
+
codex: {
|
|
54
|
+
dir: '.codex/skills',
|
|
55
|
+
wrapperTemplate: (name, description) => `---
|
|
56
|
+
name: ${name}
|
|
57
|
+
description: Imported from ./ai/commands/${name}.md
|
|
58
|
+
---
|
|
59
|
+
<system_instructions>
|
|
60
|
+
This skill redirects to the project's source command.
|
|
61
|
+
|
|
62
|
+
Source of truth: \`ai/commands/${name}.md\`
|
|
63
|
+
|
|
64
|
+
1. Open and read \`ai/commands/${name}.md\` before executing.
|
|
65
|
+
2. Follow the source command entirely.
|
|
66
|
+
3. If divergence exists, the command file prevails.
|
|
67
|
+
</system_instructions>
|
|
68
|
+
`,
|
|
69
|
+
},
|
|
70
|
+
agents: {
|
|
71
|
+
dir: '.agents/skills',
|
|
72
|
+
wrapperTemplate: (name, description) => `---
|
|
73
|
+
name: ${name}
|
|
74
|
+
description: ${description}
|
|
75
|
+
---
|
|
76
|
+
<system_instructions>
|
|
77
|
+
Source of truth: \`ai/commands/${name}.md\`
|
|
78
|
+
|
|
79
|
+
Read and follow the complete instructions in the command file above.
|
|
80
|
+
This wrapper exists for tool discovery. All logic lives in ai/commands/.
|
|
81
|
+
</system_instructions>
|
|
82
|
+
`,
|
|
83
|
+
},
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
const MCP_SERVERS = {
|
|
87
|
+
context7: {
|
|
88
|
+
command: 'npx',
|
|
89
|
+
args: ['-y', '@upstash/context7-mcp'],
|
|
90
|
+
},
|
|
91
|
+
playwright: {
|
|
92
|
+
command: 'npx',
|
|
93
|
+
args: ['-y', '@anthropic-ai/mcp-server-playwright'],
|
|
94
|
+
},
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
module.exports = { COMMANDS, PLATFORMS, MCP_SERVERS };
|
package/lib/init.js
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const { COMMANDS } = require('./constants');
|
|
3
|
+
const { ensureDir, copyDir, writeFile, log } = require('./utils');
|
|
4
|
+
const { selectLanguage } = require('./prompts');
|
|
5
|
+
const { generateWrappers } = require('./wrappers');
|
|
6
|
+
const { installMCPs } = require('./mcp');
|
|
7
|
+
|
|
8
|
+
const SCAFFOLD_DIR = path.join(__dirname, '..', 'scaffold');
|
|
9
|
+
|
|
10
|
+
async function run({ force = false, lang = null, mode = 'init' }) {
|
|
11
|
+
const projectRoot = process.cwd();
|
|
12
|
+
const isUpdate = mode === 'update';
|
|
13
|
+
|
|
14
|
+
console.log(`\n dev-workflow ${isUpdate ? 'update' : 'init'}`);
|
|
15
|
+
console.log(` ${'='.repeat(40)}\n`);
|
|
16
|
+
|
|
17
|
+
// 1. Select language
|
|
18
|
+
const selectedLang = await selectLanguage(lang);
|
|
19
|
+
console.log(`\n Language: ${selectedLang}\n`);
|
|
20
|
+
|
|
21
|
+
const commands = COMMANDS[selectedLang];
|
|
22
|
+
const langDir = path.join(SCAFFOLD_DIR, selectedLang);
|
|
23
|
+
|
|
24
|
+
// Track totals
|
|
25
|
+
let totalCreated = 0;
|
|
26
|
+
let totalSkipped = 0;
|
|
27
|
+
let totalOverwritten = 0;
|
|
28
|
+
|
|
29
|
+
// 2. Copy commands
|
|
30
|
+
console.log(' Commands:');
|
|
31
|
+
const cmdResults = copyDir(
|
|
32
|
+
path.join(langDir, 'commands'),
|
|
33
|
+
path.join(projectRoot, 'ai', 'commands'),
|
|
34
|
+
force
|
|
35
|
+
);
|
|
36
|
+
totalCreated += cmdResults.created;
|
|
37
|
+
totalSkipped += cmdResults.skipped;
|
|
38
|
+
totalOverwritten += cmdResults.overwritten;
|
|
39
|
+
console.log(` ${cmdResults.created} created, ${cmdResults.skipped} skipped, ${cmdResults.overwritten} overwritten\n`);
|
|
40
|
+
|
|
41
|
+
// 3. Copy templates
|
|
42
|
+
console.log(' Templates:');
|
|
43
|
+
const tplResults = copyDir(
|
|
44
|
+
path.join(langDir, 'templates'),
|
|
45
|
+
path.join(projectRoot, 'ai', 'templates'),
|
|
46
|
+
force
|
|
47
|
+
);
|
|
48
|
+
totalCreated += tplResults.created;
|
|
49
|
+
totalSkipped += tplResults.skipped;
|
|
50
|
+
totalOverwritten += tplResults.overwritten;
|
|
51
|
+
console.log(` ${tplResults.created} created, ${tplResults.skipped} skipped, ${tplResults.overwritten} overwritten\n`);
|
|
52
|
+
|
|
53
|
+
// 4. Create ai/rules/ with README
|
|
54
|
+
if (!isUpdate) {
|
|
55
|
+
console.log(' Rules:');
|
|
56
|
+
ensureDir(path.join(projectRoot, 'ai', 'rules'));
|
|
57
|
+
const rulesReadmeSrc = path.join(SCAFFOLD_DIR, 'rules-readme.md');
|
|
58
|
+
const rulesReadmeDest = path.join(projectRoot, 'ai', 'rules', 'README.md');
|
|
59
|
+
const status = writeFile(
|
|
60
|
+
rulesReadmeDest,
|
|
61
|
+
require('fs').readFileSync(rulesReadmeSrc, 'utf-8'),
|
|
62
|
+
false
|
|
63
|
+
);
|
|
64
|
+
log(status, rulesReadmeDest);
|
|
65
|
+
if (status === 'created') totalCreated++;
|
|
66
|
+
else totalSkipped++;
|
|
67
|
+
console.log();
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// 5. Create ai/spec/
|
|
71
|
+
if (!isUpdate) {
|
|
72
|
+
ensureDir(path.join(projectRoot, 'ai', 'spec'));
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// 6-8. Generate platform wrappers
|
|
76
|
+
console.log(' Platform wrappers:');
|
|
77
|
+
const wrapperResults = generateWrappers(projectRoot, commands, force);
|
|
78
|
+
totalCreated += wrapperResults.created;
|
|
79
|
+
totalSkipped += wrapperResults.skipped;
|
|
80
|
+
totalOverwritten += wrapperResults.overwritten;
|
|
81
|
+
console.log();
|
|
82
|
+
|
|
83
|
+
// 9. Install MCPs
|
|
84
|
+
if (!isUpdate) {
|
|
85
|
+
console.log(' MCP Servers:');
|
|
86
|
+
const mcpResults = installMCPs(projectRoot);
|
|
87
|
+
console.log(` ${mcpResults.added} configured, ${mcpResults.skipped} already present\n`);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// 10. Summary
|
|
91
|
+
console.log(` ${'='.repeat(40)}`);
|
|
92
|
+
console.log(` Done! ${totalCreated} created, ${totalSkipped} skipped, ${totalOverwritten} overwritten`);
|
|
93
|
+
console.log();
|
|
94
|
+
console.log(' Next steps:');
|
|
95
|
+
console.log(' 1. Run /analyze-project to generate project rules');
|
|
96
|
+
console.log(' 2. Run /brainstorm to start a new feature');
|
|
97
|
+
console.log(' 3. Run /help to see all available commands');
|
|
98
|
+
console.log();
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
module.exports = { run };
|
package/lib/mcp.js
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const { ensureDir } = require('./utils');
|
|
4
|
+
const { MCP_SERVERS } = require('./constants');
|
|
5
|
+
|
|
6
|
+
function installMCPs(projectRoot) {
|
|
7
|
+
const settingsPath = path.join(projectRoot, '.claude', 'settings.json');
|
|
8
|
+
let settings = {};
|
|
9
|
+
|
|
10
|
+
if (fs.existsSync(settingsPath)) {
|
|
11
|
+
try {
|
|
12
|
+
settings = JSON.parse(fs.readFileSync(settingsPath, 'utf-8'));
|
|
13
|
+
} catch {
|
|
14
|
+
settings = {};
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
if (!settings.mcpServers) {
|
|
19
|
+
settings.mcpServers = {};
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
let added = 0;
|
|
23
|
+
let skipped = 0;
|
|
24
|
+
|
|
25
|
+
for (const [name, config] of Object.entries(MCP_SERVERS)) {
|
|
26
|
+
if (settings.mcpServers[name]) {
|
|
27
|
+
skipped++;
|
|
28
|
+
} else {
|
|
29
|
+
settings.mcpServers[name] = config;
|
|
30
|
+
added++;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
ensureDir(path.dirname(settingsPath));
|
|
35
|
+
fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + '\n', 'utf-8');
|
|
36
|
+
|
|
37
|
+
return { added, skipped };
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
module.exports = { installMCPs };
|
package/lib/prompts.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
const readline = require('readline');
|
|
2
|
+
|
|
3
|
+
function question(prompt, options) {
|
|
4
|
+
const rl = readline.createInterface({
|
|
5
|
+
input: process.stdin,
|
|
6
|
+
output: process.stdout,
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
return new Promise((resolve) => {
|
|
10
|
+
const optionsStr = options.map((o, i) => ` ${i + 1}) ${o}`).join('\n');
|
|
11
|
+
rl.question(`\n${prompt}\n${optionsStr}\n\n Choose [1-${options.length}]: `, (answer) => {
|
|
12
|
+
rl.close();
|
|
13
|
+
const idx = parseInt(answer, 10) - 1;
|
|
14
|
+
if (idx >= 0 && idx < options.length) {
|
|
15
|
+
resolve(options[idx]);
|
|
16
|
+
} else {
|
|
17
|
+
resolve(options[0]);
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
async function selectLanguage(flagLang) {
|
|
24
|
+
if (flagLang && ['en', 'pt-br'].includes(flagLang)) {
|
|
25
|
+
return flagLang;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const lang = await question('Select language / Selecione o idioma:', [
|
|
29
|
+
'en',
|
|
30
|
+
'pt-br',
|
|
31
|
+
]);
|
|
32
|
+
|
|
33
|
+
return lang;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
module.exports = { selectLanguage, question };
|
package/lib/utils.js
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
|
|
4
|
+
function ensureDir(dirPath) {
|
|
5
|
+
fs.mkdirSync(dirPath, { recursive: true });
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
function fileExists(filePath) {
|
|
9
|
+
return fs.existsSync(filePath);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function copyFile(src, dest, force = false) {
|
|
13
|
+
const exists = fileExists(dest);
|
|
14
|
+
if (exists && !force) {
|
|
15
|
+
return 'skipped';
|
|
16
|
+
}
|
|
17
|
+
ensureDir(path.dirname(dest));
|
|
18
|
+
fs.copyFileSync(src, dest);
|
|
19
|
+
return exists ? 'overwritten' : 'created';
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function writeFile(filePath, content, force = false) {
|
|
23
|
+
const exists = fileExists(filePath);
|
|
24
|
+
if (exists && !force) {
|
|
25
|
+
return 'skipped';
|
|
26
|
+
}
|
|
27
|
+
ensureDir(path.dirname(filePath));
|
|
28
|
+
fs.writeFileSync(filePath, content, 'utf-8');
|
|
29
|
+
return exists ? 'overwritten' : 'created';
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function copyDir(srcDir, destDir, force = false) {
|
|
33
|
+
const results = { created: 0, skipped: 0, overwritten: 0 };
|
|
34
|
+
|
|
35
|
+
if (!fs.existsSync(srcDir)) {
|
|
36
|
+
return results;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const entries = fs.readdirSync(srcDir, { withFileTypes: true });
|
|
40
|
+
for (const entry of entries) {
|
|
41
|
+
const srcPath = path.join(srcDir, entry.name);
|
|
42
|
+
const destPath = path.join(destDir, entry.name);
|
|
43
|
+
|
|
44
|
+
if (entry.isDirectory()) {
|
|
45
|
+
const sub = copyDir(srcPath, destPath, force);
|
|
46
|
+
results.created += sub.created;
|
|
47
|
+
results.skipped += sub.skipped;
|
|
48
|
+
results.overwritten += sub.overwritten;
|
|
49
|
+
} else {
|
|
50
|
+
const status = copyFile(srcPath, destPath, force);
|
|
51
|
+
results[status]++;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return results;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function log(status, filePath) {
|
|
59
|
+
const icons = {
|
|
60
|
+
created: '\x1b[32m+\x1b[0m',
|
|
61
|
+
skipped: '\x1b[33m~\x1b[0m',
|
|
62
|
+
overwritten: '\x1b[36m!\x1b[0m',
|
|
63
|
+
};
|
|
64
|
+
const icon = icons[status] || ' ';
|
|
65
|
+
const relative = path.relative(process.cwd(), filePath);
|
|
66
|
+
console.log(` ${icon} ${relative} [${status}]`);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
module.exports = { ensureDir, fileExists, copyFile, writeFile, copyDir, log };
|
package/lib/wrappers.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const { PLATFORMS } = require('./constants');
|
|
3
|
+
const { writeFile, log } = require('./utils');
|
|
4
|
+
|
|
5
|
+
function generateWrappers(projectRoot, commands, force = false) {
|
|
6
|
+
const results = { created: 0, skipped: 0, overwritten: 0 };
|
|
7
|
+
|
|
8
|
+
for (const [platformName, platform] of Object.entries(PLATFORMS)) {
|
|
9
|
+
for (const cmd of commands) {
|
|
10
|
+
const skillDir = path.join(projectRoot, platform.dir, cmd.name);
|
|
11
|
+
const skillFile = path.join(skillDir, 'SKILL.md');
|
|
12
|
+
const content = platform.wrapperTemplate(cmd.name, cmd.description);
|
|
13
|
+
const status = writeFile(skillFile, content, force);
|
|
14
|
+
results[status]++;
|
|
15
|
+
log(status, skillFile);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
return results;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
module.exports = { generateWrappers };
|
package/package.json
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@brunosps00/dev-workflow",
|
|
3
|
+
"version": "0.0.3",
|
|
4
|
+
"description": "AI-driven development workflow commands for any project. Scaffolds a complete PRD-to-PR pipeline with multi-platform AI assistant support.",
|
|
5
|
+
"bin": {
|
|
6
|
+
"dev-workflow": "./bin/dev-workflow.js"
|
|
7
|
+
},
|
|
8
|
+
"files": [
|
|
9
|
+
"bin/",
|
|
10
|
+
"lib/",
|
|
11
|
+
"scaffold/",
|
|
12
|
+
"README.md",
|
|
13
|
+
"LICENSE"
|
|
14
|
+
],
|
|
15
|
+
"keywords": [
|
|
16
|
+
"ai",
|
|
17
|
+
"workflow",
|
|
18
|
+
"development",
|
|
19
|
+
"cli",
|
|
20
|
+
"claude",
|
|
21
|
+
"codex",
|
|
22
|
+
"copilot",
|
|
23
|
+
"opencode",
|
|
24
|
+
"prd",
|
|
25
|
+
"techspec",
|
|
26
|
+
"code-review",
|
|
27
|
+
"qa"
|
|
28
|
+
],
|
|
29
|
+
"publishConfig": {
|
|
30
|
+
"access": "public"
|
|
31
|
+
},
|
|
32
|
+
"license": "MIT",
|
|
33
|
+
"engines": {
|
|
34
|
+
"node": ">=18"
|
|
35
|
+
},
|
|
36
|
+
"repository": {
|
|
37
|
+
"type": "git",
|
|
38
|
+
"url": "https://github.com/brunosantos/dev-workflow"
|
|
39
|
+
},
|
|
40
|
+
"author": "Bruno Santos"
|
|
41
|
+
}
|