Add create-next-shadcn command to automate Next.js app scaffolding with AIDD#71
Add create-next-shadcn command to automate Next.js app scaffolding with AIDD#71
create-next-shadcn command to automate Next.js app scaffolding with AIDD#71Conversation
Co-authored-by: ericelliott <364727+ericelliott@users.noreply.github.com>
Co-authored-by: ericelliott <364727+ericelliott@users.noreply.github.com>
create-next-shadcn command to scaffold Next.js + shadcn apps via Claude CLI
|
@copilot Let's come up with a plan to start the CLI command with all the stuff we can do without invoking an LLM - automate installation of everything using the CLI tools like |
Great idea! I'll refactor to:
This separates the "can be automated" from the "needs LLM creativity" work. I'll start by extracting the automatable steps from the setup guide. |
Co-authored-by: ericelliott <364727+ericelliott@users.noreply.github.com>
Co-authored-by: ericelliott <364727+ericelliott@users.noreply.github.com>
create-next-shadcn command to scaffold Next.js + shadcn apps via Claude CLIcreate-next-shadcn command to automate Next.js app scaffolding with AIDD
|
@copilot please merge in main and resolve conflicts |
Co-authored-by: ericelliott <364727+ericelliott@users.noreply.github.com>
Done! Merged main into the branch and resolved the conflict in Changes merged:
Commit: 691abb8 |
|
@cursoragent please /review in depth - changes in this PR, only. Watch for:
|
|
Now let me compile my comprehensive review findings. 🔬 Code Review: create-next-shadcn PR🎯 Review ScopeReviewing changes in this PR focused on:
🔴 Critical Issues1. Security: Command Injection Risk (A03:2021 - Injection)const runCommand = (command, args = [], cwd = process.cwd()) =>
new Promise((resolve, reject) => {
const child = spawn(command, args, {
cwd,
shell: true,
stdio: "inherit",
});
child.on("close", (code) => {
if (code === 0) {
resolve({ success: true });
} else {
reject(new Error(`Command failed with exit code ${code}`));
}
});
child.on("error", (error) => {
reject(error);
});
});Issue: Attack Vector: If npx aidd create-next-shadcn "myapp; rm -rf /"Fix: Remove const child = spawn(command, args, {
cwd,
// Remove shell: true
stdio: "inherit",
});2. Security: Missing Input Validation (A01:2021 - Broken Access Control)export const executeCreateNextShadcn = async (projectName = "my-app") => {
const projectPath = path.resolve(process.cwd(), projectName);Issue: No validation on Attack Vectors:
Fix: Add validation: const validateProjectName = (name) => {
// Reject path traversal attempts
if (name.includes('..') || name.includes('/') || name.includes('\\')) {
throw createError({
name: 'ValidationError',
message: 'Project name must not contain path separators or parent references',
code: 'INVALID_PROJECT_NAME'
});
}
// Reject special shell characters
if (/[;&|`$<>(){}]/.test(name)) {
throw createError({
name: 'ValidationError',
message: 'Project name contains invalid characters',
code: 'INVALID_PROJECT_NAME'
});
}
return name;
};🟡 Code Quality Issues3. Inconsistent Error Handling Patternexport const executeCreateNextShadcn = async (projectName = "my-app") => {
// ... implementation
try {
// ... operations
} catch (error) {
return {
error: `Setup failed: ${error.message}`,
success: false,
};
}
};Issue: Not using Impact:
Comparison - const [cliErrors, handleCliErrors] = errorCauses({
CloneError: {
code: "CLONE_ERROR",
message: "AI folder cloning failed",
},
FileSystemError: {
code: "FILESYSTEM_ERROR",
message: "File system operation failed",
},
ValidationError: {
code: "VALIDATION_ERROR",
message: "Input validation failed",
},
});Fix: Import and use import { createError, errorCauses } from "error-causes";
const [setupErrors, handleSetupErrors] = errorCauses({
ValidationError: {
code: "VALIDATION_ERROR",
message: "Invalid project name"
},
SetupError: {
code: "SETUP_ERROR",
message: "Project setup failed"
},
CommandError: {
code: "COMMAND_ERROR",
message: "External command failed"
}
});4. Violation: Single Responsibility PrincipleThe
JavaScript Style Guide Violation: "One job per function; separate mapping from IO" Fix: Break into composable functions: const createNextApp = (projectName, projectPath) =>
runCommand("npx", [/*...args*/], projectPath);
const installAidd = (projectPath) =>
runCommand("npx", ["aidd", "--cursor"], projectPath);
const installTestDependencies = (projectPath) =>
runCommand("npm", ["install", "-D", "vitest", /*...*/], projectPath);
const configurePackageJson = async (projectPath) => {
const packageJsonPath = path.join(projectPath, "package.json");
const packageJson = await fs.readJson(packageJsonPath);
// ... configuration
await fs.writeJson(packageJsonPath, packageJson, { spaces: 2 });
};
const createBaselineTests = (projectPath) => { /*...*/ };
const createPlaywrightConfig = (projectPath) => { /*...*/ };
// Compose with asyncPipe
export const executeCreateNextShadcn = asyncPipe(
validateInput,
createNextApp,
installAidd,
installTestDependencies,
installStorybook,
configurePackageJson,
createBaselineTests,
createPlaywrightConfig,
displaySuccessMessage
);5. Duplication: Hardcoded Configuration StringsMultiple configuration strings are embedded directly in the function: packageJson.scripts = {
...packageJson.scripts,
test: "vitest run && npm run -s lint && npm run -s typecheck",
"test:e2e": "playwright test",
"test:ui": "vitest --ui",
"test:watch": "vitest",
typecheck: "tsc --noEmit",
};const testContent = `import { assert } from "riteway";
import { describe, test } from "vitest";
describe("Home page", () => {
test("baseline test", () => {
assert({
given: "a baseline test",
should: "pass",
actual: true,
expected: true,
});
});
});
`;Issue: Configuration and templates are scattered throughout the code, making them hard to maintain. JavaScript Style Guide Violation: "Keep related code together; group by feature" Fix: Extract to template constants: const PACKAGE_SCRIPTS = {
test: "vitest run && npm run -s lint && npm run -s typecheck",
"test:e2e": "playwright test",
"test:ui": "vitest --ui",
"test:watch": "vitest",
typecheck: "tsc --noEmit",
};
const BASELINE_TEST_TEMPLATE = `import { assert } from "riteway";
import { describe, test } from "vitest";
describe("Home page", () => {
test("baseline test", () => {
assert({
given: "a baseline test",
should: "pass",
actual: true,
expected: true,
});
});
});
`;
const PLAYWRIGHT_CONFIG_TEMPLATE = (/*params*/) => `...`;
const E2E_TEST_TEMPLATE = `...`;6. Missing JSDoc on Helper Functionconst runCommand = (command, args = [], cwd = process.cwd()) =>
new Promise((resolve, reject) => {
// ... implementation
});Issue: No JSDoc comment on JavaScript Style Guide: "Favor docblocks for public APIs - but keep them minimal" While this is a private helper, it's complex enough to warrant documentation: /**
* Execute a command and stream output to console
* @param {string} command - Command to execute
* @param {string[]} args - Command arguments
* @param {string} cwd - Working directory
* @returns {Promise<{success: boolean}>}
*/
const runCommand = (command, args = [], cwd = process.cwd()) => /*...*/;🔵 Test Coverage Issues7. Incomplete Test Coveragetest("should run create-next-app with correct flags", async () => {
// ... test implementation
});
test("should install aidd framework", async () => {
// ... test implementation
});
test("should install test dependencies", async () => {
// ... test implementation
});Missing Tests:
TDD Guide Violation: "Thorough - Test expected/very likely edge cases" Required Tests: test("should reject path traversal attempts", async () => {
const result = await executeCreateNextShadcn("../../../etc/passwd");
assert({
given: "path traversal attempt",
should: "fail with validation error",
actual: result.success,
expected: false,
});
});
test("should reject special shell characters", async () => {
const result = await executeCreateNextShadcn("app; rm -rf /");
assert({
given: "shell injection attempt",
should: "fail with validation error",
actual: result.success,
expected: false,
});
});
test("should handle command failures", async () => {
// Mock spawn to return non-zero exit code
// Verify error handling
});🟢 Positive ObservationsWhat's Done Well
📊 OWASP Top 10 ReviewA01:2021 - Broken Access Control🔴 FAIL: Missing input validation allows path traversal A02:2021 - Cryptographic Failures✅ PASS: No cryptographic operations in this code A03:2021 - Injection🔴 FAIL: Command injection via A04:2021 - Insecure Design🟡 WARNING: Large procedural function instead of composable security boundaries A05:2021 - Security Misconfiguration✅ PASS: No security configurations present A06:2021 - Vulnerable and Outdated Components✅ PASS: Uses latest versions of dependencies A07:2021 - Identification and Authentication Failures✅ PASS: No authentication in this code A08:2021 - Software and Data Integrity Failures✅ PASS: Uses A09:2021 - Security Logging and Monitoring Failures✅ PASS: Adequate console logging for user feedback A10:2021 - Server-Side Request Forgery (SSRF)✅ PASS: No HTTP requests in this code OWASP Score: 2 Critical Failures 📋 Summary of RecommendationsCritical (Fix Before Merge)
High Priority (Should Fix)
Medium Priority (Nice to Have)
🎬 ConclusionThe PR successfully implements Phase 1 automation for Next.js scaffolding, but has 2 critical security vulnerabilities that must be addressed before merge:
The code also exhibits quality issues (large function, inconsistent error handling) that should be refactored to align with the project's JavaScript style guide and functional programming principles. Recommendation: Request changes for security fixes, then approve after verification. |
|
Closing in favor of generic extension architecture |


Description
Adds
npx aidd create-next-shadcn [project-name]command that automates Phase 1 setup of a Next.js application with AIDD framework, tests, and tooling. Based on feedback, the command now performs deterministic automation instead of delegating to Claude CLI, making it LLM-agnostic and more reliable.Branch is now up to date with main - merged latest changes including Biome linter, vision.md, and enhanced documentation.
Changes
New command implementation (
lib/create-next-shadcn.js)create-next-appnpx aidd --cursor && npm install aidd)CLI integration (
bin/aidd.js)handleCliErrorsexport fromcli-core.jsNew
/scaffoldcommand (ai/commands/scaffold.md)Tests
spawnandfs-extra(3 tests)Merged from main
Usage
Benefits
Original prompt
💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.