Skip to content

Commit b92921f

Browse files
committed
🪷 Release v1.1.3: Interactive Mode, Beautiful CLI, Development Scanner
Major Features: - Interactive Mode: --interactive flag for step-by-step issue walkthrough - Beautiful CLI: Lotus-inspired severity bands and enhanced 🪷 branding - Development Scanner: DEV001-005 rules for AI-generated code issues - Modular Rules: New architecture with category-based organization Enhanced UX: - Colored severity bands (Critical: red, High: coral, Medium: amber, Low: green) - Consistent lotus emoji throughout scanner completion messages - Enhanced success messages with lotus theming Technical: - Made printResults() async for interactive mode support - Added ScanOptions.interactive property - New /src/rules/ modular architecture - Backward compatibility maintained Documentation: - Updated CLI.md, FEATURES.md, CHANGELOG.md, README.md - Added comprehensive 1.1.3 changelog entry - Updated version to 1.1.3
1 parent 6bb02ac commit b92921f

File tree

25 files changed

+755
-28
lines changed

25 files changed

+755
-28
lines changed

‎CHANGELOG.md‎

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,37 @@ This patch focuses on triage-first UX and noise reduction without changing schem
140140
### Notes
141141
- Non-breaking; JSON/SARIF unchanged.
142142

143+
## 1.1.3 — 2025-08-29
144+
145+
### Added
146+
- **Interactive Mode**: `--interactive` flag for step-by-step issue walkthrough with explanations, context, and fix options
147+
- **Beautiful CLI Color System**: Lotus-inspired severity bands with enhanced visual triage
148+
- Critical: Deep lotus red, High: Coral pink, Medium: Amber, Low: Lotus green
149+
- Consistent `🪷` lotus branding throughout all scanner completion messages
150+
- **Modular Rules Architecture**: New `/src/rules/` structure with category-based organization for better maintainability
151+
- **Development Scanner**: New DEV001-005 rules specifically for AI-generated code issues
152+
- DEV001: TODO/FIXME comments detection
153+
- DEV002: "Not implemented" stubs and placeholder functions
154+
- DEV003: Placeholder URLs in API endpoints (`localhost`, `example.com`)
155+
- DEV004: Hardcoded mock/example data in responses
156+
- DEV005: Empty returns or unimplemented functions
157+
158+
### Enhanced
159+
- **Triage Header**: Beautiful colored severity bands replace basic text output
160+
- **Success Messages**: Enhanced with lotus theming ("🪷 No issues found! Your app is blooming beautifully! ✨")
161+
- **Scanner Progress**: All completion messages now use `🪷` lotus emoji for consistent branding
162+
163+
### Technical
164+
- Made `printResults()` async to support interactive mode
165+
- Added new `ScanOptions.interactive` property
166+
- Enhanced `getSeverityBand()` method with lotus-inspired color palette
167+
- Backward compatibility maintained for all existing features
168+
169+
### Notes
170+
- Interactive mode provides guided issue resolution perfect for AI-assisted debugging
171+
- Development scanner addresses the "vibe-coded" app debugging crisis
172+
- All changes are non-breaking; JSON/SARIF output unchanged
173+
143174
## 1.1.2 — 2025-08-27
144175

145176
### Added

‎README.md‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,13 @@ Example:
287287
288288
CLI flags override config values.
289289
290+
## Highlights in v1.1.3
291+
292+
- **Interactive Mode**: `--interactive` for guided issue resolution with explanations and fix options
293+
- **Beautiful CLI**: Lotus-inspired severity bands and enhanced `🪷` branding throughout
294+
- **Development Scanner**: DEV001-005 rules for catching AI-generated placeholder code and incomplete implementations
295+
- **Modular Rules**: New architecture with category-based organization for maintainability
296+
290297
## Highlights in v1.1.0
291298
292299
- Colorized, branded output with lotus (🪷); control via `--color auto|always|never`

