lynxprompt 0.4.2 → 0.4.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 +294 -67
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1633,6 +1633,108 @@ async function detectProject(cwd) {
|
|
|
1633
1633
|
if (await fileExists(join4(cwd, "Dockerfile")) || await fileExists(join4(cwd, "docker-compose.yml"))) {
|
|
1634
1634
|
detected.stack.push("docker");
|
|
1635
1635
|
detected.type = "application";
|
|
1636
|
+
detected.hasDocker = true;
|
|
1637
|
+
}
|
|
1638
|
+
const licensePath = join4(cwd, "LICENSE");
|
|
1639
|
+
if (await fileExists(licensePath)) {
|
|
1640
|
+
try {
|
|
1641
|
+
const licenseContent = await readFile3(licensePath, "utf-8");
|
|
1642
|
+
const lowerContent = licenseContent.toLowerCase();
|
|
1643
|
+
if (lowerContent.includes("mit license") || lowerContent.includes("permission is hereby granted, free of charge")) {
|
|
1644
|
+
detected.license = "mit";
|
|
1645
|
+
} else if (lowerContent.includes("apache license") && lowerContent.includes("version 2.0")) {
|
|
1646
|
+
detected.license = "apache-2.0";
|
|
1647
|
+
} else if (lowerContent.includes("gnu general public license") && lowerContent.includes("version 3")) {
|
|
1648
|
+
detected.license = "gpl-3.0";
|
|
1649
|
+
} else if (lowerContent.includes("gnu lesser general public license")) {
|
|
1650
|
+
detected.license = "lgpl-3.0";
|
|
1651
|
+
} else if (lowerContent.includes("gnu affero general public license")) {
|
|
1652
|
+
detected.license = "agpl-3.0";
|
|
1653
|
+
} else if (lowerContent.includes("bsd 3-clause") || lowerContent.includes("redistribution and use in source and binary forms")) {
|
|
1654
|
+
detected.license = "bsd-3";
|
|
1655
|
+
} else if (lowerContent.includes("mozilla public license") && lowerContent.includes("2.0")) {
|
|
1656
|
+
detected.license = "mpl-2.0";
|
|
1657
|
+
} else if (lowerContent.includes("unlicense") || lowerContent.includes("this is free and unencumbered software")) {
|
|
1658
|
+
detected.license = "unlicense";
|
|
1659
|
+
}
|
|
1660
|
+
} catch {
|
|
1661
|
+
}
|
|
1662
|
+
}
|
|
1663
|
+
const gitConfigPath = join4(cwd, ".git", "config");
|
|
1664
|
+
if (await fileExists(gitConfigPath)) {
|
|
1665
|
+
try {
|
|
1666
|
+
const gitConfig = await readFile3(gitConfigPath, "utf-8");
|
|
1667
|
+
const urlMatch = gitConfig.match(/url\s*=\s*(.+)/);
|
|
1668
|
+
if (urlMatch) {
|
|
1669
|
+
const repoUrl = urlMatch[1].trim();
|
|
1670
|
+
detected.repoUrl = repoUrl;
|
|
1671
|
+
if (repoUrl.includes("github.com")) {
|
|
1672
|
+
detected.repoHost = "github";
|
|
1673
|
+
} else if (repoUrl.includes("gitlab.com") || repoUrl.includes("gitlab")) {
|
|
1674
|
+
detected.repoHost = "gitlab";
|
|
1675
|
+
} else if (repoUrl.includes("bitbucket")) {
|
|
1676
|
+
detected.repoHost = "bitbucket";
|
|
1677
|
+
} else if (repoUrl.includes("gitea") || repoUrl.includes("codeberg")) {
|
|
1678
|
+
detected.repoHost = "gitea";
|
|
1679
|
+
} else if (repoUrl.includes("azure")) {
|
|
1680
|
+
detected.repoHost = "azure";
|
|
1681
|
+
}
|
|
1682
|
+
}
|
|
1683
|
+
} catch {
|
|
1684
|
+
}
|
|
1685
|
+
}
|
|
1686
|
+
if (await fileExists(join4(cwd, ".github", "workflows"))) {
|
|
1687
|
+
detected.cicd = "github_actions";
|
|
1688
|
+
} else if (await fileExists(join4(cwd, ".gitlab-ci.yml"))) {
|
|
1689
|
+
detected.cicd = "gitlab_ci";
|
|
1690
|
+
} else if (await fileExists(join4(cwd, "Jenkinsfile"))) {
|
|
1691
|
+
detected.cicd = "jenkins";
|
|
1692
|
+
} else if (await fileExists(join4(cwd, ".circleci"))) {
|
|
1693
|
+
detected.cicd = "circleci";
|
|
1694
|
+
} else if (await fileExists(join4(cwd, ".travis.yml"))) {
|
|
1695
|
+
detected.cicd = "travis";
|
|
1696
|
+
} else if (await fileExists(join4(cwd, "azure-pipelines.yml"))) {
|
|
1697
|
+
detected.cicd = "azure_devops";
|
|
1698
|
+
} else if (await fileExists(join4(cwd, "bitbucket-pipelines.yml"))) {
|
|
1699
|
+
detected.cicd = "bitbucket";
|
|
1700
|
+
} else if (await fileExists(join4(cwd, ".drone.yml"))) {
|
|
1701
|
+
detected.cicd = "drone";
|
|
1702
|
+
}
|
|
1703
|
+
detected.existingFiles = [];
|
|
1704
|
+
const staticFiles = [
|
|
1705
|
+
".editorconfig",
|
|
1706
|
+
"CONTRIBUTING.md",
|
|
1707
|
+
"CODE_OF_CONDUCT.md",
|
|
1708
|
+
"SECURITY.md",
|
|
1709
|
+
"ROADMAP.md",
|
|
1710
|
+
".gitignore",
|
|
1711
|
+
".github/FUNDING.yml",
|
|
1712
|
+
"LICENSE",
|
|
1713
|
+
"README.md",
|
|
1714
|
+
"ARCHITECTURE.md",
|
|
1715
|
+
"CHANGELOG.md"
|
|
1716
|
+
];
|
|
1717
|
+
for (const file of staticFiles) {
|
|
1718
|
+
if (await fileExists(join4(cwd, file))) {
|
|
1719
|
+
detected.existingFiles.push(file);
|
|
1720
|
+
}
|
|
1721
|
+
}
|
|
1722
|
+
if (!detected.description) {
|
|
1723
|
+
const readmePath = join4(cwd, "README.md");
|
|
1724
|
+
if (await fileExists(readmePath)) {
|
|
1725
|
+
try {
|
|
1726
|
+
const readme = await readFile3(readmePath, "utf-8");
|
|
1727
|
+
const lines = readme.split("\n");
|
|
1728
|
+
for (const line of lines) {
|
|
1729
|
+
const trimmed = line.trim();
|
|
1730
|
+
if (trimmed && !trimmed.startsWith("#") && !trimmed.startsWith("!") && !trimmed.startsWith("[") && trimmed.length > 20) {
|
|
1731
|
+
detected.description = trimmed.substring(0, 200);
|
|
1732
|
+
break;
|
|
1733
|
+
}
|
|
1734
|
+
}
|
|
1735
|
+
} catch {
|
|
1736
|
+
}
|
|
1737
|
+
}
|
|
1636
1738
|
}
|
|
1637
1739
|
return detected.stack.length > 0 || detected.name ? detected : null;
|
|
1638
1740
|
}
|
|
@@ -2009,7 +2111,8 @@ async function initCommand(options) {
|
|
|
2009
2111
|
import chalk8 from "chalk";
|
|
2010
2112
|
import prompts4 from "prompts";
|
|
2011
2113
|
import ora7 from "ora";
|
|
2012
|
-
import
|
|
2114
|
+
import * as readline from "readline";
|
|
2115
|
+
import { writeFile as writeFile4, mkdir as mkdir4, access as access3, readFile as readFile5 } from "fs/promises";
|
|
2013
2116
|
import { join as join6, dirname as dirname4 } from "path";
|
|
2014
2117
|
|
|
2015
2118
|
// src/utils/generator.ts
|
|
@@ -2878,6 +2981,63 @@ function generateYamlConfig(options, platform) {
|
|
|
2878
2981
|
}
|
|
2879
2982
|
|
|
2880
2983
|
// src/commands/wizard.ts
|
|
2984
|
+
var STATIC_FILE_PATHS2 = {
|
|
2985
|
+
editorconfig: ".editorconfig",
|
|
2986
|
+
contributing: "CONTRIBUTING.md",
|
|
2987
|
+
codeOfConduct: "CODE_OF_CONDUCT.md",
|
|
2988
|
+
security: "SECURITY.md",
|
|
2989
|
+
roadmap: "ROADMAP.md",
|
|
2990
|
+
gitignore: ".gitignore",
|
|
2991
|
+
funding: ".github/FUNDING.yml",
|
|
2992
|
+
license: "LICENSE",
|
|
2993
|
+
readme: "README.md",
|
|
2994
|
+
architecture: "ARCHITECTURE.md",
|
|
2995
|
+
changelog: "CHANGELOG.md"
|
|
2996
|
+
};
|
|
2997
|
+
async function readExistingFile(filePath) {
|
|
2998
|
+
try {
|
|
2999
|
+
await access3(filePath);
|
|
3000
|
+
const content = await readFile5(filePath, "utf-8");
|
|
3001
|
+
return content;
|
|
3002
|
+
} catch {
|
|
3003
|
+
return null;
|
|
3004
|
+
}
|
|
3005
|
+
}
|
|
3006
|
+
async function readMultilineInput(prompt) {
|
|
3007
|
+
console.log(chalk8.white(prompt));
|
|
3008
|
+
console.log(chalk8.gray(" (Paste your content, then type EOF on a new line and press Enter to finish)"));
|
|
3009
|
+
console.log(chalk8.gray(" (Press Enter twice to skip)"));
|
|
3010
|
+
console.log();
|
|
3011
|
+
const rl = readline.createInterface({
|
|
3012
|
+
input: process.stdin,
|
|
3013
|
+
output: process.stdout
|
|
3014
|
+
});
|
|
3015
|
+
return new Promise((resolve) => {
|
|
3016
|
+
const lines = [];
|
|
3017
|
+
let emptyLineCount = 0;
|
|
3018
|
+
rl.on("line", (line) => {
|
|
3019
|
+
if (line.trim() === "EOF") {
|
|
3020
|
+
rl.close();
|
|
3021
|
+
resolve(lines.join("\n"));
|
|
3022
|
+
return;
|
|
3023
|
+
}
|
|
3024
|
+
if (line === "") {
|
|
3025
|
+
emptyLineCount++;
|
|
3026
|
+
if (emptyLineCount >= 2 && lines.length === 0) {
|
|
3027
|
+
rl.close();
|
|
3028
|
+
resolve("");
|
|
3029
|
+
return;
|
|
3030
|
+
}
|
|
3031
|
+
} else {
|
|
3032
|
+
emptyLineCount = 0;
|
|
3033
|
+
}
|
|
3034
|
+
lines.push(line);
|
|
3035
|
+
});
|
|
3036
|
+
rl.on("close", () => {
|
|
3037
|
+
resolve(lines.join("\n"));
|
|
3038
|
+
});
|
|
3039
|
+
});
|
|
3040
|
+
}
|
|
2881
3041
|
var WIZARD_STEPS = [
|
|
2882
3042
|
{ id: "format", title: "Output Format", icon: "\u{1F4E4}", tier: "basic" },
|
|
2883
3043
|
{ id: "project", title: "Project Basics", icon: "\u2728", tier: "basic" },
|
|
@@ -3544,18 +3704,27 @@ async function runInteractiveWizard(options, detected, userTier) {
|
|
|
3544
3704
|
answers.stack = stackResponse.stack || [];
|
|
3545
3705
|
const repoStep = getCurrentStep("repo");
|
|
3546
3706
|
showStep(currentStepNum, repoStep, userTier);
|
|
3707
|
+
if (detected?.repoHost || detected?.license || detected?.cicd) {
|
|
3708
|
+
console.log(chalk8.green(" \u2713 Auto-detected from your project:"));
|
|
3709
|
+
if (detected.repoHost) console.log(chalk8.gray(` \u2022 Repository: ${detected.repoHost}${detected.repoUrl ? ` (${detected.repoUrl})` : ""}`));
|
|
3710
|
+
if (detected.license) console.log(chalk8.gray(` \u2022 License: ${detected.license}`));
|
|
3711
|
+
if (detected.cicd) console.log(chalk8.gray(` \u2022 CI/CD: ${detected.cicd}`));
|
|
3712
|
+
console.log();
|
|
3713
|
+
}
|
|
3714
|
+
const repoHostChoices = [
|
|
3715
|
+
{ title: chalk8.gray("\u23ED Skip"), value: "" },
|
|
3716
|
+
...REPO_HOSTS.map((h) => ({
|
|
3717
|
+
title: detected?.repoHost === h.id ? `${h.icon} ${h.label} ${chalk8.green("(detected)")}` : `${h.icon} ${h.label}`,
|
|
3718
|
+
value: h.id
|
|
3719
|
+
}))
|
|
3720
|
+
];
|
|
3721
|
+
const detectedRepoIndex = detected?.repoHost ? repoHostChoices.findIndex((c) => c.value === detected.repoHost) : 0;
|
|
3547
3722
|
const repoHostResponse = await prompts4({
|
|
3548
3723
|
type: "select",
|
|
3549
3724
|
name: "repoHost",
|
|
3550
3725
|
message: chalk8.white("Repository host:"),
|
|
3551
|
-
choices:
|
|
3552
|
-
|
|
3553
|
-
...REPO_HOSTS.map((h) => ({
|
|
3554
|
-
title: `${h.icon} ${h.label}`,
|
|
3555
|
-
value: h.id
|
|
3556
|
-
}))
|
|
3557
|
-
],
|
|
3558
|
-
initial: 0
|
|
3726
|
+
choices: repoHostChoices,
|
|
3727
|
+
initial: detectedRepoIndex > 0 ? detectedRepoIndex : 0
|
|
3559
3728
|
}, promptConfig);
|
|
3560
3729
|
answers.repoHost = repoHostResponse.repoHost || "";
|
|
3561
3730
|
const visibilityResponse = await prompts4({
|
|
@@ -3567,18 +3736,20 @@ async function runInteractiveWizard(options, detected, userTier) {
|
|
|
3567
3736
|
inactive: "No"
|
|
3568
3737
|
}, promptConfig);
|
|
3569
3738
|
answers.isPublic = visibilityResponse.isPublic || false;
|
|
3739
|
+
const licenseChoices = [
|
|
3740
|
+
{ title: chalk8.gray("\u23ED Skip"), value: "" },
|
|
3741
|
+
...LICENSES.map((l) => ({
|
|
3742
|
+
title: detected?.license === l.id ? `${l.label} ${chalk8.green("(detected)")}` : l.label,
|
|
3743
|
+
value: l.id
|
|
3744
|
+
}))
|
|
3745
|
+
];
|
|
3746
|
+
const detectedLicenseIndex = detected?.license ? licenseChoices.findIndex((c) => c.value === detected.license) : 0;
|
|
3570
3747
|
const licenseResponse = await prompts4({
|
|
3571
3748
|
type: "select",
|
|
3572
3749
|
name: "license",
|
|
3573
3750
|
message: chalk8.white("License:"),
|
|
3574
|
-
choices:
|
|
3575
|
-
|
|
3576
|
-
...LICENSES.map((l) => ({
|
|
3577
|
-
title: l.label,
|
|
3578
|
-
value: l.id
|
|
3579
|
-
}))
|
|
3580
|
-
],
|
|
3581
|
-
initial: 0
|
|
3751
|
+
choices: licenseChoices,
|
|
3752
|
+
initial: detectedLicenseIndex > 0 ? detectedLicenseIndex : 0
|
|
3582
3753
|
}, promptConfig);
|
|
3583
3754
|
answers.license = licenseResponse.license || "";
|
|
3584
3755
|
const conventionalResponse = await prompts4({
|
|
@@ -3610,18 +3781,20 @@ async function runInteractiveWizard(options, detected, userTier) {
|
|
|
3610
3781
|
}, promptConfig);
|
|
3611
3782
|
answers.dependabot = dependabotResponse.dependabot || false;
|
|
3612
3783
|
}
|
|
3784
|
+
const cicdChoices = [
|
|
3785
|
+
{ title: chalk8.gray("\u23ED Skip"), value: "" },
|
|
3786
|
+
...CICD_OPTIONS.map((c) => ({
|
|
3787
|
+
title: detected?.cicd === c.id ? `${c.icon} ${c.label} ${chalk8.green("(detected)")}` : `${c.icon} ${c.label}`,
|
|
3788
|
+
value: c.id
|
|
3789
|
+
}))
|
|
3790
|
+
];
|
|
3791
|
+
const detectedCicdIndex = detected?.cicd ? cicdChoices.findIndex((c) => c.value === detected.cicd) : 0;
|
|
3613
3792
|
const cicdResponse = await prompts4({
|
|
3614
3793
|
type: "select",
|
|
3615
3794
|
name: "cicd",
|
|
3616
3795
|
message: chalk8.white("CI/CD Platform:"),
|
|
3617
|
-
choices:
|
|
3618
|
-
|
|
3619
|
-
...CICD_OPTIONS.map((c) => ({
|
|
3620
|
-
title: `${c.icon} ${c.label}`,
|
|
3621
|
-
value: c.id
|
|
3622
|
-
}))
|
|
3623
|
-
],
|
|
3624
|
-
initial: 0
|
|
3796
|
+
choices: cicdChoices,
|
|
3797
|
+
initial: detectedCicdIndex > 0 ? detectedCicdIndex : 0
|
|
3625
3798
|
}, promptConfig);
|
|
3626
3799
|
answers.cicd = cicdResponse.cicd || "";
|
|
3627
3800
|
const deployResponse = await prompts4({
|
|
@@ -3629,7 +3802,8 @@ async function runInteractiveWizard(options, detected, userTier) {
|
|
|
3629
3802
|
name: "deploymentTargets",
|
|
3630
3803
|
message: chalk8.white("Deployment targets:"),
|
|
3631
3804
|
choices: DEPLOYMENT_TARGETS.map((t) => ({
|
|
3632
|
-
title: `${t.icon} ${t.label}`,
|
|
3805
|
+
title: t.id === "docker" && detected?.hasDocker ? `${t.icon} ${t.label} ${chalk8.green("(detected)")}` : `${t.icon} ${t.label}`,
|
|
3806
|
+
selected: t.id === "docker" && detected?.hasDocker,
|
|
3633
3807
|
value: t.id
|
|
3634
3808
|
})),
|
|
3635
3809
|
hint: chalk8.gray("space select \u2022 enter to skip/confirm"),
|
|
@@ -3957,24 +4131,39 @@ async function runInteractiveWizard(options, detected, userTier) {
|
|
|
3957
4131
|
console.log(chalk8.gray(" Generate additional project files:"));
|
|
3958
4132
|
console.log();
|
|
3959
4133
|
const STATIC_FILE_OPTIONS = [
|
|
3960
|
-
{ title: "\u{1F4DD} .editorconfig", value: "editorconfig", desc: "Consistent code formatting"
|
|
3961
|
-
{ title: "\u{1F91D} CONTRIBUTING.md", value: "contributing", desc: "Contributor guidelines"
|
|
3962
|
-
{ title: "\u{1F4DC} CODE_OF_CONDUCT.md", value: "codeOfConduct", desc: "Community standards"
|
|
3963
|
-
{ title: "\u{1F512} SECURITY.md", value: "security", desc: "Vulnerability reporting"
|
|
3964
|
-
{ title: "\u{1F5FA}\uFE0F ROADMAP.md", value: "roadmap", desc: "Project roadmap"
|
|
3965
|
-
{ title: "\u{1F4CB} .gitignore", value: "gitignore", desc: "Git ignore patterns"
|
|
3966
|
-
{ title: "\u{1F4B0} FUNDING.yml", value: "funding", desc: "GitHub Sponsors config"
|
|
3967
|
-
{ title: "\u{1F4C4} LICENSE", value: "license", desc: "License file"
|
|
3968
|
-
{ title: "\u{1F4D6} README.md", value: "readme", desc: "Project readme"
|
|
3969
|
-
{ title: "\u{1F3D7}\uFE0F ARCHITECTURE.md", value: "architecture", desc: "Architecture docs"
|
|
3970
|
-
{ title: "\u{1F4DD} CHANGELOG.md", value: "changelog", desc: "Version history"
|
|
4134
|
+
{ title: "\u{1F4DD} .editorconfig", value: "editorconfig", desc: "Consistent code formatting" },
|
|
4135
|
+
{ title: "\u{1F91D} CONTRIBUTING.md", value: "contributing", desc: "Contributor guidelines" },
|
|
4136
|
+
{ title: "\u{1F4DC} CODE_OF_CONDUCT.md", value: "codeOfConduct", desc: "Community standards" },
|
|
4137
|
+
{ title: "\u{1F512} SECURITY.md", value: "security", desc: "Vulnerability reporting" },
|
|
4138
|
+
{ title: "\u{1F5FA}\uFE0F ROADMAP.md", value: "roadmap", desc: "Project roadmap" },
|
|
4139
|
+
{ title: "\u{1F4CB} .gitignore", value: "gitignore", desc: "Git ignore patterns" },
|
|
4140
|
+
{ title: "\u{1F4B0} FUNDING.yml", value: "funding", desc: "GitHub Sponsors config" },
|
|
4141
|
+
{ title: "\u{1F4C4} LICENSE", value: "license", desc: "License file" },
|
|
4142
|
+
{ title: "\u{1F4D6} README.md", value: "readme", desc: "Project readme" },
|
|
4143
|
+
{ title: "\u{1F3D7}\uFE0F ARCHITECTURE.md", value: "architecture", desc: "Architecture docs" },
|
|
4144
|
+
{ title: "\u{1F4DD} CHANGELOG.md", value: "changelog", desc: "Version history" }
|
|
3971
4145
|
];
|
|
4146
|
+
const existingFiles = {};
|
|
4147
|
+
for (const opt of STATIC_FILE_OPTIONS) {
|
|
4148
|
+
const filePath = STATIC_FILE_PATHS2[opt.value];
|
|
4149
|
+
if (filePath) {
|
|
4150
|
+
const content = await readExistingFile(join6(process.cwd(), filePath));
|
|
4151
|
+
if (content) {
|
|
4152
|
+
existingFiles[opt.value] = content;
|
|
4153
|
+
}
|
|
4154
|
+
}
|
|
4155
|
+
}
|
|
4156
|
+
const existingCount = Object.keys(existingFiles).length;
|
|
4157
|
+
if (existingCount > 0) {
|
|
4158
|
+
console.log(chalk8.green(` \u2713 Found ${existingCount} existing file(s) in your project`));
|
|
4159
|
+
console.log();
|
|
4160
|
+
}
|
|
3972
4161
|
const staticFilesResponse = await prompts4({
|
|
3973
4162
|
type: "multiselect",
|
|
3974
4163
|
name: "staticFiles",
|
|
3975
4164
|
message: chalk8.white("Include static files:"),
|
|
3976
4165
|
choices: STATIC_FILE_OPTIONS.map((f) => ({
|
|
3977
|
-
title: f.title,
|
|
4166
|
+
title: existingFiles[f.value] ? `${f.title} ${chalk8.green("(exists)")}` : f.title,
|
|
3978
4167
|
value: f.value,
|
|
3979
4168
|
description: chalk8.gray(f.desc)
|
|
3980
4169
|
})),
|
|
@@ -3984,22 +4173,60 @@ async function runInteractiveWizard(options, detected, userTier) {
|
|
|
3984
4173
|
answers.staticFiles = staticFilesResponse.staticFiles || [];
|
|
3985
4174
|
if (answers.staticFiles?.length > 0) {
|
|
3986
4175
|
console.log();
|
|
3987
|
-
console.log(chalk8.cyan(" \u{1F4DD} Customize file contents
|
|
3988
|
-
console.log(chalk8.gray("
|
|
4176
|
+
console.log(chalk8.cyan(" \u{1F4DD} Customize file contents:"));
|
|
4177
|
+
console.log(chalk8.gray(" For each file, choose to use existing content, write new, or use defaults."));
|
|
3989
4178
|
console.log();
|
|
3990
4179
|
answers.staticFileContents = {};
|
|
3991
4180
|
for (const fileKey of answers.staticFiles) {
|
|
3992
|
-
const
|
|
3993
|
-
if (!
|
|
3994
|
-
const
|
|
3995
|
-
|
|
3996
|
-
|
|
3997
|
-
|
|
3998
|
-
|
|
3999
|
-
|
|
4000
|
-
|
|
4001
|
-
|
|
4181
|
+
const fileOpt = STATIC_FILE_OPTIONS.find((f) => f.value === fileKey);
|
|
4182
|
+
if (!fileOpt) continue;
|
|
4183
|
+
const filePath = STATIC_FILE_PATHS2[fileKey];
|
|
4184
|
+
const existingContent = existingFiles[fileKey];
|
|
4185
|
+
if (existingContent) {
|
|
4186
|
+
const preview = existingContent.split("\n").slice(0, 3).join("\n");
|
|
4187
|
+
console.log(chalk8.gray(` \u2500\u2500\u2500 ${filePath} (existing) \u2500\u2500\u2500`));
|
|
4188
|
+
console.log(chalk8.gray(preview.substring(0, 150) + (preview.length > 150 ? "..." : "")));
|
|
4189
|
+
console.log();
|
|
4190
|
+
const actionResponse = await prompts4({
|
|
4191
|
+
type: "select",
|
|
4192
|
+
name: "action",
|
|
4193
|
+
message: chalk8.white(`${filePath}:`),
|
|
4194
|
+
choices: [
|
|
4195
|
+
{ title: chalk8.green("\u2713 Use existing content"), value: "existing" },
|
|
4196
|
+
{ title: chalk8.yellow("\u270F\uFE0F Write new content"), value: "new" },
|
|
4197
|
+
{ title: chalk8.gray("\u26A1 Generate default"), value: "default" }
|
|
4198
|
+
],
|
|
4199
|
+
initial: 0
|
|
4200
|
+
}, promptConfig);
|
|
4201
|
+
if (actionResponse.action === "existing") {
|
|
4202
|
+
answers.staticFileContents[fileKey] = existingContent;
|
|
4203
|
+
} else if (actionResponse.action === "new") {
|
|
4204
|
+
console.log();
|
|
4205
|
+
const content = await readMultilineInput(` Content for ${filePath}:`);
|
|
4206
|
+
if (content.trim()) {
|
|
4207
|
+
answers.staticFileContents[fileKey] = content;
|
|
4208
|
+
}
|
|
4209
|
+
}
|
|
4210
|
+
} else {
|
|
4211
|
+
const actionResponse = await prompts4({
|
|
4212
|
+
type: "select",
|
|
4213
|
+
name: "action",
|
|
4214
|
+
message: chalk8.white(`${filePath}:`),
|
|
4215
|
+
choices: [
|
|
4216
|
+
{ title: chalk8.gray("\u26A1 Generate default"), value: "default" },
|
|
4217
|
+
{ title: chalk8.yellow("\u270F\uFE0F Write custom content"), value: "new" }
|
|
4218
|
+
],
|
|
4219
|
+
initial: 0
|
|
4220
|
+
}, promptConfig);
|
|
4221
|
+
if (actionResponse.action === "new") {
|
|
4222
|
+
console.log();
|
|
4223
|
+
const content = await readMultilineInput(` Content for ${filePath}:`);
|
|
4224
|
+
if (content.trim()) {
|
|
4225
|
+
answers.staticFileContents[fileKey] = content;
|
|
4226
|
+
}
|
|
4227
|
+
}
|
|
4002
4228
|
}
|
|
4229
|
+
console.log();
|
|
4003
4230
|
}
|
|
4004
4231
|
}
|
|
4005
4232
|
}
|
|
@@ -4139,7 +4366,7 @@ function handleApiError3(error) {
|
|
|
4139
4366
|
|
|
4140
4367
|
// src/commands/status.ts
|
|
4141
4368
|
import chalk10 from "chalk";
|
|
4142
|
-
import { readFile as
|
|
4369
|
+
import { readFile as readFile6, readdir, access as access4 } from "fs/promises";
|
|
4143
4370
|
import { join as join7 } from "path";
|
|
4144
4371
|
import { existsSync as existsSync4 } from "fs";
|
|
4145
4372
|
var CONFIG_FILES = [
|
|
@@ -4169,7 +4396,7 @@ async function statusCommand() {
|
|
|
4169
4396
|
const configPath = join7(cwd, ".lynxprompt/conf.yml");
|
|
4170
4397
|
if (existsSync4(configPath)) {
|
|
4171
4398
|
try {
|
|
4172
|
-
const content = await
|
|
4399
|
+
const content = await readFile6(configPath, "utf-8");
|
|
4173
4400
|
const { parse: parse5 } = await import("yaml");
|
|
4174
4401
|
const config2 = parse5(content);
|
|
4175
4402
|
if (config2?.exporters?.length > 0) {
|
|
@@ -4213,7 +4440,7 @@ async function statusCommand() {
|
|
|
4213
4440
|
const filePath = join7(cwd, config2.path);
|
|
4214
4441
|
try {
|
|
4215
4442
|
await access4(filePath);
|
|
4216
|
-
const content = await
|
|
4443
|
+
const content = await readFile6(filePath, "utf-8");
|
|
4217
4444
|
const lines = content.split("\n").length;
|
|
4218
4445
|
const size = formatBytes(content.length);
|
|
4219
4446
|
foundAny = true;
|
|
@@ -4292,7 +4519,7 @@ function formatBytes(bytes) {
|
|
|
4292
4519
|
import chalk11 from "chalk";
|
|
4293
4520
|
import ora9 from "ora";
|
|
4294
4521
|
import prompts5 from "prompts";
|
|
4295
|
-
import { readFile as
|
|
4522
|
+
import { readFile as readFile7, writeFile as writeFile5, mkdir as mkdir5, readdir as readdir2 } from "fs/promises";
|
|
4296
4523
|
import { join as join8, dirname as dirname5 } from "path";
|
|
4297
4524
|
import { existsSync as existsSync5 } from "fs";
|
|
4298
4525
|
import * as yaml3 from "yaml";
|
|
@@ -4313,7 +4540,7 @@ async function syncCommand(options = {}) {
|
|
|
4313
4540
|
const spinner = ora9("Loading configuration...").start();
|
|
4314
4541
|
let config2;
|
|
4315
4542
|
try {
|
|
4316
|
-
const configContent = await
|
|
4543
|
+
const configContent = await readFile7(configPath, "utf-8");
|
|
4317
4544
|
config2 = yaml3.parse(configContent);
|
|
4318
4545
|
spinner.succeed("Configuration loaded");
|
|
4319
4546
|
} catch (error) {
|
|
@@ -4415,7 +4642,7 @@ async function loadRules(rulesPath) {
|
|
|
4415
4642
|
if (!entry.isFile()) continue;
|
|
4416
4643
|
if (!entry.name.endsWith(".md")) continue;
|
|
4417
4644
|
const filePath = join8(rulesPath, entry.name);
|
|
4418
|
-
const content = await
|
|
4645
|
+
const content = await readFile7(filePath, "utf-8");
|
|
4419
4646
|
if (content.trim()) {
|
|
4420
4647
|
files.push({ name: entry.name, content: content.trim() });
|
|
4421
4648
|
}
|
|
@@ -4503,7 +4730,7 @@ function formatAsJson(content, _agent) {
|
|
|
4503
4730
|
// src/commands/agents.ts
|
|
4504
4731
|
import chalk12 from "chalk";
|
|
4505
4732
|
import prompts6 from "prompts";
|
|
4506
|
-
import { readFile as
|
|
4733
|
+
import { readFile as readFile8, writeFile as writeFile6 } from "fs/promises";
|
|
4507
4734
|
import { join as join9 } from "path";
|
|
4508
4735
|
import { existsSync as existsSync6 } from "fs";
|
|
4509
4736
|
import * as yaml4 from "yaml";
|
|
@@ -4705,7 +4932,7 @@ async function loadConfig() {
|
|
|
4705
4932
|
return null;
|
|
4706
4933
|
}
|
|
4707
4934
|
try {
|
|
4708
|
-
const content = await
|
|
4935
|
+
const content = await readFile8(configPath, "utf-8");
|
|
4709
4936
|
return yaml4.parse(content);
|
|
4710
4937
|
} catch {
|
|
4711
4938
|
return null;
|
|
@@ -4721,7 +4948,7 @@ async function saveConfig(config2) {
|
|
|
4721
4948
|
// src/commands/check.ts
|
|
4722
4949
|
import chalk13 from "chalk";
|
|
4723
4950
|
import ora10 from "ora";
|
|
4724
|
-
import { readFile as
|
|
4951
|
+
import { readFile as readFile9, readdir as readdir3, stat } from "fs/promises";
|
|
4725
4952
|
import { join as join10 } from "path";
|
|
4726
4953
|
import { existsSync as existsSync7 } from "fs";
|
|
4727
4954
|
import * as yaml5 from "yaml";
|
|
@@ -4787,7 +5014,7 @@ async function validateLynxPromptConfig(cwd) {
|
|
|
4787
5014
|
return { errors, warnings };
|
|
4788
5015
|
}
|
|
4789
5016
|
try {
|
|
4790
|
-
const content = await
|
|
5017
|
+
const content = await readFile9(configPath, "utf-8");
|
|
4791
5018
|
const config2 = yaml5.parse(content);
|
|
4792
5019
|
if (!config2.version) {
|
|
4793
5020
|
warnings.push(".lynxprompt/conf.yml: Missing 'version' field");
|
|
@@ -4860,7 +5087,7 @@ async function checkCommand(options = {}) {
|
|
|
4860
5087
|
if (existsSync7(filePath)) {
|
|
4861
5088
|
result.files.push(file.path);
|
|
4862
5089
|
try {
|
|
4863
|
-
const content = await
|
|
5090
|
+
const content = await readFile9(filePath, "utf-8");
|
|
4864
5091
|
const validation = validateMarkdown(content, file.path);
|
|
4865
5092
|
result.errors.push(...validation.errors);
|
|
4866
5093
|
result.warnings.push(...validation.warnings);
|
|
@@ -4879,7 +5106,7 @@ async function checkCommand(options = {}) {
|
|
|
4879
5106
|
const fileStat = await stat(filePath);
|
|
4880
5107
|
if (fileStat.isFile()) {
|
|
4881
5108
|
result.files.push(`${dir.path}/${file}`);
|
|
4882
|
-
const content = await
|
|
5109
|
+
const content = await readFile9(filePath, "utf-8");
|
|
4883
5110
|
if (file.endsWith(".mdc")) {
|
|
4884
5111
|
const validation = validateMdc(content, `${dir.path}/${file}`);
|
|
4885
5112
|
result.errors.push(...validation.errors);
|
|
@@ -4955,7 +5182,7 @@ async function checkCommand(options = {}) {
|
|
|
4955
5182
|
// src/commands/diff.ts
|
|
4956
5183
|
import chalk14 from "chalk";
|
|
4957
5184
|
import ora11 from "ora";
|
|
4958
|
-
import { readFile as
|
|
5185
|
+
import { readFile as readFile10 } from "fs/promises";
|
|
4959
5186
|
import { join as join11 } from "path";
|
|
4960
5187
|
import { existsSync as existsSync8 } from "fs";
|
|
4961
5188
|
function computeDiff(oldText, newText) {
|
|
@@ -5117,7 +5344,7 @@ async function diffFileWithBlueprint(cwd, file, blueprintId, compact = false) {
|
|
|
5117
5344
|
console.log(chalk14.red(`\u2717 Blueprint has no content`));
|
|
5118
5345
|
return;
|
|
5119
5346
|
}
|
|
5120
|
-
const localContent = await
|
|
5347
|
+
const localContent = await readFile10(filePath, "utf-8");
|
|
5121
5348
|
const diff = computeDiff(blueprint.content, localContent);
|
|
5122
5349
|
const stats = getDiffStats(diff);
|
|
5123
5350
|
if (stats.added === 0 && stats.removed === 0) {
|
|
@@ -5173,7 +5400,7 @@ async function diffWithBlueprintId(cwd, blueprintId) {
|
|
|
5173
5400
|
const fullPath = join11(cwd, path2);
|
|
5174
5401
|
if (existsSync8(fullPath)) {
|
|
5175
5402
|
try {
|
|
5176
|
-
localContent = await
|
|
5403
|
+
localContent = await readFile10(fullPath, "utf-8");
|
|
5177
5404
|
localPath = path2;
|
|
5178
5405
|
break;
|
|
5179
5406
|
} catch {
|
|
@@ -5235,7 +5462,7 @@ async function diffLocal(cwd) {
|
|
|
5235
5462
|
}
|
|
5236
5463
|
let rulesContent;
|
|
5237
5464
|
try {
|
|
5238
|
-
rulesContent = await
|
|
5465
|
+
rulesContent = await readFile10(rulesPath, "utf-8");
|
|
5239
5466
|
} catch {
|
|
5240
5467
|
console.log(chalk14.red("\u2717 Could not read .lynxprompt/rules/agents.md"));
|
|
5241
5468
|
return;
|
|
@@ -5249,7 +5476,7 @@ async function diffLocal(cwd) {
|
|
|
5249
5476
|
const filePath = join11(cwd, file.path);
|
|
5250
5477
|
if (existsSync8(filePath)) {
|
|
5251
5478
|
try {
|
|
5252
|
-
const exportedContent = await
|
|
5479
|
+
const exportedContent = await readFile10(filePath, "utf-8");
|
|
5253
5480
|
let compareContent = exportedContent;
|
|
5254
5481
|
if (file.path.endsWith(".mdc")) {
|
|
5255
5482
|
const frontmatterEnd = exportedContent.indexOf("---", 3);
|