buildflow-dev 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +266 -0
- package/bin/buildflow.js +80 -0
- package/package.json +60 -0
- package/src/commands/audit.js +230 -0
- package/src/commands/init.js +239 -0
- package/src/commands/install.js +537 -0
- package/src/commands/status.js +62 -0
- package/src/commands/update.js +35 -0
- package/src/index.js +5 -0
- package/src/utils/welcome.js +83 -0
- package/templates/CLAUDE.md +75 -0
- package/templates/commands/audit.md +119 -0
- package/templates/commands/back.md +59 -0
- package/templates/commands/build.md +61 -0
- package/templates/commands/check.md +62 -0
- package/templates/commands/explain.md +53 -0
- package/templates/commands/help.md +84 -0
- package/templates/commands/modify.md +65 -0
- package/templates/commands/onboard.md +78 -0
- package/templates/commands/plan.md +60 -0
- package/templates/commands/refactor.md +58 -0
- package/templates/commands/ship.md +97 -0
- package/templates/commands/start.md +39 -0
- package/templates/commands/status.md +50 -0
- package/templates/commands/think.md +49 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Vikas Gurrapu
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
# BuildFlow
|
|
2
|
+
|
|
3
|
+
> Adaptive AI-powered development orchestration
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/buildflow-dev)
|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## Install
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
# Interactive setup (recommended)
|
|
14
|
+
npx buildflow-dev init
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
# Or install globally
|
|
19
|
+
npm install -g buildflow-dev
|
|
20
|
+
buildflow init
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## What It Does
|
|
26
|
+
|
|
27
|
+
`buildflow init` will:
|
|
28
|
+
|
|
29
|
+
1. **Detect your project** — existing codebase or greenfield, your framework, language, test setup
|
|
30
|
+
2. **Set up `.buildflow/`** — agents, memory, security rules, codebase knowledge
|
|
31
|
+
3. **Detect installed AI tools** — Claude Code, Gemini CLI, Codex CLI, Cursor, Cline, Continue
|
|
32
|
+
4. **Install `/buildflow-*` slash commands** into each detected tool
|
|
33
|
+
5. **You type `/` in your AI tool** to see and use the commands
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## Supported AI Tools
|
|
38
|
+
|
|
39
|
+
| Tool | Detection | Global Install | Local Install | Slash Commands |
|
|
40
|
+
|------|-----------|----------------|---------------|----------------|
|
|
41
|
+
| **Claude Code** | ✓ Auto-detect | `~/.claude/commands/` | `.claude/commands/` | `/buildflow-*` |
|
|
42
|
+
| **Gemini CLI** | ✓ Auto-detect | `~/.gemini/commands/` | `.gemini/commands/` | `/buildflow-*` |
|
|
43
|
+
| **Codex CLI** | ✓ Auto-detect | `~/.codex/instructions/` | `.codex/instructions/` | `/buildflow-*` |
|
|
44
|
+
| **Cursor** | ✓ Auto-detect | (local only) | `.cursor/rules/` | `@buildflow-*` |
|
|
45
|
+
| **Cline** | ✓ Auto-detect | (local only) | `.clinerules` | `/buildflow-*` |
|
|
46
|
+
| **Continue** | ✓ Auto-detect | `~/.continue/` | `.continue/` | `/buildflow-*` |
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## Commands (type `/` in your AI tool)
|
|
51
|
+
|
|
52
|
+
### Workflow
|
|
53
|
+
|
|
54
|
+
| Command | Purpose | Tokens |
|
|
55
|
+
|---------|---------|--------|
|
|
56
|
+
| `/buildflow-start` | Begin project (smart mode detection) | ~8K |
|
|
57
|
+
| `/buildflow-think` | Discuss & research (parallel agents) | ~30K |
|
|
58
|
+
| `/buildflow-plan` | Create execution plan | ~20K |
|
|
59
|
+
| `/buildflow-build` | Execute plan (parallel waves) | ~50K/task |
|
|
60
|
+
| `/buildflow-check` | Verify quality | ~20K |
|
|
61
|
+
| `/buildflow-ship` | Finalize + **security gate** | ~22K |
|
|
62
|
+
|
|
63
|
+
### Existing Codebase
|
|
64
|
+
|
|
65
|
+
| Command | Purpose | Tokens |
|
|
66
|
+
|---------|---------|--------|
|
|
67
|
+
| `/buildflow-onboard` | Map codebase (run once) | ~35K |
|
|
68
|
+
| `/buildflow-modify` | Change existing code safely | ~30K |
|
|
69
|
+
| `/buildflow-refactor` | Improve existing code | ~40K |
|
|
70
|
+
|
|
71
|
+
### Security
|
|
72
|
+
|
|
73
|
+
| Command | Purpose | Tokens |
|
|
74
|
+
|---------|---------|--------|
|
|
75
|
+
| `/buildflow-audit` | Full OWASP Top 10 scan | ~35K |
|
|
76
|
+
| `/buildflow-audit --quick` | Recent changes only | ~15K |
|
|
77
|
+
|
|
78
|
+
### Utility
|
|
79
|
+
|
|
80
|
+
| Command | Purpose | Tokens |
|
|
81
|
+
|---------|---------|--------|
|
|
82
|
+
| `/buildflow-status` | Where am I? | ~3K |
|
|
83
|
+
| `/buildflow-explain <term>` | Define jargon or describe file | ~2K |
|
|
84
|
+
| `/buildflow-back` | Undo to safe restore point | ~3K |
|
|
85
|
+
| `/buildflow-help` | Diagnostic recovery | ~15K |
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## CLI Commands (terminal, outside AI tool)
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
buildflow init # Set up BuildFlow + install slash commands
|
|
93
|
+
buildflow install # (Re)install into AI tools
|
|
94
|
+
buildflow install --tool claude # Install into specific tool
|
|
95
|
+
buildflow install --tool all # Install into all detected tools
|
|
96
|
+
buildflow audit # Terminal-level security scan (pattern-based)
|
|
97
|
+
buildflow audit --quick # Scan recent changes only
|
|
98
|
+
buildflow status # Show project state
|
|
99
|
+
buildflow update # Update commands to latest version
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
## How It Works
|
|
105
|
+
|
|
106
|
+
### 9 Specialized Agents
|
|
107
|
+
|
|
108
|
+
Each agent gets a **fresh 200K context window** — no context rot.
|
|
109
|
+
|
|
110
|
+
| Agent | Role | Used In |
|
|
111
|
+
|-------|------|---------|
|
|
112
|
+
| 🎯 Strategist | Vision & decisions | `/buildflow-start`, `/buildflow-think` |
|
|
113
|
+
| 🔍 Researcher | Parallel web research with source confidence | `/buildflow-think` |
|
|
114
|
+
| 🔄 Synthesizer | Combines parallel research findings | `/buildflow-think` |
|
|
115
|
+
| 🏗️ Architect | Dependency-aware planning | `/buildflow-plan` |
|
|
116
|
+
| ⚒️ Builder | Code matching your style (parallel) | `/buildflow-build` |
|
|
117
|
+
| 🔬 Reviewer | Quality checks (parallel) | `/buildflow-check` |
|
|
118
|
+
| 🗺️ Cartographer | Maps existing codebases | `/buildflow-onboard` |
|
|
119
|
+
| 🩺 Surgeon | Precise code modification | `/buildflow-modify` |
|
|
120
|
+
| 🔒 Security Auditor | OWASP Top 10 scanning | `/buildflow-audit`, `/buildflow-ship` |
|
|
121
|
+
|
|
122
|
+
### Parallelization
|
|
123
|
+
|
|
124
|
+
Research and building run agents in parallel:
|
|
125
|
+
|
|
126
|
+
```
|
|
127
|
+
Sequential: 3 research topics × 60s = 180s
|
|
128
|
+
Parallel: 3 researchers simultaneously = 60s (67% faster)
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### Light Memory
|
|
132
|
+
|
|
133
|
+
`.buildflow/memory/light.md` persists essentials across sessions (under 5K tokens). Saves more than it costs.
|
|
134
|
+
|
|
135
|
+
### Security Gate
|
|
136
|
+
|
|
137
|
+
Every `/buildflow-ship` runs a pre-ship security check:
|
|
138
|
+
- 🔴 Critical → **BLOCKED** (must fix)
|
|
139
|
+
- 🟡 High → WARNING (can ship, log to DEBT.md)
|
|
140
|
+
- ✅ Clean → Ship freely
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
## Project Structure
|
|
145
|
+
|
|
146
|
+
```
|
|
147
|
+
your-project/
|
|
148
|
+
├── .buildflow/
|
|
149
|
+
│ ├── core/
|
|
150
|
+
│ │ ├── vision.md ← What you're building
|
|
151
|
+
│ │ └── state.md ← Current position
|
|
152
|
+
│ ├── you/
|
|
153
|
+
│ │ ├── preferences.md ← Your settings
|
|
154
|
+
│ │ └── style-guide.md ← Auto-detected code style
|
|
155
|
+
│ ├── memory/
|
|
156
|
+
│ │ └── light.md ← Persistent context (≤5K)
|
|
157
|
+
│ ├── codebase/ ← Existing project maps
|
|
158
|
+
│ │ ├── MAP.md
|
|
159
|
+
│ │ ├── PATTERNS.md
|
|
160
|
+
│ │ ├── DEPENDENCIES.md
|
|
161
|
+
│ │ └── HOTSPOTS.md
|
|
162
|
+
│ ├── security/
|
|
163
|
+
│ │ ├── DEBT.md
|
|
164
|
+
│ │ └── reports/
|
|
165
|
+
│ ├── phases/ ← Per-phase work
|
|
166
|
+
│ └── learnings/ ← Glossary, decisions
|
|
167
|
+
│
|
|
168
|
+
├── commands/buildflow/ ← Slash command definitions
|
|
169
|
+
│ ├── start.md
|
|
170
|
+
│ ├── think.md
|
|
171
|
+
│ └── ... (14 commands)
|
|
172
|
+
│
|
|
173
|
+
└── agents/ ← Agent personalities
|
|
174
|
+
├── strategist.md
|
|
175
|
+
└── ... (9 agents)
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
For AI tools with dedicated directories:
|
|
179
|
+
|
|
180
|
+
```
|
|
181
|
+
~/.claude/commands/buildflow-*.md ← Global Claude Code
|
|
182
|
+
.claude/commands/buildflow-*.md ← Local Claude Code
|
|
183
|
+
~/.gemini/commands/buildflow-*.md ← Global Gemini CLI
|
|
184
|
+
.cursor/rules/buildflow.mdc ← Cursor
|
|
185
|
+
.clinerules ← Cline
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
---
|
|
189
|
+
|
|
190
|
+
## Examples
|
|
191
|
+
|
|
192
|
+
### New project
|
|
193
|
+
|
|
194
|
+
```bash
|
|
195
|
+
mkdir my-app && cd my-app
|
|
196
|
+
npx buildflow-dev init
|
|
197
|
+
|
|
198
|
+
# → Detects: No existing code (greenfield)
|
|
199
|
+
# → Detects: Claude Code ✓, Cursor ✓
|
|
200
|
+
# → Installs commands into both
|
|
201
|
+
# → Opens Claude Code...
|
|
202
|
+
|
|
203
|
+
/buildflow-start
|
|
204
|
+
/buildflow-think tech-stack
|
|
205
|
+
/buildflow-plan phase-1
|
|
206
|
+
/buildflow-build phase-1
|
|
207
|
+
/buildflow-check
|
|
208
|
+
/buildflow-ship ← security gate runs automatically
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
### Existing project
|
|
212
|
+
|
|
213
|
+
```bash
|
|
214
|
+
cd my-existing-app
|
|
215
|
+
npx buildflow-dev init
|
|
216
|
+
|
|
217
|
+
# → Detects: Next.js project
|
|
218
|
+
# → Detects: Claude Code ✓
|
|
219
|
+
# → Installs commands
|
|
220
|
+
# → Opens Claude Code...
|
|
221
|
+
|
|
222
|
+
/buildflow-onboard ← one-time codebase analysis
|
|
223
|
+
/buildflow-modify "Add dark mode to settings page"
|
|
224
|
+
/buildflow-refactor src/components/Dashboard.tsx
|
|
225
|
+
/buildflow-audit --quick ← security check on recent changes
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
---
|
|
229
|
+
|
|
230
|
+
## Token Economics
|
|
231
|
+
|
|
232
|
+
| Mode | Per Session | Notes |
|
|
233
|
+
|------|-------------|-------|
|
|
234
|
+
| Greenfield | 130-160K | Full workflow |
|
|
235
|
+
| Existing (first time) | +35K | One-time onboarding |
|
|
236
|
+
| Existing (after onboard) | 130-160K | Same as greenfield |
|
|
237
|
+
| Security gate (pre-ship) | +10K | Always runs with ship |
|
|
238
|
+
|
|
239
|
+
Light memory SAVES ~10K per session vs no memory (avoids re-detection).
|
|
240
|
+
|
|
241
|
+
---
|
|
242
|
+
|
|
243
|
+
## Contributing
|
|
244
|
+
|
|
245
|
+
1. Fork the repository
|
|
246
|
+
2. Create a feature branch: `git checkout -b feat/new-agent`
|
|
247
|
+
3. Make changes
|
|
248
|
+
4. Run tests: `npm test`
|
|
249
|
+
5. Submit a PR
|
|
250
|
+
|
|
251
|
+
---
|
|
252
|
+
|
|
253
|
+
## License
|
|
254
|
+
|
|
255
|
+
MIT © 2026
|
|
256
|
+
|
|
257
|
+
---
|
|
258
|
+
|
|
259
|
+
## Roadmap
|
|
260
|
+
|
|
261
|
+
- [ ] `buildflow install --tool windsurf` (Windsurf IDE)
|
|
262
|
+
- [ ] `buildflow install --tool aider` (Aider CLI)
|
|
263
|
+
- [ ] Web dashboard for project status
|
|
264
|
+
- [ ] Team collaboration features
|
|
265
|
+
- [ ] GitHub Actions integration
|
|
266
|
+
- [ ] Custom agent creation wizard
|
package/bin/buildflow.js
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { program } from 'commander'
|
|
4
|
+
import { readFileSync } from 'fs'
|
|
5
|
+
import { fileURLToPath } from 'url'
|
|
6
|
+
import { dirname, join } from 'path'
|
|
7
|
+
|
|
8
|
+
const __dirname = dirname(fileURLToPath(import.meta.url))
|
|
9
|
+
const pkg = JSON.parse(readFileSync(join(__dirname, '../package.json'), 'utf8'))
|
|
10
|
+
|
|
11
|
+
const loadInit = () => import('../src/commands/init.js')
|
|
12
|
+
const loadInstall = () => import('../src/commands/install.js')
|
|
13
|
+
const loadAudit = () => import('../src/commands/audit.js')
|
|
14
|
+
const loadStatus = () => import('../src/commands/status.js')
|
|
15
|
+
const loadUpdate = () => import('../src/commands/update.js')
|
|
16
|
+
|
|
17
|
+
program
|
|
18
|
+
.name('buildflow')
|
|
19
|
+
.description('Adaptive AI-powered development orchestration')
|
|
20
|
+
.version(pkg.version)
|
|
21
|
+
|
|
22
|
+
program
|
|
23
|
+
.command('init')
|
|
24
|
+
.description('Initialize BuildFlow in the current project')
|
|
25
|
+
.option('-y, --yes', 'Skip prompts, use defaults')
|
|
26
|
+
.option('--greenfield', 'Start a brand-new project')
|
|
27
|
+
.option('--existing', 'Add BuildFlow to existing codebase')
|
|
28
|
+
.action(async (opts) => {
|
|
29
|
+
const { run } = await loadInit()
|
|
30
|
+
await run(opts)
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
program
|
|
34
|
+
.command('install')
|
|
35
|
+
.description('Install BuildFlow slash commands into an AI tool')
|
|
36
|
+
.option('--tool <name>', 'AI tool to install into (claude|gemini|codex|cursor|all)')
|
|
37
|
+
.option('--global', 'Install globally (available in all projects)')
|
|
38
|
+
.option('--local', 'Install locally (current project only)')
|
|
39
|
+
.action(async (opts) => {
|
|
40
|
+
const { run } = await loadInstall()
|
|
41
|
+
await run(opts)
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
program
|
|
45
|
+
.command('audit')
|
|
46
|
+
.description('Run a security audit on the current project')
|
|
47
|
+
.option('-q, --quick', 'Quick audit (recent changes only)')
|
|
48
|
+
.option('-t, --target <path>', 'Audit specific file or directory')
|
|
49
|
+
.option('-c, --category <name>', 'Check specific OWASP category (A01-A10)')
|
|
50
|
+
.option('-r, --report', 'Show latest report')
|
|
51
|
+
.action(async (opts) => {
|
|
52
|
+
const { run } = await loadAudit()
|
|
53
|
+
await run(opts)
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
program
|
|
57
|
+
.command('status')
|
|
58
|
+
.description('Show BuildFlow status for current project')
|
|
59
|
+
.option('-v, --verbose', 'Show detailed status')
|
|
60
|
+
.action(async (opts) => {
|
|
61
|
+
const { run } = await loadStatus()
|
|
62
|
+
await run(opts)
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
program
|
|
66
|
+
.command('update')
|
|
67
|
+
.description('Update BuildFlow commands and agents in current project')
|
|
68
|
+
.option('--check', 'Check for updates without applying')
|
|
69
|
+
.action(async (opts) => {
|
|
70
|
+
const { run } = await loadUpdate()
|
|
71
|
+
await run(opts)
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
if (process.argv.length <= 2) {
|
|
75
|
+
const { showWelcome } = await import('../src/utils/welcome.js')
|
|
76
|
+
await showWelcome()
|
|
77
|
+
process.exit(0)
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
program.parse()
|
package/package.json
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "buildflow-dev",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Adaptive AI-powered development orchestration. Works with Claude Code, Gemini CLI, Codex CLI, Cursor, and more.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"ai",
|
|
7
|
+
"claude",
|
|
8
|
+
"gemini",
|
|
9
|
+
"codex",
|
|
10
|
+
"cursor",
|
|
11
|
+
"developer-tools",
|
|
12
|
+
"cli",
|
|
13
|
+
"workflow",
|
|
14
|
+
"scaffolding",
|
|
15
|
+
"security-audit",
|
|
16
|
+
"code-generation"
|
|
17
|
+
],
|
|
18
|
+
"homepage": "https://github.com/Vikas-gurrapu/buildflow",
|
|
19
|
+
"bugs": {
|
|
20
|
+
"url": "https://github.com/Vikas-gurrapu/buildflow/issues"
|
|
21
|
+
},
|
|
22
|
+
"repository": {
|
|
23
|
+
"type": "git",
|
|
24
|
+
"url": "git+https://github.com/Vikas-gurrapu/buildflow.git"
|
|
25
|
+
},
|
|
26
|
+
"license": "MIT",
|
|
27
|
+
"author": "Vikas Gurrapu <vikas.gurrapu@gmail.com>",
|
|
28
|
+
"type": "module",
|
|
29
|
+
"main": "src/index.js",
|
|
30
|
+
"bin": {
|
|
31
|
+
"buildflow": "./bin/buildflow.js",
|
|
32
|
+
"bf": "./bin/buildflow.js"
|
|
33
|
+
},
|
|
34
|
+
"files": [
|
|
35
|
+
"bin/",
|
|
36
|
+
"src/",
|
|
37
|
+
"templates/",
|
|
38
|
+
"README.md",
|
|
39
|
+
"LICENSE"
|
|
40
|
+
],
|
|
41
|
+
"scripts": {
|
|
42
|
+
"start": "node bin/buildflow.js",
|
|
43
|
+
"test": "node --test src/**/*.test.js",
|
|
44
|
+
"lint": "eslint src/ bin/",
|
|
45
|
+
"prepublishOnly": "npm test"
|
|
46
|
+
},
|
|
47
|
+
"dependencies": {
|
|
48
|
+
"chalk": "^5.3.0",
|
|
49
|
+
"commander": "^11.1.0",
|
|
50
|
+
"enquirer": "^2.4.1",
|
|
51
|
+
"ora": "^8.0.1",
|
|
52
|
+
"which": "^4.0.0"
|
|
53
|
+
},
|
|
54
|
+
"devDependencies": {
|
|
55
|
+
"eslint": "^8.56.0"
|
|
56
|
+
},
|
|
57
|
+
"engines": {
|
|
58
|
+
"node": ">=18.0.0"
|
|
59
|
+
}
|
|
60
|
+
}
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
import chalk from 'chalk'
|
|
2
|
+
import ora from 'ora'
|
|
3
|
+
import { existsSync, readFileSync, writeFileSync, readdirSync, statSync, mkdirSync } from 'fs'
|
|
4
|
+
import { join, relative, resolve } from 'path'
|
|
5
|
+
|
|
6
|
+
const SECRET_PATTERNS = [
|
|
7
|
+
{ pattern: /(?<![a-zA-Z])(sk|pk|rk)[-_][a-zA-Z0-9]{20,}/g, label: 'API Key (sk/pk/rk)' },
|
|
8
|
+
{ pattern: /AKIA[0-9A-Z]{16}/g, label: 'AWS Access Key' },
|
|
9
|
+
{ pattern: /-----BEGIN (RSA |EC |DSA |OPENSSH )?PRIVATE KEY/g, label: 'Private Key' },
|
|
10
|
+
{ pattern: /['"]\s*(password|passwd|pwd|secret|api.?key|auth.?token)\s*['"]?\s*[:=]\s*['"][^'"]{4,}/gi, label: 'Hardcoded credential' },
|
|
11
|
+
{ pattern: /postgres:\/\/[^@]+:[^@]+@/g, label: 'DB URL with credentials' },
|
|
12
|
+
{ pattern: /mongodb(\+srv)?:\/\/[^@]+:[^@]+@/g, label: 'MongoDB URL with credentials' },
|
|
13
|
+
]
|
|
14
|
+
|
|
15
|
+
const VULN_PATTERNS = [
|
|
16
|
+
{
|
|
17
|
+
pattern: /\.query\s*\(\s*[`'"]\s*SELECT.*?\$\{|\.query\s*\(\s*["'`].*?\+\s*\w/gs,
|
|
18
|
+
label: 'Possible SQL Injection',
|
|
19
|
+
severity: 'CRITICAL',
|
|
20
|
+
owasp: 'A03',
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
pattern: /eval\s*\(/g,
|
|
24
|
+
label: 'eval() usage',
|
|
25
|
+
severity: 'HIGH',
|
|
26
|
+
owasp: 'A03',
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
pattern: /exec\s*\(\s*[`'"]\s*.*?\$\{|execSync\s*\(\s*[`'"]\s*.*?\$\{/g,
|
|
30
|
+
label: 'Command injection risk',
|
|
31
|
+
severity: 'CRITICAL',
|
|
32
|
+
owasp: 'A03',
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
pattern: /Math\.random\s*\(\)/g,
|
|
36
|
+
label: 'Math.random() used for tokens (not cryptographically secure)',
|
|
37
|
+
severity: 'HIGH',
|
|
38
|
+
owasp: 'A07',
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
pattern: /console\.log\s*\([^)]*(?:password|token|secret|key|user)[^)]*\)/gi,
|
|
42
|
+
label: 'Sensitive data may be logged',
|
|
43
|
+
severity: 'MEDIUM',
|
|
44
|
+
owasp: 'A09',
|
|
45
|
+
},
|
|
46
|
+
]
|
|
47
|
+
|
|
48
|
+
const CODE_EXTENSIONS = new Set(['.js', '.ts', '.jsx', '.tsx', '.mjs', '.cjs', '.py', '.go', '.rs', '.java'])
|
|
49
|
+
const SKIP_DIRS = new Set(['node_modules', '.git', 'dist', 'build', '.next', '__pycache__', 'coverage'])
|
|
50
|
+
|
|
51
|
+
function* walkFiles(dir) {
|
|
52
|
+
for (const entry of readdirSync(dir)) {
|
|
53
|
+
if (SKIP_DIRS.has(entry)) continue
|
|
54
|
+
const full = join(dir, entry)
|
|
55
|
+
if (statSync(full).isDirectory()) {
|
|
56
|
+
yield* walkFiles(full)
|
|
57
|
+
} else if (CODE_EXTENSIONS.has(entry.slice(entry.lastIndexOf('.')))) {
|
|
58
|
+
yield full
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function scanFile(filePath) {
|
|
64
|
+
let content
|
|
65
|
+
try { content = readFileSync(filePath, 'utf8') } catch { return [] }
|
|
66
|
+
|
|
67
|
+
const isTestFile = /\.(test|spec)\.[jt]sx?$/.test(filePath) ||
|
|
68
|
+
filePath.includes('__tests__') ||
|
|
69
|
+
filePath.includes('fixtures')
|
|
70
|
+
|
|
71
|
+
const findings = []
|
|
72
|
+
const lines = content.split('\n')
|
|
73
|
+
|
|
74
|
+
if (!isTestFile) {
|
|
75
|
+
for (const { pattern, label } of SECRET_PATTERNS) {
|
|
76
|
+
for (let i = 0; i < lines.length; i++) {
|
|
77
|
+
pattern.lastIndex = 0
|
|
78
|
+
if (pattern.test(lines[i])) {
|
|
79
|
+
findings.push({
|
|
80
|
+
type: 'SECRET',
|
|
81
|
+
severity: 'CRITICAL',
|
|
82
|
+
label,
|
|
83
|
+
file: filePath,
|
|
84
|
+
line: i + 1,
|
|
85
|
+
snippet: lines[i].trim().slice(0, 80),
|
|
86
|
+
})
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
for (const { pattern, label, severity, owasp } of VULN_PATTERNS) {
|
|
93
|
+
for (let i = 0; i < lines.length; i++) {
|
|
94
|
+
pattern.lastIndex = 0
|
|
95
|
+
if (pattern.test(lines[i])) {
|
|
96
|
+
findings.push({
|
|
97
|
+
type: 'VULN',
|
|
98
|
+
severity,
|
|
99
|
+
label,
|
|
100
|
+
owasp,
|
|
101
|
+
file: filePath,
|
|
102
|
+
line: i + 1,
|
|
103
|
+
snippet: lines[i].trim().slice(0, 80),
|
|
104
|
+
})
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return findings
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export async function run(opts = {}) {
|
|
113
|
+
const cwd = process.cwd()
|
|
114
|
+
const base = join(cwd, '.buildflow')
|
|
115
|
+
|
|
116
|
+
if (!existsSync(base)) {
|
|
117
|
+
console.log(chalk.yellow('\n BuildFlow not initialized. Run: npx buildflow-dev init\n'))
|
|
118
|
+
return
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if (opts.report) {
|
|
122
|
+
const reportsDir = join(base, 'security', 'reports')
|
|
123
|
+
if (!existsSync(reportsDir)) {
|
|
124
|
+
console.log(chalk.dim('\n No reports yet. Run: buildflow audit\n'))
|
|
125
|
+
return
|
|
126
|
+
}
|
|
127
|
+
const reports = readdirSync(reportsDir).filter(f => f.endsWith('.md')).sort().reverse()
|
|
128
|
+
if (reports.length === 0) {
|
|
129
|
+
console.log(chalk.dim('\n No reports yet.\n'))
|
|
130
|
+
return
|
|
131
|
+
}
|
|
132
|
+
console.log('\n' + readFileSync(join(reportsDir, reports[0]), 'utf8'))
|
|
133
|
+
return
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
console.log('\n' + chalk.bold.white(' BuildFlow — Security Audit\n'))
|
|
137
|
+
|
|
138
|
+
const target = opts.target ? resolve(opts.target) : cwd
|
|
139
|
+
const spinner = ora('Scanning files...').start()
|
|
140
|
+
|
|
141
|
+
const allFindings = []
|
|
142
|
+
let fileCount = 0
|
|
143
|
+
|
|
144
|
+
for (const filePath of walkFiles(target)) {
|
|
145
|
+
fileCount++
|
|
146
|
+
allFindings.push(...scanFile(filePath))
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
spinner.stop()
|
|
150
|
+
|
|
151
|
+
const critical = allFindings.filter(f => f.severity === 'CRITICAL')
|
|
152
|
+
const high = allFindings.filter(f => f.severity === 'HIGH')
|
|
153
|
+
const medium = allFindings.filter(f => f.severity === 'MEDIUM')
|
|
154
|
+
|
|
155
|
+
console.log(chalk.dim(` Scanned ${fileCount} files\n`))
|
|
156
|
+
|
|
157
|
+
const severityLine = [
|
|
158
|
+
critical.length > 0 ? chalk.red(` 🔴 ${critical.length} critical`) : chalk.dim(' 🟤 0 critical'),
|
|
159
|
+
high.length > 0 ? chalk.yellow(` 🟡 ${high.length} high`) : chalk.dim(' ○ 0 high'),
|
|
160
|
+
medium.length > 0 ? chalk.yellow(` 🟠 ${medium.length} medium`) : chalk.dim(' ○ 0 medium'),
|
|
161
|
+
].join(' ')
|
|
162
|
+
console.log(severityLine + '\n')
|
|
163
|
+
|
|
164
|
+
if (allFindings.length === 0) {
|
|
165
|
+
console.log(chalk.green(' ✓ No issues found in quick scan.\n'))
|
|
166
|
+
console.log(chalk.dim(' Note: This is a pattern-based scan. For full OWASP analysis,'))
|
|
167
|
+
console.log(chalk.dim(' run /buildflow-audit inside your AI tool.\n'))
|
|
168
|
+
return
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
const printGroup = (findings, icon, color) => {
|
|
172
|
+
for (const f of findings) {
|
|
173
|
+
const rel = relative(cwd, f.file)
|
|
174
|
+
console.log(color(` ${icon} [${f.severity}] ${f.label}`))
|
|
175
|
+
console.log(chalk.dim(` File: ${rel}:${f.line}`))
|
|
176
|
+
console.log(chalk.dim(` Code: ${f.snippet}`))
|
|
177
|
+
if (f.owasp) console.log(chalk.dim(` OWASP: ${f.owasp}`))
|
|
178
|
+
console.log('')
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
if (critical.length > 0) {
|
|
183
|
+
console.log(chalk.bold.red(' ── Critical ──────────────────────────\n'))
|
|
184
|
+
printGroup(critical, '🔴', chalk.red)
|
|
185
|
+
}
|
|
186
|
+
if (high.length > 0) {
|
|
187
|
+
console.log(chalk.bold.yellow(' ── High ──────────────────────────────\n'))
|
|
188
|
+
printGroup(high, '🟡', chalk.yellow)
|
|
189
|
+
}
|
|
190
|
+
if (medium.length > 0) {
|
|
191
|
+
console.log(chalk.bold.yellow(' ── Medium ────────────────────────────\n'))
|
|
192
|
+
printGroup(medium, '🟠', chalk.yellow)
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
const reportsDir = join(base, 'security', 'reports')
|
|
196
|
+
mkdirSync(reportsDir, { recursive: true })
|
|
197
|
+
const reportDate = new Date().toISOString().replace(/[:.]/g, '-').slice(0, -1)
|
|
198
|
+
const reportPath = join(reportsDir, `audit-${reportDate}.md`)
|
|
199
|
+
|
|
200
|
+
const reportContent = `# Security Audit Report
|
|
201
|
+
Date: ${new Date().toISOString().split('T')[0]}
|
|
202
|
+
Scanner: buildflow-dev CLI (pattern scan)
|
|
203
|
+
Files scanned: ${fileCount}
|
|
204
|
+
|
|
205
|
+
## Summary
|
|
206
|
+
Critical: ${critical.length}
|
|
207
|
+
High: ${high.length}
|
|
208
|
+
Medium: ${medium.length}
|
|
209
|
+
|
|
210
|
+
## Findings
|
|
211
|
+
|
|
212
|
+
${allFindings.map(f =>
|
|
213
|
+
`### [${f.severity}] ${f.label}\n- File: ${relative(cwd, f.file)}:${f.line}\n- Code: \`${f.snippet}\`${f.owasp ? `\n- OWASP: ${f.owasp}` : ''}\n`
|
|
214
|
+
).join('\n')}
|
|
215
|
+
|
|
216
|
+
## Notes
|
|
217
|
+
This is a pattern-based CLI scan. For deep OWASP analysis, run /buildflow-audit in your AI tool.
|
|
218
|
+
`
|
|
219
|
+
|
|
220
|
+
writeFileSync(reportPath, reportContent)
|
|
221
|
+
|
|
222
|
+
console.log(chalk.bold('\n Recommendations:\n'))
|
|
223
|
+
if (critical.length > 0) {
|
|
224
|
+
console.log(chalk.red(' Fix critical issues before committing or shipping.'))
|
|
225
|
+
}
|
|
226
|
+
console.log(chalk.dim(`\n Report saved: ${relative(cwd, reportPath)}`))
|
|
227
|
+
console.log(chalk.dim(' For full AI-powered analysis: /buildflow-audit in your AI tool\n'))
|
|
228
|
+
|
|
229
|
+
if (critical.length > 0) process.exit(1)
|
|
230
|
+
}
|