lynxprompt 2.1.33 → 2.1.35

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
@@ -2253,15 +2253,16 @@ async function detectProject(cwd) {
2253
2253
  if (urlMatch) {
2254
2254
  const repoUrl = urlMatch[1].trim();
2255
2255
  detected.repoUrl = repoUrl;
2256
- if (repoUrl.includes("github.com")) {
2256
+ const remoteHost = repoUrlHostname(repoUrl);
2257
+ if (isHostOrSubdomain(remoteHost, "github.com")) {
2257
2258
  detected.repoHost = "github";
2258
- } else if (repoUrl.includes("gitlab.com") || repoUrl.includes("gitlab")) {
2259
+ } else if (remoteHost.includes("gitlab")) {
2259
2260
  detected.repoHost = "gitlab";
2260
- } else if (repoUrl.includes("bitbucket")) {
2261
+ } else if (remoteHost.includes("bitbucket")) {
2261
2262
  detected.repoHost = "bitbucket";
2262
- } else if (repoUrl.includes("gitea") || repoUrl.includes("codeberg")) {
2263
+ } else if (remoteHost.includes("gitea") || remoteHost.includes("codeberg")) {
2263
2264
  detected.repoHost = "gitea";
2264
- } else if (repoUrl.includes("azure")) {
2265
+ } else if (remoteHost.includes("azure")) {
2265
2266
  detected.repoHost = "azure";
2266
2267
  }
2267
2268
  }
@@ -2332,13 +2333,29 @@ async function fileExists(path2) {
2332
2333
  return false;
2333
2334
  }
2334
2335
  }
2336
+ function repoUrlHostname(url) {
2337
+ const trimmed = url.trim();
2338
+ const scp = trimmed.match(/^[^@\s/]+@([^:\s/]+):/);
2339
+ if (scp) return scp[1].toLowerCase();
2340
+ try {
2341
+ const withScheme = /^[a-z][a-z0-9+.-]*:\/\//i.test(trimmed) ? trimmed : `https://${trimmed}`;
2342
+ return new URL(withScheme).hostname.toLowerCase();
2343
+ } catch {
2344
+ return "";
2345
+ }
2346
+ }
2347
+ function isHostOrSubdomain(hostname, domain) {
2348
+ return hostname === domain || hostname.endsWith(`.${domain}`);
2349
+ }
2335
2350
  function detectRepoHost(url) {
2336
- const lower = url.toLowerCase();
2337
- if (lower.includes("github.com") || lower.includes("github:")) return "github";
2338
- if (lower.includes("gitlab.com") || lower.includes("gitlab")) return "gitlab";
2339
- if (lower.includes("bitbucket.org") || lower.includes("bitbucket:")) return "bitbucket";
2340
- if (lower.includes("gitea.") || lower.includes("gitea:") || lower.includes("codeberg.org")) return "gitea";
2341
- if (lower.includes("azure.com") || lower.includes("visualstudio.com") || lower.includes("dev.azure")) return "azure";
2351
+ const lower = url.trim().toLowerCase();
2352
+ const hostname = repoUrlHostname(lower);
2353
+ const on = (domain) => isHostOrSubdomain(hostname, domain);
2354
+ if (on("github.com") || lower.startsWith("github:")) return "github";
2355
+ if (hostname.includes("gitlab") || lower.startsWith("gitlab:")) return "gitlab";
2356
+ if (on("bitbucket.org") || lower.startsWith("bitbucket:")) return "bitbucket";
2357
+ if (hostname.startsWith("gitea.") || hostname.includes(".gitea.") || lower.startsWith("gitea:") || on("codeberg.org")) return "gitea";
2358
+ if (on("azure.com") || on("visualstudio.com")) return "azure";
2342
2359
  return "other";
2343
2360
  }
2344
2361
  function parseGitHubUrl(url) {
@@ -5709,7 +5726,7 @@ var TEST_FRAMEWORKS2 = TEST_FRAMEWORKS;
5709
5726
 
5710
5727
  // src/commands/wizard.ts
5711
5728
  var DRAFTS_DIR = ".lynxprompt/drafts";
5712
- var CLI_VERSION = "2.1.33";
5729
+ var CLI_VERSION = "2.1.35";
5713
5730
  async function saveDraftLocally(name, config2, stepReached) {
5714
5731
  const draftsPath = join3(process.cwd(), DRAFTS_DIR);
5715
5732
  await mkdir3(draftsPath, { recursive: true });
@@ -10548,7 +10565,7 @@ auto-test: false
10548
10565
  read: []
10549
10566
  # AI rules converted below as conventions
10550
10567
  conventions:
10551
- ${rawContent.split("\n").filter((line) => line.trim() && !line.startsWith("#")).map((line) => ` - "${line.replace(/"/g, '\\"').trim()}"`).slice(0, 20).join("\n")}
10568
+ ${rawContent.split("\n").filter((line) => line.trim() && !line.startsWith("#")).map((line) => ` - "${line.trim().replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`).slice(0, 20).join("\n")}
10552
10569
  `;
10553
10570
  case "tabnine":
10554
10571
  return `# Tabnine configuration
@@ -11361,7 +11378,7 @@ async function configCommand(action, valueArg) {
11361
11378
  }
11362
11379
 
11363
11380
  // src/index.ts
11364
- var CLI_VERSION2 = "2.1.33";
11381
+ var CLI_VERSION2 = "2.1.35";
11365
11382
  var program = new Command();
11366
11383
  program.name("lynxprompt").description("CLI for LynxPrompt - Generate AI IDE configuration files").version(CLI_VERSION2);
11367
11384
  program.command("wizard").description("Generate AI IDE configuration (recommended for most users)").option("-n, --name <name>", "Project name").option("-d, --description <description>", "Project description").option("-s, --stack <stack>", "Tech stack (comma-separated)").option("-f, --format <format>", "Output format: agents, cursor, or comma-separated for multiple").option("-p, --platforms <platforms>", "Alias for --format (deprecated)").option("--persona <persona>", "AI persona (fullstack, backend, frontend, devops, data, security)").option("--boundaries <level>", "Boundary preset (conservative, standard, permissive)").option("-y, --yes", "Skip prompts, use defaults (generates AGENTS.md)").option("-o, --output <dir>", "Output directory (default: current directory)").option("--repo-url <url>", "Analyze remote repository URL (GitHub/GitLab supported)").option("--blueprint", "Generate with [[VARIABLE|default]] placeholders for templates").option("--license <type>", "License type (mit, apache-2.0, gpl-3.0, etc.)").option("--ci-cd <platform>", "CI/CD platform (github_actions, gitlab_ci, jenkins, etc.)").option("--project-type <type>", "Project type (work, leisure, opensource, learning)").option("--detect-only", "Only detect project info, don't generate files").option("--load-draft <name>", "Load a saved wizard draft").option("--save-draft <name>", "Save wizard state as a draft (auto-saves at end)").option("--vars <values>", "Fill variables: VAR1=value1,VAR2=value2").action(wizardCommand);