lean-spec 0.2.7-dev.20251126090057 → 0.2.7-dev.20251126100750
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.
|
@@ -4486,50 +4486,201 @@ async function copyTemplate(source, target, cwd = process.cwd()) {
|
|
|
4486
4486
|
console.log(chalk20.gray(` Use with: lean-spec create <spec-name> --template=${templateName}`));
|
|
4487
4487
|
}
|
|
4488
4488
|
var AI_TOOL_CONFIGS = {
|
|
4489
|
+
aider: {
|
|
4490
|
+
file: "AGENTS.md",
|
|
4491
|
+
description: "Aider (uses AGENTS.md)",
|
|
4492
|
+
default: false,
|
|
4493
|
+
usesSymlink: false,
|
|
4494
|
+
detection: {
|
|
4495
|
+
commands: ["aider"],
|
|
4496
|
+
configDirs: [".aider"]
|
|
4497
|
+
}
|
|
4498
|
+
},
|
|
4489
4499
|
claude: {
|
|
4490
4500
|
file: "CLAUDE.md",
|
|
4491
|
-
description: "Claude Code
|
|
4501
|
+
description: "Claude Code (CLAUDE.md)",
|
|
4492
4502
|
default: true,
|
|
4493
|
-
usesSymlink: true
|
|
4503
|
+
usesSymlink: true,
|
|
4504
|
+
detection: {
|
|
4505
|
+
commands: ["claude"],
|
|
4506
|
+
configDirs: [".claude"],
|
|
4507
|
+
envVars: ["ANTHROPIC_API_KEY"]
|
|
4508
|
+
}
|
|
4494
4509
|
},
|
|
4495
|
-
|
|
4496
|
-
file: "
|
|
4497
|
-
description: "
|
|
4510
|
+
codex: {
|
|
4511
|
+
file: "AGENTS.md",
|
|
4512
|
+
description: "Codex CLI by OpenAI (uses AGENTS.md)",
|
|
4498
4513
|
default: false,
|
|
4499
|
-
usesSymlink:
|
|
4514
|
+
usesSymlink: false,
|
|
4515
|
+
detection: {
|
|
4516
|
+
commands: ["codex"],
|
|
4517
|
+
configDirs: [".codex"],
|
|
4518
|
+
envVars: ["OPENAI_API_KEY"]
|
|
4519
|
+
}
|
|
4500
4520
|
},
|
|
4501
4521
|
copilot: {
|
|
4502
4522
|
file: "AGENTS.md",
|
|
4503
4523
|
description: "GitHub Copilot (AGENTS.md - default)",
|
|
4504
4524
|
default: true,
|
|
4505
|
-
usesSymlink: false
|
|
4525
|
+
usesSymlink: false,
|
|
4506
4526
|
// Primary file, no symlink needed
|
|
4527
|
+
detection: {
|
|
4528
|
+
commands: ["copilot"],
|
|
4529
|
+
envVars: ["GITHUB_TOKEN"]
|
|
4530
|
+
}
|
|
4507
4531
|
},
|
|
4508
4532
|
cursor: {
|
|
4509
4533
|
file: "AGENTS.md",
|
|
4510
4534
|
description: "Cursor (uses AGENTS.md)",
|
|
4511
4535
|
default: false,
|
|
4512
|
-
usesSymlink: false
|
|
4536
|
+
usesSymlink: false,
|
|
4537
|
+
detection: {
|
|
4538
|
+
configDirs: [".cursor", ".cursorules"],
|
|
4539
|
+
commands: ["cursor"]
|
|
4540
|
+
}
|
|
4513
4541
|
},
|
|
4514
|
-
|
|
4542
|
+
droid: {
|
|
4515
4543
|
file: "AGENTS.md",
|
|
4516
|
-
description: "
|
|
4544
|
+
description: "Droid by Factory (uses AGENTS.md)",
|
|
4517
4545
|
default: false,
|
|
4518
|
-
usesSymlink: false
|
|
4546
|
+
usesSymlink: false,
|
|
4547
|
+
detection: {
|
|
4548
|
+
commands: ["droid"]
|
|
4549
|
+
}
|
|
4519
4550
|
},
|
|
4520
|
-
|
|
4551
|
+
gemini: {
|
|
4552
|
+
file: "GEMINI.md",
|
|
4553
|
+
description: "Gemini CLI (GEMINI.md)",
|
|
4554
|
+
default: false,
|
|
4555
|
+
usesSymlink: true,
|
|
4556
|
+
detection: {
|
|
4557
|
+
commands: ["gemini"],
|
|
4558
|
+
configDirs: [".gemini"],
|
|
4559
|
+
envVars: ["GOOGLE_API_KEY", "GEMINI_API_KEY"]
|
|
4560
|
+
}
|
|
4561
|
+
},
|
|
4562
|
+
opencode: {
|
|
4521
4563
|
file: "AGENTS.md",
|
|
4522
|
-
description: "
|
|
4564
|
+
description: "OpenCode (uses AGENTS.md)",
|
|
4523
4565
|
default: false,
|
|
4524
|
-
usesSymlink: false
|
|
4566
|
+
usesSymlink: false,
|
|
4567
|
+
detection: {
|
|
4568
|
+
commands: ["opencode"],
|
|
4569
|
+
configDirs: [".opencode"]
|
|
4570
|
+
}
|
|
4525
4571
|
},
|
|
4526
|
-
|
|
4572
|
+
windsurf: {
|
|
4527
4573
|
file: "AGENTS.md",
|
|
4528
|
-
description: "
|
|
4574
|
+
description: "Windsurf (uses AGENTS.md)",
|
|
4529
4575
|
default: false,
|
|
4530
|
-
usesSymlink: false
|
|
4576
|
+
usesSymlink: false,
|
|
4577
|
+
detection: {
|
|
4578
|
+
configDirs: [".windsurf", ".windsurfrules"],
|
|
4579
|
+
commands: ["windsurf"]
|
|
4580
|
+
}
|
|
4531
4581
|
}
|
|
4532
4582
|
};
|
|
4583
|
+
function commandExists(command) {
|
|
4584
|
+
try {
|
|
4585
|
+
const which = process.platform === "win32" ? "where" : "which";
|
|
4586
|
+
execSync(`${which} ${command}`, { stdio: "ignore" });
|
|
4587
|
+
return true;
|
|
4588
|
+
} catch {
|
|
4589
|
+
return false;
|
|
4590
|
+
}
|
|
4591
|
+
}
|
|
4592
|
+
async function configDirExists(dirName) {
|
|
4593
|
+
const homeDir = process.env.HOME || process.env.USERPROFILE || "";
|
|
4594
|
+
if (!homeDir) return false;
|
|
4595
|
+
try {
|
|
4596
|
+
await fs11.access(path17.join(homeDir, dirName));
|
|
4597
|
+
return true;
|
|
4598
|
+
} catch {
|
|
4599
|
+
return false;
|
|
4600
|
+
}
|
|
4601
|
+
}
|
|
4602
|
+
function envVarExists(varName) {
|
|
4603
|
+
return !!process.env[varName];
|
|
4604
|
+
}
|
|
4605
|
+
async function extensionInstalled(extensionId) {
|
|
4606
|
+
const homeDir = process.env.HOME || process.env.USERPROFILE || "";
|
|
4607
|
+
if (!homeDir) return false;
|
|
4608
|
+
const extensionDirs = [
|
|
4609
|
+
path17.join(homeDir, ".vscode", "extensions"),
|
|
4610
|
+
path17.join(homeDir, ".vscode-server", "extensions"),
|
|
4611
|
+
path17.join(homeDir, ".cursor", "extensions")
|
|
4612
|
+
];
|
|
4613
|
+
for (const extDir of extensionDirs) {
|
|
4614
|
+
try {
|
|
4615
|
+
const entries = await fs11.readdir(extDir);
|
|
4616
|
+
if (entries.some((e) => e.toLowerCase().startsWith(extensionId.toLowerCase()))) {
|
|
4617
|
+
return true;
|
|
4618
|
+
}
|
|
4619
|
+
} catch {
|
|
4620
|
+
}
|
|
4621
|
+
}
|
|
4622
|
+
return false;
|
|
4623
|
+
}
|
|
4624
|
+
async function detectInstalledAITools() {
|
|
4625
|
+
const results = [];
|
|
4626
|
+
for (const [toolKey, config] of Object.entries(AI_TOOL_CONFIGS)) {
|
|
4627
|
+
const reasons = [];
|
|
4628
|
+
const detection = config.detection;
|
|
4629
|
+
if (!detection) {
|
|
4630
|
+
results.push({ tool: toolKey, detected: false, reasons: [] });
|
|
4631
|
+
continue;
|
|
4632
|
+
}
|
|
4633
|
+
if (detection.commands) {
|
|
4634
|
+
for (const cmd of detection.commands) {
|
|
4635
|
+
if (commandExists(cmd)) {
|
|
4636
|
+
reasons.push(`'${cmd}' command found`);
|
|
4637
|
+
}
|
|
4638
|
+
}
|
|
4639
|
+
}
|
|
4640
|
+
if (detection.configDirs) {
|
|
4641
|
+
for (const dir of detection.configDirs) {
|
|
4642
|
+
if (await configDirExists(dir)) {
|
|
4643
|
+
reasons.push(`~/${dir} directory found`);
|
|
4644
|
+
}
|
|
4645
|
+
}
|
|
4646
|
+
}
|
|
4647
|
+
if (detection.envVars) {
|
|
4648
|
+
for (const envVar of detection.envVars) {
|
|
4649
|
+
if (envVarExists(envVar)) {
|
|
4650
|
+
reasons.push(`${envVar} env var set`);
|
|
4651
|
+
}
|
|
4652
|
+
}
|
|
4653
|
+
}
|
|
4654
|
+
if (detection.extensions) {
|
|
4655
|
+
for (const ext of detection.extensions) {
|
|
4656
|
+
if (await extensionInstalled(ext)) {
|
|
4657
|
+
reasons.push(`${ext} extension installed`);
|
|
4658
|
+
}
|
|
4659
|
+
}
|
|
4660
|
+
}
|
|
4661
|
+
results.push({
|
|
4662
|
+
tool: toolKey,
|
|
4663
|
+
detected: reasons.length > 0,
|
|
4664
|
+
reasons
|
|
4665
|
+
});
|
|
4666
|
+
}
|
|
4667
|
+
return results;
|
|
4668
|
+
}
|
|
4669
|
+
async function getDefaultAIToolSelection() {
|
|
4670
|
+
const detectionResults = await detectInstalledAITools();
|
|
4671
|
+
const detectedTools = detectionResults.filter((r) => r.detected).map((r) => r.tool);
|
|
4672
|
+
if (detectedTools.length > 0) {
|
|
4673
|
+
const copilotDetected = detectedTools.includes("copilot");
|
|
4674
|
+
if (!copilotDetected) {
|
|
4675
|
+
const usesAgentsMd = detectedTools.some((t) => !AI_TOOL_CONFIGS[t].usesSymlink);
|
|
4676
|
+
if (!usesAgentsMd) {
|
|
4677
|
+
detectedTools.push("copilot");
|
|
4678
|
+
}
|
|
4679
|
+
}
|
|
4680
|
+
return { defaults: detectedTools, detected: detectionResults };
|
|
4681
|
+
}
|
|
4682
|
+
return { defaults: ["copilot"], detected: detectionResults };
|
|
4683
|
+
}
|
|
4533
4684
|
async function createAgentToolSymlinks(cwd, selectedTools) {
|
|
4534
4685
|
const results = [];
|
|
4535
4686
|
const isWindows = process.platform === "win32";
|
|
@@ -4805,7 +4956,7 @@ async function initProject(skipPrompts = false, templateOption, agentToolsOption
|
|
|
4805
4956
|
if (skipPrompts) {
|
|
4806
4957
|
console.log(chalk20.gray("Using defaults: quick start with standard template"));
|
|
4807
4958
|
if (!agentToolsOption) {
|
|
4808
|
-
selectedAgentTools = ["
|
|
4959
|
+
selectedAgentTools = ["copilot"];
|
|
4809
4960
|
}
|
|
4810
4961
|
console.log("");
|
|
4811
4962
|
} else if (!templateOption) {
|
|
@@ -4912,18 +5063,31 @@ async function initProject(skipPrompts = false, templateOption, agentToolsOption
|
|
|
4912
5063
|
templateConfig.structure.pattern = "flat";
|
|
4913
5064
|
templateConfig.structure.prefix = "";
|
|
4914
5065
|
}
|
|
4915
|
-
if (!skipPrompts && !agentToolsOption
|
|
5066
|
+
if (!skipPrompts && !agentToolsOption) {
|
|
5067
|
+
const { defaults: detectedDefaults, detected: detectionResults } = await getDefaultAIToolSelection();
|
|
5068
|
+
const anyDetected = detectionResults.some((r) => r.detected);
|
|
5069
|
+
if (anyDetected) {
|
|
5070
|
+
console.log("");
|
|
5071
|
+
console.log(chalk20.cyan("\u{1F50D} Detected AI tools:"));
|
|
5072
|
+
for (const result of detectionResults) {
|
|
5073
|
+
if (result.detected) {
|
|
5074
|
+
console.log(chalk20.gray(` ${AI_TOOL_CONFIGS[result.tool].description}`));
|
|
5075
|
+
for (const reason of result.reasons) {
|
|
5076
|
+
console.log(chalk20.gray(` \u2514\u2500 ${reason}`));
|
|
5077
|
+
}
|
|
5078
|
+
}
|
|
5079
|
+
}
|
|
5080
|
+
console.log("");
|
|
5081
|
+
}
|
|
4916
5082
|
const toolChoices = Object.entries(AI_TOOL_CONFIGS).map(([key, config]) => ({
|
|
4917
5083
|
name: config.description,
|
|
4918
5084
|
value: key,
|
|
4919
|
-
checked:
|
|
5085
|
+
checked: detectedDefaults.includes(key)
|
|
4920
5086
|
}));
|
|
4921
5087
|
selectedAgentTools = await checkbox({
|
|
4922
5088
|
message: "Which AI tools do you use? (creates symlinks for tool-specific instruction files)",
|
|
4923
5089
|
choices: toolChoices
|
|
4924
5090
|
});
|
|
4925
|
-
} else if (!agentToolsOption && setupMode === "quick") {
|
|
4926
|
-
selectedAgentTools = ["claude", "copilot"];
|
|
4927
5091
|
}
|
|
4928
5092
|
const templatesDir = path17.join(cwd, ".lean-spec", "templates");
|
|
4929
5093
|
try {
|
|
@@ -5129,8 +5293,8 @@ async function scaffoldExample(exampleName, customName) {
|
|
|
5129
5293
|
const packageManager = await detectPackageManager();
|
|
5130
5294
|
console.log(chalk20.gray(`Installing dependencies with ${packageManager}...`));
|
|
5131
5295
|
try {
|
|
5132
|
-
const { execSync:
|
|
5133
|
-
|
|
5296
|
+
const { execSync: execSync4 } = await import('child_process');
|
|
5297
|
+
execSync4(`${packageManager} install`, {
|
|
5134
5298
|
cwd: targetPath,
|
|
5135
5299
|
stdio: "inherit"
|
|
5136
5300
|
});
|
|
@@ -6562,11 +6726,11 @@ async function verifyAITool(provider) {
|
|
|
6562
6726
|
let installed = false;
|
|
6563
6727
|
let version;
|
|
6564
6728
|
try {
|
|
6565
|
-
const { execSync:
|
|
6566
|
-
|
|
6729
|
+
const { execSync: execSync4 } = await import('child_process');
|
|
6730
|
+
execSync4(`which ${toolDef.cliCommand}`, { stdio: "ignore" });
|
|
6567
6731
|
installed = true;
|
|
6568
6732
|
try {
|
|
6569
|
-
const versionOutput =
|
|
6733
|
+
const versionOutput = execSync4(toolDef.versionCmd, {
|
|
6570
6734
|
encoding: "utf-8",
|
|
6571
6735
|
stdio: ["ignore", "pipe", "ignore"]
|
|
6572
6736
|
});
|
|
@@ -10833,5 +10997,5 @@ if (import.meta.url === `file://${process.argv[1]}`) {
|
|
|
10833
10997
|
}
|
|
10834
10998
|
|
|
10835
10999
|
export { agentCommand, analyzeCommand, archiveCommand, backfillCommand, boardCommand, checkCommand, compactCommand, createCommand, createMcpServer, depsCommand, examplesCommand, filesCommand, ganttCommand, initCommand, linkCommand, listCommand, mcpCommand, migrateCommand, openCommand, searchCommand, splitCommand, statsCommand, templatesCommand, timelineCommand, tokensCommand, uiCommand, unlinkCommand, updateCommand, validateCommand, viewCommand };
|
|
10836
|
-
//# sourceMappingURL=chunk-
|
|
10837
|
-
//# sourceMappingURL=chunk-
|
|
11000
|
+
//# sourceMappingURL=chunk-Q6B3LVO7.js.map
|
|
11001
|
+
//# sourceMappingURL=chunk-Q6B3LVO7.js.map
|