lynxprompt 0.5.1 → 0.5.3

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
@@ -1885,7 +1885,8 @@ async function detectFromGitHubApi(repoUrl) {
1885
1885
  type: "application",
1886
1886
  repoHost: "github",
1887
1887
  repoUrl,
1888
- license: repoInfo.license?.spdx_id?.toLowerCase()
1888
+ license: repoInfo.license?.spdx_id?.toLowerCase(),
1889
+ isPublicRepo: !repoInfo.private
1889
1890
  };
1890
1891
  const filesRes = await fetch(`https://api.github.com/repos/${owner}/${repo}/contents/`, {
1891
1892
  headers: { "User-Agent": "LynxPrompt-CLI" }
@@ -1893,6 +1894,36 @@ async function detectFromGitHubApi(repoUrl) {
1893
1894
  if (!filesRes.ok) return detected;
1894
1895
  const files = await filesRes.json();
1895
1896
  const fileNames = new Set(files.map((f) => f.name.toLowerCase()));
1897
+ if (fileNames.has("pyproject.toml")) {
1898
+ detected.stack.push("python");
1899
+ const pyprojectRes = await fetch(`https://raw.githubusercontent.com/${owner}/${repo}/HEAD/pyproject.toml`);
1900
+ if (pyprojectRes.ok) {
1901
+ try {
1902
+ const content = await pyprojectRes.text();
1903
+ if (content.includes("fastapi")) detected.stack.push("fastapi");
1904
+ if (content.includes("django")) detected.stack.push("django");
1905
+ if (content.includes("flask")) detected.stack.push("flask");
1906
+ if (content.includes("sqlalchemy")) detected.stack.push("sqlalchemy");
1907
+ if (content.includes("pydantic")) detected.stack.push("pydantic");
1908
+ if (content.includes("pytest")) detected.stack.push("pytest");
1909
+ if (content.includes("ruff")) detected.stack.push("ruff");
1910
+ } catch {
1911
+ }
1912
+ }
1913
+ } else if (fileNames.has("requirements.txt")) {
1914
+ detected.stack.push("python");
1915
+ const reqRes = await fetch(`https://raw.githubusercontent.com/${owner}/${repo}/HEAD/requirements.txt`);
1916
+ if (reqRes.ok) {
1917
+ try {
1918
+ const content = (await reqRes.text()).toLowerCase();
1919
+ if (content.includes("fastapi")) detected.stack.push("fastapi");
1920
+ if (content.includes("django")) detected.stack.push("django");
1921
+ if (content.includes("flask")) detected.stack.push("flask");
1922
+ if (content.includes("sqlalchemy")) detected.stack.push("sqlalchemy");
1923
+ } catch {
1924
+ }
1925
+ }
1926
+ }
1896
1927
  if (fileNames.has("package.json")) {
1897
1928
  const pkgRes = await fetch(`https://raw.githubusercontent.com/${owner}/${repo}/HEAD/package.json`);
1898
1929
  if (pkgRes.ok) {
@@ -1924,10 +1955,22 @@ async function detectFromGitHubApi(repoUrl) {
1924
1955
  }
1925
1956
  }
1926
1957
  }
1927
- if (fileNames.has("pyproject.toml") || fileNames.has("requirements.txt")) detected.stack.push("python");
1928
1958
  if (fileNames.has("cargo.toml")) detected.stack.push("rust");
1929
1959
  if (fileNames.has("go.mod")) detected.stack.push("go");
1930
1960
  if (fileNames.has("dockerfile")) detected.hasDocker = true;
1961
+ if (fileNames.has("docker-compose.yml") || fileNames.has("docker-compose.yaml")) {
1962
+ const composeRes = await fetch(`https://raw.githubusercontent.com/${owner}/${repo}/HEAD/docker-compose.yml`);
1963
+ if (composeRes.ok) {
1964
+ try {
1965
+ const content = (await composeRes.text()).toLowerCase();
1966
+ if (content.includes("postgres")) detected.stack.push("postgresql");
1967
+ if (content.includes("mysql")) detected.stack.push("mysql");
1968
+ if (content.includes("mongo")) detected.stack.push("mongodb");
1969
+ if (content.includes("redis")) detected.stack.push("redis");
1970
+ } catch {
1971
+ }
1972
+ }
1973
+ }
1931
1974
  if (files.some((f) => f.name === ".github" && f.type === "dir")) {
1932
1975
  detected.cicd = "github_actions";
1933
1976
  }
@@ -3516,17 +3559,17 @@ var CICD_OPTIONS = [
3516
3559
  { id: "buildkite", label: "Buildkite", icon: "\u{1F9F1}" }
3517
3560
  ];
3518
3561
  var DEPLOYMENT_TARGETS = [
3519
- { id: "vercel", label: "Vercel", icon: "\u25B2" },
3562
+ { id: "vercel", label: "Vercel", icon: "\u25B2 " },
3520
3563
  { id: "netlify", label: "Netlify", icon: "\u{1F310}" },
3521
- { id: "aws", label: "AWS", icon: "\u2601\uFE0F" },
3564
+ { id: "aws", label: "AWS", icon: "\u2601\uFE0F " },
3522
3565
  { id: "gcp", label: "Google Cloud", icon: "\u{1F308}" },
3523
3566
  { id: "azure", label: "Azure", icon: "\u{1F537}" },
3524
3567
  { id: "docker", label: "Docker", icon: "\u{1F433}" },
3525
- { id: "kubernetes", label: "Kubernetes", icon: "\u2638\uFE0F" },
3568
+ { id: "kubernetes", label: "Kubernetes", icon: "\u2638\uFE0F " },
3526
3569
  { id: "heroku", label: "Heroku", icon: "\u{1F7E3}" },
3527
3570
  { id: "digitalocean", label: "DigitalOcean", icon: "\u{1F535}" },
3528
3571
  { id: "railway", label: "Railway", icon: "\u{1F682}" },
3529
- { id: "fly", label: "Fly.io", icon: "\u2708\uFE0F" },
3572
+ { id: "fly", label: "Fly.io", icon: "\u2708\uFE0F " },
3530
3573
  { id: "cloudflare", label: "Cloudflare", icon: "\u{1F536}" }
3531
3574
  ];
3532
3575
  var CONTAINER_REGISTRIES = [
@@ -3746,7 +3789,7 @@ var COMMON_COMMANDS = {
3746
3789
  ]
3747
3790
  };
3748
3791
  var NAMING_CONVENTIONS = [
3749
- { id: "language_default", label: "Follow language conventions", desc: "Use idiomatic style" },
3792
+ { id: "language_default", label: "Follow language conventions", desc: "Use idiomatic style (recommended)" },
3750
3793
  { id: "camelCase", label: "camelCase", desc: "JavaScript, TypeScript, Java" },
3751
3794
  { id: "snake_case", label: "snake_case", desc: "Python, Ruby, Rust, Go" },
3752
3795
  { id: "PascalCase", label: "PascalCase", desc: "C#, .NET classes" },
@@ -3781,11 +3824,11 @@ var AI_BEHAVIOR_RULES = [
3781
3824
  { id: "check_for_security_issues", label: "Check for Security Issues", description: "Review for common vulnerabilities", recommended: false }
3782
3825
  ];
3783
3826
  var IMPORTANT_FILES = [
3784
- { id: "readme", label: "README.md", icon: "\u{1F4D6}" },
3785
- { id: "package", label: "package.json / pyproject.toml", icon: "\u{1F4E6}" },
3786
- { id: "tsconfig", label: "tsconfig.json / config files", icon: "\u2699\uFE0F" },
3787
- { id: "architecture", label: "ARCHITECTURE.md", icon: "\u{1F3D7}\uFE0F" },
3788
- { id: "contributing", label: "CONTRIBUTING.md", icon: "\u{1F91D}" }
3827
+ { id: "readme", label: "README.md", icon: "\u{1F4D6} " },
3828
+ { id: "package", label: "package.json / pyproject.toml", icon: "\u{1F4E6} " },
3829
+ { id: "tsconfig", label: "tsconfig.json / config files", icon: "\u2699\uFE0F " },
3830
+ { id: "architecture", label: "ARCHITECTURE.md", icon: "\u{1F3D7}\uFE0F " },
3831
+ { id: "contributing", label: "CONTRIBUTING.md", icon: "\u{1F91D} " }
3789
3832
  ];
3790
3833
  var BOUNDARY_OPTIONS = [
3791
3834
  "Delete files",
@@ -3937,8 +3980,17 @@ var DEV_OS_OPTIONS = [
3937
3980
  { id: "linux", label: "Linux", icon: "\u{1F427}" },
3938
3981
  { id: "windows", label: "Windows", icon: "\u{1FA9F}" },
3939
3982
  { id: "wsl", label: "WSL", icon: "\u{1F427}" },
3940
- { id: "remote", label: "Remote/SSH", icon: "\u2601\uFE0F" }
3983
+ { id: "remote", label: "Remote/SSH", icon: "\u2601\uFE0F" },
3984
+ { id: "devcontainer", label: "Dev Container", icon: "\u{1F4E6}" },
3985
+ { id: "codespaces", label: "GitHub Codespaces", icon: "\u2601\uFE0F" }
3941
3986
  ];
3987
+ function detectCurrentOS() {
3988
+ const platform2 = os.platform();
3989
+ if (platform2 === "darwin") return "macos";
3990
+ if (platform2 === "linux") return "linux";
3991
+ if (platform2 === "win32") return "windows";
3992
+ return "";
3993
+ }
3942
3994
  var ARCHITECTURE_PATTERNS = [
3943
3995
  { id: "monolith", label: "Monolith" },
3944
3996
  { id: "microservices", label: "Microservices" },
@@ -3954,17 +4006,16 @@ function canAccessTier(userTier, requiredTier) {
3954
4006
  const requiredLevels = { basic: 0, intermediate: 1, advanced: 2 };
3955
4007
  return tierLevels[userTier] >= requiredLevels[requiredTier];
3956
4008
  }
4009
+ function sortSelectedFirst(choices) {
4010
+ return [...choices].sort((a, b) => {
4011
+ if (a.selected && !b.selected) return -1;
4012
+ if (!a.selected && b.selected) return 1;
4013
+ return 0;
4014
+ });
4015
+ }
3957
4016
  function canAccessAI(userTier) {
3958
4017
  return userTier === "max" || userTier === "teams";
3959
4018
  }
3960
- function getAIShortcutHint() {
3961
- const platform2 = os.platform();
3962
- if (platform2 === "darwin") {
3963
- return "\u2318+I";
3964
- } else {
3965
- return "Ctrl+I";
3966
- }
3967
- }
3968
4019
  async function aiAssist(instruction, existingContent) {
3969
4020
  const spinner = ora7("AI is thinking...").start();
3970
4021
  try {
@@ -4523,40 +4574,43 @@ async function runInteractiveWizard(options, detected, userTier) {
4523
4574
  type: "text",
4524
4575
  name: "description",
4525
4576
  message: chalk8.white("Brief description:"),
4526
- initial: options.description || "",
4527
- hint: chalk8.gray("optional - helps AI understand context")
4577
+ initial: options.description || detected?.description || "",
4578
+ hint: detected?.description ? chalk8.green("(pre-filled from repo About)") : chalk8.gray("optional - helps AI understand context")
4528
4579
  }, promptConfig);
4529
4580
  answers.description = descResponse.description || "";
4581
+ const isDetectedOpenSource = detected?.isPublicRepo === true;
4582
+ const projectTypeChoices = [
4583
+ { title: chalk8.gray("\u23ED Skip"), value: "" },
4584
+ ...PROJECT_TYPES.map((t) => ({
4585
+ title: t.id === "opensource" && isDetectedOpenSource ? `${t.icon} ${t.label} ${chalk8.green("(detected)")}` : `${t.icon} ${t.label}`,
4586
+ value: t.id,
4587
+ description: chalk8.gray(t.description)
4588
+ }))
4589
+ ];
4590
+ const defaultProjectTypeIdx = isDetectedOpenSource ? projectTypeChoices.findIndex((c) => c.value === "opensource") : 0;
4530
4591
  const typeResponse = await prompts4({
4531
4592
  type: "select",
4532
4593
  name: "projectType",
4533
4594
  message: chalk8.white("Project type:"),
4534
- choices: [
4535
- { title: chalk8.gray("\u23ED Skip"), value: "" },
4536
- ...PROJECT_TYPES.map((t) => ({
4537
- title: `${t.icon} ${t.label}`,
4538
- value: t.id,
4539
- description: chalk8.gray(t.description)
4540
- }))
4541
- ],
4542
- initial: 0
4595
+ choices: projectTypeChoices,
4596
+ initial: defaultProjectTypeIdx > 0 ? defaultProjectTypeIdx : 0
4543
4597
  }, promptConfig);
4544
4598
  answers.projectType = typeResponse.projectType || "";
4599
+ const currentOS = detectCurrentOS();
4545
4600
  const devOsResponse = await prompts4({
4546
- type: "select",
4601
+ type: "autocompleteMultiselect",
4547
4602
  name: "devOS",
4548
- message: chalk8.white("Development environment:"),
4549
- choices: [
4550
- { title: chalk8.gray("\u23ED Skip"), value: "" },
4551
- ...DEV_OS_OPTIONS.map((o) => ({
4552
- title: `${o.icon} ${o.label}`,
4553
- value: o.id
4554
- }))
4555
- ],
4556
- initial: 0,
4557
- hint: chalk8.gray("Helps generate compatible commands")
4603
+ message: chalk8.white("Development environment(s) (type to search):"),
4604
+ choices: DEV_OS_OPTIONS.map((o) => ({
4605
+ title: `${o.icon} ${o.label}`,
4606
+ value: o.id,
4607
+ selected: o.id === currentOS
4608
+ // Pre-select current OS
4609
+ })),
4610
+ hint: chalk8.gray("type to filter \u2022 space select \u2022 enter confirm"),
4611
+ instructions: false
4558
4612
  }, promptConfig);
4559
- answers.devOS = devOsResponse.devOS || "";
4613
+ answers.devOS = devOsResponse.devOS || [];
4560
4614
  const archResponse = await prompts4({
4561
4615
  type: "select",
4562
4616
  name: "architecture",
@@ -4616,41 +4670,44 @@ async function runInteractiveWizard(options, detected, userTier) {
4616
4670
  console.log(chalk8.green(` \u2713 Detected in project: ${detected.stack.join(", ")}`));
4617
4671
  console.log();
4618
4672
  }
4673
+ const languageChoices = sortSelectedFirst(LANGUAGES.map((s) => ({
4674
+ title: s.title,
4675
+ value: s.value,
4676
+ selected: detected?.stack?.includes(s.value)
4677
+ })));
4619
4678
  const languageResponse = await prompts4({
4620
4679
  type: "autocompleteMultiselect",
4621
4680
  name: "languages",
4622
4681
  message: chalk8.white("Languages (type to search):"),
4623
- choices: LANGUAGES.map((s) => ({
4624
- title: s.title,
4625
- value: s.value,
4626
- selected: detected?.stack?.includes(s.value)
4627
- })),
4682
+ choices: languageChoices,
4628
4683
  hint: chalk8.gray("type to filter \u2022 space select \u2022 enter confirm"),
4629
4684
  instructions: false
4630
4685
  }, promptConfig);
4631
4686
  const selectedLanguages = languageResponse.languages || [];
4687
+ const frameworkChoices = sortSelectedFirst(FRAMEWORKS.map((s) => ({
4688
+ title: s.title,
4689
+ value: s.value,
4690
+ selected: detected?.stack?.includes(s.value)
4691
+ })));
4632
4692
  const frameworkResponse = await prompts4({
4633
4693
  type: "autocompleteMultiselect",
4634
4694
  name: "frameworks",
4635
4695
  message: chalk8.white("Frameworks (type to search):"),
4636
- choices: FRAMEWORKS.map((s) => ({
4637
- title: s.title,
4638
- value: s.value,
4639
- selected: detected?.stack?.includes(s.value)
4640
- })),
4696
+ choices: frameworkChoices,
4641
4697
  hint: chalk8.gray("type to filter \u2022 space select \u2022 enter confirm"),
4642
4698
  instructions: false
4643
4699
  }, promptConfig);
4644
4700
  const selectedFrameworks = frameworkResponse.frameworks || [];
4701
+ const databaseChoices = sortSelectedFirst(DATABASES.map((s) => ({
4702
+ title: s.title,
4703
+ value: s.value,
4704
+ selected: detected?.stack?.includes(s.value)
4705
+ })));
4645
4706
  const databaseResponse = await prompts4({
4646
4707
  type: "autocompleteMultiselect",
4647
4708
  name: "databases",
4648
4709
  message: chalk8.white("Databases (type to search):"),
4649
- choices: DATABASES.map((s) => ({
4650
- title: s.title,
4651
- value: s.value,
4652
- selected: detected?.stack?.includes(s.value)
4653
- })),
4710
+ choices: databaseChoices,
4654
4711
  hint: chalk8.gray("type to filter \u2022 space select \u2022 enter confirm"),
4655
4712
  instructions: false
4656
4713
  }, promptConfig);
@@ -4755,28 +4812,31 @@ async function runInteractiveWizard(options, detected, userTier) {
4755
4812
  initial: detectedCicdIndex > 0 ? detectedCicdIndex : 0
4756
4813
  }, promptConfig);
4757
4814
  answers.cicd = cicdResponse.cicd || "";
4815
+ const deployChoices = sortSelectedFirst(DEPLOYMENT_TARGETS.map((t) => ({
4816
+ title: t.id === "docker" && detected?.hasDocker ? `${t.icon}${t.label} ${chalk8.green("(detected)")}` : `${t.icon}${t.label}`,
4817
+ selected: t.id === "docker" && detected?.hasDocker,
4818
+ value: t.id
4819
+ })));
4758
4820
  const deployResponse = await prompts4({
4759
4821
  type: "autocompleteMultiselect",
4760
4822
  name: "deploymentTargets",
4761
4823
  message: chalk8.white("Deployment targets (type to search):"),
4762
- choices: DEPLOYMENT_TARGETS.map((t) => ({
4763
- title: t.id === "docker" && detected?.hasDocker ? `${t.icon} ${t.label} ${chalk8.green("(detected)")}` : `${t.icon} ${t.label}`,
4764
- selected: t.id === "docker" && detected?.hasDocker,
4765
- value: t.id
4766
- })),
4824
+ choices: deployChoices,
4767
4825
  hint: chalk8.gray("type to filter \u2022 space select \u2022 enter confirm"),
4768
4826
  instructions: false
4769
4827
  }, promptConfig);
4770
4828
  answers.deploymentTargets = deployResponse.deploymentTargets || [];
4829
+ const dockerSelected = (answers.deploymentTargets || []).includes("docker");
4771
4830
  const containerResponse = await prompts4({
4772
4831
  type: "toggle",
4773
4832
  name: "buildContainer",
4774
4833
  message: chalk8.white("Build container images (Docker)?"),
4775
- initial: false,
4834
+ initial: dockerSelected,
4835
+ // Default Yes if Docker selected
4776
4836
  active: "Yes",
4777
4837
  inactive: "No"
4778
4838
  }, promptConfig);
4779
- answers.buildContainer = containerResponse.buildContainer || false;
4839
+ answers.buildContainer = containerResponse.buildContainer ?? dockerSelected;
4780
4840
  if (answers.buildContainer) {
4781
4841
  const registryResponse = await prompts4({
4782
4842
  type: "select",
@@ -4792,6 +4852,16 @@ async function runInteractiveWizard(options, detected, userTier) {
4792
4852
  initial: 0
4793
4853
  }, promptConfig);
4794
4854
  answers.containerRegistry = registryResponse.containerRegistry || "";
4855
+ if (answers.containerRegistry === "custom") {
4856
+ const customRegistryResponse = await prompts4({
4857
+ type: "text",
4858
+ name: "customRegistryUrl",
4859
+ message: chalk8.white("Container registry URL:"),
4860
+ hint: chalk8.gray("e.g., registry.example.com:5000"),
4861
+ validate: (v) => v.trim() ? true : "Please enter a registry URL"
4862
+ }, promptConfig);
4863
+ answers.customRegistryUrl = customRegistryResponse.customRegistryUrl || "";
4864
+ }
4795
4865
  }
4796
4866
  const exampleRepoResponse = await prompts4({
4797
4867
  type: "text",
@@ -4812,51 +4882,55 @@ async function runInteractiveWizard(options, detected, userTier) {
4812
4882
  showStep(currentStepNum, commandsStep, userTier);
4813
4883
  console.log(chalk8.gray(" Select common commands for your project (type to search):"));
4814
4884
  console.log();
4885
+ const buildChoices = sortSelectedFirst(COMMON_COMMANDS.build.map((c) => ({
4886
+ title: chalk8.cyan(c),
4887
+ value: c,
4888
+ selected: detected?.commands?.build === c
4889
+ })));
4815
4890
  const buildResponse = await prompts4({
4816
4891
  type: "autocompleteMultiselect",
4817
4892
  name: "build",
4818
4893
  message: chalk8.white("Build commands (type to search):"),
4819
- choices: COMMON_COMMANDS.build.map((c) => ({
4820
- title: chalk8.cyan(c),
4821
- value: c,
4822
- selected: detected?.commands?.build === c
4823
- })),
4894
+ choices: buildChoices,
4824
4895
  hint: chalk8.gray("type to filter \u2022 space select \u2022 enter confirm"),
4825
4896
  instructions: false
4826
4897
  }, promptConfig);
4898
+ const testChoices = sortSelectedFirst(COMMON_COMMANDS.test.map((c) => ({
4899
+ title: chalk8.yellow(c),
4900
+ value: c,
4901
+ selected: detected?.commands?.test === c
4902
+ })));
4827
4903
  const testResponse = await prompts4({
4828
4904
  type: "autocompleteMultiselect",
4829
4905
  name: "test",
4830
4906
  message: chalk8.white("Test commands (type to search):"),
4831
- choices: COMMON_COMMANDS.test.map((c) => ({
4832
- title: chalk8.yellow(c),
4833
- value: c,
4834
- selected: detected?.commands?.test === c
4835
- })),
4907
+ choices: testChoices,
4836
4908
  hint: chalk8.gray("type to filter \u2022 space select \u2022 enter confirm"),
4837
4909
  instructions: false
4838
4910
  }, promptConfig);
4911
+ const lintChoices = sortSelectedFirst(COMMON_COMMANDS.lint.map((c) => ({
4912
+ title: chalk8.green(c),
4913
+ value: c,
4914
+ selected: detected?.commands?.lint === c
4915
+ })));
4839
4916
  const lintResponse = await prompts4({
4840
4917
  type: "autocompleteMultiselect",
4841
4918
  name: "lint",
4842
4919
  message: chalk8.white("Lint/format commands (type to search):"),
4843
- choices: COMMON_COMMANDS.lint.map((c) => ({
4844
- title: chalk8.green(c),
4845
- value: c,
4846
- selected: detected?.commands?.lint === c
4847
- })),
4920
+ choices: lintChoices,
4848
4921
  hint: chalk8.gray("type to filter \u2022 space select \u2022 enter confirm"),
4849
4922
  instructions: false
4850
4923
  }, promptConfig);
4924
+ const devChoices = sortSelectedFirst(COMMON_COMMANDS.dev.map((c) => ({
4925
+ title: chalk8.magenta(c),
4926
+ value: c,
4927
+ selected: detected?.commands?.dev === c
4928
+ })));
4851
4929
  const devResponse = await prompts4({
4852
4930
  type: "autocompleteMultiselect",
4853
4931
  name: "dev",
4854
4932
  message: chalk8.white("Dev server commands (type to search):"),
4855
- choices: COMMON_COMMANDS.dev.map((c) => ({
4856
- title: chalk8.magenta(c),
4857
- value: c,
4858
- selected: detected?.commands?.dev === c
4859
- })),
4933
+ choices: devChoices,
4860
4934
  hint: chalk8.gray("type to filter \u2022 space select \u2022 enter confirm"),
4861
4935
  instructions: false
4862
4936
  }, promptConfig);
@@ -4900,12 +4974,13 @@ async function runInteractiveWizard(options, detected, userTier) {
4900
4974
  choices: [
4901
4975
  { title: chalk8.gray("\u23ED Skip"), value: "" },
4902
4976
  ...NAMING_CONVENTIONS.map((n) => ({
4903
- title: n.label,
4977
+ title: n.id === "language_default" ? `${n.label} ${chalk8.green("\u2605 recommended")}` : n.label,
4904
4978
  value: n.id,
4905
4979
  description: chalk8.gray(n.desc)
4906
4980
  }))
4907
4981
  ],
4908
- initial: 0
4982
+ initial: 1
4983
+ // Pre-select "Follow language conventions"
4909
4984
  }, promptConfig);
4910
4985
  answers.namingConvention = namingResponse.naming || "";
4911
4986
  const errorResponse = await prompts4({
@@ -4969,15 +5044,16 @@ async function runInteractiveWizard(options, detected, userTier) {
4969
5044
  name: "aiBehavior",
4970
5045
  message: chalk8.white("AI behavior rules (type to filter):"),
4971
5046
  choices: AI_BEHAVIOR_RULES.map((r) => ({
4972
- title: r.recommended ? `${r.label} ${chalk8.green("\u2605")}` : r.label,
5047
+ title: r.recommended ? `${r.label} ${chalk8.green("\u2605 recommended")}` : r.label,
4973
5048
  value: r.id,
4974
- description: chalk8.gray(r.description)
4975
- // No pre-selection - user must explicitly choose
5049
+ description: chalk8.gray(r.description),
5050
+ selected: true
5051
+ // All selected by default
4976
5052
  })),
4977
5053
  hint: chalk8.gray("type to filter \u2022 space select \u2022 enter confirm"),
4978
5054
  instructions: false
4979
5055
  }, promptConfig);
4980
- answers.aiBehavior = aiBehaviorResponse.aiBehavior || [];
5056
+ answers.aiBehavior = aiBehaviorResponse.aiBehavior || AI_BEHAVIOR_RULES.map((r) => r.id);
4981
5057
  if (answers.aiBehavior.length > 0) {
4982
5058
  console.log(chalk8.green(" \u2713 Selected:"));
4983
5059
  for (const ruleId of answers.aiBehavior) {
@@ -5099,15 +5175,16 @@ async function runInteractiveWizard(options, detected, userTier) {
5099
5175
  }, promptConfig);
5100
5176
  answers.testLevels = testLevelsResponse.testLevels || [];
5101
5177
  const detectedFrameworks = answers.stack?.includes("typescript") || answers.stack?.includes("javascript") ? ["jest", "vitest"] : answers.stack?.includes("python") ? ["pytest"] : [];
5178
+ const testFrameworkChoices = sortSelectedFirst(TEST_FRAMEWORKS.map((f) => ({
5179
+ title: f,
5180
+ value: f,
5181
+ selected: detectedFrameworks.includes(f)
5182
+ })));
5102
5183
  const testFrameworkResponse = await prompts4({
5103
5184
  type: "autocompleteMultiselect",
5104
5185
  name: "testFrameworks",
5105
5186
  message: chalk8.white("Testing frameworks (type to search):"),
5106
- choices: TEST_FRAMEWORKS.map((f) => ({
5107
- title: f,
5108
- value: f,
5109
- selected: detectedFrameworks.includes(f)
5110
- })),
5187
+ choices: testFrameworkChoices,
5111
5188
  hint: chalk8.gray("type to filter \u2022 space select \u2022 enter confirm"),
5112
5189
  instructions: false
5113
5190
  }, promptConfig);
@@ -5277,8 +5354,9 @@ async function runInteractiveWizard(options, detected, userTier) {
5277
5354
  const hasAIAccess = canAccessAI(userTier);
5278
5355
  if (hasAIAccess) {
5279
5356
  console.log();
5280
- console.log(chalk8.magenta(` \u2728 AI Assistant available (like ${getAIShortcutHint()} in the web UI)`));
5281
- console.log(chalk8.gray(" Describe what you want to add, and AI will format it for your config."));
5357
+ console.log(chalk8.magenta(" \u2728 AI Assistant available"));
5358
+ console.log(chalk8.gray(" Type 'ai:' followed by your request to get AI-generated content."));
5359
+ console.log(chalk8.gray(" Example: ai: add guidelines for API error handling"));
5282
5360
  console.log();
5283
5361
  }
5284
5362
  const extraNotesResponse = await prompts4({