lynxprompt 0.3.1 → 0.4.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/dist/index.js +1636 -156
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -200,12 +200,7 @@ async function loginCommand() {
|
|
|
200
200
|
pollSpinner.succeed("Authentication successful!");
|
|
201
201
|
setToken(result.token);
|
|
202
202
|
setUser(result.user);
|
|
203
|
-
|
|
204
|
-
console.log(chalk.green(`\u2705 Logged in as ${chalk.bold(result.user.email)}`));
|
|
205
|
-
console.log(chalk.gray(` Plan: ${result.user.plan}`));
|
|
206
|
-
console.log(chalk.gray(` Token stored securely in config`));
|
|
207
|
-
console.log();
|
|
208
|
-
console.log(chalk.cyan("You're ready to use LynxPrompt CLI!"));
|
|
203
|
+
displayWelcome(result.user);
|
|
209
204
|
return;
|
|
210
205
|
}
|
|
211
206
|
if (result.status === "expired") {
|
|
@@ -259,6 +254,56 @@ async function tryOpenBrowser(url) {
|
|
|
259
254
|
function sleep(ms) {
|
|
260
255
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
261
256
|
}
|
|
257
|
+
function displayWelcome(user) {
|
|
258
|
+
const plan = user.plan?.toUpperCase() || "FREE";
|
|
259
|
+
const name = user.name || user.email.split("@")[0];
|
|
260
|
+
const planConfig = {
|
|
261
|
+
FREE: { color: chalk.gray, emoji: "\u{1F193}", badge: "Free" },
|
|
262
|
+
PRO: { color: chalk.cyan, emoji: "\u26A1", badge: "Pro" },
|
|
263
|
+
MAX: { color: chalk.magenta, emoji: "\u{1F680}", badge: "Max" },
|
|
264
|
+
TEAMS: { color: chalk.yellow, emoji: "\u{1F465}", badge: "Teams" }
|
|
265
|
+
};
|
|
266
|
+
const config2 = planConfig[plan] || planConfig.FREE;
|
|
267
|
+
const W = 45;
|
|
268
|
+
const b = chalk.bold;
|
|
269
|
+
const pad = (s, len) => s + " ".repeat(Math.max(0, len - s.length));
|
|
270
|
+
console.log();
|
|
271
|
+
console.log(b("\u250C" + "\u2500".repeat(W) + "\u2510"));
|
|
272
|
+
console.log(b("\u2502") + " ".repeat(W) + b("\u2502"));
|
|
273
|
+
console.log(b("\u2502") + pad(` ${config2.emoji} Welcome to LynxPrompt CLI!`, W - 1) + b("\u2502"));
|
|
274
|
+
console.log(b("\u2502") + " ".repeat(W) + b("\u2502"));
|
|
275
|
+
console.log(b("\u2502") + pad(` User: ${name}`, W) + b("\u2502"));
|
|
276
|
+
console.log(b("\u2502") + pad(` Plan: ${config2.badge}`, W) + b("\u2502"));
|
|
277
|
+
console.log(b("\u2502") + " ".repeat(W) + b("\u2502"));
|
|
278
|
+
console.log(b("\u2514" + "\u2500".repeat(W) + "\u2518"));
|
|
279
|
+
console.log();
|
|
280
|
+
console.log(chalk.bold("\u{1F4CB} Your CLI Capabilities:"));
|
|
281
|
+
console.log();
|
|
282
|
+
console.log(chalk.green(" \u2713") + " " + chalk.white("lynxprompt init") + chalk.gray(" - Generate config files"));
|
|
283
|
+
console.log(chalk.green(" \u2713") + " " + chalk.white("lynxprompt wizard") + chalk.gray(" - Interactive wizard"));
|
|
284
|
+
console.log(chalk.green(" \u2713") + " " + chalk.white("lynxprompt list") + chalk.gray(" - List your blueprints"));
|
|
285
|
+
console.log(chalk.green(" \u2713") + " " + chalk.white("lynxprompt pull <id>") + chalk.gray(" - Download blueprints"));
|
|
286
|
+
console.log(chalk.green(" \u2713") + " " + chalk.white("lynxprompt push") + chalk.gray(" - Upload blueprints to marketplace"));
|
|
287
|
+
console.log(chalk.green(" \u2713") + " " + chalk.white("lynxprompt link") + chalk.gray(" - Link project to blueprint"));
|
|
288
|
+
console.log(chalk.green(" \u2713") + " " + chalk.white("lynxprompt sync") + chalk.gray(" - Sync linked blueprints"));
|
|
289
|
+
console.log(chalk.green(" \u2713") + " " + chalk.white("lynxprompt diff") + chalk.gray(" - Compare local vs remote"));
|
|
290
|
+
if (plan === "PRO" || plan === "MAX" || plan === "TEAMS") {
|
|
291
|
+
console.log();
|
|
292
|
+
console.log(chalk.cyan(" \u26A1") + " " + chalk.white("Advanced wizards") + chalk.gray(" - More customization options"));
|
|
293
|
+
console.log(chalk.cyan(" \u26A1") + " " + chalk.white("Sell blueprints") + chalk.gray(" - Monetize your configurations"));
|
|
294
|
+
}
|
|
295
|
+
if (plan === "MAX" || plan === "TEAMS") {
|
|
296
|
+
console.log(chalk.magenta(" \u{1F680}") + " " + chalk.white("All paid blueprints") + chalk.gray(" - Access premium content"));
|
|
297
|
+
console.log(chalk.magenta(" \u{1F680}") + " " + chalk.white("Priority support") + chalk.gray(" - Get help faster"));
|
|
298
|
+
}
|
|
299
|
+
if (plan === "TEAMS") {
|
|
300
|
+
console.log(chalk.yellow(" \u{1F465}") + " " + chalk.white("Team blueprints") + chalk.gray(" - Share with your team"));
|
|
301
|
+
console.log(chalk.yellow(" \u{1F465}") + " " + chalk.white("SSO integration") + chalk.gray(" - Enterprise authentication"));
|
|
302
|
+
}
|
|
303
|
+
console.log();
|
|
304
|
+
console.log(chalk.gray("Token stored securely. Run ") + chalk.cyan("lynxprompt --help") + chalk.gray(" to see all commands."));
|
|
305
|
+
console.log();
|
|
306
|
+
}
|
|
262
307
|
|
|
263
308
|
// src/commands/logout.ts
|
|
264
309
|
import chalk2 from "chalk";
|
|
@@ -1974,7 +2019,17 @@ var PLATFORM_FILES = {
|
|
|
1974
2019
|
claude: "CLAUDE.md",
|
|
1975
2020
|
copilot: ".github/copilot-instructions.md",
|
|
1976
2021
|
windsurf: ".windsurfrules",
|
|
1977
|
-
zed: ".zed/instructions.md"
|
|
2022
|
+
zed: ".zed/instructions.md",
|
|
2023
|
+
aider: ".aider.conf.yml",
|
|
2024
|
+
cline: ".clinerules",
|
|
2025
|
+
continue: ".continue/rules.md",
|
|
2026
|
+
cody: ".cody/rules.md",
|
|
2027
|
+
amazonq: ".amazonq/rules/project.md",
|
|
2028
|
+
tabnine: ".tabnine.yaml",
|
|
2029
|
+
supermaven: ".supermaven/rules.md",
|
|
2030
|
+
codegpt: ".codegpt/rules.md",
|
|
2031
|
+
void: ".void/rules.md",
|
|
2032
|
+
goose: ".goosehints"
|
|
1978
2033
|
};
|
|
1979
2034
|
var PERSONA_DESCRIPTIONS = {
|
|
1980
2035
|
backend: "a senior backend developer specializing in APIs, databases, and microservices architecture",
|
|
@@ -1995,6 +2050,8 @@ var STACK_NAMES = {
|
|
|
1995
2050
|
ruby: "Ruby",
|
|
1996
2051
|
php: "PHP",
|
|
1997
2052
|
swift: "Swift",
|
|
2053
|
+
kotlin: "Kotlin",
|
|
2054
|
+
cpp: "C/C++",
|
|
1998
2055
|
react: "React",
|
|
1999
2056
|
nextjs: "Next.js",
|
|
2000
2057
|
vue: "Vue.js",
|
|
@@ -2007,10 +2064,44 @@ var STACK_NAMES = {
|
|
|
2007
2064
|
spring: "Spring Boot",
|
|
2008
2065
|
rails: "Ruby on Rails",
|
|
2009
2066
|
laravel: "Laravel",
|
|
2067
|
+
nestjs: "NestJS",
|
|
2068
|
+
vite: "Vite",
|
|
2069
|
+
"react-native": "React Native",
|
|
2070
|
+
postgresql: "PostgreSQL",
|
|
2071
|
+
mysql: "MySQL",
|
|
2072
|
+
mongodb: "MongoDB",
|
|
2073
|
+
redis: "Redis",
|
|
2074
|
+
sqlite: "SQLite",
|
|
2075
|
+
supabase: "Supabase",
|
|
2076
|
+
firebase: "Firebase",
|
|
2010
2077
|
prisma: "Prisma",
|
|
2011
2078
|
tailwind: "Tailwind CSS",
|
|
2012
2079
|
fastify: "Fastify"
|
|
2013
2080
|
};
|
|
2081
|
+
var NAMING_DESCRIPTIONS = {
|
|
2082
|
+
language_default: "follow idiomatic conventions for the primary language",
|
|
2083
|
+
camelCase: "use camelCase for variables and functions",
|
|
2084
|
+
snake_case: "use snake_case for variables and functions",
|
|
2085
|
+
PascalCase: "use PascalCase for classes and types",
|
|
2086
|
+
"kebab-case": "use kebab-case for file names and CSS classes"
|
|
2087
|
+
};
|
|
2088
|
+
var AI_BEHAVIOR_DESCRIPTIONS = {
|
|
2089
|
+
explain_changes: "Always explain what changes you're making and why before implementing them",
|
|
2090
|
+
preserve_style: "Preserve and follow the existing code style in the project",
|
|
2091
|
+
minimal_changes: "Make minimal, focused changes - avoid unnecessary refactoring",
|
|
2092
|
+
no_comments: "Avoid adding unnecessary comments; code should be self-documenting",
|
|
2093
|
+
prefer_simple: "Prefer simpler solutions over clever ones",
|
|
2094
|
+
test_first: "Write tests before implementing new functionality (TDD)",
|
|
2095
|
+
no_console: "Remove console.log/print statements before committing",
|
|
2096
|
+
type_strict: "Be strict with types - avoid any/Any/Object types"
|
|
2097
|
+
};
|
|
2098
|
+
var IMPORTANT_FILES_PATHS = {
|
|
2099
|
+
readme: "README.md",
|
|
2100
|
+
package: "package.json or pyproject.toml",
|
|
2101
|
+
tsconfig: "tsconfig.json or similar config",
|
|
2102
|
+
architecture: "ARCHITECTURE.md",
|
|
2103
|
+
contributing: "CONTRIBUTING.md"
|
|
2104
|
+
};
|
|
2014
2105
|
var BOUNDARIES = {
|
|
2015
2106
|
conservative: {
|
|
2016
2107
|
always: ["Read any file in the project", "Run lint and format commands"],
|
|
@@ -2069,6 +2160,265 @@ var BOUNDARIES = {
|
|
|
2069
2160
|
]
|
|
2070
2161
|
}
|
|
2071
2162
|
};
|
|
2163
|
+
var TEST_LEVEL_DESCRIPTIONS = {
|
|
2164
|
+
smoke: "Quick sanity checks for critical paths",
|
|
2165
|
+
unit: "Unit tests for individual functions and components",
|
|
2166
|
+
integration: "Integration tests for component interactions",
|
|
2167
|
+
e2e: "End-to-end tests for full user flows"
|
|
2168
|
+
};
|
|
2169
|
+
var STATIC_FILE_TEMPLATES = {
|
|
2170
|
+
editorconfig: () => `# EditorConfig is awesome: https://EditorConfig.org
|
|
2171
|
+
|
|
2172
|
+
root = true
|
|
2173
|
+
|
|
2174
|
+
[*]
|
|
2175
|
+
indent_style = space
|
|
2176
|
+
indent_size = 2
|
|
2177
|
+
end_of_line = lf
|
|
2178
|
+
charset = utf-8
|
|
2179
|
+
trim_trailing_whitespace = true
|
|
2180
|
+
insert_final_newline = true
|
|
2181
|
+
|
|
2182
|
+
[*.md]
|
|
2183
|
+
trim_trailing_whitespace = false
|
|
2184
|
+
|
|
2185
|
+
[Makefile]
|
|
2186
|
+
indent_style = tab
|
|
2187
|
+
`,
|
|
2188
|
+
contributing: (opts) => `# Contributing to ${opts.name}
|
|
2189
|
+
|
|
2190
|
+
Thank you for your interest in contributing!
|
|
2191
|
+
|
|
2192
|
+
## How to Contribute
|
|
2193
|
+
|
|
2194
|
+
1. Fork the repository
|
|
2195
|
+
2. Create a feature branch (\`git checkout -b feature/amazing-feature\`)
|
|
2196
|
+
3. Commit your changes${opts.conventionalCommits ? " using Conventional Commits format" : ""}
|
|
2197
|
+
4. Push to the branch (\`git push origin feature/amazing-feature\`)
|
|
2198
|
+
5. Open a Pull Request
|
|
2199
|
+
|
|
2200
|
+
## Development Setup
|
|
2201
|
+
|
|
2202
|
+
\`\`\`bash
|
|
2203
|
+
# Clone your fork
|
|
2204
|
+
git clone https://github.com/YOUR_USERNAME/${opts.name}.git
|
|
2205
|
+
cd ${opts.name}
|
|
2206
|
+
|
|
2207
|
+
# Install dependencies
|
|
2208
|
+
npm install
|
|
2209
|
+
|
|
2210
|
+
# Run development server
|
|
2211
|
+
npm run dev
|
|
2212
|
+
\`\`\`
|
|
2213
|
+
|
|
2214
|
+
## Code Style
|
|
2215
|
+
|
|
2216
|
+
Please follow the existing code style and conventions in this project.
|
|
2217
|
+
`,
|
|
2218
|
+
codeOfConduct: (opts) => `# Code of Conduct
|
|
2219
|
+
|
|
2220
|
+
## Our Pledge
|
|
2221
|
+
|
|
2222
|
+
We pledge to make participation in the ${opts.name} project a harassment-free experience for everyone.
|
|
2223
|
+
|
|
2224
|
+
## Our Standards
|
|
2225
|
+
|
|
2226
|
+
Examples of behavior that contributes to a positive environment:
|
|
2227
|
+
- Using welcoming and inclusive language
|
|
2228
|
+
- Being respectful of differing viewpoints
|
|
2229
|
+
- Gracefully accepting constructive criticism
|
|
2230
|
+
- Focusing on what is best for the community
|
|
2231
|
+
|
|
2232
|
+
## Enforcement
|
|
2233
|
+
|
|
2234
|
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the project team.
|
|
2235
|
+
|
|
2236
|
+
## Attribution
|
|
2237
|
+
|
|
2238
|
+
This Code of Conduct is adapted from the Contributor Covenant, version 2.1.
|
|
2239
|
+
`,
|
|
2240
|
+
security: (opts) => `# Security Policy
|
|
2241
|
+
|
|
2242
|
+
## Supported Versions
|
|
2243
|
+
|
|
2244
|
+
| Version | Supported |
|
|
2245
|
+
| ------- | ------------------ |
|
|
2246
|
+
| latest | :white_check_mark: |
|
|
2247
|
+
|
|
2248
|
+
## Reporting a Vulnerability
|
|
2249
|
+
|
|
2250
|
+
If you discover a security vulnerability in ${opts.name}, please report it by emailing the maintainers.
|
|
2251
|
+
|
|
2252
|
+
**Please do not open a public issue for security vulnerabilities.**
|
|
2253
|
+
|
|
2254
|
+
We will acknowledge receipt within 48 hours and provide a detailed response within 7 days.
|
|
2255
|
+
`,
|
|
2256
|
+
roadmap: (opts) => `# Roadmap
|
|
2257
|
+
|
|
2258
|
+
## ${opts.name} Development Roadmap
|
|
2259
|
+
|
|
2260
|
+
### Current Version
|
|
2261
|
+
|
|
2262
|
+
- Core functionality
|
|
2263
|
+
|
|
2264
|
+
### Planned Features
|
|
2265
|
+
|
|
2266
|
+
- [ ] Feature 1
|
|
2267
|
+
- [ ] Feature 2
|
|
2268
|
+
- [ ] Feature 3
|
|
2269
|
+
|
|
2270
|
+
### Long-term Goals
|
|
2271
|
+
|
|
2272
|
+
- Goal 1
|
|
2273
|
+
- Goal 2
|
|
2274
|
+
|
|
2275
|
+
---
|
|
2276
|
+
*This roadmap is subject to change based on community feedback and priorities.*
|
|
2277
|
+
`,
|
|
2278
|
+
gitignore: (opts) => {
|
|
2279
|
+
const patterns = ["# Dependencies", "node_modules/", ".pnpm-store/", ""];
|
|
2280
|
+
if (opts.stack.includes("python")) {
|
|
2281
|
+
patterns.push("# Python", "__pycache__/", "*.py[cod]", ".venv/", "venv/", "");
|
|
2282
|
+
}
|
|
2283
|
+
patterns.push("# Environment", ".env", ".env.local", ".env*.local", "");
|
|
2284
|
+
patterns.push("# Build outputs", "dist/", "build/", ".next/", "out/", "");
|
|
2285
|
+
patterns.push("# IDE", ".idea/", ".vscode/", "*.swp", "*.swo", "");
|
|
2286
|
+
patterns.push("# OS", ".DS_Store", "Thumbs.db", "");
|
|
2287
|
+
patterns.push("# Logs", "*.log", "npm-debug.log*", "");
|
|
2288
|
+
return patterns.join("\n");
|
|
2289
|
+
},
|
|
2290
|
+
funding: () => `# These are supported funding model platforms
|
|
2291
|
+
|
|
2292
|
+
github: [] # Replace with your GitHub username
|
|
2293
|
+
patreon: # Replace with your Patreon username
|
|
2294
|
+
open_collective: # Replace with your Open Collective username
|
|
2295
|
+
ko_fi: # Replace with your Ko-fi username
|
|
2296
|
+
custom: [] # Add custom funding links
|
|
2297
|
+
`,
|
|
2298
|
+
license: (opts) => {
|
|
2299
|
+
if (opts.license === "mit") {
|
|
2300
|
+
return `MIT License
|
|
2301
|
+
|
|
2302
|
+
Copyright (c) ${(/* @__PURE__ */ new Date()).getFullYear()} ${opts.name}
|
|
2303
|
+
|
|
2304
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
2305
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
2306
|
+
in the Software without restriction, including without limitation the rights
|
|
2307
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
2308
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
2309
|
+
furnished to do so, subject to the following conditions:
|
|
2310
|
+
|
|
2311
|
+
The above copyright notice and this permission notice shall be included in all
|
|
2312
|
+
copies or substantial portions of the Software.
|
|
2313
|
+
|
|
2314
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
2315
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
2316
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
2317
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
2318
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
2319
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
2320
|
+
SOFTWARE.
|
|
2321
|
+
`;
|
|
2322
|
+
}
|
|
2323
|
+
return `# License
|
|
2324
|
+
|
|
2325
|
+
This project is licensed under the ${opts.license?.toUpperCase() || "Proprietary"} license.
|
|
2326
|
+
`;
|
|
2327
|
+
},
|
|
2328
|
+
readme: (opts) => {
|
|
2329
|
+
const stackBadges = opts.stack.slice(0, 5).map((s) => STACK_NAMES[s] || s).join(" \u2022 ");
|
|
2330
|
+
return `# ${opts.name}
|
|
2331
|
+
|
|
2332
|
+
${opts.description || "A project generated with LynxPrompt."}
|
|
2333
|
+
|
|
2334
|
+
${stackBadges ? `## Tech Stack
|
|
2335
|
+
|
|
2336
|
+
${stackBadges}
|
|
2337
|
+
` : ""}
|
|
2338
|
+
## Getting Started
|
|
2339
|
+
|
|
2340
|
+
\`\`\`bash
|
|
2341
|
+
# Clone the repository
|
|
2342
|
+
git clone <repository-url>
|
|
2343
|
+
cd ${opts.name}
|
|
2344
|
+
|
|
2345
|
+
# Install dependencies
|
|
2346
|
+
npm install
|
|
2347
|
+
|
|
2348
|
+
# Run development server
|
|
2349
|
+
npm run dev
|
|
2350
|
+
\`\`\`
|
|
2351
|
+
|
|
2352
|
+
## License
|
|
2353
|
+
|
|
2354
|
+
${opts.license && opts.license !== "none" ? `This project is licensed under the ${opts.license.toUpperCase()} License.` : "See LICENSE file for details."}
|
|
2355
|
+
`;
|
|
2356
|
+
},
|
|
2357
|
+
architecture: (opts) => `# Architecture
|
|
2358
|
+
|
|
2359
|
+
## ${opts.name} Architecture Overview
|
|
2360
|
+
|
|
2361
|
+
${opts.architecture ? `### Pattern: ${opts.architecture}
|
|
2362
|
+
` : ""}
|
|
2363
|
+
### Directory Structure
|
|
2364
|
+
|
|
2365
|
+
\`\`\`
|
|
2366
|
+
${opts.name}/
|
|
2367
|
+
\u251C\u2500\u2500 src/ # Source code
|
|
2368
|
+
\u251C\u2500\u2500 tests/ # Test files
|
|
2369
|
+
\u251C\u2500\u2500 docs/ # Documentation
|
|
2370
|
+
\u2514\u2500\u2500 ...
|
|
2371
|
+
\`\`\`
|
|
2372
|
+
|
|
2373
|
+
### Key Components
|
|
2374
|
+
|
|
2375
|
+
1. **Component A** - Description
|
|
2376
|
+
2. **Component B** - Description
|
|
2377
|
+
3. **Component C** - Description
|
|
2378
|
+
|
|
2379
|
+
### Data Flow
|
|
2380
|
+
|
|
2381
|
+
Describe how data flows through the application.
|
|
2382
|
+
|
|
2383
|
+
---
|
|
2384
|
+
*Generated by LynxPrompt*
|
|
2385
|
+
`,
|
|
2386
|
+
changelog: (opts) => `# Changelog
|
|
2387
|
+
|
|
2388
|
+
All notable changes to ${opts.name} will be documented in this file.
|
|
2389
|
+
|
|
2390
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
2391
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
2392
|
+
|
|
2393
|
+
## [Unreleased]
|
|
2394
|
+
|
|
2395
|
+
### Added
|
|
2396
|
+
- Initial project setup
|
|
2397
|
+
|
|
2398
|
+
### Changed
|
|
2399
|
+
|
|
2400
|
+
### Deprecated
|
|
2401
|
+
|
|
2402
|
+
### Removed
|
|
2403
|
+
|
|
2404
|
+
### Fixed
|
|
2405
|
+
|
|
2406
|
+
### Security
|
|
2407
|
+
`
|
|
2408
|
+
};
|
|
2409
|
+
var STATIC_FILE_PATHS = {
|
|
2410
|
+
editorconfig: ".editorconfig",
|
|
2411
|
+
contributing: "CONTRIBUTING.md",
|
|
2412
|
+
codeOfConduct: "CODE_OF_CONDUCT.md",
|
|
2413
|
+
security: "SECURITY.md",
|
|
2414
|
+
roadmap: "ROADMAP.md",
|
|
2415
|
+
gitignore: ".gitignore",
|
|
2416
|
+
funding: ".github/FUNDING.yml",
|
|
2417
|
+
license: "LICENSE",
|
|
2418
|
+
readme: "README.md",
|
|
2419
|
+
architecture: "ARCHITECTURE.md",
|
|
2420
|
+
changelog: "CHANGELOG.md"
|
|
2421
|
+
};
|
|
2072
2422
|
function generateConfig(options) {
|
|
2073
2423
|
const files = {};
|
|
2074
2424
|
for (const platform of options.platforms) {
|
|
@@ -2077,13 +2427,34 @@ function generateConfig(options) {
|
|
|
2077
2427
|
files[filename] = generateFileContent(options, platform);
|
|
2078
2428
|
}
|
|
2079
2429
|
}
|
|
2430
|
+
if (options.staticFiles && options.staticFiles.length > 0) {
|
|
2431
|
+
for (const fileKey of options.staticFiles) {
|
|
2432
|
+
const filePath = STATIC_FILE_PATHS[fileKey];
|
|
2433
|
+
if (!filePath) continue;
|
|
2434
|
+
if (options.staticFileContents?.[fileKey]) {
|
|
2435
|
+
files[filePath] = options.staticFileContents[fileKey];
|
|
2436
|
+
} else {
|
|
2437
|
+
const templateFn = STATIC_FILE_TEMPLATES[fileKey];
|
|
2438
|
+
if (templateFn) {
|
|
2439
|
+
files[filePath] = templateFn(options);
|
|
2440
|
+
}
|
|
2441
|
+
}
|
|
2442
|
+
}
|
|
2443
|
+
}
|
|
2444
|
+
if (options.includeFunding && !options.staticFiles?.includes("funding")) {
|
|
2445
|
+
files[".github/FUNDING.yml"] = STATIC_FILE_TEMPLATES.funding(options);
|
|
2446
|
+
}
|
|
2080
2447
|
return files;
|
|
2081
2448
|
}
|
|
2082
2449
|
function generateFileContent(options, platform) {
|
|
2083
2450
|
const sections = [];
|
|
2084
2451
|
const isMdc = platform === "cursor";
|
|
2085
|
-
const
|
|
2086
|
-
const
|
|
2452
|
+
const isYaml = platform === "aider" || platform === "tabnine";
|
|
2453
|
+
const isPlainText = platform === "windsurf" || platform === "cline" || platform === "goose";
|
|
2454
|
+
const isMarkdown = !isMdc && !isYaml && !isPlainText;
|
|
2455
|
+
if (isYaml) {
|
|
2456
|
+
return generateYamlConfig(options, platform);
|
|
2457
|
+
}
|
|
2087
2458
|
if (isMdc) {
|
|
2088
2459
|
sections.push("---");
|
|
2089
2460
|
sections.push(`description: "${options.name} - AI coding rules"`);
|
|
@@ -2098,6 +2469,23 @@ function generateFileContent(options, platform) {
|
|
|
2098
2469
|
sections.push(`# ${options.name} - AI Assistant Configuration`);
|
|
2099
2470
|
sections.push("");
|
|
2100
2471
|
}
|
|
2472
|
+
if (options.projectType) {
|
|
2473
|
+
const typeContexts = {
|
|
2474
|
+
work: "This is a professional/enterprise project. Follow strict procedures and maintain high code quality.",
|
|
2475
|
+
leisure: "This is a personal/hobby project. Feel free to be more experimental and creative.",
|
|
2476
|
+
opensource: "This is an open-source project. Consider community guidelines and contribution standards.",
|
|
2477
|
+
learning: "This is an educational project. Explain concepts and be patient with learning-focused approaches."
|
|
2478
|
+
};
|
|
2479
|
+
if (typeContexts[options.projectType]) {
|
|
2480
|
+
if (isMarkdown || isMdc) {
|
|
2481
|
+
sections.push(`> **Project Context:** ${typeContexts[options.projectType]}`);
|
|
2482
|
+
sections.push("");
|
|
2483
|
+
} else {
|
|
2484
|
+
sections.push(`Project Context: ${typeContexts[options.projectType]}`);
|
|
2485
|
+
sections.push("");
|
|
2486
|
+
}
|
|
2487
|
+
}
|
|
2488
|
+
}
|
|
2101
2489
|
const personaDesc = PERSONA_DESCRIPTIONS[options.persona] || options.persona;
|
|
2102
2490
|
if (isMarkdown || isMdc) {
|
|
2103
2491
|
sections.push("## Persona");
|
|
@@ -2128,7 +2516,93 @@ function generateFileContent(options, platform) {
|
|
|
2128
2516
|
}
|
|
2129
2517
|
sections.push("");
|
|
2130
2518
|
}
|
|
2131
|
-
|
|
2519
|
+
if (options.letAiDecide) {
|
|
2520
|
+
if (isMarkdown || isMdc) {
|
|
2521
|
+
sections.push("> **AI Assistance:** Let AI analyze the codebase and suggest additional technologies and approaches as needed.");
|
|
2522
|
+
sections.push("");
|
|
2523
|
+
}
|
|
2524
|
+
}
|
|
2525
|
+
if (options.repoHost || options.license || options.conventionalCommits || options.semver || options.cicd || options.deploymentTargets?.length || options.buildContainer || options.exampleRepoUrl || options.documentationUrl) {
|
|
2526
|
+
if (isMarkdown || isMdc) {
|
|
2527
|
+
sections.push("## Repository & Infrastructure");
|
|
2528
|
+
sections.push("");
|
|
2529
|
+
if (options.repoHost) {
|
|
2530
|
+
sections.push(`- **Host:** ${options.repoHost.charAt(0).toUpperCase() + options.repoHost.slice(1)}`);
|
|
2531
|
+
}
|
|
2532
|
+
if (options.license && options.license !== "none") {
|
|
2533
|
+
sections.push(`- **License:** ${options.license.toUpperCase()}`);
|
|
2534
|
+
}
|
|
2535
|
+
if (options.conventionalCommits) {
|
|
2536
|
+
sections.push("- **Commits:** Follow [Conventional Commits](https://conventionalcommits.org) format");
|
|
2537
|
+
}
|
|
2538
|
+
if (options.semver) {
|
|
2539
|
+
sections.push("- **Versioning:** Follow [Semantic Versioning](https://semver.org) (semver)");
|
|
2540
|
+
}
|
|
2541
|
+
if (options.dependabot) {
|
|
2542
|
+
sections.push("- **Dependencies:** Dependabot/automated dependency updates enabled");
|
|
2543
|
+
}
|
|
2544
|
+
if (options.cicd) {
|
|
2545
|
+
const cicdNames = {
|
|
2546
|
+
github_actions: "GitHub Actions",
|
|
2547
|
+
gitlab_ci: "GitLab CI",
|
|
2548
|
+
jenkins: "Jenkins",
|
|
2549
|
+
circleci: "CircleCI",
|
|
2550
|
+
travis: "Travis CI",
|
|
2551
|
+
azure_devops: "Azure DevOps",
|
|
2552
|
+
bitbucket: "Bitbucket Pipelines",
|
|
2553
|
+
teamcity: "TeamCity",
|
|
2554
|
+
drone: "Drone",
|
|
2555
|
+
buildkite: "Buildkite"
|
|
2556
|
+
};
|
|
2557
|
+
sections.push(`- **CI/CD:** ${cicdNames[options.cicd] || options.cicd}`);
|
|
2558
|
+
}
|
|
2559
|
+
if (options.deploymentTargets && options.deploymentTargets.length > 0) {
|
|
2560
|
+
const targetNames = {
|
|
2561
|
+
vercel: "Vercel",
|
|
2562
|
+
netlify: "Netlify",
|
|
2563
|
+
aws: "AWS",
|
|
2564
|
+
gcp: "Google Cloud",
|
|
2565
|
+
azure: "Azure",
|
|
2566
|
+
docker: "Docker",
|
|
2567
|
+
kubernetes: "Kubernetes",
|
|
2568
|
+
heroku: "Heroku",
|
|
2569
|
+
digitalocean: "DigitalOcean",
|
|
2570
|
+
railway: "Railway",
|
|
2571
|
+
fly: "Fly.io",
|
|
2572
|
+
cloudflare: "Cloudflare"
|
|
2573
|
+
};
|
|
2574
|
+
const targets = options.deploymentTargets.map((t) => targetNames[t] || t).join(", ");
|
|
2575
|
+
sections.push(`- **Deployment:** ${targets}`);
|
|
2576
|
+
}
|
|
2577
|
+
if (options.buildContainer) {
|
|
2578
|
+
let containerInfo = "Docker container builds enabled";
|
|
2579
|
+
if (options.containerRegistry) {
|
|
2580
|
+
const registryNames = {
|
|
2581
|
+
dockerhub: "Docker Hub",
|
|
2582
|
+
ghcr: "GitHub Container Registry",
|
|
2583
|
+
gcr: "Google Container Registry",
|
|
2584
|
+
ecr: "AWS ECR",
|
|
2585
|
+
acr: "Azure Container Registry",
|
|
2586
|
+
quay: "Quay.io",
|
|
2587
|
+
gitlab: "GitLab Registry",
|
|
2588
|
+
custom: "Custom registry"
|
|
2589
|
+
};
|
|
2590
|
+
containerInfo += ` \u2192 ${registryNames[options.containerRegistry] || options.containerRegistry}`;
|
|
2591
|
+
}
|
|
2592
|
+
sections.push(`- **Containers:** ${containerInfo}`);
|
|
2593
|
+
}
|
|
2594
|
+
if (options.exampleRepoUrl) {
|
|
2595
|
+
sections.push(`- **Example Repo:** ${options.exampleRepoUrl} (use as reference for style/structure)`);
|
|
2596
|
+
}
|
|
2597
|
+
if (options.documentationUrl) {
|
|
2598
|
+
sections.push(`- **Documentation:** ${options.documentationUrl}`);
|
|
2599
|
+
}
|
|
2600
|
+
sections.push("");
|
|
2601
|
+
}
|
|
2602
|
+
}
|
|
2603
|
+
const hasCommands = options.commands && Object.values(options.commands).some(
|
|
2604
|
+
(v) => Array.isArray(v) ? v.length > 0 : Boolean(v)
|
|
2605
|
+
);
|
|
2132
2606
|
if (hasCommands) {
|
|
2133
2607
|
if (isMarkdown || isMdc) {
|
|
2134
2608
|
sections.push("## Commands");
|
|
@@ -2139,24 +2613,76 @@ function generateFileContent(options, platform) {
|
|
|
2139
2613
|
} else {
|
|
2140
2614
|
sections.push("Commands:");
|
|
2141
2615
|
}
|
|
2142
|
-
|
|
2143
|
-
|
|
2616
|
+
const cmdCategories = ["build", "test", "lint", "dev", "custom"];
|
|
2617
|
+
for (const cat of cmdCategories) {
|
|
2618
|
+
const cmd = options.commands[cat];
|
|
2619
|
+
if (cmd) {
|
|
2620
|
+
const cmds = Array.isArray(cmd) ? cmd : [cmd];
|
|
2621
|
+
for (const c of cmds) {
|
|
2622
|
+
if (c) {
|
|
2623
|
+
const label = cat.charAt(0).toUpperCase() + cat.slice(1);
|
|
2624
|
+
sections.push(isMarkdown || isMdc ? `# ${label}: ${c}` : `- ${label}: ${c}`);
|
|
2625
|
+
}
|
|
2626
|
+
}
|
|
2627
|
+
}
|
|
2144
2628
|
}
|
|
2145
|
-
if (
|
|
2146
|
-
sections.push(
|
|
2629
|
+
if (isMarkdown || isMdc) {
|
|
2630
|
+
sections.push("```");
|
|
2147
2631
|
}
|
|
2148
|
-
|
|
2149
|
-
|
|
2632
|
+
sections.push("");
|
|
2633
|
+
}
|
|
2634
|
+
if (options.aiBehavior && options.aiBehavior.length > 0) {
|
|
2635
|
+
if (isMarkdown || isMdc) {
|
|
2636
|
+
sections.push("## AI Behavior Rules");
|
|
2637
|
+
sections.push("");
|
|
2638
|
+
for (const rule of options.aiBehavior) {
|
|
2639
|
+
const desc = AI_BEHAVIOR_DESCRIPTIONS[rule];
|
|
2640
|
+
if (desc) {
|
|
2641
|
+
sections.push(`- ${desc}`);
|
|
2642
|
+
}
|
|
2643
|
+
}
|
|
2644
|
+
sections.push("");
|
|
2150
2645
|
}
|
|
2151
|
-
|
|
2152
|
-
|
|
2646
|
+
}
|
|
2647
|
+
if (options.importantFiles && options.importantFiles.length > 0) {
|
|
2648
|
+
if (isMarkdown || isMdc) {
|
|
2649
|
+
sections.push("## Important Files to Read");
|
|
2650
|
+
sections.push("");
|
|
2651
|
+
sections.push("Always read these files first to understand the project context:");
|
|
2652
|
+
sections.push("");
|
|
2653
|
+
for (const file of options.importantFiles) {
|
|
2654
|
+
const path2 = IMPORTANT_FILES_PATHS[file];
|
|
2655
|
+
if (path2) {
|
|
2656
|
+
sections.push(`- \`${path2}\``);
|
|
2657
|
+
}
|
|
2658
|
+
}
|
|
2659
|
+
sections.push("");
|
|
2153
2660
|
}
|
|
2661
|
+
}
|
|
2662
|
+
if (options.selfImprove) {
|
|
2154
2663
|
if (isMarkdown || isMdc) {
|
|
2155
|
-
sections.push("
|
|
2664
|
+
sections.push("## Self-Improving Blueprint");
|
|
2665
|
+
sections.push("");
|
|
2666
|
+
sections.push("> **Auto-update enabled:** As you work on this project, track patterns and update this configuration file to better reflect the project's conventions and preferences.");
|
|
2667
|
+
sections.push("");
|
|
2156
2668
|
}
|
|
2157
|
-
sections.push("");
|
|
2158
2669
|
}
|
|
2159
|
-
|
|
2670
|
+
if (options.includePersonalData) {
|
|
2671
|
+
if (isMarkdown || isMdc) {
|
|
2672
|
+
sections.push("## Commit Identity");
|
|
2673
|
+
sections.push("");
|
|
2674
|
+
sections.push("> **Personal data enabled:** Use my name and email for git commits when making changes.");
|
|
2675
|
+
sections.push("");
|
|
2676
|
+
}
|
|
2677
|
+
}
|
|
2678
|
+
let boundaries = BOUNDARIES[options.boundaries];
|
|
2679
|
+
if (options.boundaryNever?.length || options.boundaryAsk?.length) {
|
|
2680
|
+
boundaries = {
|
|
2681
|
+
...boundaries,
|
|
2682
|
+
never: options.boundaryNever?.length ? options.boundaryNever : boundaries.never,
|
|
2683
|
+
askFirst: options.boundaryAsk?.length ? options.boundaryAsk : boundaries.askFirst
|
|
2684
|
+
};
|
|
2685
|
+
}
|
|
2160
2686
|
if (boundaries) {
|
|
2161
2687
|
if (isMarkdown || isMdc) {
|
|
2162
2688
|
sections.push("## Boundaries");
|
|
@@ -2201,6 +2727,30 @@ function generateFileContent(options, platform) {
|
|
|
2201
2727
|
if (isMarkdown || isMdc) {
|
|
2202
2728
|
sections.push("## Code Style");
|
|
2203
2729
|
sections.push("");
|
|
2730
|
+
if (options.namingConvention) {
|
|
2731
|
+
const namingDesc = NAMING_DESCRIPTIONS[options.namingConvention];
|
|
2732
|
+
if (namingDesc) {
|
|
2733
|
+
sections.push(`- **Naming:** ${namingDesc}`);
|
|
2734
|
+
}
|
|
2735
|
+
}
|
|
2736
|
+
if (options.errorHandling) {
|
|
2737
|
+
const errorStyles = {
|
|
2738
|
+
try_catch: "Use try/catch blocks for error handling",
|
|
2739
|
+
result_types: "Use Result/Either types for error handling",
|
|
2740
|
+
error_codes: "Use error codes with proper documentation",
|
|
2741
|
+
exceptions: "Use custom exception classes"
|
|
2742
|
+
};
|
|
2743
|
+
if (errorStyles[options.errorHandling]) {
|
|
2744
|
+
sections.push(`- **Errors:** ${errorStyles[options.errorHandling]}`);
|
|
2745
|
+
}
|
|
2746
|
+
}
|
|
2747
|
+
if (options.loggingConventions) {
|
|
2748
|
+
sections.push(`- **Logging:** ${options.loggingConventions}`);
|
|
2749
|
+
}
|
|
2750
|
+
if (options.styleNotes) {
|
|
2751
|
+
sections.push(`- **Notes:** ${options.styleNotes}`);
|
|
2752
|
+
}
|
|
2753
|
+
sections.push("");
|
|
2204
2754
|
sections.push("Follow these conventions:");
|
|
2205
2755
|
sections.push("");
|
|
2206
2756
|
if (options.stack.includes("typescript") || options.stack.includes("javascript")) {
|
|
@@ -2234,6 +2784,49 @@ function generateFileContent(options, platform) {
|
|
|
2234
2784
|
sections.push("- Keep functions focused and testable");
|
|
2235
2785
|
sections.push("");
|
|
2236
2786
|
}
|
|
2787
|
+
if (options.testLevels?.length || options.testFrameworks?.length || options.coverageTarget) {
|
|
2788
|
+
if (isMarkdown || isMdc) {
|
|
2789
|
+
sections.push("## Testing Strategy");
|
|
2790
|
+
sections.push("");
|
|
2791
|
+
if (options.testLevels?.length) {
|
|
2792
|
+
sections.push("### Test Levels");
|
|
2793
|
+
sections.push("");
|
|
2794
|
+
for (const level of options.testLevels) {
|
|
2795
|
+
const desc = TEST_LEVEL_DESCRIPTIONS[level];
|
|
2796
|
+
if (desc) {
|
|
2797
|
+
sections.push(`- **${level.charAt(0).toUpperCase() + level.slice(1)}:** ${desc}`);
|
|
2798
|
+
}
|
|
2799
|
+
}
|
|
2800
|
+
sections.push("");
|
|
2801
|
+
}
|
|
2802
|
+
if (options.testFrameworks?.length) {
|
|
2803
|
+
sections.push("### Frameworks");
|
|
2804
|
+
sections.push("");
|
|
2805
|
+
sections.push(`Use: ${options.testFrameworks.join(", ")}`);
|
|
2806
|
+
sections.push("");
|
|
2807
|
+
}
|
|
2808
|
+
if (options.coverageTarget) {
|
|
2809
|
+
sections.push(`### Coverage Target: ${options.coverageTarget}%`);
|
|
2810
|
+
sections.push("");
|
|
2811
|
+
}
|
|
2812
|
+
if (options.testNotes) {
|
|
2813
|
+
sections.push(`**Notes:** ${options.testNotes}`);
|
|
2814
|
+
sections.push("");
|
|
2815
|
+
}
|
|
2816
|
+
}
|
|
2817
|
+
}
|
|
2818
|
+
if (options.extraNotes) {
|
|
2819
|
+
if (isMarkdown || isMdc) {
|
|
2820
|
+
sections.push("## Additional Notes");
|
|
2821
|
+
sections.push("");
|
|
2822
|
+
sections.push(options.extraNotes);
|
|
2823
|
+
sections.push("");
|
|
2824
|
+
} else {
|
|
2825
|
+
sections.push("Additional Notes:");
|
|
2826
|
+
sections.push(options.extraNotes);
|
|
2827
|
+
sections.push("");
|
|
2828
|
+
}
|
|
2829
|
+
}
|
|
2237
2830
|
if (isMarkdown || isMdc) {
|
|
2238
2831
|
sections.push("---");
|
|
2239
2832
|
sections.push("");
|
|
@@ -2241,37 +2834,82 @@ function generateFileContent(options, platform) {
|
|
|
2241
2834
|
}
|
|
2242
2835
|
return sections.join("\n");
|
|
2243
2836
|
}
|
|
2837
|
+
function generateYamlConfig(options, platform) {
|
|
2838
|
+
const lines = [];
|
|
2839
|
+
if (platform === "aider") {
|
|
2840
|
+
lines.push("# Aider configuration");
|
|
2841
|
+
lines.push(`# Project: ${options.name}`);
|
|
2842
|
+
lines.push("");
|
|
2843
|
+
lines.push("# Model settings");
|
|
2844
|
+
lines.push("model: gpt-4");
|
|
2845
|
+
lines.push("");
|
|
2846
|
+
lines.push("# Code style");
|
|
2847
|
+
if (options.stack.includes("typescript") || options.stack.includes("javascript")) {
|
|
2848
|
+
lines.push("auto-lint: true");
|
|
2849
|
+
}
|
|
2850
|
+
lines.push("");
|
|
2851
|
+
lines.push("# Custom instructions");
|
|
2852
|
+
lines.push("read:");
|
|
2853
|
+
lines.push(" - README.md");
|
|
2854
|
+
if (options.importantFiles?.includes("architecture")) {
|
|
2855
|
+
lines.push(" - ARCHITECTURE.md");
|
|
2856
|
+
}
|
|
2857
|
+
} else if (platform === "tabnine") {
|
|
2858
|
+
lines.push("# Tabnine configuration");
|
|
2859
|
+
lines.push(`# Project: ${options.name}`);
|
|
2860
|
+
lines.push("");
|
|
2861
|
+
lines.push("version: 1.0.0");
|
|
2862
|
+
lines.push("");
|
|
2863
|
+
lines.push("project:");
|
|
2864
|
+
lines.push(` name: ${options.name}`);
|
|
2865
|
+
if (options.description) {
|
|
2866
|
+
lines.push(` description: "${options.description}"`);
|
|
2867
|
+
}
|
|
2868
|
+
lines.push("");
|
|
2869
|
+
lines.push("context:");
|
|
2870
|
+
lines.push(" include:");
|
|
2871
|
+
lines.push(' - "**/*.ts"');
|
|
2872
|
+
lines.push(' - "**/*.js"');
|
|
2873
|
+
lines.push(' - "**/*.py"');
|
|
2874
|
+
}
|
|
2875
|
+
lines.push("");
|
|
2876
|
+
lines.push(`# Generated by LynxPrompt CLI`);
|
|
2877
|
+
return lines.join("\n");
|
|
2878
|
+
}
|
|
2244
2879
|
|
|
2245
2880
|
// src/commands/wizard.ts
|
|
2246
|
-
var
|
|
2247
|
-
{
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
},
|
|
2253
|
-
{
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
},
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
},
|
|
2263
|
-
{
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
},
|
|
2268
|
-
{
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
}
|
|
2881
|
+
var WIZARD_STEPS = [
|
|
2882
|
+
{ id: "format", title: "Output Format", icon: "\u{1F4E4}", tier: "basic" },
|
|
2883
|
+
{ id: "project", title: "Project Basics", icon: "\u2728", tier: "basic" },
|
|
2884
|
+
{ id: "tech", title: "Tech Stack", icon: "\u{1F4BB}", tier: "basic" },
|
|
2885
|
+
{ id: "repo", title: "Repository Setup", icon: "\u{1F500}", tier: "basic" },
|
|
2886
|
+
{ id: "commands", title: "Commands", icon: "\u{1F4CB}", tier: "intermediate" },
|
|
2887
|
+
{ id: "code_style", title: "Code Style", icon: "\u{1FA84}", tier: "intermediate" },
|
|
2888
|
+
{ id: "ai", title: "AI Behavior", icon: "\u{1F9E0}", tier: "basic" },
|
|
2889
|
+
{ id: "boundaries", title: "Boundaries", icon: "\u{1F6E1}\uFE0F", tier: "advanced" },
|
|
2890
|
+
{ id: "testing", title: "Testing Strategy", icon: "\u{1F9EA}", tier: "advanced" },
|
|
2891
|
+
{ id: "static", title: "Static Files", icon: "\u{1F4C4}", tier: "advanced" },
|
|
2892
|
+
{ id: "extra", title: "Final Details", icon: "\u{1F4AC}", tier: "basic" }
|
|
2893
|
+
];
|
|
2894
|
+
var ALL_PLATFORMS = [
|
|
2895
|
+
{ id: "agents", name: "Universal (AGENTS.md)", file: "AGENTS.md", icon: "\u{1F310}", note: "Works with all AI-enabled IDEs" },
|
|
2896
|
+
{ id: "cursor", name: "Cursor", file: ".cursor/rules/", icon: "\u26A1", note: "Native project rules format" },
|
|
2897
|
+
{ id: "claude", name: "Claude Code", file: "CLAUDE.md", icon: "\u{1F9E0}", note: "Also works with Cursor" },
|
|
2898
|
+
{ id: "copilot", name: "GitHub Copilot", file: ".github/copilot-instructions.md", icon: "\u{1F419}", note: "VS Code & JetBrains" },
|
|
2899
|
+
{ id: "windsurf", name: "Windsurf", file: ".windsurfrules", icon: "\u{1F3C4}", note: "Codeium IDE" },
|
|
2900
|
+
{ id: "zed", name: "Zed", file: ".zed/instructions.md", icon: "\u26A1", note: "Zed editor" },
|
|
2901
|
+
{ id: "aider", name: "Aider", file: ".aider.conf.yml", icon: "\u{1F916}", note: "CLI AI pair programming" },
|
|
2902
|
+
{ id: "cline", name: "Cline", file: ".clinerules", icon: "\u{1F527}", note: "VS Code extension" },
|
|
2903
|
+
{ id: "continue", name: "Continue", file: ".continue/config.json", icon: "\u27A1\uFE0F", note: "Open-source autopilot" },
|
|
2904
|
+
{ id: "cody", name: "Sourcegraph Cody", file: ".cody/config.json", icon: "\u{1F50D}", note: "Context-aware AI" },
|
|
2905
|
+
{ id: "amazonq", name: "Amazon Q", file: ".amazonq/rules/", icon: "\u{1F4E6}", note: "AWS AI assistant" },
|
|
2906
|
+
{ id: "tabnine", name: "Tabnine", file: ".tabnine.yaml", icon: "\u{1F4DD}", note: "AI code completion" },
|
|
2907
|
+
{ id: "supermaven", name: "Supermaven", file: ".supermaven/config.json", icon: "\u{1F9B8}", note: "Fast AI completions" },
|
|
2908
|
+
{ id: "codegpt", name: "CodeGPT", file: ".codegpt/config.json", icon: "\u{1F4AC}", note: "VS Code AI assistant" },
|
|
2909
|
+
{ id: "void", name: "Void", file: ".void/config.json", icon: "\u{1F573}\uFE0F", note: "Open-source Cursor alt" },
|
|
2910
|
+
{ id: "goose", name: "Goose", file: ".goosehints", icon: "\u{1FABF}", note: "Block AI agent" }
|
|
2273
2911
|
];
|
|
2274
|
-
var
|
|
2912
|
+
var LANGUAGES = [
|
|
2275
2913
|
{ title: "\u{1F537} TypeScript", value: "typescript" },
|
|
2276
2914
|
{ title: "\u{1F7E1} JavaScript", value: "javascript" },
|
|
2277
2915
|
{ title: "\u{1F40D} Python", value: "python" },
|
|
@@ -2281,7 +2919,9 @@ var TECH_STACKS = [
|
|
|
2281
2919
|
{ title: "\u{1F49C} C#/.NET", value: "csharp" },
|
|
2282
2920
|
{ title: "\u{1F48E} Ruby", value: "ruby" },
|
|
2283
2921
|
{ title: "\u{1F418} PHP", value: "php" },
|
|
2284
|
-
{ title: "\u{1F34E} Swift", value: "swift" }
|
|
2922
|
+
{ title: "\u{1F34E} Swift", value: "swift" },
|
|
2923
|
+
{ title: "\u{1F536} Kotlin", value: "kotlin" },
|
|
2924
|
+
{ title: "\u2B1B C/C++", value: "cpp" }
|
|
2285
2925
|
];
|
|
2286
2926
|
var FRAMEWORKS = [
|
|
2287
2927
|
{ title: "\u269B\uFE0F React", value: "react" },
|
|
@@ -2300,23 +2940,169 @@ var FRAMEWORKS = [
|
|
|
2300
2940
|
{ title: "\u26A1 Vite", value: "vite" },
|
|
2301
2941
|
{ title: "\u{1F4F1} React Native", value: "react-native" }
|
|
2302
2942
|
];
|
|
2303
|
-
var
|
|
2304
|
-
{ title: "\u{
|
|
2305
|
-
{ title: "\u{
|
|
2306
|
-
{ title: "\u{
|
|
2307
|
-
{ title: "\u{
|
|
2308
|
-
{ title: "\u{
|
|
2309
|
-
{ title: "\
|
|
2310
|
-
{ title: "\u{
|
|
2943
|
+
var DATABASES = [
|
|
2944
|
+
{ title: "\u{1F418} PostgreSQL", value: "postgresql" },
|
|
2945
|
+
{ title: "\u{1F42C} MySQL", value: "mysql" },
|
|
2946
|
+
{ title: "\u{1F343} MongoDB", value: "mongodb" },
|
|
2947
|
+
{ title: "\u{1F534} Redis", value: "redis" },
|
|
2948
|
+
{ title: "\u{1F4CA} SQLite", value: "sqlite" },
|
|
2949
|
+
{ title: "\u2601\uFE0F Supabase", value: "supabase" },
|
|
2950
|
+
{ title: "\u{1F525} Firebase", value: "firebase" },
|
|
2951
|
+
{ title: "\u{1F4C2} Prisma", value: "prisma" }
|
|
2952
|
+
];
|
|
2953
|
+
var REPO_HOSTS = [
|
|
2954
|
+
{ id: "github", label: "GitHub", icon: "\u{1F419}" },
|
|
2955
|
+
{ id: "gitlab", label: "GitLab", icon: "\u{1F98A}" },
|
|
2956
|
+
{ id: "bitbucket", label: "Bitbucket", icon: "\u{1FAA3}" },
|
|
2957
|
+
{ id: "gitea", label: "Gitea", icon: "\u{1F375}" },
|
|
2958
|
+
{ id: "azure", label: "Azure DevOps", icon: "\u2601\uFE0F" },
|
|
2959
|
+
{ id: "other", label: "Other", icon: "\u{1F4E6}" }
|
|
2960
|
+
];
|
|
2961
|
+
var LICENSES = [
|
|
2962
|
+
{ id: "mit", label: "MIT" },
|
|
2963
|
+
{ id: "apache-2.0", label: "Apache 2.0" },
|
|
2964
|
+
{ id: "gpl-3.0", label: "GPL 3.0" },
|
|
2965
|
+
{ id: "lgpl-3.0", label: "LGPL 3.0" },
|
|
2966
|
+
{ id: "agpl-3.0", label: "AGPL 3.0" },
|
|
2967
|
+
{ id: "bsd-3", label: "BSD 3-Clause" },
|
|
2968
|
+
{ id: "mpl-2.0", label: "MPL 2.0" },
|
|
2969
|
+
{ id: "unlicense", label: "Unlicense" },
|
|
2970
|
+
{ id: "none", label: "None / Proprietary" }
|
|
2971
|
+
];
|
|
2972
|
+
var CICD_OPTIONS = [
|
|
2973
|
+
{ id: "github_actions", label: "GitHub Actions", icon: "\u{1F419}" },
|
|
2974
|
+
{ id: "gitlab_ci", label: "GitLab CI", icon: "\u{1F98A}" },
|
|
2975
|
+
{ id: "jenkins", label: "Jenkins", icon: "\u{1F527}" },
|
|
2976
|
+
{ id: "circleci", label: "CircleCI", icon: "\u26AB" },
|
|
2977
|
+
{ id: "travis", label: "Travis CI", icon: "\u{1F528}" },
|
|
2978
|
+
{ id: "azure_devops", label: "Azure DevOps", icon: "\u2601\uFE0F" },
|
|
2979
|
+
{ id: "bitbucket", label: "Bitbucket Pipelines", icon: "\u{1FAA3}" },
|
|
2980
|
+
{ id: "teamcity", label: "TeamCity", icon: "\u{1F3E2}" },
|
|
2981
|
+
{ id: "drone", label: "Drone", icon: "\u{1F681}" },
|
|
2982
|
+
{ id: "buildkite", label: "Buildkite", icon: "\u{1F9F1}" }
|
|
2983
|
+
];
|
|
2984
|
+
var DEPLOYMENT_TARGETS = [
|
|
2985
|
+
{ id: "vercel", label: "Vercel", icon: "\u25B2" },
|
|
2986
|
+
{ id: "netlify", label: "Netlify", icon: "\u{1F310}" },
|
|
2987
|
+
{ id: "aws", label: "AWS", icon: "\u2601\uFE0F" },
|
|
2988
|
+
{ id: "gcp", label: "Google Cloud", icon: "\u{1F308}" },
|
|
2989
|
+
{ id: "azure", label: "Azure", icon: "\u{1F537}" },
|
|
2990
|
+
{ id: "docker", label: "Docker", icon: "\u{1F433}" },
|
|
2991
|
+
{ id: "kubernetes", label: "Kubernetes", icon: "\u2638\uFE0F" },
|
|
2992
|
+
{ id: "heroku", label: "Heroku", icon: "\u{1F7E3}" },
|
|
2993
|
+
{ id: "digitalocean", label: "DigitalOcean", icon: "\u{1F535}" },
|
|
2994
|
+
{ id: "railway", label: "Railway", icon: "\u{1F682}" },
|
|
2995
|
+
{ id: "fly", label: "Fly.io", icon: "\u2708\uFE0F" },
|
|
2996
|
+
{ id: "cloudflare", label: "Cloudflare", icon: "\u{1F536}" }
|
|
2997
|
+
];
|
|
2998
|
+
var CONTAINER_REGISTRIES = [
|
|
2999
|
+
{ id: "dockerhub", label: "Docker Hub", icon: "\u{1F433}" },
|
|
3000
|
+
{ id: "ghcr", label: "GitHub Container Registry", icon: "\u{1F419}" },
|
|
3001
|
+
{ id: "gcr", label: "Google Container Registry", icon: "\u{1F308}" },
|
|
3002
|
+
{ id: "ecr", label: "AWS ECR", icon: "\u2601\uFE0F" },
|
|
3003
|
+
{ id: "acr", label: "Azure Container Registry", icon: "\u{1F537}" },
|
|
3004
|
+
{ id: "quay", label: "Quay.io", icon: "\u{1F534}" },
|
|
3005
|
+
{ id: "gitlab", label: "GitLab Registry", icon: "\u{1F98A}" },
|
|
3006
|
+
{ id: "custom", label: "Custom/Self-hosted", icon: "\u{1F3E0}" }
|
|
3007
|
+
];
|
|
3008
|
+
var COMMON_COMMANDS = {
|
|
3009
|
+
build: [
|
|
3010
|
+
"npm run build",
|
|
3011
|
+
"pnpm build",
|
|
3012
|
+
"yarn build",
|
|
3013
|
+
"bun run build",
|
|
3014
|
+
"next build",
|
|
3015
|
+
"vite build",
|
|
3016
|
+
"tsc",
|
|
3017
|
+
"tsc --noEmit",
|
|
3018
|
+
"go build",
|
|
3019
|
+
"cargo build",
|
|
3020
|
+
"cargo build --release",
|
|
3021
|
+
"mvn package",
|
|
3022
|
+
"gradle build",
|
|
3023
|
+
"dotnet build",
|
|
3024
|
+
"docker build -t app .",
|
|
3025
|
+
"docker compose build"
|
|
3026
|
+
],
|
|
3027
|
+
test: [
|
|
3028
|
+
"npm test",
|
|
3029
|
+
"pnpm test",
|
|
3030
|
+
"yarn test",
|
|
3031
|
+
"bun test",
|
|
3032
|
+
"vitest",
|
|
3033
|
+
"vitest run",
|
|
3034
|
+
"jest",
|
|
3035
|
+
"jest --coverage",
|
|
3036
|
+
"pytest",
|
|
3037
|
+
"pytest --cov",
|
|
3038
|
+
"go test ./...",
|
|
3039
|
+
"cargo test",
|
|
3040
|
+
"mvn test",
|
|
3041
|
+
"gradle test",
|
|
3042
|
+
"playwright test",
|
|
3043
|
+
"cypress run"
|
|
3044
|
+
],
|
|
3045
|
+
lint: [
|
|
3046
|
+
"npm run lint",
|
|
3047
|
+
"pnpm lint",
|
|
3048
|
+
"eslint .",
|
|
3049
|
+
"eslint . --fix",
|
|
3050
|
+
"prettier --check .",
|
|
3051
|
+
"prettier --write .",
|
|
3052
|
+
"ruff check",
|
|
3053
|
+
"ruff format",
|
|
3054
|
+
"black .",
|
|
3055
|
+
"flake8",
|
|
3056
|
+
"golangci-lint run",
|
|
3057
|
+
"cargo clippy",
|
|
3058
|
+
"rubocop"
|
|
3059
|
+
],
|
|
3060
|
+
dev: [
|
|
3061
|
+
"npm run dev",
|
|
3062
|
+
"pnpm dev",
|
|
3063
|
+
"yarn dev",
|
|
3064
|
+
"bun run dev",
|
|
3065
|
+
"next dev",
|
|
3066
|
+
"vite",
|
|
3067
|
+
"vite dev",
|
|
3068
|
+
"uvicorn main:app --reload",
|
|
3069
|
+
"flask run",
|
|
3070
|
+
"rails server",
|
|
3071
|
+
"go run .",
|
|
3072
|
+
"cargo run",
|
|
3073
|
+
"dotnet run"
|
|
3074
|
+
]
|
|
3075
|
+
};
|
|
3076
|
+
var NAMING_CONVENTIONS = [
|
|
3077
|
+
{ id: "language_default", label: "Follow language conventions", desc: "Use idiomatic style" },
|
|
3078
|
+
{ id: "camelCase", label: "camelCase", desc: "JavaScript, TypeScript, Java" },
|
|
3079
|
+
{ id: "snake_case", label: "snake_case", desc: "Python, Ruby, Rust, Go" },
|
|
3080
|
+
{ id: "PascalCase", label: "PascalCase", desc: "C#, .NET classes" },
|
|
3081
|
+
{ id: "kebab-case", label: "kebab-case", desc: "CSS, HTML, URLs" }
|
|
3082
|
+
];
|
|
3083
|
+
var ERROR_PATTERNS = [
|
|
3084
|
+
{ id: "try_catch", label: "try/catch blocks" },
|
|
3085
|
+
{ id: "result_types", label: "Result/Either types" },
|
|
3086
|
+
{ id: "error_codes", label: "Error codes" },
|
|
3087
|
+
{ id: "exceptions", label: "Custom exceptions" },
|
|
3088
|
+
{ id: "other", label: "Other" }
|
|
2311
3089
|
];
|
|
2312
|
-
var
|
|
2313
|
-
{
|
|
2314
|
-
{
|
|
2315
|
-
{
|
|
2316
|
-
{
|
|
2317
|
-
{
|
|
2318
|
-
{
|
|
2319
|
-
{
|
|
3090
|
+
var AI_BEHAVIOR_RULES = [
|
|
3091
|
+
{ id: "explain_changes", label: "Explain changes before making them", recommended: true },
|
|
3092
|
+
{ id: "preserve_style", label: "Preserve existing code style", recommended: true },
|
|
3093
|
+
{ id: "minimal_changes", label: "Make minimal, focused changes", recommended: true },
|
|
3094
|
+
{ id: "no_comments", label: "Avoid adding unnecessary comments", recommended: false },
|
|
3095
|
+
{ id: "prefer_simple", label: "Prefer simpler solutions", recommended: true },
|
|
3096
|
+
{ id: "test_first", label: "Write tests before implementation", recommended: false },
|
|
3097
|
+
{ id: "no_console", label: "Remove console.log/print before committing", recommended: false },
|
|
3098
|
+
{ id: "type_strict", label: "Be strict with types (no any/Any)", recommended: false }
|
|
3099
|
+
];
|
|
3100
|
+
var IMPORTANT_FILES = [
|
|
3101
|
+
{ id: "readme", label: "README.md", icon: "\u{1F4D6}" },
|
|
3102
|
+
{ id: "package", label: "package.json / pyproject.toml", icon: "\u{1F4E6}" },
|
|
3103
|
+
{ id: "tsconfig", label: "tsconfig.json / config files", icon: "\u2699\uFE0F" },
|
|
3104
|
+
{ id: "architecture", label: "ARCHITECTURE.md", icon: "\u{1F3D7}\uFE0F" },
|
|
3105
|
+
{ id: "contributing", label: "CONTRIBUTING.md", icon: "\u{1F91D}" }
|
|
2320
3106
|
];
|
|
2321
3107
|
var BOUNDARY_PRESETS = [
|
|
2322
3108
|
{
|
|
@@ -2344,11 +3130,96 @@ var BOUNDARY_PRESETS = [
|
|
|
2344
3130
|
never: ["Modify .env", "Access external APIs without confirmation"]
|
|
2345
3131
|
}
|
|
2346
3132
|
];
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
3133
|
+
var BOUNDARY_OPTIONS = [
|
|
3134
|
+
"Delete files",
|
|
3135
|
+
"Create new files",
|
|
3136
|
+
"Rename/move files",
|
|
3137
|
+
"Rewrite large sections",
|
|
3138
|
+
"Refactor architecture",
|
|
3139
|
+
"Change dependencies",
|
|
3140
|
+
"Modify database schema",
|
|
3141
|
+
"Update API contracts",
|
|
3142
|
+
"Touch CI pipelines",
|
|
3143
|
+
"Modify Docker config",
|
|
3144
|
+
"Change environment vars",
|
|
3145
|
+
"Update docs automatically",
|
|
3146
|
+
"Edit README",
|
|
3147
|
+
"Handle secrets/credentials",
|
|
3148
|
+
"Modify auth logic",
|
|
3149
|
+
"Delete failing tests",
|
|
3150
|
+
"Skip tests temporarily"
|
|
3151
|
+
];
|
|
3152
|
+
var TEST_FRAMEWORKS = [
|
|
3153
|
+
"jest",
|
|
3154
|
+
"vitest",
|
|
3155
|
+
"mocha",
|
|
3156
|
+
"ava",
|
|
3157
|
+
"tap",
|
|
3158
|
+
"pytest",
|
|
3159
|
+
"unittest",
|
|
3160
|
+
"nose2",
|
|
3161
|
+
"go test",
|
|
3162
|
+
"testify",
|
|
3163
|
+
"cargo test",
|
|
3164
|
+
"rstest",
|
|
3165
|
+
"junit",
|
|
3166
|
+
"testng",
|
|
3167
|
+
"spock",
|
|
3168
|
+
"rspec",
|
|
3169
|
+
"minitest",
|
|
3170
|
+
"phpunit",
|
|
3171
|
+
"pest",
|
|
3172
|
+
"playwright",
|
|
3173
|
+
"cypress",
|
|
3174
|
+
"puppeteer",
|
|
3175
|
+
"selenium"
|
|
3176
|
+
];
|
|
3177
|
+
var TEST_LEVELS = [
|
|
3178
|
+
{ id: "smoke", label: "Smoke", desc: "Quick sanity checks" },
|
|
3179
|
+
{ id: "unit", label: "Unit", desc: "Individual functions/components" },
|
|
3180
|
+
{ id: "integration", label: "Integration", desc: "Component interactions" },
|
|
3181
|
+
{ id: "e2e", label: "E2E", desc: "Full user flows" }
|
|
3182
|
+
];
|
|
3183
|
+
var PROJECT_TYPES = [
|
|
3184
|
+
{ id: "work", label: "Work", icon: "\u{1F4BC}", description: "Professional/enterprise project" },
|
|
3185
|
+
{ id: "leisure", label: "Leisure", icon: "\u{1F3AE}", description: "Personal/hobby project" },
|
|
3186
|
+
{ id: "opensource", label: "Open Source", icon: "\u{1F30D}", description: "Community-driven project" },
|
|
3187
|
+
{ id: "learning", label: "Learning", icon: "\u{1F4DA}", description: "Educational/experimental" }
|
|
3188
|
+
];
|
|
3189
|
+
var DEV_OS_OPTIONS = [
|
|
3190
|
+
{ id: "macos", label: "macOS", icon: "\u{1F34E}" },
|
|
3191
|
+
{ id: "linux", label: "Linux", icon: "\u{1F427}" },
|
|
3192
|
+
{ id: "windows", label: "Windows", icon: "\u{1FA9F}" },
|
|
3193
|
+
{ id: "wsl", label: "WSL", icon: "\u{1F427}" },
|
|
3194
|
+
{ id: "remote", label: "Remote/SSH", icon: "\u2601\uFE0F" }
|
|
3195
|
+
];
|
|
3196
|
+
var ARCHITECTURE_PATTERNS = [
|
|
3197
|
+
{ id: "monolith", label: "Monolith" },
|
|
3198
|
+
{ id: "microservices", label: "Microservices" },
|
|
3199
|
+
{ id: "serverless", label: "Serverless" },
|
|
3200
|
+
{ id: "mvc", label: "MVC" },
|
|
3201
|
+
{ id: "layered", label: "Layered/N-tier" },
|
|
3202
|
+
{ id: "event_driven", label: "Event-driven" },
|
|
3203
|
+
{ id: "modular", label: "Modular monolith" },
|
|
3204
|
+
{ id: "other", label: "Other" }
|
|
3205
|
+
];
|
|
3206
|
+
function canAccessTier(userTier, requiredTier) {
|
|
3207
|
+
const tierLevels = { free: 0, pro: 1, max: 2, teams: 2 };
|
|
3208
|
+
const requiredLevels = { basic: 0, intermediate: 1, advanced: 2 };
|
|
3209
|
+
return tierLevels[userTier] >= requiredLevels[requiredTier];
|
|
3210
|
+
}
|
|
3211
|
+
function getTierBadge(tier) {
|
|
3212
|
+
switch (tier) {
|
|
3213
|
+
case "intermediate":
|
|
3214
|
+
return { label: "PRO", color: chalk8.cyan };
|
|
3215
|
+
case "advanced":
|
|
3216
|
+
return { label: "MAX", color: chalk8.magenta };
|
|
3217
|
+
default:
|
|
3218
|
+
return null;
|
|
3219
|
+
}
|
|
3220
|
+
}
|
|
3221
|
+
function getAvailableSteps(userTier) {
|
|
3222
|
+
return WIZARD_STEPS.filter((step) => canAccessTier(userTier, step.tier));
|
|
2352
3223
|
}
|
|
2353
3224
|
function printBox(lines, color = chalk8.gray) {
|
|
2354
3225
|
const maxLen = Math.max(...lines.map((l) => l.replace(/\x1b\[[0-9;]*m/g, "").length));
|
|
@@ -2362,11 +3233,86 @@ function printBox(lines, color = chalk8.gray) {
|
|
|
2362
3233
|
}
|
|
2363
3234
|
console.log(color(bottom));
|
|
2364
3235
|
}
|
|
3236
|
+
function showStep(current, step, userTier) {
|
|
3237
|
+
const availableSteps = getAvailableSteps(userTier);
|
|
3238
|
+
const total = availableSteps.length;
|
|
3239
|
+
const progress = "\u25CF".repeat(current) + "\u25CB".repeat(total - current);
|
|
3240
|
+
const badge = getTierBadge(step.tier);
|
|
3241
|
+
console.log();
|
|
3242
|
+
let stepLine = chalk8.cyan(` ${progress} Step ${current}/${total}: ${step.icon} ${step.title}`);
|
|
3243
|
+
if (badge) {
|
|
3244
|
+
stepLine += " " + badge.color(`[${badge.label}]`);
|
|
3245
|
+
}
|
|
3246
|
+
console.log(stepLine);
|
|
3247
|
+
console.log();
|
|
3248
|
+
}
|
|
3249
|
+
function showWizardOverview(userTier) {
|
|
3250
|
+
console.log(chalk8.bold(" \u{1F4CB} Wizard Steps Overview:"));
|
|
3251
|
+
console.log();
|
|
3252
|
+
let stepNum = 1;
|
|
3253
|
+
for (const step of WIZARD_STEPS) {
|
|
3254
|
+
const canAccess = canAccessTier(userTier, step.tier);
|
|
3255
|
+
const badge = getTierBadge(step.tier);
|
|
3256
|
+
if (canAccess) {
|
|
3257
|
+
let line = chalk8.green(` ${stepNum.toString().padStart(2)}. \u2713 ${step.icon} ${step.title}`);
|
|
3258
|
+
if (badge) {
|
|
3259
|
+
line += " " + badge.color(`[${badge.label}]`);
|
|
3260
|
+
}
|
|
3261
|
+
console.log(line);
|
|
3262
|
+
stepNum++;
|
|
3263
|
+
} else {
|
|
3264
|
+
let line = chalk8.gray(` \u2500 \u{1F512} ${step.icon} ${step.title}`);
|
|
3265
|
+
if (badge) {
|
|
3266
|
+
line += " " + badge.color.dim(`[${badge.label}]`);
|
|
3267
|
+
}
|
|
3268
|
+
console.log(line);
|
|
3269
|
+
}
|
|
3270
|
+
}
|
|
3271
|
+
console.log();
|
|
3272
|
+
}
|
|
3273
|
+
var promptConfig = {
|
|
3274
|
+
onCancel: () => {
|
|
3275
|
+
console.log(chalk8.yellow("\n Cancelled. Run 'lynxp wizard' anytime to restart.\n"));
|
|
3276
|
+
process.exit(0);
|
|
3277
|
+
}
|
|
3278
|
+
};
|
|
2365
3279
|
async function wizardCommand(options) {
|
|
2366
3280
|
console.log();
|
|
2367
3281
|
console.log(chalk8.cyan.bold(" \u{1F431} LynxPrompt Wizard"));
|
|
2368
3282
|
console.log(chalk8.gray(" Generate AI IDE configuration in seconds"));
|
|
2369
3283
|
console.log();
|
|
3284
|
+
const authenticated = isAuthenticated();
|
|
3285
|
+
const user = getUser();
|
|
3286
|
+
const userPlanRaw = user?.plan?.toLowerCase() || "free";
|
|
3287
|
+
const userTier = ["pro", "max", "teams"].includes(userPlanRaw) ? userPlanRaw : "free";
|
|
3288
|
+
const userPlanDisplay = user?.plan?.toUpperCase() || "FREE";
|
|
3289
|
+
if (!authenticated) {
|
|
3290
|
+
const W = 55;
|
|
3291
|
+
const y = chalk8.yellow;
|
|
3292
|
+
const pad = (s, len) => s + " ".repeat(Math.max(0, len - s.length));
|
|
3293
|
+
console.log(y("\u250C" + "\u2500".repeat(W) + "\u2510"));
|
|
3294
|
+
console.log(y("\u2502") + pad(" \u{1F4A1} Log in for full wizard features:", W - 1) + y("\u2502"));
|
|
3295
|
+
console.log(y("\u2502") + " ".repeat(W) + y("\u2502"));
|
|
3296
|
+
console.log(y("\u2502") + pad(" \u2022 Commands & Code Style [PRO]", W) + y("\u2502"));
|
|
3297
|
+
console.log(y("\u2502") + pad(" \u2022 Boundaries, Testing, Static Files [MAX]", W) + y("\u2502"));
|
|
3298
|
+
console.log(y("\u2502") + pad(" \u2022 Push configs to cloud (lynxp push)", W) + y("\u2502"));
|
|
3299
|
+
console.log(y("\u2502") + pad(" \u2022 Sync across devices (lynxp sync)", W) + y("\u2502"));
|
|
3300
|
+
console.log(y("\u2502") + " ".repeat(W) + y("\u2502"));
|
|
3301
|
+
console.log(y("\u2502") + pad(" Run: " + chalk8.cyan("lynxp login"), W + 10) + y("\u2502"));
|
|
3302
|
+
console.log(y("\u2514" + "\u2500".repeat(W) + "\u2518"));
|
|
3303
|
+
console.log();
|
|
3304
|
+
} else {
|
|
3305
|
+
const planEmoji = userTier === "teams" ? "\u{1F465}" : userTier === "max" ? "\u{1F680}" : userTier === "pro" ? "\u26A1" : "\u{1F193}";
|
|
3306
|
+
console.log(chalk8.green(` \u2713 Logged in as ${chalk8.bold(user?.name || user?.email)} ${planEmoji} ${chalk8.gray(userPlanDisplay)}`));
|
|
3307
|
+
console.log();
|
|
3308
|
+
}
|
|
3309
|
+
showWizardOverview(userTier);
|
|
3310
|
+
const accessibleSteps = getAvailableSteps(userTier);
|
|
3311
|
+
const lockedSteps = WIZARD_STEPS.length - accessibleSteps.length;
|
|
3312
|
+
if (lockedSteps > 0) {
|
|
3313
|
+
console.log(chalk8.gray(` ${lockedSteps} step${lockedSteps > 1 ? "s" : ""} locked. Upgrade at ${chalk8.cyan("https://lynxprompt.com/pricing")}`));
|
|
3314
|
+
console.log();
|
|
3315
|
+
}
|
|
2370
3316
|
const detected = await detectProject(process.cwd());
|
|
2371
3317
|
if (detected) {
|
|
2372
3318
|
const detectedInfo = [
|
|
@@ -2398,7 +3344,7 @@ async function wizardCommand(options) {
|
|
|
2398
3344
|
commands: detected?.commands || {}
|
|
2399
3345
|
};
|
|
2400
3346
|
} else {
|
|
2401
|
-
config2 = await runInteractiveWizard(options, detected);
|
|
3347
|
+
config2 = await runInteractiveWizard(options, detected, userTier);
|
|
2402
3348
|
}
|
|
2403
3349
|
const spinner = ora7("Generating configuration...").start();
|
|
2404
3350
|
try {
|
|
@@ -2435,14 +3381,21 @@ async function wizardCommand(options) {
|
|
|
2435
3381
|
console.log(` ${chalk8.cyan("\u2192")} ${chalk8.bold(filename)}`);
|
|
2436
3382
|
}
|
|
2437
3383
|
console.log();
|
|
2438
|
-
|
|
3384
|
+
const nextStepsLines = [
|
|
2439
3385
|
chalk8.gray("Your AI assistant will now follow these instructions."),
|
|
2440
3386
|
"",
|
|
2441
3387
|
chalk8.gray("Next steps:"),
|
|
2442
|
-
chalk8.cyan(" lynxp check ") + chalk8.gray("Validate configuration")
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
|
|
3388
|
+
chalk8.cyan(" lynxp check ") + chalk8.gray("Validate configuration")
|
|
3389
|
+
];
|
|
3390
|
+
if (authenticated) {
|
|
3391
|
+
nextStepsLines.push(chalk8.cyan(" lynxp push ") + chalk8.gray("Upload to cloud"));
|
|
3392
|
+
nextStepsLines.push(chalk8.cyan(" lynxp link ") + chalk8.gray("Link to a blueprint"));
|
|
3393
|
+
nextStepsLines.push(chalk8.cyan(" lynxp sync ") + chalk8.gray("Sync with linked blueprint"));
|
|
3394
|
+
} else {
|
|
3395
|
+
nextStepsLines.push(chalk8.gray(" lynxp login ") + chalk8.yellow("Log in to push & sync"));
|
|
3396
|
+
}
|
|
3397
|
+
nextStepsLines.push(chalk8.cyan(" lynxp status ") + chalk8.gray("View current setup"));
|
|
3398
|
+
printBox(nextStepsLines, chalk8.gray);
|
|
2446
3399
|
console.log();
|
|
2447
3400
|
} catch (error) {
|
|
2448
3401
|
spinner.fail("Failed to generate files");
|
|
@@ -2454,54 +3407,49 @@ async function wizardCommand(options) {
|
|
|
2454
3407
|
process.exit(1);
|
|
2455
3408
|
}
|
|
2456
3409
|
}
|
|
2457
|
-
async function runInteractiveWizard(options, detected) {
|
|
3410
|
+
async function runInteractiveWizard(options, detected, userTier) {
|
|
2458
3411
|
const answers = {};
|
|
2459
|
-
const
|
|
2460
|
-
|
|
2461
|
-
|
|
2462
|
-
|
|
2463
|
-
|
|
3412
|
+
const availableSteps = getAvailableSteps(userTier);
|
|
3413
|
+
let currentStepNum = 0;
|
|
3414
|
+
const getCurrentStep = (stepId) => {
|
|
3415
|
+
const step = availableSteps.find((s) => s.id === stepId);
|
|
3416
|
+
if (step) {
|
|
3417
|
+
currentStepNum++;
|
|
3418
|
+
return step;
|
|
2464
3419
|
}
|
|
3420
|
+
return null;
|
|
2465
3421
|
};
|
|
2466
|
-
|
|
3422
|
+
const formatStep = getCurrentStep("format");
|
|
3423
|
+
showStep(currentStepNum, formatStep, userTier);
|
|
2467
3424
|
let platforms;
|
|
2468
3425
|
if (options.format) {
|
|
2469
3426
|
platforms = options.format.split(",").map((f) => f.trim());
|
|
2470
3427
|
console.log(chalk8.gray(` Using format from flag: ${platforms.join(", ")}`));
|
|
2471
3428
|
} else {
|
|
2472
|
-
|
|
2473
|
-
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
|
|
3429
|
+
console.log(chalk8.gray(" Select the AI editors you want to generate config for:"));
|
|
3430
|
+
console.log(chalk8.gray(" (AGENTS.md is recommended - works with most AI tools)"));
|
|
3431
|
+
console.log();
|
|
3432
|
+
const platformResponse = await prompts4({
|
|
3433
|
+
type: "multiselect",
|
|
3434
|
+
name: "platforms",
|
|
3435
|
+
message: chalk8.white("Select AI editors (16 supported):"),
|
|
3436
|
+
choices: ALL_PLATFORMS.map((p) => ({
|
|
3437
|
+
title: p.id === "agents" ? `${p.icon} ${p.name} ${chalk8.green.bold("\u2605 recommended")}` : `${p.icon} ${p.name}`,
|
|
3438
|
+
value: p.id,
|
|
3439
|
+
description: chalk8.gray(p.note),
|
|
3440
|
+
selected: p.id === "agents"
|
|
3441
|
+
// Pre-select AGENTS.md
|
|
2480
3442
|
})),
|
|
2481
|
-
|
|
2482
|
-
|
|
3443
|
+
hint: chalk8.gray("space select \u2022 a toggle all \u2022 enter confirm"),
|
|
3444
|
+
min: 1,
|
|
3445
|
+
instructions: false
|
|
2483
3446
|
}, promptConfig);
|
|
2484
|
-
|
|
2485
|
-
|
|
2486
|
-
const platformResponse = await prompts4({
|
|
2487
|
-
type: "multiselect",
|
|
2488
|
-
name: "platforms",
|
|
2489
|
-
message: chalk8.white("Select AI editors:"),
|
|
2490
|
-
choices: PLATFORMS.map((p) => ({
|
|
2491
|
-
title: p.title,
|
|
2492
|
-
value: p.value
|
|
2493
|
-
})),
|
|
2494
|
-
hint: chalk8.gray("space select \u2022 a toggle all \u2022 enter confirm"),
|
|
2495
|
-
min: 1,
|
|
2496
|
-
instructions: false
|
|
2497
|
-
}, promptConfig);
|
|
2498
|
-
platforms = platformResponse.platforms || ["agents"];
|
|
2499
|
-
} else {
|
|
2500
|
-
platforms = [formatResponse.format || "agents"];
|
|
2501
|
-
}
|
|
3447
|
+
platforms = platformResponse.platforms || ["agents"];
|
|
3448
|
+
console.log(chalk8.green(` \u2713 Selected ${platforms.length} platform${platforms.length === 1 ? "" : "s"}`));
|
|
2502
3449
|
}
|
|
2503
3450
|
answers.platforms = platforms;
|
|
2504
|
-
|
|
3451
|
+
const projectStep = getCurrentStep("project");
|
|
3452
|
+
showStep(currentStepNum, projectStep, userTier);
|
|
2505
3453
|
const nameResponse = await prompts4({
|
|
2506
3454
|
type: "text",
|
|
2507
3455
|
name: "name",
|
|
@@ -2518,73 +3466,582 @@ async function runInteractiveWizard(options, detected) {
|
|
|
2518
3466
|
hint: chalk8.gray("optional - helps AI understand context")
|
|
2519
3467
|
}, promptConfig);
|
|
2520
3468
|
answers.description = descResponse.description || "";
|
|
2521
|
-
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
|
|
2525
|
-
|
|
2526
|
-
|
|
3469
|
+
const typeResponse = await prompts4({
|
|
3470
|
+
type: "select",
|
|
3471
|
+
name: "projectType",
|
|
3472
|
+
message: chalk8.white("Project type:"),
|
|
3473
|
+
choices: [
|
|
3474
|
+
{ title: chalk8.gray("\u23ED Skip"), value: "" },
|
|
3475
|
+
...PROJECT_TYPES.map((t) => ({
|
|
3476
|
+
title: `${t.icon} ${t.label}`,
|
|
3477
|
+
value: t.id,
|
|
3478
|
+
description: chalk8.gray(t.description)
|
|
3479
|
+
}))
|
|
3480
|
+
],
|
|
3481
|
+
initial: 0
|
|
3482
|
+
}, promptConfig);
|
|
3483
|
+
answers.projectType = typeResponse.projectType || "";
|
|
3484
|
+
const devOsResponse = await prompts4({
|
|
3485
|
+
type: "select",
|
|
3486
|
+
name: "devOS",
|
|
3487
|
+
message: chalk8.white("Development environment:"),
|
|
3488
|
+
choices: [
|
|
3489
|
+
{ title: chalk8.gray("\u23ED Skip"), value: "" },
|
|
3490
|
+
...DEV_OS_OPTIONS.map((o) => ({
|
|
3491
|
+
title: `${o.icon} ${o.label}`,
|
|
3492
|
+
value: o.id
|
|
3493
|
+
}))
|
|
3494
|
+
],
|
|
3495
|
+
initial: 0,
|
|
3496
|
+
hint: chalk8.gray("Helps generate compatible commands")
|
|
3497
|
+
}, promptConfig);
|
|
3498
|
+
answers.devOS = devOsResponse.devOS || "";
|
|
3499
|
+
const archResponse = await prompts4({
|
|
3500
|
+
type: "select",
|
|
3501
|
+
name: "architecture",
|
|
3502
|
+
message: chalk8.white("Architecture pattern:"),
|
|
3503
|
+
choices: [
|
|
3504
|
+
{ title: chalk8.gray("\u23ED Skip"), value: "" },
|
|
3505
|
+
...ARCHITECTURE_PATTERNS.map((a) => ({
|
|
3506
|
+
title: a.label,
|
|
3507
|
+
value: a.id
|
|
3508
|
+
}))
|
|
3509
|
+
],
|
|
3510
|
+
initial: 0
|
|
3511
|
+
}, promptConfig);
|
|
3512
|
+
answers.architecture = archResponse.architecture || "";
|
|
3513
|
+
const techStep = getCurrentStep("tech");
|
|
3514
|
+
showStep(currentStepNum, techStep, userTier);
|
|
3515
|
+
const letAiResponse = await prompts4({
|
|
3516
|
+
type: "toggle",
|
|
3517
|
+
name: "letAiDecide",
|
|
3518
|
+
message: chalk8.white("Let AI help choose additional technologies?"),
|
|
3519
|
+
initial: false,
|
|
3520
|
+
active: "Yes",
|
|
3521
|
+
inactive: "No"
|
|
3522
|
+
}, promptConfig);
|
|
3523
|
+
answers.letAiDecide = letAiResponse.letAiDecide || false;
|
|
3524
|
+
console.log();
|
|
3525
|
+
console.log(chalk8.gray(" You can also select specific technologies below:"));
|
|
3526
|
+
console.log();
|
|
3527
|
+
const allStackOptions = [...LANGUAGES, ...FRAMEWORKS, ...DATABASES];
|
|
3528
|
+
if (detected?.stack && detected.stack.length > 0) {
|
|
3529
|
+
console.log(chalk8.gray(` Detected in project: ${detected.stack.join(", ")}`));
|
|
2527
3530
|
console.log();
|
|
2528
3531
|
}
|
|
2529
3532
|
const stackResponse = await prompts4({
|
|
2530
3533
|
type: "multiselect",
|
|
2531
3534
|
name: "stack",
|
|
2532
|
-
message: chalk8.white("
|
|
3535
|
+
message: chalk8.white("Languages, frameworks & databases:"),
|
|
2533
3536
|
choices: allStackOptions.map((s) => ({
|
|
2534
3537
|
title: s.title,
|
|
2535
|
-
value: s.value
|
|
2536
|
-
|
|
3538
|
+
value: s.value
|
|
3539
|
+
// No pre-selection - user must explicitly choose
|
|
2537
3540
|
})),
|
|
2538
3541
|
hint: chalk8.gray("space select \u2022 a toggle all \u2022 enter confirm"),
|
|
2539
3542
|
instructions: false
|
|
2540
3543
|
}, promptConfig);
|
|
2541
3544
|
answers.stack = stackResponse.stack || [];
|
|
2542
|
-
|
|
3545
|
+
const repoStep = getCurrentStep("repo");
|
|
3546
|
+
showStep(currentStepNum, repoStep, userTier);
|
|
3547
|
+
const repoHostResponse = await prompts4({
|
|
3548
|
+
type: "select",
|
|
3549
|
+
name: "repoHost",
|
|
3550
|
+
message: chalk8.white("Repository host:"),
|
|
3551
|
+
choices: [
|
|
3552
|
+
{ title: chalk8.gray("\u23ED Skip"), value: "" },
|
|
3553
|
+
...REPO_HOSTS.map((h) => ({
|
|
3554
|
+
title: `${h.icon} ${h.label}`,
|
|
3555
|
+
value: h.id
|
|
3556
|
+
}))
|
|
3557
|
+
],
|
|
3558
|
+
initial: 0
|
|
3559
|
+
}, promptConfig);
|
|
3560
|
+
answers.repoHost = repoHostResponse.repoHost || "";
|
|
3561
|
+
const visibilityResponse = await prompts4({
|
|
3562
|
+
type: "toggle",
|
|
3563
|
+
name: "isPublic",
|
|
3564
|
+
message: chalk8.white("Public repository?"),
|
|
3565
|
+
initial: false,
|
|
3566
|
+
active: "Yes",
|
|
3567
|
+
inactive: "No"
|
|
3568
|
+
}, promptConfig);
|
|
3569
|
+
answers.isPublic = visibilityResponse.isPublic || false;
|
|
3570
|
+
const licenseResponse = await prompts4({
|
|
3571
|
+
type: "select",
|
|
3572
|
+
name: "license",
|
|
3573
|
+
message: chalk8.white("License:"),
|
|
3574
|
+
choices: [
|
|
3575
|
+
{ title: chalk8.gray("\u23ED Skip"), value: "" },
|
|
3576
|
+
...LICENSES.map((l) => ({
|
|
3577
|
+
title: l.label,
|
|
3578
|
+
value: l.id
|
|
3579
|
+
}))
|
|
3580
|
+
],
|
|
3581
|
+
initial: 0
|
|
3582
|
+
}, promptConfig);
|
|
3583
|
+
answers.license = licenseResponse.license || "";
|
|
3584
|
+
const conventionalResponse = await prompts4({
|
|
3585
|
+
type: "toggle",
|
|
3586
|
+
name: "conventionalCommits",
|
|
3587
|
+
message: chalk8.white("Use Conventional Commits?"),
|
|
3588
|
+
initial: false,
|
|
3589
|
+
active: "Yes",
|
|
3590
|
+
inactive: "No"
|
|
3591
|
+
}, promptConfig);
|
|
3592
|
+
answers.conventionalCommits = conventionalResponse.conventionalCommits || false;
|
|
3593
|
+
const semverResponse = await prompts4({
|
|
3594
|
+
type: "toggle",
|
|
3595
|
+
name: "semver",
|
|
3596
|
+
message: chalk8.white("Use Semantic Versioning?"),
|
|
3597
|
+
initial: false,
|
|
3598
|
+
active: "Yes",
|
|
3599
|
+
inactive: "No"
|
|
3600
|
+
}, promptConfig);
|
|
3601
|
+
answers.semver = semverResponse.semver || false;
|
|
3602
|
+
if (answers.repoHost === "github" || answers.repoHost === "gitlab") {
|
|
3603
|
+
const dependabotResponse = await prompts4({
|
|
3604
|
+
type: "toggle",
|
|
3605
|
+
name: "dependabot",
|
|
3606
|
+
message: chalk8.white("Enable Dependabot/dependency updates?"),
|
|
3607
|
+
initial: false,
|
|
3608
|
+
active: "Yes",
|
|
3609
|
+
inactive: "No"
|
|
3610
|
+
}, promptConfig);
|
|
3611
|
+
answers.dependabot = dependabotResponse.dependabot || false;
|
|
3612
|
+
}
|
|
3613
|
+
const cicdResponse = await prompts4({
|
|
3614
|
+
type: "select",
|
|
3615
|
+
name: "cicd",
|
|
3616
|
+
message: chalk8.white("CI/CD Platform:"),
|
|
3617
|
+
choices: [
|
|
3618
|
+
{ title: chalk8.gray("\u23ED Skip"), value: "" },
|
|
3619
|
+
...CICD_OPTIONS.map((c) => ({
|
|
3620
|
+
title: `${c.icon} ${c.label}`,
|
|
3621
|
+
value: c.id
|
|
3622
|
+
}))
|
|
3623
|
+
],
|
|
3624
|
+
initial: 0
|
|
3625
|
+
}, promptConfig);
|
|
3626
|
+
answers.cicd = cicdResponse.cicd || "";
|
|
3627
|
+
const deployResponse = await prompts4({
|
|
3628
|
+
type: "multiselect",
|
|
3629
|
+
name: "deploymentTargets",
|
|
3630
|
+
message: chalk8.white("Deployment targets:"),
|
|
3631
|
+
choices: DEPLOYMENT_TARGETS.map((t) => ({
|
|
3632
|
+
title: `${t.icon} ${t.label}`,
|
|
3633
|
+
value: t.id
|
|
3634
|
+
})),
|
|
3635
|
+
hint: chalk8.gray("space select \u2022 enter to skip/confirm"),
|
|
3636
|
+
instructions: false
|
|
3637
|
+
}, promptConfig);
|
|
3638
|
+
answers.deploymentTargets = deployResponse.deploymentTargets || [];
|
|
3639
|
+
const containerResponse = await prompts4({
|
|
3640
|
+
type: "toggle",
|
|
3641
|
+
name: "buildContainer",
|
|
3642
|
+
message: chalk8.white("Build container images (Docker)?"),
|
|
3643
|
+
initial: false,
|
|
3644
|
+
active: "Yes",
|
|
3645
|
+
inactive: "No"
|
|
3646
|
+
}, promptConfig);
|
|
3647
|
+
answers.buildContainer = containerResponse.buildContainer || false;
|
|
3648
|
+
if (answers.buildContainer) {
|
|
3649
|
+
const registryResponse = await prompts4({
|
|
3650
|
+
type: "select",
|
|
3651
|
+
name: "containerRegistry",
|
|
3652
|
+
message: chalk8.white("Container registry:"),
|
|
3653
|
+
choices: [
|
|
3654
|
+
{ title: chalk8.gray("\u23ED Skip"), value: "" },
|
|
3655
|
+
...CONTAINER_REGISTRIES.map((r) => ({
|
|
3656
|
+
title: `${r.icon} ${r.label}`,
|
|
3657
|
+
value: r.id
|
|
3658
|
+
}))
|
|
3659
|
+
],
|
|
3660
|
+
initial: 0
|
|
3661
|
+
}, promptConfig);
|
|
3662
|
+
answers.containerRegistry = registryResponse.containerRegistry || "";
|
|
3663
|
+
}
|
|
3664
|
+
const exampleRepoResponse = await prompts4({
|
|
3665
|
+
type: "text",
|
|
3666
|
+
name: "exampleRepoUrl",
|
|
3667
|
+
message: chalk8.white("Example repository URL (optional):"),
|
|
3668
|
+
hint: chalk8.gray("A similar public repo for AI to learn from")
|
|
3669
|
+
}, promptConfig);
|
|
3670
|
+
answers.exampleRepoUrl = exampleRepoResponse.exampleRepoUrl || "";
|
|
3671
|
+
const docsUrlResponse = await prompts4({
|
|
3672
|
+
type: "text",
|
|
3673
|
+
name: "documentationUrl",
|
|
3674
|
+
message: chalk8.white("External documentation URL (optional):"),
|
|
3675
|
+
hint: chalk8.gray("Confluence, Notion, GitBook, etc.")
|
|
3676
|
+
}, promptConfig);
|
|
3677
|
+
answers.documentationUrl = docsUrlResponse.documentationUrl || "";
|
|
3678
|
+
if (canAccessTier(userTier, "intermediate")) {
|
|
3679
|
+
const commandsStep = getCurrentStep("commands");
|
|
3680
|
+
showStep(currentStepNum, commandsStep, userTier);
|
|
3681
|
+
console.log(chalk8.gray(" Select common commands for your project:"));
|
|
3682
|
+
console.log();
|
|
3683
|
+
const buildResponse = await prompts4({
|
|
3684
|
+
type: "multiselect",
|
|
3685
|
+
name: "build",
|
|
3686
|
+
message: chalk8.white("Build commands:"),
|
|
3687
|
+
choices: COMMON_COMMANDS.build.slice(0, 12).map((c) => ({
|
|
3688
|
+
title: chalk8.cyan(c),
|
|
3689
|
+
value: c,
|
|
3690
|
+
selected: detected?.commands?.build === c
|
|
3691
|
+
})),
|
|
3692
|
+
hint: chalk8.gray("space select \u2022 enter confirm"),
|
|
3693
|
+
instructions: false
|
|
3694
|
+
}, promptConfig);
|
|
3695
|
+
const testResponse = await prompts4({
|
|
3696
|
+
type: "multiselect",
|
|
3697
|
+
name: "test",
|
|
3698
|
+
message: chalk8.white("Test commands:"),
|
|
3699
|
+
choices: COMMON_COMMANDS.test.slice(0, 12).map((c) => ({
|
|
3700
|
+
title: chalk8.yellow(c),
|
|
3701
|
+
value: c,
|
|
3702
|
+
selected: detected?.commands?.test === c
|
|
3703
|
+
})),
|
|
3704
|
+
hint: chalk8.gray("space select \u2022 enter confirm"),
|
|
3705
|
+
instructions: false
|
|
3706
|
+
}, promptConfig);
|
|
3707
|
+
const lintResponse = await prompts4({
|
|
3708
|
+
type: "multiselect",
|
|
3709
|
+
name: "lint",
|
|
3710
|
+
message: chalk8.white("Lint/format commands:"),
|
|
3711
|
+
choices: COMMON_COMMANDS.lint.slice(0, 12).map((c) => ({
|
|
3712
|
+
title: chalk8.green(c),
|
|
3713
|
+
value: c,
|
|
3714
|
+
selected: detected?.commands?.lint === c
|
|
3715
|
+
})),
|
|
3716
|
+
hint: chalk8.gray("space select \u2022 enter confirm"),
|
|
3717
|
+
instructions: false
|
|
3718
|
+
}, promptConfig);
|
|
3719
|
+
const devResponse = await prompts4({
|
|
3720
|
+
type: "multiselect",
|
|
3721
|
+
name: "dev",
|
|
3722
|
+
message: chalk8.white("Dev server commands:"),
|
|
3723
|
+
choices: COMMON_COMMANDS.dev.slice(0, 12).map((c) => ({
|
|
3724
|
+
title: chalk8.magenta(c),
|
|
3725
|
+
value: c,
|
|
3726
|
+
selected: detected?.commands?.dev === c
|
|
3727
|
+
})),
|
|
3728
|
+
hint: chalk8.gray("space select \u2022 enter confirm"),
|
|
3729
|
+
instructions: false
|
|
3730
|
+
}, promptConfig);
|
|
3731
|
+
answers.commands = {
|
|
3732
|
+
build: buildResponse.build || [],
|
|
3733
|
+
test: testResponse.test || [],
|
|
3734
|
+
lint: lintResponse.lint || [],
|
|
3735
|
+
dev: devResponse.dev || []
|
|
3736
|
+
};
|
|
3737
|
+
const customCmdResponse = await prompts4({
|
|
3738
|
+
type: "text",
|
|
3739
|
+
name: "custom",
|
|
3740
|
+
message: chalk8.white("Additional custom command (optional):"),
|
|
3741
|
+
hint: chalk8.gray("e.g., npm run migrate, make deploy")
|
|
3742
|
+
}, promptConfig);
|
|
3743
|
+
if (customCmdResponse.custom) {
|
|
3744
|
+
answers.commands.custom = customCmdResponse.custom;
|
|
3745
|
+
}
|
|
3746
|
+
} else {
|
|
3747
|
+
answers.commands = detected?.commands || {};
|
|
3748
|
+
}
|
|
3749
|
+
if (canAccessTier(userTier, "intermediate")) {
|
|
3750
|
+
const styleStep = getCurrentStep("code_style");
|
|
3751
|
+
showStep(currentStepNum, styleStep, userTier);
|
|
3752
|
+
const namingResponse = await prompts4({
|
|
3753
|
+
type: "select",
|
|
3754
|
+
name: "naming",
|
|
3755
|
+
message: chalk8.white("Naming convention:"),
|
|
3756
|
+
choices: [
|
|
3757
|
+
{ title: chalk8.gray("\u23ED Skip"), value: "" },
|
|
3758
|
+
...NAMING_CONVENTIONS.map((n) => ({
|
|
3759
|
+
title: n.label,
|
|
3760
|
+
value: n.id,
|
|
3761
|
+
description: chalk8.gray(n.desc)
|
|
3762
|
+
}))
|
|
3763
|
+
],
|
|
3764
|
+
initial: 0
|
|
3765
|
+
}, promptConfig);
|
|
3766
|
+
answers.namingConvention = namingResponse.naming || "";
|
|
3767
|
+
const errorResponse = await prompts4({
|
|
3768
|
+
type: "select",
|
|
3769
|
+
name: "errorHandling",
|
|
3770
|
+
message: chalk8.white("Error handling pattern:"),
|
|
3771
|
+
choices: [
|
|
3772
|
+
{ title: chalk8.gray("\u23ED Skip"), value: "" },
|
|
3773
|
+
...ERROR_PATTERNS.map((e) => ({
|
|
3774
|
+
title: e.label,
|
|
3775
|
+
value: e.id
|
|
3776
|
+
}))
|
|
3777
|
+
],
|
|
3778
|
+
initial: 0
|
|
3779
|
+
}, promptConfig);
|
|
3780
|
+
answers.errorHandling = errorResponse.errorHandling || "";
|
|
3781
|
+
const loggingResponse = await prompts4({
|
|
3782
|
+
type: "text",
|
|
3783
|
+
name: "loggingConventions",
|
|
3784
|
+
message: chalk8.white("Logging conventions (optional):"),
|
|
3785
|
+
hint: chalk8.gray("e.g., use structured logging, JSON format, specific lib")
|
|
3786
|
+
}, promptConfig);
|
|
3787
|
+
answers.loggingConventions = loggingResponse.loggingConventions || "";
|
|
3788
|
+
const styleNotesResponse = await prompts4({
|
|
3789
|
+
type: "text",
|
|
3790
|
+
name: "styleNotes",
|
|
3791
|
+
message: chalk8.white("Additional style notes (optional):"),
|
|
3792
|
+
hint: chalk8.gray("e.g., prefer named exports, max line length 100")
|
|
3793
|
+
}, promptConfig);
|
|
3794
|
+
answers.styleNotes = styleNotesResponse.styleNotes || "";
|
|
3795
|
+
}
|
|
3796
|
+
const aiStep = getCurrentStep("ai");
|
|
3797
|
+
showStep(currentStepNum, aiStep, userTier);
|
|
3798
|
+
const aiBehaviorResponse = await prompts4({
|
|
3799
|
+
type: "multiselect",
|
|
3800
|
+
name: "aiBehavior",
|
|
3801
|
+
message: chalk8.white("AI behavior rules:"),
|
|
3802
|
+
choices: AI_BEHAVIOR_RULES.map((r) => ({
|
|
3803
|
+
title: r.recommended ? `${r.label} ${chalk8.green("\u2605 recommended")}` : r.label,
|
|
3804
|
+
value: r.id
|
|
3805
|
+
// No pre-selection - user must explicitly choose
|
|
3806
|
+
})),
|
|
3807
|
+
hint: chalk8.gray("space select \u2022 enter to skip/confirm"),
|
|
3808
|
+
instructions: false
|
|
3809
|
+
}, promptConfig);
|
|
3810
|
+
answers.aiBehavior = aiBehaviorResponse.aiBehavior || [];
|
|
3811
|
+
const importantFilesResponse = await prompts4({
|
|
3812
|
+
type: "multiselect",
|
|
3813
|
+
name: "importantFiles",
|
|
3814
|
+
message: chalk8.white("Important files AI should read:"),
|
|
3815
|
+
choices: IMPORTANT_FILES.map((f) => ({
|
|
3816
|
+
title: `${f.icon} ${f.label}`,
|
|
3817
|
+
value: f.id
|
|
3818
|
+
// No pre-selection - user must explicitly choose
|
|
3819
|
+
})),
|
|
3820
|
+
hint: chalk8.gray("space select \u2022 enter to skip/confirm"),
|
|
3821
|
+
instructions: false
|
|
3822
|
+
}, promptConfig);
|
|
3823
|
+
answers.importantFiles = importantFilesResponse.importantFiles || [];
|
|
3824
|
+
const selfImproveResponse = await prompts4({
|
|
3825
|
+
type: "toggle",
|
|
3826
|
+
name: "selfImprove",
|
|
3827
|
+
message: chalk8.white("Enable self-improving blueprint?"),
|
|
3828
|
+
initial: false,
|
|
3829
|
+
active: "Yes",
|
|
3830
|
+
inactive: "No"
|
|
3831
|
+
}, promptConfig);
|
|
3832
|
+
answers.selfImprove = selfImproveResponse.selfImprove || false;
|
|
3833
|
+
const includePersonalResponse = await prompts4({
|
|
3834
|
+
type: "toggle",
|
|
3835
|
+
name: "includePersonalData",
|
|
3836
|
+
message: chalk8.white("Include personal data (name/email for commits)?"),
|
|
3837
|
+
initial: false,
|
|
3838
|
+
active: "Yes",
|
|
3839
|
+
inactive: "No"
|
|
3840
|
+
}, promptConfig);
|
|
3841
|
+
answers.includePersonalData = includePersonalResponse.includePersonalData || false;
|
|
3842
|
+
if (canAccessTier(userTier, "advanced")) {
|
|
3843
|
+
const boundariesStep = getCurrentStep("boundaries");
|
|
3844
|
+
showStep(currentStepNum, boundariesStep, userTier);
|
|
3845
|
+
const presetResponse = await prompts4({
|
|
3846
|
+
type: "select",
|
|
3847
|
+
name: "boundaryPreset",
|
|
3848
|
+
message: chalk8.white("Boundary preset:"),
|
|
3849
|
+
choices: [
|
|
3850
|
+
{ title: chalk8.gray("\u23ED Skip"), value: "" },
|
|
3851
|
+
...BOUNDARY_PRESETS.map((b) => ({
|
|
3852
|
+
title: b.title,
|
|
3853
|
+
value: b.value,
|
|
3854
|
+
description: chalk8.gray(b.description)
|
|
3855
|
+
}))
|
|
3856
|
+
],
|
|
3857
|
+
initial: 0
|
|
3858
|
+
}, promptConfig);
|
|
3859
|
+
answers.boundaries = presetResponse.boundaryPreset || "";
|
|
3860
|
+
const selectedPreset = BOUNDARY_PRESETS.find((b) => b.value === answers.boundaries);
|
|
3861
|
+
if (selectedPreset) {
|
|
3862
|
+
console.log();
|
|
3863
|
+
console.log(chalk8.gray(" Preset details:"));
|
|
3864
|
+
console.log(chalk8.green(` \u2713 Always: ${selectedPreset.always.slice(0, 3).join(", ")}`));
|
|
3865
|
+
console.log(chalk8.yellow(` ? Ask: ${selectedPreset.askFirst.slice(0, 2).join(", ")}`));
|
|
3866
|
+
console.log(chalk8.red(` \u2717 Never: ${selectedPreset.never.slice(0, 2).join(", ")}`));
|
|
3867
|
+
}
|
|
3868
|
+
const customizeResponse = await prompts4({
|
|
3869
|
+
type: "toggle",
|
|
3870
|
+
name: "customize",
|
|
3871
|
+
message: chalk8.white("Customize specific boundaries?"),
|
|
3872
|
+
initial: false,
|
|
3873
|
+
active: "Yes",
|
|
3874
|
+
inactive: "No"
|
|
3875
|
+
}, promptConfig);
|
|
3876
|
+
if (customizeResponse.customize) {
|
|
3877
|
+
console.log();
|
|
3878
|
+
console.log(chalk8.gray(" Select actions AI should NEVER do:"));
|
|
3879
|
+
const neverResponse = await prompts4({
|
|
3880
|
+
type: "multiselect",
|
|
3881
|
+
name: "never",
|
|
3882
|
+
message: chalk8.white("Never allow:"),
|
|
3883
|
+
choices: BOUNDARY_OPTIONS.map((o) => ({
|
|
3884
|
+
title: chalk8.red(o),
|
|
3885
|
+
value: o,
|
|
3886
|
+
selected: selectedPreset?.never.includes(o)
|
|
3887
|
+
})),
|
|
3888
|
+
instructions: false
|
|
3889
|
+
}, promptConfig);
|
|
3890
|
+
answers.boundaryNever = neverResponse.never || [];
|
|
3891
|
+
console.log(chalk8.gray(" Select actions AI should ASK before doing:"));
|
|
3892
|
+
const askResponse = await prompts4({
|
|
3893
|
+
type: "multiselect",
|
|
3894
|
+
name: "ask",
|
|
3895
|
+
message: chalk8.white("Ask first:"),
|
|
3896
|
+
choices: BOUNDARY_OPTIONS.filter((o) => !answers.boundaryNever?.includes(o)).map((o) => ({
|
|
3897
|
+
title: chalk8.yellow(o),
|
|
3898
|
+
value: o,
|
|
3899
|
+
selected: selectedPreset?.askFirst.includes(o)
|
|
3900
|
+
})),
|
|
3901
|
+
instructions: false
|
|
3902
|
+
}, promptConfig);
|
|
3903
|
+
answers.boundaryAsk = askResponse.ask || [];
|
|
3904
|
+
}
|
|
3905
|
+
} else {
|
|
3906
|
+
answers.boundaries = options.boundaries || "standard";
|
|
3907
|
+
}
|
|
3908
|
+
if (canAccessTier(userTier, "advanced")) {
|
|
3909
|
+
const testingStep = getCurrentStep("testing");
|
|
3910
|
+
showStep(currentStepNum, testingStep, userTier);
|
|
3911
|
+
const testLevelsResponse = await prompts4({
|
|
3912
|
+
type: "multiselect",
|
|
3913
|
+
name: "testLevels",
|
|
3914
|
+
message: chalk8.white("Test levels:"),
|
|
3915
|
+
choices: TEST_LEVELS.map((l) => ({
|
|
3916
|
+
title: `${l.label} - ${chalk8.gray(l.desc)}`,
|
|
3917
|
+
value: l.id,
|
|
3918
|
+
selected: l.id === "unit" || l.id === "integration"
|
|
3919
|
+
})),
|
|
3920
|
+
instructions: false
|
|
3921
|
+
}, promptConfig);
|
|
3922
|
+
answers.testLevels = testLevelsResponse.testLevels || [];
|
|
3923
|
+
const detectedFrameworks = answers.stack?.includes("typescript") || answers.stack?.includes("javascript") ? ["jest", "vitest"] : answers.stack?.includes("python") ? ["pytest"] : [];
|
|
3924
|
+
const testFrameworkResponse = await prompts4({
|
|
3925
|
+
type: "multiselect",
|
|
3926
|
+
name: "testFrameworks",
|
|
3927
|
+
message: chalk8.white("Testing frameworks:"),
|
|
3928
|
+
choices: TEST_FRAMEWORKS.slice(0, 16).map((f) => ({
|
|
3929
|
+
title: f,
|
|
3930
|
+
value: f,
|
|
3931
|
+
selected: detectedFrameworks.includes(f)
|
|
3932
|
+
})),
|
|
3933
|
+
hint: chalk8.gray("space select \u2022 enter confirm"),
|
|
3934
|
+
instructions: false
|
|
3935
|
+
}, promptConfig);
|
|
3936
|
+
answers.testFrameworks = testFrameworkResponse.testFrameworks || [];
|
|
3937
|
+
const coverageResponse = await prompts4({
|
|
3938
|
+
type: "number",
|
|
3939
|
+
name: "coverage",
|
|
3940
|
+
message: chalk8.white("Target code coverage (%):"),
|
|
3941
|
+
initial: 80,
|
|
3942
|
+
min: 0,
|
|
3943
|
+
max: 100
|
|
3944
|
+
}, promptConfig);
|
|
3945
|
+
answers.coverageTarget = coverageResponse.coverage ?? 80;
|
|
3946
|
+
const testNotesResponse = await prompts4({
|
|
3947
|
+
type: "text",
|
|
3948
|
+
name: "testNotes",
|
|
3949
|
+
message: chalk8.white("Testing notes (optional):"),
|
|
3950
|
+
hint: chalk8.gray("e.g., run e2e on main only, use msw for mocking")
|
|
3951
|
+
}, promptConfig);
|
|
3952
|
+
answers.testNotes = testNotesResponse.testNotes || "";
|
|
3953
|
+
}
|
|
3954
|
+
if (canAccessTier(userTier, "advanced")) {
|
|
3955
|
+
const staticStep = getCurrentStep("static");
|
|
3956
|
+
showStep(currentStepNum, staticStep, userTier);
|
|
3957
|
+
console.log(chalk8.gray(" Generate additional project files:"));
|
|
3958
|
+
console.log();
|
|
3959
|
+
const STATIC_FILE_OPTIONS = [
|
|
3960
|
+
{ title: "\u{1F4DD} .editorconfig", value: "editorconfig", desc: "Consistent code formatting", file: ".editorconfig" },
|
|
3961
|
+
{ title: "\u{1F91D} CONTRIBUTING.md", value: "contributing", desc: "Contributor guidelines", file: "CONTRIBUTING.md" },
|
|
3962
|
+
{ title: "\u{1F4DC} CODE_OF_CONDUCT.md", value: "codeOfConduct", desc: "Community standards", file: "CODE_OF_CONDUCT.md" },
|
|
3963
|
+
{ title: "\u{1F512} SECURITY.md", value: "security", desc: "Vulnerability reporting", file: "SECURITY.md" },
|
|
3964
|
+
{ title: "\u{1F5FA}\uFE0F ROADMAP.md", value: "roadmap", desc: "Project roadmap", file: "ROADMAP.md" },
|
|
3965
|
+
{ title: "\u{1F4CB} .gitignore", value: "gitignore", desc: "Git ignore patterns", file: ".gitignore" },
|
|
3966
|
+
{ title: "\u{1F4B0} FUNDING.yml", value: "funding", desc: "GitHub Sponsors config", file: ".github/FUNDING.yml" },
|
|
3967
|
+
{ title: "\u{1F4C4} LICENSE", value: "license", desc: "License file", file: "LICENSE" },
|
|
3968
|
+
{ title: "\u{1F4D6} README.md", value: "readme", desc: "Project readme", file: "README.md" },
|
|
3969
|
+
{ title: "\u{1F3D7}\uFE0F ARCHITECTURE.md", value: "architecture", desc: "Architecture docs", file: "ARCHITECTURE.md" },
|
|
3970
|
+
{ title: "\u{1F4DD} CHANGELOG.md", value: "changelog", desc: "Version history", file: "CHANGELOG.md" }
|
|
3971
|
+
];
|
|
3972
|
+
const staticFilesResponse = await prompts4({
|
|
3973
|
+
type: "multiselect",
|
|
3974
|
+
name: "staticFiles",
|
|
3975
|
+
message: chalk8.white("Include static files:"),
|
|
3976
|
+
choices: STATIC_FILE_OPTIONS.map((f) => ({
|
|
3977
|
+
title: f.title,
|
|
3978
|
+
value: f.value,
|
|
3979
|
+
description: chalk8.gray(f.desc)
|
|
3980
|
+
})),
|
|
3981
|
+
hint: chalk8.gray("space select \u2022 enter to skip/confirm"),
|
|
3982
|
+
instructions: false
|
|
3983
|
+
}, promptConfig);
|
|
3984
|
+
answers.staticFiles = staticFilesResponse.staticFiles || [];
|
|
3985
|
+
if (answers.staticFiles?.length > 0) {
|
|
3986
|
+
console.log();
|
|
3987
|
+
console.log(chalk8.cyan(" \u{1F4DD} Customize file contents (press Enter to use defaults):"));
|
|
3988
|
+
console.log(chalk8.gray(" You can paste content or leave empty for auto-generated defaults."));
|
|
3989
|
+
console.log();
|
|
3990
|
+
answers.staticFileContents = {};
|
|
3991
|
+
for (const fileKey of answers.staticFiles) {
|
|
3992
|
+
const fileInfo = STATIC_FILE_OPTIONS.find((f) => f.value === fileKey);
|
|
3993
|
+
if (!fileInfo) continue;
|
|
3994
|
+
const contentResponse = await prompts4({
|
|
3995
|
+
type: "text",
|
|
3996
|
+
name: "content",
|
|
3997
|
+
message: chalk8.white(`Content for ${fileInfo.file}:`),
|
|
3998
|
+
hint: chalk8.gray("paste content or Enter to skip")
|
|
3999
|
+
}, promptConfig);
|
|
4000
|
+
if (contentResponse.content && contentResponse.content.trim()) {
|
|
4001
|
+
answers.staticFileContents[fileKey] = contentResponse.content;
|
|
4002
|
+
}
|
|
4003
|
+
}
|
|
4004
|
+
}
|
|
4005
|
+
}
|
|
4006
|
+
const extraStep = getCurrentStep("extra");
|
|
4007
|
+
showStep(currentStepNum, extraStep, userTier);
|
|
2543
4008
|
const personaResponse = await prompts4({
|
|
2544
4009
|
type: "select",
|
|
2545
4010
|
name: "persona",
|
|
2546
|
-
message: chalk8.white("
|
|
2547
|
-
choices:
|
|
2548
|
-
title:
|
|
2549
|
-
value:
|
|
2550
|
-
description: chalk8.gray(
|
|
2551
|
-
|
|
2552
|
-
|
|
2553
|
-
|
|
4011
|
+
message: chalk8.white("AI assistant persona:"),
|
|
4012
|
+
choices: [
|
|
4013
|
+
{ title: chalk8.gray("\u23ED Skip"), value: "" },
|
|
4014
|
+
{ title: "\u{1F9D1}\u200D\u{1F4BB} Full-Stack Developer", value: "fullstack", description: chalk8.gray("Complete application development") },
|
|
4015
|
+
{ title: "\u2699\uFE0F Backend Developer", value: "backend", description: chalk8.gray("APIs, databases, services") },
|
|
4016
|
+
{ title: "\u{1F3A8} Frontend Developer", value: "frontend", description: chalk8.gray("UI, components, styling") },
|
|
4017
|
+
{ title: "\u{1F680} DevOps Engineer", value: "devops", description: chalk8.gray("Infrastructure, CI/CD") },
|
|
4018
|
+
{ title: "\u{1F4CA} Data Engineer", value: "data", description: chalk8.gray("Pipelines, ETL, analytics") },
|
|
4019
|
+
{ title: "\u{1F512} Security Engineer", value: "security", description: chalk8.gray("Secure code, auditing") },
|
|
4020
|
+
{ title: "\u270F\uFE0F Custom...", value: "custom", description: chalk8.gray("Define your own") }
|
|
4021
|
+
],
|
|
4022
|
+
initial: 0
|
|
2554
4023
|
}, promptConfig);
|
|
2555
4024
|
if (personaResponse.persona === "custom") {
|
|
2556
4025
|
const customPersona = await prompts4({
|
|
2557
4026
|
type: "text",
|
|
2558
4027
|
name: "value",
|
|
2559
4028
|
message: chalk8.white("Describe the custom persona:"),
|
|
2560
|
-
hint: chalk8.gray("e.g., 'ML engineer focused on PyTorch
|
|
4029
|
+
hint: chalk8.gray("e.g., 'ML engineer focused on PyTorch'")
|
|
2561
4030
|
}, promptConfig);
|
|
2562
|
-
answers.persona = customPersona.value || "
|
|
4031
|
+
answers.persona = customPersona.value || "";
|
|
2563
4032
|
} else {
|
|
2564
|
-
answers.persona = personaResponse.persona || "
|
|
4033
|
+
answers.persona = personaResponse.persona || "";
|
|
2565
4034
|
}
|
|
2566
|
-
|
|
2567
|
-
|
|
2568
|
-
|
|
2569
|
-
|
|
2570
|
-
|
|
2571
|
-
choices: BOUNDARY_PRESETS.map((b) => ({
|
|
2572
|
-
title: b.title,
|
|
2573
|
-
value: b.value,
|
|
2574
|
-
description: chalk8.gray(b.description)
|
|
2575
|
-
})),
|
|
2576
|
-
initial: 0,
|
|
2577
|
-
hint: chalk8.gray("\u2191\u2193 navigate \u2022 enter select")
|
|
4035
|
+
const extraNotesResponse = await prompts4({
|
|
4036
|
+
type: "text",
|
|
4037
|
+
name: "extraNotes",
|
|
4038
|
+
message: chalk8.white("Anything else AI should know? (optional):"),
|
|
4039
|
+
hint: chalk8.gray("Special requirements, gotchas, team conventions...")
|
|
2578
4040
|
}, promptConfig);
|
|
2579
|
-
answers.
|
|
2580
|
-
|
|
2581
|
-
|
|
2582
|
-
|
|
2583
|
-
console.log(chalk8.gray(" Always allowed: ") + chalk8.green(selectedBoundary.always.slice(0, 2).join(", ")));
|
|
2584
|
-
console.log(chalk8.gray(" Ask first: ") + chalk8.yellow(selectedBoundary.askFirst.slice(0, 2).join(", ")));
|
|
2585
|
-
console.log(chalk8.gray(" Never: ") + chalk8.red(selectedBoundary.never.slice(0, 2).join(", ")));
|
|
2586
|
-
}
|
|
2587
|
-
answers.commands = detected?.commands || {};
|
|
4041
|
+
answers.extraNotes = extraNotesResponse.extraNotes || "";
|
|
4042
|
+
console.log();
|
|
4043
|
+
console.log(chalk8.green(" \u2705 All steps completed!"));
|
|
4044
|
+
console.log();
|
|
2588
4045
|
return {
|
|
2589
4046
|
name: answers.name,
|
|
2590
4047
|
description: answers.description,
|
|
@@ -2592,7 +4049,30 @@ async function runInteractiveWizard(options, detected) {
|
|
|
2592
4049
|
platforms: answers.platforms,
|
|
2593
4050
|
persona: answers.persona,
|
|
2594
4051
|
boundaries: answers.boundaries,
|
|
2595
|
-
commands: answers.commands
|
|
4052
|
+
commands: typeof answers.commands === "object" ? answers.commands : detected?.commands || {},
|
|
4053
|
+
// Extended config for Pro/Max users
|
|
4054
|
+
projectType: answers.projectType,
|
|
4055
|
+
devOS: answers.devOS,
|
|
4056
|
+
architecture: answers.architecture,
|
|
4057
|
+
repoHost: answers.repoHost,
|
|
4058
|
+
isPublic: answers.isPublic,
|
|
4059
|
+
license: answers.license,
|
|
4060
|
+
conventionalCommits: answers.conventionalCommits,
|
|
4061
|
+
namingConvention: answers.namingConvention,
|
|
4062
|
+
errorHandling: answers.errorHandling,
|
|
4063
|
+
styleNotes: answers.styleNotes,
|
|
4064
|
+
aiBehavior: answers.aiBehavior,
|
|
4065
|
+
importantFiles: answers.importantFiles,
|
|
4066
|
+
selfImprove: answers.selfImprove,
|
|
4067
|
+
boundaryNever: answers.boundaryNever,
|
|
4068
|
+
boundaryAsk: answers.boundaryAsk,
|
|
4069
|
+
testLevels: answers.testLevels,
|
|
4070
|
+
testFrameworks: answers.testFrameworks,
|
|
4071
|
+
coverageTarget: answers.coverageTarget,
|
|
4072
|
+
testNotes: answers.testNotes,
|
|
4073
|
+
staticFiles: answers.staticFiles,
|
|
4074
|
+
includeFunding: answers.includeFunding,
|
|
4075
|
+
extraNotes: answers.extraNotes
|
|
2596
4076
|
};
|
|
2597
4077
|
}
|
|
2598
4078
|
|