codebase-ai 0.1.1 → 0.1.2
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/commands/review.md +58 -2
- package/dist/index.js +1 -1
- package/package.json +1 -1
package/commands/review.md
CHANGED
|
@@ -67,7 +67,7 @@ Follow the complete `/vb-review` workflow across all phases:
|
|
|
67
67
|
|
|
68
68
|
- **Phase 0** — Scope (`--pr N` or full codebase)
|
|
69
69
|
- **Phase 1** — Security Review (OWASP top 10, CVEs, secrets, auth/authz)
|
|
70
|
-
- **Phase 2** — Quality Review (CLAUDE.md conventions, dead code, lint, complexity)
|
|
70
|
+
- **Phase 2** — Quality Review (CLAUDE.md conventions, dead code, lint, complexity, defensive programming, minimal code)
|
|
71
71
|
- **Phase 3** — Dependency Health (outdated, vulnerable, alternatives)
|
|
72
72
|
- **Phase 4** — UI/Accessibility (contrast, ARIA, keyboard, responsive)
|
|
73
73
|
- **Phase 5** — Consolidate & prioritize
|
|
@@ -147,4 +147,60 @@ Auto-fix: [yes | no]
|
|
|
147
147
|
════════════════════════════════════════════════════════
|
|
148
148
|
```
|
|
149
149
|
|
|
150
|
-
All other behavior (security agent prompts,
|
|
150
|
+
All other behavior (security agent prompts, CVE research, accessibility checks, test generation) follows the `/vb-review` specification exactly.
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
## Phase 2 — Quality Review (Extended Rules)
|
|
155
|
+
|
|
156
|
+
The quality agent must check the following **in addition** to the base `/vb-review` quality rules.
|
|
157
|
+
|
|
158
|
+
### Defensive Programming
|
|
159
|
+
|
|
160
|
+
Check every function, method, and handler for:
|
|
161
|
+
|
|
162
|
+
- **Missing guard clauses** — function body has deep nesting where an early return/throw would flatten it. Flag any function with 3+ levels of nesting that could use guard clauses.
|
|
163
|
+
- **Missing input validation at boundaries** — functions that accept external input (API params, user input, env vars, CLI args, file reads) without validating type, range, or presence before use.
|
|
164
|
+
- **Unchecked null/undefined** — property access on values that could be null/undefined without a prior check (e.g. `user.name` where `user` could be null).
|
|
165
|
+
- **Silent failures** — empty `catch` blocks, `.catch(() => {})`, swallowed errors with no logging or rethrow. Every error boundary must either handle, log, or rethrow.
|
|
166
|
+
- **Missing error handling at I/O boundaries** — file reads, network calls, subprocess exec, DB queries with no error handling.
|
|
167
|
+
- **Optimistic assumptions** — code that assumes an array is non-empty before indexing, assumes a map key exists before accessing, or assumes an async call always resolves.
|
|
168
|
+
- **No fail-fast** — configuration or required env vars read lazily (mid-request) instead of validated at startup, so failures surface late and with poor context.
|
|
169
|
+
|
|
170
|
+
Severity guide:
|
|
171
|
+
- `high` — missing validation on external input, unchecked null on a hot path, silent catch hiding errors
|
|
172
|
+
- `medium` — deep nesting fixable with guard clauses, missing fail-fast for config
|
|
173
|
+
- `low` — optimistic array/map access in low-risk paths
|
|
174
|
+
|
|
175
|
+
### Minimal Code
|
|
176
|
+
|
|
177
|
+
Check for over-engineering and unnecessary complexity:
|
|
178
|
+
|
|
179
|
+
- **YAGNI violations** — abstractions, interfaces, config options, or generics added for hypothetical future use that have exactly one concrete caller/case today.
|
|
180
|
+
- **Premature abstraction** — a helper/utility/class created for code used in only one place. Three similar lines of code is better than a one-use abstraction.
|
|
181
|
+
- **Over-parameterization** — functions with options objects or boolean flags that only ever receive the same values. Flags that were never flipped from their default since they were added.
|
|
182
|
+
- **Unnecessary indirection** — wrapper functions that do nothing but call another function with the same signature.
|
|
183
|
+
- **Dead feature flags** — flags/toggles that are always `true` or always `false` in all environments; can just be removed.
|
|
184
|
+
- **Backwards-compatibility shims for internal code** — deprecated aliases, re-exports, or `_unused` renames for code that has no external consumers.
|
|
185
|
+
- **Excessive comments explaining obvious code** — comments that restate what the code already says clearly (e.g. `// increment counter` above `count++`). Flag only; do not auto-fix.
|
|
186
|
+
- **Over-engineered error messages** — error classes with elaborate hierarchies for a project that throws 2-3 distinct error types.
|
|
187
|
+
|
|
188
|
+
Severity guide:
|
|
189
|
+
- `medium` — YAGNI abstractions, over-parameterization, unnecessary indirection
|
|
190
|
+
- `low` — dead flags, excessive comments, minor shims
|
|
191
|
+
|
|
192
|
+
### Code Simplicity Principles
|
|
193
|
+
|
|
194
|
+
- **Flat over nested** — prefer early returns, guard clauses, and linear flow over pyramid/callback-hell structures.
|
|
195
|
+
- **Explicit over clever** — flag code that uses obscure language tricks, complex one-liners, or metaprogramming where a simple loop/condition would be clearer.
|
|
196
|
+
- **Consistent patterns** — same operation done differently in 2+ places (e.g. one place uses `?.` optional chaining, another uses explicit null check for the same pattern). Flag the inconsistency; suggest unifying to the simpler form.
|
|
197
|
+
- **Functions do one thing** — flag functions that mix concerns (e.g. validate + transform + persist in one function body >30 lines with no clear single responsibility).
|
|
198
|
+
|
|
199
|
+
Severity guide:
|
|
200
|
+
- `medium` — mixed concerns in large functions, inconsistent patterns across the codebase
|
|
201
|
+
- `low` — clever one-liners, minor style inconsistencies
|
|
202
|
+
|
|
203
|
+
### Auto-fixable vs Architectural
|
|
204
|
+
|
|
205
|
+
- **Auto-fixable (`--fix`)**: guard clause refactors (simple cases), removing empty catch blocks (replace with `// TODO: handle error`), removing dead flags set to constant values, removing unused re-exports.
|
|
206
|
+
- **Architectural (create issue, no auto-fix)**: adding input validation that requires schema/type decisions, restructuring mixed-concern functions, replacing premature abstractions (requires understanding callers).
|
package/dist/index.js
CHANGED
|
@@ -517,7 +517,7 @@ ${v("SEE ALSO")}
|
|
|
517
517
|
`:""}${v("MORE HELP")}
|
|
518
518
|
${k("codebase --help")} Show all commands
|
|
519
519
|
${_e("https://github.com/your-repo/codebase/docs","Full documentation")}
|
|
520
|
-
`)}var sa={E_NO_GIT:{message:"Not a git repository",suggestion:"Initialize git first: "+k("git init")},E_NO_PACKAGE_JSON:{message:"No package.json found",suggestion:"Initialize project: "+k("npm init")+" or "+k("pnpm init")},E_GH_NOT_AUTHENTICATED:{message:"GitHub CLI not authenticated",suggestion:"Run: "+k("gh auth login")},E_MANIFEST_NOT_FOUND:{message:".codebase.json not found",suggestion:"Run: "+k("codebase init")+" to generate it"},E_INVALID_PATH:{message:"Invalid directory path",suggestion:"Use absolute path or path relative to current directory"},E_PERMISSION_DENIED:{message:"Permission denied",suggestion:"Check file permissions or run with appropriate access"}};var rn={command:"scan",subcommand:"",positionals:[],path:process.cwd(),format:"text",depth:4,categories:[],incremental:!1,quiet:!1,raw:!1,verbose:!1,port:7432,tools:[],dryRun:!1,since:"",sync:!1,message:"",reason:"",examples:!1,helpCommand:!1},xt=new Set(["scan","setup","query","mcp","issue","status","init","scan-only","brief","next","doctor","fix","release"]);function $t(e){let t={...rn},s=[];for(let n=0;n<e.length;n++){let i=e[n];if(!i.startsWith("-")&&xt.has(i)){if(t.command=i,e[n+1]==="--help"||e[n+1]==="-h")return t.helpCommand=!0,t;break}}for(let n=0;n<e.length;n++){let i=e[n];if((i==="--help"||i==="-h")&&!t.command&&(vt(),process.exit(0)),(i==="--version"||i==="-v")&&(console.log("codebase 0.1.
|
|
520
|
+
`)}var sa={E_NO_GIT:{message:"Not a git repository",suggestion:"Initialize git first: "+k("git init")},E_NO_PACKAGE_JSON:{message:"No package.json found",suggestion:"Initialize project: "+k("npm init")+" or "+k("pnpm init")},E_GH_NOT_AUTHENTICATED:{message:"GitHub CLI not authenticated",suggestion:"Run: "+k("gh auth login")},E_MANIFEST_NOT_FOUND:{message:".codebase.json not found",suggestion:"Run: "+k("codebase init")+" to generate it"},E_INVALID_PATH:{message:"Invalid directory path",suggestion:"Use absolute path or path relative to current directory"},E_PERMISSION_DENIED:{message:"Permission denied",suggestion:"Check file permissions or run with appropriate access"}};var rn={command:"scan",subcommand:"",positionals:[],path:process.cwd(),format:"text",depth:4,categories:[],incremental:!1,quiet:!1,raw:!1,verbose:!1,port:7432,tools:[],dryRun:!1,since:"",sync:!1,message:"",reason:"",examples:!1,helpCommand:!1},xt=new Set(["scan","setup","query","mcp","issue","status","init","scan-only","brief","next","doctor","fix","release"]);function $t(e){let t={...rn},s=[];for(let n=0;n<e.length;n++){let i=e[n];if(!i.startsWith("-")&&xt.has(i)){if(t.command=i,e[n+1]==="--help"||e[n+1]==="-h")return t.helpCommand=!0,t;break}}for(let n=0;n<e.length;n++){let i=e[n];if((i==="--help"||i==="-h")&&!t.command&&(vt(),process.exit(0)),(i==="--version"||i==="-v")&&(console.log("codebase 0.1.2"),process.exit(0)),i.startsWith("--")){let o=i.slice(2);if(o==="quiet"||o==="q"){t.quiet=!0;continue}if(o==="raw"){t.raw=!0;continue}if(o==="verbose"||o==="V"){t.verbose=!0;continue}if(o==="incremental"){t.incremental=!0;continue}if(o==="dry-run"){t.dryRun=!0;continue}if(o==="sync"){t.sync=!0;continue}if(o==="examples"){t.examples=!0;continue}if(o==="mine"){s.push("mine");continue}let r=e[n+1];if(!r||r.startsWith("--"))continue;n++,o==="path"?t.path=r:o==="format"?t.format=r:o==="depth"?t.depth=parseInt(r,10)||4:o==="categories"?t.categories=r.split(",").map(a=>a.trim()):o==="port"?t.port=parseInt(r,10)||7432:o==="tools"?t.tools=r.split(",").map(a=>a.trim()):o==="since"?t.since=r:o==="message"||o==="m"?t.message=r:o==="reason"&&(t.reason=r);continue}s.push(i)}if(s.length>0&&xt.has(s[0])&&(t.command=s.shift()),s.length>0){let n=s[0];["install","uninstall","create","close","comment","list","map"].includes(n)&&(t.subcommand=s.shift())}return t.positionals=s,s.length>0&&/^[\/\.~]/.test(s[0])&&(t.path=s[0]),process.env.CODEBASE_OUTPUT&&(t.path=process.env.CODEBASE_OUTPUT),process.env.CODEBASE_PORT&&(t.port=parseInt(process.env.CODEBASE_PORT,10)||7432),process.env.CODEBASE_DEPTH&&(t.depth=parseInt(process.env.CODEBASE_DEPTH,10)||4),process.env.CODEBASE_QUIET==="true"&&(t.quiet=!0),t}function Ct(e){jt(e),process.exit(0)}I();it();Ue();he();import{resolve as qo,join as Je}from"path";import{existsSync as Ds,writeFileSync as Os,readFileSync as Mo}from"fs";import{execFile as Ps}from"child_process";import{writeFile as Lo}from"fs/promises";import{homedir as To}from"os";ye();var Fo=[V];function _s(e){return Fo.filter(t=>t.detect(e))}ye();Te();He();I();async function pt(e){U(e.quiet);let t=qo(e.path);j(`codebase \u2014 activating project intelligence
|
|
521
521
|
`);let s=await ve();s==="authenticated"?h("GitHub CLI \u2014 authenticated"):s==="not-authenticated"?(S("GitHub CLI installed but not logged in"),y("Run: gh auth login"),y("After login, re-run `npx codebase` for full GitHub integration\n")):(y("GitHub CLI not found \u2014 GitHub features disabled"),y(`To enable: brew install gh && gh auth login
|
|
522
522
|
`));let n=s==="authenticated";l(`Scanning ${t}...`);let i=await z(t,{depth:e.depth,categories:e.categories.length?e.categories:void 0,quiet:e.quiet,sync:n});for(let[d,m]of Object.entries(i))d==="version"||d==="generated_at"||typeof m!="object"||m===null||h(`${Ho(d)} (${qe(d,m)})`);let o=Je(t,".codebase.json"),r=JSON.stringify(i,null,2);await Lo(o,r,"utf-8");let a=(Buffer.byteLength(r)/1024).toFixed(1);l(`
|
|
523
523
|
Written: .codebase.json (${a} KB)`),j("AI Tool Integration");let c=_s(t),u=Go(),g=new Set(c.map(d=>d.name));for(let d of u)g.has(d.name)||(c.push(d),g.add(d.name));c.length===0?(y("No AI tool detected in project or system configs"),y("Creating CLAUDE.md as default (works with Claude Code, and readable by all tools)"),Os(Je(t,"CLAUDE.md"),`# Project Rules
|