‎docs/CLI.md‎

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ Options:
4646
--format <mode> Output format (human mode): human|table (default: human)
4747
--ai-friendly AI preset: json + context + explain + severity + cap 15
4848
--pr-comment Output Markdown summary for PR comments
49+
--interactive Walk through issues interactively with explanations and fix options
4950
--no-result-cache Disable per-file result cache (skip reuse between runs)
5051
--min-severity <level> Minimum severity to include: low|medium|high
5152
--max-issues <n> Limit output to N most important issues
@@ -92,8 +93,12 @@ ubon check --format table --group-by severity --show-confidence
9293
```
9394
9495
# Experimental P5 Next.js rules (enable/disable)
95-
ubon check --enable-rule NEXT201,NEXT202,NEXT203,NEXT205,NEXT208,NEXT209
96-
ubon check --disable-rule NEXT201,NEXT202,NEXT203,NEXT205,NEXT208,NEXT209
96+
ubon check --enable-rule NEXT201,NEXT202,NEXT203,NEXT205,NEXT208,NEXT209,NEXT210
97+
ubon check --disable-rule NEXT201,NEXT202,NEXT203,NEXT205,NEXT208,NEXT209,NEXT210
98+
99+
# Development placeholder detection (DEV001-005)
100+
ubon check --enable-rule DEV001,DEV002,DEV003,DEV004,DEV005
101+
# Great for AI-generated code with TODO/FIXME, "Not implemented", mock data
97102
```
98103

99104
#### ubon check
@@ -263,7 +268,7 @@ ubon init --profile auto
263268

264269
Options:
265270
- `--profile auto|react|next|python|vue` – override auto-detection
266-
- `--interactive` – reserved for future interactive prompts
271+
- `--interactive` – Walk through issues interactively with explanations and fix options
267272

268273
Next.js monorepo example (profile + baseline):
269274

‎docs/FEATURES.md‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,16 @@
88
| Next.js Routing/Structure (experimental) | missing 404/error pages, method validation, external router.push, server→client secret bleed | NEXT201–NEXT210 (opt-in via enable/disable) |
99
| Security (Python) | exec/eval, subprocess(shell=True), yaml.load, pickle, requests verify=False, DEBUG=True | PYSEC001–PYSEC010, PYNET001 |
1010
| Rails (experimental) | SQLi in where/find_by_sql, system/backticks, YAML.load, html_safe/raw, mass assignment | RAILS001–005 |
11+
| Development (placeholder detection) | TODO/FIXME comments, "Not implemented" stubs, placeholder URLs, mock data, empty returns | DEV001–005 |
1112
| Accessibility | <img> missing alt, inputs without labels, clickable divs without roles | A11Y001, A11Y004–005 |
1213
| Links & Resources | External link reachability with timeouts; optional internal crawling | LINK00x |
1314
| Dependency & Supply Chain | OSV.dev advisories for npm and PyPI | OSV001 |
1415
| Env & Config | .env hygiene, example drift, hardcoded fallbacks | ENV00x |
1516

1617
### Developer Experience
1718

19+
- **Interactive Mode**: `--interactive` for step-by-step issue walkthrough with explanations and fix options
20+
- **Beautiful CLI**: Lotus-inspired severity bands with enhanced visual triage (`🪷` branding throughout)
1821
- Colorized, branded output with lotus (🪷): `--color auto|always|never`
1922
- Result organization: `--group-by file|rule|severity|category`, `--min-severity`, `--max-issues`
2023
- Compact output: `--format table` for skimmable triage

