lynxprompt 0.4.0 → 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 +695 -128
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -264,15 +264,18 @@ function displayWelcome(user) {
|
|
|
264
264
|
TEAMS: { color: chalk.yellow, emoji: "\u{1F465}", badge: "Teams" }
|
|
265
265
|
};
|
|
266
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));
|
|
267
270
|
console.log();
|
|
268
|
-
console.log(
|
|
269
|
-
console.log(
|
|
270
|
-
console.log(
|
|
271
|
-
console.log(
|
|
272
|
-
console.log(
|
|
273
|
-
console.log(
|
|
274
|
-
console.log(
|
|
275
|
-
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"));
|
|
276
279
|
console.log();
|
|
277
280
|
console.log(chalk.bold("\u{1F4CB} Your CLI Capabilities:"));
|
|
278
281
|
console.log();
|
|
@@ -2163,6 +2166,259 @@ var TEST_LEVEL_DESCRIPTIONS = {
|
|
|
2163
2166
|
integration: "Integration tests for component interactions",
|
|
2164
2167
|
e2e: "End-to-end tests for full user flows"
|
|
2165
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
|
+
};
|
|
2166
2422
|
function generateConfig(options) {
|
|
2167
2423
|
const files = {};
|
|
2168
2424
|
for (const platform of options.platforms) {
|
|
@@ -2171,6 +2427,23 @@ function generateConfig(options) {
|
|
|
2171
2427
|
files[filename] = generateFileContent(options, platform);
|
|
2172
2428
|
}
|
|
2173
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
|
+
}
|
|
2174
2447
|
return files;
|
|
2175
2448
|
}
|
|
2176
2449
|
function generateFileContent(options, platform) {
|
|
@@ -2243,9 +2516,15 @@ function generateFileContent(options, platform) {
|
|
|
2243
2516
|
}
|
|
2244
2517
|
sections.push("");
|
|
2245
2518
|
}
|
|
2246
|
-
if (options.
|
|
2519
|
+
if (options.letAiDecide) {
|
|
2247
2520
|
if (isMarkdown || isMdc) {
|
|
2248
|
-
sections.push("
|
|
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");
|
|
2249
2528
|
sections.push("");
|
|
2250
2529
|
if (options.repoHost) {
|
|
2251
2530
|
sections.push(`- **Host:** ${options.repoHost.charAt(0).toUpperCase() + options.repoHost.slice(1)}`);
|
|
@@ -2256,6 +2535,68 @@ function generateFileContent(options, platform) {
|
|
|
2256
2535
|
if (options.conventionalCommits) {
|
|
2257
2536
|
sections.push("- **Commits:** Follow [Conventional Commits](https://conventionalcommits.org) format");
|
|
2258
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
|
+
}
|
|
2259
2600
|
sections.push("");
|
|
2260
2601
|
}
|
|
2261
2602
|
}
|
|
@@ -2326,6 +2667,14 @@ function generateFileContent(options, platform) {
|
|
|
2326
2667
|
sections.push("");
|
|
2327
2668
|
}
|
|
2328
2669
|
}
|
|
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
|
+
}
|
|
2329
2678
|
let boundaries = BOUNDARIES[options.boundaries];
|
|
2330
2679
|
if (options.boundaryNever?.length || options.boundaryAsk?.length) {
|
|
2331
2680
|
boundaries = {
|
|
@@ -2395,6 +2744,9 @@ function generateFileContent(options, platform) {
|
|
|
2395
2744
|
sections.push(`- **Errors:** ${errorStyles[options.errorHandling]}`);
|
|
2396
2745
|
}
|
|
2397
2746
|
}
|
|
2747
|
+
if (options.loggingConventions) {
|
|
2748
|
+
sections.push(`- **Logging:** ${options.loggingConventions}`);
|
|
2749
|
+
}
|
|
2398
2750
|
if (options.styleNotes) {
|
|
2399
2751
|
sections.push(`- **Notes:** ${options.styleNotes}`);
|
|
2400
2752
|
}
|
|
@@ -2557,14 +2909,6 @@ var ALL_PLATFORMS = [
|
|
|
2557
2909
|
{ id: "void", name: "Void", file: ".void/config.json", icon: "\u{1F573}\uFE0F", note: "Open-source Cursor alt" },
|
|
2558
2910
|
{ id: "goose", name: "Goose", file: ".goosehints", icon: "\u{1FABF}", note: "Block AI agent" }
|
|
2559
2911
|
];
|
|
2560
|
-
var OUTPUT_FORMATS = [
|
|
2561
|
-
{ title: "\u{1F310} AGENTS.md (Universal)", value: "agents", description: "Works with Claude, Copilot, Aider, Devin & more", recommended: true },
|
|
2562
|
-
{ title: "\u26A1 Cursor", value: "cursor", description: ".cursor/rules/ native format" },
|
|
2563
|
-
{ title: "\u{1F9E0} Claude Code", value: "claude", description: "CLAUDE.md format" },
|
|
2564
|
-
{ title: "\u{1F419} GitHub Copilot", value: "copilot", description: ".github/copilot-instructions.md" },
|
|
2565
|
-
{ title: "\u{1F3C4} Windsurf", value: "windsurf", description: ".windsurfrules configuration" },
|
|
2566
|
-
{ title: "\u{1F4E6} Multiple platforms...", value: "multiple", description: "Select from 16+ supported AI editors" }
|
|
2567
|
-
];
|
|
2568
2912
|
var LANGUAGES = [
|
|
2569
2913
|
{ title: "\u{1F537} TypeScript", value: "typescript" },
|
|
2570
2914
|
{ title: "\u{1F7E1} JavaScript", value: "javascript" },
|
|
@@ -2625,6 +2969,42 @@ var LICENSES = [
|
|
|
2625
2969
|
{ id: "unlicense", label: "Unlicense" },
|
|
2626
2970
|
{ id: "none", label: "None / Proprietary" }
|
|
2627
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
|
+
];
|
|
2628
3008
|
var COMMON_COMMANDS = {
|
|
2629
3009
|
build: [
|
|
2630
3010
|
"npm run build",
|
|
@@ -2806,6 +3186,23 @@ var PROJECT_TYPES = [
|
|
|
2806
3186
|
{ id: "opensource", label: "Open Source", icon: "\u{1F30D}", description: "Community-driven project" },
|
|
2807
3187
|
{ id: "learning", label: "Learning", icon: "\u{1F4DA}", description: "Educational/experimental" }
|
|
2808
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
|
+
];
|
|
2809
3206
|
function canAccessTier(userTier, requiredTier) {
|
|
2810
3207
|
const tierLevels = { free: 0, pro: 1, max: 2, teams: 2 };
|
|
2811
3208
|
const requiredLevels = { basic: 0, intermediate: 1, advanced: 2 };
|
|
@@ -2890,16 +3287,19 @@ async function wizardCommand(options) {
|
|
|
2890
3287
|
const userTier = ["pro", "max", "teams"].includes(userPlanRaw) ? userPlanRaw : "free";
|
|
2891
3288
|
const userPlanDisplay = user?.plan?.toUpperCase() || "FREE";
|
|
2892
3289
|
if (!authenticated) {
|
|
2893
|
-
|
|
2894
|
-
|
|
2895
|
-
|
|
2896
|
-
console.log(
|
|
2897
|
-
console.log(
|
|
2898
|
-
console.log(
|
|
2899
|
-
console.log(
|
|
2900
|
-
console.log(
|
|
2901
|
-
console.log(
|
|
2902
|
-
console.log(
|
|
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"));
|
|
2903
3303
|
console.log();
|
|
2904
3304
|
} else {
|
|
2905
3305
|
const planEmoji = userTier === "teams" ? "\u{1F465}" : userTier === "max" ? "\u{1F680}" : userTier === "pro" ? "\u26A1" : "\u{1F193}";
|
|
@@ -3026,40 +3426,26 @@ async function runInteractiveWizard(options, detected, userTier) {
|
|
|
3026
3426
|
platforms = options.format.split(",").map((f) => f.trim());
|
|
3027
3427
|
console.log(chalk8.gray(` Using format from flag: ${platforms.join(", ")}`));
|
|
3028
3428
|
} else {
|
|
3029
|
-
|
|
3030
|
-
|
|
3031
|
-
|
|
3032
|
-
|
|
3033
|
-
|
|
3034
|
-
|
|
3035
|
-
|
|
3036
|
-
|
|
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
|
|
3037
3442
|
})),
|
|
3038
|
-
|
|
3039
|
-
|
|
3443
|
+
hint: chalk8.gray("space select \u2022 a toggle all \u2022 enter confirm"),
|
|
3444
|
+
min: 1,
|
|
3445
|
+
instructions: false
|
|
3040
3446
|
}, promptConfig);
|
|
3041
|
-
|
|
3042
|
-
|
|
3043
|
-
console.log(chalk8.gray(" Select the AI editors you want to generate config for:"));
|
|
3044
|
-
console.log();
|
|
3045
|
-
const platformResponse = await prompts4({
|
|
3046
|
-
type: "multiselect",
|
|
3047
|
-
name: "platforms",
|
|
3048
|
-
message: chalk8.white("Select AI editors (16 supported):"),
|
|
3049
|
-
choices: ALL_PLATFORMS.map((p) => ({
|
|
3050
|
-
title: `${p.icon} ${p.name}`,
|
|
3051
|
-
value: p.id,
|
|
3052
|
-
description: chalk8.gray(p.note)
|
|
3053
|
-
})),
|
|
3054
|
-
hint: chalk8.gray("space select \u2022 a toggle all \u2022 enter confirm"),
|
|
3055
|
-
min: 1,
|
|
3056
|
-
instructions: false
|
|
3057
|
-
}, promptConfig);
|
|
3058
|
-
platforms = platformResponse.platforms || ["agents"];
|
|
3059
|
-
console.log(chalk8.green(` \u2713 Selected ${platforms.length} platform${platforms.length === 1 ? "" : "s"}`));
|
|
3060
|
-
} else {
|
|
3061
|
-
platforms = [formatResponse.format || "agents"];
|
|
3062
|
-
}
|
|
3447
|
+
platforms = platformResponse.platforms || ["agents"];
|
|
3448
|
+
console.log(chalk8.green(` \u2713 Selected ${platforms.length} platform${platforms.length === 1 ? "" : "s"}`));
|
|
3063
3449
|
}
|
|
3064
3450
|
answers.platforms = platforms;
|
|
3065
3451
|
const projectStep = getCurrentStep("project");
|
|
@@ -3084,20 +3470,63 @@ async function runInteractiveWizard(options, detected, userTier) {
|
|
|
3084
3470
|
type: "select",
|
|
3085
3471
|
name: "projectType",
|
|
3086
3472
|
message: chalk8.white("Project type:"),
|
|
3087
|
-
choices:
|
|
3088
|
-
title:
|
|
3089
|
-
|
|
3090
|
-
|
|
3091
|
-
|
|
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
|
+
],
|
|
3092
3481
|
initial: 0
|
|
3093
3482
|
}, promptConfig);
|
|
3094
|
-
answers.projectType = typeResponse.projectType || "
|
|
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 || "";
|
|
3095
3513
|
const techStep = getCurrentStep("tech");
|
|
3096
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();
|
|
3097
3527
|
const allStackOptions = [...LANGUAGES, ...FRAMEWORKS, ...DATABASES];
|
|
3098
|
-
|
|
3099
|
-
|
|
3100
|
-
console.log(chalk8.gray(` Auto-selected: ${detected?.stack?.join(", ")}`));
|
|
3528
|
+
if (detected?.stack && detected.stack.length > 0) {
|
|
3529
|
+
console.log(chalk8.gray(` Detected in project: ${detected.stack.join(", ")}`));
|
|
3101
3530
|
console.log();
|
|
3102
3531
|
}
|
|
3103
3532
|
const stackResponse = await prompts4({
|
|
@@ -3106,8 +3535,8 @@ async function runInteractiveWizard(options, detected, userTier) {
|
|
|
3106
3535
|
message: chalk8.white("Languages, frameworks & databases:"),
|
|
3107
3536
|
choices: allStackOptions.map((s) => ({
|
|
3108
3537
|
title: s.title,
|
|
3109
|
-
value: s.value
|
|
3110
|
-
|
|
3538
|
+
value: s.value
|
|
3539
|
+
// No pre-selection - user must explicitly choose
|
|
3111
3540
|
})),
|
|
3112
3541
|
hint: chalk8.gray("space select \u2022 a toggle all \u2022 enter confirm"),
|
|
3113
3542
|
instructions: false
|
|
@@ -3119,13 +3548,16 @@ async function runInteractiveWizard(options, detected, userTier) {
|
|
|
3119
3548
|
type: "select",
|
|
3120
3549
|
name: "repoHost",
|
|
3121
3550
|
message: chalk8.white("Repository host:"),
|
|
3122
|
-
choices:
|
|
3123
|
-
title:
|
|
3124
|
-
|
|
3125
|
-
|
|
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
|
+
],
|
|
3126
3558
|
initial: 0
|
|
3127
3559
|
}, promptConfig);
|
|
3128
|
-
answers.repoHost = repoHostResponse.repoHost || "
|
|
3560
|
+
answers.repoHost = repoHostResponse.repoHost || "";
|
|
3129
3561
|
const visibilityResponse = await prompts4({
|
|
3130
3562
|
type: "toggle",
|
|
3131
3563
|
name: "isPublic",
|
|
@@ -3139,22 +3571,110 @@ async function runInteractiveWizard(options, detected, userTier) {
|
|
|
3139
3571
|
type: "select",
|
|
3140
3572
|
name: "license",
|
|
3141
3573
|
message: chalk8.white("License:"),
|
|
3142
|
-
choices:
|
|
3143
|
-
title:
|
|
3144
|
-
|
|
3145
|
-
|
|
3574
|
+
choices: [
|
|
3575
|
+
{ title: chalk8.gray("\u23ED Skip"), value: "" },
|
|
3576
|
+
...LICENSES.map((l) => ({
|
|
3577
|
+
title: l.label,
|
|
3578
|
+
value: l.id
|
|
3579
|
+
}))
|
|
3580
|
+
],
|
|
3146
3581
|
initial: 0
|
|
3147
3582
|
}, promptConfig);
|
|
3148
|
-
answers.license = licenseResponse.license || "
|
|
3583
|
+
answers.license = licenseResponse.license || "";
|
|
3149
3584
|
const conventionalResponse = await prompts4({
|
|
3150
3585
|
type: "toggle",
|
|
3151
3586
|
name: "conventionalCommits",
|
|
3152
3587
|
message: chalk8.white("Use Conventional Commits?"),
|
|
3153
|
-
initial:
|
|
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,
|
|
3154
3644
|
active: "Yes",
|
|
3155
3645
|
inactive: "No"
|
|
3156
3646
|
}, promptConfig);
|
|
3157
|
-
answers.
|
|
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 || "";
|
|
3158
3678
|
if (canAccessTier(userTier, "intermediate")) {
|
|
3159
3679
|
const commandsStep = getCurrentStep("commands");
|
|
3160
3680
|
showStep(currentStepNum, commandsStep, userTier);
|
|
@@ -3233,25 +3753,38 @@ async function runInteractiveWizard(options, detected, userTier) {
|
|
|
3233
3753
|
type: "select",
|
|
3234
3754
|
name: "naming",
|
|
3235
3755
|
message: chalk8.white("Naming convention:"),
|
|
3236
|
-
choices:
|
|
3237
|
-
title:
|
|
3238
|
-
|
|
3239
|
-
|
|
3240
|
-
|
|
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
|
+
],
|
|
3241
3764
|
initial: 0
|
|
3242
3765
|
}, promptConfig);
|
|
3243
|
-
answers.namingConvention = namingResponse.naming || "
|
|
3766
|
+
answers.namingConvention = namingResponse.naming || "";
|
|
3244
3767
|
const errorResponse = await prompts4({
|
|
3245
3768
|
type: "select",
|
|
3246
3769
|
name: "errorHandling",
|
|
3247
3770
|
message: chalk8.white("Error handling pattern:"),
|
|
3248
|
-
choices:
|
|
3249
|
-
title:
|
|
3250
|
-
|
|
3251
|
-
|
|
3771
|
+
choices: [
|
|
3772
|
+
{ title: chalk8.gray("\u23ED Skip"), value: "" },
|
|
3773
|
+
...ERROR_PATTERNS.map((e) => ({
|
|
3774
|
+
title: e.label,
|
|
3775
|
+
value: e.id
|
|
3776
|
+
}))
|
|
3777
|
+
],
|
|
3252
3778
|
initial: 0
|
|
3253
3779
|
}, promptConfig);
|
|
3254
|
-
answers.errorHandling = errorResponse.errorHandling || "
|
|
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 || "";
|
|
3255
3788
|
const styleNotesResponse = await prompts4({
|
|
3256
3789
|
type: "text",
|
|
3257
3790
|
name: "styleNotes",
|
|
@@ -3267,11 +3800,11 @@ async function runInteractiveWizard(options, detected, userTier) {
|
|
|
3267
3800
|
name: "aiBehavior",
|
|
3268
3801
|
message: chalk8.white("AI behavior rules:"),
|
|
3269
3802
|
choices: AI_BEHAVIOR_RULES.map((r) => ({
|
|
3270
|
-
title: r.recommended ? `${r.label} ${chalk8.green("\u2605")}` : r.label,
|
|
3271
|
-
value: r.id
|
|
3272
|
-
|
|
3803
|
+
title: r.recommended ? `${r.label} ${chalk8.green("\u2605 recommended")}` : r.label,
|
|
3804
|
+
value: r.id
|
|
3805
|
+
// No pre-selection - user must explicitly choose
|
|
3273
3806
|
})),
|
|
3274
|
-
hint: chalk8.gray("space select \u2022 enter confirm"),
|
|
3807
|
+
hint: chalk8.gray("space select \u2022 enter to skip/confirm"),
|
|
3275
3808
|
instructions: false
|
|
3276
3809
|
}, promptConfig);
|
|
3277
3810
|
answers.aiBehavior = aiBehaviorResponse.aiBehavior || [];
|
|
@@ -3281,10 +3814,10 @@ async function runInteractiveWizard(options, detected, userTier) {
|
|
|
3281
3814
|
message: chalk8.white("Important files AI should read:"),
|
|
3282
3815
|
choices: IMPORTANT_FILES.map((f) => ({
|
|
3283
3816
|
title: `${f.icon} ${f.label}`,
|
|
3284
|
-
value: f.id
|
|
3285
|
-
|
|
3817
|
+
value: f.id
|
|
3818
|
+
// No pre-selection - user must explicitly choose
|
|
3286
3819
|
})),
|
|
3287
|
-
hint: chalk8.gray("space select \u2022 enter confirm"),
|
|
3820
|
+
hint: chalk8.gray("space select \u2022 enter to skip/confirm"),
|
|
3288
3821
|
instructions: false
|
|
3289
3822
|
}, promptConfig);
|
|
3290
3823
|
answers.importantFiles = importantFilesResponse.importantFiles || [];
|
|
@@ -3297,6 +3830,15 @@ async function runInteractiveWizard(options, detected, userTier) {
|
|
|
3297
3830
|
inactive: "No"
|
|
3298
3831
|
}, promptConfig);
|
|
3299
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;
|
|
3300
3842
|
if (canAccessTier(userTier, "advanced")) {
|
|
3301
3843
|
const boundariesStep = getCurrentStep("boundaries");
|
|
3302
3844
|
showStep(currentStepNum, boundariesStep, userTier);
|
|
@@ -3304,14 +3846,17 @@ async function runInteractiveWizard(options, detected, userTier) {
|
|
|
3304
3846
|
type: "select",
|
|
3305
3847
|
name: "boundaryPreset",
|
|
3306
3848
|
message: chalk8.white("Boundary preset:"),
|
|
3307
|
-
choices:
|
|
3308
|
-
title:
|
|
3309
|
-
|
|
3310
|
-
|
|
3311
|
-
|
|
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
|
+
],
|
|
3312
3857
|
initial: 0
|
|
3313
3858
|
}, promptConfig);
|
|
3314
|
-
answers.boundaries = presetResponse.boundaryPreset || "
|
|
3859
|
+
answers.boundaries = presetResponse.boundaryPreset || "";
|
|
3315
3860
|
const selectedPreset = BOUNDARY_PRESETS.find((b) => b.value === answers.boundaries);
|
|
3316
3861
|
if (selectedPreset) {
|
|
3317
3862
|
console.log();
|
|
@@ -3411,32 +3956,51 @@ async function runInteractiveWizard(options, detected, userTier) {
|
|
|
3411
3956
|
showStep(currentStepNum, staticStep, userTier);
|
|
3412
3957
|
console.log(chalk8.gray(" Generate additional project files:"));
|
|
3413
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
|
+
];
|
|
3414
3972
|
const staticFilesResponse = await prompts4({
|
|
3415
3973
|
type: "multiselect",
|
|
3416
3974
|
name: "staticFiles",
|
|
3417
3975
|
message: chalk8.white("Include static files:"),
|
|
3418
|
-
choices:
|
|
3419
|
-
|
|
3420
|
-
|
|
3421
|
-
|
|
3422
|
-
|
|
3423
|
-
|
|
3424
|
-
{ title: "\u{1F4CB} .gitignore", value: "gitignore", description: chalk8.gray("Git ignore patterns"), selected: true }
|
|
3425
|
-
],
|
|
3426
|
-
hint: chalk8.gray("space select \u2022 enter confirm"),
|
|
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"),
|
|
3427
3982
|
instructions: false
|
|
3428
3983
|
}, promptConfig);
|
|
3429
3984
|
answers.staticFiles = staticFilesResponse.staticFiles || [];
|
|
3430
|
-
if (answers.
|
|
3431
|
-
|
|
3432
|
-
|
|
3433
|
-
|
|
3434
|
-
|
|
3435
|
-
|
|
3436
|
-
|
|
3437
|
-
|
|
3438
|
-
|
|
3439
|
-
|
|
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
|
+
}
|
|
3440
4004
|
}
|
|
3441
4005
|
}
|
|
3442
4006
|
const extraStep = getCurrentStep("extra");
|
|
@@ -3446,6 +4010,7 @@ async function runInteractiveWizard(options, detected, userTier) {
|
|
|
3446
4010
|
name: "persona",
|
|
3447
4011
|
message: chalk8.white("AI assistant persona:"),
|
|
3448
4012
|
choices: [
|
|
4013
|
+
{ title: chalk8.gray("\u23ED Skip"), value: "" },
|
|
3449
4014
|
{ title: "\u{1F9D1}\u200D\u{1F4BB} Full-Stack Developer", value: "fullstack", description: chalk8.gray("Complete application development") },
|
|
3450
4015
|
{ title: "\u2699\uFE0F Backend Developer", value: "backend", description: chalk8.gray("APIs, databases, services") },
|
|
3451
4016
|
{ title: "\u{1F3A8} Frontend Developer", value: "frontend", description: chalk8.gray("UI, components, styling") },
|
|
@@ -3463,9 +4028,9 @@ async function runInteractiveWizard(options, detected, userTier) {
|
|
|
3463
4028
|
message: chalk8.white("Describe the custom persona:"),
|
|
3464
4029
|
hint: chalk8.gray("e.g., 'ML engineer focused on PyTorch'")
|
|
3465
4030
|
}, promptConfig);
|
|
3466
|
-
answers.persona = customPersona.value || "
|
|
4031
|
+
answers.persona = customPersona.value || "";
|
|
3467
4032
|
} else {
|
|
3468
|
-
answers.persona = personaResponse.persona || "
|
|
4033
|
+
answers.persona = personaResponse.persona || "";
|
|
3469
4034
|
}
|
|
3470
4035
|
const extraNotesResponse = await prompts4({
|
|
3471
4036
|
type: "text",
|
|
@@ -3487,6 +4052,8 @@ async function runInteractiveWizard(options, detected, userTier) {
|
|
|
3487
4052
|
commands: typeof answers.commands === "object" ? answers.commands : detected?.commands || {},
|
|
3488
4053
|
// Extended config for Pro/Max users
|
|
3489
4054
|
projectType: answers.projectType,
|
|
4055
|
+
devOS: answers.devOS,
|
|
4056
|
+
architecture: answers.architecture,
|
|
3490
4057
|
repoHost: answers.repoHost,
|
|
3491
4058
|
isPublic: answers.isPublic,
|
|
3492
4059
|
license: answers.license,
|