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 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(chalk.bold("\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510"));
269
- console.log(chalk.bold("\u2502") + " " + chalk.bold("\u2502"));
270
- console.log(chalk.bold("\u2502") + chalk.green.bold(` ${config2.emoji} Welcome to LynxPrompt CLI!`) + " " + chalk.bold("\u2502"));
271
- console.log(chalk.bold("\u2502") + " " + chalk.bold("\u2502"));
272
- console.log(chalk.bold("\u2502") + ` ${chalk.white("User:")} ${chalk.bold(name.padEnd(38))}` + chalk.bold("\u2502"));
273
- console.log(chalk.bold("\u2502") + ` ${chalk.white("Plan:")} ${config2.color(config2.badge.padEnd(38))}` + chalk.bold("\u2502"));
274
- console.log(chalk.bold("\u2502") + " " + chalk.bold("\u2502"));
275
- console.log(chalk.bold("\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518"));
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.repoHost || options.license || options.conventionalCommits) {
2519
+ if (options.letAiDecide) {
2247
2520
  if (isMarkdown || isMdc) {
2248
- sections.push("## Repository");
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
- console.log(chalk8.yellow("\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510"));
2894
- console.log(chalk8.yellow("\u2502") + chalk8.white(" \u{1F4A1} ") + chalk8.gray("Log in for full wizard features:") + " " + chalk8.yellow("\u2502"));
2895
- console.log(chalk8.yellow("\u2502") + " " + chalk8.yellow("\u2502"));
2896
- console.log(chalk8.yellow("\u2502") + chalk8.gray(" \u2022 ") + chalk8.white("Commands & Code Style") + chalk8.cyan(" [PRO]") + " " + chalk8.yellow("\u2502"));
2897
- console.log(chalk8.yellow("\u2502") + chalk8.gray(" \u2022 ") + chalk8.white("Boundaries, Testing, Static Files") + chalk8.magenta(" [MAX]") + " " + chalk8.yellow("\u2502"));
2898
- console.log(chalk8.yellow("\u2502") + chalk8.gray(" \u2022 ") + chalk8.white("Push configs to cloud") + chalk8.gray(" (lynxp push)") + " " + chalk8.yellow("\u2502"));
2899
- console.log(chalk8.yellow("\u2502") + chalk8.gray(" \u2022 ") + chalk8.white("Sync across devices") + chalk8.gray(" (lynxp sync)") + " " + chalk8.yellow("\u2502"));
2900
- console.log(chalk8.yellow("\u2502") + " " + chalk8.yellow("\u2502"));
2901
- console.log(chalk8.yellow("\u2502") + chalk8.cyan(" Run: lynxp login") + " " + chalk8.yellow("\u2502"));
2902
- console.log(chalk8.yellow("\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518"));
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
- const formatResponse = await prompts4({
3030
- type: "select",
3031
- name: "format",
3032
- message: chalk8.white("Where will you use this?"),
3033
- choices: OUTPUT_FORMATS.map((f) => ({
3034
- title: f.recommended ? `${f.title} ${chalk8.green.bold("\u2605 recommended")}` : f.title,
3035
- value: f.value,
3036
- description: chalk8.gray(f.description)
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
- initial: 0,
3039
- hint: chalk8.gray("\u2191\u2193 navigate \u2022 enter select")
3443
+ hint: chalk8.gray("space select \u2022 a toggle all \u2022 enter confirm"),
3444
+ min: 1,
3445
+ instructions: false
3040
3446
  }, promptConfig);
3041
- if (formatResponse.format === "multiple") {
3042
- console.log();
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: PROJECT_TYPES.map((t) => ({
3088
- title: `${t.icon} ${t.label}`,
3089
- value: t.id,
3090
- description: chalk8.gray(t.description)
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 || "work";
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
- const detectedStackSet = new Set(detected?.stack || []);
3099
- if (detectedStackSet.size > 0) {
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
- selected: detectedStackSet.has(s.value)
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: REPO_HOSTS.map((h) => ({
3123
- title: `${h.icon} ${h.label}`,
3124
- value: h.id
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 || "github";
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: LICENSES.map((l) => ({
3143
- title: l.label,
3144
- value: l.id
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 || "mit";
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: true,
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.conventionalCommits = conventionalResponse.conventionalCommits ?? true;
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: NAMING_CONVENTIONS.map((n) => ({
3237
- title: n.label,
3238
- value: n.id,
3239
- description: chalk8.gray(n.desc)
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 || "language_default";
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: ERROR_PATTERNS.map((e) => ({
3249
- title: e.label,
3250
- value: e.id
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 || "try_catch";
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
- selected: r.recommended
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
- selected: f.id === "readme" || f.id === "package"
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: BOUNDARY_PRESETS.map((b) => ({
3308
- title: b.title,
3309
- value: b.value,
3310
- description: chalk8.gray(b.description)
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 || "standard";
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
- { title: "\u{1F4DD} .editorconfig", value: "editorconfig", description: chalk8.gray("Consistent code formatting") },
3420
- { title: "\u{1F91D} CONTRIBUTING.md", value: "contributing", description: chalk8.gray("Contributor guidelines") },
3421
- { title: "\u{1F4DC} CODE_OF_CONDUCT.md", value: "codeOfConduct", description: chalk8.gray("Community standards") },
3422
- { title: "\u{1F512} SECURITY.md", value: "security", description: chalk8.gray("Vulnerability reporting") },
3423
- { title: "\u{1F5FA}\uFE0F ROADMAP.md", value: "roadmap", description: chalk8.gray("Project roadmap") },
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.repoHost === "github" && answers.isPublic) {
3431
- const fundingResponse = await prompts4({
3432
- type: "toggle",
3433
- name: "funding",
3434
- message: chalk8.white("Generate FUNDING.yml for GitHub Sponsors?"),
3435
- initial: false,
3436
- active: "Yes",
3437
- inactive: "No"
3438
- }, promptConfig);
3439
- answers.includeFunding = fundingResponse.funding || false;
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 || "fullstack";
4031
+ answers.persona = customPersona.value || "";
3467
4032
  } else {
3468
- answers.persona = personaResponse.persona || "fullstack";
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,