‎docs/RULES.md‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@
66
- COOKIE002: JWT token exposed in client-side cookie without security flags ([docs](https://owasp.org/www-community/controls/SecureCookieAttributes))
77
- COOKIE003: Sensitive data returned in JSON response (potential token leak)
88
- COOKIE004: Cookie used without domain/path restrictions
9+
- DEV001: Function contains TODO/FIXME comments ([docs](https://docs.ubon.dev/rules/DEV001))
10+
- DEV002: Function throws "Not implemented" or contains stub code ([docs](https://docs.ubon.dev/rules/DEV002))
11+
- DEV003: API endpoints using placeholder URLs ([docs](https://docs.ubon.dev/rules/DEV003))
12+
- DEV004: Hardcoded mock/example data in API responses ([docs](https://docs.ubon.dev/rules/DEV004))
13+
- DEV005: Function returns null or empty objects without implementation ([docs](https://docs.ubon.dev/rules/DEV005))
914
- JSNET001: HTTP request without timeout/retry policy ([docs](https://developer.mozilla.org/docs/Web/API/AbortController))
1015
- LOG001: Potential secret logged to console/logger ([docs](https://cheatsheetseries.owasp.org/cheatsheets/Logging_Cheat_Sheet.html))
1116
- OSV001: Vulnerable dependency detected
@@ -41,6 +46,7 @@
4146
- NEXT009: Unsafe redirect in Next.js API route ([docs](https://owasp.org/www-community/attacks/Unvalidated_Redirects_and_Forwards_Cheat_Sheet))
4247
- NEXT010: CORS configuration too permissive ([docs](https://developer.mozilla.org/docs/Web/HTTP/CORS))
4348
- NEXT011: Environment variable leaked in client-side code ([docs](https://nextjs.org/docs/app/building-your-application/configuring/environment-variables#bundling-environment-variables-for-the-browser))
49+
- NEXT210: Server secret serialized to client props (leak risk) ([docs](https://nextjs.org/docs/pages/building-your-application/data-fetching/get-server-side-props#caveats))
4450

4551
### Accessibility
4652
- A11Y001: Image without alt attribute ([docs](https://webaim.org/techniques/alttext/))

‎package.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "ubon",
3-
"version": "1.1.2",
3+
"version": "1.1.3",
44
"description": "Security scanner for AI-generated React/Next.js and Python apps. Catches hardcoded secrets, accessibility issues, and vulnerabilities that traditional linters miss.",
55
"main": "dist/index.js",
66
"types": "dist/index.d.ts",

‎scripts/generate-rules-md.js‎

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,24 @@
22
const fs = require('fs');
33
const path = require('path');
44

5-
// Require compiled RULES from dist; ensure build before running
6-
const rulesPath = path.join(__dirname, '..', 'dist', 'types', 'rules.js');
7-
if (!fs.existsSync(rulesPath)) {
8-
console.error('dist/types/rules.js not found. Run `npm run build` first.');
5+
// Try modular rules first, fallback to legacy
6+
let RULES = {};
7+
8+
const modularRulesPath = path.join(__dirname, '..', 'dist', 'rules', 'index.js');
9+
const legacyRulesPath = path.join(__dirname, '..', 'dist', 'types', 'rules.js');
10+
11+
if (fs.existsSync(modularRulesPath)) {
12+
console.log('Using modular rules system');
13+
const { RULES: modularRules } = require(modularRulesPath);
14+
RULES = modularRules;
15+
} else if (fs.existsSync(legacyRulesPath)) {
16+
console.log('Using legacy rules system');
17+
const { RULES: legacyRules } = require(legacyRulesPath);
18+
RULES = legacyRules;
19+
} else {
20+
console.error('No rules found. Run `npm run build` first.');
921
process.exit(1);
1022
}
11-
const { RULES } = require(rulesPath);
1223

1324
function section(title) {
1425
return `\n### ${title}\n`;

‎src/cli.ts‎

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ program
130130
.option('--no-cache', 'Disable OSV caching for this scan')
131131
.option('--ai-friendly', 'Optimize output for AI consumption (json + context + explain + grouping + cap)')
132132
.option('--pr-comment', 'Output a Markdown summary suitable for PR comments')
133+
.option('--interactive', 'Walk through issues interactively with explanations and fix options')
133134
.action(async (options) => {
134135
const scanner = new UbonScan(options.verbose, options.json, options.color as 'auto' | 'always' | 'never');
135136

@@ -169,7 +170,8 @@ program
169170
showSuppressed: !!options.showSuppressed,
170171
ignoreSuppressed: !!options.ignoreSuppressed,
171172
clearCache: !!options.clearCache,
172-
noCache: !!options.noCache
173+
noCache: !!options.noCache,
174+
interactive: !!options.interactive
173175
};
174176
const scanOptions = mergeOptions(config, cliOptions);
175177

@@ -220,7 +222,7 @@ program
220222
}
221223
} else {
222224
// Human-readable output
223-
scanner.printResults(results, scanOptions);
225+
await scanner.printResults(results, scanOptions);
224226
}
225227

226228
if (options.sarif) {
@@ -345,6 +347,7 @@ program
345347
.option('--clear-cache', 'Clear OSV vulnerability cache before scanning')
346348
.option('--no-cache', 'Disable OSV caching for this scan')
347349
.option('--pr-comment', 'Output a Markdown summary suitable for PR comments')
350+
.option('--interactive', 'Walk through issues interactively with explanations and fix options')
348351
.action(async (options) => {
349352
const scanner = new UbonScan(options.verbose, options.json, options.color as 'auto' | 'always' | 'never');
350353

@@ -383,7 +386,8 @@ program
383386
showSuppressed: !!options.showSuppressed,
384387
ignoreSuppressed: !!options.ignoreSuppressed,
385388
clearCache: !!options.clearCache,
386-
noCache: !!options.noCache
389+
noCache: !!options.noCache,
390+
interactive: !!options.interactive
387391
};
388392
const scanOptions = mergeOptions(config, cliOptions);
389393

@@ -418,7 +422,7 @@ program
418422
}
419423
} else {
420424
// Human-readable output
421-
scanner.printResults(results, scanOptions);
425+
await scanner.printResults(results, scanOptions);
422426
}
423427
if (options.sarif) {
424428
const sarif = toSarif(results, options.directory);

0 commit comments

Comments
 (0)