lynxprompt 1.2.11 → 1.2.13
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 +355 -94
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1549,6 +1549,7 @@ async function detectProject(cwd) {
|
|
|
1549
1549
|
const detected = {
|
|
1550
1550
|
name: null,
|
|
1551
1551
|
stack: [],
|
|
1552
|
+
databases: [],
|
|
1552
1553
|
commands: {},
|
|
1553
1554
|
packageManager: null,
|
|
1554
1555
|
type: "unknown"
|
|
@@ -1879,6 +1880,8 @@ function parseGitLabUrl(url) {
|
|
|
1879
1880
|
}
|
|
1880
1881
|
return null;
|
|
1881
1882
|
}
|
|
1883
|
+
var OPEN_SOURCE_LICENSES = ["mit", "apache-2.0", "gpl-3.0", "lgpl-3.0", "agpl-3.0", "bsd-2-clause", "bsd-3-clause", "mpl-2.0", "unlicense", "cc0-1.0", "isc"];
|
|
1884
|
+
var STATIC_FILES = [".editorconfig", "CONTRIBUTING.md", "CODE_OF_CONDUCT.md", "SECURITY.md", "ROADMAP.md", ".gitignore", "LICENSE", "README.md", "ARCHITECTURE.md", "CHANGELOG.md"];
|
|
1882
1885
|
async function detectFromGitHubApi(repoUrl) {
|
|
1883
1886
|
const parsed = parseGitHubUrl(repoUrl);
|
|
1884
1887
|
if (!parsed) return null;
|
|
@@ -1890,17 +1893,24 @@ async function detectFromGitHubApi(repoUrl) {
|
|
|
1890
1893
|
if (!repoRes.ok) return null;
|
|
1891
1894
|
const repoInfo = await repoRes.json();
|
|
1892
1895
|
if (repoInfo.private) return null;
|
|
1896
|
+
const licenseId = repoInfo.license?.spdx_id?.toLowerCase() || null;
|
|
1897
|
+
const isOpenSource = !repoInfo.private && (licenseId ? OPEN_SOURCE_LICENSES.includes(licenseId) : false);
|
|
1893
1898
|
const detected = {
|
|
1894
1899
|
name: repoInfo.name,
|
|
1895
1900
|
description: repoInfo.description ?? void 0,
|
|
1896
1901
|
stack: [],
|
|
1902
|
+
databases: [],
|
|
1897
1903
|
commands: {},
|
|
1898
1904
|
packageManager: null,
|
|
1899
1905
|
type: "application",
|
|
1900
1906
|
repoHost: "github",
|
|
1901
1907
|
repoUrl,
|
|
1902
|
-
license:
|
|
1903
|
-
isPublicRepo: !repoInfo.private
|
|
1908
|
+
license: licenseId ?? void 0,
|
|
1909
|
+
isPublicRepo: !repoInfo.private,
|
|
1910
|
+
isOpenSource,
|
|
1911
|
+
projectType: isOpenSource ? "open_source" : void 0,
|
|
1912
|
+
hasDocker: false,
|
|
1913
|
+
existingFiles: []
|
|
1904
1914
|
};
|
|
1905
1915
|
const filesRes = await fetch(`https://api.github.com/repos/${owner}/${repo}/contents/`, {
|
|
1906
1916
|
headers: { "User-Agent": "LynxPrompt-CLI" }
|
|
@@ -1908,32 +1918,108 @@ async function detectFromGitHubApi(repoUrl) {
|
|
|
1908
1918
|
if (!filesRes.ok) return detected;
|
|
1909
1919
|
const files = await filesRes.json();
|
|
1910
1920
|
const fileNames = new Set(files.map((f) => f.name.toLowerCase()));
|
|
1921
|
+
for (const file of STATIC_FILES) {
|
|
1922
|
+
if (files.some((f) => f.name.toLowerCase() === file.toLowerCase())) {
|
|
1923
|
+
detected.existingFiles.push(file);
|
|
1924
|
+
}
|
|
1925
|
+
}
|
|
1926
|
+
if (fileNames.has("dockerfile") || fileNames.has("docker-compose.yml") || fileNames.has("docker-compose.yaml")) {
|
|
1927
|
+
detected.hasDocker = true;
|
|
1928
|
+
detected.stack.push("docker");
|
|
1929
|
+
const dockerComposeFile = fileNames.has("docker-compose.yml") ? "docker-compose.yml" : fileNames.has("docker-compose.yaml") ? "docker-compose.yaml" : null;
|
|
1930
|
+
if (dockerComposeFile) {
|
|
1931
|
+
const composeRes = await fetch(`https://raw.githubusercontent.com/${owner}/${repo}/HEAD/${dockerComposeFile}`);
|
|
1932
|
+
if (composeRes.ok) {
|
|
1933
|
+
try {
|
|
1934
|
+
const content = await composeRes.text();
|
|
1935
|
+
const lowerContent = content.toLowerCase();
|
|
1936
|
+
if (content.includes("ghcr.io")) detected.containerRegistry = "ghcr";
|
|
1937
|
+
else if (content.includes("docker.io") || /image:\s*[a-z0-9]+\/[a-z0-9]/.test(content)) detected.containerRegistry = "dockerhub";
|
|
1938
|
+
else if (content.includes("gcr.io")) detected.containerRegistry = "gcr";
|
|
1939
|
+
else if (content.includes("ecr.") || content.includes(".amazonaws.com")) detected.containerRegistry = "ecr";
|
|
1940
|
+
else if (content.includes("azurecr.io")) detected.containerRegistry = "acr";
|
|
1941
|
+
else if (content.includes("quay.io")) detected.containerRegistry = "quay";
|
|
1942
|
+
else if (content.includes("registry.gitlab.com")) detected.containerRegistry = "gitlab_registry";
|
|
1943
|
+
if (lowerContent.includes("postgres")) detected.databases.push("postgresql");
|
|
1944
|
+
if (lowerContent.includes("mysql") && !lowerContent.includes("mysql-")) detected.databases.push("mysql");
|
|
1945
|
+
if (lowerContent.includes("mongo")) detected.databases.push("mongodb");
|
|
1946
|
+
if (lowerContent.includes("redis")) detected.databases.push("redis");
|
|
1947
|
+
if (lowerContent.includes("sqlite")) detected.databases.push("sqlite");
|
|
1948
|
+
if (lowerContent.includes("mariadb")) detected.databases.push("mariadb");
|
|
1949
|
+
} catch {
|
|
1950
|
+
}
|
|
1951
|
+
}
|
|
1952
|
+
}
|
|
1953
|
+
}
|
|
1954
|
+
if (files.some((f) => f.name === ".github" && f.type === "dir")) {
|
|
1955
|
+
const ghFilesRes = await fetch(`https://api.github.com/repos/${owner}/${repo}/contents/.github`, {
|
|
1956
|
+
headers: { "User-Agent": "LynxPrompt-CLI" }
|
|
1957
|
+
});
|
|
1958
|
+
if (ghFilesRes.ok) {
|
|
1959
|
+
const ghFiles = await ghFilesRes.json();
|
|
1960
|
+
if (ghFiles.some((f) => f.name === "workflows")) {
|
|
1961
|
+
detected.cicd = "github_actions";
|
|
1962
|
+
}
|
|
1963
|
+
}
|
|
1964
|
+
}
|
|
1965
|
+
if (fileNames.has(".gitlab-ci.yml")) detected.cicd = "gitlab_ci";
|
|
1966
|
+
if (fileNames.has("jenkinsfile")) detected.cicd = "jenkins";
|
|
1967
|
+
if (fileNames.has(".travis.yml")) detected.cicd = "travis";
|
|
1968
|
+
if (fileNames.has("azure-pipelines.yml")) detected.cicd = "azure_devops";
|
|
1911
1969
|
if (fileNames.has("pyproject.toml")) {
|
|
1912
1970
|
detected.stack.push("python");
|
|
1913
1971
|
const pyprojectRes = await fetch(`https://raw.githubusercontent.com/${owner}/${repo}/HEAD/pyproject.toml`);
|
|
1914
1972
|
if (pyprojectRes.ok) {
|
|
1915
1973
|
try {
|
|
1916
1974
|
const content = await pyprojectRes.text();
|
|
1917
|
-
|
|
1918
|
-
if (
|
|
1919
|
-
if (
|
|
1920
|
-
if (
|
|
1921
|
-
if (
|
|
1922
|
-
if (
|
|
1923
|
-
if (
|
|
1975
|
+
const lowerContent = content.toLowerCase();
|
|
1976
|
+
if (lowerContent.includes("fastapi")) detected.stack.push("fastapi");
|
|
1977
|
+
if (lowerContent.includes("django")) detected.stack.push("django");
|
|
1978
|
+
if (lowerContent.includes("flask")) detected.stack.push("flask");
|
|
1979
|
+
if (lowerContent.includes("sqlalchemy")) detected.stack.push("sqlalchemy");
|
|
1980
|
+
if (lowerContent.includes("pydantic")) detected.stack.push("pydantic");
|
|
1981
|
+
if (lowerContent.includes("pytest")) detected.testFramework = "pytest";
|
|
1982
|
+
else if (lowerContent.includes("unittest")) detected.testFramework = "unittest";
|
|
1983
|
+
detected.commands.test = "pytest";
|
|
1984
|
+
if (lowerContent.includes("ruff")) detected.commands.lint = "ruff check .";
|
|
1985
|
+
if (lowerContent.includes("asyncpg") || lowerContent.includes("psycopg")) {
|
|
1986
|
+
if (!detected.databases.includes("postgresql")) detected.databases.push("postgresql");
|
|
1987
|
+
}
|
|
1988
|
+
if (lowerContent.includes("aiosqlite") || lowerContent.includes("sqlite")) {
|
|
1989
|
+
if (!detected.databases.includes("sqlite")) detected.databases.push("sqlite");
|
|
1990
|
+
}
|
|
1991
|
+
if (lowerContent.includes("pymongo") || lowerContent.includes("motor")) {
|
|
1992
|
+
if (!detected.databases.includes("mongodb")) detected.databases.push("mongodb");
|
|
1993
|
+
}
|
|
1994
|
+
if (lowerContent.includes("redis") || lowerContent.includes("aioredis")) {
|
|
1995
|
+
if (!detected.databases.includes("redis")) detected.databases.push("redis");
|
|
1996
|
+
}
|
|
1997
|
+
if (lowerContent.includes("pymysql") || lowerContent.includes("aiomysql")) {
|
|
1998
|
+
if (!detected.databases.includes("mysql")) detected.databases.push("mysql");
|
|
1999
|
+
}
|
|
1924
2000
|
} catch {
|
|
1925
2001
|
}
|
|
1926
2002
|
}
|
|
1927
|
-
}
|
|
1928
|
-
|
|
2003
|
+
}
|
|
2004
|
+
if (fileNames.has("requirements.txt")) {
|
|
1929
2005
|
const reqRes = await fetch(`https://raw.githubusercontent.com/${owner}/${repo}/HEAD/requirements.txt`);
|
|
1930
2006
|
if (reqRes.ok) {
|
|
1931
2007
|
try {
|
|
1932
2008
|
const content = (await reqRes.text()).toLowerCase();
|
|
1933
|
-
if (
|
|
1934
|
-
if (content.includes("
|
|
1935
|
-
if (content.includes("
|
|
1936
|
-
if (content.includes("
|
|
2009
|
+
if (!detected.stack.includes("python")) detected.stack.push("python");
|
|
2010
|
+
if (content.includes("fastapi") && !detected.stack.includes("fastapi")) detected.stack.push("fastapi");
|
|
2011
|
+
if (content.includes("django") && !detected.stack.includes("django")) detected.stack.push("django");
|
|
2012
|
+
if (content.includes("flask") && !detected.stack.includes("flask")) detected.stack.push("flask");
|
|
2013
|
+
if (content.includes("sqlalchemy") && !detected.stack.includes("sqlalchemy")) detected.stack.push("sqlalchemy");
|
|
2014
|
+
if (content.includes("asyncpg") || content.includes("psycopg")) {
|
|
2015
|
+
if (!detected.databases.includes("postgresql")) detected.databases.push("postgresql");
|
|
2016
|
+
}
|
|
2017
|
+
if (content.includes("aiosqlite") || content.includes("sqlite")) {
|
|
2018
|
+
if (!detected.databases.includes("sqlite")) detected.databases.push("sqlite");
|
|
2019
|
+
}
|
|
2020
|
+
if (content.includes("pymongo") || content.includes("motor")) {
|
|
2021
|
+
if (!detected.databases.includes("mongodb")) detected.databases.push("mongodb");
|
|
2022
|
+
}
|
|
1937
2023
|
} catch {
|
|
1938
2024
|
}
|
|
1939
2025
|
}
|
|
@@ -1950,11 +2036,16 @@ async function detectFromGitHubApi(repoUrl) {
|
|
|
1950
2036
|
if (allDeps["svelte"]) detected.stack.push("svelte");
|
|
1951
2037
|
if (allDeps["express"]) detected.stack.push("express");
|
|
1952
2038
|
if (allDeps["fastify"]) detected.stack.push("fastify");
|
|
2039
|
+
if (allDeps["hono"]) detected.stack.push("hono");
|
|
1953
2040
|
if (allDeps["typescript"]) detected.stack.push("typescript");
|
|
1954
2041
|
if (allDeps["tailwindcss"]) detected.stack.push("tailwind");
|
|
1955
2042
|
if (allDeps["prisma"]) detected.stack.push("prisma");
|
|
1956
|
-
if (allDeps["
|
|
1957
|
-
if (allDeps["
|
|
2043
|
+
if (allDeps["drizzle-orm"]) detected.stack.push("drizzle");
|
|
2044
|
+
if (allDeps["vitest"]) detected.testFramework = "vitest";
|
|
2045
|
+
else if (allDeps["jest"]) detected.testFramework = "jest";
|
|
2046
|
+
else if (allDeps["@playwright/test"]) detected.testFramework = "playwright";
|
|
2047
|
+
else if (allDeps["cypress"]) detected.testFramework = "cypress";
|
|
2048
|
+
else if (allDeps["mocha"]) detected.testFramework = "mocha";
|
|
1958
2049
|
if (detected.stack.length === 0 || detected.stack.length === 1 && detected.stack[0] === "typescript") {
|
|
1959
2050
|
detected.stack.unshift("javascript");
|
|
1960
2051
|
}
|
|
@@ -1965,30 +2056,35 @@ async function detectFromGitHubApi(repoUrl) {
|
|
|
1965
2056
|
if (pkg.scripts.dev) detected.commands.dev = "npm run dev";
|
|
1966
2057
|
else if (pkg.scripts.start) detected.commands.dev = "npm run start";
|
|
1967
2058
|
}
|
|
2059
|
+
if (allDeps["pg"] || allDeps["postgres"] || allDeps["@neondatabase/serverless"]) {
|
|
2060
|
+
if (!detected.databases.includes("postgresql")) detected.databases.push("postgresql");
|
|
2061
|
+
}
|
|
2062
|
+
if (allDeps["better-sqlite3"] || allDeps["sql.js"] || allDeps["sqlite3"]) {
|
|
2063
|
+
if (!detected.databases.includes("sqlite")) detected.databases.push("sqlite");
|
|
2064
|
+
}
|
|
2065
|
+
if (allDeps["mongodb"] || allDeps["mongoose"]) {
|
|
2066
|
+
if (!detected.databases.includes("mongodb")) detected.databases.push("mongodb");
|
|
2067
|
+
}
|
|
2068
|
+
if (allDeps["redis"] || allDeps["ioredis"]) {
|
|
2069
|
+
if (!detected.databases.includes("redis")) detected.databases.push("redis");
|
|
2070
|
+
}
|
|
2071
|
+
if (allDeps["mysql"] || allDeps["mysql2"]) {
|
|
2072
|
+
if (!detected.databases.includes("mysql")) detected.databases.push("mysql");
|
|
2073
|
+
}
|
|
1968
2074
|
} catch {
|
|
1969
2075
|
}
|
|
1970
2076
|
}
|
|
1971
2077
|
}
|
|
1972
|
-
if (fileNames.has("cargo.toml"))
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
const composeRes = await fetch(`https://raw.githubusercontent.com/${owner}/${repo}/HEAD/docker-compose.yml`);
|
|
1977
|
-
if (composeRes.ok) {
|
|
1978
|
-
try {
|
|
1979
|
-
const content = (await composeRes.text()).toLowerCase();
|
|
1980
|
-
if (content.includes("postgres")) detected.stack.push("postgresql");
|
|
1981
|
-
if (content.includes("mysql")) detected.stack.push("mysql");
|
|
1982
|
-
if (content.includes("mongo")) detected.stack.push("mongodb");
|
|
1983
|
-
if (content.includes("redis")) detected.stack.push("redis");
|
|
1984
|
-
} catch {
|
|
1985
|
-
}
|
|
1986
|
-
}
|
|
2078
|
+
if (fileNames.has("cargo.toml")) {
|
|
2079
|
+
detected.stack.push("rust");
|
|
2080
|
+
detected.commands.build = "cargo build";
|
|
2081
|
+
detected.commands.test = "cargo test";
|
|
1987
2082
|
}
|
|
1988
|
-
if (
|
|
1989
|
-
detected.
|
|
2083
|
+
if (fileNames.has("go.mod")) {
|
|
2084
|
+
detected.stack.push("go");
|
|
2085
|
+
detected.commands.build = "go build";
|
|
2086
|
+
detected.commands.test = "go test ./...";
|
|
1990
2087
|
}
|
|
1991
|
-
if (fileNames.has(".gitlab-ci.yml")) detected.cicd = "gitlab_ci";
|
|
1992
2088
|
return detected;
|
|
1993
2089
|
} catch {
|
|
1994
2090
|
return null;
|
|
@@ -2006,16 +2102,24 @@ async function detectFromGitLabApi(repoUrl) {
|
|
|
2006
2102
|
if (!repoRes.ok) return null;
|
|
2007
2103
|
const repoInfo = await repoRes.json();
|
|
2008
2104
|
if (repoInfo.visibility === "private") return null;
|
|
2105
|
+
const licenseId = repoInfo.license?.key?.toLowerCase() || null;
|
|
2106
|
+
const isOpenSource = repoInfo.visibility === "public" && (licenseId ? OPEN_SOURCE_LICENSES.includes(licenseId) : false);
|
|
2009
2107
|
const detected = {
|
|
2010
2108
|
name: repoInfo.name,
|
|
2011
2109
|
description: repoInfo.description ?? void 0,
|
|
2012
2110
|
stack: [],
|
|
2111
|
+
databases: [],
|
|
2013
2112
|
commands: {},
|
|
2014
2113
|
packageManager: null,
|
|
2015
2114
|
type: "application",
|
|
2016
2115
|
repoHost: "gitlab",
|
|
2017
2116
|
repoUrl,
|
|
2018
|
-
license:
|
|
2117
|
+
license: licenseId ?? void 0,
|
|
2118
|
+
isPublicRepo: repoInfo.visibility === "public",
|
|
2119
|
+
isOpenSource,
|
|
2120
|
+
projectType: isOpenSource ? "open_source" : void 0,
|
|
2121
|
+
hasDocker: false,
|
|
2122
|
+
existingFiles: []
|
|
2019
2123
|
};
|
|
2020
2124
|
const filesRes = await fetch(`https://${host}/api/v4/projects/${encodedPath}/repository/tree?per_page=100`, {
|
|
2021
2125
|
headers: { "User-Agent": "LynxPrompt-CLI" }
|
|
@@ -2023,6 +2127,39 @@ async function detectFromGitLabApi(repoUrl) {
|
|
|
2023
2127
|
if (!filesRes.ok) return detected;
|
|
2024
2128
|
const files = await filesRes.json();
|
|
2025
2129
|
const fileNames = new Set(files.map((f) => f.name.toLowerCase()));
|
|
2130
|
+
for (const file of STATIC_FILES) {
|
|
2131
|
+
if (files.some((f) => f.name.toLowerCase() === file.toLowerCase())) {
|
|
2132
|
+
detected.existingFiles.push(file);
|
|
2133
|
+
}
|
|
2134
|
+
}
|
|
2135
|
+
if (fileNames.has(".gitlab-ci.yml")) detected.cicd = "gitlab_ci";
|
|
2136
|
+
if (fileNames.has("jenkinsfile")) detected.cicd = "jenkins";
|
|
2137
|
+
if (fileNames.has("dockerfile") || fileNames.has("docker-compose.yml") || fileNames.has("docker-compose.yaml")) {
|
|
2138
|
+
detected.hasDocker = true;
|
|
2139
|
+
detected.stack.push("docker");
|
|
2140
|
+
const dockerComposeFile = fileNames.has("docker-compose.yml") ? "docker-compose.yml" : fileNames.has("docker-compose.yaml") ? "docker-compose.yaml" : null;
|
|
2141
|
+
if (dockerComposeFile) {
|
|
2142
|
+
const composeRes = await fetch(`https://${host}/api/v4/projects/${encodedPath}/repository/files/${encodeURIComponent(dockerComposeFile)}/raw?ref=HEAD`, {
|
|
2143
|
+
headers: { "User-Agent": "LynxPrompt-CLI" }
|
|
2144
|
+
});
|
|
2145
|
+
if (composeRes.ok) {
|
|
2146
|
+
try {
|
|
2147
|
+
const content = await composeRes.text();
|
|
2148
|
+
const lowerContent = content.toLowerCase();
|
|
2149
|
+
if (content.includes("registry.gitlab.com")) detected.containerRegistry = "gitlab_registry";
|
|
2150
|
+
else if (content.includes("ghcr.io")) detected.containerRegistry = "ghcr";
|
|
2151
|
+
else if (content.includes("docker.io") || /image:\s*[a-z0-9]+\/[a-z0-9]/.test(content)) detected.containerRegistry = "dockerhub";
|
|
2152
|
+
else if (content.includes("gcr.io")) detected.containerRegistry = "gcr";
|
|
2153
|
+
if (lowerContent.includes("postgres")) detected.databases.push("postgresql");
|
|
2154
|
+
if (lowerContent.includes("mysql") && !lowerContent.includes("mysql-")) detected.databases.push("mysql");
|
|
2155
|
+
if (lowerContent.includes("mongo")) detected.databases.push("mongodb");
|
|
2156
|
+
if (lowerContent.includes("redis")) detected.databases.push("redis");
|
|
2157
|
+
if (lowerContent.includes("sqlite")) detected.databases.push("sqlite");
|
|
2158
|
+
} catch {
|
|
2159
|
+
}
|
|
2160
|
+
}
|
|
2161
|
+
}
|
|
2162
|
+
}
|
|
2026
2163
|
if (fileNames.has("package.json")) {
|
|
2027
2164
|
const pkgRes = await fetch(`https://${host}/api/v4/projects/${encodedPath}/repository/files/package.json/raw?ref=HEAD`, {
|
|
2028
2165
|
headers: { "User-Agent": "LynxPrompt-CLI" }
|
|
@@ -2033,9 +2170,17 @@ async function detectFromGitLabApi(repoUrl) {
|
|
|
2033
2170
|
const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
2034
2171
|
if (allDeps["next"]) detected.stack.push("nextjs");
|
|
2035
2172
|
if (allDeps["react"]) detected.stack.push("react");
|
|
2173
|
+
if (allDeps["vue"]) detected.stack.push("vue");
|
|
2174
|
+
if (allDeps["svelte"]) detected.stack.push("svelte");
|
|
2175
|
+
if (allDeps["express"]) detected.stack.push("express");
|
|
2176
|
+
if (allDeps["fastify"]) detected.stack.push("fastify");
|
|
2036
2177
|
if (allDeps["typescript"]) detected.stack.push("typescript");
|
|
2037
2178
|
if (allDeps["tailwindcss"]) detected.stack.push("tailwind");
|
|
2038
|
-
if (detected.stack.
|
|
2179
|
+
if (allDeps["prisma"]) detected.stack.push("prisma");
|
|
2180
|
+
if (allDeps["vitest"]) detected.testFramework = "vitest";
|
|
2181
|
+
else if (allDeps["jest"]) detected.testFramework = "jest";
|
|
2182
|
+
else if (allDeps["@playwright/test"]) detected.testFramework = "playwright";
|
|
2183
|
+
if (detected.stack.length === 0 || detected.stack.length === 1 && detected.stack[0] === "typescript") {
|
|
2039
2184
|
detected.stack.unshift("javascript");
|
|
2040
2185
|
}
|
|
2041
2186
|
if (pkg.scripts) {
|
|
@@ -2044,15 +2189,57 @@ async function detectFromGitLabApi(repoUrl) {
|
|
|
2044
2189
|
if (pkg.scripts.lint) detected.commands.lint = "npm run lint";
|
|
2045
2190
|
if (pkg.scripts.dev) detected.commands.dev = "npm run dev";
|
|
2046
2191
|
}
|
|
2192
|
+
if (allDeps["pg"] || allDeps["postgres"]) {
|
|
2193
|
+
if (!detected.databases.includes("postgresql")) detected.databases.push("postgresql");
|
|
2194
|
+
}
|
|
2195
|
+
if (allDeps["better-sqlite3"] || allDeps["sqlite3"]) {
|
|
2196
|
+
if (!detected.databases.includes("sqlite")) detected.databases.push("sqlite");
|
|
2197
|
+
}
|
|
2198
|
+
if (allDeps["mongodb"] || allDeps["mongoose"]) {
|
|
2199
|
+
if (!detected.databases.includes("mongodb")) detected.databases.push("mongodb");
|
|
2200
|
+
}
|
|
2201
|
+
if (allDeps["redis"] || allDeps["ioredis"]) {
|
|
2202
|
+
if (!detected.databases.includes("redis")) detected.databases.push("redis");
|
|
2203
|
+
}
|
|
2047
2204
|
} catch {
|
|
2048
2205
|
}
|
|
2049
2206
|
}
|
|
2050
2207
|
}
|
|
2051
|
-
if (fileNames.has("pyproject.toml")
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2208
|
+
if (fileNames.has("pyproject.toml")) {
|
|
2209
|
+
detected.stack.push("python");
|
|
2210
|
+
const pyRes = await fetch(`https://${host}/api/v4/projects/${encodedPath}/repository/files/pyproject.toml/raw?ref=HEAD`, {
|
|
2211
|
+
headers: { "User-Agent": "LynxPrompt-CLI" }
|
|
2212
|
+
});
|
|
2213
|
+
if (pyRes.ok) {
|
|
2214
|
+
try {
|
|
2215
|
+
const content = (await pyRes.text()).toLowerCase();
|
|
2216
|
+
if (content.includes("fastapi")) detected.stack.push("fastapi");
|
|
2217
|
+
if (content.includes("django")) detected.stack.push("django");
|
|
2218
|
+
if (content.includes("flask")) detected.stack.push("flask");
|
|
2219
|
+
if (content.includes("sqlalchemy")) detected.stack.push("sqlalchemy");
|
|
2220
|
+
if (content.includes("pytest")) detected.testFramework = "pytest";
|
|
2221
|
+
if (content.includes("asyncpg") || content.includes("psycopg")) {
|
|
2222
|
+
if (!detected.databases.includes("postgresql")) detected.databases.push("postgresql");
|
|
2223
|
+
}
|
|
2224
|
+
if (content.includes("aiosqlite") || content.includes("sqlite")) {
|
|
2225
|
+
if (!detected.databases.includes("sqlite")) detected.databases.push("sqlite");
|
|
2226
|
+
}
|
|
2227
|
+
} catch {
|
|
2228
|
+
}
|
|
2229
|
+
}
|
|
2230
|
+
} else if (fileNames.has("requirements.txt")) {
|
|
2231
|
+
detected.stack.push("python");
|
|
2232
|
+
}
|
|
2233
|
+
if (fileNames.has("cargo.toml")) {
|
|
2234
|
+
detected.stack.push("rust");
|
|
2235
|
+
detected.commands.build = "cargo build";
|
|
2236
|
+
detected.commands.test = "cargo test";
|
|
2237
|
+
}
|
|
2238
|
+
if (fileNames.has("go.mod")) {
|
|
2239
|
+
detected.stack.push("go");
|
|
2240
|
+
detected.commands.build = "go build";
|
|
2241
|
+
detected.commands.test = "go test ./...";
|
|
2242
|
+
}
|
|
2056
2243
|
return detected;
|
|
2057
2244
|
} catch {
|
|
2058
2245
|
return null;
|
|
@@ -3400,7 +3587,7 @@ function generateYamlConfig(options, platform2) {
|
|
|
3400
3587
|
|
|
3401
3588
|
// src/commands/wizard.ts
|
|
3402
3589
|
var DRAFTS_DIR = ".lynxprompt/drafts";
|
|
3403
|
-
var CLI_VERSION = "1.2.
|
|
3590
|
+
var CLI_VERSION = "1.2.13";
|
|
3404
3591
|
async function saveDraftLocally(name, config2, stepReached) {
|
|
3405
3592
|
const draftsPath = join4(process.cwd(), DRAFTS_DIR);
|
|
3406
3593
|
await mkdir3(draftsPath, { recursive: true });
|
|
@@ -3670,19 +3857,42 @@ var CICD_OPTIONS = [
|
|
|
3670
3857
|
{ id: "drone", label: "Drone", icon: "\u{1F681}" },
|
|
3671
3858
|
{ id: "buildkite", label: "Buildkite", icon: "\u{1F9F1}" }
|
|
3672
3859
|
];
|
|
3673
|
-
var
|
|
3860
|
+
var CLOUD_TARGETS = [
|
|
3674
3861
|
{ id: "vercel", label: "Vercel", icon: "\u25B2 " },
|
|
3675
3862
|
{ id: "netlify", label: "Netlify", icon: "\u{1F310}" },
|
|
3676
|
-
{ id: "
|
|
3677
|
-
{ id: "
|
|
3678
|
-
{ id: "
|
|
3679
|
-
{ id: "
|
|
3680
|
-
{ id: "
|
|
3681
|
-
{ id: "
|
|
3682
|
-
{ id: "
|
|
3863
|
+
{ id: "cloudflare_pages", label: "Cloudflare Pages", icon: "\u{1F536}" },
|
|
3864
|
+
{ id: "cloudflare_workers", label: "Cloudflare Workers", icon: "\u{1F536}" },
|
|
3865
|
+
{ id: "aws_lambda", label: "AWS Lambda", icon: "\u2601\uFE0F " },
|
|
3866
|
+
{ id: "aws_ecs", label: "AWS ECS", icon: "\u2601\uFE0F " },
|
|
3867
|
+
{ id: "aws_ec2", label: "AWS EC2", icon: "\u2601\uFE0F " },
|
|
3868
|
+
{ id: "gcp_cloudrun", label: "GCP Cloud Run", icon: "\u{1F308}" },
|
|
3869
|
+
{ id: "gcp_appengine", label: "GCP App Engine", icon: "\u{1F308}" },
|
|
3870
|
+
{ id: "azure_appservice", label: "Azure App Service", icon: "\u{1F537}" },
|
|
3871
|
+
{ id: "azure_functions", label: "Azure Functions", icon: "\u{1F537}" },
|
|
3683
3872
|
{ id: "railway", label: "Railway", icon: "\u{1F682}" },
|
|
3873
|
+
{ id: "render", label: "Render", icon: "\u{1F3A8}" },
|
|
3684
3874
|
{ id: "fly", label: "Fly.io", icon: "\u2708\uFE0F " },
|
|
3685
|
-
{ id: "
|
|
3875
|
+
{ id: "heroku", label: "Heroku", icon: "\u{1F7E3}" },
|
|
3876
|
+
{ id: "digitalocean_app", label: "DigitalOcean App Platform", icon: "\u{1F535}" },
|
|
3877
|
+
{ id: "deno_deploy", label: "Deno Deploy", icon: "\u{1F995}" }
|
|
3878
|
+
];
|
|
3879
|
+
var SELF_HOSTED_TARGETS = [
|
|
3880
|
+
{ id: "docker", label: "Docker", icon: "\u{1F433}" },
|
|
3881
|
+
{ id: "docker_compose", label: "Docker Compose", icon: "\u{1F433}" },
|
|
3882
|
+
{ id: "kubernetes", label: "Kubernetes", icon: "\u2638\uFE0F " },
|
|
3883
|
+
{ id: "k3s", label: "K3s", icon: "\u2638\uFE0F " },
|
|
3884
|
+
{ id: "podman", label: "Podman", icon: "\u{1F9AD}" },
|
|
3885
|
+
{ id: "bare_metal", label: "Bare Metal", icon: "\u{1F5A5}\uFE0F " },
|
|
3886
|
+
{ id: "vm", label: "Virtual Machine", icon: "\u{1F4BB}" },
|
|
3887
|
+
{ id: "proxmox", label: "Proxmox", icon: "\u{1F537}" },
|
|
3888
|
+
{ id: "unraid", label: "Unraid", icon: "\u{1F7E0}" },
|
|
3889
|
+
{ id: "truenas", label: "TrueNAS", icon: "\u{1F535}" },
|
|
3890
|
+
{ id: "synology", label: "Synology NAS", icon: "\u{1F4C1}" },
|
|
3891
|
+
{ id: "coolify", label: "Coolify", icon: "\u2744\uFE0F " },
|
|
3892
|
+
{ id: "dokku", label: "Dokku", icon: "\u{1F433}" },
|
|
3893
|
+
{ id: "caprover", label: "CapRover", icon: "\u{1F6A2}" },
|
|
3894
|
+
{ id: "portainer", label: "Portainer", icon: "\u{1F40B}" },
|
|
3895
|
+
{ id: "rancher", label: "Rancher", icon: "\u{1F404}" }
|
|
3686
3896
|
];
|
|
3687
3897
|
var CONTAINER_REGISTRIES = [
|
|
3688
3898
|
{ id: "dockerhub", label: "Docker Hub", icon: "\u{1F433}" },
|
|
@@ -4496,13 +4706,24 @@ async function runWizardWithDraftProtection(options) {
|
|
|
4496
4706
|
console.log();
|
|
4497
4707
|
console.log(chalk7.white(` Name: ${detected2.name || "unknown"}`));
|
|
4498
4708
|
if (detected2.description) console.log(chalk7.gray(` Description: ${detected2.description}`));
|
|
4709
|
+
console.log(chalk7.white(` Type: ${detected2.isOpenSource ? "Open Source" : detected2.type}`));
|
|
4499
4710
|
console.log(chalk7.white(` Stack: ${detected2.stack.join(", ") || "none detected"}`));
|
|
4500
|
-
|
|
4711
|
+
if (detected2.databases && detected2.databases.length > 0) {
|
|
4712
|
+
console.log(chalk7.white(` Databases: ${detected2.databases.join(", ")}`));
|
|
4713
|
+
}
|
|
4501
4714
|
if (detected2.packageManager) console.log(chalk7.white(` Package Manager: ${detected2.packageManager}`));
|
|
4502
|
-
if (detected2.repoHost) console.log(chalk7.white(`
|
|
4503
|
-
if (detected2.license) console.log(chalk7.white(` License: ${detected2.license}`));
|
|
4504
|
-
if (detected2.cicd) console.log(chalk7.white(` CI/CD: ${detected2.cicd}`));
|
|
4505
|
-
if (detected2.hasDocker)
|
|
4715
|
+
if (detected2.repoHost) console.log(chalk7.white(` Host: ${detected2.repoHost}`));
|
|
4716
|
+
if (detected2.license) console.log(chalk7.white(` License: ${detected2.license.toUpperCase()}`));
|
|
4717
|
+
if (detected2.cicd) console.log(chalk7.white(` CI/CD: ${detected2.cicd.replace("_", " ")}`));
|
|
4718
|
+
if (detected2.hasDocker) {
|
|
4719
|
+
const dockerInfo = detected2.containerRegistry ? `detected (registry: ${detected2.containerRegistry})` : "detected";
|
|
4720
|
+
console.log(chalk7.white(` Docker: ${dockerInfo}`));
|
|
4721
|
+
}
|
|
4722
|
+
if (detected2.testFramework) console.log(chalk7.white(` Test Framework: ${detected2.testFramework}`));
|
|
4723
|
+
if (detected2.existingFiles && detected2.existingFiles.length > 0) {
|
|
4724
|
+
const filesDisplay = detected2.existingFiles.length > 3 ? `${detected2.existingFiles.slice(0, 3).join(", ")}... (+${detected2.existingFiles.length - 3})` : detected2.existingFiles.join(", ");
|
|
4725
|
+
console.log(chalk7.white(` Static files found: ${detected2.existingFiles.length} (${filesDisplay})`));
|
|
4726
|
+
}
|
|
4506
4727
|
if (detected2.commands) {
|
|
4507
4728
|
console.log(chalk7.white(` Commands:`));
|
|
4508
4729
|
if (detected2.commands.build) console.log(chalk7.gray(` build: ${detected2.commands.build}`));
|
|
@@ -4633,7 +4854,22 @@ async function runWizardWithDraftProtection(options) {
|
|
|
4633
4854
|
chalk7.green("\u2713 Remote project detected")
|
|
4634
4855
|
];
|
|
4635
4856
|
if (detected.name) detectedInfo.push(chalk7.gray(` Name: ${detected.name}`));
|
|
4857
|
+
if (detected.isOpenSource) detectedInfo.push(chalk7.gray(` Type: Open Source`));
|
|
4636
4858
|
if (detected.stack.length > 0) detectedInfo.push(chalk7.gray(` Stack: ${detected.stack.join(", ")}`));
|
|
4859
|
+
if (detected.databases && detected.databases.length > 0) {
|
|
4860
|
+
detectedInfo.push(chalk7.gray(` Databases: ${detected.databases.join(", ")}`));
|
|
4861
|
+
}
|
|
4862
|
+
if (detected.license) detectedInfo.push(chalk7.gray(` License: ${detected.license.toUpperCase()}`));
|
|
4863
|
+
if (detected.repoHost) detectedInfo.push(chalk7.gray(` Host: ${detected.repoHost}`));
|
|
4864
|
+
if (detected.cicd) detectedInfo.push(chalk7.gray(` CI/CD: ${detected.cicd.replace("_", " ")}`));
|
|
4865
|
+
if (detected.hasDocker) {
|
|
4866
|
+
const dockerInfo = detected.containerRegistry ? `detected (registry: ${detected.containerRegistry})` : "detected";
|
|
4867
|
+
detectedInfo.push(chalk7.gray(` Docker: ${dockerInfo}`));
|
|
4868
|
+
}
|
|
4869
|
+
if (detected.existingFiles && detected.existingFiles.length > 0) {
|
|
4870
|
+
const filesDisplay = detected.existingFiles.length > 3 ? `${detected.existingFiles.slice(0, 3).join(", ")}...` : detected.existingFiles.join(", ");
|
|
4871
|
+
detectedInfo.push(chalk7.gray(` Static files found: ${detected.existingFiles.length} (${filesDisplay})`));
|
|
4872
|
+
}
|
|
4637
4873
|
if (detected.repoUrl) detectedInfo.push(chalk7.gray(` Source: ${detected.repoUrl}`));
|
|
4638
4874
|
printBox(detectedInfo, chalk7.gray);
|
|
4639
4875
|
console.log();
|
|
@@ -5233,14 +5469,14 @@ async function runInteractiveWizard(options, detected, userTier) {
|
|
|
5233
5469
|
name: "changelogTool",
|
|
5234
5470
|
message: chalk7.white("Changelog management:"),
|
|
5235
5471
|
choices: [
|
|
5236
|
-
{ title: "Manual", value: "manual" },
|
|
5237
|
-
{ title: "Conventional Changelog", value: "conventional_changelog" },
|
|
5238
|
-
{ title: "Release Please", value: "release_please" },
|
|
5239
|
-
{ title: "Semantic Release", value: "semantic_release" },
|
|
5240
|
-
{ title: "Changesets", value: "changesets" },
|
|
5241
|
-
{ title: "GitHub Releases", value: "github_releases" },
|
|
5242
|
-
{ title: "Keep a Changelog", value: "keep_a_changelog" },
|
|
5243
|
-
{ title: "Other", value: "other" }
|
|
5472
|
+
{ title: "Manual - Write CHANGELOG.md by hand", value: "manual" },
|
|
5473
|
+
{ title: "Conventional Changelog - Auto-generate from commit messages", value: "conventional_changelog" },
|
|
5474
|
+
{ title: "Release Please - Google's automated release management", value: "release_please" },
|
|
5475
|
+
{ title: "Semantic Release - Fully automated versioning & publishing", value: "semantic_release" },
|
|
5476
|
+
{ title: "Changesets - Monorepo-friendly version management", value: "changesets" },
|
|
5477
|
+
{ title: "GitHub Releases - Use GitHub's built-in release notes", value: "github_releases" },
|
|
5478
|
+
{ title: "Keep a Changelog - Manual following keepachangelog.com format", value: "keep_a_changelog" },
|
|
5479
|
+
{ title: "Other - Custom changelog tooling", value: "other" }
|
|
5244
5480
|
],
|
|
5245
5481
|
initial: 0
|
|
5246
5482
|
}, promptConfig);
|
|
@@ -5260,13 +5496,15 @@ async function runInteractiveWizard(options, detected, userTier) {
|
|
|
5260
5496
|
name: "branchStrategy",
|
|
5261
5497
|
message: chalk7.white("Branch strategy:"),
|
|
5262
5498
|
choices: [
|
|
5499
|
+
{ title: "\u{1F3AE} None (toy project) - No branching, commit directly to main", value: "none" },
|
|
5263
5500
|
{ title: "\u{1F30A} GitHub Flow - Simple: main + feature branches", value: "github_flow" },
|
|
5264
5501
|
{ title: "\u{1F333} Gitflow - develop, feature, release, hotfix branches", value: "gitflow" },
|
|
5265
5502
|
{ title: "\u{1F682} Trunk-Based - Short-lived branches, continuous integration", value: "trunk_based" },
|
|
5266
5503
|
{ title: "\u{1F98A} GitLab Flow - Environment branches (staging, production)", value: "gitlab_flow" },
|
|
5267
5504
|
{ title: "\u{1F680} Release Flow - main + release branches", value: "release_flow" }
|
|
5268
5505
|
],
|
|
5269
|
-
initial:
|
|
5506
|
+
initial: 1
|
|
5507
|
+
// Default to GitHub Flow (index 1 after adding "none")
|
|
5270
5508
|
}, promptConfig);
|
|
5271
5509
|
answers.branchStrategy = branchStrategyResponse.branchStrategy || "github_flow";
|
|
5272
5510
|
const defaultBranchResponse = await prompts3({
|
|
@@ -5282,18 +5520,7 @@ async function runInteractiveWizard(options, detected, userTier) {
|
|
|
5282
5520
|
initial: 0
|
|
5283
5521
|
}, promptConfig);
|
|
5284
5522
|
answers.defaultBranch = defaultBranchResponse.defaultBranch || "main";
|
|
5285
|
-
|
|
5286
|
-
type: "select",
|
|
5287
|
-
name: "commitWorkflow",
|
|
5288
|
-
message: chalk7.white("Commit workflow preference:"),
|
|
5289
|
-
choices: [
|
|
5290
|
-
{ title: "\u{1F500} Branch + PR - Create branches and open pull requests", value: "branch_pr" },
|
|
5291
|
-
{ title: "\u2B06\uFE0F Direct to main - Commit directly to main/master branch", value: "direct_main" }
|
|
5292
|
-
],
|
|
5293
|
-
initial: 0
|
|
5294
|
-
// Default to branch + PR
|
|
5295
|
-
}, promptConfig);
|
|
5296
|
-
answers.commitWorkflow = commitWorkflowResponse.commitWorkflow || "branch_pr";
|
|
5523
|
+
answers.commitWorkflow = answers.branchStrategy === "none" ? "direct_main" : "branch_pr";
|
|
5297
5524
|
const cicdChoices = [
|
|
5298
5525
|
{ title: chalk7.gray("\u23ED Skip"), value: "" },
|
|
5299
5526
|
...CICD_OPTIONS.map((c) => ({
|
|
@@ -5310,27 +5537,61 @@ async function runInteractiveWizard(options, detected, userTier) {
|
|
|
5310
5537
|
initial: detectedCicdIndex > 0 ? detectedCicdIndex : 0
|
|
5311
5538
|
}, promptConfig);
|
|
5312
5539
|
answers.cicd = cicdResponse.cicd || "";
|
|
5313
|
-
const
|
|
5314
|
-
|
|
5315
|
-
|
|
5316
|
-
|
|
5317
|
-
|
|
5318
|
-
|
|
5319
|
-
|
|
5320
|
-
|
|
5321
|
-
|
|
5322
|
-
|
|
5323
|
-
|
|
5324
|
-
instructions: false
|
|
5540
|
+
const deployTypeResponse = await prompts3({
|
|
5541
|
+
type: "select",
|
|
5542
|
+
name: "deployType",
|
|
5543
|
+
message: chalk7.white("Deployment environment:"),
|
|
5544
|
+
choices: [
|
|
5545
|
+
{ title: "\u2601\uFE0F Cloud only - PaaS, serverless, managed services", value: "cloud" },
|
|
5546
|
+
{ title: "\u{1F3E0} Self-hosted only - On-premise, homelab, VPS", value: "self_hosted" },
|
|
5547
|
+
{ title: "\u{1F504} Both cloud and self-hosted", value: "both" },
|
|
5548
|
+
{ title: chalk7.gray("\u23ED Skip"), value: "skip" }
|
|
5549
|
+
],
|
|
5550
|
+
initial: 0
|
|
5325
5551
|
}, promptConfig);
|
|
5326
|
-
|
|
5327
|
-
|
|
5552
|
+
const deployType = deployTypeResponse.deployType || "skip";
|
|
5553
|
+
let allDeployTargets = [];
|
|
5554
|
+
if (deployType === "cloud" || deployType === "both") {
|
|
5555
|
+
const cloudChoices = CLOUD_TARGETS.map((t) => ({
|
|
5556
|
+
title: `${t.icon}${t.label}`,
|
|
5557
|
+
value: t.id
|
|
5558
|
+
}));
|
|
5559
|
+
const cloudResponse = await prompts3({
|
|
5560
|
+
type: "autocompleteMultiselect",
|
|
5561
|
+
name: "cloudTargets",
|
|
5562
|
+
message: chalk7.white("Cloud deployment targets (type to search):"),
|
|
5563
|
+
choices: cloudChoices,
|
|
5564
|
+
hint: chalk7.gray("type to filter \u2022 space select \u2022 enter confirm"),
|
|
5565
|
+
instructions: false
|
|
5566
|
+
}, promptConfig);
|
|
5567
|
+
allDeployTargets = [...cloudResponse.cloudTargets || []];
|
|
5568
|
+
}
|
|
5569
|
+
if (deployType === "self_hosted" || deployType === "both") {
|
|
5570
|
+
const selfHostedChoices = sortSelectedFirst(SELF_HOSTED_TARGETS.map((t) => ({
|
|
5571
|
+
title: t.id === "docker" && detected?.hasDocker ? `${t.icon}${t.label} ${chalk7.green("(detected)")}` : `${t.icon}${t.label}`,
|
|
5572
|
+
selected: t.id === "docker" && detected?.hasDocker,
|
|
5573
|
+
value: t.id
|
|
5574
|
+
})));
|
|
5575
|
+
const selfHostedResponse = await prompts3({
|
|
5576
|
+
type: "autocompleteMultiselect",
|
|
5577
|
+
name: "selfHostedTargets",
|
|
5578
|
+
message: chalk7.white("Self-hosted deployment targets (type to search):"),
|
|
5579
|
+
choices: selfHostedChoices,
|
|
5580
|
+
hint: chalk7.gray("type to filter \u2022 space select \u2022 enter confirm"),
|
|
5581
|
+
instructions: false
|
|
5582
|
+
}, promptConfig);
|
|
5583
|
+
allDeployTargets = [...allDeployTargets, ...selfHostedResponse.selfHostedTargets || []];
|
|
5584
|
+
}
|
|
5585
|
+
answers.deploymentTargets = allDeployTargets;
|
|
5586
|
+
const dockerSelected = (answers.deploymentTargets || []).some(
|
|
5587
|
+
(t) => ["docker", "docker_compose", "kubernetes", "k3s", "podman"].includes(t)
|
|
5588
|
+
) || detected?.hasDocker;
|
|
5328
5589
|
const containerResponse = await prompts3({
|
|
5329
5590
|
type: "toggle",
|
|
5330
5591
|
name: "buildContainer",
|
|
5331
5592
|
message: chalk7.white("Build container images (Docker)?"),
|
|
5332
5593
|
initial: dockerSelected,
|
|
5333
|
-
// Default Yes if
|
|
5594
|
+
// Default Yes if container platform selected
|
|
5334
5595
|
active: "Yes",
|
|
5335
5596
|
inactive: "No"
|
|
5336
5597
|
}, promptConfig);
|
|
@@ -8597,7 +8858,7 @@ function handleError2(error) {
|
|
|
8597
8858
|
}
|
|
8598
8859
|
|
|
8599
8860
|
// src/index.ts
|
|
8600
|
-
var CLI_VERSION2 = "1.2.
|
|
8861
|
+
var CLI_VERSION2 = "1.2.13";
|
|
8601
8862
|
var program = new Command();
|
|
8602
8863
|
program.name("lynxprompt").description("CLI for LynxPrompt - Generate AI IDE configuration files").version(CLI_VERSION2);
|
|
8603
8864
|
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);
|